diff --git a/web/static/js9_old/analysis-plugins/fits2fits.json b/web/static/js9_old/analysis-plugins/fits2fits.json deleted file mode 100644 index 4b5df6724cb080321096d5707d02fd5bb987f5ad..0000000000000000000000000000000000000000 --- a/web/static/js9_old/analysis-plugins/fits2fits.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - {"name" : "fits2fits", - "title" : "Convert FITS to representation FITS", - "files" : "*", - "action" : "js9Xeq imsection", - "hidden" : true, - "rtype" : "fits"} -] diff --git a/web/static/js9_old/analysis-plugins/imsection.json b/web/static/js9_old/analysis-plugins/imsection.json deleted file mode 100644 index ff257b46be675a283248244d1bcabdca0f18c366..0000000000000000000000000000000000000000 --- a/web/static/js9_old/analysis-plugins/imsection.json +++ /dev/null @@ -1,11 +0,0 @@ -[ - {"name" : "imsection", - "title" : "Extract an Image Section", - "files" : "fits", - "purl" : "./params/imsection.html", - "action" : "js9Xeq imsection $filename $xdim@$xcen,$ydim@$ycen,$bin $filter $slice", - "workDir": true, - "hidden" : true, - "rtype" : "fits"} -] - diff --git a/web/static/js9_old/analysis-plugins/js9Analysis-fits.json b/web/static/js9_old/analysis-plugins/js9Analysis-fits.json deleted file mode 100644 index bc47a347397067833681c97ee82f2e60e27e1ccd..0000000000000000000000000000000000000000 --- a/web/static/js9_old/analysis-plugins/js9Analysis-fits.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - {"name" : "fitshead", - "title" : "FITS Header(s)", - "files" : "fits", - "action" : "js9Xeq fitshead $filename", - "rtype" : "text"}, - {"name" : "macros", - "title" : "Display Macros", - "action" : "js9Xeq macros $image $filename $filename(this) '$ext' '$imcenter' '$wcscenter' '$id' '$foo' '$sregions' '$bregions' '$regions(wcs)' '$regions(physical)' 'ampersand and backquote: `ls &`'", - "hidden" : true, - "rtype" : "text"} -] diff --git a/web/static/js9_old/analysis-plugins/js9Analysis-funtools.json b/web/static/js9_old/analysis-plugins/js9Analysis-funtools.json deleted file mode 100644 index 885ba2135a3115763d83c01f8a13a589f7927152..0000000000000000000000000000000000000000 --- a/web/static/js9_old/analysis-plugins/js9Analysis-funtools.json +++ /dev/null @@ -1,40 +0,0 @@ -[ - {"name" : "counts", - "title" : "Counts in Regions", - "files" : "fits", - "action" : "js9Xeq counts $filename $sregions $bregions", - "rtype" : "text"}, - {"name" : "cubecounts", - "title" : "Counts in Each Cube Slice", - "files" : "fitsHeader(NAXIS,3)", - "action" : "js9Xeq counts $filename(all) $sregions $bregions", - "rtype" : "text"}, - {"name" : "radialprofile", - "title" : "Radial Profile", - "files" : "fits", - "action" : "js9Xeq radialplot $filename $sregions $bregions", - "rtype" : "plot"}, - {"name" : "energyplot", - "title" : "Energy Spectrum", - "files" : "fits", - "action" : "js9Xeq histplot $filename[$regions] false false %energy 0", - "rtype" : "plot"}, - {"name" : "timeplot", - "title" : "Light Curve", - "files" : "fits", - "action" : "js9Xeq histplot $filename[$regions] false false %time 0", - "rtype" : "plot"}, - {"name" : "histplot", - "title" : "Histogram Plot", - "files" : "fits", - "purl" : "./params/histplot.html", - "action" : "js9Xeq histplot $filename[$regions] $norm $bwidth $column $bins", - "rtype" : "plot"}, - {"name" : "evfilter", - "title" : "Event Filter", - "files" : "fits", - "purl" : "./params/evfilter.html", - "action" : "js9Xeq evfilter $filename $filter $imcenter $dims", - "pwin" : "width=830px,height=218px,center=1,resize=1,scrolling=1", - "rtype" : "fits"} -] diff --git a/web/static/js9_old/analysis-plugins/listhdus.json b/web/static/js9_old/analysis-plugins/listhdus.json deleted file mode 100644 index 441ecad976a1ab35d682a719a1519af45b164d2b..0000000000000000000000000000000000000000 --- a/web/static/js9_old/analysis-plugins/listhdus.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - {"name" : "listhdus", - "title" : "List HDUs in a FITS File", - "files" : "fits", - "action" : "js9Xeq listhdus $filename", - "hidden" : true, - "rtype" : "text"} -] diff --git a/web/static/js9_old/analysis-plugins/loadProxy.json b/web/static/js9_old/analysis-plugins/loadProxy.json deleted file mode 100644 index 1d90de80e63ee5a171bb23653ddbfd1e00de3262..0000000000000000000000000000000000000000 --- a/web/static/js9_old/analysis-plugins/loadProxy.json +++ /dev/null @@ -1,20 +0,0 @@ -[ - {"name" : "loadproxy", - "title" : "Open a Link via Server Proxy", - "files" : "*", - "purl" : "./params/loadproxy.html", - "action" : "js9Xeq loadproxy $url", - "workDir": true, - "hidden" : true, - "rtype" : "fits" - }, - {"name" : "removeproxy", - "title" : "Remove a File from the Proxy Server", - "files" : "*", - "action" : "js9Xeq removeproxy $proxyfile", - "workDir": true, - "hidden" : true, - "rtype" : "fits" - } -] - diff --git a/web/static/js9_old/analysis-plugins/quotacheck.json b/web/static/js9_old/analysis-plugins/quotacheck.json deleted file mode 100644 index c6ba95eef33b7528464ccf596de89d3719549077..0000000000000000000000000000000000000000 --- a/web/static/js9_old/analysis-plugins/quotacheck.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - {"name" : "quotacheck", - "title" : "Check Quota for Remote Analysis", - "files" : "*", - "action" : "js9Xeq quotacheck", - "hidden" : true, - "rtype" : "text"} -] diff --git a/web/static/js9_old/analysis-plugins/uploadfits.json b/web/static/js9_old/analysis-plugins/uploadfits.json deleted file mode 100644 index cd4365299a766d6b9d10fe17fa15c5388e57a7d8..0000000000000000000000000000000000000000 --- a/web/static/js9_old/analysis-plugins/uploadfits.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - {"name" : "uploadfits", - "title" : "Upload a FITS File to the Remote Server", - "files" : "*", - "action" : "js9Xeq uploadfits $uuid", - "workDir": true, - "hidden" : true, - "rtype" : "text" - } -] diff --git a/web/static/js9_old/analysis-wrappers/js9Xeq b/web/static/js9_old/analysis-wrappers/js9Xeq deleted file mode 100755 index 43fd3c1234b1330232c6185f482c41cc466111db..0000000000000000000000000000000000000000 --- a/web/static/js9_old/analysis-wrappers/js9Xeq +++ /dev/null @@ -1,571 +0,0 @@ -#!/bin/bash -# set -x -# exec 2>$HOME/foo.log - -# make sure we have minimum arg count -if [ $# -lt 1 ]; then - echo "$0 [cmd] [args ...]" - exit 1 -fi - -# on entry, the following JS9 environment variables will be available: -# JS9_DIR top level directory of js9 helper -# JS9_WORKDIR working directory, if configured -# JS9_WORKDIR_QUOTA quota for working directory, if configured -# JS9_HOST host ip of client -# JS9_ID id (from js9 div) of client - -#defaults -CHANDRA_BINS="500:8000:1875" -XMM_BINS="400:15000:1825" -XRAY_ELEMENTS='{"text": "O VII", "x": 570, "y": "%Y"}, {"text": "O VIII", "x": 650, "y": "%Y"}, {"text": "Ne X", "x": 1020, "y": "%Y"}, {"text": "Mg XI", "x": 1340, "y": "%Y"}, {"text": "Si XIII", "x": 1850, "y": "%Y"}, {"text": "Si XIV", "x": 2010, "y": "%Y"}, {"text": "S XV", "x": 2450, "y": "%Y"}, {"text": "S XVI", "x": 2620, "y": "%Y"}, {"text": "Ar XVII", "x": 3130, "y": "%Y"}, {"text": "Ar XVIII", "x": 3320, "y": "%Y"}, {"text": "Ca XIX", "x": 3890, "y": "%Y"}, {"text": "Ca XX", "x": 4110, "y": "%Y"}, {"text": "Fe XXV", "x": 6670, "y": "%Y"}' - -# if we are being called via CGI, send stderr to stdout -if [ x"$QUERY_STRING" != x ]; then - exec 2>&1 -fi - -# error handler: send to stderr (which will go to stdout for CGI) -error() { - echo "$*" | egrep "^ERROR:" 1>/dev/null 2>&1 - if [ $? = 0 ]; then - echo "$*" >&2 - else - echo "ERROR: $*" >&2 - fi - exit 1 -} - -xsed() { - sed 's#'${JS9_DIR:-none}'#${JS9_DIR}#g;' -} - -getpar () { - egrep "$1 *=" | awk -F= '{print $2}' | awk -F/ '{print $1}' | sed "s/[' ]*\([^ ']*\)[ ']*/\1/" | tr [a-z] [A-Z] | head -1 -} - -quotacheck () { - if [ x"${JS9_WORKDIR}" = x ]; then - error "task requires configuration of a temporary work directory" - fi - mb=`du -sk . | awk '{printf("%d", ($1 + 500) / 1000)}'` - if [ ${JS9_WORKDIR_QUOTA:-0} -gt 0 ]; then - if [ ${mb:-0} -ge ${JS9_WORKDIR_QUOTA} ]; then - error "disk quota exceeded. Please close a displayed image or remove a proxy file (see File menu)." - fi - fi -} - -# sanity check that we have system programs in the path -hash awk sed egrep du mv rm cat echo 1>/dev/null 2>&1 -if [ $? != 0 ]; then - error "can't find system programs (e.g. awk, sed). Please check the PATH of the JS9 helper." -fi - -# regcnts is preferred -hash regcnts 1>/dev/null 2>&1 -if [ $? = 0 ]; then - CNTS=regcnts -else - hash funcnts 1>/dev/null 2>&1 - if [ $? = 0 ]; then - CNTS=funcnts - else - CNTS="error requires regcnts or funcnts ..." - fi -fi - -# process standard arguments -CMD="$1"; shift; -case $CMD in -counts) - if [ $# -eq 1 ]; then - ${CNTS} "$1" "$2" | xsed - else - ${CNTS} "$1" "$2" "$3" | xsed - fi - exit 0 - ;; - -fits2png) - fits2png $* - exit 0 - ;; - -fitshead) - funhead -a "$1" | xsed - exit 0 - ;; - -hist) - if [ $# -lt 4 ]; then - error "funhist filename norm width [column] [bin] [$#]" - fi - ARGS="" - FILE="$1"; shift - FILE=`echo $FILE | sed 's/\]\[/,/g'` - NORM="$1"; shift; - if [ $NORM = "true" ]; then - ARGS="$ARGS -n" - fi - WIDTH=$1; shift; - if [ $WIDTH = "true" ]; then - ARGS="$ARGS -w" - fi - COL="$1"; shift; - if [ "x$COL" = 'x%energy' ]; then - COL="pi"; - TELESCOP=`funhead $FILE | getpar TELESCOP` - case "$TELESCOP" in - CHANDRA) - COL="energy" - if [ x"$BINS" = x0 ]; then - BINS="${CHANDRA_BINS}" - fi - ;; - XMM) - if [ x"$BINS" = x0 ]; then - BINS="${XMM_BINS}" - fi - ;; - esac - fi - if [ $# -eq 0 ]; then - funhist $ARGS "$FILE" "$COL" | xsed - else - funhist $ARGS "$FILE" "$COL" "$1" | xsed - fi - exit 0 - ;; - -radialplot) - if [ $# -lt 2 ]; then - error "${CNTS} filename [source] [bkgd] [$#]" - fi - if [ x"$2" = x ]; then - error "please specify an annulus region for the source" - fi - echo "$2" | egrep 'box|circle|ellipse|line|point|poly' 1>/dev/null 2>&1 - if [ $? = 0 ]; then - error "please specify an annulus region (only) for the source" - fi - if [ $# -eq 1 ]; then - ${CNTS} -rG "$1" "$2" | funcnts2flot | xsed - else - ${CNTS} -rG "$1" "$2" "$3" | funcnts2flot | xsed - fi - exit 0 - ;; - -histplot) - if [ $# -lt 4 ]; then - error "funhist filename norm width [column] [bin] [$#]" - fi - ARGS="" - FILE="$1"; shift; - FILE=`echo $FILE | sed 's/\]\[/,/g'` - NORM="$1"; shift; - if [ $NORM = "true" ]; then - ARGS="$ARGS -n" - fi - WIDTH=$1; shift - if [ $WIDTH = "true" ]; then - if [ "x$2" = x0 ]; then - error "please don't use a bin width of 0" - fi - ARGS="$ARGS -w" - fi - COL="$1"; shift; - BINS="$1" - TELESCOP=`funhead $FILE | getpar TELESCOP` - YAXIS="counts" - XAXIS="${COL} bin" - if [ "x$COL" = 'x%energy' ]; then - COL="pi"; - XAXIS="${COL} bin" - case "$TELESCOP" in - CHANDRA) - COL="energy" - if [ x"$BINS" = x0 ]; then - BINS="${CHANDRA_BINS}" - fi - XAXIS="${COL} (ev)" - ANNOTATE="${XRAY_ELEMENTS}" - ;; - XMM) - if [ x"$BINS" = x0 ]; then - BINS="${XMM_BINS}" - fi - XAXIS="${COL} (ev)" - ;; - esac - elif [ "x$COL" = 'x%time' ]; then - COL="time" - XAXIS="${COL}" - case "$TELESCOP" in - CHANDRA|EINSTEIN|XMM) - COL="time" - XAXIS="time (sec)" - ;; - esac - fi - TITLE="$YAXIS vs. $XAXIS" - if [ x"$BINS" = "x0" ]; then - funhist $ARGS "$FILE" "$COL" | \ - funhist2flot -a "$ANNOTATE" -t "$TITLE" | xsed - else - funhist $ARGS "$FILE" "$COL" "$BINS" | \ - funhist2flot -a "$ANNOTATE" -t "$TITLE" | xsed - fi - exit 0 - ;; - -evfilter) - # required args - if [ "$#" -lt 3 ]; then - error "evfilter ifile filter cen dims [$*]" - fi - # make sure we are not over quota - quotacheck - # input file - IFILE="$1"; shift - # get filter, remove spaces - FILTER=`echo $1 | sed 's/ //g;s/__ampersand__/\&/g'`; shift - CEN="$1"; shift - # get dims - DIMS="$1"; shift - # make up funtools image section extension from cen and dims - X=`echo $CEN | awk -F, '{print $1}'` - Y=`echo $CEN | awk -F, '{print $2}'` - EXT="[$DIMS@$X,$DIMS@$Y]" - # try to get a base name for output - IBASE=`basename "$IFILE" | sed 's/\.gz$//' | sed 's/\.fits$//' | sed 's/\.ftz$//'` - # make up unique output file base - OBASE=`echo ${IBASE}_${FILTER} | sed 's/\[.*\]//g' | awk -F/ '{print $NF}' | sed 's/[,<>$&|!\*@]/_/g'` - # make up new filter ... might need to combine with old filter - echo "$IFILE" | egrep '\]\[' 1>/dev/null 2>&1 - if [ $? = 0 ]; then - # remove closing bracket from old filter - X=`echo $IFILE | sed 's/\]$//'` - # append new filter onto old filter - IFILEX="${X}&&$FILTER]" - else - IFILEX="${IFILE}[$FILTER]" - fi - # create the filtered FITS event file - funtable $IFILEX ${OBASE}.fits >& err.log - if [ $? != 0 ]; then - error "`cat err.log`" - fi - # create a smaller representation file for display - funimage ${OBASE}.fits"$EXT" stdout | gzip -c > ${OBASE}.fits.gz - if [ $? != 0 ]; then - error "`cat err.log`" - fi - # send representation file and parent file - echo "${JS9_WORKDIR}/${OBASE}.fits.gz ${JS9_WORKDIR}/${OBASE}.fits" - exit 0 - ;; - -imsection) - # optional args - while [ x"$1" != x ]; do - case $1 in - -parent) DOPARENT=1 - shift - continue;; - *) break;; - esac - done - # required args - if [ "$#" -lt 2 ]; then - error "imsection file section filter slice" - fi - hash js9helper 1>/dev/null 2>&1 - if [ $? != 0 ]; then - error "for imsection support, please build and install js9helper" - fi - # gzip files - DOGZIP=1 - # input file - IFILE="$1" - # get section - SECTION="$2"; - # get filter - FILTER="$3" - # get filter - SLICE="$4" - # false means no filter - if [ "$FILTER" = "false" ]; then - FILTER="" - fi - # try to get a base name for output - IBASE=`basename "$IFILE" | sed 's/\.gz$//' | sed 's/\.fits$//' | sed 's/\.ftz$//'` - OBASE=`echo ${IBASE}_${SECTION} | sed 's/\[.*\]//g' | awk -F/ '{print $NF}' | sed 's/[,@]/_/g'` - if [ x$DOGZIP = x1 ]; then - OFILE=${OBASE}.fits.gz - fi - # make sure we are not over quota - quotacheck - # send back relative path to the output file - echo "${JS9_WORKDIR}/${OFILE}" - # run imsection in the js9helper to generate a FITS image - # (and send back json with useful info) - js9helper -i "$IFILE" imsection \!"$OFILE" "$SECTION" "$FILTER" "$SLICE" - if [ x$DOPARENT = x1 ]; then - # send parent file, so analysis is performed on the original file - echo "${IFILE}" | xsed - fi - exit 0 - ;; - -listhdus) - # required args - if [ "$#" -lt 1 ]; then - error "listhdus file" - fi - hash js9helper 1>/dev/null 2>&1 - if [ $? != 0 ]; then - error "for listhdus support, please build and install js9helper" - fi - IFILE="$1" - js9helper -i "$IFILE" listhdus - ;; - -loadproxy) - # required args - if [ "$#" -lt 1 ]; then - error "loadproxy url" - fi - # make sure we are not over quota - quotacheck - URL=`echo $1 | sed 's/__ampersand__/\&/g'` - if [ x"$2" != x ]; then - OFILE="$2" - else - OFILE=`basename "$URL" | sed 's/\?.*//g;s/ *//g;s/%[0-9A-Fa-f][0-9A-Fa-f]//g'` - fi - # hack for google drive - if [ x"$OFILE" = xuc ]; then - OFILE="google_"$RANDOM".fits" - fi - # proxy - if [ x"$JS9_PROXY" != x ]; then - export http_proxy="$JS9_PROXY" - export https_proxy="$http_proxy" - export ftp_proxy="$http_proxy" - fi - # retrieve the FITS file via URL - hash wget 1>/dev/null 2>&1 - if [ $? = 0 ]; then - XFUNC="wget" - wget -q --output-document="$OFILE" "$URL" - else - hash curl 1>/dev/null 2>&1 - if [ $? = 0 ]; then - XFUNC="curl" - curl -s -o "$OFILE" "$URL" - else - error "requires either wget or curl" - fi - fi - if [ $? != 0 ]; then - error "could not retrieve: $URL" - else - s=`file $OFILE` - f=`echo $s | egrep "HTML document text" 1>/dev/null 2>&1` - if [ $? = 0 ]; then - f=`cat $OFILE | sed -n 's/.*\(The document has moved\) /dev/null 2>&1 - if [ $? = 0 ]; then - # look for original file + .gz (unless ofile was specified) - if [ x"$2" = x ]; then - f=`echo "$URL" | sed -n 's/.*=\([^=]*\.fits\{0,1\}\).*/\1/gp'` - if [ x"$f" != x ]; then - ext="${f##*.}" - if [ x"$ext" = xgz ]; then - NFILE="$f" - else - NFILE="$f".gz - fi - if [ x"$NFILE" != x"$OFILE" ]; then - mv $OFILE $NFILE && OFILE="$NFILE" - fi - fi - fi - else - # better be a known image file type - f=`echo $s | egrep -o '(FITS|JPEG|PNG) image data' | awk '{print $1}'` - case "$f" in - FITS|JPEG|PNG) - ;; - *) rm -rf $OFILE - error "$OFILE is not a FITS, JPEG, or PNG image file" - ;; - esac - fi - fi - # special case: in chandra archive, check for rep file generation request - echo $URL | egrep 'https://cxc.cfa.harvard.edu/cdaftp/.*_evt2.fits.gz\?repfile=true' 1>/dev/null 2>&1 - if [ $? = 0 ]; then - hash funhead 1>/dev/null 2>&1 - if [ $? = 0 ]; then - RFILE=`echo $OFILE | sed s#evt2#img#` - # which chandra inst? - INST=`funhead $OFILE | getpar INSTRUME` - # generate a rep file - case "$INST" in - HRC) - DET=`funhead $OFILE | getpar DETNAM` - case "$DET" in - HRC-S) - XCEN=32768 - YCEN=32768 - XDIM=4096 - YDIM=4096 - BLOCK=4 - BITPIX=32 - ;; - HRC-I) - XCEN=16384 - YCEN=16384 - XDIM=4096 - YDIM=4096 - BLOCK=4 - BITPIX=32 - ;; - esac - ;; - ACIS) - XCEN=4096 - YCEN=4096 - XDIM=4096 - YDIM=4096 - BLOCK=4 - BITPIX=32 - ;; - esac - if [ x$BITPIX != x ]; then - (funimage $OFILE"[$XDIM@$XCEN,$YDIM@$YCEN,$BLOCK]" stdout bitpix=$BITPIX | gzip -c > $RFILE) 2>/dev/null - if [ $? = 0 ]; then - # tell JS9 the rep name to load, along with downloaded parent - echo "${JS9_WORKDIR}/$RFILE ${JS9_WORKDIR}/$OFILE" - exit 0 - else - error "couldn't generate FITS representation file for $OFILE" - fi - fi - fi - fi - # special case: in chandra archive, check for parent file request - echo $URL | egrep 'https://cxc.cfa.harvard.edu/cdaftp/.*_img2.fits.gz\?parent=true' 1>/dev/null 2>&1 - if [ $? = 0 ]; then - PFILE=`echo $OFILE | sed s#full_img2#evt2# | sed s#cntr_img2#evt2#` - # and load the parent file asynchronously - PURL=`echo $URL | sed s#full_img2#evt2# | sed s#cntr_img2#evt2#` - # retrieve the parent file - if [ x$XFUNC = "xwget" ]; then - wget -q --output-document="$PFILE" "$PURL" - else - curl -s -o "$PFILE" "$PURL" - fi - if [ $? != 0 ]; then - error "could not retrieve parent file: $URL" - fi - # tell JS9 the new file name to load, along with parent file name - echo "${JS9_WORKDIR}/$OFILE ${JS9_WORKDIR}/$PFILE" - exit 0 - fi - fi - # tell JS9 the new file name to load (no parent file) - echo "${JS9_WORKDIR}/$OFILE" - exit 0 - ;; - -removeproxy) - # required args - if [ "$#" -lt 1 ]; then - error "removeproxy file" - fi - if [ x"${JS9_WORKDIR}" = x ]; then - error "removeproxy requires a temporary work directory" - fi - # remove file(s) from our working directory, but ignore errors - while [ x"$1" != x ]; do - PROXY=`echo $1 | sed 's/__ampersand__/\&/g'` - FILE=`basename "$PROXY"` - rm -f "$FILE" - shift - done - echo "OK" - exit 0 - ;; - -uploadfits) - # required args - if [ "$#" -lt 1 ]; then - error "uploadfits filename" - fi - FNAME="$1" - # make sure we are not over quota - quotacheck - # save stdin as a file - cat > "$FNAME" - # tell JS9 the new pathname - echo "${JS9_WORKDIR}/$FNAME" - exit 0 - ;; - -quotacheck) - # make sure we are not over quota - quotacheck - echo "OK ${JS9_WORKDIR_QUOTA:-0}" - exit 0 - ;; - -macros) - echo " - image: [$1] - file/parent: [$2] - file/this: [$3] - ext: [$4] - imcen: [$5] - wcscen: [$6] - id: [$7] - foo: [$8] (not expanded) - sregions: [$9] - bregions: [${10}] - reg(wcs): [${11}] - reg(phy): [${12}] - string1: [${13}] (passed on command line)" - exit 0 - ;; - -*) - error "unknown function: $CMD" - ;; -esac diff --git a/web/static/js9_old/astroem.js b/web/static/js9_old/astroem.js deleted file mode 100644 index cdc4ee00a8163f2bf576cf46470a1d3beed9d1e1..0000000000000000000000000000000000000000 --- a/web/static/js9_old/astroem.js +++ /dev/null @@ -1,159 +0,0 @@ - -// astroem.js: astronomy/astrophysics utilities compiled to javascript -// see: https://github.com/kripken/emscripten -var Module=typeof Module!="undefined"?Module:{};var Module;if(typeof Module!=="object"){Module={}}Module["noExitRuntime"]=true;Module["onRuntimeInitialized"]=function(){if(window.jQuery){if(Module["astroemReady"]){$(document).trigger("astroem:ready",{status:"OK"})}else{Module["astroemReady"]=true}}};var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;function logExceptionOnExit(e){if(e instanceof ExitStatus)return;let toLog=e;err("exiting due to exception: "+toLog)}var fs;var nodePath;var requireNodeFS;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}requireNodeFS=()=>{if(!nodePath){fs=require("fs");nodePath=require("path")}};read_=function shell_read(filename,binary){var ret=tryParseAsDataURI(filename);if(ret){return binary?ret:ret.toString()}requireNodeFS();filename=nodePath["normalize"](filename);return fs.readFileSync(filename,binary?undefined:"utf8")};readBinary=filename=>{var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}return ret};readAsync=(filename,onload,onerror)=>{var ret=tryParseAsDataURI(filename);if(ret){onload(ret)}requireNodeFS();filename=nodePath["normalize"](filename);fs.readFile(filename,function(err,data){if(err)onerror(err);else onload(data.buffer)})};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);if(typeof module!="undefined"){module["exports"]=Module}process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",function(reason){throw reason});quit_=(status,toThrow)=>{if(keepRuntimeAlive()){process["exitCode"]=status;throw toThrow}logExceptionOnExit(toThrow);process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=url=>{try{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText}catch(err){var data=tryParseAsDataURI(url);if(data){return intArrayToString(data)}throw err}};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{try{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}catch(err){var data=tryParseAsDataURI(url);if(data){return data}throw err}}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}var data=tryParseAsDataURI(url);if(data){onload(data.buffer);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=title=>document.title=title}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var tempRet0=0;var setTempRet0=value=>{tempRet0=value};var getTempRet0=()=>tempRet0;var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||true;var WebAssembly={Memory:function(opts){this.buffer=new ArrayBuffer(opts["initial"]*65536)},Module:function(binary){},Instance:function(module,info){this.exports=( -// EMSCRIPTEN_START_ASM -function instantiate(Ta){function c(d){d.set=function(a,b){this[a]=b};d.get=function(a){return this[a]};return d}var e;var f=new Uint8Array(123);for(var a=25;a>=0;--a){f[48+a]=52+a;f[65+a]=a;f[97+a]=26+a}f[43]=62;f[47]=63;function l(m,n,o){var g,h,a=0,i=n,j=o.length,k=n+(j*3>>2)-(o[j-2]=="=")-(o[j-1]=="=");for(;a>4;if(i>2;if(i>>0<=299){b:{switch(a|0){case 0:a=H[10653]|H[10654]<<8|(H[10655]<<16|H[10656]<<24);c=H[10649]|H[10650]<<8|(H[10651]<<16|H[10652]<<24);E[b+6|0]=c;E[b+7|0]=c>>>8;E[b+8|0]=c>>>16;E[b+9|0]=c>>>24;E[b+10|0]=a;E[b+11|0]=a>>>8;E[b+12|0]=a>>>16;E[b+13|0]=a>>>24;a=H[10647]|H[10648]<<8|(H[10649]<<16|H[10650]<<24);c=H[10643]|H[10644]<<8|(H[10645]<<16|H[10646]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 1:a=H[10731]|H[10732]<<8;E[b+24|0]=a;E[b+25|0]=a>>>8;a=H[10727]|H[10728]<<8|(H[10729]<<16|H[10730]<<24);c=H[10723]|H[10724]<<8|(H[10725]<<16|H[10726]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[10719]|H[10720]<<8|(H[10721]<<16|H[10722]<<24);c=H[10715]|H[10716]<<8|(H[10717]<<16|H[10718]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[10711]|H[10712]<<8|(H[10713]<<16|H[10714]<<24);c=H[10707]|H[10708]<<8|(H[10709]<<16|H[10710]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 101:a=H[7700]|H[7701]<<8|(H[7702]<<16|H[7703]<<24);E[b+24|0]=a;E[b+25|0]=a>>>8;E[b+26|0]=a>>>16;E[b+27|0]=a>>>24;a=H[7696]|H[7697]<<8|(H[7698]<<16|H[7699]<<24);c=H[7692]|H[7693]<<8|(H[7694]<<16|H[7695]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[7688]|H[7689]<<8|(H[7690]<<16|H[7691]<<24);c=H[7684]|H[7685]<<8|(H[7686]<<16|H[7687]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[7680]|H[7681]<<8|(H[7682]<<16|H[7683]<<24);c=H[7676]|H[7677]<<8|(H[7678]<<16|H[7679]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 103:a=H[7672]|H[7673]<<8|(H[7674]<<16|H[7675]<<24);c=H[7668]|H[7669]<<8|(H[7670]<<16|H[7671]<<24);E[b+23|0]=c;E[b+24|0]=c>>>8;E[b+25|0]=c>>>16;E[b+26|0]=c>>>24;E[b+27|0]=a;E[b+28|0]=a>>>8;E[b+29|0]=a>>>16;E[b+30|0]=a>>>24;a=H[7665]|H[7666]<<8|(H[7667]<<16|H[7668]<<24);c=H[7661]|H[7662]<<8|(H[7663]<<16|H[7664]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[7657]|H[7658]<<8|(H[7659]<<16|H[7660]<<24);c=H[7653]|H[7654]<<8|(H[7655]<<16|H[7656]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[7649]|H[7650]<<8|(H[7651]<<16|H[7652]<<24);c=H[7645]|H[7646]<<8|(H[7647]<<16|H[7648]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 104:a=H[22507]|H[22508]<<8|(H[22509]<<16|H[22510]<<24);c=H[22503]|H[22504]<<8|(H[22505]<<16|H[22506]<<24);E[b+22|0]=c;E[b+23|0]=c>>>8;E[b+24|0]=c>>>16;E[b+25|0]=c>>>24;E[b+26|0]=a;E[b+27|0]=a>>>8;E[b+28|0]=a>>>16;E[b+29|0]=a>>>24;a=H[22501]|H[22502]<<8|(H[22503]<<16|H[22504]<<24);c=H[22497]|H[22498]<<8|(H[22499]<<16|H[22500]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[22493]|H[22494]<<8|(H[22495]<<16|H[22496]<<24);c=H[22489]|H[22490]<<8|(H[22491]<<16|H[22492]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[22485]|H[22486]<<8|(H[22487]<<16|H[22488]<<24);c=H[22481]|H[22482]<<8|(H[22483]<<16|H[22484]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 105:a=H[22538]|H[22539]<<8|(H[22540]<<16|H[22541]<<24);c=H[22534]|H[22535]<<8|(H[22536]<<16|H[22537]<<24);E[b+23|0]=c;E[b+24|0]=c>>>8;E[b+25|0]=c>>>16;E[b+26|0]=c>>>24;E[b+27|0]=a;E[b+28|0]=a>>>8;E[b+29|0]=a>>>16;E[b+30|0]=a>>>24;a=H[22531]|H[22532]<<8|(H[22533]<<16|H[22534]<<24);c=H[22527]|H[22528]<<8|(H[22529]<<16|H[22530]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[22523]|H[22524]<<8|(H[22525]<<16|H[22526]<<24);c=H[22519]|H[22520]<<8|(H[22521]<<16|H[22522]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[22515]|H[22516]<<8|(H[22517]<<16|H[22518]<<24);c=H[22511]|H[22512]<<8|(H[22513]<<16|H[22514]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 106:a=H[22565]|H[22566]<<8|(H[22567]<<16|H[22568]<<24);E[b+23|0]=a;E[b+24|0]=a>>>8;E[b+25|0]=a>>>16;E[b+26|0]=a>>>24;a=H[22562]|H[22563]<<8|(H[22564]<<16|H[22565]<<24);c=H[22558]|H[22559]<<8|(H[22560]<<16|H[22561]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[22554]|H[22555]<<8|(H[22556]<<16|H[22557]<<24);c=H[22550]|H[22551]<<8|(H[22552]<<16|H[22553]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[22546]|H[22547]<<8|(H[22548]<<16|H[22549]<<24);c=H[22542]|H[22543]<<8|(H[22544]<<16|H[22545]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 107:a=H[22160]|H[22161]<<8|(H[22162]<<16|H[22163]<<24);c=H[22156]|H[22157]<<8|(H[22158]<<16|H[22159]<<24);E[b+23|0]=c;E[b+24|0]=c>>>8;E[b+25|0]=c>>>16;E[b+26|0]=c>>>24;E[b+27|0]=a;E[b+28|0]=a>>>8;E[b+29|0]=a>>>16;E[b+30|0]=a>>>24;a=H[22153]|H[22154]<<8|(H[22155]<<16|H[22156]<<24);c=H[22149]|H[22150]<<8|(H[22151]<<16|H[22152]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[22145]|H[22146]<<8|(H[22147]<<16|H[22148]<<24);c=H[22141]|H[22142]<<8|(H[22143]<<16|H[22144]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[22137]|H[22138]<<8|(H[22139]<<16|H[22140]<<24);c=H[22133]|H[22134]<<8|(H[22135]<<16|H[22136]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 108:a=H[22594]|H[22595]<<8|(H[22596]<<16|H[22597]<<24);c=H[22590]|H[22591]<<8|(H[22592]<<16|H[22593]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[22589]|H[22590]<<8|(H[22591]<<16|H[22592]<<24);c=H[22585]|H[22586]<<8|(H[22587]<<16|H[22588]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[22581]|H[22582]<<8|(H[22583]<<16|H[22584]<<24);c=H[22577]|H[22578]<<8|(H[22579]<<16|H[22580]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[22573]|H[22574]<<8|(H[22575]<<16|H[22576]<<24);c=H[22569]|H[22570]<<8|(H[22571]<<16|H[22572]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 110:E[b+24|0]=H[22276];a=H[22272]|H[22273]<<8|(H[22274]<<16|H[22275]<<24);c=H[22268]|H[22269]<<8|(H[22270]<<16|H[22271]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[22264]|H[22265]<<8|(H[22266]<<16|H[22267]<<24);c=H[22260]|H[22261]<<8|(H[22262]<<16|H[22263]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[22256]|H[22257]<<8|(H[22258]<<16|H[22259]<<24);c=H[22252]|H[22253]<<8|(H[22254]<<16|H[22255]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 111:E[b+24|0]=H[18017];a=H[18013]|H[18014]<<8|(H[18015]<<16|H[18016]<<24);c=H[18009]|H[18010]<<8|(H[18011]<<16|H[18012]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[18005]|H[18006]<<8|(H[18007]<<16|H[18008]<<24);c=H[18001]|H[18002]<<8|(H[18003]<<16|H[18004]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[17997]|H[17998]<<8|(H[17999]<<16|H[18e3]<<24);c=H[17993]|H[17994]<<8|(H[17995]<<16|H[17996]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 112:a=H[21875]|H[21876]<<8|(H[21877]<<16|H[21878]<<24);c=H[21871]|H[21872]<<8|(H[21873]<<16|H[21874]<<24);E[b+22|0]=c;E[b+23|0]=c>>>8;E[b+24|0]=c>>>16;E[b+25|0]=c>>>24;E[b+26|0]=a;E[b+27|0]=a>>>8;E[b+28|0]=a>>>16;E[b+29|0]=a>>>24;a=H[21869]|H[21870]<<8|(H[21871]<<16|H[21872]<<24);c=H[21865]|H[21866]<<8|(H[21867]<<16|H[21868]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[21861]|H[21862]<<8|(H[21863]<<16|H[21864]<<24);c=H[21857]|H[21858]<<8|(H[21859]<<16|H[21860]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[21853]|H[21854]<<8|(H[21855]<<16|H[21856]<<24);c=H[21849]|H[21850]<<8|(H[21851]<<16|H[21852]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 113:a=H[3259]|H[3260]<<8;E[b+24|0]=a;E[b+25|0]=a>>>8;a=H[3255]|H[3256]<<8|(H[3257]<<16|H[3258]<<24);c=H[3251]|H[3252]<<8|(H[3253]<<16|H[3254]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[3247]|H[3248]<<8|(H[3249]<<16|H[3250]<<24);c=H[3243]|H[3244]<<8|(H[3245]<<16|H[3246]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[3239]|H[3240]<<8|(H[3241]<<16|H[3242]<<24);c=H[3235]|H[3236]<<8|(H[3237]<<16|H[3238]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 114:E[b+24|0]=H[11016];a=H[11012]|H[11013]<<8|(H[11014]<<16|H[11015]<<24);c=H[11008]|H[11009]<<8|(H[11010]<<16|H[11011]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[11004]|H[11005]<<8|(H[11006]<<16|H[11007]<<24);c=H[11e3]|H[11001]<<8|(H[11002]<<16|H[11003]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[10996]|H[10997]<<8|(H[10998]<<16|H[10999]<<24);c=H[10992]|H[10993]<<8|(H[10994]<<16|H[10995]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 115:a=H[10958]|H[10959]<<8|(H[10960]<<16|H[10961]<<24);E[b+15|0]=a;E[b+16|0]=a>>>8;E[b+17|0]=a>>>16;E[b+18|0]=a>>>24;a=H[10955]|H[10956]<<8|(H[10957]<<16|H[10958]<<24);c=H[10951]|H[10952]<<8|(H[10953]<<16|H[10954]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[10947]|H[10948]<<8|(H[10949]<<16|H[10950]<<24);c=H[10943]|H[10944]<<8|(H[10945]<<16|H[10946]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 116:a=H[13971]|H[13972]<<8|(H[13973]<<16|H[13974]<<24);E[b+24|0]=a;E[b+25|0]=a>>>8;E[b+26|0]=a>>>16;E[b+27|0]=a>>>24;a=H[13967]|H[13968]<<8|(H[13969]<<16|H[13970]<<24);c=H[13963]|H[13964]<<8|(H[13965]<<16|H[13966]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[13959]|H[13960]<<8|(H[13961]<<16|H[13962]<<24);c=H[13955]|H[13956]<<8|(H[13957]<<16|H[13958]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[13951]|H[13952]<<8|(H[13953]<<16|H[13954]<<24);c=H[13947]|H[13948]<<8|(H[13949]<<16|H[13950]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 117:a=H[17752]|H[17753]<<8|(H[17754]<<16|H[17755]<<24);E[b+40|0]=a;E[b+41|0]=a>>>8;E[b+42|0]=a>>>16;E[b+43|0]=a>>>24;a=H[17748]|H[17749]<<8|(H[17750]<<16|H[17751]<<24);c=H[17744]|H[17745]<<8|(H[17746]<<16|H[17747]<<24);E[b+32|0]=c;E[b+33|0]=c>>>8;E[b+34|0]=c>>>16;E[b+35|0]=c>>>24;E[b+36|0]=a;E[b+37|0]=a>>>8;E[b+38|0]=a>>>16;E[b+39|0]=a>>>24;a=H[17740]|H[17741]<<8|(H[17742]<<16|H[17743]<<24);c=H[17736]|H[17737]<<8|(H[17738]<<16|H[17739]<<24);E[b+24|0]=c;E[b+25|0]=c>>>8;E[b+26|0]=c>>>16;E[b+27|0]=c>>>24;E[b+28|0]=a;E[b+29|0]=a>>>8;E[b+30|0]=a>>>16;E[b+31|0]=a>>>24;a=H[17732]|H[17733]<<8|(H[17734]<<16|H[17735]<<24);c=H[17728]|H[17729]<<8|(H[17730]<<16|H[17731]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[17724]|H[17725]<<8|(H[17726]<<16|H[17727]<<24);c=H[17720]|H[17721]<<8|(H[17722]<<16|H[17723]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[17716]|H[17717]<<8|(H[17718]<<16|H[17719]<<24);c=H[17712]|H[17713]<<8|(H[17714]<<16|H[17715]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 121:a=H[3770]|H[3771]<<8|(H[3772]<<16|H[3773]<<24);E[b+15|0]=a;E[b+16|0]=a>>>8;E[b+17|0]=a>>>16;E[b+18|0]=a>>>24;a=H[3767]|H[3768]<<8|(H[3769]<<16|H[3770]<<24);c=H[3763]|H[3764]<<8|(H[3765]<<16|H[3766]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[3759]|H[3760]<<8|(H[3761]<<16|H[3762]<<24);c=H[3755]|H[3756]<<8|(H[3757]<<16|H[3758]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 122:a=H[5997]|H[5998]<<8|(H[5999]<<16|H[6e3]<<24);c=H[5993]|H[5994]<<8|(H[5995]<<16|H[5996]<<24);E[b+13|0]=c;E[b+14|0]=c>>>8;E[b+15|0]=c>>>16;E[b+16|0]=c>>>24;E[b+17|0]=a;E[b+18|0]=a>>>8;E[b+19|0]=a>>>16;E[b+20|0]=a>>>24;a=H[5992]|H[5993]<<8|(H[5994]<<16|H[5995]<<24);c=H[5988]|H[5989]<<8|(H[5990]<<16|H[5991]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[5984]|H[5985]<<8|(H[5986]<<16|H[5987]<<24);c=H[5980]|H[5981]<<8|(H[5982]<<16|H[5983]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 123:a=H[29316]|H[29317]<<8|(H[29318]<<16|H[29319]<<24);c=H[29312]|H[29313]<<8|(H[29314]<<16|H[29315]<<24);E[b+15|0]=c;E[b+16|0]=c>>>8;E[b+17|0]=c>>>16;E[b+18|0]=c>>>24;E[b+19|0]=a;E[b+20|0]=a>>>8;E[b+21|0]=a>>>16;E[b+22|0]=a>>>24;a=H[29309]|H[29310]<<8|(H[29311]<<16|H[29312]<<24);c=H[29305]|H[29306]<<8|(H[29307]<<16|H[29308]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[29301]|H[29302]<<8|(H[29303]<<16|H[29304]<<24);c=H[29297]|H[29298]<<8|(H[29299]<<16|H[29300]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 124:a=H[20975]|H[20976]<<8|(H[20977]<<16|H[20978]<<24);c=H[20971]|H[20972]<<8|(H[20973]<<16|H[20974]<<24);E[b+23|0]=c;E[b+24|0]=c>>>8;E[b+25|0]=c>>>16;E[b+26|0]=c>>>24;E[b+27|0]=a;E[b+28|0]=a>>>8;E[b+29|0]=a>>>16;E[b+30|0]=a>>>24;a=H[20968]|H[20969]<<8|(H[20970]<<16|H[20971]<<24);c=H[20964]|H[20965]<<8|(H[20966]<<16|H[20967]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[20960]|H[20961]<<8|(H[20962]<<16|H[20963]<<24);c=H[20956]|H[20957]<<8|(H[20958]<<16|H[20959]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[20952]|H[20953]<<8|(H[20954]<<16|H[20955]<<24);c=H[20948]|H[20949]<<8|(H[20950]<<16|H[20951]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 125:a=H[34736]|H[34737]<<8|(H[34738]<<16|H[34739]<<24);c=H[34732]|H[34733]<<8|(H[34734]<<16|H[34735]<<24);E[b+22|0]=c;E[b+23|0]=c>>>8;E[b+24|0]=c>>>16;E[b+25|0]=c>>>24;E[b+26|0]=a;E[b+27|0]=a>>>8;E[b+28|0]=a>>>16;E[b+29|0]=a>>>24;a=H[34730]|H[34731]<<8|(H[34732]<<16|H[34733]<<24);c=H[34726]|H[34727]<<8|(H[34728]<<16|H[34729]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[34722]|H[34723]<<8|(H[34724]<<16|H[34725]<<24);c=H[34718]|H[34719]<<8|(H[34720]<<16|H[34721]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[34714]|H[34715]<<8|(H[34716]<<16|H[34717]<<24);c=H[34710]|H[34711]<<8|(H[34712]<<16|H[34713]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 126:a=H[4461]|H[4462]<<8;E[b+24|0]=a;E[b+25|0]=a>>>8;a=H[4457]|H[4458]<<8|(H[4459]<<16|H[4460]<<24);c=H[4453]|H[4454]<<8|(H[4455]<<16|H[4456]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[4449]|H[4450]<<8|(H[4451]<<16|H[4452]<<24);c=H[4445]|H[4446]<<8|(H[4447]<<16|H[4448]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[4441]|H[4442]<<8|(H[4443]<<16|H[4444]<<24);c=H[4437]|H[4438]<<8|(H[4439]<<16|H[4440]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 151:a=H[51172]|H[51173]<<8|(H[51174]<<16|H[51175]<<24);c=H[51168]|H[51169]<<8|(H[51170]<<16|H[51171]<<24);E[b+23|0]=c;E[b+24|0]=c>>>8;E[b+25|0]=c>>>16;E[b+26|0]=c>>>24;E[b+27|0]=a;E[b+28|0]=a>>>8;E[b+29|0]=a>>>16;E[b+30|0]=a>>>24;a=H[51165]|H[51166]<<8|(H[51167]<<16|H[51168]<<24);c=H[51161]|H[51162]<<8|(H[51163]<<16|H[51164]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[51157]|H[51158]<<8|(H[51159]<<16|H[51160]<<24);c=H[51153]|H[51154]<<8|(H[51155]<<16|H[51156]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[51149]|H[51150]<<8|(H[51151]<<16|H[51152]<<24);c=H[51145]|H[51146]<<8|(H[51147]<<16|H[51148]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 152:a=H[51203]|H[51204]<<8|(H[51205]<<16|H[51206]<<24);c=H[51199]|H[51200]<<8|(H[51201]<<16|H[51202]<<24);E[b+23|0]=c;E[b+24|0]=c>>>8;E[b+25|0]=c>>>16;E[b+26|0]=c>>>24;E[b+27|0]=a;E[b+28|0]=a>>>8;E[b+29|0]=a>>>16;E[b+30|0]=a>>>24;a=H[51196]|H[51197]<<8|(H[51198]<<16|H[51199]<<24);c=H[51192]|H[51193]<<8|(H[51194]<<16|H[51195]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[51188]|H[51189]<<8|(H[51190]<<16|H[51191]<<24);c=H[51184]|H[51185]<<8|(H[51186]<<16|H[51187]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[51180]|H[51181]<<8|(H[51182]<<16|H[51183]<<24);c=H[51176]|H[51177]<<8|(H[51178]<<16|H[51179]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 153:a=H[7730]|H[7731]<<8|(H[7732]<<16|H[7733]<<24);c=H[7726]|H[7727]<<8|(H[7728]<<16|H[7729]<<24);E[b+22|0]=c;E[b+23|0]=c>>>8;E[b+24|0]=c>>>16;E[b+25|0]=c>>>24;E[b+26|0]=a;E[b+27|0]=a>>>8;E[b+28|0]=a>>>16;E[b+29|0]=a>>>24;a=H[7724]|H[7725]<<8|(H[7726]<<16|H[7727]<<24);c=H[7720]|H[7721]<<8|(H[7722]<<16|H[7723]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[7716]|H[7717]<<8|(H[7718]<<16|H[7719]<<24);c=H[7712]|H[7713]<<8|(H[7714]<<16|H[7715]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[7708]|H[7709]<<8|(H[7710]<<16|H[7711]<<24);c=H[7704]|H[7705]<<8|(H[7706]<<16|H[7707]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 154:a=H[27825]|H[27826]<<8|(H[27827]<<16|H[27828]<<24);c=H[27821]|H[27822]<<8|(H[27823]<<16|H[27824]<<24);E[b+23|0]=c;E[b+24|0]=c>>>8;E[b+25|0]=c>>>16;E[b+26|0]=c>>>24;E[b+27|0]=a;E[b+28|0]=a>>>8;E[b+29|0]=a>>>16;E[b+30|0]=a>>>24;a=H[27818]|H[27819]<<8|(H[27820]<<16|H[27821]<<24);c=H[27814]|H[27815]<<8|(H[27816]<<16|H[27817]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[27810]|H[27811]<<8|(H[27812]<<16|H[27813]<<24);c=H[27806]|H[27807]<<8|(H[27808]<<16|H[27809]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[27802]|H[27803]<<8|(H[27804]<<16|H[27805]<<24);c=H[27798]|H[27799]<<8|(H[27800]<<16|H[27801]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 155:a=H[57918]|H[57919]<<8|(H[57920]<<16|H[57921]<<24);c=H[57914]|H[57915]<<8|(H[57916]<<16|H[57917]<<24);E[b+22|0]=c;E[b+23|0]=c>>>8;E[b+24|0]=c>>>16;E[b+25|0]=c>>>24;E[b+26|0]=a;E[b+27|0]=a>>>8;E[b+28|0]=a>>>16;E[b+29|0]=a>>>24;a=H[57912]|H[57913]<<8|(H[57914]<<16|H[57915]<<24);c=H[57908]|H[57909]<<8|(H[57910]<<16|H[57911]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[57904]|H[57905]<<8|(H[57906]<<16|H[57907]<<24);c=H[57900]|H[57901]<<8|(H[57902]<<16|H[57903]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[57896]|H[57897]<<8|(H[57898]<<16|H[57899]<<24);c=H[57892]|H[57893]<<8|(H[57894]<<16|H[57895]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 156:a=H[51141]|H[51142]<<8|(H[51143]<<16|H[51144]<<24);E[b+24|0]=a;E[b+25|0]=a>>>8;E[b+26|0]=a>>>16;E[b+27|0]=a>>>24;a=H[51137]|H[51138]<<8|(H[51139]<<16|H[51140]<<24);c=H[51133]|H[51134]<<8|(H[51135]<<16|H[51136]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[51129]|H[51130]<<8|(H[51131]<<16|H[51132]<<24);c=H[51125]|H[51126]<<8|(H[51127]<<16|H[51128]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[51121]|H[51122]<<8|(H[51123]<<16|H[51124]<<24);c=H[51117]|H[51118]<<8|(H[51119]<<16|H[51120]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 157:a=H[17146]|H[17147]<<8|(H[17148]<<16|H[17149]<<24);E[b+24|0]=a;E[b+25|0]=a>>>8;E[b+26|0]=a>>>16;E[b+27|0]=a>>>24;a=H[17142]|H[17143]<<8|(H[17144]<<16|H[17145]<<24);c=H[17138]|H[17139]<<8|(H[17140]<<16|H[17141]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[17134]|H[17135]<<8|(H[17136]<<16|H[17137]<<24);c=H[17130]|H[17131]<<8|(H[17132]<<16|H[17133]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[17126]|H[17127]<<8|(H[17128]<<16|H[17129]<<24);c=H[17122]|H[17123]<<8|(H[17124]<<16|H[17125]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 158:a=H[29374]|H[29375]<<8|(H[29376]<<16|H[29377]<<24);c=H[29370]|H[29371]<<8|(H[29372]<<16|H[29373]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[29369]|H[29370]<<8|(H[29371]<<16|H[29372]<<24);c=H[29365]|H[29366]<<8|(H[29367]<<16|H[29368]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[29361]|H[29362]<<8|(H[29363]<<16|H[29364]<<24);c=H[29357]|H[29358]<<8|(H[29359]<<16|H[29360]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[29353]|H[29354]<<8|(H[29355]<<16|H[29356]<<24);c=H[29349]|H[29350]<<8|(H[29351]<<16|H[29352]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 159:a=H[17229]|H[17230]<<8|(H[17231]<<16|H[17232]<<24);c=H[17225]|H[17226]<<8|(H[17227]<<16|H[17228]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[17224]|H[17225]<<8|(H[17226]<<16|H[17227]<<24);c=H[17220]|H[17221]<<8|(H[17222]<<16|H[17223]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[17216]|H[17217]<<8|(H[17218]<<16|H[17219]<<24);c=H[17212]|H[17213]<<8|(H[17214]<<16|H[17215]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[17208]|H[17209]<<8|(H[17210]<<16|H[17211]<<24);c=H[17204]|H[17205]<<8|(H[17206]<<16|H[17207]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 201:a=H[8071]|H[8072]<<8|(H[8073]<<16|H[8074]<<24);E[b+24|0]=a;E[b+25|0]=a>>>8;E[b+26|0]=a>>>16;E[b+27|0]=a>>>24;a=H[8067]|H[8068]<<8|(H[8069]<<16|H[8070]<<24);c=H[8063]|H[8064]<<8|(H[8065]<<16|H[8066]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[8059]|H[8060]<<8|(H[8061]<<16|H[8062]<<24);c=H[8055]|H[8056]<<8|(H[8057]<<16|H[8058]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[8051]|H[8052]<<8|(H[8053]<<16|H[8054]<<24);c=H[8047]|H[8048]<<8|(H[8049]<<16|H[8050]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 202:a=H[11698]|H[11699]<<8|(H[11700]<<16|H[11701]<<24);E[b+24|0]=a;E[b+25|0]=a>>>8;E[b+26|0]=a>>>16;E[b+27|0]=a>>>24;a=H[11694]|H[11695]<<8|(H[11696]<<16|H[11697]<<24);c=H[11690]|H[11691]<<8|(H[11692]<<16|H[11693]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[11686]|H[11687]<<8|(H[11688]<<16|H[11689]<<24);c=H[11682]|H[11683]<<8|(H[11684]<<16|H[11685]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[11678]|H[11679]<<8|(H[11680]<<16|H[11681]<<24);c=H[11674]|H[11675]<<8|(H[11676]<<16|H[11677]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 203:a=H[8363]|H[8364]<<8|(H[8365]<<16|H[8366]<<24);c=H[8359]|H[8360]<<8|(H[8361]<<16|H[8362]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[8358]|H[8359]<<8|(H[8360]<<16|H[8361]<<24);c=H[8354]|H[8355]<<8|(H[8356]<<16|H[8357]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[8350]|H[8351]<<8|(H[8352]<<16|H[8353]<<24);c=H[8346]|H[8347]<<8|(H[8348]<<16|H[8349]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[8342]|H[8343]<<8|(H[8344]<<16|H[8345]<<24);c=H[8338]|H[8339]<<8|(H[8340]<<16|H[8341]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 204:a=H[29270]|H[29271]<<8|(H[29272]<<16|H[29273]<<24);E[b+23|0]=a;E[b+24|0]=a>>>8;E[b+25|0]=a>>>16;E[b+26|0]=a>>>24;a=H[29267]|H[29268]<<8|(H[29269]<<16|H[29270]<<24);c=H[29263]|H[29264]<<8|(H[29265]<<16|H[29266]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[29259]|H[29260]<<8|(H[29261]<<16|H[29262]<<24);c=H[29255]|H[29256]<<8|(H[29257]<<16|H[29258]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[29251]|H[29252]<<8|(H[29253]<<16|H[29254]<<24);c=H[29247]|H[29248]<<8|(H[29249]<<16|H[29250]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 205:a=H[20287]|H[20288]<<8|(H[20289]<<16|H[20290]<<24);c=H[20283]|H[20284]<<8|(H[20285]<<16|H[20286]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[20282]|H[20283]<<8|(H[20284]<<16|H[20285]<<24);c=H[20278]|H[20279]<<8|(H[20280]<<16|H[20281]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[20274]|H[20275]<<8|(H[20276]<<16|H[20277]<<24);c=H[20270]|H[20271]<<8|(H[20272]<<16|H[20273]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[20266]|H[20267]<<8|(H[20268]<<16|H[20269]<<24);c=H[20262]|H[20263]<<8|(H[20264]<<16|H[20265]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 206:a=H[21566]|H[21567]<<8|(H[21568]<<16|H[21569]<<24);c=H[21562]|H[21563]<<8|(H[21564]<<16|H[21565]<<24);E[b+22|0]=c;E[b+23|0]=c>>>8;E[b+24|0]=c>>>16;E[b+25|0]=c>>>24;E[b+26|0]=a;E[b+27|0]=a>>>8;E[b+28|0]=a>>>16;E[b+29|0]=a>>>24;a=H[21560]|H[21561]<<8|(H[21562]<<16|H[21563]<<24);c=H[21556]|H[21557]<<8|(H[21558]<<16|H[21559]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[21552]|H[21553]<<8|(H[21554]<<16|H[21555]<<24);c=H[21548]|H[21549]<<8|(H[21550]<<16|H[21551]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[21544]|H[21545]<<8|(H[21546]<<16|H[21547]<<24);c=H[21540]|H[21541]<<8|(H[21542]<<16|H[21543]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 207:a=H[25609]|H[25610]<<8|(H[25611]<<16|H[25612]<<24);c=H[25605]|H[25606]<<8|(H[25607]<<16|H[25608]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[25604]|H[25605]<<8|(H[25606]<<16|H[25607]<<24);c=H[25600]|H[25601]<<8|(H[25602]<<16|H[25603]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[25596]|H[25597]<<8|(H[25598]<<16|H[25599]<<24);c=H[25592]|H[25593]<<8|(H[25594]<<16|H[25595]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[25588]|H[25589]<<8|(H[25590]<<16|H[25591]<<24);c=H[25584]|H[25585]<<8|(H[25586]<<16|H[25587]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 208:a=H[11670]|H[11671]<<8|(H[11672]<<16|H[11673]<<24);c=H[11666]|H[11667]<<8|(H[11668]<<16|H[11669]<<24);E[b+23|0]=c;E[b+24|0]=c>>>8;E[b+25|0]=c>>>16;E[b+26|0]=c>>>24;E[b+27|0]=a;E[b+28|0]=a>>>8;E[b+29|0]=a>>>16;E[b+30|0]=a>>>24;a=H[11663]|H[11664]<<8|(H[11665]<<16|H[11666]<<24);c=H[11659]|H[11660]<<8|(H[11661]<<16|H[11662]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[11655]|H[11656]<<8|(H[11657]<<16|H[11658]<<24);c=H[11651]|H[11652]<<8|(H[11653]<<16|H[11654]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[11647]|H[11648]<<8|(H[11649]<<16|H[11650]<<24);c=H[11643]|H[11644]<<8|(H[11645]<<16|H[11646]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 209:a=H[4817]|H[4818]<<8|(H[4819]<<16|H[4820]<<24);c=H[4813]|H[4814]<<8|(H[4815]<<16|H[4816]<<24);E[b+23|0]=c;E[b+24|0]=c>>>8;E[b+25|0]=c>>>16;E[b+26|0]=c>>>24;E[b+27|0]=a;E[b+28|0]=a>>>8;E[b+29|0]=a>>>16;E[b+30|0]=a>>>24;a=H[4810]|H[4811]<<8|(H[4812]<<16|H[4813]<<24);c=H[4806]|H[4807]<<8|(H[4808]<<16|H[4809]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[4802]|H[4803]<<8|(H[4804]<<16|H[4805]<<24);c=H[4798]|H[4799]<<8|(H[4800]<<16|H[4801]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[4794]|H[4795]<<8|(H[4796]<<16|H[4797]<<24);c=H[4790]|H[4791]<<8|(H[4792]<<16|H[4793]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 210:a=H[26479]|H[26480]<<8|(H[26481]<<16|H[26482]<<24);c=H[26475]|H[26476]<<8|(H[26477]<<16|H[26478]<<24);E[b+14|0]=c;E[b+15|0]=c>>>8;E[b+16|0]=c>>>16;E[b+17|0]=c>>>24;E[b+18|0]=a;E[b+19|0]=a>>>8;E[b+20|0]=a>>>16;E[b+21|0]=a>>>24;a=H[26473]|H[26474]<<8|(H[26475]<<16|H[26476]<<24);c=H[26469]|H[26470]<<8|(H[26471]<<16|H[26472]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[26465]|H[26466]<<8|(H[26467]<<16|H[26468]<<24);c=H[26461]|H[26462]<<8|(H[26463]<<16|H[26464]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 211:a=H[20038]|H[20039]<<8|(H[20040]<<16|H[20041]<<24);c=H[20034]|H[20035]<<8|(H[20036]<<16|H[20037]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[20033]|H[20034]<<8|(H[20035]<<16|H[20036]<<24);c=H[20029]|H[20030]<<8|(H[20031]<<16|H[20032]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[20025]|H[20026]<<8|(H[20027]<<16|H[20028]<<24);c=H[20021]|H[20022]<<8|(H[20023]<<16|H[20024]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[20017]|H[20018]<<8|(H[20019]<<16|H[20020]<<24);c=H[20013]|H[20014]<<8|(H[20015]<<16|H[20016]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 212:a=H[20124]|H[20125]<<8|(H[20126]<<16|H[20127]<<24);E[b+24|0]=a;E[b+25|0]=a>>>8;E[b+26|0]=a>>>16;E[b+27|0]=a>>>24;a=H[20120]|H[20121]<<8|(H[20122]<<16|H[20123]<<24);c=H[20116]|H[20117]<<8|(H[20118]<<16|H[20119]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[20112]|H[20113]<<8|(H[20114]<<16|H[20115]<<24);c=H[20108]|H[20109]<<8|(H[20110]<<16|H[20111]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[20104]|H[20105]<<8|(H[20106]<<16|H[20107]<<24);c=H[20100]|H[20101]<<8|(H[20102]<<16|H[20103]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 213:a=H[19952]|H[19953]<<8|(H[19954]<<16|H[19955]<<24);c=H[19948]|H[19949]<<8|(H[19950]<<16|H[19951]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[19947]|H[19948]<<8|(H[19949]<<16|H[19950]<<24);c=H[19943]|H[19944]<<8|(H[19945]<<16|H[19946]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[19939]|H[19940]<<8|(H[19941]<<16|H[19942]<<24);c=H[19935]|H[19936]<<8|(H[19937]<<16|H[19938]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[19931]|H[19932]<<8|(H[19933]<<16|H[19934]<<24);c=H[19927]|H[19928]<<8|(H[19929]<<16|H[19930]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 214:a=H[20067]|H[20068]<<8|(H[20069]<<16|H[20070]<<24);c=H[20063]|H[20064]<<8|(H[20065]<<16|H[20066]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[20062]|H[20063]<<8|(H[20064]<<16|H[20065]<<24);c=H[20058]|H[20059]<<8|(H[20060]<<16|H[20061]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[20054]|H[20055]<<8|(H[20056]<<16|H[20057]<<24);c=H[20050]|H[20051]<<8|(H[20052]<<16|H[20053]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[20046]|H[20047]<<8|(H[20048]<<16|H[20049]<<24);c=H[20042]|H[20043]<<8|(H[20044]<<16|H[20045]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 215:a=H[20096]|H[20097]<<8|(H[20098]<<16|H[20099]<<24);c=H[20092]|H[20093]<<8|(H[20094]<<16|H[20095]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[20091]|H[20092]<<8|(H[20093]<<16|H[20094]<<24);c=H[20087]|H[20088]<<8|(H[20089]<<16|H[20090]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[20083]|H[20084]<<8|(H[20085]<<16|H[20086]<<24);c=H[20079]|H[20080]<<8|(H[20081]<<16|H[20082]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[20075]|H[20076]<<8|(H[20077]<<16|H[20078]<<24);c=H[20071]|H[20072]<<8|(H[20073]<<16|H[20074]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 216:a=H[20154]|H[20155]<<8|(H[20156]<<16|H[20157]<<24);c=H[20150]|H[20151]<<8|(H[20152]<<16|H[20153]<<24);E[b+22|0]=c;E[b+23|0]=c>>>8;E[b+24|0]=c>>>16;E[b+25|0]=c>>>24;E[b+26|0]=a;E[b+27|0]=a>>>8;E[b+28|0]=a>>>16;E[b+29|0]=a>>>24;a=H[20148]|H[20149]<<8|(H[20150]<<16|H[20151]<<24);c=H[20144]|H[20145]<<8|(H[20146]<<16|H[20147]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[20140]|H[20141]<<8|(H[20142]<<16|H[20143]<<24);c=H[20136]|H[20137]<<8|(H[20138]<<16|H[20139]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[20132]|H[20133]<<8|(H[20134]<<16|H[20135]<<24);c=H[20128]|H[20129]<<8|(H[20130]<<16|H[20131]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 217:a=H[19720]|H[19721]<<8|(H[19722]<<16|H[19723]<<24);c=H[19716]|H[19717]<<8|(H[19718]<<16|H[19719]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[19712]|H[19713]<<8|(H[19714]<<16|H[19715]<<24);c=H[19708]|H[19709]<<8|(H[19710]<<16|H[19711]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[19704]|H[19705]<<8|(H[19706]<<16|H[19707]<<24);c=H[19700]|H[19701]<<8|(H[19702]<<16|H[19703]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 218:a=H[5412]|H[5413]<<8|(H[5414]<<16|H[5415]<<24);c=H[5408]|H[5409]<<8|(H[5410]<<16|H[5411]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[5404]|H[5405]<<8|(H[5406]<<16|H[5407]<<24);c=H[5400]|H[5401]<<8|(H[5402]<<16|H[5403]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[5396]|H[5397]<<8|(H[5398]<<16|H[5399]<<24);c=H[5392]|H[5393]<<8|(H[5394]<<16|H[5395]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 219:a=H[26196]|H[26197]<<8|(H[26198]<<16|H[26199]<<24);c=H[26192]|H[26193]<<8|(H[26194]<<16|H[26195]<<24);E[b+15|0]=c;E[b+16|0]=c>>>8;E[b+17|0]=c>>>16;E[b+18|0]=c>>>24;E[b+19|0]=a;E[b+20|0]=a>>>8;E[b+21|0]=a>>>16;E[b+22|0]=a>>>24;a=H[26189]|H[26190]<<8|(H[26191]<<16|H[26192]<<24);c=H[26185]|H[26186]<<8|(H[26187]<<16|H[26188]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[26181]|H[26182]<<8|(H[26183]<<16|H[26184]<<24);c=H[26177]|H[26178]<<8|(H[26179]<<16|H[26180]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 220:a=H[20183]|H[20184]<<8|(H[20185]<<16|H[20186]<<24);c=H[20179]|H[20180]<<8|(H[20181]<<16|H[20182]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[20178]|H[20179]<<8|(H[20180]<<16|H[20181]<<24);c=H[20174]|H[20175]<<8|(H[20176]<<16|H[20177]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[20170]|H[20171]<<8|(H[20172]<<16|H[20173]<<24);c=H[20166]|H[20167]<<8|(H[20168]<<16|H[20169]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[20162]|H[20163]<<8|(H[20164]<<16|H[20165]<<24);c=H[20158]|H[20159]<<8|(H[20160]<<16|H[20161]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 221:E[b+24|0]=H[35536];a=H[35532]|H[35533]<<8|(H[35534]<<16|H[35535]<<24);c=H[35528]|H[35529]<<8|(H[35530]<<16|H[35531]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[35524]|H[35525]<<8|(H[35526]<<16|H[35527]<<24);c=H[35520]|H[35521]<<8|(H[35522]<<16|H[35523]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[35516]|H[35517]<<8|(H[35518]<<16|H[35519]<<24);c=H[35512]|H[35513]<<8|(H[35514]<<16|H[35515]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 222:a=H[32946]|H[32947]<<8;E[b+24|0]=a;E[b+25|0]=a>>>8;a=H[32942]|H[32943]<<8|(H[32944]<<16|H[32945]<<24);c=H[32938]|H[32939]<<8|(H[32940]<<16|H[32941]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[32934]|H[32935]<<8|(H[32936]<<16|H[32937]<<24);c=H[32930]|H[32931]<<8|(H[32932]<<16|H[32933]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[32926]|H[32927]<<8|(H[32928]<<16|H[32929]<<24);c=H[32922]|H[32923]<<8|(H[32924]<<16|H[32925]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 223:a=H[33790]|H[33791]<<8|(H[33792]<<16|H[33793]<<24);c=H[33786]|H[33787]<<8|(H[33788]<<16|H[33789]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[33782]|H[33783]<<8|(H[33784]<<16|H[33785]<<24);c=H[33778]|H[33779]<<8|(H[33780]<<16|H[33781]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[33774]|H[33775]<<8|(H[33776]<<16|H[33777]<<24);c=H[33770]|H[33771]<<8|(H[33772]<<16|H[33773]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 224:a=H[8153]|H[8154]<<8|(H[8155]<<16|H[8156]<<24);c=H[8149]|H[8150]<<8|(H[8151]<<16|H[8152]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[8145]|H[8146]<<8|(H[8147]<<16|H[8148]<<24);c=H[8141]|H[8142]<<8|(H[8143]<<16|H[8144]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[8137]|H[8138]<<8|(H[8139]<<16|H[8140]<<24);c=H[8133]|H[8134]<<8|(H[8135]<<16|H[8136]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 225:a=H[34490]|H[34491]<<8|(H[34492]<<16|H[34493]<<24);E[b+23|0]=a;E[b+24|0]=a>>>8;E[b+25|0]=a>>>16;E[b+26|0]=a>>>24;a=H[34487]|H[34488]<<8|(H[34489]<<16|H[34490]<<24);c=H[34483]|H[34484]<<8|(H[34485]<<16|H[34486]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[34479]|H[34480]<<8|(H[34481]<<16|H[34482]<<24);c=H[34475]|H[34476]<<8|(H[34477]<<16|H[34478]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[34471]|H[34472]<<8|(H[34473]<<16|H[34474]<<24);c=H[34467]|H[34468]<<8|(H[34469]<<16|H[34470]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 226:a=H[23441]|H[23442]<<8|(H[23443]<<16|H[23444]<<24);c=H[23437]|H[23438]<<8|(H[23439]<<16|H[23440]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[23433]|H[23434]<<8|(H[23435]<<16|H[23436]<<24);c=H[23429]|H[23430]<<8|(H[23431]<<16|H[23432]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[23425]|H[23426]<<8|(H[23427]<<16|H[23428]<<24);c=H[23421]|H[23422]<<8|(H[23423]<<16|H[23424]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 227:a=H[23212]|H[23213]<<8|(H[23214]<<16|H[23215]<<24);c=H[23208]|H[23209]<<8|(H[23210]<<16|H[23211]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[23204]|H[23205]<<8|(H[23206]<<16|H[23207]<<24);c=H[23200]|H[23201]<<8|(H[23202]<<16|H[23203]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[23196]|H[23197]<<8|(H[23198]<<16|H[23199]<<24);c=H[23192]|H[23193]<<8|(H[23194]<<16|H[23195]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 228:E[b+24|0]=H[26409];a=H[26405]|H[26406]<<8|(H[26407]<<16|H[26408]<<24);c=H[26401]|H[26402]<<8|(H[26403]<<16|H[26404]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[26397]|H[26398]<<8|(H[26399]<<16|H[26400]<<24);c=H[26393]|H[26394]<<8|(H[26395]<<16|H[26396]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[26389]|H[26390]<<8|(H[26391]<<16|H[26392]<<24);c=H[26385]|H[26386]<<8|(H[26387]<<16|H[26388]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 229:E[b+24|0]=H[26434];a=H[26430]|H[26431]<<8|(H[26432]<<16|H[26433]<<24);c=H[26426]|H[26427]<<8|(H[26428]<<16|H[26429]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[26422]|H[26423]<<8|(H[26424]<<16|H[26425]<<24);c=H[26418]|H[26419]<<8|(H[26420]<<16|H[26421]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[26414]|H[26415]<<8|(H[26416]<<16|H[26417]<<24);c=H[26410]|H[26411]<<8|(H[26412]<<16|H[26413]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 230:a=H[26459]|H[26460]<<8;E[b+24|0]=a;E[b+25|0]=a>>>8;a=H[26455]|H[26456]<<8|(H[26457]<<16|H[26458]<<24);c=H[26451]|H[26452]<<8|(H[26453]<<16|H[26454]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[26447]|H[26448]<<8|(H[26449]<<16|H[26450]<<24);c=H[26443]|H[26444]<<8|(H[26445]<<16|H[26446]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[26439]|H[26440]<<8|(H[26441]<<16|H[26442]<<24);c=H[26435]|H[26436]<<8|(H[26437]<<16|H[26438]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 231:a=H[25655]|H[25656]<<8|(H[25657]<<16|H[25658]<<24);c=H[25651]|H[25652]<<8|(H[25653]<<16|H[25654]<<24);E[b+15|0]=c;E[b+16|0]=c>>>8;E[b+17|0]=c>>>16;E[b+18|0]=c>>>24;E[b+19|0]=a;E[b+20|0]=a>>>8;E[b+21|0]=a>>>16;E[b+22|0]=a>>>24;a=H[25648]|H[25649]<<8|(H[25650]<<16|H[25651]<<24);c=H[25644]|H[25645]<<8|(H[25646]<<16|H[25647]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[25640]|H[25641]<<8|(H[25642]<<16|H[25643]<<24);c=H[25636]|H[25637]<<8|(H[25638]<<16|H[25639]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 232:a=H[25632]|H[25633]<<8|(H[25634]<<16|H[25635]<<24);c=H[25628]|H[25629]<<8|(H[25630]<<16|H[25631]<<24);E[b+15|0]=c;E[b+16|0]=c>>>8;E[b+17|0]=c>>>16;E[b+18|0]=c>>>24;E[b+19|0]=a;E[b+20|0]=a>>>8;E[b+21|0]=a>>>16;E[b+22|0]=a>>>24;a=H[25625]|H[25626]<<8|(H[25627]<<16|H[25628]<<24);c=H[25621]|H[25622]<<8|(H[25623]<<16|H[25624]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[25617]|H[25618]<<8|(H[25619]<<16|H[25620]<<24);c=H[25613]|H[25614]<<8|(H[25615]<<16|H[25616]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 233:a=H[15411]|H[15412]<<8|(H[15413]<<16|H[15414]<<24);E[b+24|0]=a;E[b+25|0]=a>>>8;E[b+26|0]=a>>>16;E[b+27|0]=a>>>24;a=H[15407]|H[15408]<<8|(H[15409]<<16|H[15410]<<24);c=H[15403]|H[15404]<<8|(H[15405]<<16|H[15406]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[15399]|H[15400]<<8|(H[15401]<<16|H[15402]<<24);c=H[15395]|H[15396]<<8|(H[15397]<<16|H[15398]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[15391]|H[15392]<<8|(H[15393]<<16|H[15394]<<24);c=H[15387]|H[15388]<<8|(H[15389]<<16|H[15390]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 234:a=H[20009]|H[20010]<<8|(H[20011]<<16|H[20012]<<24);c=H[20005]|H[20006]<<8|(H[20007]<<16|H[20008]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[20004]|H[20005]<<8|(H[20006]<<16|H[20007]<<24);c=H[2e4]|H[20001]<<8|(H[20002]<<16|H[20003]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[19996]|H[19997]<<8|(H[19998]<<16|H[19999]<<24);c=H[19992]|H[19993]<<8|(H[19994]<<16|H[19995]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[19988]|H[19989]<<8|(H[19990]<<16|H[19991]<<24);c=H[19984]|H[19985]<<8|(H[19986]<<16|H[19987]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 235:a=H[15348]|H[15349]<<8|(H[15350]<<16|H[15351]<<24);E[b+23|0]=a;E[b+24|0]=a>>>8;E[b+25|0]=a>>>16;E[b+26|0]=a>>>24;a=H[15345]|H[15346]<<8|(H[15347]<<16|H[15348]<<24);c=H[15341]|H[15342]<<8|(H[15343]<<16|H[15344]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[15337]|H[15338]<<8|(H[15339]<<16|H[15340]<<24);c=H[15333]|H[15334]<<8|(H[15335]<<16|H[15336]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[15329]|H[15330]<<8|(H[15331]<<16|H[15332]<<24);c=H[15325]|H[15326]<<8|(H[15327]<<16|H[15328]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 236:a=H[23339]|H[23340]<<8|(H[23341]<<16|H[23342]<<24);c=H[23335]|H[23336]<<8|(H[23337]<<16|H[23338]<<24);E[b+22|0]=c;E[b+23|0]=c>>>8;E[b+24|0]=c>>>16;E[b+25|0]=c>>>24;E[b+26|0]=a;E[b+27|0]=a>>>8;E[b+28|0]=a>>>16;E[b+29|0]=a>>>24;a=H[23333]|H[23334]<<8|(H[23335]<<16|H[23336]<<24);c=H[23329]|H[23330]<<8|(H[23331]<<16|H[23332]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[23325]|H[23326]<<8|(H[23327]<<16|H[23328]<<24);c=H[23321]|H[23322]<<8|(H[23323]<<16|H[23324]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[23317]|H[23318]<<8|(H[23319]<<16|H[23320]<<24);c=H[23313]|H[23314]<<8|(H[23315]<<16|H[23316]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 237:a=H[21597]|H[21598]<<8|(H[21599]<<16|H[21600]<<24);c=H[21593]|H[21594]<<8|(H[21595]<<16|H[21596]<<24);E[b+23|0]=c;E[b+24|0]=c>>>8;E[b+25|0]=c>>>16;E[b+26|0]=c>>>24;E[b+27|0]=a;E[b+28|0]=a>>>8;E[b+29|0]=a>>>16;E[b+30|0]=a>>>24;a=H[21590]|H[21591]<<8|(H[21592]<<16|H[21593]<<24);c=H[21586]|H[21587]<<8|(H[21588]<<16|H[21589]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[21582]|H[21583]<<8|(H[21584]<<16|H[21585]<<24);c=H[21578]|H[21579]<<8|(H[21580]<<16|H[21581]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[21574]|H[21575]<<8|(H[21576]<<16|H[21577]<<24);c=H[21570]|H[21571]<<8|(H[21572]<<16|H[21573]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 241:a=H[7124]|H[7125]<<8|(H[7126]<<16|H[7127]<<24);c=H[7120]|H[7121]<<8|(H[7122]<<16|H[7123]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[7119]|H[7120]<<8|(H[7121]<<16|H[7122]<<24);c=H[7115]|H[7116]<<8|(H[7117]<<16|H[7118]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[7111]|H[7112]<<8|(H[7113]<<16|H[7114]<<24);c=H[7107]|H[7108]<<8|(H[7109]<<16|H[7110]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[7103]|H[7104]<<8|(H[7105]<<16|H[7106]<<24);c=H[7099]|H[7100]<<8|(H[7101]<<16|H[7102]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 251:a=H[21027]|H[21028]<<8|(H[21029]<<16|H[21030]<<24);E[b+24|0]=a;E[b+25|0]=a>>>8;E[b+26|0]=a>>>16;E[b+27|0]=a>>>24;a=H[21023]|H[21024]<<8|(H[21025]<<16|H[21026]<<24);c=H[21019]|H[21020]<<8|(H[21021]<<16|H[21022]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[21015]|H[21016]<<8|(H[21017]<<16|H[21018]<<24);c=H[21011]|H[21012]<<8|(H[21013]<<16|H[21014]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[21007]|H[21008]<<8|(H[21009]<<16|H[21010]<<24);c=H[21003]|H[21004]<<8|(H[21005]<<16|H[21006]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 252:a=H[34521]|H[34522]<<8|(H[34523]<<16|H[34524]<<24);c=H[34517]|H[34518]<<8|(H[34519]<<16|H[34520]<<24);E[b+23|0]=c;E[b+24|0]=c>>>8;E[b+25|0]=c>>>16;E[b+26|0]=c>>>24;E[b+27|0]=a;E[b+28|0]=a>>>8;E[b+29|0]=a>>>16;E[b+30|0]=a>>>24;a=H[34514]|H[34515]<<8|(H[34516]<<16|H[34517]<<24);c=H[34510]|H[34511]<<8|(H[34512]<<16|H[34513]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[34506]|H[34507]<<8|(H[34508]<<16|H[34509]<<24);c=H[34502]|H[34503]<<8|(H[34504]<<16|H[34505]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[34498]|H[34499]<<8|(H[34500]<<16|H[34501]<<24);c=H[34494]|H[34495]<<8|(H[34496]<<16|H[34497]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 253:E[b+24|0]=H[17055];a=H[17051]|H[17052]<<8|(H[17053]<<16|H[17054]<<24);c=H[17047]|H[17048]<<8|(H[17049]<<16|H[17050]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[17043]|H[17044]<<8|(H[17045]<<16|H[17046]<<24);c=H[17039]|H[17040]<<8|(H[17041]<<16|H[17042]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[17035]|H[17036]<<8|(H[17037]<<16|H[17038]<<24);c=H[17031]|H[17032]<<8|(H[17033]<<16|H[17034]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 254:a=H[17079]|H[17080]<<8|(H[17081]<<16|H[17082]<<24);E[b+23|0]=a;E[b+24|0]=a>>>8;E[b+25|0]=a>>>16;E[b+26|0]=a>>>24;a=H[17076]|H[17077]<<8|(H[17078]<<16|H[17079]<<24);c=H[17072]|H[17073]<<8|(H[17074]<<16|H[17075]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[17068]|H[17069]<<8|(H[17070]<<16|H[17071]<<24);c=H[17064]|H[17065]<<8|(H[17066]<<16|H[17067]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[17060]|H[17061]<<8|(H[17062]<<16|H[17063]<<24);c=H[17056]|H[17057]<<8|(H[17058]<<16|H[17059]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 255:a=H[27726]|H[27727]<<8|(H[27728]<<16|H[27729]<<24);c=H[27722]|H[27723]<<8|(H[27724]<<16|H[27725]<<24);E[b+15|0]=c;E[b+16|0]=c>>>8;E[b+17|0]=c>>>16;E[b+18|0]=c>>>24;E[b+19|0]=a;E[b+20|0]=a>>>8;E[b+21|0]=a>>>16;E[b+22|0]=a>>>24;a=H[27719]|H[27720]<<8|(H[27721]<<16|H[27722]<<24);c=H[27715]|H[27716]<<8|(H[27717]<<16|H[27718]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[27711]|H[27712]<<8|(H[27713]<<16|H[27714]<<24);c=H[27707]|H[27708]<<8|(H[27709]<<16|H[27710]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 261:a=H[25320]|H[25321]<<8;E[b+24|0]=a;E[b+25|0]=a>>>8;a=H[25316]|H[25317]<<8|(H[25318]<<16|H[25319]<<24);c=H[25312]|H[25313]<<8|(H[25314]<<16|H[25315]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[25308]|H[25309]<<8|(H[25310]<<16|H[25311]<<24);c=H[25304]|H[25305]<<8|(H[25306]<<16|H[25307]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[25300]|H[25301]<<8|(H[25302]<<16|H[25303]<<24);c=H[25296]|H[25297]<<8|(H[25298]<<16|H[25299]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 262:a=H[25374]|H[25375]<<8|(H[25376]<<16|H[25377]<<24);E[b+24|0]=a;E[b+25|0]=a>>>8;E[b+26|0]=a>>>16;E[b+27|0]=a>>>24;a=H[25370]|H[25371]<<8|(H[25372]<<16|H[25373]<<24);c=H[25366]|H[25367]<<8|(H[25368]<<16|H[25369]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[25362]|H[25363]<<8|(H[25364]<<16|H[25365]<<24);c=H[25358]|H[25359]<<8|(H[25360]<<16|H[25361]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[25354]|H[25355]<<8|(H[25356]<<16|H[25357]<<24);c=H[25350]|H[25351]<<8|(H[25352]<<16|H[25353]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 263:a=H[19980]|H[19981]<<8|(H[19982]<<16|H[19983]<<24);E[b+24|0]=a;E[b+25|0]=a>>>8;E[b+26|0]=a>>>16;E[b+27|0]=a>>>24;a=H[19976]|H[19977]<<8|(H[19978]<<16|H[19979]<<24);c=H[19972]|H[19973]<<8|(H[19974]<<16|H[19975]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[19968]|H[19969]<<8|(H[19970]<<16|H[19971]<<24);c=H[19964]|H[19965]<<8|(H[19966]<<16|H[19967]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[19960]|H[19961]<<8|(H[19962]<<16|H[19963]<<24);c=H[19956]|H[19957]<<8|(H[19958]<<16|H[19959]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 264:break b;default:break a}}a=H[10988]|H[10989]<<8|(H[10990]<<16|H[10991]<<24);c=H[10984]|H[10985]<<8|(H[10986]<<16|H[10987]<<24);E[b+22|0]=c;E[b+23|0]=c>>>8;E[b+24|0]=c>>>16;E[b+25|0]=c>>>24;E[b+26|0]=a;E[b+27|0]=a>>>8;E[b+28|0]=a>>>16;E[b+29|0]=a>>>24;a=H[10982]|H[10983]<<8|(H[10984]<<16|H[10985]<<24);c=H[10978]|H[10979]<<8|(H[10980]<<16|H[10981]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[10974]|H[10975]<<8|(H[10976]<<16|H[10977]<<24);c=H[10970]|H[10971]<<8|(H[10972]<<16|H[10973]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[10966]|H[10967]<<8|(H[10968]<<16|H[10969]<<24);c=H[10962]|H[10963]<<8|(H[10964]<<16|H[10965]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return}if((a|0)<=599){c:{switch(a-301|0){case 0:a=H[13153]|H[13154]<<8|(H[13155]<<16|H[13156]<<24);E[b+15|0]=a;E[b+16|0]=a>>>8;E[b+17|0]=a>>>16;E[b+18|0]=a>>>24;a=H[13150]|H[13151]<<8|(H[13152]<<16|H[13153]<<24);c=H[13146]|H[13147]<<8|(H[13148]<<16|H[13149]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[13142]|H[13143]<<8|(H[13144]<<16|H[13145]<<24);c=H[13138]|H[13139]<<8|(H[13140]<<16|H[13141]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 1:a=H[8429]|H[8430]<<8|(H[8431]<<16|H[8432]<<24);c=H[8425]|H[8426]<<8|(H[8427]<<16|H[8428]<<24);E[b+23|0]=c;E[b+24|0]=c>>>8;E[b+25|0]=c>>>16;E[b+26|0]=c>>>24;E[b+27|0]=a;E[b+28|0]=a>>>8;E[b+29|0]=a>>>16;E[b+30|0]=a>>>24;a=H[8422]|H[8423]<<8|(H[8424]<<16|H[8425]<<24);c=H[8418]|H[8419]<<8|(H[8420]<<16|H[8421]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[8414]|H[8415]<<8|(H[8416]<<16|H[8417]<<24);c=H[8410]|H[8411]<<8|(H[8412]<<16|H[8413]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[8406]|H[8407]<<8|(H[8408]<<16|H[8409]<<24);c=H[8402]|H[8403]<<8|(H[8404]<<16|H[8405]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 3:a=H[5876]|H[5877]<<8|(H[5878]<<16|H[5879]<<24);c=H[5872]|H[5873]<<8|(H[5874]<<16|H[5875]<<24);E[b+14|0]=c;E[b+15|0]=c>>>8;E[b+16|0]=c>>>16;E[b+17|0]=c>>>24;E[b+18|0]=a;E[b+19|0]=a>>>8;E[b+20|0]=a>>>16;E[b+21|0]=a>>>24;a=H[5870]|H[5871]<<8|(H[5872]<<16|H[5873]<<24);c=H[5866]|H[5867]<<8|(H[5868]<<16|H[5869]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[5862]|H[5863]<<8|(H[5864]<<16|H[5865]<<24);c=H[5858]|H[5859]<<8|(H[5860]<<16|H[5861]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 5:a=H[5559]|H[5560]<<8|(H[5561]<<16|H[5562]<<24);E[b+24|0]=a;E[b+25|0]=a>>>8;E[b+26|0]=a>>>16;E[b+27|0]=a>>>24;a=H[5555]|H[5556]<<8|(H[5557]<<16|H[5558]<<24);c=H[5551]|H[5552]<<8|(H[5553]<<16|H[5554]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[5547]|H[5548]<<8|(H[5549]<<16|H[5550]<<24);c=H[5543]|H[5544]<<8|(H[5545]<<16|H[5546]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[5539]|H[5540]<<8|(H[5541]<<16|H[5542]<<24);c=H[5535]|H[5536]<<8|(H[5537]<<16|H[5538]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 6:a=H[12394]|H[12395]<<8|(H[12396]<<16|H[12397]<<24);c=H[12390]|H[12391]<<8|(H[12392]<<16|H[12393]<<24);E[b+13|0]=c;E[b+14|0]=c>>>8;E[b+15|0]=c>>>16;E[b+16|0]=c>>>24;E[b+17|0]=a;E[b+18|0]=a>>>8;E[b+19|0]=a>>>16;E[b+20|0]=a>>>24;a=H[12389]|H[12390]<<8|(H[12391]<<16|H[12392]<<24);c=H[12385]|H[12386]<<8|(H[12387]<<16|H[12388]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[12381]|H[12382]<<8|(H[12383]<<16|H[12384]<<24);c=H[12377]|H[12378]<<8|(H[12379]<<16|H[12380]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 7:E[b+24|0]=H[12422];a=H[12418]|H[12419]<<8|(H[12420]<<16|H[12421]<<24);c=H[12414]|H[12415]<<8|(H[12416]<<16|H[12417]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[12410]|H[12411]<<8|(H[12412]<<16|H[12413]<<24);c=H[12406]|H[12407]<<8|(H[12408]<<16|H[12409]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[12402]|H[12403]<<8|(H[12404]<<16|H[12405]<<24);c=H[12398]|H[12399]<<8|(H[12400]<<16|H[12401]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 8:a=H[15896]|H[15897]<<8|(H[15898]<<16|H[15899]<<24);c=H[15892]|H[15893]<<8|(H[15894]<<16|H[15895]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[15888]|H[15889]<<8|(H[15890]<<16|H[15891]<<24);c=H[15884]|H[15885]<<8|(H[15886]<<16|H[15887]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[15880]|H[15881]<<8|(H[15882]<<16|H[15883]<<24);c=H[15876]|H[15877]<<8|(H[15878]<<16|H[15879]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 9:E[b+24|0]=H[15875];a=H[15871]|H[15872]<<8|(H[15873]<<16|H[15874]<<24);c=H[15867]|H[15868]<<8|(H[15869]<<16|H[15870]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[15863]|H[15864]<<8|(H[15865]<<16|H[15866]<<24);c=H[15859]|H[15860]<<8|(H[15861]<<16|H[15862]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[15855]|H[15856]<<8|(H[15857]<<16|H[15858]<<24);c=H[15851]|H[15852]<<8|(H[15853]<<16|H[15854]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 10:E[b+24|0]=H[20947];a=H[20943]|H[20944]<<8|(H[20945]<<16|H[20946]<<24);c=H[20939]|H[20940]<<8|(H[20941]<<16|H[20942]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[20935]|H[20936]<<8|(H[20937]<<16|H[20938]<<24);c=H[20931]|H[20932]<<8|(H[20933]<<16|H[20934]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[20927]|H[20928]<<8|(H[20929]<<16|H[20930]<<24);c=H[20923]|H[20924]<<8|(H[20925]<<16|H[20926]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 11:a=H[20921]|H[20922]<<8;E[b+24|0]=a;E[b+25|0]=a>>>8;a=H[20917]|H[20918]<<8|(H[20919]<<16|H[20920]<<24);c=H[20913]|H[20914]<<8|(H[20915]<<16|H[20916]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[20909]|H[20910]<<8|(H[20911]<<16|H[20912]<<24);c=H[20905]|H[20906]<<8|(H[20907]<<16|H[20908]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[20901]|H[20902]<<8|(H[20903]<<16|H[20904]<<24);c=H[20897]|H[20898]<<8|(H[20899]<<16|H[20900]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 13:a=H[29293]|H[29294]<<8|(H[29295]<<16|H[29296]<<24);c=H[29289]|H[29290]<<8|(H[29291]<<16|H[29292]<<24);E[b+15|0]=c;E[b+16|0]=c>>>8;E[b+17|0]=c>>>16;E[b+18|0]=c>>>24;E[b+19|0]=a;E[b+20|0]=a>>>8;E[b+21|0]=a>>>16;E[b+22|0]=a>>>24;a=H[29286]|H[29287]<<8|(H[29288]<<16|H[29289]<<24);c=H[29282]|H[29283]<<8|(H[29284]<<16|H[29285]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[29278]|H[29279]<<8|(H[29280]<<16|H[29281]<<24);c=H[29274]|H[29275]<<8|(H[29276]<<16|H[29277]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 16:a=H[15786]|H[15787]<<8|(H[15788]<<16|H[15789]<<24);c=H[15782]|H[15783]<<8|(H[15784]<<16|H[15785]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[15781]|H[15782]<<8|(H[15783]<<16|H[15784]<<24);c=H[15777]|H[15778]<<8|(H[15779]<<16|H[15780]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[15773]|H[15774]<<8|(H[15775]<<16|H[15776]<<24);c=H[15769]|H[15770]<<8|(H[15771]<<16|H[15772]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[15765]|H[15766]<<8|(H[15767]<<16|H[15768]<<24);c=H[15761]|H[15762]<<8|(H[15763]<<16|H[15764]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 19:a=H[6697]|H[6698]<<8|(H[6699]<<16|H[6700]<<24);c=H[6693]|H[6694]<<8|(H[6695]<<16|H[6696]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[6692]|H[6693]<<8|(H[6694]<<16|H[6695]<<24);c=H[6688]|H[6689]<<8|(H[6690]<<16|H[6691]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[6684]|H[6685]<<8|(H[6686]<<16|H[6687]<<24);c=H[6680]|H[6681]<<8|(H[6682]<<16|H[6683]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[6676]|H[6677]<<8|(H[6678]<<16|H[6679]<<24);c=H[6672]|H[6673]<<8|(H[6674]<<16|H[6675]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 20:a=H[43168]|H[43169]<<8|(H[43170]<<16|H[43171]<<24);c=H[43164]|H[43165]<<8|(H[43166]<<16|H[43167]<<24);E[b+23|0]=c;E[b+24|0]=c>>>8;E[b+25|0]=c>>>16;E[b+26|0]=c>>>24;E[b+27|0]=a;E[b+28|0]=a>>>8;E[b+29|0]=a>>>16;E[b+30|0]=a>>>24;a=H[43161]|H[43162]<<8|(H[43163]<<16|H[43164]<<24);c=H[43157]|H[43158]<<8|(H[43159]<<16|H[43160]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[43153]|H[43154]<<8|(H[43155]<<16|H[43156]<<24);c=H[43149]|H[43150]<<8|(H[43151]<<16|H[43152]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[43145]|H[43146]<<8|(H[43147]<<16|H[43148]<<24);c=H[43141]|H[43142]<<8|(H[43143]<<16|H[43144]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 21:a=H[45304]|H[45305]<<8|(H[45306]<<16|H[45307]<<24);c=H[45300]|H[45301]<<8|(H[45302]<<16|H[45303]<<24);E[b+14|0]=c;E[b+15|0]=c>>>8;E[b+16|0]=c>>>16;E[b+17|0]=c>>>24;E[b+18|0]=a;E[b+19|0]=a>>>8;E[b+20|0]=a>>>16;E[b+21|0]=a>>>24;a=H[45298]|H[45299]<<8|(H[45300]<<16|H[45301]<<24);c=H[45294]|H[45295]<<8|(H[45296]<<16|H[45297]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[45290]|H[45291]<<8|(H[45292]<<16|H[45293]<<24);c=H[45286]|H[45287]<<8|(H[45288]<<16|H[45289]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 22:a=H[41539]|H[41540]<<8|(H[41541]<<16|H[41542]<<24);c=H[41535]|H[41536]<<8|(H[41537]<<16|H[41538]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[41531]|H[41532]<<8|(H[41533]<<16|H[41534]<<24);c=H[41527]|H[41528]<<8|(H[41529]<<16|H[41530]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[41523]|H[41524]<<8|(H[41525]<<16|H[41526]<<24);c=H[41519]|H[41520]<<8|(H[41521]<<16|H[41522]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 39:a=H[23285]|H[23286]<<8|(H[23287]<<16|H[23288]<<24);c=H[23281]|H[23282]<<8|(H[23283]<<16|H[23284]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[23277]|H[23278]<<8|(H[23279]<<16|H[23280]<<24);c=H[23273]|H[23274]<<8|(H[23275]<<16|H[23276]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 40:a=H[13316]|H[13317]<<8|(H[13318]<<16|H[13319]<<24);E[b+24|0]=a;E[b+25|0]=a>>>8;E[b+26|0]=a>>>16;E[b+27|0]=a>>>24;a=H[13312]|H[13313]<<8|(H[13314]<<16|H[13315]<<24);c=H[13308]|H[13309]<<8|(H[13310]<<16|H[13311]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[13304]|H[13305]<<8|(H[13306]<<16|H[13307]<<24);c=H[13300]|H[13301]<<8|(H[13302]<<16|H[13303]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[13296]|H[13297]<<8|(H[13298]<<16|H[13299]<<24);c=H[13292]|H[13293]<<8|(H[13294]<<16|H[13295]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 41:a=H[26157]|H[26158]<<8|(H[26159]<<16|H[26160]<<24);c=H[26153]|H[26154]<<8|(H[26155]<<16|H[26156]<<24);E[b+15|0]=c;E[b+16|0]=c>>>8;E[b+17|0]=c>>>16;E[b+18|0]=c>>>24;E[b+19|0]=a;E[b+20|0]=a>>>8;E[b+21|0]=a>>>16;E[b+22|0]=a>>>24;a=H[26150]|H[26151]<<8|(H[26152]<<16|H[26153]<<24);c=H[26146]|H[26147]<<8|(H[26148]<<16|H[26149]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[26142]|H[26143]<<8|(H[26144]<<16|H[26145]<<24);c=H[26138]|H[26139]<<8|(H[26140]<<16|H[26141]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 42:a=H[26173]|H[26174]<<8|(H[26175]<<16|H[26176]<<24);c=H[26169]|H[26170]<<8|(H[26171]<<16|H[26172]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[26165]|H[26166]<<8|(H[26167]<<16|H[26168]<<24);c=H[26161]|H[26162]<<8|(H[26163]<<16|H[26164]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 43:a=H[27739]|H[27740]<<8|(H[27741]<<16|H[27742]<<24);c=H[27735]|H[27736]<<8|(H[27737]<<16|H[27738]<<24);E[b+5|0]=c;E[b+6|0]=c>>>8;E[b+7|0]=c>>>16;E[b+8|0]=c>>>24;E[b+9|0]=a;E[b+10|0]=a>>>8;E[b+11|0]=a>>>16;E[b+12|0]=a>>>24;a=H[27734]|H[27735]<<8|(H[27736]<<16|H[27737]<<24);c=H[27730]|H[27731]<<8|(H[27732]<<16|H[27733]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 44:a=H[29416]|H[29417]<<8|(H[29418]<<16|H[29419]<<24);c=H[29412]|H[29413]<<8|(H[29414]<<16|H[29415]<<24);E[b+14|0]=c;E[b+15|0]=c>>>8;E[b+16|0]=c>>>16;E[b+17|0]=c>>>24;E[b+18|0]=a;E[b+19|0]=a>>>8;E[b+20|0]=a>>>16;E[b+21|0]=a>>>24;a=H[29410]|H[29411]<<8|(H[29412]<<16|H[29413]<<24);c=H[29406]|H[29407]<<8|(H[29408]<<16|H[29409]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[29402]|H[29403]<<8|(H[29404]<<16|H[29405]<<24);c=H[29398]|H[29399]<<8|(H[29400]<<16|H[29401]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 45:a=H[29435]|H[29436]<<8|(H[29437]<<16|H[29438]<<24);E[b+15|0]=a;E[b+16|0]=a>>>8;E[b+17|0]=a>>>16;E[b+18|0]=a>>>24;a=H[29432]|H[29433]<<8|(H[29434]<<16|H[29435]<<24);c=H[29428]|H[29429]<<8|(H[29430]<<16|H[29431]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[29424]|H[29425]<<8|(H[29426]<<16|H[29427]<<24);c=H[29420]|H[29421]<<8|(H[29422]<<16|H[29423]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 46:a=H[13868]|H[13869]<<8|(H[13870]<<16|H[13871]<<24);E[b+16|0]=a;E[b+17|0]=a>>>8;E[b+18|0]=a>>>16;E[b+19|0]=a>>>24;a=H[13864]|H[13865]<<8|(H[13866]<<16|H[13867]<<24);c=H[13860]|H[13861]<<8|(H[13862]<<16|H[13863]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[13856]|H[13857]<<8|(H[13858]<<16|H[13859]<<24);c=H[13852]|H[13853]<<8|(H[13854]<<16|H[13855]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 47:a=H[50505]|H[50506]<<8|(H[50507]<<16|H[50508]<<24);E[b+24|0]=a;E[b+25|0]=a>>>8;E[b+26|0]=a>>>16;E[b+27|0]=a>>>24;a=H[50501]|H[50502]<<8|(H[50503]<<16|H[50504]<<24);c=H[50497]|H[50498]<<8|(H[50499]<<16|H[50500]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[50493]|H[50494]<<8|(H[50495]<<16|H[50496]<<24);c=H[50489]|H[50490]<<8|(H[50491]<<16|H[50492]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[50485]|H[50486]<<8|(H[50487]<<16|H[50488]<<24);c=H[50481]|H[50482]<<8|(H[50483]<<16|H[50484]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 59:a=H[11171]|H[11172]<<8|(H[11173]<<16|H[11174]<<24);c=H[11167]|H[11168]<<8|(H[11169]<<16|H[11170]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[11163]|H[11164]<<8|(H[11165]<<16|H[11166]<<24);c=H[11159]|H[11160]<<8|(H[11161]<<16|H[11162]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[11155]|H[11156]<<8|(H[11157]<<16|H[11158]<<24);c=H[11151]|H[11152]<<8|(H[11153]<<16|H[11154]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 60:a=H[11149]|H[11150]<<8;E[b+24|0]=a;E[b+25|0]=a>>>8;a=H[11145]|H[11146]<<8|(H[11147]<<16|H[11148]<<24);c=H[11141]|H[11142]<<8|(H[11143]<<16|H[11144]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[11137]|H[11138]<<8|(H[11139]<<16|H[11140]<<24);c=H[11133]|H[11134]<<8|(H[11135]<<16|H[11136]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[11129]|H[11130]<<8|(H[11131]<<16|H[11132]<<24);c=H[11125]|H[11126]<<8|(H[11127]<<16|H[11128]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 61:a=H[51821]|H[51822]<<8;E[b+24|0]=a;E[b+25|0]=a>>>8;a=H[51817]|H[51818]<<8|(H[51819]<<16|H[51820]<<24);c=H[51813]|H[51814]<<8|(H[51815]<<16|H[51816]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[51809]|H[51810]<<8|(H[51811]<<16|H[51812]<<24);c=H[51805]|H[51806]<<8|(H[51807]<<16|H[51808]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[51801]|H[51802]<<8|(H[51803]<<16|H[51804]<<24);c=H[51797]|H[51798]<<8|(H[51799]<<16|H[51800]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 62:a=H[51839]|H[51840]<<8|(H[51841]<<16|H[51842]<<24);E[b+16|0]=a;E[b+17|0]=a>>>8;E[b+18|0]=a>>>16;E[b+19|0]=a>>>24;a=H[51835]|H[51836]<<8|(H[51837]<<16|H[51838]<<24);c=H[51831]|H[51832]<<8|(H[51833]<<16|H[51834]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[51827]|H[51828]<<8|(H[51829]<<16|H[51830]<<24);c=H[51823]|H[51824]<<8|(H[51825]<<16|H[51826]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 63:a=H[21331]|H[21332]<<8|(H[21333]<<16|H[21334]<<24);c=H[21327]|H[21328]<<8|(H[21329]<<16|H[21330]<<24);E[b+15|0]=c;E[b+16|0]=c>>>8;E[b+17|0]=c>>>16;E[b+18|0]=c>>>24;E[b+19|0]=a;E[b+20|0]=a>>>8;E[b+21|0]=a>>>16;E[b+22|0]=a>>>24;a=H[21324]|H[21325]<<8|(H[21326]<<16|H[21327]<<24);c=H[21320]|H[21321]<<8|(H[21322]<<16|H[21323]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[21316]|H[21317]<<8|(H[21318]<<16|H[21319]<<24);c=H[21312]|H[21313]<<8|(H[21314]<<16|H[21315]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 64:E[b+24|0]=H[28009];a=H[28005]|H[28006]<<8|(H[28007]<<16|H[28008]<<24);c=H[28001]|H[28002]<<8|(H[28003]<<16|H[28004]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[27997]|H[27998]<<8|(H[27999]<<16|H[28e3]<<24);c=H[27993]|H[27994]<<8|(H[27995]<<16|H[27996]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[27989]|H[27990]<<8|(H[27991]<<16|H[27992]<<24);c=H[27985]|H[27986]<<8|(H[27987]<<16|H[27988]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 65:a=H[51867]|H[51868]<<8;E[b+24|0]=a;E[b+25|0]=a>>>8;a=H[51863]|H[51864]<<8|(H[51865]<<16|H[51866]<<24);c=H[51859]|H[51860]<<8|(H[51861]<<16|H[51862]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[51855]|H[51856]<<8|(H[51857]<<16|H[51858]<<24);c=H[51851]|H[51852]<<8|(H[51853]<<16|H[51854]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[51847]|H[51848]<<8|(H[51849]<<16|H[51850]<<24);c=H[51843]|H[51844]<<8|(H[51845]<<16|H[51846]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 66:E[b+16|0]=H[51885];a=H[51881]|H[51882]<<8|(H[51883]<<16|H[51884]<<24);c=H[51877]|H[51878]<<8|(H[51879]<<16|H[51880]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[51873]|H[51874]<<8|(H[51875]<<16|H[51876]<<24);c=H[51869]|H[51870]<<8|(H[51871]<<16|H[51872]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 67:a=H[51767]|H[51768]<<8|(H[51769]<<16|H[51770]<<24);c=H[51763]|H[51764]<<8|(H[51765]<<16|H[51766]<<24);E[b+14|0]=c;E[b+15|0]=c>>>8;E[b+16|0]=c>>>16;E[b+17|0]=c>>>24;E[b+18|0]=a;E[b+19|0]=a>>>8;E[b+20|0]=a>>>16;E[b+21|0]=a>>>24;a=H[51761]|H[51762]<<8|(H[51763]<<16|H[51764]<<24);c=H[51757]|H[51758]<<8|(H[51759]<<16|H[51760]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[51753]|H[51754]<<8|(H[51755]<<16|H[51756]<<24);c=H[51749]|H[51750]<<8|(H[51751]<<16|H[51752]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 68:a=H[51795]|H[51796]<<8;E[b+24|0]=a;E[b+25|0]=a>>>8;a=H[51791]|H[51792]<<8|(H[51793]<<16|H[51794]<<24);c=H[51787]|H[51788]<<8|(H[51789]<<16|H[51790]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[51783]|H[51784]<<8|(H[51785]<<16|H[51786]<<24);c=H[51779]|H[51780]<<8|(H[51781]<<16|H[51782]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[51775]|H[51776]<<8|(H[51777]<<16|H[51778]<<24);c=H[51771]|H[51772]<<8|(H[51773]<<16|H[51774]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 100:a=H[15205]|H[15206]<<8|(H[15207]<<16|H[15208]<<24);c=H[15201]|H[15202]<<8|(H[15203]<<16|H[15204]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[15200]|H[15201]<<8|(H[15202]<<16|H[15203]<<24);c=H[15196]|H[15197]<<8|(H[15198]<<16|H[15199]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[15192]|H[15193]<<8|(H[15194]<<16|H[15195]<<24);c=H[15188]|H[15189]<<8|(H[15190]<<16|H[15191]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[15184]|H[15185]<<8|(H[15186]<<16|H[15187]<<24);c=H[15180]|H[15181]<<8|(H[15182]<<16|H[15183]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 101:a=H[15236]|H[15237]<<8|(H[15238]<<16|H[15239]<<24);c=H[15232]|H[15233]<<8|(H[15234]<<16|H[15235]<<24);E[b+23|0]=c;E[b+24|0]=c>>>8;E[b+25|0]=c>>>16;E[b+26|0]=c>>>24;E[b+27|0]=a;E[b+28|0]=a>>>8;E[b+29|0]=a>>>16;E[b+30|0]=a>>>24;a=H[15229]|H[15230]<<8|(H[15231]<<16|H[15232]<<24);c=H[15225]|H[15226]<<8|(H[15227]<<16|H[15228]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[15221]|H[15222]<<8|(H[15223]<<16|H[15224]<<24);c=H[15217]|H[15218]<<8|(H[15219]<<16|H[15220]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[15213]|H[15214]<<8|(H[15215]<<16|H[15216]<<24);c=H[15209]|H[15210]<<8|(H[15211]<<16|H[15212]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 102:a=H[11242]|H[11243]<<8;E[b+24|0]=a;E[b+25|0]=a>>>8;a=H[11238]|H[11239]<<8|(H[11240]<<16|H[11241]<<24);c=H[11234]|H[11235]<<8|(H[11236]<<16|H[11237]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[11230]|H[11231]<<8|(H[11232]<<16|H[11233]<<24);c=H[11226]|H[11227]<<8|(H[11228]<<16|H[11229]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[11222]|H[11223]<<8|(H[11224]<<16|H[11225]<<24);c=H[11218]|H[11219]<<8|(H[11220]<<16|H[11221]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 103:a=H[17010]|H[17011]<<8;E[b+24|0]=a;E[b+25|0]=a>>>8;a=H[17006]|H[17007]<<8|(H[17008]<<16|H[17009]<<24);c=H[17002]|H[17003]<<8|(H[17004]<<16|H[17005]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[16998]|H[16999]<<8|(H[17e3]<<16|H[17001]<<24);c=H[16994]|H[16995]<<8|(H[16996]<<16|H[16997]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[16990]|H[16991]<<8|(H[16992]<<16|H[16993]<<24);c=H[16986]|H[16987]<<8|(H[16988]<<16|H[16989]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 104:a=H[4670]|H[4671]<<8|(H[4672]<<16|H[4673]<<24);c=H[4666]|H[4667]<<8|(H[4668]<<16|H[4669]<<24);E[b+22|0]=c;E[b+23|0]=c>>>8;E[b+24|0]=c>>>16;E[b+25|0]=c>>>24;E[b+26|0]=a;E[b+27|0]=a>>>8;E[b+28|0]=a>>>16;E[b+29|0]=a>>>24;a=H[4664]|H[4665]<<8|(H[4666]<<16|H[4667]<<24);c=H[4660]|H[4661]<<8|(H[4662]<<16|H[4663]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[4656]|H[4657]<<8|(H[4658]<<16|H[4659]<<24);c=H[4652]|H[4653]<<8|(H[4654]<<16|H[4655]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[4648]|H[4649]<<8|(H[4650]<<16|H[4651]<<24);c=H[4644]|H[4645]<<8|(H[4646]<<16|H[4647]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 105:E[b+24|0]=H[22662];a=H[22658]|H[22659]<<8|(H[22660]<<16|H[22661]<<24);c=H[22654]|H[22655]<<8|(H[22656]<<16|H[22657]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[22650]|H[22651]<<8|(H[22652]<<16|H[22653]<<24);c=H[22646]|H[22647]<<8|(H[22648]<<16|H[22649]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[22642]|H[22643]<<8|(H[22644]<<16|H[22645]<<24);c=H[22638]|H[22639]<<8|(H[22640]<<16|H[22641]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 106:a=H[15145]|H[15146]<<8|(H[15147]<<16|H[15148]<<24);c=H[15141]|H[15142]<<8|(H[15143]<<16|H[15144]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[15140]|H[15141]<<8|(H[15142]<<16|H[15143]<<24);c=H[15136]|H[15137]<<8|(H[15138]<<16|H[15139]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[15132]|H[15133]<<8|(H[15134]<<16|H[15135]<<24);c=H[15128]|H[15129]<<8|(H[15130]<<16|H[15131]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[15124]|H[15125]<<8|(H[15126]<<16|H[15127]<<24);c=H[15120]|H[15121]<<8|(H[15122]<<16|H[15123]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 107:a=H[15176]|H[15177]<<8|(H[15178]<<16|H[15179]<<24);c=H[15172]|H[15173]<<8|(H[15174]<<16|H[15175]<<24);E[b+23|0]=c;E[b+24|0]=c>>>8;E[b+25|0]=c>>>16;E[b+26|0]=c>>>24;E[b+27|0]=a;E[b+28|0]=a>>>8;E[b+29|0]=a>>>16;E[b+30|0]=a>>>24;a=H[15169]|H[15170]<<8|(H[15171]<<16|H[15172]<<24);c=H[15165]|H[15166]<<8|(H[15167]<<16|H[15168]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[15161]|H[15162]<<8|(H[15163]<<16|H[15164]<<24);c=H[15157]|H[15158]<<8|(H[15159]<<16|H[15160]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[15153]|H[15154]<<8|(H[15155]<<16|H[15156]<<24);c=H[15149]|H[15150]<<8|(H[15151]<<16|H[15152]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 108:a=H[4562]|H[4563]<<8|(H[4564]<<16|H[4565]<<24);c=H[4558]|H[4559]<<8|(H[4560]<<16|H[4561]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[4557]|H[4558]<<8|(H[4559]<<16|H[4560]<<24);c=H[4553]|H[4554]<<8|(H[4555]<<16|H[4556]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[4549]|H[4550]<<8|(H[4551]<<16|H[4552]<<24);c=H[4545]|H[4546]<<8|(H[4547]<<16|H[4548]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[4541]|H[4542]<<8|(H[4543]<<16|H[4544]<<24);c=H[4537]|H[4538]<<8|(H[4539]<<16|H[4540]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 109:a=H[19923]|H[19924]<<8|(H[19925]<<16|H[19926]<<24);E[b+24|0]=a;E[b+25|0]=a>>>8;E[b+26|0]=a>>>16;E[b+27|0]=a>>>24;a=H[19919]|H[19920]<<8|(H[19921]<<16|H[19922]<<24);c=H[19915]|H[19916]<<8|(H[19917]<<16|H[19918]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[19911]|H[19912]<<8|(H[19913]<<16|H[19914]<<24);c=H[19907]|H[19908]<<8|(H[19909]<<16|H[19910]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[19903]|H[19904]<<8|(H[19905]<<16|H[19906]<<24);c=H[19899]|H[19900]<<8|(H[19901]<<16|H[19902]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 110:a=H[6961]|H[6962]<<8|(H[6963]<<16|H[6964]<<24);c=H[6957]|H[6958]<<8|(H[6959]<<16|H[6960]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[6953]|H[6954]<<8|(H[6955]<<16|H[6956]<<24);c=H[6949]|H[6950]<<8|(H[6951]<<16|H[6952]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[6945]|H[6946]<<8|(H[6947]<<16|H[6948]<<24);c=H[6941]|H[6942]<<8|(H[6943]<<16|H[6944]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 111:a=H[3983]|H[3984]<<8|(H[3985]<<16|H[3986]<<24);c=H[3979]|H[3980]<<8|(H[3981]<<16|H[3982]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[3978]|H[3979]<<8|(H[3980]<<16|H[3981]<<24);c=H[3974]|H[3975]<<8|(H[3976]<<16|H[3977]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[3970]|H[3971]<<8|(H[3972]<<16|H[3973]<<24);c=H[3966]|H[3967]<<8|(H[3968]<<16|H[3969]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[3962]|H[3963]<<8|(H[3964]<<16|H[3965]<<24);c=H[3958]|H[3959]<<8|(H[3960]<<16|H[3961]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 112:a=H[24472]|H[24473]<<8|(H[24474]<<16|H[24475]<<24);c=H[24468]|H[24469]<<8|(H[24470]<<16|H[24471]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[24464]|H[24465]<<8|(H[24466]<<16|H[24467]<<24);c=H[24460]|H[24461]<<8|(H[24462]<<16|H[24463]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[24456]|H[24457]<<8|(H[24458]<<16|H[24459]<<24);c=H[24452]|H[24453]<<8|(H[24454]<<16|H[24455]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 113:a=H[24405]|H[24406]<<8;E[b+24|0]=a;E[b+25|0]=a>>>8;a=H[24401]|H[24402]<<8|(H[24403]<<16|H[24404]<<24);c=H[24397]|H[24398]<<8|(H[24399]<<16|H[24400]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[24393]|H[24394]<<8|(H[24395]<<16|H[24396]<<24);c=H[24389]|H[24390]<<8|(H[24391]<<16|H[24392]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[24385]|H[24386]<<8|(H[24387]<<16|H[24388]<<24);c=H[24381]|H[24382]<<8|(H[24383]<<16|H[24384]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 119:a=H[15264]|H[15265]<<8|(H[15266]<<16|H[15267]<<24);E[b+24|0]=a;E[b+25|0]=a>>>8;E[b+26|0]=a>>>16;E[b+27|0]=a>>>24;a=H[15260]|H[15261]<<8|(H[15262]<<16|H[15263]<<24);c=H[15256]|H[15257]<<8|(H[15258]<<16|H[15259]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[15252]|H[15253]<<8|(H[15254]<<16|H[15255]<<24);c=H[15248]|H[15249]<<8|(H[15250]<<16|H[15251]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[15244]|H[15245]<<8|(H[15246]<<16|H[15247]<<24);c=H[15240]|H[15241]<<8|(H[15242]<<16|H[15243]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 130:a=H[15022]|H[15023]<<8|(H[15024]<<16|H[15025]<<24);E[b+23|0]=a;E[b+24|0]=a>>>8;E[b+25|0]=a>>>16;E[b+26|0]=a>>>24;a=H[15019]|H[15020]<<8|(H[15021]<<16|H[15022]<<24);c=H[15015]|H[15016]<<8|(H[15017]<<16|H[15018]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[15011]|H[15012]<<8|(H[15013]<<16|H[15014]<<24);c=H[15007]|H[15008]<<8|(H[15009]<<16|H[15010]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[15003]|H[15004]<<8|(H[15005]<<16|H[15006]<<24);c=H[14999]|H[15e3]<<8|(H[15001]<<16|H[15002]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 131:a=H[21096]|H[21097]<<8|(H[21098]<<16|H[21099]<<24);c=H[21092]|H[21093]<<8|(H[21094]<<16|H[21095]<<24);E[b+21|0]=c;E[b+22|0]=c>>>8;E[b+23|0]=c>>>16;E[b+24|0]=c>>>24;E[b+25|0]=a;E[b+26|0]=a>>>8;E[b+27|0]=a>>>16;E[b+28|0]=a>>>24;a=H[21091]|H[21092]<<8|(H[21093]<<16|H[21094]<<24);c=H[21087]|H[21088]<<8|(H[21089]<<16|H[21090]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[21083]|H[21084]<<8|(H[21085]<<16|H[21086]<<24);c=H[21079]|H[21080]<<8|(H[21081]<<16|H[21082]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[21075]|H[21076]<<8|(H[21077]<<16|H[21078]<<24);c=H[21071]|H[21072]<<8|(H[21073]<<16|H[21074]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 132:a=H[23695]|H[23696]<<8|(H[23697]<<16|H[23698]<<24);c=H[23691]|H[23692]<<8|(H[23693]<<16|H[23694]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[23687]|H[23688]<<8|(H[23689]<<16|H[23690]<<24);c=H[23683]|H[23684]<<8|(H[23685]<<16|H[23686]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[23679]|H[23680]<<8|(H[23681]<<16|H[23682]<<24);c=H[23675]|H[23676]<<8|(H[23677]<<16|H[23678]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 133:a=H[15757]|H[15758]<<8|(H[15759]<<16|H[15760]<<24);c=H[15753]|H[15754]<<8|(H[15755]<<16|H[15756]<<24);E[b+14|0]=c;E[b+15|0]=c>>>8;E[b+16|0]=c>>>16;E[b+17|0]=c>>>24;E[b+18|0]=a;E[b+19|0]=a>>>8;E[b+20|0]=a>>>16;E[b+21|0]=a>>>24;a=H[15751]|H[15752]<<8|(H[15753]<<16|H[15754]<<24);c=H[15747]|H[15748]<<8|(H[15749]<<16|H[15750]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[15743]|H[15744]<<8|(H[15745]<<16|H[15746]<<24);c=H[15739]|H[15740]<<8|(H[15741]<<16|H[15742]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 134:a=H[15849]|H[15850]<<8;E[b+24|0]=a;E[b+25|0]=a>>>8;a=H[15845]|H[15846]<<8|(H[15847]<<16|H[15848]<<24);c=H[15841]|H[15842]<<8|(H[15843]<<16|H[15844]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[15837]|H[15838]<<8|(H[15839]<<16|H[15840]<<24);c=H[15833]|H[15834]<<8|(H[15835]<<16|H[15836]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[15829]|H[15830]<<8|(H[15831]<<16|H[15832]<<24);c=H[15825]|H[15826]<<8|(H[15827]<<16|H[15828]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 135:a=H[21127]|H[21128]<<8|(H[21129]<<16|H[21130]<<24);c=H[21123]|H[21124]<<8|(H[21125]<<16|H[21126]<<24);E[b+23|0]=c;E[b+24|0]=c>>>8;E[b+25|0]=c>>>16;E[b+26|0]=c>>>24;E[b+27|0]=a;E[b+28|0]=a>>>8;E[b+29|0]=a>>>16;E[b+30|0]=a>>>24;a=H[21120]|H[21121]<<8|(H[21122]<<16|H[21123]<<24);c=H[21116]|H[21117]<<8|(H[21118]<<16|H[21119]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[21112]|H[21113]<<8|(H[21114]<<16|H[21115]<<24);c=H[21108]|H[21109]<<8|(H[21110]<<16|H[21111]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[21104]|H[21105]<<8|(H[21106]<<16|H[21107]<<24);c=H[21100]|H[21101]<<8|(H[21102]<<16|H[21103]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 200:a=H[23715]|H[23716]<<8|(H[23717]<<16|H[23718]<<24);E[b+16|0]=a;E[b+17|0]=a>>>8;E[b+18|0]=a>>>16;E[b+19|0]=a>>>24;a=H[23711]|H[23712]<<8|(H[23713]<<16|H[23714]<<24);c=H[23707]|H[23708]<<8|(H[23709]<<16|H[23710]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[23703]|H[23704]<<8|(H[23705]<<16|H[23706]<<24);c=H[23699]|H[23700]<<8|(H[23701]<<16|H[23702]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 201:a=H[20419]|H[20420]<<8|(H[20421]<<16|H[20422]<<24);E[b+15|0]=a;E[b+16|0]=a>>>8;E[b+17|0]=a>>>16;E[b+18|0]=a>>>24;a=H[20416]|H[20417]<<8|(H[20418]<<16|H[20419]<<24);c=H[20412]|H[20413]<<8|(H[20414]<<16|H[20415]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[20408]|H[20409]<<8|(H[20410]<<16|H[20411]<<24);c=H[20404]|H[20405]<<8|(H[20406]<<16|H[20407]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 202:E[b+24|0]=H[14858];a=H[14854]|H[14855]<<8|(H[14856]<<16|H[14857]<<24);c=H[14850]|H[14851]<<8|(H[14852]<<16|H[14853]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[14846]|H[14847]<<8|(H[14848]<<16|H[14849]<<24);c=H[14842]|H[14843]<<8|(H[14844]<<16|H[14845]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[14838]|H[14839]<<8|(H[14840]<<16|H[14841]<<24);c=H[14834]|H[14835]<<8|(H[14836]<<16|H[14837]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 203:a=H[20999]|H[21e3]<<8|(H[21001]<<16|H[21002]<<24);c=H[20995]|H[20996]<<8|(H[20997]<<16|H[20998]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=a;E[b+21|0]=a>>>8;E[b+22|0]=a>>>16;E[b+23|0]=a>>>24;a=H[20991]|H[20992]<<8|(H[20993]<<16|H[20994]<<24);c=H[20987]|H[20988]<<8|(H[20989]<<16|H[20990]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[20983]|H[20984]<<8|(H[20985]<<16|H[20986]<<24);c=H[20979]|H[20980]<<8|(H[20981]<<16|H[20982]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return;case 204:break c;default:break a}}a=H[26092]|H[26093]<<8|(H[26094]<<16|H[26095]<<24);c=H[26088]|H[26089]<<8|(H[26090]<<16|H[26091]<<24);E[b+15|0]=c;E[b+16|0]=c>>>8;E[b+17|0]=c>>>16;E[b+18|0]=c>>>24;E[b+19|0]=a;E[b+20|0]=a>>>8;E[b+21|0]=a>>>16;E[b+22|0]=a>>>24;a=H[26085]|H[26086]<<8|(H[26087]<<16|H[26088]<<24);c=H[26081]|H[26082]<<8|(H[26083]<<16|H[26084]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[26077]|H[26078]<<8|(H[26079]<<16|H[26080]<<24);c=H[26073]|H[26074]<<8|(H[26075]<<16|H[26076]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return}a=H[5433]|H[5434]<<8|(H[5435]<<16|H[5436]<<24);c=H[5429]|H[5430]<<8|(H[5431]<<16|H[5432]<<24);E[b+13|0]=c;E[b+14|0]=c>>>8;E[b+15|0]=c>>>16;E[b+16|0]=c>>>24;E[b+17|0]=a;E[b+18|0]=a>>>8;E[b+19|0]=a>>>16;E[b+20|0]=a>>>24;a=H[5428]|H[5429]<<8|(H[5430]<<16|H[5431]<<24);c=H[5424]|H[5425]<<8|(H[5426]<<16|H[5427]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[5420]|H[5421]<<8|(H[5422]<<16|H[5423]<<24);c=H[5416]|H[5417]<<8|(H[5418]<<16|H[5419]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24;return}a=H[5433]|H[5434]<<8|(H[5435]<<16|H[5436]<<24);c=H[5429]|H[5430]<<8|(H[5431]<<16|H[5432]<<24);E[b+13|0]=c;E[b+14|0]=c>>>8;E[b+15|0]=c>>>16;E[b+16|0]=c>>>24;E[b+17|0]=a;E[b+18|0]=a>>>8;E[b+19|0]=a>>>16;E[b+20|0]=a>>>24;a=H[5428]|H[5429]<<8|(H[5430]<<16|H[5431]<<24);c=H[5424]|H[5425]<<8|(H[5426]<<16|H[5427]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=a;E[b+13|0]=a>>>8;E[b+14|0]=a>>>16;E[b+15|0]=a>>>24;a=H[5420]|H[5421]<<8|(H[5422]<<16|H[5423]<<24);c=H[5416]|H[5417]<<8|(H[5418]<<16|H[5419]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=a;E[b+5|0]=a>>>8;E[b+6|0]=a>>>16;E[b+7|0]=a>>>24}function uh(a,b,c,d,e,f,g,h){var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=N(0),A=0,B=0,C=0,D=0,P=0,U=0,V=N(0),W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=N(0),da=0,ea=0,fa=0,ga=0,ha=0,ia=N(0),ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=N(0),ra=0,sa=0,ta=0,ua=N(0),va=0,wa=N(0),xa=N(0),ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Ga=0,Ha=0,Ja=0,Ka=N(0),La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Va=N(0),Xa=0,Ya=0,Za=0,_a=0,$a=0,db=0,eb=0,fb=0,gb=0,hb=N(0),ib=0,jb=0,kb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=N(0),tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0,Eb=0,Fb=0,Gb=0,Hb=0,Ib=0,Jb=0,Kb=0,Lb=0,Mb=0,Ob=0,Pb=0,Qb=0,Sb=0,Tb=0,Ub=0,Vb=0,Wb=0,Xb=0,Yb=0,Zb=0,_b=0,$b=0,ac=0,bc=N(0),cc=0,ec=0,fc=0,gc=0;D=Fa-384|0;Fa=D;a:{if(G[h>>2]>0){break a}if(!Nb(a,h)){Ua(59541);G[h>>2]=413;break a}l=G[a>>2];i=G[a+4>>2];b:{if((l|0)!=G[i+76>>2]){mb(a,l+1|0,0,h);break b}if((G[i+128>>2]&G[i+132>>2])!=-1){break b}if((Rb(a,h)|0)>0){break a}}l=2;ba=4;Na=2;c:{d:{e:{f:{i=b&-2;switch(i-20|0){case 0:break d;case 10:break e;default:break f}}Na=1;if(b-11>>>0<2){break d}if((i|0)==40){break e}l=4;Na=4;if((b|0)==42){break d}if((b|0)==82){ba=8;l=8;Na=8;break d}Ua(24476);break c}l=4;Na=4}i=ba;g:{h:{i:{j:{k:{Ga=G[a+4>>2];switch(G[Ga+1048>>2]-11|0){case 20:break g;case 0:case 10:case 11:case 40:break j;case 30:break k;default:break i}}switch(G[Ga+1104>>2]-8|0){case 0:case 8:break g;default:break h}}i=Na;l:{switch(G[Ga+1104>>2]-8|0){case 8:i=l;break g;case 0:break g;default:break l}}i=ba;break g}Ua(16274);break c}i=8}m:{n:{o:{r=lb(G[Ga+1136>>2],i);if(r){Oa=1;G[D+320>>2]=1;G[D+352>>2]=1;G[D+356>>2]=1;G[D+288>>2]=1;G[D+292>>2]=1;G[D+256>>2]=1;G[D+260>>2]=1;G[D+160>>2]=1;G[D+164>>2]=1;G[D+360>>2]=1;G[D+324>>2]=1;G[D+328>>2]=1;G[D+296>>2]=1;G[D+300>>2]=1;G[D+264>>2]=1;G[D+268>>2]=1;G[D+168>>2]=1;G[D+172>>2]=1;G[D+364>>2]=1;G[D+368>>2]=1;G[D+332>>2]=1;G[D+336>>2]=1;G[D+372>>2]=1;G[D+340>>2]=1;G[D+304>>2]=1;G[D+308>>2]=1;G[D+272>>2]=1;G[D+276>>2]=1;G[D+176>>2]=1;G[D+180>>2]=1;l=0;Ra=G[Ga+1108>>2];if((Ra|0)>0){break o}Pa=1;break n}Ua(59462);G[h>>2]=113;break a}while(1){i=l<<2;o=G[i+c>>2];G[i+(D+128|0)>>2]=o;j=G[d+i>>2];G[i+(D+96|0)>>2]=j;k=i+Ga|0;p=G[k+1112>>2];G[i+(D+352|0)>>2]=p;if((o|0)<=0){Wa(r);G[h>>2]=321;break a}ba=G[k+1052>>2];G[i+(D+320|0)>>2]=ba;G[i+(D+160|0)>>2]=Oa;G[i+(D+288|0)>>2]=((o-1|0)/(ba|0)|0)+1;o=i+(D+256|0)|0;na=((j-1|0)/(ba|0)|0)+1|0;i=((p-1|0)/(ba|0)|0)+1|0;G[o>>2]=(i|0)>(na|0)?na:i;Oa=M(i,Oa);l=l+1|0;if((Ra|0)!=(l|0)){continue}break}Oa=G[D+308>>2];Pa=G[D+276>>2];if((Oa|0)>(Pa|0)){break m}}Sa=G[D+372>>2];Ta=G[D+340>>2];Ya=G[D+272>>2];ub=G[D+304>>2];if((Ya|0)<(ub|0)){b=M(Pa,Ta);G[D+212>>2]=(b|0)<(Sa|0)?b:Sa;G[D+244>>2]=M(Pa-1|0,Ta)+1;break m}Za=G[D+368>>2];_a=G[D+336>>2];$a=G[D+268>>2];vb=G[D+300>>2];if(($a|0)<(vb|0)){b=M(Pa,Ta);G[D+212>>2]=(b|0)<(Sa|0)?b:Sa;G[D+244>>2]=M(Pa-1|0,Ta)+1;G[D+240>>2]=M(Ya-1|0,_a)+1;b=M(_a,Ya);G[D+208>>2]=(b|0)<(Za|0)?b:Za;break m}db=G[D+364>>2];eb=G[D+332>>2];kb=G[D+264>>2];wb=G[D+296>>2];if((kb|0)>=(wb|0)){xb=G[D+352>>2];yb=G[D+320>>2];zb=G[D+256>>2];Ab=G[D+288>>2];Gb=G[D+164>>2];Bb=G[D+292>>2];Hb=G[D+168>>2];Ib=G[D+172>>2];Jb=G[D+176>>2];Kb=G[D+180>>2];nb=G[D+328>>2];c=M(nb,kb);ob=G[D+360>>2];Cb=(c|0)<(ob|0)?c:ob;c=M(eb,$a);Lb=(c|0)<(db|0)?c:db;pb=G[D+324>>2];qb=G[D+260>>2];c=M(pb,qb);rb=G[D+356>>2];Mb=(c|0)<(rb|0)?c:rb;Ob=Ra&-2;Pb=Ra&1;Db=M(kb-1|0,nb)+1|0;Qb=M($a-1|0,eb)+1|0;Sb=M(qb-1|0,pb)+1|0;while(1){c=Oa-1|0;d=M(c,Ta);G[D+244>>2]=d+1;i=M(Oa,Ta);i=(i|0)<(Sa|0)?i:Sa;G[D+212>>2]=i;Tb=i-d|0;Ub=M(c,Kb);c=ub;while(1){d=c-1|0;i=M(d,_a);G[D+240>>2]=i+1;l=M(c,_a);l=(l|0)<(Za|0)?l:Za;G[D+208>>2]=l;p:{if((qb|0)>=(Bb|0)){Vb=M(l-i|0,Tb);Wb=M(d,Jb)+Ub|0;d=vb;while(1){i=d-1|0;l=M(i,eb);G[D+236>>2]=l+1;o=M(d,eb);o=(o|0)<(db|0)?o:db;G[D+204>>2]=o;q:{if((zb|0)>=(Ab|0)){Xb=M(o-l|0,Vb);Yb=M(i,Ib)+Wb|0;Ga=wb;while(1){i=Ga-1|0;l=M(i,nb);G[D+232>>2]=l+1;o=M(Ga,nb);o=(o|0)<(ob|0)?o:ob;G[D+200>>2]=o;Zb=M(o-l|0,Xb);_b=M(i,Hb)+Yb|0;jb=Bb;while(1){i=jb-1|0;l=M(i,pb);G[D+228>>2]=l+1;o=M(jb,pb);o=(o|0)<(rb|0)?o:rb;G[D+196>>2]=o;$b=M(o-l|0,Zb);ac=M(i,Gb)+_b|0;i=Ab;while(1){l=M(i-1|0,yb);G[D+224>>2]=l+1;o=M(i,yb);o=(o|0)<(xb|0)?o:xb;G[D+192>>2]=o;Eb=i;Ba=ac+i|0;j=M(o-l|0,$b);so(a,Ba,j,b,e,g,r,0,D+92|0,h);if(G[h>>2]==415){cb(r,0,M(j,Na));G[h>>2]=0}u=D+224|0;X=D+192|0;x=D+128|0;W=D+96|0;p=0;s=0;o=Fa-192|0;Fa=o;r:{if(G[h>>2]>0){break r}i=o;G[i+112>>2]=0;G[i+116>>2]=0;G[i+80>>2]=0;G[i+84>>2]=0;G[i+48>>2]=0;G[i+52>>2]=0;G[i+104>>2]=0;G[i+108>>2]=0;G[i+96>>2]=0;G[i+100>>2]=0;G[i+64>>2]=0;G[i+68>>2]=0;G[i+72>>2]=0;G[i+76>>2]=0;G[i+32>>2]=0;G[i+36>>2]=0;G[i+40>>2]=0;G[i+44>>2]=0;A=1;G[i>>2]=1;G[i+160>>2]=1;G[i+128>>2]=1;G[i+132>>2]=1;G[i+4>>2]=1;G[i+8>>2]=1;G[i+164>>2]=1;G[i+168>>2]=1;G[i+136>>2]=1;G[i+12>>2]=1;G[i+172>>2]=1;G[i+140>>2]=1;G[i+144>>2]=1;G[i+16>>2]=1;G[i+20>>2]=1;G[i+176>>2]=1;G[i+180>>2]=1;G[i+148>>2]=1;s:{t:{if((Ra|0)<=0){i=0;v=0;l=Na;break t}while(1){i=s<<2;p=G[i+X>>2];l=G[i+x>>2];if((p|0)<(l|0)){break r}v=G[i+u>>2];m=G[i+W>>2];if((v|0)>(m|0)){break r}n=G[i+o>>2];k=n>>31;aa=i+(o+160|0)|0;k=(k^n)-k|0;n=(m-l|0)/(k|0)|0;da=n+1|0;G[aa>>2]=da;if((n|0)<0){break s}w=i+(o+128|0)|0;m=p-v|0;q=m+1|0;G[w>>2]=q;if((m|0)<0){break s}if(s){G[w>>2]=M(q,G[(i+o|0)+124>>2])}q=l-1|0;m=p-1|0;p=v-1|0;while(1){if((p-q|0)%(k|0)|0){_=(m|0)>(p|0);p=p+1|0;if(_){continue}break r}break}while(1){if((m-q|0)%(k|0)|0){_=(m|0)>(p|0);m=m-1|0;if(_){continue}break r}break}q=m;m=1-l|0;q=(q+m|0)/(k|0)|0;G[i+(o- -64|0)>>2]=(n|0)>(q|0)?q:n;p=(m+p|0)/(k|0)|0;G[i+(o+96|0)>>2]=(p|0)>0?p:0;p=l-v|0;p=(p|0)>0?p:0;m=v-l|0;l=i+(o+32|0)|0;u:{while(1){if(!((m+p|0)%(k|0)|0)){break u}p=p+1|0;if((p|0)>2]){continue}break}G[l>>2]=p;break r}G[l>>2]=p;if(s){G[aa>>2]=M(da,G[(i+o|0)+156>>2])}s=s+1|0;if((Ra|0)!=(s|0)){continue}break}v=G[o+112>>2];p=G[o+80>>2];if((v|0)>(p|0)){break r}s=G[o+64>>2];i=G[o+96>>2];A=(s-i|0)+1|0;l=M(Na,A)}m=G[o+76>>2];q=G[o+108>>2];if((m|0)<(q|0)){break r}k=l;aa=G[o+160>>2];da=G[o+128>>2];_=G[o+32>>2];Y=G[o+36>>2];B=G[o+132>>2];$=G[o+164>>2];ha=G[o+40>>2];la=G[o+136>>2];va=G[o+168>>2];fa=G[o+44>>2];ka=G[o+140>>2];ma=G[o+172>>2];ja=G[o+48>>2];oa=(p-v|0)+1|0;za=(m-q|0)+1|0;Aa=G[o+72>>2];u=G[o+104>>2];Ea=(Aa-u|0)+1|0;Ca=G[o+68>>2];x=G[o+100>>2];La=(Ca-x|0)+1|0;C=0;X=0;while(1){Ha=M(ka,X+ja|0);Qa=M(ma,v+C|0);n=0;w=0;while(1){if((u|0)<=(Aa|0)){Ja=Qa+M(va,n+q|0)|0;fb=Ha+M(la,w+fa|0)|0;W=0;ea=0;while(1){if((x|0)<=(Ca|0)){gb=Ja+M($,u+W|0)|0;Da=_+(fb+M(B,ea+ha|0)|0)|0;pa=0;ga=0;while(1){if((i|0)<=(s|0)){p=Da+M(da,Y+ga|0)|0;m=(gb+M(aa,x+pa|0)|0)+i|0;l=i;while(1){bb(M(p,Na)+r|0,M(m,Na)+f|0,k);m=m+A|0;p=p+A|0;l=l+A|0;if((s|0)>=(l|0)){continue}break}}ga=ga+1|0;pa=pa+1|0;if((La|0)!=(pa|0)){continue}break}}ea=ea+1|0;W=W+1|0;if((Ea|0)!=(W|0)){continue}break}}w=w+1|0;n=n+1|0;if((za|0)!=(n|0)){continue}break}X=X+1|0;C=C+1|0;if((oa|0)!=(C|0)){continue}break}break r}G[h>>2]=323}Fa=o+192|0;v:{if(G[h>>2]){break v}na=1;if((Ra|0)>0){i=0;l=0;u=0;if((Ra|0)!=1){while(1){o=l<<2;k=o|4;p=D+192|0;w=G[k+p>>2];m=k;k=D+224|0;m=w-G[m+k>>2]|0;s=m+1|0;o=G[o+p>>2]-G[k+o>>2]|0;k=o+1|0;p=(o|0)>0;o=p?i?i:k:i;m=(m|0)>0;na=M(m?o?s:1:1,M(p?i?k:1:1,na));l=l+2|0;ba=m?o?o:s:o;i=ba;u=u+2|0;if((Ob|0)!=(u|0)){continue}break}}if(Pb){l=l<<2;l=G[l+(D+192|0)>>2]-G[l+(D+224|0)>>2]|0;o=l+1|0;l=(l|0)>0;ba=l?i?i:o:i;na=M(l?i?o:1:1,na)}if(ba){break v}}ba=1}o=j;n=0;m=0;A=0;C=0;x=0;P=0;U=0;ra=0;W=0;v=0;p=0;aa=0;X=0;Z=0;sa=0;ea=0;pa=0;la=0;La=0;Fb=0;_=Fa-80|0;Fa=_;G[_+76>>2]=1;G[_+60>>2]=0;G[_+24>>2]=0;G[_+28>>2]=1072693248;G[_+16>>2]=0;G[_+20>>2]=0;w:{if(G[h>>2]>0){break w}x:{j=G[a+4>>2];if(!(!((b|0)==163|b-82>>>0<2)&(b|0)!=42|(K[j+1076>>2]!=N(9999)|G[j+1048>>2]-21>>>0<2))){Ua(60755);break x}i=G[j+1228>>2];y:{if(!i){break y}k=i;i=(Ba-1|0)%(((G[j+1112>>2]-1|0)/G[j+1052>>2]|0)+1|0)|0;l=i<<2;if((Ba|0)!=G[k+l>>2]){break y}l=G[l+G[j+1240>>2]>>2];if(l){Wa(l);j=G[a+4>>2]}i=i<<2;l=G[i+G[j+1244>>2]>>2];if(l){Wa(l);j=G[a+4>>2]}G[G[j+1240>>2]+i>>2]=0;G[i+G[G[a+4>>2]+1244>>2]>>2]=0;j=G[a+4>>2];G[i+G[j+1228>>2]>>2]=0;G[i+G[j+1232>>2]>>2]=0;G[i+G[j+1236>>2]>>2]=0;G[i+G[j+1248>>2]>>2]=0}if(G[j+1048>>2]==-1){l=Fa-16|0;Fa=l;i=G[a+4>>2];z:{if(G[i+1148>>2]<=0){A:{B:{switch(b-21|0){case 10:G[l+12>>2]=4870193;break A;case 21:G[l+12>>2]=4542769;break A;default:Ua(7966);G[h>>2]=413;break z;case 0:break B}}G[l+12>>2]=4804657}Bi(a,999,35949,l+12|0,h);i=G[a+4>>2]}dc(a,0,35949,i+1148|0,h);Bk(a,b,G[G[a+4>>2]+1148>>2],Ba,Ba>>31,1,0,o,o>>31,r,h)}Fa=l+16|0;break w}va=G[j+1104>>2];$=(va|0)>0?G[j+1164>>2]!=-1?0:e:e;t=L[j+1192>>3];y=L[j+1184>>3];l=G[j+1208>>2];C:{D:{switch(b-11|0){case 9:k=o;E:{if(!(!((va|0)!=16|y!=1)&t==32768)){Ua(7807);G[h>>2]=413;break E}F:{j=G[a+4>>2];i=G[j+1048>>2];m=i-21|0;if(!((1<>>0<=30:0)|(i|0)==11)){G[_+72>>2]=4;if(($|0)!=1){break F}if((k|0)<=0){break E}i=I[g>>1];j=k;if(j&1){j=k-1|0;m=I[r+(j<<1)>>1];G[r+(j<<2)>>2]=(i|0)==(m|0)?l:m-32768|0}if((k|0)==1){break E}while(1){k=j-1|0;m=I[r+(k<<1)>>1];G[r+(k<<2)>>2]=(i|0)==(m|0)?l:m-32768|0;j=j-2|0;m=I[r+(j<<1)>>1];G[r+(j<<2)>>2]=(i|0)==(m|0)?l:m-32768|0;if(k>>>0>1){continue}break}break E}G[_+72>>2]=2;if(($|0)!=1){if((k|0)<=0){break E}i=k-1|0;m=k&3;if(m){j=0;while(1){k=k-1|0;s=r+(k<<1)|0;F[s>>1]=I[s>>1]^32768;j=j+1|0;if((m|0)!=(j|0)){continue}break}}if(i>>>0<3){break E}while(1){i=r+(k<<1)|0;j=i-2|0;F[j>>1]=I[j>>1]^32768;i=i-4|0;F[i>>1]=I[i>>1]^32768;i=k-3|0;j=r+(i<<1)|0;F[j>>1]=I[j>>1]^32768;k=k-4|0;j=r+(k<<1)|0;F[j>>1]=I[j>>1]^32768;if(i>>>0>1){continue}break}break E}if((k|0)<=0){break E}i=I[g>>1];s=k-1|0;n=k&3;if(n){j=0;while(1){k=k-1|0;w=r+(k<<1)|0;m=I[w>>1];F[w>>1]=(i|0)==(m|0)?l:m^32768;j=j+1|0;if((n|0)!=(j|0)){continue}break}}if(s>>>0<3){break E}while(1){m=r+(k<<1)|0;s=m-2|0;j=I[s>>1];F[s>>1]=(i|0)==(j|0)?l:j^32768;m=m-4|0;j=I[m>>1];F[m>>1]=(i|0)==(j|0)?l:j^32768;m=k-3|0;s=r+(m<<1)|0;j=I[s>>1];F[s>>1]=(i|0)==(j|0)?l:j^32768;k=k-4|0;s=r+(k<<1)|0;j=I[s>>1];F[s>>1]=(i|0)==(j|0)?l:j^32768;if(m>>>0>1){continue}break}break E}i=G[h>>2];G:{if(G[j+1048>>2]==41){if((i|0)>0){break E}n=(k|0)<1e4?k:1e4;i=ab(n<<2);if(!i){break G}H:{if((k|0)<=0){break H}j=k-n|0;while(1){I:{if((n|0)<=0){break I}x=0;k=0;if(n-1>>>0>=3){m=n&-4;u=0;while(1){G[i+(k<<2)>>2]=I[r+(j+k<<1)>>1]-32768;s=k|1;G[i+(s<<2)>>2]=I[r+(j+s<<1)>>1]-32768;s=k|2;G[i+(s<<2)>>2]=I[r+(j+s<<1)>>1]-32768;s=k|3;G[i+(s<<2)>>2]=I[r+(j+s<<1)>>1]-32768;k=k+4|0;u=u+4|0;if((m|0)!=(u|0)){continue}break}}m=n&3;if(!m){break I}while(1){G[i+(k<<2)>>2]=I[r+(j+k<<1)>>1]-32768;k=k+1|0;x=x+1|0;if((m|0)!=(x|0)){continue}break}}bb(r+(j<<2)|0,i,n<<2);if(!j){break H}k=(j|0)>1e4;n=k?n:j;j=j?k?j-1e4|0:0:0;if((n|0)>0){continue}break}}Wa(i);break E}if((i|0)>0){break E}n=(k|0)<1e4?k:1e4;i=ab(n<<2);if(!i){break G}J:{if((k|0)<=0){break J}j=k-n|0;while(1){K:{if((n|0)<=0){break K}x=0;k=0;if(n-1>>>0>=3){m=n&-4;u=0;while(1){G[i+(k<<2)>>2]=I[r+(j+k<<1)>>1];s=k|1;G[i+(s<<2)>>2]=I[r+(j+s<<1)>>1];s=k|2;G[i+(s<<2)>>2]=I[r+(j+s<<1)>>1];s=k|3;G[i+(s<<2)>>2]=I[r+(j+s<<1)>>1];k=k+4|0;u=u+4|0;if((m|0)!=(u|0)){continue}break}}m=n&3;if(!m){break K}while(1){G[i+(k<<2)>>2]=I[r+(j+k<<1)>>1];k=k+1|0;x=x+1|0;if((m|0)!=(x|0)){continue}break}}bb(r+(j<<2)|0,i,n<<2);if(!j){break J}k=(j|0)>1e4;n=k?n:j;j=j?k?j-1e4|0:0:0;if((n|0)>0){continue}break}}Wa(i);break E}Ua(61691);G[h>>2]=113}break C;case 0:k=o;L:{if(!(!((va|0)!=8|y!=1)&t==0)){Ua(7807);G[h>>2]=413;break L}M:{N:{i=G[G[a+4>>2]+1048>>2];j=i-21|0;if(!((1<>>0<=30:0)|(i|0)==11)){G[_+72>>2]=4;if(($|0)!=1){break N}if((k|0)<=0){break M}i=H[g|0];s=k-1|0;n=k&3;if(n){j=0;while(1){k=k-1|0;m=H[r+k|0];G[r+(k<<2)>>2]=(i|0)==(m|0)?l:m;j=j+1|0;if((n|0)!=(j|0)){continue}break}}if(s>>>0<3){break M}while(1){m=k-1|0;j=H[m+r|0];G[r+(m<<2)>>2]=(i|0)==(j|0)?l:j;m=k-2|0;j=H[m+r|0];G[r+(m<<2)>>2]=(i|0)==(j|0)?l:j;j=k-3|0;m=H[j+r|0];G[r+(j<<2)>>2]=(i|0)==(m|0)?l:m;k=k-4|0;m=H[r+k|0];G[r+(k<<2)>>2]=(i|0)==(m|0)?l:m;if(j>>>0>1){continue}break}break M}G[_+72>>2]=1;if(($|0)!=1){break M}i=H[g|0];if((i|0)==(l|0)|(k|0)<=0){break M}j=k-1|0;m=k&3;if(m){while(1){k=k-1|0;s=r+k|0;if((i|0)==H[s|0]){E[s|0]=l}x=x+1|0;if((m|0)!=(x|0)){continue}break}}if(j>>>0<3){break M}while(1){j=k+r|0;m=j-1|0;if((i|0)==H[m|0]){E[m|0]=l}j=j-2|0;if((i|0)==H[j|0]){E[j|0]=l}j=k-3|0;m=j+r|0;if((i|0)==H[m|0]){E[m|0]=l}k=k-4|0;m=r+k|0;if((i|0)==H[m|0]){E[m|0]=l}if(j>>>0>1){continue}break}break M}if(G[h>>2]>0){break M}n=(k|0)<1e4?k:1e4;i=ab(n<<2);if(!i){Ua(61778);G[h>>2]=113;break L}O:{if((k|0)<=0){break O}j=k-n|0;while(1){P:{if((n|0)<=0){break P}x=0;k=0;if(n-1>>>0>=3){m=n&-4;u=0;while(1){G[i+(k<<2)>>2]=H[r+(j+k|0)|0];s=k|1;G[i+(s<<2)>>2]=H[r+(j+s|0)|0];s=k|2;G[i+(s<<2)>>2]=H[r+(j+s|0)|0];s=k|3;G[i+(s<<2)>>2]=H[r+(j+s|0)|0];k=k+4|0;u=u+4|0;if((m|0)!=(u|0)){continue}break}}m=n&3;if(!m){break P}while(1){G[i+(k<<2)>>2]=H[r+(j+k|0)|0];k=k+1|0;x=x+1|0;if((m|0)!=(x|0)){continue}break}}bb(r+(j<<2)|0,i,n<<2);if(!j){break O}k=(j|0)>1e4;n=k?n:j;j=j?k?j-1e4|0:0:0;if((n|0)>0){continue}break}}Wa(i)}}break C;case 1:k=o;Q:{if(!(!((va|0)!=8|y!=1)&t==-128)){Ua(7807);G[h>>2]=413;break Q}R:{S:{i=G[G[a+4>>2]+1048>>2];j=i-21|0;if(!((1<>>0<=30:0)|(i|0)==11)){G[_+72>>2]=4;if(($|0)!=1){break S}if((k|0)<=0){break R}i=H[g|0];j=k;if(j&1){j=k-1|0;m=H[r+j|0];G[r+(j<<2)>>2]=(i|0)==(m|0)?l:(m<<24>>24)+128|0}if((k|0)==1){break R}while(1){k=j-1|0;m=H[k+r|0];G[r+(k<<2)>>2]=(i|0)==(m|0)?l:(m<<24>>24)+128|0;j=j-2|0;m=E[r+j|0];G[r+(j<<2)>>2]=(i|0)==(m&255)?l:m+128|0;if(k>>>0>1){continue}break}break R}G[_+72>>2]=1;if(($|0)!=1){if((k|0)<=0){break R}i=k-1|0;m=k&3;if(m){j=0;while(1){k=k-1|0;s=r+k|0;E[s|0]=H[s|0]^128;j=j+1|0;if((m|0)!=(j|0)){continue}break}}if(i>>>0<3){break R}while(1){i=k+r|0;j=i-1|0;E[j|0]=H[j|0]^128;i=i-2|0;E[i|0]=H[i|0]^128;i=k-3|0;j=i+r|0;E[j|0]=H[j|0]^128;k=k-4|0;j=r+k|0;E[j|0]=H[j|0]^128;if(i>>>0>1){continue}break}break R}if((k|0)<=0){break R}i=H[g|0];s=k-1|0;n=k&3;if(n){j=0;while(1){k=k-1|0;w=r+k|0;m=H[w|0];E[w|0]=(i|0)==(m|0)?l:m^128;j=j+1|0;if((n|0)!=(j|0)){continue}break}}if(s>>>0<3){break R}while(1){m=k+r|0;s=m-1|0;j=H[s|0];E[s|0]=(i|0)==(j|0)?l:j^128;m=m-2|0;j=H[m|0];E[m|0]=(i|0)==(j|0)?l:j^128;m=k-3|0;s=m+r|0;j=H[s|0];E[s|0]=(i|0)==(j|0)?l:j^128;k=k-4|0;s=r+k|0;j=H[s|0];E[s|0]=(i|0)==(j|0)?l:j^128;if(m>>>0>1){continue}break}break R}if(G[h>>2]>0){break R}n=(k|0)<1e4?k:1e4;i=ab(n<<2);if(!i){Ua(61821);G[h>>2]=113;break Q}T:{if((k|0)<=0){break T}j=k-n|0;while(1){U:{if((n|0)<=0){break U}x=0;k=0;if(n-1>>>0>=3){m=n&-4;u=0;while(1){G[i+(k<<2)>>2]=E[r+(j+k|0)|0]+128;s=k|1;G[i+(s<<2)>>2]=E[r+(j+s|0)|0]+128;s=k|2;G[i+(s<<2)>>2]=E[r+(j+s|0)|0]+128;s=k|3;G[i+(s<<2)>>2]=E[r+(j+s|0)|0]+128;k=k+4|0;u=u+4|0;if((m|0)!=(u|0)){continue}break}}m=n&3;if(!m){break U}while(1){G[i+(k<<2)>>2]=E[r+(j+k|0)|0]+128;k=k+1|0;x=x+1|0;if((m|0)!=(x|0)){continue}break}}bb(r+(j<<2)|0,i,n<<2);if(!j){break T}k=(j|0)>1e4;n=k?n:j;j=j?k?j-1e4|0:0:0;if((n|0)>0){continue}break}}Wa(i)}}break C;case 20:k=o;V:{if(!(!((va|0)!=32|y!=1)&t==0)){Ua(7807);G[h>>2]=413;break V}G[_+72>>2]=4;W:{if(($|0)!=1){break W}i=G[g>>2];if((i|0)==(l|0)|(k|0)<=0){break W}j=k-1|0;m=k&3;if(m){while(1){k=k-1|0;s=r+(k<<2)|0;if((i|0)==G[s>>2]){G[s>>2]=l}n=n+1|0;if((m|0)!=(n|0)){continue}break}}if(j>>>0<3){break W}while(1){j=r+(k<<2)|0;m=j-4|0;if((i|0)==G[m>>2]){G[m>>2]=l}j=j-8|0;if((i|0)==G[j>>2]){G[j>>2]=l}j=k-3|0;m=r+(j<<2)|0;if((i|0)==G[m>>2]){G[m>>2]=l}k=k-4|0;m=r+(k<<2)|0;if((i|0)==G[m>>2]){G[m>>2]=l}if(j>>>0>1){continue}break}}}break C;case 19:k=o;X:{if(!(!((va|0)!=32|y!=1)&t==2147483648)){Ua(7807);G[h>>2]=413;break X}G[_+72>>2]=4;Y:{if(($|0)!=1){if((k|0)<=0){break Y}i=k-1|0;m=k&3;if(m){j=0;while(1){k=k-1|0;s=r+(k<<2)|0;G[s>>2]=G[s>>2]^-2147483648;j=j+1|0;if((m|0)!=(j|0)){continue}break}}if(i>>>0<3){break Y}while(1){i=r+(k<<2)|0;j=i-4|0;G[j>>2]=G[j>>2]^-2147483648;i=i-8|0;G[i>>2]=G[i>>2]^-2147483648;i=k-3|0;j=r+(i<<2)|0;G[j>>2]=G[j>>2]^-2147483648;k=k-4|0;j=r+(k<<2)|0;G[j>>2]=G[j>>2]^-2147483648;if(i>>>0>1){continue}break}break Y}if((k|0)<=0){break Y}i=G[g>>2];m=k-1|0;s=k&3;if(s){while(1){k=k-1|0;w=r+(k<<2)|0;j=G[w>>2];G[w>>2]=(i|0)==(j|0)?l:j^-2147483648;n=n+1|0;if((s|0)!=(n|0)){continue}break}}if(m>>>0<3){break Y}while(1){m=r+(k<<2)|0;s=m-4|0;j=G[s>>2];G[s>>2]=(i|0)==(j|0)?l:j^-2147483648;m=m-8|0;j=G[m>>2];G[m>>2]=(i|0)==(j|0)?l:j^-2147483648;m=k-3|0;s=r+(m<<2)|0;j=G[s>>2];G[s>>2]=(i|0)==(j|0)?l:j^-2147483648;k=k-4|0;s=r+(k<<2)|0;j=G[s>>2];G[s>>2]=(i|0)==(j|0)?l:j^-2147483648;if(m>>>0>1){continue}break}}}break C;case 31:Ha=_+24|0;Qa=_+16|0;s=Fa-16|0;Fa=s;G[s+12>>2]=0;G[s+8>>2]=0;Z:{_:{if((va|0)!=32&(va&-33)!=-64?1:t!=0|y!=1){Ua(7807);break _}G[_+72>>2]=4;$:{aa:{ba:{ca:{k=G[a+4>>2];if(G[k+1156>>2]>0){qa=N(-9119119840596153e-51);qa=($|0)==1?K[g>>2]:qa;da:{ea:{n=G[k+1080>>2];switch(n+1|0){case 0:break da;case 2:case 3:break ea;default:break ca}}i=G[k+1028>>2];fa:{if(!i){if(G[k+1084>>2]){break fa}j=Wc(0);k=sq();i=G[a+4>>2];G[i+1084>>2]=((G[i+76>>2]+(j+((k|0)/1e4|0)|0)|0)%1e4|0)+1;Jc(a,31,41550,i+1084|0,0,h);break fa}if((i&G[k+1084>>2])>=0){break fa}w=k+1084|0;if((o|0)>0){i=o<<2;i=(i|0)>1?i:1;j=i&1;k=0;if(i-1>>>0>=3){i=i&2147483644;n=0;while(1){m=H[r+(k|3)|0]+(H[r+(k|2)|0]+(H[r+(k|1)|0]+(H[k+r|0]+m|0)|0)|0)|0;k=k+4|0;n=n+4|0;if((i|0)!=(n|0)){continue}break}}if(j){while(1){m=H[k+r|0]+m|0;k=k+1|0;x=x+1|0;if((j|0)!=(x|0)){continue}break}}i=((m>>>0)%1e4|0)+1|0}else{i=1}G[w>>2]=i;Jc(a,31,41550,w,0,h)}k=G[a+4>>2];x=(Ba+G[k+1084>>2]|0)-1|0;n=G[k+1080>>2]}sb=K[k+1076>>2];w=n;n=0;m=0;t=0;y=0;q=Fa-48|0;Fa=q;G[q+40>>2]=0;G[q+12>>2]=0;G[q+8>>2]=0;aa=M(ba,na);ga:{ha:{if((aa|0)<2){t=1;break ha}ia:{if(sb>=N(0)){Ea=q+40|0;ga=q+12|0;ja=q+8|0;oa=q+32|0;za=q+24|0;Aa=q+16|0;i=(ba|0)<9;A=M(i?na:1,ba);ja:{if((A|0)<=8){ka:{if((A|0)<=0){ua=N(-34028234663852886e22);ia=N(34028234663852886e22);A=0;break ka}la:{ma:{if($){j=A&1;if((A|0)!=1){break ma}ia=N(34028234663852886e22);ua=N(-34028234663852886e22);A=0;break la}k=A&3;j=0;na:{if(A-1>>>0<3){ia=N(34028234663852886e22);ua=N(-34028234663852886e22);break na}u=A&-4;ia=N(34028234663852886e22);ua=N(-34028234663852886e22);while(1){i=n<<2;z=K[r+(i|12)>>2];V=K[r+(i|8)>>2];ca=K[r+(i|4)>>2];wa=K[i+r>>2];xa=uaxa?ca:xa;xa=V>xa?V:xa;ua=z>xa?z:xa;wa=ia>wa?wa:ia;ca=ca>2];ua=z>ua?z:ua;ia=z>2];if(z!=qa){ia=zua?z:ua}z=K[r+(u|4)>>2];if(z!=qa){ia=zua?z:ua}n=n+2|0;i=i+2|0;if((k|0)!=(i|0)){continue}break}}if(!j){break ka}z=K[r+(n<<2)>>2];if(z==qa){break ka}ua=z>ua?z:ua;ia=z>2]=ia}if(ja){K[ja>>2]=ua}if(Ea){G[Ea>>2]=A}if(oa){G[oa>>2]=0;G[oa+4>>2]=0}if(za){G[za>>2]=0;G[za+4>>2]=0}if(!Aa){break ja}G[Aa>>2]=0;G[Aa+4>>2]=0;break ja}oa:{da=lb(A,4);if(!da){break oa}B=lb(A,4);if(!B){Wa(da);break oa}ka=lb(A,4);if(!ka){Wa(da);Wa(B);break oa}Ca=i?1:na;Y=lb(Ca,8);if(!Y){Wa(da);Wa(B);Wa(ka);break oa}ha=lb(Ca,8);if(!ha){Wa(da);Wa(B);Wa(ka);Wa(Y);break oa}pa:{qa:{ma=lb(Ca,8);if(ma){if((Ca|0)>0){break qa}z=N(-34028234663852886e22);ia=N(34028234663852886e22);i=0;break pa}Wa(da);Wa(B);Wa(ka);Wa(Y);Wa(ha);break oa}C=(ga|ja)!=0;fa=($|0)!=0;ia=N(34028234663852886e22);z=N(-34028234663852886e22);i=0;while(1){u=r+(M(A,la)<<2)|0;n=0;k=0;ra:{sa:{if(!$){break sa}while(1){if(K[u+(n<<2)>>2]!=qa){k=n;break sa}n=n+1|0;if((A|0)!=(n|0)){continue}break}break ra}if((k|0)==(A|0)){break ra}ua=K[u+(k<<2)>>2];ta:{if(!C){break ta}ia=ia>ua?ua:ia;if(!(z(n|0))){break ua}while(1){if(K[u+(n<<2)>>2]!=qa){break ua}n=n+1|0;if((A|0)!=(n|0)){continue}break}i=j;break ra}if((n|0)==(A|0)){i=j;break ra}xa=K[u+(n<<2)>>2];va:{if(!C){break va}ia=ia>xa?xa:ia;if(!(z(n|0))){break wa}while(1){if(K[u+(n<<2)>>2]!=qa){break wa}n=n+1|0;if((A|0)!=(n|0)){continue}break}i=j;break ra}if((n|0)==(A|0)){i=j;break ra}Va=K[u+(n<<2)>>2];xa:{if(!C){break xa}ia=ia>Va?Va:ia;if(!(z(n|0))){break ya}while(1){if(K[u+(n<<2)>>2]!=qa){break ya}n=n+1|0;if((A|0)!=(n|0)){continue}break}i=j;break ra}if((n|0)==(A|0)){i=j;break ra}ca=K[u+(n<<2)>>2];za:{if(!C){break za}ia=ca(n|0))){break Aa}while(1){if(K[u+(n<<2)>>2]!=qa){break Aa}n=n+1|0;if((A|0)!=(n|0)){continue}break}i=j;break ra}if((n|0)==(A|0)){i=j;break ra}Ka=K[u+(n<<2)>>2];Ba:{if(!C){break Ba}ia=ia>Ka?Ka:ia;if(!(z(n|0))){break Ca}while(1){if(K[u+(n<<2)>>2]!=qa){break Ca}n=n+1|0;if((A|0)!=(n|0)){continue}break}i=j;break ra}if((n|0)==(A|0)){i=j;break ra}wa=K[u+(n<<2)>>2];Da:{if(!C){break Da}ia=ia>wa?wa:ia;if(!(z(n|0))){break Ea}while(1){if(K[u+(n<<2)>>2]!=qa){break Ea}n=n+1|0;if((A|0)!=(n|0)){continue}break}i=j;break ra}if((n|0)==(A|0)){i=j;break ra}hb=K[u+(n<<2)>>2];Fa:{if(!C){break Fa}ia=ia>hb?hb:ia;if(!(z(n|0))){break Ga}while(1){if(K[u+(n<<2)>>2]!=qa){break Ga}n=n+1|0;if((A|0)!=(n|0)){continue}break}i=j;break ra}if((n|0)==(A|0)){i=j;break ra}V=K[u+(n<<2)>>2];Ha:{if(!C){break Ha}ia=V>2]!=qa){break Ja}n=n+1|0;if((A|0)!=(n|0)){continue}break}break Ia}if((n|0)==(A|0)){break Ia}V=K[u+(n<<2)>>2];Ka:{if(!C){break Ka}ia=V>2]=O(N(ca-wa));j=j+1|0}La:{Ma:{if(!(Ja|(xa!=Va|ca!=Va))){if(wa==Ka){break Ma}}Ja=k<<2;K[Ja+B>>2]=O(N(N(N(ca+ca)-xa)-wa));K[ka+Ja>>2]=O(N(N(ua+N(N(wa*N(-4))+N(N(ca*N(6))+N(xa*N(-4)))))+V));k=k+1|0;break La}i=i+1|0}ua=bc;n=n+1|0;if((A|0)>(n|0)){continue}}break}i=i+k|0;n=ma+(X<<3)|0;Na:{Oa:{switch(k|0){case 1:if((j|0)==1){L[Y+(W<<3)>>3]=K[da>>2];W=W+1|0}L[ha+(X<<3)>>3]=K[B>>2];V=K[ka>>2];break Na;case 0:break ra;default:break Oa}}if((j|0)>=2){ec=Y+(W<<3)|0,fc=+Jk(da,k),L[ec>>3]=fc;W=W+1|0}ec=ha+(X<<3)|0,fc=+Jk(B,k),L[ec>>3]=fc;V=Jk(ka,k)}L[n>>3]=V;X=X+1|0}la=la+1|0;if((Ca|0)!=(la|0)){continue}break}Pa:{Qa:{switch(X|0){case 1:t=L[ma>>3];y=L[ha>>3];break Pa;case 0:break Pa;default:break Qa}}oe(ha,X,8,14);oe(ma,X,8,14);j=(X-1|0)/2<<3;k=(X|0)/2<<3;t=(L[j+ma>>3]+L[k+ma>>3])*.5;y=(L[j+ha>>3]+L[k+ha>>3])*.5}Ra:{switch(W|0){case 1:ra=L[Y>>3];break pa;case 0:break pa;default:break Ra}}oe(Y,W,8,14);ra=(L[Y+((W-1|0)/2<<3)>>3]+L[Y+((W|0)/2<<3)>>3])*.5}if(Ea){G[Ea>>2]=i}if(ga){K[ga>>2]=ia}if(ja){K[ja>>2]=z}if(oa){L[oa>>3]=ra*1.0483579}if(za){L[za>>3]=y*.6052697}if(Aa){L[Aa>>3]=t*.1772048}Wa(ma);Wa(ha);Wa(Y);Wa(ka);Wa(B);Wa(da);break ja}G[q+44>>2]=113}j=G[q+40>>2];Sa:{if(!(j|!$)){G[q+8>>2]=1065353216;G[q+12>>2]=0;t=1;break Sa}t=L[q+16>>3];y=L[q+32>>3];Z=L[q+24>>3];y=y!=0?y>2];V=K[q+8>>2];break ia}t=+N(-sb);j=(ba|0)<5;i=M(j?na:1,ba);if((i|0)<=4){Ta:{if((i|0)<=0){V=N(-34028234663852886e22);z=N(34028234663852886e22);j=0;break Ta}Ua:{Va:{if($){k=i&1;if((i|0)!=1){break Va}j=0;z=N(34028234663852886e22);V=N(-34028234663852886e22);break Ua}n=i&3;Wa:{if(i-1>>>0<3){z=N(34028234663852886e22);V=N(-34028234663852886e22);break Wa}u=i&-4;z=N(34028234663852886e22);V=N(-34028234663852886e22);k=0;while(1){j=m<<2;ca=K[r+(j|12)>>2];wa=K[r+(j|8)>>2];xa=K[r+(j|4)>>2];Ka=K[j+r>>2];V=VKa?Ka:z;z=z>xa?xa:z;z=z>wa?wa:z;z=z>ca?ca:z;m=m+4|0;k=k+4|0;if((u|0)!=(k|0)){continue}break}}if(n){while(1){ca=K[r+(m<<2)>>2];V=Vca?ca:z;m=m+1|0;A=A+1|0;if((n|0)!=(A|0)){continue}break}}j=i;break Ta}n=i&-2;j=0;z=N(34028234663852886e22);V=N(-34028234663852886e22);i=0;while(1){u=m<<2;ca=K[u+r>>2];if(ca!=qa){V=Vca?ca:z;j=j+1|0}ca=K[r+(u|4)>>2];if(ca!=qa){V=Vca?ca:z;j=j+1|0}m=m+2|0;i=i+2|0;if((n|0)!=(i|0)){continue}break}}if(!k){break Ta}ca=K[r+(m<<2)>>2];if(ca==qa){break Ta}V=Vca?ca:z;j=j+1|0}K[q+8>>2]=V;K[q+12>>2]=z;G[q+40>>2]=j;break ia}X=j?1:na;Xa:{if((X|0)<=0){V=N(-34028234663852886e22);z=N(34028234663852886e22);j=0;break Xa}j=0;u=($|0)!=0;z=N(34028234663852886e22);V=N(-34028234663852886e22);while(1){n=r+(M(i,A)<<2)|0;m=0;k=0;Ya:{Za:{if(!$){break Za}while(1){if(K[n+(m<<2)>>2]!=qa){k=m;break Za}m=m+1|0;if((i|0)!=(m|0)){continue}break}break Ya}if((i|0)==(k|0)){break Ya}ca=K[n+(k<<2)>>2];V=Vca?ca:z;_a:{m=k+1|0;if(!(u&(i|0)>(m|0))){break _a}while(1){if(K[n+(m<<2)>>2]!=qa){break _a}m=m+1|0;if((i|0)!=(m|0)){continue}break}break Ya}if((i|0)==(m|0)){break Ya}ca=K[n+(m<<2)>>2];V=Vca?ca:z;$a:{m=m+1|0;if(!(u&(i|0)>(m|0))){break $a}while(1){if(K[n+(m<<2)>>2]!=qa){break $a}m=m+1|0;if((i|0)!=(m|0)){continue}break}break Ya}if((i|0)==(m|0)){break Ya}ca=K[n+(m<<2)>>2];V=Vca?ca:z;ab:{m=m+1|0;if(!(u&(i|0)>(m|0))){break ab}while(1){if(K[n+(m<<2)>>2]!=qa){break ab}m=m+1|0;if((i|0)!=(m|0)){continue}break}break Ya}if((i|0)==(m|0)){break Ya}ca=K[n+(m<<2)>>2];V=Vca?ca:z;m=m+1|0;bb:{if((i|0)<=(m|0)){break bb}while(1){cb:{if(!(u&(i|0)>(m|0))){break cb}while(1){if(K[n+(m<<2)>>2]!=qa){break cb}m=m+1|0;if((i|0)!=(m|0)){continue}break}break bb}if((i|0)==(m|0)){break bb}ca=K[n+(m<<2)>>2];V=Vca?ca:z;j=j+1|0;m=m+1|0;if((i|0)>(m|0)){continue}break}}j=j+4|0}A=A+1|0;if((X|0)!=(A|0)){continue}break}}K[q+12>>2]=z;G[q+40>>2]=j;K[q+8>>2]=V}m=0;if(+N(V-z)/t>4294967284){break ga}db:{eb:{fb:{gb:{hb:{if((x|0)>0){m=G[49098];if(!m){m=113;if(uo()){break ga}m=G[49098];j=G[q+40>>2]}i=(j|0)==(aa|0);k=(x-1>>>0)%1e4|0;y=+K[(k<<2)+m>>2]*500;if(!(O(y)<2147483648)){break hb}m=~~y;if(i){break gb}break fb}k=0;if((j|0)==(aa|0)){break gb}V=K[q+12>>2];y=+V+t*2147483637;break eb}m=-2147483648;if(!i){break fb}}ib:{if((w|0)==2){V=K[q+12>>2];y=+V+t*2147483637;break ib}z=K[q+8>>2];V=K[q+12>>2];if(+N(z-V)/t<2147483637){y=+V/t+.5;jb:{if(O(y)<0x8000000000000000){j=O(y)>=1?~~(y>0?Q(S(y*2.3283064365386963e-10),4294967295):T((y-+(~~y>>>0>>>0))*2.3283064365386963e-10))>>>0:0;i=~~y>>>0;break jb}j=-2147483648;i=0}y=t*(+(i>>>0)+ +(j|0)*4294967296);break ib}y=+N(z+V)*.5}i=0;if((x|0)<=0){if((aa|0)<=0){break db}while(1){k=i<<2;Z=(+K[k+r>>2]-y)/t;Z=Z+(Z>=0?.5:-.5);kb:{if(O(Z)<2147483648){j=~~Z;break kb}j=-2147483648}G[k+r>>2]=j;i=i+1|0;if((aa|0)!=(i|0)){continue}break}break db}if((aa|0)<=0){break db}n=G[49098];while(1){j=i<<2;z=K[j+r>>2];X=j+r|0;lb:{if((w|0)==2){j=-2147483646;if(z==N(0)){break lb}}Z=(+z-y)/t+ +K[n+(m<<2)>>2]+-.5;Z=Z+(Z>=0?.5:-.5);if(O(Z)<2147483648){j=~~Z;break lb}j=-2147483648}G[X>>2]=j;m=m+1|0;mb:{if((m|0)!=1e4){break mb}j=k+1|0;k=(j|0)==1e4?0:j;z=N(K[n+(k<<2)>>2]*N(500));if(N(O(z))>2];y=+V+t*2147483637;if((x|0)<=0){break eb}if((aa|0)<=0){break db}n=G[49098];i=0;while(1){u=i<<2;z=K[u+r>>2];j=-2147483647;nb:{if(z==qa){break nb}if((w|0)==2){j=-2147483646;if(z==N(0)){break nb}}Z=(+z-y)/t+ +K[n+(m<<2)>>2]+-.5;Z=Z+(Z>=0?.5:-.5);if(O(Z)<2147483648){j=~~Z;break nb}j=-2147483648}G[r+u>>2]=j;m=m+1|0;ob:{if((m|0)!=1e4){break ob}j=k+1|0;k=(j|0)==1e4?0:j;z=N(K[n+(k<<2)>>2]*N(500));if(N(O(z))>2];i=-2147483647;pb:{if(z==qa){break pb}Z=(+z-y)/t;Z=Z+(Z>=0?.5:-.5);if(O(Z)<2147483648){i=~~Z;break pb}i=-2147483648}G[j+r>>2]=i;m=m+1|0;if((aa|0)!=(m|0)){continue}break}}Z=(+V-y)/t;Z=Z+(Z>=0?.5:-.5);qb:{if(O(Z)<2147483648){i=~~Z;break qb}i=-2147483648}G[s+12>>2]=i;Z=(+K[q+8>>2]-y)/t;Z=Z+(Z>=0?.5:-.5);rb:{if(O(Z)<2147483648){i=~~Z;break rb}i=-2147483648}G[s+8>>2]=i;m=1}L[Ha>>3]=t;L[Qa>>3]=y}Fa=q+48|0;G[_+76>>2]=m;if((m|0)<2){break $}G[h>>2]=m;break Z}if(K[k+1076>>2]==N(9999)){break ba}if(($|0)==1){break aa}k=0;if((o|0)<=0){break $}while(1){sb:{tb:{j=r+(k<<2)|0;z=K[j>>2];t=+z;if(t<-2147483648.49){G[h>>2]=-11;break tb}if(t>2147483647.49){G[h>>2]=-11;i=2147483647;break sb}if(z>=N(0)){t=t+.5;if(!(O(t)<2147483648)){break tb}i=~~t;break sb}t=t+-.5;if(!(O(t)<2147483648)){break tb}i=~~t;break sb}i=-2147483648}G[j>>2]=i;k=k+1|0;if((o|0)!=(k|0)){continue}break}break $}Ua(44315);Ua(45142);break _}if(($|0)!=1|(o|0)<=0){break $}z=K[g>>2];k=0;if(o-1>>>0>=3){j=o&-4;while(1){i=k<<2;n=i+r|0;if(z==K[n>>2]){G[n>>2]=-1}n=r+(i|4)|0;if(z==K[n>>2]){G[n>>2]=-1}n=r+(i|8)|0;if(z==K[n>>2]){G[n>>2]=-1}i=r+(i|12)|0;if(z==K[i>>2]){G[i>>2]=-1}k=k+4|0;x=x+4|0;if((j|0)!=(x|0)){continue}break}}i=o&3;if(!i){break $}while(1){j=r+(k<<2)|0;if(z==K[j>>2]){G[j>>2]=-1}k=k+1|0;m=m+1|0;if((i|0)!=(m|0)){continue}break}break $}if((o|0)<=0){break $}V=K[g>>2];k=0;while(1){j=r+(k<<2)|0;z=K[j>>2];i=l;ub:{if(z==V){break ub}vb:{t=+z;if(t<-2147483648.49){G[h>>2]=-11;break vb}if(t>2147483647.49){G[h>>2]=-11;i=2147483647;break ub}if(z>=N(0)){t=t+.5;if(!(O(t)<2147483648)){break vb}i=~~t;break ub}t=t+-.5;if(!(O(t)<2147483648)){break vb}i=~~t;break ub}i=-2147483648}G[j>>2]=i;k=k+1|0;if((o|0)!=(k|0)){continue}break}}break Z}G[h>>2]=413}Fa=s+16|0;break C;case 71:A=_+24|0;ga=_+16|0;s=Fa-16|0;Fa=s;G[s+12>>2]=0;G[s+8>>2]=0;wb:{xb:{if((va|0)!=32&(va&-33)!=-64?1:t!=0|y!=1){Ua(7807);break xb}G[_+72>>2]=4;yb:{zb:{Ab:{Bb:{k=G[a+4>>2];if(G[k+1156>>2]>0){t=-91191291391491e-49;t=($|0)==1?L[g>>3]:t;j=0;Cb:{Db:{m=G[k+1080>>2];switch(m+1|0){case 0:break Cb;case 2:case 3:break Db;default:break Bb}}i=G[k+1028>>2];Eb:{if(!i){if(G[k+1084>>2]){break Eb}j=Wc(0);k=sq();i=G[a+4>>2];G[i+1084>>2]=((G[i+76>>2]+(j+((k|0)/1e4|0)|0)|0)%1e4|0)+1;Jc(a,31,41550,i+1084|0,0,h);break Eb}if((i&G[k+1084>>2])>=0){break Eb}w=k+1084|0;if((o|0)>0){i=o<<3;i=(i|0)>1?i:1;n=i&1;k=0;if(i-1>>>0>=3){i=i&2147483640;m=0;while(1){x=H[r+(k|3)|0]+(H[r+(k|2)|0]+(H[r+(k|1)|0]+(H[k+r|0]+x|0)|0)|0)|0;k=k+4|0;m=m+4|0;if((i|0)!=(m|0)){continue}break}}if(n){while(1){x=H[k+r|0]+x|0;k=k+1|0;j=j+1|0;if((n|0)!=(j|0)){continue}break}}i=((x>>>0)%1e4|0)+1|0}else{i=1}G[w>>2]=i;Jc(a,31,41550,w,0,h)}k=G[a+4>>2];j=(Ba+G[k+1084>>2]|0)-1|0;m=G[k+1080>>2]}w=j;ya=t;z=K[k+1076>>2];q=m;i=0;t=0;j=0;y=0;u=0;W=M(ba,na);Fb:{Gb:{if((W|0)<2){Z=1;k=0;break Gb}Hb:{Ib:{Jb:{Kb:{Lb:{Mb:{if(z>=N(0)){k=(ba|0)<9;n=M(k?na:1,ba);if((n|0)<=8){if((n|0)<=0){U=-17976931348623157e292;P=17976931348623157e292;break Jb}Nb:{Ob:{if($){m=n&1;if((n|0)!=1){break Ob}k=0;P=17976931348623157e292;U=-17976931348623157e292;break Nb}j=n&3;Pb:{if(n-1>>>0<3){P=17976931348623157e292;U=-17976931348623157e292;k=0;break Pb}m=n&-4;k=0;P=17976931348623157e292;U=-17976931348623157e292;while(1){i=k<<3;t=L[r+(i|24)>>3];y=L[r+(i|16)>>3];Z=L[r+(i|8)>>3];sa=L[i+r>>3];ta=Uta?Z:ta;ta=y>ta?y:ta;U=t>ta?t:ta;sa=P>sa?sa:P;Z=Z>3];if(t!=ya){U=t>U?t:U;P=t>3];if(t!=ya){U=t>U?t:U;P=t>3];if(t==ya){break Jb}U=t>U?t:U;P=t0){break Rb}U=-17976931348623157e292;P=17976931348623157e292;break Qb}Wa(da);Wa(B);Wa(fa);Wa(Y);Wa(ha);break Lb}la=($|0)!=0;P=17976931348623157e292;U=-17976931348623157e292;while(1){x=r+(M(n,u)<<3)|0;k=0;m=0;Sb:{Tb:{if(!$){break Tb}while(1){if(L[x+(k<<3)>>3]!=ya){m=k;break Tb}k=k+1|0;if((n|0)!=(k|0)){continue}break}break Sb}if((m|0)==(n|0)){break Sb}Z=L[x+(m<<3)>>3];U=UZ?Z:P;j=i+1|0;Ub:{k=m+1|0;if(!(la&(n|0)>(k|0))){break Ub}while(1){if(L[x+(k<<3)>>3]!=ya){break Ub}k=k+1|0;if((n|0)!=(k|0)){continue}break}i=j;break Sb}if((k|0)==(n|0)){i=j;break Sb}t=L[x+(k<<3)>>3];U=t>U?t:U;P=t(k|0))){break Vb}while(1){if(L[x+(k<<3)>>3]!=ya){break Vb}k=k+1|0;if((n|0)!=(k|0)){continue}break}i=j;break Sb}if((k|0)==(n|0)){i=j;break Sb}sa=L[x+(k<<3)>>3];U=Usa?sa:P;j=i+3|0;Wb:{k=k+1|0;if(!(la&(n|0)>(k|0))){break Wb}while(1){if(L[x+(k<<3)>>3]!=ya){break Wb}k=k+1|0;if((n|0)!=(k|0)){continue}break}i=j;break Sb}if((k|0)==(n|0)){i=j;break Sb}y=L[x+(k<<3)>>3];U=y>U?y:U;P=y(k|0))){break Xb}while(1){if(L[x+(k<<3)>>3]!=ya){break Xb}k=k+1|0;if((n|0)!=(k|0)){continue}break}i=j;break Sb}if((k|0)==(n|0)){i=j;break Sb}ra=L[x+(k<<3)>>3];U=Ura?ra:P;j=i+5|0;Yb:{k=k+1|0;if(!(la&(n|0)>(k|0))){break Yb}while(1){if(L[x+(k<<3)>>3]!=ya){break Yb}k=k+1|0;if((n|0)!=(k|0)){continue}break}i=j;break Sb}if((k|0)==(n|0)){i=j;break Sb}ta=L[x+(k<<3)>>3];U=Uta?ta:P;j=i+6|0;Zb:{k=k+1|0;if(!(la&(n|0)>(k|0))){break Zb}while(1){if(L[x+(k<<3)>>3]!=ya){break Zb}k=k+1|0;if((n|0)!=(k|0)){continue}break}i=j;break Sb}if((k|0)==(n|0)){i=j;break Sb}ib=L[x+(k<<3)>>3];U=Uib?ib:P;j=i+7|0;_b:{k=k+1|0;if(!(la&(n|0)>(k|0))){break _b}while(1){if(L[x+(k<<3)>>3]!=ya){break _b}k=k+1|0;if((n|0)!=(k|0)){continue}break}i=j;break Sb}if((k|0)==(n|0)){i=j;break Sb}Ma=L[x+(k<<3)>>3];U=UMa?Ma:P;i=i+8|0;m=0;C=0;k=k+1|0;if((n|0)<=(k|0)){break Sb}while(1){$b:{cc=t;t=sa;sa=y;y=ra;ra=ta;ta=ib;ib=Ma;ac:{if(!(la&(k|0)<(n|0))){break ac}while(1){if(L[x+(k<<3)>>3]!=ya){break ac}k=k+1|0;if((n|0)!=(k|0)){continue}break}break $b}if((k|0)==(n|0)){break $b}Ma=L[x+(k<<3)>>3];j=y!=ra;if(!(!j&ra==ta)){L[da+(C<<3)>>3]=O(y-ta);C=C+1|0}ja=UMa;bc:{cc:{if(!(j|(t!=sa|y!=sa))){if(ra==ta){break cc}}j=m<<3;L[j+B>>3]=O(y+y-t-ta);L[j+fa>>3]=O(Z+(ta*-4+(y*6+t*-4))+Ma);m=m+1|0;break bc}i=i+1|0}U=ja?Ma:U;P=oa?Ma:P;Z=cc;k=k+1|0;if((n|0)>(k|0)){continue}}break}i=i+m|0;j=ka+(X<<3)|0;dc:{ec:{switch(m|0){case 1:if((C|0)==1){L[Y+(aa<<3)>>3]=L[da>>3];aa=aa+1|0}L[ha+(X<<3)>>3]=L[B>>3];t=L[fa>>3];break dc;case 0:break Sb;default:break ec}}if((C|0)>=2){ec=Y+(aa<<3)|0,fc=Mi(da,m),L[ec>>3]=fc;aa=aa+1|0}ec=ha+(X<<3)|0,fc=Mi(B,m),L[ec>>3]=fc;t=Mi(fa,m)}L[j>>3]=t;X=X+1|0}u=u+1|0;if((ma|0)!=(u|0)){continue}break}y=0;sa=0;Z=0;fc:{gc:{switch(X|0){case 1:Z=L[ka>>3];sa=L[ha>>3];break fc;case 0:break fc;default:break gc}}oe(ha,X,8,14);oe(ka,X,8,14);j=(X-1|0)/2<<3;k=(X|0)/2<<3;Z=(L[j+ka>>3]+L[k+ka>>3])*.5;sa=(L[j+ha>>3]+L[k+ha>>3])*.5}hc:{switch(aa|0){case 1:y=L[Y>>3];break Qb;case 0:break Qb;default:break hc}}oe(Y,aa,8,14);y=(L[Y+((aa-1|0)/2<<3)>>3]+L[Y+((aa|0)/2<<3)>>3])*.5}Wa(ka);Wa(ha);Wa(Y);Wa(fa);Wa(B);Wa(da);t=Z*.1772048;ra=y*1.0483579;y=sa*.6052697;break Ib}Z=+N(-z);ic:{k=(ba|0)<5;i=M(k?na:1,ba);if((i|0)<=4){if((i|0)<=0){break ic}jc:{kc:{if($){m=i&1;if((i|0)!=1){break kc}i=0;P=17976931348623157e292;U=-17976931348623157e292;k=0;break jc}m=i&3;lc:{if(i-1>>>0<3){P=17976931348623157e292;U=-17976931348623157e292;k=0;break lc}n=i&-4;k=0;P=17976931348623157e292;U=-17976931348623157e292;while(1){j=k<<3;t=L[r+(j|24)>>3];y=L[r+(j|16)>>3];ra=L[r+(j|8)>>3];sa=L[j+r>>3];ta=Uta?ra:ta;ta=y>ta?y:ta;U=t>ta?t:ta;sa=P>sa?sa:P;ra=ra>3];U=t>U?t:U;P=t>3];if(t!=ya){U=t>U?t:U;P=t>3];if(t!=ya){U=t>U?t:U;P=t>3];if(t==ya){break Hb}U=t>U?t:U;P=t>3]!=ya){u=k;break nc}k=k+1|0;if((k|0)!=(i|0)){continue}break}break mc}if((i|0)==(u|0)){break mc}t=L[m+(u<<3)>>3];U=t>U?t:U;P=t>3]!=ya){break oc}k=k+1|0;if((k|0)!=(i|0)){continue}break}break mc}if((i|0)==(k|0)){break mc}t=L[m+(k<<3)>>3];U=t>U?t:U;P=t>3]!=ya){break pc}k=k+1|0;if((k|0)!=(i|0)){continue}break}break mc}if((i|0)==(k|0)){break mc}t=L[m+(k<<3)>>3];U=t>U?t:U;P=t>3]!=ya){break qc}k=k+1|0;if((k|0)!=(i|0)){continue}break}break mc}if((i|0)==(k|0)){break mc}t=L[m+(k<<3)>>3];U=t>U?t:U;P=t=(i|0)){break rc}while(1){sc:{if(!(n&(i|0)>(k|0))){break sc}while(1){if(L[m+(k<<3)>>3]!=ya){break sc}k=k+1|0;if((k|0)!=(i|0)){continue}break}break rc}if((i|0)==(k|0)){break rc}t=L[m+(k<<3)>>3];U=t>U?t:U;P=t>3];U=t>U?t:U;P=tra?ra:y:y;t=t!=0?t4294967284){break Fb}uc:{vc:{wc:{xc:{yc:{if((w|0)>0){k=G[49098];if(!k){k=113;if(uo()){break Fb}k=G[49098]}i=(i|0)==(W|0);C=(w-1>>>0)%1e4|0;z=N(K[(C<<2)+k>>2]*N(500));if(!(N(O(z))=1?~~(t>0?Q(S(t*2.3283064365386963e-10),4294967295):T((t-+(~~t>>>0>>>0))*2.3283064365386963e-10))>>>0:0;i=~~t>>>0;break Ac}j=-2147483648;i=0}t=Z*(+(i>>>0)+ +(j|0)*4294967296);break zc}t=(P+U)*.5}if((w|0)<=0){if((W|0)<=0){break uc}k=0;if((W|0)!=1){m=W&-2;i=0;while(1){w=r+(k<<2)|0;y=(L[r+(k<<3)>>3]-t)/Z;y=y+(y>=0?.5:-.5);Bc:{if(O(y)<2147483648){j=~~y;break Bc}j=-2147483648}G[w>>2]=j;n=k|1;y=(L[r+(n<<3)>>3]-t)/Z;y=y+(y>=0?.5:-.5);Cc:{if(O(y)<2147483648){j=~~y;break Cc}j=-2147483648}G[r+(n<<2)>>2]=j;k=k+2|0;i=i+2|0;if((m|0)!=(i|0)){continue}break}}if(!(W&1)){break uc}j=r+(k<<2)|0;y=(L[r+(k<<3)>>3]-t)/Z;y=y+(y>=0?.5:-.5);Dc:{if(O(y)<2147483648){i=~~y;break Dc}i=-2147483648}G[j>>2]=i;break uc}if((W|0)<=0){break uc}m=G[49098];n=(q|0)!=2;i=0;while(1){y=L[r+(i<<3)>>3];w=r+(i<<2)|0;Ec:{if(!n){j=-2147483646;if(y==0){break Ec}}y=(y-t)/Z+ +K[m+(k<<2)>>2]+-.5;y=y+(y>=0?.5:-.5);if(O(y)<2147483648){j=~~y;break Ec}j=-2147483648}G[w>>2]=j;k=k+1|0;Fc:{if((k|0)!=1e4){break Fc}j=C+1|0;C=(j|0)==1e4?0:j;z=N(K[m+(C<<2)>>2]*N(500));if(N(O(z))>3];j=-2147483647;Gc:{if(y==ya){break Gc}if(!n){j=-2147483646;if(y==0){break Gc}}y=(y-t)/Z+ +K[m+(k<<2)>>2]+-.5;y=y+(y>=0?.5:-.5);if(O(y)<2147483648){j=~~y;break Gc}j=-2147483648}G[w>>2]=j;k=k+1|0;Hc:{if((k|0)!=1e4){break Hc}j=C+1|0;C=(j|0)==1e4?0:j;z=N(K[m+(C<<2)>>2]*N(500));if(N(O(z))>3];i=-2147483647;Ic:{if(y==ya){break Ic}y=(y-t)/Z;y=y+(y>=0?.5:-.5);if(O(y)<2147483648){i=~~y;break Ic}i=-2147483648}G[j>>2]=i;k=k+1|0;if((W|0)!=(k|0)){continue}break}}y=(P-t)/Z;y=y+(y>=0?.5:-.5);Jc:{if(O(y)<2147483648){i=~~y;break Jc}i=-2147483648}G[s+12>>2]=i;y=(U-t)/Z;y=y+(y>=0?.5:-.5);Kc:{if(O(y)<2147483648){i=~~y;break Kc}i=-2147483648}G[s+8>>2]=i;k=1}L[A>>3]=Z;L[ga>>3]=t}G[_+76>>2]=k;if((k|0)<2){break yb}G[h>>2]=k;break wb}if(K[k+1076>>2]==N(9999)){break Ab}if(($|0)==1){break zb}k=0;if((o|0)<=0){break yb}while(1){j=r+(k<<2)|0;Lc:{Mc:{t=L[r+(k<<3)>>3];if(t<-2147483648.49){G[h>>2]=-11;break Mc}if(t>2147483647.49){G[h>>2]=-11;i=2147483647;break Lc}if(t>=0){t=t+.5;if(!(O(t)<2147483648)){break Mc}i=~~t;break Lc}t=t+-.5;if(!(O(t)<2147483648)){break Mc}i=~~t;break Lc}i=-2147483648}G[j>>2]=i;k=k+1|0;if((o|0)!=(k|0)){continue}break}break yb}Ua(44341);Ua(45142);break xb}if(($|0)!=1|(o|0)<=0){break yb}t=L[g>>3];k=0;if(o-1>>>0>=3){n=o&-4;j=0;while(1){i=k<<3;m=i+r|0;if(t==L[m>>3]){G[m>>2]=-1;G[m+4>>2]=-1}m=r+(i|8)|0;if(t==L[m>>3]){G[m>>2]=-1;G[m+4>>2]=-1}m=r+(i|16)|0;if(t==L[m>>3]){G[m>>2]=-1;G[m+4>>2]=-1}i=r+(i|24)|0;if(t==L[i>>3]){G[i>>2]=-1;G[i+4>>2]=-1}k=k+4|0;j=j+4|0;if((n|0)!=(j|0)){continue}break}}j=o&3;if(!j){break yb}while(1){i=r+(k<<3)|0;if(t==L[i>>3]){G[i>>2]=-1;G[i+4>>2]=-1}k=k+1|0;x=x+1|0;if((j|0)!=(x|0)){continue}break}break yb}if((o|0)<=0){break yb}y=L[g>>3];k=0;while(1){j=r+(k<<2)|0;t=L[r+(k<<3)>>3];i=l;Nc:{if(t==y){break Nc}Oc:{if(t<-2147483648.49){G[h>>2]=-11;break Oc}if(t>2147483647.49){G[h>>2]=-11;i=2147483647;break Nc}if(t>=0){t=t+.5;if(!(O(t)<2147483648)){break Oc}i=~~t;break Nc}t=t+-.5;if(!(O(t)<2147483648)){break Oc}i=~~t;break Nc}i=-2147483648}G[j>>2]=i;k=k+1|0;if((o|0)!=(k|0)){continue}break}}break wb}G[h>>2]=413}Fa=s+16|0;break C;default:Ua(60591);G[h>>2]=410;break w;case 10:break D}}k=o;Z=L[j+1200>>3];Pc:{if(!(!((va|0)!=16|y!=1)&t==0)){Ua(7887);G[h>>2]=413;break Pc}Qc:{Rc:{Sc:{switch(G[G[a+4>>2]+1048>>2]-11|0){case 0:case 10:case 11:case 40:G[_+72>>2]=2;if(($|0)!=1){break Qc}i=F[g>>1];if((i|0)==(l|0)|(k|0)<=0){break Qc}m=k-1|0;s=k&3;if(s){j=0;n=i&65535;while(1){k=k-1|0;w=r+(k<<1)|0;if((n|0)==I[w>>1]){F[w>>1]=l}j=j+1|0;if((s|0)!=(j|0)){continue}break}}if(m>>>0<3){break Qc}i=i&65535;while(1){j=r+(k<<1)|0;m=j-2|0;if((i|0)==I[m>>1]){F[m>>1]=l}j=j-4|0;if((i|0)==I[j>>1]){F[j>>1]=l}j=k-3|0;m=r+(j<<1)|0;if((i|0)==I[m>>1]){F[m>>1]=l}k=k-4|0;m=r+(k<<1)|0;if((i|0)==I[m>>1]){F[m>>1]=l}if(j>>>0>1){continue}break};break Qc;case 30:G[_+72>>2]=4;if(($|0)==1){if((k|0)<=0){break Qc}i=I[g>>1];s=k-1|0;n=k&3;if(n){j=0;while(1){k=k-1|0;m=I[r+(k<<1)>>1];G[r+(k<<2)>>2]=(i|0)==(m|0)?l:m<<16>>16;j=j+1|0;if((n|0)!=(j|0)){continue}break}}if(s>>>0<3){break Qc}while(1){m=k-1|0;j=I[r+(m<<1)>>1];G[r+(m<<2)>>2]=(i|0)==(j|0)?l:j<<16>>16;m=k-2|0;j=F[r+(m<<1)>>1];G[r+(m<<2)>>2]=(i|0)==(j&65535)?l:j;j=k-3|0;m=F[r+(j<<1)>>1];G[r+(j<<2)>>2]=(i|0)==(m&65535)?l:m;k=k-4|0;m=F[r+(k<<1)>>1];G[r+(k<<2)>>2]=(i|0)==(m&65535)?l:m;if(j>>>0>1){continue}break}break Qc}if(G[h>>2]>0){break Qc}n=(k|0)<1e4?k:1e4;i=ab(n<<2);if(!i){break Rc}Tc:{if((k|0)<=0){break Tc}j=k-n|0;while(1){Uc:{if((n|0)<=0){break Uc}m=0;k=0;if(n-1>>>0>=3){s=n&-4;x=0;while(1){G[i+(k<<2)>>2]=F[r+(j+k<<1)>>1];w=k|1;G[i+(w<<2)>>2]=F[r+(j+w<<1)>>1];w=k|2;G[i+(w<<2)>>2]=F[r+(j+w<<1)>>1];w=k|3;G[i+(w<<2)>>2]=F[r+(j+w<<1)>>1];k=k+4|0;x=x+4|0;if((s|0)!=(x|0)){continue}break}}s=n&3;if(!s){break Uc}while(1){G[i+(k<<2)>>2]=F[r+(j+k<<1)>>1];k=k+1|0;m=m+1|0;if((s|0)!=(m|0)){continue}break}}bb(r+(j<<2)|0,i,n<<2);if(!j){break Tc}k=(j|0)>1e4;n=k?n:j;j=j?k?j-1e4|0:0:0;if((n|0)>0){continue}break}}Wa(i);break Qc;default:break Sc}}G[_+72>>2]=4;if(Z==32768){if(($|0)==1){if((k|0)<=0){break Qc}i=I[g>>1];j=k;if(j&1){j=k-1|0;m=I[r+(j<<1)>>1];G[r+(j<<2)>>2]=(i|0)==(m|0)?l:(m<<16>>16)+32768|0}if((k|0)==1){break Qc}while(1){k=j-1|0;m=I[r+(k<<1)>>1];G[r+(k<<2)>>2]=(i|0)==(m|0)?l:(m<<16>>16)+32768|0;j=j-2|0;m=F[r+(j<<1)>>1];G[r+(j<<2)>>2]=(i|0)==(m&65535)?l:m+32768|0;if(k>>>0>1){continue}break}break Qc}if(G[h>>2]>0){break Qc}n=(k|0)<1e4?k:1e4;i=ab(n<<2);if(!i){break Rc}Vc:{if((k|0)<=0){break Vc}j=k-n|0;while(1){Wc:{if((n|0)<=0){break Wc}m=0;k=0;if(n-1>>>0>=3){s=n&-4;x=0;while(1){G[i+(k<<2)>>2]=F[r+(j+k<<1)>>1]+32768;w=k|1;G[i+(w<<2)>>2]=F[r+(j+w<<1)>>1]+32768;w=k|2;G[i+(w<<2)>>2]=F[r+(j+w<<1)>>1]+32768;w=k|3;G[i+(w<<2)>>2]=F[r+(j+w<<1)>>1]+32768;k=k+4|0;x=x+4|0;if((s|0)!=(x|0)){continue}break}}s=n&3;if(!s){break Wc}while(1){G[i+(k<<2)>>2]=F[r+(j+k<<1)>>1]+32768;k=k+1|0;m=m+1|0;if((s|0)!=(m|0)){continue}break}}bb(r+(j<<2)|0,i,n<<2);if(!j){break Vc}k=(j|0)>1e4;n=k?n:j;j=j?k?j-1e4|0:0:0;if((n|0)>0){continue}break}}Wa(i);break Qc}if(($|0)==1){if((k|0)<=0){break Qc}i=I[g>>1];s=k-1|0;n=k&3;if(n){j=0;while(1){k=k-1|0;m=I[r+(k<<1)>>1];G[r+(k<<2)>>2]=(i|0)==(m|0)?l:m<<16>>16;j=j+1|0;if((n|0)!=(j|0)){continue}break}}if(s>>>0<3){break Qc}while(1){m=k-1|0;j=I[r+(m<<1)>>1];G[r+(m<<2)>>2]=(i|0)==(j|0)?l:j<<16>>16;m=k-2|0;j=F[r+(m<<1)>>1];G[r+(m<<2)>>2]=(i|0)==(j&65535)?l:j;j=k-3|0;m=F[r+(j<<1)>>1];G[r+(j<<2)>>2]=(i|0)==(m&65535)?l:m;k=k-4|0;m=F[r+(k<<1)>>1];G[r+(k<<2)>>2]=(i|0)==(m&65535)?l:m;if(j>>>0>1){continue}break}break Qc}if(G[h>>2]>0){break Qc}n=(k|0)<1e4?k:1e4;i=ab(n<<2);if(!i){break Rc}Xc:{if((k|0)<=0){break Xc}j=k-n|0;while(1){Yc:{if((n|0)<=0){break Yc}m=0;k=0;if(n-1>>>0>=3){s=n&-4;x=0;while(1){G[i+(k<<2)>>2]=F[r+(j+k<<1)>>1];w=k|1;G[i+(w<<2)>>2]=F[r+(j+w<<1)>>1];w=k|2;G[i+(w<<2)>>2]=F[r+(j+w<<1)>>1];w=k|3;G[i+(w<<2)>>2]=F[r+(j+w<<1)>>1];k=k+4|0;x=x+4|0;if((s|0)!=(x|0)){continue}break}}s=n&3;if(!s){break Yc}while(1){G[i+(k<<2)>>2]=F[r+(j+k<<1)>>1];k=k+1|0;m=m+1|0;if((s|0)!=(m|0)){continue}break}}bb(r+(j<<2)|0,i,n<<2);if(!j){break Xc}k=(j|0)>1e4;n=k?n:j;j=j?k?j-1e4|0:0:0;if((n|0)>0){continue}break}}Wa(i);break Qc}Ua(61735);G[h>>2]=113}}}if(G[h>>2]>0){break w}i=G[a+4>>2];Zc:{_c:{if(G[_+76>>2]){Ea=G[i+1140>>2];G[_+68>>2]=Ea;w=lb(Ea,1);G[_+64>>2]=w;if(!w){Ua(60886);break Zc}$c:{ad:{bd:{cd:{dd:{ed:{fd:{gd:{n=G[i+1048>>2];switch(n-11|0){case 30:break ad;case 40:break bd;case 10:case 11:break cd;case 0:break fd;case 20:break gd;default:break $c}}j=0;if((o|0)<=0){break dd}break ed}hd:{id:{switch(G[_+72>>2]-1|0){case 1:m=0;s=G[i+1212>>2];X=ab(s<<2);jd:{if(!X){Ua(2991);i=-1;break jd}i=r;q=I[i>>1];l=q<<8|q>>>8;E[w|0]=l;E[w+1|0]=l>>>8;l=w+2|0;kd:{if((o|0)<=0){break kd}v=o;W=w+Ea|0;x=I[i>>1];o=s;k=8;while(1){j=v-m|0;o=(j|0)<(s|0)?j:o;u=(o|0)<=0;ld:{if(u){t=0;break ld}aa=o&1;md:{if((o|0)==1){j=0;t=0;break md}da=o&-2;j=0;t=0;p=0;while(1){n=I[i+(j+m<<1)>>1];x=n-x<<16;Y=x>>16<<1^x>>31;G[X+(j<<2)>>2]=Y;C=j|1;x=I[i+(C+m<<1)>>1];n=x-n<<16;n=n>>16<<1^n>>31;G[X+(C<<2)>>2]=n;t=t+ +(Y>>>0)+ +(n>>>0);j=j+2|0;p=p+2|0;if((da|0)!=(p|0)){continue}break}}if(aa){n=X+(j<<2)|0;j=I[i+(j+m<<1)>>1];p=j-x<<16;p=p>>16<<1^p>>31;G[n>>2]=p;t=t+ +(p>>>0);x=j}x=x&65535}p=0;nd:{od:{y=R((t-+((o|0)/2|0)+-1)/+(o|0),0);pd:{if(y<4294967296&y>=0){j=~~y>>>0;break pd}j=0}aa=j>>>0<2;qd:{if(!aa){while(1){n=p;p=n+1|0;da=j&65535;j=da>>>1|0;if(da>>>0>3){continue}break}if(n>>>0<13){break qd}j=4;if((k|0)>=29){j=4-k|0;q=G[(k<<2)+104832>>2]&15>>>j|q<>2]&15|q<>0-k;l=l+1|0;j=(k|0)<-7;k=k+8|0;if(j){continue}break}}p=0;if(u){break nd}while(1){n=G[X+(p<<2)>>2];j=16;if((k|0)>=17){j=16-k|0;q=G[(k<<2)+104832>>2]&n>>j|q<>2]|q<>0-k;l=l+1|0;j=(k|0)<-7;k=k+8|0;if(j){continue}break}}p=p+1|0;if((o|0)!=(p|0)){continue}break}break nd}if(t==0){break od}}n=p+1|0;j=4;if((k|0)>=29){j=4-k|0;q=G[(k<<2)+104832>>2]&n>>>j|q<>2]|q<>0-k;l=l+1|0;j=(k|0)<-7;k=k+8|0;if(j){continue}break}}if(!u){da=-1<>2];n=Y>>p;rd:{if((n|0)<(k|0)){j=n+1|0;k=k-j|0;q=q<>>3|0;cb(fa,0,C+1|0);q=(n-((j&-8)+k|0)|0)-8|0;j=(l+C|0)+2|0}l=j;k=7-q|0;q=1}sd:{if(aa){break sd}q=Y&da|q<0){break sd}while(1){E[l|0]=q>>0-k;l=l+1|0;j=(k|0)<-7;k=k+8|0;if(j){continue}break}}u=u+1|0;if((u|0)!=(o|0)){continue}break}}if(l>>>0<=W>>>0){break nd}Ua(11479);Wa(X);i=-1;break jd}j=4;if((k|0)>=29){q=q<0){break nd}while(1){E[l|0]=q>>0-k;l=l+1|0;j=(k|0)<-7;k=k+8|0;if(j){continue}break}}m=m+s|0;if((v|0)>(m|0)){continue}break}if((k|0)>7){break kd}E[l|0]=q<>2];X=ab(k<<2);td:{if(!X){Ua(2991);i=-1;break td}i=r;q=H[i|0];E[w|0]=q;p=w+1|0;v=o;ud:{if((o|0)<=0){break ud}W=w+Ea|0;x=H[i|0];s=k;l=8;while(1){o=v-m|0;s=(k|0)>(o|0)?o:s;u=(s|0)<=0;vd:{if(u){t=0;break vd}aa=s&1;wd:{if((s|0)==1){j=0;t=0;break wd}da=s&-2;j=0;t=0;o=0;while(1){n=H[i+(j+m|0)|0];x=n-x<<24;Y=x>>24<<1^x>>31;G[X+(j<<2)>>2]=Y;C=j|1;x=H[i+(C+m|0)|0];n=x-n<<24;n=n>>24<<1^n>>31;G[X+(C<<2)>>2]=n;t=t+ +(Y>>>0)+ +(n>>>0);j=j+2|0;o=o+2|0;if((da|0)!=(o|0)){continue}break}}if(aa){n=X+(j<<2)|0;o=H[i+(j+m|0)|0];j=o-x<<24;j=j>>24<<1^j>>31;G[n>>2]=j;t=t+ +(j>>>0);x=o}x=x&255}o=0;xd:{yd:{y=R((t-+((s|0)/2|0)+-1)/+(s|0),0);zd:{if(y<4294967296&y>=0){j=~~y>>>0;break zd}j=0}aa=j>>>0<2;Ad:{if(!aa){while(1){n=o;o=n+1|0;da=j&255;j=da>>>1|0;if(da>>>0>3){continue}break}if(n>>>0<5){break Ad}j=3;if((l|0)>=30){j=3-l|0;q=G[(l<<2)+104832>>2]&7>>>j|q<>2]&7|q<>0-l;p=p+1|0;o=(l|0)<-7;l=l+8|0;if(o){continue}break}}o=0;if(u){break xd}while(1){n=G[X+(o<<2)>>2];j=8;if((l|0)>=25){j=8-l|0;q=G[(l<<2)+104832>>2]&n>>j|q<>2]|q<>0-l;p=p+1|0;j=(l|0)<-7;l=l+8|0;if(j){continue}break}}o=o+1|0;if((s|0)!=(o|0)){continue}break}break xd}if(t==0){break yd}}n=o+1|0;j=3;if((l|0)>=30){j=3-l|0;q=G[(l<<2)+104832>>2]&n>>>j|q<>2]|q<>0-l;p=p+1|0;j=(l|0)<-7;l=l+8|0;if(j){continue}break}}if(!u){da=-1<>2];n=Y>>o;Bd:{if((n|0)<(l|0)){j=n+1|0;l=l-j|0;q=q<>>3|0;cb(fa,0,C+1|0);q=(n-((j&-8)+l|0)|0)-8|0;j=(p+C|0)+2|0}p=j;l=7-q|0;q=1}Cd:{if(aa){break Cd}q=Y&da|q<0){break Cd}while(1){E[p|0]=q>>0-l;p=p+1|0;j=(l|0)<-7;l=l+8|0;if(j){continue}break}}u=u+1|0;if((s|0)!=(u|0)){continue}break}}if(p>>>0<=W>>>0){break xd}Ua(11479);Wa(X);i=-1;break td}j=3;if((l|0)>=30){q=q<0){break xd}while(1){E[p|0]=q>>0-l;p=p+1|0;o=(l|0)<-7;l=l+8|0;if(o){continue}break}}m=k+m|0;if((v|0)>(m|0)){continue}break}if((l|0)>7){break ud}E[p|0]=q<>2];X=ab(k<<2);Dd:{if(!X){Ua(2991);i=-1;break Dd}i=r;j=G[i>>2];l=j<<24|j<<8&16711680|(j>>>8&65280|j>>>24);E[w|0]=l;E[w+1|0]=l>>>8;E[w+2|0]=l>>>16;E[w+3|0]=l>>>24;l=w+4|0;s=o;Ed:{if((o|0)<=0){break Ed}W=w+Ea|0;m=G[i>>2];o=k;q=8;while(1){p=s-x|0;o=(k|0)>(p|0)?p:o;u=(o|0)<=0;Fd:{if(u){t=0;break Fd}aa=o&1;Gd:{if((o|0)==1){n=0;t=0;break Gd}da=o&-2;n=0;t=0;p=0;while(1){v=G[i+(n+x<<2)>>2];m=v-m|0;Y=m<<1^m>>31;G[X+(n<<2)>>2]=Y;C=n|1;m=G[i+(C+x<<2)>>2];v=m-v|0;v=v<<1^v>>31;G[X+(C<<2)>>2]=v;t=t+ +(Y>>>0)+ +(v>>>0);n=n+2|0;p=p+2|0;if((da|0)!=(p|0)){continue}break}}if(!aa){break Fd}p=G[i+(n+x<<2)>>2];m=p-m|0;m=m<<1^m>>31;G[X+(n<<2)>>2]=m;t=t+ +(m>>>0);m=p}p=0;Hd:{Id:{y=R((t-+((o|0)/2|0)+-1)/+(o|0),0);Jd:{if(y<4294967296&y>=0){n=~~y>>>0;break Jd}n=0}aa=n>>>0<2;Kd:{if(!aa){while(1){v=p;p=p+1|0;da=n>>>0>3;n=n>>>1|0;if(da){continue}break}if(v>>>0<24){break Kd}n=5;if((q|0)>=28){n=5-q|0;j=G[(q<<2)+104832>>2]&26>>>n|j<>2]&26|j<>0-q;l=l+1|0;p=(q|0)<-7;q=q+8|0;if(p){continue}break}}p=0;if(u){break Hd}while(1){n=G[X+(p<<2)>>2];v=32-q|0;j=G[(q<<2)+104832>>2]&n>>v|j<>2]|j<>0-q;l=l+1|0;v=(q|0)<-7;q=q+8|0;if(v){continue}break}}p=p+1|0;if((o|0)!=(p|0)){continue}break}break Hd}if(t==0){break Id}}v=p+1|0;n=5;if((q|0)>=28){n=5-q|0;j=G[(q<<2)+104832>>2]&v>>>n|j<>2]|j<>0-q;l=l+1|0;v=(q|0)<-7;q=q+8|0;if(v){continue}break}}if(!u){da=-1<>2];n=Y>>p;Ld:{if((n|0)<(q|0)){v=n+1|0;q=q-v|0;j=j<>>3|0;cb(fa,0,v+1|0);j=(n-((j&-8)+q|0)|0)-8|0;l=(l+v|0)+2|0}q=7-j|0;j=1}Md:{if(aa){break Md}j=Y&da|j<0){break Md}while(1){E[l|0]=j>>0-q;l=l+1|0;v=(q|0)<-7;q=q+8|0;if(v){continue}break}}u=u+1|0;if((u|0)!=(o|0)){continue}break}}if(l>>>0<=W>>>0){break Hd}Ua(11479);Wa(X);i=-1;break Dd}n=5;if((q|0)>=28){j=j<0){break Hd}while(1){E[l|0]=j>>0-q;l=l+1|0;p=(q|0)<-7;q=q+8|0;if(p){continue}break}}x=k+x|0;if((s|0)>(x|0)){continue}break}if((q|0)>7){break Ed}E[l|0]=j<>2]);Ua(60641);break x}pe(a,G[G[a+4>>2]+1144>>2],Ba,Ba>>31,1,0,i,0,G[_+64>>2],h);break $c}while(1){if(J[r+(j<<2)>>2]<16777216){j=j+1|0;if((o|0)!=(j|0)){continue}break dd}break}Ua(63440);break x}m=0;i=1;l=0;if((o|0)>0){v=w-2|0;F[w+4>>1]=65436;F[w+10>>1]=0;F[w+12>>1]=0;F[w>>1]=0;F[w+2>>1]=7;j=r;l=G[j>>2];l=(l|0)>0?l:0;n=o+1|0;X=n-1|0;k=8;s=1;p=1;q=1;while(1){Nd:{Od:{Pd:{if((p|0)<(X|0)){o=p+1|0;m=G[j+(p<<2)>>2];m=(m|0)>0?m:0;if((m|0)==(l|0)){p=o;break Nd}if(l){break Pd}p=o;break Od}q=l?q:n;o=p+1|0}i=q-i|0;Qd:{Rd:{x=(l|0)<=0;if(x){l=s;break Rd}if((l|0)==(s|0)){break Rd}s=l-s|0;u=s>>31;if((s^u)-u>>>0>=4096){s=k<<1;F[s+v>>1]=l&4095|4096;F[s+w>>1]=l>>>12;k=k+2|0;break Rd}u=v+(k<<1)|0;s=(s|0)<0?12288-s|0:s- -8192|0;F[u>>1]=s;k=k+1|0;if(i|(p|0)!=(q|0)){break Rd}F[u>>1]=s|16384;break Qd}Sd:{if((i|0)<=0){break Sd}while(1){s=v+(k<<1)|0;u=(i|0)<4095?i:4095;F[s>>1]=u;k=k+1|0;W=i>>>0>4095;i=i-4095|0;if(W){continue}break}if(x|(p|0)!=(q|0)){break Sd}F[s>>1]=u+20481;break Qd}i=o-q|0;if((i|0)<=0){break Qd}while(1){F[v+(k<<1)>>1]=((i|0)<4095?i:4095)+16384;k=k+1|0;p=i>>>0>4095;i=i-4095|0;if(p){continue}break}}s=l;i=o;p=i;o=i}q=o;l=m}m=l;if((n|0)>(p|0)){continue}break}l=k-1|0;i=(l|0)/32768|0;F[w+8>>1]=i;F[w+6>>1]=l-(i<<15)}if((l|0)<0){Wa(G[_+64>>2]);Ua(60698);break x}Ng(a,G[G[a+4>>2]+1144>>2],Ba,Ba>>31,1,0,l,0,G[_+64>>2],h);break $c}z=K[i+1076>>2];Td:{if(!((b|0)!=42|z!=N(9999))){ke(r,o);if(G[G[a+4>>2]+1048>>2]==22){to(r,o,o>>31)}o=o<<2;break Td}if(!((b|0)!=82|z!=N(9999))){Ge(r,o);if(G[G[a+4>>2]+1048>>2]==22){l=o>>31;k=l;i=o;m=i<<3;j=lb(1,m);if(!!i&(k|0)>=0|(k|0)>0){l=r;while(1){s=j+v|0;E[s|0]=H[l|0];s=i+s|0;E[s|0]=H[l+1|0];s=i+s|0;E[s|0]=H[l+2|0];s=i+s|0;E[s|0]=H[l+3|0];s=i+s|0;E[s|0]=H[l+4|0];s=i+s|0;E[s|0]=H[l+5|0];s=i+s|0;E[s|0]=H[l+6|0];E[i+s|0]=H[l+7|0];l=l+8|0;s=v+1|0;p=s?p:p+1|0;v=s;if((o|0)!=(s|0)|(k|0)!=(p|0)){continue}break}}bb(r,j,m);Wa(j)}o=o<<3;break Td}Ud:{switch(G[_+72>>2]-1|0){case 1:Af(r,o);if(G[G[a+4>>2]+1048>>2]==22){n=o<<1;i=ab(n);j=o>>31;Vd:{if(!o&(j|0)<=0|(j|0)<0){break Vd}l=r;s=i;k=o;m=j-!k|0;k=k-1|0;if(!m&k>>>0>=3|m){k=o&-4;while(1){E[s|0]=H[l|0];E[o+s|0]=H[l+1|0];E[s+1|0]=H[l+2|0];E[o+(s+1|0)|0]=H[l+3|0];E[s+2|0]=H[l+4|0];E[o+(s+2|0)|0]=H[l+5|0];E[s+3|0]=H[l+6|0];E[o+(s+3|0)|0]=H[l+7|0];s=s+4|0;l=l+8|0;m=v+4|0;p=m>>>0<4?p+1|0:p;v=m;if((k|0)!=(m|0)|(j|0)!=(p|0)){continue}break}}k=o&3;j=0;if(!(k|j)){break Vd}v=0;p=0;while(1){E[s|0]=H[l|0];E[o+s|0]=H[l+1|0];s=s+1|0;l=l+2|0;w=p;p=v+1|0;w=p?w:w+1|0;v=p;p=w;if((k|0)!=(v|0)|(j|0)!=(p|0)){continue}break}}bb(r,i,n);Wa(i)}o=o<<1;break Td;case 3:ke(r,o);n=G[G[a+4>>2]+1048>>2];break;case 0:break Td;default:break Ud}}if((n|0)==22){to(r,o,o>>31)}o=o<<2}gp(r,o,_- -64|0,_+68|0,_+60|0,h);pe(a,G[G[a+4>>2]+1144>>2],Ba,Ba>>31,1,0,G[_+60>>2],0,G[_+64>>2],h);break $c}Wd:{Xd:{switch(G[_+72>>2]-2|0){case 0:Af(r,o);break Wd;case 2:break Xd;default:break Wd}}ke(r,o)}Ua(10683);break x}qa=K[i+1220>>2];Yd:{if(qa>N(0)){W=l;Ha=_+48|0;Qa=_+32|0;u=0;s=0;t=0;y=0;ra=0;Ja=_+40|0;Zd:{if(!Ja){break Zd}_d:{$d:{ae:{be:{i=(ba|0)<9;B=M(i?na:1,ba);if((B|0)<=8){if((B|0)<=0){break $d}ce:{de:{if($){if((B|0)!=1){break de}break ce}s=B&3;i=0;ee:{if(B-1>>>0<3){A=2147483647;C=-2147483648;l=0;break ee}n=B&-4;l=0;A=2147483647;C=-2147483648;while(1){j=l<<2;k=G[r+(j|12)>>2];p=G[r+(j|8)>>2];m=G[r+(j|4)>>2];j=G[j+r>>2];w=(j|0)>(C|0)?j:C;w=(m|0)>(w|0)?m:w;w=(p|0)>(w|0)?p:w;C=(k|0)>(w|0)?k:w;j=(j|0)<(A|0)?j:A;j=(j|0)>(m|0)?m:j;j=(j|0)>(p|0)?p:j;A=(j|0)>(k|0)?k:j;l=l+4|0;v=v+4|0;if((n|0)!=(v|0)){continue}break}}if(s){break be}break $d}k=B&-2;A=2147483647;C=-2147483648;l=0;while(1){p=u<<2;i=G[p+r>>2];if((i|0)!=(W|0)){C=(i|0)>(C|0)?i:C;A=(i|0)<(A|0)?i:A;l=l+1|0}i=G[r+(p|4)>>2];if((i|0)!=(W|0)){C=(i|0)>(C|0)?i:C;A=(i|0)<(A|0)?i:A;l=l+1|0}u=u+2|0;s=s+2|0;if((k|0)!=(s|0)){continue}break}}break $d}fa=lb(B,8);if(!fa){break ae}ka=lb(B,8);if(!ka){Wa(fa);break ae}ga=lb(B,8);if(!ga){Wa(fa);Wa(ka);break ae}Ca=i?1:na;ma=lb(Ca,8);if(!ma){Wa(fa);Wa(ka);Wa(ga);break ae}ja=lb(Ca,8);if(!ja){Wa(fa);Wa(ka);Wa(ga);Wa(ma);break ae}fe:{ge:{Aa=lb(Ca,8);if(Aa){if((Ca|0)>0){break ge}break fe}Wa(fa);Wa(ka);Wa(ga);Wa(ma);Wa(ja);break ae}oa=($|0)!=0;A=2147483647;C=-2147483648;l=0;while(1){ha=r+(M(B,La)<<2)|0;u=0;i=0;he:{ie:{if(!$){break ie}while(1){if((W|0)!=G[ha+(u<<2)>>2]){i=u;break ie}u=u+1|0;if((B|0)!=(u|0)){continue}break}break he}if((i|0)==(B|0)){break he}x=G[ha+(i<<2)>>2];C=(x|0)>(C|0)?x:C;A=(x|0)<(A|0)?x:A;j=l+1|0;je:{u=i+1|0;if(!(oa&(B|0)>(u|0))){break je}while(1){if((W|0)!=G[ha+(u<<2)>>2]){break je}u=u+1|0;if((B|0)!=(u|0)){continue}break}l=j;break he}if((u|0)==(B|0)){l=j;break he}i=G[ha+(u<<2)>>2];C=(i|0)>(C|0)?i:C;A=(i|0)<(A|0)?i:A;j=l+2|0;ke:{u=u+1|0;if(!(oa&(B|0)>(u|0))){break ke}while(1){if((W|0)!=G[ha+(u<<2)>>2]){break ke}u=u+1|0;if((B|0)!=(u|0)){continue}break}l=j;break he}if((u|0)==(B|0)){l=j;break he}n=G[ha+(u<<2)>>2];C=(n|0)>(C|0)?n:C;A=(n|0)<(A|0)?n:A;j=l+3|0;le:{u=u+1|0;if(!(oa&(B|0)>(u|0))){break le}while(1){if((W|0)!=G[ha+(u<<2)>>2]){break le}u=u+1|0;if((B|0)!=(u|0)){continue}break}l=j;break he}if((u|0)==(B|0)){l=j;break he}v=G[ha+(u<<2)>>2];C=(v|0)>(C|0)?v:C;A=(v|0)<(A|0)?v:A;j=l+4|0;me:{u=u+1|0;if(!(oa&(B|0)>(u|0))){break me}while(1){if((W|0)!=G[ha+(u<<2)>>2]){break me}u=u+1|0;if((B|0)!=(u|0)){continue}break}l=j;break he}if((u|0)==(B|0)){l=j;break he}s=G[ha+(u<<2)>>2];C=(s|0)>(C|0)?s:C;A=(s|0)<(A|0)?s:A;j=l+5|0;ne:{u=u+1|0;if(!(oa&(B|0)>(u|0))){break ne}while(1){if((W|0)!=G[ha+(u<<2)>>2]){break ne}u=u+1|0;if((B|0)!=(u|0)){continue}break}l=j;break he}if((u|0)==(B|0)){l=j;break he}j=G[ha+(u<<2)>>2];C=(j|0)>(C|0)?j:C;A=(j|0)<(A|0)?j:A;k=l+6|0;oe:{u=u+1|0;if(!(oa&(B|0)>(u|0))){break oe}while(1){if((W|0)!=G[ha+(u<<2)>>2]){break oe}u=u+1|0;if((B|0)!=(u|0)){continue}break}l=k;break he}if((u|0)==(B|0)){l=k;break he}m=G[ha+(u<<2)>>2];C=(m|0)>(C|0)?m:C;A=(m|0)<(A|0)?m:A;k=l+7|0;pe:{u=u+1|0;if(!(oa&(B|0)>(u|0))){break pe}while(1){if((W|0)!=G[ha+(u<<2)>>2]){break pe}u=u+1|0;if((B|0)!=(u|0)){continue}break}l=k;break he}if((u|0)==(B|0)){l=k;break he}q=G[ha+(u<<2)>>2];C=(q|0)>(C|0)?q:C;A=(q|0)<(A|0)?q:A;l=l+8|0;za=0;la=0;u=u+1|0;if((B|0)<=(u|0)){break he}while(1){qe:{k=i;i=n;n=v;v=s;s=j;j=m;m=q;re:{if(!(oa&(u|0)<(B|0))){break re}while(1){if((W|0)!=G[ha+(u<<2)>>2]){break re}u=u+1|0;if((B|0)!=(u|0)){continue}break}break qe}if((u|0)==(B|0)){break qe}q=G[ha+(u<<2)>>2];aa=(s|0)!=(v|0);if(!(!aa&(j|0)==(s|0))){p=(v>>31)-((j>>31)+(j>>>0>v>>>0)|0)|0;w=p>>31;da=fa+(la<<3)|0;Y=w^v-j;G[da>>2]=Y-w;G[da+4>>2]=(p^w)-((w>>>0>Y>>>0)+w|0);la=la+1|0}fb=(q|0)>(C|0);gb=(q|0)<(A|0);se:{te:{if(!(aa|((i|0)!=(n|0)|(n|0)!=(v|0)))){if((j|0)==(s|0)){break te}}Da=za<<3;da=Da+ka|0;w=v>>31;tb=w;p=v;w=w<<1|p>>>31;Y=p<<1;p=(i>>31)+(j>>31)|0;X=i+j|0;p=X>>>0>>0?p+1|0:p;aa=X;X=p;p=w-(p+(aa>>>0>Y>>>0)|0)|0;w=p>>31;Y=Y-aa|0;Xa=Y^w;G[da>>2]=Xa-w;G[da+4>>2]=(p^w)-((w>>>0>Xa>>>0)+w|0);da=ga+Da|0;Y=q>>31;Da=Au(v,tb,6,0);w=Da+x|0;p=Ia+(x>>31)|0;p=w>>>0>>0?p+1|0:p;x=p;p=X<<2|aa>>>30;aa=aa<<2;Da=w-aa|0;X=Da+q|0;w=(x-((w>>>0>>0)+p|0)|0)+Y|0;w=X>>>0>>0?w+1|0:w;p=w>>31;x=X^p;G[da>>2]=x-p;G[da+4>>2]=(p^w)-((x>>>0

>>0)+p|0);za=za+1|0;break se}l=l+1|0}C=fb?q:C;A=gb?q:A;x=k;u=u+1|0;if((B|0)>(u|0)){continue}}break}l=l+za|0;k=Aa+(pa<<3)|0;ue:{ve:{switch(za|0){case 1:if((la|0)==1){L[ma+(ea<<3)>>3]=+J[fa>>2]+ +G[fa+4>>2]*4294967296;ea=ea+1|0}L[ja+(pa<<3)>>3]=+J[ka>>2]+ +G[ka+4>>2]*4294967296;i=G[ga>>2];j=G[ga+4>>2];break ue;case 0:break he;default:break ve}}if((la|0)>=2){ec=ma+(ea<<3)|0,fc=+(Ik(fa,za)>>>0)+ +(Ia|0)*4294967296,L[ec>>3]=fc;ea=ea+1|0}ec=ja+(pa<<3)|0,fc=+(Ik(ka,za)>>>0)+ +(Ia|0)*4294967296,L[ec>>3]=fc;i=Ik(ga,za);j=Ia}L[k>>3]=+(i>>>0)+ +(j|0)*4294967296;pa=pa+1|0}La=La+1|0;if((Ca|0)!=(La|0)){continue}break}we:{xe:{switch(pa|0){case 1:t=L[Aa>>3];ra=L[ja>>3];break we;case 0:break we;default:break xe}}oe(ja,pa,8,14);oe(Aa,pa,8,14);i=(pa-1|0)/2<<3;l=(pa|0)/2<<3;t=(L[i+Aa>>3]+L[l+Aa>>3])*.5;ra=(L[i+ja>>3]+L[l+ja>>3])*.5}ye:{switch(ea|0){case 1:y=L[ma>>3];break fe;case 0:break fe;default:break ye}}oe(ma,ea,8,14);y=(L[ma+((ea-1|0)/2<<3)>>3]+L[ma+((ea|0)/2<<3)>>3])*.5}Wa(Aa);Wa(ja);Wa(ma);Wa(ga);Wa(ka);Wa(fa);Fb=t*.1772048;t=y*1.0483579;y=ra*.6052697;break _d}while(1){j=G[r+(l<<2)>>2];C=(j|0)>(C|0)?j:C;A=(j|0)<(A|0)?j:A;l=l+1|0;i=i+1|0;if((s|0)!=(i|0)){continue}break}break $d}G[h>>2]=113}y=0}if(Ha){L[Ha>>3]=t}if(Ja){L[Ja>>3]=y}if(!Qa){break Zd}L[Qa>>3]=Fb}y=L[_+48>>3];t=L[_+40>>3];if(!(y==0|!(y>3]=y;t=y}Z=+qa;y=L[_+32>>3];if(!(y==0|!(t>y))){L[_+40>>3]=y;t=y}qa=N(t*Z);break Yd}if(!(qa>2]=Ea;i=va-8|0;t=+qa+.5;ze:{if(O(t)<2147483648){l=~~t;break ze}l=-2147483648}Ae:{Be:{switch(i|0){case 0:case 8:p=l;W=G[_+64>>2];X=0;aa=Fa-16|0;Fa=aa;if(G[h>>2]<=0){o=(ba|0)<(na|0)?na:ba;t=oc(+N(o|0))/.6931471805599453+.5;Ce:{if(O(t)<2147483648){l=~~t;break Ce}l=-2147483648}De:{Ee:{Fe:{Ge:{He:{i=ab((o+1|0)/2<<2);if(i){pa=l+((o|0)>1<0){da=ba<<1;ga=1;l=2;s=1;j=-4;k=-2;o=0;n=ba;m=na;while(1){v=k;k=j;w=s;s=l;u=(n|0)%2|0;q=0;la=(m|0)%2|0;va=m-la|0;if((va|0)>0){C=o^1;B=n-u|0;while(1){l=M(q,ba);j=ba+l|0;x=0;if((B|0)>0){while(1){Y=r+(j<<2)|0;$=G[Y+4>>2];fa=G[Y>>2];ka=$-fa|0;ea=l<<2;ma=r+(ea|4)|0;ha=G[ma>>2];A=r+ea|0;ea=G[A>>2];G[Y+4>>2]=(ka-ha|0)+ea>>o;Da=Y;Y=$+fa|0;$=ea+ha|0;fa=Y-$>>o;G[Da>>2]=v&((fa|0)<0?0:w)+fa;ha=(ha+ka|0)-ea>>o;G[ma>>2]=v&((ha|0)<0?0:w)+ha;Y=$+Y>>o;G[A>>2]=((Y|0)<0?ga:s)+Y&k;j=j+2|0;l=l+2|0;x=x+2|0;if((B|0)>(x|0)){continue}break}}if(u){j=r+(j<<2)|0;x=G[j>>2];Y=r+(l<<2)|0;$=G[Y>>2];l=x-$<>2]=v&l+((l|0)<0?0:w);l=x+$<>2]=((l|0)<0?ga:s)+l&k}q=q+2|0;if((va|0)>(q|0)){continue}break}}Ie:{if(!la){break Ie}l=M(q,ba);Y=n-u|0;if((Y|0)>0){j=o^1;q=0;while(1){C=l<<2;B=r+(C|4)|0;x=G[B>>2];fa=B;C=r+C|0;B=G[C>>2];$=x-B<>2]=v&(($|0)<0?0:w)+$;x=x+B<>2]=((x|0)<0?ga:s)+x&k;l=l+2|0;q=q+2|0;if((Y|0)>(q|0)){continue}break}}if(!u){break Ie}j=r+(l<<2)|0;l=G[j>>2]<<2-o;G[j>>2]=l+((l|0)<0?ga:s)&k}if(!((n|0)<2|(m|0)<=0)){Y=n-2|0;l=(Y>>>1|0)+1|0;w=l&-8;v=l&7;C=n-3|0;l=(C>>>1|0)+1|0;B=l&-8;x=l&7;ga=0;while(1){l=i;q=r+(M(ba,ga)<<2)|0;o=q+4|0;j=o;u=0;$=Y>>>0<14;if(!$){while(1){G[l>>2]=G[j>>2];G[l+4>>2]=G[j+8>>2];G[l+8>>2]=G[j+16>>2];G[l+12>>2]=G[j+24>>2];G[l+16>>2]=G[j+32>>2];G[l+20>>2]=G[j+40>>2];G[l+24>>2]=G[j+48>>2];G[l+28>>2]=G[j+56>>2];j=j- -64|0;l=l+32|0;u=u+8|0;if((w|0)!=(u|0)){continue}break}}u=0;if(v){while(1){G[l>>2]=G[j>>2];j=j+8|0;l=l+4|0;u=u+1|0;if((v|0)!=(u|0)){continue}break}}Je:{if((n|0)<3){break Je}l=0;if(C>>>0>=14){while(1){G[o>>2]=G[q+8>>2];G[o+4>>2]=G[q+16>>2];G[o+8>>2]=G[q+24>>2];G[o+12>>2]=G[q+32>>2];G[o+16>>2]=G[q+40>>2];G[o+20>>2]=G[q+48>>2];G[o+24>>2]=G[q+56>>2];G[o+28>>2]=G[q+64>>2];o=o+32|0;q=q- -64|0;l=l+8|0;if((B|0)!=(l|0)){continue}break}}l=0;if(!x){break Je}while(1){G[o>>2]=G[q+8>>2];o=o+4|0;q=q+8|0;l=l+1|0;if((x|0)!=(l|0)){continue}break}}j=0;l=i;if(!$){while(1){G[o>>2]=G[l>>2];G[o+4>>2]=G[l+4>>2];G[o+8>>2]=G[l+8>>2];G[o+12>>2]=G[l+12>>2];G[o+16>>2]=G[l+16>>2];G[o+20>>2]=G[l+20>>2];G[o+24>>2]=G[l+24>>2];G[o+28>>2]=G[l+28>>2];l=l+32|0;o=o+32|0;j=j+8|0;if((w|0)!=(j|0)){continue}break}}j=0;if(v){while(1){G[o>>2]=G[l>>2];l=l+4|0;o=o+4|0;j=j+1|0;if((v|0)!=(j|0)){continue}break}}ga=ga+1|0;if((ga|0)!=(m|0)){continue}break}}if(!((m|0)<2|(n|0)<=0)){C=m-2|0;l=(C>>>1|0)+1|0;u=l&-4;w=l&3;B=m-3|0;l=(B>>>1|0)+1|0;$=l&-4;Y=l&3;x=0;while(1){l=i;v=r+(x<<2)|0;j=ba<<2;o=v+j|0;q=o;A=0;ha=C>>>0<6;if(!ha){while(1){G[l>>2]=G[q>>2];fa=q;q=da<<2;ea=fa+q|0;G[l+4>>2]=G[ea>>2];ea=q+ea|0;G[l+8>>2]=G[ea>>2];ea=q+ea|0;G[l+12>>2]=G[ea>>2];q=q+ea|0;l=l+16|0;A=A+4|0;if((u|0)!=(A|0)){continue}break}}ga=0;if(w){while(1){G[l>>2]=G[q>>2];l=l+4|0;q=(da<<2)+q|0;ga=ga+1|0;if((w|0)!=(ga|0)){continue}break}}Ke:{if((m|0)<3){break Ke}q=0;if(B>>>0>=6){while(1){l=da<<2;v=l+v|0;G[o>>2]=G[v>>2];o=j+o|0;v=l+v|0;G[o>>2]=G[v>>2];o=j+o|0;v=l+v|0;G[o>>2]=G[v>>2];o=j+o|0;v=l+v|0;G[o>>2]=G[v>>2];o=j+o|0;q=q+4|0;if(($|0)!=(q|0)){continue}break}}l=0;if(!Y){break Ke}while(1){v=(da<<2)+v|0;G[o>>2]=G[v>>2];o=j+o|0;l=l+1|0;if((Y|0)!=(l|0)){continue}break}}q=0;l=i;if(!ha){while(1){G[o>>2]=G[l>>2];o=j+o|0;G[o>>2]=G[l+4>>2];o=j+o|0;G[o>>2]=G[l+8>>2];o=j+o|0;G[o>>2]=G[l+12>>2];o=j+o|0;l=l+16|0;q=q+4|0;if((u|0)!=(q|0)){continue}break}}q=0;if(w){while(1){G[o>>2]=G[l>>2];l=l+4|0;o=j+o|0;q=q+1|0;if((w|0)!=(q|0)){continue}break}}x=x+1|0;if((x|0)!=(n|0)){continue}break}}o=1;j=k<<1;l=s<<1;ga=l-1|0;n=n+1>>1;m=m+1>>1;X=X+1|0;if((pa|0)!=(X|0)){continue}break}}Wa(i);Le:{if((p|0)<=1){u=M(ba,na);break Le}u=M(ba,na);if((u|0)<=0){break Le}i=p+1>>>1|0;l=i-1|0;j=(r+(u<<2)|0)-4|0;i=1-i|0;o=r;while(1){k=G[o>>2];G[o>>2]=(((k|0)>0?l:i)+k|0)/(p|0);o=o+4|0;if(j>>>0>=o>>>0){continue}break}}o=0;i=G[_+12>>2];G[48827]=i;G[_+12>>2]=0;G[48828]=0;if((i|0)>=2){E[W|0]=221;E[W+1|0]=153;G[48828]=2;o=2}if((i|0)>(o|0)){E[o+W|0]=na>>>24;o=o|1;G[48828]=o}if((i|0)>(o|0)){E[o+W|0]=na>>>16;o=o+1|0;G[48828]=o}if((i|0)>(o|0)){E[o+W|0]=na>>>8;o=o+1|0;G[48828]=o}if((i|0)>(o|0)){E[o+W|0]=na;o=o+1|0;G[48828]=o}if((i|0)>(o|0)){E[o+W|0]=ba>>>24;o=o+1|0;G[48828]=o}if((i|0)>(o|0)){E[o+W|0]=ba>>>16;o=o+1|0;G[48828]=o}if((i|0)>(o|0)){E[o+W|0]=ba>>>8;o=o+1|0;G[48828]=o}if((i|0)>(o|0)){E[o+W|0]=ba;o=o+1|0;G[48828]=o}if((i|0)>(o|0)){E[o+W|0]=p>>>24;o=o+1|0;G[48828]=o}if((i|0)>(o|0)){E[o+W|0]=p>>>16;o=o+1|0;G[48828]=o}if((i|0)>(o|0)){E[o+W|0]=p>>>8;o=o+1|0;G[48828]=o}if((i|0)>(o|0)){E[o+W|0]=p;G[48828]=o+1}i=G[r>>2];cp(W,i,i>>31);l=0;G[r>>2]=0;j=8;k=lb(1,(u+7|0)/8|0);i=3029;if(!k){break Fe}if((u|0)<=0){break He}ga=0;while(1){p=r+(l<<2)|0;o=G[p>>2];Me:{Ne:{if((o|0)>0){i=k+ga|0;E[i|0]=H[i|0]<<1;break Ne}i=j;if((o|0)>=0){break Me}i=k+ga|0;E[i|0]=H[i|0]<<1|1;G[p>>2]=0-o}i=j-1|0}j=i?i:8;ga=!i+ga|0;l=l+1|0;if((u|0)!=(l|0)){continue}break}if((j|0)!=8){i=k+ga|0;E[i|0]=H[i|0]<>2]=0;G[aa>>2]=0;G[aa+4>>2]=0;A=(ba+1|0)/2|0;x=(na+1|0)/2|0;o=0;l=0;j=0;while(1){p=aa+(((j|0)>=(A|0))+((l|0)>=(x|0))<<2)|0;i=G[p>>2];m=p;p=G[r+(o<<2)>>2];G[m>>2]=(i|0)>(p|0)?i:p;i=j+1|0;j=(i|0)<(ba|0)?i:0;l=((i|0)>=(ba|0))+l|0;o=o+1|0;if((u|0)!=(o|0)){continue}break}u=0;o=G[aa>>2];if((o|0)<=0){break Ge}while(1){u=u+1|0;i=o>>>0>1;o=o>>>1|0;if(i){continue}break}break Ge}Ua(2963);break Ee}G[aa+4>>2]=0;G[aa+8>>2]=0;A=(ba+1|0)/2|0;x=(na+1|0)/2|0;ga=0;o=0;u=0}G[aa>>2]=o;j=0;o=G[aa+4>>2];Oe:{if((o|0)<=0){v=o;l=0;break Oe}l=0;while(1){l=l+1|0;i=o>>>0>1;v=o>>>1|0;o=v;if(i){continue}break}}G[aa+4>>2]=v;o=G[aa+8>>2];Pe:{if((o|0)<=0){v=o;break Pe}while(1){j=j+1|0;i=o>>>0>1;v=o>>>1|0;o=v;if(i){continue}break}}G[aa+8>>2]=v;q=G[48828];o=q+3|0;if((o|0)<=G[48827]){i=q+W|0;E[i+2|0]=j;E[i+1|0]=l;E[i|0]=u;G[48828]=o;G[48830]=8;G[48832]=0;G[48833]=0;G[48829]=0;o=Li(W,r,ba,x,A,u&255);Qe:{if(o){break Qe}i=(ba|0)/2|0;l=l&255;o=Li(W,r+(A<<2)|0,ba,x,i,l);if(o){break Qe}p=M(x,ba);m=(na|0)/2|0;o=Li(W,r+(p<<2)|0,ba,m,A,l);if(o){break Qe}o=Li(W,r+(p+A<<2)|0,ba,m,i,j&255)}j=G[48829]<<4;G[48829]=j;i=G[48830];l=i-4|0;G[48830]=l;if((i|0)<=4){l=G[48828];E[l+W|0]=j>>4-i;if((l|0)>>0<4?p+1|0:p;G[48832]=i;G[48833]=p;Re:{if((l|0)>=8){q=G[48828];break Re}q=G[48828];E[W+q|0]=j<(q|0)){q=q+1|0;G[48828]=q}w=(l>>31)+p|0;i=i+l|0;w=i>>>0>>0?w+1|0:w;G[48832]=i;G[48833]=w}Se:{Te:{if((ga|0)<=0){j=G[48827];break Te}j=G[48827];i=q+ga|0;if((j|0)<(i|0)){break Se}bb(q+W|0,k,ga);G[48828]=i;q=i}Wa(k);G[_+12>>2]=q;i=16770;if((j|0)<=(q|0)){break Fe}break De}Wa(k)}G[_+12>>2]=q;i=16770}Ua(i)}o=413}G[h>>2]=o}Fa=aa+16|0;break Ae;default:break Be}}if(G[h>>2]<=0){Ue:{v=(o|0)<1e4?o:1e4;j=ab(v<<3);if(!j){Ua(61864);G[h>>2]=113;break Ue}Ve:{if((o|0)<=0){break Ve}o=o-v|0;while(1){We:{if((v|0)<=0){break We}k=0;i=0;if(v-1>>>0>=3){p=v&-4;q=0;while(1){m=j+(i<<3)|0;s=G[r+(i+o<<2)>>2];G[m>>2]=s;G[m+4>>2]=s>>31;m=i|1;s=j+(m<<3)|0;m=G[r+(m+o<<2)>>2];G[s>>2]=m;G[s+4>>2]=m>>31;m=i|2;s=j+(m<<3)|0;m=G[r+(m+o<<2)>>2];G[s>>2]=m;G[s+4>>2]=m>>31;m=i|3;s=j+(m<<3)|0;m=G[r+(m+o<<2)>>2];G[s>>2]=m;G[s+4>>2]=m>>31;i=i+4|0;q=q+4|0;if((p|0)!=(q|0)){continue}break}}p=v&3;if(!p){break We}while(1){m=j+(i<<3)|0;s=G[r+(i+o<<2)>>2];G[m>>2]=s;G[m+4>>2]=s>>31;i=i+1|0;k=k+1|0;if((p|0)!=(k|0)){continue}break}}bb(r+(o<<3)|0,j,v<<3);if(!o){break Ve}i=(o|0)>1e4;v=i?v:o;o=o?i?o-1e4|0:0:0;if((v|0)>0){continue}break}}Wa(j)}}Y=l;oa=G[_+64>>2];j=0;A=0;ja=Fa-32|0;Fa=ja;if(G[h>>2]<=0){l=(ba|0)<(na|0)?na:ba;t=oc(+N(l|0))/.6931471805599453+.5;Xe:{if(O(t)<2147483648){i=~~t;break Xe}i=-2147483648}Ye:{Ze:{_e:{$e:{af:{X=ab((l+1|0)/2<<3);if(X){Qa=i+((l|0)>1<0){za=ba<<1;v=2;p=0;C=-2;W=-1;w=-4;m=-1;aa=1;x=0;u=1;o=0;k=na;s=ba;while(1){da=u;q=o;u=v;o=p;$=C;ha=W;C=w;W=m;Aa=(s|0)%2|0;ga=0;Ja=(k|0)%2|0;fb=k-Ja|0;if((fb|0)>0){Ea=s-Aa|0;v=!j;while(1){i=M(ba,ga);l=ba+i|0;n=0;if((Ea|0)>0){while(1){m=r+(l<<3)|0;pa=G[m+8>>2];w=pa;ma=G[m>>2];ka=ma;gb=w-ka|0;La=gb;B=i<<3;la=r+(B|8)|0;ea=G[la>>2];va=r+B|0;B=G[va>>2];fa=(La-ea|0)+B|0;Ha=G[m+12>>2];Da=G[m+4>>2];tb=Ha-(Da+(w>>>0>>0)|0)|0;Ca=G[la+4>>2];p=tb-(Ca+(ea>>>0>La>>>0)|0)|0;La=G[va+4>>2];w=p+La|0;w=B>>>0>fa>>>0?w+1|0:w;Xa=fa;ka=j&31;fa=m;if((j&63)>>>0>=32){p=w>>31;w=w>>ka}else{p=w>>ka;w=((1<>>ka}G[m+8>>2]=w;G[fa+12>>2]=p;w=m;p=Ha+Da|0;m=ma+pa|0;p=m>>>0>>0?p+1|0:p;pa=p;p=Ca+La|0;fa=B+ea|0;p=fa>>>0>>0?p+1|0:p;Da=fa;ma=fa;Ha=m-fa|0;fa=w;fa=w;ka=p;ma=pa-(p+(m>>>0>>0)|0)|0;w=j&31;if((j&63)>>>0>=32){p=ma>>31;w=ma>>w}else{p=ma>>w;w=((1<>>w}ma=w;Xa=(p|0)<0;Ha=w+(Xa?0:da)|0;w=p+(Xa?0:q)|0;G[fa>>2]=$&Ha;G[fa+4>>2]=ha&(ma>>>0>Ha>>>0?w+1|0:w);w=la;p=Ca+tb|0;la=ea+gb|0;p=la>>>0>>0?p+1|0:p;ea=la;la=ea-B|0;ea=p-((B>>>0>ea>>>0)+La|0)|0;B=j&31;if((j&63)>>>0>=32){p=ea>>31;B=ea>>B}else{p=ea>>B;B=((1<>>B}ea=(p|0)<0;la=B+(ea?0:da)|0;ea=p+(ea?0:q)|0;G[w>>2]=$&la;G[w+4>>2]=ha&(B>>>0>la>>>0?ea+1|0:ea);p=ka+pa|0;B=m+Da|0;p=B>>>0>>0?p+1|0:p;pa=B;B=j&31;if((j&63)>>>0>=32){ea=p>>31;p=p>>B}else{ea=p>>B;p=((1<>>B}m=p;pa=(ea|0)<0;B=m+(pa?aa:u)|0;p=ea+(pa?x:o)|0;w=va;G[w>>2]=B&C;G[w+4>>2]=W&(m>>>0>B>>>0?p+1|0:p);l=l+2|0;i=i+2|0;n=n+2|0;if((Ea|0)>(n|0)){continue}break}}if(Aa){l=r+(l<<3)|0;m=G[l>>2];i=r+(i<<3)|0;ea=G[i>>2];n=ea;w=m-n|0;pa=G[l+4>>2];la=G[i+4>>2];p=pa-(la+(n>>>0>m>>>0)|0)|0;n=v&31;if((v&63)>>>0>=32){p=w<>>32-n|p<>2]=B&$;G[l+4>>2]=ha&(n>>>0>B>>>0?w+1|0:w);p=la+pa|0;l=m+ea|0;p=l>>>0>>0?p+1|0:p;m=l;l=v&31;if((v&63)>>>0>=32){w=m<>>32-l|p<>2]=p&C;G[i+4>>2]=W&(l>>>0>p>>>0?m+1|0:m)}ga=ga+2|0;if((fb|0)>(ga|0)){continue}break}}bf:{if(!Ja){break bf}i=M(ba,ga);la=s-Aa|0;if((la|0)>0){v=!j;l=0;while(1){m=i<<3;p=r+(m|8)|0;n=G[p>>2];w=m+r|0;m=w;va=G[m>>2];ea=va;pa=n-ea|0;B=p;B=p;fa=G[p+4>>2];ka=G[m+4>>2];m=fa-(ka+(n>>>0>>0)|0)|0;ea=pa;p=v&31;if((v&63)>>>0>=32){m=ea<>>32-p|m<>2]=$&pa;G[B+4>>2]=ha&(ea>>>0>pa>>>0?p+1|0:p);p=w;m=fa+ka|0;w=n+va|0;m=w>>>0>>0?m+1|0:m;n=p;B=w;w=v&31;if((v&63)>>>0>=32){p=B<>>32-w|m<>2]=w&C;G[n+4>>2]=W&(m>>>0>w>>>0?p+1|0:p);i=i+2|0;l=l+2|0;if((la|0)>(l|0)){continue}break}}if(!Aa){break bf}i=r+(i<<3)|0;m=i;m=i;p=G[i+4>>2];l=G[i>>2];j=2-j|0;i=j&31;if((j&63)>>>0>=32){p=l<>>32-i|p<>2]=l&C;G[m+4>>2]=W&(i>>>0>l>>>0?p+1|0:p)}if(!((s|0)<2|(k|0)<=0)){q=s-2|0;i=(q>>>1|0)+1|0;m=i&-8;p=i&7;aa=s-3|0;i=(aa>>>1|0)+1|0;da=i&-8;w=i&7;x=0;while(1){l=X;n=r+(M(x,ba)<<3)|0;i=n+8|0;j=i;v=0;B=q>>>0<14;if(!B){while(1){$=G[j+4>>2];G[l>>2]=G[j>>2];G[l+4>>2]=$;$=G[j+20>>2];G[l+8>>2]=G[j+16>>2];G[l+12>>2]=$;$=G[j+36>>2];G[l+16>>2]=G[j+32>>2];G[l+20>>2]=$;$=G[j+52>>2];G[l+24>>2]=G[j+48>>2];G[l+28>>2]=$;$=G[j+68>>2];G[l+32>>2]=G[j+64>>2];G[l+36>>2]=$;$=G[j+84>>2];G[l+40>>2]=G[j+80>>2];G[l+44>>2]=$;$=G[j+100>>2];G[l+48>>2]=G[j+96>>2];G[l+52>>2]=$;$=G[j+116>>2];G[l+56>>2]=G[j+112>>2];G[l+60>>2]=$;j=j+128|0;l=l- -64|0;v=v+8|0;if((m|0)!=(v|0)){continue}break}}v=0;if(p){while(1){$=G[j+4>>2];G[l>>2]=G[j>>2];G[l+4>>2]=$;j=j+16|0;l=l+8|0;v=v+1|0;if((p|0)!=(v|0)){continue}break}}cf:{if((s|0)<3){break cf}l=0;if(aa>>>0>=14){while(1){j=G[n+20>>2];G[i>>2]=G[n+16>>2];G[i+4>>2]=j;j=G[n+36>>2];G[i+8>>2]=G[n+32>>2];G[i+12>>2]=j;j=G[n+52>>2];G[i+16>>2]=G[n+48>>2];G[i+20>>2]=j;j=G[n+68>>2];G[i+24>>2]=G[n+64>>2];G[i+28>>2]=j;j=G[n+84>>2];G[i+32>>2]=G[n+80>>2];G[i+36>>2]=j;j=G[n+100>>2];G[i+40>>2]=G[n+96>>2];G[i+44>>2]=j;j=G[n+116>>2];G[i+48>>2]=G[n+112>>2];G[i+52>>2]=j;j=G[n+132>>2];G[i+56>>2]=G[n+128>>2];G[i+60>>2]=j;i=i- -64|0;n=n+128|0;l=l+8|0;if((da|0)!=(l|0)){continue}break}}l=0;if(!w){break cf}while(1){j=G[n+20>>2];G[i>>2]=G[n+16>>2];G[i+4>>2]=j;i=i+8|0;n=n+16|0;l=l+1|0;if((w|0)!=(l|0)){continue}break}}j=0;l=X;if(!B){while(1){v=G[l+4>>2];G[i>>2]=G[l>>2];G[i+4>>2]=v;v=G[l+12>>2];G[i+8>>2]=G[l+8>>2];G[i+12>>2]=v;v=G[l+20>>2];G[i+16>>2]=G[l+16>>2];G[i+20>>2]=v;v=G[l+28>>2];G[i+24>>2]=G[l+24>>2];G[i+28>>2]=v;v=G[l+36>>2];G[i+32>>2]=G[l+32>>2];G[i+36>>2]=v;v=G[l+44>>2];G[i+40>>2]=G[l+40>>2];G[i+44>>2]=v;v=G[l+52>>2];G[i+48>>2]=G[l+48>>2];G[i+52>>2]=v;v=G[l+60>>2];G[i+56>>2]=G[l+56>>2];G[i+60>>2]=v;l=l- -64|0;i=i- -64|0;j=j+8|0;if((m|0)!=(j|0)){continue}break}}j=0;if(p){while(1){v=G[l+4>>2];G[i>>2]=G[l>>2];G[i+4>>2]=v;l=l+8|0;i=i+8|0;j=j+1|0;if((p|0)!=(j|0)){continue}break}}x=x+1|0;if((x|0)!=(k|0)){continue}break}}if(!((k|0)<2|(s|0)<=0)){da=k-2|0;i=(da>>>1|0)+1|0;w=i&-4;p=i&3;B=k-3|0;i=(B>>>1|0)+1|0;$=i&-4;aa=i&3;m=0;while(1){l=X;q=r+(m<<3)|0;j=ba<<3;i=q+j|0;n=i;ga=0;ha=da>>>0<6;if(!ha){while(1){v=G[n+4>>2];G[l>>2]=G[n>>2];G[l+4>>2]=v;v=za<<3;n=v+n|0;x=G[n+4>>2];G[l+8>>2]=G[n>>2];G[l+12>>2]=x;n=n+v|0;x=G[n+4>>2];G[l+16>>2]=G[n>>2];G[l+20>>2]=x;n=n+v|0;x=G[n+4>>2];G[l+24>>2]=G[n>>2];G[l+28>>2]=x;n=n+v|0;l=l+32|0;ga=ga+4|0;if((w|0)!=(ga|0)){continue}break}}x=0;if(p){while(1){v=G[n+4>>2];G[l>>2]=G[n>>2];G[l+4>>2]=v;l=l+8|0;n=n+(za<<3)|0;x=x+1|0;if((p|0)!=(x|0)){continue}break}}df:{if((k|0)<3){break df}n=0;if(B>>>0>=6){while(1){l=za<<3;v=l+q|0;q=G[v+4>>2];G[i>>2]=G[v>>2];G[i+4>>2]=q;v=l+v|0;q=G[v+4>>2];i=i+j|0;G[i>>2]=G[v>>2];G[i+4>>2]=q;v=l+v|0;q=G[v+4>>2];i=i+j|0;G[i>>2]=G[v>>2];G[i+4>>2]=q;q=l+v|0;l=q;v=G[l+4>>2];i=i+j|0;G[i>>2]=G[l>>2];G[i+4>>2]=v;i=i+j|0;n=n+4|0;if(($|0)!=(n|0)){continue}break}}l=0;if(!aa){break df}while(1){q=(za<<3)+q|0;n=G[q+4>>2];G[i>>2]=G[q>>2];G[i+4>>2]=n;i=i+j|0;l=l+1|0;if((aa|0)!=(l|0)){continue}break}}n=0;l=X;if(!ha){while(1){v=G[l+4>>2];G[i>>2]=G[l>>2];G[i+4>>2]=v;v=G[l+12>>2];i=i+j|0;G[i>>2]=G[l+8>>2];G[i+4>>2]=v;v=G[l+20>>2];i=i+j|0;G[i>>2]=G[l+16>>2];G[i+4>>2]=v;v=G[l+28>>2];i=i+j|0;G[i>>2]=G[l+24>>2];G[i+4>>2]=v;i=i+j|0;l=l+32|0;n=n+4|0;if((w|0)!=(n|0)){continue}break}}n=0;if(p){while(1){v=G[l+4>>2];G[i>>2]=G[l>>2];G[i+4>>2]=v;l=l+8|0;i=i+j|0;n=n+1|0;if((p|0)!=(n|0)){continue}break}}m=m+1|0;if((m|0)!=(s|0)){continue}break}}i=C;m=W<<1|i>>>31;w=i<<1;i=u;p=o<<1|i>>>31;v=i<<1;i=v;aa=i-1|0;x=p-!i|0;j=1;s=s+1>>1;k=k+1>>1;A=A+1|0;if((Qa|0)!=(A|0)){continue}break}}Wa(X);ef:{if((Y|0)<=1){v=M(ba,na);break ef}v=M(ba,na);if((v|0)<=0){break ef}j=(r+(v<<3)|0)-8|0;k=(Y+1>>>1|0)-1|0;i=k;p=0-i|0;m=0-((i|0)!=0)|0;i=r;while(1){o=G[i+4>>2];s=o;l=G[i>>2];n=!!l&(o|0)>=0|(o|0)>0;o=(n?k:p)+l|0;ea=s+(n?0:m)|0;ec=i,gc=Bu(o,l>>>0>o>>>0?ea+1|0:ea,Y,0),G[ec>>2]=gc;G[i+4>>2]=Ia;i=i+8|0;if(j>>>0>=i>>>0){continue}break}}i=0;s=G[_+12>>2];G[48827]=s;G[_+12>>2]=0;G[48828]=0;if((s|0)>=2){E[oa|0]=221;E[oa+1|0]=153;G[48828]=2;i=2}if((i|0)<(s|0)){E[i+oa|0]=na>>>24;i=i|1;G[48828]=i}if((i|0)<(s|0)){E[i+oa|0]=na>>>16;i=i+1|0;G[48828]=i}if((i|0)<(s|0)){E[i+oa|0]=na>>>8;i=i+1|0;G[48828]=i}if((i|0)<(s|0)){E[i+oa|0]=na;i=i+1|0;G[48828]=i}if((i|0)<(s|0)){E[i+oa|0]=ba>>>24;i=i+1|0;G[48828]=i}if((i|0)<(s|0)){E[i+oa|0]=ba>>>16;i=i+1|0;G[48828]=i}if((i|0)<(s|0)){E[i+oa|0]=ba>>>8;i=i+1|0;G[48828]=i}if((i|0)<(s|0)){E[i+oa|0]=ba;i=i+1|0;G[48828]=i}if((i|0)<(s|0)){E[i+oa|0]=Y>>>24;i=i+1|0;G[48828]=i}if((i|0)<(s|0)){E[i+oa|0]=Y>>>16;i=i+1|0;G[48828]=i}if((i|0)<(s|0)){E[i+oa|0]=Y>>>8;i=i+1|0;G[48828]=i}if((i|0)<(s|0)){E[i+oa|0]=Y;G[48828]=i+1}cp(oa,G[r>>2],G[r+4>>2]);G[r>>2]=0;G[r+4>>2]=0;j=8;u=lb(1,(v+7|0)/8|0);i=3155;if(!u){break _e}l=0;if((v|0)<=0){break af}x=0;while(1){p=r+(l<<3)|0;o=p;i=G[o+4>>2];k=G[o>>2];ff:{gf:{if(!!k&(i|0)>=0|(i|0)>0){i=u+x|0;E[i|0]=H[i|0]<<1;break gf}if((i|0)>0|(i|0)>=0){break ff}o=u+x|0;E[o|0]=H[o|0]<<1|1;G[p>>2]=0-k;G[p+4>>2]=0-(((k|0)!=0)+i|0)}j=j-1|0}o=j;j=o?o:8;x=!o+x|0;l=l+1|0;if((v|0)!=(l|0)){continue}break}if((j|0)!=8){i=u+x|0;E[i|0]=H[i|0]<>2]=0;G[ja+20>>2]=0;G[ja+8>>2]=0;G[ja+12>>2]=0;G[ja>>2]=0;G[ja+4>>2]=0;q=(ba+1|0)/2|0;ga=(na+1|0)/2|0;i=0;l=0;j=0;while(1){p=ja+(((j|0)>=(q|0))+((l|0)>=(ga|0))<<3)|0;k=p;o=G[k+4>>2];m=G[k>>2];n=r+(i<<3)|0;k=G[n+4>>2];w=m;n=G[n>>2];m=(k|0)<=(o|0)&m>>>0>n>>>0|(k|0)<(o|0);G[p>>2]=m?w:n;G[p+4>>2]=m?o:k;o=j+1|0;j=(o|0)<(ba|0)?o:0;l=((o|0)>=(ba|0))+l|0;i=i+1|0;if((v|0)!=(i|0)){continue}break}n=0;v=G[ja>>2];p=G[ja+4>>2];if(!v&(p|0)<=0|(p|0)<0){break $e}while(1){n=n+1|0;i=!p&v>>>0>1|(p|0)!=0;v=(p&1)<<31|v>>>1;p=p>>>1|0;if(i){continue}break}break $e}Ua(3119);break Ze}v=0;p=0;G[ja+16>>2]=0;G[ja+20>>2]=0;G[ja+8>>2]=0;G[ja+12>>2]=0;G[ja>>2]=0;G[ja+4>>2]=0;q=(ba+1|0)/2|0;ga=(na+1|0)/2|0;x=0;n=0}G[ja>>2]=v;G[ja+4>>2]=p;l=0;i=G[ja+12>>2];p=i;v=G[ja+8>>2];hf:{if(!v&(i|0)<=0|(i|0)<0){w=v;m=p;i=0;break hf}i=0;while(1){i=i+1|0;j=!p&v>>>0>1|(p|0)!=0;o=p;p=o>>>1|0;w=(o&1)<<31|v>>>1;m=p;v=w;if(j){continue}break}}G[ja+8>>2]=w;G[ja+12>>2]=m;v=G[ja+16>>2];p=G[ja+20>>2];jf:{if(!v&(p|0)<=0|(p|0)<0){w=v;m=p;break jf}while(1){l=l+1|0;o=!p&v>>>0>1|(p|0)!=0;w=(p&1)<<31|v>>>1;v=w;m=p>>>1|0;p=m;if(o){continue}break}}G[ja+16>>2]=w;G[ja+20>>2]=m;v=G[48828];j=v+3|0;if((j|0)<=(s|0)){o=v+oa|0;E[o+2|0]=l;E[o+1|0]=i;E[o|0]=n;G[48828]=j;G[48830]=8;G[48832]=0;G[48833]=0;G[48829]=0;j=Ki(oa,r,ba,ga,q,n&255);kf:{if(j){break kf}o=(ba|0)/2|0;i=i&255;j=Ki(oa,r+(q<<3)|0,ba,ga,o,i);if(j){break kf}k=M(ba,ga);p=(na|0)/2|0;j=Ki(oa,r+(k<<3)|0,ba,p,q,i);if(j){break kf}j=Ki(oa,r+(k+q<<3)|0,ba,p,o,l&255)}o=G[48829]<<4;G[48829]=o;l=G[48830];i=l-4|0;G[48830]=i;if((l|0)<=4){i=G[48828];E[i+oa|0]=o>>4-l;if((i|0)>>0<4?p+1|0:p;G[48832]=l;G[48833]=p;lf:{if((i|0)>=8){v=G[48828];break lf}v=G[48828];E[oa+v|0]=o<(v|0)){v=v+1|0;G[48828]=v}p=(i>>31)+p|0;l=i+l|0;p=l>>>0>>0?p+1|0:p;G[48832]=l;G[48833]=p}mf:{nf:{if((x|0)<=0){l=G[48827];break nf}l=G[48827];i=v+x|0;if((l|0)<(i|0)){break mf}bb(v+oa|0,u,x);G[48828]=i;v=i}Wa(u);G[_+12>>2]=v;i=16802;if((l|0)<=(v|0)){break _e}break Ye}Wa(u)}G[_+12>>2]=v;i=16770}Ua(i)}j=413}G[h>>2]=j}Fa=ja+32|0}i=G[_+12>>2];pe(a,G[G[a+4>>2]+1144>>2],Ba,Ba>>31,1,0,i,i>>31,G[_+64>>2],h)}i=G[G[a+4>>2]+1156>>2];if((i|0)<=0){break _c}j=i;i=Ba>>31;Ff(a,j,Ba,i,1,0,1,0,_+24|0,h);Ff(a,G[G[a+4>>2]+1160>>2],Ba,i,1,0,1,0,_+16|0,h);break _c}of:{if(G[i+1152>>2]>0){break of}Bi(a,999,35928,G[i+1036>>2]?35904:35908,h);if(G[h>>2]>0){break of}dc(a,0,35928,G[a+4>>2]+1152|0,h)}pf:{if((b|0)==42){s=o<<2;t=+(s>>>0)*1.1;qf:{if(t<4294967296&t>=0){i=~~t>>>0;break qf}i=0}G[_+68>>2]=i;i=lb(i,1);G[_+64>>2]=i;if(!i){Ua(60838);break Zc}rf:{if(($|0)!=1|(o|0)<=0){break rf}z=K[g>>2];i=0;j=0;if(o-1>>>0>=3){k=o&-4;while(1){l=j<<2;p=l+r|0;if(z==K[p>>2]){G[p>>2]=-1}p=r+(l|4)|0;if(z==K[p>>2]){G[p>>2]=-1}p=r+(l|8)|0;if(z==K[p>>2]){G[p>>2]=-1}l=r+(l|12)|0;if(z==K[l>>2]){G[l>>2]=-1}j=j+4|0;v=v+4|0;if((k|0)!=(v|0)){continue}break}}l=o&3;if(!l){break rf}while(1){k=r+(j<<2)|0;if(z==K[k>>2]){G[k>>2]=-1}j=j+1|0;i=i+1|0;if((l|0)!=(i|0)){continue}break}}ke(r,o);break pf}s=o<<3;t=+(s>>>0)*1.1;sf:{if(t<4294967296&t>=0){i=~~t>>>0;break sf}i=0}G[_+68>>2]=i;i=lb(i,1);G[_+64>>2]=i;if(!i){Ua(60838);break Zc}tf:{if(($|0)!=1|(o|0)<=0){break tf}t=L[g>>3];i=0;j=0;if(o-1>>>0>=3){p=o&-4;while(1){l=j<<3;k=l+r|0;if(t==L[k>>3]){G[k>>2]=-1;G[k+4>>2]=-1}k=r+(l|8)|0;if(t==L[k>>3]){G[k>>2]=-1;G[k+4>>2]=-1}k=r+(l|16)|0;if(t==L[k>>3]){G[k>>2]=-1;G[k+4>>2]=-1}l=r+(l|24)|0;if(t==L[l>>3]){G[l>>2]=-1;G[l+4>>2]=-1}j=j+4|0;v=v+4|0;if((p|0)!=(v|0)){continue}break}}k=o&3;if(!k){break tf}while(1){l=r+(j<<3)|0;if(t==L[l>>3]){G[l>>2]=-1;G[l+4>>2]=-1}j=j+1|0;i=i+1|0;if((k|0)!=(i|0)){continue}break}}Ge(r,o)}gp(r,s,_- -64|0,_+68|0,_+60|0,h);pe(a,G[G[a+4>>2]+1152>>2],Ba,Ba>>31,1,0,G[_+60>>2],0,G[_+64>>2],h)}Wa(G[_+64>>2]);break w}G[h>>2]=113;break w}G[h>>2]=413}Fa=_+80|0;i=Eb+1|0;if((zb|0)!=(Eb|0)){continue}break}i=(jb|0)!=(qb|0);jb=jb+1|0;if(i){continue}break}i=(Ga|0)!=(kb|0);Ga=Ga+1|0;if(i){continue}break}break q}G[D+200>>2]=Cb;G[D+232>>2]=Db;G[D+228>>2]=Sb;G[D+196>>2]=Mb}i=(d|0)!=($a|0);d=d+1|0;if(i){continue}break}break p}G[D+204>>2]=Lb;G[D+236>>2]=Qb;G[D+232>>2]=Db;G[D+200>>2]=Cb}d=(c|0)!=(Ya|0);c=c+1|0;if(d){continue}break}c=(Oa|0)!=(Pa|0);Oa=Oa+1|0;if(c){continue}break}Ga=G[a+4>>2];break m}b=M(Pa,Ta);G[D+212>>2]=(b|0)<(Sa|0)?b:Sa;G[D+244>>2]=M(Pa-1|0,Ta)+1;G[D+240>>2]=M(Ya-1|0,_a)+1;b=M(_a,Ya);G[D+208>>2]=(b|0)<(Za|0)?b:Za;G[D+236>>2]=M($a-1|0,eb)+1;b=M(eb,$a);G[D+204>>2]=(b|0)<(db|0)?b:db}Wa(r);if(!e|G[Ga+1104>>2]>=0){break a}G[D+88>>2]=0;kc(a,34861,D,D+88|0);if(!G[D+88>>2]){break a}kc(a,35408,D,h);Fh(a,34861,-2147483647,-1,3583,h);a=G[a+4>>2];G[a+1164>>2]=-1;G[a+1208>>2]=-2147483647;break a}G[h>>2]=410}Fa=D+384|0}function so(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,J=0,P=0,Q=N(0),R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=N(0),da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Ga=0,Ha=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Va=0,Xa=0,Ya=0,Za=0,_a=0,$a=0;o=Fa-80|0;Fa=o;G[o+76>>2]=g;G[o+72>>2]=0;E[o+59|0]=0;F[o+56>>1]=0;G[o+52>>2]=0;G[o+48>>2]=0;G[o+24>>2]=0;G[o+28>>2]=0;G[o+8>>2]=0;G[o+12>>2]=0;G[o>>2]=0;G[o+4>>2]=0;a:{if(G[j>>2]>0){break a}T=a;a=G[a+4>>2];k=G[a+1112>>2];b:{c:{B=G[a+1228>>2];if(B){ma=((k-1|0)/G[a+1052>>2]|0)+1|0;break c}m=G[a+1052>>2];p=(k-1|0)/(m|0)|0;if((k|0)==(m|0)&G[a+1056>>2]==1){break b}ma=p+1|0;B=lb(ma,4);G[a+1228>>2]=B;_a=a,$a=lb(ma,4),G[_a+1240>>2]=$a;_a=a,$a=lb(ma,4),G[_a+1244>>2]=$a;_a=a,$a=lb(ma,4),G[_a+1232>>2]=$a;_a=a,$a=lb(ma,4),G[_a+1236>>2]=$a;_a=a,$a=lb(ma,4),G[_a+1248>>2]=$a;if(B){break c}ma=0;break b}ma=(b-1|0)%(ma|0)|0;k=ma<<2;if(G[k+B>>2]!=(b|0)|G[k+G[a+1236>>2]>>2]!=(d|0)){break b}b=ma<<2;bb(g,G[b+G[a+1240>>2]>>2],G[b+G[a+1232>>2]>>2]);if((e|0)==2){bb(h,G[b+G[G[T+4>>2]+1244>>2]>>2],c)}G[i>>2]=G[b+G[G[T+4>>2]+1248>>2]>>2];break a}g=G[a+1144>>2];a=b;s=a>>31;Le(T,g,a,s,o+8|0,o,j);d:{if(G[j>>2]==107){break d}e:{f:{g:{if(!(G[o+8>>2]|G[o+12>>2])){b=G[T+4>>2];g=G[b+1148>>2];if((g|0)>0){Le(T,g,a,s,o+8|0,o,j);c=G[o+8>>2];if(!(c|G[o>>2]|(G[o+12>>2]|G[o+4>>2]))){break d}k=c;p=k>>31;g=k;b=p;c=G[G[T+4>>2]+1148>>2];l=G[o+76>>2];if((e|0)<=1){bg(T,d,c,a,s,1,0,g,b,f,l,i,j);break a}f=Fa-16|0;Fa=f;if(G[j>>2]<=0){h:{i:{switch(d-1|0){case 0:xp(T,c,a,s,1,0,g,b,l,j);break h;case 10:Re(T,c,a,s,1,0,g,b,1,2,0,l,h,i,j);break h;case 11:Ef(T,c,a,s,1,0,g,b,1,2,0,l,h,i,j);break h;case 19:Gf(T,c,a,s,1,0,g,b,1,2,0,l,h,i,j);break h;case 20:jf(T,c,a,s,1,0,g,b,1,2,0,l,h,i,j);break h;case 29:Dh(T,c,a,s,1,0,g,b,2,0,l,h,i,j);break h;case 30:Eh(T,c,a,s,1,0,g,b,2,0,l,h,i,j);break h;case 39:qe(T,c,a,s,1,0,g,b,1,2,0,l,h,i,j);break h;case 40:Ud(T,c,a,s,1,0,g,b,1,2,0,l,h,i,j);break h;case 79:hf(T,c,a,s,1,0,g,b,1,2,0,0,l,h,i,j);break h;case 80:Se(T,c,a,s,1,0,g,b,1,2,0,0,l,h,i,j);break h;case 41:ae(T,c,a,s,1,0,g,b,1,2,N(0),l,h,i,j);break h;case 81:Id(T,c,a,s,1,0,g,b,1,2,0,l,h,i,j);break h;case 82:e=b<<1|g>>>31;k=g<<1;d=lb(k,1);ae(T,c,a,s,1,0,k,e,1,2,N(0),l,d,i,j);j:{if(!g&(b|0)<=0|(b|0)<0){break j}a=0;c=0;if((g|0)!=1|b){i=g&-2;while(1){E[h+r|0]=H[a+d|0]?1:H[d+(a|1)|0]!=0;E[(r|1)+h|0]=H[d+(a|2)|0]?1:H[d+(a|3)|0]!=0;k=v;c=r+2|0;k=c>>>0<2?k+1|0:k;r=c;v=k;a=a+4|0;e=n;c=U+2|0;e=c>>>0<2?e+1|0:e;U=c;n=e;if((i|0)!=(c|0)|(b|0)!=(e|0)){continue}break}c=r}if(!(g&1)){break j}E[c+h|0]=H[a+d|0]?1:H[d+(a|1)|0]!=0}Wa(d);break h;case 162:p=b<<1|g>>>31;e=g<<1;d=lb(e,1);Id(T,c,a,s,1,0,e,p,1,2,0,l,d,i,j);k:{if(!g&(b|0)<=0|(b|0)<0){break k}a=0;c=0;if((g|0)!=1|b){e=g&-2;while(1){E[h+r|0]=H[a+d|0]?1:H[d+(a|1)|0]!=0;E[(r|1)+h|0]=H[d+(a|2)|0]?1:H[d+(a|3)|0]!=0;k=v;c=r+2|0;k=c>>>0<2?k+1|0:k;r=c;v=k;a=a+4|0;c=U+2|0;p=c>>>0<2?n+1|0:n;U=c;n=p;if((e|0)!=(c|0)|(b|0)!=(n|0)){continue}break}c=r}if(!(g&1)){break k}E[c+h|0]=H[a+d|0]?1:H[d+(a|1)|0]!=0}Wa(d);break h;case 13:fg(T,c,a,s,1,0,g,b,2,0,l,h,i,j);break h;case 15:xh(T,c,a,s,1,0,g,b,2,f+14|0,l,h,i,j);break h;default:break i}}G[j>>2]=410}}Fa=f+16|0;break a}b=G[b+1152>>2];if((b|0)>0){Le(T,b,a,s,o+8|0,o,j);l=G[o+8>>2];if(!(l|G[o>>2]|(G[o+12>>2]|G[o+4>>2]))){break d}g=ab(l);if(!g){Ua(60281);break f}k=l;p=k>>31;if((bg(T,11,G[G[T+4>>2]+1152>>2],a,s,1,0,k,p,o+59|0,g,0,j)|0)>0){Ua(23110);Wa(g);break a}l:{m:{n:{a=G[G[T+4>>2]+1104>>2];if((a|0)==-32){b=2}else{if((a|0)!=-64){break n}b=3}b=c<>2]=b;if((d|0)==42|(d|0)==82){break l}Ua(21152);break m}Ua(24600)}Wa(g);break e}o:{p:{if((d|0)==42){if((a|0)!=-64){break p}a=ab(b);G[o+48>>2]=a;if(!a){Ua(60462);break g}if(!Qi(g,G[o+8>>2],o+48|0,o+68|0,0,o- -64|0,j)){break o}Ua(21671);Wa(G[o+48>>2]);Wa(g);break a}if((d|0)!=82|(a|0)!=-32){break p}a=ab(b);G[o+52>>2]=a;if(!a){Ua(60347);break g}if(!Qi(g,G[o+8>>2],o+52|0,o+68|0,0,o- -64|0,j)){break o}Ua(21671);Wa(G[o+52>>2]);Wa(g);break a}if(!Qi(g,G[o+8>>2],o+76|0,o+68|0,0,o- -64|0,j)){break o}Ua(21671);Wa(g);break a}Wa(g);a=G[o+64>>2];if((a|0)==c<<2){a=G[o+52>>2];q:{if(a){ke(a,c);break q}ke(G[o+76>>2],c)}if((d|0)==42){a=G[o+76>>2];gl(a,c,1,0,e,f?K[f>>2]:N(0),h,i,a);break a}if((d|0)==82){bl(G[o+52>>2],c,1,0,e,f?L[f>>3]:0,h,i,G[o+76>>2]);Wa(G[o+52>>2]);break a}Ua(7574);break e}if((a|0)==c<<3){a=G[o+48>>2];r:{if(a){Ge(a,c);break r}Ge(G[o+76>>2],c)}if((d|0)==42){Wi(G[o+48>>2],c,1,0,e,f?K[f>>2]:N(0),h,i,G[o+76>>2]);Wa(G[o+48>>2]);G[o+48>>2]=0;break a}if((d|0)==82){a=G[o+76>>2];dl(a,c,1,0,e,f?L[f>>3]:0,h,i,a);break a}Ua(7734);break e}Ua(19778);break e}G[j>>2]=415;break a}if(!((e|0)!=2|(c|0)<=0)){cb(h,0,c)}if(i){G[i>>2]=0}m=G[T+4>>2];w=L[m+1200>>3];s:{t:{u:{v:{g=G[m+1156>>2];switch(g+1|0){case 0:break u;case 1:break v;default:break t}}G[o+32>>2]=0;G[o+36>>2]=0;G[o+40>>2]=0;G[o+44>>2]=1072693248;break s}L[o+40>>3]=L[m+1168>>3];L[o+32>>3]=L[m+1176>>3];break s}Hf(T,g,a,s,1,0,1,0,0,o+40|0,0,j);Hf(T,G[G[T+4>>2]+1160>>2],a,s,1,0,1,0,0,o+32|0,0,j);if(G[j>>2]>0){Ua(21703);break a}m=G[T+4>>2];if((G[m+1104>>2]|32)!=-32){break s}u=L[m+1184>>3];z=L[m+1192>>3];if(u==1&z==0){break s}L[o+40>>3]=u*L[o+40>>3];L[o+32>>3]=L[o+32>>3]*u+z}if(!(L[o+40>>3]!=1|L[o+32>>3]!=0)){L[o+40>>3]=L[m+1184>>3];L[o+32>>3]=L[m+1192>>3]}w:{x:{y:{z:{B=G[m+1164>>2];switch(B+1|0){case 1:break w;case 0:break y;default:break z}}Up(T,B,a,s,o+60|0,0,j);if(G[j>>2]<=0){m=G[T+4>>2];break x}Ua(21763);break a}G[o+60>>2]=G[m+1208>>2]}B=e}A:{B:{C:{D:{E:{F:{G:{H:{I:{k=G[m+1048>>2];switch(k-11|0){case 10:case 11:case 40:break G;case 0:break H;case 30:break I;default:break D}}J:{switch(G[m+1104>>2]-8|0){case 0:case 8:break D;default:break J}}g=c<<3;break C}K:{switch(G[m+1104>>2]-8|0){case 8:break F;case 0:break K;default:break D}}if(G[m+1216>>2]!=1){break D}break B}e=G[m+1104>>2];if((e|0)==8){break B}g=k-21|0;if(g>>>0>30){break D}if(1<>2]!=2){break D}g=c<<1;break C}g=c<<1;if((e|0)==16){break C}g=k-21|0;if(g>>>0>30|!(1<>2]=g;break A}G[o+68>>2]=c;g=c}e=ab(g);G[o+72>>2]=e;if(!e){Ua(60529);break f}p=G[o+8>>2];g=p;L:{M:{N:{if((k|0)==31){g=ab(g<<1);if(!g){break N}k=p;p=k>>31;bg(T,21,G[m+1144>>2],a,s,1,0,k,p,o+56|0,g,0,j);break L}g=ab(g);if(g){break M}}Ua(60413);Wa(G[o+72>>2]);break f}e=p;p=e>>31;bg(T,11,G[m+1144>>2],a,s,1,0,e,p,o+59|0,g,0,j)}if(G[j>>2]>0){Ua(23110);Wa(g);Wa(G[o+72>>2]);break a}O:{P:{Q:{R:{S:{T:{U:{V:{W:{X:{e=G[T+4>>2];switch(G[e+1048>>2]-11|0){case 40:break S;case 10:case 11:break T;case 20:break U;case 30:break W;case 0:break X;default:break R}}a=G[e+1212>>2];Y:{switch(G[e+1216>>2]-1|0){case 1:n=G[o+72>>2];p=a;v=g+3|0;r=G[o+8>>2]+g|0;k=H[g+1|0]|H[g|0]<<8;l=H[g+2|0];a=8;Z:{_:{$:{while(1){if((c|0)<=(q|0)){break $}e=a-4|0;if((a|0)<=3){while(1){l=H[v|0]|l<<8;a=e>>>0<4294967288;v=v+1|0;e=e+8|0;if(a){continue}break}}a=p+q|0;m=(a|0)<(c|0)?a:c;x=-1<>>e|0)-1|0;da:{if((s|0)<0){if((m|0)<=(q|0)){break da}a=m+(q^-1)|0;l=0;s=m-q&7;if(s){while(1){F[n+(q<<1)>>1]=k;q=q+1|0;l=l+1|0;if((s|0)!=(l|0)){continue}break}}if(a>>>0<7){break ba}while(1){a=n+(q<<1)|0;F[a>>1]=k;F[a+14>>1]=k;F[a+12>>1]=k;F[a+10>>1]=k;F[a+8>>1]=k;F[a+6>>1]=k;F[a+4>>1]=k;F[a+2>>1]=k;q=q+8|0;if((m|0)!=(q|0)){continue}break}break ba}if((s|0)!=14){if((m|0)<=(q|0)){break aa}while(1){if(!t){while(1){e=e+8|0;t=H[v|0];v=v+1|0;if(!t){continue}break}}a=e-G[(t<<2)+103808>>2]|0;e=(a^-1)+e|0;l=1<>>0<4294967288;v=v+1|0;e=e+8|0;if(t){continue}break}}a=a<>>e;a=(a>>>1^0-(a&1))+k|0;F[n+(q<<1)>>1]=a;k=a&65535;t=(-1<(q|0)){break ca}}break aa}s=8-e|0;U=16-e|0;while(1){a=t<>>0>7;v=v+1|0;l=l-8|0;if(t){continue}break}}ea:{if(!e){t=0;break ea}aa=H[v|0];t=aa&x;a=aa>>>0-l|a;v=v+1|0}a=(0-(a&1)^a>>>1)+k|0;F[n+(q<<1)>>1]=a;k=a&65535;q=q+1|0;if((m|0)!=(q|0)){continue}break}}q=m}a=e;l=t;if(r>>>0>=v>>>0){continue}break}e=1;l=16504;break _}e=0;l=11554;if(r>>>0<=v>>>0){break Z}}Ua(l)}m=e;G[j>>2]=e;e=1;a=0;l=0;break O;case 0:break Q;default:break Y}}n=G[o+72>>2];p=a;a=H[g|0]|H[g+1|0]<<8|(H[g+2|0]<<16|H[g+3|0]<<24);k=a<<24|a<<8&16711680|(a>>>8&65280|a>>>24);v=g+5|0;r=G[o+8>>2]+g|0;l=H[g+4|0];a=8;fa:{ga:{ha:{while(1){if((c|0)<=(q|0)){break ha}e=a-5|0;if((a|0)<=4){while(1){l=H[v|0]|l<<8;a=e>>>0<4294967288;v=v+1|0;e=e+8|0;if(a){continue}break}}a=p+q|0;m=(a|0)<(c|0)?a:c;x=-1<>>e|0)-1|0;la:{if((s|0)<0){if((m|0)<=(q|0)){break la}a=m+(q^-1)|0;l=0;s=m-q&7;if(s){while(1){G[n+(q<<2)>>2]=k;q=q+1|0;l=l+1|0;if((s|0)!=(l|0)){continue}break}}if(a>>>0<7){break ja}while(1){a=n+(q<<2)|0;G[a>>2]=k;G[a+28>>2]=k;G[a+24>>2]=k;G[a+20>>2]=k;G[a+16>>2]=k;G[a+12>>2]=k;G[a+8>>2]=k;G[a+4>>2]=k;q=q+8|0;if((m|0)!=(q|0)){continue}break}break ja}if((s|0)!=25){if((m|0)<=(q|0)){break ia}while(1){if(!t){while(1){e=e+8|0;t=H[v|0];v=v+1|0;if(!t){continue}break}}a=e-G[(t<<2)+103808>>2]|0;e=(a^-1)+e|0;l=1<>>0<4294967288;v=v+1|0;e=e+8|0;if(t){continue}break}}a=a<>>e;k=(a>>>1^0-(a&1))+k|0;G[n+(q<<2)>>2]=k;t=(-1<(q|0)){break ka}}break ia}s=24-e|0;U=32-e|0;while(1){a=t<>>0>7;v=v+1|0;l=l-8|0;if(t){continue}break}}ma:{if(!e){t=0;break ma}aa=H[v|0];t=aa&x;a=aa>>>0-l|a;v=v+1|0}k=(0-(a&1)^a>>>1)+k|0;G[n+(q<<2)>>2]=k;q=q+1|0;if((m|0)!=(q|0)){continue}break}}q=m}a=e;l=t;if(r>>>0>=v>>>0){continue}break}e=1;l=16504;break ga}e=0;l=11554;if(r>>>0<=v>>>0){break fa}}Ua(l)}a=e;break V}a=G[e+1224>>2];na:{switch(G[e+1104>>2]-8|0){case 0:case 8:v=G[o+72>>2];k=o- -64|0;wa=Fa-16|0;Fa=wa;U=G[j>>2];if((U|0)<=0){e=H[g|0]|H[g+1|0]<<8;G[48834]=2;F[wa+14>>1]=e;oa:{if((e|0)!=(H[189772]|H[189773]<<8)){Ua(5235);U=414;break oa}e=H[g+2|0]|H[g+3|0]<<8|(H[g+4|0]<<16|H[g+5|0]<<24);G[o+20>>2]=e<<24|e<<8&16711680|(e>>>8&65280|e>>>24);e=H[g+6|0]|H[g+7|0]<<8|(H[g+8|0]<<16|H[g+9|0]<<24);G[k>>2]=e<<24|e<<8&16711680|(e>>>8&65280|e>>>24);e=H[g+10|0]|H[g+11|0]<<8|(H[g+12|0]<<16|H[g+13|0]<<24);G[o+16>>2]=e<<24|e<<8&16711680|(e>>>8&65280|e>>>24);l=H[g+18|0]|H[g+19|0]<<8|(H[g+20|0]<<16|H[g+21|0]<<24);x=H[g+24|0];n=H[g+23|0];U=H[g+22|0];G[48834]=25;e=G[k>>2];m=(e+1|0)/2|0;q=G[o+20>>2];p=(q+1|0)/2|0;s=M(e,q);if((s|0)>0){cb(v,0,s<<2)}t=l>>>8&65280|l>>>24|(l<<8&16711680|l<<24);G[48835]=0;pa:{U=Ji(g,v,e,p,m,U);qa:{if(U){break qa}l=(e|0)/2|0;U=Ji(g,v+(m<<2)|0,e,p,l,n);if(U){break qa}p=M(e,p);q=(q|0)/2|0;U=Ji(g,v+(p<<2)|0,e,q,m,n);if(U){break qa}U=Ji(g,v+(m+p<<2)|0,e,q,l,x);if(U){break qa}R=G[48836];e=G[48835];if((e|0)<=3){l=G[48834];m=H[l+g|0];G[48834]=l+1;R=m|R<<8;G[48836]=R;e=e+8|0}e=e-4|0;G[48835]=e;if(!(R>>e&15)){break pa}Ua(7346);U=414}G[v>>2]=t;break oa}G[48835]=0;if((s|0)>0){m=G[48834];l=0;while(1){e=v+(r<<2)|0;p=G[e>>2];ra:{if(!p){break ra}if(l){l=l-1|0}else{R=H[g+m|0];m=m+1|0;G[48834]=m;G[48836]=R;l=7}G[48835]=l;if(!(R>>>l&1)){break ra}G[e>>2]=0-p}r=r+1|0;if((s|0)!=(r|0)){continue}break}}G[v>>2]=t;G[j>>2]=0;r=G[o+16>>2];sa:{if((r|0)<2){break sa}e=M(G[o+20>>2],G[k>>2]);if((e|0)<=0){break sa}l=(v+(e<<2)|0)-4|0;e=v;while(1){G[e>>2]=M(G[e>>2],r);e=e+4|0;if(l>>>0>=e>>>0){continue}break}r=G[o+16>>2]}na=G[o+20>>2];x=G[k>>2];l=(x|0)<(na|0)?na:x;m=ab((l+1|0)/2<<2);if(!m){Ua(2937);U=414;break oa}U=0;u=oc(+N(l|0))/.6931471805599453+.5;ta:{if(O(u)<2147483648){e=~~u;break ta}e=-2147483648}l=((l|0)>1<>2];G[v>>2]=(k+(4<>1)|0)+(k>>31)&n<<2;if((l|0)>0){ya=0-x|0;k=n<<1;pa=1<>1;sa=0-qa|0;ta=x<<1;Z=0-ta|0;ha=2<>1;l=t-1|0;a=q;la=1;S=1;P=1;y=x;while(1){p=a;s=n;oa=e;e=P<<1;pa=pa>>1;n=(pa|0)>=(y|0);P=e-n|0;W=S<<1;fa=(na|0)<=(pa|0);S=W-fa|0;V=(S|0)<=0;if(!V){C=P+1>>1;aa=C-1|0;a=aa>>31&aa;J=C-a&3;ga=C+(a^-1)|0;X=P-C<<2;$=aa<<1;da=(e+(n?-1:0)|0)-2|0;a=(da>>>1|0)+1|0;Y=a&-8;A=a&7;R=0;while(1){a=M(x,R);if((P|0)>(C|0)){bb(m,v+(a+C<<2)|0,X)}ua:{if((P|0)<=0){break ua}D=v+(a<<2)|0;e=D+(aa<<2)|0;n=D+($<<2)|0;r=0;a=aa;if(J){while(1){G[n>>2]=G[e>>2];a=a-1|0;n=n-8|0;e=e-4|0;r=r+1|0;if((J|0)!=(r|0)){continue}break}}if(ga>>>0>=3){while(1){G[n>>2]=G[e>>2];G[n-8>>2]=G[e-4>>2];G[n-16>>2]=G[e-8>>2];G[n-24>>2]=G[e-12>>2];n=n-32|0;e=e-16|0;r=(a|0)>3;a=a-4|0;if(r){continue}break}}if((P|0)<2){break ua}e=D+4|0;a=0;n=m;if(da>>>0>=14){while(1){G[e>>2]=G[n>>2];G[e+8>>2]=G[n+4>>2];G[e+16>>2]=G[n+8>>2];G[e+24>>2]=G[n+12>>2];G[e+32>>2]=G[n+16>>2];G[e+40>>2]=G[n+20>>2];G[e+48>>2]=G[n+24>>2];G[e+56>>2]=G[n+28>>2];n=n+32|0;e=e- -64|0;a=a+8|0;if((Y|0)!=(a|0)){continue}break}}a=0;if(!A){break ua}while(1){G[e>>2]=G[n>>2];n=n+4|0;e=e+8|0;a=a+1|0;if((A|0)!=(a|0)){continue}break}}R=R+1|0;if((S|0)!=(R|0)){continue}break}}q=q>>1;ga=(P|0)<=0;if(!ga){a=W+(fa?-1:0)|0;aa=S+1>>1;e=a-aa|0;J=e&3;W=e-1|0;R=aa-1|0;e=R>>31&R;A=aa-e&3;fa=aa+(e^-1)|0;X=M(x,aa);$=a-2|0;a=($>>>1|0)+1|0;da=a&-4;D=a&3;Y=M(x,R);ka=Y<<1;ea=0;while(1){C=v+(ea<<2)|0;va:{if((S|0)<=(aa|0)){break va}n=C+(X<<2)|0;r=0;e=m;a=aa;if(J){while(1){G[e>>2]=G[n>>2];a=a+1|0;e=e+4|0;n=(x<<2)+n|0;r=r+1|0;if((J|0)!=(r|0)){continue}break}}if(W>>>0<3){break va}while(1){G[e>>2]=G[n>>2];r=n;n=x<<2;r=r+n|0;G[e+4>>2]=G[r>>2];r=n+r|0;G[e+8>>2]=G[r>>2];r=n+r|0;G[e+12>>2]=G[r>>2];n=n+r|0;e=e+16|0;a=a+4|0;if((S|0)!=(a|0)){continue}break}}wa:{if(V){break wa}e=C+(Y<<2)|0;n=C+(ka<<2)|0;r=0;a=R;if(A){while(1){G[n>>2]=G[e>>2];a=a-1|0;n=(Z<<2)+n|0;e=(ya<<2)+e|0;r=r+1|0;if((A|0)!=(r|0)){continue}break}}if(fa>>>0>=3){while(1){G[n>>2]=G[e>>2];r=n;n=Z<<2;r=r+n|0;_=e;e=ya<<2;_=_+e|0;G[r>>2]=G[_>>2];r=n+r|0;_=e+_|0;G[r>>2]=G[_>>2];r=n+r|0;_=e+_|0;G[r>>2]=G[_>>2];n=n+r|0;e=e+_|0;r=(a|0)>3;a=a-4|0;if(r){continue}break}}if((S|0)<2){break wa}n=C+(x<<2)|0;r=0;e=m;if($>>>0>=6){while(1){G[n>>2]=G[e>>2];a=ta<<2;n=a+n|0;G[n>>2]=G[e+4>>2];n=a+n|0;G[n>>2]=G[e+8>>2];n=a+n|0;G[n>>2]=G[e+12>>2];n=a+n|0;e=e+16|0;r=r+4|0;if((da|0)!=(r|0)){continue}break}}a=0;if(!D){break wa}while(1){G[n>>2]=G[e>>2];e=e+4|0;n=(ta<<2)+n|0;a=a+1|0;if((D|0)!=(a|0)){continue}break}}ea=ea+1|0;if((P|0)!=(ea|0)){continue}break}}aa=l;X=q-1|0;xa:{if(ba){break xa}D=S-2|0;A=(S|0)<5;if(!A){a=2;if(ga){break xa}while(1){e=M(a,x);r=x+e|0;n=0;while(1){J=G[v+(e+ta<<2)>>2];R=G[v+(e<<2)>>2];l=J-R|0;W=G[v+(e-ta<<2)>>2];R=R-W|0;C=(l|0)>(R|0)?l:R;C=(C>>31&C)<<2;l=(l|0)<(R|0)?l:R;l=((l|0)>0?l:0)<<2;if((C|0)<(l|0)){R=J-W|0;l=(l|0)>(R|0)?R:l;l=(l|0)>(C|0)?l:C;R=v+(r<<2)|0;C=G[R>>2];l=l-(C<<3)|0;l=((l|0)<0?l+7|0:l)>>3;l=(l|0)<(qa|0)?l:qa;G[R>>2]=C+((l|0)>(sa|0)?l:sa)}r=r+2|0;e=e+2|0;n=n+2|0;if((P|0)>(n|0)){continue}break}a=a+2|0;if((D|0)>(a|0)){continue}break}}if(!((P|0)<5|V)){W=P-2|0;ea=0;while(1){R=2;a=M(x,ea);r=G[v+(a<<2)>>2];n=a+2|0;l=G[v+(n<<2)>>2];while(1){a=l;e=n+2|0;l=G[v+(e<<2)>>2];C=l-a|0;V=a-r|0;J=(C|0)>(V|0)?C:V;J=(J>>31&J)<<2;C=(C|0)<(V|0)?C:V;C=((C|0)>0?C:0)<<2;if((J|0)<(C|0)){r=l-r|0;r=(r|0)<(C|0)?r:C;J=(r|0)>(J|0)?r:J;r=v+(n<<2|4)|0;C=G[r>>2];n=J-(C<<3)|0;n=((n|0)<0?n+7|0:n)>>3;n=(n|0)<(qa|0)?n:qa;G[r>>2]=C+((n|0)>(sa|0)?n:sa)}r=a;n=e;R=R+2|0;if((W|0)>(R|0)){continue}break}ea=ea+2|0;if((S|0)>(ea|0)){continue}break}}if((P|0)<5|A){break xa}ga=P-2|0;r=2;while(1){n=M(r,x)+2|0;R=x+n|0;a=2;while(1){J=v+(n+ta<<2)|0;$=G[J+8>>2];e=n<<2;C=G[e+v>>2];V=$-C|0;l=G[v+(e|4)>>2]<<1;W=v+(R<<2)|0;e=G[W>>2]<<1;da=l+e|0;A=(V>>31&V)-da|0;Y=G[J-8>>2];J=C-Y|0;fa=(e+(J>>31&J)|0)-l|0;fa=(A|0)>(fa|0)?A:fa;ka=v+(n-ta<<2)|0;_=G[ka+8>>2];A=C-_|0;ia=(A>>31&A)-e|0;ka=G[ka-8>>2];C=ka-C|0;ua=e+(C>>31&C)|0;ia=l+((ia|0)>(ua|0)?ia:ua)|0;fa=((fa|0)>(ia|0)?fa:ia)<<4;V=((V|0)>0?V:0)-da|0;J=(e+((J|0)>0?J:0)|0)-l|0;V=(J|0)>(V|0)?V:J;J=((A|0)>0?A:0)-e|0;e=e+((C|0)>0?C:0)|0;e=l+((e|0)>(J|0)?J:e)|0;e=((e|0)>(V|0)?V:e)<<4;if((fa|0)<(e|0)){l=$+(ka-(Y+_|0)|0)|0;e=(e|0)>(l|0)?l:e;l=G[W+4>>2];e=((e|0)>(fa|0)?e:fa)-(l<<6)|0;e=((e|0)<0?e+63|0:e)>>6;e=(e|0)<(qa|0)?e:qa;G[W+4>>2]=((e|0)>(sa|0)?e:sa)+l}R=R+2|0;n=n+2|0;a=a+2|0;if((ga|0)>(a|0)){continue}break}r=r+2|0;if((D|0)>(r|0)){continue}break}}$=(y|0)>(pa|0);da=(na|0)>(pa|0);la=oa?la:2;l=oa?X:0;J=(P|0)%2|0;X=(S|0)%2|0;Y=S-X|0;ya:{if((Y|0)<=0){e=0;break ya}fa=P-J|0;e=0;while(1){r=M(e,x);n=x+r|0;a=0;if((fa|0)>0){while(1){R=v+(n<<2)|0;C=G[R+4>>2];A=s&((C|0)<0?l:q)+C;V=A&p;D=0-V|0;C=G[R>>2];C=((C|0)<0?aa:t)+C&k;C=((C|0)<0?V:D)+C|0;_=D;ga=r<<2;ka=v+(ga|4)|0;D=G[ka>>2];D=((D|0)<0?aa:t)+D&k;D=((D|0)<0?V:_)+D|0;W=(C^A^D)&ha;_=v+ga|0;ga=G[_>>2];za:{if((ga|0)>=0){V=(V+ga|0)-W|0;break za}V=ga+(V?V-W|0:W)|0}W=V+C|0;ga=A+D|0;G[R+4>>2]=W+ga>>la;G[R>>2]=W-ga>>la;R=V-C|0;G[ka>>2]=R+(D-A|0)>>la;G[_>>2]=R+(A-D|0)>>la;n=n+2|0;r=r+2|0;a=a+2|0;if((fa|0)>(a|0)){continue}break}}if(J){R=v+(n<<2)|0;a=G[R>>2];a=((a|0)<0?aa:t)+a&k;n=a&ha;D=n;_=0-n|0;r=v+(r<<2)|0;n=G[r>>2];n=((n|0)<0?D:_)+n|0;G[R>>2]=a+n>>la;G[r>>2]=n-a>>la}e=e+2|0;if((Y|0)>(e|0)){continue}break}}R=$?pa:0;C=da?pa:0;Aa:{if(!X){break Aa}e=M(e,x);a=0;V=P-J|0;if((V|0)>0){while(1){A=e<<2;D=v+(A|4)|0;n=G[D>>2];n=((n|0)<0?aa:t)+n&k;r=n&ha;$=r;_=0-r|0;r=v+A|0;A=G[r>>2];A=((A|0)<0?$:_)+A|0;G[D>>2]=A+n>>la;G[r>>2]=A-n>>la;e=e+2|0;a=a+2|0;if((V|0)>(a|0)){continue}break}}if(!J){break Aa}a=v+(e<<2)|0;G[a>>2]=G[a>>2]>>la}y=y-R|0;na=na-C|0;e=oa-1|0;n=s>>1;a=p>>1;t=q;k=s;ha=p;if((oa|0)>0){continue}break}}Wa(m)}G[j>>2]=U}Fa=wa+16|0;a=U;break V;default:break na}}s=a;S=G[o+72>>2];Ja=o- -64|0;Na=Fa-16|0;Fa=Na;a=G[j>>2];Ba:{if((a|0)>0){break Ba}a=H[g|0]|H[g+1|0]<<8;G[48834]=2;F[Na+14>>1]=a;if((a|0)!=(H[189772]|H[189773]<<8)){Ua(5235);a=414;G[j>>2]=414;break Ba}a=H[g+2|0]|H[g+3|0]<<8|(H[g+4|0]<<16|H[g+5|0]<<24);G[o+20>>2]=a<<24|a<<8&16711680|(a>>>8&65280|a>>>24);a=H[g+6|0]|H[g+7|0]<<8|(H[g+8|0]<<16|H[g+9|0]<<24);G[Ja>>2]=a<<24|a<<8&16711680|(a>>>8&65280|a>>>24);a=H[g+10|0]|H[g+11|0]<<8|(H[g+12|0]<<16|H[g+13|0]<<24);G[o+16>>2]=a<<24|a<<8&16711680|(a>>>8&65280|a>>>24);l=H[g+14|0]|H[g+15|0]<<8|(H[g+16|0]<<16|H[g+17|0]<<24);a=H[g+18|0]|H[g+19|0]<<8|(H[g+20|0]<<16|H[g+21|0]<<24);U=H[g+24|0];t=H[g+23|0];aa=H[g+22|0];G[48834]=25;m=G[Ja>>2];n=(m+1|0)/2|0;v=G[o+20>>2];r=(v+1|0)/2|0;q=M(m,v);if((q|0)>0){cb(S,0,q<<3)}x=((a&255)<<24|l>>>8)&-16777216|((a&16777215)<<8|l>>>24)&16711680|(a>>>8&65280|a>>>24);p=l<<8;e=0;k=p&16711680;x=e|x;p=l<<24|k|((a<<24|l>>>8)&65280|(a<<8|l>>>24)&255)|oa;G[48835]=0;Ca:{a=Ii(g,S,m,r,n,aa);Da:{if(a){break Da}e=(m|0)/2|0;a=Ii(g,S+(n<<3)|0,m,r,e,t);if(a){break Da}l=M(m,r);k=(v|0)/2|0;a=Ii(g,S+(l<<3)|0,m,k,n,t);if(a){break Da}a=Ii(g,S+(l+n<<3)|0,m,k,e,U);if(a){break Da}k=G[48836];a=G[48835];if((a|0)<=3){e=G[48834];l=H[e+g|0];G[48834]=e+1;k=l|k<<8;G[48836]=k;a=a+8|0}a=a-4|0;G[48835]=a;if(!(k>>a&15)){break Ca}Ua(7377);a=414}G[S>>2]=x;G[S+4>>2]=p;G[j>>2]=a;break Ba}G[48835]=0;if((q|0)>0){m=G[48834];a=0;while(1){n=S+(a<<3)|0;l=n;e=G[l+4>>2];l=G[l>>2];Ea:{if(!(e|l)){break Ea}if(y){y=y-1|0}else{k=H[g+m|0];m=m+1|0;G[48834]=m;G[48836]=k;y=7}G[48835]=y;if(!(k>>>y&1)){break Ea}G[n>>2]=0-l;G[n+4>>2]=0-(((l|0)!=0)+e|0)}a=a+1|0;if((q|0)!=(a|0)){continue}break}}G[S>>2]=x;G[S+4>>2]=p;G[j>>2]=0;W=G[Ja>>2];Ba=G[o+20>>2];l=G[o+16>>2];Fa:{if((l|0)<2){break Fa}a=M(W,Ba);if((a|0)<=0){break Fa}e=(S+(a<<3)|0)-8|0;a=S;while(1){_a=a,$a=Au(G[a>>2],G[a+4>>2],l,0),G[_a>>2]=$a;G[a+4>>2]=Ia;a=a+8|0;if(e>>>0>=a>>>0){continue}break}}m=(W|0)<(Ba|0)?Ba:W;aa=ab((m+1|0)/2<<3);Ga:{if(!aa){Ua(3091);a=414;break Ga}u=oc(+N(m|0))/.6931471805599453+.5;Ha:{if(O(u)<2147483648){e=~~u;break Ha}e=-2147483648}a=G[S+4>>2];k=a;r=e+((m|0)>1<>>0>=32){p=4<>>32-e;m=4<>1;p=(p&1)<<31|m>>>1;m=p+G[S>>2]|0;e=e+k|0;e=m>>>0

>>0?e+1|0:e;p=m;m=e;e=k>>31;n=e;e=p+e|0;k=m+n|0;q=e;p=e>>>0>>0?k+1|0:k;e=a;k=e&31;if((e&63)>>>0>=32){e=1<>>32-k}U=m;n=e;m=0-(e+((U|0)!=0)|0)|0;x=0-U|0;e=S;G[e>>2]=x<<2&q;G[e+4>>2]=(m<<2|x>>>30)&p;if((r|0)>0){Pa=0-W|0;e=x;k=m<<1|e>>>31;wa=e<<1;pa=k;ha=1<>1;Ea=e;Ga=0-e|0;va=e>>31;xa=0-(va+((e|0)!=0)|0)|0;e=a;l=e&31;if((e&63)>>>0>=32){e=2<>>32-l;qa=2<>1;sa=k;la=(e&1)<<31|qa>>>1;r=la-1|0;v=k-!la|0;k=U;p=n;oa=1;ra=1;ea=1;q=W;while(1){ya=a;l=ea<<1;ha=ha>>1;s=(ha|0)>=(q|0);ea=l-s|0;V=ra<<1;A=(ha|0)>=(Ba|0);ra=V-A|0;J=(ra|0)<=0;if(!J){R=ea+1>>1;e=R-1|0;a=e>>31&e;C=R-a&3;D=R+(a^-1)|0;Z=ea-R<<3;fa=e<<1;ga=(l+(s?-1:0)|0)-2|0;a=(ga>>>1|0)+1|0;ba=a&-8;P=a&7;y=0;while(1){a=M(y,W);if((R|0)<(ea|0)){bb(aa,S+(a+R<<3)|0,Z)}Ia:{if((ea|0)<=0){break Ia}na=S+(a<<3)|0;a=na+(e<<3)|0;l=na+(fa<<3)|0;t=0;s=e;if(C){while(1){X=G[a+4>>2];G[l>>2]=G[a>>2];G[l+4>>2]=X;s=s-1|0;l=l-16|0;a=a-8|0;t=t+1|0;if((C|0)!=(t|0)){continue}break}}if(D>>>0>=3){while(1){t=G[a+4>>2];G[l>>2]=G[a>>2];G[l+4>>2]=t;X=a-8|0;$=G[X+4>>2];t=l-16|0;G[t>>2]=G[X>>2];G[t+4>>2]=$;X=a-16|0;$=G[X+4>>2];t=l-32|0;G[t>>2]=G[X>>2];G[t+4>>2]=$;X=a-24|0;$=G[X+4>>2];t=l-48|0;G[t>>2]=G[X>>2];G[t+4>>2]=$;l=l+-64|0;a=a-32|0;t=(s|0)>3;s=s-4|0;if(t){continue}break}}if((ea|0)<2){break Ia}a=na+8|0;s=0;l=aa;if(ga>>>0>=14){while(1){t=G[l+4>>2];G[a>>2]=G[l>>2];G[a+4>>2]=t;t=G[l+12>>2];G[a+16>>2]=G[l+8>>2];G[a+20>>2]=t;t=G[l+20>>2];G[a+32>>2]=G[l+16>>2];G[a+36>>2]=t;t=G[l+28>>2];G[a+48>>2]=G[l+24>>2];G[a+52>>2]=t;t=G[l+36>>2];G[a+64>>2]=G[l+32>>2];G[a+68>>2]=t;t=G[l+44>>2];G[a+80>>2]=G[l+40>>2];G[a+84>>2]=t;t=G[l+52>>2];G[a+96>>2]=G[l+48>>2];G[a+100>>2]=t;t=G[l+60>>2];G[a+112>>2]=G[l+56>>2];G[a+116>>2]=t;l=l- -64|0;a=a+128|0;s=s+8|0;if((ba|0)!=(s|0)){continue}break}}s=0;if(!P){break Ia}while(1){t=G[l+4>>2];G[a>>2]=G[l>>2];G[a+4>>2]=t;l=l+8|0;a=a+16|0;s=s+1|0;if((P|0)!=(s|0)){continue}break}}y=y+1|0;if((y|0)!=(ra|0)){continue}break}}U=(n&1)<<31|U>>>1;n=n>>1;D=(ea|0)<=0;if(!D){a=V+(A?-1:0)|0;e=ra+1>>1;l=a-e|0;y=l&3;Z=l-1|0;R=e-1|0;l=R>>31&R;na=e-l&3;fa=e+(l^-1)|0;ga=M(e,W);ba=a-2|0;a=(ba>>>1|0)+1|0;X=a&-4;V=a&3;$=M(R,W);da=$<<1;P=0;while(1){C=S+(P<<3)|0;Ja:{if((e|0)>=(ra|0)){break Ja}l=C+(ga<<3)|0;t=0;a=aa;s=e;if(y){while(1){A=G[l+4>>2];G[a>>2]=G[l>>2];G[a+4>>2]=A;s=s+1|0;a=a+8|0;l=l+(W<<3)|0;t=t+1|0;if((y|0)!=(t|0)){continue}break}}if(Z>>>0<3){break Ja}while(1){t=G[l+4>>2];G[a>>2]=G[l>>2];G[a+4>>2]=t;t=l;l=W<<3;t=t+l|0;A=G[t+4>>2];G[a+8>>2]=G[t>>2];G[a+12>>2]=A;t=l+t|0;A=G[t+4>>2];G[a+16>>2]=G[t>>2];G[a+20>>2]=A;t=l+t|0;A=G[t+4>>2];G[a+24>>2]=G[t>>2];G[a+28>>2]=A;l=l+t|0;a=a+32|0;s=s+4|0;if((ra|0)!=(s|0)){continue}break}}Ka:{if(J){break Ka}a=C+($<<3)|0;l=C+(da<<3)|0;t=0;s=R;if(na){while(1){A=G[a+4>>2];G[l>>2]=G[a>>2];G[l+4>>2]=A;s=s-1|0;l=l+(Qa<<3)|0;a=a+(Pa<<3)|0;t=t+1|0;if((na|0)!=(t|0)){continue}break}}if(fa>>>0>=3){while(1){t=G[a+4>>2];G[l>>2]=G[a>>2];G[l+4>>2]=t;t=a;a=Pa<<3;A=t+a|0;Y=G[A+4>>2];t=l;l=Qa<<3;t=t+l|0;G[t>>2]=G[A>>2];G[t+4>>2]=Y;A=a+A|0;Y=G[A+4>>2];t=l+t|0;G[t>>2]=G[A>>2];G[t+4>>2]=Y;A=a+A|0;Y=G[A+4>>2];t=l+t|0;G[t>>2]=G[A>>2];G[t+4>>2]=Y;l=l+t|0;a=a+A|0;t=(s|0)>3;s=s-4|0;if(t){continue}break}}if((ra|0)<2){break Ka}l=C+(W<<3)|0;t=0;a=aa;if(ba>>>0>=6){while(1){s=G[a+4>>2];G[l>>2]=G[a>>2];G[l+4>>2]=s;C=G[a+12>>2];s=l;l=Ca<<3;s=s+l|0;G[s>>2]=G[a+8>>2];G[s+4>>2]=C;C=G[a+20>>2];s=l+s|0;G[s>>2]=G[a+16>>2];G[s+4>>2]=C;C=G[a+28>>2];s=l+s|0;G[s>>2]=G[a+24>>2];G[s+4>>2]=C;l=l+s|0;a=a+32|0;t=t+4|0;if((X|0)!=(t|0)){continue}break}}s=0;if(!V){break Ka}while(1){t=G[a+4>>2];G[l>>2]=G[a>>2];G[l+4>>2]=t;a=a+8|0;l=l+(Ca<<3)|0;s=s+1|0;if((V|0)!=(s|0)){continue}break}}P=P+1|0;if((P|0)!=(ea|0)){continue}break}}na=x;R=m;V=k;C=p;fa=r;ga=v;Oa=U-1|0;Xa=n-!U|0;La:{if(Va){break La}Ka=ra-2|0;ba=(ra|0)<5;if(!ba){y=2;if(D){break La}while(1){a=M(y,W);l=W+a|0;s=0;while(1){p=S+(a+Ca<<3)|0;e=G[p>>2];r=S+(a<<3)|0;k=G[r>>2];v=e-k|0;t=S+(a-Ca<<3)|0;m=G[t>>2];x=k-m|0;A=G[p+4>>2];p=G[r+4>>2];r=A-(p+(e>>>0>>0)|0)|0;D=G[t+4>>2];t=p-(D+(k>>>0>>0)|0)|0;k=v>>>0>x>>>0&(r|0)>=(t|0)|(r|0)>(t|0);p=k?v:x;P=k?r:t;k=P>>31;P=k&P;k=p&k;p=P<<2|k>>>30;P=k<<2;k=v>>>0>>0&(r|0)<=(t|0)|(r|0)<(t|0);v=k?v:x;k=k?r:t;r=!!v&(k|0)>=0|(k|0)>0;t=r?v:0;k=r?k:0;r=t;v=r<<2;k=k<<2|r>>>30;if(P>>>0>>0&(k|0)>=(p|0)|(k|0)>(p|0)){t=A-((e>>>0>>0)+D|0)|0;e=e-m|0;m=e;e=e>>>0>>0&(k|0)>=(t|0)|(k|0)>(t|0);m=e?m:v;r=m;e=e?t:k;m=(p|0)<=(e|0)&m>>>0>P>>>0|(e|0)>(p|0);k=m?r:P;t=m?e:p;r=S+(l<<3)|0;e=G[r+4>>2];v=e;m=G[r>>2];e=e<<3|m>>>29;p=m<<3;e=t-((k>>>0

>>0)+e|0)|0;k=k-p|0;t=k+7|0;p=t>>>0<7?e+1|0:e;x=k;k=(e|0)<0;t=k?t:x;k=k?p:e;p=t;e=k>>3;k=(k&7)<<29|p>>>3;p=k;k=k>>>0>>0&(e|0)<=(va|0)|(e|0)<(va|0);p=k?p:Ea;t=p;k=k?e:va;e=k;p=(xa|0)<=(e|0)&p>>>0>Ga>>>0|(e|0)>(xa|0);e=m+(p?t:Ga)|0;p=v+(p?k:xa)|0;G[r>>2]=e;G[r+4>>2]=e>>>0>>0?p+1|0:p}l=l+2|0;a=a+2|0;s=s+2|0;if((ea|0)>(s|0)){continue}break}y=y+2|0;if((Ka|0)>(y|0)){continue}break}}if(!((ea|0)<5|J)){X=ea-2|0;y=0;while(1){a=M(y,W);e=S+(a<<3)|0;r=G[e>>2];v=G[e+4>>2];l=2;a=a+2|0;e=S+(a<<3)|0;x=G[e>>2];m=G[e+4>>2];while(1){s=x;t=m;J=a+2|0;k=S+(J<<3)|0;x=G[k>>2];e=s;A=x-e|0;D=e-r|0;m=G[k+4>>2];k=m-((e>>>0>x>>>0)+t|0)|0;P=t-((e>>>0>>0)+v|0)|0;e=A>>>0>D>>>0&(k|0)>=(P|0)|(k|0)>(P|0);p=e?A:D;Z=e?k:P;e=Z>>31;Z=e&Z;e=p&e;p=Z<<2|e>>>30;Z=e<<2;e=A>>>0>>0&(k|0)<=(P|0)|(k|0)<(P|0);A=e?A:D;e=e?k:P;k=!!A&(e|0)>=0|(e|0)>0;P=k?A:0;e=k?e:0;k=P;P=k<<2;e=e<<2|k>>>30;if(Z>>>0

>>0&(e|0)>=(p|0)|(e|0)>(p|0)){k=m-((r>>>0>x>>>0)+v|0)|0;r=x-r|0;v=r;r=r>>>0

>>0&(e|0)>=(k|0)|(e|0)>(k|0);v=r?v:P;k=r?k:e;e=k;r=(p|0)<=(e|0)&v>>>0>Z>>>0|(e|0)>(p|0);e=r?v:Z;v=r?k:p;a=S+(a<<3|8)|0;k=G[a+4>>2];P=k;r=G[a>>2];p=r;k=k<<3|p>>>29;p=p<<3;k=v-((e>>>0

>>0)+k|0)|0;v=e-p|0;e=a;a=k;k=v+7|0;p=k>>>0<7?a+1|0:a;D=k;k=(a|0)<0;v=k?D:v;a=k?p:a;p=v;k=a>>3;a=(a&7)<<29|p>>>3;p=a;a=a>>>0>>0&(k|0)<=(va|0)|(k|0)<(va|0);p=a?p:Ea;v=p;k=a?k:va;a=k;p=(xa|0)<=(a|0)&p>>>0>Ga>>>0|(a|0)>(xa|0);a=r+(p?v:Ga)|0;p=P+(p?k:xa)|0;G[e>>2]=a;G[e+4>>2]=a>>>0>>0?p+1|0:p}r=s;v=t;a=J;l=l+2|0;if((X|0)>(l|0)){continue}break}y=y+2|0;if((y|0)<(ra|0)){continue}break}}if((ea|0)<5|ba){break La}Ya=ea-2|0;t=2;while(1){a=M(t,W)+2|0;l=W+a|0;s=2;while(1){J=S+(a+Ca<<3)|0;e=J;x=G[e+16>>2];m=a<<3;p=m+S|0;k=G[p>>2];D=x-k|0;Ra=G[e+20>>2];Y=G[p+4>>2];Z=Ra-(Y+(k>>>0>x>>>0)|0)|0;e=Z>>31;P=e&D;ba=e&Z;e=S+(m|8)|0;m=G[e+4>>2];e=G[e>>2];r=e<<1;p=m<<1|e>>>31;v=p;e=p;ka=S+(l<<3)|0;m=ka;p=G[m+4>>2];m=G[m>>2];p=p<<1|m>>>31;m=m<<1;y=m+r|0;A=p;e=p+e|0;e=m>>>0>y>>>0?e+1|0:e;Da=e;p=ba-(e+(y>>>0>P>>>0)|0)|0;P=P-y|0;e=J-16|0;ua=G[e>>2];ba=k-ua|0;Sa=G[e+4>>2];X=Y-(Sa+(k>>>0>>0)|0)|0;e=X>>31;J=m+(e&ba)|0;e=A+(e&X)|0;e=m>>>0>J>>>0?e+1|0:e;e=e-((r>>>0>J>>>0)+v|0)|0;$=P;J=J-r|0;P=(e|0)<=(p|0)&P>>>0>J>>>0|(e|0)<(p|0);_=P?$:J;e=P?p:e;Ha=e;J=S+(a-Ca<<3)|0;e=J;P=G[e+16>>2];$=k-P|0;Ta=G[e+20>>2];da=Y-(Ta+(k>>>0

>>0)|0)|0;e=da>>31;p=e&$;ia=(e&da)-((m>>>0>p>>>0)+A|0)|0;za=p-m|0;e=J-16|0;J=G[e>>2];La=G[e+4>>2];Y=La-((k>>>0>J>>>0)+Y|0)|0;e=J-k|0;k=Y>>31;Ma=m+(e&k)|0;k=A+(k&Y)|0;Za=za;p=Ma;k=m>>>0>p>>>0?k+1|0:k;za=p>>>0>>0&(k|0)<=(ia|0)|(k|0)<(ia|0);p=r+(za?Za:p)|0;k=v+(za?ia:k)|0;k=p>>>0>>0?k+1|0:k;ia=p;p=p>>>0<_>>>0&(k|0)<=(Ha|0)|(k|0)<(Ha|0);_=p?_:ia;p=p?Ha:k;k=_;_=k<<4;p=p<<4|k>>>28;ia=p;k=!!D&(Z|0)>=0|(Z|0)>0;p=k?D:0;k=(k?Z:0)-((p>>>0>>0)+Da|0)|0;y=p-y|0;p=!!ba&(X|0)>=0|(X|0)>0;D=m+(p?ba:0)|0;p=A+(p?X:0)|0;p=m>>>0>D>>>0?p+1|0:p;p=p-((r>>>0>D>>>0)+v|0)|0;D=D-r|0;Z=D;D=y>>>0>>0&(k|0)<=(p|0)|(k|0)<(p|0);y=D?y:Z;k=D?k:p;p=k;Z=r;k=!!$&(da|0)>=0|(da|0)>0;D=k?$:0;k=(k?da:0)-((m>>>0>D>>>0)+A|0)|0;r=e;e=!!e&(Y|0)>=0|(Y|0)>0;r=m+(e?r:0)|0;e=A+(e?Y:0)|0;e=m>>>0>r>>>0?e+1|0:e;D=D-m|0;m=r;r=m>>>0>D>>>0&(e|0)>=(k|0)|(e|0)>(k|0);A=r?D:m;m=Z+A|0;k=(r?k:e)+v|0;e=m;k=e>>>0>>0?k+1|0:k;e=(p|0)<=(k|0)&e>>>0>y>>>0|(k|0)>(p|0);m=e?y:m;k=e?p:k;e=m;r=e<<4;k=k<<4|e>>>28;p=k;if(r>>>0>_>>>0&(k|0)>=(ia|0)|(k|0)>(ia|0)){m=ka;e=Sa+Ta|0;k=P+ua|0;e=k>>>0

>>0?e+1|0:e;v=x+(J-k|0)|0;k=Ra+(La-((k>>>0>J>>>0)+e|0)|0)|0;e=v;k=e>>>0>>0?k+1|0:k;e=e>>>0>>0&(k|0)<=(p|0)|(k|0)<(p|0);r=e?v:r;k=e?k:p;e=k;p=(ia|0)<=(e|0)&r>>>0>_>>>0|(e|0)>(ia|0);e=p?r:_;v=p?k:ia;k=G[m+12>>2];x=k;p=G[m+8>>2];k=k<<6|p>>>26;r=p<<6;k=v-((e>>>0>>0)+k|0)|0;r=e-r|0;e=k;v=r+63|0;e=v>>>0<63?e+1|0:e;y=r;r=(k|0)<0;v=r?v:y;e=r?e:k;r=v;k=e>>6;e=(e&63)<<26|r>>>6;r=e;e=e>>>0>>0&(k|0)<=(va|0)|(k|0)<(va|0);r=e?r:Ea;v=r;k=e?k:va;e=k;r=(xa|0)<=(e|0)&r>>>0>Ga>>>0|(e|0)>(xa|0);e=p+(r?v:Ga)|0;k=x+(r?k:xa)|0;G[m+8>>2]=e;G[m+12>>2]=e>>>0

>>0?k+1|0:k}l=l+2|0;a=a+2|0;s=s+2|0;if((Ya|0)>(s|0)){continue}break}t=t+2|0;if((Ka|0)>(t|0)){continue}break}}La=(q|0)>(ha|0);Ka=(ha|0)<(Ba|0);oa=ya?oa:2;r=ya?Oa:0;v=ya?Xa:0;ua=(ea|0)%2|0;za=(ra|0)%2|0;Ma=ra-za|0;Ma:{if((Ma|0)<=0){s=0;break Ma}Ha=ea-ua|0;m=oa;s=0;while(1){a=M(s,W);l=W+a|0;t=0;if((Ha|0)>0){while(1){y=S+(l<<3)|0;e=y;k=G[e+12>>2];e=G[e+8>>2];p=(k|0)<0;x=e+(p?r:U)|0;p=k+(p?v:n)|0;p=e>>>0>x>>>0?p+1|0:p;P=x&na;e=V&P;Da=p&R;k=C&Da;Z=k;J=k;x=0-e|0;k=0-(((e|0)!=0)+k|0)|0;D=k;A=G[y>>2];X=G[y+4>>2];$=(X|0)<0;ba=A+($?fa:la)|0;p=X+($?ga:sa)|0;p=A>>>0>ba>>>0?p+1|0:p;A=ba&wa;p=p&pa;ba=p;X=(p|0)<0;p=A+(X?e:x)|0;k=ba+(X?J:k)|0;J=p;$=P^p;A=p>>>0>>0?k+1|0:k;da=Da^A;Y=a<<3;X=S+(Y|8)|0;k=X;p=G[k+4>>2];k=G[k>>2];ka=(p|0)<0;ba=k+(ka?fa:la)|0;p=p+(ka?ga:sa)|0;p=k>>>0>ba>>>0?p+1|0:p;k=ba&wa;p=p&pa;ba=p;_=$;$=(p|0)<0;p=k;x=($?e:x)+k|0;k=ba+($?Z:D)|0;k=p>>>0>x>>>0?k+1|0:k;p=qa&(_^x);ba=k;da=ta&(k^da);$=S+Y|0;k=$;D=G[k+4>>2];k=G[k>>2];Na:{if((D|0)>0|(D|0)>=0){Y=e+k|0;e=D+Z|0;e=k>>>0>Y>>>0?e+1|0:e;k=Y;D=k-p|0;Z=e-((k>>>0

>>0)+da|0)|0;break Na}ka=!(e|Z);Y=k+(ka?p:e-p|0)|0;p=D+(ka?da:Z-((e>>>0

>>0)+da|0)|0)|0;D=Y;Z=k>>>0>D>>>0?p+1|0:p}e=Z+A|0;k=J+D|0;e=k>>>0>>0?e+1|0:e;p=k;da=e;k=ba+Da|0;Y=x+P|0;k=Y>>>0>>0?k+1|0:k;_=Y+p|0;ka=k;e=k+e|0;e=Y>>>0>_>>>0?e+1|0:e;k=e;Oa=_;ia=m&31;_=y;if((m&63)>>>0>=32){e=k>>31;k=k>>ia}else{e=k>>ia;k=((1<>>ia}G[y+8>>2]=k;G[_+12>>2]=e;e=p-Y|0;p=da-((p>>>0>>0)+ka|0)|0;da=e;k=m&31;if((m&63)>>>0>=32){e=p>>31;k=p>>k}else{e=p>>k;k=((1<>>k}G[y>>2]=k;G[y+4>>2]=e;k=X;y=D-J|0;X=x-P|0;p=y+X|0;A=Z-((J>>>0>D>>>0)+A|0)|0;e=A+(ba-((x>>>0

>>0)+Da|0)|0)|0;e=p>>>0>>0?e+1|0:e;D=p;J=m&31;if((m&63)>>>0>=32){p=e>>31;e=e>>J}else{p=e>>J;e=((1<>>J}G[k>>2]=e;G[k+4>>2]=p;e=A+(Da-((x>>>0>P>>>0)+ba|0)|0)|0;p=y+(P-x|0)|0;e=p>>>0>>0?e+1|0:e;y=p;x=m&31;k=$;if((m&63)>>>0>=32){p=e>>31;e=e>>x}else{p=e>>x;e=((1<>>x}G[k>>2]=e;G[k+4>>2]=p;l=l+2|0;a=a+2|0;t=t+2|0;if((Ha|0)>(t|0)){continue}break}}if(ua){l=S+(l<<3)|0;t=l;e=G[l>>2];k=G[l+4>>2];p=(k|0)<0;l=e+(p?fa:la)|0;k=k+(p?ga:sa)|0;k=e>>>0>l>>>0?k+1|0:k;l=l&wa;e=qa&l;p=e;x=0-e|0;y=x;x=S+(a<<3)|0;a=x;e=G[a+4>>2];a=G[a>>2];J=(e|0)<0;y=(J?p:y)+a|0;P=k&pa;k=ta&P;p=e+(J?k:0-(((p|0)!=0)+k|0)|0)|0;p=a>>>0>y>>>0?p+1|0:p;k=y;a=l+k|0;e=p+P|0;y=a;a=a>>>0>>0?e+1|0:e;J=y;y=m&31;if((m&63)>>>0>=32){e=a>>31;a=a>>y}else{e=a>>y;a=((1<>>y}G[t>>2]=a;G[t+4>>2]=e;a=k-l|0;l=p-((k>>>0>>0)+P|0)|0;k=a;a=m&31;if((m&63)>>>0>=32){e=l>>31;a=l>>a}else{e=l>>a;a=((1<>>a}G[x>>2]=a;G[x+4>>2]=e}s=s+2|0;if((Ma|0)>(s|0)){continue}break}}J=La?ha:0;A=Ka?ha:0;Oa:{if(!za){break Oa}a=M(s,W);D=ea-ua|0;if((D|0)>0){l=0;while(1){p=a<<3;k=S+(p|8)|0;s=k;e=G[k>>2];k=G[k+4>>2];t=(k|0)<0;m=e+(t?fa:la)|0;k=k+(t?ga:sa)|0;k=e>>>0>m>>>0?k+1|0:k;m=m&wa;e=qa&m;Z=e;t=0-e|0;y=t;t=p+S|0;e=t;x=G[e+4>>2];e=G[e>>2];ba=(x|0)<0;p=e;y=(ba?Z:y)+e|0;P=k&pa;e=ta&P;e=x+(ba?e:0-(((Z|0)!=0)+e|0)|0)|0;e=p>>>0>y>>>0?e+1|0:e;k=y;y=m+k|0;x=e;p=P+e|0;p=m>>>0>y>>>0?p+1|0:p;e=p;Z=y;p=oa;y=p&31;if((p&63)>>>0>=32){p=e>>31;e=e>>y}else{p=e>>y;e=((1<>>y}G[s>>2]=e;G[s+4>>2]=p;e=k-m|0;m=x-((k>>>0>>0)+P|0)|0;s=e;e=oa;k=e&31;if((e&63)>>>0>=32){p=m>>31;e=m>>k}else{p=m>>k;e=((1<>>k}G[t>>2]=e;G[t+4>>2]=p;a=a+2|0;l=l+2|0;if((D|0)>(l|0)){continue}break}}if(!ua){break Oa}a=S+(a<<3)|0;l=a;m=a;e=G[a+4>>2];k=G[a>>2];a=oa&31;if((oa&63)>>>0>=32){p=e>>31;a=e>>a}else{p=e>>a;a=((1<>>a}G[m>>2]=a;G[l+4>>2]=p}q=q-J|0;Ba=Ba-A|0;a=ya-1|0;x=(R&1)<<31|na>>>1;m=R>>1;p=C>>1;k=(C&1)<<31|V>>>1;qa=V;ta=C;la=U;sa=n;wa=na;pa=R;if((ya|0)>0){continue}break}}Wa(aa);a=0}G[j>>2]=a;e=M(G[Ja>>2],G[o+20>>2]);if((e|0)<=0){break Ba}l=0;a=0;if(e-1>>>0>=3){k=e&-4;s=0;while(1){G[S+(a<<2)>>2]=G[S+(a<<3)>>2];m=a|1;G[S+(m<<2)>>2]=G[S+(m<<3)>>2];m=a|2;G[S+(m<<2)>>2]=G[S+(m<<3)>>2];m=a|3;G[S+(m<<2)>>2]=G[S+(m<<3)>>2];a=a+4|0;s=s+4|0;if((k|0)!=(s|0)){continue}break}}e=e&3;if(e){while(1){G[S+(a<<2)>>2]=G[S+(a<<3)>>2];a=a+1|0;l=l+1|0;if((e|0)!=(l|0)){continue}break}}a=G[j>>2]}Fa=Na+16|0}m=a;G[j>>2]=a;e=0;a=1;l=0;break O}a=1;t=G[o+72>>2];e=F[g+4>>1];Pa:{if((e|0)>0){v=e&65535;r=4;break Pa}v=F[g+6>>1]+(F[g+8>>1]<<15)|0;r=F[g+2>>1]+1|0}if(!((c|0)<=0|(v|0)<=0)){q=1;Qa:{if((r|0)>(v|0)){k=1;break Qa}oa=g-2|0;p=t-4|0;x=c+1|0;aa=x-1|0;k=1;s=1;while(1){Ra:{if(n){n=0;break Ra}n=0;U=F[oa+(r<<1)>>1];Sa:{if((U|0)<-4095){break Sa}e=U&4095;Ta:{Ua:{switch((U|0)/4096&65535){case 0:case 4:case 5:e=e+s|0;l=e-1|0;R=(l|0)<(aa|0)?l:aa;C=(s|0)>1?s:1;m=R-C|0;if((m|0)<0){s=e;break Sa}s=k+m|0;S=k+1|0;l=S+m|0;U=U&-4096;Va:{if((U|0)!=16384){if((k|0)<=(s|0)){cb(p+(k<<2)|0,0,(m<<2)+4|0)}if((U|0)!=20480|(e|0)>(x|0)){break Va}G[p+(s<<2)>>2]=q;break Va}if((k|0)>(s|0)){break Va}s=m+1&7;if(s){while(1){G[p+(k<<2)>>2]=q;k=k+1|0;n=n+1|0;if((s|0)!=(n|0)){continue}break}}n=0;if(m>>>0<7){break Va}s=(S+R|0)-C|0;while(1){U=k<<2;m=U+p|0;G[m>>2]=q;G[t+U>>2]=q;G[m+28>>2]=q;G[m+24>>2]=q;G[m+20>>2]=q;G[m+16>>2]=q;G[m+12>>2]=q;G[m+8>>2]=q;k=k+8|0;if((s|0)!=(k|0)){continue}break}}s=e;k=l;break Sa;case 6:q=e+q|0;break Ta;case 2:q=e+q|0;break Sa;case 3:q=q-e|0;break Sa;case 7:q=q-e|0;break Ta;case 1:break Ua;default:break Sa}}n=1;q=e|F[(r<<1)+g>>1]<<12;break Sa}if(!((s|0)<=0|(s|0)>=(x|0))){G[p+(k<<2)>>2]=q;k=k+1|0}s=s+1|0}if((s|0)>=(x|0)){break Qa}}e=(r|0)!=(v|0);r=r+1|0;if(e){continue}break}}if((c|0)>=(k|0)){cb((t+(k<<2)|0)-4|0,0,(c-k<<2)+4|0)}}e=0;break P}Qi(g,G[o+8>>2],o+72|0,o+68|0,17,o- -64|0,j);a=G[o+64>>2];if((a|0)==c<<1){if(G[G[T+4>>2]+1048>>2]==22){n=G[o+72>>2];e=c<<1;p=ab(e);a=c>>31;Wa:{if(!c&(a|0)<=0|(a|0)<0){break Wa}s=0-c|0;q=e+n|0;l=e+p|0;if((c|0)!=1|a){r=c&-2;m=0;while(1){k=q-1|0;E[l-1|0]=H[k|0];E[l-2|0]=H[k+s|0];q=q-2|0;E[l-3|0]=H[q|0];l=l-4|0;E[l|0]=H[q+s|0];k=m;m=x+2|0;k=m>>>0<2?k+1|0:k;x=m;m=k;if((r|0)!=(x|0)|(a|0)!=(k|0)){continue}break}}if(!(c&1)){break Wa}a=q-1|0;E[l-1|0]=H[a|0];E[l-2|0]=H[a+s|0]}bb(n,p,e);Wa(p)}Af(G[o+72>>2],c);e=1;a=0;break P}if((a|0)==c<<2){if(G[G[T+4>>2]+1048>>2]==22){s=G[o+72>>2];m=0;e=c>>31;r=e;a=c;k=a<<2;p=ab(k);if(!!a&(e|0)>=0|(e|0)>0){q=M(a,-3);t=0-a|0;n=k+s|0;l=k+p|0;a=0-(a<<1)|0;while(1){n=n-1|0;E[l-1|0]=H[n|0];E[l-2|0]=H[n+t|0];E[l-3|0]=H[a+n|0];l=l-4|0;E[l|0]=H[n+q|0];e=m;m=x+1|0;e=m?e:e+1|0;x=m;m=e;if((c|0)!=(x|0)|(r|0)!=(e|0)){continue}break}}bb(s,p,k);Wa(p)}ke(G[o+72>>2],c);e=0;a=1;break P}if((a|0)==c<<3){if(G[G[T+4>>2]+1048>>2]==22){k=G[o+72>>2];m=0;p=c>>31;s=p;a=c;e=a<<3;l=ab(e);if(!!a&(p|0)>=0|(p|0)>0){n=M(a,-7);r=M(a,-6);q=M(a,-5);t=M(a,-3);v=0-a|0;ha=e+k|0;y=e+l|0;U=0-(a<<2)|0;a=0-(a<<1)|0;while(1){ha=ha-1|0;E[y-1|0]=H[ha|0];E[y-2|0]=H[v+ha|0];E[y-3|0]=H[a+ha|0];E[y-4|0]=H[t+ha|0];E[y-5|0]=H[U+ha|0];E[y-6|0]=H[q+ha|0];E[y-7|0]=H[r+ha|0];y=y-8|0;E[y|0]=H[n+ha|0];p=m;m=x+1|0;p=m?p:p+1|0;x=m;m=p;if((c|0)!=(x|0)|(s|0)!=(m|0)){continue}break}}bb(k,l,e);Wa(l)}Ge(G[o+72>>2],c);a=0;e=0;break P}if((a|0)==(c|0)){a=0;e=0;m=G[j>>2];l=1;break O}Ua(19778);Wa(G[o+72>>2]);break e}Ua(10657);Wa(G[o+72>>2]);Wa(g);break e}Ua(16244);Wa(G[o+72>>2]);break e}q=G[o+72>>2];n=a;m=g+2|0;v=G[o+8>>2]+g|0;a=H[g+1|0];t=H[g|0];e=8;Xa:{Ya:{Za:{while(1){if((c|0)<=(l|0)){break Za}k=e-3|0;if((e|0)<=2){while(1){a=H[m|0]|a<<8;e=k>>>0<4294967288;m=m+1|0;k=k+8|0;if(e){continue}break}}e=l+n|0;p=(c|0)>(e|0)?e:c;x=-1<>>k|0)-1|0;bb:{if((s|0)<0){if((l|0)>=(p|0)){break bb}cb(l+q|0,t,p-l|0);break $a}if((s|0)!=6){if((l|0)>=(p|0)){break _a}while(1){if(!e){while(1){k=k+8|0;e=H[m|0];m=m+1|0;if(!e){continue}break}}a=k-G[(e<<2)+103808>>2]|0;k=(a^-1)+k|0;e=1<>>0<4294967288;m=m+1|0;k=k+8|0;if(r){continue}break}}a=a<>>k;a=(a>>>1^0-(a&1))+t|0;E[l+q|0]=a;t=a&255;e=(-1<0){s=m;r=k;break cb}s=m+1|0;a=H[m|0]|a;r=8}db:{if(!k){e=0;m=s;break db}m=s+1|0;s=H[s|0];e=s&x;a=s>>>r|a}a=(0-(a&1)^a>>>1)+t|0;E[l+q|0]=a;t=a&255;l=l+1|0;if((p|0)!=(l|0)){continue}break}}l=p}a=e;e=k;if(m>>>0<=v>>>0){continue}break}k=1;e=16504;break Ya}k=0;e=11554;if(m>>>0>=v>>>0){break Xa}}Ua(e)}m=k;G[j>>2]=k;a=0;e=0;l=1;break O}m=G[j>>2];l=0}Wa(g);if(m){Wa(G[o+72>>2]);break a}f=f?f:o+24|0;eb:{fb:{switch(d-11|0){case 10:g=G[T+4>>2];if(K[g+1076>>2]==N(9999)){e=F[f>>1];f=G[o+76>>2];u=L[o+32>>3];w=L[o+40>>3];g=G[o+72>>2];if(a){Xk(g,c,w,u,B,e,h,i,f,j);a=2;break eb}Wk(g,c,w,u,B,e,h,i,f,j);a=2;break eb}if(a){u=L[o+32>>3];z=L[o+40>>3];a=G[o+72>>2];if(!(G[g+1048>>2]!=31|w!=32768)){Yk(a,c,z,u+-32768,B,G[o+60>>2],F[f>>1],h,i,G[o+76>>2],j);a=2;break eb}Yk(a,c,z,u,B,G[o+60>>2],F[f>>1],h,i,G[o+76>>2],j);a=2;if(G[G[T+4>>2]+1048>>2]!=41){break eb}e=G[j>>2];if((e|0)!=412&(e|0)!=-11){break eb}G[j>>2]=0;break eb}if(e){Op(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,F[o+60>>1],F[f>>1],h,i,G[o+76>>2],j);a=2;break eb}a=2;if(!l){break eb}Np(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,H[o+60|0],F[f>>1],h,i,G[o+76>>2],j);break eb;case 20:g=G[T+4>>2];if(K[g+1076>>2]==N(9999)){e=G[f>>2];f=G[o+76>>2];u=L[o+32>>3];w=L[o+40>>3];g=G[o+72>>2];if(a){Rp(g,c,w,u,B,e,h,i,f,j);a=4;break eb}Qp(g,c,w,u,B,e,h,i,f,j);a=4;break eb}if(a){u=L[o+32>>3];z=L[o+40>>3];a=G[o+72>>2];if(!(G[g+1048>>2]!=31|w!=32768)){Tp(a,c,z,u+-32768,B,G[o+60>>2],G[f>>2],h,i,G[o+76>>2],j);a=4;break eb}Tp(a,c,z,u,B,G[o+60>>2],G[f>>2],h,i,G[o+76>>2],j);a=4;break eb}if(e){g=G[o+72>>2];l=I[o+60>>1];s=G[f>>2];e=G[o+76>>2];k=0;w=L[o+40>>3];z=L[o+32>>3];a=w==1&z==0;gb:{hb:{if(!B){if(a){break hb}n=0;if((c|0)<=0){break gb}while(1){f=e+(n<<2)|0;ib:{jb:{u=+F[g+(n<<1)>>1]*w+z;if(u<-2147483648.49){G[j>>2]=-11;break jb}if(u>2147483647.49){G[j>>2]=-11;a=2147483647;break ib}if(!(O(u)<2147483648)){break jb}a=~~u;break ib}a=-2147483648}G[f>>2]=a;n=n+1|0;if((n|0)!=(c|0)){continue}break}break gb}if(!a){if((c|0)<=0){break gb}n=0;while(1){a=I[g+(n<<1)>>1];kb:{if((a|0)==(l|0)){G[i>>2]=1;if((B|0)==1){G[e+(n<<2)>>2]=s;break kb}E[h+n|0]=1;break kb}u=+(a<<16>>16)*w+z;if(u<-2147483648.49){G[j>>2]=-11;G[e+(n<<2)>>2]=-2147483648;break kb}if(u>2147483647.49){G[j>>2]=-11;G[e+(n<<2)>>2]=2147483647;break kb}f=e+(n<<2)|0;if(O(u)<2147483648){a=~~u}else{a=-2147483648}G[f>>2]=a}n=n+1|0;if((n|0)!=(c|0)){continue}break}break gb}if((c|0)<=0){break gb}if((B|0)!=1){n=0;if((c|0)!=1){f=c&-2;while(1){a=I[g+(n<<1)>>1];lb:{if((a|0)==(l|0)){G[i>>2]=1;E[h+n|0]=1;break lb}G[e+(n<<2)>>2]=a<<16>>16}a=n|1;j=I[g+(a<<1)>>1];mb:{if((j|0)!=(l|0)){G[e+(a<<2)>>2]=j<<16>>16;break mb}G[i>>2]=1;E[a+h|0]=1}n=n+2|0;k=k+2|0;if((f|0)!=(k|0)){continue}break}}if(!(c&1)){break gb}a=I[g+(n<<1)>>1];if((a|0)!=(l|0)){G[e+(n<<2)>>2]=a<<16>>16;break gb}G[i>>2]=1;E[h+n|0]=1;break gb}n=0;if((c|0)!=1){f=c&-2;while(1){j=e+(n<<2)|0;a=I[g+(n<<1)>>1];nb:{if((a|0)!=(l|0)){a=a<<16>>16;break nb}G[i>>2]=1;a=s}G[j>>2]=a;j=n|1;a=I[g+(j<<1)>>1];ob:{if((a|0)!=(l|0)){a=a<<16>>16;break ob}G[i>>2]=1;a=s}G[e+(j<<2)>>2]=a;n=n+2|0;k=k+2|0;if((f|0)!=(k|0)){continue}break}}if(!(c&1)){break gb}a=I[g+(n<<1)>>1];pb:{if((a|0)!=(l|0)){s=a<<16>>16;break pb}G[i>>2]=1}G[e+(n<<2)>>2]=s;break gb}if((c|0)<=0){break gb}n=0;if(c-1>>>0>=3){a=c&-4;f=0;while(1){G[e+(n<<2)>>2]=F[g+(n<<1)>>1];j=n|1;G[e+(j<<2)>>2]=F[g+(j<<1)>>1];j=n|2;G[e+(j<<2)>>2]=F[g+(j<<1)>>1];j=n|3;G[e+(j<<2)>>2]=F[g+(j<<1)>>1];n=n+4|0;f=f+4|0;if((a|0)!=(f|0)){continue}break}}a=c&3;if(!a){break gb}while(1){G[e+(n<<2)>>2]=F[g+(n<<1)>>1];n=n+1|0;k=k+1|0;if((a|0)!=(k|0)){continue}break}}a=4;break eb}a=4;if(!l){break eb}l=G[o+72>>2];k=H[o+60|0];e=G[f>>2];g=G[o+76>>2];w=L[o+40>>3];z=L[o+32>>3];f=w==1&z==0;qb:{rb:{if(!B){if(f){break rb}n=0;if((c|0)<=0){break qb}while(1){f=g+(n<<2)|0;sb:{tb:{u=+H[l+n|0]*w+z;if(u<-2147483648.49){G[j>>2]=-11;break tb}if(u>2147483647.49){G[j>>2]=-11;e=2147483647;break sb}if(!(O(u)<2147483648)){break tb}e=~~u;break sb}e=-2147483648}G[f>>2]=e;n=n+1|0;if((n|0)!=(c|0)){continue}break}break qb}if(!f){if((c|0)<=0){break qb}n=0;while(1){f=H[l+n|0];ub:{if((f|0)==(k|0)){G[i>>2]=1;if((B|0)==1){G[g+(n<<2)>>2]=e;break ub}E[h+n|0]=1;break ub}u=+(f>>>0)*w+z;if(u<-2147483648.49){G[j>>2]=-11;G[g+(n<<2)>>2]=-2147483648;break ub}if(u>2147483647.49){G[j>>2]=-11;G[g+(n<<2)>>2]=2147483647;break ub}p=g+(n<<2)|0;if(O(u)<2147483648){f=~~u}else{f=-2147483648}G[p>>2]=f}n=n+1|0;if((n|0)!=(c|0)){continue}break}break qb}if((c|0)<=0){break qb}if((B|0)!=1){n=0;if((c|0)!=1){j=c&-2;f=0;while(1){e=H[l+n|0];vb:{if((e|0)==(k|0)){G[i>>2]=1;E[h+n|0]=1;break vb}G[g+(n<<2)>>2]=e}e=n|1;m=H[e+l|0];wb:{if((m|0)!=(k|0)){G[g+(e<<2)>>2]=m;break wb}G[i>>2]=1;E[e+h|0]=1}n=n+2|0;f=f+2|0;if((j|0)!=(f|0)){continue}break}}if(!(c&1)){break qb}e=H[l+n|0];if((e|0)!=(k|0)){G[g+(n<<2)>>2]=e;break qb}G[i>>2]=1;E[h+n|0]=1;break qb}n=0;if((c|0)!=1){j=c&-2;m=0;while(1){p=g+(n<<2)|0;f=H[l+n|0];if((f|0)==(k|0)){G[i>>2]=1;f=e}G[p>>2]=f;p=n|1;f=H[p+l|0];if((k|0)==(f|0)){G[i>>2]=1;f=e}G[g+(p<<2)>>2]=f;n=n+2|0;m=m+2|0;if((j|0)!=(m|0)){continue}break}}if(!(c&1)){break qb}g=g+(n<<2)|0;f=H[l+n|0];if((f|0)==(k|0)){G[i>>2]=1}else{e=f}G[g>>2]=e;break qb}if((c|0)<=0){break qb}s=0;n=0;if(c-1>>>0>=3){e=c&-4;f=0;while(1){G[g+(n<<2)>>2]=H[l+n|0];j=n|1;G[g+(j<<2)>>2]=H[j+l|0];j=n|2;G[g+(j<<2)>>2]=H[j+l|0];j=n|3;G[g+(j<<2)>>2]=H[j+l|0];n=n+4|0;f=f+4|0;if((e|0)!=(f|0)){continue}break}}e=c&3;if(!e){break qb}while(1){G[g+(n<<2)>>2]=H[l+n|0];n=n+1|0;s=s+1|0;if((e|0)!=(s|0)){continue}break}}break eb;case 30:g=G[T+4>>2];if(K[g+1076>>2]==N(9999)){e=G[f>>2];f=G[o+76>>2];u=L[o+32>>3];w=L[o+40>>3];g=G[o+72>>2];if(a){al(g,c,w,u,B,e,h,i,f,j);a=4;break eb}$k(g,c,w,u,B,e,h,i,f,j);a=4;break eb}if(a){u=L[o+32>>3];z=L[o+40>>3];a=G[o+72>>2];if(!(G[g+1048>>2]!=31|w!=32768)){_k(a,c,z,u+-32768,B,G[o+60>>2],G[f>>2],h,i,G[o+76>>2],j);a=4;break eb}_k(a,c,z,u,B,G[o+60>>2],G[f>>2],h,i,G[o+76>>2],j);a=4;break eb}if(e){aq(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,F[o+60>>1],G[f>>2],h,i,G[o+76>>2],j);a=4;break eb}a=4;if(!l){break eb}bq(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,H[o+60|0],G[f>>2],h,i,G[o+76>>2],j);break eb;case 31:Q=K[f>>2];f=G[T+4>>2];if(K[f+1076>>2]==N(9999)){e=G[o+76>>2];u=L[o+32>>3];w=L[o+40>>3];f=G[o+72>>2];if(a){gl(f,c,w,u,B,Q,h,i,e);a=4;break eb}Wi(f,c,w,u,B,Q,h,i,e);a=4;break eb}g=G[f+1080>>2];if(g-1>>>0<=1){if(a){k=(G[f+1084>>2]+b|0)-1|0;e=G[o+72>>2];u=L[o+40>>3];z=L[o+32>>3];f=G[o+60>>2];a=G[o+76>>2];n=0;l=0;xb:{yb:{q=G[49098];if(q){break yb}q=lb(1e4,4);G[49098]=q;if(!q){break xb}w=1;while(1){p=(n<<2)+q|0;w=w*16807;ja=w/2147483647;zb:{if(O(ja)<2147483648){j=~~ja;break zb}j=-2147483648}w=+(j|0)*-2147483647+w;K[p>>2]=w/2147483647;n=n+1|0;if((n|0)!=1e4){continue}break}if(O(w)<2147483648){j=~~w}else{j=-2147483648}if((j|0)==1043618065){break yb}Ua(25400);break xb}k=(k-1|0)%1e4|0;ca=N(K[(k<<2)+q>>2]*N(500));Ab:{if(N(O(ca))>2];Cb:{if((j|0)!=(f|0)){if((g|0)==2){ca=N(0);if((j|0)==-2147483646){break Cb}}ca=N((+(j|0)-+K[(n<<2)+q>>2]+.5)*u+z);break Cb}G[i>>2]=1;ca=Q}K[a+m>>2]=ca;n=n+1|0;Db:{if((n|0)!=1e4){break Db}j=k+1|0;k=(j|0)==1e4?0:j;ca=N(K[(k<<2)+q>>2]*N(500));if(N(O(ca))>2];j=a+j|0;Eb:{if((g|0)==2){Q=N(0);if((f|0)==-2147483646){break Eb}}Q=N((+(f|0)-+K[(n<<2)+q>>2]+.5)*u+z)}K[j>>2]=Q;n=n+1|0;Fb:{if((n|0)!=1e4){break Fb}f=k+1|0;k=(f|0)==1e4?0:f;Q=N(K[(k<<2)+q>>2]*N(500));if(N(O(Q))>2];Gb:{if((m|0)==(f|0)){G[i>>2]=1;E[h+l|0]=1;break Gb}if(!((g|0)!=2|(m|0)!=-2147483646)){G[a+j>>2]=0;break Gb}K[a+j>>2]=(+(m|0)-+K[G[49098]+(n<<2)>>2]+.5)*u+z}n=n+1|0;Hb:{if((n|0)!=1e4){break Hb}j=k+1|0;k=(j|0)==1e4?0:j;Q=N(K[G[49098]+(k<<2)>>2]*N(500));if(N(O(Q))>2]+b|0)-1|0;a=G[o+72>>2];u=L[o+40>>3];z=L[o+32>>3];f=I[o+60>>1];e=G[o+76>>2];q=0;k=0;Ib:{Jb:{m=G[49098];if(m){break Jb}m=lb(1e4,4);G[49098]=m;if(!m){break Ib}w=1;while(1){p=(q<<2)+m|0;w=w*16807;ja=w/2147483647;Kb:{if(O(ja)<2147483648){g=~~ja;break Kb}g=-2147483648}w=+(g|0)*-2147483647+w;K[p>>2]=w/2147483647;q=q+1|0;if((q|0)!=1e4){continue}break}if(O(w)<2147483648){g=~~w}else{g=-2147483648}if((g|0)==1043618065){break Jb}Ua(25400);break Ib}s=(j-1|0)%1e4|0;ca=N(K[(s<<2)+m>>2]*N(500));Lb:{if(N(O(ca))>1];Nb:{if((j|0)!=(f|0)){ca=N((+(j<<16>>16)-+K[(q<<2)+m>>2]+.5)*u+z);break Nb}G[i>>2]=1;ca=Q}K[g>>2]=ca;q=q+1|0;Ob:{if((q|0)!=1e4){break Ob}g=s+1|0;s=(g|0)==1e4?0:g;ca=N(K[(s<<2)+m>>2]*N(500));if(N(O(ca))>2]=(+F[a+(k<<1)>>1]-+K[(q<<2)+m>>2]+.5)*u+z;q=q+1|0;Pb:{if((q|0)!=1e4){break Pb}f=s+1|0;s=(f|0)==1e4?0:f;Q=N(K[(s<<2)+m>>2]*N(500));if(N(O(Q))>1];Qb:{if((g|0)==(f|0)){G[i>>2]=1;E[h+k|0]=1;break Qb}K[e+(k<<2)>>2]=(+(g<<16>>16)-+K[G[49098]+(q<<2)>>2]+.5)*u+z}q=q+1|0;Rb:{if((q|0)!=1e4){break Rb}g=s+1|0;s=(g|0)==1e4?0:g;Q=N(K[G[49098]+(s<<2)>>2]*N(500));if(N(O(Q))>2]+b|0)-1|0;e=G[o+72>>2];u=L[o+40>>3];z=L[o+32>>3];g=H[o+60|0];f=G[o+76>>2];l=0;q=0;Sb:{Tb:{k=G[49098];if(k){break Tb}k=lb(1e4,4);G[49098]=k;if(!k){break Sb}w=1;while(1){p=(l<<2)+k|0;w=w*16807;ja=w/2147483647;Ub:{if(O(ja)<2147483648){j=~~ja;break Ub}j=-2147483648}w=+(j|0)*-2147483647+w;K[p>>2]=w/2147483647;l=l+1|0;if((l|0)!=1e4){continue}break}if(O(w)<2147483648){j=~~w}else{j=-2147483648}if((j|0)==1043618065){break Tb}Ua(25400);break Sb}m=(m-1|0)%1e4|0;ca=N(K[(m<<2)+k>>2]*N(500));Vb:{if(N(O(ca))>>0)-+K[(l<<2)+k>>2]+.5)*u+z);break Xb}G[i>>2]=1;ca=Q}K[j>>2]=ca;l=l+1|0;Yb:{if((l|0)!=1e4){break Yb}j=m+1|0;m=(j|0)==1e4?0:j;ca=N(K[(m<<2)+k>>2]*N(500));if(N(O(ca))>2]=(+H[e+q|0]-+K[(l<<2)+k>>2]+.5)*u+z;l=l+1|0;Zb:{if((l|0)!=1e4){break Zb}g=m+1|0;m=(g|0)==1e4?0:g;Q=N(K[(m<<2)+k>>2]*N(500));if(N(O(Q))>2]=1;E[h+q|0]=1;break _b}K[f+(q<<2)>>2]=(+(j>>>0)-+K[G[49098]+(l<<2)>>2]+.5)*u+z}l=l+1|0;$b:{if((l|0)!=1e4){break $b}j=m+1|0;m=(j|0)==1e4?0:j;Q=N(K[G[49098]+(m<<2)>>2]*N(500));if(N(O(Q))>3];z=L[o+40>>3];a=G[o+72>>2];if(!(G[f+1048>>2]!=31|w!=32768)){fl(a,c,z,u+-32768,B,G[o+60>>2],Q,h,i,G[o+76>>2]);a=4;break eb}fl(a,c,z,u,B,G[o+60>>2],Q,h,i,G[o+76>>2]);a=4;break eb}if(e){jq(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,F[o+60>>1],Q,h,i,G[o+76>>2]);a=4;break eb}a=4;if(!l){break eb}iq(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,H[o+60|0],Q,h,i,G[o+76>>2]);break eb;case 71:u=L[f>>3];f=G[T+4>>2];if(K[f+1076>>2]==N(9999)){e=G[o+76>>2];w=L[o+32>>3];z=L[o+40>>3];f=G[o+72>>2];if(a){bl(f,c,z,w,B,u,h,i,e);a=8;break eb}dl(f,c,z,w,B,u,h,i,e);a=8;break eb}g=G[f+1080>>2];if(g-1>>>0<=1){if(a){m=(G[f+1084>>2]+b|0)-1|0;e=G[o+72>>2];z=L[o+40>>3];ja=L[o+32>>3];f=G[o+60>>2];a=G[o+76>>2];l=0;q=0;ac:{bc:{k=G[49098];if(k){break bc}k=lb(1e4,4);G[49098]=k;if(!k){break ac}w=1;while(1){p=(l<<2)+k|0;w=w*16807;Aa=w/2147483647;cc:{if(O(Aa)<2147483648){j=~~Aa;break cc}j=-2147483648}w=+(j|0)*-2147483647+w;K[p>>2]=w/2147483647;l=l+1|0;if((l|0)!=1e4){continue}break}if(O(w)<2147483648){j=~~w}else{j=-2147483648}if((j|0)==1043618065){break bc}Ua(25400);break ac}m=(m-1|0)%1e4|0;Q=N(K[(m<<2)+k>>2]*N(500));dc:{if(N(O(Q))>2];fc:{if((j|0)!=(f|0)){if((g|0)==2){w=0;if((j|0)==-2147483646){break fc}}w=(+(j|0)-+K[(l<<2)+k>>2]+.5)*z+ja;break fc}G[i>>2]=1;w=u}L[p>>3]=w;l=l+1|0;gc:{if((l|0)!=1e4){break gc}j=m+1|0;m=(j|0)==1e4?0:j;Q=N(K[(m<<2)+k>>2]*N(500));if(N(O(Q))>2];j=a+(q<<3)|0;hc:{if((g|0)==2){u=0;if((f|0)==-2147483646){break hc}}u=(+(f|0)-+K[(l<<2)+k>>2]+.5)*z+ja}L[j>>3]=u;l=l+1|0;ic:{if((l|0)!=1e4){break ic}f=m+1|0;m=(f|0)==1e4?0:f;Q=N(K[(m<<2)+k>>2]*N(500));if(N(O(Q))>2];jc:{if((j|0)==(f|0)){G[i>>2]=1;E[h+q|0]=1;break jc}if(!((g|0)!=2|(j|0)!=-2147483646)){j=a+(q<<3)|0;G[j>>2]=0;G[j+4>>2]=0;break jc}L[a+(q<<3)>>3]=(+(j|0)-+K[G[49098]+(l<<2)>>2]+.5)*z+ja}l=l+1|0;kc:{if((l|0)!=1e4){break kc}j=m+1|0;m=(j|0)==1e4?0:j;Q=N(K[G[49098]+(m<<2)>>2]*N(500));if(N(O(Q))>2]+b|0)-1|0;a=G[o+72>>2];z=L[o+40>>3];ja=L[o+32>>3];f=I[o+60>>1];e=G[o+76>>2];q=0;k=0;lc:{mc:{m=G[49098];if(m){break mc}m=lb(1e4,4);G[49098]=m;if(!m){break lc}w=1;while(1){p=(q<<2)+m|0;w=w*16807;Aa=w/2147483647;nc:{if(O(Aa)<2147483648){g=~~Aa;break nc}g=-2147483648}w=+(g|0)*-2147483647+w;K[p>>2]=w/2147483647;q=q+1|0;if((q|0)!=1e4){continue}break}if(O(w)<2147483648){g=~~w}else{g=-2147483648}if((g|0)==1043618065){break mc}Ua(25400);break lc}s=(j-1|0)%1e4|0;Q=N(K[(s<<2)+m>>2]*N(500));oc:{if(N(O(Q))>1];qc:{if((j|0)!=(f|0)){w=(+(j<<16>>16)-+K[(q<<2)+m>>2]+.5)*z+ja;break qc}G[i>>2]=1;w=u}L[g>>3]=w;q=q+1|0;rc:{if((q|0)!=1e4){break rc}g=s+1|0;s=(g|0)==1e4?0:g;Q=N(K[(s<<2)+m>>2]*N(500));if(N(O(Q))>3]=(+F[a+(k<<1)>>1]-+K[(q<<2)+m>>2]+.5)*z+ja;q=q+1|0;sc:{if((q|0)!=1e4){break sc}f=s+1|0;s=(f|0)==1e4?0:f;Q=N(K[(s<<2)+m>>2]*N(500));if(N(O(Q))>1];tc:{if((g|0)==(f|0)){G[i>>2]=1;E[h+k|0]=1;break tc}L[e+(k<<3)>>3]=(+(g<<16>>16)-+K[G[49098]+(q<<2)>>2]+.5)*z+ja}q=q+1|0;uc:{if((q|0)!=1e4){break uc}g=s+1|0;s=(g|0)==1e4?0:g;Q=N(K[G[49098]+(s<<2)>>2]*N(500));if(N(O(Q))>2]+b|0)-1|0;e=G[o+72>>2];z=L[o+40>>3];ja=L[o+32>>3];g=H[o+60|0];f=G[o+76>>2];l=0;q=0;vc:{wc:{k=G[49098];if(k){break wc}k=lb(1e4,4);G[49098]=k;if(!k){break vc}w=1;while(1){p=(l<<2)+k|0;w=w*16807;Aa=w/2147483647;xc:{if(O(Aa)<2147483648){j=~~Aa;break xc}j=-2147483648}w=+(j|0)*-2147483647+w;K[p>>2]=w/2147483647;l=l+1|0;if((l|0)!=1e4){continue}break}if(O(w)<2147483648){j=~~w}else{j=-2147483648}if((j|0)==1043618065){break wc}Ua(25400);break vc}m=(m-1|0)%1e4|0;Q=N(K[(m<<2)+k>>2]*N(500));yc:{if(N(O(Q))>>0)-+K[(l<<2)+k>>2]+.5)*z+ja;break Ac}G[i>>2]=1;w=u}L[j>>3]=w;l=l+1|0;Bc:{if((l|0)!=1e4){break Bc}j=m+1|0;m=(j|0)==1e4?0:j;Q=N(K[(m<<2)+k>>2]*N(500));if(N(O(Q))>3]=(+H[e+q|0]-+K[(l<<2)+k>>2]+.5)*z+ja;l=l+1|0;Cc:{if((l|0)!=1e4){break Cc}g=m+1|0;m=(g|0)==1e4?0:g;Q=N(K[(m<<2)+k>>2]*N(500));if(N(O(Q))>2]=1;E[h+q|0]=1;break Dc}L[f+(q<<3)>>3]=(+(j>>>0)-+K[G[49098]+(l<<2)>>2]+.5)*z+ja}l=l+1|0;Ec:{if((l|0)!=1e4){break Ec}j=m+1|0;m=(j|0)==1e4?0:j;Q=N(K[G[49098]+(m<<2)>>2]*N(500));if(N(O(Q))>3];ja=L[o+40>>3];a=G[o+72>>2];if(!(G[f+1048>>2]!=31|w!=32768)){cl(a,c,ja,z+-32768,B,G[o+60>>2],u,h,i,G[o+76>>2]);a=8;break eb}cl(a,c,ja,z,B,G[o+60>>2],u,h,i,G[o+76>>2]);a=8;break eb}if(e){fq(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,F[o+60>>1],u,h,i,G[o+76>>2]);a=8;break eb}a=8;if(!l){break eb}eq(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,H[o+60|0],u,h,i,G[o+76>>2]);break eb;case 0:if(a){up(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,G[o+60>>2],H[f|0],h,i,G[o+76>>2],j);a=1;break eb}if(e){Tk(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,F[o+60>>1],H[f|0],h,i,G[o+76>>2],j);a=1;break eb}a=1;if(!l){break eb}vp(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,H[o+60|0],H[f|0],h,i,G[o+76>>2],j);break eb;case 1:if(a){Do(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,G[o+60>>2],E[f|0],h,i,G[o+76>>2],j);a=1;break eb}if(e){Eo(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,F[o+60>>1],E[f|0],h,i,G[o+76>>2],j);a=1;break eb}a=1;if(!l){break eb}Co(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,H[o+60|0],E[f|0],h,i,G[o+76>>2],j);break eb;case 9:g=G[T+4>>2];if(K[g+1076>>2]==N(9999)){e=I[f>>1];f=G[o+76>>2];u=L[o+32>>3];w=L[o+40>>3];g=G[o+72>>2];if(a){Ip(g,c,w,u,B,e,h,i,f,j);a=2;break eb}Hp(g,c,w,u,B,e,h,i,f,j);a=2;break eb}if(a){u=L[o+32>>3];z=L[o+40>>3];a=G[o+72>>2];if(!(G[g+1048>>2]!=31|w!=32768)){Vk(a,c,z,u+-32768,B,G[o+60>>2],I[f>>1],h,i,G[o+76>>2],j);a=2;break eb}Vk(a,c,z,u,B,G[o+60>>2],I[f>>1],h,i,G[o+76>>2],j);a=2;break eb}if(e){Gp(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,F[o+60>>1],I[f>>1],h,i,G[o+76>>2],j);a=2;break eb}a=2;if(!l){break eb}Jp(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,H[o+60|0],I[f>>1],h,i,G[o+76>>2],j);break eb;case 19:g=G[T+4>>2];if(K[g+1076>>2]==N(9999)){g=G[f>>2];e=G[o+76>>2];u=L[o+32>>3];w=L[o+40>>3];f=G[o+72>>2];if(a){k=0;m=0;Fc:{Gc:{if(!B){if(w==1&u==0){break Gc}if((c|0)<=0){break Fc}while(1){Hc:{Ic:{g=m<<2;z=+K[g+f>>2]*w+u;if(z<-.49){G[j>>2]=-11;break Ic}if(z>4294967295.49){G[j>>2]=-11;a=-1;break Hc}if(!(z<4294967296&z>=0)){break Ic}a=~~z>>>0;break Hc}a=0}G[e+g>>2]=a;m=m+1|0;if((m|0)!=(c|0)){continue}break}break Fc}m=f+2|0;Jc:{Kc:{if(!(w==1&u==0)){if((c|0)<=0){break Fc}if(!(u<4294967296&u>=0)){break Kc}a=~~u>>>0;break Jc}if((c|0)<=0){break Fc}while(1){Lc:{Mc:{Nc:{Oc:{a=I[m>>1]&32640;switch(((a|0)==32640?1:!a<<1)|0){case 0:break Mc;case 1:break Oc;default:break Nc}}G[i>>2]=1;if((B|0)==1){G[e+(k<<2)>>2]=g;break Lc}E[h+k|0]=1;break Lc}G[e+(k<<2)>>2]=0;break Lc}a=k<<2;Q=K[a+f>>2];u=+Q;if(u<-.49){G[j>>2]=-11;G[a+e>>2]=0;break Lc}if(u>4294967295.49){G[j>>2]=-11;G[a+e>>2]=-1;break Lc}p=a+e|0;if(Q=N(0)){a=~~Q>>>0}else{a=0}G[p>>2]=a}m=m+4|0;k=k+1|0;if((k|0)!=(c|0)){continue}break}break Fc}a=0}while(1){Pc:{Qc:{Rc:{Sc:{l=I[m>>1]&32640;switch(((l|0)==32640?1:!l<<1)|0){case 0:break Qc;case 1:break Sc;default:break Rc}}G[i>>2]=1;if((B|0)==1){G[e+(k<<2)>>2]=g;break Pc}E[h+k|0]=1;break Pc}if(u<-.49){G[j>>2]=-11;G[e+(k<<2)>>2]=0;break Pc}if(u>4294967295.49){G[j>>2]=-11;G[e+(k<<2)>>2]=-1;break Pc}G[e+(k<<2)>>2]=a;break Pc}l=k<<2;z=+K[l+f>>2]*w+u;if(z<-.49){G[j>>2]=-11;G[e+l>>2]=0;break Pc}if(z>4294967295.49){G[j>>2]=-11;G[e+(k<<2)>>2]=-1;break Pc}l=e+(k<<2)|0;if(z<4294967296&z>=0){p=~~z>>>0}else{p=0}G[l>>2]=p}m=m+4|0;k=k+1|0;if((k|0)!=(c|0)){continue}break}break Fc}if((c|0)<=0){break Fc}while(1){Tc:{Uc:{g=m<<2;Q=K[g+f>>2];u=+Q;if(u<-.49){G[j>>2]=-11;break Uc}if(u>4294967295.49){G[j>>2]=-11;a=-1;break Tc}if(!(Q=N(0))){break Uc}a=~~Q>>>0;break Tc}a=0}G[e+g>>2]=a;m=m+1|0;if((m|0)!=(c|0)){continue}break}}a=4;break eb}k=0;m=0;Vc:{Wc:{if(!B){if(w==1&u==0){break Wc}if((c|0)<=0){break Vc}while(1){g=e+(m<<2)|0;Xc:{Yc:{z=L[f+(m<<3)>>3]*w+u;if(z<-.49){G[j>>2]=-11;break Yc}if(z>4294967295.49){G[j>>2]=-11;a=-1;break Xc}if(!(z<4294967296&z>=0)){break Yc}a=~~z>>>0;break Xc}a=0}G[g>>2]=a;m=m+1|0;if((m|0)!=(c|0)){continue}break}break Vc}m=f+6|0;Zc:{_c:{if(!(w==1&u==0)){if((c|0)<=0){break Vc}if(!(u<4294967296&u>=0)){break _c}a=~~u>>>0;break Zc}if((c|0)<=0){break Vc}while(1){$c:{ad:{bd:{cd:{a=I[m>>1]&32752;switch(((a|0)==32752?1:!a<<1)|0){case 0:break ad;case 1:break cd;default:break bd}}G[i>>2]=1;if((B|0)==1){G[e+(k<<2)>>2]=g;break $c}E[h+k|0]=1;break $c}G[e+(k<<2)>>2]=0;break $c}u=L[f+(k<<3)>>3];if(u<-.49){G[j>>2]=-11;G[e+(k<<2)>>2]=0;break $c}if(u>4294967295.49){G[j>>2]=-11;G[e+(k<<2)>>2]=-1;break $c}p=e+(k<<2)|0;if(u<4294967296&u>=0){a=~~u>>>0}else{a=0}G[p>>2]=a}m=m+8|0;k=k+1|0;if((k|0)!=(c|0)){continue}break}break Vc}a=0}while(1){dd:{ed:{fd:{gd:{l=I[m>>1]&32752;switch(((l|0)==32752?1:!l<<1)|0){case 0:break ed;case 1:break gd;default:break fd}}G[i>>2]=1;if((B|0)==1){G[e+(k<<2)>>2]=g;break dd}E[h+k|0]=1;break dd}if(u<-.49){G[j>>2]=-11;G[e+(k<<2)>>2]=0;break dd}if(u>4294967295.49){G[j>>2]=-11;G[e+(k<<2)>>2]=-1;break dd}G[e+(k<<2)>>2]=a;break dd}z=L[f+(k<<3)>>3]*w+u;if(z<-.49){G[j>>2]=-11;G[e+(k<<2)>>2]=0;break dd}if(z>4294967295.49){G[j>>2]=-11;G[e+(k<<2)>>2]=-1;break dd}l=e+(k<<2)|0;if(z<4294967296&z>=0){p=~~z>>>0}else{p=0}G[l>>2]=p}m=m+8|0;k=k+1|0;if((k|0)!=(c|0)){continue}break}break Vc}if((c|0)<=0){break Vc}while(1){g=e+(m<<2)|0;hd:{id:{u=L[f+(m<<3)>>3];if(u<-.49){G[j>>2]=-11;break id}if(u>4294967295.49){G[j>>2]=-11;a=-1;break hd}if(!(u<4294967296&u>=0)){break id}a=~~u>>>0;break hd}a=0}G[g>>2]=a;m=m+1|0;if((m|0)!=(c|0)){continue}break}}a=4;break eb}if(a){u=L[o+32>>3];z=L[o+40>>3];a=G[o+72>>2];if(!(G[g+1048>>2]!=31|w!=32768)){yp(a,c,z,u+-32768,B,G[o+60>>2],G[f>>2],h,i,G[o+76>>2],j);a=4;break eb}yp(a,c,z,u,B,G[o+60>>2],G[f>>2],h,i,G[o+76>>2],j);a=4;break eb}if(e){g=G[o+72>>2];l=I[o+60>>1];a=G[f>>2];f=G[o+76>>2];w=L[o+40>>3];z=L[o+32>>3];e=w==1&z==0;jd:{kd:{if(!B){if(e){break kd}n=0;if((c|0)<=0){break jd}while(1){e=f+(n<<2)|0;ld:{md:{u=+F[g+(n<<1)>>1]*w+z;if(u<-.49){G[j>>2]=-11;break md}if(u>4294967295.49){G[j>>2]=-11;a=-1;break ld}if(!(u<4294967296&u>=0)){break md}a=~~u>>>0;break ld}a=0}G[e>>2]=a;n=n+1|0;if((n|0)!=(c|0)){continue}break}break jd}if(!e){if((c|0)<=0){break jd}n=0;while(1){e=I[g+(n<<1)>>1];nd:{if((e|0)==(l|0)){G[i>>2]=1;if((B|0)==1){G[f+(n<<2)>>2]=a;break nd}E[h+n|0]=1;break nd}u=+(e<<16>>16)*w+z;if(u<-.49){G[j>>2]=-11;G[f+(n<<2)>>2]=0;break nd}if(u>4294967295.49){G[j>>2]=-11;G[f+(n<<2)>>2]=-1;break nd}k=f+(n<<2)|0;if(u<4294967296&u>=0){e=~~u>>>0}else{e=0}G[k>>2]=e}n=n+1|0;if((n|0)!=(c|0)){continue}break}break jd}if((c|0)<=0){break jd}if((B|0)!=1){n=0;while(1){a=I[g+(n<<1)>>1];od:{if((a|0)==(l|0)){G[i>>2]=1;E[h+n|0]=1;break od}a=a<<16>>16;if((a|0)<0){G[j>>2]=-11;G[f+(n<<2)>>2]=0;break od}G[f+(n<<2)>>2]=a}n=n+1|0;if((n|0)!=(c|0)){continue}break}break jd}n=0;if((c|0)!=1){k=c&-2;s=0;while(1){e=I[g+(n<<1)>>1];pd:{if((e|0)!=(l|0)){e=e<<16>>16;if((e|0)>=0){break pd}G[j>>2]=-11;e=0;break pd}G[i>>2]=1;e=a}G[f+(n<<2)>>2]=e;m=n|1;e=I[g+(m<<1)>>1];qd:{if((e|0)!=(l|0)){e=e<<16>>16;if((e|0)>=0){break qd}G[j>>2]=-11;e=0;break qd}G[i>>2]=1;e=a}G[f+(m<<2)>>2]=e;n=n+2|0;s=s+2|0;if((k|0)!=(s|0)){continue}break}}if(!(c&1)){break jd}e=I[g+(n<<1)>>1];rd:{if((e|0)!=(l|0)){a=e<<16>>16;if((a|0)>=0){break rd}G[j>>2]=-11;a=0;break rd}G[i>>2]=1}G[f+(n<<2)>>2]=a;break jd}if((c|0)<=0){break jd}n=0;if((c|0)!=1){l=c&-2;e=0;while(1){k=f+(n<<2)|0;a=F[g+(n<<1)>>1];sd:{if((a|0)<0){G[j>>2]=-11;a=0;break sd}a=a&65535}G[k>>2]=a;k=n|1;a=F[g+(k<<1)>>1];td:{if((a|0)>=0){a=a&65535;break td}G[j>>2]=-11;a=0}G[f+(k<<2)>>2]=a;n=n+2|0;e=e+2|0;if((l|0)!=(e|0)){continue}break}}if(!(c&1)){break jd}e=0;a=F[g+(n<<1)>>1];ud:{if((a|0)>=0){e=a&65535;break ud}G[j>>2]=-11}G[f+(n<<2)>>2]=e}a=4;break eb}a=4;if(!l){break eb}l=G[o+72>>2];k=H[o+60|0];e=G[f>>2];g=G[o+76>>2];w=L[o+40>>3];z=L[o+32>>3];f=w==1&z==0;vd:{wd:{if(!B){if(f){break wd}n=0;if((c|0)<=0){break vd}while(1){f=g+(n<<2)|0;xd:{yd:{u=+H[l+n|0]*w+z;if(u<-.49){G[j>>2]=-11;break yd}if(u>4294967295.49){G[j>>2]=-11;e=-1;break xd}if(!(u<4294967296&u>=0)){break yd}e=~~u>>>0;break xd}e=0}G[f>>2]=e;n=n+1|0;if((n|0)!=(c|0)){continue}break}break vd}if(!f){if((c|0)<=0){break vd}n=0;while(1){f=H[l+n|0];zd:{if((f|0)==(k|0)){G[i>>2]=1;if((B|0)==1){G[g+(n<<2)>>2]=e;break zd}E[h+n|0]=1;break zd}u=+(f>>>0)*w+z;if(u<-.49){G[j>>2]=-11;G[g+(n<<2)>>2]=0;break zd}if(u>4294967295.49){G[j>>2]=-11;G[g+(n<<2)>>2]=-1;break zd}p=g+(n<<2)|0;if(u<4294967296&u>=0){f=~~u>>>0}else{f=0}G[p>>2]=f}n=n+1|0;if((n|0)!=(c|0)){continue}break}break vd}if((c|0)<=0){break vd}if((B|0)!=1){n=0;if((c|0)!=1){j=c&-2;f=0;while(1){e=H[l+n|0];Ad:{if((e|0)==(k|0)){G[i>>2]=1;E[h+n|0]=1;break Ad}G[g+(n<<2)>>2]=e}e=n|1;m=H[e+l|0];Bd:{if((m|0)!=(k|0)){G[g+(e<<2)>>2]=m;break Bd}G[i>>2]=1;E[e+h|0]=1}n=n+2|0;f=f+2|0;if((j|0)!=(f|0)){continue}break}}if(!(c&1)){break vd}e=H[l+n|0];if((e|0)!=(k|0)){G[g+(n<<2)>>2]=e;break vd}G[i>>2]=1;E[h+n|0]=1;break vd}n=0;if((c|0)!=1){j=c&-2;m=0;while(1){p=g+(n<<2)|0;f=H[l+n|0];if((f|0)==(k|0)){G[i>>2]=1;f=e}G[p>>2]=f;p=n|1;f=H[p+l|0];if((k|0)==(f|0)){G[i>>2]=1;f=e}G[g+(p<<2)>>2]=f;n=n+2|0;m=m+2|0;if((j|0)!=(m|0)){continue}break}}if(!(c&1)){break vd}g=g+(n<<2)|0;f=H[l+n|0];if((f|0)==(k|0)){G[i>>2]=1}else{e=f}G[g>>2]=e;break vd}if((c|0)<=0){break vd}s=0;n=0;if(c-1>>>0>=3){e=c&-4;f=0;while(1){G[g+(n<<2)>>2]=H[l+n|0];j=n|1;G[g+(j<<2)>>2]=H[j+l|0];j=n|2;G[g+(j<<2)>>2]=H[j+l|0];j=n|3;G[g+(j<<2)>>2]=H[j+l|0];n=n+4|0;f=f+4|0;if((e|0)!=(f|0)){continue}break}}e=c&3;if(!e){break vd}while(1){G[g+(n<<2)>>2]=H[l+n|0];n=n+1|0;s=s+1|0;if((e|0)!=(s|0)){continue}break}}break eb;case 29:g=G[T+4>>2];if(K[g+1076>>2]==N(9999)){e=G[f>>2];f=G[o+76>>2];u=L[o+32>>3];w=L[o+40>>3];g=G[o+72>>2];if(a){Cp(g,c,w,u,B,e,h,i,f,j);a=4;break eb}Bp(g,c,w,u,B,e,h,i,f,j);a=4;break eb}if(a){u=L[o+32>>3];z=L[o+40>>3];a=G[o+72>>2];if(!(G[g+1048>>2]!=31|w!=32768)){Uk(a,c,z,u+-32768,B,G[o+60>>2],G[f>>2],h,i,G[o+76>>2],j);a=4;break eb}Uk(a,c,z,u,B,G[o+60>>2],G[f>>2],h,i,G[o+76>>2],j);a=4;break eb}if(e){Dp(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,F[o+60>>1],G[f>>2],h,i,G[o+76>>2],j);a=4;break eb}a=4;if(!l){break eb}Ep(G[o+72>>2],c,L[o+40>>3],L[o+32>>3],B,H[o+60|0],G[f>>2],h,i,G[o+76>>2],j);break eb;default:break fb}}G[j>>2]=410;a=0}Wa(G[o+72>>2]);m=G[T+4>>2];if(!G[m+1228>>2]|G[m+1112>>2]==G[m+1052>>2]&G[m+1056>>2]==1){break a}f=M(a,c);e=ma<<2;if(!((f|0)==G[e+G[m+1232>>2]>>2]&G[e+G[m+1236>>2]>>2]==(d|0))){a=G[e+G[m+1240>>2]>>2];if(a){Wa(a);m=G[T+4>>2]}a=G[m+1244>>2];e=ma<<2;g=G[a+e>>2];if(g){Wa(g);a=G[G[T+4>>2]+1244>>2]}G[a+e>>2]=0;a=G[T+4>>2];G[e+G[a+1228>>2]>>2]=0;G[e+G[a+1232>>2]>>2]=0;G[e+G[a+1236>>2]>>2]=0;g=ab(f);G[e+G[a+1240>>2]>>2]=g;m=G[T+4>>2];if(!G[e+G[m+1240>>2]>>2]){break a}if((B|0)==2){a=ab(c);e=ma<<2;G[e+G[m+1244>>2]>>2]=a;m=G[T+4>>2];if(!G[e+G[m+1244>>2]>>2]){break a}}a=ma<<2;G[a+G[m+1232>>2]>>2]=f;G[a+G[m+1236>>2]>>2]=d}a=ma<<2;bb(G[a+G[m+1240>>2]>>2],G[o+76>>2],f);if((B|0)==2){bb(G[G[G[T+4>>2]+1244>>2]+(ma<<2)>>2],h,c)}c=G[T+4>>2];G[a+G[c+1228>>2]>>2]=b;G[a+G[c+1248>>2]>>2]=G[i>>2];break a}Wa(g)}G[j>>2]=113;break a}G[j>>2]=414;break a}G[j>>2]=415}Fa=o+80|0}function Eq(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,K=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,$a=0,ab=0,db=0,eb=0,fb=0,gb=0,ib=0,jb=0,kb=0,lb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0,Eb=0,Fb=0,Gb=0,Hb=0,Ib=0,Jb=0,Kb=0,Lb=0,Mb=0,Nb=0,Ob=0,Pb=0,Qb=0,Rb=0,Sb=0,Tb=0,Vb=0,Wb=0,Xb=0,Yb=0,Zb=0,_b=0,$b=0,ac=0,bc=0,cc=0,dc=0,ec=0,fc=0,gc=0,hc=0,ic=0,jc=0,kc=0,lc=0,mc=0,nc=0,oc=0,pc=0,qc=0,rc=0,sc=0,tc=0,uc=0,vc=0,wc=0,xc=0,yc=0,zc=0,Ac=0,Bc=0,Cc=0,Dc=0,Ec=0,Fc=0,Gc=0,Hc=0,Ic=0,Jc=0,Kc=0,Lc=0,Mc=0,Nc=0,Oc=0,Pc=0,Qc=0,Rc=0;b=G[a+32>>2];Ha=b+88|0;while(1){a=G[b+8>>2];a:{b:{c:{d:{while(1){e:{switch(a-1|0){case 1:break d;case 0:break e;default:continue}}break}a=0;c=G[b>>2];e=G[b+80>>2];f:{if(!G[c+20>>2]|(e|0)>=G[b+76>>2]){break f}g=G[c+16>>2];while(1){E[g|0]=H[G[b+44>>2]+e|0];e=G[b+80>>2]+1|0;G[b+80>>2]=e;a=G[b>>2];c=G[a+24>>2]+1|0;G[a+24>>2]=c;g=G[a+16>>2]+1|0;G[a+16>>2]=g;d=G[a+20>>2]-1|0;G[a+20>>2]=d;if(!c){G[a+28>>2]=G[a+28>>2]+1}a=1;if(!d){break f}if(G[b+76>>2]>(e|0)){continue}break}}Da=a|Da;if(G[b+76>>2]>(e|0)){break b}a=G[b+4>>2];if(!(G[b+12>>2]|(a|0)!=4)&(G[b+56>>2]<=0|J[b+52>>2]>255)){break b}G[b+608>>2]=-1;G[b+76>>2]=0;G[b+80>>2]=0;G[b+68>>2]=0;cb(Ha,0,256);G[b+8>>2]=2;G[b+620>>2]=G[b+620>>2]+1;if((a|0)!=3){break c}if(G[b+12>>2]){break d}if(G[b+56>>2]<=0|J[b+52>>2]>255){break b}}a=G[b+4>>2]}g=G[b+72>>2];n=G[b+68>>2];g:{if((a|0)!=2){i=0;if((g|0)<=(n|0)){break g}a=G[b>>2];if(!G[a+4>>2]|!G[b+12>>2]){break g}while(1){e=G[b+56>>2];h:{i:{c=G[b+52>>2];a=H[G[a>>2]];j:{if((c|0)!=(a|0)){if((e|0)!=1){break j}e=G[b+608>>2];G[b+608>>2]=e<<8^G[((c&255^e>>>24)<<2)+191040>>2];E[(b+c|0)+88|0]=1;E[G[b+36>>2]+G[b+68>>2]|0]=c;G[b+52>>2]=a;G[b+68>>2]=G[b+68>>2]+1;break h}if((e|0)!=255){break i}}if(c>>>0<=255){sl(b)}G[b+56>>2]=1;G[b+52>>2]=a;break h}G[b+56>>2]=e+1}a=G[b>>2];G[a>>2]=G[a>>2]+1;c=G[a+4>>2]-1|0;G[a+4>>2]=c;e=G[a+8>>2]+1|0;G[a+8>>2]=e;if(!e){G[a+12>>2]=G[a+12>>2]+1}e=G[b+12>>2]-1|0;G[b+12>>2]=e;i=1;n=G[b+68>>2];g=G[b+72>>2];if(!c|(n|0)>=(g|0)){break g}if(e){continue}break}break g}i=0;if((g|0)<=(n|0)){break g}c=G[b>>2];if(!G[c+4>>2]){break g}a=G[b+52>>2];d=G[c>>2];while(1){e=G[b+56>>2];k:{l:{c=H[d|0];m:{if((c|0)!=(a|0)){if((e|0)!=1){break m}e=G[b+608>>2];G[b+608>>2]=e<<8^G[((a&255^e>>>24)<<2)+191040>>2];E[(a+b|0)+88|0]=1;E[G[b+36>>2]+G[b+68>>2]|0]=a;G[b+52>>2]=c;G[b+68>>2]=G[b+68>>2]+1;break k}if((e|0)!=255){break l}}if(a>>>0<=255){sl(b)}G[b+56>>2]=1;G[b+52>>2]=c;break k}G[b+56>>2]=e+1}a=G[b>>2];d=G[a>>2]+1|0;G[a>>2]=d;e=G[a+4>>2]-1|0;G[a+4>>2]=e;i=G[a+8>>2]+1|0;G[a+8>>2]=i;if(!i){G[a+12>>2]=G[a+12>>2]+1}i=1;n=G[b+68>>2];g=G[b+72>>2];if((n|0)>=(g|0)){break g}a=c;if(e){continue}break}}Ea=i|Ea;a=G[b+4>>2];if(!(G[b+12>>2]|(a|0)==2)){if(J[b+52>>2]<=255){sl(b);a=G[b+4>>2]}G[b+52>>2]=256;G[b+56>>2]=0;a=(a|0)==4;break a}a=0;if((g|0)<=(n|0)){break a}if(G[G[b>>2]+4>>2]){continue}}return((Da|Ea)&255)!=0}Ia=a;f=0;j=0;T=0;v=0;X=0;_=0;$=0;R=Fa-288|0;Fa=R;a=G[b+68>>2];if((a|0)>0){c=G[b+608>>2]^-1;G[b+608>>2]=c;e=Eu(G[b+612>>2],1)^c;G[b+612>>2]=e;d=G[b+620>>2];if((d|0)>=2){G[b+76>>2]=0}if(G[b+616>>2]>=2){G[R+28>>2]=a;G[R+24>>2]=e;G[R+20>>2]=c;G[R+16>>2]=d;_a(G[24367],75372,R+16|0)}r=Fa-4592|0;Fa=r;B=G[b+616>>2];S=G[b+24>>2];t=G[b+32>>2];s=G[b+68>>2];n:{o:{if((s|0)<1e4){break o}q=G[b+36>>2];a=G[b+48>>2];a=(a|0)>1?a:1;z=M(s,(((a>>>0<100?a:100)-1&255)>>>0)/3|0);G[r+60>>2]=z;if((B|0)>=4){hb(86989,33,1,G[24367])}x=(q+(s+(s&1)|0)|0)+34|0;u=cb(S,0,262148);c=H[q|0]<<8;D=s-1|0;e=D;while(1){a=e;F[x+(a<<1)>>1]=0;c=H[a+q|0]<<8|c>>8;d=u+(c<<2)|0;G[d>>2]=G[d>>2]+1;d=a-1|0;F[x+(d<<1)>>1]=0;c=H[d+q|0]<<8|c>>8;d=u+(c<<2)|0;G[d>>2]=G[d>>2]+1;d=a-2|0;F[x+(d<<1)>>1]=0;c=H[d+q|0]<<8|c>>8;d=u+(c<<2)|0;G[d>>2]=G[d>>2]+1;d=a-3|0;F[x+(d<<1)>>1]=0;c=H[d+q|0]<<8|c>>8;d=u+(c<<2)|0;G[d>>2]=G[d>>2]+1;e=a-4|0;if(a>>>0>6){continue}break}p:{if(a>>>0<4){break p}if(a&1){a=e}else{F[x+(e<<1)>>1]=0;c=H[e+q|0]<<8|c>>8;d=u+(c<<2)|0;G[d>>2]=G[d>>2]+1;a=a-5|0}if(!e){break p}while(1){F[x+(a<<1)>>1]=0;c=H[a+q|0]<<8|c>>8;e=u+(c<<2)|0;G[e>>2]=G[e>>2]+1;e=a-1|0;F[x+(e<<1)>>1]=0;c=H[e+q|0]<<8|c>>8;d=u+(c<<2)|0;G[d>>2]=G[d>>2]+1;a=a-2|0;if(e){continue}break}}a=0;while(1){c=a+s|0;E[c+q|0]=H[a+q|0];F[x+(c<<1)>>1]=0;c=a|1;e=c+s|0;E[e+q|0]=H[c+q|0];F[x+(e<<1)>>1]=0;a=a+2|0;if((a|0)!=34){continue}break}if((B|0)>=4){hb(86961,27,1,G[24367])}e=G[u>>2];c=1;while(1){a=u+(c<<2)|0;e=G[a>>2]+e|0;G[a>>2]=e;e=e+G[a+4>>2]|0;G[a+4>>2]=e;e=e+G[a+8>>2]|0;G[a+8>>2]=e;e=e+G[a+12>>2]|0;G[a+12>>2]=e;c=c+4|0;if((c|0)!=65537){continue}break}c=H[q|0]<<8;e=D;while(1){a=e;d=H[a+q|0];i=u+((d<<8|c<<16>>>24)<<2)|0;c=G[i>>2]-1|0;G[i>>2]=c;G[t+(c<<2)>>2]=a;i=a-1|0;g=H[i+q|0];d=u+((d|g<<8)<<2)|0;c=G[d>>2]-1|0;G[d>>2]=c;G[t+(c<<2)>>2]=i;d=a-2|0;i=H[d+q|0];g=u+((g|i<<8)<<2)|0;c=G[g>>2]-1|0;G[g>>2]=c;G[t+(c<<2)>>2]=d;g=a-3|0;c=i|H[g+q|0]<<8;i=u+(c<<2)|0;d=G[i>>2]-1|0;G[i>>2]=d;G[t+(d<<2)>>2]=g;e=a-4|0;if(a>>>0>6){continue}break}if(a>>>0>3){while(1){a=e;c=H[a+q|0]<<8|c<<16>>>24;i=u+(c<<2)|0;d=G[i>>2]-1|0;G[i>>2]=d;G[t+(d<<2)>>2]=a;e=a-1|0;if(a){continue}break}}a=0;cb(r+2112|0,0,256);while(1){c=r+2368|0;G[c+(a<<2)>>2]=a;e=a|1;G[c+(e<<2)>>2]=e;e=a|2;G[c+(e<<2)>>2]=e;e=a|3;G[c+(e<<2)>>2]=e;e=a|4;G[c+(e<<2)>>2]=e;e=a|5;G[c+(e<<2)>>2]=e;e=a|6;G[c+(e<<2)>>2]=e;e=a|7;G[c+(e<<2)>>2]=e;a=a+8|0;if((a|0)!=256){continue}break}d=364;while(1){e=(d|0)/3|0;if((d|0)<=767){g=(e|0)>255?e:255;a=e;while(1){i=a;n=G[(r+2368|0)+(a<<2)>>2];c=u+(n<<10)|0;l=G[c+1024>>2]-G[c>>2]|0;while(1){q:{c=a-e|0;m=G[(r+2368|0)+(c<<2)>>2];h=u+(m<<10)|0;if(l>>>0>=G[h+1024>>2]-G[h>>2]>>>0){c=a;break q}G[(r+2368|0)+(a<<2)>>2]=m;a=c;if((e|0)<=(a|0)){continue}}break}G[(r+2368|0)+(c<<2)>>2]=n;a=i+1|0;if((g|0)!=(i|0)){continue}break}}a=d-3|0;d=e;if(a>>>0>2){continue}break}U=G[24367];k=z;r:{s:{t:{while(1){A=G[(r+2368|0)+(T<<2)>>2];W=A<<8;y=0;while(1){if((A|0)!=(y|0)){O=u+(y+W<<2)|0;a=G[O>>2];u:{if(a&2097152){break u}c=G[O+4>>2]&-2097153;C=c-1|0;P=a&-2097153;if((C|0)<=(P|0)){break u}if((B|0)>=4){G[r+40>>2]=v;G[r+36>>2]=y;G[r+32>>2]=A;G[r+44>>2]=c-P;_a(U,74822,r+32|0)}G[r+4192>>2]=P;G[r+3792>>2]=C;G[r+3392>>2]=2;i=1;while(1){o=i;i=i-1|0;a=i<<2;w=a+(r+3392|0)|0;Y=a+(r+3792|0)|0;Z=a+(r+4192|0)|0;v:while(1){if(o>>>0>=98){zd(1001)}w:{p=G[w>>2];l=G[Y>>2];d=G[Z>>2];a=l-d|0;if(!((p|0)<15&(a|0)>=20)){c=0;x:{if((a|0)<=0){break x}while(1){g=c;c=c+1|0;if((a|0)>=G[(g<<2)+189552>>2]){continue}break}if(!g){break x}while(1){e=g;g=e-1|0;m=G[(g<<2)+189552>>2];h=m+d|0;n=h;while(1){y:{if((l|0)<(n|0)){break y}k=G[t+(n<<2)>>2];o=k+p|0;a=n;while(1){z:{c=a-m|0;w=G[t+(c<<2)>>2];if(!tl(w+p|0,o,q,x,s,r+60|0)){c=a;break z}G[t+(a<<2)>>2]=w;a=c;if((h|0)<=(a|0)){continue}}break}G[t+(c<<2)>>2]=k;if((l|0)<=(n|0)){break y}a=n+1|0;k=G[t+(a<<2)>>2];o=k+p|0;while(1){A:{c=a-m|0;w=G[t+(c<<2)>>2];if(!tl(w+p|0,o,q,x,s,r+60|0)){c=a;break A}G[t+(a<<2)>>2]=w;a=c;if((h|0)<=(a|0)){continue}}break}G[t+(c<<2)>>2]=k;a=n+2|0;if((l|0)<(a|0)){break y}k=G[t+(a<<2)>>2];o=k+p|0;while(1){B:{c=a-m|0;w=G[t+(c<<2)>>2];if(!tl(w+p|0,o,q,x,s,r+60|0)){c=a;break B}G[t+(a<<2)>>2]=w;a=c;if((h|0)<=(a|0)){continue}}break}G[t+(c<<2)>>2]=k;n=n+3|0;k=G[r+60>>2];if((k|0)>=0){continue}break t}break}if((e|0)>1){continue}break}k=G[r+60>>2]}if((k|0)<0){break t}break w}Q=t+(d<<2)|0;a=H[q+(p+G[Q>>2]|0)|0];c=H[q+(p+G[t+(l<<2)>>2]|0)|0];g=a>>>0>>0?a:c;e=H[q+(p+G[t+(d+l<<1&-4)>>2]|0)|0];a=a>>>0>c>>>0?a:c;c=a>>>0>e>>>0?e>>>0>>0?g:e:a;g=l;n=g;m=d;a=d;while(1){e=a;C:{if((a|0)>(n|0)){break C}D:while(1){e=(a|0)>(n|0)?a:n;while(1){h=t+(a<<2)|0;K=G[h>>2];V=H[q+(K+p|0)|0];if((V|0)==(c|0)){e=t+(m<<2)|0;G[h>>2]=G[e>>2];G[e>>2]=K;m=m+1|0;h=(a|0)<(n|0);e=a+1|0;a=e;if(h){continue D}break C}if(c>>>0>>0){e=a;break C}h=(a|0)!=(e|0);a=a+1|0;if(h){continue}break}break}e=e+1|0}E:{F:{if((e|0)>(n|0)){break F}G:while(1){a=n;while(1){h=t+(a<<2)|0;K=G[h>>2];V=H[q+(K+p|0)|0];if((V|0)==(c|0)){n=t+(g<<2)|0;G[h>>2]=G[n>>2];G[n>>2]=K;n=a-1|0;g=g-1|0;if((a|0)>(e|0)){continue G}break F}if(c>>>0>V>>>0){break E}h=(a|0)>(e|0);a=a-1|0;if(h){continue}break}break}n=((e|0)>(n|0)?n:e)-1|0}if((g|0)<(m|0)){G[w>>2]=p+1;continue v}a=m-d|0;c=e-m|0;h=(a|0)<(c|0)?a:c;H:{if((h|0)<=0){break H}a=e-h|0;I:{if(!(h&1)){i=d;c=h;break I}c=G[Q>>2];i=t+(a<<2)|0;G[Q>>2]=G[i>>2];G[i>>2]=c;a=a+1|0;i=d+1|0;c=h-1|0}if((h|0)==1){break H}while(1){h=t+(i<<2)|0;K=G[h>>2];Q=t+(a<<2)|0;G[h>>2]=G[Q>>2];G[Q>>2]=K;K=G[h+4>>2];G[h+4>>2]=G[Q+4>>2];G[Q+4>>2]=K;a=a+2|0;i=i+2|0;h=c-3|0;c=c-2|0;if(h>>>0<4294967294){continue}break}}a=l-g|0;n=g-n|0;g=(a|0)<(n|0)?a:n;J:{if((g|0)<=0){break J}a=l-g|0;K:{if(!(g&1)){i=e;c=g;break K}c=t+(e<<2)|0;i=G[c>>2];h=c;a=a+1|0;c=t+(a<<2)|0;G[h>>2]=G[c>>2];G[c>>2]=i;i=e+1|0;c=g-1|0}if((g|0)==1){break J}while(1){g=t+(i<<2)|0;h=G[g>>2];Q=t+(a<<2)|0;G[g>>2]=G[Q+4>>2];G[Q+4>>2]=h;h=G[g+4>>2];K=g;a=a+2|0;g=t+(a<<2)|0;G[K+4>>2]=G[g>>2];G[g>>2]=h;i=i+2|0;g=c-3|0;c=c-2|0;if(g>>>0<4294967294){continue}break}}h=(d-m|0)+e|0;i=h-1|0;e=i-d|0;a=l-n|0;c=a+1|0;g=l-c|0;L:{if((e|0)>=(g|0)){e=g;m=c;c=d;d=l;l=i;break L}m=d;d=i}i=p+1|0;n=a-h|0;M:{if((n|0)<=(e|0)){n=e;e=m;g=a;a=d;d=i;i=p;m=h;break M}e=h;g=d;d=p}N:{if((l-c|0)>=(n|0)){h=e;e=c;n=a;a=l;l=i;i=p;break N}h=c;n=l;l=p}G[Z>>2]=e;G[Y>>2]=a;G[w>>2]=i;a=o<<2;c=a+4|0;e=r+4192|0;G[c+e>>2]=m;G[a+e>>2]=h;e=r+3792|0;G[e+a>>2]=n;G[c+e>>2]=g;e=a;a=r+3392|0;G[e+a>>2]=l;G[a+c>>2]=d;i=o+2|0;break w}n=t+(e<<2)|0;V=G[n>>2];G[n>>2]=K;G[h>>2]=V;n=a-1|0;a=e+1|0;continue}}break}if((i|0)>0){continue}break}if((k|0)<0){break t}v=(C+(v-P|0)|0)+1|0;a=G[O>>2]}G[O>>2]=a|2097152}y=y+1|0;if((y|0)!=256){continue}break}g=A+(r+2112|0)|0;if(H[g|0]){zd(1006)}a=0;while(1){c=a<<2;e=u+(A+(a<<8)<<2)|0;G[c+(r+1088|0)>>2]=G[e>>2]&-2097153;G[c+(r- -64|0)>>2]=(G[e+4>>2]&-2097153)-1;a=a+1|0;if((a|0)!=256){continue}break}d=u+(W<<2)|0;a=G[d>>2]&-2097153;i=A<<2;n=i+(r+1088|0)|0;e=G[n>>2];if((a|0)<(e|0)){while(1){c=G[t+(a<<2)>>2]-1|0;l=(s&c>>31)+c|0;c=H[l+q|0];if(!H[c+(r+2112|0)|0]){e=(r+1088|0)+(c<<2)|0;c=G[e>>2];G[e>>2]=c+1;G[t+(c<<2)>>2]=l;e=G[n>>2]}a=a+1|0;if((e|0)>(a|0)){continue}break}}n=d+1024|0;a=(G[n>>2]&-2097153)-1|0;l=i+(r- -64|0)|0;i=G[l>>2];if((a|0)>(i|0)){while(1){c=G[t+(a<<2)>>2]-1|0;m=(s&c>>31)+c|0;c=H[m+q|0];if(!H[c+(r+2112|0)|0]){i=(r- -64|0)+(c<<2)|0;c=G[i>>2];G[i>>2]=c-1;G[t+(c<<2)>>2]=m;i=G[l>>2]}a=a-1|0;if((i|0)<(a|0)){continue}break}}if(!(!e&(i|0)==(D|0)|(e-1|0)==(i|0))){zd(1007)}c=0;while(1){a=c<<8;e=u+(a+A<<2)|0;G[e>>2]=G[e>>2]|2097152;e=u+(A+(a|256)<<2)|0;G[e>>2]=G[e>>2]|2097152;e=u+(A+(a|512)<<2)|0;G[e>>2]=G[e>>2]|2097152;a=u+(A+(a|768)<<2)|0;G[a>>2]=G[a>>2]|2097152;c=c+4|0;if((c|0)!=256){continue}break}E[g|0]=1;O:{if(T>>>0>254){break O}g=G[n>>2]&-2097153;i=G[d>>2]&-2097153;d=g-i|0;c=0;while(1){a=c;c=a+1|0;if(d>>a>65534){continue}break}e=d-1|0;P:{if((d|0)<=0){break P}c=e;if(d&1){c=G[(t+(g<<2)|0)-4>>2];g=e>>>a|0;F[x+(c<<1)>>1]=g;if((c|0)<=33){F[x+(c+s<<1)>>1]=g}c=d-2|0}if(!e){break P}while(1){d=G[t+(c+i<<2)>>2];g=c>>>a|0;F[x+(d<<1)>>1]=g;if((d|0)<=33){F[x+(d+s<<1)>>1]=g}g=c-1|0;d=G[t+(g+i<<2)>>2];g=g>>>a|0;F[x+(d<<1)>>1]=g;if((d|0)<=33){F[x+(d+s<<1)>>1]=g}d=(c|0)>1;c=c-2|0;if(d){continue}break}}if(e>>a<65536){break O}zd(1002)}T=T+1|0;if((T|0)!=256){continue}break}if((B|0)<4){break t}G[r+16>>2]=s;G[r+20>>2]=v;G[r+24>>2]=s-v;_a(U,73623,r+16|0);break s}if((B|0)<3){break r}}a=z-k|0;G[r>>2]=a;G[r+4>>2]=s;L[r+8>>3]=N(N(a|0)/N(s|0));xb(U,72301,r)}if((k|0)>=0){break n}if((B|0)<2){break o}hb(70237,53,1,U)}p=G[b+16>>2];u=G[b+20>>2];a=0;e=0;i=0;q=Fa-2896|0;Fa=q;if((B|0)>=4){hb(86961,27,1,G[24367])}cb(q+1056|0,0,1028);c=1;if((s|0)>0){if(s-1>>>0>=3){g=s&-4;while(1){d=q+1056|0;n=d+(H[a+u|0]<<2)|0;G[n>>2]=G[n>>2]+1;n=d+(H[u+(a|1)|0]<<2)|0;G[n>>2]=G[n>>2]+1;n=d+(H[u+(a|2)|0]<<2)|0;G[n>>2]=G[n>>2]+1;d=d+(H[u+(a|3)|0]<<2)|0;G[d>>2]=G[d>>2]+1;a=a+4|0;e=e+4|0;if((g|0)!=(e|0)){continue}break}}e=s&3;if(e){while(1){d=(q+1056|0)+(H[a+u|0]<<2)|0;G[d>>2]=G[d>>2]+1;a=a+1|0;i=i+1|0;if((e|0)!=(i|0)){continue}break}}i=G[q+1056>>2]}bb(q+32|0,q+1056|0,1024);while(1){a=(q+1056|0)+(c<<2)|0;e=G[a>>2]+i|0;G[a>>2]=e;e=e+G[a+4>>2]|0;G[a+4>>2]=e;e=e+G[a+8>>2]|0;G[a+8>>2]=e;i=e+G[a+12>>2]|0;G[a+12>>2]=i;c=c+4|0;if((c|0)!=257){continue}break}Q:{if((s|0)<=0){break Q}a=0;if((s|0)!=1){d=s&-2;c=0;while(1){i=q+1056|0;g=i+(H[a+u|0]<<2)|0;e=G[g>>2]-1|0;G[g>>2]=e;G[p+(e<<2)>>2]=a;g=a|1;i=i+(H[g+u|0]<<2)|0;e=G[i>>2]-1|0;G[i>>2]=e;G[p+(e<<2)>>2]=g;a=a+2|0;c=c+2|0;if((d|0)!=(c|0)){continue}break}}if(!(s&1)){break Q}e=(q+1056|0)+(H[a+u|0]<<2)|0;c=G[e>>2]-1|0;G[e>>2]=c;G[p+(c<<2)>>2]=a}if((s|0)>=-63){cb(S,0,((s|0)/32<<2)+8|0)}a=0;c=0;while(1){e=c<<2;d=q+1056|0;i=G[e+d>>2];g=S+(i>>5<<2)|0;G[g>>2]=G[g>>2]|1<>2];d=S+(e>>5<<2)|0;G[d>>2]=G[d>>2]|1<>5<<2)|0;G[e>>2]=G[e>>2]|1<>5<<2)|0;d=G[e>>2];Qc=e,Rc=Eu(-2,c)&d,G[Qc>>2]=Rc;a=a+1|0;if((a|0)!=32){continue}break}v=G[24367];U=(B|0)<4;x=1;while(1){if(!U){G[q+16>>2]=x;_a(v,66110,q+16|0)}a=0;c=0;if((s|0)>0){while(1){e=G[p+(a<<2)>>2]-x|0;c=G[S+(a>>>3&536870908)>>2]>>>a&1?a:c;G[u+((s&e>>31)+e<<2)>>2]=c;a=a+1|0;if((s|0)!=(a|0)){continue}break}}A=0;z=-1;while(1){c=z;while(1){c=c+1|0;a=1<>5<<2)>>2];if(c&31?a:0){continue}break}if(a){while(1){a=c;c=a+32|0;if(G[S+(a>>5<<2)>>2]==-1){continue}break}while(1){c=a;a=a+1|0;if(G[S+(c>>5<<2)>>2]>>>c&1){continue}break}}R:{a=c;if((s|0)<(a|0)){break R}while(1){i=a;e=G[S+(a>>5<<2)>>2]&1<>5<<2)>>2]){continue}break}while(1){i=a;a=a+1|0;if(!(G[S+(i>>5<<2)>>2]>>>i&1)){continue}break}}if((i|0)>(s|0)){break R}z=i-1|0;if((c|0)>=(i|0)){continue}B=c-1|0;G[q+2496>>2]=B;G[q+2096>>2]=z;A=((A-c|0)+z|0)+2|0;k=1;T=0;while(1){D=k;if(k>>>0>=99){zd(1004)}k=D-1|0;a=k<<2;O=a+(q+2096|0)|0;e=G[O>>2];P=a+(q+2496|0)|0;l=G[P>>2];a=e-l|0;S:{if((a|0)<=9){T:{if((e|0)==(l|0)){break T}U:{if((a|0)<4){break U}a=e-4|0;if((l|0)>(a|0)){break U}while(1){g=a;m=G[p+(a<<2)>>2];d=a+4|0;V:{if((e|0)<(d|0)){break V}h=G[u+(m<<2)>>2];n=g;while(1){a=d;d=G[p+(a<<2)>>2];if(h>>>0<=J[u+(d<<2)>>2]){a=n;break V}G[p+(n<<2)>>2]=d;n=a;d=a+4|0;if((e|0)>=(d|0)){continue}break}}G[p+(a<<2)>>2]=m;a=g-1|0;if((g|0)>(l|0)){continue}break}}if((e|0)<=(l|0)){break T}g=e+1|0;a=e;while(1){d=a-1|0;n=G[p+(d<<2)>>2];if((a|0)<=(e|0)){m=G[u+(n<<2)>>2];W:{while(1){h=p+(a<<2)|0;o=G[h>>2];if(m>>>0<=J[u+(o<<2)>>2]){break W}G[h-4>>2]=o;h=(a|0)!=(e|0);a=a+1|0;if(h){continue}break}a=g}a=a-1|0}else{a=d}G[(a<<2)+p>>2]=n;a=d;if((l|0)<(a|0)){continue}break}}if((D|0)>1){continue}break S}a=l;X:{Y:{Z:{T=M(T,7621)+1&32767;switch((T>>>0)%3|0){case 0:break X;case 1:break Z;default:break Y}}a=e+l>>1;break X}a=e}d=G[u+(G[p+(a<<2)>>2]<<2)>>2];m=e;h=e;o=l;a=l;while(1){g=a;_:{if((a|0)>(h|0)){break _}$:while(1){g=(a|0)>(h|0)?a:h;while(1){n=p+(a<<2)|0;y=G[n>>2];w=G[u+(y<<2)>>2];if((w|0)==(d|0)){g=p+(o<<2)|0;G[n>>2]=G[g>>2];G[g>>2]=y;o=o+1|0;n=(a|0)<(h|0);g=a+1|0;a=g;if(n){continue $}break _}if((d|0)<(w|0)){g=a;break _}n=(a|0)!=(g|0);a=a+1|0;if(n){continue}break}break}g=g+1|0}aa:{ba:{ca:{if((g|0)>(h|0)){break ca}da:while(1){a=h;while(1){n=p+(a<<2)|0;y=G[n>>2];w=G[u+(y<<2)>>2];if((w|0)==(d|0)){h=n;n=p+(m<<2)|0;G[h>>2]=G[n>>2];G[n>>2]=y;h=a-1|0;m=m-1|0;if((a|0)>(g|0)){continue da}break ca}if((d|0)>(w|0)){break ba}n=(a|0)>(g|0);a=a-1|0;if(n){continue}break}break}h=((g|0)>(h|0)?h:g)-1|0}if((m|0)<(o|0)){break aa}a=o-l|0;d=g-o|0;k=(a|0)<(d|0)?a:d;ea:{if((k|0)<=0){break ea}a=g-k|0;fa:{if(!(k&1)){n=l;d=k;break fa}d=p+(l<<2)|0;n=G[d>>2];C=d;d=p+(a<<2)|0;G[C>>2]=G[d>>2];G[d>>2]=n;a=a+1|0;n=l+1|0;d=k-1|0}if((k|0)==1){break ea}while(1){k=p+(n<<2)|0;w=G[k>>2];y=p+(a<<2)|0;G[k>>2]=G[y>>2];G[y>>2]=w;w=G[k+4>>2];G[k+4>>2]=G[y+4>>2];G[y+4>>2]=w;a=a+2|0;n=n+2|0;k=d-3|0;d=d-2|0;if(k>>>0<4294967294){continue}break}}a=e-m|0;h=m-h|0;m=(a|0)<(h|0)?a:h;ga:{if((m|0)<=0){break ga}a=e-m|0;ha:{if(!(m&1)){n=g;d=m;break ha}d=p+(g<<2)|0;n=G[d>>2];k=d;a=a+1|0;d=p+(a<<2)|0;G[k>>2]=G[d>>2];G[d>>2]=n;n=g+1|0;d=m-1|0}if((m|0)==1){break ga}while(1){m=p+(n<<2)|0;k=G[m>>2];y=p+(a<<2)|0;G[m>>2]=G[y+4>>2];G[y+4>>2]=k;k=G[m+4>>2];C=m;a=a+2|0;m=p+(a<<2)|0;G[C+4>>2]=G[m>>2];G[m>>2]=k;n=n+2|0;m=d-3|0;d=d-2|0;if(m>>>0<4294967294){continue}break}}d=(l+(o^-1)|0)+g|0;a=(e-h|0)+1|0;ia:{if((d-l|0)>(e-a|0)){G[O>>2]=d;break ia}G[P>>2]=a;a=l;e=d}d=D<<2;G[d+(q+2096|0)>>2]=e;G[d+(q+2496|0)>>2]=a;k=D+1|0;break aa}h=p+(g<<2)|0;w=G[h>>2];G[h>>2]=y;G[n>>2]=w;h=a-1|0;a=g+1|0;continue}break}if((k|0)>0){continue}}break}a=-1;if((c|0)>(i|0)){continue}while(1){c=G[u+(G[p+(B<<2)>>2]<<2)>>2];if((c|0)!=(a|0)){a=S+(B>>5<<2)|0;G[a>>2]=G[a>>2]|1<>2]=A;_a(v,68866,q);x=x<<1;if(A?(s|0)>=(x|0):0){continue}hb(86927,33,1,v);break ja}x=x<<1;if((s|0)<(x|0)){break ja}if(A){continue}}break}ka:{if((s|0)<=0){break ka}i=s&1;la:{if((s|0)==1){e=0;a=0;break la}g=s&-2;e=0;a=0;d=0;while(1){c=a;a=a+1|0;n=(q+32|0)+(c<<2)|0;l=G[n>>2];if(!l){continue}G[n>>2]=l-1;E[u+G[p+(e<<2)>>2]|0]=c;n=e|1;while(1){a=c;c=a+1|0;l=(q+32|0)+(a<<2)|0;m=G[l>>2];if(!m){continue}break}G[l>>2]=m-1;E[u+G[p+(n<<2)>>2]|0]=a;e=e+2|0;d=d+2|0;if((g|0)!=(d|0)){continue}break}}if(i){while(1){c=a;a=a+1|0;d=(q+32|0)+(c<<2)|0;i=G[d>>2];if(!i){continue}break}G[d>>2]=i-1;E[u+G[p+(e<<2)>>2]|0]=c;a=c}if((a|0)<256){break ka}zd(1005)}Fa=q+2896|0}G[b+28>>2]=-1;c=G[b+68>>2];ma:{if((c|0)>0){a=0;while(1){if(!G[t+(a<<2)>>2]){G[b+28>>2]=a;break ma}a=a+1|0;if((c|0)!=(a|0)){continue}break}}zd(1003)}Fa=r+4592|0;a=G[b+68>>2]}G[b+44>>2]=G[b+20>>2]+a;if(G[b+620>>2]==1){G[b+600>>2]=1107296256;G[b+604>>2]=8;a=G[b+76>>2];h=1107296256;while(1){E[G[b+44>>2]+a|0]=h>>>24;a=G[b+76>>2]+1|0;G[b+76>>2]=a;h=G[b+600>>2]<<8;G[b+600>>2]=h;c=G[b+604>>2];G[b+604>>2]=c-8;if((c|0)>15){continue}break}G[b+604>>2]=c;h=90<<32-c|h;G[b+600>>2]=h;if((c|0)>=8){while(1){E[G[b+44>>2]+a|0]=h>>>24;a=G[b+76>>2]+1|0;G[b+76>>2]=a;h=G[b+600>>2]<<8;G[b+600>>2]=h;e=G[b+604>>2];c=e-8|0;G[b+604>>2]=c;if((e|0)>15){continue}break}}e=c+8|0;G[b+604>>2]=e;h=104<<24-c|h;G[b+600>>2]=h;d=G[b+624>>2]+48|0;if((c|0)>=0){while(1){E[G[b+44>>2]+a|0]=h>>>24;a=G[b+76>>2]+1|0;G[b+76>>2]=a;h=G[b+600>>2]<<8;G[b+600>>2]=h;c=G[b+604>>2];e=c-8|0;G[b+604>>2]=e;if((c|0)>15){continue}break}}G[b+604>>2]=e+8;G[b+600>>2]=(d&255)<<24-e|h;a=G[b+68>>2]}if((a|0)>0){d=G[b+604>>2];na:{if((d|0)<=7){a=G[b+600>>2];break na}c=G[b+76>>2];a=G[b+600>>2];while(1){E[G[b+44>>2]+c|0]=a>>>24;c=G[b+76>>2]+1|0;G[b+76>>2]=c;a=G[b+600>>2]<<8;G[b+600>>2]=a;e=G[b+604>>2];d=e-8|0;G[b+604>>2]=d;if((e|0)>15){continue}break}}e=d+8|0;G[b+604>>2]=e;a=49<<24-d|a;G[b+600>>2]=a;if((d|0)>=0){c=G[b+76>>2];while(1){E[G[b+44>>2]+c|0]=a>>>24;c=G[b+76>>2]+1|0;G[b+76>>2]=c;a=G[b+600>>2]<<8;G[b+600>>2]=a;d=G[b+604>>2];e=d-8|0;G[b+604>>2]=e;if((d|0)>15){continue}break}}d=e+8|0;G[b+604>>2]=d;a=65<<24-e|a;G[b+600>>2]=a;if((e|0)>=0){c=G[b+76>>2];while(1){E[G[b+44>>2]+c|0]=a>>>24;c=G[b+76>>2]+1|0;G[b+76>>2]=c;a=G[b+600>>2]<<8;G[b+600>>2]=a;e=G[b+604>>2];d=e-8|0;G[b+604>>2]=d;if((e|0)>15){continue}break}}e=d+8|0;G[b+604>>2]=e;a=89<<24-d|a;G[b+600>>2]=a;if((d|0)>=0){c=G[b+76>>2];while(1){E[G[b+44>>2]+c|0]=a>>>24;c=G[b+76>>2]+1|0;G[b+76>>2]=c;a=G[b+600>>2]<<8;G[b+600>>2]=a;d=G[b+604>>2];e=d-8|0;G[b+604>>2]=e;if((d|0)>15){continue}break}}d=e+8|0;G[b+604>>2]=d;a=38<<24-e|a;G[b+600>>2]=a;if((e|0)>=0){c=G[b+76>>2];while(1){E[G[b+44>>2]+c|0]=a>>>24;c=G[b+76>>2]+1|0;G[b+76>>2]=c;a=G[b+600>>2]<<8;G[b+600>>2]=a;e=G[b+604>>2];d=e-8|0;G[b+604>>2]=d;if((e|0)>15){continue}break}}e=d+8|0;G[b+604>>2]=e;a=83<<24-d|a;G[b+600>>2]=a;if((d|0)>=0){c=G[b+76>>2];while(1){E[G[b+44>>2]+c|0]=a>>>24;c=G[b+76>>2]+1|0;G[b+76>>2]=c;a=G[b+600>>2]<<8;G[b+600>>2]=a;d=G[b+604>>2];e=d-8|0;G[b+604>>2]=e;if((d|0)>15){continue}break}}G[b+604>>2]=e+8;G[b+600>>2]=89<<24-e|a;Fq(b,G[b+608>>2]);e=G[b+604>>2];oa:{if((e|0)<=7){a=G[b+600>>2];break oa}c=G[b+76>>2];a=G[b+600>>2];while(1){E[G[b+44>>2]+c|0]=a>>>24;c=G[b+76>>2]+1|0;G[b+76>>2]=c;a=G[b+600>>2]<<8;G[b+600>>2]=a;d=G[b+604>>2];e=d-8|0;G[b+604>>2]=e;if((d|0)>15){continue}break}}G[b+600>>2]=a;d=e+1|0;G[b+604>>2]=d;i=G[b+28>>2];if((e|0)>=7){c=G[b+76>>2];while(1){E[G[b+44>>2]+c|0]=a>>>24;c=G[b+76>>2]+1|0;G[b+76>>2]=c;a=G[b+600>>2]<<8;G[b+600>>2]=a;e=G[b+604>>2];d=e-8|0;G[b+604>>2]=d;if((e|0)>15){continue}break}}G[b+604>>2]=d+24;G[b+600>>2]=i<<8-d|a;G[b+84>>2]=0;i=G[b+40>>2];m=G[b+36>>2];p=G[b+32>>2];a=0;while(1){c=a+b|0;if(H[c+88|0]){E[c+344|0]=f;f=f+1|0;G[b+84>>2]=f}c=(a|1)+b|0;if(H[c+88|0]){E[c+344|0]=f;f=f+1|0;G[b+84>>2]=f}a=a+2|0;if((a|0)!=256){continue}break}pa:{if((f|0)<-1){break pa}a=0;cb(b+632|0,0,(f<<2)+8|0);if((f|0)<=0){break pa}if(f-1>>>0>=7){d=f&-8;c=0;while(1){e=R+32|0;E[e+a|0]=a;g=a|1;E[g+e|0]=g;g=a|2;E[g+e|0]=g;g=a|3;E[g+e|0]=g;g=a|4;E[g+e|0]=g;g=a|5;E[g+e|0]=g;g=a|6;E[g+e|0]=g;g=e;e=a|7;E[g+e|0]=e;a=a+8|0;c=c+8|0;if((d|0)!=(c|0)){continue}break}}e=f&7;if(!e){break pa}c=0;while(1){E[(R+32|0)+a|0]=a;a=a+1|0;c=c+1|0;if((e|0)!=(c|0)){continue}break}}a=G[b+68>>2];qa:{if((a|0)<=0){h=0;break qa}g=b+632|0;n=b+636|0;d=R+32|1;h=0;while(1){c=H[R+32|0];e=G[p+(X<<2)>>2]-1|0;l=H[(H[m+((e>>31&a)+e|0)|0]+b|0)+344|0];ra:{if((c|0)==(l|0)){j=j+1|0;break ra}if((j|0)>0){c=j-1|0;a=c&1;e=a?n:g;G[e>>2]=G[e>>2]+1;F[i+(h<<1)>>1]=a;h=h+1|0;if(j>>>0>=3){while(1){a=c-2|0;c=a&2;e=c?n:g;G[e>>2]=G[e>>2]+1;F[i+(h<<1)>>1]=c>>>1;h=h+1|0;c=a>>>1|0;if(a>>>0>3){continue}break}}j=0;c=H[R+32|0]}e=H[R+33|0];E[R+33|0]=c;a=d;if((e|0)!=(l|0)){while(1){c=H[a+1|0];E[a+1|0]=e;a=a+1|0;e=c;if((c|0)!=(l|0)){continue}break}}E[R+32|0]=l;a=(a-R|0)-31|0;F[i+(h<<1)>>1]=a;a=(a<<2)+b|0;G[a+632>>2]=G[a+632>>2]+1;h=h+1|0;a=G[b+68>>2]}X=X+1|0;if((X|0)<(a|0)){continue}break}if((j|0)<=0){break qa}c=j-1|0;a=c&1;e=a?n:g;G[e>>2]=G[e>>2]+1;F[i+(h<<1)>>1]=a;h=h+1|0;if(j>>>0<3){break qa}while(1){a=c-2|0;c=a&2;e=c?n:g;G[e>>2]=G[e>>2]+1;F[i+(h<<1)>>1]=c>>>1;h=h+1|0;c=a>>>1|0;if(a>>>0>3){continue}break}}a=f+1|0;F[i+(h<<1)>>1]=a;a=(a<<2)+b|0;G[a+632>>2]=G[a+632>>2]+1;G[b+628>>2]=h+1;l=0;o=Fa-208|0;Fa=o;D=G[b+40>>2];if(G[b+616>>2]>=3){a=G[b+68>>2];c=G[b+628>>2];G[o+136>>2]=G[b+84>>2];G[o+132>>2]=c;G[o+128>>2]=a;_a(G[24367],72501,o+128|0)}t=G[b+84>>2];k=t+2|0;z=(k|0)>1?k:1;x=b+37668|0;if((t|0)>=-1){cb(x,15,z);cb(b+37926|0,15,z);cb(b+38184|0,15,z);cb(b+38442|0,15,z);cb(b+38700|0,15,z);cb(b+38958|0,15,z)}f=G[b+628>>2];if((f|0)<=0){zd(3001);f=G[b+628>>2]}p=2;sa:{if((f|0)<200){break sa}p=3;if(f>>>0<600){break sa}p=4;if(f>>>0<1200){break sa}_=f>>>0>2399;p=f>>>0<2400?5:6}r=z&2147483644;h=z&3;S=z-1|0;q=G[24367];d=p;while(1){a=l-1|0;i=d;e=0;d=(f|0)/(d|0)|0;ta:{if((d|0)<=0){break ta}if((a|0)>(t|0)){break ta}while(1){c=a;a=a+1|0;g=(a<<2)+b|0;e=G[g+632>>2]+e|0;if((c|0)<(t|0)&(d|0)>(e|0)){continue}break}if((i|0)==(p|0)|(c|0)<(l|0)){break ta}if((i|0)==1|(p-i&-2147483647)!=1){break ta}a=c;e=e-G[g+632>>2]|0}c=e;if(G[b+616>>2]>=3){e=G[b+628>>2];G[o+108>>2]=c;L[o+112>>3]=+N(c|0)*100/+N(e|0);G[o+104>>2]=a;G[o+100>>2]=l;G[o+96>>2]=i;xb(q,89345,o+96|0)}d=i-1|0;ua:{if((t|0)<-1){break ua}m=0;e=0;g=0;if(S>>>0>=3){while(1){n=(M(d,258)+b|0)+37668|0;E[n+e|0]=(e|0)<(l|0)?15:(a|0)<(e|0)?15:0;j=e|1;E[j+n|0]=(j|0)<(l|0)?15:(a|0)<=(e|0)?15:0;j=e|2;E[j+n|0]=(j|0)<(l|0)?15:(a|0)<(j|0)?15:0;P=n;n=e|3;E[P+n|0]=(l|0)>(n|0)?15:(a|0)<(n|0)?15:0;e=e+4|0;g=g+4|0;if((r|0)!=(g|0)){continue}break}}if(!h){break ua}while(1){E[((M(d,258)+b|0)+e|0)+37668|0]=(e|0)<(l|0)?15:(a|0)<(e|0)?15:0;e=e+1|0;m=m+1|0;if((h|0)!=(m|0)){continue}break}}f=f-c|0;l=a+1|0;if((i|0)>1){continue}break}s=(t|0)<-1;Ja=s|!_;h=b+51600|0;Ka=b+50568|0;La=b+49536|0;Ma=b+48504|0;Na=b+47472|0;Oa=b+46440|0;Pa=b+45408|0;Qa=p<<1;f=z<<2;Ra=p<<2;u=(p|0)==5;while(1){cb(o+160|0,0,Ra);if(!s){cb(Pa,0,f);cb(Oa,0,f)}n=(p|0)==2;va:{if(n){break va}if(!s){cb(Na,0,f)}if((p|0)==3){break va}if(!s){cb(Ma,0,f)}if((p|0)==4){break va}if(!s){cb(La,0,f)}if(u){break va}if(!s){cb(Ka,0,f)}if(s|(p|0)==6){break va}cb(h,0,f)}e=0;if(!Ja){while(1){c=(e<<4)+b|0;a=b+e|0;G[c+51600>>2]=H[e+x|0]|H[a+37926|0]<<16;G[c+51604>>2]=H[a+38184|0]|H[a+38442|0]<<16;G[c+51608>>2]=H[a+38700|0]|H[a+38958|0]<<16;e=e+1|0;if((z|0)!=(e|0)){continue}break}}e=0;j=0;r=0;l=G[b+628>>2];if((l|0)>0){while(1){cb(o+196|0,0,Qa);g=e+49|0;i=(g|0)<(l|0)?g:l-1|0;m=i-e|0;Ga=(m|0)==49&_;wa:{if(!Ga){c=e;if((i|0)<(c|0)){break wa}while(1){a=c;c=I[(a<<1)+D>>1]+b|0;F[o+196>>1]=I[o+196>>1]+H[c+37668|0];F[o+198>>1]=I[o+198>>1]+H[c+37926|0];xa:{if(n){break xa}F[o+200>>1]=I[o+200>>1]+H[c+38184|0];if((p|0)==3){break xa}F[o+202>>1]=I[o+202>>1]+H[c+38442|0];if((p|0)==4){break xa}F[o+204>>1]=I[o+204>>1]+H[c+38700|0];if(u){break xa}F[o+206>>1]=I[o+206>>1]+H[c+38958|0];if((p|0)==6){break xa}F[o+208>>1]=I[o+208>>1]+H[c+39216|0]}c=a+1|0;if((a|0)!=(i|0)){continue}break}break wa}c=(I[(g<<1)+D>>1]<<4)+h|0;Sa=G[c>>2];a=(e<<1)+D|0;d=(I[a+96>>1]<<4)+h|0;Ta=G[d>>2];l=(I[a+94>>1]<<4)+h|0;Ua=G[l>>2];A=(I[a+92>>1]<<4)+h|0;Va=G[A>>2];B=(I[a+90>>1]<<4)+h|0;Wa=G[B>>2];T=(I[a+88>>1]<<4)+h|0;Xa=G[T>>2];v=(I[a+86>>1]<<4)+h|0;Ya=G[v>>2];y=(I[a+84>>1]<<4)+h|0;Za=G[y>>2];U=(I[a+82>>1]<<4)+h|0;$a=G[U>>2];X=(I[a+80>>1]<<4)+h|0;ab=G[X>>2];O=(I[a+78>>1]<<4)+h|0;db=G[O>>2];P=(I[a+76>>1]<<4)+h|0;eb=G[P>>2];w=(I[a+74>>1]<<4)+h|0;fb=G[w>>2];Q=(I[a+72>>1]<<4)+h|0;gb=G[Q>>2];W=(I[a+70>>1]<<4)+h|0;ib=G[W>>2];C=(I[a+68>>1]<<4)+h|0;jb=G[C>>2];Y=(I[a+66>>1]<<4)+h|0;kb=G[Y>>2];Z=(I[a- -64>>1]<<4)+h|0;lb=G[Z>>2];K=(I[a+62>>1]<<4)+h|0;mb=G[K>>2];V=(I[a+60>>1]<<4)+h|0;nb=G[V>>2];aa=(I[a+58>>1]<<4)+h|0;ob=G[aa>>2];ba=(I[a+56>>1]<<4)+h|0;pb=G[ba>>2];ca=(I[a+54>>1]<<4)+h|0;qb=G[ca>>2];da=(I[a+52>>1]<<4)+h|0;rb=G[da>>2];ea=(I[a+50>>1]<<4)+h|0;sb=G[ea>>2];fa=(I[a+48>>1]<<4)+h|0;tb=G[fa>>2];ga=(I[a+46>>1]<<4)+h|0;ub=G[ga>>2];ha=(I[a+44>>1]<<4)+h|0;vb=G[ha>>2];ia=(I[a+42>>1]<<4)+h|0;wb=G[ia>>2];ja=(I[a+40>>1]<<4)+h|0;yb=G[ja>>2];ka=(I[a+38>>1]<<4)+h|0;zb=G[ka>>2];la=(I[a+36>>1]<<4)+h|0;Ab=G[la>>2];ma=(I[a+34>>1]<<4)+h|0;Bb=G[ma>>2];na=(I[a+32>>1]<<4)+h|0;Cb=G[na>>2];oa=(I[a+30>>1]<<4)+h|0;Db=G[oa>>2];pa=(I[a+28>>1]<<4)+h|0;Eb=G[pa>>2];qa=(I[a+26>>1]<<4)+h|0;Fb=G[qa>>2];ra=(I[a+24>>1]<<4)+h|0;Gb=G[ra>>2];sa=(I[a+22>>1]<<4)+h|0;Hb=G[sa>>2];ta=(I[a+20>>1]<<4)+h|0;Ib=G[ta>>2];ua=(I[a+18>>1]<<4)+h|0;Jb=G[ua>>2];va=(I[a+16>>1]<<4)+h|0;Kb=G[va>>2];wa=(I[a+14>>1]<<4)+h|0;Lb=G[wa>>2];xa=(I[a+12>>1]<<4)+h|0;Mb=G[xa>>2];ya=(I[a+10>>1]<<4)+h|0;Nb=G[ya>>2];za=(I[a+8>>1]<<4)+h|0;Ob=G[za>>2];Aa=(I[a+6>>1]<<4)+h|0;Pb=G[Aa>>2];Ba=(I[a+4>>1]<<4)+h|0;Qb=G[Ba>>2];Ca=(I[a>>1]<<4)+h|0;Rb=G[Ca>>2];a=(I[a+2>>1]<<4)+h|0;Sb=G[a>>2];Tb=G[c+4>>2];Vb=G[d+4>>2];Wb=G[l+4>>2];Xb=G[A+4>>2];Yb=G[B+4>>2];Zb=G[T+4>>2];_b=G[v+4>>2];$b=G[y+4>>2];ac=G[U+4>>2];bc=G[X+4>>2];cc=G[O+4>>2];dc=G[P+4>>2];ec=G[w+4>>2];fc=G[Q+4>>2];gc=G[W+4>>2];hc=G[C+4>>2];ic=G[Y+4>>2];jc=G[Z+4>>2];kc=G[K+4>>2];lc=G[V+4>>2];mc=G[aa+4>>2];nc=G[ba+4>>2];oc=G[ca+4>>2];pc=G[da+4>>2];qc=G[ea+4>>2];rc=G[fa+4>>2];sc=G[ga+4>>2];tc=G[ha+4>>2];uc=G[ia+4>>2];vc=G[ja+4>>2];wc=G[ka+4>>2];xc=G[la+4>>2];yc=G[ma+4>>2];zc=G[na+4>>2];Ac=G[oa+4>>2];Bc=G[pa+4>>2];Cc=G[qa+4>>2];Dc=G[ra+4>>2];Ec=G[sa+4>>2];Fc=G[ta+4>>2];Gc=G[ua+4>>2];Hc=G[va+4>>2];Ic=G[wa+4>>2];Jc=G[xa+4>>2];Kc=G[ya+4>>2];Lc=G[za+4>>2];Mc=G[Aa+4>>2];Nc=G[Ba+4>>2];Oc=G[Ca+4>>2];Pc=G[a+4>>2];a=G[c+8>>2]+(G[d+8>>2]+(G[l+8>>2]+(G[A+8>>2]+(G[B+8>>2]+(G[T+8>>2]+(G[v+8>>2]+(G[y+8>>2]+(G[U+8>>2]+(G[X+8>>2]+(G[O+8>>2]+(G[P+8>>2]+(G[w+8>>2]+(G[Q+8>>2]+(G[W+8>>2]+(G[C+8>>2]+(G[Y+8>>2]+(G[Z+8>>2]+(G[K+8>>2]+(G[V+8>>2]+(G[aa+8>>2]+(G[ba+8>>2]+(G[ca+8>>2]+(G[da+8>>2]+(G[ea+8>>2]+(G[fa+8>>2]+(G[ga+8>>2]+(G[ha+8>>2]+(G[ia+8>>2]+(G[ja+8>>2]+(G[ka+8>>2]+(G[la+8>>2]+(G[ma+8>>2]+(G[na+8>>2]+(G[oa+8>>2]+(G[pa+8>>2]+(G[qa+8>>2]+(G[ra+8>>2]+(G[sa+8>>2]+(G[ta+8>>2]+(G[ua+8>>2]+(G[va+8>>2]+(G[wa+8>>2]+(G[xa+8>>2]+(G[ya+8>>2]+(G[za+8>>2]+(G[Aa+8>>2]+(G[Ba+8>>2]+(G[a+8>>2]+G[Ca+8>>2]|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0;F[o+204>>1]=a;F[o+206>>1]=a>>>16;a=((((((((((((((gc+(hc+(ic+(jc+(kc+(lc+(mc+(nc+(oc+(pc+(qc+(rc+(sc+(tc+(uc+(vc+(wc+(xc+(yc+(zc+(Ac+(Bc+(Cc+(Dc+(Ec+(Fc+(Gc+(Hc+(Ic+(Jc+(Kc+(Lc+(Mc+(Nc+(Oc+Pc|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)+fc|0)+ec|0)+dc|0)+cc|0)+bc|0)+ac|0)+$b|0)+_b|0)+Zb|0)+Yb|0)+Xb|0)+Wb|0)+Vb|0)+Tb|0;F[o+200>>1]=a;F[o+202>>1]=a>>>16;a=((((((((((((((((((((((((((((((((((((((((((((((((Rb+Sb|0)+Qb|0)+Pb|0)+Ob|0)+Nb|0)+Mb|0)+Lb|0)+Kb|0)+Jb|0)+Ib|0)+Hb|0)+Gb|0)+Fb|0)+Eb|0)+Db|0)+Cb|0)+Bb|0)+Ab|0)+zb|0)+yb|0)+wb|0)+vb|0)+ub|0)+tb|0)+sb|0)+rb|0)+qb|0)+pb|0)+ob|0)+nb|0)+mb|0)+lb|0)+kb|0)+jb|0)+ib|0)+gb|0)+fb|0)+eb|0)+db|0)+ab|0)+$a|0)+Za|0)+Ya|0)+Xa|0)+Wa|0)+Va|0)+Ua|0)+Ta|0)+Sa|0;F[o+196>>1]=a;F[o+198>>1]=a>>>16}a=I[o+196>>1];c=I[o+198>>1];d=(a|0)<(c|0)?a:c;c=a>>>0>c>>>0;ya:{if(n){break ya}a=I[o+200>>1];c=a>>>0>>0?2:c;d=(a|0)>(d|0)?d:a;if((p|0)==3){break ya}a=I[o+202>>1];c=a>>>0>>0?3:c;d=(a|0)>(d|0)?d:a;if((p|0)==4){break ya}a=I[o+204>>1];c=a>>>0>>0?4:c;d=(a|0)>(d|0)?d:a;if(u){break ya}a=I[o+206>>1];c=a>>>0>>0?5:c;d=(a|0)>(d|0)?d:a;if((p|0)==6){break ya}a=I[o+208>>1];c=a>>>0>>0?6:c;d=(a|0)>(d|0)?d:a}a=(o+160|0)+(c<<2)|0;G[a>>2]=G[a>>2]+1;E[(b+r|0)+1664|0]=c;za:{if(!Ga){if((e|0)>(i|0)){break za}l=0;a=m+1&3;if(a){while(1){g=((M(c,1032)+b|0)+(I[(e<<1)+D>>1]<<2)|0)+45408|0;G[g>>2]=G[g>>2]+1;e=e+1|0;l=l+1|0;if((a|0)!=(l|0)){continue}break}}if(m>>>0<3){break za}while(1){a=(M(c,1032)+b|0)+45408|0;g=(e<<1)+D|0;l=a+(I[g>>1]<<2)|0;G[l>>2]=G[l>>2]+1;l=a+(I[g+2>>1]<<2)|0;G[l>>2]=G[l>>2]+1;g=a+(I[g+4>>1]<<2)|0;G[g>>2]=G[g>>2]+1;g=e+3|0;a=a+(I[(g<<1)+D>>1]<<2)|0;G[a>>2]=G[a>>2]+1;e=e+4|0;if((g|0)!=(i|0)){continue}break}break za}a=(M(c,1032)+b|0)+45408|0;e=(e<<1)+D|0;c=a+(I[e>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+2>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+4>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+6>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+8>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+10>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+12>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+14>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+16>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+18>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+20>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+22>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+24>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+26>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+28>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+30>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+32>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+34>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+36>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+38>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+40>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+42>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+44>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+46>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+48>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+50>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+52>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+54>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+56>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+58>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+60>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+62>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e- -64>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+66>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+68>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+70>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+72>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+74>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+76>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+78>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+80>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+82>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+84>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+86>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+88>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+90>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+92>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+94>>1]<<2)|0;G[c>>2]=G[c>>2]+1;c=a+(I[e+96>>1]<<2)|0;G[c>>2]=G[c>>2]+1;a=a+(I[(g<<1)+D>>1]<<2)|0;G[a>>2]=G[a>>2]+1}r=r+1|0;j=d+j|0;e=i+1|0;l=G[b+628>>2];if((e|0)<(l|0)){continue}break}}if(G[b+616>>2]>=3){G[o+84>>2]=(j|0)/8;G[o+80>>2]=$+1;_a(q,66402,o+80|0);e=0;while(1){G[o+64>>2]=G[(o+160|0)+(e<<2)>>2];_a(q,66542,o- -64|0);e=e+1|0;if((p|0)!=(e|0)){continue}break}Ub(10,q)}e=0;while(1){j=(M(e,258)+b|0)+37668|0;a=(M(e,1032)+b|0)+45408|0;c=0;m=0;l=Fa-5168|0;Fa=l;d=(k|0)<=0;Aa:{if(d){break Aa}if((k|0)!=1){i=k&-2;while(1){g=c<<2;n=g|4;A=l+2064|0;g=G[a+g>>2];G[n+A>>2]=g?g<<8:256;c=c+2|0;g=G[a+n>>2];G[A+(c<<2)>>2]=g?g<<8:256;m=m+2|0;if((i|0)!=(m|0)){continue}break}}if(!(k&1)){break Aa}c=c<<2;a=G[c+a>>2];G[(c+l|0)+2068>>2]=a?a<<8:256}G[l+2064>>2]=0;G[l+4128>>2]=0;G[l>>2]=-2;Ba:{if(d){break Ba}y=k<<2;U=l|4;A=k&-2;B=k&1;T=k-1|0;X=k>>>0<260;while(1){cb(U,255,y);i=0;g=1;while(1){n=l+4128|0;i=i+1|0;G[n+(i<<2)>>2]=g;v=l+2064|0;d=G[v+(g<<2)>>2];c=i;a=c>>>1|0;m=G[n+(a<<2)>>2];if((d|0)>2]){while(1){n=l+4128|0;G[n+(c<<2)>>2]=m;c=a;a=a>>>1|0;m=G[n+(a<<2)>>2];if((d|0)>2]){continue}break}}G[(l+4128|0)+(c<<2)>>2]=g;g=g+1|0;if((i|0)!=(k|0)){continue}break}if(!X){zd(2001)}g=k;i=g;if((g|0)>=2){while(1){O=G[l+4132>>2];v=G[(l+4128|0)+(i<<2)>>2];G[l+4132>>2]=v;n=i-1|0;c=1;a=1;Ca:{if(i>>>0<3){break Ca}m=2;P=G[(l+2064|0)+(v<<2)>>2];d=1;while(1){K=l+2064|0;w=l+4128|0;if((n|0)<=(m|0)){a=m}else{a=m|1;C=a;W=l+2064|0;Q=a<<2;a=l+4128|0;a=G[W+(G[Q+a>>2]<<2)>>2]>2]<<2)>>2]?C:m}m=G[w+(a<<2)>>2];if((P|0)>2]){a=d;break Ca}G[(l+4128|0)+(d<<2)>>2]=m;d=a;m=a<<1;if((m|0)<(i|0)){continue}break}}d=a<<2;a=l+4128|0;G[d+a>>2]=v;P=G[l+4132>>2];w=a+(n<<2)|0;m=G[w>>2];G[l+4132>>2]=m;Da:{if((i|0)<4){break Da}v=i-2|0;a=2;Q=G[(l+2064|0)+(m<<2)>>2];d=1;while(1){c=l+2064|0;W=l+4128|0;if((a|0)<(v|0)){C=a|1;K=C;Y=l+2064|0;V=C<<2;C=l+4128|0;a=G[Y+(G[V+C>>2]<<2)>>2]>2]<<2)>>2]?K:a}C=c;c=a;a=G[(a<<2)+W>>2];if((Q|0)>2]){c=d;break Da}G[(l+4128|0)+(d<<2)>>2]=a;d=c;a=c<<1;if((v|0)>=(a|0)){continue}break}}v=P<<2;g=g+1|0;G[v+l>>2]=g;a=O<<2;G[a+l>>2]=g;O=l+4128|0;G[O+(c<<2)>>2]=m;c=g<<2;G[c+l>>2]=-1;d=l+2064|0;m=G[d+a>>2];a=m&255;P=c+d|0;c=G[d+v>>2];v=c&255;v=(a>>>0>v>>>0?a:v)+1|(c&-256)+(m&-256);G[P>>2]=v;G[w>>2]=g;c=n;a=c>>1;m=G[O+(a<<2)>>2];if((v|0)>2]){while(1){d=l+4128|0;G[d+(c<<2)>>2]=m;c=a;a=a>>1;m=G[d+(a<<2)>>2];if((v|0)>2]){continue}break}}G[(l+4128|0)+(c<<2)>>2]=g;a=i>>>0>2;i=n;if(a){continue}break}}if((g|0)>=516){zd(2002)}v=(k|0)<=0;if(v){break Ba}g=0;i=1;m=0;if(T){while(1){c=i;a=0;while(1){d=a;a=a+1|0;c=G[l+(c<<2)>>2];if((c|0)>=0){continue}break}O=i+j|0;E[O-1|0]=d;c=i+1|0;a=0;while(1){n=a;a=a+1|0;c=G[l+(c<<2)>>2];if((c|0)>=0){continue}break}E[O|0]=n;g=(n|0)>17?1:(d|0)>17?1:g;i=i+2|0;m=m+2|0;if((A|0)!=(m|0)){continue}break}}c=0;a=i;if(B){while(1){d=c;c=c+1|0;a=G[l+(a<<2)>>2];if((a|0)>=0){continue}break}E[(i+j|0)-1|0]=d;g=(d|0)>17?1:g}if(!(g&255)){break Ba}Ea:{if(!v){m=0;c=1;if(!T){break Ea}while(1){a=(l+2064|0)+(c<<2)|0;G[a>>2]=((G[a>>2]>>8)/2<<8)+256;G[a+4>>2]=((G[a+4>>2]>>8)/2<<8)+256;c=c+2|0;m=m+2|0;if((A|0)!=(m|0)){continue}break}break Ea}G[l+2064>>2]=0;G[l+4128>>2]=0;G[l>>2]=-2;break Ba}if(B){a=(l+2064|0)+(c<<2)|0;G[a>>2]=((G[a>>2]>>8)/2<<8)+256}G[l+2064>>2]=0;G[l+4128>>2]=0;G[l>>2]=-2;if(!v){continue}break}}Fa=l+5168|0;e=e+1|0;if((p|0)!=(e|0)){continue}break}$=$+1|0;if(($|0)!=4){continue}break}if((r|0)>=18003){zd(3003)}E[o+144|0]=0;E[o+145|0]=1;Fa:{if((p|0)==2){break Fa}E[o+146|0]=2;if((p|0)==3){break Fa}E[o+147|0]=3;if((p|0)==4){break Fa}E[o+148|0]=4;if((p|0)==5){break Fa}E[o+149|0]=5;if((p|0)==6){break Fa}E[o+150|0]=6}if((r|0)>0){m=0;a=H[o+144|0];while(1){l=0;d=b+m|0;c=H[d+1664|0];if((c|0)!=(a&255)){while(1){l=l+1|0;i=l+(o+144|0)|0;e=H[i|0];E[i|0]=a;a=e;if((c|0)!=(a|0)){continue}break}}E[d+19666|0]=l;a=c;m=m+1|0;if((r|0)!=(m|0)){continue}break}}s=z&2147483644;f=z&3;q=(t|0)<-1;g=0;while(1){a=32;l=0;Ga:{if(q){break Ga}d=0;e=0;j=0;if(S>>>0>=3){while(1){c=(M(g,258)+b|0)+37668|0;i=H[c+e|0];a=(a|0)<(i|0)?a:i;n=H[c+(e|1)|0];a=(a|0)<(n|0)?a:n;m=H[c+(e|2)|0];a=(a|0)<(m|0)?a:m;c=H[c+(e|3)|0];a=(a|0)<(c|0)?a:c;i=(i|0)<(l|0)?l:i;i=(i|0)>(n|0)?i:n;i=(i|0)>(m|0)?i:m;l=(c|0)<(i|0)?i:c;e=e+4|0;j=j+4|0;if((s|0)!=(j|0)){continue}break}}if(f){while(1){c=H[((M(g,258)+b|0)+e|0)+37668|0];a=(a|0)<(c|0)?a:c;l=(c|0)<(l|0)?l:c;e=e+1|0;d=d+1|0;if((f|0)!=(d|0)){continue}break}}if(l>>>0>=18){zd(3004)}if((a|0)>0){break Ga}zd(3005)}d=(M(g,1032)+b|0)+39216|0;i=(M(g,258)+b|0)+37668|0;e=0;if((a|0)<=(l|0)){n=k&-2;m=k&1;while(1){c=a;Ha:{if((k|0)<=0){break Ha}a=0;h=0;if((k|0)!=1){while(1){if((c|0)==H[a+i|0]){G[d+(a<<2)>>2]=e;e=e+1|0}j=a|1;if((c|0)==H[j+i|0]){G[d+(j<<2)>>2]=e;e=e+1|0}a=a+2|0;h=h+2|0;if((n|0)!=(h|0)){continue}break}}if(!m|(c|0)!=H[a+i|0]){break Ha}G[d+(a<<2)>>2]=e;e=e+1|0}a=c+1|0;e=e<<1;if((c|0)!=(l|0)){continue}break}}g=g+1|0;if((p|0)!=(g|0)){continue}break}l=0;while(1){a=(o+144|0)+l|0;E[a|0]=0;c=(l<<4)+b|0;e=H[c+88|0]!=0;E[a|0]=e;e=H[c+89|0]?1:e;E[a|0]=e;e=H[c+90|0]?1:e;E[a|0]=e;e=H[c+91|0]?1:e;E[a|0]=e;e=H[c+92|0]?1:e;E[a|0]=e;e=H[c+93|0]?1:e;E[a|0]=e;e=H[c+94|0]?1:e;E[a|0]=e;e=H[c+95|0]?1:e;E[a|0]=e;e=H[c+96|0]?1:e;E[a|0]=e;e=H[c+97|0]?1:e;E[a|0]=e;e=H[c+98|0]?1:e;E[a|0]=e;e=H[c+99|0]?1:e;E[a|0]=e;e=H[c+100|0]?1:e;E[a|0]=e;e=H[c+101|0]?1:e;E[a|0]=e;e=H[c+102|0]?1:e;E[a|0]=e;E[a|0]=H[c+103|0]?1:e;l=l+1|0;if((l|0)!=16){continue}break}d=0;i=G[b+76>>2];e=i;while(1){c=G[b+600>>2];g=G[b+604>>2];Ia:{if(H[(o+144|0)+d|0]){if((g|0)>=8){while(1){E[G[b+44>>2]+e|0]=c>>>24;e=G[b+76>>2]+1|0;G[b+76>>2]=e;c=G[b+600>>2]<<8;G[b+600>>2]=c;a=G[b+604>>2];g=a-8|0;G[b+604>>2]=g;if((a|0)>15){continue}break}}c=-2147483648>>>g|c;break Ia}if((g|0)<8){break Ia}while(1){E[G[b+44>>2]+e|0]=c>>>24;e=G[b+76>>2]+1|0;G[b+76>>2]=e;c=G[b+600>>2]<<8;G[b+600>>2]=c;a=G[b+604>>2];g=a-8|0;G[b+604>>2]=g;if((a|0)>15){continue}break}}G[b+600>>2]=c;g=g+1|0;G[b+604>>2]=g;d=d+1|0;if((d|0)!=16){continue}break}a=0;while(1){if(H[(o+144|0)+a|0]){n=a<<4;d=0;while(1){Ja:{if(H[((d+n|0)+b|0)+88|0]){if((g|0)>=8){while(1){E[G[b+44>>2]+e|0]=c>>>24;e=G[b+76>>2]+1|0;G[b+76>>2]=e;c=G[b+600>>2]<<8;G[b+600>>2]=c;l=G[b+604>>2];g=l-8|0;G[b+604>>2]=g;if((l|0)>15){continue}break}}c=-2147483648>>>g|c;break Ja}if((g|0)<8){break Ja}while(1){E[G[b+44>>2]+e|0]=c>>>24;e=G[b+76>>2]+1|0;G[b+76>>2]=e;c=G[b+600>>2]<<8;G[b+600>>2]=c;l=G[b+604>>2];g=l-8|0;G[b+604>>2]=g;if((l|0)>15){continue}break}}G[b+600>>2]=c;g=g+1|0;G[b+604>>2]=g;d=d+1|0;if((d|0)!=16){continue}break}}a=a+1|0;if((a|0)!=16){continue}break}if(G[b+616>>2]>=3){G[o+48>>2]=e-i;_a(G[24367],67789,o+48|0);g=G[b+604>>2];e=G[b+76>>2]}c=G[b+600>>2];Ka:{if((g|0)<8){a=e;break Ka}a=e;while(1){E[G[b+44>>2]+a|0]=c>>>24;a=G[b+76>>2]+1|0;G[b+76>>2]=a;c=G[b+600>>2]<<8;G[b+600>>2]=c;d=G[b+604>>2];g=d-8|0;G[b+604>>2]=g;if((d|0)>15){continue}break}}c=p<<29-g|c;G[b+600>>2]=c;d=g+3|0;G[b+604>>2]=d;if((g|0)>=5){while(1){E[G[b+44>>2]+a|0]=c>>>24;a=G[b+76>>2]+1|0;G[b+76>>2]=a;c=G[b+600>>2]<<8;G[b+600>>2]=c;i=G[b+604>>2];d=i-8|0;G[b+604>>2]=d;if((i|0)>15){continue}break}}c=r<<17-d|c;G[b+600>>2]=c;m=d+15|0;G[b+604>>2]=m;if((r|0)>0){f=0;while(1){d=0;i=(b+f|0)+19666|0;g=H[i|0];if(g){while(1){if((m|0)>=8){while(1){E[G[b+44>>2]+a|0]=c>>>24;a=G[b+76>>2]+1|0;G[b+76>>2]=a;c=G[b+600>>2]<<8;G[b+600>>2]=c;g=G[b+604>>2];m=g-8|0;G[b+604>>2]=m;if((g|0)>15){continue}break}g=H[i|0]}c=-2147483648>>>m|c;G[b+600>>2]=c;m=m+1|0;G[b+604>>2]=m;d=d+1|0;if(d>>>0<(g&255)>>>0){continue}break}}if((m|0)>=8){while(1){E[G[b+44>>2]+a|0]=c>>>24;a=G[b+76>>2]+1|0;G[b+76>>2]=a;c=G[b+600>>2]<<8;G[b+600>>2]=c;d=G[b+604>>2];m=d-8|0;G[b+604>>2]=m;if((d|0)>15){continue}break}}G[b+600>>2]=c;m=m+1|0;G[b+604>>2]=m;f=f+1|0;if((r|0)!=(f|0)){continue}break}}l=0;n=(t|0)<-1;if(G[b+616>>2]>=3){G[o+32>>2]=a-e;_a(G[24367],67756,o+32|0);m=G[b+604>>2];a=G[b+76>>2]}e=a;while(1){h=M(l,258)+b|0;d=H[h+37668|0];c=G[b+600>>2];if((m|0)>=8){while(1){E[G[b+44>>2]+e|0]=c>>>24;e=G[b+76>>2]+1|0;G[b+76>>2]=e;c=G[b+600>>2]<<8;G[b+600>>2]=c;i=G[b+604>>2];m=i-8|0;G[b+604>>2]=m;if((i|0)>15){continue}break}}c=d<<27-m|c;G[b+600>>2]=c;m=m+5|0;G[b+604>>2]=m;f=0;if(!n){while(1){i=(f+h|0)+37668|0;g=H[i|0];if((g|0)>(d|0)){while(1){if((m|0)>=8){while(1){E[G[b+44>>2]+e|0]=c>>>24;e=G[b+76>>2]+1|0;G[b+76>>2]=e;c=G[b+600>>2]<<8;G[b+600>>2]=c;g=G[b+604>>2];m=g-8|0;G[b+604>>2]=m;if((g|0)>15){continue}break}}c=2<<30-m|c;G[b+600>>2]=c;m=m+2|0;G[b+604>>2]=m;d=d+1|0;g=H[i|0];if((d|0)<(g|0)){continue}break}}if((d|0)>(g|0)){while(1){if((m|0)>=8){while(1){E[G[b+44>>2]+e|0]=c>>>24;e=G[b+76>>2]+1|0;G[b+76>>2]=e;c=G[b+600>>2]<<8;G[b+600>>2]=c;g=G[b+604>>2];m=g-8|0;G[b+604>>2]=m;if((g|0)>15){continue}break}}c=3<<30-m|c;G[b+600>>2]=c;m=m+2|0;G[b+604>>2]=m;d=d-1|0;if((d|0)>H[i|0]){continue}break}}if((m|0)>=8){while(1){E[G[b+44>>2]+e|0]=c>>>24;e=G[b+76>>2]+1|0;G[b+76>>2]=e;c=G[b+600>>2]<<8;G[b+600>>2]=c;i=G[b+604>>2];m=i-8|0;G[b+604>>2]=m;if((i|0)>15){continue}break}}G[b+600>>2]=c;m=m+1|0;G[b+604>>2]=m;f=f+1|0;if((z|0)!=(f|0)){continue}break}}l=l+1|0;if((p|0)!=(l|0)){continue}break}if(G[b+616>>2]>=3){G[o+16>>2]=e-a;_a(G[24367],67771,o+16|0);e=G[b+76>>2]}j=0;c=G[b+628>>2];La:{if((c|0)<=0){l=0;break La}l=0;while(1){m=j+49|0;n=(c|0)>(m|0)?m:c-1|0;a=(b+l|0)+1664|0;if(p>>>0<=H[a|0]){zd(3006)}Ma:{if(!((n-j|0)==49&_)){if((j|0)>(n|0)){break Ma}d=G[b+604>>2];while(1){i=I[(j<<1)+D>>1];c=H[a|0];g=H[(i+(M(c,258)+b|0)|0)+37668|0];i=G[((M(c,1032)+b|0)+(i<<2)|0)+39216>>2];c=G[b+600>>2];if((d|0)>=8){m=G[b+76>>2];while(1){E[G[b+44>>2]+m|0]=c>>>24;m=G[b+76>>2]+1|0;G[b+76>>2]=m;c=G[b+600>>2]<<8;G[b+600>>2]=c;h=G[b+604>>2];d=h-8|0;G[b+604>>2]=d;if((h|0)>15){continue}break}}d=d+g|0;G[b+600>>2]=i<<32-d|c;G[b+604>>2]=d;c=(j|0)!=(n|0);j=j+1|0;if(c){continue}break}break Ma}a=H[a|0];c=(M(a,1032)+b|0)+39216|0;g=(j<<1)+D|0;d=I[g>>1];h=G[c+(d<<2)>>2];i=(M(a,258)+b|0)+37668|0;a=H[i+d|0];d=G[b+600>>2];f=G[b+604>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=a+f|0;d=h<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+2>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+4>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+6>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+8>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+10>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+12>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+14>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+16>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+18>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+20>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+22>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+24>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+26>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+28>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+30>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+32>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+34>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+36>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+38>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+40>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+42>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+44>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+46>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+48>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+50>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+52>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+54>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+56>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+58>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+60>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+62>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g- -64>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+66>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+68>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+70>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+72>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+74>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+76>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+78>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+80>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+82>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+84>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+86>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+88>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+90>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+92>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}f=f+h|0;d=a<<32-f|d;G[b+600>>2]=d;G[b+604>>2]=f;a=I[g+94>>1];h=H[a+i|0];a=G[c+(a<<2)>>2];if((f|0)>=8){j=G[b+76>>2];while(1){E[G[b+44>>2]+j|0]=d>>>24;j=G[b+76>>2]+1|0;G[b+76>>2]=j;d=G[b+600>>2]<<8;G[b+600>>2]=d;k=G[b+604>>2];f=k-8|0;G[b+604>>2]=f;if((k|0)>15){continue}break}}k=a;a=f+h|0;d=k<<32-a|d;G[b+600>>2]=d;G[b+604>>2]=a;g=I[g+96>>1];h=H[g+i|0];k=G[c+(g<<2)>>2];if((a|0)>=8){g=G[b+76>>2];while(1){E[G[b+44>>2]+g|0]=d>>>24;g=G[b+76>>2]+1|0;G[b+76>>2]=g;d=G[b+600>>2]<<8;G[b+600>>2]=d;z=G[b+604>>2];a=z-8|0;G[b+604>>2]=a;if((z|0)>15){continue}break}}j=a+h|0;g=k<<32-j|d;G[b+600>>2]=g;G[b+604>>2]=j;a=I[(m<<1)+D>>1];d=H[a+i|0];a=G[c+(a<<2)>>2];if((j|0)>=8){c=G[b+76>>2];while(1){E[G[b+44>>2]+c|0]=g>>>24;c=G[b+76>>2]+1|0;G[b+76>>2]=c;g=G[b+600>>2]<<8;G[b+600>>2]=g;i=G[b+604>>2];j=i-8|0;G[b+604>>2]=j;if((i|0)>15){continue}break}}c=a;a=d+j|0;G[b+600>>2]=c<<32-a|g;G[b+604>>2]=a}l=l+1|0;c=G[b+628>>2];j=n+1|0;if((c|0)>(j|0)){continue}break}}if((l|0)!=(r|0)){zd(3007)}if(G[b+616>>2]>=3){G[o>>2]=G[b+76>>2]-e;_a(G[24367],74870,o)}Fa=o+208|0}Na:{if(!Ia){break Na}d=G[b+604>>2];Oa:{if((d|0)<=7){a=G[b+600>>2];break Oa}c=G[b+76>>2];a=G[b+600>>2];while(1){E[G[b+44>>2]+c|0]=a>>>24;c=G[b+76>>2]+1|0;G[b+76>>2]=c;a=G[b+600>>2]<<8;G[b+600>>2]=a;e=G[b+604>>2];d=e-8|0;G[b+604>>2]=d;if((e|0)>15){continue}break}}e=d+8|0;G[b+604>>2]=e;a=23<<24-d|a;G[b+600>>2]=a;if((d|0)>=0){c=G[b+76>>2];while(1){E[G[b+44>>2]+c|0]=a>>>24;c=G[b+76>>2]+1|0;G[b+76>>2]=c;a=G[b+600>>2]<<8;G[b+600>>2]=a;d=G[b+604>>2];e=d-8|0;G[b+604>>2]=e;if((d|0)>15){continue}break}}d=e+8|0;G[b+604>>2]=d;a=114<<24-e|a;G[b+600>>2]=a;if((e|0)>=0){c=G[b+76>>2];while(1){E[G[b+44>>2]+c|0]=a>>>24;c=G[b+76>>2]+1|0;G[b+76>>2]=c;a=G[b+600>>2]<<8;G[b+600>>2]=a;e=G[b+604>>2];d=e-8|0;G[b+604>>2]=d;if((e|0)>15){continue}break}}e=d+8|0;G[b+604>>2]=e;a=69<<24-d|a;G[b+600>>2]=a;if((d|0)>=0){c=G[b+76>>2];while(1){E[G[b+44>>2]+c|0]=a>>>24;c=G[b+76>>2]+1|0;G[b+76>>2]=c;a=G[b+600>>2]<<8;G[b+600>>2]=a;d=G[b+604>>2];e=d-8|0;G[b+604>>2]=e;if((d|0)>15){continue}break}}d=e+8|0;G[b+604>>2]=d;a=56<<24-e|a;G[b+600>>2]=a;if((e|0)>=0){c=G[b+76>>2];while(1){E[G[b+44>>2]+c|0]=a>>>24;c=G[b+76>>2]+1|0;G[b+76>>2]=c;a=G[b+600>>2]<<8;G[b+600>>2]=a;e=G[b+604>>2];d=e-8|0;G[b+604>>2]=d;if((e|0)>15){continue}break}}e=d+8|0;G[b+604>>2]=e;a=80<<24-d|a;G[b+600>>2]=a;if((d|0)>=0){c=G[b+76>>2];while(1){E[G[b+44>>2]+c|0]=a>>>24;c=G[b+76>>2]+1|0;G[b+76>>2]=c;a=G[b+600>>2]<<8;G[b+600>>2]=a;d=G[b+604>>2];e=d-8|0;G[b+604>>2]=e;if((d|0)>15){continue}break}}G[b+604>>2]=e+8;G[b+600>>2]=144<<24-e|a;Fq(b,G[b+612>>2]);if(G[b+616>>2]>=2){G[R>>2]=G[b+612>>2];_a(G[24367],68298,R)}if(G[b+604>>2]<=0){break Na}a=G[b+76>>2];c=G[b+600>>2];while(1){E[G[b+44>>2]+a|0]=c>>>24;a=G[b+76>>2]+1|0;G[b+76>>2]=a;c=G[b+600>>2]<<8;G[b+600>>2]=c;e=G[b+604>>2];G[b+604>>2]=e-8;if((e|0)>8){continue}break}}Fa=R+288|0;G[b+8>>2]=1;continue}}function ch(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,I=0,J=0,K=0,P=0,R=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0;j=Fa-13232|0;Fa=j;G[j+13176>>2]=0;k=1;G[j+384>>2]=1;f=G[d>>2];a:{if((f|0)>0){e=f;break a}b:{c:{if((f|0)==-102){break c}i=1;d:{e:{e=f;switch(e+105|0){case 2:break c;case 0:break d;case 1:break e;default:break b}}i=0;m=1;break c}g=1;i=0;k=0}p=m;e=0;G[d>>2]=0;m=i;i=k}G[a>>2]=0;if(G[47541]){e=ji();G[d>>2]=e;if((e|0)>0){break a}}k=b;f:{g:{h:{i:{j:{k:{l:{while(1){n=H[k|0];if((n|0)!=32){m:{if(!n){Ua(54779);break f}n:{if(!i){if(Va(k)>>>0>=1025){Ua(54819);break f}Za(j+12112|0,k);E[j+11072|0]=0;G[j+13152>>2]=1701603686;G[j+13156>>2]=3092282;E[j+1e4|0]=0;E[j+6640|0]=0;E[j+5600|0]=0;E[j+8880|0]=0;E[j+4560|0]=0;E[j+1440|0]=0;break n}dh(k,j+13152|0,j+12112|0,j+11072|0,j+1e4|0,j+8880|0,j+6640|0,j+5600|0,j+4560|0,j+1440|0,d);e=G[d>>2]}if((e|0)>0){Ua(54331);Ua(k);break i}E[j+7680|0]=0;E[j+8720|0]=0;i=0;if(H[j+1e4|0]){e=(Va(j+1e4|0)+j|0)+9999|0;if(H[e|0]==35){E[e|0]=0;i=1}Pj(j+1e4|0,j+13192|0,j+9920|0,j+13188|0,j+13180|0,j+8720|0,j+7680|0,d);e=G[d>>2];if((e|0)>0){break a}}E[j+2480|0]=0;E[j+3520|0]=0;o:{if(!H[j+11072|0]){break o}if(H[j+4560|0]?1:H[j+6640|0]|H[j+8720|0]){Za(j+3520|0,j+11072|0);E[j+11072|0]=0;break o}if(!(H[j+8880|0]|H[j+5600|0])){break o}Za(j+2480|0,j+11072|0);E[j+11072|0]=0}y=j+13152|0;e=j+12112|0;D=j+1e4|0;t=j+8880|0;r=j+6640|0;s=j+5600|0;l=g;g=Fa-7312|0;Fa=g;x=j+13216|0;G[x>>2]=0;n=c;p:{q:{if(!c){break q}B=Za(g,e);if(!Ib(y,42193)){if(Oj(B,d)){break q}}w=(n|0)!=1;c=-1;e=0;while(1){r:{o=G[(e<<2)+1243184>>2];if(!o){break r}s:{t:{if(G[o+24>>2]){if(Ib(y,42193)){break r}A=G[o+12>>2];if(Va(A)>>>0>=1025){Ua(54862);break s}A=Za(g+6240|0,A);if(Oj(A,d)){break q}if(Xa(B,A)){break r}u:{if(!l){if(H[t|0]|H[r|0]){break r}A=H[s|0];if(!(w|(A|0)!=0)){break u}c=A?c:e;break r}c=e;if(w){break r}}break t}dh(G[o+12>>2],g+7280|0,g+6240|0,g+4160|0,g+5200|0,g+3120|0,g+2080|0,g+1040|0,0,0,d);if(G[d>>2]>0){Ua(54425);Ua(G[o+12>>2]);break q}if(!Ib(g+7280|0,42193)){if(Oj(g+6240|0,d)){break q}}if(Xa(y,g+7280|0)){break r}if(Xa(B,g+6240|0)){break r}v:{if(H[s|0]|H[g+1040|0]?1:H[t|0]|H[g+3120|0]|(H[r|0]|H[g+2080|0])){if(Xa(t,g+3120|0)){break r}if(Xa(r,g+2080|0)){break r}if(Xa(s,g+1040|0)){break r}A=Xa(D,g+5200|0);if(!(w|(A|0)!=0)){break v}c=A?c:e;break r}c=e;if(w){break r}}}c=e;if(G[o+84>>2]){break r}Ua(32763);Ua(k)}G[d>>2]=104;c=104;break p}e=e+1|0;if((e|0)!=1e4){continue}break}if((c|0)<0){break q}c=G[(c<<2)+1243184>>2];e=lb(1,8);G[a>>2]=e;if(!e){Ua(54617);Ua(k);G[d>>2]=113;c=113;break p}G[e>>2]=0;G[e+4>>2]=c;G[c+8>>2]=G[c+8>>2]+1;if(H[r|0]){E[D|0]=0}E[t|0]=0;E[r|0]=0;E[s|0]=0;G[x>>2]=1}c=G[d>>2]}Fa=g+7312|0;if((c|0)>0){break i}g=0;if(!G[j+13216>>2]){g=G[310142];while(1){if((g|0)<=0){break m}g=g-1|0;if(Xa(M(g,84)+1240576|0,j+13152|0)){continue}break}G[d>>2]=0;c=G[(M(g,84)+1240576|0)+40>>2];w:{if(!c){break w}e=j+13152|0;r=Za(j+11040|0,e);c=Ja[c|0](e,j+12112|0,j+11072|0)|0;G[d>>2]=c;if(c){Ua(54576);Ua(k);break i}if(!Xa(r,j+13152|0)){break w}g=G[310142];while(1){if((g|0)<=0){break l}g=g-1|0;if(Xa(M(g,84)+1240576|0,j+13152|0)){continue}break}G[d>>2]=0}x:{c=G[(M(g,84)+1240576|0)+44>>2];if(c){c=Ja[c|0](j+12112|0,n,j+13184|0)|0;G[d>>2]=c;if((c|0)<=0){break x}Ua(54675);Ua(k);break i}Ua(54279);Ua(k);break f}c=M(g,84)+1240576|0;e=Ja[G[c+64>>2]](G[j+13184>>2],j+13208|0)|0;G[d>>2]=e;if((e|0)>0){Ja[G[c+56>>2]](G[j+13184>>2])|0;Ua(54727);Ua(k);break i}e=lb(1,8);G[a>>2]=e;if(!e){Ja[G[(M(g,84)+1240576|0)+56>>2]](G[j+13184>>2])|0;Ua(54617);Ua(k);break g}c=lb(1,1736);G[e+4>>2]=c;if(!c){Ja[G[(M(g,84)+1240576|0)+56>>2]](G[j+13184>>2])|0;Ua(54617);Ua(k);Wa(G[a>>2]);G[a>>2]=0;break g}r=Va(k)+1|0;r=ab((r|0)>32?r:32);G[c+12>>2]=r;if(!r){Ja[G[(M(g,84)+1240576|0)+56>>2]](G[j+13184>>2])|0;Ua(54376);Ua(k);Wa(G[G[a>>2]+4>>2]);Wa(G[a>>2]);G[a>>2]=0;break g}o=lb(1001,8);G[c+96>>2]=o;if(!o){Ja[G[(M(g,84)+1240576|0)+56>>2]](G[j+13184>>2])|0;Ua(54168);Ua(k);Wa(G[G[G[a>>2]+4>>2]+12>>2]);Wa(G[G[a>>2]+4>>2]);Wa(G[a>>2]);G[a>>2]=0;break g}o=lb(40,2880);G[c+1252>>2]=o;y:{z:{if(o){cb(c+1256|0,255,160);o=c+1728|0;G[o>>2]=38;G[o+4>>2]=39;o=c+1720|0;G[o>>2]=36;G[o+4>>2]=37;o=c+1712|0;G[o>>2]=34;G[o+4>>2]=35;o=c+1704|0;G[o>>2]=32;G[o+4>>2]=33;o=c+1696|0;G[o>>2]=30;G[o+4>>2]=31;o=c+1688|0;G[o>>2]=28;G[o+4>>2]=29;o=c+1680|0;G[o>>2]=26;G[o+4>>2]=27;o=c+1672|0;G[o>>2]=24;G[o+4>>2]=25;o=c+1664|0;G[o>>2]=22;G[o+4>>2]=23;o=c+1656|0;G[o>>2]=20;G[o+4>>2]=21;o=c+1648|0;G[o>>2]=18;G[o+4>>2]=19;o=c+1640|0;G[o>>2]=16;G[o+4>>2]=17;o=c+1632|0;G[o>>2]=14;G[o+4>>2]=15;o=c+1624|0;G[o>>2]=12;G[o+4>>2]=13;o=c+1616|0;G[o>>2]=10;G[o+4>>2]=11;o=c+1608|0;G[o>>2]=8;G[o+4>>2]=9;o=c+1600|0;G[o>>2]=6;G[o+4>>2]=7;o=c+1592|0;G[o>>2]=4;G[o+4>>2]=5;o=c+1584|0;G[o>>2]=2;G[o+4>>2]=3;G[c+1576>>2]=0;G[c+1580>>2]=1;G[c+92>>2]=1e3;o=G[j+13184>>2];G[c+4>>2]=g;G[c>>2]=o;Za(r,k);g=G[j+13208>>2];r=G[j+13212>>2];G[c+128>>2]=-1;G[c+132>>2]=-1;G[c+84>>2]=n;G[c+40>>2]=g;G[c+44>>2]=r;G[c+32>>2]=g;G[c+36>>2]=r;G[c+72>>2]=-1;G[c+24>>2]=l;G[c+20>>2]=i;G[c+16>>2]=555;G[c+8>>2]=1;i=0;Hc(e,0,0,d);c=G[a>>2];if(G[d>>2]>0){break y}n=G[c+4>>2];break z}Ja[G[(M(g,84)+1240576|0)+56>>2]](G[j+13184>>2])|0;Ua(54224);Ua(k);Wa(G[G[G[a>>2]+4>>2]+96>>2]);Wa(G[G[G[a>>2]+4>>2]+12>>2]);Wa(G[G[a>>2]+4>>2]);Wa(G[a>>2]);G[a>>2]=0;break g}while(1){A:{e=i<<2;g=e+1243184|0;if(!G[g>>2]){break A}e=e+1243184|0;g=e+4|0;if(!G[g>>2]){break A}g=e+8|0;if(!G[g>>2]){break A}g=e+12|0;if(!G[g>>2]){break A}g=e+16|0;if(!G[g>>2]){break A}i=i+5|0;if((i|0)!=1e4){continue}break y}break}G[g>>2]=n;c=G[a>>2]}if((Wf(c,j+13224|0,d)|0)>0){Ua(67445);Ua(k);if(G[d>>2]==252){Ua(44068)}Qb(G[a>>2],d);G[a>>2]=0;break i}g=H[j+11072|0]!=0}if(H[j+1e4|0]){c=G[j+13192>>2];B:{if(c){mb(G[a>>2],c+1|0,j+13224|0,d);break B}if(!H[j+9920|0]){break B}Je(G[a>>2],G[j+13180>>2],j+9920|0,G[j+13188>>2],d)}if(G[d>>2]<=0){break j}Ua(37207);C:{if((c|0)>0){G[j+16>>2]=c;k=j+1072|0;Ya(k,81,44578,j+16|0);break C}G[j+64>>2]=j+9920;b=j+1072|0;Ya(b,81,48820,j- -64|0);Ua(b);b=G[j+13188>>2];if(b){G[j+48>>2]=b;b=j+1072|0;Ya(b,81,48850,j+48|0);Ua(b)}k=44598;b=G[j+13180>>2];if((b|0)==-1){break C}G[j+32>>2]=G[(b<<2)+141388>>2];b=j+1072|0;Ya(b,81,48785,j+32|0);Ua(b)}Ua(k);Qb(G[a>>2],d);G[a>>2]=0;break i}if(!(H[j+8720|0]|((f|0)==-102|m|p)|(H[j+5600|0]|H[j+8880|0]))){if(!H[j+6640|0]){break j}}G[j+13220>>2]=G[G[a>>2]>>2]+1;if(G[j+13220>>2]!=1){break j}Qd(G[a>>2],j+384|0,d);if((m^-1)&G[j+384>>2]!=0){break j}if(xi(G[a>>2],j+13224|0,d)){break k}while(1){c=G[j+13224>>2];D:{if(!c&m|(c|0)!=0&p){break D}if(!c){Qd(G[a>>2],j+384|0,d);if(G[j+384>>2]<=0){break D}break j}E[j+8800|0]=0;G[j+13176>>2]=0;c=j+8800|0;Cb(G[a>>2],16,35480,c,0,j+13176|0);if(Sb(c,34885)){break D}if(Sb(j+8800|0,17342)){break D}if(gc(j+8800|0,35609,8)){break j}}if(!xi(G[a>>2],j+13224|0,d)){continue}break}break k}}else{k=k+1|0;continue}break}G[d>>2]=124;Ua(54530);Ua(j+13152|0);Ua(k);break i}G[d>>2]=124;Ua(54482);Ua(k);Ua(j+13152|0);break i}if(G[d>>2]==107){G[d>>2]=0}mb(G[a>>2],1,j+13224|0,d)}E:{F:{G:{H:{I:{if(H[j+8720|0]){J:{if(E[j+7680|0]-48>>>0<=9){G[j>>2]=j+13204;Qc(j+7680|0,27698,j);if(G[j+13204>>2]>0){break J}Ua(37590);break h}g=G[a>>2];e=j+7680|0;f=j+13204|0;c=Fa-32|0;Fa=c;k=G[d>>2];K:{if(k){break K}L:{if(fh(g,e,c+24|0,c+20|0,c+28|0,c,d)){break L}M:{e=G[c+20>>2];N:{if((e|0)<0){G[c+20>>2]=0-e;if(G[c+24>>2]!=14|(e|0)!=-1){break N}G[f>>2]=0;if(!H[(G[309722]+M(G[309725],344)|0)+88|0]){break L}zi(g,c+20|0,d);if(!G[c+20>>2]){break L}G[f>>2]=1;break L}if(G[c+24>>2]!=14){break N}if((e|0)==1){break M}}Yd();Ua(43091);k=432;G[d>>2]=432;break K}G[f>>2]=0;if(($f(G[309728],G[309729],0,0,37,f,d)|0)!=-1){break L}G[d>>2]=0}Yd();k=G[d>>2]}Fa=c+32|0;if((k|0)>0){Ua(37162);Ua(j+7680|0);Ua(37538);Ua(j+1e4|0);Qb(G[a>>2],d);G[a>>2]=0;break i}if(G[j+13204>>2]){break J}Ua(39430);break h}O:{if(!(H[j+4560|0]|!H[j+3520|0])){Za(j+11072|0,j+3520|0);break O}E[j+11080|0]=H[41194];c=H[41190]|H[41191]<<8|(H[41192]<<16|H[41193]<<24);G[j+11072>>2]=H[41186]|H[41187]<<8|(H[41188]<<16|H[41189]<<24);G[j+11076>>2]=c}if((sd(j+13228|0,j+11072|0,d)|0)>0){Ua(37483);Ua(j+11072|0);break i}p=G[a>>2];r=G[j+13228>>2];o=j+8720|0;t=G[j+13204>>2];n=Fa-30960|0;Fa=n;cb(n+576|0,0,81);bb(n+16|0,141408,560);e=G[d>>2];P:{if((e|0)>0){break P}Q:{if((dc(p,0,o,n+952|0,d)|0)>0){Ua(36498);Ua(o);break Q}if((yc(p,G[n+952>>2],t,t>>31,1,0,1,0,0,n+808|0,n+800|0,n+768|0,n+820|0,n+948|0,n+940|0,n+848|0,n+840|0,n+816|0,n+856|0,n+832|0,n+956|0,n+824|0,n+960|0,d)|0)>0){break Q}c=n+576|0;f=n+936|0;zb(92041,G[n+952>>2],c,f);fo(p,0,c,o,n+952|0,f);if(G[n+956>>2]!=2){Ua(44105);Ua(43386);e=227;G[d>>2]=227;break P}c=G[n+948>>2];R:{if((c|0)<0){G[n+944>>2]=1;f=G[n+860>>2];G[n+864>>2]=G[n+856>>2];G[n+868>>2]=f;G[n+948>>2]=0-c;break R}c=G[n+952>>2];s=n+864|0;l=Fa-336|0;Fa=l;G[l+156>>2]=0;if(G[d>>2]<=0){f=l+80|0;zb(34647,c,f,d);E[l+160|0]=0;if((kc(p,f,l+240|0,l+156|0)|0)<=0){mc(l+240|0,l+160|0,0,l+156|0)}E[l|0]=0;fd(l+160|0,l,l+156|0);k=Fa-144|0;Fa=k;S:{if(G[d>>2]>0){break S}f=G[p>>2];if((f|0)!=G[G[p+4>>2]+76>>2]){mb(p,f+1|0,0,d)}T:{if((c|0)>0){f=G[p+4>>2];if((c|0)<=G[f+936>>2]){break T}}G[d>>2]=302;break S}w=c-1|0;y=G[f+968>>2];U:{if(!H[l|0]){G[n+944>>2]=1;c=y+M(w,160)|0;f=G[c+92>>2];G[s>>2]=G[c+88>>2];G[s+4>>2]=f;break U}G[n+944>>2]=0;V:{W:{g=jb(l,40);if(g){m=1;f=0;while(1){c=g+1|0;G[k+140>>2]=c;v=vb(c,k+140|0);g=G[n+944>>2];B=(g|0)>=9;v=v+.1;X:{if(O(v)<0x8000000000000000){e=O(v)>=1?~~(v>0?Q(S(v*2.3283064365386963e-10),4294967295):T((v-+(~~v>>>0>>>0))*2.3283064365386963e-10))>>>0:0;i=~~v>>>0;break X}e=-2147483648;i=0}c=e;if(!B){e=s+(g<<3)|0;G[e>>2]=i;G[e+4>>2]=c}if((c|0)<0){Ua(58151);break W}G[n+944>>2]=g+1;e=G[k+140>>2];g=jb(e,44);G[k+140>>2]=g;m=Au(m,f,i,c);f=Ia;if(g){continue}break}if(!jb(e,41)){G[k+16>>2]=l;Ya(k+48|0,81,9840,k+16|0);break V}c=y+M(w,160)|0;if(G[c+80>>2]<=0){break U}e=G[c+88>>2];c=G[c+92>>2];if((m|0)==(e|0)&(f|0)==(c|0)){break U}L[k+40>>3]=+(m>>>0)+ +(f|0)*4294967296;L[k+32>>3]=+(e>>>0)+ +(c|0)*4294967296;c=k+48|0;Ya(c,81,19587,k+32|0);Ua(c);break W}G[k>>2]=l;Ya(k+48|0,81,9840,k);break V}Ua(l)}G[d>>2]=263}}Fa=k+144|0}Fa=l+336|0}if(G[d>>2]>0){Ua(24558);break Q}Y:{Z:{_:{$:{aa:{ba:{ca:{da:{ea:{c=G[n+948>>2];switch(c-11|0){case 10:break Z;case 1:case 2:case 4:case 5:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break _;case 0:case 3:break $;case 31:break ca;case 30:break da;default:break ea}}switch(c-81|0){case 0:break aa;case 1:break ba;default:break _}}e=32;c=G[n+856>>2];g=G[n+860>>2]<<2|c>>>30;c=c<<2;break Y}e=-32;c=G[n+856>>2];g=G[n+860>>2]<<2|c>>>30;c=c<<2;break Y}e=-64;c=G[n+856>>2];g=G[n+860>>2]<<3|c>>>29;c=c<<3;break Y}e=64;c=G[n+856>>2];g=G[n+860>>2]<<3|c>>>29;c=c<<3;break Y}e=8;g=G[n+860>>2];c=G[n+856>>2];break Y}Ua(37725);Ua(o);Ua(n+768|0);Ua(43208);e=261;G[d>>2]=261;break P}e=16;c=G[n+856>>2];g=G[n+860>>2]<<1|c>>>31;c=c<<1}f=g;i=G[n+944>>2];m=n+864|0;g=G[d>>2];if((g|0)<=0){k=G[r>>2];g=G[r+4>>2];if((k|0)!=G[g+76>>2]){mb(r,k+1|0,0,d);g=G[r+4>>2];k=G[g+76>>2]}l=G[g+96>>2]+(k<<3)|0;if(G[g+104>>2]!=G[l>>2]|G[g+108>>2]!=G[l+4>>2]){Ke(r,d)}Yi(r,e,i,m,d);g=G[d>>2]}if((g|0)>0){Ua(21879);break Q}uk(p,r,9,n+16|0,70,G[n+952>>2],d);G[n+4>>2]=o;G[n>>2]=t;Ya(n+672|0,81,48947,n);sh(p,0,d);Jb(p,G[n+848>>2],G[n+852>>2],1,d);g=c>>>0<3e4&(f|0)<=0|(f|0)<0;e=g?c:3e4;g=g?f:0;i=n+960|0;ic(p,e,g,i,d);ld(r,1,0,1,0,e,g,i,d);m=c-e|0;f=f-((c>>>0>>0)+g|0)|0;fa:{if(!(m|f)){break fa}c=e+1|0;g=c?g:g+1|0;e=c;while(1){if(G[d>>2]>0){break fa}i=m>>>0<3e4&(f|0)<=0|(f|0)<0;c=i?m:3e4;i=i?f:0;l=G[p+4>>2];k=Ja[G[(M(G[l+4>>2],84)+1240576|0)+76>>2]](G[l>>2],n+960|0,c)|0;ga:{if((k|0)!=107){if((k|0)<=0){break ga}Ua(38146);Ua(G[l+12>>2]);l=108}else{l=107}G[d>>2]=l}ld(r,1,0,e,g,c,i,n+960|0,d);g=g+i|0;l=c+e|0;g=l>>>0>>0?g+1|0:g;e=l;f=f-((c>>>0>m>>>0)+i|0)|0;m=m-c|0;if(f|m){continue}break}}Rb(r,d)}e=G[d>>2]}Fa=n+30960|0;if((e|0)<=0){break I}Ua(36385);Ua(j+1e4|0);Qb(G[a>>2],d);G[a>>2]=0;break i}if(!H[j+5600|0]){break E}if(g){break G}if($m(j+13152|0)){break G}if(H[j+11072|0]|!H[j+2480|0]){break H}Za(j+11072|0,j+2480|0);break F}Qb(G[a>>2],d);G[a>>2]=G[j+13228>>2];if(H[j+5600|0]){break G}g=1;break E}E[j+11080|0]=H[41194];c=H[41190]|H[41191]<<8|(H[41192]<<16|H[41193]<<24);G[j+11072>>2]=H[41186]|H[41187]<<8|(H[41188]<<16|H[41189]<<24);G[j+11076>>2]=c;break F}G[G[G[a>>2]+4>>2]+84>>2]=1;E[j+11072|0]=0}g=1;f=j+5600|0;p=0;m=0;o=0;l=Fa-544|0;Fa=l;G[l+532>>2]=-1;G[l+524>>2]=0;G[l+520>>2]=0;G[l+188>>2]=0;ha:{ia:{ja:{ka:{c=j+11072|0;if(!H[c|0]){break ka}if((sd(l+540|0,c,d)|0)>0){Ua(50586);break ja}G[l+536>>2]=G[G[a>>2]>>2]+1;c=G[a>>2];e=G[G[c+4>>2]+20>>2];c=mb(c,1,0,d);la:{if(!e){if((c|0)<=0){c=1;while(1){ne(G[a>>2],G[l+540>>2],d);c=c+1|0;if((mb(G[a>>2],c,0,d)|0)<=0){continue}break}}c=G[d>>2];if((c|0)==107){G[d>>2]=0;break la}if((c|0)<=0){break la}Qb(G[l+540>>2],d);Ua(50681);break ja}ne(G[a>>2],G[l+540>>2],d);mb(G[a>>2],G[l+536>>2],0,d);ne(G[a>>2],G[l+540>>2],d);if(G[d>>2]>0){Qb(G[l+540>>2],d);Ua(50681);break ja}G[l+536>>2]=2}Qb(G[a>>2],d);c=G[l+540>>2];G[a>>2]=c;if((mb(c,G[l+536>>2],0,d)|0)<=0){break ka}Ua(50738);break ja}c=f+4|0;ma:{na:{oa:{pa:{qa:{ra:{while(1){f=H[c|0];if((f|0)!=32){sa:{if((f|0)==64){if(Nj(c+1|0,l+188|0,d)){break ja}e=G[l+188>>2];while(1){c=e;e=c+1|0;if(H[c|0]==32){continue}break}}G[l+520>>2]=0;pk(G[a>>2],l+524|0,l+520|0);e=c;f=Fa-16|0;Fa=f;ta:while(1){ua:{va:{wa:{xa:{ya:{za:{Aa:{Ba:{Ca:{Da:{k=H[e|0];switch(k|0){case 0:break wa;case 40:break xa;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 35:case 36:case 37:case 38:case 41:case 42:case 43:break ya;case 39:break za;case 34:break Aa;case 44:break Ca;default:break Da}}if((k|0)==91){break Ba}if((k|0)!=123){break ya}k=1;G[f+12>>2]=e+1;if(!ii(f+12|0)){break va}break wa}E[e|0]=59;G[f+12>>2]=e+1;e=G[f+12>>2];continue}k=1;G[f+12>>2]=e+1;if(!hi(f+12|0)){break va}break wa}e=e+1|0;G[f+12>>2]=e;while(1){i=H[e|0];if(!i){k=1;break wa}if((i|0)==34){G[f+12>>2]=e+1;e=G[f+12>>2];continue ta}else{e=e+1|0;continue}}}e=e+1|0;G[f+12>>2]=e;while(1){i=H[e|0];if(!i){k=1;break wa}if((i|0)==39){G[f+12>>2]=e+1;e=G[f+12>>2];continue ta}else{e=e+1|0;continue}}}G[f+12>>2]=e+1;break va}k=1;G[f+12>>2]=e+1;if(!gi(f+12|0)){break va}}Fa=f+16|0;break ua}e=G[f+12>>2];continue}break}if(k){break ia}if(G[d>>2]){break qa}B=l+351|0;n=l+352|1;while(1){if(H[c|0]==32){while(1){f=H[c+1|0];c=c+1|0;if((f|0)==32){continue}break}}e=qc(c,36383);Ea:{if(!e){break Ea}f=lb(e+1|0,1);if(!f){Ua(48441);G[d>>2]=113;break Ea}f=qb(f,c,e);if((e|0)<=0){m=f;break Ea}D=c+e|0;x=H[D|0];E[e+f|0]=0;c=f;t=c;Fa:{Ga:{Ha:{Ia:{switch(H[c|0]-32|0){case 1:case 13:e=f+1|0;Ja:{c=H[f+1|0];if(!c){break Ja}Ka:{i=Va(e);if((i|0)<2){break Ka}if((c|0)==35){break Ja}i=f+i|0;if(H[i|0]!=43){break Ka}E[i|0]=0;while(1){La:{G[l+12>>2]=0;G[d>>2]=0;dc(G[a>>2],0,e,l+532|0,d);c=G[d>>2];if(c?(c|0)!=237:0){break La}if((wk(G[a>>2],G[l+532>>2],l+12|0)|0)>0){Ua(37876);Ua(f);if(p){Wa(p)}c=G[l+188>>2];if(c){Wa(c)}Wa(f);c=G[l+12>>2];G[d>>2]=c;break ha}G[l+524>>2]=G[l+524>>2]-1;u=1;if(G[d>>2]==237){continue}}break}G[d>>2]=0;G[l+532>>2]=-1;e=0;break Fa}if((c|0)==35){break Ja}if((dc(G[a>>2],0,e,l+532|0,d)|0)>0&G[d>>2]!=237){break Ja}G[d>>2]=0;if((wk(G[a>>2],G[l+532>>2],d)|0)>0){Ua(37876);Ua(f);if(p){Wa(p)}c=G[l+188>>2];if(!c){break ma}Wa(c);break ma}G[l+532>>2]=-1;G[l+524>>2]=G[l+524>>2]-1;u=1;break Ha}df();c=0;G[d>>2]=0;i=H[f+1|0]==35?f+2|0:e;e=Va(i);Ma:{if((e|0)<2){break Ma}e=(e+i|0)-1|0;if(H[e|0]!=43){break Ma}E[e|0]=0;c=1}Na:{Oa:{if(jb(i,63)){break Oa}if(jb(i,42)){break Oa}if(!jb(i,35)){break Na}}ef(G[a>>2],1,d)}while(1){e=c;if((kf(G[a>>2],i,d)|0)>0){if(!(!e|G[d>>2]!=202)){df();break Ga}Ua(36552);Ua(i);if(p){Wa(p)}c=G[l+188>>2];if(!c){break ma}Wa(c);Wa(f);break ja}c=1;if(e){continue}break};break Ha;case 0:while(1){e=H[c+1|0];t=c+1|0;c=t;if((e|0)==32){continue}break};break;default:break Ia}}Pa:{k=qc(t,36176);if(k){c=lb(k+1|0,1);if(c){break Pa}Ua(48441);G[d>>2]=113}Ua(39537);Ua(f);if(p){Wa(p)}c=G[l+188>>2];if(c){Wa(c)}Wa(f);c=G[d>>2];if(c){break ha}break na}c=qb(c,t,k);if(Va(c)>>>0>=71){Ua(39699);Ua(f);if(p){Wa(p)}e=G[l+188>>2];if(e){Wa(e)}Wa(f);Wa(c);break na}i=Za(l+352|0,c);Wa(c);Qa:{Ra:{Sa:{if(H[i|0]!=35){break Sa}e=jb(n,35);c=Va(i);if((e|0)!=(c+B|0)){break Sa}e=G[l+532>>2];if((e|0)<=0){Ua(37835);Ua(i);Ua(3358);Ua(26610);c=G[l+188>>2];if(!c){break oa}Wa(c);break oa}E[(c+i|0)-1|0]=0;zb(n,e,l+272|0,d);e=n;c=G[d>>2];if(!c){break Ra}break ha}if((jb(i,35)|0)!=(Va(i)+B|0)|G[l+532>>2]<=0){break Qa}G[l+520>>2]=0;dc(G[a>>2],0,i,l+528|0,l+520|0);c=G[l+520>>2];if(!c|(c|0)==237){break Qa}df();c=Za(l+112|0,i);ba=(Va(c)+c|0)-1|0,ca=0,E[ba|0]=ca;zb(c,G[l+532>>2],l+272|0,d);if(G[d>>2]){c=G[l+188>>2];if(!c){break ma}Wa(c);Wa(f);break ja}G[l+520>>2]=0;e=i;if(kc(G[a>>2],l+272|0,l+16|0,l+520|0)){break Qa}}Za(e,l+272|0)}e=k+t|0;Ta:{if(H[e|0]==40){Ua:{Va:{Wa:{if(G[d>>2]){break Wa}c=qc(e,64244);if(!c){break Wa}k=lb(c+1|0,1);if(k){break Va}Ua(48441);G[d>>2]=113}c=Va(i)+i|0;E[c|0]=41;E[c+1|0]=0;break Ua}k=qb(k,e,c);if((Va(k)+Va(i)|0)-70>>>0<=4294967224){Ua(39650);c=G[l+188>>2];if(c){Wa(c)}Wa(f);Wa(k);break na}r=Gb(i,k);r=Va(r)+r|0;E[r|0]=41;E[r+1|0]=0;Wa(k);e=c+e|0}c=0;break Ta}c=1}while(1){if(!c){e=e+1|0;c=1;continue}c=H[e|0];if((c|0)!=32){if((c|0)!=61){dc(G[a>>2],0,i,l+528|0,d);c=G[d>>2];if((c|0)==237){while(1){c=G[l+528>>2];G[l+532>>2]=c;o=1;if(!p){p=lb(999,4)}G[((c<<2)+p|0)-4>>2]=1;dc(G[a>>2],0,i,l+528|0,d);c=G[d>>2];if((c|0)==237){continue}break}if((c|0)==219){break Ga}}if((c|0)<=0){c=G[l+528>>2];G[l+532>>2]=c;o=1;if(!p){p=lb(999,4)}G[((c<<2)+p|0)-4>>2]=1;break Ha}if((c|0)==999){break Ga}Ua(38943);Ua(e);if(p){Wa(p)}c=G[l+188>>2];if(!c){break oa}Wa(c);Wa(f);break na}if(H[e+1|0]==61){c=e+2|0;while(1){e=c;c=c+1|0;if(H[e|0]==32){continue}break}Xa:{Ya:{Za:{if(G[d>>2]){break Za}c=qc(e,68332);if(!c){break Za}k=lb(c+1|0,1);if(k){break Ya}Ua(48441);G[d>>2]=113}E[l+272|0]=0;break Xa}c=qb(k,e,c);if(Va(c)>>>0>=71){Ua(39594);e=G[l+188>>2];if(e){Wa(e)}Wa(f);Wa(c);break na}Za(l+272|0,c);Wa(c)}if((dc(G[a>>2],0,l+272|0,l+532|0,d)|0)<=0){c=l+432|0;zb(35402,G[l+532>>2],c,d);if((gj(G[a>>2],c,i,0,d)|0)>0){Ua(21946);Ua(36165);Ua(l+272|0);Ua(36154);Ua(i);if(p){Wa(p)}c=G[l+188>>2];if(!c){break ma}Wa(c);Wa(f);break ja}o=1;if(!p){p=lb(999,4)}G[((G[l+532>>2]<<2)+p|0)-4>>2]=1;break Ha}df();G[d>>2]=0;if((pl(G[a>>2],l+272|0,i,d)|0)<=0){break Ha}Ua(36600);Ua(f);if(p){Wa(p)}c=G[l+188>>2];if(!c){break ma}Wa(c);Wa(f);break ja}E[l+192|0]=0;_a:{$a:{ab:{bb:{cb:{c=G[d>>2];db:{if(c){break db}if(H[i|0]==32){while(1){c=H[i+1|0];i=i+1|0;if((c|0)==32){continue}break}}c=qc(i,64753);if(!c){c=0;break db}k=lb(c+1|0,1);if(k){break cb}Ua(48441);c=113;G[d>>2]=113}E[l+272|0]=0;if(H[i|0]!=40){break _a}if(!c){break bb}break ab}k=qb(k,i,c);if(Va(k)>>>0>=71){Ua(50634);if(p){Wa(p)}c=G[l+188>>2];if(c){Wa(c)}Wa(f);Wa(k);break na}Za(l+272|0,k);Wa(k);i=c+i|0;if(H[i|0]!=40){break _a}}c=i+1|0;if(H[i+1|0]==32){while(1){i=H[c+1|0];c=c+1|0;if((i|0)==32){continue}break}}i=qc(c,64244);if(!i){break ab}k=lb(i+1|0,1);if(k){break $a}Ua(48441);G[d>>2]=113}E[l+192|0]=0;break _a}c=qb(k,c,i);if(Va(c)>>>0>=71){Ua(50634);if(p){Wa(p)}e=G[l+188>>2];if(e){Wa(e)}Wa(f);Wa(c);break na}Za(l+192|0,c);Wa(c)}r=G[a>>2];i=e+1|0;c=l+272|0;e=l+192|0;t=0;w=Fa-16|0;Fa=w;G[w+12>>2]=1;G[w+8>>2]=2147483647;k=Fa-240|0;Fa=k;s=G[d>>2];eb:{if(s){break eb}fb:{gb:{if(fh(r,i,k+216|0,k+204|0,k+212|0,k+176|0,d)){break gb}s=G[k+204>>2];i=s;if((i|0)<0){i=0-s|0;G[k+204>>2]=i}G[k+164>>2]=0;hb:{ib:{jb:{kb:{if((dc(r,0,c,k+164|0,d)|0)==219){G[d>>2]=0;lb:{mb:{nb:{if(H[c|0]==35){if((s|0)>=0){Yd();Ua(62856);break fb}c=c+1|0;ob:{if(Ib(c,32708)){if(Ib(c,33332)){break nb}if(G[k+216>>2]!=16){break ob}break nb}if(G[k+216>>2]==16){break nb}}Yd();Ua(62804);break fb}if((s|0)>=0){break mb}if((kc(r,c,k+80|0,d)|0)==202){G[k+164>>2]=-1;break lb}if(G[d>>2]){break gb}}s=G[k+164>>2];if((s|0)<0){break lb}break hb}G[k+164>>2]=-1}G[d>>2]=0;pk(r,k+164|0,d);G[k+164>>2]=G[k+164>>2]+1;pb:{qb:{if(e){s=H[e|0];if(s){break qb}}if(G[309736]==2){G[k>>2]=i;e=k- -64|0;Ya(e,15,27698,k);rb:{sb:{tb:{ub:{vb:{wb:{i=G[k+216>>2];switch(i-14|0){case 1:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:break pb;case 2:break sb;case 27:break ub;case 0:break vb;default:break wb}}xb:{switch(i-81|0){case 0:break rb;case 1:break tb;default:break xb}}if((i|0)!=1){break pb}i=k- -64|0;i=Va(i)+i|0;E[i|0]=88;E[i+1|0]=0;break pb}i=k- -64|0;i=Va(i)+i|0;E[i|0]=76;E[i+1|0]=0;break pb}i=k- -64|0;i=Va(i)+i|0;E[i|0]=74;E[i+1|0]=0;break pb}i=k- -64|0;i=Va(i)+i|0;E[i|0]=68;E[i+1|0]=0;break pb}i=k- -64|0;i=Va(i)+i|0;E[i|0]=65;E[i+1|0]=0;break pb}i=k- -64|0;i=Va(i)+i|0;E[i|0]=75;E[i+1|0]=0;break pb}e=k- -64|0;yb:{zb:{Ab:{Bb:{s=G[k+216>>2];switch(s-14|0){case 1:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:break pb;case 2:break yb;case 27:break zb;case 0:break Ab;default:break Bb}}if((s|0)==1){break yb}if((s|0)!=82){break pb}i=H[40291]|H[40292]<<8|(H[40293]<<16|H[40294]<<24);E[k+67|0]=i;E[k+68|0]=i>>>8;E[k+69|0]=i>>>16;E[k+70|0]=i>>>24;G[k+64>>2]=H[40288]|H[40289]<<8|(H[40290]<<16|H[40291]<<24);break pb}Yd();Ua(23377);s=227;G[d>>2]=227;break eb}G[k+64>>2]=3223881;break pb}G[k+16>>2]=i;Ya(k- -64|0,16,26859,k+16|0);break pb}if(G[309736]!=2|(s<<24>>24)-58>>>0>4294967285){break pb}if(!(G[k+216>>2]!=1|(s|0)!=66)){i=i+7>>>3|0;G[k+204>>2]=i}G[k+36>>2]=e;G[k+32>>2]=i;e=k- -64|0;Ya(e,16,8745,k+32|0)}Bi(r,G[k+164>>2],c,e,d);i=G[k+212>>2];if((i|0)>=2){il(r,G[k+164>>2],i,k+176|0,d)}i=k+55|0;zb(34755,G[k+164>>2],i,d);if((kc(r,i,k+80|0,d)|0)!=202){break ib}G[d>>2]=0;Cb:{switch(G[309736]-1|0){case 0:break kb;case 1:break Cb;default:break ib}}Vf(e,k+208|0,k+172|0,k+168|0,d);s=255;y=0;Db:{Eb:{Fb:{Gb:{i=G[k+208>>2];switch(i-11|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break ib;case 0:break Db;case 20:case 30:break Eb;case 10:break Fb;default:break Gb}}if((i|0)!=81){break ib}s=0;y=-2147483648;break Db}s=-32768;y=-1;break Db}s=-2147483648;y=-1}hd(r,k+55|0,s,y,19871,d);t=G[k+164>>2];i=Fa-16|0;Fa=i;Hb:{if(G[d>>2]>0){break Hb}if((Dc(r,i+12|0,d)|0)<=0){if(G[i+12>>2]!=2){G[d>>2]=227;break Hb}t=(G[G[r+4>>2]+968>>2]+M(t,160)|0)-48|0;G[t>>2]=s;G[t+4>>2]=y}}break jb}if(G[d>>2]){break gb}i=k- -64|0;zb(34647,G[k+164>>2],i,d);kc(r,i,k+80|0,d);s=G[d>>2];Ib:{Jb:{if((s|0)!=202){if(s){break Ib}il(r,G[k+164>>2],G[k+212>>2],k+176|0,d);break Jb}G[d>>2]=0;df();i=G[k+212>>2];if((i|0)<2){break Jb}il(r,G[k+164>>2],i,k+176|0,d)}s=G[d>>2]}if(s){break gb}break ib}lc(r,k+55|0,34769,17971,d);t=G[k+164>>2];i=Fa-16|0;Fa=i;Kb:{if(G[d>>2]>0){break Kb}if((Dc(r,i+12|0,d)|0)<=0){if(G[i+12>>2]!=1){G[d>>2]=226;break Kb}t=(G[G[r+4>>2]+968>>2]+M(t,160)|0)-40|0;E[t|0]=0;qb(t,34769,19)}}}Fa=i+16|0;t=1}s=G[k+164>>2]}if((s|0)>0){Ec(r,40853,k+48|0,0,d);c=G[309728];if(ki(c,d)){break gb}e=G[k+164>>2];c=G[309729]+M(c,244)|0;G[c+84>>2]=2;G[c+80>>2]=0;G[c+4>>2]=e;G[c>>2]=r;G[309728]=G[309728]+1;G[k+220>>2]=0;c=G[w+12>>2];i=G[w+8>>2]-c|0;e=i+1|0;G[k+228>>2]=e;s=G[309728];J=G[309729];y=c-1|0;Lb:{if(!(G[w+12>>2]!=1|(i|0)<9)){c=0;if(G[w+8>>2]==G[k+48>>2]){break Lb}}c=e}Mb:{if(($f(s,J,y,c,34,k+216|0,d)|0)==-1){G[d>>2]=0;break Mb}if(G[d>>2]){break gb}}if(!t|G[k+232>>2]){break gb}kf(r,k+55|0,d);break gb}i=G[309725];t=G[309722];Nb:{Ob:{Pb:{Qb:{s=G[k+216>>2];switch(s-14|0){case 1:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:break gb;case 2:break Nb;case 0:break Ob;case 27:break Pb;default:break Qb}}if((s|0)==1){break Nb}if((s|0)!=82){break gb}Kd(r,c,L[(t+M(i,344)|0)+88>>3],15,e,d);break gb}s=c;c=G[(t+M(i,344)|0)+88>>2];Gc(r,s,c,c>>31,e,d);break gb}Kh(r,c,E[(t+M(i,344)|0)+88|0],e,d);break gb}if(!Ib(c,32708)){ze(r,(t+M(i,344)|0)+88|0,d);break gb}i=(t+M(i,344)|0)+88|0;if(!Ib(c,33332)){Pg(r,i,d);break gb}Gl(r,c,i,e,d)}Yd();s=G[d>>2];break eb}s=432;G[d>>2]=432}Fa=k+240|0;Fa=w+16|0;if((s|0)>0){Ua(15043);if(p){Wa(p)}c=G[l+188>>2];if(!c){break ma}Wa(c);Wa(f);break ja}G[l+520>>2]=0;dc(G[a>>2],0,l+272|0,l+528|0,l+520|0);if(!G[l+520>>2]){c=G[l+528>>2];G[l+532>>2]=c;o=1;if(!p){p=lb(999,4)}G[((c<<2)+p|0)-4>>2]=1;c=G[l+524>>2];if((c|0)>=G[l+532>>2]){break Ha}G[l+524>>2]=c+1;break Ha}df()}else{c=0;continue}break}}e=G[d>>2];break Fa}G[d>>2]=0;e=0}c=D+((x|0)==59)|0;Wa(f);if(!e){continue}}break}if(u|!o){break sa}c=G[l+524>>2];if((c|0)<=0){break sa}while(1){Rb:{f=c-1|0;if(G[(f<<2)+p>>2]){break Rb}if((wk(G[a>>2],c,d)|0)<=0){break Rb}Ua(37876);Ua(m);Wa(p);c=G[l+188>>2];if(c){Wa(c)}if(m){break pa}break ja}e=c>>>0>1;c=f;if(e){continue}break}break ra}}else{c=c+1|0;continue}break}if(!p){break qa}}Wa(p)}c=G[l+188>>2];if(c){Wa(c)}if(!m){break ja}}Wa(m);break ja}Wa(f)}c=125;G[d>>2]=125;break ha}Wa(f)}c=G[d>>2];break ha}Ua(14957);Ua(c);c=G[l+188>>2];if(c){Wa(c)}c=431;G[d>>2]=431}Fa=l+544|0;if((c|0)<=0){break E}Ua(54018);Ua(37048);Ua(j+5600|0);Qb(G[a>>2],d);G[a>>2]=0;break i}k=0;Sb:{if(!H[j+8880|0]){break Sb}Dc(G[a>>2],j+13224|0,d);if(!G[j+13224>>2]){c=H[j+11072|0];Tb:{if(!(c|!H[j+2480|0])){Za(j+11072|0,j+2480|0);break Tb}if(c){break Tb}E[j+11080|0]=H[40798];c=H[40794]|H[40795]<<8|(H[40796]<<16|H[40797]<<24);G[j+11072>>2]=H[40790]|H[40791]<<8|(H[40792]<<16|H[40793]<<24);G[j+11076>>2]=c}f=j+8880|0;z=Fa-16|0;Fa=z;c=j+11072|0;Ub:{if((sd(z+12|0,c,d)|0)>0){Ua(37e3);Ua(c);break Ub}G[z+8>>2]=G[G[a>>2]>>2]+1;i=G[a>>2];if(!G[G[i+4>>2]+20>>2]){e=1;m=G[z+8>>2];if((m|0)>1){Vb:{while(1){Wb:{mb(G[a>>2],e,0,d);if((ne(G[a>>2],G[z+12>>2],d)|0)>0){break Wb}e=e+1|0;m=G[z+8>>2];if((e|0)<(m|0)){continue}break Vb}break}Qb(G[z+12>>2],d);break Ub}i=G[a>>2]}mb(i,m,0,d);i=G[a>>2]}u=G[z+12>>2];t=0;h=Fa-432|0;Fa=h;c=G[35500];G[h+416>>2]=c;e=G[35499];g=G[35498];G[h+408>>2]=g;G[h+412>>2]=e;q=G[35497];m=G[35496];G[h+400>>2]=m;G[h+404>>2]=q;n=G[35495];l=G[35494];G[h+392>>2]=l;G[h+396>>2]=n;p=G[35493];r=G[35492];G[h+384>>2]=r;G[h+388>>2]=p;G[h+368>>2]=c;G[h+360>>2]=g;G[h+364>>2]=e;G[h+352>>2]=m;G[h+356>>2]=q;G[h+344>>2]=l;G[h+348>>2]=n;G[h+336>>2]=r;G[h+340>>2]=p;G[h+320>>2]=c;G[h+312>>2]=g;G[h+316>>2]=e;G[h+304>>2]=m;G[h+308>>2]=q;G[h+296>>2]=l;G[h+300>>2]=n;G[h+288>>2]=r;G[h+292>>2]=p;G[h+272>>2]=c;G[h+264>>2]=g;G[h+268>>2]=e;G[h+256>>2]=m;G[h+260>>2]=q;G[h+248>>2]=l;G[h+252>>2]=n;G[h+240>>2]=r;G[h+244>>2]=p;c=G[d>>2];Xb:{if((c|0)>0){break Xb}Eg(i,h+428|0,d);Qd(i,h+424|0,d);Yb:{Zb:{if((de(i,G[h+424>>2],h+384|0,d)|0)>0){break Zb}c=G[h+424>>2];if(c-5>>>0<=4294967291){Ua(6803);break Yb}pd(u,G[h+428>>2],c,h+384|0,d);Td(i,h+420|0,0,d);c=4;if(G[h+420>>2]>=4){while(1){e=h- -64|0;Sd(i,c,e,d);if((mk(e)|0)>=21){wb(u,h- -64|0,d)}e=G[h+420>>2]>(c|0);c=c+1|0;if(e){continue}break}}if(G[d>>2]>0){Ua(24227);break Zb}G[h+236>>2]=f;if(G[h+424>>2]>0){while(1){q=h+236|0;g=Fa-96|0;Fa=g;G[g+12>>2]=0;c=G[d>>2];_b:{if((c|0)>0){break _b}$b:{ac:{bc:{cc:{if(!Rf(q,39477,g+12|0,g+92|0,d)){F[g+16>>1]=42;break cc}c=G[g+12>>2];if(Va(c)>>>0>=71){Ua(61573);Wa(c);break $b}e=Za(g+16|0,c);Wa(c);G[g+12>>2]=0;c=H[e|0];if((c|0)!=42){break bc}}G[h+380>>2]=1;c=0;break ac}if(!((c|0)!=45|H[e+1|0]!=42)){G[h+380>>2]=0;c=1;break ac}if(!G[g+92>>2]){break $b}c=G[q>>2];if(H[c|0]!=58){break $b}ba=h,ca=_b(e),G[ba+380>>2]=ca;G[q>>2]=c+1;m=Rf(q,39477,g+12|0,g+92|0,d);c=G[g+12>>2];if(!(G[g+92>>2]?m:0)){if(!c){break $b}Wa(c);break $b}if(Va(c)>>>0>=71){Ua(61573);Wa(c);break $b}e=Za(e,c);Wa(c);G[g+12>>2]=0;c=_b(e)}G[h+376>>2]=c;s=1;e=G[q>>2];if(H[e|0]==58){G[q>>2]=e+1;e=Rf(q,49007,g+12|0,g+92|0,d);c=G[g+12>>2];dc:{ec:{if(!(G[g+92>>2]?e:0)){if(c){break ec}break $b}if(Va(c)>>>0<71){break dc}Ua(61573)}Wa(c);break $b}e=Za(g+16|0,c);Wa(c);G[g+12>>2]=0;s=_b(e);e=G[q>>2]}G[h+372>>2]=s;w=H[e|0];fc:{if((w|0)!=44){c=e;break fc}c=e+1|0;G[q>>2]=c;w=H[e+1|0]}if((w|0)==32){while(1){e=c+1|0;G[q>>2]=e;m=H[c+1|0];c=e;if((m|0)==32){continue}break}}if((G[h+380>>2]|G[h+376>>2])<0|(s|0)<=0){break $b}c=G[d>>2];break _b}c=125;G[d>>2]=125}Fa=g+96|0;if((c|0)>0){Ua(36921);Ua(f);break Zb}e=G[h+376>>2];gc:{if(!e){e=G[(h+384|0)+(t<<2)>>2];G[h+376>>2]=e;o=G[h+380>>2];c=e;break gc}g=G[h+380>>2];c=G[(h+384|0)+(t<<2)>>2];o=g?g:c;G[h+380>>2]=o}if(!((c|0)>=(o|0)&(c|0)>=(e|0))){Ua(38574);Ua(f);break Yb}c=t<<2;G[c+(h+288|0)>>2]=e;G[c+(h+336|0)>>2]=o;g=c+(h+240|0)|0;m=G[h+372>>2];G[g>>2]=m;l=c+(h+16|0)|0;q=(e|0)<(o|0);c=(m+(q?o-e|0:e-o|0)|0)/(m|0)|0;G[l>>2]=c;t=t+1|0;m=h+160|0;zb(33788,t,m,d);Ad(u,m,c,c>>31,0,d);if(!((o|0)==1&G[g>>2]==1)){c=-1;while(1){zb(32948,t,h+160|0,d);m=(c|0)==-1;if(!m){n=h+160|0;n=Va(n)+n|0;E[n|0]=c+65;E[n+1|0]=0}G[h+60>>2]=0;hc:{if(Cb(i,82,h+160|0,h+8|0,0,h+60|0)){break hc}if((e|0)>=(o|0)){v=L[h+8>>3]-+(o|0)}else{v=+(o|0)-L[h+8>>3]}v=v/+G[g>>2]+1;L[h+8>>3]=v;Jd(u,h+160|0,v,15,d);if(G[g>>2]==1&(e|0)>=(o|0)){break hc}zb(33351,t,h+160|0,d);if(!m){n=h+160|0;n=Va(n)+n|0;E[n|0]=c+65;E[n+1|0]=0}G[h+60>>2]=0;if(!Cb(i,82,h+160|0,h,0,h+60|0)){n=G[g>>2];v=L[h>>3]*+(((e|0)<(o|0)?0-n|0:n)|0);L[h>>3]=v;Jd(u,h+160|0,v,15,d)}zb(31915,t,h+160|0,d);if(!m){m=h+160|0;m=Va(m)+m|0;E[m|0]=c+65;E[m+1|0]=0}G[h+60>>2]=0;E[h+162|0]=49;if(!Cb(i,82,h+160|0,h,0,h+60|0)){m=G[g>>2];v=L[h>>3]*+((q?0-m|0:m)|0);L[h>>3]=v;Jd(u,h+160|0,v,15,d)}G[h+60>>2]=0;E[h+162|0]=50;if(!Cb(i,82,h+160|0,h,0,h+60|0)){m=G[g>>2];v=L[h>>3]*+((q?0-m|0:m)|0);L[h>>3]=v;Jd(u,h+160|0,v,15,d)}G[h+60>>2]=0;E[h+162|0]=51;if(!Cb(i,82,h+160|0,h,0,h+60|0)){m=G[g>>2];v=L[h>>3]*+((q?0-m|0:m)|0);L[h>>3]=v;Jd(u,h+160|0,v,15,d)}G[h+60>>2]=0;E[h+162|0]=52;if(!Cb(i,82,h+160|0,h,0,h+60|0)){m=G[g>>2];v=L[h>>3]*+((q?0-m|0:m)|0);L[h>>3]=v;Jd(u,h+160|0,v,15,d)}G[h+60>>2]=0;E[h+162|0]=53;if(!Cb(i,82,h+160|0,h,0,h+60|0)){m=G[g>>2];v=L[h>>3]*+((q?0-m|0:m)|0);L[h>>3]=v;Jd(u,h+160|0,v,15,d)}G[h+60>>2]=0;E[h+162|0]=54;if(!Cb(i,82,h+160|0,h,0,h+60|0)){m=G[g>>2];v=L[h>>3]*+((q?0-m|0:m)|0);L[h>>3]=v;Jd(u,h+160|0,v,15,d)}G[h+60>>2]=0;E[h+162|0]=55;if(!Cb(i,82,h+160|0,h,0,h+60|0)){m=G[g>>2];v=L[h>>3]*+((q?0-m|0:m)|0);L[h>>3]=v;Jd(u,h+160|0,v,15,d)}G[h+60>>2]=0;E[h+162|0]=56;if(!Cb(i,82,h+160|0,h,0,h+60|0)){m=G[g>>2];v=L[h>>3]*+((q?0-m|0:m)|0);L[h>>3]=v;Jd(u,h+160|0,v,15,d)}G[h+60>>2]=0;E[h+162|0]=57;if(Cb(i,82,h+160|0,h,0,h+60|0)){break hc}m=G[g>>2];v=L[h>>3]*+((q?0-m|0:m)|0);L[h>>3]=v;Jd(u,h+160|0,v,15,d)}c=c+1|0;if((c|0)!=26){continue}break}}if(G[h+424>>2]>(t|0)){continue}break}}if((Rb(u,d)|0)>0){break Zb}mq(i,d);mq(u,d);f=G[h+428>>2];c=f>>31;n=G[h+16>>2];o=ab(M(n,(c^f)-c>>>3|0));if(!o){Ua(14142);c=113;G[d>>2]=113;break Xb}D=G[h+340>>2];A=G[h+292>>2];ic:{if((D|0)>(A|0)){c=G[h+244>>2];r=(c+(D-A|0)|0)/(c|0)|0;break ic}c=G[h+244>>2];r=(c+(A-D|0)|0)/(c|0)|0}y=G[h+344>>2];x=G[h+296>>2];jc:{if((y|0)>(x|0)){w=G[h+248>>2];l=(w+(y-x|0)|0)/(w|0)|0;break jc}w=G[h+248>>2];l=(w+(x-y|0)|0)/(w|0)|0}t=G[h+348>>2];B=G[h+300>>2];kc:{if((t|0)>(B|0)){c=G[h+252>>2];p=(c+(t-B|0)|0)/(c|0)|0;break kc}c=G[h+252>>2];p=(c+(B-t|0)|0)/(c|0)|0}lc:{if((p|0)<=0){break lc}if((l|0)>0){if((r|0)>0){s=n>>31;m=1;while(1){c=M(G[h+252>>2],C);c=t+((t|0)>(B|0)?0-c|0:c)|0;G[h+348>>2]=c;G[h+300>>2]=c;w=0;while(1){c=0;e=M(G[h+248>>2],w);e=y+((x|0)<(y|0)?0-e|0:e)|0;G[h+344>>2]=e;G[h+296>>2]=e;g=m;q=g>>31;f=q;while(1){e=M(G[h+244>>2],c);e=D+((A|0)<(D|0)?0-e|0:e)|0;G[h+340>>2]=e;G[h+292>>2]=e;mc:{nc:{oc:{pc:{qc:{e=G[h+428>>2];if((e|0)<=7){if((e|0)==-64){break qc}if((e|0)!=-32){break mc}hq(i,G[h+424>>2],h+384|0,h+336|0,h+288|0,h+240|0,N(-9119119840596153e-51),o,h+56|0,d);Ek(u,1,m,f,n,s,o,N(-9119119840596153e-51),d);break mc}rc:{switch(e-8|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:break mc;case 0:break nc;case 8:break oc;case 24:break pc;default:break rc}}if((e|0)!=64){break mc}Xp(i,G[h+424>>2],h+384|0,h+336|0,h+288|0,h+240|0,o,h+56|0,d);Gk(u,m,f,n,s,o,d);break mc}dq(i,G[h+424>>2],h+384|0,h+336|0,h+288|0,h+240|0,-91191291391491e-49,o,h+56|0,d);Zo(u,m,f,n,s,o,-91191291391491e-49,d);break mc}Vp(i,G[h+424>>2],h+384|0,h+336|0,h+288|0,h+240|0,o,h+56|0,d);Fk(u,m,f,n,s,o,d);break mc}Mp(i,G[h+424>>2],h+384|0,h+336|0,h+288|0,h+240|0,o,h+56|0,d);Rk(u,m,f,n,s,o,d);break mc}rp(i,G[h+424>>2],h+384|0,h+336|0,h+288|0,h+240|0,o,h+56|0,d);Sk(u,m,f,n,s,o,d)}e=f+s|0;g=m+n|0;e=g>>>0>>0?e+1|0:e;m=g;f=e;c=c+1|0;if((r|0)!=(c|0)){continue}break}w=w+1|0;if((l|0)!=(w|0)){continue}break}C=C+1|0;if((p|0)!=(C|0)){continue}break}break lc}c=M(p-1|0,c);c=t+((t|0)>(B|0)?0-c|0:c)|0;G[h+300>>2]=c;G[h+348>>2]=c;c=M(l-1|0,w);c=y+((x|0)<(y|0)?0-c|0:c)|0;G[h+344>>2]=c;G[h+296>>2]=c;break lc}c=M(p-1|0,c);c=t+((t|0)>(B|0)?0-c|0:c)|0;G[h+300>>2]=c;G[h+348>>2]=c}Wa(o);c=G[d>>2];if((c|0)<=0){break Xb}Ua(14195)}c=G[d>>2];break Xb}c=212;G[d>>2]=212}Fa=h+432|0;if((c|0)>0){Qb(G[z+12>>2],d);break Ub}e=G[z+8>>2]+1|0;sc:{c=G[a>>2];if(G[G[c+4>>2]+20>>2]){break sc}if((mb(c,e,0,d)|0)<=0){while(1){ne(G[a>>2],G[z+12>>2],d);e=e+1|0;if((mb(G[a>>2],e,0,d)|0)<=0){continue}break}}c=G[d>>2];if((c|0)==107){G[d>>2]=0;break sc}if((c|0)<=0){break sc}Qb(G[z+12>>2],d);break Ub}Qb(G[a>>2],d);c=G[z+12>>2];G[a>>2]=c;f=G[z+8>>2];if((f|0)!=(e-1|0)){mb(c,f,0,d);break Ub}if((Rb(c,d)|0)<=0){break Ub}Qb(G[a>>2],d)}Fa=z+16|0;if(G[d>>2]<=0){break Sb}Ua(53904);Ua(36735);Ua(j+8880|0);Qb(G[a>>2],d);G[a>>2]=0;break i}if(H[j+6640|0]){zi(G[a>>2],j+13200|0,d);c=G[j+13200>>2];k=lb(c,1);if(!k){Ua(53842);Ua(36833);Ua(j+8880|0);Qb(G[a>>2],d);G[a>>2]=0;break g}if((hn(G[a>>2],j+8880|0,1,c,j+13196|0,k,d)|0)<=0){break Sb}Ua(53969);Ua(36833);Ua(j+8880|0);Wa(k);Qb(G[a>>2],d);G[a>>2]=0;break i}tc:{uc:{if(g){break uc}if($m(j+13152|0)){break uc}c=H[j+11072|0];if(!(c|!H[j+2480|0])){Za(j+11072|0,j+2480|0);break tc}if(c){break tc}E[j+11080|0]=H[40798];c=H[40794]|H[40795]<<8|(H[40796]<<16|H[40797]<<24);G[j+11072>>2]=H[40790]|H[40791]<<8|(H[40792]<<16|H[40793]<<24);G[j+11076>>2]=c;break tc}G[G[G[a>>2]+4>>2]+84>>2]=1;E[j+11072|0]=0}f=j+8880|0;x=Fa-16|0;Fa=x;vc:{wc:{A=j+11072|0;xc:{if(H[A|0]){if((sd(x+12|0,A,d)|0)>0){Ua(23216);Ua(A);break vc}G[x+8>>2]=G[G[a>>2]>>2]+1;c=G[a>>2];yc:{if(!G[G[c+4>>2]+20>>2]){e=1;m=G[x+8>>2];if((m|0)<=1){break yc}while(1){zc:{mb(G[a>>2],e,0,d);if((ne(G[a>>2],G[x+12>>2],d)|0)>0){break zc}e=e+1|0;m=G[x+8>>2];if((e|0)<(m|0)){continue}break yc}break}Qb(G[x+12>>2],d);break vc}mb(c,1,0,d);if((ne(G[a>>2],G[x+12>>2],d)|0)>0){break wc}m=G[x+8>>2]}mb(G[a>>2],m,0,d);e=wo(G[a>>2],G[x+12>>2],d);c=G[x+12>>2];if((e|0)>0){Qb(c,d);break vc}Ad(c,40853,0,0,0,d);e=G[x+12>>2];c=G[e+4>>2];G[c+944>>2]=0;G[c+948>>2]=0;G[c+952>>2]=0;G[c+956>>2]=0;if((Rb(e,d)|0)<=0){e=G[x+12>>2];t=G[a>>2];break xc}Qb(G[x+12>>2],d);break vc}e=G[a>>2];G[x+12>>2]=e;t=e}o=e;u=Fa-96|0;Fa=u;e=G[d>>2];Ac:{if(e){break Ac}Bc:{Cc:{if(fh(t,f,u+72|0,u- -64|0,u+68|0,u+32|0,d)){break Cc}e=G[u+64>>2];p=e;if((e|0)<0){p=0-e|0;G[u+64>>2]=p}if(!(G[u+72>>2]==14&(p|0)==1)){Yd();Ua(43091);e=432;G[d>>2]=432;break Ac}c=G[t>>2];if((c|0)!=G[G[t+4>>2]+76>>2]){mb(t,c+1|0,0,d)}if(G[d>>2]){break Cc}c=G[t+4>>2];i=G[c+952>>2];f=G[c+956>>2];n=f;if(!(f|i)){break Cc}C=G[c+960>>2];r=G[c+984>>2];s=G[c+988>>2];g=G[o>>2];c=G[o+4>>2];if((g|0)!=G[c+76>>2]){mb(o,g+1|0,0,d);c=G[o+4>>2]}if(G[c+132>>2]<0){Rb(o,d)}if(G[d>>2]){break Cc}g=C;c=g>>31;J=g;D=c;c=G[o+4>>2];f=G[c+960>>2];g=f>>31;m=G[c+956>>2];B=m;w=G[c+952>>2];Dc:{if(m|w){y=G[c+988>>2];l=G[c+984>>2];break Dc}G[c+984>>2]=0;G[c+988>>2]=0;y=0;l=0}if((f|0)!=(J|0)|(g|0)!=(D|0)){Ua(4328);Yd();e=436;G[d>>2]=436;break Ac}c=ab(i+1|0);G[u+84>>2]=i;G[u+80>>2]=0;G[u+76>>2]=c;Ec:{Fc:{Gc:{if(!c){Ua(14248);break Gc}E[c+i|0]=0;Hc:{if((e|0)<0){p=H[(G[309722]+M(G[309725],344)|0)+88|0];Ic:{if(!i&(n|0)<=0|(n|0)<0){break Ic}m=0;f=0;c=i;e=n-!c|0;c=c-1|0;if(!e&c>>>0>=3|e){c=i&-4;while(1){E[m+G[u+76>>2]|0]=p;E[G[u+76>>2]+(m|1)|0]=p;E[G[u+76>>2]+(m|2)|0]=p;E[G[u+76>>2]+(m|3)|0]=p;g=f;f=m+4|0;g=f>>>0<4?g+1|0:g;m=f;f=g;g=q;e=I+4|0;g=e>>>0<4?g+1|0:g;I=e;q=g;if((c|0)!=(e|0)|(n|0)!=(g|0)){continue}break}}g=i&3;c=0;if(!(g|c)){break Ic}while(1){E[m+G[u+76>>2]|0]=p;q=f;f=m+1|0;q=f?q:q+1|0;m=f;f=q;e=h;q=z+1|0;e=q?e:e+1|0;z=q;h=e;if((g|0)!=(q|0)|(c|0)!=(e|0)){continue}break}}p=p?i:0;break Hc}p=0;$f(G[309728],G[309729],0,0,34,u+72|0,d);if(!i&(n|0)<=0|(n|0)<0){break Hc}K=i&3;c=G[u+76>>2];Jc:{if((!i|0)==(n|0)&i-1>>>0<3){m=0;f=0;break Jc}e=i&-4;m=0;f=0;while(1){p=((((H[c+m|0]!=0)+p|0)+(H[c+(m|1)|0]!=0)|0)+(H[c+(m|2)|0]!=0)|0)+(H[c+(m|3)|0]!=0)|0;g=f;f=m+4|0;g=f>>>0<4?g+1|0:g;m=f;f=g;g=q;q=I+4|0;g=q>>>0<4?g+1|0:g;I=q;q=g;if((e|0)!=(I|0)|(n|0)!=(g|0)){continue}break}}if(!(K|P)){break Hc}while(1){p=(H[c+m|0]!=0)+p|0;e=f;f=m+1|0;e=f?e:e+1|0;m=f;f=e;e=z+1|0;q=e?h:h+1|0;z=e;h=q;if((K|0)!=(e|0)|(P|0)!=(h|0)){continue}break}}if(G[d>>2]){break Ec}q=C;C=ab((q|0)>5e5?q:5e5);if(C){break Fc}}Yd();e=113;G[d>>2]=113;break Ac}m=1;c=5e5/(q|0)|0;h=(c|0)>1?c:1;z=(o|0)!=(t|0);Kc:{if(!z){f=G[u+76>>2];e=1;while(1){c=e;e=c+1|0;m=c;if(H[(c+f|0)-1|0]){continue}break}break Kc}c=w+1|0;if((c|0)<2){break Kc}Ig(o,w,B,p,p>>31,d)}f=M(h,q);I=f;K=f>>31;f=0;while(1){e=0;Lc:{Mc:{while(1){if(H[(m+G[u+76>>2]|0)-1|0]){ee(t,m,f,1,0,J,D,C+M(e,q)|0,d);e=e+1|0;if((h|0)==(e|0)){break Mc}}if(!G[d>>2]){g=f;f=m+1|0;g=f?g:g+1|0;m=f;f=g;if((f|0)<=(n|0)&i>>>0>=m>>>0|(f|0)<(n|0)){continue}}break}if(!e){break Lc}f=M(e,q);ld(o,c,c>>31,1,0,f,f>>31,C,d);c=c+e|0;break Lc}ld(o,c,c>>31,1,0,I,K,C,d);c=c+h|0;if(G[d>>2]){break Lc}e=m+1|0;f=e?f:f+1|0;m=e;if((f|0)<=(n|0)&e>>>0<=i>>>0|(f|0)<(n|0)){continue}}break}Nc:{if(!z){f=c>>31;if(c>>>0>i>>>0&(f|0)>=(n|0)|(f|0)>(n|0)){break Nc}g=n-((c>>>0>i>>>0)+f|0)|0;e=(i-c|0)+1|0;g=e?g:g+1|0;xk(t,c,f,e,g,d);break Nc}if(!(r|s)|!p){break Nc}c=G[o>>2];e=G[o+4>>2];if((c|0)!=G[e+76>>2]){mb(o,c+1|0,0,d);e=G[o+4>>2]}f=G[e+128>>2];h=G[e+132>>2];c=y+G[e+980>>2]|0;g=l+G[e+976>>2]|0;c=g>>>0>>0?c+1|0:c;i=g;e=c;c=i+2879|0;g=c>>>0<2879?e+1|0:e;c=Cu(c,g);q=c;c=0;c=2879-(((c|0)!=0)+q|0)|0;g=0;if(r>>>0>c>>>0&(s|0)>=(g|0)|(g|0)<(s|0)){q=(r-c|0)+2879|0;c=s-((c>>>0>r>>>0)+g|0)|0;Bf(o,Bu(q,q>>>0<2879?c+1|0:c,2880,0),1,d)}g=s+y|0;c=l+r|0;g=c>>>0>>0?g+1|0:g;Gc(o,33303,c,g,0,d);c=f;g=c+i|0;f=e+h|0;f=c>>>0>g>>>0?f+1|0:f;m=g;c=G[t>>2];e=G[t+4>>2];if((c|0)!=G[e+76>>2]){mb(t,c+1|0,0,d);e=G[t+4>>2]}q=G[e+128>>2];c=q+G[e+976>>2]|0;g=G[e+980>>2]+G[e+132>>2]|0;z=c;h=c>>>0>>0?g+1|0:g;while(1){if(!G[d>>2]){Jb(t,z,h,0,d);e=r>>>0<5e5&(s|0)<=0|(s|0)<0?r:5e5;g=e;c=e>>31;q=e;ic(t,e,c,C,d);Jb(o,m,f,1,d);Wb(o,e,c,C,d);e=c+f|0;g=m+g|0;e=g>>>0>>0?e+1|0:e;m=g;f=e;g=c+h|0;e=q+z|0;g=e>>>0>>0?g+1|0:g;z=e;h=g;s=s-((q>>>0>r>>>0)+c|0)|0;r=r-q|0;if(s|r){continue}}break}if(!(l|y)){break Nc}e=1;c=G[o+4>>2];if(G[c+936>>2]<=0|(p|0)<=0){break Nc}g=(p>>31)+B|0;f=p+w|0;g=f>>>0

>>0?g+1|0:g;i=f;while(1){m=w;f=B;if(G[(G[c+968>>2]+M(e,160)|0)-80>>2]<0){while(1){c=f;f=m+1|0;c=f?c:c+1|0;m=f;f=c;Le(o,e,m,c,u+24|0,u+16|0,d);q=y+G[u+20>>2]|0;c=l+G[u+16>>2]|0;q=c>>>0>>0?q+1|0:q;G[u+16>>2]=c;G[u+20>>2]=q;ph(o,e,m,f,G[u+24>>2],G[u+28>>2],c,q,d);if((f|0)<=(g|0)&i>>>0>m>>>0|(f|0)<(g|0)){continue}break}c=G[o+4>>2]}f=G[c+936>>2]>(e|0);e=e+1|0;if(f){continue}break}}Wa(C)}c=G[u+76>>2];Oc:{if(c){Wa(c);break Oc}G[u+4>>2]=412;G[u>>2]=30721;kb(74371,u)}Yd();$n(o,d);break Bc}Yd()}e=G[d>>2]}Fa=u+96|0;c=H[A|0];if((e|0)>0){if(!c){break vc}Qb(G[x+12>>2],d);break vc}if(!c){break vc}c=G[a>>2];Pc:{if(!G[G[c+4>>2]+20>>2]){e=G[x+8>>2]+1|0;if((mb(c,e,0,d)|0)<=0){while(1){ne(G[a>>2],G[x+12>>2],d);e=e+1|0;if((mb(G[a>>2],e,0,d)|0)<=0){continue}break}}c=G[d>>2];if((c|0)==107){G[d>>2]=0;break Pc}if((c|0)<=0){break Pc}Qb(G[x+12>>2],d);break vc}G[x+8>>2]=2}Qb(G[a>>2],d);c=G[x+12>>2];G[a>>2]=c;mb(c,G[x+8>>2],0,d);break vc}Qb(G[x+12>>2],d)}Fa=x+16|0;if(G[d>>2]>0){Ua(53958);Ua(36833);Ua(j+8880|0);Qb(G[a>>2],d);G[a>>2]=0;break i}ze(G[a>>2],38410,d);ze(G[a>>2],b,d)}if(H[j+6640|0]){Qc:{if(!(H[j+4560|0]|!H[j+3520|0])){Za(j+11072|0,j+3520|0);break Qc}E[j+11080|0]=H[40505];c=H[40501]|H[40502]<<8|(H[40503]<<16|H[40504]<<24);G[j+11072>>2]=H[40497]|H[40498]<<8|(H[40499]<<16|H[40500]<<24);G[j+11076>>2]=c}h=j+6640|0;o=j+80|0;m=j+464|0;n=j+432|0;q=j+400|0;l=j+1072|0;p=j+784|0;r=j+496|0;s=j+392|0;t=j+1360|0;u=0;C=0;g=Fa-96|0;Fa=g;G[g+12>>2]=0;Rc:{if(G[d>>2]>0){break Rc}G[j+380>>2]=2;G[j+388>>2]=31;G[s>>2]=0;G[s+4>>2]=1072693248;G[j+376>>2]=0;E[t|0]=0;E[o|0]=0;E[l|0]=0;E[p|0]=0;E[r|0]=0;G[m>>2]=1589294263;G[m+4>>2]=-1196933592;G[n>>2]=1589294263;G[n+4>>2]=-1196933592;G[q>>2]=1589294263;G[q+4>>2]=-1196933592;E[o+71|0]=0;E[l+71|0]=0;E[p+71|0]=0;E[r+71|0]=0;G[m+8>>2]=1589294263;G[m+12>>2]=-1196933592;G[n+8>>2]=1589294263;G[n+12>>2]=-1196933592;G[q+8>>2]=1589294263;G[q+12>>2]=-1196933592;E[o+142|0]=0;E[l+142|0]=0;E[p+142|0]=0;E[r+142|0]=0;G[m+16>>2]=1589294263;G[m+20>>2]=-1196933592;G[n+16>>2]=1589294263;G[n+20>>2]=-1196933592;G[q+16>>2]=1589294263;G[q+20>>2]=-1196933592;E[o+213|0]=0;E[l+213|0]=0;E[p+213|0]=0;E[r+213|0]=0;G[m+24>>2]=1589294263;G[m+28>>2]=-1196933592;G[n+24>>2]=1589294263;G[n+28>>2]=-1196933592;G[q+24>>2]=1589294263;G[q+28>>2]=-1196933592;c=h+3|0;G[g+92>>2]=c;Sc:{Tc:{Uc:{Vc:{Wc:{Xc:{Yc:{e=H[h+3|0];switch(e-98|0){case 0:break Uc;case 2:break Vc;case 16:break Wc;case 8:break Xc;case 7:break Yc;default:break Sc}}G[j+388>>2]=21;c=h+4|0;break Tc}c=h+4|0;break Tc}G[j+388>>2]=42;c=h+4|0;break Tc}G[j+388>>2]=82;c=h+4|0;break Tc}G[j+388>>2]=11;c=h+4|0}G[g+92>>2]=c;e=H[c|0];C=1}Zc:{_c:{if((e|0)==32){B=q+24|0;D=n+24|0;x=m+24|0;A=r+213|0;I=p+213|0;J=l+213|0;z=o+213|0;K=q+16|0;P=n+16|0;R=m+16|0;U=r+142|0;V=p+142|0;W=l+142|0;w=o+142|0;X=q+8|0;Y=n+8|0;Z=m+8|0;_=r+71|0;$=p+71|0;aa=l+71|0;y=o+71|0;break _c}if(!e){break Rc}Ua(36699);Ua(h);break Zc}while(1){if((e|0)==32){f=c+1|0;G[g+92>>2]=f;e=H[c+1|0];c=f;continue}break}if(!e){break Rc}if((e|0)==64){if(Nj(c+1|0,g+12|0,d)){break Rc}u=G[g+12>>2];i=u;while(1){c=i;G[g+92>>2]=c;i=c+1|0;e=H[c|0];if((e|0)==32){continue}break}}$c:{ad:{bd:{cd:{if((e|0)==40){while(1){f=c+1|0;G[g+92>>2]=f;e=H[c+1|0];c=f;if((e|0)==32){continue}break}f=qc(c,63664);qb(o,c,f);c=c+f|0;e=1;while(1){G[g+92>>2]=c;f=H[c|0];if((f|0)!=32){if((f|0)==41){break cd}while(1){f=c+1|0;G[g+92>>2]=f;e=H[c+1|0];c=f;if((e|0)==32){continue}break}f=qc(c,63664);qb(y,c,f);c=c+f|0;e=2;while(1){G[g+92>>2]=c;f=H[c|0];if((f|0)!=32){if((f|0)==41){break cd}while(1){f=c+1|0;G[g+92>>2]=f;e=H[c+1|0];c=f;if((e|0)==32){continue}break}f=qc(c,63664);qb(w,c,f);c=c+f|0;e=3;while(1){G[g+92>>2]=c;f=H[c|0];if((f|0)!=32){if((f|0)==41){break cd}while(1){f=c+1|0;G[g+92>>2]=f;e=H[c+1|0];c=f;if((e|0)==32){continue}break}f=qc(c,63664);qb(z,c,f);c=c+f|0;e=4;while(1){G[g+92>>2]=c;f=H[c|0];if((f|0)!=32){if((f|0)==41){break cd}Ua(40168);Ua(h);c=G[g+12>>2];if(!c){break Zc}Wa(c);break Zc}else{c=c+1|0;continue}}}else{c=c+1|0;continue}}}else{c=c+1|0;continue}}}else{c=c+1|0;continue}}}Cg(g+92|0,o,m,n,q,l,p,r,d);dd:{if(G[d>>2]>0){break dd}ed:{fd:{gd:{hd:{id:{jd:{kd:{ld:{md:{nd:{c=G[g+92>>2];e=H[c|0];switch(e-32|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:break gd;case 27:break id;case 12:break md;case 0:break nd;default:break jd}}while(1){if((e|0)==32){f=c+1|0;G[g+92>>2]=f;e=H[c+1|0];c=f;continue}break}od:{switch(e-44|0){case 15:break id;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:break kd;case 0:break od;default:break ld}}G[g+92>>2]=c+1;break kd}G[g+92>>2]=c+1;break kd}if(!e){break id}}Cg(g+92|0,y,Z,Y,X,aa,$,_,d);if(G[d>>2]>0){break dd}u=2;pd:{qd:{rd:{sd:{c=G[g+92>>2];e=H[c|0];switch(e-32|0){case 27:break fd;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:break gd;case 12:break rd;case 0:break sd;default:break pd}}while(1){if((e|0)==32){f=c+1|0;G[g+92>>2]=f;e=H[c+1|0];c=f;continue}break}td:{switch(e-44|0){default:if(e){break qd}break fd;case 15:break fd;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:break qd;case 0:break td}}G[g+92>>2]=c+1;break qd}G[g+92>>2]=c+1}Cg(g+92|0,w,R,P,K,W,V,U,d);if(G[d>>2]>0){break dd}u=3;ud:{vd:{wd:{c=G[g+92>>2];e=H[c|0];switch(e-32|0){case 27:break fd;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:break gd;case 12:break vd;case 0:break wd;default:break hd}}while(1){if((e|0)==32){f=c+1|0;G[g+92>>2]=f;e=H[c+1|0];c=f;continue}break}xd:{switch(e-44|0){default:if(e){break ud}break fd;case 15:break fd;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:break ud;case 0:break xd}}G[g+92>>2]=c+1;break ud}G[g+92>>2]=c+1}Cg(g+92|0,z,x,D,B,J,I,A,d);if(G[d>>2]>0){break dd}u=4;yd:{zd:{Ad:{Bd:{c=G[g+92>>2];e=H[c|0];switch(e-32|0){case 27:break fd;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:break gd;case 12:break zd;case 0:break Ad;default:break Bd}}if(e){break gd}break fd}while(1){if((e|0)==32){f=c+1|0;G[g+92>>2]=f;e=H[c+1|0];c=f;continue}break}Cd:{switch(e-44|0){default:if(e){break yd}break fd;case 15:break fd;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:break yd;case 0:break Cd}}G[g+92>>2]=c+1;break yd}G[g+92>>2]=c+1}Ua(39222);Ua(6625);Ua(h);break Zc}if(e){break gd}break fd}if(e){break gd}}G[j+380>>2]=1;if(H[o|0]|L[m>>3]!=-91191291391491e-49|L[n>>3]!=-91191291391491e-49){break ed}G[j+380>>2]=2;L[q+8>>3]=L[q>>3];break ed}if(!e){break fd}}Ua(39260);Ua(h);c=G[g+12>>2];if(!c){break Zc}Wa(c);break Zc}G[j+380>>2]=u}if(H[c|0]!=59){break ad}break bd}Ua(39376);Ua(h);c=G[g+12>>2];if(!c){break Rc}Wa(c);break Rc}G[j+380>>2]=e;while(1){f=c;c=c+1|0;G[g+92>>2]=c;e=H[f+1|0];if((e|0)==32){continue}break}if((e|0)!=61){if(!e){if(!u){break Rc}Wa(u);break Rc}Ua(39222);Ua(7525);Ua(h);c=G[g+12>>2];if(!c){break Zc}Wa(c);break Zc}c=f+2|0;while(1){G[g+92>>2]=c;f=H[c|0];c=c+1|0;if((f|0)==32){continue}break}Cg(g+92|0,g+16|0,m,n,q,l,p,r,d);if(G[d>>2]>0){break $c}c=1;if(G[j+380>>2]>1){while(1){f=c<<3;L[f+m>>3]=L[m>>3];L[f+n>>3]=L[n>>3];L[f+q>>3]=L[q>>3];f=M(c,71);Za(f+l|0,l);Za(f+p|0,p);Za(f+r|0,r);c=c+1|0;if((c|0)>2]){continue}break}}c=G[g+92>>2];while(1){f=H[c|0];if((f|0)!=32){if(!f){break Rc}if((f|0)==59){break bd}Ua(39319);Ua(h);c=G[g+12>>2];if(!c){break Zc}Wa(c);break Zc}else{c=c+1|0;G[g+92>>2]=c;continue}}}while(1){f=c+1|0;G[g+92>>2]=f;e=H[c+1|0];c=f;if((e|0)==32){continue}break}c=g+16|0;Cg(g+92|0,t,g,g,s,c,c,c,d);if(G[d>>2]>0){Ua(39177);Ua(h);c=G[g+12>>2];if(!c){break Rc}Wa(c);break Rc}if((H[t|0]?0:L[s>>3]==1)|C){break ad}G[j+388>>2]=42}c=G[g+92>>2];while(1){f=H[c|0];if((f|0)!=32){if(f){Ua(39119);Ua(h);G[d>>2]=125}c=G[g+12>>2];if(!c){break Rc}Wa(c);break Rc}else{c=c+1|0;G[g+92>>2]=c;continue}}}Ua(39222);Ua(h);c=G[g+12>>2];if(!c){break Rc}Wa(c);break Rc}G[d>>2]=125}Fa=g+96|0;s=j+11072|0;e=G[j+388>>2];f=G[j+380>>2];v=L[j+392>>3];g=G[j+376>>2];c=Fa-176|0;Fa=c;Dd:{if(G[d>>2]>0){break Dd}if((f|0)>=5){Ua(6766);G[d>>2]=320;break Dd}i=G[a>>2];h=G[i>>2];if((h|0)!=G[G[i+4>>2]+76>>2]){mb(i,h+1|0,0,d)}u=8;Ed:{Fd:{Gd:{switch(e-11|0){case 20:u=32;break Ed;case 31:u=-32;break Ed;default:if((e|0)==82){break Fd}case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:G[d>>2]=410;break Dd;case 0:break Ed;case 10:break Gd}}u=16;break Ed}u=-64}Hd:{if((_j(G[a>>2],f,o,m,n,q,l,p,r,c+144|0,c+112|0,c+80|0,c+48|0,c+16|0,d)|0)>0){Ua(6126);break Hd}Id:{Jd:{if(H[t|0]){if(!Cb(G[a>>2],82,t,c+8|0,0,d)){v=L[c+8>>3];break Jd}G[d>>2]=0;if((dc(G[a>>2],0,t,c+140|0,d)|0)>0){Ua(66743);Ua(t);break Hd}G[c+8>>2]=1589294263;G[c+12>>2]=-1196933592;break Id}L[c+8>>3]=v}if(!(!(v<=0)|v==-91191291391491e-49)){Ua(45241);G[d>>2]=125;break Dd}if(!g|v==-91191291391491e-49){break Id}L[c+8>>3]=1/v}if((sd(c+172|0,s,d)|0)>0){Ua(16402);break Hd}if((pd(G[c+172>>2],u,f,c+112|0,d)|0)>0){Ua(25086);break Hd}if((tk(G[a>>2],G[c+172>>2],c+144|0,d)|0)>0){Ua(11702);break Hd}e=c+144|0;Zj(G[a>>2],G[c+172>>2],f,e,d);q=c+80|0;i=c+16|0;En(G[c+172>>2],f,q,i,d);if((Dn(G[a>>2],G[c+172>>2],u,f,c+112|0,e,q,c+48|0,i,L[c+8>>3],G[c+140>>2],g,k,d)|0)>0){Ua(7256);break Hd}Qb(G[a>>2],d);G[a>>2]=G[c+172>>2]}}Fa=c+176|0;if(k){Wa(k)}if(G[d>>2]>0){Ua(54065);Ua(37098);Ua(j+6640|0);Qb(G[a>>2],d);G[a>>2]=0;break i}ze(G[a>>2],37365,d);ze(G[a>>2],b,d)}if(H[j+4560|0]){Kd:{if(H[j+3520|0]){Za(j+11072|0,j+3520|0);break Kd}E[j+11080|0]=H[40354];c=H[40350]|H[40351]<<8|(H[40352]<<16|H[40353]<<24);G[j+11072>>2]=H[40346]|H[40347]<<8|(H[40348]<<16|H[40349]<<24);G[j+11076>>2]=c}Dc(G[a>>2],j+13224|0,d);Ld:{if(!G[j+13224>>2]){f=j+4560|0;h=Fa-192|0;Fa=h;cb(h+8|4,0,176);G[h+4>>2]=33141;G[h+20>>2]=a;G[h+16>>2]=h+4;G[h+8>>2]=1;c=j+11072|0;Md:{if((sd(h+36|0,c,d)|0)>0){Ua(36786);Ua(c);break Md}G[h>>2]=G[G[a>>2]>>2]+1;c=8;Nd:{Od:{Pd:{Qd:{switch(E[f+3|0]-66|0){case 7:case 39:c=16;break Pd;case 8:case 40:c=32;break Pd;case 16:case 48:c=-32;break Pd;case 0:case 32:break Pd;case 2:case 34:break Qd;default:break Od}}c=-64}G[h+28>>2]=c;c=f+4|0;break Nd}c=G[h+28>>2]?f+4|0:f+3|0}f=G[G[G[a>>2]+4>>2]+20>>2]!=0;e=H[c|0]==49;c=e+c|0;if(H[c|0]!=32){Ua(38845);Ua(c)}l=e|f;while(1){q=c;c=c+1|0;if(H[q|0]==32){continue}break}Rd:{i=G[h>>2];if(l&1|(i|0)<2){break Rd}c=1;Sd:{if(l&1){mb(G[a>>2],1,0,d);if((ne(G[a>>2],G[h+36>>2],d)|0)>0){break Sd}i=G[h>>2];break Rd}while(1){mb(G[a>>2],c,0,d);if((ne(G[a>>2],G[h+36>>2],d)|0)>0){break Sd}c=c+1|0;i=G[h>>2];if((c|0)<(i|0)){continue}break}break Rd}Qb(G[h+36>>2],d);break Md}mb(G[a>>2],i,0,d);G[h+24>>2]=q;i=h+8|0;f=Fa-608|0;Fa=f;G[f+600>>2]=0;G[f+592>>2]=0;G[f+596>>2]=0;G[f+584>>2]=0;G[f+588>>2]=0;G[f+540>>2]=33141;e=Fd(34019);G[309801]=(e|0)!=0;c=G[d>>2];if(!c){c=G[i+8>>2];Td:{Ud:{if(!c){break Ud}c=G[c>>2];if(!c){break Ud}if(H[c|0]){break Td}}G[i+8>>2]=f+540;if(!e){break Td}G[f+160>>2]=33141;kb(89473,f+160|0)}g=G[i+28>>2];m=G[G[i+12>>2]>>2];G[309731]=i;Vd:{if(fh(m,G[i+16>>2],f+584|0,f+572|0,f+580|0,f+544|0,d)){break Vd}c=G[f+572>>2];if((c|0)<0){G[f+572>>2]=0-c}c=34853;Wd:{Xd:{Yd:{Zd:{_d:{$d:{ae:{e=G[f+584>>2];switch(e-14|0){case 0:break Xd;case 27:break Yd;case 1:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:break Zd;case 2:break $d;default:break ae}}if((e|0)==1){break _d}if((e|0)!=82){break Zd}c=35602;break Xd}G[d>>2]=-1;Ua(24519)}if(!G[309801]){break Wd}yb(36053);c=33396;break Xd}G[d>>2]=-1;Ua(20856);c=65657;break Xd}c=35076}if(!G[309801]){break Wd}G[f+148>>2]=e;G[f+144>>2]=c;kb(78438,f+144|0)}if(G[d>>2]){break Vd}if(mh(m,5,f+576|0,f+580|0,f+544|0,d)){Ua(6165);break Vd}if(G[309801]){G[f+128>>2]=G[f+576>>2];kb(74805,f+128|0)}c=G[f+576>>2];if(!((c|0)==-64|(e|0)!=82)){G[f+576>>2]=-32;c=-32}e=G[i+20>>2];if(e){G[f+576>>2]=e;c=e}if(G[309801]){G[f+112>>2]=c;kb(74787,f+112|0);c=G[f+576>>2]}if(pd(g,c,G[f+580>>2],f+544|0,d)){Ua(24281);break Vd}be:{ce:{if(!Td(m,f+268|0,f+264|0,d)){e=1;if(G[f+268>>2]>0){while(1){de:{c=e;ee:{if(Sd(m,c,f+176|0,d)){G[f+96>>2]=c;Ya(f+272|0,256,30210,f+96|0);break ee}e=mk(f+176|0);if((e|0)==10|(e|0)==130&c>>>0<12){break de}n=G[f+576>>2]<0;if(n&(e|0)==40|n&(e|0)==30){break de}if(!wb(g,f+176|0,d)){break de}G[f+84>>2]=G[d>>2];G[f+80>>2]=f+176;Ya(f+272|0,256,78700,f+80|0)}Ua(f+272|0);break Vd}e=c+1|0;if((c|0)>2]){continue}break}}fe:{ge:{he:{ie:{je:{ke:{le:{c=G[f+576>>2];switch(c-8|0){case 0:break ge;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:break he;case 24:break je;case 8:break ke;default:break le}}if((c|0)==-64){break ie}if((c|0)!=-32){break he}c=42;break ce}c=21;break fe}c=41;break fe}c=82;break ce}G[f>>2]=c;c=f+272|0;Ya(c,256,74762,f);Ua(c);G[d>>2]=-1;break Vd}c=11}G[f+584>>2]=c;e=G[i+24>>2];G[f+272>>2]=e;p=0;if(!e){G[f+176>>2]=0;if(Ec(m,34862,f+272|0,0,f+176|0)){me:{ne:{oe:{pe:{qe:{e=G[f+576>>2];switch(e-8|0){case 24:break oe;case 8:break pe;case 0:break qe;default:break ne}}G[f+272>>2]=255;break me}G[f+272>>2]=-32768;break me}G[f+272>>2]=-2147483648;break me}G[f+64>>2]=e;kb(75109,f- -64|0)}p=1}e=G[f+272>>2];G[i+24>>2]=e}lq(g,e,e>>31,d);if(!G[309801]){break be}G[f+48>>2]=G[f+272>>2];kb(73321,f+48|0);break be}Ua(8285);break Vd}G[f+584>>2]=c;p=0}if(!H[i+32|0]){c=G[309728];if(ki(c,d)){break Vd}G[309728]=G[309728]+1;e=G[i+28>>2];m=G[309729]+M(c,244)|0;G[m+84>>2]=2;G[m>>2]=e;fn(e,35819,G[f+576>>2],G[309730]+M(c,124)|0,m);G[f+596>>2]=-1;re:{if(($f(G[309728],G[309729],0,0,34,f+584|0,d)|0)==-1){G[d>>2]=0;break re}if(G[d>>2]){break Vd}}if(G[f+600>>2]){if(!p){break Vd}c=G[i+24>>2];Gc(g,34862,c,c>>31,19882,d);if(G[d>>2]){Ua(25874)}if(!G[309801]){break Vd}yb(8509);G[f+16>>2]=G[d>>2];kb(78550,f+16|0);break Vd}if(G[f+576>>2]<=0){break Vd}if(!lq(g,-1234554321,-1,d)){break Vd}Ua(16728);break Vd}e=i+32|0;i=i+107|0;m=G[309725];n=G[309722];se:{te:{switch(c-14|0){default:if((c|0)!=82){break se}Kd(g,e,L[(n+M(m,344)|0)+88>>3],15,i,d);break Vd;case 27:c=G[(n+M(m,344)|0)+88>>2];Gc(g,e,c,c>>31,i,d);break Vd;case 0:Kh(g,e,E[(n+M(m,344)|0)+88|0],i,d);break Vd;case 1:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:break se;case 2:break te}}Gl(g,e,(n+M(m,344)|0)+88|0,i,d);break Vd}G[f+32>>2]=c;c=f+272|0;Ya(c,256,78648,f+32|0);Ua(c)}Yd();c=G[d>>2]}Fa=f+608|0;if(c){Ua(36889);Ua(q);Qb(G[h+36>>2],d);break Md}e=G[h>>2];ue:{if(l&1){break ue}c=e+1|0;if((mb(G[a>>2],c,0,d)|0)>0){break ue}while(1){ne(G[a>>2],G[h+36>>2],d);e=c;c=c+1|0;if((mb(G[a>>2],c,0,d)|0)<=0){continue}break}}ve:{c=G[d>>2];if((c|0)==107){G[d>>2]=0;break ve}if((c|0)<=0){break ve}Qb(G[h+36>>2],d);break Md}Qb(G[a>>2],d);c=G[h+36>>2];G[a>>2]=c;f=G[h>>2];if((f|0)==(e|0)){break Md}mb(c,f,0,d)}Fa=h+192|0;if(G[d>>2]<=0){break Ld}Ua(54121);Ua(37621);Ua(j+4560|0);Qb(G[a>>2],d);G[a>>2]=0;break i}Ua(33240);Ua(j+4560|0);Qb(G[a>>2],d);G[a>>2]=0;e=233;G[d>>2]=233;break a}ze(G[a>>2],38623,d);ze(G[a>>2],b,d)}if(!H[j+1440|0]){break i}_m(G[a>>2],j+1440|0,d)}e=G[d>>2];break a}Ua(j+7680|0);Ua(37538);Ua(j+1e4|0);Qb(G[a>>2],d);G[a>>2]=0;e=307;G[d>>2]=307;break a}e=113;G[d>>2]=113;break a}e=104;G[d>>2]=104}Fa=j+13232|0;return e}function fh(a,b,c,d,e,f,g){var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,K=0,N=0,O=0,P=0,Q=0;u=Fa-80|0;Fa=u;G[u+76>>2]=0;h=G[g>>2];a:{if(h){break a}b:{c:{if(Rb(a,g)){break c}G[309730]=0;G[309728]=0;G[309729]=0;G[309715]=0;G[309712]=a;G[309724]=0;G[309714]=35;G[309713]=36;G[309736]=0;G[309737]=0;G[309722]=0;G[309723]=0;Dc(a,1238944,g);d:{if(!G[309736]){mh(a,9,u+68|0,u+72|0,u+32|0,g);if(G[g>>2]){Ua(6727);break c}i=G[u+72>>2];G[309734]=(i|0)>0;j=1;h=0;if((i|0)>0){if(i-1>>>0>=3){o=i&-4;while(1){s=j;j=h<<2;l=u+32|0;j=M(M(M(M(s,G[j+l>>2]),G[l+(j|4)>>2]),G[l+(j|8)>>2]),G[l+(j|12)>>2]);h=h+4|0;k=k+4|0;if((o|0)!=(k|0)){continue}break}}l=i&3;if(l){while(1){j=M(G[(u+32|0)+(h<<2)>>2],j);h=h+1|0;v=v+1|0;if((l|0)!=(v|0)){continue}break}}G[309734]=j;h=j}if(!G[309801]){break d}G[u+20>>2]=h;G[u+16>>2]=i;kb(73289,u+16|0);break d}if(!Ec(a,40853,1238936,0,u+76|0)){break d}G[309734]=0}e:{if(H[b|0]==64){if(Nj(b+1|0,1238876,g)){break c}h=G[309719];j=Va(h);break e}j=Va(b);h=ab(j+2|0);G[309719]=h;h=Za(h,b)}b=h+j|0;b=Va(b)+b|0;E[b|0]=10;E[b+1|0]=0;G[309720]=0;G[309721]=0;b=G[309704];f:{if(b){b=G[b+(G[309705]<<2)>>2];if(b){break f}}Uj();b=Tj(G[309700]);G[G[309704]+(G[309705]<<2)>>2]=b}Sj(b,0);h=G[309704]+(G[309705]<<2)|0;b=G[h>>2];G[309738]=G[b+16>>2];b=G[b+8>>2];G[309706]=b;G[309710]=b;G[309700]=G[G[h>>2]>>2];E[1238828]=H[b|0];q=Fa-26144|0;Fa=q;G[309630]=-2;A=100;K=q+256|0;k=K;s=q+25856|0;v=s;g:{h:{while(1){i:{F[s>>1]=p;j:{k:{l:{m:{n:{o:{p:{q:{r:{s:{t:{u:{b=A<<1;if((b+v|0)-2>>>0<=s>>>0){if((A|0)>9999){break u}A=(b|0)<1e4?b:1e4;b=ab(M(A,258)+255|0);if(!b){break u}j=s-v>>1;h=j+1|0;b=bb(b,v,h<<1);i=h<<8;K=bb(b+(((A<<1)+255|0)/256<<8)|0,K,i);if((q+25856|0)!=(v|0)){Wa(v)}s=1;if((h|0)>=(A|0)){v=b;break h}s=b+(j<<1)|0;k=(i+K|0)-256|0;v=b}if((p|0)==2){s=0;break i}v:{w:{x:{x=F[(p<<1)+127056>>1];if((x|0)==-40){break x}o=G[309630];if((o|0)==-2){m=Fa-576|0;Fa=m;if(!H[1238808]){E[1238808]=1;if(!H[1238812]){E[1238812]=1}if(!G[309700]){G[309700]=G[30060]}if(!G[309701]){G[309701]=G[29763]}h=G[309704];y:{if(h){l=G[309705];i=G[(l<<2)+h>>2];if(i){break y}}Uj();i=Tj(G[309700]);h=G[309704];l=G[309705];G[h+(l<<2)>>2]=i}G[309738]=G[i+16>>2];b=G[i+8>>2];G[309710]=b;G[309706]=b;G[309700]=G[G[(l<<2)+h>>2]>>2];E[1238828]=H[b|0]}z:{A:{B:{C:{D:{E:{F:{G:{H:{I:{J:{K:{L:{M:{N:{O:while(1){b=G[309706];E[b|0]=H[1238828];i=H[1238812];o=b;P:while(1){h=H[(H[o|0]<<2)+137104|0];j=i<<1;if(I[j+138128>>1]){G[309709]=o;G[309708]=i}l=h;n=F[j+139424>>1]+h|0;if(F[(n<<1)+138480>>1]!=(i|0)){while(1){i=F[(i<<1)+139792>>1];l=(i|0)>=174?G[(h<<2)+140160>>2]:l;h=l&255;n=h+F[(i<<1)+139424>>1]|0;if(I[(n<<1)+138480>>1]!=(i&65535)){continue}break}}o=o+1|0;i=F[(n<<1)+140400>>1];if(I[(i<<1)+139424>>1]!=413){continue}while(1){j=b;Q:{R:while(1){i=I[(i<<1)+138128>>1];if(!i){o=G[309709];i=I[(G[309708]<<1)+138128>>1]}G[309710]=j;G[309711]=o-j;E[1238828]=H[o|0];E[o|0]=0;h=i<<16>>16;b=o;S:{while(1){G[309706]=b;i=277;T:{switch(h|0){case 0:E[o|0]=H[1238828];i=G[309708];o=G[309709];continue R;case 2:b=G[309710];i=Va(b);while(1){j=b+i|0;h=i-1|0;i=h;if(H[j|0]==32){continue}break};rb(1238528,b+1|0,h);E[h+1238528|0]=0;i=262;break B;case 3:l=0;h=G[309710];i=Va(h);if((i|0)>=256){break I}while(1){b=h+i|0;l=i-1|0;i=l;if(H[b|0]==32){continue}break};rb(m+320|0,h+1|0,l);break C;case 4:l=0;h=G[309710];i=Va(h);if((i|0)>=256){break H}while(1){b=h+i|0;l=i-1|0;i=l;if(H[b|0]==32){continue}break};rb(m+320|0,h+1|0,l);break D;case 5:l=0;b=G[309710];i=H[b+2|0];if(i){h=b+2|0;while(1){l=l<<1|(i&255)==49;i=H[h+1|0];h=h+1|0;if(i){continue}break}}G[309632]=l;i=259;break B;case 6:l=0;b=G[309710];i=H[b+2|0];if(i){h=b+2|0;while(1){l=(i<<24>>24)-48|l<<3;i=H[h+1|0];h=h+1|0;if(i){continue}break}}G[309632]=l;i=259;break B;case 7:l=0;b=G[309710];i=H[b+2|0];if(i){h=b+2|0;while(1){b=i<<24>>24;j=b-48|0;l=l<<4|(j>>>0<10?j:b-87|0);i=H[h+1|0];h=h+1|0;if(i){continue}break}}G[309632]=l;i=259;break B;case 8:O=1238528,P=_b(G[309710]),G[O>>2]=P;i=259;break B;case 9:E[1238528]=!(H[G[309710]]-84&223);i=258;break B;case 10:O=1238528,Q=sb(G[309710]),L[O>>3]=Q;i=260;break B;case 11:if(!Ib(G[309710],34898)){G[309632]=1413754136;G[309633]=1074340347;i=260;break B}if(!Ib(G[309710],35749)){G[309632]=-1961601175;G[309633]=1074118410;i=260;break B}if(!Ib(G[309710],35099)){G[309632]=-1571644103;G[309633]=1066524486;i=260;break B}if(!Ib(G[309710],33143)){i=273;break B}if(!Ib(G[309710],34768)){i=274;break B}if(!Ib(G[309710],34761)){i=275;break B}b=G[309710];if(H[b+1|0]==36){h=Va(b);E[1238528]=35;rb(1238529,b+2|0,h-3|0);G[309710]=1238528;E[h+1238526|0]=0;b=1238528}i=Ja[G[309713]](b,1238528)|0;break B;case 12:i=0;h=G[309710];b=Va(h)-2|0;U:{if((b|0)>=256){G[309737]=431;b=H[65311]|H[65312]<<8|(H[65313]<<16|H[65314]<<24);G[m+336>>2]=H[65307]|H[65308]<<8|(H[65309]<<16|H[65310]<<24);G[m+340>>2]=b;b=H[65319]|H[65320]<<8|(H[65321]<<16|H[65322]<<24);G[m+344>>2]=H[65315]|H[65316]<<8|(H[65317]<<16|H[65318]<<24);G[m+348>>2]=b;E[m+352|0]=H[65323];b=H[65295]|H[65296]<<8|(H[65297]<<16|H[65298]<<24);G[m+320>>2]=H[65291]|H[65292]<<8|(H[65293]<<16|H[65294]<<24);G[m+324>>2]=b;b=H[65303]|H[65304]<<8|(H[65305]<<16|H[65306]<<24);G[m+328>>2]=H[65299]|H[65300]<<8|(H[65301]<<16|H[65302]<<24);G[m+332>>2]=b;j=qb(m+320|0,h+1|0,20);b=Va(j)+j|0;h=H[65197]|H[65198]<<8|(H[65199]<<16|H[65200]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[65201];Ua(j);break U}rb(1238528,h+1|0,b);i=b}E[i+1238528|0]=0;i=261;break B;case 13:b=G[309710];if(H[b|0]==36){h=b+1|0;b=Va(b)-2|0;rb(1238528,h,b);G[309710]=1238528;E[b+1238528|0]=0;b=1238528}i=mi(b,1238528);break B;case 14:i=0;h=G[309710];while(1){b=E[h+i|0];b=b-97>>>0<26?b&95:b;E[i+1238528|0]=b;i=i+1|0;if(b&255){continue}break};V:{W:{X:{Y:{Z:{_:{$:{aa:{j=H[1238528];switch(j-66|0){case 12:break Z;case 3:break _;case 1:break $;case 0:break aa;default:break Y}}if(nb(1238528,64426,5)){break W}i=264;break B}i=264;b=G[309632];if((b|0)!=1129466179|G[309633]!=2639180){break X}break B}if(nb(1238528,64687,9)){break W}i=264;break B}if(nb(1238528,64506,6)){break W}i=264;break B}b=G[309632];h=G[309633];if((j|0)!=73){break X}i=264;if((b|0)==1431196489&(h|0)==2640972){break B}}ba:{switch((b&255)-71|0){case 0:if(!nb(1238528,64484,11)){i=266;break B}if(nb(1238528,64534,12)){break W}i=267;break B;case 12:break V;case 11:break ba;default:break W}}if(nb(1238528,64495,11)){break W}i=268;break B}i=263;break B}i=G[309632]==1397904467&G[309633]==2642516?265:263;break B;case 21:i=278;break B;case 22:i=279;break B;case 23:i=280;break B;case 24:i=281;break B;case 25:i=283;break B;case 26:i=282;break B;case 27:i=284;break B;case 28:i=10;break B;case 29:i=E[G[309710]];break B;case 30:hb(G[309710],G[309711],1,G[309701]);continue O;case 32:i=0;break B;case 20:break B;case 19:break J;case 18:break K;case 17:break L;case 16:break M;case 15:break N;case 1:continue O;case 31:break T;default:break Q}}y=G[309710];E[o|0]=H[1238828];r=G[309704];w=G[309705];z=r+(w<<2)|0;h=G[z>>2];ca:{if(G[h+44>>2]){l=G[309738];break ca}l=G[h+16>>2];G[309738]=l;G[h>>2]=G[309700];h=G[z>>2];G[h+44>>2]=1}n=G[309706];i=G[h+4>>2];b=l+i|0;if(n>>>0<=b>>>0){j=G[309710];h=(y^-1)+o|0;o=j+h|0;G[309706]=o;i=H[1238812];b=j;if((h|0)>0){while(1){h=1;l=H[b|0];if(l){h=H[(l<<2)+137104|0]}l=i<<1;if(I[l+138128>>1]){G[309709]=b;G[309708]=i}n=F[l+139424>>1]+h|0;if(F[(n<<1)+138480>>1]!=(i|0)){l=h;while(1){i=F[(i<<1)+139792>>1];l=(i|0)>=174?G[(h<<2)+140160>>2]:l;h=l&255;n=h+F[(i<<1)+139424>>1]|0;if(I[(n<<1)+138480>>1]!=(i&65535)){continue}break}}i=F[(n<<1)+140400>>1];b=b+1|0;if((o|0)!=(b|0)){continue}break}}if(I[(i<<1)+138128>>1]){G[309709]=o;G[309708]=i}h=i;l=F[(h<<1)+139424>>1]+1|0;if(F[(l<<1)+138480>>1]!=(h|0)){while(1){b=I[(h<<1)+139792>>1];h=b<<16>>16;l=F[(h<<1)+139424>>1]+1|0;if(I[(l<<1)+138480>>1]!=(b|0)){continue}break}}h=F[(l<<1)+140400>>1];if(!l|(h|0)==173){continue R}o=o+1|0;G[309706]=o;b=j;i=h;continue P}if(b+1>>>0>>0){break G}b=G[309710];if(!G[h+40>>2]){h=32;if((n-b|0)==1){continue}break S}t=(b^-1)+n|0;if((t|0)>0){B=t&7;da:{if((n-b|0)-2>>>0<7){h=b;break da}C=t&-8;l=0;h=b;while(1){E[i|0]=H[h|0];E[i+1|0]=H[h+1|0];E[i+2|0]=H[h+2|0];E[i+3|0]=H[h+3|0];E[i+4|0]=H[h+4|0];E[i+5|0]=H[h+5|0];E[i+6|0]=H[h+6|0];E[i+7|0]=H[h+7|0];i=i+8|0;h=h+8|0;l=l+8|0;if((C|0)!=(l|0)){continue}break}}l=0;if(B){while(1){E[i|0]=H[h|0];i=i+1|0;h=h+1|0;l=l+1|0;if((B|0)!=(l|0)){continue}break}}h=G[z>>2]}ea:{fa:{if(G[h+44>>2]==2){G[309738]=0;break fa}l=b-n|0;while(1){b=G[h+12>>2];i=b+l|0;if(!i){if(!G[h+20>>2]){G[h+4>>2]=0;break E}i=G[h+4>>2];r=b<<1;b=r?r:b+(b>>>3|0)|0;G[h+12>>2]=b;b=ub(i,b+2|0);G[h+4>>2]=b;if(!b){break E}n=b+(n-i|0)|0;G[309706]=n;r=G[309704];w=G[309705];h=G[r+(w<<2)>>2];continue}break}b=t+G[h+4>>2]|0;r=(w<<2)+r|0;if(!G[309721]){z=(i>>>0<8192?i:8192)-1|0;h=G[309720];n=G[309719];i=0;ga:{ha:{while(1){ia:{G[309720]=h+1;E[b+i|0]=H[h+n|0];l=i+1|0;h=G[309720];n=G[309719];w=H[h+n|0];if((i|0)==(z|0)){break ia}i=l;if(w){continue}break ha}break}if(w){break ga}}G[309721]=1}E[b+l|0]=0;G[309738]=l;G[G[r>>2]+16>>2]=l;h=G[309705];b=G[309704];i=0;break ea}E[b|0]=0;G[309738]=0;h=G[r>>2]}l=0;G[h+16>>2]=0;if(!t){b=G[309700];h=G[309704];ja:{if(h){i=G[h+(G[309705]<<2)>>2];if(i){break ja}}Uj();i=Tj(G[309700]);G[G[309704]+(G[309705]<<2)>>2]=i}Sj(i,b);b=G[309704];h=G[309705];n=b+(h<<2)|0;i=G[n>>2];l=G[i+16>>2];G[309738]=l;i=G[i+8>>2];G[309706]=i;G[309710]=i;G[309700]=G[G[n>>2]>>2];E[1238828]=H[i|0];i=1;break ea}b=G[309704];h=G[309705];G[G[b+(h<<2)>>2]+44>>2]=2;i=2}b=(h<<2)+b|0;n=G[b>>2];h=l+t|0;ka:{if(J[n+12>>2]>=h>>>0){l=G[n+4>>2];break ka}l=ub(G[n+4>>2],h+(l>>>1|0)|0);G[G[b>>2]+4>>2]=l;l=G[G[b>>2]+4>>2];if(!l){break F}}G[309738]=h;E[h+l|0]=0;E[(h+G[G[b>>2]+4>>2]|0)+1|0]=0;b=G[G[b>>2]+4>>2];G[309710]=b;h=32;if((i|0)==1){continue}break}la:{switch(i|0){case 0:h=(y^-1)+o|0;o=h+b|0;G[309706]=o;i=H[1238812];j=b;if((h|0)<=0){continue P}while(1){h=1;l=H[j|0];if(l){h=H[(l<<2)+137104|0]}l=i<<1;if(I[l+138128>>1]){G[309709]=j;G[309708]=i}n=F[l+139424>>1]+h|0;if(F[(n<<1)+138480>>1]!=(i|0)){l=h;while(1){i=F[(i<<1)+139792>>1];l=(i|0)>=174?G[(h<<2)+140160>>2]:l;h=l&255;n=h+F[(i<<1)+139424>>1]|0;if(I[(n<<1)+138480>>1]!=(i&65535)){continue}break}}i=F[(n<<1)+140400>>1];j=j+1|0;if((o|0)!=(j|0)){continue}break};continue P;case 2:break la;default:continue O}}i=G[G[G[309704]+(G[309705]<<2)>>2]+4>>2];l=G[309738]}o=i+l|0;G[309706]=o;i=H[1238812];j=b;if(b>>>0>=o>>>0){continue}break}while(1){h=1;l=H[j|0];if(l){h=H[(l<<2)+137104|0]}if(I[(i<<1)+138128>>1]){G[309709]=j;G[309708]=i}n=F[(i<<1)+139424>>1]+h|0;if(F[(n<<1)+138480>>1]!=(i|0)){l=h;while(1){i=F[(i<<1)+139792>>1];l=(i|0)>=174?G[(h<<2)+140160>>2]:l;h=l&255;n=h+F[(i<<1)+139424>>1]|0;if(I[(n<<1)+138480>>1]!=(i&65535)){continue}break}}i=F[(n<<1)+140400>>1];j=j+1|0;if((o|0)!=(j|0)){continue}break}continue}break}break}break}G[m>>2]=26483;_a(G[24367],70017,m);break A}i=287;break B}i=288;break B}i=285;break B}i=286;break B}i=276;break B}G[309737]=431;b=H[65274]|H[65275]<<8|(H[65276]<<16|H[65277]<<24);G[m+336>>2]=H[65270]|H[65271]<<8|(H[65272]<<16|H[65273]<<24);G[m+340>>2]=b;b=H[65282]|H[65283]<<8|(H[65284]<<16|H[65285]<<24);G[m+344>>2]=H[65278]|H[65279]<<8|(H[65280]<<16|H[65281]<<24);G[m+348>>2]=b;b=H[65287]|H[65288]<<8|(H[65289]<<16|H[65290]<<24);j=H[65283]|H[65284]<<8|(H[65285]<<16|H[65286]<<24);E[m+349|0]=j;E[m+350|0]=j>>>8;E[m+351|0]=j>>>16;E[m+352|0]=j>>>24;E[m+353|0]=b;E[m+354|0]=b>>>8;E[m+355|0]=b>>>16;E[m+356|0]=b>>>24;b=H[65258]|H[65259]<<8|(H[65260]<<16|H[65261]<<24);G[m+320>>2]=H[65254]|H[65255]<<8|(H[65256]<<16|H[65257]<<24);G[m+324>>2]=b;b=H[65266]|H[65267]<<8|(H[65268]<<16|H[65269]<<24);G[m+328>>2]=H[65262]|H[65263]<<8|(H[65264]<<16|H[65265]<<24);G[m+332>>2]=b;j=qb(m+320|0,h,20);b=Va(j)+j|0;h=H[65197]|H[65198]<<8|(H[65199]<<16|H[65200]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[65201];Ua(j);break C}G[309737]=431;b=H[65237]|H[65238]<<8|(H[65239]<<16|H[65240]<<24);G[m+336>>2]=H[65233]|H[65234]<<8|(H[65235]<<16|H[65236]<<24);G[m+340>>2]=b;b=H[65245]|H[65246]<<8|(H[65247]<<16|H[65248]<<24);G[m+344>>2]=H[65241]|H[65242]<<8|(H[65243]<<16|H[65244]<<24);G[m+348>>2]=b;b=H[65250]|H[65251]<<8|(H[65252]<<16|H[65253]<<24);j=H[65246]|H[65247]<<8|(H[65248]<<16|H[65249]<<24);E[m+349|0]=j;E[m+350|0]=j>>>8;E[m+351|0]=j>>>16;E[m+352|0]=j>>>24;E[m+353|0]=b;E[m+354|0]=b>>>8;E[m+355|0]=b>>>16;E[m+356|0]=b>>>24;b=H[65221]|H[65222]<<8|(H[65223]<<16|H[65224]<<24);G[m+320>>2]=H[65217]|H[65218]<<8|(H[65219]<<16|H[65220]<<24);G[m+324>>2]=b;b=H[65229]|H[65230]<<8|(H[65231]<<16|H[65232]<<24);G[m+328>>2]=H[65225]|H[65226]<<8|(H[65227]<<16|H[65228]<<24);G[m+332>>2]=b;j=qb(m+320|0,h,20);b=Va(j)+j|0;h=H[65197]|H[65198]<<8|(H[65199]<<16|H[65200]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[65201];Ua(j);break D}G[m+16>>2]=29150;_a(G[24367],70017,m+16|0);break A}G[m+32>>2]=63865;_a(G[24367],70017,m+32|0);break A}G[m+48>>2]=3914;_a(G[24367],70017,m+48|0);break A}i=0;E[(m+320|0)+l|0]=0;E[m+64|0]=0;h=H[m+320|0];if(h){while(1){ma:{na:{switch((h<<24>>24)-48|0){case 0:b=m- -64|0;b=Va(b)+b|0;h=H[41656]|H[41657]<<8|(H[41658]<<16|H[41659]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[41660];break ma;case 1:b=m- -64|0;b=Va(b)+b|0;h=H[41375]|H[41376]<<8|(H[41377]<<16|H[41378]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[41379];break ma;case 2:b=m- -64|0;b=Va(b)+b|0;h=H[41630]|H[41631]<<8|(H[41632]<<16|H[41633]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[41634];break ma;case 3:b=m- -64|0;b=Va(b)+b|0;h=H[41331]|H[41332]<<8|(H[41333]<<16|H[41334]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[41335];break ma;case 4:b=m- -64|0;b=Va(b)+b|0;h=H[41640]|H[41641]<<8|(H[41642]<<16|H[41643]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[41644];break ma;case 5:b=m- -64|0;b=Va(b)+b|0;h=H[41354]|H[41355]<<8|(H[41356]<<16|H[41357]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[41358];break ma;case 6:b=m- -64|0;b=Va(b)+b|0;h=H[41601]|H[41602]<<8|(H[41603]<<16|H[41604]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[41605];break ma;case 7:b=m- -64|0;b=Va(b)+b|0;h=H[41321]|H[41322]<<8|(H[41323]<<16|H[41324]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[41325];break ma;case 8:b=m- -64|0;b=Va(b)+b|0;h=H[41651]|H[41652]<<8|(H[41653]<<16|H[41654]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[41655];break ma;case 9:b=m- -64|0;b=Va(b)+b|0;h=H[41370]|H[41371]<<8|(H[41372]<<16|H[41373]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[41374];break ma;case 17:case 49:b=m- -64|0;b=Va(b)+b|0;h=H[41625]|H[41626]<<8|(H[41627]<<16|H[41628]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[41629];break ma;case 18:case 50:b=m- -64|0;b=Va(b)+b|0;h=H[41326]|H[41327]<<8|(H[41328]<<16|H[41329]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[41330];break ma;case 19:case 51:b=m- -64|0;b=Va(b)+b|0;h=H[41635]|H[41636]<<8|(H[41637]<<16|H[41638]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[41639];break ma;case 20:case 52:b=m- -64|0;b=Va(b)+b|0;h=H[41349]|H[41350]<<8|(H[41351]<<16|H[41352]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[41353];break ma;case 21:case 53:b=m- -64|0;b=Va(b)+b|0;h=H[41596]|H[41597]<<8|(H[41598]<<16|H[41599]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[41600];break ma;case 22:case 54:b=m- -64|0;b=Va(b)+b|0;h=H[41316]|H[41317]<<8|(H[41318]<<16|H[41319]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[41320];break ma;case 40:case 72:break na;default:break ma}}b=m- -64|0;b=Va(b)+b|0;h=H[3698]|H[3699]<<8|(H[3700]<<16|H[3701]<<24);E[b|0]=h;E[b+1|0]=h>>>8;E[b+2|0]=h>>>16;E[b+3|0]=h>>>24;E[b+4|0]=H[3702]}i=i+1|0;h=H[i+(m+320|0)|0];if(h){continue}break}}Za(1238528,m- -64|0);i=262;break B}h=0;E[(m+320|0)+l|0]=0;E[m+64|0]=0;l=H[m+320|0];if(l){while(1){i=3158064;oa:{pa:{qa:{switch((l<<24>>24)-48|0){case 1:i=3223600;break pa;case 2:i=3158320;break pa;case 3:i=3223856;break pa;case 4:i=3158065;break pa;case 5:i=3223601;break pa;case 6:i=3158321;break pa;case 7:i=3223857;break pa;case 0:break pa;case 40:case 72:break qa;default:break oa}}i=7895160}b=m- -64|0;b=Va(b)+b|0;E[b|0]=i;E[b+1|0]=i>>>8;E[b+2|0]=i>>>16;E[b+3|0]=i>>>24}h=h+1|0;l=H[h+(m+320|0)|0];if(l){continue}break}}Za(1238528,m- -64|0);i=262}Fa=m+576|0;break z}ca(2);W()}o=i;G[309630]=i}ra:{if((o|0)<=0){G[309630]=0;b=0;break ra}if((o|0)==256){G[309630]=257;break k}b=2;if(o>>>0>291){break ra}b=E[o+127680|0]}h=b+x|0;if(h>>>0>1725){break x}h=h<<1;if((b|0)!=F[h+127984>>1]){break x}p=F[h+131440>>1];if((p|0)>0){k=k+256|0;bb(k,1238528,256);G[309630]=-2;D=D?D-1|0:0;break j}o=0-p|0;break w}o=H[p+134896|0];if(!o){break v}}x=E[o+135216|0];h=(1-x<<8)+k|0;b=G[h>>2];bb(q+4|0,h+4|0,252);sa:{switch(o-5|0){case 0:h=G[k-256>>2];if((h|0)<0){wc(36007);break l}G[309725]=h;break n;case 1:h=G[k-256>>2];if((h|0)<0){wc(36007);break l}G[309725]=h;break n;case 2:h=G[k-256>>2];if((h|0)<0){wc(36007);break l}G[309725]=h;break n;case 3:h=G[k-256>>2];if((h|0)<0){wc(36007);break l}G[309725]=h;break n;case 4:D=0;break n;case 5:b=zg(G[k>>2]);if((b|0)<0){break l}break n;case 6:h=G[309722];i=k-512|0;b=G[i>>2];j=G[(h+M(b,344)|0)+8>>2];if((j|0)>=10){b=yg(b);G[i>>2]=b;if((b|0)<0){break l}b=zg(b);if((b|0)<0){break l}h=G[309722];j=G[(h+M(b,344)|0)+8>>2]}i=G[k>>2];h=M(b,344)+h|0;G[h+8>>2]=j+1;G[(h+(j<<2)|0)+12>>2]=i;break n;case 7:b=zg(G[k>>2]);if((b|0)<0){break l}break n;case 8:j=G[309722];i=k-512|0;b=G[i>>2];h=j+M(b,344)|0;l=G[(M(G[k>>2],344)+j|0)+52>>2];if(G[h+52>>2]<(l|0)){G[h+52>>2]=l;b=G[i>>2]}h=G[(M(b,344)+j|0)+8>>2];if((h|0)>=10){b=yg(b);G[i>>2]=b;if((b|0)<0){break l}b=zg(b);if((b|0)<0){break l}j=G[309722];h=G[(j+M(b,344)|0)+8>>2]}i=G[k>>2];j=M(b,344)+j|0;G[j+8>>2]=h+1;G[(j+(h<<2)|0)+12>>2]=i;break n;case 9:h=G[309722];i=k-512|0;b=G[i>>2];j=G[(h+M(b,344)|0)+8>>2];if((j|0)>=10){b=yg(b);G[i>>2]=b;if((b|0)<0){break l}b=zg(b);if((b|0)<0){break l}h=G[309722];j=G[(h+M(b,344)|0)+8>>2]}i=G[k>>2];h=M(b,344)+h|0;G[h+8>>2]=j+1;G[(h+(j<<2)|0)+12>>2]=i;break n;case 10:j=G[309722];i=k-512|0;G[(j+M(G[i>>2],344)|0)+52>>2]=G[(M(G[k>>2],344)+j|0)+52>>2];b=G[i>>2];h=G[(M(b,344)+j|0)+8>>2];if((h|0)>=10){b=yg(b);G[i>>2]=b;if((b|0)<0){break l}b=zg(b);if((b|0)<0){break l}j=G[309722];h=G[(j+M(b,344)|0)+8>>2]}i=G[k>>2];j=M(b,344)+j|0;G[j+8>>2]=h+1;G[(j+(h<<2)|0)+12>>2]=i;break n;case 11:b=yg(G[k-256>>2]);if((b|0)<0){break l}break n;case 12:b=yg(G[k-256>>2]);if((b|0)<0){break l}break n;case 13:b=Cd(262,k,Va(k)+1|0);if((b|0)<0){break l}O=G[309722]+M(b,344)|0,P=Va(k),G[O+56>>2]=P;break n;case 14:b=xf(G[k>>2]);if((b|0)<0){break l}break n;case 15:b=11244;h=G[k-256>>2];j=G[309722]+M(h,344)|0;if(G[j+52>>2]!=259|G[j>>2]!=-1e3){break m}b=oi(G[k-768>>2],h);if((b|0)<0){break l}break n;case 16:h=k-512|0;b=bc(262,G[h>>2],38,G[k>>2]);if((b|0)<0){break l}j=M(G[h>>2],344);h=G[309722];j=G[(j+h|0)+56>>2];i=h+M(b,344)|0;h=G[(h+M(G[k>>2],344)|0)+56>>2];G[i+56>>2]=(h|0)<(j|0)?j:h;break n;case 17:h=k-512|0;b=bc(262,G[h>>2],124,G[k>>2]);if((b|0)<0){break l}j=M(G[h>>2],344);h=G[309722];j=G[(j+h|0)+56>>2];i=h+M(b,344)|0;h=G[(h+M(G[k>>2],344)|0)+56>>2];G[i+56>>2]=(h|0)<(j|0)?j:h;break n;case 18:b=5652;j=G[309722];h=G[k>>2];i=k-512|0;l=G[i>>2];if((G[(j+M(h,344)|0)+56>>2]+G[(j+M(l,344)|0)+56>>2]|0)>255){break m}b=bc(262,l,43,h);if((b|0)<0){break l}h=G[309722];G[(h+M(b,344)|0)+56>>2]=G[(h+M(G[k>>2],344)|0)+56>>2]+G[(h+M(G[i>>2],344)|0)+56>>2];break n;case 19:b=Od(G[k-768>>2],1,G[k-256>>2],0,0,0,0);if((b|0)<0){break l}break n;case 20:b=Od(G[k-1280>>2],2,G[k-768>>2],G[k-256>>2],0,0,0);if((b|0)<0){break l}break n;case 21:b=Od(G[k-1792>>2],3,G[k-1280>>2],G[k-768>>2],G[k-256>>2],0,0);if((b|0)<0){break l}break n;case 22:b=Od(G[k-2304>>2],4,G[k-1792>>2],G[k-1280>>2],G[k-768>>2],G[k-256>>2],0);if((b|0)<0){break l}break n;case 23:b=Od(G[k-2816>>2],5,G[k-2304>>2],G[k-1792>>2],G[k-1280>>2],G[k-768>>2],G[k-256>>2]);if((b|0)<0){break l}break n;case 24:b=Fb(262,286,G[k>>2]);if((b|0)<0){break l}break n;case 25:b=G[k-256>>2];break n;case 26:b=Cd(259,k,4);if((b|0)<0){break l}break n;case 27:b=Cd(260,k,8);if((b|0)<0){break l}break n;case 28:b=xf(G[k>>2]);if((b|0)<0){break l}break n;case 29:b=11244;h=G[k-256>>2];j=G[309722]+M(h,344)|0;if(G[j+52>>2]!=259|G[j>>2]!=-1e3){break m}b=oi(G[k-768>>2],h);if((b|0)<0){break l}break n;case 30:b=Vb(259,1035,0,0,0,0,0,0,0,0,0);break n;case 31:b=Vb(259,1036,0,0,0,0,0,0,0,0,0);break n;case 32:l=G[309722];h=k-512|0;b=G[h>>2];i=G[(l+M(b,344)|0)+52>>2];j=G[k>>2];l=G[(l+M(j,344)|0)+52>>2];ta:{if((i|0)>(l|0)){j=Fb(i,0,j);G[k>>2]=j;b=G[h>>2];break ta}if((i|0)>=(l|0)){break ta}b=Fb(l,0,b);G[h>>2]=b;j=G[k>>2]}b=bc(G[(G[309722]+M(b,344)|0)+52>>2],b,37,j);if((b|0)<0){break l}break n;case 33:l=G[309722];h=k-512|0;b=G[h>>2];i=G[(l+M(b,344)|0)+52>>2];j=G[k>>2];l=G[(l+M(j,344)|0)+52>>2];ua:{if((i|0)>(l|0)){j=Fb(i,0,j);G[k>>2]=j;b=G[h>>2];break ua}if((i|0)>=(l|0)){break ua}b=Fb(l,0,b);G[h>>2]=b;j=G[k>>2]}b=bc(G[(G[309722]+M(b,344)|0)+52>>2],b,43,j);if((b|0)<0){break l}break n;case 34:l=G[309722];h=k-512|0;b=G[h>>2];i=G[(l+M(b,344)|0)+52>>2];j=G[k>>2];l=G[(l+M(j,344)|0)+52>>2];va:{if((i|0)>(l|0)){j=Fb(i,0,j);G[k>>2]=j;b=G[h>>2];break va}if((i|0)>=(l|0)){break va}b=Fb(l,0,b);G[h>>2]=b;j=G[k>>2]}b=bc(G[(G[309722]+M(b,344)|0)+52>>2],b,45,j);if((b|0)<0){break l}break n;case 35:l=G[309722];h=k-512|0;b=G[h>>2];i=G[(l+M(b,344)|0)+52>>2];j=G[k>>2];l=G[(l+M(j,344)|0)+52>>2];wa:{if((i|0)>(l|0)){j=Fb(i,0,j);G[k>>2]=j;b=G[h>>2];break wa}if((i|0)>=(l|0)){break wa}b=Fb(l,0,b);G[h>>2]=b;j=G[k>>2]}b=bc(G[(G[309722]+M(b,344)|0)+52>>2],b,42,j);if((b|0)<0){break l}break n;case 36:l=G[309722];h=k-512|0;b=G[h>>2];i=G[(l+M(b,344)|0)+52>>2];j=G[k>>2];l=G[(l+M(j,344)|0)+52>>2];xa:{if((i|0)>(l|0)){j=Fb(i,0,j);G[k>>2]=j;b=G[h>>2];break xa}if((i|0)>=(l|0)){break xa}b=Fb(l,0,b);G[h>>2]=b;j=G[k>>2]}b=bc(G[(G[309722]+M(b,344)|0)+52>>2],b,47,j);if((b|0)<0){break l}break n;case 37:b=27829;j=G[309722];h=G[k-512>>2];if(G[(j+M(h,344)|0)+52>>2]!=259){break m}i=G[k>>2];if(G[(j+M(i,344)|0)+52>>2]!=259){break m}b=bc(259,h,38,i);break n;case 38:b=27829;j=G[309722];h=G[k-512>>2];if(G[(j+M(h,344)|0)+52>>2]!=259){break m}i=G[k>>2];if(G[(j+M(i,344)|0)+52>>2]!=259){break m}b=bc(259,h,124,i);break n;case 39:b=27829;j=G[309722];h=G[k-512>>2];if(G[(j+M(h,344)|0)+52>>2]!=259){break m}i=G[k>>2];if(G[(j+M(i,344)|0)+52>>2]!=259){break m}b=bc(259,h,94,i);break n;case 40:l=G[309722];h=k-512|0;b=G[h>>2];i=G[(l+M(b,344)|0)+52>>2];j=G[k>>2];l=G[(l+M(j,344)|0)+52>>2];ya:{if((i|0)>(l|0)){j=Fb(i,0,j);G[k>>2]=j;b=G[h>>2];break ya}if((i|0)>=(l|0)){break ya}b=Fb(l,0,b);G[h>>2]=b;j=G[k>>2]}b=bc(G[(G[309722]+M(b,344)|0)+52>>2],b,285,j);if((b|0)<0){break l}break n;case 41:b=G[k>>2];break n;case 42:b=G[k>>2];b=Fb(G[(G[309722]+M(b,344)|0)+52>>2],289,b);if((b|0)<0){break l}break n;case 43:b=G[k-256>>2];break n;case 44:b=k-512|0;h=Fb(G[(G[309722]+M(G[b>>2],344)|0)+52>>2],0,G[k>>2]);G[k>>2]=h;b=G[b>>2];b=bc(G[(G[309722]+M(b,344)|0)+52>>2],b,42,h);if((b|0)<0){break l}break n;case 45:h=k-512|0;b=Fb(G[(G[309722]+M(G[k>>2],344)|0)+52>>2],0,G[h>>2]);G[h>>2]=b;h=G[k>>2];b=bc(G[(G[309722]+M(h,344)|0)+52>>2],b,42,h);if((b|0)<0){break l}break n;case 46:l=G[309722];i=k-512|0;j=G[i>>2];h=G[(l+M(j,344)|0)+52>>2];b=G[k>>2];l=G[(l+M(b,344)|0)+52>>2];za:{if((h|0)>(l|0)){b=Fb(h,0,b);G[k>>2]=b;j=G[i>>2];break za}if((h|0)>=(l|0)){break za}j=Fb(l,0,j);G[i>>2]=j;b=G[k>>2]}if(!Cc(j,b)){wc(5493);break l}l=k-1024|0;h=Vb(0,1034,3,j,b,G[l>>2],0,0,0,0,0);if((h|0)<0){break l}b=G[309722];j=G[i>>2];m=G[k>>2];if(G[(b+M(j,344)|0)+56>>2]>2]){xc(h,m);j=G[i>>2];b=G[309722]}G[(M(G[l>>2],344)+b|0)+52>>2]=G[(M(j,344)+b|0)+52>>2];j=G[l>>2];if(!Cc(j,h)){wc(13975);break l}G[(M(j,344)+b|0)+52>>2]=258;i=G[(M(h,344)+b|0)+56>>2];j=b;b=G[l>>2];if((i|0)>=G[(j+M(b,344)|0)+56>>2]){b=h;break n}xc(h,b);b=h;break n;case 47:l=G[309722];i=k-512|0;j=G[i>>2];h=G[(l+M(j,344)|0)+52>>2];b=G[k>>2];l=G[(l+M(b,344)|0)+52>>2];Aa:{if((h|0)>(l|0)){b=Fb(h,0,b);G[k>>2]=b;j=G[i>>2];break Aa}if((h|0)>=(l|0)){break Aa}j=Fb(l,0,j);G[i>>2]=j;b=G[k>>2]}if(!Cc(j,b)){wc(5493);break l}l=k-1024|0;h=Vb(0,1034,3,j,b,G[l>>2],0,0,0,0,0);if((h|0)<0){break l}b=G[309722];j=G[i>>2];m=G[k>>2];if(G[(b+M(j,344)|0)+56>>2]>2]){xc(h,m);j=G[i>>2];b=G[309722]}G[(M(G[l>>2],344)+b|0)+52>>2]=G[(M(j,344)+b|0)+52>>2];j=G[l>>2];if(!Cc(j,h)){wc(13975);break l}G[(M(j,344)+b|0)+52>>2]=258;i=G[(M(h,344)+b|0)+56>>2];j=b;b=G[l>>2];if((i|0)>=G[(j+M(b,344)|0)+56>>2]){b=h;break n}xc(h,b);b=h;break n;case 48:l=G[309722];i=k-512|0;j=G[i>>2];h=G[(l+M(j,344)|0)+52>>2];b=G[k>>2];l=G[(l+M(b,344)|0)+52>>2];Ba:{if((h|0)>(l|0)){b=Fb(h,0,b);G[k>>2]=b;j=G[i>>2];break Ba}if((h|0)>=(l|0)){break Ba}j=Fb(l,0,j);G[i>>2]=j;b=G[k>>2]}if(!Cc(j,b)){wc(5493);break l}l=k-1024|0;h=Vb(0,1034,3,j,b,G[l>>2],0,0,0,0,0);if((h|0)<0){break l}b=G[309722];j=G[i>>2];m=G[k>>2];if(G[(b+M(j,344)|0)+56>>2]>2]){xc(h,m);j=G[i>>2];b=G[309722]}G[(M(G[l>>2],344)+b|0)+52>>2]=G[(M(j,344)+b|0)+52>>2];j=G[l>>2];if(!Cc(j,h)){wc(13975);break l}G[(M(j,344)+b|0)+52>>2]=258;i=G[(M(h,344)+b|0)+56>>2];j=b;b=G[l>>2];if((i|0)>=G[(j+M(b,344)|0)+56>>2]){b=h;break n}xc(h,b);b=h;break n;case 49:b=28709;h=k-256|0;if(H[h|0]!=82){break m}if(Xa(h,64608)){if(Xa(h,64546)){break m}b=1042}else{b=1001}b=Vb(260,b,0,0,0,0,0,0,0,0,0);if((b|0)<0){break l}break n;case 50:b=28642;Ca:{Da:{Ea:{Fa:{h=k-512|0;switch(H[h|0]-65|0){case 0:break Da;case 13:break Ea;case 18:break Fa;default:break m}}if(Xa(h,64596)){break m}b=Vb(259,1002,1,G[k-256>>2],0,0,0,0,0,0,0);break Ca}if(Xa(h,64616)){break m}b=Cd(259,(G[309722]+M(G[k-256>>2],344)|0)+56|0,4);break Ca}if(Xa(h,64601)){break m}G[q+26064>>2]=0;b=bc(259,G[k-256>>2],290,Cd(259,q+26064|0,4))}if((b|0)<0){break l}break n;case 51:b=28450;h=k-512|0;if(H[h|0]!=78){break m}Ga:{if(!Xa(h,64616)){b=Cd(259,(G[309722]+M(G[k-256>>2],344)|0)+56|0,4);break Ga}if(Xa(h,64728)){break m}b=Vb(259,1040,1,G[k-256>>2],0,0,0,0,0,0,0)}if((b|0)<0){break l}break n;case 52:b=28421;Ha:{Ia:{Ja:{Ka:{La:{Ma:{h=k-512|0;switch(H[h|0]-65|0){case 0:break Ja;case 12:break Ka;case 18:break La;case 13:break Ma;default:break m}}if(!Xa(h,64616)){b=Cd(259,(G[309722]+M(G[k-256>>2],344)|0)+56|0,4);break Ha}if(Xa(h,64728)){break m}b=Cd(259,(G[309722]+M(G[k-256>>2],344)|0)+56|0,4);break Ha}if(Xa(h,64596)){break m}b=Vb(259,1002,1,G[k-256>>2],0,0,0,0,0,0,0);break Ha}if(Xa(h,64569)){break Ia}b=G[k-256>>2];b=Vb(G[(G[309722]+M(b,344)|0)+52>>2],1022,1,b,0,0,0,0,0,0,0);G[(G[309722]+M(b,344)|0)+56>>2]=1;break Ha}if(Xa(h,64601)){break m}G[q+26064>>2]=0;b=bc(259,G[k-256>>2],290,Cd(259,q+26064|0,4));break Ha}if(Xa(h,64431)){break m}b=G[k-256>>2];b=Vb(G[(G[309722]+M(b,344)|0)+52>>2],1024,1,b,0,0,0,0,0,0,0);G[(G[309722]+M(b,344)|0)+56>>2]=1}if((b|0)<0){break l}break n;case 53:Na:{Oa:{Pa:{Qa:{Ra:{Sa:{Ta:{Ua:{Va:{Wa:{Xa:{l=k-512|0;b=H[l|0];switch(b-65|0){case 17:break Oa;case 13:break Ta;case 12:break Ua;case 0:break Wa;case 18:break Xa;default:break Na}}if(Xa(l,64596)){break Va}b=G[k-256>>2];b=Vb(G[(G[309722]+M(b,344)|0)+52>>2],1002,1,b,0,0,0,0,0,0,0);break o}if(Xa(l,64704)){break Sa}b=Vb(260,1038,1,G[k-256>>2],0,0,0,0,0,0,0);break o}if(Xa(l,64436)){break Ra}b=Vb(260,1039,1,G[k-256>>2],0,0,0,0,0,0,0);break o}if(Xa(l,64588)){break Pa}b=G[k-256>>2];b=Vb(G[(G[309722]+M(b,344)|0)+52>>2],1037,1,b,0,0,0,0,0,0,0);break o}if(!Xa(l,64616)){b=Cd(259,(G[309722]+M(G[k-256>>2],344)|0)+56|0,4);break o}if(Xa(l,64728)){break Na}b=Vb(259,1040,1,G[k-256>>2],0,0,0,0,0,0,0);break o}Ya:{if(Xa(l,64601)){break Ya}h=k-256|0;if(G[(G[309722]+M(G[h>>2],344)|0)+52>>2]!=259){break Ya}G[q+26064>>2]=0;b=bc(259,G[h>>2],290,Cd(259,q+26064|0,4));break o}if(Xa(l,64601)){break Qa}h=k-256|0;if(G[(G[309722]+M(G[h>>2],344)|0)+52>>2]!=260){break Qa}G[q+26064>>2]=0;G[q+26068>>2]=0;b=bc(260,G[h>>2],290,Cd(260,q+26064|0,8));break o}Za:{if(Xa(l,64678)){break Za}h=k-256|0;if(G[(G[309722]+M(G[h>>2],344)|0)+52>>2]!=259){break Za}G[q+26064>>2]=0;b=bc(259,G[h>>2],291,Cd(259,q+26064|0,4));break o}if(Xa(l,64678)){break Na}h=k-256|0;if(G[(G[309722]+M(G[h>>2],344)|0)+52>>2]!=260){break Na}G[q+26064>>2]=0;G[q+26068>>2]=0;b=bc(260,G[h>>2],291,Cd(260,q+26064|0,8));break o}if(Xa(l,64464)){break Na}b=Vb(0,1017,1,G[k-256>>2],0,0,0,0,0,0,0);break o}if(!Xa(l,64569)){b=G[k-256>>2];b=Vb(G[(G[309722]+M(b,344)|0)+52>>2],1022,1,b,0,0,0,0,0,0,0);break o}if(Xa(l,64431)){break Na}b=G[k-256>>2];b=Vb(G[(G[309722]+M(b,344)|0)+52>>2],1024,1,b,0,0,0,0,0,0,0);break o}if(!Xa(l,64608)){b=Vb(0,1001,1,G[k-256>>2],0,0,0,0,0,0,0);if((b|0)<0){break l}G[(G[309722]+M(b,344)|0)+52>>2]=260;break n}if(Xa(l,64546)){break Na}b=Vb(0,1042,1,G[k-256>>2],0,0,0,0,0,0,0);if((b|0)<0){break l}G[(G[309722]+M(b,344)|0)+52>>2]=260;break n}j=k-256|0;h=G[j>>2];if(G[(G[309722]+M(h,344)|0)+52>>2]!=260){h=Fb(260,0,h);G[j>>2]=h;b=H[l|0]}_a:{$a:{ab:{bb:{cb:{db:{eb:{i=b&255;if((i|0)==83){if(Xa(l,64564)){break eb}b=Vb(0,1004,1,h,0,0,0,0,0,0,0);break o}j=0;fb:{switch(i-65|0){case 2:if(Xa(l,64459)){break db}b=Vb(0,1005,1,h,0,0,0,0,0,0,0);break o;case 19:if(Xa(l,64583)){break cb}b=Vb(0,1006,1,h,0,0,0,0,0,0,0);break o;case 0:break fb;default:break ab}}gb:{if(Xa(l,64555)){if(Xa(l,64563)){break gb}}b=Vb(0,1007,1,h,0,0,0,0,0,0,0);break o}hb:{if(Xa(l,64450)){if(Xa(l,64458)){break hb}}b=Vb(0,1008,1,h,0,0,0,0,0,0,0);break o}if(Xa(l,64574)){if(Xa(l,64582)){break $a}}b=Vb(0,1009,1,h,0,0,0,0,0,0,0);break o}if(Xa(l,64661)){break bb}b=Vb(0,1010,1,h,0,0,0,0,0,0,0);break o}if(Xa(l,64655)){break bb}b=Vb(0,1011,1,h,0,0,0,0,0,0,0);break o}if(Xa(l,64667)){break $a}b=Vb(0,1012,1,h,0,0,0,0,0,0,0);break o}j=(b&255)!=83}ib:{jb:{kb:{i=b&255;switch(i-69|0){case 7:break jb;case 0:break kb;default:break ib}}if(Xa(l,64512)){break s}b=Vb(0,1013,1,h,0,0,0,0,0,0,0);break o}if(!Xa(l,64673)){b=Vb(0,1014,1,h,0,0,0,0,0,0,0);break o}if(Xa(l,64745)){break s}b=Vb(0,1015,1,h,0,0,0,0,0,0,0);break o}if((i|0)==83){break t}if((b&255)!=82){break $a}i=1;if(Xa(l,64713)){break _a}b=Vb(0,1021,1,h,0,0,0,0,0,0,0);break o}i=0;if((b&255)!=70){break _a}if(Xa(l,64477)){break _a}b=Vb(0,1020,1,h,0,0,0,0,0,0,0);break o}if(!j){break p}break q;case 54:h=k-1024|0;if(H[h|0]!=83){break n}if(Xa(h,64469)){break n}b=Vb(259,1045,2,G[k-768>>2],G[k-256>>2],0,0,0,0,0,0);if((b|0)<0){break l}break n;case 55:b=28571;lb:{mb:{nb:{ob:{h=k-1024|0;switch(H[h|0]-65|0){case 18:break lb;case 12:break mb;case 0:break nb;case 3:break ob;default:break m}}if(Xa(h,64640)){break m}b=22761;j=G[309722];l=k-768|0;i=G[l>>2];m=k-256|0;h=G[m>>2];if(G[(j+M(i,344)|0)+56>>2]>2]){break m}if(!Cc(i,h)){break m}b=G[(j+M(i,344)|0)+52>>2];j=G[(j+M(h,344)|0)+52>>2];pb:{if((b|0)>(j|0)){h=Fb(b,0,h);G[m>>2]=h;i=G[l>>2];break pb}if((b|0)>=(j|0)){break pb}i=Fb(j,0,i);G[l>>2]=i;h=G[m>>2]}b=Vb(0,1031,2,i,h,0,0,0,0,0,0);if((b|0)<0){break l}break n}if(Xa(h,64736)){break m}h=G[309722];i=k-768|0;b=G[i>>2];if(G[(h+M(b,344)|0)+52>>2]!=260){b=Fb(260,0,b);G[i>>2]=b;l=G[309722]}else{l=h}h=k-256|0;j=G[h>>2];if(G[(l+M(j,344)|0)+52>>2]!=260){j=Fb(260,0,j);G[h>>2]=j;b=G[i>>2]}if(!Cc(b,j)){wc(22920);break l}b=Vb(0,1018,2,b,j,0,0,0,0,0,0);if((b|0)<0){break l}j=G[309722];h=G[h>>2];if(G[(j+M(G[i>>2],344)|0)+56>>2]>=G[(j+M(h,344)|0)+56>>2]){break n}xc(b,h);break n}if(!Xa(h,64569)){m=G[309722];h=k-768|0;j=G[h>>2];l=G[(m+M(j,344)|0)+52>>2];i=k-256|0;b=G[i>>2];m=G[(m+M(b,344)|0)+52>>2];qb:{if((l|0)>(m|0)){b=Fb(l,0,b);G[i>>2]=b;j=G[h>>2];break qb}if((l|0)>=(m|0)){break qb}j=Fb(m,0,j);G[h>>2]=j;b=G[i>>2]}if(!Cc(j,b)){wc(23023);break l}b=Vb(0,1023,2,j,b,0,0,0,0,0,0);if((b|0)<0){break l}l=M(G[h>>2],344);h=G[309722];j=G[i>>2];if(G[(l+h|0)+56>>2]>=G[(h+M(j,344)|0)+56>>2]){break n}xc(b,j);break n}if(Xa(h,64431)){break m}m=G[309722];h=k-768|0;j=G[h>>2];l=G[(m+M(j,344)|0)+52>>2];i=k-256|0;b=G[i>>2];m=G[(m+M(b,344)|0)+52>>2];rb:{if((l|0)>(m|0)){b=Fb(l,0,b);G[i>>2]=b;j=G[h>>2];break rb}if((l|0)>=(m|0)){break rb}j=Fb(m,0,j);G[h>>2]=j;b=G[i>>2]}if(!Cc(j,b)){wc(22971);break l}b=Vb(0,1025,2,j,b,0,0,0,0,0,0);if((b|0)<0){break l}l=M(G[h>>2],344);h=G[309722];j=G[i>>2];if(G[(l+h|0)+56>>2]>=G[(h+M(j,344)|0)+56>>2]){break n}xc(b,j);break n}if(Xa(h,64623)){break m}b=4942;h=G[309722];i=k-768|0;j=G[i>>2];l=h+M(j,344)|0;if(G[l>>2]!=-1e3|G[l+56>>2]!=1){break m}r=G[(h+M(j,344)|0)+52>>2];l=k-256|0;b=G[l>>2];h=G[(h+M(b,344)|0)+52>>2];if((r|0)!=(h|0)){j=Fb(h,0,j);G[i>>2]=j;b=G[l>>2]}b=Vb(0,1046,2,b,j,0,0,0,0,0,0);break n;case 56:b=28478;h=k-2048|0;if(H[h|0]!=65){break m}if(Xa(h,64526)){break m}b=G[309722];n=k-1792|0;h=G[n>>2];if(G[(b+M(h,344)|0)+52>>2]!=260){O=n,P=Fb(260,0,h),G[O>>2]=P;b=G[309722]}l=k-1280|0;h=G[l>>2];if(G[(M(h,344)+b|0)+52>>2]!=260){O=l,P=Fb(260,0,h),G[O>>2]=P;b=G[309722]}m=k-768|0;h=G[m>>2];if(G[(M(h,344)+b|0)+52>>2]!=260){O=m,P=Fb(260,0,h),G[O>>2]=P;b=G[309722]}p=k-256|0;i=G[p>>2];if(G[(b+M(i,344)|0)+52>>2]!=260){i=Fb(260,0,i);G[p>>2]=i}b=22711;t=G[n>>2];h=G[l>>2];if(!Cc(t,h)){break m}j=G[m>>2];if(!Cc(h,j)){break m}if(!Cc(j,i)){break m}h=Vb(0,1041,4,t,h,j,i,0,0,0,0);if((h|0)<0){break l}b=G[309722];i=G[l>>2];j=G[(b+M(i,344)|0)+56>>2];if((j|0)>G[(M(G[n>>2],344)+b|0)+56>>2]){xc(h,i);b=G[309722];j=G[(b+M(G[l>>2],344)|0)+56>>2]}l=j;i=G[m>>2];j=G[(M(i,344)+b|0)+56>>2];if((l|0)<(j|0)){xc(h,i);b=G[309722];j=G[(b+M(G[m>>2],344)|0)+56>>2]}i=b;b=G[p>>2];if(G[(i+M(b,344)|0)+56>>2]<=(j|0)){b=h;break n}xc(h,b);b=h;break n;case 57:b=Od(G[k-768>>2],1,G[k-256>>2],0,0,0,0);if((b|0)<0){break l}break n;case 58:b=Od(G[k-1280>>2],2,G[k-768>>2],G[k-256>>2],0,0,0);if((b|0)<0){break l}break n;case 59:b=Od(G[k-1792>>2],3,G[k-1280>>2],G[k-768>>2],G[k-256>>2],0,0);if((b|0)<0){break l}break n;case 60:b=Od(G[k-2304>>2],4,G[k-1792>>2],G[k-1280>>2],G[k-768>>2],G[k-256>>2],0);if((b|0)<0){break l}break n;case 61:b=Od(G[k-2816>>2],5,G[k-2304>>2],G[k-1792>>2],G[k-1280>>2],G[k-768>>2],G[k-256>>2]);if((b|0)<0){break l}break n;case 62:b=Fb(259,287,G[k>>2]);if((b|0)<0){break l}break n;case 63:b=Fb(259,287,G[k>>2]);if((b|0)<0){break l}break n;case 64:b=Fb(260,288,G[k>>2]);if((b|0)<0){break l}break n;case 65:b=Fb(260,288,G[k>>2]);if((b|0)<0){break l}break n;case 66:b=Cd(258,k,1);if((b|0)<0){break l}break n;case 67:b=xf(G[k>>2]);if((b|0)<0){break l}break n;case 68:b=11244;h=G[k-256>>2];j=G[309722]+M(h,344)|0;if(G[j+52>>2]!=259|G[j>>2]!=-1e3){break m}b=oi(G[k-768>>2],h);if((b|0)<0){break l}break n;case 69:b=bc(258,G[k-512>>2],278,G[k>>2]);if((b|0)<0){break l}G[(G[309722]+M(b,344)|0)+56>>2]=1;break n;case 70:b=bc(258,G[k-512>>2],279,G[k>>2]);if((b|0)<0){break l}G[(G[309722]+M(b,344)|0)+56>>2]=1;break n;case 71:b=bc(258,G[k-512>>2],281,G[k>>2]);if((b|0)<0){break l}G[(G[309722]+M(b,344)|0)+56>>2]=1;break n;case 72:b=bc(258,G[k-512>>2],282,G[k>>2]);if((b|0)<0){break l}G[(G[309722]+M(b,344)|0)+56>>2]=1;break n;case 73:b=bc(258,G[k-512>>2],280,G[k>>2]);if((b|0)<0){break l}G[(G[309722]+M(b,344)|0)+56>>2]=1;break n;case 74:b=bc(258,G[k-512>>2],283,G[k>>2]);if((b|0)<0){break l}G[(G[309722]+M(b,344)|0)+56>>2]=1;break n;case 75:l=G[309722];h=k-512|0;j=G[h>>2];i=G[(l+M(j,344)|0)+52>>2];b=G[k>>2];l=G[(l+M(b,344)|0)+52>>2];sb:{if((i|0)>(l|0)){b=Fb(i,0,b);G[k>>2]=b;j=G[h>>2];break sb}if((i|0)>=(l|0)){break sb}j=Fb(l,0,j);G[h>>2]=j;b=G[k>>2]}b=bc(258,j,280,b);if((b|0)<0){break l}break n;case 76:l=G[309722];h=k-512|0;j=G[h>>2];i=G[(l+M(j,344)|0)+52>>2];b=G[k>>2];l=G[(l+M(b,344)|0)+52>>2];tb:{if((i|0)>(l|0)){b=Fb(i,0,b);G[k>>2]=b;j=G[h>>2];break tb}if((i|0)>=(l|0)){break tb}j=Fb(l,0,j);G[h>>2]=j;b=G[k>>2]}b=bc(258,j,281,b);if((b|0)<0){break l}break n;case 77:l=G[309722];h=k-512|0;j=G[h>>2];i=G[(l+M(j,344)|0)+52>>2];b=G[k>>2];l=G[(l+M(b,344)|0)+52>>2];ub:{if((i|0)>(l|0)){b=Fb(i,0,b);G[k>>2]=b;j=G[h>>2];break ub}if((i|0)>=(l|0)){break ub}j=Fb(l,0,j);G[h>>2]=j;b=G[k>>2]}b=bc(258,j,283,b);if((b|0)<0){break l}break n;case 78:l=G[309722];h=k-512|0;j=G[h>>2];i=G[(l+M(j,344)|0)+52>>2];b=G[k>>2];l=G[(l+M(b,344)|0)+52>>2];vb:{if((i|0)>(l|0)){b=Fb(i,0,b);G[k>>2]=b;j=G[h>>2];break vb}if((i|0)>=(l|0)){break vb}j=Fb(l,0,j);G[h>>2]=j;b=G[k>>2]}b=bc(258,j,282,b);if((b|0)<0){break l}break n;case 79:l=G[309722];h=k-512|0;j=G[h>>2];i=G[(l+M(j,344)|0)+52>>2];b=G[k>>2];l=G[(l+M(b,344)|0)+52>>2];wb:{if((i|0)>(l|0)){b=Fb(i,0,b);G[k>>2]=b;j=G[h>>2];break wb}if((i|0)>=(l|0)){break wb}j=Fb(l,0,j);G[h>>2]=j;b=G[k>>2]}b=bc(258,j,126,b);if((b|0)<0){break l}break n;case 80:l=G[309722];h=k-512|0;j=G[h>>2];i=G[(l+M(j,344)|0)+52>>2];b=G[k>>2];l=G[(l+M(b,344)|0)+52>>2];xb:{if((i|0)>(l|0)){b=Fb(i,0,b);G[k>>2]=b;j=G[h>>2];break xb}if((i|0)>=(l|0)){break xb}j=Fb(l,0,j);G[h>>2]=j;b=G[k>>2]}b=bc(258,j,278,b);if((b|0)<0){break l}break n;case 81:l=G[309722];h=k-512|0;j=G[h>>2];i=G[(l+M(j,344)|0)+52>>2];b=G[k>>2];l=G[(l+M(b,344)|0)+52>>2];yb:{if((i|0)>(l|0)){b=Fb(i,0,b);G[k>>2]=b;j=G[h>>2];break yb}if((i|0)>=(l|0)){break yb}j=Fb(l,0,j);G[h>>2]=j;b=G[k>>2]}b=bc(258,j,279,b);if((b|0)<0){break l}break n;case 82:b=bc(258,G[k-512>>2],278,G[k>>2]);if((b|0)<0){break l}G[(G[309722]+M(b,344)|0)+56>>2]=1;break n;case 83:b=bc(258,G[k-512>>2],279,G[k>>2]);if((b|0)<0){break l}G[(G[309722]+M(b,344)|0)+56>>2]=1;break n;case 84:b=bc(258,G[k-512>>2],280,G[k>>2]);if((b|0)<0){break l}G[(G[309722]+M(b,344)|0)+56>>2]=1;break n;case 85:b=bc(258,G[k-512>>2],283,G[k>>2]);if((b|0)<0){break l}G[(G[309722]+M(b,344)|0)+56>>2]=1;break n;case 86:b=bc(258,G[k-512>>2],281,G[k>>2]);if((b|0)<0){break l}G[(G[309722]+M(b,344)|0)+56>>2]=1;break n;case 87:b=bc(258,G[k-512>>2],282,G[k>>2]);if((b|0)<0){break l}G[(G[309722]+M(b,344)|0)+56>>2]=1;break n;case 88:b=bc(258,G[k-512>>2],277,G[k>>2]);if((b|0)<0){break l}break n;case 89:b=bc(258,G[k-512>>2],276,G[k>>2]);if((b|0)<0){break l}break n;case 90:b=bc(258,G[k-512>>2],278,G[k>>2]);if((b|0)<0){break l}break n;case 91:b=bc(258,G[k-512>>2],279,G[k>>2]);if((b|0)<0){break l}break n;case 92:l=G[309722];j=k-1024|0;i=G[j>>2];h=G[(l+M(i,344)|0)+52>>2];b=k-512|0;m=G[b>>2];l=G[(l+M(m,344)|0)+52>>2];zb:{if((h|0)>(l|0)){O=b,P=Fb(h,0,m),G[O>>2]=P;i=G[j>>2];break zb}if((h|0)>=(l|0)){break zb}i=Fb(l,0,i);G[j>>2]=i}m=G[309722];l=G[(m+M(i,344)|0)+52>>2];h=G[k>>2];m=G[(m+M(h,344)|0)+52>>2];Ab:{if((l|0)>(m|0)){h=Fb(l,0,h);G[k>>2]=h;break Ab}if((l|0)>=(m|0)){break Ab}O=j,P=Fb(m,0,i),G[O>>2]=P;h=G[k>>2]}m=G[309722];i=G[b>>2];l=G[(m+M(i,344)|0)+52>>2];m=G[(m+M(h,344)|0)+52>>2];Bb:{if((l|0)>(m|0)){O=k,P=Fb(l,0,h),G[O>>2]=P;i=G[b>>2];break Bb}if((l|0)>=(m|0)){break Bb}i=Fb(m,0,i);G[b>>2]=i}O=b,P=bc(258,i,282,G[j>>2]),G[O>>2]=P;h=bc(258,G[j>>2],282,G[k>>2]);G[k>>2]=h;b=bc(258,G[b>>2],277,h);if((b|0)<0){break l}break n;case 93:h=k-512|0;b=G[h>>2];j=G[k>>2];if(!Cc(b,j)){wc(5493);break l}i=j;j=k-1024|0;b=Vb(0,1034,3,b,i,G[j>>2],0,0,0,0,0);if((b|0)<0){break l}l=M(G[h>>2],344);h=G[309722];i=G[k>>2];if(G[(l+h|0)+56>>2]>2]){xc(b,i)}h=G[j>>2];if(!Cc(h,b)){wc(13975);break l}j=G[309722];if(G[(j+M(b,344)|0)+56>>2]>=G[(j+M(h,344)|0)+56>>2]){break n}xc(b,h);break n;case 94:b=28605;h=k-512|0;if(H[h|0]!=73){break m}if(Xa(h,64632)){break m}b=Vb(0,1030,1,G[k-256>>2],0,0,0,0,0,0,0);if((b|0)<0){break l}G[(G[309722]+M(b,344)|0)+52>>2]=258;break n;case 95:b=28605;h=k-512|0;if(H[h|0]!=73){break m}if(Xa(h,64632)){break m}b=Vb(0,1030,1,G[k-256>>2],0,0,0,0,0,0,0);if((b|0)<0){break l}G[(G[309722]+M(b,344)|0)+52>>2]=258;break n;case 96:b=28605;h=k-512|0;if(H[h|0]!=73){break m}if(Xa(h,64632)){break m}b=Vb(258,1030,1,G[k-256>>2],0,0,0,0,0,0,0);if((b|0)<0){break l}break n;case 97:b=28563;h=k-1024|0;if(H[h|0]!=68){break m}if(Xa(h,64640)){break m}b=22761;i=G[309722];h=G[k-768>>2];j=G[k-256>>2];if(G[(i+M(h,344)|0)+56>>2]>2]){break m}if(!Cc(h,j)){break m}b=Vb(0,1031,2,h,j,0,0,0,0,0,0);if((b|0)<0){break l}break n;case 98:b=G[309722];i=k-1280|0;h=G[i>>2];if(G[(b+M(h,344)|0)+52>>2]!=260){O=i,P=Fb(260,0,h),G[O>>2]=P;b=G[309722]}l=k-768|0;j=G[l>>2];if(G[(M(j,344)+b|0)+52>>2]!=260){j=Fb(260,0,j);G[l>>2]=j;b=G[309722]}m=k-256|0;h=G[m>>2];if(G[(b+M(h,344)|0)+52>>2]!=260){h=Fb(260,0,h);G[m>>2]=h;j=G[l>>2]}b=22663;n=G[i>>2];if(!Cc(n,j)){break m}if(!Cc(j,h)){break m}b=28300;p=k-1536|0;if(H[p|0]!=78){break m}if(Xa(p,64506)){break m}b=Vb(258,1026,3,n,j,h,0,0,0,0,0);if((b|0)<0){break l}j=G[309722];n=G[i>>2];h=G[(j+M(n,344)|0)+56>>2];if((h|0)>G[(M(b,344)+j|0)+56>>2]){xc(b,n);j=G[309722];h=G[(j+M(G[i>>2],344)|0)+56>>2]}r=h;i=G[l>>2];h=G[(M(i,344)+j|0)+56>>2];if((r|0)<(h|0)){xc(b,i);j=G[309722];h=G[(j+M(G[l>>2],344)|0)+56>>2]}i=h;h=G[m>>2];if((i|0)>=G[(M(h,344)+j|0)+56>>2]){break n}xc(b,h);break n;case 99:b=G[309722];l=k-2304|0;h=G[l>>2];if(G[(b+M(h,344)|0)+52>>2]!=260){O=l,P=Fb(260,0,h),G[O>>2]=P;b=G[309722]}m=k-1792|0;h=G[m>>2];if(G[(M(h,344)+b|0)+52>>2]!=260){O=m,P=Fb(260,0,h),G[O>>2]=P;b=G[309722]}n=k-1280|0;h=G[n>>2];if(G[(M(h,344)+b|0)+52>>2]!=260){O=n,P=Fb(260,0,h),G[O>>2]=P;b=G[309722]}p=k-768|0;h=G[p>>2];if(G[(M(h,344)+b|0)+52>>2]!=260){O=p,P=Fb(260,0,h),G[O>>2]=P;b=G[309722]}t=k-256|0;i=G[t>>2];if(G[(b+M(i,344)|0)+52>>2]!=260){i=Fb(260,0,i);G[t>>2]=i}b=22870;r=G[l>>2];h=G[m>>2];if(!Cc(r,h)){break m}j=G[n>>2];if(!Cc(h,j)){break m}y=G[p>>2];if(!Cc(j,y)){break m}if(!Cc(y,i)){break m}b=28300;w=k-2560|0;if(H[w|0]!=67){break m}if(Xa(w,64696)){break m}h=Vb(258,1027,5,r,h,j,y,i,0,0,0);if((h|0)<0){break l}b=G[309722];i=G[l>>2];j=G[(b+M(i,344)|0)+56>>2];if((j|0)>G[(M(h,344)+b|0)+56>>2]){xc(h,i);b=G[309722];j=G[(b+M(G[l>>2],344)|0)+56>>2]}l=j;i=G[m>>2];j=G[(M(i,344)+b|0)+56>>2];if((l|0)<(j|0)){xc(h,i);b=G[309722];j=G[(b+M(G[m>>2],344)|0)+56>>2]}l=j;i=G[n>>2];j=G[(M(i,344)+b|0)+56>>2];if((l|0)<(j|0)){xc(h,i);b=G[309722];j=G[(b+M(G[n>>2],344)|0)+56>>2]}l=j;i=G[p>>2];j=G[(M(i,344)+b|0)+56>>2];if((l|0)<(j|0)){xc(h,i);b=G[309722];j=G[(b+M(G[p>>2],344)|0)+56>>2]}i=b;b=G[t>>2];if(G[(i+M(b,344)|0)+56>>2]<=(j|0)){b=h;break n}xc(h,b);b=h;break n;case 100:b=G[309722];i=k-3328|0;h=G[i>>2];if(G[(b+M(h,344)|0)+52>>2]!=260){O=i,P=Fb(260,0,h),G[O>>2]=P;b=G[309722]}l=k-2816|0;h=G[l>>2];if(G[(M(h,344)+b|0)+52>>2]!=260){O=l,P=Fb(260,0,h),G[O>>2]=P;b=G[309722]}m=k-2304|0;h=G[m>>2];if(G[(M(h,344)+b|0)+52>>2]!=260){O=m,P=Fb(260,0,h),G[O>>2]=P;b=G[309722]}n=k-1792|0;h=G[n>>2];if(G[(M(h,344)+b|0)+52>>2]!=260){O=n,P=Fb(260,0,h),G[O>>2]=P;b=G[309722]}p=k-1280|0;h=G[p>>2];if(G[(M(h,344)+b|0)+52>>2]!=260){O=p,P=Fb(260,0,h),G[O>>2]=P;b=G[309722]}t=k-768|0;h=G[t>>2];if(G[(M(h,344)+b|0)+52>>2]!=260){O=t,P=Fb(260,0,h),G[O>>2]=P;b=G[309722]}y=k-256|0;j=G[y>>2];if(G[(b+M(j,344)|0)+52>>2]!=260){j=Fb(260,0,j);G[y>>2]=j}b=22812;N=G[i>>2];h=G[l>>2];if(!Cc(N,h)){break m}r=G[m>>2];if(!Cc(h,r)){break m}w=G[n>>2];if(!Cc(r,w)){break m}z=G[p>>2];if(!Cc(w,z)){break m}B=G[t>>2];if(!Cc(z,B)){break m}if(!Cc(B,j)){break m}b=28331;Cb:{Db:{Eb:{C=k-3584|0;switch(H[C|0]-66|0){case 3:break Db;case 0:break Eb;default:break m}}if(Xa(C,64426)){break m}b=1028;break Cb}if(Xa(C,64687)){break m}b=1029}h=Vb(258,b,7,N,h,r,w,z,B,j,0);if((h|0)<0){break l}b=G[309722];r=G[i>>2];j=G[(b+M(r,344)|0)+56>>2];if((j|0)>G[(M(h,344)+b|0)+56>>2]){xc(h,r);b=G[309722];j=G[(b+M(G[i>>2],344)|0)+56>>2]}r=j;i=G[l>>2];j=G[(M(i,344)+b|0)+56>>2];if((r|0)<(j|0)){xc(h,i);b=G[309722];j=G[(b+M(G[l>>2],344)|0)+56>>2]}l=j;i=G[m>>2];j=G[(M(i,344)+b|0)+56>>2];if((l|0)<(j|0)){xc(h,i);b=G[309722];j=G[(b+M(G[m>>2],344)|0)+56>>2]}l=j;i=G[n>>2];j=G[(M(i,344)+b|0)+56>>2];if((l|0)<(j|0)){xc(h,i);b=G[309722];j=G[(b+M(G[n>>2],344)|0)+56>>2]}l=j;i=G[p>>2];j=G[(M(i,344)+b|0)+56>>2];if((l|0)<(j|0)){xc(h,i);b=G[309722];j=G[(b+M(G[p>>2],344)|0)+56>>2]}l=j;i=G[t>>2];j=G[(M(i,344)+b|0)+56>>2];if((l|0)<(j|0)){xc(h,i);b=G[309722];j=G[(b+M(G[t>>2],344)|0)+56>>2]}i=b;b=G[y>>2];if(G[(i+M(b,344)|0)+56>>2]<=(j|0)){b=h;break n}xc(h,b);b=h;break n;case 101:b=xg(1032,92041,-99,-99,49028,49036);if((b|0)<0){break l}break n;case 102:b=xg(1032,k-256|0,-99,-99,49028,49036);if((b|0)<0){break l}break n;case 103:b=xg(1032,k-768|0,G[k-256>>2],-99,49028,49036);if((b|0)<0){break l}break n;case 104:b=xg(1032,k-1792|0,G[k-1280>>2],-99,k-768|0,k-256|0);if((b|0)<0){break l}break n;case 105:b=xg(1047,k-1280|0,G[k-768>>2],G[k-256>>2],49028,49036);if((b|0)<0){break l}break n;case 106:b=xg(1047,k-2304|0,G[k-1792>>2],G[k-1280>>2],k-768|0,k-256|0);if((b|0)<0){break l}break n;case 107:b=Xj(k-256|0,-99,-99,92041);if((b|0)<0){break l}break n;case 108:b=Xj(k-1280|0,G[k-768>>2],G[k-256>>2],92041);if((b|0)<0){break l}break n;case 109:b=Xj(k-1792|0,G[k-1280>>2],G[k-768>>2],k-256|0);if((b|0)<0){break l}break n;case 110:b=Od(G[k-768>>2],1,G[k-256>>2],0,0,0,0);if((b|0)<0){break l}break n;case 111:b=Od(G[k-1280>>2],2,G[k-768>>2],G[k-256>>2],0,0,0);if((b|0)<0){break l}break n;case 112:b=Od(G[k-1792>>2],3,G[k-1280>>2],G[k-768>>2],G[k-256>>2],0,0);if((b|0)<0){break l}break n;case 113:b=Od(G[k-2304>>2],4,G[k-1792>>2],G[k-1280>>2],G[k-768>>2],G[k-256>>2],0);if((b|0)<0){break l}break n;case 114:b=Od(G[k-2816>>2],5,G[k-2304>>2],G[k-1792>>2],G[k-1280>>2],G[k-768>>2],G[k-256>>2]);if((b|0)<0){break l}break n;case 115:b=Fb(258,286,G[k>>2]);if((b|0)<0){break l}break n;case 116:b=G[k-256>>2];break n;case 117:b=Cd(261,k,Va(k)+1|0);if((b|0)<0){break l}O=G[309722]+M(b,344)|0,P=Va(k),G[O+56>>2]=P;break n;case 118:b=xf(G[k>>2]);if((b|0)<0){break l}break n;case 119:b=11244;h=G[k-256>>2];j=G[309722]+M(h,344)|0;if(G[j+52>>2]!=259|G[j>>2]!=-1e3){break m}b=oi(G[k-768>>2],h);if((b|0)>=0){break n}break l;case 120:b=Vb(261,1036,0,0,0,0,0,0,0,0,0);break n;case 121:b=G[k-256>>2];break n;case 122:b=6389;j=G[309722];h=G[k>>2];i=k-512|0;l=G[i>>2];if((G[(j+M(h,344)|0)+56>>2]+G[(j+M(l,344)|0)+56>>2]|0)>255){break m}b=bc(261,l,43,h);if((b|0)<0){break l}h=G[309722];G[(h+M(b,344)|0)+56>>2]=G[(h+M(G[k>>2],344)|0)+56>>2]+G[(h+M(G[i>>2],344)|0)+56>>2];break n;case 123:b=15790;h=G[309722];j=G[k-1024>>2];if(G[(h+M(j,344)|0)+56>>2]!=1){break m}i=G[k>>2];b=G[(h+M(i,344)|0)+56>>2];l=k-512|0;m=G[l>>2];h=G[(h+M(m,344)|0)+56>>2];b=Vb(0,1034,3,m,i,j,0,0,0,0,(b|0)>(h|0)?b:h);if((b|0)<0){break l}h=G[309722];j=G[k>>2];if(G[(h+M(G[l>>2],344)|0)+56>>2]>=G[(h+M(j,344)|0)+56>>2]){break n}xc(b,j);break n;case 124:b=28671;h=k-1024|0;if(H[h|0]!=68){break m}if(Xa(h,64640)){break m}h=G[309722];j=k-256|0;i=G[j>>2];b=G[(h+M(i,344)|0)+56>>2];l=k-768|0;m=G[l>>2];h=G[(h+M(m,344)|0)+56>>2];b=Vb(0,1031,2,m,i,0,0,0,0,0,(b|0)>(h|0)?b:h);if((b|0)<0){break l}h=G[309722];j=G[(h+M(G[j>>2],344)|0)+56>>2];if((j|0)<=G[(h+M(G[l>>2],344)|0)+56>>2]){break n}G[(h+M(b,344)|0)+56>>2]=j;break n;case 125:break sa;default:break n}}b=28522;h=k-1536|0;if(H[h|0]!=83){break m}if(Xa(h,64720)){break m}b=50785;h=G[309722];l=G[k-768>>2];j=h+M(l,344)|0;if(G[j+52>>2]!=259|G[j+56>>2]!=1){break m}j=G[k-256>>2];i=h+M(j,344)|0;if(G[i+52>>2]!=259|G[i+56>>2]!=1){break m}b=40257;h=G[(G[i>>2]==-1e3?(h+M(j,344)|0)+88|0:(h+M(G[k-1280>>2],344)|0)+56|0)>>2];if(h-256>>>0<4294967041){break m}b=Vb(0,1044,3,G[k-1280>>2],l,j,0,0,0,0,h);if((b|0)<0){break l}break n}Fb:{switch(D|0){case 0:G[309696]=G[309696]+1;if(!G[309737]){G[309737]=431}b=q+26064|0;bb(b,136908,80);E[q+26143|0]=0;Ua(b);break k;case 3:break Fb;default:break k}}b=G[309630];if((b|0)<=0){if(b){break k}s=1;break i}G[309630]=-2;break k}if(!G[309737]){G[309737]=431}b=q+26064|0;bb(b,136989,80);E[q+26143|0]=0;Ua(b);s=2;break i}if(!Xa(l,64444)){break r}}b=28613;i=0;if(j){break q}break m}b=Vb(0,1016,1,h,0,0,0,0,0,0,0);break o}if(Xa(l,64649)){break p}b=Vb(0,1019,1,h,0,0,0,0,0,0,0);break o}b=28613;if(!i){break m}if(Xa(l,64517)){break m}b=Vb(0,1043,1,h,0,0,0,0,0,0,0);G[(G[309722]+M(b,344)|0)+52>>2]=259}if((b|0)<0){break l}}h=k-(x<<8)|0;k=h+256|0;G[k>>2]=b;bb(h+260|0,q+4|0,252);s=s-(x<<1)|0;j=F[s>>1];h=E[o+135360|0]-56|0;b=j+F[(h<<1)+135504>>1]|0;if(!(b>>>0>1725|I[(b<<1)+127984>>1]!=(j&65535))){p=F[(b<<1)+131440>>1];break j}p=E[h+135522|0];break j}wc(b)}k=k-(x<<8)|0;s=s-(x<<1)|0;p=F[s>>1]}while(1){Gb:{b=F[(p<<1)+127056>>1];Hb:{if((b|0)==-40|(b|0)<-1){break Hb}b=b+1<<1;if(I[b+127984>>1]!=1){break Hb}b=F[b+131440>>1];if((b|0)>0){break Gb}}if((s|0)==(v|0)){s=1;break i}else{k=k-256|0;s=s-2|0;p=F[s>>1];continue}}break}p=b&65535;k=k+256|0;bb(k,1238528,256);D=3}s=s+2|0;continue}break}if((q+25856|0)==(v|0)){break g}}Wa(v)}Fa=q+26144|0;if(s){break b}h=G[309737];G[g>>2]=h;if(h){break a}if(!G[309723]){Ua(15026);break b}if(!G[309728]){G[309729]=1238960;G[309740]=a}o=G[309722];l=G[309725];i=o+M(l,344)|0;a=G[i+60>>2];G[e>>2]=a;G[d>>2]=G[i+56>>2];Ib:{if((a|0)<=0){break Ib}a=a-1|0;a=a>>>0<4?a:4;b=a+1|0;v=b&3;j=0;h=0;if(a>>>0>=3){x=b&-4;a=(o+M(l,344)|0)- -64|0;e=0;while(1){b=h<<2;G[b+f>>2]=G[a+b>>2];k=b|4;G[k+f>>2]=G[a+k>>2];k=b|8;G[k+f>>2]=G[a+k>>2];b=b|12;G[b+f>>2]=G[a+b>>2];h=h+4|0;e=e+4|0;if((x|0)!=(e|0)){continue}break}}if(!v){break Ib}a=o+M(l,344)|0;while(1){b=h<<2;G[b+f>>2]=G[(a+b|0)- -64>>2];h=h+1|0;j=j+1|0;if((v|0)!=(j|0)){continue}break}}Jb:{Kb:{switch(G[i+52>>2]-258|0){case 0:G[c>>2]=14;a=14;break Jb;case 1:G[c>>2]=41;a=41;break Jb;case 2:G[c>>2]=82;a=82;break Jb;case 4:G[c>>2]=1;a=1;break Jb;case 3:G[c>>2]=16;a=16;break Jb;default:break Kb}}G[c>>2]=0;Ua(21131);G[309737]=432;G[g>>2]=432;a=G[c>>2]}G[309735]=a;a=G[309719];Lb:{if(a){Wa(a);break Lb}G[u+4>>2]=940;G[u>>2]=30721;kb(74408,u)}if(G[i>>2]!=-1e3){break c}G[d>>2]=0-G[d>>2]}h=G[g>>2];break a}h=431;G[g>>2]=431}Fa=u+80|0;return h}function ei(a,b,c,d,e,f,g,h,i,j,k){a=a|0;b=b|0;c=c|0;d=+d;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,P=0,R=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Ga=0,Ha=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Va=0,Za=0,_a=0,$a=0,ab=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,kb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Db=0,Eb=0,Fb=0,Gb=0,Hb=0,Ib=0,Jb=0,Kb=0,Lb=0,Mb=0,Ob=0,Pb=0,Qb=0,Rb=0,Sb=0,Tb=0,Ub=0,Vb=0,Wb=0,Xb=0,Yb=0,Zb=0,$b=0,ac=0,bc=0,cc=0,dc=0,ec=0,fc=0,gc=N(0),hc=0,ic=0,jc=0;r=Fa-1280|0;Fa=r;G[r+1272>>2]=0;G[r+1176>>2]=0;G[r+1180>>2]=1072693248;G[r+1168>>2]=0;G[r+1172>>2]=0;G[r+40>>2]=G[36314];l=G[36313];G[r+32>>2]=G[36312];G[r+36>>2]=l;G[r+24>>2]=0;G[r+28>>2]=0;G[r+16>>2]=0;G[r+20>>2]=0;B=G[47542];if(di(g,19692,32736,r+48|0)){B=nc(r+48|0,0,10)}G[r+1256>>2]=0;G[r+1260>>2]=0;G[r+1248>>2]=0;G[r+1252>>2]=0;G[r+1232>>2]=1;G[r+1236>>2]=1;G[r+1216>>2]=1;G[r+1220>>2]=1;G[r+1184>>2]=1;G[r+1188>>2]=1;G[r+1240>>2]=1;G[r+1244>>2]=1;G[r+1224>>2]=1;G[r+1228>>2]=1;G[r+1192>>2]=1;G[r+1196>>2]=1;Qd(a,r+1276|0,k);g=G[r+1276>>2];de(a,(g|0)<4?g:4,r+1248|0,k);Eg(a,j,k);a:{if(G[r+1276>>2]<=1){G[k>>2]=320;g=0;break a}Z=1;b:{if(d==0){break b}Z=d;if(!(d<0)){break b}Z=1/O(d)}g=0;Ha=1;if(!(!f|!H[f|0])){c:{if(!Xa(f,16840)){l=le(16836);break c}d:{if(!jb(f,58)){if(!jb(f,44)){break d}}l=le(f);break c}G[r>>2]=f;f=r+48|0;Ya(f,1024,8751,r);l=le(f)}f=pc(l,48944);if(f){while(1){e:{f:{if(!Xa(f,49138)){if((u|0)<=1){break f}u=2;break e}if(!Xa(f,16840)){f=g<<2;G[f+(r+16|0)>>2]=0-G[f+(r+1248|0)>>2];q=g;break e}o=g<<2;f=_b(f);G[o+(r+16|0)>>2]=f;if((f|0)<=G[o+(r+1248|0)>>2]&(f|0)>0){break e}G[k>>2]=116;g=0;break a}G[(r+32|0)+(u<<2)>>2]=g;u=u+1|0}f=pc(0,48944);if(f){o=g>>>0<3;g=g+1|0;if(o){continue}}break}g=G[r+32>>2];Ha=G[r+36>>2]}else{Ha=1}Wa(l)}l=G[(r+1248|0)+(g<<2)>>2];g:{if(Z>=1){d=+(l|0)/Z;h:{if(O(d)<2147483648){f=~~d;break h}f=-2147483648}d=Z*+(f|0);i:{if(O(d)<2147483648){f=~~d;break i}f=-2147483648}u=G[(r+1248|0)+(Ha<<2)>>2];d=+(u|0)/Z;j:{if(O(d)<2147483648){o=~~d;break j}o=-2147483648}d=Z*+(o|0);if(O(d)<2147483648){t=~~d;break g}t=-2147483648;break g}f=l;u=G[(r+1248|0)+(Ha<<2)>>2];t=u}k:{l:{if(!b){break l}o=G[b>>2];if(!o){break l}b=G[b+4>>2];if(!b){break l}o=(f|0)>(o|0)?o:f;m:{n:{if(!c){break n}d=L[c>>3];if(d==0){break n}Mb=L[c+8>>3];if(Mb!=0){break m}}Mb=+(t|0)*.5;d=+(f|0)*.5}c=(b|0)<(t|0)?b:t;y=g<<2;w=y+(r+1232|0)|0;Ob=+(o|0)*.5;fc=d-Ob+1;o:{if(O(fc)<2147483648){b=~~fc;break o}b=-2147483648}G[w>>2]=b;o=(o&-2147483647)==1;y=y+(r+1216|0)|0;d=Ob+d;p:{if(O(d)<2147483648){b=~~d;break p}b=-2147483648}G[y>>2]=b+o;o=Ha<<2;y=o+(r+1232|0)|0;d=+(c|0)*.5;Ob=Mb-d+1;q:{if(O(Ob)<2147483648){b=~~Ob;break q}b=-2147483648}G[y>>2]=b;o=o+(r+1216|0)|0;d=d+Mb;r:{if(O(d)<2147483648){b=~~d;break r}b=-2147483648}G[o>>2]=b;if((c&-2147483647)!=1){break k}G[o>>2]=b+1;break k}b=g<<2;c=r+1232|0;G[b+c>>2]=1;G[b+(r+1216|0)>>2]=f;b=Ha<<2;G[b+c>>2]=1;G[b+(r+1216|0)>>2]=t}g=g<<2;y=r+1216|0;b=g+y|0;c=G[b>>2];c=(c|0)>1?c:1;G[b>>2]=(c|0)<(l|0)?c:l;w=r+1232|0;o=w+g|0;c=G[o>>2];c=(c|0)>1?c:1;G[o>>2]=(c|0)<(l|0)?c:l;l=Ha<<2;c=l+y|0;g=G[c>>2];g=(g|0)>1?g:1;g=(g|0)<(u|0)?g:u;G[c>>2]=g;y=l+w|0;l=G[y>>2];l=(l|0)>1?l:1;l=(l|0)<(u|0)?l:u;G[y>>2]=l;s:{if(Yc(Z,1)==0){if(!(Z>0)){break s}g=G[b>>2];gc=N(Z);w=G[o>>2];u=0;while(1){t:{_=g-w|0;f=_+1|0;if((_|0)<0){break t}if(Yc(+N(N(f|0)/gc),1)==0){break t}g=g-1|0;u=u+1|0;if(+(u|0)>2]=g;if(!(Z>0)){break s}g=G[c>>2];u=0;while(1){u:{w=g-l|0;t=w+1|0;if((w|0)<0){break u}if(Yc(+N(N(t|0)/gc),1)==0){break u}g=g-1|0;u=u+1|0;if(+(u|0)>2]=g;break s}t=(g-l|0)+1|0;f=(G[b>>2]-G[o>>2]|0)+1|0}W=1;u=G[r+1276>>2];v:{if((u|0)<=0){break v}l=G[r+16>>2];if(l){w=(l|0)<0;_=w?1:l;g=G[r+1248>>2];G[r+1232>>2]=(g|0)>(_|0)?_:g;l=w?g:l;l=(l|0)>1?l:1;G[r+1216>>2]=(g|0)>(l|0)?l:g;W=w?g:1}u=(u|0)<4?u:4;if((u|0)==1){break v}l=G[r+20>>2];if(l){w=(l|0)<0;_=w?1:l;g=G[r+1252>>2];G[r+1236>>2]=(g|0)>(_|0)?_:g;l=w?g:l;l=(l|0)>1?l:1;G[r+1220>>2]=(g|0)>(l|0)?l:g;W=w?g:W}if((u|0)==2){break v}l=G[r+24>>2];if(l){w=(l|0)<0;_=w?1:l;g=G[r+1256>>2];G[r+1240>>2]=(g|0)>(_|0)?_:g;l=w?g:l;l=(l|0)>1?l:1;G[r+1224>>2]=(g|0)>(l|0)?l:g;W=w?g:W}if((u|0)==3){break v}l=G[r+28>>2];if(!l){break v}u=(l|0)<0;w=u?1:l;g=G[r+1260>>2];G[r+1244>>2]=(g|0)>(w|0)?w:g;l=u?g:l;l=(l|0)>1?l:1;G[r+1228>>2]=(g|0)>(l|0)?l:g;W=u?g:W}w:{x:{y:{if(h){G[h>>2]=G[o>>2];G[h+4>>2]=G[y>>2];if(!q){break y}G[h+8>>2]=G[(r+1232|0)+(q<<2)>>2]}if(!i){break w}G[i>>2]=G[b>>2];G[i+4>>2]=G[c>>2];if(!q){break w}c=(r+1216|0)+(q<<2)|0;b=2;break x}if(!i){break w}G[i>>2]=G[b>>2];b=1}G[(b<<2)+i>>2]=G[c>>2]}Ja=M(f,t);_a=M(Ja,W);if((_a|0)<=1){G[k>>2]=323;g=0;break a}Cb(a,82,35661,r+1176|0,r+1072|0,r+1272|0);if(G[r+1272>>2]!=204){Cb(a,82,34377,r+1168|0,r+1072|0,r+1272|0)}d=L[r+1168>>3];Mb=L[r+1176>>3];h=0;Lb=0;z:{if(Z==1){break z}Lb=1;if(!(!e|(e|0)==115)){break z}h=1;Lb=0}u=42;g=0;b=d!=0|Mb!=1;hc=G[j>>2];e=hc;if((e|0)==64){G[j>>2]=-64;e=-64}A:{B:{C:{D:{E:{F:{G:{H:{I:{Ka=Eu(e- -64|0,29);switch(Ka|0){case 4:break A;case 0:break D;case 16:break E;case 12:break F;case 6:break G;case 10:break H;case 9:break I;default:break a}}if(b){break B}if(h){break C}if(Lb){break B}Ka=1;u=11;break A}if(b){break B}if(h){break C}if(Lb){break B}Ka=2;u=21;break A}if(b){break B}if(h){break C}if(Lb){break B}Ka=2;u=20;break A}if(b){break B}Ka=4;if(!Lb){u=31;break A}e=-32;G[j>>2]=-32;break A}if(b|Lb){break B}Ka=8;u=81;break A}Ka=8;u=82;break A}e=32;G[j>>2]=32;Ka=4;u=31;break A}e=-32;G[j>>2]=-32;Ka=4}J:{if(Z==1){Pb=M(Ka,_a);if(!(!B|(Pb|0)<=(B|0))){G[k>>2]=113;break a}U=lb(Pb,1);if(!U){G[k>>2]=113;break a}Ha=0;l=r+1232|0;o=r+1216|0;q=r+1184|0;c=0;i=0;V=Fa-848|0;Fa=V;K:{if(G[k>>2]>0){break K}Qd(a,V+40|0,k);de(a,9,V,k);L:{M:{if(Nb(a,k)){break M}e=1;N:{O:{f=G[V+40>>2];if((f|0)<=0){break O}while(1){b=i<<2;if(G[b+q>>2]!=1|G[b+l>>2]!=1){break O}h=G[b+V>>2];b=G[b+o>>2];if((h|0)!=(b|0)){break O}e=Au(e,g,b,b>>31);g=Ia;i=i+1|0;if((f|0)!=(i|0)){continue}break}break N}if((f|0)!=(i|0)){break M}}if(!(e|g)|G[k>>2]>0){break K}Qd(a,V+44|0,k);b=G[V+44>>2];P:{if((b|0)<=0){break P}i=0;if(b-1>>>0>=3){o=b&-4;f=0;while(1){h=V+48|0;q=h+(c<<3)|0;t=G[l+(c<<2)>>2];G[q>>2]=t;G[q+4>>2]=t>>31;q=c|1;t=h+(q<<3)|0;q=G[l+(q<<2)>>2];G[t>>2]=q;G[t+4>>2]=q>>31;q=c|2;t=h+(q<<3)|0;q=G[l+(q<<2)>>2];G[t>>2]=q;G[t+4>>2]=q>>31;q=c|3;h=h+(q<<3)|0;q=G[l+(q<<2)>>2];G[h>>2]=q;G[h+4>>2]=q>>31;c=c+4|0;f=f+4|0;if((o|0)!=(f|0)){continue}break}}b=b&3;if(!b){break P}while(1){f=(V+48|0)+(c<<3)|0;h=G[l+(c<<2)>>2];G[f>>2]=h;G[f+4>>2]=h>>31;c=c+1|0;i=i+1|0;if((b|0)!=(i|0)){continue}break}}Bo(a,u,V+48|0,e,g,0,U,0,k);break L}Q:{switch(u-11|0){case 0:rp(a,G[V+40>>2],V,l,o,q,U,0,k);break L;case 1:la=a;a=0;qa=1;m=Fa-400|0;Fa=m;t=G[V+40>>2];R:{if(t-10>>>0<=4294967286){G[m>>2]=t;a=m+32|0;Ya(a,81,24134,m);Ua(a);G[k>>2]=320;break R}if(Nb(la,k)){if((t|0)!=1){b=t&-2;while(1){c=D<<3;e=m+32|0;f=c+e|0;g=D<<2;h=G[g+l>>2];G[f>>2]=h;G[f+4>>2]=h>>31;f=c;c=m+128|0;f=f+c|0;g=G[g+o>>2];G[f>>2]=g;G[f+4>>2]=g>>31;g=e;e=D|1;f=e<<3;g=g+f|0;e=e<<2;h=G[e+l>>2];G[g>>2]=h;G[g+4>>2]=h>>31;c=c+f|0;e=G[e+o>>2];G[c>>2]=e;G[c+4>>2]=e>>31;D=D+2|0;a=a+2|0;if((b|0)!=(a|0)){continue}break}}if(t&1){a=D<<3;b=a+(m+32|0)|0;c=D<<2;e=G[c+l>>2];G[b>>2]=e;G[b+4>>2]=e>>31;a=a+(m+128|0)|0;b=G[c+o>>2];G[a>>2]=b;G[a+4>>2]=b>>31}E[m+352|0]=0;md(la,12,m+32|0,m+128|0,q,1,m+352|0,U,0,0,k);break R}if((Dc(la,m+124|0,k)|0)>0){break R}y=G[m+124>>2];S:{if(!y){b=1;qa=2;A=1;c=1;break S}e=t<<2;b=G[e+q>>2];A=G[e+l>>2];c=G[e+o>>2]}G[m+352>>2]=1;G[m+356>>2]=1;e=1;g=0;G[m+128>>2]=1;G[m+132>>2]=0;G[m+304>>2]=1;G[m+308>>2]=1;G[m+256>>2]=1;G[m+260>>2]=1;G[m+136>>2]=1;G[m+140>>2]=0;G[m+208>>2]=1;G[m+212>>2]=1;G[m+360>>2]=1;G[m+144>>2]=1;G[m+148>>2]=0;G[m+312>>2]=1;G[m+316>>2]=1;G[m+264>>2]=1;G[m+268>>2]=1;G[m+152>>2]=1;G[m+156>>2]=0;G[m+216>>2]=1;G[m+220>>2]=1;G[m+364>>2]=1;G[m+368>>2]=1;G[m+320>>2]=1;G[m+272>>2]=1;G[m+160>>2]=1;G[m+164>>2]=0;G[m+224>>2]=1;G[m+372>>2]=1;G[m+376>>2]=1;G[m+168>>2]=1;G[m+172>>2]=0;G[m+324>>2]=1;G[m+328>>2]=1;G[m+276>>2]=1;G[m+280>>2]=1;G[m+176>>2]=1;G[m+180>>2]=0;G[m+228>>2]=1;G[m+232>>2]=1;G[m+184>>2]=1;G[m+188>>2]=0;G[m+380>>2]=1;G[m+384>>2]=1;G[m+332>>2]=1;G[m+336>>2]=1;G[m+284>>2]=1;G[m+288>>2]=1;G[m+192>>2]=1;G[m+196>>2]=0;G[m+236>>2]=1;G[m+240>>2]=1;T:{while(1){h=a<<2;f=G[h+o>>2];i=G[h+l>>2];U:{if((f|0)>=(i|0)){u=G[h+(m+208|0)>>2];break U}if(y){break T}G[h+(m+208|0)>>2]=-1;u=-1}G[h+(m+304|0)>>2]=f;G[h+(m+352|0)>>2]=i;G[h+(m+256|0)>>2]=G[h+q>>2];B=m+128|0;f=a+1|0;i=B+(f<<3)|0;h=G[h+V>>2];h=Au(e,g,h,h>>31);G[i>>2]=h;w=i;i=Ia;G[w+4>>2]=i;a=B+(a<<3)|0;ic=a,jc=Au(e,g,u,u>>31),G[ic>>2]=jc;G[a+4>>2]=Ia;e=h;g=i;a=f;if((t|0)!=(f|0)){continue}break}a=(m+128|0)+(t<<3)|0;e=G[a>>2];f=e;e=G[(m+208|0)+(t<<2)>>2];ic=a,jc=Au(f,G[a+4>>2],e,e>>31),G[ic>>2]=jc;G[a+4>>2]=Ia;V:{if(!((t|0)!=1|G[V>>2]!=1)){D=(c-A|0)/(b|0)|0;c=A;a=b;break V}e=G[m+208>>2];a=M(e,G[m+256>>2]);D=(M(e,G[m+304>>2]-G[m+352>>2]|0)|0)/G[q>>2]|0}if((c|0)<(A|0)){break R}ba=G[m+240>>2];ia=M(ba,G[m+384>>2]);e=M(ba,G[m+336>>2]);if((ia|0)>(e|0)){break R}ca=G[m+236>>2];ja=M(ca,G[m+380>>2]);f=M(ca,G[m+332>>2]);if((ja|0)>(f|0)){break R}x=G[m+232>>2];R=M(x,G[m+376>>2]);g=M(x,G[m+328>>2]);if((R|0)>(g|0)){break R}P=G[m+228>>2];X=M(P,G[m+372>>2]);h=M(P,G[m+324>>2]);if((X|0)>(h|0)){break R}W=G[m+224>>2];s=M(W,G[m+368>>2]);i=M(W,G[m+320>>2]);if((s|0)>(i|0)){break R}$=G[m+220>>2];ka=M($,G[m+364>>2]);l=M($,G[m+316>>2]);if((ka|0)>(l|0)){break R}da=G[m+216>>2];ma=M(da,G[m+360>>2]);o=M(da,G[m+312>>2]);if((ma|0)>(o|0)){break R}ea=G[m+212>>2];oa=M(ea,G[m+356>>2]);q=M(ea,G[m+308>>2]);if((oa|0)>(q|0)){break R}ra=D+1|0;hb=ra>>31;ib=G[m+192>>2];kb=G[m+196>>2];mb=G[m+184>>2];nb=G[m+188>>2];ob=G[m+176>>2];pb=G[m+180>>2];qb=G[m+168>>2];rb=G[m+172>>2];sb=G[m+160>>2];tb=G[m+164>>2];ub=G[m+152>>2];vb=G[m+156>>2];wb=G[m+144>>2];xb=G[m+148>>2];yb=G[m+136>>2];zb=G[m+140>>2];t=G[m+352>>2];sa=t;Ab=t>>31;La=c;ta=c>>31;pa=b;Bb=b>>31;ga=A>>31;Ma=e;z=e>>31;Db=ba>>31;ha=ia>>31;Ja=f;Y=f>>31;Eb=ca>>31;$a=ja>>31;ab=g;Na=g>>31;Fb=x>>31;fa=R>>31;na=h;Oa=h>>31;Gb=P>>31;Hb=X>>31;Pa=i;Qa=i>>31;Ib=W>>31;cb=s>>31;db=l;Ra=l>>31;Jb=$>>31;Sa=ka>>31;eb=o;Ta=o>>31;Kb=da>>31;fb=ma>>31;Va=q;Za=q>>31;Qb=ea>>31;gb=oa>>31;b=G[m+288>>2];ua=b;Rb=b>>31;b=G[m+284>>2];va=b;Sb=b>>31;b=G[m+280>>2];wa=b;Tb=b>>31;b=G[m+276>>2];xa=b;Ub=b>>31;b=G[m+272>>2];ya=b;Vb=b>>31;b=G[m+268>>2];za=b;Wb=b>>31;b=G[m+264>>2];Aa=b;Xb=b>>31;b=G[m+260>>2];n=b;Yb=b>>31;D=0;while(1){b=ia;c=ha;while(1){p=Au(ib,kb,b-ba|0,c-((b>>>0>>0)+Db|0)|0);Zb=Ia;f=ja;h=$a;while(1){C=Au(mb,nb,f-ca|0,h-((f>>>0>>0)+Eb|0)|0);$b=Ia;i=R;o=fa;while(1){Ba=Au(ob,pb,i-x|0,o-((i>>>0>>0)+Fb|0)|0);ac=Ia;q=X;t=Hb;while(1){Ca=Au(qb,rb,q-P|0,t-((q>>>0

>>0)+Gb|0)|0);bc=Ia;u=s;y=cb;while(1){Da=Au(sb,tb,u-W|0,y-((u>>>0>>0)+Ib|0)|0);cc=Ia;B=ka;aa=Sa;while(1){Ea=Au(ub,vb,B-$|0,aa-((B>>>0<$>>>0)+Jb|0)|0);dc=Ia;w=ma;_=fb;while(1){Ga=Au(wb,xb,w-da|0,_-((w>>>0>>0)+Kb|0)|0);ec=Ia;e=oa;g=gb;while(1){v=Au(yb,zb,e-ea|0,g-((e>>>0>>0)+Qb|0)|0)+sa|0;l=Ab+Ia|0;l=v>>>0>>0?l+1|0:l;v=v+Ga|0;l=l+ec|0;l=v>>>0>>0?l+1|0:l;v=v+Ea|0;l=l+dc|0;l=v>>>0>>0?l+1|0:l;v=v+Da|0;l=l+cc|0;l=v>>>0>>0?l+1|0:l;v=v+Ca|0;l=l+bc|0;l=v>>>0>>0?l+1|0:l;v=v+Ba|0;l=l+ac|0;l=v>>>0>>0?l+1|0:l;v=v+C|0;l=l+$b|0;l=v>>>0>>0?l+1|0:l;v=p+v|0;l=l+Zb|0;if((Ef(la,qa,A,ga,v,p>>>0>v>>>0?l+1|0:l,ra,hb,a,1,0,D+U|0,m+123|0,m+32|0,k)|0)>0){break R}D=D+ra|0;l=g+Yb|0;e=e+n|0;l=e>>>0>>0?l+1|0:l;g=l;if(e>>>0<=Va>>>0&(Za|0)>=(l|0)|(l|0)<(Za|0)){continue}break}l=_+Xb|0;e=w+Aa|0;l=e>>>0>>0?l+1|0:l;w=e;_=l;if(e>>>0<=eb>>>0&(Ta|0)>=(l|0)|(l|0)<(Ta|0)){continue}break}l=aa+Wb|0;e=B+za|0;l=e>>>0>>0?l+1|0:l;B=e;aa=l;if(e>>>0<=db>>>0&(Ra|0)>=(l|0)|(l|0)<(Ra|0)){continue}break}l=y+Vb|0;e=u+ya|0;l=e>>>0>>0?l+1|0:l;u=e;y=l;if(e>>>0<=Pa>>>0&(Qa|0)>=(l|0)|(l|0)<(Qa|0)){continue}break}l=t+Ub|0;e=q+xa|0;l=e>>>0>>0?l+1|0:l;q=e;t=l;if(e>>>0<=na>>>0&(Oa|0)>=(l|0)|(l|0)<(Oa|0)){continue}break}l=o+Tb|0;e=i+wa|0;l=e>>>0>>0?l+1|0:l;i=e;o=l;if(e>>>0<=ab>>>0&(Na|0)>=(l|0)|(l|0)<(Na|0)){continue}break}l=h+Sb|0;e=f+va|0;l=e>>>0>>0?l+1|0:l;f=e;h=l;if(e>>>0<=Ja>>>0&(Y|0)>=(l|0)|(l|0)<(Y|0)){continue}break}l=c+Rb|0;b=b+ua|0;l=b>>>0>>0?l+1|0:l;c=l;if(b>>>0<=Ma>>>0&(z|0)>=(l|0)|(l|0)<(z|0)){continue}break}l=ga+Bb|0;b=A+pa|0;l=b>>>0>>0?l+1|0:l;A=b;ga=l;if(b>>>0<=La>>>0&(ta|0)>=(l|0)|(l|0)<(ta|0)){continue}break}break R}G[m+16>>2]=a+1;a=m+32|0;Ya(a,81,27284,m+16|0);Ua(a);G[k>>2]=321}Fa=m+400|0;break L;case 9:X=a;Ba=1;n=Fa-352|0;Fa=n;f=G[V+40>>2];W:{if(f-10>>>0<=4294967286){G[n>>2]=f;a=n+32|0;Ya(a,81,23953,n);Ua(a);G[k>>2]=320;break W}X:{if(Nb(X,k)){if((f|0)!=1){a=f&-2;while(1){b=C<<3;e=n+32|0;g=b+e|0;h=C<<2;i=G[h+l>>2];G[g>>2]=i;G[g+4>>2]=i>>31;g=b;b=n+128|0;g=g+b|0;h=G[h+o>>2];G[g>>2]=h;G[g+4>>2]=h>>31;h=e;e=C|1;g=e<<3;h=h+g|0;e=e<<2;i=G[e+l>>2];G[h>>2]=i;G[h+4>>2]=i>>31;b=b+g|0;e=G[e+o>>2];G[b>>2]=e;G[b+4>>2]=e>>31;C=C+2|0;c=c+2|0;if((a|0)!=(c|0)){continue}break}}if(f&1){a=C<<3;b=a+(n+32|0)|0;c=C<<2;e=G[c+l>>2];G[b>>2]=e;G[b+4>>2]=e>>31;a=a+(n+128|0)|0;b=G[c+o>>2];G[a>>2]=b;G[a+4>>2]=b>>31}F[n+304>>1]=0;md(X,20,n+32|0,n+128|0,q,1,n+304|0,U,0,0,k);break X}if((Dc(X,n+124|0,k)|0)>0){break X}Y:{if(!G[n+124>>2]){b=1;Ba=2;A=1;a=1;break Y}e=f<<2;b=G[e+q>>2];A=G[e+l>>2];a=G[e+o>>2]}G[n+256>>2]=1;G[n+304>>2]=1;G[n+308>>2]=1;G[n+208>>2]=1;e=1;g=0;G[n+128>>2]=1;G[n+132>>2]=0;G[n+136>>2]=1;G[n+140>>2]=0;G[n+312>>2]=1;G[n+260>>2]=1;G[n+264>>2]=1;G[n+212>>2]=1;G[n+216>>2]=1;G[n+144>>2]=1;G[n+148>>2]=0;G[n+152>>2]=1;G[n+156>>2]=0;G[n+316>>2]=1;G[n+320>>2]=1;G[n+268>>2]=1;G[n+272>>2]=1;G[n+220>>2]=1;G[n+224>>2]=1;G[n+160>>2]=1;G[n+164>>2]=0;G[n+324>>2]=1;G[n+276>>2]=1;G[n+228>>2]=1;G[n+168>>2]=1;G[n+172>>2]=0;G[n+280>>2]=1;G[n+328>>2]=1;G[n+332>>2]=1;G[n+232>>2]=1;G[n+176>>2]=1;G[n+180>>2]=0;G[n+184>>2]=1;G[n+188>>2]=0;G[n+336>>2]=1;G[n+284>>2]=1;G[n+288>>2]=1;G[n+236>>2]=1;G[n+240>>2]=1;G[n+192>>2]=1;G[n+196>>2]=0;while(1){h=c<<2;i=G[h+o>>2];t=G[h+l>>2];if((i|0)<(t|0)){G[n+16>>2]=c+1;a=n+32|0;Ya(a,81,27103,n+16|0);Ua(a);G[k>>2]=321;break W}G[h+(n+256|0)>>2]=i;G[h+(n+304|0)>>2]=t;G[h+(n+208|0)>>2]=G[h+q>>2];i=e;e=G[h+V>>2];e=Au(i,g,e,e>>31);c=c+1|0;h=(n+128|0)+(c<<3)|0;G[h>>2]=e;g=Ia;G[h+4>>2]=g;if((c|0)!=(f|0)){continue}break}Z:{if(!((f|0)!=1|G[V>>2]!=1)){C=(a-A|0)/(b|0)|0;a=A;c=b;break Z}C=(G[n+256>>2]-G[n+304>>2]|0)/G[q>>2]|0;c=G[n+208>>2]}if((a|0)<(A|0)){break X}pa=G[n+336>>2];e=G[n+288>>2];if((pa|0)>(e|0)){break X}ba=G[n+332>>2];f=G[n+284>>2];if((ba|0)>(f|0)){break X}ia=G[n+328>>2];g=G[n+280>>2];if((ia|0)>(g|0)){break X}ca=G[n+324>>2];h=G[n+276>>2];if((ca|0)>(h|0)){break X}ja=G[n+320>>2];i=G[n+272>>2];if((ja|0)>(i|0)){break X}x=G[n+316>>2];l=G[n+268>>2];if((x|0)>(l|0)){break X}R=G[n+312>>2];o=G[n+264>>2];if((R|0)>(o|0)){break X}P=G[n+308>>2];q=G[n+260>>2];if((P|0)>(q|0)){break X}W=c;Y=C+1|0;Na=Y>>31;Oa=G[n+192>>2];Qa=G[n+196>>2];Ra=G[n+184>>2];Ta=G[n+188>>2];Za=G[n+176>>2];v=G[n+180>>2];ra=G[n+168>>2];hb=G[n+172>>2];ib=G[n+160>>2];kb=G[n+164>>2];mb=G[n+152>>2];nb=G[n+156>>2];ob=G[n+144>>2];pb=G[n+148>>2];qb=G[n+136>>2];rb=G[n+140>>2];c=G[n+304>>2];s=c;sb=c>>31;$=a;p=a>>31;a=b;tb=b>>31;ga=A>>31;ka=e;Ca=e>>31;da=pa>>31;ma=f;Da=f>>31;ea=ba>>31;oa=g;Ea=g>>31;la=ia>>31;sa=h;Ga=h>>31;La=ca>>31;Ma=i;m=i>>31;ha=ja>>31;Ja=l;D=l>>31;$a=x>>31;ab=o;qa=o>>31;fa=R>>31;na=q;ta=q>>31;Hb=P>>31;b=G[n+240>>2];Pa=b;ub=b>>31;b=G[n+236>>2];cb=b;vb=b>>31;b=G[n+232>>2];db=b;wb=b>>31;b=G[n+228>>2];Sa=b;xb=b>>31;b=G[n+224>>2];eb=b;yb=b>>31;b=G[n+220>>2];fb=b;zb=b>>31;b=G[n+216>>2];Va=b;Ab=b>>31;b=G[n+212>>2];gb=b;Bb=b>>31;C=0;while(1){b=pa;c=da;while(1){ua=Au(Oa,Qa,b-1|0,c-!b|0);Db=Ia;f=ba;h=ea;while(1){va=Au(Ra,Ta,f-1|0,h-!f|0);Eb=Ia;i=ia;o=la;while(1){wa=Au(Za,v,i-1|0,o-!i|0);Fb=Ia;q=ca;t=La;while(1){xa=Au(ra,hb,q-1|0,t-!q|0);Gb=Ia;u=ja;y=ha;while(1){ya=Au(ib,kb,u-1|0,y-!u|0);Ib=Ia;B=x;aa=$a;while(1){za=Au(mb,nb,B-1|0,aa-!B|0);Jb=Ia;w=R;_=fa;while(1){Aa=Au(ob,pb,w-1|0,_-!w|0);Kb=Ia;e=P;g=Hb;while(1){z=Au(qb,rb,e-1|0,g-!e|0)+s|0;l=sb+Ia|0;l=s>>>0>z>>>0?l+1|0:l;z=z+Aa|0;l=l+Kb|0;l=z>>>0>>0?l+1|0:l;z=z+za|0;l=l+Jb|0;l=z>>>0>>0?l+1|0:l;z=z+ya|0;l=l+Ib|0;l=z>>>0>>0?l+1|0:l;z=z+xa|0;l=l+Gb|0;l=z>>>0>>0?l+1|0:l;z=z+wa|0;l=l+Fb|0;l=z>>>0>>0?l+1|0:l;z=z+va|0;l=l+Eb|0;l=z>>>0>>0?l+1|0:l;z=z+ua|0;l=l+Db|0;if((Gf(X,Ba,A,ga,z,z>>>0>>0?l+1|0:l,Y,Na,W,1,0,(C<<1)+U|0,n+123|0,n+32|0,k)|0)>0){break X}C=C+Y|0;l=g+Bb|0;e=e+gb|0;l=e>>>0>>0?l+1|0:l;g=l;if(e>>>0<=na>>>0&(ta|0)>=(l|0)|(l|0)<(ta|0)){continue}break}l=_+Ab|0;e=w+Va|0;l=e>>>0>>0?l+1|0:l;w=e;_=l;if(e>>>0<=ab>>>0&(qa|0)>=(l|0)|(l|0)<(qa|0)){continue}break}l=aa+zb|0;e=B+fb|0;l=e>>>0>>0?l+1|0:l;B=e;aa=l;if(e>>>0<=Ja>>>0&(D|0)>=(l|0)|(l|0)<(D|0)){continue}break}l=y+yb|0;e=u+eb|0;l=e>>>0>>0?l+1|0:l;u=e;y=l;if(e>>>0<=Ma>>>0&(m|0)>=(l|0)|(l|0)<(m|0)){continue}break}l=t+xb|0;e=q+Sa|0;l=e>>>0>>0?l+1|0:l;q=e;t=l;if(e>>>0<=sa>>>0&(Ga|0)>=(l|0)|(l|0)<(Ga|0)){continue}break}l=o+wb|0;e=i+db|0;l=e>>>0>>0?l+1|0:l;i=e;o=l;if(e>>>0<=oa>>>0&(Ea|0)>=(l|0)|(l|0)<(Ea|0)){continue}break}l=h+vb|0;e=f+cb|0;l=e>>>0>>0?l+1|0:l;f=e;h=l;if(e>>>0<=ma>>>0&(Da|0)>=(l|0)|(l|0)<(Da|0)){continue}break}l=c+ub|0;b=b+Pa|0;l=b>>>0>>0?l+1|0:l;c=l;if(b>>>0<=ka>>>0&(Ca|0)>=(l|0)|(l|0)<(Ca|0)){continue}break}l=ga+tb|0;b=a+A|0;l=b>>>0>>0?l+1|0:l;A=b;ga=l;if(b>>>0<=$>>>0&(p|0)>=(l|0)|(l|0)<(p|0)){continue}break}}}Fa=n+352|0;break L;case 10:Mp(a,G[V+40>>2],V,l,o,q,U,0,k);break L;case 19:W=a;Ba=1;p=Fa-352|0;Fa=p;f=G[V+40>>2];_:{if(f-10>>>0<=4294967286){G[p>>2]=f;a=p+32|0;Ya(a,81,23771,p);Ua(a);G[k>>2]=320;break _}$:{if(Nb(W,k)){if((f|0)!=1){a=f&-2;while(1){b=C<<3;e=p+32|0;g=b+e|0;h=C<<2;i=G[h+l>>2];G[g>>2]=i;G[g+4>>2]=i>>31;g=b;b=p+128|0;g=g+b|0;h=G[h+o>>2];G[g>>2]=h;G[g+4>>2]=h>>31;h=e;e=C|1;g=e<<3;h=h+g|0;e=e<<2;i=G[e+l>>2];G[h>>2]=i;G[h+4>>2]=i>>31;b=b+g|0;e=G[e+o>>2];G[b>>2]=e;G[b+4>>2]=e>>31;C=C+2|0;c=c+2|0;if((a|0)!=(c|0)){continue}break}}if(f&1){a=C<<3;b=a+(p+32|0)|0;c=C<<2;e=G[c+l>>2];G[b>>2]=e;G[b+4>>2]=e>>31;a=a+(p+128|0)|0;b=G[c+o>>2];G[a>>2]=b;G[a+4>>2]=b>>31}G[p+304>>2]=0;md(W,30,p+32|0,p+128|0,q,1,p+304|0,U,0,0,k);break $}if((Dc(W,p+124|0,k)|0)>0){break $}aa:{if(!G[p+124>>2]){b=1;Ba=2;A=1;a=1;break aa}e=f<<2;b=G[e+q>>2];A=G[e+l>>2];a=G[e+o>>2]}G[p+256>>2]=1;G[p+304>>2]=1;G[p+308>>2]=1;G[p+208>>2]=1;e=1;g=0;G[p+128>>2]=1;G[p+132>>2]=0;G[p+136>>2]=1;G[p+140>>2]=0;G[p+312>>2]=1;G[p+260>>2]=1;G[p+264>>2]=1;G[p+212>>2]=1;G[p+216>>2]=1;G[p+144>>2]=1;G[p+148>>2]=0;G[p+152>>2]=1;G[p+156>>2]=0;G[p+316>>2]=1;G[p+320>>2]=1;G[p+268>>2]=1;G[p+272>>2]=1;G[p+220>>2]=1;G[p+224>>2]=1;G[p+160>>2]=1;G[p+164>>2]=0;G[p+324>>2]=1;G[p+276>>2]=1;G[p+228>>2]=1;G[p+168>>2]=1;G[p+172>>2]=0;G[p+280>>2]=1;G[p+328>>2]=1;G[p+332>>2]=1;G[p+232>>2]=1;G[p+176>>2]=1;G[p+180>>2]=0;G[p+184>>2]=1;G[p+188>>2]=0;G[p+336>>2]=1;G[p+284>>2]=1;G[p+288>>2]=1;G[p+236>>2]=1;G[p+240>>2]=1;G[p+192>>2]=1;G[p+196>>2]=0;while(1){h=c<<2;i=G[h+o>>2];t=G[h+l>>2];if((i|0)<(t|0)){G[p+16>>2]=c+1;a=p+32|0;Ya(a,81,26921,p+16|0);Ua(a);G[k>>2]=321;break _}G[h+(p+256|0)>>2]=i;G[h+(p+304|0)>>2]=t;G[h+(p+208|0)>>2]=G[h+q>>2];i=e;e=G[h+V>>2];e=Au(i,g,e,e>>31);c=c+1|0;h=(p+128|0)+(c<<3)|0;G[h>>2]=e;g=Ia;G[h+4>>2]=g;if((c|0)!=(f|0)){continue}break}ba:{if(!((f|0)!=1|G[V>>2]!=1)){C=(a-A|0)/(b|0)|0;a=A;c=b;break ba}C=(G[p+256>>2]-G[p+304>>2]|0)/G[q>>2]|0;c=G[p+208>>2]}if((a|0)<(A|0)){break $}ba=G[p+336>>2];e=G[p+288>>2];if((ba|0)>(e|0)){break $}ia=G[p+332>>2];f=G[p+284>>2];if((ia|0)>(f|0)){break $}ca=G[p+328>>2];g=G[p+280>>2];if((ca|0)>(g|0)){break $}ja=G[p+324>>2];h=G[p+276>>2];if((ja|0)>(h|0)){break $}x=G[p+320>>2];i=G[p+272>>2];if((x|0)>(i|0)){break $}R=G[p+316>>2];l=G[p+268>>2];if((R|0)>(l|0)){break $}P=G[p+312>>2];o=G[p+264>>2];if((P|0)>(o|0)){break $}X=G[p+308>>2];q=G[p+260>>2];if((X|0)>(q|0)){break $}s=c;C=C+1|0;Na=C>>31;Oa=G[p+192>>2];Qa=G[p+196>>2];Ra=G[p+184>>2];Ta=G[p+188>>2];Za=G[p+176>>2];v=G[p+180>>2];ra=G[p+168>>2];hb=G[p+172>>2];ib=G[p+160>>2];kb=G[p+164>>2];mb=G[p+152>>2];nb=G[p+156>>2];ob=G[p+144>>2];pb=G[p+148>>2];c=G[p+304>>2];$=c;qb=c>>31;rb=G[p+136>>2];sb=G[p+140>>2];ka=a;Ca=a>>31;pa=b;tb=b>>31;ga=A>>31;da=e;Da=e>>31;ma=ba>>31;ea=f;Ea=f>>31;a=G[p+236>>2];oa=a;ub=a>>31;la=ia>>31;sa=g;Ga=g>>31;a=G[p+232>>2];La=a;vb=a>>31;Ma=ca>>31;ha=h;m=h>>31;a=G[p+228>>2];Ja=a;wb=a>>31;$a=ja>>31;ab=i;D=i>>31;a=G[p+224>>2];fa=a;xb=a>>31;na=x>>31;Hb=l;qa=l>>31;a=G[p+220>>2];Pa=a;yb=a>>31;cb=R>>31;db=o;ta=o>>31;a=G[p+216>>2];Sa=a;zb=a>>31;eb=P>>31;fb=q;z=q>>31;a=G[p+212>>2];Va=a;Ab=a>>31;gb=X>>31;a=G[p+240>>2];ua=a;Bb=a>>31;a=0;while(1){b=ba;c=ma;while(1){ca:{if(C){va=Au(Oa,Qa,b-1|0,c-!b|0);Db=Ia;f=ia;h=la;while(1){wa=Au(Ra,Ta,f-1|0,h-!f|0);Eb=Ia;i=ca;o=Ma;while(1){xa=Au(Za,v,i-1|0,o-!i|0);Fb=Ia;q=ja;t=$a;while(1){ya=Au(ra,hb,q-1|0,t-!q|0);Gb=Ia;u=x;y=na;while(1){za=Au(ib,kb,u-1|0,y-!u|0);Ib=Ia;B=R;aa=cb;while(1){Aa=Au(mb,nb,B-1|0,aa-!B|0);Jb=Ia;w=P;_=eb;while(1){n=Au(ob,pb,w-1|0,_-!w|0);Kb=Ia;e=X;g=gb;while(1){if(G[k>>2]>0){break _}Y=Au(rb,sb,e-1|0,g-!e|0)+$|0;l=qb+Ia|0;l=Y>>>0<$>>>0?l+1|0:l;Y=n+Y|0;l=l+Kb|0;l=n>>>0>Y>>>0?l+1|0:l;Y=Y+Aa|0;l=l+Jb|0;l=Y>>>0>>0?l+1|0:l;Y=Y+za|0;l=l+Ib|0;l=Y>>>0>>0?l+1|0:l;Y=Y+ya|0;l=l+Gb|0;l=Y>>>0>>0?l+1|0:l;Y=Y+xa|0;l=l+Fb|0;l=Y>>>0>>0?l+1|0:l;Y=Y+wa|0;l=l+Eb|0;l=Y>>>0>>0?l+1|0:l;Y=Y+va|0;l=l+Db|0;qe(W,Ba,A,ga,Y,Y>>>0>>0?l+1|0:l,C,Na,s,1,0,(a<<2)+U|0,p+123|0,p+32|0,k);if(G[k>>2]>0){break _}a=a+C|0;l=g+Ab|0;e=e+Va|0;l=e>>>0>>0?l+1|0:l;g=l;if(e>>>0<=fb>>>0&(z|0)>=(l|0)|(l|0)<(z|0)){continue}break}l=_+zb|0;e=w+Sa|0;l=e>>>0>>0?l+1|0:l;w=e;_=l;if(e>>>0<=db>>>0&(ta|0)>=(l|0)|(l|0)<(ta|0)){continue}break}l=aa+yb|0;e=B+Pa|0;l=e>>>0>>0?l+1|0:l;B=e;aa=l;if(e>>>0<=Hb>>>0&(qa|0)>=(l|0)|(l|0)<(qa|0)){continue}break}l=y+xb|0;e=u+fa|0;l=e>>>0>>0?l+1|0:l;u=e;y=l;if(e>>>0<=ab>>>0&(D|0)>=(l|0)|(l|0)<(D|0)){continue}break}l=t+wb|0;e=q+Ja|0;l=e>>>0>>0?l+1|0:l;q=e;t=l;if(e>>>0<=ha>>>0&(m|0)>=(l|0)|(l|0)<(m|0)){continue}break}l=o+vb|0;e=i+La|0;l=e>>>0>>0?l+1|0:l;i=e;o=l;if(e>>>0<=sa>>>0&(Ga|0)>=(l|0)|(l|0)<(Ga|0)){continue}break}l=h+ub|0;e=f+oa|0;l=e>>>0>>0?l+1|0:l;f=e;h=l;if(e>>>0<=ea>>>0&(Ea|0)>=(l|0)|(l|0)<(Ea|0)){continue}break}break ca}if(G[k>>2]>0){break _}}l=c+Bb|0;b=b+ua|0;l=b>>>0>>0?l+1|0:l;c=l;if(b>>>0<=da>>>0&(Da|0)>=(l|0)|(l|0)<(Da|0)){continue}break}l=ga+tb|0;b=A+pa|0;l=b>>>0>>0?l+1|0:l;A=b;ga=l;if(b>>>0<=ka>>>0&(Ca|0)>=(l|0)|(l|0)<(Ca|0)){continue}break}}}Fa=p+352|0;break L;case 20:Vp(a,G[V+40>>2],V,l,o,q,U,0,k);break L;case 29:X=a;Ba=1;n=Fa-352|0;Fa=n;f=G[V+40>>2];da:{if(f-10>>>0<=4294967286){G[n>>2]=f;a=n+32|0;Ya(a,81,23862,n);Ua(a);G[k>>2]=320;break da}ea:{if(Nb(X,k)){if((f|0)!=1){a=f&-2;while(1){b=C<<3;e=n+32|0;g=b+e|0;h=C<<2;i=G[h+l>>2];G[g>>2]=i;G[g+4>>2]=i>>31;g=b;b=n+128|0;g=g+b|0;h=G[h+o>>2];G[g>>2]=h;G[g+4>>2]=h>>31;h=e;e=C|1;g=e<<3;h=h+g|0;e=e<<2;i=G[e+l>>2];G[h>>2]=i;G[h+4>>2]=i>>31;b=b+g|0;e=G[e+o>>2];G[b>>2]=e;G[b+4>>2]=e>>31;C=C+2|0;c=c+2|0;if((a|0)!=(c|0)){continue}break}}if(f&1){a=C<<3;b=a+(n+32|0)|0;c=C<<2;e=G[c+l>>2];G[b>>2]=e;G[b+4>>2]=e>>31;a=a+(n+128|0)|0;b=G[c+o>>2];G[a>>2]=b;G[a+4>>2]=b>>31}G[n+304>>2]=0;md(X,40,n+32|0,n+128|0,q,1,n+304|0,U,0,0,k);break ea}if((Dc(X,n+124|0,k)|0)>0){break ea}fa:{if(!G[n+124>>2]){b=1;Ba=2;A=1;a=1;break fa}e=f<<2;b=G[e+q>>2];A=G[e+l>>2];a=G[e+o>>2]}G[n+256>>2]=1;G[n+304>>2]=1;G[n+308>>2]=1;G[n+208>>2]=1;e=1;g=0;G[n+128>>2]=1;G[n+132>>2]=0;G[n+136>>2]=1;G[n+140>>2]=0;G[n+312>>2]=1;G[n+260>>2]=1;G[n+264>>2]=1;G[n+212>>2]=1;G[n+216>>2]=1;G[n+144>>2]=1;G[n+148>>2]=0;G[n+152>>2]=1;G[n+156>>2]=0;G[n+316>>2]=1;G[n+320>>2]=1;G[n+268>>2]=1;G[n+272>>2]=1;G[n+220>>2]=1;G[n+224>>2]=1;G[n+160>>2]=1;G[n+164>>2]=0;G[n+324>>2]=1;G[n+276>>2]=1;G[n+228>>2]=1;G[n+168>>2]=1;G[n+172>>2]=0;G[n+280>>2]=1;G[n+328>>2]=1;G[n+332>>2]=1;G[n+232>>2]=1;G[n+176>>2]=1;G[n+180>>2]=0;G[n+184>>2]=1;G[n+188>>2]=0;G[n+336>>2]=1;G[n+284>>2]=1;G[n+288>>2]=1;G[n+236>>2]=1;G[n+240>>2]=1;G[n+192>>2]=1;G[n+196>>2]=0;while(1){h=c<<2;i=G[h+o>>2];t=G[h+l>>2];if((i|0)<(t|0)){G[n+16>>2]=c+1;a=n+32|0;Ya(a,81,27012,n+16|0);Ua(a);G[k>>2]=321;break da}G[h+(n+256|0)>>2]=i;G[h+(n+304|0)>>2]=t;G[h+(n+208|0)>>2]=G[h+q>>2];i=e;e=G[h+V>>2];e=Au(i,g,e,e>>31);c=c+1|0;h=(n+128|0)+(c<<3)|0;G[h>>2]=e;g=Ia;G[h+4>>2]=g;if((c|0)!=(f|0)){continue}break}ga:{if(!((f|0)!=1|G[V>>2]!=1)){C=(a-A|0)/(b|0)|0;a=A;c=b;break ga}C=(G[n+256>>2]-G[n+304>>2]|0)/G[q>>2]|0;c=G[n+208>>2]}if((a|0)<(A|0)){break ea}pa=G[n+336>>2];e=G[n+288>>2];if((pa|0)>(e|0)){break ea}ba=G[n+332>>2];f=G[n+284>>2];if((ba|0)>(f|0)){break ea}ia=G[n+328>>2];g=G[n+280>>2];if((ia|0)>(g|0)){break ea}ca=G[n+324>>2];h=G[n+276>>2];if((ca|0)>(h|0)){break ea}ja=G[n+320>>2];i=G[n+272>>2];if((ja|0)>(i|0)){break ea}x=G[n+316>>2];l=G[n+268>>2];if((x|0)>(l|0)){break ea}R=G[n+312>>2];o=G[n+264>>2];if((R|0)>(o|0)){break ea}P=G[n+308>>2];q=G[n+260>>2];if((P|0)>(q|0)){break ea}W=c;Y=C+1|0;Na=Y>>31;Oa=G[n+192>>2];Qa=G[n+196>>2];Ra=G[n+184>>2];Ta=G[n+188>>2];Za=G[n+176>>2];v=G[n+180>>2];ra=G[n+168>>2];hb=G[n+172>>2];ib=G[n+160>>2];kb=G[n+164>>2];mb=G[n+152>>2];nb=G[n+156>>2];ob=G[n+144>>2];pb=G[n+148>>2];qb=G[n+136>>2];rb=G[n+140>>2];c=G[n+304>>2];s=c;sb=c>>31;$=a;p=a>>31;a=b;tb=b>>31;ga=A>>31;ka=e;Ca=e>>31;da=pa>>31;ma=f;Da=f>>31;ea=ba>>31;oa=g;Ea=g>>31;la=ia>>31;sa=h;Ga=h>>31;La=ca>>31;Ma=i;m=i>>31;ha=ja>>31;Ja=l;D=l>>31;$a=x>>31;ab=o;qa=o>>31;fa=R>>31;na=q;ta=q>>31;Hb=P>>31;b=G[n+240>>2];Pa=b;ub=b>>31;b=G[n+236>>2];cb=b;vb=b>>31;b=G[n+232>>2];db=b;wb=b>>31;b=G[n+228>>2];Sa=b;xb=b>>31;b=G[n+224>>2];eb=b;yb=b>>31;b=G[n+220>>2];fb=b;zb=b>>31;b=G[n+216>>2];Va=b;Ab=b>>31;b=G[n+212>>2];gb=b;Bb=b>>31;C=0;while(1){b=pa;c=da;while(1){ua=Au(Oa,Qa,b-1|0,c-!b|0);Db=Ia;f=ba;h=ea;while(1){va=Au(Ra,Ta,f-1|0,h-!f|0);Eb=Ia;i=ia;o=la;while(1){wa=Au(Za,v,i-1|0,o-!i|0);Fb=Ia;q=ca;t=La;while(1){xa=Au(ra,hb,q-1|0,t-!q|0);Gb=Ia;u=ja;y=ha;while(1){ya=Au(ib,kb,u-1|0,y-!u|0);Ib=Ia;B=x;aa=$a;while(1){za=Au(mb,nb,B-1|0,aa-!B|0);Jb=Ia;w=R;_=fa;while(1){Aa=Au(ob,pb,w-1|0,_-!w|0);Kb=Ia;e=P;g=Hb;while(1){z=Au(qb,rb,e-1|0,g-!e|0)+s|0;l=sb+Ia|0;l=s>>>0>z>>>0?l+1|0:l;z=z+Aa|0;l=l+Kb|0;l=z>>>0>>0?l+1|0:l;z=z+za|0;l=l+Jb|0;l=z>>>0>>0?l+1|0:l;z=z+ya|0;l=l+Ib|0;l=z>>>0>>0?l+1|0:l;z=z+xa|0;l=l+Gb|0;l=z>>>0>>0?l+1|0:l;z=z+wa|0;l=l+Fb|0;l=z>>>0>>0?l+1|0:l;z=z+va|0;l=l+Eb|0;l=z>>>0>>0?l+1|0:l;z=z+ua|0;l=l+Db|0;if((qe(X,Ba,A,ga,z,z>>>0>>0?l+1|0:l,Y,Na,W,1,0,(C<<2)+U|0,n+123|0,n+32|0,k)|0)>0){break ea}C=C+Y|0;l=g+Bb|0;e=e+gb|0;l=e>>>0>>0?l+1|0:l;g=l;if(e>>>0<=na>>>0&(ta|0)>=(l|0)|(l|0)<(ta|0)){continue}break}l=_+Ab|0;e=w+Va|0;l=e>>>0>>0?l+1|0:l;w=e;_=l;if(e>>>0<=ab>>>0&(qa|0)>=(l|0)|(l|0)<(qa|0)){continue}break}l=aa+zb|0;e=B+fb|0;l=e>>>0>>0?l+1|0:l;B=e;aa=l;if(e>>>0<=Ja>>>0&(D|0)>=(l|0)|(l|0)<(D|0)){continue}break}l=y+yb|0;e=u+eb|0;l=e>>>0>>0?l+1|0:l;u=e;y=l;if(e>>>0<=Ma>>>0&(m|0)>=(l|0)|(l|0)<(m|0)){continue}break}l=t+xb|0;e=q+Sa|0;l=e>>>0>>0?l+1|0:l;q=e;t=l;if(e>>>0<=sa>>>0&(Ga|0)>=(l|0)|(l|0)<(Ga|0)){continue}break}l=o+wb|0;e=i+db|0;l=e>>>0>>0?l+1|0:l;i=e;o=l;if(e>>>0<=oa>>>0&(Ea|0)>=(l|0)|(l|0)<(Ea|0)){continue}break}l=h+vb|0;e=f+cb|0;l=e>>>0>>0?l+1|0:l;f=e;h=l;if(e>>>0<=ma>>>0&(Da|0)>=(l|0)|(l|0)<(Da|0)){continue}break}l=c+ub|0;b=b+Pa|0;l=b>>>0>>0?l+1|0:l;c=l;if(b>>>0<=ka>>>0&(Ca|0)>=(l|0)|(l|0)<(Ca|0)){continue}break}l=ga+tb|0;b=a+A|0;l=b>>>0>>0?l+1|0:l;A=b;ga=l;if(b>>>0<=$>>>0&(p|0)>=(l|0)|(l|0)<(p|0)){continue}break}}}Fa=n+352|0;break L;case 30:la=a;a=0;qa=1;m=Fa-400|0;Fa=m;t=G[V+40>>2];ha:{if(t-10>>>0<=4294967286){G[m>>2]=t;a=m+32|0;Ya(a,81,23817,m);Ua(a);G[k>>2]=320;break ha}if(Nb(la,k)){if((t|0)!=1){b=t&-2;while(1){c=D<<3;e=m+32|0;f=c+e|0;g=D<<2;h=G[g+l>>2];G[f>>2]=h;G[f+4>>2]=h>>31;f=c;c=m+128|0;f=f+c|0;g=G[g+o>>2];G[f>>2]=g;G[f+4>>2]=g>>31;g=e;e=D|1;f=e<<3;g=g+f|0;e=e<<2;h=G[e+l>>2];G[g>>2]=h;G[g+4>>2]=h>>31;c=c+f|0;e=G[e+o>>2];G[c>>2]=e;G[c+4>>2]=e>>31;D=D+2|0;a=a+2|0;if((b|0)!=(a|0)){continue}break}}if(t&1){a=D<<3;b=a+(m+32|0)|0;c=D<<2;e=G[c+l>>2];G[b>>2]=e;G[b+4>>2]=e>>31;a=a+(m+128|0)|0;b=G[c+o>>2];G[a>>2]=b;G[a+4>>2]=b>>31}G[m+352>>2]=0;md(la,41,m+32|0,m+128|0,q,1,m+352|0,U,0,0,k);break ha}if((Dc(la,m+124|0,k)|0)>0){break ha}y=G[m+124>>2];ia:{if(!y){b=1;qa=2;A=1;c=1;break ia}e=t<<2;b=G[e+q>>2];A=G[e+l>>2];c=G[e+o>>2]}G[m+352>>2]=1;G[m+356>>2]=1;e=1;g=0;G[m+128>>2]=1;G[m+132>>2]=0;G[m+304>>2]=1;G[m+308>>2]=1;G[m+256>>2]=1;G[m+260>>2]=1;G[m+136>>2]=1;G[m+140>>2]=0;G[m+208>>2]=1;G[m+212>>2]=1;G[m+360>>2]=1;G[m+144>>2]=1;G[m+148>>2]=0;G[m+312>>2]=1;G[m+316>>2]=1;G[m+264>>2]=1;G[m+268>>2]=1;G[m+152>>2]=1;G[m+156>>2]=0;G[m+216>>2]=1;G[m+220>>2]=1;G[m+364>>2]=1;G[m+368>>2]=1;G[m+320>>2]=1;G[m+272>>2]=1;G[m+160>>2]=1;G[m+164>>2]=0;G[m+224>>2]=1;G[m+372>>2]=1;G[m+376>>2]=1;G[m+168>>2]=1;G[m+172>>2]=0;G[m+324>>2]=1;G[m+328>>2]=1;G[m+276>>2]=1;G[m+280>>2]=1;G[m+176>>2]=1;G[m+180>>2]=0;G[m+228>>2]=1;G[m+232>>2]=1;G[m+184>>2]=1;G[m+188>>2]=0;G[m+380>>2]=1;G[m+384>>2]=1;G[m+332>>2]=1;G[m+336>>2]=1;G[m+284>>2]=1;G[m+288>>2]=1;G[m+192>>2]=1;G[m+196>>2]=0;G[m+236>>2]=1;G[m+240>>2]=1;ja:{while(1){h=a<<2;f=G[h+o>>2];i=G[h+l>>2];ka:{if((f|0)>=(i|0)){u=G[h+(m+208|0)>>2];break ka}if(y){break ja}G[h+(m+208|0)>>2]=-1;u=-1}G[h+(m+304|0)>>2]=f;G[h+(m+352|0)>>2]=i;G[h+(m+256|0)>>2]=G[h+q>>2];B=m+128|0;f=a+1|0;i=B+(f<<3)|0;h=G[h+V>>2];h=Au(e,g,h,h>>31);G[i>>2]=h;w=i;i=Ia;G[w+4>>2]=i;a=B+(a<<3)|0;ic=a,jc=Au(e,g,u,u>>31),G[ic>>2]=jc;G[a+4>>2]=Ia;e=h;g=i;a=f;if((t|0)!=(f|0)){continue}break}a=(m+128|0)+(t<<3)|0;e=G[a>>2];f=e;e=G[(m+208|0)+(t<<2)>>2];ic=a,jc=Au(f,G[a+4>>2],e,e>>31),G[ic>>2]=jc;G[a+4>>2]=Ia;la:{if(!((t|0)!=1|G[V>>2]!=1)){D=(c-A|0)/(b|0)|0;c=A;a=b;break la}e=G[m+208>>2];a=M(e,G[m+256>>2]);D=(M(e,G[m+304>>2]-G[m+352>>2]|0)|0)/G[q>>2]|0}if((c|0)<(A|0)){break ha}ba=G[m+240>>2];ia=M(ba,G[m+384>>2]);e=M(ba,G[m+336>>2]);if((ia|0)>(e|0)){break ha}ca=G[m+236>>2];ja=M(ca,G[m+380>>2]);f=M(ca,G[m+332>>2]);if((ja|0)>(f|0)){break ha}x=G[m+232>>2];R=M(x,G[m+376>>2]);g=M(x,G[m+328>>2]);if((R|0)>(g|0)){break ha}P=G[m+228>>2];X=M(P,G[m+372>>2]);h=M(P,G[m+324>>2]);if((X|0)>(h|0)){break ha}W=G[m+224>>2];s=M(W,G[m+368>>2]);i=M(W,G[m+320>>2]);if((s|0)>(i|0)){break ha}$=G[m+220>>2];ka=M($,G[m+364>>2]);l=M($,G[m+316>>2]);if((ka|0)>(l|0)){break ha}da=G[m+216>>2];ma=M(da,G[m+360>>2]);o=M(da,G[m+312>>2]);if((ma|0)>(o|0)){break ha}ea=G[m+212>>2];oa=M(ea,G[m+356>>2]);q=M(ea,G[m+308>>2]);if((oa|0)>(q|0)){break ha}ra=D+1|0;hb=ra>>31;ib=G[m+192>>2];kb=G[m+196>>2];mb=G[m+184>>2];nb=G[m+188>>2];ob=G[m+176>>2];pb=G[m+180>>2];qb=G[m+168>>2];rb=G[m+172>>2];sb=G[m+160>>2];tb=G[m+164>>2];ub=G[m+152>>2];vb=G[m+156>>2];wb=G[m+144>>2];xb=G[m+148>>2];yb=G[m+136>>2];zb=G[m+140>>2];t=G[m+352>>2];sa=t;Ab=t>>31;La=c;ta=c>>31;pa=b;Bb=b>>31;ga=A>>31;Ma=e;z=e>>31;Db=ba>>31;ha=ia>>31;Ja=f;Y=f>>31;Eb=ca>>31;$a=ja>>31;ab=g;Na=g>>31;Fb=x>>31;fa=R>>31;na=h;Oa=h>>31;Gb=P>>31;Hb=X>>31;Pa=i;Qa=i>>31;Ib=W>>31;cb=s>>31;db=l;Ra=l>>31;Jb=$>>31;Sa=ka>>31;eb=o;Ta=o>>31;Kb=da>>31;fb=ma>>31;Va=q;Za=q>>31;Qb=ea>>31;gb=oa>>31;b=G[m+288>>2];ua=b;Rb=b>>31;b=G[m+284>>2];va=b;Sb=b>>31;b=G[m+280>>2];wa=b;Tb=b>>31;b=G[m+276>>2];xa=b;Ub=b>>31;b=G[m+272>>2];ya=b;Vb=b>>31;b=G[m+268>>2];za=b;Wb=b>>31;b=G[m+264>>2];Aa=b;Xb=b>>31;b=G[m+260>>2];n=b;Yb=b>>31;D=0;while(1){b=ia;c=ha;while(1){p=Au(ib,kb,b-ba|0,c-((b>>>0>>0)+Db|0)|0);Zb=Ia;f=ja;h=$a;while(1){C=Au(mb,nb,f-ca|0,h-((f>>>0>>0)+Eb|0)|0);$b=Ia;i=R;o=fa;while(1){Ba=Au(ob,pb,i-x|0,o-((i>>>0>>0)+Fb|0)|0);ac=Ia;q=X;t=Hb;while(1){Ca=Au(qb,rb,q-P|0,t-((q>>>0

>>0)+Gb|0)|0);bc=Ia;u=s;y=cb;while(1){Da=Au(sb,tb,u-W|0,y-((u>>>0>>0)+Ib|0)|0);cc=Ia;B=ka;aa=Sa;while(1){Ea=Au(ub,vb,B-$|0,aa-((B>>>0<$>>>0)+Jb|0)|0);dc=Ia;w=ma;_=fb;while(1){Ga=Au(wb,xb,w-da|0,_-((w>>>0>>0)+Kb|0)|0);ec=Ia;e=oa;g=gb;while(1){v=Au(yb,zb,e-ea|0,g-((e>>>0>>0)+Qb|0)|0)+sa|0;l=Ab+Ia|0;l=v>>>0>>0?l+1|0:l;v=v+Ga|0;l=l+ec|0;l=v>>>0>>0?l+1|0:l;v=v+Ea|0;l=l+dc|0;l=v>>>0>>0?l+1|0:l;v=v+Da|0;l=l+cc|0;l=v>>>0>>0?l+1|0:l;v=v+Ca|0;l=l+bc|0;l=v>>>0>>0?l+1|0:l;v=v+Ba|0;l=l+ac|0;l=v>>>0>>0?l+1|0:l;v=v+C|0;l=l+$b|0;l=v>>>0>>0?l+1|0:l;v=p+v|0;l=l+Zb|0;if((Ud(la,qa,A,ga,v,p>>>0>v>>>0?l+1|0:l,ra,hb,a,1,0,(D<<2)+U|0,m+123|0,m+32|0,k)|0)>0){break ha}D=D+ra|0;l=g+Yb|0;e=e+n|0;l=e>>>0>>0?l+1|0:l;g=l;if(e>>>0<=Va>>>0&(Za|0)>=(l|0)|(l|0)<(Za|0)){continue}break}l=_+Xb|0;e=w+Aa|0;l=e>>>0>>0?l+1|0:l;w=e;_=l;if(e>>>0<=eb>>>0&(Ta|0)>=(l|0)|(l|0)<(Ta|0)){continue}break}l=aa+Wb|0;e=B+za|0;l=e>>>0>>0?l+1|0:l;B=e;aa=l;if(e>>>0<=db>>>0&(Ra|0)>=(l|0)|(l|0)<(Ra|0)){continue}break}l=y+Vb|0;e=u+ya|0;l=e>>>0>>0?l+1|0:l;u=e;y=l;if(e>>>0<=Pa>>>0&(Qa|0)>=(l|0)|(l|0)<(Qa|0)){continue}break}l=t+Ub|0;e=q+xa|0;l=e>>>0>>0?l+1|0:l;q=e;t=l;if(e>>>0<=na>>>0&(Oa|0)>=(l|0)|(l|0)<(Oa|0)){continue}break}l=o+Tb|0;e=i+wa|0;l=e>>>0>>0?l+1|0:l;i=e;o=l;if(e>>>0<=ab>>>0&(Na|0)>=(l|0)|(l|0)<(Na|0)){continue}break}l=h+Sb|0;e=f+va|0;l=e>>>0>>0?l+1|0:l;f=e;h=l;if(e>>>0<=Ja>>>0&(Y|0)>=(l|0)|(l|0)<(Y|0)){continue}break}l=c+Rb|0;b=b+ua|0;l=b>>>0>>0?l+1|0:l;c=l;if(b>>>0<=Ma>>>0&(z|0)>=(l|0)|(l|0)<(z|0)){continue}break}l=ga+Bb|0;b=A+pa|0;l=b>>>0>>0?l+1|0:l;A=b;ga=l;if(b>>>0<=La>>>0&(ta|0)>=(l|0)|(l|0)<(ta|0)){continue}break}break ha}G[m+16>>2]=a+1;a=m+32|0;Ya(a,81,26967,m+16|0);Ua(a);G[k>>2]=321}Fa=m+400|0;break L;case 69:la=a;a=0;qa=1;m=Fa-400|0;Fa=m;t=G[V+40>>2];ma:{if(t-10>>>0<=4294967286){G[m>>2]=t;a=m+32|0;Ya(a,81,23817,m);Ua(a);G[k>>2]=320;break ma}if(Nb(la,k)){if((t|0)!=1){b=t&-2;while(1){c=D<<3;e=m+32|0;f=c+e|0;g=D<<2;h=G[g+l>>2];G[f>>2]=h;G[f+4>>2]=h>>31;f=c;c=m+128|0;f=f+c|0;g=G[g+o>>2];G[f>>2]=g;G[f+4>>2]=g>>31;g=e;e=D|1;f=e<<3;g=g+f|0;e=e<<2;h=G[e+l>>2];G[g>>2]=h;G[g+4>>2]=h>>31;c=c+f|0;e=G[e+o>>2];G[c>>2]=e;G[c+4>>2]=e>>31;D=D+2|0;a=a+2|0;if((b|0)!=(a|0)){continue}break}}if(t&1){a=D<<3;b=a+(m+32|0)|0;c=D<<2;e=G[c+l>>2];G[b>>2]=e;G[b+4>>2]=e>>31;a=a+(m+128|0)|0;b=G[c+o>>2];G[a>>2]=b;G[a+4>>2]=b>>31}G[m+352>>2]=0;G[m+356>>2]=0;md(la,80,m+32|0,m+128|0,q,1,m+352|0,U,0,0,k);break ma}if((Dc(la,m+124|0,k)|0)>0){break ma}y=G[m+124>>2];na:{if(!y){b=1;qa=2;A=1;c=1;break na}e=t<<2;b=G[e+q>>2];A=G[e+l>>2];c=G[e+o>>2]}G[m+352>>2]=1;G[m+356>>2]=1;e=1;g=0;G[m+128>>2]=1;G[m+132>>2]=0;G[m+304>>2]=1;G[m+308>>2]=1;G[m+256>>2]=1;G[m+260>>2]=1;G[m+136>>2]=1;G[m+140>>2]=0;G[m+208>>2]=1;G[m+212>>2]=1;G[m+360>>2]=1;G[m+144>>2]=1;G[m+148>>2]=0;G[m+312>>2]=1;G[m+316>>2]=1;G[m+264>>2]=1;G[m+268>>2]=1;G[m+152>>2]=1;G[m+156>>2]=0;G[m+216>>2]=1;G[m+220>>2]=1;G[m+364>>2]=1;G[m+368>>2]=1;G[m+320>>2]=1;G[m+272>>2]=1;G[m+160>>2]=1;G[m+164>>2]=0;G[m+224>>2]=1;G[m+372>>2]=1;G[m+376>>2]=1;G[m+168>>2]=1;G[m+172>>2]=0;G[m+324>>2]=1;G[m+328>>2]=1;G[m+276>>2]=1;G[m+280>>2]=1;G[m+176>>2]=1;G[m+180>>2]=0;G[m+228>>2]=1;G[m+232>>2]=1;G[m+184>>2]=1;G[m+188>>2]=0;G[m+380>>2]=1;G[m+384>>2]=1;G[m+332>>2]=1;G[m+336>>2]=1;G[m+284>>2]=1;G[m+288>>2]=1;G[m+192>>2]=1;G[m+196>>2]=0;G[m+236>>2]=1;G[m+240>>2]=1;oa:{while(1){h=a<<2;f=G[h+o>>2];i=G[h+l>>2];pa:{if((f|0)>=(i|0)){u=G[h+(m+208|0)>>2];break pa}if(y){break oa}G[h+(m+208|0)>>2]=-1;u=-1}G[h+(m+304|0)>>2]=f;G[h+(m+352|0)>>2]=i;G[h+(m+256|0)>>2]=G[h+q>>2];B=m+128|0;f=a+1|0;i=B+(f<<3)|0;h=G[h+V>>2];h=Au(e,g,h,h>>31);G[i>>2]=h;w=i;i=Ia;G[w+4>>2]=i;a=B+(a<<3)|0;ic=a,jc=Au(e,g,u,u>>31),G[ic>>2]=jc;G[a+4>>2]=Ia;e=h;g=i;a=f;if((t|0)!=(f|0)){continue}break}a=(m+128|0)+(t<<3)|0;e=G[a>>2];f=e;e=G[(m+208|0)+(t<<2)>>2];ic=a,jc=Au(f,G[a+4>>2],e,e>>31),G[ic>>2]=jc;G[a+4>>2]=Ia;qa:{if(!((t|0)!=1|G[V>>2]!=1)){D=(c-A|0)/(b|0)|0;c=A;a=b;break qa}e=G[m+208>>2];a=M(e,G[m+256>>2]);D=(M(e,G[m+304>>2]-G[m+352>>2]|0)|0)/G[q>>2]|0}if((c|0)<(A|0)){break ma}ba=G[m+240>>2];ia=M(ba,G[m+384>>2]);e=M(ba,G[m+336>>2]);if((ia|0)>(e|0)){break ma}ca=G[m+236>>2];ja=M(ca,G[m+380>>2]);f=M(ca,G[m+332>>2]);if((ja|0)>(f|0)){break ma}x=G[m+232>>2];R=M(x,G[m+376>>2]);g=M(x,G[m+328>>2]);if((R|0)>(g|0)){break ma}P=G[m+228>>2];X=M(P,G[m+372>>2]);h=M(P,G[m+324>>2]);if((X|0)>(h|0)){break ma}W=G[m+224>>2];s=M(W,G[m+368>>2]);i=M(W,G[m+320>>2]);if((s|0)>(i|0)){break ma}$=G[m+220>>2];ka=M($,G[m+364>>2]);l=M($,G[m+316>>2]);if((ka|0)>(l|0)){break ma}da=G[m+216>>2];ma=M(da,G[m+360>>2]);o=M(da,G[m+312>>2]);if((ma|0)>(o|0)){break ma}ea=G[m+212>>2];oa=M(ea,G[m+356>>2]);q=M(ea,G[m+308>>2]);if((oa|0)>(q|0)){break ma}ra=D+1|0;hb=ra>>31;ib=G[m+192>>2];kb=G[m+196>>2];mb=G[m+184>>2];nb=G[m+188>>2];ob=G[m+176>>2];pb=G[m+180>>2];qb=G[m+168>>2];rb=G[m+172>>2];sb=G[m+160>>2];tb=G[m+164>>2];ub=G[m+152>>2];vb=G[m+156>>2];wb=G[m+144>>2];xb=G[m+148>>2];yb=G[m+136>>2];zb=G[m+140>>2];t=G[m+352>>2];sa=t;Ab=t>>31;La=c;ta=c>>31;pa=b;Bb=b>>31;ga=A>>31;Ma=e;z=e>>31;Db=ba>>31;ha=ia>>31;Ja=f;Y=f>>31;Eb=ca>>31;$a=ja>>31;ab=g;Na=g>>31;Fb=x>>31;fa=R>>31;na=h;Oa=h>>31;Gb=P>>31;Hb=X>>31;Pa=i;Qa=i>>31;Ib=W>>31;cb=s>>31;db=l;Ra=l>>31;Jb=$>>31;Sa=ka>>31;eb=o;Ta=o>>31;Kb=da>>31;fb=ma>>31;Va=q;Za=q>>31;Qb=ea>>31;gb=oa>>31;b=G[m+288>>2];ua=b;Rb=b>>31;b=G[m+284>>2];va=b;Sb=b>>31;b=G[m+280>>2];wa=b;Tb=b>>31;b=G[m+276>>2];xa=b;Ub=b>>31;b=G[m+272>>2];ya=b;Vb=b>>31;b=G[m+268>>2];za=b;Wb=b>>31;b=G[m+264>>2];Aa=b;Xb=b>>31;b=G[m+260>>2];n=b;Yb=b>>31;D=0;while(1){b=ia;c=ha;while(1){p=Au(ib,kb,b-ba|0,c-((b>>>0>>0)+Db|0)|0);Zb=Ia;f=ja;h=$a;while(1){C=Au(mb,nb,f-ca|0,h-((f>>>0>>0)+Eb|0)|0);$b=Ia;i=R;o=fa;while(1){Ba=Au(ob,pb,i-x|0,o-((i>>>0>>0)+Fb|0)|0);ac=Ia;q=X;t=Hb;while(1){Ca=Au(qb,rb,q-P|0,t-((q>>>0

>>0)+Gb|0)|0);bc=Ia;u=s;y=cb;while(1){Da=Au(sb,tb,u-W|0,y-((u>>>0>>0)+Ib|0)|0);cc=Ia;B=ka;aa=Sa;while(1){Ea=Au(ub,vb,B-$|0,aa-((B>>>0<$>>>0)+Jb|0)|0);dc=Ia;w=ma;_=fb;while(1){Ga=Au(wb,xb,w-da|0,_-((w>>>0>>0)+Kb|0)|0);ec=Ia;e=oa;g=gb;while(1){v=Au(yb,zb,e-ea|0,g-((e>>>0>>0)+Qb|0)|0)+sa|0;l=Ab+Ia|0;l=v>>>0>>0?l+1|0:l;v=v+Ga|0;l=l+ec|0;l=v>>>0>>0?l+1|0:l;v=v+Ea|0;l=l+dc|0;l=v>>>0>>0?l+1|0:l;v=v+Da|0;l=l+cc|0;l=v>>>0>>0?l+1|0:l;v=v+Ca|0;l=l+bc|0;l=v>>>0>>0?l+1|0:l;v=v+Ba|0;l=l+ac|0;l=v>>>0>>0?l+1|0:l;v=v+C|0;l=l+$b|0;l=v>>>0>>0?l+1|0:l;v=p+v|0;l=l+Zb|0;if((hf(la,qa,A,ga,v,p>>>0>v>>>0?l+1|0:l,ra,hb,a,1,0,0,(D<<3)+U|0,m+123|0,m+32|0,k)|0)>0){break ma}D=D+ra|0;l=g+Yb|0;e=e+n|0;l=e>>>0>>0?l+1|0:l;g=l;if(e>>>0<=Va>>>0&(Za|0)>=(l|0)|(l|0)<(Za|0)){continue}break}l=_+Xb|0;e=w+Aa|0;l=e>>>0>>0?l+1|0:l;w=e;_=l;if(e>>>0<=eb>>>0&(Ta|0)>=(l|0)|(l|0)<(Ta|0)){continue}break}l=aa+Wb|0;e=B+za|0;l=e>>>0>>0?l+1|0:l;B=e;aa=l;if(e>>>0<=db>>>0&(Ra|0)>=(l|0)|(l|0)<(Ra|0)){continue}break}l=y+Vb|0;e=u+ya|0;l=e>>>0>>0?l+1|0:l;u=e;y=l;if(e>>>0<=Pa>>>0&(Qa|0)>=(l|0)|(l|0)<(Qa|0)){continue}break}l=t+Ub|0;e=q+xa|0;l=e>>>0>>0?l+1|0:l;q=e;t=l;if(e>>>0<=na>>>0&(Oa|0)>=(l|0)|(l|0)<(Oa|0)){continue}break}l=o+Tb|0;e=i+wa|0;l=e>>>0>>0?l+1|0:l;i=e;o=l;if(e>>>0<=ab>>>0&(Na|0)>=(l|0)|(l|0)<(Na|0)){continue}break}l=h+Sb|0;e=f+va|0;l=e>>>0>>0?l+1|0:l;f=e;h=l;if(e>>>0<=Ja>>>0&(Y|0)>=(l|0)|(l|0)<(Y|0)){continue}break}l=c+Rb|0;b=b+ua|0;l=b>>>0>>0?l+1|0:l;c=l;if(b>>>0<=Ma>>>0&(z|0)>=(l|0)|(l|0)<(z|0)){continue}break}l=ga+Bb|0;b=A+pa|0;l=b>>>0>>0?l+1|0:l;A=b;ga=l;if(b>>>0<=La>>>0&(ta|0)>=(l|0)|(l|0)<(ta|0)){continue}break}break ma}G[m+16>>2]=a+1;a=m+32|0;Ya(a,81,26967,m+16|0);Ua(a);G[k>>2]=321}Fa=m+400|0;break L;case 70:Xp(a,G[V+40>>2],V,l,o,q,U,0,k);break L;case 31:hq(a,G[V+40>>2],V,l,o,q,N(0),U,0,k);break L;case 71:dq(a,G[V+40>>2],V,l,o,q,0,U,0,k);break L;default:break Q}}G[k>>2]=410}}Fa=V+848|0;b=0;B=0;c=0;aa=0;i=0;q=0;break J}o=lb(M(f,Ka),1);if(!o){G[k>>2]=113;break a}d=+(f|0)/Z;ra:{if(O(d)<2147483648){w=~~d;break ra}w=-2147483648}R=M(w,Ka);d=+(t|0)/Z;sa:{if(O(d)<2147483648){h=~~d;break sa}h=-2147483648}Pb=M(M(R,h),W);U=lb(Pb,1);if(!U){G[k>>2]=113;break a}_=0;Ha=0;b=0;B=0;c=0;i=0;q=0;ta:{ua:{va:{wa:{xa:{ya:{switch(Eu(e- -64|0,29)|0){case 9:_=o;Ha=U;break xa;case 10:A=o;b=U;break xa;case 6:pa=o;B=U;break wa;case 12:ba=o;c=U;break va;case 16:ia=o;aa=U;break ua;case 4:ca=o;i=U;break ta;case 0:break ya;default:break ta}}ja=o;q=U;break ta}B=0}c=0}aa=0}}e=G[r+1244>>2];G[r+1208>>2]=G[r+1240>>2];G[r+1212>>2]=e;e=G[r+1236>>2];G[r+1200>>2]=G[r+1232>>2];G[r+1204>>2]=e;za:{if(Z>=1){d=Z*+(h|0);Aa:{if(O(d)<2147483648){t=~~d;break Aa}t=-2147483648}y=1;R=0;d=Z*+(w|0);Ba:{if(O(d)<2147483648){e=~~d;break Ba}e=-2147483648}break za}d=1/Z;Ca:{if(O(d)<2147483648){y=~~d;break Ca}y=-2147483648}e=f}if((W|0)<=0){break J}ga=e;if((t|0)>0){g=f;oa=f>>31;ka=y&-4;X=y&3;la=y-2|0;$=y-1|0;sa=$&-4;da=$&3;$a=(y|0)<=0;while(1){G[r+1208>>2]=G[r+1240>>2]+ea;La=M(ea,Ja);P=0;ma=0;Da:{if((ga|0)<=0){while(1){G[r+1272>>2]=0;G[r+1204>>2]=G[r+1236>>2]+P;cg(a,u,r+1200|0,g,oa,0,o,0,r+1272|0);if(G[r+1272>>2]){break Da}Ea:{if(!(Z<1)){break Ea}d=+(P|0)/Z;Fa:{if(O(d)<2147483648){e=~~d;break Fa}e=-2147483648}if((y|0)<2){break Ea}e=M(La+M(e,w)|0,Ka)+U|0;h=0;f=1;if(la>>>0>2){while(1){bb(e+M(f,R)|0,e,R);bb(e+M(f+1|0,R)|0,e,R);bb(e+M(f+2|0,R)|0,e,R);bb(e+M(f+3|0,R)|0,e,R);f=f+4|0;h=h+4|0;if((sa|0)!=(h|0)){continue}break}}h=0;if(!da){break Ea}while(1){bb(e+M(f,R)|0,e,R);f=f+1|0;h=h+1|0;if((da|0)!=(h|0)){continue}break}}P=P+1|0;if((t|0)!=(P|0)){continue}break Da}}while(1){G[r+1272>>2]=0;G[r+1204>>2]=G[r+1236>>2]+ma;cg(a,u,r+1200|0,g,oa,0,o,0,r+1272|0);if(G[r+1272>>2]){break Da}ab=Eu(G[j>>2]- -64|0,29);d=+(ma|0)/Z;Ga:{if(O(d)<2147483648){e=~~d;break Ga}e=-2147483648}Ma=La+M(e,w)|0;P=0;while(1){d=+(P|0)/Z;Ha:{if(O(d)<2147483648){e=~~d;break Ha}e=-2147483648}x=e+Ma|0;Ia:{Ja:{switch(ab|0){case 0:if($a){break Ia}l=(P<<3)+ja|0;e=0;f=0;h=0;if($>>>0>=3){while(1){s=(f+x<<3)+q|0;L[s>>3]=L[l>>3]+L[s>>3];s=((f|1)+x<<3)+q|0;L[s>>3]=L[l>>3]+L[s>>3];s=((f|2)+x<<3)+q|0;L[s>>3]=L[l>>3]+L[s>>3];s=((f|3)+x<<3)+q|0;L[s>>3]=L[l>>3]+L[s>>3];f=f+4|0;h=h+4|0;if((ka|0)!=(h|0)){continue}break}}if(!X){break Ia}while(1){h=(f+x<<3)+q|0;L[h>>3]=L[l>>3]+L[h>>3];f=f+1|0;e=e+1|0;if((X|0)!=(e|0)){continue}break};break Ia;case 4:if((y|0)<=0){break Ia}l=(P<<2)+ca|0;e=0;f=0;h=0;if($>>>0>=3){while(1){s=(f+x<<2)+i|0;K[s>>2]=K[l>>2]+K[s>>2];s=((f|1)+x<<2)+i|0;K[s>>2]=K[l>>2]+K[s>>2];s=((f|2)+x<<2)+i|0;K[s>>2]=K[l>>2]+K[s>>2];s=((f|3)+x<<2)+i|0;K[s>>2]=K[l>>2]+K[s>>2];f=f+4|0;h=h+4|0;if((ka|0)!=(h|0)){continue}break}}if(!X){break Ia}while(1){h=(f+x<<2)+i|0;K[h>>2]=K[l>>2]+K[h>>2];f=f+1|0;e=e+1|0;if((X|0)!=(e|0)){continue}break};break Ia;case 16:if((y|0)<=0){break Ia}s=(P<<3)+ia|0;e=0;f=0;h=0;if($>>>0>=3){while(1){l=(f+x<<3)+aa|0;fa=l;na=G[s>>2];ha=na+G[l>>2]|0;l=G[l+4>>2]+G[s+4>>2]|0;G[fa>>2]=ha;G[fa+4>>2]=ha>>>0>>0?l+1|0:l;l=((f|1)+x<<3)+aa|0;fa=l;na=G[s>>2];ha=na+G[l>>2]|0;l=G[l+4>>2]+G[s+4>>2]|0;G[fa>>2]=ha;G[fa+4>>2]=ha>>>0>>0?l+1|0:l;l=((f|2)+x<<3)+aa|0;fa=l;na=G[s>>2];ha=na+G[l>>2]|0;l=G[l+4>>2]+G[s+4>>2]|0;G[fa>>2]=ha;G[fa+4>>2]=ha>>>0>>0?l+1|0:l;l=((f|3)+x<<3)+aa|0;fa=l;na=G[s>>2];ha=na+G[l>>2]|0;l=G[l+4>>2]+G[s+4>>2]|0;G[fa>>2]=ha;G[fa+4>>2]=ha>>>0>>0?l+1|0:l;f=f+4|0;h=h+4|0;if((ka|0)!=(h|0)){continue}break}}if(!X){break Ia}while(1){h=(f+x<<3)+aa|0;l=G[h+4>>2]+G[s+4>>2]|0;fa=G[s>>2];ha=fa+G[h>>2]|0;G[h>>2]=ha;G[h+4>>2]=ha>>>0>>0?l+1|0:l;f=f+1|0;e=e+1|0;if((X|0)!=(e|0)){continue}break};break Ia;case 12:if((y|0)<=0){break Ia}l=(P<<2)+ba|0;e=0;f=0;h=0;if($>>>0>=3){while(1){s=(f+x<<2)+c|0;G[s>>2]=G[s>>2]+G[l>>2];s=((f|1)+x<<2)+c|0;G[s>>2]=G[s>>2]+G[l>>2];s=((f|2)+x<<2)+c|0;G[s>>2]=G[s>>2]+G[l>>2];s=((f|3)+x<<2)+c|0;G[s>>2]=G[s>>2]+G[l>>2];f=f+4|0;h=h+4|0;if((ka|0)!=(h|0)){continue}break}}if(!X){break Ia}while(1){h=(f+x<<2)+c|0;G[h>>2]=G[h>>2]+G[l>>2];f=f+1|0;e=e+1|0;if((X|0)!=(e|0)){continue}break};break Ia;case 6:if((y|0)<=0){break Ia}l=(P<<1)+pa|0;e=0;f=0;h=0;if($>>>0>=3){while(1){s=(f+x<<1)+B|0;F[s>>1]=I[s>>1]+I[l>>1];s=((f|1)+x<<1)+B|0;F[s>>1]=I[s>>1]+I[l>>1];s=((f|2)+x<<1)+B|0;F[s>>1]=I[s>>1]+I[l>>1];s=((f|3)+x<<1)+B|0;F[s>>1]=I[s>>1]+I[l>>1];f=f+4|0;h=h+4|0;if((ka|0)!=(h|0)){continue}break}}if(!X){break Ia}while(1){h=(f+x<<1)+B|0;F[h>>1]=I[h>>1]+I[l>>1];f=f+1|0;e=e+1|0;if((X|0)!=(e|0)){continue}break};break Ia;case 10:if((y|0)<=0){break Ia}l=(P<<1)+A|0;e=0;f=0;h=0;if($>>>0>=3){while(1){s=(f+x<<1)+b|0;F[s>>1]=I[s>>1]+I[l>>1];s=((f|1)+x<<1)+b|0;F[s>>1]=I[s>>1]+I[l>>1];s=((f|2)+x<<1)+b|0;F[s>>1]=I[s>>1]+I[l>>1];s=((f|3)+x<<1)+b|0;F[s>>1]=I[s>>1]+I[l>>1];f=f+4|0;h=h+4|0;if((ka|0)!=(h|0)){continue}break}}if(!X){break Ia}while(1){h=(f+x<<1)+b|0;F[h>>1]=I[h>>1]+I[l>>1];f=f+1|0;e=e+1|0;if((X|0)!=(e|0)){continue}break};break Ia;case 9:break Ja;default:break Ia}}if((y|0)<=0){break Ia}l=P+_|0;e=0;f=0;h=0;if($>>>0>=3){while(1){s=(f+x|0)+Ha|0;E[s|0]=H[s|0]+H[l|0];s=((f|1)+x|0)+Ha|0;E[s|0]=H[s|0]+H[l|0];s=((f|2)+x|0)+Ha|0;E[s|0]=H[s|0]+H[l|0];s=((f|3)+x|0)+Ha|0;E[s|0]=H[s|0]+H[l|0];f=f+4|0;h=h+4|0;if((ka|0)!=(h|0)){continue}break}}if(!X){break Ia}while(1){h=(f+x|0)+Ha|0;E[h|0]=H[h|0]+H[l|0];f=f+1|0;e=e+1|0;if((X|0)!=(e|0)){continue}break}}P=P+1|0;if((ga|0)!=(P|0)){continue}break}Ka:{if(!(Z<1)|(y|0)<2){break Ka}e=M(Ka,Ma)+U|0;h=0;f=1;if(la>>>0>2){while(1){bb(e+M(f,R)|0,e,R);bb(e+M(f+1|0,R)|0,e,R);bb(e+M(f+2|0,R)|0,e,R);bb(e+M(f+3|0,R)|0,e,R);f=f+4|0;h=h+4|0;if((sa|0)!=(h|0)){continue}break}}h=0;if(!da){break Ka}while(1){bb(e+M(f,R)|0,e,R);f=f+1|0;h=h+1|0;if((da|0)!=(h|0)){continue}break}}ma=ma+1|0;if((ma|0)!=(t|0)){continue}break}}Wa(o);ea=ea+1|0;if((ea|0)!=(W|0)){continue}break}break J}a=G[r+1240>>2];while(1){Wa(o);g=g+1|0;if((W|0)!=(g|0)){continue}break}G[r+1208>>2]=(a+W|0)-1}La:{if(!Lb){break La}_a=(Pb|0)/(Ka|0)|0;if((_a|0)<=0){break La}d=Z*Z;Z=Z>=1?d:1/d;g=0;while(1){Ma:{Na:{switch(Eu(G[j>>2]- -64|0,29)|0){case 9:a=g+Ha|0;d=+H[a|0]/Z;if(d<4294967296&d>=0){E[a|0]=~~d>>>0;break Ma}E[a|0]=0;break Ma;case 10:a=(g<<1)+b|0;d=+F[a>>1]/Z;if(O(d)<2147483648){F[a>>1]=~~d;break Ma}F[a>>1]=0;break Ma;case 6:a=(g<<1)+B|0;d=+I[a>>1]/Z;if(d<4294967296&d>=0){F[a>>1]=~~d>>>0;break Ma}F[a>>1]=0;break Ma;case 12:a=(g<<2)+c|0;d=+G[a>>2]/Z;if(O(d)<2147483648){G[a>>2]=~~d;break Ma}G[a>>2]=-2147483648;break Ma;case 16:a=(g<<3)+aa|0;d=(+J[a>>2]+ +G[a+4>>2]*4294967296)/Z;if(O(d)<0x8000000000000000){G[a>>2]=~~d>>>0;G[a+4>>2]=O(d)>=1?~~(d>0?Q(S(d*2.3283064365386963e-10),4294967295):T((d-+(~~d>>>0>>>0))*2.3283064365386963e-10))>>>0:0;break Ma}G[a>>2]=0;G[a+4>>2]=-2147483648;break Ma;case 4:a=(g<<2)+i|0;K[a>>2]=+K[a>>2]/Z;break Ma;case 0:break Na;default:break Ma}}a=(g<<3)+q|0;L[a>>3]=L[a>>3]/Z}g=g+1|0;if((_a|0)!=(g|0)){continue}break}}if((hc|0)!=64){g=U;break a}g=0;Oa:{Pa:{Qa:{Ra:{if((_a|0)>0){while(1){d=L[(g<<3)+U>>3];if(d>2147483647){g=U;break a}if(!(d<-2147483648)){g=g+1|0;if((_a|0)==(g|0)){break Ra}continue}break}g=U;break a}g=lb(_a,4);if(!g){break Qa}break Oa}g=lb(_a,4);if(g){break Pa}}G[k>>2]=113;g=0;break a}if((_a|0)<=0){break Oa}e=0;f=0;if(_a-1>>>0>=3){b=_a&-4;u=0;while(1){c=(f<<2)+g|0;d=bh(L[(f<<3)+U>>3]);Sa:{if(O(d)<2147483648){a=~~d;break Sa}a=-2147483648}G[c>>2]=a;a=f|1;c=(a<<2)+g|0;d=bh(L[(a<<3)+U>>3]);Ta:{if(O(d)<2147483648){a=~~d;break Ta}a=-2147483648}G[c>>2]=a;a=f|2;c=(a<<2)+g|0;d=bh(L[(a<<3)+U>>3]);Ua:{if(O(d)<2147483648){a=~~d;break Ua}a=-2147483648}G[c>>2]=a;a=f|3;c=(a<<2)+g|0;d=bh(L[(a<<3)+U>>3]);Va:{if(O(d)<2147483648){a=~~d;break Va}a=-2147483648}G[c>>2]=a;f=f+4|0;u=u+4|0;if((b|0)!=(u|0)){continue}break}}b=_a&3;if(!b){break Oa}while(1){c=(f<<2)+g|0;d=bh(L[(f<<3)+U>>3]);Wa:{if(O(d)<2147483648){a=~~d;break Wa}a=-2147483648}G[c>>2]=a;f=f+1|0;e=e+1|0;if((b|0)!=(e|0)){continue}break}}Wa(U);G[j>>2]=32}Fa=r+1280|0;return g|0}function Jq(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,K=0,N=0;d=G[a+60>>2];p=Fa-4112|0;Fa=p;a:{b:{c:{d:{e:{b=G[a+48>>2];if(!b){break e}c=H[b|0];if(!c){break e}if(!Xa(b,32148)){break e}if(!Xa(b,92037)){break e}l=b;f:{while(1){g:{h:{i:{c=c&255;switch(c|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:break f;case 0:break g;case 9:case 10:case 32:break h;default:break i}}if((c|0)!=59){break f}}c=H[l+1|0];l=l+1|0;continue}break}l=G[952412];break a}l=Ic(1,180);if(!l){break b}K=l,N=Lc(d),G[K+28>>2]=N;b=Lc(b);Yb(b,b);w=b;j:{if(H[b|0]!=91){break j}w=b+1|0;c=Va(w);while(1){if((c|0)<=0){break j}d=b+c|0;c=c-1|0;if(H[d|0]!=93){continue}break}E[d|0]=0}c=Ic(Va(w)+1|0,1);Yb(w,c);pb(b);k:{if(H[c|0]!=64){K=l,N=Lc(c),G[K+16>>2]=N;break k}b=Ol(c+1|0);if(!b){break k}K=l,N=Lc(b),G[K+16>>2]=N;pb(b)}pb(c);b=G[l+16>>2];if(!(H[b|0]?b:0)){l=G[952412];break a}b=Lc(0);G[l>>2]=b;w=0;c=Lc(b);if(c){b=Lh(c,3441,p+16|0);pb(c);w=(b|0)!=0}G[l+4>>2]=2;E[p+16|0]=0;l:{b=Fd(35762);m:{if(b){if(H[Za(p+16|0,b)|0]){break m}}b=Lc(G[l>>2]);if(b){Lh(b,26055,p+16|0);pb(b)}if(!H[p+16|0]){break l}}if(Xc(p+16|0,30815)){break l}c=1;G[l+4>>2]=1;break d}c=G[l+4>>2];if((c|0)!=2){break d}if(l){G[l+136>>2]=145;G[l+132>>2]=146;G[l+128>>2]=147;G[l+124>>2]=148;G[l+120>>2]=149;G[l+116>>2]=150;G[l+112>>2]=151;G[l+104>>2]=43322}G[l+68>>2]=2;break c}l=G[952412];break a}G[p>>2]=c;Tb(G[24367],75705,p)}E[p+16|0]=0;b=Fd(33318);n:{if(b){if(H[Za(p+16|0,b)|0]){break n}}b=Lc(G[l>>2]);if(b){Lh(b,4716,p+16|0);pb(b)}if(H[p+16|0]){break n}F[p+20>>1]=H[20720]|H[20721]<<8;G[p+16>>2]=H[20716]|H[20717]<<8|(H[20718]<<16|H[20719]<<24)}K=l,N=(Ql(p+16|0)|0)!=0,G[K+8>>2]=N;E[p+16|0]=0;b=Fd(35058);o:{p:{if(b){c=H[Za(p+16|0,b)|0];if(c){break p}}b=Lc(G[l>>2]);if(b){Lh(b,17540,p+16|0);pb(b)}c=H[p+16|0];if(!c){break o}}q:{if((c<<24>>24)-48>>>0<=9){c=_b(p+16|0);break q}c=1;if(Ql(p+16|0)){break q}c=0;d=0;f=p+16|0;if(!(!f|!H[f|0])){b=Xb(Va(f)+1|0);d=b;e=H[f|0];r:{if(!e){break r}while(1){d=e<<24>>24;if(!((d|0)==32|d-9>>>0<5)){d=b;while(1){E[d|0]=e;d=d+1|0;e=H[f+1|0];f=f+1|0;if(e){continue}break}break r}e=H[f+1|0];f=f+1|0;if(e){continue}break}d=b}E[d|0]=0;f=d-b|0;s:{if(!f){break s}while(1){d=d-1|0;g=E[d|0];if(!((g|0)==32|g-9>>>0<5)){break s}E[d|0]=0;f=f-1|0;if(f){continue}break}}d=H[b|0];if(d){f=b;while(1){d=d<<24>>24;if(d-65>>>0<26){E[f|0]=d-65>>>0<26?d|32:d}d=H[f+1|0];f=f+1|0;if(d){continue}break}}d=1;t:{if(!Xa(b,20716)){break t}if(!Xa(b,13555)){break t}if(!Xa(b,18607)){break t}d=!Xa(b,41974)}pb(b)}if(!d){break o}}G[l+12>>2]=c}G[320796]=G[320796]+1;r=Fa-224|0;Fa=r;G[950220]=l;zl();K=3792640,N=Lc(16977),G[K>>2]=N;b=G[G[950220]+28>>2];u:{v:{if(b){if(!ob(b,41167,3805472)){G[951368]=0;G[951369]=1072693248}if(!ob(b,41142,3805488)){G[951372]=0;G[951373]=0}if(!ob(b,40771,3805480)){G[951370]=0;G[951371]=0}if(!ob(b,40752,3805496)){G[951374]=0;G[951375]=1072693248}if(!ob(b,41229,3805504)){G[951376]=0;G[951377]=0}if(!ob(b,40821,3805512)){break v}break u}G[951370]=0;G[951371]=0;G[951368]=0;G[951369]=1072693248;G[951372]=0;G[951373]=0;G[951376]=0;G[951377]=0;G[951374]=0;G[951375]=1072693248}G[951378]=0;G[951379]=0}k=L[475685];if(!(L[475684]!=1|k!=0|L[475688]!=.5)){G[951376]=0;G[951377]=0}if(!(k!=0|L[475687]!=1|L[475689]!=.5)){G[951378]=0;G[951379]=0}c=G[950220];b=G[c+28>>2];if(!(!b|!H[b|0])){Ce(G[947122]);bi(G[G[950220]+28>>2],256e3);b=rd(G[G[950220]+28>>2]);G[947122]=b;w:{if(!(!b|!(b?G[b+3312>>2]:0))){c=G[947122];x:{if(!G[c+3304>>2]){L[474082]=L[c+760>>3];b=c+768|0;break x}L[474082]=L[c+768>>3];b=c+760|0}L[474083]=L[b>>3];k=L[c+48>>3];k=G[c+3256>>2]?-k:k;break w}G[948166]=0;G[948167]=0;G[948164]=0;G[948165]=0;k=0}L[474081]=k;c=G[950220]}G[945061]=1;G[950218]=0;Cl(G[c+16>>2]);i=Fa-4784|0;Fa=i;y:{z:{A:{B:{C:{if(!H[3780236]){E[3780236]=1;if(!G[945060]){b=ab(65544);G[945060]=b;if(!b){break C}}if(!G[945061]){G[945061]=1}d=G[945057];if(!d){d=G[30060];G[945057]=d}if(!G[945058]){G[945058]=G[29763]}f=G[945062];D:{E:{if(f){h=G[945063];e=G[(h<<2)+f>>2];if(e){break D}g=G[950329];if(g-1>>>0>h>>>0){break E}b=g+8|0;c=ub(f,b<<2);G[945062]=c;if(!c){break A}c=c+(g<<2)|0;G[c>>2]=0;G[c+4>>2]=0;G[c+24>>2]=0;G[c+28>>2]=0;G[c+16>>2]=0;G[c+20>>2]=0;G[c+8>>2]=0;G[c+12>>2]=0;G[950329]=b;d=G[945057];break E}b=ab(4);G[945062]=b;if(!b){break A}G[b>>2]=0;G[950329]=1;G[945063]=0}e=ab(48);if(!e){break z}G[e+12>>2]=16384;b=ab(16386);G[e+4>>2]=b;if(!b){break z}G[e+20>>2]=1;$i(e,d);f=G[945062];h=G[945063];G[f+(h<<2)>>2]=e}G[950324]=G[e+16>>2];b=G[e+8>>2];G[945070]=b;G[945064]=b;G[945057]=G[G[(h<<2)+f>>2]>>2];E[3780260]=H[b|0]}n=G[24367];F:while(1){b=G[945064];E[b|0]=H[3780260];c=G[945060];G[945066]=c+4;e=G[945061];G[c>>2]=e;h=b;G:{H:while(1){q=I[(e<<1)+169696>>1];while(1){f=H[H[h|0]+156960|0];d=f;q=d+(q<<16>>16)|0;if(F[(q<<1)+157216>>1]!=(e|0)){while(1){e=F[(e<<1)+171568>>1];d=(e|0)>=900?H[f+173440|0]:d;f=d&255;q=f+F[(e<<1)+169696>>1]|0;if(I[(q<<1)+157216>>1]!=(e&65535)){continue}break}}c=G[945066];d=c+4|0;G[945066]=d;e=F[(q<<1)+173536>>1];G[c>>2]=e;h=h+1|0;q=I[(e<<1)+169696>>1];if((q|0)!=6150){continue}break}c=b;I:while(1){e=d-4|0;G[945066]=e;d=G[e>>2];f=F[(d<<1)+186016>>1];b=G[945067];J:{while(1){if(!f|F[(d<<1)+186018>>1]<=(f|0)){e=e-4|0;G[945066]=e;h=h-1|0;d=G[e>>2];f=F[(d<<1)+186016>>1];continue}else{K:{q=F[(f<<1)+187824>>1];L:{if(q&16384|b){if((b|0)!=(q|0)){break L}G[945067]=0;q=q&49151;break J}if(!(q&8192)){break K}G[945068]=h;G[945069]=e;b=q&-24577|16384;G[945067]=b}f=f+1|0;continue}}break}G[945069]=e;G[945068]=h}G[945070]=c;G[945071]=h-c;E[3780260]=H[h|0];E[h|0]=0;g=G[945071];if(g>>>0<8192){b=g+1|0;t=b&3;d=0;f=G[945070];e=0;if(g>>>0>=3){o=b&-4;b=0;while(1){E[e+3780288|0]=H[e+f|0];g=e|1;E[g+3780288|0]=H[f+g|0];g=e|2;E[g+3780288|0]=H[f+g|0];g=e|3;E[g+3780288|0]=H[f+g|0];e=e+4|0;b=b+4|0;if((o|0)!=(b|0)){continue}break}}if(t){while(1){E[e+3780288|0]=H[e+f|0];e=e+1|0;d=d+1|0;if((t|0)!=(d|0)){continue}break}}e=q<<16>>16;G[945064]=h;while(1){M:{N:{O:{P:{Q:{R:{S:{T:{U:{V:{W:{switch(e-1|0){case 0:if(!H[3780288]){continue F}if(!G[950330]){Lb()}c=Xb(Va(3780288)+1|0);Yb(3780288,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);continue F;case 1:G[i+684>>2]=0;dj(36360);if(Ld(3780288,i+688|0,i+684|0)){pb(G[948160]);b=Lc(i+688|0);G[948160]=b;Rl(b)}cj();continue F;case 2:G[945061]=7;continue F;case 3:G[945061]=7;continue F;case 4:G[945061]=7;continue F;case 5:if(G[945061]-5>>>0<=1){Wd()}Lb();G[945061]=7;continue F;case 6:G[945061]=1;continue F;case 7:G[945061]=1;continue F;case 9:if(G[945061]-5>>>0<=1){Wd()}Lb();G[945061]=9;G[947120]=G[947120]+1;continue F;case 10:G[947120]=G[947120]+1;continue F;case 11:b=G[947120]-1|0;G[947120]=b;if(b){continue F}G[945061]=1;continue F;case 18:case 19:if(G[945061]-5>>>0<=1){Wd();Lb()}G[945061]=5;Fl();continue F;case 20:X:{if(H[3780288]){G[i+20>>2]=3780288;G[i+16>>2]=21453;Tb(n,69475,i+16|0);break X}G[i>>2]=21453;Tb(n,68751,i)}b=G[945062];Y:{if(!b){break Y}c=b+(G[945063]<<2)|0;b=G[c>>2];if(!b){break Y}G[b+16>>2]=0;E[G[b+4>>2]]=0;E[G[b+4>>2]+1|0]=0;G[b+44>>2]=0;G[b+28>>2]=1;d=G[b+4>>2];G[b+8>>2]=d;if((b|0)!=G[c>>2]){break Y}b=G[b+16>>2];G[945064]=d;G[950324]=b;G[945070]=d;G[945057]=G[G[c>>2]>>2];E[3780260]=H[d|0]}E[3801300]=1;continue F;case 21:f=0;G[947121]=G[947121]+1;b=G[948160];if(!(!b|!H[b|0])){if(!Xc(b,25125)){jg(1);continue F}f=!Xc(b,16977)<<1}jg(f);continue F;case 22:G[947121]=G[947121]+1;K=Va(3780288)+3780287|0,N=0,E[K|0]=N;jg(1);continue F;case 23:G[947121]=G[947121]+1;K=Va(3780288)+3780287|0,N=0,E[K|0]=N;jg(2);continue F;case 24:b=G[947122];if(b){b=G[b+3312>>2]}else{b=0}if(!b){Z:{if(H[3780288]){G[i+68>>2]=3780288;G[i+64>>2]=22047;Tb(n,69475,i- -64|0);break Z}G[i+48>>2]=22047;Tb(n,68751,i+48|0)}b=G[945062];_:{if(!b){break _}c=b+(G[945063]<<2)|0;b=G[c>>2];if(!b){break _}G[b+16>>2]=0;E[G[b+4>>2]]=0;E[G[b+4>>2]+1|0]=0;G[b+44>>2]=0;G[b+28>>2]=1;d=G[b+4>>2];G[b+8>>2]=d;if((b|0)!=G[c>>2]){break _}b=G[b+16>>2];G[945064]=d;G[950324]=b;G[945070]=d;G[945057]=G[G[c>>2]>>2];E[3780260]=H[d|0]}E[3801300]=1}b=G[947121]+1|0;G[947121]=b;s=oj(3780288);if((b&-2147483647)==1){L[473562]=s;b=G[321386];if(!b|(b|0)==46|(b|0)==100){continue F}b=G[948160];$:{if(!b){break $}if(!Xa(b,25125)){break $}if(!Xa(b,16977)){break $}if(!Ej(b,16917,3)){continue F}if(!Ej(b,16966,3)){continue F}}L[473562]=s*15;continue F}k=L[473562];b=G[947122];e=G[948160];aa:{ba:{if(!e){break ba}if(!Xa(e,25125)){break ba}if(Xa(e,16977)){break aa}}e=0}pf(b,k,s,e,3788504,3788512,3788520);L[i+32>>3]=L[473563];L[i+40>>3]=L[473564];Ya(3788528,4096,19679,i+32|0);if(!H[3788528]){continue F}if(!G[950330]){Lb()}c=Xb(Va(3788528)+1|0);Yb(3788528,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);continue F;case 25:b=G[947121];g=b+1|0;G[947121]=g;ca:{da:{if((b|0)<2){break da}f=G[948156];switch(f-6|0){case 0:case 7:break da;default:break ca}}b=G[947122];if(b){b=G[b+3312>>2]}else{b=0}if(!b){ea:{if(H[3780288]){G[i+116>>2]=3780288;G[i+112>>2]=22047;Tb(n,69475,i+112|0);break ea}G[i+96>>2]=22047;Tb(n,68751,i+96|0)}b=G[945062];fa:{if(!b){break fa}c=b+(G[945063]<<2)|0;b=G[c>>2];if(!b){break fa}G[b+16>>2]=0;E[G[b+4>>2]]=0;E[G[b+4>>2]+1|0]=0;G[b+44>>2]=0;G[b+28>>2]=1;d=G[b+4>>2];G[b+8>>2]=d;if((b|0)!=G[c>>2]){break fa}b=G[b+16>>2];G[945064]=d;G[950324]=b;G[945070]=d;G[945057]=G[G[c>>2]>>2];E[3780260]=H[d|0]}E[3801300]=1}b=G[947121];s=vb(3780288,0);if((b&-2147483647)==1){L[473562]=s;continue F}k=L[473562];b=G[947122];e=G[948160];ga:{ha:{if(!e){break ha}if(!Xa(e,25125)){break ha}if(Xa(e,16977)){break ga}}e=0}pf(b,k,s,e,3788504,3788512,3788520);L[i+80>>3]=L[473563];L[i+88>>3]=L[473564];Ya(3788528,4096,19679,i+80|0);if(!H[3788528]){continue F}if(!G[950330]){Lb()}c=Xb(Va(3788528)+1|0);Yb(3788528,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);continue F}ia:{b=(f|0)!=7;ja:{if(!b&(g|0)==3|!b&(g|0)==4){break ja}b=(f|0)==8;if(b&(g|0)==3|b&(g|0)==4){break ja}b=(f|0)==9;if(b&(g|0)==3|b&(g|0)==4){break ja}b=(f|0)==10;if(b&(g|0)==3|b&(g|0)==4){break ja}if((f|0)!=11){break ia}}k=vb(3780288,0);L[474079]=k;b=G[948160];ka:{if(!b){break ka}if(!Xa(b,25125)){break ka}if(Xa(b,16977)){k=k+L[474081];L[474079]=k}if(!Xa(b,16977)|!G[G[947122]+3256>>2]){break ka}k=-k;L[474079]=k}L[i+128>>3]=k;Ya(3788528,4096,19682,i+128|0);if(!H[3788528]){continue F}if(!G[950330]){Lb()}c=Xb(Va(3788528)+1|0);Yb(3788528,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);continue F}la:{b=(f|0)==7;ma:{if((f|0)==8&(g|0)==5|(b&(g|0)==5|(g|0)==8&b)){break ma}d=(g|0)==10;if(d&(f|0)==8){break ma}c=(f|0)==9;b=(g|0)==5;if(c&b|c&(g|0)==8){break ma}c=b;b=(f|0)==10;if(c&b){break ma}if(!(b&d)){break la}}k=vb(3780288,0);L[474079]=k;L[i+144>>3]=k;Ya(3788528,4096,19682,i+144|0);if(!H[3788528]){continue F}if(!G[950330]){Lb()}c=Xb(Va(3788528)+1|0);Yb(3788528,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);continue F}b=G[947122];if(b){b=G[b+3312>>2]}else{b=0}na:{if(!(!b|L[474082]==0)){if(L[474083]!=0){break na}}_i(22074)}oa:{switch(G[948156]-2|0){case 0:case 2:k=vb(3780288,0);L[474079]=k;b=G[948160];pa:{if(!b){break pa}if(!Xa(b,25125)){break pa}if(Xa(b,16977)){k=k+L[474081];L[474079]=k}if(!Xa(b,16977)|!G[G[947122]+3256>>2]){break pa}k=-k;L[474079]=k}L[i+176>>3]=k;Ya(3792672,4096,19682,i+176|0);break;default:break oa}}b=G[947121];B=vb(3780288,0);qa:{if((b&-2147483647)==1){y=L[474082];s=vb(3780288,0);k=L[474082];u=-s/k;if(B/y<0){break qa}u=s/k;break qa}y=L[474083];s=vb(3780288,0);k=L[474083];u=-s/k;if(B/y<0){break qa}u=s/k}k=u;L[474079]=k;L[i+160>>3]=k;Ya(3788528,4096,19682,i+160|0);Te(3788528);Tg(L[474079]);continue F;case 26:b=G[947121];g=b+1|0;G[947121]=g;ra:{sa:{if((b|0)<2){break sa}f=G[948156];switch(f-6|0){case 0:case 7:break sa;default:break ra}}b=G[947122];if(b){b=G[b+3312>>2]}else{b=0}if(!b){ta:{if(H[3780288]){G[i+228>>2]=3780288;G[i+224>>2]=22047;Tb(n,69475,i+224|0);break ta}G[i+208>>2]=22047;Tb(n,68751,i+208|0)}b=G[945062];ua:{if(!b){break ua}c=b+(G[945063]<<2)|0;b=G[c>>2];if(!b){break ua}G[b+16>>2]=0;E[G[b+4>>2]]=0;E[G[b+4>>2]+1|0]=0;G[b+44>>2]=0;G[b+28>>2]=1;d=G[b+4>>2];G[b+8>>2]=d;if((b|0)!=G[c>>2]){break ua}b=G[b+16>>2];G[945064]=d;G[950324]=b;G[945070]=d;G[945057]=G[G[c>>2]>>2];E[3780260]=H[d|0]}E[3801300]=1}b=G[947121];s=vb(3780288,0)/.017453292519943295;if((b&-2147483647)==1){L[473562]=s;continue F}k=L[473562];b=G[947122];e=G[948160];va:{wa:{if(!e){break wa}if(!Xa(e,25125)){break wa}if(Xa(e,16977)){break va}}e=0}pf(b,k,s,e,3788504,3788512,3788520);L[i+192>>3]=L[473563];L[i+200>>3]=L[473564];Ya(3788528,4096,19679,i+192|0);if(!H[3788528]){continue F}if(!G[950330]){Lb()}c=Xb(Va(3788528)+1|0);Yb(3788528,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);continue F}xa:{b=(f|0)!=7;ya:{if(!b&(g|0)==3|!b&(g|0)==4){break ya}b=(f|0)==8;if(b&(g|0)==3|b&(g|0)==4){break ya}b=(f|0)==9;if(b&(g|0)==3|b&(g|0)==4){break ya}b=(f|0)==10;if(b&(g|0)==3|b&(g|0)==4){break ya}if((f|0)!=11){break xa}}k=vb(3780288,0)/.017453292519943295;L[474079]=k;b=G[948160];za:{if(!b){break za}if(!Xa(b,25125)){break za}if(Xa(b,16977)){k=k+L[474081];L[474079]=k}if(!Xa(b,16977)|!G[G[947122]+3256>>2]){break za}k=-k;L[474079]=k}L[i+240>>3]=k;Ya(3788528,4096,19682,i+240|0);if(!H[3788528]){continue F}if(!G[950330]){Lb()}c=Xb(Va(3788528)+1|0);Yb(3788528,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);continue F}Aa:{b=(f|0)==7;Ba:{if((f|0)==8&(g|0)==5|(b&(g|0)==5|(g|0)==8&b)){break Ba}d=(g|0)==10;if(d&(f|0)==8){break Ba}c=(f|0)==9;b=(g|0)==5;if(c&b|c&(g|0)==8){break Ba}c=b;b=(f|0)==10;if(c&b){break Ba}if(!(b&d)){break Aa}}k=vb(3780288,0);L[474079]=k;L[i+256>>3]=k;Ya(3788528,4096,19682,i+256|0);if(!H[3788528]){continue F}if(!G[950330]){Lb()}c=Xb(Va(3788528)+1|0);Yb(3788528,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);continue F}b=G[947122];if(b){b=G[b+3312>>2]}else{b=0}Ca:{if(!(!b|L[474082]==0)){if(L[474083]!=0){break Ca}}_i(22074)}Da:{switch(G[948156]-2|0){case 0:case 2:k=vb(3780288,0)/.017453292519943295;L[474079]=k;b=G[948160];Ea:{if(!b){break Ea}if(!Xa(b,25125)){break Ea}if(Xa(b,16977)){k=k+L[474081];L[474079]=k}if(!Xa(b,16977)|!G[G[947122]+3256>>2]){break Ea}k=-k;L[474079]=k}L[i+288>>3]=k;Ya(3792672,4096,19682,i+288|0);break;default:break Da}}b=G[947121];B=vb(3780288,0);Fa:{if((b&-2147483647)==1){y=L[474082];s=vb(3780288,0);k=L[474082];u=-s/k;if(B/y<0){break Fa}u=s/k;break Fa}y=L[474083];s=vb(3780288,0);k=L[474083];u=-s/k;if(B/y<0){break Fa}u=s/k}k=u/.017453292519943295;L[474079]=k;L[i+272>>3]=k;Ya(3788528,4096,19682,i+272|0);Te(3788528);Tg(L[474079]);continue F;case 27:b=G[947122];if(b){b=G[b+3312>>2]}else{b=0}Ga:{if(!(!b|L[474082]==0)){if(L[474083]!=0){break Ga}}Ha:{if(H[3780288]){G[i+340>>2]=3780288;G[i+336>>2]=22074;Tb(n,69475,i+336|0);break Ha}G[i+320>>2]=22074;Tb(n,68751,i+320|0)}b=G[945062];Ia:{if(!b){break Ia}c=b+(G[945063]<<2)|0;b=G[c>>2];if(!b){break Ia}G[b+16>>2]=0;E[G[b+4>>2]]=0;E[G[b+4>>2]+1|0]=0;G[b+44>>2]=0;G[b+28>>2]=1;d=G[b+4>>2];G[b+8>>2]=d;if((b|0)!=G[c>>2]){break Ia}b=G[b+16>>2];G[945064]=d;G[950324]=b;G[945070]=d;G[945057]=G[G[c>>2]>>2];E[3780260]=H[d|0]}E[3801300]=1}b=G[947121]+1|0;G[947121]=b;B=vb(3780288,0);Ja:{if((b&-2147483647)==1){y=L[474082];s=vb(3780288,0);k=L[474082]*60;u=-s/k;if(B/(y*60)<0){break Ja}u=s/k;break Ja}y=L[474083];s=vb(3780288,0);k=L[474083]*60;u=-s/k;if(B/(y*60)<0){break Ja}u=s/k}k=u;L[474079]=k;L[i+304>>3]=k;Ya(3788528,4096,19682,i+304|0);if(H[3788528]){if(!G[950330]){Lb()}c=Xb(Va(3788528)+1|0);Yb(3788528,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c)}Tg(L[474079]);continue F;case 28:b=G[947122];if(b){b=G[b+3312>>2]}else{b=0}Ka:{if(!(!b|L[474082]==0)){if(L[474083]!=0){break Ka}}La:{if(H[3780288]){G[i+388>>2]=3780288;G[i+384>>2]=22074;Tb(n,69475,i+384|0);break La}G[i+368>>2]=22074;Tb(n,68751,i+368|0)}b=G[945062];Ma:{if(!b){break Ma}c=b+(G[945063]<<2)|0;b=G[c>>2];if(!b){break Ma}G[b+16>>2]=0;E[G[b+4>>2]]=0;E[G[b+4>>2]+1|0]=0;G[b+44>>2]=0;G[b+28>>2]=1;d=G[b+4>>2];G[b+8>>2]=d;if((b|0)!=G[c>>2]){break Ma}b=G[b+16>>2];G[945064]=d;G[950324]=b;G[945070]=d;G[945057]=G[G[c>>2]>>2];E[3780260]=H[d|0]}E[3801300]=1}b=G[947121]+1|0;G[947121]=b;B=vb(3780288,0);Na:{if((b&-2147483647)==1){y=L[474082];s=vb(3780288,0);k=L[474082]*3600;u=-s/k;if(B/(y*3600)<0){break Na}u=s/k;break Na}y=L[474083];s=vb(3780288,0);k=L[474083]*3600;u=-s/k;if(B/(y*3600)<0){break Na}u=s/k}k=u;L[474079]=k;L[i+352>>3]=k;Ya(3788528,4096,19682,i+352|0);if(H[3788528]){if(!G[950330]){Lb()}c=Xb(Va(3788528)+1|0);Yb(3788528,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c)}Tg(L[474079]);continue F;case 29:f=nc(jb(3780288,61)+1|0,0,10);if((f|0)<=0){Oa:{if(H[3780288]){G[i+420>>2]=3780288;G[i+416>>2]=10555;Tb(n,69475,i+416|0);break Oa}G[i+400>>2]=10555;Tb(n,68751,i+400|0)}b=G[945062];Pa:{if(!b){break Pa}c=b+(G[945063]<<2)|0;b=G[c>>2];if(!b){break Pa}G[b+16>>2]=0;E[G[b+4>>2]]=0;E[G[b+4>>2]+1|0]=0;G[b+44>>2]=0;G[b+28>>2]=1;d=G[b+4>>2];G[b+8>>2]=d;if((b|0)!=G[c>>2]){break Pa}b=G[b+16>>2];G[945064]=d;G[950324]=b;G[945070]=d;G[945057]=G[G[c>>2]>>2];E[3780260]=H[d|0]}E[3801300]=1;continue F}Qa:{Ra:{switch(G[948156]-1|0){case 1:G[947121]=G[947121]-2;break Qa;case 2:G[947121]=G[947121]-1;break Qa;case 3:G[947121]=G[947121]-2;break Qa;case 0:case 10:break Qa;default:break Ra}}Sa:{if(H[3780288]){G[i+580>>2]=3780288;G[i+576>>2]=67700;Tb(n,69475,i+576|0);break Sa}G[i+560>>2]=67700;Tb(n,68751,i+560|0)}b=G[945062];Ta:{if(!b){break Ta}c=b+(G[945063]<<2)|0;b=G[c>>2];if(!b){break Ta}G[b+16>>2]=0;E[G[b+4>>2]]=0;E[G[b+4>>2]+1|0]=0;G[b+44>>2]=0;G[b+28>>2]=1;d=G[b+4>>2];G[b+8>>2]=d;if((b|0)!=G[c>>2]){break Ta}b=G[b+16>>2];G[945064]=d;G[950324]=b;G[945070]=d;G[945057]=G[G[c>>2]>>2];E[3780260]=H[d|0]}E[3801300]=1}G[i+544>>2]=f;Ya(i+688|0,4096,30101,i+544|0);if(H[i+688|0]){if(!G[950330]){Lb()}b=i+688|0;c=Xb(Va(b)+1|0);Yb(b,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c)}c=G[(G[950332]+(G[950330]<<2)|0)-4>>2];b=G[c+28>>2];if(b){d=Lc(b+G[c+24>>2]|0);if(d){c=G[950330];b=G[(G[950332]+(c<<2)|0)-4>>2];E[G[b+24>>2]+G[b+28>>2]|0]=0;if(!c){Lb()}c=Xb(2);Yb(16232,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);if(H[d|0]){if(!G[950330]){Lb()}c=Xb(Va(d)+1|0);Yb(d,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c)}G[i+528>>2]=f;c=i+688|0;Ya(c,4096,66542,i+528|0);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+32|0,b+36|0);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+40|0,b+44|0);E[3805456]=1;Wa(d)}b=G[G[(G[950332]+(G[950330]<<2)|0)-4>>2]+52>>2];if(b){pb(b);b=(G[950332]+(G[950330]<<2)|0)-4|0;G[G[b>>2]+52>>2]=0;G[G[b>>2]+56>>2]=0}Ua:{Va:{b=G[948156];if(b-1>>>0>=4){if((b|0)!=11){break Va}s=(L[475681]-L[475680])/+(f|0);e=1;while(1){k=L[475680];L[i+520>>3]=+(e|0)*s+k;L[i+512>>3]=k+ +(e-1|0)*s;c=i+688|0;Ya(c,4096,19679,i+512|0);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(35975,b+52|0,b+56|0);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+52|0,b+56|0);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(92037,b+52|0,b+56|0);b=(e|0)==(f|0);e=e+1|0;if(!b){continue}break}break Ua}s=(L[475681]-L[475680])/+(f|0);e=1;while(1){k=L[475680];L[i+504>>3]=+(e|0)*s+k;L[i+496>>3]=k+ +(e-1|0)*s;b=i+688|0;Ya(b,4096,19679,i+496|0);c=b;b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+52|0,b+56|0);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(35974,b+52|0,b+56|0);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(92037,b+52|0,b+56|0);b=(e|0)==(f|0);e=e+1|0;if(!b){continue}break}break Ua}Wa:{if(H[3780288]){G[i+484>>2]=3780288;G[i+480>>2]=67700;Tb(n,69475,i+480|0);break Wa}G[i+464>>2]=67700;Tb(n,68751,i+464|0)}b=G[945062];Xa:{if(!b){break Xa}c=b+(G[945063]<<2)|0;b=G[c>>2];if(!b){break Xa}G[b+16>>2]=0;E[G[b+4>>2]]=0;E[G[b+4>>2]+1|0]=0;G[b+44>>2]=0;G[b+28>>2]=1;d=G[b+4>>2];G[b+8>>2]=d;if((b|0)!=G[c>>2]){break Xa}b=G[b+16>>2];G[945064]=d;G[950324]=b;G[945070]=d;G[945057]=G[G[c>>2]>>2];E[3780260]=H[d|0]}E[3801300]=1}e=G[950330];if(!e){Lb();e=G[950330]}b=G[(G[950332]+(e<<2)|0)-4>>2];G[b+4>>2]=G[b+4>>2]|32;continue F}Ya:{if(H[3780288]){G[i+452>>2]=3780288;G[i+448>>2]=10582;Tb(n,69475,i+448|0);break Ya}G[i+432>>2]=10582;Tb(n,68751,i+432|0)}b=G[945062];Za:{if(!b){break Za}c=b+(G[945063]<<2)|0;b=G[c>>2];if(!b){break Za}G[b+16>>2]=0;E[G[b+4>>2]]=0;E[G[b+4>>2]+1|0]=0;G[b+44>>2]=0;G[b+28>>2]=1;d=G[b+4>>2];G[b+8>>2]=d;if((b|0)!=G[c>>2]){break Za}b=G[b+16>>2];G[945064]=d;G[950324]=b;G[945070]=d;G[945057]=G[G[c>>2]>>2];E[3780260]=H[d|0]}E[3801300]=1;continue F;case 30:e=0;b=G[947121];if(!El(b)){Wd();Lb();G[945061]=1;E[h|0]=H[3780260];G[945070]=c;G[945064]=c;G[945071]=0;E[3780260]=H[c|0];E[c|0]=0;d=G[945071];if(d>>>0>=8192){break B}b=d+1|0;f=b&3;g=G[945070];if(d>>>0>=3){d=b&-4;h=0;while(1){E[e+3780288|0]=H[e+g|0];b=e|1;E[b+3780288|0]=H[b+g|0];b=e|2;E[b+3780288|0]=H[b+g|0];b=e|3;E[b+3780288|0]=H[b+g|0];e=e+4|0;h=h+4|0;if((d|0)!=(h|0)){continue}break}}h=0;if(f){while(1){E[e+3780288|0]=H[e+g|0];e=e+1|0;h=h+1|0;if((f|0)!=(h|0)){continue}break}}G[945064]=c;continue F}G[947121]=b+1;b=G[948160];if(!(!b|!H[b|0])){if(!Xc(b,25125)){jg(1);continue F}e=!Xc(b,16977)<<1}jg(e);continue F;case 31:Wd();Lb();e=0;G[945061]=1;E[h|0]=H[3780260];G[945070]=c;G[945064]=c;G[945071]=0;E[3780260]=H[c|0];E[c|0]=0;d=G[945071];if(d>>>0>=8192){break B}b=d+1|0;f=b&3;g=G[945070];if(d>>>0>=3){d=b&-4;h=0;while(1){E[e+3780288|0]=H[e+g|0];b=e|1;E[b+3780288|0]=H[b+g|0];b=e|2;E[b+3780288|0]=H[b+g|0];b=e|3;E[b+3780288|0]=H[b+g|0];e=e+4|0;h=h+4|0;if((d|0)!=(h|0)){continue}break}}h=0;if(f){while(1){E[e+3780288|0]=H[e+g|0];e=e+1|0;h=h+1|0;if((f|0)!=(h|0)){continue}break}}G[945064]=c;continue F;case 33:c=G[(G[950332]+(G[950330]<<2)|0)-4>>2];b=jb(3780288,123);K=c,N=_b(b?b+1|0:3780288),G[K+48>>2]=N;if(G[950216]){continue F}Wd();G[945061]=1;continue F;case 34:G[950216]=G[950216]+1;continue F;case 35:c=G[(G[950332]+(G[950330]<<2)|0)-4>>2];b=jb(3780289,123);K=c,N=_b(b?b+1|0:3780289),G[K+48>>2]=N;b=G[950216];if(b){b=b-1|0;G[950216]=b;if(b){continue F}Wd();G[945061]=1;continue F}Wd();G[945061]=1;G[950217]=G[950217]-1;Lb();if(!G[950330]){Lb()}c=Xb(2);Yb(64244,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);Lb();continue F;case 36:b=G[950216];if(b){b=b-1|0;G[950216]=b;if(b){continue F}Wd();G[945061]=1;continue F}Wd();G[945061]=1;G[950217]=G[950217]-1;Lb();if(!G[950330]){Lb()}c=Xb(2);Yb(64244,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);Lb();continue F;case 37:Wd();Dl();G[945061]=1;continue F;case 38:Wd();Lb();G[945061]=1;continue F;case 39:e=0;E[h|0]=H[3780260];G[945070]=c;f=h-1|0;G[945064]=f;G[945071]=f-c;E[3780260]=H[f|0];E[f|0]=0;c=G[945071];if(c>>>0>=8192){break B}b=c+1|0;d=b&3;g=G[945070];if(c>>>0>=3){c=b&-4;h=0;while(1){E[e+3780288|0]=H[e+g|0];b=e|1;E[b+3780288|0]=H[b+g|0];b=e|2;E[b+3780288|0]=H[b+g|0];b=e|3;E[b+3780288|0]=H[b+g|0];e=e+4|0;h=h+4|0;if((c|0)!=(h|0)){continue}break}}h=0;if(d){while(1){E[e+3780288|0]=H[e+g|0];e=e+1|0;h=h+1|0;if((d|0)!=(h|0)){continue}break}}G[945064]=f;b=G[945061];G[945061]=3;G[950218]=(b-1|0)/2;G[947121]=0;G[950219]=0;e=G[950330];if(!e){Lb();e=G[950330]}b=G[(G[950332]+(e<<2)|0)-4>>2];G[b+4>>2]=G[b+4>>2]|8;c=G[950220];if(c){b=G[c+144>>2];if(b){b=Ja[b|0](c,3780288)|0}else{b=3780288}}else{b=0}Te(b);G[950221]=G[950221]+1;continue F;case 40:if(!G[950330]){Lb()}c=Xb(2);Yb(49008,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);continue F;case 41:G[950219]=G[950219]+1;if(!G[950330]){Lb()}c=Xb(2);Yb(64753,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);continue F;case 42:b=G[950219]-1|0;G[950219]=b;if(b){if(!G[950330]){Lb()}c=Xb(2);Yb(64244,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);continue F}G[945061]=G[950218]<<1|1;c=G[950220];if(c){b=G[c+148>>2];if(b){b=Ja[b|0](c,64244)|0}else{b=64244}}else{b=0}Te(b);continue F;case 43:if(G[945061]-5>>>0<=1){Wd();Lb()}if(G[950222]>=100){_a:{if(H[3780288]){G[i+676>>2]=3780288;G[i+672>>2]=3405;Tb(n,69475,i+672|0);break _a}G[i+656>>2]=3405;Tb(n,68751,i+656|0)}b=G[945062];$a:{if(!b){break $a}c=b+(G[945063]<<2)|0;b=G[c>>2];if(!b){break $a}G[b+16>>2]=0;E[G[b+4>>2]]=0;E[G[b+4>>2]+1|0]=0;G[b+44>>2]=0;G[b+28>>2]=1;d=G[b+4>>2];G[b+8>>2]=d;if((b|0)!=G[c>>2]){break $a}b=G[b+16>>2];G[945064]=d;G[950324]=b;G[945070]=d;G[945057]=G[G[c>>2]>>2];E[3780260]=H[d|0]}E[3801300]=1}g=Ol(3780289);if(!g){ab:{if(H[3780288]){G[i+644>>2]=3780288;G[i+640>>2]=23075;Tb(n,69475,i+640|0);break ab}G[i+624>>2]=23075;Tb(n,68751,i+624|0)}b=G[945062];bb:{if(!b){break bb}c=b+(G[945063]<<2)|0;b=G[c>>2];if(!b){break bb}G[b+16>>2]=0;E[G[b+4>>2]]=0;E[G[b+4>>2]+1|0]=0;G[b+44>>2]=0;G[b+28>>2]=1;d=G[b+4>>2];G[b+8>>2]=d;if((b|0)!=G[c>>2]){break bb}b=G[b+16>>2];G[945064]=d;G[950324]=b;G[945070]=d;G[945057]=G[G[c>>2]>>2];E[3780260]=H[d|0]}E[3801300]=1;break G}if(!H[g|0]){break G}f=0;b=G[945062];if(b){f=G[b+(G[945063]<<2)>>2]}b=G[950222];G[950222]=b+1;G[(b<<2)+3800896>>2]=f;Lb();if(!G[950330]){Lb()}c=Xb(2);Yb(64753,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);Cl(g);pb(g);continue F;case 45:G[947121]=G[947121]+1;if(!H[3780288]){continue F}if(!G[950330]){Lb()}c=Xb(Va(3780288)+1|0);Yb(3780288,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);continue F;case 46:Bl(i+688|0,4095);G[947121]=G[947121]+1;if(!H[i+688|0]){continue F}if(!G[950330]){Lb()}b=i+688|0;c=Xb(Va(b)+1|0);Yb(b,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);continue F;case 47:Dl();if(G[945061]-3>>>0<2){continue F}G[945061]=1;continue F;case 48:G[950217]=G[950217]+1;Lb();if(H[3780288]){if(!G[950330]){Lb()}c=Xb(Va(3780288)+1|0);Yb(3780288,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c)}Lb();continue F;case 49:G[950217]=G[950217]-1;Lb();if(H[3780288]){if(!G[950330]){Lb()}c=Xb(Va(3780288)+1|0);Yb(3780288,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c)}Lb();continue F;case 50:Lb();G[945061]=1;continue F;case 51:if(!H[3780288]){continue F}if(!G[950330]){Lb()}c=Xb(Va(3780288)+1|0);Yb(3780288,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);continue F;case 54:case 55:case 56:case 57:case 58:b=G[950222];G[950222]=b-1;if((b|0)<=0){b=G[945062];cb:{if(!b){break cb}b=b+(G[945063]<<2)|0;c=G[b>>2];if(!c){break cb}G[b>>2]=0;if(G[c+20>>2]){Wa(G[c+4>>2])}Wa(c)}Fa=i+4784|0;break y}if(!G[950330]){Lb()}c=Xb(2);Yb(64244,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c,b+24|0,b+12|0);pb(c);Lb();b=G[945062];db:{if(!b){break db}b=b+(G[945063]<<2)|0;c=G[b>>2];if(!c){break db}G[b>>2]=0;if(G[c+20>>2]){Wa(G[c+4>>2])}Wa(c)}Al(G[(G[950222]<<2)+3800896>>2]);continue F;case 52:hb(3780288,G[945071],1,G[945058]);continue F;case 53:E[h|0]=H[3780260];z=G[945062];A=G[945063];t=z+(A<<2)|0;d=G[t>>2];eb:{if(G[d+44>>2]){q=G[950324];break eb}q=G[d+16>>2];G[950324]=q;G[d>>2]=G[945057];d=G[t>>2];G[d+44>>2]=1}D=G[945064];e=G[d+4>>2];b=q+e|0;if(D>>>0<=b>>>0){g=G[945060];b=g+4|0;G[945066]=b;c=G[945070];d=(f^-1)+h|0;h=c+d|0;G[945064]=h;e=G[945061];G[g>>2]=e;g=c;if((d|0)>0){while(1){f=1;d=H[g|0];if(d){f=H[d+156960|0]}d=f&255;q=d+F[(e<<1)+169696>>1]|0;if(F[(q<<1)+157216>>1]!=(e|0)){while(1){e=F[(e<<1)+171568>>1];f=(e|0)>=900?H[d+173440|0]:f;d=f&255;q=d+F[(e<<1)+169696>>1]|0;if(I[(q<<1)+157216>>1]!=(e&65535)){continue}break}}e=F[(q<<1)+173536>>1];G[b>>2]=e;b=b+4|0;g=g+1|0;if((h|0)!=(g|0)){continue}break}G[945066]=b}f=F[(e<<1)+169696>>1]+1|0;if(F[(f<<1)+157216>>1]!=(e|0)){while(1){d=I[(e<<1)+171568>>1];e=d<<16>>16;f=F[(e<<1)+169696>>1]+1|0;if(I[(f<<1)+157216>>1]!=(d|0)){continue}break}}d=I[(f<<1)+173536>>1];if((d|0)==899){break O}G[945066]=b+4;e=d<<16>>16;G[b>>2]=e;if(!d){break O}h=h+1|0;G[945064]=h;b=c;continue H}if(D>>>0>b+1>>>0){break V}b=G[945070];if(!G[d+40>>2]){if((D-b|0)!=1){break P}break M}x=D+(b^-1)|0;if((x|0)>0){o=x&7;fb:{if((D-b|0)-2>>>0<7){d=b;break fb}g=x&-8;q=0;d=b;while(1){E[e|0]=H[d|0];E[e+1|0]=H[d+1|0];E[e+2|0]=H[d+2|0];E[e+3|0]=H[d+3|0];E[e+4|0]=H[d+4|0];E[e+5|0]=H[d+5|0];E[e+6|0]=H[d+6|0];E[e+7|0]=H[d+7|0];e=e+8|0;d=d+8|0;q=q+8|0;if((g|0)!=(q|0)){continue}break}}q=0;if(o){while(1){E[e|0]=H[d|0];e=e+1|0;d=d+1|0;q=q+1|0;if((o|0)!=(q|0)){continue}break}}d=G[t>>2]}if(G[d+44>>2]==2){G[950324]=0;break S}b=G[d+12>>2]+(b-D|0)|0;if(!b){break U}b=b>>>0<8192?b:8192;e=0;gb:{hb:{if(G[d+24>>2]){ib:{while(1){jb:{g=en(G[945057]);d=g+1|0;switch(d|0){case 0:case 11:break ib;default:break jb}}E[(x+G[G[G[945062]+(G[945063]<<2)>>2]+4>>2]|0)+e|0]=g;e=e+1|0;if((b|0)!=(e|0)){continue}break}e=b}kb:{switch(d|0){case 11:break hb;case 0:break kb;default:break gb}}b=G[945057];lb:{if(G[b+76>>2]<0){b=G[b>>2];break lb}b=G[b>>2]}if(!(b>>>5&1)){break gb}qd(29320);W()}g=0;G[48624]=0;e=zc(x+G[d+4>>2]|0,1,b,G[945057]);G[950324]=e;if(!e){while(1){e=G[945057];mb:{if(G[e+76>>2]<0){d=G[e>>2];break mb}d=G[e>>2]}if(!(d>>>5&1)){z=G[945062];A=G[945063];d=G[z+(A<<2)>>2];break S}if(G[48624]!=27){break T}G[48624]=0;G[e>>2]=G[e>>2]&-49;e=zc(x+G[G[G[945062]+(G[945063]<<2)>>2]+4>>2]|0,1,b,G[945057]);G[950324]=e;if(!e){continue}break}}z=G[945062];A=G[945063];d=G[z+(A<<2)>>2];G[d+16>>2]=e;break Q}E[(x+G[G[G[945062]+(G[945063]<<2)>>2]+4>>2]|0)+e|0]=10;e=e+1|0}g=0;G[950324]=e;z=G[945062];A=G[945063];d=G[z+(A<<2)>>2];G[d+16>>2]=e;if(e){break Q}break R;case 8:case 12:case 13:case 14:case 15:case 16:case 17:case 32:case 44:continue F;default:break W}}qd(26483);W()}qd(29150);W()}qd(33408);W()}qd(29320);W()}G[d+16>>2]=0}if(!x){e=G[945057];o=G[945062];nb:{ob:{if(o){d=G[945063];b=G[o+(d<<2)>>2];if(b){break nb}g=G[950329];if(d>>>0>>0){break ob}b=g+8|0;d=ub(o,b<<2);G[945062]=d;if(!d){break A}d=d+(g<<2)|0;G[d>>2]=0;G[d+4>>2]=0;G[d+24>>2]=0;G[d+28>>2]=0;G[d+16>>2]=0;G[d+20>>2]=0;G[d+8>>2]=0;G[d+12>>2]=0;G[950329]=b;break ob}b=ab(4);G[945062]=b;if(!b){break A}G[b>>2]=0;G[950329]=1;G[945063]=0}g=G[945057];b=ab(48);if(!b){break z}G[b+12>>2]=16384;d=ab(16386);G[b+4>>2]=d;if(!d){break z}G[b+20>>2]=1;$i(b,g);G[G[945062]+(G[945063]<<2)>>2]=b}$i(b,e);d=G[945062]+(G[945063]<<2)|0;b=G[d>>2];G[950324]=G[b+16>>2];b=G[b+8>>2];G[945064]=b;G[945070]=b;G[945057]=G[G[d>>2]>>2];E[3780260]=H[b|0];z=G[945062];A=G[945063];d=G[z+(A<<2)>>2];e=G[950324];g=1;break Q}g=2;G[d+44>>2]=2;e=0}t=(A<<2)+z|0;o=e+x|0;pb:{if(o>>>0<=J[d+12>>2]){e=G[d+4>>2];break pb}b=G[d+4>>2];d=o+(e>>>1|0)|0;b=ub(b,d);G[G[t>>2]+4>>2]=b;b=G[t>>2];e=G[b+4>>2];if(!e){break N}G[b+12>>2]=d-2}G[950324]=o;E[e+o|0]=0;E[(o+G[G[t>>2]+4>>2]|0)+1|0]=0;b=G[G[t>>2]+4>>2];G[945070]=b;if((g|0)==1){break M}qb:{switch(g|0){case 0:c=G[945060];g=c+4|0;G[945066]=g;d=(f^-1)+h|0;h=d+b|0;G[945064]=h;e=G[945061];G[c>>2]=e;c=b;if((d|0)<=0){continue H}while(1){f=1;d=H[c|0];if(d){f=H[d+156960|0]}d=f&255;q=d+F[(e<<1)+169696>>1]|0;if(F[(q<<1)+157216>>1]!=(e|0)){while(1){e=F[(e<<1)+171568>>1];f=(e|0)>=900?H[d+173440|0]:f;d=f&255;q=d+F[(e<<1)+169696>>1]|0;if(I[(q<<1)+157216>>1]!=(e&65535)){continue}break}}e=F[(q<<1)+173536>>1];G[g>>2]=e;g=g+4|0;c=c+1|0;if((h|0)!=(c|0)){continue}break};G[945066]=g;continue H;case 2:break qb;default:continue F}}e=G[G[G[945062]+(G[945063]<<2)>>2]+4>>2];q=G[950324]}h=e+q|0;G[945064]=h;c=G[945060];g=c+4|0;G[945066]=g;e=G[945061];G[c>>2]=e;if(b>>>0>=h>>>0){c=b;break O}c=b;while(1){f=1;d=H[c|0];if(d){f=H[d+156960|0]}d=f&255;q=d+F[(e<<1)+169696>>1]|0;if(F[(q<<1)+157216>>1]!=(e|0)){while(1){e=F[(e<<1)+171568>>1];f=(e|0)>=900?H[d+173440|0]:f;d=f&255;q=d+F[(e<<1)+169696>>1]|0;if(I[(q<<1)+157216>>1]!=(e&65535)){continue}break}}e=F[(q<<1)+173536>>1];G[g>>2]=e;g=g+4|0;c=c+1|0;if((h|0)!=(c|0)){continue}break}G[945066]=g;c=b}d=G[945066];continue I}qd(63819);W()}G[945064]=b;e=((G[945061]-1|0)/2|0)+55|0;f=b;continue}}break}break}break B}pb(g);rb:{if(H[3780288]){G[i+612>>2]=3780288;G[i+608>>2]=2809;Tb(n,69475,i+608|0);break rb}G[i+592>>2]=2809;Tb(n,68751,i+592|0)}b=G[945062];sb:{if(!b){break sb}c=b+(G[945063]<<2)|0;b=G[c>>2];if(!b){break sb}G[b+16>>2]=0;E[G[b+4>>2]]=0;E[G[b+4>>2]+1|0]=0;G[b+44>>2]=0;G[b+28>>2]=1;d=G[b+4>>2];G[b+8>>2]=d;if((b|0)!=G[c>>2]){break sb}b=G[b+16>>2];G[945064]=d;G[950324]=b;G[945070]=d;G[945057]=G[G[c>>2]>>2];E[3780260]=H[d|0]}E[3801300]=1;continue}}qd(63671);W()}qd(33004);W()}qd(64041);W()}qd(63953);W()}c=-1;if(!H[3801300]){d=G[950330];if(!(!G[G[950220]+12>>2]|(d|0)<=0)){f=G[24367];c=0;while(1){b=G[G[950332]+(c<<2)>>2];d=G[b>>2];b=G[b+24>>2];tb:{if(b){G[r+212>>2]=b;G[r+208>>2]=d;_a(f,69251,r+208|0);break tb}G[r+196>>2]=d;G[r+192>>2]=c;_a(f,68424,r+192|0)}d=G[950330];c=c+1|0;if((d|0)>(c|0)){continue}break}}ub:{vb:{wb:{if((d|0)<=0){f=0;G[950328]=0;G[951383]=0;break wb}e=G[950332];o=G[24367];f=0;b=0;c=0;while(1){g=c<<2;h=G[g+e>>2];if(!(!h|!G[h+24>>2])){f=G[h+4>>2];if((f&6)==2){xb:{if(H[3780288]){G[r+180>>2]=3780288;G[r+176>>2]=53772;Tb(o,69475,r+176|0);break xb}G[r+160>>2]=53772;Tb(o,68751,r+160|0)}d=G[945062];yb:{if(!d){break yb}h=d+(G[945063]<<2)|0;d=G[h>>2];if(!d){break yb}G[d+16>>2]=0;E[G[d+4>>2]]=0;E[G[d+4>>2]+1|0]=0;G[d+44>>2]=0;G[d+28>>2]=1;e=G[d+4>>2];G[d+8>>2]=e;if((d|0)!=G[h>>2]){break yb}d=G[d+16>>2];G[945064]=e;G[950324]=d;G[945070]=e;G[945057]=G[G[h>>2]>>2];E[3780260]=H[e|0]}E[3801300]=1}if((f&5)==5){zb:{if(H[3780288]){G[r+148>>2]=3780288;G[r+144>>2]=62372;Tb(o,69475,r+144|0);break zb}G[r+128>>2]=62372;Tb(o,68751,r+128|0)}d=G[945062];Ab:{if(!d){break Ab}h=d+(G[945063]<<2)|0;d=G[h>>2];if(!d){break Ab}G[d+16>>2]=0;E[G[d+4>>2]]=0;E[G[d+4>>2]+1|0]=0;G[d+44>>2]=0;G[d+28>>2]=1;e=G[d+4>>2];G[d+8>>2]=e;if((d|0)!=G[h>>2]){break Ab}d=G[d+16>>2];G[945064]=e;G[950324]=d;G[945070]=e;G[945057]=G[G[h>>2]>>2];E[3780260]=H[e|0]}E[3801300]=1}if((f&9)==9){Bb:{if(H[3780288]){G[r+116>>2]=3780288;G[r+112>>2]=62307;Tb(o,69475,r+112|0);break Bb}G[r+96>>2]=62307;Tb(o,68751,r+96|0)}d=G[945062];Cb:{if(!d){break Cb}h=d+(G[945063]<<2)|0;d=G[h>>2];if(!d){break Cb}G[d+16>>2]=0;E[G[d+4>>2]]=0;E[G[d+4>>2]+1|0]=0;G[d+44>>2]=0;G[d+28>>2]=1;e=G[d+4>>2];G[d+8>>2]=e;if((d|0)!=G[h>>2]){break Cb}d=G[d+16>>2];G[945064]=e;G[950324]=d;G[945070]=e;G[945057]=G[G[h>>2]>>2];E[3780260]=H[e|0]}E[3801300]=1}e=G[950332];d=G[G[g+e>>2]+4>>2];v=(d&1)+v|0;b=(d>>>1&1)+b|0;m=(d>>>2&1)+m|0;d=G[950330]}c=c+1|0;if((c|0)<(d|0)){continue}break}if(!(!v|(b|m))){F[1890146]=H[26857]|H[26858]<<8;G[945072]=H[26853]|H[26854]<<8|(H[26855]<<16|H[26856]<<24);Fl();Wd();d=G[950330]}G[950328]=0;G[951383]=0;if((d|0)>0){break vb}}m=G[950332];break ub}m=G[950332];c=0;while(1){h=c<<2;g=G[h+m>>2];Db:{if(!g){break Db}b=G[g+24>>2];if(!b){break Db}if(Zi(c,0)){E[3805528]=0}E[3805536]=0;b=Jh(b,152,g);pb(G[G[h+G[950332]>>2]+24>>2]);m=G[950332];G[G[h+m>>2]+24>>2]=b;d=G[950330]}c=c+1|0;if((c|0)<(d|0)){continue}break}}oe(m,d,4,153);b=0;if(!(!G[G[950220]+12>>2]|G[950330]<=0)){g=G[24367];c=0;while(1){d=G[G[950332]+(c<<2)>>2];m=G[d>>2];d=G[d+24>>2];Eb:{if(d){G[r+84>>2]=d;G[r+80>>2]=m;_a(g,69253,r+80|0);break Eb}G[r+68>>2]=m;G[r+64>>2]=c;_a(g,68426,r- -64|0)}c=c+1|0;if((c|0)0){c=0;while(1){Gb:{Hb:{Ib:{d=G[G[950332]+(c<<2)>>2];if(!d){break Ib}while(1){h=G[d+24>>2];if(!h){break Ib}g=G[d+4>>2];if(!g){Bb(h,3801304,3805520);d=G[950326];m=Va(d)+d|0;d=m-2|0;if(!(H[d|0]!=40|H[m-1|0]!=41)){E[d|0]=0}c=c+1|0;m=G[950330];if((c|0)>=(m|0)){break Gb}d=G[G[950332]+(c<<2)>>2];if(!d){break Ib}continue}break}if(Zi(c,0)){E[3805528]=0}E[3805536]=1;o=Jh(h,152,d);Jb:{if(Zi(c,o)){m=0;f=Va(G[950326]);d=f-1|0;Kb:{if((d|0)<0){break Kb}while(1){h=G[950326]+d|0;if(H[h|0]!=40){break Kb}E[h|0]=0;d=d-1|0;m=m+1|0;if((f|0)!=(m|0)){continue}break}m=f}d=b&4;h=g&4;Lb:{if(!(!d|!h)){Bb(1782,3801304,3805520);break Lb}f=g&1;if(!(!d|!f)){if((e|0)>0){Bb(64244,3801304,3805520);e=e-1|0}Mb:{if(!G[G[950220]+8>>2]){d=65326;break Mb}d=1782;if((e|0)<=0){break Mb}Bb(64244,3801304,3805520);e=e-1|0}Bb(d,3801304,3805520);Bb(64753,3801304,3805520);e=e+1|0;break Lb}b=b&1;if(!(!h|(b&f|!b))){if(!(!G[G[950220]+8>>2]|(e|0)<=0)){Bb(64244,3801304,3805520);e=e-1|0}Bb(65326,3801304,3805520);Bb(64753,3801304,3805520);if(!G[G[950220]+8>>2]){e=e+1|0;break Lb}Bb(64753,3801304,3805520);e=e+2|0;break Lb}Bb(65326,3801304,3805520)}b=0;if(!m){break Jb}while(1){t=G[950326];d=0;Nb:{if(!t){break Nb}d=0;if(!H[t|0]){break Nb}d=Va(t)}f=G[951380];if((f|0)<=(d+2|0)){i=f^-1;h=d+3|0;f=f+1024|0;f=(i+((f|0)<(h|0)?h:f)&-1024)+f|0;G[951380]=f}Ob:{if(!d){d=Ic(f,1);break Ob}d=lf(t,f)}G[950326]=d;d=Va(d)+d|0;E[d|0]=40;E[d+1|0]=0;b=b+1|0;if((m|0)!=(b|0)){continue}break}break Jb}if(c|!G[G[950220]+8>>2]){break Jb}Bb(64752,3801304,3805520);e=e+2|0}Bb(o,3801304,3805520);pb(o);b=G[G[G[950332]+(c<<2)>>2]+52>>2];if(b){b=b+(H[b|0]==44)|0}else{b=85390}Bb(b,3801308,3805524);b=c+1|0;m=G[950330];Pb:{if((b|0)>=(m|0)){break Pb}f=G[950332];v=G[f+(b<<2)>>2];if((g|0)!=G[v+4>>2]){break Pb}o=g&4?1782:65326;while(1){d=b;h=(c|0)<0;Qb:{if(h){break Qb}while(1){Rb:{c=d;d=c-1|0;m=G[(d<<2)+f>>2];Sb:{if(!m){break Sb}m=G[m+24>>2];if(!m){break Sb}if(!Xa(m,64753)){break Sb}if(Xa(m,64244)){break Rb}}if(c>>>0>1){continue}break Qb}break}d=E[(Va(m)+m|0)-1|0];c=d-33|0;if((1<>>0<=29:0)|(d|0)==124){break Qb}E[3805528]=0}t=Jh(G[v+24>>2],152,v);Tb:{Ub:{Vb:{if(!t){break Vb}d=E[t|0];if(!d){break Vb}c=d-33|0;if((d|0)==124|(1<>>0<=29:0)){break Ub}}Wb:{if(h){break Wb}m=G[950332];c=b;while(1){Xb:{d=c;c=c-1|0;f=G[m+(c<<2)>>2];Yb:{if(!f){break Yb}f=G[f+24>>2];if(!f){break Yb}if(!Xa(f,64753)){break Yb}if(Xa(f,64244)){break Xb}}if(d>>>0>1){continue}break Wb}break}d=E[(Va(f)+f|0)-1|0];c=d-33|0;if((1<>>0<=29:0)|(d|0)==124){break Wb}f=0;d=Va(G[950326]);c=d-1|0;if((c|0)<0){Bb(o,3801304,3805520);break Wb}Zb:{while(1){m=G[950326]+c|0;if(H[m|0]!=40){break Zb}E[m|0]=0;c=c-1|0;f=f+1|0;if((d|0)!=(f|0)){continue}break}f=d}Bb(o,3801304,3805520);v=0;if(!f){break Wb}while(1){h=G[950326];c=0;_b:{if(!h){break _b}c=0;if(!H[h|0]){break _b}c=Va(h)}d=G[951380];if((d|0)<=(c+2|0)){i=d^-1;m=c+3|0;d=d+1024|0;d=(i+((d|0)<(m|0)?m:d)&-1024)+d|0;G[951380]=d}$b:{if(!c){c=Ic(d,1);break $b}c=lf(h,d)}G[950326]=c;c=Va(c)+c|0;E[c|0]=40;E[c+1|0]=0;v=v+1|0;if((v|0)!=(f|0)){continue}break}}if(!t|!H[t|0]){break Tb}}d=0;f=Va(t);m=G[950326];if(!(!m|!H[m|0])){d=Va(m)}c=G[951380];f=d+f|0;if((c|0)<=(f+1|0)){h=c^-1;f=f+2|0;c=c+1024|0;c=(h+((c|0)<(f|0)?f:c)&-1024)+c|0;G[951380]=c}ac:{if(!d){c=Ic(c,1);break ac}c=lf(m,c)}G[950326]=c;Gb(c,t)}pb(t);c=G[G[G[950332]+(b<<2)>>2]+52>>2];if(c){c=c+(H[c|0]==44)|0}else{c=85390}Bb(c,3801308,3805524);m=G[950330];d=b+1|0;if((m|0)>(d|0)){c=b;f=G[950332];b=d;v=G[f+(b<<2)>>2];if((g|0)==G[v+4>>2]){continue}}break}b=d}c=b;b=g;break Hb}c=c+1|0;b=f}f=b;if((c|0)<(m|0)){continue}}break}if(!(!G[G[950220]+8>>2]|!(b&1))){Bb(41692,3801304,3805520)}if(!e){break Fb}}while(1){Bb(64244,3801304,3805520);e=e-1|0;if(e){continue}break}}m=0;d=G[950326];b=Va(d);bc:{cc:{if((b|0)>0){h=b&1;dc:{if((b|0)==1){f=0;c=0;break dc}g=b&-2;f=0;c=0;e=0;while(1){b=H[c+d|0];f=(((b|0)==40)+f|0)-((b|0)==41)|0;b=H[(c|1)+d|0];f=(f+((b|0)==40)|0)-((b|0)==41)|0;c=c+2|0;e=e+2|0;if((g|0)!=(e|0)){continue}break}}if(h){b=H[c+d|0];f=(((b|0)==40)+f|0)-((b|0)==41)|0}if(!f){break cc}b=G[24367];if(G[G[950220]+12>>2]){G[r+52>>2]=d;G[r+48>>2]=f;_a(b,69632,r+48|0)}ec:{if(H[3780288]){G[r+36>>2]=3780288;G[r+32>>2]=7502;Tb(b,69475,r+32|0);break ec}G[r+16>>2]=7502;Tb(b,68751,r+16|0)}b=G[945062];fc:{if(!b){break fc}c=b+(G[945063]<<2)|0;b=G[c>>2];if(!b){break fc}G[b+16>>2]=0;E[G[b+4>>2]]=0;E[G[b+4>>2]+1|0]=0;G[b+44>>2]=0;G[b+28>>2]=1;d=G[b+4>>2];G[b+8>>2]=d;if((b|0)!=G[c>>2]){break fc}b=G[b+16>>2];G[945064]=d;G[950324]=b;G[945070]=d;G[945057]=G[G[c>>2]>>2];E[3780260]=H[d|0]}E[3801300]=1;d=G[950326]}if(!d){break bc}}if(Xa(d,64156)){m=d;break bc}pb(d);G[950326]=0}d=0;if(G[G[950220]+12>>2]){G[r>>2]=m;_a(G[24367],69376,r);m=G[950326]}K=l,N=Lc(m),G[K+160>>2]=N;K=l,N=Lc(G[950327]),G[K+176>>2]=N;G[l+164>>2]=G[950221];G[l+172>>2]=G[950328];h=G[950330];gc:{if((h|0)<=0){break gc}g=G[950332];c=0;if((h|0)!=1){m=h&-2;e=0;while(1){f=c<<2;b=G[f+g>>2];if(H[b+4|0]&4){d=G[b+20>>2]+d|0}b=G[g+(f|4)>>2];if(H[b+4|0]&4){d=G[b+20>>2]+d|0}c=c+2|0;e=e+2|0;if((m|0)!=(e|0)){continue}break}}if(!(h&1)){break gc}b=G[g+(c<<2)>>2];if(!(H[b+4|0]&4)){break gc}d=G[b+20>>2]+d|0}G[l+168>>2]=d;zl();b=G[945062];if(b){d=G[945063];c=(d<<2)+b|0;f=G[c>>2];if(f){G[c>>2]=0;if(G[f+20>>2]){Wa(G[f+4>>2]);d=G[945063];b=G[945062]}Wa(f);G[(d<<2)+b>>2]=0}}else{b=0}Wa(b);Wa(G[945060]);G[945063]=0;G[945062]=0;G[950329]=0;G[945064]=0;E[3780236]=0;G[945061]=0;G[945060]=0;G[945066]=0;G[945057]=0;G[945058]=0;c=G[l+172>>2]}Fa=r+224|0;hc:{ic:{switch(c+1|0){case 1:Hh(l);l=G[952412];break a;case 0:break hc;default:break ic}}if(w){break a}c=0;jc:{if(!l){break jc}if(G[l+12>>2]>=2){hb(70217,19,1,G[24367])}b=G[l+112>>2];c=1;if(!b){break jc}c=Ja[b|0](l)|0}if(!c){break hc}c=0;kc:{if(!l){break kc}if(G[l+12>>2]>=2){hb(73247,22,1,G[24367])}b=G[l+116>>2];c=1;if(!b){break kc}c=Ja[b|0](l)|0}if(!c){break hc}c=0;lc:{if(!l){break lc}if(G[l+12>>2]>=2){hb(72480,20,1,G[24367])}b=G[l+120>>2];c=1;if(!b){break lc}c=Ja[b|0](l)|0}if(!c){break hc}c=0;mc:{if(!l){break mc}if(G[l+12>>2]>=2){hb(73225,21,1,G[24367])}b=G[l+124>>2];c=1;if(!b){break mc}c=Ja[b|0](l)|0}if(!c){break hc}if(!Hl(l)){break hc}b=0;nc:{if(!l){break nc}oc:{if(G[l+12>>2]>=2){hb(72832,22,1,G[24367]);b=1;if(G[l+12>>2]>1){break oc}}c=G[l+132>>2];b=1;if(!c){break nc}b=Ja[c|0](l)|0}}if(!b){break hc}if(G[l+4>>2]==2|G[l+12>>2]>1){break a}}Hh(l)}l=0}Fa=p+4112|0;G[a+116>>2]=l;if(!(!l|(l|0)==G[952412])){e=G[a+4>>2];h=G[a+8>>2];w=G[a+12>>2];g=G[a+16>>2];m=G[a+72>>2];D=a+80|0;A=Fa-16|0;Fa=A;if(!(!l|(l|0)==G[952412])){if(G[l+4>>2]==2){z=A+12|0;v=Fa-16|0;Fa=v;if(l){o=Fa-4112|0;Fa=o;d=Ic(M(Va(G[l+160>>2]),10)|1,1);pc:{if(!G[l+172>>2]){break pc}j=G[l+160>>2];b=G[l+104>>2];qc:{if(b){G[o>>2]=b;Ya(o+16|0,4095,16239,o);break qc}E[o+18|0]=H[16243];F[o+16>>1]=H[16241]|H[16242]<<8}c=d;while(1){f=H[j|0];while(1){if(!f){break pc}b=Sb(j,o+16|0);if(!b){break pc}j=Va(o+16|0)+b|0;if(!H[j|0]){break pc}rc:{if(!fb(j,64277,8)){break rc}if(!fb(j,64253,4)){break rc}if(!fb(j,64368,7)){break rc}if(!fb(j,64343,8)){break rc}if(!fb(j,64352,5)){break rc}if(!fb(j,64419,6)){break rc}if(!fb(j,64418,7)){break rc}if(!fb(j,64410,7)){break rc}if(!fb(j,64402,7)){break rc}if(!fb(j,64390,4)){break rc}if(!fb(j,64382,6)){break rc}if(!fb(j,64259,6)){break rc}if(!fb(j,64276,9)){break rc}if(!fb(j,64252,5)){break rc}if(!fb(j,64367,8)){break rc}if(!fb(j,64342,9)){break rc}if(!fb(j,64389,5)){break rc}if(!fb(j,64266,9)){break rc}if(!fb(j,64246,5)){break rc}if(!fb(j,64358,8)){break rc}if(!fb(j,64332,9)){break rc}if(!fb(j,64376,5)){break rc}if(!fb(j,64258,7)){break rc}if(!fb(j,64312,8)){break rc}if(!fb(j,64395,6)){break rc}f=1;if(fb(j,64321,10)){continue}}break}while(1){j=H[b|0];if(!(!j|(j|0)==40)){E[c|0]=j;b=b+1|0;c=c+1|0;continue}break}E[c|0]=105;f=H[b|0];if((f|0)!=40){c=c+1|0}else{E[c+1|0]=40;C=C+1|0;f=H[b+1|0];b=b+1|0;c=c+2|0}sc:{if(!f){j=b;break sc}j=b;if(!C){break sc}while(1){E[c|0]=f;C=(((f|0)==40)+C|0)-((f|0)==41)|0;c=c+1|0;j=b+1|0;f=H[b+1|0];if(!f){break sc}b=j;if(C){continue}break}}E[c|0]=59;c=c+1|0;continue}}Fa=o+4112|0;E[v+12|0]=105;E[v+13|0]=105;E[v+14|0]=105;E[v+15|0]=0;b=G[l+172>>2];G[v+8>>2]=G[l+160>>2];G[v+4>>2]=d;G[v>>2]=b;ea(194216,v+12|0,v|0)|0;if(d){Wa(d)}c=0;p=Fa-48|0;Fa=p;E[p+47|0]=0;b=ea(194112,p+47|0,0)|0;G[945054]=0;tc:{if((b|0)<=0){if(!z){break tc}G[z>>2]=0;break tc}n=lb(1,64);G[n>>2]=b;b=b<<2|1;G[n+4>>2]=b;b=lb(b,168);d=(m|0)>1?m:1;G[n+32>>2]=d;G[n+8>>2]=b;G[n+44>>2]=1;G[n+36>>2]=1;G[n+28>>2]=g;c=(w|0)>1?w:1;G[n+24>>2]=c;G[n+20>>2]=h;b=(e|0)>1?e:1;G[n+16>>2]=b;c=(g-c|0)/(d|0)|0;g=c+1|0;G[n+48>>2]=g;m=(h-b|0)/(d|0)|0;x=m+1|0;G[n+40>>2]=x;t=m+2|0;C=lb(t,4);G[945055]=10240;b=lb(10240,16);G[945056]=b;G[b>>2]=0;w=c+2|0;K=n,N=lb(w,4),G[K+52>>2]=N;o=lb(w,4);G[n+56>>2]=o;e=lb(w,4);G[n+60>>2]=e;uc:{if((c|0)<-1){break uc}d=0;f=0;if(g>>>0>=7){b=w&-8;j=0;while(1){h=f<<2;G[h+o>>2]=x;G[o+(h|4)>>2]=x;G[o+(h|8)>>2]=x;G[o+(h|12)>>2]=x;G[o+(h|16)>>2]=x;G[o+(h|20)>>2]=x;G[o+(h|24)>>2]=x;G[o+(h|28)>>2]=x;f=f+8|0;j=j+8|0;if((b|0)!=(j|0)){continue}break}}b=w&7;if(b){while(1){G[o+(f<<2)>>2]=x;f=f+1|0;d=d+1|0;if((b|0)!=(d|0)){continue}break}}if((c|0)<-1){break uc}b=0;c=0;if(g>>>0>=7){d=w&-8;f=0;while(1){j=c<<2;G[j+e>>2]=1;G[e+(j|4)>>2]=1;G[e+(j|8)>>2]=1;G[e+(j|12)>>2]=1;G[e+(j|16)>>2]=1;G[e+(j|20)>>2]=1;G[e+(j|24)>>2]=1;G[e+(j|28)>>2]=1;c=c+8|0;f=f+8|0;if((d|0)!=(f|0)){continue}break}}d=w&7;if(!d){break uc}while(1){G[e+(c<<2)>>2]=1;c=c+1|0;b=b+1|0;if((d|0)!=(b|0)){continue}break}}E[p+43|0]=105;E[p+44|0]=105;E[p+45|0]=105;E[p+46|0]=0;G[p+20>>2]=0;G[p+24>>2]=0;G[p+16>>2]=n;ea(194144,p+43|0,p+16|0)|0;j=G[n+44>>2];if((j|0)<=G[n+48>>2]){o=t<<2;e=(m|0)>=0;while(1){m=j;f=j<<2;vc:{if(!G[f+G[n+52>>2]>>2]){break vc}j=G[945056];b=G[945054];if(G[j+(b<<4)>>2]){d=b+1|0;G[945054]=d;c=G[945055];if((c|0)<=(d|0)){b=c+10240|0;G[945055]=b;j=ub(j,b<<4);G[945056]=j;cb((c<<4)+j|0,0,163840)}G[(d<<4)+j>>2]=0}b=G[f+G[n+56>>2]>>2];if((b|0)>G[f+G[n+60>>2]>>2]){break vc}j=(C+(b-G[n+36>>2]<<2)|0)+4|0;d=0;while(1){G[n+12>>2]=0;G[p>>2]=n;E[p+39|0]=105;E[p+40|0]=105;E[p+41|0]=105;E[p+42|0]=0;c=b;G[p+4>>2]=b;G[p+8>>2]=m;wc:{if(!(ea(194176,p+39|0,p|0)|0)){break wc}xc:{yc:{switch(G[j>>2]+1|0){case 1:d=d+1|0;b=G[n+12>>2];b=b?b:-1;break xc;case 0:break yc;default:break wc}}b=G[n+12>>2];if((b|0)<=0){break wc}}G[j>>2]=b}j=j+4|0;b=c+1|0;if((c|0)>2]>>2]){continue}break}if(!d){break vc}zc:{if(!e){c=G[945054];b=G[945056];break zc}j=1;h=m+1|0;b=G[945056];c=G[945054];d=G[945055];while(1){w=G[C+(j<<2)>>2];g=(c<<4)+b|0;f=G[g>>2];if((w|0)!=(f|0)){Ac:{if(!f){break Ac}G[g+12>>2]=j-1;c=c+1|0;G[945054]=c;if((c|0)<(d|0)){break Ac}f=d+10240|0;G[945055]=f;b=ub(b,f<<4);G[945056]=b;cb((d<<4)+b|0,0,163840);d=f}f=G[n+44>>2];g=(c<<4)+b|0;G[g+8>>2]=j;G[g>>2]=w;G[g+4>>2]=h-f}j=j+1|0;if((t|0)!=(j|0)){continue}break}}d=(c<<4)+b|0;Bc:{if(!G[d>>2]){break Bc}G[d+12>>2]=(G[n+40>>2]-G[n+36>>2]|0)+1;c=c+1|0;G[945054]=c;d=G[945055];if((d|0)>(c|0)){break Bc}c=d+10240|0;G[945055]=c;b=ub(b,c<<4);G[945056]=b;cb(b+(d<<4)|0,0,163840)}cb(C,0,o)}j=m+1|0;if((m|0)>2]){continue}break}}if(C){Wa(C)}if(G[n+4>>2]>0){f=0;while(1){j=G[n+8>>2];m=M(f,168);d=G[(j+m|0)+24>>2];if(d){b=0;c=G[n+48>>2];if((c|0)>=0){while(1){j=G[G[(m+G[n+8>>2]|0)+24>>2]+(b<<2)>>2];if(j){while(1){c=G[j>>2];Wa(j);j=c;if(c){continue}break}c=G[n+48>>2]}d=(b|0)<(c|0);b=b+1|0;if(d){continue}break}d=G[(m+G[n+8>>2]|0)+24>>2]}Wa(d);j=G[n+8>>2]}b=G[(j+m|0)+124>>2];if(b){Wa(b);j=G[n+8>>2]}b=G[(j+m|0)+32>>2];if(b){Wa(b)}f=f+1|0;if((f|0)>2]){continue}break}}b=G[n+8>>2];if(b){Wa(b)}b=G[n+52>>2];if(b){Wa(b)}b=G[n+56>>2];if(b){Wa(b)}b=G[n+60>>2];if(b){Wa(b)}Wa(n);if(z){G[z>>2]=G[945054]}c=G[945056]}Fa=p+48|0}else{c=0}Fa=v+16|0;G[a+112>>2]=c}if(D){G[D>>2]=G[l+168>>2]}j=G[A+12>>2]}Fa=A+16|0;G[a+76>>2]=j;b=G[G[a+116>>2]+16>>2];j=Ic(M(Va(b),3),1);G[a+52>>2]=j;c=H[b|0];if(c){while(1){E[j|0]=c;if(H[b|0]!=10){j=j+1|0}else{E[j+1|0]=35;E[j+2|0]=32;j=j+3|0}c=H[b+1|0];b=b+1|0;if(c){continue}break}j=G[a+52>>2]}K=a,N=lf(j,Va(j)+1|0),G[K+52>>2]=N}b=G[a+80>>2];if(b){K=a,N=Ic(b,8),G[K+104>>2]=N;K=a,N=Ic(G[a+80>>2],8),G[K+108>>2]=N;K=a,N=Ic(G[a+80>>2],4),G[K+84>>2]=N;K=a,N=Ic(G[a+80>>2],4),G[K+88>>2]=N;a=G[a+80>>2]}else{a=0}return a}function qj(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,I=0,J=0,K=0,N=0,P=0;c=Fa-3008|0;Fa=c;d=lb(1,9416);b=H[b|0];b=(b|0)==32?0:b;E[c+1967|0]=b;E[d+9404|0]=b;if(rf(a,35488,c+1967|0,63,c+1968|0)){e=c+1968|0;b=lb(Va(e)+2|0,1);G[d+9400>>2]=b;Za(b,e)}G[d+4064>>2]=0;G[d+4004>>2]=0;G[d+3268>>2]=0;G[d+3272>>2]=0;b=d+4032|0;G[b>>2]=-1;G[b+4>>2]=0;D=c+2816|0;b=D;G[b>>2]=0;G[b+4>>2]=0;J=c+2824|0;b=J;G[b>>2]=0;G[b+4>>2]=0;G[c+2832>>2]=0;G[c+2836>>2]=0;G[c+2800>>2]=0;G[c+2804>>2]=0;G[c+2808>>2]=0;G[c+2812>>2]=0;G[c+2144>>2]=0;G[c+2148>>2]=0;G[c+2840>>2]=0;G[c+2844>>2]=0;G[d+48>>2]=0;G[d+52>>2]=0;G[d+3300>>2]=0;G[c+2120>>2]=0;h=c+2120|0;i=Fa-16|0;Fa=i;e=E[c+1967|0];a:{if((e|0)<=63){Md(a,33794,h);break a}q=Za(i,33794);b=Va(33794)+q|0;E[b|0]=e;E[b+1|0]=0;Md(a,q,h)}Fa=i+16|0;b=G[c+2120>>2];b:{if(b){break b}Md(a,33794,c+2120|0);b=G[c+2120>>2];if(b){break b}Md(a,33788,c+2120|0);b=G[c+2120>>2];if(b){break b}Md(a,34652,c+2120|0);b=G[c+2120>>2]}c:{d:{if((b|0)<=0){jd(25828);break d}if(b>>>0>=3){G[c+2120>>2]=2;b=2}G[d+3320>>2]=b;G[d+3316>>2]=b;G[d+136>>2]=0;G[d+140>>2]=0;G[d+4040>>2]=b;w=d+136|0;ob(a,41261,w);g=L[d+136>>3];if(g<1){ob(a,33148,w);g=L[w>>3]}if(g<1){jd(25791);break d}G[d+144>>2]=0;G[d+148>>2]=0;B=d+144|0;ob(a,40853,B);if(L[d+144>>3]<1){ob(a,34932,B)}b=G[c+2120>>2];e:{f:{if((b|0)>=2){if(!(L[B>>3]<1)){break f}jd(25918);break d}if((b|0)!=1){break e}}h=G[24367];i=H[33792]|H[33793]<<8;q=H[33788]|H[33789]<<8|(H[33790]<<16|H[33791]<<24);m=H[35421]|H[35422]<<8;r=H[35417]|H[35418]<<8|(H[35419]<<16|H[35420]<<24);while(1){F[c+2132>>1]=i;G[c+2128>>2]=q;b=f;f=b+1|0;G[c+1920>>2]=f;e=c+2032|0;db(e,30633,c+1920|0);e=Gb(c+2128|0,e);g:{if(Md(a,e,c+2124|0)){break g}h:{i:{switch(b|0){case 0:g=L[w>>3];if(!(g>1)){break h}if(O(g)<2147483648){G[c+2124>>2]=~~g;break g}G[c+2124>>2]=-2147483648;break g;case 1:break i;default:break h}}g=L[B>>3];if(!(g>1)){break h}if(O(g)<2147483648){G[c+2124>>2]=~~g;break g}G[c+2124>>2]=-2147483648;break g}G[c+1904>>2]=e;_a(h,86533,c+1904|0)}E[e+4|0]=m;E[e+5|0]=m>>>8;E[e|0]=r;E[e+1|0]=r>>>8;E[e+2|0]=r>>>16;E[e+3|0]=r>>>24;b=c+2032|0;j:{if(!ie(a,Gb(e,b),16,b)){break j}if(!ug(c+2032|0,35917)){break j}G[c+2124>>2]=0}j=(G[c+2124>>2]>1)+j|0;if(G[c+2120>>2]>(f|0)){continue}break}}G[c+2120>>2]=j;G[d+3316>>2]=j;G[d+3320>>2]=j;ie(a,35441,16,d+3336|0);Md(a,33968,d+3332|0);b=0;e=G[321351];G[d+9408>>2]=0;G[d+3324>>2]=e;Md(a,35104,d+9408|0);K=cb(d+832|0,0,648);cb(c+2144|0,0,648);h=G[c+2120>>2];k:{if((h|0)>0){q=h-1|0;if(q>>>0>=3){f=h&-4;i=d+832|0;while(1){e=i+(M(b,h)+b<<3)|0;G[e>>2]=0;G[e+4>>2]=1072693248;e=b|1;e=i+(M(e,h)+e<<3)|0;G[e>>2]=0;G[e+4>>2]=1072693248;e=b|2;e=i+(M(e,h)+e<<3)|0;G[e>>2]=0;G[e+4>>2]=1072693248;e=b|3;e=i+(M(e,h)+e<<3)|0;G[e>>2]=0;G[e+4>>2]=1072693248;b=b+4|0;u=u+4|0;if((f|0)!=(u|0)){continue}break}}f=h&3;if(f){j=0;while(1){e=(M(b,h)+b<<3)+d|0;G[e+832>>2]=0;G[e+836>>2]=1072693248;b=b+1|0;j=j+1|0;if((f|0)!=(j|0)){continue}break}}j=0;b=0;if(q>>>0>=3){f=h&-4;u=0;while(1){i=c+2144|0;e=i+(M(b,h)+b<<3)|0;G[e>>2]=0;G[e+4>>2]=1072693248;e=b|1;e=i+(M(e,h)+e<<3)|0;G[e>>2]=0;G[e+4>>2]=1072693248;e=b|2;e=i+(M(e,h)+e<<3)|0;G[e>>2]=0;G[e+4>>2]=1072693248;e=b|3;e=(M(e,h)+e<<3)+i|0;G[e>>2]=0;G[e+4>>2]=1072693248;b=b+4|0;u=u+4|0;if((f|0)!=(u|0)){continue}break}}f=h&3;if(f){while(1){e=(c+2144|0)+(M(b,h)+b<<3)|0;G[e>>2]=0;G[e+4>>2]=1072693248;b=b+1|0;j=j+1|0;if((f|0)!=(j|0)){continue}break}}u=0;I=d+760|0;cb(I,0,72);j=0;if(q>>>0>=7){f=h&-8;i=d+760|0;e=0;while(1){q=j<<3;b=q+i|0;G[b>>2]=0;G[b+4>>2]=1072693248;b=i+(q|8)|0;G[b>>2]=0;G[b+4>>2]=1072693248;b=i+(q|16)|0;G[b>>2]=0;G[b+4>>2]=1072693248;b=i+(q|24)|0;G[b>>2]=0;G[b+4>>2]=1072693248;b=i+(q|32)|0;G[b>>2]=0;G[b+4>>2]=1072693248;b=i+(q|40)|0;G[b>>2]=0;G[b+4>>2]=1072693248;b=i+(q|48)|0;G[b>>2]=0;G[b+4>>2]=1072693248;b=i+(q|56)|0;G[b>>2]=0;G[b+4>>2]=1072693248;j=j+8|0;e=e+8|0;if((f|0)!=(e|0)){continue}break}}e=h&7;if(!e){break k}while(1){b=(j<<3)+d|0;G[b+760>>2]=0;G[b+764>>2]=1072693248;j=j+1|0;u=u+1|0;if((e|0)!=(u|0)){continue}break}break k}I=d+760|0;cb(I,0,72)}l:{if(rf(a,34226,c+1967|0,63,c+1968|0)){b=0;u=0;r=0;j=Fa-96|0;Fa=j;i=c+1968|0;m:{if(!i){break m}h=Va(i);p=lb(1,h+1|0);n:{if((h|0)<=0){break n}if((h|0)!=1){f=h&-2;while(1){e=H[b+i|0];E[b+p|0]=(e-97&255)>>>0<26?e-32|0:e;e=b|1;q=H[e+i|0];E[e+p|0]=(q-97&255)>>>0<26?q-32|0:q;b=b+2|0;r=r+2|0;if((f|0)!=(r|0)){continue}break}}if(!(h&1)){break n}e=b+p|0;b=H[b+i|0];E[e|0]=(b-97&255)>>>0<26?b-32|0:b}E[h+p|0]=0;if((Va(p)|0)==1){u=H[p|0];break m}E[j+88|0]=0;G[j+80>>2]=1314079575;G[j+84>>2]=4541761;u=95;h=0;while(1){q=h?h- -64|0:0;E[j+87|0]=q;if(ie(a,j+80|0,72,j)){m=Va(j);w=lb(1,m+1|0);o:{if((m|0)<=0){break o}b=0;if((m|0)!=1){f=m&-2;r=0;while(1){e=H[b+j|0];E[b+w|0]=(e-97&255)>>>0<26?e-32|0:e;e=b|1;i=H[e+j|0];E[e+w|0]=(i-97&255)>>>0<26?i-32|0:i;b=b+2|0;r=r+2|0;if((f|0)!=(r|0)){continue}break}}if(!(m&1)){break o}e=b+w|0;b=H[b+j|0];E[e|0]=(b-97&255)>>>0<26?b-32|0:b}E[m+w|0]=0;b=Xa(w,p);Wa(w);u=b?u:q}h=h+1|0;if((h|0)!=27){continue}break}Wa(p)}Fa=j+96|0;b=u<<24>>24;E[c+2976|0]=b;p:{q:{if((b|0)==95){G[c+1888>>2]=c+1968;_a(G[24367],70021,c+1888|0);G[d+9392>>2]=0;break q}b=qj(a,c+2976|0);G[d+9392>>2]=b;if(b){break p}}jd(5132);break d}G[b+9396>>2]=d;break l}G[d+9392>>2]=0}G[d+3224>>2]=0;G[d+3228>>2]=0;e=d+3232|0;G[e>>2]=0;G[e+4>>2]=0;b=d+3224|0;r:{if(Zb(a,35715,c+1967|0,b)){L[e>>3]=L[b>>3]/299792.5;break r}if(Zb(a,35707,c+1967|0,e)){L[b>>3]=L[e>>3]*299792.5;break r}if(!ob(a,32691,b)){break r}L[e>>3]=L[b>>3]/299792.5}j=cb(d+4176|0,0,80);s:{t:{u:{v:{if(rf(a,41295,c+1967|0,16,c+2976|0)){b=c+2976|0;m=Za(c+2944|0,b);h=rf(a,40882,c+1967|0,16,m);Za(d+3368|0,b);Za(d+3384|0,m);w:{if(ug(m,33504)){f=2;q=1;break w}b=ug(m,35895);f=b?2:1;q=(b|0)!=0}b=d+3400|0;E[b|0]=0;e=c+1967|0;rf(a,40521,e,9,b);b=d+3416|0;E[b|0]=0;rf(a,40374,e,9,b);if(tm(d,c+2976|0,m)){break d}x:{if(G[d+3260>>2]){break x}e=d+3560|0;y:{if(rf(a,41241,c+1967|0,16,e)){break y}if(Lm(a,41248,e)){break y}E[e|0]=0}if(!Xa(e,16895)){G[d+3260>>2]=-1}if(!h){break x}b=d+3592|0;z:{if(rf(a,40833,c+1967|0,16,b)){break z}if(Lm(a,40840,b)){break z}E[b|0]=0}if(Xa(e,16895)){break x}G[d+3260>>2]=-1}G[d+616>>2]=0;G[d+620>>2]=1072693248;h=c+1967|0;e=d+616|0;Zb(a,41201,h,e);b=d+624|0;G[b>>2]=0;G[b+4>>2]=1072693248;Zb(a,40799,h,b);G[d+688>>2]=0;G[d+692>>2]=0;L[d+16>>3]=L[d+616>>3];L[d+24>>3]=L[b>>3];Zb(a,41279,h,d+688|0);b=d+696|0;G[b>>2]=0;G[b+4>>2]=0;Zb(a,40866,h,b);A:{B:{C:{switch(G[d+3964>>2]-7|0){default:g=L[b>>3];break A;case 0:g=90-L[b>>3];break B;case 1:break C}}g=L[b>>3]+-90}L[b>>3]=g}L[d+8>>3]=g;G[d+3176>>2]=0;G[d+3180>>2]=1083127808;n=L[d+688>>3];L[d>>3]=n;b=G[d+3304>>2];L[d+4080>>3]=b?n:g;L[d+4072>>3]=b?g:n;s=c+1967|0;Zb(a,35545,s,d+3176|0);G[d+3184>>2]=0;G[d+3188>>2]=1083127808;L[d+4088>>3]=L[d+3176>>3];Zb(a,35537,s,d+3184|0);G[d+4052>>2]=I;G[d+4044>>2]=e;b=d+4168|0;G[b>>2]=0;G[b+4>>2]=0;G[d+4048>>2]=K;L[d+4096>>3]=L[d+3184>>3];Zb(a,41543,s,b);G[c+1872>>2]=0;b=c+2128|0;db(b,29941,c+1872|0);Zb(a,b,s,j);G[c+1856>>2]=1;db(b,29941,c+1856|0);x=d+4184|0;Zb(a,b,s,x);G[c+1840>>2]=2;db(b,29941,c+1840|0);A=d+4192|0;Zb(a,b,s,A);G[c+1824>>2]=3;db(b,29941,c+1824|0);u=d+4200|0;Zb(a,b,s,u);G[c+1808>>2]=4;db(b,29941,c+1808|0);p=d+4208|0;Zb(a,b,s,p);G[c+1792>>2]=5;db(b,29941,c+1792|0);r=d+4216|0;Zb(a,b,s,r);G[c+1776>>2]=6;db(b,29941,c+1776|0);w=d+4224|0;Zb(a,b,s,w);G[c+1760>>2]=7;db(b,29941,c+1760|0);m=d+4232|0;Zb(a,b,s,m);G[c+1744>>2]=8;db(b,29941,c+1744|0);h=d+4240|0;Zb(a,b,s,h);G[c+1728>>2]=9;db(b,29941,c+1728|0);e=d+4248|0;Zb(a,b,s,e);G[c+1712>>2]=f;db(c+2904|0,41069,c+1712|0);G[c+1696>>2]=f;db(c+2896|0,40711,c+1696|0);G[c+1680>>2]=f;db(c+2888|0,40490,c+1680|0);D:{E:{F:{G:{H:{I:{J:{K:{L:{M:{N:{b=G[d+3260>>2];switch(b-1|0){case 35:break F;case 26:break G;case 17:break H;case 8:break I;case 9:break J;case 12:break K;case 1:break L;case 0:case 3:case 13:case 14:case 15:case 16:break M;case 6:break N;default:break D}}G[c+1668>>2]=0;G[c+1664>>2]=f;s=c+2128|0;db(s,29879,c+1664|0);b=c+1967|0;Zb(a,s,b,j);G[c+1652>>2]=1;G[c+1648>>2]=f;db(s,29879,c+1648|0);Zb(a,s,b,x);G[c+1636>>2]=2;G[c+1632>>2]=f;db(s,29879,c+1632|0);Zb(a,s,b,A);G[c+1620>>2]=3;G[c+1616>>2]=f;db(s,29879,c+1616|0);Zb(a,s,b,u);G[c+1604>>2]=4;G[c+1600>>2]=f;db(s,29879,c+1600|0);Zb(a,s,b,p);G[c+1588>>2]=5;G[c+1584>>2]=f;db(s,29879,c+1584|0);Zb(a,s,b,r);G[c+1572>>2]=6;G[c+1568>>2]=f;db(s,29879,c+1568|0);Zb(a,s,b,w);G[c+1556>>2]=7;G[c+1552>>2]=f;db(s,29879,c+1552|0);Zb(a,s,b,m);G[c+1540>>2]=8;G[c+1536>>2]=f;db(s,29879,c+1536|0);Zb(a,s,b,h);G[c+1524>>2]=9;G[c+1520>>2]=f;db(s,29879,c+1520|0);Zb(a,s,b,e);break E}b=c+1967|0;Zb(a,c+2904|0,b,x);Zb(a,c+2896|0,b,A);break E}b=c+1967|0;Zb(a,c+2904|0,b,x);Zb(a,c+2896|0,b,A);if(L[u>>3]==0){G[u>>2]=0;G[u+4>>2]=1079410688}Zb(a,c+2888|0,c+1967|0,u);break E}if(L[x>>3]==0){G[x>>2]=0;G[x+4>>2]=1072693248}Zb(a,c+2904|0,c+1967|0,x);break E}if(L[x>>3]==0){G[x>>2]=0;G[x+4>>2]=1072693248}Zb(a,c+2904|0,c+1967|0,x);if(L[A>>3]==0){G[A>>2]=0;G[A+4>>2]=1072693248}Zb(a,c+2896|0,c+1967|0,A);break E}if(L[x>>3]==0){G[x>>2]=0;G[x+4>>2]=1079410688}Zb(a,c+2904|0,c+1967|0,x);break E}Zb(a,c+2904|0,c+1967|0,x);break E}b=c+1967|0;Zb(a,41130,b,x);Zb(a,40746,b,A);break E}Zb(a,41130,c+1967|0,x)}b=G[d+3260>>2]}if((b|0)==33){m=ab(2e3);h=ab(2e3);Of(a,41248,m);Of(a,40840,h);f=ab(2e3);e=ab(2e3);O:{if(!(L[d+3176>>3]>360)){break O}b=d+3176|0;if(kd(m,21617,b)){break O}if(kd(h,21617,b)){break O}G[b>>2]=0;G[b+4>>2]=1080459264}b=d+3192|0;P:{if(kd(m,13552,b)){break P}if(kd(h,13552,b)){break P}G[b>>2]=442745336;G[b+4>>2]=1078765020}b=d;Q:{R:{if(sf(m,10928,f)){break R}if(sf(h,10928,f)){break R}i=0;break Q}i=Xh(f)}G[b+6040>>2]=i;b=d;S:{T:{if(sf(h,10921,e)){break T}if(sf(m,10921,e)){break T}i=0;break S}i=Xh(e)}G[b+6044>>2]=i;qg(d);Wa(m);Wa(h);Wa(f);Wa(e);b=1;U:{if(!(G[d+6044>>2]|G[d+6040>>2])){break U}b=0}if(b){break v}b=G[d+3260>>2]}if((b|0)==34){k=Fa-160|0;Fa=k;z=ab(2e3);x=ab(2e3);if(!Of(a,41248,z)){b=Gb(bb(ab(Va(a)+200|0),64865,161),a);Of(b,41248,z);Of(b,40840,x);Wa(b)}Of(a,40840,x);s=ab(2e3);A=ab(2e3);V:{if(!(L[d+3176>>3]>360)){break V}b=d+3176|0;if(kd(z,21617,b)){break V}if(kd(x,21617,b)){break V}G[b>>2]=0;G[b+4>>2]=1080459264}b=d+3192|0;W:{if(kd(z,13552,b)){break W}if(kd(x,13552,b)){break W}G[b>>2]=442745336;G[b+4>>2]=1078765020}G[k+144>>2]=0;b=k+152|0;db(b,29831,k+144|0);u=d+4176|0;if(!kd(z,b,u)){G[u>>2]=0;G[u+4>>2]=0}G[k+128>>2]=1;b=k+152|0;db(b,29831,k+128|0);j=d+4184|0;if(!kd(z,b,j)){G[j>>2]=0;G[j+4>>2]=0}G[k+112>>2]=2;b=k+152|0;db(b,29831,k+112|0);p=d+4192|0;if(!kd(z,b,p)){G[p>>2]=0;G[p+4>>2]=0}G[k+96>>2]=3;b=k+152|0;db(b,29831,k+96|0);r=d+4200|0;if(!kd(z,b,r)){G[r>>2]=0;G[r+4>>2]=0}G[k+80>>2]=4;b=k+152|0;db(b,29831,k+80|0);w=d+4208|0;if(!kd(z,b,w)){G[w>>2]=0;G[w+4>>2]=0}G[k+64>>2]=5;b=k+152|0;db(b,29831,k- -64|0);m=d+4216|0;if(!kd(z,b,m)){G[m>>2]=0;G[m+4>>2]=0}G[k+48>>2]=6;b=k+152|0;db(b,29831,k+48|0);h=d+4224|0;if(!kd(z,b,h)){G[h>>2]=0;G[h+4>>2]=0}G[k+32>>2]=7;b=k+152|0;db(b,29831,k+32|0);f=d+4232|0;if(!kd(z,b,f)){G[f>>2]=0;G[f+4>>2]=0}G[k+16>>2]=8;b=k+152|0;db(b,29831,k+16|0);e=d+4240|0;if(!kd(z,b,e)){G[e>>2]=0;G[e+4>>2]=0}G[k>>2]=9;b=k+152|0;db(b,29831,k);i=b;b=d+4248|0;if(!kd(z,i,b)){G[b>>2]=0;G[b+4>>2]=0}b=d;X:{Y:{if(sf(z,10928,s)){break Y}if(sf(x,10928,s)){break Y}i=0;break X}i=Xh(s)}G[b+6040>>2]=i;b=d;Z:{_:{if(sf(x,10921,A)){break _}if(sf(z,10921,A)){break _}i=0;break Z}i=Xh(A)}G[b+6044>>2]=i;$:{aa:{if(L[d+4248>>3]!=0){e=9;break aa}if(L[e>>3]!=0){e=8;break aa}if(L[f>>3]!=0){e=7;break aa}if(L[h>>3]!=0){e=6;break aa}if(L[m>>3]!=0){e=5;break aa}if(L[w>>3]!=0){e=4;break aa}if(L[r>>3]!=0){e=3;break aa}if(L[p>>3]!=0){G[d+3276>>2]=2;break $}if(L[j>>3]!=0){G[d+3276>>2]=1;break $}if(L[u>>3]!=0){G[d+3276>>2]=0;break $}G[d+3276>>2]=-1;break $}G[d+3276>>2]=e;h=e&3;r=e-1|0;n=L[d+4184>>3];w=d+4176|0;m=1;ba:{ca:{da:{while(1){v=+(m|0)*3.141592653589793/180;f=0;g=0;b=e;if(h){while(1){g=g*v+L[((b<<3)+d|0)+4176>>3]*+(b|0);b=b-1|0;f=f+1|0;if((h|0)!=(f|0)){continue}break}}if(r>>>0>=3){while(1){f=b-1|0;g=((g*v+L[w+(b<<3)>>3]*+(b|0))*v+L[w+(f<<3)>>3]*+(f|0))*v;f=b-2|0;g=(g+L[w+(f<<3)>>3]*+(f|0))*v;f=b-3|0;g=g+L[w+(f<<3)>>3]*+(f|0);f=(b|0)>4;b=b-4|0;if(f){continue}break}}if(g<=0){l=t-n*(v-t)/(g-n);f=e&3;if(f){break da}b=e;break ca}n=g;t=v;m=m+1|0;if((m|0)!=181){continue}break}l=3.141592653589793;break ba}j=0;b=e;while(1){o=o*l+L[((b<<3)+d|0)+4176>>3]*+(b|0);b=b-1|0;j=j+1|0;if((f|0)!=(j|0)){continue}break}}if(r>>>0>=3){h=d+4176|0;while(1){f=b-1|0;o=((o*l+L[h+(b<<3)>>3]*+(b|0))*l+L[h+(f<<3)>>3]*+(f|0))*l;f=b-2|0;o=(o+L[h+(f<<3)>>3]*+(f|0))*l;f=b-3|0;o=o+L[h+(f<<3)>>3]*+(f|0);f=(b|0)>4;b=b-4|0;if(f){continue}break}}if(O(o)<1e-13){break ba}b=o<0;y=b?t:l;t=b?n:o;n=b?l:v;g=b?o:g;l=y-t*(n-y)/(g-t);f=e&3;ea:{if(!f){b=e;break ea}j=0;b=e;while(1){C=C*l+L[((b<<3)+d|0)+4176>>3]*+(b|0);b=b-1|0;j=j+1|0;if((f|0)!=(j|0)){continue}break}}if(r>>>0>=3){h=d+4176|0;while(1){f=b-1|0;v=((C*l+L[h+(b<<3)>>3]*+(b|0))*l+L[h+(f<<3)>>3]*+(f|0))*l;f=b-2|0;v=(v+L[h+(f<<3)>>3]*+(f|0))*l;f=b-3|0;C=v+L[h+(f<<3)>>3]*+(f|0);f=(b|0)>4;b=b-4|0;if(f){continue}break}}if(O(C)<1e-13){break ba}o=0;b=C<0;y=b?y:l;v=b?t:C;t=b?l:n;n=b?C:g;l=y-v*(t-y)/(n-v);f=e&3;fa:{if(!f){b=e;break fa}j=0;b=e;while(1){o=o*l+L[((b<<3)+d|0)+4176>>3]*+(b|0);b=b-1|0;j=j+1|0;if((f|0)!=(j|0)){continue}break}}if(r>>>0>=3){h=d+4176|0;while(1){f=b-1|0;g=((o*l+L[h+(b<<3)>>3]*+(b|0))*l+L[h+(f<<3)>>3]*+(f|0))*l;f=b-2|0;g=(g+L[h+(f<<3)>>3]*+(f|0))*l;f=b-3|0;o=g+L[h+(f<<3)>>3]*+(f|0);f=(b|0)>4;b=b-4|0;if(f){continue}break}}if(O(o)<1e-13){break ba}g=0;b=o<0;y=b?y:l;v=b?v:o;t=b?l:t;n=b?o:n;l=y-v*(t-y)/(n-v);f=e&3;ga:{if(!f){b=e;break ga}j=0;b=e;while(1){g=g*l+L[((b<<3)+d|0)+4176>>3]*+(b|0);b=b-1|0;j=j+1|0;if((f|0)!=(j|0)){continue}break}}if(r>>>0>=3){h=d+4176|0;while(1){f=b-1|0;g=((g*l+L[h+(b<<3)>>3]*+(b|0))*l+L[h+(f<<3)>>3]*+(f|0))*l;f=b-2|0;g=(g+L[h+(f<<3)>>3]*+(f|0))*l;f=b-3|0;g=g+L[h+(f<<3)>>3]*+(f|0);f=(b|0)>4;b=b-4|0;if(f){continue}break}}if(O(g)<1e-13){break ba}o=0;b=g<0;y=b?y:l;v=b?v:g;t=b?l:t;n=b?g:n;l=y-v*(t-y)/(n-v);f=e&3;ha:{if(!f){b=e;break ha}j=0;b=e;while(1){o=o*l+L[((b<<3)+d|0)+4176>>3]*+(b|0);b=b-1|0;j=j+1|0;if((f|0)!=(j|0)){continue}break}}if(r>>>0>=3){h=d+4176|0;while(1){f=b-1|0;g=((o*l+L[h+(b<<3)>>3]*+(b|0))*l+L[h+(f<<3)>>3]*+(f|0))*l;f=b-2|0;g=(g+L[h+(f<<3)>>3]*+(f|0))*l;f=b-3|0;o=g+L[h+(f<<3)>>3]*+(f|0);f=(b|0)>4;b=b-4|0;if(f){continue}break}}if(O(o)<1e-13){break ba}g=0;b=o<0;y=b?y:l;v=b?v:o;t=b?l:t;n=b?o:n;l=y-v*(t-y)/(n-v);f=e&3;ia:{if(!f){b=e;break ia}j=0;b=e;while(1){g=g*l+L[((b<<3)+d|0)+4176>>3]*+(b|0);b=b-1|0;j=j+1|0;if((f|0)!=(j|0)){continue}break}}if(r>>>0>=3){h=d+4176|0;while(1){f=b-1|0;g=((g*l+L[h+(b<<3)>>3]*+(b|0))*l+L[h+(f<<3)>>3]*+(f|0))*l;f=b-2|0;g=(g+L[h+(f<<3)>>3]*+(f|0))*l;f=b-3|0;g=g+L[h+(f<<3)>>3]*+(f|0);f=(b|0)>4;b=b-4|0;if(f){continue}break}}if(O(g)<1e-13){break ba}o=0;b=g<0;y=b?y:l;v=b?v:g;t=b?l:t;n=b?g:n;l=y-v*(t-y)/(n-v);f=e&3;ja:{if(!f){b=e;break ja}j=0;b=e;while(1){o=o*l+L[((b<<3)+d|0)+4176>>3]*+(b|0);b=b-1|0;j=j+1|0;if((f|0)!=(j|0)){continue}break}}if(r>>>0>=3){h=d+4176|0;while(1){f=b-1|0;g=((o*l+L[h+(b<<3)>>3]*+(b|0))*l+L[h+(f<<3)>>3]*+(f|0))*l;f=b-2|0;g=(g+L[h+(f<<3)>>3]*+(f|0))*l;f=b-3|0;o=g+L[h+(f<<3)>>3]*+(f|0);f=(b|0)>4;b=b-4|0;if(f){continue}break}}if(O(o)<1e-13){break ba}g=0;b=o<0;y=b?y:l;v=b?v:o;t=b?l:t;n=b?o:n;l=y-v*(t-y)/(n-v);f=e&3;ka:{if(!f){b=e;break ka}j=0;b=e;while(1){g=g*l+L[((b<<3)+d|0)+4176>>3]*+(b|0);b=b-1|0;j=j+1|0;if((f|0)!=(j|0)){continue}break}}if(r>>>0>=3){h=d+4176|0;while(1){f=b-1|0;g=((g*l+L[h+(b<<3)>>3]*+(b|0))*l+L[h+(f<<3)>>3]*+(f|0))*l;f=b-2|0;g=(g+L[h+(f<<3)>>3]*+(f|0))*l;f=b-3|0;g=g+L[h+(f<<3)>>3]*+(f|0);f=(b|0)>4;b=b-4|0;if(f){continue}break}}if(O(g)<1e-13){break ba}o=0;b=g<0;C=b?y:l;y=b?v:g;v=b?l:t;t=b?g:n;l=C-y*(v-C)/(t-y);f=e&3;la:{if(!f){b=e;break la}j=0;b=e;while(1){o=o*l+L[((b<<3)+d|0)+4176>>3]*+(b|0);b=b-1|0;j=j+1|0;if((f|0)!=(j|0)){continue}break}}if(r>>>0>=3){h=d+4176|0;while(1){f=b-1|0;g=((o*l+L[h+(b<<3)>>3]*+(b|0))*l+L[h+(f<<3)>>3]*+(f|0))*l;f=b-2|0;g=(g+L[h+(f<<3)>>3]*+(f|0))*l;f=b-3|0;o=g+L[h+(f<<3)>>3]*+(f|0);f=(b|0)>4;b=b-4|0;if(f){continue}break}}if(O(o)<1e-13){break ba}b=o<0;n=b?C:l;g=b?y:o;l=n-g*((b?l:v)-n)/((b?o:t)-g)}o=0;f=e+1&3;if(f){b=0;while(1){o=o*l+L[((e<<3)+d|0)+4176>>3];e=e-1|0;b=b+1|0;if((f|0)!=(b|0)){continue}break}}while(1){b=(e<<3)+d|0;o=(((o*l+L[b+4176>>3])*l+L[b+4168>>3])*l+L[b+4160>>3])*l+L[b+4152>>3];b=(e|0)>3;e=e-4|0;if(b){continue}break}L[d+3248>>3]=o;L[d+3240>>3]=l}qg(d);Wa(z);Wa(x);Wa(s);Wa(A);Fa=k+160|0;if(G[d+6044>>2]|G[d+6040>>2]){b=0}else{b=1}if(b){E[d+3375|0]=78;b=7;break u}b=G[d+3260>>2]}if((b|0)!=35){break t}break v}b=H[c+1967|0];if((b|32)!=32){G[c>>2]=b<<24>>24;a=c+2032|0;db(a,30781,c);jd(a);break d}if(Pc(a,34954)){G[d+3260>>2]=31;e=Pc(a,34954);ob(e,34954,c+2944|0);ob(e,34681,c+2912|0);ob(e,33940,c+2904|0);L[d+152>>3]=(L[c+2944>>3]+L[c+2912>>3]/60+L[c+2904>>3]/3600)*15*3.141592653589793/180;E[c+1936|0]=43;ie(e,34400,1,c+1936|0);b=H[c+1936|0];ob(e,35836,c+2896|0);ob(e,34673,c+2888|0);ob(e,33915,c+2880|0);g=L[c+2896>>3]+L[c+2888>>3]/60+L[c+2880>>3]/3600;L[d+160>>3]=((b|0)==45?-g:g)*3.141592653589793/180;ob(a,32863,d+120|0);Md(a,32863,c+1952|0);b=G[c+1952>>2];L[d+128>>3]=L[d+120>>3];b=(b|0)==1950?3427142:3492678;E[d+3848|0]=b;E[d+3849|0]=b>>>8;E[d+3850|0]=b>>>16;E[d+3851|0]=b>>>24;ob(a,34948,d+128|0);G[c+808>>2]=d+3848;L[c+768>>3]=L[c+2904>>3];G[c+776>>2]=E[c+1936|0];L[c+784>>3]=L[c+2896>>3];L[c+792>>3]=L[c+2888>>3];L[c+800>>3]=L[c+2880>>3];L[c+752>>3]=L[c+2944>>3];L[c+760>>3]=L[c+2912>>3];Eb(d+3972|0,9081,c+752|0);ob(a,35652,d+168|0);ob(a,32664,d+192|0);ob(a,32655,d+200|0);ob(a,41208,d+176|0);ob(a,40806,d+184|0);f=Pc(a,41268);G[c+736>>2]=1;b=c+2128|0;db(b,29957,c+736|0);G[d+208>>2]=0;G[d+212>>2]=0;ob(f,b,d+208|0);G[c+720>>2]=2;db(b,29957,c+720|0);e=d+216|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,b,e);G[c+704>>2]=3;db(b,29957,c+704|0);e=d+224|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,b,e);G[c+688>>2]=4;db(b,29957,c+688|0);e=d+232|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,b,e);G[c+672>>2]=5;db(b,29957,c+672|0);e=d+240|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+656>>2]=6;db(b,29957,c+656|0);e=d+248|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);f=Pc(a,41223);G[c+640>>2]=1;db(b,29925,c+640|0);G[d+256>>2]=0;G[d+260>>2]=0;ob(f,b,d+256|0);G[c+624>>2]=2;db(b,29925,c+624|0);e=d+264|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+608>>2]=3;db(b,29925,c+608|0);e=d+272|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+592>>2]=4;db(b,29925,c+592|0);e=d+280|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+576>>2]=5;db(b,29925,c+576|0);e=d+288|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+560>>2]=6;db(b,29925,c+560|0);e=d+296|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+544>>2]=7;db(b,29925,c+544|0);e=d+304|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+528>>2]=8;db(b,29925,c+528|0);e=d+312|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+512>>2]=9;db(b,29925,c+512|0);e=d+320|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+496>>2]=10;db(b,29925,c+496|0);e=d+328|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+480>>2]=11;db(b,29925,c+480|0);e=d+336|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+464>>2]=12;db(b,29925,c+464|0);e=d+344|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+448>>2]=13;db(b,29925,c+448|0);e=d+352|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+432>>2]=14;db(b,29925,c+432|0);e=d+360|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+416>>2]=15;db(b,29925,c+416|0);e=d+368|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+400>>2]=16;db(b,29925,c+400|0);e=d+376|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+384>>2]=17;db(b,29925,c+384|0);e=d+384|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+368>>2]=18;db(b,29925,c+368|0);e=d+392|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+352>>2]=19;db(b,29925,c+352|0);e=d+400|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);G[c+336>>2]=20;db(b,29925,c+336|0);e=d+408|0;G[e>>2]=0;G[e+4>>2]=0;ob(f,c+2128|0,e);e=Pc(a,41195);G[c+320>>2]=1;db(b,29918,c+320|0);G[d+416>>2]=0;G[d+420>>2]=0;ob(e,b,d+416|0);G[c+304>>2]=2;db(b,29918,c+304|0);a=d+424|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,b,a);G[c+288>>2]=3;db(b,29918,c+288|0);a=d+432|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,b,a);G[c+272>>2]=4;db(b,29918,c+272|0);a=d+440|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,b,a);G[c+256>>2]=5;db(b,29918,c+256|0);a=d+448|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,c+2128|0,a);G[c+240>>2]=6;db(b,29918,c+240|0);a=d+456|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,c+2128|0,a);G[c+224>>2]=7;db(b,29918,c+224|0);a=d+464|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,c+2128|0,a);G[c+208>>2]=8;db(b,29918,c+208|0);a=d+472|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,c+2128|0,a);G[c+192>>2]=9;db(b,29918,c+192|0);a=d+480|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,c+2128|0,a);G[c+176>>2]=10;db(b,29918,c+176|0);a=d+488|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,c+2128|0,a);G[c+160>>2]=11;db(b,29918,c+160|0);a=d+496|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,c+2128|0,a);G[c+144>>2]=12;db(b,29918,c+144|0);a=d+504|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,c+2128|0,a);G[c+128>>2]=13;db(b,29918,c+128|0);a=d+512|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,c+2128|0,a);G[c+112>>2]=14;db(b,29918,c+112|0);a=d+520|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,c+2128|0,a);G[c+96>>2]=15;db(b,29918,c+96|0);a=d+528|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,c+2128|0,a);G[c+80>>2]=16;db(b,29918,c+80|0);a=d+536|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,c+2128|0,a);G[c+64>>2]=17;db(b,29918,c- -64|0);a=d+544|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,c+2128|0,a);G[c+48>>2]=18;db(b,29918,c+48|0);a=d+552|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,c+2128|0,a);G[c+32>>2]=19;db(b,29918,c+32|0);a=d+560|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,c+2128|0,a);G[c+16>>2]=20;db(b,29918,c+16|0);a=d+568|0;G[a>>2]=0;G[a+4>>2]=0;ob(e,b,a);G[d+3312>>2]=1;a=H[35967]|H[35968]<<8;E[d+3512|0]=a;E[d+3513|0]=a>>>8;E[d+3514|0]=H[35969];E[d+3544|0]=68;E[d+3545|0]=83;E[d+3546|0]=83;E[d+3547|0]=0;E[d+3528|0]=68;E[d+3529|0]=69;E[d+3530|0]=67;E[d+3531|0]=0;G[d+3288>>2]=3;G[d+3292>>2]=0;E[d+3376|0]=H[33746];b=H[33742]|H[33743]<<8|(H[33744]<<16|H[33745]<<24);a=H[33738]|H[33739]<<8|(H[33740]<<16|H[33741]<<24);E[d+3368|0]=a;E[d+3369|0]=a>>>8;E[d+3370|0]=a>>>16;E[d+3371|0]=a>>>24;E[d+3372|0]=b;E[d+3373|0]=b>>>8;E[d+3374|0]=b>>>16;E[d+3375|0]=b>>>24;b=H[33733]|H[33734]<<8|(H[33735]<<16|H[33736]<<24);e=d+3384|0;a=H[33729]|H[33730]<<8|(H[33731]<<16|H[33732]<<24);E[e|0]=a;E[e+1|0]=a>>>8;E[e+2|0]=a>>>16;E[e+3|0]=a>>>24;E[e+4|0]=b;E[e+5|0]=b>>>8;E[e+6|0]=b>>>16;E[e+7|0]=b>>>24;E[d+3392|0]=H[33737];n=L[d+136>>3]*.5;L[d+616>>3]=n;L[d+16>>3]=n;g=L[d+144>>3]*.5;L[d+24>>3]=g;L[d+624>>3]=g;Zg(n,g,d,c+2872|0,c+2856|0);n=L[c+2872>>3];L[d+688>>3]=n;g=L[c+2856>>3];L[d+8>>3]=g;L[d>>3]=n;L[d+696>>3]=g;b=c+2864|0;a=c+2848|0;Zg(L[d+616>>3],L[d+624>>3]+1,d,b,a);g=L[c+2848>>3]-L[c+2856>>3];L[d+40>>3]=g;L[d+32>>3]=-g;pj(d);G[d+3312>>2]=1;qg(d);t=L[d+48>>3]*3.141592653589793/180;L[c+1944>>3]=t;n=L[d+624>>3];g=ib(t);Zg(L[d+616>>3]+eb(t),n+g,d,b,a);N=d,P=-pg(L[c+2872>>3],L[c+2856>>3],L[c+2864>>3],L[c+2848>>3]),L[N+760>>3]=P;t=L[d+624>>3];n=L[c+1944>>3];g=eb(n);Zg(L[d+616>>3]+ib(n),t+g,d,b,a);g=pg(L[c+2872>>3],L[c+2856>>3],L[c+2864>>3],L[c+2848>>3]);L[d+768>>3]=g;rj(d,L[d+760>>3],g,L[d+48>>3]);break s}ma:{na:{if(Pc(a,32970)){break na}if(Pc(a,35643)){break na}if(Pc(a,41286)){break na}if(Pc(a,35348)){break na}if(!Pc(a,41215)){break ma}}G[c+2880>>2]=0;G[c+2884>>2]=0;ob(a,32970,c+2880|0);g=L[c+2880>>3];if(g==0){ob(a,35643,c+2880|0);g=L[c+2880>>3]}oa:{if(g==0){ob(a,41215,c+2880|0);g=L[c+2880>>3];if(g!=0){L[c+2840>>3]=g/-3600;ob(a,40813,c+2880|0);L[c+2832>>3]=L[c+2880>>3]/3600;break oa}ob(a,35348,c+2880|0);g=L[c+2880>>3];if(g!=0){L[c+2840>>3]=g/-3600;ob(a,35339,c+2880|0);L[c+2832>>3]=L[c+2880>>3]/3600;break oa}b=c+2880|0;ob(a,41286,b);L[c+2840>>3]=L[c+2880>>3]/-3600;ob(a,40873,b);L[c+2832>>3]=L[c+2880>>3]/3600;break oa}g=g/3600;L[c+2832>>3]=g;L[c+2840>>3]=-g}G[c+1944>>2]=0;G[c+1948>>2]=0;ob(a,41309,c+1944|0);if(L[d+48>>3]==0){ob(a,40896,c+1944|0)}rj(d,L[c+2840>>3],L[c+2832>>3],L[c+1944>>3]);L[d+616>>3]=L[d+136>>3]*.5+.5;b=d+624|0;L[b>>3]=L[d+144>>3]*.5+.5;if(Pc(a,41201)){ob(a,41201,d+616|0);ob(a,40799,b)}G[d+688>>2]=0;G[d+692>>2]=-1064355840;L[d+16>>3]=L[d+616>>3];L[d+24>>3]=L[d+624>>3];b=Ye(a,35967);if(b){g=Km(b);N=d,P=ec(b,40241,Va(b))?g*15:g,L[N+688>>3]=P;b=1}else{b=0}if(!b){jd(33880);break d}e=d+696|0;G[e>>2]=0;G[e+4>>2]=-1064355840;b=Ye(a,35895);if(b){N=e,P=Km(b),L[N>>3]=P;b=1}else{b=0}if(!b){jd(33845);break d}G[d+3304>>2]=0;n=L[d+688>>3];L[d>>3]=n;b=d+4088|0;G[b>>2]=0;G[b+4>>2]=1083127808;g=L[d+696>>3];L[d+4080>>3]=g;L[d+4072>>3]=n;L[d+8>>3]=g;if(!ob(a,35545,b)){ob(a,35553,b)}b=d+4096|0;G[b>>2]=0;G[b+4>>2]=1083127808;ob(a,35537,b);pa:{if(ob(a,33932,c+1952|0)){L[d+128>>3]=(L[c+1952>>3]+-15019.81352)/365.242198781+1900;break pa}e=d+128|0;if(!vg(a,33923,e)){if(vg(a,35389,e)){break pa}if(ob(a,34948,e)){break pa}L[d+128>>3]=L[d+120>>3];break pa}b=c+2912|0;ie(a,33923,32,b);if(jb(b,84)){break pa}if(ob(a,33299,c+1936|0)){L[e>>3]=L[e>>3]+L[c+1936>>3]/8765.812770744;break pa}if(!ob(a,35806,c+1936|0)){break pa}L[e>>3]=L[e>>3]+L[c+1936>>3]/8765.812770744}tm(d,34601,34592);G[d+3304>>2]=0;E[c+2944|0]=0;pm(a,d,c+2944|0);pj(d);G[d+3312>>2]=1;G[d+3288>>2]=3;G[d+3292>>2]=0;break s}jd(23641);break d}E[d+3390|0]=65;F[d+3374>>1]=20033;b=3}G[d+3260>>2]=b;E[d+3391|0]=78}if(G[d+3324>>2]>0){pm(a,d,c+1967|0)}pj(d);p=a;a=0;m=Fa-80|0;Fa=m;qa:{if(G[d+6048>>2]!=1){break qa}if(G[d+3324>>2]==2){G[d+6056>>2]=0;G[d+3324>>2]=3;G[d+8480>>2]=0;G[d+7672>>2]=0;G[d+6864>>2]=0;break qa}b=d+6056|0;ra:{if(!Md(p,34126,b)){jd(13771);break ra}h=G[b>>2];if((h|0)<0){break ra}b=h+1|0;f=b&3;i=(h<<3)+8|0;if(h>>>0>=3){e=b&-4;b=0;while(1){cb((M(a,80)+d|0)+6064|0,0,i);cb((M(a|1,80)+d|0)+6064|0,0,i);cb((M(a|2,80)+d|0)+6064|0,0,i);cb((M(a|3,80)+d|0)+6064|0,0,i);a=a+4|0;b=b+4|0;if((e|0)!=(b|0)){continue}break}}if(f){b=0;while(1){cb((M(a,80)+d|0)+6064|0,0,i);a=a+1|0;b=b+1|0;if((f|0)!=(b|0)){continue}break}}e=0;if((h|0)<0){break ra}b=h+1|0;while(1){a=0;if((e|0)<=(h|0)){while(1){G[m+48>>2]=e;G[m+52>>2]=a;f=m+68|0;db(f,29871,m+48|0);ob(p,f,((M(e,80)+d|0)+(a<<3)|0)+6064|0);a=a+1|0;if((b|0)!=(a|0)){continue}break}}b=b-1|0;a=(e|0)!=(h|0);e=e+1|0;if(a){continue}break}}b=d+6864|0;sa:{if(!Md(p,34118,b)){jd(13714);break sa}a=0;h=G[b>>2];if((h|0)<0){break sa}b=h+1|0;f=b&3;i=(h<<3)+8|0;if(h>>>0>=3){e=b&-4;b=0;while(1){cb((M(a,80)+d|0)+6872|0,0,i);cb((M(a|1,80)+d|0)+6872|0,0,i);cb((M(a|2,80)+d|0)+6872|0,0,i);cb((M(a|3,80)+d|0)+6872|0,0,i);a=a+4|0;b=b+4|0;if((e|0)!=(b|0)){continue}break}}if(f){b=0;while(1){cb((M(a,80)+d|0)+6872|0,0,i);a=a+1|0;b=b+1|0;if((f|0)!=(b|0)){continue}break}}e=0;if((h|0)<0){break sa}b=h+1|0;while(1){a=0;if((e|0)<=(h|0)){while(1){G[m+32>>2]=e;G[m+36>>2]=a;f=m+68|0;db(f,29863,m+32|0);ob(p,f,((M(e,80)+d|0)+(a<<3)|0)+6872|0);a=a+1|0;if((b|0)!=(a|0)){continue}break}}b=b-1|0;a=(e|0)!=(h|0);e=e+1|0;if(a){continue}break}}b=d+7672|0;ta:{if(!Md(p,34109,b)){jd(13656);break ta}a=0;h=G[b>>2];if((h|0)<0){break ta}b=h+1|0;f=b&3;i=(h<<3)+8|0;if(h>>>0>=3){e=b&-4;b=0;while(1){cb((M(a,80)+d|0)+7680|0,0,i);cb((M(a|1,80)+d|0)+7680|0,0,i);cb((M(a|2,80)+d|0)+7680|0,0,i);cb((M(a|3,80)+d|0)+7680|0,0,i);a=a+4|0;b=b+4|0;if((e|0)!=(b|0)){continue}break}}if(f){b=0;while(1){cb((M(a,80)+d|0)+7680|0,0,i);a=a+1|0;b=b+1|0;if((f|0)!=(b|0)){continue}break}}e=0;if((h|0)<0){break ta}b=h+1|0;while(1){a=0;if((e|0)<=(h|0)){while(1){G[m+16>>2]=e;G[m+20>>2]=a;f=m+68|0;db(f,29854,m+16|0);ob(p,f,((M(e,80)+d|0)+(a<<3)|0)+7680|0);a=a+1|0;if((b|0)!=(a|0)){continue}break}}b=b-1|0;a=(e|0)!=(h|0);e=e+1|0;if(a){continue}break}}b=d+8480|0;if(!Md(p,34100,b)){jd(13598);break qa}a=0;h=G[b>>2];if((h|0)<0){break qa}b=h+1|0;f=b&3;i=(h<<3)+8|0;if(h>>>0>=3){e=b&-4;b=0;while(1){cb((M(a,80)+d|0)+8488|0,0,i);cb((M(a|1,80)+d|0)+8488|0,0,i);cb((M(a|2,80)+d|0)+8488|0,0,i);cb((M(a|3,80)+d|0)+8488|0,0,i);a=a+4|0;b=b+4|0;if((e|0)!=(b|0)){continue}break}}if(f){b=0;while(1){cb((M(a,80)+d|0)+8488|0,0,i);a=a+1|0;b=b+1|0;if((f|0)!=(b|0)){continue}break}}e=0;if((h|0)<0){break qa}b=h+1|0;while(1){a=0;if((e|0)<=(h|0)){while(1){G[m>>2]=e;G[m+4>>2]=a;f=m+68|0;db(f,29845,m);ob(p,f,((M(e,80)+d|0)+(a<<3)|0)+8488|0);a=a+1|0;if((b|0)!=(a|0)){continue}break}}b=b-1|0;a=(e|0)!=(h|0);e=e+1|0;if(a){continue}break}}Fa=m+80|0;G[d+3268>>2]=0;G[d+3272>>2]=0;i=c+1967|0;a=c+2800|0;f=Zb(p,41174,i,a);e=Zb(p,40778,i,a|8);b=Zb(p,41149,i,D);a=Zb(p,40759,i,J);ua:{va:{if(G[d+3324>>2]==2){break va}i=Pc(p,41161);if(!i){break va}e=d+3268|0;G[d+3260>>2]=32;a=H[35383]|H[35384]<<8|(H[35385]<<16|H[35386]<<24);E[d+3544|0]=a;E[d+3545|0]=a>>>8;E[d+3546|0]=a>>>16;E[d+3547|0]=a>>>24;b=d+3548|0;a=H[35387]|H[35388]<<8;E[b|0]=a;E[b+1|0]=a>>>8;G[c+1504>>2]=1;a=c+2128|0;db(a,29911,c+1504|0);G[d+256>>2]=0;G[d+260>>2]=0;if(ob(i,a,d+256|0)){G[e>>2]=1}G[c+1488>>2]=2;a=c+2128|0;db(a,29911,c+1488|0);b=d+264|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=2}G[c+1472>>2]=3;a=c+2128|0;db(a,29911,c+1472|0);b=d+272|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=3}G[c+1456>>2]=4;a=c+2128|0;db(a,29911,c+1456|0);b=d+280|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=4}G[c+1440>>2]=5;a=c+2128|0;db(a,29911,c+1440|0);b=d+288|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=5}G[c+1424>>2]=6;a=c+2128|0;db(a,29911,c+1424|0);b=d+296|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=6}G[c+1408>>2]=7;a=c+2128|0;db(a,29911,c+1408|0);b=d+304|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=7}G[c+1392>>2]=8;a=c+2128|0;db(a,29911,c+1392|0);b=d+312|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=8}G[c+1376>>2]=9;a=c+2128|0;db(a,29911,c+1376|0);b=d+320|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=9}G[c+1360>>2]=10;a=c+2128|0;db(a,29911,c+1360|0);b=d+328|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=10}G[c+1344>>2]=11;a=c+2128|0;db(a,29911,c+1344|0);b=d+336|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=11}G[c+1328>>2]=12;a=c+2128|0;db(a,29911,c+1328|0);b=d+344|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=12}G[c+1312>>2]=13;a=c+2128|0;db(a,29911,c+1312|0);b=d+352|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=13}G[c+1296>>2]=14;a=c+2128|0;db(a,29911,c+1296|0);b=d+360|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=14}G[c+1280>>2]=15;a=c+2128|0;db(a,29911,c+1280|0);b=d+368|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=15}G[c+1264>>2]=16;a=c+2128|0;db(a,29911,c+1264|0);b=d+376|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=16}G[c+1248>>2]=17;a=c+2128|0;db(a,29911,c+1248|0);b=d+384|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=17}G[c+1232>>2]=18;a=c+2128|0;db(a,29911,c+1232|0);b=d+392|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=18}G[c+1216>>2]=19;a=c+2128|0;db(a,29911,c+1216|0);b=d+400|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=19}G[c+1200>>2]=20;a=c+2128|0;db(a,29911,c+1200|0);b=d+408|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(i,a,b)){G[e>>2]=20}f=d+3272|0;e=Pc(p,41136);G[c+1184>>2]=1;a=c+2128|0;db(a,29904,c+1184|0);G[d+416>>2]=0;G[d+420>>2]=0;if(ob(e,a,d+416|0)){G[f>>2]=1}G[c+1168>>2]=2;a=c+2128|0;db(a,29904,c+1168|0);b=d+424|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=2}G[c+1152>>2]=3;a=c+2128|0;db(a,29904,c+1152|0);b=d+432|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=3}G[c+1136>>2]=4;a=c+2128|0;db(a,29904,c+1136|0);b=d+440|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=4}G[c+1120>>2]=5;a=c+2128|0;db(a,29904,c+1120|0);b=d+448|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=5}G[c+1104>>2]=6;a=c+2128|0;db(a,29904,c+1104|0);b=d+456|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=6}G[c+1088>>2]=7;a=c+2128|0;db(a,29904,c+1088|0);b=d+464|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=7}G[c+1072>>2]=8;a=c+2128|0;db(a,29904,c+1072|0);b=d+472|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=8}G[c+1056>>2]=9;a=c+2128|0;db(a,29904,c+1056|0);b=d+480|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=9}G[c+1040>>2]=10;a=c+2128|0;db(a,29904,c+1040|0);b=d+488|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=10}G[c+1024>>2]=11;a=c+2128|0;db(a,29904,c+1024|0);b=d+496|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=11}G[c+1008>>2]=12;a=c+2128|0;db(a,29904,c+1008|0);b=d+504|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=12}G[c+992>>2]=13;a=c+2128|0;db(a,29904,c+992|0);b=d+512|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=13}G[c+976>>2]=14;a=c+2128|0;db(a,29904,c+976|0);b=d+520|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=14}G[c+960>>2]=15;a=c+2128|0;db(a,29904,c+960|0);b=d+528|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=15}G[c+944>>2]=16;a=c+2128|0;db(a,29904,c+944|0);b=d+536|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=16}G[c+928>>2]=17;a=c+2128|0;db(a,29904,c+928|0);b=d+544|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=17}G[c+912>>2]=18;a=c+2128|0;db(a,29904,c+912|0);b=d+552|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=18}G[c+896>>2]=19;a=c+2128|0;db(a,29904,c+896|0);b=d+560|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=19}G[c+880>>2]=20;a=c+2128|0;db(a,29904,c+880|0);b=d+568|0;G[b>>2]=0;G[b+4>>2]=0;if(ob(e,a,b)){G[f>>2]=20}rg(L[d+616>>3],L[d+624>>3],d,c+2872|0,c+2856|0);b=c+2864|0;a=c+2848|0;rg(L[d+616>>3],L[d+624>>3]+1,d,b,a);n=L[c+2856>>3];g=L[c+2848>>3];G[d+3312>>2]=1;g=g-n;L[d+40>>3]=g;L[d+32>>3]=-g;qg(d);L[c+1944>>3]=L[d+48>>3]*3.141592653589793/180;rg(L[d+616>>3],L[d+624>>3],d,c+2872|0,c+2856|0);t=L[d+624>>3];n=L[c+1944>>3];g=ib(n);rg(L[d+616>>3]+eb(n),t+g,d,b,a);g=-pg(L[c+2872>>3],L[c+2856>>3],L[c+2864>>3],L[c+2848>>3]);L[d+32>>3]=g;L[d+760>>3]=g;t=L[d+624>>3];n=L[c+1944>>3];g=eb(n);rg(L[d+616>>3]+ib(n),t+g,d,b,a);g=pg(L[c+2872>>3],L[c+2856>>3],L[c+2864>>3],L[c+2848>>3]);L[d+40>>3]=g;L[d+768>>3]=g;L[d+56>>3]=L[c+2800>>3];L[d- -64>>3]=L[c+2808>>3];L[d+72>>3]=L[c+2816>>3];L[d+80>>3]=L[c+2824>>3];sg(2,d+56|0,d+88|0);break ua}wa:{if(!(b|(e|f))){if(!a){break wa}}G[d+3300>>2]=1;a=c+2800|0;if(a){G[d+3300>>2]=1;L[d+56>>3]=L[a>>3];L[d- -64>>3]=L[a+8>>3];L[d+72>>3]=L[a+16>>3];L[d+80>>3]=L[a+24>>3];sg(2,d+56|0,d+88|0);g=L[a>>3];n=g*g;g=L[a+16>>3];L[d+32>>3]=V(n+g*g);g=L[a+8>>3];n=g*g;g=L[a+24>>3];L[d+40>>3]=V(n+g*g);if(G[d+3304>>2]){g=L[a+16>>3];L[a+16>>3]=-L[a+8>>3];L[a+8>>3]=-g}rm(d);G[d+3312>>2]=1;qg(d);L[d+760>>3]=L[d+32>>3];L[d+768>>3]=L[d+40>>3]}break ua}if(Zb(p,41234,c+1967|0,c+2840|0)){Zb(p,40826,c+1967|0,c+2832|0);xa:{if(L[c+2840>>3]!=0){g=L[c+2832>>3];if(!(L[B>>3]>1)|g!=0){break xa}}ya:{za:{if(Pc(p,32970)){break za}if(Pc(p,35643)){break za}if(Pc(p,41286)){break za}if(Pc(p,35348)){break za}if(!Pc(p,41215)){break ya}}G[c+2880>>2]=0;G[c+2884>>2]=0;ob(p,32970,c+2880|0);o=L[c+2880>>3];if(o==0){ob(p,35643,c+2880|0);o=L[c+2880>>3]}if(o==0){ob(p,41215,c+2880|0);g=L[c+2880>>3];if(g!=0){if(L[c+2840>>3]==0){L[c+2840>>3]=g/-3600}g=L[c+2832>>3];if(g!=0){break xa}ob(p,40813,c+2880|0);g=L[c+2880>>3]/3600;L[c+2832>>3]=g;break xa}ob(p,35348,c+2880|0);g=L[c+2880>>3];if(g!=0){if(L[c+2840>>3]==0){L[c+2840>>3]=g/-3600}g=L[c+2832>>3];if(g!=0){break xa}ob(p,35339,c+2880|0);g=L[c+2880>>3]/3600;L[c+2832>>3]=g;break xa}ob(p,41286,c+2880|0);g=L[c+2880>>3];if(!(g==0|L[c+2840>>3]!=0)){L[c+2840>>3]=g/-3600}g=L[c+2832>>3];if(g!=0){break xa}ob(p,40873,c+2880|0);g=L[c+2880>>3]/3600;L[c+2832>>3]=g;break xa}if(L[c+2840>>3]==0){L[c+2840>>3]=o/-3600}g=L[c+2832>>3];if(g!=0){break xa}g=o/3600;L[c+2832>>3]=g;break xa}g=L[c+2832>>3]}if(!(!(L[B>>3]>1)|g!=0)){L[c+2832>>3]=-L[c+2840>>3]}G[d+784>>2]=0;G[d+788>>2]=1072693248;G[d+776>>2]=0;G[d+780>>2]=1072693248;b=0;cb(c+2144|0,0,648);cb(K,0,648);i=G[c+2120>>2];Aa:{if((i|0)<=0){break Aa}if(i-1>>>0>=3){e=i&-4;j=0;while(1){f=c+2144|0;a=f+(M(b,i)+b<<3)|0;G[a>>2]=0;G[a+4>>2]=1072693248;a=b|1;a=f+(M(a,i)+a<<3)|0;G[a>>2]=0;G[a+4>>2]=1072693248;a=b|2;a=f+(M(a,i)+a<<3)|0;G[a>>2]=0;G[a+4>>2]=1072693248;a=b|3;a=(M(a,i)+a<<3)+f|0;G[a>>2]=0;G[a+4>>2]=1072693248;b=b+4|0;j=j+4|0;if((e|0)!=(j|0)){continue}break}}e=i&3;if(!e){break Aa}j=0;while(1){a=(c+2144|0)+(M(b,i)+b<<3)|0;G[a>>2]=0;G[a+4>>2]=1072693248;b=b+1|0;j=j+1|0;if((e|0)!=(j|0)){continue}break}}Ba:{if(H[c+1967|0]){break Ba}if(!ob(p,41366,c+2144|0)){break Ba}j=G[c+2120>>2];if((j|0)>0){e=0;f=0;while(1){b=0;G[c+2124>>2]=0;a=e+1|0;if((j|0)>0){while(1){q=(c+2144|0)+(f<<3)|0;L[q>>3]=(b|0)==(e|0)?1:0;G[c+864>>2]=a;G[c+868>>2]=b+1;b=c+2128|0;db(b,29818,c+864|0);ob(p,b,q);b=G[c+2124>>2]+1|0;G[c+2124>>2]=b;f=f+1|0;j=G[c+2120>>2];if((j|0)>(b|0)){continue}break}}e=a;if((j|0)>(a|0)){continue}break}}qm(d,L[c+2840>>3],L[c+2832>>3],c+2144|0);break ua}if(Zb(p,41180,c+1967|0,c+2144|0)){j=G[c+2120>>2];if((j|0)>0){e=0;f=0;while(1){b=0;G[c+2124>>2]=0;a=e+1|0;if((j|0)>0){while(1){q=(c+2144|0)+(f<<3)|0;L[q>>3]=(b|0)==(e|0)?1:0;G[c+848>>2]=a;G[c+852>>2]=b+1;b=c+2128|0;db(b,29808,c+848|0);Zb(p,b,c+1967|0,q);b=G[c+2124>>2]+1|0;G[c+2124>>2]=b;f=f+1|0;j=G[c+2120>>2];if((j|0)>(b|0)){continue}break}}e=a;if((j|0)>(a|0)){continue}break}}qm(d,L[c+2840>>3],L[c+2832>>3],c+2144|0);break ua}G[c+1944>>2]=0;G[c+1948>>2]=0;Zb(p,q?40896:41309,c+1967|0,c+1944|0);rj(d,L[c+2840>>3],L[c+2832>>3],L[c+1944>>3]);break ua}G[d+40>>2]=0;G[d+44>>2]=1072693248;G[d+32>>2]=0;G[d+36>>2]=1072693248;G[d+3300>>2]=0;G[d+48>>2]=0;G[d+52>>2]=0;G[d+768>>2]=0;G[d+772>>2]=1072693248;G[d+760>>2]=0;G[d+764>>2]=1072693248;jd(41398)}Ca:{if(G[d+3260>>2]!=3|G[d+3316>>2]!=2){break Ca}a=G[d+3168>>2];if(a){tg(a);G[d+3168>>2]=0}a=G[d+3172>>2];if(a){tg(a);G[d+3172>>2]=0}f=0;G[d+1560>>2]=0;cb(d+1568|0,0,1600);cb(d+4424|0,0,1600);G[c+2124>>2]=0;j=0;while(1){G[c+836>>2]=j;G[c+832>>2]=1;a=c+2128|0;db(a,29879,c+832|0);Da:{if(!Zb(p,a,c+1967|0,((G[c+2124>>2]<<3)+d|0)+1568|0)){b=G[c+2124>>2];a=((b<<3)+d|0)+1568|0;G[a>>2]=0;G[a+4>>2]=0;break Da}f=f+1|0;b=G[c+2124>>2]}j=b+1|0;G[c+2124>>2]=j;if((b|0)<99){continue}break}j=0;G[c+2124>>2]=0;while(1){G[c+820>>2]=j;G[c+816>>2]=2;a=c+2128|0;db(a,29879,c+816|0);Ea:{if(Zb(p,a,c+1967|0,((G[c+2124>>2]<<3)+d|0)+2368|0)){f=f+1|0;b=G[c+2124>>2];break Ea}b=G[c+2124>>2];a=((b<<3)+d|0)+2368|0;G[a>>2]=0;G[a+4>>2]=0}j=b+1|0;G[c+2124>>2]=j;if((b|0)<99){continue}break}if(G[d+6048>>2]==1|(f|0)<=0){break Ca}b=100;i=M(G[d+4024>>2],100);q=M(G[d+4028>>2],100);h=d+1568|0;while(1){e=b<<3;a=e+d|0;L[a+4424>>3]=L[h+(b+q<<3)>>3];L[a+5224>>3]=L[h+(b+i<<3)>>3];if(b){a=d+4424|0;f=b-1|0;L[a+(f<<3)>>3]=L[h+(f+q<<3)>>3];L[(a+e|0)+792>>3]=L[h+(f+i<<3)>>3];b=b-2|0;continue}break}k=Fa-224|0;Fa=k;G[k+168>>2]=1;G[k+172>>2]=1;Fa:{if(G[d+3316>>2]!=2){break Fa}b=G[d+4028>>2];h=G[d+4024>>2];u=d+4008|0;if(Xa(u,34606)|L[(M(h,800)+d|0)+1576>>3]==0&L[(M(b,800)+d|0)+1576>>3]==0){break Fa}a=G[d+9392>>2];Ga:{if(a){cc(a,0,0,k+72|0,k- -64|0);cc(G[d+9392>>2],L[d+136>>3],L[d+144>>3],k+56|0,k+48|0);break Ga}G[k+64>>2]=0;G[k+68>>2]=0;G[k+72>>2]=0;G[k+76>>2]=0;L[k+56>>3]=L[d+136>>3];L[k+48>>3]=L[d+144>>3]}Ha:{if(!h){g=L[k+64>>3];o=L[k+48>>3]-g;t=L[k+72>>3];n=L[k+56>>3]-t;break Ha}g=L[k+72>>3];o=L[k+56>>3]-g;t=L[k+64>>3];n=L[k+48>>3]-t}e=lb(288,8);i=lb(144,8);q=lb(144,8);f=b<<3;b=k+192|0;B=f+b|0;g=g+.5;L[B>>3]=g;a=k+176|0;D=a+f|0;L[D>>3]=g;m=b;b=h<<3;z=m+b|0;g=t+.5;L[z>>3]=g;j=a+b|0;L[j>>3]=g;J=d+4144|0;x=d+4036|0;n=n/11;g=o/11;a=k+208|0;s=a+f|0;A=a+b|0;r=11;a=e;b=q;w=i;while(1){m=r;L[z>>3]=L[j>>3];f=11;while(1){if(Yh(k+192|0,x,k+208|0)){G[k+32>>2]=u;h=k+80|0;db(h,9038,k+32|0);jd(h)}L[w>>3]=L[A>>3];L[b>>3]=L[s>>3];vm(J,L[A>>3],L[s>>3],a,a+8|0);L[z>>3]=n+L[z>>3];h=f;f=f-1|0;a=a+16|0;b=b+8|0;w=w+8|0;if(h){continue}break}L[B>>3]=g+L[B>>3];r=m-1|0;if(m){continue}break}a=k+208|0;Yh(k+176|0,x,a);L[A>>3]=L[A>>3]+.0002777777777777778;zj(a,x,k+192|0);g=L[z>>3]-L[j>>3];n=g*g;g=L[B>>3]-L[D>>3];g=V(n+g*g)*3600;if(g==0){G[k+16>>2]=u;a=k+80|0;db(a,9038,k+16|0);jd(a)}G[k+164>>2]=1;g=.04/g;r=0;a=1;Ia:{while(1){if((a|0)>=2){tg(r)}r=Im(k+168|0,k+164|0);Gm(r,e,i);f=143;a=e;b=i;Ja:{while(1){h=g>3]);if(h){break Ja}h=f;f=f-1|0;a=a+16|0;b=b+8|0;if(h){continue}break}G[k+164>>2]=G[k+164>>2]+1;break Ia}b=G[k+164>>2];a=b+1|0;G[k+164>>2]=a;if(h&(b|0)<=8){continue}break}jd(14561);G[d+1560>>2]=1}G[d+3168>>2]=r;G[d+6024>>2]=r;a=k+208|0;Yh(k+176|0,x,a);L[s>>3]=L[s>>3]+.0002777777777777778;zj(a,x,k+192|0);g=L[z>>3]-L[j>>3];n=g*g;g=L[B>>3]-L[D>>3];g=V(n+g*g)*3600;if(g==0){G[k>>2]=u;a=k+80|0;db(a,9038,k);jd(a)}G[k+164>>2]=1;g=.04/g;a=1;Ka:{while(1){if((a|0)>=2){tg(r)}r=Im(k+168|0,k+164|0);Gm(r,e,q);f=143;a=e;b=q;La:{while(1){h=g>3]);if(h){break La}h=f;f=f-1|0;a=a+16|0;b=b+8|0;if(h){continue}break}G[k+164>>2]=G[k+164>>2]+1;break Ka}b=G[k+164>>2];a=b+1|0;G[k+164>>2]=a;if(h&(b|0)<=8){continue}break}jd(14561);G[d+1560>>2]=1}G[d+3172>>2]=r;G[d+6028>>2]=r;Wa(e);Wa(i);Wa(q)}Fa=k+224|0;G[d+4064>>2]=0}a=d+3544|0;Ma:{if(fb(a,34142,6)){if(fb(a,34781,5)){break Ma}}G[d+3288>>2]=5;G[d+3292>>2]=-1}Na:{if(ob(p,33932,c+1952|0)){L[d+128>>3]=(L[c+1952>>3]+-15019.81352)/365.242198781+1900;break Na}b=d+128|0;if(!vg(p,33923,b)){if(vg(p,35389,b)){break Na}if(ob(p,34948,b)){break Na}L[d+128>>3]=L[d+120>>3];break Na}a=c+2912|0;ie(p,33923,32,a);if(jb(a,84)){break Na}if(ob(p,33299,c+1936|0)){L[b>>3]=L[b>>3]+L[c+1936>>3]/8765.812770744;break Na}if(!ob(p,35806,c+1936|0)){break Na}L[b>>3]=L[b>>3]+L[c+1936>>3]/8765.812770744}G[d+3312>>2]=1}G[d+3328>>2]=0;G[d+3296>>2]=0;G[d+3284>>2]=1;G[d+4052>>2]=I;G[d+4044>>2]=d+616;G[d+4048>>2]=K;e=0;w=Fa-32|0;Fa=w;if(!(!d|!G[d+3312>>2])){while(1){Oa:{if(!e){G[w+24>>2]=H[35802]|H[35803]<<8|(H[35804]<<16|H[35805]<<24);a=H[35798]|H[35799]<<8|(H[35800]<<16|H[35801]<<24);G[w+16>>2]=H[35794]|H[35795]<<8|(H[35796]<<16|H[35797]<<24);G[w+20>>2]=a;break Oa}G[w>>2]=e;db(w+16|0,29995,w)}a=e<<2;i=G[a+1285504>>2];Pa:{if(i){if(!G[d+3312>>2]){break Pa}m=Va(i);if((m|0)<=0){break Pa}h=(a+d|0)+9288|0;a=G[h>>2];if(a){Wa(a)}a=lb(m+2|0,1);G[h>>2]=a;if(!a){break Pa}a=0;if((m|0)!=1){f=m&-2;u=0;while(1){b=H[a+i|0];E[G[h>>2]+a|0]=(b|0)==95?32:b;b=a|1;q=H[b+i|0];E[b+G[h>>2]|0]=(q|0)==95?32:q;a=a+2|0;u=u+2|0;if((f|0)!=(u|0)){continue}break}}if(m&1){b=G[h>>2]+a|0;a=H[a+i|0];E[b|0]=(a|0)==95?32:a}E[m+G[h>>2]|0]=0;break Pa}i=Fd(w+16|0);if(i){if(!G[d+3312>>2]){break Pa}m=Va(i);if((m|0)<=0){break Pa}h=(a+d|0)+9288|0;a=G[h>>2];if(a){Wa(a)}a=lb(m+2|0,1);G[h>>2]=a;if(!a){break Pa}a=0;if((m|0)!=1){f=m&-2;u=0;while(1){b=H[a+i|0];E[G[h>>2]+a|0]=(b|0)==95?32:b;b=a|1;q=H[b+i|0];E[b+G[h>>2]|0]=(q|0)==95?32:q;a=a+2|0;u=u+2|0;if((f|0)!=(u|0)){continue}break}}if(m&1){b=G[h>>2]+a|0;a=H[a+i|0];E[b|0]=(a|0)==95?32:a}E[m+G[h>>2]|0]=0;break Pa}Qa:{switch(e-1|0){case 0:if(!G[d+3312>>2]){break Pa}a=G[d+9292>>2];if(a){Wa(a)}a=lb(13,1);G[d+9292>>2]=a;if(!a){break Pa}E[a+8|0]=32;E[a+9|0]=37;E[a+10|0]=115;E[a+11|0]=0;E[a|0]=115;E[a+1|0]=117;E[a+2|0]=97;E[a+3|0]=50;E[a+4|0]=32;E[a+5|0]=45;E[a+6|0]=97;E[a+7|0]=104;break Pa;case 1:if(!G[d+3312>>2]){break Pa}a=G[d+9296>>2];if(a){Wa(a)}a=lb(13,1);G[d+9296>>2]=a;if(!a){break Pa}E[a+8|0]=32;E[a+9|0]=37;E[a+10|0]=115;E[a+11|0]=0;E[a|0]=115;E[a+1|0]=103;E[a+2|0]=115;E[a+3|0]=99;E[a+4|0]=32;E[a+5|0]=45;E[a+6|0]=97;E[a+7|0]=104;break Pa;case 2:if(!G[d+3312>>2]){break Pa}a=G[d+9300>>2];if(a){Wa(a)}a=lb(13,1);G[d+9300>>2]=a;if(!a){break Pa}E[a+8|0]=32;E[a+9|0]=37;E[a+10|0]=115;E[a+11|0]=0;E[a|0]=115;E[a+1|0]=116;E[a+2|0]=121;E[a+3|0]=50;E[a+4|0]=32;E[a+5|0]=45;E[a+6|0]=97;E[a+7|0]=104;break Pa;case 3:if(!G[d+3312>>2]){break Pa}a=G[d+9304>>2];if(a){Wa(a)}a=lb(13,1);G[d+9304>>2]=a;if(!a){break Pa}E[a+8|0]=32;E[a+9|0]=37;E[a+10|0]=115;E[a+11|0]=0;E[a|0]=115;E[a+1|0]=112;E[a+2|0]=112;E[a+3|0]=109;E[a+4|0]=32;E[a+5|0]=45;E[a+6|0]=97;E[a+7|0]=104;break Pa;case 4:if(!G[d+3312>>2]){break Pa}a=G[d+9308>>2];if(a){Wa(a)}a=lb(13,1);G[d+9308>>2]=a;if(!a){break Pa}E[a+8|0]=32;E[a+9|0]=37;E[a+10|0]=115;E[a+11|0]=0;E[a|0]=115;E[a+1|0]=115;E[a+2|0]=97;E[a+3|0]=111;E[a+4|0]=32;E[a+5|0]=45;E[a+6|0]=97;E[a+7|0]=104;break Pa;default:break Qa}}G[(a+d|0)+9288>>2]=0}e=e+1|0;if((e|0)!=10){continue}break}}Fa=w+32|0;break c}Ce(d);d=0}Fa=c+3008|0;return d}function Wt(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,J=0,K=0,L=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0;_=Fa-16|0;Fa=_;if(G[a+5060>>2]!=4){w=a;Z=c;x=_+12|0;if(x){G[x>>2]=0}a:{b:{c:{d:{e:{if(!w){break e}G[w+5060>>2]=0;if(!b){break e}if((Z|0)>=0){break d}}if(x){G[x>>2]=-2}a=0;if(!w){break a}G[w+5060>>2]=-2;break b}if(H[w+5008|0]){if(x){G[x>>2]=-1}G[w+5060>>2]=-1;break b}if(!Z){if(x){G[x>>2]=0}G[w+5060>>2]=0;break b}G[w+5028>>2]=b;G[w+5032>>2]=Z;ba=w+4|0;$=w+5012|0;while(1){b=G[w>>2];f:{if(G[b+76>>2]<0){a=G[b>>2];break f}a=G[b>>2]}if(a>>>5&1){break c}g:{if(G[w+5016>>2]){break g}a=Tf(b);if((a|0)==-1){break g}ak(a,b);b=zc(ba,1,5e3,G[w>>2]);a=G[w>>2];h:{if(G[a+76>>2]<0){a=G[a>>2];break h}a=G[a>>2]}if(a>>>5&1){break c}G[w+5016>>2]=b;G[w+5004>>2]=b;G[w+5012>>2]=ba}S=Fa-32|0;Fa=S;f=-2;i:{if(!$){break i}d=G[$+32>>2];if(!d|G[d>>2]!=($|0)){break i}Q=d+1092|0;i=G[d+4>>2];aa=G[24367];while(1){f=-1;j:{k:{l:{m:{n:{switch(i-1|0){case 1:b=H[d+16|0];if(!H[d+40|0]){break m}l=G[d>>2];a=G[l+20>>2];if(!b){break l}if(!a){break k}g=G[d+12>>2];while(1){if(g){E[G[l+16>>2]]=H[d+8|0];b=G[d+3168>>2];a=G[((H[d+8|0]^b>>>24)<<2)+191040>>2];g=G[d+12>>2]-1|0;G[d+12>>2]=g;G[d+3168>>2]=a^b<<8;l=G[d>>2];b=G[l+24>>2]+1|0;G[l+24>>2]=b;G[l+16>>2]=G[l+16>>2]+1;a=G[l+20>>2]-1|0;G[l+20>>2]=a;if(!b){G[l+28>>2]=G[l+28>>2]+1}if(a){continue}break k}s=G[d+1088>>2];h=G[d+64064>>2];a=h+1|0;if((s|0)==(a|0)){break k}f=-4;if((a|0)<(s|0)){break i}G[d+12>>2]=1;j=G[d+60>>2];E[d+8|0]=j;c=G[d+56>>2];n=M(G[d+36>>2],1e5);if(c>>>0>=n>>>0){break i}i=0;g=256;while(1){b=g+i>>1;a=(c|0)>2];g=a?b:g;i=a?i:b;if((g-i|0)!=1){continue}break}k=G[d+3152>>2];b=I[k+(c<<1)>>1];q=G[d+3156>>2];r=b|H[q+(c>>>1|0)|0]>>>(c<<2&4)<<16&983040;G[d+56>>2]=r;p=G[d+20>>2];if(!p){a=G[d+24>>2];p=G[(a<<2)+192064>>2];a=a+1|0;G[d+24>>2]=(a|0)==512?0:a}g=1;o=s+1|0;G[d+1088>>2]=o;c=p-1|0;G[d+20>>2]=c;o:{if((h|0)==(s|0)){break o}a=i&255^(c|0)==1;if((a|0)!=(j|0)){G[d+60>>2]=a;break o}G[d+12>>2]=2;if(n>>>0<=r>>>0){break i}i=0;g=256;while(1){e=g+i>>1;a=(r|0)>2];g=a?e:g;i=a?i:e;if((g-i|0)!=1){continue}break}a=H[q+(r>>>1|0)|0]>>>(b<<2&4)<<16&983040;b=I[k+(r<<1)>>1];p=a|b;G[d+56>>2]=p;if(!c){a=G[d+24>>2];c=G[(a<<2)+192064>>2];a=a+1|0;G[d+24>>2]=(a|0)==512?0:a}g=2;e=s+2|0;G[d+1088>>2]=e;c=c-1|0;G[d+20>>2]=c;if((h|0)==(o|0)){break o}a=i&255^(c|0)==1;if((a|0)!=(j|0)){G[d+60>>2]=a;break o}G[d+12>>2]=3;if(n>>>0<=p>>>0){break i}i=0;g=256;while(1){o=g+i>>1;a=(p|0)>2];g=a?o:g;i=a?i:o;if((g-i|0)!=1){continue}break}a=H[q+(p>>>1|0)|0]>>>(b<<2&4)<<16&983040;b=I[k+(p<<1)>>1];o=a|b;G[d+56>>2]=o;if(!c){a=G[d+24>>2];c=G[(a<<2)+192064>>2];a=a+1|0;G[d+24>>2]=(a|0)==512?0:a}g=3;G[d+1088>>2]=s+3;c=c-1|0;G[d+20>>2]=c;if((e|0)==(h|0)){break o}a=i&255^(c|0)==1;if((a|0)!=(j|0)){G[d+60>>2]=a;break o}if(n>>>0<=o>>>0){break i}i=0;g=256;while(1){e=g+i>>1;a=(o|0)>2];g=a?e:g;i=a?i:e;if((g-i|0)!=1){continue}break}a=H[q+(o>>>1|0)|0]>>>(b<<2&4)<<16&983040;b=I[k+(o<<1)>>1];o=a|b;G[d+56>>2]=o;if(!c){a=G[d+24>>2];c=G[(a<<2)+192064>>2];a=a+1|0;G[d+24>>2]=(a|0)==512?0:a}G[d+1088>>2]=s+4;c=c-1|0;G[d+20>>2]=c;g=(i&255^(c|0)==1)+4|0;G[d+12>>2]=g;if(n>>>0<=o>>>0){break i}i=0;p=256;while(1){e=i+p>>1;a=(o|0)>2];p=a?e:p;i=a?i:e;if((p-i|0)!=1){continue}break}G[d+60>>2]=i;G[d+56>>2]=I[k+(o<<1)>>1]|H[q+(o>>>1|0)|0]>>>(b<<2&4)<<16&983040;if(!c){a=G[d+24>>2];c=G[(a<<2)+192064>>2];a=a+1|0;G[d+24>>2]=(a|0)==512?0:a}G[d+1088>>2]=s+5;a=c-1|0;G[d+20>>2]=a;G[d+60>>2]=(a|0)==1^i}if(G[l+20>>2]){continue}break};break k;case 0:break i;default:break n}}if((i|0)<10){continue}break j}if(b){b=G[d>>2];if(!G[b+20>>2]){break k}g=G[d+12>>2];while(1){if(g){E[G[b+16>>2]]=H[d+8|0];b=G[d+3168>>2];a=G[((H[d+8|0]^b>>>24)<<2)+191040>>2];g=G[d+12>>2]-1|0;G[d+12>>2]=g;G[d+3168>>2]=a^b<<8;b=G[d>>2];c=G[b+24>>2]+1|0;G[b+24>>2]=c;G[b+16>>2]=G[b+16>>2]+1;a=G[b+20>>2]-1|0;G[b+20>>2]=a;if(!c){G[b+28>>2]=G[b+28>>2]+1}if(!a){break k}continue}q=G[d+1088>>2];j=G[d+64064>>2];a=j+1|0;if((q|0)==(a|0)){break k}f=-4;if((a|0)<(q|0)){break i}G[d+12>>2]=1;i=G[d+60>>2];E[d+8|0]=i;a=G[d+56>>2];k=M(G[d+36>>2],1e5);if(a>>>0>=k>>>0){break i}h=G[d+3148>>2];c=G[h+(a<<2)>>2];e=c>>>8|0;G[d+56>>2]=e;r=G[d+20>>2];if(!r){a=G[d+24>>2];r=G[(a<<2)+192064>>2];a=a+1|0;G[d+24>>2]=(a|0)==512?0:a}g=1;l=q+1|0;G[d+1088>>2]=l;r=r-1|0;G[d+20>>2]=r;p:{if((j|0)==(q|0)){break p}a=c&255^(r|0)==1;if((a|0)!=(i|0)){G[d+60>>2]=a;break p}G[d+12>>2]=2;if(e>>>0>=k>>>0){break i}c=G[h+(e<<2)>>2];o=c>>>8|0;G[d+56>>2]=o;if(!r){a=G[d+24>>2];r=G[(a<<2)+192064>>2];a=a+1|0;G[d+24>>2]=(a|0)==512?0:a}g=2;e=q+2|0;G[d+1088>>2]=e;r=r-1|0;G[d+20>>2]=r;if((j|0)==(l|0)){break p}a=c&255^(r|0)==1;if((a|0)!=(i|0)){G[d+60>>2]=a;break p}G[d+12>>2]=3;if(k>>>0<=o>>>0){break i}c=G[h+(o<<2)>>2];l=c>>>8|0;G[d+56>>2]=l;if(!r){a=G[d+24>>2];r=G[(a<<2)+192064>>2];a=a+1|0;G[d+24>>2]=(a|0)==512?0:a}g=3;G[d+1088>>2]=q+3;r=r-1|0;G[d+20>>2]=r;if((e|0)==(j|0)){break p}a=c&255^(r|0)==1;if((a|0)!=(i|0)){G[d+60>>2]=a;break p}if(k>>>0<=l>>>0){break i}c=G[h+(l<<2)>>2];e=c>>>8|0;G[d+56>>2]=e;if(!r){a=G[d+24>>2];r=G[(a<<2)+192064>>2];a=a+1|0;G[d+24>>2]=(a|0)==512?0:a}G[d+1088>>2]=q+4;p=r-1|0;G[d+20>>2]=p;g=(c&255^(p|0)==1)+4|0;G[d+12>>2]=g;if(e>>>0>=k>>>0){break i}a=G[h+(e<<2)>>2];G[d+56>>2]=a>>>8;c=a&255;G[d+60>>2]=c;if(!p){a=G[d+24>>2];p=G[(a<<2)+192064>>2];a=a+1|0;G[d+24>>2]=(a|0)==512?0:a}G[d+1088>>2]=q+5;a=p-1|0;G[d+20>>2]=a;G[d+60>>2]=c^(a|0)==1}if(G[b+20>>2]){continue}break}break k}n=M(G[d+36>>2],1e5);q=G[d+64064>>2];o=q+1|0;l=G[d+56>>2];s=G[d+3148>>2];c=G[d+60>>2];a=G[d+1088>>2];p=G[d+12>>2];e=H[d+8|0];i=G[d+3168>>2];b=G[d>>2];g=G[b+16>>2];k=G[b+20>>2];r=k;q:{r:while(1){s:{t:{u:{if((p|0)<=0){b=a;break u}if(!r){break s}b=e&255;while(1){if((p|0)==1){b=a;p=0;break t}E[g|0]=e;i=G[((b^i>>>24)<<2)+191040>>2]^i<<8;g=g+1|0;p=p-1|0;r=r-1|0;if(r){continue}break}break s}p=1}while(1){if(!p){if(!r){r=0;p=1;break q}E[g|0]=e;i=G[((e&255^i>>>24)<<2)+191040>>2]^i<<8;r=r-1|0;g=g+1|0;p=1;continue}f=-4;if((b|0)>(o|0)){break i}if((b|0)==(o|0)){p=0;b=o;break q}if(l>>>0>=n>>>0){break i}e=c;a=b+1|0;c=G[s+(l<<2)>>2];l=c>>>8|0;v:{c=c&255;if((e|0)!=(c|0)){b=a;break v}if((b|0)==(q|0)){b=a;c=e;break v}if(l>>>0>=n>>>0){break i}p=2;h=G[s+(l<<2)>>2];l=h>>>8|0;c=e;a=o;j=b+2|0;if((a|0)==(j|0)){continue r}a=j;j=c;c=h&255;if((j|0)!=(c|0)){continue r}if(l>>>0>=n>>>0){break i}h=G[s+(l<<2)>>2];l=h>>>8|0;p=3;c=e;a=o;j=b+3|0;if((a|0)==(j|0)){continue r}a=j;j=c;c=h&255;if((j|0)!=(c|0)){continue r}if(l>>>0>=n>>>0){break i}l=G[s+(l<<2)>>2];c=l>>>8|0;if(c>>>0>=n>>>0){break i}a=b+5|0;p=(l&255)+4|0;b=G[s+(c<<2)>>2];l=b>>>8|0;c=b&255;continue r}p=0;continue}}break}b=a;r=0}j=G[d>>2];a=G[j+24>>2];o=a+(k-r|0)|0;G[j+24>>2]=o;if(a>>>0>o>>>0){G[j+28>>2]=G[j+28>>2]+1}G[d+1088>>2]=b;G[d+12>>2]=p;E[d+8|0]=e;G[d+3168>>2]=i;G[d+3148>>2]=s;G[d+60>>2]=c;G[d+56>>2]=l;G[j+20>>2]=r;G[j+16>>2]=g;break k}if(!a){break k}g=G[d+12>>2];while(1){if(g){E[G[l+16>>2]]=H[d+8|0];b=G[d+3168>>2];a=G[((H[d+8|0]^b>>>24)<<2)+191040>>2];g=G[d+12>>2]-1|0;G[d+12>>2]=g;G[d+3168>>2]=a^b<<8;l=G[d>>2];b=G[l+24>>2]+1|0;G[l+24>>2]=b;G[l+16>>2]=G[l+16>>2]+1;a=G[l+20>>2]-1|0;G[l+20>>2]=a;if(!b){G[l+28>>2]=G[l+28>>2]+1}if(!a){break k}continue}n=G[d+1088>>2];p=G[d+64064>>2];a=p+1|0;if((n|0)==(a|0)){break k}f=-4;if((a|0)<(n|0)){break i}G[d+12>>2]=1;j=G[d+60>>2];E[d+8|0]=j;o=G[d+56>>2];q=M(G[d+36>>2],1e5);if(o>>>0>=q>>>0){break i}i=0;g=256;while(1){b=g+i>>1;a=(o|0)>2];g=a?b:g;i=a?i:b;if((g-i|0)!=1){continue}break}g=1;k=G[d+3152>>2];e=I[k+(o<<1)>>1];r=G[d+3156>>2];a=H[r+(o>>>1|0)|0];c=n+1|0;G[d+1088>>2]=c;h=e|a>>>(o<<2&4)<<16&983040;G[d+56>>2]=h;w:{if((n|0)==(p|0)){break w}a=i&255;if((a|0)!=(j|0)){G[d+60>>2]=a;break w}G[d+12>>2]=2;if(h>>>0>=q>>>0){break i}i=0;g=256;while(1){b=g+i>>1;a=(h|0)>2];g=a?b:g;i=a?i:b;if((g-i|0)!=1){continue}break}o=I[k+(h<<1)>>1];a=H[r+(h>>>1|0)|0];g=2;b=n+2|0;G[d+1088>>2]=b;h=o|a>>>(e<<2&4)<<16&983040;G[d+56>>2]=h;if((c|0)==(p|0)){break w}a=i&255;if((a|0)!=(j|0)){G[d+60>>2]=a;break w}G[d+12>>2]=3;if(h>>>0>=q>>>0){break i}i=0;g=256;while(1){c=g+i>>1;a=(h|0)>2];g=a?c:g;i=a?i:c;if((g-i|0)!=1){continue}break}e=I[k+(h<<1)>>1];a=H[r+(h>>>1|0)|0];g=3;G[d+1088>>2]=n+3;o=e|a>>>(o<<2&4)<<16&983040;G[d+56>>2]=o;if((b|0)==(p|0)){break w}a=i&255;if((a|0)!=(j|0)){G[d+60>>2]=a;break w}if(o>>>0>=q>>>0){break i}i=0;g=256;while(1){b=g+i>>1;a=(o|0)>2];g=a?b:g;i=a?i:b;if((g-i|0)!=1){continue}break}c=I[k+(o<<1)>>1];a=H[r+(o>>>1|0)|0];G[d+1088>>2]=n+4;g=(i&255)+4|0;G[d+12>>2]=g;e=c|a>>>(e<<2&4)<<16&983040;G[d+56>>2]=e;if(e>>>0>=q>>>0){break i}i=0;p=256;while(1){b=i+p>>1;a=(e|0)>2];p=a?b:p;i=a?i:b;if((p-i|0)!=1){continue}break}G[d+60>>2]=i;b=I[k+(e<<1)>>1];a=H[r+(e>>>1|0)|0];G[d+1088>>2]=n+5;G[d+56>>2]=b|a>>>(c<<2&4)<<16&983040}if(G[l+20>>2]){continue}break}}f=0;if(G[d+12>>2]|G[d+1088>>2]!=(G[d+64064>>2]+1|0)){break i}b=G[d+3168>>2]^-1;G[d+3168>>2]=b;a=G[d+48>>2];if((a|0)>=3){a=G[d+3160>>2];G[S+20>>2]=b;G[S+16>>2]=a;_a(aa,1024,S+16|0);a=G[d+48>>2]}if((a|0)>=2){Ub(93,aa)}a=G[d+3168>>2];if((a|0)!=G[d+3160>>2]){f=-4;break i}G[d+4>>2]=14;Aa=d,Ba=Eu(G[d+3172>>2],1)^a,G[Aa+3172>>2]=Ba}a=0;e=0;j=0;f=0;i=0;k=0;o=0;g=0;n=0;l=0;q=0;u=0;h=0;s=0;p=0;r=0;A=0;y=0;B=0;z=0;C=0;O=0;D=0;L=0;t=0;J=0;K=0;N=0;T=0;U=0;V=0;W=0;P=0;Y=0;X=0;R=Fa-16|0;Fa=R;ca=d+64020|0;v=G[d>>2];x:{y:{z:{A:{B:{C:{D:{E:{F:{G:{H:{I:{J:{K:{L:{M:{N:{O:{P:{Q:{R:{S:{T:{U:{V:{W:{X:{Y:{Z:{_:{$:{aa:{ba:{ca:{da:{ea:{fa:{ga:{ha:{ia:{ja:{ka:{la:{ma:{na:{oa:{pa:{qa:{ra:{sa:{ta:{ua:{va:{wa:{xa:{ya:{za:{Aa:{Ba:{Ca:{Da:{Ea:{Fa:{Ga:{Ha:{Ia:{Ja:{Ka:{La:{Ma:{Na:{Oa:{Pa:{Qa:{Ra:{Sa:{Ta:{Ua:{Va:{Wa:{Xa:{Ya:{Za:{_a:{$a:{ab:{bb:{cb:{db:{eb:{fb:{gb:{hb:{c=G[d+4>>2];if((c|0)==10){cb(ca,0,96);G[d+4>>2]=10;da=d+64112|0;ea=d+64108|0;fa=d+64104|0;ga=d+64100|0;ha=d+64096|0;ia=d+64092|0;ja=d+64088|0;ka=d+64084|0;la=d+64080|0;ma=d+64076|0;na=d+64072|0;oa=d+64068|0;pa=d+64064|0;qa=d+64060|0;ra=d+64056|0;sa=d+64052|0;ta=d+64048|0;ua=d+64044|0;va=d+64040|0;wa=d+64036|0;xa=d+64032|0;ya=d+64028|0;za=d+64024|0;c=G[d+32>>2];if((c|0)<=7){break hb}k=G[d+28>>2];break gb}da=d+64112|0;ea=d+64108|0;fa=d+64104|0;ga=d+64100|0;ha=d+64096|0;ia=d+64092|0;ja=d+64088|0;ka=d+64084|0;la=d+64080|0;ma=d+64076|0;na=d+64072|0;oa=d+64068|0;pa=d+64064|0;qa=d+64060|0;ra=d+64056|0;sa=d+64052|0;ta=d+64048|0;ua=d+64044|0;va=d+64040|0;wa=d+64036|0;xa=d+64032|0;ya=d+64028|0;za=d+64024|0;U=G[d+64112>>2];V=G[d+64108>>2];W=G[d+64104>>2];T=G[d+64100>>2];P=G[d+64096>>2];X=G[d+64092>>2];z=G[d+64088>>2];b=G[d+64084>>2];l=G[d+64080>>2];Y=G[d+64076>>2];o=G[d+64072>>2];g=G[d+64068>>2];n=G[d+64064>>2];t=G[d+64060>>2];A=G[d+64056>>2];y=G[d+64052>>2];C=G[d+64048>>2];D=G[d+64044>>2];p=G[d+64040>>2];L=G[d+64036>>2];B=G[d+64032>>2];O=G[d+64028>>2];r=G[d+64024>>2];s=G[d+64020>>2];ib:{switch(c-11|0){case 31:c=G[d+32>>2];break va;case 26:c=G[d+32>>2];m=0;break Q;case 28:J=G[d+32>>2];m=0;break P;case 25:break R;case 19:break V;case 9:break da;case 3:break wa;case 23:break Aa;case 22:break Ba;case 21:break Ca;case 18:break Da;case 17:break Ea;case 29:break Fa;case 27:break Ga;case 39:break Ia;case 38:break Ja;case 37:break Ka;case 36:break La;case 35:break Ma;case 34:break Na;case 33:break Oa;case 32:break Pa;case 24:break Qa;case 20:break Ra;case 16:break Sa;case 15:break Ta;case 14:break Ua;case 13:break Va;case 12:break Wa;case 11:break Xa;case 10:break Ya;case 8:break Za;case 7:break _a;case 6:break $a;case 5:break ab;case 4:break bb;case 2:break cb;case 1:break db;case 0:break fb;case 30:break ib;default:break Ha}}K=G[d+32>>2];m=1;break P}f=G[v+4>>2];a=c;while(1){if(!f){a=0;f=0;break y}m=G[v>>2];b=H[m|0];c=a+8|0;G[d+32>>2]=c;k=b|G[d+28>>2]<<8;G[d+28>>2]=k;f=f-1|0;G[v+4>>2]=f;G[v>>2]=m+1;b=G[v+8>>2]+1|0;G[v+8>>2]=b;if(!b){G[v+12>>2]=G[v+12>>2]+1}b=(a|0)>=0;a=c;if(!b){continue}break}}c=c-8|0;G[d+32>>2]=c;u=-5;b=0;f=0;a=0;if((k>>>c&255)==66){break eb}break y}c=G[d+32>>2];a=s}s=a;G[d+4>>2]=11;if((c|0)>=8){k=G[d+28>>2];break za}f=G[v+4>>2];a=c;while(1){if(!f){break O}i=G[v>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;k=e|G[d+28>>2]<<8;G[d+28>>2]=k;f=f-1|0;G[v+4>>2]=f;G[v>>2]=i+1;e=G[v+8>>2]+1|0;G[v+8>>2]=e;if(!e){G[v+12>>2]=G[v+12>>2]+1}e=(a|0)>=0;a=c;if(!e){continue}break}break za}c=G[d+32>>2];break ya}c=G[d+32>>2];break xa}c=G[d+32>>2];f=r;a=p;q=n;j=g;e=o;i=l;h=b;break ta}k=G[d+32>>2];f=r;a=p;q=n;j=g;e=o;i=l;h=b;break ha}k=G[d+32>>2];f=r;a=p;q=n;j=g;e=o;i=l;h=b;break ga}k=G[d+32>>2];f=r;a=p;q=n;j=g;e=o;i=l;h=b;break fa}k=G[d+32>>2];f=r;a=p;q=n;j=g;e=o;i=l;h=b;break ea}c=G[d+32>>2];break ca}c=G[d+32>>2];break ba}c=G[d+32>>2];break aa}c=G[d+32>>2];break $}c=G[d+32>>2];break _}c=G[d+32>>2];break Z}c=G[d+32>>2];break Y}c=G[d+32>>2];break U}N=G[d+32>>2];m=3;break S}k=G[d+32>>2];f=r;a=p;q=n;j=g;e=o;i=l;h=b;break qa}k=G[d+32>>2];f=r;a=p;q=n;j=g;e=o;i=l;h=b;break pa}k=G[d+32>>2];f=r;a=p;q=n;j=g;e=o;i=l;h=b;break oa}k=G[d+32>>2];f=r;a=p;q=n;j=g;e=o;i=l;h=b;break na}k=G[d+32>>2];f=r;a=p;q=n;j=g;e=o;i=l;h=b;break ma}k=G[d+32>>2];f=r;a=p;q=n;j=g;e=o;i=l;h=b;break la}k=G[d+32>>2];f=r;a=p;q=n;j=g;e=o;i=l;h=b;break ka}k=G[d+32>>2];f=r;a=p;q=n;j=g;e=o;i=l;h=b;break ja}zd(4001);zd(4002);break O}m=3;break P}m=4;break P}m=1;break X}m=1;break W}m=1;break T}m=1;break S}m=2;break S}c=c-8|0;G[d+32>>2]=c;u=-5;i=l;h=b;e=o;j=g;q=n;a=p;f=r;if((k>>>c&255)!=90){break y}}G[d+4>>2]=12;jb:{if((c|0)>=8){k=G[d+28>>2];break jb}f=G[v+4>>2];a=c;while(1){if(!f){break O}i=G[v>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;k=e|G[d+28>>2]<<8;G[d+28>>2]=k;f=f-1|0;G[v+4>>2]=f;G[v>>2]=i+1;e=G[v+8>>2]+1|0;G[v+8>>2]=e;if(!e){G[v+12>>2]=G[v+12>>2]+1}e=(a|0)>=0;a=c;if(!e){continue}break}}c=c-8|0;G[d+32>>2]=c;u=-5;i=l;h=b;e=o;j=g;q=n;a=p;f=r;if((k>>>c&255)!=104){break y}}G[d+4>>2]=13;kb:{if((c|0)>=8){j=G[d+28>>2];break kb}f=G[v+4>>2];a=c;while(1){if(!f){break O}i=G[v>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[v+4>>2]=f;G[v>>2]=i+1;e=G[v+8>>2]+1|0;G[v+8>>2]=e;if(!e){G[v+12>>2]=G[v+12>>2]+1}e=(a|0)>=0;a=c;if(!e){continue}break}}a=c-8|0;G[d+32>>2]=a;a=j>>>a&255;G[d+36>>2]=a;u=-5;if(a-58>>>0<4294967287){break N}e=a-48|0;G[d+36>>2]=e;c=G[v+44>>2];a=G[v+36>>2];if(H[d+40|0]){Aa=d,Ba=Ja[a|0](c,M(e,2e5),1)|0,G[Aa+3152>>2]=Ba;c=Ja[G[v+36>>2]](G[v+44>>2],M(G[d+36>>2],1e5)>>1,1)|0;G[d+3156>>2]=c;u=-3;if(!G[d+3152>>2]){break N}i=l;h=b;e=o;j=g;q=n;a=p;f=r;if(!c){break y}break wa}a=Ja[a|0](c,M(e,4e5),1)|0;G[d+3148>>2]=a;if(a){break wa}u=-3;break N}G[d+4>>2]=14;c=G[d+32>>2];lb:{if((c|0)>=8){j=G[d+28>>2];break lb}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){break O}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>=0;a=c;if(!e){continue}break}}c=c-8|0;G[d+32>>2]=c;k=j>>>c&255;if((k|0)!=23){break ua}}f=r;a=p;q=n;j=g;e=o;i=l;h=b;G[d+4>>2]=42;if((c|0)<8){break sa}n=G[d+28>>2];break ra}u=-4;f=r;a=p;q=n;j=g;e=o;i=l;h=b;if((k|0)!=49){break y}}G[d+4>>2]=15;if((c|0)>=8){n=G[d+28>>2];break ia}g=G[d>>2];b=G[g+4>>2];k=c;while(1){if(!b){u=0;break y}o=G[g>>2];l=H[o|0];c=k+8|0;G[d+32>>2]=c;n=l|G[d+28>>2]<<8;G[d+28>>2]=n;b=b-1|0;G[g+4>>2]=b;G[g>>2]=o+1;l=G[g+8>>2]+1|0;G[g+8>>2]=l;if(!l){G[g+12>>2]=G[g+12>>2]+1}l=(k|0)>=0;k=c;if(!l){continue}break}break ia}g=G[d>>2];b=G[g+4>>2];k=c;while(1){if(!b){u=0;break y}o=G[g>>2];l=H[o|0];c=k+8|0;G[d+32>>2]=c;n=l|G[d+28>>2]<<8;G[d+28>>2]=n;b=b-1|0;G[g+4>>2]=b;G[g>>2]=o+1;l=G[g+8>>2]+1|0;G[g+8>>2]=l;if(!l){G[g+12>>2]=G[g+12>>2]+1}l=(k|0)>=0;k=c;if(!l){continue}break}}k=c-8|0;G[d+32>>2]=k;u=-4;if((n>>>k&255)!=114){break y}}G[d+4>>2]=43;mb:{if((k|0)>=8){n=G[d+28>>2];break mb}g=G[d>>2];c=G[g+4>>2];b=k;while(1){if(!c){u=0;break y}o=G[g>>2];l=H[o|0];k=b+8|0;G[d+32>>2]=k;n=l|G[d+28>>2]<<8;G[d+28>>2]=n;c=c-1|0;G[g+4>>2]=c;G[g>>2]=o+1;l=G[g+8>>2]+1|0;G[g+8>>2]=l;if(!l){G[g+12>>2]=G[g+12>>2]+1}l=(b|0)>=0;b=k;if(!l){continue}break}}k=k-8|0;G[d+32>>2]=k;u=-4;if((n>>>k&255)!=69){break y}}G[d+4>>2]=44;nb:{if((k|0)>=8){n=G[d+28>>2];break nb}g=G[d>>2];c=G[g+4>>2];b=k;while(1){if(!c){u=0;break y}o=G[g>>2];l=H[o|0];k=b+8|0;G[d+32>>2]=k;n=l|G[d+28>>2]<<8;G[d+28>>2]=n;c=c-1|0;G[g+4>>2]=c;G[g>>2]=o+1;l=G[g+8>>2]+1|0;G[g+8>>2]=l;if(!l){G[g+12>>2]=G[g+12>>2]+1}l=(b|0)>=0;b=k;if(!l){continue}break}}k=k-8|0;G[d+32>>2]=k;u=-4;if((n>>>k&255)!=56){break y}}G[d+4>>2]=45;ob:{if((k|0)>=8){n=G[d+28>>2];break ob}g=G[d>>2];c=G[g+4>>2];b=k;while(1){if(!c){u=0;break y}o=G[g>>2];l=H[o|0];k=b+8|0;G[d+32>>2]=k;n=l|G[d+28>>2]<<8;G[d+28>>2]=n;c=c-1|0;G[g+4>>2]=c;G[g>>2]=o+1;l=G[g+8>>2]+1|0;G[g+8>>2]=l;if(!l){G[g+12>>2]=G[g+12>>2]+1}l=(b|0)>=0;b=k;if(!l){continue}break}}k=k-8|0;G[d+32>>2]=k;u=-4;if((n>>>k&255)!=80){break y}}G[d+4>>2]=46;pb:{if((k|0)>=8){n=G[d+28>>2];break pb}g=G[d>>2];c=G[g+4>>2];b=k;while(1){if(!c){u=0;break y}o=G[g>>2];l=H[o|0];k=b+8|0;G[d+32>>2]=k;n=l|G[d+28>>2]<<8;G[d+28>>2]=n;c=c-1|0;G[g+4>>2]=c;G[g>>2]=o+1;l=G[g+8>>2]+1|0;G[g+8>>2]=l;if(!l){G[g+12>>2]=G[g+12>>2]+1}l=(b|0)>=0;b=k;if(!l){continue}break}}k=k-8|0;G[d+32>>2]=k;u=-4;if((n>>>k&255)!=144){break y}G[d+3164>>2]=0}G[d+4>>2]=47;qb:{if((k|0)>=8){n=G[d+28>>2];break qb}g=G[d>>2];c=G[g+4>>2];b=k;while(1){if(!c){u=0;break y}o=G[g>>2];l=H[o|0];k=b+8|0;G[d+32>>2]=k;n=l|G[d+28>>2]<<8;G[d+28>>2]=n;c=c-1|0;G[g+4>>2]=c;G[g>>2]=o+1;l=G[g+8>>2]+1|0;G[g+8>>2]=l;if(!l){G[g+12>>2]=G[g+12>>2]+1}l=(b|0)>=0;b=k;if(!l){continue}break}}k=k-8|0;G[d+32>>2]=k;G[d+3164>>2]=n>>>k&255|G[d+3164>>2]<<8}G[d+4>>2]=48;rb:{if((k|0)>=8){n=G[d+28>>2];break rb}g=G[d>>2];c=G[g+4>>2];b=k;while(1){if(!c){u=0;break y}o=G[g>>2];l=H[o|0];k=b+8|0;G[d+32>>2]=k;n=l|G[d+28>>2]<<8;G[d+28>>2]=n;c=c-1|0;G[g+4>>2]=c;G[g>>2]=o+1;l=G[g+8>>2]+1|0;G[g+8>>2]=l;if(!l){G[g+12>>2]=G[g+12>>2]+1}l=(b|0)>=0;b=k;if(!l){continue}break}}k=k-8|0;G[d+32>>2]=k;G[d+3164>>2]=n>>>k&255|G[d+3164>>2]<<8}G[d+4>>2]=49;sb:{if((k|0)>=8){n=G[d+28>>2];break sb}g=G[d>>2];c=G[g+4>>2];b=k;while(1){if(!c){u=0;break y}o=G[g>>2];l=H[o|0];k=b+8|0;G[d+32>>2]=k;n=l|G[d+28>>2]<<8;G[d+28>>2]=n;c=c-1|0;G[g+4>>2]=c;G[g>>2]=o+1;l=G[g+8>>2]+1|0;G[g+8>>2]=l;if(!l){G[g+12>>2]=G[g+12>>2]+1}l=(b|0)>=0;b=k;if(!l){continue}break}}k=k-8|0;G[d+32>>2]=k;G[d+3164>>2]=n>>>k&255|G[d+3164>>2]<<8}G[d+4>>2]=50;tb:{if((k|0)>=8){n=G[d+28>>2];break tb}g=G[d>>2];c=G[g+4>>2];b=k;while(1){if(!c){u=0;break y}o=G[g>>2];l=H[o|0];k=b+8|0;G[d+32>>2]=k;n=l|G[d+28>>2]<<8;G[d+28>>2]=n;c=c-1|0;G[g+4>>2]=c;G[g>>2]=o+1;l=G[g+8>>2]+1|0;G[g+8>>2]=l;if(!l){G[g+12>>2]=G[g+12>>2]+1}l=(b|0)>=0;b=k;if(!l){continue}break}}G[d+4>>2]=1;b=k-8|0;G[d+32>>2]=b;G[d+3164>>2]=n>>>b&255|G[d+3164>>2]<<8;u=4;break y}k=c-8|0;G[d+32>>2]=k;u=-4;if((n>>>k&255)!=65){break y}}G[d+4>>2]=16;ub:{if((k|0)>=8){n=G[d+28>>2];break ub}g=G[d>>2];c=G[g+4>>2];b=k;while(1){if(!c){u=0;break y}o=G[g>>2];l=H[o|0];k=b+8|0;G[d+32>>2]=k;n=l|G[d+28>>2]<<8;G[d+28>>2]=n;c=c-1|0;G[g+4>>2]=c;G[g>>2]=o+1;l=G[g+8>>2]+1|0;G[g+8>>2]=l;if(!l){G[g+12>>2]=G[g+12>>2]+1}l=(b|0)>=0;b=k;if(!l){continue}break}}k=k-8|0;G[d+32>>2]=k;u=-4;if((n>>>k&255)!=89){break y}}G[d+4>>2]=17;vb:{if((k|0)>=8){n=G[d+28>>2];break vb}g=G[d>>2];c=G[g+4>>2];b=k;while(1){if(!c){u=0;break y}o=G[g>>2];l=H[o|0];k=b+8|0;G[d+32>>2]=k;n=l|G[d+28>>2]<<8;G[d+28>>2]=n;c=c-1|0;G[g+4>>2]=c;G[g>>2]=o+1;l=G[g+8>>2]+1|0;G[g+8>>2]=l;if(!l){G[g+12>>2]=G[g+12>>2]+1}l=(b|0)>=0;b=k;if(!l){continue}break}}k=k-8|0;G[d+32>>2]=k;u=-4;if((n>>>k&255)!=38){break y}}G[d+4>>2]=18;wb:{if((k|0)>=8){n=G[d+28>>2];break wb}g=G[d>>2];c=G[g+4>>2];b=k;while(1){if(!c){u=0;break y}o=G[g>>2];l=H[o|0];k=b+8|0;G[d+32>>2]=k;n=l|G[d+28>>2]<<8;G[d+28>>2]=n;c=c-1|0;G[g+4>>2]=c;G[g>>2]=o+1;l=G[g+8>>2]+1|0;G[g+8>>2]=l;if(!l){G[g+12>>2]=G[g+12>>2]+1}l=(b|0)>=0;b=k;if(!l){continue}break}}k=k-8|0;G[d+32>>2]=k;u=-4;if((n>>>k&255)!=83){break y}}G[d+4>>2]=19;xb:{if((k|0)>=8){n=G[d+28>>2];break xb}g=G[d>>2];c=G[g+4>>2];b=k;while(1){if(!c){u=0;break y}o=G[g>>2];l=H[o|0];k=b+8|0;G[d+32>>2]=k;n=l|G[d+28>>2]<<8;G[d+28>>2]=n;c=c-1|0;G[g+4>>2]=c;G[g>>2]=o+1;l=G[g+8>>2]+1|0;G[g+8>>2]=l;if(!l){G[g+12>>2]=G[g+12>>2]+1}l=(b|0)>=0;b=k;if(!l){continue}break}}b=k-8|0;G[d+32>>2]=b;u=-4;if((n>>>b&255)!=89){break y}b=G[d+44>>2]+1|0;G[d+44>>2]=b;if(G[d+48>>2]>=2){G[R>>2]=b;_a(G[24367],66375,R)}G[d+3160>>2]=0;r=f;p=a;n=q;g=j;o=e;l=i;b=h}G[d+4>>2]=20;c=G[d+32>>2];yb:{if((c|0)>=8){j=G[d+28>>2];break yb}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){break O}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>=0;a=c;if(!e){continue}break}}c=c-8|0;G[d+32>>2]=c;G[d+3160>>2]=j>>>c&255|G[d+3160>>2]<<8}G[d+4>>2]=21;zb:{if((c|0)>=8){j=G[d+28>>2];break zb}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){break O}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>=0;a=c;if(!e){continue}break}}c=c-8|0;G[d+32>>2]=c;G[d+3160>>2]=j>>>c&255|G[d+3160>>2]<<8}G[d+4>>2]=22;Ab:{if((c|0)>=8){j=G[d+28>>2];break Ab}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){break O}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>=0;a=c;if(!e){continue}break}}c=c-8|0;G[d+32>>2]=c;G[d+3160>>2]=j>>>c&255|G[d+3160>>2]<<8}G[d+4>>2]=23;Bb:{if((c|0)>=8){j=G[d+28>>2];break Bb}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){break O}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>=0;a=c;if(!e){continue}break}}c=c-8|0;G[d+32>>2]=c;G[d+3160>>2]=j>>>c&255|G[d+3160>>2]<<8}G[d+4>>2]=24;Cb:{if((c|0)>0){j=G[d+28>>2];break Cb}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){break O}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>-8;a=c;if(!e){continue}break}}G[d+52>>2]=0;c=c-1|0;G[d+32>>2]=c;E[d+16|0]=j>>>c&1}G[d+4>>2]=25;Db:{if((c|0)>=8){j=G[d+28>>2];break Db}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){break O}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>=0;a=c;if(!e){continue}break}}c=c-8|0;G[d+32>>2]=c;G[d+52>>2]=j>>>c&255|G[d+52>>2]<<8}G[d+4>>2]=26;Eb:{if((c|0)>=8){j=G[d+28>>2];break Eb}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){break O}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>=0;a=c;if(!e){continue}break}}c=c-8|0;G[d+32>>2]=c;G[d+52>>2]=j>>>c&255|G[d+52>>2]<<8}G[d+4>>2]=27;Fb:{if((c|0)>=8){j=G[d+28>>2];break Fb}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){break O}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>=0;a=c;if(!e){continue}break}}a=c-8|0;G[d+32>>2]=a;c=j>>>a&255|G[d+52>>2]<<8;G[d+52>>2]=c;k=0;u=-4;if((c|0)<0){break N}i=l;h=b;e=o;j=g;q=n;a=p;f=r;if((c|0)>(M(G[d+36>>2],1e5)|10)){break y}m=0}while(1){Gb:{Hb:{if(!m){if((k|0)>=16){break Hb}s=k;m=1;continue}G[d+4>>2]=28;c=G[d+32>>2];Ib:{if((c|0)>0){j=G[d+28>>2];break Ib}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){break O}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>-8;a=c;if(!e){continue}break}}a=c-1|0;G[d+32>>2]=a;E[(d+s|0)+3436|0]=j>>>a&1;k=s+1|0;break Gb}s=0;cb(d+3180|0,0,256);f=r;m=0;break W}m=0;continue}}while(1){Jb:{Kb:{Lb:{Mb:{if(!m){if((s|0)>15){break Mb}r=0;if(!H[(d+s|0)+3436|0]){break Jb}break Kb}G[d+4>>2]=29;c=G[d+32>>2];if((c|0)>0){j=G[d+28>>2];break Lb}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){break O}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>-8;a=c;if(!e){continue}break}break Lb}a=0;G[d+3176>>2]=0;m=0;while(1){if(H[(d+m|0)+3180|0]){E[(a+d|0)+3452|0]=m;a=G[d+3176>>2]+1|0;G[d+3176>>2]=a}c=m|1;if(H[(c+d|0)+3180|0]){E[(a+d|0)+3452|0]=c;a=G[d+3176>>2]+1|0;G[d+3176>>2]=a}m=m+2|0;if((m|0)!=256){continue}break}if(!a){u=-4;i=l;h=b;e=o;j=g;q=n;break L}B=a+2|0;r=f;break V}a=c-1|0;G[d+32>>2]=a;if(j>>>a&1){E[(((s<<4)+r|0)+d|0)+3180|0]=1}r=r+1|0}f=r;if((f|0)>15){break Jb}m=1;continue}s=s+1|0;m=0;continue}}G[d+4>>2]=30;c=G[d+32>>2];Nb:{if((c|0)>=3){j=G[d+28>>2];break Nb}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){break O}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>-6;a=c;if(!e){continue}break}}c=c-3|0;G[d+32>>2]=c;L=j>>>c&7;if(L>>>0>7){break U}u=-4;i=l;h=b;e=o;j=g;q=n;a=p;f=r;if(1<>2]=31;Ob:{if((c|0)>=15){j=G[d+28>>2];break Ob}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){u=0;i=l;h=b;e=o;j=g;q=n;a=p;break z}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>6;a=c;if(!e){continue}break}}c=c-15|0;G[d+32>>2]=c;a=0;p=j>>>c&32767;if(p){m=0;break T}u=-4;i=l;h=b;e=o;j=g;q=n;break z}while(1){Pb:{if(!m){if((a|0)>=(p|0)){break Pb}r=0;s=a;m=1;continue}while(1){G[d+4>>2]=32;c=G[d+32>>2];Qb:{if((c|0)>0){j=G[d+28>>2];break Qb}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){break O}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>-8;a=c;if(!e){continue}break}}a=c-1|0;G[d+32>>2]=a;if(j>>>a&1){u=-4;r=r+1|0;if((L|0)>(r|0)){continue}break N}break}E[(d+s|0)+25870|0]=r;a=s+1|0;m=0;continue}break}m=0;if((L|0)>0){while(1){E[(R+10|0)+m|0]=m;m=m+1|0;if((m&255)<(L|0)){continue}break}}O=0;s=0;if((p|0)>0){k=0;while(1){j=d+k|0;m=H[j+25870|0];h=H[m+(R+10|0)|0];Rb:{if(!m){break Rb}i=m-1|0;a=0;f=m;e=f&3;if(e){while(1){c=R+10|0;q=c+m|0;m=m-1|0;E[q|0]=H[c+m|0];f=f-1|0;a=a+1|0;if((e|0)!=(a&255)){continue}break}}if((i&255)>>>0<3){break Rb}while(1){c=m+R|0;m=m-4|0;a=m+(R+10|0)|0;a=H[a|0]|H[a+1|0]<<8|(H[a+2|0]<<16|H[a+3|0]<<24);E[c+7|0]=a;E[c+8|0]=a>>>8;E[c+9|0]=a>>>16;E[c+10|0]=a>>>24;f=f-4|0;if(f&255){continue}break}}E[R+10|0]=h;E[j+7868|0]=h;k=k+1|0;if((p|0)!=(k|0)){continue}break}s=p}m=0}while(1){Sb:{Tb:{Ub:{Vb:{switch(m|0){case 0:if((O|0)>=(L|0)){O=0;if((L|0)>0){O=B&-4;C=B&3;u=0;N=(B|0)<=0;D=B-1>>>0<3;while(1){Wb:{if(N){f=32;a=0;break Wb}q=0;f=32;a=0;m=0;i=0;if(!D){while(1){e=(M(u,258)+d|0)+43872|0;k=H[e+m|0];c=(f|0)<(k|0)?f:k;h=H[e+(m|1)|0];c=(c|0)<(h|0)?c:h;j=H[e+(m|2)|0];c=(c|0)<(j|0)?c:j;e=H[e+(m|3)|0];f=(c|0)<(e|0)?c:e;a=(a|0)>(k|0)?a:k;a=(a|0)>(h|0)?a:h;a=(a|0)>(j|0)?a:j;a=(a|0)>(e|0)?a:e;m=m+4|0;i=i+4|0;if((O|0)!=(i|0)){continue}break}}if(!C){break Wb}while(1){c=H[((M(u,258)+d|0)+m|0)+43872|0];f=(c|0)>(f|0)?f:c;a=(a|0)>(c|0)?a:c;m=m+1|0;q=q+1|0;if((C|0)!=(q|0)){continue}break}}t=M(u,1032)+d|0;m=t+45420|0;y=t+57804|0;v=(M(u,258)+d|0)+43872|0;i=0;j=a;c=f;s=(c|0)>(a|0);if(!s){n=B&-2;q=B&1;a=c;while(1){e=a;Xb:{if((B|0)<=0){break Xb}a=0;k=0;if((B|0)!=1){while(1){if((e|0)==H[a+v|0]){G[y+(i<<2)>>2]=a;i=i+1|0}h=a|1;if((e|0)==H[v+h|0]){G[y+(i<<2)>>2]=h;i=i+1|0}a=a+2|0;k=k+2|0;if((n|0)!=(k|0)){continue}break}}if(!q|(e|0)!=H[a+v|0]){break Xb}G[y+(i<<2)>>2]=a;i=i+1|0}a=e+1|0;if((e|0)!=(j|0)){continue}break}}t=cb(t+51612|0,0,92);Yb:{if((B|0)<=0){break Yb}i=0;if((B|0)!=1){h=B&-2;a=0;while(1){e=t+(H[i+v|0]<<2)|0;G[e+4>>2]=G[e+4>>2]+1;e=t+(H[v+(i|1)|0]<<2)|0;G[e+4>>2]=G[e+4>>2]+1;i=i+2|0;a=a+2|0;if((h|0)!=(a|0)){continue}break}}if(!(B&1)){break Yb}a=t+(H[i+v|0]<<2)|0;G[a+4>>2]=G[a+4>>2]+1}a=G[t+8>>2]+G[t+4>>2]|0;G[t+8>>2]=a;a=a+G[t+12>>2]|0;G[t+12>>2]=a;a=a+G[t+16>>2]|0;G[t+16>>2]=a;a=a+G[t+20>>2]|0;G[t+20>>2]=a;a=a+G[t+24>>2]|0;G[t+24>>2]=a;a=a+G[t+28>>2]|0;G[t+28>>2]=a;a=a+G[t+32>>2]|0;G[t+32>>2]=a;a=a+G[t+36>>2]|0;G[t+36>>2]=a;a=a+G[t+40>>2]|0;G[t+40>>2]=a;a=a+G[t+44>>2]|0;G[t+44>>2]=a;a=a+G[t+48>>2]|0;G[t+48>>2]=a;a=a+G[t+52>>2]|0;G[t+52>>2]=a;a=a+G[t+56>>2]|0;G[t+56>>2]=a;a=a+G[t+60>>2]|0;G[t+60>>2]=a;a=a+G[t+64>>2]|0;G[t+64>>2]=a;a=a+G[t+68>>2]|0;G[t+68>>2]=a;a=a+G[t+72>>2]|0;G[t+72>>2]=a;a=a+G[t+76>>2]|0;G[t+76>>2]=a;a=a+G[t+80>>2]|0;G[t+80>>2]=a;a=a+G[t+84>>2]|0;G[t+84>>2]=a;G[t+88>>2]=a+G[t+88>>2];m=cb(m,0,92);Zb:{if(s){break Zb}e=(j-c|0)+1|0;n=e&1;k=0;a=c;if((j|0)!=(a|0)){q=e&-2;h=0;while(1){s=a<<2;i=s+4|0;e=i+t|0;k=(G[e>>2]-G[s+t>>2]|0)+k|0;G[m+s>>2]=k-1;a=a+2|0;e=(G[t+(a<<2)>>2]-G[e>>2]|0)+(k<<1)|0;G[i+m>>2]=e-1;k=e<<1;h=h+2|0;if((q|0)!=(h|0)){continue}break}}if(!n){break Zb}a=a<<2;e=a+t|0;G[a+m>>2]=((G[e+4>>2]-G[e>>2]|0)+k|0)-1}_b:{if((c|0)>=(j|0)){break _b}i=c^-1;if(j-c&1){e=c<<2;c=c+1|0;a=t+(c<<2)|0;G[a>>2]=((G[e+m>>2]<<1)-G[a>>2]|0)+2}if((i|0)==(0-j|0)){break _b}while(1){i=c<<2;e=i+4|0;a=e+t|0;G[a>>2]=((G[i+m>>2]<<1)-G[a>>2]|0)+2;c=c+2|0;a=t+(c<<2)|0;G[a>>2]=((G[e+m>>2]<<1)-G[a>>2]|0)+2;if((c|0)!=(j|0)){continue}break}}G[((u<<2)+d|0)+63996>>2]=f;u=u+1|0;if((L|0)!=(u|0)){continue}break}O=L}i=G[d+36>>2];a=G[d+3176>>2];cb(d- -64|0,0,1024);D=a+1|0;a=4095;j=d+3708|0;m=15;while(1){f=a+j|0;c=m;h=c<<4;E[f|0]=h|15;e=a-15|0;E[e+j|0]=h;E[f-1|0]=h|14;E[f-2|0]=h|13;E[f-3|0]=h|12;E[f-4|0]=h|11;E[f-5|0]=h|10;E[f-6|0]=h|9;E[f-7|0]=h|8;E[f-8|0]=h|7;E[f-9|0]=h|6;E[f-10|0]=h|5;E[f-11|0]=h|4;E[f-12|0]=h|3;E[f-13|0]=h|2;E[f-14|0]=h|1;G[((c<<2)+d|0)+7804>>2]=e;m=c-1|0;a=a-16|0;if(c){continue}break}t=M(i,1e5);if((p|0)<=0){u=-4;s=256;q=0;i=l;h=b;e=o;j=g;y=0;C=0;a=p;break z}P=H[d+7868|0];a=M(P,1032)+d|0;W=a+45420|0;U=a+57804|0;V=a+51612|0;s=256;y=49;n=0;T=G[((P<<2)+d|0)+63996>>2];b=T;C=0;break R}m=1;continue;default:G[d+4>>2]=35;$b:{if((N|0)>0){k=G[d+28>>2];break $b}i=G[d>>2];f=G[i+4>>2];a=N;while(1){if(!f){break O}e=G[i>>2];c=H[e|0];N=a+8|0;G[d+32>>2]=N;k=c|G[d+28>>2]<<8;G[d+28>>2]=k;f=f-1|0;G[i+4>>2]=f;G[i>>2]=e+1;c=G[i+8>>2]+1|0;G[i+8>>2]=c;if(!c){G[i+12>>2]=G[i+12>>2]+1}c=(a|0)>-8;a=N;if(!c){continue}break}}a=N-1|0;G[d+32>>2]=a;Y=(k>>>a&1?-1:1)+Y|0;break Tb;case 2:G[d+4>>2]=34;c=G[d+32>>2];ac:{if((c|0)>0){j=G[d+28>>2];break ac}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){break O}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>-8;a=c;if(!e){continue}break}}N=c-1|0;G[d+32>>2]=N;if(!(j>>>N&1)){E[((M(O,258)+d|0)+s|0)+43872|0]=Y;s=s+1|0;break Ub}m=3;continue;case 1:break Vb}}G[d+4>>2]=33;c=G[d+32>>2];bc:{if((c|0)>=5){j=G[d+28>>2];break bc}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){break O}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>-4;a=c;if(!e){continue}break}}a=c-5|0;G[d+32>>2]=a;Y=j>>>a&31;s=0}if((B|0)<=(s|0)){break Sb}}if(Y-21>>>0>=4294967276){m=2;continue}u=-4;break M}O=O+1|0;m=0;continue}}G[d+4>>2]=36;f=G[d+32>>2];cc:{if((f|0)>=(b|0)){k=G[d+28>>2];break cc}i=G[d>>2];a=G[i+4>>2];while(1){if(!a){break O}e=G[i>>2];c=H[e|0];f=f+8|0;G[d+32>>2]=f;k=c|G[d+28>>2]<<8;G[d+28>>2]=k;a=a-1|0;G[i+4>>2]=a;G[i>>2]=e+1;c=G[i+8>>2]+1|0;G[i+8>>2]=c;if(!c){G[i+12>>2]=G[i+12>>2]+1}if((b|0)>(f|0)){continue}break}}c=f-b|0;G[d+32>>2]=c;z=(-1<>>c;m=1}while(1){dc:{ec:{fc:{gc:{hc:{if(!m){G[d+4>>2]=37;if((c|0)<=0){break hc}j=G[d+28>>2];break gc}u=-4;if((b|0)>20){break N}a=b<<2;if(G[a+W>>2]>=(z|0)){break fc}b=b+1|0;break ec}h=G[d>>2];f=G[h+4>>2];a=c;while(1){if(!f){break O}i=G[h>>2];e=H[i|0];c=a+8|0;G[d+32>>2]=c;j=e|G[d+28>>2]<<8;G[d+28>>2]=j;f=f-1|0;G[h+4>>2]=f;G[h>>2]=i+1;e=G[h+8>>2]+1|0;G[h+8>>2]=e;if(!e){G[h+12>>2]=G[h+12>>2]+1}e=(a|0)>-8;a=c;if(!e){continue}break}}c=c-1|0;G[d+32>>2]=c;X=j>>>c&1;z=X|z<<1;break dc}a=z-G[a+V>>2]|0;if(a>>>0>257){break N}i=(a<<2)+U|0;m=2;break P}m=0;continue}m=1;continue}}while(1){ic:{jc:{kc:{lc:{mc:{nc:{oc:{pc:{qc:{rc:{sc:{tc:{uc:{vc:{wc:{switch(m|0){case 0:G[d+4>>2]=39;if((J|0)<=0){break vc}k=G[d+28>>2];break uc;case 1:G[d+4>>2]=41;if((K|0)<=0){break sc}k=G[d+28>>2];break rc;case 2:A=G[i>>2];break mc;case 3:break wc;default:break tc}}G[d+4>>2]=38;f=G[d+32>>2];if((f|0)>=(b|0)){k=G[d+28>>2];break oc}j=G[d>>2];a=G[j+4>>2];while(1){if(!a){break O}e=G[j>>2];c=H[e|0];f=f+8|0;G[d+32>>2]=f;k=c|G[d+28>>2]<<8;G[d+28>>2]=k;a=a-1|0;G[j+4>>2]=a;G[j>>2]=e+1;c=G[j+8>>2]+1|0;G[j+8>>2]=c;if(!c){G[j+12>>2]=G[j+12>>2]+1}if((b|0)>(f|0)){continue}break}break oc}j=G[d>>2];f=G[j+4>>2];a=J;while(1){if(!f){break O}e=G[j>>2];c=H[e|0];J=a+8|0;G[d+32>>2]=J;k=c|G[d+28>>2]<<8;G[d+28>>2]=k;f=f-1|0;G[j+4>>2]=f;G[j>>2]=e+1;c=G[j+8>>2]+1|0;G[j+8>>2]=c;if(!c){G[j+12>>2]=G[j+12>>2]+1}c=(a|0)>-8;a=J;if(!c){continue}break}}J=J-1|0;G[d+32>>2]=J;X=k>>>J&1;z=X|z<<1;break nc}G[d+4>>2]=40;f=G[d+32>>2];if((f|0)>=(b|0)){k=G[d+28>>2];break qc}j=G[d>>2];a=G[j+4>>2];while(1){if(!a){break O}e=G[j>>2];c=H[e|0];f=f+8|0;G[d+32>>2]=f;k=c|G[d+28>>2]<<8;G[d+28>>2]=k;a=a-1|0;G[j+4>>2]=a;G[j>>2]=e+1;c=G[j+8>>2]+1|0;G[j+8>>2]=c;if(!c){G[j+12>>2]=G[j+12>>2]+1}if((b|0)>(f|0)){continue}break}break qc}j=G[d>>2];f=G[j+4>>2];a=K;while(1){if(!f){break O}e=G[j>>2];c=H[e|0];K=a+8|0;G[d+32>>2]=K;k=c|G[d+28>>2]<<8;G[d+28>>2]=k;f=f-1|0;G[j+4>>2]=f;G[j>>2]=e+1;c=G[j+8>>2]+1|0;G[j+8>>2]=c;if(!c){G[j+12>>2]=G[j+12>>2]+1}c=(a|0)>-8;a=K;if(!c){continue}break}}K=K-1|0;G[d+32>>2]=K;X=k>>>K&1;z=X|z<<1;break pc}K=f-b|0;G[d+32>>2]=K;z=(-1<>>K}u=-4;if((b|0)>20){break N}xc:{yc:{a=b<<2;if(G[a+W>>2]<(z|0)){b=b+1|0;break yc}a=z-G[a+V>>2]|0;if(a>>>0>257){break N}i=(a<<2)+U|0;break xc}m=1;continue}m=2;continue}J=f-b|0;G[d+32>>2]=J;z=(-1<>>J}u=-4;if((b|0)>20){break N}a=b<<2;if(G[a+W>>2]<(z|0)){b=b+1|0;break ic}a=z-G[a+V>>2]|0;if(a>>>0>257){break N}A=G[(a<<2)+U>>2];if(A>>>0<2){h=b;e=o;break lc}c=H[(H[(G[d+7804>>2]+d|0)+3708|0]+d|0)+3452|0];a=((c<<2)+d|0)- -64|0;j=g+1|0;G[a>>2]=j+G[a>>2];zc:{Ac:{Bc:{Cc:{if(H[d+40|0]){if((g|0)>=0){break Ac}break Cc}if((g|0)>=0){break Bc}}g=j;break zc}q=(n|0)>(t|0)?n:t;while(1){if((n|0)==(q|0)){break F}G[G[d+3148>>2]+(n<<2)>>2]=c;n=n+1|0;a=(j|0)>1;g=j-1|0;j=g;if(a){continue}break}break zc}q=(n|0)>(t|0)?n:t;while(1){if((n|0)==(q|0)){break F}F[G[d+3152>>2]+(n<<1)>>1]=c;n=n+1|0;a=(j|0)>1;g=j-1|0;j=g;if(a){continue}break}}}h=b;q=n;if((A|0)==(D|0)){break jc}e=1;if(A>>>0>1){break kc}g=-1}u=-4;if((e|0)>2097151){break C}Dc:{Ec:{switch(A|0){case 0:g=e+g|0;break Dc;case 1:break Ec;default:break Dc}}g=(e<<1)+g|0}o=e<<1;if(!y){C=C+1|0;if((C|0)>=(p|0)){break D}P=H[(d+C|0)+7868|0];a=M(P,1032)+d|0;V=a+51612|0;U=a+57804|0;W=a+45420|0;y=50;T=G[((P<<2)+d|0)+63996>>2]}y=y-1|0;b=T;m=3;continue}u=-4;if((q|0)>=(t|0)){e=o;break B}f=A-1|0;Fc:{if(f>>>0<=15){j=G[d+7804>>2];k=H[((j+f|0)+d|0)+3708|0];Gc:{if(f>>>0>3){while(1){a=(f+j|0)+d|0;b=a+3705|0;a=a+3704|0;a=H[a|0]|H[a+1|0]<<8|(H[a+2|0]<<16|H[a+3|0]<<24);E[b|0]=a;E[b+1|0]=a>>>8;E[b+2|0]=a>>>16;E[b+3|0]=a>>>24;f=f-4|0;if(f>>>0>3){continue}break}if(!f){break Gc}}e=f-1|0;c=f&3;if(c){a=0;while(1){b=(f+j|0)+d|0;E[b+3708|0]=H[b+3707|0];f=f-1|0;a=a+1|0;if((c|0)!=(a|0)){continue}break}}if(e>>>0<3){break Gc}while(1){c=(f+j|0)+d|0;b=c+3707|0;a=c+3706|0;a=H[a|0]|H[a+1|0]<<8;E[b|0]=a;E[b+1|0]=a>>>8;b=c+3705|0;a=c+3704|0;a=H[a|0]|H[a+1|0]<<8;E[b|0]=a;E[b+1|0]=a>>>8;f=f-4|0;if(f){continue}break}}E[(d+j|0)+3708|0]=k;break Fc}m=f>>>4|0;b=((m<<2)+d|0)+7804|0;c=G[b>>2];a=f&15;f=c+a|0;k=H[(f+d|0)+3708|0];if(a){a=d+3708|0;while(1){c=a+f|0;f=f-1|0;E[c|0]=H[a+f|0];c=G[b>>2];if((f|0)>(c|0)){continue}break}}G[b>>2]=c+1;e=d+7804|0;c=d+3708|0;while(1){a=e+(m<<2)|0;b=G[a>>2]-1|0;G[a>>2]=b;a=m-1|0;E[b+c|0]=H[(c+G[e+(a<<2)>>2]|0)+15|0];b=(m|0)>1;m=a;if(b){continue}break}a=G[d+7804>>2]-1|0;G[d+7804>>2]=a;E[(a+d|0)+3708|0]=k;if(G[d+7804>>2]){break Fc}f=15;c=4095;j=d+3708|0;while(1){b=c+j|0;a=f;e=((a<<2)+d|0)+7804|0;E[b|0]=H[(j+G[e>>2]|0)+15|0];E[b-1|0]=H[(j+G[e>>2]|0)+14|0];E[b-2|0]=H[(j+G[e>>2]|0)+13|0];E[b-3|0]=H[(j+G[e>>2]|0)+12|0];E[b-4|0]=H[(j+G[e>>2]|0)+11|0];E[b-5|0]=H[(j+G[e>>2]|0)+10|0];E[b-6|0]=H[(j+G[e>>2]|0)+9|0];E[b-7|0]=H[(j+G[e>>2]|0)+8|0];E[b-8|0]=H[(j+G[e>>2]|0)+7|0];E[b-9|0]=H[(j+G[e>>2]|0)+6|0];E[b-10|0]=H[(j+G[e>>2]|0)+5|0];E[b-11|0]=H[(j+G[e>>2]|0)+4|0];E[b-12|0]=H[(j+G[e>>2]|0)+3|0];E[b-13|0]=H[(j+G[e>>2]|0)+2|0];E[b-14|0]=H[(j+G[e>>2]|0)+1|0];b=c-15|0;E[b+j|0]=H[j+G[e>>2]|0];G[e>>2]=b;f=a-1|0;c=c-16|0;if(a){continue}break}}b=H[((k&255)+d|0)+3452|0];a=((b<<2)+d|0)- -64|0;G[a>>2]=G[a>>2]+1;Hc:{if(H[d+40|0]){F[G[d+3152>>2]+(q<<1)>>1]=b;break Hc}G[G[d+3148>>2]+(q<<2)>>2]=b}n=q+1|0;if(!y){C=C+1|0;if((C|0)>=(p|0)){break D}P=H[(d+C|0)+7868|0];a=M(P,1032)+d|0;V=a+51612|0;U=a+57804|0;W=a+45420|0;y=50;T=G[((P<<2)+d|0)+63996>>2]}y=y-1|0;b=T;m=4;continue}m=0;u=-4;a=G[d+52>>2];if((a|0)<0|(a|0)>=(q|0)){break G}while(1){a=G[((m<<2)+d|0)- -64>>2];if((a|0)<0|(a|0)>(q|0)){break H}s=m|1;a=G[((s<<2)+d|0)- -64>>2];if((a|0)<0|(a|0)>(q|0)){break G}s=m|2;a=G[((s<<2)+d|0)- -64>>2];if((a|0)<0|(a|0)>(q|0)){break G}s=m|3;a=G[((s<<2)+d|0)- -64>>2];if((a|0)<0|(a|0)>(q|0)){break G}m=m+4|0;if((m|0)!=256){continue}break}k=0;G[d+1092>>2]=0;n=d+1092|0;f=1;j=d- -64|0;b=1;while(1){i=b<<2;e=i+n|0;a=j+i|0;G[e>>2]=G[a-4>>2];c=i+4|0;G[c+n>>2]=G[a>>2];a=i+8|0;G[a+n>>2]=G[c+j>>2];G[e+12>>2]=G[a+j>>2];b=b+4|0;if((b|0)!=257){continue}break}while(1){c=(f<<2)+d|0;a=c+1092|0;b=G[a>>2]+k|0;G[a>>2]=b;a=c+1096|0;b=b+G[a>>2]|0;G[a>>2]=b;a=c+1100|0;b=b+G[a>>2]|0;G[a>>2]=b;a=c+1104|0;k=b+G[a>>2]|0;G[a>>2]=k;f=f+4|0;if((f|0)!=257){continue}break}s=0;while(1){a=G[((s<<2)+d|0)+1092>>2];if((a|0)<0|(a|0)>(q|0)){break G}m=1;b=s|1;if((b|0)==257){f=0;while(1){a=G[((m<<2)+d|0)+1092>>2];if((a|0)<(f|0)){i=l;e=o;j=g;D=A;a=p;f=r;s=m;break y}b=a;s=m+1|0;a=G[((s<<2)+d|0)+1092>>2];if((b|0)>(a|0)){break G}b=a;s=m+2|0;a=G[((s<<2)+d|0)+1092>>2];if((b|0)>(a|0)){break G}s=m+3|0;f=G[((s<<2)+d|0)+1092>>2];if((a|0)>(f|0)){break G}m=m+4|0;if((m|0)!=257){continue}break}G[d+3168>>2]=-1;m=0;E[d+8|0]=0;G[d+12>>2]=0;G[d+4>>2]=2;if(G[d+48>>2]>=2){hb(26719,6,1,G[24367])}Ic:{Jc:{Kc:{if(H[d+40|0]){while(1){e=m<<2;a=e+d|0;G[a+2120>>2]=G[a+1092>>2];a=m|1;if((a|0)==257){break Kc}c=d+2120|0;a=a<<2;b=d+1092|0;G[c+a>>2]=G[b+a>>2];a=e|8;G[a+c>>2]=G[a+b>>2];a=e|12;G[a+c>>2]=G[a+b>>2];m=m+4|0;continue}}f=G[d+3148>>2];s=0;Lc:{if((q|0)<=0){break Lc}if((q|0)!=1){e=q&-2;j=d+1092|0;b=0;while(1){c=j+(H[f+(m<<2)|0]<<2)|0;a=f+(G[c>>2]<<2)|0;G[a>>2]=G[a>>2]|m<<8;G[c>>2]=G[c>>2]+1;c=m|1;i=j+(H[f+(c<<2)|0]<<2)|0;a=f+(G[i>>2]<<2)|0;G[a>>2]=G[a>>2]|c<<8;G[i>>2]=G[i>>2]+1;m=m+2|0;b=b+2|0;if((e|0)!=(b|0)){continue}break}}s=q;if(!(s&1)){break Lc}b=((H[f+(m<<2)|0]<<2)+d|0)+1092|0;a=f+(G[b>>2]<<2)|0;G[a>>2]=G[a>>2]|m<<8;G[b>>2]=G[b>>2]+1}a=G[f+(G[d+52>>2]<<2)>>2];G[d+1088>>2]=0;a=a>>>8|0;G[d+56>>2]=a;if(!H[d+16|0]){break Jc}G[d+20>>2]=0;G[d+24>>2]=0;u=1;if(a>>>0>=M(G[d+36>>2],1e5)>>>0){break x}b=G[f+(a<<2)>>2];G[d+1088>>2]=1;G[d+56>>2]=b>>>8;u=0;a=G[48016];G[d+24>>2]=1;a=a-1|0;G[d+20>>2]=a;G[d+60>>2]=b&255^(a|0)==1;break G}if((q|0)>0){m=0;while(1){a=G[d+3152>>2]+(m<<1)|0;c=((H[a|0]<<2)+d|0)+2120|0;e=G[c>>2];F[a>>1]=e;a=G[d+3156>>2]+(m>>>1|0)|0;b=H[a|0];E[a|0]=m&1?b&15|e>>>12&1048560:b&-16|e>>>16;G[c>>2]=G[c>>2]+1;m=m+1|0;if((q|0)!=(m|0)){continue}break}}m=G[d+52>>2];f=H[G[d+3156>>2]+(m>>1)|0]>>>(m<<2&4)<<16&983040|I[G[d+3152>>2]+(m<<1)>>1];while(1){e=G[d+3152>>2]+(f<<1)|0;c=I[e>>1];a=G[d+3156>>2]+(f>>>1|0)|0;b=H[a|0];F[e>>1]=m;e=H[a|0];s=f;f=c|b>>>(f<<2&4)<<16&983040;E[a|0]=s&1?e&15|m>>>12&1048560:e&-16|m>>>16;m=s;if((m|0)!=G[d+52>>2]){continue}break}G[d+1088>>2]=0;G[d+56>>2]=s;if(H[d+16|0]){G[d+20>>2]=0;G[d+24>>2]=0;u=1;if(M(G[d+36>>2],1e5)>>>0<=s>>>0){break x}c=Cq(s,n);G[d+60>>2]=c;e=G[d+56>>2];b=I[G[d+3152>>2]+(e<<1)>>1];a=H[G[d+3156>>2]+(e>>>1|0)|0];G[d+1088>>2]=G[d+1088>>2]+1;G[d+56>>2]=b|a>>>(e<<2&4)<<16&983040;m=G[d+20>>2];if(!m){a=G[d+24>>2];m=G[(a<<2)+192064>>2];a=a+1|0;G[d+24>>2]=(a|0)==512?0:a}a=m-1|0;G[d+20>>2]=a;G[d+60>>2]=c^(a|0)==1;break Ic}u=1;if(M(G[d+36>>2],1e5)>>>0<=s>>>0){break x}Aa=d,Ba=Cq(s,n),G[Aa+60>>2]=Ba;c=G[d+56>>2];b=I[G[d+3152>>2]+(c<<1)>>1];a=H[G[d+3156>>2]+(c>>>1|0)|0];G[d+1088>>2]=G[d+1088>>2]+1;G[d+56>>2]=b|a>>>(c<<2&4)<<16&983040;break Ic}u=1;if(a>>>0>=M(G[d+36>>2],1e5)>>>0){break x}a=G[f+(a<<2)>>2];G[d+1088>>2]=1;G[d+56>>2]=a>>>8;G[d+60>>2]=a&255;u=0;break G}u=0;i=l;e=o;j=g;D=A;break L}a=G[((b<<2)+d|0)+1092>>2];if((a|0)<0|(a|0)>(q|0)){break I}b=s|2;a=G[((b<<2)+d|0)+1092>>2];if((a|0)<0|(a|0)>(q|0)){break J}b=s|3;a=G[((b<<2)+d|0)+1092>>2];if((a|0)<0|(a|0)>(q|0)){break K}s=s+4|0;continue}}m=0;continue}}u=0}}h=b;j=g;q=n;break E}a=p;break y}i=l;e=o;j=g;D=A;a=p;f=r;s=b;break y}i=l;e=o;j=g;D=A;a=p;f=r;s=b;break y}i=l;e=o;j=g;D=A;a=p;f=r;s=b;break y}i=l;e=o;j=g;D=A;a=p;f=r;s=m;break y}i=l;e=o;j=g;D=A;break A}h=b}i=l;e=o;break A}y=0;e=o}q=n}i=l;j=g}a=p}f=r}G[ca>>2]=s;G[za>>2]=f;G[ya>>2]=O;G[xa>>2]=B;G[wa>>2]=L;G[va>>2]=a;G[ua>>2]=D;G[ta>>2]=C;G[sa>>2]=y;G[ra>>2]=A;G[qa>>2]=t;G[pa>>2]=q;G[oa>>2]=j;G[na>>2]=e;G[ma>>2]=Y;G[la>>2]=i;G[ka>>2]=h;G[ja>>2]=z;G[ia>>2]=X;G[ha>>2]=P;G[ga>>2]=T;G[fa>>2]=W;G[ea>>2]=V;G[da>>2]=U}Fa=R+16|0;f=u;if((f|0)==4){if(G[d+48>>2]>=3){a=G[d+3164>>2];G[S+4>>2]=G[d+3172>>2];G[S>>2]=a;_a(aa,3783,S)}f=G[d+3172>>2]==G[d+3164>>2]?4:-4;break i}i=2;if(G[d+4>>2]==2){continue}break}}Fa=S+32|0;if(f&-5){if(x){G[x>>2]=f}G[w+5060>>2]=f;break b}Mc:{Nc:{Oc:{switch(f|0){case 0:b=G[w>>2];a=Tf(b);if((a|0)!=-1){ak(a,b);break Nc}if(G[w+5016>>2]){break Nc}if(!G[w+5032>>2]){break Mc}if(x){G[x>>2]=-7}G[w+5060>>2]=-7;break b;case 4:break Oc;default:break Nc}}if(x){G[x>>2]=4}G[w+5060>>2]=4;a=Z-G[w+5032>>2]|0;break a}if(G[w+5032>>2]){continue}}break}if(x){G[x>>2]=0}G[w+5060>>2]=0;a=Z;break a}if(x){G[x>>2]=-6}G[w+5060>>2]=-6}a=0}e=G[_+12>>2]&-5?-1:a}Fa=_+16|0;return e|0}function qn(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,I=0,J=0;c=Fa-2992|0;Fa=c;b=G[a+8>>2];a:{if(!b){l=1;break a}j=G[309722];l=1;d=b;while(1){d=d-1|0;e=d<<2;f=j+M(G[(e+a|0)+12>>2],344)|0;G[e+(c+2944|0)>>2]=f;e=e+(c+2896|0)|0;g=G[f>>2];G[e>>2]=(g|0)!=-1e3;b:{if((g|0)!=-1e3){G[e>>2]=G[f+56>>2];l=0;break b}c:{d:{switch(G[f+52>>2]-258|0){case 2:L[((c+16|0)+M(d,288)|0)+32>>3]=L[f+88>>3];break c;case 1:G[((c+16|0)+M(d,288)|0)+32>>2]=G[f+88>>2];break c;case 0:E[((c+16|0)+M(d,288)|0)+32|0]=H[f+88|0];break c;default:break d}}Za((M(d,288)+c|0)+48|0,f+88|0)}E[(c+6|0)+d|0]=0}if(d){continue}break}}f=G[a>>2];e:{if(!((f|0)==1001|(f&-2)==1042|(!b|!l))){f:{g:{switch(f-1002|0){case 0:h:{switch(G[G[c+2944>>2]+52>>2]-258|0){case 0:G[a+88>>2]=H[c+48|0]!=0;break f;case 1:G[a+88>>2]=G[c+48>>2];break f;case 2:L[a+88>>3]=L[c+48>>3];break f;case 4:break h;default:break f}}Za(a+88|0,c+48|0);break f;case 36:i:{switch(G[G[c+2944>>2]+52>>2]-259|0){case 0:L[a+88>>3]=G[c+48>>2];break f;case 1:break i;default:break f}}L[a+88>>3]=L[c+48>>3];break f;case 37:G[a+88>>2]=0;G[a+92>>2]=0;break f;case 35:j:{switch(G[G[c+2944>>2]+52>>2]-258|0){case 0:G[a+88>>2]=H[c+48|0]!=0;break f;case 1:G[a+88>>2]=G[c+48>>2];break f;default:break j}}L[a+88>>3]=L[c+48>>3];break f;case 41:if(G[G[c+2944>>2]+52>>2]==260){F=a,I=Bg(L[c+48>>3]),G[F+88>>2]=I;break f}F=a,I=Bg(+G[c+48>>2]),G[F+88>>2]=I;break f;case 15:if(G[G[c+2944>>2]+52>>2]==260){h=L[c+48>>3];L[a+88>>3]=h>0?h:-h;break f}f=G[c+48>>2];b=f>>31;G[a+88>>2]=(b^f)-b;break f;case 38:G[a+88>>2]=1;break f;case 28:E[a+88|0]=0;break f;case 29:k:{switch(G[a+52>>2]-258|0){case 0:E[a+88|0]=H[c+48|0];break f;case 1:G[a+88>>2]=G[c+48>>2];break f;case 2:L[a+88>>3]=L[c+48>>3];break f;case 3:break k;default:break f}}Za(a+88|0,c+48|0);break f;case 44:l:{switch(G[a+52>>2]-259|0){case 0:G[a+88>>2]=G[c+48>>2];break f;case 1:break l;default:break f}}L[a+88>>3]=L[c+48>>3];break f;case 2:F=a,J=ib(L[c+48>>3]),L[F+88>>3]=J;break f;case 3:F=a,J=eb(L[c+48>>3]),L[F+88>>3]=J;break f;case 4:F=a,J=Mc(L[c+48>>3]),L[F+88>>3]=J;break f;case 5:h=L[c+48>>3];if(h<-1|h>1){wc(15900);break f}F=a,J=fc(h),L[F+88>>3]=J;break f;case 6:h=L[c+48>>3];if(h<-1|h>1){wc(6516);break f}F=a,J=Sc(h),L[F+88>>3]=J;break f;case 7:F=a,J=Pd(L[c+48>>3]),L[F+88>>3]=J;break f;case 8:F=a,J=wn(L[c+48>>3]),L[F+88>>3]=J;break f;case 9:F=a,J=vn(L[c+48>>3]),L[F+88>>3]=J;break f;case 10:F=a,J=un(L[c+48>>3]),L[F+88>>3]=J;break f;case 11:F=a,J=af(L[c+48>>3]),L[F+88>>3]=J;break f;case 12:h=L[c+48>>3];if(h<=0){wc(17554);break f}F=a,J=oc(h),L[F+88>>3]=J;break f;case 13:h=L[c+48>>3];if(h<=0){wc(41565);break f}F=a,J=tn(h),L[F+88>>3]=J;break f;case 14:h=L[c+48>>3];if(h<0){wc(4463);break f}L[a+88>>3]=V(h);break f;case 17:L[a+88>>3]=T(L[c+48>>3]);break f;case 18:L[a+88>>3]=S(L[c+48>>3]);break f;case 19:L[a+88>>3]=S(L[c+48>>3]+.5);break f;case 16:F=a,J=Db(L[c+48>>3],L[c+336>>3]),L[F+88>>3]=J;break f;case 39:m=L[c+48>>3];k=L[c+336>>3];p=L[c+624>>3];o=L[c+912>>3];h=L[154849];if(h==0){G[309698]=-1571644103;G[309699]=1066524486;h=.017453292519943295}t=eb(h*k);u=eb(h*o);m=ib((p-m)*h*.5);k=ib((o-k)*h*.5);k=Q(R(k*k+m*(m*(t*u)),0),1);k=Db(V(k),V(1-k));L[a+88>>3]=(k+k)/h;case 20:m:{switch(G[a+52>>2]-259|0){case 1:L[a+88>>3]=L[c+48>>3];break f;case 0:G[a+88>>2]=G[c+48>>2];break f;case 3:break m;default:break f}}Za(a+88|0,c+48|0);break f;case 21:n:{switch(G[a+52>>2]-259|0){case 1:h=L[c+48>>3];k=L[c+336>>3];L[a+88>>3]=h>2];f=G[c+336>>2];G[a+88>>2]=(b|0)<(f|0)?b:f;break f;case 22:o:{switch(G[a+52>>2]-259|0){case 1:L[a+88>>3]=L[c+48>>3];break f;case 0:G[a+88>>2]=G[c+48>>2];break f;case 3:break o;default:break f}}Za(a+88|0,c+48|0);break f;case 23:p:{switch(G[a+52>>2]-259|0){case 1:h=L[c+48>>3];k=L[c+336>>3];L[a+88>>3]=h>k?h:k;break f;case 0:break p;default:break f}}b=G[c+48>>2];f=G[c+336>>2];G[a+88>>2]=(b|0)>(f|0)?b:f;break f;case 24:E[a+88|0]=L[c+624>>3]>O(L[c+48>>3]-L[c+336>>3]);break f;case 25:h=L[c+912>>3]-L[c+48>>3];p=h*h;h=L[c+1200>>3]-L[c+336>>3];p=p+h*h;h=L[c+624>>3];E[a+88|0]=p<=h*h;break f;case 26:m=L[c+48>>3];p=L[c+336>>3];h=L[c+624>>3];k=L[c+912>>3];t=L[c+1488>>3];u=L[c+1776>>3];z=L[c+1200>>3]/180*3.141592653589793;o=ib(z);m=t-m;t=eb(z);p=u-p;u=m*t+o*p;b=u>=h*-.5&u<=h*.5;h=p*t-m*o;E[a+88|0]=b&h>=k*-.5&h<=k*.5;break f;case 27:k=L[c+1488>>3];o=L[c+48>>3];m=L[c+1200>>3]/180*3.141592653589793;h=ib(m);p=L[c+336>>3];t=L[c+1776>>3];k=k-o;o=eb(m);m=t-p;p=(k*o+h*m)/L[c+624>>3];h=(m*o-k*h)/L[c+912>>3];E[a+88|0]=p*p+h*h<=1;break f;case 32:q:{switch(G[a+52>>2]-258|0){case 0:E[a+88|0]=H[(H[c+624|0]?c+16|0:c+304|0)+32|0];break f;case 1:G[a+88>>2]=G[(H[c+624|0]?c+16|0:c+304|0)+32>>2];break f;case 2:L[a+88>>3]=L[(H[c+624|0]?c+16|0:c+304|0)+32>>3];break f;case 3:break q;default:break f}}Za(a+88|0,(H[c+624|0]?c+16|0:c+304|0)+32|0);break f;case 42:kn(a+88|0,G[a+56>>2],c+48|0,G[c+16>>2],G[c+336>>2]);break f;case 43:break g;default:break f}}b=c+48|0;f=Sb(b,c+336|0);if(!f){G[a+88>>2]=0;break f}G[a+88>>2]=(f-b|0)+1}G[a>>2]=-1e3;break e}Nd(a);if(G[309737]){break e}f=G[309727];b=G[a+56>>2];d=M(f,b);r:{s:{t:{u:{v:{w:{x:{y:{z:{A:{B:{C:{D:{E:{F:{G:{H:{I:{J:{K:{L:{M:{N:{O:{P:{Q:{R:{S:{T:{U:{V:{W:{X:{Y:{Z:{_:{$:{aa:{ba:{ca:{switch(G[a>>2]-1001|0){case 28:if(!f){break e}n=a+88|0;j=a+84|0;break Z;case 27:if(!f){break e}n=a+88|0;j=a+84|0;break Y;case 26:if(!f){break e}n=a+88|0;j=a+84|0;break X;case 25:if(!f){break e}j=a+88|0;e=a+84|0;break W;case 40:if(!f){break e}break R;case 17:if(!f){break e}break ba;case 20:if(!d){break e}while(1){d=d-1|0;b=H[d+G[G[c+2944>>2]+84>>2]|0];E[G[a+84>>2]+d|0]=b;if(!b){b=d<<3;L[b+G[a+88>>2]>>3]=S(L[b+G[G[c+2944>>2]+88>>2]>>3]+.5)}if(d){continue}break};break e;case 19:if(!d){break e}while(1){d=d-1|0;b=H[d+G[G[c+2944>>2]+84>>2]|0];E[G[a+84>>2]+d|0]=b;if(!b){b=d<<3;L[b+G[a+88>>2]>>3]=S(L[b+G[G[c+2944>>2]+88>>2]>>3])}if(d){continue}break};break e;case 18:if(!d){break e}while(1){d=d-1|0;b=H[d+G[G[c+2944>>2]+84>>2]|0];E[G[a+84>>2]+d|0]=b;if(!b){b=d<<3;L[b+G[a+88>>2]>>3]=T(L[b+G[G[c+2944>>2]+88>>2]>>3])}if(d){continue}break};break e;case 5:break A;case 4:break B;case 3:break C;case 41:break D;case 0:break E;case 34:break F;case 35:break G;case 42:break H;case 1:break I;case 37:break J;case 38:break K;case 36:break L;case 16:break M;case 39:break N;case 29:break O;case 30:break P;case 45:break Q;case 21:break S;case 22:break T;case 23:break U;case 24:break V;case 33:break _;case 43:break $;case 44:break aa;case 15:break ca;case 14:break r;case 13:break s;case 12:break t;case 11:break u;case 10:break v;case 9:break w;case 8:break x;case 7:break y;case 6:break z;default:break e}}if(!d){break e}while(1){d=d-1|0;b=H[d+G[G[c+2944>>2]+84>>2]|0];E[G[a+84>>2]+d|0]=b;if(!b){b=d<<3;h=L[b+G[G[c+2944>>2]+88>>2]>>3];if(h<0){b=b+G[a+88>>2]|0;G[b>>2]=0;G[b+4>>2]=0;E[G[a+84>>2]+d|0]=1;if(d){continue}break e}L[b+G[a+88>>2]>>3]=V(h)}if(d){continue}break}break e}while(1){f=f-1|0;g=G[a+56>>2];if(g){while(1){d=d-1|0;b=d;e=G[c+2900>>2];da:{if((e|0)<=1){b=f;if(!e){break da}}e=G[c+2948>>2];L[c+336>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+7|0]=H[G[e+84>>2]+b|0]}b=G[c+2896>>2];ea:{fa:{if((b|0)<=1){if(!b){b=H[c+6|0];break ea}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(f<<3)>>3];b=H[G[b+84>>2]+f|0];break fa}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(d<<3)>>3];b=H[G[b+84>>2]+d|0]}E[c+6|0]=b}b=H[c+7|0]|b&255;E[G[a+84>>2]+d|0]=(b|0)!=0;g=g-1|0;if(!b){F=G[a+88>>2]+(d<<3)|0,J=Db(L[c+48>>3],L[c+336>>3]),L[F>>3]=J}if(g){continue}break}}if(f){continue}break}break e}if(!f){break e}j=G[G[c+2944>>2]>>2]==-1e3;i=G[G[c+2948>>2]>>2]==-1e3;while(1){b=G[c+2944>>2];f=f-1|0;ga:{if(j){g=b+88|0;b=0;break ga}g=G[G[b+88>>2]+(f<<2)>>2];b=H[G[b+84>>2]+f|0]!=0}d=G[c+2948>>2];ha:{ia:{ja:{ka:{if(i){e=d+88|0}else{if(H[G[d+84>>2]+f|0]){break ka}e=G[G[d+88>>2]+(f<<2)>>2]}G[G[a+88>>2]+(f<<2)>>2]=0;d=1;if(b){break ha}b=Sb(g,e);if(b){break ja}}d=1;b=0;break ia}d=0;b=(b-g|0)+1|0}G[G[a+88>>2]+(f<<2)>>2]=b}E[G[a+84>>2]+f|0]=d;if(f){continue}break}break e}if(!f){break e}d=G[c+2944>>2];e=G[d+56>>2];n=G[G[c+2948>>2]>>2]==-1e3;q=G[d>>2]!=-1e3;s=G[G[c+2952>>2]>>2]==-1e3;while(1){d=G[c+2948>>2];f=f-1|0;la:{if(n){i=d+88|0;d=0;break la}i=G[d+88>>2]+(f<<2)|0;d=H[G[d+84>>2]+f|0]!=0}j=G[c+2944>>2];i=G[i>>2];ma:{if(!q){g=j+88|0;if(e){break ma}e=Va(g);break ma}d=H[G[j+84>>2]+f|0]?1:d;g=G[G[j+88>>2]+(f<<2)>>2]}na:{if(s){l=b;break na}j=G[c+2952>>2];l=G[G[j+88>>2]+(f<<2)>>2];d=H[G[j+84>>2]+f|0]?1:d}j=f<<2;E[G[j+G[a+88>>2]>>2]]=0;d=i?d:1;if(!d){if((kn(G[j+G[a+88>>2]>>2],l,g,e,i)|0)<0){break e}}E[G[a+84>>2]+f|0]=d;if(f){continue}break}break e}oa:{switch(G[a+52>>2]-258|0){case 3:if(!f){break e}b=c+336|0;d=c+48|0;while(1){f=f-1|0;if(G[c+2904>>2]){e=G[c+2952>>2];E[c+624|0]=H[G[e+88>>2]+f|0];E[c+8|0]=H[G[e+84>>2]+f|0]}if(G[c+2900>>2]){e=G[c+2948>>2];Za(b,G[G[e+88>>2]+(f<<2)>>2]);E[c+7|0]=H[G[e+84>>2]+f|0]}if(G[c+2896>>2]){e=G[c+2944>>2];Za(d,G[G[e+88>>2]+(f<<2)>>2]);E[c+6|0]=H[G[e+84>>2]+f|0]}e=H[c+8|0];E[G[a+84>>2]+f|0]=e;if(!e){e=G[G[a+88>>2]+(f<<2)>>2];if(H[c+624|0]){Za(e,d);E[G[a+84>>2]+f|0]=H[c+6|0];if(f){continue}break e}Za(e,b);E[G[a+84>>2]+f|0]=H[c+7|0];if(f){continue}break e}E[G[G[a+88>>2]+(f<<2)>>2]]=0;if(f){continue}break};break e;case 0:if(!f){break e}while(1){f=f-1|0;g=G[a+56>>2];if(g){while(1){d=d-1|0;b=d;e=G[c+2904>>2];pa:{if((e|0)<=1){b=f;if(!e){break pa}}e=G[c+2952>>2];E[c+624|0]=H[G[e+88>>2]+b|0];E[c+8|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2900>>2];qa:{if((e|0)<=1){b=f;if(!e){break qa}}e=G[c+2948>>2];E[c+336|0]=H[G[e+88>>2]+b|0];E[c+7|0]=H[G[e+84>>2]+b|0]}b=G[c+2896>>2];ra:{if((b|0)<=1){if(!b){break ra}b=G[c+2944>>2];E[c+48|0]=H[G[b+88>>2]+f|0];E[c+6|0]=H[G[b+84>>2]+f|0];break ra}b=G[c+2944>>2];E[c+48|0]=H[G[b+88>>2]+d|0];E[c+6|0]=H[G[b+84>>2]+d|0]}g=g-1|0;b=H[c+8|0];E[G[a+84>>2]+d|0]=b;if(!b){sa:{if(H[c+624|0]){E[G[a+88>>2]+d|0]=H[c+48|0];b=H[c+6|0];break sa}E[G[a+88>>2]+d|0]=H[c+336|0];b=H[c+7|0]}E[G[a+84>>2]+d|0]=b}if(g){continue}break}}if(f){continue}break};break e;case 1:if(!f){break e}while(1){f=f-1|0;g=G[a+56>>2];if(g){while(1){d=d-1|0;b=d;e=G[c+2904>>2];ta:{if((e|0)<=1){b=f;if(!e){break ta}}e=G[c+2952>>2];E[c+624|0]=H[G[e+88>>2]+b|0];E[c+8|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2900>>2];ua:{if((e|0)<=1){b=f;if(!e){break ua}}e=G[c+2948>>2];G[c+336>>2]=G[G[e+88>>2]+(b<<2)>>2];E[c+7|0]=H[G[e+84>>2]+b|0]}b=G[c+2896>>2];va:{if((b|0)<=1){if(!b){break va}b=G[c+2944>>2];G[c+48>>2]=G[G[b+88>>2]+(f<<2)>>2];E[c+6|0]=H[G[b+84>>2]+f|0];break va}b=G[c+2944>>2];G[c+48>>2]=G[G[b+88>>2]+(d<<2)>>2];E[c+6|0]=H[G[b+84>>2]+d|0]}g=g-1|0;b=H[c+8|0];E[G[a+84>>2]+d|0]=b;if(!b){wa:{if(H[c+624|0]){G[G[a+88>>2]+(d<<2)>>2]=G[c+48>>2];b=H[c+6|0];break wa}G[G[a+88>>2]+(d<<2)>>2]=G[c+336>>2];b=H[c+7|0]}E[G[a+84>>2]+d|0]=b}if(g){continue}break}}if(f){continue}break};break e;case 2:break oa;default:break e}}if(!f){break e}while(1){f=f-1|0;g=G[a+56>>2];if(g){while(1){d=d-1|0;b=d;e=G[c+2904>>2];xa:{if((e|0)<=1){b=f;if(!e){break xa}}e=G[c+2952>>2];E[c+624|0]=H[G[e+88>>2]+b|0];E[c+8|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2900>>2];ya:{if((e|0)<=1){b=f;if(!e){break ya}}e=G[c+2948>>2];L[c+336>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+7|0]=H[G[e+84>>2]+b|0]}b=G[c+2896>>2];za:{if((b|0)<=1){if(!b){break za}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(f<<3)>>3];E[c+6|0]=H[G[b+84>>2]+f|0];break za}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(d<<3)>>3];E[c+6|0]=H[G[b+84>>2]+d|0]}g=g-1|0;b=H[c+8|0];E[G[a+84>>2]+d|0]=b;if(!b){Aa:{if(H[c+624|0]){L[G[a+88>>2]+(d<<3)>>3]=L[c+48>>3];b=H[c+6|0];break Aa}L[G[a+88>>2]+(d<<3)>>3]=L[c+336>>3];b=H[c+7|0]}E[G[a+84>>2]+d|0]=b}if(g){continue}break}}if(f){continue}break}break e}while(1){f=f-1|0;g=G[a+56>>2];if(g){while(1){d=d-1|0;b=d;e=G[c+2920>>2];Ba:{if((e|0)<=1){b=f;if(!e){break Ba}}e=G[c+2968>>2];L[c+1776>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+12|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2916>>2];Ca:{if((e|0)<=1){b=f;if(!e){break Ca}}e=G[c+2964>>2];L[c+1488>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+11|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2912>>2];Da:{if((e|0)<=1){b=f;if(!e){break Da}}e=G[c+2960>>2];L[c+1200>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+10|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2908>>2];Ea:{if((e|0)<=1){b=f;if(!e){break Ea}}e=G[c+2956>>2];L[c+912>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+9|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2904>>2];Fa:{if((e|0)<=1){b=f;if(!e){break Fa}}e=G[c+2952>>2];L[c+624>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+8|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2900>>2];Ga:{if((e|0)<=1){b=f;if(!e){break Ga}}e=G[c+2948>>2];L[c+336>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+7|0]=H[G[e+84>>2]+b|0]}b=G[c+2896>>2];Ha:{Ia:{if((b|0)<=1){if(!b){b=H[c+6|0];break Ha}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(f<<3)>>3];b=H[G[b+84>>2]+f|0];break Ia}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(d<<3)>>3];b=H[G[b+84>>2]+d|0]}E[c+6|0]=b}g=g-1|0;i=1;e=j;Ja:{Ka:{if(b&255){break Ka}e=j;if(H[c+7|0]){break Ka}e=j;if(H[c+8|0]){break Ka}e=j;if(H[c+9|0]){break Ka}e=j;if(H[c+10|0]){break Ka}e=j;if(H[c+11|0]){break Ka}b=H[c+12|0];E[G[j>>2]+d|0]=(b|0)!=0;if(b){break Ja}k=L[c+48>>3];o=L[c+1488>>3];m=L[c+1200>>3]/180*3.141592653589793;h=ib(m);p=L[c+336>>3];t=L[c+1776>>3];k=o-k;o=eb(m);m=t-p;p=(k*o+h*m)/L[c+624>>3];h=(m*o-k*h)/L[c+912>>3];i=p*p+h*h<=1;e=n}E[G[e>>2]+d|0]=i}if(g){continue}break}}if(f){continue}break}break e}while(1){f=f-1|0;g=G[a+56>>2];if(g){while(1){d=d-1|0;b=d;e=G[c+2920>>2];La:{if((e|0)<=1){b=f;if(!e){break La}}e=G[c+2968>>2];L[c+1776>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+12|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2916>>2];Ma:{if((e|0)<=1){b=f;if(!e){break Ma}}e=G[c+2964>>2];L[c+1488>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+11|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2912>>2];Na:{if((e|0)<=1){b=f;if(!e){break Na}}e=G[c+2960>>2];L[c+1200>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+10|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2908>>2];Oa:{if((e|0)<=1){b=f;if(!e){break Oa}}e=G[c+2956>>2];L[c+912>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+9|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2904>>2];Pa:{if((e|0)<=1){b=f;if(!e){break Pa}}e=G[c+2952>>2];L[c+624>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+8|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2900>>2];Qa:{if((e|0)<=1){b=f;if(!e){break Qa}}e=G[c+2948>>2];L[c+336>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+7|0]=H[G[e+84>>2]+b|0]}b=G[c+2896>>2];Ra:{Sa:{if((b|0)<=1){if(!b){b=H[c+6|0];break Ra}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(f<<3)>>3];b=H[G[b+84>>2]+f|0];break Sa}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(d<<3)>>3];b=H[G[b+84>>2]+d|0]}E[c+6|0]=b}g=g-1|0;i=1;e=j;Ta:{Ua:{if(b&255){break Ua}e=j;if(H[c+7|0]){break Ua}e=j;if(H[c+8|0]){break Ua}e=j;if(H[c+9|0]){break Ua}e=j;if(H[c+10|0]){break Ua}e=j;if(H[c+11|0]){break Ua}b=H[c+12|0];E[G[j>>2]+d|0]=(b|0)!=0;if(b){break Ta}k=L[c+336>>3];o=L[c+1776>>3];m=L[c+1200>>3]/180*3.141592653589793;h=ib(m);p=L[c+1488>>3]-L[c+48>>3];m=eb(m);o=o-k;k=p*m+h*o;t=L[c+624>>3];b=k>=t*-.5&k<=t*.5;h=o*m-p*h;k=L[c+912>>3];i=b&h>=k*-.5&h<=k*.5;e=n}E[G[e>>2]+d|0]=i}if(g){continue}break}}if(f){continue}break}break e}while(1){f=f-1|0;g=G[a+56>>2];if(g){while(1){d=d-1|0;b=d;e=G[c+2912>>2];Va:{if((e|0)<=1){b=f;if(!e){break Va}}e=G[c+2960>>2];L[c+1200>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+10|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2908>>2];Wa:{if((e|0)<=1){b=f;if(!e){break Wa}}e=G[c+2956>>2];L[c+912>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+9|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2904>>2];Xa:{if((e|0)<=1){b=f;if(!e){break Xa}}e=G[c+2952>>2];L[c+624>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+8|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2900>>2];Ya:{if((e|0)<=1){b=f;if(!e){break Ya}}e=G[c+2948>>2];L[c+336>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+7|0]=H[G[e+84>>2]+b|0]}b=G[c+2896>>2];Za:{_a:{if((b|0)<=1){if(!b){b=H[c+6|0];break Za}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(f<<3)>>3];b=H[G[b+84>>2]+f|0];break _a}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(d<<3)>>3];b=H[G[b+84>>2]+d|0]}E[c+6|0]=b}g=g-1|0;i=1;e=j;$a:{ab:{if(b&255){break ab}e=j;if(H[c+7|0]){break ab}e=j;if(H[c+8|0]){break ab}e=j;if(H[c+9|0]){break ab}b=H[c+10|0];E[G[j>>2]+d|0]=(b|0)!=0;if(b){break $a}h=L[c+912>>3]-L[c+48>>3];p=h*h;h=L[c+1200>>3]-L[c+336>>3];p=p+h*h;h=L[c+624>>3];i=p<=h*h;e=n}E[G[e>>2]+d|0]=i}if(g){continue}break}}if(f){continue}break}break e}while(1){f=f-1|0;g=G[a+56>>2];if(g){while(1){d=d-1|0;b=d;i=G[c+2904>>2];bb:{if((i|0)<=1){b=f;if(!i){break bb}}i=G[c+2952>>2];L[c+624>>3]=L[G[i+88>>2]+(b<<3)>>3];E[c+8|0]=H[G[i+84>>2]+b|0]}b=d;i=G[c+2900>>2];cb:{if((i|0)<=1){b=f;if(!i){break cb}}i=G[c+2948>>2];L[c+336>>3]=L[G[i+88>>2]+(b<<3)>>3];E[c+7|0]=H[G[i+84>>2]+b|0]}b=G[c+2896>>2];db:{eb:{if((b|0)<=1){if(!b){b=H[c+6|0];break db}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(f<<3)>>3];b=H[G[b+84>>2]+f|0];break eb}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(d<<3)>>3];b=H[G[b+84>>2]+d|0]}E[c+6|0]=b}g=g-1|0;i=1;fb:{if(H[c+7|0]|b&255){b=e}else{b=H[c+8|0];E[G[e>>2]+d|0]=(b|0)!=0;if(b){break fb}i=L[c+624>>3]>O(L[c+48>>3]-L[c+336>>3]);b=j}E[G[b>>2]+d|0]=i}if(g){continue}break}}if(f){continue}break}break e}gb:{hb:{switch(G[a+52>>2]-259|0){case 1:if(!f){break e}break gb;case 0:break hb;default:break e}}if(!f){break e}while(1){f=f-1|0;g=G[a+56>>2];if(g){while(1){d=d-1|0;b=d;e=G[c+2900>>2];ib:{if((e|0)<=1){b=f;if(!e){break ib}}e=G[c+2948>>2];G[c+336>>2]=G[G[e+88>>2]+(b<<2)>>2];E[c+7|0]=H[G[e+84>>2]+b|0]}b=G[c+2896>>2];jb:{kb:{if((b|0)<=1){if(!b){b=H[c+6|0];break jb}b=G[c+2944>>2];G[c+48>>2]=G[G[b+88>>2]+(f<<2)>>2];b=H[G[b+84>>2]+f|0];break kb}b=G[c+2944>>2];G[c+48>>2]=G[G[b+88>>2]+(d<<2)>>2];b=H[G[b+84>>2]+d|0]}E[c+6|0]=b}g=g-1|0;b=b&255;e=H[c+7|0];lb:{if(!(!b|!e)){E[G[a+84>>2]+d|0]=1;b=0;break lb}if(b){E[G[a+84>>2]+d|0]=0;b=G[c+336>>2];break lb}E[G[a+84>>2]+d|0]=0;b=G[c+48>>2];if(e){break lb}e=G[c+336>>2];b=(b|0)>(e|0)?b:e}G[G[a+88>>2]+(d<<2)>>2]=b;if(g){continue}break}}if(f){continue}break}break e}while(1){f=f-1|0;g=G[a+56>>2];if(g){while(1){d=d-1|0;b=d;e=G[c+2900>>2];mb:{if((e|0)<=1){b=f;if(!e){break mb}}e=G[c+2948>>2];L[c+336>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+7|0]=H[G[e+84>>2]+b|0]}b=G[c+2896>>2];nb:{ob:{if((b|0)<=1){if(!b){b=H[c+6|0];break nb}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(f<<3)>>3];b=H[G[b+84>>2]+f|0];break ob}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(d<<3)>>3];b=H[G[b+84>>2]+d|0]}E[c+6|0]=b}g=g-1|0;b=b&255;e=H[c+7|0];pb:{if(!(!b|!e)){E[G[a+84>>2]+d|0]=1;h=0;break pb}if(b){E[G[a+84>>2]+d|0]=0;h=L[c+336>>3];break pb}E[G[a+84>>2]+d|0]=0;h=L[c+48>>3];if(e){break pb}k=L[c+336>>3];h=h>k?h:k}L[G[a+88>>2]+(d<<3)>>3]=h;if(g){continue}break}}if(f){continue}break}break e}e=M(G[G[c+2944>>2]+56>>2],f);qb:{switch(G[a+52>>2]-259|0){case 3:if(!f){break e}rb:while(1){f=f-1|0;b=f<<2;d=G[b+G[G[c+2944>>2]+88>>2]>>2];g=48;while(1){e=H[d|0];sb:{if((e|0)!=49){if(e){break sb}E[G[b+G[a+88>>2]>>2]]=g;E[G[b+G[a+88>>2]>>2]+1|0]=0;if(f){continue rb}break e}g=49}d=d+1|0;continue}};case 0:if(!f){break e}while(1){l=1;f=f-1|0;E[f+G[a+84>>2]|0]=1;b=e;g=G[G[c+2944>>2]+56>>2];d=g;if(d){while(1){d=d-1|0;b=b-1|0;j=G[c+2944>>2];if(!H[b+G[j+84>>2]|0]){j=G[G[j+88>>2]+(b<<2)>>2];E[G[a+84>>2]+f|0]=0;i=l?j:(i|0)>(j|0)?i:j;l=0}if(d){continue}break}e=e-g|0}G[G[a+88>>2]+(f<<2)>>2]=i;if(f){continue}break};break e;case 1:break qb;default:break e}}if(!f){break e}while(1){i=1;f=f-1|0;E[f+G[a+84>>2]|0]=1;b=e;j=G[G[c+2944>>2]+56>>2];d=j;if(d){while(1){d=d-1|0;b=b-1|0;g=G[c+2944>>2];if(!H[b+G[g+84>>2]|0]){k=L[G[g+88>>2]+(b<<3)>>3];E[G[a+84>>2]+f|0]=0;h=i?k:h>k?h:k;i=0}if(d){continue}break}e=e-j|0}L[G[a+88>>2]+(f<<3)>>3]=h;if(f){continue}break}break e}tb:{ub:{switch(G[a+52>>2]-259|0){case 1:if(!f){break e}break tb;case 0:break ub;default:break e}}if(!f){break e}while(1){f=f-1|0;g=G[a+56>>2];if(g){while(1){d=d-1|0;b=d;e=G[c+2900>>2];vb:{if((e|0)<=1){b=f;if(!e){break vb}}e=G[c+2948>>2];G[c+336>>2]=G[G[e+88>>2]+(b<<2)>>2];E[c+7|0]=H[G[e+84>>2]+b|0]}b=G[c+2896>>2];wb:{xb:{if((b|0)<=1){if(!b){b=H[c+6|0];break wb}b=G[c+2944>>2];G[c+48>>2]=G[G[b+88>>2]+(f<<2)>>2];b=H[G[b+84>>2]+f|0];break xb}b=G[c+2944>>2];G[c+48>>2]=G[G[b+88>>2]+(d<<2)>>2];b=H[G[b+84>>2]+d|0]}E[c+6|0]=b}g=g-1|0;b=b&255;e=H[c+7|0];yb:{if(!(!b|!e)){E[G[a+84>>2]+d|0]=1;b=0;break yb}if(b){E[G[a+84>>2]+d|0]=0;b=G[c+336>>2];break yb}E[G[a+84>>2]+d|0]=0;b=G[c+48>>2];if(e){break yb}e=G[c+336>>2];b=(b|0)<(e|0)?b:e}G[G[a+88>>2]+(d<<2)>>2]=b;if(g){continue}break}}if(f){continue}break}break e}while(1){f=f-1|0;g=G[a+56>>2];if(g){while(1){d=d-1|0;b=d;e=G[c+2900>>2];zb:{if((e|0)<=1){b=f;if(!e){break zb}}e=G[c+2948>>2];L[c+336>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+7|0]=H[G[e+84>>2]+b|0]}b=G[c+2896>>2];Ab:{Bb:{if((b|0)<=1){if(!b){b=H[c+6|0];break Ab}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(f<<3)>>3];b=H[G[b+84>>2]+f|0];break Bb}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(d<<3)>>3];b=H[G[b+84>>2]+d|0]}E[c+6|0]=b}g=g-1|0;b=b&255;e=H[c+7|0];Cb:{if(!(!b|!e)){E[G[a+84>>2]+d|0]=1;h=0;break Cb}if(b){E[G[a+84>>2]+d|0]=0;h=L[c+336>>3];break Cb}E[G[a+84>>2]+d|0]=0;h=L[c+48>>3];if(e){break Cb}k=L[c+336>>3];h=h>2]+(d<<3)>>3]=h;if(g){continue}break}}if(f){continue}break}break e}e=M(G[G[c+2944>>2]+56>>2],f);Db:{switch(G[a+52>>2]-259|0){case 3:if(!f){break e}Eb:while(1){f=f-1|0;b=f<<2;d=G[b+G[G[c+2944>>2]+88>>2]>>2];g=49;while(1){e=H[d|0];Fb:{if((e|0)!=48){if(e){break Fb}E[G[b+G[a+88>>2]>>2]]=g;E[G[b+G[a+88>>2]>>2]+1|0]=0;if(f){continue Eb}break e}g=48}d=d+1|0;continue}};case 0:if(!f){break e}while(1){l=1;f=f-1|0;E[f+G[a+84>>2]|0]=1;b=e;g=G[G[c+2944>>2]+56>>2];d=g;if(d){while(1){d=d-1|0;b=b-1|0;j=G[c+2944>>2];if(!H[b+G[j+84>>2]|0]){j=G[G[j+88>>2]+(b<<2)>>2];E[G[a+84>>2]+f|0]=0;i=l?j:(i|0)<(j|0)?i:j;l=0}if(d){continue}break}e=e-g|0}G[G[a+88>>2]+(f<<2)>>2]=i;if(f){continue}break};break e;case 1:break Db;default:break e}}if(!f){break e}while(1){i=1;f=f-1|0;E[f+G[a+84>>2]|0]=1;b=e;j=G[G[c+2944>>2]+56>>2];d=j;if(d){while(1){d=d-1|0;b=b-1|0;g=G[c+2944>>2];if(!H[b+G[g+84>>2]|0]){k=L[G[g+88>>2]+(b<<3)>>3];E[G[a+84>>2]+f|0]=0;h=i?k:h>2]+(f<<3)>>3]=h;if(f){continue}break}break e}while(1){f=f-1|0;g=G[a+56>>2];Gb:{if(!g){break Gb}while(1){d=d-1|0;b=d;e=G[c+2908>>2];Hb:{if((e|0)<=1){b=f;if(!e){break Hb}}e=G[c+2956>>2];L[c+912>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+9|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2904>>2];Ib:{if((e|0)<=1){b=f;if(!e){break Ib}}e=G[c+2952>>2];L[c+624>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+8|0]=H[G[e+84>>2]+b|0]}b=d;e=G[c+2900>>2];Jb:{if((e|0)<=1){b=f;if(!e){break Jb}}e=G[c+2948>>2];L[c+336>>3]=L[G[e+88>>2]+(b<<3)>>3];E[c+7|0]=H[G[e+84>>2]+b|0]}b=G[c+2896>>2];Kb:{Lb:{if((b|0)<=1){if(!b){b=H[c+6|0];break Kb}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(f<<3)>>3];b=H[G[b+84>>2]+f|0];break Lb}b=G[c+2944>>2];L[c+48>>3]=L[G[b+88>>2]+(d<<3)>>3];b=H[G[b+84>>2]+d|0]}E[c+6|0]=b}g=g-1|0;Mb:{if(!(H[c+8|0]|(H[c+7|0]|b&255))){b=H[c+9|0];E[G[a+84>>2]+d|0]=(b|0)!=0;if(b){break Mb}k=L[c+912>>3];o=L[c+624>>3];m=L[c+48>>3];p=L[c+336>>3];h=L[154849];if(h==0){G[309698]=-1571644103;G[309699]=1066524486;h=.017453292519943295}t=eb(p*h);u=eb(k*h);o=ib((o-m)*h*.5);k=ib((k-p)*h*.5);b=G[a+88>>2]+(d<<3)|0;k=Q(R(k*k+o*(o*(t*u)),0),1);k=Db(V(k),V(1-k));L[b>>3]=(k+k)/h;if(!g){break Gb}continue}E[G[a+84>>2]+d|0]=1}if(g){continue}break}}if(f){continue}break}break e}Nb:{switch(G[a+52>>2]-259|0){case 1:if(!d){break e}while(1){d=d-1|0;f=d<<3;b=f+G[a+88>>2]|0;e=G[c+2944>>2];h=L[f+G[e+88>>2]>>3];Ob:{if(h==L[G[c+2948>>2]+88>>3]){G[b>>2]=0;G[b+4>>2]=0;b=1;break Ob}L[b>>3]=h;b=H[G[e+84>>2]+d|0]}E[G[a+84>>2]+d|0]=b;if(d){continue}break};break e;case 0:break Nb;default:break e}}if(!d){break e}while(1){d=d-1|0;f=d<<2;b=f+G[a+88>>2]|0;e=G[c+2944>>2];f=G[f+G[e+88>>2]>>2];Pb:{if((f|0)==G[G[c+2948>>2]+88>>2]){G[b>>2]=0;b=1;break Pb}G[b>>2]=f;b=H[G[e+84>>2]+d|0]}E[G[a+84>>2]+d|0]=b;if(d){continue}break}break e}Qb:{switch(G[a+52>>2]-258|0){case 3:if(!f){break e}e=c+48|0;j=c+336|0;while(1){f=f-1|0;if(G[c+2900>>2]){b=G[c+2948>>2];E[c+7|0]=H[G[b+84>>2]+f|0];Za(j,G[G[b+88>>2]+(f<<2)>>2])}Rb:{if(!G[c+2896>>2]){b=H[c+6|0];break Rb}g=G[c+2944>>2];b=H[G[g+84>>2]+f|0];E[c+6|0]=b;Za(e,G[G[g+88>>2]+(f<<2)>>2])}b=b&255;E[G[a+84>>2]+(b?f:d)|0]=b?H[c+7|0]:0;Za(G[G[a+88>>2]+(f<<2)>>2],b?j:e);if(f){continue}break};break e;case 0:if(!f){break e}e=c+48|0;j=c+336|0;while(1){f=f-1|0;g=G[a+56>>2];if(g){while(1){d=d-1|0;b=d;i=G[c+2900>>2];Sb:{if((i|0)<=1){b=f;if(!i){break Sb}}i=G[c+2948>>2];E[c+7|0]=H[G[i+84>>2]+b|0];E[c+336|0]=H[G[i+88>>2]+b|0]}b=G[c+2896>>2];Tb:{if((b|0)<=1){if(!b){b=H[c+6|0];break Tb}i=G[c+2944>>2];b=H[G[i+84>>2]+f|0];E[c+6|0]=b;E[c+48|0]=H[G[i+88>>2]+f|0];break Tb}i=G[c+2944>>2];b=H[G[i+84>>2]+d|0];E[c+6|0]=b;E[c+48|0]=H[G[i+88>>2]+d|0]}b=b&255;E[G[a+84>>2]+d|0]=b?H[c+7|0]:0;E[G[a+88>>2]+d|0]=H[(b?j:e)|0];g=g-1|0;if(g){continue}break}}if(f){continue}break};break e;case 1:if(!f){break e}e=c+48|0;j=c+336|0;while(1){f=f-1|0;g=G[a+56>>2];if(g){while(1){d=d-1|0;b=d;i=G[c+2900>>2];Ub:{if((i|0)<=1){b=f;if(!i){break Ub}}i=G[c+2948>>2];E[c+7|0]=H[G[i+84>>2]+b|0];G[c+336>>2]=G[G[i+88>>2]+(b<<2)>>2]}b=G[c+2896>>2];Vb:{if((b|0)<=1){if(!b){b=H[c+6|0];break Vb}i=G[c+2944>>2];b=H[G[i+84>>2]+f|0];E[c+6|0]=b;G[c+48>>2]=G[G[i+88>>2]+(f<<2)>>2];break Vb}i=G[c+2944>>2];b=H[G[i+84>>2]+d|0];E[c+6|0]=b;G[c+48>>2]=G[G[i+88>>2]+(d<<2)>>2]}b=b&255;E[G[a+84>>2]+d|0]=b?H[c+7|0]:0;G[G[a+88>>2]+(d<<2)>>2]=G[(b?j:e)>>2];g=g-1|0;if(g){continue}break}}if(f){continue}break};break e;case 2:break Qb;default:break e}}if(!f){break e}e=c+48|0;j=c+336|0;while(1){f=f-1|0;g=G[a+56>>2];if(g){while(1){d=d-1|0;b=d;i=G[c+2900>>2];Wb:{if((i|0)<=1){b=f;if(!i){break Wb}}i=G[c+2948>>2];E[c+7|0]=H[G[i+84>>2]+b|0];L[c+336>>3]=L[G[i+88>>2]+(b<<3)>>3]}b=G[c+2896>>2];Xb:{if((b|0)<=1){if(!b){b=H[c+6|0];break Xb}i=G[c+2944>>2];b=H[G[i+84>>2]+f|0];E[c+6|0]=b;L[c+48>>3]=L[G[i+88>>2]+(f<<3)>>3];break Xb}i=G[c+2944>>2];b=H[G[i+84>>2]+d|0];E[c+6|0]=b;L[c+48>>3]=L[G[i+88>>2]+(d<<3)>>3]}b=b&255;E[G[a+84>>2]+d|0]=b?H[c+7|0]:0;L[G[a+88>>2]+(d<<3)>>3]=L[(b?j:e)>>3];g=g-1|0;if(g){continue}break}}if(f){continue}break}break e}b=G[G[c+2944>>2]+52>>2]==261?f:d;if(!b){break e}d=b;if(b&1){d=b-1|0;E[d+G[a+88>>2]|0]=H[G[G[c+2944>>2]+84>>2]+d|0];E[G[a+84>>2]+d|0]=0}if((b|0)==1){break e}while(1){b=d-1|0;E[b+G[a+88>>2]|0]=H[b+G[G[c+2944>>2]+84>>2]|0];E[b+G[a+84>>2]|0]=0;d=d-2|0;E[d+G[a+88>>2]|0]=H[G[G[c+2944>>2]+84>>2]+d|0];E[G[a+84>>2]+d|0]=0;if(d){continue}break}break e}if(!f){break e}b=G[c+2944>>2];j=G[b+52>>2]==261?1:G[b+56>>2];g=j-1|0;l=j&1;e=M(f,j);while(1){f=f-1|0;E[f+G[a+84>>2]|0]=0;i=f<<2;G[i+G[a+88>>2]>>2]=0;if(j){n=G[G[c+2944>>2]+84>>2];d=j;b=e;if(l){b=e-1|0;if(!H[n+b|0]){d=i+G[a+88>>2]|0;G[d>>2]=G[d>>2]+1}d=g}if((j|0)!=1){while(1){if(!H[(b+n|0)-1|0]){q=i+G[a+88>>2]|0;G[q>>2]=G[q>>2]+1}d=d-2|0;b=b-2|0;if(!H[n+b|0]){q=i+G[a+88>>2]|0;G[q>>2]=G[q>>2]+1}if(d){continue}break}}e=e-j|0}if(f){continue}break}break e}if(G[G[c+2944>>2]+52>>2]!=260){if(!d){break e}while(1){d=d-1|0;e=d<<2;f=G[c+2944>>2];j=G[e+G[f+88>>2]>>2];b=j>>31;G[e+G[a+88>>2]>>2]=(b^j)-b;E[G[a+84>>2]+d|0]=H[G[f+84>>2]+d|0];if(d){continue}break}break e}if(!d){break e}while(1){d=d-1|0;f=d<<3;b=G[c+2944>>2];h=L[f+G[b+88>>2]>>3];L[f+G[a+88>>2]>>3]=h>0?h:-h;E[G[a+84>>2]+d|0]=H[G[b+84>>2]+d|0];if(d){continue}break}break e}b=G[c+2944>>2];n=G[b+84>>2];d=G[b+88>>2];j=G[b+56>>2];Yb:{Zb:{if(G[b+52>>2]==259){e=ab(j<<2);if(!e){break Zb}if((f|0)>0){A=j&3;D=j-1>>>0<3;while(1){_b:{if(!j){g=e;break _b}l=0;i=j;g=e;b=n;if(A){while(1){if(!H[b|0]){G[g>>2]=G[d>>2];g=g+4|0}i=i-1|0;b=b+1|0;d=d+4|0;l=l+1|0;if((A|0)!=(l|0)){continue}break}}if(!D){while(1){if(!H[b|0]){G[g>>2]=G[d>>2];g=g+4|0}if(!H[b+1|0]){G[g>>2]=G[d+4>>2];g=g+4|0}if(!H[b+2|0]){G[g>>2]=G[d+8>>2];g=g+4|0}i=i-4|0;if(!H[b+3|0]){G[g>>2]=G[d+12>>2];g=g+4|0}b=b+4|0;d=d+16|0;if(i){continue}break}}n=j+n|0}b=g-e|0;$b:{if((b|0)>0){E[G[a+84>>2]+q|0]=0;l=0;b=b>>>2|0;g=b-1|0;x=(g|0)/2|0;ac:{if(b>>>0<2){break ac}while(1){s=l+1|0;if((s|0)==(g|0)){b=e+(l<<2)|0;i=G[b>>2];g=e+(g<<2)|0;l=G[g>>2];if((i|0)<=(l|0)){break ac}G[b>>2]=l;G[g>>2]=i;break ac}r=e+((g+l|0)/2<<2)|0;b=G[r>>2];v=e+(g<<2)|0;i=G[v>>2];bc:{if((b|0)<=(i|0)){b=i;break bc}G[r>>2]=i;G[v>>2]=b}w=e+(l<<2)|0;i=G[w>>2];if((i|0)>(b|0)){G[w>>2]=b;G[v>>2]=i;i=G[w>>2]}b=G[r>>2];if((i|0)<(b|0)){G[r>>2]=i;G[w>>2]=b;b=G[r>>2]}i=e+(s<<2)|0;G[r>>2]=G[i>>2];G[i>>2]=b;b=g;while(1){r=G[w>>2];while(1){s=s+1|0;B=e+(s<<2)|0;C=G[B>>2];if((r|0)>(C|0)){continue}break}while(1){i=b;b=b-1|0;v=e+(b<<2)|0;y=G[v>>2];if((r|0)<(y|0)){continue}break}if((i|0)>(s|0)){G[B>>2]=y;G[v>>2]=C;continue}break}G[w>>2]=y;G[v>>2]=r;g=(i|0)>(x|0)?i-2|0:g;l=(b|0)>(x|0)?l:s;if((g|0)>(l|0)){continue}break}}b=G[e+(x<<2)>>2];break $b}E[G[a+84>>2]+q|0]=1;b=0}G[G[a+88>>2]+(q<<2)>>2]=b;q=q+1|0;if((q|0)!=(f|0)){continue}break}}Wa(e);break e}e=ab(j<<3);if(!e){break Yb}if((f|0)>0){s=j&3;r=j-1>>>0<3;while(1){cc:{if(!j){g=e;break cc}l=0;i=j;g=e;b=n;if(s){while(1){if(!H[b|0]){L[g>>3]=L[d>>3];g=g+8|0}i=i-1|0;b=b+1|0;d=d+8|0;l=l+1|0;if((s|0)!=(l|0)){continue}break}}if(!r){while(1){if(!H[b|0]){L[g>>3]=L[d>>3];g=g+8|0}if(!H[b+1|0]){L[g>>3]=L[d+8>>3];g=g+8|0}if(!H[b+2|0]){L[g>>3]=L[d+16>>3];g=g+8|0}i=i-4|0;if(!H[b+3|0]){L[g>>3]=L[d+24>>3];g=g+8|0}b=b+4|0;d=d+32|0;if(i){continue}break}}n=j+n|0}b=g-e|0;dc:{if((b|0)>0){E[G[a+84>>2]+q|0]=0;h=Mi(e,b>>>3|0);break dc}E[G[a+84>>2]+q|0]=1;h=0}L[G[a+88>>2]+(q<<3)>>3]=h;q=q+1|0;if((q|0)!=(f|0)){continue}break}}Wa(e);break e}wc(14017);Wa(G[a+88>>2]);break e}wc(14017);Wa(G[a+88>>2]);break e}d=G[c+2944>>2];b=M(G[d+56>>2],f);ec:{switch(G[d+52>>2]-259|0){case 1:if(!f){break e}while(1){f=f-1|0;fc:{gc:{g=G[c+2944>>2];e=G[g+56>>2];if(e){q=e&1;n=G[g+84>>2];j=e-1|0;hc:{if(!j){l=0;h=0;d=b;break hc}s=e&-2;l=0;h=0;d=b;i=0;while(1){r=d-1|0;if(!H[r+n|0]){h=h+L[G[g+88>>2]+(r<<3)>>3];l=l+1|0}d=d-2|0;if(!H[n+d|0]){h=h+L[G[g+88>>2]+(d<<3)>>3];l=l+1|0}i=i+2|0;if((s|0)!=(i|0)){continue}break}}ic:{if(!q){break ic}d=d-1|0;if(H[d+n|0]){break ic}l=l+1|0;h=h+L[G[g+88>>2]+(d<<3)>>3]}d=b-e|0;if((l|0)>=2){break gc}b=d}E[G[a+84>>2]+f|0]=0;h=0;break fc}o=+(l|0);jc:{if(!e){h=0;break jc}k=h/o;i=G[g+84>>2];h=0;if(q){b=b-1|0;if(!H[i+b|0]){h=L[G[g+88>>2]+(b<<3)>>3]-k;h=h*h+0}e=j}if(j){while(1){j=b-1|0;if(!H[j+i|0]){m=L[G[g+88>>2]+(j<<3)>>3]-k;h=m*m+h}e=e-2|0;b=b-2|0;if(!H[i+b|0]){m=L[G[g+88>>2]+(b<<3)>>3]-k;h=m*m+h}if(e){continue}break}}b=d}E[G[a+84>>2]+f|0]=0;h=V(h/(o+-1))}L[G[a+88>>2]+(f<<3)>>3]=h;if(f){continue}break};break e;case 0:break ec;default:break e}}if(!f){break e}while(1){f=f-1|0;kc:{lc:{g=G[c+2944>>2];e=G[g+56>>2];if(e){q=e&1;n=G[g+84>>2];j=e-1|0;mc:{if(!j){l=0;h=0;d=b;break mc}s=e&-2;l=0;h=0;d=b;i=0;while(1){r=d-1|0;if(!H[r+n|0]){h=h+ +G[G[g+88>>2]+(r<<2)>>2];l=l+1|0}d=d-2|0;if(!H[n+d|0]){h=h+ +G[G[g+88>>2]+(d<<2)>>2];l=l+1|0}i=i+2|0;if((s|0)!=(i|0)){continue}break}}nc:{if(!q){break nc}d=d-1|0;if(H[d+n|0]){break nc}l=l+1|0;h=h+ +G[G[g+88>>2]+(d<<2)>>2]}d=b-e|0;if((l|0)>=2){break lc}b=d}E[G[a+84>>2]+f|0]=0;h=0;break kc}o=+(l|0);oc:{if(!e){h=0;break oc}k=h/o;i=G[g+84>>2];h=0;if(q){b=b-1|0;if(!H[i+b|0]){h=+G[G[g+88>>2]+(b<<2)>>2]-k;h=h*h+0}e=j}if(j){while(1){j=b-1|0;if(!H[j+i|0]){m=+G[G[g+88>>2]+(j<<2)>>2]-k;h=m*m+h}e=e-2|0;b=b-2|0;if(!H[i+b|0]){m=+G[G[g+88>>2]+(b<<2)>>2]-k;h=m*m+h}if(e){continue}break}}b=d}E[G[a+84>>2]+f|0]=0;h=V(h/(o+-1))}L[G[a+88>>2]+(f<<3)>>3]=h;if(f){continue}break}break e}b=G[c+2944>>2];d=M(G[b+56>>2],f);pc:{switch(G[b+52>>2]-259|0){case 1:if(!f){break e}while(1){f=f-1|0;e=f<<3;b=e+G[a+88>>2]|0;G[b>>2]=0;G[b+4>>2]=0;qc:{j=G[c+2944>>2];b=G[j+56>>2];if(b){g=G[j+84>>2];i=0;while(1){b=b-1|0;d=d-1|0;if(!H[g+d|0]){n=e+G[a+88>>2]|0;L[n>>3]=L[G[j+88>>2]+(d<<3)>>3]+L[n>>3];i=i+1|0}if(b){continue}break}if(i){break qc}}E[G[a+84>>2]+f|0]=1;if(f){continue}break e}E[G[a+84>>2]+f|0]=0;b=e+G[a+88>>2]|0;L[b>>3]=L[b>>3]/+(i|0);if(f){continue}break};break e;case 0:break pc;default:break e}}if(!f){break e}while(1){f=f-1|0;e=f<<3;b=e+G[a+88>>2]|0;G[b>>2]=0;G[b+4>>2]=0;rc:{j=G[c+2944>>2];b=G[j+56>>2];if(b){g=G[j+84>>2];i=0;while(1){b=b-1|0;d=d-1|0;if(!H[g+d|0]){n=e+G[a+88>>2]|0;L[n>>3]=L[n>>3]+ +G[G[j+88>>2]+(d<<2)>>2];i=i+1|0}if(b){continue}break}if(i){break rc}}E[G[a+84>>2]+f|0]=1;if(f){continue}break e}E[G[a+84>>2]+f|0]=0;b=e+G[a+88>>2]|0;L[b>>3]=L[b>>3]/+(i|0);if(f){continue}break}break e}b=G[c+2944>>2];d=M(G[b+56>>2],f);sc:{tc:{uc:{vc:{wc:{switch(G[b+52>>2]-258|0){case 2:if(!f){break e}break tc;case 1:if(!f){break e}break sc;case 0:if(!f){break e}break vc;default:break wc}}if(!f){break e}break uc}while(1){f=f-1|0;e=f<<2;G[e+G[a+88>>2]>>2]=0;E[G[a+84>>2]+f|0]=1;b=G[G[c+2944>>2]+56>>2];if(b){while(1){b=b-1|0;d=d-1|0;j=G[c+2944>>2];if(!H[d+G[j+84>>2]|0]){g=e+G[a+88>>2]|0;G[g>>2]=G[g>>2]+(H[G[j+88>>2]+d|0]!=0);E[G[a+84>>2]+f|0]=0}if(b){continue}break}}if(f){continue}break}break e}while(1){f=f-1|0;b=f<<2;d=G[b+G[G[c+2944>>2]+88>>2]>>2];G[b+G[a+88>>2]>>2]=0;E[G[a+84>>2]+f|0]=0;while(1){xc:{e=H[d|0];yc:{if((e|0)!=49){if(!e){break xc}break yc}e=b+G[a+88>>2]|0;G[e>>2]=G[e>>2]+1}d=d+1|0;continue}break}if(f){continue}break}break e}while(1){f=f-1|0;e=f<<3;b=e+G[a+88>>2]|0;G[b>>2]=0;G[b+4>>2]=0;E[G[a+84>>2]+f|0]=1;b=G[G[c+2944>>2]+56>>2];if(b){while(1){b=b-1|0;d=d-1|0;j=G[c+2944>>2];if(!H[d+G[j+84>>2]|0]){g=e+G[a+88>>2]|0;L[g>>3]=L[G[j+88>>2]+(d<<3)>>3]+L[g>>3];E[G[a+84>>2]+f|0]=0}if(b){continue}break}}if(f){continue}break}break e}while(1){f=f-1|0;e=f<<2;G[e+G[a+88>>2]>>2]=0;E[G[a+84>>2]+f|0]=1;b=G[G[c+2944>>2]+56>>2];if(b){while(1){b=b-1|0;d=d-1|0;j=G[c+2944>>2];if(!H[d+G[j+84>>2]|0]){g=e+G[a+88>>2]|0;G[g>>2]=G[g>>2]+G[G[j+88>>2]+(d<<2)>>2];E[G[a+84>>2]+f|0]=0}if(b){continue}break}}if(f){continue}break}break e}f=G[c+2944>>2];b=G[f>>2];if(G[f+52>>2]==260){if((b|0)!=-1e3){if(!d){break e}while(1){d=d-1|0;E[d+G[a+84>>2]|0]=H[G[G[c+2944>>2]+84>>2]+d|0];b=d<<3;if(L[b+G[G[c+2944>>2]+88>>2]>>3]<0){E[G[a+84>>2]+d|0]=1}if(!H[G[a+84>>2]+d|0]){b=Bg(L[b+G[G[c+2944>>2]+88>>2]>>3]);G[G[a+88>>2]+(d<<2)>>2]=b}if(d){continue}break}break e}if(!d){break e}while(1){d=d-1|0;E[d+G[a+84>>2]|0]=L[c+48>>3]<0;if(!H[G[a+84>>2]+d|0]){b=Bg(L[c+48>>3]);G[G[a+88>>2]+(d<<2)>>2]=b}if(d){continue}break}break e}if((b|0)!=-1e3){if(!d){break e}while(1){d=d-1|0;E[d+G[a+84>>2]|0]=H[G[G[c+2944>>2]+84>>2]+d|0];b=d<<2;if(G[b+G[G[c+2944>>2]+88>>2]>>2]<0){E[G[a+84>>2]+d|0]=1}if(!H[G[a+84>>2]+d|0]){f=Bg(+G[b+G[G[c+2944>>2]+88>>2]>>2]);G[b+G[a+88>>2]>>2]=f}if(d){continue}break}break e}if(!d){break e}while(1){d=d-1|0;E[d+G[a+84>>2]|0]=G[c+48>>2]>>>31;if(!H[G[a+84>>2]+d|0]){b=Bg(+G[c+48>>2]);G[G[a+88>>2]+(d<<2)>>2]=b}if(d){continue}break}break e}zc:{switch(G[a+52>>2]-259|0){case 2:if(!f){break e}d=f;if(d&1){d=f-1|0;E[G[G[a+88>>2]+(d<<2)>>2]]=0;E[G[a+84>>2]+d|0]=1}if((f|0)==1){break e}while(1){b=d-1|0;E[G[G[a+88>>2]+(b<<2)>>2]]=0;E[b+G[a+84>>2]|0]=1;d=d-2|0;E[G[G[a+88>>2]+(d<<2)>>2]]=0;E[G[a+84>>2]+d|0]=1;if(d){continue}break};break e;case 0:break zc;default:break e}}if(!f){break e}b=f-1|0;e=f&3;if(e){d=0;while(1){f=f-1|0;G[G[a+88>>2]+(f<<2)>>2]=0;E[G[a+84>>2]+f|0]=1;d=d+1|0;if((e|0)!=(d|0)){continue}break}}if(b>>>0<3){break e}while(1){b=f-1|0;G[G[a+88>>2]+(b<<2)>>2]=0;E[b+G[a+84>>2]|0]=1;b=f-2|0;G[G[a+88>>2]+(b<<2)>>2]=0;E[b+G[a+84>>2]|0]=1;b=f-3|0;G[G[a+88>>2]+(b<<2)>>2]=0;E[b+G[a+84>>2]|0]=1;f=f-4|0;G[G[a+88>>2]+(f<<2)>>2]=0;E[G[a+84>>2]+f|0]=1;if(f){continue}break}break e}if(!f){break e}d=f;if(d&1){d=f-1|0;G[G[a+88>>2]+(d<<2)>>2]=G[309726]+d;E[G[a+84>>2]+d|0]=0}if((f|0)==1){break e}while(1){b=d-1|0;G[G[a+88>>2]+(b<<2)>>2]=b+G[309726];E[b+G[a+84>>2]|0]=0;d=d-2|0;G[G[a+88>>2]+(d<<2)>>2]=G[309726]+d;E[G[a+84>>2]+d|0]=0;if(d){continue}break}break e}if(!d){break e}while(1){b=Au(G[309618],G[309619],1284865837,1481765933)+1|0;f=Ia;f=b?f:f+1|0;G[309618]=b;G[309619]=f;d=d-1|0;L[G[a+88>>2]+(d<<3)>>3]=+(f>>>1|0)*4.656612873077393e-10;E[G[a+84>>2]+d|0]=0;if(d){continue}break}break e}if(!d){break e}while(1){Ac:{if(!H[1238480]){f=Au(G[309618],G[309619],1284865837,1481765933)+1|0;b=Ia;G[309618]=f;b=f?b:b+1|0;G[309619]=b;j=Au(G[309618],G[309619],1284865837,1481765933)+1|0;f=Ia;f=j?f:f+1|0;G[309618]=j;G[309619]=f;E[1238480]=1;h=V(oc(+(b>>>1|0)*4.656612873077393e-10)*-2);k=+(f>>>1|0)*4.656612873077393e-10*6.283185307179586;F=1238488,J=h*eb(k),L[F>>3]=J;h=h*ib(k);break Ac}E[1238480]=0;h=L[154811]}d=d-1|0;L[G[a+88>>2]+(d<<3)>>3]=h;E[G[a+84>>2]+d|0]=0;if(d){continue}break}break e}if(!d){break e}while(1){d=d-1|0;b=H[d+G[G[c+2944>>2]+84>>2]|0];E[G[a+84>>2]+d|0]=b;if(!b){b=d<<3;F=b+G[a+88>>2]|0,J=ib(L[b+G[G[c+2944>>2]+88>>2]>>3]),L[F>>3]=J}if(d){continue}break}break e}if(!d){break e}while(1){d=d-1|0;b=H[d+G[G[c+2944>>2]+84>>2]|0];E[G[a+84>>2]+d|0]=b;if(!b){b=d<<3;F=b+G[a+88>>2]|0,J=eb(L[b+G[G[c+2944>>2]+88>>2]>>3]),L[F>>3]=J}if(d){continue}break}break e}if(!d){break e}while(1){d=d-1|0;b=H[d+G[G[c+2944>>2]+84>>2]|0];E[G[a+84>>2]+d|0]=b;if(!b){b=d<<3;F=b+G[a+88>>2]|0,J=Mc(L[b+G[G[c+2944>>2]+88>>2]>>3]),L[F>>3]=J}if(d){continue}break}break e}if(!d){break e}while(1){d=d-1|0;b=H[d+G[G[c+2944>>2]+84>>2]|0];E[G[a+84>>2]+d|0]=b;if(!b){b=d<<3;h=L[b+G[G[c+2944>>2]+88>>2]>>3];if(h<-1|h>1){b=b+G[a+88>>2]|0;G[b>>2]=0;G[b+4>>2]=0;E[G[a+84>>2]+d|0]=1;if(d){continue}break e}F=b+G[a+88>>2]|0,J=fc(h),L[F>>3]=J}if(d){continue}break}break e}if(!d){break e}while(1){d=d-1|0;b=H[d+G[G[c+2944>>2]+84>>2]|0];E[G[a+84>>2]+d|0]=b;if(!b){b=d<<3;h=L[b+G[G[c+2944>>2]+88>>2]>>3];if(h<-1|h>1){b=b+G[a+88>>2]|0;G[b>>2]=0;G[b+4>>2]=0;E[G[a+84>>2]+d|0]=1;if(d){continue}break e}F=b+G[a+88>>2]|0,J=Sc(h),L[F>>3]=J}if(d){continue}break}break e}if(!d){break e}while(1){d=d-1|0;b=H[d+G[G[c+2944>>2]+84>>2]|0];E[G[a+84>>2]+d|0]=b;if(!b){b=d<<3;F=b+G[a+88>>2]|0,J=Pd(L[b+G[G[c+2944>>2]+88>>2]>>3]),L[F>>3]=J}if(d){continue}break}break e}if(!d){break e}while(1){d=d-1|0;b=H[d+G[G[c+2944>>2]+84>>2]|0];E[G[a+84>>2]+d|0]=b;if(!b){b=d<<3;F=b+G[a+88>>2]|0,J=wn(L[b+G[G[c+2944>>2]+88>>2]>>3]),L[F>>3]=J}if(d){continue}break}break e}if(!d){break e}while(1){d=d-1|0;b=H[d+G[G[c+2944>>2]+84>>2]|0];E[G[a+84>>2]+d|0]=b;if(!b){b=d<<3;F=b+G[a+88>>2]|0,J=vn(L[b+G[G[c+2944>>2]+88>>2]>>3]),L[F>>3]=J}if(d){continue}break}break e}if(!d){break e}while(1){d=d-1|0;b=H[d+G[G[c+2944>>2]+84>>2]|0];E[G[a+84>>2]+d|0]=b;if(!b){b=d<<3;F=b+G[a+88>>2]|0,J=un(L[b+G[G[c+2944>>2]+88>>2]>>3]),L[F>>3]=J}if(d){continue}break}break e}if(!d){break e}while(1){d=d-1|0;b=H[d+G[G[c+2944>>2]+84>>2]|0];E[G[a+84>>2]+d|0]=b;if(!b){b=d<<3;F=b+G[a+88>>2]|0,J=af(L[b+G[G[c+2944>>2]+88>>2]>>3]),L[F>>3]=J}if(d){continue}break}break e}if(!d){break e}while(1){d=d-1|0;b=H[d+G[G[c+2944>>2]+84>>2]|0];E[G[a+84>>2]+d|0]=b;if(!b){b=d<<3;h=L[b+G[G[c+2944>>2]+88>>2]>>3];if(h<=0){b=b+G[a+88>>2]|0;G[b>>2]=0;G[b+4>>2]=0;E[G[a+84>>2]+d|0]=1;if(d){continue}break e}F=b+G[a+88>>2]|0,J=oc(h),L[F>>3]=J}if(d){continue}break}break e}if(!d){break e}while(1){d=d-1|0;b=H[d+G[G[c+2944>>2]+84>>2]|0];E[G[a+84>>2]+d|0]=b;if(!b){b=d<<3;h=L[b+G[G[c+2944>>2]+88>>2]>>3];if(h<=0){b=b+G[a+88>>2]|0;G[b>>2]=0;G[b+4>>2]=0;E[G[a+84>>2]+d|0]=1;if(d){continue}break e}F=b+G[a+88>>2]|0,J=tn(h),L[F>>3]=J}if(d){continue}break}}d=G[a+8>>2];if(d){while(1){d=d-1|0;a=G[(c+2944|0)+(d<<2)>>2];if(G[a>>2]>0){Wa(G[a+88>>2])}if(d){continue}break}}Fa=c+2992|0}function Tq(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,w=0,x=0,y=0,z=0,B=0,C=0,D=0,F=0,I=0,P=0,T=0,U=0,X=0,Y=0,Z=N(0),_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=N(0),qa=0,ra=0;c=Fa-2544|0;Fa=c;G[c+2392>>2]=0;G[c+1856>>2]=0;G[c+1860>>2]=2146959360;Wc(1292356);r=G[29763];G[321435]=r;G[47589]=1;G[323090]=G[323089];G[323091]=0;G[47590]=0;G[323092]=0;G[323093]=0;E[1292384]=0;E[1292640]=0;F=1;z=1;y=1;a:{b:{c:{while(1){e=d;d=1;d:{switch(of(a,b,33061)+1|0){case 98:qa=190364,ra=_b(G[321433]),G[qa>>2]=ra;d=e;continue;case 123:y=vb(G[321433],c+1868|0);d=e;e=G[321433];if(J[c+1868>>2]>=Va(e)+e>>>0){continue}G[c+1728>>2]=e;_a(G[321435],81462,c+1728|0);break a;case 101:qa=1292364,ra=nj(G[321433]),G[qa>>2]=ra;d=e;continue;case 116:g=ac(G[321433],49010);G[321435]=g;d=e;if(g){continue}G[c+1744>>2]=G[321433];_a(0,80991,c+1744|0);break a;case 106:Za(1292640,G[321433]);d=e;continue;case 112:Za(1292384,G[321433]);d=e;continue;case 120:G[323093]=1;Za(1292896,G[321433]);d=e;continue;case 88:z=vb(G[321433],c+1868|0);d=e;e=G[321433];if(J[c+1868>>2]>=Va(e)+e>>>0){continue}G[c+1760>>2]=e;_a(G[321435],81748,c+1760|0);break a;case 117:U=vb(G[321433],c+1868|0);d=e;e=G[321433];if(J[c+1868>>2]>=Va(e)+e>>>0){continue}G[c+1776>>2]=e;_a(G[321435],81650,c+1776|0);break a;case 121:F=vb(G[321433],c+1868|0);d=e;e=G[321433];if(J[c+1868>>2]>=Va(e)+e>>>0){continue}G[c+1792>>2]=e;_a(G[321435],81558,c+1792|0);break a;case 99:t=nc(G[321433],c+1868|0,10);g=G[321433];if(J[c+1868>>2]>>0){n=1;t=0;d=e;m=Fa-8224|0;Fa=m;G[925240]=0;g=Za(m+32|0,g);if(G[323091]>=3){G[m+16>>2]=g;kb(76778,m+16|0);$a(G[29763])}u=Va(g)+g|0;while(1){e=g;if(H[e|0]==32){g=e+1|0;if(e>>>0>>0){continue}}break}e:{if(e>>>0>=u>>>0){j=G[925240];break e}o=G[29763];g=e;while(1){j=H[e|0]-32|0;if(!(!j|(j|0)==12|e>>>0>=u>>>0)){e=e+1|0;continue}E[e|0]=0;j=G[925240];qa=(j<<3)+3700976|0,ra=_b(g),G[qa>>2]=ra;while(1){f:{g=e+1|0;D=H[e+1|0];if((D|0)!=32){break f}e=g;if(u>>>0>e>>>0){continue}}break}e=g;if(u>>>0<=e>>>0){break e}while(1){j=D-32|0;if(!(!j|(j|0)==12|e>>>0>=u>>>0)){D=H[e+1|0];e=e+1|0;continue}break}E[e|0]=0;j=G[925240];D=(j<<3)+3700976|0;g=_b(g);G[D+4>>2]=g;if(G[323091]){G[m+8>>2]=g;G[m>>2]=j;G[m+4>>2]=G[D>>2];kb(73855,m);$a(o);j=G[925240]}j=j+1|0;G[925240]=j;g=e+1|0;if(u>>>0>g>>>0){continue}break}}Fa=m+8224|0;if((j|0)>3){continue}G[c+1808>>2]=G[321433];_a(G[321435],80307,c+1808|0);break a}d=e;if((t|0)>=0){continue}G[c+1824>>2]=t;_a(G[321435],82230,c+1824|0);break a;case 0:break b;case 89:continue;case 105:break d;default:break c}}j=nc(G[321433],c+1868|0,10);G[323092]=j;g=G[321433];if(J[c+1868>>2]>=Va(g)+g>>>0){d=e;if((j|0)>=0){continue}}break}G[c+1840>>2]=g;_a(G[321435],81309,c+1840|0);break a}G[c>>2]=G[b>>2];_a(G[321435],81983,c);break a}g:{h:{i:{j:{k:{l:{d=a;a=G[47589];if((d-a|0)>2){a=(a<<2)+b|0;Za(1293152,G[a>>2]);Za(1293408,G[a+4>>2]);da=Za(c+2128|0,G[a+8>>2]);Lf(1293152,0,G[323092]);Lf(da,1,0);if(H[1292640]){Lf(1292640,1,0)}if(H[1292384]){Lf(1292384,1,0)}a=Va(1293408);m:{n:{o:{if(a>>>0>=6){b=-5;d=a+1293403|0;if(!fb(d,33598,5)){break n}if(fb(d,5646,5)){break o}break n}if((a|0)!=5){break m}}b=-4;d=a+1293404|0;if(!fb(d,33380,4)){break n}if(fb(d,5001,4)){break m}}E[(a+b|0)+1293408|0]=0}Za(1293664,1293408);a=Va(1293408)+1293408|0;b=H[5646]|H[5647]<<8|(H[5648]<<16|H[5649]<<24);E[a|0]=b;E[a+1|0]=b>>>8;E[a+2|0]=b>>>16;E[a+3|0]=b>>>24;b=H[5650]|H[5651]<<8;E[a+4|0]=b;E[a+5|0]=b>>>8;a=Va(1293664)+1293664|0;b=H[5645]|H[5646]<<8|(H[5647]<<16|H[5648]<<24);d=H[5641]|H[5642]<<8|(H[5643]<<16|H[5644]<<24);E[a|0]=d;E[a+1|0]=d>>>8;E[a+2|0]=d>>>16;E[a+3|0]=d>>>24;E[a+4|0]=b;E[a+5|0]=b>>>8;E[a+6|0]=b>>>16;E[a+7|0]=b>>>24;b=H[5648]|H[5649]<<8|(H[5650]<<16|H[5651]<<24);E[a+7|0]=b;E[a+8|0]=b>>>8;E[a+9|0]=b>>>16;E[a+10|0]=b>>>24;p:{if(G[323091]<=0){break p}G[c+1712>>2]=1293152;kb(76473,c+1712|0);G[c+1696>>2]=1293408;kb(76451,c+1696|0);G[c+1680>>2]=1293664;kb(76687,c+1680|0);G[c+1664>>2]=da;kb(76276,c+1664|0);if(H[1292640]){G[c+1648>>2]=1292640;kb(90289,c+1648|0)}if(H[1292384]){G[c+1632>>2]=1292384;kb(90266,c+1632|0)}$a(r);if(G[323091]<=0){break p}Wc(1292356);L[c+1616>>3]=G[323089]-G[323090]|0;gb(91957,c+1616|0);$a(r)}a=Fa-416|0;Fa=a;G[a+412>>2]=0;q:{r:{s:{t:{u:{v:{w:{if(!Rc(1293920,1293152,0,a+412|0)){b=G[323092];if((b|0)>0){if(mb(G[323480],b+1|0,0,a+412|0)){break w}}if(Yj(G[323480],1292336,a+412|0)){break v}if(Eg(G[323480],1293956,a+412|0)){break u}x:{if(!G[323093]){break x}if(Rc(3700832,1292896,0,a+412|0)){break t}b=G[323092];if((b|0)<=0){break x}if(mb(G[925208],b+1|0,0,a+412|0)){break s}}if(G[323091]>=3){G[a>>2]=G[323084];kb(69897,a);$a(G[29763])}b=rd(G[323084]);G[323483]=b;if(!b){break r}f=L[161745];L[b+16>>3]=f+L[b+16>>3];L[b+24>>3]=f+L[b+24>>3];k=f+f;f=k+L[b+136>>3];L[b+136>>3]=f;k=k+L[b+144>>3];L[b+144>>3]=k;if(O(k)<2147483648){b=~~k}else{b=-2147483648}G[323482]=b;if(O(f)<2147483648){b=~~f}else{b=-2147483648}G[323481]=b;y:{if(de(G[323480],2,a+144|0,a+412|0)){G[a+412>>2]=0;break y}b=G[a+148>>2];G[323481]=G[a+144>>2];G[323482]=b}G[323488]=0;b=G[323483];f=L[b+32>>3];z:{A:{if(!(f<0&L[b+40>>3]<0|f>0&L[b+40>>3]>0)){b=43640;if(G[323091]>2){break A}break z}G[323488]=1;b=43704;if(G[323091]<3){break z}}yb(b)}f=2e3;b=4;B:{C:{D:{E:{F:{d=G[323483];switch(G[d+3964>>2]-1|0){case 2:break B;case 3:break D;case 1:break E;case 0:break F;default:break C}}b=0;if(L[d+120>>3]!=1950){break B}f=1950;break B}b=1;if(L[d+120>>3]==2e3){break B}f=1950;break B}if(L[d+120>>3]!=1950){b=2;break B}b=3;f=1950;break B}b=0}L[161743]=f;G[323484]=b;Fa=a+416|0;break q}G[a+128>>2]=1293152;b=a+144|0;db(b,33643,a+128|0);G[a+112>>2]=b;_a(G[321435],80471,a+112|0);break a}b=G[a+412>>2];d=a+144|0;uc(b,d);G[a+96>>2]=b;G[a+100>>2]=d;_a(G[321435],80427,a+96|0);break a}b=G[a+412>>2];d=a+144|0;uc(b,d);G[a+80>>2]=b;G[a+84>>2]=d;_a(G[321435],80427,a+80|0);break a}b=G[a+412>>2];d=a+144|0;uc(b,d);G[a+64>>2]=b;G[a+68>>2]=d;_a(G[321435],80427,a- -64|0);break a}G[a+48>>2]=1292896;b=a+144|0;db(b,33604,a+48|0);G[a+32>>2]=b;_a(G[321435],80471,a+32|0);break a}b=G[a+412>>2];d=a+144|0;uc(b,d);G[a+16>>2]=b;G[a+20>>2]=d;_a(G[321435],80427,a+16|0);break a}hb(84433,53,1,G[321435]);break a}if(H[1292640]){mj(1292640,1)}if(G[323091]>0){G[c+1600>>2]=G[323481];kb(73494,c+1600|0);G[c+1584>>2]=G[323482];kb(73469,c+1584|0);G[c+1568>>2]=G[323484];kb(75841,c+1568|0);L[c+1552>>3]=L[161743];gb(70933,c+1552|0);G[c+1536>>2]=G[323488];kb(75769,c+1536|0);G[c+1520>>2]=G[323483]+3544;kb(90117,c+1520|0);$a(r)}a=G[323483]+3544|0;G:{if(!Xa(a,34606)){break G}if(!Xa(a,34543)){break G}if(!Xa(a,35981)){break G}if(!Xa(a,35072)){break G}if(Xa(a,35873)){break l}}G[323490]=0;G[323491]=0;if(e){a=G[323482];b=M(a,a);a=G[323481];h=V(+(b+M(a,a)|0));H:{if(O(h)<2147483648){a=~~h;break H}a=-2147483648}h=+(a|0);L[161745]=h}if(G[323091]>0){L[c+1488>>3]=h;gb(90054,c+1488|0);$a(r)}_=G[323489];mj(da,0);ga=(_|0)==-64;if(H[1292384]){mj(1292384,2)}D=ga?-64:-32;if(G[323091]>0){G[c+1472>>2]=G[323493];kb(73443,c+1472|0);G[c+1456>>2]=G[323494];kb(73418,c+1456|0);G[c+1440>>2]=G[323496];kb(75817,c+1440|0);L[c+1424>>3]=L[161749];gb(70908,c+1424|0);G[c+1408>>2]=G[323500];kb(75745,c+1408|0);G[c+1392>>2]=G[323495]+3544;kb(69711,c+1392|0);G[c+1376>>2]=D;kb(75793,c+1376|0);$a(r)}a=G[323495]+3544|0;I:{if(!Xa(a,34606)){break I}if(!Xa(a,34543)){break I}if(!Xa(a,35981)){break I}if(!Xa(a,35072)){break I}if(Xa(a,35873)){break k}}if(G[323484]!=G[323496]){break j}a=H[1292384];J:{if(H[1292640]){if(a){a=Th(1300832,2100832);break J}a=Th(1300832,2900832);break J}b=G[323084];if(a){a=Th(b,2100832);break J}a=Th(b,2900832)}G[c+2392>>2]=a;if(a){break i}if(G[323091]>=2){yb(16676);$a(r)}g=G[323481];a=M(g,24)+24|0;qa=1292340,ra=ab(a),G[qa>>2]=ra;qa=1292348,ra=ab(a),G[qa>>2]=ra;qa=1292344,ra=ab(a),G[qa>>2]=ra;qa=1292352,ra=ab(a),G[qa>>2]=ra;a=g<<3;fa=ab(a);if(G[323093]){ia=ab(a)}d=0;h=-1e8;l=1e8;if(G[323482]<0){k=1e8;i=-1e8;break g}i=-1e8;k=1e8;while(1){b=d;q=+(d|0)+.5;he(.5,q,c+2440|0,c+2432|0);f=L[c+2440>>3];a=1;K:{if(f<-.5){break K}a=1;if(f>+G[323533]+1.5){break K}p=L[c+2432>>3];a=1;if(p<-.5){break K}a=p>+G[323535]+1.5}if(G[323091]>=3){L[c+1312>>3]=f;L[c+1320>>3]=L[c+2432>>3];G[c+1328>>2]=a;G[c+1296>>2]=0;G[c+1300>>2]=1071644672;L[c+1304>>3]=q;gb(87953,c+1296|0);$a(r);cc(G[323483],.5,q,c+2408|0,c+2400|0);Bd(G[323495],L[c+2408>>3],L[c+2400>>3],c+2424|0,c+2416|0,c+2396|0);L[c+1264>>3]=L[c+2424>>3];L[c+1272>>3]=L[c+2416>>3];G[c+1280>>2]=G[c+2396>>2];L[c+1248>>3]=L[c+2408>>3];L[c+1256>>3]=L[c+2400>>3];gb(87888,c+1248|0)}L:{if(!a){f=L[c+2432>>3];l=f>3];i=ip?p:k;if(f>h){break L}}f=h}he(+G[323481]+.5,q,c+2440|0,c+2432|0);d=1;h=L[c+2440>>3];M:{if(h<-.5|h>+G[323533]+1.5){break M}p=L[c+2432>>3];if(p<-.5){break M}d=p>+G[323535]+1.5}if(G[323091]>=3){L[c+1216>>3]=h;L[c+1224>>3]=L[c+2432>>3];G[c+1232>>2]=d;L[c+1208>>3]=q;L[c+1200>>3]=+G[323481]+.5;gb(87953,c+1200|0);$a(r);cc(G[323483],+G[323481]+.5,q,c+2408|0,c+2400|0);Bd(G[323495],L[c+2408>>3],L[c+2400>>3],c+2424|0,c+2416|0,c+2396|0);L[c+1168>>3]=L[c+2424>>3];L[c+1176>>3]=L[c+2416>>3];G[c+1184>>2]=G[c+2396>>2];L[c+1152>>3]=L[c+2408>>3];L[c+1160>>3]=L[c+2400>>3];gb(87888,c+1152|0)}N:{if(!d){h=L[c+2432>>3];l=h>3];i=iq?q:k;if(f>2]=G[b>>2];_a(G[321435],81983,c+16|0);break a}G[c+1504>>2]=a;a=c+1872|0;db(a,14454,c+1504|0);lj(a);W()}G[c+1360>>2]=a;a=c+1872|0;db(a,14369,c+1360|0);lj(a);W()}G[c+1344>>2]=14292;_a(G[321435],80471,c+1344|0);break a}hb(83546,102,1,G[321435]);break a}g=G[323481]}d=0;if((g|0)>=0){while(1){b=d;q=+(d|0)+.5;he(q,.5,c+2440|0,c+2432|0);f=L[c+2440>>3];a=1;O:{if(f<-.5){break O}a=1;if(f>+G[323533]+1.5){break O}p=L[c+2432>>3];a=1;if(p<-.5){break O}a=p>+G[323535]+1.5}if(G[323091]>=3){L[c+1120>>3]=f;L[c+1128>>3]=L[c+2432>>3];G[c+1136>>2]=a;L[c+1104>>3]=q;G[c+1112>>2]=0;G[c+1116>>2]=1071644672;gb(87953,c+1104|0);$a(r);cc(G[323483],q,.5,c+2408|0,c+2400|0);Bd(G[323495],L[c+2408>>3],L[c+2400>>3],c+2424|0,c+2416|0,c+2396|0);L[c+1072>>3]=L[c+2424>>3];L[c+1080>>3]=L[c+2416>>3];G[c+1088>>2]=G[c+2396>>2];L[c+1056>>3]=L[c+2408>>3];L[c+1064>>3]=L[c+2400>>3];gb(87888,c+1056|0)}P:{if(!a){f=L[c+2432>>3];l=f>3];i=ip?p:k;if(f>h){break P}}f=h}he(q,+G[323482]+.5,c+2440|0,c+2432|0);d=1;h=L[c+2440>>3];Q:{if(h<-.5|h>+G[323533]+1.5){break Q}p=L[c+2432>>3];if(p<-.5){break Q}d=p>+G[323535]+1.5}if(G[323091]>=3){L[c+1024>>3]=h;L[c+1032>>3]=L[c+2432>>3];G[c+1040>>2]=d;L[c+1008>>3]=q;L[c+1016>>3]=+G[323482]+.5;gb(87953,c+1008|0);$a(r);cc(G[323483],q,+G[323482]+.5,c+2408|0,c+2400|0);Bd(G[323495],L[c+2408>>3],L[c+2400>>3],c+2424|0,c+2416|0,c+2396|0);L[c+976>>3]=L[c+2424>>3];L[c+984>>3]=L[c+2416>>3];G[c+992>>2]=G[c+2396>>2];L[c+960>>3]=L[c+2408>>3];L[c+968>>3]=L[c+2400>>3];gb(87888,c+960|0)}R:{if(!d){h=L[c+2432>>3];l=h>3];i=iq?q:k;if(f=0){while(1){G[c+2440>>2]=0;G[c+2444>>2]=1071644672;e=d;f=+(d|0)+.5;L[c+2432>>3]=f;Uh(.5,f,c+1872|0,c+2448|0);q=L[c+1872>>3];a=1;S:{if(q<-.5){break S}a=1;if(q>+G[323532]+1.5){break S}p=L[c+2448>>3];a=1;if(p<-.5){break S}a=p>+G[323534]+1.5}if(G[323091]>=3){L[c+928>>3]=q;L[c+936>>3]=L[c+2448>>3];G[c+944>>2]=a;G[c+912>>2]=0;G[c+916>>2]=1071644672;L[c+920>>3]=f;gb(87920,c+912|0);$a(r)}T:{if(!a){l=fh){break T}}f=h}q=+G[323493]+.5;L[c+2440>>3]=q;h=L[c+2432>>3];Uh(q,h,c+1872|0,c+2448|0);d=1;p=L[c+1872>>3];U:{if(p<-.5|p>+G[323532]+1.5){break U}s=L[c+2448>>3];if(s<-.5){break U}d=s>+G[323534]+1.5}if(G[323091]>=3){L[c+880>>3]=p;L[c+888>>3]=L[c+2448>>3];G[c+896>>2]=d;L[c+864>>3]=q;L[c+872>>3]=h;gb(87920,c+864|0);$a(r)}V:{if(!d){l=hq?q:k;if(f=0){while(1){G[c+2432>>2]=0;G[c+2436>>2]=1071644672;b=d;f=+(d|0)+.5;L[c+2440>>3]=f;Uh(f,.5,c+1872|0,c+2448|0);q=L[c+1872>>3];a=1;W:{if(q<-.5){break W}a=1;if(q>+G[323532]+1.5){break W}p=L[c+2448>>3];a=1;if(p<-.5){break W}a=p>+G[323534]+1.5}if(G[323091]>=3){L[c+832>>3]=q;L[c+840>>3]=L[c+2448>>3];G[c+848>>2]=a;L[c+816>>3]=f;G[c+824>>2]=0;G[c+828>>2]=1071644672;gb(87920,c+816|0);$a(r)}X:{if(a){break X}i=f>i?f:i;k=f>3]=h;q=L[c+2440>>3];Uh(q,h,c+1872|0,c+2448|0);d=1;p=L[c+1872>>3];Y:{if(p<-.5|p>+G[323532]+1.5){break Y}s=L[c+2448>>3];if(s<-.5){break Y}d=s>+G[323534]+1.5}if(G[323091]>=3){L[c+784>>3]=p;L[c+792>>3]=L[c+2448>>3];G[c+800>>2]=d;L[c+768>>3]=q;L[c+776>>3]=h;gb(87920,c+768|0);$a(r)}Z:{if(!d){l=hq?q:k;if(f0;f=k+-1;$:{if(O(f)<2147483648){d=~~f;break $}d=-2147483648}m=(d|0)>0;I=j?e:0;ba=m?d:0;f=h-l+2;aa:{if(O(f)<2147483648){g=~~f;break aa}g=-2147483648}w=(b|0)<(g|0)?b:g;f=i-k+2;ba:{if(O(f)<2147483648){b=~~f;break ba}b=-2147483648}x=(a|0)<(b|0)?a:b;if(G[323091]>=2){yb(38515);L[c+752>>3]=k;gb(70528,c+752|0);L[c+736>>3]=i;gb(70462,c+736|0);L[c+720>>3]=l;gb(70511,c+720|0);L[c+704>>3]=h;gb(70445,c+704|0);G[c+688>>2]=ba;kb(74016,c+688|0);G[c+672>>2]=x;kb(73982,c+672|0);G[c+656>>2]=I;kb(73999,c+656|0);G[c+640>>2]=w;kb(73965,c+640|0);$a(r)}ca:{da:{ea:{fa:{ga:{if(!(i>2]=b;if(!b){break ja}d=d+1|0;if((w|0)!=(d|0)){continue}break ha}break}break ea}if(G[323091]>0){G[c+624>>2]=M(w,M(e,x));kb(68827,c+624|0);$a(r)}a=(w|0)>0&(x|0)>0;ka:{if((_|0)!=-64){if(!a){break ka}B=x&-8;m=x&7;j=0;ca=x-1>>>0<7;while(1){a=G[(j<<2)+C>>2];b=0;o=0;if(!ca){while(1){d=b<<2;G[d+a>>2]=2143289344;G[a+(d|4)>>2]=2143289344;G[a+(d|8)>>2]=2143289344;G[a+(d|12)>>2]=2143289344;G[a+(d|16)>>2]=2143289344;G[a+(d|20)>>2]=2143289344;G[a+(d|24)>>2]=2143289344;G[a+(d|28)>>2]=2143289344;b=b+8|0;o=o+8|0;if((B|0)!=(o|0)){continue}break}}g=0;if(m){while(1){G[a+(b<<2)>>2]=2143289344;b=b+1|0;g=g+1|0;if((m|0)!=(g|0)){continue}break}}j=j+1|0;if((w|0)!=(j|0)){continue}break}break ka}if(!a){break ka}B=x&-8;m=x&7;j=0;ca=x-1>>>0<7;while(1){a=G[(j<<2)+C>>2];b=0;o=0;if(!ca){while(1){d=b<<3;g=d+a|0;G[g>>2]=0;G[g+4>>2]=2146959360;g=a+(d|8)|0;G[g>>2]=0;G[g+4>>2]=2146959360;g=a+(d|16)|0;G[g>>2]=0;G[g+4>>2]=2146959360;g=a+(d|24)|0;G[g>>2]=0;G[g+4>>2]=2146959360;g=a+(d|32)|0;G[g>>2]=0;G[g+4>>2]=2146959360;g=a+(d|40)|0;G[g>>2]=0;G[g+4>>2]=2146959360;g=a+(d|48)|0;G[g>>2]=0;G[g+4>>2]=2146959360;d=a+(d|56)|0;G[d>>2]=0;G[d+4>>2]=2146959360;b=b+8|0;o=o+8|0;if((B|0)!=(o|0)){continue}break}}g=0;if(m){while(1){d=a+(b<<3)|0;G[d>>2]=0;G[d+4>>2]=2146959360;b=b+1|0;g=g+1|0;if((m|0)!=(g|0)){continue}break}}j=j+1|0;if((w|0)!=(j|0)){continue}break}}B=ab(u);if(B){if((w|0)>0){g=x<<3;j=x<<2;m=M(e,x);u=(_|0)==-64;b=(x|0)<=0;d=0;while(1){a=ab(m);G[B+(d<<2)>>2]=a;if(!a){break da}la:{if(!u){if(b){break la}cb(a,0,j);break la}if(b){break la}cb(a,0,g)}d=d+1|0;if((w|0)!=(d|0)){continue}break}}if(G[323091]>0){G[c+608>>2]=M(w,M(e,x));kb(68942,c+608|0);$a(r)}G[c+2488>>2]=1;G[c+2492>>2]=1;G[c+2480>>2]=1;G[c+2484>>2]=t+1;if((G[323482]-t|0)>(t|0)){a=G[323481];ca=a;ja=a>>31;na=(n|0)!=1;q=y*-.5;oa=(_|0)!=-64;j=t;k=z;while(1){a=G[323481];ma:{na:{if(!na){u=a-1|0;m=0;X=G[925240];oa:{if((X|0)<=0){n=0;break oa}p=+(j|0);n=0;e=G[925244];g=G[925245];f=+(a|0);d=1;i=0;o=1;while(1){pa:{m=(d|0)==(X|0);b=((m?0:d)<<3)+3700976|0;a=G[b>>2];l=+(g|0);b=G[b+4>>2];s=+(b|0);if(!(p>(ls?l:s))){d=d+1|0;e=a;g=b;if(!m){continue}m=0;if(!o){break pa}n=0;break oa}l=(p-l)*+(a-e|0)/+(b-g|0)+ +(e|0);i=i>l?i:l;f=f0?a:0}if(G[323091]>=2){G[c+588>>2]=n;G[c+584>>2]=u;G[c+580>>2]=m;G[c+576>>2]=j;kb(62587,c+576|0);$a(r)}if(n){break na}G[c+2484>>2]=G[c+2484>>2]+1;break ma}u=a-t|0;if(G[323091]==2){G[c+592>>2]=j;kb(67859,c+592|0);$a(r)}m=t}if(!cg(G[323480],82,c+2480|0,ca,ja,c+1856|0,fa,c+2508|0,c+2392|0)){ra:{if(G[323093]){if(cg(G[925208],82,c+2480|0,ca,ja,c+1856|0,ia,c+2508|0,c+2392|0)){break ra}}G[c+2484>>2]=G[c+2484>>2]+1;sa:{ta:{if(!(y==1&ka)){if(G[323481]<0){break sa}if(y!=1){f=q+ +(j+1|0);d=0;while(1){a=d+1|0;i=+(a|0);b=M(d,24);e=b+G[323085]|0;e=he(q+i,f,e,e+8|0);G[(b+G[323085]|0)+16>>2]=e;e=b+G[323087]|0;e=he(y*.5+i,f,e,e+8|0);G[(b+G[323087]|0)+16>>2]=e;g=G[323481];b=(g|0)>(d|0);d=a;if(b){continue}break}break ta}f=+(j|0)+.5;a=G[323085];a=he(.5,f,a,a+8|0);n=G[323085];G[n+16>>2]=a;ka=1;d=1;g=G[323481];if((g|0)<=0){break ta}while(1){a=M(d,24);b=a+n|0;b=he(+(d|0)+.5,f,b,b+8|0);n=G[323085];e=a+n|0;G[e+16>>2]=b;a=(a+G[323087]|0)-24|0;L[a>>3]=L[e>>3];i=L[e+8>>3];G[a+16>>2]=b;L[a+8>>3]=i;g=G[323481];a=(g|0)>(d|0);d=d+1|0;if(a){continue}break}break ta}a=G[323085];G[323085]=G[323086];G[323086]=a;a=G[323087];G[323087]=G[323088];G[925218]=a;G[323088]=a;g=G[323481];ka=1}if((g|0)<0){break sa}if(y!=1){i=y*.5;f=i+ +(j+1|0);d=0;while(1){a=d+1|0;l=+(a|0);b=M(d,24);e=b+G[323086]|0;e=he(q+l,f,e,e+8|0);G[(b+G[323086]|0)+16>>2]=e;e=b+G[323088]|0;e=he(i+l,f,e,e+8|0);G[(b+G[323088]|0)+16>>2]=e;b=G[323481]>(d|0);d=a;if(b){continue}break}break sa}f=+(j|0)+1.5;a=G[323086];a=he(.5,f,a,a+8|0);n=G[323086];G[n+16>>2]=a;d=1;if(G[323481]<=0){break sa}while(1){a=M(d,24);b=a+n|0;b=he(+(d|0)+.5,f,b,b+8|0);n=G[323086];e=a+n|0;G[e+16>>2]=b;a=(a+G[323088]|0)-24|0;L[a>>3]=L[e>>3];i=L[e+8>>3];G[a+16>>2]=b;L[a+8>>3]=i;a=G[323481]>(d|0);d=d+1|0;if(a){continue}break}}if((m|0)>=(u|0)){break ma}while(1){a=m<<3;f=L[a+fa>>3];b=G[323093];if(b){k=L[a+ia>>3];k=z*(k>>0>2146435072|(a&2146435072)==2146435072){break ua}f=F*f;if(G[323091]>=3){va:{if(b){L[c+528>>3]=k;L[c+520>>3]=f;G[c+516>>2]=m;G[c+512>>2]=j;gb(91901,c+512|0);break va}L[c+504>>3]=f;G[c+500>>2]=m;G[c+496>>2]=j;gb(90181,c+496|0)}$a(r)}wa:{if(G[323488]){b=G[323088];a=M(m,24);d=b+a|0;L[c+1872>>3]=L[d>>3];L[c+2448>>3]=L[d+8>>3];o=G[323086];d=a+o|0;L[c+1880>>3]=L[d>>3];L[c+2456>>3]=L[d+8>>3];e=G[323085];a=a+e|0;L[c+1888>>3]=L[a>>3];L[c+2464>>3]=L[a+8>>3];g=G[323087];n=g;break wa}n=G[323087];a=M(m,24);b=n+a|0;L[c+1872>>3]=L[b>>3];L[c+2448>>3]=L[b+8>>3];e=G[323085];b=a+e|0;L[c+1880>>3]=L[b>>3];L[c+2456>>3]=L[b+8>>3];o=G[323086];a=a+o|0;L[c+1888>>3]=L[a>>3];L[c+2464>>3]=L[a+8>>3];g=G[323088];b=g}a=M(m,24);d=a+g|0;L[c+1896>>3]=L[d>>3];L[c+2472>>3]=L[d+8>>3];b=a+b|0;if(G[b+16>>2]){break ua}d=a+o|0;if(G[d+16>>2]){break ua}g=a+n|0;if(G[g+16>>2]){break ua}a=a+e|0;if(G[a+16>>2]){break ua}i=L[d+8>>3];l=L[g+8>>3];p=L[a+8>>3];s=p>-1e8?p:-1e8;s=l>s?l:s;la=i>s?i:s;s=L[b+8>>3];n=la>3];$=L[g>>3];aa=L[a>>3];T=aa>-1e8?aa:-1e8;T=T<$?$:T;ma=P>T?P:T;T=L[b>>3];aa=aa<1e8?aa:1e8;$=$T?T:P;d=G[323091];p=p<1e8?p:1e8;l=ls?s:i;i=S(p+-.5);xa:{if(O(i)<2147483648){e=~~i;break xa}e=-2147483648}b=T>ma;i=n?s:la;l=S(P+-.5);ya:{if(O(l)<2147483648){a=~~l;break ya}a=-2147483648}l=b?T:ma;s=S(i+-.5)+1;za:{if(O(s)<2147483648){b=~~s;break za}b=-2147483648}d=(d|0)<3;s=S(l+-.5)+1;Aa:{if(O(s)<2147483648){g=~~s;break Aa}g=-2147483648}if(!d){id();L[c+480>>3]=P;gb(73190,c+480|0);L[c+464>>3]=l;gb(73148,c+464|0);L[c+448>>3]=p;gb(73169,c+448|0);L[c+432>>3]=i;gb(73127,c+432|0);id();G[c+420>>2]=g;G[c+416>>2]=a;kb(73913,c+416|0);G[c+404>>2]=b;G[c+400>>2]=e;kb(73885,c+400|0);id()}if((b|0)<=(e|0)|(a|0)>=(g|0)){break ua}Ba:{if(!oa){if(!(k>0)){break Ba}while(1){d=e-I|0;if(!((d|0)<0|(d|0)>=(w|0))){d=d<<2;X=d+B|0;ea=d+C|0;i=+(e|0);l=i+.5;p=i+1.5;d=a;while(1){n=d-ba|0;Ca:{if((n|0)<0|(n|0)>=(x|0)){break Ca}h=+(d|0);h=gm(c+1872|0,c+2448|0,h+.5,h+1.5,l,p,L[462610]);Y=n<<3;n=Y+G[ea>>2]|0;s=L[n>>3];A(+s);o=v(1)|0;ha=v(0)|0;i=f*h*k;s=(o&2146435072)==2146435072?i:i+s;o=o&2147483647;L[n>>3]=(o|0)==2146435072&(ha|0)!=0|o>>>0>2146435072?i:s;o=Y+G[X>>2]|0;L[o>>3]=h*k+L[o>>3];if(G[323091]<3){break Ca}G[c+300>>2]=m;G[c+296>>2]=j;G[c+292>>2]=d;G[c+288>>2]=e;kb(66704,c+288|0);i=L[n>>3];L[c+272>>3]=L[o>>3];L[c+264>>3]=i;L[c+256>>3]=h;gb(87725,c+256|0);$a(r)}d=d+1|0;if((g|0)>(d|0)){continue}break}}e=e+1|0;if((b|0)!=(e|0)){continue}break}break ua}while(1){d=e-I|0;if(!((d|0)<0|(d|0)>=(w|0))){d=d<<2;X=d+B|0;ea=d+C|0;i=+(e|0);l=i+.5;p=i+1.5;d=a;while(1){n=d-ba|0;Da:{if((n|0)<0|(n|0)>=(x|0)){break Da}if(k>0){h=+(d|0);h=gm(c+1872|0,c+2448|0,h+.5,h+1.5,l,p,L[462610])}i=f*h*k;o=n<<2;n=o+G[ea>>2]|0;s=i+ +K[n>>2];Y=G[n>>2];K[n>>2]=(Y&2147483647)>>>0>2139095040?i:(Y&2139095040)==2139095040?i:s;o=o+G[X>>2]|0;K[o>>2]=h*k+ +K[o>>2];if(G[323091]<3){break Da}G[c+396>>2]=m;G[c+392>>2]=j;G[c+388>>2]=d;G[c+384>>2]=e;kb(66704,c+384|0);Z=K[n>>2];L[c+368>>3]=K[o>>2];L[c+352>>3]=h;L[c+360>>3]=Z;gb(87725,c+352|0);$a(r)}d=d+1|0;if((g|0)>(d|0)){continue}break}}e=e+1|0;if((b|0)!=(e|0)){continue}break}break ua}f=k*(f*h);while(1){d=e-I|0;if(!((d|0)<0|(d|0)>=(w|0))){d=d<<2;X=d+B|0;ea=d+C|0;d=a;while(1){n=d-ba|0;Ea:{if((n|0)<0|(n|0)>=(x|0)){break Ea}Y=n<<3;n=Y+G[ea>>2]|0;i=L[n>>3];A(+i);o=v(1)|0;ha=v(0)|0;i=(o&2146435072)==2146435072?f:f+i;o=o&2147483647;L[n>>3]=(o|0)==2146435072&(ha|0)!=0|o>>>0>2146435072?f:i;o=Y+G[X>>2]|0;L[o>>3]=h*k+L[o>>3];if(G[323091]<3){break Ea}G[c+348>>2]=m;G[c+344>>2]=j;G[c+340>>2]=d;G[c+336>>2]=e;kb(66704,c+336|0);i=L[n>>3];L[c+320>>3]=L[o>>3];L[c+312>>3]=i;L[c+304>>3]=h;gb(87725,c+304|0);$a(r)}d=d+1|0;if((g|0)>(d|0)){continue}break}}e=e+1|0;if((b|0)!=(e|0)){continue}break}}m=m+1|0;if((u|0)!=(m|0)){continue}break}break ma}a=G[c+2392>>2];b=c+2512|0;uc(a,b);G[c+544>>2]=a;G[c+548>>2]=b;_a(G[321435],80427,c+544|0);break a}a=G[c+2392>>2];b=c+2512|0;uc(a,b);G[c+560>>2]=a;G[c+564>>2]=b;_a(G[321435],80427,c+560|0);break a}j=j+1|0;if((j|0)<(G[323482]-t|0)){continue}break}}if(G[323091]>0){Wc(1292356);L[c+240>>3]=G[323089]-G[323090]|0;gb(91859,c+240|0);$a(r)}if(!Qb(G[323480],c+2392|0)){e=0;a=(w|0)>0&(x|0)>0;if((_|0)!=-64){z=0;g=99999;if(!a){break ga}n=0;k=0;y=0;F=0;o=0;t=0;b=99999;while(1){a=e<<2;m=G[a+C>>2];u=G[a+B>>2];pa=N(L[c+1856>>3]);d=0;while(1){j=d<<2;a=j+m|0;j=j+u|0;Z=K[j>>2];Fa:{if(!(Z>N(0))){K[a>>2]=pa;G[j>>2]=0;break Fa}Z=N(K[a>>2]/Z);K[a>>2]=Z;Ga:{if(n){h=+Z;U=+K[j>>2];break Ga}h=+Z;F=h;y=h;U=+K[j>>2];k=U;z=k}t=(e|0)>(t|0)?e:t;b=(b|0)>(e|0)?e:b;o=(d|0)>(o|0)?d:o;g=(d|0)<(g|0)?d:g;z=zU?U:k;y=h>y?h:y;F=h>2];d=0;while(1){m=d<<3;a=m+u|0;h=L[a>>3];Ha:{if(!(h>0)){L[m+G[j>>2]>>3]=L[c+1856>>3];G[a>>2]=0;G[a+4>>2]=0;break Ha}m=m+G[j>>2]|0;h=L[m>>3]/h;L[m>>3]=h;f=L[a>>3];z=n?z:f;z=f>z?f:z;k=n?k:f;k=fh?h:f;t=(e|0)>(t|0)?e:t;b=(b|0)>(e|0)?e:b;o=(d|0)>(o|0)?d:o;g=(d|0)<(g|0)?d:g;n=1}d=d+1|0;if((x|0)!=(d|0)){continue}break}e=e+1|0;if((w|0)!=(e|0)){continue}break}break fa}break ca}break da}hb(82189,40,1,G[321435]);break a}b=99999;t=0;o=0;F=0;y=0;k=0}j=t+I|0;a=b+I|0;d=o+ba|0;m=g+ba|0;if(G[323091]>0){L[c+224>>3]=F;gb(70479,c+224|0);L[c+208>>3]=y;gb(70429,c+208|0);L[c+192>>3]=k;gb(70495,c+192|0);L[c+176>>3]=z;gb(90164,c+176|0);G[c+160>>2]=m;kb(75656,c+160|0);G[c+144>>2]=d;kb(75626,c+144|0);G[c+128>>2]=a;kb(75641,c+128|0);G[c+112>>2]=j;kb(75611,c+112|0)}Ia:{Ja:{Ka:{La:{Ma:{Na:{if(!((b|0)>(t|0)|(g|0)>(o|0))){Ed(1293408);Ed(1293664);if(sd(1293968,1293408,c+2392|0)){break ca}if(G[47591]){if(sd(3700888,1293664,c+2392|0)){break ca}}if(pd(G[323492],D,2,1293972,c+2392|0)){break ca}if(G[323091]>0){yb(62207);$a(r)}Oa:{if(!G[47591]){break Oa}if(pd(G[925222],D,2,3700892,c+2392|0)){break ca}if(G[323091]<=0){break Oa}yb(62252);$a(r)}if(Xi(G[323492],da,c+2392|0)){break ca}if(G[323091]>0){yb(24964);$a(r)}Pa:{if(!G[47591]){break Pa}if(Xi(G[925222],da,c+2392|0)){break ca}if(G[323091]<=0){break Pa}yb(72935);$a(r)}b=D>>31;if(Gc(G[323492],32941,D,b,0,c+2392|0)){break ca}if(G[47591]){if(Gc(G[925222],32941,D,b,0,c+2392|0)){break ca}}if(Gc(G[323492],33788,2,0,0,c+2392|0)){break ca}d=(d-m|0)+1|0;b=d>>31;e=d;if(Gc(G[323492],41261,d,b,0,c+2392|0)){break ca}t=(j-a|0)+1|0;d=t>>31;if(Gc(G[323492],40853,t,d,0,c+2392|0)){break ca}h=+(m|0);if(Kd(G[323492],41201,L[462616]-h,-14,0,c+2392|0)){break ca}f=+(a|0);if(Kd(G[323492],40799,L[462617]-f,-14,0,c+2392|0)){break ca}if(Kd(G[323492],41229,L[462618]-h,-14,0,c+2392|0)){break ca}if(Kd(G[323492],40821,L[462619]-f,-14,0,c+2392|0)){break ca}Qa:{if(!G[47591]){break Qa}if(Gc(G[925222],33788,2,0,0,c+2392|0)){break ca}if(Gc(G[925222],41261,e,b,0,c+2392|0)){break ca}if(Gc(G[925222],40853,t,d,0,c+2392|0)){break ca}if(Kd(G[925222],41201,L[462616]-h,-14,0,c+2392|0)){break ca}if(Kd(G[925222],40799,L[462617]-f,-14,0,c+2392|0)){break ca}if(Kd(G[925222],41229,L[462618]-h,-14,0,c+2392|0)){break ca}if(Kd(G[925222],40821,L[462619]-f,-14,0,c+2392|0)){break ca}if(!G[323091]){break Qa}yb(29099);$a(r)}t=ga?82:42;G[c+2480>>2]=1;G[c+2484>>2]=1;j=(a|0)>(j|0)?a:j;Ra:{if((_|0)==-64){m=g<<3;d=a;while(1){if(ag(G[323492],t,c+2480|0,e,b,m+G[(d-I<<2)+C>>2]|0,c+2392|0)){break Na}G[c+2484>>2]=G[c+2484>>2]+1;u=(d|0)==(j|0);d=d+1|0;if(!u){continue}break}break Ra}d=a;while(1){if(ag(G[323492],t,c+2480|0,e,b,G[(d-I<<2)+C>>2]+(g<<2)|0,c+2392|0)){break Ma}G[c+2484>>2]=G[c+2484>>2]+1;m=(d|0)!=(j|0);d=d+1|0;if(m){continue}break}}if(G[323091]>0){yb(25009);$a(r)}Sa:{if(!G[47591]){break Sa}G[c+2480>>2]=1;G[c+2484>>2]=1;if((_|0)==-64){d=g<<3;while(1){if(ag(G[925222],t,c+2480|0,e,b,d+G[B+(a-I<<2)>>2]|0,c+2392|0)){break La}G[c+2484>>2]=G[c+2484>>2]+1;g=(a|0)==(j|0);a=a+1|0;if(!g){continue}break}break Sa}while(1){if(ag(G[925222],t,c+2480|0,e,b,G[B+(a-I<<2)>>2]+(g<<2)|0,c+2392|0)){break Ka}G[c+2484>>2]=G[c+2484>>2]+1;d=(a|0)!=(j|0);a=a+1|0;if(d){continue}break}}if(G[323091]>0){yb(72981);$a(r)}if(Qb(G[323492],c+2392|0)){break ca}if(G[323091]>0){yb(27772);$a(r)}Ta:{if(!G[47591]){break Ta}if(Qb(G[925222],c+2392|0)){break ca}if(G[323091]<=0){break Ta}yb(73519);$a(r)}d=0;if((w|0)<=0){break Ja}while(1){Wa(G[(d<<2)+C>>2]);d=d+1|0;if((w|0)!=(d|0)){continue}break}Wa(C);if((w|0)<=0){break Ia}d=0;while(1){Wa(G[B+(d<<2)>>2]);d=d+1|0;if((w|0)!=(d|0)){continue}break}break Ia}lj(43899);W()}a=G[c+2392>>2];b=c+2512|0;uc(a,b);G[c+80>>2]=a;G[c+84>>2]=b;_a(G[321435],80427,c+80|0);break a}a=G[c+2392>>2];b=c+2512|0;uc(a,b);G[c+96>>2]=a;G[c+100>>2]=b;_a(G[321435],80427,c+96|0);break a}a=G[c+2392>>2];b=c+2512|0;uc(a,b);G[c+48>>2]=a;G[c+52>>2]=b;_a(G[321435],80427,c+48|0);break a}a=G[c+2392>>2];b=c+2512|0;uc(a,b);G[c+64>>2]=a;G[c+68>>2]=b;_a(G[321435],80427,c- -64|0);break a}Wa(C)}Wa(B);a=G[323085];if(a){Wa(a)}a=G[323086];if(a){Wa(a)}a=G[323087];if(a){Wa(a)}a=G[323088];if(a){Wa(a)}if(fa){Wa(fa)}a=G[323483];if(a){Ce(a)}a=G[323495];if(a){Ce(a)}a=G[323084];if(a){Wa(a)}Wc(1292356);L[c+32>>3]=G[323089]-G[323090]|0;xb(G[321435],77637,c+32|0);$a(r);$a(G[321435]);Hb(G[321435]);sc(0);W()}hb(79462,75,1,G[321435]);break a}hb(79538,75,1,G[321435]);break a}a=Fa-48|0;Fa=a;b=G[c+2392>>2];d=a+16|0;uc(b,d);G[a>>2]=b;G[a+4>>2]=d;_a(G[321435],80427,a)}$a(G[321435]);Hb(G[321435]);sc(1);W()}function Sq(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,I=0,J=0,K=0,N=0,P=0,Q=0,R=0,T=0,U=0,V=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0;c=Fa-82640|0;Fa=c;G[c+1304>>2]=0;G[c+1308>>2]=2146959360;Wc(3705196);Y=1;G[926296]=1;n=G[29763];G[321435]=n;G[47589]=1;G[926300]=G[926299];E[c+1568|0]=0;G[926301]=0;G[47590]=0;d=1;a:{b:{c:{d:{e:{f:{g:{h:{i:{while(1){e=d;d=0;j:{k:{l:{m:{n:{i=of(a,b,38893);switch(i-97|0){case 4:continue;case 18:break j;case 13:break k;case 3:break l;case 15:break m;case 0:break n;case 1:case 2:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 14:case 16:case 17:break h;default:break i}}Y=1;d=e;e=Za(c+2080|0,G[321433]);if(!nb(e,16019,5)){continue}Y=2;if(!nb(e,16012,7)){continue}Y=4;if(!nb(e,4678,6)){continue}yb(32573);$a(n);break a}Za(c+1568|0,G[321433]);d=e;continue}fa=3705204,ga=nj(G[321433]),G[fa>>2]=ga;d=e;continue}G[926296]=0;d=e;continue}i=ac(G[321433],49010);G[321435]=i;d=e;if(i){continue}break}G[c+1296>>2]=G[321433];kb(80991,c+1296|0);break a}if((i|0)!=-1){break h}d=a;a=G[47589];if((d-a|0)>2){a=(a<<2)+b|0;g=Za(c+1312|0,G[a>>2]);t=Za(c+1824|0,G[a+4>>2]);Za(3705216,G[a+8>>2]);if(G[926301]>0){Wc(3705196);L[c+1280>>3]=G[926299]-G[926300]|0;gb(78117,c+1280|0);$a(n)}Lf(t,1,0);a=Va(3705216);o:{if(a>>>0<6){break o}a=a+3705211|0;if(fb(a,5646,5)){break o}E[a|0]=0}a=Va(3705216);p:{if(a>>>0<6){break p}a=a+3705211|0;if(fb(a,33598,5)){break p}E[a|0]=0}a=Va(3705216);q:{if(a>>>0<5){break q}a=a+3705212|0;if(fb(a,5001,4)){break q}E[a|0]=0}a=Va(3705216);r:{if(a>>>0<5){break r}a=a+3705212|0;if(fb(a,33380,4)){break r}E[a|0]=0}Za(3705472,3705216);a=Va(3705216);b=a+3705220|0;d=H[5650]|H[5651]<<8;E[b|0]=d;E[b+1|0]=d>>>8;a=a+3705216|0;b=H[5646]|H[5647]<<8|(H[5648]<<16|H[5649]<<24);E[a|0]=b;E[a+1|0]=b>>>8;E[a+2|0]=b>>>16;E[a+3|0]=b>>>24;d=Va(3705472);a=d+3705479|0;b=H[5648]|H[5649]<<8|(H[5650]<<16|H[5651]<<24);E[a|0]=b;E[a+1|0]=b>>>8;E[a+2|0]=b>>>16;E[a+3|0]=b>>>24;b=H[5645]|H[5646]<<8|(H[5647]<<16|H[5648]<<24);a=d+3705472|0;d=H[5641]|H[5642]<<8|(H[5643]<<16|H[5644]<<24);E[a|0]=d;E[a+1|0]=d>>>8;E[a+2|0]=d>>>16;E[a+3|0]=d>>>24;E[a+4|0]=b;E[a+5|0]=b>>>8;E[a+6|0]=b>>>16;E[a+7|0]=b>>>24;if(G[926301]>0){G[c+1264>>2]=g;kb(76753,c+1264|0);G[c+1248>>2]=3705216;kb(76728,c+1248|0);G[c+1232>>2]=3705472;kb(76298,c+1232|0);G[c+1216>>2]=t;kb(76496,c+1216|0);$a(n)}f=ac(t,13287);if(f){E[c+2384|0]=0;s:while(1){if(!vc(c+82384|0,256,f)){break g}a=(Va(c+82384|0)+c|0)+82383|0;if(H[a|0]==10){E[a|0]=0}a=(Va(c+82384|0)+c|0)+82383|0;if(H[a|0]==13){E[a|0]=0}if(G[926301]>=3){G[c+1200>>2]=c+82384;kb(76800,c+1200|0);$a(n)}a=Va(c+82384|0);if((a|0)<=79){cb(a+(c+82384|0)|0,32,80-a|0)}E[c+82464|0]=0;b=Va(c+2384|0);a=Va(c+82384|0);t:{if((a|0)>0){bb(b+(c+2384|0)|0,c+82384|0,a);if(a>>>0>79){break t}}cb(c+2384+(a+b)|0,32,80-a|0)}E[(b+c|0)+2464|0]=0;b=c+82384|0;i=a+b|0;while(1){d=b;a=H[d|0];if((a|0)==32){b=d+1|0;if(d>>>0>>0){continue}}break}B=d;while(1){b=a&255;if(!(!((b|0)==61|(b|0)==32)&i>>>0>B>>>0)){b=B;while(1){a=(a&255)-32|0;if(!(a>>>0>29|!(1<>>0>=i>>>0)){a=H[b+1|0];b=b+1|0;continue}break}E[B|0]=0;a=(H[b|0]==39)+b|0;while(1){u:{v:{switch(H[a|0]-32|0){case 0:case 7:break u;default:break v}}if(a>>>0>=i>>>0){break u}a=a+1|0;continue}break}E[a|0]=0;if(G[926301]>=2){G[c+1188>>2]=b;G[c+1184>>2]=d;kb(76184,c+1184|0);$a(n)}if(!Xa(d,41295)){Za(3705728,b)}if(!Xa(d,41261)){fa=3705988,ga=_b(b),G[fa>>2]=ga;fa=3706060,ga=_b(b),G[fa>>2]=ga}if(!Xa(d,40853)){fa=3705992,ga=_b(b),G[fa>>2]=ga;fa=3706064,ga=_b(b),G[fa>>2]=ga}if(!Xa(d,41201)){fa=3706e3,ha=sb(b),L[fa>>3]=ha;fa=3706072,ha=sb(b),L[fa>>3]=ha}if(!Xa(d,40799)){fa=3706008,ha=sb(b),L[fa>>3]=ha;fa=3706080,ha=sb(b),L[fa>>3]=ha}if(!Xa(d,41279)){fa=3706016,ha=sb(b),L[fa>>3]=ha;fa=3706088,ha=sb(b),L[fa>>3]=ha}if(!Xa(d,40866)){fa=3706024,ha=sb(b),L[fa>>3]=ha;fa=3706096,ha=sb(b),L[fa>>3]=ha}o=o+1|0;if((o|0)!=1e3){continue s}break g}a=H[B+1|0];B=B+1|0;continue}}}G[c+32>>2]=44379;_a(G[321435],80471,c+32|0);break f}G[c+16>>2]=G[b>>2];kb(79810,c+16|0);break a}G[c>>2]=G[b>>2];kb(79810,c);break a}Hb(f);a=rd(c+2384|0);G[926528]=a;w:{x:{y:{z:{A:{B:{C:{D:{E:{F:{G:{H:{I:{if(a){ca=Xa(Va(3705728)+3705725|0,34150);if((Rh(g)|0)<=0){break I}P=Pb(10369);K=Pb(21447);Q=Pb(41041);T=Pb(40643);U=Pb(41002);q=Pb(40604);D=Pb(41034);r=Pb(40636);A=Pb(40995);N=Pb(40585);y=Pb(41022);b=Pb(40624);a=Va(c+1568|0);d=G[(G[925773]+M(K,4108)|0)+4104>>2];if((K|0)<0){K=Pb(22604)}if((y|0)<0){y=Pb(6868)}if((b|0)<0){b=Pb(16725)}if((P|K|(U|q))<0){break H}if((A|N|(y|b))<0){break H}if((D|r|(Q|T))<0){break H}x=(a+d|0)+16|0;a=0;p=G[47592];d=p<<2;_=ab(d);F=ab(d);B=ab(d);o=ab(d);f=ab(d);i=p<<3;l=ab(i);k=ab(i);g=ab(i);j=ab(i);s=ab(i);m=ab(i);Z=ab(d);X=ab(d);if((p|0)>0){while(1){d=a<<2;fa=d+F|0,ga=ab(x),G[fa>>2]=ga;fa=d+B|0,ga=ab(x),G[fa>>2]=ga;fa=d+o|0,ga=ab(32),G[fa>>2]=ga;fa=d+f|0,ga=ab(32),G[fa>>2]=ga;a=a+1|0;if((p|0)!=(a|0)){continue}break}}i=0;if(G[926301]>0){Wc(3705196);L[c+1168>>3]=G[926299]-G[926300]|0;gb(77881,c+1168|0);$a(n)}a=nf();G[926297]=a;if((a|0)>=0){da=c+2379|0;v=1;a=0;while(1){i=a<<2;fa=i+_|0,ga=_b((P|0)>2]:0),G[fa>>2]=ga;d=a<<3;$=d+l|0;fa=$,ha=sb((U|0)>2]:0),L[fa>>3]=ha;fa=d+k|0,ha=sb((q|0)>2]:0),L[fa>>3]=ha;fa=d+g|0,ha=sb((D|0)>2]:0),L[fa>>3]=ha;fa=d+j|0,ha=sb((r|0)>2]:0),L[fa>>3]=ha;p=d+s|0;fa=p,ha=sb((A|0)>2]:0),L[fa>>3]=ha;d=d+m|0;fa=d,ha=sb((N|0)>2]:0),L[fa>>3]=ha;aa=i+Z|0;fa=aa,ga=_b(G[925783]>(y|0)?G[(G[925773]+M(y,4108)|0)+4096>>2]:0),G[fa>>2]=ga;ba=i+X|0;fa=ba,ga=_b(G[925783]>(b|0)?G[(G[925773]+M(b,4108)|0)+4096>>2]:0),G[fa>>2]=ga;Za(G[i+o>>2],(Q|0)>2]:0);Za(G[f+i>>2],(T|0)>2]:0);J:{if(ca){break J}u=L[p>>3];z=L[463250];w=O(u-z);V=+G[926497];K:{if(!(w>V)){h=u;break K}ea=360/O(L[$>>3]);while(1){h=u-ea;if(O(h-z)>w){w=O(u-z);h=u;break K}L[p>>3]=h;u=h;z=L[463250];w=O(h-z);if(VV)){break J}u=360/O(L[$>>3]);while(1){h=h+u;if(O(h-z)>w){break J}L[p>>3]=h;z=L[463250];w=O(h-z);if(V>3];L:{if(v){I=L[d>>3];J=I-+G[ba>>2]+1;R=h-+G[aa>>2]+1;C=h;break L}u=h-+G[aa>>2]+1;R=uC?h:C;h=L[d>>3];I=h>I?h:I;h=h-+G[ba>>2]+1;if(!(h(K|0)?G[(G[925773]+M(K,4108)|0)+4096>>2]:0;if(H[d|0]!=47){v=c+1568|0;if(Va(d)>>>0>=2){d=(!fb(d,42201,2)<<1)+d|0}Za(3703136,v);v=Va(3703136);if(!((v|0)<=0|H[v+3703135|0]==47)){v=Va(3703136)+3703136|0;E[v|0]=47;E[v+1|0]=0}Gb(3703136,d);d=3703136}p=Za(p,d);M:{if(!G[926296]){break M}d=Va(p);if(d>>>0<6){break M}if(fb(d+da|0,5646,5)){break M}E[(d+p|0)-5|0]=0}d=i+F|0;Za(G[d>>2],p);if(G[926296]){d=G[d>>2];d=Va(d)+d|0;v=H[5646]|H[5647]<<8|(H[5648]<<16|H[5649]<<24);E[d|0]=v;E[d+1|0]=v>>>8;E[d+2|0]=v>>>16;E[d+3|0]=v>>>24;v=H[5650]|H[5651]<<8;E[d+4|0]=v;E[d+5|0]=v>>>8;d=i+B|0;Za(G[d>>2],p);d=G[d>>2];d=Va(d)+d|0;i=H[5645]|H[5646]<<8|(H[5647]<<16|H[5648]<<24);p=H[5641]|H[5642]<<8|(H[5643]<<16|H[5644]<<24);E[d|0]=p;E[d+1|0]=p>>>8;E[d+2|0]=p>>>16;E[d+3|0]=p>>>24;E[d+4|0]=i;E[d+5|0]=i>>>8;E[d+6|0]=i>>>16;E[d+7|0]=i>>>24;i=H[5648]|H[5649]<<8|(H[5650]<<16|H[5651]<<24);E[d+7|0]=i;E[d+8|0]=i>>>8;E[d+9|0]=i>>>16;E[d+10|0]=i>>>24}N:{i=a+1|0;if((i|0)!=G[47592]){break N}p=a+51|0;G[47592]=p;a=p<<2;_=ub(_,a);F=ub(F,a);B=ub(B,a);o=ub(o,a);f=ub(f,a);d=p<<3;g=ub(g,d);j=ub(j,d);s=ub(s,d);m=ub(m,d);Z=ub(Z,a);X=ub(X,a);l=ub(l,d);k=ub(k,d);a=i;while(1){O:{d=a<<2;fa=d+F|0,ga=ab(x),G[fa>>2]=ga;v=ab(x);G[d+B>>2]=v;fa=d+o|0,ga=ab(32),G[fa>>2]=ga;fa=d+f|0,ga=ab(32),G[fa>>2]=ga;if(!v){break O}a=a+1|0;if((p|0)!=(a|0)){continue}break N}break}G[c+1152>>2]=62744;_a(G[321435],83707,c+1152|0);break e}v=0;d=nf();G[926297]=d;a=i;if((d|0)>=0){continue}break}}Qh();d=0;a=G[926301];if((a|0)>=3){G[c+1136>>2]=i;kb(90312,c+1136|0);if(i){while(1){b=d<<2;a=G[b+F>>2];P:{if(G[926296]){G[c+1124>>2]=G[b+B>>2];G[c+1120>>2]=a;kb(76122,c+1120|0);break P}G[c+1104>>2]=a;kb(77142,c+1104|0)}d=d+1|0;if((i|0)!=(d|0)){continue}break}}id();$a(n);a=G[926301]}if((a|0)>0){Wc(3705196);L[c+1088>>3]=G[926299]-G[926300]|0;gb(78164,c+1088|0);$a(n)}Q:{if(!Sb(G[o>>2],34149)){break Q}b=0;G[926298]=1;if(!i){break Q}while(1){a=b<<3;d=a+g|0;h=(L[463252]-L[d>>3])/L[a+l>>3];if(O(S(h+.5)-h)>.1){break G}f=a+s|0;L[f>>3]=h+L[f>>3];f=a+j|0;h=(L[463253]-L[f>>3])/L[a+k>>3];if(O(S(h+.5)-h)>.1){break F}a=a+m|0;L[a>>3]=h+L[a>>3];L[d>>3]=L[463252];L[f>>3]=L[463253];b=b+1|0;if((i|0)!=(b|0)){continue}break}}a=M(G[47592],20);b=ab(a);G[926508]=b;if(!b){break E}if(G[926296]){a=ab(a);G[926509]=a;if(!a){break D}}if(G[926301]>0){Wc(3705196);L[c+1008>>3]=G[926299]-G[926300]|0;gb(77772,c+1008|0);$a(n)}R:{if(!e){break R}h=C-R+1;if(h<+G[926497]){L[463250]=C;if(O(h)<2147483648){a=~~h}else{a=-2147483648}G[926497]=a}h=I-J+1;if(!(h<+G[926498])){break R}L[463251]=I;if(O(h)<2147483648){a=~~h}else{a=-2147483648}G[926498]=a}e=G[926301];if((e|0)>0){G[c+992>>2]=G[926497];kb(73395,c+992|0);G[c+976>>2]=G[926498];kb(73355,c+976|0);L[c+960>>3]=L[463250];gb(71170,c+960|0);L[c+944>>3]=L[463251];gb(71147,c+944|0);$a(n);e=G[926301]}b=G[926497];h=O(C-R);S:{if(O(h)<2147483648){a=~~h;break S}a=-2147483648}a=(a|0)<(b|0)?b:a;if((e|0)>0){G[c+928>>2]=a;kb(75346,c+928|0);$a(n)}a=a<<3;P=ab(a);x=ab(a);if(!P){break C}if(!x){break B}T:{if(G[926301]<=0){break T}Wc(3705196);L[c+912>>3]=G[926299]-G[926300]|0;gb(77668,c+912|0);$a(n);if(G[926301]<2){break T}yb(33824);yb(5006);yb(48714);$a(n)}w=0;U:{if(!i){break U}z=L[g>>3];if(z!=z){break A}h=L[j>>3];if(h!=h){break A}C=L[l>>3];if(C!=C){break A}J=L[k>>3];if(J!=J){break A}b=G[926508];u=L[463251]-L[m>>3]+1;V:{if(O(u)<2147483648){a=~~u;break V}a=-2147483648}G[b+8>>2]=a;d=(a+G[X>>2]|0)-1|0;e=G[926498];e=(d|0)<(e|0)?d:e;G[b+16>>2]=e;u=L[463250];w=L[s>>3];W:{if(!(u>w)){u=-S(w-u+.5);break W}u=S(u-w+.5)}X:{if(O(u)<2147483648){d=~~u;break X}d=-2147483648}G[b+12>>2]=d;if(G[926301]>=2){G[c+908>>2]=d;G[c+904>>2]=e;G[c+900>>2]=a;G[c+896>>2]=0;kb(73825,c+896|0);$a(n);b=G[926508]}G[b>>2]=0;if(G[926296]){G[G[926509]>>2]=0}w=C*J+0;e=1;if((i|0)==1){break U}u=h;while(1){f=e<<3;if(z!=L[f+g>>3]|u!=L[f+j>>3]){break A}R=L[f+l>>3];if(R!=C){break A}V=L[f+k>>3];if(V!=J){break A}o=M(e,20);a=o+b|0;h=L[463251]-L[f+m>>3]+1;Y:{if(O(h)<2147483648){b=~~h;break Y}b=-2147483648}G[a+8>>2]=b;d=(b+G[(e<<2)+X>>2]|0)-1|0;y=G[926498];y=(d|0)<(y|0)?d:y;G[a+16>>2]=y;d=a;h=L[463250];I=L[f+s>>3];Z:{if(h>I){h=S(h-I+.5);break Z}h=-S(I-h+.5)}_:{if(O(h)<2147483648){a=~~h;break _}a=-2147483648}G[d+12>>2]=a;if(G[926301]>=2){G[c+892>>2]=a;G[c+888>>2]=y;G[c+884>>2]=b;G[c+880>>2]=e;kb(73825,c+880|0);$a(n)}b=G[926508];G[o+b>>2]=0;if(G[926296]){G[o+G[926509]>>2]=0}w=R*V+w;e=e+1|0;if((i|0)!=(e|0)){continue}break}}b=G[47592]<<2;a=ab(b);G[926510]=a;e=ab(b);G[926511]=e;f=ab(b);G[926512]=f;b=ab(b);G[926513]=b;if(!b){break z}$:{if(!i){break $}d=0;j=G[926508];if((i|0)!=1){k=i&-2;g=0;while(1){o=d<<2;s=j+M(d,20)|0;G[o+a>>2]=G[s+8>>2];G[e+o>>2]=d;G[f+o>>2]=G[s+16>>2];G[b+o>>2]=d;o=d|1;s=o<<2;l=j+M(o,20)|0;G[s+a>>2]=G[l+8>>2];G[e+s>>2]=o;G[f+s>>2]=G[l+16>>2];G[b+s>>2]=o;d=d+2|0;g=g+2|0;if((k|0)!=(g|0)){continue}break}}if(i&1){g=d<<2;j=j+M(d,20)|0;G[g+a>>2]=G[j+8>>2];G[e+g>>2]=d;G[f+g>>2]=G[j+16>>2];G[b+g>>2]=d}if((i|0)<2){break $}g=i;k=g-2|0;j=k;while(1){g=g-1|0;b=G[926511];d=0;while(1){e=d<<2;f=e+a|0;o=G[f>>2];d=d+1|0;s=d<<2;l=s+a|0;m=G[l>>2];if((o|0)>(m|0)){G[f>>2]=m;G[l>>2]=o;e=b+e|0;f=G[e>>2];q=e;e=b+s|0;G[q>>2]=G[e>>2];G[e>>2]=f}if((d|0)!=(g|0)){continue}break}b=(j|0)>0;j=j-1|0;if(b){continue}break}if((i|0)<2){break $}a=G[926512];g=i;while(1){g=g-1|0;b=G[926513];d=0;while(1){e=d<<2;f=e+a|0;j=G[f>>2];d=d+1|0;o=d<<2;s=o+a|0;l=G[s>>2];if((j|0)>(l|0)){G[f>>2]=l;G[s>>2]=j;e=b+e|0;f=G[e>>2];j=e;e=b+o|0;G[j>>2]=G[e>>2];G[e>>2]=f}if((d|0)!=(g|0)){continue}break}b=(k|0)>0;k=k-1|0;if(b){continue}break}}d=0;a=G[926301];if((a|0)>=2){yb(38904);yb(66443);yb(48721);aa:{if(i){while(1){a=d<<2;b=G[a+G[926511]>>2];a=G[a+G[926510]>>2];G[c+848>>2]=d;G[c+852>>2]=a;G[c+856>>2]=b;kb(73842,c+848|0);d=d+1|0;if((i|0)!=(d|0)){continue}break}$a(n);yb(38918);yb(66462);yb(48721);if(!i){break aa}d=0;while(1){a=d<<2;b=G[a+G[926513]>>2];a=G[a+G[926512]>>2];G[c+832>>2]=d;G[c+836>>2]=a;G[c+840>>2]=b;kb(73842,c+832|0);d=d+1|0;if((i|0)!=(d|0)){continue}break}break aa}$a(n);yb(38918);yb(66462);yb(48721)}$a(n);a=G[926301]}if((a|0)>0){Wc(3705196);L[c+816>>3]=G[926299]-G[926300]|0;gb(77941,c+816|0);$a(n)}d=0;ba:{ca:{a=G[926497];b=a<<2;p=ab(b);if(p){if((a|0)<=0){break ba}break ca}Ae(6001);W()}da:{while(1){ea:{e=ab(400);G[p+(d<<2)>>2]=e;if(!e){break ea}d=d+1|0;if((a|0)!=(d|0)){continue}break da}break}G[c+64>>2]=21285;_a(G[321435],83707,c- -64|0);break e}o=ab(b);if(o){break x}break y}o=ab(b);if(!o){break y}break w}hb(83821,57,1,G[321435]);break a}G[c+48>>2]=g;_a(G[321435],81102,c+48|0);break a}hb(79662,147,1,G[321435]);break a}G[c+1048>>2]=G[(b<<2)+F>>2];L[c+1040>>3]=h;a=c+82384|0;Eb(a,9179,c+1040|0);G[c+1024>>2]=a;_a(G[321435],80471,c+1024|0);break f}G[c+1080>>2]=G[(b<<2)+F>>2];L[c+1072>>3]=h;a=c+82384|0;Eb(a,9234,c+1072|0);G[c+1056>>2]=a;_a(G[321435],80471,c+1056|0);break f}Ae(5719);W()}Ae(5714);W()}Ae(11466);W()}Ae(11618);W()}G[c+864>>2]=25461;_a(G[321435],80471,c+864|0);break f}Ae(13558);W()}Ae(6020);W()}d=0;if((a|0)<=0){break w}while(1){fa:{e=ab(400);G[(d<<2)+o>>2]=e;if(!e){break fa}d=d+1|0;if((a|0)!=(d|0)){continue}break w}break}G[c+80>>2]=21302;_a(G[321435],83707,c+80|0);break e}ga:{Q=ab(b);if(Q){if(G[926301]>0){Wc(3705196);L[c+800>>3]=G[926299]-G[926300]|0;gb(77828,c+800|0);$a(n);a=G[926497]}a=a<<3;T=ab(a);U=ab(a);if(T){if(U){if(G[926301]>0){Wc(3705196);L[c+784>>3]=G[926299]-G[926300]|0;gb(77717,c+784|0);$a(n)}Ed(3705216);Ed(3705472);if(!sd(3705984,3705216,3705188)){if(!sd(3706056,3705472,3705188)){G[926526]=2;a=G[926498];G[926498]=1;if(!pd(G[926496],-64,2,3705988,3705188)){if(G[926301]>0){yb(62208);$a(n)}if(!pd(G[926514],-64,2,3706060,3705188)){ha:{if(G[926301]<=0){G[926498]=a;break ha}yb(62252);$a(n);G[926498]=a;if(G[926301]<=0){break ha}Wc(3705196);L[c+768>>3]=G[926299]-G[926300]|0;gb(78035,c+768|0);$a(n)}if(!Xi(G[926496],t,3705188)){if(G[926301]>0){yb(24964);$a(n)}if(!Xi(G[926514],t,3705188)){if(G[926301]>0){yb(25041);$a(n)}if(!Gc(G[926496],32941,-64,-1,0,3705188)){if(!Gc(G[926514],32941,-64,-1,0,3705188)){if(!Gc(G[926496],33788,2,0,0,3705188)){a=G[926497];if(!Gc(G[926496],41261,a,a>>31,0,3705188)){a=G[926498];if(!Gc(G[926496],40853,a,a>>31,0,3705188)){if(!Gc(G[926514],33788,2,0,0,3705188)){a=G[926497];if(!Gc(G[926514],41261,a,a>>31,0,3705188)){a=G[926498];if(!Gc(G[926514],40853,a,a>>31,0,3705188)){if(!Kd(G[926496],41201,L[463250],-14,0,3705188)){if(!Kd(G[926496],40799,L[463251],-14,0,3705188)){if(!Kd(G[926514],41201,L[463250],-14,0,3705188)){if(!Kd(G[926514],40799,L[463251],-14,0,3705188)){if(G[926301]>0){Wc(3705196);L[c+752>>3]=G[926299]-G[926300]|0;gb(78075,c+752|0);$a(n)}a=0;d=Fa-16|0;Fa=d;G[926532]=500;e=ab(2e3);G[926533]=e;ia:{ja:{while(1){b=ab(16);G[e+(a<<2)>>2]=b;if(!b){break ja}G[b+8>>2]=-1;G[b+12>>2]=-1;G[b>>2]=-1;G[b+4>>2]=0;a=a+1|0;if((a|0)!=500){continue}break}G[926535]=0;G[926534]=0;Fa=d+16|0;break ia}G[d>>2]=5694;_a(G[321435],83707,d);break b}ka:{la:{ma:{na:{oa:{pa:{qa:{ra:{if(G[926498]<=0){break ra}u=O(w)*.017453292519943295*.017453292519943295/+(i|0);s=1;y=50;b=0;d=0;K=0;while(1){a=G[926301];if((a|0)>=2){G[c+736>>2]=s;kb(75146,c+736|0);$a(n);a=G[926301]}if((a|0)==1){G[c+720>>2]=s;kb(30435,c+720|0);$a(n)}a=G[926497];if((a|0)>0){cb(Q,0,a<<2)}sa:{if((b|0)>=(i|0)){break sa}while(1){a=b<<2;if(G[a+G[926510]>>2]>(s|0)){break sa}m=G[a+G[926511]>>2];e=0;a=0;l=Fa-16|0;Fa=l;ta:{ua:{va:{wa:{xa:{ya:{k=G[926535];if(k){j=G[926533];g=G[926534];if((k|0)<=0){break wa}f=k&3;if(k-1>>>0>=3){break ya}break xa}a=1;f=G[G[926533]>>2];G[f+4>>2]=1;G[f>>2]=m;break va}t=k&-4;while(1){a=G[G[j+(G[G[j+(G[G[j+(g<<2)>>2]+8>>2]<<2)>>2]+8>>2]<<2)>>2]+8>>2];g=G[G[j+(a<<2)>>2]+8>>2];e=e+4|0;if((t|0)!=(e|0)){continue}break}}if(!f){break wa}e=0;while(1){a=g;g=G[G[j+(a<<2)>>2]+8>>2];e=e+1|0;if((f|0)!=(e|0)){continue}break}}f=G[j+(g<<2)>>2];G[f+12>>2]=a;G[f+4>>2]=1;G[f>>2]=m;a=0;za:{Aa:{e=G[926532];if((e|0)<=0){break Aa}while(1){if(!G[G[j+(a<<2)>>2]+4>>2]){break Aa}a=a+1|0;if((e|0)!=(a|0)){continue}break}a=e;break za}if((a|0)!=(e|0)){break va}}j=ub(j,(e<<2)+2e3|0);G[926533]=j;m=e+500|0;while(1){f=ab(16);G[j+(e<<2)>>2]=f;if(!f){break ua}G[f+8>>2]=-1;G[f+12>>2]=-1;G[f>>2]=-1;G[f+4>>2]=0;e=e+1|0;if((m|0)>(e|0)){continue}break}G[926532]=m;f=G[j+(g<<2)>>2]}G[f+8>>2]=a;G[926535]=k+1;Fa=l+16|0;break ta}G[l>>2]=50554;_a(G[321435],83707,l);break b}b=b+1|0;if((i|0)!=(b|0)){continue}break}b=i}Ba:{if((d|0)>=(i|0)){break Ba}while(1){a=d<<2;if(G[a+G[926512]>>2]>=(s|0)){break Ba}m=G[a+G[926513]>>2];a=G[926533];k=G[926534];e=k;while(1){Ca:{g=G[a+(e<<2)>>2];if(!G[g+4>>2]){break Ca}if((m|0)==G[g>>2]){G[926535]=G[926535]-1;j=G[g+12>>2];f=G[g+8>>2];Da:{if((e|0)!=(k|0)){break Da}G[926534]=f;if(G[G[a+(f<<2)>>2]+4>>2]){break Da}e=G[926532];Ea:{if((e|0)<=0){break Ea}l=0;f=0;if(e-1>>>0>=3){t=e&-4;j=0;while(1){g=f<<2;k=G[g+a>>2];G[k+8>>2]=-1;G[k+12>>2]=-1;G[k>>2]=-1;G[k+4>>2]=0;k=G[a+(g|4)>>2];G[k+8>>2]=-1;G[k+12>>2]=-1;G[k>>2]=-1;G[k+4>>2]=0;k=G[a+(g|8)>>2];G[k+8>>2]=-1;G[k+12>>2]=-1;G[k>>2]=-1;G[k+4>>2]=0;g=G[a+(g|12)>>2];G[g+8>>2]=-1;G[g+12>>2]=-1;G[g>>2]=-1;G[g+4>>2]=0;f=f+4|0;j=j+4|0;if((t|0)!=(j|0)){continue}break}}g=e&3;if(!g){break Ea}while(1){e=G[a+(f<<2)>>2];G[e+8>>2]=-1;G[e+12>>2]=-1;G[e>>2]=-1;G[e+4>>2]=0;f=f+1|0;l=l+1|0;if((g|0)!=(l|0)){continue}break}}G[926535]=0;G[926534]=0;break Ca}G[g+8>>2]=-1;G[g+12>>2]=-1;G[g>>2]=-1;G[g+4>>2]=0;if((j|0)==-1){G[G[a+(f<<2)>>2]+12>>2]=-1;break Ca}if((f|0)==-1){G[G[a+(j<<2)>>2]+8>>2]=-1;break Ca}G[G[a+(f<<2)>>2]+12>>2]=j;G[G[a+(j<<2)>>2]+8>>2]=f;break Ca}e=G[g+8>>2];if((e|0)!=-1){continue}}break}a=M(m,20);e=a+G[926508]|0;if(G[e>>2]){if(Qb(G[e+4>>2],3705188)){break ka}G[a+G[926508]>>2]=0;G[926526]=G[926526]-1}Fa:{if(!G[926296]){break Fa}e=a+G[926509]|0;if(!G[e>>2]){break Fa}if(Qb(G[e+4>>2],3705188)){break la}G[a+G[926509]>>2]=0;G[926526]=G[926526]-1}d=d+1|0;if((i|0)!=(d|0)){continue}break}d=i}t=G[926535];if(G[926301]>=2){G[c+672>>2]=t;kb(90331,c+672|0);yb(68050);yb(48669);$a(n)}if((t|0)>0){D=s+1|0;k=0;while(1){g=G[926533];e=G[926534];f=0;while(1){Ga:{e=G[g+(e<<2)>>2];if(!G[e+4>>2]){a=-1;break Ga}if((f|0)==(k|0)){a=G[e>>2];break Ga}f=f+1|0;a=-1;e=G[e+8>>2];if((e|0)!=-1){continue}}break}if(G[926301]>=2){e=G[G[926508]+M(a,20)>>2];G[c+656>>2]=G[(a<<2)+F>>2];G[c+640>>2]=a;G[c+644>>2]=e;G[c+648>>2]=G[926526];G[c+652>>2]=200;kb(69231,c+640|0);$a(n)}Ha:{Ia:{Ja:{Ka:{La:{Ma:{Na:{Oa:{Pa:{Qa:{Ra:{Sa:{Ta:{f=G[926508];m=M(a,20);e=f+m|0;if(!G[e>>2]){g=G[926526];G[926526]=g+1;if((g|0)>=200){break ga}g=a<<2;f=g+F|0;if(Rc(e+4|0,G[f>>2],0,3705188)){break Ta}if(G[926301]>=2){G[c+592>>2]=a;kb(73953,c+592|0);$a(n)}e=G[926508];G[e+m>>2]=1;if(G[926296]){e=G[926526];G[926526]=e+1;if((e|0)>=200){break ga}e=g+B|0;if(Rc((m+G[926509]|0)+4|0,G[e>>2],0,3705188)){break Sa}G[m+G[926509]>>2]=1;e=G[926508]}if(Yj(G[(e+m|0)+4>>2],c+2380|0,3705188)){break Ra}if(G[926301]>=3){G[c+528>>2]=G[c+2380>>2];kb(69940,c+528|0);$a(n)}e=rd(G[c+2380>>2]);G[926527]=e;if(!e){break Qa}g=G[926528];if(Xa(e+3512|0,g+3512|0)){break Pa}if(Xa(e+3528|0,g+3528|0)){break Oa}if(!G[926298]){if(O(L[e>>3]-L[g>>3])>1e-8){break Na}if(O(L[e+8>>3]-L[g+8>>3])>1e-8){break Ma}}if(O(L[e+56>>3]-L[g+56>>3])>1e-8|O(L[e- -64>>3]-L[g- -64>>3])>1e-8|(O(L[e+72>>3]-L[g+72>>3])>1e-8|O(L[e+80>>3]-L[g+80>>3])>1e-8)){break La}if(L[e+120>>3]!=L[g+120>>3]){break Ka}f=G[926508]}G[c+2352>>2]=1;e=G[(f+m|0)+8>>2];G[c+2360>>2]=1;G[c+2364>>2]=1;f=D-e|0;G[c+2356>>2]=f;e=a<<2;j=G[e+Z>>2];if(G[926301]>=3){G[c+448>>2]=a;kb(86350,c+448|0);G[c+432>>2]=G[c+2356>>2];kb(73378,c+432|0);G[c+416>>2]=j;kb(73338,c+416|0);$a(n);f=G[c+2356>>2]}if(!(G[e+X>>2]<(f|0)|(f|0)<=0)){G[926297]=0;e=j>>31;if(cg(G[(m+G[926508]|0)+4>>2],82,c+2352|0,j,e,c+1304|0,P,c+2348|0,3705188)){break Ja}if(!G[926296]){if((j|0)<=0){break Ha}g=0;e=0;if(j-1>>>0>=7){q=j&-8;l=0;while(1){f=e<<3;r=f+x|0;G[r>>2]=0;G[r+4>>2]=1072693248;r=x+(f|8)|0;G[r>>2]=0;G[r+4>>2]=1072693248;r=x+(f|16)|0;G[r>>2]=0;G[r+4>>2]=1072693248;r=x+(f|24)|0;G[r>>2]=0;G[r+4>>2]=1072693248;r=x+(f|32)|0;G[r>>2]=0;G[r+4>>2]=1072693248;r=x+(f|40)|0;G[r>>2]=0;G[r+4>>2]=1072693248;r=x+(f|48)|0;G[r>>2]=0;G[r+4>>2]=1072693248;f=x+(f|56)|0;G[f>>2]=0;G[f+4>>2]=1072693248;e=e+8|0;l=l+8|0;if((q|0)!=(l|0)){continue}break}}f=j&7;if(!f){break Ia}while(1){l=x+(e<<3)|0;G[l>>2]=0;G[l+4>>2]=1072693248;e=e+1|0;g=g+1|0;if((f|0)!=(g|0)){continue}break}break Ia}if(!cg(G[(m+G[926509]|0)+4>>2],82,c+2352|0,j,e,c+1304|0,x,c+2348|0,3705188)){break Ia}a=G[926297];b=c+82384|0;uc(a,b);G[c+384>>2]=a;G[c+388>>2]=b;kb(80427,c+384|0);break d}if(G[926301]<3){break Ha}yb(8367);$a(n);break Ha}G[c+624>>2]=G[f>>2];a=c+82384|0;db(a,33643,c+624|0);G[c+608>>2]=a;_a(G[321435],80471,c+608|0);break f}G[c+576>>2]=G[e>>2];a=c+82384|0;db(a,33681,c+576|0);G[c+560>>2]=a;_a(G[321435],80471,c+560|0);break f}a=G[926297];b=c+82384|0;uc(a,b);G[c+544>>2]=a;G[c+548>>2]=b;kb(80427,c+544|0);break d}hb(84433,53,1,G[321435]);break a}G[c+512>>2]=G[f>>2];a=c+82384|0;db(a,20661,c+512|0);G[c+496>>2]=a;_a(G[321435],80471,c+496|0);break f}G[c+480>>2]=G[f>>2];a=c+82384|0;db(a,20567,c+480|0);G[c+464>>2]=a;_a(G[321435],80471,c+464|0);break f}G[c+144>>2]=G[f>>2];a=c+82384|0;db(a,20614,c+144|0);G[c+128>>2]=a;_a(G[321435],80471,c+128|0);break f}G[c+176>>2]=G[f>>2];a=c+82384|0;db(a,20520,c+176|0);G[c+160>>2]=a;_a(G[321435],80471,c+160|0);break f}G[c+208>>2]=G[f>>2];a=c+82384|0;db(a,20471,c+208|0);G[c+192>>2]=a;_a(G[321435],80471,c+192|0);break f}G[c+240>>2]=G[f>>2];a=c+82384|0;db(a,20423,c+240|0);G[c+224>>2]=a;_a(G[321435],80471,c+224|0);break f}a=G[926297];b=c+82384|0;uc(a,b);G[c+400>>2]=a;G[c+404>>2]=b;kb(80427,c+400|0);break d}f=0;if((j|0)<=0){break Ha}while(1){g=f<<3;l=g+P|0;e=G[l+4>>2];l=G[l>>2];q=e&2147483647;Ua:{if((q|0)==2146435072&(l|0)!=0|q>>>0>2146435072|(e&2146435072)==2146435072|L[g+x>>3]<=0){break Ua}g=G[(m+G[926508]|0)+12>>2]+f|0;if((g|0)<0){break Ua}e=G[926497];if((e|0)<=(g|0)){break Ua}g=g<<2;r=g+Q|0;l=G[r>>2];Va:{if((l|0)<(y|0)){break Va}y=y+50|0;if(G[926301]>0){G[c+368>>2]=y;kb(75296,c+368|0);$a(n);e=G[926497]}Wa:{if((e|0)<=0){f=0;break Wa}e=y<<3;f=0;while(1){A=f<<2;N=A+p|0;q=ub(G[N>>2],e);G[N>>2]=q;if(!q){break ma}A=o+A|0;q=ub(G[A>>2],e);G[A>>2]=q;if(!q){break na}f=f+1|0;if((f|0)>2]>>3]=L[q+P>>3];L[e+G[g+o>>2]>>3]=L[q+x>>3];G[r>>2]=l+1}f=f+1|0;if((j|0)>(f|0)){continue}break}}f=G[926526];Xa:{Ya:{if(!((f|0)<200|K)){K=1;if(G[926301]<=0){break Ya}yb(85320);$a(n);f=G[926526]}if((f|0)<200){break Xa}}if(Qb(G[(m+G[926508]|0)+4>>2],3705188)){break oa}if(G[926301]>=2){G[c+304>>2]=a;kb(73941,c+304|0);$a(n)}G[m+G[926508]>>2]=0;G[926526]=G[926526]-1;if(!G[926296]){break Xa}if(Qb(G[(m+G[926509]|0)+4>>2],3705188)){break pa}G[m+G[926509]>>2]=0;G[926526]=G[926526]-1}k=k+1|0;if((t|0)!=(k|0)){continue}break}}j=0;f=G[926497];if((f|0)>0){while(1){a=j<<3;g=a+T|0;G[g>>2]=0;G[g+4>>2]=0;k=a+U|0;a=k;G[a>>2]=0;G[a+4>>2]=0;Za:{_a:{$a:{ab:{bb:{e=j<<2;a=G[e+Q>>2];if((a|0)>0){cb:{switch(Y-1|0){case 3:break $a;case 1:break bb;case 0:break cb;default:break Za}}l=G[e+o>>2];e=G[e+p>>2];f=0;m=1;w=0;z=0;while(1){t=f<<3;q=t+l|0;h=L[q>>3];if(!(h>0)){f=f+1|0;if((a|0)!=(f|0)){continue}if(m&1){break ab}break _a}w=L[e+t>>3]*h+w;L[g>>3]=w;z=L[q>>3]+z;L[k>>3]=z;m=0;f=f+1|0;if((a|0)!=(f|0)){continue}break}break _a}break ab}t=G[e+p>>2];q=G[e+o>>2];e=a;l=Fa-32|0;Fa=l;db:{eb:{fb:{f=G[926529];if(!f){f=1024;G[926529]=1024;a=ab(8192);G[926530]=a;fa=3706124,ga=ab(8192),G[fa>>2]=ga;if(!a){break fb}}a=1;v=f;f=e<<1;if((v|0)<(f|0)){G[926529]=f;f=e<<4;m=ub(G[926530],f);G[926530]=m;fa=3706124,ga=ub(G[926531],f),G[fa>>2]=ga;if(!m){break eb}}G[g>>2]=0;G[g+4>>2]=0;G[k>>2]=0;G[k+4>>2]=0;gb:{if((e|0)<=0){break gb}h=u*.5;f=0;D=G[926531];r=G[926530];a=0;while(1){A=a<<3;m=A+q|0;if(h>3]){N=f<<3;L[N+r>>3]=L[t+A>>3];L[D+N>>3]=L[m>>3];L[k>>3]=L[m>>3]+L[k>>3];f=f+1|0}a=a+1|0;if((e|0)!=(a|0)){continue}break}if(!f){a=1;break gb}e=1;m=G[926530];hb:{ib:{if((f|0)!=1){t=G[926531];while(1){a=e;while(1){jb:{q=a<<3;a=a-1|0;D=a<<3;r=D+m|0;h=L[r>>3];A=m+q|0;C=L[A>>3];if(!(h>C)){break jb}q=q+t|0;J=L[q>>3];L[A>>3]=h;v=q;q=t+D|0;L[v>>3]=L[q>>3];L[r>>3]=C;L[q>>3]=J;if(a){continue}}break}e=e+1|0;if((f|0)!=(e|0)){continue}break}if(!(f&1)){break ib}}else{f=1}h=L[((f|0)/2<<3)+m>>3];break hb}h=L[m>>3];if((f|0)==2){break hb}a=m+((f|0)/2<<3)|0;h=(L[a>>3]+L[a-8>>3])*.5}L[g>>3]=h;a=0}Fa=l+32|0;break db}G[l>>2]=3626;_a(G[321435],83707,l);break b}G[l+16>>2]=62721;_a(G[321435],83707,l+16|0);break b}if(!a){break Za}}L[g>>3]=L[c+1304>>3];G[k>>2]=0;G[k+4>>2]=0;break Za}l=G[e+o>>2];m=G[e+p>>2];G[k>>2]=0;G[k+4>>2]=1072693248;k=a&1;kb:{if((a|0)==1){f=0;h=0;break kb}a=a&-2;f=0;h=0;e=0;while(1){t=f<<3;h=!(L[t+l>>3]>0)|!(L[m+t>>3]>0)?h:h+1;t=(f|1)<<3;h=!(L[t+l>>3]>0)|!(L[m+t>>3]>0)?h:h+1;f=f+2|0;e=e+2|0;if((a|0)!=(e|0)){continue}break}}lb:{if(!k){break lb}a=f<<3;if(!(L[a+l>>3]>0)|!(L[a+m>>3]>0)){break lb}h=h+1}L[g>>3]=h;break Za}L[g>>3]=w/z}f=G[926497];j=j+1|0;if((f|0)>(j|0)){continue}break}}G[c+2360>>2]=1;G[c+2364>>2]=1;G[c+2356>>2]=s;G[c+2352>>2]=1;a=f>>31;if(ag(G[926496],82,c+2352|0,f,a,T,3705188)){break qa}if(!ag(G[926514],82,c+2352|0,f,a,U,3705188)){a=G[926498]<=(s|0);s=s+1|0;if(a){break ra}continue}break}a=G[926297];b=c+82384|0;uc(a,b);G[c+256>>2]=a;G[c+260>>2]=b;kb(80427,c+256|0);break d}if(G[926301]>0){Wc(3705196);L[c+112>>3]=G[926299]-G[926300]|0;gb(77992,c+112|0);$a(n)}if(Qb(G[926496],3705188)){break c}if(Qb(G[926514],3705188)){break c}if(G[926301]>0){yb(27750);$a(n)}Wc(3705196);L[c+96>>3]=G[926299]-G[926300]|0;xb(G[321435],77637,c+96|0);$a(n);$a(G[321435]);Hb(G[321435]);sc(0);W()}a=G[926297];b=c+82384|0;uc(a,b);G[c+272>>2]=a;G[c+276>>2]=b;kb(80427,c+272|0);break d}a=G[926297];b=c+82384|0;uc(a,b);G[c+288>>2]=a;G[c+292>>2]=b;kb(80427,c+288|0);break d}a=G[926297];b=c+82384|0;uc(a,b);G[c+320>>2]=a;G[c+324>>2]=b;kb(80427,c+320|0);break d}Ed(3705216);Ed(3705472);G[c+352>>2]=62784;_a(G[321435],83707,c+352|0);break e}Ed(3705216);Ed(3705472);G[c+336>>2]=62764;_a(G[321435],83707,c+336|0);break e}a=G[926297];b=c+82384|0;uc(a,b);G[c+688>>2]=a;G[c+692>>2]=b;kb(80427,c+688|0);break d}a=G[926297];b=c+82384|0;uc(a,b);G[c+704>>2]=a;G[c+708>>2]=b;kb(80427,c+704|0);break d}break c}break c}break c}break c}break c}break c}break c}break c}break c}break c}break c}break c}break c}break c}break c}break c}break c}break c}Ae(21295);W()}Ae(21278);W()}Ae(5471);W()}yb(32524);$a(n)}Ed(3705216);Ed(3705472);break a}$a(G[321435]);break a}Ed(3705216);Ed(3705472);$a(G[321435]);Hb(G[321435]);sc(a);W()}a=Fa-48|0;Fa=a;b=G[926297];d=a+16|0;uc(b,d);G[a>>2]=b;G[a+4>>2]=d;kb(80427,a);Ed(3705216);Ed(3705472);$a(G[321435]);Hb(G[321435]);sc(b);W()}$a(G[321435])}$a(G[321435]);Hb(G[321435]);sc(1);W()}function xu(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;j=Fa-32|0;Fa=j;G[j+28>>2]=0;G[j+24>>2]=0;G[j+20>>2]=0;G[j+16>>2]=0;Tl();c=Ic(1,72);G[j+28>>2]=c;G[c+64>>2]=G[29763];G[c+56>>2]=0;G[c+60>>2]=1072693248;G[c>>2]=1;G[c+4>>2]=32;G[c+8>>2]=1;c=G[j+28>>2];G[c+68>>2]=G[24367];G[c+44>>2]=0;c=Ic(1,128);G[j+24>>2]=c;G[c>>2]=0;c=Ic(1,128);G[j+20>>2]=c;G[c>>2]=1;c=Ic(1,40);G[j+16>>2]=c;G[c+32>>2]=0;G[c+36>>2]=1072693248;G[952413]=G[j+28>>2];G[952414]=G[j+24>>2];d=G[j+20>>2];G[952416]=c;G[952415]=d;G[945053]=154;d=G[j+28>>2];e=G[j+24>>2];c=G[j+20>>2];i=G[j+16>>2];g=Fa-32|0;Fa=g;G[47589]=1;h=G[24367];a:{b:{while(1){c:{switch(of(a,b,40975)+1|0){case 99:v=d,w=sb(G[321433]),L[v+56>>3]=w;continue;case 100:k=G[321433];G[d+16>>2]=1;G[d+48>>2]=k;if(!Sb(k,16840)){continue}G[d+12>>2]=1;continue;case 102:k=ac(G[321433],4017);G[d+68>>2]=k;if(k){G[945052]=k;continue}G[g>>2]=G[321433];Tb(h,69432,g);continue;case 104:G[d+20>>2]=1;continue;case 72:G[d+20>>2]=2;continue;case 107:G[d+44>>2]=1;continue;case 110:G[d+24>>2]=1;continue;case 112:k=ac(G[321433],4017);G[d+64>>2]=k;if(k){continue}G[g+16>>2]=G[321433];Tb(h,69388,g+16|0);continue;case 113:G[d+28>>2]=1;continue;case 115:G[d+32>>2]=1;continue;case 116:G[d+36>>2]=1;continue;case 123:G[d+40>>2]=1;continue;case 85:G[d+4>>2]=9;continue;case 50:G[d+16>>2]=1;continue;case 105:break b;case 0:break c;default:continue}}break}h=G[47589];a=a-h|0;if((a|0)>0){d:{v=e,x=Lc(G[(h<<2)+b>>2]),G[v+56>>2]=x;e:{if((a|0)!=1){h=G[((G[47589]<<2)+b|0)+4>>2];G[e+48>>2]=h;if(H[h|0]){break e}}G[e+48>>2]=64139}f:{if(a>>>0<3){break f}e=2;if((a|0)!=3){e=3;h=Lc(G[((G[47589]<<2)+b|0)+8>>2])}else{h=0}G[c+56>>2]=h;e=G[(G[47589]+e<<2)+b>>2];G[c+48>>2]=e;v=i,w=vb(e,g+28|0),L[v+24>>3]=w;e=G[c+48>>2];if(!(!e|!H[e|0]|(e|0)!=G[g+28>>2])){G[d>>2]=2;G[i+24>>2]=0;G[i+28>>2]=0;break f}if((a|0)==4){break d}G[d>>2]=1;G[c+48>>2]=0}Fa=g+32|0;break a}}}c=Fa-16|0;Fa=c;G[c>>2]=G[b>>2];a=G[24367];_a(a,76030,c);hb(86149,19,1,a);hb(87583,71,1,a);hb(70291,74,1,a);hb(87528,44,1,a);hb(68630,35,1,a);_a(a,87669,0);hb(70146,26,1,a);hb(87360,55,1,a);hb(68777,49,1,a);hb(87314,45,1,a);hb(68580,49,1,a);hb(87416,70,1,a);hb(68890,29,1,a);hb(68666,51,1,a);hb(68506,49,1,a);sc(1);W()}xl(G[j+28>>2],G[j+24>>2]);a=G[j+20>>2];g:{if(!G[a+48>>2]){break g}if(G[a+56>>2]){xl(G[j+28>>2],a);break g}b=G[j+24>>2];G[a+4>>2]=G[b+4>>2];G[a+8>>2]=G[b+8>>2];G[a+12>>2]=G[b+12>>2];G[a+16>>2]=G[b+16>>2];G[a+20>>2]=G[b+20>>2];G[a+24>>2]=G[b+24>>2];G[a+72>>2]=G[b+72>>2];G[a+60>>2]=G[b+60>>2];c=G[b+68>>2];G[a+28>>2]=1;G[a+68>>2]=c;G[a+124>>2]=G[b+124>>2]}if(!Jq(G[j+24>>2])){G[j>>2]=G[G[j+24>>2]+48>>2];Tb(G[24367],89438,j)}b=G[j+20>>2];h:{if(!G[b+48>>2]){a=G[j+28>>2];break h}Jq(b);a=G[j+28>>2];if(!G[a+24>>2]){b=G[j+20>>2];break h}b=G[j+20>>2];if(G[G[j+24>>2]+80>>2]!=G[b+80>>2]){break h}G[a>>2]=3}c=G[j+24>>2];d=G[j+16>>2];i:{if(G[b+56>>2]){f=L[c+96>>3];if(!(f>0)){break i}m=L[b+96>>3];if(!(m>0)){break i}f=f/m;L[d+32>>3]=f*f;break i}b=G[c+120>>2];if(!b|!(b?G[b+3312>>2]:0)){break i}b=G[c+120>>2];if(!G[b+3304>>2]){f=L[b+760>>3];L[c+96>>3]=(f<0?-f:f)*+G[c+72>>2];break i}f=L[b+768>>3];L[c+96>>3]=(f<0?-f:f)*+G[c+72>>2]}j:{if(!G[a+32>>2]){break j}a=G[c+116>>2];if(!a){break j}v=d,x=Lc(G[a+176>>2]),G[v>>2]=x}v=d,x=Ic(G[c+80>>2],8),G[v+8>>2]=x;v=d,x=Ic(G[c+80>>2],8),G[v+12>>2]=x;v=d,x=Ic(G[c+80>>2],8),G[v+16>>2]=x;v=d,x=Ic(G[c+80>>2],8),G[v+20>>2]=x;a=G[j+24>>2];d=G[j+20>>2];e=G[j+16>>2];b=Fa-416|0;Fa=b;k:{l:{m:{c=G[j+28>>2];switch(G[c+44>>2]){case 1:break l;case 0:break m;default:break k}}hb(73014,9,1,G[c+64>>2]);g=G[c+64>>2];G[b+192>>2]=G[a+56>>2];_a(g,70001,b+192|0);if(G[c+12>>2]){g=G[c+64>>2];G[b+176>>2]=G[a+40>>2];_a(g,75865,b+176|0)}f=L[c+56>>3];if(f!=1){g=G[c+64>>2];L[b+160>>3]=f;xb(g,72366,b+160|0)}f=L[a+96>>3];if(f>0){g=G[c+64>>2];L[b+144>>3]=f*3600;xb(g,71125,b+144|0)}hb(73211,13,1,G[c+64>>2]);g=G[d+56>>2];n:{if(g){i=G[c+64>>2];G[b+128>>2]=g;_a(i,70001,b+128|0);f=L[d+96>>3];if(f>0){g=G[c+64>>2];L[b+112>>3]=f*3600;xb(g,71125,b+112|0)}if(L[e+32>>3]==1){break n}e=G[c+64>>2];f=L[a+96>>3];L[b+104>>3]=L[d+96>>3];L[b+96>>3]=f;xb(e,88547,b+96|0);break n}d=G[c+64>>2];if(G[c>>2]!=1){G[b+80>>2]=G[a+56>>2];_a(d,70001,b+80|0);break n}L[b+64>>3]=L[e+24>>3];xb(d,72e3,b- -64|0)}if(G[c+28>>2]|!(L[a+96>>3]>0)){a=16895}else{a=30700}hb(68718,15,1,G[c+64>>2]);d=G[c+64>>2];G[b+48>>2]=a;_a(d,86480,b+48|0);d=G[c+64>>2];G[b+32>>2]=a;_a(d,86453,b+32|0);d=G[c+64>>2];G[b+16>>2]=a;_a(d,86426,b+16|0);if(!G[c+32>>2]){break k}d=G[c+64>>2];G[b>>2]=a;_a(d,68734,b);hb(68920,21,1,G[c+64>>2]);break k}hb(68421,2,1,G[c+64>>2]);hb(68390,14,1,G[c+64>>2]);f=L[c+56>>3];if(f!=1){g=G[c+64>>2];L[b+400>>3]=f;xb(g,87112,b+400|0)}f=L[a+96>>3];if(f>0){g=G[c+64>>2];L[b+384>>3]=f*3600;xb(g,87085,b+384|0)}if(G[c+12>>2]){g=G[c+64>>2];G[b+368>>2]=G[a+40>>2];_a(g,87136,b+368|0)}g=G[c+64>>2];G[b+352>>2]=G[a+56>>2];_a(g,89998,b+352|0);hb(87079,5,1,G[c+64>>2]);hb(68405,18,1,G[c+64>>2]);o:{if(G[d+56>>2]){f=L[d+96>>3];if(f>0){g=G[c+64>>2];L[b+336>>3]=f*3600;xb(g,71099,b+336|0)}if(L[e+32>>3]!=1){e=G[c+64>>2];f=L[a+96>>3];L[b+328>>3]=L[d+96>>3];L[b+320>>3]=f;xb(e,87220,b+320|0)}e=G[c+64>>2];G[b+304>>2]=G[d+56>>2];_a(e,89998,b+304|0);break o}d=G[c+64>>2];if(G[c>>2]!=1){G[b+288>>2]=G[a+56>>2];_a(d,89998,b+288|0);break o}L[b+272>>3]=L[e+24>>3];xb(d,71973,b+272|0)}hb(87079,5,1,G[c+64>>2]);if(G[c+28>>2]|!(L[a+96>>3]>0)){a=16895}else{a=30700}hb(68370,19,1,G[c+64>>2]);if(G[c+32>>2]){d=G[c+64>>2];G[b+256>>2]=a;_a(d,87165,b+256|0);hb(87186,25,1,G[c+64>>2])}d=G[c+64>>2];G[b+240>>2]=a;_a(d,87292,b+240|0);d=G[c+64>>2];G[b+224>>2]=a;_a(d,87255,b+224|0);d=G[c+64>>2];G[b+208>>2]=a;_a(d,90020,b+208|0);hb(87079,5,1,G[c+64>>2])}Fa=b+416|0;p:{while(1){Iq(G[j+28>>2],G[j+24>>2]);b=G[j+28>>2];if(G[b>>2]!=1){Iq(b,G[j+20>>2]);b=G[j+28>>2]}while(1){a=G[j+24>>2];d=G[j+20>>2];q:{r:{switch(G[b+36>>2]-1|0){case 0:bb(G[a+108>>2],G[a+104>>2],G[a+80>>2]<<3);bb(G[a+88>>2],G[a+84>>2],G[a+80>>2]<<2);if(G[a+80>>2]>=2){g=G[a+84>>2];e=G[g>>2];i=G[a+104>>2];f=L[i>>3];c=1;while(1){h=i+(c<<3)|0;f=f+L[h>>3];L[h>>3]=f;h=g+(c<<2)|0;e=G[h>>2]+e|0;G[h>>2]=e;c=c+1|0;if((c|0)>2]){continue}break}}if(G[b>>2]==1){break q}bb(G[d+108>>2],G[d+104>>2],G[d+80>>2]<<3);bb(G[d+88>>2],G[d+84>>2],G[d+80>>2]<<2);if(G[d+80>>2]<2){break q}a=G[d+84>>2];e=G[a>>2];b=G[d+104>>2];f=L[b>>3];c=1;while(1){g=b+(c<<3)|0;f=f+L[g>>3];L[g>>3]=f;g=a+(c<<2)|0;e=G[g>>2]+e|0;G[g>>2]=e;c=c+1|0;if((c|0)>2]){continue}break};break q;case 1:break r;default:break q}}bb(G[a+104>>2],G[a+108>>2],G[a+80>>2]<<3);bb(G[a+84>>2],G[a+88>>2],G[a+80>>2]<<2);if(G[b>>2]==1){break q}bb(G[d+104>>2],G[d+108>>2],G[d+80>>2]<<3);bb(G[d+84>>2],G[d+88>>2],G[d+80>>2]<<2)}d=G[j+24>>2];c=G[j+20>>2];a=G[j+16>>2];b=0;f=0;h=Fa-16|0;Fa=h;s:{t:{u:{v:{k=G[j+28>>2];switch(G[k>>2]-1|0){case 0:break t;case 1:break u;case 2:break v;default:break s}}if(G[d+80>>2]<=0){break s}i=G[c+84>>2];p=G[24367];while(1){n=b<<2;e=G[n+i>>2];if(!e){G[h>>2]=b;Tb(p,75994,h);i=G[c+84>>2];e=G[n+i>>2]}g=b<<3;l=g+G[c+104>>2]|0;f=L[a+32>>3]*(+G[n+G[d+84>>2]>>2]/+(e|0));m=L[l>>3]*f;L[g+G[a+8>>2]>>3]=m;e=g+G[d+104>>2]|0;L[g+G[a+16>>2]>>3]=L[e>>3]-m;L[g+G[a+20>>2]>>3]=V(f*f*L[l>>3]+L[e>>3]);L[g+G[a+12>>2]>>3]=G[k+8>>2]?f*V(L[l>>3]):0;b=b+1|0;if((b|0)>2]){continue}break}break s}w:{x:{y:{z:{if(G[k+36>>2]==1){b=G[c+80>>2]-1|0;L[a+24>>3]=L[G[c+104>>2]+(b<<3)>>3];b=G[G[c+84>>2]+(b<<2)>>2];break z}G[a+4>>2]=0;G[a+24>>2]=0;G[a+28>>2]=0;e=G[c+80>>2];if((e|0)<=0){break x}n=e&1;g=G[c+84>>2];i=G[c+104>>2];A:{if((e|0)==1){c=0;break A}l=e&-2;c=0;e=0;while(1){f=L[i+(c<<3)>>3]+f;L[a+24>>3]=f;b=G[g+(c<<2)>>2]+b|0;G[a+4>>2]=b;p=c|1;f=L[i+(p<<3)>>3]+f;L[a+24>>3]=f;b=b+G[g+(p<<2)>>2]|0;G[a+4>>2]=b;c=c+2|0;e=e+2|0;if((l|0)!=(e|0)){continue}break}}if(!n){break y}L[a+24>>3]=L[i+(c<<3)>>3]+f;b=G[g+(c<<2)>>2]+b|0}G[a+4>>2]=b}if(b){break w}}Tb(G[24367],75968,0)}e=G[d+80>>2];if((e|0)<=0){break s}g=G[a+12>>2];i=G[k+8>>2];k=G[a+20>>2];n=G[a+16>>2];l=G[d+104>>2];p=G[a+8>>2];d=G[d+84>>2];m=+G[a+4>>2];b=0;while(1){c=b<<3;f=L[a+32>>3]*(+G[d+(b<<2)>>2]/m);q=L[a+24>>3]*f;L[c+p>>3]=q;r=c+l|0;L[c+n>>3]=L[r>>3]-q;L[c+k>>3]=V(f*f*L[a+24>>3]+L[r>>3]);L[c+g>>3]=i?f*V(L[a+24>>3]):0;b=b+1|0;if((e|0)!=(b|0)){continue}break}break s}e=G[d+80>>2];if((e|0)<=0){break s}g=G[a+12>>2];i=G[a+20>>2];k=G[a+16>>2];n=G[d+104>>2];l=G[a+8>>2];d=G[d+84>>2];while(1){c=b<<3;f=L[a+24>>3]*+G[d+(b<<2)>>2];L[c+l>>3]=f;p=c+n|0;L[c+k>>3]=L[p>>3]-f;L[c+i>>3]=V(L[p>>3]);c=c+g|0;G[c>>2]=0;G[c+4>>2]=0;b=b+1|0;if((e|0)!=(b|0)){continue}break}}Fa=h+16|0;h=G[j+24>>2];k=G[j+16>>2];i=0;n=0;p=0;c=Fa-29792|0;Fa=c;B:{C:{D:{d=G[j+28>>2];switch(G[d+44>>2]){case 1:break C;case 0:break D;default:break B}}E[c+25696|0]=0;if(G[d+12>>2]){G[c+720>>2]=G[h+36>>2]+1;Ya(c+25696|0,4096,30105,c+720|0)}E:{if(G[d+36>>2]==1){if(!G[d+12>>2]){Ub(10,G[d+64>>2])}a=G[d+64>>2];G[c+672>>2]=c+25696;_a(a,69018,c+672|0);a=G[d+64>>2];b=G[d+4>>2];G[c+660>>2]=b;G[c+656>>2]=b;_a(a,10851,c+656|0);break E}if(G[d+4>>2]==9){Ub(12,G[d+64>>2])}if(!G[d+12>>2]){Ub(10,G[d+64>>2])}a=G[d+64>>2];G[c+704>>2]=c+25696;_a(a,69060,c+704|0);a=G[d+64>>2];b=G[d+4>>2];G[c+692>>2]=b;G[c+688>>2]=b;_a(a,10881,c+688|0)}a=G[d+64>>2];b=G[d+4>>2];G[c+644>>2]=b;G[c+640>>2]=b;_a(a,10604,c+640|0);b=G[d+64>>2];a=G[d+4>>2];G[c+632>>2]=a;G[c+628>>2]=a;G[c+624>>2]=a;_a(b,10379,c+624|0);a=d- -64|0;if(G[d+32>>2]){e=G[a>>2];b=G[d+4>>2];G[c+620>>2]=b;G[c+616>>2]=b;G[c+612>>2]=b;G[c+608>>2]=b;_a(e,40650,c+608|0)}Ub(10,G[d+64>>2]);b=G[d+64>>2];e=G[d+4>>2];G[c+596>>2]=e;G[c+592>>2]=e;_a(b,48566,c+592|0);b=G[d+64>>2];e=G[d+4>>2];G[c+580>>2]=e;G[c+576>>2]=e;_a(b,48570,c+576|0);e=G[d+64>>2];b=G[d+4>>2];G[c+568>>2]=b;G[c+564>>2]=b;G[c+560>>2]=b;_a(e,48532,c+560|0);if(G[d+32>>2]){e=G[a>>2];b=G[d+4>>2];G[c+556>>2]=b;G[c+552>>2]=b;G[c+548>>2]=b;G[c+544>>2]=b;_a(e,48521,c+544|0)}Ub(10,G[a>>2]);if(G[k>>2]){dj(49008)}if(G[h+80>>2]>0){e=G[k>>2];g=0;while(1){F:{if(!e){break F}g=jb(e,10);if(!g){g=0;break F}E[g|0]=0}l=G[G[h+84>>2]+(i<<2)>>2];G:{H:{if(l){b=i<<3;s=L[b+G[k+20>>2]>>3];f=+(l|0);m=s/f;t=L[b+G[k+16>>2]>>3];q=t/f;I:{if(G[d+28>>2]){break I}o=L[h+96>>3];if(!(o>0)){break I}o=o*o;f=o*f*1296e4;m=m/o/1296e4;q=q/o/1296e4}l=G[d+20>>2];if(l>>>0<=2){n=G[(l<<2)+189380>>2]}o=L[b+G[k+8>>2]>>3];u=L[b+G[k+12>>2]>>3];l=G[d+64>>2];b=G[d+4>>2];L[c+536>>3]=m;G[c+528>>2]=b;L[c+520>>3]=q;G[c+512>>2]=b;L[c+504>>3]=f;G[c+496>>2]=b;L[c+488>>3]=u;G[c+480>>2]=b;L[c+472>>3]=o;G[c+464>>2]=b;L[c+456>>3]=s;G[c+448>>2]=b;L[c+440>>3]=t;G[c+436>>2]=b;G[c+432>>2]=i+1;xb(l,n,c+432|0);if(!G[d+32>>2]|!e){break H}G[c+21600>>2]=0;J:{K:{if(!Ld(e,c+5216|0,c+21600|0)){break K}if(!nb(c+5216|0,35978,3)){break K}f=vb(c+5216|0,0);L:{if(G[d+28>>2]){break L}m=L[h+96>>3];if(!(m>0)){break L}b=G[a>>2];G[c+400>>2]=G[d+4>>2];L[c+408>>3]=f*m*3600;xb(b,19001,c+400|0);break J}b=G[a>>2];l=G[d+4>>2];L[c+424>>3]=f;G[c+416>>2]=l;xb(b,19001,c+416|0);break J}b=G[a>>2];l=G[d+4>>2];G[c+388>>2]=35978;G[c+384>>2]=l;_a(b,8526,c+384|0)}M:{N:{if(!Ld(e,c+5216|0,c+21600|0)){break N}if(!nb(c+5216|0,35978,3)){break N}f=vb(c+5216|0,0);O:{if(!G[d+28>>2]){m=L[h+96>>3];if(m>0){break O}}b=G[a>>2];l=G[d+4>>2];L[c+376>>3]=f;G[c+368>>2]=l;xb(b,19001,c+368|0);break M}b=G[a>>2];G[c+352>>2]=G[d+4>>2];L[c+360>>3]=f*m*3600;xb(b,19001,c+352|0);break M}b=G[a>>2];l=G[d+4>>2];G[c+340>>2]=35978;G[c+336>>2]=l;_a(b,8526,c+336|0)}P:{Q:{if(!Ld(e,c+5216|0,c+21600|0)){break Q}if(!nb(c+5216|0,35978,3)){break Q}f=vb(c+5216|0,0);b=G[a>>2];l=G[d+4>>2];L[c+328>>3]=f;G[c+320>>2]=l;xb(b,19001,c+320|0);break P}b=G[a>>2];l=G[d+4>>2];G[c+308>>2]=35978;G[c+304>>2]=l;_a(b,8526,c+304|0)}R:{if(!Ld(e,c+5216|0,c+21600|0)){break R}if(!nb(c+5216|0,35978,3)){break R}f=vb(c+5216|0,0);b=G[a>>2];l=G[d+4>>2];L[c+296>>3]=f;G[c+288>>2]=l;xb(b,19001,c+288|0);break H}b=G[a>>2];l=G[d+4>>2];G[c+276>>2]=35978;G[c+272>>2]=l;_a(b,8526,c+272|0);break H}if(!G[d+40>>2]){break G}b=G[d+20>>2];if(b>>>0<=2){n=G[(b<<2)+189380>>2]}l=G[d+64>>2];b=G[d+4>>2];G[c+264>>2]=0;G[c+268>>2]=0;G[c+256>>2]=b;G[c+248>>2]=0;G[c+252>>2]=0;G[c+240>>2]=b;G[c+232>>2]=0;G[c+236>>2]=0;G[c+224>>2]=b;G[c+216>>2]=0;G[c+220>>2]=0;G[c+208>>2]=b;G[c+200>>2]=0;G[c+204>>2]=0;G[c+192>>2]=b;G[c+184>>2]=0;G[c+188>>2]=0;G[c+176>>2]=b;G[c+168>>2]=0;G[c+172>>2]=0;G[c+164>>2]=b;G[c+160>>2]=i+1;xb(l,n,c+160|0);if(!G[d+32>>2]|!e){break H}G[c+21600>>2]=0;S:{T:{if(!Ld(e,c+5216|0,c+21600|0)){break T}if(!nb(c+5216|0,35978,3)){break T}f=vb(c+5216|0,0);U:{if(G[d+28>>2]){break U}m=L[h+96>>3];if(!(m>0)){break U}b=G[a>>2];G[c+128>>2]=G[d+4>>2];L[c+136>>3]=f*m*3600;xb(b,19001,c+128|0);break S}b=G[a>>2];l=G[d+4>>2];L[c+152>>3]=f;G[c+144>>2]=l;xb(b,19001,c+144|0);break S}b=G[a>>2];l=G[d+4>>2];G[c+116>>2]=35978;G[c+112>>2]=l;_a(b,8526,c+112|0)}V:{W:{if(!Ld(e,c+5216|0,c+21600|0)){break W}if(!nb(c+5216|0,35978,3)){break W}f=vb(c+5216|0,0);X:{if(!G[d+28>>2]){m=L[h+96>>3];if(m>0){break X}}b=G[a>>2];l=G[d+4>>2];L[c+104>>3]=f;G[c+96>>2]=l;xb(b,19001,c+96|0);break V}b=G[a>>2];G[c+80>>2]=G[d+4>>2];L[c+88>>3]=f*m*3600;xb(b,19001,c+80|0);break V}b=G[a>>2];l=G[d+4>>2];G[c+68>>2]=35978;G[c+64>>2]=l;_a(b,8526,c- -64|0)}Y:{Z:{if(!Ld(e,c+5216|0,c+21600|0)){break Z}if(!nb(c+5216|0,35978,3)){break Z}f=vb(c+5216|0,0);b=G[a>>2];l=G[d+4>>2];L[c+56>>3]=f;G[c+48>>2]=l;xb(b,19001,c+48|0);break Y}b=G[a>>2];l=G[d+4>>2];G[c+36>>2]=35978;G[c+32>>2]=l;_a(b,8526,c+32|0)}_:{if(!Ld(e,c+5216|0,c+21600|0)){break _}if(!nb(c+5216|0,35978,3)){break _}f=vb(c+5216|0,0);b=G[a>>2];l=G[d+4>>2];L[c+24>>3]=f;G[c+16>>2]=l;xb(b,19001,c+16|0);break H}b=G[a>>2];l=G[d+4>>2];G[c+4>>2]=35978;G[c>>2]=l;_a(b,8526,c)}Ub(10,G[a>>2])}if(g){E[g|0]=10;e=g+1|0}i=i+1|0;if((i|0)>2]){continue}break}}if(G[k>>2]){cj()}Ub(10,G[a>>2]);$a(G[a>>2]);break B}E[c+1120|0]=0;if(G[d+12>>2]){G[c+1104>>2]=G[h+36>>2]+1;Ya(c+1120|0,4096,30633,c+1104|0)}a=G[d+36>>2];b=G[d+64>>2];G[c+1088>>2]=c+1120;a=(a|0)==1;_a(b,a?85159:85121,c+1088|0);G[c+5244>>2]=10911;G[c+5240>>2]=5880;G[c+5236>>2]=31629;G[c+5232>>2]=10623;G[c+5228>>2]=26062;G[c+5224>>2]=10905;G[c+5220>>2]=5483;G[c+5216>>2]=a?13535:18018;if(G[d+32>>2]){G[c+5260>>2]=40688;G[c+5256>>2]=41048;G[c+5252>>2]=40616;G[c+5248>>2]=41014}if(G[k>>2]){dj(49008)}if(G[h+80>>2]>0){l=G[k>>2];while(1){$:{if(!l){break $}n=jb(l,10);if(!n){n=0;break $}E[n|0]=0}b=G[G[h+84>>2]+(i<<2)>>2];aa:{ba:{ca:{if(b){a=i<<3;s=L[a+G[k+20>>2]>>3];f=+(b|0);m=s/f;t=L[a+G[k+16>>2]>>3];q=t/f;da:{if(G[d+28>>2]){break da}o=L[h+96>>3];if(!(o>0)){break da}o=o*o;f=o*f*1296e4;m=m/o/1296e4;q=q/o/1296e4}b=G[d+20>>2];if(b>>>0<=2){p=G[(b<<2)+189392>>2]}o=L[a+G[k+12>>2]>>3];u=L[a+G[k+8>>2]>>3];L[c+976>>3]=t;G[c+984>>2]=G[c+5224>>2];L[c+992>>3]=s;G[c+1e3>>2]=G[c+5228>>2];L[c+1008>>3]=u;G[c+1016>>2]=G[c+5232>>2];L[c+1024>>3]=o;G[c+1032>>2]=G[c+5236>>2];L[c+1040>>3]=f;G[c+1048>>2]=G[c+5240>>2];L[c+1056>>3]=q;G[c+1064>>2]=G[c+5244>>2];L[c+1072>>3]=m;G[c+960>>2]=G[c+5216>>2];G[c+964>>2]=i+1;G[c+968>>2]=G[c+5220>>2];a=c+21600|0;Ya(a,4096,p,c+960|0);Sg(G[d+64>>2],a);ea:{if(!G[d+32>>2]|!l){break ea}g=0;G[c+1116>>2]=0;hb(67812,2,1,G[d+64>>2]);while(1){fa:{ga:{if(!Ld(l,c+25696|0,c+1116|0)){break ga}if(!nb(c+25696|0,35978,3)){break ga}f=vb(c+25696|0,0);ha:{if(G[d+28>>2]|g>>>0>1){break ha}m=L[h+96>>3];if(!(m>0)){break ha}L[c+936>>3]=f*m*3600;G[c+928>>2]=G[(c+(g<<2)|0)+5248>>2];Ya(c+21600|0,4096,19222,c+928|0);break fa}L[c+952>>3]=f;G[c+944>>2]=G[(c+(g<<2)|0)+5248>>2];Ya(c+21600|0,4096,19222,c+944|0);break fa}G[c+916>>2]=65593;G[c+912>>2]=G[(c+(g<<2)|0)+5248>>2];Ya(c+21600|0,4096,8547,c+912|0)}r=G[d+64>>2];a=c+21600|0;while(1){ia:{ja:{ka:{e=Sb(a,16007);if(!e){e=Sb(a,34391);if(!e){break ka}}b=e+4|0;break ja}e=Sb(a,16008);if(!e){e=Sb(a,34392);if(!e){break ia}}b=e+3|0}E[e|0]=0;fe(a,r);hb(65587,5,1,r);a=b;continue}break}fe(a,r);if((g|0)==3){break ea}Ub(44,G[d+64>>2]);g=g+1|0;continue}}Ub(125,G[d+64>>2]);if((G[h+80>>2]-1|0)!=(i|0)){break ca}break ba}if(!G[d+40>>2]){break aa}a=G[d+20>>2];if(a>>>0<=2){p=G[(a<<2)+189404>>2]}a=G[d+64>>2];G[c+800>>2]=0;G[c+804>>2]=0;G[c+808>>2]=G[c+5224>>2];G[c+816>>2]=0;G[c+820>>2]=0;G[c+824>>2]=G[c+5228>>2];G[c+832>>2]=0;G[c+836>>2]=0;G[c+840>>2]=G[c+5232>>2];G[c+848>>2]=0;G[c+852>>2]=0;G[c+856>>2]=G[c+5236>>2];G[c+864>>2]=0;G[c+868>>2]=0;G[c+872>>2]=G[c+5240>>2];G[c+880>>2]=0;G[c+884>>2]=0;G[c+888>>2]=G[c+5244>>2];G[c+896>>2]=0;G[c+900>>2]=0;G[c+784>>2]=G[c+5216>>2];G[c+788>>2]=i+1;G[c+792>>2]=G[c+5220>>2];xb(a,p,c+784|0);la:{if(!G[d+32>>2]|!l){break la}g=0;G[c+1116>>2]=0;hb(67812,2,1,G[d+64>>2]);while(1){ma:{na:{if(!Ld(l,c+25696|0,c+1116|0)){break na}if(!nb(c+25696|0,35978,3)){break na}f=vb(c+25696|0,0);oa:{if(G[d+28>>2]|g>>>0>1){break oa}m=L[h+96>>3];if(!(m>0)){break oa}L[c+760>>3]=f*m*3600;G[c+752>>2]=G[(c+(g<<2)|0)+5248>>2];Ya(c+21600|0,4096,19104,c+752|0);break ma}L[c+776>>3]=f;G[c+768>>2]=G[(c+(g<<2)|0)+5248>>2];Ya(c+21600|0,4096,19104,c+768|0);break ma}G[c+740>>2]=65593;G[c+736>>2]=G[(c+(g<<2)|0)+5248>>2];Ya(c+21600|0,4096,8534,c+736|0)}r=G[d+64>>2];a=c+21600|0;while(1){pa:{qa:{ra:{e=Sb(a,16007);if(!e){e=Sb(a,34391);if(!e){break ra}}b=e+4|0;break qa}e=Sb(a,16008);if(!e){e=Sb(a,34392);if(!e){break pa}}b=e+3|0}E[e|0]=0;fe(a,r);hb(65587,5,1,r);a=b;continue}break}fe(a,r);if((g|0)==3){break la}Ub(44,G[d+64>>2]);g=g+1|0;continue}}Ub(125,G[d+64>>2]);if((G[h+80>>2]-1|0)==(i|0)){break ba}}Ub(44,G[d+64>>2])}Ub(10,G[d+64>>2])}if(n){E[n|0]=10;l=n+1|0}i=i+1|0;if((i|0)>2]){continue}break}}if(G[k>>2]){cj()}hb(87159,5,1,G[d+64>>2]);$a(G[d+64>>2])}Fa=c+29792|0;b=G[j+28>>2];if(G[b+36>>2]==1){G[b+36>>2]=2;continue}break}h=G[j+24>>2];a=0;e=0;i=0;g=0;f=0;d=Fa-8544|0;Fa=d;sa:{ta:{switch(G[b+44>>2]){case 0:a=G[b+4>>2];ua:{if(G[b+36>>2]){if((a|0)==9){Ub(12,G[b+64>>2])}Ub(10,G[b+64>>2]);if(G[h+52>>2]){hb(86390,20,1,G[b+64>>2]);a=G[b+64>>2];G[d+160>>2]=G[h+52>>2];_a(a,90110,d+160|0)}hb(75886,21,1,G[b+64>>2]);c=G[b+64>>2];a=G[b+4>>2];G[d+156>>2]=a;G[d+152>>2]=a;G[d+148>>2]=a;G[d+144>>2]=a;_a(c,68450,d+144|0);c=G[b+64>>2];a=G[b+4>>2];G[d+140>>2]=a;G[d+136>>2]=a;G[d+132>>2]=a;G[d+128>>2]=a;_a(c,87023,d+128|0);if(G[h+80>>2]<=0){break ua}a=0;while(1){i=G[G[h+84>>2]+(a<<2)>>2];e=i+e|0;m=L[G[h+104>>2]+(a<<3)>>3];f=f+m;c=G[b+20>>2];if(c>>>0<=2){g=G[(c<<2)+189440>>2]}k=G[b+64>>2];c=G[b+4>>2];G[d+124>>2]=e;G[d+120>>2]=c;L[d+112>>3]=f;G[d+104>>2]=c;G[d+100>>2]=i;G[d+96>>2]=c;L[d+88>>3]=m;G[d+84>>2]=c;a=a+1|0;G[d+80>>2]=a;xb(k,g,d+80|0);if(G[h+80>>2]>(a|0)){continue}break}break ua}if((a|0)==9){Ub(12,G[b+64>>2])}if(G[h+52>>2]){hb(86390,20,1,G[b+64>>2]);a=G[b+64>>2];G[d+64>>2]=G[h+52>>2];_a(a,90110,d- -64|0)}hb(75908,14,1,G[b+64>>2]);a=G[b+64>>2];c=G[b+4>>2];G[d+52>>2]=c;G[d+48>>2]=c;_a(a,6911,d+48|0);Ub(10,G[b+64>>2]);a=G[b+64>>2];c=G[b+4>>2];G[d+36>>2]=c;G[d+32>>2]=c;_a(a,48566,d+32|0);Ub(10,G[b+64>>2]);if(G[h+80>>2]<=0){break ua}a=0;while(1){c=G[b+20>>2];if(c>>>0<=2){i=G[(c<<2)+189452>>2]}f=L[G[h+104>>2]+(a<<3)>>3];e=G[b+64>>2];c=G[b+4>>2];G[d+20>>2]=G[G[h+84>>2]+(a<<2)>>2];G[d+16>>2]=c;L[d+8>>3]=f;G[d+4>>2]=c;a=a+1|0;G[d>>2]=a;xb(e,i,d);Ub(10,G[b+64>>2]);if(G[h+80>>2]>(a|0)){continue}break}}Ub(10,G[b+64>>2]);$a(G[b+64>>2]);break sa;case 1:break ta;default:break sa}}E[d+4448|0]=0;if(G[b+12>>2]){G[d+336>>2]=G[h+36>>2]+1;Ya(d+4448|0,4096,30633,d+336|0)}va:{wa:{c=G[h+52>>2];xa:{if(c){if(H[c|0]){i=Va(c)}g=lb(i<<1|1,1);if((i|0)>0){while(1){ya:{za:{k=H[a+c|0];if((k|0)!=10){if((k|0)!=34){break za}k=e+g|0;E[k|0]=92;E[k+1|0]=34;e=e+1|0;break ya}E[e+g|0]=59;k=a+1|0;a=H[c+k|0]==35?k:a;break ya}E[e+g|0]=k}e=e+1|0;a=a+1|0;if((i|0)>(a|0)){continue}break}}E[e+g|0]=0;a=G[b+36>>2];c=G[b+64>>2];G[d+320>>2]=d+4448;_a(c,67652,d+320|0);c=G[b+64>>2];G[d+304>>2]=g;_a(c,87212,d+304|0);if(a){break xa}break wa}if(!G[b+36>>2]){break wa}}a=G[b+64>>2];G[d+288>>2]=d+4448;_a(a,85224,d+288|0);if(G[h+80>>2]<=0){break va}a=0;e=0;i=0;while(1){c=G[G[h+84>>2]+(a<<2)>>2];e=c+e|0;m=L[G[h+104>>2]+(a<<3)>>3];f=f+m;k=G[b+20>>2];if(k>>>0<=2){i=G[(k<<2)+189476>>2]}G[d+276>>2]=e;G[d+272>>2]=3737;L[d+264>>3]=f;G[d+256>>2]=5601;G[d+252>>2]=c;G[d+248>>2]=6934;L[d+240>>3]=m;G[d+232>>2]=5476;G[d+224>>2]=18018;c=a+1|0;G[d+228>>2]=c;k=d+352|0;Ya(k,4096,i,d+224|0);Sg(G[b+64>>2],k);if((G[h+80>>2]-1|0)!=(a|0)){Ub(44,G[b+64>>2])}Ub(10,G[b+64>>2]);a=c;if((c|0)>2]){continue}break}break va}a=G[b+64>>2];G[d+208>>2]=d+4448;_a(a,85203,d+208|0);if(G[h+80>>2]<=0){break va}a=0;e=0;while(1){c=G[b+20>>2];if(c>>>0<=2){e=G[(c<<2)+189416>>2]}f=L[G[h+104>>2]+(a<<3)>>3];G[d+204>>2]=G[G[h+84>>2]+(a<<2)>>2];G[d+200>>2]=6934;L[d+192>>3]=f;G[d+184>>2]=5476;c=a+1|0;G[d+180>>2]=c;G[d+176>>2]=18018;i=d+352|0;Ya(i,4096,e,d+176|0);Sg(G[b+64>>2],i);if((G[h+80>>2]-1|0)!=(a|0)){Ub(44,G[b+64>>2])}Ub(10,G[b+64>>2]);a=c;if((c|0)>2]){continue}break}}hb(87159,5,1,G[b+64>>2]);$a(G[b+64>>2]);if(!g){break sa}Wa(g)}Fa=d+8544|0;h=G[j+20>>2];b=G[j+16>>2];a=0;e=0;i=0;g=0;f=0;c=Fa-8736|0;Fa=c;Aa:{Ba:{Ca:{d=G[j+28>>2];switch(G[d+44>>2]){case 1:break Ba;case 0:break Ca;default:break Aa}}Da:{Ea:{Fa:{switch(G[d>>2]-2|0){case 0:if(G[d+4>>2]==9){Ub(12,G[d+64>>2])}if(G[h+52>>2]){hb(87487,23,1,G[d+64>>2]);a=G[d+64>>2];G[c+240>>2]=G[h+52>>2];_a(a,90110,c+240|0)}hb(75949,18,1,G[d+64>>2]);a=G[d+64>>2];g=G[d+4>>2];G[c+228>>2]=g;G[c+224>>2]=g;_a(a,6911,c+224|0);Ub(10,G[d+64>>2]);a=G[d+64>>2];g=G[d+4>>2];G[c+212>>2]=g;G[c+208>>2]=g;_a(a,48566,c+208|0);Ub(10,G[d+64>>2]);a=G[d+20>>2];if(a>>>0<=2){e=G[(a<<2)+189428>>2]}g=G[d+64>>2];f=L[b+24>>3];a=G[d+4>>2];G[c+196>>2]=G[b+4>>2];G[c+192>>2]=a;L[c+184>>3]=f;G[c+180>>2]=a;G[c+176>>2]=66360;xb(g,e,c+176|0);Ub(10,G[d+64>>2]);a=d- -64|0;break Ea;case 1:break Fa;default:break Da}}a=G[d+4>>2];Ga:{if(G[d+36>>2]){if((a|0)==9){Ub(12,G[d+64>>2])}if(G[h+52>>2]){hb(87487,23,1,G[d+64>>2]);a=G[d+64>>2];G[c+160>>2]=G[h+52>>2];_a(a,90110,c+160|0)}hb(75923,25,1,G[d+64>>2]);b=G[d+64>>2];a=G[d+4>>2];G[c+156>>2]=a;G[c+152>>2]=a;G[c+148>>2]=a;G[c+144>>2]=a;_a(b,68450,c+144|0);b=G[d+64>>2];a=G[d+4>>2];G[c+140>>2]=a;G[c+136>>2]=a;G[c+132>>2]=a;G[c+128>>2]=a;_a(b,87023,c+128|0);if(G[h+80>>2]<=0){break Ga}a=0;while(1){g=G[G[h+84>>2]+(a<<2)>>2];e=g+e|0;m=L[G[h+104>>2]+(a<<3)>>3];f=f+m;b=G[d+20>>2];if(b>>>0<=2){i=G[(b<<2)+189440>>2]}k=G[d+64>>2];b=G[d+4>>2];G[c+124>>2]=e;G[c+120>>2]=b;L[c+112>>3]=f;G[c+104>>2]=b;G[c+100>>2]=g;G[c+96>>2]=b;L[c+88>>3]=m;G[c+84>>2]=b;a=a+1|0;G[c+80>>2]=a;xb(k,i,c+80|0);if(G[h+80>>2]>(a|0)){continue}break}break Ga}if((a|0)==9){Ub(12,G[d+64>>2])}if(G[h+52>>2]){hb(87487,23,1,G[d+64>>2]);a=G[d+64>>2];G[c+64>>2]=G[h+52>>2];_a(a,90110,c- -64|0)}hb(75949,18,1,G[d+64>>2]);a=G[d+64>>2];b=G[d+4>>2];G[c+52>>2]=b;G[c+48>>2]=b;_a(a,6911,c+48|0);Ub(10,G[d+64>>2]);a=G[d+64>>2];b=G[d+4>>2];G[c+36>>2]=b;G[c+32>>2]=b;_a(a,48566,c+32|0);Ub(10,G[d+64>>2]);if(G[h+80>>2]<=0){break Ga}a=0;while(1){b=G[d+20>>2];if(b>>>0<=2){i=G[(b<<2)+189452>>2]}f=L[G[h+104>>2]+(a<<3)>>3];e=G[d+64>>2];b=G[d+4>>2];G[c+20>>2]=G[G[h+84>>2]+(a<<2)>>2];G[c+16>>2]=b;L[c+8>>3]=f;G[c+4>>2]=b;a=a+1|0;G[c>>2]=a;xb(e,i,c);Ub(10,G[d+64>>2]);if(G[h+80>>2]>(a|0)){continue}break}}a=d- -64|0}Ub(10,G[a>>2])}$a(G[d+64>>2]);break Aa}E[c+4640|0]=0;if(G[d+12>>2]){G[c+528>>2]=G[h+36>>2]+1;Ya(c+4640|0,4096,30633,c+528|0)}k=G[h+52>>2];if(k){if(H[k|0]){i=Va(k)}g=lb(i<<1|1,1);if((i|0)>0){while(1){Ha:{Ia:{n=H[a+k|0];if((n|0)!=10){if((n|0)!=34){break Ia}n=e+g|0;E[n|0]=92;E[n+1|0]=34;e=e+1|0;break Ha}E[e+g|0]=59;n=a+1|0;a=H[k+n|0]==35?n:a;break Ha}E[e+g|0]=n}e=e+1|0;a=a+1|0;if((i|0)>(a|0)){continue}break}}E[e+g|0]=0}Ja:{Ka:{La:{switch(G[d>>2]-2|0){case 0:if(g){a=G[d+64>>2];G[c+512>>2]=c+4640;_a(a,67674,c+512|0);a=G[d+64>>2];G[c+496>>2]=g;_a(a,87212,c+496|0)}a=G[d+64>>2];G[c+480>>2]=c+4640;_a(a,85251,c+480|0);e=d- -64|0;a=0;i=G[d+20>>2];if(i>>>0<=2){a=G[(i<<2)+189464>>2]}f=L[b+24>>3];G[c+476>>2]=G[b+4>>2];G[c+472>>2]=6934;L[c+464>>3]=f;G[c+456>>2]=5476;G[c+452>>2]=65542;G[c+448>>2]=18018;b=c+544|0;Ya(b,4096,a,c+448|0);Sg(G[e>>2],b);Ub(10,G[e>>2]);break Ka;case 1:break La;default:break Ja}}Ma:{if(G[d+36>>2]){if(g){a=G[d+64>>2];G[c+432>>2]=c+4640;_a(a,67674,c+432|0);a=G[d+64>>2];G[c+416>>2]=g;_a(a,87212,c+416|0)}a=G[d+64>>2];G[c+400>>2]=c+4640;_a(a,85276,c+400|0);if(G[h+80>>2]<=0){break Ma}e=0;a=0;i=0;while(1){b=G[G[h+84>>2]+(a<<2)>>2];e=b+e|0;m=L[G[h+104>>2]+(a<<3)>>3];f=f+m;k=G[d+20>>2];if(k>>>0<=2){i=G[(k<<2)+189476>>2]}G[c+388>>2]=e;G[c+384>>2]=3737;L[c+376>>3]=f;G[c+368>>2]=5601;G[c+364>>2]=b;G[c+360>>2]=6934;L[c+352>>3]=m;G[c+344>>2]=5476;G[c+336>>2]=18018;b=a+1|0;G[c+340>>2]=b;k=c+544|0;Ya(k,4096,i,c+336|0);Sg(G[d+64>>2],k);if((G[h+80>>2]-1|0)!=(a|0)){Ub(44,G[d+64>>2])}Ub(10,G[d+64>>2]);a=b;if((a|0)>2]){continue}break}break Ma}if(g){a=G[d+64>>2];G[c+320>>2]=c+4640;_a(a,67674,c+320|0);a=G[d+64>>2];G[c+304>>2]=g;_a(a,87212,c+304|0)}a=G[d+64>>2];G[c+288>>2]=c+4640;_a(a,85251,c+288|0);if(G[h+80>>2]<=0){break Ma}a=0;e=0;while(1){b=G[d+20>>2];if(b>>>0<=2){e=G[(b<<2)+189488>>2]}f=L[G[h+104>>2]+(a<<3)>>3];G[c+284>>2]=G[G[h+84>>2]+(a<<2)>>2];G[c+280>>2]=6934;L[c+272>>3]=f;G[c+264>>2]=5476;b=a+1|0;G[c+260>>2]=b;G[c+256>>2]=18018;i=c+544|0;Ya(i,4096,e,c+256|0);Sg(G[d+64>>2],i);if((G[h+80>>2]-1|0)!=(a|0)){Ub(44,G[d+64>>2])}Ub(10,G[d+64>>2]);a=b;if((a|0)>2]){continue}break}}e=d- -64|0}hb(87159,5,1,G[e>>2])}$a(G[d+64>>2]);if(!g){break Aa}Wa(g)}Fa=c+8736|0;if(!G[G[j+28>>2]+12>>2]){break p}a=G[j+20>>2];d=G[a+40>>2];Na:{if(!d){break Na}b=G[a+36>>2]+1|0;G[a+36>>2]=b;c=G[a+64>>2];if((b|0)<(d|0)){G[a+68>>2]=c+M(b,G[a+44>>2]);Hq(a,0);break Na}G[a+68>>2]=c}a=G[j+24>>2];d=G[a+40>>2];if(!d){break p}b=G[a+36>>2]+1|0;G[a+36>>2]=b;c=G[a+64>>2];if((b|0)<(d|0)){G[a+68>>2]=c+M(b,G[a+44>>2]);Hq(a,G[j+16>>2]);continue}break}G[a+68>>2]=c}a=Fa-4112|0;Fa=a;b=G[j+28>>2];if(G[b+44>>2]==1){v=a,x=Wc(0),G[v+12>>2]=x;c=rb(a+16|0,wl(rq(a+12|0)),4095);v=(Va(c)+c|0)-1|0,x=0,E[v|0]=x;d=G[b+64>>2];G[a>>2]=c;_a(d,89982,a);hb(68364,2,1,G[b+64>>2]);$a(G[b+64>>2])}Fa=a+4112|0;yl(G[j+28>>2],G[j+24>>2],G[j+20>>2],G[j+16>>2]);Fa=j+32|0;return 0}function hf(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){var q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,P=N(0),R=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0;x=Fa-29104|0;Fa=x;q=G[p>>2];a:{if(!(g|h)|(q|0)>0){break a}if(o){G[o>>2]=0}if((j|0)==2){cb(n,0,g)}if((yc(a,b,c,d,e,f,g,h,i>>31,x+29096|0,x+29088|0,x+28992|0,x+29064|0,x+29084|0,x+29080|0,x+29040|0,x+29032|0,x+29060|0,x+29048|0,x+29016|0,x+29076|0,x+29024|0,x+28864|0,p)|0)>0){q=G[p>>2];break a}G[x+29060>>2]=M(G[x+29060>>2],i);R=1;c=G[x+29080>>2];X=c;Y=c>>31;b:{if(G[x+29084>>2]!=16){break b}Gd(x+28992|0,x+29072|0,x+29056|0,x+29068|0,p);c=G[x+29068>>2];if((c|0)<=0){break b}if(c-1>>>0>=7){d=c&-8;q=0;while(1){R=R*10*10*10*10*10*10*10*10;q=q+8|0;if((d|0)!=(q|0)){continue}break}}c=c&7;if(!c){break b}q=0;while(1){R=R*10;q=q+1|0;if((c|0)!=(q|0)){continue}break}}c:{if(!(k|l)&(j|0)==1){break c}e=G[x+29028>>2];c=G[x+29024>>2];d=G[x+29084>>2];if(!e&(c|0)==1234554321&((d|0)%10|0)==1){break c}f=e-(c>>>0<32768)|0;if(((f|0)==-1&c-32768>>>0<4294901760|(f|0)!=-1)&(d|0)==21|(!e&c>>>0>255|(e|0)!=0)&(d|0)==11){break c}D=(d|0)==16?H[x+28864|0]==1?0:j:j}_=0-i|0;e=0;f=0;d:{while(1){d=g>>>0>>0&(h|0)<=(Y|0)|(h|0)<(Y|0)?g:X;c=d;j=c>>31;t=c;q=j;e:{if((i|0)>=0){c=G[x+29036>>2];j=c;c=G[x+29052>>2]+(c^-1)|0;r=G[x+29032>>2];u=r^-1;d=u+G[x+29048>>2]|0;c=Bu(d,d>>>0>>0?c+1|0:c,i,0);d=Ia;break e}r=G[x+29032>>2];j=G[x+29036>>2];c=Bu(r,j,_,0);d=Ia}w=c;u=G[x+29044>>2];c=G[x+29040>>2];v=Au(G[x+29016>>2],G[x+29020>>2],U,V);c=c+v|0;u=Ia+u|0;u=c>>>0>>0?u+1|0:u;B=c;v=r;r=G[x+29060>>2];c=(r|0)/(i|0)|0;v=Au(v,j,c,c>>31);j=B+v|0;c=Ia+u|0;u=j;j=j>>>0>>0?c+1|0:c;c=d;v=w+1|0;d=(d|0)<=(q|0)&t>>>0>w>>>0|(d|0)<(q|0);w=d?v:t;f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{c=G[x+29084>>2];switch(c-11|0){case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break h;case 5:break i;case 31:break k;case 10:break l;case 0:break m;case 30:break n;default:break o}}switch(c-81|0){case 0:break g;case 1:break j;default:break h}}t=x- -64|0;Uc(a,u,j,w,r,t,p);A=G[x+29024>>2];c=k;d=l;j=e+n|0;v=(e<<3)+m|0;z=L[x+29096>>3];C=L[x+29088>>3];q=z==1&C==0;p:{q:{if(!D){if(q){break q}r=0;if((w|0)<=0){break p}while(1){j=v+(r<<3)|0;s=+G[t+(r<<2)>>2]*z+C;r:{if(s<0){G[p>>2]=-11;d=0;c=0;break r}if(s>0x10000000000000000){G[p>>2]=-11;d=-1;c=-1;break r}if(O(s)<0x8000000000000000){d=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;c=~~s>>>0;break r}d=-2147483648;c=0}G[j>>2]=c;G[j+4>>2]=d;r=r+1|0;if((w|0)!=(r|0)){continue}break}break p}if(!q){if((w|0)<=0){break p}r=0;while(1){q=G[t+(r<<2)>>2];s:{if((q|0)==(A|0)){G[o>>2]=1;if((D|0)==1){q=v+(r<<3)|0;G[q>>2]=c;G[q+4>>2]=d;break s}E[j+r|0]=1;break s}s=+(q|0)*z+C;if(s<0){G[p>>2]=-11;q=v+(r<<3)|0;G[q>>2]=0;G[q+4>>2]=0;break s}if(s>0x10000000000000000){G[p>>2]=-11;q=v+(r<<3)|0;G[q>>2]=-1;G[q+4>>2]=-1;break s}q=v+(r<<3)|0;t:{if(s<0x10000000000000000&s>=0){y=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;u=~~s>>>0;break t}y=0;u=0}G[q>>2]=u;G[q+4>>2]=y}r=r+1|0;if((w|0)!=(r|0)){continue}break}break p}if((w|0)<=0){break p}if((D|0)!=1){r=0;while(1){c=G[t+(r<<2)>>2];u:{if((c|0)==(A|0)){G[o>>2]=1;E[j+r|0]=1;break u}if((c|0)<0){G[p>>2]=-11;c=v+(r<<3)|0;G[c>>2]=0;G[c+4>>2]=0;break u}d=v+(r<<3)|0;G[d>>2]=c;G[d+4>>2]=0}r=r+1|0;if((w|0)!=(r|0)){continue}break}break p}r=0;if((w|0)!=1){B=w&-2;u=0;while(1){y=v+(r<<3)|0;j=G[t+(r<<2)>>2];v:{if((j|0)!=(A|0)){q=0;if((j|0)>=0){break v}G[p>>2]=-11;j=0;q=0;break v}G[o>>2]=1;j=c;q=d}G[y>>2]=j;G[y+4>>2]=q;y=r|1;j=G[t+(y<<2)>>2];w:{if((j|0)!=(A|0)){q=0;if((j|0)>=0){break w}G[p>>2]=-11;j=0;q=0;break w}G[o>>2]=1;j=c;q=d}y=v+(y<<3)|0;G[y>>2]=j;G[y+4>>2]=q;r=r+2|0;u=u+2|0;if((B|0)!=(u|0)){continue}break}}if(!(w&1)){break p}j=G[t+(r<<2)>>2];x:{if((j|0)!=(A|0)){if((j|0)>=0){c=j;d=0;break x}G[p>>2]=-11;c=0;d=0;break x}G[o>>2]=1}j=v+(r<<3)|0;G[j>>2]=c;G[j+4>>2]=d;break p}if((w|0)<=0){break p}r=0;if((w|0)!=1){j=w&-2;u=0;while(1){d=v+(r<<3)|0;c=G[t+(r<<2)>>2];if((c|0)<0){G[p>>2]=-11;c=0}G[d>>2]=c;G[d+4>>2]=0;d=r|1;c=G[t+(d<<2)>>2];if((c|0)<0){G[p>>2]=-11;c=0}d=v+(d<<3)|0;G[d>>2]=c;G[d+4>>2]=0;r=r+2|0;u=u+2|0;if((j|0)!=(u|0)){continue}break}}if(!(w&1)){break p}d=v+(r<<3)|0;c=G[t+(r<<2)>>2];if((c|0)<0){G[p>>2]=-11;c=0}G[d>>2]=c;G[d+4>>2]=0}break f}t=x- -64|0;$d(a,u,j,w,r,t,p);A=H[x+29024|0];c=k;d=l;j=e+n|0;r=(e<<3)+m|0;z=L[x+29096>>3];C=L[x+29088>>3];q=z==1&C==0;y:{z:{if(!D){if(q){break z}u=0;if((w|0)<=0){break y}while(1){j=r+(u<<3)|0;A:{B:{s=+H[t+u|0]*z+C;if(s<0){G[p>>2]=-11;break B}if(s>0x10000000000000000){G[p>>2]=-11;d=-1;c=-1;break A}if(!(s<0x10000000000000000&s>=0)){break B}d=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;c=~~s>>>0;break A}d=0;c=0}G[j>>2]=c;G[j+4>>2]=d;u=u+1|0;if((w|0)!=(u|0)){continue}break}break y}if(!q){if((w|0)<=0){break y}u=0;while(1){q=H[t+u|0];C:{if((q|0)==(A|0)){G[o>>2]=1;if((D|0)==1){q=r+(u<<3)|0;G[q>>2]=c;G[q+4>>2]=d;break C}E[j+u|0]=1;break C}s=+(q>>>0)*z+C;if(s<0){G[p>>2]=-11;q=r+(u<<3)|0;G[q>>2]=0;G[q+4>>2]=0;break C}if(s>0x10000000000000000){G[p>>2]=-11;q=r+(u<<3)|0;G[q>>2]=-1;G[q+4>>2]=-1;break C}q=r+(u<<3)|0;D:{if(s<0x10000000000000000&s>=0){y=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;B=~~s>>>0;break D}y=0;B=0}G[q>>2]=B;G[q+4>>2]=y}u=u+1|0;if((w|0)!=(u|0)){continue}break}break y}if((w|0)<=0){break y}if((D|0)!=1){u=0;if((w|0)!=1){d=w&-2;v=0;while(1){c=H[t+u|0];E:{if((c|0)==(A|0)){G[o>>2]=1;E[j+u|0]=1;break E}q=r+(u<<3)|0;G[q>>2]=c;G[q+4>>2]=0}c=u|1;q=H[c+t|0];F:{if((q|0)!=(A|0)){c=r+(c<<3)|0;G[c>>2]=q;G[c+4>>2]=0;break F}G[o>>2]=1;E[c+j|0]=1}u=u+2|0;v=v+2|0;if((d|0)!=(v|0)){continue}break}}if(!(w&1)){break y}c=H[t+u|0];if((c|0)!=(A|0)){d=r+(u<<3)|0;G[d>>2]=c;G[d+4>>2]=0;break y}G[o>>2]=1;E[j+u|0]=1;break y}u=0;if((w|0)!=1){B=w&-2;v=0;while(1){y=r+(u<<3)|0;j=H[t+u|0];if((j|0)!=(A|0)){q=0}else{G[o>>2]=1;j=c;q=d}G[y>>2]=j;G[y+4>>2]=q;y=u|1;j=H[y+t|0];if((j|0)!=(A|0)){q=0}else{G[o>>2]=1;j=c;q=d}y=r+(y<<3)|0;G[y>>2]=j;G[y+4>>2]=q;u=u+2|0;v=v+2|0;if((B|0)!=(v|0)){continue}break}}if(!(w&1)){break y}j=H[t+u|0];G:{if((j|0)!=(A|0)){c=j;d=0;break G}G[o>>2]=1}j=r+(u<<3)|0;G[j>>2]=c;G[j+4>>2]=d;break y}if((w|0)<=0){break y}j=0;u=0;if(w-1>>>0>=3){c=w&-4;v=0;while(1){d=r+(u<<3)|0;G[d>>2]=H[t+u|0];G[d+4>>2]=0;d=u|1;q=r+(d<<3)|0;G[q>>2]=H[d+t|0];G[q+4>>2]=0;d=u|2;q=r+(d<<3)|0;G[q>>2]=H[d+t|0];G[q+4>>2]=0;d=u|3;q=r+(d<<3)|0;G[q>>2]=H[d+t|0];G[q+4>>2]=0;u=u+4|0;v=v+4|0;if((c|0)!=(v|0)){continue}break}}c=w&3;if(!c){break y}while(1){d=r+(u<<3)|0;G[d>>2]=H[t+u|0];G[d+4>>2]=0;u=u+1|0;j=j+1|0;if((c|0)!=(j|0)){continue}break}}break f}y=x- -64|0;Pe(a,u,j,w,r,y,p);q=I[x+29024>>1];c=k;d=l;B=e+n|0;A=(e<<3)+m|0;z=L[x+29096>>3];C=L[x+29088>>3];j=z==1&C==0;H:{I:{if(!D){if(j){break I}t=0;if((w|0)<=0){break H}while(1){j=A+(t<<3)|0;J:{K:{s=+F[y+(t<<1)>>1]*z+C;if(s<-0x8000000000000000){G[p>>2]=-11;break K}if(s>0x8000000000000000){G[p>>2]=-11;d=2147483647;c=-1;break J}if(!(O(s)<0x8000000000000000)){break K}d=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;c=~~s>>>0;break J}d=-2147483648;c=0}G[j>>2]=c;G[j+4>>2]=d;t=t+1|0;if((w|0)!=(t|0)){continue}break}break H}if(!j){if((w|0)<=0){break H}t=0;while(1){j=I[y+(t<<1)>>1];L:{if((j|0)==(q|0)){G[o>>2]=1;if((D|0)==1){j=A+(t<<3)|0;G[j>>2]=c;G[j+4>>2]=d;break L}E[t+B|0]=1;break L}s=+(j<<16>>16)*z+C;if(s<-0x8000000000000000){G[p>>2]=-11;j=A+(t<<3)|0;G[j>>2]=0;G[j+4>>2]=-2147483648;break L}if(s>0x8000000000000000){G[p>>2]=-11;j=A+(t<<3)|0;G[j>>2]=-1;G[j+4>>2]=2147483647;break L}j=A+(t<<3)|0;M:{if(O(s)<0x8000000000000000){r=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;u=~~s>>>0;break M}r=-2147483648;u=0}G[j>>2]=u;G[j+4>>2]=r}t=t+1|0;if((w|0)!=(t|0)){continue}break}break H}if((w|0)<=0){break H}if((D|0)!=1){t=0;if((w|0)!=1){W=w&-2;v=0;while(1){c=I[y+(t<<1)>>1];N:{if((c|0)==(q|0)){G[o>>2]=1;E[t+B|0]=1;break N}r=c<<16;j=r>>31;d=A+(t<<3)|0;G[d>>2]=r>>16;G[d+4>>2]=j}d=t|1;c=I[y+(d<<1)>>1];O:{if((c|0)!=(q|0)){u=c<<16;r=u>>31;d=A+(d<<3)|0;G[d>>2]=u>>16;G[d+4>>2]=r;break O}G[o>>2]=1;E[d+B|0]=1}t=t+2|0;v=v+2|0;if((W|0)!=(v|0)){continue}break}}if(!(w&1)){break H}c=I[y+(t<<1)>>1];if((c|0)!=(q|0)){j=c<<16;u=j>>31;d=A+(t<<3)|0;G[d>>2]=j>>16;G[d+4>>2]=u;break H}G[o>>2]=1;E[t+B|0]=1;break H}t=0;if((w|0)!=1){W=w&-2;v=0;while(1){B=A+(t<<3)|0;j=I[y+(t<<1)>>1];P:{if((j|0)!=(q|0)){r=j<<16;j=r>>31;r=r>>16;break P}G[o>>2]=1;j=d;r=c}G[B>>2]=r;G[B+4>>2]=j;B=t|1;j=I[y+(B<<1)>>1];Q:{if((j|0)!=(q|0)){u=j<<16;r=u>>31;u=u>>16;j=r;break Q}G[o>>2]=1;u=c;j=d}r=A+(B<<3)|0;G[r>>2]=u;G[r+4>>2]=j;t=t+2|0;v=v+2|0;if((W|0)!=(v|0)){continue}break}}if(!(w&1)){break H}j=I[y+(t<<1)>>1];R:{if((j|0)!=(q|0)){j=j<<16;u=j>>31;c=j>>16;d=u;break R}G[o>>2]=1}j=A+(t<<3)|0;G[j>>2]=c;G[j+4>>2]=d;break H}if((w|0)<=0){break H}t=0;if((w|0)!=1){j=w&-2;u=0;while(1){c=A+(t<<3)|0;d=F[y+(t<<1)>>1];S:{if((d|0)<0){G[p>>2]=-11;d=0;break S}d=d&65535}G[c>>2]=d;G[c+4>>2]=0;d=t|1;c=F[y+(d<<1)>>1];T:{if((c|0)>=0){c=c&65535;break T}G[p>>2]=-11;c=0}d=A+(d<<3)|0;G[d>>2]=c;G[d+4>>2]=0;t=t+2|0;u=u+2|0;if((j|0)!=(u|0)){continue}break}}if(!(w&1)){break H}c=A+(t<<3)|0;d=F[y+(t<<1)>>1];U:{if((d|0)>=0){d=d&65535;break U}G[p>>2]=-11;d=0}G[c>>2]=d;G[c+4>>2]=0}break f}q=x- -64|0;Uc(a,u,j,w,r,q,p);C=L[x+29096>>3];z=L[x+29088>>3];v=e+n|0;j=(e<<3)+m|0;r=0;u=0;V:{W:{if(!D){if(C==1&z==0){break W}if((w|0)<=0){break V}while(1){r=j+(u<<3)|0;X:{Y:{s=+K[q+(u<<2)>>2]*C+z;if(s<0){G[p>>2]=-11;break Y}if(s>0x10000000000000000){G[p>>2]=-11;d=-1;c=-1;break X}if(!(s<0x10000000000000000&s>=0)){break Y}d=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;c=~~s>>>0;break X}d=0;c=0}G[r>>2]=c;G[r+4>>2]=d;u=u+1|0;if((w|0)!=(u|0)){continue}break}break V}u=q+2|0;Z:{_:{if(!(C==1&z==0)){if((w|0)<=0){break V}if(!(z<0x10000000000000000&z>=0)){break _}d=O(z)>=1?~~(z>0?Q(S(z*2.3283064365386963e-10),4294967295):T((z-+(~~z>>>0>>>0))*2.3283064365386963e-10))>>>0:0;c=~~z>>>0;break Z}if((w|0)<=0){break V}while(1){$:{aa:{ba:{ca:{c=I[u>>1]&32640;switch(((c|0)==32640?1:!c<<1)|0){case 0:break aa;case 1:break ca;default:break ba}}G[o>>2]=1;if((D|0)==1){c=j+(r<<3)|0;G[c>>2]=k;G[c+4>>2]=l;break $}E[r+v|0]=1;break $}c=j+(r<<3)|0;G[c>>2]=0;G[c+4>>2]=0;break $}P=K[q+(r<<2)>>2];if(P>2]=-11;c=j+(r<<3)|0;G[c>>2]=0;G[c+4>>2]=0;break $}if(P>N(0x10000000000000000)){G[p>>2]=-11;c=j+(r<<3)|0;G[c>>2]=-1;G[c+4>>2]=-1;break $}c=j+(r<<3)|0;da:{if(P=N(0)){t=N(O(P))>=N(1)?~~(P>N(0)?N(Q(N(S(N(P*N(2.3283064365386963e-10)))),N(4294967296))):N(T(N(N(P-N(~~P>>>0>>>0))*N(2.3283064365386963e-10)))))>>>0:0;d=~~P>>>0;break da}t=0;d=0}G[c>>2]=d;G[c+4>>2]=t}u=u+4|0;r=r+1|0;if((w|0)!=(r|0)){continue}break}break V}d=0;c=0}while(1){ea:{fa:{ga:{ha:{t=I[u>>1]&32640;switch(((t|0)==32640?1:!t<<1)|0){case 0:break fa;case 1:break ha;default:break ga}}G[o>>2]=1;if((D|0)==1){t=j+(r<<3)|0;G[t>>2]=k;G[t+4>>2]=l;break ea}E[r+v|0]=1;break ea}if(z<0){G[p>>2]=-11;t=j+(r<<3)|0;G[t>>2]=0;G[t+4>>2]=0;break ea}if(z>0x10000000000000000){G[p>>2]=-11;t=j+(r<<3)|0;G[t>>2]=-1;G[t+4>>2]=-1;break ea}t=j+(r<<3)|0;G[t>>2]=c;G[t+4>>2]=d;break ea}s=+K[q+(r<<2)>>2]*C+z;if(s<0){G[p>>2]=-11;t=j+(r<<3)|0;G[t>>2]=0;G[t+4>>2]=0;break ea}if(s>0x10000000000000000){G[p>>2]=-11;t=j+(r<<3)|0;G[t>>2]=-1;G[t+4>>2]=-1;break ea}t=j+(r<<3)|0;ia:{if(s<0x10000000000000000&s>=0){y=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;B=~~s>>>0;break ia}y=0;B=0}G[t>>2]=B;G[t+4>>2]=y}u=u+4|0;r=r+1|0;if((w|0)!=(r|0)){continue}break}break V}if((w|0)<=0){break V}while(1){r=j+(u<<3)|0;ja:{ka:{P=K[q+(u<<2)>>2];if(P>2]=-11;break ka}if(P>N(0x10000000000000000)){G[p>>2]=-11;d=-1;c=-1;break ja}if(!(P=N(0))){break ka}d=N(O(P))>=N(1)?~~(P>N(0)?N(Q(N(S(N(P*N(2.3283064365386963e-10)))),N(4294967296))):N(T(N(N(P-N(~~P>>>0>>>0))*N(2.3283064365386963e-10)))))>>>0:0;c=~~P>>>0;break ja}d=0;c=0}G[r>>2]=c;G[r+4>>2]=d;u=u+1|0;if((w|0)!=(u|0)){continue}break}}break f}c=u;u=x- -64|0;Tc(a,c,j,w,r,u,p);C=L[x+29096>>3];z=L[x+29088>>3];v=e+n|0;q=(e<<3)+m|0;r=0;j=0;la:{ma:{if(!D){if(C==1&z==0){break ma}if((w|0)<=0){break la}while(1){na:{oa:{r=j<<3;s=L[r+u>>3]*C+z;if(s<0){G[p>>2]=-11;break oa}if(s>0x10000000000000000){G[p>>2]=-11;d=-1;c=-1;break na}if(!(s<0x10000000000000000&s>=0)){break oa}d=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;c=~~s>>>0;break na}d=0;c=0}r=q+r|0;G[r>>2]=c;G[r+4>>2]=d;j=j+1|0;if((w|0)!=(j|0)){continue}break}break la}j=u+6|0;pa:{qa:{if(!(C==1&z==0)){if((w|0)<=0){break la}if(!(z<0x10000000000000000&z>=0)){break qa}d=O(z)>=1?~~(z>0?Q(S(z*2.3283064365386963e-10),4294967295):T((z-+(~~z>>>0>>>0))*2.3283064365386963e-10))>>>0:0;c=~~z>>>0;break pa}if((w|0)<=0){break la}while(1){ra:{sa:{ta:{ua:{c=I[j>>1]&32752;switch(((c|0)==32752?1:!c<<1)|0){case 0:break sa;case 1:break ua;default:break ta}}G[o>>2]=1;if((D|0)==1){c=q+(r<<3)|0;G[c>>2]=k;G[c+4>>2]=l;break ra}E[r+v|0]=1;break ra}c=q+(r<<3)|0;G[c>>2]=0;G[c+4>>2]=0;break ra}c=r<<3;s=L[c+u>>3];if(s<0){G[p>>2]=-11;c=c+q|0;G[c>>2]=0;G[c+4>>2]=0;break ra}if(s>0x10000000000000000){G[p>>2]=-11;c=c+q|0;G[c>>2]=-1;G[c+4>>2]=-1;break ra}c=c+q|0;va:{if(s<0x10000000000000000&s>=0){t=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;d=~~s>>>0;break va}t=0;d=0}G[c>>2]=d;G[c+4>>2]=t}j=j+8|0;r=r+1|0;if((w|0)!=(r|0)){continue}break}break la}d=0;c=0}while(1){wa:{xa:{ya:{za:{t=I[j>>1]&32752;switch(((t|0)==32752?1:!t<<1)|0){case 0:break xa;case 1:break za;default:break ya}}G[o>>2]=1;if((D|0)==1){t=q+(r<<3)|0;G[t>>2]=k;G[t+4>>2]=l;break wa}E[r+v|0]=1;break wa}if(z<0){G[p>>2]=-11;t=q+(r<<3)|0;G[t>>2]=0;G[t+4>>2]=0;break wa}if(z>0x10000000000000000){G[p>>2]=-11;t=q+(r<<3)|0;G[t>>2]=-1;G[t+4>>2]=-1;break wa}t=q+(r<<3)|0;G[t>>2]=c;G[t+4>>2]=d;break wa}t=r<<3;s=L[t+u>>3]*C+z;if(s<0){G[p>>2]=-11;t=q+t|0;G[t>>2]=0;G[t+4>>2]=0;break wa}if(s>0x10000000000000000){G[p>>2]=-11;t=q+(r<<3)|0;G[t>>2]=-1;G[t+4>>2]=-1;break wa}t=q+(r<<3)|0;Aa:{if(s<0x10000000000000000&s>=0){y=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;B=~~s>>>0;break Aa}y=0;B=0}G[t>>2]=B;G[t+4>>2]=y}j=j+8|0;r=r+1|0;if((w|0)!=(r|0)){continue}break}break la}if((w|0)<=0){break la}while(1){Ba:{Ca:{r=j<<3;s=L[r+u>>3];if(s<0){G[p>>2]=-11;break Ca}if(s>0x10000000000000000){G[p>>2]=-11;d=-1;c=-1;break Ba}if(!(s<0x10000000000000000&s>=0)){break Ca}d=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;c=~~s>>>0;break Ba}d=0;c=0}r=q+r|0;G[r>>2]=c;G[r+4>>2]=d;j=j+1|0;if((w|0)!=(j|0)){continue}break}}break f}Jb(a,u,j,0,p);c=G[x+29060>>2];d=G[x+29064>>2];Da:{if((c|0)==(d|0)){c=M(c,w);ic(a,c,c>>31,x- -64|0,p);break Da}Rd(a,d,w,c-d|0,x- -64|0,p)}u=x- -64|0;C=L[x+29096>>3];$=L[x+29088>>3];aa=G[x+29064>>2];ba=e+n|0;y=(e<<3)+m|0;A=0;v=Fa-112|0;Fa=v;W=x+28864|0;ca=Va(W);if((w|0)>0){while(1){Ea:{j=u+aa|0;Z=H[j|0];E[j|0]=0;c=u;Fa:{Ga:{if(H[W|0]==1){break Ga}if(fb(W,u,ca)){break Ga}c=j;if(!D){break Fa}G[o>>2]=1;if((D|0)==1){c=(A<<3)+y|0;G[c>>2]=k;G[c+4>>2]=l;c=j;break Fa}E[A+ba|0]=1;break Fa}while(1){d=H[c|0];if((d|0)==32){c=c+1|0;continue}break}t=1;Ha:{switch(d-43|0){case 0:case 2:while(1){q=H[c+1|0];c=c+1|0;if((q|0)==32){continue}break};t=(d|0)==45?-1:1;d=q;break;default:break Ha}}z=0;if((d-48&255)>>>0<10){while(1){s=z*10+ +(d<<24>>24);q=c;while(1){d=H[q+1|0];c=q+1|0;q=c;if((d|0)==32){continue}break}z=s+-48;if((d-48&255)>>>0<=9){continue}break}}s=R;Ia:{Ja:{switch(d-44|0){case 0:case 2:break Ja;default:break Ia}}q=c;while(1){d=H[q+1|0];c=q+1|0;q=c;if((d|0)==32){continue}break}s=1;if((d-48&255)>>>0>=10){break Ia}while(1){z=z*10+ +(d<<24>>24)+-48;q=c;while(1){d=H[q+1|0];c=q+1|0;q=c;if((d|0)==32){continue}break}s=s*10;if((d-48&255)>>>0<=9){continue}break}}Ka:{if((d&254)!=68){B=1;q=0;break Ka}while(1){B=1;q=c;c=c+1|0;d=H[q+1|0];if((d|0)==32){continue}break}La:{switch(d-43|0){case 0:case 2:q=q+2|0;while(1){c=q;q=c+1|0;r=H[c|0];if((r|0)==32){continue}break};B=(d|0)==45?-1:1;d=r;break;default:break La}}q=0;if((d-48&255)>>>0>=10){break Ka}while(1){r=d;da=M(q,10)-48|0;q=c;while(1){d=H[q+1|0];c=q+1|0;q=c;if((d|0)==32){continue}break}q=da+(r<<24>>24)|0;if((d-48&255)>>>0<=9){continue}break}}if(d){G[v+48>>2]=H[23477]|H[23478]<<8|(H[23479]<<16|H[23480]<<24);c=H[23473]|H[23474]<<8|(H[23475]<<16|H[23476]<<24);G[v+40>>2]=H[23469]|H[23470]<<8|(H[23471]<<16|H[23472]<<24);G[v+44>>2]=c;c=H[23465]|H[23466]<<8|(H[23467]<<16|H[23468]<<24);G[v+32>>2]=H[23461]|H[23462]<<8|(H[23463]<<16|H[23464]<<24);G[v+36>>2]=c;c=H[23457]|H[23458]<<8|(H[23459]<<16|H[23460]<<24);G[v+24>>2]=H[23453]|H[23454]<<8|(H[23455]<<16|H[23456]<<24);G[v+28>>2]=c;c=H[23449]|H[23450]<<8|(H[23451]<<16|H[23452]<<24);G[v+16>>2]=H[23445]|H[23446]<<8|(H[23447]<<16|H[23448]<<24);G[v+20>>2]=c;c=v+16|0;Ua(c);G[v>>2]=u;Ya(c,81,43022,v);Ua(c);E[j|0]=Z;G[p>>2]=409;break Ea}s=z*+(t|0)/s*$b(10,+(M(q,B)|0))*C+$;Ma:{if(s<0){G[p>>2]=-11;d=(A<<3)+y|0;G[d>>2]=0;G[d+4>>2]=0;break Ma}if(s>0x10000000000000000){G[p>>2]=-11;d=(A<<3)+y|0;G[d>>2]=-1;G[d+4>>2]=-1;break Ma}d=(A<<3)+y|0;Na:{if(s<0x10000000000000000&s>=0){u=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;q=~~s>>>0;break Na}u=0;q=0}G[d>>2]=q;G[d+4>>2]=u}}u=c;E[j|0]=Z;A=A+1|0;if((w|0)!=(A|0)){continue}}break}}Fa=v+112|0;break f}G[x>>2]=b;G[x+4>>2]=x+28992;a=x+28896|0;Ya(a,81,8924,x);Ua(a);q=311;if(G[x+29076>>2]==1){break d}q=312;break d}t=(e<<3)+m|0;Tc(a,u,j,w,r,t,p);u=G[x+29024>>2];A=G[x+29028>>2];c=k;d=l;j=e+n|0;z=L[x+29096>>3];C=L[x+29088>>3];q=z==1&C==0x8000000000000000;Oa:{Pa:{if(!D){if(q){if((w|0)<=0){break Oa}u=0;v=0;if(w-1>>>0>=3){d=w&-4;j=0;while(1){c=v<<3;q=c+t|0;r=c+t|0;A=G[r>>2];r=G[r+4>>2]^-2147483648;G[q>>2]=A;G[q+4>>2]=r;q=c|8;r=q+t|0;q=q+t|0;A=G[q>>2];q=G[q+4>>2]^-2147483648;G[r>>2]=A;G[r+4>>2]=q;q=c|16;r=q+t|0;q=q+t|0;A=G[q>>2];q=G[q+4>>2]^-2147483648;G[r>>2]=A;G[r+4>>2]=q;c=c|24;q=c+t|0;c=c+t|0;r=G[c>>2];c=G[c+4>>2]^-2147483648;G[q>>2]=r;G[q+4>>2]=c;v=v+4|0;j=j+4|0;if((d|0)!=(j|0)){continue}break}}c=w&3;if(!c){break Oa}while(1){d=v<<3;j=d+t|0;d=d+t|0;q=G[d>>2];d=G[d+4>>2]^-2147483648;G[j>>2]=q;G[j+4>>2]=d;v=v+1|0;u=u+1|0;if((c|0)!=(u|0)){continue}break}break Oa}if(z==1&C==0){break Pa}v=0;if((w|0)<=0){break Oa}while(1){Qa:{Ra:{j=v<<3;c=j+t|0;s=(+J[c>>2]+ +G[c+4>>2]*4294967296)*z+C;if(s<0){G[p>>2]=-11;break Ra}if(s>0x10000000000000000){G[p>>2]=-11;d=-1;c=-1;break Qa}if(!(s<0x10000000000000000&s>=0)){break Ra}d=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;c=~~s>>>0;break Qa}d=0;c=0}j=j+t|0;G[j>>2]=c;G[j+4>>2]=d;v=v+1|0;if((w|0)!=(v|0)){continue}break}break Oa}Sa:{Ta:{Ua:{if(q){if((w|0)<=0){break Oa}if((D|0)==1){break Sa}v=0;if((w|0)!=1){c=w&-2;r=0;while(1){d=v<<3;q=d+t|0;y=G[q>>2];q=G[q+4>>2];Va:{if((y|0)==(u|0)&(q|0)==(A|0)){G[o>>2]=1;E[j+v|0]=1;break Va}d=d+t|0;G[d>>2]=y;G[d+4>>2]=q^-2147483648}d=v|1;q=d<<3;y=q+t|0;B=G[y>>2];y=G[y+4>>2];Wa:{if((B|0)!=(u|0)|(y|0)!=(A|0)){d=q+t|0;G[d>>2]=B;G[d+4>>2]=y^-2147483648;break Wa}G[o>>2]=1;E[d+j|0]=1}v=v+2|0;r=r+2|0;if((c|0)!=(r|0)){continue}break}}if(!(w&1)){break Oa}c=v<<3;d=c+t|0;q=G[d>>2];d=G[d+4>>2];if((q|0)==(u|0)&(d|0)==(A|0)){break Ua}c=c+t|0;G[c>>2]=q;G[c+4>>2]=d^-2147483648;break Oa}if(z==1&C==0){break Ta}if((w|0)<=0){break Oa}v=0;while(1){q=v<<3;r=q+t|0;y=G[r>>2];r=G[r+4>>2];Xa:{if((y|0)==(u|0)&(r|0)==(A|0)){G[o>>2]=1;if((D|0)==1){q=q+t|0;G[q>>2]=c;G[q+4>>2]=d;break Xa}E[j+v|0]=1;break Xa}s=(+(y>>>0)+ +(r|0)*4294967296)*z+C;if(s<0){G[p>>2]=-11;q=q+t|0;G[q>>2]=0;G[q+4>>2]=0;break Xa}if(s>0x10000000000000000){G[p>>2]=-11;q=q+t|0;G[q>>2]=-1;G[q+4>>2]=-1;break Xa}q=q+t|0;Ya:{if(s<0x10000000000000000&s>=0){y=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;r=~~s>>>0;break Ya}y=0;r=0}G[q>>2]=r;G[q+4>>2]=y}v=v+1|0;if((w|0)!=(v|0)){continue}break}break Oa}G[o>>2]=1;E[j+v|0]=1;break Oa}if((w|0)<=0){break Oa}v=0;while(1){q=v<<3;r=q+t|0;y=G[r>>2];r=G[r+4>>2];Za:{if((y|0)==(u|0)&(r|0)==(A|0)){G[o>>2]=1;if((D|0)==1){q=q+t|0;G[q>>2]=c;G[q+4>>2]=d;break Za}E[j+v|0]=1;break Za}if((r|0)<0){G[p>>2]=-11;q=q+t|0;G[q>>2]=0;G[q+4>>2]=0;break Za}q=q+t|0;G[q>>2]=y;G[q+4>>2]=r}v=v+1|0;if((w|0)!=(v|0)){continue}break}break Oa}v=0;if((w|0)!=1){y=w&-2;r=0;while(1){B=v<<3;q=B+t|0;j=G[q>>2];q=G[q+4>>2];_a:{if((j|0)!=(u|0)|(q|0)!=(A|0)){q=q^-2147483648;break _a}G[o>>2]=1;j=c;q=d}B=t+B|0;G[B>>2]=j;G[B+4>>2]=q;B=(v|1)<<3;q=B+t|0;j=G[q>>2];q=G[q+4>>2];$a:{if((j|0)!=(u|0)|(q|0)!=(A|0)){q=q^-2147483648;break $a}G[o>>2]=1;j=c;q=d}B=t+B|0;G[B>>2]=j;G[B+4>>2]=q;v=v+2|0;r=r+2|0;if((y|0)!=(r|0)){continue}break}}if(!(w&1)){break Oa}q=t+(v<<3)|0;j=G[q>>2];q=G[q+4>>2];ab:{if((j|0)!=(u|0)|(q|0)!=(A|0)){c=j;d=q^-2147483648;break ab}G[o>>2]=1}j=t+(v<<3)|0;G[j>>2]=c;G[j+4>>2]=d;break Oa}if((w|0)<=0){break Oa}v=0;if((w|0)!=1){j=w&-2;r=0;while(1){q=v<<3;c=q+t|0;d=G[c+4>>2];c=G[c>>2];q=q+t|0;if((d|0)<0){G[p>>2]=-11;d=0;c=0}G[q>>2]=c;G[q+4>>2]=d;q=(v|1)<<3;c=q+t|0;d=G[c+4>>2];c=G[c>>2];q=q+t|0;if((d|0)<0){G[p>>2]=-11;d=0;c=0}G[q>>2]=c;G[q+4>>2]=d;v=v+2|0;r=r+2|0;if((j|0)!=(r|0)){continue}break}}if(!(w&1)){break Oa}j=v<<3;c=j+t|0;d=G[c+4>>2];c=G[c>>2];j=j+t|0;if((d|0)<0){G[p>>2]=-11;d=0;c=0}G[j>>2]=c;G[j+4>>2]=d}}q=G[p>>2];if((q|0)>0){s=+(e>>>0)+ +(f|0)*4294967296;R=s+1;s=s+ +(w|0);bb:{if(G[x+29076>>2]>0){G[x+32>>2]=b;L[x+24>>3]=s;L[x+16>>3]=R;Ya(x+28896|0,81,46757,x+16|0);break bb}L[x+56>>3]=s;L[x+48>>3]=R;Ya(x+28896|0,81,46698,x+48|0)}Ua(x+28896|0);q=G[p>>2];break a}c=w;u=c>>31;j=c;h=h-((g>>>0>>0)+u|0)|0;g=g-c|0;if(h|g){c=M(i,w);q=c;d=c+G[x+29032>>2]|0;c=G[x+29036>>2]+(c>>31)|0;c=d>>>0>>0?c+1|0:c;G[x+29032>>2]=d;q=c;G[x+29036>>2]=c;c=e+j|0;j=f+u|0;j=c>>>0>>0?j+1|0:j;e=c;f=j;u=G[x+29052>>2];c=u;w=G[x+29048>>2];if((q|0)>=(c|0)&d>>>0>=w>>>0|(c|0)<(q|0)){j=Bu(d,q,w,u);c=U+j|0;r=Ia;V=V+r|0;V=c>>>0>>0?V+1|0:V;U=c;c=Au(j,r,w,u);G[x+29032>>2]=d-c;G[x+29036>>2]=q-(Ia+(c>>>0>d>>>0)|0);continue}if((q|0)>0|(q|0)>=0){continue}j=U;U=Bu(d^-1,q^-1,w,u)+1|0;c=Ia;c=U?c:c+1|0;r=U;U=j-r|0;V=V-((j>>>0>>0)+c|0)|0;c=Au(r,c,w,u)+d|0;j=q+Ia|0;G[x+29032>>2]=c;G[x+29036>>2]=c>>>0>>0?j+1|0:j;continue}break}if((q|0)!=-11){break a}Ua(44994);q=412}G[p>>2]=q}Fa=x+29104|0;return q}function Vq(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,I=0,K=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0;c=Fa-82176|0;Fa=c;G[321982]=-1571644103;G[321983]=1066524486;G[321985]=5;G[47589]=1;r=G[29763];G[321435]=r;G[47590]=0;E[1287936]=0;x=.01;F=50;a:{b:{c:{d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{while(1){B=d;d=1;n:{o:{p:{q:{r:{p=of(a,b,36679);switch(p-100|0){case 17:continue;case 15:break n;case 16:break o;case 11:break p;case 5:break q;case 0:break r;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 10:case 12:case 13:case 14:break i;default:break m}}E[1287936]=1;d=B;continue}d=nc(G[321433],c+1252|0,0);F=G[321433];if(J[c+1252>>2]>>0){break l}F=(d|0)>1?d:1;d=B;continue}p=nc(G[321433],c+1252|0,0);G[321985]=p;d=G[321433];if(J[c+1252>>2]>>0){break k}d=B;if((p|0)>=0){continue}G[321985]=0;continue}x=vb(G[321433],c+1252|0);d=G[321433];if(J[c+1252>>2]>>0){break j}d=B;if(!(x<0)){continue}x=0;continue}p=ac(G[321433],49010);G[321435]=p;d=B;if(p){continue}break}G[c+1248>>2]=G[321433];_a(0,80991,c+1248|0);break a}if((p|0)!=-1){break i}d=a;a=G[47589];if((d-a|0)<=1){break h}a=(a<<2)+b|0;p=Za(c+1536|0,G[a>>2]);m=Za(c+1280|0,G[a+4>>2]);Lf(p,1,0);g=Fa-480|0;Fa=g;s:{l=ac(p,13287);if(l){G[322016]=0;G[321992]=0;G[322070]=0;G[322071]=0;G[322072]=0;G[322073]=0;G[322074]=0;G[322075]=0;G[322076]=0;G[322077]=0;G[322078]=0;G[322079]=0;G[322080]=0;E[1287984]=0;E[1288080]=0;E[1288160]=0;E[1288336]=0;E[1288416]=0;E[1288496]=0;E[1288656]=0;E[1288576]=0;E[1288736]=0;E[1288816]=0;E[1288896]=0;E[1288976]=0;E[1289056]=0;if(!vc(g+224|0,256,l)){break s}t:while(1){b=g+224|0;s=b+Va(b)|0;while(1){a=b;f=H[b|0];if((f|0)==32){b=a+1|0;if(a>>>0>>0){continue}}break}d=a;while(1){b=f&255;if(!(!((b|0)==32|(b|0)==61)&d>>>0>>0)){b=d;while(1){f=(f&255)-32|0;if(!(f>>>0>29|!(1<>>0>=s>>>0)){f=H[b+1|0];b=b+1|0;continue}break}E[d|0]=0;f=(H[b|0]==39)+b|0;while(1){d=H[f|0]-10|0;if(!(f>>>0>=s>>>0|(1<>>0<=29:0))){f=f+1|0;continue}break}E[f|0]=0;u:{v:{if(!Xa(a,41234)){f=1287968;a=1287984;break v}if(!Xa(a,40826)){f=1288064;a=1288080;break v}if(!Xa(a,40896)){f=1288280;a=1288160;break v}if(!Xa(a,41174)){f=1288284;a=1288336;break v}if(!Xa(a,40778)){f=1288288;a=1288416;break v}if(!Xa(a,41149)){f=1288292;a=1288496;break v}if(!Xa(a,40759)){f=1288296;a=1288576;break v}if(!Xa(a,41180)){f=1288300;a=1288656;break v}if(!Xa(a,40784)){f=1288304;a=1288736;break v}if(!Xa(a,41155)){f=1288308;a=1288816;break v}if(!Xa(a,40765)){f=1288312;a=1288896;break v}if(!Xa(a,34948)){f=1288316;a=1288976;break v}if(Xa(a,32863)){break u}f=1288320;a=1289056}G[f>>2]=1;Za(a,b)}if(vc(g+224|0,256,l)){continue t}break s}f=H[d+1|0];d=d+1|0;continue}}}G[g>>2]=p;_a(G[321435],80820,g);break a}if(H[1287936]){yb(40077);if(G[321992]){G[g+208>>2]=1287984;kb(76419,g+208|0)}if(G[322016]){G[g+192>>2]=1288080;kb(76387,g+192|0)}if(G[322070]){G[g+176>>2]=1288160;kb(76403,g+176|0)}if(G[322071]){G[g+160>>2]=1288336;kb(76617,g+160|0)}if(G[322072]){G[g+144>>2]=1288416;kb(76553,g+144|0)}if(G[322073]){G[g+128>>2]=1288496;kb(76585,g+128|0)}if(G[322074]){G[g+112>>2]=1288576;kb(76521,g+112|0)}if(G[322075]){G[g+96>>2]=1288656;kb(76633,g+96|0)}if(G[322076]){G[g+80>>2]=1288736;kb(76569,g+80|0)}if(G[322077]){G[g+64>>2]=1288816;kb(76601,g- -64|0)}if(G[322078]){G[g+48>>2]=1288896;kb(76537,g+48|0)}if(G[322079]){G[g+32>>2]=1288976;kb(76435,g+32|0)}if(G[322080]){G[g+16>>2]=1289056;kb(76260,g+16|0)}id()}Fa=g+480|0;a=ac(m,49010);G[321986]=a;if(!a){break g}if(H[1287936]){yb(44716);yb(63237);yb(51058);$a(r)}s=G[321985];a=(s<<2)+4|0;ga=1287948,ha=ab(a),G[ga>>2]=ha;ga=1287952,ha=ab(a),G[ga>>2]=ha;w:{if((s|0)>0){q=s&-4;t=s&3;i=s-1|0;v=(s<<3)+8|0;b=0;while(1){g=ab(v);d=b<<2;G[d+G[321987]>>2]=g;g=ab(v);G[d+G[321988]>>2]=g;g=G[d+G[321988]>>2];m=G[d+G[321987]>>2];d=0;f=0;if(i>>>0>=3){while(1){l=d<<3;j=l+m|0;G[j>>2]=0;G[j+4>>2]=0;j=g+l|0;G[j>>2]=0;G[j+4>>2]=0;j=l|8;w=j+m|0;G[w>>2]=0;G[w+4>>2]=0;j=g+j|0;G[j>>2]=0;G[j+4>>2]=0;j=l|16;w=j+m|0;G[w>>2]=0;G[w+4>>2]=0;j=g+j|0;G[j>>2]=0;G[j+4>>2]=0;l=l|24;j=l+m|0;G[j>>2]=0;G[j+4>>2]=0;l=g+l|0;G[l>>2]=0;G[l+4>>2]=0;d=d+4|0;f=f+4|0;if((q|0)!=(f|0)){continue}break}}f=0;if(t){while(1){l=d<<3;j=l+m|0;G[j>>2]=0;G[j+4>>2]=0;l=g+l|0;G[l>>2]=0;G[l+4>>2]=0;d=d+1|0;f=f+1|0;if((t|0)!=(f|0)){continue}break}}b=b+1|0;if((s|0)!=(b|0)){continue}break}l=0;ga=1287956,ha=ab(a),G[ga>>2]=ha;ga=1287960,ha=ab(a),G[ga>>2]=ha;if((s|0)<=0){break w}q=s&-4;t=s&3;v=(s<<3)+8|0;while(1){f=0;b=ab(v);a=l<<2;G[a+G[321989]>>2]=b;b=ab(v);G[a+G[321990]>>2]=b;b=G[a+G[321990]>>2];g=G[a+G[321989]>>2];d=0;a=0;if(i>>>0>=3){while(1){m=d<<3;j=m+g|0;G[j>>2]=0;G[j+4>>2]=0;j=b+m|0;G[j>>2]=0;G[j+4>>2]=0;j=m|8;w=j+g|0;G[w>>2]=0;G[w+4>>2]=0;j=b+j|0;G[j>>2]=0;G[j+4>>2]=0;j=m|16;w=j+g|0;G[w>>2]=0;G[w+4>>2]=0;j=b+j|0;G[j>>2]=0;G[j+4>>2]=0;m=m|24;j=m+g|0;G[j>>2]=0;G[j+4>>2]=0;m=b+m|0;G[m>>2]=0;G[m+4>>2]=0;d=d+4|0;a=a+4|0;if((q|0)!=(a|0)){continue}break}}if(t){while(1){a=d<<3;m=a+g|0;G[m>>2]=0;G[m+4>>2]=0;a=a+b|0;G[a>>2]=0;G[a+4>>2]=0;d=d+1|0;f=f+1|0;if((t|0)!=(f|0)){continue}break}}l=l+1|0;if((s|0)!=(l|0)){continue}break}break w}ga=1287956,ha=ab(a),G[ga>>2]=ha;ga=1287960,ha=ab(a),G[ga>>2]=ha}if(H[1287936]){yb(44488);$a(r);s=G[321985]}l=M(s,s);w=l<<1;a=w|1;b=a<<2;m=ab(b);t=ab(b);if(l){b=w>>>0>1?w:1;a=a<<3;d=0;while(1){g=d<<2;ga=g+m|0,ha=ab(16),G[ga>>2]=ha;ga=g+t|0,ha=ab(a),G[ga>>2]=ha;d=d+1|0;if((b|0)!=(d|0)){continue}break}}g=ac(p,13287);if(!g){break f}E[c+1824|0]=0;a=0;while(1){if(vc(c+81824|0,256,g)){b=(Va(c+81824|0)+c|0)+81823|0;if(H[b|0]==10){E[b|0]=0}b=(Va(c+81824|0)+c|0)+81823|0;if(H[b|0]==13){E[b|0]=0}d=Va(c+1824|0);b=Va(c+81824|0);x:{if((b|0)>0){bb(d+(c+1824|0)|0,c+81824|0,b);if(b>>>0>79){break x}}cb(c+1824+(b+d)|0,32,80-b|0)}E[(c+d|0)+1904|0]=0;a=a+1|0;if((a|0)!=1e3){continue}}break}if(H[1287936]){yb(86179);$a(r);b=Va(c+1824|0);a=0;while(1){d=0;cb(c+82080|0,0,80);p=M(a,80);while(1){y:{i=d+p|0;f=(i|0)>(b|0);if(f){break y}E[(c+82080|0)+d|0]=H[i+(c+1824|0)|0];i=d|1;v=i+p|0;f=(v|0)>(b|0);if(f){break y}E[i+(c+82080|0)|0]=H[v+(c+1824|0)|0];d=d+2|0;if((d|0)!=80){continue}}break}E[c+82160|0]=0;d=80;while(1){z:{p=(c+82080|0)+d|0;if((H[p|0]|32)!=32){break z}E[p|0]=0;p=(c+d|0)+82079|0;if((H[p|0]|32)!=32){break z}E[p|0]=0;p=d-2|0;i=p+(c+82080|0)|0;if((H[i|0]|32)!=32){break z}E[i|0]=0;d=d-3|0;if(p){continue}}break}a=a+1|0;if(H[c+82080|0]){G[c+1184>>2]=a;G[c+1188>>2]=c+82080;kb(69623,c+1184|0)}if(!f){continue}break}id();$a(r)}a=rd(c+1824|0);G[321991]=a;if(!a){break e}Wg(a,0);if(H[1287936]){yb(73546);$a(r)}G[c+1264>>2]=0;cc(G[321991],.5,.5,c+1808|0,c+1800|0);Bd(G[321991],L[c+1808>>3],L[c+1800>>3],c+82080|0,c+1816|0,c+1264|0);h=L[c+82080>>3]+-.5;L[161033]=h;L[161034]=L[c+1816>>3]+-.5;if(H[1287936]){L[c+1168>>3]=h;gb(72339,c+1168|0);L[c+1152>>3]=L[161034];gb(90238,c+1152|0);$a(r)}Hb(g);p=0;d=G[321991];if(G[d+3260>>2]==31){G[321992]=1;L[c+1136>>3]=L[d+760>>3];Eb(1287984,19360,c+1136|0);G[322016]=1;L[c+1120>>3]=L[G[321991]+768>>3];Eb(1288080,19360,c+1120|0);G[321992]=1;L[c+1104>>3]=L[G[321991]+48>>3];Eb(1288160,19360,c+1104|0);d=G[321991]}h=(L[d+136>>3]+1)*.5;L[c+1824>>3]=h;e=(L[d+144>>3]+1)*.5;L[c+81824>>3]=e;cc(d,h,e,c+1808|0,c+1800|0);o=sb(1287984);a=c+1264|0;b=c+1256|0;cc(G[321991],L[c+1824>>3]+1,L[c+81824>>3],a,b);k=L[c+1264>>3];h=L[160991];n=L[c+1256>>3]*h;e=eb(n);y=k*h;P=ib(y);C=L[c+1808>>3];Q=h*L[c+1800>>3];k=eb(Q);C=C*h;$=ib(C);y=eb(y);C=eb(C);h=Sc(ib(Q)*ib(n)+(C*k*(y*e)+$*k*(P*e)))/h;L[161030]=o<0?-h:h;o=sb(1288080);cc(G[321991],L[c+1824>>3],L[c+81824>>3]+1,a,b);k=L[c+1264>>3];h=L[160991];n=L[c+1256>>3]*h;e=eb(n);y=k*h;P=ib(y);C=L[c+1808>>3];Q=h*L[c+1800>>3];k=eb(Q);C=C*h;$=ib(C);y=eb(y);C=eb(C);h=Sc(ib(Q)*ib(n)+(C*k*(y*e)+$*k*(P*e)))/h;L[161031]=o<0?-h:h;a=G[321991];h=L[a+144>>3];e=L[a+136>>3];A:{if(O(e)<2147483648){a=~~e;break A}a=-2147483648}d=h<+(a|0);ea=1;if(O(h)<2147483648){b=~~h}else{b=-2147483648}h=+((d?b:a)|0)*.125;B:{if(O(h)<2147483648){a=~~h;break B}a=-2147483648}v=(a|0)>1?a:1;h=+(a|0)/20;C:{if(O(h)<2147483648){a=~~h;break C}a=-2147483648}X=(a|0)>1?a:1;u=w>>>0>1?w:1;Y=u&2147483644;R=u&3;fa=u-1|0;I=u<<3;Z=l-1|0;_=t+(Z<<2)|0;Wh();aa=c+1040|0;S=c+1048|0;T=c+1056|0;U=c+1064|0;D=c+1072|0;N=c+1080|0;D:{while(1){E:{if(!l){break E}a=0;d=0;f=0;if(fa>>>0>=3){while(1){b=d<<2;g=G[b+m>>2];G[g>>2]=0;G[g+4>>2]=0;cb(G[b+t>>2],0,I);g=b|4;i=G[g+m>>2];G[i>>2]=0;G[i+4>>2]=0;cb(G[g+t>>2],0,I);g=b|8;i=G[g+m>>2];G[i>>2]=0;G[i+4>>2]=0;cb(G[g+t>>2],0,I);b=b|12;g=G[b+m>>2];G[g>>2]=0;G[g+4>>2]=0;cb(G[b+t>>2],0,I);d=d+4|0;f=f+4|0;if((Y|0)!=(f|0)){continue}break}}if(!R){break E}while(1){b=d<<2;g=G[b+m>>2];G[g>>2]=0;G[g+4>>2]=0;cb(G[b+t>>2],0,I);d=d+1|0;a=a+1|0;if((R|0)!=(a|0)){continue}break}}if(H[1287936]){G[c+1088>>2]=p;kb(78391,c+1088|0);$a(r)}q=0;e=0;d=G[321991];if(L[d+136>>3]+1>0){while(1){if(L[d+144>>3]+1>0){h=e+-.5;j=0;e=0;while(1){e=e+-.5;cc(d,h,e,c+82080|0,c+1816|0);G[c+1276>>2]=0;Bd(G[322064],L[c+82080>>3],L[c+1816>>3],c+1824|0,c+81824|0,c+1276|0);k=L[c+1824>>3];o=h-k;if(H[1287936]){L[aa>>3]=L[c+82080>>3];L[S>>3]=L[c+1816>>3];L[T>>3]=k;L[U>>3]=L[c+81824>>3];L[D>>3]=o;G[N>>2]=G[c+1276>>2];L[c+1024>>3]=h;L[c+1032>>3]=e;gb(88178,c+1024|0);$a(r)}F:{if(!(G[c+1276>>2]?B:1)){break F}g=G[321985];if((g|0)<=0){break F}ba=g&-2;ca=g&1;i=0;while(1){da=M(i,s);n=$b(h,+(i|0));f=0;while(1){k=$b(e,+(f|0));a=f+da<<2;b=G[a+m>>2];L[b>>3]=n*k*o+L[b>>3];z=G[a+t>>2];b=0;while(1){A=M(b,s);k=$b(h,+(b+i|0));d=0;a=0;if((g|0)!=1){while(1){K=z+(d+A<<3)|0;ga=K,ia=k*$b(e,+(d+f|0))+L[K>>3],L[ga>>3]=ia;K=d|1;V=z+(K+A<<3)|0;ga=V,ia=k*$b(e,+(f+K|0))+L[V>>3],L[ga>>3]=ia;d=d+2|0;a=a+2|0;if((ba|0)!=(a|0)){continue}break}}if(ca){a=z+(d+A<<3)|0;ga=a,ia=k*$b(e,+(d+f|0))+L[a>>3],L[ga>>3]=ia}b=b+1|0;if((g|0)!=(b|0)){continue}break}f=f+1|0;if((g|0)!=(f|0)){continue}break}i=i+1|0;if((g|0)!=(i|0)){continue}break}}j=j+v|0;e=+(j|0);d=G[321991];if(e>3]+1){continue}break}}q=q+v|0;e=+(q|0);if(e>3]+1){continue}break}}e=0;q=0;if(H[1287936]){G[c+1008>>2]=p;kb(78297,c+1008|0);$a(r);d=G[321991]}if(L[d+136>>3]+1>0){while(1){if(L[d+144>>3]+1>0){k=e+-.5;j=0;e=0;while(1){h=e+-.5;cc(d,k,h,c+82080|0,c+1816|0);G[c+1276>>2]=0;Bd(G[322064],L[c+82080>>3],L[c+1816>>3],c+1824|0,c+81824|0,c+1276|0);o=L[c+81824>>3];e=h-o;if(H[1287936]){L[c+960>>3]=L[c+82080>>3];L[c+968>>3]=L[c+1816>>3];L[c+976>>3]=L[c+1824>>3];L[c+984>>3]=o;L[c+992>>3]=e;G[c+1e3>>2]=G[c+1276>>2];L[c+944>>3]=k;L[c+952>>3]=h;gb(88178,c+944|0);$a(r)}G:{if(!(G[c+1276>>2]?B:1)){break G}g=G[321985];if((g|0)<=0){break G}ba=g&-2;ca=g&1;i=0;while(1){da=l+M(i,s)|0;o=+(i|0);f=0;while(1){h=L[c+81824>>3];n=$b(L[c+1824>>3],o);h=$b(h,+(f|0));a=f+da<<2;b=G[a+m>>2];L[b>>3]=n*h*e+L[b>>3];z=G[a+t>>2];b=0;while(1){A=l+M(b,s)|0;h=+(b+i|0);d=0;a=0;if((g|0)!=1){while(1){n=L[c+81824>>3];K=z+(d+A<<3)|0;ga=K,ia=$b(L[c+1824>>3],h)*$b(n,+(d+f|0))+L[K>>3],L[ga>>3]=ia;n=L[c+81824>>3];K=d|1;V=z+(K+A<<3)|0;ga=V,ia=$b(L[c+1824>>3],h)*$b(n,+(f+K|0))+L[V>>3],L[ga>>3]=ia;d=d+2|0;a=a+2|0;if((ba|0)!=(a|0)){continue}break}}if(ca){n=L[c+81824>>3];a=z+(d+A<<3)|0;ga=a,ia=$b(L[c+1824>>3],h)*$b(n,+(d+f|0))+L[a>>3],L[ga>>3]=ia}b=b+1|0;if((g|0)!=(b|0)){continue}break}f=f+1|0;if((g|0)!=(f|0)){continue}break}i=i+1|0;if((g|0)!=(i|0)){continue}break}}j=j+v|0;e=+(j|0);d=G[321991];if(e>3]+1){continue}break}}q=q+v|0;e=+(q|0);if(e>3]+1){continue}break}}if(L[G[_>>2]+(Z<<3)>>3]==0){break d}if(H[1287936]){yb(40053);a=0;if(l){while(1){yb(36468);b=a<<2;g=G[b+t>>2];d=0;while(1){L[c+928>>3]=L[g+(d<<3)>>3];gb(66481,c+928|0);d=d+1|0;if((l|0)!=(d|0)){continue}break}yb(36690);L[c+912>>3]=L[G[b+m>>2]>>3];gb(73117,c+912|0);a=a+1|0;if((l|0)!=(a|0)){continue}break}}id()}km(t,w,m);if(H[1287936]){yb(40011);a=0;if(l){while(1){yb(36468);b=a<<2;g=G[b+t>>2];d=0;while(1){L[c+896>>3]=L[g+(d<<3)>>3];gb(66481,c+896|0);d=d+1|0;if((l|0)!=(d|0)){continue}break}yb(36690);L[c+880>>3]=L[G[b+m>>2]>>3];gb(73117,c+880|0);a=a+1|0;if((l|0)!=(a|0)){continue}break}}id()}f=0;b=G[321985];if((b|0)>0){while(1){if((b|0)>0){g=M(f,s);d=0;a=G[321988];while(1){i=G[m+(d+g<<2)>>2];q=G[(f<<2)+a>>2]+(d<<3)|0;e=L[i>>3]*.5+L[q>>3];L[q>>3]=e;h=e==0?-999:L[i>>3]/e*100;if(H[1287936]){L[c+864>>3]=h;L[c+856>>3]=e;G[c+852>>2]=d;G[c+848>>2]=f;gb(89254,c+848|0);$a(r);b=G[321985];a=G[321988]}d=d+1|0;if((d|0)<(b|0)){continue}break}}f=f+1|0;if((f|0)<(b|0)){continue}break}}f=0;if(H[1287936]){id();b=G[321985]}if((b|0)>0){while(1){if((b|0)>0){g=l+M(f,s)|0;d=0;a=G[321990];while(1){i=G[m+(d+g<<2)>>2];q=G[(f<<2)+a>>2]+(d<<3)|0;e=L[i>>3]*.5+L[q>>3];L[q>>3]=e;h=e==0?-999:L[i>>3]/e*100;if(H[1287936]){L[c+832>>3]=h;L[c+824>>3]=e;G[c+820>>2]=d;G[c+816>>2]=f;gb(89223,c+816|0);$a(r);b=G[321985];a=G[321990]}d=d+1|0;if((d|0)<(b|0)){continue}break}}f=f+1|0;if((f|0)<(b|0)){continue}break}}Wh();if(H[1287936]){G[c+800>>2]=p;kb(78506,c+800|0);$a(r)}a=0;e=0;h=0;o=0;d=G[321991];if(L[d+136>>3]+1>0){while(1){if(L[d+144>>3]+1>0){n=e+-.5;b=0;k=0;while(1){e=k+-.5;cc(d,n,e,c+82080|0,c+1816|0);G[c+1276>>2]=0;Bd(G[322064],L[c+82080>>3],L[c+1816>>3],c+1824|0,c+81824|0,c+1276|0);if(H[1287936]){L[c+752>>3]=L[c+82080>>3];L[c+760>>3]=L[c+1816>>3];L[c+768>>3]=L[c+1824>>3];L[c+776>>3]=L[c+81824>>3];G[c+784>>2]=G[c+1276>>2];L[c+736>>3]=n;L[c+744>>3]=e;gb(88046,c+736|0);$a(r)}H:{if(!(G[c+1276>>2]?B:1)){break H}k=O(n-L[c+1824>>3]);o=k>o?k:o;e=O(e-L[c+81824>>3]);if(!(e>h)){break H}h=e}b=b+v|0;k=+(b|0);d=G[321991];if(k>3]+1){continue}break}}a=a+v|0;e=+(a|0);if(e>3]+1){continue}break}}if(H[1287936]){G[c+728>>2]=p;L[c+720>>3]=o;gb(78628,c+720|0);G[c+712>>2]=p;L[c+704>>3]=h;gb(78588,c+704|0);$a(r)}if(o>>0>p>>>0;if((p|0)!=(F|0)){continue}break}p=F}Z=u&2147483644;R=u&3;I=(w>>>0>1?w:1)<<3;_=l-1|0;aa=t+(_<<2)|0;Wh();Y=1;g=0;I:{while(1){J:{if(!l){break J}a=0;d=0;f=0;if(fa>>>0>=3){while(1){b=d<<2;i=G[b+m>>2];G[i>>2]=0;G[i+4>>2]=0;cb(G[b+t>>2],0,I);i=b|4;q=G[i+m>>2];G[q>>2]=0;G[q+4>>2]=0;cb(G[i+t>>2],0,I);i=b|8;q=G[i+m>>2];G[q>>2]=0;G[q+4>>2]=0;cb(G[i+t>>2],0,I);b=b|12;i=G[b+m>>2];G[i>>2]=0;G[i+4>>2]=0;cb(G[b+t>>2],0,I);d=d+4|0;f=f+4|0;if((Z|0)!=(f|0)){continue}break}}if(!R){break J}while(1){b=d<<2;f=G[b+m>>2];G[f>>2]=0;G[f+4>>2]=0;cb(G[b+t>>2],0,I);d=d+1|0;a=a+1|0;if((R|0)!=(a|0)){continue}break}}if(H[1287936]){G[c+688>>2]=g;kb(78344,c+688|0);$a(r)}q=0;e=0;d=G[321991];if(L[d+136>>3]+1>0){while(1){if(L[d+144>>3]+1>0){h=e+-.5;j=0;e=0;while(1){e=e+-.5;cc(G[322064],h,e,c+82080|0,c+1816|0);G[c+1276>>2]=0;Bd(G[321991],L[c+82080>>3],L[c+1816>>3],c+1824|0,c+81824|0,c+1276|0);G[c+1276>>2]=0;k=L[c+1824>>3]-L[161033];L[c+1824>>3]=k;n=L[c+81824>>3]-L[161034];L[c+81824>>3]=n;o=h-k;K:{L:{if(!H[1287936]){break L}L[c+640>>3]=L[c+82080>>3];L[c+648>>3]=L[c+1816>>3];L[c+656>>3]=k;L[c+664>>3]=n;L[c+672>>3]=o;G[c+680>>2]=0;L[c+624>>3]=h;L[c+632>>3]=e;gb(88107,c+624|0);$a(r);if(B){break L}if(G[c+1276>>2]){break K}}u=G[321985];if((u|0)<=0){break K}S=u&-2;T=u&1;i=0;while(1){U=M(i,s);n=$b(h,+(i|0));f=0;while(1){k=$b(e,+(f|0));a=f+U<<2;b=G[a+m>>2];L[b>>3]=n*k*o+L[b>>3];z=G[a+t>>2];b=0;while(1){A=M(b,s);k=$b(h,+(b+i|0));d=0;a=0;if((u|0)!=1){while(1){D=z+(d+A<<3)|0;ga=D,ia=k*$b(e,+(d+f|0))+L[D>>3],L[ga>>3]=ia;D=d|1;N=z+(D+A<<3)|0;ga=N,ia=k*$b(e,+(f+D|0))+L[N>>3],L[ga>>3]=ia;d=d+2|0;a=a+2|0;if((S|0)!=(a|0)){continue}break}}if(T){a=z+(d+A<<3)|0;ga=a,ia=k*$b(e,+(d+f|0))+L[a>>3],L[ga>>3]=ia}b=b+1|0;if((u|0)!=(b|0)){continue}break}f=f+1|0;if((u|0)!=(f|0)){continue}break}i=i+1|0;if((u|0)!=(i|0)){continue}break}}j=j+v|0;e=+(j|0);d=G[321991];if(e>3]+1){continue}break}}q=q+v|0;e=+(q|0);if(e>3]+1){continue}break}}e=0;q=0;if(H[1287936]){G[c+608>>2]=g;kb(78250,c+608|0);$a(r);d=G[321991]}if(L[d+136>>3]+1>0){while(1){if(L[d+144>>3]+1>0){k=e+-.5;j=0;e=0;while(1){h=e+-.5;cc(G[322064],k,h,c+82080|0,c+1816|0);G[c+1276>>2]=0;Bd(G[321991],L[c+82080>>3],L[c+1816>>3],c+1824|0,c+81824|0,c+1276|0);G[c+1276>>2]=0;n=L[c+1824>>3]-L[161033];L[c+1824>>3]=n;e=L[c+81824>>3]-L[161034];L[c+81824>>3]=e;o=h-e;M:{N:{if(!H[1287936]){break N}L[c+560>>3]=L[c+82080>>3];L[c+568>>3]=L[c+1816>>3];L[c+576>>3]=n;L[c+584>>3]=e;L[c+592>>3]=o;G[c+600>>2]=0;L[c+544>>3]=k;L[c+552>>3]=h;gb(88107,c+544|0);$a(r);if(B){break N}if(G[c+1276>>2]){break M}}u=G[321985];if((u|0)<=0){break M}S=u&-2;T=u&1;i=0;while(1){U=l+M(i,s)|0;e=+(i|0);f=0;while(1){h=L[c+81824>>3];n=$b(L[c+1824>>3],e);h=$b(h,+(f|0));a=f+U<<2;b=G[a+m>>2];L[b>>3]=n*h*o+L[b>>3];z=G[a+t>>2];b=0;while(1){A=l+M(b,s)|0;h=+(b+i|0);d=0;a=0;if((u|0)!=1){while(1){n=L[c+81824>>3];D=z+(d+A<<3)|0;ga=D,ia=$b(L[c+1824>>3],h)*$b(n,+(d+f|0))+L[D>>3],L[ga>>3]=ia;n=L[c+81824>>3];D=d|1;N=z+(D+A<<3)|0;ga=N,ia=$b(L[c+1824>>3],h)*$b(n,+(f+D|0))+L[N>>3],L[ga>>3]=ia;d=d+2|0;a=a+2|0;if((S|0)!=(a|0)){continue}break}}if(T){n=L[c+81824>>3];a=z+(d+A<<3)|0;ga=a,ia=$b(L[c+1824>>3],h)*$b(n,+(d+f|0))+L[a>>3],L[ga>>3]=ia}b=b+1|0;if((u|0)!=(b|0)){continue}break}f=f+1|0;if((u|0)!=(f|0)){continue}break}i=i+1|0;if((u|0)!=(i|0)){continue}break}}j=j+v|0;e=+(j|0);d=G[321991];if(e>3]+1){continue}break}}q=q+v|0;e=+(q|0);if(e>3]+1){continue}break}}if(L[G[aa>>2]+(_<<3)>>3]==0){break c}if(H[1287936]){yb(40029);a=0;if(l){while(1){yb(36468);b=a<<2;f=G[b+t>>2];d=0;while(1){L[c+528>>3]=L[f+(d<<3)>>3];gb(66481,c+528|0);d=d+1|0;if((l|0)!=(d|0)){continue}break}yb(36690);L[c+512>>3]=L[G[b+m>>2]>>3];gb(73117,c+512|0);a=a+1|0;if((l|0)!=(a|0)){continue}break}}id()}km(t,w,m);if(H[1287936]){yb(40011);a=0;if(l){while(1){yb(36468);b=a<<2;f=G[b+t>>2];d=0;while(1){L[c+496>>3]=L[f+(d<<3)>>3];gb(66481,c+496|0);d=d+1|0;if((l|0)!=(d|0)){continue}break}yb(36690);L[c+480>>3]=L[G[b+m>>2]>>3];gb(73117,c+480|0);a=a+1|0;if((l|0)!=(a|0)){continue}break}}id()}f=0;b=G[321985];if((b|0)>0){while(1){if((b|0)>0){i=M(f,s);d=0;a=G[321987];while(1){q=G[m+(d+i<<2)>>2];j=G[(f<<2)+a>>2]+(d<<3)|0;e=L[q>>3]*.5+L[j>>3];L[j>>3]=e;h=e==0?-999:L[q>>3]/e*100;if(H[1287936]){L[c+464>>3]=h;L[c+456>>3]=e;G[c+452>>2]=d;G[c+448>>2]=f;gb(89315,c+448|0);$a(r);b=G[321985];a=G[321987]}d=d+1|0;if((d|0)<(b|0)){continue}break}}f=f+1|0;if((f|0)<(b|0)){continue}break}}f=0;if(H[1287936]){id();b=G[321985]}if((b|0)>0){while(1){if((b|0)>0){i=l+M(f,s)|0;d=0;a=G[321989];while(1){q=G[m+(d+i<<2)>>2];j=G[(f<<2)+a>>2]+(d<<3)|0;e=L[q>>3]*.5+L[j>>3];L[j>>3]=e;h=e==0?-999:L[q>>3]/e*100;if(H[1287936]){L[c+432>>3]=h;L[c+424>>3]=e;G[c+420>>2]=d;G[c+416>>2]=f;gb(89285,c+416|0);$a(r);b=G[321985];a=G[321989]}d=d+1|0;if((d|0)<(b|0)){continue}break}}f=f+1|0;if((f|0)<(b|0)){continue}break}}Wh();if(H[1287936]){G[c+400>>2]=g;kb(78462,c+400|0);$a(r)}a=0;e=0;h=0;k=0;b=G[321991];if(L[b+136>>3]+1>0){while(1){if(L[b+144>>3]+1>0){n=e+-.5;d=0;o=0;while(1){e=o+-.5;cc(G[322064],n,e,c+82080|0,c+1816|0);G[c+1276>>2]=0;Bd(G[321991],L[c+82080>>3],L[c+1816>>3],c+1824|0,c+81824|0,c+1276|0);G[c+1276>>2]=0;o=L[c+1824>>3]-L[161033];L[c+1824>>3]=o;y=L[c+81824>>3]-L[161034];L[c+81824>>3]=y;O:{P:{if(!H[1287936]){break P}L[c+352>>3]=L[c+82080>>3];L[c+360>>3]=L[c+1816>>3];L[c+368>>3]=o;L[c+376>>3]=y;G[c+384>>2]=0;L[c+336>>3]=n;L[c+344>>3]=e;gb(87985,c+336|0);$a(r);if(B){break P}if(G[c+1276>>2]){break O}}o=O(n-L[c+1824>>3]);k=k>3]);if(!(e>h)){break O}h=e}d=d+v|0;o=+(d|0);b=G[321991];if(o>3]+1){continue}break}}a=a+v|0;e=+(a|0);if(e>3]+1){continue}break}}if(H[1287936]){G[c+328>>2]=g;L[c+320>>3]=k;gb(78608,c+320|0);G[c+312>>2]=g;L[c+304>>3]=h;gb(78568,c+304|0);$a(r)}if(k>>0>g>>>0;if((g|0)!=(F|0)){continue}break}g=F}Q:{if(!H[1287936]){break Q}id();if(!H[1287936]){break Q}yb(10782);$a(r)}n=0;h=0;d=G[321991];if(L[d+136>>3]+1>0){e=0;a=0;while(1){if(L[d+144>>3]+1>0){e=e+-.5;b=0;k=0;while(1){x=k+-.5;cc(d,e,x,c+82080|0,c+1816|0);G[c+1276>>2]=0;Bd(G[322064],L[c+82080>>3],L[c+1816>>3],c+1824|0,c+81824|0,c+1276|0);if(H[1287936]){L[c+256>>3]=L[c+82080>>3];L[c+264>>3]=L[c+1816>>3];L[c+272>>3]=L[c+1824>>3];L[c+280>>3]=L[c+81824>>3];G[c+288>>2]=G[c+1276>>2];L[c+240>>3]=e;L[c+248>>3]=x;gb(88046,c+240|0);$a(r)}R:{if(!(G[c+1276>>2]?B:1)){break R}k=O(e-L[c+1824>>3]);n=k>n?k:n;x=O(x-L[c+81824>>3]);if(!(x>h)){break R}h=x}b=b+X|0;k=+(b|0);d=G[321991];if(k>3]+1){continue}break}}a=a+X|0;e=+(a|0);if(e>3]+1){continue}break}}S:{if(!H[1287936]){break S}id();L[c+224>>3]=n;gb(70408,c+224|0);L[c+208>>3]=h;gb(70366,c+208|0);$a(r);if(!H[1287936]){break S}yb(10746);$a(r)}k=0;x=0;b=G[321991];if(L[b+136>>3]+1>0){e=0;a=0;while(1){if(L[b+144>>3]+1>0){y=e+-.5;d=0;o=0;while(1){e=o+-.5;cc(G[322064],y,e,c+82080|0,c+1816|0);G[c+1276>>2]=0;Bd(G[321991],L[c+82080>>3],L[c+1816>>3],c+1824|0,c+81824|0,c+1276|0);G[c+1276>>2]=0;o=L[c+1824>>3]-L[161033];L[c+1824>>3]=o;P=L[c+81824>>3]-L[161034];L[c+81824>>3]=P;T:{U:{if(!H[1287936]){break U}L[c+160>>3]=L[c+82080>>3];L[c+168>>3]=L[c+1816>>3];L[c+176>>3]=o;L[c+184>>3]=P;G[c+192>>2]=0;L[c+144>>3]=y;L[c+152>>3]=e;gb(87985,c+144|0);$a(r);if(B){break U}if(G[c+1276>>2]){break T}}o=O(y-L[c+1824>>3]);k=k>3]);if(!(e>x)){break T}x=e}d=d+X|0;o=+(d|0);b=G[321991];if(o>3]+1){continue}break}}a=a+X|0;e=+(a|0);if(e>3]+1){continue}break}}if(H[1287936]){L[c+128>>3]=k;gb(70387,c+128|0);L[c+112>>3]=x;gb(90142,c+112|0);$a(r)}Hb(G[321986]);L[c+88>>3]=k;L[c+96>>3]=x;a=F-1|0;G[c+80>>2]=(ea?p:a)+1;G[c+104>>2]=(Y?g:a)+1;L[c+64>>3]=n;L[c+72>>3]=h;xb(G[321435],79198,c- -64|0);$a(r);$a(G[321435]);Hb(G[321435]);sc(0);W()}G[c+1200>>2]=F;_a(G[321435],81164,c+1200|0);break b}G[c+1216>>2]=d;_a(G[321435],81239,c+1216|0);break b}G[c+1232>>2]=d;_a(G[321435],81385,c+1232|0);break b}G[c>>2]=G[b>>2];_a(G[321435],84889,c);break a}G[c+16>>2]=G[b>>2];_a(G[321435],84889,c+16|0);break a}G[c+32>>2]=m;_a(G[321435],80640,c+32|0);break b}G[c+48>>2]=p;_a(G[321435],80820,c+48|0);break a}hb(84378,54,1,G[321435]);break a}hb(82436,70,1,G[321435]);break a}hb(82365,70,1,G[321435]);break a}$a(r)}$a(G[321435]);Hb(G[321435]);sc(1);W()}function Oq(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,K=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Wa=0;c=Fa-23536|0;Fa=c;n=ab(64);r=ab(4096);G[n>>2]=r;Ta=n,Ua=ab(4096),G[Ta+4>>2]=Ua;Ta=n,Ua=ab(4096),G[Ta+8>>2]=Ua;Ta=n,Ua=ab(4096),G[Ta+12>>2]=Ua;Ta=n,Ua=ab(4096),G[Ta+16>>2]=Ua;Ta=n,Ua=ab(4096),G[Ta+20>>2]=Ua;Ta=n,Ua=ab(4096),G[Ta+24>>2]=Ua;Ta=n,Ua=ab(4096),G[Ta+28>>2]=Ua;Ta=n,Ua=ab(4096),G[Ta+32>>2]=Ua;Ta=n,Ua=ab(4096),G[Ta+36>>2]=Ua;Ta=n,Ua=ab(4096),G[Ta+40>>2]=Ua;Ta=n,Ua=ab(4096),G[Ta+44>>2]=Ua;Ta=n,Ua=ab(4096),G[Ta+48>>2]=Ua;Ta=n,Ua=ab(4096),G[Ta+52>>2]=Ua;Ta=n,Ua=ab(4096),G[Ta+56>>2]=Ua;Ta=n,Ua=ab(4096),G[Ta+60>>2]=Ua;m=ab(32768);a:{b:{c:{d:{e:{f:{g:{h:{i:{j:{k:{l=ab(32768);if(l){G[47589]=1;X=G[29763];G[321435]=X;G[47590]=0;G[935722]=0;l:{m:while(1){w=e;while(1){e=1;n:{o:{p:{q:{r:{g=of(a,b,36988);switch(g-80|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 31:case 33:case 34:break j;case 30:continue m;case 35:break n;case 32:break o;case 0:break p;case 21:break q;case 20:break r;default:break l}}Ta=3742888,Ua=nj(G[321433]),G[Ta>>2]=Ua;continue}e=G[321433];N=_b(e);if((N|0)<0){break k}ya=jb(e,37)?1:ya;e=w;continue m}e=_b(G[321433]);Ma=(e|0)>0?e:0;e=w;continue m}e=w;w=G[321433];B=sb(w);if(!(B<=0)){continue m}G[c+1312>>2]=w;_a(G[321435],80706,c+1312|0);break a}e=ac(G[321433],49010);G[321435]=e;if(e){continue}break}break}G[c+1328>>2]=G[321433];kb(80991,c+1328|0);break a}if((g|0)!=-1){break j}za=1;g=G[47589];p=a-g|0;if((p|0)<=1){break i}e=(g<<2)+b|0;ja=Za(c+19440|0,G[e>>2]);Na=Za(c+15344|0,G[e+4>>2]);if((p|0)==2){break e}e=G[e+8>>2];d=Xa(e,34868);P=0;if(!d){break f}if(!Xa(e,35899)){Aa=1;t=1;P=0;break f}if(!Xa(e,34873)){t=2;Oa=1;break g}if(!Xa(e,35912)){t=3;Ba=1;break g}if(!Xa(e,34820)){t=4;P=1;break f}if(Xa(e,34819)){break h}t=5;Pa=1;P=0;break f}hb(83879,56,1,G[321435]);$a(G[29763]);break a}G[c+1296>>2]=e;_a(G[321435],80767,c+1296|0);break a}G[c>>2]=G[b>>2];kb(84675,c);break c}G[c+16>>2]=G[b>>2];kb(84675,c+16|0);break c}hb(83124,90,1,G[321435]);break c}P=0}za=!d;if(p>>>0<4){break e}q=vb(G[((g<<2)+b|0)+12>>2],c+1340|0);a=G[((G[47589]<<2)+b|0)+12>>2];if(J[c+1340>>2]>=Va(a)+a>>>0){break d}hb(81841,60,1,G[321435]);break a}q=Ba?1950:Aa?1950:2e3}G[935572]=G[935722];s:{t:{u:{v:{d=ac(Na,49010);if(d){if((Rh(ja)|0)>0){b=Pb(23501);w:{if((b|0)>=0){if((nf()|0)>=0){e=16;while(1){Za(G[(Z<<2)+n>>2],(b|0)>2]:0);Z=Z+1|0;if((Z|0)>=(e|0)){a=e+16|0;n=ab(a<<2);while(1){Ta=(e<<2)+n|0,Ua=ab(4096),G[Ta>>2]=Ua;e=e+1|0;if((a|0)>(e|0)){continue}break}e=a}if((nf()|0)>=0){continue}break}break w}Qh();B=-2;g=2;h=360;e=0;break u}Za(r,ja);Z=1}Qh();Sa=c+11248|1;h=360;e=0;ka=4096;g=2;_=1;la=1;x:{y:{z:{while(1){a=Za(ja,G[(ma<<2)+n>>2]);if(G[935722]>0){G[c+1284>>2]=a;G[c+1280>>2]=ma;kb(76821,c+1280|0);$a(X)}if((Rh(a)|0)<=0){break x}na=Pb(6975);oa=Pb(40414);pa=Pb(40474);qa=Pb(40395);ra=Pb(40402);sa=Pb(40314);ta=Pb(40326);ua=Pb(40295);va=Pb(40302);C=Pb(41002);r=Pb(40604);u=Pb(41060);Ca=1;$=Pb(40707);aa=Pb(40486);ba=Pb(40342);v=Pb(41055);ca=Pb(40695);da=Pb(40481);ea=Pb(40337);A:{B:{if((u|$|(aa|ba))<0){break B}if((v|ca|da)<0){break B}if((ea|0)>=0){break A}}u=Pb(41029);$=Pb(40631);aa=Pb(40469);ba=Pb(40321);v=Pb(41009);ca=Pb(40611);da=Pb(40409);ea=Pb(40309);C:{if((u|$|(aa|ba))<0){break C}if((v|ca|da)<0){break C}if((ea|0)>=0){break A}}Da=Pb(41041);Ea=Pb(40643);Ga=Pb(3709);fa=Pb(16725);ga=Pb(6868);Ha=Pb(41034);Ia=Pb(40636);Ja=Pb(40995);Ka=Pb(40585);C=Pb(41002);r=Pb(40604);La=Pb(40700);Pb(17534);if((ga|0)<0){ga=Pb(41022)}if((fa|0)<0){fa=Pb(40624)}D:{if((Da|Ea|(fa|ga))<0){break D}if((Ha|Ia|(Ja|Ka))<0){break D}if((C|r)<0){break D}Ca=2;if((La|0)>=0){break A}}Ca=3;u=Pb(30988);v=Pb(30707);if((u|v)>=0){break A}u=Pb(13594);v=Pb(5251);if((u|v)>=0){break A}u=Pb(41034);v=Pb(40636);if((u|v)<0){break y}}G[935728]=0;G[935729]=1084178432;G[935725]=0;a=Xd(32863);if(a){Za(c+11248|0,a)}a=Xd(34948);if(a){Za(c+11248|0,a)}a=Xd(3709);if(a){Za(c+11248|0,a)}a=Xd(17534);if(a){Za(c+11248|0,a)}a=Xd(33588);if(a){Za(c+7152|0,a)}a=Xd(34666);if(a){Za(c+7152|0,a)}a=Xd(33589);if(a){Za(c+7152|0,a)}a=Xd(35752);if(a){Za(c+7152|0,a)}a=Xd(33575);if(a){Za(c+7152|0,a)}a=Xd(5347);if(a){Za(c+7152|0,a)}a=Xd(16343);if(a){Za(c+7152|0,a)}a=Xd(5348);if(a){Za(c+7152|0,a)}a=Xd(25955);if(a){Za(c+7152|0,a)}a=Xd(5338);if(a){Za(c+7152|0,a)}b=0;a=0;if(H[c+7152|0]){while(1){p=c+7152|0;s=p+b|0;a=E[s|0];E[s|0]=a-65>>>0<26?a|32:a;a=Va(p);b=b+1|0;if(a>>>0>b>>>0){continue}break}}b=106;E:{F:{G:{switch((H[c+11248|0]&223)-66|0){default:f=sb(c+11248|0);Y=2e3;if(f==0){break F}break E;case 0:b=98;break;case 8:break G}}Y=sb(Sa)}f=Y}L[467864]=f;s=I[c+7152>>1]!=29029;b=H[(a+c|0)+7151|0]==106?106:b;if(!(s|(b|0)!=106)){G[935725]=0}p=I[c+7152>>1]!=25445;H:{I:{if((b|0)==106){a=2;if(!p){break I}}b=(b|0)==98;p=b&!p;a=p?3:1;if(b&!s){break I}if(!p){break H}}G[935725]=a}if(I[c+7152>>1]==24935){G[935725]=4}if(I[c+7152>>1]==26483){G[935725]=5}if(I[c+7152>>1]==30067){G[935725]=5}la=(sa|ta|(ua|va))<0?0:la;_=(oa|pa|(qa|ra))<0?0:_;J:{if((nf()|0)>=0){p=(la|0)!=0;while(1){K:{if((na|0)<0){break K}if(Ue(na)){g=-1;break K}a=_b(G[925783]>(na|0)?G[(G[925773]+M(na,4108)|0)+4096>>2]:0);b=a;if(Q){if((a|0)==2){g=-1;break K}b=(a|0)==(g|0)?g:-1}if((a|0)<3){g=b;break K}L:{M:{if(!(!_|(b|0)<3)){if(Ue(oa)){break M}if(Ue(pa)){break M}if(Ue(qa)){break M}if(Ue(ra)){break M}Qa=_b(G[925783]>(oa|0)?G[(G[925773]+M(oa,4108)|0)+4096>>2]:0);x=sb(G[925783]>(pa|0)?G[(G[925773]+M(pa,4108)|0)+4096>>2]:0);j=sb(G[925783]>(qa|0)?G[(G[925773]+M(qa,4108)|0)+4096>>2]:0);y=sb(G[925783]>(ra|0)?G[(G[925773]+M(ra,4108)|0)+4096>>2]:0)}if((b|0)<4){a=p;break L}if(!la){a=p;break L}a=1;if(Ue(sa)){b=-1;break L}if(Ue(ta)){b=-1;break L}if(Ue(ua)){b=-1;break L}if(Ue(va)){b=-1;break L}Ra=_b(G[925783]>(sa|0)?G[(G[925773]+M(sa,4108)|0)+4096>>2]:0);i=sb(G[925783]>(ta|0)?G[(G[925773]+M(ta,4108)|0)+4096>>2]:0);o=sb(G[925783]>(ua|0)?G[(G[925773]+M(ua,4108)|0)+4096>>2]:0);ha=sb(G[925783]>(va|0)?G[(G[925773]+M(va,4108)|0)+4096>>2]:0);break L}a=p;b=-1}if(!Q){R=x;S=y;T=i;z=o;U=ha;V=Qa;A=j;K=Ra}b=(b|0)<3?b:_?b:-1;wa=wa+1|0;if(_){b=x!=R?-1:b;g=y!=S;f=+(V|0)-A;A=j>A?j:A;k=+(Qa|0)-j;f=A+(f3&a)){break K}a=i!=T?-1:g;b=U!=ha;f=+(K|0)-z;z=o>z?o:z;k=+(Ra|0)-o;f=z+(f(u|0)?G[(G[925773]+M(u,4108)|0)+4096>>2]:0),L[Ta+3048>>3]=Wa;f=sb(G[925783]>(v|0)?G[(G[925773]+M(v,4108)|0)+4096>>2]:0);L[c+3040>>3]=f;dd(G[935725],L[467864],L[c+3048>>3],f,t,q,c+3032|0,c+3024|0);a=e<<3;L[a+m>>3]=L[c+3032>>3];L[a+l>>3]=L[c+3024>>3];R:{if((C|0)<0){break R}f=O(sb(G[925783]>(C|0)?G[(G[925773]+M(C,4108)|0)+4096>>2]:0));if(!(f(r|0)?G[(G[925773]+M(r,4108)|0)+4096>>2]:0));if(!(f(u|0)?G[(G[925773]+M(u,4108)|0)+4096>>2]:0),L[Ta+3048>>3]=Wa;f=sb(G[925783]>(v|0)?G[(G[925773]+M(v,4108)|0)+4096>>2]:0);L[c+3040>>3]=f;b=c+3032|0;s=c+3024|0;dd(G[935725],L[467864],L[c+3048>>3],f,t,q,b,s);a=e<<3;L[a+m>>3]=L[c+3032>>3];L[a+l>>3]=L[c+3024>>3];Ta=c,Wa=sb(G[925783]>($|0)?G[(G[925773]+M($,4108)|0)+4096>>2]:0),L[Ta+3048>>3]=Wa;f=sb(G[925783]>(ca|0)?G[(G[925773]+M(ca,4108)|0)+4096>>2]:0);L[c+3040>>3]=f;dd(G[935725],L[467864],L[c+3048>>3],f,t,q,b,s);D=a+8|0;L[D+m>>3]=L[c+3032>>3];L[l+D>>3]=L[c+3024>>3];Ta=c,Wa=sb(G[925783]>(aa|0)?G[(G[925773]+M(aa,4108)|0)+4096>>2]:0),L[Ta+3048>>3]=Wa;f=sb(G[925783]>(da|0)?G[(G[925773]+M(da,4108)|0)+4096>>2]:0);L[c+3040>>3]=f;dd(G[935725],L[467864],L[c+3048>>3],f,t,q,b,s);D=a+16|0;L[D+m>>3]=L[c+3032>>3];L[l+D>>3]=L[c+3024>>3];Ta=c,Wa=sb(G[925783]>(ba|0)?G[(G[925773]+M(ba,4108)|0)+4096>>2]:0),L[Ta+3048>>3]=Wa;f=sb(G[925783]>(ea|0)?G[(G[925773]+M(ea,4108)|0)+4096>>2]:0);L[c+3040>>3]=f;dd(G[935725],L[467864],L[c+3048>>3],f,t,q,b,s);a=a+24|0;L[a+m>>3]=L[c+3032>>3];L[a+l>>3]=L[c+3024>>3];S:{if((C|0)<0){break S}f=O(sb(G[925783]>(C|0)?G[(G[925773]+M(C,4108)|0)+4096>>2]:0));if(!(f(r|0)?G[(G[925773]+M(r,4108)|0)+4096>>2]:0));if(!(f(Da|0)?G[(G[925773]+M(Da,4108)|0)+4096>>2]:0);Za(3742936,G[925783]>(Ea|0)?G[(G[925773]+M(Ea,4108)|0)+4096>>2]:0);Ta=3742952,Ua=_b(G[925783]>(ga|0)?G[(G[925773]+M(ga,4108)|0)+4096>>2]:0),G[Ta>>2]=Ua;Ta=3742956,Ua=_b(G[925783]>(fa|0)?G[(G[925773]+M(fa,4108)|0)+4096>>2]:0),G[Ta>>2]=Ua;Ta=3742960,Wa=sb(G[925783]>(Ja|0)?G[(G[925773]+M(Ja,4108)|0)+4096>>2]:0),L[Ta>>3]=Wa;Ta=3742968,Wa=sb(G[925783]>(Ka|0)?G[(G[925773]+M(Ka,4108)|0)+4096>>2]:0),L[Ta>>3]=Wa;Ta=3742976,Wa=sb(G[925783]>(Ha|0)?G[(G[925773]+M(Ha,4108)|0)+4096>>2]:0),L[Ta>>3]=Wa;Ta=3742984,Wa=sb(G[925783]>(Ia|0)?G[(G[925773]+M(Ia,4108)|0)+4096>>2]:0),L[Ta>>3]=Wa;Ta=3742992,Wa=sb(G[925783]>(C|0)?G[(G[925773]+M(C,4108)|0)+4096>>2]:0),L[Ta>>3]=Wa;Ta=3743e3,Wa=sb(G[925783]>(r|0)?G[(G[925773]+M(r,4108)|0)+4096>>2]:0),L[Ta>>3]=Wa;f=sb(G[925783]>(La|0)?G[(G[925773]+M(La,4108)|0)+4096>>2]:0);G[935726]=2e3;L[467876]=f;if((Ga|0)>=0){Ta=3742904,Ua=_b(G[925783]>(Ga|0)?G[(G[925773]+M(Ga,4108)|0)+4096>>2]:0),G[Ta>>2]=Ua}E[c+1424|0]=0;a=H[33554]|H[33555]<<8|(H[33556]<<16|H[33557]<<24);G[c+1344>>2]=H[33550]|H[33551]<<8|(H[33552]<<16|H[33553]<<24);G[c+1348>>2]=a;G[c+1352>>2]=H[33558]|H[33559]<<8|(H[33560]<<16|H[33561]<<24);f=L[467874];k=L[467875];b=Va(c+1424|0);a=Va(c+1344|0);T:{if((a|0)>0){bb(b+(c+1424|0)|0,c+1344|0,a);if(a>>>0>79){break T}}cb(c+1424+(a+b)|0,32,80-a|0)}E[(b+c|0)+1504|0]=0;a=H[40385]|H[40386]<<8|(H[40387]<<16|H[40388]<<24);G[c+1344>>2]=H[40381]|H[40382]<<8|(H[40383]<<16|H[40384]<<24);G[c+1348>>2]=a;a=H[40391]|H[40392]<<8|(H[40393]<<16|H[40394]<<24);b=H[40387]|H[40388]<<8|(H[40389]<<16|H[40390]<<24);F[c+1350>>1]=b;F[c+1352>>1]=b>>>16;F[c+1354>>1]=a;F[c+1356>>1]=a>>>16;b=Va(c+1424|0);a=Va(c+1344|0);U:{if((a|0)>0){bb(b+(c+1424|0)|0,c+1344|0,a);if(a>>>0>79){break U}}cb(c+1424+(a+b)|0,32,80-a|0)}E[(b+c|0)+1504|0]=0;a=H[40967]|H[40968]<<8|(H[40969]<<16|H[40970]<<24);G[c+1344>>2]=H[40963]|H[40964]<<8|(H[40965]<<16|H[40966]<<24);G[c+1348>>2]=a;G[c+1352>>2]=H[40971]|H[40972]<<8|(H[40973]<<16|H[40974]<<24);b=Va(c+1424|0);a=Va(c+1344|0);V:{if((a|0)>0){bb(b+(c+1424|0)|0,c+1344|0,a);if(a>>>0>79){break V}}cb(c+1424+(a+b)|0,32,80-a|0)}E[(b+c|0)+1504|0]=0;G[c+1264>>2]=G[935738];a=c+1344|0;db(a,30391,c+1264|0);b=Va(c+1424|0);a=Va(a);W:{if((a|0)>0){bb(b+(c+1424|0)|0,c+1344|0,a);if(a>>>0>79){break W}}cb(c+1424+(a+b)|0,32,80-a|0)}E[(b+c|0)+1504|0]=0;G[c+1248>>2]=G[935739];a=c+1344|0;db(a,30378,c+1248|0);b=Va(c+1424|0);a=Va(a);X:{if((a|0)>0){bb(b+(c+1424|0)|0,c+1344|0,a);if(a>>>0>79){break X}}cb(c+1424+(a+b)|0,32,80-a|0)}E[(b+c|0)+1504|0]=0;G[c+1232>>2]=3742920;a=c+1344|0;db(a,64770,c+1232|0);b=Va(c+1424|0);a=Va(a);Y:{if((a|0)>0){bb(b+(c+1424|0)|0,c+1344|0,a);if(a>>>0>79){break Y}}cb(c+1424+(a+b)|0,32,80-a|0)}E[(b+c|0)+1504|0]=0;G[c+1216>>2]=3742936;a=c+1344|0;db(a,64755,c+1216|0);b=Va(c+1424|0);a=Va(a);Z:{if((a|0)>0){bb(b+(c+1424|0)|0,c+1344|0,a);if(a>>>0>79){break Z}}cb(c+1424+(a+b)|0,32,80-a|0)}E[(b+c|0)+1504|0]=0;L[c+1200>>3]=L[467872];a=c+1344|0;Eb(a,18769,c+1200|0);b=Va(c+1424|0);a=Va(a);_:{if((a|0)>0){bb(b+(c+1424|0)|0,c+1344|0,a);if(a>>>0>79){break _}}cb(c+1424+(a+b)|0,32,80-a|0)}E[(b+c|0)+1504|0]=0;L[c+1184>>3]=L[467873];a=c+1344|0;Eb(a,18701,c+1184|0);b=Va(c+1424|0);a=Va(a);$:{if((a|0)>0){bb(b+(c+1424|0)|0,c+1344|0,a);if(a>>>0>79){break $}}cb(c+1424+(a+b)|0,32,80-a|0)}E[(b+c|0)+1504|0]=0;L[c+1168>>3]=L[467870];a=c+1344|0;Eb(a,18735,c+1168|0);b=Va(c+1424|0);a=Va(a);aa:{if((a|0)>0){bb(b+(c+1424|0)|0,c+1344|0,a);if(a>>>0>79){break aa}}cb(c+1424+(a+b)|0,32,80-a|0)}E[(b+c|0)+1504|0]=0;L[c+1152>>3]=L[467871];a=c+1344|0;Eb(a,18667,c+1152|0);b=Va(c+1424|0);a=Va(a);ba:{if((a|0)>0){bb(b+(c+1424|0)|0,c+1344|0,a);if(a>>>0>79){break ba}}cb(c+1424+(a+b)|0,32,80-a|0)}E[(b+c|0)+1504|0]=0;L[c+1136>>3]=L[467874];a=c+1344|0;Eb(a,18752,c+1136|0);b=Va(c+1424|0);a=Va(a);ca:{if((a|0)>0){bb(b+(c+1424|0)|0,c+1344|0,a);if(a>>>0>79){break ca}}cb(c+1424+(a+b)|0,32,80-a|0)}E[(b+c|0)+1504|0]=0;L[c+1120>>3]=L[467875];a=c+1344|0;Eb(a,18684,c+1120|0);b=Va(c+1424|0);a=Va(a);da:{if((a|0)>0){bb(b+(c+1424|0)|0,c+1344|0,a);if(a>>>0>79){break da}}cb(c+1424+(a+b)|0,32,80-a|0)}E[(b+c|0)+1504|0]=0;L[c+1104>>3]=L[467876];a=c+1344|0;Eb(a,18718,c+1104|0);b=Va(c+1424|0);a=Va(a);ea:{if((a|0)>0){bb(b+(c+1424|0)|0,c+1344|0,a);if(a>>>0>79){break ea}}cb(c+1424+(a+b)|0,32,80-a|0)}E[(b+c|0)+1504|0]=0;G[c+1088>>2]=G[935726];a=c+1344|0;db(a,30339,c+1088|0);b=Va(c+1424|0);a=Va(a);fa:{if((a|0)>0){bb(b+(c+1424|0)|0,c+1344|0,a);if(a>>>0>79){break fa}}cb(c+1424+(a+b)|0,32,80-a|0)}E[(b+c|0)+1504|0]=0;G[c+1344>>2]=4476485;b=Va(c+1424|0);a=Va(c+1344|0);ga:{if((a|0)>0){bb(b+(c+1424|0)|0,c+1344|0,a);if(a>>>0>79){break ga}}cb(c+1424+(a+b)|0,32,80-a|0)}E[(b+c|0)+1504|0]=0;a=rd(c+1424|0);G[935724]=a;if(!a){break J}k=O(k);f=O(f);f=f>2]-1|0){case 2:break ja;case 3:break la;case 1:break ma;case 0:break na;default:break ka}}G[935728]=0;G[935729]=1084178432;G[935725]=0;h=1950;if(L[b+120>>3]==1950){break ia}break ha}G[935728]=0;G[935729]=1084127232;G[935725]=1;if(L[b+120>>3]==2e3){break ia}break ha}G[935728]=0;G[935729]=1084178432;G[935725]=2;h=1950;a=3;if(L[b+120>>3]==1950){break ja}break ha}a=0}G[935725]=a}L[467864]=h}h=s?k:f;a=b;b=c+3048|0;s=c+3040|0;cc(a,.5,.5,b,s);D=c+3032|0;xa=c+3024|0;dd(G[935725],L[467864],L[c+3048>>3],L[c+3040>>3],t,q,D,xa);a=e<<3;L[a+m>>3]=L[c+3032>>3];L[a+l>>3]=L[c+3024>>3];cc(G[935724],+G[935738]+.5,.5,b,s);dd(G[935725],L[467864],L[c+3048>>3],L[c+3040>>3],t,q,D,xa);ia=a+8|0;L[ia+m>>3]=L[c+3032>>3];L[l+ia>>3]=L[c+3024>>3];cc(G[935724],+G[935738]+.5,+G[935739]+.5,b,s);dd(G[935725],L[467864],L[c+3048>>3],L[c+3040>>3],t,q,D,xa);ia=a+16|0;L[ia+m>>3]=L[c+3032>>3];L[l+ia>>3]=L[c+3024>>3];cc(G[935724],.5,+G[935739]+.5,b,s);dd(G[935725],L[467864],L[c+3048>>3],L[c+3040>>3],t,q,D,xa);a=a+24|0;L[a+m>>3]=L[c+3032>>3];L[a+l>>3]=L[c+3024>>3];e=e+4|0}if((e|0)>=(ka|0)){ka=ka+4096|0;a=ka<<3;m=ub(m,a);l=ub(l,a);if(!l){break z}}h=B>0?B:h;if((nf()|0)>=0){continue}break}}Qh();ma=ma+1|0;if((ma|0)==(Z|0)){break v}continue}break}G[c+1072>>2]=Q;_a(G[321435],83021,c+1072|0);break a}Hb(d);hb(83879,56,1,G[321435]);break c}hb(80079,227,1,G[321435]);break a}G[c+48>>2]=a;_a(G[321435],81102,c+48|0);break a}G[c+32>>2]=ja;_a(G[321435],81049,c+32|0);break a}hb(83936,60,1,G[321435]);break c}b=0;B=-2;if((e|0)>0){break t}}j=-2;i=-2;break s}f=1;i=-1;j=-1;o=-1;y=1;x=1;while(1){a=b<<3;k=L[a+m>>3];ha=L[a+l>>3]*.017453292519943295;B=eb(ha);Y=k*.017453292519943295;k=B*ib(Y);j=jo?k:o;x=kk?k:f;b=b+1|0;if((e|0)!=(b|0)){continue}break}B=o-x;j=j-y;i=i-f}if(i>1?1:B>1|j>1){hb(85307,12,1,d);hb(86411,14,1,d);i=180/h;oa:{if(O(i)<2147483648){a=~~i;break oa}a=-2147483648}e=(g|0)!=-1;i=360/h;pa:{if(O(i)<2147483648){b=~~i;break pa}b=-2147483648}qa:{if(!e){hb(86498,12,1,d);break qa}G[c+432>>2]=g;_a(d,75597,c+432|0)}G[c+416>>2]=b;_a(d,75530,c+416|0);G[c+400>>2]=a;_a(d,75516,c+400|0);t=3;e=0;ra:{if((g|0)>=3){G[c+384>>2]=V;_a(d,75502,c+384|0);if((g|0)==3){break ra}G[c+368>>2]=K;_a(d,75488,c+368|0);e=1}t=g}if(za){hb(89784,21,1,d);hb(89762,21,1,d);L[c+352>>3]=q;xb(d,70545,c+352|0)}if(Aa){hb(89784,21,1,d);hb(89762,21,1,d);L[c+336>>3]=q;xb(d,70545,c+336|0)}if(Oa){hb(89740,21,1,d);hb(89674,21,1,d);L[c+320>>3]=q;xb(d,70545,c+320|0)}if(Ba){hb(89740,21,1,d);hb(89674,21,1,d);L[c+304>>3]=q;xb(d,70545,c+304|0)}if(P){hb(89718,21,1,d);hb(89652,21,1,d)}if(Pa){hb(89696,21,1,d);hb(89630,21,1,d)}G[c+288>>2]=0;G[c+292>>2]=0;xb(d,71373,c+288|0);G[c+272>>2]=0;G[c+276>>2]=0;xb(d,71319,c+272|0);if((g|0)>=3){L[c+256>>3]=R;xb(d,71283,c+256|0)}if(e){L[c+240>>3]=T;xb(d,71229,c+240|0)}L[c+224>>3]=(+(b|0)+1)*.5;xb(d,72266,c+224|0);L[c+208>>3]=(+(a|0)+1)*.5;xb(d,72248,c+208|0);if((g|0)>=3){L[c+192>>3]=A;xb(d,71247,c+192|0)}if(e){L[c+176>>3]=z;xb(d,71193,c+176|0)}L[c+160>>3]=-h;xb(d,71355,c+160|0);L[c+144>>3]=h;xb(d,71301,c+144|0);if((g|0)>=3){L[c+128>>3]=S;xb(d,71265,c+128|0)}if(e){L[c+112>>3]=U;xb(d,71211,c+112|0)}G[c+96>>2]=0;G[c+100>>2]=0;xb(d,71337,c+96|0);hb(85385,4,1,d);$a(d);Hb(d);E[c+3056|0]=0;if((t|0)<0){bb(c+3056|0,42233,79)}G[c+80>>2]=a;G[c+68>>2]=Q;G[c+72>>2]=wa;G[c+76>>2]=b;G[c+64>>2]=c+3056;_a(G[321435],79294,c- -64|0);$a(X);break b}sa:{if(w){a=0;ta:{if((e|0)<3){break ta}if((Yl(e,m,l,0)|0)<0){break ta}if(G[935573]>0){Xl()}a=ab(112);L[a>>3]=L[467787];L[a+32>>3]=L[467788];L[a+8>>3]=L[467794];L[a+40>>3]=L[467795];L[a+16>>3]=L[467801];L[a+48>>3]=L[467802];L[a+24>>3]=L[467808];L[a+56>>3]=L[467809];L[a+64>>3]=L[467815];L[a+72>>3]=L[467816];L[a+80>>3]=L[467822];L[a+88>>3]=L[467823];L[a+96>>3]=L[467824]}break sa}a=0;ua:{if((e|0)<3){break ua}if((Yl(e,m,l,1)|0)<0){break ua}if(G[935573]>0){Xl()}a=ab(112);L[a>>3]=L[467787];L[a+32>>3]=L[467788];L[a+8>>3]=L[467794];L[a+40>>3]=L[467795];L[a+16>>3]=L[467801];L[a+48>>3]=L[467802];L[a+24>>3]=L[467808];L[a+56>>3]=L[467809];L[a+64>>3]=L[467815];L[a+72>>3]=L[467816];L[a+80>>3]=L[467822];L[a+88>>3]=L[467823];L[a+96>>3]=L[467824]}}if(a){h=h<=0?.0002777777777777778:h>=360?.0002777777777777778:h;va:{if(!Ma){break va}h=+(Ma|0);i=L[a+88>>3];j=L[a+80>>3];if(i>j){h=i/h;break va}h=j/h}wa:{if(!ya){break wa}i=+(N|0)/100;xa:{j=L[a+88>>3]/h;ya:{if(O(j)<2147483648){e=~~j;break ya}e=-2147483648}j=L[a+80>>3]/h;za:{if(O(j)<2147483648){b=~~j;break za}b=-2147483648}if((e|0)<(b|0)){i=i*+(b|0);if(!(O(i)<2147483648)){break xa}N=~~i;break wa}i=i*+(e|0);if(!(O(i)<2147483648)){break xa}N=~~i;break wa}N=-2147483648}if(G[935722]>0){G[c+1060>>2]=ya;G[c+1056>>2]=N;kb(88478,c+1056|0);$a(X)}i=L[a+80>>3];j=L[a+88>>3];hb(85307,12,1,d);hb(86411,14,1,d);f=j/h;j=+(N<<1);o=f+j;Aa:{if(O(o)<2147483648){b=~~o;break Aa}b=-2147483648}e=i>h*+(b|0)?b+2|0:b;j=i/h+j;Ba:{if(O(j)<2147483648){b=~~j;break Ba}b=-2147483648}w=i>h*+(b|0)?b+2|0:b;Ca:{if((g|0)==-1){hb(86498,12,1,d);break Ca}G[c+1040>>2]=g;_a(d,75597,c+1040|0)}G[c+1024>>2]=w;_a(d,75530,c+1024|0);G[c+1008>>2]=e;_a(d,75516,c+1008|0);n=3;b=0;Da:{if((g|0)>=3){G[c+992>>2]=V;_a(d,75502,c+992|0);if((g|0)==3){break Da}G[c+976>>2]=K;_a(d,75488,c+976|0);b=1}n=g}if(za){hb(89960,21,1,d);hb(89938,21,1,d);L[c+960>>3]=q;xb(d,70545,c+960|0)}if(Aa){hb(89960,21,1,d);hb(89938,21,1,d);L[c+944>>3]=q;xb(d,70545,c+944|0)}if(Oa){hb(89916,21,1,d);hb(89850,21,1,d);L[c+928>>3]=q;xb(d,70545,c+928|0)}if(Ba){hb(89916,21,1,d);hb(89850,21,1,d);L[c+912>>3]=q;xb(d,70545,c+912|0)}if(P){hb(89894,21,1,d);hb(89828,21,1,d)}if(Pa){hb(89872,21,1,d);hb(89806,21,1,d)}L[c+896>>3]=L[a+64>>3];xb(d,71373,c+896|0);L[c+880>>3]=L[a+72>>3];xb(d,71319,c+880|0);if((g|0)>=3){L[c+864>>3]=R;xb(d,71283,c+864|0)}if(b){L[c+848>>3]=T;xb(d,71229,c+848|0)}i=+(w|0);L[c+832>>3]=(i+1)*.5;xb(d,72266,c+832|0);j=+(e|0);L[c+816>>3]=(j+1)*.5;xb(d,72248,c+816|0);if((g|0)>=3){L[c+800>>3]=A;xb(d,71247,c+800|0)}if(b){L[c+784>>3]=z;xb(d,71193,c+784|0)}L[c+768>>3]=-h;xb(d,71355,c+768|0);L[c+752>>3]=h;xb(d,71301,c+752|0);if((g|0)>=3){L[c+736>>3]=S;xb(d,71265,c+736|0)}if(b){L[c+720>>3]=U;xb(d,71211,c+720|0)}L[c+704>>3]=L[a+96>>3];xb(d,71337,c+704|0);hb(85385,4,1,d);$a(d);Hb(d);r=0;b=Fa-84112|0;Fa=b;Ea:{Fa:{K=ac(Na,13287);if(K){E[b+16|0]=0;V=G[29763];while(1){if(vc(b+80016|0,4096,K)){g=(Va(b+80016|0)+b|0)+80015|0;if(H[g|0]==10){E[g|0]=0}g=(Va(b+80016|0)+b|0)+80015|0;if(H[g|0]==13){E[g|0]=0}if(G[935722]>=3){G[b>>2]=b+80016;kb(76800,b);$a(V)}p=Va(b+16|0);g=Va(b+80016|0);Ga:{if((g|0)>0){bb(p+(b+16|0)|0,b+80016|0,g);if(g>>>0>79){break Ga}}cb(b+16+(g+p)|0,32,80-g|0)}E[(b+p|0)+96|0]=0;r=r+1|0;if((r|0)!=1e3){continue}}break}g=rd(b+16|0);G[935754]=g;if(!g){break Fa}Fa=b+84112|0;break Ea}hb(84323,54,1,G[321435]);break a}hb(84378,54,1,G[321435]);break a}b=c+3032|0;g=c+3024|0;cc(G[935754],.5,.5,b,g);L[m>>3]=L[c+3032>>3];L[l>>3]=L[c+3024>>3];o=i+.5;cc(G[935754],o,.5,b,g);L[m+8>>3]=L[c+3032>>3];L[l+8>>3]=L[c+3024>>3];f=o;o=j+.5;cc(G[935754],f,o,b,g);L[m+16>>3]=L[c+3032>>3];L[l+16>>3]=L[c+3024>>3];cc(G[935754],.5,o,b,g);o=L[c+3032>>3];L[m+24>>3]=o;f=L[c+3024>>3];L[l+24>>3]=f;if(G[935722]!=1){E[c+3056|0]=0;Ha:{if((n|0)>=0){x=L[l+16>>3];y=L[m+16>>3];z=L[l+8>>3];A=L[m+8>>3];R=L[l>>3];S=L[m>>3];T=L[a+96>>3];U=L[a+72>>3];L[c+592>>3]=L[a+64>>3];L[c+600>>3]=U;L[c+608>>3]=h*i;L[c+616>>3]=h*j;L[c+624>>3]=T;L[c+632>>3]=S;L[c+640>>3]=R;L[c+648>>3]=A;L[c+656>>3]=z;L[c+664>>3]=y;L[c+672>>3]=x;L[c+680>>3]=o;L[c+688>>3]=f;G[c+576>>2]=Q;G[c+580>>2]=wa;G[c+584>>2]=w;G[c+588>>2]=e;xb(G[321435],77424,c+576|0);break Ha}b=c+3056|0;bb(b,42312,77);o=L[l+24>>3];f=L[m+24>>3];x=L[l+16>>3];y=L[m+16>>3];z=L[l+8>>3];A=L[m+8>>3];R=L[l>>3];S=L[m>>3];T=L[a+96>>3];U=L[a+72>>3];k=L[a+64>>3];G[c+464>>2]=e;L[c+472>>3]=k;L[c+480>>3]=U;L[c+488>>3]=h*i;L[c+496>>3]=h*j;L[c+504>>3]=T;L[c+512>>3]=S;L[c+520>>3]=R;L[c+528>>3]=A;L[c+536>>3]=z;L[c+544>>3]=y;L[c+552>>3]=x;L[c+560>>3]=f;L[c+568>>3]=o;G[c+452>>2]=Q;G[c+456>>2]=wa;G[c+460>>2]=w;a=G[321435];G[c+448>>2]=b;xb(a,77201,c+448|0)}$a(X)}break b}hb(83649,57,1,G[321435])}$a(X);break a}$a(G[321435]);Hb(G[321435]);sc(0);W()}$a(G[321435]);Hb(G[321435]);sc(1);W()}function Ch(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0;r=Fa-16|0;Fa=r;x=-2;a:{if(!G[a+36>>2]|(!a|!G[a+32>>2])){break a}f=G[a+28>>2];if(!f|G[f>>2]!=(a|0)){break a}g=G[f+4>>2];if(g-16180>>>0>31){break a}o=G[a+12>>2];if(!o){break a}c=G[a>>2];if(!(G[a+4>>2]?c:1)){break a}if((g|0)==16191){G[f+4>>2]=16192;g=16192}O=f+92|0;z=f+756|0;A=f+116|0;D=f+88|0;B=f+112|0;y=f+1332|0;d=G[f+64>>2];C=G[a+4>>2];h=C;e=G[f+60>>2];l=G[a+16>>2];t=l;b:{c:{d:while(1){e:{b=-3;i=1;f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{p:{q:{r:{s:{t:{u:{v:{w:{x:{y:{z:{A:{B:{C:{D:{E:{F:{G:{H:{I:{J:{K:{L:{M:{N:{O:{P:{Q:{R:{S:{T:{U:{V:{W:{X:{Y:{Z:{_:{$:{aa:{ba:{ca:{da:{ea:{fa:{ga:{ha:{ia:{ja:{ka:{la:{ma:{switch(g-16180|0){case 23:m=G[f+76>>2];b=c;g=h;break A;case 21:i=G[f+76>>2];break C;case 18:g=G[f+108>>2];break L;case 27:g=G[f+12>>2];break f;case 16:if(d>>>0>=14){break U}if(!h){break e}b=d+8|0;g=c+1|0;i=h-1|0;e=(H[c|0]<>>0<=5){break V}c=g;h=i;d=b;break U;case 9:if(d>>>0>=32){break $}if(!h){break e}b=c+1|0;g=h-1|0;e=(H[c|0]<>>0<=23){break aa}c=b;h=g;break $;case 1:if(d>>>0>=16){break ka}if(!h){break e}b=d+8|0;g=c+1|0;i=h-1|0;e=(H[c|0]<>>0<=7){break la}c=g;h=i;d=b;break ka;case 8:break j;case 7:break k;case 6:break l;case 5:break m;case 24:break z;case 22:break B;case 20:break J;case 19:break K;case 30:break b;case 26:break Q;case 25:break R;case 17:break T;case 29:break c;case 15:break W;case 14:break X;case 13:break Y;case 11:case 12:break Z;case 10:break _;case 4:break da;case 3:break ga;case 2:break ja;case 0:break ma;case 28:break g;default:break a}}k=G[f+12>>2];if(!k){break P}na:{if(d>>>0>=16){break na}if(!h){break e}b=d+8|0;g=c+1|0;i=h-1|0;e=(H[c|0]<>>0>7){c=g;h=i;d=b;break na}if(!i){c=g;h=0;d=b;b=n;break c}d=d+16|0;h=h-2|0;e=(H[c+1|0]<>2]){G[f+40>>2]=15}e=0;d=Oc(0,0,0);G[f+28>>2]=d;E[r+12|0]=31;E[r+13|0]=139;W=f,X=Oc(d,r+12|0,2),G[W+28>>2]=X;G[f+4>>2]=16181;d=0;g=G[f+4>>2];continue}G[f+20>>2]=0;b=G[f+36>>2];if(b){G[b+48>>2]=-1}if(!(((e<<8&65280)+(e>>>8|0)>>>0)%31|0?0:k&1)){G[a+24>>2]=17233;G[f+4>>2]=16209;g=G[f+4>>2];continue}if((e&15)!=8){G[a+24>>2]=26035;G[f+4>>2]=16209;g=G[f+4>>2];continue}g=e>>>4|0;k=g&15;i=k+8|0;j=k>>>0<=7;b=G[f+40>>2];if(!b){G[f+40>>2]=i;b=i}if(!(b>>>0>=i>>>0&j)){d=d-4|0;G[a+24>>2]=19724;G[f+4>>2]=16209;e=g;g=G[f+4>>2];continue}G[f+24>>2]=256<>2]=b;G[a+48>>2]=b;G[f+4>>2]=e&8192?16189:16191;e=0;g=G[f+4>>2];continue}if(!i){c=g;h=0;d=b;b=n;break c}d=d+16|0;h=h-2|0;e=(H[c+1|0]<>2]=e;if((e&255)!=8){G[a+24>>2]=26035;G[f+4>>2]=16209;g=G[f+4>>2];continue}if(e&57344){G[a+24>>2]=5085;G[f+4>>2]=16209;g=G[f+4>>2];continue}d=G[f+36>>2];if(d){G[d>>2]=e>>>8&1}if(!(!(e&512)|!(H[f+12|0]&4))){E[r+12|0]=e;E[r+13|0]=e>>>8;W=f,X=Oc(G[f+28>>2],r+12|0,2),G[W+28>>2]=X}G[f+4>>2]=16182;d=0;e=0;break ia}if(d>>>0>31){break ha}}if(!h){break e}b=c+1|0;g=h-1|0;e=(H[c|0]<>>0>23){c=b;h=g;break ha}i=d+8|0;if(!g){c=b;h=0;d=i;b=n;break c}b=c+2|0;g=h-2|0;e=(H[c+1|0]<>>0>15){c=b;h=g;break ha}i=d+16|0;if(!g){c=b;h=0;d=i;b=n;break c}b=c+3|0;g=h-3|0;e=(H[c+2|0]<>>0>7){c=b;h=g;break ha}d=d+24|0;if(!g){c=b;h=0;b=n;break c}h=h-4|0;e=(H[c+3|0]<>2];if(d){G[d+4>>2]=e}if(!(!(H[f+21|0]&2)|!(H[f+12|0]&4))){E[r+12|0]=e;E[r+13|0]=e>>>8;E[r+14|0]=e>>>16;E[r+15|0]=e>>>24;W=f,X=Oc(G[f+28>>2],r+12|0,4),G[W+28>>2]=X}G[f+4>>2]=16183;d=0;e=0;break fa}if(d>>>0>15){break ea}}if(!h){break e}b=c+1|0;g=h-1|0;e=(H[c|0]<>>0>7){c=b;h=g;break ea}d=d+8|0;if(!g){c=b;h=0;b=n;break c}h=h-2|0;e=(H[c+1|0]<>2];if(d){G[d+12>>2]=e>>>8;G[d+8>>2]=e&255}if(!(!(H[f+21|0]&2)|!(H[f+12|0]&4))){E[r+12|0]=e;E[r+13|0]=e>>>8;W=f,X=Oc(G[f+28>>2],r+12|0,2),G[W+28>>2]=X}G[f+4>>2]=16184;g=0;d=0;e=0;b=G[f+20>>2];if(b&1024){break ca}break o}b=G[f+20>>2];if(!(b&1024)){g=d;break o}g=e;if(d>>>0>15){break ba}}if(!h){h=0;e=g;b=n;break c}i=c+1|0;k=h-1|0;e=(H[c|0]<>>0>7){c=i;h=k;break ba}d=d+8|0;if(!k){c=i;h=0;b=n;break c}h=h-2|0;e=(H[c+1|0]<>2]=e;d=G[f+36>>2];if(d){G[d+20>>2]=e}d=0;if(!(!(b&512)|!(H[f+12|0]&4))){E[r+12|0]=e;E[r+13|0]=e>>>8;W=f,X=Oc(G[f+28>>2],r+12|0,2),G[W+28>>2]=X}e=0;break n}i=d+8|0;if(!g){c=b;h=0;d=i;b=n;break c}b=c+2|0;g=h-2|0;e=(H[c+1|0]<>>0>15){c=b;h=g;break $}i=d+16|0;if(!g){c=b;h=0;d=i;b=n;break c}b=c+3|0;g=h-3|0;e=(H[c+2|0]<>>0>7){c=b;h=g;break $}d=d+24|0;if(!g){c=b;h=0;b=n;break c}h=h-4|0;e=(H[c+3|0]<>>8&65280|e>>>24);G[f+28>>2]=d;G[a+48>>2]=d;G[f+4>>2]=16190;e=0;d=0}if(!G[f+16>>2]){G[a+16>>2]=l;G[a+12>>2]=o;G[a+4>>2]=h;G[a>>2]=c;G[f+64>>2]=d;G[f+60>>2]=e;x=2;break a}b=gf(0,0,0);G[f+28>>2]=b;G[a+48>>2]=b;G[f+4>>2]=16191}oa:{pa:{if(!G[f+8>>2]){if(d>>>0<3){break pa}break oa}G[f+4>>2]=16206;e=e>>>(d&7)|0;d=d&-8;g=G[f+4>>2];continue}if(!h){break e}h=h-1|0;e=(H[c|0]<>2]=e&1;g=16193;qa:{ra:{sa:{switch((e>>>1&3)-1|0){case 0:G[f+80>>2]=113520;G[f+88>>2]=9;G[f+92>>2]=5;G[f+84>>2]=115568;G[f+4>>2]=16199;break qa;case 1:g=16196;break ra;case 2:break sa;default:break ra}}G[a+24>>2]=21052;g=16209}G[f+4>>2]=g}d=d-3|0;e=e>>>3|0;g=G[f+4>>2];continue}e=e>>>(d&7)|0;d=d&-8;ta:{if(d>>>0>31){break ta}if(!h){break e}b=d+8|0;g=c+1|0;i=h-1|0;e=(H[c|0]<>>0>23){c=g;h=i;d=b;break ta}if(!i){c=g;h=0;d=b;b=n;break c}g=d+16|0;i=c+2|0;k=h-2|0;e=(H[c+1|0]<>>0>15){c=i;h=k;d=g;break ta}if(!k){c=i;h=0;d=g;b=n;break c}b=d+24|0;i=c+3|0;k=h-3|0;e=(H[c+2|0]<>>16|0)){G[a+24>>2]=7070;G[f+4>>2]=16209;g=G[f+4>>2];continue}G[f+4>>2]=16194;G[f+68>>2]=b;e=0;d=0}G[f+4>>2]=16195}b=G[f+68>>2];if(b){b=b>>>0>>0?b:h;b=b>>>0>>0?b:l;if(!b){break h}g=bb(o,c,b);G[f+68>>2]=G[f+68>>2]-b;o=b+g|0;l=l-b|0;c=b+c|0;h=h-b|0;g=G[f+4>>2];continue}G[f+4>>2]=16191;g=G[f+4>>2];continue}if(!i){c=g;h=0;d=b;b=n;break c}d=d+16|0;h=h-2|0;e=(H[c+1|0]<>2]=b+257;g=e>>>5&31;G[f+104>>2]=g+1;k=(e>>>10&15)+4|0;G[f+96>>2]=k;d=d-14|0;e=e>>>14|0;if(!(g>>>0<30&b>>>0<=29)){G[a+24>>2]=6875;G[f+4>>2]=16209;g=G[f+4>>2];continue}G[f+4>>2]=16197;g=0;G[f+108>>2]=0;break S}g=G[f+108>>2];k=G[f+96>>2];if(g>>>0>=k>>>0){break M}}b=g;while(1){if(d>>>0<=2){if(!h){break e}h=h-1|0;e=(H[c|0]<>2]=g;F[((I[(b<<1)+113472>>1]<<1)+f|0)+116>>1]=e&7;d=d-3|0;e=e>>>3|0;b=g;if(k>>>0>b>>>0){continue}break}break M}if(!l){break y}E[o|0]=G[f+68>>2];G[f+4>>2]=16200;l=l-1|0;o=o+1|0;g=G[f+4>>2];continue}g=G[f+12>>2];if(!g){g=0;break N}ua:{if(d>>>0>31){i=c;break ua}if(!h){break e}b=d+8|0;i=c+1|0;k=h-1|0;e=(H[c|0]<>>0>23){h=k;d=b;break ua}if(!k){c=i;h=0;d=b;b=n;break c}k=d+16|0;i=c+2|0;j=h-2|0;e=(H[c+1|0]<>>0>15){h=j;d=k;break ua}if(!j){c=i;h=0;d=k;b=n;break c}b=d+24|0;i=c+3|0;j=h-3|0;e=(H[c+2|0]<>>0>7){h=j;d=b;break ua}if(!j){c=i;h=0;d=b;b=n;break c}d=d+32|0;i=c+4|0;h=h-4|0;e=(H[c+3|0]<>2]=c+G[a+20>>2];G[f+32>>2]=c+G[f+32>>2];b=g&4;if(!(!b|(l|0)==(t|0))){b=o-c|0;g=G[f+28>>2];va:{if(G[f+20>>2]){c=Oc(g,b,c);break va}c=gf(g,b,c)}G[f+28>>2]=c;G[a+48>>2]=c;g=G[f+12>>2];b=g&4}if(!b|G[f+28>>2]==((G[f+20>>2]?e:e<<8&16711680|e<<24|(e>>>8&65280|e>>>24))|0)){break O}G[a+24>>2]=17279;G[f+4>>2]=16209;c=i;t=l;g=G[f+4>>2];continue}G[f+4>>2]=16192;break q}c=i;e=0;d=0;t=l}G[f+4>>2]=16207;break f}if(g>>>0<=18){i=0;b=g;n=3-b&3;if(n){while(1){F[((I[(b<<1)+113472>>1]<<1)+f|0)+116>>1]=0;b=b+1|0;i=i+1|0;if((n|0)!=(i|0)){continue}break}}if(g-16>>>0>=3){while(1){n=f+116|0;g=b<<1;F[n+(I[g+113472>>1]<<1)>>1]=0;F[n+(I[g+113474>>1]<<1)>>1]=0;F[n+(I[g+113476>>1]<<1)>>1]=0;F[n+(I[g+113478>>1]<<1)>>1]=0;b=b+4|0;if((b|0)!=19){continue}break}}G[f+108>>2]=19}G[f+88>>2]=7;G[f+80>>2]=y;G[f+112>>2]=y;g=0;n=Pk(0,A,19,B,D,z);if(n){G[a+24>>2]=5060;G[f+4>>2]=16209;g=G[f+4>>2];continue}G[f+4>>2]=16198;G[f+108>>2]=0;n=0}w=G[f+100>>2];s=w+G[f+104>>2]|0;if(s>>>0>g>>>0){u=-1<>2]^-1;q=G[f+80>>2];while(1){m=d;i=h;k=c;p=e&u;j=H[(q+(p<<2)|0)+1|0];wa:{if(j>>>0<=d>>>0){b=d;break wa}while(1){if(!i){break I}j=H[k|0]<>>0>b>>>0){continue}break}c=k;h=i}d=I[(q+(p<<2)|0)+2>>1];xa:{if(d>>>0<=15){i=g+1|0;G[f+108>>2]=i;F[((g<<1)+f|0)+116>>1]=d;d=b-j|0;e=e>>>j|0;g=i;break xa}ya:{za:{Aa:{switch(d-16|0){case 0:d=j+2|0;if(d>>>0>b>>>0){while(1){if(!h){break p}h=h-1|0;e=(H[c|0]<>>0>b>>>0){continue}break}}d=b-j|0;b=e>>>j|0;if(!g){G[a+24>>2]=5255;G[f+4>>2]=16209;e=b;g=G[f+4>>2];continue d}d=d-2|0;e=b>>>2|0;i=(b&3)+3|0;b=I[((g<<1)+f|0)+114>>1];break ya;case 1:d=j+3|0;if(d>>>0>b>>>0){while(1){if(!h){break p}h=h-1|0;e=(H[c|0]<>>0>b>>>0){continue}break}}d=(b-j|0)-3|0;b=e>>>j|0;e=b>>>3|0;i=(b&7)+3|0;break za;default:break Aa}}d=j+7|0;if(d>>>0>b>>>0){while(1){if(!h){break p}h=h-1|0;e=(H[c|0]<>>0>b>>>0){continue}break}}d=(b-j|0)-7|0;b=e>>>j|0;e=b>>>7|0;i=(b&127)+11|0}b=0}if(s>>>0>>0){break F}j=i-1|0;k=0;m=i&3;if(m){while(1){F[((g<<1)+f|0)+116>>1]=b;g=g+1|0;i=i-1|0;k=k+1|0;if((m|0)!=(k|0)){continue}break}}if(j>>>0>=3){while(1){k=(g<<1)+f|0;F[k+118>>1]=b;F[k+116>>1]=b;F[k+120>>1]=b;F[k+122>>1]=b;g=g+4|0;i=i-4|0;if(i){continue}break}}G[f+108>>2]=g}if(g>>>0>>0){continue}break}}if(!I[f+628>>1]){G[a+24>>2]=17150;G[f+4>>2]=16209;g=G[f+4>>2];continue}G[f+88>>2]=9;G[f+80>>2]=y;G[f+112>>2]=y;n=Pk(1,A,w,B,D,z);if(n){G[a+24>>2]=5032;G[f+4>>2]=16209;g=G[f+4>>2];continue}G[f+92>>2]=6;G[f+84>>2]=G[f+112>>2];n=Pk(2,(G[f+100>>2]<<1)+A|0,G[f+104>>2],B,O,z);if(n){G[a+24>>2]=5110;G[f+4>>2]=16209;g=G[f+4>>2];continue}G[f+4>>2]=16199;n=0}G[f+4>>2]=16200}if(!(h>>>0<6|l>>>0<258)){G[a+16>>2]=l;G[a+12>>2]=o;G[a+4>>2]=h;G[a>>2]=c;G[f+64>>2]=d;G[f+60>>2]=e;e=G[a+12>>2];d=G[a+16>>2];c=e+d|0;s=c+(t^-1)|0;m=G[a+28>>2];o=G[m+52>>2];P=(c+(o^-1)|0)-t|0;u=o&7;K=G[m+44>>2];Q=o+K|0;w=c-257|0;R=(d-t|0)+e|0;g=G[a>>2];L=(g+G[a+4>>2]|0)-5|0;S=-1<>2]^-1;T=-1<>2]^-1;M=G[m+84>>2];N=G[m+80>>2];h=G[m+64>>2];j=G[m+60>>2];k=G[m+56>>2];U=G[m+48>>2];V=o-1>>>0<7;while(1){if(h>>>0<=14){j=((H[g|0]<>>c|0;c=I[d+2>>1];Ba:{Ca:{Da:{b=H[d|0];if(!b){break Da}Ea:{Fa:{Ga:{while(1){if(b&16){l=c&65535;c=b&15;Ha:{if(!c){d=g;b=j;break Ha}Ia:{if(c>>>0<=h>>>0){b=h;break Ia}b=h+8|0;j=(H[g|0]<>>c|0}if(h>>>0<=14){b=((H[d|0]<>>c|0;c=I[g+2>>1];b=H[g|0];if(b&16){break Ga}while(1){if(!(b&64)){b=(((-1<>>c|0;c=I[b+2>>1];b=H[b|0];if(!(b&16)){continue}break Ga}break}l=25378;g=d;break Fa}d=b&255;if(!(d&64)){d=(((-1<>>c|0;c=I[d+2>>1];b=H[d|0];if(!b){break Da}continue}break}l=25322;c=16191;if(b&32){break Ea}break Fa}p=c&65535;b=b&15;Ja:{if(b>>>0<=h>>>0){c=h;g=d;break Ja}j=(H[d|0]<>>0<=c>>>0){break Ja}j=(H[d+1|0]<>>b|0;Ka:{q=d+p|0;c=e-R|0;if(q>>>0>c>>>0){i=q-c|0;if(!(!G[m+7108>>2]|i>>>0<=U>>>0)){l=17312;break Fa}La:{Ma:{if(!o){b=k+(K-i|0)|0;if(i>>>0>=l>>>0){break La}p=(p+(d+s|0)|0)-e|0;d=0;c=i;v=c&7;if(v){while(1){E[e|0]=H[b|0];c=c-1|0;e=e+1|0;b=b+1|0;d=d+1|0;if((v|0)!=(d|0)){continue}break}}if(p>>>0<7){break Ma}while(1){E[e|0]=H[b|0];E[e+1|0]=H[b+1|0];E[e+2|0]=H[b+2|0];E[e+3|0]=H[b+3|0];E[e+4|0]=H[b+4|0];E[e+5|0]=H[b+5|0];E[e+6|0]=H[b+6|0];E[e+7|0]=H[b+7|0];e=e+8|0;b=b+8|0;c=c-8|0;if(c){continue}break}break Ma}if(i>>>0>o>>>0){b=k+(Q-i|0)|0;i=i-o|0;if(i>>>0>=l>>>0){break La}p=(p+(d+P|0)|0)-e|0;d=0;c=i;v=c&7;if(v){while(1){E[e|0]=H[b|0];c=c-1|0;e=e+1|0;b=b+1|0;d=d+1|0;if((v|0)!=(d|0)){continue}break}}if(p>>>0>=7){while(1){E[e|0]=H[b|0];E[e+1|0]=H[b+1|0];E[e+2|0]=H[b+2|0];E[e+3|0]=H[b+3|0];E[e+4|0]=H[b+4|0];E[e+5|0]=H[b+5|0];E[e+6|0]=H[b+6|0];E[e+7|0]=H[b+7|0];e=e+8|0;b=b+8|0;c=c-8|0;if(c){continue}break}}l=l-i|0;if(o>>>0>=l>>>0){b=k;break La}d=0;c=o;b=k;if(u){while(1){E[e|0]=H[b|0];c=c-1|0;e=e+1|0;b=b+1|0;d=d+1|0;if((u|0)!=(d|0)){continue}break}}if(!V){while(1){E[e|0]=H[b|0];E[e+1|0]=H[b+1|0];E[e+2|0]=H[b+2|0];E[e+3|0]=H[b+3|0];E[e+4|0]=H[b+4|0];E[e+5|0]=H[b+5|0];E[e+6|0]=H[b+6|0];E[e+7|0]=H[b+7|0];e=e+8|0;b=b+8|0;c=c-8|0;if(c){continue}break}}b=e-q|0;l=l-o|0;break La}b=k+(o-i|0)|0;if(i>>>0>=l>>>0){break La}p=(p+(d+s|0)|0)-e|0;d=0;c=i;v=c&7;if(v){while(1){E[e|0]=H[b|0];c=c-1|0;e=e+1|0;b=b+1|0;d=d+1|0;if((v|0)!=(d|0)){continue}break}}if(p>>>0<7){break Ma}while(1){E[e|0]=H[b|0];E[e+1|0]=H[b+1|0];E[e+2|0]=H[b+2|0];E[e+3|0]=H[b+3|0];E[e+4|0]=H[b+4|0];E[e+5|0]=H[b+5|0];E[e+6|0]=H[b+6|0];E[e+7|0]=H[b+7|0];e=e+8|0;b=b+8|0;c=c-8|0;if(c){continue}break}}b=e-q|0;l=l-i|0}Na:{if(l>>>0<3){break Na}c=0;d=l-3|0;i=((d>>>0)/3|0)+1&3;if(i){while(1){E[e|0]=H[b|0];E[e+1|0]=H[b+1|0];E[e+2|0]=H[b+2|0];l=l-3|0;e=e+3|0;b=b+3|0;c=c+1|0;if((i|0)!=(c|0)){continue}break}}if(d>>>0<9){break Na}while(1){E[e|0]=H[b|0];E[e+1|0]=H[b+1|0];E[e+2|0]=H[b+2|0];E[e+3|0]=H[b+3|0];E[e+4|0]=H[b+4|0];E[e+5|0]=H[b+5|0];E[e+6|0]=H[b+6|0];E[e+7|0]=H[b+7|0];E[e+8|0]=H[b+8|0];E[e+9|0]=H[b+9|0];E[e+10|0]=H[b+10|0];E[e+11|0]=H[b+11|0];e=e+12|0;b=b+12|0;l=l-12|0;if(l>>>0>2){continue}break}}if(!l){break Ca}E[e|0]=H[b|0];if((l|0)!=1){break Ka}e=e+1|0;break Ca}d=e-q|0;while(1){c=e;b=d;E[e|0]=H[b|0];E[e+1|0]=H[b+1|0];E[e+2|0]=H[b+2|0];e=e+3|0;d=b+3|0;l=l-3|0;if(l>>>0>2){continue}break}if(!l){break Ca}E[c+3|0]=H[d|0];if((l|0)==1){e=c+4|0;break Ca}E[c+4|0]=H[b+4|0];e=c+5|0;break Ca}E[e+1|0]=H[b+1|0];e=e+2|0;break Ca}G[a+24>>2]=l;c=16209}G[m+4>>2]=c;break Ba}E[e|0]=c;e=e+1|0}if(g>>>0>=L>>>0){break Ba}if(e>>>0>>0){continue}}break}G[a+12>>2]=e;c=g-(h>>>3|0)|0;G[a>>2]=c;G[a+16>>2]=(w-e|0)+257;G[a+4>>2]=(L-c|0)+5;c=h&7;G[m+64>>2]=c;G[m+60>>2]=(-1<>2];e=G[f+60>>2];h=G[a+4>>2];c=G[a>>2];l=G[a+16>>2];o=G[a+12>>2];if(G[f+4>>2]!=16191){break q}G[f+7112>>2]=-1;g=G[f+4>>2];continue}G[f+7112>>2]=0;i=d;g=h;b=c;s=G[f+80>>2];p=-1<>2]^-1;j=s+((p&e)<<2)|0;m=H[j+1|0];Oa:{if(m>>>0<=d>>>0){k=d;break Oa}while(1){if(!g){break G}j=H[b|0]<>>0>>0){continue}break}}p=I[j+2>>1];i=H[j|0];if(!i|i&240){break E}h=g;c=b;d=k;u=-1<>>m|0)+p<<2)|0;j=H[q+1|0];Pa:{if(d>>>0>=m+j>>>0){i=k;break Pa}while(1){if(!h){break H}j=H[c|0]<>>m|0)+p<<2)|0;j=H[q+1|0];if(d>>>0>>0){continue}break}}k=i-m|0;e=e>>>m|0;i=H[q|0];p=I[q+2>>1];break D}c=c+h|0;d=(h<<3)+d|0;break e}c=b+g|0;d=(g<<3)+k|0;break e}c=c+h|0;d=(h<<3)+d|0;break e}G[a+24>>2]=5255;G[f+4>>2]=16209;g=G[f+4>>2];continue}j=m;m=0;c=b;h=g}G[f+68>>2]=p&65535;G[f+7112>>2]=j+m;d=k-j|0;e=e>>>j|0;if(!i){G[f+4>>2]=16205;g=G[f+4>>2];continue}if(i&32){G[f+4>>2]=16191;G[f+7112>>2]=-1;g=G[f+4>>2];continue}if(i&64){G[a+24>>2]=25322;G[f+4>>2]=16209;g=G[f+4>>2];continue}G[f+4>>2]=16201;i=i&15;G[f+76>>2]=i}j=c;k=h;Qa:{if(!i){b=G[f+68>>2];break Qa}g=d;b=c;if(d>>>0>>0){while(1){if(!h){break t}h=h-1|0;e=(H[b|0]<>>0>g>>>0){continue}break}}G[f+7112>>2]=G[f+7112>>2]+i;b=G[f+68>>2]+((-1<>2]=b;d=g-i|0;e=e>>>i|0}G[f+4>>2]=16202;G[f+7116>>2]=b}i=d;g=h;b=c;s=G[f+84>>2];p=-1<>2]^-1;j=s+((p&e)<<2)|0;m=H[j+1|0];Ra:{if(m>>>0<=d>>>0){k=d;break Ra}while(1){if(!g){break u}j=H[b|0]<>>0>>0){continue}break}}p=I[j+2>>1];j=H[j|0];Sa:{if(j&240){i=m;c=G[f+7112>>2];break Sa}h=g;c=b;d=k;u=-1<>>m|0)+p<<2)|0;i=H[q+1|0];Ta:{if(d>>>0>=m+i>>>0){j=k;break Ta}while(1){if(!h){break v}i=H[c|0]<>>m|0)+p<<2)|0;i=H[q+1|0];if(d>>>0>>0){continue}break}b=c;g=h}k=j-m|0;e=e>>>m|0;j=H[q|0];p=I[q+2>>1];c=G[f+7112>>2]+m|0}G[f+7112>>2]=c+i;d=k-i|0;e=e>>>i|0;if(j&64){G[a+24>>2]=25378;G[f+4>>2]=16209;c=b;h=g;g=G[f+4>>2];continue}G[f+4>>2]=16203;m=j&15;G[f+76>>2]=m;G[f+72>>2]=p&65535}Ua:{if(!m){c=b;h=g;break Ua}i=d;h=g;k=b;Va:{if(d>>>0>=m>>>0){c=b;break Va}while(1){if(!h){break w}h=h-1|0;e=(H[k|0]<>>0>i>>>0){continue}break}}G[f+7112>>2]=G[f+7112>>2]+m;G[f+72>>2]=G[f+72>>2]+((-1<>>m|0}G[f+4>>2]=16204}if(l){break x}}l=0;break h}b=G[f+72>>2];g=t-l|0;Wa:{if(b>>>0>g>>>0){b=b-g|0;if(!(!G[f+7108>>2]|b>>>0<=J[f+48>>2])){G[a+24>>2]=17312;G[f+4>>2]=16209;g=G[f+4>>2];continue}g=G[f+52>>2];Xa:{if(g>>>0>>0){b=b-g|0;g=G[f+56>>2]+(G[f+44>>2]-b|0)|0;break Xa}g=G[f+56>>2]+(g-b|0)|0}i=G[f+68>>2];b=b>>>0>>0?b:i;break Wa}g=o-b|0;i=G[f+68>>2];b=i}k=b>>>0>>0?b:l;G[f+68>>2]=i-k;j=k-1|0;i=0;m=k&7;if(!m){break s}b=k;while(1){E[o|0]=H[g|0];b=b-1|0;o=o+1|0;g=g+1|0;i=i+1|0;if((m|0)!=(i|0)){continue}break}break r}c=b+g|0;d=(g<<3)+d|0;break e}c=b+g|0;d=(g<<3)+k|0;break e}c=c+h|0;d=(h<<3)+d|0;break e}c=k+j|0;d=(k<<3)+d|0;break e}b=k}if(j>>>0>=7){while(1){E[o|0]=H[g|0];E[o+1|0]=H[g+1|0];E[o+2|0]=H[g+2|0];E[o+3|0]=H[g+3|0];E[o+4|0]=H[g+4|0];E[o+5|0]=H[g+5|0];E[o+6|0]=H[g+6|0];E[o+7|0]=H[g+7|0];o=o+8|0;g=g+8|0;b=b-8|0;if(b){continue}break}}l=l-k|0;if(G[f+68>>2]){break q}G[f+4>>2]=16200;g=G[f+4>>2];continue}g=G[f+4>>2];continue}h=0;d=b;b=n;break c}d=G[f+36>>2];if(d){G[d+16>>2]=0}d=g}G[f+4>>2]=16185}i=G[f+20>>2];if(i&1024){g=G[f+68>>2];b=g>>>0>>0?g:h;if(b){k=G[f+36>>2];Ya:{if(!k){break Ya}j=G[k+16>>2];if(!j){break Ya}g=G[k+20>>2]-g|0;i=G[k+24>>2];bb(g+j|0,c,i>>>0>>0?i-g|0:b);i=G[f+20>>2]}if(!(!(i&512)|!(H[f+12|0]&4))){W=f,X=Oc(G[f+28>>2],c,b),G[W+28>>2]=X}g=G[f+68>>2]-b|0;G[f+68>>2]=g;h=h-b|0;c=b+c|0}if(g){break h}}G[f+4>>2]=16186;G[f+68>>2]=0}Za:{if(H[f+21|0]&8){g=0;if(!h){break i}while(1){b=H[c+g|0];i=G[f+36>>2];_a:{if(!i){break _a}k=G[i+28>>2];if(!k){break _a}j=G[i+32>>2];i=G[f+68>>2];if(j>>>0<=i>>>0){break _a}G[f+68>>2]=i+1;E[i+k|0]=b}g=g+1|0;if(h>>>0>g>>>0?b:0){continue}break}if(!(!(H[f+21|0]&2)|!(H[f+12|0]&4))){W=f,X=Oc(G[f+28>>2],c,g),G[W+28>>2]=X}c=c+g|0;h=h-g|0;if(!b){break Za}break h}b=G[f+36>>2];if(!b){break Za}G[b+28>>2]=0}G[f+4>>2]=16187;G[f+68>>2]=0}$a:{if(H[f+21|0]&16){g=0;if(!h){break i}while(1){b=H[c+g|0];i=G[f+36>>2];ab:{if(!i){break ab}k=G[i+36>>2];if(!k){break ab}j=G[i+40>>2];i=G[f+68>>2];if(j>>>0<=i>>>0){break ab}G[f+68>>2]=i+1;E[i+k|0]=b}g=g+1|0;if(h>>>0>g>>>0?b:0){continue}break}if(!(!(H[f+21|0]&2)|!(H[f+12|0]&4))){W=f,X=Oc(G[f+28>>2],c,g),G[W+28>>2]=X}c=c+g|0;h=h-g|0;if(!b){break $a}break h}b=G[f+36>>2];if(!b){break $a}G[b+36>>2]=0}G[f+4>>2]=16188}k=G[f+20>>2];if(k&512){bb:{if(d>>>0>15){g=c;break bb}if(!h){break e}b=d+8|0;g=c+1|0;i=h-1|0;e=(H[c|0]<>>0>7){h=i;d=b;break bb}if(!i){c=g;h=0;d=b;b=n;break c}d=d+16|0;g=c+2|0;h=h-2|0;e=(H[c+1|0]<>1]==(e|0))){G[a+24>>2]=17514;G[f+4>>2]=16209;c=g;g=G[f+4>>2];continue}e=0;d=0;c=g}b=G[f+36>>2];if(b){G[b+48>>2]=1;G[b+44>>2]=k>>>9&1}b=Oc(0,0,0);G[f+28>>2]=b;G[a+48>>2]=b;G[f+4>>2]=16191;g=G[f+4>>2];continue}h=0}i=n}b=i;break c}cb:{if(!(!g|!G[f+20>>2])){db:{if(d>>>0>31){g=c;break db}if(!h){break e}b=d+8|0;g=c+1|0;i=h-1|0;e=(H[c|0]<>>0>23){h=i;d=b;break db}if(!i){c=g;h=0;d=b;b=n;break c}i=d+16|0;g=c+2|0;k=h-2|0;e=(H[c+1|0]<>>0>15){h=k;d=i;break db}if(!k){c=g;h=0;d=i;b=n;break c}b=d+24|0;g=c+3|0;k=h-3|0;e=(H[c+2|0]<>>0>7){h=k;d=b;break db}if(!k){c=g;h=0;d=b;b=n;break c}d=d+32|0;g=c+4|0;h=h-4|0;e=(H[c+3|0]<>2]!=(e|0)){break cb}d=0;e=0;c=g}G[f+4>>2]=16208;b=1;break c}G[a+24>>2]=17256;G[f+4>>2]=16209;c=g;g=G[f+4>>2];continue}break}h=0;b=n}G[a+16>>2]=l;G[a+12>>2]=o;G[a+4>>2]=h;G[a>>2]=c;G[f+64>>2]=d;G[f+60>>2]=e;eb:{fb:{if(!G[f+44>>2]){if((l|0)==(t|0)|J[f+4>>2]>16208){break fb}}d=t-l|0;c=G[a+28>>2];g=G[c+56>>2];gb:{if(!g){n=1;g=Ja[G[a+32>>2]](G[a+40>>2],1<>2],1)|0;G[c+56>>2]=g;if(!g){break gb}}h=G[c+44>>2];if(!h){G[c+48>>2]=0;G[c+52>>2]=0;h=1<>2];G[c+44>>2]=h}hb:{if(d>>>0>=h>>>0){bb(g,o-h|0,h);G[c+52>>2]=0;break hb}i=h;h=G[c+52>>2];i=i-h|0;n=i>>>0>>0;g=g+h|0;h=n?i:d;bb(g,o-d|0,h);if(n){d=d-h|0;bb(G[c+56>>2],o-d|0,d);G[c+52>>2]=d;break hb}n=0;d=h+G[c+52>>2]|0;g=d;d=G[c+44>>2];G[c+52>>2]=(g|0)==(d|0)?0:g;g=d;d=G[c+48>>2];if(g>>>0<=d>>>0){break gb}G[c+48>>2]=d+h;break gb}G[c+48>>2]=G[c+44>>2];n=0}if(n){break eb}l=G[a+16>>2];h=G[a+4>>2]}G[a+8>>2]=G[a+8>>2]+(C-h|0);c=t-l|0;G[a+20>>2]=c+G[a+20>>2];G[f+32>>2]=c+G[f+32>>2];if(!(!(H[f+12|0]&4)|(l|0)==(t|0))){d=G[a+12>>2]-c|0;g=G[f+28>>2];ib:{if(G[f+20>>2]){c=Oc(g,d,c);break ib}c=gf(g,d,c)}G[f+28>>2]=c;G[a+48>>2]=c}c=a;a=G[f+4>>2];G[c+44>>2]=((G[f+64>>2]+((G[f+8>>2]!=0)<<6)|0)+(((a|0)==16191)<<7)|0)+((a|0)==16199?256:((a|0)==16194)<<8);x=(h|0)==(C|0)?(l|0)==(t|0)?b?b:-5:b:b;break a}G[f+4>>2]=16210}x=-4}Fa=r+16|0;return x}function Ij(a,b,c,d,e,f,g,h){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=N(0),z=0,A=0,B=0,C=0,D=0,F=0,I=0,J=0,P=0,Q=0,R=0,S=0,T=0,U=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0;i=Fa-4688|0;Fa=i;t=G[47542];u=31;a:{if(!di(g,3730,32901,i+2528|0)){break a}j=Eu(nc(i+2528|0,0,10)- -64|0,29);if(j>>>0>16){break a}u=G[(j<<2)+145260>>2]}if(di(g,19692,32736,i+2528|0)){t=nc(i+2528|0,0,10)}m=di(g,21827,35570,i+1504|0);G[i+3660>>2]=0;E[i+1408|0]=0;Cb(a,16,35394,i+1408|0,i+1312|0,i+3660|0);b:{c:{d:{if(!G[i+3660>>2]){if(!Xc(i+1408|0,32954)){break d}}G[i+3660>>2]=0;E[i+1408|0]=0;Cb(a,16,35693,i+1408|0,i+1312|0,i+3660|0);if(G[i+3660>>2]){break c}if((_b(i+1408|0)|0)<=0){break c}}u=h;g=0;j=0;m=Fa-48|0;Fa=m;G[m+12>>2]=92041;G[m+24>>2]=1;G[m+28>>2]=21073;e:{if(!a){G[u>>2]=1;a=0;break e}G[m+8>>2]=a;b=Fa-128|0;Fa=b;G[b+32>>2]=0;G[b+48>>2]=0;G[m+44>>2]=0;f:{g:{h:{i:{j:{d=G[m+8>>2];k:{l:{if(d){G[b+24>>2]=d;break l}d=b+24|0;h=G[m+12>>2];c=b+48|0;a=G[c>>2];if((a|0)<=0){G[c>>2]=-102;ch(d,h,0,c);a=G[c>>2]}if(a){break k}d=G[b+24>>2]}if(Dc(d,b+56|0,b+48|0)){break k}if(G[b+56>>2]&-3){G[b+16>>2]=G[m+12>>2];_a(G[24367],86885,b+16|0);g=1;break f}if(Ec(G[b+24>>2],33788,b+36|0,0,b+48|0)){break k}B=G[b+36>>2];g=ab(B<<2);l=G[b+24>>2];h=Fa-352|0;Fa=h;d=b+48|0;a=G[d>>2];m:{if((a|0)>0){break m}G[b+52>>2]=0;E[h+256|0]=0;s=qb(h+256|0,33788,74);t=Va(s);if(t){a=0;if((t|0)>0){while(1){k=a+s|0;c=E[k|0];E[k|0]=c-97>>>0<26?c&95:c;a=a+1|0;if((t|0)!=(a|0)){continue}break}}n:{if(G[d>>2]>0){a=G[l+4>>2];k=G[a+76>>2];break n}k=G[l>>2];a=G[l+4>>2];if((k|0)!=G[a+76>>2]){mb(l,k+1|0,0,d);a=G[l+4>>2];k=G[a+76>>2]}c=G[a+104>>2];j=G[a+96>>2]+(k<<3)|0;v=G[j>>2];j=Bu(c-v|0,G[a+108>>2]-(G[j+4>>2]+(c>>>0>>0)|0)|0,80,0)}c=G[l>>2];if((c|0)!=(k|0)){mb(l,c+1|0,0,d);a=G[l+4>>2];k=G[a+76>>2]}c=3;k=G[a+96>>2]+(k<<3)|0;v=G[k>>2]+160|0;k=G[k+4>>2];G[a+120>>2]=v;G[a+124>>2]=v>>>0<160?k+1|0:k;o:{p:{if((j|0)>=3){B=B+1|0;v=t+(h+160|0)|0;k=0;while(1){if((Jg(l,h+160|0,d)|0)>0){a=G[d>>2];break m}a=c;q:{if(fb(s,h+160|0,t)){break q}E[h+248|0]=0;x=jb(h+160|0,61);if(!x){break q}x=x-v|0;c=207;if((x|0)>=8){break o}c=qb(h+248|0,v,x);G[h+348>>2]=0;if((ue(c,h+344|0,h+348|0)|0)>0){break q}c=G[h+344>>2];if((c|0)>=(B|0)|(c|0)<=0){break q}c=h+80|0;mc(h+160|0,c,h,d);lk(c,(G[h+344>>2]-1<<2)+g|0,d);c=G[h+344>>2]-1|0;if((c|0)>=G[b+52>>2]){G[b+52>>2]=c+1}if(G[d>>2]!=204){break q}G[d>>2]=0;k=1}c=a+1|0;if((a|0)!=(j|0)){continue}break}if(k){break p}}a=G[d>>2];break m}a=G[d>>2];if((a|0)>0){break m}c=204}a=c;G[d>>2]=a;break m}a=G[d>>2]}Fa=h+352|0;if(a){break k}r:{s:{switch(G[b+56>>2]){case 0:d=0;a=G[b+52>>2];if((a|0)<=0){break j}while(1){p=G[(d<<2)+g>>2];if((p|0)<2){d=d+1|0;if((a|0)!=(d|0)){continue}break j}break};a=0;h=0;break r;case 2:break s;default:break j}}if(G[b+52>>2]>=2){a=G[g+4>>2];n=a;q=a>>31}if(vd(G[b+24>>2],G[m+24>>2],0,b+28|0,0,b+48|0)){break k}if(!(n|q)){break j}a=G[b+28>>2];h=a>>31}if(Ec(G[b+24>>2],35693,b+32|0,0,b+48|0)){if(G[b+48>>2]!=202){break k}G[b+48>>2]=0}G[b+44>>2]=-1;if(Ec(G[b+24>>2],32876,b+44|0,0,b+48|0)){if(G[b+48>>2]!=202){break k}G[b+48>>2]=0}G[b+40>>2]=-1;if(Ec(G[b+24>>2],32885,b+40|0,0,b+48|0)){if(G[b+48>>2]!=202){break k}G[b+48>>2]=0}d=G[b+32>>2];t:{if(d){break t}d=0;u:{v:{c=G[b+40>>2];if((c|0)>=0){f=V(+((c+1>>>0)/12|0))+.5;if(!(O(f)<2147483648)){break v}d=~~f;break u}w:{switch(G[b+56>>2]){case 0:f=V(+((p>>>0)/12>>>0))+.5;if(!(O(f)<2147483648)){break v}d=~~f;break u;case 2:break w;default:break t}}f=V(+(Bu(Au(n,q,a,h),Ia,12,0)>>>0)+ +(Ia|0)*4294967296)+.5;if(!(O(f)<2147483648)){break v}d=~~f;break u}d=-2147483648}G[b+32>>2]=d}G[m+32>>2]=d;c=M(M(d,d),12);G[m+40>>2]=c;if(G[b+44>>2]<0){G[b+44>>2]=0}if(G[b+40>>2]<0){G[b+40>>2]=c-1}x:{if(Fc(G[b+24>>2],33575,b+96|0,0,b+48|0)){if(G[b+48>>2]!=202){break k}G[b+48>>2]=0;break x}y:{switch(H[b+96|0]-67|0){case 4:E[m+28|0]=71;break x;case 2:E[m+28|0]=69;break x;case 0:break y;default:break x}}E[m+28|0]=81}z:{if(Fc(G[b+24>>2],35081,b- -64|0,0,b+48|0)){if(G[b+48>>2]!=202){break k}G[b+48>>2]=0;break z}if(!nb(b- -64|0,35812,7)){E[m+29|0]=78;break z}if(!nb(b- -64|0,35085,5)){E[m+29|0]=82;break z}G[b>>2]=b- -64;_a(G[24367],86680,b)}d=ab(G[m+40>>2]<<2);G[m+44>>2]=d;if(!d){break i}j=G[b+44>>2];A:{if((j|0)<=0){break A}if(j-1>>>0>=7){k=j&-8;c=0;while(1){G[d+24>>2]=-240822174;G[d+28>>2]=-240822174;G[d+16>>2]=-240822174;G[d+20>>2]=-240822174;G[d+8>>2]=-240822174;G[d+12>>2]=-240822174;G[d>>2]=-240822174;G[d+4>>2]=-240822174;d=d+32|0;c=c+8|0;if((k|0)!=(c|0)){continue}break}}j=j&7;if(!j){break A}c=0;while(1){G[d>>2]=-240822174;d=d+4|0;c=c+1|0;if((j|0)!=(c|0)){continue}break}}B:{switch(G[b+56>>2]){case 2:if(!n&(q|0)<=0|(q|0)<0){break g}p=0;l=0;j=a<<2;while(1){c=Fa-16|0;Fa=c;k=p+1|0;l=k?l:l+1|0;p=k;ae(G[b+24>>2],G[m+24>>2],k,l,1,0,a,h,1,1,N(-1.637499996306027e30),d,c+15|0,b+60|0,b+48|0);Fa=c+16|0;if(G[b+48>>2]){break k}d=d+j|0;if((n|0)!=(p|0)|(l|0)!=(q|0)){continue}break};break g;case 0:break B;default:break g}}if(!hl(G[b+24>>2],0,1,0,p,0,N(-1.637499996306027e30),d,b+60|0,b+48|0)){break g}}wf(G[24367],G[b+48>>2]);break h}hb(86720,39,1,G[24367]);break h}Vm()}if(g){Wa(g)}a=G[m+44>>2];if(a){Wa(a)}G[m+44>>2]=0;g=G[b+48>>2];break f}h=G[b+40>>2];d=h+1|0;a=G[m+40>>2];C:{if((d|0)>=(a|0)){break C}g=G[m+44>>2]+(d<<2)|0;j=a+(h^-1)&7;if(j){c=0;while(1){G[g>>2]=-240822174;d=d+1|0;g=g+4|0;c=c+1|0;if((j|0)!=(c|0)){continue}break}}if((a-h|0)-2>>>0<7){break C}while(1){G[g+24>>2]=-240822174;G[g+28>>2]=-240822174;G[g+16>>2]=-240822174;G[g+20>>2]=-240822174;G[g+8>>2]=-240822174;G[g+12>>2]=-240822174;G[g>>2]=-240822174;G[g+4>>2]=-240822174;g=g+32|0;d=d+8|0;if((a|0)!=(d|0)){continue}break}}g=0;if(G[m+8>>2]){break f}Qb(G[b+24>>2],b+48|0)}Fa=b+128|0;G[u>>2]=g;a=0;if(g){break e}c=0;n=Fa-144|0;Fa=n;h=G[m+32>>2];t=E[m+30|0];G[n+60>>2]=0;p=G[(t<<2)+144220>>2];a=M(p,h);G[n+56>>2]=a;G[n+52>>2]=a;D:{E:{F:{G:{if(G[m+8>>2]){if(!sd(n+48|0,42094,n+60|0)){break G}break F}if(sd(n+48|0,G[m+20>>2],n+60|0)){break F}}if(pd(G[n+48>>2],-32,2,n+52|0,n+60|0)){break F}l=G[n+48>>2];a=Fa-192|0;Fa=a;G[a+108>>2]=0;g=a+108|0;Kh(l,35787,0,4821,g);d=Fa-128|0;Fa=d;if(G[g>>2]<=0){Wc(d);b=ol(d);H:{if(!b){ma(d+96|0,25,33950,rq(d)|0)|0;G[d+84>>2]=H[16970]|H[16971]<<8|(H[16972]<<16|H[16973]<<24);b=H[16973]|H[16974]<<8|(H[16975]<<16|H[16976]<<24);E[d+87|0]=b;E[d+88|0]=b>>>8;E[d+89|0]=b>>>16;E[d+90|0]=b>>>24;break H}ma(d+96|0,25,33950,b|0)|0;G[d+84>>2]=5526816}G[d+8>>2]=H[65213]|H[65214]<<8|(H[65215]<<16|H[65216]<<24);b=H[65209]|H[65210]<<8|(H[65211]<<16|H[65212]<<24);G[d>>2]=H[65205]|H[65206]<<8|(H[65207]<<16|H[65208]<<24);G[d+4>>2]=b;q=Gb(d,d+96|0);b=Va(q)+q|0;j=H[5940]|H[5941]<<8|(H[5942]<<16|H[5943]<<24);k=H[5936]|H[5937]<<8|(H[5938]<<16|H[5939]<<24);E[b|0]=k;E[b+1|0]=k>>>8;E[b+2|0]=k>>>16;E[b+3|0]=k>>>24;E[b+4|0]=j;E[b+5|0]=j>>>8;E[b+6|0]=j>>>16;E[b+7|0]=j>>>24;j=H[5976]|H[5977]<<8|(H[5978]<<16|H[5979]<<24);E[b+40|0]=j;E[b+41|0]=j>>>8;E[b+42|0]=j>>>16;E[b+43|0]=j>>>24;j=H[5972]|H[5973]<<8|(H[5974]<<16|H[5975]<<24);k=H[5968]|H[5969]<<8|(H[5970]<<16|H[5971]<<24);E[b+32|0]=k;E[b+33|0]=k>>>8;E[b+34|0]=k>>>16;E[b+35|0]=k>>>24;E[b+36|0]=j;E[b+37|0]=j>>>8;E[b+38|0]=j>>>16;E[b+39|0]=j>>>24;j=H[5964]|H[5965]<<8|(H[5966]<<16|H[5967]<<24);k=H[5960]|H[5961]<<8|(H[5962]<<16|H[5963]<<24);E[b+24|0]=k;E[b+25|0]=k>>>8;E[b+26|0]=k>>>16;E[b+27|0]=k>>>24;E[b+28|0]=j;E[b+29|0]=j>>>8;E[b+30|0]=j>>>16;E[b+31|0]=j>>>24;j=H[5956]|H[5957]<<8|(H[5958]<<16|H[5959]<<24);k=H[5952]|H[5953]<<8|(H[5954]<<16|H[5955]<<24);E[b+16|0]=k;E[b+17|0]=k>>>8;E[b+18|0]=k>>>16;E[b+19|0]=k>>>24;E[b+20|0]=j;E[b+21|0]=j>>>8;E[b+22|0]=j>>>16;E[b+23|0]=j>>>24;j=H[5948]|H[5949]<<8|(H[5950]<<16|H[5951]<<24);k=H[5944]|H[5945]<<8|(H[5946]<<16|H[5947]<<24);E[b+8|0]=k;E[b+9|0]=k>>>8;E[b+10|0]=k>>>16;E[b+11|0]=k>>>24;E[b+12|0]=j;E[b+13|0]=j>>>8;E[b+14|0]=j>>>16;E[b+15|0]=j>>>24;b=Gb(q,d+84|0);j=Va(b)+b|0;E[j|0]=41;E[j+1|0]=0;Dq(l,35389,b,g)}Fa=d+128|0;b=G[m+32>>2];y=N(N((H[m+30|0]?b<<2|1:M(b,5)+1|0)|0)*N(.5));K[a+100>>2]=y;K[a+104>>2]=y;xd(l,42,41201,a+104|0,16844,g);xd(l,42,40799,a+100|0,16844,g);if(!H[m+30|0]){b=a+108|0;Qg(l,41180,N(.7071067690849304),-8,4912,b);Qg(l,40784,N(.7071067690849304),-8,4912,b);Qg(l,41155,N(-.7071067690849304),-8,4912,b);Qg(l,40765,N(.7071067690849304),-8,4912,b)}f=-90/+G[m+32>>2]/1.4142135623730951;b=a+108|0;ll(l,41234,f,-8,4885,b);ll(l,40826,-f,-8,4885,b);b=H[m+30|0]?34928:32859;j=34433;k=33498;g=25205;d=25157;I:{J:{switch(H[m+28|0]-69|0){case 0:j=34438;k=33503;g=25186;d=25138;break I;case 12:j=48516;k=48506;g=15463;d=14698;break I;case 2:break I;default:break J}}j=34428;k=33493;g=25224;d=25176}G[a+84>>2]=b;G[a+80>>2]=j;j=a+112|0;db(j,8784,a+80|0);G[a+68>>2]=b;G[a+64>>2]=g;q=a+128|0;db(q,14538,a- -64|0);s=a+108|0;lc(l,41295,j,q,s);G[a+52>>2]=b;G[a+48>>2]=k;db(j,8784,a+48|0);G[a+36>>2]=b;G[a+32>>2]=d;db(q,14538,a+32|0);lc(l,40882,j,q,s);y=N(N(N(E[m+31|0])*N(90))+N(0));K[a+96>>2]=y;K:{L:{M:{switch(H[m+30|0]){case 0:G[a+92>>2]=0;break K;case 1:G[a+92>>2]=1119092736;y=N(y+N(180));break L;default:break M}}G[a+92>>2]=-1028390912;y=N(y+N(180))}K[a+96>>2]=y}if(y>N(360)){K[a+96>>2]=y+N(-360)}G[a+16>>2]=g;b=a+128|0;db(b,4684,a+16|0);g=a+108|0;xd(l,42,41279,a+96|0,b,g);G[a>>2]=d;db(b,4684,a);xd(l,42,40866,a+92|0,b,g);N:{if(H[m+30|0]){b=H[21646]|H[21647]<<8|(H[21648]<<16|H[21649]<<24);G[a+144>>2]=H[21642]|H[21643]<<8|(H[21644]<<16|H[21645]<<24);G[a+148>>2]=b;b=H[21654]|H[21655]<<8|(H[21656]<<16|H[21657]<<24);G[a+152>>2]=H[21650]|H[21651]<<8|(H[21652]<<16|H[21653]<<24);G[a+156>>2]=b;b=H[21662]|H[21663]<<8|(H[21664]<<16|H[21665]<<24);G[a+160>>2]=H[21658]|H[21659]<<8|(H[21660]<<16|H[21661]<<24);G[a+164>>2]=b;b=H[21667]|H[21668]<<8|(H[21669]<<16|H[21670]<<24);d=H[21663]|H[21664]<<8|(H[21665]<<16|H[21666]<<24);E[a+165|0]=d;E[a+166|0]=d>>>8;E[a+167|0]=d>>>16;E[a+168|0]=d>>>24;E[a+169|0]=b;E[a+170|0]=b>>>8;E[a+171|0]=b>>>16;E[a+172|0]=b>>>24;G[a+88>>2]=1127481344;b=H[21630]|H[21631]<<8|(H[21632]<<16|H[21633]<<24);G[a+128>>2]=H[21626]|H[21627]<<8|(H[21628]<<16|H[21629]<<24);G[a+132>>2]=b;b=H[21638]|H[21639]<<8|(H[21640]<<16|H[21641]<<24);G[a+136>>2]=H[21634]|H[21635]<<8|(H[21636]<<16|H[21637]<<24);G[a+140>>2]=b;xd(l,42,35545,a+88|0,a+128|0,a+108|0);if(H[m+30|0]){break N}}b=a+108|0;hd(l,41130,4,0,61663,b);hd(l,40746,3,0,61635,b)}b=a+108|0;wb(l,68332,b);Pg(l,H[m+30|0]?3517:3449,b);Pg(l,8444,b);Pg(l,26653,b);Pg(l,30833,b);Fa=a+192|0;a=G[a+108>>2];G[n+60>>2]=a;if(a){break F}O:{a=h<<2;c=ab(a);if(c){o=ab(a);if(o){break O}}Vm();o=0;break E}if((h|0)>0){v=h-1|0;U=(h<<2)+o|0;W=M(h,h);B=h>>31;J=(p|0)>1?p:1;p=1;l=0;X=M(t,100);while(1){a=0;g=0;while(1){P=a+h|0;q=v-g|0;x=0;while(1){b=E[m+31|0];d=(M(I,20)+X|0)+(x<<2)|0;a=G[d+144240>>2];P:{if(!b|(a|0)<0){break P}if(a>>>0>=4){b=a+b|0;if(a>>>0>=8){a=(b|0)>11?b-4|0:b;break P}a=(b|0)>7?b-4|0:b;break P}a=a+b|0;a=(a|0)>3?a-4|0:a}Q:{R:{if((a|0)>=0){Y=d+144848|0;Q=G[d+144544>>2];if(H[m+29|0]!=78){b=a;a=c;j=0;k=0;if((h|0)>0){R=1-h|0;S=h<<3;s=h<<1;d=s-1|0;Z=M(d,d)-1|0;t=M(M(h,h),24)|1;d=h-1|0;_=t+d|0;$=h-2|0;aa=0-s|0;ba=0-h|0;b=b<<2;C=M(h,G[b+145200>>2]);ca=C+g|0;D=M(h,G[b+145152>>2]);da=D+g|0;b=d-g|0;ea=b+D|0;fa=b+C|0;d=0;b=0;while(1){S:{T:{switch(Q|0){case 0:b=j+ca|0;d=j+ea|0;break S;case 1:b=j+fa|0;d=(k+D|0)-g|0;break S;case 2:b=(k+C|0)-g|0;d=D+(R+(g+k|0)|0)|0;break S;case 3:break T;default:break S}}d=j+da|0;b=C+(R+(g+k|0)|0)|0}d=((d>>31&S)+d|0)+1|0;U:{if((b|0)>(h|0)){j=0;if((b|0)==(s|0)){break U}j=s-b<<1;F=j-1|0;j=(($-b|0)+M(F,F)|0)+M(j,(d|0)/(s|0)|0)+(d|0)%(s|0)|0;break U}j=(M(h-b|0,S)+Z|0)+d|0;if((b|0)>=(ba|0)){break U}j=t;if((b|0)<=(aa|0)){break U}j=b+s<<1;F=j|1;ga=j;j=(d|0)/(s|0)|0;j=((b+_|0)-M(F,F)|0)+M(ga,j)+(d-M(j,s))|0}G[a>>2]=(j-1|0)/2;j=k^-1;a=a+4|0;k=k+1|0;if((h|0)!=(k|0)){continue}break}}break R}C=M(a,W);d=0;k=c;while(1){b=0;a=0;V:{W:{switch(Q|0){case 3:b=d;a=g;break V;case 2:b=q;a=d;break V;case 1:b=v-d|0;a=q;break V;case 0:break W;default:break V}}a=v-d|0;b=g}j=1;s=0;if(a|b){while(1){t=b;s=0-(b&1)&j<<1|(0-(a&1)&j|s);if((a|b)&1){G[k>>2]=s}b=t>>1;j=j<<2;D=a>>>0>1;a=a>>1;if(t>>>0>1|D){continue}break}}G[k>>2]=s+C;k=k+4|0;d=d+1|0;if((h|0)!=(d|0)){continue}break}break R}b=G[n+48>>2];a=n+60|0;X:{if(Nb(b,a)){Ua(28060);G[a>>2]=413;a=413;break X}rc(b,2,1,0,p,l,h,B,a);a=G[a>>2]}if(a){break F}break Q}b=G[Y>>2];G[n+60>>2]=0;d=G[m+44>>2];a=o;j=c;while(1){K[a>>2]=K[d+(G[j>>2]<<2)>>2];j=j+4|0;a=a+4|0;if(U>>>0>a>>>0){continue}break}Y:{if(!b){break Y}Z:{_:{$:{aa:{ba:{a=b>>31;switch((a^-1)+(a^b)|0){case 0:break $;case 1:break aa;case 2:break ba;default:break _}}d=0;a=(b>>>31|0)+g|0;break Z}d=a+P|0;a=h;break Z}d=((b|0)>0)+g|0;a=h;break Z}d=0;a=P-((b|0)>0)|0}if((a|0)<=(d|0)){break Y}b=(a<<2)+o|0;a=(d<<2)+o|0;while(1){G[a>>2]=-240822174;a=a+4|0;if(b>>>0>a>>>0){continue}break}}if(Ek(G[n+48>>2],0,p,l,h,B,o,N(-1.637499996306027e30),n+60|0)){break F}}a=h;b=a+p|0;l=l+B|0;l=a>>>0>b>>>0?l+1|0:l;p=b;x=x+1|0;if((J|0)!=(x|0)){continue}break}a=g^-1;g=g+1|0;if((h|0)!=(g|0)){continue}break}I=I+1|0;if((J|0)!=(I|0)){continue}break}}a=G[m+12>>2];if(!(!a|!H[a|0])){G[n+32>>2]=a;a=n- -64|0;db(a,9908,n+32|0);ze(G[n+48>>2],a,n+60|0)}G[n+16>>2]=G[m+32>>2];a=n- -64|0;db(a,30612,n+16|0);ze(G[n+48>>2],a,n+60|0);G[n>>2]=H[m+29|0]==78?35812:35085;db(a,9816,n);if(H[m+29|0]==114){a=n- -64|0;a=Va(a)+a|0;b=H[62300]|H[62301]<<8|(H[62302]<<16|H[62303]<<24);c=H[62296]|H[62297]<<8|(H[62298]<<16|H[62299]<<24);E[a|0]=c;E[a+1|0]=c>>>8;E[a+2|0]=c>>>16;E[a+3|0]=c>>>24;E[a+4|0]=b;E[a+5|0]=b>>>8;E[a+6|0]=b>>>16;E[a+7|0]=b>>>24;b=H[62303]|H[62304]<<8|(H[62305]<<16|H[62306]<<24);E[a+7|0]=b;E[a+8|0]=b>>>8;E[a+9|0]=b>>>16;E[a+10|0]=b>>>24}ze(G[n+48>>2],n- -64|0,n+60|0);a=G[n+48>>2];ca:{if(G[m+8>>2]){G[m+16>>2]=a;break ca}Qb(a,n+60|0)}a=0;break D}wf(G[24367],G[n+60>>2])}if(c){Wa(c)}if(o){Wa(o)}if(!G[m+8>>2]){G[m+16>>2]=0}a=G[n+60>>2]}Fa=n+144|0;G[u>>2]=a;a=G[m+44>>2];if(a){Wa(a)}a=G[m+16>>2]}Fa=m+48|0;g=0;if(G[u>>2]){break b}g=a;if(!e|!(L[e>>3]==0|L[e+8>>3]==0)){break b}G[i+3660>>2]=0;de(g,2,i+3664|0,i+3660|0);if(L[e>>3]==0){L[e>>3]=G[i+3664>>2]/2|0}if(L[e+8>>3]!=0){break b}L[e+8>>3]=G[i+3668>>2]/2|0;break b}G[i+3616>>2]=1589294263;G[i+3620>>2]=-1196933592;E[i+1232|0]=0;G[i+3584>>2]=1589294263;G[i+3588>>2]=-1196933592;z=1;da:{if(f==0){break da}z=f;if(!(f<0)){break da}z=1/O(f)}L[i+3552>>3]=z;E[i+656|0]=0;E[i+368|0]=0;E[i+80|0]=0;G[i+3624>>2]=1589294263;G[i+3628>>2]=-1196933592;G[i+3592>>2]=1589294263;G[i+3596>>2]=-1196933592;L[i+3560>>3]=z;E[i+727|0]=0;E[i+439|0]=0;E[i+151|0]=0;G[i+3632>>2]=1589294263;G[i+3636>>2]=-1196933592;G[i+3600>>2]=1589294263;G[i+3604>>2]=-1196933592;L[i+3568>>3]=z;E[i+798|0]=0;E[i+510|0]=0;E[i+222|0]=0;G[i+3608>>2]=1589294263;G[i+3612>>2]=-1196933592;G[i+3640>>2]=1589294263;G[i+3644>>2]=-1196933592;L[i+3576>>3]=z;E[i+869|0]=0;E[i+581|0]=0;E[i+293|0]=0;ea:{fa:{ga:{if(c){l=le(c);c=pc(l,49007);if(c){ha=rb(i+944|0,c,71),ia=0,E[ha+70|0]=ia}c=pc(0,49007);if(c){rb(i+1015|0,c,71);E[i+1085|0]=0}g=pc(0,49007);E[i+1086|0]=0;ha:{if(!g){break ha}j=H[g|0];if(!j){break ha}c=i+1086|0;ia:{ja:{ka:{while(1){k=j&255;if(!k|(k|0)==58){break ga}E[c|0]=j;j=H[g+1|0];if(!j|(j|0)==58){break ia}E[c+1|0]=j;j=H[g+2|0];if(!j|(j|0)==58){break ja}E[c+2|0]=j;j=o|3;k=c+3|0;q=H[g+3|0];if(!q|(q|0)==58){break ka}if((j|0)!=71){E[c+3|0]=q;o=o+4|0;c=c+4|0;j=H[g+4|0];g=g+4|0;continue}break}g=g+3|0;j=71;break fa}g=g+3|0;break fa}k=c+2|0;j=o|2;g=g+2|0;break fa}k=c+1|0;j=o|1;g=g+1|0;break fa}Wa(l);c=2;break ea}E[i+1015|0]=0;E[i+944|0]=0;c=2;break ea}k=c;j=o}E[k|0]=0;la:{ma:{if(H[g|0]==58){E[i+3664|0]=0;o=i+3664|0;na:{c=H[g+1|0];if(c){g=g+1|0;while(1){if((c&255)==58|j>>>0>1023){break na}E[o|0]=c;j=j+1|0;o=o+1|0;c=H[g+1|0];g=g+1|0;if(c){continue}break}}E[o|0]=0;f=sb(i+3664|0);break la}E[o|0]=0;f=sb(i+3664|0);if((c&255)!=58){break la}E[i+3664|0]=0;o=i+3664|0;oa:{c=H[g+1|0];if(c){g=g+1|0;while(1){if((c&255)==58|j>>>0>1023){break oa}E[o|0]=c;j=j+1|0;o=o+1|0;c=H[g+1|0];g=g+1|0;if(c){continue}break}}E[o|0]=0;w=sb(i+3664|0);break ma}E[o|0]=0;w=sb(i+3664|0);if((c&255)!=58){break ma}E[i+3664|0]=0;o=i+3664|0;c=H[g+1|0];pa:{if(!c){break pa}g=g+1|0;while(1){if((c&255)==58|j>>>0>1023){break pa}E[o|0]=c;j=j+1|0;o=o+1|0;c=H[g+1|0];g=g+1|0;if(c){continue}break}}E[o|0]=0;r=sb(i+3664|0);L[i+3600>>3]=w;L[i+3632>>3]=f;L[i+3568>>3]=r;Wa(l);c=3;break ea}G[i+3568>>2]=0;G[i+3572>>2]=1072693248;Wa(l);c=3;break ea}L[i+3600>>3]=w;L[i+3632>>3]=f;Wa(l);c=3;break ea}L[i+3568>>3]=f;Wa(l);c=3}zi(a,i+3656|0,h);j=G[i+3656>>2];g=j+1|0;q=lb(g,1);qa:{if(!(!b|!H[b|0])){g=0;hn(a,b,0,j,i+3652|0,q,h);if(!G[h>>2]){break qa}break b}if((j|0)<0){break qa}cb(q,1,g)}b=Fa-96|0;Fa=b;l=c;_j(a,c,i+944|0,i+3616|0,i+3584|0,i+3552|0,i+656|0,i+368|0,i+80|0,i- -64|0,i+48|0,b- -64|0,b+32|0,b,h);ra:{if(G[h>>2]|(c|0)<=0){break ra}K[i+32>>2]=L[b+64>>3];K[i+16>>2]=L[b+32>>3];K[i>>2]=L[b>>3];c=(l|0)<4?l:4;if((c|0)==1){break ra}K[i+36>>2]=L[b+72>>3];K[i+20>>2]=L[b+40>>3];K[i+4>>2]=L[b+8>>3];if((c|0)==2){break ra}K[i+40>>2]=L[b+80>>3];K[i+24>>2]=L[b+48>>3];K[i+8>>2]=L[b+16>>3];if((c|0)==3){break ra}K[i+44>>2]=L[b+88>>3];K[i+28>>2]=L[b+56>>3];K[i+12>>2]=L[b+24>>3]}Fa=b+96|0;g=0;if(G[h>>2]){break b}f=z*+G[i+48>>2];sa:{if(O(f)<2147483648){b=~~f;break sa}b=-2147483648}G[i+48>>2]=b;f=z*+G[i+52>>2];ta:{if(O(f)<2147483648){c=~~f;break ta}c=-2147483648}G[i+52>>2]=c;f=+N(K[i+20>>2]+K[i+36>>2])*.5;ua:{if(O(f)<2147483648){k=~~f;break ua}k=-2147483648}f=+(k|0);w=+N(K[i+16>>2]+K[i+32>>2])*.5;va:{if(O(w)<2147483648){k=~~w;break va}k=-2147483648}w=+(k|0);wa:{xa:{if(!d){break xa}j=G[d>>2];if(!j){break xa}k=G[d+4>>2];if(!k){break xa}ya:{za:{if(!e){break za}r=L[e>>3];if(r==0){break za}A=L[e+8>>3];if(A==0){break za}w=r;f=A;break ya}k=(c|0)>(k|0)?k:c;j=(b|0)>(j|0)?j:b}r=+(k|0)*.5;A=f-r;Aa:{if(O(A)<2147483648){b=~~A;break Aa}b=-2147483648}L[i+3624>>3]=b|0;A=+(j|0)*.5;T=w-A;Ba:{if(O(T)<2147483648){b=~~T;break Ba}b=-2147483648}L[i+3616>>3]=b|0;r=f+r;Ca:{if(O(r)<2147483648){b=~~r;break Ca}b=-2147483648}L[i+3592>>3]=b|0;r=w+A;Da:{if(O(r)<2147483648){b=~~r;break Da}b=-2147483648}L[i+3584>>3]=b|0;break wa}j=b;k=c}Ea:{if(!t){break Ea}r=(L[i+3592>>3]-L[i+3624>>3])/L[i+3560>>3];A=(L[i+3584>>3]-L[i+3616>>3])/L[i+3552>>3];Fa:{if(O(A)<2147483648){b=~~A;break Fa}b=-2147483648}r=r*+(b|0);Ga:{if(O(r)<2147483648){b=~~r;break Ga}b=-2147483648}Ha:{if((l|0)==2){break Ha}r=(L[i+3600>>3]-L[i+3632>>3])/L[i+3568>>3]*+(b|0);if(O(r)<2147483648){b=~~r;break Ha}b=-2147483648}if((M(vk(u),b)|0)<=(t|0)){break Ea}G[h>>2]=113;break b}t=m?i+1504|0:42094;m=i+944|0;n=i+3616|0;s=i+3584|0;v=i+3552|0;B=i+656|0;x=i+368|0;C=i+80|0;p=i+1232|0;c=0;r=1;b=Fa-176|0;Fa=b;Ia:{if(G[h>>2]>0){break Ia}if((l|0)>=5){Ua(6766);G[h>>2]=320;break Ia}o=G[a>>2];if((o|0)!=G[G[a+4>>2]+76>>2]){mb(a,o+1|0,0,h)}o=8;Ja:{Ka:{La:{switch(u-11|0){case 20:o=32;break Ja;case 31:o=-32;break Ja;default:if((u|0)==82){break Ka}case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:G[h>>2]=410;break Ia;case 0:break Ja;case 10:break La}}o=16;break Ja}o=-64}if((_j(a,l,m,n,s,v,B,x,C,b+144|0,b+112|0,b+80|0,b+48|0,b+16|0,h)|0)>0){Ua(6126);break Ia}Ma:{Na:{if(H[p|0]){if(!Cb(a,82,p,b+8|0,0,h)){r=L[b+8>>3];break Na}G[h>>2]=0;if((dc(a,0,p,b+140|0,h)|0)>0){Ua(66743);Ua(p);break Ia}G[b+8>>2]=1589294263;G[b+12>>2]=-1196933592;break Ma}L[b+8>>3]=1}if(!(!(r<=0)|r==-91191291391491e-49)){Ua(45241);G[h>>2]=125;break Ia}}if((sd(b+172|0,t,h)|0)>0){Ua(16402);break Ia}if((pd(G[b+172>>2],o,l,b+112|0,h)|0)>0){Ua(25086);break Ia}if((tk(a,G[b+172>>2],b+144|0,h)|0)>0){Ua(11702);break Ia}p=b+144|0;Zj(a,G[b+172>>2],l,p,h);u=b+80|0;m=b+16|0;En(G[b+172>>2],l,u,m,h);if((Dn(a,G[b+172>>2],o,l,b+112|0,p,u,b+48|0,m,L[b+8>>3],G[b+140>>2],0,q,h)|0)>0){Ua(7256);break Ia}c=G[b+172>>2]}Fa=b+176|0;if(G[h>>2]){break b}G[i+3660>>2]=0;b=i+3664|0;h=i+3660|0;zb(34641,G[i+64>>2],b,h);l=i+1408|0;o=i+1312|0;Cb(a,16,b,l,o,h);zb(34165,1,b,h);g=c;Jc(c,16,b,l,21232,h);G[i+3660>>2]=0;zb(34553,1,b,h);c=i+32|0;Jc(g,42,b,c,26534,h);G[i+3660>>2]=0;zb(33042,1,b,h);p=i+16|0;Jc(g,42,b,p,26561,h);G[i+3660>>2]=0;zb(34659,1,b,h);u=i+48|0;Jc(g,41,b,u,6701,h);G[i+3660>>2]=0;zb(34641,G[i+68>>2],b,h);Cb(a,16,b,l,o,h);zb(34165,2,b,h);Jc(g,16,b,l,21232,h);G[i+3660>>2]=0;zb(34553,2,b,h);Jc(g,42,b,c|4,26534,h);G[i+3660>>2]=0;zb(33042,2,b,h);Jc(g,42,b,p|4,26561,h);G[i+3660>>2]=0;zb(34659,2,b,h);Jc(g,41,b,u|4,6701,h);if(O(f)<2147483648){b=~~f}else{b=-2147483648}if(O(w)<2147483648){c=~~w}else{c=-2147483648}Sm(a,g,c,b,j,k,z,0);if(d){G[d+4>>2]=k;G[d>>2]=j}if(e){L[e+8>>3]=f;L[e>>3]=w}if(nb(t,42094,7)){b=0;a=Fa-16|0;Fa=a;c=i+3660|0;if(G[c>>2]<=0){G[a+12>>2]=G[g>>2]+1;if((Xf(g,c)|0)>0){Ua(45102)}while(1){d=G[g+4>>2];e=d+(b<<2)|0;if(!(G[e+1256>>2]<0|!G[e+1416>>2])){Hg(d,b,c)}b=b+1|0;if((b|0)!=40){continue}break}if(G[c>>2]!=112){b=G[g+4>>2];d=G[(M(G[b+4>>2],84)+1240576|0)+68>>2];if(d){Ja[d|0](G[b>>2])|0}}if((Zn(g,G[a+12>>2]-1|0,a+8|0,c)|0)>0){Ua(45061)}}Fa=a+16|0}if(q){Wa(q)}}Fa=i+4688|0;return g|0}function Mh(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,I=0,J=0,N=0,P=0,Q=0,R=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0;f=Fa-2416|0;Fa=f;G[935250]=G[935250]+1;G[f+344>>2]=0;a:{if(Rc(f+348|0,a,0,f+344|0)){G[f+192>>2]=a;db(c,9154,f+192|0);G[935251]=G[935251]+1;if(!G[935249]){x=1;break a}G[f+176>>2]=a;kb(80536,f+176|0);$a(G[29763]);x=1;break a}Be(a,f+208|0);d=G[f+252>>2];c=G[f+248>>2];G[b+1028>>2]=1;G[b+1032>>2]=c;G[b+1036>>2]=d;G[f+344>>2]=0;if(!mb(G[f+348>>2],1,0,f+344|0)){$=b+1080|0;aa=b+1050|0;ba=b+1040|0;U=f+1376|1;C=G[29763];while(1){G[935252]=G[935252]+1;G[f+344>>2]=0;b:{c:{if(Vc(G[f+348>>2],41295,f+1376|0,f+352|0,f+344|0)){if(G[926536]){G[f+160>>2]=a;kb(69177,f+160|0);$a(C)}c=G[b+1028>>2];G[935246]=G[935246]+1;if(G[935249]){G[f+148>>2]=c;G[f+144>>2]=a;kb(79e3,f+144|0);$a(C)}A=(c|0)==1?1:A;x=x+1|0;D=0;G[935253]=G[935253]+1;n=0;if(G[935256]){break c}break b}c=f+1376|0;d:{if(H[f+1376|0]!=39){break d}d=(Va(f+1376|0)+f|0)+1375|0;if(H[d|0]!=39){break d}E[d|0]=0;c=U}if(Va(c)>>>0<=7){E[c|0]=0}while(1){g=H[c|0];if(!((g|0)==45|!g)){c=c+1|0;continue}break}while(1){d=g&255;if((d|0)==45){g=H[c+1|0];c=c+1|0;continue}break}if(!d){if(G[926536]){G[f+128>>2]=a;kb(69204,f+128|0);$a(C)}c=G[b+1028>>2];G[935246]=G[935246]+1;if(G[935249]){G[f+116>>2]=c;G[f+112>>2]=a;kb(79063,f+112|0);$a(C)}A=(c|0)==1?1:A;x=x+1|0;D=0;G[935253]=G[935253]+1;n=0;if(G[935256]){break c}break b}G[f+344>>2]=0;if(Vc(G[f+348>>2],40882,f+1376|0,f+352|0,f+344|0)){if(G[926536]){G[f+96>>2]=a;kb(69123,f+96|0);$a(C)}c=G[b+1028>>2];G[935246]=G[935246]+1;if(G[935249]){G[f+84>>2]=c;G[f+80>>2]=a;kb(78874,f+80|0);$a(C)}A=(c|0)==1?1:A;x=x+1|0;D=0;G[935253]=G[935253]+1;n=0;if(G[935256]){break c}break b}c=f+1376|0;e:{if(H[f+1376|0]!=39){break e}d=(Va(f+1376|0)+f|0)+1375|0;if(H[d|0]!=39){break e}E[d|0]=0;c=U}if(Va(c)>>>0<=7){E[c|0]=0}while(1){g=H[c|0];if(!((g|0)==45|!g)){c=c+1|0;continue}break}while(1){d=g&255;if((d|0)==45){g=H[c+1|0];c=c+1|0;continue}break}D=1;if(d){break c}if(G[926536]){G[f+64>>2]=a;kb(69150,f- -64|0);$a(C)}c=G[b+1028>>2];G[935246]=G[935246]+1;if(G[935249]){G[f+52>>2]=c;G[f+48>>2]=a;kb(78937,f+48|0);$a(C)}A=(c|0)==1?1:A;x=x+1|0;D=0;G[935253]=G[935253]+1;n=0;if(!G[935256]){break b}}g=G[b+1028>>2];f:{if((g|0)!=1){break f}c=0;if(G[935262]<=0){break f}while(1){G[f+344>>2]=0;g=M(c,516);g:{if(Vc(G[f+348>>2],g+G[935263]|0,f+1376|0,f+352|0,f+344|0)){E[(g+G[935263]|0)+384|0]=0;break g}d=f+1376|0;h:{if(H[f+1376|0]!=39){break h}h=(Va(f+1376|0)+f|0)+1375|0;if(H[h|0]!=39){break h}E[h|0]=0;d=U}Za((g+G[935263]|0)+384|0,d)}c=c+1|0;if((c|0)>2]}c=0;x=x-((g|0)==2&(A|0)!=0)|0;i:{j:{k:{if(!D){D=0;break k}G[f+344>>2]=0;if(Yj(G[f+348>>2],f+2412|0,f+344|0)){D=0;G[935253]=G[935253]+1;if(G[935256]){break k}break b}n=rd(G[f+2412>>2]);l:{if(!n){h=G[b+1028>>2];G[935246]=G[935246]+1;d=G[935253]+1|0;G[935253]=d;A=(h|0)==1?1:A;x=x+1|0;if(G[935249]){G[f+36>>2]=h;G[f+32>>2]=a;kb(78749,f+32|0);$a(C);d=G[935253]}G[935253]=d+1;if(!G[935256]){n=0;break b}D=1;d=Wg(n,1);n=0;if((d|0)==1){break l}break k}if((Wg(n,1)|0)!=1){break j}}if(G[926536]){G[f+16>>2]=a;kb(69102,f+16|0);$a(C)}d=G[b+1028>>2];G[935246]=G[935246]+1;if(G[935249]){G[f+4>>2]=d;G[f>>2]=a;kb(78818,f);$a(C)}A=(d|0)==1?1:A;x=x+1|0;n=0;D=1;G[935253]=G[935253]+1;if(!G[935256]){break b}}G[f+344>>2]=0;if(Vc(G[f+348>>2],41261,f+1376|0,f+352|0,f+344|0)){d=0}else{d=_b(f+1376|0)}G[b+1060>>2]=d;if(!Vc(G[f+348>>2],40853,f+1376|0,f+352|0,f+344|0)){c=_b(f+1376|0)}G[b+1068>>2]=0;G[b+1072>>2]=0;E[b+1050|0]=0;E[b+1040|0]=0;G[b+1064>>2]=c;cb($,0,136);break i}e=L[n+136>>3];m:{if(O(e)<2147483648){c=~~e;break m}c=-2147483648}G[b+1060>>2]=c;e=L[n+144>>3];n:{if(O(e)<2147483648){c=~~e;break n}c=-2147483648}G[b+1064>>2]=c;c=Za(ba,n+3368|0);Za(aa,n+3384|0);K[b+1068>>2]=L[n+16>>3];K[b+1072>>2]=L[n+24>>3];y=L[n+120>>3];L[b+1208>>3]=y;L[b+1080>>3]=L[n>>3];L[b+1088>>3]=L[n+8>>3];l=L[n+32>>3];L[b+1096>>3]=l;e=L[n+40>>3];L[b+1104>>3]=e;p=L[n+48>>3];L[b+1112>>3]=p;o:{if(!(p<-90|p>90)|(!(l>0)|!(e>0))){break o}L[b+1104>>3]=-e;L[b+1096>>3]=-l;e=p+180;if(e>=360){while(1){e=e+-360;if(e>=360){continue}break}}L[b+1112>>3]=e;if(!(e<=-360)){break o}while(1){e=e+360;if(e<=-360){continue}break}L[b+1112>>3]=e}d=fb(c,34433,4);c=fb(c,34438,4);cc(n,+G[b+1060>>2]*.5,+G[b+1064>>2]*.5,f+336|0,f+328|0);k=c?!d<<2:2;dd(k,y,L[f+336>>3],L[f+328>>3],0,2e3,f+320|0,f+312|0);L[b+1120>>3]=L[f+320>>3];L[b+1128>>3]=L[f+312>>3];e=L[b+1096>>3];p:{if(!(!(e<0&L[b+1104>>3]<0)&(!(e>0)|!(L[b+1104>>3]>0)))){g=f+336|0;h=f+328|0;cc(n,-.5,-.5,g,h);d=f+304|0;c=f+296|0;dd(k,y,L[f+336>>3],L[f+328>>3],0,2e3,d,c);L[b+1136>>3]=L[f+304>>3];L[b+1144>>3]=L[f+296>>3];cc(n,L[n+136>>3]+.5,-.5,g,h);dd(k,y,L[f+336>>3],L[f+328>>3],0,2e3,d,c);L[b+1152>>3]=L[f+304>>3];L[b+1160>>3]=L[f+296>>3];cc(n,L[n+136>>3]+.5,L[n+144>>3]+.5,g,h);dd(k,y,L[f+336>>3],L[f+328>>3],0,2e3,d,c);L[b+1168>>3]=L[f+304>>3];L[b+1176>>3]=L[f+296>>3];cc(n,-.5,L[n+144>>3]+.5,g,h);dd(k,y,L[f+336>>3],L[f+328>>3],0,2e3,d,c);l=L[f+304>>3];L[b+1184>>3]=l;e=L[f+296>>3];L[b+1192>>3]=e;break p}g=f+336|0;h=f+328|0;cc(n,-.5,-.5,g,h);d=f+304|0;c=f+296|0;dd(k,y,L[f+336>>3],L[f+328>>3],0,2e3,d,c);L[b+1136>>3]=L[f+304>>3];L[b+1144>>3]=L[f+296>>3];cc(n,L[n+136>>3]+.5,-.5,g,h);dd(k,y,L[f+336>>3],L[f+328>>3],0,2e3,d,c);L[b+1184>>3]=L[f+304>>3];L[b+1192>>3]=L[f+296>>3];cc(n,L[n+136>>3]+.5,L[n+144>>3]+.5,g,h);dd(k,y,L[f+336>>3],L[f+328>>3],0,2e3,d,c);L[b+1168>>3]=L[f+304>>3];L[b+1176>>3]=L[f+296>>3];cc(n,-.5,L[n+144>>3]+.5,g,h);dd(k,y,L[f+336>>3],L[f+328>>3],0,2e3,d,c);l=L[f+304>>3];L[b+1152>>3]=l;e=L[f+296>>3];L[b+1160>>3]=e}B=e*.01745329252;Y=eb(B);l=l*.01745329252;V=ib(l);e=L[b+1120>>3];y=L[b+1128>>3]*.01745329252;Z=eb(y);e=e*.01745329252;p=ib(e);l=eb(l);e=eb(e);ea=b,fa=Sc(ib(y)*ib(B)+(e*Z*(l*Y)+p*Z*(V*Y)))/.01745329252,L[ea+1200>>3]=fa;Wa(G[f+2412>>2]);D=1}g=0;if(G[935262]>0){while(1){G[f+344>>2]=0;h=M(g,516);q:{r:{if(Vc(G[f+348>>2],h+G[935263]|0,f+1376|0,f+352|0,f+344|0)){d=G[935263];c=(h+d|0)+256|0;break r}d=f+1376|0;s:{if(H[f+1376|0]!=39){break s}c=(Va(f+1376|0)+f|0)+1375|0;if(H[c|0]!=39){break s}E[c|0]=0;d=U}Za((h+G[935263]|0)+256|0,d);d=G[935263];c=h+d|0;if(H[c+256|0]){break q}c=c+256|0}Za(c,(d+h|0)+384|0)}g=g+1|0;if((g|0)>2]=G[935247];W=0;i=Fa-1072|0;Fa=i;h=H[41649]|H[41650]<<8;F[i+778>>1]=h;E[i+684|0]=H[35851];d=H[34154]|H[34155]<<8;F[i+696>>1]=d;c=H[34156];E[i+698|0]=c;G[i+768>>2]=5391428;g=H[41645]|H[41646]<<8|(H[41647]<<16|H[41648]<<24);F[i+774>>1]=g;q=g>>>16|0;F[i+776>>1]=q;F[i+608>>1]=d;E[i+610|0]=c;G[i+680>>2]=H[35847]|H[35848]<<8|(H[35849]<<16|H[35850]<<24);F[i+690>>1]=h;F[i+686>>1]=g;F[i+688>>1]=q;if(!G[935247]){g=0;c=G[935259];hb(70071,20,1,G[935266]);hb(2544,130,1,G[935266]);hb(1880,87,1,G[935266]);d=G[935262];t:{if(c){if((d|0)>0){while(1){c=M(g,516);G[i+592>>2]=G[(c+G[935263]|0)+512>>2];db(i+1040|0,1785,i+592|0);h=c+G[935263]|0;d=0;while(1){c=E[d+h|0];E[(i+784|0)+d|0]=c-65>>>0<26?c|32:c;c=Va(h)>>>0>d>>>0;d=d+1|0;if(c){continue}break}G[i+576>>2]=i+784;_a(G[935266],i+1040|0,i+576|0);g=g+1|0;if((g|0)0){while(1){h=M(d,516);G[i+560>>2]=G[(h+G[935263]|0)+512>>2];c=i+1040|0;db(c,1785,i+560|0);G[i+544>>2]=(h+G[935263]|0)+128;_a(G[935266],c,i+544|0);d=d+1|0;if((d|0)0){while(1){c=M(g,516);G[i+528>>2]=G[(c+G[935263]|0)+512>>2];db(i+1040|0,1785,i+528|0);h=c+G[935263]|0;d=0;while(1){c=E[d+h|0];E[(i+784|0)+d|0]=c-65>>>0<26?c|32:c;c=Va(h)>>>0>d>>>0;d=d+1|0;if(c){continue}break}G[i+512>>2]=i+784;_a(G[935266],i+1040|0,i+512|0);g=g+1|0;if((g|0)>2]=G[(h+G[935263]|0)+512>>2];c=i+1040|0;db(c,1785,i+496|0);G[i+480>>2]=(h+G[935263]|0)+128;_a(G[935266],c,i+480|0);d=d+1|0;if((d|0)>3]=L[b+1120>>3];L[i+760>>3]=L[b+1128>>3];r=0;s=0;p=0;B=0;N=0;V=0;y=0;I=0;h=Fa-224|0;Fa=h;u:{v:{w:{d=i+696|0;k=i+608|0;if(Xa(d,k)){break w}if(Xa(d+78|0,k+78|0)){break w}c=0;break v}s=H[d|0];if(s){c=d;while(1){g=s<<24>>24;if(g-65>>>0<26){E[c|0]=g-65>>>0<26?g|32:g}s=H[c+1|0];c=c+1|0;if(s){continue}break}}q=d+78|0;s=H[q|0];if(s){c=q;while(1){g=s<<24>>24;if(g-65>>>0<26){E[c|0]=g-65>>>0<26?g|32:g}s=H[c+1|0];c=c+1|0;if(s){continue}break}}s=H[k|0];if(s){c=k;while(1){g=s<<24>>24;if(g-65>>>0<26){E[c|0]=g-65>>>0<26?g|32:g}s=H[c+1|0];c=c+1|0;if(s){continue}break}}g=k+78|0;s=H[g|0];if(s){c=g;while(1){w=s<<24>>24;if(w-65>>>0<26){E[c|0]=w-65>>>0<26?w|32:w}s=H[c+1|0];c=c+1|0;if(s){continue}break}}x:{y:{if(!Xa(d,13289)){break y}if(!Xa(d,30708)){break y}s=0;break x}s=0;z:{switch(H[q|0]-98|0){case 0:s=1;break;case 8:break z;default:break u}}V=vb(d+79|0,h+192|0);c=G[h+192>>2];if(!c|H[c|0]){break u}}A:{B:{if(!Xa(k,13289)){break B}if(!Xa(k,30708)){break B}break A}C:{switch(H[g|0]-98|0){case 0:N=1;break;case 8:break C;default:break u}}y=vb(k+79|0,h+192|0);c=G[h+192>>2];if(!c|H[c|0]){break u}}D:{if(!Xa(d,13289)){break D}if(!Xa(d,30708)){s=s?3:2;break D}if(!Xa(d,31605)){s=4;break D}if(Xa(d,17546)){break u}s=5}E:{if(!Xa(k,13289)){break E}if(!Xa(k,30708)){N=N?3:2;break E}if(!Xa(k,31605)){N=4;break E}if(Xa(k,17546)){break u}N=5}c=1}ca=c;if((am(d+72|0,h+192|0,h+184|0)|0)<0){break u}w=d- -64|0;q=d+28|0;v=d;g=d+3|0;c=G[h+192>>2];d=G[h+184>>2];if(!(!c|(d|0)==1)){ea=v,fa=vb(g,h+220|0),L[ea+56>>3]=fa;c=G[h+220>>2];if(!c|H[c|0]){break u}ea=w,fa=vb(q,h+220|0),L[ea>>3]=fa;c=G[h+220>>2];if(!c|H[c|0]){break u}c=G[h+192>>2]}F:{G:{if(!(c|(d|0)!=1)){L[h+176>>3]=L[v+56>>3];Eb(g,18786,h+176|0);L[h+160>>3]=L[w>>3];Eb(q,18786,h+160|0);break G}H:{I:{J:{K:{L:{switch(d-1|0){case 1:l=L[w>>3];e=L[v+56>>3];break K;case 3:l=L[w>>3];e=L[v+56>>3];break I;case 0:break G;case 4:break J;case 2:break L;default:break F}}l=L[w>>3]/1e3;e=L[v+56>>3]/1e3}L[v+56>>3]=e*57.29577951308232;e=l*57.29577951308232;break H}l=L[w>>3]/1e3;e=L[v+56>>3]/1e3}L[v+56>>3]=e/3600;e=l/3600}L[w>>3]=e;break F}j=Fa-448|0;Fa=j;c=Za(j+400|0,g);z=Za(j+352|0,q);F[j+64>>1]=48;F[j+160>>1]=48;F[j+16>>1]=48;d=0;_=Za(j+208|0,c);e=-1;l=1;M:{N:{while(1){q=c+d|0;g=H[q|0];if((g|0)!=32){O:{switch(g-43|0){case 2:break N;case 0:break O;default:break M}}}else{d=d+1|0;continue}break}e=1}E[q|0]=32;l=e}o=-1;m=-1;u=-1;P:{Q:{R:{d=Va(c);if((d|0)<=0){break R}J=d&1;S:{if((d|0)==1){d=0;break S}P=d&-2;d=0;while(1){R=d|1;X=H[R+c|0]&223;g=H[c+d|0]&223;u=(X|0)==83?R:(g|0)==83?d:u;m=(X|0)==77?R:(g|0)==77?d:m;Q=(g|0)==68;t=(g|0)==72;g=t?r:Q?1:r;r=g;q=(X|0)==68;da=q?1:g;g=(X|0)==72;r=g?r:da;o=g?R:q?R:t?d:Q?d:o;d=d+2|0;I=I+2|0;if((P|0)!=(I|0)){continue}break}}if(J){t=H[c+d|0]&223;q=(t|0)==68;g=(t|0)==72;o=g?d:q?d:o;r=g?r:q?1:r;m=(t|0)==77?d:m;u=(t|0)==83?d:u}d=1;if(!((o|0)<=0|(m|0)<=0)&(m|0)<(o|0)|!((o|0)<=0|(u|0)<=0)&(o|0)>(u|0)){break P}if(!((m|0)<=0|(u|0)<=0)&(m|0)>(u|0)){break P}T:{U:{V:{W:{d=(o|0)>0;X:{if(d){ea=Za(j+160|0,c)+o|0,ga=0,E[ea|0]=ga;if((m|0)<=0){break X}if(m-1>>>0<=o>>>0){break W}d=1;ea=Za(j- -64|0,(c+o|0)+1|0)+((o^-1)+m|0)|0,ga=0,E[ea|0]=ga;if((u|0)>0){break V}break R}if((m|0)>0){break W}}if((u|0)<=0){break R}g=u-1|0;break U}ea=Za(j- -64|0,c)+m|0,ga=0,E[ea|0]=ga;if((u|0)<=0){break R}}g=u-1|0;if((m|0)>=(g|0)){break U}Za(j+16|0,(c+m|0)+1|0);u=(m^-1)+u|0;break T}if(!(!d|(g|0)<=(o|0))){Za(j+16|0,(c+o|0)+1|0);u=(o^-1)+u|0;break T}Za(j+16|0,c)}E[(j+16|0)+u|0]=0;G[j+8>>2]=0;break Q}G[j+8>>2]=0;if((o&m&u)==-1){while(1){d=c;c=c+1|0;g=H[d|0];if((g|0)==32){continue}break}G[j+304>>2]=d;if(!g){break Q}c=0;while(1){q=c;Y:{while(1){c=g&255;if(!c){break Y}if(!((c|0)==32|(c|0)==58)){g=H[d+1|0];d=d+1|0;continue}break}E[d|0]=0;d=d+1|0}g=d;while(1){d=g;g=d+1|0;if(H[d|0]==32){continue}break}c=q+1|0;G[(j+304|0)+(c<<2)>>2]=d;g=H[d|0];if(g){continue}break}G[j+8>>2]=c;if(q>>>0>=2){Za(j+160|0,G[j+304>>2]);Za(j- -64|0,G[j+308>>2]);Za(j+16|0,G[j+312>>2]);break Q}Z:{switch(q|0){case 1:Za(j- -64|0,G[j+304>>2]);Za(j+16|0,G[j+308>>2]);break Q;case 0:break Z;default:break Q}}Za(j+16|0,G[j+304>>2]);break Q}if((m&u)==-1){c=c+o|0;while(1){g=H[c+1|0];d=c+1|0;c=d;if((g|0)==32){continue}break}G[j+304>>2]=d;if(!g){break Q}c=0;while(1){q=c;_:{while(1){c=g&255;if(!c){break _}if(!((c|0)==32|(c|0)==58)){g=H[d+1|0];d=d+1|0;continue}break}E[d|0]=0;d=d+1|0}g=d;while(1){d=g;g=d+1|0;if(H[d|0]==32){continue}break}c=q+1|0;G[(j+304|0)+(c<<2)>>2]=d;g=H[d|0];if(g){continue}break}G[j+8>>2]=c;$:{switch(q|0){case 1:Za(j- -64|0,G[j+304>>2]);Za(j+16|0,G[j+308>>2]);break Q;case 0:break $;default:break Q}}Za(j- -64|0,G[j+304>>2]);break Q}if((u|0)!=-1){break Q}Nh((c+m|0)+1|0,j+304|0,j+8|0);if(G[j+8>>2]!=1){break Q}Za(j+16|0,G[j+304>>2])}d=0;aa:{if((mg(j+16|0)|0)!=1){I=0;e=0;break aa}mg(j- -64|0);e=0;I=mg(j+160|0);if((I|0)!=1){break aa}e=sb(j+16|0);if(e>60){p=e/1e4;ba:{if(O(p)<2147483648){c=~~p;break ba}c=-2147483648}B=+(c|0);p=e-B*1e4;e=p/100;ca:{if(O(e)<2147483648){c=~~e;break ca}c=-2147483648}e=p;p=+(c|0);e=e-p*100;I=1;break aa}I=1;B=sb(j+160|0);p=sb(j- -64|0)}L[v+56>>3]=l*((r|0)==1?1:15)*(B+p/60+e/3600);J=Za(j+256|0,_);g=Va(J);e=vb(J,j+12|0);da:{if(!H[J|0]){c=0;break da}while(1){c=d+J|0;if(H[c|0]==46){E[c|0]=0}c=Va(J);d=d+1|0;if(c>>>0>d>>>0){continue}break}}if(!(G[j+12>>2]!=(g+J|0)|c>>>0>4)){L[v+56>>3]=e;I=0}F[j+64>>1]=48;F[j+112>>1]=48;F[j+16>>1]=48;d=0;q=Za(_,z);e=-1;l=1;ea:{fa:{while(1){g=d+z|0;c=H[g|0];if((c|0)!=32){ga:{switch(c-43|0){case 2:break fa;case 0:break ga;default:break ea}}}else{d=d+1|0;continue}break}e=1}E[g|0]=32;l=e}r=-1;o=-1;m=-1;ha:{ia:{c=Va(z);if((c|0)<=0){break ia}g=c&1;ja:{if((c|0)==1){d=0;break ja}c=c&-2;d=0;u=0;while(1){P=d|1;Q=H[P+z|0]&223;t=H[d+z|0]&223;m=(Q|0)==83?P:(t|0)==83?d:m;o=(Q|0)==77?P:(t|0)==77?d:o;r=(Q|0)==68?P:(t|0)==68?d:r;d=d+2|0;u=u+2|0;if((c|0)!=(u|0)){continue}break}}if(g){c=H[d+z|0]&223;m=(c|0)==83?d:m;o=(c|0)==77?d:o;r=(c|0)==68?d:r}d=1;if(!((r|0)<=0|(o|0)<=0)&(o|0)<(r|0)|!((r|0)<=0|(m|0)<=0)&(m|0)<(r|0)){break P}if(!((o|0)<=0|(m|0)<=0)&(m|0)<(o|0)){break P}ka:{la:{ma:{na:{d=(r|0)>0;oa:{if(d){ea=Za(j+112|0,z)+r|0,ga=0,E[ea|0]=ga;if((o|0)<=0){break oa}if(o-1>>>0<=r>>>0){break na}d=1;ea=Za(j- -64|0,(r+z|0)+1|0)+((r^-1)+o|0)|0,ga=0,E[ea|0]=ga;if((m|0)>0){break ma}break ia}if((o|0)>0){break na}}if((m|0)<=0){break ia}c=m-1|0;break la}ea=Za(j- -64|0,z)+o|0,ga=0,E[ea|0]=ga;if((m|0)<=0){break ia}}c=m-1|0;if((o|0)>=(c|0)){break la}Za(j+16|0,(o+z|0)+1|0);m=(o^-1)+m|0;break ka}if(!(!d|(c|0)<=(r|0))){Za(j+16|0,(r+z|0)+1|0);m=(r^-1)+m|0;break ka}Za(j+16|0,z)}E[(j+16|0)+m|0]=0;G[j+8>>2]=0;break ha}G[j+8>>2]=0;pa:{qa:{ra:{if((r&o&m)!=-1){if((o&m)!=-1){break pa}Nh((r+z|0)+1|0,j+304|0,j+8|0);switch(G[j+8>>2]-1|0){case 0:break qa;case 1:break ra;default:break ha}}Nh(z,j+304|0,j+8|0);c=G[j+8>>2];if((c|0)>=3){Za(j+112|0,G[j+304>>2]);Za(j- -64|0,G[j+308>>2]);Za(j+16|0,G[j+312>>2]);break ha}sa:{switch(c-1|0){case 1:Za(j- -64|0,G[j+304>>2]);Za(j+16|0,G[j+308>>2]);break ha;case 0:break sa;default:break ha}}Za(j+16|0,G[j+304>>2]);break ha}c=G[j+304>>2];Za(Za(j- -64|0,c),c);Za(j+16|0,G[j+308>>2]);break ha}Za(j- -64|0,G[j+304>>2]);break ha}if((m|0)!=-1){break ha}Nh((o+z|0)+1|0,j+304|0,j+8|0);if(G[j+8>>2]!=1){break ha}Za(j+16|0,G[j+304>>2])}c=1;B=0;d=0;ta:{ua:{if((mg(j+16|0)|0)!=1){break ua}if((mg(j- -64|0)|0)!=1){break ua}p=0;e=0;g=mg(j+112|0);if((g|0)!=1){break ta}e=sb(j+16|0);if(e>60){p=e/1e4;va:{if(O(p)<2147483648){g=~~p;break va}g=-2147483648}B=+(g|0);p=e-B*1e4;e=p/100;wa:{if(O(e)<2147483648){g=~~e;break wa}g=-2147483648}e=p;p=+(g|0);e=e-p*100;g=1;break ta}g=1;B=sb(j+112|0);p=sb(j- -64|0);break ta}g=0;p=0;e=0}L[w>>3]=l*(B+p/60+e/3600);t=Za(J,q);q=Va(t);e=vb(t,j+12|0);if(H[t|0]){while(1){c=d+t|0;if(H[c|0]==46){E[c|0]=0}d=d+1|0;c=Va(t);if(d>>>0>>0){continue}break}c=c>>>0<5}xa:{if(!(!c|G[j+12>>2]!=(q+t|0))){L[w>>3]=e;g=0;c=0;if(!(O(e)>90)){break xa}}if(!(g|I)){d=3;break P}c=!g<<1}d=I?c:1}Fa=j+448|0;if(d){break u}}e=L[v+56>>3];if(e<0){while(1){e=e+360;if(e<0){continue}break}L[v+56>>3]=e}if(e>360){while(1){e=e+-360;if(e>360){continue}break}L[v+56>>3]=e}l=L[w>>3];if(l<-90|l>90){break u}ya:{if(ca){dd(s,V,e,l,N,y,k+56|0,k- -64|0);break ya}L[k+64>>3]=l;L[k+56>>3]=e}if((am(k+72|0,0,h+220|0)|0)<0){break u}c=G[h+220>>2];t=$l(c,1);if((t|0)<0){break u}v=$l(c,0);if((v|0)<0){break u}w=k+28|0;q=k+3|0;za:{Aa:{Ba:{Ca:{switch(c-1|0){default:e=L[k+56>>3];break Aa;case 2:e=L[k+56>>3]*.017453292519943295*1e3;L[k+56>>3]=e;l=L[k+64>>3]*.017453292519943295*1e3;break Ba;case 3:e=L[k+56>>3]*3600;L[k+56>>3]=e;l=L[k+64>>3]*3600;break Ba;case 4:e=L[k+56>>3]*3600*1e3;L[k+56>>3]=e;l=L[k+64>>3]*3600*1e3;break Ba;case 0:m=-1;e=L[k+56>>3];Da:{if(e<-360|e>360){break Da}Ea:{if(e<0){G[h+200>>2]=1;e=O(e);break Ea}G[h+200>>2]=0}l=e/15;e=S(l);Fa:{if(O(e)<2147483648){c=~~e;break Fa}c=-2147483648}G[h+212>>2]=c;l=(l-+(c|0))*60;e=S(l);Ga:{if(O(e)<2147483648){g=~~e;break Ga}g=-2147483648}G[h+208>>2]=g;p=$b(10,+(t|0));e=(l-+(g|0))*60;Ha:{if(e<0){e=T(e*p+-.5);break Ha}e=S(e*p+.5)}e=e/p;L[h+192>>3]=e;if(e>=60){L[h+192>>3]=e+-60;g=g+1|0;G[h+208>>2]=g}m=0;if((g|0)<60){break Da}G[h+208>>2]=g-60;G[h+212>>2]=G[h+212>>2]+1}if((m|0)<0){break u}g=G[h+200>>2]?48783:92041;d=G[h+208>>2];c=G[h+212>>2];Ia:{if(!t){L[h+112>>3]=L[h+192>>3];G[h+96>>2]=g;G[h+100>>2]=c;G[h+104>>2]=d;Eb(q,7144,h+96|0);break Ia}G[h+144>>2]=t;L[h+152>>3]=L[h+192>>3];G[h+128>>2]=g;G[h+132>>2]=c;G[h+136>>2]=d;G[h+140>>2]=t+3;Eb(q,7188,h+128|0)}e=L[h+192>>3]+(+G[h+212>>2]*1e4+ +G[h+208>>2]*100);L[k+56>>3]=e;if(G[h+200>>2]){L[k+56>>3]=-e}g=-1;e=L[k+64>>3];Ja:{if(e<-360|e>360){break Ja}Ka:{if(e<0){G[h+200>>2]=1;e=O(e);break Ka}G[h+200>>2]=0}l=S(e);La:{if(O(l)<2147483648){c=~~l;break La}c=-2147483648}G[h+216>>2]=c;l=(e-+(c|0))*60;e=S(l);Ma:{if(O(e)<2147483648){d=~~e;break Ma}d=-2147483648}G[h+204>>2]=d;p=$b(10,+(v|0));e=(l-+(d|0))*60;Na:{if(e<0){e=T(e*p+-.5);break Na}e=S(e*p+.5)}e=e/p;L[h+184>>3]=e;if(e>=60){L[h+184>>3]=e+-60;d=d+1|0;G[h+204>>2]=d}g=0;if((d|0)<60){break Ja}G[h+204>>2]=d-60;G[h+216>>2]=G[h+216>>2]+1}if((g|0)<0){break u}g=G[h+200>>2]?48783:49026;d=G[h+204>>2];c=G[h+216>>2];Oa:{if(!v){L[h+48>>3]=L[h+184>>3];G[h+32>>2]=g;G[h+36>>2]=c;G[h+40>>2]=d;Eb(w,7166,h+32|0);break Oa}G[h+80>>2]=v;L[h+88>>3]=L[h+184>>3];G[h+64>>2]=g;G[h+68>>2]=c;G[h+72>>2]=d;G[h+76>>2]=v+3;Eb(w,7210,h- -64|0)}e=L[h+184>>3]+(+G[h+216>>2]*1e4+ +G[h+204>>2]*100);L[k+64>>3]=e;if(!G[h+200>>2]){break za}L[k+64>>3]=-e;break za;case 1:break Ca}}e=L[k+56>>3]*.017453292519943295;L[k+56>>3]=e;l=L[k+64>>3]*.017453292519943295}L[k+64>>3]=l}e=bm(e,t);L[k+56>>3]=e;L[h+24>>3]=e;G[h+16>>2]=t;Eb(q,19659,h+16|0);e=bm(L[k+64>>3],v);L[k+64>>3]=e;L[h+8>>3]=e;G[h>>2]=v;Eb(w,19653,h)}}Fa=h+224|0;G[i+464>>2]=G[b>>2];_a(G[935266],29730,i+464|0);L[i+448>>3]=L[b+1120>>3];xb(G[935266],18791,i+448|0);L[i+432>>3]=L[b+1128>>3];xb(G[935266],18791,i+432|0);G[i+416>>2]=k|3;_a(G[935266],8700,i+416|0);G[i+400>>2]=i+636;_a(G[935266],8700,i+400|0);G[i+384>>2]=G[b+1060>>2];_a(G[935266],29730,i+384|0);G[i+368>>2]=G[b+1064>>2];_a(G[935266],29730,i+368|0);G[i+352>>2]=b+1040;_a(G[935266],8651,i+352|0);G[i+336>>2]=b+1050;_a(G[935266],8651,i+336|0);L[i+320>>3]=K[b+1068>>2];xb(G[935266],18922,i+320|0);L[i+304>>3]=K[b+1072>>2];xb(G[935266],18922,i+304|0);L[i+288>>3]=L[b+1080>>3];xb(G[935266],18791,i+288|0);L[i+272>>3]=L[b+1088>>3];xb(G[935266],18791,i+272|0);L[i+256>>3]=L[b+1096>>3];xb(G[935266],25572,i+256|0);L[i+240>>3]=L[b+1104>>3];xb(G[935266],25572,i+240|0);L[i+224>>3]=L[b+1112>>3];xb(G[935266],18791,i+224|0);L[i+208>>3]=L[b+1208>>3];xb(G[935266],19234,i+208|0);if(G[935262]>0){while(1){d=M(W,516);G[i+192>>2]=G[(d+G[935263]|0)+512>>2];c=i+1040|0;db(c,8433,i+192|0);G[i+176>>2]=(d+G[935263]|0)+256;_a(G[935266],c,i+176|0);W=W+1|0;if((W|0)>3]=L[b+1136>>3];xb(G[935266],18791,i+160|0);L[i+144>>3]=L[b+1144>>3];xb(G[935266],18791,i+144|0);L[i+128>>3]=L[b+1152>>3];xb(G[935266],18791,i+128|0);L[i+112>>3]=L[b+1160>>3];xb(G[935266],18791,i+112|0);L[i+96>>3]=L[b+1168>>3];xb(G[935266],18791,i+96|0);L[i+80>>3]=L[b+1176>>3];xb(G[935266],18791,i+80|0);L[i+64>>3]=L[b+1184>>3];xb(G[935266],18791,i- -64|0);L[i+48>>3]=L[b+1192>>3];xb(G[935266],18791,i+48|0)}c=G[b+1036>>2];G[i+32>>2]=G[b+1032>>2];G[i+36>>2]=c;_a(G[935266],26726,i+32|0);G[i+16>>2]=G[b+1028>>2]-1;_a(G[935266],29730,i+16|0);G[i>>2]=b+4;_a(G[935266],69730,i);$a(G[935266]);G[935247]=G[935247]+1;Fa=i+1072|0;G[935254]=G[935254]+1;if(!D){break b}Wa(n)}c=G[b+1028>>2]+1|0;G[b+1028>>2]=c;G[f+344>>2]=0;if(!mb(G[f+348>>2],c,0,f+344|0)){continue}break}}G[f+344>>2]=0;Qb(G[f+348>>2],f+344|0)}Fa=f+2416|0;return x}function qq(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0;j=Fa-816|0;Fa=j;a:{if(G[i>>2]>0){break a}l=G[a>>2];k=G[a+4>>2];if((l|0)!=G[k+76>>2]){mb(a,l+1|0,0,i);k=G[a+4>>2];l=G[k+76>>2]}l=G[k+96>>2]+(l<<3)|0;if(G[k+104>>2]!=G[l>>2]|G[k+108>>2]!=G[l+4>>2]){G[i>>2]=201;break a}if((c|0)<0){G[i>>2]=218;break a}if(d>>>0>=1e3){G[i>>2]=216;break a}E[j+352|0]=0;if(h){qb(j+352|0,h,70)}lc(a,34516,35618,15302,i);b:{if(G[i>>2]>0){break b}G[j+240>>2]=8;G[j+244>>2]=0;E[j+256|0]=0;if((db(j+256|0,26741,j+240|0)|0)<0){Ua(17884);G[i>>2]=401}h=j+640|0;Ob(32941,j+256|0,7410,h,i);wb(a,h,i);if(G[i>>2]>0){break b}G[j+224>>2]=2;G[j+228>>2]=0;E[j+256|0]=0;if((db(j+256|0,26741,j+224|0)|0)<0){Ua(17884);G[i>>2]=401}h=j+640|0;Ob(33788,j+256|0,23165,h,i);wb(a,h,i)}c:{d:{if(d){k=0;while(1){m=(k<<2)+f|0;Vf(G[m>>2],j+636|0,j+632|0,j+628|0,i);e:{f:{l=G[j+636>>2];h=l-1|0;if(h){if((h|0)!=15){break f}h=G[j+632>>2];l=h>>31;break e}h=(G[j+632>>2]+7|0)/8|0;l=h>>31;break e}if((l|0)>0){h=M(G[j+632>>2],(l>>>0)/10|0);l=h>>31;break e}h=8;m=G[m>>2];l=0;if((H[m|0]|32)==112){break e}h=H[m+1|0]-80&223?16:8;l=0}if(G[i>>2]>0){break c}n=l+n|0;m=h+o|0;n=m>>>0>>0?n+1|0:n;o=m;k=k+1|0;if((k|0)!=(d|0)){continue}break}break d}if(G[i>>2]>0){break c}}G[j+208>>2]=o;G[j+212>>2]=n;E[j+256|0]=0;if((db(j+256|0,26741,j+208|0)|0)<0){Ua(17884);G[i>>2]=401}h=j+640|0;Ob(41261,j+256|0,7422,h,i);wb(a,h,i);if(G[i>>2]>0){break c}G[j+192>>2]=b;G[j+196>>2]=c;E[j+256|0]=0;if((db(j+256|0,26741,j+192|0)|0)<0){Ua(17884);G[i>>2]=401}b=j+640|0;Ob(40853,j+256|0,23289,b,i);wb(a,b,i);if(G[i>>2]>0){break c}G[j+176>>2]=0;G[j+180>>2]=0;E[j+256|0]=0;if((db(j+256|0,26741,j+176|0)|0)<0){Ua(17884);G[i>>2]=401}b=j+640|0;Ob(33303,j+256|0,31608,b,i);wb(a,b,i);if(G[i>>2]>0){break c}G[j+160>>2]=1;G[j+164>>2]=0;E[j+256|0]=0;if((db(j+256|0,26741,j+160|0)|0)<0){Ua(17884);G[i>>2]=401}b=j+640|0;Ob(33311,j+256|0,61992,b,i);wb(a,b,i);if(G[i>>2]>0){break c}E[j+256|0]=0;G[j+144>>2]=d;G[j+148>>2]=d>>31;if((db(j+256|0,26741,j+144|0)|0)<0){Ua(17884);G[i>>2]=401}b=j+640|0;Ob(33837,j+256|0,3872,b,i);wb(a,b,i)}n=(d|0)>0?d:0;h=0;while(1){g:{if((h|0)==(n|0)){break g}o=h<<2;d=o+e|0;if(H[G[d>>2]]){b=h+1|0;G[j+128>>2]=b;c=j+432|0;Ya(c,73,29741,j+128|0);k=b;b=j+512|0;zb(35402,k,b,i);lc(a,b,G[d>>2],c,i)}b=G[f+o>>2];if(Va(b)>>>0>=30){Ua(56310);G[i>>2]=261;break g}c=Za(j+592|0,b);Yf(c);h=h+1|0;zb(34641,h,j+512|0,i);d=H[26802]|H[26803]<<8|(H[26804]<<16|H[26805]<<24);b=H[26798]|H[26799]<<8|(H[26800]<<16|H[26801]<<24);E[j+445|0]=b;E[j+446|0]=b>>>8;E[j+447|0]=b>>>16;E[j+448|0]=b>>>24;E[j+449|0]=d;E[j+450|0]=d>>>8;E[j+451|0]=d>>>16;E[j+452|0]=d>>>24;b=H[26797]|H[26798]<<8|(H[26799]<<16|H[26800]<<24);G[j+440>>2]=H[26793]|H[26794]<<8|(H[26795]<<16|H[26796]<<24);G[j+444>>2]=b;b=H[26789]|H[26790]<<8|(H[26791]<<16|H[26792]<<24);G[j+432>>2]=H[26785]|H[26786]<<8|(H[26787]<<16|H[26788]<<24);G[j+436>>2]=b;Vf(c,j+636|0,j+632|0,j+628|0,i);h:{i:{j:{k:{l:{m:{n:{o:{p:{q:{r:{s:{t:{u:{v:{w:{x:{b=G[j+636>>2];switch(b-1|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 11:case 12:case 14:case 16:case 17:case 18:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 34:case 35:case 36:case 37:case 38:case 42:case 43:case 44:case 45:case 46:case 47:case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 65:case 66:case 67:case 68:case 69:case 70:case 71:case 72:case 73:case 74:case 75:case 76:case 77:case 78:break j;case 82:break l;case 81:break m;case 41:break n;case 79:break o;case 39:break p;case 80:break q;case 40:break r;case 19:break s;case 20:break t;case 13:break u;case 10:break v;case 0:break w;case 15:break x;default:break k}}b=j+432|0;b=Va(b)+b|0;k=H[11103]|H[11104]<<8|(H[11105]<<16|H[11106]<<24);d=H[11099]|H[11100]<<8|(H[11101]<<16|H[11102]<<24);E[b|0]=d;E[b+1|0]=d>>>8;E[b+2|0]=d>>>16;E[b+3|0]=d>>>24;E[b+4|0]=k;E[b+5|0]=k>>>8;E[b+6|0]=k>>>16;E[b+7|0]=k>>>24;d=H[11115]|H[11116]<<8;E[b+16|0]=d;E[b+17|0]=d>>>8;k=H[11111]|H[11112]<<8|(H[11113]<<16|H[11114]<<24);d=H[11107]|H[11108]<<8|(H[11109]<<16|H[11110]<<24);E[b+8|0]=d;E[b+9|0]=d>>>8;E[b+10|0]=d>>>16;E[b+11|0]=d>>>24;E[b+12|0]=k;E[b+13|0]=k>>>8;E[b+14|0]=k>>>16;E[b+15|0]=k>>>24;b=jb(c,65);G[j+112>>2]=j+628;if((Qc(b+1|0,27698,j+112|0)|0)!=1){break h}b=G[j+632>>2];if((b|0)>=G[j+628>>2]){break h}if((b|0)==1){d=H[36118]|H[36119]<<8|(H[36120]<<16|H[36121]<<24);b=H[36114]|H[36115]<<8|(H[36116]<<16|H[36117]<<24);E[j+471|0]=b;E[j+472|0]=b>>>8;E[j+473|0]=b>>>16;E[j+474|0]=b>>>24;E[j+475|0]=d;E[j+476|0]=d>>>8;E[j+477|0]=d>>>16;E[j+478|0]=d>>>24;b=H[36111]|H[36112]<<8|(H[36113]<<16|H[36114]<<24);G[j+464>>2]=H[36107]|H[36108]<<8|(H[36109]<<16|H[36110]<<24);G[j+468>>2]=b;b=H[36103]|H[36104]<<8|(H[36105]<<16|H[36106]<<24);G[j+456>>2]=H[36099]|H[36100]<<8|(H[36101]<<16|H[36102]<<24);G[j+460>>2]=b;b=H[36095]|H[36096]<<8|(H[36097]<<16|H[36098]<<24);G[j+448>>2]=H[36091]|H[36092]<<8|(H[36093]<<16|H[36094]<<24);G[j+452>>2]=b;b=H[36087]|H[36088]<<8|(H[36089]<<16|H[36090]<<24);G[j+440>>2]=H[36083]|H[36084]<<8|(H[36085]<<16|H[36086]<<24);G[j+444>>2]=b;b=H[36079]|H[36080]<<8|(H[36081]<<16|H[36082]<<24);G[j+432>>2]=H[36075]|H[36076]<<8|(H[36077]<<16|H[36078]<<24);G[j+436>>2]=b;break h}b=H[13285]|H[13286]<<8|(H[13287]<<16|H[13288]<<24);G[j+472>>2]=H[13281]|H[13282]<<8|(H[13283]<<16|H[13284]<<24);G[j+476>>2]=b;b=H[13277]|H[13278]<<8|(H[13279]<<16|H[13280]<<24);G[j+464>>2]=H[13273]|H[13274]<<8|(H[13275]<<16|H[13276]<<24);G[j+468>>2]=b;b=H[13269]|H[13270]<<8|(H[13271]<<16|H[13272]<<24);G[j+456>>2]=H[13265]|H[13266]<<8|(H[13267]<<16|H[13268]<<24);G[j+460>>2]=b;b=H[13261]|H[13262]<<8|(H[13263]<<16|H[13264]<<24);G[j+448>>2]=H[13257]|H[13258]<<8|(H[13259]<<16|H[13260]<<24);G[j+452>>2]=b;b=H[13253]|H[13254]<<8|(H[13255]<<16|H[13256]<<24);G[j+440>>2]=H[13249]|H[13250]<<8|(H[13251]<<16|H[13252]<<24);G[j+444>>2]=b;b=H[13245]|H[13246]<<8|(H[13247]<<16|H[13248]<<24);G[j+432>>2]=H[13241]|H[13242]<<8|(H[13243]<<16|H[13244]<<24);G[j+436>>2]=b;break h}b=j+432|0;d=Va(b)+b|0;b=H[33394]|H[33395]<<8|(H[33396]<<16|H[33397]<<24);E[d|0]=b;E[d+1|0]=b>>>8;E[d+2|0]=b>>>16;E[d+3|0]=b>>>24;b=H[33398]|H[33399]<<8;E[d+4|0]=b;E[d+5|0]=b>>>8;break h}b=j+432|0;d=Va(b)+b|0;b=H[35376]|H[35377]<<8|(H[35378]<<16|H[35379]<<24);E[d|0]=b;E[d+1|0]=b>>>8;E[d+2|0]=b>>>16;E[d+3|0]=b>>>24;b=H[35379]|H[35380]<<8|(H[35381]<<16|H[35382]<<24);E[d+3|0]=b;E[d+4|0]=b>>>8;E[d+5|0]=b>>>16;E[d+6|0]=b>>>24;break h}b=j+432|0;b=Va(b)+b|0;k=H[34848]|H[34849]<<8|(H[34850]<<16|H[34851]<<24);d=H[34844]|H[34845]<<8|(H[34846]<<16|H[34847]<<24);E[b|0]=d;E[b+1|0]=d>>>8;E[b+2|0]=d>>>16;E[b+3|0]=d>>>24;E[b+4|0]=k;E[b+5|0]=k>>>8;E[b+6|0]=k>>>16;E[b+7|0]=k>>>24;E[b+16|0]=H[34860];k=H[34856]|H[34857]<<8|(H[34858]<<16|H[34859]<<24);d=H[34852]|H[34853]<<8|(H[34854]<<16|H[34855]<<24);E[b+8|0]=d;E[b+9|0]=d>>>8;E[b+10|0]=d>>>16;E[b+11|0]=d>>>24;E[b+12|0]=k;E[b+13|0]=k>>>8;E[b+14|0]=k>>>16;E[b+15|0]=k>>>24;break h}b=j+432|0;b=Va(b)+b|0;k=H[34087]|H[34088]<<8|(H[34089]<<16|H[34090]<<24);d=H[34083]|H[34084]<<8|(H[34085]<<16|H[34086]<<24);E[b|0]=d;E[b+1|0]=d>>>8;E[b+2|0]=d>>>16;E[b+3|0]=d>>>24;E[b+4|0]=k;E[b+5|0]=k>>>8;E[b+6|0]=k>>>16;E[b+7|0]=k>>>24;E[b+16|0]=H[34099];k=H[34095]|H[34096]<<8|(H[34097]<<16|H[34098]<<24);d=H[34091]|H[34092]<<8|(H[34093]<<16|H[34094]<<24);E[b+8|0]=d;E[b+9|0]=d>>>8;E[b+10|0]=d>>>16;E[b+11|0]=d>>>24;E[b+12|0]=k;E[b+13|0]=k>>>8;E[b+14|0]=k>>>16;E[b+15|0]=k>>>24;break h}b=j+432|0;b=Va(b)+b|0;k=H[34087]|H[34088]<<8|(H[34089]<<16|H[34090]<<24);d=H[34083]|H[34084]<<8|(H[34085]<<16|H[34086]<<24);E[b|0]=d;E[b+1|0]=d>>>8;E[b+2|0]=d>>>16;E[b+3|0]=d>>>24;E[b+4|0]=k;E[b+5|0]=k>>>8;E[b+6|0]=k>>>16;E[b+7|0]=k>>>24;E[b+16|0]=H[34099];k=H[34095]|H[34096]<<8|(H[34097]<<16|H[34098]<<24);d=H[34091]|H[34092]<<8|(H[34093]<<16|H[34094]<<24);E[b+8|0]=d;E[b+9|0]=d>>>8;E[b+10|0]=d>>>16;E[b+11|0]=d>>>24;E[b+12|0]=k;E[b+13|0]=k>>>8;E[b+14|0]=k>>>16;E[b+15|0]=k>>>24;break h}b=j+432|0;b=Va(b)+b|0;k=H[34070]|H[34071]<<8|(H[34072]<<16|H[34073]<<24);d=H[34066]|H[34067]<<8|(H[34068]<<16|H[34069]<<24);E[b|0]=d;E[b+1|0]=d>>>8;E[b+2|0]=d>>>16;E[b+3|0]=d>>>24;E[b+4|0]=k;E[b+5|0]=k>>>8;E[b+6|0]=k>>>16;E[b+7|0]=k>>>24;E[b+16|0]=H[34082];k=H[34078]|H[34079]<<8|(H[34080]<<16|H[34081]<<24);d=H[34074]|H[34075]<<8|(H[34076]<<16|H[34077]<<24);E[b+8|0]=d;E[b+9|0]=d>>>8;E[b+10|0]=d>>>16;E[b+11|0]=d>>>24;E[b+12|0]=k;E[b+13|0]=k>>>8;E[b+14|0]=k>>>16;E[b+15|0]=k>>>24;break h}b=j+432|0;b=Va(b)+b|0;k=H[34053]|H[34054]<<8|(H[34055]<<16|H[34056]<<24);d=H[34049]|H[34050]<<8|(H[34051]<<16|H[34052]<<24);E[b|0]=d;E[b+1|0]=d>>>8;E[b+2|0]=d>>>16;E[b+3|0]=d>>>24;E[b+4|0]=k;E[b+5|0]=k>>>8;E[b+6|0]=k>>>16;E[b+7|0]=k>>>24;E[b+16|0]=H[34065];k=H[34061]|H[34062]<<8|(H[34063]<<16|H[34064]<<24);d=H[34057]|H[34058]<<8|(H[34059]<<16|H[34060]<<24);E[b+8|0]=d;E[b+9|0]=d>>>8;E[b+10|0]=d>>>16;E[b+11|0]=d>>>24;E[b+12|0]=k;E[b+13|0]=k>>>8;E[b+14|0]=k>>>16;E[b+15|0]=k>>>24;break h}b=j+432|0;b=Va(b)+b|0;k=H[34070]|H[34071]<<8|(H[34072]<<16|H[34073]<<24);d=H[34066]|H[34067]<<8|(H[34068]<<16|H[34069]<<24);E[b|0]=d;E[b+1|0]=d>>>8;E[b+2|0]=d>>>16;E[b+3|0]=d>>>24;E[b+4|0]=k;E[b+5|0]=k>>>8;E[b+6|0]=k>>>16;E[b+7|0]=k>>>24;E[b+16|0]=H[34082];k=H[34078]|H[34079]<<8|(H[34080]<<16|H[34081]<<24);d=H[34074]|H[34075]<<8|(H[34076]<<16|H[34077]<<24);E[b+8|0]=d;E[b+9|0]=d>>>8;E[b+10|0]=d>>>16;E[b+11|0]=d>>>24;E[b+12|0]=k;E[b+13|0]=k>>>8;E[b+14|0]=k>>>16;E[b+15|0]=k>>>24;break h}b=j+432|0;b=Va(b)+b|0;k=H[34053]|H[34054]<<8|(H[34055]<<16|H[34056]<<24);d=H[34049]|H[34050]<<8|(H[34051]<<16|H[34052]<<24);E[b|0]=d;E[b+1|0]=d>>>8;E[b+2|0]=d>>>16;E[b+3|0]=d>>>24;E[b+4|0]=k;E[b+5|0]=k>>>8;E[b+6|0]=k>>>16;E[b+7|0]=k>>>24;E[b+16|0]=H[34065];k=H[34061]|H[34062]<<8|(H[34063]<<16|H[34064]<<24);d=H[34057]|H[34058]<<8|(H[34059]<<16|H[34060]<<24);E[b+8|0]=d;E[b+9|0]=d>>>8;E[b+10|0]=d>>>16;E[b+11|0]=d>>>24;E[b+12|0]=k;E[b+13|0]=k>>>8;E[b+14|0]=k>>>16;E[b+15|0]=k>>>24;break h}b=j+432|0;b=Va(b)+b|0;k=H[34828]|H[34829]<<8|(H[34830]<<16|H[34831]<<24);d=H[34824]|H[34825]<<8|(H[34826]<<16|H[34827]<<24);E[b|0]=d;E[b+1|0]=d>>>8;E[b+2|0]=d>>>16;E[b+3|0]=d>>>24;E[b+4|0]=k;E[b+5|0]=k>>>8;E[b+6|0]=k>>>16;E[b+7|0]=k>>>24;k=H[34834]|H[34835]<<8|(H[34836]<<16|H[34837]<<24);d=H[34830]|H[34831]<<8|(H[34832]<<16|H[34833]<<24);E[b+6|0]=d;E[b+7|0]=d>>>8;E[b+8|0]=d>>>16;E[b+9|0]=d>>>24;E[b+10|0]=k;E[b+11|0]=k>>>8;E[b+12|0]=k>>>16;E[b+13|0]=k>>>24;break h}b=j+432|0;b=Va(b)+b|0;k=H[35597]|H[35598]<<8|(H[35599]<<16|H[35600]<<24);d=H[35593]|H[35594]<<8|(H[35595]<<16|H[35596]<<24);E[b|0]=d;E[b+1|0]=d>>>8;E[b+2|0]=d>>>16;E[b+3|0]=d>>>24;E[b+4|0]=k;E[b+5|0]=k>>>8;E[b+6|0]=k>>>16;E[b+7|0]=k>>>24;k=H[35605]|H[35606]<<8|(H[35607]<<16|H[35608]<<24);d=H[35601]|H[35602]<<8|(H[35603]<<16|H[35604]<<24);E[b+8|0]=d;E[b+9|0]=d>>>8;E[b+10|0]=d>>>16;E[b+11|0]=d>>>24;E[b+12|0]=k;E[b+13|0]=k>>>8;E[b+14|0]=k>>>16;E[b+15|0]=k>>>24;break h}b=j+432|0;k=Va(b)+b|0;d=H[32998]|H[32999]<<8|(H[33e3]<<16|H[33001]<<24);b=H[32994]|H[32995]<<8|(H[32996]<<16|H[32997]<<24);E[k|0]=b;E[k+1|0]=b>>>8;E[k+2|0]=b>>>16;E[k+3|0]=b>>>24;E[k+4|0]=d;E[k+5|0]=d>>>8;E[k+6|0]=d>>>16;E[k+7|0]=d>>>24;b=H[33002]|H[33003]<<8;E[k+8|0]=b;E[k+9|0]=b>>>8;break h}if((b|0)==163){break i}}if((b|0)>=0){break h}b=j+432|0;b=Va(b)+b|0;k=H[3678]|H[3679]<<8|(H[3680]<<16|H[3681]<<24);d=H[3674]|H[3675]<<8|(H[3676]<<16|H[3677]<<24);E[b|0]=d;E[b+1|0]=d>>>8;E[b+2|0]=d>>>16;E[b+3|0]=d>>>24;E[b+4|0]=k;E[b+5|0]=k>>>8;E[b+6|0]=k>>>16;E[b+7|0]=k>>>24;k=H[3694]|H[3695]<<8|(H[3696]<<16|H[3697]<<24);d=H[3690]|H[3691]<<8|(H[3692]<<16|H[3693]<<24);E[b+16|0]=d;E[b+17|0]=d>>>8;E[b+18|0]=d>>>16;E[b+19|0]=d>>>24;E[b+20|0]=k;E[b+21|0]=k>>>8;E[b+22|0]=k>>>16;E[b+23|0]=k>>>24;k=H[3686]|H[3687]<<8|(H[3688]<<16|H[3689]<<24);d=H[3682]|H[3683]<<8|(H[3684]<<16|H[3685]<<24);E[b+8|0]=d;E[b+9|0]=d>>>8;E[b+10|0]=d>>>16;E[b+11|0]=d>>>24;E[b+12|0]=k;E[b+13|0]=k>>>8;E[b+14|0]=k>>>16;E[b+15|0]=k>>>24;break h}b=j+432|0;b=Va(b)+b|0;k=H[32981]|H[32982]<<8|(H[32983]<<16|H[32984]<<24);d=H[32977]|H[32978]<<8|(H[32979]<<16|H[32980]<<24);E[b|0]=d;E[b+1|0]=d>>>8;E[b+2|0]=d>>>16;E[b+3|0]=d>>>24;E[b+4|0]=k;E[b+5|0]=k>>>8;E[b+6|0]=k>>>16;E[b+7|0]=k>>>24;E[b+16|0]=H[32993];k=H[32989]|H[32990]<<8|(H[32991]<<16|H[32992]<<24);d=H[32985]|H[32986]<<8|(H[32987]<<16|H[32988]<<24);E[b+8|0]=d;E[b+9|0]=d>>>8;E[b+10|0]=d>>>16;E[b+11|0]=d>>>24;E[b+12|0]=k;E[b+13|0]=k>>>8;E[b+14|0]=k>>>16;E[b+15|0]=k>>>24}k=c;d=k;l=k;b=G[j+636>>2];m=b>>31;y:{z:{A:{B:{C:{D:{E:{b=(b^m)-m|0;switch(b-12|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:break A;case 28:break C;case 8:break D;case 0:break E;default:break B}}while(1){b=k;k=b+1|0;if(H[b|0]!=83){continue}break}E[b|0]=66;b=j+512|0;lc(a,b,c,j+432|0,i);zb(34362,h,b,i);b=H[7466]|H[7467]<<8|(H[7468]<<16|H[7469]<<24);G[j+448>>2]=H[7462]|H[7463]<<8|(H[7464]<<16|H[7465]<<24);G[j+452>>2]=b;b=H[7458]|H[7459]<<8|(H[7460]<<16|H[7461]<<24);G[j+440>>2]=H[7454]|H[7455]<<8|(H[7456]<<16|H[7457]<<24);G[j+444>>2]=b;b=H[7450]|H[7451]<<8|(H[7452]<<16|H[7453]<<24);G[j+432>>2]=H[7446]|H[7447]<<8|(H[7448]<<16|H[7449]<<24);G[j+436>>2]=b;if(G[i>>2]<=0){G[j+16>>2]=0;E[j+736|0]=0;G[j+24>>2]=0;G[j+28>>2]=-1067450368;if((Ya(j+736|0,71,19659,j+16|0)|0)<0){Ua(17928);G[i>>2]=402}b=jb(j+736|0,44);if(b){E[b|0]=46}if(jb(j+736|0,78)){Ua(35198);G[i>>2]=402}b=j+640|0;Ob(j+512|0,j+736|0,j+432|0,b,i);wb(a,b,i)}zb(34838,h,j+512|0,i);G[j+448>>2]=H[29394]|H[29395]<<8|(H[29396]<<16|H[29397]<<24);b=H[29390]|H[29391]<<8|(H[29392]<<16|H[29393]<<24);G[j+440>>2]=H[29386]|H[29387]<<8|(H[29388]<<16|H[29389]<<24);G[j+444>>2]=b;b=H[29382]|H[29383]<<8|(H[29384]<<16|H[29385]<<24);G[j+432>>2]=H[29378]|H[29379]<<8|(H[29380]<<16|H[29381]<<24);G[j+436>>2]=b;if(G[i>>2]>0){break y}G[j>>2]=0;E[j+736|0]=0;G[j+8>>2]=0;G[j+12>>2]=1072693248;if((Ya(j+736|0,71,19659,j)|0)<0){Ua(17928);G[i>>2]=402}b=jb(j+736|0,44);if(b){E[b|0]=46}if(jb(j+736|0,78)){Ua(35198);G[i>>2]=402}b=j+640|0;Ob(j+512|0,j+736|0,j+432|0,b,i);wb(a,b,i);break y}while(1){b=d;d=b+1|0;if(H[b|0]!=85){continue}break}E[b|0]=73;b=j+512|0;lc(a,b,c,j+432|0,i);zb(34362,h,b,i);c=H[6483]|H[6484]<<8|(H[6485]<<16|H[6486]<<24);b=H[6479]|H[6480]<<8|(H[6481]<<16|H[6482]<<24);E[j+453|0]=b;E[j+454|0]=b>>>8;E[j+455|0]=b>>>16;E[j+456|0]=b>>>24;E[j+457|0]=c;E[j+458|0]=c>>>8;E[j+459|0]=c>>>16;E[j+460|0]=c>>>24;b=H[6478]|H[6479]<<8|(H[6480]<<16|H[6481]<<24);G[j+448>>2]=H[6474]|H[6475]<<8|(H[6476]<<16|H[6477]<<24);G[j+452>>2]=b;b=H[6470]|H[6471]<<8|(H[6472]<<16|H[6473]<<24);G[j+440>>2]=H[6466]|H[6467]<<8|(H[6468]<<16|H[6469]<<24);G[j+444>>2]=b;b=H[6462]|H[6463]<<8|(H[6464]<<16|H[6465]<<24);G[j+432>>2]=H[6458]|H[6459]<<8|(H[6460]<<16|H[6461]<<24);G[j+436>>2]=b;if(G[i>>2]<=0){G[j+48>>2]=0;E[j+736|0]=0;G[j+56>>2]=0;G[j+60>>2]=1088421888;if((Ya(j+736|0,71,19659,j+48|0)|0)<0){Ua(17928);G[i>>2]=402}b=jb(j+736|0,44);if(b){E[b|0]=46}if(jb(j+736|0,78)){Ua(35198);G[i>>2]=402}b=j+640|0;Ob(j+512|0,j+736|0,j+432|0,b,i);wb(a,b,i)}zb(34838,h,j+512|0,i);G[j+448>>2]=H[29394]|H[29395]<<8|(H[29396]<<16|H[29397]<<24);b=H[29390]|H[29391]<<8|(H[29392]<<16|H[29393]<<24);G[j+440>>2]=H[29386]|H[29387]<<8|(H[29388]<<16|H[29389]<<24);G[j+444>>2]=b;b=H[29382]|H[29383]<<8|(H[29384]<<16|H[29385]<<24);G[j+432>>2]=H[29378]|H[29379]<<8|(H[29380]<<16|H[29381]<<24);G[j+436>>2]=b;if(G[i>>2]>0){break y}G[j+32>>2]=0;E[j+736|0]=0;G[j+40>>2]=0;G[j+44>>2]=1072693248;if((Ya(j+736|0,71,19659,j+32|0)|0)<0){Ua(17928);G[i>>2]=402}b=jb(j+736|0,44);if(b){E[b|0]=46}if(jb(j+736|0,78)){Ua(35198);G[i>>2]=402}b=j+640|0;Ob(j+512|0,j+736|0,j+432|0,b,i);wb(a,b,i);break y}while(1){b=l;l=b+1|0;if(H[b|0]!=86){continue}break}E[b|0]=74;b=j+512|0;lc(a,b,c,j+432|0,i);zb(34362,h,b,i);c=H[6483]|H[6484]<<8|(H[6485]<<16|H[6486]<<24);b=H[6479]|H[6480]<<8|(H[6481]<<16|H[6482]<<24);E[j+453|0]=b;E[j+454|0]=b>>>8;E[j+455|0]=b>>>16;E[j+456|0]=b>>>24;E[j+457|0]=c;E[j+458|0]=c>>>8;E[j+459|0]=c>>>16;E[j+460|0]=c>>>24;b=H[6478]|H[6479]<<8|(H[6480]<<16|H[6481]<<24);G[j+448>>2]=H[6474]|H[6475]<<8|(H[6476]<<16|H[6477]<<24);G[j+452>>2]=b;b=H[6470]|H[6471]<<8|(H[6472]<<16|H[6473]<<24);G[j+440>>2]=H[6466]|H[6467]<<8|(H[6468]<<16|H[6469]<<24);G[j+444>>2]=b;b=H[6462]|H[6463]<<8|(H[6464]<<16|H[6465]<<24);G[j+432>>2]=H[6458]|H[6459]<<8|(H[6460]<<16|H[6461]<<24);G[j+436>>2]=b;if(G[i>>2]<=0){G[j+80>>2]=0;E[j+736|0]=0;G[j+88>>2]=0;G[j+92>>2]=1105199104;if((Ya(j+736|0,71,19659,j+80|0)|0)<0){Ua(17928);G[i>>2]=402}b=jb(j+736|0,44);if(b){E[b|0]=46}if(jb(j+736|0,78)){Ua(35198);G[i>>2]=402}b=j+640|0;Ob(j+512|0,j+736|0,j+432|0,b,i);wb(a,b,i)}zb(34838,h,j+512|0,i);G[j+448>>2]=H[29394]|H[29395]<<8|(H[29396]<<16|H[29397]<<24);b=H[29390]|H[29391]<<8|(H[29392]<<16|H[29393]<<24);G[j+440>>2]=H[29386]|H[29387]<<8|(H[29388]<<16|H[29389]<<24);G[j+444>>2]=b;b=H[29382]|H[29383]<<8|(H[29384]<<16|H[29385]<<24);G[j+432>>2]=H[29378]|H[29379]<<8|(H[29380]<<16|H[29381]<<24);G[j+436>>2]=b;if(G[i>>2]>0){break y}G[j+64>>2]=0;E[j+736|0]=0;G[j+72>>2]=0;G[j+76>>2]=1072693248;if((Ya(j+736|0,71,19659,j- -64|0)|0)<0){Ua(17928);G[i>>2]=402}b=jb(j+736|0,44);if(b){E[b|0]=46}if(jb(j+736|0,78)){Ua(35198);G[i>>2]=402}b=j+640|0;Ob(j+512|0,j+736|0,j+432|0,b,i);wb(a,b,i);break y}if((b|0)==80){break z}}lc(a,j+512|0,c,j+432|0,i);break y}while(1){b=k;k=b+1|0;if(H[b|0]!=87){continue}break}E[b|0]=75;d=j+512|0;lc(a,d,c,j+432|0,i);l=j+256|0;zb(34362,h,l,i);c=Va(l)+l|0;b=H[68292]|H[68293]<<8|(H[68294]<<16|H[68295]<<24);E[c|0]=b;E[c+1|0]=b>>>8;E[c+2|0]=b>>>16;E[c+3|0]=b>>>24;b=H[68296]|H[68297]<<8;E[c+4|0]=b;E[c+5|0]=b>>>8;E[j+264|0]=0;b=Va(l)+l|0;k=H[6437]|H[6438]<<8|(H[6439]<<16|H[6440]<<24);c=H[6433]|H[6434]<<8|(H[6435]<<16|H[6436]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;E[b+4|0]=k;E[b+5|0]=k>>>8;E[b+6|0]=k>>>16;E[b+7|0]=k>>>24;k=H[6483]|H[6484]<<8|(H[6485]<<16|H[6486]<<24);c=H[6479]|H[6480]<<8|(H[6481]<<16|H[6482]<<24);E[b+46|0]=c;E[b+47|0]=c>>>8;E[b+48|0]=c>>>16;E[b+49|0]=c>>>24;E[b+50|0]=k;E[b+51|0]=k>>>8;E[b+52|0]=k>>>16;E[b+53|0]=k>>>24;k=H[6477]|H[6478]<<8|(H[6479]<<16|H[6480]<<24);c=H[6473]|H[6474]<<8|(H[6475]<<16|H[6476]<<24);E[b+40|0]=c;E[b+41|0]=c>>>8;E[b+42|0]=c>>>16;E[b+43|0]=c>>>24;E[b+44|0]=k;E[b+45|0]=k>>>8;E[b+46|0]=k>>>16;E[b+47|0]=k>>>24;k=H[6469]|H[6470]<<8|(H[6471]<<16|H[6472]<<24);c=H[6465]|H[6466]<<8|(H[6467]<<16|H[6468]<<24);E[b+32|0]=c;E[b+33|0]=c>>>8;E[b+34|0]=c>>>16;E[b+35|0]=c>>>24;E[b+36|0]=k;E[b+37|0]=k>>>8;E[b+38|0]=k>>>16;E[b+39|0]=k>>>24;k=H[6461]|H[6462]<<8|(H[6463]<<16|H[6464]<<24);c=H[6457]|H[6458]<<8|(H[6459]<<16|H[6460]<<24);E[b+24|0]=c;E[b+25|0]=c>>>8;E[b+26|0]=c>>>16;E[b+27|0]=c>>>24;E[b+28|0]=k;E[b+29|0]=k>>>8;E[b+30|0]=k>>>16;E[b+31|0]=k>>>24;k=H[6453]|H[6454]<<8|(H[6455]<<16|H[6456]<<24);c=H[6449]|H[6450]<<8|(H[6451]<<16|H[6452]<<24);E[b+16|0]=c;E[b+17|0]=c>>>8;E[b+18|0]=c>>>16;E[b+19|0]=c>>>24;E[b+20|0]=k;E[b+21|0]=k>>>8;E[b+22|0]=k>>>16;E[b+23|0]=k>>>24;k=H[6445]|H[6446]<<8|(H[6447]<<16|H[6448]<<24);c=H[6441]|H[6442]<<8|(H[6443]<<16|H[6444]<<24);E[b+8|0]=c;E[b+9|0]=c>>>8;E[b+10|0]=c>>>16;E[b+11|0]=c>>>24;E[b+12|0]=k;E[b+13|0]=k>>>8;E[b+14|0]=k>>>16;E[b+15|0]=k>>>24;wb(a,l,i);zb(34838,h,d,i);G[j+448>>2]=H[29394]|H[29395]<<8|(H[29396]<<16|H[29397]<<24);b=H[29390]|H[29391]<<8|(H[29392]<<16|H[29393]<<24);G[j+440>>2]=H[29386]|H[29387]<<8|(H[29388]<<16|H[29389]<<24);G[j+444>>2]=b;b=H[29382]|H[29383]<<8|(H[29384]<<16|H[29385]<<24);G[j+432>>2]=H[29378]|H[29379]<<8|(H[29380]<<16|H[29381]<<24);G[j+436>>2]=b;if(G[i>>2]>0){break y}G[j+96>>2]=0;E[j+736|0]=0;G[j+104>>2]=0;G[j+108>>2]=1072693248;if((Ya(j+736|0,71,19659,j+96|0)|0)<0){Ua(17928);G[i>>2]=402}b=jb(j+736|0,44);if(b){E[b|0]=46}if(jb(j+736|0,78)){Ua(35198);G[i>>2]=402}b=j+640|0;Ob(j+512|0,j+736|0,j+432|0,b,i);wb(a,b,i)}F:{if(!g){break F}c=g+o|0;b=G[c>>2];if(!b|!H[b|0]){break F}b=j+512|0;zb(33357,h,b,i);lc(a,b,G[c>>2],26762,i)}if(G[i>>2]<=0){continue}}break}if(H[j+352|0]){lc(a,35480,j+352|0,15289,i)}if(G[i>>2]<=0){break a}Ua(56256)}Fa=j+816|0}function $f(a,b,c,d,e,f,g){var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,J=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0;j=Fa-496|0;Fa=j;G[j+468>>2]=0;G[j+432>>2]=G[29736];i=G[29735];G[j+424>>2]=G[29734];G[j+428>>2]=i;i=G[29733];G[j+416>>2]=G[29732];G[j+420>>2]=i;i=G[29731];G[j+408>>2]=G[29730];G[j+412>>2]=i;i=G[29729];G[j+400>>2]=G[29728];G[j+404>>2]=i;G[j+384>>2]=0;G[j+388>>2]=0;i=G[g>>2];a:{if((i|0)>0){break a}b:{if(a>>>0>=1e3){Ua(51315);break b}Dc(G[b>>2],j+476|0,g);c:{d:{if(a){while(1){e:{f:{g:{i=M(p,244)+b|0;h=G[i+80>>2];k=G[i+84>>2]!=2?(h|0)<0?0-h|0:h:h;switch(k|0){case 0:case 11:case 12:case 14:case 16:case 20:case 21:case 31:case 40:case 41:case 42:case 81:case 82:case 83:break e;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 13:case 15:case 17:case 18:case 19:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 32:case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 43:case 44:case 45:case 46:case 47:case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 65:case 66:case 67:case 68:case 69:case 70:case 71:case 72:case 73:case 74:case 75:case 76:case 77:case 78:case 79:case 80:break f;default:break g}}if((k|0)==163){break e}}a=p+1|0;h:{if((k|0)<0){G[j+32>>2]=a;Ya(j+288|0,81,51457,j+32|0);break h}G[j+52>>2]=h;G[j+48>>2]=a;Ya(j+288|0,81,51639,j+48|0)}Ua(j+288|0);break c}G[i+96>>2]=0;G[i+100>>2]=0;E[i+174|0]=0;l=i+104|0;E[l|0]=0;Dc(G[i>>2],j+472|0,g);h=G[j+472>>2];i:{if(!G[j+476>>2]){if(h){G[j+64>>2]=p+1;Ya(j+288|0,81,51403,j- -64|0);i=233;G[g>>2]=233;break a}G[i+4>>2]=0;h=H[35678]|H[35679]<<8|(H[35680]<<16|H[35681]<<24);E[i+8|0]=h;E[i+9|0]=h>>>8;E[i+10|0]=h>>>16;E[i+11|0]=h>>>24;h=H[35682]|H[35683]<<8;E[i+12|0]=h;E[i+13|0]=h>>>8;G[j+492>>2]=0;Fc(G[i>>2],33369,l,0,j+492|0);break i}if(!h){G[j+80>>2]=p+1;Ya(j+288|0,81,51350,j+80|0);i=235;G[g>>2]=235;break a}k=i+4|0;j:{h=G[i+4>>2];k:{if((h|0)<=0){h=i+8|0;if(dc(G[i>>2],0,h,k,g)){G[j+112>>2]=h;G[j+116>>2]=p+1;a=j+288|0;Ya(a,81,51528,j+112|0);Ua(a);break d}h=G[k>>2];if((h|0)<=0){break k}}if(G[G[G[i>>2]+4>>2]+936>>2]>=(h|0)){break j}}G[j+100>>2]=h;G[j+96>>2]=p+1;a=j+288|0;Ya(a,81,51581,j+96|0);Ua(a);break b}G[j+492>>2]=0;q=h;h=j+208|0;m=j+492|0;zb(34547,q,h,m);Ec(G[i>>2],h,i+96|0,0,m);G[j+492>>2]=0;zb(33036,G[k>>2],h,m);Ec(G[i>>2],h,i+100|0,0,m);G[j+492>>2]=0;zb(35402,G[k>>2],h,m);Fc(G[i>>2],h,i+8|0,0,m);if(G[j+492>>2]){E[i+8|0]=0}G[j+492>>2]=0;h=j+208|0;m=j+492|0;zb(33357,G[k>>2],h,m);Fc(G[i>>2],h,l,0,m);G[j+492>>2]=0;zb(34187,G[k>>2],h,m);Fc(G[i>>2],h,i+174|0,0,m)}p=p+1|0;if((p|0)!=(a|0)){continue}break}}V=(c|0)>0?c:0;c=G[b>>2];l:{if(!G[j+476>>2]){Qd(c,j+488|0,g);de(G[b>>2],9,j+400|0,g);G[j+492>>2]=0;Ec(G[b>>2],33752,j+396|0,0,j+492|0);o=G[j+400>>2];i=G[j+488>>2];if(!(G[j+492>>2]|!G[j+396>>2]|(o|(i|0)<2))){Ec(G[b>>2],33311,j+464|0,0,g);o=G[j+464>>2];i=G[j+488>>2]}m:{if((i|0)<2){break m}c=i-1|0;k=c&3;n:{if(i-2>>>0<3){i=1;break n}m=c&-4;h=0;i=1;while(1){c=(j+400|0)+(i<<2)|0;o=M(M(M(M(G[c>>2],o),G[c+4>>2]),G[c+8>>2]),G[c+12>>2]);i=i+4|0;h=h+4|0;if((m|0)!=(h|0)){continue}break}}if(!k){break m}p=0;while(1){o=M(G[(j+400|0)+(i<<2)>>2],o);i=i+1|0;p=p+1|0;if((k|0)!=(p|0)){continue}break}}n=V+1|0;v=1;break l}Ec(c,40853,j+464|0,0,g);n=1;o=G[j+464>>2];v=V+1|0}c=o-V|0;c=(c|0)>0?c:0;G[j+464>>2]=c;o:{if(!d){jo(G[b>>2],j+460|0,g);h=1;if((a|0)>=2){o=1;while(1){c=G[M(o,244)+b>>2];i=0;p:{q:{while(1){if((c|0)!=G[M(i,244)+b>>2]){i=i+1|0;if((o|0)!=(i|0)){continue}break q}break}if((i|0)!=(o|0)){break p}}jo(c,j+456|0,g);c=G[j+460>>2];d=G[j+456>>2];G[j+460>>2]=(c|0)<(d|0)?c:d;h=h+1|0}o=o+1|0;if((o|0)!=(a|0)){continue}break}}c=G[j+460>>2]/(h|0)|0;G[j+460>>2]=(c|0)>1?c:1;break o}if((d|0)<0){G[j+460>>2]=c;break o}G[j+460>>2]=(c|0)<(d|0)?c:d}r:{s:{t:{x=lb(a,16);if(x){if((a|0)>0){w=v>>31;m=0;while(1){k=M(m,244)+b|0;c=G[k>>2];u:{v:{w:{if(!G[j+476>>2]){Eg(c,j+484|0,g);x:{y:{z:{A:{c=G[j+484>>2];B:{if((c|0)<=7){if((c|0)==-64){break y}if((c|0)!=-32){break B}o=42;break v}C:{switch(c-8|0){case 0:break w;case 24:break z;case 8:break A;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:break B;default:break C}}if((c|0)==64){break x}}o=G[j+480>>2];break u}o=21;break v}o=41;break v}o=82;break v}o=81;break v}if((vd(c,G[k+4>>2],j+480|0,j+452|0,j+444|0,g)|0)>0){break r}o=G[j+480>>2];if((o|0)>=0){break u}G[j+460>>2]=1;if(G[k+84>>2]!=2){break u}G[j+16>>2]=m+1;a=j+288|0;Ya(a,81,51457,j+16|0);Ua(a);break c}o=11}G[j+480>>2]=o}c=o>>31;if(((c^o)-c|0)==1){o=M(o,11);G[j+480>>2]=o;G[j+452>>2]=(G[j+452>>2]+7|0)/8}p=G[k+80>>2];if(!p){c=o>>31;p=(c^o)-c|0;G[k+80>>2]=p}D:{E:{F:{c=G[j+476>>2];if(!((p|0)!=16?c:0)){i=G[j+460>>2];G[k+92>>2]=(c|0)!=2|G[j+452>>2]!=0;c=o>>31;c=(c^o)-c|0;d=c-11|0;if(d>>>0>30|!(1<=0){p=G[j+452>>2];break G}p=1;G[j+452>>2]=1;if(G[j+464>>2]<=0){break G}i=0;c=0;while(1){h=c+w|0;d=v;l=d+i|0;nh(G[k>>2],G[k+4>>2],l,d>>>0>l>>>0?h+1|0:h,j+448|0,0,g);d=G[j+452>>2];h=G[j+448>>2];p=(d|0)>(h|0)?d:h;G[j+452>>2]=p;h=c;c=i+1|0;h=c?h:h+1|0;i=c;d=G[j+464>>2];l=i>>>0>>0;c=h;d=d>>31;if(l&(h|0)<=(d|0)|(d|0)>(h|0)){continue}break}o=G[j+480>>2]}c=G[j+460>>2];G[k+92>>2]=p;i=M(c,p);c=o>>31;c=(c^o)-c|0;d=c-11|0;if(!(1<>>0<=30:0)&(c|0)!=81){break D}G[j+492>>2]=0;d=G[j+476>>2];zb(34755,G[k+4>>2],j+208|0,j+492|0);c=G[k>>2];H:{if((d|0)==1){Fc(c,j+208|0,j+128|0,0,j+492|0);if(!G[j+492>>2]){o=j+128|0;while(1){c=H[o|0];if((c|0)!=32){if(!c){break H}ue(j+128|0,j+440|0,j+492|0);if(G[j+492>>2]){break H}break D}else{o=o+1|0;continue}}}G[j+440>>2]=0;break D}Ec(c,j+208|0,j+440|0,0,j+492|0);if(G[j+492>>2]){G[j+440>>2]=0;break D}if(G[j+440>>2]){break D}}G[j+440>>2]=-2147483648;break D}if((c|0)!=81){break D}}G[j+492>>2]=0;Ec(G[k>>2],34862,j+440|0,0,j+492|0);if(!G[j+492>>2]){break D}G[j+440>>2]=0}I:{J:{K:{L:{M:{N:{O:{P:{Q:{R:{S:{T:{U:{V:{W:{X:{Y:{Z:{_:{$:{aa:{ba:{ca:{da:{ea:{fa:{ga:{ha:{ia:{ja:{ka:{la:{ma:{na:{oa:{pa:{qa:{ra:{sa:{ta:{c=G[k+80>>2];switch(c-11|0){case 5:break ia;case 71:break ja;case 72:break ka;case 31:break la;case 29:break ma;case 30:break na;case 19:break oa;case 20:break pa;case 9:break qa;case 10:break ra;case 1:break sa;case 0:break ta;case 2:case 4:case 6:case 7:case 8:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 32:case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 65:case 66:case 67:case 68:case 69:break ea;case 70:break ga;case 3:break ha;default:break fa}}Z=k,_=lb(i+1|0,1),G[Z+88>>2]=_;c=x+(m<<4)|0;G[c>>2]=1;i=G[j+480>>2];d=i>>31;d=(d^i)-d|0;i=d-11|0;if(i>>>0>30|!(1<>2]=_;c=x+(m<<4)|0;G[c>>2]=1;i=G[j+480>>2];d=i>>31;d=(d^i)-d|0;i=d-11|0;if(i>>>0>30|!(1<>2]=_;c=x+(m<<4)|0;G[c>>2]=2;i=G[j+480>>2];d=i>>31;d=(d^i)-d|0;i=d-11|0;if(i>>>0>30|!(1<>2]=_;c=x+(m<<4)|0;G[c>>2]=2;i=G[j+480>>2];d=i>>31;d=(d^i)-d|0;i=d-11|0;if(i>>>0>30|!(1<>2]=_;c=x+(m<<4)|0;G[c>>2]=4;i=G[j+480>>2];d=i>>31;d=(d^i)-d|0;i=d-11|0;if(i>>>0>30|!(1<>2]=_;c=x+(m<<4)|0;G[c>>2]=4;i=G[j+480>>2];d=i>>31;d=(d^i)-d|0;i=d-11|0;if(i>>>0>30|!(1<>2]=_;c=x+(m<<4)|0;G[c>>2]=4;i=G[j+480>>2];d=i>>31;d=(d^i)-d|0;i=d-11|0;if(i>>>0>30|!(1<>2]=_;c=x+(m<<4)|0;G[c>>2]=4;i=G[j+480>>2];d=i>>31;d=(d^i)-d|0;i=d-11|0;if(i>>>0>30|!(1<>2]=_;c=x+(m<<4)|0;G[c>>2]=4;i=G[j+480>>2];d=i>>31;d=(d^i)-d|0;i=d-11|0;if(i>>>0>30|!(1<>2]=_;c=x+(m<<4)|0;G[c+8>>2]=-2059275978;G[c>>2]=4;break I}Z=k,_=lb(i+1|0,8),G[Z+88>>2]=_;c=x+(m<<4)|0;G[c>>2]=8;i=G[j+480>>2];d=i>>31;d=(d^i)-d|0;i=d-11|0;if(i>>>0>30|!(1<>2]==1){o=G[j+444>>2];G[j+452>>2]=o;break ua}o=G[j+452>>2]}c=i+1|0;l=lb(c,4);G[k+88>>2]=l;s=x+(m<<4)|0;h=o+1|0;G[s>>2]=h;if(!l){break I}d=lb(h,1);G[s+8>>2]=d;if((o|0)>0){E[d+1|0]=1}d=lb(M(c,h),1);G[l>>2]=d;if(!d){break t}va:{if((i|0)<=0){break va}o=1;if(i-1>>>0>=3){r=i&-4;c=0;while(1){q=l+(o<<2)|0;d=d+h|0;G[q>>2]=d;d=d+h|0;t=d+h|0;G[q+8>>2]=t;G[q+4>>2]=d;d=h+t|0;G[q+12>>2]=d;o=o+4|0;c=c+4|0;if((r|0)!=(c|0)){continue}break}}c=i&3;i=0;if(!c){break va}while(1){d=d+h|0;G[l+(o<<2)>>2]=d;o=o+1|0;i=i+1|0;if((c|0)!=(i|0)){continue}break}}G[j+492>>2]=0;c=j+208|0;d=j+492|0;zb(34755,G[k+4>>2],c,d);Fc(G[k>>2],c,j+128|0,0,d);if(G[j+492>>2]){break I}qb(G[s+8>>2],j+128|0,G[j+452>>2]);break I}Z=k,_=lb(i+1|0,1),G[Z+88>>2]=_;c=x+(m<<4)|0;E[c+8|0]=2;G[c>>2]=1;break I}Z=k,_=lb(i+1|0,8),G[Z+88>>2]=_;c=x+(m<<4)|0;G[c>>2]=8;i=G[j+480>>2];d=i>>31;d=(d^i)-d|0;i=d-11|0;if(i>>>0>30|!(1<>2]=c;G[j>>2]=m+1;c=j+288|0;Ya(c,81,51691,j);i=410;break s}if((d|0)==81){break ca}G[c+8>>2]=0;G[c+12>>2]=-2147483648;break I}d=G[j+440>>2];G[c+8>>2]=d;G[c+12>>2]=d>>31;break I}Z=k,_=lb(i<<1|1,8),G[Z+88>>2]=_;c=x+(m<<4)|0;G[c+8>>2]=1589294263;G[c+12>>2]=-1196933592;G[c>>2]=8;break I}if((d|0)==81){break $}G[c+8>>2]=1589294263;G[c+12>>2]=-1196933592;break I}L[c+8>>3]=G[j+440>>2];break I}if((d|0)==81){break Z}G[c+8>>2]=-2059275978;break I}K[c+8>>2]=G[j+440>>2];break I}if((d|0)==81){break X}G[c+8>>2]=2147483647;break I}d=G[j+440>>2];if((d|0)<0){G[c+8>>2]=2147483647;break I}G[c+8>>2]=d;break I}if((d|0)==81){break V}G[c+8>>2]=-2147483648;break I}G[c+8>>2]=G[j+440>>2];break I}if((d|0)==81){break T}G[c+8>>2]=-1;break I}d=G[j+440>>2];d=(d|0)>0?d:0;G[j+440>>2]=d;G[c+8>>2]=d;break I}if((d|0)==81){break R}G[c+8>>2]=-2147483648;break I}G[c+8>>2]=G[j+440>>2];break I}if((d|0)==81){break P}F[c+8>>1]=65535;break I}d=G[j+440>>2];d=(d|0)<65535?d:65535;d=(d|0)>0?d:0;G[j+440>>2]=d;F[c+8>>1]=d;break I}if((d|0)==81){break N}F[c+8>>1]=32768;break I}d=G[j+440>>2];d=(d|0)<32767?d:32767;d=(d|0)>-32768?d:-32768;G[j+440>>2]=d;F[c+8>>1]=d;break I}if((d|0)==81){break L}E[c+8|0]=128;break I}d=G[j+440>>2];d=(d|0)<127?d:127;d=(d|0)>-128?d:-128;G[j+440>>2]=d;E[c+8|0]=d;break I}if((d|0)==81){break J}E[c+8|0]=255;break I}d=G[j+440>>2];d=(d|0)<255?d:255;d=(d|0)>0?d:0;G[j+440>>2]=d;E[c+8|0]=d}if(!G[k+88>>2]){break t}m=m+1|0;if((m|0)!=(a|0)){continue}break}}T=G[j+464>>2];if(!T){break r}X=(a|0)<=0;while(1){c=G[j+460>>2];D=(c|0)>(T|0)?T:c;wa:{if(X){break wa}h=n>>31;w=v>>31;o=0;while(1){s=M(o,244)+b|0;xa:{if(G[s+84>>2]==2){break xa}c=G[s+88>>2];r=G[s+80>>2];ya:{if((r|0)==16){i=G[(x+(o<<4)|0)+8>>2];c=c+4|0;break ya}d=x+(o<<4)|0;i=d+8|0;c=c+G[d>>2]|0}k=G[s>>2];za:{if(!G[j+476>>2]){l=j+468|0;q=M(D,G[s+92>>2]);d=q>>31;m=G[g>>2];if(!(!(d|q)|(m|0)>0)){Aa:{Ba:{switch(r-11|0){case 0:if(!i){wp(k,n,h,q,d,0,c,l,g);break Aa}wp(k,n,h,q,d,H[i|0],c,l,g);break Aa;case 1:if(!i){Fo(k,n,h,q,d,0,c,l,g);break Aa}Fo(k,n,h,q,d,E[i|0],c,l,g);break Aa;case 9:if(!i){Kp(k,n,h,q,d,0,c,l,g);break Aa}Kp(k,n,h,q,d,I[i>>1],c,l,g);break Aa;case 10:if(!i){Pp(k,n,h,q,d,0,c,l,g);break Aa}Pp(k,n,h,q,d,F[i>>1],c,l,g);break Aa;case 19:if(!i){zp(k,n,h,q,d,0,c,l,g);break Aa}zp(k,n,h,q,d,G[i>>2],c,l,g);break Aa;case 20:if(!i){Wp(k,n,h,q,d,0,c,l,g);break Aa}Wp(k,n,h,q,d,G[i>>2],c,l,g);break Aa;case 29:if(!i){Fp(k,n,h,q,d,0,c,l,g);break Aa}Fp(k,n,h,q,d,G[i>>2],c,l,g);break Aa;case 30:if(!i){cq(k,n,h,q,d,0,c,l,g);break Aa}cq(k,n,h,q,d,G[i>>2],c,l,g);break Aa;case 69:if(!i){Ap(k,n,h,q,d,0,0,c,l,g);break Aa}Ap(k,n,h,q,d,G[i>>2],G[i+4>>2],c,l,g);break Aa;case 70:if(!i){_p(k,n,h,q,d,0,0,c,l,g);break Aa}_p(k,n,h,q,d,G[i>>2],G[i+4>>2],c,l,g);break Aa;case 31:if(!i){hl(k,1,n,h,q,d,N(0),c,l,g);break Aa}hl(k,1,n,h,q,d,K[i>>2],c,l,g);break Aa;case 71:if(!i){gq(k,n,h,q,d,0,c,l,g);break Aa}gq(k,n,h,q,d,L[i>>3],c,l,g);break Aa;default:break Ba}}G[g>>2]=410}m=G[g>>2]}if((m|0)<=0){break za}break wa}if((vd(k,G[s+4>>2],j+480|0,j+452|0,j+444|0,g)|0)>0){break r}if(G[j+480>>2]<0){nh(G[s>>2],G[s+4>>2],v,w,s+92|0,0,g)}d=M(D,G[s+92>>2]);if((bg(G[s>>2],G[s+80>>2],G[s+4>>2],v,w,n,h,d,d>>31,i,c,j+468|0,g)|0)>0){break wa}}c=G[s+88>>2];d=G[s+80>>2];if(G[j+468>>2]){if((d|0)==16){d=G[c>>2];c=x+(o<<4)|0;bb(d,G[c+8>>2],G[c>>2]);break xa}bb(c,i,G[x+(o<<4)>>2]);break xa}if((d|0)==16){cb(G[c>>2],0,G[x+(o<<4)>>2]);break xa}cb(c,0,G[x+(o<<4)>>2])}o=o+1|0;if((o|0)!=(a|0)){continue}break}}if(G[g>>2]>0){break r}c=G[j+464>>2];Ca:{if(!G[j+476>>2]){c=Ja[e|0](c,V,n,D,a,b,f)|0;break Ca}c=Ja[e|0](c,V,v,D,a,b,f)|0}G[g>>2]=c;if(c-1>>>0<4294967294){break r}G[j+492>>2]=0;if(!X){r=n>>31;y=v>>31;o=0;while(1){Da:{k=M(o,244)+b|0;Ea:{if(!G[k+84>>2]){break Ea}p=G[k+88>>2];l=G[k+80>>2];Fa:{if((l|0)==16){c=p+4|0;p=G[p>>2];i=2;break Fa}i=G[x+(o<<4)>>2];c=p+i|0}h=G[k>>2];d=G[j+476>>2];if(nb(p,j+384|0,i)){if(!d){d=M(D,G[k+92>>2]);k=d;m=d>>31;i=j+492|0;d=G[i>>2];if((d|0)<=0){Ga:{if(!p){Ao(h,l,n,r,k,m,c,i);break Ga}Ha:{switch(l-11|0){case 0:l=H[p|0];d=Fa-16|0;Fa=d;Ia:{if(Nb(h,i)){E[d+15|0]=l;bd(h,11,n,r,k,m,1,c,d+15|0,i);break Ia}qp(h,2,1,0,n,r,k,m,c,l,i)}Fa=d+16|0;break Ga;case 1:l=E[p|0];d=Fa-16|0;Fa=d;Ja:{if(Nb(h,i)){E[d+15|0]=l;bd(h,12,n,r,k,m,1,c,d+15|0,i);break Ja}Xo(h,2,1,0,n,r,k,m,c,l,i)}Fa=d+16|0;break Ga;case 9:l=I[p>>1];d=Fa-16|0;Fa=d;Ka:{if(Nb(h,i)){F[d+14>>1]=l;bd(h,20,n,r,k,m,1,c,d+14|0,i);break Ka}Uo(h,2,1,0,n,r,k,m,c,l,i)}Fa=d+16|0;break Ga;case 10:l=F[p>>1];d=Fa-16|0;Fa=d;La:{if(Nb(h,i)){F[d+14>>1]=l;bd(h,21,n,r,k,m,1,c,d+14|0,i);break La}pp(h,2,1,0,n,r,k,m,c,l,i)}Fa=d+16|0;break Ga;case 19:l=G[p>>2];d=Fa-16|0;Fa=d;Ma:{if(Nb(h,i)){G[d+12>>2]=l;bd(h,30,n,r,k,m,1,c,d+12|0,i);break Ma}No(h,2,1,0,n,r,k,m,c,l,i)}Fa=d+16|0;break Ga;case 20:l=G[p>>2];d=Fa-16|0;Fa=d;Na:{if(Nb(h,i)){G[d+12>>2]=l;bd(h,31,n,r,k,m,1,c,d+12|0,i);break Na}Io(h,2,1,0,n,r,k,m,c,l,i)}Fa=d+16|0;break Ga;case 29:l=G[p>>2];d=Fa-16|0;Fa=d;Oa:{if(Nb(h,i)){G[d+12>>2]=l;bd(h,40,n,r,k,m,1,c,d+12|0,i);break Oa}So(h,2,1,0,n,r,k,m,c,l,i)}Fa=d+16|0;break Ga;case 30:l=G[p>>2];d=Fa-16|0;Fa=d;Pa:{if(Nb(h,i)){G[d+12>>2]=l;bd(h,41,n,r,k,m,1,c,d+12|0,i);break Pa}Lo(h,2,1,0,n,r,k,m,c,l,i)}Fa=d+16|0;break Ga;case 69:d=G[p>>2];l=G[p+4>>2];Qa:{if(Nb(h,i)){Ua(28105);G[i>>2]=413;break Qa}Qo(h,2,1,0,n,r,k,m,c,d,l,i)}break Ga;case 70:d=G[p>>2];l=G[p+4>>2];Ra:{if(Nb(h,i)){Ua(28161);G[i>>2]=413;break Ra}Ko(h,2,1,0,n,r,k,m,c,d,l,i)}break Ga;case 31:Ek(h,1,n,r,k,m,c,K[p>>2],i);break Ga;case 71:Zo(h,n,r,k,m,c,L[p>>3],i);break Ga;default:break Ha}}G[i>>2]=410}d=G[i>>2]}if((d|0)<=0){break Ea}break Da}if((vd(h,G[k+4>>2],j+480|0,j+452|0,j+444|0,g)|0)>0){break r}if(G[j+480>>2]<0){nh(G[k>>2],G[k+4>>2],v,y,k+92|0,0,g)}d=G[k>>2];l=G[k+80>>2];i=G[k+4>>2];h=M(D,G[k+92>>2]);m=h;t=h>>31;z=0;B=0;C=0;s=0;u=j+492|0;h=G[u>>2];if((h|0)<=0){Sa:{if(!p){Bk(d,l,i,v,y,n,r,m,t,c,u);break Sa}Ta:{switch(l-11|0){case 0:qp(d,i,v,y,n,r,m,t,c,H[p|0],u);break Sa;case 1:Xo(d,i,v,y,n,r,m,t,c,E[p|0],u);break Sa;case 9:Uo(d,i,v,y,n,r,m,t,c,I[p>>1],u);break Sa;case 10:pp(d,i,v,y,n,r,m,t,c,F[p>>1],u);break Sa;case 19:No(d,i,v,y,n,r,m,t,c,G[p>>2],u);break Sa;case 20:Io(d,i,v,y,n,r,m,t,c,G[p>>2],u);break Sa;case 29:So(d,i,v,y,n,r,m,t,c,G[p>>2],u);break Sa;case 30:Lo(d,i,v,y,n,r,m,t,c,G[p>>2],u);break Sa;case 69:Qo(d,i,v,y,n,r,m,t,c,G[p>>2],G[p+4>>2],u);break Sa;case 70:Ko(d,i,v,y,n,r,m,t,c,G[p>>2],G[p+4>>2],u);break Sa;case 31:Dk(d,i,v,y,n,r,m,t,c,K[p>>2],u);break Sa;case 71:Hk(d,i,v,y,n,r,m,t,c,L[p>>3],u);break Sa;case 72:k=d;d=n;h=r<<1|d>>>31;d=d<<1;l=d-1|0;q=h-!d|0;d=m;h=t<<1|d>>>31;Dk(k,i,v,y,l,q,d<<1,h,c,K[p>>2],u);break Sa;case 152:k=d;d=n;h=r<<1|d>>>31;d=d<<1;l=d-1|0;q=h-!d|0;d=m;h=t<<1|d>>>31;Hk(k,i,v,y,l,q,d<<1,h,c,L[p>>3],u);break Sa;case 3:U=H[p|0];if(G[u>>2]<=0){Ua:{k=G[d>>2];h=G[d+4>>2];Va:{if((k|0)!=G[h+76>>2]){mb(d,k+1|0,0,u);break Va}if((G[h+128>>2]&G[h+132>>2])!=-1){break Va}if((Rb(d,u)|0)>0){break Ua}}h=G[G[d+4>>2]+968>>2]+M(i-1|0,160)|0;Wa:{if(G[h+80>>2]>0){A=G[h+88>>2];J=G[h+92>>2];break Wa}h=r+t|0;k=m+n|0;h=k>>>0>>0?h+1|0:h;A=k-1|0;J=h-!k|0}if(!m&(t|0)<=0|(t|0)<0|(Go(d,i,v,y,n,r,m,t,c,u)|0)>0){break Ua}h=v;k=n;l=Au(A,J,h-1|0,y-!h|0)+k|0;h=Ia+r|0;z=l;P=k>>>0>l>>>0?h+1|0:h;w=0;q=0;k=0;l=0;while(1){Xa:{if((U|0)!=H[c+w|0]){if(k|l){h=P+(q-((k>>>0>w>>>0)+l|0)|0)|0;B=z+(w-k|0)|0;h=B>>>0>>0?h+1|0:h;p=h;Q=Bu(B-1|0,h-!B|0,A,J);h=Ia;R=h;O=Q+1|0;h=O?h:h+1|0;S=h;h=Au(A,J,Q,R);if((rc(d,i,O,S,B-h|0,p-(Ia+(h>>>0>B>>>0)|0)|0,k,l,u)|0)>0){break Ua}}h=s;k=C+1|0;h=k?h:h+1|0;C=k;s=h;h=0;k=0;break Xa}C=0;s=0;h=l;k=k+1|0;h=k?h:h+1|0}l=h;h=q;q=w+1|0;h=q?h:h+1|0;w=q;q=h;if((m|0)!=(w|0)|(t|0)!=(h|0)){continue}break}if(!(k|l)|(s|C)){break Ua}h=P+(t-((k>>>0>m>>>0)+l|0)|0)|0;c=z+(m-k|0)|0;h=c>>>0>>0?h+1|0:h;m=h;q=Bu(c-1|0,h-!c|0,A,J);h=Ia;s=h;t=d;d=q+1|0;h=d?h:h+1|0;w=d;d=Au(A,J,q,s);rc(t,i,w,h,c-d|0,m-(Ia+(c>>>0>>0)|0)|0,k,l,u)}}break Sa;case 5:C=Fa-16|0;Fa=C;if(G[u>>2]<=0){Ya:{k=G[d>>2];h=G[d+4>>2];Za:{if((k|0)!=G[h+76>>2]){mb(d,k+1|0,0,u);break Za}if((G[h+128>>2]&G[h+132>>2])!=-1){break Za}if((Rb(d,u)|0)>0){break Ya}}vd(d,i,0,C+12|0,C+8|0,u);h=G[C+12>>2];if(G[G[d+4>>2]+80>>2]==2){h=(h|0)/G[C+8>>2]|0;G[C+12>>2]=h}if(!m&(t|0)<=0|(t|0)<0){break Ya}l=h;q=h>>31;h=v;k=n;l=Au(l,q,h-1|0,y-!h|0)+k|0;h=r+Ia|0;s=l;J=k>>>0>l>>>0?h+1|0:h;w=0;q=0;k=0;l=0;while(1){_a:{if(Xa(p,G[(w<<2)+c>>2])){if(k|l){h=J+(q-((k>>>0>w>>>0)+l|0)|0)|0;A=s+(w-k|0)|0;h=A>>>0>>0?h+1|0:h;P=h;O=h-!A|0;h=G[C+12>>2];U=h;R=h>>31;Q=Bu(A-1|0,O,h,R);h=Ia;O=h;S=Q+1|0;h=S?h:h+1|0;W=h;h=Au(U,R,Q,O);if((rc(d,i,S,W,A-h|0,P-(Ia+(h>>>0>A>>>0)|0)|0,k,l,u)|0)>0){break Ya}}h=B;k=z+1|0;h=k?h:h+1|0;z=k;B=h;h=0;k=0;break _a}if(z|B){h=J+(q-((w>>>0>>0)+B|0)|0)|0;U=w-z|0;A=s+U|0;h=A>>>0>>0?h+1|0:h;P=h;S=h-!A|0;h=G[C+12>>2];R=h;O=h>>31;Q=Bu(A-1|0,S,h,O);h=Ia;S=h;Y=Q+1|0;h=Y?h:h+1|0;W=h;h=Au(R,O,Q,S);if((dg(d,i,Y,W,A-h|0,P-(Ia+(h>>>0>A>>>0)|0)|0,z,B,(U<<2)+c|0,u)|0)>0){break Ya}}z=0;B=0;h=l;k=k+1|0;h=k?h:h+1|0}l=h;h=q;q=w+1|0;h=q?h:h+1|0;w=q;q=h;if((m|0)!=(w|0)|(t|0)!=(h|0)){continue}break}if(z|B){k=d;h=J+(t-((m>>>0>>0)+B|0)|0)|0;q=m-z|0;d=s+q|0;h=d>>>0>>0?h+1|0:h;m=h;l=h-!d|0;h=G[C+12>>2];s=h;w=h>>31;l=Bu(d-1|0,l,h,w);h=Ia;t=h;P=i;i=l+1|0;h=i?h:h+1|0;R=i;i=Au(s,w,l,t);dg(k,P,R,h,d-i|0,m-(Ia+(d>>>0>>0)|0)|0,z,B,(q<<2)+c|0,u);break Ya}if(!(k|l)){break Ya}h=J+(t-((k>>>0>m>>>0)+l|0)|0)|0;c=s+(m-k|0)|0;h=c>>>0>>0?h+1|0:h;m=h;q=h-!c|0;h=G[C+12>>2];s=h;w=h>>31;q=Bu(c-1|0,q,h,w);h=Ia;t=h;z=d;d=q+1|0;h=d?h:h+1|0;B=d;d=Au(q,t,s,w);rc(z,i,B,h,c-d|0,m-(Ia+(c>>>0>>0)|0)|0,k,l,u)}}Fa=C+16|0;break Sa;default:break Ta}}G[u>>2]=410}h=G[u>>2]}if((h|0)<=0){break Ea}break Da}if(!d){d=M(D,G[k+92>>2]);if((Ao(h,l,n,r,d,d>>31,c,j+492|0)|0)<=0){break Ea}break Da}if((vd(h,G[k+4>>2],j+480|0,j+452|0,j+444|0,g)|0)>0){break r}if(G[j+480>>2]<0){nh(G[k>>2],G[k+4>>2],v,y,k+92|0,0,g)}d=M(D,G[k+92>>2]);if((Bk(G[k>>2],G[k+80>>2],G[k+4>>2],v,y,n,r,d,d>>31,c,j+492|0)|0)>0){break Da}}o=o+1|0;if((o|0)!=(a|0)){continue}}break}c=G[g>>2]}if(c){break r}c=G[j+492>>2];G[g>>2]=c;if(c){break r}c=G[j+476>>2];n=(c?0:D)+n|0;v=(c?D:0)+v|0;T=T-D|0;if(T){continue}break}break r}Ua(7297);i=113;G[g>>2]=113;break a}c=5352;i=113}Ua(c);G[g>>2]=i}if((a|0)>0){i=0;while(1){c=M(i,244)+b|0;$a:{if(G[c+80>>2]!=16){break $a}d=G[c+88>>2];if(!d){break $a}Wa(G[d>>2]);Wa(G[(x+(i<<4)|0)+8>>2])}c=G[c+88>>2];if(c){Wa(c)}i=i+1|0;if((i|0)!=(a|0)){continue}break}}Wa(x)}i=G[g>>2];break a}i=410;G[g>>2]=410;break a}i=302;G[g>>2]=302}Fa=j+496|0;return i}function Yi(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=N(0),v=0;f=Fa-432|0;Fa=f;a:{if(G[e>>2]>0){break a}h=G[a>>2];j=G[a+4>>2];if((h|0)!=G[j+76>>2]){mb(a,h+1|0,0,e);j=G[a+4>>2];h=G[j+76>>2]}k=G[j+96>>2]+(h<<3)|0;if(G[j+104>>2]!=G[k>>2]|G[j+108>>2]!=G[k+4>>2]){G[e>>2]=201;break a}if(!(!c|!G[j+992>>2])){b:{if((c|0)<=0){break b}h=0;j=0;if(c-1>>>0>=3){g=c&-4;while(1){k=f+256|0;G[k+(j<<2)>>2]=G[(j<<3)+d>>2];l=j|1;G[k+(l<<2)>>2]=G[(l<<3)+d>>2];l=j|2;G[k+(l<<2)>>2]=G[(l<<3)+d>>2];l=j|3;G[k+(l<<2)>>2]=G[(l<<3)+d>>2];j=j+4|0;n=n+4|0;if((g|0)!=(n|0)){continue}break}}k=c&3;if(!k){break b}while(1){G[(f+256|0)+(j<<2)>>2]=G[(j<<3)+d>>2];j=j+1|0;h=h+1|0;if((k|0)!=(h|0)){continue}break}}d=a;h=b;l=f+256|0;b=0;g=Fa-304|0;Fa=g;G[g+200>>2]=G[29766];a=G[29765];G[g+192>>2]=G[29764];G[g+196>>2]=a;G[g+160>>2]=G[29770];a=G[29769];G[g+152>>2]=G[29768];G[g+156>>2]=a;c:{if(G[e>>2]>0){break c}n=G[d+4>>2];d:{if(!((h|0)>=0|K[n+1020>>2]!=N(9999)|G[n+992>>2]-21>>>0<2)){Ua(61493);break d}t=G[n+992>>2];if(!t){G[n+992>>2]=11;t=11}e:{f:{g:{h:{i:{j:{if((h|0)<0){u=K[n+1020>>2];if(u==N(9999)){break f}a=G[n+1024>>2];if(!a){break j}if(u!=N(0)){break f}if((a|0)!=-1){break g}K[n+1020>>2]=16;break f}k=16;v=1;k:{switch(h-10|0){case 10:break e;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:break f;case 0:break k;default:break i}}k=8;break h}G[n+1024>>2]=1;if(u==N(0)){break g}break f}if((h|0)!=40){break f}k=32}v=0;break e}K[n+1020>>2]=4}v=0;k=h}a=G[n+1016>>2];G[g+48>>2]=G[n+1012>>2];G[g+52>>2]=a;a=G[n+1e3>>2];G[g+32>>2]=G[n+996>>2];G[g+36>>2]=a;a=G[n+1008>>2];G[g+40>>2]=G[n+1004>>2];G[g+44>>2]=a;l:{m:{n:{o:{if((t|0)!=41){break o}if((c|0)<2){break l}a=0;j=c-1|0;if(j>>>0>=3){o=c&-4;while(1){m=b;b=a<<2;b=(((m+(G[b+l>>2]>3)|0)+(G[l+(b|4)>>2]>3)|0)+(G[l+(b|8)>>2]>3)|0)+(G[l+(b|12)>>2]>3)|0;a=a+4|0;p=p+4|0;if((o|0)!=(p|0)){continue}break}}p=c&3;if(p){while(1){b=(G[l+(a<<2)>>2]>3)+b|0;a=a+1|0;i=i+1|0;if((p|0)!=(i|0)){continue}break}}if(b>>>0<2){break m}a=0;p:{if((c|0)<2){break p}a=1;if(J[g+36>>2]>=2){break p}while(1){a=a+1|0;if((c|0)!=(a|0)&J[(g+32|0)+(a<<2)>>2]<2){continue}break}a=(a|0)<(c|0)}b=G[g+32>>2];q:{if(!(G[g+36>>2]!=-1|(b|0)>0)){G[g+32>>2]=G[l>>2];G[g+36>>2]=G[l+4>>2];if((c|0)<3){break q}b=c-2|0;i=b&7;a=2;if(c-3>>>0>=7){p=b&-8;j=0;while(1){o=a<<2;m=g+32|0;b=o+m|0;G[b>>2]=1;G[m+(o|4)>>2]=1;G[b+24>>2]=1;G[b+28>>2]=1;G[b+16>>2]=1;G[b+20>>2]=1;G[b+8>>2]=1;G[b+12>>2]=1;a=a+8|0;j=j+8|0;if((p|0)!=(j|0)){continue}break}}if(!i){break q}b=0;while(1){G[(g+32|0)+(a<<2)>>2]=1;a=a+1|0;b=b+1|0;if((i|0)!=(b|0)){continue}break}break q}b=(b|0)>0;if(!(b|!(a^1))){G[g+32>>2]=G[l>>2];a=G[l+4>>2];if((a|0)<31){G[g+36>>2]=a;break q}b=16;r:{if((a&15)-4>>>0<4294967293){break r}b=24;if(((a>>>0)%24|0)-4>>>0<4294967293){break r}b=20;if(((a>>>0)%20|0)-4>>>0<4294967293){break r}b=30;if(((a>>>0)%30|0)-4>>>0<4294967293){break r}b=28;if(((a>>>0)%28|0)-4>>>0<4294967293){break r}b=26;if(((a>>>0)%26|0)-4>>>0<4294967293){break r}b=22;if(((a>>>0)%22|0)-4>>>0<4294967293){break r}b=18;if(((a>>>0)%18|0)-4>>>0<4294967293){break r}b=((a>>>0)%14|0)-4>>>0<4294967293?14:17}G[g+36>>2]=b;break q}if(!b){G[g+32>>2]=G[l>>2]}if((c|0)<2){break q}a=1;if((c|0)!=2){p=j&-2;b=0;while(1){i=a<<2;o=i+(g+32|0)|0;m=G[o>>2];s:{t:{if((m|0)<0){i=G[i+l>>2];break t}if(m){break s}i=1}G[o>>2]=i}i=a+1<<2;o=i+(g+32|0)|0;m=G[o>>2];u:{v:{if((m|0)>=0){if(m){break u}i=1;break v}i=G[i+l>>2]}G[o>>2]=i}a=a+2|0;b=b+2|0;if((p|0)!=(b|0)){continue}break}}if(!(j&1)){break q}a=a<<2;b=a+(g+32|0)|0;j=G[b>>2];w:{if((j|0)>=0){if(j){break q}a=1;break w}a=G[a+l>>2]}G[b>>2]=a}x:{y:{if((c|0)<=0){break y}a=0;j=-1;b=-1;while(1){z:{if(G[(g+32|0)+(a<<2)>>2]<2){break z}if((b|0)<0){b=a;break z}i=(j|0)<0;j=a;if(i){break z}Ua(60978);break d}a=a+1|0;if((c|0)!=(a|0)){continue}break}if((b|0)<0){break y}if((j|0)>=0){break x}}Ua(61041);break d}A:{i=(g+32|0)+(b<<2)|0;o=G[i>>2];if((o|0)>=4){a=(g+32|0)+(j<<2)|0;p=G[a>>2];if((p|0)>3){break A}}Ua(61100);break d}b=G[l+(b<<2)>>2];m=(b|0)/(o|0)|0;q=b-M(o,m)|0;if(q-1>>>0<=2){r=i;s=T(+(q|0)/+(m|0));B:{if(O(s)<2147483648){i=~~s;break B}i=-2147483648}i=i+o|0;G[r>>2]=i;if(((b|0)%(i|0)|0)-1>>>0<3){break n}p=G[a>>2]}b=G[l+(j<<2)>>2];j=(b|0)/(p|0)|0;i=b-M(j,p)|0;if(i-1>>>0>2){break o}m=a;s=T(+(i|0)/+(j|0));C:{if(O(s)<2147483648){a=~~s;break C}a=-2147483648}a=a+p|0;G[m>>2]=a;if(((b|0)%(a|0)|0)-1>>>0>2){break o}Ua(61304);break d}j=1;o=(c|0)<=0;D:{if(o){break D}if(G[g+32>>2]<=0){G[g+32>>2]=G[l>>2]}a=1;if((c|0)==1){break D}b=c-1|0;p=b&1;if((c|0)!=2){m=b&-2;b=0;while(1){i=a<<2;q=i+(g+32|0)|0;r=G[q>>2];E:{F:{if((r|0)<0){i=G[i+l>>2];break F}if(r){break E}i=1}G[q>>2]=i}i=a+1<<2;q=i+(g+32|0)|0;r=G[q>>2];G:{H:{if((r|0)>=0){if(r){break G}i=1;break H}i=G[i+l>>2]}G[q>>2]=i}a=a+2|0;b=b+2|0;if((m|0)!=(b|0)){continue}break}}if(!p){break D}a=a<<2;b=a+(g+32|0)|0;i=G[b>>2];I:{if((i|0)>=0){if(i){break D}a=1;break I}a=G[a+l>>2]}G[b>>2]=a}p=G[n+1036>>2];a=0;b=H[35846];E[g+174|0]=b;E[g+170|0]=b;b=H[35844]|H[35845]<<8;F[g+172>>1]=b;F[g+168>>1]=b;G[g+176>>2]=p?4346161:4345905;G[g+188>>2]=g+168;G[g+184>>2]=g+172;G[g+180>>2]=g+176;J:{if(o){break J}if((c|0)!=1){o=c&-2;i=0;while(1){b=a<<2;m=b|4;q=G[m+l>>2]-1|0;r=m;m=g+32|0;j=M(((q|0)/G[r+m>>2]|0)+1|0,M(((G[b+l>>2]-1|0)/G[b+m>>2]|0)+1|0,j));a=a+2|0;i=i+2|0;if((o|0)!=(i|0)){continue}break}}if(!(c&1)){break J}a=a<<2;j=M(((G[a+l>>2]-1|0)/G[a+(g+32|0)>>2]|0)+1|0,j)}K:{if((k|0)<0){b=3;if(K[n+1020>>2]!=N(9999)){break K}}b=1}L:{M:{switch(t+1|0){case 22:a=H[41112]|H[41113]<<8|(H[41114]<<16|H[41115]<<24);E[g+211|0]=a;E[g+212|0]=a>>>8;E[g+213|0]=a>>>16;E[g+214|0]=a>>>24;G[g+208>>2]=H[41109]|H[41110]<<8|(H[41111]<<16|H[41112]<<24);break L;case 23:a=H[40742]|H[40743]<<8|(H[40744]<<16|H[40745]<<24);E[g+211|0]=a;E[g+212|0]=a>>>8;E[g+213|0]=a>>>16;E[g+214|0]=a>>>24;G[g+208>>2]=H[40739]|H[40740]<<8|(H[40741]<<16|H[40742]<<24);break L;case 52:G[g+208>>2]=1346984514;G[g+212>>2]=3235634;break L;case 32:a=H[41119]|H[41120]<<8|(H[41121]<<16|H[41122]<<24);E[g+211|0]=a;E[g+212|0]=a>>>8;E[g+213|0]=a>>>16;E[g+214|0]=a>>>24;G[g+208>>2]=H[41116]|H[41117]<<8|(H[41118]<<16|H[41119]<<24);if(p){G[g+176>>2]=4804913;break L}G[g+176>>2]=4804657;break L;case 42:G[g+216>>2]=H[41084]|H[41085]<<8|(H[41086]<<16|H[41087]<<24);a=H[41080]|H[41081]<<8|(H[41082]<<16|H[41083]<<24);G[g+208>>2]=H[41076]|H[41077]<<8|(H[41078]<<16|H[41079]<<24);G[g+212>>2]=a;break L;case 0:a=H[33725]|H[33726]<<8|(H[33727]<<16|H[33728]<<24);E[g+215|0]=a;E[g+216|0]=a>>>8;E[g+217|0]=a>>>16;E[g+218|0]=a>>>24;a=H[33722]|H[33723]<<8|(H[33724]<<16|H[33725]<<24);G[g+208>>2]=H[33718]|H[33719]<<8|(H[33720]<<16|H[33721]<<24);G[g+212>>2]=a;break L;default:Ua(61448);break d;case 12:break M}}a=H[41126]|H[41127]<<8|(H[41128]<<16|H[41129]<<24);E[g+211|0]=a;E[g+212|0]=a>>>8;E[g+213|0]=a>>>16;E[g+214|0]=a>>>24;G[g+208>>2]=H[41123]|H[41124]<<8|(H[41125]<<16|H[41126]<<24)}i=G[n+76>>2];a=0;nl(d,2,j,j>>31,b,g+192|0,g+180|0,g+152|0,0,e);Rg(d,35668,1,24671,e);if(!i){Rg(d,35504,1,26e3,e)}hd(d,32893,k,k>>31,24353,e);hd(d,33763,c,c>>31,24325,e);N:{if((c|0)<=0){break N}b=0;while(1){j=b+1|0;G[g+16>>2]=j;i=g+224|0;Ya(i,75,29932,g+16|0);b=G[l+(b<<2)>>2];hd(d,i,b,b>>31,6981,e);b=j;if((c|0)!=(b|0)){continue}break}if((c|0)<=0){break N}while(1){b=a+1|0;G[g>>2]=b;j=g+224|0;Ya(j,75,29987,g);a=G[(g+32|0)+(a<<2)>>2];hd(d,j,a,a>>31,29206,e);a=b;if((c|0)!=(a|0)){continue}break}}O:{if((k|0)>=0){break O}b=G[d+4>>2];if(K[b+1020>>2]==N(9999)){lc(d,32673,35436,14623,e);break O}P:{Q:{R:{S:{T:{U:{a=G[b+1024>>2];switch(a|0){case 0:break S;case 2:break U;default:break T}}if(nb(g+208|0,41076,12)){break Q}G[b+1024>>2]=1;hb(86760,124,1,G[24367]);a=G[G[d+4>>2]+1024>>2]}switch(a+1|0){case 2:break R;case 0:break P;case 3:break Q;default:break O}}G[b+1024>>2]=1}lc(d,32673,41088,16314,e);xd(d,31,41550,G[d+4>>2]+1028|0,5737,e);break O}lc(d,32673,40718,16314,e);xd(d,31,41550,G[d+4>>2]+1028|0,5737,e);if(nb(g+208|0,41123,7)){break O}E[g+216|0]=H[35435];a=H[35431]|H[35432]<<8|(H[35433]<<16|H[35434]<<24);G[g+208>>2]=H[35427]|H[35428]<<8|(H[35429]<<16|H[35430]<<24);G[g+212>>2]=a;break O}lc(d,32673,34039,14665,e)}lc(d,35408,g+208|0,16292,e);a=G[G[d+4>>2]+992>>2];V:{if((a|0)!=41){if((a|0)!=11){break V}lc(d,41302,35357,19755,e);hd(d,41273,32,0,17187,e);lc(d,40889,32962,63346,e);W:{switch(k-8|0){case 0:hd(d,40860,1,0,63346,e);break V;case 8:hd(d,40860,2,0,63346,e);break V;default:break W}}hd(d,40860,4,0,63346,e);break V}lc(d,41302,35662,10532,e);Qg(d,41273,K[G[d+4>>2]+1040>>2],7,10532,e);lc(d,40889,34908,13828,e);a=G[G[d+4>>2]+1044>>2];hd(d,40860,a,a>>31,13828,e)}X:{Y:{if(v){G[g+104>>2]=H[4533]|H[4534]<<8|(H[4535]<<16|H[4536]<<24);a=H[4529]|H[4530]<<8|(H[4531]<<16|H[4532]<<24);G[g+96>>2]=H[4525]|H[4526]<<8|(H[4527]<<16|H[4528]<<24);G[g+100>>2]=a;a=H[4521]|H[4522]<<8|(H[4523]<<16|H[4524]<<24);G[g+88>>2]=H[4517]|H[4518]<<8|(H[4519]<<16|H[4520]<<24);G[g+92>>2]=a;a=H[4513]|H[4514]<<8|(H[4515]<<16|H[4516]<<24);G[g+80>>2]=H[4509]|H[4510]<<8|(H[4511]<<16|H[4512]<<24);G[g+84>>2]=a;a=H[4505]|H[4506]<<8|(H[4507]<<16|H[4508]<<24);G[g+72>>2]=H[4501]|H[4502]<<8|(H[4503]<<16|H[4504]<<24);G[g+76>>2]=a;a=H[4497]|H[4498]<<8|(H[4499]<<16|H[4500]<<24);G[g+64>>2]=H[4493]|H[4494]<<8|(H[4495]<<16|H[4496]<<24);G[g+68>>2]=a;s=32768;break Y}if((h|0)!=40){if((h|0)!=10){break X}E[g+104|0]=H[20261];a=H[20257]|H[20258]<<8|(H[20259]<<16|H[20260]<<24);G[g+96>>2]=H[20253]|H[20254]<<8|(H[20255]<<16|H[20256]<<24);G[g+100>>2]=a;a=H[20249]|H[20250]<<8|(H[20251]<<16|H[20252]<<24);G[g+88>>2]=H[20245]|H[20246]<<8|(H[20247]<<16|H[20248]<<24);G[g+92>>2]=a;a=H[20241]|H[20242]<<8|(H[20243]<<16|H[20244]<<24);G[g+80>>2]=H[20237]|H[20238]<<8|(H[20239]<<16|H[20240]<<24);G[g+84>>2]=a;a=H[20233]|H[20234]<<8|(H[20235]<<16|H[20236]<<24);G[g+72>>2]=H[20229]|H[20230]<<8|(H[20231]<<16|H[20232]<<24);G[g+76>>2]=a;a=H[20225]|H[20226]<<8|(H[20227]<<16|H[20228]<<24);G[g+64>>2]=H[20221]|H[20222]<<8|(H[20223]<<16|H[20224]<<24);G[g+68>>2]=a;s=-128;break Y}a=H[17708]|H[17709]<<8|(H[17710]<<16|H[17711]<<24);E[g+103|0]=a;E[g+104|0]=a>>>8;E[g+105|0]=a>>>16;E[g+106|0]=a>>>24;a=H[17705]|H[17706]<<8|(H[17707]<<16|H[17708]<<24);G[g+96>>2]=H[17701]|H[17702]<<8|(H[17703]<<16|H[17704]<<24);G[g+100>>2]=a;a=H[17697]|H[17698]<<8|(H[17699]<<16|H[17700]<<24);G[g+88>>2]=H[17693]|H[17694]<<8|(H[17695]<<16|H[17696]<<24);G[g+92>>2]=a;a=H[17689]|H[17690]<<8|(H[17691]<<16|H[17692]<<24);G[g+80>>2]=H[17685]|H[17686]<<8|(H[17687]<<16|H[17688]<<24);G[g+84>>2]=a;a=H[17681]|H[17682]<<8|(H[17683]<<16|H[17684]<<24);G[g+72>>2]=H[17677]|H[17678]<<8|(H[17679]<<16|H[17680]<<24);G[g+76>>2]=a;a=H[17673]|H[17674]<<8|(H[17675]<<16|H[17676]<<24);G[g+64>>2]=H[17669]|H[17670]<<8|(H[17671]<<16|H[17672]<<24);G[g+68>>2]=a;s=2147483648}c=g- -64|0;be(d,34377,s,c,e);a=H[10528]|H[10529]<<8|(H[10530]<<16|H[10531]<<24);b=H[10524]|H[10525]<<8|(H[10526]<<16|H[10527]<<24);E[g+79|0]=b;E[g+80|0]=b>>>8;E[g+81|0]=b>>>16;E[g+82|0]=b>>>24;E[g+83|0]=a;E[g+84|0]=a>>>8;E[g+85|0]=a>>>16;E[g+86|0]=a>>>24;a=H[10521]|H[10522]<<8|(H[10523]<<16|H[10524]<<24);G[g+72>>2]=H[10517]|H[10518]<<8|(H[10519]<<16|H[10520]<<24);G[g+76>>2]=a;a=H[10513]|H[10514]<<8|(H[10515]<<16|H[10516]<<24);G[g+64>>2]=H[10509]|H[10510]<<8|(H[10511]<<16|H[10512]<<24);G[g+68>>2]=a;be(d,35661,1,c,e)}break c}Ua(61231);break d}Ua(61165);break d}Ua(61377)}G[e>>2]=413}Fa=g+304|0;break a}Z:{if(!h){h=H[26031]|H[26032]<<8|(H[26033]<<16|H[26034]<<24);E[f+127|0]=h;E[f+128|0]=h>>>8;E[f+129|0]=h>>>16;E[f+130|0]=h>>>24;h=H[26028]|H[26029]<<8|(H[26030]<<16|H[26031]<<24);G[f+120>>2]=H[26024]|H[26025]<<8|(H[26026]<<16|H[26027]<<24);G[f+124>>2]=h;h=H[26020]|H[26021]<<8|(H[26022]<<16|H[26023]<<24);G[f+112>>2]=H[26016]|H[26017]<<8|(H[26018]<<16|H[26019]<<24);G[f+116>>2]=h;h=H[26012]|H[26013]<<8|(H[26014]<<16|H[26015]<<24);G[f+104>>2]=H[26008]|H[26009]<<8|(H[26010]<<16|H[26011]<<24);G[f+108>>2]=h;h=H[26004]|H[26005]<<8|(H[26006]<<16|H[26007]<<24);G[f+96>>2]=H[26e3]|H[26001]<<8|(H[26002]<<16|H[26003]<<24);G[f+100>>2]=h;if(G[e>>2]>0){break Z}F[f+176>>1]=84;h=f+256|0;Ob(35530,f+176|0,f+96|0,h,e);wb(a,h,e);break Z}h=H[15459]|H[15460]<<8|(H[15461]<<16|H[15462]<<24);G[f+104>>2]=H[15455]|H[15456]<<8|(H[15457]<<16|H[15458]<<24);G[f+108>>2]=h;h=H[15451]|H[15452]<<8|(H[15453]<<16|H[15454]<<24);G[f+96>>2]=H[15447]|H[15448]<<8|(H[15449]<<16|H[15450]<<24);G[f+100>>2]=h;lc(a,34516,35678,f+96|0,e)}h=16;_:{$:{if((b|0)==20){break $}aa:{if((b|0)<=7){if((b|0)==-64|(b|0)==-32){break aa}break _}h=32;ba:{switch(b-8|0){default:if((b|0)!=80){break _}h=64;break $;case 32:break $;case 0:case 8:case 24:case 56:break aa;case 2:break ba;case 1:case 3:case 4:case 5:case 6:case 7:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:break _}}h=8;break $}h=b}k=H[16897]|H[16898]<<8|(H[16899]<<16|H[16900]<<24);g=H[16893]|H[16894]<<8|(H[16895]<<16|H[16896]<<24);F[f+118>>1]=g;F[f+120>>1]=g>>>16;F[f+122>>1]=k;F[f+124>>1]=k>>>16;k=H[16891]|H[16892]<<8|(H[16893]<<16|H[16894]<<24);G[f+112>>2]=H[16887]|H[16888]<<8|(H[16889]<<16|H[16890]<<24);G[f+116>>2]=k;k=H[16883]|H[16884]<<8|(H[16885]<<16|H[16886]<<24);G[f+104>>2]=H[16879]|H[16880]<<8|(H[16881]<<16|H[16882]<<24);G[f+108>>2]=k;k=H[16875]|H[16876]<<8|(H[16877]<<16|H[16878]<<24);G[f+96>>2]=H[16871]|H[16872]<<8|(H[16873]<<16|H[16874]<<24);G[f+100>>2]=k;if(G[e>>2]>0){break a}E[f+176|0]=0;G[f+64>>2]=h;G[f+68>>2]=h>>31;if((db(f+176|0,26741,f- -64|0)|0)<0){Ua(17884);G[e>>2]=401}h=f+256|0;Ob(32941,f+176|0,f+96|0,h,e);wb(a,h,e);if(G[e>>2]>0){break a}if(c>>>0>=1e3){G[f>>2]=c;a=f+256|0;Ya(a,81,30538,f);Ua(a);G[e>>2]=212;break a}G[f+112>>2]=H[7252]|H[7253]<<8|(H[7254]<<16|H[7255]<<24);h=H[7248]|H[7249]<<8|(H[7250]<<16|H[7251]<<24);G[f+104>>2]=H[7244]|H[7245]<<8|(H[7246]<<16|H[7247]<<24);G[f+108>>2]=h;h=H[7240]|H[7241]<<8|(H[7242]<<16|H[7243]<<24);G[f+96>>2]=H[7236]|H[7237]<<8|(H[7238]<<16|H[7239]<<24);G[f+100>>2]=h;hd(a,33788,c,0,f+96|0,e);h=H[66106]|H[66107]<<8|(H[66108]<<16|H[66109]<<24);k=H[66102]|H[66103]<<8|(H[66104]<<16|H[66105]<<24);E[f+109|0]=k;E[f+110|0]=k>>>8;E[f+111|0]=k>>>16;E[f+112|0]=k>>>24;E[f+113|0]=h;E[f+114|0]=h>>>8;E[f+115|0]=h>>>16;E[f+116|0]=h>>>24;h=H[66101]|H[66102]<<8|(H[66103]<<16|H[66104]<<24);G[f+104>>2]=H[66097]|H[66098]<<8|(H[66099]<<16|H[66100]<<24);G[f+108>>2]=h;h=H[66093]|H[66094]<<8|(H[66095]<<16|H[66096]<<24);G[f+96>>2]=H[66089]|H[66090]<<8|(H[66091]<<16|H[66092]<<24);G[f+100>>2]=h;if(c){j=f+116|0;h=0;while(1){k=h+1|0;g=(h<<3)+d|0;h=G[g+4>>2];i=G[g>>2];if((h|0)<0){G[f+16>>2]=k;L[f+24>>3]=+(i>>>0)+ +(h|0)*4294967296;a=f+256|0;Ya(a,81,19457,f+16|0);Ua(a);G[e>>2]=213;break a}G[f+48>>2]=k;Ya(j,53,30633,f+48|0);zb(33788,k,f+176|0,e);if(G[e>>2]<=0){h=G[g+4>>2];G[f+32>>2]=G[g>>2];G[f+36>>2]=h;E[f+352|0]=0;if((db(f+352|0,26741,f+32|0)|0)<0){Ua(17884);G[e>>2]=401}h=f+256|0;Ob(f+176|0,f+352|0,f+96|0,h,e);wb(a,h,e)}h=k;if((h|0)!=(c|0)){continue}break}}ca:{if(!G[G[a+4>>2]+76>>2]){G[f+128>>2]=H[6580]|H[6581]<<8|(H[6582]<<16|H[6583]<<24);c=H[6576]|H[6577]<<8|(H[6578]<<16|H[6579]<<24);G[f+120>>2]=H[6572]|H[6573]<<8|(H[6574]<<16|H[6575]<<24);G[f+124>>2]=c;c=H[6568]|H[6569]<<8|(H[6570]<<16|H[6571]<<24);G[f+112>>2]=H[6564]|H[6565]<<8|(H[6566]<<16|H[6567]<<24);G[f+116>>2]=c;c=H[6560]|H[6561]<<8|(H[6562]<<16|H[6563]<<24);G[f+104>>2]=H[6556]|H[6557]<<8|(H[6558]<<16|H[6559]<<24);G[f+108>>2]=c;c=H[6552]|H[6553]<<8|(H[6554]<<16|H[6555]<<24);G[f+96>>2]=H[6548]|H[6549]<<8|(H[6550]<<16|H[6551]<<24);G[f+100>>2]=c;Rg(a,35787,1,f+96|0,e);wb(a,3277,e);wb(a,34961,e);break ca}c=H[41831]|H[41832]<<8|(H[41833]<<16|H[41834]<<24);E[f+119|0]=c;E[f+120|0]=c>>>8;E[f+121|0]=c>>>16;E[f+122|0]=c>>>24;c=H[41828]|H[41829]<<8|(H[41830]<<16|H[41831]<<24);G[f+112>>2]=H[41824]|H[41825]<<8|(H[41826]<<16|H[41827]<<24);G[f+116>>2]=c;c=H[41820]|H[41821]<<8|(H[41822]<<16|H[41823]<<24);G[f+104>>2]=H[41816]|H[41817]<<8|(H[41818]<<16|H[41819]<<24);G[f+108>>2]=c;c=H[41812]|H[41813]<<8|(H[41814]<<16|H[41815]<<24);G[f+96>>2]=H[41808]|H[41809]<<8|(H[41810]<<16|H[41811]<<24);G[f+100>>2]=c;d=f+96|0;hd(a,33303,0,0,d,e);c=H[41477]|H[41478]<<8|(H[41479]<<16|H[41480]<<24);E[f+119|0]=c;E[f+120|0]=c>>>8;E[f+121|0]=c>>>16;E[f+122|0]=c>>>24;c=H[41474]|H[41475]<<8|(H[41476]<<16|H[41477]<<24);G[f+112>>2]=H[41470]|H[41471]<<8|(H[41472]<<16|H[41473]<<24);G[f+116>>2]=c;c=H[41466]|H[41467]<<8|(H[41468]<<16|H[41469]<<24);G[f+104>>2]=H[41462]|H[41463]<<8|(H[41464]<<16|H[41465]<<24);G[f+108>>2]=c;c=H[41458]|H[41459]<<8|(H[41460]<<16|H[41461]<<24);G[f+96>>2]=H[41454]|H[41455]<<8|(H[41456]<<16|H[41457]<<24);G[f+100>>2]=c;hd(a,33311,1,0,d,e)}da:{if((b|0)==20){G[f+136>>2]=H[4533]|H[4534]<<8|(H[4535]<<16|H[4536]<<24);b=H[4529]|H[4530]<<8|(H[4531]<<16|H[4532]<<24);G[f+128>>2]=H[4525]|H[4526]<<8|(H[4527]<<16|H[4528]<<24);G[f+132>>2]=b;b=H[4521]|H[4522]<<8|(H[4523]<<16|H[4524]<<24);G[f+120>>2]=H[4517]|H[4518]<<8|(H[4519]<<16|H[4520]<<24);G[f+124>>2]=b;b=H[4513]|H[4514]<<8|(H[4515]<<16|H[4516]<<24);G[f+112>>2]=H[4509]|H[4510]<<8|(H[4511]<<16|H[4512]<<24);G[f+116>>2]=b;b=H[4505]|H[4506]<<8|(H[4507]<<16|H[4508]<<24);G[f+104>>2]=H[4501]|H[4502]<<8|(H[4503]<<16|H[4504]<<24);G[f+108>>2]=b;b=H[4497]|H[4498]<<8|(H[4499]<<16|H[4500]<<24);G[f+96>>2]=H[4493]|H[4494]<<8|(H[4495]<<16|H[4496]<<24);G[f+100>>2]=b;be(a,34377,32768,f+96|0,e);break da}if((b|0)!=10){if((b|0)!=80){if((b|0)!=40){break a}b=H[17708]|H[17709]<<8|(H[17710]<<16|H[17711]<<24);E[f+135|0]=b;E[f+136|0]=b>>>8;E[f+137|0]=b>>>16;E[f+138|0]=b>>>24;b=H[17705]|H[17706]<<8|(H[17707]<<16|H[17708]<<24);G[f+128>>2]=H[17701]|H[17702]<<8|(H[17703]<<16|H[17704]<<24);G[f+132>>2]=b;b=H[17697]|H[17698]<<8|(H[17699]<<16|H[17700]<<24);G[f+120>>2]=H[17693]|H[17694]<<8|(H[17695]<<16|H[17696]<<24);G[f+124>>2]=b;b=H[17689]|H[17690]<<8|(H[17691]<<16|H[17692]<<24);G[f+112>>2]=H[17685]|H[17686]<<8|(H[17687]<<16|H[17688]<<24);G[f+116>>2]=b;b=H[17681]|H[17682]<<8|(H[17683]<<16|H[17684]<<24);G[f+104>>2]=H[17677]|H[17678]<<8|(H[17679]<<16|H[17680]<<24);G[f+108>>2]=b;b=H[17673]|H[17674]<<8|(H[17675]<<16|H[17676]<<24);G[f+96>>2]=H[17669]|H[17670]<<8|(H[17671]<<16|H[17672]<<24);G[f+100>>2]=b;be(a,34377,2147483648,f+96|0,e);break da}b=f+256|0;bb(b,17588,81);wb(a,b,e);break da}E[f+136|0]=H[20261];b=H[20257]|H[20258]<<8|(H[20259]<<16|H[20260]<<24);G[f+128>>2]=H[20253]|H[20254]<<8|(H[20255]<<16|H[20256]<<24);G[f+132>>2]=b;b=H[20249]|H[20250]<<8|(H[20251]<<16|H[20252]<<24);G[f+120>>2]=H[20245]|H[20246]<<8|(H[20247]<<16|H[20248]<<24);G[f+124>>2]=b;b=H[20241]|H[20242]<<8|(H[20243]<<16|H[20244]<<24);G[f+112>>2]=H[20237]|H[20238]<<8|(H[20239]<<16|H[20240]<<24);G[f+116>>2]=b;b=H[20233]|H[20234]<<8|(H[20235]<<16|H[20236]<<24);G[f+104>>2]=H[20229]|H[20230]<<8|(H[20231]<<16|H[20232]<<24);G[f+108>>2]=b;b=H[20225]|H[20226]<<8|(H[20227]<<16|H[20228]<<24);G[f+96>>2]=H[20221]|H[20222]<<8|(H[20223]<<16|H[20224]<<24);G[f+100>>2]=b;be(a,34377,-128,f+96|0,e)}b=H[10528]|H[10529]<<8|(H[10530]<<16|H[10531]<<24);c=H[10524]|H[10525]<<8|(H[10526]<<16|H[10527]<<24);E[f+111|0]=c;E[f+112|0]=c>>>8;E[f+113|0]=c>>>16;E[f+114|0]=c>>>24;E[f+115|0]=b;E[f+116|0]=b>>>8;E[f+117|0]=b>>>16;E[f+118|0]=b>>>24;b=H[10521]|H[10522]<<8|(H[10523]<<16|H[10524]<<24);G[f+104>>2]=H[10517]|H[10518]<<8|(H[10519]<<16|H[10520]<<24);G[f+108>>2]=b;b=H[10513]|H[10514]<<8|(H[10515]<<16|H[10516]<<24);G[f+96>>2]=H[10509]|H[10510]<<8|(H[10511]<<16|H[10512]<<24);G[f+100>>2]=b;be(a,35661,1,f+96|0,e);break a}G[f+80>>2]=b;a=f+256|0;Ya(a,81,30501,f+80|0);Ua(a);G[e>>2]=211}Fa=f+432|0}function bn(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;l=Fa-208|0;Fa=l;G[309831]=G[309831]+1;G[l+204>>2]=0;E[l+32|0]=0;G[l+24>>2]=0;G[l+28>>2]=0;d=b;n=Fa-16|0;Fa=n;p=l+204|0;b=G[p>>2];if(!b){s=Fa-16|0;Fa=s;b=G[p>>2];if((b|0)<=0){e=G[a>>2];G[n+8>>2]=e;b=G[a+4>>2];if((G[b+128>>2]&G[b+132>>2])!=-1){G[s+12>>2]=0;e=e+1|0;if((mb(a,e,0,s+12|0)|0)<=0){b=e;while(1){G[n+8>>2]=b;b=b+1|0;if((mb(a,b,0,s+12|0)|0)<=0){continue}break}}mb(a,e,0,p)}b=G[p>>2]}Fa=s+16|0;G[p>>2]=b;e=G[n+8>>2];if(e){b=mb(a,e,n+12|0,p);G[p>>2]=b}if(b){G[p>>2]=0}m=Fa-544|0;Fa=m;G[m+540>>2]=0;G[m+536>>2]=0;G[m+532>>2]=0;E[m+280|0]=H[35098];b=H[35094]|H[35095]<<8|(H[35096]<<16|H[35097]<<24);G[m+272>>2]=H[35090]|H[35091]<<8|(H[35092]<<16|H[35093]<<24);G[m+276>>2]=b;G[m+500>>2]=m+369;G[m+504>>2]=m+386;G[m+508>>2]=m+403;G[m+512>>2]=m+420;b=m+288|0;G[m+468>>2]=b|9;G[m+472>>2]=m+306;G[m+476>>2]=m+315;G[m+496>>2]=m+352;G[m+464>>2]=b;G[m+480>>2]=m+324;G[m+516>>2]=m+437;G[m+484>>2]=m+333;g=m+496|0;f=m+464|0;j=Fa-160|0;Fa=j;b=G[30023];G[j+152>>2]=G[30022];G[j+156>>2]=b;b=G[30021];G[j+144>>2]=G[30020];G[j+148>>2]=b;E[j+142|0]=H[35991];F[j+140>>1]=H[35989]|H[35990]<<8;G[j+136>>2]=H[35468]|H[35469]<<8|(H[35470]<<16|H[35471]<<24);b=H[35464]|H[35465]<<8|(H[35466]<<16|H[35467]<<24);G[j+128>>2]=H[35460]|H[35461]<<8|(H[35462]<<16|H[35463]<<24);G[j+132>>2]=b;G[j+124>>2]=4272691;e=H[34454]|H[34455]<<8|(H[34456]<<16|H[34457]<<24);b=H[34450]|H[34451]<<8|(H[34452]<<16|H[34453]<<24);E[j+111|0]=b;E[j+112|0]=b>>>8;E[j+113|0]=b>>>16;E[j+114|0]=b>>>24;E[j+115|0]=e;E[j+116|0]=e>>>8;E[j+117|0]=e>>>16;E[j+118|0]=e>>>24;b=H[34447]|H[34448]<<8|(H[34449]<<16|H[34450]<<24);G[j+104>>2]=H[34443]|H[34444]<<8|(H[34445]<<16|H[34446]<<24);G[j+108>>2]=b;s=H[34880];E[j+102|0]=s;e=H[34878]|H[34879]<<8;F[j+100>>1]=e;b=G[30027];G[j+88>>2]=G[30026];G[j+92>>2]=b;b=G[30025];G[j+80>>2]=G[30024];G[j+84>>2]=b;E[j+78|0]=s;F[j+76>>1]=e;b=G[30031];G[j+56>>2]=G[30030];G[j+60>>2]=b;b=G[30029];G[j+48>>2]=G[30028];G[j+52>>2]=b;E[j+46|0]=H[35999];F[j+44>>1]=H[35997]|H[35998]<<8;b=G[30035];G[j+24>>2]=G[30034];G[j+28>>2]=b;b=G[30033];G[j+16>>2]=G[30032];G[j+20>>2]=b;E[j+12|0]=H[35996];G[j+8>>2]=H[35992]|H[35993]<<8|(H[35994]<<16|H[35995]<<24);b=G[p>>2];if(!b){Za(G[g>>2],j+144|0);Za(G[f>>2],j+140|0);Za(G[g+4>>2],j+128|0);Za(G[f+4>>2],j+124|0);Za(G[g+8>>2],j+104|0);Za(G[f+8>>2],j+100|0);Za(G[g+12>>2],j+80|0);Za(G[f+12>>2],j+76|0);Za(G[g+16>>2],j+16|0);Za(G[f+16>>2],j+8|0);Za(G[g+20>>2],j+48|0);Za(G[f+20>>2],j+44|0);G[m+540>>2]=6;b=G[p>>2]}Fa=j+160|0;G[p>>2]=b;x=G[m+540>>2];v=Fa-192|0;Fa=v;b=G[p>>2];a:{if((b|0)>0){break a}E[v+16|0]=0;b=G[a>>2];q=G[a+4>>2];if((b|0)!=G[q+76>>2]){mb(a,b+1|0,0,p);q=G[a+4>>2];b=G[q+76>>2]}b:{c:{d:{e:{s=G[q+96>>2];e=s+(b<<3)|0;if(G[q+104>>2]!=G[e>>2]|G[q+108>>2]!=G[e+4>>2]){if(G[q+88>>2]!=(b|0)){break e}b=s+(b<<3)|0;i=J[b+8>>2]>2];e=G[b+12>>2];b=G[q+44>>2];if(i&(e|0)<=(b|0)|(b|0)>(e|0)){break e}}nl(a,2,0,0,x,g,f,0,v+16|0,p);break d}if(x>>>0>999){break c}b=0;f:{if(!x){break f}}s=H[v+16|0];if((x|0)>0){while(1){Vf(G[f+(b<<2)>>2],v+96|0,v+188|0,v+184|0,p);q=r;g:{h:{i:{e=G[v+96>>2]-1|0;if(e){if((e|0)==15){break i}else{break h}}r=(G[v+188>>2]+7|0)/8|0;break g}r=G[v+188>>2];break g}r=M(G[v+184>>2],G[v+188>>2])}e=q+(r>>31)|0;h=h+r|0;r=h>>>0>>0?e+1|0:e;b=b+1|0;if((x|0)!=(b|0)){continue}break}q=G[a+4>>2]}if(G[q+84>>2]!=1){break b}Rb(a,p);_n(a,p);e=G[a+4>>2];o=G[e+76>>2]+1|0;b=G[e+96>>2]+(o<<3)|0;i=G[b>>2];k=G[b+4>>2];G[e+80>>2]=2;s=(((x<<1)+((s|0)!=0)|0)+44|0)/36|0;if((Bf(a,s,1,p)|0)>0){break d}w=G[a+4>>2];e=G[w+88>>2];b=e+1|0;G[w+88>>2]=b;u=G[w+96>>2];j=G[w+76>>2];j:{if((e|0)<(j|0)){break j}r=e-j|0;h=r+1&3;if(h){q=0;while(1){t=(b<<3)+u|0;e=G[t+4>>2];G[t+8>>2]=G[t>>2];G[t+12>>2]=e;b=b-1|0;q=q+1|0;if((h|0)!=(q|0)){continue}break}}if(r>>>0<3){break j}while(1){t=(b<<3)+u|0;e=G[t+4>>2];G[t+8>>2]=G[t>>2];G[t+12>>2]=e;h=t-8|0;e=G[h+4>>2];G[t>>2]=G[h>>2];G[t+4>>2]=e;r=t-16|0;e=G[r+4>>2];G[h>>2]=G[r>>2];G[h+4>>2]=e;h=t-24|0;e=G[h+4>>2];G[r>>2]=G[h>>2];G[r+4>>2]=e;b=b-4|0;if((j|0)<(b|0)){continue}break}}h=(o<<3)+u|0;G[h>>2]=i;G[h+4>>2]=k;G[w+76>>2]=o;G[a>>2]=o;G[w+120>>2]=i;G[w+124>>2]=k;b=G[h+4>>2];G[w+104>>2]=G[h>>2];G[w+108>>2]=b;e=G[h>>2];b=G[h+4>>2];G[w+80>>2]=2;h=M(s,2880);e=h+e|0;G[w+128>>2]=e;b=(h>>31)+b|0;G[w+132>>2]=e>>>0>>0?b+1|0:b;qq(a,0,0,x,g,f,0,v+16|0,p);Rb(a,p)}b=G[p>>2];break a}G[v>>2]=x;b=v+96|0;Ya(b,81,30574,v);Ua(b);b=216;G[p>>2]=216;break a}b=112;G[p>>2]=112}Fa=v+192|0;G[p>>2]=b;if(!b){G[m+536>>2]=G[a>>2]+1;Vc(a,33837,m+112|0,m+32|0,p);vq(a,35480,m+272|0,23611,p);Fh(a,33996,0,0,60936,p);if(!(!d|!H[d|0])){vq(a,35496,d,21520,p)}k:{if((x|0)<=0){break k}b=0;while(1){if(G[p>>2]){break k}l:{m:{d=(m+496|0)+(b<<2)|0;if(!Ib(G[d>>2],120096)){break m}if(!Ib(G[d>>2],34443)){break m}b=b+1|0;break l}b=b+1|0;G[m+16>>2]=b;d=m+192|0;Ya(d,75,29963,m+16|0);y=p,z=Fc(a,d,m+112|0,m+32|0,p),G[y>>2]=z;G[m>>2]=b;Ya(d,75,29971,m);y=p,z=Fh(a,d,0,0,20187,p),G[y>>2]=z}if((b|0)!=(x|0)){continue}break}}b=1;while(1){d=b;b=d+1|0;if(!Je(a,-1,35090,d,p)){continue}break}if(G[p>>2]==301){G[p>>2]=0}mb(a,G[m+536>>2],m+532|0,p);Ad(a,33996,d,0,65398,p);b=G[p>>2]}Fa=m+544|0;G[p>>2]=b}Fa=n+16|0;G[l+204>>2]=b;n:{if(b){break n}G[l+200>>2]=G[a>>2]+1;if((c|0)>0){d=c;b=l+196|0;c=l+204|0;mb(a,d,b,c);Un(a,G[l+200>>2],c);mb(a,G[l+200>>2],b,c);b=G[l+204>>2];if(b){break n}}c=6;while(1){o:{b=eh(0);G[l+204>>2]=b;if(b){break o}p:{q:{switch(G[47524]-1|0){case 3:case 4:G[l+204>>2]=369;break o;case 1:G[309831]=G[309831]-1;break o;case 0:r:{if(G[310098]==2){rb(l+112|0,G[310118],80);break r}b=G[47540];G[47540]=b+1;G[l+16>>2]=b;Ya(l+112|0,80,29887,l+16|0)}E[l+191|0]=0;b=bn(a,l+112|0,G[l+200>>2]);break p;case 2:if(!G[309816]){G[l+204>>2]=363;break o}if(G[309823]){G[l+204>>2]=364;break o}b=G[309817];G[309823]=G[309816];G[309824]=b;G[309829]=G[309822];b=G[309821];G[309827]=G[309820];G[309828]=b;b=G[309819];G[309825]=G[309818];G[309826]=b;G[l+204>>2]=0;G[309816]=0;b=Qj(a,G[l+200>>2],0);break p;default:break q}}d=Va(1240396);s:{if(d-2>>>0>4){break s}e=d-1|0;if(H[e+1240396|0]!=35){break s}if(!H[l+32|0]){b=l+32|0;bb(b,1240396,e);E[b+e|0]=0}if((Va(l+32|0)|0)==(e|0)){c=!nb(l+32|0,1240396,e)+c|0}G[l>>2]=c;Ya(d+1240395|0,76-d|0,30633,l)}b=360;d=G[l+24>>2];t:{if(!d){d=ab(176);break t}d=ub(G[l+28>>2],M(d,176)+176|0)}if(!d){break p}h=G[l+24>>2];G[l+28>>2]=d;d=bb(d+M(h,176)|0,1240392,176);u:{if(G[310098]!=2){break u}e=G[310118];if(!e){break u}q=d;d=ab(Va(e)+1|0);G[q+80>>2]=d;if(!d){break p}Za(d,e)}G[l+24>>2]=h+1;b=0}G[l+204>>2]=b;if(!b){continue}}break}mb(a,G[l+200>>2],l+196|0,l+204|0);v:{w:{if(G[l+204>>2]){break w}b=cn(a,l+24|0,6);G[l+204>>2]=b;if(b){break w}b=Rj(l+24|0,a);G[l+204>>2]=b;if(!b){break v}}G[l+196>>2]=0;c=a;t=Fa-16016|0;Fa=t;G[t+16008>>2]=0;d=l+196|0;if(!G[d>>2]){a=ik(c,t+16008|0,d);G[d>>2]=a;h=G[t+16008>>2];x:{if((h|0)<=0){break x}while(1){if(a){break x}a=0;g=Fa-7552|0;Fa=g;G[g+7548>>2]=0;G[g+7544>>2]=0;G[g+7540>>2]=0;G[g+7536>>2]=0;G[g+7532>>2]=0;G[g+7528>>2]=0;G[g+76>>2]=0;b=G[d>>2];if(!b){G[g+7544>>2]=G[G[c+4>>2]+84>>2];y:{if(G[g+7544>>2]!=1){Ua(58442);G[d>>2]=350;break y}u=g+76|0;i=0;f=Fa-6544|0;Fa=f;G[f+6504>>2]=0;G[f+6500>>2]=0;E[f+15|0]=0;o=G[d>>2];z:{if(o){break z}o=jk(c,f+6540|0,f+6536|0,f+6532|0,f+6528|0,f+6524|0,f+6520|0,f+6516|0,d);G[d>>2]=o;A:{if(o){break A}b=G[f+6540>>2];k=G[f+6536>>2];j=G[f+6532>>2];s=G[f+6528>>2];r=G[f+6524>>2];e=G[f+6520>>2];n=Fa-16|0;Fa=n;G[n+12>>2]=0;G[n+8>>2]=0;G[n+4>>2]=0;o=G[d>>2];if(!o){B:{C:{D:{E:{F:{G:{if(b){vd(c,b,n+12|0,n+8|0,n+4|0,d);b=G[d>>2];if(b|G[n+12>>2]!=16){break G}o=56889;b=G[n+8>>2];if((b|0)>8|(b|0)!=G[n+4>>2]){break D}}if(k){vd(c,k,n+12|0,n+8|0,n+4|0,d);b=G[d>>2];if(b|G[n+12>>2]!=16){break F}o=56938;b=G[n+8>>2];if((b|0)>32|(b|0)!=G[n+4>>2]){break D}}H:{if(!j){break H}vd(c,j,n+12|0,n+8|0,n+4|0,d);b=G[d>>2];if(!(b|G[n+12>>2]!=41)&G[n+8>>2]<2){break H}o=56841;if(!b){break D}break C}I:{if(!s){break I}vd(c,s,n+12|0,n+8|0,n+4|0,d);b=G[d>>2];if(!(b|G[n+12>>2]!=41)&G[n+8>>2]<2){break I}o=56743;if(!b){break D}break C}if(r){vd(c,r,n+12|0,n+8|0,n+4|0,d);b=G[d>>2];if(b|G[n+12>>2]!=16){break E}o=56792;b=G[n+8>>2];if((b|0)>256|(b|0)!=G[n+4>>2]){break D}}if(!e){break B}vd(c,e,n+12|0,n+8|0,n+4|0,d);b=G[d>>2];if(!(b|G[n+12>>2]!=16)){o=56983;b=G[n+8>>2];if((b|0)>3|(b|0)!=G[n+4>>2]){break D}break B}o=56983;if(b){break C}break D}o=56889;if(!b){break D}break C}o=56938;if(!b){break D}break C}o=56792;if(b){break C}}G[d>>2]=340}Ua(o)}o=G[d>>2]}Fa=n+16|0;G[d>>2]=o;if(o){break A}G[f+8>>2]=f+6416;b=G[f+6540>>2];if(b){y=d,z=Df(c,b,h,h>>31,f+15|0,f+8|0,f+6508|0,d),G[y>>2]=z;J:{K:{if(!Ib(f+6416|0,32755)){break K}if(!Ib(f+6416|0,35678)){break K}i=1;if(!Ib(f+6416|0,35630)){break J}i=2;if(!Ib(f+6416|0,35618)){break J}i=-1;break J}i=0}G[f+6512>>2]=i}G[f+8>>2]=f+6336;b=G[f+6536>>2];if(b){y=d,z=Df(c,b,h,h>>31,f+15|0,f+8|0,f+6508|0,d),G[y>>2]=z}b=G[f+6532>>2];if(b){y=d,z=Zk(c,b,h,h>>31,f+6500|0,f+6508|0,d),G[y>>2]=z}b=G[f+6528>>2];if(b){y=d,z=Zk(c,b,h,h>>31,f+6504|0,f+6508|0,d),G[y>>2]=z}G[f+8>>2]=f+3136;b=G[f+6524>>2];if(b){y=d,z=Df(c,b,h,h>>31,f+15|0,f+8|0,f+6508|0,d),G[y>>2]=z}G[f+8>>2]=f+6256;b=G[f+6520>>2];L:{if(b){o=Df(c,b,h,h>>31,f+15|0,f+8|0,f+6508|0,d);G[d>>2]=o;break L}o=G[d>>2]}M:{N:{O:{if(o){break O}r=G[f+6516>>2];if(r>>>0>12){break O}P:{Q:{R:{b=1<>2]=104;G[f>>2]=f+6256;b=f+5216|0;Ya(b,81,52370,f);Ua(b);break O}if(ad(f+3136|0)){Ua(52686);b=Rc(u,f+3136|0,1,d);G[d>>2]=b;if(!b){break P}G[d>>2]=0;Ua(52331);b=Rc(u,f+3136|0,0,d);break Q}Ua(52823);if(H[f+3136|0]==47){Ua(52424);b=f+2096|0;y=d,z=kh(f+3136|0,b,d),G[y>>2]=z;Ua(52600);b=Rc(u,b,1,d);G[d>>2]=b;if(!b){break P}G[d>>2]=0;Ua(52331);b=Rc(u,f+2096|0,0,d);break Q}Ua(52774);y=d,z=yf(c,f+5216|0,f+4176|0,0,0,0,d),G[y>>2]=z;b=H[f+5216|0];if(b){if(!(ad(f+5216|0)|(b|0)==47)){e=f+16|0;cf(e,d);b=Va(e)+e|0;E[b|0]=47;E[b+1|0]=0;if((Va(e)+Va(f+5216|0)|0)-1024>>>0<=4294966270){Ua(52513);G[d>>2]=125;break O}b=f+5216|0;Za(b,Gb(f+16|0,b))}b=Dg(f+5216|0,f+3136|0,f+2096|0,d);G[d>>2]=b;if(b){break O}if(!ad(f+2096|0)){e=f+2096|0;b=f+1056|0;y=d,z=kh(e,b,d),G[y>>2]=z;Za(e,b)}b=Rc(u,f+2096|0,1,d);G[d>>2]=b;if(!b){break P}G[d>>2]=0;Ua(52644);b=Rc(u,f+2096|0,0,d);G[d>>2]=b;if(!b){break P}G[d>>2]=0}b=H[f+4176|0];if(b){if(!(ad(f+4176|0)|(b|0)==47)){b=f+16|0;cf(b,d);if((Va(b)+Va(f+4176|0)|0)-1024>>>0<=4294966270){Ua(52468);G[d>>2]=125;break O}e=f+16|0;b=Va(e)+e|0;E[b|0]=47;E[b+1|0]=0;b=f+4176|0;Za(b,Gb(e,b))}b=Dg(f+4176|0,f+3136|0,f+2096|0,d);G[d>>2]=b;if(b){break O}if(!ad(f+2096|0)){e=f+2096|0;b=f+1056|0;y=d,z=kh(e,b,d),G[y>>2]=z;Za(e,b)}b=Rc(u,f+2096|0,1,d);G[d>>2]=b;if(!b){break P}G[d>>2]=0;Ua(52644);b=Rc(u,f+2096|0,0,d);G[d>>2]=b;if(!b){break P}G[d>>2]=0}Ua(52558);G[d>>2]=342;break O}b=Mj(c,u,d)}G[d>>2]=b;if(b){break O}}if(r>>>0>12){break O}b=1<>2],G[f+6504>>2],f+6512|0,d);G[d>>2]=o;break M}o=Je(G[u>>2],i,f+6336|0,G[f+6500>>2],d);G[d>>2]=o;if((o|0)!=301){break M}G[d>>2]=342;Ua(52732);break O}if(!H[f+6416|0]|!H[f+6336|0]){break N}b=G[f+6500>>2];if((b|0)<=0){break N}o=Je(G[u>>2],i,f+6336|0,b,d);G[d>>2]=o;if((o|0)!=301){break M}G[d>>2]=342;Ua(52732)}o=G[d>>2];break M}b=mb(G[u>>2],G[f+6504>>2],f+6512|0,d);o=(b|0)==107?342:b;G[d>>2]=o}if(o){break A}o=0;break z}b=G[u>>2];if(!b){break z}Qb(b,d);o=G[d>>2]}Fa=f+6544|0;G[d>>2]=o;G[g+7544>>2]=G[G[G[g+76>>2]+4>>2]+84>>2];G[d>>2]=G[d>>2];S:{if(G[g+7544>>2]!=1){break S}y=d,z=Ec(c,33996,g+7532|0,g+2160|0,d),G[y>>2]=z;se(G[G[G[g+76>>2]+4>>2]+12>>2],g+1120|0,d);se(G[G[c+4>>2]+12>>2],g+80|0,d);T:{if(G[G[g+76>>2]+4>>2]==G[c+4>>2]){break T}if(!fb(g+1120|0,g+80|0,1025)){break T}G[g+7532>>2]=0-G[g+7532>>2]}b=yf(c,g+6496|0,g+5456|0,0,0,0,d);G[d>>2]=b;if(b){break y}y=d,z=cf(g+3376|0,d),G[y>>2]=z;b=H[g+6496|0];U:{if(!b|(b|0)==47){break U}if(ad(g+6496|0)){break U}e=Za(g+4416|0,g+3376|0);if((Va(e)+Va(g+6496|0)|0)-1024>>>0<=4294966270){Ua(56553);G[d>>2]=125;break y}b=Va(e)+e|0;E[b|0]=47;E[b+1|0]=0;b=g+6496|0;_d(Gb(e,b),b,d)}b=H[g+5456|0];V:{if(!b|(b|0)==47){break V}if(ad(g+5456|0)){break V}e=Za(g+4416|0,g+3376|0);if((Va(e)+Va(g+5456|0)|0)-1024>>>0<=4294966270){Ua(56553);G[d>>2]=125;break y}b=Va(e)+e|0;E[b|0]=47;E[b+1|0]=0;b=g+5456|0;_d(Gb(e,b),b,d)}y=d,z=lh(G[g+76>>2],g+7540|0,d),G[y>>2]=z;q=Sd(G[g+76>>2],0,g+2160|0,d);G[d>>2]=q;e=1;r=G[g+7540>>2];if((r|0)<=0){break S}while(1){if(!(a|q)){b=e;G[g+64>>2]=b;a=g+3296|0;Ya(a,75,30030,g- -64|0);q=Ec(G[g+76>>2],a,g+7528|0,g+2160|0,d);G[d>>2]=q;a=0;W:{if(q){break W}e=G[g+7532>>2];s=G[g+7528>>2];if((s|0)>0){q=0;a=b;if((e|0)==(s|0)){break W}}a=0;if((s|0)>=0){q=0;break W}if((e|0)!=(s|0)){q=0;break W}G[g+48>>2]=b;e=g+3296|0;Ya(e,75,30038,g+48|0);q=Di(G[g+76>>2],e,g+2252|0,g+2160|0,d);G[d>>2]=q;X:{Y:{if(!q){e=G[g+2252>>2];Za(g+2256|0,e);Wa(e);q=G[d>>2]}Z:{if(q){if((q|0)!=202){break W}G[g+36>>2]=b;G[g+32>>2]=b;a=g+2160|0;Ya(a,81,30009,g+32|0);Ua(a);q=0;break Z}Vn(g+2256|0);q=0;a=H[g+2256|0];if(!a){break X}if(ad(g+2256|0)|(a|0)==47){break X}a=g+4416|0;y=d,z=io(G[g+76>>2],a,d),G[y>>2]=z;a=Uf(a,47);if(a){E[a|0]=0}if((Va(g+4416|0)+Va(g+2256|0)|0)-1024>>>0>4294966270){break Y}Ua(56553);q=125}G[d>>2]=q;a=0;break W}e=g+4416|0;a=Va(e)+e|0;E[a|0]=47;E[a+1|0]=0;a=g+2256|0;q=_d(Gb(e,a),a,d);G[d>>2]=q}if(Xa(g+2256|0,g+6496|0)){a=0;if(Xa(g+2256|0,g+5456|0)){break W}}a=b}e=b+1|0;if((b|0)!=(r|0)){continue}}break}if(!a){break S}G[g+16>>2]=a;b=g+3296|0;Ya(b,75,30030,g+16|0);y=d,z=kf(G[g+76>>2],b,d),G[y>>2]=z;G[g>>2]=a;Ya(b,75,30038,g);kf(G[g+76>>2],b,d);G[d>>2]=0;y=d,z=lh(G[g+76>>2],g+7540|0,d),G[y>>2]=z}y=d,z=xk(c,h,h>>31,1,0,d),G[y>>2]=z}a=G[g+76>>2];if(a){Qb(a,d)}b=G[d>>2]}Fa=g+7552|0;a=b;G[d>>2]=b;b=(h|0)>1;h=h-1|0;if(b){continue}break}}h=0;i=Fa-2496|0;Fa=i;G[i+2492>>2]=0;G[i+2484>>2]=0;G[i+2480>>2]=0;G[i+60>>2]=0;a=G[d>>2];if(!a){a=Fc(c,34516,i+320|0,i- -64|0,d);G[d>>2]=a;_:{if((a|0)==202){G[i+320>>2]=1296650832;G[i+324>>2]=5853761;G[d>>2]=0;break _}a=Va(i+320|0);if(H[i+320|0]!=39|H[(a+i|0)+319|0]!=39){break _}b=a-2|0;if((b|0)>0){a=i+320|0;yd(a,a|1,b)}E[b+(i+320|0)|0]=0}$:{aa:{a=Va(i+320|0)-1|0;if((a|0)<=0){break aa}while(1){if(H[(i+320|0)+h|0]!=32){break aa}h=h+1|0;if((h|0)!=(a|0)){continue}break}break $}if((a|0)==(h|0)|(a|0)<0){break $}while(1){b=(i+320|0)+a|0;if(H[b|0]!=32){break $}E[b|0]=0;b=(a|0)>0;a=a-1|0;if(b){continue}break}}a=Ec(c,33996,i+2480|0,i- -64|0,d);G[d>>2]=a;if((a|0)==202){G[i+2480>>2]=1;G[d>>2]=0}a=Fc(c,35480,i+240|0,i- -64|0,d);G[d>>2]=a;ba:{if((a|0)==202){E[i+240|0]=0;G[d>>2]=0;break ba}a=Va(i+240|0);if(H[i+240|0]!=39|H[(a+i|0)+239|0]!=39){break ba}b=a-2|0;if((b|0)>0){a=i+240|0;yd(a,a|1,b)}E[b+(i+240|0)|0]=0}h=0;ca:{da:{a=Va(i+240|0)-1|0;if((a|0)<=0){break da}while(1){if(H[(i+240|0)+h|0]!=32){break da}h=h+1|0;if((h|0)!=(a|0)){continue}break}break ca}if((a|0)==(h|0)|(a|0)<0){break ca}while(1){b=(i+240|0)+a|0;if(H[b|0]!=32){break ca}E[b|0]=0;b=(a|0)>0;a=a-1|0;if(b){continue}break}}G[i+2492>>2]=G[c>>2]+1;a=yf(c,i+1440|0,i+400|0,0,0,0,d);G[d>>2]=a;ea:{if(a){break ea}h=lh(c,i+2484|0,d);G[d>>2]=h;a=1;s=G[i+2484>>2];if((s|0)>0){while(1){if(h){break ea}e=a;j=i+60|0;k=Fa-4416|0;Fa=k;G[k+4412>>2]=0;G[k+4408>>2]=0;a=G[d>>2];fa:{if(a){break fa}G[j>>2]=0;y=d,z=lh(c,k+4412|0,d),G[y>>2]=z;ga:{a=G[k+4412>>2];ha:{if((a|0)<(e|0)){G[d>>2]=344;G[k+4>>2]=a;G[k>>2]=e;a=k+80|0;Ya(a,73,52044,k);Ua(a);a=G[d>>2];break ha}G[k+64>>2]=e;a=k+4320|0;Ya(a,75,30030,k- -64|0);a=Ec(c,a,k+4408|0,k+80|0,d);G[d>>2]=a;if(a){break ga}a=G[k+4408>>2];ia:{ja:{if((a|0)>0){a=Mj(c,j,d);G[d>>2]=a;break ja}ka:{la:{ma:{if(!a){G[d>>2]=344;G[k+20>>2]=e;G[k+16>>2]=0;Ya(k+80|0,73,52142,k+16|0);break ma}G[k+48>>2]=e;G[k+4408>>2]=0-a;a=k+4320|0;Ya(a,75,30038,k+48|0);a=Di(c,a,k+3276|0,k+80|0,d);G[d>>2]=a;if(!a){a=G[k+3276>>2];Za(k+3280|0,a);Wa(a);a=G[d>>2]}if((a|0)!=202){break la}G[d>>2]=344;G[k+32>>2]=e;Ya(k+80|0,73,52007,k+32|0)}Ua(k+80|0);break ka}a=k+3280|0;Vn(a);if(ad(a)){Ua(52277);a=Rc(j,k+3280|0,1,d);G[d>>2]=a;if(!a){break ia}Ua(52226);G[d>>2]=0;a=Rc(j,k+3280|0,0,d);G[d>>2]=a;break ja}a=k+1200|0;y=d,z=kh(k+3280|0,a,d),G[y>>2]=z;a=Rc(j,a,1,d);G[d>>2]=a;if(!a){break ia}Ua(52226);G[d>>2]=0;a=Rc(j,k+1200|0,0,d);G[d>>2]=a;if(!a){break ia}G[d>>2]=0;b=k+160|0;G[k+76>>2]=b;a=k+1200|0;G[k+72>>2]=a;y=d,z=yf(c,a,b,0,0,0,d),G[y>>2]=z;G[j>>2]=0;a=1;r=0;while(1){b=a;a=0;r=G[(k+72|0)+(r<<2)>>2];h=0;na:{if(!H[r|0]){break na}h=Dg(r,k+3280|0,k+2240|0,d);G[d>>2]=h;if(h){G[d>>2]=0;h=0;break na}if(!ad(k+2240|0)){h=k+2240|0;y=d,z=kh(h,r,d),G[y>>2]=z;Za(h,r)}h=Rc(j,k+2240|0,1,d);G[d>>2]=h;if(!h){break ka}Ua(52100);Ua(52184);G[d>>2]=0;h=Rc(j,k+2240|0,0,d);G[d>>2]=0;h=!h}r=1;if(b&!h){continue}break}}a=G[d>>2]}if(a){break ga}}a=G[j>>2];if(!a){Ua(51953);a=343;G[d>>2]=343;break ga}a=Je(a,-1,35090,G[k+4408>>2],d)?343:0;G[d>>2]=a}if(a){break ga}a=0;break fa}b=G[j>>2];if(!b){break fa}Qb(b,d);G[j>>2]=0;a=G[d>>2]}Fa=k+4416|0;G[d>>2]=a;oa:{if(a){G[d>>2]=0;G[i+48>>2]=e;a=i- -64|0;Ya(a,81,58694,i+48|0);Ua(a);break oa}G[i+2488>>2]=G[G[G[i+60>>2]+4>>2]+84>>2];if(G[i+2488>>2]!=1){G[i+32>>2]=e;a=i- -64|0;Ya(a,81,58545,i+32|0);Ua(a);break oa}G[i+2476>>2]=0;pa:{if(!H[i+1440|0]){h=G[d>>2];break pa}h=hk(G[i+60>>2],i+320|0,i+240|0,G[i+2480>>2],G[i+2492>>2],i+1440|0,i+2476|0,d);G[d>>2]=h}if(!(!H[i+400|0]|(h|0)!=342)){G[d>>2]=0;h=hk(G[i+60>>2],i+320|0,i+240|0,G[i+2480>>2],G[i+2492>>2],i+400|0,i+2476|0,d);G[d>>2]=h}if(!h){a=G[i+2476>>2];h=xk(G[i+60>>2],a,a>>31,1,0,d);G[d>>2]=h}if((h|0)==342){Ua(58641)}G[d>>2]=0;a=G[i+60>>2];if(!a){break oa}Qb(a,d);G[i+60>>2]=0}a=e+1|0;h=G[d>>2];if((e|0)!=(s|0)){continue}break}}if(h|1){break ea}G[i+2488>>2]=G[G[c+4>>2]+84>>2];if(G[i+2488>>2]){if((s|0)<=0){break ea}h=G[d>>2];a=1;while(1){if(h){break ea}G[i+16>>2]=a;b=i+160|0;Ya(b,75,30030,i+16|0);kf(c,b,d);G[i>>2]=a;Ya(b,75,30038,i);kf(c,b,d);h=G[d>>2];if((h|0)==202){G[d>>2]=0;h=0}b=(a|0)!=(s|0);a=a+1|0;if(b){continue}break}break ea}Ua(58736)}a=G[i+60>>2];if(a){Qb(a,d)}a=G[d>>2]}Fa=i+2496|0;G[d>>2]=a;y=d,z=vo(c,t+16012|0,d),G[y>>2]=z}Fa=t+16016|0}c=G[l+24>>2];if((c|0)>0){b=0;while(1){d=M(b,176);a=d+G[l+28>>2]|0;qa:{if(G[a>>2]!=2){break qa}a=G[a+80>>2];if(!a){break qa}Wa(a);G[(d+G[l+28>>2]|0)+80>>2]=0;c=G[l+24>>2]}b=b+1|0;if((c|0)>(b|0)){continue}break}}a=G[l+28>>2];if(a){Wa(a)}b=G[l+204>>2]}Fa=l+208|0;return b}function Xj(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,I=0,J=0,K=0,N=0,P=0;n=Fa-352|0;Fa=n;a:{b:{c:{d:{if((b|0)==-99){if((mi(33141,n)|0)!=269){break d}b=xf(G[n>>2])}if((c|0)==-99){break c}break b}if(!G[309737]){G[309737]=431}a=n+272|0;bb(a,136827,80);E[n+351|0]=0;Ua(a);I=-1;break a}if((mi(32826,n)|0)==269){c=xf(G[n>>2]);break b}if(!G[309737]){G[309737]=431}a=n+272|0;bb(a,136746,80);E[n+351|0]=0;Ua(a);I=-1;break a}y=Fb(260,0,b);v=Fb(260,0,c);e:{f:{g:{h:{i:{z=G[309723];if((z|0)==G[309724]){b=G[309722];j:{if(b){G[309724]=z<<1;b=ub(b,M(z,688));break j}G[309724]=100;b=ab(34400)}if(!b){break i}G[309722]=b;z=G[309723]}w=z+1|0;G[309723]=w;I=-1;if((y|v|z)<0){break a}k:{b=G[309722];c=G[(b+M(y,344)|0)+56>>2];if((c|0)==1){break k}f=G[(M(v,344)+b|0)+56>>2];if((f|0)==1){break k}l:{if(G[(M(y,344)+b|0)+52>>2]!=G[(M(v,344)+b|0)+52>>2]|(c|0)!=(f|0)){break l}e=G[(M(y,344)+b|0)+60>>2];if((e|0)!=G[(M(v,344)+b|0)+60>>2]){break l}f=1;if((e|0)<=0){break k}c=0;if(e-1>>>0>=3){o=e&-4;while(1){p=c<<2;i=p|4;m=f;f=(M(y,344)+b|0)- -64|0;l=(M(v,344)+b|0)- -64|0;m=G[f+i>>2]==G[i+l>>2]?G[p+f>>2]==G[l+p>>2]?m:0:0;i=p|8;m=G[i+f>>2]==G[i+l>>2]?m:0;i=f;f=p|12;f=G[i+f>>2]==G[f+l>>2]?m:0;c=c+4|0;j=j+4|0;if((o|0)!=(j|0)){continue}break}}e=e&3;if(e){while(1){p=f;f=c<<2;f=G[(f+(M(y,344)+b|0)|0)- -64>>2]==G[(f+(M(v,344)+b|0)|0)- -64>>2]?p:0;c=c+1|0;g=g+1|0;if((e|0)!=(g|0)){continue}break}}if(f){break k}}if(!G[309737]){G[309737]=431}a=n+272|0;bb(a,136422,80);E[n+351|0]=0;Ua(a);break a}if(G[309724]==(w|0)){G[309724]=w<<1;b=ub(b,M(w,688));if(!b){break h}G[309722]=b;w=G[309723]}G[309723]=w+1;if((w|0)<0){break e}D=M(w,344)+b|0;G[D+12>>2]=z;G[D+8>>2]=3;c=D;G[c+52>>2]=258;G[c+56>>2]=1;G[c+4>>2]=29;G[c>>2]=1033;G[c+20>>2]=v;G[c+16>>2]=y;G[c+60>>2]=1;G[c+64>>2]=1;j=M(y,344)+b|0;G[c+56>>2]=G[j+56>>2];G[c+60>>2]=G[j+60>>2];p=G[j+60>>2];m:{if((p|0)<=0){break m}f=0;c=0;if(p-1>>>0>=3){o=p&-4;g=0;while(1){l=(M(w,344)+b|0)- -64|0;e=c<<2;i=(M(y,344)+b|0)- -64|0;G[l+e>>2]=G[i+e>>2];r=e|4;G[r+l>>2]=G[i+r>>2];r=e|8;G[r+l>>2]=G[i+r>>2];e=e|12;G[e+l>>2]=G[e+i>>2];c=c+4|0;g=g+4|0;if((o|0)!=(g|0)){continue}break}}g=p&3;if(!g){break m}while(1){e=c<<2;G[(e+(M(w,344)+b|0)|0)- -64>>2]=G[(e+(M(y,344)+b|0)|0)- -64>>2];c=c+1|0;f=f+1|0;if((g|0)!=(f|0)){continue}break}}c=G[(M(v,344)+b|0)+56>>2];n:{if((c|0)<=G[j+56>>2]){break n}G[D+56>>2]=c;c=M(v,344)+b|0;G[D+60>>2]=G[c+60>>2];j=G[c+60>>2];if((j|0)<=0){break n}f=0;c=0;if(j-1>>>0>=3){i=j&-4;g=0;while(1){p=(M(w,344)+b|0)- -64|0;e=c<<2;l=(M(v,344)+b|0)- -64|0;G[p+e>>2]=G[l+e>>2];o=e|4;G[o+p>>2]=G[l+o>>2];o=e|8;G[o+p>>2]=G[l+o>>2];e=e|12;G[e+p>>2]=G[e+l>>2];c=c+4|0;g=g+4|0;if((i|0)!=(g|0)){continue}break}}g=j&3;if(!g){break n}while(1){e=c<<2;G[(e+(M(w,344)+b|0)|0)- -64>>2]=G[(e+(M(v,344)+b|0)|0)- -64>>2];c=c+1|0;f=f+1|0;if((g|0)!=(f|0)){continue}break}}c=M(z,344)+b|0;G[c>>2]=-1e3;G[c+4>>2]=0;G[n+268>>2]=0;G[n+264>>2]=0;g=H[d|0];if(g){if((g|0)!=32){f=d;break g}while(1){g=H[d+1|0];f=d+1|0;d=f;if((g|0)==32){continue}break}break g}c=Wj(M(y,344)+b|0);G[n+268>>2]=c;g=Wj(M(v,344)+b|0);G[n+264>>2]=g;if((c|g)>=0){break f}if(!G[309737]){G[309737]=431}a=n+272|0;bb(a,136665,80);E[n+351|0]=0;Ua(a);a=G[309723];if(!a){break a}G[309723]=a-1;break a}G[309737]=113;I=-1;break a}G[309737]=113;break a}c=f;o:{while(1){p:{q:{r:{d=g&255;switch(d-32|0){case 0:case 12:break p;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:break q;default:break r}}if(!d){break o}}g=H[c+1|0];c=c+1|0;continue}break}E[c|0]=0;c=c+1|0}while(1){d=H[c|0];if((d|0)!=32){if(!d){if(!G[309737]){G[309737]=431}a=n+272|0;bb(a,136503,80);E[n+351|0]=0;Ua(a);a=G[309723];if(!a){break a}G[309723]=a-1;break a}dc(G[309712],0,f,n+268|0,1238948);dc(G[309712],0,c,n+264|0,1238948);if(!G[309737]){g=G[n+264>>2];c=G[n+268>>2];break f}a=n+272|0;bb(a,136584,80);E[n+351|0]=0;Ua(a);a=G[309723];if(!a){break a}G[309723]=a-1;break a}else{c=c+1|0;continue}}}G[n+272>>2]=0;s:{if((c|0)<=0|(g|0)<=0){break s}G[n+260>>2]=0;Bn(G[309712],c,g,n+280|0,n+288|0,n+296|0,n+304|0,n+312|0,n+320|0,n+328|0,n+336|0,n+260|0);c=G[n+260>>2];if(c){if((c|0)==505){G[n+272>>2]=0;break s}G[309737]=c;a=G[309723];if(!a){break a}G[309723]=a-1;break a}G[n+272>>2]=1}c=a;a=n+272|0;x=n+256|0;e=0;F=Fa-16|0;Fa=F;G[F+8>>2]=0;if(!G[309737]){rh();t:{if(ch(F+12|0,c,0,F+8|0)){qh();o=a;m=x;t=Fa-32|0;Fa=t;u:{if(G[309737]){break u}v:{q=ab(80);if(!q){break v}G[q>>2]=0;G[q+4>>2]=0;w:{if(!(!o|!G[o>>2])){bb(q+8|0,o,72);break w}G[q+8>>2]=0}d=ab(512);if(!d){Wa(q);break v}C=ac(c,13287);if(!C){G[t>>2]=c;Ya(d,512,42961,t);Ua(d);Wa(d);Wa(q);G[309737]=104;break u}G[309737]=104;p=512;x:{y:{z:{A:{if(vc(d,512,C)){J=o- -64|0;while(1){G[309737]=0;a=d;f=Va(a);c=p;B:{if((f|0)!=(c-1|0)){break B}while(1){if(H[(a+f|0)-1|0]==10){p=c;d=a;break B}p=c<<1;d=ub(a,p);if(!d){x=113;c=42507;d=a;break z}g=d+f|0;vc(g,c+1|0,C);a=d;f=Va(g)+f|0;c=p;if((f|0)==(c-1|0)){continue}break}}f=d;C:{if(H[f|0]==35){while(1){a=f;f=a+1|0;c=E[a+1|0];if((c|0)==32|c-9>>>0<5){continue}break}if(gc(f,36648,7)){break C}x=431;if(G[q>>2]){c=42785;break z}a=a+8|0;while(1){c=a;a=c+1|0;f=E[c|0];if((f|0)==32|f-9>>>0<5){continue}break}if(!gc(c,16895,5)){e=0;break C}if(!gc(c,25131,6)){e=1;break C}e=2;if(!gc(c,5783,6)){break C}if(!gc(c,6871,3)){break C}c=43851;break z}if(!gc(d,30820,4)|!H[d|0]){break C}while(1){a=f;g=0;i=1;j=e;while(1){x=431;if(G[309737]){c=22021;break z}c=E[f|0];if(!c){c=22021;break z}D:{E:{F:{G:{H:{switch(c-10|0){default:if((c|0)!=100){break G}j=g?1:j;break G;case 30:c=0;E[f|0]=0;f=f+1|0;if(!g){g=f;break E}G[309737]=1;break E;case 31:E[f|0]=0;f=f+1|0;if(g){break D}G[309737]=1;g=0;break F;case 0:case 25:E[f|0]=0;c=!g;break E;case 48:j=g?2:j;break G;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 26:case 27:case 28:case 29:case 32:case 33:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:break G;case 34:break H}}i=i+1|0}f=f+1|0}c=0}if(!c){continue}}break}if(G[309737]){c=22021;break z}while(1){c=a;a=c+1|0;e=E[c|0];if((e|0)==32|e-9>>>0<5){continue}break}I:{if(!(e|g)){e=j;break I}J:{K:{if(!gc(c,36333,6)){c=c+6|0;j=0;break K}if(!gc(c,36323,9)){c=c+9|0;j=0;break K}if(!gc(c,36315,7)){c=c+7|0;j=0;break K}L:{if(!gc(c,36380,4)){break L}if(!gc(c,36375,4)){break L}if(!gc(c,36309,5)){c=c+5|0;j=1;break K}e=1;if(!gc(c,40249,3)){break I}if(!gc(c,40333,3)){break I}if(!gc(c,6487,4)){break I}e=0;if(!gc(c,25125,5)){break I}if(!gc(c,16977,8)){break I}if(!gc(c,36350,9)){f=28258;break J}if(gc(c,36340,9)){break K}f=28216;break J}c=c+4|0;j=1}e=j;a=G[q+4>>2];r=G[q>>2];if(!((r|0)%10|0)){M:{if(a){a=ub(a,M(r,168)+1680|0);break M}a=ab(1680)}if(!a){x=113;c=30900;break z}G[q+4>>2]=a;r=G[q>>2]}G[q>>2]=r+1;k=M(r,168)+a|0;a=k;G[a+48>>2]=0;G[a+52>>2]=0;G[a+4>>2]=0;E[a|0]=1;G[a+56>>2]=0;G[a+60>>2]=0;a=a- -64|0;G[a>>2]=0;G[a+4>>2]=0;G[k+72>>2]=0;G[k+76>>2]=0;G[k+80>>2]=0;G[k+84>>2]=0;G[k+88>>2]=0;G[k+92>>2]=0;G[k+96>>2]=0;G[k+100>>2]=0;G[k+104>>2]=0;G[k+108>>2]=0;G[k+136>>2]=0;G[k+140>>2]=0;G[k+144>>2]=0;G[k+148>>2]=0;G[k+152>>2]=0;G[k+156>>2]=0;G[k+160>>2]=0;G[k+164>>2]=0;l=k+48|0;while(1){a=c;c=c+1|0;j=E[a|0];if((j|0)==32|j-9>>>0<5){continue}break}N:{switch((j&255)-43|0){case 2:E[k|0]=0;case 0:a=c;break;default:break N}}while(1){c=a;a=c+1|0;j=E[c|0];if((j|0)==32|j-9>>>0<5){continue}break}if(!j){c=22021;break z}a=Va(c)-1|0;r=c+a|0;j=E[r|0];if((j|0)==32|j-9>>>0<5){while(1){E[r|0]=0;a=a-1|0;r=c+a|0;j=E[r|0];if((j|0)==32|j-9>>>0<5){continue}break}}O:{P:{Q:{R:{S:{T:{U:{if(!Ib(c,22631)){h=2;G[k+4>>2]=2;if((i|0)!=3){break U}break R}if(!Ib(c,5443)){G[k+4>>2]=3;h=2;if((i|0)!=4){break U}break R}if(!Ib(c,20708)){if(i-9>>>0<4294967291){break U}if(i>>>0<=5){G[k+4>>2]=4;G[l+32>>2]=0;G[l+36>>2]=0;break S}G[k+4>>2]=5;G[l+56>>2]=0;G[l+60>>2]=0;G[l+48>>2]=0;G[l+52>>2]=0;break S}if(!Ib(c,5437)){G[k+4>>2]=5;V:{switch(i-6|0){default:G[309737]=431;break;case 0:case 2:break V}}G[l+48>>2]=0;G[l+52>>2]=0;G[l+56>>2]=0;G[l+60>>2]=0;break S}W:{if(Ib(c,3720)){if(Ib(c,3717)){break W}}if(i-9>>>0<4294967291){break U}if(i>>>0<=5){G[k+4>>2]=6;G[l+32>>2]=0;G[l+36>>2]=0;break S}G[k+4>>2]=7;G[l+56>>2]=0;G[l+60>>2]=0;G[l+48>>2]=0;G[l+52>>2]=0;break S}X:{if(Ib(c,22621)){if(Ib(c,22618)){break X}}G[k+4>>2]=8;if(i-6>>>0<=4294967293){G[309737]=431}G[l+32>>2]=0;G[l+36>>2]=0;h=4;break R}Y:{Z:{if(!Ib(c,26591)){break Z}if(!Ib(c,26588)){break Z}if(!Ib(c,5463)){break Z}if(Ib(c,5460)){break Y}}G[k+4>>2]=9;if(i-6>>>0<=4294967293){G[309737]=431}G[l+32>>2]=0;G[l+36>>2]=0;break S}_:{if(Ib(c,10502)){if(Ib(c,23667)){break _}}G[k+4>>2]=10;h=2;if((i|0)!=4){break U}break R}if(!Ib(c,4710)){G[k+4>>2]=0;h=2;if((i|0)!=2){break U}break R}if(!Ib(c,21330)){G[k+4>>2]=1;h=4;if((i|0)!=4){break U}break R}if(!Ib(c,15727)){G[k+4>>2]=11;if(i&1|(i|0)<6){break U}if(G[309737]){break Q}a=ab(i<<3);G[l+4>>2]=a;if(a){break P}x=113;c=6073;break z}if(Ib(c,31649)){break T}G[k+4>>2]=12;h=2;if((i|0)==8){break R}}G[309737]=431;break Q}$:{aa:{if(!Ib(c,31634)){G[k+4>>2]=13;if(i-12>>>0<=4294967293){break aa}break $}if(Ib(c,31648)){f=38036;break J}G[k+4>>2]=14;if(i-12>>>0>4294967293){break $}}G[309737]=431}G[l+80>>2]=0;G[l+84>>2]=0}h=2}if(!G[309737]){break O}}Ua(15597);Ua(c);break A}G[l>>2]=i;h=i;l=a}j=0;while(1){a=g;while(1){c=a;a=c+1|0;if(H[c|0]!=44){continue}break}E[c|0]=0;r=a;while(1){c=H[r|0];if(!(!c|(c|0)==44)){r=r+1|0;continue}break}E[r|0]=0;ba:{ca:{if(jb(g,58)){s=0;c=0;e=nc(g,t+28|0,10);g=G[t+28>>2];da:{if(!g|H[g|0]!=58){break da}c=nc(g+1|0,t+28|0,10);g=G[t+28>>2];if(!g|H[g|0]!=58){break da}s=sb(g+1|0)}s=s/3600+(+(c|0)/60+ +(e|0));while(1){c=a;a=c+1|0;g=E[c|0];if((g|0)==32|g-9>>>0<5){continue}break}u=0;a=0;c=nc(c+((g|0)==45)|0,t+28|0,10);e=G[t+28>>2];ea:{if(!e|H[e|0]!=58){break ea}a=nc(e+1|0,t+28|0,10);e=G[t+28>>2];if(!e|H[e|0]!=58){break ea}u=sb(e+1|0)}s=s*15;u=(g|0)==45?+(0-c|0)+ +(a|0)/-60+u/-3600:u/3600+(+(a|0)/60+ +(c|0));A=j?A:u;B=j?B:s;e=2;break ca}s=sb(g);B=j?B:s;u=sb(a);A=j?A:u;if(e){break ca}e=0;break ba}x=505;c=42685;if(!o|!G[o>>2]){break z}if(ri(s,u,L[o+8>>3],L[o+16>>3],L[o+24>>3],L[o+32>>3],L[o+40>>3],L[o+48>>3],L[o+56>>3],J,t+16|0,t+8|0)){Ua(42739);break A}u=L[t+8>>3];s=L[t+16>>3]}g=r+1|0;a=j<<3;L[a+l>>3]=s;L[(a|8)+l>>3]=u;j=j+2|0;if((h|0)>(j|0)){continue}break}if((i|0)>(j|0)){while(1){a=g;while(1){c=H[a|0];if(!(!c|(c|0)==44)){a=a+1|0;continue}break}E[a|0]=0;r=(j<<3)+l|0;u=vb(g,t+28|0);L[r>>3]=u;c=G[t+28>>2];fa:{if(!c){break fa}ga:{ha:{c=H[c|0];switch(c-34|0){case 1:case 2:case 3:case 4:break fa;case 0:case 5:break ga;default:break ha}}if((c|0)!=100){break fa}}u=u/((c|0)==39?60:(c|0)==34?3600:1);if(ri(B,A+(A<0?u:-u),L[o+8>>3],L[o+16>>3],L[o+24>>3],L[o+32>>3],L[o+40>>3],L[o+48>>3],L[o+56>>3],J,t+16|0,t+8|0)){Ua(42739);break A}u=L[t+16>>3]-L[l>>3];s=u*u;u=L[t+8>>3]-L[l+8>>3];L[r>>3]=V(s+u*u)}g=a+1|0;j=j+1|0;if((i|0)!=(j|0)){continue}break}}a=G[k+4>>2];ia:{ja:{if((a|0)!=5){if((a|0)!=7){break ia}if((i|0)==7){break ja}break ia}if((i|0)!=7){break ia}}L[l+56>>3]=L[l+48>>3]}ka:{if(!e){break ka}c=4;x=3;r=2;la:{ma:{na:{switch(a-4|0){case 1:case 3:x=7;r=6;break ma;case 0:case 2:case 4:case 5:break la;case 6:case 8:break ma;case 9:case 10:break na;default:break ka}}L[l+16>>3]=L[o+56>>3]+L[l+16>>3];x=10;r=3}a=(r<<3)+l|0;L[a>>3]=L[o+56>>3]+L[a>>3];c=x}a=(c<<3)+l|0;L[a>>3]=L[o+56>>3]+L[a>>3]}yn(k);if(H[f|0]){continue}break C}Ua(f);break z}if(H[f|0]){continue}break}}if(vc(d,p,C)){continue}break}}c=0;g=G[q>>2];oa:{if((g|0)<=0){break oa}while(1){a=c;e=G[q+4>>2];pa:{if(H[e+M(c,168)|0]){break pa}while(1){f=a;if((a|0)<2){break pa}a=f-1|0;if(!H[e+M(a,168)|0]){continue}break}g=f-2|0;while(1){a=G[q+4>>2];if(H[a+M(g,168)|0]){f=ub(a,M(G[q>>2],168)+168|0);G[q+4>>2]=f;a=G[q>>2];G[q>>2]=a+1;e=g+1|0;if((e|0)<(a|0)){while(1){f=G[q+4>>2]+M(a,168)|0;bb(f,f-168|0,168);a=a-1|0;if((e|0)<(a|0)){continue}break}f=G[q+4>>2]}c=c+1|0;bb(M(e,168)+f|0,M(c,168)+f|0,168)}a=(g|0)>0;g=g-1|0;if(a){continue}break}g=G[q>>2]}c=c+1|0;if((g|0)>(c|0)){continue}break}if((g|0)<=0){break oa}e=G[q+4>>2];f=0;a=0;if((g|0)!=1){j=g&-2;c=0;while(1){p=e+M(a,168)|0;f=(H[p|0]!=0)+f|0;G[p+8>>2]=f;p=e+M(a|1,168)|0;f=f+(H[p|0]!=0)|0;G[p+8>>2]=f;a=a+2|0;c=c+2|0;if((j|0)!=(c|0)){continue}break}}if(!(g&1)){break oa}a=e+M(a,168)|0;G[a+8>>2]=(H[a|0]!=0)+f}}if(G[309737]){break y}G[m>>2]=q;break x}Ua(c);G[309737]=x}qi(q)}Hb(C);Wa(d);break u}Ua(42507);G[309737]=113}Fa=t+32|0;break t}k=G[F+12>>2];i=a;a=Fa-624|0;Fa=a;h=bb(a,123296,426);qa:{if(G[309737]){break qa}q=ab(80);if(!q){Ua(42507);G[309737]=113;break qa}G[q>>2]=0;G[q+4>>2]=0;ra:{if(!(!i|!G[i>>2])){bb(q+8|0,i,72);break ra}G[q+8>>2]=0}G[h+580>>2]=0;c=h+592|0;a=h+580|0;dc(k,0,h,c,a);d=h+71|0;f=c|4;dc(k,0,d,f,a);g=h+142|0;j=c|8;dc(k,0,g,j,a);p=h+213|0;l=c|12;dc(k,0,p,l,a);o=h+284|0;r=h+608|0;dc(k,0,o,r,a);sa:{ta:{ua:{va:{if(G[h+580>>2]){c=43172;if(Je(k,2,34525,1,1238948)){break va}}c=44284;if(Cb(k,31,40853,q,h+432|0,1238948)){break va}a=ab(M(G[q>>2],168));G[q+4>>2]=a;if(!a){a=30900;break ta}c=43299;if(dc(k,0,h,h+592|0,1238948)){break va}if(dc(k,0,d,f,1238948)){break va}if(dc(k,0,g,j,1238948)){break va}if(dc(k,0,p,l,1238948)){break va}if(dc(k,0,o,r,1238948)){break va}K=dc(k,0,h+355|0,h+612|0,1238948);r=1;wa:{if(!G[q+8>>2]){break wa}e=ab(72);if(!e){a=30942;break ta}G[e>>2]=1;a=e- -64|0;if(Bn(k,G[h+592>>2],G[h+596>>2],e+8|0,e+16|0,e+24|0,e+32|0,e+40|0,e+48|0,e+56|0,a,1238948)){G[e>>2]=0;G[309737]=0;break wa}if(!G[e>>2]|!G[i>>2]){break wa}xa:{if(O(L[e+8>>3]-L[i+8>>3])>1e-6|O(L[e+16>>3]-L[i+16>>3])>1e-6|(O(L[e+24>>3]-L[i+24>>3])>1e-6|O(L[e+32>>3]-L[i+32>>3])>1e-6)){break xa}if(O(L[e+40>>3]-L[i+40>>3])>1e-6|O(L[e+48>>3]-L[i+48>>3])>1e-6|O(L[e+56>>3]-L[i+56>>3])>1e-6){break xa}if(Xa(a,i- -64|0)){break wa}}r=0}c=43261;if(Zf(k,G[h+592>>2],1,h+588|0,h+544|0,1238948)){break va}if(Zf(k,G[h+596>>2],1,h+588|0,h+544|4,1238948)){break va}if(Zf(k,G[h+600>>2],1,h+588|0,h+544|8,1238948)){break va}if(Zf(k,G[h+604>>2],1,h+588|0,h+544|12,1238948)){break va}if(Zf(k,G[h+608>>2],1,h+588|0,h+560|0,1238948)){break va}if(Zf(k,G[h+612>>2],1,h+588|0,h+564|0,1238948)){break va}N=h,P=ab(72),G[N+508>>2]=P;if(G[q>>2]<=0){break ua}C=i- -64|0;J=e- -64|0;t=1;g=0;while(1){m=G[q+4>>2]+M(t-1|0,168)|0;a=m;G[a+48>>2]=0;G[a+52>>2]=0;G[a+104>>2]=0;G[a+108>>2]=0;G[a+96>>2]=0;G[a+100>>2]=0;G[a+88>>2]=0;G[a+92>>2]=0;G[a+80>>2]=0;G[a+84>>2]=0;G[a+72>>2]=0;G[a+76>>2]=0;a=a- -64|0;G[a>>2]=0;G[a+4>>2]=0;G[m+56>>2]=0;G[m+60>>2]=0;G[m+136>>2]=0;G[m+140>>2]=0;G[m+144>>2]=0;G[m+148>>2]=0;G[m+152>>2]=0;G[m+156>>2]=0;G[m+160>>2]=0;G[m+164>>2]=0;if(Df(k,G[h+600>>2],t,g,68332,h+508|0,h+584|0,1238948)){c=43829;break va}E[m|0]=1;c=G[h+508>>2];if(H[c|0]==33){E[m|0]=0;c=c+1|0}if(!Xa(c,123728)){G[m+4>>2]=0}if(!Xa(c,123799)){G[m+4>>2]=2}if(!Xa(c,123870)){G[m+4>>2]=4}if(!Xa(c,123941)){G[m+4>>2]=3}if(!Xa(c,124012)){G[m+4>>2]=5}if(!Xa(c,124083)){G[m+4>>2]=6}if(!Xa(c,124154)){G[m+4>>2]=6}if(!Xa(c,124225)){G[m+4>>2]=7}if(!Xa(c,124296)){G[m+4>>2]=8}if(!Xa(c,124367)){G[m+4>>2]=8}if(!Xa(c,124438)){G[m+4>>2]=11}if(!Xa(c,124509)){G[m+4>>2]=10}if(!Xa(c,124580)){G[m+4>>2]=10}if(!Xa(c,124651)){G[m+4>>2]=9}if(!Xa(c,124722)){G[m+4>>2]=9}if(!Xa(c,124793)){G[m+4>>2]=9}o=m+48|0;ya:{za:{Aa:{if(!Xa(c,124864)){G[m+4>>2]=9;j=1;break Aa}a=G[m+4>>2];if((a|0)==11){a=lb(G[h+544>>2]<<1,8);G[o+4>>2]=a;if(!a){a=6073;break ta}j=G[h+544>>2];G[o>>2]=j<<1;if((j|0)>0){break za}c=a;break ya}j=(a|0)==8?2:1}a=o}p=0;d=0;while(1){l=d;f=p;c=f+1|0;d=c?l:l+1|0;p=c;c=a;if(Hf(k,G[h+592>>2],t,g,p,d,1,0,-91191291391491e-49,c,h+584|0,1238948)){Ua(15684);break ua}Ba:{Ca:{if(L[c>>3]==-91191291391491e-49){break Ca}if(Hf(k,G[h+596>>2],t,g,p,d,1,0,-91191291391491e-49,c+8|0,h+584|0,1238948)){Ua(15641);break ua}s=L[c+8>>3];if(s==-91191291391491e-49){break Ca}a=c+16|0;B=L[c>>3];if(!(f|l)){u=B;A=s;break Ba}if(u!=B|s!=A){break Ba}f=p;c=a}j=f;G[o>>2]=f<<1;break ya}if((j|0)!=(p|0)|d){continue}break}c=a}Da:{if(r){break Da}a=0;d=c-(j<<4)|0;A=L[d+8>>3];u=L[d>>3];if((j|0)<=0){break Da}while(1){Ea:{f=d+(a<<4)|0;p=f+8|0;zn(L[f>>3],L[p>>3],L[e+8>>3],L[e+16>>3],L[e+24>>3],L[e+32>>3],L[e+40>>3],L[e+48>>3],L[e+56>>3],J,h+520|0,h+512|0);ri(L[h+520>>3],L[h+512>>3],L[i+8>>3],L[i+16>>3],L[i+24>>3],L[i+32>>3],L[i+40>>3],L[i+48>>3],L[i+56>>3],C,f,p);if(G[309737]){break Ea}a=a+1|0;if((j|0)!=(a|0)){continue}break Da}break}Ua(7470);break ua}a=G[m+4>>2];d=a-2|0;if(!(d>>>0>8|!(447>>>d&1))){d=G[(d<<2)+124936>>2];if(Hf(k,G[h+604>>2],t,g,1,0,d,0,0,c,h+584|0,1238948)){Ua(15522);break ua}Fa:{if(!r){a=0;while(1){s=L[c>>3];L[h+536>>3]=u;s=A+s;L[h+528>>3]=s;zn(u,s,L[e+8>>3],L[e+16>>3],L[e+24>>3],L[e+32>>3],L[e+40>>3],L[e+48>>3],L[e+56>>3],J,h+520|0,h+512|0);ri(L[h+520>>3],L[h+512>>3],L[i+8>>3],L[i+16>>3],L[i+24>>3],L[i+32>>3],L[i+40>>3],L[i+48>>3],L[i+56>>3],C,h+536|0,h+528|0);if(G[309737]){Ua(7470);break ua}s=L[h+536>>3]-L[o>>3];B=s*s;s=L[h+528>>3]-L[o+8>>3];L[c>>3]=V(B+s*s);c=c+8|0;a=a+1|0;if((d|0)!=(a|0)){continue}break}break Fa}c=(d<<3)+c|0}a=G[m+4>>2]}a=a-4|0;Ga:{if(a>>>0>6|!(111>>>a&1)){break Ga}d=G[(a<<2)+124972>>2];if(Hf(k,G[h+608>>2],t,g,1,0,d,0,0,c,h+584|0,1238948)){Ua(15557);break ua}if(r){break Ga}s=L[i+56>>3]-L[e+56>>3];if(d-1>>>0>=3){f=d&-4;a=0;while(1){L[c>>3]=s+L[c>>3];L[c+8>>3]=s+L[c+8>>3];L[c+16>>3]=s+L[c+16>>3];L[c+24>>3]=s+L[c+24>>3];c=c+32|0;a=a+4|0;if((f|0)!=(a|0)){continue}break}}d=d&3;a=0;while(1){L[c>>3]=s+L[c>>3];c=c+8|0;a=a+1|0;if((d|0)!=(a|0)){continue}break}}Ha:{if(!K){if(!bg(k,31,G[h+612>>2],t,g,1,0,1,0,0,m+8|0,h+584|0,1238948)){break Ha}Ua(15479);break ua}G[m+8>>2]=1}yn(m);a=G[q>>2];c=a>>>0>t>>>0;a=a>>31;a=c&(a|0)>=(g|0)|(a|0)>(g|0);c=t+1|0;g=c?g:g+1|0;t=c;if(a){continue}break}break ua}Ua(c)}if(G[309737]){qi(q);break sa}G[x>>2]=q;break sa}Ua(a);G[309737]=113;qi(q)}Qb(k,1238948)}Fa=h+624|0}}Fa=F+16|0;if(G[309737]){a=G[309723];if(!a){break a}G[309723]=a-1;break a}G[(M(z,344)+b|0)+88>>2]=G[n+256>>2];a=G[309722];if(G[a+M(y,344)>>2]!=-1e3|G[a+M(v,344)>>2]!=-1e3){break e}Ja[G[D+4>>2]](D)}I=w}Fa=n+352|0;return I}function Se(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){var q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,K=0,N=0,P=0,R=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0;t=Fa-29104|0;Fa=t;r=G[p>>2];a:{if(!(g|h)|(r|0)>0){break a}if(o){G[o>>2]=0}if((j|0)==2){cb(n,0,g)}if((yc(a,b,c,d,e,f,g,h,i>>31,t+29096|0,t+29088|0,t+28992|0,t+29064|0,t+29084|0,t+29080|0,t+29040|0,t+29032|0,t+29060|0,t+29048|0,t+29016|0,t+29076|0,t+29024|0,t+28864|0,p)|0)>0){r=G[p>>2];break a}G[t+29060>>2]=M(G[t+29060>>2],i);R=1;c=G[t+29080>>2];_=c;$=c>>31;b:{if(G[t+29084>>2]!=16){break b}Gd(t+28992|0,t+29072|0,t+29056|0,t+29068|0,p);d=G[t+29068>>2];if((d|0)<=0){break b}if(d-1>>>0>=7){c=d&-8;while(1){R=R*10*10*10*10*10*10*10*10;D=D+8|0;if((c|0)!=(D|0)){continue}break}}c=d&7;if(!c){break b}D=0;while(1){R=R*10;D=D+1|0;if((c|0)!=(D|0)){continue}break}}D=0;f=G[t+29084>>2];c:{d:{if(!(k|l)&(j|0)==1){break d}e=G[t+29028>>2];c=G[t+29024>>2];if(!e&(c|0)==1234554321&((f|0)%10|0)==1){break d}if(!((e-(c>>>0<32768)|0)==-1&c-32768>>>0>=4294901760|(f|0)!=21)){W=0;break c}W=0;if(!(!e&c>>>0<=255|(f|0)!=11)){break c}D=(f|0)==16?H[t+28864|0]==1?0:j:j}W=0;if((f|0)!=81){break c}c=g>>>0<268435455&(h|0)<=0|(h|0)<0;_=c?g:268435455;$=c?h:0;W=!D&L[t+29096>>3]==1&L[t+29088>>3]==0}ba=0-i|0;e=0;f=0;e:{while(1){c=g>>>0<_>>>0&(h|0)<=($|0)|(h|0)<($|0)?g:_;j=c;c=c>>31;B=j;A=c;f:{if((i|0)>=0){d=G[t+29036>>2];z=d;d=G[t+29052>>2]+(d^-1)|0;u=G[t+29032>>2];c=u^-1;j=c+G[t+29048>>2]|0;r=Bu(j,c>>>0>j>>>0?d+1|0:d,i,0);c=Ia;break f}u=G[t+29032>>2];z=G[t+29036>>2];r=Bu(u,z,ba,0);c=Ia}j=G[t+29044>>2];v=G[t+29040>>2];d=Au(G[t+29016>>2],G[t+29020>>2],X,V);q=v+d|0;v=Ia+j|0;v=d>>>0>q>>>0?v+1|0:v;j=z;z=G[t+29060>>2];d=(z|0)/(i|0)|0;d=Au(u,j,d,d>>31);q=d+q|0;j=Ia+v|0;j=d>>>0>q>>>0?j+1|0:j;x=q;v=r+1|0;c=r>>>0>>0&(c|0)<=(A|0)|(c|0)<(A|0);u=c?v:B;g:{h:{i:{j:{k:{l:{m:{n:{o:{c=G[t+29084>>2];switch(c-11|0){case 30:break h;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break i;case 5:break j;case 31:break l;case 10:break m;case 0:break n;default:break o}}p:{switch(c-81|0){case 1:break k;case 0:break p;default:break i}}y=(e<<3)+m|0;Tc(a,x,j,u,z,y,p);if(W){break g}q=G[t+29024>>2];x=G[t+29028>>2];z=e+n|0;K=L[t+29096>>3];N=L[t+29088>>3];c=K==1&N==0x8000000000000000;q:{r:{if(!D){s:{t:{if(c){if((u|0)<=0){break q}w=0;if((u|0)!=1){r=u&-2;B=0;while(1){j=w<<3;d=j+y|0;c=G[d+4>>2];d=G[d>>2];u:{if((c|0)>0|(c|0)>=0){G[p>>2]=-11;d=-1;v=2147483647;break u}v=c^-2147483648}c=j+y|0;G[c>>2]=d;G[c+4>>2]=v;j=(w|1)<<3;d=j+y|0;c=G[d+4>>2];d=G[d>>2];v=c^-2147483648;v:{if((c|0)<0){break v}G[p>>2]=-11;d=-1;v=2147483647}c=j+y|0;G[c>>2]=d;G[c+4>>2]=v;w=w+2|0;B=B+2|0;if((r|0)!=(B|0)){continue}break}}if(!(u&1)){break q}d=y+(w<<3)|0;c=G[d+4>>2];d=G[d>>2];if((c|0)>0|(c|0)>=0){break t}j=c^-2147483648;break s}if(K==1&N==0){break r}w=0;if((u|0)<=0){break q}while(1){w:{x:{d=w<<3;c=d+y|0;s=(+J[c>>2]+ +G[c+4>>2]*4294967296)*K+N;if(s<-0x8000000000000000){G[p>>2]=-11;break x}if(s>0x8000000000000000){G[p>>2]=-11;r=-1;j=2147483647;break w}if(!(O(s)<0x8000000000000000)){break x}r=~~s>>>0;j=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;break w}r=0;j=-2147483648}c=d+y|0;G[c>>2]=r;G[c+4>>2]=j;w=w+1|0;if((u|0)!=(w|0)){continue}break}break q}G[p>>2]=-11;d=-1;j=2147483647}c=y+(w<<3)|0;G[c>>2]=d;G[c+4>>2]=j;break q}if(c){if((u|0)<=0){break q}w=0;while(1){r=w<<3;c=r+y|0;d=G[c>>2];j=G[c+4>>2];y:{if((d|0)==(q|0)&(j|0)==(x|0)){G[o>>2]=1;if((D|0)==1){c=r+y|0;G[c>>2]=k;G[c+4>>2]=l;break y}E[w+z|0]=1;break y}if((j|0)>0|(j|0)>=0){G[p>>2]=-11;c=r+y|0;G[c>>2]=-1;G[c+4>>2]=2147483647;break y}c=r+y|0;G[c>>2]=d;G[c+4>>2]=j^-2147483648}w=w+1|0;if((u|0)!=(w|0)){continue}break}break q}if(!(K==1&N==0)){if((u|0)<=0){break q}w=0;while(1){j=w<<3;c=j+y|0;d=G[c>>2];c=G[c+4>>2];z:{if((d|0)==(q|0)&(c|0)==(x|0)){G[o>>2]=1;if((D|0)==1){c=j+y|0;G[c>>2]=k;G[c+4>>2]=l;break z}E[w+z|0]=1;break z}s=(+(d>>>0)+ +(c|0)*4294967296)*K+N;if(s<-0x8000000000000000){G[p>>2]=-11;c=j+y|0;G[c>>2]=0;G[c+4>>2]=-2147483648;break z}if(s>0x8000000000000000){G[p>>2]=-11;c=j+y|0;G[c>>2]=-1;G[c+4>>2]=2147483647;break z}j=j+y|0;A:{if(O(s)<0x8000000000000000){d=~~s>>>0;c=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;break A}d=0;c=-2147483648}G[j>>2]=d;G[j+4>>2]=c}w=w+1|0;if((u|0)!=(w|0)){continue}break}break q}if((u|0)<=0){break q}if((D|0)!=1){w=0;if((u|0)!=1){A=u&-2;B=0;while(1){r=w<<3;c=r+y|0;j=G[c>>2];d=G[c+4>>2];B:{if((j|0)==(q|0)&(d|0)==(x|0)){G[o>>2]=1;E[w+z|0]=1;break B}c=r+y|0;G[c>>2]=j;G[c+4>>2]=d}v=w|1;r=v<<3;c=r+y|0;j=G[c>>2];d=G[c+4>>2];C:{if((j|0)!=(q|0)|(d|0)!=(x|0)){c=r+y|0;G[c>>2]=j;G[c+4>>2]=d;break C}G[o>>2]=1;E[v+z|0]=1}w=w+2|0;B=B+2|0;if((A|0)!=(B|0)){continue}break}}if(!(u&1)){break q}r=w<<3;c=r+y|0;j=G[c>>2];d=G[c+4>>2];if((j|0)!=(q|0)|(d|0)!=(x|0)){c=r+y|0;G[c>>2]=j;G[c+4>>2]=d;break q}G[o>>2]=1;E[w+z|0]=1;break q}w=0;if((u|0)!=1){r=u&-2;B=0;while(1){j=w<<3;d=j+y|0;c=G[d>>2];d=G[d+4>>2];if((c|0)==(q|0)&(d|0)==(x|0)){G[o>>2]=1;d=l;c=k}j=j+y|0;G[j>>2]=c;G[j+4>>2]=d;j=(w|1)<<3;d=j+y|0;c=G[d>>2];d=G[d+4>>2];if((c|0)==(q|0)&(d|0)==(x|0)){G[o>>2]=1;d=l;c=k}j=j+y|0;G[j>>2]=c;G[j+4>>2]=d;w=w+2|0;B=B+2|0;if((r|0)!=(B|0)){continue}break}}if(!(u&1)){break q}j=w<<3;d=j+y|0;c=G[d>>2];d=G[d+4>>2];if((c|0)==(q|0)&(d|0)==(x|0)){G[o>>2]=1;d=l;c=k}j=j+y|0;G[j>>2]=c;G[j+4>>2]=d;break q}if((u|0)<=0){break q}v=0;w=0;if(u-1>>>0>=3){r=u&-4;z=0;while(1){A=w<<3;j=A+y|0;d=y+A|0;c=G[d+4>>2];G[j>>2]=G[d>>2];G[j+4>>2]=c;c=A|8;j=c+y|0;d=c+y|0;c=G[d+4>>2];G[j>>2]=G[d>>2];G[j+4>>2]=c;c=A|16;j=c+y|0;d=c+y|0;c=G[d+4>>2];G[j>>2]=G[d>>2];G[j+4>>2]=c;c=A|24;j=c+y|0;d=c+y|0;c=G[d+4>>2];G[j>>2]=G[d>>2];G[j+4>>2]=c;w=w+4|0;z=z+4|0;if((r|0)!=(z|0)){continue}break}}r=u&3;if(!r){break q}while(1){c=w<<3;j=c+y|0;d=c+y|0;c=G[d+4>>2];G[j>>2]=G[d>>2];G[j+4>>2]=c;w=w+1|0;v=v+1|0;if((r|0)!=(v|0)){continue}break}}break g}B=t- -64|0;$d(a,x,j,u,z,B,p);z=H[t+29024|0];c=k;d=l;A=e+n|0;x=(e<<3)+m|0;K=L[t+29096>>3];N=L[t+29088>>3];j=K==1&N==0;D:{E:{if(!D){if(j){break E}q=0;if((u|0)<=0){break D}while(1){c=x+(q<<3)|0;F:{G:{s=+H[q+B|0]*K+N;if(s<-0x8000000000000000){G[p>>2]=-11;break G}if(s>0x8000000000000000){G[p>>2]=-11;j=-1;d=2147483647;break F}if(!(O(s)<0x8000000000000000)){break G}j=~~s>>>0;d=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;break F}j=0;d=-2147483648}G[c>>2]=j;G[c+4>>2]=d;q=q+1|0;if((u|0)!=(q|0)){continue}break}break D}if(!j){if((u|0)<=0){break D}q=0;while(1){j=H[q+B|0];H:{if((j|0)==(z|0)){G[o>>2]=1;if((D|0)==1){j=x+(q<<3)|0;G[j>>2]=c;G[j+4>>2]=d;break H}E[q+A|0]=1;break H}s=+(j>>>0)*K+N;if(s<-0x8000000000000000){G[p>>2]=-11;j=x+(q<<3)|0;G[j>>2]=0;G[j+4>>2]=-2147483648;break H}if(s>0x8000000000000000){G[p>>2]=-11;j=x+(q<<3)|0;G[j>>2]=-1;G[j+4>>2]=2147483647;break H}v=x+(q<<3)|0;I:{if(O(s)<0x8000000000000000){r=~~s>>>0;j=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;break I}r=0;j=-2147483648}G[v>>2]=r;G[v+4>>2]=j}q=q+1|0;if((u|0)!=(q|0)){continue}break}break D}if((u|0)<=0){break D}if((D|0)!=1){q=0;if((u|0)!=1){j=u&-2;w=0;while(1){d=H[q+B|0];J:{if((d|0)==(z|0)){G[o>>2]=1;E[q+A|0]=1;break J}c=x+(q<<3)|0;G[c>>2]=d;G[c+4>>2]=0}c=q|1;d=H[c+B|0];K:{if((d|0)!=(z|0)){c=x+(c<<3)|0;G[c>>2]=d;G[c+4>>2]=0;break K}G[o>>2]=1;E[c+A|0]=1}q=q+2|0;w=w+2|0;if((j|0)!=(w|0)){continue}break}}if(!(u&1)){break D}d=H[q+B|0];if((d|0)!=(z|0)){c=x+(q<<3)|0;G[c>>2]=d;G[c+4>>2]=0;break D}G[o>>2]=1;E[q+A|0]=1;break D}q=0;if((u|0)!=1){A=u&-2;w=0;while(1){v=x+(q<<3)|0;j=H[q+B|0];if((j|0)!=(z|0)){r=0}else{G[o>>2]=1;j=c;r=d}G[v>>2]=j;G[v+4>>2]=r;v=q|1;j=H[v+B|0];if((j|0)!=(z|0)){r=0}else{G[o>>2]=1;j=c;r=d}v=x+(v<<3)|0;G[v>>2]=j;G[v+4>>2]=r;q=q+2|0;w=w+2|0;if((A|0)!=(w|0)){continue}break}}if(!(u&1)){break D}j=H[q+B|0];L:{if((j|0)!=(z|0)){c=j;d=0;break L}G[o>>2]=1}j=x+(q<<3)|0;G[j>>2]=c;G[j+4>>2]=d;break D}if((u|0)<=0){break D}z=0;q=0;if(u-1>>>0>=3){j=u&-4;w=0;while(1){c=x+(q<<3)|0;G[c>>2]=H[q+B|0];G[c+4>>2]=0;d=q|1;c=x+(d<<3)|0;G[c>>2]=H[d+B|0];G[c+4>>2]=0;d=q|2;c=x+(d<<3)|0;G[c>>2]=H[d+B|0];G[c+4>>2]=0;d=q|3;c=x+(d<<3)|0;G[c>>2]=H[d+B|0];G[c+4>>2]=0;q=q+4|0;w=w+4|0;if((j|0)!=(w|0)){continue}break}}d=u&3;if(!d){break D}while(1){c=x+(q<<3)|0;G[c>>2]=H[q+B|0];G[c+4>>2]=0;q=q+1|0;z=z+1|0;if((d|0)!=(z|0)){continue}break}}break g}q=t- -64|0;Pe(a,x,j,u,z,q,p);r=I[t+29024>>1];c=k;d=l;B=e+n|0;y=(e<<3)+m|0;K=L[t+29096>>3];N=L[t+29088>>3];j=K==1&N==0;M:{N:{if(!D){if(j){break N}C=0;if((u|0)<=0){break M}while(1){c=y+(C<<3)|0;O:{P:{s=+F[q+(C<<1)>>1]*K+N;if(s<-0x8000000000000000){G[p>>2]=-11;break P}if(s>0x8000000000000000){G[p>>2]=-11;j=-1;d=2147483647;break O}if(!(O(s)<0x8000000000000000)){break P}j=~~s>>>0;d=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;break O}j=0;d=-2147483648}G[c>>2]=j;G[c+4>>2]=d;C=C+1|0;if((u|0)!=(C|0)){continue}break}break M}if(!j){if((u|0)<=0){break M}C=0;while(1){j=I[q+(C<<1)>>1];Q:{if((j|0)==(r|0)){G[o>>2]=1;if((D|0)==1){j=y+(C<<3)|0;G[j>>2]=c;G[j+4>>2]=d;break Q}E[B+C|0]=1;break Q}s=+(j<<16>>16)*K+N;if(s<-0x8000000000000000){G[p>>2]=-11;j=y+(C<<3)|0;G[j>>2]=0;G[j+4>>2]=-2147483648;break Q}if(s>0x8000000000000000){G[p>>2]=-11;j=y+(C<<3)|0;G[j>>2]=-1;G[j+4>>2]=2147483647;break Q}A=y+(C<<3)|0;R:{if(O(s)<0x8000000000000000){v=~~s>>>0;j=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;break R}v=0;j=-2147483648}G[A>>2]=v;G[A+4>>2]=j}C=C+1|0;if((u|0)!=(C|0)){continue}break}break M}if((u|0)<=0){break M}if((D|0)!=1){C=0;if((u|0)!=1){z=u&-2;x=0;while(1){c=I[q+(C<<1)>>1];S:{if((c|0)==(r|0)){G[o>>2]=1;E[B+C|0]=1;break S}A=c<<16;v=A>>31;d=y+(C<<3)|0;G[d>>2]=A>>16;G[d+4>>2]=v}d=C|1;c=I[q+(d<<1)>>1];T:{if((c|0)!=(r|0)){j=c<<16;A=j>>31;d=y+(d<<3)|0;G[d>>2]=j>>16;G[d+4>>2]=A;break T}G[o>>2]=1;E[d+B|0]=1}C=C+2|0;x=x+2|0;if((z|0)!=(x|0)){continue}break}}if(!(u&1)){break M}c=I[q+(C<<1)>>1];if((c|0)!=(r|0)){v=c<<16;j=v>>31;d=y+(C<<3)|0;G[d>>2]=v>>16;G[d+4>>2]=j;break M}G[o>>2]=1;E[B+C|0]=1;break M}C=0;if((u|0)!=1){B=u&-2;x=0;while(1){z=y+(C<<3)|0;j=I[q+(C<<1)>>1];U:{if((j|0)!=(r|0)){A=j<<16;v=A>>31;A=A>>16;j=v;break U}G[o>>2]=1;A=c;j=d}G[z>>2]=A;G[z+4>>2]=j;z=C|1;j=I[q+(z<<1)>>1];V:{if((j|0)!=(r|0)){j=j<<16;A=j>>31;v=j>>16;j=A;break V}G[o>>2]=1;v=c;j=d}A=y+(z<<3)|0;G[A>>2]=v;G[A+4>>2]=j;C=C+2|0;x=x+2|0;if((B|0)!=(x|0)){continue}break}}if(!(u&1)){break M}j=I[q+(C<<1)>>1];W:{if((j|0)!=(r|0)){v=j<<16;j=v>>31;c=v>>16;d=j;break W}G[o>>2]=1}j=y+(C<<3)|0;G[j>>2]=c;G[j+4>>2]=d;break M}if((u|0)<=0){break M}x=0;C=0;if(u-1>>>0>=3){j=u&-4;z=0;while(1){d=y+(C<<3)|0;c=F[q+(C<<1)>>1];G[d>>2]=c;G[d+4>>2]=c>>31;c=C|1;d=y+(c<<3)|0;c=F[q+(c<<1)>>1];G[d>>2]=c;G[d+4>>2]=c>>31;c=C|2;d=y+(c<<3)|0;c=F[q+(c<<1)>>1];G[d>>2]=c;G[d+4>>2]=c>>31;c=C|3;d=y+(c<<3)|0;c=F[q+(c<<1)>>1];G[d>>2]=c;G[d+4>>2]=c>>31;C=C+4|0;z=z+4|0;if((j|0)!=(z|0)){continue}break}}j=u&3;if(!j){break M}while(1){d=y+(C<<3)|0;c=F[q+(C<<1)>>1];G[d>>2]=c;G[d+4>>2]=c>>31;C=C+1|0;x=x+1|0;if((j|0)!=(x|0)){continue}break}}break g}c=t- -64|0;Uc(a,x,j,u,z,c,p);Zp(c,u,L[t+29096>>3],L[t+29088>>3],D,k,l,e+n|0,o,(e<<3)+m|0,p);break g}c=t- -64|0;Tc(a,x,j,u,z,c,p);Yp(c,u,L[t+29096>>3],L[t+29088>>3],D,k,l,e+n|0,o,(e<<3)+m|0,p);break g}Jb(a,x,j,0,p);d=G[t+29060>>2];c=G[t+29064>>2];X:{if((d|0)==(c|0)){c=M(d,u);ic(a,c,c>>31,t- -64|0,p);break X}Rd(a,c,u,d-c|0,t- -64|0,p)}v=t- -64|0;K=L[t+29096>>3];N=L[t+29088>>3];q=G[t+29064>>2];x=e+n|0;Z=(e<<3)+m|0;U=0;P=Fa-112|0;Fa=P;w=t+28864|0;B=Va(w);if((u|0)>0){while(1){Y:{c=q+v|0;y=H[c|0];E[c|0]=0;j=v;Z:{_:{if(H[w|0]==1){break _}if(fb(w,v,B)){break _}j=c;if(!D){break Z}G[o>>2]=1;if((D|0)==1){d=(U<<3)+Z|0;G[d>>2]=k;G[d+4>>2]=l;break Z}E[x+U|0]=1;break Z}while(1){d=H[j|0];if((d|0)==32){j=j+1|0;continue}break}C=1;$:{switch(d-43|0){case 0:case 2:while(1){r=H[j+1|0];j=j+1|0;if((r|0)==32){continue}break};C=(d|0)==45?-1:1;d=r;break;default:break $}}Y=0;if((d-48&255)>>>0<10){while(1){s=Y*10+ +(d<<24>>24);r=j;while(1){d=H[r+1|0];j=r+1|0;r=j;if((d|0)==32){continue}break}Y=s+-48;if((d-48&255)>>>0<=9){continue}break}}s=R;aa:{ba:{switch(d-44|0){case 0:case 2:break ba;default:break aa}}r=j;while(1){d=H[r+1|0];j=r+1|0;r=j;if((d|0)==32){continue}break}s=1;if((d-48&255)>>>0>=10){break aa}while(1){Y=Y*10+ +(d<<24>>24)+-48;r=j;while(1){d=H[r+1|0];j=r+1|0;r=j;if((d|0)==32){continue}break}s=s*10;if((d-48&255)>>>0<=9){continue}break}}ca:{if((d&254)!=68){aa=1;r=0;break ca}while(1){aa=1;r=j;j=j+1|0;d=H[r+1|0];if((d|0)==32){continue}break}da:{switch(d-43|0){case 0:case 2:r=r+2|0;while(1){j=r;r=j+1|0;A=H[j|0];if((A|0)==32){continue}break};aa=(d|0)==45?-1:1;d=A;break;default:break da}}r=0;if((d-48&255)>>>0>=10){break ca}while(1){A=d;z=M(r,10)-48|0;r=j;while(1){d=H[r+1|0];j=r+1|0;r=j;if((d|0)==32){continue}break}r=z+(A<<24>>24)|0;if((d-48&255)>>>0<=9){continue}break}}if(d){G[P+48>>2]=H[23477]|H[23478]<<8|(H[23479]<<16|H[23480]<<24);d=H[23473]|H[23474]<<8|(H[23475]<<16|H[23476]<<24);G[P+40>>2]=H[23469]|H[23470]<<8|(H[23471]<<16|H[23472]<<24);G[P+44>>2]=d;d=H[23465]|H[23466]<<8|(H[23467]<<16|H[23468]<<24);G[P+32>>2]=H[23461]|H[23462]<<8|(H[23463]<<16|H[23464]<<24);G[P+36>>2]=d;d=H[23457]|H[23458]<<8|(H[23459]<<16|H[23460]<<24);G[P+24>>2]=H[23453]|H[23454]<<8|(H[23455]<<16|H[23456]<<24);G[P+28>>2]=d;d=H[23449]|H[23450]<<8|(H[23451]<<16|H[23452]<<24);G[P+16>>2]=H[23445]|H[23446]<<8|(H[23447]<<16|H[23448]<<24);G[P+20>>2]=d;d=P+16|0;Ua(d);G[P>>2]=v;Ya(d,81,43022,P);Ua(d);E[c|0]=y;G[p>>2]=409;break Y}s=Y*+(C|0)/s*$b(10,+(M(r,aa)|0))*K+N;ea:{if(s<-0x8000000000000000){G[p>>2]=-11;d=(U<<3)+Z|0;G[d>>2]=0;G[d+4>>2]=-2147483648;break ea}if(s>0x8000000000000000){G[p>>2]=-11;d=(U<<3)+Z|0;G[d>>2]=-1;G[d+4>>2]=2147483647;break ea}v=(U<<3)+Z|0;fa:{if(O(s)<0x8000000000000000){r=~~s>>>0;d=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;break fa}r=0;d=-2147483648}G[v>>2]=r;G[v+4>>2]=d}}v=j;E[c|0]=y;U=U+1|0;if((u|0)!=(U|0)){continue}}break}}Fa=P+112|0;break g}G[t>>2]=b;G[t+4>>2]=t+28992;a=t+28896|0;Ya(a,81,8924,t);Ua(a);r=311;if(G[t+29076>>2]==1){break e}r=312;break e}B=t- -64|0;Uc(a,x,j,u,z,B,p);z=G[t+29024>>2];c=k;d=l;A=e+n|0;x=(e<<3)+m|0;K=L[t+29096>>3];N=L[t+29088>>3];j=K==1&N==0;ga:{ha:{if(!D){if(j){break ha}q=0;if((u|0)<=0){break ga}while(1){c=x+(q<<3)|0;ia:{ja:{s=+G[B+(q<<2)>>2]*K+N;if(s<-0x8000000000000000){G[p>>2]=-11;break ja}if(s>0x8000000000000000){G[p>>2]=-11;j=-1;d=2147483647;break ia}if(!(O(s)<0x8000000000000000)){break ja}j=~~s>>>0;d=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;break ia}j=0;d=-2147483648}G[c>>2]=j;G[c+4>>2]=d;q=q+1|0;if((u|0)!=(q|0)){continue}break}break ga}if(!j){if((u|0)<=0){break ga}q=0;while(1){j=G[B+(q<<2)>>2];ka:{if((j|0)==(z|0)){G[o>>2]=1;if((D|0)==1){j=x+(q<<3)|0;G[j>>2]=c;G[j+4>>2]=d;break ka}E[q+A|0]=1;break ka}s=+(j|0)*K+N;if(s<-0x8000000000000000){G[p>>2]=-11;j=x+(q<<3)|0;G[j>>2]=0;G[j+4>>2]=-2147483648;break ka}if(s>0x8000000000000000){G[p>>2]=-11;j=x+(q<<3)|0;G[j>>2]=-1;G[j+4>>2]=2147483647;break ka}v=x+(q<<3)|0;la:{if(O(s)<0x8000000000000000){r=~~s>>>0;j=O(s)>=1?~~(s>0?Q(S(s*2.3283064365386963e-10),4294967295):T((s-+(~~s>>>0>>>0))*2.3283064365386963e-10))>>>0:0;break la}r=0;j=-2147483648}G[v>>2]=r;G[v+4>>2]=j}q=q+1|0;if((u|0)!=(q|0)){continue}break}break ga}if((u|0)<=0){break ga}if((D|0)!=1){q=0;if((u|0)!=1){d=u&-2;w=0;while(1){j=G[B+(q<<2)>>2];ma:{if((j|0)==(z|0)){G[o>>2]=1;E[q+A|0]=1;break ma}c=x+(q<<3)|0;G[c>>2]=j;G[c+4>>2]=j>>31}c=q|1;j=G[B+(c<<2)>>2];na:{if((j|0)!=(z|0)){c=x+(c<<3)|0;G[c>>2]=j;G[c+4>>2]=j>>31;break na}G[o>>2]=1;E[c+A|0]=1}q=q+2|0;w=w+2|0;if((d|0)!=(w|0)){continue}break}}if(!(u&1)){break ga}d=G[B+(q<<2)>>2];if((d|0)!=(z|0)){c=x+(q<<3)|0;G[c>>2]=d;G[c+4>>2]=d>>31;break ga}G[o>>2]=1;E[q+A|0]=1;break ga}q=0;if((u|0)!=1){A=u&-2;w=0;while(1){v=x+(q<<3)|0;j=G[B+(q<<2)>>2];oa:{if((j|0)!=(z|0)){r=j>>31;break oa}G[o>>2]=1;j=c;r=d}G[v>>2]=j;G[v+4>>2]=r;v=q|1;j=G[B+(v<<2)>>2];pa:{if((j|0)!=(z|0)){r=j>>31;break pa}G[o>>2]=1;j=c;r=d}v=x+(v<<3)|0;G[v>>2]=j;G[v+4>>2]=r;q=q+2|0;w=w+2|0;if((A|0)!=(w|0)){continue}break}}if(!(u&1)){break ga}j=G[B+(q<<2)>>2];qa:{if((j|0)!=(z|0)){c=j;d=c>>31;break qa}G[o>>2]=1}j=x+(q<<3)|0;G[j>>2]=c;G[j+4>>2]=d;break ga}if((u|0)<=0){break ga}z=0;q=0;if(u-1>>>0>=3){j=u&-4;w=0;while(1){d=x+(q<<3)|0;c=G[B+(q<<2)>>2];G[d>>2]=c;G[d+4>>2]=c>>31;c=q|1;d=x+(c<<3)|0;c=G[B+(c<<2)>>2];G[d>>2]=c;G[d+4>>2]=c>>31;c=q|2;d=x+(c<<3)|0;c=G[B+(c<<2)>>2];G[d>>2]=c;G[d+4>>2]=c>>31;c=q|3;d=x+(c<<3)|0;c=G[B+(c<<2)>>2];G[d>>2]=c;G[d+4>>2]=c>>31;q=q+4|0;w=w+4|0;if((j|0)!=(w|0)){continue}break}}j=u&3;if(!j){break ga}while(1){d=x+(q<<3)|0;c=G[B+(q<<2)>>2];G[d>>2]=c;G[d+4>>2]=c>>31;q=q+1|0;z=z+1|0;if((j|0)!=(z|0)){continue}break}}}r=G[p>>2];if((r|0)>0){s=+(e>>>0)+ +(f|0)*4294967296;R=s+1;s=s+ +(u|0);ra:{if(G[t+29076>>2]>0){G[t+32>>2]=b;L[t+24>>3]=s;L[t+16>>3]=R;Ya(t+28896|0,81,46757,t+16|0);break ra}L[t+56>>3]=s;L[t+48>>3]=R;Ya(t+28896|0,81,46698,t+48|0)}Ua(t+28896|0);r=G[p>>2];break a}v=u>>31;j=u;c=j;h=h-((c>>>0>g>>>0)+v|0)|0;g=g-c|0;if(h|g){c=M(i,u);r=c+G[t+29032>>2]|0;d=G[t+29036>>2]+(c>>31)|0;d=c>>>0>r>>>0?d+1|0:d;c=r;G[t+29032>>2]=c;r=d;G[t+29036>>2]=d;d=e+j|0;j=f+v|0;j=d>>>0>>0?j+1|0:j;e=d;f=j;u=G[t+29052>>2];d=u;q=G[t+29048>>2];if((r|0)>=(d|0)&c>>>0>=q>>>0|(d|0)<(r|0)){j=Bu(c,r,q,u);v=X+j|0;d=Ia;V=V+d|0;V=v>>>0>>0?V+1|0:V;X=v;d=Au(j,d,q,u);G[t+29032>>2]=c-d;G[t+29036>>2]=r-(Ia+(c>>>0>>0)|0);continue}if((r|0)>0|(r|0)>=0){continue}j=Bu(c^-1,r^-1,q,u)+1|0;A=Ia;A=j?A:A+1|0;d=X;X=d-j|0;V=V-((d>>>0>>0)+A|0)|0;d=Au(j,A,q,u)+c|0;j=r+Ia|0;G[t+29032>>2]=d;G[t+29036>>2]=c>>>0>d>>>0?j+1|0:j;continue}break}if((r|0)!=-11){break a}Ua(44994);r=412}G[p>>2]=r}Fa=t+29104|0;return r}function Gm(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,H=0,I=0,J=0,K=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,X=0,Y=0,Z=0,_=0,$=0;F=Fa-80|0;Fa=F;a:{b:{c:{d:{if(b){j=G[a>>2];d=G[a+16>>2];f=G[a+8>>2];y=lb(M(f,f),8);if(y){D=lb(f,8);if(!D){break d}g=143;t=f-1|0;if(!b){break c}z=f&3;r=d&-4;P=d&3;u=(d|0)<=0;U=d-1>>>0>2;while(1){p=g;e:{if(u){break e}i=0;g=0;s=0;if(U){while(1){d=g<<3;n=F+48|0;L[d+n>>3]=L[b>>3];L[n+(d|8)>>3]=L[b+8>>3];L[n+(d|16)>>3]=L[b+16>>3];L[n+(d|24)>>3]=L[b+24>>3];g=g+4|0;b=b+32|0;s=s+4|0;if((r|0)!=(s|0)){continue}break}}if(!P){break e}while(1){L[(F+48|0)+(g<<3)>>3]=L[b>>3];g=g+1|0;b=b+8|0;i=i+1|0;if((P|0)!=(i|0)){continue}break}}$g(a,F+48|0);f:{if(!l){e=1;l=0;break f}e=L[l>>3];l=l+8|0}if(f){h=L[c>>3];d=t;g=y;n=D;o=j;while(1){v=d;k=e*L[o>>3];L[n>>3]=k*h+L[n>>3];s=0;i=f;d=j;if(z){while(1){L[g>>3]=k*L[d>>3]+L[g>>3];g=g+8|0;d=d+8|0;i=i-1|0;s=s+1|0;if((z|0)!=(s|0)){continue}break}}if(t>>>0>=3){while(1){L[g>>3]=k*L[d>>3]+L[g>>3];L[g+8>>3]=k*L[d+8>>3]+L[g+8>>3];L[g+16>>3]=k*L[d+16>>3]+L[g+16>>3];L[g+24>>3]=k*L[d+24>>3]+L[g+24>>3];g=g+32|0;d=d+32|0;i=i-4|0;if(i){continue}break}}d=v-1|0;n=n+8|0;o=o+8|0;if(v){continue}break}}c=c+8|0;g=p-1|0;if(p){continue}break}break b}G[F+4>>2]=65985;G[F>>2]=66133;_a(G[24367],90100,F);break a}G[F+36>>2]=64147;G[F+32>>2]=66156;_a(G[24367],90100,F+32|0);break a}G[F+20>>2]=65960;G[F+16>>2]=66133;_a(G[24367],90100,F+16|0);break a}if(!f){break b}z=f&3;P=f&7;r=f-1|0;while(1){o=g;i=0;d=f;g=j;if(P){while(1){L[g>>3]=L[v>>3];g=g+8|0;v=v+8|0;d=d-1|0;i=i+1|0;if((P|0)!=(i|0)){continue}break}}if(r>>>0>=7){while(1){L[g>>3]=L[v>>3];L[g+8>>3]=L[v+8>>3];L[g+16>>3]=L[v+16>>3];L[g+24>>3]=L[v+24>>3];L[g+32>>3]=L[v+32>>3];L[g+40>>3]=L[v+40>>3];L[g+48>>3]=L[v+48>>3];L[g+56>>3]=L[v+56>>3];g=g- -64|0;v=v- -64|0;d=d-8|0;if(d){continue}break}}g:{if(!l){e=1;l=0;break g}e=L[l>>3];l=l+8|0}h=L[c>>3];d=t;g=y;b=D;n=j;while(1){p=d;k=e*L[n>>3];L[b>>3]=k*h+L[b>>3];s=0;i=f;d=j;if(z){while(1){L[g>>3]=k*L[d>>3]+L[g>>3];g=g+8|0;d=d+8|0;i=i-1|0;s=s+1|0;if((z|0)!=(s|0)){continue}break}}if(r>>>0>=3){while(1){L[g>>3]=k*L[d>>3]+L[g>>3];L[g+8>>3]=k*L[d+8>>3]+L[g+8>>3];L[g+16>>3]=k*L[d+16>>3]+L[g+16>>3];L[g+24>>3]=k*L[d+24>>3]+L[g+24>>3];g=g+32|0;d=d+32|0;i=i-4|0;if(i){continue}break}}d=p-1|0;b=b+8|0;n=n+8|0;if(p){continue}break}g=o-1|0;c=c+8|0;if(o){continue}break}}S=Fa-32|0;Fa=S;d=0;i=Fa-16|0;Fa=i;h:{i:{j:{k:{n=ab(f<<3);if(n){if((f|0)<=0){break j}while(1){l=M(d,f);o=n+(d<<3)|0;l:{if(!d){b=0;while(1){e=L[(b+l<<3)+y>>3];m:{if(!b){if(e<=0){break i}L[o>>3]=V(e);break m}L[(M(b,f)<<3)+y>>3]=e/L[o>>3]}b=b+1|0;if((f|0)!=(b|0)){continue}break}break l}p=d&1;g=d-1|0;v=(g+l<<3)+y|0;c=d;while(1){t=M(c,f);e=L[(c+l<<3)+y>>3];if(p){e=e-L[v>>3]*L[(g+t<<3)+y>>3];b=g}else{b=d}if((d|0)!=1){while(1){j=b-1|0;k=e-L[(j+l<<3)+y>>3]*L[(j+t<<3)+y>>3];j=b-2|0;e=k-L[(j+l<<3)+y>>3]*L[(j+t<<3)+y>>3];s=(b|0)>2;b=j;if(s){continue}break}}n:{if((c|0)==(d|0)){if(e<=0){break i}L[o>>3]=V(e);break n}L[(d+t<<3)+y>>3]=e/L[o>>3]}c=c+1|0;if((f|0)!=(c|0)){continue}break}}d=d+1|0;if((f|0)!=(d|0)){continue}break}break k}G[i+4>>2]=65812;G[i>>2]=66133;_a(G[24367],90100,i);ca(-1);W()}j=0;if((f|0)<=0){break j}while(1){g=j<<3;l=g+D|0;e=L[l>>3];o:{if(!j){break o}d=M(f,j);p:{if(!(j&1)){b=j;break p}b=j-1|0;e=e-L[(d+b<<3)+y>>3]*L[(b<<3)+D>>3]}if((j|0)==1){break o}while(1){c=b-1|0;k=e-L[(c+d<<3)+y>>3]*L[(c<<3)+D>>3];c=b-2|0;e=k-L[(c+d<<3)+y>>3]*L[(c<<3)+D>>3];o=(b|0)>2;b=c;if(o){continue}break}}L[l>>3]=e/L[g+n>>3];j=j+1|0;if((j|0)!=(f|0)){continue}break}j=0;if((f|0)<=0){break j}c=f;while(1){d=c;c=c-1|0;g=c<<3;l=g+D|0;e=L[l>>3];q:{if((d|0)>=(f|0)){break q}if(j&1){e=e-L[(M(d,f)+c<<3)+y>>3]*L[(d<<3)+D>>3];b=d+1|0}else{b=d}if((j|0)==1){break q}while(1){o=b+1|0;e=e-L[(M(b,f)+c<<3)+y>>3]*L[(b<<3)+D>>3]-L[(M(o,f)+c<<3)+y>>3]*L[(o<<3)+D>>3];b=b+2|0;if((f|0)!=(b|0)){continue}break}}L[l>>3]=e/L[g+n>>3];j=j+1|0;if((d|0)>1){continue}break}}Wa(n);b=0;break h}Wa(n);b=-1}Fa=i+16|0;r:{s:{t:{if(b){b=f<<3;U=ab(M(b,f));if(!U){break t}$=ab(b);if(!$){break s}s=y;v=U;t=$;r=0;J=Fa+-64|0;Fa=J;u:{v:{w:{b=f<<3;H=ab(b);if(H){x:{y:{P=ab(b);if(P){if((f|0)>0){break y}z=f-1|0;break x}G[J+36>>2]=65810;G[J+32>>2]=66133;_a(G[24367],90100,J+32|0);break v}u=f-2|0;E=f-1|0;Q=f+1|0;while(1){i=r;w=i<<3;K=w+H|0;L[K>>3]=q*m;r=i+1|0;n=f-r|0;q=0;m=0;g=f-i|0;z:{if((g|0)<=0){break z}d=0;b=g;j=(M(i,Q)<<3)+s|0;c=j;l=f-i&3;if(l){while(1){b=b-1|0;m=m+O(L[c>>3]);c=c+8|0;d=d+1|0;if((l|0)!=(d|0)){continue}break}}A=E-i>>>0<3;if(!A){while(1){m=m+O(L[c>>3])+O(L[c+8>>3])+O(L[c+16>>3])+O(L[c+24>>3]);c=c+32|0;b=b-4|0;if(b){continue}break}}if(m==0){break z}e=0;c=j;b=g;if(b&1){e=L[j>>3]/m;L[j>>3]=e;c=j+8|0;e=e*e+0;b=g-1|0}if((i|0)!=(E|0)){while(1){k=L[c>>3]/m;L[c>>3]=k;h=L[c+8>>3]/m;L[c+8>>3]=h;e=h*h+(k*k+e);c=c+16|0;b=b-2|0;if(b){continue}break}}k=O(V(e));x=k;C=-k;k=L[j>>3];h=k>=0?x:C;L[j>>3]=k+h;q=-h;if(n){k=k*q-e;p=w+((M(f,r)<<3)+s|0)|0;o=g&3;z=n;while(1){l=0;h=0;d=g;c=p;b=j;if(o){while(1){d=d-1|0;h=L[c>>3]*L[b>>3]+h;c=c+8|0;b=b+8|0;l=l+1|0;if((o|0)!=(l|0)){continue}break}}if(!A){while(1){h=L[c+24>>3]*L[b+24>>3]+(L[c+16>>3]*L[b+16>>3]+(L[c+8>>3]*L[b+8>>3]+(L[c>>3]*L[b>>3]+h)));b=b+32|0;c=c+32|0;d=d-4|0;if(d){continue}break}}e=h/k;l=0;d=g;c=p;b=j;if(o){while(1){L[c>>3]=e*L[b>>3]+L[c>>3];c=c+8|0;b=b+8|0;d=d-1|0;l=l+1|0;if((o|0)!=(l|0)){continue}break}}if(!A){while(1){L[c>>3]=e*L[b>>3]+L[c>>3];L[c+8>>3]=e*L[b+8>>3]+L[c+8>>3];L[c+16>>3]=e*L[b+16>>3]+L[c+16>>3];L[c+24>>3]=e*L[b+24>>3]+L[c+24>>3];c=c+32|0;b=b+32|0;d=d-4|0;if(d){continue}break}}p=(f<<3)+p|0;z=z-1|0;if(z){continue}break}}c=0;b=g&3;if(b){while(1){L[j>>3]=m*L[j>>3];j=j+8|0;g=g-1|0;c=c+1|0;if((b|0)!=(c|0)){continue}break}}if(A){break z}while(1){L[j>>3]=m*L[j>>3];L[j+8>>3]=m*L[j+8>>3];L[j+16>>3]=m*L[j+16>>3];L[j+24>>3]=m*L[j+24>>3];j=j+32|0;g=g-4|0;if(g){continue}break}}A=t+w|0;L[A>>3]=q*m;q=0;A:{if(!((f|0)==(r|0)|(f|0)<=(i|0))){m=0;if(!n){break A}d=0;b=n;c=s+w|0;w=M(f,r)<<3;l=c+w|0;c=l;g=E-i|0;p=g&3;if(p){while(1){b=b-1|0;m=m+O(L[c>>3]);c=(f<<3)+c|0;d=d+1|0;if((p|0)!=(d|0)){continue}break}}R=u-i|0;z=R>>>0<3;if(!z){while(1){d=f<<3;j=d+c|0;I=d+j|0;o=I+d|0;m=m+O(L[c>>3])+O(L[j>>3])+O(L[I>>3])+O(L[o>>3]);c=d+o|0;b=b-4|0;if(b){continue}break}}if(m==0){break A}B:{if(!n){e=0;break B}e=0;b=n;c=l;if(g&1){e=L[l>>3]/m;L[l>>3]=e;c=(f<<3)+l|0;e=e*e+0;b=n-1|0}if((i|0)==(u|0)){break B}while(1){h=L[c>>3]/m;L[c>>3]=h;d=f<<3;c=d+c|0;k=L[c>>3]/m;L[c>>3]=k;c=c+d|0;e=k*k+(h*h+e);b=b-2|0;if(b){continue}break}}k=O(V(e));x=k;C=-k;k=L[l>>3];h=k>=0?x:C;L[l>>3]=k+h;o=r<<3;j=o+H|0;q=-h;C:{if(!n){break C}e=k*q-e;d=n;c=j;b=l;if(g&1){L[j>>3]=L[l>>3]/e;c=j+8|0;d=n-1|0;b=(f<<3)+l|0}if((i|0)==(u|0)){break C}while(1){L[c>>3]=L[b>>3]/e;g=b;b=f<<3;g=g+b|0;L[c+8>>3]=L[g>>3]/e;b=b+g|0;c=c+16|0;d=d-2|0;if(d){continue}break}}if((f|0)!=(r|0)){g=w+(o+s|0)|0;o=f-r|0;while(1){o=o-1|0;D:{if(!n){break D}c=0;h=0;i=n;b=g;d=l;if(p){while(1){i=i-1|0;h=L[b>>3]*L[d>>3]+h;w=f<<3;b=w+b|0;d=d+w|0;c=c+1|0;if((p|0)!=(c|0)){continue}break}}if(R>>>0>2){while(1){c=f<<3;w=c+b|0;I=c+w|0;X=I+c|0;Y=c+d|0;Z=Y+c|0;_=Z+c|0;h=L[X>>3]*L[_>>3]+(L[I>>3]*L[Z>>3]+(L[w>>3]*L[Y>>3]+(L[b>>3]*L[d>>3]+h)));b=c+X|0;d=c+_|0;i=i-4|0;if(i){continue}break}}if(!n){break D}i=0;d=n;c=j;b=g;if(p){while(1){L[b>>3]=h*L[c>>3]+L[b>>3];c=c+8|0;d=d-1|0;b=(f<<3)+b|0;i=i+1|0;if((p|0)!=(i|0)){continue}break}}if(z){break D}while(1){L[b>>3]=h*L[c>>3]+L[b>>3];i=b;b=f<<3;i=i+b|0;L[i>>3]=h*L[c+8>>3]+L[i>>3];i=b+i|0;L[i>>3]=h*L[c+16>>3]+L[i>>3];i=b+i|0;L[i>>3]=h*L[c+24>>3]+L[i>>3];b=b+i|0;c=c+32|0;d=d-4|0;if(d){continue}break}}g=g+8|0;if(o){continue}break}}if(!n){break A}c=0;if(p){while(1){L[l>>3]=m*L[l>>3];n=n-1|0;l=(f<<3)+l|0;c=c+1|0;if((p|0)!=(c|0)){continue}break}}if(z){break A}while(1){L[l>>3]=m*L[l>>3];b=f<<3;c=b+l|0;L[c>>3]=m*L[c>>3];c=b+c|0;L[c>>3]=m*L[c>>3];c=b+c|0;L[c>>3]=m*L[c>>3];l=b+c|0;n=n-4|0;if(n){continue}break}break A}m=0}e=O(L[A>>3])+O(L[K>>3]);T=e=(z|0)){w=M(f,g);break E}r=j-1|0;F:{if(q==0){w=M(f,g);E=M(f,p);break F}w=M(f,g);if(!j){break E}o=((M(f,p)<<3)+s|0)+(g<<3)|0;e=q*L[o>>3];n=p<<3;u=n+((w<<3)+v|0)|0;c=u;b=o;d=j;if(d&1){L[u>>3]=L[o>>3]/e;c=u+8|0;d=r;b=o+(f<<3)|0}if((j|0)!=1){while(1){L[c>>3]=L[b>>3]/e;l=b;b=f<<3;l=l+b|0;L[c+8>>3]=L[l>>3]/e;b=b+l|0;c=c+16|0;d=d-2|0;if(d){continue}break}if(!j){break E}}E=M(f,p);n=n+((E<<3)+v|0)|0;A=j&3;l=j;while(1){i=0;h=0;d=j;c=n;b=o;if(A){while(1){d=d-1|0;h=L[b>>3]*L[c>>3]+h;c=c+8|0;b=(f<<3)+b|0;i=i+1|0;if((A|0)!=(i|0)){continue}break}}K=r>>>0<3;if(!K){while(1){i=f<<3;Q=i+b|0;R=i+Q|0;I=R+i|0;h=L[I>>3]*L[c+24>>3]+(L[R>>3]*L[c+16>>3]+(L[Q>>3]*L[c+8>>3]+(L[b>>3]*L[c>>3]+h)));b=i+I|0;c=c+32|0;d=d-4|0;if(d){continue}break}}i=0;d=j;c=n;b=u;if(A){while(1){L[c>>3]=h*L[b>>3]+L[c>>3];c=c+8|0;b=b+8|0;d=d-1|0;i=i+1|0;if((A|0)!=(i|0)){continue}break}}if(!K){while(1){L[c>>3]=h*L[b>>3]+L[c>>3];L[c+8>>3]=h*L[b+8>>3]+L[c+8>>3];L[c+16>>3]=h*L[b+16>>3]+L[c+16>>3];L[c+24>>3]=h*L[b+24>>3]+L[c+24>>3];c=c+32|0;b=b+32|0;d=d-4|0;if(d){continue}break}}n=(f<<3)+n|0;l=l-1|0;if(l){continue}break}}if(!j){break E}b=((E<<3)+v|0)+(g<<3)|0;c=((w<<3)+v|0)+(p<<3)|0;d=0;n=j&3;if(n){while(1){G[c>>2]=0;G[c+4>>2]=0;G[b>>2]=0;G[b+4>>2]=0;c=c+8|0;j=j-1|0;b=(f<<3)+b|0;d=d+1|0;if((n|0)!=(d|0)){continue}break}}if(r>>>0<3){break E}while(1){G[c>>2]=0;G[c+4>>2]=0;G[b>>2]=0;G[b+4>>2]=0;G[c+8>>2]=0;G[c+12>>2]=0;d=b;b=f<<3;d=d+b|0;G[d>>2]=0;G[d+4>>2]=0;G[c+16>>2]=0;G[c+20>>2]=0;d=b+d|0;G[d>>2]=0;G[d+4>>2]=0;G[c+24>>2]=0;G[c+28>>2]=0;d=b+d|0;G[d>>2]=0;G[d+4>>2]=0;b=b+d|0;c=c+32|0;j=j-4|0;if(j){continue}break}}b=(g+w<<3)+v|0;G[b>>2]=0;G[b+4>>2]=1072693248;c=g-1|0;j=f-g|0;q=L[(g<<3)+H>>3];if((g|0)>0){continue}break}}if((f|0)>0){E=0;R=E+1|0;b=f^-1;I=b+f|0;X=b+f|0;u=f<<3;Y=-8-u|0;Z=(f+M(f-1|0,f)<<3)-8|0;o=0;l=f;while(1){b=l;l=b-1|0;c=l<<3;g=c+((M(f,l)<<3)+s|0)|0;w=o+E|0;A=o+R|0;p=f-l|0;e=L[c+t>>3];G:{H:{I:{J:{n=f-b|0;if(n){d=0;b=n;j=g+u|0;c=j;i=o+E&7;if(i){while(1){G[c>>2]=0;G[c+4>>2]=0;b=b-1|0;c=c+u|0;d=d+1|0;if((i|0)!=(d|0)){continue}break}}if(o+X>>>0>=7){while(1){G[c>>2]=0;G[c+4>>2]=0;c=c+u|0;G[c>>2]=0;G[c+4>>2]=0;c=c+u|0;G[c>>2]=0;G[c+4>>2]=0;c=c+u|0;G[c>>2]=0;G[c+4>>2]=0;c=c+u|0;G[c>>2]=0;G[c+4>>2]=0;c=c+u|0;G[c>>2]=0;G[c+4>>2]=0;c=c+u|0;G[c>>2]=0;G[c+4>>2]=0;c=c+u|0;G[c>>2]=0;G[c+4>>2]=0;c=c+u|0;b=b-8|0;if(b){continue}break}}if(e!=0){break J}break H}if(e==0){break H}m=1/e;break I}m=1/e;if(!n){break I}_=o+I|0;Q=A&3;K=w&3;r=p-1|0;while(1){K:{if(!r){h=0;break K}i=0;h=0;d=r;c=j;b=g;if(K){while(1){d=d-1|0;h=L[b+8>>3]*L[c+8>>3]+h;c=c+8|0;b=b+8|0;i=i+1|0;if((K|0)!=(i|0)){continue}break}}if(_>>>0<3){break K}while(1){h=L[b+32>>3]*L[c+32>>3]+(L[b+24>>3]*L[c+24>>3]+(L[b+16>>3]*L[c+16>>3]+(L[b+8>>3]*L[c+8>>3]+h)));c=c+32|0;b=b+32|0;d=d-4|0;if(d){continue}break}}n=n-1|0;L:{if(!p){break L}e=m*(h/L[g>>3]);i=0;d=p;c=j;b=g;if(Q){while(1){L[c>>3]=e*L[b>>3]+L[c>>3];c=c+8|0;b=b+8|0;d=d-1|0;i=i+1|0;if((Q|0)!=(i|0)){continue}break}}if(w>>>0<3){break L}while(1){L[c>>3]=e*L[b>>3]+L[c>>3];L[c+8>>3]=e*L[b+8>>3]+L[c+8>>3];L[c+16>>3]=e*L[b+16>>3]+L[c+16>>3];L[c+24>>3]=e*L[b+24>>3]+L[c+24>>3];c=c+32|0;b=b+32|0;d=d-4|0;if(d){continue}break}}j=j+u|0;if(n){continue}break}}if(!p){break G}b=0;c=g;d=A&3;if(d){while(1){L[c>>3]=m*L[c>>3];c=c+8|0;p=p-1|0;b=b+1|0;if((d|0)!=(b|0)){continue}break}}if(w>>>0<3){break G}while(1){L[c>>3]=m*L[c>>3];L[c+8>>3]=m*L[c+8>>3];L[c+16>>3]=m*L[c+16>>3];L[c+24>>3]=m*L[c+24>>3];c=c+32|0;p=p-4|0;if(p){continue}break}break G}if(!p){break G}cb((Z+M(o,Y)|0)+s|0,0,A<<3)}L[g>>3]=L[g>>3]+1;o=o+1|0;if((f|0)!=(o|0)){continue}break}}if((f|0)<=0){break w}A=f&3;n=f-1|0;E=f&1;o=f;M:while(1){p=o;o=o-1|0;b=o<<3;Q=b+H|0;K=p-2|0;c=K<<3;R=c+H|0;I=c+t|0;w=b+t|0;g=0;while(1){l=o;N:{O:{while(1){if(T+O(L[(l<<3)+H>>3])==T){break N}c=l-1|0;if(T+O(L[(c<<3)+t>>3])==T){break O}b=(l|0)<=0;l=c;if(!b){continue}break}c=-1;l=-1}if((l|0)>=(p|0)){break N}r=(M(c,f)<<3)+s|0;u=r+8|0;i=(M(f,l)<<3)+s|0;h=1;j=l;while(1){b=j<<3;q=h*L[b+H>>3];e=O(q);if(T+e==T){break N}b=b+t|0;m=L[b>>3];h=O(m);P:{if(h>3]=k;e=1/k;h=e*-q;Q:{if(!f){break Q}e=m*e;d=f;c=i;b=r;if(E){k=L[r>>3];m=L[i>>3];L[r>>3]=k*e+h*m;L[i>>3]=m*e-h*k;c=i+8|0;d=n;b=u}if(!n){break Q}while(1){k=L[b>>3];m=L[c>>3];L[b>>3]=k*e+h*m;L[c>>3]=m*e-h*k;k=L[b+8>>3];m=L[c+8>>3];L[b+8>>3]=k*e+h*m;L[c+8>>3]=m*e-h*k;c=c+16|0;b=b+16|0;d=d-2|0;if(d){continue}break}}i=(f<<3)+i|0;j=j+1|0;if((p|0)>(j|0)){continue}break}}e=L[w>>3];if((l|0)==(o|0)){R:{if(!(e<0)){break R}L[w>>3]=-e;c=(M(f,o)<<3)+v|0;d=0;b=f;if(A){while(1){L[c>>3]=-L[c>>3];c=c+8|0;b=b-1|0;d=d+1|0;if((A|0)!=(d|0)){continue}break}}if(n>>>0<3){break R}while(1){L[c>>3]=-L[c>>3];L[c+8>>3]=-L[c+8>>3];L[c+16>>3]=-L[c+16>>3];L[c+24>>3]=-L[c+24>>3];c=c+32|0;b=b-4|0;if(b){continue}break}}z=z-1|0;if((p|0)>1){continue M}break w}if((g|0)!=99){u=l<<3;q=L[u+t>>3];m=L[I>>3];h=L[R>>3];k=L[Q>>3];h=((m-e)*(e+m)+(h-k)*(h+k))/(m*(k+k));x=O(h);S:{if(x>1){C=x;x=1/x;x=C*V(x*x+1);break S}x=V(h*h+1)}C=(q-e)*(e+q);e=O(x);e=(C+k*(m/(h+(h>=0?e:-e))-k))/q;if((l|0)<=(K|0)){b=M(f,l)<<3;i=b+s|0;j=b+v|0;h=1;m=1;while(1){d=i;c=j;b=l;l=b+1|0;j=l<<3;k=L[j+H>>3];x=m*k;C=L[j+t>>3];r=b<<3;b=r+H|0;m=O(e);B=h*k;h=O(B);T:{if(m>h){k=h/m;k=m*V(k*k+1);break T}k=0;if(B==0){break T}k=m/h;k=h*V(k*k+1)}L[b>>3]=k;h=B/k;B=x*h;m=e/k;e=q*m;j=(f<<3)+c|0;U:{if(!E){i=f;b=j;break U}k=L[c>>3];N=L[j>>3];L[c>>3]=k*m+h*N;L[j>>3]=N*m-h*k;c=c+8|0;i=n;b=j+8|0}if(n){while(1){k=L[c>>3];N=L[b>>3];L[c>>3]=k*m+h*N;L[b>>3]=N*m-h*k;k=L[c+8>>3];N=L[b+8>>3];L[c+8>>3]=k*m+h*N;L[b+8>>3]=N*m-h*k;b=b+16|0;c=c+16|0;i=i-2|0;if(i){continue}break}}q=x*m-h*q;x=C*m;N=e+B;e=O(N);C=C*h;k=O(C);V:{W:{if(e>k){k=k/e;B=k*k+1;break W}if(C==0){b=r+t|0;G[b>>2]=0;G[b+4>>2]=0;break V}e=e/k;B=e*e+1;e=k}e=e*V(B);L[r+t>>3]=e;if(e==0){break V}e=1/e;h=C*e;m=N*e}e=q*h;k=m*x;x=x*h;C=m*q;i=(f<<3)+d|0;X:{if(!f){break X}Y:{if(!E){c=i;b=f;break Y}q=L[d>>3];B=L[i>>3];L[d>>3]=q*m+h*B;L[i>>3]=B*m-h*q;c=i+8|0;d=d+8|0;b=n}if(!n){break X}while(1){q=L[d>>3];B=L[c>>3];L[d>>3]=q*m+h*B;L[c>>3]=B*m-h*q;q=L[d+8>>3];B=L[c+8>>3];L[d+8>>3]=q*m+h*B;L[c+8>>3]=B*m-h*q;c=c+16|0;d=d+16|0;b=b-2|0;if(b){continue}break}}q=k-e;e=C+x;if((l|0)!=(z|0)){continue}break}}b=u+H|0;G[b>>2]=0;G[b+4>>2]=0;L[Q>>3]=e;L[w>>3]=q;g=g+1|0;continue}break}break}G[J+52>>2]=63704;G[J+48>>2]=66042;_a(G[24367],90100,J+48|0);break v}G[J+20>>2]=65829;G[J+16>>2]=66133;_a(G[24367],90100,J+16|0);break v}Z:{if(!f){break Z}g=f-1|0;h=0;j=f&3;_:{if(!j){b=f;c=t;break _}d=0;b=f;c=t;while(1){e=L[c>>3];h=e>h?e:h;c=c+8|0;b=b-1|0;d=d+1|0;if((j|0)!=(d|0)){continue}break}}if(g>>>0>=3){while(1){e=L[c+24>>3];k=L[c+16>>3];m=L[c+8>>3];q=L[c>>3];h=hk?e:k;c=c+32|0;b=b-4|0;if(b){continue}break}}if(!f){break Z}e=h*1e-11;c=t;b=f;j=b&3;if(j){d=0;while(1){if(e>L[c>>3]){G[c>>2]=0;G[c+4>>2]=0}b=b-1|0;c=c+8|0;d=d+1|0;if((j|0)!=(d|0)){continue}break}}if(g>>>0>2){while(1){if(e>L[c>>3]){G[c>>2]=0;G[c+4>>2]=0}if(e>L[c+8>>3]){G[c+8>>2]=0;G[c+12>>2]=0}if(e>L[c+16>>3]){G[c+16>>2]=0;G[c+20>>2]=0}b=b-4|0;if(e>L[c+24>>3]){G[c+24>>2]=0;G[c+28>>2]=0}c=c+32|0;if(b){continue}break}}if(!f){break Z}n=f&3;l=f<<3;o=f-1>>>0<3;j=f;g=P;while(1){j=j-1|0;k=L[t>>3];$:{if(k!=0){x=0/k;if(!f){break $}i=0;h=0;d=f;c=D;b=s;if(n){while(1){d=d-1|0;h=L[b>>3]*L[c>>3]+h;c=c+8|0;b=b+8|0;i=i+1|0;if((n|0)!=(i|0)){continue}break}}if(!o){while(1){h=L[b+24>>3]*L[c+24>>3]+(L[b+16>>3]*L[c+16>>3]+(L[b+8>>3]*L[c+8>>3]+(L[b>>3]*L[c>>3]+h)));c=c+32|0;b=b+32|0;d=d-4|0;if(d){continue}break}}s=l+s|0;x=h/k;break $}s=l+s|0;x=0}L[g>>3]=x;t=t+8|0;g=g+8|0;if(j){continue}break}}if((f|0)>0){n=f&3;g=0;o=f-1>>>0<3;while(1){h=0;d=f;c=P;b=v;i=0;if(n){while(1){d=d-1|0;h=L[b>>3]*L[c>>3]+h;c=c+8|0;b=(f<<3)+b|0;i=i+1|0;if((n|0)!=(i|0)){continue}break}}if(!o){while(1){j=f<<3;l=j+b|0;i=j+l|0;t=i+j|0;h=L[t>>3]*L[c+24>>3]+(L[i>>3]*L[c+16>>3]+(L[l>>3]*L[c+8>>3]+(L[b>>3]*L[c>>3]+h)));b=j+t|0;c=c+32|0;d=d-4|0;if(d){continue}break}}L[(g<<3)+D>>3]=h;v=v+8|0;g=g+1|0;if((g|0)!=(f|0)){continue}break}}Wa(P);Wa(H);Fa=J- -64|0;break u}ca(-1);W()}Wa(U);Wa($)}Fa=S+32|0;break r}G[S+4>>2]=65768;G[S>>2]=66133;_a(G[24367],90100,S);break a}G[S+20>>2]=65790;G[S+16>>2]=66133;_a(G[24367],90100,S+16|0);break a}Wa(y);if(f){bb(G[a+4>>2],D,f<<3)}Wa(D);Fa=F+80|0;return}ca(-1);W()}function pf(a,b,c,d,e,f,g){var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,H=0,I=0,J=0,K=0,N=0,P=0,S=0,T=0,U=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Ga=0,Ha=0,Ia=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0;q=Fa-32|0;Fa=q;if(!(!a|!G[a+3312>>2])){G[g>>2]=0;L[q+16>>3]=c;L[q+24>>3]=b;n=G[a+3264>>2];a:{if((n|0)!=-90){if((n|0)!=90){break a}L[q+16>>3]=90-c;break a}L[q+16>>3]=c+-90}b:{if(!d){s=G[a+3964>>2];h=L[a+120>>3];break b}s=Nf(d);h=Zh(d)}G[a+592>>2]=0;G[a+596>>2]=1072693248;c:{if((s|0)<=0){break c}d:{switch(s-6|0){case 0:case 4:break c;default:break d}}Bm(s,G[a+3964>>2],h,L[a+120>>3],q+24|0,q+16|0,L[a+128>>3])}e:{f:{g:{h:{i:{j:{k:{d=G[a+3260>>2];switch(d-31|0){case 3:break h;case 2:break i;case 1:break j;case 0:break k;default:break g}}l=L[q+24>>3];i=L[q+16>>3];G[q+8>>2]=0;G[q+12>>2]=0;G[q>>2]=0;G[q+4>>2]=0;h=L[a+160>>3];i=i*3.141592653589793/180;j=eb(i);m=ib(i);if(h==0){h=L[a+8>>3]*3.141592653589793/180;L[a+160>>3]=h}i=L[a+152>>3];k=eb(h);h=ib(h);if(i==0){i=L[a+8>>3]*3.141592653589793/180;L[a+152>>3]=i}d=1;l=l*3.141592653589793/180-i;p=eb(l);i=m*h+j*k*p;l:{if(i==0){break l}o=ib(l);l=L[a+168>>3];if(l==0){break l}ga=(m*k-h*j*p)*206264.8062470964/i;h=ga/l;ha=j*o*206264.8062470964/i;i=ha/l;ia=L[a+472>>3];ka=ia*3;z=L[a+512>>3];la=z*4;D=L[a+496>>3];S=D*3;C=L[a+352>>3];ja=C*4;na=L[a+336>>3];xa=na*3;oa=L[a+312>>3];ya=oa*3;p=L[a+448>>3];za=L[a+432>>3];K=L[a+424>>3];o=L[a+288>>3];Aa=L[a+272>>3];T=L[a+264>>3];t=L[a+480>>3];Ba=t+t;N=L[a+440>>3];Ca=N+N;r=L[a+504>>3];Da=r+r;v=L[a+488>>3];Ea=v+v;U=L[a+464>>3];X=U+U;aa=L[a+456>>3];Ga=aa+aa;B=L[a+344>>3];Ha=B+B;F=L[a+328>>3];Ia=F+F;Y=L[a+296>>3];Ka=Y+Y;x=L[a+320>>3];La=x+x;Z=L[a+304>>3];ba=Z+Z;_=L[a+280>>3];Ma=_+_;ca=L[a+416>>3];da=L[a+256>>3];d=0;while(1){m:{j=h*h;m=i*i;l=j+m;pa=l*l;qa=h*j;ra=j*i;sa=h*m;ta=i*m;k=h*i;P=i*C*pa+(i*B*l+(na*qa+(F*ra+(x*sa+(oa*ta+(Z*l+(Y*j+(o*k+(_*m+(Aa+(da*i+h*T)))))))))))-ha;$=j*j;ea=m*m;fa=j*(m*6);ua=C*($+(ea*5+fa))+(B*(m*3+j)+(F*j+(La*k+(ya*m+(ba*i+(o*h+(Ma*i+da)))))));ea=z*(ea+($*5+fa))+(r*(j*3+m)+(v*m+(Ba*k+(ka*j+(X*h+(p*i+(Ca*h+ca)))))));fa=k*la*l+(Da*k+(S*m+(Ea*k+(t*j+(X*i+(Ga*i+(p*h+K)))))));va=k*ja*l+(Ha*k+(xa*j+(Ia*k+(x*m+(ba*h+(Ka*h+(o*i+T)))))));$=ua*ea-fa*va;j=h*z*pa+(h*r*l+(D*ta+(v*sa+(t*ra+(ia*qa+(U*l+(aa*m+(p*k+(N*j+(za+(ca*h+i*K)))))))))))-ga;m=(P*fa-j*ua)/$;h=h+m;j=(va*j-P*ea)/$;i=i+j;if(O(j)<5e-7&O(m)<5e-7){break m}d=d+1|0;if((d|0)!=50){continue}}break}d=1;j=L[a+192>>3];if(j==0){break l}m=L[a+200>>3];if(m==0){break l}k=L[a+248>>3];L[q+8>>3]=(L[a+224>>3]-i*1e3)/j-L[a+176>>3]+1+-.5;h=(k+h*1e3)/m-L[a+184>>3]+1+-.5;L[q>>3]=h;d=-1;i=L[q+8>>3];if(i<.5|i>L[a+136>>3]+.5|(h<.5|h>L[a+144>>3]+.5)){break l}d=0}if(d){break f}break e}h=L[q+24>>3];d=0;n=G[a+3272>>2];u=G[a+3268>>2];i=Mc(L[q+16>>3]*3.141592653589793/180);m=h*3.141592653589793/180-L[a+688>>3]*3.141592653589793/180;j=eb(m);k=L[a+696>>3]*3.141592653589793/180;h=Mc(k);l=L[a+112>>3];o=h;h=(1-h*j/i)/(h+j/i);K=Mc(m)*eb(k)*(1-o*h)*180/3.141592653589793;T=h*180/3.141592653589793;h=K*L[a+104>>3]+l*T;i=K*L[a+88>>3]+L[a+96>>3]*T;B=L[a+456>>3];N=L[a+432>>3];U=L[a+424>>3];F=L[a+296>>3];X=L[a+272>>3];aa=L[a+264>>3];Y=L[a+448>>3];$=Y+Y;Z=L[a+440>>3];ga=Z+Z;ba=L[a+288>>3];ha=ba+ba;_=L[a+280>>3];ia=_+_;ka=L[a+416>>3];la=L[a+256>>3];s=(u|0)<7;u=u>>>0<9;while(1){p=F*i+(ha*h+X);l=h*i;m=h*h;k=i*i;o=F*l+(ba*m+(_*k+(X*h+(aa*i+la))));t=m+k;ca=m*i;da=h*k;z=h*m;C=i*k;j=F*h+(ia*i+aa);n:{if(s){break n}r=L[a+312>>3];v=L[a+304>>3];o=r*z+(v*C+o);p=r*3*m+p;D=v*3*k+j;j=D;if(u){break n}j=L[a+352>>3];r=L[a+344>>3];P=L[a+336>>3];S=P+P;v=L[a+328>>3];x=L[a+320>>3];p=j*(m*3+k)+((r+r)*l+(S*h+((v+v)*l+(x*k+p))));o=h*j*t+(i*r*t+(P*t+(v*ca+(x*da+o))));j=(j+j)*l+(r*(k*3+m)+(S*i+(v*m+((x+x)*l+D))))}r=B*i+($*h+N);v=B*l+(Y*m+(Z*k+(N*h+(U*i+ka))));D=o-K;o=B*h+(ga*i+U);o:{if((n|0)<7){break o}x=L[a+472>>3];S=x*z;z=L[a+464>>3];v=S+(z*C+v);r=x*3*m+r;S=z*3*k+o;o=S;if(n>>>0<9){break o}o=L[a+512>>3];x=L[a+504>>3];P=L[a+496>>3];ja=P+P;z=L[a+488>>3];C=L[a+480>>3];r=o*(m*3+k)+((x+x)*l+(ja*h+((z+z)*l+(C*k+r))));v=h*o*t+(i*x*t+(P*t+(z*ca+(C*da+v))));o=(o+o)*l+(x*(k*3+m)+(ja*i+(z*m+((C+C)*l+S))))}m=v-T;v=D*o-m*j;j=j*r-o*p;k=v/j;h=h+k;j=(p*m-D*r)/j;i=i+j;if(!(O(j)<5e-7&O(k)<5e-7)){d=d+1|0;if((d|0)!=50){continue}}break}L[q+8>>3]=i+L[a+616>>3];h=h+L[a+624>>3];L[q>>3]=h;d=-1;i=L[q+8>>3];if(!(i<.5|i>L[a+136>>3]+.5|(h<.5|h>L[a+144>>3]+.5))){d=0}if(d){break f}break e}k=L[q+24>>3];n=a+688|0;d=G[a+3304>>2];l=L[n+(((d|0)!=0)<<3)>>3];m=L[n+(!d<<3)>>3];h=L[a+3176>>3];i=L[q+16>>3]*3.141592653589793/180;t=ib(i);j=eb(i);m=(90-m)*3.141592653589793/180;r=ib(m);v=eb(m);k=(k-l)*3.141592653589793/180;o=ib(k);D=h!=999?h*3.141592653589793/180:3.141592653589793;l=eb(k);h=j*v;p=t*r-l*h;if(O(p)<1e-5){p=h*(1-l)-eb(i+m)}o=o*-j;p:{if(!(p==0&o==0)){h=Db(o,p);break p}h=k+-3.141592653589793}h=D+h;q:{if(h>3.141592653589793){h=h+-6.283185307179586;break q}if(!(h<-3.141592653589793)){break q}h=h+6.283185307179586}r:{if(Yc(k,3.141592653589793)==0){i=l*m+i;k=i>1.5707963267948966?3.141592653589793-i:i;if(!(k<-1.5707963267948966)){break r}k=-3.141592653589793-k;break r}i=t*v+l*(j*r);if(O(i)>.99){k=Sc(V(p*p+o*o));if(i>=0){break r}k=-k;break r}k=fc(i)}l=0;i=ib(k);j=0;s:{if(i==0){break s}i=L[a+3192>>3]*eb(k)/i;if(!(G[a+6040>>2]|G[a+6044>>2])){j=ib(h);h=eb(h)*-i;i=j*i;l=d?h:i;j=d?i:h;break s}j=eb(h);d=0;r=ib(h)*i;h=r;v=j*-i;j=v;while(1){l=1;k=0;i=h;n=G[a+6040>>2];if(n){i=Ee(n,h,j);l=qf(G[a+6040>>2],h,j,1,0)+1;k=qf(G[a+6040>>2],h,j,0,1);i=h+i}n=G[a+6044>>2];t:{if(!n){p=1;t=0;m=j;break t}m=Ee(n,h,j);t=qf(G[a+6044>>2],h,j,1,0);p=qf(G[a+6044>>2],h,j,0,1)+1;m=j+m}o=l*p-t*k;u:{if(o==0){break u}i=i-r;m=m-v;l=(i*t-m*l)/o;j=j+l;k=(k*m-i*p)/o;h=h+k;k=O(k);l=O(l);k=k>l?k:l;i=O(i);m=O(m);i=i>m?i:m;if((i>2];l=d?j:h;j=d?h:j}v:{w:{if(G[a+3300>>2]){L[q+8>>3]=l*L[a+88>>3]+j*L[a+96>>3];h=l*L[a+104>>3]+j*L[a+112>>3];break w}h=L[a+48>>3];x:{if(h!=0){i=h*3.141592653589793/180;h=ib(i);i=eb(i);L[q+8>>3]=l*i+j*h;j=j*i-h*l;break x}L[q+8>>3]=l}L[q>>3]=j;h=L[a+32>>3];if(h!=0){L[q+8>>3]=L[q+8>>3]/h}h=L[a+40>>3];if(h==0){break v}h=L[q>>3]/h}L[q>>3]=h}L[q+8>>3]=L[q+8>>3]+L[a+16>>3];L[q>>3]=L[q>>3]+L[a+24>>3];break e}k=L[q+24>>3];n=a+688|0;d=G[a+3304>>2];l=L[n+(((d|0)!=0)<<3)>>3];m=L[n+(!d<<3)>>3];j=L[a+3176>>3];h=L[q+16>>3]*3.141592653589793/180;t=ib(h);i=eb(h);m=(90-m)*3.141592653589793/180;r=ib(m);v=eb(m);k=(k-l)*3.141592653589793/180;o=ib(k);D=j!=999?j*3.141592653589793/180:3.141592653589793;p=eb(k);j=i*v;l=t*r-p*j;if(O(l)<1e-5){l=j*(1-p)-eb(h+m)}o=o*-i;y:{if(!(l==0&o==0)){j=Db(o,l);break y}j=k+-3.141592653589793}j=D+j;z:{if(j>3.141592653589793){j=j+-6.283185307179586;break z}if(!(j<-3.141592653589793)){break z}j=j+6.283185307179586}A:{if(Yc(k,3.141592653589793)==0){h=p*m+h;h=h>1.5707963267948966?3.141592653589793-h:h;if(!(h<-1.5707963267948966)){break A}h=-3.141592653589793-h;break A}i=t*v+p*(i*r);if(O(i)>.99){h=Sc(V(l*l+o*o));if(i>=0){break A}h=-h;break A}h=fc(i)}h=1.5707963267948966-h;i=((((((((((h*0+L[a+4248>>3])*h+L[a+4240>>3])*h+L[a+4232>>3])*h+L[a+4224>>3])*h+L[a+4216>>3])*h+L[a+4208>>3])*h+L[a+4200>>3])*h+L[a+4192>>3])*h+L[a+4184>>3])*h+L[a+4176>>3])*L[a+3192>>3];B:{if(!(G[a+6040>>2]|G[a+6044>>2])){h=ib(j);j=eb(j)*-i;h=h*i;k=d?j:h;h=d?h:j;break B}m=eb(j);d=0;r=ib(j)*i;h=r;v=m*-i;j=v;while(1){k=0;i=h;p=1;l=0;n=G[a+6040>>2];if(n){i=Ee(n,h,j);p=qf(G[a+6040>>2],h,j,1,0)+1;l=qf(G[a+6040>>2],h,j,0,1);i=h+i}n=G[a+6044>>2];C:{if(!n){t=1;m=j;break C}m=Ee(n,h,j);k=qf(G[a+6044>>2],h,j,1,0);t=qf(G[a+6044>>2],h,j,0,1)+1;m=j+m}o=p*t-k*l;D:{if(o==0){break D}i=i-r;m=m-v;k=(i*k-m*p)/o;j=j+k;l=(l*m-i*t)/o;h=h+l;l=O(l);k=O(k);k=km?i:m;if((i>2];k=d?j:h;h=d?h:j}E:{F:{if(G[a+3300>>2]){L[q+8>>3]=k*L[a+88>>3]+h*L[a+96>>3];h=k*L[a+104>>3]+h*L[a+112>>3];break F}i=L[a+48>>3];G:{if(i!=0){j=i*3.141592653589793/180;i=ib(j);j=eb(j);L[q+8>>3]=k*j+h*i;h=h*j-i*k;break G}L[q+8>>3]=k}L[q>>3]=h;h=L[a+32>>3];if(h!=0){L[q+8>>3]=L[q+8>>3]/h}h=L[a+40>>3];if(h==0){break E}h=L[q>>3]/h}L[q>>3]=h}L[q+8>>3]=L[q+8>>3]+L[a+16>>3];L[q>>3]=L[q>>3]+L[a+24>>3];break e}h=L[q+16>>3];i=L[q+24>>3];if(!(G[a+3324>>2]!=2&(d|0)>0)){m=h;h=0;n=G[a+3260>>2];x=L[a+40>>3];v=L[a+32>>3];U=L[a+24>>3];T=L[a+16>>3];F=L[a+8>>3];K=L[a>>3];N=L[a+48>>3]*3.141592653589793/180;z=ib(N);C=eb(N);if((n|0)<=0){k=0}else{d=G[a+3304>>2];j=d?F:K;k=i-j;h=(d?K:F)*3.141592653589793/180;l=j*3.141592653589793/180;o=m*3.141592653589793/180;j=eb(o);p=T*v;H:{if(p>180|p<-180){i=k>360?i+-360:i;if(!(k<0)){break H}i=i+360;break H}i=k>180?i+-360:i;if(!(k<-180)){break H}i=i+360}r=i*3.141592653589793/180;k=r-l;p=j*ib(k);X=eb(h);k=eb(k);B=ib(o);k=B*ib(h)+k*(j*X)}I:{J:{K:{switch(n-3|0){case 8:t=o-h;p=r-l;break J;case 1:d=1;if(k<0){break I}k=ib(h);l=eb(r-l);t=B*eb(h)-l*(k*j);break J;case 0:case 30:case 31:case 32:d=1;if(k<=0){break I}k=eb(h);l=eb(r-l);o=ib(h);h=B*o+l*(j*k);t=(B*k-l*(o*j))/h;p=p/h;break J;case 3:k=eb(h);o=eb(r-l);l=1;t=ib(h);h=Sc(Q(R(B*t+o*(j*k),-1),1));if(h!=0){l=h/ib(h)}t=(B*k-t*j*o)*l;p=p*l;break J;case 26:d=1;if(h==0){break I}k=eb(r-l);t=(eb(h)-j*k)/ib(h);break J;case 17:case 27:d=1;if(O(o)>1.5707963267948974|O(h)>1.5707963267948974){break I}t=o-h;p=j*(r-l);break J;case 9:d=2;h=Mc(o*.5+.7853981633974487);if(h<1e-5){break I}j=x*C+v*z;j=j==0?1:j;k=(F*.5+45)*3.141592653589793/180;p=oc(Mc(j*.5*.01745329252+k));o=j*3.141592653589793/180;j=oc(Mc(k));k=o/(p-j);t=k*oc(h)-j*k;h=eb(F*3.141592653589793/180);p=(h<=0?1:h)*(r-l);break J;case 19:d=1;j=(r-l)*.5;if(O(j)>1.5707963267948974){break I}d=3;p=eb(o);k=V((p*eb(j)+1)*.5);if(O(k)<1e-5){break I}l=F*3.141592653589793/180;h=x*C+v*z;t=h==0?.017453292519943295:h*3.141592653589793/180;h=l+t;r=eb(h);B=ib(h);h=eb(l);D=t;l=ib(l);t=V((h+1)*.5);r=B/V((r+1)*.5)-l/t;r=D/(r==0?1:r);t=r*ib(o)/k-l*r/t;l=v*C-z*x;o=l==0?.017453292519943295:l*3.141592653589793/180;r=o*.5;l=ib(r)*(h+h);h=o*V((h*eb(r)+1)*.5)/(l==0?1:l);p=(h+h)*p*ib(j)/k;break J;case 2:d=1;if(O(o)>1.5707963267948974){break I}k=eb(h);l=eb(r-l);h=ib(h);o=j*k*l+(B*h+1);if(O(o)<1e-5){break I}o=2/o;t=o*(B*k-h*j*l);p=p*o;break J;case 13:break K;default:break J}}k=Mc(h);p=k*-2;j=p*p;l=ib(h)*(l-r);t=l*l;D=l;l=1/k;h=o-h;r=h;h=k*k;k=k/3;o=p*-.25;k=l*(r*(r*(r*(r*(j*j*-.0390625+(h*.1875*j+(h*-.125*h+k*o)))+(k*.5+(o*h+p*j*.0625)))+(j*-.125+h*.5))+p*.5)+1);h=(t/-6+1)*(D*k);L:{if(G[a+3300>>2]){j=L[a+56>>3];j=j/O(j);break L}j=h;h=v/O(v)}p=h*j;t=l-k*(t*-.5+1)}M:{if((n|0)>0){j=p*180/3.141592653589793;h=t*180/3.141592653589793;break M}j=i-K;h=m-F}d=G[a+3304>>2];i=d?h:j;h=d?j:h;N:{if(G[a+3300>>2]){j=i*L[a+104>>3]+h*L[a+112>>3];i=i*L[a+88>>3]+h*L[a+96>>3];break N}O:{if(N==0){j=h;break O}j=h*C-z*i;i=i*C+z*h}i=i/(v!=0?v:1);if(x==0){break N}j=j/x}h=T+i;L[q+8>>3]=h;P:{if((n|0)!=11){break P}m=L[a+136>>3];Q:{if(m0){break Q}break P}if(!(h<0)){break P}i=360/v+h;if(!(m>=i)){break P}}L[q+8>>3]=i}L[q>>3]=U+j;d=0}if(d){break f}break e}d=Fa-112|0;Fa=d;G[q+8>>2]=0;G[q+12>>2]=0;G[q>>2]=0;G[q+4>>2]=0;u=a+4004|0;R:{if(G[a+4004>>2]!=137){s=1;if(sj(G[a+4040>>2],a+3368|0,u)){break R}}G[d+104>>2]=0;G[d+108>>2]=0;G[d+96>>2]=0;G[d+100>>2]=0;G[d+88>>2]=0;G[d+92>>2]=0;G[d+80>>2]=0;G[d+84>>2]=0;y=d+80|0;L[y+(G[a+4024>>2]<<3)>>3]=i;L[y+(G[a+4028>>2]<<3)>>3]=h;G[d+16>>2]=0;G[d+20>>2]=0;G[d+24>>2]=0;G[d+28>>2]=0;G[d+40>>2]=0;G[d+44>>2]=1072693248;G[d+32>>2]=0;G[d+36>>2]=1072693248;G[d+48>>2]=0;G[d+52>>2]=0;G[d+56>>2]=0;G[d+60>>2]=0;G[d+72>>2]=0;G[d+76>>2]=1072693248;G[d+64>>2]=0;G[d+68>>2]=1072693248;W=a+3368|0;H=a+688|0;s=a+4064|0;w=a+4144|0;A=d+48|0;J=a+4036|0;Na=d+16|0;S:{if(G[u>>2]!=137){n=1;if(sj(G[J+4>>2],W,u)){break S}}W=G[J+4>>2];T:{if((W|0)<=0){break T}ma=G[u+20>>2];n=0;if((W|0)!=1){Oa=W&-2;while(1){if(!((n|0)==(ma|0)|G[u+24>>2]==(n|0))){I=n<<3;L[I+A>>3]=L[y+I>>3]-L[H+I>>3]}I=n|1;if(!((I|0)==(ma|0)|(I|0)==G[u+24>>2])){I=I<<3;L[I+A>>3]=L[y+I>>3]-L[H+I>>3]}n=n+2|0;wa=wa+2|0;if((Oa|0)!=(wa|0)){continue}break}}if(!(W&1)|(n|0)==(ma|0)|G[u+24>>2]==(n|0)){break T}n=n<<3;L[n+A>>3]=L[n+y>>3]-L[n+H>>3]}U:{if(G[u>>2]==999){break U}H=u+4|0;if(!Xa(H,34233)){n=2;if(L[s+16>>3]==0){break S}E[H|0]=83;E[H+1|0]=73;E[H+2|0]=78;E[H+3|0]=0;G[w+40>>2]=0;G[w+44>>2]=0;Pa=w,Qa=Mb(L[s+16>>3])/Kb(L[s+16>>3]),L[Pa+48>>3]=Qa;G[w+4>>2]=G[w+4>>2]>>31}n=G[u+20>>2]<<3;h=L[n+y>>3];I=y;y=G[u+24>>2]<<3;i=L[I+y>>3];W=n+A|0;y=A+y|0;V:{W:{if(G[s>>2]!=137){n=1;if(um(H,s,w)){break W}}j=Mb(i);t=Kb(i);k=h-L[s+40>>3];m=Mb(k);l=Kb(k);h=t*L[s+72>>3]-m*(j*L[s+64>>3]);if(O(h)<1e-5){h=Mb(L[s+48>>3]+i);h=j*L[s+64>>3]*(1-m)-h}l=l*-j;X:{if(!(h==0&l==0)){o=Ac(l,h);break X}o=k+-180}p=o+L[s+56>>3];L[d+8>>3]=p;o=-360;Y:{if(!(p>180)){o=360;if(!(p<-180)){break Y}}L[d+8>>3]=p+o}Z:{_:{if(Yc(k,180)==0){h=m*L[s+48>>3]+i;h=h>90?180-h:h;L[d>>3]=h;if(!(h<-90)){break Z}h=-180-h;break _}i=t*L[s+64>>3]+m*(j*L[s+72>>3]);if(O(i)>.99){h=Yg(V(h*h+l*l));if(!(i<0)){break _}h=-h;break _}h=Bc(i)}L[d>>3]=h}s=Ja[G[w+1888>>2]](L[d+8>>3],L[d>>3],w,W,y)|0;n=0;if(!s){break V}n=(s|0)==1?2:3}}if(n){break S}n=G[u+28>>2];if((n|0)==-1){break U}s=A+(n<<3)|0;n=A+(G[u+24>>2]<<3)|0;i=L[n>>3];h=L[w+24>>3];h=h==0?90:h*3.141592653589793*.5;$:{if(i>3]=i+h;i=5;break $}m=h*.5;if(m>3]=i-h;i=0;break $}n=A+(G[u+20>>2]<<3)|0;j=L[n>>3];if(j>h*2.5){L[n>>3]=h*-3+j;i=4;break $}if(j>h*1.5){L[n>>3]=j-(h+h);i=3;break $}i=1;if(!(j>m)){break $}L[n>>3]=j-h;i=2}L[s>>3]=i}n=((zj(A,J,Na)|0)!=0)<<2}s=n;if(n){break R}L[q+8>>3]=L[d+16>>3];L[q>>3]=L[d+24>>3];h=L[d+32>>3];L[a+592>>3]=G[a+3260>>2]-24>>>0<3?h+-1:h;s=0}Fa=d+112|0;if(!s){break e}}G[g>>2]=1}k=L[q>>3];l=L[q+8>>3];d=G[a+9392>>2];aa:{if(d){pf(d,l,k,0,e,f,g);d=G[g>>2];break aa}d=0;h=0;i=0;A=Fa-80|0;ba:{if(G[a+6048>>2]==1){j=k-L[a+24>>3];m=l-L[a+16>>3];w=G[a+8480>>2];n=G[a+7672>>2];ca:{if((n|0)<0){break ca}while(1){y=M(n-d|0,80)+a|0;u=d<<3;h=L[(y+u|0)+7680>>3];H=u+A|0;u=d;da:{if(!d){break da}s=0;J=u&3;if(J){while(1){d=d-1|0;h=j*h+L[(y+(d<<3)|0)+7680>>3];s=s+1|0;if((J|0)!=(s|0)){continue}break}}if(u-1>>>0<3){break da}while(1){J=y+7680|0;s=J+(d<<3)|0;h=j*(j*(j*(j*h+L[s-8>>3])+L[s-16>>3])+L[s-24>>3]);s=d-4|0;h=h+L[J+(s<<3)>>3];J=(d|0)>4;d=s;if(J){continue}break}}L[H>>3]=h;d=u+1|0;if((n|0)!=(u|0)){continue}break}h=L[A>>3];if((n|0)<=0){i=h;break ca}u=n-1|0;d=n+1|0;y=n&3;ea:{if(!y){i=h;break ea}s=0;i=h;while(1){i=m*i+L[A+(d-n<<3)>>3];n=n-1|0;s=s+1|0;if((y|0)!=(s|0)){continue}break}}if(u>>>0<3){break ca}while(1){u=A+(d-n<<3)|0;i=m*(m*(m*(m*i+L[u>>3])+L[u+8>>3])+L[u+16>>3]);u=n-3|0;i=i+L[A+(d-u<<3)>>3];n=n-4|0;if(u>>>0>1){continue}break}}L[e>>3]=i;d=0;fa:{if((w|0)<0){break fa}while(1){y=M(w-d|0,80)+a|0;n=d<<3;h=L[(y+n|0)+8488>>3];H=n+A|0;n=d;ga:{if(!d){break ga}s=0;u=n&3;if(u){while(1){d=d-1|0;h=j*h+L[(y+(d<<3)|0)+8488>>3];s=s+1|0;if((u|0)!=(s|0)){continue}break}}if(n-1>>>0<3){break ga}while(1){s=y+8488|0;u=s+(d<<3)|0;h=j*(j*(j*(j*h+L[u-8>>3])+L[u-16>>3])+L[u-24>>3]);u=d-4|0;h=h+L[s+(u<<3)>>3];s=(d|0)>4;d=u;if(s){continue}break}}L[H>>3]=h;d=n+1|0;if((n|0)!=(w|0)){continue}break}h=L[A>>3];if((w|0)<=0){break fa}n=w-1|0;d=w+1|0;u=w&3;if(u){s=0;while(1){h=m*h+L[A+(d-w<<3)>>3];w=w-1|0;s=s+1|0;if((u|0)!=(s|0)){continue}break}}if(n>>>0<3){break fa}while(1){n=A+(d-w<<3)|0;h=m*(m*(m*(m*h+L[n>>3])+L[n+8>>3])+L[n+16>>3]);n=w-3|0;h=h+L[A+(d-n<<3)>>3];w=w-4|0;if(n>>>0>1){continue}break}}L[f>>3]=h;L[e>>3]=L[e>>3]+l;L[f>>3]=L[f>>3]+k;break ba}L[e>>3]=l;L[f>>3]=k}d=G[g>>2];if(d){break aa}h=L[e>>3];ha:{if(h<.5){break ha}i=L[f>>3];if(i<.5|h>L[a+136>>3]+.5){break ha}d=0;if(!(i>L[a+144>>3]+.5)){break aa}}d=2;G[g>>2]=2}L[a+608>>3]=c;L[a+600>>3]=b;G[a+3308>>2]=d;L[a+576>>3]=L[e>>3];L[a+584>>3]=L[f>>3]}Fa=q+32|0}function li(a,b,c,d,e,f,g,h){var i=0,j=0,k=0,l=0;a:{b:{c:{d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{p:{q:{r:{s:{t:{u:{v:{w:{x:{y:{switch(e-11|0){case 3:z:{switch(a-11|0){default:if((a|0)!=82){break x}if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){E[a+g|0]=L[(a<<3)+b>>3]!=0;i=a|1;E[i+g|0]=L[(i<<3)+b>>3]!=0;i=a|2;E[i+g|0]=L[(i<<3)+b>>3]!=0;i=a|3;E[i+g|0]=L[(i<<3)+b>>3]!=0;a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break e}while(1){E[a+g|0]=L[(a<<3)+b>>3]!=0;a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break e;case 31:if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){E[a+g|0]=K[(a<<2)+b>>2]!=N(0);i=a|1;E[i+g|0]=K[(i<<2)+b>>2]!=N(0);i=a|2;E[i+g|0]=K[(i<<2)+b>>2]!=N(0);i=a|3;E[i+g|0]=K[(i<<2)+b>>2]!=N(0);a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break e}while(1){E[a+g|0]=K[(a<<2)+b>>2]!=N(0);a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break e;case 30:if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){E[a+g|0]=G[(a<<2)+b>>2]!=0;i=a|1;E[i+g|0]=G[(i<<2)+b>>2]!=0;i=a|2;E[i+g|0]=G[(i<<2)+b>>2]!=0;i=a|3;E[i+g|0]=G[(i<<2)+b>>2]!=0;a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break e}while(1){E[a+g|0]=G[(a<<2)+b>>2]!=0;a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break e;case 10:if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){E[a+g|0]=I[(a<<1)+b>>1]!=0;i=a|1;E[i+g|0]=I[(i<<1)+b>>1]!=0;i=a|2;E[i+g|0]=I[(i<<1)+b>>1]!=0;i=a|3;E[i+g|0]=I[(i<<1)+b>>1]!=0;a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break e}while(1){E[a+g|0]=I[(a<<1)+b>>1]!=0;a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break e;case 1:case 2:case 4:case 5:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break x;case 0:case 3:break z}}if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){E[a+g|0]=H[a+b|0]!=0;i=a|1;E[i+g|0]=H[b+i|0]!=0;i=a|2;E[i+g|0]=H[b+i|0]!=0;i=a|3;E[i+g|0]=H[b+i|0]!=0;a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break e}while(1){E[a+g|0]=H[a+b|0]!=0;a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break e;case 0:A:{switch(a-11|0){case 30:a=0;if((d|0)<=0){break d}while(1){B:{if(H[a+c|0]){E[a+g|0]=H[f|0];G[h>>2]=1;break B}e=G[(a<<2)+b>>2];if((e|0)<0){G[309737]=-11;E[a+g|0]=0;break B}if(e>>>0>=256){G[309737]=-11;E[a+g|0]=255;break B}E[a+g|0]=e}a=a+1|0;if((d|0)!=(a|0)){continue}break};break d;case 31:tp(b,d,1,0,0,0,0,0,g,1238948);break f;default:if((a|0)==82){break i}break;case 1:case 2:case 4:case 5:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break A;case 0:case 3:break g;case 10:break h}}G[309737]=410;break f;case 10:C:{switch(a-11|0){case 30:a=0;if((d|0)<=0){break d}while(1){D:{if(H[a+c|0]){F[(a<<1)+g>>1]=I[f>>1];G[h>>2]=1;break D}e=G[(a<<2)+b>>2];if((e|0)<=-32769){G[309737]=-11;F[(a<<1)+g>>1]=32768;break D}if((e|0)>=32768){G[309737]=-11;F[(a<<1)+g>>1]=32767;break D}F[(a<<1)+g>>1]=e}a=a+1|0;if((d|0)!=(a|0)){continue}break};break d;case 31:Xk(b,d,1,0,0,0,0,0,g,1238948);break j;default:if((a|0)==82){break m}break;case 10:break k;case 0:case 3:break l;case 1:case 2:case 4:case 5:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break C}}G[309737]=410;break j;case 20:E:{switch(a-11|0){case 30:if((d|0)<=0){break d}a=0;if(d-1>>>0>=3){i=d&-4;e=0;while(1){k=a<<2;G[k+g>>2]=G[b+k>>2];l=k|4;G[l+g>>2]=G[b+l>>2];l=k|8;G[l+g>>2]=G[b+l>>2];k=k|12;G[k+g>>2]=G[b+k>>2];a=a+4|0;e=e+4|0;if((i|0)!=(e|0)){continue}break}}e=d&3;if(!e){break n}while(1){k=a<<2;G[k+g>>2]=G[b+k>>2];a=a+1|0;j=j+1|0;if((e|0)!=(j|0)){continue}break};break n;case 10:if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){G[(a<<2)+g>>2]=F[(a<<1)+b>>1];i=a|1;G[(i<<2)+g>>2]=F[(i<<1)+b>>1];i=a|2;G[(i<<2)+g>>2]=F[(i<<1)+b>>1];i=a|3;G[(i<<2)+g>>2]=F[(i<<1)+b>>1];a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break n}while(1){G[(a<<2)+g>>2]=F[(a<<1)+b>>1];a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break n;case 0:case 3:if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){G[(a<<2)+g>>2]=H[a+b|0];i=a|1;G[(i<<2)+g>>2]=H[b+i|0];i=a|2;G[(i<<2)+g>>2]=H[b+i|0];i=a|3;G[(i<<2)+g>>2]=H[b+i|0];a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break n}while(1){G[(a<<2)+g>>2]=H[a+b|0];a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break n;case 31:Rp(b,d,1,0,0,0,0,0,g,1238948);break n;default:if((a|0)==82){break o}break;case 1:case 2:case 4:case 5:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break E}}G[309737]=410;break n;case 30:F:{switch(a-11|0){case 30:if((d|0)<=0){break d}a=0;if(d-1>>>0>=3){i=d&-4;e=0;while(1){k=a<<2;G[k+g>>2]=G[b+k>>2];l=k|4;G[l+g>>2]=G[b+l>>2];l=k|8;G[l+g>>2]=G[b+l>>2];k=k|12;G[k+g>>2]=G[b+k>>2];a=a+4|0;e=e+4|0;if((i|0)!=(e|0)){continue}break}}e=d&3;if(!e){break p}while(1){k=a<<2;G[k+g>>2]=G[b+k>>2];a=a+1|0;j=j+1|0;if((e|0)!=(j|0)){continue}break};break p;case 10:if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){G[(a<<2)+g>>2]=F[(a<<1)+b>>1];i=a|1;G[(i<<2)+g>>2]=F[(i<<1)+b>>1];i=a|2;G[(i<<2)+g>>2]=F[(i<<1)+b>>1];i=a|3;G[(i<<2)+g>>2]=F[(i<<1)+b>>1];a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break p}while(1){G[(a<<2)+g>>2]=F[(a<<1)+b>>1];a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break p;case 0:case 3:if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){G[(a<<2)+g>>2]=H[a+b|0];i=a|1;G[(i<<2)+g>>2]=H[b+i|0];i=a|2;G[(i<<2)+g>>2]=H[b+i|0];i=a|3;G[(i<<2)+g>>2]=H[b+i|0];a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break p}while(1){G[(a<<2)+g>>2]=H[a+b|0];a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break p;case 31:al(b,d,1,0,0,0,0,0,g,1238948);break p;default:if((a|0)==82){break q}break;case 1:case 2:case 4:case 5:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break F}}G[309737]=410;break p;case 70:G:{switch(a-11|0){case 30:if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){i=(a<<3)+g|0;l=G[(a<<2)+b>>2];G[i>>2]=l;G[i+4>>2]=l>>31;i=a|1;l=(i<<3)+g|0;i=G[(i<<2)+b>>2];G[l>>2]=i;G[l+4>>2]=i>>31;i=a|2;l=(i<<3)+g|0;i=G[(i<<2)+b>>2];G[l>>2]=i;G[l+4>>2]=i>>31;i=a|3;l=(i<<3)+g|0;i=G[(i<<2)+b>>2];G[l>>2]=i;G[l+4>>2]=i>>31;a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break r}while(1){k=(a<<3)+g|0;i=G[(a<<2)+b>>2];G[k>>2]=i;G[k+4>>2]=i>>31;a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break r;case 10:if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){i=(a<<3)+g|0;l=F[(a<<1)+b>>1];G[i>>2]=l;G[i+4>>2]=l>>31;i=a|1;l=(i<<3)+g|0;i=F[(i<<1)+b>>1];G[l>>2]=i;G[l+4>>2]=i>>31;i=a|2;l=(i<<3)+g|0;i=F[(i<<1)+b>>1];G[l>>2]=i;G[l+4>>2]=i>>31;i=a|3;l=(i<<3)+g|0;i=F[(i<<1)+b>>1];G[l>>2]=i;G[l+4>>2]=i>>31;a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break r}while(1){k=(a<<3)+g|0;i=F[(a<<1)+b>>1];G[k>>2]=i;G[k+4>>2]=i>>31;a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break r;case 0:case 3:if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){i=(a<<3)+g|0;G[i>>2]=H[a+b|0];G[i+4>>2]=0;i=a|1;l=(i<<3)+g|0;G[l>>2]=H[b+i|0];G[l+4>>2]=0;i=a|2;l=(i<<3)+g|0;G[l>>2]=H[b+i|0];G[l+4>>2]=0;i=a|3;l=(i<<3)+g|0;G[l>>2]=H[b+i|0];G[l+4>>2]=0;a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break r}while(1){k=(a<<3)+g|0;G[k>>2]=H[a+b|0];G[k+4>>2]=0;a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break r;case 31:Zp(b,d,1,0,0,0,0,0,0,g,1238948);break r;default:if((a|0)==82){break s}break;case 1:case 2:case 4:case 5:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break G}}G[309737]=410;break r;case 31:H:{switch(a-11|0){case 31:if((d|0)<=0){break d}a=0;if(d-1>>>0>=3){i=d&-4;e=0;while(1){k=a<<2;K[k+g>>2]=K[b+k>>2];l=k|4;K[l+g>>2]=K[b+l>>2];l=k|8;K[l+g>>2]=K[b+l>>2];k=k|12;K[k+g>>2]=K[b+k>>2];a=a+4|0;e=e+4|0;if((i|0)!=(e|0)){continue}break}}e=d&3;if(!e){break t}while(1){k=a<<2;K[k+g>>2]=K[b+k>>2];a=a+1|0;j=j+1|0;if((e|0)!=(j|0)){continue}break};break t;case 30:if((d|0)<=0){break d}a=0;if(d-1>>>0>=3){i=d&-4;e=0;while(1){k=a<<2;K[k+g>>2]=G[b+k>>2];l=k|4;K[l+g>>2]=G[b+l>>2];l=k|8;K[l+g>>2]=G[b+l>>2];k=k|12;K[k+g>>2]=G[b+k>>2];a=a+4|0;e=e+4|0;if((i|0)!=(e|0)){continue}break}}e=d&3;if(!e){break t}while(1){k=a<<2;K[k+g>>2]=G[b+k>>2];a=a+1|0;j=j+1|0;if((e|0)!=(j|0)){continue}break};break t;case 10:if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){K[(a<<2)+g>>2]=F[(a<<1)+b>>1];i=a|1;K[(i<<2)+g>>2]=F[(i<<1)+b>>1];i=a|2;K[(i<<2)+g>>2]=F[(i<<1)+b>>1];i=a|3;K[(i<<2)+g>>2]=F[(i<<1)+b>>1];a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break t}while(1){K[(a<<2)+g>>2]=F[(a<<1)+b>>1];a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break t;case 0:case 3:if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){K[(a<<2)+g>>2]=H[a+b|0];i=a|1;K[(i<<2)+g>>2]=H[b+i|0];i=a|2;K[(i<<2)+g>>2]=H[b+i|0];i=a|3;K[(i<<2)+g>>2]=H[b+i|0];a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break t}while(1){K[(a<<2)+g>>2]=H[a+b|0];a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break t;default:if((a|0)==82){break u}break;case 1:case 2:case 4:case 5:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break H}}G[309737]=410;break t;case 71:I:{switch(a-11|0){default:if((a|0)!=82){break w}if((d|0)<=0){break d}a=0;if(d-1>>>0>=3){i=d&-4;e=0;while(1){k=a<<3;L[k+g>>3]=L[b+k>>3];l=k|8;L[l+g>>3]=L[b+l>>3];l=k|16;L[l+g>>3]=L[b+l>>3];k=k|24;L[k+g>>3]=L[b+k>>3];a=a+4|0;e=e+4|0;if((i|0)!=(e|0)){continue}break}}e=d&3;if(!e){break v}while(1){k=a<<3;L[k+g>>3]=L[b+k>>3];a=a+1|0;j=j+1|0;if((e|0)!=(j|0)){continue}break};break v;case 31:if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){L[(a<<3)+g>>3]=K[(a<<2)+b>>2];i=a|1;L[(i<<3)+g>>3]=K[(i<<2)+b>>2];i=a|2;L[(i<<3)+g>>3]=K[(i<<2)+b>>2];i=a|3;L[(i<<3)+g>>3]=K[(i<<2)+b>>2];a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break v}while(1){L[(a<<3)+g>>3]=K[(a<<2)+b>>2];a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break v;case 30:if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){L[(a<<3)+g>>3]=G[(a<<2)+b>>2];i=a|1;L[(i<<3)+g>>3]=G[(i<<2)+b>>2];i=a|2;L[(i<<3)+g>>3]=G[(i<<2)+b>>2];i=a|3;L[(i<<3)+g>>3]=G[(i<<2)+b>>2];a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break v}while(1){L[(a<<3)+g>>3]=G[(a<<2)+b>>2];a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break v;case 10:if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){L[(a<<3)+g>>3]=F[(a<<1)+b>>1];i=a|1;L[(i<<3)+g>>3]=F[(i<<1)+b>>1];i=a|2;L[(i<<3)+g>>3]=F[(i<<1)+b>>1];i=a|3;L[(i<<3)+g>>3]=F[(i<<1)+b>>1];a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break v}while(1){L[(a<<3)+g>>3]=F[(a<<1)+b>>1];a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break v;case 0:case 3:break I;case 1:case 2:case 4:case 5:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break w}}if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){L[(a<<3)+g>>3]=H[a+b|0];i=a|1;L[(i<<3)+g>>3]=H[b+i|0];i=a|2;L[(i<<3)+g>>3]=H[b+i|0];i=a|3;L[(i<<3)+g>>3]=H[b+i|0];a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break v}while(1){L[(a<<3)+g>>3]=H[a+b|0];a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break};break v;default:break y}}G[309737]=410;break d}G[309737]=410;break e}G[309737]=410}if((d|0)<=0){break d}a=d&1;b=0;if((d|0)!=1){e=d&-2;d=0;while(1){if(H[b+c|0]){L[(b<<3)+g>>3]=L[f>>3];G[h>>2]=1}j=b|1;if(H[j+c|0]){L[(j<<3)+g>>3]=L[f>>3];G[h>>2]=1}b=b+2|0;d=d+2|0;if((e|0)!=(d|0)){continue}break}}if(!a|!H[b+c|0]){break d}L[(b<<3)+g>>3]=L[f>>3];break a}Wi(b,d,1,0,0,N(0),0,0,g)}if((d|0)<=0){break d}a=d&1;b=0;if((d|0)!=1){e=d&-2;d=0;while(1){if(H[b+c|0]){K[(b<<2)+g>>2]=K[f>>2];G[h>>2]=1}j=b|1;if(H[j+c|0]){K[(j<<2)+g>>2]=K[f>>2];G[h>>2]=1}b=b+2|0;d=d+2|0;if((e|0)!=(d|0)){continue}break}}if(!a|!H[b+c|0]){break d}K[(b<<2)+g>>2]=K[f>>2];break a}Yp(b,d,1,0,0,0,0,0,0,g,1238948)}if((d|0)<=0){break d}a=d&1;b=0;if((d|0)!=1){e=d&-2;d=0;while(1){if(H[b+c|0]){k=G[f+4>>2];j=(b<<3)+g|0;G[j>>2]=G[f>>2];G[j+4>>2]=k;G[h>>2]=1}j=b|1;if(H[j+c|0]){k=G[f+4>>2];j=(j<<3)+g|0;G[j>>2]=G[f>>2];G[j+4>>2]=k;G[h>>2]=1}b=b+2|0;d=d+2|0;if((e|0)!=(d|0)){continue}break}}if(!a|!H[b+c|0]){break d}a=(b<<3)+g|0;b=G[f+4>>2];G[a>>2]=G[f>>2];G[a+4>>2]=b;break a}$k(b,d,1,0,0,0,0,0,g,1238948)}if((d|0)<=0){break d}a=d&1;b=0;if((d|0)!=1){e=d&-2;d=0;while(1){if(H[b+c|0]){G[(b<<2)+g>>2]=G[f>>2];G[h>>2]=1}j=b|1;if(H[j+c|0]){G[(j<<2)+g>>2]=G[f>>2];G[h>>2]=1}b=b+2|0;d=d+2|0;if((e|0)!=(d|0)){continue}break}}if(!a|!H[b+c|0]){break d}break c}Qp(b,d,1,0,0,0,0,0,g,1238948)}if((d|0)<=0){break d}a=d&1;b=0;if((d|0)!=1){e=d&-2;d=0;while(1){if(H[b+c|0]){G[(b<<2)+g>>2]=G[f>>2];G[h>>2]=1}j=b|1;if(H[j+c|0]){G[(j<<2)+g>>2]=G[f>>2];G[h>>2]=1}b=b+2|0;d=d+2|0;if((e|0)!=(d|0)){continue}break}}if(!a|!H[b+c|0]){break d}break c}Wk(b,d,1,0,0,0,0,0,g,1238948);break j}if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){F[(a<<1)+g>>1]=H[a+b|0];i=a|1;F[(i<<1)+g>>1]=H[b+i|0];i=a|2;F[(i<<1)+g>>1]=H[b+i|0];i=a|3;F[(i<<1)+g>>1]=H[b+i|0];a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break j}while(1){F[(a<<1)+g>>1]=H[a+b|0];a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break}break j}if((d|0)<=0){break d}a=0;if(d-1>>>0>=3){i=d&-4;e=0;while(1){k=a<<1;F[k+g>>1]=I[b+k>>1];l=k|2;F[l+g>>1]=I[b+l>>1];l=k|4;F[l+g>>1]=I[b+l>>1];k=k|6;F[k+g>>1]=I[b+k>>1];a=a+4|0;e=e+4|0;if((i|0)!=(e|0)){continue}break}}e=d&3;if(!e){break j}while(1){k=a<<1;F[k+g>>1]=I[b+k>>1];a=a+1|0;j=j+1|0;if((e|0)!=(j|0)){continue}break}}if((d|0)<=0){break d}a=d&1;b=0;if((d|0)!=1){e=d&-2;d=0;while(1){if(H[b+c|0]){F[(b<<1)+g>>1]=I[f>>1];G[h>>2]=1}j=b|1;if(H[j+c|0]){F[(j<<1)+g>>1]=I[f>>1];G[h>>2]=1}b=b+2|0;d=d+2|0;if((e|0)!=(d|0)){continue}break}}if(!a|!H[b+c|0]){break d}F[(b<<1)+g>>1]=I[f>>1];break a}sp(b,d,1,0,0,0,0,0,g,1238948);break f}Tk(b,d,1,0,0,0,0,0,0,g,1238948);break f}if((d|0)<=0){break d}e=0;a=0;if(d-1>>>0>=3){k=d&-4;while(1){E[a+g|0]=H[a+b|0];i=a|1;E[i+g|0]=H[b+i|0];i=a|2;E[i+g|0]=H[b+i|0];i=a|3;E[i+g|0]=H[b+i|0];a=a+4|0;j=j+4|0;if((k|0)!=(j|0)){continue}break}}j=d&3;if(!j){break f}while(1){E[a+g|0]=H[a+b|0];a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break}}if((d|0)<=0){break d}a=d&1;b=0;if((d|0)!=1){e=d&-2;d=0;while(1){if(H[b+c|0]){E[b+g|0]=H[f|0];G[h>>2]=1}j=b|1;if(H[j+c|0]){E[g+j|0]=H[f|0];G[h>>2]=1}b=b+2|0;d=d+2|0;if((e|0)!=(d|0)){continue}break}}if(!a|!H[b+c|0]){break d}break b}if((d|0)<=0){break d}a=d&1;b=0;if((d|0)!=1){e=d&-2;d=0;while(1){if(H[b+c|0]){E[b+g|0]=H[f|0];G[h>>2]=1}j=b|1;if(H[j+c|0]){E[g+j|0]=H[f|0];G[h>>2]=1}b=b+2|0;d=d+2|0;if((e|0)!=(d|0)){continue}break}}if(!a|!H[b+c|0]){break d}break b}return}G[(b<<2)+g>>2]=G[f>>2];break a}E[b+g|0]=H[f|0]}G[h>>2]=1}function Wf(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=N(0),r=0,s=0;l=Fa-448|0;Fa=l;d=G[c>>2];if((d|0)<=0){a:{if((Sd(a,1,l+352|0,c)|0)>0){tb(5,45368);break a}d=rb(l+272|0,l+352|0,8);E[d+8|0]=0;b:{if(H[d+7|0]!=32){break b}E[d+7|0]=0;if(H[d+6|0]!=32){break b}E[d+6|0]=0;if(H[d+5|0]!=32){break b}E[d+5|0]=0;if(H[d+4|0]!=32){break b}E[d+4|0]=0;if(H[d+3|0]!=32){break b}E[d+3|0]=0;if(H[d+2|0]!=32){break b}E[d+2|0]=0;if(H[d+1|0]!=32){break b}E[d+1|0]=0;if(H[d|0]!=32){break b}E[d|0]=0}if((mc(l+352|0,l+192|0,l+112|0,c)|0)>0){tb(5,39481);tb(5,l+352|0);break a}c:{d:{if(!nb(d,35530,7)){bo(a,c);if(!b){break d}G[b>>2]=0;break d}if(!nb(d,34516,9)){if((fd(l+192|0,l+32|0,c)|0)>0){break c}d=l+32|0;while(1){e=d;d=d+1|0;if(H[e|0]==32){continue}break}if(!Xa(e,35630)){h=Fa-464|0;Fa=h;e:{if(G[c>>2]>0){break e}e=G[a>>2];d=G[a+4>>2];if((e|0)!=G[d+76>>2]){mb(a,e+1|0,0,c);d=G[a+4>>2]}G[d+80>>2]=1;e=G[d+44>>2];G[d+104>>2]=G[d+40>>2];G[d+108>>2]=e;if((mo(a,h+440|0,h+432|0,h+448|0,h+460|0,c)|0)>0){break e}if(G[h+448>>2]|G[h+452>>2]){tb(5,45670);G[h+80>>2]=G[h+448>>2];d=h+96|0;Ya(d,81,27397,h+80|0);tb(5,d);G[c>>2]=214;break e}i=G[h+444>>2];e=G[a+4>>2];d=e;G[d+960>>2]=G[h+440>>2];G[d+964>>2]=i;G[d+936>>2]=G[h+460>>2];if(G[d+1228>>2]){d=0;i=(G[e+1112>>2]-1|0)/G[e+1052>>2]|0;if((i|0)>=0){while(1){g=d<<2;e=G[a+4>>2];f=G[g+G[e+1240>>2]>>2];if(f){Wa(f);e=G[a+4>>2]}e=G[G[e+1244>>2]+g>>2];if(e){Wa(e)}e=(d|0)!=(i|0);d=d+1|0;if(e){continue}break}e=G[a+4>>2]}Wa(G[e+1248>>2]);Wa(G[G[a+4>>2]+1236>>2]);Wa(G[G[a+4>>2]+1232>>2]);Wa(G[G[a+4>>2]+1244>>2]);Wa(G[G[a+4>>2]+1240>>2]);Wa(G[G[a+4>>2]+1228>>2]);e=G[a+4>>2];d=e;G[d+1228>>2]=0;G[d+1232>>2]=0;d=d+1244|0;G[d>>2]=0;G[d+4>>2]=0;d=e+1236|0;G[d>>2]=0;G[d+4>>2]=0}d=G[e+968>>2];if(d){Wa(d)}f:{g:{i=G[h+460>>2];if((i|0)>0){d=lb(i,160);if(d){break g}tb(5,50279);G[G[a+4>>2]+968>>2]=0;G[c>>2]=111;break e}f=G[a+4>>2];G[f+968>>2]=0;break f}f=G[a+4>>2];G[f+968>>2]=d;if(i-1>>>0>=3){g=i&-4;e=0;while(1){E[d+120|0]=1;G[d+104>>2]=0;G[d+108>>2]=0;G[d+96>>2]=0;G[d+100>>2]=1072693248;E[d|0]=0;E[d+160|0]=0;G[d+80>>2]=-9999;G[d+72>>2]=-1;G[d+76>>2]=-1;E[d+320|0]=0;E[d+480|0]=0;E[d+280|0]=1;G[d+264>>2]=0;G[d+268>>2]=0;G[d+256>>2]=0;G[d+260>>2]=1072693248;E[d+440|0]=1;G[d+424>>2]=0;G[d+428>>2]=0;G[d+416>>2]=0;G[d+420>>2]=1072693248;G[d+240>>2]=-9999;G[d+232>>2]=-1;G[d+236>>2]=-1;E[d+600|0]=1;G[d+584>>2]=0;G[d+588>>2]=0;G[d+576>>2]=0;G[d+580>>2]=1072693248;G[d+400>>2]=-9999;G[d+392>>2]=-1;G[d+396>>2]=-1;G[d+560>>2]=-9999;G[d+552>>2]=-1;G[d+556>>2]=-1;d=d+640|0;e=e+4|0;if((g|0)!=(e|0)){continue}break}}i=i&3;if(!i){break f}e=0;while(1){E[d+120|0]=1;G[d+104>>2]=0;G[d+108>>2]=0;G[d+96>>2]=0;G[d+100>>2]=1072693248;E[d|0]=0;G[d+80>>2]=-9999;G[d+72>>2]=-1;G[d+76>>2]=-1;d=d+160|0;e=e+1|0;if((i|0)!=(e|0)){continue}break}}d=G[h+436>>2];e=G[h+432>>2];G[f+944>>2]=e;G[f+948>>2]=d;G[f+952>>2]=e;G[f+956>>2]=d;i=G[h+440>>2];g=G[h+444>>2];G[f+1088>>2]=0;G[f+984>>2]=0;G[f+988>>2]=0;r=f,s=Au(e,d,i,g),G[r+976>>2]=s;G[f+980>>2]=Ia;e=8;g=0;h:{while(1){Cf(a,e,h+352|0,h+272|0,h+192|0,c);i:{j:{k:{l:{m:{d=G[c>>2];switch(d-205|0){case 2:break j;case 0:break k;case 1:break l;default:break m}}if((d|0)==107){break h}}if((d|0)<=0){break i}break e}d=h+272|0;d=Va(d)+d|0;E[d|0]=39;E[d+1|0]=0}G[c>>2]=0}n:{d=H[h+352|0];o:{if((d|0)==84){ao(a,h+352|0,h+272|0,c);f=H[h+352|0];break o}f=G[h+352>>2];if((d|0)!=69){break o}if((f|0)==4476485){break n}}g=H[h+192|0]|(H[h+272|0]|f&255)?0:g+1|0;e=e+1|0;continue}break}i=G[a+4>>2];p=G[h+460>>2];if((p|0)>0){e=G[i+968>>2];f=0;while(1){if(G[e+80>>2]==-9999){d=h+352|0;zb(34641,f+1|0,d,c);G[h>>2]=d;d=h+96|0;Ya(d,81,45726,h);tb(5,d);G[c>>2]=232;break e}k=G[e+72>>2];d=G[e+76>>2];if((k&d)==-1){d=h+352|0;zb(34749,f+1|0,d,c);G[h+16>>2]=d;d=h+96|0;Ya(d,81,45726,h+16|0);tb(5,d);G[c>>2]=231;break e}p:{n=G[i+960>>2];j=G[i+964>>2];if(!(n|j)){break p}if(!((k>>>0>>0&(d|0)<=(j|0)|(d|0)<(j|0))&((d|0)>0|(d|0)>=0))){d=h+352|0;zb(34749,f+1|0,d,c);G[h+68>>2]=k;G[h+64>>2]=d;d=h+96|0;Ya(d,81,45767,h- -64|0);tb(5,d);G[c>>2]=234;break e}o=G[e+152>>2];k=o+k|0;d=(o>>31)+d|0;d=k>>>0>>0?d+1|0:d;if((d|0)<=(j|0)&k>>>0<=n>>>0|(d|0)<(j|0)){break p}G[h+48>>2]=f+1;d=h+96|0;Ya(d,81,50344,h+48|0);tb(5,d);G[h+36>>2]=G[G[a+4>>2]+960>>2];G[h+32>>2]=e+140;Ya(d,81,27412,h+32|0);tb(5,d);G[c>>2]=236;break e}e=e+160|0;f=f+1|0;if((p|0)!=(f|0)){continue}break}}e=G[i+124>>2];d=G[i+120>>2];g=M(g,80)+80|0;G[i+104>>2]=d-g;G[i+108>>2]=e-((g>>31)+(d>>>0>>0)|0);g=e-(d>>>0<80)|0;d=d-80|0;e=Cu(d,g);f=(d-e|0)+2880|0;d=g-(Ia+(d>>>0>>0)|0)|0;e=f;G[i+128>>2]=e;d=e>>>0<2880?d+1|0:d;G[i+132>>2]=d;g=G[i+96>>2]+(G[i+76>>2]<<3)|0;k=e;f=Au(G[h+432>>2],G[h+436>>2],G[h+440>>2],G[h+444>>2])+2879|0;e=Ia;e=f>>>0<2879?e+1|0:e;j=f;f=k+f|0;k=d;d=e;e=k+d|0;e=f>>>0>>0?e+1|0:e;d=Cu(j,d);G[g+8>>2]=f-d;G[g+12>>2]=e-(Ia+(d>>>0>f>>>0)|0);d=G[g+4>>2];G[i+120>>2]=G[g>>2];G[i+124>>2]=d;break e}tb(5,45615);G[c>>2]=210}Fa=h+464|0;if(!b){break d}G[b>>2]=1;break d}q:{r:{if(!Xa(e,35618)){break r}if(!Xa(e,35627)){break r}if(Xa(e,35628)){break q}}i=Fa-416|0;Fa=i;s:{if(G[c>>2]>0){break s}e=G[a>>2];d=G[a+4>>2];if((e|0)!=G[d+76>>2]){mb(a,e+1|0,0,c);d=G[a+4>>2]}G[d+80>>2]=2;e=G[d+44>>2];G[d+104>>2]=G[d+40>>2];G[d+108>>2]=e;if((mo(a,i+392|0,i+384|0,i+400|0,i+412|0,c)|0)>0){break s}g=G[i+396>>2];e=G[a+4>>2];d=e;G[d+960>>2]=G[i+392>>2];G[d+964>>2]=g;G[d+936>>2]=G[i+412>>2];if(G[d+1228>>2]){d=0;g=(G[e+1112>>2]-1|0)/G[e+1052>>2]|0;if((g|0)>=0){while(1){h=d<<2;e=G[a+4>>2];f=G[h+G[e+1240>>2]>>2];if(f){Wa(f);e=G[a+4>>2]}e=G[G[e+1244>>2]+h>>2];if(e){Wa(e)}e=(d|0)!=(g|0);d=d+1|0;if(e){continue}break}e=G[a+4>>2]}Wa(G[e+1248>>2]);Wa(G[G[a+4>>2]+1236>>2]);Wa(G[G[a+4>>2]+1232>>2]);Wa(G[G[a+4>>2]+1244>>2]);Wa(G[G[a+4>>2]+1240>>2]);Wa(G[G[a+4>>2]+1228>>2]);e=G[a+4>>2];d=e;G[d+1228>>2]=0;G[d+1232>>2]=0;d=d+1244|0;G[d>>2]=0;G[d+4>>2]=0;d=e+1236|0;G[d>>2]=0;G[d+4>>2]=0}d=G[e+968>>2];if(d){Wa(d)}t:{u:{g=G[i+412>>2];if((g|0)>0){d=lb(g,160);if(d){break u}tb(5,50214);G[G[a+4>>2]+968>>2]=0;G[c>>2]=111;break s}f=G[a+4>>2];G[f+968>>2]=0;break t}f=G[a+4>>2];G[f+968>>2]=d;if((g|0)!=1){h=g&-2;e=0;while(1){G[d+112>>2]=1234554321;G[d+116>>2]=0;G[d+104>>2]=0;G[d+108>>2]=0;G[d+96>>2]=0;G[d+100>>2]=1072693248;E[d|0]=0;E[d+160|0]=0;E[d+120|0]=0;G[d+88>>2]=1;G[d+92>>2]=0;G[d+80>>2]=-9999;G[d+272>>2]=1234554321;G[d+276>>2]=0;G[d+264>>2]=0;G[d+268>>2]=0;G[d+256>>2]=0;G[d+260>>2]=1072693248;E[d+280|0]=0;G[d+248>>2]=1;G[d+252>>2]=0;G[d+240>>2]=-9999;d=d+320|0;e=e+2|0;if((h|0)!=(e|0)){continue}break}}if(!(g&1)){break t}G[d+112>>2]=1234554321;G[d+116>>2]=0;G[d+104>>2]=0;G[d+108>>2]=0;G[d+96>>2]=0;G[d+100>>2]=1072693248;E[d|0]=0;E[d+120|0]=0;G[d+88>>2]=1;G[d+92>>2]=0;G[d+80>>2]=-9999}d=G[i+388>>2];e=G[i+384>>2];G[f+944>>2]=e;G[f+948>>2]=d;G[f+952>>2]=e;G[f+956>>2]=d;r=f,s=Au(e,d,G[i+392>>2],G[i+396>>2]),G[r+976>>2]=s;G[f+980>>2]=Ia;d=G[i+400>>2];e=G[i+404>>2];G[f+1088>>2]=0;G[f+984>>2]=d;G[f+988>>2]=e;d=8;g=0;v:{while(1){Cf(a,d,i+288|0,i+208|0,i+128|0,c);w:{x:{y:{z:{A:{e=G[c>>2];switch(e-205|0){case 2:break x;case 0:break y;case 1:break z;default:break A}}if((e|0)==107){break v}}if((e|0)<=0){break w}break s}e=i+208|0;e=Va(e)+e|0;E[e|0]=39;E[e+1|0]=0}G[c>>2]=0}B:{C:{D:{E:{F:{h=H[i+288|0];switch(h-84|0){case 6:break E;case 0:break F;default:break D}}ao(a,i+288|0,i+208|0,c);e=H[i+288|0];break C}e=90;if(nb(i+288|0,35668,7)|H[i+208|0]!=84){break C}G[G[a+4>>2]+1088>>2]=1;break C}e=G[i+288>>2];if((h|0)!=69){break C}if((e|0)==4476485){break B}}g=H[i+128|0]|(H[i+208|0]|e&255)?0:g+1|0;d=d+1|0;continue}break}h=G[a+4>>2];f=G[i+412>>2];if((f|0)>0){e=G[h+968>>2];d=0;while(1){d=d+1|0;if(G[e+80>>2]==-9999){e=d;d=i+288|0;zb(34641,e,d,c);G[i>>2]=d;d=i+32|0;Ya(d,81,45574,i);tb(5,d);G[c>>2]=232;break s}e=e+160|0;if((d|0)!=(f|0)){continue}break}}e=G[h+124>>2];d=G[h+120>>2];g=M(g,80)+80|0;G[h+104>>2]=d-g;G[h+108>>2]=e-((g>>31)+(d>>>0>>0)|0);g=e-(d>>>0<80)|0;d=d-80|0;e=Cu(d,g);f=(d-e|0)+2880|0;e=g-(Ia+(d>>>0>>0)|0)|0;d=f;G[h+128>>2]=d;e=d>>>0<2880?e+1|0:e;G[h+132>>2]=e;g=e;f=G[h+96>>2]+(G[h+76>>2]<<3)|0;k=d;e=G[h+988>>2]+G[h+980>>2]|0;j=G[h+976>>2];d=j+G[h+984>>2]|0;h=d+2879|0;d=d>>>0>>0?e+1|0:e;d=h>>>0<2879?d+1|0:d;j=h;h=k+h|0;e=d;d=d+g|0;e=Cu(j,e);G[f+8>>2]=h-e;G[f+12>>2]=(h>>>0>>0?d+1|0:d)-(Ia+(e>>>0>h>>>0)|0);g=0;e=0;f=0;h=Fa-112|0;Fa=h;G:{if(G[c>>2]>0){break G}j=G[a>>2];d=G[a+4>>2];H:{I:{if((j|0)!=G[d+76>>2]){mb(a,j+1|0,0,c);break I}if((G[d+128>>2]&G[d+132>>2])!=-1){break I}if((Rb(a,c)|0)>0){break H}}j=G[a+4>>2];d=G[j+968>>2];j=G[j+936>>2];G[i+376>>2]=0;G[i+380>>2]=0;if((j|0)<=0){break H}while(1){G[d+72>>2]=g;G[d+76>>2]=e;J:{K:{L:{e=G[d+80>>2];g=e-1|0;if(g){if((g|0)==15){break K}else{break L}}e=G[d+92>>2];g=G[d+88>>2]+7|0;e=g>>>0<7?e+1|0:e;g=Bu(g,e,8,0);e=Ia;break J}if((e|0)>0){g=Au(G[d+88>>2],G[d+92>>2],(e>>>0)/10|0,0);e=Ia;break J}k=d+140|0;e=k;while(1){g=E[e|0];e=e+1|0;if(g-48>>>0<10){continue}break}M:{switch((g&255)-80|0){case 0:g=G[d+88>>2];e=G[d+92>>2]<<3|g>>>29;g=g<<3;break J;case 1:g=G[d+88>>2];e=G[d+92>>2]<<4|g>>>28;g=g<<4;break J;default:break M}}G[h>>2]=k;d=h+16|0;Ya(d,81,9871,h);tb(5,d);G[c>>2]=261;break G}g=G[d+88>>2];e=G[d+92>>2]}k=G[i+376>>2];g=k+g|0;e=G[i+380>>2]+e|0;e=g>>>0>>0?e+1|0:e;G[i+376>>2]=g;G[i+380>>2]=e;d=d+160|0;f=f+1|0;if((j|0)!=(f|0)){continue}break}}}Fa=h+112|0;d=G[i+376>>2];e=G[i+392>>2];if((d|0)!=(e|0)|G[i+380>>2]!=G[i+396>>2]){G[i+20>>2]=d;G[i+16>>2]=e;d=i+32|0;Ya(d,81,27469,i+16|0);tb(5,d);G[c>>2]=241}d=G[a+4>>2];e=G[d+96>>2]+(G[d+76>>2]<<3)|0;g=G[e+4>>2];G[d+120>>2]=G[e>>2];G[d+124>>2]=g;if(G[d+1088>>2]!=1){break s}f=Fa-208|0;Fa=f;G[f+32>>2]=0;N:{if(G[c>>2]>0){break N}if((Cb(a,16,35408,f+48|0,0,c)|0)>0){Ua(15952);Ua(13201);break N}E[G[a+4>>2]+1092|0]=0;d=11;qb(G[a+4>>2]+1092|0,f+48|0,11);O:{P:{Q:{R:{S:{T:{U:{g=H[f+48|0];switch(g-71|0){case 0:break S;case 1:break T;case 11:break U;default:break R}}if(!nb(f+48|0,41123,7)){break Q}if(!nb(f+48|0,35427,9)){break Q}break P}if(nb(f+48|0,41076,12)){break P}d=41;break Q}if(!nb(f+48|0,41109,7)){d=21;break Q}if(nb(f+48|0,40739,7)){break P}d=22;break Q}e=G[f+48>>2];h=G[f+52>>2];if((g|0)==66){d=51;if((e|0)==1346984514&(h|0)==3235634){break Q}}V:{switch((e&255)-78|0){case 2:if(nb(f+48|0,41116,7)){break P}d=31;break Q;case 0:break V;default:break P}}if(nb(f+48|0,33718,11)){break P}d=-1}e=G[a+4>>2];G[e+1048>>2]=d;if((Cb(a,31,32893,e+1104|0,0,c)|0)>0){Ua(26247);break N}G[f+40>>2]=0;G[f+44>>2]=0;W:{X:{if(G[G[a+4>>2]+1104>>2]>=0){break X}if((dc(a,0,34356,f+32|0,f+44|0)|0)!=219){break X}if((dc(a,0,35636,f+32|0,f+40|0)|0)!=219){break X}G[G[a+4>>2]+1076>>2]=1176255488;break W}G[f+44>>2]=0;if((Cb(a,16,32673,f+48|0,0,f+44|0)|0)>0){d=G[a+4>>2];G[d+1076>>2]=0;G[d+1080>>2]=0;break W}Y:{Z:{_:{switch(H[f+48|0]-78|0){case 0:if(nb(f+48|0,35436,5)){break Z}G[G[a+4>>2]+1076>>2]=1176255488;break W;case 5:break _;default:break Y}}if(!nb(f+48|0,41088,21)){G[G[a+4>>2]+1080>>2]=1;break W}if(nb(f+48|0,40718,21)){break Y}G[G[a+4>>2]+1080>>2]=2;break W}if(nb(f+48|0,34039,10)){break Y}G[G[a+4>>2]+1080>>2]=-1;break W}G[G[a+4>>2]+1080>>2]=0}G[f+44>>2]=0;d=Cb(a,31,41550,f+36|0,0,f+44|0);e=G[a+4>>2];G[e+1084>>2]=(d|0)<=0?G[f+36>>2]:1;if((Cb(a,31,33763,e+1108|0,0,c)|0)>0){Ua(26294);break N}$:{d=G[G[a+4>>2]+1108>>2];if((d|0)<=0){Ua(63525);break $}aa:{ba:{ca:{if(d>>>0<7){d=0;e=1;j=1;while(1){h=d+1|0;G[f+16>>2]=h;g=f+128|0;Ya(g,75,29932,f+16|0);k=d<<2;Cb(a,41,g,(k+G[a+4>>2]|0)+1112|0,0,c);if(G[c>>2]>0){Ua(26200);break N}G[f>>2]=h;Ya(f+128|0,75,29987,f);g=G[a+4>>2];da:{if(!d){G[g+1052>>2]=G[g+1112>>2];break da}G[(g+k|0)+1052>>2]=1}G[f+44>>2]=0;Cb(a,41,f+128|0,(g+k|0)+1052|0,0,f+44|0);g=G[a+4>>2];k=k+g|0;d=G[k+1052>>2];j=M(((G[k+1112>>2]-1|0)/(d|0)|0)+1|0,j);e=M(d,e);d=h;if((d|0)>2]){continue}break}if((j|0)!=G[g+952>>2]|G[g+956>>2]!=j>>31){Ua(24707);break O}d=G[g+1048>>2];if((d|0)!=41){if((d|0)!=11){break aa}if((Cb(a,31,41273,g+1212|0,0,c)|0)>0){Ua(26340);break N}G[f+44>>2]=0;ea:{if(!Cb(a,16,40889,f+48|0,0,f+44|0)){if(H[f+48|0]==78){d=nb(f+48|0,33385,9);G[f+44>>2]=0;if(d){break ea}break ca}G[f+44>>2]=0;break ea}G[f+44>>2]=0}if((Cb(a,31,40860,G[a+4>>2]+1216|0,0,f+44|0)|0)>0){break ca}g=G[a+4>>2];break ba}if((Cb(a,42,41273,g+1220|0,0,c)|0)>0){Ua(26340);break N}G[f+44>>2]=0;Cb(a,31,40860,G[a+4>>2]+1224|0,0,f+44|0);g=G[a+4>>2];break aa}Ua(6584);break $}g=G[a+4>>2];G[g+1216>>2]=4}h=G[g+1212>>2];if((h|0)>15){break aa}d=G[g+1216>>2];if((d|0)<9){break aa}G[f+44>>2]=d;G[g+1212>>2]=d;G[g+1216>>2]=h}G[g+1136>>2]=e;d=e;e=G[g+1104>>2];h=G[g+1212>>2];j=G[g+1048>>2];fa:{if((j|0)==11){if((e|0)==16){d=(((d|0)/(h|0)|0)+(d<<1)|0)+6|0;break fa}d=(((d|0)/(h|0)|0)+(d<<2)|0)+6|0;break fa}ga:{if(j-21>>>0<=1){ha:{switch(e-8|0){case 8:d=d<<1;break fa;case 0:break ga;default:break ha}}d=d<<2;break fa}ia:{switch(j-41|0){case 10:m=+(d|0)*1.01*+(e|0)*.125+601;if(O(m)<2147483648){d=~~m;break fa}d=-2147483648;break fa;case 0:ja:{switch(e-8|0){case 0:case 8:m=+(d|0)*2.2+26;if(O(m)<2147483648){d=~~m;break fa}d=-2147483648;break fa;default:break ja}}m=+(d|0)*4.4+26;if(O(m)<2147483648){d=~~m;break fa}d=-2147483648;break fa;default:break ia}}d=d<<2}}G[g+1140>>2]=d;if((dc(a,0,35951,g+1144|0,c)|0)>0){Ua(51886);break O}rh();G[f+44>>2]=0;d=f+44|0;dc(a,0,35949,G[a+4>>2]+1148|0,d);G[f+44>>2]=0;dc(a,0,35928,G[a+4>>2]+1152|0,d);G[f+44>>2]=0;ka:{if((dc(a,0,35636,G[a+4>>2]+1156|0,d)|0)<=0){break ka}G[f+44>>2]=0;if((Cb(a,82,35636,G[a+4>>2]+1168|0,0,f+44|0)|0)>0){break ka}G[G[a+4>>2]+1156>>2]=-1}G[f+44>>2]=0;la:{if((dc(a,0,34356,G[a+4>>2]+1160|0,f+44|0)|0)<=0){break la}G[f+44>>2]=0;if((Cb(a,82,34356,G[a+4>>2]+1176|0,0,f+44|0)|0)>0){break la}G[G[a+4>>2]+1160>>2]=-1}G[f+44>>2]=0;ma:{if((dc(a,0,34861,G[a+4>>2]+1164|0,f+44|0)|0)<=0){break ma}G[f+44>>2]=0;if((Cb(a,31,34861,G[a+4>>2]+1208|0,0,f+44|0)|0)>0){G[f+44>>2]=0;if((Cb(a,31,34862,G[a+4>>2]+1208|0,0,f+44|0)|0)>0){break ma}}G[G[a+4>>2]+1164>>2]=-1}G[f+44>>2]=0;e=Cb(a,82,35661,G[a+4>>2]+1184|0,0,f+44|0);d=G[a+4>>2];if((e|0)>0){G[d+1184>>2]=0;G[d+1188>>2]=1072693248}G[f+44>>2]=0;e=Cb(a,82,34377,d+1192|0,0,f+44|0);d=G[a+4>>2];na:{if((e|0)>0){e=d+1192|0;G[e>>2]=0;G[e+4>>2]=0;G[e+8>>2]=0;G[e+12>>2]=0;break na}L[d+1200>>3]=L[d+1192>>3]}q=K[d+1020>>2];if(q!=N(0)){K[d+1076>>2]=q}qh();break N}G[c>>2]=212;break N}Ua(37781);Ua(f+48|0)}G[c>>2]=414}Fa=f+208|0;break s}tb(5,45518);G[c>>2]=210}Fa=i+416|0;if(!b){break d}G[b>>2]=2;break d}G[l+444>>2]=0;bo(a,l+444|0);d=G[l+444>>2];if(!(!b|(d|0)!=251)){G[b>>2]=-1;break d}G[c>>2]=d;if(!b){break d}G[b>>2]=0;break d}oa:{switch(H[l+352|0]){case 0:case 10:G[c>>2]=107;break d;default:break oa}}G[c>>2]=252;tb(5,49619);tb(5,l+352|0)}b=G[a+4>>2];d=(G[b+76>>2]<<3)+G[b+96>>2]|0;f=J[d+8>>2]>2];d=G[d+12>>2];e=G[b+44>>2];if(f&(d|0)<=(e|0)|(d|0)<(e|0)){G[b+48>>2]=0;break a}G[b+48>>2]=1;Ym(a,l,c);if(nb(l,42094,7)){if(nb(l,42043,11)){break a}}b=a;a=G[a+4>>2];a=(G[a+76>>2]<<3)+G[a+96>>2]|0;Wm(b,G[a+8>>2],G[a+12>>2],c);break a}tb(5,38683);tb(5,l+192|0)}d=G[c>>2]}Fa=l+448|0;return d}function Jm(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,w=0,x=0,y=0,z=0,A=0,C=0,D=0,F=0,I=0;p=Fa-48|0;Fa=p;a:{if(c>>>0<=2){c=c<<2;z=G[c+92732>>2];A=G[c+92720>>2];while(1){c=G[b+4>>2];b:{if((c|0)!=G[b+104>>2]){G[b+4>>2]=c+1;c=H[c|0];break b}c=jc(b)}if((c|0)==32|c-9>>>0<5){continue}break}n=1;c:{d:{switch(c-43|0){case 0:case 2:break d;default:break c}}n=(c|0)==45?-1:1;c=G[b+4>>2];if((c|0)!=G[b+104>>2]){G[b+4>>2]=c+1;c=H[c|0];break c}c=jc(b)}e:{f:{while(1){if(E[g+2831|0]==(c|32)){g:{if(g>>>0>6){break g}c=G[b+4>>2];if((c|0)!=G[b+104>>2]){G[b+4>>2]=c+1;c=H[c|0];break g}c=jc(b)}g=g+1|0;if((g|0)!=8){continue}break f}break}if((g|0)!=3){if((g|0)==8){break f}if(!d|g>>>0<4){break e}if((g|0)==8){break f}}c=G[b+116>>2];if((c|0)>0|(c|0)>=0){G[b+4>>2]=G[b+4>>2]-1}if(!d|g>>>0<4){break f}c=(c|0)<0;while(1){if(!c){G[b+4>>2]=G[b+4>>2]-1}g=g-1|0;if(g>>>0>3){continue}break}}j=Fa-16|0;Fa=j;g=(B(N(N(n|0)*N(Y))),v(2));b=g&2147483647;h:{if(b-8388608>>>0<=2130706431){k=b<<25;c=(b>>>7|0)+1065353216|0;break h}k=g<<25;c=g>>>7|2147418112;if(b>>>0>=2139095040){break h}k=0;c=0;if(!b){break h}c=b;b=P(b);od(j,c,0,0,0,b+81|0);i=G[j>>2];h=G[j+4>>2];k=G[j+8>>2];c=G[j+12>>2]^65536|16265-b<<16}G[p>>2]=i;G[p+4>>2]=h;G[p+8>>2]=k;G[p+12>>2]=g&-2147483648|c;Fa=j+16|0;i=G[p+8>>2];h=G[p+12>>2];k=G[p>>2];j=G[p+4>>2];break a}i:{j:{k:{if(g){break k}g=0;while(1){if(E[g+16008|0]!=(c|32)){break k}l:{if(g>>>0>1){break l}c=G[b+4>>2];if((c|0)!=G[b+104>>2]){G[b+4>>2]=c+1;c=H[c|0];break l}c=jc(b)}g=g+1|0;if((g|0)!=3){continue}break}break j}m:{switch(g|0){case 0:n:{if((c|0)!=48){break n}g=G[b+4>>2];o:{if((g|0)!=G[b+104>>2]){G[b+4>>2]=g+1;g=H[g|0];break o}g=jc(b)}if((g&-33)==88){f=Fa-432|0;Fa=f;c=G[b+4>>2];p:{if((c|0)!=G[b+104>>2]){G[b+4>>2]=c+1;g=H[c|0];break p}g=jc(b)}q:{r:{while(1){if((g|0)!=48){s:{if((g|0)!=46){break q}c=G[b+4>>2];if((c|0)==G[b+104>>2]){break s}G[b+4>>2]=c+1;g=H[c|0];break r}}else{c=G[b+4>>2];if((c|0)!=G[b+104>>2]){s=1;G[b+4>>2]=c+1;g=H[c|0]}else{s=1;g=jc(b)}continue}break}g=jc(b)}e=1;if((g|0)!=48){break q}while(1){c=q;q=c-1|0;r=r-!c|0;c=G[b+4>>2];t:{if((c|0)!=G[b+104>>2]){G[b+4>>2]=c+1;g=H[c|0];break t}g=jc(b)}if((g|0)==48){continue}break}s=1}j=1073676288;while(1){u:{c=g|32;v:{w:{F=g-48|0;if(F>>>0<10){break w}if((g|0)!=46&c-97>>>0>=6){break u}if((g|0)!=46){break w}if(e){break u}e=1;q=i;r=h;break v}c=(g|0)>57?c-87|0:F;x:{if((h|0)<=0&i>>>0<=7|(h|0)<0){t=c+(t<<4)|0;break x}if(!h&i>>>0<=28){Zd(f+48|0,c);tc(f+32|0,x,y,k,j,0,0,0,1073414144);x=G[f+32>>2];y=G[f+36>>2];k=G[f+40>>2];j=G[f+44>>2];tc(f+16|0,G[f+48>>2],G[f+52>>2],G[f+56>>2],G[f+60>>2],x,y,k,j);Zc(f,G[f+16>>2],G[f+20>>2],G[f+24>>2],G[f+28>>2],l,o,u,w);u=G[f+8>>2];w=G[f+12>>2];l=G[f>>2];o=G[f+4>>2];break x}if(m|!c){break x}tc(f+80|0,x,y,k,j,0,0,0,1073610752);Zc(f- -64|0,G[f+80>>2],G[f+84>>2],G[f+88>>2],G[f+92>>2],l,o,u,w);u=G[f+72>>2];w=G[f+76>>2];m=1;l=G[f+64>>2];o=G[f+68>>2]}c=i+1|0;h=c?h:h+1|0;i=c;s=1}c=G[b+4>>2];if((c|0)!=G[b+104>>2]){G[b+4>>2]=c+1;g=H[c|0]}else{g=jc(b)}continue}break}y:{if(!s){c=G[b+116>>2];z:{A:{if((c|0)>0|(c|0)>=0){c=G[b+4>>2];G[b+4>>2]=c-1;if(!d){break A}G[b+4>>2]=c-2;if(!e){break z}G[b+4>>2]=c-3;break z}if(d){break z}}te(b,0,0)}td(f+96|0,+(n|0)*0);l=G[f+96>>2];o=G[f+100>>2];c=G[f+108>>2];b=G[f+104>>2];break y}if((h|0)<=0&i>>>0<=7|(h|0)<0){k=i;j=h;while(1){t=t<<4;c=k+1|0;j=c?j:j+1|0;k=c;if((c|0)!=8|j){continue}break}}B:{C:{D:{if((g&-33)==80){k=Hm(b,d);c=Ia;j=c;if(k|(c|0)!=-2147483648){break B}if(d){c=G[b+116>>2];if((c|0)>0|(c|0)>=0){break D}break C}l=0;o=0;te(b,0,0);c=0;b=0;break y}k=0;j=0;if(G[b+116>>2]<0){break B}}G[b+4>>2]=G[b+4>>2]-1}k=0;j=0}if(!t){td(f+112|0,+(n|0)*0);l=G[f+112>>2];o=G[f+116>>2];c=G[f+124>>2];b=G[f+120>>2];break y}b=e?q:i;h=(e?r:h)<<2|b>>>30;b=k+(b<<2)|0;d=h+j|0;d=b>>>0>>0?d+1|0:d;i=b-32|0;h=d-(b>>>0<32)|0;b=h;if(i>>>0>0-z>>>0&(b|0)>=0|(b|0)>0){G[48624]=68;Zd(f+160|0,n);tc(f+144|0,G[f+160>>2],G[f+164>>2],G[f+168>>2],G[f+172>>2],-1,-1,-1,2147418111);tc(f+128|0,G[f+144>>2],G[f+148>>2],G[f+152>>2],G[f+156>>2],-1,-1,-1,2147418111);l=G[f+128>>2];o=G[f+132>>2];c=G[f+140>>2];b=G[f+136>>2];break y}b=z-226|0;c=b>>31;if((h|0)>=(c|0)&b>>>0<=i>>>0|(c|0)<(h|0)){if((t|0)>=0){while(1){Zc(f+416|0,l,o,u,w,0,0,0,-1073807360);c=Zm(l,o,u,w,1073610752);b=(c|0)<0;Zc(f+400|0,l,o,u,w,b?l:G[f+416>>2],b?o:G[f+420>>2],b?u:G[f+424>>2],b?w:G[f+428>>2]);b=i;i=b-1|0;h=h-!b|0;u=G[f+408>>2];w=G[f+412>>2];l=G[f+400>>2];o=G[f+404>>2];t=t<<1|(c|0)>=0;if((t|0)>=0){continue}break}}d=h-((z>>31)+(i>>>0>>0)|0)|0;b=(i-z|0)+32|0;d=b>>>0<32?d+1|0:d;c=b>>>0>>0&(d|0)<=0|(d|0)<0?(b|0)>0?b:0:A;E:{if((c|0)>=113){Zd(f+384|0,n);q=G[f+392>>2];r=G[f+396>>2];x=G[f+384>>2];y=G[f+388>>2];h=0;b=0;break E}td(f+352|0,Qf(1,144-c|0));Zd(f+336|0,n);x=G[f+336>>2];y=G[f+340>>2];q=G[f+344>>2];r=G[f+348>>2];Tm(f+368|0,G[f+352>>2],G[f+356>>2],G[f+360>>2],G[f+364>>2],x,y,q,r);C=G[f+376>>2];D=G[f+380>>2];h=G[f+372>>2];b=G[f+368>>2]}c=!(t&1)&((Sf(l,o,u,w,0,0,0,0)|0)!=0&(c|0)<32);wg(f+320|0,c+t|0);tc(f+304|0,x,y,q,r,G[f+320>>2],G[f+324>>2],G[f+328>>2],G[f+332>>2]);d=b;Zc(f+272|0,G[f+304>>2],G[f+308>>2],G[f+312>>2],G[f+316>>2],b,h,C,D);b=c;tc(f+288|0,x,y,q,r,b?0:l,b?0:o,b?0:u,b?0:w);Zc(f+256|0,G[f+288>>2],G[f+292>>2],G[f+296>>2],G[f+300>>2],G[f+272>>2],G[f+276>>2],G[f+280>>2],G[f+284>>2]);Fj(f+240|0,G[f+256>>2],G[f+260>>2],G[f+264>>2],G[f+268>>2],d,h,C,D);b=G[f+240>>2];c=G[f+244>>2];d=G[f+248>>2];h=G[f+252>>2];if(!Sf(b,c,d,h,0,0,0,0)){G[48624]=68}Om(f+224|0,b,c,d,h,i);l=G[f+224>>2];o=G[f+228>>2];c=G[f+236>>2];b=G[f+232>>2];break y}G[48624]=68;Zd(f+208|0,n);tc(f+192|0,G[f+208>>2],G[f+212>>2],G[f+216>>2],G[f+220>>2],0,0,0,65536);tc(f+176|0,G[f+192>>2],G[f+196>>2],G[f+200>>2],G[f+204>>2],0,0,0,65536);l=G[f+176>>2];o=G[f+180>>2];c=G[f+188>>2];b=G[f+184>>2]}G[p+16>>2]=l;G[p+20>>2]=o;G[p+24>>2]=b;G[p+28>>2]=c;Fa=f+432|0;i=G[p+24>>2];h=G[p+28>>2];k=G[p+16>>2];j=G[p+20>>2];break a}if(G[b+116>>2]<0){break n}G[b+4>>2]=G[b+4>>2]-1}g=b;f=n;t=d;d=0;n=0;e=Fa-8976|0;Fa=e;D=z+A|0;F=0-D|0;F:{G:{while(1){if((c|0)!=48){H:{if((c|0)!=46){break F}b=G[g+4>>2];if((b|0)==G[g+104>>2]){break H}G[g+4>>2]=b+1;c=H[b|0];break G}}else{b=G[g+4>>2];if((b|0)!=G[g+104>>2]){d=1;G[g+4>>2]=b+1;c=H[b|0]}else{d=1;c=jc(g)}continue}break}c=jc(g)}m=1;if((c|0)!=48){break F}while(1){b=i;i=b-1|0;h=h-!b|0;b=G[g+4>>2];I:{if((b|0)!=G[g+104>>2]){G[g+4>>2]=b+1;c=H[b|0];break I}c=jc(g)}if((c|0)==48){continue}break}d=1}G[e+784>>2]=0;J:{K:{b=(c|0)==46;l=c-48|0;L:{M:{N:{O:{if(b|l>>>0<=9){while(1){P:{if(b&1){if(!m){i=k;h=j;m=1;break P}b=!d;break O}b=k+1|0;j=b?j:j+1|0;k=b;if((n|0)<=2044){C=(c|0)==48?C:k;b=(e+784|0)+(n<<2)|0;if(s){l=(M(G[b>>2],10)+c|0)-48|0}G[b>>2]=l;d=1;c=s+1|0;b=(c|0)==9;s=b?0:c;n=b+n|0;break P}if((c|0)==48){break P}G[e+8960>>2]=G[e+8960>>2]|1;C=18396}b=G[g+4>>2];Q:{if((b|0)!=G[g+104>>2]){G[g+4>>2]=b+1;c=H[b|0];break Q}c=jc(g)}b=(c|0)==46;l=c-48|0;if(b|l>>>0<10){continue}break}}i=m?i:k;h=m?h:j;if(!(!d|(c&-33)!=69)){l=Hm(g,t);b=Ia;o=b;R:{if(l|(b|0)!=-2147483648){break R}if(!t){break L}l=0;o=0;if(G[g+116>>2]<0){break R}G[g+4>>2]=G[g+4>>2]-1}if(!d){break M}h=h+o|0;b=i+l|0;h=b>>>0>>0?h+1|0:h;i=b;break K}b=!d;if((c|0)<0){break N}}if(G[g+116>>2]<0){break N}G[g+4>>2]=G[g+4>>2]-1}if(!b){break K}}G[48624]=28}k=0;j=0;te(g,0,0);c=0;b=0;break J}b=G[e+784>>2];if(!b){td(e,+(f|0)*0);k=G[e>>2];j=G[e+4>>2];c=G[e+12>>2];b=G[e+8>>2];break J}if(!(k>>>0>9&(j|0)>=0|(j|0)>0|((i|0)!=(k|0)|(h|0)!=(j|0))|(b>>>A|0?(A|0)<=30:0))){Zd(e+48|0,f);wg(e+32|0,b);tc(e+16|0,G[e+48>>2],G[e+52>>2],G[e+56>>2],G[e+60>>2],G[e+32>>2],G[e+36>>2],G[e+40>>2],G[e+44>>2]);k=G[e+16>>2];j=G[e+20>>2];c=G[e+28>>2];b=G[e+24>>2];break J}if(i>>>0>(z|0)/-2>>>0&(h|0)>=0|(h|0)>0){G[48624]=68;Zd(e+96|0,f);tc(e+80|0,G[e+96>>2],G[e+100>>2],G[e+104>>2],G[e+108>>2],-1,-1,-1,2147418111);tc(e- -64|0,G[e+80>>2],G[e+84>>2],G[e+88>>2],G[e+92>>2],-1,-1,-1,2147418111);k=G[e+64>>2];j=G[e+68>>2];c=G[e+76>>2];b=G[e+72>>2];break J}b=z-226|0;c=i>>>0>>0;b=b>>31;if(c&(h|0)<=(b|0)|(b|0)>(h|0)){G[48624]=68;Zd(e+144|0,f);tc(e+128|0,G[e+144>>2],G[e+148>>2],G[e+152>>2],G[e+156>>2],0,0,0,65536);tc(e+112|0,G[e+128>>2],G[e+132>>2],G[e+136>>2],G[e+140>>2],0,0,0,65536);k=G[e+112>>2];j=G[e+116>>2];c=G[e+124>>2];b=G[e+120>>2];break J}if(s){if((s|0)<=8){b=(e+784|0)+(n<<2)|0;g=G[b>>2];while(1){g=M(g,10);s=s+1|0;if((s|0)!=9){continue}break}G[b>>2]=g}n=n+1|0}S:{m=i;if((C|0)>(i|0)|(C|0)>=9|(i|0)>17){break S}if((m|0)==9){Zd(e+192|0,f);wg(e+176|0,G[e+784>>2]);tc(e+160|0,G[e+192>>2],G[e+196>>2],G[e+200>>2],G[e+204>>2],G[e+176>>2],G[e+180>>2],G[e+184>>2],G[e+188>>2]);k=G[e+160>>2];j=G[e+164>>2];c=G[e+172>>2];b=G[e+168>>2];break J}if((m|0)<=8){Zd(e+272|0,f);wg(e+256|0,G[e+784>>2]);tc(e+240|0,G[e+272>>2],G[e+276>>2],G[e+280>>2],G[e+284>>2],G[e+256>>2],G[e+260>>2],G[e+264>>2],G[e+268>>2]);Zd(e+224|0,G[(0-m<<2)+92720>>2]);Nm(e+208|0,G[e+240>>2],G[e+244>>2],G[e+248>>2],G[e+252>>2],G[e+224>>2],G[e+228>>2],G[e+232>>2],G[e+236>>2]);k=G[e+208>>2];j=G[e+212>>2];c=G[e+220>>2];b=G[e+216>>2];break J}b=(M(m,-3)+A|0)+27|0;c=G[e+784>>2];if(c>>>b|0?(b|0)<=30:0){break S}Zd(e+352|0,f);wg(e+336|0,c);tc(e+320|0,G[e+352>>2],G[e+356>>2],G[e+360>>2],G[e+364>>2],G[e+336>>2],G[e+340>>2],G[e+344>>2],G[e+348>>2]);Zd(e+304|0,G[(m<<2)+92648>>2]);tc(e+288|0,G[e+320>>2],G[e+324>>2],G[e+328>>2],G[e+332>>2],G[e+304>>2],G[e+308>>2],G[e+312>>2],G[e+316>>2]);k=G[e+288>>2];j=G[e+292>>2];c=G[e+300>>2];b=G[e+296>>2];break J}while(1){c=n;n=c-1|0;if(!G[(e+784|0)+(n<<2)>>2]){continue}break}s=0;d=(m|0)%9|0;T:{if(!d){b=0;break T}b=0;d=(m|0)<0?d+9|0:d;U:{if(!c){c=0;break U}i=G[(0-d<<2)+92720>>2];j=1e9/(i|0)|0;l=0;g=0;while(1){h=l;k=(e+784|0)+(g<<2)|0;n=G[k>>2];l=(n>>>0)/(i>>>0)|0;h=h+l|0;G[k>>2]=h;h=!h&(b|0)==(g|0);b=h?b+1&2047:b;m=h?m-9|0:m;l=M(j,n-M(i,l)|0);g=g+1|0;if((g|0)!=(c|0)){continue}break}if(!l){break U}G[(e+784|0)+(c<<2)>>2]=l;c=c+1|0}m=(m-d|0)+9|0}while(1){k=(e+784|0)+(b<<2)|0;V:{while(1){if(((m|0)!=36|J[k>>2]>=10384593)&(m|0)>=36){break V}d=c+2047|0;l=0;while(1){g=d&2047;n=(e+784|0)+(g<<2)|0;d=G[n>>2];j=d>>>3|0;h=d<<29;i=h+l|0;d=j;d=h>>>0>i>>>0?d+1|0:d;h=d;if(!h&i>>>0<1000000001){l=0}else{d=i;l=Du(d,h,1e9,0);i=d-Au(l,Ia,1e9,0)|0}G[n>>2]=i;c=(g|0)!=(c-1&2047)?c:(b|0)==(g|0)?c:i?c:g;d=g-1|0;if((b|0)!=(g|0)){continue}break}s=s-29|0;if(!l){continue}break}b=b-1&2047;if((c|0)==(b|0)){d=e+784|0;i=d+((c+2046&2047)<<2)|0;c=c-1&2047;G[i>>2]=G[i>>2]|G[d+(c<<2)>>2]}m=m+9|0;G[(e+784|0)+(b<<2)>>2]=l;continue}break}W:{X:while(1){i=c+1&2047;j=(e+784|0)+((c-1&2047)<<2)|0;while(1){h=(m|0)>45?9:1;Y:{while(1){d=b;g=0;Z:{while(1){_:{b=d+g&2047;if((b|0)==(c|0)){break _}b=G[(e+784|0)+(b<<2)>>2];k=G[(g<<2)+92672>>2];if(b>>>0>>0){break _}if(b>>>0>k>>>0){break Z}g=g+1|0;if((g|0)!=4){continue}}break}if((m|0)!=36){break Z}i=0;h=0;g=0;k=0;j=0;while(1){b=d+g&2047;if((b|0)==(c|0)){c=c+1&2047;G[(e+(c<<2)|0)+780>>2]=0}wg(e+768|0,G[(e+784|0)+(b<<2)>>2]);tc(e+752|0,i,h,k,j,0,0,1342177280,1075633366);Zc(e+736|0,G[e+752>>2],G[e+756>>2],G[e+760>>2],G[e+764>>2],G[e+768>>2],G[e+772>>2],G[e+776>>2],G[e+780>>2]);k=G[e+744>>2];j=G[e+748>>2];i=G[e+736>>2];h=G[e+740>>2];g=g+1|0;if((g|0)!=4){continue}break}Zd(e+720|0,f);tc(e+704|0,i,h,k,j,G[e+720>>2],G[e+724>>2],G[e+728>>2],G[e+732>>2]);k=G[e+712>>2];j=G[e+716>>2];i=0;h=0;l=G[e+704>>2];o=G[e+708>>2];t=s+113|0;g=t-z|0;n=(g|0)<(A|0);b=n?(g|0)>0?g:0:A;if((b|0)<=112){break Y}break W}s=h+s|0;b=c;if((d|0)==(b|0)){continue}break}k=1e9>>>h|0;n=-1<>2];g=(t>>>h|0)+g|0;G[l>>2]=g;g=!g&(b|0)==(d|0);b=g?b+1&2047:b;m=g?m-9|0:m;g=M(k,n&t);d=d+1&2047;if((d|0)!=(c|0)){continue}break}if(!g){continue}if((b|0)!=(i|0)){G[(e+784|0)+(c<<2)>>2]=g;c=i;continue X}G[j>>2]=G[j>>2]|1;continue}break}break}td(e+656|0,Qf(1,225-b|0));Tm(e+688|0,G[e+656>>2],G[e+660>>2],G[e+664>>2],G[e+668>>2],l,o,k,j);x=G[e+696>>2];y=G[e+700>>2];u=G[e+688>>2];w=G[e+692>>2];td(e+640|0,Qf(1,113-b|0));Mm(e+672|0,l,o,k,j,G[e+640>>2],G[e+644>>2],G[e+648>>2],G[e+652>>2]);i=G[e+672>>2];h=G[e+676>>2];q=G[e+680>>2];r=G[e+684>>2];Fj(e+624|0,l,o,k,j,i,h,q,r);Zc(e+608|0,u,w,x,y,G[e+624>>2],G[e+628>>2],G[e+632>>2],G[e+636>>2]);k=G[e+616>>2];j=G[e+620>>2];l=G[e+608>>2];o=G[e+612>>2]}m=d+4&2047;$:{if((m|0)==(c|0)){break $}m=G[(e+784|0)+(m<<2)>>2];aa:{if(m>>>0<=499999999){if(!m&(d+5&2047)==(c|0)){break aa}td(e+496|0,+(f|0)*.25);Zc(e+480|0,i,h,q,r,G[e+496>>2],G[e+500>>2],G[e+504>>2],G[e+508>>2]);q=G[e+488>>2];r=G[e+492>>2];i=G[e+480>>2];h=G[e+484>>2];break aa}if((m|0)!=5e8){td(e+592|0,+(f|0)*.75);Zc(e+576|0,i,h,q,r,G[e+592>>2],G[e+596>>2],G[e+600>>2],G[e+604>>2]);q=G[e+584>>2];r=G[e+588>>2];i=G[e+576>>2];h=G[e+580>>2];break aa}I=+(f|0);if((d+5&2047)==(c|0)){td(e+528|0,I*.5);Zc(e+512|0,i,h,q,r,G[e+528>>2],G[e+532>>2],G[e+536>>2],G[e+540>>2]);q=G[e+520>>2];r=G[e+524>>2];i=G[e+512>>2];h=G[e+516>>2];break aa}td(e+560|0,I*.75);Zc(e+544|0,i,h,q,r,G[e+560>>2],G[e+564>>2],G[e+568>>2],G[e+572>>2]);q=G[e+552>>2];r=G[e+556>>2];i=G[e+544>>2];h=G[e+548>>2]}if((b|0)>111){break $}Mm(e+464|0,i,h,q,r,0,0,0,1073676288);if(Sf(G[e+464>>2],G[e+468>>2],G[e+472>>2],G[e+476>>2],0,0,0,0)){break $}Zc(e+448|0,i,h,q,r,0,0,0,1073676288);q=G[e+456>>2];r=G[e+460>>2];i=G[e+448>>2];h=G[e+452>>2]}Zc(e+432|0,l,o,k,j,i,h,q,r);Fj(e+416|0,G[e+432>>2],G[e+436>>2],G[e+440>>2],G[e+444>>2],u,w,x,y);k=G[e+424>>2];j=G[e+428>>2];l=G[e+416>>2];o=G[e+420>>2];ba:{if((-2-D|0)>=(t&2147483647)){break ba}G[e+408>>2]=k;G[e+412>>2]=j&2147483647;G[e+400>>2]=l;G[e+404>>2]=o;tc(e+384|0,l,o,k,j,0,0,0,1073610752);d=Zm(G[e+400>>2],G[e+404>>2],G[e+408>>2],G[e+412>>2],1081081856);c=(d|0)<0;k=c?k:G[e+392>>2];j=c?j:G[e+396>>2];l=c?l:G[e+384>>2];o=c?o:G[e+388>>2];s=((d|0)>=0)+s|0;if((Sf(i,h,q,r,0,0,0,0)|0)!=0&(c?n:n&(b|0)!=(g|0))?0:(s+110|0)<=(F|0)){break ba}G[48624]=68}Om(e+368|0,l,o,k,j,s);k=G[e+368>>2];j=G[e+372>>2];c=G[e+380>>2];b=G[e+376>>2]}G[p+40>>2]=b;G[p+44>>2]=c;G[p+32>>2]=k;G[p+36>>2]=j;Fa=e+8976|0;i=G[p+40>>2];h=G[p+44>>2];k=G[p+32>>2];j=G[p+36>>2];break a;case 3:break j;default:break m}}c=G[b+116>>2];if((c|0)>0|(c|0)>=0){G[b+4>>2]=G[b+4>>2]-1}break i}ca:{c=G[b+4>>2];da:{if((c|0)!=G[b+104>>2]){G[b+4>>2]=c+1;c=H[c|0];break da}c=jc(b)}if((c|0)==40){g=1;break ca}h=2147450880;if(G[b+116>>2]<0){break a}G[b+4>>2]=G[b+4>>2]-1;break a}while(1){ea:{c=G[b+4>>2];fa:{if((c|0)!=G[b+104>>2]){G[b+4>>2]=c+1;c=H[c|0];break fa}c=jc(b)}if(!(c-48>>>0<10|c-65>>>0<26|(c|0)==95)){if(c-97>>>0>=26){break ea}}g=g+1|0;continue}break}h=2147450880;if((c|0)==41){break a}c=G[b+116>>2];if((c|0)>0|(c|0)>=0){G[b+4>>2]=G[b+4>>2]-1}ga:{if(d){if(g){break ga}break a}break i}while(1){g=g-1|0;if((c|0)>0|(c|0)>=0){G[b+4>>2]=G[b+4>>2]-1}if(g){continue}break}break a}G[48624]=28;te(b,0,0)}h=0}G[a>>2]=k;G[a+4>>2]=j;G[a+8>>2]=i;G[a+12>>2]=h;Fa=p+48|0}function Yl(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,H=0,I=0,J=0,K=0,N=0,P=0;B=Fa+-64|0;Fa=B;G[935654]=-1571644103;G[935655]=1066524486;G[935656]=1413754136;G[935657]=1074340347;m=G[935572];G[935573]=m;G[935653]=0;h=ab(M(a,56));G[935658]=h;a:{b:{if(!h){break b}G[935653]=a;if((m|0)>=2){yb(36656);$a(G[29763]);a=G[935653]}if((a|0)>0){m=G[29763];while(1){if(G[935573]>=2){a=o<<3;e=L[a+b>>3];L[B+56>>3]=L[a+c>>3];L[B+48>>3]=e;gb(72389,B+48|0);$a(m)}a=G[935658]+M(o,56)|0;h=o<<3;f=L[h+b>>3];L[a>>3]=f;e=L[c+h>>3];L[a+8>>3]=e;g=L[467827];N=a,P=eb(f*g)*eb(e*g),L[N+16>>3]=P;i=f;f=L[467827];N=a,P=ib(i*f)*eb(e*f),L[N+24>>3]=P;f=L[467827];G[a+48>>2]=o;N=a,P=ib(e*f),L[N+32>>3]=P;o=o+1|0;if((o|0)>3]+L[s+32>>3];g=g+L[o+24>>3]+L[s+24>>3];e=e+L[o+16>>3]+L[s+16>>3];a=a+2|0;m=m+2|0;if((z|0)!=(m|0)){continue}break}}if(!(h&1)){break c}a=b+M(a,56)|0;f=f+L[a+32>>3];g=g+L[a+24>>3];e=e+L[a+16>>3]}i=f;f=V(f*f+(e*e+g*g));k=i/f;L[467834]=k;g=g/f;L[467833]=g;f=e/f;L[467832]=f;e=Db(g,f);j=L[467827];e=e/j;L[467830]=e;N=3742648,P=fc(k)/j,L[N>>3]=P;if(e>=360){while(1){e=e+-360;if(e>=360){continue}break}L[467830]=e}if(e<0){while(1){e=e+360;if(e<0){continue}break}L[467830]=e}a=0;if(G[935573]>=2){yb(38834);L[c+112>>3]=L[467832];gb(73105,c+112|0);L[c+96>>3]=L[467833];gb(73093,c+96|0);L[c+80>>3]=L[467834];gb(73081,c+80|0);L[c+64>>3]=L[467830];gb(71809,c- -64|0);L[c+48>>3]=L[467831];gb(90223,c+48|0);h=G[935653]}b=G[935658];e=1;d:{if((h|0)<=0){m=0;break d}m=0;while(1){o=b+M(a,56)|0;j=L[o+32>>3]*k+(L[o+16>>3]*f+g*L[o+24>>3]);o=j>3]=P;e=L[b>>3];a=b+M(m,56)|0;L[b>>3]=L[a>>3];L[a>>3]=e;e=L[b+8>>3];L[b+8>>3]=L[a+8>>3];L[a+8>>3]=e;e=L[b+16>>3];L[b+16>>3]=L[a+16>>3];L[a+16>>3]=e;e=L[b+24>>3];L[b+24>>3]=L[a+24>>3];L[a+24>>3]=e;e=L[b+32>>3];L[b+32>>3]=L[a+32>>3];L[a+32>>3]=e;m=G[b+48>>2];G[b+48>>2]=G[a+48>>2];G[a+48>>2]=m;G[b+52>>2]=0;G[b+40>>2]=0;G[b+44>>2]=-1074790400;e=L[b+16>>3];f=L[467833];g=L[b+24>>3];l=L[467832];k=e*f-g*l;v=g;g=L[467834];i=L[b+32>>3];j=v*g-i*f;l=i*l-e*g;e=V(k*k+(j*j+l*l));if(!(!(e>3]=e;gb(73024,c+32|0);$a(G[29763])}if(!(e<=0)){l=l/e;j=j/e;k=k/e}if(G[935653]>=2){a=G[935658];p=-j;h=G[29763];m=1;while(1){o=M(m,56);b=o+a|0;G[b+52>>2]=0;e=L[23878];i=L[a+16>>3];n=L[b+16>>3];g=L[a+24>>3];f=L[b+24>>3];e:{if(!(!(e>O(i-n))|!(e>O(g-f))|!(e>O(L[a+32>>3]-L[b+32>>3])))){G[b+40>>2]=0;G[b+44>>2]=0;G[b+52>>2]=1;G[935659]=G[935659]+1;break e}v=e;e=i*f-g*n;r=L[b+32>>3];q=L[a+32>>3];g=g*r-q*f;f=n*q-i*r;i=V(e*e+(g*g+f*f));if(!(!(v>i)|G[935573]<3)){L[c+16>>3]=i;gb(73024,c+16|0);$a(h)}if(!(i<=0)){f=f/i;g=g/i;e=e/i}i=j*f-l*g;f=l*e-k*f;g=p*e+k*g;e=V(i*i+(f*f+g*g));if(!(!(e>3]=e;gb(73024,c);$a(h)}f:{if(e<=0){e=0;break f}i=i/e;g=g/e;f=f/e}a=G[935658];b=o+a|0;L[b+40>>3]=e;if(!(L[a+32>>3]*i+(L[a+16>>3]*f+g*L[a+24>>3])<0)){break e}L[b+40>>3]=-e}m=m+1|0;if((m|0)=2){ej();a=G[935573]}if((a|0)>0){b=0;a=Fa+-64|0;Fa=a;yb(30686);L[a+48>>3]=L[467830];L[a+56>>3]=L[467831];gb(71476,a+48|0);L[a+32>>3]=L[467830];L[a+40>>3]=L[467831];gb(71497,a+32|0);e=L[467837]*2.2;L[a+16>>3]=e;L[a+24>>3]=e;gb(71538,a+16|0);yb(19839);yb(11636);yb(27702);yb(29237);if(G[935653]>0){while(1){c=G[935658]+M(b,56)|0;e=L[c+8>>3];L[a>>3]=L[c>>3];L[a+8>>3]=e;gb(68556,a);b=b+1|0;if((b|0)=2){yb(37661);ej()}g:{if(G[935659]<=0){break g}b=0;c=G[935653];if((c|0)>0){m=G[935658];o=0;while(1){a=m+M(o,56)|0;if(!G[a+52>>2]){c=m+M(b,56)|0;L[c>>3]=L[a>>3];L[c+8>>3]=L[a+8>>3];L[c+16>>3]=L[a+16>>3];L[c+24>>3]=L[a+24>>3];L[c+32>>3]=L[a+32>>3];L[c+40>>3]=L[a+40>>3];a=G[a+48>>2];G[c+52>>2]=0;G[c+48>>2]=a;c=G[935653];b=b+1|0}o=o+1|0;if((o|0)<(c|0)){continue}break}}G[935653]=b;if(G[935573]<2){break g}yb(40091);ej()}h=Fa-160|0;Fa=h;c=G[935658];h:{b=ab(8);if(b){i:{G[b+4>>2]=0;G[b>>2]=c;a=ab(8);if(!a){break i}G[a+4>>2]=b;G[a>>2]=c+56;j:{if(G[935653]>=3){E=G[29763];o=2;while(1){k:{if(G[935573]<2){break k}yb(48638);b=G[(G[935658]+M(o,56)|0)+48>>2];G[h+144>>2]=o;G[h+148>>2]=b;kb(86245,h+144|0);b=a;if(!a){yb(17300);break k}while(1){c=G[b>>2];m=G[c+48>>2];e=L[c>>3];f=L[c+8>>3];g=L[c+16>>3];k=L[c+24>>3];L[h+136>>3]=L[c+32>>3];L[h+128>>3]=k;L[h+120>>3]=g;L[h+112>>3]=f;L[h+104>>3]=e;G[h+96>>2]=m;gb(71391,h+96|0);b=G[b+4>>2];if(b){continue}break}}m=G[a+4>>2];l:{if(m){s=G[935658];b=G[a>>2];c=a;break l}s=G[935658];c=ab(8);if(!c){break i}G[c+4>>2]=a;b=M(o,56)+s|0;G[c>>2]=b;o=o+1|0;m=a}a=s;s=M(o,56);z=a+s|0;a=Fa-48|0;Fa=a;m=G[m>>2];f=L[m+16>>3];g=L[b+24>>3];k=L[m+24>>3];j=L[b+16>>3];e=f*g-k*j;i=k;k=L[b+32>>3];l=L[m+32>>3];g=i*k-l*g;f=l*j-f*k;k=V(e*e+(g*g+f*f));if(!(!(k>3]=k;gb(73024,a+32|0);$a(G[29763])}if(!(k<=0)){f=f/k;g=g/k;e=e/k}l=L[b+16>>3];j=L[z+24>>3];i=L[b+24>>3];n=L[z+16>>3];k=l*j-i*n;v=i;i=L[z+32>>3];p=L[b+32>>3];j=v*i-p*j;l=p*n-l*i;i=V(k*k+(j*j+l*l));if(!(!(i>3]=i;gb(73024,a+16|0);$a(G[29763])}if(!(i<=0)){l=l/i;j=j/i;k=k/i}i=j*f-l*g;f=l*e-k*f;e=g*k-j*e;g=V(i*i+(f*f+e*e));if(!(!(g>3]=g;gb(73024,a);$a(G[29763])}if(!(g<=0)){i=i/g;f=f/g;e=e/g}Fa=a+48|0;a=G[935573];m:{if(!(L[b+32>>3]*i+(L[b+16>>3]*f+e*L[b+24>>3])>0)){if((a|0)>=2){a=G[(s+G[935658]|0)+48>>2];b=G[b+48>>2];G[h+80>>2]=G[m+48>>2];G[h+84>>2]=b;G[h+88>>2]=a;G[h+92>>2]=a;kb(88440,h+80|0);$a(E)}b=G[935658];a=ab(8);if(!a){break i}G[a+4>>2]=c;G[a>>2]=b+s;o=o+1|0;break m}if((a|0)>=3){a=G[(s+G[935658]|0)+48>>2];s=G[G[c>>2]+48>>2];b=G[b+48>>2];G[h+64>>2]=G[m+48>>2];G[h+68>>2]=b;G[h+72>>2]=a;G[h+76>>2]=s;kb(88402,h- -64|0);$a(E)}a=G[c+4>>2];Wa(c)}n:{if(G[935573]<2){break n}b=G[(G[935658]+M(o,56)|0)+48>>2];G[h+48>>2]=o;G[h+52>>2]=b;kb(86289,h+48|0);b=a;if(!a){yb(17300);break n}while(1){c=G[b>>2];m=G[c+48>>2];e=L[c>>3];f=L[c+8>>3];g=L[c+16>>3];k=L[c+24>>3];L[h+40>>3]=L[c+32>>3];L[h+32>>3]=k;L[h+24>>3]=g;L[h+16>>3]=f;L[h+8>>3]=e;G[h>>2]=m;gb(71391,h);b=G[b+4>>2];if(b){continue}break}}if(G[935653]>(o|0)){continue}break}if((o|0)>2){break j}}a=0}Fa=h+160|0;break h}}yb(65598);sc(1);W()}G[935652]=a;if(!a){break b}a=G[935573];if((a|0)>=2){yb(37307);o=G[935652];o:{if(o){while(1){a=G[o>>2];b=G[a+48>>2];e=L[a>>3];f=L[a+8>>3];g=L[a+16>>3];k=L[a+24>>3];L[B+40>>3]=L[a+32>>3];L[B+32>>3]=k;L[B+24>>3]=g;L[B+16>>3]=f;L[B+8>>3]=e;G[B>>2]=b;gb(71391,B);o=G[o+4>>2];if(o){continue}break o}}yb(17300)}a=G[935573]}if((a|0)>0){a=Fa-48|0;Fa=a;b=G[935652];p:{if(!b){break p}yb(3901);c=G[b>>2];e=L[c>>3];L[a+40>>3]=L[c+8>>3];L[a+32>>3]=e;gb(71654,a+32|0);c=G[b+4>>2];if(!c){break p}while(1){m=G[c>>2];e=L[m>>3];L[a+24>>3]=L[m+8>>3];L[a+16>>3]=e;gb(71634,a+16|0);c=G[c+4>>2];if(c){continue}break}}b=G[b>>2];e=L[b>>3];L[a+8>>3]=L[b+8>>3];L[a>>3]=e;gb(71634,a);yb(4674);$a(G[29763]);Fa=a+48|0}o=0;q:{switch(d|0){case 0:b=0;c=0;h=Fa-592|0;Fa=h;a=G[935652];r:{if(a){e=999;f=-999;s=1;m=a;while(1){d=G[m>>2];g=L[d+32>>3];s=g>0?0:s;z=e>g;e=z?g:e;c=z?d:c;z=f>2];if(m){continue}break}if((s|0)!=1){break r}}c=b}m=G[935573];if((m|0)>=2){G[h+576>>2]=G[c+48>>2];kb(75467,h+576|0);$a(G[29763]);m=G[935573]}e=L[c+24>>3];f=L[c+16>>3];g=e*0+f*-0;j=L[c+32>>3];k=j*0-e;l=j*-0+f;e=V(g*g+(k*k+l*l));if(!(!(e>3]=e;gb(73024,h+560|0);$a(G[29763])}if(!(e<=0)){l=l/e;k=k/e;g=g/e}e=L[c+16>>3];f=L[c+24>>3];q=e*l-f*k;i=f*g;f=L[c+32>>3];w=i-f*l;x=k*f-e*g;e=V(q*q+(w*w+x*x));if(!(!(e>3]=e;gb(73024,h+544|0);$a(G[29763])}if(!(e<=0)){x=x/e;w=w/e;q=q/e}r=-k;t=-l;s:{if(!a){s=G[935573];n=L[23878];break s}s=G[935573];n=L[23878];z=G[29763];p=999;d=a;while(1){c=G[d>>2];d=G[d+4>>2];f=L[c+16>>3];e=L[c+24>>3];i=f*l+e*r;j=L[c+32>>3];e=e*g+j*t;f=k*j-f*g;j=V(i*i+(e*e+f*f));if(!(!(j>3]=j;gb(73024,h+528|0);$a(z);s=G[935573];n=L[23878]}if(!(j<=0)){i=i/j;f=f/j;e=e/j}e=i*q+(e*w+x*f);m=e>3];f=L[b+24>>3];j=e*l+f*r;i=f*g;f=L[b+32>>3];p=i+f*t;u=k*f-e*g;e=V(j*j+(p*p+u*u));if(!(!(e>3]=e;gb(73024,h+512|0);$a(G[29763])}if(!(e<=0)){u=u/e;p=p/e;j=j/e}if(G[935573]>=2){G[h+496>>2]=G[b+48>>2];kb(75446,h+496|0);$a(G[29763])}e=999;f=-999;d=G[a>>2];c=d;b=a;while(1){m=G[b>>2];i=L[m+32>>3]*g+(L[m+16>>3]*k+l*L[m+24>>3]);s=i>2];if(b){continue}break};f=L[c+24>>3];i=L[c+32>>3];y=f*g+i*t;n=L[c+16>>3];A=k*i-n*g;e=y*f-A*n;v=A*i;A=n*l+f*r;f=v-A*f;n=n*A-y*i;i=V(e*e+(f*f+n*n));if(!(!(i>3]=i;gb(73024,h+480|0);$a(G[29763])}if(!(i<=0)){n=n/i;f=f/i;e=e/i}i=L[d+24>>3];y=L[d+32>>3];A=i*g+y*t;t=L[d+16>>3];k=k*y-t*g;g=A*i-k*t;l=t*l+i*r;k=k*y-l*i;l=t*l-A*y;i=V(g*g+(k*k+l*l));if(!(!(i>3]=i;gb(73024,h+464|0);$a(G[29763])}if(!(i<=0)){l=l/i;k=k/i;g=g/i}m=G[935573];if((m|0)>=2){yb(86139);L[h+448>>3]=q;L[h+440>>3]=x;L[h+432>>3]=w;gb(73059,h+432|0);L[h+416>>3]=j;L[h+408>>3]=u;L[h+400>>3]=p;gb(73059,h+400|0);L[h+384>>3]=e;L[h+376>>3]=n;L[h+368>>3]=f;gb(73059,h+368|0);L[h+352>>3]=g;L[h+344>>3]=l;L[h+336>>3]=k;gb(73059,h+336|0);$a(G[29763]);m=G[935573]}i=w*n-x*f;r=x*e-q*n;t=q*f-w*e;y=V(i*i+(r*r+t*t));if(!(!(y>3]=y;gb(73024,h+320|0);$a(G[29763])}if(!(y<=0)){t=t/y;r=r/y;i=i/y}b=i*L[c+32>>3]+(r*L[c+16>>3]+t*L[c+24>>3])<0;t=b?-t:t;y=b?-r:r;r=Db(t,y);A=b?-i:i;J=fc(A);F=L[467827];i=r/F;if(i>=360){while(1){i=i+-360;if(i>=360){continue}break}}if(i<0){while(1){i=i+360;if(i<0){continue}break}}r=u*e+j*-n;n=p*n+u*-f;e=j*f-p*e;f=V(n*n+(r*r+e*e));if(!(!(f>3]=f;gb(73024,h+304|0);$a(G[29763])}if(!(f<=0)){n=n/f;r=r/f;e=e/f}b=n*L[c+32>>3]+(r*L[c+16>>3]+e*L[c+24>>3])<0;C=b?-e:e;r=b?-r:r;e=Db(C,r);D=b?-n:n;K=fc(D);H=L[467827];e=e/H;if(e>=360){while(1){e=e+-360;if(e>=360){continue}break}}if(e<0){while(1){e=e+360;if(e<0){continue}break}}n=-p;f=p*l-u*k;p=u*g-j*l;j=n*g+j*k;n=V(f*f+(p*p+j*j));if(!(!(n>3]=n;gb(73024,h+288|0);$a(G[29763])}if(!(n<=0)){j=j/n;p=p/n;f=f/n}b=f*L[d+32>>3]+(p*L[d+16>>3]+j*L[d+24>>3])<0;n=b?-j:j;p=b?-p:p;j=Db(n,p);u=b?-f:f;v=fc(u);I=L[467827];f=j/I;if(f>=360){while(1){f=f+-360;if(f>=360){continue}break}}if(f<0){while(1){f=f+360;if(f<0){continue}break}}j=w*l+x*-k;l=x*g+q*-l;g=-w*g+q*k;k=V(j*j+(l*l+g*g));if(!(!(k>3]=k;gb(73024,h+272|0);$a(G[29763])}if(!(k<=0)){j=j/k;l=l/k;g=g/k}b=j*L[d+32>>3]+(l*L[d+16>>3]+g*L[d+24>>3])<0;k=b?-g:g;l=b?-l:l;g=Db(k,l);j=b?-j:j;q=fc(j);w=L[467827];g=g/w;if(g>=360){while(1){g=g+-360;if(g>=360){continue}break}}if(g<0){while(1){g=g+360;if(g<0){continue}break}}m=G[935573];if((m|0)>=2){yb(86125);L[h+264>>3]=J/F;L[h+256>>3]=i;gb(71544,h+256|0);L[h+248>>3]=K/H;L[h+240>>3]=e;gb(71544,h+240|0);L[h+232>>3]=v/I;L[h+224>>3]=f;gb(71544,h+224|0);L[h+216>>3]=q/w;L[h+208>>3]=g;gb(71544,h+208|0);$a(G[29763]);m=G[935573]}f=t*u-A*n;e=D*l-r*j;g=A*p-y*u;j=C*j-D*k;i=f*e-g*j;v=g;g=r*k-C*l;k=y*n-t*p;e=v*g-k*e;f=k*j-f*g;g=V(i*i+(e*e+f*f));if(!(!(g>3]=g;gb(73024,h+192|0);$a(G[29763])}if(!(g<=0)){i=i/g;f=f/g;e=e/g}b=i*A+(e*y+t*f)<0;n=b?-f:f;p=b?-e:e;e=Db(n,p);r=b?-i:i;f=fc(r);j=L[467827];k=e/j;if(k>=360){while(1){k=k+-360;if(k>=360){continue}break}}if(k<0){while(1){k=k+360;if(k<0){continue}break}}i=f/j;g=j*i;e=ib(g);L[467844]=e;L[467858]=e;q=j*0;f=eb(q);l=eb(g);w=f*l;L[467850]=w;g=ib(q);q=l*g;L[467847]=q;x=j*k;j=ib(x);u=l*j;L[467843]=u;v=l;l=eb(x);x=v*l;L[467842]=x;L[467860]=w;L[467859]=q;L[467855]=u;L[467852]=x;q=e*-f;w=g*l;L[467849]=j*q-w;x=g*j;L[467848]=x+q*l;q=f*l;u=e*-g;L[467846]=q+j*u;v=u*l;u=f*j;L[467845]=v-u;j=e*-j;L[467857]=f*j-w;L[467856]=j*g+q;e=e*-l;L[467854]=f*e+x;L[467853]=e*g-u;e=1e20;f=-1e20;g=-1e20;j=1e20;while(1){b=G[a>>2];Vl(L[b>>3],L[b+8>>3]);l=L[467839];f=fl?l:e;l=L[467838];g=gl?l:j;a=G[a+4>>2];if(a){continue}break};if(G[935573]>=2){L[h+176>>3]=j;gb(71604,h+176|0);L[h+160>>3]=g;gb(71574,h+160|0);L[h+144>>3]=e;gb(71589,h+144|0);L[h+128>>3]=f;gb(71559,h+128|0);$a(G[29763])}L[467819]=r;L[467818]=n;L[467817]=p;L[467816]=i;L[467815]=k;G[935648]=0;G[935649]=0;v=i;i=L[467827];n=v*i;l=ib(n);L[467844]=l;L[467858]=l;e=O(e);f=O(f);e=e>f?e:f;p=e+e;L[467823]=p;e=O(j);f=O(g);e=e>f?e:f;r=e+e;L[467822]=r;f=i*0;e=eb(f);j=eb(n);n=e*j;L[467850]=n;f=ib(f);q=j*f;L[467847]=q;k=k*i;g=ib(k);i=j*g;L[467843]=i;k=eb(k);j=j*k;L[467842]=j;L[467860]=n;L[467859]=q;L[467855]=i;L[467852]=j;j=l*-e;i=f*k;L[467849]=g*j-i;n=f*g;L[467848]=n+k*j;j=e*k;q=l*-f;L[467846]=j+g*q;v=k*q;q=e*g;L[467845]=v-q;g=l*-g;L[467857]=e*g-i;L[467856]=g*f+j;i=e;e=l*-k;L[467854]=i*e+n;L[467853]=e*f-q;mf(r*-.5,p*-.5);L[467787]=L[467840];L[467788]=L[467841];mf(L[467822]*.5,L[467823]*-.5);L[467794]=L[467840];L[467795]=L[467841];mf(L[467822]*.5,L[467823]*.5);L[467801]=L[467840];L[467802]=L[467841];mf(L[467822]*-.5,L[467823]*.5);L[467808]=L[467840];L[467809]=L[467841];if(G[935573]>=2){L[h+112>>3]=L[467815];L[h+120>>3]=L[467816];gb(71674,h+112|0);L[h+96>>3]=L[467822];gb(71917,h+96|0);L[h+80>>3]=L[467823];gb(71843,h+80|0);L[h+64>>3]=L[467824];gb(71823,h- -64|0);L[h+48>>3]=L[467787];L[h+56>>3]=L[467788];gb(71782,h+48|0);L[h+32>>3]=L[467794];L[h+40>>3]=L[467795];gb(71755,h+32|0);L[h+16>>3]=L[467801];L[h+24>>3]=L[467802];gb(71728,h+16|0);L[h>>3]=L[467808];L[h+8>>3]=L[467809];gb(71701,h);$a(G[29763])}Fa=h+592|0;break a;case 1:Wl(G[935652]);break a;case 2:a=G[935652];Wl(a);G[935650]=0;G[935651]=0;if(!a){break a}g=L[467827];k=L[467819];j=L[467818];l=L[467817];e=0;while(1){b=G[a>>2];f=Sc(L[b+32>>3]*k+(L[b+16>>3]*l+j*L[b+24>>3]))/g;if(f>e){L[467825]=f;e=f}a=G[a+4>>2];if(a){continue}break};break a;case 3:break a;default:break q}}a=G[935652];if(G[935653]>0){Wa(G[935658])}if(!a){break b}while(1){b=G[a+4>>2];Wa(a);a=b;if(a){continue}break}}o=-1}Fa=B- -64|0;return o}function Mk(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;d=-2;a:{b:{c:{d:{if(!G[a+36>>2]|(!a|!G[a+32>>2])){break d}c=G[a+28>>2];if(!c|G[c>>2]!=(a|0)){break d}e:{f:{e=G[c+4>>2];switch(e-57|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 13:case 14:case 15:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 47:case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:break d;case 0:case 12:case 16:case 34:case 46:case 56:break e;default:break f}}if((e|0)==666){break e}if((e|0)!=42){break d}}if(b>>>0>5){break d}g:{h:{if(!G[a+12>>2]){break h}f=G[a+4>>2];if(G[a>>2]?0:f){break h}if((b|0)==4|(e|0)!=666){break g}}G[a+24>>2]=G[26248];return-2}if(!G[a+16>>2]){break b}d=G[c+40>>2];G[c+40>>2]=b;i:{if(G[c+20>>2]){cd(c);h=G[c+20>>2];e=G[a+16>>2];d=e>>>0>h>>>0?h:e;j:{if(!d){break j}bb(G[a+12>>2],G[c+16>>2],d);G[a+12>>2]=d+G[a+12>>2];G[c+16>>2]=d+G[c+16>>2];G[a+20>>2]=d+G[a+20>>2];e=G[a+16>>2]-d|0;G[a+16>>2]=e;f=G[c+20>>2];h=f-d|0;G[c+20>>2]=h;if((d|0)!=(f|0)){break j}G[c+16>>2]=G[c+8>>2]}if(e){e=G[c+4>>2];break i}break a}if((b|0)==4|f|((b<<1)+(b>>>0>4?-9:0)|0)>((d<<1)+((d|0)>4?-9:0)|0)){break i}break b}k:{l:{m:{n:{if((e|0)!=42){if((e|0)!=666){break n}if(!G[a+4>>2]){break m}break b}f=(G[c+48>>2]<<12)-30720|0;d=0;o:{if(G[c+136>>2]>1){break o}e=G[c+132>>2];if((e|0)<2){break o}d=64;if(e>>>0<6){break o}d=(e|0)==6?128:192}G[c+20>>2]=h+1;d=d|f;d=G[c+108>>2]?d|32:d;E[G[c+8>>2]+h|0]=d>>>8;e=G[c+20>>2];G[c+20>>2]=e+1;E[e+G[c+8>>2]|0]=(d|(d>>>0)%31)^31;if(G[c+108>>2]){d=G[a+48>>2];e=G[c+20>>2];G[c+20>>2]=e+1;E[e+G[c+8>>2]|0]=d>>>24;e=G[c+20>>2];G[c+20>>2]=e+1;E[e+G[c+8>>2]|0]=d>>>16;d=G[a+48>>2];e=G[c+20>>2];G[c+20>>2]=e+1;E[e+G[c+8>>2]|0]=d>>>8;e=G[c+20>>2];G[c+20>>2]=e+1;E[e+G[c+8>>2]|0]=d}m=a,n=gf(0,0,0),G[m+48>>2]=n;G[c+4>>2]=113;Mg(a);if(G[c+20>>2]){break a}e=G[c+4>>2]}p:{q:{r:{s:{t:{u:{if((e|0)==57){m=a,n=Oc(0,0,0),G[m+48>>2]=n;d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=31;d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=139;d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=8;d=G[c+28>>2];if(d){break u}d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=0;d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=0;d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=0;d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=0;d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=0;d=2;e=G[c+132>>2];if((e|0)!=9){d=G[c+136>>2]>1?4:((e|0)<2)<<2}e=G[c+20>>2];G[c+20>>2]=e+1;E[e+G[c+8>>2]|0]=d;d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=3;G[c+4>>2]=113;Mg(a);if(G[c+20>>2]){break a}e=G[c+4>>2]}switch(e-69|0){case 34:break q;case 22:break r;case 4:break s;case 0:break t;default:break p}}e=G[d+36>>2];f=G[d+28>>2];g=G[d+16>>2];h=G[d+44>>2];i=G[d>>2];j=G[c+20>>2];G[c+20>>2]=j+1;d=2;E[j+G[c+8>>2]|0]=((h|0)!=0)<<1|(i|0)!=0|((g|0)!=0)<<2|((f|0)!=0)<<3|((e|0)!=0)<<4;e=G[G[c+28>>2]+4>>2];f=G[c+20>>2];G[c+20>>2]=f+1;E[f+G[c+8>>2]|0]=e;e=G[G[c+28>>2]+4>>2];f=G[c+20>>2];G[c+20>>2]=f+1;E[f+G[c+8>>2]|0]=e>>>8;e=I[G[c+28>>2]+6>>1];f=G[c+20>>2];G[c+20>>2]=f+1;E[f+G[c+8>>2]|0]=e;e=H[G[c+28>>2]+7|0];f=G[c+20>>2];G[c+20>>2]=f+1;E[f+G[c+8>>2]|0]=e;e=G[c+132>>2];if((e|0)!=9){d=G[c+136>>2]>1?4:((e|0)<2)<<2}e=G[c+20>>2];G[c+20>>2]=e+1;E[e+G[c+8>>2]|0]=d;d=G[G[c+28>>2]+12>>2];e=G[c+20>>2];G[c+20>>2]=e+1;E[e+G[c+8>>2]|0]=d;d=G[c+28>>2];if(G[d+16>>2]){d=G[d+20>>2];e=G[c+20>>2];G[c+20>>2]=e+1;E[e+G[c+8>>2]|0]=d;d=G[G[c+28>>2]+20>>2];e=G[c+20>>2];G[c+20>>2]=e+1;E[e+G[c+8>>2]|0]=d>>>8;d=G[c+28>>2]}if(G[d+44>>2]){m=a,n=Oc(G[a+48>>2],G[c+8>>2],G[c+20>>2]),G[m+48>>2]=n}G[c+4>>2]=69;G[c+32>>2]=0}f=G[c+28>>2];h=G[f+16>>2];if(h){e=G[c+12>>2];d=G[c+20>>2];g=G[c+32>>2];f=I[f+20>>1]-g|0;if(e>>>0>>0){while(1){g=e-d|0;bb(G[c+8>>2]+d|0,G[G[c+28>>2]+16>>2]+G[c+32>>2]|0,g);e=G[c+12>>2];G[c+20>>2]=e;if(!(!G[G[c+28>>2]+44>>2]|d>>>0>=e>>>0)){m=a,n=Oc(G[a+48>>2],G[c+8>>2]+d|0,e-d|0),G[m+48>>2]=n}G[c+32>>2]=g+G[c+32>>2];d=G[a+28>>2];cd(d);e=G[d+20>>2];h=G[a+16>>2];e=e>>>0>>0?e:h;v:{if(!e){break v}bb(G[a+12>>2],G[d+16>>2],e);G[a+12>>2]=e+G[a+12>>2];G[d+16>>2]=e+G[d+16>>2];G[a+20>>2]=e+G[a+20>>2];G[a+16>>2]=G[a+16>>2]-e;h=G[d+20>>2];G[d+20>>2]=h-e;if((e|0)!=(h|0)){break v}G[d+16>>2]=G[d+8>>2]}if(G[c+20>>2]){break a}d=0;f=f-g|0;e=G[c+12>>2];if(f>>>0>e>>>0){continue}break}h=G[G[c+28>>2]+16>>2];g=G[c+32>>2]}bb(G[c+8>>2]+d|0,g+h|0,f);e=G[c+20>>2]+f|0;G[c+20>>2]=e;if(!(!G[G[c+28>>2]+44>>2]|d>>>0>=e>>>0)){m=a,n=Oc(G[a+48>>2],G[c+8>>2]+d|0,e-d|0),G[m+48>>2]=n}G[c+32>>2]=0}G[c+4>>2]=73}if(G[G[c+28>>2]+28>>2]){f=G[c+20>>2];while(1){w:{d=G[c+20>>2];if((d|0)!=G[c+12>>2]){break w}if(!(!G[G[c+28>>2]+44>>2]|d>>>0<=f>>>0)){m=a,n=Oc(G[a+48>>2],G[c+8>>2]+f|0,d-f|0),G[m+48>>2]=n}d=G[a+28>>2];cd(d);e=G[d+20>>2];f=G[a+16>>2];e=e>>>0>>0?e:f;x:{if(!e){break x}bb(G[a+12>>2],G[d+16>>2],e);G[a+12>>2]=e+G[a+12>>2];G[d+16>>2]=e+G[d+16>>2];G[a+20>>2]=e+G[a+20>>2];G[a+16>>2]=G[a+16>>2]-e;f=G[d+20>>2];G[d+20>>2]=f-e;if((e|0)!=(f|0)){break x}G[d+16>>2]=G[d+8>>2]}d=0;f=0;if(!G[c+20>>2]){break w}break a}e=G[G[c+28>>2]+28>>2];g=G[c+32>>2];G[c+32>>2]=g+1;e=H[e+g|0];G[c+20>>2]=d+1;E[G[c+8>>2]+d|0]=e;if(e){continue}break}y:{if(!G[G[c+28>>2]+44>>2]){break y}d=G[c+20>>2];if(d>>>0<=f>>>0){break y}m=a,n=Oc(G[a+48>>2],G[c+8>>2]+f|0,d-f|0),G[m+48>>2]=n}G[c+32>>2]=0}G[c+4>>2]=91}z:{if(!G[G[c+28>>2]+36>>2]){break z}f=G[c+20>>2];while(1){A:{d=G[c+20>>2];if((d|0)!=G[c+12>>2]){break A}if(!(!G[G[c+28>>2]+44>>2]|d>>>0<=f>>>0)){m=a,n=Oc(G[a+48>>2],G[c+8>>2]+f|0,d-f|0),G[m+48>>2]=n}d=G[a+28>>2];cd(d);e=G[d+20>>2];f=G[a+16>>2];e=e>>>0>>0?e:f;B:{if(!e){break B}bb(G[a+12>>2],G[d+16>>2],e);G[a+12>>2]=e+G[a+12>>2];G[d+16>>2]=e+G[d+16>>2];G[a+20>>2]=e+G[a+20>>2];G[a+16>>2]=G[a+16>>2]-e;f=G[d+20>>2];G[d+20>>2]=f-e;if((e|0)!=(f|0)){break B}G[d+16>>2]=G[d+8>>2]}d=0;f=0;if(!G[c+20>>2]){break A}break a}e=G[G[c+28>>2]+36>>2];g=G[c+32>>2];G[c+32>>2]=g+1;e=H[e+g|0];G[c+20>>2]=d+1;E[G[c+8>>2]+d|0]=e;if(e){continue}break}if(!G[G[c+28>>2]+44>>2]){break z}d=G[c+20>>2];if(d>>>0<=f>>>0){break z}m=a,n=Oc(G[a+48>>2],G[c+8>>2]+f|0,d-f|0),G[m+48>>2]=n}G[c+4>>2]=103}if(G[G[c+28>>2]+44>>2]){d=G[c+20>>2];if(J[c+12>>2]>>0){Mg(a);if(G[c+20>>2]){break c}d=0}e=G[a+48>>2];G[c+20>>2]=d+1;E[G[c+8>>2]+d|0]=e;d=G[a+48>>2];e=G[c+20>>2];G[c+20>>2]=e+1;E[e+G[c+8>>2]|0]=d>>>8;m=a,n=Oc(0,0,0),G[m+48>>2]=n}G[c+4>>2]=113;Mg(a);if(!G[c+20>>2]){break p}break a}if(G[a+4>>2]){break l}}if(G[c+116>>2]){break l}if(!b|G[c+4>>2]==666){break k}}d=G[c+132>>2];C:{if(!d){e=jp(c,b);break C}D:{switch(G[c+136>>2]-2|0){case 0:E:{F:{while(1){G:{if(G[c+116>>2]){break G}Ri(c);if(G[c+116>>2]){break G}if(b){break F}e=0;break E}G[c+96>>2]=0;d=H[G[c+56>>2]+G[c+108>>2]|0];e=G[c+5792>>2];F[G[c+5796>>2]+(e<<1)>>1]=0;G[c+5792>>2]=e+1;E[e+G[c+5784>>2]|0]=d;d=(d<<2)+c|0;F[d+148>>1]=I[d+148>>1]+1;G[c+116>>2]=G[c+116>>2]-1;f=G[c+108>>2]+1|0;G[c+108>>2]=f;if(G[c+5792>>2]!=(G[c+5788>>2]-1|0)){continue}d=G[c+92>>2];if((d|0)>=0){e=d+G[c+56>>2]|0}else{e=0}ge(c,e,f-d|0,0);G[c+92>>2]=G[c+108>>2];d=G[c>>2];e=G[d+28>>2];cd(e);f=G[e+20>>2];g=G[d+16>>2];f=f>>>0>>0?f:g;H:{if(!f){break H}bb(G[d+12>>2],G[e+16>>2],f);G[d+12>>2]=f+G[d+12>>2];G[e+16>>2]=f+G[e+16>>2];G[d+20>>2]=f+G[d+20>>2];G[d+16>>2]=G[d+16>>2]-f;d=G[e+20>>2];G[e+20>>2]=d-f;if((d|0)!=(f|0)){break H}G[e+16>>2]=G[e+8>>2]}if(G[G[c>>2]+16>>2]){continue}break}e=0;break E}G[c+5812>>2]=0;if((b|0)==4){d=G[c+92>>2];if((d|0)>=0){e=d+G[c+56>>2]|0}else{e=0}ge(c,e,G[c+108>>2]-d|0,1);G[c+92>>2]=G[c+108>>2];d=G[c>>2];e=G[d+28>>2];cd(e);f=G[e+20>>2];g=G[d+16>>2];f=f>>>0>>0?f:g;I:{if(!f){break I}bb(G[d+12>>2],G[e+16>>2],f);G[d+12>>2]=f+G[d+12>>2];G[e+16>>2]=f+G[e+16>>2];G[d+20>>2]=f+G[d+20>>2];G[d+16>>2]=G[d+16>>2]-f;d=G[e+20>>2];G[e+20>>2]=d-f;if((d|0)!=(f|0)){break I}G[e+16>>2]=G[e+8>>2]}e=G[G[c>>2]+16>>2]?3:2;break E}J:{if(!G[c+5792>>2]){break J}d=G[c+92>>2];if((d|0)>=0){e=d+G[c+56>>2]|0}else{e=0}ge(c,e,G[c+108>>2]-d|0,0);G[c+92>>2]=G[c+108>>2];d=G[c>>2];e=G[d+28>>2];cd(e);f=G[e+20>>2];g=G[d+16>>2];f=f>>>0>>0?f:g;K:{if(!f){break K}bb(G[d+12>>2],G[e+16>>2],f);G[d+12>>2]=f+G[d+12>>2];G[e+16>>2]=f+G[e+16>>2];G[d+20>>2]=f+G[d+20>>2];G[d+16>>2]=G[d+16>>2]-f;d=G[e+20>>2];G[e+20>>2]=d-f;if((d|0)!=(f|0)){break K}G[e+16>>2]=G[e+8>>2]}if(G[G[c>>2]+16>>2]){break J}e=0;break E}e=1}break C;case 1:L:{while(1){M:{N:{O:{g=G[c+116>>2];if(g>>>0>=259){G[c+96>>2]=0;break O}Ri(c);g=G[c+116>>2];e=0;if(!(g>>>0>=259|b)){break L}if(g){G[c+96>>2]=0;if(g>>>0>2){break O}j=G[c+108>>2];break N}G[c+5812>>2]=0;if((b|0)==4){d=G[c+92>>2];if((d|0)>=0){e=d+G[c+56>>2]|0}else{e=0}ge(c,e,G[c+108>>2]-d|0,1);G[c+92>>2]=G[c+108>>2];d=G[c>>2];e=G[d+28>>2];cd(e);f=G[e+20>>2];g=G[d+16>>2];f=f>>>0>>0?f:g;P:{if(!f){break P}bb(G[d+12>>2],G[e+16>>2],f);G[d+12>>2]=f+G[d+12>>2];G[e+16>>2]=f+G[e+16>>2];G[d+20>>2]=f+G[d+20>>2];G[d+16>>2]=G[d+16>>2]-f;d=G[e+20>>2];G[e+20>>2]=d-f;if((d|0)!=(f|0)){break P}G[e+16>>2]=G[e+8>>2]}e=G[G[c>>2]+16>>2]?3:2;break L}Q:{if(!G[c+5792>>2]){break Q}d=G[c+92>>2];if((d|0)>=0){e=d+G[c+56>>2]|0}else{e=0}ge(c,e,G[c+108>>2]-d|0,0);G[c+92>>2]=G[c+108>>2];d=G[c>>2];e=G[d+28>>2];cd(e);f=G[e+20>>2];g=G[d+16>>2];f=f>>>0>>0?f:g;R:{if(!f){break R}bb(G[d+12>>2],G[e+16>>2],f);G[d+12>>2]=f+G[d+12>>2];G[e+16>>2]=f+G[e+16>>2];G[d+20>>2]=f+G[d+20>>2];G[d+16>>2]=G[d+16>>2]-f;d=G[e+20>>2];G[e+20>>2]=d-f;if((d|0)!=(f|0)){break R}G[e+16>>2]=G[e+8>>2]}if(G[G[c>>2]+16>>2]){break Q}e=0;break L}e=1;break L}j=G[c+108>>2];if(!j){j=0;break N}k=G[c+56>>2]+j|0;d=k-1|0;h=H[d|0];if((h|0)!=H[k|0]|(h|0)!=H[d+2|0]|(h|0)!=H[d+3|0]){break N}l=k+258|0;d=-1;S:{T:{U:{V:{W:{X:{while(1){f=d+k|0;if((h|0)==H[f+4|0]){if((h|0)!=H[f+5|0]){break X}if((h|0)!=H[f+6|0]){break W}if((h|0)!=H[f+7|0]){break V}e=d+8|0;i=e+k|0;if((h|0)!=H[i|0]){break S}if((h|0)!=H[f+9|0]){break U}if((h|0)!=H[f+10|0]){break T}i=f+11|0;if((h|0)!=H[i|0]){break S}f=(d|0)<247;d=e;if(f){continue}break S}break}i=f+4|0;break S}i=f+5|0;break S}i=f+6|0;break S}i=f+7|0;break S}i=f+9|0;break S}i=f+10|0}d=(i-l|0)+258|0;d=d>>>0>>0?d:g;G[c+96>>2]=d;if(d>>>0<3){break N}e=G[c+5792>>2];F[G[c+5796>>2]+(e<<1)>>1]=1;G[c+5792>>2]=e+1;d=d-3|0;E[e+G[c+5784>>2]|0]=d;d=((H[(d&255)+116208|0]<<2)+c|0)+1176|0;F[d>>1]=I[d>>1]+1;d=((H[115696]<<2)+c|0)+2440|0;F[d>>1]=I[d>>1]+1;d=G[c+96>>2];G[c+96>>2]=0;G[c+116>>2]=G[c+116>>2]-d;g=d+G[c+108>>2]|0;G[c+108>>2]=g;break M}d=H[G[c+56>>2]+j|0];e=G[c+5792>>2];F[G[c+5796>>2]+(e<<1)>>1]=0;G[c+5792>>2]=e+1;E[e+G[c+5784>>2]|0]=d;d=(d<<2)+c|0;F[d+148>>1]=I[d+148>>1]+1;G[c+116>>2]=G[c+116>>2]-1;g=G[c+108>>2]+1|0;G[c+108>>2]=g}if(G[c+5792>>2]!=(G[c+5788>>2]-1|0)){continue}d=G[c+92>>2];if((d|0)>=0){e=d+G[c+56>>2]|0}else{e=0}ge(c,e,g-d|0,0);G[c+92>>2]=G[c+108>>2];d=G[c>>2];e=G[d+28>>2];cd(e);f=G[e+20>>2];g=G[d+16>>2];f=f>>>0>>0?f:g;Y:{if(!f){break Y}bb(G[d+12>>2],G[e+16>>2],f);G[d+12>>2]=f+G[d+12>>2];G[e+16>>2]=f+G[e+16>>2];G[d+20>>2]=f+G[d+20>>2];G[d+16>>2]=G[d+16>>2]-f;d=G[e+20>>2];G[e+20>>2]=d-f;if((d|0)!=(f|0)){break Y}G[e+16>>2]=G[e+8>>2]}if(G[G[c>>2]+16>>2]){continue}break}e=0}break C;default:break D}}e=Ja[G[M(d,12)+118440>>2]](c,b)|0}d=e;if((d&-2)==2){G[c+4>>2]=666}if(!(d&-3)){d=0;if(G[a+16>>2]){break d}break a}if((d|0)!=1){break k}Z:{_:{switch(b-1|0){case 0:e=G[c+5820>>2];d=I[c+5816>>1]|2<>1]=d;$:{if((e|0)>=14){e=G[c+20>>2];G[c+20>>2]=e+1;E[e+G[c+8>>2]|0]=d;d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=H[c+5817|0];e=G[c+5820>>2];d=2>>>16-e|0;F[c+5816>>1]=d;e=e-13|0;break $}e=e+3|0}G[c+5820>>2]=e;aa:{if((e|0)>=10){e=G[c+20>>2];G[c+20>>2]=e+1;E[e+G[c+8>>2]|0]=d;d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=H[c+5817|0];d=0;F[c+5816>>1]=0;e=G[c+5820>>2]-9|0;break aa}e=e+7|0}G[c+5820>>2]=e;ba:{ca:{if((e|0)==16){e=G[c+20>>2];G[c+20>>2]=e+1;E[e+G[c+8>>2]|0]=d;d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=H[c+5817|0];F[c+5816>>1]=0;e=0;break ca}if((e|0)<8){break ba}e=G[c+20>>2];G[c+20>>2]=e+1;E[e+G[c+8>>2]|0]=d;F[c+5816>>1]=H[c+5817|0];e=G[c+5820>>2]-8|0}G[c+5820>>2]=e}break Z;case 4:break Z;default:break _}}Si(c,0,0,0);if((b|0)!=3){break Z}d=G[c+68>>2];e=(G[c+76>>2]<<1)-2|0;F[d+e>>1]=0;cb(d,0,e);if(G[c+116>>2]){break Z}G[c+5812>>2]=0;G[c+92>>2]=0;G[c+108>>2]=0}Mg(a);if(G[a+16>>2]){break k}break a}d=0;if((b|0)!=4){break d}d=1;e=G[c+24>>2];if((e|0)<=0){break d}b=G[a+48>>2];da:{if((e|0)==2){d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=b;b=G[a+48>>2];d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=b>>>8;b=I[a+50>>1];d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=b;b=H[a+51|0];d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=b;b=G[a+8>>2];d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=b;b=G[a+8>>2];d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=b>>>8;b=I[a+10>>1];d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=b;b=H[a+11|0];break da}d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=b>>>24;d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=b>>>16;b=G[a+48>>2];d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=b>>>8}d=G[c+20>>2];G[c+20>>2]=d+1;E[d+G[c+8>>2]|0]=b;Mg(a);a=G[c+24>>2];if((a|0)>0){G[c+24>>2]=0-a}d=!G[c+20>>2]}return d}G[c+40>>2]=-1;return 0}G[a+24>>2]=G[26251];return-5}G[c+40>>2]=-1;return 0}function Bi(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,I=0,K=0,L=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0;D=Fa-16|0;Fa=D;G[D+12>>2]=c;G[D+8>>2]=d;h=a;V=D+12|0;Q=D+8|0;f=Fa-368|0;Fa=f;a:{if(G[e>>2]>0){break a}a=G[h>>2];c=G[h+4>>2];b:{c:{if((a|0)!=G[c+76>>2]){mb(h,a+1|0,0,e);break c}if((G[c+128>>2]&G[c+132>>2])!=-1){break c}if((Rb(h,e)|0)>0){break b}}c=G[h+4>>2];if(!G[c+80>>2]){Ua(50904);G[e>>2]=235;break a}a=0;if((b|0)<=0){G[e>>2]=302;break a}I=G[c+936>>2];while(1){c=G[(a<<2)+Q>>2];if(Va(c)>>>0>=71){Ua(50965);G[e>>2]=261;break a}c=Za(f+256|0,c);Yf(c);d:{if(G[G[h+4>>2]+80>>2]==1){Gd(c,f+364|0,f+340|0,f+360|0,e);c=G[f+340>>2]+1|0;d=c;c=c>>31;break d}Vf(c,f+364|0,f+336|0,f+340|0,e);d=G[f+364>>2];if((d|0)<0){d=jb(c,81)?16:8;c=0;break d}e:{f:{c=d-1|0;if(c){if((c|0)==15){break f}break e}c=(G[f+336>>2]+7|0)/8|0;d=c;c=c>>31;break d}c=G[f+336>>2];d=c;c=c>>31;break d}c=M(G[f+336>>2],(d>>>0)/10|0);d=c;c=c>>31}c=c+j|0;d=d+m|0;c=d>>>0>>0?c+1|0:c;m=d;j=c;a=a+1|0;if((a|0)!=1){continue}break}if(G[e>>2]>0){break a}a=G[h+4>>2];p=G[a+960>>2];q=G[a+964>>2];r=G[a+952>>2];g=G[a+956>>2];l=Au(r,g,m,j);c=Ia;n=c;d=c;s=G[a+984>>2];o=G[a+976>>2];i=s+o|0;k=G[a+988>>2];c=k+G[a+980>>2]|0;c=i>>>0>>0?c+1|0:c;o=i+2879|0;c=o>>>0<2879?c+1|0:c;c=Cu(o,c);i=Ia;o=0-(i+(c>>>0>2879)|0)|0;if(2879-c>>>0>>0&(o|0)<=(d|0)|(d|0)>(o|0)){i=i+n|0;a=c;c=c+l|0;if((Bf(h,Bu(c,a>>>0>c>>>0?i+1|0:i,2880,0),1,e)|0)>0){break b}a=G[h+4>>2];s=G[a+984>>2];k=G[a+988>>2]}if(!!s&(k|0)>=0|(k|0)>0){c=G[a+980>>2]+G[a+132>>2]|0;d=G[a+128>>2];o=d+G[a+976>>2]|0;if((Ci(h,o,d>>>0>o>>>0?c+1|0:c,s,k,l,n,e)|0)>0){break b}a=G[h+4>>2]}R=I+1|0;P=(b|0)>(I|0);t=P?R:b;c=l;d=c+G[a+976>>2]|0;b=n+G[a+980>>2]|0;b=c>>>0>d>>>0?b+1|0:b;c=d;G[a+976>>2]=c;G[a+980>>2]=b;a=0;G[f+356>>2]=0;Ad(h,34350,c,b,65398,f+356|0);o=p;v=q;if(!P){b=(G[G[h+4>>2]+968>>2]+M(t,160)|0)-88|0;o=G[b>>2];v=G[b+4>>2]}u=Fa-1e4|0;Fa=u;if(!(!(g|r)|G[e>>2]>0)){d=G[h+4>>2];S=(G[d+80>>2]==1)<<5;b=j+q|0;c=m+p|0;b=c>>>0

>>0?b+1|0:b;z=c;x=b;g:{if((b|0)<=0&c>>>0<=1e4|(b|0)<0){if(!!m&(j|0)>=0|(j|0)>0){cb(u,S,m)}c=G[d+980>>2]+G[d+132>>2]|0;b=G[d+128>>2];k=b+G[d+976>>2]|0;l=k;c=b>>>0>k>>>0?c+1|0:c;b=c;k=G[d+44>>2];if(l>>>0>J[d+40>>2]&(c|0)>=(k|0)|(c|0)>(k|0)){k=d;c=l+2879|0;b=c>>>0<2879?b+1|0:b;d=c;c=Cu(c,b);G[k+40>>2]=d-c;G[k+44>>2]=b-(Ia+(c>>>0>d>>>0)|0)}c=v;b=o+1|0;c=b?c:c+1|0;n=b;d=c;b=o;i=p-b|0;k=q-((b>>>0>p>>>0)+v|0)|0;l=m+u|0;ee(h,r,g,n,c,i,k,l,e);b=G[h+4>>2];G[b+960>>2]=z;G[b+964>>2]=x;b=i+m|0;i=j+k|0;ld(h,r,g,n,c,b,b>>>0>>0?i+1|0:i,u,e);b=G[h+4>>2];G[b+960>>2]=p;G[b+964>>2]=q;if(r>>>0<2&(g|0)<=0|(g|0)<0){break g}while(1){c=r-1|0;b=g-!r|0;ee(h,c,b,n,d,p,q,l,e);k=G[h+4>>2];G[k+960>>2]=z;G[k+964>>2]=x;ld(h,c,b,n,d,z,x,u,e);k=G[h+4>>2];G[k+960>>2]=p;G[k+964>>2]=q;k=!g&r>>>0>2|(g|0)!=0;r=c;g=b;if(k){continue}break}break g}c=q;b=p+9999|0;c=b>>>0<9999?c+1|0:c;y=b;w=c;c=b;b=o;i=w-((c>>>0>>0)+v|0)|0;B=c-b|0;K=Bu(B,i,1e4,0);L=Ia;h:{if(B>>>0<1e4&(i|0)<=0|(i|0)<0){break h}s=1;k=0;c=Au(K,L,1e4,0);d=c+o|0;b=Ia+v|0;b=c>>>0>d>>>0?b+1|0:b;c=d;l=c-9999|0;b=b-(c>>>0<9999)|0;n=b;c=q-((l>>>0>p>>>0)+b|0)|0;b=(p-l|0)+1|0;c=b?c:c+1|0;d=b;b=c;ee(h,r,g,l,n,d,c,u,e);c=G[h+4>>2];G[c+960>>2]=z;G[c+964>>2]=x;c=j+n|0;C=l+m|0;c=C>>>0>>0?c+1|0:c;ld(h,r,g,C,c,d,b,u,e);d=G[h+4>>2];b=d;G[b+960>>2]=p;G[b+964>>2]=q;b=B;c=b-1e4|0;if((b>>>0<1e4|0)==(i|0)&c>>>0<1e4){break h}while(1){b=l;l=b-1e4|0;n=n-(b>>>0<1e4)|0;ee(h,r,g,l,n,1e4,0,u,e);b=G[h+4>>2];G[b+960>>2]=z;G[b+964>>2]=x;c=j+n|0;b=l+m|0;c=b>>>0>>0?c+1|0:c;ld(h,r,g,b,c,1e4,0,u,e);d=G[h+4>>2];b=d;G[b+960>>2]=p;G[b+964>>2]=q;b=k;c=s+1|0;b=c?b:b+1|0;s=c;k=b;if((K|0)!=(c|0)|(L|0)!=(b|0)){continue}break}}k=Bu(y,w,1e4,0);l=Ia;if(!(r>>>0<2&(g|0)<=0|(g|0)<0|(!p&(q|0)<=0|(q|0)<0))){c=Au(k,l,1e4,0);d=c-1e4|0;b=d;T=p-b|0;c=Ia-(c>>>0<1e4)|0;U=q-(c+(b>>>0>p>>>0)|0)|0;b=k>>>0>1&(l|0)>=0|(l|0)>0;N=b?k:1;O=b?l:0;b=o;d=b+d|0;c=c+v|0;c=b>>>0>d>>>0?c+1|0:c;d=d+1|0;b=d?c:c+1|0;C=d;d=m+d|0;c=b+j|0;K=d;B=d>>>0>>0?c+1|0:c;L=y>>>0<2e4&(w|0)<=0|(w|0)<0;s=r;k=g;while(1){y=s-1|0;w=k-!s|0;d=w;ee(h,y,d,C,b,T,U,u,e);c=G[h+4>>2];G[c+960>>2]=z;G[c+964>>2]=x;ld(h,y,d,K,B,T,U,u,e);d=G[h+4>>2];c=d;G[c+960>>2]=p;G[c+964>>2]=q;A=1;i=0;l=C;n=b;if(!L){while(1){c=l;l=c-1e4|0;n=n-(c>>>0<1e4)|0;ee(h,y,w,l,n,1e4,0,u,e);c=G[h+4>>2];G[c+960>>2]=z;G[c+964>>2]=x;c=j+n|0;d=l+m|0;c=d>>>0>>0?c+1|0:c;ld(h,y,w,d,c,1e4,0,u,e);d=G[h+4>>2];c=d;G[c+960>>2]=p;G[c+964>>2]=q;c=A+1|0;i=c?i:i+1|0;A=c;if((N|0)!=(c|0)|(i|0)!=(O|0)){continue}break}}c=s>>>0>2&(k|0)>=0|(k|0)>0;s=y;k=w;if(c){continue}break}}N=cb(u,S,m>>>0<1e4&(j|0)<=0|(j|0)<0?m:1e4);G[d+960>>2]=z;G[d+964>>2]=x;b=j;c=m+9999|0;b=c>>>0<9999?b+1|0:b;c=Bu(c,b,1e4,0);k=Ia;if(!(!r&(g|0)<=0|(g|0)<0|(!m&(j|0)<=0|(j|0)<0))){b=c>>>0>1&(k|0)>=0|(k|0)>0;K=b?c:1;L=b?k:0;b=Au(c,k,-1e4,-1);d=b+m|0;c=Ia+j|0;c=b>>>0>d>>>0?c+1|0:c;b=d+1e4|0;c=b>>>0<1e4?c+1|0:c;O=b;w=c;i=v;b=o+1|0;i=b?i:i+1|0;x=b;d=b;k=b+O|0;C=i;b=i+c|0;B=k;d=d>>>0>k>>>0?b+1|0:b;y=m>>>0<10001&(j|0)<=0|(j|0)<0;A=1;i=0;while(1){ld(h,A,i,x,C,O,w,N,e);s=1;k=0;l=B;n=d;if(!y){while(1){ld(h,A,i,l,n,1e4,0,N,e);b=n;c=l+1e4|0;b=c>>>0<1e4?b+1|0:b;l=c;n=b;c=k;b=s+1|0;c=b?c:c+1|0;s=b;k=c;if((K|0)!=(b|0)|(L|0)!=(c|0)){continue}break}}k=(r|0)!=(A|0)|(g|0)!=(i|0);b=i;c=A+1|0;b=c?b:b+1|0;A=c;i=b;if(k){continue}break}d=G[h+4>>2]}G[d+960>>2]=p;G[d+964>>2]=q}}Fa=u+1e4|0;if(!(G[G[h+4>>2]+80>>2]!=1|(I|0)<=0)){while(1){a=a+1|0;b=f+176|0;zb(34749,a,b,e);_f(h,b,f+344|0,f+96|0,e);b=G[f+344>>2];c=G[f+348>>2];if(b>>>0>o>>>0&(c|0)>=(v|0)|(c|0)>(v|0)){c=c+j|0;d=b+m|0;c=d>>>0>>0?c+1|0:c;b=d;G[f+344>>2]=b;G[f+348>>2]=c;Ad(h,f+176|0,b,c,65398,e)}if((a|0)!=(I|0)){continue}break}}a=I+1|0;Ad(h,33837,a,a>>31,65398,e);b=j+q|0;a=m+p|0;b=a>>>0

>>0?b+1|0:b;Ad(h,41261,a,b,65398,e);if(!P){ko(h,t,I,1,e)}s=H[26754]|H[26755]<<8|(H[26756]<<16|H[26757]<<24);r=H[26758]|H[26759]<<8|(H[26760]<<16|H[26761]<<24);n=H[26746]|H[26747]<<8|(H[26748]<<16|H[26749]<<24);l=H[26750]|H[26751]<<8|(H[26752]<<16|H[26753]<<24);m=H[26825]|H[26826]<<8|(H[26827]<<16|H[26828]<<24);p=H[26829]|H[26830]<<8|(H[26831]<<16|H[26832]<<24);k=H[26817]|H[26818]<<8|(H[26819]<<16|H[26820]<<24);d=H[26821]|H[26822]<<8|(H[26823]<<16|H[26824]<<24);q=0;while(1){G[f+104>>2]=s;G[f+108>>2]=r;G[f+96>>2]=n;G[f+100>>2]=l;b=f+176|0;zb(35402,t,b,e);a=q<<2;lc(h,b,G[a+V>>2],f+96|0,e);G[f+104>>2]=m;G[f+108>>2]=p;G[f+96>>2]=k;G[f+100>>2]=d;c=Za(f+256|0,G[a+Q>>2]);Yf(c);zb(34641,t,b,e);a=c;b=G[f+364>>2];i=b>>31;i:{j:{k:{l:{m:{n:{o:{b=(b^i)-i|0;switch(b-12|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:break k;case 28:break m;case 8:break n;case 0:break o;default:break l}}while(1){b=a;a=b+1|0;if(H[b|0]!=83){continue}break}E[b|0]=66;i=f+176|0;b=f+96|0;lc(h,i,c,b,e);zb(34362,t,i,e);a=H[7466]|H[7467]<<8|(H[7468]<<16|H[7469]<<24);G[f+112>>2]=H[7462]|H[7463]<<8|(H[7464]<<16|H[7465]<<24);G[f+116>>2]=a;a=H[7458]|H[7459]<<8|(H[7460]<<16|H[7461]<<24);G[f+104>>2]=H[7454]|H[7455]<<8|(H[7456]<<16|H[7457]<<24);G[f+108>>2]=a;a=H[7450]|H[7451]<<8|(H[7452]<<16|H[7453]<<24);G[f+96>>2]=H[7446]|H[7447]<<8|(H[7448]<<16|H[7449]<<24);G[f+100>>2]=a;be(h,i,-128,b,e);zb(34838,t,i,e);G[f+112>>2]=H[29394]|H[29395]<<8|(H[29396]<<16|H[29397]<<24);a=H[29390]|H[29391]<<8|(H[29392]<<16|H[29393]<<24);G[f+104>>2]=H[29386]|H[29387]<<8|(H[29388]<<16|H[29389]<<24);G[f+108>>2]=a;a=H[29382]|H[29383]<<8|(H[29384]<<16|H[29385]<<24);G[f+96>>2]=H[29378]|H[29379]<<8|(H[29380]<<16|H[29381]<<24);G[f+100>>2]=a;be(h,i,1,b,e);break i}while(1){b=a;a=b+1|0;if(H[b|0]!=85){continue}break}E[b|0]=73;g=f+176|0;b=f+96|0;lc(h,g,c,b,e);zb(34362,t,g,e);i=H[6483]|H[6484]<<8|(H[6485]<<16|H[6486]<<24);a=H[6479]|H[6480]<<8|(H[6481]<<16|H[6482]<<24);E[f+117|0]=a;E[f+118|0]=a>>>8;E[f+119|0]=a>>>16;E[f+120|0]=a>>>24;E[f+121|0]=i;E[f+122|0]=i>>>8;E[f+123|0]=i>>>16;E[f+124|0]=i>>>24;a=H[6478]|H[6479]<<8|(H[6480]<<16|H[6481]<<24);G[f+112>>2]=H[6474]|H[6475]<<8|(H[6476]<<16|H[6477]<<24);G[f+116>>2]=a;a=H[6470]|H[6471]<<8|(H[6472]<<16|H[6473]<<24);G[f+104>>2]=H[6466]|H[6467]<<8|(H[6468]<<16|H[6469]<<24);G[f+108>>2]=a;a=H[6462]|H[6463]<<8|(H[6464]<<16|H[6465]<<24);G[f+96>>2]=H[6458]|H[6459]<<8|(H[6460]<<16|H[6461]<<24);G[f+100>>2]=a;be(h,g,32768,b,e);zb(34838,t,g,e);G[f+112>>2]=H[29394]|H[29395]<<8|(H[29396]<<16|H[29397]<<24);a=H[29390]|H[29391]<<8|(H[29392]<<16|H[29393]<<24);G[f+104>>2]=H[29386]|H[29387]<<8|(H[29388]<<16|H[29389]<<24);G[f+108>>2]=a;a=H[29382]|H[29383]<<8|(H[29384]<<16|H[29385]<<24);G[f+96>>2]=H[29378]|H[29379]<<8|(H[29380]<<16|H[29381]<<24);G[f+100>>2]=a;be(h,g,1,b,e);break i}while(1){b=a;a=b+1|0;if(H[b|0]!=86){continue}break}E[b|0]=74;g=f+176|0;b=f+96|0;lc(h,g,c,b,e);zb(34362,t,g,e);i=H[6483]|H[6484]<<8|(H[6485]<<16|H[6486]<<24);a=H[6479]|H[6480]<<8|(H[6481]<<16|H[6482]<<24);E[f+117|0]=a;E[f+118|0]=a>>>8;E[f+119|0]=a>>>16;E[f+120|0]=a>>>24;E[f+121|0]=i;E[f+122|0]=i>>>8;E[f+123|0]=i>>>16;E[f+124|0]=i>>>24;a=H[6478]|H[6479]<<8|(H[6480]<<16|H[6481]<<24);G[f+112>>2]=H[6474]|H[6475]<<8|(H[6476]<<16|H[6477]<<24);G[f+116>>2]=a;a=H[6470]|H[6471]<<8|(H[6472]<<16|H[6473]<<24);G[f+104>>2]=H[6466]|H[6467]<<8|(H[6468]<<16|H[6469]<<24);G[f+108>>2]=a;a=H[6462]|H[6463]<<8|(H[6464]<<16|H[6465]<<24);G[f+96>>2]=H[6458]|H[6459]<<8|(H[6460]<<16|H[6461]<<24);G[f+100>>2]=a;be(h,g,2147483648,b,e);zb(34838,t,g,e);G[f+112>>2]=H[29394]|H[29395]<<8|(H[29396]<<16|H[29397]<<24);a=H[29390]|H[29391]<<8|(H[29392]<<16|H[29393]<<24);G[f+104>>2]=H[29386]|H[29387]<<8|(H[29388]<<16|H[29389]<<24);G[f+108>>2]=a;a=H[29382]|H[29383]<<8|(H[29384]<<16|H[29385]<<24);G[f+96>>2]=H[29378]|H[29379]<<8|(H[29380]<<16|H[29381]<<24);G[f+100>>2]=a;be(h,g,1,b,e);break i}if((b|0)==80){break j}}lc(h,f+176|0,c,f+96|0,e);break i}while(1){b=a;a=b+1|0;if(H[b|0]!=87){continue}break}E[b|0]=75;i=f+176|0;b=f+96|0;lc(h,i,c,b,e);zb(34362,t,f,e);g=Va(f)+f|0;a=H[68292]|H[68293]<<8|(H[68294]<<16|H[68295]<<24);E[g|0]=a;E[g+1|0]=a>>>8;E[g+2|0]=a>>>16;E[g+3|0]=a>>>24;a=H[68296]|H[68297]<<8;E[g+4|0]=a;E[g+5|0]=a>>>8;E[f+8|0]=0;a=Va(f)+f|0;j=H[6437]|H[6438]<<8|(H[6439]<<16|H[6440]<<24);g=H[6433]|H[6434]<<8|(H[6435]<<16|H[6436]<<24);E[a|0]=g;E[a+1|0]=g>>>8;E[a+2|0]=g>>>16;E[a+3|0]=g>>>24;E[a+4|0]=j;E[a+5|0]=j>>>8;E[a+6|0]=j>>>16;E[a+7|0]=j>>>24;j=H[6483]|H[6484]<<8|(H[6485]<<16|H[6486]<<24);g=H[6479]|H[6480]<<8|(H[6481]<<16|H[6482]<<24);E[a+46|0]=g;E[a+47|0]=g>>>8;E[a+48|0]=g>>>16;E[a+49|0]=g>>>24;E[a+50|0]=j;E[a+51|0]=j>>>8;E[a+52|0]=j>>>16;E[a+53|0]=j>>>24;j=H[6477]|H[6478]<<8|(H[6479]<<16|H[6480]<<24);g=H[6473]|H[6474]<<8|(H[6475]<<16|H[6476]<<24);E[a+40|0]=g;E[a+41|0]=g>>>8;E[a+42|0]=g>>>16;E[a+43|0]=g>>>24;E[a+44|0]=j;E[a+45|0]=j>>>8;E[a+46|0]=j>>>16;E[a+47|0]=j>>>24;j=H[6469]|H[6470]<<8|(H[6471]<<16|H[6472]<<24);g=H[6465]|H[6466]<<8|(H[6467]<<16|H[6468]<<24);E[a+32|0]=g;E[a+33|0]=g>>>8;E[a+34|0]=g>>>16;E[a+35|0]=g>>>24;E[a+36|0]=j;E[a+37|0]=j>>>8;E[a+38|0]=j>>>16;E[a+39|0]=j>>>24;j=H[6461]|H[6462]<<8|(H[6463]<<16|H[6464]<<24);g=H[6457]|H[6458]<<8|(H[6459]<<16|H[6460]<<24);E[a+24|0]=g;E[a+25|0]=g>>>8;E[a+26|0]=g>>>16;E[a+27|0]=g>>>24;E[a+28|0]=j;E[a+29|0]=j>>>8;E[a+30|0]=j>>>16;E[a+31|0]=j>>>24;j=H[6453]|H[6454]<<8|(H[6455]<<16|H[6456]<<24);g=H[6449]|H[6450]<<8|(H[6451]<<16|H[6452]<<24);E[a+16|0]=g;E[a+17|0]=g>>>8;E[a+18|0]=g>>>16;E[a+19|0]=g>>>24;E[a+20|0]=j;E[a+21|0]=j>>>8;E[a+22|0]=j>>>16;E[a+23|0]=j>>>24;j=H[6445]|H[6446]<<8|(H[6447]<<16|H[6448]<<24);g=H[6441]|H[6442]<<8|(H[6443]<<16|H[6444]<<24);E[a+8|0]=g;E[a+9|0]=g>>>8;E[a+10|0]=g>>>16;E[a+11|0]=g>>>24;E[a+12|0]=j;E[a+13|0]=j>>>8;E[a+14|0]=j>>>16;E[a+15|0]=j>>>24;wb(h,f,e);zb(34838,t,i,e);G[f+112>>2]=H[29394]|H[29395]<<8|(H[29396]<<16|H[29397]<<24);a=H[29390]|H[29391]<<8|(H[29392]<<16|H[29393]<<24);G[f+104>>2]=H[29386]|H[29387]<<8|(H[29388]<<16|H[29389]<<24);G[f+108>>2]=a;a=H[29382]|H[29383]<<8|(H[29384]<<16|H[29385]<<24);G[f+96>>2]=H[29378]|H[29379]<<8|(H[29380]<<16|H[29381]<<24);G[f+100>>2]=a;be(h,i,1,b,e)}if(G[G[h+4>>2]+80>>2]==1){a=H[26853]|H[26854]<<8|(H[26855]<<16|H[26856]<<24);G[f+112>>2]=H[26849]|H[26850]<<8|(H[26851]<<16|H[26852]<<24);G[f+116>>2]=a;F[f+120>>1]=H[26857]|H[26858]<<8;a=H[26837]|H[26838]<<8|(H[26839]<<16|H[26840]<<24);G[f+96>>2]=H[26833]|H[26834]<<8|(H[26835]<<16|H[26836]<<24);G[f+100>>2]=a;a=H[26845]|H[26846]<<8|(H[26847]<<16|H[26848]<<24);G[f+104>>2]=H[26841]|H[26842]<<8|(H[26843]<<16|H[26844]<<24);G[f+108>>2]=a;i=v;a=o+((t|0)==(R|0)?2:1)|0;i=a>>>0>>0?i+1|0:i;G[f+344>>2]=a;G[f+348>>2]=i;a=f+176|0;zb(34749,t,a,e);hd(h,a,G[f+344>>2],G[f+348>>2],f+96|0,e);Gd(c,f+364|0,f+340|0,f+360|0,e);a=G[f+340>>2]+1|0;c=a+o|0;b=(a>>31)+v|0;o=c;v=a>>>0>c>>>0?b+1|0:b}t=t+1|0;q=q+1|0;if((q|0)!=1){continue}break}Rb(h,e)}}Fa=f+368|0;Fa=D+16|0}function ht(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;s=Fa-16|0;Fa=s;b=0;G[s+8>>2]=0;G[c>>2]=-1;a:{b:{while(1){e=M(b,48)+757232|0;if(!G[e>>2]){d=b;break b}d=b+1|0;e=M(d,48)+757232|0;if(!G[e>>2]){break b}d=b+2|0;e=M(d,48)+757232|0;if(!G[e>>2]){break b}d=b+3|0;e=M(d,48)+757232|0;if(!G[e>>2]){break b}d=b+4|0;e=M(d,48)+757232|0;if(!G[e>>2]){break b}b=b+5|0;if((b|0)!=1e4){continue}break}Ua(55816);b=103;break a}G[c>>2]=d;d=M(d,48);G[e>>2]=d+757236;b=d+757256|0;G[b>>2]=0;G[b+4>>2]=0;b=d+757244|0;G[b>>2]=0;G[b+4>>2]=2880;G[d+757240>>2]=b;b=d+757264|0;G[b>>2]=0;G[b+4>>2]=0;G[d+757252>>2]=17;b=0;G[s+12>>2]=0;d=M(G[c>>2],48);u=G[d+757232>>2];v=G[d+757240>>2];d=0;g=Fa-800|0;Fa=g;G[u>>2]=0;G[v>>2]=0;G[s+8>>2]=0;l=Fa-128|0;Fa=l;G[g+268>>2]=0;r=ac(a,30817);c:{if(!r){Ua(37968);Ua(a);break c}d:{if(He(r,0,2)){Ua(38078);break d}j=ek(r);if((j|0)<0){Ua(38110);break d}if(He(r,0,0)){Ua(38256);Ua(a);break c}f=j+5e3|0;e=lb(1,f);if(!e){G[l>>2]=f;e=l+32|0;Ya(e,81,11810,l);Ua(e);Ua(a);break c}G[g+268>>2]=f;f=zc(e,1,j,r);Hb(r);if((f|0)>1023){d=e;break c}G[l+20>>2]=1024;G[l+16>>2]=f;f=l+32|0;Ya(f,81,44636,l+16|0);Ua(f);Ua(a);Wa(e);break c}Ua(a)}Fa=l+128|0;i=d;e:{if(!d){d=104;G[s+12>>2]=104;break e}w=G[g+268>>2];F[g+544>>1]=H[35790]|H[35791]<<8;E[g+546|0]=H[35792];cb(g+544|3,32,77);E[g+624|0]=0;d=1;f=lb(6,1);f:{g:{if(!f){Ua(23507);break g}e=H[i|0];E[f|0]=H[i+!e|0];e=i+(e?2:3)|0;E[f+1|0]=H[e|0];E[f+2|0]=H[e+2|0];E[f+3|0]=H[e+4|0];E[f+4|0]=H[e+6|0];e=fb(f,13157,5);Wa(f);if(!e){break f}}d=!fb(i,40598,5)<<1}r=d;h:{if((d|0)<=0){Ua(11851);break h}t=(r|0)==2;e=M((((w+(t?-2046:-2052)|0)/((t?81:162)|0)|0)+24|0)/36|0,2880)+14404|0;G[v>>2]=e;d=lb(e,1);if(!d){G[g>>2]=e;Ya(g+272|0,81,12331,g);break h}G[u>>2]=d;l=rb(d,g+544|0,80);F[g+368>>1]=84;ud(l,35530,g+368|0);j=t?10:16;h=H[j+i|0];d=(h|0)!=0;G[189304]=d;if((r|0)!=1){d=H[i+(h?14:17)|0]|H[i+(h?15:16)|0]<<8|H[i+(h?16:15)|0]<<16|H[i+(h?17:14)|0]<<24}G[189280]=d;f=j+3|0;e=j|1;d=j+2|0;d=H[i+(h?j:f)|0]|H[i+(h?e:d)|0]<<8|H[i+(h?d:e)|0]<<16|H[i+(h?f:j)|0]<<24;e=d-2|0;if(!(e>>>0>=11|!(1599>>>e&1))){G[g+256>>2]=G[(e<<2)+120244>>2];q=g+368|0;Ya(q,30,30633,g+256|0);ud(l,32941,q);Dd(l,32941,21031);e=0;m=t?18:20;j=m|1;f=m+2|0;h=G[189304]==1;d=m+3|0;x=H[i+(h?j:f)|0]<<8|H[i+(h?m:d)|0]|H[i+(h?f:j)|0]<<16|H[i+(h?d:m)|0]<<24;G[g+240>>2]=x;Ya(q,30,30633,g+240|0);ud(l,33788,q);Dd(l,33788,6965);o=t?22:24;j=o|1;f=o+2|0;h=G[189304]==1;d=o+3|0;G[g+224>>2]=H[i+(h?j:f)|0]<<8|H[i+(h?o:d)|0]|H[i+(h?f:j)|0]<<16|H[i+(h?d:o)|0]<<24;Ya(q,30,30633,g+224|0);ud(l,41261,q);Dd(l,41261,32499);j=l+320|0;i:{if((x|0)<2){break i}h=o+5|0;j=o+6|0;m=G[189304]==1;f=o+4|0;d=o+7|0;G[g+208>>2]=H[i+(m?h:j)|0]<<8|H[i+(m?f:d)|0]|H[i+(m?j:h)|0]<<16|H[i+(m?d:f)|0]<<24;d=g+368|0;Ya(d,30,30633,g+208|0);ud(l,40853,d);Dd(l,40853,32446);j=l+400|0;if((x|0)==2){break i}n=1;h=o+9|0;j=o+10|0;m=G[189304]==1;f=o+8|0;d=o+11|0;G[g+192>>2]=H[i+(m?h:j)|0]<<8|H[i+(m?f:d)|0]|H[i+(m?j:h)|0]<<16|H[i+(m?d:f)|0]<<24;d=g+368|0;Ya(d,30,30633,g+192|0);ud(l,40514,d);Dd(l,40514,32393);j=l+480|0;if(x>>>0<4){break i}e=1;h=o+13|0;j=o+14|0;m=G[189304]==1;f=o+12|0;d=o+15|0;G[g+176>>2]=H[i+(m?h:j)|0]<<8|H[i+(m?f:d)|0]|H[i+(m?j:h)|0]<<16|H[i+(m?d:f)|0]<<24;d=g+368|0;Ya(d,30,30633,g+176|0);ud(l,40363,d);Dd(l,40363,32340);j=l+560|0}j:{k:{if((r|0)==2){f=lb(384,1);if(!f){break k}d=0;while(1){m=d+i|0;h=H[m+638|0];E[d+f|0]=(h-1&255)>>>0<31?32:h;h=d|1;if((h|0)==383){break j}o=f+h|0;h=H[m+639|0];E[o|0]=(h-1&255)>>>0<31?32:h;d=d+2|0;continue}}f=Kn(i,732);break j}Ua(23559);f=0}d=Va(f);if((d|0)<=7){cb(d+f|0,32,8-d|0);E[f+8|0]=0}d=Va(f);E[g+368|0]=39;q=g+368|0;d=(d|0)<67?d:67;rb(q|1,f,d);d=d+g|0;E[d+369|0]=39;E[d+370|0]=0;ud(l,33480,q);Dd(l,33480,21601);Wa(f);o=t?50:52;h=o|1;f=o+2|0;m=G[189304]==1;d=o+3|0;G[g+160>>2]=H[i+(m?h:f)|0]<<8|H[i+(m?o:d)|0]|H[i+(m?f:h)|0]<<16|H[i+(m?d:o)|0]<<24;Ya(q,30,30633,g+160|0);ud(l,41253,q);Dd(l,41253,32471);if((x|0)<2){j=j+160|0}else{m=o+5|0;h=o+6|0;q=G[189304]==1;f=o+4|0;d=o+7|0;G[g+144>>2]=H[i+(q?m:h)|0]<<8|H[i+(q?f:d)|0]|H[i+(q?h:m)|0]<<16|H[i+(q?d:f)|0]<<24;d=g+368|0;Ya(d,30,30633,g+144|0);ud(l,40845,d);Dd(l,40845,32418);j=j+240|0}if(n){h=o|9;n=o+10|0;m=G[189304]==1;f=o|8;d=o+11|0;G[g+128>>2]=H[i+(m?h:n)|0]<<8|H[i+(m?f:d)|0]|H[i+(m?n:h)|0]<<16|H[i+(m?d:f)|0]<<24;d=g+368|0;Ya(d,30,30633,g+128|0);ud(l,40506,d);Dd(l,40506,32365);j=j+80|0}if(e){n=o+13|0;f=o+14|0;h=G[189304]==1;e=o+12|0;d=o+15|0;G[g+112>>2]=H[i+(h?n:f)|0]<<8|H[i+(h?e:d)|0]|H[i+(h?f:n)|0]<<16|H[i+(h?d:e)|0]<<24;d=g+368|0;Ya(d,30,30633,g+112|0);ud(l,40355,d);Dd(l,40355,32312);j=j+80|0}d=Va(a);E[g+368|0]=39;e=g+368|0;d=(d|0)<67?d:67;rb(e|1,a,d);d=d+g|0;E[d+369|0]=39;E[d+370|0]=0;ud(l,35585,e);Dd(l,35585,21498);l:{m:{if((r|0)==2){e=lb(256,1);if(!e){break m}d=0;while(1){h=d+e|0;n=d+i|0;f=H[n+126|0];E[h|0]=(f-1&255)>>>0<31?32:f;f=H[n+127|0];E[h+1|0]=(f-1&255)>>>0<31?32:f;f=H[n+128|0];E[h+2|0]=(f-1&255)>>>0<31?32:f;d=d+3|0;if((d|0)!=255){continue}break}break l}e=Kn(i,412);break l}Ua(23559);e=0}n:{if(fb(e,34134,3)){d=e;break n}d=Jn(e,a);if(!d){d=e;break n}Wa(e)}o:{if(jb(d,47)){a=d;break o}if(jb(d,36)){a=d;break o}a=Jn(d,a);if(!a){a=d;break o}Wa(d)}n=t?86:88;d=jb(a,33);p:{if(d){d=d+1|0;e=Va(d);E[g+368|0]=39;h=g+368|0;e=(e|0)<67?e:67;rb(h|1,d,e);break p}d=Va(a);E[g+368|0]=39;h=g+368|0;e=(d|0)<67?d:67;rb(h|1,a,e)}d=g+e|0;E[d+369|0]=39;E[d+370|0]=0;ud(l,35562,h);Wa(a);Dd(l,35562,22112);e=n|1;d=n+2|0;f=G[189304]==1;a=n+3|0;G[g+96>>2]=(H[i+(f?e:d)|0]<<9|H[i+(f?n:a)|0]<<1|H[i+(f?d:e)|0]<<17|H[i+(f?a:n)|0]<<25)-2;a=g+368|0;Ya(a,30,30633,g+96|0);ud(l,35139,a);Dd(l,35139,64159);G[g+80>>2]=r;Ya(a,30,30633,g+80|0);ud(l,34012,a);Dd(l,34012,63491);q:{if(G[189280]){F[g+368>>1]=84;break q}F[g+368>>1]=70}ud(l,34237,g+368|0);Dd(l,34237,33508);f=0;E[g+528|0]=0;a=j+400|0;r:{if((r|0)==2){cb(g+448|0,32,80);if((w|0)<2047){break r}d=2046;while(1){s:{t:{u:{e=H[d+i|0];switch(e|0){case 0:break r;case 10:break u;default:break t}}f=g+448|0;e=rb(a,f,80);a=nb(f,66596,7);cb(f,32,80);a=e+(a?80:0)|0;f=0;break s}if((f|0)>=81){if(nb(g+448|0,66596,7)){f=9;a=rb(a,g+448|0,80)+80|0}cb(g+448|0,32,80)}if((e-33&255)>>>0<=93){E[(g+448|0)+f|0]=e}f=f+1|0}d=d+1|0;if((w|0)!=(d|0)){continue}break}break r}d=G[189304];cb(g+448|0,32,80);if((w|0)<2053){break r}e=(d|0)!=1;d=2052;while(1){v:{w:{x:{j=H[i+(d|e)|0];switch(j|0){case 0:break r;case 10:break x;default:break w}}if(nb(g+448|0,66596,7)){a=rb(a,g+448|0,80)+80|0}cb(g+448|0,32,80);f=0;break v}if((f|0)>=81){if(nb(g+448|0,66596,7)){f=9;a=rb(a,g+448|0,80)+80|0}cb(g+448|0,32,80)}if((j-33&255)>>>0<=93){E[(g+448|0)+f|0]=j}f=f+1|0}d=d+2|0;if((w|0)>(d|0)){continue}break}}rb(a,g+544|0,80);d=0;y:{z:{A:{while(1){n=d+l|0;if(!H[n|0]){f=d;break A}f=1;a=d+l|0;n=a+1|0;if(!H[n|0]){break A}n=a+2|0;if(!H[n|0]){break A}n=a+3|0;if(!H[n|0]){break A}n=a+4|0;if(!H[n|0]){break A}d=d+5|0;if((d|0)!=57600){continue}break}n=l+57600|0;break z}if(f){break z}j=0;break y}a=l;while(1){j=0;f=ec(a,35790,n-a|0);if(!f){break y}e=(f-l|0)%80|0;B:{if((e|0)>=8){a=f+1|0;break B}d=H[f+3|0];if(!((d|0)==61|(d-33&255)>>>0>93)){a=f+1|0;break B}j=f-e|0;if((e|0)>0){e=f+1|0;d=j;while(1){a=H[d|0]==32?a:e;d=d+1|0;if(f>>>0>d>>>0){continue}break}}if(a>>>0<=f>>>0){break y}}j=0;if(a>>>0>>0){continue}break}}a=G[v>>2];d=j+80|0;G[s+8>>2]=d-l;E[g+546|0]=H[68332];F[g+544>>1]=H[68330]|H[68331]<<8;a=l+(a-((a>>>0)%2880|0)|0)|0;if(a>>>0>d>>>0){while(1){d=rb(d,g+544|0,80)+80|0;if(a>>>0>d>>>0){continue}break}}d=G[s+12>>2];Wa(i);if((d|0)>0){break e}a=G[s+8>>2];G[s+8>>2]=(a-((a-1>>>0)%2880|0)|0)+2879;a=G[u>>2];d=Fe(a,35562);C:{if(!d){break C}if((Va(d)|0)<=254){Za(g+544|0,d);break C}y=rb(g+544|0,d,254),z=0,E[y+254|0]=z}d=0;e=Fe(a,35139);D:{if(!e){break D}if(Va(e)>>>0>29){break D}d=2147483647;p=sb(Za(g+448|0,e));k=p+.001;if(k>2147483647){break D}E:{if(p>=0){if(!(O(k)<2147483648)){break E}d=~~k;break D}d=-2147483648;k=p+-.001;if(k<-2147483648){break D}if(!(O(k)<2147483648)){break E}d=~~k;break D}d=-2147483648}F:{G:{f=g+544|0;e=jb(f,33);m=ac(e?e+1|0:f,30817);if(!m){Ua(38183);Ua(g+544|0);break G}f=lb(d,1);if(!f){Ua(11761);Ua(g+544|0);Hb(m);break G}e=d;d=zc(f,1,d,m);if((e|0)>(d|0)){G[g+36>>2]=1024;G[g+32>>2]=d;a=g+448|0;Ya(a,81,44679,g+32|0);Ua(a);Wa(f);Hb(m);break G}H:{e=lb(6,1);I:{if(!e){Ua(23507);break I}d=H[f|0];E[e|0]=H[f+!d|0];d=f+(d?2:3)|0;E[e+1|0]=H[d|0];E[e+2|0]=H[d+2|0];E[e+3|0]=H[d+4|0];E[e+4|0]=H[d+6|0];d=fb(e,3744,5);Wa(e);if(!d){break H}}if(!fb(f,40592,5)){break H}Ua(38224);Ua(g+544|0);Wa(f);Hb(m);break G}Wa(f);j=1;e=Fe(a,33788);d=1;J:{if(!e){break J}d=1;if(Va(e)>>>0>29){break J}p=sb(Za(g+448|0,e));k=p+.001;d=2147483647;if(k>2147483647){break J}K:{if(p>=0){if(!(O(k)<2147483648)){break K}d=~~k;break J}k=p+-.001;d=-2147483648;if(k<-2147483648){break J}if(!(O(k)<2147483648)){break K}d=~~k;break J}d=-2147483648}e=Fe(a,41261);L:{if(!e){break L}if(Va(e)>>>0>29){break L}j=2147483647;p=sb(Za(g+448|0,e));k=p+.001;if(k>2147483647){break L}M:{if(p>=0){if(!(O(k)<2147483648)){break M}j=~~k;break L}j=-2147483648;k=p+-.001;if(k<-2147483648){break L}if(!(O(k)<2147483648)){break M}j=~~k;break L}j=-2147483648}n=1;e=Fe(a,41253);r=1;N:{if(!e){break N}r=1;if(Va(e)>>>0>29){break N}p=sb(Za(g+448|0,e));k=p+.001;r=2147483647;if(k>2147483647){break N}O:{if(p>=0){if(!(O(k)<2147483648)){break O}r=~~k;break N}k=p+-.001;r=-2147483648;if(k<-2147483648){break N}if(!(O(k)<2147483648)){break O}r=~~k;break N}r=-2147483648}f=1;h=1;P:{if((d|0)<2){break P}e=Fe(a,40853);f=1;Q:{if(!e){break Q}f=1;if(Va(e)>>>0>29){break Q}p=sb(Za(g+448|0,e));k=p+.001;f=2147483647;if(k>2147483647){break Q}R:{if(p>=0){if(!(O(k)<2147483648)){break R}f=~~k;break Q}k=p+-.001;f=-2147483648;if(k<-2147483648){break Q}if(!(O(k)<2147483648)){break R}f=~~k;break Q}f=-2147483648}Fe(a,40845);if(d>>>0<3){break P}n=Fe(a,40514);e=1;S:{if(!n){break S}e=1;if(Va(n)>>>0>29){break S}p=sb(Za(g+448|0,n));k=p+.001;e=2147483647;if(k>2147483647){break S}T:{if(p>=0){if(!(O(k)<2147483648)){break T}e=~~k;break S}k=p+-.001;e=-2147483648;if(k<-2147483648){break S}if(!(O(k)<2147483648)){break T}e=~~k;break S}e=-2147483648}n=e;if(d>>>0<4){break P}d=Fe(a,40363);if(!d){break P}if(Va(d)>>>0>29){break P}h=2147483647;p=sb(Za(g+448|0,d));k=p+.001;if(k>2147483647){break P}U:{if(p>=0){if(!(O(k)<2147483648)){break U}h=~~k;break P}h=-2147483648;k=p+-.001;if(k<-2147483648){break P}if(!(O(k)<2147483648)){break U}h=~~k;break P}h=-2147483648}V:{W:{X:{d=Fe(a,32941);if(!d){break X}if(Va(d)>>>0>29){break X}k=sb(Za(g+448|0,d));p=k+.001;if(p>2147483647){break X}if(k>=0){break W}p=k+-.001;if(!(p<-2147483648)){break W}e=-2147483648;d=-2147483648;break V}e=2147483647;d=2147483647;break V}if(O(p)<2147483648){e=~~p}else{e=-2147483648}if((e|0)>=0){d=e;break V}d=0-e|0}Y:{l=(d|0)/8|0;i=M(l,j);q=M(i,M(M(f,n),h));d=(q+G[s+8>>2]|0)-1|0;h=(d-((d>>>0)%2880|0)|0)+2880|0;if(h>>>0<=J[v>>2]){break Y}a=ub(G[u>>2],h);if(a){break Y}G[g+48>>2]=G[s+8>>2];a=g+448|0;Ya(a,81,11506,g+48|0);Ua(a);Ua(g+544|0);Hb(m);break G}G[u>>2]=a;G[v>>2]=h;d=G[s+8>>2];G[s+8>>2]=h;d=a+d|0;Z:{if((j|0)==(r|0)){f=zc(d,1,q,m);break Z}h=0;n=(f|0)==1?(n|0)>1?n:f:f;if((n|0)<=0){f=0;break Z}r=M(l,r-j|0);a=d;f=0;while(1){j=zc(a,1,i,m);He(m,r,1);f=f+j|0;a=a+i|0;h=h+1|0;if((n|0)!=(h|0)){continue}break}}Hb(m);if((f|0)<(q|0)){G[g+68>>2]=q;G[g+64>>2]=f;a=g+448|0;Ya(a,81,44679,g- -64|0);Ua(a);Ua(g+544|0);break G}if(!G[189280]){break F}_:{switch(Eu(e- -64|0,28)|0){case 5:if((q|0)<2){break F}e=d+q|0;while(1){a=H[d+1|0];E[d+1|0]=H[d|0];E[d|0]=a;d=d+2|0;if(e>>>0>d>>>0){continue}break};break F;case 6:if((q|0)<4){break F}f=d+q|0;while(1){e=H[d+3|0];E[d+3|0]=H[d|0];a=H[d+2|0];E[d+2|0]=H[d+1|0];E[d+1|0]=a;E[d|0]=e;d=d+4|0;if(f>>>0>d>>>0){continue}break};break F;case 3:if((q|0)<2){break F}e=d+q|0;while(1){a=H[d+1|0];E[d+1|0]=H[d|0];E[d|0]=a;d=d+2|0;if(e>>>0>d>>>0){continue}break};break F;case 2:if((q|0)<4){break F}f=d+q|0;while(1){e=H[d+3|0];E[d+3|0]=H[d|0];a=H[d+2|0];E[d+2|0]=H[d+1|0];E[d+1|0]=a;E[d|0]=e;d=d+4|0;if(f>>>0>d>>>0){continue}break};break F;case 0:break _;default:break F}}if((q|0)<8){break F}r=d+q|0;while(1){j=H[d+7|0];E[d+7|0]=H[d|0];f=H[d+6|0];E[d+6|0]=H[d+1|0];e=H[d+5|0];E[d+5|0]=H[d+2|0];a=H[d+4|0];E[d+4|0]=H[d+3|0];E[d+3|0]=a;E[d+2|0]=e;E[d+1|0]=f;E[d|0]=j;d=d+8|0;if(r>>>0>d>>>0){continue}break}break F}G[s+12>>2]=104}d=G[s+12>>2];break e}G[g+16>>2]=d;d=g+272|0;Ya(d,81,30404,g+16|0);Ua(d)}Ua(a);d=104;G[s+12>>2]=104;Wa(i)}Fa=g+800|0;G[s+12>>2]=d;a=G[c>>2];if(d){a=M(a,48)+757232|0;Wa(G[G[a>>2]>>2]);G[a>>2]=0;G[a+4>>2]=0;Ua(55760);b=G[s+12>>2];break a}c=M(a,48);a=c+757256|0;G[a>>2]=0;G[a+4>>2]=0;a=c+757264|0;G[a>>2]=G[s+8>>2];G[a+4>>2]=0}Fa=s+16|0;return b|0}function dd(a,b,c,d,e,f,g,h){var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;i=Fa-32|0;Fa=i;if(G[321436]){j=G[24367];hb(88717,28,1,j);$a(j)}l=1950;j=a&-2;a:{if((j|0)==4){break a}l=b;if(l!=0){break a}l=a&-3?1950:2e3}L[i>>3]=d;L[i+8>>3]=c;k=(a|0)!=(e|0);v=e&-2;b=1950;b:{if((v|0)==4){break b}b=f;if(f!=0){break b}b=e&-3?1950:2e3}c:{if(!(k|l!=b)){L[g>>3]=c;L[h>>3]=d;break c}d:{if((j|0)==2){j=!a;a=(a|0)==2;jj(c,d,i+8|0,i,l,!(j|a));a=!(a^j);if((e|0)!=(a|0)|b!=l){break d}L[g>>3]=L[i+8>>3];L[h>>3]=L[i>>3];break c}e:{f:{switch(a-4|0){case 1:g:{if(H[3706360]){q=L[463310];m=L[463296];s=L[463312];break g}G[926594]=442745336;G[926595]=1078765020;G[926592]=-1571644103;G[926593]=1066524486;G[926596]=52553840;G[926597]=-1075344588;G[926600]=-673237620;G[926601]=-1078782476;G[926604]=71334806;G[926605]=1072007784;G[926608]=-505530574;G[926609]=1072016415;G[926612]=1753527554;G[926613]=-1078674469;G[926616]=-910810613;G[926617]=1072129682;G[926620]=-1081034383;G[926621]=1072680502;G[926624]=489187355;G[926625]=1069297225;E[3706360]=1;q=.9939225903997749;m=.017453292519943295;s=.11008126222478191}n=m*d;d=eb(n);c=m*c;p=ib(c);m=eb(c);c=0;f=ib(n);m=d*m;d=p*d;q=s*f+(m*0+q*d);n=O(q);h:{if(n>=1){z=i,A=fc(q/n),L[z+16>>3]=A;break h}c=L[463308];n=L[463304];p=L[463306];s=L[463302];w=L[463298];x=L[463300];z=i,A=fc(q),L[z+16>>3]=A;c=Db(c*f+(n*m+d*p),s*f+(w*m+d*x))}d=L[463297];c=c*d;if(c<0){while(1){c=c+360;if(c<0){continue}break}}L[i+24>>3]=c;if(c>360){while(1){c=c+-360;if(c>360){continue}break}L[i+24>>3]=c}d=d*L[i+16>>3];L[i+16>>3]=d;c=90;i:{if(!(O(d)>=90)){break i}G[i+24>>2]=0;G[i+28>>2]=0;d=L[i+16>>3];if(!(d>90)){c=-90;if(!(d<-90)){break i}}L[i+16>>3]=c}c=L[i+24>>3];if((e|0)==4){L[g>>3]=c;L[h>>3]=L[i+16>>3];break c}cm(c,L[i+16>>3],i+8|0,i);break e;case 0:break f;default:break d}}if((e|0)==5){dm(c,d,g,h);break c}cm(c,d,i+24|0,i+16|0);L[i+8>>3]=L[i+24>>3];L[i>>3]=L[i+16>>3]}a=1}if(!((a|0)!=(e|0)|b!=l)){L[g>>3]=L[i+8>>3];L[h>>3]=L[i>>3];break c}j:{k:{l:{switch(a|0){case 1:m:{switch(e|0){default:if(b!=l){ng(l,L[i+8>>3],L[i>>3],b,i+24|0,i+16|0);L[i+8>>3]=L[i+24>>3];L[i>>3]=L[i+16>>3]}if((e|0)!=1){break j}L[g>>3]=L[i+8>>3];L[h>>3]=L[i>>3];break c;case 0:case 2:break m}}c=L[i+8>>3];f=L[i>>3];u=i+24|0;y=i+16|0;a=Fa+-64|0;Fa=a;if(G[321436]){j=G[24367];hb(88989,34,1,j);$a(j)}d=O(l);n:{o:{if(G[47601]){p:{if(d==1950){L[a+48>>3]=f;L[a+56>>3]=c;break p}ng(d,c,f,1950,a+56|0,a+48|0);f=L[a+48>>3];c=L[a+56>>3]}Oh(c,f,1950,a+24|0,a+16|0,a+8|0,a);c=L[a+56>>3]+L[a+24>>3];L[a+56>>3]=c;L[a+48>>3]=L[a+48>>3]+L[a+16>>3];if(G[321436]){j=G[24367];hb(89190,32,1,j);$a(j);c=L[a+56>>3]}if(c>360){while(1){c=c+-360;if(c>360){continue}break}L[a+56>>3]=c}if(c<0){while(1){c=c+360;if(c<0){continue}break}L[a+56>>3]=c}d=1950;f=L[a+48>>3];if(!(O(f)>90)){break n}f=f>0?180-f:-(f+180);L[a+48>>3]=f;c=c+180;c=c>=360?c+-360:c;break o}L[a+48>>3]=f}L[a+56>>3]=c}q:{if(d!=1950){ng(d,c,f,1950,a+40|0,a+32|0);break q}L[a+32>>3]=f;L[a+40>>3]=c}j=Fa-32|0;Fa=j;if(G[321436]){k=G[24367];hb(88645,36,1,k);$a(k)}o=a+40|0;f=L[o>>3];r=a+32|0;l=L[r>>3];m=O(l);r:{if(m<89.999){if(G[321436]){k=G[24367];hb(88829,31,1,k);$a(k)}s:{if(H[3739672]){d=L[467461];c=L[467464];break s}G[934922]=0;G[934923]=1080367104;G[934928]=-1571644103;G[934929]=1066524486;G[934924]=1660415268;G[934925]=1058591923;G[934926]=537691728;G[934927]=1054926027;G[934920]=1660415268;G[934921]=1058591923;E[3739672]=1;d=168.75;c=.017453292519943295}d=f+d;f=c*(d>=360?d+-360:d);d=0;l=l*c;c=eb(l);if(!(m>=90)){d=L[467460]*ib(f)/c}m=L[467462];q=L[467463];L[o>>3]=d+L[o>>3];z=r,A=m*eb(f)*ib(l)+c*q+L[r>>3],L[z>>3]=A;if(G[321436]){k=G[24367];hb(89190,32,1,k);$a(k)}d=L[o>>3];if(d>360){while(1){d=d+-360;if(d>360){continue}break}L[o>>3]=d}if(d<0){while(1){d=d+360;if(d<0){continue}break}L[o>>3]=d}if(!(O(L[r>>3])>90)){break r}c=d+180;L[o>>3]=c>=360?c+-360:c;c=L[r>>3];L[r>>3]=c>0?180-c:-(c+180);break r}ij(f,l,j+24|0,j+16|0,1949.9997905544149,0);f=L[j+24>>3];l=L[j+16>>3];k=G[24367];if(G[321436]){hb(88929,35,1,k);$a(k)}t=j+8|0;hj(f,l,t,j);c=L[j>>3];d=f-L[t>>3];if(G[321436]){hb(89190,32,1,k);$a(k)}if(d>360){while(1){d=d+-360;if(d>360){continue}break}}c=l-c;if(d<0){while(1){d=d+360;if(d<0){continue}break}}if(O(c)>90){c=c>0?180-c:-(c+180);d=d+180;d=d>=360?d+-360:d}hj(d,c,t,j);c=L[j>>3];d=f-L[t>>3];if(G[321436]){hb(89190,32,1,k);$a(k)}if(d>360){while(1){d=d+-360;if(d>360){continue}break}}c=l-c;if(d<0){while(1){d=d+360;if(d<0){continue}break}}if(O(c)>90){c=c>0?180-c:-(c+180);d=d+180;d=d>=360?d+-360:d}hj(d,c,t,j);if(G[321436]){hb(89190,32,1,k);$a(k)}d=L[j+24>>3]-L[j+8>>3];L[j+24>>3]=d;L[j+16>>3]=L[j+16>>3]-L[j>>3];if(G[321436]){k=G[24367];hb(89190,32,1,k);$a(k);d=L[j+24>>3]}if(d>360){while(1){d=d+-360;if(d>360){continue}break}L[j+24>>3]=d}if(d<0){while(1){d=d+360;if(d<0){continue}break}L[j+24>>3]=d}c=L[j+16>>3];if(O(c)>90){c=c>0?180-c:-(c+180);L[j+16>>3]=c;d=d+180;d=d>=360?d+-360:d;L[j+24>>3]=d}jj(d,c,o,r,1949.9997905544149,0)}Fa=j+32|0;c=L[a+40>>3]+.00014583333333333335;if(c>360){while(1){c=c+-360;if(c>360){continue}break}}L[a+40>>3]=c;if(c<0){while(1){c=c+360;if(c<0){continue}break}L[a+40>>3]=c}if(G[321436]){j=G[24367];hb(89190,32,1,j);$a(j);c=L[a+40>>3]}if(c>360){while(1){c=c+-360;if(c>360){continue}break}L[a+40>>3]=c}if(c<0){while(1){c=c+360;if(c<0){continue}break}L[a+40>>3]=c}f=L[a+32>>3];if(O(f)>90){f=f>0?180-f:-(f+180);L[a+32>>3]=f;c=c+180;c=c>=360?c+-360:c;L[a+40>>3]=c}Ug(1949.9997905544149,c,f,2e3,u,y);Fa=a- -64|0;if(b!=2e3){c=L[i+24>>3];L[i+8>>3]=c;d=L[i+16>>3];L[i>>3]=d;Ug(2e3,c,d,b,i+24|0,i+16|0)}c=L[i+24>>3];if(e){break k}L[g>>3]=c;L[h>>3]=L[i+16>>3];break c;case 0:break l;default:break j}}t:{switch(e|0){default:c=L[i>>3];f=L[i+8>>3];if(l!=2e3){Ug(l,f,c,2e3,i+24|0,i+16|0);f=L[i+24>>3];L[i+8>>3]=f;c=L[i+16>>3];L[i>>3]=c}t=i+24|0;u=i+16|0;d=0;j=Fa+-64|0;Fa=j;if(G[321436]){a=G[24367];hb(89051,34,1,a);$a(a)}q=b!=0?O(b):1950;n=f;s=c;l=1950;c=l+-1950;f=(c*365.2421988+2433282.4235+-2451545)/365.25+2e3;Ug(2e3,n,s,f,j+56|0,j+48|0);c=L[j+56>>3]+(c*.01*.085+.035)*-15/3600;if(c>360){while(1){c=c+-360;if(c>360){continue}break}}L[j+56>>3]=c;if(c<0){while(1){c=c+360;if(c<0){continue}break}L[j+56>>3]=c}a=Fa-16|0;Fa=a;if(G[321436]){k=G[24367];hb(88682,34,1,k);$a(k)}o=j+56|0;n=L[o>>3];r=j+48|0;m=L[r>>3];u:{if(O(m)<89.999){k=G[24367];v:{if(!G[321436]){break v}hb(88861,35,1,k);$a(k);if(!G[321436]){break v}hb(88829,31,1,k);$a(k)}w:{if(H[3739672]){d=L[467461];c=L[467464];break w}G[934922]=0;G[934923]=1080367104;G[934928]=-1571644103;G[934929]=1066524486;G[934924]=1660415268;G[934925]=1058591923;G[934926]=537691728;G[934927]=1054926027;G[934920]=1660415268;G[934921]=1058591923;E[3739672]=1;d=168.75;c=.017453292519943295}d=d+n;d=c*(d>=360?d+-360:d);p=c*m;c=eb(p);if(O(m)>=90){f=0}else{f=L[467460]*ib(d)/c}L[a+8>>3]=f;f=L[467463];d=L[467462]*eb(d)*ib(p)+c*f;L[a>>3]=d;c=n-L[a+8>>3];if(G[321436]){hb(89190,32,1,k);$a(k)}if(c>360){while(1){c=c+-360;if(c>360){continue}break}}d=m-d;if(c<0){while(1){c=c+360;if(c<0){continue}break}}if(O(d)>90){d=d>0?180-d:-(d+180);c=c+180;c=c>=360?c+-360:c}if(G[321436]){hb(88829,31,1,k);$a(k)}x:{if(!H[3739672]){G[934922]=0;G[934923]=1080367104;G[934928]=-1571644103;G[934929]=1066524486;G[934924]=1660415268;G[934925]=1058591923;G[934926]=537691728;G[934927]=1054926027;G[934920]=1660415268;G[934921]=1058591923;E[3739672]=1;p=.017453292519943295;f=168.75;break x}p=L[467464];f=L[467461]}c=c+f;c=p*(c>=360?c+-360:c);p=d*p;f=eb(p);if(O(d)>=90){d=0}else{d=L[467460]*ib(c)/f}L[a+8>>3]=d;d=L[467463];d=L[467462]*eb(c)*ib(p)+f*d;L[a>>3]=d;c=n-L[a+8>>3];if(G[321436]){hb(89190,32,1,k);$a(k)}if(c>360){while(1){c=c+-360;if(c>360){continue}break}}d=m-d;if(c<0){while(1){c=c+360;if(c<0){continue}break}}if(O(d)>90){d=d>0?180-d:-(d+180);c=c+180;c=c>=360?c+-360:c}if(G[321436]){hb(88829,31,1,k);$a(k)}y:{if(!H[3739672]){G[934922]=0;G[934923]=1080367104;G[934928]=-1571644103;G[934929]=1066524486;G[934924]=1660415268;G[934925]=1058591923;G[934926]=537691728;G[934927]=1054926027;G[934920]=1660415268;G[934921]=1058591923;E[3739672]=1;m=168.75;f=.017453292519943295;break y}m=L[467461];f=L[467464]}c=c+m;c=f*(c>=360?c+-360:c);m=d*f;f=eb(m);if(O(d)>=90){d=0}else{d=L[467460]*ib(c)/f}L[a+8>>3]=d;d=L[467463];z=a,A=L[467462]*eb(c)*ib(m)+f*d,L[z>>3]=A;L[o>>3]=L[o>>3]-L[a+8>>3];L[r>>3]=L[r>>3]-L[a>>3];if(G[321436]){k=G[24367];hb(89190,32,1,k);$a(k)}c=L[o>>3];if(c>360){while(1){c=c+-360;if(c>360){continue}break}L[o>>3]=c}if(c<0){while(1){c=c+360;if(c<0){continue}break}L[o>>3]=c}if(!(O(L[r>>3])>90)){break u}c=c+180;L[o>>3]=c>=360?c+-360:c;c=L[r>>3];L[r>>3]=c>0?180-c:-(c+180);break u}ij(n,m,a+8|0,a,f,0);m=L[a>>3];n=L[a+8>>3];if(G[321436]){k=G[24367];hb(88897,31,1,k);$a(k)}if(!H[3739720]){G[934934]=-1124855371;G[934935]=1064784320;G[934932]=-1571644103;G[934933]=1066524486;E[3739720]=1}if(f!=L[23803]){L[23803]=f;c=(f+-2e3)*.01;p=c*c;L[467468]=p*-1.236e-7+(c*-42037e-9+.016708617);L[467469]=(p*46e-5+(c*.71953+102.93735))*L[467466]}if(O(m)>89.999){c=0}else{c=L[467467];d=L[467468];s=n;n=L[467466];p=L[467469]-s*n;s=ib(p);m=m*n;c=d*c;d=ib(m)*(s*c);c=c*eb(p)/eb(m)}c=c+L[a+8>>3];L[a+8>>3]=c;L[a>>3]=d+L[a>>3];if(G[321436]){k=G[24367];hb(89190,32,1,k);$a(k);c=L[a+8>>3]}if(c>360){while(1){c=c+-360;if(c>360){continue}break}L[a+8>>3]=c}if(c<0){while(1){c=c+360;if(c<0){continue}break}L[a+8>>3]=c}d=L[a>>3];if(O(d)>90){d=d>0?180-d:-(d+180);L[a>>3]=d;c=c+180;c=c>=360?c+-360:c;L[a+8>>3]=c}jj(c,d,o,r,f,0)}Fa=a+16|0;z:{if(G[47601]){c=L[j+56>>3];A:{if(l==1950){L[j+40>>3]=c;f=L[j+48>>3];L[j+32>>3]=f;break A}ng(l,c,L[j+48>>3],1950,j+40|0,j+32|0);f=L[j+32>>3];c=L[j+40>>3]}a=j+24|0;k=j+16|0;o=j+8|0;B:{if(O(f)>89.999){G[a>>2]=0;G[a+4>>2]=0;G[k>>2]=0;G[k+4>>2]=0;G[o>>2]=0;G[o+4>>2]=0;G[j>>2]=0;G[j+4>>2]=0;break B}r=G[47600];G[47600]=-1;Oh(c,f,l,a,k,o,j);m=L[k>>3];d=c-L[a>>3];if(d<0){while(1){d=d+360;if(d<0){continue}break}}if(d>360){while(1){d=d+-360;if(d>360){continue}break}}Oh(d,f-m,l,a,k,o,j);m=L[k>>3];d=c-L[a>>3];if(d<0){while(1){d=d+360;if(d<0){continue}break}}if(d>360){while(1){d=d+-360;if(d>360){continue}break}}Oh(d,f-m,l,a,k,o,j);G[47600]=r}c=L[j+40>>3]-L[j+24>>3];L[j+40>>3]=c;L[j+32>>3]=L[j+32>>3]-L[j+16>>3];if(G[321436]){a=G[24367];hb(89190,32,1,a);$a(a);c=L[j+40>>3]}if(c>360){while(1){c=c+-360;if(c>360){continue}break}L[j+40>>3]=c}if(c<0){while(1){c=c+360;if(c<0){continue}break}L[j+40>>3]=c}f=L[j+32>>3];if(O(f)>90){f=f>0?180-f:-(f+180);L[j+32>>3]=f;c=c+180;c=c>=360?c+-360:c;L[j+40>>3]=c}if(q!=1950){ng(1950,c,f,q,t,u);break z}L[t>>3]=c;L[u>>3]=f;break z}c=L[j+56>>3];if(l!=q){ng(l,c,L[j+48>>3],q,t,u);break z}L[t>>3]=c;L[u>>3]=L[j+48>>3]}Fa=j- -64|0;c=L[i+24>>3];if((e|0)==1){L[g>>3]=c;L[h>>3]=L[i+16>>3];break c}L[i+8>>3]=c;L[i>>3]=L[i+16>>3];break j;case 0:case 2:break t}}if(b!=l){Ug(l,L[i+8>>3],L[i>>3],b,i+24|0,i+16|0);L[i+8>>3]=L[i+24>>3];L[i>>3]=L[i+16>>3]}if(e){break j}L[g>>3]=L[i+8>>3];L[h>>3]=L[i>>3];break c}L[i+8>>3]=c;L[i>>3]=L[i+16>>3]}if((v|0)==2){ij(L[i+8>>3],L[i>>3],g,h,b,(e|0)!=0&(e|0)!=2);break c}if((v|0)!=4){break c}m=L[i+8>>3];l=L[i>>3];if(G[321436]){a=G[24367];hb(89139,25,1,a);$a(a)}C:{if(H[3706664]){c=L[463350];d=L[463348];f=L[463334];n=L[463352];break C}G[926670]=442745336;G[926671]=1078765020;G[926668]=-1571644103;G[926669]=1066524486;G[926672]=-1929575474;G[926673]=-1078909396;G[926676]=2146916876;G[926677]=-1075057251;G[926680]=875303292;G[926681]=-1075908019;G[926684]=-102333635;G[926685]=1071614172;G[926688]=203628506;G[926689]=-1076047236;G[926692]=656523441;G[926693]=1072157603;G[926696]=-960750452;G[926697]=-1075068062;G[926700]=-1327103221;G[926701]=-1077404504;G[926704]=-867076380;G[926705]=1071477737;E[3706664]=1;d=-.8676008111514348;c=-.18837460172292028;f=.017453292519943295;n=.4601997847838517}q=f*l;l=eb(q);f=f*m;m=ib(f);f=eb(f);b=ib(q);s=d;d=f*l;f=c;c=m*l;f=n*b+(s*d+f*c);l=O(f);D:{if(l>=1){z=i,A=fc(f/l),L[z+16>>3]=A;b=0;break D}l=L[463346];m=L[463342];q=L[463344];n=L[463340];p=L[463336];s=L[463338];z=i,A=fc(f),L[z+16>>3]=A;b=Db(l*b+(m*d+c*q),n*b+(p*d+c*s))}c=L[463335];b=b*c;if(b<0){while(1){b=b+360;if(b<0){continue}break}}L[i+24>>3]=b;if(b>360){while(1){b=b+-360;if(b>360){continue}break}L[i+24>>3]=b}c=c*L[i+16>>3];L[i+16>>3]=c;b=90;E:{if(!(O(c)>=90)){break E}G[i+24>>2]=0;G[i+28>>2]=0;c=L[i+16>>3];if(!(c>90)){b=-90;if(!(c<-90)){break E}}L[i+16>>3]=b}b=L[i+24>>3];if((e|0)==5){dm(b,L[i+16>>3],g,h);break c}L[g>>3]=b;L[h>>3]=L[i+16>>3]}Fa=i+32|0}function xh(a,b,c,d,e,f,g,h,i,j,k,l,m,n){var o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=N(0),x=0,y=0,z=0,A=0,B=0,C=0,D=0,I=0,J=0,P=0,Q=0,R=0;o=Fa-896|0;Fa=o;G[o+248>>2]=0;G[o+252>>2]=1072693248;a:{if(!(g|h)|G[n>>2]>0){break a}p=G[a>>2];q=G[a+4>>2];b:{c:{if((p|0)!=G[q+76>>2]){mb(a,p+1|0,0,n);break c}if((G[q+128>>2]&G[q+132>>2])!=-1){break c}if((Rb(a,n)|0)>0){break b}}if(!((b|0)>0&G[G[a+4>>2]+936>>2]>=(b|0))){G[o>>2]=b;a=o+336|0;Ya(a,81,30457,o);Ua(a);G[n>>2]=302;break a}co(a,b,o+880|0,0,0,n);p=G[o+880>>2];if((p|0)<0){p=0-p|0;G[o+880>>2]=p}t=G[(G[G[a+4>>2]+968>>2]+M(b,160)|0)-80>>2];q=t>>31;d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{q=(q^t)-q|0;switch(q-14|0){case 0:break k;case 2:break l;case 1:break d;default:break m}}if((q|0)==83){break j}if((q|0)!=163){break d}j=1;q=c;c=f<<1|e>>>31;e=e<<1;r=e-1|0;e=c-!e|0;c=g;f=h<<1|c>>>31;p=c<<1;c=lb(p,8);Id(a,b,q,d,r,e,p,f,1,1,-91191291391491e-49,c,l,m,n);if(G[n>>2]>0){break e}Ck(a,b,o+884|0,n);d=(G[o+884>>2]-3|0)/2|0;G[o+884>>2]=d;e=b;b=o+800|0;zb(34187,e,b,n);E[o+768|0]=0;G[o+888>>2]=0;if(Fc(a,b,o+736|0,0,o+888|0)){break h}Ai(o+736|0,o+768|0);switch(H[o+736|0]-65|0){case 0:break g;case 8:case 14:case 25:case 40:case 46:case 57:break i;default:break h}}t=a;y=i;z=j;D=k;p=Fa-29072|0;Fa=p;n:{if(!(g|h)|G[n>>2]>0){break n}a=G[t>>2];if((a|0)!=G[G[t+4>>2]+76>>2]){mb(t,a+1|0,0,n)}if(m){G[m>>2]=0}if((y|0)==2){cb(l,0,g)}o:{p:{if((b|0)>0){a=G[t+4>>2];if(G[a+936>>2]>=(b|0)){break p}}G[p>>2]=b;a=p+28864|0;Ya(a,81,30457,p);Ua(a);a=302;break o}a=G[(G[a+968>>2]+M(b,160)|0)-80>>2];G[p+29068>>2]=a;q:{r:{s:{if((a|0)!=16){if((a|0)!=-16){break q}g=1;h=0;if((yc(t,b,c,d,1,0,1,0,0,p+29e3|0,p+28992|0,p+28960|0,p+29056|0,p+29068|0,p+29064|0,p+29032|0,p+29024|0,p+29052|0,p+29040|0,p+29008|0,p+29060|0,p+29016|0,p+28832|0,n)|0)<=0){break s}break n}if((yc(t,b,c,d,e,f,g,h,0,p+29e3|0,p+28992|0,p+28960|0,p+29056|0,p+29068|0,p+29064|0,p+29032|0,p+29024|0,p+29052|0,p+29040|0,p+29008|0,p+29060|0,p+29016|0,p+28832|0,n)|0)>0){break n}b=G[p+29056>>2];if((b|0)<2881){break r}G[p+29052>>2]=b;G[p+29064>>2]=1;G[p+29040>>2]=1;G[p+29044>>2]=0;break r}b=G[p+29040>>2];G[p+29056>>2]=b}I=1;a=Va(p+28832|0);J=a?a:1;t:{if(z?0:(y|0)==1){break t}u:{if(!(!z|(y|0)!=1)){if(!H[z|0]){break t}if(H[p+28832|0]!=1){break u}break t}if(H[p+28832|0]==1){break t}}I=!y|(b|0)<(J|0)}R=p+31|0;c=0;d=0;while(1){a=G[p+29064>>2];i=a;e=a>>31;a=G[p+29040>>2];k=G[p+29044>>2];f=G[p+29036>>2];b=G[p+29032>>2];j=Au(G[p+29008>>2],G[p+29012>>2],P,r);b=b+j|0;f=Ia+f|0;f=b>>>0>>0?f+1|0:f;q=b;b=G[p+29024>>2];x=G[p+29028>>2];j=G[p+29052>>2];A=Au(b,x,j,j>>31);j=q+A|0;q=Ia+f|0;Jb(t,j,j>>>0>>0?q+1|0:q,0,n);i=g>>>0>>0&(e|0)>=(h|0)|(e|0)>(h|0)?g:i;q=i;f=q>>31;e=k-((a>>>0>>0)+x|0)|0;a=a-b|0;b=a;a=a>>>0>q>>>0&(e|0)>=(f|0)|(e|0)>(f|0);x=a?q:b;b=G[p+29052>>2];e=G[p+29056>>2];v:{if((b|0)==(e|0)){b=M(b,x);ic(t,b,b>>31,p+32|0,n);break v}Rd(t,e,x,b-e|0,p+32|0,n)}q=x;f=q>>31;e=q;a=c+e|0;q=d+f|0;q=a>>>0>>0?q+1|0:q;w:{A=a;v=a-1|0;a=v;b=a>>>0>>0;a=a>>31;if(b&(a|0)<=(d|0)|(a|0)<(d|0)){break w}a=G[p+29056>>2];k=M(x,a)+R|0;if(I){while(1){u=G[D+(v<<2)>>2];i=u+a|0;b=i-1|0;x:{y:{if((a|0)<=1){j=0;E[i|0]=0;if((a|0)==1){break y}break x}j=a-1|0;z:{if(H[k|0]!=32){break z}B=u+1|0;C=(k-a|0)+1|0;a=b;while(1){if((j|0)>1){j=j-1|0;i=a;b=a-1|0;a=b;k=k-1|0;if(H[k|0]==32){continue}break z}break}j=0;k=C;i=B;b=u}E[i|0]=0}i=0;a=j;u=a+1&3;if(u){while(1){E[b|0]=H[k|0];a=a-1|0;b=b-1|0;k=k-1|0;i=i+1|0;if((u|0)!=(i|0)){continue}break}}if(j>>>0<=2){break x}while(1){E[b|0]=H[k|0];E[b-1|0]=H[k-1|0];E[b-2|0]=H[k-2|0];E[b-3|0]=H[k-3|0];b=b-4|0;k=k-4|0;i=(a|0)==3;a=a-4|0;if(!i){continue}break}}v=v-1|0;a=v;b=a>>>0>>0;a=a>>31;if(b&(a|0)<=(d|0)|(a|0)<(d|0)){break w}a=G[p+29056>>2];continue}}while(1){Q=D+(v<<2)|0;u=G[Q>>2];i=u+a|0;b=i-1|0;A:{B:{if((a|0)>=2){j=a-1|0;C:{if(H[k|0]!=32){break C}B=u+1|0;C=(k-a|0)+1|0;while(1){D:{i=b;if((a|0)<=2){break D}a=j;j=a-1|0;b=i-1|0;k=k-1|0;if(H[k|0]==32){continue}break C}break}j=0;k=C;i=B;b=u}E[i|0]=0;break B}j=0;E[i|0]=0;if((a|0)!=1){break A}}i=0;a=j;u=a+1&3;if(u){while(1){E[b|0]=H[k|0];a=a-1|0;b=b-1|0;k=k-1|0;i=i+1|0;if((u|0)!=(i|0)){continue}break}}if(j>>>0<3){break A}while(1){E[b|0]=H[k|0];E[b-1|0]=H[k-1|0];E[b-2|0]=H[k-2|0];E[b-3|0]=H[k-3|0];b=b-4|0;k=k-4|0;i=(a|0)!=3;a=a-4|0;if(i){continue}break}}a=G[Q>>2];E:{if(fb(p+28832|0,a,J)){break E}G[m>>2]=1;if((y|0)==1){if(z){Za(a,z);break E}E[a|0]=32;E[a+1|0]=0;break E}E[l+v|0]=1}v=v-1|0;a=v;b=a>>>0>>0;a=a>>31;if(b&(a|0)<=(d|0)|(a|0)<(d|0)){break w}a=G[p+29056>>2];continue}}if(G[n>>2]>0){s=+(c>>>0)+ +(d|0)*4294967296;L[p+16>>3]=s+1;L[p+24>>3]=s+ +(x|0);a=p+28864|0;Ya(a,81,45884,p+16|0);Ua(a);break n}h=h-((e>>>0>g>>>0)+f|0)|0;g=g-e|0;if(!(h|g)){break n}f=f+G[p+29028>>2]|0;a=e+G[p+29024>>2]|0;f=a>>>0>>0?f+1|0:f;G[p+29024>>2]=a;G[p+29028>>2]=f;c=A;d=q;if(G[p+29040>>2]!=(a|0)|G[p+29044>>2]!=(f|0)){continue}G[p+29024>>2]=0;G[p+29028>>2]=0;f=r;a=P+1|0;f=a?f:f+1|0;P=a;r=f;continue}}a=309}G[n>>2]=a}Fa=p+29072|0;break b}r=ab(g);fg(a,b,c,d,e,f,g,h,i,E[j|0],r,l,m,n);F:{if(!g&(h|0)<=0|(h|0)<0|G[n>>2]>0){break F}d=g&1;i=0;a=0;if((g|0)!=1|h){j=g&-2;a=h;g=0;h=0;e=0;f=0;while(1){c=G[(g<<2)+k>>2];b=H[g+r|0];b=(b|0)==1?84:b?78:70;E[c|0]=b;E[c+1|0]=b>>>8;c=g|1;b=H[c+r|0];c=G[(c<<2)+k>>2];b=(b|0)==1?84:b?78:70;E[c|0]=b;E[c+1|0]=b>>>8;c=h;b=g+2|0;c=b>>>0<2?c+1|0:c;g=b;h=c;b=e+2|0;q=b>>>0<2?f+1|0:f;e=b;f=q;if((j|0)!=(b|0)|(a|0)!=(f|0)){continue}break}a=g}if(!(d|i)){break F}b=G[(a<<2)+k>>2];a=H[a+r|0];a=(a|0)==1?84:a?78:70;E[b|0]=a;E[b+1|0]=a>>>8}Wa(r);break b}j=1;r=c;q=f<<1|e>>>31;c=e<<1;f=c-1|0;p=q-!c|0;e=g;c=h<<1|e>>>31;e=e<<1;q=lb(e,4);ae(a,b,r,d,f,p,e,c,1,1,N(-9119119840596153e-51),q,l,m,n);G:{if(G[n>>2]>0){break G}Ck(a,b,o+884|0,n);c=(G[o+884>>2]-3|0)/2|0;G[o+884>>2]=c;d=b;b=o+800|0;zb(34187,d,b,n);E[o+768|0]=0;G[o+888>>2]=0;H:{I:{J:{if(Fc(a,b,o+736|0,0,o+888|0)){break J}Ai(o+736|0,o+768|0);K:{switch(H[o+736|0]-65|0){case 0:break I;case 8:case 14:case 25:case 40:case 46:case 57:break K;default:break J}}j=0}if(H[o+768|0]){break H}}a=H[35735]|H[35736]<<8|(H[35737]<<16|H[35738]<<24);E[o+771|0]=a;E[o+772|0]=a>>>8;E[o+773|0]=a>>>16;E[o+774|0]=a>>>24;G[o+768>>2]=H[35732]|H[35733]<<8|(H[35734]<<16|H[35735]<<24)}if(!g&(h|0)<=0|(h|0)<0){break G}e=0;f=0;a=0;while(1){b=(e<<2)+k|0;d=G[b>>2];E[d|0]=40;E[d+1|0]=0;m=a<<2;w=K[m+q>>2];L:{if(w==N(-9119119840596153e-51)){E[o+340|0]=H[34773];G[o+336>>2]=H[34769]|H[34770]<<8|(H[34771]<<16|H[34772]<<24);if((i|0)!=2){break L}E[e+l|0]=1;break L}if(!j){if(N(O(w))>2]=d;Ya(o+336|0,400,o+768|0,o+176|0);break L}L[o+160>>3]=w;Ya(o+336|0,400,o+768|0,o+160|0)}qb(G[b>>2],o+336|0,c);d=G[b>>2];d=Va(d)+d|0;E[d|0]=44;E[d+1|0]=0;w=K[q+(m|4)>>2];M:{if(w==N(-9119119840596153e-51)){E[o+340|0]=H[34773];G[o+336>>2]=H[34769]|H[34770]<<8|(H[34771]<<16|H[34772]<<24);if((i|0)!=2){break M}E[e+l|0]=1;break M}if(!j){if(N(O(w))>2]=d;Ya(o+336|0,400,o+768|0,o+144|0);break M}L[o+128>>3]=w;Ya(o+336|0,400,o+768|0,o+128|0)}qb(G[b>>2],o+336|0,c);b=G[b>>2];b=Va(b)+b|0;E[b|0]=41;E[b+1|0]=0;a=a+2|0;b=e+1|0;f=b?f:f+1|0;e=b;if((g|0)!=(b|0)|(f|0)!=(h|0)){continue}break}}Wa(q);break b}j=0}if(H[o+768|0]){break f}}G[o+768>>2]=775107109;G[o+772>>2]=4535601}if(!g&(h|0)<=0|(h|0)<0){break e}e=0;f=0;a=0;while(1){b=(e<<2)+k|0;m=G[b>>2];E[m|0]=40;E[m+1|0]=0;n=a<<3;s=L[n+c>>3];N:{if(s==-91191291391491e-49){E[o+340|0]=H[34773];G[o+336>>2]=H[34769]|H[34770]<<8|(H[34771]<<16|H[34772]<<24);if((i|0)!=2){break N}E[e+l|0]=1;break N}if(!j){if(O(s)<2147483648){m=~~s}else{m=-2147483648}G[o+240>>2]=m;Ya(o+336|0,400,o+768|0,o+240|0);break N}L[o+224>>3]=s;Ya(o+336|0,400,o+768|0,o+224|0)}qb(G[b>>2],o+336|0,d);m=G[b>>2];m=Va(m)+m|0;E[m|0]=44;E[m+1|0]=0;s=L[c+(n|8)>>3];O:{if(s==-91191291391491e-49){E[o+340|0]=H[34773];G[o+336>>2]=H[34769]|H[34770]<<8|(H[34771]<<16|H[34772]<<24);if((i|0)!=2){break O}E[e+l|0]=1;break O}if(!j){if(O(s)<2147483648){m=~~s}else{m=-2147483648}G[o+208>>2]=m;Ya(o+336|0,400,o+768|0,o+208|0);break O}L[o+192>>3]=s;Ya(o+336|0,400,o+768|0,o+192|0)}qb(G[b>>2],o+336|0,d);b=G[b>>2];b=Va(b)+b|0;E[b|0]=41;E[b+1|0]=0;a=a+2|0;b=e+1|0;f=b?f:f+1|0;e=b;if((g|0)!=(b|0)|(f|0)!=(h|0)){continue}break}}Wa(c);break b}P:{t=(q|0)!=81;if(!(t|(p|0)!=81)){q=lb(g,8);r=lb(g,1);G[o+884>>2]=20;Se(a,b,c,d,e,f,g,h,1,2,0,0,q,r,m,n);if(G[n>>2]>0){break P}Q:{if(j){a=rb(o+256|0,j,79);E[a+79|0]=0;a=Va(a);break Q}F[o+256>>1]=32;a=1}if(!g&(h|0)<=0|(h|0)<0){break P}e=0;f=0;b=(a|0)<21;while(1){R:{if(H[e+r|0]){a=(e<<2)+k|0;E[G[a>>2]]=0;a=G[a>>2];S:{if(!b){qb(a,o+256|0,20);break S}G[o+32>>2]=20;G[o+36>>2]=o+256;db(a,8725,o+32|0)}if((i|0)!=2){break R}E[e+l|0]=1;break R}a=q+(e<<3)|0;c=G[a+4>>2];G[o+16>>2]=G[a>>2];G[o+20>>2]=c;a=o+336|0;Ya(a,400,26734,o+16|0);c=(e<<2)+k|0;E[G[c>>2]]=0;qb(G[c>>2],a,20)}a=e+1|0;f=a?f:f+1|0;e=a;if((a|0)!=(g|0)|(f|0)!=(h|0)){continue}break}break P}r=lb(g,8);T:{if(!((p|0)!=80|t)){q=lb(g,1);G[o+884>>2]=20;hf(a,b,c,d,e,f,g,h,1,2,0,0,r,q,m,n);if(G[n>>2]>0){Wa(q);break T}U:{if(j){a=rb(o+256|0,j,79);E[a+79|0]=0;a=Va(a);break U}F[o+256>>1]=32;a=1}if(!!g&(h|0)>=0|(h|0)>0){e=0;f=0;b=(a|0)<21;while(1){V:{if(H[e+q|0]){a=(e<<2)+k|0;E[G[a>>2]]=0;a=G[a>>2];W:{if(!b){qb(a,o+256|0,20);break W}G[o+64>>2]=20;G[o+68>>2]=o+256;db(a,8725,o- -64|0)}if((i|0)!=2){break V}E[e+l|0]=1;break V}a=r+(e<<3)|0;c=G[a+4>>2];G[o+48>>2]=G[a>>2];G[o+52>>2]=c;a=o+336|0;Ya(a,400,4033,o+48|0);c=(e<<2)+k|0;E[G[c>>2]]=0;qb(G[c>>2],a,20)}c=f;a=e+1|0;c=a?c:c+1|0;e=a;f=c;if((g|0)!=(a|0)|(h|0)!=(c|0)){continue}break}}Wa(q);break T}if((Id(a,b,c,d,e,f,g,h,1,i,-91191291391491e-49,r,l,m,n)|0)>0){break T}Ck(a,b,o+884|0,n);c=o+800|0;zb(34838,b,c,n);G[o+888>>2]=0;e=o+888|0;d=Kc(a,c,o+248|0,e);s=L[o+248>>3];zb(34187,b,c,n);E[o+768|0]=0;G[o+888>>2]=0;d=!d&s!=1;m=!d&q>>>0<42;X:{Y:{Z:{if(Fc(a,c,o+736|0,0,e)){break Z}Ai(o+736|0,o+768|0);_:{switch(H[o+736|0]-65|0){case 0:E[o+768|0]=0;break Y;case 8:case 14:case 25:case 40:case 46:case 57:break _;default:break Z}}m=1}if(H[o+768|0]){break X}}c=b;b=o+800|0;zb(34641,c,b,n);Fc(a,b,o+736|0,0,n);if(d&q>>>0<22){G[o+768>>2]=875635493;G[o+772>>2]=4666926;break X}if(d&(q|0)==41){E[o+776|0]=H[35120];a=H[35116]|H[35117]<<8|(H[35118]<<16|H[35119]<<24);G[o+768>>2]=H[35112]|H[35113]<<8|(H[35114]<<16|H[35115]<<24);G[o+772>>2]=a;break X}if(d&(q|0)==81){E[o+776|0]=H[35120];a=H[35116]|H[35117]<<8|(H[35118]<<16|H[35119]<<24);G[o+768>>2]=H[35112]|H[35113]<<8|(H[35114]<<16|H[35115]<<24);G[o+772>>2]=a;break X}Dc(a,o+892|0,n);if(G[o+892>>2]==1){Ai(o+736|0,o+768|0);break X}$:{switch(q-1|0){case 0:G[o+768>>2]=6566949;break X;case 10:G[o+768>>2]=6566949;break X;case 20:G[o+768>>2]=6567461;break X;default:break $}}if((q|0)==41){m=0;a=H[19403]|H[19404]<<8|(H[19405]<<16|H[19406]<<24);E[o+771|0]=a;E[o+772|0]=a>>>8;E[o+773|0]=a>>>16;E[o+774|0]=a>>>24;G[o+768>>2]=H[19400]|H[19401]<<8|(H[19402]<<16|H[19403]<<24);break X}if((q|0)!=82){if((q|0)!=42){break X}G[o+768>>2]=875635493;G[o+772>>2]=4666926;break X}E[o+776|0]=H[35120];a=H[35116]|H[35117]<<8|(H[35118]<<16|H[35119]<<24);G[o+768>>2]=H[35112]|H[35113]<<8|(H[35114]<<16|H[35115]<<24);G[o+772>>2]=a}aa:{if(j){a=rb(o+256|0,j,79);E[a+79|0]=0;a=Va(a);break aa}F[o+256>>1]=32;a=1}if(!g&(h|0)<=0|(h|0)<0){break T}e=0;f=0;if((q|0)==1){while(1){b=(e<<2)+k|0;c=G[b>>2];s=L[r+(e<<3)>>3];ba:{if(O(s)<2147483648){a=~~s;break ba}a=-2147483648}E[c|0]=a&128?49:48;E[G[b>>2]+1|0]=a&64?49:48;E[G[b>>2]+2|0]=a&32?49:48;E[G[b>>2]+3|0]=a&16?49:48;E[G[b>>2]+4|0]=a&8?49:48;E[G[b>>2]+5|0]=a&4?49:48;E[G[b>>2]+6|0]=a&2?49:48;E[G[b>>2]+7|0]=a&1?49:48;E[G[b>>2]+8|0]=0;a=e+1|0;f=a?f:f+1|0;e=a;if((g|0)!=(a|0)|(f|0)!=(h|0)){continue}break T}}c=i-1|0;b=G[o+884>>2];d=(b|0)>=(a|0);while(1){ca:{da:{ea:{fa:{switch(c|0){case 1:a=e;if(!H[l+a|0]){break ea}break da;case 0:break fa;default:break ea}}a=e;if(L[r+(a<<3)>>3]==-91191291391491e-49){break da}}s=L[r+(e<<3)>>3];ga:{if(m){if(O(s)<2147483648){a=~~s}else{a=-2147483648}G[o+80>>2]=a;Ya(o+336|0,400,o+768|0,o+80|0);break ga}L[o+96>>3]=s;Ya(o+336|0,400,o+768|0,o+96|0)}if((Va(o+336|0)|0)>(b|0)){cb(o+336|0,42,b)}a=(e<<2)+k|0;E[G[a>>2]]=0;qb(G[a>>2],o+336|0,b);break ca}a=(a<<2)+k|0;E[G[a>>2]]=0;a=G[a>>2];if(!d){qb(a,o+256|0,b);break ca}G[o+112>>2]=b;G[o+116>>2]=o+256;db(a,8725,o+112|0)}a=e+1|0;f=a?f:f+1|0;e=a;if((g|0)!=(a|0)|(f|0)!=(h|0)){continue}break}}Wa(r);break b}Wa(r);Wa(q)}}Fa=o+896|0} -function Ef(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,P=0,Q=N(0),R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0;q=Fa-29104|0;Fa=q;p=G[o>>2];a:{if(!(g|h)|(p|0)>0){break a}if(n){G[n>>2]=0}if((j|0)==2){cb(m,0,g)}yc(a,b,c,d,e,f,g,h,i>>31,q+29096|0,q+29088|0,q+28992|0,q+29064|0,q+29084|0,q+29080|0,q+29040|0,q+29032|0,q+29060|0,q+29048|0,q+29016|0,q+29076|0,q+29024|0,q+28864|0,o);z=G[q+29084>>2];if(!((i|0)!=1|(z|0)!=14)){fg(a,b,c,d,e,f,g,h,j,k,l,m,n,o);p=G[o>>2];break a}if(jb(q+28992|0,65)){if(G[o>>2]==308){G[o>>2]=0;df()}G[q+29060>>2]=1;G[q+29084>>2]=11;c=G[q+29064>>2];d=c>>31;G[q+29064>>2]=1;G[q+29048>>2]=c;G[q+29052>>2]=d;G[q+29096>>2]=0;G[q+29100>>2]=1072693248;G[q+29088>>2]=0;G[q+29092>>2]=0;G[q+29024>>2]=1234554321;G[q+29028>>2]=0;G[q+29080>>2]=28800;z=11}p=G[o>>2];if((p|0)>0){break a}G[q+29060>>2]=M(G[q+29060>>2],i);C=1;b:{if((z|0)!=16|G[q+29076>>2]!=1){break b}Gd(q+28992|0,q+29072|0,q+29056|0,q+29068|0,o);d=G[q+29068>>2];if((d|0)<=0){break b}if(d-1>>>0>=7){c=d&-8;p=0;while(1){C=C*10*10*10*10*10*10*10*10;p=p+8|0;if((c|0)!=(p|0)){continue}break}}c=d&7;if(!c){break b}p=0;while(1){C=C*10;p=p+1|0;if((c|0)!=(p|0)){continue}break}}z=0;c:{if(k?0:(j|0)==1){break c}f=G[q+29028>>2];c=G[q+29024>>2];p=G[q+29084>>2];if(!f&(c|0)==1234554321&((p|0)%10|0)==1){break c}e=f-(c>>>0<32768)|0;if(((e|0)==-1&c-32768>>>0<4294901760|(e|0)!=-1)&(p|0)==21|(!f&c>>>0>255|(f|0)!=0)&(p|0)==11){break c}z=(p|0)==16?H[q+28864|0]==1?0:j:j}X=0-i|0;e=0;f=0;d:{while(1){c=G[q+29080>>2];j=c>>31;c=(h|0)<=(j|0)&c>>>0>g>>>0|(h|0)<(j|0)?g:c;d=c>>31;u=c;x=d;e:{if((i|0)>=0){d=G[q+29036>>2];p=G[q+29052>>2]+(d^-1)|0;c=G[q+29032>>2];j=c^-1;v=j+G[q+29048>>2]|0;v=Bu(v,j>>>0>v>>>0?p+1|0:p,i,0);j=Ia;break e}c=G[q+29032>>2];d=G[q+29036>>2];v=Bu(c,d,X,0);j=Ia}s=G[q+29044>>2];w=G[q+29040>>2];p=Au(G[q+29016>>2],G[q+29020>>2],D,P);w=w+p|0;s=Ia+s|0;s=p>>>0>w>>>0?s+1|0:s;t=w;p=c;w=G[q+29060>>2];c=(w|0)/(i|0)|0;d=Au(p,d,c,c>>31);p=t+d|0;c=Ia+s|0;c=d>>>0>p>>>0?c+1|0:c;s=p;p=j;d=v+1|0;p=d;d=(j|0)<=(x|0)&u>>>0>v>>>0|(j|0)<(x|0);u=d?p:u;f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{d=G[q+29084>>2];switch(d-11|0){case 0:break g;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break h;case 5:break i;case 31:break k;case 30:break m;case 10:break n;default:break o}}switch(d-81|0){case 1:break j;case 0:break l;default:break h}}d=c;c=q- -64|0;Pe(a,s,d,u,w,c,o);Eo(c,u,L[q+29096>>3],L[q+29088>>3],z,F[q+29024>>1],k,e+m|0,n,e+l|0,o);break f}d=c;c=q- -64|0;Uc(a,s,d,u,w,c,o);Do(c,u,L[q+29096>>3],L[q+29088>>3],z,G[q+29024>>2],k,e+m|0,n,e+l|0,o);break f}t=q- -64|0;Tc(a,s,c,u,w,t,o);w=G[q+29024>>2];s=G[q+29028>>2];j=e+m|0;c=e+l|0;y=L[q+29096>>3];A=L[q+29088>>3];d=y==1&A==0x8000000000000000;p:{q:{r:{s:{t:{if(!z){if(d){if((u|0)<=0){break p}d=0;if((u|0)!=1){s=u&-2;j=0;while(1){x=c+d|0;p=t+(d<<3)|0;v=G[p+4>>2];p=G[p>>2];if((v|0)!=-2147483648|p>>>0>=128){G[o>>2]=-11;p=127}E[x|0]=p;x=d|1;p=t+(x<<3)|0;v=G[p+4>>2];p=G[p>>2];if(!((v|0)==-2147483648&p>>>0<=127)){G[o>>2]=-11;p=127}E[c+x|0]=p;d=d+2|0;j=j+2|0;if((s|0)!=(j|0)){continue}break}}if(!(u&1)){break p}j=t+(d<<3)|0;p=G[j+4>>2];j=G[j>>2];if((p|0)!=-2147483648|j>>>0>127){break t}break s}if(y==1&A==0){break q}d=0;if((u|0)<=0){break p}while(1){p=c+d|0;j=t+(d<<3)|0;r=(+J[j>>2]+ +G[j+4>>2]*4294967296)*y+A;u:{if(r<-128.49){G[o>>2]=-11;j=128;break u}if(r>127.49){G[o>>2]=-11;j=127;break u}j=~~r;if(O(r)<2147483648){break u}j=-2147483648}E[p|0]=j;d=d+1|0;if((u|0)!=(d|0)){continue}break}break p}if(d){if((u|0)<=0){break p}d=(z|0)==1;x=d?k:1;v=d?c:j;d=0;while(1){p=t+(d<<3)|0;j=G[p>>2];p=G[p+4>>2];v:{if((j|0)==(w|0)&(p|0)==(s|0)){G[n>>2]=1;j=x;p=v;break v}if((p|0)!=-2147483648|j>>>0>=128){G[o>>2]=-11;j=127}p=c}E[p+d|0]=j;d=d+1|0;if((u|0)!=(d|0)){continue}break}break p}if(y==1&A==0){break r}if((u|0)<=0){break p}d=(z|0)==1;x=d?k:1;v=d?c:j;d=0;while(1){j=t+(d<<3)|0;p=G[j>>2];j=G[j+4>>2];w:{if((p|0)==(w|0)&(j|0)==(s|0)){G[n>>2]=1;j=x;p=v;break w}r=(+(p>>>0)+ +(j|0)*4294967296)*y+A;x:{if(r<-128.49){G[o>>2]=-11;j=128;break x}if(r>127.49){G[o>>2]=-11;j=127;break x}j=~~r;if(O(r)<2147483648){break x}j=-2147483648}p=c}E[p+d|0]=j;d=d+1|0;if((u|0)!=(d|0)){continue}break}break p}G[o>>2]=-11;j=127}E[c+d|0]=j;break p}if((u|0)<=0){break p}d=(z|0)==1;x=d?k:1;v=d?c:j;d=0;while(1){p=t+(d<<3)|0;j=G[p>>2];p=G[p+4>>2];y:{if((j|0)==(w|0)&(p|0)==(s|0)){G[n>>2]=1;j=x;p=v;break y}z:{if((p|0)<0&j>>>0<=4294967167|(p|0)<-1){G[o>>2]=-11;j=128;break z}if((p|0)>=0&j>>>0>=128|(p|0)>0){G[o>>2]=-11;j=127}}p=c}E[p+d|0]=j;d=d+1|0;if((u|0)!=(d|0)){continue}break}break p}if((u|0)<=0){break p}d=0;while(1){v=c+d|0;p=t+(d<<3)|0;j=G[p+4>>2];p=G[p>>2];A:{if((j|0)<0&p>>>0<=4294967167|(j|0)<-1){G[o>>2]=-11;p=128;break A}if((j|0)>=0&p>>>0>=128|(j|0)>0){G[o>>2]=-11;p=127;break A}}E[v|0]=p;d=d+1|0;if((u|0)!=(d|0)){continue}break}}break f}d=s;s=q- -64|0;Uc(a,d,c,u,w,s,o);A=L[q+29096>>3];y=L[q+29088>>3];j=e+m|0;d=e+l|0;t=0;B:{C:{if(!z){if(A==1&y==0){break C}if((u|0)<=0){break B}while(1){c=d+t|0;r=+K[s+(t<<2)>>2]*A+y;D:{if(r<-128.49){G[o>>2]=-11;j=128;break D}if(r>127.49){G[o>>2]=-11;j=127;break D}j=~~r;if(O(r)<2147483648){break D}j=-2147483648}E[c|0]=j;t=t+1|0;if((u|0)!=(t|0)){continue}break}break B}t=s+2|0;E:{F:{if(!(A==1&y==0)){if((u|0)<=0){break B}c=(z|0)==1;x=c?k:1;v=c?d:j;if(!(O(y)<2147483648)){break F}p=~~y;break E}if((u|0)<=0){break B}c=(z|0)==1;v=c?k:1;c=c?d:j;w=0;while(1){p=d;j=0;G:{H:{I:{x=I[t>>1]&32640;switch(((x|0)==32640?1:!x<<1)|0){case 0:break H;case 1:break I;default:break G}}G[n>>2]=1;p=c;j=v;break G}Q=K[s+(w<<2)>>2];r=+Q;J:{if(r<-128.49){G[o>>2]=-11;j=128;break J}if(r>127.49){G[o>>2]=-11;j=127;break J}j=~~Q;if(N(O(Q))>1]&32640;switch(((c|0)==32640?1:!c<<1)|0){case 0:break M;case 1:break O;default:break N}}G[n>>2]=1;j=x;c=v;break K}if(y<-128.49){G[o>>2]=-11;j=128;break L}j=p;c=d;if(!(y>127.49)){break K}G[o>>2]=-11;j=127;break L}r=+K[s+(w<<2)>>2]*A+y;if(r<-128.49){G[o>>2]=-11;j=128;break L}if(r>127.49){G[o>>2]=-11;j=127;break L}j=~~r;if(O(r)<2147483648){break L}j=-2147483648}c=d}E[c+w|0]=j;t=t+4|0;w=w+1|0;if((u|0)!=(w|0)){continue}break}break B}if((u|0)<=0){break B}while(1){c=d+t|0;Q=K[s+(t<<2)>>2];r=+Q;P:{if(r<-128.49){G[o>>2]=-11;j=128;break P}if(r>127.49){G[o>>2]=-11;j=127;break P}j=~~Q;if(N(O(Q))>3];y=L[q+29088>>3];j=e+m|0;d=e+l|0;t=0;Q:{R:{if(!z){if(A==1&y==0){break R}if((u|0)<=0){break Q}while(1){c=d+t|0;r=L[s+(t<<3)>>3]*A+y;S:{if(r<-128.49){G[o>>2]=-11;j=128;break S}if(r>127.49){G[o>>2]=-11;j=127;break S}j=~~r;if(O(r)<2147483648){break S}j=-2147483648}E[c|0]=j;t=t+1|0;if((u|0)!=(t|0)){continue}break}break Q}t=s+6|0;T:{U:{if(!(A==1&y==0)){if((u|0)<=0){break Q}c=(z|0)==1;x=c?k:1;v=c?d:j;if(!(O(y)<2147483648)){break U}p=~~y;break T}if((u|0)<=0){break Q}c=(z|0)==1;v=c?k:1;c=c?d:j;w=0;while(1){p=d;j=0;V:{W:{X:{x=I[t>>1]&32752;switch(((x|0)==32752?1:!x<<1)|0){case 0:break W;case 1:break X;default:break V}}G[n>>2]=1;p=c;j=v;break V}r=L[s+(w<<3)>>3];Y:{if(r<-128.49){G[o>>2]=-11;j=128;break Y}if(r>127.49){G[o>>2]=-11;j=127;break Y}j=~~r;if(O(r)<2147483648){break Y}j=-2147483648}}E[p+w|0]=j;t=t+8|0;w=w+1|0;if((u|0)!=(w|0)){continue}break}break Q}p=-2147483648}w=0;while(1){Z:{_:{$:{aa:{ba:{c=I[t>>1]&32752;switch(((c|0)==32752?1:!c<<1)|0){case 0:break $;case 1:break ba;default:break aa}}G[n>>2]=1;j=x;c=v;break Z}if(y<-128.49){G[o>>2]=-11;j=128;break _}j=p;c=d;if(!(y>127.49)){break Z}G[o>>2]=-11;j=127;break _}r=L[s+(w<<3)>>3]*A+y;if(r<-128.49){G[o>>2]=-11;j=128;break _}if(r>127.49){G[o>>2]=-11;j=127;break _}j=~~r;if(O(r)<2147483648){break _}j=-2147483648}c=d}E[c+w|0]=j;t=t+8|0;w=w+1|0;if((u|0)!=(w|0)){continue}break}break Q}if((u|0)<=0){break Q}while(1){c=d+t|0;r=L[s+(t<<3)>>3];ca:{if(r<-128.49){G[o>>2]=-11;j=128;break ca}if(r>127.49){G[o>>2]=-11;j=127;break ca}j=~~r;if(O(r)<2147483648){break ca}j=-2147483648}E[c|0]=j;t=t+1|0;if((u|0)!=(t|0)){continue}break}}break f}Jb(a,s,c,0,o);d=G[q+29060>>2];c=G[q+29064>>2];da:{if((d|0)==(c|0)){c=M(d,u);ic(a,c,c>>31,q- -64|0,o);break da}Rd(a,c,u,d-c|0,q- -64|0,o)}d=q- -64|0;y=L[q+29096>>3];A=L[q+29088>>3];Y=G[q+29064>>2];j=e+m|0;t=e+l|0;S=0;B=Fa-112|0;Fa=B;T=q+28864|0;Z=Va(T);if((u|0)>0){ea:{c=(z|0)==1;w=c?k:1;s=c?t:j;while(1){v=d+Y|0;V=H[v|0];E[v|0]=0;j=d;fa:{ga:{ha:{if(H[T|0]==1){break ha}if(fb(T,d,Z)){break ha}d=v;if(!z){break fa}G[n>>2]=1;p=w;j=v;c=s;break ga}while(1){c=H[j|0];if((c|0)==32){j=j+1|0;continue}break}W=1;ia:{switch(c-43|0){case 0:case 2:while(1){p=H[j+1|0];j=j+1|0;if((p|0)==32){continue}break};W=(c|0)==45?-1:1;c=p;break;default:break ia}}R=0;if((c-48&255)>>>0<10){while(1){r=R*10+ +(c<<24>>24);p=j;while(1){c=H[p+1|0];j=p+1|0;p=j;if((c|0)==32){continue}break}R=r+-48;if((c-48&255)>>>0<=9){continue}break}}r=C;ja:{ka:{switch(c-44|0){case 0:case 2:break ka;default:break ja}}p=j;while(1){c=H[p+1|0];j=p+1|0;p=j;if((c|0)==32){continue}break}r=1;if((c-48&255)>>>0>=10){break ja}while(1){R=R*10+ +(c<<24>>24)+-48;p=j;while(1){c=H[p+1|0];j=p+1|0;p=j;if((c|0)==32){continue}break}r=r*10;if((c-48&255)>>>0<=9){continue}break}}la:{if((c&254)!=68){U=1;p=0;break la}while(1){U=1;p=j;j=p+1|0;c=H[p+1|0];if((c|0)==32){continue}break}ma:{switch(c-43|0){case 0:case 2:p=p+2|0;while(1){j=p;p=p+1|0;x=H[j|0];if((x|0)==32){continue}break};U=(c|0)==45?-1:1;c=x;break;default:break ma}}p=0;if((c-48&255)>>>0>=10){break la}while(1){x=c;_=M(p,10)-48|0;p=j;while(1){c=H[p+1|0];j=p+1|0;p=j;if((c|0)==32){continue}break}p=(x<<24>>24)+_|0;if((c-48&255)>>>0<=9){continue}break}}if(c){G[B+48>>2]=H[23477]|H[23478]<<8|(H[23479]<<16|H[23480]<<24);c=H[23473]|H[23474]<<8|(H[23475]<<16|H[23476]<<24);G[B+40>>2]=H[23469]|H[23470]<<8|(H[23471]<<16|H[23472]<<24);G[B+44>>2]=c;c=H[23465]|H[23466]<<8|(H[23467]<<16|H[23468]<<24);G[B+32>>2]=H[23461]|H[23462]<<8|(H[23463]<<16|H[23464]<<24);G[B+36>>2]=c;c=H[23457]|H[23458]<<8|(H[23459]<<16|H[23460]<<24);G[B+24>>2]=H[23453]|H[23454]<<8|(H[23455]<<16|H[23456]<<24);G[B+28>>2]=c;c=H[23449]|H[23450]<<8|(H[23451]<<16|H[23452]<<24);G[B+16>>2]=H[23445]|H[23446]<<8|(H[23447]<<16|H[23448]<<24);G[B+20>>2]=c;c=B+16|0;Ua(c);G[B>>2]=d;Ya(c,81,43022,B);Ua(c);E[v|0]=V;G[o>>2]=409;break ea}r=R*+(W|0)/r*$b(10,+(M(p,U)|0))*y+A;na:{if(r<-128.49){G[o>>2]=-11;p=128;break na}if(r>127.49){G[o>>2]=-11;p=127;break na}p=~~r;if(O(r)<2147483648){break na}p=-2147483648}c=t}E[c+S|0]=p;d=j}E[v|0]=V;S=S+1|0;if((u|0)!=(S|0)){continue}break}}}Fa=B+112|0;break f}G[q>>2]=b;G[q+4>>2]=q+28992;a=q+28896|0;Ya(a,81,8979,q);Ua(a);p=311;if(G[q+29076>>2]==1){break d}p=312;break d}d=c;c=e+l|0;$d(a,s,d,u,w,c,o);Co(c,u,L[q+29096>>3],L[q+29088>>3],z,H[q+29024|0],k,e+m|0,n,c,o)}p=G[o>>2];if((p|0)>0){r=+(e>>>0)+ +(f|0)*4294967296;C=r+1;r=r+ +(u|0);oa:{if(G[q+29076>>2]>0){G[q+32>>2]=b;L[q+24>>3]=r;L[q+16>>3]=C;Ya(q+28896|0,81,47998,q+16|0);break oa}L[q+56>>3]=r;L[q+48>>3]=C;Ya(q+28896|0,81,47938,q+48|0)}Ua(q+28896|0);p=G[o>>2];break a}d=u;j=d>>31;h=h-((d>>>0>g>>>0)+j|0)|0;g=g-d|0;if(h|g){c=M(i,u);v=c+G[q+29032>>2]|0;p=G[q+29036>>2]+(c>>31)|0;p=c>>>0>v>>>0?p+1|0:p;c=v;G[q+29032>>2]=c;G[q+29036>>2]=p;s=f+j|0;e=d+e|0;s=e>>>0>>0?s+1|0:s;f=s;s=G[q+29052>>2];d=s;x=G[q+29048>>2];if((p|0)>=(d|0)&c>>>0>=x>>>0|(d|0)<(p|0)){j=Bu(c,p,x,s);v=D+j|0;d=Ia;P=P+d|0;P=v>>>0>>0?P+1|0:P;D=v;d=Au(x,s,j,d);G[q+29032>>2]=c-d;G[q+29036>>2]=p-(Ia+(c>>>0>>0)|0);continue}if((p|0)>0|(p|0)>=0){continue}j=D;D=Bu(c^-1,p^-1,x,s)+1|0;d=Ia;d=D?d:d+1|0;v=D;D=j-v|0;P=P-((j>>>0>>0)+d|0)|0;d=Au(x,s,v,d)+c|0;s=p+Ia|0;G[q+29032>>2]=d;G[q+29036>>2]=c>>>0>d>>>0?s+1|0:s;continue}break}if((p|0)!=-11){break a}Ua(44994);p=412}G[o>>2]=p}Fa=q+29104|0;return p}function cc(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,H=0,I=0,J=0,K=0,N=0;j=Fa-144|0;Fa=j;a:{if(!a|!G[a+3312>>2]){break a}L[a+584>>3]=c;L[a+576>>3]=b;f=L[160676];G[a+3308>>2]=0;L[a+592>>3]=f;g=G[a+9392>>2];b:{if(g){cc(g,b,c,j+24|0,j+16|0);break b}f=b;h=c;g=0;b=0;c=0;s=Fa-80|0;c:{if(G[a+6048>>2]==1){i=h-L[a+24>>3];m=f-L[a+16>>3];o=G[a+6864>>2];q=G[a+6056>>2];d:{if((q|0)<0){break d}while(1){t=M(q-g|0,80)+a|0;l=g<<3;b=L[(t+l|0)+6064>>3];v=l+s|0;l=g;e:{if(!g){break e}k=0;y=l&3;if(y){while(1){g=g-1|0;b=i*b+L[(t+(g<<3)|0)+6064>>3];k=k+1|0;if((y|0)!=(k|0)){continue}break}}if(l-1>>>0<3){break e}while(1){y=t+6064|0;k=y+(g<<3)|0;b=i*(i*(i*(i*b+L[k-8>>3])+L[k-16>>3])+L[k-24>>3]);k=g-4|0;b=b+L[y+(k<<3)>>3];y=(g|0)>4;g=k;if(y){continue}break}}L[v>>3]=b;g=l+1|0;if((l|0)!=(q|0)){continue}break}b=L[s>>3];if((q|0)<=0){c=b;break d}l=q-1|0;g=q+1|0;t=q&3;f:{if(!t){c=b;break f}k=0;c=b;while(1){c=m*c+L[s+(g-q<<3)>>3];q=q-1|0;k=k+1|0;if((t|0)!=(k|0)){continue}break}}if(l>>>0<3){break d}while(1){l=s+(g-q<<3)|0;c=m*(m*(m*(m*c+L[l>>3])+L[l+8>>3])+L[l+16>>3]);l=q-3|0;c=c+L[s+(g-l<<3)>>3];q=q-4|0;if(l>>>0>1){continue}break}}L[j+24>>3]=c;g=0;g:{if((o|0)<0){break g}while(1){q=M(o-g|0,80)+a|0;l=g<<3;b=L[(q+l|0)+6872>>3];t=l+s|0;l=g;h:{if(!g){break h}k=0;v=l&3;if(v){while(1){g=g-1|0;b=i*b+L[(q+(g<<3)|0)+6872>>3];k=k+1|0;if((v|0)!=(k|0)){continue}break}}if(l-1>>>0<3){break h}while(1){v=q+6872|0;k=v+(g<<3)|0;b=i*(i*(i*(i*b+L[k-8>>3])+L[k-16>>3])+L[k-24>>3]);k=g-4|0;b=b+L[v+(k<<3)>>3];v=(g|0)>4;g=k;if(v){continue}break}}L[t>>3]=b;g=l+1|0;if((l|0)!=(o|0)){continue}break}b=L[s>>3];if((o|0)<=0){break g}l=o-1|0;g=o+1|0;q=o&3;if(q){k=0;while(1){b=m*b+L[s+(g-o<<3)>>3];o=o-1|0;k=k+1|0;if((q|0)!=(k|0)){continue}break}}if(l>>>0<3){break g}while(1){l=s+(g-o<<3)|0;b=m*(m*(m*(m*b+L[l>>3])+L[l+8>>3])+L[l+16>>3]);l=o-3|0;b=b+L[s+(g-l<<3)>>3];o=o-4|0;if(l>>>0>1){continue}break}}L[j+16>>3]=b;L[j+24>>3]=L[j+24>>3]+f;L[j+16>>3]=L[j+16>>3]+h;break c}L[j+24>>3]=f;L[j+16>>3]=h}}i:{j:{k:{l:{m:{n:{o:{p:{q:{r:{s:{t:{g=G[a+3260>>2];switch(g-31|0){case 3:break q;case 2:break r;case 1:break s;case 0:break t;default:break p}}if(!Zg(L[j+24>>3],L[j+16>>3],a,j+8|0,j)){break o}break n}if(!rg(L[j+24>>3],L[j+16>>3],a,j+8|0,j)){break o}break n}h=L[j+24>>3]-L[a+616>>3];f=L[j+16>>3]-L[a+624>>3];u:{v:{if(G[a+3300>>2]){b=h*L[a+72>>3]+f*L[a+80>>3];c=h*L[a+56>>3]+f*L[a- -64>>3];break v}b=0;g=2;i=L[a+760>>3];if(i==0){c=0;break u}c=0;m=L[a+768>>3];if(m==0){break u}f=f*m;c=h*i;b=L[a+48>>3];if(b==0){b=f;break v}b=b*3.141592653589793/180;h=eb(b);i=ib(b);b=c*i+f*h;c=c*h-i*f}n=L[a+3176>>3];g=G[a+6040>>2];l=G[a+3304>>2];h=(90-L[((!l<<3)+a|0)+688>>3])*3.141592653589793/180;p=ib(h);u=eb(h);f=c;if(g){f=c+Ee(g,c,b)}g=G[a+6044>>2];if(g){b=b+Ee(g,c,b)}c=0;i=V(f*f+b*b);if(i!=0){c=Db(f,-b)}i=Db(L[a+3192>>3],i);m=eb(i);n=c-n*3.141592653589793/180;f=eb(n);w=ib(i);b=ib(n);g=(l|0)!=0;r=u*m;c=w*p-f*r;if(O(c)<1e-5){c=r*(1-f)-eb(h+i)}r=b*-m;w:{if(!(c==0&r==0)){b=Db(r,c);break w}b=n+3.141592653589793}x=L[((g<<3)+a|0)+688>>3];b=x+b*180/3.141592653589793;x:{if(x>=0){if(!(b<0)){break x}b=b+360;break x}if(!(b>0)){break x}b=b+-360}y:{if(b>360){b=b+-360;break y}if(!(b<-360)){break y}b=b+360}if(Yc(n,3.141592653589793)==0){g=0;c=(f*h+i)*180/3.141592653589793;c=c>90?180-c:c;if(!(c<-90)){break u}c=-180-c;break u}f=w*u+f*(p*m);z:{if(O(f)>.99){h=Sc(V(c*c+r*r));c=h*180/3.141592653589793;if(f>=0){break z}c=h*-180/3.141592653589793;break z}c=fc(f)*180/3.141592653589793}g=0}L[j+8>>3]=b;L[j>>3]=c;if(!g){break o}break n}f=0;k=0;b=L[j+24>>3]-L[a+616>>3];h=L[j+16>>3]-L[a+624>>3];A:{B:{if(G[a+3300>>2]){i=b*L[a+72>>3]+h*L[a+80>>3];b=b*L[a+56>>3]+h*L[a- -64>>3];break B}c=0;g=2;i=L[a+760>>3];if(i==0){break A}m=L[a+768>>3];if(m==0){break A}c=h*m;b=b*i;f=L[a+48>>3];if(f==0){i=c;break B}h=f*3.141592653589793/180;f=eb(h);h=ib(h);i=b*h+c*f;b=b*f-h*c}A=L[a+3176>>3];g=G[a+6040>>2];l=G[a+3276>>2];s=G[a+3304>>2];u=(90-L[((!s<<3)+a|0)+688>>3])*3.141592653589793/180;w=ib(u);x=eb(u);m=b;if(g){m=b+Ee(g,b,i)}g=G[a+6044>>2];if(g){i=i+Ee(g,b,i)}g=1;c=0;if((l|0)<=0){f=0;break A}p=V(m*m+i*i)/L[a+3192>>3];C:{D:{switch(l-1|0){case 0:b=(p-L[a+4176>>3])/L[a+4184>>3];break C;case 1:f=L[a+4184>>3];h=L[a+4192>>3];n=f*f+h*-4*(L[a+4176>>3]-p);if(n<0){f=0;break A}b=0;n=V(n);h=h+h;c=(n-f)/h;f=(-f-n)/h;h=cf?c:f:h;if(h<0){c=0;f=0;if(!(h<-1e-13)){break C}break A}b=3.141592653589793;if(!(h>3.141592653589793)){b=h;break C}c=0;f=0;if(!(h>3.141592653589893)){break C}break A;default:break D}}n=L[a+4176>>3];if(p>3];h=L[a+3248>>3];if(!(p>h)){q=l+1&3;f=b;while(1){b=.1;c=(h-p)/(h-n);E:{if(c<.1){break E}b=c;if(!(b>.9)){break E}b=.9}b=f-b*(f-r);o=0;c=0;g=l;if(q){while(1){c=c*b+L[((g<<3)+a|0)+4176>>3];g=g-1|0;o=o+1|0;if((q|0)!=(o|0)){continue}break}}if(l>>>0>=3){while(1){o=(g<<3)+a|0;c=(((c*b+L[o+4176>>3])*b+L[o+4168>>3])*b+L[o+4160>>3])*b+L[o+4152>>3];o=(g|0)>3;g=g-4|0;if(o){continue}break}}F:{if(!(c>>0<99;h=c;k=k+1|0;if(g){continue}break}break C}f=0;if(p>h+1e-13){break A}}c=0;if(p!=0){c=Db(m,-i)}h=1.5707963267948966-b;i=eb(h);m=c-A*3.141592653589793/180;b=eb(m);r=ib(h);c=ib(m);g=(s|0)!=0;n=x*i;f=r*w-b*n;if(O(f)<1e-5){f=n*(1-b)-eb(u+h)}n=c*-i;G:{if(!(f==0&n==0)){c=Db(n,f);break G}c=m+3.141592653589793}p=L[((g<<3)+a|0)+688>>3];c=p+c*180/3.141592653589793;H:{if(p>=0){if(!(c<0)){break H}c=c+360;break H}if(!(c>0)){break H}c=c+-360}I:{if(c>360){c=c+-360;break I}if(!(c<-360)){break I}c=c+360}if(Yc(m,3.141592653589793)==0){g=0;b=(b*u+h)*180/3.141592653589793;f=b>90?180-b:b;if(!(f<-90)){break A}f=-180-f;break A}b=r*x+w*i*b;J:{if(O(b)>.99){h=Sc(V(f*f+n*n));f=h*180/3.141592653589793;if(b>=0){break J}f=h*-180/3.141592653589793;break J}f=fc(b)*180/3.141592653589793}g=0}L[j+8>>3]=c;L[j>>3]=f;if(!g){break o}break n}b=L[j+16>>3];f=L[j+24>>3];if(!(G[a+3324>>2]!=2&(g|0)>0)){c=b-L[a+24>>3];f=f-L[a+16>>3];w=L[a+40>>3];x=L[a+32>>3];u=L[a+8>>3];h=L[a>>3];k=G[a+3260>>2];g=G[a+3300>>2];i=L[a+48>>3]*3.141592653589793/180;A=ib(i);B=eb(i);K:{L:{M:{if(g){b=f*L[a+72>>3]+c*L[a+80>>3];f=f*L[a+56>>3]+c*L[a- -64>>3];break M}b=0;if(!(x!=0&w!=0)){G[j+8>>2]=0;G[j+12>>2]=0;g=2;break L}c=c*w;f=f*x;if(i==0){b=c;break M}b=f*A+c*B;f=f*B-A*c}l=G[a+3304>>2];i=l?b:f;L[j+8>>3]=h+i;b=l?f:b;L[j>>3]=u+b;g=0;if((k|0)<=0){break K}c=(l?u:h)*3.141592653589793/180;n=i*3.141592653589793/180;D=n*n;i=b*3.141592653589793/180;p=D+i*i;h=(l?h:u)*3.141592653589793/180;m=ib(h);r=eb(h);f=0;b=0;N:{O:{switch(k-3|0){case 8:f=h+i;b=c+n;break N;case 1:g=1;if(p>1){break K}f=V(1-p);b=m*f+i*r;if(b>1|b<-1){break K}h=r*f-i*m;if(h==0&n==0){break K}f=fc(b);b=c+Db(n,h);break N;case 0:case 30:case 31:case 32:g=1;if(p>1){break K}f=r-i*m;if(f==0){break K}b=c+Db(n,f);f=Pd((i*r+m)*eb(b-c)/f);break N;case 3:g=1;if(p>=9.869604401089369){break K}f=V(p);h=eb(f);b=1;if(f!=0){b=ib(f)/f}f=i*r*b+m*h;if(f>1|f<-1){break K}h=h-f*m;b=r*(n*b);if(h==0&b==0){break K}f=fc(f);b=c+Db(b,h);break N;case 26:g=1;f=r-i*m;if(f==0){break K}b=c+Db(n,f);i=eb(b-c);if(i==0){break K}f=f/i;if(f>1|f<-1){break K}f=Sc(f);if(!(h<0)){break N}f=-f;break N;case 17:case 27:g=1;f=h+i;if(O(f)>1.5707963267948974){break K}b=eb(f);if(O(n)>b*6.28318530717959*.5){break K}if(!(b>1e-5)){b=c;break N}b=c+n/b;break N;case 9:b=(u*.5+45)*3.141592653589793/180;f=Mc(b);h=w*B+x*A;h=h==0?1:h;m=oc(Mc(h*.5*.01745329252+b));f=oc(f);g=1;b=eb(u*3.141592653589793/180);b=c+n/(b<=0?1:b);if(O(b-c)>6.28318530717959){break K}h=h*3.141592653589793/180/(m-f);if(h!=0){f=(i+f*h)/h}else{f=0}f=Pd(af(f));f=f+f+-1.5707963267948974;break N;case 19:b=u*3.141592653589793/180;m=eb(b);f=x*B-A*w;p=f==0?.017453292519943295:f*3.141592653589793/180;f=p*.5;u=ib(f);I=eb(f);f=w*B+x*A;w=f==0?.017453292519943295:f*3.141592653589793/180;f=b+w;x=eb(f);A=ib(f);r=ib(b);if(n==0){f=h;b=c;if(i==0){break N}}g=1;b=(m+m)*u;b=p*V((m*I+1)*.5)/(b==0?1:b);h=V((m+1)*.5);f=A/V((x+1)*.5)-r/h;f=w/(f==0?1:f);i=r*f/h+i;h=i/f;h=4-D/(b*(b*4))-h*h;if(h>4|h<2){break K}h=V(h)*.5;f=i*h/f;if(O(f)>1){break K}f=fc(f);i=eb(f);if(O(i)<1e-5){break K}b=n*h/((b+b)*i);if(O(b)>1){break K}b=fc(b);b=b+b+c;break N;case 2:g=1;b=(4-p)/(p+4);if(O(b)>1){break K}h=b+1;b=b*m+i*r*h*.5;if(O(b)>1){break K}f=fc(b);b=eb(f);if(O(b)<1e-5){break K}n=n*h/(b+b);if(O(n)>1){break K}h=ib(f);n=fc(n);p=eb(n);u=r*b*p+(h*m+1);if(O(u)<1e-5){break K}b=h*r-m*b*p;b=c+(O((b+b)/u-i)>1e-5?3.141592653589795-n:n);break N;case 13:break O;default:break N}}f=1/Mc(h)-i;b=c-Db(n,h<0?-f:f)/m;f=fc(1/(m+m)*(m*m*(1-(D+f*f))+1))}b=b-c>3.141592653589795?b+-6.28318530717959:b;b=b-c<-3.141592653589795?b+6.28318530717959:b;L[j+8>>3]=(b<0?b+6.28318530717959:b)*180/3.141592653589793;b=f*180/3.141592653589793;g=0}L[j>>3]=b}if(!g){break o}break n}G[j+96>>2]=0;G[j+100>>2]=0;G[j+104>>2]=0;G[j+108>>2]=0;G[j+8>>2]=0;G[j+12>>2]=0;G[j>>2]=0;G[j+4>>2]=0;G[j+80>>2]=0;G[j+84>>2]=0;G[j+88>>2]=0;G[j+92>>2]=0;L[j+56>>3]=b;L[j+48>>3]=f;G[j+72>>2]=0;G[j+76>>2]=1072693248;L[j+64>>3]=g-24>>>0<3?+(G[321354]+1|0):L[160676];q=a+3368|0;C=j+48|0;k=a+4036|0;t=j+80|0;l=a+4144|0;F=j+40|0;H=j+32|0;y=a+688|0;s=a+4064|0;v=j+112|0;o=a+4004|0;P:{if(G[o>>2]!=137){g=1;if(sj(G[k+4>>2],q,o)){break P}}g=4;if(Yh(C,k,t)){break P}k=G[k+4>>2];Q:{if((k|0)<=0){break Q}C=G[o+20>>2];g=0;if((k|0)!=1){J=k&-2;q=0;while(1){if(!((g|0)==(C|0)|G[o+24>>2]==(g|0))){z=g<<3;L[z+v>>3]=L[t+z>>3]+L[y+z>>3]}z=g|1;if(!((z|0)==(C|0)|(z|0)==G[o+24>>2])){z=z<<3;L[z+v>>3]=L[t+z>>3]+L[y+z>>3]}g=g+2|0;q=q+2|0;if((J|0)!=(q|0)){continue}break}}if(!(k&1)|(g|0)==(C|0)|G[o+24>>2]==(g|0)){break Q}g=g<<3;L[g+v>>3]=L[g+t>>3]+L[g+y>>3]}if(G[o>>2]!=999){k=G[o+28>>2];R:{if((k|0)==-1){break R}g=3;b=L[(k<<3)+t>>3];c=b+.5;S:{if(O(c)<2147483648){k=~~c;break S}k=-2147483648}if(O(b-+(k|0))>1e-10){break P}b=L[l+24>>3];b=b==0?90:b*3.141592653589793*.5;T:{switch(k|0){case 0:g=(G[o+24>>2]<<3)+t|0;L[g>>3]=b+L[g>>3];break R;case 2:g=(G[o+20>>2]<<3)+t|0;L[g>>3]=b+L[g>>3];break R;case 3:g=(G[o+20>>2]<<3)+t|0;L[g>>3]=b+b+L[g>>3];break R;case 4:g=(G[o+20>>2]<<3)+t|0;L[g>>3]=b*3+L[g>>3];break R;case 1:break R;case 5:break T;default:break P}}g=(G[o+24>>2]<<3)+t|0;L[g>>3]=L[g>>3]-b}k=o+4|0;if(!Xa(k,34233)){g=2;if(L[s+16>>3]==0){break P}E[k|0]=83;E[k+1|0]=73;E[k+2|0]=78;E[k+3|0]=0;G[l+40>>2]=0;G[l+44>>2]=0;K=l,N=Mb(L[s+16>>3])/Kb(L[s+16>>3]),L[K+48>>3]=N;G[l+4>>2]=G[l+4>>2]>>31}q=k;g=G[o+20>>2]<<3;b=L[g+t>>3];k=G[o+24>>2]<<3;c=L[k+t>>3];g=g+v|0;k=k+v|0;U:{V:{if(G[s>>2]!=137){o=1;if(um(q,s,l)){break V}}l=Ja[G[l+1892>>2]](b,c,l,F,H)|0;if(l){g=(l|0)==1?2:3;break U}b=L[F>>3];m=L[H>>3];f=Mb(m);p=Kb(m);n=b-L[s+56>>3];h=Mb(n);b=Kb(n);i=p*L[s+72>>3]-h*(f*L[s+64>>3]);if(O(i)<1e-5){c=Mb(L[s+48>>3]+m);i=f*L[s+64>>3]*(1-h)-c}r=b*-f;W:{if(!(i==0&r==0)){b=Ac(r,i);break W}b=n+180}b=b+L[s+40>>3];L[g>>3]=b;X:{Y:{if(L[s+40>>3]>=0){c=360;if(b<0){break Y}break X}c=-360;if(!(b>0)){break X}}b=b+c;L[g>>3]=b}c=-360;Z:{if(!(b>360)){c=360;if(!(b<-360)){break Z}}L[g>>3]=b+c}_:{$:{if(Yc(n,180)==0){b=h*L[s+48>>3]+m;b=b>90?180-b:b;L[k>>3]=b;if(!(b<-90)){break _}b=-180-b;break $}c=p*L[s+64>>3]+h*(f*L[s+72>>3]);if(O(c)>.99){b=Yg(V(i*i+r*r));if(!(c<0)){break $}b=-b;break $}b=Bc(c)}L[k>>3]=b}o=0}g=o}if(g){break P}}g=0}if(g){break n}g=j+112|0;L[j+8>>3]=L[g+(G[a+4024>>2]<<3)>>3];L[j>>3]=L[g+(G[a+4028>>2]<<3)>>3]}b=0;c=0;if(G[a+3308>>2]){break i}if(G[a+3260>>2]>0){Bm(G[a+3964>>2],G[a+3968>>2],L[a+120>>3],L[a+3952>>3],j+8|0,j,L[a+128>>3])}g=G[a+3264>>2];if((g|0)==-90){break l}if((g|0)==90){break m}c=L[j>>3];break j}G[a+3308>>2]=1;b=0;c=0;break i}c=90-L[j>>3];break k}c=L[j>>3]+-90}L[j>>3]=c}b=L[j+8>>3];L[a+608>>3]=c;L[a+600>>3]=b}L[d>>3]=b;L[e>>3]=c;a=G[a+3968>>2];if((a|0)<=0){break a}aa:{switch(a-6|0){case 0:case 4:break a;default:break aa}}c=360;b=L[d>>3];if(!(b<0)){c=-360;if(!(b>360)){break a}}L[d>>3]=b+c}Fa=j+144|0}function Wh(){var a=0,b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;a=Fa-34160|0;Fa=a;lm(G[321986]);b=G[321991];j=L[b+136>>3];l=(j+1)*.5;k=L[b+144>>3];i=(k+1)*.5;cc(b,l,i,a+1032|0,a+1024|0);E[a+1296|0]=0;b=H[33554]|H[33555]<<8|(H[33556]<<16|H[33557]<<24);G[a+1040>>2]=H[33550]|H[33551]<<8|(H[33552]<<16|H[33553]<<24);G[a+1044>>2]=b;G[a+1048>>2]=H[33558]|H[33559]<<8|(H[33560]<<16|H[33561]<<24);h=Va(a+1296|0);e=Va(a+1040|0);if(O(k)<2147483648){c=~~k}else{c=-2147483648}g=(e|0)<=0;if(O(j)<2147483648){b=~~j}else{b=-2147483648}a:{if(!g){bb(h+(a+1296|0)|0,a+1040|0,e);if(e>>>0>79){break a}}cb(a+1296+(e+h)|0,32,80-e|0)}E[(a+h|0)+1376|0]=0;h=a+1040|0;G[a+1008>>2]=h;_a(G[321986],70017,a+1008|0);e=H[40391]|H[40392]<<8|(H[40393]<<16|H[40394]<<24);g=H[40387]|H[40388]<<8|(H[40389]<<16|H[40390]<<24);F[a+1046>>1]=g;F[a+1048>>1]=g>>>16;F[a+1050>>1]=e;F[a+1052>>1]=e>>>16;g=H[40385]|H[40386]<<8|(H[40387]<<16|H[40388]<<24);G[a+1040>>2]=H[40381]|H[40382]<<8|(H[40383]<<16|H[40384]<<24);G[a+1044>>2]=g;g=Va(a+1296|0);h=Va(h);b:{if((h|0)>0){bb(g+(a+1296|0)|0,a+1040|0,h);if(h>>>0>79){break b}}cb(a+1296+(g+h)|0,32,80-h|0)}E[(a+g|0)+1376|0]=0;h=a+1040|0;G[a+992>>2]=h;_a(G[321986],70017,a+992|0);G[a+1048>>2]=H[40971]|H[40972]<<8|(H[40973]<<16|H[40974]<<24);g=H[40967]|H[40968]<<8|(H[40969]<<16|H[40970]<<24);G[a+1040>>2]=H[40963]|H[40964]<<8|(H[40965]<<16|H[40966]<<24);G[a+1044>>2]=g;g=Va(a+1296|0);h=Va(h);c:{if((h|0)>0){bb(g+(a+1296|0)|0,a+1040|0,h);if(h>>>0>79){break c}}cb(a+1296+(g+h)|0,32,80-h|0)}E[(a+g|0)+1376|0]=0;g=a+1040|0;G[a+976>>2]=g;_a(G[321986],70017,a+976|0);G[a+960>>2]=b;db(g,30391,a+960|0);b=Va(a+1296|0);g=Va(g);d:{if((g|0)>0){bb(b+(a+1296|0)|0,a+1040|0,g);if(g>>>0>79){break d}}cb(a+1296+(b+g)|0,32,80-g|0)}E[(a+b|0)+1376|0]=0;b=a+1040|0;G[a+944>>2]=b;_a(G[321986],70017,a+944|0);G[a+928>>2]=c;db(b,30378,a+928|0);c=Va(a+1296|0);b=Va(b);e:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break e}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;G[a+912>>2]=a+1040;_a(G[321986],70017,a+912|0);b=G[321991]+3512|0;f:{g:{if(!fb(b,35967,2)){E[a+1064|0]=H[65167];b=H[65163]|H[65164]<<8|(H[65165]<<16|H[65166]<<24);c=a+1056|0;G[c>>2]=H[65159]|H[65160]<<8|(H[65161]<<16|H[65162]<<24);G[c+4>>2]=b;b=H[65155]|H[65156]<<8|(H[65157]<<16|H[65158]<<24);G[a+1048>>2]=H[65151]|H[65152]<<8|(H[65153]<<16|H[65154]<<24);G[a+1052>>2]=b;b=H[65147]|H[65148]<<8|(H[65149]<<16|H[65150]<<24);G[a+1040>>2]=H[65143]|H[65144]<<8|(H[65145]<<16|H[65146]<<24);G[a+1044>>2]=b;b=Va(a+1296|0);c=Va(a+1040|0);h:{if((c|0)>0){bb(b+(a+1296|0)|0,a+1040|0,c);if(c>>>0>79){break h}}cb(a+1296+(b+c)|0,32,80-c|0)}E[(a+b|0)+1376|0]=0;g=a+1040|0;G[a+848>>2]=g;_a(G[321986],70017,a+848|0);E[a+1064|0]=H[65142];b=H[65138]|H[65139]<<8|(H[65140]<<16|H[65141]<<24);c=a+1056|0;G[c>>2]=H[65134]|H[65135]<<8|(H[65136]<<16|H[65137]<<24);G[c+4>>2]=b;b=H[65130]|H[65131]<<8|(H[65132]<<16|H[65133]<<24);G[a+1048>>2]=H[65126]|H[65127]<<8|(H[65128]<<16|H[65129]<<24);G[a+1052>>2]=b;b=H[65122]|H[65123]<<8|(H[65124]<<16|H[65125]<<24);G[a+1040>>2]=H[65118]|H[65119]<<8|(H[65120]<<16|H[65121]<<24);G[a+1044>>2]=b;f=Va(a+1296|0);d=Va(g);if((d|0)<=0){break g}bb((a+1296|0)+f|0,a+1040|0,d);if(d>>>0<=79){break g}break f}G[a+896>>2]=b;b=a+1040|0;db(b,65095,a+896|0);c=Va(a+1296|0);b=Va(b);i:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break i}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=a+1040|0;G[a+880>>2]=b;_a(G[321986],70017,a+880|0);G[a+864>>2]=G[321991]+3528;db(b,65072,a+864|0);f=Va(a+1296|0);d=Va(b);if((d|0)<=0){break g}bb((a+1296|0)+f|0,a+1040|0,d);if(d>>>0>79){break f}}cb(a+1296+(d+f)|0,32,80-d|0)}E[(a+f|0)+1376|0]=0;b=a+1040|0;G[a+832>>2]=b;_a(G[321986],70017,a+832|0);L[a+816>>3]=L[a+1032>>3];Eb(b,19350,a+816|0);c=Va(a+1296|0);b=Va(b);j:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break j}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=a+1040|0;G[a+800>>2]=b;_a(G[321986],70017,a+800|0);L[a+784>>3]=L[a+1024>>3];Eb(b,19314,a+784|0);c=Va(a+1296|0);b=Va(b);k:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break k}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=a+1040|0;G[a+768>>2]=b;_a(G[321986],70017,a+768|0);L[a+752>>3]=l;Eb(b,19332,a+752|0);c=Va(a+1296|0);b=Va(b);l:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break l}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=a+1040|0;G[a+736>>2]=b;_a(G[321986],70017,a+736|0);L[a+720>>3]=i;Eb(b,19296,a+720|0);c=Va(a+1296|0);b=Va(b);m:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break m}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;G[a+704>>2]=a+1040;_a(G[321986],70017,a+704|0);if(G[321992]){L[a+688>>3]=L[161030];b=a+1040|0;Eb(b,19384,a+688|0);c=Va(a+1296|0);b=Va(b);n:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break n}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=G[321986];G[a+672>>2]=a+1040;_a(b,70017,a+672|0)}if(G[322016]){L[a+656>>3]=L[161031];b=a+1040|0;Eb(b,19368,a+656|0);c=Va(a+1296|0);b=Va(b);o:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break o}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=G[321986];G[a+640>>2]=a+1040;_a(b,70017,a+640|0)}if(G[322070]){G[a+624>>2]=1288160;b=a+1040|0;db(b,9321,a+624|0);c=Va(a+1296|0);b=Va(b);p:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break p}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=G[321986];G[a+608>>2]=a+1040;_a(b,70017,a+608|0)}if(G[322071]){G[a+592>>2]=1288336;b=a+1040|0;db(b,9425,a+592|0);c=Va(a+1296|0);b=Va(b);q:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break q}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=G[321986];G[a+576>>2]=a+1040;_a(b,70017,a+576|0)}if(G[322072]){G[a+560>>2]=1288416;b=a+1040|0;db(b,9373,a+560|0);c=Va(a+1296|0);b=Va(b);r:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break r}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=G[321986];G[a+544>>2]=a+1040;_a(b,70017,a+544|0)}if(G[322073]){G[a+528>>2]=1288496;b=a+1040|0;db(b,9399,a+528|0);c=Va(a+1296|0);b=Va(b);s:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break s}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=G[321986];G[a+512>>2]=a+1040;_a(b,70017,a+512|0)}if(G[322074]){G[a+496>>2]=1288576;b=a+1040|0;db(b,9347,a+496|0);c=Va(a+1296|0);b=Va(b);t:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break t}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=G[321986];G[a+480>>2]=a+1040;_a(b,70017,a+480|0)}if(G[322075]){G[a+464>>2]=1288656;b=a+1040|0;db(b,9438,a+464|0);c=Va(a+1296|0);b=Va(b);u:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break u}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=G[321986];G[a+448>>2]=a+1040;_a(b,70017,a+448|0)}if(G[322076]){G[a+432>>2]=1288736;b=a+1040|0;db(b,9386,a+432|0);c=Va(a+1296|0);b=Va(b);v:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break v}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=G[321986];G[a+416>>2]=a+1040;_a(b,70017,a+416|0)}if(G[322077]){G[a+400>>2]=1288816;b=a+1040|0;db(b,9412,a+400|0);c=Va(a+1296|0);b=Va(b);w:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break w}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=G[321986];G[a+384>>2]=a+1040;_a(b,70017,a+384|0)}if(G[322078]){G[a+368>>2]=1288896;b=a+1040|0;db(b,9360,a+368|0);c=Va(a+1296|0);b=Va(b);x:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break x}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=G[321986];G[a+352>>2]=a+1040;_a(b,70017,a+352|0)}if(G[322079]){G[a+336>>2]=1288976;b=a+1040|0;db(b,9334,a+336|0);c=Va(a+1296|0);b=Va(b);y:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break y}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=G[321986];G[a+320>>2]=a+1040;_a(b,70017,a+320|0)}if(G[322080]){G[a+304>>2]=1289056;b=a+1040|0;db(b,9308,a+304|0);c=Va(a+1296|0);b=Va(b);z:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break z}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;b=G[321986];G[a+288>>2]=a+1040;_a(b,70017,a+288|0)}G[a+272>>2]=G[321985]-1;b=a+1040|0;db(b,30365,a+272|0);c=Va(a+1296|0);b=Va(b);A:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break A}}cb(a+1296+(b+c)|0,32,80-b|0)}e=0;E[(a+c|0)+1376|0]=0;G[a+256>>2]=a+1040;_a(G[321986],70017,a+256|0);f=G[321985];if((f|0)>0){while(1){d=0;if((f|0)>0){while(1){i=L[G[G[321987]+(e<<2)>>2]+(d<<3)>>3];G[a+240>>2]=e;G[a+244>>2]=d;L[a+248>>3]=i;b=a+1040|0;Eb(b,25553,a+240|0);c=Va(a+1296|0);b=Va(b);B:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break B}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;G[a+224>>2]=a+1040;_a(G[321986],70017,a+224|0);d=d+1|0;f=G[321985];if((d|0)<(f|0)){continue}break}}e=e+1|0;if((e|0)<(f|0)){continue}break}}G[a+208>>2]=f-1;b=a+1040|0;db(b,30352,a+208|0);c=Va(a+1296|0);b=Va(b);C:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break C}}cb(a+1296+(b+c)|0,32,80-b|0)}e=0;E[(a+c|0)+1376|0]=0;G[a+192>>2]=a+1040;_a(G[321986],70017,a+192|0);f=G[321985];if((f|0)>0){while(1){d=0;if((f|0)>0){while(1){i=L[G[G[321989]+(e<<2)>>2]+(d<<3)>>3];G[a+176>>2]=e;G[a+180>>2]=d;L[a+184>>3]=i;b=a+1040|0;Eb(b,25534,a+176|0);c=Va(a+1296|0);b=Va(b);D:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break D}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;G[a+160>>2]=a+1040;_a(G[321986],70017,a+160|0);d=d+1|0;f=G[321985];if((d|0)<(f|0)){continue}break}}e=e+1|0;if((e|0)<(f|0)){continue}break}}G[a+144>>2]=f-1;b=a+1040|0;db(b,30263,a+144|0);c=Va(a+1296|0);b=Va(b);E:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break E}}cb(a+1296+(b+c)|0,32,80-b|0)}e=0;E[(a+c|0)+1376|0]=0;G[a+128>>2]=a+1040;_a(G[321986],70017,a+128|0);f=G[321985];if((f|0)>0){while(1){d=0;if((f|0)>0){while(1){i=L[G[G[321988]+(e<<2)>>2]+(d<<3)>>3];G[a+112>>2]=e;G[a+116>>2]=d;L[a+120>>3]=i;b=a+1040|0;Eb(b,25515,a+112|0);c=Va(a+1296|0);b=Va(b);F:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break F}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;G[a+96>>2]=a+1040;_a(G[321986],70017,a+96|0);d=d+1|0;f=G[321985];if((d|0)<(f|0)){continue}break}}e=e+1|0;if((e|0)<(f|0)){continue}break}}G[a+80>>2]=f-1;b=a+1040|0;db(b,30250,a+80|0);c=Va(a+1296|0);b=Va(b);G:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break G}}cb(a+1296+(b+c)|0,32,80-b|0)}e=0;E[(a+c|0)+1376|0]=0;G[a+64>>2]=a+1040;_a(G[321986],70017,a- -64|0);f=G[321985];if((f|0)>0){while(1){d=0;if((f|0)>0){while(1){i=L[G[G[321990]+(e<<2)>>2]+(d<<3)>>3];G[a+48>>2]=e;G[a+52>>2]=d;L[a+56>>3]=i;b=a+1040|0;Eb(b,25496,a+48|0);c=Va(a+1296|0);b=Va(b);H:{if((b|0)>0){bb(c+(a+1296|0)|0,a+1040|0,b);if(b>>>0>79){break H}}cb(a+1296+(b+c)|0,32,80-b|0)}E[(a+c|0)+1376|0]=0;G[a+32>>2]=a+1040;_a(G[321986],70017,a+32|0);d=d+1|0;f=G[321985];if((d|0)<(f|0)){continue}break}}e=e+1|0;if((e|0)<(f|0)){continue}break}}G[a+1040>>2]=4476485;b=Va(a+1296|0);c=Va(a+1040|0);I:{if((c|0)>0){bb(b+(a+1296|0)|0,a+1040|0,c);if(c>>>0>79){break I}}cb(a+1296+(b+c)|0,32,80-c|0)}E[(a+b|0)+1376|0]=0;G[a+16>>2]=a+1040;_a(G[321986],70017,a+16|0);if(H[1287936]){yb(86205);h=Va(a+1296|0);f=0;while(1){d=0;cb(a+34064|0,0,80);g=M(f,80);while(1){J:{b=d+g|0;e=(b|0)>(h|0);if(e){break J}E[(a+34064|0)+d|0]=H[b+(a+1296|0)|0];c=d|1;b=c+g|0;e=(h|0)<(b|0);if(e){break J}E[c+(a+34064|0)|0]=H[(a+1296|0)+b|0];d=d+2|0;if((d|0)!=80){continue}}break}E[a+34144|0]=0;d=80;while(1){K:{b=(a+34064|0)+d|0;if((H[b|0]|32)!=32){break K}E[b|0]=0;b=(a+d|0)+34063|0;if((H[b|0]|32)!=32){break K}E[b|0]=0;c=d-2|0;b=c+(a+34064|0)|0;if((H[b|0]|32)!=32){break K}E[b|0]=0;d=d-3|0;if(c){continue}}break}f=f+1|0;if(H[a+34064|0]){G[a>>2]=f;G[a+4>>2]=a+34064;kb(69623,a)}if(!e){continue}break}id();$a(G[29763])}b=rd(a+1296|0);G[322064]=b;if(b){if(H[1287936]){yb(73585);$a(G[29763])}$a(G[321986]);Fa=a+34160|0;return}hb(84378,54,1,G[321435]);$a(G[321435]);Hb(G[321435]);sc(1);W()}function um(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;o=1;a:{b:{if(!Xa(a,34161)){yj(c);break b}if(!Xa(a,34157)){xj(c);break b}if(!Xa(a,34606)){E[c|0]=84;E[c+1|0]=65;E[c+2|0]=78;E[c+3|0]=0;G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;G[c+4>>2]=G[c+4>>2]<0?-103:103;if(L[c+24>>3]==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020}G[c+1892>>2]=85;G[c+1888>>2]=86;a=99;c:{while(1){l=(a<<3)+c|0;if(L[l+280>>3]!=0|L[l+1080>>3]!=0){break c}j=a-1|0;if(L[((j<<3)+c|0)+280>>3]!=0){a=j;break c}if(L[l+1072>>3]!=0){a=j;break c}a=a-2|0;if(j){continue}break}a=-1}G[c+276>>2]=(a|0)>0?a:0;j=0;break a}if(!Xa(a,35072)){G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=83;E[c+1|0]=84;E[c+2|0]=71;E[c+3|0]=0;E[c+4|0]=104;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;d=L[c+24>>3];d:{if(d==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;e=114.59155902616465;d=.008726646259971648;break d}e=d+d;d=1/e}G[c+1892>>2]=87;G[c+1888>>2]=88;L[c+112>>3]=e;L[c+120>>3]=d;break b}if(!Xa(a,34543)){E[c|0]=83;E[c+1|0]=73;E[c+2|0]=78;E[c+3|0]=0;G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;G[c+4>>2]=G[c+4>>2]<0?-105:105;e=L[c+24>>3];if(e==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;e=57.29577951308232}G[c+1892>>2]=89;G[c+1888>>2]=90;L[c+112>>3]=1/e;d=L[c+40>>3];e=d*d;d=L[c+48>>3];d=e+d*d;L[c+120>>3]=d;L[c+136>>3]=d+-1;L[c+128>>3]=d+1;j=0;break a}if(!Xa(a,35873)){G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=65;E[c+1|0]=82;E[c+2|0]=67;E[c+3|0]=0;E[c+4|0]=106;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;d=L[c+24>>3];e:{if(d==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;e=1;d=1;break e}e=d*3.141592653589793/180;d=1/e}G[c+1892>>2]=91;G[c+1888>>2]=92;L[c+112>>3]=e;L[c+120>>3]=d;break b}if(!Xa(a,34418)){wj(c);break b}if(!Xa(a,35981)){G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=90;E[c+1|0]=69;E[c+2|0]=65;E[c+3|0]=0;E[c+4|0]=108;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;d=L[c+24>>3];f:{if(d==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;e=114.59155902616465;d=.008726646259971648;break f}e=d+d;d=1/e}G[c+1892>>2]=93;G[c+1888>>2]=94;L[c+112>>3]=e;L[c+120>>3]=d;break b}if(!Xa(a,33992)){G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=65;E[c+1|0]=73;E[c+2|0]=82;E[c+3|0]=0;E[c+4|0]=109;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;e=L[c+24>>3];if(e==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;e=57.29577951308232}g=e+e;L[c+112>>3]=g;d=L[c+40>>3];g:{h:{if(d==90){G[c+128>>2]=0;G[c+132>>2]=1072693248;G[c+120>>2]=0;G[c+124>>2]=-1075838976;e=1;break h}if(!(d>-90)){break g}f=Mb((90-d)*.5);d=f*f;d=oc(f)*d/(1-d);L[c+120>>3]=d;e=.5-d;L[c+128>>3]=e;g=L[c+112>>3]}G[c+1892>>2]=115;G[c+1888>>2]=116;L[c+160>>3]=57.29577951308232/e;L[c+152>>3]=e*1e-4;G[c+144>>2]=-350469331;G[c+148>>2]=1058682594;L[c+136>>3]=e*g}break b}if(!Xa(a,34172)){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=67;E[c+1|0]=89;E[c+2|0]=80;E[c+3|0]=0;E[c+4|0]=201;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;h=L[c+24>>3];i:{j:{if(h==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;d=L[c+48>>3];L[c+112>>3]=d;if(d==0){break i}L[c+120>>3]=1/d;e=(d+L[c+40>>3])*57.29577951308232;L[c+128>>3]=e;if(e!=0){break j}break i}d=L[c+48>>3];f=h*d*3.141592653589793/180;L[c+112>>3]=f;if(f==0){break i}L[c+120>>3]=1/f;e=h*(d+L[c+40>>3]);L[c+128>>3]=e;if(e==0){break i}}G[c+1892>>2]=117;G[c+1888>>2]=118;L[c+136>>3]=1/e}break b}if(!Xa(a,35985)){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=67;E[c+1|0]=69;E[c+2|0]=65;E[c+3|0]=0;E[c+4|0]=202;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];k:{l:{if(f==0){G[c+112>>2]=0;G[c+116>>2]=1072693248;G[c+24>>2]=442745336;G[c+28>>2]=1078765020;G[c+120>>2]=0;G[c+124>>2]=1072693248;d=L[c+40>>3];if(d<=0|d>1){break k}L[c+128>>3]=57.29577951308232/d;d=d/57.29577951308232;break l}L[c+120>>3]=57.29577951308232/f;L[c+112>>3]=f*3.141592653589793/180;d=L[c+40>>3];if(d<=0|d>1){break k}L[c+128>>3]=f/d;d=d/f}G[c+1892>>2]=119;G[c+1888>>2]=120;L[c+136>>3]=d}break b}if(!Xa(a,34150)){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=67;E[c+1|0]=65;E[c+2|0]=82;E[c+3|0]=0;E[c+4|0]=203;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;d=L[c+24>>3];m:{if(d==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;e=1;d=1;break m}e=d*3.141592653589793/180;d=1/e}G[c+1892>>2]=95;G[c+1888>>2]=96;L[c+112>>3]=e;L[c+120>>3]=d;break b}if(!Xa(a,34035)){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=77;E[c+1|0]=69;E[c+2|0]=82;E[c+3|0]=0;E[c+4|0]=204;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;d=L[c+24>>3];n:{if(d==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;e=1;d=1;break n}e=d*3.141592653589793/180;d=1/e}G[c+1892>>2]=97;G[c+1888>>2]=98;L[c+112>>3]=e;L[c+120>>3]=d;break b}if(!Xa(a,34777)){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=83;E[c+1|0]=70;E[c+2|0]=76;E[c+3|0]=0;E[c+4|0]=45;E[c+5|0]=1;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;d=L[c+24>>3];o:{if(d==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;e=1;d=1;break o}e=d*3.141592653589793/180;d=1/e}G[c+1892>>2]=99;G[c+1888>>2]=100;L[c+112>>3]=e;L[c+120>>3]=d;break b}if(!Xa(a,34138)){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=80;E[c+1|0]=65;E[c+2|0]=82;E[c+3|0]=0;E[c+4|0]=46;E[c+5|0]=1;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;d=L[c+24>>3];p:{if(d==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;g=.005555555555555556;e=180;f=1;d=1;break p}e=d*3.141592653589793;g=1/e;f=e/180;d=1/f}G[c+1892>>2]=121;G[c+1888>>2]=122;L[c+112>>3]=f;L[c+136>>3]=g;L[c+128>>3]=e;L[c+120>>3]=d;break b}if(!Xa(a,34745)){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=77;E[c+1|0]=79;E[c+2|0]=76;E[c+3|0]=0;E[c+4|0]=47;E[c+5|0]=1;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;e=L[c+24>>3];if(e==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;e=57.29577951308232}G[c+1892>>2]=123;G[c+1888>>2]=124;G[c+144>>2]=1841940611;G[c+148>>2]=1071931184;L[c+136>>3]=90/e;d=e*1.4142135623730951;L[c+112>>3]=d;L[c+128>>3]=1/d;L[c+120>>3]=d/90;break b}if(!Xa(a,33400)){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=65;E[c+1|0]=73;E[c+2|0]=84;E[c+3|0]=0;E[c+4|0]=145;E[c+5|0]=1;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;e=L[c+24>>3];if(e==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;e=57.29577951308232}G[c+1892>>2]=125;G[c+1888>>2]=126;d=e+e;L[c+136>>3]=1/d;d=e*d;L[c+112>>3]=d;d=1/(d+d);L[c+120>>3]=d;L[c+128>>3]=d*.25;break b}if(!Xa(a,34213)){E[c|0]=67;E[c+1|0]=79;E[c+2|0]=80;E[c+3|0]=0;G[c+8>>2]=0;G[c+12>>2]=0;d=L[c+40>>3];L[c+16>>3]=d;G[c+4>>2]=G[c+4>>2]<0?-501:501;if(L[c+24>>3]==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020}d=Kb(d);L[c+112>>3]=d;q:{if(d==0){break q}L[c+120>>3]=1/d;d=L[c+24>>3]*Mb(L[c+48>>3]);L[c+136>>3]=d;if(d==0){break q}L[c+144>>3]=1/d;d=Xe(L[c+40>>3]);G[c+1892>>2]=127;G[c+1888>>2]=128;d=1/d;L[c+152>>3]=d;L[c+128>>3]=d*L[c+136>>3]}break b}if(!Xa(a,35423)){vj(c);break b}if(!Xa(a,35777)){uj(c);break b}if(!Xa(a,34383)){tj(c);break b}if(!Xa(a,34532)){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=66;E[c+1|0]=79;E[c+2|0]=78;E[c+3|0]=0;E[c+4|0]=89;E[c+5|0]=2;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;d=L[c+24>>3];r:{if(d==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;G[c+120>>2]=0;G[c+124>>2]=1072693248;d=Mb(L[c+40>>3])*57.29577951308232/Kb(L[c+40>>3])+L[c+40>>3];break r}L[c+120>>3]=d*3.141592653589793/180;d=d*(Mb(L[c+40>>3])/Kb(L[c+40>>3])+L[c+40>>3]*3.141592653589793/180)}G[c+1892>>2]=135;G[c+1888>>2]=136;L[c+128>>3]=d;break b}if(!Xa(a,34387)){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=80;E[c+1|0]=67;E[c+2|0]=79;E[c+3|0]=0;E[c+4|0]=90;E[c+5|0]=2;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;d=L[c+24>>3];s:{if(d==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;g=1;f=1;d=114.59155902616465;break s}g=d*3.141592653589793/180;f=1/g;d=d+d}G[c+1892>>2]=137;G[c+1888>>2]=138;L[c+112>>3]=g;L[c+128>>3]=d;L[c+120>>3]=f;break b}if(!Xa(a,35861)){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=84;E[c+1|0]=83;E[c+2|0]=67;E[c+3|0]=0;E[c+4|0]=189;E[c+5|0]=2;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;d=L[c+24>>3];t:{if(d==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;e=45;d=.022222222222222223;break t}e=d*3.141592653589793*.25;d=1/e}G[c+1892>>2]=101;G[c+1888>>2]=102;L[c+112>>3]=e;L[c+120>>3]=d;break b}if(!Xa(a,35869)){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=67;E[c+1|0]=83;E[c+2|0]=67;E[c+3|0]=0;E[c+4|0]=190;E[c+5|0]=2;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;d=L[c+24>>3];u:{if(d==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;e=45;d=.022222222222222223;break u}e=d*3.141592653589793*.25;d=1/e}G[c+1892>>2]=103;G[c+1888>>2]=104;L[c+112>>3]=e;L[c+120>>3]=d;break b}if(!Xa(a,35865)){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=81;E[c+1|0]=83;E[c+2|0]=67;E[c+3|0]=0;E[c+4|0]=191;E[c+5|0]=2;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;d=L[c+24>>3];v:{if(d==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;e=45;d=.022222222222222223;break v}e=d*3.141592653589793*.25;d=1/e}G[c+1892>>2]=105;G[c+1888>>2]=106;L[c+112>>3]=e;L[c+120>>3]=d;break b}if(!Xa(a,32859)){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=72;E[c+1|0]=80;E[c+2|0]=88;E[c+3|0]=0;E[c+4|0]=33;E[c+5|0]=3;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;i=L[c+48>>3];w:{if(O(i)<2147483648){a=~~i;break w}a=-2147483648}G[c+272>>2]=(a|0)%2;d=L[c+24>>3];x:{if(d==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=1;d=1;break x}f=57.29577951308232/d;d=d*3.141592653589793/180}L[c+112>>3]=d;G[c+1892>>2]=139;G[c+1888>>2]=140;L[c+120>>3]=f;f=i+-1;L[c+128>>3]=f/i;L[c+144>>3]=(i+1)*.5;k=L[c+40>>3];L[c+168>>3]=k/360;h=180/k;L[c+160>>3]=h;L[c+152>>3]=f*90/k;f=i*90/k;L[c+136>>3]=f;L[c+184>>3]=d*h;L[c+176>>3]=d*f;break b}if(!Xa(a,34928)){E[c|0]=88;E[c+1|0]=80;E[c+2|0]=72;E[c+3|0]=0;E[c+4|0]=34;E[c+5|0]=3;E[c+6|0]=0;E[c+7|0]=0;d=L[c+24>>3];y:{if(d==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;g=1;d=1;break y}g=57.29577951308232/d;d=d*3.141592653589793/180}G[c+1892>>2]=141;G[c+1888>>2]=142;G[c+160>>2]=-1279502567;G[c+164>>2]=1066787723;G[c+152>>2]=1514773339;G[c+156>>2]=1079410611;G[c+144>>2]=1232524644;G[c+148>>2]=1078420498;G[c+136>>2]=-350469331;G[c+140>>2]=1058682594;G[c+128>>2]=1431655765;G[c+132>>2]=1071994197;L[c+120>>3]=g/1.4142135623730951;L[c+112>>3]=d/1.4142135623730951;break b}j=1;if(Xa(a,35970)){break a}G[c+1892>>2]=107;G[c+1888>>2]=108;E[c|0]=84;E[c+1|0]=79;E[c+2|0]=65;E[c+3|0]=0;E[c+4|0]=35;E[c+5|0]=3;E[c+6|0]=0;E[c+7|0]=0}j=0}z:{if(j){break z}h=L[b+24>>3];d=L[c+16>>3];A:{if(d==90){if(h==999){G[b+24>>2]=0;G[b+28>>2]=1080459264}L[b+40>>3]=L[b+8>>3];e=L[b+16>>3];L[b+32>>3]=e;L[b+48>>3]=90-e;break A}f=L[b+16>>3];if(h==999){L[b+24>>3]=d>f?180:0}m=Mb(f);n=Kb(L[b+16>>3]);d=Mb(L[b+24>>3]);k=Kb(L[b+24>>3]);h=Mb(L[c+16>>3]);f=d*h;i=Kb(L[c+16>>3]);d=V(f*f+i*i);B:{if(d==0){if(n!=0){break z}e=L[b+32>>3];break B}d=n/d;if(O(d)>1){break z}f=Ac(i,f);d=Yg(d);e=f+d;C:{if(e>180){e=e+-360;break C}if(!(e<-180)){break C}e=e+360}g=f-d;D:{if(g>180){g=g+-360;break D}if(!(g<-180)){break D}g=g+360}d=L[b+32>>3];e=O(d-e)>3]=e}L[b+48>>3]=90-e;d=m*Mb(e);E:{F:{if(O(d)<1e-10){if(O(m)<1e-10){f=L[b+8>>3];L[b+40>>3]=f;L[b+48>>3]=90-L[c+16>>3];break E}if(e>0){G[b+48>>2]=0;G[b+52>>2]=0;L[b+40>>3]=L[b+8>>3]+L[b+24>>3]+-180;break F}if(!(e<0)){break F}G[b+48>>2]=0;G[b+52>>2]=1080459264;f=L[b+8>>3];L[b+40>>3]=f-L[b+24>>3];break E}f=(i-Kb(e)*n)/d;d=k*h/m;if(f==0&d==0){break z}p=b,q=L[b+8>>3]-Ac(d,f),L[p+40>>3]=q}f=L[b+8>>3]}d=L[b+40>>3];if(f>=0){if(!(d<0)){break A}L[b+40>>3]=d+360;break A}if(!(d>0)){break A}L[b+40>>3]=d+-360}L[b+56>>3]=L[b+24>>3];p=b- -64|0,q=Mb(L[b+48>>3]),L[p>>3]=q;d=Kb(L[b+48>>3]);G[b>>2]=137;L[b+72>>3]=d;o=(O(e)>90.0000000001)<<1}return o}function mk(a){var b=0,c=0,d=0,e=0,f=0,g=0;g=Fa-32|0;Fa=g;E[g|0]=0;d=qb(g,a,8);e=d+Va(d)|0;b=H[68293]|H[68294]<<8|(H[68295]<<16|H[68296]<<24);f=H[68289]|H[68290]<<8|(H[68291]<<16|H[68292]<<24);E[e|0]=f;E[e+1|0]=f>>>8;E[e+2|0]=f>>>16;E[e+3|0]=f>>>24;E[e+4|0]=b;E[e+5|0]=b>>>8;E[e+6|0]=b>>>16;E[e+7|0]=b>>>24;E[e+8|0]=H[68297];e=Va(d);if(e){while(1){f=c+d|0;b=E[f|0];E[f|0]=b-97>>>0<26?b&95:b;c=c+1|0;if((e|0)!=(c|0)){continue}break}}b=d+1|0;c=130;a:{b:{c:{d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{p:{q:{r:{s:{t:{u:{e=H[d|0];switch(e-32|0){case 52:break h;case 51:break i;case 50:break j;case 48:break k;case 46:break l;case 45:break m;case 44:break n;case 40:break o;case 39:break p;case 37:break q;case 36:break r;case 35:break s;case 34:break t;case 58:break u;case 0:break a;case 55:break f;case 56:break g;default:break e}}v:{w:{x:{a=H[b|0];switch(a-67|0){case 0:break w;case 6:break x;default:break v}}if(nb(b,67972,7)){break b}c=20;break a}if(nb(b,35409,7)){break b}c=20;break a}y:{z:{A:{B:{if((a|0)==78){if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1162690894){break B}c=20;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}c=0;C:{switch(a-66|0){case 20:if(nb(b,34815,3)){break b}c=20;if((H[d+4|0]-48&255)>>>0>=10){break b}break a;case 18:if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1162627412){break y}c=20;if((H[d+5|0]-48&255)>>>0>=10){break b}break a;case 24:break z;case 17:break A;case 0:break C;default:break c}}c=20;if(!nb(b,66555,7)){break a}if(!nb(b,67937,7)){break a}break d}if(nb(b,33788,5)){break d}c=20;a=H[d+6|0];if((a|0)==32){break a}if((a-48&255)>>>0>=10){break b}break a}c=20;if(!nb(b,67964,7)){break a}if(nb(b,66668,7)){break b}break a}if(nb(b,68017,7)){break b}c=20;break a}if(nb(b,34517,7)){break b}c=20;break a}D:{switch(H[b|0]-73|0){case 0:if(nb(b,67887,7)){break b}c=10;break a;case 3:if(!nb(b,66684,7)){c=10;break a}if(nb(b,68025,7)){break b}c=40;break a;case 10:if(nb(b,67964,7)){break b}c=30;break a;case 17:if(nb(b,68017,7)){break b}c=30;break a;case 12:break D;default:break b}}if(nb(b,68001,7)){break b}c=70;break a}E:{F:{G:{H:{I:{J:{K:{switch(H[b|0]-68|0){case 11:if(nb(b,33333,6)){break J}if(H[a|0]==67){c=10;if(!fb(a,40528,47)){break a}if(!fb(a,16350,47)){break a}if(!fb(a,40421,47)){break a}if(!fb(a,5281,47)){break a}if(!fb(a,17402,47)){break a}}c=H[d+7|0]==32?130:150;break a;case 0:break E;case 15:break F;case 14:break G;case 17:break H;case 16:break I;case 4:break K;default:break b}}if(nb(b,34624,7)){break b}c=100;break a}if(nb(b,35368,7)){break b}c=140;break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1162893652){break b}c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1414090325){break b}c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1279350354){c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1481199698){c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1096044370){c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1380271186){break b}c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1380276563){break b}c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1414284612){c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}c=110;if((H[d+2|0]-48&255)>>>0>=10){break b}break a}if(H[b|0]!=65){break b}if(!nb(b,66628,7)){c=100;break a}c=60;if(!nb(b,66620,7)){break a}if(!nb(b,66563,7)){break a}if(nb(b,33924,7)){break b}c=120;break a}L:{M:{N:{O:{switch(H[b|0]-78|0){case 10:if(nb(b,67981,7)){break N}c=10;break a;case 2:break L;case 3:break M;case 0:break O;default:break b}}if(nb(b,68042,7)){break b}c=10;break a}if(!nb(b,66660,7)){c=90;if(H[a|0]!=69){break a}c=fb(a,65168,28)?90:20;break a}c=90;if(!nb(b,67929,7)){break a}if(nb(b,34796,7)){break b}break a}c=120;if(!nb(b,32864,6)){break a}if(nb(b,34881,3)|(H[d+4|0]-48&255)>>>0>=10){break b}break a}if(nb(b,68033,7)){break b}c=120;break a}P:{a=H[b|0]-67|0;if(a){if((a|0)==15){break P}else{break b}}if(nb(b,67905,7)){break b}c=10;break a}if(nb(b,67913,7)){break b}c=10;break a}Q:{switch(H[b|0]-68|0){case 0:c=90;if(!nb(b,66652,7)){break a}if(!nb(b,67921,7)){break a}if(nb(b,34787,7)){break b}break a;case 5:break Q;default:break b}}if(nb(b,32709,6)){break b}c=H[d+7|0]==32?130:150;break a}a=H[b|0]-65|0;if(a){if((a|0)!=14){break b}c=110;if(!nb(b,35546,6)){break a}if(nb(b,34217,3)|(H[d+4|0]-48&255)>>>0>=10){break b}break a}c=110;if(!nb(b,35538,6)){break a}if(nb(b,34183,3)|(H[d+4|0]-48&255)>>>0>=10){break b}break a}if(H[b|0]!=74){break b}c=120;if(!nb(b,66612,7)){break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1112491082|(H[d+5|0]-48&255)>>>0>=10){break b}break a}if(H[b|0]!=65|(H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1397315649){break b}c=10;a=H[d+5|0];if((a|0)==32){break a}if((a-48&255)>>>0>=10){break b}break a}R:{switch(H[b|0]-67|0){case 0:if(!nb(b,67905,7)){c=10;break a}c=110;if((H[d+2|0]-48&255)>>>0>=10){break b}break a;case 19:c=110;if((H[d+2|0]-48&255)>>>0>=10){break b}break a;case 16:break R;default:break b}}c=110;if((H[d+2|0]-48&255)>>>0>=10){break b}break a}if(H[b|0]!=65){break b}c=120;if(!nb(b,33585,7)){break a}if(!nb(b,33568,6)){break a}if(nb(b,35703,3)|(H[d+4|0]-48&255)>>>0>=10){break b}break a}if(H[b|0]!=73){break b}if(nb(b,67956,7)){break b}c=10;break a}S:{T:{U:{V:{W:{X:{Y:{Z:{_:{$:{aa:{ba:{ca:{da:{ea:{fa:{ga:{switch(H[b|0]-66|0){case 18:if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1162893652){break b}c=10;if((H[d+5|0]-48&255)>>>0>=10){break b}break a;case 4:if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1297239878){break fa}c=10;if((H[d+5|0]-48&255)>>>0>=10){break b}break a;case 20:break T;case 14:break U;case 21:break W;case 1:break X;case 10:break Z;case 24:break _;case 17:break $;case 19:break ba;case 2:break ca;case 12:break da;case 6:break ea;case 0:break ga;default:break b}}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1280262978){break b}c=10;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if(nb(b,66604,7)){break b}c=10;break a}if(nb(b,68009,7)){break b}c=10;break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1280070990){break b}c=40;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if(nb(b,34662,3)){break aa}c=50;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1414090325){break b}c=70;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1347635524){break Y}c=80;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1279345491){break S}c=30;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1330791770){break b}c=30;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1313426764){c=60;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1480674636){break b}c=60;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1313426756){c=60;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))!=1480674628){break b}c=60;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1348031555){c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if(!nb(b,32700,3)){c=110;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1229870403){c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if(!nb(b,34396,3)){c=110;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1280725571){c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if(!nb(b,33155,3)){c=110;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1481658947){c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if(!nb(b,34193,3)){c=110;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1414484547){c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1414284355){c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if(!nb(b,35699,3)){c=110;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}if(!nb(b,35758,3)){c=110;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}if(nb(b,32704,3)){break V}c=110;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}if(nb(b,33911,3)){break b}c=110;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}c=110;if((H[d+2|0]-48&255)>>>0>=10){break b}break a}c=110;if((H[d+2|0]-48&255)>>>0>=10){break b}break a}c=110;if((H[d+2|0]-48&255)>>>0>=10){break b}break a}c=110;if((H[d+2|0]-48&255)>>>0>=10){break b}break a}if(H[b|0]!=84){break b}if(nb(b,34517,7)){break b}c=10;break a}if(H[b|0]!=67){break b}c=110;if(!nb(b,33795,6)){break a}if(!nb(b,35489,6)){break a}if(!nb(b,33057,3)){if((H[d+4|0]-48&255)>>>0>=10){break b}break a}if(nb(b,34405,3)|(H[d+4|0]-48&255)>>>0>=10){break b}break a}if((e-48&255)>>>0>9){break b}ha:{ia:{ja:{ka:{a=H[b|0];switch(a-67|0){case 16:break ia;case 19:break ja;case 0:break ka;default:break ha}}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1348031555){c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if(!nb(b,32700,3)){c=110;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1229870403){c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if(!nb(b,34396,3)){c=110;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1280725571){c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if(!nb(b,33155,3)){c=110;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1481658947){c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if(!nb(b,34193,3)){c=110;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1414484547){c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if((H[b|0]|H[b+1|0]<<8|(H[b+2|0]<<16|H[b+3|0]<<24))==1414284355){c=110;if((H[d+5|0]-48&255)>>>0>=10){break b}break a}if(!nb(b,35699,3)){c=110;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}if(!nb(b,35758,3)){c=110;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}if(nb(b,32704,3)){break b}c=110;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}c=110;if((H[d+2|0]-48&255)>>>0>=10){break b}break a}c=110;if((H[d+2|0]-48&255)>>>0>=10){break b}break a}if((a-48&255)>>>0>9){break b}b=H[d+2|0];a=H[d+3|0];if(!((b|0)!=80|(a|0)!=67)){c=110;if((H[d+4|0]-48&255)>>>0>=10){break b}break a}if((b|0)!=67|(a|0)!=68){break b}c=110;if((H[d+4|0]-48&255)>>>0<10){break a}break b}c=(a|0)!=78}la:{if((a|0)!=69){break la}if(nb(b,66676,7)){break la}c=20;break a}ma:{if(!c){break ma}if(nb(b,35828,7)){break ma}c=20;break a}na:{switch(a-68|0){case 12:if(nb(b,66571,7)){break b}c=20;break a;case 3:if(nb(b,66579,7)){break b}c=20;break a;case 13:if(nb(b,32674,7)){break b}c=20;break a;case 0:break na;default:break b}}if(nb(b,41551,7)){break b}c=20;break a}c=150}Fa=g+32|0;return c}function dh(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;a:{b:{c:{d:{l=G[k>>2];if((l|0)<=0){if(c){E[c|0]=0}if(b){E[b|0]=0}if(d){E[d|0]=0}if(e){E[e|0]=0}if(g){E[g|0]=0}if(h){E[h|0]=0}if(f){E[f|0]=0}if(i){E[i|0]=0}if(j){E[j|0]=0}l=Va(a);if(l){u=l+1|0;p=lb(3,u);if(!p){G[k>>2]=113;return 113}e:{f:{g:{h:{if(H[a|0]!=45){break h}i:{j:{l=H[a+1|0];switch(l-32|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:break h;case 0:case 8:break i;default:break j}}if((l|0)==91){break i}if(l){break h}}o=a+1|0;if(!b){break f}n=Va(b)+b|0;m=H[42061]|H[42062]<<8|(H[42063]<<16|H[42064]<<24);l=H[42057]|H[42058]<<8|(H[42059]<<16|H[42060]<<24);E[n|0]=l;E[n+1|0]=l>>>8;E[n+2|0]=l>>>16;E[n+3|0]=l>>>24;E[n+4|0]=m;E[n+5|0]=m>>>8;E[n+6|0]=m>>>16;E[n+7|0]=m>>>24;E[n+8|0]=H[42065];break g}k:{if(!gc(a,15936,5)){if(b){n=Va(b)+b|0;m=H[42061]|H[42062]<<8|(H[42063]<<16|H[42064]<<24);l=H[42057]|H[42058]<<8|(H[42059]<<16|H[42060]<<24);E[n|0]=l;E[n+1|0]=l>>>8;E[n+2|0]=l>>>16;E[n+3|0]=l>>>24;E[n+4|0]=m;E[n+5|0]=m>>>8;E[n+6|0]=m>>>16;E[n+7|0]=m>>>24;E[n+8|0]=H[42065]}o=a+5|0;break k}m=Sb(a,42197);l=jb(a,40);if(!(!m|(l|0)!=0&l>>>0>>0)){l=m-a|0;if((l|0)>=17){Ua(43433);break a}if(b){qb(b,a,l+3|0)}o=m+3|0;break k}if(!fb(a,36983,4)){if(b){m=Va(b)+b|0;l=H[42036]|H[42037]<<8|(H[42038]<<16|H[42039]<<24);E[m|0]=l;E[m+1|0]=l>>>8;E[m+2|0]=l>>>16;E[m+3|0]=l>>>24;l=H[42039]|H[42040]<<8|(H[42041]<<16|H[42042]<<24);E[m+3|0]=l;E[m+4|0]=l>>>8;E[m+5|0]=l>>>16;E[m+6|0]=l>>>24}o=a+4|0;break k}if(!fb(a,36980,7)){if(b){n=Va(b)+b|0;m=H[42037]|H[42038]<<8|(H[42039]<<16|H[42040]<<24);l=H[42033]|H[42034]<<8|(H[42035]<<16|H[42036]<<24);E[n|0]=l;E[n+1|0]=l>>>8;E[n+2|0]=l>>>16;E[n+3|0]=l>>>24;E[n+4|0]=m;E[n+5|0]=m>>>8;E[n+6|0]=m>>>16;E[n+7|0]=m>>>24;l=H[42041]|H[42042]<<8;E[n+8|0]=l;E[n+9|0]=l>>>8}o=a+7|0;break k}if(!fb(a,36974,5)){if(b){l=Va(b)+b|0;E[l|0]=104;E[l+1|0]=116;E[l+2|0]=116;E[l+3|0]=112;E[l+4|0]=58;E[l+5|0]=47;E[l+6|0]=47;E[l+7|0]=0}o=a+5|0;break k}if(!fb(a,37360,4)){if(b){m=Va(b)+b|0;l=H[42094]|H[42095]<<8|(H[42096]<<16|H[42097]<<24);E[m|0]=l;E[m+1|0]=l>>>8;E[m+2|0]=l>>>16;E[m+3|0]=l>>>24;l=H[42097]|H[42098]<<8|(H[42099]<<16|H[42100]<<24);E[m+3|0]=l;E[m+4|0]=l>>>8;E[m+5|0]=l>>>16;E[m+6|0]=l>>>24}o=a+4|0;break k}if(!fb(a,37358,6)){if(b){n=Va(b)+b|0;m=H[42085]|H[42086]<<8|(H[42087]<<16|H[42088]<<24);l=H[42081]|H[42082]<<8|(H[42083]<<16|H[42084]<<24);E[n|0]=l;E[n+1|0]=l>>>8;E[n+2|0]=l>>>16;E[n+3|0]=l>>>24;E[n+4|0]=m;E[n+5|0]=m>>>8;E[n+6|0]=m>>>16;E[n+7|0]=m>>>24;E[n+8|0]=H[42089]}o=a+6|0;break k}if(!fb(a,38404,5)){if(b){l=Va(b)+b|0;E[l|0]=102;E[l+1|0]=105;E[l+2|0]=108;E[l+3|0]=101;E[l+4|0]=58;E[l+5|0]=47;E[l+6|0]=47;E[l+7|0]=0}o=a+5|0;break k}o=a;if(!b){break f}l=Va(b)+b|0;E[l|0]=102;E[l+1|0]=105;E[l+2|0]=108;E[l+3|0]=101;E[l+4|0]=58;E[l+5|0]=47;E[l+6|0]=47;E[l+7|0]=0;break g}if(!b){break f}}if(fb(b,42025,7)){break f}if(!jb(o,40)){if(!jb(o,91)){break f}}l=Va(o);m=l+o|0;while(1){m=m-1|0;n=H[m|0];if((n|0)==32){continue}break}if((n|0)==41|(n|0)==93){break f}if(!c){break e}if(l>>>0>=1025){Ua(43462);break a}Za(c,o);break e}if(H[o|0]==91){a=(H[a|0]!=45)+o|0}else{a=Sb(o,32652);a=a?a+2|0:o}m=jb(a,40);q=jb(a,91);l:{if(!m){m=0;break l}a=jb(m,41);if(!a){break l}while(1){l=H[a+1|0];a=a+1|0;if((l|0)==32){continue}if(!l|(l|0)==91){break l}m=jb(m+1|0,40);a=jb(a,41);if(!a){break l}if(m){continue}break}}m:{if((m|0)==(q|0)){Gb(p,o);break m}if(!(!m|m>>>0>=q>>>0?q:0)){l=qb(p,o,m-o|0);n=m+1|0;m=jb(n,41);if(!m){break b}if(d){a=m-n|0;if((a|0)>=1025){break b}qb(d,n,a)}q=jb(m,91);break m}qb(p,o,q-o|0)}a=Va(p);n:{if((a|0)<2){break n}while(1){l=a-1|0;m=l+p|0;if(H[m|0]!=32){break n}E[m|0]=0;m=a>>>0>2;a=l;if(m){continue}break}}o:{if(!d){break o}a=Va(d);if((a|0)<2){break o}while(1){l=a-1|0;m=l+d|0;if(H[m|0]!=32){break o}E[m|0]=0;m=a>>>0>2;a=l;if(m){continue}break}}a=Sb(p,17462);if(!(!a|!b|H[a+4|0])){a=H[42097]|H[42098]<<8|(H[42099]<<16|H[42100]<<24);E[b+7|0]=a;E[b+8|0]=a>>>8;E[b+9|0]=a>>>16;E[b+10|0]=a>>>24;l=H[42094]|H[42095]<<8|(H[42096]<<16|H[42097]<<24);a=H[42090]|H[42091]<<8|(H[42092]<<16|H[42093]<<24);E[b|0]=a;E[b+1|0]=a>>>8;E[b+2|0]=a>>>16;E[b+3|0]=a>>>24;E[b+4|0]=l;E[b+5|0]=l>>>8;E[b+6|0]=l>>>16;E[b+7|0]=l>>>24}r=Va(p);m=r-1|0;o=1;p:{if((r|0)<=0){break p}a=m;while(1){t=a+p|0;if(H[t|0]!=43){l=(a|0)>0;a=a-1|0;if(l){continue}break p}break}if(!a){break p}n=r-a|0;if((n|0)>6){break p}q:{r:{l=a+1|0;a=l;if((r|0)<=(a|0)){break r}a=l;while(1){if(E[a+p|0]-48>>>0>9){break r}a=a+1|0;if((r|0)!=(a|0)){continue}break}break q}if((a|0)!=(r|0)){break p}}if(e){rb(e,l+p|0,n)}o=0;E[t|0]=0}if(!(!d|H[d|0]!=42|(r|0)<=0)){while(1){a=m;l=a+p|0;if(H[l|0]!=47){m=a-1|0;if(a){continue}}break}a=l+1|0;if(Va(a)>>>0>=1025){break c}Za(d,a)}if(c){if(Va(p)>>>0>=1025){break c}Za(c,p)}if(!q){break e}s:{if(!o){break s}l=q+1|0;s=jb(l,93);if(!s){Ua(65026);Wa(p);break a}t:{u:{switch(H[l|0]-66|0){case 0:case 2:case 4:case 7:case 8:case 16:case 19:case 32:case 34:case 36:case 39:case 40:case 48:case 51:break u;default:break t}}a=q+2|0;v:{w:{x:{d=H[q+2|0];switch(d-66|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:break v;case 0:case 10:break w;default:break x}}switch(d-98|0){case 0:case 10:break w;default:break v}}a=q+3|0;d=H[q+3|0]}if((d<<24>>24)-48>>>0>=10){break t}while(1){d=E[a+1|0];a=a+1|0;if(d-48>>>0<10){continue}break}y:{z:{a=d&255;switch(a-44|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:break t;case 0:case 14:break y;default:break z}}if((a|0)!=93){break t}}A:{if(!b){break A}if(Sb(b,15936)){a=H[42062]|H[42063]<<8|(H[42064]<<16|H[42065]<<24);E[b+8|0]=a;E[b+9|0]=a>>>8;E[b+10|0]=a>>>16;E[b+11|0]=a>>>24;d=H[42058]|H[42059]<<8|(H[42060]<<16|H[42061]<<24);a=H[42054]|H[42055]<<8|(H[42056]<<16|H[42057]<<24);E[b|0]=a;E[b+1|0]=a>>>8;E[b+2|0]=a>>>16;E[b+3|0]=a>>>24;E[b+4|0]=d;E[b+5|0]=d>>>8;E[b+6|0]=d>>>16;E[b+7|0]=d>>>24;break A}a=H[42118]|H[42119]<<8|(H[42120]<<16|H[42121]<<24);E[b+7|0]=a;E[b+8|0]=a>>>8;E[b+9|0]=a>>>16;E[b+10|0]=a>>>24;d=H[42115]|H[42116]<<8|(H[42117]<<16|H[42118]<<24);a=H[42111]|H[42112]<<8|(H[42113]<<16|H[42114]<<24);E[b|0]=a;E[b+1|0]=a>>>8;E[b+2|0]=a>>>16;E[b+3|0]=a>>>24;E[b+4|0]=d;E[b+5|0]=d>>>8;E[b+6|0]=d>>>16;E[b+7|0]=d>>>24}B:{if(!c){break B}if(Va(c)+Va(q)>>>0>=1025){break c}a=jb(Gb(c,q),93);if(!a){break B}E[a+1|0]=0}if(e){E[e|0]=48;E[e+1|0]=0}a=jb(s+1|0,91);if(!f|!a){break e}a=a+1|0;if(Va(f)+Va(a)>>>0>=1025){break c}a=jb(Gb(f,a),93);if(!a){break e}E[a|0]=0;break e}m=l;while(1){a=m;m=a+1|0;d=H[a|0];if((d|0)==32){continue}break}if((d<<24>>24)-48>>>0<=9){while(1){d=E[a+1|0];a=a+1|0;if(d-48>>>0<10){continue}break}}b=l;a=(d&255)-42|0;if(1<>>0<=16:0){break s}while(1){a=b;b=a+1|0;w=H[a|0];if((w|0)==32){continue}break}y=gc(a,66349,4);r=gc(a,15943,3);x=gc(a,3751,3);C:{if(gc(a,66032,9)){n=0;if(gc(a,31920,9)){break C}}n=1}if(!gc(a,64290,10)){break s}if(!gc(a,64301,10)){break s}v=s-l|0;D:{if((v|0)<0){d=0;c=0;break D}t=s-q|0;m=0;c=0;E:{while(1){b=1;d=0;F:{G:{H:{I:{J:{o=H[a|0];switch(o-32|0){case 92:break J;case 12:case 27:case 61:break D;case 0:break E;case 14:break F;case 28:case 29:case 30:break H;case 6:break I;default:break G}}if(H[a+1|0]==124){break H}break G}if(H[a+1|0]!=38){break G}}z=1}b=c}a=a+1|0;c=b;m=m+1|0;if((t|0)!=(m|0)){continue}break}break D}while(1){b=o&255;if((b|0)==32){o=H[a+1|0];a=a+1|0;continue}break}if((b|0)==93){break D}if(!y|(!r|!x)&m>>>0<=4){break s}K:{switch((o&255)-33|0){case 0:case 4:case 5:case 9:case 10:case 12:case 14:case 27:case 28:case 29:case 91:d=1;break;default:break K}}A=1;if(!x){break s}}if(d&A|((w|0)==64&(c|0)!=0|z|n)){break s}if(e){if((v|0)>=1025){break c}qb(e,l,v)}q=s+1|0}d=p+u|0;l=Gb(d,q);a=Va(l);L:{if((a|0)<=0){break L}while(1){b=a-1|0;c=b+l|0;if(H[c|0]!=32){break L}E[c|0]=0;c=a>>>0>1;a=b;if(c){continue}break}}if(!H[l|0]){break e}m=d+u|0;a=Sb(l,15942);M:{N:{if(a){break N}a=Sb(l,34574);if(a){break N}a=Sb(l,15947);if(!a){break M}}d=H[a+4|0];b=d-98|0;if(!(b>>>0>16|!(1<>>0>=1025){break c}b=jb(Za(g,b),93);if(!b){break d}E[b|0]=0;b=b-1|0;if(H[b|0]!=32){break O}E[b|0]=0}Za(a,Za(m,jb(a,93)+1|0))}P:{g=Sb(l,66348);Q:{if(g){break Q}g=Sb(l,66636);if(g){break Q}g=Sb(l,66354);if(!g){break P}}c=0;R:while(1){e=g+5|0;a=e;while(1){d=H[a|0];if((d|0)==32){a=a+1|0;continue}break}c=(d|0)!=64?c:1;while(1){S:{T:{b=d&255;U:{if((b|0)!=39){if((b|0)==93){break T}if(b){break U}Ua(65026);Wa(p);break a}a=jb(a+1|0,39);if(!a){Ua(20291);Wa(p);break a}d=H[a|0]}if((d&255)!=91){d=a;break S}d=jb(a+1|0,93);if(d){break S}Ua(5174);Wa(p);break a}V:{if(!h){break V}d=(g^-1)+a|0;if(Va(h)+d>>>0>=1025){break c}W:{if(!H[h|0]){B=rb(h,g+1|0,d)+d|0,C=0,E[B|0]=C;break W}b=Va(h)+h|0;E[b|0]=59;E[b+1|0]=0;qb(h,e,d-4|0);if(!c){break W}Ua(4201);Wa(p);break a}d=Va(h)-1|0;b=h+d|0;if(H[b|0]!=32){break V}while(1){E[b|0]=0;d=d-1|0;b=h+d|0;if(H[b|0]==32){continue}break}}Za(g,Za(m,a+1|0));g=Sb(l,66348);X:{if(g){break X}g=Sb(l,66636);if(g){break X}g=Sb(l,66354)}if(g){continue R}break P}a=d+1|0;d=H[d+1|0];continue}}}Y:{g=Sb(l,3750);Z:{if(g){break Z}g=Sb(l,32871);if(g){break Z}g=Sb(l,3774);if(!g){break Y}}d=4;_:{$:{b=H[g+4|0];switch(b-66|0){case 0:case 2:case 7:case 8:case 16:case 32:case 34:case 39:case 40:case 48:break $;default:break _}}b=H[g+5|0];d=5}a=32;d=(d+g|0)+((b&255)==49)|0;if(H[d|0]!=32){break Y}while(1){aa:{ba:{ca:{b=a&255;da:{if((b|0)!=39){if((b|0)==93){break ca}if(b){break da}Ua(65026);Wa(p);break a}d=jb(d+1|0,39);if(!d){break ba}a=H[d|0]}if((a&255)!=91){a=d;break aa}a=jb(d+1|0,93);if(a){break aa}Ua(5174);Wa(p);break a}ea:{if(!i){break ea}a=(g^-1)+d|0;if((a|0)>=1025){break c}c=rb(i,g+1|0,a);E[c+a|0]=0;a=a-1|0;b=c+a|0;if(H[b|0]!=32){break ea}while(1){E[b|0]=0;a=a-1|0;b=c+a|0;if(H[b|0]==32){continue}break}}Za(g,Za(m,d+1|0));break Y}Ua(20291);Wa(p);break a}d=a+1|0;a=H[a+1|0];continue}}b=Sb(l,5790);fa:{if(!b){break fa}a=H[b+9|0];if((a|0)!=93&(a|0)!=32){break fa}ga:{if(!j){break ga}a=b+1|0;if(Va(a)>>>0>=1025){break c}a=jb(Za(j,a),93);if(!a){break d}E[a|0]=0;a=a-1|0;if(H[a|0]!=32){break ga}E[a|0]=0}Za(b,Za(m,jb(b,93)+1|0))}if(!f){break e}a=H[l|0];if(!a){break e}ha:{if((a|0)!=91){break ha}e=0;a=l;ia:while(1){ja:{g=Sb(l,32631);d=g-a|0;if((d|0)<3){break ja}c=a+1|0;a=c;while(1){b=H[a|0];if((b|0)!=32){if((Va(f)+d|0)-1019>>>0<=4294966270){break c}e=(b|0)!=64?e:1;if(!(!H[f|0]|!e)){Ua(4146);Wa(p);break a}b=Va(f)+f|0;a=H[64752]|H[64753]<<8;E[b|0]=a;E[b+1|0]=a>>>8;E[b+2|0]=H[64754];a=qb(f,c,d-1|0);b=Va(a)+a|0;a=H[65324]|H[65325]<<8|(H[65326]<<16|H[65327]<<24);E[b|0]=a;E[b+1|0]=a>>>8;E[b+2|0]=a>>>16;E[b+3|0]=a>>>24;E[b+4|0]=H[65328];a=g+1|0;if(H[g+1|0]==91){continue ia}break ha}else{a=a+1|0;continue}}}break}c=(Va(l)+l|0)-1|0;if(H[c|0]!=93){break ha}g=a+1|0;d=g;while(1){b=H[d|0];if((b|0)!=32){c=c-a|0;d=E[f|0];if((((c|0)!=(0-d|0))<<2)+Va(f)>>>0>=1025){break c}if(!(!d|!((b|0)!=64?e:1))){Ua(4146);Wa(p);break a}if(d){b=Va(f)+f|0;a=H[64752]|H[64753]<<8;E[b|0]=a;E[b+1|0]=a>>>8;E[b+2|0]=H[64754];a=qb(f,g,c-1|0);b=Va(a)+a|0;a=H[63668]|H[63669]<<8;E[b|0]=a;E[b+1|0]=a>>>8;E[b+2|0]=H[63670];break e}qb(f,g,c-1|0);break e}else{d=d+1|0;continue}}}Ua(14908);G[k>>2]=125}Wa(p)}l=G[k>>2]}return l}Ua(65026);Ua(l);Wa(p);break a}Wa(p);break a}Wa(l)}G[k>>2]=125;return 125}function Ps(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;i=Fa-256|0;Fa=i;G[i+168>>2]=0;if(G[309801]){G[i+160>>2]=e;G[i+156>>2]=d;G[i+152>>2]=c;G[i+148>>2]=b;G[i+144>>2]=a;kb(87765,i+144|0)}l=e-1|0;a:{b:{if((b+1|0)!=(c|0)){g=G[309810];break b}G[309810]=g;G[g+16>>2]=0;b=G[g+12>>2];b=(b|0)>0?(a|0)>(b|0)?b:a:(b|0)<0?a:d;G[g+12>>2]=b;G[309805]=(b+c|0)-1;b=G[g+4>>2];c:{if(!b){b=M(l,244)+f|0;if(!G[b+84>>2]){Ua(65613);c=434;break a}G[309803]=G[b+88>>2];G[g>>2]=G[b+80>>2];G[309808]=0;G[309809]=0;G[i+172>>2]=0;d:{e:{if(!G[309736]){b=G[G[309731]+24>>2];if(!b){break d}k=b>>31;break e}b=M(l,244)+f|0;j=G[b>>2];o=G[b+4>>2];g=0;h=Fa-352|0;Fa=h;k=i+172|0;f:{if(G[k>>2]>0){break f}G[i+164>>2]=0;E[h+256|0]=0;u=qb(h+256|0,34755,74);p=Va(u);if(p){if((p|0)>0){while(1){n=g+u|0;b=E[n|0];E[n|0]=b-97>>>0<26?b&95:b;g=g+1|0;if((p|0)!=(g|0)){continue}break}}g:{if(G[k>>2]>0){g=G[j+4>>2];b=G[g+76>>2];break g}b=G[j>>2];g=G[j+4>>2];if((b|0)!=G[g+76>>2]){mb(j,b+1|0,0,k);g=G[j+4>>2];b=G[g+76>>2]}q=G[g+104>>2];n=G[g+96>>2]+(b<<3)|0;s=G[n>>2];q=Bu(q-s|0,G[g+108>>2]-(G[n+4>>2]+(q>>>0>>0)|0)|0,80,0)}n=G[j>>2];if((n|0)!=(b|0)){mb(j,n+1|0,0,k);g=G[j+4>>2];b=G[g+76>>2]}b=G[g+96>>2]+(b<<3)|0;n=G[b>>2]+160|0;b=G[b+4>>2];G[g+120>>2]=n;G[g+124>>2]=n>>>0<160?b+1|0:b;h:{i:{if((q|0)>=3){s=o+1|0;n=p+(h+160|0)|0;b=3;while(1){if((Jg(j,h+160|0,k)|0)>0){break f}g=b;j:{if(fb(u,h+160|0,p)){break j}E[h+248|0]=0;b=jb(h+160|0,61);if(!b){break j}b=b-n|0;v=207;if((b|0)>=8){break h}b=qb(h+248|0,n,b);G[h+348>>2]=0;if((ue(b,h+344|0,h+348|0)|0)>0){break j}b=G[h+344>>2];if((b|0)>=(s|0)|(b|0)<(o|0)){break j}b=h+80|0;mc(h+160|0,b,h,k);Ie(b,(G[h+344>>2]-o<<3)+1239232|0,k);b=G[h+344>>2]-o|0;if((b|0)>=G[i+164>>2]){G[i+164>>2]=b+1}if(G[k>>2]!=204){break j}G[k>>2]=0;w=1}b=g+1|0;if((g|0)!=(q|0)){continue}break}if(w){break i}}break f}if(G[k>>2]>0){break f}v=204}G[k>>2]=v}}Fa=h+352|0;g=G[309810];if(G[i+172>>2]!=403){break d}b=-32768;k=-1;k:{switch(G[g>>2]-21|0){case 10:case 20:break k;case 0:break e;default:break d}}b=-2147483648}G[309808]=b;G[309809]=k}b=(M(l,244)+f|0)+92|0;break c}G[309802]=b;b=G[g+8>>2];G[309803]=b?b:1239248;b=(G[309722]+M(G[309725],344)|0)+56|0}G[309806]=G[b>>2];b=1;l:{m:{n:{switch(G[g>>2]-1|0){case 20:b=2;break m;case 80:case 81:b=8;break m;case 0:case 10:case 13:break m;case 15:case 30:case 40:case 41:break n;default:break l}}b=4}G[309804]=b}o:{switch(G[(G[309722]+M(G[309725],344)|0)+52>>2]-258|0){case 0:G[309807]=1;break b;case 1:G[309807]=4;break b;case 2:break o;default:break b}}G[309807]=8}p:{if(G[g+4>>2]){break p}G[309802]=G[(M(l,244)+f|0)+88>>2]+G[309804];q:{switch(G[g>>2]-11|0){case 3:E[G[309803]]=85;break p;case 0:E[G[309803]]=G[309808];break p;case 10:F[G[309803]>>1]=G[309808];break p;case 20:G[G[309803]>>2]=G[309808];break p;case 30:G[G[309803]>>2]=G[309808];break p;case 70:g=G[309809];b=G[309803];G[b>>2]=G[309808];G[b+4>>2]=g;break p;case 31:G[G[309803]>>2]=-2059275978;break p;case 71:b=G[309803];G[b>>2]=1589294263;G[b+4>>2]=-1196933592;break p;case 5:break q;default:break p}}b=G[309803];E[G[b>>2]]=1;E[G[b>>2]+1|0]=0}G[309732]=c;b=G[309805]-c|0;k=(b|0)<(d|0)?b+1|0:d;G[309733]=k;r:{if((e|0)<=0){break r}u=k<<2;s:{t:{u:{while(1){v:{o=M(m,244)+f|0;if(G[o+84>>2]!=2){d=G[309730];j=d+M(m,124)|0;h=G[j+88>>2];b=M(h,k);w:{x:{y:{z:{A:{B:{C:{g=G[j+84>>2];switch(g-258|0){case 2:break y;case 1:break z;case 0:break A;case 3:break B;case 4:break C;default:break x}}b=G[j+120>>2];D:{if(!b){break D}g=G[b>>2];if(g){Wa(g);break D}G[i+132>>2]=1386;G[i+128>>2]=30721;kb(74561,i+128|0)}Wa(b);l=ab(u);if(!l){break u}q=h+1|0;b=ab(M(q,k));G[l>>2]=b;if(!b){break v}if((k|0)>0){n=(h+7|0)/8|0;p=0;while(1){b=l+(p<<2)|0;g=G[l>>2]+M(p,q)|0;G[b>>2]=g;if((h|0)>0){d=M(n,p)+1|0;g=0;while(1){s=g&7;E[G[b>>2]+g|0]=H[G[o+88>>2]+d|0]>>>(s^7)&1?49:48;d=((s|0)==7)+d|0;g=g+1|0;if((h|0)!=(g|0)){continue}break}g=G[b>>2];b=h}else{b=0}E[b+g|0]=0;p=p+1|0;if((p|0)!=(k|0)){continue}break}}G[j+116>>2]=l;G[j+120>>2]=l;break w}g=G[o+88>>2];b=G[j+116>>2];if(b){Wa(b)}b=ab(k);G[j+116>>2]=b;if(!b){break t}d=k;if(d){while(1){b=d-1|0;h=G[g>>2];l=H[h|0];if(l){d=G[g+(d<<2)>>2];if((l|0)==H[d|0]){d=Xa(h,d)}else{d=-1}}else{d=1}E[b+G[j+116>>2]|0]=!d;d=b;if(b){continue}break}}G[j+120>>2]=g+4;break w}d=G[o+88>>2];g=G[j+116>>2];if(g){Wa(g)}g=ab(b);G[j+116>>2]=g;if(!g){break t}E:{if(!b){break E}g=b;if(b&1){g=b-1|0;l=g+G[j+116>>2]|0;h=H[d|0];if(h){h=(h|0)==H[b+d|0]}else{h=0}E[l|0]=h}if((b|0)==1){break E}while(1){b=0;h=H[d|0];if(h){b=(h|0)==H[d+g|0]}h=g-1|0;E[h+G[j+116>>2]|0]=b;g=g-2|0;l=g+G[j+116>>2]|0;b=H[d|0];if(b){b=(b|0)==H[d+h|0]}else{b=0}E[l|0]=b;if(g){continue}break}}G[j+120>>2]=d+1;break w}d=G[o+88>>2];g=G[j+116>>2];if(g){Wa(g)}g=ab(b);G[j+116>>2]=g;if(!g){break t}F:{if(!b){break F}g=b;if(b&1){g=b-1|0;l=g+G[j+116>>2]|0;h=G[d>>2];if(h){h=(h|0)==G[d+(b<<2)>>2]}else{h=0}E[l|0]=h}if((b|0)==1){break F}while(1){b=0;h=G[d>>2];if(h){b=(h|0)==G[d+(g<<2)>>2]}h=g-1|0;E[h+G[j+116>>2]|0]=b;g=g-2|0;l=g+G[j+116>>2]|0;b=G[d>>2];if(b){b=(b|0)==G[d+(h<<2)>>2]}else{b=0}E[l|0]=b;if(g){continue}break}}G[j+120>>2]=d+4;break w}d=G[o+88>>2];g=G[j+116>>2];if(g){Wa(g)}g=ab(b);G[j+116>>2]=g;if(!g){break t}G:{if(!b){break G}g=b;if(b&1){g=b-1|0;l=g+G[j+116>>2]|0;r=L[d>>3];if(r==0){h=0}else{h=r==L[d+(b<<3)>>3]}E[l|0]=h}if((b|0)==1){break G}while(1){h=g-1|0;l=h+G[j+116>>2]|0;r=L[d>>3];if(r!=0){b=r==L[d+(g<<3)>>3]}else{b=0}E[l|0]=b;g=g-2|0;l=g+G[j+116>>2]|0;r=L[d>>3];if(r!=0){b=r==L[d+(h<<3)>>3]}else{b=0}E[l|0]=b;if(g){continue}break}}G[j+120>>2]=d+8;break w}G[i+112>>2]=g;b=i+176|0;Ya(b,80,75041,i+112|0);Ua(b)}if(G[309737]){break s}}m=m+1|0;if((m|0)!=(e|0)){continue}break r}break}Wa(l)}G[(d+M(m,124)|0)+116>>2]=0;G[j+120>>2]=0}G[309737]=113}if(!m){break r}while(1){m=m-1|0;b=G[309730]+M(m,124)|0;H:{if(G[b+84>>2]!=262){break H}d=G[G[b+120>>2]>>2];if(d){Wa(d);break H}G[i+100>>2]=1492;G[i+96>>2]=30721;kb(74649,i+96|0)}d=G[b+116>>2];I:{if(d){Wa(d);break I}G[i+84>>2]=1493;G[i+80>>2]=30721;kb(74444,i+80|0)}G[b+116>>2]=0;if(m){continue}break}}J:{K:{if(!k){break K}while(1){L:{j=(k|0)<2500?k:2500;pn(c,j);if(G[309737]){break L}h=G[309722]+M(G[309725],344)|0;t=G[h>>2]==-1e3?1:t;M:{N:{O:{switch(G[h+52>>2]-258|0){case 0:case 1:case 2:P:{if(t){E[i+176|0]=0;if((k|0)<=0){break P}b=(j|0)>1?j:1;f=h+88|0;d=G[309806];e=0;while(1){G[i+164>>2]=0;g=0;if((d|0)>0){while(1){li(G[309735],f,i+176|0,G[h+56>>2],G[G[309810]>>2],G[309803],G[309802]+M(G[309804],M(d,e)+g|0)|0,i+168|0);g=G[i+164>>2]+1|0;G[i+164>>2]=g;d=G[309806];if((g|0)<(d|0)){continue}break}}e=e+1|0;if((b|0)!=(e|0)){continue}break}break P}e=G[309806];b=G[h+56>>2];Q:{if((e|0)==(b|0)){li(G[309735],G[h+88>>2],G[h+84>>2],M(e,j),G[G[309810]>>2],G[309803],G[309802],i+168|0);break Q}if((b|0)==1){if((k|0)<=0){break Q}b=(j|0)>1?j:1;g=0;while(1){G[i+164>>2]=0;d=0;if((e|0)>0){while(1){li(G[309735],G[h+88>>2]+M(G[309807],g)|0,G[h+84>>2]+g|0,1,G[G[309810]>>2],G[309803],G[309802]+M(G[309804],M(e,g)+d|0)|0,i+168|0);d=G[i+164>>2]+1|0;G[i+164>>2]=d;e=G[309806];if((e|0)>(d|0)){continue}break}}g=g+1|0;if((b|0)!=(g|0)){continue}break}break Q}if((k|0)<=0){break Q}b=(b|0)>(e|0)?e:b;d=(j|0)>1?j:1;g=0;while(1){f=M(G[h+56>>2],g);li(G[309735],G[h+88>>2]+M(f,G[309807])|0,f+G[h+84>>2]|0,b,G[G[309810]>>2],G[309803],G[309802]+M(G[309804],M(e,g))|0,i+168|0);e=G[309806];if((b|0)<(e|0)){f=G[309804];cb(G[309802]+M(f,b+M(e,g)|0)|0,0,M(f,e-b|0))}g=g+1|0;if((d|0)!=(g|0)){continue}break}}if(G[h>>2]<=0){break P}b=G[h+88>>2];if(b){Wa(b);break P}G[i+4>>2]=1214;G[i>>2]=30721;kb(74324,i)}g=G[309737];if((g|0)!=-11){break M}G[309737]=412;Ua(20787);break N;case 4:R:{S:{switch(G[G[309810]>>2]-1|0){case 10:if((k|0)<=0){break R}f=(j|0)>1?j:1;e=h+88|0;m=0;b=G[309802];d=-1;while(1){G[i+164>>2]=0;T:{if(G[h+56>>2]<=0){break T}g=0;if(!t){while(1){if(!(g&7)){d=d+1|0;E[b+d|0]=0;g=G[i+164>>2]}if(H[G[G[e>>2]+(m<<2)>>2]+g|0]==49){l=b+d|0;E[l|0]=H[l|0]|128>>>(g&7);g=G[i+164>>2]}g=g+1|0;G[i+164>>2]=g;if(G[h+56>>2]>(g|0)){continue}break T}}while(1){if(!(g&7)){d=d+1|0;E[b+d|0]=0;g=G[i+164>>2]}if(H[e+g|0]==49){l=b+d|0;E[l|0]=H[l|0]|128>>>(g&7);g=G[i+164>>2]}g=g+1|0;G[i+164>>2]=g;if(G[h+56>>2]>(g|0)){continue}break}}m=m+1|0;if((f|0)!=(m|0)){continue}break};break R;case 0:case 13:if(t){if((k|0)<=0){break R}b=(j|0)>1?j:1;f=h+88|0;m=G[309802];e=0;while(1){G[i+164>>2]=0;g=0;d=G[h+56>>2];if((d|0)>0){while(1){E[m+(M(d,e)+g|0)|0]=H[f+g|0]==49;g=G[i+164>>2]+1|0;G[i+164>>2]=g;d=G[h+56>>2];if((g|0)<(d|0)){continue}break}}e=e+1|0;if((b|0)!=(e|0)){continue}break}break R}if((k|0)<=0){break R}b=(j|0)>1?j:1;f=G[309802];d=0;while(1){G[i+164>>2]=0;g=0;e=G[h+56>>2];if((e|0)>0){while(1){E[f+(M(d,e)+g|0)|0]=H[G[G[h+88>>2]+(d<<2)>>2]+g|0]==49;g=G[i+164>>2]+1|0;G[i+164>>2]=g;e=G[h+56>>2];if((g|0)<(e|0)){continue}break}}d=d+1|0;if((b|0)!=(d|0)){continue}break};break R;case 15:G[i+164>>2]=0;if(t){if((k|0)<=0){break R}b=h+88|0;g=0;d=G[309802];while(1){Za(G[d+(g<<2)>>2],b);g=G[i+164>>2]+1|0;G[i+164>>2]=g;if((g|0)<(j|0)){continue}break}break R}if((k|0)<=0){break R}g=0;b=G[309802];while(1){d=g<<2;Za(G[d+b>>2],G[d+G[h+88>>2]>>2]);g=G[i+164>>2]+1|0;G[i+164>>2]=g;if((g|0)<(j|0)){continue}break};break R;default:break S}}Ua(43732);G[309737]=432}if(G[h>>2]<=0){break N}b=G[G[h+88>>2]>>2];U:{if(b){Wa(b);break U}G[i+36>>2]=1274;G[i+32>>2]=30721;kb(74596,i+32|0)}b=G[h+88>>2];if(b){Wa(b);break N}G[i+20>>2]=1275;G[i+16>>2]=30721;kb(74274,i+16|0);break N;case 3:break O;default:break N}}V:{if(G[G[309810]>>2]==16){if(t){G[i+164>>2]=0;if((k|0)<=0){break V}b=h+88|0;g=0;d=G[309802];while(1){Za(G[d+(g<<2)>>2],b);g=G[i+164>>2]+1|0;G[i+164>>2]=g;if((g|0)<(j|0)){continue}break}break V}G[i+164>>2]=0;b=G[i+168>>2];W:{if((k|0)<=0){d=b;break W}g=0;f=G[309803];m=G[309802];while(1){l=g<<2;o=G[l+m>>2];d=1;e=f;if(!H[G[h+84>>2]+g|0]){e=l+G[h+88>>2]|0;d=b}Za(o,G[e>>2]);g=G[i+164>>2]+1|0;G[i+164>>2]=g;b=d;if((g|0)<(j|0)){continue}break}}G[i+168>>2]=d;break V}Ua(43779);G[309737]=432}if(G[h>>2]<=0){break N}b=G[G[h+88>>2]>>2];X:{if(b){Wa(b);break X}G[i+68>>2]=1300;G[i+64>>2]=30721;kb(74596,i- -64|0)}b=G[h+88>>2];if(b){Wa(b);break N}G[i+52>>2]=1301;G[i+48>>2]=30721;kb(74274,i+48|0)}g=G[309737]}c=c+j|0;if(g){break L}k=k-j|0;Y:{Z:{_:{switch(G[h+52>>2]-261|0){case 1:if(G[G[309810]>>2]!=11){break Z}b=G[309802]+M(M(j,G[309804]),(G[h+56>>2]+7|0)/8|0)|0;break Y;case 0:break _;default:break Z}}b=G[309802]+M(j,G[309804])|0;break Y}b=G[309802]+M(G[309806],M(j,G[309804]))|0}G[309802]=b;if(k){continue}}break}if(!G[i+168>>2]){break K}b=G[309810];G[b+16>>2]=1;break J}b=G[309810];if(G[b+4>>2]){break J}d=G[309803];if(G[b>>2]==16){d=G[d>>2];e=I[619624];E[d|0]=e;E[d+1|0]=e>>>8;break J}bb(d,1239248,G[309804])}$:{if(!G[309736]){g=G[309737];break $}g=G[309737];if(g|G[309805]!=(c-1|0)){break $}g=0;c=-1;if(G[b+12>>2]<(a|0)){break a}}c=g}Fa=i+256|0;return c|0}function Qc(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;y=Fa-16|0;Fa=y;G[y+12>>2]=c;d=Fa-144|0;Fa=d;e=cb(d,0,144);G[e+76>>2]=-1;G[e+44>>2]=a;G[e+32>>2]=4;G[e+84>>2]=a;d=b;v=c;a=0;j=Fa-304|0;Fa=j;a:{b:{c:{d:{if(G[e+4>>2]){break d}si(e);if(G[e+4>>2]){break d}break c}b=H[d|0];if(!b){break a}e:{f:{g:{h:{while(1){i:{b=b&255;j:{if((b|0)==32|b-9>>>0<5){while(1){b=d;d=d+1|0;c=H[b+1|0];if((c|0)==32|c-9>>>0<5){continue}break}te(e,0,0);while(1){c=G[e+4>>2];k:{if((c|0)!=G[e+104>>2]){G[e+4>>2]=c+1;c=H[c|0];break k}c=jc(e)}if((c|0)==32|c-9>>>0<5){continue}break}d=G[e+4>>2];c=G[e+116>>2];if((c|0)>0|(c|0)>=0){d=d-1|0;G[e+4>>2]=d}c=d-G[e+44>>2]|0;d=c>>31;g=c;h=p+G[e+124>>2]|0;c=r+G[e+120>>2]|0;h=c>>>0>>0?h+1|0:h;f=c;c=g+c|0;h=d+h|0;r=c;p=c>>>0>>0?h+1|0:h;break j}l:{m:{n:{if(H[d|0]==37){b=H[d+1|0];if((b|0)==42){break n}if((b|0)!=37){break m}}te(e,0,0);o:{if(H[d|0]==37){while(1){b=G[e+4>>2];p:{if((b|0)!=G[e+104>>2]){G[e+4>>2]=b+1;b=H[b|0];break p}b=jc(e)}if((b|0)==32|b-9>>>0<5){continue}break}d=d+1|0;break o}b=G[e+4>>2];if((b|0)!=G[e+104>>2]){G[e+4>>2]=b+1;b=H[b|0];break o}b=jc(e)}if(H[d|0]!=(b|0)){c=G[e+116>>2];if((c|0)>0|(c|0)>=0){G[e+4>>2]=G[e+4>>2]-1}if((b|0)>=0){break a}g=0;if(w){break a}break c}b=G[e+4>>2]-G[e+44>>2]|0;f=b>>31;g=b;b=p+G[e+124>>2]|0;c=r+G[e+120>>2]|0;b=c>>>0>>0?b+1|0:b;h=c;c=g+c|0;g=b+f|0;r=c;p=c>>>0>>0?g+1|0:g;b=d;break j}l=0;b=d+2|0;break l}if(!(H[d+2|0]!=36|b-48>>>0>=10)){b=H[d+1|0]-48|0;c=Fa-16|0;G[c+12>>2]=v;b=(b>>>0>1?(b<<2)-4|0:0)+v|0;G[c+8>>2]=b+4;l=G[b>>2];b=d+3|0;break l}l=G[v>>2];v=v+4|0;b=d+1|0}m=0;d=0;if(H[b|0]-48>>>0<10){while(1){d=(H[b|0]+M(d,10)|0)-48|0;c=H[b+1|0];b=b+1|0;if(c-48>>>0<10){continue}break}}o=H[b|0];if((o|0)==109){n=0;m=(l|0)!=0;o=H[b+1|0];a=0;b=b+1|0}c=b;b=c+1|0;f=3;g=m;q:{r:{switch(o-65|0){case 39:f=c+2|0;c=H[c+1|0]==104;b=c?f:b;f=c?-2:-1;break q;case 43:f=c+2|0;c=H[c+1|0]==108;b=c?f:b;f=c?3:1;break q;case 51:case 57:f=1;break q;case 11:f=2;break q;case 41:break q;case 0:case 2:case 4:case 5:case 6:case 18:case 23:case 26:case 32:case 34:case 35:case 36:case 37:case 38:case 40:case 45:case 46:case 47:case 50:case 52:case 55:break r;default:break e}}f=0;b=c}g=f;c=H[b|0];f=(c&47)==3;t=f?1:g;s=f?c|32:c;s:{if((s|0)==91){break s}t:{if((s|0)!=110){if((s|0)!=99){break t}d=(d|0)>1?d:1;break s}wm(l,t,r,p);break j}te(e,0,0);while(1){c=G[e+4>>2];u:{if((c|0)!=G[e+104>>2]){G[e+4>>2]=c+1;c=H[c|0];break u}c=jc(e)}if((c|0)==32|c-9>>>0<5){continue}break}c=G[e+4>>2];f=G[e+116>>2];if((f|0)>0|(f|0)>=0){c=c-1|0;G[e+4>>2]=c}c=c-G[e+44>>2]|0;f=c>>31;i=c;h=p+G[e+124>>2]|0;c=r+G[e+120>>2]|0;h=c>>>0>>0?h+1|0:h;g=c;c=i+c|0;p=f+h|0;p=c>>>0>>0?p+1|0:p;r=c}i=d;u=d>>31;te(e,d,u);c=G[e+4>>2];v:{if((c|0)!=G[e+104>>2]){G[e+4>>2]=c+1;break v}if((jc(e)|0)<0){break f}}c=G[e+116>>2];if((c|0)>0|(c|0)>=0){G[e+4>>2]=G[e+4>>2]-1}c=16;w:{x:{y:{z:{A:{switch(s-88|0){default:c=s-65|0;if(c>>>0>6|!(1<>2]-G[e+44>>2]|0;if(G[e+120>>2]!=(0-c|0)|G[e+124>>2]!=(0-((c>>31)+((c|0)!=0)|0)|0)){break y}break g;case 3:case 11:case 27:if((s|16)==115){cb(j+32|0,-1,257);E[j+32|0]=0;if((s|0)!=115){break x}E[j+65|0]=0;E[j+46|0]=0;F[j+42>>1]=0;F[j+44>>1]=0;break x}f=H[b+1|0];g=(f|0)==94;cb(j+32|0,g,257);E[j+32|0]=0;c=g?b+2|0:b+1|0;B:{C:{D:{b=H[(g?2:1)+b|0];if((b|0)!=45){if((b|0)==93){break D}f=(f|0)!=94;b=c;break B}f=(f|0)!=94;E[j+78|0]=f;break C}f=(f|0)!=94;E[j+126|0]=f}b=c+1|0}while(1){c=H[b|0];E:{if((c|0)!=45){if(!c){break f}if((c|0)==93){break x}break E}c=45;g=H[b+1|0];if(!g|(g|0)==93){break E}h=b+1|0;b=H[b-1|0];F:{if(g>>>0<=b>>>0){c=g;break F}while(1){b=b+1|0;E[b+(j+32|0)|0]=f;c=H[h|0];if(c>>>0>b>>>0){continue}break}}b=h}E[(c+j|0)+33|0]=f;b=b+1|0;continue};case 23:c=8;break z;case 12:case 29:c=10;break z;case 1:case 2:case 4:case 5:case 6:case 7:case 8:case 10:case 16:case 18:case 19:case 20:case 21:case 22:case 25:case 26:case 28:case 30:case 31:break w;case 0:case 24:case 32:break z;case 17:break A}}c=0}i=0;h=0;f=0;g=0;o=0;u=Fa-16|0;Fa=u;G:{if(!((c|0)!=1&c>>>0<=36)){G[48624]=28;break G}while(1){d=G[e+4>>2];H:{if((d|0)!=G[e+104>>2]){G[e+4>>2]=d+1;d=H[d|0];break H}d=jc(e)}if((d|0)==32|d-9>>>0<5){continue}break}I:{J:{switch(d-43|0){case 0:case 2:break J;default:break I}}o=(d|0)==45?-1:0;d=G[e+4>>2];if((d|0)!=G[e+104>>2]){G[e+4>>2]=d+1;d=H[d|0];break I}d=jc(e)}K:{L:{M:{N:{if(!((c|0)!=0&(c|0)!=16|(d|0)!=48)){d=G[e+4>>2];O:{if((d|0)!=G[e+104>>2]){G[e+4>>2]=d+1;d=H[d|0];break O}d=jc(e)}if((d&-33)==88){c=16;d=G[e+4>>2];P:{if((d|0)!=G[e+104>>2]){G[e+4>>2]=d+1;d=H[d|0];break P}d=jc(e)}if(H[d+96993|0]<16){break M}c=G[e+116>>2];if((c|0)>0|(c|0)>=0){G[e+4>>2]=G[e+4>>2]-1}te(e,0,0);break G}if(c){break N}c=8;break M}c=c?c:10;if(c>>>0>H[d+96993|0]){break N}c=G[e+116>>2];if((c|0)>0|(c|0)>=0){G[e+4>>2]=G[e+4>>2]-1}te(e,0,0);G[48624]=28;break G}if((c|0)!=10){break M}f=d-48|0;if(f>>>0<=9){c=0;while(1){c=M(c,10)+f|0;g=c>>>0<429496729;d=G[e+4>>2];Q:{if((d|0)!=G[e+104>>2]){G[e+4>>2]=d+1;d=H[d|0];break Q}d=jc(e)}f=d-48|0;if(g&f>>>0<=9){continue}break}i=c}R:{if(f>>>0>9){break R}g=Au(i,0,10,0);c=Ia;while(1){d=f+g|0;h=d>>>0>>0?c+1|0:c;i=d;g=(h|0)==429496729&d>>>0>=2576980378|h>>>0>429496729;c=G[e+4>>2];S:{if((c|0)!=G[e+104>>2]){G[e+4>>2]=c+1;d=H[c|0];break S}d=jc(e)}f=d-48|0;if(g|f>>>0>9){break R}g=Au(i,h,10,0);c=Ia;if((c|0)==-1&(f^-1)>>>0>=g>>>0|(c|0)!=-1){continue}break}c=10;break L}c=10;if(f>>>0<=9){break L}break K}if(c-1&c){g=H[d+96993|0];if(g>>>0>>0){while(1){f=M(c,f)+g|0;i=f>>>0<119304647;d=G[e+4>>2];T:{if((d|0)!=G[e+104>>2]){G[e+4>>2]=d+1;d=H[d|0];break T}d=jc(e)}g=H[d+96993|0];if(i&g>>>0>>0){continue}break}i=f}if(c>>>0<=g>>>0){break L}while(1){k=Au(i,h,c,0);f=Ia;g=g&255;if((f|0)==-1&(g^-1)>>>0>>0){break L}d=g+k|0;h=d>>>0>>0?f+1|0:f;i=d;d=G[e+4>>2];U:{if((d|0)!=G[e+104>>2]){G[e+4>>2]=d+1;d=H[d|0];break U}d=jc(e)}g=H[d+96993|0];if(c>>>0<=g>>>0){break L}ed(u,c,0,0,0,i,h,0,0);if(!(G[u+8>>2]|G[u+12>>2])){continue}break}break L}k=E[(M(c,23)>>>5&7)+97249|0];f=H[d+96993|0];if(f>>>0>>0){while(1){g=g<>>0<134217728;d=G[e+4>>2];V:{if((d|0)!=G[e+104>>2]){G[e+4>>2]=d+1;d=H[d|0];break V}d=jc(e)}f=H[d+96993|0];if(i&f>>>0>>0){continue}break}i=g}if(c>>>0<=f>>>0){break L}g=k;q=g&31;if((g&63)>>>0>=32){g=0;q=-1>>>q|0}else{g=-1>>>q|0;q=g|(1<>>0>q>>>0){break L}while(1){x=f&255;f=i;d=k&31;if((k&63)>>>0>=32){h=f<>>32-d|h<>2];W:{if((d|0)!=G[e+104>>2]){G[e+4>>2]=d+1;d=H[d|0];break W}d=jc(e)}f=H[d+96993|0];if(c>>>0<=f>>>0){break L}if((g|0)==(h|0)&i>>>0<=q>>>0|g>>>0>h>>>0){continue}break}}if(H[d+96993|0]>=c>>>0){break K}while(1){d=G[e+4>>2];X:{if((d|0)!=G[e+104>>2]){G[e+4>>2]=d+1;d=H[d|0];break X}d=jc(e)}if(H[d+96993|0]>>0){continue}break}G[48624]=68;o=0;i=-1;h=-1}c=G[e+116>>2];if((c|0)>0|(c|0)>=0){G[e+4>>2]=G[e+4>>2]-1}Y:{if((h&i)!=-1){break Y}}c=o;d=c^i;i=d-c|0;f=c>>31;h=(f^h)-((c>>>0>d>>>0)+f|0)|0}Fa=u+16|0;c=G[e+4>>2]-G[e+44>>2]|0;if(G[e+120>>2]==(0-c|0)&G[e+124>>2]==(0-((c>>31)+((c|0)!=0)|0)|0)){break g}if(!(!l|(s|0)!=112)){G[l>>2]=i;break w}wm(l,t,i,h);break w}if(!l){break w}d=G[j+16>>2];c=G[j+20>>2];i=G[j+8>>2];m=G[j+12>>2];Z:{switch(t|0){case 0:h=Fa-32|0;Fa=h;f=c&2147483647;g=f-1065418752|0;k=f-1082064896|0;_:{if((g|0)==(k|0)&0|g>>>0>>0){f=(c&33554431)<<7|d>>>25;g=0;o=g;k=d&33554431;if(!(!g&(k|0)==16777216?!(i|m):!g&k>>>0<16777216)){g=f+1073741825|0;break _}g=f+1073741824|0;if(k^16777216|i|(m|o)){break _}g=(f&1)+g|0;break _}if(!(!d&(f|0)==2147418112?!(i|m):f>>>0<2147418112)){g=((c&33554431)<<7|d>>>25)&4194303|2143289344;break _}g=2139095040;if(f>>>0>1082064895){break _}g=0;f=f>>>16|0;if(f>>>0<16145){break _}g=c&65535|65536;od(h+16|0,i,m,d,g,f-16129|0);eg(h,i,m,d,g,16257-f|0);i=G[h+8>>2];g=(G[h+12>>2]&33554431)<<7|i>>>25;k=G[h>>2]|(G[h+16>>2]|G[h+24>>2]|(G[h+20>>2]|G[h+28>>2]))!=0;m=G[h+4>>2];f=0;i=i&33554431;if(!(!f&(i|0)==16777216?!(k|m):!f&i>>>0<16777216)){g=g+1|0;break _}if(i^16777216|k|(f|m)){break _}g=(g&1)+g|0}Fa=h+32|0;G[l>>2]=c&-2147483648|g;break w;case 1:A=l,B=Ui(i,m,d,c),L[A>>3]=B;break w;case 2:break Z;default:break w}}G[l>>2]=i;G[l+4>>2]=m;G[l+8>>2]=d;G[l+12>>2]=c;break w}x=(s|0)==99;f=x?d+1|0:31;$:{if((t|0)==1){c=l;if(m){c=ab(f<<2);if(!c){break h}}G[j+296>>2]=0;G[j+300>>2]=0;d=0;while(1){a=c;aa:{while(1){c=G[e+4>>2];ba:{if((c|0)!=G[e+104>>2]){G[e+4>>2]=c+1;c=H[c|0];break ba}c=jc(e)}if(!H[(c+j|0)+33|0]){break aa}E[j+27|0]=c;k=j+28|0;n=0;t=Fa-16|0;Fa=t;c=j+296|0;h=c?c:195176;c=G[h>>2];ca:{da:{g=j+27|0;ea:{if(!g){if(c){break ea}break ca}n=-2;k=k?k:t+12|0;fa:{if(c){o=1;break fa}c=H[g|0];o=c<<24>>24;if((o|0)>=0){G[k>>2]=c;n=(o|0)!=0;break ca}c=E[g|0];if(!G[G[48787]>>2]){G[k>>2]=c&57343;n=1;break ca}c=(c&255)-194|0;if(c>>>0>50){break ea}c=G[(c<<2)+97264>>2];break da}q=H[g|0];z=q>>>3|0;if((z-16|(c>>26)+z)>>>0>7){break ea}while(1){o=o-1|0;c=q-128|c<<6;if((c|0)>=0){G[h>>2]=0;G[k>>2]=c;n=1-o|0;break ca}if(!o){break da}g=g+1|0;q=H[g|0];if((q&192)==128){continue}break}}G[h>>2]=0;G[48624]=25;n=-1;break ca}G[h>>2]=c}Fa=t+16|0;c=n;if((c|0)==-2){continue}n=0;if((c|0)==-1){break f}if(a){G[(d<<2)+a>>2]=G[j+28>>2];d=d+1|0}if(!((d|0)==(f|0)&m)){continue}break}g=1;f=f<<1|1;c=ub(a,f<<2);if(c){continue}break e}break}n=0;f=a;if(j+296|0?G[j+296>>2]:0){break f}break $}if(m){d=0;c=ab(f);if(!c){break h}while(1){a=c;while(1){c=G[e+4>>2];ga:{if((c|0)!=G[e+104>>2]){G[e+4>>2]=c+1;c=H[c|0];break ga}c=jc(e)}if(!H[(c+j|0)+33|0]){f=0;n=a;break $}E[a+d|0]=c;d=d+1|0;if((f|0)!=(d|0)){continue}break}g=1;f=f<<1|1;c=ub(a,f);if(c){continue}break}n=a;a=0;break e}d=0;if(l){while(1){a=G[e+4>>2];ha:{if((a|0)!=G[e+104>>2]){G[e+4>>2]=a+1;a=H[a|0];break ha}a=jc(e)}if(H[(a+j|0)+33|0]){E[d+l|0]=a;d=d+1|0;continue}else{f=0;a=l;n=a;break $}}}while(1){a=G[e+4>>2];ia:{if((a|0)!=G[e+104>>2]){G[e+4>>2]=a+1;a=H[a|0];break ia}a=jc(e)}if(H[(a+j|0)+33|0]){continue}break}a=0;n=0;f=0}c=G[e+4>>2];g=G[e+116>>2];if((g|0)>0|(g|0)>=0){c=c-1|0;G[e+4>>2]=c}g=c-G[e+44>>2]|0;c=g+G[e+120>>2]|0;h=G[e+124>>2]+(g>>31)|0;h=c>>>0>>0?h+1|0:h;if(!(h|c)|((c|0)!=(i|0)|(h|0)!=(u|0))&(s|0)==99){break i}if(m){G[l>>2]=a}ja:{if(x){break ja}if(f){G[(d<<2)+f>>2]=0}if(!n){n=0;break ja}E[d+n|0]=0}a=f}c=G[e+4>>2]-G[e+44>>2]|0;d=c>>31;i=c;g=p+G[e+124>>2]|0;c=r+G[e+120>>2]|0;g=c>>>0>>0?g+1|0:g;f=c;c=i+c|0;p=d+g|0;p=c>>>0>>0?p+1|0:p;r=c;w=((l|0)!=0)+w|0}d=b+1|0;b=H[b+1|0];if(b){continue}break a}break}a=f;break g}g=1;n=0;a=0;break e}g=m;break b}g=m}if(w){break b}}w=-1}if(!g){break a}Wa(n);Wa(a)}Fa=j+304|0;Fa=e+144|0;Fa=y+16|0;return w}function ab(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;l=Fa-16|0;Fa=l;a:{b:{c:{d:{e:{f:{g:{h:{i:{j:{k:{if(a>>>0<=244){e=G[48625];h=a>>>0<11?16:a+11&-8;c=h>>>3|0;b=e>>>c|0;if(b&3){c=c+((b^-1)&1)|0;a=c<<3;b=a+194540|0;d=G[a+194548>>2];a=G[d+8>>2];l:{if((b|0)==(a|0)){m=194500,n=Eu(-2,c)&e,G[m>>2]=n;break l}G[a+12>>2]=b;G[b+8>>2]=a}a=d+8|0;b=c<<3;G[d+4>>2]=b|3;b=b+d|0;G[b+4>>2]=G[b+4>>2]|1;break a}k=G[48627];if(k>>>0>=h>>>0){break k}if(b){a=2<>>12&16;c=a;b=b>>>a|0;a=b>>>5&8;c=c|a;b=b>>>a|0;a=b>>>2&4;c=c|a;b=b>>>a|0;a=b>>>1&2;c=c|a;b=b>>>a|0;a=b>>>1&1;d=(c|a)+(b>>>a|0)|0;a=d<<3;b=a+194540|0;g=G[a+194548>>2];a=G[g+8>>2];m:{if((b|0)==(a|0)){e=Eu(-2,d)&e;G[48625]=e;break m}G[a+12>>2]=b;G[b+8>>2]=a}G[g+4>>2]=h|3;c=g+h|0;a=d<<3;d=a-h|0;G[c+4>>2]=d|1;G[a+g>>2]=d;if(k){b=(k&-8)+194540|0;f=G[48630];a=1<<(k>>>3);n:{if(!(a&e)){G[48625]=a|e;a=b;break n}a=G[b+8>>2]}G[b+8>>2]=f;G[a+12>>2]=f;G[f+12>>2]=b;G[f+8>>2]=a}a=g+8|0;G[48630]=c;G[48627]=d;break a}j=G[48626];if(!j){break k}b=(0-j&j)-1|0;a=b>>>12&16;c=a;b=b>>>a|0;a=b>>>5&8;c=c|a;b=b>>>a|0;a=b>>>2&4;c=c|a;b=b>>>a|0;a=b>>>1&2;c=c|a;b=b>>>a|0;a=b>>>1&1;c=G[((c|a)+(b>>>a|0)<<2)+194804>>2];f=(G[c+4>>2]&-8)-h|0;b=c;while(1){o:{a=G[b+16>>2];if(!a){a=G[b+20>>2];if(!a){break o}}b=(G[a+4>>2]&-8)-h|0;d=b>>>0>>0;f=d?b:f;c=d?a:c;b=a;continue}break}i=G[c+24>>2];d=G[c+12>>2];if((d|0)!=(c|0)){a=G[c+8>>2];G[a+12>>2]=d;G[d+8>>2]=a;break b}b=c+20|0;a=G[b>>2];if(!a){a=G[c+16>>2];if(!a){break j}b=c+16|0}while(1){g=b;d=a;b=a+20|0;a=G[b>>2];if(a){continue}b=d+16|0;a=G[d+16>>2];if(a){continue}break}G[g>>2]=0;break b}h=-1;if(a>>>0>4294967231){break k}a=a+11|0;h=a&-8;j=G[48626];if(!j){break k}f=0-h|0;e=0;p:{if(h>>>0<256){break p}e=31;if(h>>>0>16777215){break p}a=a>>>8|0;g=a+1048320>>>16&8;a=a<>>16&4;a=a<>>16&2;a=(a<>>15|0)-(b|(c|g))|0;e=(a<<1|h>>>a+21&1)+28|0}b=G[(e<<2)+194804>>2];q:{r:{s:{if(!b){a=0;break s}a=0;c=h<<((e|0)==31?0:25-(e>>>1|0)|0);while(1){t:{g=(G[b+4>>2]&-8)-h|0;if(g>>>0>=f>>>0){break t}d=b;f=g;if(f){break t}f=0;a=b;break r}g=G[b+20>>2];b=G[((c>>>29&4)+b|0)+16>>2];a=g?(g|0)==(b|0)?a:g:a;c=c<<1;if(b){continue}break}}if(!(a|d)){d=0;a=2<>>12&16;c=a;b=b>>>a|0;a=b>>>5&8;c=c|a;b=b>>>a|0;a=b>>>2&4;c=c|a;b=b>>>a|0;a=b>>>1&2;c=c|a;b=b>>>a|0;a=b>>>1&1;a=G[((c|a)+(b>>>a|0)<<2)+194804>>2]}if(!a){break q}}while(1){b=(G[a+4>>2]&-8)-h|0;c=b>>>0>>0;f=c?b:f;d=c?a:d;b=G[a+16>>2];if(b){a=b}else{a=G[a+20>>2]}if(a){continue}break}}if(!d|G[48627]-h>>>0<=f>>>0){break k}e=G[d+24>>2];c=G[d+12>>2];if((d|0)!=(c|0)){a=G[d+8>>2];G[a+12>>2]=c;G[c+8>>2]=a;break c}b=d+20|0;a=G[b>>2];if(!a){a=G[d+16>>2];if(!a){break i}b=d+16|0}while(1){g=b;c=a;b=a+20|0;a=G[b>>2];if(a){continue}b=c+16|0;a=G[c+16>>2];if(a){continue}break}G[g>>2]=0;break c}c=G[48627];if(c>>>0>=h>>>0){d=G[48630];b=c-h|0;u:{if(b>>>0>=16){G[48627]=b;a=d+h|0;G[48630]=a;G[a+4>>2]=b|1;G[c+d>>2]=b;G[d+4>>2]=h|3;break u}G[48630]=0;G[48627]=0;G[d+4>>2]=c|3;a=c+d|0;G[a+4>>2]=G[a+4>>2]|1}a=d+8|0;break a}i=G[48628];if(i>>>0>h>>>0){b=i-h|0;G[48628]=b;c=G[48631];a=c+h|0;G[48631]=a;G[a+4>>2]=b|1;G[c+4>>2]=h|3;a=c+8|0;break a}a=0;j=h+47|0;if(G[48743]){c=G[48745]}else{G[48746]=-1;G[48747]=-1;G[48744]=4096;G[48745]=4096;G[48743]=l+12&-16^1431655768;G[48748]=0;G[48736]=0;c=4096}g=j+c|0;f=0-c|0;b=g&f;if(b>>>0<=h>>>0){break a}d=G[48735];if(d){c=G[48733];e=c+b|0;if(d>>>0>>0|c>>>0>=e>>>0){break a}}if(H[194944]&4){break f}v:{w:{d=G[48631];if(d){a=194948;while(1){c=G[a>>2];if(c>>>0<=d>>>0&d>>>0>2]>>>0){break w}a=G[a+8>>2];if(a){continue}break}}c=gg(0);if((c|0)==-1){break g}e=b;d=G[48744];a=d-1|0;if(a&c){e=(b-c|0)+(a+c&0-d)|0}if(e>>>0<=h>>>0|e>>>0>2147483646){break g}d=G[48735];if(d){a=G[48733];f=a+e|0;if(d>>>0>>0|a>>>0>=f>>>0){break g}}a=gg(e);if((c|0)!=(a|0)){break v}break e}e=f&g-i;if(e>>>0>2147483646){break g}c=gg(e);if((c|0)==(G[a>>2]+G[a+4>>2]|0)){break h}a=c}if(!((a|0)==-1|h+48>>>0<=e>>>0)){c=G[48745];c=c+(j-e|0)&0-c;if(c>>>0>2147483646){c=a;break e}if((gg(c)|0)!=-1){e=c+e|0;c=a;break e}gg(0-e|0);break g}c=a;if((a|0)!=-1){break e}break g}d=0;break b}c=0;break c}if((c|0)!=-1){break e}}G[48736]=G[48736]|4}if(b>>>0>2147483646){break d}c=gg(b);a=gg(0);if((c|0)==-1|(a|0)==-1|a>>>0<=c>>>0){break d}e=a-c|0;if(e>>>0<=h+40>>>0){break d}}a=G[48733]+e|0;G[48733]=a;if(a>>>0>J[48734]){G[48734]=a}x:{y:{z:{g=G[48631];if(g){a=194948;while(1){d=G[a>>2];b=G[a+4>>2];if((d+b|0)==(c|0)){break z}a=G[a+8>>2];if(a){continue}break}break y}a=G[48629];if(!(a>>>0<=c>>>0?a:0)){G[48629]=c}a=0;G[48738]=e;G[48737]=c;G[48633]=-1;G[48634]=G[48743];G[48740]=0;while(1){d=a<<3;b=d+194540|0;G[d+194548>>2]=b;G[d+194552>>2]=b;a=a+1|0;if((a|0)!=32){continue}break}d=e-40|0;a=c+8&7?-8-c&7:0;b=d-a|0;G[48628]=b;a=a+c|0;G[48631]=a;G[a+4>>2]=b|1;G[(c+d|0)+4>>2]=40;G[48632]=G[48747];break x}if(H[a+12|0]&8|d>>>0>g>>>0|c>>>0<=g>>>0){break y}G[a+4>>2]=b+e;a=g+8&7?-8-g&7:0;c=a+g|0;G[48631]=c;b=G[48628]+e|0;a=b-a|0;G[48628]=a;G[c+4>>2]=a|1;G[(b+g|0)+4>>2]=40;G[48632]=G[48747];break x}if(J[48629]>c>>>0){G[48629]=c}b=c+e|0;a=194948;A:{B:{C:{D:{E:{F:{while(1){if((b|0)!=G[a>>2]){a=G[a+8>>2];if(a){continue}break F}break}if(!(H[a+12|0]&8)){break E}}a=194948;while(1){b=G[a>>2];if(b>>>0<=g>>>0){f=b+G[a+4>>2]|0;if(f>>>0>g>>>0){break D}}a=G[a+8>>2];continue}}G[a>>2]=c;G[a+4>>2]=G[a+4>>2]+e;j=(c+8&7?-8-c&7:0)+c|0;G[j+4>>2]=h|3;e=b+(b+8&7?-8-b&7:0)|0;i=h+j|0;a=e-i|0;if((e|0)==(g|0)){G[48631]=i;a=G[48628]+a|0;G[48628]=a;G[i+4>>2]=a|1;break B}if(G[48630]==(e|0)){G[48630]=i;a=G[48627]+a|0;G[48627]=a;G[i+4>>2]=a|1;G[a+i>>2]=a;break B}f=G[e+4>>2];if((f&3)==1){g=f&-8;G:{if(f>>>0<=255){d=G[e+8>>2];b=f>>>3|0;c=G[e+12>>2];if((c|0)==(d|0)){m=194500,n=G[48625]&Eu(-2,b),G[m>>2]=n;break G}G[d+12>>2]=c;G[c+8>>2]=d;break G}h=G[e+24>>2];c=G[e+12>>2];H:{if((e|0)!=(c|0)){b=G[e+8>>2];G[b+12>>2]=c;G[c+8>>2]=b;break H}I:{f=e+20|0;b=G[f>>2];if(b){break I}f=e+16|0;b=G[f>>2];if(b){break I}c=0;break H}while(1){d=f;c=b;f=b+20|0;b=G[f>>2];if(b){continue}f=c+16|0;b=G[c+16>>2];if(b){continue}break}G[d>>2]=0}if(!h){break G}d=G[e+28>>2];b=(d<<2)+194804|0;J:{if(G[b>>2]==(e|0)){G[b>>2]=c;if(c){break J}m=194504,n=G[48626]&Eu(-2,d),G[m>>2]=n;break G}G[h+(G[h+16>>2]==(e|0)?16:20)>>2]=c;if(!c){break G}}G[c+24>>2]=h;b=G[e+16>>2];if(b){G[c+16>>2]=b;G[b+24>>2]=c}b=G[e+20>>2];if(!b){break G}G[c+20>>2]=b;G[b+24>>2]=c}e=e+g|0;f=G[e+4>>2];a=a+g|0}G[e+4>>2]=f&-2;G[i+4>>2]=a|1;G[a+i>>2]=a;if(a>>>0<=255){b=(a&-8)+194540|0;c=G[48625];a=1<<(a>>>3);K:{if(!(c&a)){G[48625]=a|c;a=b;break K}a=G[b+8>>2]}G[b+8>>2]=i;G[a+12>>2]=i;G[i+12>>2]=b;G[i+8>>2]=a;break B}f=31;if(a>>>0<=16777215){b=a>>>8|0;f=b+1048320>>>16&8;b=b<>>16&4;b=b<>>16&2;b=(b<>>15|0)-(c|(d|f))|0;f=(b<<1|a>>>b+21&1)+28|0}G[i+28>>2]=f;G[i+16>>2]=0;G[i+20>>2]=0;b=(f<<2)+194804|0;d=G[48626];c=1<>2]=i;break L}f=a<<((f|0)==31?0:25-(f>>>1|0)|0);c=G[b>>2];while(1){b=c;if((G[b+4>>2]&-8)==(a|0)){break C}c=f>>>29|0;f=f<<1;d=(c&4)+b|0;c=G[d+16>>2];if(c){continue}break}G[d+16>>2]=i}G[i+24>>2]=b;G[i+12>>2]=i;G[i+8>>2]=i;break B}d=e-40|0;a=c+8&7?-8-c&7:0;b=d-a|0;G[48628]=b;a=a+c|0;G[48631]=a;G[a+4>>2]=b|1;G[(c+d|0)+4>>2]=40;G[48632]=G[48747];a=(f+(f-39&7?39-f&7:0)|0)-47|0;d=a>>>0>>0?g:a;G[d+4>>2]=27;a=G[48740];G[d+16>>2]=G[48739];G[d+20>>2]=a;a=G[48738];G[d+8>>2]=G[48737];G[d+12>>2]=a;G[48739]=d+8;G[48738]=e;G[48737]=c;G[48740]=0;a=d+24|0;while(1){G[a+4>>2]=7;b=a+8|0;a=a+4|0;if(b>>>0>>0){continue}break}if((d|0)==(g|0)){break x}G[d+4>>2]=G[d+4>>2]&-2;f=d-g|0;G[g+4>>2]=f|1;G[d>>2]=f;if(f>>>0<=255){b=(f&-8)+194540|0;c=G[48625];a=1<<(f>>>3);M:{if(!(c&a)){G[48625]=a|c;a=b;break M}a=G[b+8>>2]}G[b+8>>2]=g;G[a+12>>2]=g;G[g+12>>2]=b;G[g+8>>2]=a;break x}a=31;if(f>>>0<=16777215){a=f>>>8|0;d=a+1048320>>>16&8;a=a<>>16&4;a=a<>>16&2;a=(a<>>15|0)-(b|(c|d))|0;a=(a<<1|f>>>a+21&1)+28|0}G[g+28>>2]=a;G[g+16>>2]=0;G[g+20>>2]=0;b=(a<<2)+194804|0;d=G[48626];c=1<>2]=g;break N}a=f<<((a|0)==31?0:25-(a>>>1|0)|0);d=G[b>>2];while(1){b=d;if((f|0)==(G[b+4>>2]&-8)){break A}c=a>>>29|0;a=a<<1;c=(c&4)+b|0;d=G[c+16>>2];if(d){continue}break}G[c+16>>2]=g}G[g+24>>2]=b;G[g+12>>2]=g;G[g+8>>2]=g;break x}a=G[b+8>>2];G[a+12>>2]=i;G[b+8>>2]=i;G[i+24>>2]=0;G[i+12>>2]=b;G[i+8>>2]=a}a=j+8|0;break a}a=G[b+8>>2];G[a+12>>2]=g;G[b+8>>2]=g;G[g+24>>2]=0;G[g+12>>2]=b;G[g+8>>2]=a}a=G[48628];if(a>>>0<=h>>>0){break d}b=a-h|0;G[48628]=b;c=G[48631];a=c+h|0;G[48631]=a;G[a+4>>2]=b|1;G[c+4>>2]=h|3;a=c+8|0;break a}G[48624]=48;a=0;break a}O:{if(!e){break O}b=G[d+28>>2];a=(b<<2)+194804|0;P:{if(G[a>>2]==(d|0)){G[a>>2]=c;if(c){break P}j=Eu(-2,b)&j;G[48626]=j;break O}G[e+(G[e+16>>2]==(d|0)?16:20)>>2]=c;if(!c){break O}}G[c+24>>2]=e;a=G[d+16>>2];if(a){G[c+16>>2]=a;G[a+24>>2]=c}a=G[d+20>>2];if(!a){break O}G[c+20>>2]=a;G[a+24>>2]=c}Q:{if(f>>>0<=15){a=f+h|0;G[d+4>>2]=a|3;a=a+d|0;G[a+4>>2]=G[a+4>>2]|1;break Q}G[d+4>>2]=h|3;e=d+h|0;G[e+4>>2]=f|1;G[e+f>>2]=f;if(f>>>0<=255){b=(f&-8)+194540|0;c=G[48625];a=1<<(f>>>3);R:{if(!(c&a)){G[48625]=a|c;a=b;break R}a=G[b+8>>2]}G[b+8>>2]=e;G[a+12>>2]=e;G[e+12>>2]=b;G[e+8>>2]=a;break Q}a=31;if(f>>>0<=16777215){a=f>>>8|0;g=a+1048320>>>16&8;a=a<>>16&4;a=a<>>16&2;a=(a<>>15|0)-(b|(c|g))|0;a=(a<<1|f>>>a+21&1)+28|0}G[e+28>>2]=a;G[e+16>>2]=0;G[e+20>>2]=0;b=(a<<2)+194804|0;S:{c=1<>2]=e;break T}a=f<<((a|0)==31?0:25-(a>>>1|0)|0);h=G[b>>2];while(1){b=h;if((G[b+4>>2]&-8)==(f|0)){break S}c=a>>>29|0;a=a<<1;c=(c&4)+b|0;h=G[c+16>>2];if(h){continue}break}G[c+16>>2]=e}G[e+24>>2]=b;G[e+12>>2]=e;G[e+8>>2]=e;break Q}a=G[b+8>>2];G[a+12>>2]=e;G[b+8>>2]=e;G[e+24>>2]=0;G[e+12>>2]=b;G[e+8>>2]=a}a=d+8|0;break a}U:{if(!i){break U}b=G[c+28>>2];a=(b<<2)+194804|0;V:{if(G[a>>2]==(c|0)){G[a>>2]=d;if(d){break V}m=194504,n=Eu(-2,b)&j,G[m>>2]=n;break U}G[i+(G[i+16>>2]==(c|0)?16:20)>>2]=d;if(!d){break U}}G[d+24>>2]=i;a=G[c+16>>2];if(a){G[d+16>>2]=a;G[a+24>>2]=d}a=G[c+20>>2];if(!a){break U}G[d+20>>2]=a;G[a+24>>2]=d}W:{if(f>>>0<=15){a=f+h|0;G[c+4>>2]=a|3;a=a+c|0;G[a+4>>2]=G[a+4>>2]|1;break W}G[c+4>>2]=h|3;d=c+h|0;G[d+4>>2]=f|1;G[d+f>>2]=f;if(k){b=(k&-8)+194540|0;g=G[48630];a=1<<(k>>>3);X:{if(!(a&e)){G[48625]=a|e;a=b;break X}a=G[b+8>>2]}G[b+8>>2]=g;G[a+12>>2]=g;G[g+12>>2]=b;G[g+8>>2]=a}G[48630]=d;G[48627]=f}a=c+8|0}Fa=l+16|0;return a|0}function ae(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=N(0),C=N(0),D=0,I=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=N(0);p=Fa-29104|0;Fa=p;q=G[o>>2];a:{if(!(g|h)|(q|0)>0){break a}if(n){G[n>>2]=0}if((j|0)==2){cb(m,0,g)}if((yc(a,b,c,d,e,f,g,h,i>>31,p+29096|0,p+29088|0,p+28992|0,p+29064|0,p+29084|0,p+29080|0,p+29040|0,p+29032|0,p+29060|0,p+29048|0,p+29016|0,p+29076|0,p+29024|0,p+28864|0,o)|0)>0){q=G[o>>2];break a}G[p+29060>>2]=M(G[p+29060>>2],i);D=1;c=G[p+29080>>2];R=c;S=c>>31;b:{if(G[p+29084>>2]!=16){break b}Gd(p+28992|0,p+29072|0,p+29056|0,p+29068|0,o);c=G[p+29068>>2];if((c|0)<=0){break b}if(c-1>>>0>=7){d=c&-8;while(1){D=D*10*10*10*10*10*10*10*10;z=z+8|0;if((d|0)!=(z|0)){continue}break}}c=c&7;if(!c){break b}z=0;while(1){D=D*10;z=z+1|0;if((c|0)!=(z|0)){continue}break}}z=0;d=G[p+29084>>2];c:{d:{if((j|0)==1&k==N(0)){break d}e=G[p+29028>>2];c=G[p+29024>>2];if(!e&(c|0)==1234554321&((d|0)%10|0)==1){break d}if(!((e-(c>>>0<32768)|0)==-1&c-32768>>>0>=4294901760|(d|0)!=21)){P=0;break c}P=0;if(!(!e&c>>>0<=255|(d|0)!=11)){break c}z=(d|0)==16?H[p+28864|0]==1?0:j:j}P=0;if((d|0)!=42){break c}c=g>>>0<536870911&(h|0)<=0|(h|0)<0;R=c?g:536870911;S=c?h:0;P=!z&L[p+29096>>3]==1&L[p+29088>>3]==0}W=0-i|0;e=0;f=0;e:{while(1){d=g>>>0>>0&(h|0)<=(S|0)|(h|0)<(S|0)?g:R;c=d;q=c>>31;u=c;f:{if((i|0)>=0){c=G[p+29036>>2];s=c;c=G[p+29052>>2]+(c^-1)|0;v=G[p+29032>>2];j=v^-1;d=j+G[p+29048>>2]|0;c=Bu(d,d>>>0>>0?c+1|0:c,i,0);d=Ia;break f}v=G[p+29032>>2];s=G[p+29036>>2];c=Bu(v,s,W,0);d=Ia}t=c;j=G[p+29044>>2];c=G[p+29040>>2];r=Au(G[p+29016>>2],G[p+29020>>2],I,O);c=c+r|0;j=Ia+j|0;j=c>>>0>>0?j+1|0:j;T=c;r=G[p+29060>>2];c=(r|0)/(i|0)|0;v=Au(v,s,c,c>>31);s=T+v|0;c=Ia+j|0;c=v>>>0>s>>>0?c+1|0:c;v=s;j=c;c=d;s=t+1|0;d=(d|0)<=(q|0)&u>>>0>t>>>0|(d|0)<(q|0);u=d?s:u;g:{h:{i:{j:{k:{l:{m:{n:{o:{p:{c=G[p+29084>>2];switch(c-11|0){case 0:break h;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break i;case 5:break j;case 30:break m;case 10:break n;case 31:break o;default:break p}}switch(c-81|0){case 1:break k;case 0:break l;default:break i}}c=(e<<2)+l|0;Uc(a,v,j,u,r,c,o);if(P){break g}gl(c,u,L[p+29096>>3],L[p+29088>>3],z,k,e+m|0,n,c);break g}c=p- -64|0;Pe(a,v,j,u,r,c,o);jq(c,u,L[p+29096>>3],L[p+29088>>3],z,F[p+29024>>1],k,e+m|0,n,(e<<2)+l|0);break g}c=p- -64|0;Uc(a,v,j,u,r,c,o);fl(c,u,L[p+29096>>3],L[p+29088>>3],z,G[p+29024>>2],k,e+m|0,n,(e<<2)+l|0);break g}c=j;j=p- -64|0;Tc(a,v,c,u,r,j,o);q=G[p+29024>>2];v=G[p+29028>>2];C=k;r=e+m|0;d=(e<<2)+l|0;x=L[p+29096>>3];A=L[p+29088>>3];c=x==1&A==0x8000000000000000;q:{if(!z){if(c){if((u|0)<=0){break q}q=0;c=0;if(u-1>>>0>=3){v=u&-4;t=0;while(1){r=j+(c<<3)|0;K[d+(c<<2)>>2]=+J[r>>2]+ +((G[r+4>>2]^-2147483648)>>>0)*4294967296;r=c|1;s=d+(r<<2)|0;r=j+(r<<3)|0;K[s>>2]=+J[r>>2]+ +((G[r+4>>2]^-2147483648)>>>0)*4294967296;r=c|2;s=d+(r<<2)|0;r=j+(r<<3)|0;K[s>>2]=+J[r>>2]+ +((G[r+4>>2]^-2147483648)>>>0)*4294967296;r=c|3;s=d+(r<<2)|0;r=j+(r<<3)|0;K[s>>2]=+J[r>>2]+ +((G[r+4>>2]^-2147483648)>>>0)*4294967296;c=c+4|0;t=t+4|0;if((v|0)!=(t|0)){continue}break}}t=u&3;if(!t){break q}while(1){v=j+(c<<3)|0;K[d+(c<<2)>>2]=+J[v>>2]+ +((G[v+4>>2]^-2147483648)>>>0)*4294967296;c=c+1|0;q=q+1|0;if((t|0)!=(q|0)){continue}break}break q}if(!(x==1&A==0)){if((u|0)<=0){break q}c=0;if((u|0)!=1){q=u&-2;t=0;while(1){v=j+(c<<3)|0;K[d+(c<<2)>>2]=(+J[v>>2]+ +G[v+4>>2]*4294967296)*x+A;v=c|1;s=d+(v<<2)|0;v=j+(v<<3)|0;K[s>>2]=(+J[v>>2]+ +G[v+4>>2]*4294967296)*x+A;c=c+2|0;t=t+2|0;if((q|0)!=(t|0)){continue}break}}if(!(u&1)){break q}d=d+(c<<2)|0;c=j+(c<<3)|0;K[d>>2]=(+J[c>>2]+ +G[c+4>>2]*4294967296)*x+A;break q}if((u|0)<=0){break q}q=0;c=0;if(u-1>>>0>=3){v=u&-4;t=0;while(1){r=j+(c<<3)|0;K[d+(c<<2)>>2]=+J[r>>2]+ +G[r+4>>2]*4294967296;r=c|1;s=d+(r<<2)|0;r=j+(r<<3)|0;K[s>>2]=+J[r>>2]+ +G[r+4>>2]*4294967296;r=c|2;s=d+(r<<2)|0;r=j+(r<<3)|0;K[s>>2]=+J[r>>2]+ +G[r+4>>2]*4294967296;r=c|3;s=d+(r<<2)|0;r=j+(r<<3)|0;K[s>>2]=+J[r>>2]+ +G[r+4>>2]*4294967296;c=c+4|0;t=t+4|0;if((v|0)!=(t|0)){continue}break}}t=u&3;if(!t){break q}while(1){v=j+(c<<3)|0;K[d+(c<<2)>>2]=+J[v>>2]+ +G[v+4>>2]*4294967296;c=c+1|0;q=q+1|0;if((t|0)!=(q|0)){continue}break}break q}if(c){if((u|0)<=0){break q}c=0;while(1){t=j+(c<<3)|0;s=G[t>>2];t=G[t+4>>2];r:{if((s|0)==(q|0)&(t|0)==(v|0)){G[n>>2]=1;if((z|0)==1){K[d+(c<<2)>>2]=C;break r}E[c+r|0]=1;break r}K[d+(c<<2)>>2]=+(s>>>0)+ +((t^-2147483648)>>>0)*4294967296}c=c+1|0;if((u|0)!=(c|0)){continue}break}break q}s:{if(!(x==1&A==0)){if((u|0)<=0){break q}if((z|0)==1){break s}c=0;while(1){t=j+(c<<3)|0;s=G[t>>2];t=G[t+4>>2];t:{if((s|0)==(q|0)&(t|0)==(v|0)){G[n>>2]=1;E[c+r|0]=1;break t}K[d+(c<<2)>>2]=(+(s>>>0)+ +(t|0)*4294967296)*x+A}c=c+1|0;if((u|0)!=(c|0)){continue}break}break q}if((u|0)<=0){break q}if((z|0)!=1){c=0;if((u|0)!=1){w=u&-2;t=0;while(1){s=j+(c<<3)|0;y=G[s>>2];s=G[s+4>>2];u:{if((y|0)==(q|0)&(s|0)==(v|0)){G[n>>2]=1;E[c+r|0]=1;break u}K[d+(c<<2)>>2]=+(y>>>0)+ +(s|0)*4294967296}s=c|1;y=j+(s<<3)|0;Q=G[y>>2];y=G[y+4>>2];v:{if((Q|0)!=(q|0)|(y|0)!=(v|0)){K[d+(s<<2)>>2]=+(Q>>>0)+ +(y|0)*4294967296;break v}G[n>>2]=1;E[r+s|0]=1}c=c+2|0;t=t+2|0;if((w|0)!=(t|0)){continue}break}}if(!(u&1)){break q}t=q;j=j+(c<<3)|0;q=G[j>>2];j=G[j+4>>2];if((t|0)!=(q|0)|(j|0)!=(v|0)){K[d+(c<<2)>>2]=+(q>>>0)+ +(j|0)*4294967296;break q}G[n>>2]=1;E[c+r|0]=1;break q}c=0;if((u|0)!=1){r=u&-2;t=0;while(1){s=d+(c<<2)|0;w=j+(c<<3)|0;y=G[w>>2];w=G[w+4>>2];w:{if((y|0)!=(q|0)|(w|0)!=(v|0)){B=N(+(y>>>0)+ +(w|0)*4294967296);break w}G[n>>2]=1;B=C}K[s>>2]=B;s=c|1;w=j+(s<<3)|0;y=G[w>>2];w=G[w+4>>2];x:{if((y|0)!=(q|0)|(w|0)!=(v|0)){B=N(+(y>>>0)+ +(w|0)*4294967296);break x}G[n>>2]=1;B=C}K[d+(s<<2)>>2]=B;c=c+2|0;t=t+2|0;if((r|0)!=(t|0)){continue}break}}if(!(u&1)){break q}t=q;j=j+(c<<3)|0;q=G[j>>2];j=G[j+4>>2];y:{if((t|0)!=(q|0)|(j|0)!=(v|0)){C=N(+(q>>>0)+ +(j|0)*4294967296);break y}G[n>>2]=1}K[d+(c<<2)>>2]=C;break q}c=0;if((u|0)!=1){r=u&-2;t=0;while(1){s=d+(c<<2)|0;w=j+(c<<3)|0;y=G[w>>2];w=G[w+4>>2];z:{if((y|0)!=(q|0)|(w|0)!=(v|0)){B=N((+(y>>>0)+ +(w|0)*4294967296)*x+A);break z}G[n>>2]=1;B=C}K[s>>2]=B;s=c|1;w=j+(s<<3)|0;y=G[w>>2];w=G[w+4>>2];A:{if((y|0)!=(q|0)|(w|0)!=(v|0)){B=N((+(y>>>0)+ +(w|0)*4294967296)*x+A);break A}G[n>>2]=1;B=C}K[d+(s<<2)>>2]=B;c=c+2|0;t=t+2|0;if((r|0)!=(t|0)){continue}break}}if(!(u&1)){break q}t=q;j=j+(c<<3)|0;q=G[j>>2];j=G[j+4>>2];B:{if((t|0)!=(q|0)|(j|0)!=(v|0)){C=N((+(q>>>0)+ +(j|0)*4294967296)*x+A);break B}G[n>>2]=1}K[d+(c<<2)>>2]=C}break g}c=p- -64|0;Tc(a,v,j,u,r,c,o);Wi(c,u,L[p+29096>>3],L[p+29088>>3],z,k,e+m|0,n,(e<<2)+l|0);break g}Jb(a,v,j,0,o);c=G[p+29060>>2];d=G[p+29064>>2];C:{if((c|0)==(d|0)){c=M(c,u);ic(a,c,c>>31,p- -64|0,o);break C}Rd(a,d,u,c-d|0,p- -64|0,o)}t=p- -64|0;X=L[p+29096>>3];Y=L[p+29088>>3];Z=G[p+29064>>2];_=e+m|0;y=(e<<2)+l|0;s=0;r=Fa-112|0;Fa=r;Q=p+28864|0;$=Va(Q);if((u|0)>0){while(1){D:{d=t+Z|0;U=H[d|0];E[d|0]=0;j=t;E:{F:{if(H[Q|0]==1){break F}if(fb(Q,t,$)){break F}j=d;if(!z){break E}G[n>>2]=1;if((z|0)==1){K[(s<<2)+y>>2]=k;break E}E[s+_|0]=1;break E}while(1){c=H[j|0];if((c|0)==32){j=j+1|0;continue}break}V=1;G:{switch(c-43|0){case 0:case 2:while(1){q=H[j+1|0];j=j+1|0;if((q|0)==32){continue}break};V=(c|0)==45?-1:1;c=q;break;default:break G}}A=0;if((c-48&255)>>>0<10){while(1){x=A*10+ +(c<<24>>24);q=j;while(1){c=H[q+1|0];j=q+1|0;q=j;if((c|0)==32){continue}break}A=x+-48;if((c-48&255)>>>0<=9){continue}break}}x=D;H:{I:{switch(c-44|0){case 0:case 2:break I;default:break H}}q=j;while(1){c=H[q+1|0];j=q+1|0;q=j;if((c|0)==32){continue}break}x=1;if((c-48&255)>>>0>=10){break H}while(1){A=A*10+ +(c<<24>>24)+-48;q=j;while(1){c=H[q+1|0];j=q+1|0;q=j;if((c|0)==32){continue}break}x=x*10;if((c-48&255)>>>0<=9){continue}break}}J:{if((c&254)!=68){w=1;q=0;break J}while(1){w=1;q=j;j=j+1|0;c=H[q+1|0];if((c|0)==32){continue}break}K:{switch(c-43|0){case 0:case 2:q=q+2|0;while(1){j=q;q=j+1|0;v=H[j|0];if((v|0)==32){continue}break};w=(c|0)==45?-1:1;c=v;break;default:break K}}q=0;if((c-48&255)>>>0>=10){break J}while(1){v=c;T=M(q,10)-48|0;q=j;while(1){c=H[q+1|0];j=q+1|0;q=j;if((c|0)==32){continue}break}q=T+(v<<24>>24)|0;if((c-48&255)>>>0<=9){continue}break}}if(c){G[r+48>>2]=H[23477]|H[23478]<<8|(H[23479]<<16|H[23480]<<24);c=H[23473]|H[23474]<<8|(H[23475]<<16|H[23476]<<24);G[r+40>>2]=H[23469]|H[23470]<<8|(H[23471]<<16|H[23472]<<24);G[r+44>>2]=c;c=H[23465]|H[23466]<<8|(H[23467]<<16|H[23468]<<24);G[r+32>>2]=H[23461]|H[23462]<<8|(H[23463]<<16|H[23464]<<24);G[r+36>>2]=c;c=H[23457]|H[23458]<<8|(H[23459]<<16|H[23460]<<24);G[r+24>>2]=H[23453]|H[23454]<<8|(H[23455]<<16|H[23456]<<24);G[r+28>>2]=c;c=H[23449]|H[23450]<<8|(H[23451]<<16|H[23452]<<24);G[r+16>>2]=H[23445]|H[23446]<<8|(H[23447]<<16|H[23448]<<24);G[r+20>>2]=c;c=r+16|0;Ua(c);G[r>>2]=t;Ya(c,81,43022,r);Ua(c);E[d|0]=U;G[o>>2]=409;break D}aa=(s<<2)+y|0,ba=N(A*+(V|0)/x*$b(10,+(M(q,w)|0))*X+Y),K[aa>>2]=ba}t=j;E[d|0]=U;s=s+1|0;if((s|0)!=(u|0)){continue}}break}}Fa=r+112|0;break g}G[p>>2]=b;G[p+4>>2]=p+28992;a=p+28896|0;Ya(a,81,8924,p);Ua(a);q=311;if(G[p+29076>>2]==1){break e}q=312;break e}c=p- -64|0;$d(a,v,j,u,r,c,o);iq(c,u,L[p+29096>>3],L[p+29088>>3],z,H[p+29024|0],k,e+m|0,n,(e<<2)+l|0)}q=G[o>>2];if((q|0)>0){x=+(e>>>0)+ +(f|0)*4294967296;D=x+1;x=x+ +(u|0);L:{if(G[p+29076>>2]>0){G[p+32>>2]=b;L[p+24>>3]=x;L[p+16>>3]=D;Ya(p+28896|0,81,47439,p+16|0);break L}L[p+56>>3]=x;L[p+48>>3]=D;Ya(p+28896|0,81,47380,p+48|0)}Ua(p+28896|0);q=G[o>>2];break a}c=u;j=c>>31;t=c;s=j;h=h-(j+(g>>>0>>0)|0)|0;g=g-c|0;if(h|g){c=M(i,u);j=c;d=c+G[p+29032>>2]|0;c=G[p+29036>>2]+(c>>31)|0;c=d>>>0>>0?c+1|0:c;G[p+29032>>2]=d;j=c;G[p+29036>>2]=c;c=f+s|0;q=e+t|0;c=q>>>0>>0?c+1|0:c;e=q;f=c;t=G[p+29052>>2];c=t;u=G[p+29048>>2];if((j|0)>=(c|0)&d>>>0>=u>>>0|(c|0)<(j|0)){q=Bu(d,j,u,t);c=I+q|0;s=Ia;O=O+s|0;O=c>>>0>>0?O+1|0:O;I=c;c=Au(q,s,u,t);G[p+29032>>2]=d-c;G[p+29036>>2]=j-(Ia+(c>>>0>d>>>0)|0);continue}if((j|0)>0|(j|0)>=0){continue}q=I;I=Bu(d^-1,j^-1,u,t)+1|0;c=Ia;c=I?c:c+1|0;s=I;I=q-s|0;O=O-((q>>>0>>0)+c|0)|0;q=Au(s,c,u,t)+d|0;c=j+Ia|0;G[p+29032>>2]=q;G[p+29036>>2]=d>>>0>q>>>0?c+1|0:c;continue}break}if((q|0)!=-11){break a}Ua(44994);q=412}G[o>>2]=q}Fa=p+29104|0;return q}function Id(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,I=0,K=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0;q=Fa-29104|0;Fa=q;p=G[o>>2];a:{if(!(g|h)|(p|0)>0){break a}if(n){G[n>>2]=0}if((j|0)==2){cb(m,0,g)}if((yc(a,b,c,d,e,f,g,h,i>>31,q+29096|0,q+29088|0,q+28992|0,q+29064|0,q+29084|0,q+29068|0,q+29040|0,q+29032|0,q+29060|0,q+29048|0,q+29016|0,q+29080|0,q+29024|0,q+28864|0,o)|0)>0){p=G[o>>2];break a}G[q+29060>>2]=M(G[q+29060>>2],i);N=1;c=G[q+29068>>2];R=c;S=c>>31;b:{if(G[q+29084>>2]!=16){break b}Gd(q+28992|0,q+29076|0,q+29056|0,q+29072|0,o);c=G[q+29072>>2];if((c|0)<=0){break b}if(c-1>>>0>=7){d=c&-8;while(1){N=N*10*10*10*10*10*10*10*10;z=z+8|0;if((d|0)!=(z|0)){continue}break}}c=c&7;if(!c){break b}z=0;while(1){N=N*10;z=z+1|0;if((c|0)!=(z|0)){continue}break}}z=0;d=G[q+29084>>2];c:{d:{if((j|0)==1&k==0){break d}e=G[q+29028>>2];c=G[q+29024>>2];if(!e&(c|0)==1234554321&((d|0)%10|0)==1){break d}if(!((e-(c>>>0<32768)|0)==-1&c-32768>>>0>=4294901760|(d|0)!=21)){K=0;break c}K=0;if(!(!e&c>>>0<=255|(d|0)!=11)){break c}z=(d|0)==16?H[q+28864|0]==1?0:j:j}K=0;if((d|0)!=82){break c}c=g>>>0<268435455&(h|0)<=0|(h|0)<0;R=c?g:268435455;S=c?h:0;K=!z&L[q+29096>>3]==1&L[q+29088>>3]==0}U=0-i|0;e=0;f=0;e:{while(1){d=g>>>0>>0&(h|0)<=(S|0)|(h|0)<(S|0)?g:R;c=d;j=c>>31;t=c;p=j;f:{if((i|0)>=0){c=G[q+29036>>2];r=c;c=G[q+29052>>2]+(c^-1)|0;s=G[q+29032>>2];j=s^-1;d=j+G[q+29048>>2]|0;c=Bu(d,d>>>0>>0?c+1|0:c,i,0);d=Ia;break f}s=G[q+29032>>2];r=G[q+29036>>2];c=Bu(s,r,U,0);d=Ia}u=c;j=G[q+29044>>2];c=G[q+29040>>2];v=Au(G[q+29016>>2],G[q+29020>>2],O,Q);c=c+v|0;j=Ia+j|0;j=c>>>0>>0?j+1|0:j;I=c;v=G[q+29060>>2];c=(v|0)/(i|0)|0;s=Au(s,r,c,c>>31);r=I+s|0;c=Ia+j|0;c=s>>>0>r>>>0?c+1|0:c;s=r;j=c;c=d;r=u+1|0;d=(d|0)<=(p|0)&t>>>0>u>>>0|(d|0)<(p|0);t=d?r:t;g:{h:{i:{j:{k:{l:{m:{n:{o:{c=G[q+29084>>2];switch(c-11|0){case 0:break h;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break i;case 5:break j;case 31:break k;case 30:break m;case 10:break n;default:break o}}p:{switch(c-81|0){case 0:break l;case 1:break p;default:break i}}c=(e<<3)+l|0;Tc(a,s,j,t,v,c,o);if(K){break g}dl(c,t,L[q+29096>>3],L[q+29088>>3],z,k,e+m|0,n,c);break g}c=q- -64|0;Pe(a,s,j,t,v,c,o);fq(c,t,L[q+29096>>3],L[q+29088>>3],z,F[q+29024>>1],k,e+m|0,n,(e<<3)+l|0);break g}c=q- -64|0;Uc(a,s,j,t,v,c,o);cl(c,t,L[q+29096>>3],L[q+29088>>3],z,G[q+29024>>2],k,e+m|0,n,(e<<3)+l|0);break g}c=j;j=q- -64|0;Tc(a,s,c,t,v,j,o);u=G[q+29024>>2];s=G[q+29028>>2];y=k;v=e+m|0;d=(e<<3)+l|0;B=L[q+29096>>3];C=L[q+29088>>3];c=B==1&C==0x8000000000000000;q:{if(!z){if(c){if((t|0)<=0){break q}u=0;c=0;if(t-1>>>0>=3){v=t&-4;p=0;while(1){s=c<<3;r=j+s|0;L[s+d>>3]=+J[r>>2]+ +((G[r+4>>2]^-2147483648)>>>0)*4294967296;r=s|8;I=r+d|0;r=j+r|0;L[I>>3]=+J[r>>2]+ +((G[r+4>>2]^-2147483648)>>>0)*4294967296;r=s|16;I=r+d|0;r=j+r|0;L[I>>3]=+J[r>>2]+ +((G[r+4>>2]^-2147483648)>>>0)*4294967296;s=s|24;r=s+d|0;s=j+s|0;L[r>>3]=+J[s>>2]+ +((G[s+4>>2]^-2147483648)>>>0)*4294967296;c=c+4|0;p=p+4|0;if((v|0)!=(p|0)){continue}break}}p=t&3;if(!p){break q}while(1){s=c<<3;r=s+d|0;s=j+s|0;L[r>>3]=+J[s>>2]+ +((G[s+4>>2]^-2147483648)>>>0)*4294967296;c=c+1|0;u=u+1|0;if((p|0)!=(u|0)){continue}break}break q}if(!(B==1&C==0)){if((t|0)<=0){break q}c=0;if((t|0)!=1){s=t&-2;p=0;while(1){u=c<<3;v=j+u|0;L[u+d>>3]=(+J[v>>2]+ +G[v+4>>2]*4294967296)*B+C;u=u|8;r=u+d|0;u=j+u|0;L[r>>3]=(+J[u>>2]+ +G[u+4>>2]*4294967296)*B+C;c=c+2|0;p=p+2|0;if((s|0)!=(p|0)){continue}break}}if(!(t&1)){break q}c=c<<3;d=c+d|0;c=c+j|0;L[d>>3]=(+J[c>>2]+ +G[c+4>>2]*4294967296)*B+C;break q}if((t|0)<=0){break q}u=0;c=0;if(t-1>>>0>=3){v=t&-4;p=0;while(1){s=c<<3;r=j+s|0;L[s+d>>3]=+J[r>>2]+ +G[r+4>>2]*4294967296;r=s|8;I=r+d|0;r=j+r|0;L[I>>3]=+J[r>>2]+ +G[r+4>>2]*4294967296;r=s|16;I=r+d|0;r=j+r|0;L[I>>3]=+J[r>>2]+ +G[r+4>>2]*4294967296;s=s|24;r=s+d|0;s=j+s|0;L[r>>3]=+J[s>>2]+ +G[s+4>>2]*4294967296;c=c+4|0;p=p+4|0;if((v|0)!=(p|0)){continue}break}}p=t&3;if(!p){break q}while(1){s=c<<3;r=s+d|0;s=j+s|0;L[r>>3]=+J[s>>2]+ +G[s+4>>2]*4294967296;c=c+1|0;u=u+1|0;if((p|0)!=(u|0)){continue}break}break q}if(c){if((t|0)<=0){break q}c=0;while(1){p=c<<3;r=p+j|0;w=G[r>>2];r=G[r+4>>2];r:{if((w|0)==(u|0)&(r|0)==(s|0)){G[n>>2]=1;if((z|0)==1){L[d+p>>3]=y;break r}E[c+v|0]=1;break r}L[d+p>>3]=+(w>>>0)+ +((r^-2147483648)>>>0)*4294967296}c=c+1|0;if((t|0)!=(c|0)){continue}break}break q}s:{if(!(B==1&C==0)){if((t|0)<=0){break q}if((z|0)==1){break s}c=0;while(1){p=c<<3;r=p+j|0;w=G[r>>2];r=G[r+4>>2];t:{if((w|0)==(u|0)&(r|0)==(s|0)){G[n>>2]=1;E[c+v|0]=1;break t}L[d+p>>3]=(+(w>>>0)+ +(r|0)*4294967296)*B+C}c=c+1|0;if((t|0)!=(c|0)){continue}break}break q}if((t|0)<=0){break q}if((z|0)!=1){c=0;if((t|0)!=1){r=t&-2;p=0;while(1){w=c<<3;x=w+j|0;D=G[x>>2];x=G[x+4>>2];u:{if((D|0)==(u|0)&(x|0)==(s|0)){G[n>>2]=1;E[c+v|0]=1;break u}L[d+w>>3]=+(D>>>0)+ +(x|0)*4294967296}w=c|1;x=w<<3;D=x+j|0;P=G[D>>2];D=G[D+4>>2];v:{if((P|0)!=(u|0)|(D|0)!=(s|0)){L[d+x>>3]=+(P>>>0)+ +(D|0)*4294967296;break v}G[n>>2]=1;E[v+w|0]=1}c=c+2|0;p=p+2|0;if((r|0)!=(p|0)){continue}break}}if(!(t&1)){break q}r=u;p=j;j=c<<3;p=p+j|0;u=G[p>>2];p=G[p+4>>2];if((r|0)!=(u|0)|(p|0)!=(s|0)){L[d+j>>3]=+(u>>>0)+ +(p|0)*4294967296;break q}G[n>>2]=1;E[c+v|0]=1;break q}c=0;if((t|0)!=1){v=t&-2;p=0;while(1){r=c<<3;w=r+j|0;x=G[w>>2];w=G[w+4>>2];w:{if((x|0)!=(u|0)|(w|0)!=(s|0)){A=+(x>>>0)+ +(w|0)*4294967296;break w}G[n>>2]=1;A=y}L[d+r>>3]=A;r=(c|1)<<3;w=r+j|0;x=G[w>>2];w=G[w+4>>2];x:{if((x|0)!=(u|0)|(w|0)!=(s|0)){A=+(x>>>0)+ +(w|0)*4294967296;break x}G[n>>2]=1;A=y}L[d+r>>3]=A;c=c+2|0;p=p+2|0;if((v|0)!=(p|0)){continue}break}}if(!(t&1)){break q}j=j+(c<<3)|0;p=G[j>>2];j=G[j+4>>2];y:{if((p|0)!=(u|0)|(j|0)!=(s|0)){y=+(p>>>0)+ +(j|0)*4294967296;break y}G[n>>2]=1}L[d+(c<<3)>>3]=y;break q}c=0;if((t|0)!=1){v=t&-2;p=0;while(1){r=c<<3;w=r+j|0;x=G[w>>2];w=G[w+4>>2];z:{if((x|0)!=(u|0)|(w|0)!=(s|0)){A=(+(x>>>0)+ +(w|0)*4294967296)*B+C;break z}G[n>>2]=1;A=y}L[d+r>>3]=A;r=(c|1)<<3;w=r+j|0;x=G[w>>2];w=G[w+4>>2];A:{if((x|0)!=(u|0)|(w|0)!=(s|0)){A=(+(x>>>0)+ +(w|0)*4294967296)*B+C;break A}G[n>>2]=1;A=y}L[d+r>>3]=A;c=c+2|0;p=p+2|0;if((v|0)!=(p|0)){continue}break}}if(!(t&1)){break q}j=j+(c<<3)|0;p=G[j>>2];j=G[j+4>>2];B:{if((p|0)!=(u|0)|(j|0)!=(s|0)){y=(+(p>>>0)+ +(j|0)*4294967296)*B+C;break B}G[n>>2]=1}L[d+(c<<3)>>3]=y}break g}c=q- -64|0;Uc(a,s,j,t,v,c,o);bl(c,t,L[q+29096>>3],L[q+29088>>3],z,k,e+m|0,n,(e<<3)+l|0);break g}Jb(a,s,j,0,o);c=G[q+29060>>2];d=G[q+29064>>2];C:{if((c|0)==(d|0)){c=M(c,t);ic(a,c,c>>31,q- -64|0,o);break C}Rd(a,d,t,c-d|0,q- -64|0,o)}u=q- -64|0;B=L[q+29096>>3];C=L[q+29088>>3];V=G[q+29064>>2];W=e+m|0;x=(e<<3)+l|0;r=0;v=Fa-112|0;Fa=v;D=q+28864|0;X=Va(D);if((t|0)>0){while(1){D:{d=u+V|0;P=H[d|0];E[d|0]=0;j=u;E:{F:{if(H[D|0]==1){break F}if(fb(D,u,X)){break F}j=d;if(!z){break E}G[n>>2]=1;if((z|0)==1){L[(r<<3)+x>>3]=k;break E}E[r+W|0]=1;break E}while(1){c=H[j|0];if((c|0)==32){j=j+1|0;continue}break}T=1;G:{switch(c-43|0){case 0:case 2:while(1){p=H[j+1|0];j=j+1|0;if((p|0)==32){continue}break};T=(c|0)==45?-1:1;c=p;break;default:break G}}A=0;if((c-48&255)>>>0<10){while(1){y=A*10+ +(c<<24>>24);p=j;while(1){c=H[p+1|0];j=p+1|0;p=j;if((c|0)==32){continue}break}A=y+-48;if((c-48&255)>>>0<=9){continue}break}}y=N;H:{I:{switch(c-44|0){case 0:case 2:break I;default:break H}}p=j;while(1){c=H[p+1|0];j=p+1|0;p=j;if((c|0)==32){continue}break}y=1;if((c-48&255)>>>0>=10){break H}while(1){A=A*10+ +(c<<24>>24)+-48;p=j;while(1){c=H[p+1|0];j=p+1|0;p=j;if((c|0)==32){continue}break}y=y*10;if((c-48&255)>>>0<=9){continue}break}}J:{if((c&254)!=68){w=1;p=0;break J}while(1){w=1;p=j;j=j+1|0;c=H[p+1|0];if((c|0)==32){continue}break}K:{switch(c-43|0){case 0:case 2:p=p+2|0;while(1){j=p;p=j+1|0;s=H[j|0];if((s|0)==32){continue}break};w=(c|0)==45?-1:1;c=s;break;default:break K}}p=0;if((c-48&255)>>>0>=10){break J}while(1){s=c;I=M(p,10)-48|0;p=j;while(1){c=H[p+1|0];j=p+1|0;p=j;if((c|0)==32){continue}break}p=I+(s<<24>>24)|0;if((c-48&255)>>>0<=9){continue}break}}if(c){G[v+48>>2]=H[23477]|H[23478]<<8|(H[23479]<<16|H[23480]<<24);c=H[23473]|H[23474]<<8|(H[23475]<<16|H[23476]<<24);G[v+40>>2]=H[23469]|H[23470]<<8|(H[23471]<<16|H[23472]<<24);G[v+44>>2]=c;c=H[23465]|H[23466]<<8|(H[23467]<<16|H[23468]<<24);G[v+32>>2]=H[23461]|H[23462]<<8|(H[23463]<<16|H[23464]<<24);G[v+36>>2]=c;c=H[23457]|H[23458]<<8|(H[23459]<<16|H[23460]<<24);G[v+24>>2]=H[23453]|H[23454]<<8|(H[23455]<<16|H[23456]<<24);G[v+28>>2]=c;c=H[23449]|H[23450]<<8|(H[23451]<<16|H[23452]<<24);G[v+16>>2]=H[23445]|H[23446]<<8|(H[23447]<<16|H[23448]<<24);G[v+20>>2]=c;c=v+16|0;Ua(c);G[v>>2]=u;Ya(c,81,43022,v);Ua(c);E[d|0]=P;G[o>>2]=409;break D}Y=(r<<3)+x|0,Z=A*+(T|0)/y*$b(10,+(M(p,w)|0))*B+C,L[Y>>3]=Z}u=j;E[d|0]=P;r=r+1|0;if((r|0)!=(t|0)){continue}}break}}Fa=v+112|0;break g}G[q>>2]=b;G[q+4>>2]=q+28992;a=q+28896|0;Ya(a,81,8924,q);Ua(a);p=311;if(G[q+29080>>2]==1){break e}p=312;break e}c=q- -64|0;$d(a,s,j,t,v,c,o);eq(c,t,L[q+29096>>3],L[q+29088>>3],z,H[q+29024|0],k,e+m|0,n,(e<<3)+l|0)}p=G[o>>2];if((p|0)>0){y=+(e>>>0)+ +(f|0)*4294967296;k=y+1;y=y+ +(t|0);L:{if(G[q+29080>>2]>0){G[q+32>>2]=b;L[q+24>>3]=y;L[q+16>>3]=k;Ya(q+28896|0,81,47713,q+16|0);break L}L[q+56>>3]=y;L[q+48>>3]=k;Ya(q+28896|0,81,47654,q+48|0)}Ua(q+28896|0);p=G[o>>2];break a}c=t;j=c>>31;u=c;h=h-((g>>>0>>0)+j|0)|0;g=g-c|0;if(h|g){c=M(i,t);p=c;d=c+G[q+29032>>2]|0;c=G[q+29036>>2]+(c>>31)|0;c=d>>>0

>>0?c+1|0:c;G[q+29032>>2]=d;p=c;G[q+29036>>2]=c;c=f+j|0;u=e+u|0;c=u>>>0>>0?c+1|0:c;e=u;f=c;t=G[q+29052>>2];c=t;r=G[q+29048>>2];if((p|0)>=(c|0)&d>>>0>=r>>>0|(c|0)<(p|0)){c=Bu(d,p,r,t);j=c>>31;s=c;u=O+c|0;c=j+Q|0;c=u>>>0>>0?c+1|0:c;O=u;Q=c;c=Au(s,j,r,t);G[q+29032>>2]=d-c;G[q+29036>>2]=p-(Ia+(c>>>0>d>>>0)|0);continue}if((p|0)>0|(p|0)>=0){continue}c=Bu(d^-1,p^-1,r,t);c=c+1|0;j=c>>31;u=O;O=u-c|0;Q=Q-((c>>>0>u>>>0)+j|0)|0;j=Au(c,j,r,t)+d|0;c=p+Ia|0;G[q+29032>>2]=j;G[q+29036>>2]=d>>>0>j>>>0?c+1|0:c;continue}break}if((p|0)!=-11){break a}Ua(44994);p=412}G[o>>2]=p}Fa=q+29104|0;return p}function ao(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0;e=Fa-192|0;Fa=e;if(G[d>>2]<=0){G[e+92>>2]=0;f=G[a>>2];if((f|0)!=G[G[a+4>>2]+76>>2]){mb(a,f+1|0,0,d)}f=b+1|0;a:{b:{switch(H[b+1|0]-66|0){case 18:if(fb(f,35418,4)){break a}G[48624]=0;G[e+80>>2]=0;d=b+5|0;i=e,j=nc(d,e+72|0,10),G[i+80>>2]=j;if((H[G[e+72>>2]]|32)!=32){G[e+92>>2]=407}if(G[48624]==68){b=H[67017]|H[67018]<<8|(H[67019]<<16|H[67020]<<24);f=H[67013]|H[67014]<<8|(H[67015]<<16|H[67016]<<24);F[e+142>>1]=f;F[e+144>>1]=f>>>16;F[e+146>>1]=b;F[e+148>>1]=b>>>16;b=H[67011]|H[67012]<<8|(H[67013]<<16|H[67014]<<24);G[e+136>>2]=H[67007]|H[67008]<<8|(H[67009]<<16|H[67010]<<24);G[e+140>>2]=b;b=H[67003]|H[67004]<<8|(H[67005]<<16|H[67006]<<24);G[e+128>>2]=H[66999]|H[67e3]<<8|(H[67001]<<16|H[67002]<<24);G[e+132>>2]=b;b=H[66995]|H[66996]<<8|(H[66997]<<16|H[66998]<<24);G[e+120>>2]=H[66991]|H[66992]<<8|(H[66993]<<16|H[66994]<<24);G[e+124>>2]=b;b=H[66987]|H[66988]<<8|(H[66989]<<16|H[66990]<<24);G[e+112>>2]=H[66983]|H[66984]<<8|(H[66985]<<16|H[66986]<<24);G[e+116>>2]=b;b=H[66979]|H[66980]<<8|(H[66981]<<16|H[66982]<<24);G[e+104>>2]=H[66975]|H[66976]<<8|(H[66977]<<16|H[66978]<<24);G[e+108>>2]=b;b=H[66971]|H[66972]<<8|(H[66973]<<16|H[66974]<<24);G[e+96>>2]=H[66967]|H[66968]<<8|(H[66969]<<16|H[66970]<<24);G[e+100>>2]=b;tb(5,qb(e+96|0,d,25));G[e+92>>2]=412;G[48624]=0}if(G[e+92>>2]>0){break a}b=G[e+80>>2];if((b|0)<=0){break a}a=G[a+4>>2];if((b|0)>G[a+936>>2]){break a}a=G[a+968>>2];if((fd(c,e+96|0,e+92|0)|0)>0){break a}Za((a+M(b,160)|0)-160|0,e+96|0);break a;case 4:if(fb(f,34642,4)){break a}G[48624]=0;G[e+80>>2]=0;f=b+5|0;i=e,j=nc(f,e+72|0,10),G[i+80>>2]=j;if((H[G[e+72>>2]]|32)!=32){G[e+92>>2]=407}if(G[48624]==68){b=H[67017]|H[67018]<<8|(H[67019]<<16|H[67020]<<24);g=H[67013]|H[67014]<<8|(H[67015]<<16|H[67016]<<24);F[e+142>>1]=g;F[e+144>>1]=g>>>16;F[e+146>>1]=b;F[e+148>>1]=b>>>16;b=H[67011]|H[67012]<<8|(H[67013]<<16|H[67014]<<24);G[e+136>>2]=H[67007]|H[67008]<<8|(H[67009]<<16|H[67010]<<24);G[e+140>>2]=b;b=H[67003]|H[67004]<<8|(H[67005]<<16|H[67006]<<24);G[e+128>>2]=H[66999]|H[67e3]<<8|(H[67001]<<16|H[67002]<<24);G[e+132>>2]=b;b=H[66995]|H[66996]<<8|(H[66997]<<16|H[66998]<<24);G[e+120>>2]=H[66991]|H[66992]<<8|(H[66993]<<16|H[66994]<<24);G[e+124>>2]=b;b=H[66987]|H[66988]<<8|(H[66989]<<16|H[66990]<<24);G[e+112>>2]=H[66983]|H[66984]<<8|(H[66985]<<16|H[66986]<<24);G[e+116>>2]=b;b=H[66979]|H[66980]<<8|(H[66981]<<16|H[66982]<<24);G[e+104>>2]=H[66975]|H[66976]<<8|(H[66977]<<16|H[66978]<<24);G[e+108>>2]=b;b=H[66971]|H[66972]<<8|(H[66973]<<16|H[66974]<<24);G[e+96>>2]=H[66967]|H[66968]<<8|(H[66969]<<16|H[66970]<<24);G[e+100>>2]=b;tb(5,qb(e+96|0,f,25));G[e+92>>2]=412;G[48624]=0}if(G[e+92>>2]>0){break a}b=G[e+80>>2];if((b|0)<=0){break a}f=G[a+4>>2];if((b|0)>G[f+936>>2]){break a}f=G[f+968>>2];if((fd(c,e+96|0,e+92|0)|0)>0){break a}b=(f+M(b,160)|0)-160|0;i=rb(b+140|0,e+96|0,9),j=0,E[i+9|0]=j;if(G[G[a+4>>2]+80>>2]==1){if((Gd(e+96|0,e+72|0,e+84|0,e+88|0,d)|0)>0){break a}G[b+88>>2]=1;G[b+92>>2]=0;G[b+80>>2]=16;G[b+152>>2]=G[e+84>>2];break a}if((Vf(e+96|0,e+72|0,e+88|0,e+84|0,d)|0)>0){break a}G[b+80>>2]=G[e+72>>2];a=G[e+88>>2];G[b+88>>2]=a;G[b+92>>2]=a>>31;if(G[e+72>>2]==16){c=G[b+152>>2];if((a|0)>=(c|0)?c:0){break a}G[b+152>>2]=G[e+84>>2];break a}G[b+152>>2]=G[e+84>>2];break a;case 0:if(fb(f,34750,4)){break a}G[48624]=0;G[e+80>>2]=0;g=b+5|0;i=e,j=nc(g,e+72|0,10),G[i+80>>2]=j;if((H[G[e+72>>2]]|32)!=32){G[e+92>>2]=407}if(G[48624]==68){f=H[67017]|H[67018]<<8|(H[67019]<<16|H[67020]<<24);h=H[67013]|H[67014]<<8|(H[67015]<<16|H[67016]<<24);F[e+142>>1]=h;F[e+144>>1]=h>>>16;F[e+146>>1]=f;F[e+148>>1]=f>>>16;f=H[67011]|H[67012]<<8|(H[67013]<<16|H[67014]<<24);G[e+136>>2]=H[67007]|H[67008]<<8|(H[67009]<<16|H[67010]<<24);G[e+140>>2]=f;f=H[67003]|H[67004]<<8|(H[67005]<<16|H[67006]<<24);G[e+128>>2]=H[66999]|H[67e3]<<8|(H[67001]<<16|H[67002]<<24);G[e+132>>2]=f;f=H[66995]|H[66996]<<8|(H[66997]<<16|H[66998]<<24);G[e+120>>2]=H[66991]|H[66992]<<8|(H[66993]<<16|H[66994]<<24);G[e+124>>2]=f;f=H[66987]|H[66988]<<8|(H[66989]<<16|H[66990]<<24);G[e+112>>2]=H[66983]|H[66984]<<8|(H[66985]<<16|H[66986]<<24);G[e+116>>2]=f;f=H[66979]|H[66980]<<8|(H[66981]<<16|H[66982]<<24);G[e+104>>2]=H[66975]|H[66976]<<8|(H[66977]<<16|H[66978]<<24);G[e+108>>2]=f;f=H[66971]|H[66972]<<8|(H[66973]<<16|H[66974]<<24);G[e+96>>2]=H[66967]|H[66968]<<8|(H[66969]<<16|H[66970]<<24);G[e+100>>2]=f;tb(5,qb(e+96|0,g,25));G[e+92>>2]=412;G[48624]=0}if(G[e+92>>2]>0){break a}f=G[e+80>>2];if((f|0)<=0){break a}a=G[a+4>>2];if((f|0)>G[a+936>>2]|G[a+80>>2]==2){break a}a=G[a+968>>2];if((ue(c,e+72|0,d)|0)>0){G[e+4>>2]=c;G[e>>2]=b;a=e+96|0;Ya(a,81,9527,e);tb(5,a);break a}a=(a+M(f,160)|0)-160|0;b=G[e+72>>2]-1|0;G[a+72>>2]=b;G[a+76>>2]=b>>31;break a;case 17:if(fb(f,34839,4)){break a}G[48624]=0;G[e+80>>2]=0;f=b+5|0;i=e,j=nc(f,e+72|0,10),G[i+80>>2]=j;if((H[G[e+72>>2]]|32)!=32){G[e+92>>2]=407}if(G[48624]==68){d=H[67017]|H[67018]<<8|(H[67019]<<16|H[67020]<<24);g=H[67013]|H[67014]<<8|(H[67015]<<16|H[67016]<<24);F[e+142>>1]=g;F[e+144>>1]=g>>>16;F[e+146>>1]=d;F[e+148>>1]=d>>>16;d=H[67011]|H[67012]<<8|(H[67013]<<16|H[67014]<<24);G[e+136>>2]=H[67007]|H[67008]<<8|(H[67009]<<16|H[67010]<<24);G[e+140>>2]=d;d=H[67003]|H[67004]<<8|(H[67005]<<16|H[67006]<<24);G[e+128>>2]=H[66999]|H[67e3]<<8|(H[67001]<<16|H[67002]<<24);G[e+132>>2]=d;d=H[66995]|H[66996]<<8|(H[66997]<<16|H[66998]<<24);G[e+120>>2]=H[66991]|H[66992]<<8|(H[66993]<<16|H[66994]<<24);G[e+124>>2]=d;d=H[66987]|H[66988]<<8|(H[66989]<<16|H[66990]<<24);G[e+112>>2]=H[66983]|H[66984]<<8|(H[66985]<<16|H[66986]<<24);G[e+116>>2]=d;d=H[66979]|H[66980]<<8|(H[66981]<<16|H[66982]<<24);G[e+104>>2]=H[66975]|H[66976]<<8|(H[66977]<<16|H[66978]<<24);G[e+108>>2]=d;d=H[66971]|H[66972]<<8|(H[66973]<<16|H[66974]<<24);G[e+96>>2]=H[66967]|H[66968]<<8|(H[66969]<<16|H[66970]<<24);G[e+100>>2]=d;tb(5,qb(e+96|0,f,25));G[e+92>>2]=412;G[48624]=0}if(G[e+92>>2]>0){break a}d=G[e+80>>2];if((d|0)<=0){break a}a=G[a+4>>2];if((d|0)>G[a+936>>2]){break a}a=G[a+968>>2];if((me(c,e+72|0,e+92|0)|0)>0){G[e+20>>2]=c;G[e+16>>2]=b;a=e+96|0;Ya(a,81,9932,e+16|0);tb(5,a);break a}L[(a+M(d,160)|0)+-64>>3]=L[e+72>>3];break a;case 24:if(fb(f,34378,4)){break a}G[48624]=0;G[e+80>>2]=0;f=b+5|0;i=e,j=nc(f,e+72|0,10),G[i+80>>2]=j;if((H[G[e+72>>2]]|32)!=32){G[e+92>>2]=407}if(G[48624]==68){d=H[67017]|H[67018]<<8|(H[67019]<<16|H[67020]<<24);g=H[67013]|H[67014]<<8|(H[67015]<<16|H[67016]<<24);F[e+142>>1]=g;F[e+144>>1]=g>>>16;F[e+146>>1]=d;F[e+148>>1]=d>>>16;d=H[67011]|H[67012]<<8|(H[67013]<<16|H[67014]<<24);G[e+136>>2]=H[67007]|H[67008]<<8|(H[67009]<<16|H[67010]<<24);G[e+140>>2]=d;d=H[67003]|H[67004]<<8|(H[67005]<<16|H[67006]<<24);G[e+128>>2]=H[66999]|H[67e3]<<8|(H[67001]<<16|H[67002]<<24);G[e+132>>2]=d;d=H[66995]|H[66996]<<8|(H[66997]<<16|H[66998]<<24);G[e+120>>2]=H[66991]|H[66992]<<8|(H[66993]<<16|H[66994]<<24);G[e+124>>2]=d;d=H[66987]|H[66988]<<8|(H[66989]<<16|H[66990]<<24);G[e+112>>2]=H[66983]|H[66984]<<8|(H[66985]<<16|H[66986]<<24);G[e+116>>2]=d;d=H[66979]|H[66980]<<8|(H[66981]<<16|H[66982]<<24);G[e+104>>2]=H[66975]|H[66976]<<8|(H[66977]<<16|H[66978]<<24);G[e+108>>2]=d;d=H[66971]|H[66972]<<8|(H[66973]<<16|H[66974]<<24);G[e+96>>2]=H[66967]|H[66968]<<8|(H[66969]<<16|H[66970]<<24);G[e+100>>2]=d;tb(5,qb(e+96|0,f,25));G[e+92>>2]=412;G[48624]=0}if(G[e+92>>2]>0){break a}d=G[e+80>>2];if((d|0)<=0){break a}a=G[a+4>>2];if((d|0)>G[a+936>>2]){break a}a=G[a+968>>2];if((me(c,e+72|0,e+92|0)|0)>0){G[e+36>>2]=c;G[e+32>>2]=b;a=e+96|0;Ya(a,81,9932,e+32|0);tb(5,a);break a}L[(a+M(d,160)|0)-56>>3]=L[e+72>>3];break a;case 12:if(fb(f,34769,4)){break a}G[48624]=0;G[e+80>>2]=0;f=b+5|0;i=e,j=nc(f,e+72|0,10),G[i+80>>2]=j;if((H[G[e+72>>2]]|32)!=32){G[e+92>>2]=407}if(G[48624]==68){d=H[67017]|H[67018]<<8|(H[67019]<<16|H[67020]<<24);g=H[67013]|H[67014]<<8|(H[67015]<<16|H[67016]<<24);F[e+142>>1]=g;F[e+144>>1]=g>>>16;F[e+146>>1]=d;F[e+148>>1]=d>>>16;d=H[67011]|H[67012]<<8|(H[67013]<<16|H[67014]<<24);G[e+136>>2]=H[67007]|H[67008]<<8|(H[67009]<<16|H[67010]<<24);G[e+140>>2]=d;d=H[67003]|H[67004]<<8|(H[67005]<<16|H[67006]<<24);G[e+128>>2]=H[66999]|H[67e3]<<8|(H[67001]<<16|H[67002]<<24);G[e+132>>2]=d;d=H[66995]|H[66996]<<8|(H[66997]<<16|H[66998]<<24);G[e+120>>2]=H[66991]|H[66992]<<8|(H[66993]<<16|H[66994]<<24);G[e+124>>2]=d;d=H[66987]|H[66988]<<8|(H[66989]<<16|H[66990]<<24);G[e+112>>2]=H[66983]|H[66984]<<8|(H[66985]<<16|H[66986]<<24);G[e+116>>2]=d;d=H[66979]|H[66980]<<8|(H[66981]<<16|H[66982]<<24);G[e+104>>2]=H[66975]|H[66976]<<8|(H[66977]<<16|H[66978]<<24);G[e+108>>2]=d;d=H[66971]|H[66972]<<8|(H[66973]<<16|H[66974]<<24);G[e+96>>2]=H[66967]|H[66968]<<8|(H[66969]<<16|H[66970]<<24);G[e+100>>2]=d;tb(5,qb(e+96|0,f,25));G[e+92>>2]=412;G[48624]=0}if(G[e+92>>2]>0){break a}d=G[e+80>>2];if((d|0)<=0){break a}f=G[a+4>>2];if((d|0)>G[f+936>>2]){break a}a=(G[f+968>>2]+M(d,160)|0)-160|0;if(G[f+80>>2]==1){if((fd(c,e+96|0,e+92|0)|0)>0){break a}i=rb(a+120|0,e+96|0,17),j=0,E[i+17|0]=j;break a}if((yi(c,e+72|0,e+92|0)|0)>0){G[e+52>>2]=c;G[e+48>>2]=b;a=e+96|0;Ya(a,81,9527,e+48|0);tb(5,a);break a}b=G[e+76>>2];G[a+112>>2]=G[e+72>>2];G[a+116>>2]=b;break a;case 2:if(fb(f,34662,3)|G[G[a+4>>2]+80>>2]==1){break a}if((ue(b+4|0,e+80|0,e+92|0)|0)>0){break a}b=G[e+80>>2];if((b|0)<=0){break a}a=G[a+4>>2];if((b|0)>G[a+936>>2]){break a}a=(G[a+968>>2]+M(b,160)|0)-160|0;b=G[a+80>>2];if((b|0)!=16&(b|0)!=-9999){break a}b=jb(c,40);if(!b){break a}b=b+1|0;G[e+96>>2]=b;b=nc(b,e+96|0,10);G[e+84>>2]=b;c=G[a+88>>2];d=c;f=(d|0)!=1;c=G[a+92>>2];g=b>>>0>d>>>0;d=b>>31;if((f|(c|0)!=0)&(g&(d|0)>=(c|0)|(c|0)<(d|0))){break a}G[a+152>>2]=b;break a;case 6:break b;default:break a}}if(fb(f,34351,4)|G[G[a+4>>2]+80>>2]==1){break a}if((yi(c,e+72|0,e+92|0)|0)>0){G[e+68>>2]=c;G[e+64>>2]=b;a=e+96|0;Ya(a,81,9527,e- -64|0);tb(5,a);break a}b=G[e+76>>2];a=G[a+4>>2];G[a+976>>2]=G[e+72>>2];G[a+980>>2]=b}}Fa=e+192|0}function md(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Va=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0,Eb=0,Fb=0,Gb=0,Hb=0,Ib=0;l=Fa-400|0;Fa=l;G[l+12>>2]=0;a:{if(G[k>>2]>0){break a}if(!Nb(a,k)){Ua(59600);G[k>>2]=414;break a}b:{c:{d:{switch(b-20|0){case 1:A=2;s=G[a+4>>2];o=G[s+1136>>2];w=ab(o<<1);if(g){break c}q=0;break b;case 11:A=4;s=G[a+4>>2];o=G[s+1136>>2];w=ab(o<<2);q=0;if(!g){break b}q=+G[g>>2];break b;case 21:A=4;s=G[a+4>>2];o=G[s+1136>>2];w=ab(o<<2);q=0;if(!g){break b}q=+G[g>>2];break b;case 22:A=4;s=G[a+4>>2];o=G[s+1136>>2];w=ab(o<<2);q=0;if(!g){break b}q=+K[g>>2];break b;case 62:A=8;s=G[a+4>>2];o=G[s+1136>>2];w=ab(o<<3);q=0;if(!g){break b}q=L[g>>3];break b;case 0:A=2;s=G[a+4>>2];o=G[s+1136>>2];w=ab(o<<1);q=0;if(!g){break b}q=+I[g>>1];break b;case 10:A=4;s=G[a+4>>2];o=G[s+1136>>2];w=ab(o<<2);q=0;if(!g){break b}q=+J[g>>2];break b;case 20:A=4;s=G[a+4>>2];o=G[s+1136>>2];w=ab(o<<2);q=0;if(!g){break b}q=+J[g>>2];break b;default:break d}}A=1;if(b-11>>>0<=1){s=G[a+4>>2];o=G[s+1136>>2];w=ab(o);q=0;if(!g){break b}q=+H[g|0];break b}Ua(24407);G[k>>2]=410;break a}q=+F[g>>1]}e:{if(!w){Ua(59502);break e}f:{ba=(f|0)==1?q==0?0:f:f;if((ba|0)!=2){break f}ca=lb(o,1);if(ca){break f}Ua(59502);Wa(w);break e}O=1;G[l+272>>2]=1;G[l+304>>2]=1;G[l+308>>2]=1;G[l+240>>2]=1;G[l+244>>2]=1;G[l+208>>2]=1;G[l+212>>2]=1;G[l+112>>2]=1;G[l+116>>2]=1;G[l+312>>2]=1;G[l+276>>2]=1;G[l+280>>2]=1;G[l+248>>2]=1;G[l+252>>2]=1;G[l+216>>2]=1;G[l+220>>2]=1;G[l+120>>2]=1;G[l+124>>2]=1;G[l+316>>2]=1;G[l+320>>2]=1;G[l+284>>2]=1;G[l+288>>2]=1;G[l+324>>2]=1;G[l+292>>2]=1;G[l+256>>2]=1;G[l+260>>2]=1;G[l+224>>2]=1;G[l+228>>2]=1;G[l+128>>2]=1;G[l+132>>2]=1;N=G[s+1108>>2];if((N|0)>0){f=0;while(1){B=f<<2;n=G[B+e>>2];U=0-n|0;x=n;n=f<<3;p=n+c|0;v=G[p>>2];n=d+n|0;r=G[n>>2];p=G[p+4>>2];n=G[n+4>>2];o=v>>>0>r>>>0&(p|0)>=(n|0)|(n|0)<(p|0);G[B+(l+16|0)>>2]=o?U:x;o=o?v:r;G[B+(l+48|0)>>2]=o;r=r>>>0>v>>>0&(n|0)>=(p|0)|(n|0)>(p|0)?v:r;G[B+(l+80|0)>>2]=r;n=s+B|0;p=G[n+1112>>2];G[B+(l+304|0)>>2]=p;if((r|0)<=0){if((ba|0)==2){Wa(ca)}Wa(w);G[k>>2]=321;break a}v=G[n+1052>>2];G[B+(l+272|0)>>2]=v;G[B+(l+112|0)>>2]=O;G[B+(l+240|0)>>2]=((r-1|0)/(v|0)|0)+1;n=((o-1|0)/(v|0)|0)+1|0;p=((p-1|0)/(v|0)|0)+1|0;G[B+(l+208|0)>>2]=(n|0)<(p|0)?n:p;O=M(p,O);f=f+1|0;if((N|0)!=(f|0)){continue}break}}if(j){G[j>>2]=0}Q=G[l+228>>2];V=G[l+260>>2];g:{if((Q|0)<(V|0)){break g}R=G[l+324>>2];S=G[l+292>>2];W=G[l+224>>2];Ba=G[l+256>>2];if((W|0)<(Ba|0)){a=M(S,Q);G[l+164>>2]=(a|0)<(R|0)?a:R;G[l+196>>2]=M(Q-1|0,S)+1;break g}X=G[l+320>>2];Y=G[l+288>>2];Z=G[l+220>>2];Ca=G[l+252>>2];if((Z|0)<(Ca|0)){a=M(S,Q);G[l+164>>2]=(a|0)<(R|0)?a:R;G[l+196>>2]=M(Q-1|0,S)+1;G[l+192>>2]=M(W-1|0,Y)+1;a=M(Y,W);G[l+160>>2]=(a|0)<(X|0)?a:X;break g}_=G[l+316>>2];$=G[l+284>>2];ka=G[l+216>>2];B=G[l+248>>2];if((ka|0)>=(B|0)){Da=G[l+304>>2];Ea=G[l+272>>2];Ga=G[l+208>>2];Ha=G[l+240>>2];Va=G[l+116>>2];Ia=G[l+244>>2];Xa=G[l+120>>2];Ya=G[l+124>>2];Za=G[l+128>>2];_a=G[l+132>>2];la=G[l+280>>2];c=M(la,ka);ma=G[l+312>>2];Ja=(c|0)<(ma|0)?c:ma;c=M($,Z);$a=(c|0)<(_|0)?c:_;na=G[l+276>>2];oa=G[l+212>>2];c=M(na,oa);pa=G[l+308>>2];cb=(c|0)<(pa|0)?c:pa;Ka=M(ka-1|0,la)+1|0;db=M(Z-1|0,$)+1|0;eb=M(oa-1|0,na)+1|0;while(1){e=V-1|0;d=M(e,S);G[l+196>>2]=d+1;c=M(S,V);c=(c|0)<(R|0)?c:R;G[l+164>>2]=c;fb=c-d|0;gb=M(e,_a);e=Ba;while(1){f=e-1|0;d=M(f,Y);G[l+192>>2]=d+1;c=M(e,Y);c=(c|0)<(X|0)?c:X;G[l+160>>2]=c;h:{if((oa|0)>=(Ia|0)){hb=M(c-d|0,fb);ib=M(f,Za)+gb|0;s=Ca;while(1){f=s-1|0;d=M(f,$);G[l+188>>2]=d+1;c=M(s,$);c=(c|0)<(_|0)?c:_;G[l+156>>2]=c;i:{if((Ga|0)>=(Ha|0)){jb=M(c-d|0,hb);kb=M(f,Ya)+ib|0;U=B;while(1){f=U-1|0;d=M(f,la);G[l+184>>2]=d+1;c=M(U,la);c=(c|0)<(ma|0)?c:ma;G[l+152>>2]=c;mb=M(c-d|0,jb);nb=M(f,Xa)+kb|0;O=Ia;while(1){f=O-1|0;d=M(f,na);G[l+180>>2]=d+1;c=M(O,na);c=(c|0)<(pa|0)?c:pa;G[l+148>>2]=c;ob=M(c-d|0,mb);pb=M(f,Va)+nb|0;c=Ha;while(1){d=M(c,Ea);x=(d|0)<(Da|0)?d:Da;G[l+144>>2]=x;v=M(c-1|0,Ea);G[l+176>>2]=v+1;d=0;j:{k:{if(!((N|0)<=0|G[k>>2]>0)){while(1){u=d<<2;o=G[u+(l+144|0)>>2];z=G[u+(l+80|0)>>2];if((o|0)<(z|0)){break j}C=G[u+(l+176|0)>>2];n=G[u+(l+48|0)>>2];if((C|0)>(n|0)){break j}f=G[u+(l+16|0)>>2];p=f>>31;r=u+(l+368|0)|0;D=(f^p)-p|0;f=(n-z|0)/(D|0)|0;p=f+1|0;G[r>>2]=p;if((f|0)<0){break k}P=u+(l+336|0)|0;n=o-C|0;f=n+1|0;G[P>>2]=f;if((n|0)<0){break k}if(d){G[P>>2]=M(f,G[(l+u|0)+332>>2])}aa=z-1|0;f=o-1|0;o=C-1|0;while(1){if((o-aa|0)%(D|0)|0){n=(f|0)>(o|0);o=o+1|0;if(n){continue}break j}break}while(1){if((f-aa|0)%(D|0)|0){n=(f|0)>(o|0);f=f-1|0;if(n){continue}break j}break}f=z-C|0;o=(f|0)>0?f:0;f=C-z|0;while(1){if((f+o|0)%(D|0)|0){o=o+1|0;if((o|0)>2]){continue}break j}break}if(d){G[r>>2]=M(p,G[(l+u|0)+364>>2])}d=d+1|0;if((N|0)!=(d|0)){continue}break}}so(a,c+pb|0,M(x-v|0,ob),b,ba,g,w,ca,l+12|0,k);if(!(!j|!G[l+12>>2])){G[j>>2]=1}da=l+176|0;aa=l+144|0;ea=l+80|0;v=l+48|0;r=l+16|0;d=0;x=0;fa=0;E=0;ga=0;m=Fa-192|0;Fa=m;l:{if(G[k>>2]>0){break l}G[m+112>>2]=0;G[m+116>>2]=0;G[m+80>>2]=0;G[m+84>>2]=0;G[m+48>>2]=0;G[m+52>>2]=0;G[m+104>>2]=0;G[m+108>>2]=0;G[m+96>>2]=0;G[m+100>>2]=0;G[m+64>>2]=0;G[m+68>>2]=0;G[m+72>>2]=0;G[m+76>>2]=0;G[m+32>>2]=0;G[m+36>>2]=0;G[m+40>>2]=0;G[m+44>>2]=0;T=1;G[m>>2]=1;G[m+160>>2]=1;G[m+128>>2]=1;G[m+132>>2]=1;G[m+4>>2]=1;G[m+8>>2]=1;G[m+164>>2]=1;G[m+168>>2]=1;G[m+136>>2]=1;G[m+12>>2]=1;G[m+172>>2]=1;G[m+140>>2]=1;G[m+144>>2]=1;G[m+16>>2]=1;G[m+20>>2]=1;G[m+176>>2]=1;G[m+180>>2]=1;G[m+148>>2]=1;m:{n:{if((N|0)<=0){t=1;break n}while(1){y=E<<2;P=G[y+aa>>2];u=G[y+ea>>2];if((P|0)<(u|0)){break l}C=G[y+da>>2];d=G[y+v>>2];if((C|0)>(d|0)){break l}f=G[r+y>>2];G[m+y>>2]=f;o=y+(m+160|0)|0;n=d-u|0;d=f>>31;z=(d^f)-d|0;D=(n|0)/(z|0)|0;p=D+1|0;G[o>>2]=p;if((D|0)<0){break m}x=y+(m+128|0)|0;f=P-C|0;d=f+1|0;G[x>>2]=d;if((f|0)<0){break m}if(E){G[x>>2]=M(d,G[(m+y|0)+124>>2])}n=u-1|0;t=P-1|0;d=C-1|0;while(1){if((d-n|0)%(z|0)|0){f=(d|0)<(t|0);d=d+1|0;if(f){continue}break l}break}while(1){if((t-n|0)%(z|0)|0){f=(d|0)<(t|0);t=t-1|0;if(f){continue}break l}break}n=1-u|0;f=(n+t|0)/(z|0)|0;G[y+(m- -64|0)>>2]=(f|0)<(D|0)?f:D;d=(d+n|0)/(z|0)|0;G[y+(m+96|0)>>2]=(d|0)>0?d:0;d=u-C|0;d=(d|0)>0?d:0;f=C-u|0;n=y+(m+32|0)|0;o:{while(1){if(!((d+f|0)%(z|0)|0)){break o}d=d+1|0;if((d|0)>2]){continue}break}G[n>>2]=d;break l}G[n>>2]=d;if(E){G[o>>2]=M(p,G[(m+y|0)+156>>2])}E=E+1|0;if((N|0)!=(E|0)){continue}break}x=G[m+96>>2];E=G[m+64>>2];fa=G[m+112>>2];d=G[m+80>>2];t=G[m>>2];if((t|0)!=1){break n}T=(E-x|0)+1|0}if((d|0)<(fa|0)){break l}n=G[m+76>>2];qa=G[m+108>>2];if((n|0)<(qa|0)){break l}La=M(A,T);f=(t|0)>0;Ma=f?T:0-T|0;ta=G[m+160>>2];qb=f?x:ta+(x^-1)|0;ua=G[m+4>>2];f=ua>>31;rb=(f^ua)-f|0;va=G[m+8>>2];f=va>>31;sb=(f^va)-f|0;wa=G[m+12>>2];f=wa>>31;tb=(f^wa)-f|0;xa=G[m+16>>2];f=xa>>31;ub=(f^xa)-f|0;f=t>>31;Na=M((f^t)-f|0,T);vb=G[m+128>>2];wb=G[m+32>>2];Oa=G[m+36>>2];xb=G[m+132>>2];ya=G[m+164>>2];Pa=G[m+40>>2];yb=G[m+136>>2];za=G[m+168>>2];Qa=G[m+44>>2];zb=G[m+140>>2];Aa=G[m+172>>2];Ab=G[m+176>>2];Ra=G[m+48>>2];Bb=(d-fa|0)+1|0;Cb=(n-qa|0)+1|0;Sa=G[m+72>>2];ra=G[m+104>>2];Db=(Sa-ra|0)+1|0;Ta=G[m+68>>2];sa=G[m+100>>2];Eb=(Ta-sa|0)+1|0;Fb=(N|0)<5;Gb=(N|0)<4;Hb=(N|0)<3;Ib=(N|0)<2;y=(ba|0)!=2;d=0;while(1){p:{if(Fb){f=d;break p}p=G[ea+16>>2];n=G[da+16>>2];while(1){f=d;d=d+1|0;if((((f+n|0)+Ra|0)-p|0)%(ub|0)|0){continue}break}}v=(xa|0)>0?M(fa+ga|0,Aa):Ab-M((fa+ga|0)+1|0,Aa)|0;u=M(f+Ra|0,zb);ha=0;d=0;while(1){q:{if(Gb){o=d;break q}p=G[ea+12>>2];n=G[da+12>>2];while(1){o=d;d=d+1|0;if((((n+o|0)+Qa|0)-p|0)%(tb|0)|0){continue}break}}d=(wa|0)>0?M(za,ha+qa|0):Aa-M(za,(ha+qa|0)+1|0)|0;if((ra|0)<=(Sa|0)){z=d+v|0;C=M(o+Qa|0,yb)+u|0;ia=0;d=0;while(1){r:{if(Hb){p=d;break r}r=G[ea+8>>2];n=G[da+8>>2];while(1){p=d;d=d+1|0;if((((n+p|0)+Pa|0)-r|0)%(sb|0)|0){continue}break}}d=(va|0)>0?M(ya,ia+ra|0):za-M(ya,(ia+ra|0)+1|0)|0;if((sa|0)<=(Ta|0)){D=d+z|0;P=(M(p+Pa|0,xb)+C|0)+wb|0;ja=0;d=0;while(1){s:{if(Ib){n=d;break s}aa=G[ea+4>>2];r=G[da+4>>2];while(1){n=d;d=d+1|0;if((((n+r|0)+Oa|0)-aa|0)%(rb|0)|0){continue}break}}r=(ua|0)>0?M(ja+sa|0,ta):ya-M((ja+sa|0)+1|0,ta)|0;t:{if((x|0)>(E|0)){break t}d=M(n+Oa|0,vb)+P|0;t=(r+D|0)+qb|0;r=x;if(!y){while(1){bb(i+t|0,d+ca|0,T);bb(M(t,A)+h|0,M(d,A)+w|0,La);t=t+Ma|0;d=d+Na|0;r=r+T|0;if((E|0)>=(r|0)){continue}break t}}while(1){bb(M(t,A)+h|0,M(d,A)+w|0,La);t=t+Ma|0;d=d+Na|0;r=r+T|0;if((E|0)>=(r|0)){continue}break}}d=n+1|0;ja=ja+1|0;if((Eb|0)!=(ja|0)){continue}break}}d=p+1|0;ia=ia+1|0;if((Db|0)!=(ia|0)){continue}break}}d=o+1|0;ha=ha+1|0;if((Cb|0)!=(ha|0)){continue}break}d=f+1|0;ga=ga+1|0;if((Bb|0)!=(ga|0)){continue}break}break l}G[k>>2]=323}Fa=m+192|0;break j}G[k>>2]=323}d=(c|0)!=(Ga|0);c=c+1|0;if(d){continue}break}c=(O|0)!=(oa|0);O=O+1|0;if(c){continue}break}c=(U|0)!=(ka|0);U=U+1|0;if(c){continue}break}break i}G[l+152>>2]=Ja;G[l+184>>2]=Ka;G[l+180>>2]=eb;G[l+148>>2]=cb}c=(s|0)!=(Z|0);s=s+1|0;if(c){continue}break}break h}G[l+156>>2]=$a;G[l+188>>2]=db;G[l+184>>2]=Ka;G[l+152>>2]=Ja}c=(e|0)!=(W|0);e=e+1|0;if(c){continue}break}c=(Q|0)!=(V|0);V=V+1|0;if(c){continue}break}break g}a=M(S,Q);G[l+164>>2]=(a|0)<(R|0)?a:R;G[l+196>>2]=M(Q-1|0,S)+1;G[l+192>>2]=M(W-1|0,Y)+1;a=M(Y,W);G[l+160>>2]=(a|0)<(X|0)?a:X;G[l+188>>2]=M(Z-1|0,$)+1;a=M($,Z);G[l+156>>2]=(a|0)<(_|0)?a:_}if((ba|0)==2){Wa(ca)}Wa(w);break a}G[k>>2]=113}Fa=l+400|0}function zh(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;l=Fa-29104|0;Fa=l;k=G[j>>2];a:{if((k|0)>0){break a}b:{c:{if((yc(a,b,c,d,e,f,g,h,1,l+29032|0,l+29024|0,l+28992|0,l+29088|0,l+29100|0,l+29096|0,l+29064|0,l+29056|0,l+29084|0,l+29072|0,l+29048|0,l+29092|0,l+29040|0,l+28832|0,j)|0)>0){break c}if(G[l+29100>>2]==16){Ne(l+28992|0,l+28960|0)}if(!(g|h)){k=G[j>>2];break b}c=0;d=0;while(1){e=G[l+29096>>2];k=e;e=e>>31;r=G[l+29072>>2];q=G[l+29076>>2];f=G[l+29068>>2];m=G[l+29064>>2];o=Au(G[l+29048>>2],G[l+29052>>2],x,y);m=m+o|0;f=Ia+f|0;f=m>>>0>>0?f+1|0:f;u=m;m=G[l+29056>>2];s=G[l+29060>>2];o=G[l+29084>>2];n=Au(m,s,o,o>>31);o=u+n|0;f=Ia+f|0;Jb(a,o,o>>>0>>0?f+1|0:f,1,j);k=g>>>0>>0&(e|0)>=(h|0)|(e|0)>(h|0)?g:k;e=k;f=e>>31;e=q-((m>>>0>r>>>0)+s|0)|0;r=r-m|0;m=r;r=k>>>0>>0&(e|0)>=(f|0)|(e|0)>(f|0);m=r?k:m;d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{e=G[l+29100>>2];switch(e-11|0){case 30:break g;case 0:break h;case 10:break i;case 31:break j;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break m;case 5:break n;default:break o}}p:{switch(e-81|0){case 1:break k;case 0:break p;default:break m}}s=(c<<3)+i|0;v=L[l+29032>>3];e=v!=1;t=L[l+29024>>3];if(!(e|t!=0x8000000000000000)){if((m|0)<=0){break e}q=0;k=0;if(m-1>>>0>=3){n=m&-4;o=0;while(1){e=k<<3;f=l+32|0;r=e+f|0;u=e+s|0;w=G[u>>2];u=G[u+4>>2]^-2147483648;G[r>>2]=w;G[r+4>>2]=u;r=e|8;u=r+f|0;r=r+s|0;w=G[r>>2];r=G[r+4>>2]^-2147483648;G[u>>2]=w;G[u+4>>2]=r;r=e|16;u=r+f|0;r=r+s|0;w=G[r>>2];r=G[r+4>>2]^-2147483648;G[u>>2]=w;G[u+4>>2]=r;e=e|24;f=e+f|0;e=e+s|0;r=G[e>>2];e=G[e+4>>2]^-2147483648;G[f>>2]=r;G[f+4>>2]=e;k=k+4|0;o=o+4|0;if((n|0)!=(o|0)){continue}break}}e=m&3;if(!e){break e}while(1){f=k<<3;o=f+(l+32|0)|0;f=f+s|0;n=G[f>>2];f=G[f+4>>2]^-2147483648;G[o>>2]=n;G[o+4>>2]=f;k=k+1|0;q=q+1|0;if((e|0)!=(q|0)){continue}break}break e}if(!e&t==0){break f}k=0;if((m|0)<=0){break e}while(1){q:{r:{o=k<<3;e=o+s|0;p=(+J[e>>2]+ +J[e+4>>2]*4294967296-t)/v;if(p<-0x8000000000000000){G[j>>2]=-11;break r}if(p>0x8000000000000000){G[j>>2]=-11;f=2147483647;e=-1;break q}if(p>=0){p=p+.5;if(!(O(p)<0x8000000000000000)){break r}f=O(p)>=1?~~(p>0?Q(S(p*2.3283064365386963e-10),4294967295):T((p-+(~~p>>>0>>>0))*2.3283064365386963e-10))>>>0:0;e=~~p>>>0;break q}p=p+-.5;if(!(O(p)<0x8000000000000000)){break r}f=O(p)>=1?~~(p>0?Q(S(p*2.3283064365386963e-10),4294967295):T((p-+(~~p>>>0>>>0))*2.3283064365386963e-10))>>>0:0;e=~~p>>>0;break q}f=-2147483648;e=0}o=o+(l+32|0)|0;G[o>>2]=e;G[o+4>>2]=f;k=k+1|0;if((k|0)!=(m|0)){continue}break}break e}if(H[l+28961|0]==115){break m}o=(c<<3)+i|0;s=l+28960|0;n=G[l+29088>>2];f=l+32|0;q=0;k=Fa-32|0;Fa=k;p=L[l+29032>>3];t=L[l+29024>>3];s:{if(!(p==1&t==0)){if((m|0)<=0){break s}e=f;while(1){r=o+(q<<3)|0;L[k+16>>3]=(+J[r>>2]+ +J[r+4>>2]*4294967296-t)/p;Eb(e,s,k+16|0);e=e+n|0;if(H[e|0]){G[j>>2]=-11}q=q+1|0;if((q|0)!=(m|0)){continue}break}break s}if((m|0)<=0){break s}e=f;while(1){r=o+(q<<3)|0;L[k>>3]=+J[r>>2]+ +J[r+4>>2]*4294967296;Eb(e,s,k);e=e+n|0;if(H[e|0]){G[j>>2]=-11}q=q+1|0;if((q|0)!=(m|0)){continue}break}}q=jb(f,44);if(q){while(1){E[q|0]=46;q=jb(q,44);if(q){continue}break}}Fa=k+32|0;e=G[l+29084>>2];f=G[l+29088>>2];if((e|0)!=(f|0)){break l}e=M(e,m);Wb(a,e,e>>31,l+32|0,j);break d}G[l>>2]=b;G[l+4>>2]=l+28992;a=l+28864|0;Ya(a,81,8813,l);Ua(a);if(G[l+29092>>2]==1){k=311;G[j>>2]=311;break a}k=312;G[j>>2]=312;break a}wd(a,f,m,e-f|0,l+32|0,j);break d}e=(c<<3)+i|0;p=L[l+29032>>3];t=L[l+29024>>3];t:{if(!(p==1&t==0)){if((m|0)<=0){break t}k=0;if((m|0)!=1){o=m&-2;q=0;while(1){f=k<<3;s=l+32|0;n=e+f|0;L[f+s>>3]=(+J[n>>2]+ +J[n+4>>2]*4294967296-t)/p;f=f|8;n=f+s|0;f=e+f|0;L[n>>3]=(+J[f>>2]+ +J[f+4>>2]*4294967296-t)/p;k=k+2|0;q=q+2|0;if((o|0)!=(q|0)){continue}break}}if(!(m&1)){break t}f=k<<3;e=e+f|0;L[f+(l+32|0)>>3]=(+J[e>>2]+ +J[e+4>>2]*4294967296-t)/p;break t}if((m|0)<=0){break t}q=0;k=0;if(m-1>>>0>=3){n=m&-4;o=0;while(1){f=k<<3;s=l+32|0;r=e+f|0;L[f+s>>3]=+J[r>>2]+ +J[r+4>>2]*4294967296;r=f|8;u=r+s|0;r=e+r|0;L[u>>3]=+J[r>>2]+ +J[r+4>>2]*4294967296;r=f|16;u=r+s|0;r=e+r|0;L[u>>3]=+J[r>>2]+ +J[r+4>>2]*4294967296;f=f|24;r=f+s|0;f=e+f|0;L[r>>3]=+J[f>>2]+ +J[f+4>>2]*4294967296;k=k+4|0;o=o+4|0;if((n|0)!=(o|0)){continue}break}}f=m&3;if(!f){break t}while(1){o=k<<3;n=o+(l+32|0)|0;o=e+o|0;L[n>>3]=+J[o>>2]+ +J[o+4>>2]*4294967296;k=k+1|0;q=q+1|0;if((f|0)!=(q|0)){continue}break}}_c(a,m,G[l+29084>>2],l+32|0,j);break d}e=(c<<3)+i|0;p=L[l+29032>>3];t=L[l+29024>>3];u:{if(!(p==1&t==0)){if((m|0)<=0){break u}k=0;if((m|0)!=1){f=m&-2;o=0;while(1){q=l+32|0;s=e+(k<<3)|0;K[q+(k<<2)>>2]=(+J[s>>2]+ +J[s+4>>2]*4294967296-t)/p;s=k|1;n=q+(s<<2)|0;q=e+(s<<3)|0;K[n>>2]=(+J[q>>2]+ +J[q+4>>2]*4294967296-t)/p;k=k+2|0;o=o+2|0;if((f|0)!=(o|0)){continue}break}}if(!(m&1)){break u}e=e+(k<<3)|0;K[(l+32|0)+(k<<2)>>2]=(+J[e>>2]+ +J[e+4>>2]*4294967296-t)/p;break u}if((m|0)<=0){break u}o=0;k=0;if(m-1>>>0>=3){s=m&-4;q=0;while(1){f=l+32|0;n=e+(k<<3)|0;K[f+(k<<2)>>2]=+J[n>>2]+ +J[n+4>>2]*4294967296;n=k|1;r=f+(n<<2)|0;n=e+(n<<3)|0;K[r>>2]=+J[n>>2]+ +J[n+4>>2]*4294967296;n=k|2;r=f+(n<<2)|0;n=e+(n<<3)|0;K[r>>2]=+J[n>>2]+ +J[n+4>>2]*4294967296;n=k|3;r=f+(n<<2)|0;f=e+(n<<3)|0;K[r>>2]=+J[f>>2]+ +J[f+4>>2]*4294967296;k=k+4|0;q=q+4|0;if((s|0)!=(q|0)){continue}break}}f=m&3;if(!f){break u}while(1){q=e+(k<<3)|0;K[(l+32|0)+(k<<2)>>2]=+J[q>>2]+ +J[q+4>>2]*4294967296;k=k+1|0;o=o+1|0;if((f|0)!=(o|0)){continue}break}}$c(a,m,G[l+29084>>2],l+32|0,j);break d}f=(c<<3)+i|0;t=L[l+29032>>3];v=L[l+29024>>3];v:{if(!(t==1&v==0)){k=0;if((m|0)<=0){break v}while(1){n=(l+32|0)+(k<<1)|0;e=f+(k<<3)|0;p=(+J[e>>2]+ +J[e+4>>2]*4294967296-v)/t;w:{if(p<-32768.49){G[j>>2]=-11;e=32768;break w}if(p>32767.49){G[j>>2]=-11;e=32767;break w}x:{if(p>=0){p=p+.5;if(!(O(p)<2147483648)){break x}e=~~p;break w}p=p+-.5;if(!(O(p)<2147483648)){break x}e=~~p;break w}e=-2147483648}F[n>>1]=e;k=k+1|0;if((m|0)!=(k|0)){continue}break}break v}if((m|0)<=0){break v}k=0;if((m|0)!=1){s=m&-2;o=0;while(1){n=(l+32|0)+(k<<1)|0;e=f+(k<<3)|0;q=G[e+4>>2];e=G[e>>2];if(!q&e>>>0>=32768|q){G[j>>2]=-11;e=32767}F[n>>1]=e;q=k|1;e=f+(q<<3)|0;n=G[e+4>>2];e=G[e>>2];if(!(!n&e>>>0<=32767)){G[j>>2]=-11;e=32767}F[(l+32|0)+(q<<1)>>1]=e;k=k+2|0;o=o+2|0;if((s|0)!=(o|0)){continue}break}}if(!(m&1)){break v}o=(l+32|0)+(k<<1)|0;e=f+(k<<3)|0;f=G[e+4>>2];e=G[e>>2];if(!(!f&e>>>0<=32767)){G[j>>2]=-11;e=32767}F[o>>1]=e}Oe(a,m,G[l+29084>>2],l+32|0,j);break d}f=(c<<3)+i|0;t=L[l+29032>>3];v=L[l+29024>>3];y:{if(!(t==1&v==0)){k=0;if((m|0)<=0){break y}while(1){n=(l+32|0)+k|0;z:{A:{e=f+(k<<3)|0;p=(+J[e>>2]+ +J[e+4>>2]*4294967296-v)/t;if(p<-.49){G[j>>2]=-11;break A}if(p>255.49){G[j>>2]=-11;e=255;break z}p=p+.5;if(!(p<4294967296&p>=0)){break A}e=~~p>>>0;break z}e=0}E[n|0]=e;k=k+1|0;if((m|0)!=(k|0)){continue}break}break y}if((m|0)<=0){break y}k=0;if((m|0)!=1){s=m&-2;o=0;while(1){n=(l+32|0)+k|0;e=f+(k<<3)|0;q=G[e+4>>2];e=G[e>>2];if(!q&e>>>0>=256|q){G[j>>2]=-11;e=255}E[n|0]=e;q=k|1;e=f+(q<<3)|0;n=G[e+4>>2];e=G[e>>2];if(!(!n&e>>>0<=255)){G[j>>2]=-11;e=255}E[q+(l+32|0)|0]=e;k=k+2|0;o=o+2|0;if((s|0)!=(o|0)){continue}break}}if(!(m&1)){break y}o=(l+32|0)+k|0;e=f+(k<<3)|0;f=G[e+4>>2];e=G[e>>2];if(!(!f&e>>>0<=255)){G[j>>2]=-11;e=255}E[o|0]=e}we(a,m,G[l+29084>>2],l+32|0,j);break d}f=(c<<3)+i|0;t=L[l+29032>>3];v=L[l+29024>>3];B:{if(!(t==1&v==0)){k=0;if((m|0)<=0){break B}while(1){n=(l+32|0)+(k<<2)|0;C:{D:{e=f+(k<<3)|0;p=(+J[e>>2]+ +J[e+4>>2]*4294967296-v)/t;if(p<-2147483648.49){G[j>>2]=-11;break D}if(p>2147483647.49){G[j>>2]=-11;e=2147483647;break C}if(p>=0){p=p+.5;if(!(O(p)<2147483648)){break D}e=~~p;break C}p=p+-.5;if(!(O(p)<2147483648)){break D}e=~~p;break C}e=-2147483648}G[n>>2]=e;k=k+1|0;if((m|0)!=(k|0)){continue}break}break B}if((m|0)<=0){break B}k=0;if((m|0)!=1){s=m&-2;o=0;while(1){n=(l+32|0)+(k<<2)|0;e=f+(k<<3)|0;q=G[e+4>>2];e=G[e>>2];if(!q&e>>>0>=2147483648|q){G[j>>2]=-11;e=2147483647}G[n>>2]=e;q=k|1;e=f+(q<<3)|0;n=G[e+4>>2];e=G[e>>2];if(!(!n&e>>>0<=2147483647)){G[j>>2]=-11;e=2147483647}G[(l+32|0)+(q<<2)>>2]=e;k=k+2|0;o=o+2|0;if((s|0)!=(o|0)){continue}break}}if(!(m&1)){break B}o=(l+32|0)+(k<<2)|0;e=f+(k<<3)|0;f=G[e+4>>2];e=G[e>>2];if(!(!f&e>>>0<=2147483647)){G[j>>2]=-11;e=2147483647}G[o>>2]=e}$c(a,m,G[l+29084>>2],l+32|0,j);break d}if((m|0)<=0){break e}k=0;if((m|0)!=1){q=m&-2;o=0;while(1){n=k<<3;e=n+s|0;f=G[e+4>>2];e=G[e>>2];n=n+(l+32|0)|0;if((f|0)<0){G[j>>2]=-11;f=2147483647;e=-1}G[n>>2]=e;G[n+4>>2]=f;n=(k|1)<<3;e=n+s|0;f=G[e+4>>2];e=G[e>>2];n=n+(l+32|0)|0;if((f|0)<0){G[j>>2]=-11;f=2147483647;e=-1}G[n>>2]=e;G[n+4>>2]=f;k=k+2|0;o=o+2|0;if((q|0)!=(o|0)){continue}break}}if(!(m&1)){break e}k=k<<3;e=k+s|0;f=G[e+4>>2];e=G[e>>2];k=k+(l+32|0)|0;if((f|0)<0){G[j>>2]=-11;f=2147483647;e=-1}G[k>>2]=e;G[k+4>>2]=f}_c(a,m,G[l+29084>>2],l+32|0,j)}k=G[j>>2];if((k|0)>0){f=d;a=c+1|0;f=a?f:f+1|0;L[l+16>>3]=+(a>>>0)+ +(f|0)*4294967296;e=m;f=e>>31;a=c+e|0;f=d+f|0;L[l+24>>3]=+(a>>>0)+ +((a>>>0>>0?f+1|0:f)|0)*4294967296;a=l+28864|0;Ya(a,81,46437,l+16|0);Ua(a);break c}e=m;f=e>>31;r=f;h=h-(f+(e>>>0>g>>>0)|0)|0;g=g-e|0;if(!(h|g)){break b}f=d+r|0;c=c+e|0;f=c>>>0>>0?f+1|0:f;d=f;f=r+G[l+29060>>2]|0;m=e+G[l+29056>>2]|0;f=m>>>0>>0?f+1|0:f;e=m;G[l+29056>>2]=e;G[l+29060>>2]=f;if(G[l+29072>>2]!=(e|0)|G[l+29076>>2]!=(f|0)){continue}G[l+29056>>2]=0;G[l+29060>>2]=0;e=y;f=x+1|0;e=f?e:e+1|0;x=f;y=e;continue}}k=G[j>>2];break a}if((k|0)!=-11){break a}Ua(44927);k=412;G[j>>2]=412}Fa=l+29104|0;return k}function Ud(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,I=0,K=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0;q=Fa-29104|0;Fa=q;p=G[o>>2];a:{if(!(g|h)|(p|0)>0){break a}if(n){G[n>>2]=0}if((j|0)==2){cb(m,0,g)}if((yc(a,b,c,d,e,f,g,h,i>>31,q+29096|0,q+29088|0,q+28992|0,q+29064|0,q+29084|0,q+29080|0,q+29040|0,q+29032|0,q+29060|0,q+29048|0,q+29016|0,q+29076|0,q+29024|0,q+28864|0,o)|0)>0){p=G[o>>2];break a}G[q+29060>>2]=M(G[q+29060>>2],i);A=1;c=G[q+29080>>2];N=c;P=c>>31;b:{if(G[q+29084>>2]!=16){break b}Gd(q+28992|0,q+29072|0,q+29056|0,q+29068|0,o);c=G[q+29068>>2];if((c|0)<=0){break b}if(c-1>>>0>=7){d=c&-8;p=0;while(1){A=A*10*10*10*10*10*10*10*10;p=p+8|0;if((d|0)!=(p|0)){continue}break}}c=c&7;if(!c){break b}p=0;while(1){A=A*10;p=p+1|0;if((c|0)!=(p|0)){continue}break}}c:{if(k?0:(j|0)==1){break c}e=G[q+29028>>2];c=G[q+29024>>2];d=G[q+29084>>2];if(!e&(c|0)==1234554321&((d|0)%10|0)==1){break c}f=e-(c>>>0<32768)|0;if(((f|0)==-1&c-32768>>>0<4294901760|(f|0)!=-1)&(d|0)==21|(!e&c>>>0>255|(e|0)!=0)&(d|0)==11){break c}x=(d|0)==16?H[q+28864|0]==1?0:j:j}S=0-i|0;e=0;f=0;d:{while(1){d=g>>>0>>0&(h|0)<=(P|0)|(h|0)<(P|0)?g:N;c=d;d=c>>31;s=c;v=d;e:{if((i|0)>=0){d=G[q+29036>>2];j=G[q+29052>>2]+(d^-1)|0;c=G[q+29032>>2];r=c^-1;p=r+G[q+29048>>2]|0;j=Bu(p,p>>>0>>0?j+1|0:j,i,0);p=Ia;break e}c=G[q+29032>>2];d=G[q+29036>>2];j=Bu(c,d,S,0);p=Ia}r=j;j=G[q+29044>>2];u=G[q+29040>>2];t=Au(G[q+29016>>2],G[q+29020>>2],B,C);u=u+t|0;j=Ia+j|0;j=t>>>0>u>>>0?j+1|0:j;D=u;t=c;u=G[q+29060>>2];c=(u|0)/(i|0)|0;t=Au(t,d,c,c>>31);d=D+t|0;c=Ia+j|0;c=d>>>0>>0?c+1|0:c;t=r+1|0;p=r>>>0>>0&(p|0)<=(v|0)|(p|0)<(v|0);r=p?t:s;f:{g:{h:{i:{j:{k:{l:{m:{n:{j=G[q+29084>>2];switch(j-11|0){case 30:break g;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break h;case 5:break i;case 31:break k;case 10:break l;case 0:break m;default:break n}}o:{switch(j-81|0){case 1:break j;case 0:break o;default:break h}}j=u;u=q- -64|0;Tc(a,d,c,r,j,u,o);d=G[q+29024>>2];v=G[q+29028>>2];t=e+m|0;j=(e<<2)+l|0;w=L[q+29096>>3];y=L[q+29088>>3];c=w==1&y==0x8000000000000000;p:{q:{if(!x){r:{s:{if(c){if((r|0)<=0){break p}p=0;if((r|0)!=1){d=r&-2;v=0;while(1){t=j+(p<<2)|0;c=u+(p<<3)|0;s=G[c+4>>2];c=G[c>>2];if((s|0)!=-2147483648|c>>>0>=2147483648){G[o>>2]=-11;c=2147483647}G[t>>2]=c;t=p|1;c=u+(t<<3)|0;s=G[c+4>>2];c=G[c>>2];if(!((s|0)==-2147483648&c>>>0<=2147483647)){G[o>>2]=-11;c=2147483647}G[j+(t<<2)>>2]=c;p=p+2|0;v=v+2|0;if((d|0)!=(v|0)){continue}break}}if(!(r&1)){break p}c=u+(p<<3)|0;d=G[c+4>>2];c=G[c>>2];if((d|0)!=-2147483648|c>>>0>2147483647){break s}break r}if(w==1&y==0){break q}p=0;if((r|0)<=0){break p}while(1){d=j+(p<<2)|0;t:{u:{c=u+(p<<3)|0;z=(+J[c>>2]+ +G[c+4>>2]*4294967296)*w+y;if(z<-0x7ffffffffffffc00){G[o>>2]=-11;break u}if(z>0x7ffffffffffffc00){G[o>>2]=-11;c=2147483647;break t}if(!(O(z)<2147483648)){break u}c=~~z;break t}c=-2147483648}G[d>>2]=c;p=p+1|0;if((r|0)!=(p|0)){continue}break}break p}G[o>>2]=-11;c=2147483647}G[j+(p<<2)>>2]=c;break p}if(c){if((r|0)<=0){break p}p=0;while(1){s=u+(p<<3)|0;c=G[s>>2];s=G[s+4>>2];v:{if((c|0)==(d|0)&(s|0)==(v|0)){G[n>>2]=1;if((x|0)==1){G[j+(p<<2)>>2]=k;break v}E[p+t|0]=1;break v}if((s|0)!=-2147483648|c>>>0>=2147483648){G[o>>2]=-11;G[j+(p<<2)>>2]=2147483647;break v}G[j+(p<<2)>>2]=c}p=p+1|0;if((r|0)!=(p|0)){continue}break}break p}if(!(w==1&y==0)){if((r|0)<=0){break p}p=0;while(1){c=u+(p<<3)|0;s=G[c>>2];c=G[c+4>>2];w:{if((s|0)==(d|0)&(c|0)==(v|0)){G[n>>2]=1;if((x|0)==1){G[j+(p<<2)>>2]=k;break w}E[p+t|0]=1;break w}z=(+(s>>>0)+ +(c|0)*4294967296)*w+y;if(z<-0x7ffffffffffffc00){G[o>>2]=-11;G[j+(p<<2)>>2]=-2147483648;break w}if(z>0x7ffffffffffffc00){G[o>>2]=-11;G[j+(p<<2)>>2]=2147483647;break w}s=j+(p<<2)|0;if(O(z)<2147483648){c=~~z}else{c=-2147483648}G[s>>2]=c}p=p+1|0;if((r|0)!=(p|0)){continue}break}break p}if((r|0)<=0){break p}p=0;while(1){c=u+(p<<3)|0;s=G[c>>2];c=G[c+4>>2];x:{if((s|0)==(d|0)&(c|0)==(v|0)){G[n>>2]=1;if((x|0)==1){G[j+(p<<2)>>2]=k;break x}E[p+t|0]=1;break x}if((c|0)<0&s>>>0<=2147483647|(c|0)<-1){G[o>>2]=-11;G[j+(p<<2)>>2]=-2147483648;break x}if((c|0)>=0&s>>>0>=2147483648|(c|0)>0){G[o>>2]=-11;G[j+(p<<2)>>2]=2147483647;break x}G[j+(p<<2)>>2]=s}p=p+1|0;if((r|0)!=(p|0)){continue}break}break p}if((r|0)<=0){break p}p=0;if((r|0)!=1){t=r&-2;v=0;while(1){s=j+(p<<2)|0;d=u+(p<<3)|0;c=G[d+4>>2];d=G[d>>2];y:{if((c|0)<0&d>>>0<=2147483647|(c|0)<-1){G[o>>2]=-11;d=-2147483648;break y}if((c|0)>=0&d>>>0>=2147483648|(c|0)>0){G[o>>2]=-11;d=2147483647}}G[s>>2]=d;s=p|1;d=u+(s<<3)|0;c=G[d+4>>2];d=G[d>>2];z:{if((c|0)>=-1&d>>>0>=2147483648|(c|0)>=0){if((c|0)<=0&d>>>0<=2147483647|(c|0)<0){break z}G[o>>2]=-11;d=2147483647;break z}G[o>>2]=-11;d=-2147483648}G[j+(s<<2)>>2]=d;p=p+2|0;v=v+2|0;if((t|0)!=(v|0)){continue}break}}if(!(r&1)){break p}j=j+(p<<2)|0;d=u+(p<<3)|0;c=G[d+4>>2];d=G[d>>2];A:{if((c|0)>=-1&d>>>0>=2147483648|(c|0)>=0){if((c|0)<=0&d>>>0<=2147483647|(c|0)<0){break A}G[o>>2]=-11;d=2147483647;break A}G[o>>2]=-11;d=-2147483648}G[j>>2]=d}break f}j=c;c=q- -64|0;$d(a,d,j,r,u,c,o);bq(c,r,L[q+29096>>3],L[q+29088>>3],x,H[q+29024|0],k,e+m|0,n,(e<<2)+l|0,o);break f}j=c;c=q- -64|0;Pe(a,d,j,r,u,c,o);aq(c,r,L[q+29096>>3],L[q+29088>>3],x,F[q+29024>>1],k,e+m|0,n,(e<<2)+l|0,o);break f}j=c;c=q- -64|0;Uc(a,d,j,r,u,c,o);al(c,r,L[q+29096>>3],L[q+29088>>3],x,k,e+m|0,n,(e<<2)+l|0,o);break f}j=c;c=q- -64|0;Tc(a,d,j,r,u,c,o);$k(c,r,L[q+29096>>3],L[q+29088>>3],x,k,e+m|0,n,(e<<2)+l|0,o);break f}Jb(a,d,c,0,o);c=G[q+29060>>2];d=G[q+29064>>2];B:{if((c|0)==(d|0)){c=M(c,r);ic(a,c,c>>31,q- -64|0,o);break B}Rd(a,d,r,c-d|0,q- -64|0,o)}v=q- -64|0;z=L[q+29096>>3];T=L[q+29088>>3];U=G[q+29064>>2];V=e+m|0;D=(e<<2)+l|0;s=0;t=Fa-112|0;Fa=t;I=q+28864|0;W=Va(I);if((r|0)>0){while(1){C:{d=v+U|0;Q=H[d|0];E[d|0]=0;j=v;D:{E:{if(H[I|0]==1){break E}if(fb(I,v,W)){break E}j=d;if(!x){break D}G[n>>2]=1;if((x|0)==1){G[(s<<2)+D>>2]=k;break D}E[s+V|0]=1;break D}while(1){c=H[j|0];if((c|0)==32){j=j+1|0;continue}break}R=1;F:{switch(c-43|0){case 0:case 2:while(1){p=H[j+1|0];j=j+1|0;if((p|0)==32){continue}break};R=(c|0)==45?-1:1;c=p;break;default:break F}}y=0;if((c-48&255)>>>0<10){while(1){w=y*10+ +(c<<24>>24);p=j;while(1){c=H[p+1|0];j=p+1|0;p=j;if((c|0)==32){continue}break}y=w+-48;if((c-48&255)>>>0<=9){continue}break}}w=A;G:{H:{switch(c-44|0){case 0:case 2:break H;default:break G}}p=j;while(1){c=H[p+1|0];j=p+1|0;p=j;if((c|0)==32){continue}break}w=1;if((c-48&255)>>>0>=10){break G}while(1){y=y*10+ +(c<<24>>24)+-48;p=j;while(1){c=H[p+1|0];j=p+1|0;p=j;if((c|0)==32){continue}break}w=w*10;if((c-48&255)>>>0<=9){continue}break}}I:{if((c&254)!=68){K=1;p=0;break I}while(1){K=1;p=j;j=p+1|0;c=H[p+1|0];if((c|0)==32){continue}break}J:{switch(c-43|0){case 0:case 2:p=p+2|0;while(1){j=p;p=p+1|0;u=H[j|0];if((u|0)==32){continue}break};K=(c|0)==45?-1:1;c=u;break;default:break J}}p=0;if((c-48&255)>>>0>=10){break I}while(1){u=c;X=M(p,10)-48|0;p=j;while(1){c=H[p+1|0];j=p+1|0;p=j;if((c|0)==32){continue}break}p=(u<<24>>24)+X|0;if((c-48&255)>>>0<=9){continue}break}}if(c){G[t+48>>2]=H[23477]|H[23478]<<8|(H[23479]<<16|H[23480]<<24);c=H[23473]|H[23474]<<8|(H[23475]<<16|H[23476]<<24);G[t+40>>2]=H[23469]|H[23470]<<8|(H[23471]<<16|H[23472]<<24);G[t+44>>2]=c;c=H[23465]|H[23466]<<8|(H[23467]<<16|H[23468]<<24);G[t+32>>2]=H[23461]|H[23462]<<8|(H[23463]<<16|H[23464]<<24);G[t+36>>2]=c;c=H[23457]|H[23458]<<8|(H[23459]<<16|H[23460]<<24);G[t+24>>2]=H[23453]|H[23454]<<8|(H[23455]<<16|H[23456]<<24);G[t+28>>2]=c;c=H[23449]|H[23450]<<8|(H[23451]<<16|H[23452]<<24);G[t+16>>2]=H[23445]|H[23446]<<8|(H[23447]<<16|H[23448]<<24);G[t+20>>2]=c;c=t+16|0;Ua(c);G[t>>2]=v;Ya(c,81,43022,t);Ua(c);E[d|0]=Q;G[o>>2]=409;break C}w=y*+(R|0)/w*$b(10,+(M(p,K)|0))*z+T;K:{if(w<-0x7ffffffffffffc00){G[o>>2]=-11;G[(s<<2)+D>>2]=-2147483648;break K}if(w>0x7ffffffffffffc00){G[o>>2]=-11;G[(s<<2)+D>>2]=2147483647;break K}p=(s<<2)+D|0;if(O(w)<2147483648){c=~~w}else{c=-2147483648}G[p>>2]=c}}v=j;E[d|0]=Q;s=s+1|0;if((r|0)!=(s|0)){continue}}break}}Fa=t+112|0;break f}G[q>>2]=b;G[q+4>>2]=q+28992;a=q+28896|0;Ya(a,81,8924,q);Ua(a);p=311;if(G[q+29076>>2]==1){break d}p=312;break d}j=c;c=q- -64|0;Uc(a,d,j,r,u,c,o);_k(c,r,L[q+29096>>3],L[q+29088>>3],x,G[q+29024>>2],k,e+m|0,n,(e<<2)+l|0,o)}p=G[o>>2];if((p|0)>0){w=+(e>>>0)+ +(f|0)*4294967296;A=w+1;w=w+ +(r|0);L:{if(G[q+29076>>2]>0){G[q+32>>2]=b;L[q+24>>3]=w;L[q+16>>3]=A;Ya(q+28896|0,81,46757,q+16|0);break L}L[q+56>>3]=w;L[q+48>>3]=A;Ya(q+28896|0,81,46698,q+48|0)}Ua(q+28896|0);p=G[o>>2];break a}j=r;c=j>>31;d=j;v=c;h=h-(c+(j>>>0>g>>>0)|0)|0;g=g-j|0;if(h|g){j=M(i,r);p=j;c=p+G[q+29032>>2]|0;j=G[q+29036>>2]+(p>>31)|0;j=c>>>0

>>0?j+1|0:j;G[q+29032>>2]=c;p=j;G[q+29036>>2]=p;j=e;e=d;j=j+d|0;d=f+v|0;d=e>>>0>j>>>0?d+1|0:d;e=j;f=d;v=G[q+29052>>2];d=v;r=G[q+29048>>2];if((p|0)>=(d|0)&c>>>0>=r>>>0|(d|0)<(p|0)){j=Bu(c,p,r,v);d=B+j|0;s=Ia;C=C+s|0;C=d>>>0>>0?C+1|0:C;B=d;d=Au(r,v,j,s);G[q+29032>>2]=c-d;G[q+29036>>2]=p-(Ia+(c>>>0>>0)|0);continue}if((p|0)>0|(p|0)>=0){continue}d=B;B=Bu(c^-1,p^-1,r,v)+1|0;j=Ia;j=B?j:j+1|0;s=B;B=d-s|0;C=C-((d>>>0>>0)+j|0)|0;j=Au(r,v,s,j)+c|0;d=p+Ia|0;G[q+29032>>2]=j;G[q+29036>>2]=c>>>0>j>>>0?d+1|0:d;continue}break}if((p|0)!=-11){break a}Ua(44994);p=412}G[o>>2]=p}Fa=q+29104|0;return p}function yh(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;l=Fa-29104|0;Fa=l;m=G[j>>2];a:{if((m|0)>0){break a}b:{c:{if((yc(a,b,c,d,e,f,g,h,1,l+29032|0,l+29024|0,l+28992|0,l+29088|0,l+29100|0,l+29096|0,l+29064|0,l+29056|0,l+29084|0,l+29072|0,l+29048|0,l+29092|0,l+29040|0,l+28832|0,j)|0)>0){break c}c=G[l+29096>>2];w=c;x=c>>31;if(G[l+29100>>2]==16){Ne(l+28992|0,l+28960|0)}if(!(g|h)){m=G[j>>2];break b}c=0;d=0;while(1){n=G[l+29072>>2];r=G[l+29076>>2];f=G[l+29068>>2];k=G[l+29064>>2];e=Au(G[l+29048>>2],G[l+29052>>2],y,z);k=k+e|0;f=Ia+f|0;f=e>>>0>k>>>0?f+1|0:f;p=k;k=G[l+29056>>2];q=G[l+29060>>2];e=G[l+29084>>2];e=Au(k,q,e,e>>31);p=p+e|0;f=Ia+f|0;Jb(a,p,e>>>0>p>>>0?f+1|0:f,1,j);e=g>>>0>>0&(h|0)<=(x|0)|(h|0)<(x|0)?g:w;t=e>>31;p=e;f=n;e=k;k=r-((f>>>0>>0)+q|0)|0;e=f-e|0;f=e;e=e>>>0>p>>>0&(k|0)>=(t|0)|(k|0)>(t|0);n=e?p:f;d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{p:{q:{f=G[l+29100>>2];switch(f-11|0){case 30:break i;case 0:break j;case 10:break k;case 31:break l;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break o;case 5:break p;default:break q}}r:{switch(f-81|0){case 1:break m;case 0:break r;default:break o}}t=(c<<3)+i|0;s=L[l+29032>>3];f=s!=1;u=L[l+29024>>3];if(!(f|u!=0x8000000000000000)){if((n|0)<=0){break e}m=0;if((n|0)!=1){q=n&-2;e=0;while(1){p=m<<3;k=p+t|0;f=G[k+4>>2];k=G[k>>2];s:{if((f|0)<0){G[j>>2]=-11;k=0;r=-2147483648;break s}r=f^-2147483648}f=p+(l+32|0)|0;G[f>>2]=k;G[f+4>>2]=r;p=(m|1)<<3;k=p+t|0;f=G[k+4>>2];k=G[k>>2];r=f^-2147483648;t:{if((f|0)>0|(f|0)>=0){break t}G[j>>2]=-11;k=0;r=-2147483648}f=p+(l+32|0)|0;G[f>>2]=k;G[f+4>>2]=r;m=m+2|0;e=e+2|0;if((q|0)!=(e|0)){continue}break}}if(!(n&1)){break e}p=m<<3;k=p+t|0;f=G[k+4>>2];k=G[k>>2];if((f|0)<0){break h}q=f^-2147483648;break g}if(!f&u==0){break f}m=0;if((n|0)<=0){break e}while(1){u:{v:{k=m<<3;f=k+t|0;o=(+J[f>>2]+ +G[f+4>>2]*4294967296-u)/s;if(o<-0x8000000000000000){G[j>>2]=-11;break v}if(o>0x8000000000000000){G[j>>2]=-11;q=-1;p=2147483647;break u}if(o>=0){o=o+.5;if(!(O(o)<0x8000000000000000)){break v}q=~~o>>>0;p=O(o)>=1?~~(o>0?Q(S(o*2.3283064365386963e-10),4294967295):T((o-+(~~o>>>0>>>0))*2.3283064365386963e-10))>>>0:0;break u}o=o+-.5;if(!(O(o)<0x8000000000000000)){break v}q=~~o>>>0;p=O(o)>=1?~~(o>0?Q(S(o*2.3283064365386963e-10),4294967295):T((o-+(~~o>>>0>>>0))*2.3283064365386963e-10))>>>0:0;break u}q=0;p=-2147483648}f=k+(l+32|0)|0;G[f>>2]=q;G[f+4>>2]=p;m=m+1|0;if((n|0)!=(m|0)){continue}break}break e}if(H[l+28961|0]==115){break o}t=(c<<3)+i|0;r=l+28960|0;q=G[l+29088>>2];f=l+32|0;e=0;m=Fa-32|0;Fa=m;s=L[l+29032>>3];o=L[l+29024>>3];w:{if(!(s==1&o==0)){if((n|0)<=0){break w}k=f;while(1){p=t+(e<<3)|0;L[m+16>>3]=(+J[p>>2]+ +G[p+4>>2]*4294967296-o)/s;Eb(k,r,m+16|0);k=k+q|0;if(H[k|0]){G[j>>2]=-11}e=e+1|0;if((e|0)!=(n|0)){continue}break}break w}if((n|0)<=0){break w}k=f;while(1){p=t+(e<<3)|0;L[m>>3]=+J[p>>2]+ +G[p+4>>2]*4294967296;Eb(k,r,m);k=k+q|0;if(H[k|0]){G[j>>2]=-11}e=e+1|0;if((e|0)!=(n|0)){continue}break}}e=jb(f,44);if(e){while(1){E[e|0]=46;e=jb(e,44);if(e){continue}break}}Fa=m+32|0;k=G[l+29084>>2];f=G[l+29088>>2];if((k|0)!=(f|0)){break n}f=M(k,n);Wb(a,f,f>>31,l+32|0,j);break d}G[l>>2]=b;G[l+4>>2]=l+28992;a=l+28864|0;Ya(a,81,8813,l);Ua(a);if(G[l+29092>>2]==1){m=311;G[j>>2]=311;break a}m=312;G[j>>2]=312;break a}wd(a,f,n,k-f|0,l+32|0,j);break d}m=(c<<3)+i|0;s=L[l+29032>>3];o=L[l+29024>>3];x:{if(!(s==1&o==0)){if((n|0)<=0){break x}e=0;if((n|0)!=1){p=n&-2;t=0;while(1){q=e<<3;k=l+32|0;f=m+q|0;L[q+k>>3]=(+J[f>>2]+ +G[f+4>>2]*4294967296-o)/s;f=q|8;k=f+k|0;f=f+m|0;L[k>>3]=(+J[f>>2]+ +G[f+4>>2]*4294967296-o)/s;e=e+2|0;t=t+2|0;if((p|0)!=(t|0)){continue}break}}if(!(n&1)){break x}f=e<<3;e=f+(l+32|0)|0;f=f+m|0;L[e>>3]=(+J[f>>2]+ +G[f+4>>2]*4294967296-o)/s;break x}if((n|0)<=0){break x}t=0;e=0;if(n-1>>>0>=3){k=n&-4;p=0;while(1){r=e<<3;q=l+32|0;f=m+r|0;L[r+q>>3]=+J[f>>2]+ +G[f+4>>2]*4294967296;f=r|8;v=f+q|0;f=f+m|0;L[v>>3]=+J[f>>2]+ +G[f+4>>2]*4294967296;f=r|16;v=f+q|0;f=f+m|0;L[v>>3]=+J[f>>2]+ +G[f+4>>2]*4294967296;f=r|24;r=f+q|0;f=f+m|0;L[r>>3]=+J[f>>2]+ +G[f+4>>2]*4294967296;e=e+4|0;p=p+4|0;if((k|0)!=(p|0)){continue}break}}k=n&3;if(!k){break x}while(1){f=e<<3;p=f+(l+32|0)|0;f=f+m|0;L[p>>3]=+J[f>>2]+ +G[f+4>>2]*4294967296;e=e+1|0;t=t+1|0;if((k|0)!=(t|0)){continue}break}}_c(a,n,G[l+29084>>2],l+32|0,j);break d}q=(c<<3)+i|0;s=L[l+29032>>3];o=L[l+29024>>3];y:{if(!(s==1&o==0)){if((n|0)<=0){break y}m=0;if((n|0)!=1){p=n&-2;e=0;while(1){k=l+32|0;f=q+(m<<3)|0;K[k+(m<<2)>>2]=(+J[f>>2]+ +G[f+4>>2]*4294967296-o)/s;f=m|1;k=k+(f<<2)|0;f=q+(f<<3)|0;K[k>>2]=(+J[f>>2]+ +G[f+4>>2]*4294967296-o)/s;m=m+2|0;e=e+2|0;if((p|0)!=(e|0)){continue}break}}if(!(n&1)){break y}f=q+(m<<3)|0;K[(l+32|0)+(m<<2)>>2]=(+J[f>>2]+ +G[f+4>>2]*4294967296-o)/s;break y}if((n|0)<=0){break y}e=0;m=0;if(n-1>>>0>=3){k=n&-4;t=0;while(1){p=l+32|0;f=q+(m<<3)|0;K[p+(m<<2)>>2]=+J[f>>2]+ +G[f+4>>2]*4294967296;f=m|1;r=p+(f<<2)|0;f=q+(f<<3)|0;K[r>>2]=+J[f>>2]+ +G[f+4>>2]*4294967296;f=m|2;r=p+(f<<2)|0;f=q+(f<<3)|0;K[r>>2]=+J[f>>2]+ +G[f+4>>2]*4294967296;f=m|3;p=p+(f<<2)|0;f=q+(f<<3)|0;K[p>>2]=+J[f>>2]+ +G[f+4>>2]*4294967296;m=m+4|0;t=t+4|0;if((k|0)!=(t|0)){continue}break}}k=n&3;if(!k){break y}while(1){f=q+(m<<3)|0;K[(l+32|0)+(m<<2)>>2]=+J[f>>2]+ +G[f+4>>2]*4294967296;m=m+1|0;e=e+1|0;if((k|0)!=(e|0)){continue}break}}$c(a,n,G[l+29084>>2],l+32|0,j);break d}q=(c<<3)+i|0;u=L[l+29032>>3];s=L[l+29024>>3];z:{if(!(u==1&s==0)){m=0;if((n|0)<=0){break z}while(1){k=(l+32|0)+(m<<1)|0;f=q+(m<<3)|0;o=(+J[f>>2]+ +G[f+4>>2]*4294967296-s)/u;A:{if(o<-32768.49){G[j>>2]=-11;e=32768;break A}if(o>32767.49){G[j>>2]=-11;e=32767;break A}B:{if(o>=0){o=o+.5;if(!(O(o)<2147483648)){break B}e=~~o;break A}o=o+-.5;if(!(O(o)<2147483648)){break B}e=~~o;break A}e=-2147483648}F[k>>1]=e;m=m+1|0;if((n|0)!=(m|0)){continue}break}break z}m=0;if((n|0)<=0){break z}while(1){e=(l+32|0)+(m<<1)|0;k=q+(m<<3)|0;f=G[k+4>>2];k=G[k>>2];C:{if((f|0)<0&k>>>0<=4294934527|(f|0)<-1){G[j>>2]=-11;k=32768;break C}if((f|0)>=0&k>>>0>=32768|(f|0)>0){G[j>>2]=-11;k=32767;break C}}F[e>>1]=k;m=m+1|0;if((n|0)!=(m|0)){continue}break}}Oe(a,n,G[l+29084>>2],l+32|0,j);break d}q=(c<<3)+i|0;s=L[l+29032>>3];o=L[l+29024>>3];D:{if(!(s==1&o==0)){m=0;if((n|0)<=0){break D}while(1){k=(l+32|0)+m|0;E:{F:{f=q+(m<<3)|0;u=(+J[f>>2]+ +G[f+4>>2]*4294967296-o)/s;if(u<-.49){G[j>>2]=-11;break F}if(u>255.49){G[j>>2]=-11;e=255;break E}u=u+.5;if(!(u<4294967296&u>=0)){break F}e=~~u>>>0;break E}e=0}E[k|0]=e;m=m+1|0;if((n|0)!=(m|0)){continue}break}break D}m=0;if((n|0)<=0){break D}while(1){p=(l+32|0)+m|0;k=q+(m<<3)|0;f=G[k+4>>2];k=G[k>>2];G:{if((f|0)<0){G[j>>2]=-11;k=0;break G}if(!f&k>>>0>=256|f){G[j>>2]=-11;k=255}}E[p|0]=k;m=m+1|0;if((n|0)!=(m|0)){continue}break}}we(a,n,G[l+29084>>2],l+32|0,j);break d}r=(c<<3)+i|0;u=L[l+29032>>3];s=L[l+29024>>3];H:{if(!(u==1&s==0)){m=0;if((n|0)<=0){break H}while(1){k=(l+32|0)+(m<<2)|0;I:{J:{f=r+(m<<3)|0;o=(+J[f>>2]+ +G[f+4>>2]*4294967296-s)/u;if(o<-2147483648.49){G[j>>2]=-11;break J}if(o>2147483647.49){G[j>>2]=-11;e=2147483647;break I}if(o>=0){o=o+.5;if(!(O(o)<2147483648)){break J}e=~~o;break I}o=o+-.5;if(!(O(o)<2147483648)){break J}e=~~o;break I}e=-2147483648}G[k>>2]=e;m=m+1|0;if((n|0)!=(m|0)){continue}break}break H}if((n|0)<=0){break H}m=0;if((n|0)!=1){q=n&-2;e=0;while(1){p=(l+32|0)+(m<<2)|0;k=r+(m<<3)|0;f=G[k+4>>2];k=G[k>>2];K:{if((f|0)<0&k>>>0<=2147483647|(f|0)<-1){G[j>>2]=-11;k=-2147483648;break K}if((f|0)>=0&k>>>0>=2147483648|(f|0)>0){G[j>>2]=-11;k=2147483647;break K}}G[p>>2]=k;p=m|1;k=r+(p<<3)|0;f=G[k+4>>2];k=G[k>>2];L:{if((f|0)>=-1&k>>>0>=2147483648|(f|0)>=0){if((f|0)<=0&k>>>0<=2147483647|(f|0)<0){break L}G[j>>2]=-11;k=2147483647;break L}G[j>>2]=-11;k=-2147483648}G[(l+32|0)+(p<<2)>>2]=k;m=m+2|0;e=e+2|0;if((q|0)!=(e|0)){continue}break}}if(!(n&1)){break H}p=(l+32|0)+(m<<2)|0;k=r+(m<<3)|0;f=G[k+4>>2];k=G[k>>2];M:{if((f|0)>=-1&k>>>0>=2147483648|(f|0)>=0){if((f|0)<=0&k>>>0<=2147483647|(f|0)<0){break M}G[j>>2]=-11;k=2147483647;break M}G[j>>2]=-11;k=-2147483648}G[p>>2]=k}$c(a,n,G[l+29084>>2],l+32|0,j);break d}G[j>>2]=-11;k=0;q=-2147483648}f=p+(l+32|0)|0;G[f>>2]=k;G[f+4>>2]=q;break e}if((n|0)<=0){break e}bb(l+32|0,t,n<<3)}_c(a,n,G[l+29084>>2],l+32|0,j)}m=G[j>>2];if((m|0)>0){f=d;a=c+1|0;f=a?f:f+1|0;L[l+16>>3]=+(a>>>0)+ +(f|0)*4294967296;k=n>>31;a=c+n|0;k=d+k|0;L[l+24>>3]=+(a>>>0)+ +((a>>>0>>0?k+1|0:k)|0)*4294967296;a=l+28864|0;Ya(a,81,46630,l+16|0);Ua(a);break c}e=n;k=n>>31;h=h-((n>>>0>g>>>0)+k|0)|0;g=g-n|0;if(!(h|g)){break b}f=d+k|0;c=c+e|0;f=c>>>0>>0?f+1|0:f;d=f;k=k+G[l+29060>>2]|0;n=e+G[l+29056>>2]|0;k=n>>>0>>0?k+1|0:k;f=l;G[f+29056>>2]=n;G[f+29060>>2]=k;if(G[f+29072>>2]!=(n|0)|G[f+29076>>2]!=(k|0)){continue}G[l+29056>>2]=0;G[l+29060>>2]=0;e=z;f=y+1|0;e=f?e:e+1|0;y=f;z=e;continue}}m=G[j>>2];break a}if((m|0)!=-11){break a}Ua(44927);m=412;G[j>>2]=412}Fa=l+29104|0;return m}function sd(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;i=Fa-2208|0;Fa=i;G[a>>2]=0;d=G[c>>2];a:{if((d|0)>0){e=d;break a}if((d|0)==-106){G[c>>2]=0;m=1}if(G[47541]){e=ji();G[c>>2]=e;if((e|0)>0){break a}}b:{c:{d:{while(1){e=H[b|0];if((e|0)!=32){e:{if(!e){Ua(50141);break b}f:{g:{if((d|0)==-106){if(Va(b)>>>0<1025){break g}Ua(50183);break b}f=(e|0)==33;b=f+b|0;e=b;g=i+2176|0;h=i+1136|0;j=i+96|0;l=i+16|0;h:{i:{if(G[c>>2]<=0){if(g){E[g|0]=0}if(h){E[h|0]=0}if(j){E[j|0]=0}if(l){E[l|0]=0}while(1){d=H[e|0];if((d|0)!=32){j:{k:{l:{if((d|0)==45&(H[e+1|0]|32)==32){break l}if(!Xa(e,4377)){break l}if(Xa(e,33295)){break k}}if(!g){break j}e=H[41984]|H[41985]<<8;E[g+8|0]=e;E[g+9|0]=e>>>8;e=H[41980]|H[41981]<<8|(H[41982]<<16|H[41983]<<24);d=H[41976]|H[41977]<<8|(H[41978]<<16|H[41979]<<24);E[g|0]=d;E[g+1|0]=d>>>8;E[g+2|0]=d>>>16;E[g+3|0]=d>>>24;E[g+4|0]=e;E[g+5|0]=e>>>8;E[g+6|0]=e>>>16;E[g+7|0]=e>>>24;break j}d=Sb(e,42197);m:{if(d){if(g){k=d-e|0;if((k|0)>=17){break i}qb(g,e,k+3|0)}e=d+3|0;break m}if(!g){break m}d=Va(g)+g|0;E[d|0]=102;E[d+1|0]=105;E[d+2|0]=108;E[d+3|0]=101;E[d+4|0]=58;E[d+5|0]=47;E[d+6|0]=47;E[d+7|0]=0}d=jb(e,40);k=jb(e,91);n:{o:{p:{q:{if(h){if(d){n=d-e|0;if((n|0)>=1025){break i}qb(h,e,n);break q}if(k){d=k-e|0;if((d|0)>=1025){break i}qb(h,e,d);break o}if(Va(e)>>>0>=1025){break i}Za(h,e);break n}if(!d){break p}}e=d+1|0;d=jb(e,41);if(!d){break i}if(!j){break p}d=d-e|0;if((d|0)>=1025){break i}qb(j,e,d)}if(!k){break n}}e=k+1|0;d=jb(e,93);if(!d){break i}if(!l){break n}d=d-e|0;if((d|0)>=1025){break i}qb(l,e,d)}if(!g|!h){break j}if(Xa(g,42185)){break j}e=Sb(h,2750);if(!e|(H[e+3|0]|32)!=32){break j}e=H[42137]|H[42138]<<8|(H[42139]<<16|H[42140]<<24);E[g+15|0]=e;E[g+16|0]=e>>>8;E[g+17|0]=e>>>16;E[g+18|0]=e>>>24;e=H[42134]|H[42135]<<8|(H[42136]<<16|H[42137]<<24);d=H[42130]|H[42131]<<8|(H[42132]<<16|H[42133]<<24);E[g+8|0]=d;E[g+9|0]=d>>>8;E[g+10|0]=d>>>16;E[g+11|0]=d>>>24;E[g+12|0]=e;E[g+13|0]=e>>>8;E[g+14|0]=e>>>16;E[g+15|0]=e>>>24;e=H[42126]|H[42127]<<8|(H[42128]<<16|H[42129]<<24);d=H[42122]|H[42123]<<8|(H[42124]<<16|H[42125]<<24);E[g|0]=d;E[g+1|0]=d>>>8;E[g+2|0]=d>>>16;E[g+3|0]=d>>>24;E[g+4|0]=e;E[g+5|0]=e>>>8;E[g+6|0]=e>>>16;E[g+7|0]=e>>>24}e=G[c>>2]}else{e=e+1|0;continue}break}}break h}G[c>>2]=125}if(G[c>>2]<=0){break f}Ua(5e4);Ua(b);break d}Za(i+1136|0,b);E[i+96|0]=0;G[i+2176>>2]=1701603686;G[i+2180>>2]=3092282;E[i+16|0]=0}e=G[310142];while(1){if((e|0)<=0){break e}e=e-1|0;if(Xa(M(e,84)+1240576|0,i+2176|0)){continue}break}G[c>>2]=0;r:{if(!f){break r}d=G[(M(e,84)+1240576|0)+60>>2];if(!d){break r}Ja[d|0](i+1136|0)|0}s:{d=G[(M(e,84)+1240576|0)+48>>2];if(d){d=Ja[d|0](i+1136|0,i+12|0)|0;G[c>>2]=d;if(!d){break s}Ua(39966);Ua(b);break d}Ua(49952);Ua(b);break b}g=lb(1,8);G[a>>2]=g;if(!g){Ja[G[(M(e,84)+1240576|0)+56>>2]](G[i+12>>2])|0;Ua(54617);Ua(b);break c}d=lb(1,1736);G[g+4>>2]=d;if(!d){Ja[G[(M(e,84)+1240576|0)+56>>2]](G[i+12>>2])|0;Ua(54617);Ua(b);Wa(G[a>>2]);G[a>>2]=0;break c}h=Va(b)+1|0;h=ab((h|0)>32?h:32);G[d+12>>2]=h;if(!h){Ja[G[(M(e,84)+1240576|0)+56>>2]](G[i+12>>2])|0;Ua(50046);Ua(b);Wa(G[G[a>>2]+4>>2]);Wa(G[a>>2]);G[a>>2]=0;break b}f=lb(1001,8);G[d+96>>2]=f;if(!f){Ja[G[(M(e,84)+1240576|0)+56>>2]](G[i+12>>2])|0;Ua(49841);Ua(b);Wa(G[G[G[a>>2]+4>>2]+12>>2]);Wa(G[G[a>>2]+4>>2]);Wa(G[a>>2]);G[a>>2]=0;break c}f=lb(40,2880);G[d+1252>>2]=f;t:{u:{if(f){cb(d+1256|0,255,160);f=d+1728|0;G[f>>2]=38;G[f+4>>2]=39;f=d+1720|0;G[f>>2]=36;G[f+4>>2]=37;f=d+1712|0;G[f>>2]=34;G[f+4>>2]=35;f=d+1704|0;G[f>>2]=32;G[f+4>>2]=33;f=d+1696|0;G[f>>2]=30;G[f+4>>2]=31;f=d+1688|0;G[f>>2]=28;G[f+4>>2]=29;f=d+1680|0;G[f>>2]=26;G[f+4>>2]=27;f=d+1672|0;G[f>>2]=24;G[f+4>>2]=25;f=d+1664|0;G[f>>2]=22;G[f+4>>2]=23;f=d+1656|0;G[f>>2]=20;G[f+4>>2]=21;f=d+1648|0;G[f>>2]=18;G[f+4>>2]=19;f=d+1640|0;G[f>>2]=16;G[f+4>>2]=17;f=d+1632|0;G[f>>2]=14;G[f+4>>2]=15;f=d+1624|0;G[f>>2]=12;G[f+4>>2]=13;f=d+1616|0;G[f>>2]=10;G[f+4>>2]=11;f=d+1608|0;G[f>>2]=8;G[f+4>>2]=9;f=d+1600|0;G[f>>2]=6;G[f+4>>2]=7;f=d+1592|0;G[f>>2]=4;G[f+4>>2]=5;f=d+1584|0;G[f>>2]=2;G[f+4>>2]=3;G[d+1576>>2]=0;G[d+1580>>2]=1;G[d+92>>2]=1e3;f=G[i+12>>2];G[d+4>>2]=e;G[d>>2]=f;Za(h,b);G[d+40>>2]=0;G[d+44>>2]=0;G[d+32>>2]=0;G[d+36>>2]=0;G[d+128>>2]=-1;G[d+132>>2]=-1;G[d+84>>2]=1;G[d+72>>2]=-1;G[d+24>>2]=m;G[d+16>>2]=555;G[d+8>>2]=1;f=0;Hc(g,0,1,c);if(G[c>>2]>0){break t}d=G[G[a>>2]+4>>2];break u}Ja[G[(M(e,84)+1240576|0)+56>>2]](G[i+12>>2])|0;Ua(49897);Ua(b);Wa(G[G[G[a>>2]+4>>2]+96>>2]);Wa(G[G[G[a>>2]+4>>2]+12>>2]);Wa(G[G[a>>2]+4>>2]);Wa(G[a>>2]);G[a>>2]=0;break c}while(1){v:{e=f<<2;b=e+1243184|0;if(!G[b>>2]){break v}e=e+1243184|0;b=e+4|0;if(!G[b>>2]){break v}b=e+8|0;if(!G[b>>2]){break v}b=e+12|0;if(!G[b>>2]){break v}b=e+16|0;if(!G[b>>2]){break v}f=f+5|0;if((f|0)!=1e4){continue}break t}break}G[b>>2]=d}if(H[i+96|0]){j=G[a>>2];h=Fa-112|0;Fa=h;G[h+104>>2]=0;l=i+96|0;if(!(!l|G[c>>2]>0|!H[l|0])){ch(h+108|0,l,0,h+104|0);w:{if(G[h+104>>2]){tb(2,h);f=Fa-192|0;Fa=f;x:{if(G[c>>2]|!c){break x}b=362;y:{if(!j|!l){break y}G[47540]=1;G[309831]=0;G[309830]=0;E[1239392]=0;b=368;e=G[309833];d=G[309832];if(!e&(d|0)>0|((d|0)<=0?e:0)){break y}if(d?1:e){if((d|0)>0){b=0;while(1){d=b<<3;g=G[d+e>>2];if(g){Wa(g);G[d+G[309833]>>2]=0;e=G[309833]}G[(d+e|0)+4>>2]=0;b=b+1|0;if((b|0)>2]=G[j>>2]+1;z:{if(G[f+188>>2]>1){e=2;while(1){A:{G[c>>2]=0;mb(j,1,f+184|0,c);if(G[c>>2]){d=G[f+188>>2];break A}g=e;Cb(j,16,35480,f+16|0,0,c);B:{if(G[c>>2]){break B}Cb(j,41,33996,f+180|0,0,c);m=f+16|0;b=G[c>>2];if(b){if((b|0)!=204){break B}G[c>>2]=0;e=1}else{e=G[f+180>>2]}d=0;b=368;C:{if(!m){break C}k=G[309833];n=G[309832];if(!k&(n|0)>0|((n|0)<=0?k:0)){break C}if((n|0)>0){while(1){if(!Xa(m,G[k+(d<<3)>>2])){b=0;d=k+(d<<3)|0;if((e|0)<=G[d+4>>2]){break C}G[d+4>>2]=e;break C}d=d+1|0;if((n|0)!=(d|0)){continue}break}}b=360;D:{if(!k){d=ab(8);break D}d=ub(k,(n<<3)+8|0)}if(!d){break C}k=ab(Va(m)+1|0);if(!k){Wa(d);break C}b=0;k=Za(k,m);G[309833]=d;m=G[309832];d=d+(m<<3)|0;G[d+4>>2]=e;G[d>>2]=k;G[309832]=m+1}G[c>>2]=b}e=g+1|0;d=G[f+188>>2];if((g|0)<(d|0)){continue}}break}mb(j,d,f+184|0,c);if(G[c>>2]){break x}d=0;break z}b=f+184|0;mb(j,1,b,c);Td(j,f+16|0,f+180|0,c);mb(j,G[f+188>>2],b,c);if(G[c>>2]){break x}d=G[f+16>>2]<=0}b=dn(l);G[c>>2]=b;if(b){break x}b=Va(l);E:{while(1){e=b;b=e-1|0;if((b|0)<0){break E}if(H[b+l|0]!=47){continue}break}if((e|0)<=0){break E}b=(e|0)<999?e:999;o=bb(1239392,l,b)+b|0,p=0,E[o|0]=p}F:{G:{H:{while(1){I:{e=eh(1);if(e){break I}e=0;b=369;J:{K:{switch(G[47524]-1|0){case 3:if(!d){e=369;break I}e=G[309816];if(!e){b=363;break F}if(G[309823]){b=364;break G}b=G[309817];G[309823]=G[309816];G[309824]=b;G[309829]=G[309822];b=G[309821];G[309827]=G[309820];G[309828]=b;b=G[309819];G[309825]=G[309818];G[309826]=b;G[309816]=0;e=Qj(j,0,3);break J;case 2:e=G[309816];if(!e){b=363;break F}if(G[309823]){b=364;break G}b=G[309817];G[309823]=G[309816];G[309824]=b;G[309829]=G[309822];b=G[309821];G[309827]=G[309820];G[309828]=b;b=G[309819];G[309825]=G[309818];G[309826]=b;G[309816]=0;e=Qj(j,0,((d|0)!=0)<<1);break J;case 4:break I;case 0:break K;default:break H}}L:{if(G[310098]==2){rb(f+96|0,G[310118],80);break L}b=G[47540];G[47540]=b+1;G[f>>2]=b;Ya(f+96|0,80,29887,f)}E[f+175|0]=0;e=bn(j,f+96|0,0)}d=0;if(!e){continue}}break}b=e}e=G[309816];if(!e){break F}}Wa(e);G[309822]=0;G[309820]=0;G[309821]=0;G[309818]=0;G[309819]=0;G[309816]=0;G[309817]=0}e=G[309823];if(e){Wa(e);G[309829]=0;G[309827]=0;G[309828]=0;G[309825]=0;G[309826]=0;G[309823]=0;G[309824]=0}d=G[309833];e=G[309832];if(!(!d&(e|0)>0|((e|0)<=0?d:0)|!(e?1:d))){if((e|0)>0){e=0;while(1){g=e<<3;l=G[g+d>>2];if(l){Wa(l);G[g+G[309833]>>2]=0;d=G[309833]}G[(d+g|0)+4>>2]=0;e=e+1|0;if((e|0)>2]=b}Fa=f+192|0;break w}mb(G[h+108>>2],1,0,c);b=G[c>>2];if((b|0)<=0){d=h+25|0;while(1){Td(G[h+108>>2],h+100|0,h+96|0,c);b=1;if(G[h+100>>2]>0){while(1){e=b;Sd(G[h+108>>2],e,h,c);M:{if(G[h>>2]!=1431257936|G[h+4>>2]!=538989646){break M}if(!nb(d,41970,5)){break M}b=H[41971]|H[41972]<<8|(H[41973]<<16|H[41974]<<24);g=H[41967]|H[41968]<<8|(H[41969]<<16|H[41970]<<24);F[h+22>>1]=g;F[h+24>>1]=g>>>16;F[h+26>>1]=b;F[h+28>>1]=b>>>16;b=H[41965]|H[41966]<<8|(H[41967]<<16|H[41968]<<24);G[h+16>>2]=H[41961]|H[41962]<<8|(H[41963]<<16|H[41964]<<24);G[h+20>>2]=b;b=H[41957]|H[41958]<<8|(H[41959]<<16|H[41960]<<24);G[h+8>>2]=H[41953]|H[41954]<<8|(H[41955]<<16|H[41956]<<24);G[h+12>>2]=b;b=H[41949]|H[41950]<<8|(H[41951]<<16|H[41952]<<24);G[h>>2]=H[41945]|H[41946]<<8|(H[41947]<<16|H[41948]<<24);G[h+4>>2]=b}wb(j,h,c);b=e+1|0;if((e|0)>2]){continue}break}}xi(G[h+108>>2],0,c);Ke(j,c);b=G[c>>2];if((b|0)<=0){continue}break}}if((b|0)==107){G[c>>2]=0}Qb(G[h+108>>2],c)}mb(j,1,0,c)}Fa=h+112|0}if(!H[i+16|0]){break d}_m(G[a>>2],i+16|0,c);break d}}else{b=b+1|0;continue}break}G[c>>2]=124;Ua(50095);Ua(b)}e=G[c>>2];break a}e=113;G[c>>2]=113;break a}e=105;G[c>>2]=105}Fa=i+2208|0;return e}function Qe(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;l=Fa-29104|0;Fa=l;k=G[j>>2];a:{if((k|0)>0){break a}b:{c:{if((yc(a,b,c,d,e,f,g,h,1,l+29032|0,l+29024|0,l+28992|0,l+29088|0,l+29100|0,l+29096|0,l+29064|0,l+29056|0,l+29084|0,l+29072|0,l+29048|0,l+29092|0,l+29040|0,l+28832|0,j)|0)>0){break c}if(G[l+29100>>2]==16){Ne(l+28992|0,l+28960|0)}if(!(g|h)){k=G[j>>2];break b}c=0;d=0;while(1){e=G[l+29096>>2];k=e;e=k>>31;s=G[l+29072>>2];n=G[l+29076>>2];f=G[l+29068>>2];m=G[l+29064>>2];p=Au(G[l+29048>>2],G[l+29052>>2],v,w);m=m+p|0;f=Ia+f|0;f=m>>>0

>>0?f+1|0:f;x=m;m=G[l+29056>>2];q=G[l+29060>>2];p=G[l+29084>>2];r=Au(m,q,p,p>>31);p=x+r|0;f=Ia+f|0;Jb(a,p,p>>>0>>0?f+1|0:f,1,j);k=g>>>0>>0&(e|0)>=(h|0)|(e|0)>(h|0)?g:k;f=k>>31;e=n-((m>>>0>s>>>0)+q|0)|0;s=s-m|0;m=s;s=k>>>0>>0&(e|0)>=(f|0)|(e|0)>(f|0);m=s?k:m;d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{p:{e=G[l+29100>>2];switch(e-11|0){case 0:break h;case 10:break i;case 31:break j;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break m;case 5:break n;case 30:break o;default:break p}}switch(e-81|0){case 0:break g;case 1:break k;default:break m}}p=(c<<2)+i|0;u=L[l+29032>>3];e=u!=1;t=L[l+29024>>3];if(!(e|t!=2147483648)){if((m|0)<=0){break e}f=0;k=0;if(m-1>>>0>=3){r=m&-4;e=0;while(1){n=k<<2;q=l+32|0;G[n+q>>2]=G[p+n>>2]^-2147483648;s=n|4;G[s+q>>2]=G[p+s>>2]^-2147483648;s=n|8;G[s+q>>2]=G[p+s>>2]^-2147483648;n=n|12;G[n+q>>2]=G[p+n>>2]^-2147483648;k=k+4|0;e=e+4|0;if((r|0)!=(e|0)){continue}break}}e=m&3;if(!e){break e}while(1){n=k<<2;G[n+(l+32|0)>>2]=G[p+n>>2]^-2147483648;k=k+1|0;f=f+1|0;if((e|0)!=(f|0)){continue}break}break e}if(!e&t==0){break f}k=0;if((m|0)<=0){break e}while(1){q:{r:{f=k<<2;o=(+J[f+p>>2]-t)/u;if(o<-2147483648.49){G[j>>2]=-11;break r}if(o>2147483647.49){G[j>>2]=-11;e=2147483647;break q}if(o>=0){o=o+.5;if(!(O(o)<2147483648)){break r}e=~~o;break q}o=o+-.5;if(!(O(o)<2147483648)){break r}e=~~o;break q}e=-2147483648}G[f+(l+32|0)>>2]=e;k=k+1|0;if((k|0)!=(m|0)){continue}break}break e}if(H[l+28961|0]==115){break m}n=(c<<2)+i|0;q=l+28960|0;r=G[l+29088>>2];f=l+32|0;k=0;p=Fa-32|0;Fa=p;o=L[l+29032>>3];t=L[l+29024>>3];s:{if(!(o==1&t==0)){if((m|0)<=0){break s}e=f;while(1){L[p+16>>3]=(+J[n+(k<<2)>>2]-t)/o;Eb(e,q,p+16|0);e=e+r|0;if(H[e|0]){G[j>>2]=-11}k=k+1|0;if((k|0)!=(m|0)){continue}break}break s}if((m|0)<=0){break s}e=f;while(1){L[p>>3]=J[n+(k<<2)>>2];Eb(e,q,p);e=e+r|0;if(H[e|0]){G[j>>2]=-11}k=k+1|0;if((k|0)!=(m|0)){continue}break}}k=jb(f,44);if(k){while(1){E[k|0]=46;k=jb(k,44);if(k){continue}break}}Fa=p+32|0;e=G[l+29084>>2];f=G[l+29088>>2];if((e|0)!=(f|0)){break l}e=M(e,m);Wb(a,e,e>>31,l+32|0,j);break d}G[l>>2]=b;G[l+4>>2]=l+28992;a=l+28864|0;Ya(a,81,8813,l);Ua(a);if(G[l+29092>>2]==1){k=311;G[j>>2]=311;break a}k=312;G[j>>2]=312;break a}wd(a,f,m,e-f|0,l+32|0,j);break d}p=(c<<2)+i|0;o=L[l+29032>>3];t=L[l+29024>>3];t:{if(!(o==1&t==0)){if((m|0)<=0){break t}k=0;if((m|0)!=1){f=m&-2;e=0;while(1){n=l+32|0;L[n+(k<<3)>>3]=(+J[p+(k<<2)>>2]-t)/o;q=k|1;L[n+(q<<3)>>3]=(+J[p+(q<<2)>>2]-t)/o;k=k+2|0;e=e+2|0;if((f|0)!=(e|0)){continue}break}}if(!(m&1)){break t}L[(l+32|0)+(k<<3)>>3]=(+J[p+(k<<2)>>2]-t)/o;break t}if((m|0)<=0){break t}e=0;k=0;if(m-1>>>0>=3){q=m&-4;f=0;while(1){n=l+32|0;L[n+(k<<3)>>3]=J[p+(k<<2)>>2];r=k|1;L[n+(r<<3)>>3]=J[p+(r<<2)>>2];r=k|2;L[n+(r<<3)>>3]=J[p+(r<<2)>>2];r=k|3;L[n+(r<<3)>>3]=J[p+(r<<2)>>2];k=k+4|0;f=f+4|0;if((q|0)!=(f|0)){continue}break}}f=m&3;if(!f){break t}while(1){L[(l+32|0)+(k<<3)>>3]=J[p+(k<<2)>>2];k=k+1|0;e=e+1|0;if((f|0)!=(e|0)){continue}break}}_c(a,m,G[l+29084>>2],l+32|0,j);break d}p=(c<<2)+i|0;o=L[l+29032>>3];t=L[l+29024>>3];u:{if(!(o==1&t==0)){if((m|0)<=0){break u}k=0;if((m|0)!=1){n=m&-2;f=0;while(1){e=k<<2;q=l+32|0;K[e+q>>2]=(+J[e+p>>2]-t)/o;e=e|4;K[e+q>>2]=(+J[e+p>>2]-t)/o;k=k+2|0;f=f+2|0;if((n|0)!=(f|0)){continue}break}}if(!(m&1)){break u}e=k<<2;K[e+(l+32|0)>>2]=(+J[e+p>>2]-t)/o;break u}if((m|0)<=0){break u}f=0;k=0;if(m-1>>>0>=3){r=m&-4;e=0;while(1){n=k<<2;q=l+32|0;K[n+q>>2]=J[p+n>>2];s=n|4;K[s+q>>2]=J[p+s>>2];s=n|8;K[s+q>>2]=J[p+s>>2];n=n|12;K[n+q>>2]=J[p+n>>2];k=k+4|0;e=e+4|0;if((r|0)!=(e|0)){continue}break}}e=m&3;if(!e){break u}while(1){n=k<<2;K[n+(l+32|0)>>2]=J[p+n>>2];k=k+1|0;f=f+1|0;if((e|0)!=(f|0)){continue}break}}$c(a,m,G[l+29084>>2],l+32|0,j);break d}p=(c<<2)+i|0;t=L[l+29032>>3];u=L[l+29024>>3];v:{if(!(t==1&u==0)){k=0;if((m|0)<=0){break v}while(1){f=(l+32|0)+(k<<1)|0;o=(+J[p+(k<<2)>>2]-u)/t;w:{if(o<-32768.49){G[j>>2]=-11;e=32768;break w}if(o>32767.49){G[j>>2]=-11;e=32767;break w}x:{if(o>=0){o=o+.5;if(!(O(o)<2147483648)){break x}e=~~o;break w}o=o+-.5;if(!(O(o)<2147483648)){break x}e=~~o;break w}e=-2147483648}F[f>>1]=e;k=k+1|0;if((m|0)!=(k|0)){continue}break}break v}if((m|0)<=0){break v}k=0;if((m|0)!=1){n=m&-2;f=0;while(1){q=(l+32|0)+(k<<1)|0;e=G[p+(k<<2)>>2];if(e>>>0>=32768){G[j>>2]=-11;e=32767}F[q>>1]=e;q=k|1;e=G[p+(q<<2)>>2];if(e>>>0>32767){G[j>>2]=-11;e=32767}F[(l+32|0)+(q<<1)>>1]=e;k=k+2|0;f=f+2|0;if((n|0)!=(f|0)){continue}break}}if(!(m&1)){break v}f=(l+32|0)+(k<<1)|0;e=G[p+(k<<2)>>2];if(e>>>0>32767){G[j>>2]=-11;e=32767}F[f>>1]=e}Oe(a,m,G[l+29084>>2],l+32|0,j);break d}p=(c<<2)+i|0;t=L[l+29032>>3];u=L[l+29024>>3];y:{if(!(t==1&u==0)){k=0;if((m|0)<=0){break y}while(1){f=(l+32|0)+k|0;z:{A:{o=(+J[p+(k<<2)>>2]-u)/t;if(o<-.49){G[j>>2]=-11;break A}if(o>255.49){G[j>>2]=-11;e=255;break z}o=o+.5;if(!(o<4294967296&o>=0)){break A}e=~~o>>>0;break z}e=0}E[f|0]=e;k=k+1|0;if((m|0)!=(k|0)){continue}break}break y}if((m|0)<=0){break y}k=0;if((m|0)!=1){n=m&-2;f=0;while(1){q=(l+32|0)+k|0;e=G[p+(k<<2)>>2];if(e>>>0>=256){G[j>>2]=-11;e=255}E[q|0]=e;q=k|1;e=G[p+(q<<2)>>2];if(e>>>0>255){G[j>>2]=-11;e=255}E[q+(l+32|0)|0]=e;k=k+2|0;f=f+2|0;if((n|0)!=(f|0)){continue}break}}if(!(m&1)){break y}f=(l+32|0)+k|0;e=G[p+(k<<2)>>2];if(e>>>0>255){G[j>>2]=-11;e=255}E[f|0]=e}we(a,m,G[l+29084>>2],l+32|0,j);break d}p=(c<<2)+i|0;u=L[l+29032>>3];e=u!=1;t=L[l+29024>>3];B:{if(!(e|t!=0x8000000000000000)){if((m|0)<=0){break B}e=0;k=0;if(m-1>>>0>=3){q=m&-4;f=0;while(1){n=l+32|0;r=n+(k<<3)|0;G[r>>2]=G[p+(k<<2)>>2];G[r+4>>2]=-2147483648;r=k|1;s=n+(r<<3)|0;G[s>>2]=G[p+(r<<2)>>2];G[s+4>>2]=-2147483648;r=k|2;s=n+(r<<3)|0;G[s>>2]=G[p+(r<<2)>>2];G[s+4>>2]=-2147483648;r=k|3;n=n+(r<<3)|0;G[n>>2]=G[p+(r<<2)>>2];G[n+4>>2]=-2147483648;k=k+4|0;f=f+4|0;if((q|0)!=(f|0)){continue}break}}f=m&3;if(!f){break B}while(1){n=(l+32|0)+(k<<3)|0;G[n>>2]=G[p+(k<<2)>>2];G[n+4>>2]=-2147483648;k=k+1|0;e=e+1|0;if((f|0)!=(e|0)){continue}break}break B}if(!(!e&t==0)){k=0;if((m|0)<=0){break B}while(1){n=(l+32|0)+(k<<3)|0;C:{D:{o=(+J[p+(k<<2)>>2]-t)/u;if(o<-0x8000000000000000){G[j>>2]=-11;break D}if(o>0x8000000000000000){G[j>>2]=-11;f=2147483647;e=-1;break C}if(o>=0){o=o+.5;if(!(O(o)<0x8000000000000000)){break D}f=O(o)>=1?~~(o>0?Q(S(o*2.3283064365386963e-10),4294967295):T((o-+(~~o>>>0>>>0))*2.3283064365386963e-10))>>>0:0;e=~~o>>>0;break C}o=o+-.5;if(!(O(o)<0x8000000000000000)){break D}f=O(o)>=1?~~(o>0?Q(S(o*2.3283064365386963e-10),4294967295):T((o-+(~~o>>>0>>>0))*2.3283064365386963e-10))>>>0:0;e=~~o>>>0;break C}f=-2147483648;e=0}G[n>>2]=e;G[n+4>>2]=f;k=k+1|0;if((m|0)!=(k|0)){continue}break}break B}if((m|0)<=0){break B}e=0;k=0;if(m-1>>>0>=3){q=m&-4;f=0;while(1){n=l+32|0;r=n+(k<<3)|0;G[r>>2]=G[p+(k<<2)>>2];G[r+4>>2]=0;r=k|1;s=n+(r<<3)|0;G[s>>2]=G[p+(r<<2)>>2];G[s+4>>2]=0;r=k|2;s=n+(r<<3)|0;G[s>>2]=G[p+(r<<2)>>2];G[s+4>>2]=0;r=k|3;n=n+(r<<3)|0;G[n>>2]=G[p+(r<<2)>>2];G[n+4>>2]=0;k=k+4|0;f=f+4|0;if((q|0)!=(f|0)){continue}break}}f=m&3;if(!f){break B}while(1){n=(l+32|0)+(k<<3)|0;G[n>>2]=G[p+(k<<2)>>2];G[n+4>>2]=0;k=k+1|0;e=e+1|0;if((f|0)!=(e|0)){continue}break}}_c(a,m,G[l+29084>>2],l+32|0,j);break d}if((m|0)<=0){break e}k=0;if((m|0)!=1){n=m&-2;f=0;while(1){q=k<<2;e=G[q+p>>2];if((e|0)<0){G[j>>2]=-11;e=2147483647}G[q+(l+32|0)>>2]=e;q=(k|1)<<2;e=G[q+p>>2];if((e|0)<0){G[j>>2]=-11;e=2147483647}G[q+(l+32|0)>>2]=e;k=k+2|0;f=f+2|0;if((n|0)!=(f|0)){continue}break}}if(!(m&1)){break e}e=k<<2;k=G[e+p>>2];if((k|0)<0){G[j>>2]=-11;k=2147483647}G[e+(l+32|0)>>2]=k}$c(a,m,G[l+29084>>2],l+32|0,j)}k=G[j>>2];if((k|0)>0){f=d;a=c+1|0;f=a?f:f+1|0;L[l+16>>3]=+(a>>>0)+ +(f|0)*4294967296;e=m;f=e>>31;a=c+e|0;f=d+f|0;L[l+24>>3]=+(a>>>0)+ +((a>>>0>>0?f+1|0:f)|0)*4294967296;a=l+28864|0;Ya(a,81,46437,l+16|0);Ua(a);break c}e=m;f=e>>31;s=f;h=h-(f+(e>>>0>g>>>0)|0)|0;g=g-e|0;if(!(h|g)){break b}f=d+s|0;c=c+e|0;f=c>>>0>>0?f+1|0:f;d=f;f=s+G[l+29060>>2]|0;m=e+G[l+29056>>2]|0;f=m>>>0>>0?f+1|0:f;e=m;G[l+29056>>2]=e;G[l+29060>>2]=f;if(G[l+29072>>2]!=(e|0)|G[l+29076>>2]!=(f|0)){continue}G[l+29056>>2]=0;G[l+29060>>2]=0;e=w;f=v+1|0;e=f?e:e+1|0;v=f;w=e;continue}}k=G[j>>2];break a}if((k|0)!=-11){break a}Ua(44927);k=412;G[j>>2]=412}Fa=l+29104|0;return k}function jf(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,I=0,K=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0;q=Fa-29104|0;Fa=q;p=G[o>>2];a:{if(!(g|h)|(p|0)>0){break a}if(n){G[n>>2]=0}if((j|0)==2){cb(m,0,g)}if((yc(a,b,c,d,e,f,g,h,i>>31,q+29096|0,q+29088|0,q+28992|0,q+29064|0,q+29084|0,q+29080|0,q+29040|0,q+29032|0,q+29060|0,q+29048|0,q+29016|0,q+29076|0,q+29024|0,q+28864|0,o)|0)>0){p=G[o>>2];break a}G[q+29060>>2]=M(G[q+29060>>2],i);A=1;c=G[q+29080>>2];R=c;S=c>>31;b:{if(G[q+29084>>2]!=16){break b}Gd(q+28992|0,q+29072|0,q+29056|0,q+29068|0,o);d=G[q+29068>>2];if((d|0)<=0){break b}if(d-1>>>0>=7){c=d&-8;while(1){A=A*10*10*10*10*10*10*10*10;w=w+8|0;if((c|0)!=(w|0)){continue}break}}c=d&7;if(!c){break b}w=0;while(1){A=A*10;w=w+1|0;if((c|0)!=(w|0)){continue}break}}w=0;p=G[q+29084>>2];c:{d:{e:{if(k?0:(j|0)==1){break e}f=G[q+29028>>2];c=G[q+29024>>2];if(!f&(c|0)==1234554321&((p|0)%10|0)==1){break e}e=f-(c>>>0<32768)|0;if(((e|0)==-1&c-32768>>>0<4294901760|(e|0)!=-1)&(p|0)==21){break d}N=0;if(!(!f&c>>>0<=255|(p|0)!=11)){break c}w=(p|0)==16?H[q+28864|0]==1?0:j:j}N=0;if((p|0)!=21){break c}}c=g>>>0<1073741823&(h|0)<=0|(h|0)<0;R=c?g:1073741823;S=c?h:0;N=!w&L[q+29096>>3]==1&L[q+29088>>3]==0}X=0-i|0;e=0;f=0;f:{while(1){c=g>>>0>>0&(h|0)<=(S|0)|(h|0)<(S|0)?g:R;d=c>>31;y=c;x=d;g:{if((i|0)>=0){d=G[q+29036>>2];p=G[q+29052>>2]+(d^-1)|0;c=G[q+29032>>2];j=c^-1;t=j+G[q+29048>>2]|0;t=Bu(t,j>>>0>t>>>0?p+1|0:p,i,0);j=Ia;break g}c=G[q+29032>>2];d=G[q+29036>>2];t=Bu(c,d,X,0);j=Ia}r=G[q+29044>>2];z=G[q+29040>>2];p=Au(G[q+29016>>2],G[q+29020>>2],B,D);s=z+p|0;r=Ia+r|0;r=p>>>0>s>>>0?r+1|0:r;p=c;v=G[q+29060>>2];c=(v|0)/(i|0)|0;d=Au(p,d,c,c>>31);p=d+s|0;c=Ia+r|0;c=d>>>0>p>>>0?c+1|0:c;z=p;p=j;d=t+1|0;p=d;d=t>>>0>>0&(j|0)<=(x|0)|(j|0)<(x|0);s=d?p:y;h:{i:{j:{k:{l:{m:{n:{o:{p:{q:{d=G[q+29084>>2];switch(d-11|0){case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break j;case 5:break k;case 31:break m;case 30:break n;case 0:break o;case 10:break p;default:break q}}switch(d-81|0){case 0:break i;case 1:break l;default:break j}}d=c;c=(e<<1)+l|0;Pe(a,z,d,s,v,c,o);if(N){break h}Op(c,s,L[q+29096>>3],L[q+29088>>3],w,F[q+29024>>1],k,e+m|0,n,c,o);break h}d=c;c=q- -64|0;$d(a,z,d,s,v,c,o);Np(c,s,L[q+29096>>3],L[q+29088>>3],w,H[q+29024|0],k,e+m|0,n,(e<<1)+l|0,o);break h}d=c;c=q- -64|0;Uc(a,z,d,s,v,c,o);Yk(c,s,L[q+29096>>3],L[q+29088>>3],w,G[q+29024>>2],k,e+m|0,n,(e<<1)+l|0,o);break h}d=c;c=q- -64|0;Uc(a,z,d,s,v,c,o);Xk(c,s,L[q+29096>>3],L[q+29088>>3],w,k,e+m|0,n,(e<<1)+l|0,o);break h}d=c;c=q- -64|0;Tc(a,z,d,s,v,c,o);Wk(c,s,L[q+29096>>3],L[q+29088>>3],w,k,e+m|0,n,(e<<1)+l|0,o);break h}Jb(a,z,c,0,o);d=G[q+29060>>2];c=G[q+29064>>2];r:{if((d|0)==(c|0)){c=M(d,s);ic(a,c,c>>31,q- -64|0,o);break r}Rd(a,c,s,d-c|0,q- -64|0,o)}t=q- -64|0;I=L[q+29096>>3];K=L[q+29088>>3];Y=G[q+29064>>2];z=e+m|0;Q=(e<<1)+l|0;C=0;r=Fa-112|0;Fa=r;T=q+28864|0;v=Va(T);if((s|0)>0){while(1){s:{c=t+Y|0;V=H[c|0];E[c|0]=0;j=t;t:{u:{if(H[T|0]==1){break u}if(fb(T,t,v)){break u}j=c;if(!w){break t}G[n>>2]=1;if((w|0)==1){F[(C<<1)+Q>>1]=k;break t}E[z+C|0]=1;break t}while(1){d=H[j|0];if((d|0)==32){j=j+1|0;continue}break}W=1;v:{switch(d-43|0){case 0:case 2:while(1){p=H[j+1|0];j=j+1|0;if((p|0)==32){continue}break};W=(d|0)==45?-1:1;d=p;break;default:break v}}P=0;if((d-48&255)>>>0<10){while(1){u=P*10+ +(d<<24>>24);p=j;while(1){d=H[p+1|0];j=p+1|0;p=j;if((d|0)==32){continue}break}P=u+-48;if((d-48&255)>>>0<=9){continue}break}}u=A;w:{x:{switch(d-44|0){case 0:case 2:break x;default:break w}}p=j;while(1){d=H[p+1|0];j=p+1|0;p=j;if((d|0)==32){continue}break}u=1;if((d-48&255)>>>0>=10){break w}while(1){P=P*10+ +(d<<24>>24)+-48;p=j;while(1){d=H[p+1|0];j=p+1|0;p=j;if((d|0)==32){continue}break}u=u*10;if((d-48&255)>>>0<=9){continue}break}}y:{if((d&254)!=68){U=1;p=0;break y}while(1){U=1;p=j;j=p+1|0;d=H[p+1|0];if((d|0)==32){continue}break}z:{switch(d-43|0){case 0:case 2:p=p+2|0;while(1){j=p;p=p+1|0;x=H[j|0];if((x|0)==32){continue}break};U=(d|0)==45?-1:1;d=x;break;default:break z}}p=0;if((d-48&255)>>>0>=10){break y}while(1){x=d;y=M(p,10)-48|0;p=j;while(1){d=H[p+1|0];j=p+1|0;p=j;if((d|0)==32){continue}break}p=(x<<24>>24)+y|0;if((d-48&255)>>>0<=9){continue}break}}if(d){G[r+48>>2]=H[23477]|H[23478]<<8|(H[23479]<<16|H[23480]<<24);d=H[23473]|H[23474]<<8|(H[23475]<<16|H[23476]<<24);G[r+40>>2]=H[23469]|H[23470]<<8|(H[23471]<<16|H[23472]<<24);G[r+44>>2]=d;d=H[23465]|H[23466]<<8|(H[23467]<<16|H[23468]<<24);G[r+32>>2]=H[23461]|H[23462]<<8|(H[23463]<<16|H[23464]<<24);G[r+36>>2]=d;d=H[23457]|H[23458]<<8|(H[23459]<<16|H[23460]<<24);G[r+24>>2]=H[23453]|H[23454]<<8|(H[23455]<<16|H[23456]<<24);G[r+28>>2]=d;d=H[23449]|H[23450]<<8|(H[23451]<<16|H[23452]<<24);G[r+16>>2]=H[23445]|H[23446]<<8|(H[23447]<<16|H[23448]<<24);G[r+20>>2]=d;d=r+16|0;Ua(d);G[r>>2]=t;Ya(d,81,43022,r);Ua(d);E[c|0]=V;G[o>>2]=409;break s}u=P*+(W|0)/u*$b(10,+(M(p,U)|0))*I+K;A:{if(u<-32768.49){G[o>>2]=-11;F[(C<<1)+Q>>1]=32768;break A}if(u>32767.49){G[o>>2]=-11;F[(C<<1)+Q>>1]=32767;break A}d=(C<<1)+Q|0;if(O(u)<2147483648){p=~~u}else{p=-2147483648}F[d>>1]=p}}t=j;E[c|0]=V;C=C+1|0;if((C|0)!=(s|0)){continue}}break}}Fa=r+112|0;break h}G[q>>2]=b;G[q+4>>2]=q+28992;a=q+28896|0;Ya(a,81,8924,q);Ua(a);p=311;if(G[q+29076>>2]==1){break f}p=312;break f}y=q- -64|0;Tc(a,z,c,s,v,y,o);x=G[q+29024>>2];t=G[q+29028>>2];j=e+m|0;v=(e<<1)+l|0;I=L[q+29096>>3];K=L[q+29088>>3];c=I==1&K==0x8000000000000000;B:{C:{D:{E:{F:{if(!w){if(c){if((s|0)<=0){break B}p=0;if((s|0)!=1){x=s&-2;t=0;while(1){j=v+(p<<1)|0;c=y+(p<<3)|0;d=G[c+4>>2];c=G[c>>2];if((d|0)!=-2147483648|c>>>0>=32768){G[o>>2]=-11;c=32767}F[j>>1]=c;j=p|1;c=y+(j<<3)|0;d=G[c+4>>2];c=G[c>>2];if(!((d|0)==-2147483648&c>>>0<=32767)){G[o>>2]=-11;c=32767}F[v+(j<<1)>>1]=c;p=p+2|0;t=t+2|0;if((x|0)!=(t|0)){continue}break}}if(!(s&1)){break B}c=y+(p<<3)|0;d=G[c+4>>2];c=G[c>>2];if((d|0)!=-2147483648|c>>>0>32767){break F}break E}if(I==1&K==0){break C}p=0;if((s|0)<=0){break B}while(1){d=v+(p<<1)|0;c=y+(p<<3)|0;u=(+J[c>>2]+ +G[c+4>>2]*4294967296)*I+K;G:{if(u<-32768.49){G[o>>2]=-11;c=32768;break G}if(u>32767.49){G[o>>2]=-11;c=32767;break G}c=~~u;if(O(u)<2147483648){break G}c=-2147483648}F[d>>1]=c;p=p+1|0;if((s|0)!=(p|0)){continue}break}break B}if(c){if((s|0)<=0){break B}p=0;while(1){c=y+(p<<3)|0;d=G[c>>2];c=G[c+4>>2];H:{if((d|0)==(x|0)&(c|0)==(t|0)){G[n>>2]=1;if((w|0)==1){F[v+(p<<1)>>1]=k;break H}E[j+p|0]=1;break H}if((c|0)!=-2147483648|d>>>0>=32768){G[o>>2]=-11;F[v+(p<<1)>>1]=32767;break H}F[v+(p<<1)>>1]=d}p=p+1|0;if((s|0)!=(p|0)){continue}break}break B}if(I==1&K==0){break D}if((s|0)<=0){break B}p=0;while(1){c=y+(p<<3)|0;d=G[c>>2];c=G[c+4>>2];I:{if((d|0)==(x|0)&(c|0)==(t|0)){G[n>>2]=1;if((w|0)==1){F[v+(p<<1)>>1]=k;break I}E[j+p|0]=1;break I}u=(+(d>>>0)+ +(c|0)*4294967296)*I+K;if(u<-32768.49){G[o>>2]=-11;F[v+(p<<1)>>1]=32768;break I}if(u>32767.49){G[o>>2]=-11;F[v+(p<<1)>>1]=32767;break I}c=v+(p<<1)|0;if(O(u)<2147483648){d=~~u}else{d=-2147483648}F[c>>1]=d}p=p+1|0;if((s|0)!=(p|0)){continue}break}break B}G[o>>2]=-11;c=32767}F[v+(p<<1)>>1]=c;break B}if((s|0)<=0){break B}p=0;while(1){c=y+(p<<3)|0;d=G[c>>2];c=G[c+4>>2];J:{if((d|0)==(x|0)&(c|0)==(t|0)){G[n>>2]=1;if((w|0)==1){F[v+(p<<1)>>1]=k;break J}E[j+p|0]=1;break J}if((c|0)<0&d>>>0<=4294934527|(c|0)<-1){G[o>>2]=-11;F[v+(p<<1)>>1]=32768;break J}if((c|0)>=0&d>>>0>=32768|(c|0)>0){G[o>>2]=-11;F[v+(p<<1)>>1]=32767;break J}F[v+(p<<1)>>1]=d}p=p+1|0;if((s|0)!=(p|0)){continue}break}break B}if((s|0)<=0){break B}p=0;while(1){j=v+(p<<1)|0;d=y+(p<<3)|0;c=G[d+4>>2];d=G[d>>2];K:{if((c|0)<0&d>>>0<=4294934527|(c|0)<-1){G[o>>2]=-11;d=32768;break K}if((c|0)>=0&d>>>0>=32768|(c|0)>0){G[o>>2]=-11;d=32767;break K}}F[j>>1]=d;p=p+1|0;if((s|0)!=(p|0)){continue}break}}}p=G[o>>2];if((p|0)>0){u=+(e>>>0)+ +(f|0)*4294967296;A=u+1;u=u+ +(s|0);L:{if(G[q+29076>>2]>0){G[q+32>>2]=b;L[q+24>>3]=u;L[q+16>>3]=A;Ya(q+28896|0,81,47140,q+16|0);break L}L[q+56>>3]=u;L[q+48>>3]=A;Ya(q+28896|0,81,47081,q+48|0)}Ua(q+28896|0);p=G[o>>2];break a}d=s;j=d>>31;h=h-((d>>>0>g>>>0)+j|0)|0;g=g-d|0;if(h|g){c=M(i,s);t=c+G[q+29032>>2]|0;p=G[q+29036>>2]+(c>>31)|0;p=c>>>0>t>>>0?p+1|0:p;c=t;G[q+29032>>2]=c;G[q+29036>>2]=p;r=f+j|0;e=d+e|0;r=e>>>0>>0?r+1|0:r;f=r;r=G[q+29052>>2];d=r;x=G[q+29048>>2];if((p|0)>=(d|0)&c>>>0>=x>>>0|(d|0)<(p|0)){j=Bu(c,p,x,r);t=B+j|0;d=Ia;D=D+d|0;D=t>>>0>>0?D+1|0:D;B=t;d=Au(x,r,j,d);G[q+29032>>2]=c-d;G[q+29036>>2]=p-(Ia+(c>>>0>>0)|0);continue}if((p|0)>0|(p|0)>=0){continue}j=B;B=Bu(c^-1,p^-1,x,r)+1|0;d=Ia;d=B?d:d+1|0;t=B;B=j-t|0;D=D-((j>>>0>>0)+d|0)|0;d=Au(x,r,t,d)+c|0;r=p+Ia|0;G[q+29032>>2]=d;G[q+29036>>2]=c>>>0>d>>>0?r+1|0:r;continue}break}if((p|0)!=-11){break a}Ua(44994);p=412}G[o>>2]=p}Fa=q+29104|0;return p}function Ah(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;l=Fa-29104|0;Fa=l;k=G[j>>2];a:{if((k|0)>0){break a}b:{c:{if((yc(a,b,c,d,e,f,g,h,1,l+29032|0,l+29024|0,l+28992|0,l+29088|0,l+29100|0,l+29096|0,l+29064|0,l+29056|0,l+29084|0,l+29072|0,l+29048|0,l+29092|0,l+29040|0,l+28832|0,j)|0)>0){break c}if(G[l+29100>>2]==16){Ne(l+28992|0,l+28960|0)}if(!(g|h)){k=G[j>>2];break b}c=0;d=0;while(1){e=G[l+29096>>2];v=e;e=e>>31;o=G[l+29072>>2];p=G[l+29076>>2];f=G[l+29068>>2];m=G[l+29064>>2];n=Au(G[l+29048>>2],G[l+29052>>2],w,x);k=m+n|0;f=Ia+f|0;f=k>>>0>>0?f+1|0:f;t=k;k=G[l+29056>>2];m=G[l+29060>>2];n=G[l+29084>>2];r=Au(k,m,n,n>>31);n=t+r|0;f=Ia+f|0;Jb(a,n,n>>>0>>0?f+1|0:f,1,j);v=g>>>0>>0&(e|0)>=(h|0)|(e|0)>(h|0)?g:v;e=v;f=e>>31;e=p-((k>>>0>o>>>0)+m|0)|0;o=o-k|0;m=o;o=o>>>0>v>>>0&(e|0)>=(f|0)|(e|0)>(f|0);v=o?v:m;e=v;d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{f=G[l+29100>>2];switch(f-11|0){case 0:break g;case 30:break h;case 31:break i;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break k;case 5:break l;case 10:break m;default:break n}}o:{switch(f-81|0){case 1:break j;case 0:break o;default:break k}}p=(c<<1)+i|0;u=L[l+29032>>3];f=u!=1;s=L[l+29024>>3];if(!(f|s!=0x8000000000000000)){if((e|0)<=0){break e}f=0;k=0;if(e-1>>>0>=3){r=e&-4;n=0;while(1){m=l+32|0;o=m+(k<<3)|0;G[o>>2]=I[p+(k<<1)>>1];G[o+4>>2]=-2147483648;o=k|1;t=m+(o<<3)|0;G[t>>2]=I[p+(o<<1)>>1];G[t+4>>2]=-2147483648;o=k|2;t=m+(o<<3)|0;G[t>>2]=I[p+(o<<1)>>1];G[t+4>>2]=-2147483648;o=m;m=k|3;o=o+(m<<3)|0;G[o>>2]=I[p+(m<<1)>>1];G[o+4>>2]=-2147483648;k=k+4|0;n=n+4|0;if((r|0)!=(n|0)){continue}break}}n=e&3;if(!n){break e}while(1){m=(l+32|0)+(k<<3)|0;G[m>>2]=I[p+(k<<1)>>1];G[m+4>>2]=-2147483648;k=k+1|0;f=f+1|0;if((n|0)!=(f|0)){continue}break}break e}if(!f&s==0){break f}k=0;if((e|0)<=0){break e}while(1){m=(l+32|0)+(k<<3)|0;p:{q:{q=(+I[p+(k<<1)>>1]-s)/u;if(q<-0x8000000000000000){G[j>>2]=-11;break q}if(q>0x8000000000000000){G[j>>2]=-11;n=2147483647;f=-1;break p}if(q>=0){q=q+.5;if(!(O(q)<0x8000000000000000)){break q}n=O(q)>=1?~~(q>0?Q(S(q*2.3283064365386963e-10),4294967295):T((q-+(~~q>>>0>>>0))*2.3283064365386963e-10))>>>0:0;f=~~q>>>0;break p}q=q+-.5;if(!(O(q)<0x8000000000000000)){break q}n=O(q)>=1?~~(q>0?Q(S(q*2.3283064365386963e-10),4294967295):T((q-+(~~q>>>0>>>0))*2.3283064365386963e-10))>>>0:0;f=~~q>>>0;break p}n=-2147483648;f=0}G[m>>2]=f;G[m+4>>2]=n;k=k+1|0;if((e|0)!=(k|0)){continue}break}break e}n=(c<<1)+i|0;f=l+32|0;m=0;u=L[l+29032>>3];k=u!=1;s=L[l+29024>>3];r:{if(!(k|s!=32768)){if((e|0)<=0){break r}k=0;if(e-1>>>0>=3){o=e&-4;r=0;while(1){p=k<<1;F[p+f>>1]=I[p+n>>1]^32768;t=p|2;F[t+f>>1]=I[n+t>>1]^32768;t=p|4;F[t+f>>1]=I[n+t>>1]^32768;p=p|6;F[p+f>>1]=I[p+n>>1]^32768;k=k+4|0;r=r+4|0;if((o|0)!=(r|0)){continue}break}}p=e&3;if(!p){break r}while(1){r=k<<1;F[r+f>>1]=I[n+r>>1]^32768;k=k+1|0;m=m+1|0;if((p|0)!=(m|0)){continue}break}break r}if(!(!k&s==0)){k=0;if((e|0)<=0){break r}while(1){m=k<<1;q=(+I[m+n>>1]-s)/u;s:{if(q<-32768.49){G[j>>2]=-11;p=32768;break s}if(q>32767.49){G[j>>2]=-11;p=32767;break s}t:{if(q>=0){q=q+.5;if(!(O(q)<2147483648)){break t}p=~~q;break s}q=q+-.5;if(!(O(q)<2147483648)){break t}p=~~q;break s}p=-2147483648}F[f+m>>1]=p;k=k+1|0;if((e|0)!=(k|0)){continue}break}break r}if((e|0)<=0){break r}k=0;if((e|0)!=1){r=e&-2;while(1){o=k<<1;p=F[o+n>>1];if((p|0)<0){G[j>>2]=-11;p=32767}F[f+o>>1]=p;o=(k|1)<<1;p=F[o+n>>1];if((p|0)<0){G[j>>2]=-11;p=32767}F[f+o>>1]=p;k=k+2|0;m=m+2|0;if((r|0)!=(m|0)){continue}break}}if(!(e&1)){break r}m=n;n=k<<1;k=F[m+n>>1];if((k|0)<0){G[j>>2]=-11;k=32767}F[f+n>>1]=k}Oe(a,e,G[l+29084>>2],f,j);break d}if(H[l+28961|0]==115){break k}m=(c<<1)+i|0;k=e;r=l+28960|0;o=G[l+29088>>2];f=l+32|0;n=0;p=Fa-32|0;Fa=p;q=L[l+29032>>3];s=L[l+29024>>3];u:{if(!(q==1&s==0)){if((k|0)<=0){break u}e=f;while(1){L[p+16>>3]=(+I[m+(n<<1)>>1]-s)/q;Eb(e,r,p+16|0);e=e+o|0;if(H[e|0]){G[j>>2]=-11}n=n+1|0;if((k|0)!=(n|0)){continue}break}break u}if((k|0)<=0){break u}e=f;while(1){L[p>>3]=I[m+(n<<1)>>1];Eb(e,r,p);e=e+o|0;if(H[e|0]){G[j>>2]=-11}n=n+1|0;if((k|0)!=(n|0)){continue}break}}n=jb(f,44);if(n){while(1){E[n|0]=46;n=jb(n,44);if(n){continue}break}}Fa=p+32|0;e=G[l+29084>>2];f=G[l+29088>>2];if((e|0)==(f|0)){e=M(e,k);Wb(a,e,e>>31,l+32|0,j);break d}wd(a,f,k,e-f|0,l+32|0,j);break d}G[l>>2]=b;G[l+4>>2]=l+28992;a=l+28864|0;Ya(a,81,8813,l);Ua(a);if(G[l+29092>>2]==1){k=311;G[j>>2]=311;break a}k=312;G[j>>2]=312;break a}p=(c<<1)+i|0;q=L[l+29032>>3];s=L[l+29024>>3];v:{if(!(q==1&s==0)){if((e|0)<=0){break v}k=0;if((e|0)!=1){n=e&-2;f=0;while(1){m=l+32|0;L[m+(k<<3)>>3]=(+I[p+(k<<1)>>1]-s)/q;o=m;m=k|1;L[o+(m<<3)>>3]=(+I[p+(m<<1)>>1]-s)/q;k=k+2|0;f=f+2|0;if((n|0)!=(f|0)){continue}break}}if(!(e&1)){break v}L[(l+32|0)+(k<<3)>>3]=(+I[p+(k<<1)>>1]-s)/q;break v}if((e|0)<=0){break v}f=0;k=0;if(e-1>>>0>=3){r=e&-4;n=0;while(1){m=l+32|0;L[m+(k<<3)>>3]=I[p+(k<<1)>>1];o=k|1;L[m+(o<<3)>>3]=I[p+(o<<1)>>1];o=k|2;L[m+(o<<3)>>3]=I[p+(o<<1)>>1];o=m;m=k|3;L[o+(m<<3)>>3]=I[p+(m<<1)>>1];k=k+4|0;n=n+4|0;if((r|0)!=(n|0)){continue}break}}n=e&3;if(!n){break v}while(1){L[(l+32|0)+(k<<3)>>3]=I[p+(k<<1)>>1];k=k+1|0;f=f+1|0;if((n|0)!=(f|0)){continue}break}}_c(a,e,G[l+29084>>2],l+32|0,j);break d}p=(c<<1)+i|0;q=L[l+29032>>3];s=L[l+29024>>3];w:{if(!(q==1&s==0)){if((e|0)<=0){break w}k=0;if((e|0)!=1){n=e&-2;f=0;while(1){m=l+32|0;K[m+(k<<2)>>2]=(+I[p+(k<<1)>>1]-s)/q;o=m;m=k|1;K[o+(m<<2)>>2]=(+I[p+(m<<1)>>1]-s)/q;k=k+2|0;f=f+2|0;if((n|0)!=(f|0)){continue}break}}if(!(e&1)){break w}K[(l+32|0)+(k<<2)>>2]=(+I[p+(k<<1)>>1]-s)/q;break w}if((e|0)<=0){break w}f=0;k=0;if(e-1>>>0>=3){r=e&-4;n=0;while(1){m=l+32|0;K[m+(k<<2)>>2]=I[p+(k<<1)>>1];o=k|1;K[m+(o<<2)>>2]=I[p+(o<<1)>>1];o=k|2;K[m+(o<<2)>>2]=I[p+(o<<1)>>1];o=m;m=k|3;K[o+(m<<2)>>2]=I[p+(m<<1)>>1];k=k+4|0;n=n+4|0;if((r|0)!=(n|0)){continue}break}}n=e&3;if(!n){break w}while(1){K[(l+32|0)+(k<<2)>>2]=I[p+(k<<1)>>1];k=k+1|0;f=f+1|0;if((n|0)!=(f|0)){continue}break}}$c(a,e,G[l+29084>>2],l+32|0,j);break d}p=(c<<1)+i|0;s=L[l+29032>>3];u=L[l+29024>>3];x:{if(!(s==1&u==0)){k=0;if((e|0)<=0){break x}while(1){m=(l+32|0)+(k<<2)|0;y:{z:{q=(+I[p+(k<<1)>>1]-u)/s;if(q<-2147483648.49){G[j>>2]=-11;break z}if(q>2147483647.49){G[j>>2]=-11;f=2147483647;break y}if(q>=0){q=q+.5;if(!(O(q)<2147483648)){break z}f=~~q;break y}q=q+-.5;if(!(O(q)<2147483648)){break z}f=~~q;break y}f=-2147483648}G[m>>2]=f;k=k+1|0;if((e|0)!=(k|0)){continue}break}break x}if((e|0)<=0){break x}f=0;k=0;if(e-1>>>0>=3){r=e&-4;n=0;while(1){m=l+32|0;G[m+(k<<2)>>2]=I[p+(k<<1)>>1];o=k|1;G[m+(o<<2)>>2]=I[p+(o<<1)>>1];o=k|2;G[m+(o<<2)>>2]=I[p+(o<<1)>>1];o=m;m=k|3;G[o+(m<<2)>>2]=I[p+(m<<1)>>1];k=k+4|0;n=n+4|0;if((r|0)!=(n|0)){continue}break}}n=e&3;if(!n){break x}while(1){G[(l+32|0)+(k<<2)>>2]=I[p+(k<<1)>>1];k=k+1|0;f=f+1|0;if((n|0)!=(f|0)){continue}break}}$c(a,e,G[l+29084>>2],l+32|0,j);break d}p=(c<<1)+i|0;s=L[l+29032>>3];u=L[l+29024>>3];A:{if(!(s==1&u==0)){k=0;if((e|0)<=0){break A}while(1){m=(l+32|0)+k|0;B:{C:{q=(+I[p+(k<<1)>>1]-u)/s;if(q<-.49){G[j>>2]=-11;break C}if(q>255.49){G[j>>2]=-11;f=255;break B}q=q+.5;if(!(q<4294967296&q>=0)){break C}f=~~q>>>0;break B}f=0}E[m|0]=f;k=k+1|0;if((e|0)!=(k|0)){continue}break}break A}if((e|0)<=0){break A}k=0;if((e|0)!=1){m=e&-2;n=0;while(1){r=(l+32|0)+k|0;f=I[p+(k<<1)>>1];if(f>>>0>=256){G[j>>2]=-11;f=255}E[r|0]=f;r=k|1;f=I[p+(r<<1)>>1];if(f>>>0>255){G[j>>2]=-11;f=255}E[r+(l+32|0)|0]=f;k=k+2|0;n=n+2|0;if((m|0)!=(n|0)){continue}break}}if(!(e&1)){break A}n=(l+32|0)+k|0;f=I[p+(k<<1)>>1];if(f>>>0>255){G[j>>2]=-11;f=255}E[n|0]=f}we(a,e,G[l+29084>>2],l+32|0,j);break d}if((e|0)<=0){break e}f=0;k=0;if(e-1>>>0>=3){r=e&-4;n=0;while(1){m=l+32|0;o=m+(k<<3)|0;G[o>>2]=I[p+(k<<1)>>1];G[o+4>>2]=0;o=k|1;t=m+(o<<3)|0;G[t>>2]=I[p+(o<<1)>>1];G[t+4>>2]=0;o=k|2;t=m+(o<<3)|0;G[t>>2]=I[p+(o<<1)>>1];G[t+4>>2]=0;o=m;m=k|3;o=o+(m<<3)|0;G[o>>2]=I[p+(m<<1)>>1];G[o+4>>2]=0;k=k+4|0;n=n+4|0;if((r|0)!=(n|0)){continue}break}}n=e&3;if(!n){break e}while(1){m=(l+32|0)+(k<<3)|0;G[m>>2]=I[p+(k<<1)>>1];G[m+4>>2]=0;k=k+1|0;f=f+1|0;if((n|0)!=(f|0)){continue}break}}_c(a,e,G[l+29084>>2],l+32|0,j)}k=G[j>>2];if((k|0)>0){f=d;a=c+1|0;f=a?f:f+1|0;L[l+16>>3]=+(a>>>0)+ +(f|0)*4294967296;e=v;f=e>>31;a=c+e|0;f=d+f|0;L[l+24>>3]=+(a>>>0)+ +((a>>>0>>0?f+1|0:f)|0)*4294967296;a=l+28864|0;Ya(a,81,46820,l+16|0);Ua(a);break c}e=v;f=e>>31;o=f;h=h-(f+(e>>>0>g>>>0)|0)|0;g=g-e|0;if(!(h|g)){break b}f=d+o|0;c=c+e|0;f=c>>>0>>0?f+1|0:f;d=f;f=o+G[l+29060>>2]|0;k=e+G[l+29056>>2]|0;f=k>>>0>>0?f+1|0:f;G[l+29056>>2]=k;G[l+29060>>2]=f;if(G[l+29072>>2]!=(k|0)|G[l+29076>>2]!=(f|0)){continue}G[l+29056>>2]=0;G[l+29060>>2]=0;e=x;f=w+1|0;e=f?e:e+1|0;w=f;x=e;continue}}k=G[j>>2];break a}if((k|0)!=-11){break a}Ua(44927);k=412;G[j>>2]=412}Fa=l+29104|0;return k}function Bh(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;l=Fa-29104|0;Fa=l;k=G[j>>2];a:{if((k|0)>0){break a}b:{c:{if((yc(a,b,c,d,e,f,g,h,1,l+29032|0,l+29024|0,l+28992|0,l+29088|0,l+29100|0,l+29096|0,l+29064|0,l+29056|0,l+29084|0,l+29072|0,l+29048|0,l+29092|0,l+29040|0,l+28832|0,j)|0)>0){break c}if(G[l+29100>>2]==16){Ne(l+28992|0,l+28960|0)}if(!(g|h)){k=G[j>>2];break b}c=0;d=0;while(1){e=G[l+29096>>2];r=e;e=e>>31;o=G[l+29072>>2];t=G[l+29076>>2];f=G[l+29068>>2];m=G[l+29064>>2];k=Au(G[l+29048>>2],G[l+29052>>2],w,x);m=m+k|0;f=Ia+f|0;f=k>>>0>m>>>0?f+1|0:f;n=m;k=G[l+29056>>2];p=G[l+29060>>2];m=G[l+29084>>2];u=Au(k,p,m,m>>31);n=n+u|0;m=Ia+f|0;Jb(a,n,n>>>0>>0?m+1|0:m,1,j);m=g>>>0>>0&(e|0)>=(h|0)|(e|0)>(h|0)?g:r;e=m;f=e>>31;n=e;e=t-((k>>>0>o>>>0)+p|0)|0;o=o-k|0;m=m>>>0>>0&(e|0)>=(f|0)|(e|0)>(f|0);o=m?n:o;d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{p:{e=G[l+29100>>2];switch(e-11|0){case 10:break h;case 30:break i;case 31:break j;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break m;case 5:break n;case 0:break o;default:break p}}switch(e-81|0){case 0:break g;case 1:break k;default:break m}}r=c+i|0;v=L[l+29032>>3];e=v!=1;q=L[l+29024>>3];if(!(e|q!=-128)){if((o|0)<=0){break e}e=0;k=0;if(o-1>>>0>=3){t=o&-4;m=0;while(1){n=l+32|0;E[n+k|0]=H[k+r|0]^128;p=k|1;E[p+n|0]=H[r+p|0]^128;p=k|2;E[p+n|0]=H[r+p|0]^128;f=n;n=k|3;E[f+n|0]=H[r+n|0]^128;k=k+4|0;m=m+4|0;if((t|0)!=(m|0)){continue}break}}m=o&3;if(!m){break e}while(1){E[(l+32|0)+k|0]=H[k+r|0]^128;k=k+1|0;e=e+1|0;if((m|0)!=(e|0)){continue}break}break e}if(!e&q==0){break f}k=0;if((o|0)<=0){break e}while(1){f=(l+32|0)+k|0;q:{r:{s=(+E[k+r|0]-q)/v;if(s<-.49){G[j>>2]=-11;break r}if(s>255.49){G[j>>2]=-11;e=255;break q}s=s+.5;if(!(s<4294967296&s>=0)){break r}e=~~s>>>0;break q}e=0}E[f|0]=e;k=k+1|0;if((o|0)!=(k|0)){continue}break}break e}if(jb(l+28992|0,65)){m=G[l+29084>>2];e=G[l+29088>>2];if((m|0)!=(e|0)){break l}e=o;m=e>>31;Wb(a,e,m,c+i|0,j);break d}if(H[l+28961|0]==115){break m}n=c+i|0;t=l+28960|0;p=G[l+29088>>2];m=l+32|0;k=0;r=Fa-32|0;Fa=r;q=L[l+29032>>3];s=L[l+29024>>3];s:{if(!(q==1&s==0)){if((o|0)<=0){break s}e=m;while(1){L[r+16>>3]=(+E[k+n|0]-s)/q;Eb(e,t,r+16|0);e=e+p|0;if(H[e|0]){G[j>>2]=-11}k=k+1|0;if((o|0)!=(k|0)){continue}break}break s}if((o|0)<=0){break s}e=m;while(1){L[r>>3]=E[k+n|0];Eb(e,t,r);e=e+p|0;if(H[e|0]){G[j>>2]=-11}k=k+1|0;if((o|0)!=(k|0)){continue}break}}k=jb(m,44);if(k){while(1){E[k|0]=46;k=jb(k,44);if(k){continue}break}}Fa=r+32|0;e=G[l+29084>>2];m=G[l+29088>>2];if((e|0)==(m|0)){e=M(e,o);Wb(a,e,e>>31,l+32|0,j);break d}wd(a,m,o,e-m|0,l+32|0,j);break d}G[l>>2]=b;G[l+4>>2]=l+28992;a=l+28864|0;Ya(a,81,8813,l);Ua(a);if(G[l+29092>>2]==1){k=311;G[j>>2]=311;break a}k=312;G[j>>2]=312;break a}wd(a,e,(o|0)/(e|0)|0,m-e|0,c+i|0,j);break d}r=c+i|0;q=L[l+29032>>3];s=L[l+29024>>3];t:{if(!(q==1&s==0)){if((o|0)<=0){break t}k=0;if((o|0)!=1){m=o&-2;e=0;while(1){n=l+32|0;L[n+(k<<3)>>3]=(+E[k+r|0]-s)/q;f=n;n=k|1;L[f+(n<<3)>>3]=(+E[r+n|0]-s)/q;k=k+2|0;e=e+2|0;if((m|0)!=(e|0)){continue}break}}if(!(o&1)){break t}L[(l+32|0)+(k<<3)>>3]=(+E[k+r|0]-s)/q;break t}if((o|0)<=0){break t}e=0;k=0;if(o-1>>>0>=3){t=o&-4;m=0;while(1){n=l+32|0;L[n+(k<<3)>>3]=E[k+r|0];p=k|1;L[n+(p<<3)>>3]=E[r+p|0];p=k|2;L[n+(p<<3)>>3]=E[r+p|0];p=k|3;L[n+(p<<3)>>3]=E[r+p|0];k=k+4|0;m=m+4|0;if((t|0)!=(m|0)){continue}break}}m=o&3;if(!m){break t}while(1){L[(l+32|0)+(k<<3)>>3]=E[k+r|0];k=k+1|0;e=e+1|0;if((m|0)!=(e|0)){continue}break}}_c(a,o,G[l+29084>>2],l+32|0,j);break d}r=c+i|0;q=L[l+29032>>3];s=L[l+29024>>3];u:{if(!(q==1&s==0)){if((o|0)<=0){break u}k=0;if((o|0)!=1){m=o&-2;e=0;while(1){n=l+32|0;K[n+(k<<2)>>2]=(+E[k+r|0]-s)/q;f=n;n=k|1;K[f+(n<<2)>>2]=(+E[r+n|0]-s)/q;k=k+2|0;e=e+2|0;if((m|0)!=(e|0)){continue}break}}if(!(o&1)){break u}K[(l+32|0)+(k<<2)>>2]=(+E[k+r|0]-s)/q;break u}if((o|0)<=0){break u}e=0;k=0;if(o-1>>>0>=3){t=o&-4;m=0;while(1){n=l+32|0;K[n+(k<<2)>>2]=E[k+r|0];p=k|1;K[n+(p<<2)>>2]=E[r+p|0];p=k|2;K[n+(p<<2)>>2]=E[r+p|0];p=k|3;K[n+(p<<2)>>2]=E[r+p|0];k=k+4|0;m=m+4|0;if((t|0)!=(m|0)){continue}break}}m=o&3;if(!m){break u}while(1){K[(l+32|0)+(k<<2)>>2]=E[k+r|0];k=k+1|0;e=e+1|0;if((m|0)!=(e|0)){continue}break}}$c(a,o,G[l+29084>>2],l+32|0,j);break d}r=c+i|0;s=L[l+29032>>3];v=L[l+29024>>3];v:{if(!(s==1&v==0)){k=0;if((o|0)<=0){break v}while(1){f=(l+32|0)+(k<<2)|0;w:{x:{q=(+E[k+r|0]-v)/s;if(q<-2147483648.49){G[j>>2]=-11;break x}if(q>2147483647.49){G[j>>2]=-11;e=2147483647;break w}if(q>=0){q=q+.5;if(!(O(q)<2147483648)){break x}e=~~q;break w}q=q+-.5;if(!(O(q)<2147483648)){break x}e=~~q;break w}e=-2147483648}G[f>>2]=e;k=k+1|0;if((o|0)!=(k|0)){continue}break}break v}if((o|0)<=0){break v}e=0;k=0;if(o-1>>>0>=3){t=o&-4;m=0;while(1){n=l+32|0;G[n+(k<<2)>>2]=E[k+r|0];p=k|1;G[n+(p<<2)>>2]=E[r+p|0];p=k|2;G[n+(p<<2)>>2]=E[r+p|0];p=k|3;G[n+(p<<2)>>2]=E[r+p|0];k=k+4|0;m=m+4|0;if((t|0)!=(m|0)){continue}break}}m=o&3;if(!m){break v}while(1){G[(l+32|0)+(k<<2)>>2]=E[k+r|0];k=k+1|0;e=e+1|0;if((m|0)!=(e|0)){continue}break}}$c(a,o,G[l+29084>>2],l+32|0,j);break d}r=c+i|0;s=L[l+29032>>3];v=L[l+29024>>3];y:{if(!(s==1&v==0)){k=0;if((o|0)<=0){break y}while(1){f=(l+32|0)+(k<<1)|0;q=(+E[k+r|0]-v)/s;z:{if(q<-32768.49){G[j>>2]=-11;e=32768;break z}if(q>32767.49){G[j>>2]=-11;e=32767;break z}A:{if(q>=0){q=q+.5;if(!(O(q)<2147483648)){break A}e=~~q;break z}q=q+-.5;if(!(O(q)<2147483648)){break A}e=~~q;break z}e=-2147483648}F[f>>1]=e;k=k+1|0;if((o|0)!=(k|0)){continue}break}break y}if((o|0)<=0){break y}e=0;k=0;if(o-1>>>0>=3){t=o&-4;m=0;while(1){n=l+32|0;F[n+(k<<1)>>1]=E[k+r|0];p=k|1;F[n+(p<<1)>>1]=E[r+p|0];p=k|2;F[n+(p<<1)>>1]=E[r+p|0];p=k|3;F[n+(p<<1)>>1]=E[r+p|0];k=k+4|0;m=m+4|0;if((t|0)!=(m|0)){continue}break}}m=o&3;if(!m){break y}while(1){F[(l+32|0)+(k<<1)>>1]=E[k+r|0];k=k+1|0;e=e+1|0;if((m|0)!=(e|0)){continue}break}}Oe(a,o,G[l+29084>>2],l+32|0,j);break d}r=c+i|0;B:{C:{D:{E:{v=L[l+29032>>3];e=v!=1;s=L[l+29024>>3];if(!(e|s!=0x8000000000000000)){if((o|0)<=0){break B}k=0;if((o|0)!=1){t=o&-2;e=0;while(1){m=(l+32|0)+(k<<3)|0;n=E[k+r|0];F:{if((n|0)<0){G[j>>2]=-11;f=0;break F}f=n&255}G[m>>2]=f;G[m+4>>2]=-2147483648;n=k|1;m=E[n+r|0];G:{if((m|0)>=0){m=m&255;break G}G[j>>2]=-11;m=0}n=(l+32|0)+(n<<3)|0;G[n>>2]=m;G[n+4>>2]=-2147483648;k=k+2|0;e=e+2|0;if((t|0)!=(e|0)){continue}break}}if(!(o&1)){break B}e=E[k+r|0];if((e|0)<0){break E}e=e&255;break D}if(!e&s==0){break C}k=0;if((o|0)<=0){break B}while(1){n=(l+32|0)+(k<<3)|0;H:{I:{q=(+E[k+r|0]-s)/v;if(q<-0x8000000000000000){G[j>>2]=-11;break I}if(q>0x8000000000000000){G[j>>2]=-11;m=2147483647;e=-1;break H}if(q>=0){q=q+.5;if(!(O(q)<0x8000000000000000)){break I}m=O(q)>=1?~~(q>0?Q(S(q*2.3283064365386963e-10),4294967295):T((q-+(~~q>>>0>>>0))*2.3283064365386963e-10))>>>0:0;e=~~q>>>0;break H}q=q+-.5;if(!(O(q)<0x8000000000000000)){break I}m=O(q)>=1?~~(q>0?Q(S(q*2.3283064365386963e-10),4294967295):T((q-+(~~q>>>0>>>0))*2.3283064365386963e-10))>>>0:0;e=~~q>>>0;break H}m=-2147483648;e=0}G[n>>2]=e;G[n+4>>2]=m;k=k+1|0;if((o|0)!=(k|0)){continue}break}break B}G[j>>2]=-11;e=0}m=(l+32|0)+(k<<3)|0;G[m>>2]=e;G[m+4>>2]=-2147483648;break B}if((o|0)<=0){break B}e=0;k=0;if(o-1>>>0>=3){t=o&-4;m=0;while(1){n=l+32|0;p=n+(k<<3)|0;u=E[k+r|0];G[p>>2]=u;G[p+4>>2]=u>>31;p=k|1;u=n+(p<<3)|0;p=E[r+p|0];G[u>>2]=p;G[u+4>>2]=p>>31;p=k|2;u=n+(p<<3)|0;p=E[r+p|0];G[u>>2]=p;G[u+4>>2]=p>>31;p=k|3;n=n+(p<<3)|0;p=E[r+p|0];G[n>>2]=p;G[n+4>>2]=p>>31;k=k+4|0;m=m+4|0;if((t|0)!=(m|0)){continue}break}}m=o&3;if(!m){break B}while(1){n=(l+32|0)+(k<<3)|0;t=E[k+r|0];G[n>>2]=t;G[n+4>>2]=t>>31;k=k+1|0;e=e+1|0;if((m|0)!=(e|0)){continue}break}}_c(a,o,G[l+29084>>2],l+32|0,j);break d}if((o|0)<=0){break e}k=0;if((o|0)!=1){n=o&-2;m=0;while(1){t=(l+32|0)+k|0;e=E[k+r|0];if((e|0)<0){G[j>>2]=-11;e=0}E[t|0]=e;t=k|1;e=E[t+r|0];if((e|0)<0){G[j>>2]=-11;e=0}E[t+(l+32|0)|0]=e;k=k+2|0;m=m+2|0;if((n|0)!=(m|0)){continue}break}}if(!(o&1)){break e}m=(l+32|0)+k|0;e=E[k+r|0];if((e|0)<0){G[j>>2]=-11;e=0}E[m|0]=e}we(a,o,G[l+29084>>2],l+32|0,j)}k=G[j>>2];if((k|0)>0){m=d;a=c+1|0;m=a?m:m+1|0;L[l+16>>3]=+(a>>>0)+ +(m|0)*4294967296;e=o;f=e>>31;a=c+e|0;f=d+f|0;L[l+24>>3]=+(a>>>0)+ +((a>>>0>>0?f+1|0:f)|0)*4294967296;a=l+28864|0;Ya(a,81,47869,l+16|0);Ua(a);break c}e=o;f=e>>31;h=h-((e>>>0>g>>>0)+f|0)|0;g=g-e|0;if(!(h|g)){break b}m=d+f|0;c=c+e|0;m=c>>>0>>0?m+1|0:m;d=m;f=f+G[l+29060>>2]|0;m=e+G[l+29056>>2]|0;f=m>>>0>>0?f+1|0:f;e=m;G[l+29056>>2]=e;G[l+29060>>2]=f;if(G[l+29072>>2]!=(e|0)|G[l+29076>>2]!=(f|0)){continue}G[l+29056>>2]=0;G[l+29060>>2]=0;e=x;f=w+1|0;e=f?e:e+1|0;w=f;x=e;continue}}k=G[j>>2];break a}if((k|0)!=-11){break a}Ua(44927);k=412;G[j>>2]=412}Fa=l+29104|0;return k}function qe(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,I=0,K=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0;q=Fa-29104|0;Fa=q;p=G[o>>2];a:{if(!(g|h)|(p|0)>0){break a}if(n){G[n>>2]=0}if((j|0)==2){cb(m,0,g)}if((yc(a,b,c,d,e,f,g,h,0,q+29096|0,q+29088|0,q+28992|0,q+29064|0,q+29084|0,q+29080|0,q+29040|0,q+29032|0,q+29060|0,q+29048|0,q+29016|0,q+29076|0,q+29024|0,q+28864|0,o)|0)>0){p=G[o>>2];break a}G[q+29060>>2]=M(G[q+29060>>2],i);z=1;c=G[q+29080>>2];O=c;P=c>>31;b:{if(G[q+29084>>2]!=16){break b}Gd(q+28992|0,q+29072|0,q+29056|0,q+29068|0,o);d=G[q+29068>>2];if((d|0)<=0){break b}if(d-1>>>0>=7){c=d&-8;p=0;while(1){z=z*10*10*10*10*10*10*10*10;p=p+8|0;if((c|0)!=(p|0)){continue}break}}c=d&7;if(!c){break b}p=0;while(1){z=z*10;p=p+1|0;if((c|0)!=(p|0)){continue}break}}c:{if(k?0:(j|0)==1){break c}c=G[q+29028>>2];p=c;d=!c;c=G[q+29024>>2];f=G[q+29084>>2];if(d&(c|0)==1234554321&((f|0)%10|0)==1){break c}e=p-(c>>>0<32768)|0;if(((e|0)==-1&c-32768>>>0<4294901760|(e|0)!=-1)&(f|0)==21|(!p&c>>>0>255|(p|0)!=0)&(f|0)==11){break c}y=(f|0)==16?H[q+28864|0]==1?0:j:j}U=i>>31;e=0;f=0;d:{while(1){c=G[q+29044>>2];j=G[q+29040>>2];d=Au(G[q+29016>>2],G[q+29020>>2],Q,R);j=j+d|0;c=Ia+c|0;c=d>>>0>j>>>0?c+1|0:c;s=G[q+29032>>2];p=G[q+29036>>2];w=G[q+29060>>2];d=(w|0)/(i|0)|0;d=Au(s,p,d,d>>31);j=d+j|0;c=Ia+c|0;u=j;j=d>>>0>j>>>0?c+1|0:c;p=G[q+29052>>2]+(p^-1)|0;c=s^-1;d=c+G[q+29048>>2]|0;v=Bu(d,c>>>0>d>>>0?p+1|0:p,i,U);c=Ia;s=c;d=v+1|0;c=d?c:c+1|0;p=d;r=p;c=g>>>0>>0&(h|0)<=(P|0)|(h|0)<(P|0)?g:O;p=c>>31;d=c;c=c>>>0>v>>>0&(p|0)>=(s|0)|(p|0)>(s|0);r=c?r:d;e:{f:{g:{h:{i:{j:{k:{l:{m:{c=G[q+29084>>2];switch(c-11|0){case 30:break f;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break g;case 5:break h;case 31:break j;case 10:break k;case 0:break l;default:break m}}n:{switch(c-81|0){case 1:break i;case 0:break n;default:break g}}c=w;w=q- -64|0;Tc(a,u,j,r,c,w,o);v=G[q+29024>>2];s=G[q+29028>>2];j=e+m|0;u=(e<<2)+l|0;B=L[q+29096>>3];C=L[q+29088>>3];c=B==1&C==0x8000000000000000;o:{p:{if(!y){q:{r:{if(c){if((r|0)<=0){break o}p=0;if((r|0)!=1){v=r&-2;s=0;while(1){d=u+(p<<2)|0;c=w+(p<<3)|0;j=G[c+4>>2];c=G[c>>2];if((j|0)>-2147483647|(j|0)>=-2147483647){G[o>>2]=-11;c=-1}G[d>>2]=c;j=p|1;c=w+(j<<3)|0;d=G[c+4>>2];c=G[c>>2];if((d|0)!=-2147483648){G[o>>2]=-11;c=-1}G[u+(j<<2)>>2]=c;p=p+2|0;s=s+2|0;if((v|0)!=(s|0)){continue}break}}if(!(r&1)){break o}c=w+(p<<3)|0;d=G[c+4>>2];c=G[c>>2];if((d|0)!=-2147483648){break r}break q}if(B==1&C==0){break p}p=0;if((r|0)<=0){break o}while(1){d=u+(p<<2)|0;s:{t:{c=w+(p<<3)|0;t=(+J[c>>2]+ +G[c+4>>2]*4294967296)*B+C;if(t<-.49){G[o>>2]=-11;break t}if(t>0xfffffffffffff800){G[o>>2]=-11;c=-1;break s}if(!(t<4294967296&t>=0)){break t}c=~~t>>>0;break s}c=0}G[d>>2]=c;p=p+1|0;if((r|0)!=(p|0)){continue}break}break o}G[o>>2]=-11;c=-1}G[u+(p<<2)>>2]=c;break o}if(c){if((r|0)<=0){break o}p=0;while(1){d=w+(p<<3)|0;c=G[d>>2];d=G[d+4>>2];u:{if((c|0)==(v|0)&(d|0)==(s|0)){G[n>>2]=1;if((y|0)==1){G[u+(p<<2)>>2]=k;break u}E[j+p|0]=1;break u}if((d|0)>-2147483647|(d|0)>=-2147483647){G[o>>2]=-11;G[u+(p<<2)>>2]=-1;break u}G[u+(p<<2)>>2]=c}p=p+1|0;if((r|0)!=(p|0)){continue}break}break o}if(!(B==1&C==0)){if((r|0)<=0){break o}p=0;while(1){c=w+(p<<3)|0;d=G[c>>2];c=G[c+4>>2];v:{if((d|0)==(v|0)&(c|0)==(s|0)){G[n>>2]=1;if((y|0)==1){G[u+(p<<2)>>2]=k;break v}E[j+p|0]=1;break v}t=(+(d>>>0)+ +(c|0)*4294967296)*B+C;if(t<-.49){G[o>>2]=-11;G[u+(p<<2)>>2]=0;break v}if(t>0xfffffffffffff800){G[o>>2]=-11;G[u+(p<<2)>>2]=-1;break v}c=u+(p<<2)|0;if(t<4294967296&t>=0){d=~~t>>>0}else{d=0}G[c>>2]=d}p=p+1|0;if((r|0)!=(p|0)){continue}break}break o}if((r|0)<=0){break o}p=0;while(1){d=w+(p<<3)|0;c=G[d>>2];d=G[d+4>>2];w:{if((c|0)==(v|0)&(d|0)==(s|0)){G[n>>2]=1;if((y|0)==1){G[u+(p<<2)>>2]=k;break w}E[j+p|0]=1;break w}if((d|0)<0){G[o>>2]=-11;G[u+(p<<2)>>2]=0;break w}if((d|0)==1|d>>>0>1){G[o>>2]=-11;G[u+(p<<2)>>2]=-1;break w}G[u+(p<<2)>>2]=c}p=p+1|0;if((r|0)!=(p|0)){continue}break}break o}if((r|0)<=0){break o}p=0;if((r|0)!=1){v=r&-2;s=0;while(1){j=u+(p<<2)|0;c=w+(p<<3)|0;d=G[c+4>>2];c=G[c>>2];x:{if((d|0)<0){G[o>>2]=-11;c=0;break x}if((d|0)==1|d>>>0>1){G[o>>2]=-11;c=-1}}G[j>>2]=c;j=p|1;d=w+(j<<3)|0;c=G[d+4>>2];d=G[d>>2];y:{if((c|0)>0|(c|0)>=0){if(!c){break y}G[o>>2]=-11;d=-1;break y}G[o>>2]=-11;d=0}G[u+(j<<2)>>2]=d;p=p+2|0;s=s+2|0;if((v|0)!=(s|0)){continue}break}}if(!(r&1)){break o}j=u+(p<<2)|0;d=w+(p<<3)|0;c=G[d+4>>2];d=G[d>>2];z:{if((c|0)>0|(c|0)>=0){if(!c){break z}G[o>>2]=-11;d=-1;break z}G[o>>2]=-11;d=0}G[j>>2]=d}break e}c=q- -64|0;$d(a,u,j,r,w,c,o);Ep(c,r,L[q+29096>>3],L[q+29088>>3],y,H[q+29024|0],k,e+m|0,n,(e<<2)+l|0,o);break e}c=q- -64|0;Pe(a,u,j,r,w,c,o);Dp(c,r,L[q+29096>>3],L[q+29088>>3],y,F[q+29024>>1],k,e+m|0,n,(e<<2)+l|0,o);break e}c=q- -64|0;Uc(a,u,j,r,w,c,o);Cp(c,r,L[q+29096>>3],L[q+29088>>3],y,k,e+m|0,n,(e<<2)+l|0,o);break e}c=q- -64|0;Tc(a,u,j,r,w,c,o);Bp(c,r,L[q+29096>>3],L[q+29088>>3],y,k,e+m|0,n,(e<<2)+l|0,o);break e}Jb(a,u,j,0,o);d=G[q+29060>>2];c=G[q+29064>>2];A:{if((d|0)==(c|0)){c=M(d,r);ic(a,c,c>>31,q- -64|0,o);break A}Rd(a,c,r,d-c|0,q- -64|0,o)}s=q- -64|0;B=L[q+29096>>3];C=L[q+29088>>3];V=G[q+29064>>2];W=e+m|0;I=(e<<2)+l|0;A=0;x=Fa-112|0;Fa=x;K=q+28864|0;u=Va(K);if((r|0)>0){while(1){B:{c=s+V|0;S=H[c|0];E[c|0]=0;j=s;C:{D:{if(H[K|0]==1){break D}if(fb(K,s,u)){break D}j=c;if(!y){break C}G[n>>2]=1;if((y|0)==1){G[(A<<2)+I>>2]=k;break C}E[A+W|0]=1;break C}while(1){d=H[j|0];if((d|0)==32){j=j+1|0;continue}break}T=1;E:{switch(d-43|0){case 0:case 2:while(1){p=H[j+1|0];j=j+1|0;if((p|0)==32){continue}break};T=(d|0)==45?-1:1;d=p;break;default:break E}}D=0;if((d-48&255)>>>0<10){while(1){t=D*10+ +(d<<24>>24);p=j;while(1){d=H[p+1|0];j=p+1|0;p=j;if((d|0)==32){continue}break}D=t+-48;if((d-48&255)>>>0<=9){continue}break}}t=z;F:{G:{switch(d-44|0){case 0:case 2:break G;default:break F}}p=j;while(1){d=H[p+1|0];j=p+1|0;p=j;if((d|0)==32){continue}break}t=1;if((d-48&255)>>>0>=10){break F}while(1){D=D*10+ +(d<<24>>24)+-48;p=j;while(1){d=H[p+1|0];j=p+1|0;p=j;if((d|0)==32){continue}break}t=t*10;if((d-48&255)>>>0<=9){continue}break}}H:{if((d&254)!=68){N=1;p=0;break H}while(1){N=1;p=j;j=p+1|0;d=H[p+1|0];if((d|0)==32){continue}break}I:{switch(d-43|0){case 0:case 2:p=p+2|0;while(1){j=p;p=p+1|0;v=H[j|0];if((v|0)==32){continue}break};N=(d|0)==45?-1:1;d=v;break;default:break I}}p=0;if((d-48&255)>>>0>=10){break H}while(1){v=d;w=M(p,10)-48|0;p=j;while(1){d=H[p+1|0];j=p+1|0;p=j;if((d|0)==32){continue}break}p=(v<<24>>24)+w|0;if((d-48&255)>>>0<=9){continue}break}}if(d){G[x+48>>2]=H[23477]|H[23478]<<8|(H[23479]<<16|H[23480]<<24);d=H[23473]|H[23474]<<8|(H[23475]<<16|H[23476]<<24);G[x+40>>2]=H[23469]|H[23470]<<8|(H[23471]<<16|H[23472]<<24);G[x+44>>2]=d;d=H[23465]|H[23466]<<8|(H[23467]<<16|H[23468]<<24);G[x+32>>2]=H[23461]|H[23462]<<8|(H[23463]<<16|H[23464]<<24);G[x+36>>2]=d;d=H[23457]|H[23458]<<8|(H[23459]<<16|H[23460]<<24);G[x+24>>2]=H[23453]|H[23454]<<8|(H[23455]<<16|H[23456]<<24);G[x+28>>2]=d;d=H[23449]|H[23450]<<8|(H[23451]<<16|H[23452]<<24);G[x+16>>2]=H[23445]|H[23446]<<8|(H[23447]<<16|H[23448]<<24);G[x+20>>2]=d;d=x+16|0;Ua(d);G[x>>2]=s;Ya(d,81,43022,x);Ua(d);E[c|0]=S;G[o>>2]=409;break B}t=D*+(T|0)/t*$b(10,+(M(p,N)|0))*B+C;J:{if(t<-.49){G[o>>2]=-11;G[(A<<2)+I>>2]=0;break J}if(t>0xfffffffffffff800){G[o>>2]=-11;G[(A<<2)+I>>2]=-1;break J}d=(A<<2)+I|0;if(t<4294967296&t>=0){p=~~t>>>0}else{p=0}G[d>>2]=p}}s=j;E[c|0]=S;A=A+1|0;if((r|0)!=(A|0)){continue}}break}}Fa=x+112|0;break e}G[q>>2]=b;G[q+4>>2]=q+28992;a=q+28896|0;Ya(a,81,8924,q);Ua(a);p=311;if(G[q+29076>>2]==1){break d}p=312;break d}c=q- -64|0;Uc(a,u,j,r,w,c,o);Uk(c,r,L[q+29096>>3],L[q+29088>>3],y,G[q+29024>>2],k,e+m|0,n,(e<<2)+l|0,o)}p=G[o>>2];if((p|0)>0){t=+(e>>>0)+ +(f|0)*4294967296;z=t+1;t=t+ +(r|0);K:{if(G[q+29076>>2]>0){G[q+32>>2]=b;L[q+24>>3]=t;L[q+16>>3]=z;Ya(q+28896|0,81,46566,q+16|0);break K}L[q+56>>3]=t;L[q+48>>3]=z;Ya(q+28896|0,81,46506,q+48|0)}Ua(q+28896|0);p=G[o>>2];break a}d=r;c=d>>31;h=h-((d>>>0>g>>>0)+c|0)|0;g=g-d|0;if(h|g){p=M(i,r);s=p;v=p+G[q+29032>>2]|0;p=G[q+29036>>2]+(p>>31)|0;p=s>>>0>v>>>0?p+1|0:p;s=v;G[q+29032>>2]=s;G[q+29036>>2]=p;c=c+f|0;e=d+e|0;c=e>>>0>>0?c+1|0:c;f=c;v=G[q+29048>>2];d=G[q+29052>>2];c=d;if(v>>>0>s>>>0&(c|0)>=(p|0)|(c|0)>(p|0)){continue}c=s;s=Bu(c,p,v,d);j=Ia;d=Au(s,j,v,d);G[q+29032>>2]=c-d;G[q+29036>>2]=p-(Ia+(c>>>0>>0)|0);c=j+R|0;d=Q;p=d+s|0;Q=p;R=d>>>0>p>>>0?c+1|0:c;continue}break}if((p|0)!=-11){break a}Ua(44994);p=412}G[o>>2]=p}Fa=q+29104|0;return p}function Re(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,I=0,K=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0;q=Fa-29104|0;Fa=q;p=G[o>>2];a:{if(!(g|h)|(p|0)>0){break a}if(n){G[n>>2]=0}if((j|0)==2){cb(m,0,g)}yc(a,b,c,d,e,f,g,h,(i|0)<0?15:16,q+29096|0,q+29088|0,q+28992|0,q+29064|0,q+29084|0,q+29080|0,q+29040|0,q+29032|0,q+29060|0,q+29048|0,q+29016|0,q+29076|0,q+29024|0,q+28864|0,o);p=G[q+29080>>2];P=p;Q=p>>31;r=G[q+29084>>2];if(!((i|0)!=1|(r|0)!=14)){fg(a,b,c,d,e,f,g,h,j,k<<24>>24,l,m,n,o);p=G[o>>2];break a}p=G[o>>2];if((p|0)>0){break a}G[q+29060>>2]=M(G[q+29060>>2],i);A=1;b:{if((r|0)!=16|G[q+29076>>2]!=1){break b}Gd(q+28992|0,q+29072|0,q+29056|0,q+29068|0,o);d=G[q+29068>>2];if((d|0)<=0){break b}if(d-1>>>0>=7){c=d&-8;p=0;while(1){A=A*10*10*10*10*10*10*10*10;p=p+8|0;if((c|0)!=(p|0)){continue}break}}c=d&7;if(!c){break b}p=0;while(1){A=A*10;p=p+1|0;if((c|0)!=(p|0)){continue}break}}f=G[q+29084>>2];c:{d:{e:{if(k?0:(j|0)==1){break e}e=G[q+29028>>2];c=G[q+29024>>2];if(!e&(c|0)==1234554321&((f|0)%10|0)==1){break e}if(!((e-(c>>>0<32768)|0)==-1&c-32768>>>0>=4294901760|(f|0)!=21)){N=0;break c}if((!e&c>>>0>255|(e|0)!=0)&(f|0)==11){break d}z=(f|0)==16?H[q+28864|0]==1?0:j:j}N=0;if((f|0)!=11){break c}}c=g>>>0<2147483647&(h|0)<=0|(h|0)<0;P=c?g:2147483647;Q=c?h:0;N=!z&L[q+29096>>3]==1&L[q+29088>>3]==0}V=0-i|0;e=0;f=0;f:{while(1){c=g>>>0

>>0&(h|0)<=(Q|0)|(h|0)<(Q|0)?g:P;d=c>>31;t=c;v=d;g:{if((i|0)>=0){d=G[q+29036>>2];p=G[q+29052>>2]+(d^-1)|0;c=G[q+29032>>2];j=c^-1;r=j+G[q+29048>>2]|0;r=Bu(r,j>>>0>r>>>0?p+1|0:p,i,0);j=Ia;break g}c=G[q+29032>>2];d=G[q+29036>>2];r=Bu(c,d,V,0);j=Ia}s=G[q+29044>>2];w=G[q+29040>>2];p=Au(G[q+29016>>2],G[q+29020>>2],B,C);w=w+p|0;s=Ia+s|0;s=p>>>0>w>>>0?s+1|0:s;x=w;p=c;w=G[q+29060>>2];c=(w|0)/(i|0)|0;d=Au(p,d,c,c>>31);p=x+d|0;c=Ia+s|0;c=d>>>0>p>>>0?c+1|0:c;s=p;p=j;d=r+1|0;p=d;d=(j|0)<=(v|0)&t>>>0>r>>>0|(j|0)<(v|0);t=d?p:t;h:{i:{j:{k:{l:{m:{n:{o:{p:{q:{d=G[q+29084>>2];switch(d-11|0){case 10:break i;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break j;case 5:break k;case 31:break m;case 30:break o;case 0:break p;default:break q}}switch(d-81|0){case 1:break l;case 0:break n;default:break j}}d=c;c=e+l|0;$d(a,s,d,t,w,c,o);if(N){break h}vp(c,t,L[q+29096>>3],L[q+29088>>3],z,H[q+29024|0],k,e+m|0,n,c,o);break h}d=c;c=q- -64|0;Uc(a,s,d,t,w,c,o);up(c,t,L[q+29096>>3],L[q+29088>>3],z,G[q+29024>>2],k,e+m|0,n,e+l|0,o);break h}x=q- -64|0;Tc(a,s,c,t,w,x,o);w=G[q+29024>>2];s=G[q+29028>>2];j=e+m|0;c=e+l|0;D=L[q+29096>>3];I=L[q+29088>>3];d=D==1&I==0x8000000000000000;r:{s:{if(!z){t:{u:{if(d){if((t|0)<=0){break r}d=0;if((t|0)!=1){s=t&-2;j=0;while(1){v=c+d|0;p=x+(d<<3)|0;r=G[p+4>>2];p=G[p>>2];if((r|0)!=-2147483648|p>>>0>=256){G[o>>2]=-11;p=255}E[v|0]=p;v=d|1;p=x+(v<<3)|0;r=G[p+4>>2];p=G[p>>2];if(!((r|0)==-2147483648&p>>>0<=255)){G[o>>2]=-11;p=255}E[c+v|0]=p;d=d+2|0;j=j+2|0;if((s|0)!=(j|0)){continue}break}}if(!(t&1)){break r}j=x+(d<<3)|0;p=G[j+4>>2];j=G[j>>2];if((p|0)!=-2147483648|j>>>0>255){break u}break t}if(D==1&I==0){break s}d=0;if((t|0)<=0){break r}while(1){p=c+d|0;v:{w:{j=x+(d<<3)|0;u=(+J[j>>2]+ +G[j+4>>2]*4294967296)*D+I;if(u<-.49){G[o>>2]=-11;break w}if(u>255.49){G[o>>2]=-11;j=255;break v}if(!(u<4294967296&u>=0)){break w}j=~~u>>>0;break v}j=0}E[p|0]=j;d=d+1|0;if((t|0)!=(d|0)){continue}break}break r}G[o>>2]=-11;j=255}E[c+d|0]=j;break r}if(d){if((t|0)<=0){break r}d=(z|0)==1;v=d?k:1;r=d?c:j;d=0;while(1){p=x+(d<<3)|0;j=G[p>>2];p=G[p+4>>2];x:{if((j|0)==(w|0)&(p|0)==(s|0)){G[n>>2]=1;j=v;p=r;break x}if((p|0)!=-2147483648|j>>>0>=256){G[o>>2]=-11;j=255}p=c}E[p+d|0]=j;d=d+1|0;if((t|0)!=(d|0)){continue}break}break r}if(!(D==1&I==0)){if((t|0)<=0){break r}d=(z|0)==1;v=d?k:1;r=d?c:j;d=0;while(1){j=x+(d<<3)|0;p=G[j>>2];j=G[j+4>>2];y:{if((p|0)==(w|0)&(j|0)==(s|0)){G[n>>2]=1;j=v;p=r;break y}z:{A:{u=(+(p>>>0)+ +(j|0)*4294967296)*D+I;if(u<-.49){G[o>>2]=-11;break A}if(u>255.49){G[o>>2]=-11;j=255;break z}if(!(u<4294967296&u>=0)){break A}j=~~u>>>0;break z}j=0}p=c}E[p+d|0]=j;d=d+1|0;if((t|0)!=(d|0)){continue}break}break r}if((t|0)<=0){break r}d=(z|0)==1;v=d?k:1;r=d?c:j;d=0;while(1){p=x+(d<<3)|0;j=G[p>>2];p=G[p+4>>2];B:{if((j|0)==(w|0)&(p|0)==(s|0)){G[n>>2]=1;j=v;p=r;break B}C:{if((p|0)<0){G[o>>2]=-11;j=0;break C}if(!p&j>>>0>=256|p){G[o>>2]=-11;j=255}}p=c}E[p+d|0]=j;d=d+1|0;if((t|0)!=(d|0)){continue}break}break r}if((t|0)<=0){break r}d=0;while(1){r=c+d|0;p=x+(d<<3)|0;j=G[p+4>>2];p=G[p>>2];D:{if((j|0)<0){G[o>>2]=-11;p=0;break D}if(!j&p>>>0>=256|j){G[o>>2]=-11;p=255}}E[r|0]=p;d=d+1|0;if((t|0)!=(d|0)){continue}break}}break h}d=c;c=q- -64|0;Uc(a,s,d,t,w,c,o);tp(c,t,L[q+29096>>3],L[q+29088>>3],z,k,e+m|0,n,e+l|0,o);break h}d=c;c=q- -64|0;Tc(a,s,d,t,w,c,o);sp(c,t,L[q+29096>>3],L[q+29088>>3],z,k,e+m|0,n,e+l|0,o);break h}Jb(a,s,c,0,o);d=G[q+29060>>2];c=G[q+29064>>2];E:{if((d|0)==(c|0)){c=M(d,t);ic(a,c,c>>31,q- -64|0,o);break E}Rd(a,c,t,d-c|0,q- -64|0,o)}d=q- -64|0;D=L[q+29096>>3];I=L[q+29088>>3];W=G[q+29064>>2];j=e+m|0;x=e+l|0;O=0;y=Fa-112|0;Fa=y;R=q+28864|0;X=Va(R);if((t|0)>0){F:{c=(z|0)==1;w=c?k:1;s=c?x:j;while(1){r=d+W|0;T=H[r|0];E[r|0]=0;p=d;G:{H:{I:{if(H[R|0]==1){break I}if(fb(R,d,X)){break I}d=r;if(!z){break G}G[n>>2]=1;c=w;p=r;d=s;break H}while(1){c=H[p|0];if((c|0)==32){p=p+1|0;continue}break}U=1;J:{switch(c-43|0){case 0:case 2:while(1){j=H[p+1|0];p=p+1|0;if((j|0)==32){continue}break};U=(c|0)==45?-1:1;c=j;break;default:break J}}K=0;if((c-48&255)>>>0<10){while(1){u=K*10+ +(c<<24>>24);j=p;while(1){c=H[j+1|0];p=j+1|0;j=p;if((c|0)==32){continue}break}K=u+-48;if((c-48&255)>>>0<=9){continue}break}}u=A;K:{L:{switch(c-44|0){case 0:case 2:break L;default:break K}}j=p;while(1){c=H[j+1|0];p=j+1|0;j=p;if((c|0)==32){continue}break}u=1;if((c-48&255)>>>0>=10){break K}while(1){K=K*10+ +(c<<24>>24)+-48;j=p;while(1){c=H[j+1|0];p=j+1|0;j=p;if((c|0)==32){continue}break}u=u*10;if((c-48&255)>>>0<=9){continue}break}}M:{if((c&254)!=68){S=1;j=0;break M}while(1){S=1;j=p;p=p+1|0;c=H[j+1|0];if((c|0)==32){continue}break}N:{switch(c-43|0){case 0:case 2:j=j+2|0;while(1){p=j;j=p+1|0;v=H[p|0];if((v|0)==32){continue}break};S=(c|0)==45?-1:1;c=v;break;default:break N}}j=0;if((c-48&255)>>>0>=10){break M}while(1){v=c;Y=M(j,10)-48|0;j=p;while(1){c=H[j+1|0];p=j+1|0;j=p;if((c|0)==32){continue}break}j=(v<<24>>24)+Y|0;if((c-48&255)>>>0<=9){continue}break}}if(c){G[y+48>>2]=H[23477]|H[23478]<<8|(H[23479]<<16|H[23480]<<24);c=H[23473]|H[23474]<<8|(H[23475]<<16|H[23476]<<24);G[y+40>>2]=H[23469]|H[23470]<<8|(H[23471]<<16|H[23472]<<24);G[y+44>>2]=c;c=H[23465]|H[23466]<<8|(H[23467]<<16|H[23468]<<24);G[y+32>>2]=H[23461]|H[23462]<<8|(H[23463]<<16|H[23464]<<24);G[y+36>>2]=c;c=H[23457]|H[23458]<<8|(H[23459]<<16|H[23460]<<24);G[y+24>>2]=H[23453]|H[23454]<<8|(H[23455]<<16|H[23456]<<24);G[y+28>>2]=c;c=H[23449]|H[23450]<<8|(H[23451]<<16|H[23452]<<24);G[y+16>>2]=H[23445]|H[23446]<<8|(H[23447]<<16|H[23448]<<24);G[y+20>>2]=c;c=y+16|0;Ua(c);G[y>>2]=d;Ya(c,81,43022,y);Ua(c);E[r|0]=T;G[o>>2]=409;break F}O:{P:{u=K*+(U|0)/u*$b(10,+(M(j,S)|0))*D+I;if(u<-.49){G[o>>2]=-11;break P}if(u>255.49){G[o>>2]=-11;c=255;break O}if(!(u<4294967296&u>=0)){break P}c=~~u>>>0;break O}c=0}d=x}E[d+O|0]=c;d=p}E[r|0]=T;O=O+1|0;if((t|0)!=(O|0)){continue}break}}}Fa=y+112|0;break h}G[q>>2]=b;G[q+4>>2]=q+28992;a=q+28896|0;Ya(a,81,8979,q);Ua(a);p=311;if(G[q+29076>>2]==1){break f}p=312;break f}d=c;c=q- -64|0;Pe(a,s,d,t,w,c,o);Tk(c,t,L[q+29096>>3],L[q+29088>>3],z,F[q+29024>>1],k,e+m|0,n,e+l|0,o)}p=G[o>>2];if((p|0)>0){u=+(e>>>0)+ +(f|0)*4294967296;A=u+1;u=u+ +(t|0);Q:{if(G[q+29076>>2]>0){G[q+32>>2]=b;L[q+24>>3]=u;L[q+16>>3]=A;Ya(q+28896|0,81,48189,q+16|0);break Q}L[q+56>>3]=u;L[q+48>>3]=A;Ya(q+28896|0,81,48130,q+48|0)}Ua(q+28896|0);p=G[o>>2];break a}d=t;j=d>>31;h=h-((d>>>0>g>>>0)+j|0)|0;g=g-d|0;if(h|g){c=M(i,t);r=c+G[q+29032>>2]|0;p=G[q+29036>>2]+(c>>31)|0;p=c>>>0>r>>>0?p+1|0:p;c=r;G[q+29032>>2]=c;G[q+29036>>2]=p;s=f+j|0;e=d+e|0;s=e>>>0>>0?s+1|0:s;f=s;s=G[q+29052>>2];d=s;v=G[q+29048>>2];if((p|0)>=(d|0)&c>>>0>=v>>>0|(d|0)<(p|0)){j=Bu(c,p,v,s);r=B+j|0;d=Ia;C=C+d|0;C=r>>>0>>0?C+1|0:C;B=r;d=Au(v,s,j,d);G[q+29032>>2]=c-d;G[q+29036>>2]=p-(Ia+(c>>>0>>0)|0);continue}if((p|0)>0|(p|0)>=0){continue}j=B;B=Bu(c^-1,p^-1,v,s)+1|0;d=Ia;d=B?d:d+1|0;r=B;B=j-r|0;C=C-((j>>>0>>0)+d|0)|0;d=Au(v,s,r,d)+c|0;s=p+Ia|0;G[q+29032>>2]=d;G[q+29036>>2]=c>>>0>d>>>0?s+1|0:s;continue}break}if((p|0)!=-11){break a}Ua(44994);p=412}G[o>>2]=p}Fa=q+29104|0;return p}function Kf(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;f=Fa-4528|0;Fa=f;G[f+404>>2]=0;G[f+400>>2]=0;a:{b:{c:{d:{e:{f:{g:{h:{i=E[a|0];switch(i-102|0){case 1:case 2:case 4:case 5:case 7:case 8:case 9:case 10:case 11:case 12:case 14:break b;case 15:break c;case 13:break d;case 6:break e;case 3:break f;case 0:break g;default:break h}}if(!i|(i|0)==35){break a}break b}if(Xa(a,22609)){break b}i:{if(c){a=G[b>>2];j:{if(!a){break j}c=G[936854];if(!c){break j}while(1){b=G[c+4>>2];e=Sb(b,a);k:{if(!e){break k}if((Va(e)|0)!=(Va(a)|0)){break k}if((b|0)==(e|0)|H[b+(e+(b^-1)|0)|0]==47){break i}}c=G[c>>2];if(c){continue}break}}G[f+48>>2]=a;_a(G[24367],89497,f+48|0);h=1;break a}c=G[936855];if(c){break i}G[f+16>>2]=a;_a(G[24367],89404,f+16|0);h=1;break a}b=G[c+16>>2];if(!b){break a}a=G[29763];if(d){hb(68347,9,1,a);b=G[c+16>>2]}c=G[c+4>>2];G[f+36>>2]=b;G[f+32>>2]=c;_a(a,69095,f+32|0);$a(a);break a}if(!Xa(a,25125)){if(!c){G[f+68>>2]=1;G[f+72>>2]=0;G[f+64>>2]=a;_a(G[24367],88305,f- -64|0);h=1;break a}c=Il(G[b>>2]);if(!c){h=1;break a}G[936855]=c;if(d){hb(68357,6,1,G[29763])}a=G[c+16>>2];a=a?a:36147;b=Fd(33984);l:{if(!b){b=a;break l}if(!H[b|0]){b=a;break l}d=Sb(a,b);if(!d){b=a;break l}if(!H[d|0]){b=a;break l}if(Xa(d,a)){b=a;break l}b=qb(rb(f+432|0,1522,4095),Va(b)+a|0,4095);pb(a)}a=G[c+4>>2];G[f+84>>2]=b;G[f+80>>2]=a;a=G[29763];_a(a,69095,f+80|0);$a(a);break a}if(!Xa(a,31902)){if(!c){G[f+100>>2]=1;G[f+104>>2]=0;G[f+96>>2]=a;_a(G[24367],88305,f+96|0);h=1;break a}a=Il(G[b>>2]);if(!a){h=1;break a}G[936855]=a;break a}if(!Xa(a,14072)){i=G[936855];if(!i){G[f+112>>2]=a;_a(G[24367],89404,f+112|0);h=1;break a}h=1;if((c|0)<=1){G[f+132>>2]=2;G[f+128>>2]=a;_a(G[24367],88249,f+128|0);break a}a=0;n=Kj(G[i+16>>2],0,33281,0,f+408|0,f+404|0);if(G[f+404>>2]){G[f+240>>2]=G[i+16>>2];_a(G[24367],89535,f+240|0);break a}d=G[b+4>>2];p=G[b>>2];e=32824;h=0;m:{if(c>>>0<3){break m}a=G[b+8>>2];n:{if(!a){a=0;break n}a=le(a);l=Sb(a,36004);if(!l){break n}E[l|0]=0;e=l+2|0}if(c>>>0<4){break m}h=G[b+12>>2]}o:{if(d){l=G[f+408>>2];c=Fa-432|0;Fa=c;G[c+428>>2]=0;G[f+428>>2]=0;G[c+176>>2]=c+192;G[c+172>>2]=c+240;G[c+168>>2]=c+288;G[c+164>>2]=c+336;G[c+160>>2]=c+384;p:{q:{if((Qc(d,32013,c+160|0)|0)==5){g=sb(c+384|0);j=sb(c+336|0);k=sb(c+288|0);m=sb(c+240|0);q=f,r=vb(c+192|0,c+188|0),L[q+384>>3]=r;d=G[c+188>>2];if(!d){break q}d=E[d|0];if(!d|((d-65>>>0<26?d|32:d)|0)!=97){break q}G[f+428>>2]=1;break q}G[c+156>>2]=c+240;G[c+152>>2]=c+288;G[c+148>>2]=c+336;G[c+144>>2]=c+384;if((Qc(d,32215,c+144|0)|0)==4){g=sb(c+384|0);j=sb(c+336|0);k=sb(c+288|0);m=sb(c+240|0);G[f+384>>2]=0;G[f+388>>2]=1072693248;break q}G[c+136>>2]=c+288;G[c+132>>2]=c+336;G[c+128>>2]=c+384;r:{if((Qc(d,32047,c+128|0)|0)==3){g=sb(c+384|0);j=sb(c+336|0);q=f,r=vb(c+288|0,c+188|0),L[q+384>>3]=r;d=G[c+188>>2];if(!d){break r}d=E[d|0];if(!d|((d-65>>>0<26?d|32:d)|0)!=97){break r}G[f+428>>2]=1;break r}G[c+116>>2]=c+336;G[c+112>>2]=c+384;if((Qc(d,32249,c+112|0)|0)==2){g=sb(c+384|0);j=sb(c+336|0);G[f+384>>2]=0;G[f+388>>2]=1072693248;break r}G[c+96>>2]=c+192;G[c+92>>2]=c+240;G[c+88>>2]=c+288;G[c+84>>2]=c+336;G[c+80>>2]=c+384;s:{if((Qc(d,31930,c+80|0)|0)==5){g=sb(c+384|0);t:{if(O(g)<2147483648){d=~~g;break t}d=-2147483648}G[f+392>>2]=d;q=f,r=sb(c+336|0),L[q+368>>3]=r;g=sb(c+288|0);u:{if(O(g)<2147483648){d=~~g;break u}d=-2147483648}G[f+396>>2]=d;q=f,r=sb(c+240|0),L[q+376>>3]=r;q=f,r=vb(c+192|0,c+188|0),L[q+384>>3]=r;d=G[c+188>>2];if(!d){break s}d=E[d|0];if(!d|((d-65>>>0<26?d|32:d)|0)!=97){break s}G[f+428>>2]=1;break s}G[c+76>>2]=c+240;G[c+72>>2]=c+288;G[c+68>>2]=c+336;G[c+64>>2]=c+384;if((Qc(d,32151,c- -64|0)|0)==4){g=sb(c+384|0);v:{if(O(g)<2147483648){d=~~g;break v}d=-2147483648}G[f+392>>2]=d;q=f,r=sb(c+336|0),L[q+368>>3]=r;g=sb(c+288|0);w:{if(O(g)<2147483648){d=~~g;break w}d=-2147483648}G[f+396>>2]=d;q=f,r=sb(c+240|0),L[q+376>>3]=r;G[f+384>>2]=0;G[f+388>>2]=1072693248;break s}G[c+56>>2]=c+288;G[c+52>>2]=c+336;G[c+48>>2]=c+384;if((Qc(d,31963,c+48|0)|0)==3){g=sb(c+384|0);x:{if(O(g)<2147483648){d=~~g;break x}d=-2147483648}G[f+392>>2]=d;g=sb(c+336|0);L[f+368>>3]=g;G[f+396>>2]=d;L[f+376>>3]=g;q=f,r=vb(c+288|0,c+188|0),L[q+384>>3]=r;d=G[c+188>>2];if(!d){break s}d=E[d|0];if(!d|((d-65>>>0<26?d|32:d)|0)!=97){break s}G[f+428>>2]=1;break s}G[c+36>>2]=c+336;G[c+32>>2]=c+384;if((Qc(d,32184,c+32|0)|0)==2){g=sb(c+384|0);y:{if(O(g)<2147483648){d=~~g;break y}d=-2147483648}G[f+392>>2]=d;g=sb(c+336|0);L[f+368>>3]=g;G[f+396>>2]=d;L[f+376>>3]=g;G[f+384>>2]=0;G[f+388>>2]=1072693248;break s}G[c+24>>2]=c+288;G[c+20>>2]=c+336;G[c+16>>2]=c+384;z:{if((Qc(d,32098,c+16|0)|0)==3){g=sb(c+384|0);A:{if(O(g)<2147483648){d=~~g;break A}d=-2147483648}G[f+392>>2]=d;G[f+368>>2]=0;G[f+372>>2]=0;g=sb(c+336|0);B:{if(O(g)<2147483648){d=~~g;break B}d=-2147483648}G[f+396>>2]=d;G[f+376>>2]=0;G[f+380>>2]=0;q=f,r=vb(c+288|0,c+188|0),L[q+384>>3]=r;d=G[c+188>>2];if(!d){break z}d=E[d|0];if(!d|((d-65>>>0<26?d|32:d)|0)!=97){break z}G[f+428>>2]=1;break z}G[c+4>>2]=c+336;G[c>>2]=c+384;if((Qc(d,32281,c)|0)!=2){break p}g=sb(c+384|0);C:{if(O(g)<2147483648){d=~~g;break C}d=-2147483648}G[f+392>>2]=d;G[f+368>>2]=0;G[f+372>>2]=0;g=sb(c+336|0);D:{if(O(g)<2147483648){d=~~g;break D}d=-2147483648}G[f+396>>2]=d;G[f+376>>2]=0;G[f+380>>2]=0;G[f+384>>2]=0;G[f+388>>2]=1072693248}o=3;if(l){break p}de(n,2,c+420|0,c+428|0);o=0;if(G[c+428>>2]){break p}L[f+368>>3]=G[c+420>>2]/2|0;L[f+376>>3]=G[c+424>>2]/2|0}o=2;g=L[f+376>>3];l=G[f+396>>2];j=L[f+368>>3];k=+(G[f+392>>2]/2|0);m=j+k;E:{if(O(m)<2147483648){d=~~m;break E}d=-2147483648}G[f+424>>2]=d;j=j-k+1;F:{if(O(j)<2147483648){d=~~j;break F}d=-2147483648}G[f+420>>2]=d;j=+((l|0)/2|0);k=g+j;G:{if(O(k)<2147483648){d=~~k;break G}d=-2147483648}G[f+416>>2]=d;g=g-j+1;H:{if(O(g)<2147483648){d=~~g;break H}d=-2147483648}G[f+412>>2]=d;break p}k=g;m=j}if(O(j)<2147483648){d=~~j}else{d=-2147483648}G[f+424>>2]=d;if(O(g)<2147483648){d=~~g}else{d=-2147483648}G[f+420>>2]=d;if(O(m)<2147483648){d=~~m}else{d=-2147483648}G[f+416>>2]=d;if(O(k)<2147483648){d=~~k}else{d=-2147483648}G[f+412>>2]=d;o=1;G[f+392>>2]=(G[f+424>>2]-G[f+420>>2]|0)+1;G[f+396>>2]=(G[f+416>>2]-G[f+412>>2]|0)+1;L[f+368>>3]=(G[f+420>>2]+G[f+424>>2]|0)/2|0;L[f+376>>3]=(G[f+412>>2]+G[f+416>>2]|0)/2|0}Fa=c+432|0;if(o){break o}}a=G[b>>2];G[f+144>>2]=G[i+16>>2];G[f+148>>2]=a?a:35436;_a(G[24367],76842,f+144|0);h=1;break a}sd(f+364|0,p,f+404|0);b=G[f+404>>2];if(b){a=f+432|0;uc(b,a);G[f+224>>2]=G[i+16>>2];G[f+228>>2]=a;_a(G[24367],77036,f+224|0);h=1;break a}I:{if(!G[f+408>>2]){if(!Kl(n,G[f+364>>2],f+392|0,f+368|0,L[f+384>>3],G[f+428>>2],h,f+404|0)){break I}a=f+432|0;uc(G[f+404>>2],a);G[f+176>>2]=G[i+16>>2];G[f+180>>2]=a;_a(G[24367],76884,f+176|0);h=1;break a}b=0;c=Ij(n,a,e,f+392|0,f+368|0,1,0,f+404|0);d=G[f+404>>2];if(d){a=f+432|0;uc(d,a);G[f+208>>2]=G[i+16>>2];G[f+212>>2]=a;_a(G[24367],76984,f+208|0);h=1;break a}Cb(c,16,41295,f+432|0,0,f+404|0);J:{if(G[f+404>>2]){break J}if(!Sb(f+432|0,32857)){if(!Sb(f+432|0,3703)){break J}}b=f+368|0}G[f+404>>2]=0;if(Kl(c,G[f+364>>2],f+392|0,b,L[f+384>>3],G[f+428>>2],0,f+404|0)){a=f+432|0;uc(G[f+404>>2],a);G[f+192>>2]=G[i+16>>2];G[f+196>>2]=a;_a(G[24367],76884,f+192|0);h=1;break a}G[f+400>>2]=0;_e(c,f+400|0)}b=G[f+404>>2];if(b){a=f+432|0;uc(b,a);G[f+160>>2]=G[i+16>>2];G[f+164>>2]=a;_a(G[24367],76931,f+160|0);_e(G[f+364>>2],f+404|0);h=1;break a}h=0;G[f+400>>2]=0;b=f+400|0;_e(n,b);G[f+400>>2]=0;_e(G[f+364>>2],b);if(!a){break a}Wa(a);break a}if(Xa(a,13568)){break b}if(!e){break a}b=G[936855];if(!b){G[f+256>>2]=a;_a(G[24367],89404,f+256|0);h=1;break a}G[f+288>>2]=G[b+4>>2];a=G[29763];_a(a,69990,f+288|0);b=G[b+16>>2];G[f+272>>2]=b?b:36e3;_a(a,69980,f+272|0);$a(a);break a}if(!Xa(a,4458)){a=G[29763];b=G[936854];if(b){fe(G[b+4>>2],a);c=G[b>>2];if(c){while(1){Ub(32,a);fe(G[c+4>>2],a);c=G[c>>2];if(c){continue}break}}Ub(10,a)}$a(a);break a}if(Xa(a,5451)){break b}b=G[936855];if(!b){G[f+304>>2]=a;_a(G[24367],89404,f+304|0);h=1;break a}Pl(G[b+16>>2],0);$a(G[29763]);break a}if(Xa(a,17450)){break b}if(c){c=G[b>>2];K:{L:{a=Gg(34915,61);if((a|0)!=34915){a=a-34915|0;if(!H[a+34915|0]){break L}}G[48624]=28;break K}e=Va(c);b=ab((e+a|0)+2|0);if(!b){break K}bb(b,34915,a);i=a+b|0;E[i|0]=61;bb(i+1|0,c,e+1|0);Ul(b,a,b)}a=G[29763];if(d){hb(68334,12,1,a)}q=f,s=Fd(34915),G[q+336>>2]=s;_a(a,70017,f+336|0);$a(a);break a}G[f+324>>2]=1;G[f+328>>2]=0;G[f+320>>2]=a;_a(G[24367],88305,f+320|0);h=1;break a}if(Xa(a,24219)){break b}if(!c){G[f+356>>2]=1;G[f+360>>2]=0;G[f+352>>2]=a;_a(G[24367],88305,f+352|0);h=1;break a}Jl(G[b>>2]);break a}G[f>>2]=a;_a(G[24367],89569,f);h=2}Fa=f+4528|0;return h}function bo(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;g=Fa-8144|0;Fa=g;a:{if(G[b>>2]>0){break a}f=G[a>>2];c=G[a+4>>2];if((f|0)!=G[c+76>>2]){mb(a,f+1|0,0,b);c=G[a+4>>2]}G[c+80>>2]=0;f=G[c+44>>2];G[c+104>>2]=G[c+40>>2];G[c+108>>2]=f;G[g+8140>>2]=0;G[g+8136>>2]=G[b>>2];f=a;m=g+8132|0;e=g+8128|0;c=g+8124|0;n=g+112|0;k=g+8112|0;o=g+8108|0;s=g+8120|0;l=g+96|0;q=g+88|0;p=g+104|0;r=g+8116|0;d=Fa-832|0;Fa=d;b:{if(G[b>>2]>0){break b}a=G[f>>2];if((a|0)!=G[G[f+4>>2]+76>>2]){mb(f,a+1|0,0,b)}if(m){G[m>>2]=1}Cf(f,1,d+464|0,d+384|0,d+304|0,b);c:{d:{e:{f:{g:{if(!G[G[f+4>>2]+76>>2]){if(!nb(d+464|0,35530,7)){h:{a=H[d+384|0]-70|0;if(a){if((a|0)==14){break g}break h}if(!m){break g}G[m>>2]=0;break g}e=220;break c}G[d+176>>2]=d+464;a=d+720|0;Ya(a,81,10257,d+176|0);Ua(a);e=221;break c}if(!nb(d+464|0,34516,9)){if((fd(d+384|0,d+224|0,b)|0)>0){Ua(38683);Ua(d+384|0);break b}if(H[d+384|0]==39){if(!nb(d+224|0,35678,6)){break g}if(!nb(d+224|0,35675,9)){break g}}G[d+192>>2]=d+384;a=d+720|0;Ya(a,81,9729,d+192|0);Ua(a);if(!G[G[f+4>>2]+1088>>2]){h=1;break g}tb(3,d+720|0);i:{if(!e){break i}Eg(f,e,b);if(G[b>>2]<=0){break i}Ua(24871);break b}j:{if(!c){break j}Qd(f,c,b);if(G[b>>2]<=0){break j}Ua(24918);break b}i=9;if(!n){break f}nk(f,999,n,b);if(G[b>>2]<=0){break f}Ua(24823);break b}G[d+208>>2]=d+464;a=d+720|0;Ya(a,81,10206,d+208|0);Ua(a);e=225;break c}a=d+464|0;Cf(f,2,a,d+384|0,d+304|0,b);if(nb(a,32941,7)){G[d+160>>2]=d+464;a=d+720|0;Ya(a,81,10146,d+160|0);Ua(a);e=222;break c}if((ue(d+384|0,d+824|0,b)|0)>0){G[d>>2]=d+384;a=d+720|0;Ya(a,81,9481,d);Ua(a);e=211;break c}k:{m=G[d+824>>2];l:{if((m|0)<=7){if((m|0)==-64){break k}if((m|0)!=-32){break l}break k}a=m-8|0;if((m|0)==64|(1<>>0<=24:0)){break k}}G[d+16>>2]=d+384;a=d+720|0;Ya(a,81,10109,d+16|0);Ua(a);e=211;break c}if(e){G[e>>2]=m}no(f,3,33788,d+820|0,b);a=G[b>>2];e=223;if((a|0)==208){break c}e=(a|0)!=209;a=G[d+820>>2];if(!(e&(a|0)<1e3)){G[d+32>>2]=a;a=d+720|0;Ya(a,81,16947,d+32|0);Ua(a);e=212;break c}if(c){G[c>>2]=a}if((a|0)<=0){i=4;break f}a=0;i=4;if(!n){while(1){c=a+1|0;e=d+640|0;zb(33788,c,e,b);th(f,a+4|0,e,d+808|0,b);m:{switch(G[b>>2]-208|0){case 0:break d;case 1:break e;default:break m}}i=i+1|0;a=c;if((a|0)>2]){continue}break f}}while(1){c=a+1|0;e=d+640|0;zb(33788,c,e,b);th(f,a+4|0,e,d+808|0,b);n:{switch(G[b>>2]-208|0){case 0:break d;case 1:break e;default:break n}}if((a|0)<999){e=n+(a<<3)|0;a=G[d+812>>2];G[e>>2]=G[d+808>>2];G[e+4>>2]=a}i=i+1|0;a=c;if((a|0)>2]){continue}break}}if(l){G[l>>2]=0;G[l+4>>2]=1072693248}if(q){G[q>>2]=0;G[q+4>>2]=0}if(k){G[k>>2]=0}if(o){G[o>>2]=1}if(s){G[s>>2]=0}if(p){G[p>>2]=1234554321;G[p+4>>2]=0}G[r>>2]=0;e=G[b>>2];o:{p:{while(1){q:{r:{s:{if((Sd(f,i,d+544|0,b)|0)>0){if(G[b>>2]==203){break q}Ua(47776);break s}a=d+464|0;Fi(d+544|0,a,d+828|0);t:{if((go(a,b)|0)<=0){break t}G[d+148>>2]=d+464;G[d+144>>2]=i;a=d+720|0;Ya(a,81,10301,d+144|0);Ua(a);if((i>>>0)%36|0){break t}Ua(47502)}if(!(nb(d+464|0,35661,7)|!l)){G[r>>2]=0;c=d+384|0;mc(d+544|0,c,d+304|0,b);a=1;if((me(c,l,b)|0)<=0){break r}G[b>>2]=e;G[l>>2]=0;G[l+4>>2]=1072693248;G[d+48>>2]=d+384;c=d+720|0;Ya(c,81,10024,d+48|0);Ua(c);break r}if(!(nb(d+464|0,34377,6)|!q)){G[r>>2]=0;c=d+384|0;mc(d+544|0,c,d+304|0,b);a=1;if((me(c,q,b)|0)<=0){break r}G[b>>2]=e;G[q>>2]=0;G[q+4>>2]=0;G[d+64>>2]=d+384;c=d+720|0;Ya(c,81,9974,d- -64|0);Ua(c);break r}if(!(nb(d+464|0,34862,6)|!p)){G[r>>2]=0;c=d+384|0;mc(d+544|0,c,d+304|0,b);a=1;if((yi(c,p,b)|0)<=0){break r}G[b>>2]=e;G[p>>2]=1234554321;G[p+4>>2]=0;G[d+80>>2]=d+384;c=d+720|0;Ya(c,81,9677,d+80|0);Ua(c);break r}if(!(nb(d+464|0,33303,7)|!k)){G[r>>2]=0;c=d+384|0;mc(d+544|0,c,d+304|0,b);a=1;if((ue(c,k,b)|0)<=0){break r}G[d+96>>2]=d+384;c=d+720|0;Ya(c,81,9571,d+96|0);Ua(c);break r}if(!(nb(d+464|0,33311,7)|!o)){G[r>>2]=0;c=d+384|0;mc(d+544|0,c,d+304|0,b);a=1;if((ue(c,o,b)|0)<=0){break r}G[d+112>>2]=d+384;c=d+720|0;Ya(c,81,9624,d+112|0);Ua(c);break r}if(!(nb(d+464|0,35787,7)|!s)){G[r>>2]=0;mc(d+544|0,d+384|0,d+304|0,b);a=1;c=G[b>>2];if((c|0)<=0){G[s>>2]=H[d+384|0]==84;c=G[b>>2]}if((c|0)<=0){break r}G[b>>2]=e;G[s>>2]=0;G[d+128>>2]=d+384;c=d+720|0;Ya(c,81,9764,d+128|0);Ua(c);break r}a=0;if(G[d+464>>2]==4476485){break r}if(!H[d+544|0]){a=1;G[r>>2]=G[r>>2]+1;break r}G[r>>2]=0}a=1}if(G[b>>2]>0){break p}i=i+1|0;if(a){continue}break o}break}G[b>>2]=e;if((e|0)<=0){break o}}Ua(G[G[f+4>>2]+76>>2]?42900:42841);break b}if(!h){break b}e=233;break c}e=213;break c}e=224}G[b>>2]=e}Fa=d+832|0;a=G[b>>2];u:{if((a|0)==233){G[b>>2]=G[g+8136>>2];break u}if((a|0)>0){break a}}c=G[f+4>>2];a=G[c+120>>2];o=G[c+124>>2];e=M(G[g+8116>>2],80)+80|0;G[c+104>>2]=a-e;G[c+108>>2]=o-((e>>31)+(e>>>0>a>>>0)|0);e=Cu(a-80|0,o-(a>>>0<80)|0);h=(a-e|0)+2800|0;l=o-(Ia+(a>>>0>>0)|0)|0;G[c+128>>2]=h;G[c+132>>2]=h>>>0<2800?l+1|0:l;t=1;v:{if(G[g+112>>2]|G[g+116>>2]|G[g+8124>>2]<=0){break v}G[g+8136>>2]=0;ef(f,2,b);if(!po(f,33752,g+8140|0,g,g+8136|0)){break v}G[g+8140>>2]=0}w:{x:{y:{z:{A:{a=G[g+8128>>2];if((a|0)<=7){if((a|0)==-64){break A}if((a|0)!=-32){break y}t=4;i=42;break w}i=11;B:{switch(a-8|0){case 8:t=2;i=21;break w;case 0:break w;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:break y;case 24:break B;default:break z}}t=4;i=41;break w}t=8;i=82;break w}if((a|0)==64){break x}}i=0;t=0;break w}t=8;i=81}c=G[f+4>>2];u=G[g+8124>>2];G[c+136>>2]=u;C:{if(!u){break C}h=G[g+8140>>2];e=G[g+116>>2];a=G[g+112>>2];G[c+144>>2]=a;G[c+148>>2]=e;v=h?1:a;w=h?0:e;if((u|0)<2){break C}a=u-1|0;d=a&3;D:{if(u-2>>>0<3){a=1;break D}o=a&-4;a=1;x=c+144|0;while(1){n=a<<3;k=g+112|0;e=n+k|0;r=G[e+4>>2];l=G[e>>2];e=n+x|0;G[e>>2]=l;G[e+4>>2]=r;h=n+8|0;e=h+k|0;q=G[e+4>>2];p=G[e>>2];e=h+x|0;G[e>>2]=p;G[e+4>>2]=q;h=n+16|0;e=h+k|0;s=G[e+4>>2];m=G[e>>2];e=h+x|0;G[e>>2]=m;G[e+4>>2]=s;h=n+24|0;e=h+k|0;n=G[e+4>>2];k=G[e>>2];e=h+x|0;G[e>>2]=k;G[e+4>>2]=n;v=Au(k,n,Au(m,s,Au(p,q,Au(v,w,l,r),Ia),Ia),Ia);w=Ia;a=a+4|0;j=j+4|0;if((o|0)!=(j|0)){continue}break}}if(!d){break C}k=0;while(1){e=a<<3;j=e+(g+112|0)|0;o=G[j+4>>2];h=G[j>>2];j=c+e|0;G[j+144>>2]=h;G[j+148>>2]=o;a=a+1|0;v=Au(v,w,h,o);w=Ia;k=k+1|0;if((d|0)!=(k|0)){continue}break}}j=G[c+96>>2]+(G[c+76>>2]<<3)|0;a=G[g+8112>>2];e=a+v|0;h=(a>>31)+w|0;n=Au(t,0,e,a>>>0>e>>>0?h+1|0:h);k=Ia;a=G[g+8108>>2];q=a;p=a>>31;s=Au(n,k,a,p);a=Ia;o=a;e=s+2879|0;a=e>>>0<2879?a+1|0:a;h=e;e=G[c+128>>2];m=h+e|0;l=G[c+132>>2]+a|0;l=e>>>0>m>>>0?l+1|0:l;e=m;a=Cu(h,a);G[j+8>>2]=e-a;G[j+12>>2]=l-(Ia+(a>>>0>e>>>0)|0);G[c+1088>>2]=0;G[c+984>>2]=0;G[c+988>>2]=0;G[c+976>>2]=s;G[c+980>>2]=o;E:{if(!u){G[c+936>>2]=0;G[c+960>>2]=0;G[c+964>>2]=0;if(G[c+1228>>2]){a=0;e=(G[c+1112>>2]-1|0)/G[c+1052>>2]|0;if((e|0)>=0){while(1){j=a<<2;c=G[f+4>>2];b=G[j+G[c+1240>>2]>>2];if(b){Wa(b);c=G[f+4>>2]}b=G[G[c+1244>>2]+j>>2];if(b){Wa(b)}b=(a|0)!=(e|0);a=a+1|0;if(b){continue}break}c=G[f+4>>2]}Wa(G[c+1248>>2]);Wa(G[G[f+4>>2]+1236>>2]);Wa(G[G[f+4>>2]+1232>>2]);Wa(G[G[f+4>>2]+1244>>2]);Wa(G[G[f+4>>2]+1240>>2]);Wa(G[G[f+4>>2]+1228>>2]);c=G[f+4>>2];a=c;G[a+1228>>2]=0;G[a+1232>>2]=0;a=a+1244|0;G[a>>2]=0;G[a+4>>2]=0;a=c+1236|0;G[a>>2]=0;G[a+4>>2]=0}a=G[c+968>>2];if(a){Wa(a);c=G[f+4>>2]}G[c+944>>2]=0;G[c+948>>2]=0;G[c+968>>2]=0;G[c+952>>2]=0;G[c+956>>2]=0;break E}G[c+960>>2]=n;G[c+964>>2]=k;G[c+944>>2]=q;G[c+948>>2]=p;G[c+952>>2]=q;G[c+956>>2]=p;G[c+936>>2]=2;if(G[c+1228>>2]){a=0;h=(G[c+1112>>2]-1|0)/G[c+1052>>2]|0;if((h|0)>=0){while(1){e=a<<2;c=G[f+4>>2];j=G[e+G[c+1240>>2]>>2];if(j){Wa(j);c=G[f+4>>2]}c=G[G[c+1244>>2]+e>>2];if(c){Wa(c)}c=(a|0)!=(h|0);a=a+1|0;if(c){continue}break}c=G[f+4>>2]}Wa(G[c+1248>>2]);Wa(G[G[f+4>>2]+1236>>2]);Wa(G[G[f+4>>2]+1232>>2]);Wa(G[G[f+4>>2]+1244>>2]);Wa(G[G[f+4>>2]+1240>>2]);Wa(G[G[f+4>>2]+1228>>2]);c=G[f+4>>2];a=c;G[a+1228>>2]=0;G[a+1232>>2]=0;a=a+1244|0;G[a>>2]=0;G[a+4>>2]=0;a=c+1236|0;G[a>>2]=0;G[a+4>>2]=0}a=G[c+968>>2];if(a){Wa(a)}e=lb(2,160);if(!e){tb(5,49776);G[G[f+4>>2]+968>>2]=0;G[b>>2]=111;break a}c=G[f+4>>2];G[c+968>>2]=e;G[e+152>>2]=t;G[e+80>>2]=i;G[e+72>>2]=0;G[e+76>>2]=0;a=G[g+8112>>2];G[e+104>>2]=0;G[e+108>>2]=0;G[e+96>>2]=0;G[e+100>>2]=1072693248;G[e+88>>2]=a;G[e+92>>2]=a>>31;j=G[g+104>>2];b=G[g+108>>2];G[e+312>>2]=t;G[e+240>>2]=i;a=M(a,t);G[e+232>>2]=a;G[e+236>>2]=a>>31;G[e+112>>2]=j;G[e+116>>2]=b;G[e+248>>2]=v;G[e+252>>2]=w;L[e+256>>3]=L[g+96>>3];y=L[g+88>>3];G[e+272>>2]=j;G[e+276>>2]=b;L[e+264>>3]=y}b=G[c+96>>2]+(G[c+76>>2]<<3)|0;a=G[b+4>>2];G[c+120>>2]=G[b>>2];G[c+124>>2]=a}Fa=g+8144|0}function Gf(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,I=0,K=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0;q=Fa-29104|0;Fa=q;p=G[o>>2];a:{if(!(g|h)|(p|0)>0){break a}if(n){G[n>>2]=0}if((j|0)==2){cb(m,0,g)}if((yc(a,b,c,d,e,f,g,h,0,q+29096|0,q+29088|0,q+28992|0,q+29064|0,q+29084|0,q+29080|0,q+29040|0,q+29032|0,q+29060|0,q+29048|0,q+29016|0,q+29076|0,q+29024|0,q+28864|0,o)|0)>0){p=G[o>>2];break a}G[q+29060>>2]=M(G[q+29060>>2],i);C=1;c=G[q+29080>>2];d=c>>31;b:{if(G[q+29084>>2]!=16){break b}Gd(q+28992|0,q+29072|0,q+29056|0,q+29068|0,o);e=G[q+29068>>2];if((e|0)<=0){break b}if(e-1>>>0>=7){f=e&-8;p=0;while(1){C=C*10*10*10*10*10*10*10*10;p=p+8|0;if((f|0)!=(p|0)){continue}break}}e=e&7;if(!e){break b}p=0;while(1){C=C*10;p=p+1|0;if((e|0)!=(p|0)){continue}break}}f=G[q+29084>>2];c:{d:{if(k?0:(j|0)==1){break d}e=G[q+29028>>2];p=e;e=G[q+29024>>2];if(!p&(e|0)==1234554321&((f|0)%10|0)==1){break d}if(!((p-(e>>>0<32768)|0)==-1&e-32768>>>0>4294901759|(f|0)!=21)){d=g>>>0<1073741823&(h|0)<=0|(h|0)<0;c=d?g:1073741823;d=d?h:0;break c}if((!p&e>>>0>255|(p|0)!=0)&(f|0)==11){break c}A=(f|0)==16?H[q+28864|0]==1?0:j:j}if((f|0)!=21){break c}d=g>>>0<1073741823&(h|0)<=0|(h|0)<0;c=d?g:1073741823;d=d?h:0}S=i>>31;e=0;f=0;e:{while(1){j=G[q+29044>>2];p=G[q+29040>>2];r=Au(G[q+29016>>2],G[q+29020>>2],K,P);p=p+r|0;j=Ia+j|0;j=p>>>0>>0?j+1|0:j;v=p;r=G[q+29032>>2];t=G[q+29036>>2];y=G[q+29060>>2];p=(y|0)/(i|0)|0;u=Au(r,t,p,p>>31);p=v+u|0;j=Ia+j|0;v=p;u=p>>>0>>0?j+1|0:j;p=r^-1;j=p+G[q+29048>>2]|0;r=G[q+29052>>2]+(t^-1)|0;t=Bu(j,j>>>0

>>0?r+1|0:r,i,S);j=Ia;s=j;p=t+1|0;j=p?j:j+1|0;D=p;p=c>>>0>g>>>0&(d|0)>=(h|0)|(d|0)>(h|0)?g:c;j=p;p=p>>31;r=j;j=j>>>0>t>>>0&(p|0)>=(s|0)|(p|0)>(s|0);t=j?D:r;f:{g:{h:{i:{j:{k:{l:{m:{n:{j=G[q+29084>>2];switch(j-11|0){case 10:break g;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break h;case 5:break i;case 31:break k;case 30:break l;case 0:break m;default:break n}}o:{switch(j-81|0){case 1:break j;case 0:break o;default:break h}}j=y;y=q- -64|0;Tc(a,v,u,t,j,y,o);j=G[q+29024>>2];r=G[q+29028>>2];v=e+m|0;u=(e<<1)+l|0;x=L[q+29096>>3];B=L[q+29088>>3];p=x==1&B==0x8000000000000000;p:{q:{if(!A){r:{s:{if(p){if((t|0)<=0){break p}p=0;if((t|0)!=1){r=t&-2;v=0;while(1){s=u+(p<<1)|0;j=y+(p<<3)|0;w=G[j+4>>2];j=G[j>>2];if((w|0)!=-2147483648|j>>>0>=65536){G[o>>2]=-11;j=65535}F[s>>1]=j;s=p|1;j=y+(s<<3)|0;w=G[j+4>>2];j=G[j>>2];if(!((w|0)==-2147483648&j>>>0<=65535)){G[o>>2]=-11;j=65535}F[u+(s<<1)>>1]=j;p=p+2|0;v=v+2|0;if((r|0)!=(v|0)){continue}break}}if(!(t&1)){break p}j=y+(p<<3)|0;r=G[j+4>>2];j=G[j>>2];if((r|0)!=-2147483648|j>>>0>65535){break s}break r}if(x==1&B==0){break q}p=0;if((t|0)<=0){break p}while(1){r=u+(p<<1)|0;t:{u:{j=y+(p<<3)|0;z=(+J[j>>2]+ +G[j+4>>2]*4294967296)*x+B;if(z<-.49){G[o>>2]=-11;break u}if(z>65535.49){G[o>>2]=-11;j=65535;break t}if(!(z<4294967296&z>=0)){break u}j=~~z>>>0;break t}j=0}F[r>>1]=j;p=p+1|0;if((t|0)!=(p|0)){continue}break}break p}G[o>>2]=-11;j=65535}F[u+(p<<1)>>1]=j;break p}if(p){if((t|0)<=0){break p}p=0;while(1){w=y+(p<<3)|0;s=G[w>>2];w=G[w+4>>2];v:{if((s|0)==(j|0)&(w|0)==(r|0)){G[n>>2]=1;if((A|0)==1){F[u+(p<<1)>>1]=k;break v}E[p+v|0]=1;break v}if((w|0)!=-2147483648|s>>>0>=65536){G[o>>2]=-11;F[u+(p<<1)>>1]=65535;break v}F[u+(p<<1)>>1]=s}p=p+1|0;if((t|0)!=(p|0)){continue}break}break p}if(!(x==1&B==0)){if((t|0)<=0){break p}p=0;while(1){s=y+(p<<3)|0;w=G[s>>2];s=G[s+4>>2];w:{if((w|0)==(j|0)&(s|0)==(r|0)){G[n>>2]=1;if((A|0)==1){F[u+(p<<1)>>1]=k;break w}E[p+v|0]=1;break w}z=(+(w>>>0)+ +(s|0)*4294967296)*x+B;if(z<-.49){G[o>>2]=-11;F[u+(p<<1)>>1]=0;break w}if(z>65535.49){G[o>>2]=-11;F[u+(p<<1)>>1]=65535;break w}D=u+(p<<1)|0;if(z<4294967296&z>=0){s=~~z>>>0}else{s=0}F[D>>1]=s}p=p+1|0;if((t|0)!=(p|0)){continue}break}break p}if((t|0)<=0){break p}p=0;while(1){s=y+(p<<3)|0;w=G[s>>2];s=G[s+4>>2];x:{if((w|0)==(j|0)&(s|0)==(r|0)){G[n>>2]=1;if((A|0)==1){F[u+(p<<1)>>1]=k;break x}E[p+v|0]=1;break x}if((s|0)<0){G[o>>2]=-11;F[u+(p<<1)>>1]=0;break x}if(!s&w>>>0>=65536|s){G[o>>2]=-11;F[u+(p<<1)>>1]=65535;break x}F[u+(p<<1)>>1]=w}p=p+1|0;if((t|0)!=(p|0)){continue}break}break p}if((t|0)<=0){break p}p=0;while(1){v=u+(p<<1)|0;j=y+(p<<3)|0;r=G[j+4>>2];j=G[j>>2];y:{if((r|0)<0){G[o>>2]=-11;j=0;break y}if(!r&j>>>0>=65536|r){G[o>>2]=-11;j=65535}}F[v>>1]=j;p=p+1|0;if((t|0)!=(p|0)){continue}break}}break f}j=q- -64|0;$d(a,v,u,t,y,j,o);Jp(j,t,L[q+29096>>3],L[q+29088>>3],A,H[q+29024|0],k,e+m|0,n,(e<<1)+l|0,o);break f}j=q- -64|0;Uc(a,v,u,t,y,j,o);Vk(j,t,L[q+29096>>3],L[q+29088>>3],A,G[q+29024>>2],k,e+m|0,n,(e<<1)+l|0,o);break f}j=q- -64|0;Uc(a,v,u,t,y,j,o);Ip(j,t,L[q+29096>>3],L[q+29088>>3],A,k,e+m|0,n,(e<<1)+l|0,o);break f}j=q- -64|0;Tc(a,v,u,t,y,j,o);Hp(j,t,L[q+29096>>3],L[q+29088>>3],A,k,e+m|0,n,(e<<1)+l|0,o);break f}Jb(a,v,u,0,o);j=G[q+29060>>2];p=G[q+29064>>2];z:{if((j|0)==(p|0)){j=M(j,t);ic(a,j,j>>31,q- -64|0,o);break z}Rd(a,p,t,j-p|0,q- -64|0,o)}v=q- -64|0;z=L[q+29096>>3];T=L[q+29088>>3];U=G[q+29064>>2];V=e+m|0;I=(e<<1)+l|0;w=0;s=Fa-112|0;Fa=s;N=q+28864|0;W=Va(N);if((t|0)>0){while(1){A:{u=v+U|0;Q=H[u|0];E[u|0]=0;j=v;B:{C:{if(H[N|0]==1){break C}if(fb(N,v,W)){break C}j=u;if(!A){break B}G[n>>2]=1;if((A|0)==1){F[(w<<1)+I>>1]=k;break B}E[w+V|0]=1;break B}while(1){r=H[j|0];if((r|0)==32){j=j+1|0;continue}break}R=1;D:{switch(r-43|0){case 0:case 2:while(1){p=H[j+1|0];j=j+1|0;if((p|0)==32){continue}break};R=(r|0)==45?-1:1;r=p;break;default:break D}}B=0;if((r-48&255)>>>0<10){while(1){x=B*10+ +(r<<24>>24);p=j;while(1){r=H[p+1|0];j=p+1|0;p=j;if((r|0)==32){continue}break}B=x+-48;if((r-48&255)>>>0<=9){continue}break}}x=C;E:{F:{switch(r-44|0){case 0:case 2:break F;default:break E}}p=j;while(1){r=H[p+1|0];j=p+1|0;p=j;if((r|0)==32){continue}break}x=1;if((r-48&255)>>>0>=10){break E}while(1){B=B*10+ +(r<<24>>24)+-48;p=j;while(1){r=H[p+1|0];j=p+1|0;p=j;if((r|0)==32){continue}break}x=x*10;if((r-48&255)>>>0<=9){continue}break}}G:{if((r&254)!=68){O=1;p=0;break G}while(1){O=1;p=j;j=p+1|0;r=H[p+1|0];if((r|0)==32){continue}break}H:{switch(r-43|0){case 0:case 2:p=p+2|0;while(1){j=p;p=p+1|0;y=H[j|0];if((y|0)==32){continue}break};O=(r|0)==45?-1:1;r=y;break;default:break H}}p=0;if((r-48&255)>>>0>=10){break G}while(1){y=r;D=M(p,10)-48|0;p=j;while(1){r=H[p+1|0];j=p+1|0;p=j;if((r|0)==32){continue}break}p=(y<<24>>24)+D|0;if((r-48&255)>>>0<=9){continue}break}}if(r){G[s+48>>2]=H[23477]|H[23478]<<8|(H[23479]<<16|H[23480]<<24);j=H[23473]|H[23474]<<8|(H[23475]<<16|H[23476]<<24);G[s+40>>2]=H[23469]|H[23470]<<8|(H[23471]<<16|H[23472]<<24);G[s+44>>2]=j;j=H[23465]|H[23466]<<8|(H[23467]<<16|H[23468]<<24);G[s+32>>2]=H[23461]|H[23462]<<8|(H[23463]<<16|H[23464]<<24);G[s+36>>2]=j;j=H[23457]|H[23458]<<8|(H[23459]<<16|H[23460]<<24);G[s+24>>2]=H[23453]|H[23454]<<8|(H[23455]<<16|H[23456]<<24);G[s+28>>2]=j;j=H[23449]|H[23450]<<8|(H[23451]<<16|H[23452]<<24);G[s+16>>2]=H[23445]|H[23446]<<8|(H[23447]<<16|H[23448]<<24);G[s+20>>2]=j;j=s+16|0;Ua(j);G[s>>2]=v;Ya(j,81,43022,s);Ua(j);E[u|0]=Q;G[o>>2]=409;break A}x=B*+(R|0)/x*$b(10,+(M(p,O)|0))*z+T;I:{if(x<-.49){G[o>>2]=-11;F[(w<<1)+I>>1]=0;break I}if(x>65535.49){G[o>>2]=-11;F[(w<<1)+I>>1]=65535;break I}p=(w<<1)+I|0;if(x<4294967296&x>=0){r=~~x>>>0}else{r=0}F[p>>1]=r}}v=j;E[u|0]=Q;w=w+1|0;if((t|0)!=(w|0)){continue}}break}}Fa=s+112|0;break f}G[q>>2]=b;G[q+4>>2]=q+28992;a=q+28896|0;Ya(a,81,8924,q);Ua(a);p=311;if(G[q+29076>>2]==1){break e}p=312;break e}j=(e<<1)+l|0;Pe(a,v,u,t,y,j,o);Gp(j,t,L[q+29096>>3],L[q+29088>>3],A,F[q+29024>>1],k,e+m|0,n,j,o)}p=G[o>>2];if((p|0)>0){x=+(e>>>0)+ +(f|0)*4294967296;C=x+1;x=x+ +(t|0);J:{if(G[q+29076>>2]>0){G[q+32>>2]=b;L[q+24>>3]=x;L[q+16>>3]=C;Ya(q+28896|0,81,46949,q+16|0);break J}L[q+56>>3]=x;L[q+48>>3]=C;Ya(q+28896|0,81,46889,q+48|0)}Ua(q+28896|0);p=G[o>>2];break a}j=t;r=j>>31;u=r;h=h-(r+(g>>>0>>0)|0)|0;g=g-j|0;if(h|g){p=M(i,t);v=p;r=p+G[q+29032>>2]|0;p=G[q+29036>>2]+(p>>31)|0;p=r>>>0>>0?p+1|0:p;G[q+29032>>2]=r;G[q+29036>>2]=p;f=f+u|0;e=e+j|0;f=e>>>0>>0?f+1|0:f;j=G[q+29048>>2];u=G[q+29052>>2];if(j>>>0>r>>>0&(u|0)>=(p|0)|(p|0)<(u|0)){continue}v=Bu(r,p,j,u);t=Ia;j=Au(v,t,j,u);G[q+29032>>2]=r-j;G[q+29036>>2]=p-(Ia+(j>>>0>r>>>0)|0);r=t+P|0;j=v+K|0;r=j>>>0>>0?r+1|0:r;K=j;P=r;continue}break}if((p|0)!=-11){break a}Ua(44994);p=412}G[o>>2]=p}Fa=q+29104|0;return p}function xe(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;l=Fa-29104|0;Fa=l;k=G[j>>2];a:{if((k|0)>0){break a}b:{c:{if((yc(a,b,c,d,e,f,g,h,1,l+29032|0,l+29024|0,l+28992|0,l+29088|0,l+29100|0,l+29096|0,l+29064|0,l+29056|0,l+29084|0,l+29072|0,l+29048|0,l+29092|0,l+29040|0,l+28832|0,j)|0)>0){break c}c=G[l+29096>>2];v=c;w=c>>31;if(G[l+29100>>2]==16){Ne(l+28992|0,l+28960|0)}if(!(g|h)){k=G[j>>2];break b}e=0;f=0;while(1){p=G[l+29072>>2];k=G[l+29076>>2];c=G[l+29068>>2];d=G[l+29064>>2];m=Au(G[l+29048>>2],G[l+29052>>2],x,y);d=d+m|0;c=Ia+c|0;c=d>>>0>>0?c+1|0:c;r=d;m=G[l+29056>>2];o=G[l+29060>>2];d=G[l+29084>>2];q=Au(m,o,d,d>>31);d=r+q|0;c=Ia+c|0;Jb(a,d,d>>>0>>0?c+1|0:c,1,j);d=g>>>0>>0&(h|0)<=(w|0)|(h|0)<(w|0)?g:v;c=d>>31;q=d;d=k-((m>>>0>p>>>0)+o|0)|0;p=p-m|0;m=p;p=(c|0)<=(d|0)&p>>>0>q>>>0|(c|0)<(d|0);m=p?q:m;d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{p:{c=G[l+29100>>2];switch(c-11|0){case 0:break h;case 10:break i;case 31:break j;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break m;case 5:break n;case 30:break o;default:break p}}switch(c-81|0){case 0:break g;case 1:break k;default:break m}}d=(e<<2)+i|0;s=L[l+29032>>3];u=L[l+29024>>3];if(s==1&u==0){break f}k=0;if((m|0)<=0){break e}while(1){q:{r:{o=k<<2;n=(+G[o+d>>2]-u)/s;if(n<-2147483648.49){G[j>>2]=-11;break r}if(n>2147483647.49){G[j>>2]=-11;c=2147483647;break q}if(n>=0){n=n+.5;if(!(O(n)<2147483648)){break r}c=~~n;break q}n=n+-.5;if(!(O(n)<2147483648)){break r}c=~~n;break q}c=-2147483648}G[o+(l+32|0)>>2]=c;k=k+1|0;if((m|0)!=(k|0)){continue}break}break e}if(H[l+28961|0]==115){break m}q=(e<<2)+i|0;r=l+28960|0;p=G[l+29088>>2];d=l+32|0;o=0;k=Fa-32|0;Fa=k;n=L[l+29032>>3];s=L[l+29024>>3];s:{if(!(n==1&s==0)){if((m|0)<=0){break s}c=d;while(1){L[k+16>>3]=(+G[q+(o<<2)>>2]-s)/n;Eb(c,r,k+16|0);c=c+p|0;if(H[c|0]){G[j>>2]=-11}o=o+1|0;if((o|0)!=(m|0)){continue}break}break s}if((m|0)<=0){break s}c=d;while(1){L[k>>3]=G[q+(o<<2)>>2];Eb(c,r,k);c=c+p|0;if(H[c|0]){G[j>>2]=-11}o=o+1|0;if((o|0)!=(m|0)){continue}break}}o=jb(d,44);if(o){while(1){E[o|0]=46;o=jb(o,44);if(o){continue}break}}Fa=k+32|0;c=G[l+29084>>2];d=G[l+29088>>2];if((c|0)!=(d|0)){break l}c=M(c,m);Wb(a,c,c>>31,l+32|0,j);break d}G[l>>2]=b;G[l+4>>2]=l+28992;a=l+28864|0;Ya(a,81,8813,l);Ua(a);if(G[l+29092>>2]==1){k=311;G[j>>2]=311;break a}k=312;G[j>>2]=312;break a}wd(a,d,m,c-d|0,l+32|0,j);break d}c=(e<<2)+i|0;n=L[l+29032>>3];s=L[l+29024>>3];t:{if(!(n==1&s==0)){if((m|0)<=0){break t}k=0;if((m|0)!=1){o=m&-2;d=0;while(1){q=l+32|0;L[q+(k<<3)>>3]=(+G[c+(k<<2)>>2]-s)/n;r=k|1;L[q+(r<<3)>>3]=(+G[c+(r<<2)>>2]-s)/n;k=k+2|0;d=d+2|0;if((o|0)!=(d|0)){continue}break}}if(!(m&1)){break t}L[(l+32|0)+(k<<3)>>3]=(+G[c+(k<<2)>>2]-s)/n;break t}if((m|0)<=0){break t}d=0;k=0;if(m-1>>>0>=3){r=m&-4;o=0;while(1){q=l+32|0;L[q+(k<<3)>>3]=G[c+(k<<2)>>2];p=k|1;L[q+(p<<3)>>3]=G[c+(p<<2)>>2];p=k|2;L[q+(p<<3)>>3]=G[c+(p<<2)>>2];p=k|3;L[q+(p<<3)>>3]=G[c+(p<<2)>>2];k=k+4|0;o=o+4|0;if((r|0)!=(o|0)){continue}break}}o=m&3;if(!o){break t}while(1){L[(l+32|0)+(k<<3)>>3]=G[c+(k<<2)>>2];k=k+1|0;d=d+1|0;if((o|0)!=(d|0)){continue}break}}_c(a,m,G[l+29084>>2],l+32|0,j);break d}c=(e<<2)+i|0;n=L[l+29032>>3];s=L[l+29024>>3];u:{if(!(n==1&s==0)){if((m|0)<=0){break u}d=0;if((m|0)!=1){q=m&-2;o=0;while(1){k=d<<2;r=l+32|0;K[k+r>>2]=(+G[c+k>>2]-s)/n;k=k|4;K[k+r>>2]=(+G[c+k>>2]-s)/n;d=d+2|0;o=o+2|0;if((q|0)!=(o|0)){continue}break}}if(!(m&1)){break u}d=d<<2;K[d+(l+32|0)>>2]=(+G[c+d>>2]-s)/n;break u}if((m|0)<=0){break u}o=0;d=0;if(m-1>>>0>=3){p=m&-4;r=0;while(1){k=d<<2;q=l+32|0;K[k+q>>2]=G[c+k>>2];t=k|4;K[t+q>>2]=G[c+t>>2];t=k|8;K[t+q>>2]=G[c+t>>2];k=k|12;K[k+q>>2]=G[c+k>>2];d=d+4|0;r=r+4|0;if((p|0)!=(r|0)){continue}break}}k=m&3;if(!k){break u}while(1){q=d<<2;K[q+(l+32|0)>>2]=G[c+q>>2];d=d+1|0;o=o+1|0;if((k|0)!=(o|0)){continue}break}}$c(a,m,G[l+29084>>2],l+32|0,j);break d}q=(e<<2)+i|0;s=L[l+29032>>3];u=L[l+29024>>3];v:{if(!(s==1&u==0)){k=0;if((m|0)<=0){break v}while(1){d=(l+32|0)+(k<<1)|0;n=(+G[q+(k<<2)>>2]-u)/s;w:{if(n<-32768.49){G[j>>2]=-11;c=32768;break w}if(n>32767.49){G[j>>2]=-11;c=32767;break w}x:{if(n>=0){n=n+.5;if(!(O(n)<2147483648)){break x}c=~~n;break w}n=n+-.5;if(!(O(n)<2147483648)){break x}c=~~n;break w}c=-2147483648}F[d>>1]=c;k=k+1|0;if((m|0)!=(k|0)){continue}break}break v}if((m|0)<=0){break v}k=0;if((m|0)!=1){c=m&-2;o=0;while(1){d=G[q+(k<<2)>>2];y:{if((d|0)<=-32769){G[j>>2]=-11;d=32768;break y}if((d|0)<32768){break y}G[j>>2]=-11;d=32767}F[(l+32|0)+(k<<1)>>1]=d;r=k|1;d=G[q+(r<<2)>>2];z:{if((d|0)>=-32768){if((d|0)<=32767){break z}G[j>>2]=-11;d=32767;break z}G[j>>2]=-11;d=32768}F[(l+32|0)+(r<<1)>>1]=d;k=k+2|0;o=o+2|0;if((c|0)!=(o|0)){continue}break}}if(!(m&1)){break v}d=G[q+(k<<2)>>2];A:{if((d|0)>=-32768){if((d|0)<=32767){break A}G[j>>2]=-11;d=32767;break A}G[j>>2]=-11;d=32768}F[(l+32|0)+(k<<1)>>1]=d}Oe(a,m,G[l+29084>>2],l+32|0,j);break d}c=(e<<2)+i|0;s=L[l+29032>>3];u=L[l+29024>>3];B:{if(!(s==1&u==0)){k=0;if((m|0)<=0){break B}while(1){p=(l+32|0)+k|0;C:{D:{n=(+G[c+(k<<2)>>2]-u)/s;if(n<-.49){G[j>>2]=-11;break D}if(n>255.49){G[j>>2]=-11;d=255;break C}n=n+.5;if(!(n<4294967296&n>=0)){break D}d=~~n>>>0;break C}d=0}E[p|0]=d;k=k+1|0;if((m|0)!=(k|0)){continue}break}break B}if((m|0)<=0){break B}k=0;if((m|0)!=1){q=m&-2;o=0;while(1){d=G[c+(k<<2)>>2];E:{if((d|0)<0){G[j>>2]=-11;d=0;break E}if(d>>>0<256){break E}G[j>>2]=-11;d=255}E[(l+32|0)+k|0]=d;r=k|1;d=G[c+(r<<2)>>2];F:{if((d|0)>=0){if(d>>>0<=255){break F}G[j>>2]=-11;d=255;break F}G[j>>2]=-11;d=0}E[r+(l+32|0)|0]=d;k=k+2|0;o=o+2|0;if((q|0)!=(o|0)){continue}break}}if(!(m&1)){break B}d=G[c+(k<<2)>>2];G:{if((d|0)>=0){if(d>>>0<=255){break G}G[j>>2]=-11;d=255;break G}G[j>>2]=-11;d=0}E[(l+32|0)+k|0]=d}we(a,m,G[l+29084>>2],l+32|0,j);break d}q=(e<<2)+i|0;H:{I:{J:{K:{u=L[l+29032>>3];c=u!=1;s=L[l+29024>>3];if(!(c|s!=0x8000000000000000)){if((m|0)<=0){break H}k=0;if((m|0)!=1){r=m&-2;d=0;while(1){o=(l+32|0)+(k<<3)|0;c=G[q+(k<<2)>>2];if((c|0)<0){G[j>>2]=-11;c=0}G[o>>2]=c;G[o+4>>2]=-2147483648;o=k|1;c=G[q+(o<<2)>>2];if((c|0)<0){G[j>>2]=-11;c=0}o=(l+32|0)+(o<<3)|0;G[o>>2]=c;G[o+4>>2]=-2147483648;k=k+2|0;d=d+2|0;if((r|0)!=(d|0)){continue}break}}if(!(m&1)){break H}c=G[q+(k<<2)>>2];if((c|0)<0){break K}break J}if(!c&s==0){break I}k=0;if((m|0)<=0){break H}while(1){o=(l+32|0)+(k<<3)|0;L:{M:{n=(+G[q+(k<<2)>>2]-s)/u;if(n<-0x8000000000000000){G[j>>2]=-11;break M}if(n>0x8000000000000000){G[j>>2]=-11;d=2147483647;c=-1;break L}if(n>=0){n=n+.5;if(!(O(n)<0x8000000000000000)){break M}d=O(n)>=1?~~(n>0?Q(S(n*2.3283064365386963e-10),4294967295):T((n-+(~~n>>>0>>>0))*2.3283064365386963e-10))>>>0:0;c=~~n>>>0;break L}n=n+-.5;if(!(O(n)<0x8000000000000000)){break M}d=O(n)>=1?~~(n>0?Q(S(n*2.3283064365386963e-10),4294967295):T((n-+(~~n>>>0>>>0))*2.3283064365386963e-10))>>>0:0;c=~~n>>>0;break L}d=-2147483648;c=0}G[o>>2]=c;G[o+4>>2]=d;k=k+1|0;if((m|0)!=(k|0)){continue}break}break H}G[j>>2]=-11;c=0}d=(l+32|0)+(k<<3)|0;G[d>>2]=c;G[d+4>>2]=-2147483648;break H}if((m|0)<=0){break H}d=0;k=0;if(m-1>>>0>=3){r=m&-4;o=0;while(1){c=l+32|0;p=c+(k<<3)|0;t=G[q+(k<<2)>>2];G[p>>2]=t;G[p+4>>2]=t>>31;p=k|1;t=c+(p<<3)|0;p=G[q+(p<<2)>>2];G[t>>2]=p;G[t+4>>2]=p>>31;p=k|2;t=c+(p<<3)|0;p=G[q+(p<<2)>>2];G[t>>2]=p;G[t+4>>2]=p>>31;p=k|3;c=c+(p<<3)|0;p=G[q+(p<<2)>>2];G[c>>2]=p;G[c+4>>2]=p>>31;k=k+4|0;o=o+4|0;if((r|0)!=(o|0)){continue}break}}c=m&3;if(!c){break H}while(1){o=(l+32|0)+(k<<3)|0;r=G[q+(k<<2)>>2];G[o>>2]=r;G[o+4>>2]=r>>31;k=k+1|0;d=d+1|0;if((c|0)!=(d|0)){continue}break}}_c(a,m,G[l+29084>>2],l+32|0,j);break d}if((m|0)<=0){break e}bb(l+32|0,d,m<<2)}$c(a,m,G[l+29084>>2],l+32|0,j)}k=G[j>>2];if((k|0)>0){c=f;a=e+1|0;c=a?c:c+1|0;L[l+16>>3]=+(a>>>0)+ +(c|0)*4294967296;c=m;d=c>>31;a=c+e|0;c=d+f|0;L[l+24>>3]=+(a>>>0)+ +((a>>>0>>0?c+1|0:c)|0)*4294967296;a=l+28864|0;Ya(a,81,46630,l+16|0);Ua(a);break c}c=m;d=c>>31;p=c;h=h-((g>>>0>>0)+d|0)|0;g=g-c|0;if(!(h|g)){break b}c=d+f|0;m=e+p|0;c=m>>>0>>0?c+1|0:c;e=m;f=c;c=d+G[l+29060>>2]|0;m=p+G[l+29056>>2]|0;c=m>>>0

>>0?c+1|0:c;G[l+29056>>2]=m;G[l+29060>>2]=c;if(G[l+29072>>2]!=(m|0)|G[l+29076>>2]!=(c|0)){continue}G[l+29056>>2]=0;G[l+29060>>2]=0;c=y;d=x+1|0;c=d?c:c+1|0;x=d;y=c;continue}}k=G[j>>2];break a}if((k|0)!=-11){break a}Ua(44927);k=412;G[j>>2]=412}Fa=l+29104|0;return k}function Ng(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;l=Fa-29104|0;Fa=l;k=G[j>>2];a:{if((k|0)>0){break a}b:{c:{if((yc(a,b,c,d,e,f,g,h,1,l+29032|0,l+29024|0,l+28992|0,l+29088|0,l+29100|0,l+29096|0,l+29064|0,l+29056|0,l+29084|0,l+29072|0,l+29048|0,l+29092|0,l+29040|0,l+28832|0,j)|0)>0){break c}c=G[l+29096>>2];v=c;w=c>>31;if(G[l+29100>>2]==16){Ne(l+28992|0,l+28960|0)}if(!(g|h)){k=G[j>>2];break b}e=0;f=0;while(1){n=G[l+29072>>2];k=G[l+29076>>2];c=G[l+29068>>2];d=G[l+29064>>2];m=Au(G[l+29048>>2],G[l+29052>>2],x,y);d=d+m|0;c=Ia+c|0;c=d>>>0>>0?c+1|0:c;s=d;m=G[l+29056>>2];q=G[l+29060>>2];d=G[l+29084>>2];p=Au(m,q,d,d>>31);d=s+p|0;c=Ia+c|0;Jb(a,d,d>>>0

>>0?c+1|0:c,1,j);d=g>>>0>>0&(h|0)<=(w|0)|(h|0)<(w|0)?g:v;c=d>>31;p=d;d=k-((m>>>0>n>>>0)+q|0)|0;n=n-m|0;m=n;n=(c|0)<=(d|0)&n>>>0>p>>>0|(c|0)<(d|0);m=n?p:m;d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{p:{q:{r:{s:{t:{c=G[l+29100>>2];switch(c-11|0){case 0:break j;case 30:break k;case 31:break l;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break o;case 5:break p;case 10:break s;default:break t}}switch(c-81|0){case 1:break m;case 0:break r;default:break o}}d=(e<<1)+i|0;r=L[l+29032>>3];t=L[l+29024>>3];if(r==1&t==0){break q}k=0;if((m|0)<=0){break e}while(1){q=k<<1;o=(+F[q+d>>1]-t)/r;u:{if(o<-32768.49){G[j>>2]=-11;c=32768;break u}if(o>32767.49){G[j>>2]=-11;c=32767;break u}v:{if(o>=0){o=o+.5;if(!(O(o)<2147483648)){break v}c=~~o;break u}o=o+-.5;if(!(O(o)<2147483648)){break v}c=~~o;break u}c=-2147483648}F[q+(l+32|0)>>1]=c;k=k+1|0;if((m|0)!=(k|0)){continue}break}break e}q=(e<<1)+i|0;t=L[l+29032>>3];c=t!=1;r=L[l+29024>>3];if(!(c|r!=0x8000000000000000)){if((m|0)<=0){break f}k=0;if((m|0)!=1){s=m&-2;c=0;while(1){d=(l+32|0)+(k<<3)|0;p=F[q+(k<<1)>>1];w:{if((p|0)<0){G[j>>2]=-11;p=0;break w}p=p&65535}G[d>>2]=p;G[d+4>>2]=-2147483648;p=k|1;d=F[q+(p<<1)>>1];x:{if((d|0)>=0){d=d&65535;break x}G[j>>2]=-11;d=0}p=(l+32|0)+(p<<3)|0;G[p>>2]=d;G[p+4>>2]=-2147483648;k=k+2|0;c=c+2|0;if((s|0)!=(c|0)){continue}break}}if(!(m&1)){break f}c=F[q+(k<<1)>>1];if((c|0)<0){break i}c=c&65535;break h}if(!c&r==0){break g}k=0;if((m|0)<=0){break f}while(1){p=(l+32|0)+(k<<3)|0;y:{z:{o=(+F[q+(k<<1)>>1]-r)/t;if(o<-0x8000000000000000){G[j>>2]=-11;break z}if(o>0x8000000000000000){G[j>>2]=-11;d=2147483647;c=-1;break y}if(o>=0){o=o+.5;if(!(O(o)<0x8000000000000000)){break z}d=O(o)>=1?~~(o>0?Q(S(o*2.3283064365386963e-10),4294967295):T((o-+(~~o>>>0>>>0))*2.3283064365386963e-10))>>>0:0;c=~~o>>>0;break y}o=o+-.5;if(!(O(o)<0x8000000000000000)){break z}d=O(o)>=1?~~(o>0?Q(S(o*2.3283064365386963e-10),4294967295):T((o-+(~~o>>>0>>>0))*2.3283064365386963e-10))>>>0:0;c=~~o>>>0;break y}d=-2147483648;c=0}G[p>>2]=c;G[p+4>>2]=d;k=k+1|0;if((m|0)!=(k|0)){continue}break}break f}bb(l+32|0,d,m<<1);break e}if(H[l+28961|0]==115){break o}p=(e<<1)+i|0;s=l+28960|0;n=G[l+29088>>2];d=l+32|0;k=0;q=Fa-32|0;Fa=q;o=L[l+29032>>3];r=L[l+29024>>3];A:{if(!(o==1&r==0)){if((m|0)<=0){break A}c=d;while(1){L[q+16>>3]=(+F[p+(k<<1)>>1]-r)/o;Eb(c,s,q+16|0);c=c+n|0;if(H[c|0]){G[j>>2]=-11}k=k+1|0;if((m|0)!=(k|0)){continue}break}break A}if((m|0)<=0){break A}c=d;while(1){L[q>>3]=F[p+(k<<1)>>1];Eb(c,s,q);c=c+n|0;if(H[c|0]){G[j>>2]=-11}k=k+1|0;if((m|0)!=(k|0)){continue}break}}k=jb(d,44);if(k){while(1){E[k|0]=46;k=jb(k,44);if(k){continue}break}}Fa=q+32|0;c=G[l+29084>>2];d=G[l+29088>>2];if((c|0)!=(d|0)){break n}c=M(c,m);Wb(a,c,c>>31,l+32|0,j);break d}G[l>>2]=b;G[l+4>>2]=l+28992;a=l+28864|0;Ya(a,81,8813,l);Ua(a);if(G[l+29092>>2]==1){k=311;G[j>>2]=311;break a}k=312;G[j>>2]=312;break a}wd(a,d,m,c-d|0,l+32|0,j);break d}q=(e<<1)+i|0;o=L[l+29032>>3];r=L[l+29024>>3];B:{if(!(o==1&r==0)){if((m|0)<=0){break B}k=0;if((m|0)!=1){d=m&-2;c=0;while(1){p=l+32|0;L[p+(k<<3)>>3]=(+F[q+(k<<1)>>1]-r)/o;n=p;p=k|1;L[n+(p<<3)>>3]=(+F[q+(p<<1)>>1]-r)/o;k=k+2|0;c=c+2|0;if((d|0)!=(c|0)){continue}break}}if(!(m&1)){break B}L[(l+32|0)+(k<<3)>>3]=(+F[q+(k<<1)>>1]-r)/o;break B}if((m|0)<=0){break B}c=0;k=0;if(m-1>>>0>=3){s=m&-4;d=0;while(1){p=l+32|0;L[p+(k<<3)>>3]=F[q+(k<<1)>>1];n=k|1;L[p+(n<<3)>>3]=F[q+(n<<1)>>1];n=k|2;L[p+(n<<3)>>3]=F[q+(n<<1)>>1];n=k|3;L[p+(n<<3)>>3]=F[q+(n<<1)>>1];k=k+4|0;d=d+4|0;if((s|0)!=(d|0)){continue}break}}d=m&3;if(!d){break B}while(1){L[(l+32|0)+(k<<3)>>3]=F[q+(k<<1)>>1];k=k+1|0;c=c+1|0;if((d|0)!=(c|0)){continue}break}}_c(a,m,G[l+29084>>2],l+32|0,j);break d}q=(e<<1)+i|0;o=L[l+29032>>3];r=L[l+29024>>3];C:{if(!(o==1&r==0)){if((m|0)<=0){break C}k=0;if((m|0)!=1){d=m&-2;c=0;while(1){p=l+32|0;K[p+(k<<2)>>2]=(+F[q+(k<<1)>>1]-r)/o;n=p;p=k|1;K[n+(p<<2)>>2]=(+F[q+(p<<1)>>1]-r)/o;k=k+2|0;c=c+2|0;if((d|0)!=(c|0)){continue}break}}if(!(m&1)){break C}K[(l+32|0)+(k<<2)>>2]=(+F[q+(k<<1)>>1]-r)/o;break C}if((m|0)<=0){break C}c=0;k=0;if(m-1>>>0>=3){s=m&-4;d=0;while(1){p=l+32|0;K[p+(k<<2)>>2]=F[q+(k<<1)>>1];n=k|1;K[p+(n<<2)>>2]=F[q+(n<<1)>>1];n=k|2;K[p+(n<<2)>>2]=F[q+(n<<1)>>1];n=k|3;K[p+(n<<2)>>2]=F[q+(n<<1)>>1];k=k+4|0;d=d+4|0;if((s|0)!=(d|0)){continue}break}}d=m&3;if(!d){break C}while(1){K[(l+32|0)+(k<<2)>>2]=F[q+(k<<1)>>1];k=k+1|0;c=c+1|0;if((d|0)!=(c|0)){continue}break}}$c(a,m,G[l+29084>>2],l+32|0,j);break d}q=(e<<1)+i|0;r=L[l+29032>>3];t=L[l+29024>>3];D:{if(!(r==1&t==0)){k=0;if((m|0)<=0){break D}while(1){d=(l+32|0)+(k<<2)|0;E:{F:{o=(+F[q+(k<<1)>>1]-t)/r;if(o<-2147483648.49){G[j>>2]=-11;break F}if(o>2147483647.49){G[j>>2]=-11;c=2147483647;break E}if(o>=0){o=o+.5;if(!(O(o)<2147483648)){break F}c=~~o;break E}o=o+-.5;if(!(O(o)<2147483648)){break F}c=~~o;break E}c=-2147483648}G[d>>2]=c;k=k+1|0;if((m|0)!=(k|0)){continue}break}break D}if((m|0)<=0){break D}c=0;k=0;if(m-1>>>0>=3){s=m&-4;d=0;while(1){p=l+32|0;G[p+(k<<2)>>2]=F[q+(k<<1)>>1];n=k|1;G[p+(n<<2)>>2]=F[q+(n<<1)>>1];n=k|2;G[p+(n<<2)>>2]=F[q+(n<<1)>>1];n=k|3;G[p+(n<<2)>>2]=F[q+(n<<1)>>1];k=k+4|0;d=d+4|0;if((s|0)!=(d|0)){continue}break}}d=m&3;if(!d){break D}while(1){G[(l+32|0)+(k<<2)>>2]=F[q+(k<<1)>>1];k=k+1|0;c=c+1|0;if((d|0)!=(c|0)){continue}break}}$c(a,m,G[l+29084>>2],l+32|0,j);break d}q=(e<<1)+i|0;r=L[l+29032>>3];t=L[l+29024>>3];G:{if(!(r==1&t==0)){k=0;if((m|0)<=0){break G}while(1){d=(l+32|0)+k|0;H:{I:{o=(+F[q+(k<<1)>>1]-t)/r;if(o<-.49){G[j>>2]=-11;break I}if(o>255.49){G[j>>2]=-11;c=255;break H}o=o+.5;if(!(o<4294967296&o>=0)){break I}c=~~o>>>0;break H}c=0}E[d|0]=c;k=k+1|0;if((m|0)!=(k|0)){continue}break}break G}if((m|0)<=0){break G}k=0;if((m|0)!=1){p=m&-2;d=0;while(1){c=F[q+(k<<1)>>1];J:{if((c|0)<0){G[j>>2]=-11;c=0;break J}if(c>>>0<256){break J}G[j>>2]=-11;c=255}E[(l+32|0)+k|0]=c;s=k|1;c=F[q+(s<<1)>>1];K:{if((c|0)>=0){if(c>>>0<=255){break K}G[j>>2]=-11;c=255;break K}G[j>>2]=-11;c=0}E[s+(l+32|0)|0]=c;k=k+2|0;d=d+2|0;if((p|0)!=(d|0)){continue}break}}if(!(m&1)){break G}c=F[q+(k<<1)>>1];L:{if((c|0)>=0){if(c>>>0<=255){break L}G[j>>2]=-11;c=255;break L}G[j>>2]=-11;c=0}E[(l+32|0)+k|0]=c}we(a,m,G[l+29084>>2],l+32|0,j);break d}G[j>>2]=-11;c=0}d=(l+32|0)+(k<<3)|0;G[d>>2]=c;G[d+4>>2]=-2147483648;break f}if((m|0)<=0){break f}c=0;k=0;if(m-1>>>0>=3){s=m&-4;d=0;while(1){p=l+32|0;n=p+(k<<3)|0;u=F[q+(k<<1)>>1];G[n>>2]=u;G[n+4>>2]=u>>31;n=k|1;u=p+(n<<3)|0;n=F[q+(n<<1)>>1];G[u>>2]=n;G[u+4>>2]=n>>31;n=k|2;u=p+(n<<3)|0;n=F[q+(n<<1)>>1];G[u>>2]=n;G[u+4>>2]=n>>31;n=k|3;p=p+(n<<3)|0;n=F[q+(n<<1)>>1];G[p>>2]=n;G[p+4>>2]=n>>31;k=k+4|0;d=d+4|0;if((s|0)!=(d|0)){continue}break}}d=m&3;if(!d){break f}while(1){p=(l+32|0)+(k<<3)|0;s=F[q+(k<<1)>>1];G[p>>2]=s;G[p+4>>2]=s>>31;k=k+1|0;c=c+1|0;if((d|0)!=(c|0)){continue}break}}_c(a,m,G[l+29084>>2],l+32|0,j);break d}Oe(a,m,G[l+29084>>2],l+32|0,j)}k=G[j>>2];if((k|0)>0){c=f;a=e+1|0;c=a?c:c+1|0;L[l+16>>3]=+(a>>>0)+ +(c|0)*4294967296;c=m;d=c>>31;a=c+e|0;c=d+f|0;L[l+24>>3]=+(a>>>0)+ +((a>>>0>>0?c+1|0:c)|0)*4294967296;a=l+28864|0;Ya(a,81,47013,l+16|0);Ua(a);break c}c=m;d=c>>31;n=c;h=h-((g>>>0>>0)+d|0)|0;g=g-c|0;if(!(h|g)){break b}c=d+f|0;m=e+n|0;c=m>>>0>>0?c+1|0:c;e=m;f=c;c=d+G[l+29060>>2]|0;m=n+G[l+29056>>2]|0;c=m>>>0>>0?c+1|0:c;G[l+29056>>2]=m;G[l+29060>>2]=c;if(G[l+29072>>2]!=(m|0)|G[l+29076>>2]!=(c|0)){continue}G[l+29056>>2]=0;G[l+29060>>2]=0;c=y;d=x+1|0;c=d?c:c+1|0;x=d;y=c;continue}}k=G[j>>2];break a}if((k|0)!=-11){break a}Ua(44927);k=412;G[j>>2]=412}Fa=l+29104|0;return k}function yc(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x){var y=0,z=0,A=0,B=0,C=0,D=0,F=0,I=0,K=0,N=0,O=0,P=0;y=Fa-448|0;Fa=y;G[y+444>>2]=0;a:{b:{c:{A=G[a>>2];z=G[a+4>>2];d:{e:{if((A|0)!=G[z+76>>2]){mb(a,A+1|0,0,x);break e}if((G[z+128>>2]&G[z+132>>2])==-1){if((Rb(a,x)|0)<=0){break e}break d}if((i|0)==15|(i|0)<=0){break e}A=G[49820];if(A-41>>>0<=4294967255){an(199280);z=G[a+4>>2];A=G[49820]}if((A|0)!=G[z+4>>2]){break e}B=G[z+128>>2];A=G[z+132>>2]-(B>>>0<2880)|0;C=G[z+104>>2];D=C;B=B-2880|0;F=B;B=C>>>0>B>>>0;C=G[z+108>>2];B=B&(A|0)<=(C|0)|(A|0)<(C|0);if(G[z+112>>2]==((B?D:F)|0)&G[z+116>>2]==((B?C:A)|0)){break e}rk(a,x)}z=G[a+4>>2];A=G[z+80>>2];if(!c&(d|0)<=0|(d|0)<0){I=+(c>>>0)+ +(d|0)*4294967296;if(!A){L[y>>3]=I;a=y+336|0;Ya(a,81,19547,y);tb(5,a);break c}L[y+16>>3]=I;a=y+336|0;Ya(a,81,19506,y+16|0);tb(5,a);break c}if(!(!!e&(f|0)>=0|(f|0)>0|(A|0)==1)){G[y+32>>2]=e;a=y+336|0;Ya(a,81,27597,y+32|0);break b}if((h|0)<0){L[y+48>>3]=+(g>>>0)+ +(h|0)*4294967296;a=y+336|0;Ya(a,81,19407,y+48|0);tb(5,a);G[x>>2]=306;a=306;break a}if(!((b|0)>0&G[z+936>>2]>=(b|0))){G[y+80>>2]=b;b=y+336|0;Ya(b,81,30457,y+80|0);tb(5,b);G[y+64>>2]=G[G[a+4>>2]+936>>2];Ya(b,81,44143,y- -64|0);tb(5,b);G[x>>2]=302;a=302;break a}G[u>>2]=A;A=G[z+964>>2];G[t>>2]=G[z+960>>2];G[t+4>>2]=A;A=G[z+128>>2];D=G[z+132>>2];F=G[z+968>>2]+M(b,160)|0;C=F-160|0;L[j>>3]=L[C+96>>3];L[k>>3]=L[C+104>>3];z=C;B=G[z+116>>2];G[v>>2]=G[z+112>>2];G[v+4>>2]=B;B=G[z+72>>2];K=G[z+76>>2];G[m>>2]=G[z+152>>2];G[r>>2]=G[z+152>>2];G[n>>2]=G[z+80>>2];N=G[z+92>>2];G[s>>2]=G[z+88>>2];G[s+4>>2]=N;Za(l,F-20|0);l=Za(w,F-40|0);if(!(H[l|0]|G[u>>2]!=1)){w=H[68296]|H[68297]<<8;E[l+16|0]=w;E[l+17|0]=w>>>8;w=H[68292]|H[68293]<<8|(H[68294]<<16|H[68295]<<24);z=H[68288]|H[68289]<<8|(H[68290]<<16|H[68291]<<24);E[l+8|0]=z;E[l+9|0]=z>>>8;E[l+10|0]=z>>>16;E[l+11|0]=z>>>24;E[l+12|0]=w;E[l+13|0]=w>>>8;E[l+14|0]=w>>>16;E[l+15|0]=w>>>24;w=H[68284]|H[68285]<<8|(H[68286]<<16|H[68287]<<24);z=H[68280]|H[68281]<<8|(H[68282]<<16|H[68283]<<24);E[l|0]=z;E[l+1|0]=z>>>8;E[l+2|0]=z>>>16;E[l+3|0]=z>>>24;E[l+4|0]=w;E[l+5|0]=w>>>8;E[l+6|0]=w>>>16;E[l+7|0]=w>>>24;w=G[m>>2];E[l+((w|0)<17?w:17)|0]=0}z=G[n>>2];if(i-15>>>0<=3){l=z>>31;if(!(G[u>>2]==1|((l^z)-l|0)!=16)){G[r>>2]=1;if((z|0)<0){l=G[m>>2];G[s>>2]=l;G[s+4>>2]=l>>31}G[m>>2]=1;G[j>>2]=0;G[j+4>>2]=1072693248;G[k>>2]=0;G[k+4>>2]=0;G[v>>2]=1234554321;G[v+4>>2]=0;G[o>>2]=28800;z=G[n>>2]<0?-11:11;G[n>>2]=z}i=i-16|0}j=z>>31;if(((j^z)-j|0)==1){z=M(z,11);G[n>>2]=z;j=G[s+4>>2];k=G[s>>2]+7|0;j=k>>>0<7?j+1|0:j;O=s,P=Bu(k,j,8,0),G[O>>2]=P;G[s+4>>2]=Ia}k=G[u>>2];f:{if((k|0)!=2){break f}if((z|0)!=-16){if((z|0)!=16){break f}j=G[m>>2];if(j){O=s,P=Bu(G[s>>2],G[s+4>>2],j,j>>31),G[O>>2]=P;G[s+4>>2]=Ia;break f}G[s>>2]=0;G[s+4>>2]=0;break f}G[r>>2]=1;G[m>>2]=g}j=(k|0)==1;G[q>>2]=j?0:e-1|0;G[q+4>>2]=j?0:f-!e|0;f=z>>31;if((f^z)-f>>>0>=83){z=(((z|0)<=0?-1:1)+z|0)/2|0;G[n>>2]=z;j=G[s>>2];f=G[s+4>>2]<<1|j>>>31;G[s>>2]=j<<1;G[s+4>>2]=f;G[m>>2]=G[m>>2]/2;G[r>>2]=G[r>>2]/2}g:{h:{i:{f=z>>31;j=(f^z)-f|0;if((j|0)!=16){f=7200;if((j|0)==42){break h}if((j|0)!=82){break i}f=3600;break h}j=G[m>>2];f=28799;if(!j){break h}f=28799/(j|0)|0;G[o>>2]=f;if(f){break g}G[y+324>>2]=28799;G[y+320>>2]=j;a=y+336|0;Ya(a,81,30110,y+320|0);tb(5,a);G[x>>2]=236;a=236;break a}f=28800/G[m>>2]|0}G[o>>2]=f}m=(i|0)==-1?0:i;f=D+K|0;j=A+B|0;f=j>>>0>>0?f+1|0:f;l=Au(G[t>>2],G[t+4>>2],c-1|0,d-!c|0);k=l+j|0;j=Ia+f|0;G[p>>2]=k;G[p+4>>2]=k>>>0>>0?j+1|0:j;o=G[u>>2];if(!(o|!m)){f=h+G[q+4>>2]|0;a=g+G[q>>2]|0;f=a>>>0>>0?f+1|0:f;b=G[s+4>>2];if((b|0)>=(f|0)&J[s>>2]>=a>>>0|(b|0)>(f|0)){break d}G[s>>2]=a;G[s+4>>2]=f;break d}f=G[n>>2];if((f|0)>0){f=G[q+4>>2];l=G[s+4>>2];b=G[q>>2];j=G[s>>2];if((f|0)>=(l|0)&b>>>0>=j>>>0|(f|0)>(l|0)){G[y+228>>2]=j;G[y+224>>2]=b+1;a=y+336|0;Ya(a,81,27330,y+224|0);break b}f=f+h|0;k=b+g|0;f=k>>>0>>0?f+1|0:f;b=k;f=Bu(b-1|0,f-!b|0,j,l)+c|0;b=d+Ia|0;b=c>>>0>f>>>0?b+1|0:b;k=b;j=G[a+4>>2];b=G[j+952>>2];l=G[j+956>>2];j:{k:{if(m){if(!(g|h)|((k|0)<=(l|0)&b>>>0>=f>>>0|(k|0)<(l|0))){break j}if(G[j+48>>2]){c=G[j+988>>2];if(!G[j+984>>2]&(c|0)<=0|(c|0)<0){break k}}c=a;d=b;a=f-b|0;b=k-((b>>>0>f>>>0)+l|0)|0;if((Ig(c,d,l,a,b,x)|0)<=0){break j}L[y+96>>3]=+(a>>>0)+ +(b|0)*4294967296;a=y+336|0;Ya(a,81,44236,y+96|0);tb(5,a);break d}if(!((b>>>0>>0&(k|0)>=(l|0)|(k|0)>(l|0))&(i|0)!=-1)){break j}l:{if(!o){if(b>>>0>>0&(d|0)>=(l|0)|(d|0)>(l|0)){G[y+128>>2]=c;b=y+336|0;Ya(b,81,48884,y+128|0);tb(5,b);G[y+112>>2]=G[G[a+4>>2]+952>>2];Ya(b,81,46003,y+112|0);break l}tb(5,36433);G[y+160>>2]=G[s>>2];a=y+336|0;Ya(a,81,36282,y+160|0);tb(5,a);G[y+148>>2]=e;G[y+144>>2]=g;Ya(a,81,44434,y+144|0);break l}tb(5,38480);a=G[a+4>>2];b=G[a+952>>2];a=G[a+956>>2];L[y+216>>3]=+J[s>>2]+ +G[s+4>>2]*4294967296;L[y+208>>3]=+(b>>>0)+ +(a|0)*4294967296;a=y+336|0;Ya(a,81,36180,y+208|0);tb(5,a);e=G[q+4>>2];b=G[q>>2]+1|0;e=b?e:e+1|0;L[y+192>>3]=+(b>>>0)+ +(e|0)*4294967296;L[y+184>>3]=+(c>>>0)+ +(d|0)*4294967296;L[y+176>>3]=+(g>>>0)+ +(h|0)*4294967296;Ya(a,81,43538,y+176|0)}tb(5,y+336|0);break c}G[j+952>>2]=f;G[j+956>>2]=k;c=G[j+980>>2];a=j;e=G[a+976>>2];d=Au(G[a+960>>2],G[a+964>>2],f-b|0,k-((b>>>0>f>>>0)+l|0)|0);b=e+d|0;j=Ia+c|0;G[a+976>>2]=b;G[a+980>>2]=b>>>0>>0?j+1|0:j}if(!h&g>>>0<2|(G[s>>2]!=1|G[s+4>>2])|(m|0)==2){break d}a=G[t>>2];b=G[t+4>>2];if(a>>>0>2147483647&(b|0)>=0|(b|0)>0){break d}G[r>>2]=a;G[s>>2]=g;G[s+4>>2]=h;break d}G[n>>2]=0-f;m:{n:{if(m){f=h+G[q+4>>2]|0;e=g+G[q>>2]|0;f=e>>>0>>0?f+1|0:f;G[s>>2]=e;G[s+4>>2]=f;o:{e=G[a+4>>2];f=c>>>0>J[e+952>>2];e=G[e+956>>2];if(f&(d|0)>=(e|0)|(d|0)>(e|0)){break o}Le(a,b,c,d,y+424|0,y+432|0,y+444|0);if(G[y+444>>2]){break o}g=G[C+80>>2];p:{q:{if((g|0)<=-83){e=G[y+424>>2];j=G[y+428>>2]<<1|e>>>31;e=e<<1;f=j;break q}e=G[y+424>>2];f=G[y+428>>2];if((g|0)!=-1){break p}e=e+7|0;f=e>>>0<7?f+1|0:f;e=Bu(e,f,8,0);f=Ia}G[y+424>>2]=e;G[y+428>>2]=f}h=J[s>>2]>e>>>0;e=G[s+4>>2];if(h&(e|0)>=(f|0)|(e|0)>(f|0)){break o}e=G[a+4>>2];f=G[e+976>>2];h=G[e+980>>2];j=f;k=G[y+436>>2];e=D+k|0;i=G[y+432>>2];f=A+i|0;e=f>>>0>>0?e+1|0:e;l=f;f=j+f|0;j=e+h|0;G[p>>2]=f;G[p+4>>2]=f>>>0>>0?j+1|0:j;e=a;f=b;a=G[s>>2];b=G[s+4>>2];j=Bu(a,b,2,0);h=a;a=(g|0)<-82;ph(e,f,c,d,a?j:h,a?Ia:b,i,k,x);break d}z=G[a+4>>2];f=z;e=G[f+952>>2];f=G[f+956>>2];if(e>>>0>>0&(f|0)<=(d|0)|(d|0)>(f|0)){h=e;g=c-e|0;e=d-((c>>>0>>0)+f|0)|0;if((Ig(a,h,f,g,e,x)|0)>0){break n}z=G[a+4>>2]}f=G[z+988>>2];j=D+G[z+980>>2]|0;e=A+G[z+976>>2]|0;j=e>>>0>>0?j+1|0:j;g=e;e=e+G[z+984>>2]|0;f=f+j|0;G[p>>2]=e;G[p+4>>2]=e>>>0>>0?f+1|0:f;e=b;f=c;b=G[s>>2];c=G[s+4>>2];h=Bu(b,c,2,0);g=b;b=G[C+80>>2]<-82;ph(a,e,f,d,b?h:g,b?Ia:c,G[z+984>>2],G[z+988>>2],x);z=G[a+4>>2];r:{if(G[z+48>>2]){break r}c=G[z+988>>2];f=D+G[z+980>>2]|0;b=A+G[z+976>>2]|0;f=b>>>0>>0?f+1|0:f;d=b;b=b+G[z+984>>2]|0;f=c+f|0;f=b>>>0>>0?f+1|0:f;d=b;b=G[r>>2];c=Au(G[s>>2],G[s+4>>2],b,b>>31);b=d+c|0;j=Ia+f|0;j=b>>>0>>0?j+1|0:j;c=G[z+96>>2]+(G[z+76>>2]<<3)|0;d=G[c+8>>2];c=G[c+12>>2];if(b>>>0<=d>>>0&(c|0)>=(j|0)|(c|0)>(j|0)){break r}f=(c^-1)+j|0;d=d^-1;b=d+b|0;b=Bu(b,b>>>0>>0?f+1|0:f,2880,0)+1|0;if((Bf(a,b,1,x)|0)>0){break m}z=G[a+4>>2]}b=G[z+988>>2];d=G[z+984>>2];a=G[r>>2];c=Au(G[s>>2],G[s+4>>2],a,a>>31);a=d+c|0;e=Ia+b|0;G[z+984>>2]=a;G[z+988>>2]=a>>>0>>0?e+1|0:e;break d}f=G[a+4>>2];g=J[f+952>>2]>>0;f=G[f+956>>2];if(g&(f|0)<=(d|0)|(d|0)>(f|0)){tb(5,23343);a=G[a+4>>2];b=G[a+952>>2];a=G[a+956>>2];L[y+280>>3]=+(c>>>0)+ +(d|0)*4294967296;L[y+272>>3]=+(b>>>0)+ +(a|0)*4294967296;a=y+336|0;Ya(a,81,43488,y+272|0);tb(5,a);break c}Le(a,b,c,d,y+424|0,y+432|0,x);d=G[y+428>>2];c=G[y+424>>2];G[s>>2]=c;G[s+4>>2]=d;b=G[C+80>>2];s:{if((b|0)<=-83){b=c;f=d<<1|b>>>31;c=b<<1;d=f}else{if((b|0)!=-1){break s}b=d;c=c+7|0;b=c>>>0<7?b+1|0:b;c=Bu(c,b,8,0);d=Ia}G[s>>2]=c;G[s+4>>2]=d}b=G[q+4>>2];if((b|0)>=(d|0)&J[q>>2]>=c>>>0|(b|0)>(d|0)){G[y+304>>2]=e;a=y+336|0;Ya(a,81,27528,y+304|0);tb(5,a);G[y+288>>2]=G[s>>2];Ya(a,81,5563,y+288|0);break b}a=G[a+4>>2];b=G[a+976>>2];c=G[a+980>>2];f=D+G[y+436>>2]|0;a=A+G[y+432>>2]|0;f=a>>>0>>0?f+1|0:f;d=b;b=a;a=d+a|0;j=c+f|0;G[p>>2]=a;G[p+4>>2]=a>>>0>>0?j+1|0:j;break d}L[y+240>>3]=+(g>>>0)+ +(e|0)*4294967296;a=y+336|0;Ya(a,81,44236,y+240|0);tb(5,a);break d}G[y+256>>2]=b;a=y+336|0;Ya(a,81,42616,y+256|0);tb(5,a)}a=G[x>>2];break a}G[x>>2]=307;a=307;break a}tb(5,a);G[x>>2]=308;a=308}Fa=y+448|0;return a}function pe(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;l=Fa-29104|0;Fa=l;k=G[j>>2];a:{if((k|0)>0){break a}b:{c:{if((yc(a,b,c,d,e,f,g,h,17,l+29032|0,l+29024|0,l+28992|0,l+29088|0,l+29100|0,l+29096|0,l+29064|0,l+29056|0,l+29084|0,l+29072|0,l+29048|0,l+29092|0,l+29040|0,l+28832|0,j)|0)>0){break c}c=G[l+29096>>2];d=c>>31;k=G[l+29100>>2];if((k|0)==16){Ne(l+28992|0,l+28960|0);k=G[l+29100>>2]}if(!(g|h)){k=G[j>>2];break b}e=g>>>0<2147483647&(h|0)<=0|(h|0)<0;f=c;v=L[l+29032>>3]==1&L[l+29024>>3]==0&(k|0)==11;c=v;w=c?e?g:2147483647:f;x=c?e?h:0:d;e=0;f=0;while(1){n=G[l+29072>>2];q=G[l+29076>>2];c=G[l+29068>>2];d=G[l+29064>>2];m=Au(G[l+29048>>2],G[l+29052>>2],y,z);d=d+m|0;c=Ia+c|0;c=d>>>0>>0?c+1|0:c;k=d;m=G[l+29056>>2];p=G[l+29060>>2];d=G[l+29084>>2];s=Au(m,p,d,d>>31);k=k+s|0;d=Ia+c|0;Jb(a,k,k>>>0>>0?d+1|0:d,1,j);d=g>>>0>>0&(h|0)<=(x|0)|(h|0)<(x|0)?g:w;c=d>>31;k=d;d=q-((m>>>0>n>>>0)+p|0)|0;n=n-m|0;m=n;n=k>>>0>>0&(c|0)<=(d|0)|(c|0)<(d|0);m=n?k:m;d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{d=G[l+29100>>2];switch(d-11|0){case 10:break g;case 30:break h;case 31:break i;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break l;case 5:break m;case 0:break n;default:break o}}switch(d-81|0){case 1:break j;case 0:break f;default:break l}}if(v){we(a,m,G[l+29084>>2],e+i|0,j);break d}n=e+i|0;r=L[l+29032>>3];t=L[l+29024>>3];if(!(r==1&t==0)){k=0;if((m|0)<=0){break e}while(1){d=(l+32|0)+k|0;p:{q:{o=(+H[k+n|0]-t)/r;if(o<-.49){G[j>>2]=-11;break q}if(o>255.49){G[j>>2]=-11;c=255;break p}o=o+.5;if(!(o<4294967296&o>=0)){break q}c=~~o>>>0;break p}c=0}E[d|0]=c;k=k+1|0;if((m|0)!=(k|0)){continue}break}break e}bb(l+32|0,n,m);break e}if(jb(l+28992|0,65)){n=G[l+29084>>2];d=G[l+29088>>2];if((n|0)!=(d|0)){break k}n=m>>31;Wb(a,m,n,e+i|0,j);break d}if(H[l+28961|0]==115){break l}p=e+i|0;s=l+28960|0;c=G[l+29088>>2];n=l+32|0;k=0;q=Fa-32|0;Fa=q;o=L[l+29032>>3];r=L[l+29024>>3];r:{if(!(o==1&r==0)){if((m|0)<=0){break r}d=n;while(1){L[q+16>>3]=(+H[k+p|0]-r)/o;Eb(d,s,q+16|0);d=c+d|0;if(H[d|0]){G[j>>2]=-11}k=k+1|0;if((m|0)!=(k|0)){continue}break}break r}if((m|0)<=0){break r}d=n;while(1){L[q>>3]=H[k+p|0];Eb(d,s,q);d=c+d|0;if(H[d|0]){G[j>>2]=-11}k=k+1|0;if((m|0)!=(k|0)){continue}break}}k=jb(n,44);if(k){while(1){E[k|0]=46;k=jb(k,44);if(k){continue}break}}Fa=q+32|0;d=G[l+29084>>2];n=G[l+29088>>2];if((d|0)==(n|0)){d=M(d,m);Wb(a,d,d>>31,l+32|0,j);break d}wd(a,n,m,d-n|0,l+32|0,j);break d}G[l>>2]=b;G[l+4>>2]=l+28992;a=l+28864|0;Ya(a,81,8813,l);Ua(a);if(G[l+29092>>2]==1){k=311;G[j>>2]=311;break a}k=312;G[j>>2]=312;break a}wd(a,d,(m|0)/(d|0)|0,n-d|0,e+i|0,j);break d}q=e+i|0;o=L[l+29032>>3];r=L[l+29024>>3];s:{if(!(o==1&r==0)){if((m|0)<=0){break s}k=0;if((m|0)!=1){n=m&-2;d=0;while(1){p=l+32|0;L[p+(k<<3)>>3]=(+H[k+q|0]-r)/o;c=p;p=k|1;L[c+(p<<3)>>3]=(+H[q+p|0]-r)/o;k=k+2|0;d=d+2|0;if((n|0)!=(d|0)){continue}break}}if(!(m&1)){break s}L[(l+32|0)+(k<<3)>>3]=(+H[k+q|0]-r)/o;break s}if((m|0)<=0){break s}d=0;k=0;if(m-1>>>0>=3){s=m&-4;n=0;while(1){p=l+32|0;L[p+(k<<3)>>3]=H[k+q|0];c=k|1;L[p+(c<<3)>>3]=H[c+q|0];c=k|2;L[p+(c<<3)>>3]=H[c+q|0];c=k|3;L[p+(c<<3)>>3]=H[c+q|0];k=k+4|0;n=n+4|0;if((s|0)!=(n|0)){continue}break}}n=m&3;if(!n){break s}while(1){L[(l+32|0)+(k<<3)>>3]=H[k+q|0];k=k+1|0;d=d+1|0;if((n|0)!=(d|0)){continue}break}}_c(a,m,G[l+29084>>2],l+32|0,j);break d}q=e+i|0;o=L[l+29032>>3];r=L[l+29024>>3];t:{if(!(o==1&r==0)){if((m|0)<=0){break t}k=0;if((m|0)!=1){n=m&-2;d=0;while(1){p=l+32|0;K[p+(k<<2)>>2]=(+H[k+q|0]-r)/o;c=p;p=k|1;K[c+(p<<2)>>2]=(+H[q+p|0]-r)/o;k=k+2|0;d=d+2|0;if((n|0)!=(d|0)){continue}break}}if(!(m&1)){break t}K[(l+32|0)+(k<<2)>>2]=(+H[k+q|0]-r)/o;break t}if((m|0)<=0){break t}d=0;k=0;if(m-1>>>0>=3){s=m&-4;n=0;while(1){p=l+32|0;K[p+(k<<2)>>2]=H[k+q|0];c=k|1;K[p+(c<<2)>>2]=H[c+q|0];c=k|2;K[p+(c<<2)>>2]=H[c+q|0];c=k|3;K[p+(c<<2)>>2]=H[c+q|0];k=k+4|0;n=n+4|0;if((s|0)!=(n|0)){continue}break}}n=m&3;if(!n){break t}while(1){K[(l+32|0)+(k<<2)>>2]=H[k+q|0];k=k+1|0;d=d+1|0;if((n|0)!=(d|0)){continue}break}}$c(a,m,G[l+29084>>2],l+32|0,j);break d}q=e+i|0;r=L[l+29032>>3];t=L[l+29024>>3];u:{if(!(r==1&t==0)){k=0;if((m|0)<=0){break u}while(1){d=(l+32|0)+(k<<2)|0;v:{w:{o=(+H[k+q|0]-t)/r;if(o<-2147483648.49){G[j>>2]=-11;break w}if(o>2147483647.49){G[j>>2]=-11;c=2147483647;break v}if(o>=0){o=o+.5;if(!(O(o)<2147483648)){break w}c=~~o;break v}o=o+-.5;if(!(O(o)<2147483648)){break w}c=~~o;break v}c=-2147483648}G[d>>2]=c;k=k+1|0;if((m|0)!=(k|0)){continue}break}break u}if((m|0)<=0){break u}d=0;k=0;if(m-1>>>0>=3){s=m&-4;n=0;while(1){p=l+32|0;G[p+(k<<2)>>2]=H[k+q|0];c=k|1;G[p+(c<<2)>>2]=H[c+q|0];c=k|2;G[p+(c<<2)>>2]=H[c+q|0];c=k|3;G[p+(c<<2)>>2]=H[c+q|0];k=k+4|0;n=n+4|0;if((s|0)!=(n|0)){continue}break}}n=m&3;if(!n){break u}while(1){G[(l+32|0)+(k<<2)>>2]=H[k+q|0];k=k+1|0;d=d+1|0;if((n|0)!=(d|0)){continue}break}}$c(a,m,G[l+29084>>2],l+32|0,j);break d}q=e+i|0;r=L[l+29032>>3];t=L[l+29024>>3];x:{if(!(r==1&t==0)){k=0;if((m|0)<=0){break x}while(1){d=(l+32|0)+(k<<1)|0;o=(+H[k+q|0]-t)/r;y:{if(o<-32768.49){G[j>>2]=-11;c=32768;break y}if(o>32767.49){G[j>>2]=-11;c=32767;break y}z:{if(o>=0){o=o+.5;if(!(O(o)<2147483648)){break z}c=~~o;break y}o=o+-.5;if(!(O(o)<2147483648)){break z}c=~~o;break y}c=-2147483648}F[d>>1]=c;k=k+1|0;if((m|0)!=(k|0)){continue}break}break x}if((m|0)<=0){break x}d=0;k=0;if(m-1>>>0>=3){s=m&-4;n=0;while(1){p=l+32|0;F[p+(k<<1)>>1]=H[k+q|0];c=k|1;F[p+(c<<1)>>1]=H[c+q|0];c=k|2;F[p+(c<<1)>>1]=H[c+q|0];c=k|3;F[p+(c<<1)>>1]=H[c+q|0];k=k+4|0;n=n+4|0;if((s|0)!=(n|0)){continue}break}}n=m&3;if(!n){break x}while(1){F[(l+32|0)+(k<<1)>>1]=H[k+q|0];k=k+1|0;d=d+1|0;if((n|0)!=(d|0)){continue}break}}Oe(a,m,G[l+29084>>2],l+32|0,j);break d}q=e+i|0;t=L[l+29032>>3];d=t!=1;r=L[l+29024>>3];A:{if(!(d|r!=0x8000000000000000)){if((m|0)<=0){break A}d=0;k=0;if(m-1>>>0>=3){s=m&-4;n=0;while(1){p=l+32|0;c=p+(k<<3)|0;G[c>>2]=H[k+q|0];G[c+4>>2]=-2147483648;c=k|1;u=p+(c<<3)|0;G[u>>2]=H[c+q|0];G[u+4>>2]=-2147483648;c=k|2;u=p+(c<<3)|0;G[u>>2]=H[c+q|0];G[u+4>>2]=-2147483648;c=k|3;p=p+(c<<3)|0;G[p>>2]=H[c+q|0];G[p+4>>2]=-2147483648;k=k+4|0;n=n+4|0;if((s|0)!=(n|0)){continue}break}}n=m&3;if(!n){break A}while(1){p=(l+32|0)+(k<<3)|0;G[p>>2]=H[k+q|0];G[p+4>>2]=-2147483648;k=k+1|0;d=d+1|0;if((n|0)!=(d|0)){continue}break}break A}if(!(!d&r==0)){k=0;if((m|0)<=0){break A}while(1){p=(l+32|0)+(k<<3)|0;B:{C:{o=(+H[k+q|0]-r)/t;if(o<-0x8000000000000000){G[j>>2]=-11;break C}if(o>0x8000000000000000){G[j>>2]=-11;n=2147483647;c=-1;break B}if(o>=0){o=o+.5;if(!(O(o)<0x8000000000000000)){break C}n=O(o)>=1?~~(o>0?Q(S(o*2.3283064365386963e-10),4294967295):T((o-+(~~o>>>0>>>0))*2.3283064365386963e-10))>>>0:0;c=~~o>>>0;break B}o=o+-.5;if(!(O(o)<0x8000000000000000)){break C}n=O(o)>=1?~~(o>0?Q(S(o*2.3283064365386963e-10),4294967295):T((o-+(~~o>>>0>>>0))*2.3283064365386963e-10))>>>0:0;c=~~o>>>0;break B}n=-2147483648;c=0}G[p>>2]=c;G[p+4>>2]=n;k=k+1|0;if((m|0)!=(k|0)){continue}break}break A}if((m|0)<=0){break A}d=0;k=0;if(m-1>>>0>=3){s=m&-4;n=0;while(1){p=l+32|0;c=p+(k<<3)|0;G[c>>2]=H[k+q|0];G[c+4>>2]=0;c=k|1;u=p+(c<<3)|0;G[u>>2]=H[c+q|0];G[u+4>>2]=0;c=k|2;u=p+(c<<3)|0;G[u>>2]=H[c+q|0];G[u+4>>2]=0;c=k|3;p=p+(c<<3)|0;G[p>>2]=H[c+q|0];G[p+4>>2]=0;k=k+4|0;n=n+4|0;if((s|0)!=(n|0)){continue}break}}n=m&3;if(!n){break A}while(1){p=(l+32|0)+(k<<3)|0;G[p>>2]=H[k+q|0];G[p+4>>2]=0;k=k+1|0;d=d+1|0;if((n|0)!=(d|0)){continue}break}}_c(a,m,G[l+29084>>2],l+32|0,j);break d}we(a,m,G[l+29084>>2],l+32|0,j)}k=G[j>>2];if((k|0)>0){d=f;a=e+1|0;d=a?d:d+1|0;L[l+16>>3]=+(a>>>0)+ +(d|0)*4294967296;d=m>>31;a=m+e|0;d=d+f|0;L[l+24>>3]=+(a>>>0)+ +((a>>>0>>0?d+1|0:d)|0)*4294967296;a=l+28864|0;Ya(a,81,48062,l+16|0);Ua(a);break c}c=m;d=m>>31;n=d;h=h-(d+(m>>>0>g>>>0)|0)|0;g=g-m|0;if(!(h|g)){break b}d=f+n|0;m=c+e|0;d=m>>>0>>0?d+1|0:d;e=m;f=d;d=n+G[l+29060>>2]|0;m=c+G[l+29056>>2]|0;d=m>>>0>>0?d+1|0:d;G[l+29056>>2]=m;G[l+29060>>2]=d;if(G[l+29072>>2]!=(m|0)|G[l+29076>>2]!=(d|0)){continue}G[l+29056>>2]=0;G[l+29060>>2]=0;c=z;d=y+1|0;c=d?c:c+1|0;y=d;z=c;continue}}k=G[j>>2];break a}if((k|0)!=-11){break a}Ua(44927);k=412;G[j>>2]=412}Fa=l+29104|0;return k} -function Qq(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;e=Fa-1824|0;Fa=e;G[935247]=0;G[935248]=0;G[935249]=0;G[935250]=0;G[935251]=0;G[935252]=0;G[935253]=0;G[935254]=0;E[e+1568|0]=0;E[3741020]=0;G[935256]=0;G[935257]=0;G[935258]=0;G[935259]=0;E[e+1312|0]=0;G[935260]=0;m=G[29763];G[321435]=m;G[47589]=1;G[935261]=1;G[935262]=0;o=3741052,p=ab(16512),G[o>>2]=p;j=32;a:{b:{c:{d:{e:{f:{g:{h:{i:{j:{k:{l:while(1){m:{n:{o:{p:{q:{r:{s:{t:{u:{v:{w:{c=of(a,b,2788);switch(c-67|0){case 49:break m;case 35:break n;case 48:break o;case 33:break p;case 31:break q;case 55:break r;case 30:break s;case 0:break t;case 32:break u;case 47:break v;case 38:break w;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 34:case 36:case 37:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 50:case 51:case 52:case 53:case 54:break f;default:break k}}G[935249]=1;continue}G[935257]=1;continue}G[935259]=1;continue}G[935261]=0;continue}G[935258]=1;continue}G[935260]=1;continue}G[935256]=1;continue}E[3741020]=1;continue}c=ac(G[321433],49010);G[321435]=c;if(c){continue}G[e+112>>2]=G[321433];kb(80991,e+112|0);break a}c=ac(G[321433],13287);G[935264]=c;if(!c){break j}if(!vc(e+288|0,1024,c)){continue}while(1){x:{y:{h=Va(e+288|0);c=h+e|0;switch(H[c+287|0]-10|0){case 0:case 3:break y;default:break x}}E[c+287|0]=0;continue}g=e+288|0;i=h+g|0;z:{if((h|0)<=0){break z}while(1){c=H[g|0];if((c|0)!=32&(c|0)!=9){break z}g=g+1|0;if(i>>>0>g>>>0){continue}break}}if((g|0)==(i|0)){continue l}A:{if(g>>>0>=i>>>0){c=g;break A}d=(e+288|0)+g+(h-g)|0;c=g;while(1){f=H[c|0];if((f|0)==9|(f|0)==32){break A}c=c+1|0;if((d|0)!=(c|0)){continue}break}c=d}E[c|0]=0;f=c+1|0;B:{if(i>>>0<=f>>>0){break B}c=(e+288|0)+c+(h-c)|0;while(1){d=H[f|0];if((d|0)!=32&(d|0)!=9){break B}f=f+1|0;if((c|0)!=(f|0)){continue}break}f=c}d=f;C:{if(i>>>0<=d>>>0){break C}c=(e+288|0)+f+(h-f)|0;while(1){k=H[d|0];if((k|0)==9|(k|0)==32){break C}d=d+1|0;if((c|0)!=(d|0)){continue}break}d=c}E[d|0]=0;c=d+1|0;D:{if(i>>>0<=c>>>0){break D}d=(e+288|0)+d+(h-d)|0;while(1){k=H[c|0];if((k|0)!=32&(k|0)!=9){break D}c=c+1|0;if((d|0)!=(c|0)){continue}break}c=d}d=c;E:{if(c>>>0>=i>>>0){break E}h=(e+288|0)+c+(h-c)|0;while(1){i=H[d|0];if((i|0)==9|(i|0)==32){break E}d=d+1|0;if((h|0)!=(d|0)){continue}break}d=h}E[d|0]=0;Za(G[935263]+M(G[935262],516)|0,g);Za((G[935263]+M(G[935262],516)|0)+128|0,f);h=G[935263];o=h+M(G[935262],516)|0,p=_b(c),G[o+512>>2]=p;d=G[935262];i=h+M(d,516)|0;k=Va(i);if(k>>>0>J[i+512>>2]){G[i+512>>2]=k;d=G[935262]}h=h+M(d,516)|0;if(!H[h|0]){break i}if(!H[h+128|0]){break h}E[h+256|0]=0;E[(G[935263]+M(G[935262],516)|0)+384|0]=0;if(H[3741020]){G[e+180>>2]=g;G[e+184>>2]=f;G[e+188>>2]=c;G[e+176>>2]=G[935262];kb(76089,e+176|0);$a(m)}c=G[935262]+1|0;G[935262]=c;if((c|0)>=(j|0)){j=j+32|0;o=3741052,p=ub(G[935263],M(j,516)),G[o>>2]=p}if(vc(e+288|0,1024,G[935264])){continue}break}continue}if((Rh(G[321433])|0)<=0){break g}n=1;l=Pb(21447);if((l|0)>=0){continue}l=Pb(22604);if((l|0)>=0){continue}break}hb(82832,65,1,G[321435]);break a}if((c|0)!=-1){break f}c=a;a=G[47589];if((c-a|0)<=1){break e}a=(a<<2)+b|0;b=Za(e+1568|0,G[a>>2]);h=Za(e+1312|0,G[a+4>>2]);a=Va(b);F:{if(a>>>0<2){break F}a=(a+b|0)-1|0;if(H[a|0]!=47){break F}E[a|0]=0}if(!(!G[935261]|G[47608]<=0)){a=G[935262];f=G[935263];g=0;while(1){c=M(a,516)+f|0;a=g<<5;Za(c,a+190448|0);Za((G[935263]+M(G[935262],516)|0)+128|0,a+190736|0);f=G[935263];G[(f+M(G[935262],516)|0)+512>>2]=G[(g<<2)+156848>>2];a=G[935262]+1|0;G[935262]=a;if((a|0)>=(j|0)){j=j+32|0;f=ub(f,M(j,516));G[935263]=f;a=G[935262]}g=g+1|0;if((g|0)>2]&61440)!=16384){break c}G[935265]=0;g=0;G:{if(H[b|0]==47){break G}a=Va(b);G[935265]=a;if(!a){break G}if(H[(a+b|0)-1|0]==47){g=a;break G}g=a+1|0;G[935265]=g}if(H[3741020]){G[e+80>>2]=b;G[e+84>>2]=g;_a(G[321435],87830,e+80|0);$a(m)}a=ac(h,49010);G[935266]=a;if(!a){break b}H:{if(n){a=Fa-600160|0;Fa=a;if((nf()|0)>=0){i=a+500157|0;g=G[29763];while(1){c=Za(a+160|0,G[925783]>(l|0)?G[(G[925773]+M(l,4108)|0)+4096>>2]:0);if(H[3741020]){G[a+64>>2]=c;kb(76135,a- -64|0);$a(g)}G[a+52>>2]=c;G[a+48>>2]=b;db(a+500160|0,8778,a+48|0);Za(3741076,c);if(H[3741020]){G[a+36>>2]=3741076;G[a+32>>2]=a+500160;kb(76239,a+32|0);$a(g)}I:{if(Be(a+500160|0,a+72|0)){break I}c=Va(a+500160|0);if(H[3741020]){G[a+16>>2]=a+500160;kb(77122,a+16|0);$a(g)}if(G[935260]){if(!fb(c+i|0,2750,3)){break I}}if(!G[935258]){d=c+(a+500160|0)|0;f=d-9|0;if(!fb(f,4996,9)){break I}if(!fb(f,33375,9)){break I}f=d-10|0;if(!fb(f,5641,10)){break I}if(!fb(f,33593,10)){break I}f=d-12|0;if(!fb(f,2685,12)){break I}if(!fb(f,2722,12)){break I}d=d-13|0;if(!fb(d,2698,13)){break I}if(!fb(d,2735,13)){break I}}c=c+(a+500160|0)|0;d=c-4|0;J:{if(!fb(d,5001,4)){break J}if(!fb(d,33380,4)){break J}d=c-5|0;if(!fb(d,5646,5)){break J}if(!fb(d,33598,5)){break J}d=c-7|0;if(!fb(d,2754,7)){break J}if(!fb(d,2771,7)){break J}if(!fb(d,2690,7)){break J}if(!fb(d,2727,7)){break J}d=c-8|0;if(!fb(d,2762,8)){break J}if(!fb(d,2779,8)){break J}if(!fb(d,2703,8)){break J}if(fb(d,2740,8)){break I}}E[a+400160|0]=0;K:{d=c-7|0;L:{if(!fb(d,2690,7)){break L}if(!fb(d,2727,7)){break L}c=c-8|0;if(!fb(c,2703,8)){break L}if(fb(c,2740,8)){break K}}c=H[32853]|H[32854]<<8|(H[32855]<<16|H[32856]<<24);d=H[32849]|H[32850]<<8|(H[32851]<<16|H[32852]<<24);F[a+100166>>1]=d;F[a+100168>>1]=d>>>16;F[a+100170>>1]=c;F[a+100172>>1]=c>>>16;c=H[32847]|H[32848]<<8|(H[32849]<<16|H[32850]<<24);G[a+100160>>2]=H[32843]|H[32844]<<8|(H[32845]<<16|H[32846]<<24);G[a+100164>>2]=c;d=Za(a+300160|0,kj(a+100160|0));c=Va(d)+d|0;f=H[5646]|H[5647]<<8|(H[5648]<<16|H[5649]<<24);E[c|0]=f;E[c+1|0]=f>>>8;E[c+2|0]=f>>>16;E[c+3|0]=f>>>24;f=H[5650]|H[5651]<<8;E[c+4|0]=f;E[c+5|0]=f>>>8;G[a+4>>2]=d;G[a>>2]=a+500160;c=a+200160|0;db(c,9290,a);ka(c|0)|0;c=Mh(d,3741072,a+400160|0);if(c){G[935248]=c+G[935248]}Vg(d);break I}c=Mh(a+500160|0,3741072,a+400160|0);if(!c){break I}G[935248]=c+G[935248]}if((nf()|0)>=0){continue}break}}Fa=a+600160|0;break H}Zl(b)}Hb(G[935266]);b=0;a=Fa-100256|0;Fa=a;c=H[32839]|H[32840]<<8|(H[32841]<<16|H[32842]<<24);d=H[32835]|H[32836]<<8|(H[32837]<<16|H[32838]<<24);E[a+7|0]=d;E[a+8|0]=d>>>8;E[a+9|0]=d>>>16;E[a+10|0]=d>>>24;E[a+11|0]=c;E[a+12|0]=c>>>8;E[a+13|0]=c>>>16;E[a+14|0]=c>>>24;c=H[32832]|H[32833]<<8|(H[32834]<<16|H[32835]<<24);G[a>>2]=H[32828]|H[32829]<<8|(H[32830]<<16|H[32831]<<24);G[a+4>>2]=c;c=Za(a+128|0,kj(a));M:{d=ac(h,13287);if(d){N:{O:{g=ac(c,49010);if(g){if(vc(a+256|0,1e5,d)){break O}break N}hb(84217,56,1,G[321435]);break a}while(1){E[a+100255|0]=0;f=a+256|0;i=Va(f);fe(f,g);i=i-1|0;b=(b|0)<(i|0)?i:b;if(vc(f,1e5,d)){continue}break}}Hb(d);Hb(g);d=ac(c,13287);if(!d){hb(84159,57,1,G[321435])}g=ac(h,49010);if(g){if(vc(a+256|0,1e5,d)){f=(a+256|0)+b|0;while(1){b=Va(a+256|0)+a|0;if(H[b+255|0]==10){E[b+255|0]=0}P:{if(H[a+256|0]==92){b=a+256|0;b=Va(b)+b|0;E[b|0]=10;E[b+1|0]=0;break P}b=Va(a+256|0);if((b|0)<=99999){cb(b+(a+256|0)|0,32,1e5-b|0)}E[f|0]=0;b=a+256|0;b=Va(b)+b|0;if(H[a+256|0]==124){E[b+2|0]=H[68369];h=H[68367]|H[68368]<<8;E[b|0]=h;E[b+1|0]=h>>>8;break P}E[b+2|0]=H[90053];h=H[90051]|H[90052]<<8;E[b|0]=h;E[b+1|0]=h>>>8}b=a+256|0;fe(b,g);if(vc(b,1e5,d)){continue}break}}Hb(g);Hb(d);Vg(c);Fa=a+100256|0;break M}hb(84105,53,1,G[321435]);break a}hb(83997,52,1,G[321435]);break a}G[e- -64>>2]=G[935246];G[e+48>>2]=G[935247];G[e+52>>2]=G[935250];G[e+56>>2]=G[935252];G[e+60>>2]=G[935251];_a(G[321435],79126,e+48|0);$a(G[321435]);Hb(G[321435]);sc(0);W()}G[e+128>>2]=G[321433];kb(80929,e+128|0);break a}G[e+144>>2]=d;_a(G[321435],84616,e+144|0);break a}G[e+160>>2]=d;_a(G[321435],84557,e+160|0);break a}G[e+192>>2]=G[321433];kb(80867,e+192|0);break a}G[e>>2]=c;_a(G[321435],83072,e);break a}G[e+16>>2]=G[b>>2];_a(G[321435],82507,e+16|0);break a}G[e+32>>2]=b;_a(G[321435],80593,e+32|0);break a}G[e+96>>2]=b;_a(G[321435],79410,e+96|0);break a}hb(84050,54,1,G[321435])}$a(G[321435]);Hb(G[321435]);sc(1);W()}function Xp(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,H=0,I=0,J=0,K=0,L=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Ga=0,Ha=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Va=0,Wa=0,Xa=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,lb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0;ma=1;j=Fa-400|0;Fa=j;a:{if(b-10>>>0<=4294967286){G[j>>2]=b;a=j+32|0;Ya(a,81,23817,j);Ua(a);G[i>>2]=320;break a}if(Nb(a,i)){if((b|0)!=1){c=b&-2;while(1){k=u<<3;n=j+32|0;o=k+n|0;p=u<<2;r=G[p+d>>2];G[o>>2]=r;G[o+4>>2]=r>>31;o=k;k=j+128|0;o=o+k|0;p=G[e+p>>2];G[o>>2]=p;G[o+4>>2]=p>>31;s=n;n=u|1;o=n<<3;p=s+o|0;n=n<<2;r=G[n+d>>2];G[p>>2]=r;G[p+4>>2]=r>>31;k=k+o|0;n=G[e+n>>2];G[k>>2]=n;G[k+4>>2]=n>>31;u=u+2|0;q=q+2|0;if((c|0)!=(q|0)){continue}break}}if(b&1){b=u<<3;c=b+(j+32|0)|0;k=d;d=u<<2;k=G[k+d>>2];G[c>>2]=k;G[c+4>>2]=k>>31;b=b+(j+128|0)|0;c=G[d+e>>2];G[b>>2]=c;G[b+4>>2]=c>>31}G[j+352>>2]=0;G[j+356>>2]=0;md(a,81,j+32|0,j+128|0,f,1,j+352|0,g,0,h,i);break a}if((Dc(a,j+124|0,i)|0)>0){break a}w=G[j+124>>2];b:{if(!w){r=1;ma=2;p=1;o=1;break b}k=b<<2;r=G[k+f>>2];p=G[e+k>>2];o=G[d+k>>2]}if(h){G[h>>2]=0}G[j+352>>2]=1;G[j+356>>2]=1;k=1;G[j+128>>2]=1;G[j+132>>2]=0;G[j+304>>2]=1;G[j+308>>2]=1;G[j+256>>2]=1;G[j+260>>2]=1;G[j+136>>2]=1;G[j+140>>2]=0;G[j+208>>2]=1;G[j+212>>2]=1;G[j+360>>2]=1;G[j+144>>2]=1;G[j+148>>2]=0;G[j+312>>2]=1;G[j+316>>2]=1;G[j+264>>2]=1;G[j+268>>2]=1;G[j+152>>2]=1;G[j+156>>2]=0;G[j+216>>2]=1;G[j+220>>2]=1;G[j+364>>2]=1;G[j+368>>2]=1;G[j+320>>2]=1;G[j+272>>2]=1;G[j+160>>2]=1;G[j+164>>2]=0;G[j+224>>2]=1;G[j+372>>2]=1;G[j+376>>2]=1;G[j+168>>2]=1;G[j+172>>2]=0;G[j+324>>2]=1;G[j+328>>2]=1;G[j+276>>2]=1;G[j+280>>2]=1;G[j+176>>2]=1;G[j+180>>2]=0;G[j+228>>2]=1;G[j+232>>2]=1;G[j+184>>2]=1;G[j+188>>2]=0;G[j+380>>2]=1;G[j+384>>2]=1;G[j+332>>2]=1;G[j+336>>2]=1;G[j+284>>2]=1;G[j+288>>2]=1;G[j+192>>2]=1;G[j+196>>2]=0;G[j+236>>2]=1;G[j+240>>2]=1;c:{while(1){m=q<<2;t=G[m+e>>2];s=G[d+m>>2];d:{if((t|0)>=(s|0)){v=G[m+(j+208|0)>>2];break d}if(w){break c}G[m+(j+208|0)>>2]=-1;v=-1}G[m+(j+304|0)>>2]=t;G[m+(j+352|0)>>2]=s;G[m+(j+256|0)>>2]=G[f+m>>2];x=j+128|0;t=q+1|0;s=x+(t<<3)|0;m=G[c+m>>2];m=Au(k,n,m,m>>31);G[s>>2]=m;O=s;s=Ia;G[O+4>>2]=s;q=x+(q<<3)|0;Cb=q,Db=Au(k,n,v,v>>31),G[Cb>>2]=Db;G[q+4>>2]=Ia;k=m;n=s;q=t;if((q|0)!=(b|0)){continue}break}d=(j+128|0)+(b<<3)|0;e=G[d>>2];k=e;e=G[(j+208|0)+(b<<2)>>2];Cb=d,Db=Au(k,G[d+4>>2],e,e>>31),G[Cb>>2]=Db;G[d+4>>2]=Ia;e:{if(!((b|0)!=1|G[c>>2]!=1)){u=(p-o|0)/(r|0)|0;p=o;e=r;break e}b=G[j+208>>2];e=M(b,G[j+256>>2]);u=(M(b,G[j+304>>2]-G[j+352>>2]|0)|0)/G[f>>2]|0}if((p|0)<(o|0)){break a}E=G[j+240>>2];na=M(E,G[j+384>>2]);b=M(E,G[j+336>>2]);if((na|0)>(b|0)){break a}x=G[j+236>>2];oa=M(x,G[j+380>>2]);c=M(x,G[j+332>>2]);if((oa|0)>(c|0)){break a}y=G[j+232>>2];P=M(y,G[j+376>>2]);d=M(y,G[j+328>>2]);if((P|0)>(d|0)){break a}z=G[j+228>>2];Q=M(z,G[j+372>>2]);f=M(z,G[j+324>>2]);if((Q|0)>(f|0)){break a}A=G[j+224>>2];R=M(A,G[j+368>>2]);k=M(A,G[j+320>>2]);if((R|0)>(k|0)){break a}B=G[j+220>>2];S=M(B,G[j+364>>2]);n=M(B,G[j+316>>2]);if((S|0)>(n|0)){break a}C=G[j+216>>2];T=M(C,G[j+360>>2]);q=M(C,G[j+312>>2]);if((T|0)>(q|0)){break a}D=G[j+212>>2];U=M(D,G[j+356>>2]);t=M(D,G[j+308>>2]);if((U|0)>(t|0)){break a}F=u+1|0;wa=F>>31;tb=G[j+192>>2];ub=G[j+196>>2];xa=G[j+184>>2];ya=G[j+188>>2];za=G[j+176>>2];Aa=G[j+180>>2];Ba=G[j+168>>2];Ca=G[j+172>>2];Da=G[j+160>>2];Ea=G[j+164>>2];Ga=G[j+152>>2];Ha=G[j+156>>2];Ja=G[j+144>>2];Ka=G[j+148>>2];La=G[j+136>>2];Ma=G[j+140>>2];m=G[j+352>>2];V=m;Na=m>>31;vb=p;Oa=p>>31;Pa=r;wb=r>>31;W=o;X=o>>31;xb=b;Qa=b>>31;yb=E>>31;zb=na>>31;Ra=c;Y=c>>31;Sa=x>>31;Ab=oa>>31;Ta=d;Z=d>>31;Va=y>>31;Wa=P>>31;Xa=f;_=f>>31;Za=z>>31;_a=Q>>31;$a=k;$=k>>31;ab=A>>31;bb=R>>31;cb=n;aa=n>>31;db=B>>31;eb=S>>31;fb=q;ba=q>>31;gb=C>>31;hb=T>>31;ib=t;ca=t>>31;jb=D>>31;O=U>>31;b=G[j+288>>2];kb=b;Bb=b>>31;b=G[j+284>>2];da=b;lb=b>>31;b=G[j+280>>2];ea=b;mb=b>>31;b=G[j+276>>2];fa=b;nb=b>>31;b=G[j+272>>2];ga=b;ob=b>>31;b=G[j+268>>2];ha=b;pb=b>>31;b=G[j+264>>2];ia=b;qb=b>>31;b=G[j+260>>2];ja=b;rb=b>>31;u=0;while(1){ka=na;pa=zb;while(1){la=Au(tb,ub,ka-E|0,pa-((E>>>0>ka>>>0)+yb|0)|0);sb=Ia;c=oa;v=c;d=Ab;w=d;f:{if(h){while(1){H=Au(xa,ya,c-x|0,d-((c>>>0>>0)+Sa|0)|0);qa=Ia;f=P;o=Wa;while(1){I=Au(za,Aa,f-y|0,o-((f>>>0>>0)+Va|0)|0);ra=Ia;p=Q;r=_a;while(1){J=Au(Ba,Ca,p-z|0,r-((p>>>0>>0)+Za|0)|0);sa=Ia;q=R;t=bb;while(1){K=Au(Da,Ea,q-A|0,t-((q>>>0>>0)+ab|0)|0);ta=Ia;v=S;w=eb;while(1){L=Au(Ga,Ha,v-B|0,w-((v>>>0>>0)+db|0)|0);ua=Ia;m=T;s=hb;while(1){N=Au(Ja,Ka,m-C|0,s-((m>>>0>>0)+gb|0)|0);va=Ia;k=U;n=O;while(1){l=Au(La,Ma,k-D|0,n-((k>>>0>>0)+jb|0)|0)+V|0;b=Na+Ia|0;b=l>>>0>>0?b+1|0:b;l=l+N|0;b=b+va|0;b=l>>>0>>0?b+1|0:b;l=l+L|0;b=b+ua|0;b=l>>>0>>0?b+1|0:b;l=l+K|0;b=b+ta|0;b=l>>>0>>0?b+1|0:b;l=l+J|0;b=b+sa|0;b=l>>>0>>0?b+1|0:b;l=l+I|0;b=b+ra|0;b=l>>>0>>0?b+1|0:b;l=l+H|0;b=b+qa|0;b=l>>>0>>0?b+1|0:b;l=l+la|0;b=b+sb|0;if((Se(a,ma,W,X,l,l>>>0>>0?b+1|0:b,F,wa,e,1,0,0,(u<<3)+g|0,j+123|0,j+32|0,i)|0)>0){break a}if(G[j+32>>2]){G[h>>2]=1}u=u+F|0;b=n+rb|0;k=k+ja|0;b=k>>>0>>0?b+1|0:b;n=b;if(k>>>0<=ib>>>0&(ca|0)>=(b|0)|(b|0)<(ca|0)){continue}break}b=s+qb|0;k=m+ia|0;b=k>>>0>>0?b+1|0:b;m=k;s=b;if(k>>>0<=fb>>>0&(ba|0)>=(b|0)|(b|0)<(ba|0)){continue}break}b=w+pb|0;k=v+ha|0;b=k>>>0>>0?b+1|0:b;v=k;w=b;if(k>>>0<=cb>>>0&(aa|0)>=(b|0)|(b|0)<(aa|0)){continue}break}b=t+ob|0;k=q+ga|0;b=k>>>0>>0?b+1|0:b;q=k;t=b;if(k>>>0<=$a>>>0&($|0)>=(b|0)|(b|0)<($|0)){continue}break}b=r+nb|0;k=p+fa|0;b=k>>>0>>0?b+1|0:b;p=k;r=b;if(k>>>0<=Xa>>>0&(_|0)>=(b|0)|(b|0)<(_|0)){continue}break}b=o+mb|0;f=f+ea|0;b=f>>>0>>0?b+1|0:b;o=b;if(f>>>0<=Ta>>>0&(Z|0)>=(b|0)|(b|0)<(Z|0)){continue}break}b=d+lb|0;c=c+da|0;b=c>>>0>>0?b+1|0:b;d=b;if(c>>>0<=Ra>>>0&(Y|0)>=(b|0)|(b|0)<(Y|0)){continue}break f}}while(1){H=Au(xa,ya,v-x|0,w-((v>>>0>>0)+Sa|0)|0);qa=Ia;f=P;o=Wa;while(1){I=Au(za,Aa,f-y|0,o-((f>>>0>>0)+Va|0)|0);ra=Ia;p=Q;r=_a;while(1){J=Au(Ba,Ca,p-z|0,r-((p>>>0>>0)+Za|0)|0);sa=Ia;q=R;t=bb;while(1){K=Au(Da,Ea,q-A|0,t-((q>>>0>>0)+ab|0)|0);ta=Ia;c=S;d=eb;while(1){L=Au(Ga,Ha,c-B|0,d-((c>>>0>>0)+db|0)|0);ua=Ia;m=T;s=hb;while(1){N=Au(Ja,Ka,m-C|0,s-((m>>>0>>0)+gb|0)|0);va=Ia;k=U;n=O;while(1){l=Au(La,Ma,k-D|0,n-((k>>>0>>0)+jb|0)|0)+V|0;b=Na+Ia|0;b=l>>>0>>0?b+1|0:b;l=l+N|0;b=b+va|0;b=l>>>0>>0?b+1|0:b;l=l+L|0;b=b+ua|0;b=l>>>0>>0?b+1|0:b;l=l+K|0;b=b+ta|0;b=l>>>0>>0?b+1|0:b;l=l+J|0;b=b+sa|0;b=l>>>0>>0?b+1|0:b;l=l+I|0;b=b+ra|0;b=l>>>0>>0?b+1|0:b;l=l+H|0;b=b+qa|0;b=l>>>0>>0?b+1|0:b;l=l+la|0;b=b+sb|0;if((Se(a,ma,W,X,l,l>>>0>>0?b+1|0:b,F,wa,e,1,0,0,(u<<3)+g|0,j+123|0,j+32|0,i)|0)>0){break a}u=u+F|0;b=n+rb|0;k=k+ja|0;b=k>>>0>>0?b+1|0:b;n=b;if(k>>>0<=ib>>>0&(ca|0)>=(b|0)|(b|0)<(ca|0)){continue}break}b=s+qb|0;k=m+ia|0;b=k>>>0>>0?b+1|0:b;m=k;s=b;if(k>>>0<=fb>>>0&(ba|0)>=(b|0)|(b|0)<(ba|0)){continue}break}b=d+pb|0;c=c+ha|0;b=c>>>0>>0?b+1|0:b;d=b;if(c>>>0<=cb>>>0&(aa|0)>=(b|0)|(b|0)<(aa|0)){continue}break}b=t+ob|0;c=q+ga|0;b=c>>>0>>0?b+1|0:b;q=c;t=b;if(c>>>0<=$a>>>0&($|0)>=(b|0)|(b|0)<($|0)){continue}break}b=r+nb|0;c=p+fa|0;b=c>>>0>>0?b+1|0:b;p=c;r=b;if(c>>>0<=Xa>>>0&(_|0)>=(b|0)|(b|0)<(_|0)){continue}break}b=o+mb|0;c=f+ea|0;b=c>>>0>>0?b+1|0:b;f=c;o=b;if(c>>>0<=Ta>>>0&(Z|0)>=(b|0)|(b|0)<(Z|0)){continue}break}b=w+lb|0;c=v+da|0;b=c>>>0>>0?b+1|0:b;v=c;w=b;if(c>>>0<=Ra>>>0&(Y|0)>=(b|0)|(b|0)<(Y|0)){continue}break}}b=pa+Bb|0;c=ka+kb|0;b=c>>>0>>0?b+1|0:b;ka=c;pa=b;if(c>>>0<=xb>>>0&(Qa|0)>=(b|0)|(b|0)<(Qa|0)){continue}break}b=X+wb|0;c=W+Pa|0;b=c>>>0>>0?b+1|0:b;W=c;X=b;if(c>>>0<=vb>>>0&(Oa|0)>=(b|0)|(b|0)<(Oa|0)){continue}break}break a}G[j+16>>2]=q+1;a=j+32|0;Ya(a,81,26967,j+16|0);Ua(a);G[i>>2]=321}Fa=j+400|0}function hq(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,H=0,I=0,J=0,L=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Ga=0,Ha=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Va=0,Wa=0,Xa=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,lb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0,Eb=0,Fb=0;oa=1;k=Fa-400|0;Fa=k;a:{if(b-10>>>0<=4294967286){G[k>>2]=b;a=k+32|0;Ya(a,81,23999,k);Ua(a);G[j>>2]=320;break a}if(Nb(a,j)){if((b|0)!=1){c=b&-2;while(1){l=v<<3;o=k+32|0;p=l+o|0;q=v<<2;s=G[q+d>>2];G[p>>2]=s;G[p+4>>2]=s>>31;p=l;l=k+128|0;p=p+l|0;q=G[e+q>>2];G[p>>2]=q;G[p+4>>2]=q>>31;t=o;o=v|1;p=o<<3;q=t+p|0;o=o<<2;s=G[o+d>>2];G[q>>2]=s;G[q+4>>2]=s>>31;l=l+p|0;o=G[e+o>>2];G[l>>2]=o;G[l+4>>2]=o>>31;v=v+2|0;r=r+2|0;if((c|0)!=(r|0)){continue}break}}if(b&1){b=v<<3;c=b+(k+32|0)|0;l=d;d=v<<2;l=G[l+d>>2];G[c>>2]=l;G[c+4>>2]=l>>31;b=b+(k+128|0)|0;c=G[d+e>>2];G[b>>2]=c;G[b+4>>2]=c>>31}K[k+352>>2]=g;md(a,42,k+32|0,k+128|0,f,1,k+352|0,h,0,i,j);break a}if((Dc(a,k+124|0,j)|0)>0){break a}x=G[k+124>>2];b:{if(!x){s=1;oa=2;q=1;p=1;break b}l=b<<2;s=G[l+f>>2];q=G[e+l>>2];p=G[d+l>>2]}if(i){G[i>>2]=0}G[k+352>>2]=1;G[k+356>>2]=1;l=1;G[k+128>>2]=1;G[k+132>>2]=0;G[k+304>>2]=1;G[k+308>>2]=1;G[k+256>>2]=1;G[k+260>>2]=1;G[k+136>>2]=1;G[k+140>>2]=0;G[k+208>>2]=1;G[k+212>>2]=1;G[k+360>>2]=1;G[k+144>>2]=1;G[k+148>>2]=0;G[k+312>>2]=1;G[k+316>>2]=1;G[k+264>>2]=1;G[k+268>>2]=1;G[k+152>>2]=1;G[k+156>>2]=0;G[k+216>>2]=1;G[k+220>>2]=1;G[k+364>>2]=1;G[k+368>>2]=1;G[k+320>>2]=1;G[k+272>>2]=1;G[k+160>>2]=1;G[k+164>>2]=0;G[k+224>>2]=1;G[k+372>>2]=1;G[k+376>>2]=1;G[k+168>>2]=1;G[k+172>>2]=0;G[k+324>>2]=1;G[k+328>>2]=1;G[k+276>>2]=1;G[k+280>>2]=1;G[k+176>>2]=1;G[k+180>>2]=0;G[k+228>>2]=1;G[k+232>>2]=1;G[k+184>>2]=1;G[k+188>>2]=0;G[k+380>>2]=1;G[k+384>>2]=1;G[k+332>>2]=1;G[k+336>>2]=1;G[k+284>>2]=1;G[k+288>>2]=1;G[k+192>>2]=1;G[k+196>>2]=0;G[k+236>>2]=1;G[k+240>>2]=1;c:{while(1){n=r<<2;u=G[n+e>>2];t=G[d+n>>2];d:{if((u|0)>=(t|0)){w=G[n+(k+208|0)>>2];break d}if(x){break c}G[n+(k+208|0)>>2]=-1;w=-1}G[n+(k+304|0)>>2]=u;G[n+(k+352|0)>>2]=t;G[n+(k+256|0)>>2]=G[f+n>>2];y=k+128|0;u=r+1|0;t=y+(u<<3)|0;n=G[c+n>>2];n=Au(l,o,n,n>>31);G[t>>2]=n;Q=t;t=Ia;G[Q+4>>2]=t;r=y+(r<<3)|0;Eb=r,Fb=Au(l,o,w,w>>31),G[Eb>>2]=Fb;G[r+4>>2]=Ia;l=n;o=t;r=u;if((r|0)!=(b|0)){continue}break}d=(k+128|0)+(b<<3)|0;e=G[d>>2];l=e;e=G[(k+208|0)+(b<<2)>>2];Eb=d,Fb=Au(l,G[d+4>>2],e,e>>31),G[Eb>>2]=Fb;G[d+4>>2]=Ia;e:{if(!((b|0)!=1|G[c>>2]!=1)){v=(q-p|0)/(s|0)|0;q=p;e=s;break e}b=G[k+208>>2];e=M(b,G[k+256>>2]);v=(M(b,G[k+304>>2]-G[k+352>>2]|0)|0)/G[f>>2]|0}if((q|0)<(p|0)){break a}F=G[k+240>>2];pa=M(F,G[k+384>>2]);b=M(F,G[k+336>>2]);if((pa|0)>(b|0)){break a}y=G[k+236>>2];qa=M(y,G[k+380>>2]);c=M(y,G[k+332>>2]);if((qa|0)>(c|0)){break a}z=G[k+232>>2];R=M(z,G[k+376>>2]);d=M(z,G[k+328>>2]);if((R|0)>(d|0)){break a}A=G[k+228>>2];S=M(A,G[k+372>>2]);f=M(A,G[k+324>>2]);if((S|0)>(f|0)){break a}B=G[k+224>>2];T=M(B,G[k+368>>2]);l=M(B,G[k+320>>2]);if((T|0)>(l|0)){break a}C=G[k+220>>2];U=M(C,G[k+364>>2]);o=M(C,G[k+316>>2]);if((U|0)>(o|0)){break a}D=G[k+216>>2];V=M(D,G[k+360>>2]);r=M(D,G[k+312>>2]);if((V|0)>(r|0)){break a}E=G[k+212>>2];W=M(E,G[k+356>>2]);u=M(E,G[k+308>>2]);if((W|0)>(u|0)){break a}H=v+1|0;ya=H>>31;vb=G[k+192>>2];wb=G[k+196>>2];za=G[k+184>>2];Aa=G[k+188>>2];Ba=G[k+176>>2];Ca=G[k+180>>2];Da=G[k+168>>2];Ea=G[k+172>>2];Ga=G[k+160>>2];Ha=G[k+164>>2];Ja=G[k+152>>2];Ka=G[k+156>>2];La=G[k+144>>2];Ma=G[k+148>>2];Na=G[k+136>>2];Oa=G[k+140>>2];n=G[k+352>>2];X=n;Pa=n>>31;xb=q;Qa=q>>31;Ra=s;yb=s>>31;Y=p;Z=p>>31;zb=b;Sa=b>>31;Ab=F>>31;Bb=pa>>31;Ta=c;_=c>>31;Va=y>>31;Cb=qa>>31;Wa=d;$=d>>31;Xa=z>>31;Za=R>>31;_a=f;aa=f>>31;$a=A>>31;ab=S>>31;bb=l;ba=l>>31;cb=B>>31;db=T>>31;eb=o;ca=o>>31;fb=C>>31;gb=U>>31;hb=r;da=r>>31;ib=D>>31;jb=V>>31;kb=u;ea=u>>31;lb=E>>31;Q=W>>31;b=G[k+288>>2];mb=b;Db=b>>31;b=G[k+284>>2];fa=b;nb=b>>31;b=G[k+280>>2];ga=b;ob=b>>31;b=G[k+276>>2];ha=b;pb=b>>31;b=G[k+272>>2];ia=b;qb=b>>31;b=G[k+268>>2];ja=b;rb=b>>31;b=G[k+264>>2];ka=b;sb=b>>31;b=G[k+260>>2];la=b;tb=b>>31;v=0;while(1){ma=pa;ra=Bb;while(1){na=Au(vb,wb,ma-F|0,ra-((F>>>0>ma>>>0)+Ab|0)|0);ub=Ia;c=qa;w=c;d=Cb;x=d;f:{if(i){while(1){I=Au(za,Aa,c-y|0,d-((c>>>0>>0)+Va|0)|0);sa=Ia;f=R;p=Za;while(1){J=Au(Ba,Ca,f-z|0,p-((f>>>0>>0)+Xa|0)|0);ta=Ia;q=S;s=ab;while(1){L=Au(Da,Ea,q-A|0,s-((q>>>0>>0)+$a|0)|0);ua=Ia;r=T;u=db;while(1){N=Au(Ga,Ha,r-B|0,u-((r>>>0>>0)+cb|0)|0);va=Ia;w=U;x=gb;while(1){O=Au(Ja,Ka,w-C|0,x-((w>>>0>>0)+fb|0)|0);wa=Ia;n=V;t=jb;while(1){P=Au(La,Ma,n-D|0,t-((n>>>0>>0)+ib|0)|0);xa=Ia;l=W;o=Q;while(1){m=Au(Na,Oa,l-E|0,o-((l>>>0>>0)+lb|0)|0)+X|0;b=Pa+Ia|0;b=m>>>0>>0?b+1|0:b;m=m+P|0;b=b+xa|0;b=m>>>0

>>0?b+1|0:b;m=m+O|0;b=b+wa|0;b=m>>>0>>0?b+1|0:b;m=m+N|0;b=b+va|0;b=m>>>0>>0?b+1|0:b;m=m+L|0;b=b+ua|0;b=m>>>0>>0?b+1|0:b;m=m+J|0;b=b+ta|0;b=m>>>0>>0?b+1|0:b;m=m+I|0;b=b+sa|0;b=m>>>0>>0?b+1|0:b;m=m+na|0;b=b+ub|0;if((ae(a,oa,Y,Z,m,m>>>0>>0?b+1|0:b,H,ya,e,1,g,(v<<2)+h|0,k+123|0,k+32|0,j)|0)>0){break a}if(G[k+32>>2]){G[i>>2]=1}v=v+H|0;b=o+tb|0;l=l+la|0;b=l>>>0>>0?b+1|0:b;o=b;if(l>>>0<=kb>>>0&(ea|0)>=(b|0)|(b|0)<(ea|0)){continue}break}b=t+sb|0;l=n+ka|0;b=l>>>0>>0?b+1|0:b;n=l;t=b;if(l>>>0<=hb>>>0&(da|0)>=(b|0)|(b|0)<(da|0)){continue}break}b=x+rb|0;l=w+ja|0;b=l>>>0>>0?b+1|0:b;w=l;x=b;if(l>>>0<=eb>>>0&(ca|0)>=(b|0)|(b|0)<(ca|0)){continue}break}b=u+qb|0;l=r+ia|0;b=l>>>0>>0?b+1|0:b;r=l;u=b;if(l>>>0<=bb>>>0&(ba|0)>=(b|0)|(b|0)<(ba|0)){continue}break}b=s+pb|0;l=q+ha|0;b=l>>>0>>0?b+1|0:b;q=l;s=b;if(l>>>0<=_a>>>0&(aa|0)>=(b|0)|(b|0)<(aa|0)){continue}break}b=p+ob|0;f=f+ga|0;b=f>>>0>>0?b+1|0:b;p=b;if(f>>>0<=Wa>>>0&($|0)>=(b|0)|(b|0)<($|0)){continue}break}b=d+nb|0;c=c+fa|0;b=c>>>0>>0?b+1|0:b;d=b;if(c>>>0<=Ta>>>0&(_|0)>=(b|0)|(b|0)<(_|0)){continue}break f}}while(1){I=Au(za,Aa,w-y|0,x-((w>>>0>>0)+Va|0)|0);sa=Ia;f=R;p=Za;while(1){J=Au(Ba,Ca,f-z|0,p-((f>>>0>>0)+Xa|0)|0);ta=Ia;q=S;s=ab;while(1){L=Au(Da,Ea,q-A|0,s-((q>>>0>>0)+$a|0)|0);ua=Ia;r=T;u=db;while(1){N=Au(Ga,Ha,r-B|0,u-((r>>>0>>0)+cb|0)|0);va=Ia;c=U;d=gb;while(1){O=Au(Ja,Ka,c-C|0,d-((c>>>0>>0)+fb|0)|0);wa=Ia;n=V;t=jb;while(1){P=Au(La,Ma,n-D|0,t-((n>>>0>>0)+ib|0)|0);xa=Ia;l=W;o=Q;while(1){m=Au(Na,Oa,l-E|0,o-((l>>>0>>0)+lb|0)|0)+X|0;b=Pa+Ia|0;b=m>>>0>>0?b+1|0:b;m=m+P|0;b=b+xa|0;b=m>>>0

>>0?b+1|0:b;m=m+O|0;b=b+wa|0;b=m>>>0>>0?b+1|0:b;m=m+N|0;b=b+va|0;b=m>>>0>>0?b+1|0:b;m=m+L|0;b=b+ua|0;b=m>>>0>>0?b+1|0:b;m=m+J|0;b=b+ta|0;b=m>>>0>>0?b+1|0:b;m=m+I|0;b=b+sa|0;b=m>>>0>>0?b+1|0:b;m=m+na|0;b=b+ub|0;if((ae(a,oa,Y,Z,m,m>>>0>>0?b+1|0:b,H,ya,e,1,g,(v<<2)+h|0,k+123|0,k+32|0,j)|0)>0){break a}v=v+H|0;b=o+tb|0;l=l+la|0;b=l>>>0>>0?b+1|0:b;o=b;if(l>>>0<=kb>>>0&(ea|0)>=(b|0)|(b|0)<(ea|0)){continue}break}b=t+sb|0;l=n+ka|0;b=l>>>0>>0?b+1|0:b;n=l;t=b;if(l>>>0<=hb>>>0&(da|0)>=(b|0)|(b|0)<(da|0)){continue}break}b=d+rb|0;c=c+ja|0;b=c>>>0>>0?b+1|0:b;d=b;if(c>>>0<=eb>>>0&(ca|0)>=(b|0)|(b|0)<(ca|0)){continue}break}b=u+qb|0;c=r+ia|0;b=c>>>0>>0?b+1|0:b;r=c;u=b;if(c>>>0<=bb>>>0&(ba|0)>=(b|0)|(b|0)<(ba|0)){continue}break}b=s+pb|0;c=q+ha|0;b=c>>>0>>0?b+1|0:b;q=c;s=b;if(c>>>0<=_a>>>0&(aa|0)>=(b|0)|(b|0)<(aa|0)){continue}break}b=p+ob|0;c=f+ga|0;b=c>>>0>>0?b+1|0:b;f=c;p=b;if(c>>>0<=Wa>>>0&($|0)>=(b|0)|(b|0)<($|0)){continue}break}b=x+nb|0;c=w+fa|0;b=c>>>0>>0?b+1|0:b;w=c;x=b;if(c>>>0<=Ta>>>0&(_|0)>=(b|0)|(b|0)<(_|0)){continue}break}}b=ra+Db|0;c=ma+mb|0;b=c>>>0>>0?b+1|0:b;ma=c;ra=b;if(c>>>0<=zb>>>0&(Sa|0)>=(b|0)|(b|0)<(Sa|0)){continue}break}b=Z+yb|0;c=Y+Ra|0;b=c>>>0>>0?b+1|0:b;Y=c;Z=b;if(c>>>0<=xb>>>0&(Qa|0)>=(b|0)|(b|0)<(Qa|0)){continue}break}break a}G[k+16>>2]=r+1;a=k+32|0;Ya(a,81,27149,k+16|0);Ua(a);G[j>>2]=321}Fa=k+400|0}function dq(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,H=0,I=0,J=0,K=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Ga=0,Ha=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Va=0,Wa=0,Xa=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,lb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0,Eb=0,Fb=0;oa=1;k=Fa-400|0;Fa=k;a:{if(b-10>>>0<=4294967286){G[k>>2]=b;a=k+32|0;Ya(a,81,24044,k);Ua(a);G[j>>2]=320;break a}if(Nb(a,j)){if((b|0)!=1){c=b&-2;while(1){l=v<<3;o=k+32|0;p=l+o|0;q=v<<2;s=G[q+d>>2];G[p>>2]=s;G[p+4>>2]=s>>31;p=l;l=k+128|0;p=p+l|0;q=G[e+q>>2];G[p>>2]=q;G[p+4>>2]=q>>31;t=o;o=v|1;p=o<<3;q=t+p|0;o=o<<2;s=G[o+d>>2];G[q>>2]=s;G[q+4>>2]=s>>31;l=l+p|0;o=G[e+o>>2];G[l>>2]=o;G[l+4>>2]=o>>31;v=v+2|0;r=r+2|0;if((c|0)!=(r|0)){continue}break}}if(b&1){b=v<<3;c=b+(k+32|0)|0;l=d;d=v<<2;l=G[l+d>>2];G[c>>2]=l;G[c+4>>2]=l>>31;b=b+(k+128|0)|0;c=G[d+e>>2];G[b>>2]=c;G[b+4>>2]=c>>31}L[k+352>>3]=g;md(a,82,k+32|0,k+128|0,f,1,k+352|0,h,0,i,j);break a}if((Dc(a,k+124|0,j)|0)>0){break a}x=G[k+124>>2];b:{if(!x){s=1;oa=2;q=1;p=1;break b}l=b<<2;s=G[l+f>>2];q=G[e+l>>2];p=G[d+l>>2]}if(i){G[i>>2]=0}G[k+352>>2]=1;G[k+356>>2]=1;l=1;G[k+128>>2]=1;G[k+132>>2]=0;G[k+304>>2]=1;G[k+308>>2]=1;G[k+256>>2]=1;G[k+260>>2]=1;G[k+136>>2]=1;G[k+140>>2]=0;G[k+208>>2]=1;G[k+212>>2]=1;G[k+360>>2]=1;G[k+144>>2]=1;G[k+148>>2]=0;G[k+312>>2]=1;G[k+316>>2]=1;G[k+264>>2]=1;G[k+268>>2]=1;G[k+152>>2]=1;G[k+156>>2]=0;G[k+216>>2]=1;G[k+220>>2]=1;G[k+364>>2]=1;G[k+368>>2]=1;G[k+320>>2]=1;G[k+272>>2]=1;G[k+160>>2]=1;G[k+164>>2]=0;G[k+224>>2]=1;G[k+372>>2]=1;G[k+376>>2]=1;G[k+168>>2]=1;G[k+172>>2]=0;G[k+324>>2]=1;G[k+328>>2]=1;G[k+276>>2]=1;G[k+280>>2]=1;G[k+176>>2]=1;G[k+180>>2]=0;G[k+228>>2]=1;G[k+232>>2]=1;G[k+184>>2]=1;G[k+188>>2]=0;G[k+380>>2]=1;G[k+384>>2]=1;G[k+332>>2]=1;G[k+336>>2]=1;G[k+284>>2]=1;G[k+288>>2]=1;G[k+192>>2]=1;G[k+196>>2]=0;G[k+236>>2]=1;G[k+240>>2]=1;c:{while(1){n=r<<2;u=G[n+e>>2];t=G[d+n>>2];d:{if((u|0)>=(t|0)){w=G[n+(k+208|0)>>2];break d}if(x){break c}G[n+(k+208|0)>>2]=-1;w=-1}G[n+(k+304|0)>>2]=u;G[n+(k+352|0)>>2]=t;G[n+(k+256|0)>>2]=G[f+n>>2];y=k+128|0;u=r+1|0;t=y+(u<<3)|0;n=G[c+n>>2];n=Au(l,o,n,n>>31);G[t>>2]=n;Q=t;t=Ia;G[Q+4>>2]=t;r=y+(r<<3)|0;Eb=r,Fb=Au(l,o,w,w>>31),G[Eb>>2]=Fb;G[r+4>>2]=Ia;l=n;o=t;r=u;if((r|0)!=(b|0)){continue}break}d=(k+128|0)+(b<<3)|0;e=G[d>>2];l=e;e=G[(k+208|0)+(b<<2)>>2];Eb=d,Fb=Au(l,G[d+4>>2],e,e>>31),G[Eb>>2]=Fb;G[d+4>>2]=Ia;e:{if(!((b|0)!=1|G[c>>2]!=1)){v=(q-p|0)/(s|0)|0;q=p;e=s;break e}b=G[k+208>>2];e=M(b,G[k+256>>2]);v=(M(b,G[k+304>>2]-G[k+352>>2]|0)|0)/G[f>>2]|0}if((q|0)<(p|0)){break a}F=G[k+240>>2];pa=M(F,G[k+384>>2]);b=M(F,G[k+336>>2]);if((pa|0)>(b|0)){break a}y=G[k+236>>2];qa=M(y,G[k+380>>2]);c=M(y,G[k+332>>2]);if((qa|0)>(c|0)){break a}z=G[k+232>>2];R=M(z,G[k+376>>2]);d=M(z,G[k+328>>2]);if((R|0)>(d|0)){break a}A=G[k+228>>2];S=M(A,G[k+372>>2]);f=M(A,G[k+324>>2]);if((S|0)>(f|0)){break a}B=G[k+224>>2];T=M(B,G[k+368>>2]);l=M(B,G[k+320>>2]);if((T|0)>(l|0)){break a}C=G[k+220>>2];U=M(C,G[k+364>>2]);o=M(C,G[k+316>>2]);if((U|0)>(o|0)){break a}D=G[k+216>>2];V=M(D,G[k+360>>2]);r=M(D,G[k+312>>2]);if((V|0)>(r|0)){break a}E=G[k+212>>2];W=M(E,G[k+356>>2]);u=M(E,G[k+308>>2]);if((W|0)>(u|0)){break a}H=v+1|0;ya=H>>31;vb=G[k+192>>2];wb=G[k+196>>2];za=G[k+184>>2];Aa=G[k+188>>2];Ba=G[k+176>>2];Ca=G[k+180>>2];Da=G[k+168>>2];Ea=G[k+172>>2];Ga=G[k+160>>2];Ha=G[k+164>>2];Ja=G[k+152>>2];Ka=G[k+156>>2];La=G[k+144>>2];Ma=G[k+148>>2];Na=G[k+136>>2];Oa=G[k+140>>2];n=G[k+352>>2];X=n;Pa=n>>31;xb=q;Qa=q>>31;Ra=s;yb=s>>31;Y=p;Z=p>>31;zb=b;Sa=b>>31;Ab=F>>31;Bb=pa>>31;Ta=c;_=c>>31;Va=y>>31;Cb=qa>>31;Wa=d;$=d>>31;Xa=z>>31;Za=R>>31;_a=f;aa=f>>31;$a=A>>31;ab=S>>31;bb=l;ba=l>>31;cb=B>>31;db=T>>31;eb=o;ca=o>>31;fb=C>>31;gb=U>>31;hb=r;da=r>>31;ib=D>>31;jb=V>>31;kb=u;ea=u>>31;lb=E>>31;Q=W>>31;b=G[k+288>>2];mb=b;Db=b>>31;b=G[k+284>>2];fa=b;nb=b>>31;b=G[k+280>>2];ga=b;ob=b>>31;b=G[k+276>>2];ha=b;pb=b>>31;b=G[k+272>>2];ia=b;qb=b>>31;b=G[k+268>>2];ja=b;rb=b>>31;b=G[k+264>>2];ka=b;sb=b>>31;b=G[k+260>>2];la=b;tb=b>>31;v=0;while(1){ma=pa;ra=Bb;while(1){na=Au(vb,wb,ma-F|0,ra-((F>>>0>ma>>>0)+Ab|0)|0);ub=Ia;c=qa;w=c;d=Cb;x=d;f:{if(i){while(1){I=Au(za,Aa,c-y|0,d-((c>>>0>>0)+Va|0)|0);sa=Ia;f=R;p=Za;while(1){J=Au(Ba,Ca,f-z|0,p-((f>>>0>>0)+Xa|0)|0);ta=Ia;q=S;s=ab;while(1){K=Au(Da,Ea,q-A|0,s-((q>>>0>>0)+$a|0)|0);ua=Ia;r=T;u=db;while(1){N=Au(Ga,Ha,r-B|0,u-((r>>>0>>0)+cb|0)|0);va=Ia;w=U;x=gb;while(1){O=Au(Ja,Ka,w-C|0,x-((w>>>0>>0)+fb|0)|0);wa=Ia;n=V;t=jb;while(1){P=Au(La,Ma,n-D|0,t-((n>>>0>>0)+ib|0)|0);xa=Ia;l=W;o=Q;while(1){m=Au(Na,Oa,l-E|0,o-((l>>>0>>0)+lb|0)|0)+X|0;b=Pa+Ia|0;b=m>>>0>>0?b+1|0:b;m=m+P|0;b=b+xa|0;b=m>>>0

>>0?b+1|0:b;m=m+O|0;b=b+wa|0;b=m>>>0>>0?b+1|0:b;m=m+N|0;b=b+va|0;b=m>>>0>>0?b+1|0:b;m=m+K|0;b=b+ua|0;b=m>>>0>>0?b+1|0:b;m=m+J|0;b=b+ta|0;b=m>>>0>>0?b+1|0:b;m=m+I|0;b=b+sa|0;b=m>>>0>>0?b+1|0:b;m=m+na|0;b=b+ub|0;if((Id(a,oa,Y,Z,m,m>>>0>>0?b+1|0:b,H,ya,e,1,g,(v<<3)+h|0,k+123|0,k+32|0,j)|0)>0){break a}if(G[k+32>>2]){G[i>>2]=1}v=v+H|0;b=o+tb|0;l=l+la|0;b=l>>>0>>0?b+1|0:b;o=b;if(l>>>0<=kb>>>0&(ea|0)>=(b|0)|(b|0)<(ea|0)){continue}break}b=t+sb|0;l=n+ka|0;b=l>>>0>>0?b+1|0:b;n=l;t=b;if(l>>>0<=hb>>>0&(da|0)>=(b|0)|(b|0)<(da|0)){continue}break}b=x+rb|0;l=w+ja|0;b=l>>>0>>0?b+1|0:b;w=l;x=b;if(l>>>0<=eb>>>0&(ca|0)>=(b|0)|(b|0)<(ca|0)){continue}break}b=u+qb|0;l=r+ia|0;b=l>>>0>>0?b+1|0:b;r=l;u=b;if(l>>>0<=bb>>>0&(ba|0)>=(b|0)|(b|0)<(ba|0)){continue}break}b=s+pb|0;l=q+ha|0;b=l>>>0>>0?b+1|0:b;q=l;s=b;if(l>>>0<=_a>>>0&(aa|0)>=(b|0)|(b|0)<(aa|0)){continue}break}b=p+ob|0;f=f+ga|0;b=f>>>0>>0?b+1|0:b;p=b;if(f>>>0<=Wa>>>0&($|0)>=(b|0)|(b|0)<($|0)){continue}break}b=d+nb|0;c=c+fa|0;b=c>>>0>>0?b+1|0:b;d=b;if(c>>>0<=Ta>>>0&(_|0)>=(b|0)|(b|0)<(_|0)){continue}break f}}while(1){I=Au(za,Aa,w-y|0,x-((w>>>0>>0)+Va|0)|0);sa=Ia;f=R;p=Za;while(1){J=Au(Ba,Ca,f-z|0,p-((f>>>0>>0)+Xa|0)|0);ta=Ia;q=S;s=ab;while(1){K=Au(Da,Ea,q-A|0,s-((q>>>0>>0)+$a|0)|0);ua=Ia;r=T;u=db;while(1){N=Au(Ga,Ha,r-B|0,u-((r>>>0>>0)+cb|0)|0);va=Ia;c=U;d=gb;while(1){O=Au(Ja,Ka,c-C|0,d-((c>>>0>>0)+fb|0)|0);wa=Ia;n=V;t=jb;while(1){P=Au(La,Ma,n-D|0,t-((n>>>0>>0)+ib|0)|0);xa=Ia;l=W;o=Q;while(1){m=Au(Na,Oa,l-E|0,o-((l>>>0>>0)+lb|0)|0)+X|0;b=Pa+Ia|0;b=m>>>0>>0?b+1|0:b;m=m+P|0;b=b+xa|0;b=m>>>0

>>0?b+1|0:b;m=m+O|0;b=b+wa|0;b=m>>>0>>0?b+1|0:b;m=m+N|0;b=b+va|0;b=m>>>0>>0?b+1|0:b;m=m+K|0;b=b+ua|0;b=m>>>0>>0?b+1|0:b;m=m+J|0;b=b+ta|0;b=m>>>0>>0?b+1|0:b;m=m+I|0;b=b+sa|0;b=m>>>0>>0?b+1|0:b;m=m+na|0;b=b+ub|0;if((Id(a,oa,Y,Z,m,m>>>0>>0?b+1|0:b,H,ya,e,1,g,(v<<3)+h|0,k+123|0,k+32|0,j)|0)>0){break a}v=v+H|0;b=o+tb|0;l=l+la|0;b=l>>>0>>0?b+1|0:b;o=b;if(l>>>0<=kb>>>0&(ea|0)>=(b|0)|(b|0)<(ea|0)){continue}break}b=t+sb|0;l=n+ka|0;b=l>>>0>>0?b+1|0:b;n=l;t=b;if(l>>>0<=hb>>>0&(da|0)>=(b|0)|(b|0)<(da|0)){continue}break}b=d+rb|0;c=c+ja|0;b=c>>>0>>0?b+1|0:b;d=b;if(c>>>0<=eb>>>0&(ca|0)>=(b|0)|(b|0)<(ca|0)){continue}break}b=u+qb|0;c=r+ia|0;b=c>>>0>>0?b+1|0:b;r=c;u=b;if(c>>>0<=bb>>>0&(ba|0)>=(b|0)|(b|0)<(ba|0)){continue}break}b=s+pb|0;c=q+ha|0;b=c>>>0>>0?b+1|0:b;q=c;s=b;if(c>>>0<=_a>>>0&(aa|0)>=(b|0)|(b|0)<(aa|0)){continue}break}b=p+ob|0;c=f+ga|0;b=c>>>0>>0?b+1|0:b;f=c;p=b;if(c>>>0<=Wa>>>0&($|0)>=(b|0)|(b|0)<($|0)){continue}break}b=x+nb|0;c=w+fa|0;b=c>>>0>>0?b+1|0:b;w=c;x=b;if(c>>>0<=Ta>>>0&(_|0)>=(b|0)|(b|0)<(_|0)){continue}break}}b=ra+Db|0;c=ma+mb|0;b=c>>>0>>0?b+1|0:b;ma=c;ra=b;if(c>>>0<=zb>>>0&(Sa|0)>=(b|0)|(b|0)<(Sa|0)){continue}break}b=Z+yb|0;c=Y+Ra|0;b=c>>>0>>0?b+1|0:b;Y=c;Z=b;if(c>>>0<=xb>>>0&(Qa|0)>=(b|0)|(b|0)<(Qa|0)){continue}break}break a}G[k+16>>2]=r+1;a=k+32|0;Ya(a,81,27194,k+16|0);Ua(a);G[j>>2]=321}Fa=k+400|0}function Mp(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,H=0,I=0,J=0,K=0,L=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Ga=0,Ha=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Va=0,Wa=0,Xa=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,lb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0,Eb=0;na=1;j=Fa-400|0;Fa=j;a:{if(b-10>>>0<=4294967286){G[j>>2]=b;a=j+32|0;Ya(a,81,23908,j);Ua(a);G[i>>2]=320;break a}if(Nb(a,i)){if((b|0)!=1){c=b&-2;while(1){k=u<<3;n=j+32|0;o=k+n|0;p=u<<2;r=G[p+d>>2];G[o>>2]=r;G[o+4>>2]=r>>31;o=k;k=j+128|0;o=o+k|0;p=G[e+p>>2];G[o>>2]=p;G[o+4>>2]=p>>31;s=n;n=u|1;o=n<<3;p=s+o|0;n=n<<2;r=G[n+d>>2];G[p>>2]=r;G[p+4>>2]=r>>31;k=k+o|0;n=G[e+n>>2];G[k>>2]=n;G[k+4>>2]=n>>31;u=u+2|0;q=q+2|0;if((c|0)!=(q|0)){continue}break}}if(b&1){b=u<<3;c=b+(j+32|0)|0;k=d;d=u<<2;k=G[k+d>>2];G[c>>2]=k;G[c+4>>2]=k>>31;b=b+(j+128|0)|0;c=G[d+e>>2];G[b>>2]=c;G[b+4>>2]=c>>31}F[j+352>>1]=0;md(a,21,j+32|0,j+128|0,f,1,j+352|0,g,0,h,i);break a}if((Dc(a,j+124|0,i)|0)>0){break a}w=G[j+124>>2];b:{if(!w){r=1;na=2;p=1;o=1;break b}k=b<<2;r=G[k+f>>2];p=G[e+k>>2];o=G[d+k>>2]}if(h){G[h>>2]=0}G[j+352>>2]=1;G[j+356>>2]=1;k=1;G[j+128>>2]=1;G[j+132>>2]=0;G[j+304>>2]=1;G[j+308>>2]=1;G[j+256>>2]=1;G[j+260>>2]=1;G[j+136>>2]=1;G[j+140>>2]=0;G[j+208>>2]=1;G[j+212>>2]=1;G[j+360>>2]=1;G[j+144>>2]=1;G[j+148>>2]=0;G[j+312>>2]=1;G[j+316>>2]=1;G[j+264>>2]=1;G[j+268>>2]=1;G[j+152>>2]=1;G[j+156>>2]=0;G[j+216>>2]=1;G[j+220>>2]=1;G[j+364>>2]=1;G[j+368>>2]=1;G[j+320>>2]=1;G[j+272>>2]=1;G[j+160>>2]=1;G[j+164>>2]=0;G[j+224>>2]=1;G[j+372>>2]=1;G[j+376>>2]=1;G[j+168>>2]=1;G[j+172>>2]=0;G[j+324>>2]=1;G[j+328>>2]=1;G[j+276>>2]=1;G[j+280>>2]=1;G[j+176>>2]=1;G[j+180>>2]=0;G[j+228>>2]=1;G[j+232>>2]=1;G[j+184>>2]=1;G[j+188>>2]=0;G[j+380>>2]=1;G[j+384>>2]=1;G[j+332>>2]=1;G[j+336>>2]=1;G[j+284>>2]=1;G[j+288>>2]=1;G[j+192>>2]=1;G[j+196>>2]=0;G[j+236>>2]=1;G[j+240>>2]=1;c:{while(1){m=q<<2;t=G[m+e>>2];s=G[d+m>>2];d:{if((t|0)>=(s|0)){v=G[m+(j+208|0)>>2];break d}if(w){break c}G[m+(j+208|0)>>2]=-1;v=-1}G[m+(j+304|0)>>2]=t;G[m+(j+352|0)>>2]=s;G[m+(j+256|0)>>2]=G[f+m>>2];x=j+128|0;t=q+1|0;s=x+(t<<3)|0;m=G[c+m>>2];m=Au(k,n,m,m>>31);G[s>>2]=m;P=s;s=Ia;G[P+4>>2]=s;q=x+(q<<3)|0;Db=q,Eb=Au(k,n,v,v>>31),G[Db>>2]=Eb;G[q+4>>2]=Ia;k=m;n=s;q=t;if((q|0)!=(b|0)){continue}break}d=(j+128|0)+(b<<3)|0;e=G[d>>2];k=e;e=G[(j+208|0)+(b<<2)>>2];Db=d,Eb=Au(k,G[d+4>>2],e,e>>31),G[Db>>2]=Eb;G[d+4>>2]=Ia;e:{if(!((b|0)!=1|G[c>>2]!=1)){u=(p-o|0)/(r|0)|0;p=o;e=r;break e}b=G[j+208>>2];e=M(b,G[j+256>>2]);u=(M(b,G[j+304>>2]-G[j+352>>2]|0)|0)/G[f>>2]|0}if((p|0)<(o|0)){break a}E=G[j+240>>2];oa=M(E,G[j+384>>2]);b=M(E,G[j+336>>2]);if((oa|0)>(b|0)){break a}x=G[j+236>>2];pa=M(x,G[j+380>>2]);c=M(x,G[j+332>>2]);if((pa|0)>(c|0)){break a}y=G[j+232>>2];Q=M(y,G[j+376>>2]);d=M(y,G[j+328>>2]);if((Q|0)>(d|0)){break a}z=G[j+228>>2];R=M(z,G[j+372>>2]);f=M(z,G[j+324>>2]);if((R|0)>(f|0)){break a}A=G[j+224>>2];S=M(A,G[j+368>>2]);k=M(A,G[j+320>>2]);if((S|0)>(k|0)){break a}B=G[j+220>>2];T=M(B,G[j+364>>2]);n=M(B,G[j+316>>2]);if((T|0)>(n|0)){break a}C=G[j+216>>2];U=M(C,G[j+360>>2]);q=M(C,G[j+312>>2]);if((U|0)>(q|0)){break a}D=G[j+212>>2];V=M(D,G[j+356>>2]);t=M(D,G[j+308>>2]);if((V|0)>(t|0)){break a}H=u+1|0;xa=H>>31;ub=G[j+192>>2];vb=G[j+196>>2];ya=G[j+184>>2];za=G[j+188>>2];Aa=G[j+176>>2];Ba=G[j+180>>2];Ca=G[j+168>>2];Da=G[j+172>>2];Ea=G[j+160>>2];Ga=G[j+164>>2];Ha=G[j+152>>2];Ja=G[j+156>>2];Ka=G[j+144>>2];La=G[j+148>>2];Ma=G[j+136>>2];Na=G[j+140>>2];m=G[j+352>>2];W=m;Oa=m>>31;wb=p;Pa=p>>31;Qa=r;xb=r>>31;X=o;Y=o>>31;yb=b;Ra=b>>31;zb=E>>31;Ab=oa>>31;Sa=c;Z=c>>31;Ta=x>>31;Bb=pa>>31;Va=d;_=d>>31;Wa=y>>31;Xa=Q>>31;Za=f;$=f>>31;_a=z>>31;$a=R>>31;ab=k;aa=k>>31;bb=A>>31;cb=S>>31;db=n;ba=n>>31;eb=B>>31;fb=T>>31;gb=q;ca=q>>31;hb=C>>31;ib=U>>31;jb=t;da=t>>31;kb=D>>31;P=V>>31;b=G[j+288>>2];lb=b;Cb=b>>31;b=G[j+284>>2];ea=b;mb=b>>31;b=G[j+280>>2];fa=b;nb=b>>31;b=G[j+276>>2];ga=b;ob=b>>31;b=G[j+272>>2];ha=b;pb=b>>31;b=G[j+268>>2];ia=b;qb=b>>31;b=G[j+264>>2];ja=b;rb=b>>31;b=G[j+260>>2];ka=b;sb=b>>31;u=0;while(1){la=oa;qa=Ab;while(1){ma=Au(ub,vb,la-E|0,qa-((E>>>0>la>>>0)+zb|0)|0);tb=Ia;c=pa;v=c;d=Bb;w=d;f:{if(h){while(1){I=Au(ya,za,c-x|0,d-((c>>>0>>0)+Ta|0)|0);ra=Ia;f=Q;o=Xa;while(1){J=Au(Aa,Ba,f-y|0,o-((f>>>0>>0)+Wa|0)|0);sa=Ia;p=R;r=$a;while(1){K=Au(Ca,Da,p-z|0,r-((p>>>0>>0)+_a|0)|0);ta=Ia;q=S;t=cb;while(1){L=Au(Ea,Ga,q-A|0,t-((q>>>0>>0)+bb|0)|0);ua=Ia;v=T;w=fb;while(1){N=Au(Ha,Ja,v-B|0,w-((v>>>0>>0)+eb|0)|0);va=Ia;m=U;s=ib;while(1){O=Au(Ka,La,m-C|0,s-((m>>>0>>0)+hb|0)|0);wa=Ia;k=V;n=P;while(1){l=Au(Ma,Na,k-D|0,n-((k>>>0>>0)+kb|0)|0)+W|0;b=Oa+Ia|0;b=l>>>0>>0?b+1|0:b;l=l+O|0;b=b+wa|0;b=l>>>0>>0?b+1|0:b;l=l+N|0;b=b+va|0;b=l>>>0>>0?b+1|0:b;l=l+L|0;b=b+ua|0;b=l>>>0>>0?b+1|0:b;l=l+K|0;b=b+ta|0;b=l>>>0>>0?b+1|0:b;l=l+J|0;b=b+sa|0;b=l>>>0>>0?b+1|0:b;l=l+I|0;b=b+ra|0;b=l>>>0>>0?b+1|0:b;l=l+ma|0;b=b+tb|0;if((jf(a,na,X,Y,l,l>>>0>>0?b+1|0:b,H,xa,e,1,0,(u<<1)+g|0,j+123|0,j+32|0,i)|0)>0){break a}if(G[j+32>>2]){G[h>>2]=1}u=u+H|0;b=n+sb|0;k=k+ka|0;b=k>>>0>>0?b+1|0:b;n=b;if(k>>>0<=jb>>>0&(da|0)>=(b|0)|(b|0)<(da|0)){continue}break}b=s+rb|0;k=m+ja|0;b=k>>>0>>0?b+1|0:b;m=k;s=b;if(k>>>0<=gb>>>0&(ca|0)>=(b|0)|(b|0)<(ca|0)){continue}break}b=w+qb|0;k=v+ia|0;b=k>>>0>>0?b+1|0:b;v=k;w=b;if(k>>>0<=db>>>0&(ba|0)>=(b|0)|(b|0)<(ba|0)){continue}break}b=t+pb|0;k=q+ha|0;b=k>>>0>>0?b+1|0:b;q=k;t=b;if(k>>>0<=ab>>>0&(aa|0)>=(b|0)|(b|0)<(aa|0)){continue}break}b=r+ob|0;k=p+ga|0;b=k>>>0>>0?b+1|0:b;p=k;r=b;if(k>>>0<=Za>>>0&($|0)>=(b|0)|(b|0)<($|0)){continue}break}b=o+nb|0;f=f+fa|0;b=f>>>0>>0?b+1|0:b;o=b;if(f>>>0<=Va>>>0&(_|0)>=(b|0)|(b|0)<(_|0)){continue}break}b=d+mb|0;c=c+ea|0;b=c>>>0>>0?b+1|0:b;d=b;if(c>>>0<=Sa>>>0&(Z|0)>=(b|0)|(b|0)<(Z|0)){continue}break f}}while(1){I=Au(ya,za,v-x|0,w-((v>>>0>>0)+Ta|0)|0);ra=Ia;f=Q;o=Xa;while(1){J=Au(Aa,Ba,f-y|0,o-((f>>>0>>0)+Wa|0)|0);sa=Ia;p=R;r=$a;while(1){K=Au(Ca,Da,p-z|0,r-((p>>>0>>0)+_a|0)|0);ta=Ia;q=S;t=cb;while(1){L=Au(Ea,Ga,q-A|0,t-((q>>>0>>0)+bb|0)|0);ua=Ia;c=T;d=fb;while(1){N=Au(Ha,Ja,c-B|0,d-((c>>>0>>0)+eb|0)|0);va=Ia;m=U;s=ib;while(1){O=Au(Ka,La,m-C|0,s-((m>>>0>>0)+hb|0)|0);wa=Ia;k=V;n=P;while(1){l=Au(Ma,Na,k-D|0,n-((k>>>0>>0)+kb|0)|0)+W|0;b=Oa+Ia|0;b=l>>>0>>0?b+1|0:b;l=l+O|0;b=b+wa|0;b=l>>>0>>0?b+1|0:b;l=l+N|0;b=b+va|0;b=l>>>0>>0?b+1|0:b;l=l+L|0;b=b+ua|0;b=l>>>0>>0?b+1|0:b;l=l+K|0;b=b+ta|0;b=l>>>0>>0?b+1|0:b;l=l+J|0;b=b+sa|0;b=l>>>0>>0?b+1|0:b;l=l+I|0;b=b+ra|0;b=l>>>0>>0?b+1|0:b;l=l+ma|0;b=b+tb|0;if((jf(a,na,X,Y,l,l>>>0>>0?b+1|0:b,H,xa,e,1,0,(u<<1)+g|0,j+123|0,j+32|0,i)|0)>0){break a}u=u+H|0;b=n+sb|0;k=k+ka|0;b=k>>>0>>0?b+1|0:b;n=b;if(k>>>0<=jb>>>0&(da|0)>=(b|0)|(b|0)<(da|0)){continue}break}b=s+rb|0;k=m+ja|0;b=k>>>0>>0?b+1|0:b;m=k;s=b;if(k>>>0<=gb>>>0&(ca|0)>=(b|0)|(b|0)<(ca|0)){continue}break}b=d+qb|0;c=c+ia|0;b=c>>>0>>0?b+1|0:b;d=b;if(c>>>0<=db>>>0&(ba|0)>=(b|0)|(b|0)<(ba|0)){continue}break}b=t+pb|0;c=q+ha|0;b=c>>>0>>0?b+1|0:b;q=c;t=b;if(c>>>0<=ab>>>0&(aa|0)>=(b|0)|(b|0)<(aa|0)){continue}break}b=r+ob|0;c=p+ga|0;b=c>>>0>>0?b+1|0:b;p=c;r=b;if(c>>>0<=Za>>>0&($|0)>=(b|0)|(b|0)<($|0)){continue}break}b=o+nb|0;c=f+fa|0;b=c>>>0>>0?b+1|0:b;f=c;o=b;if(c>>>0<=Va>>>0&(_|0)>=(b|0)|(b|0)<(_|0)){continue}break}b=w+mb|0;c=v+ea|0;b=c>>>0>>0?b+1|0:b;v=c;w=b;if(c>>>0<=Sa>>>0&(Z|0)>=(b|0)|(b|0)<(Z|0)){continue}break}}b=qa+Cb|0;c=la+lb|0;b=c>>>0>>0?b+1|0:b;la=c;qa=b;if(c>>>0<=yb>>>0&(Ra|0)>=(b|0)|(b|0)<(Ra|0)){continue}break}b=Y+xb|0;c=X+Qa|0;b=c>>>0>>0?b+1|0:b;X=c;Y=b;if(c>>>0<=wb>>>0&(Pa|0)>=(b|0)|(b|0)<(Pa|0)){continue}break}break a}G[j+16>>2]=q+1;a=j+32|0;Ya(a,81,27058,j+16|0);Ua(a);G[i>>2]=321}Fa=j+400|0}function rp(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,H=0,I=0,J=0,K=0,L=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Ga=0,Ha=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Va=0,Wa=0,Xa=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,lb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0,Eb=0;na=1;j=Fa-400|0;Fa=j;a:{if(b-10>>>0<=4294967286){G[j>>2]=b;a=j+32|0;Ya(a,81,24089,j);Ua(a);G[i>>2]=320;break a}if(Nb(a,i)){if((b|0)!=1){c=b&-2;while(1){k=u<<3;n=j+32|0;o=k+n|0;p=u<<2;r=G[p+d>>2];G[o>>2]=r;G[o+4>>2]=r>>31;o=k;k=j+128|0;o=o+k|0;p=G[e+p>>2];G[o>>2]=p;G[o+4>>2]=p>>31;s=n;n=u|1;o=n<<3;p=s+o|0;n=n<<2;r=G[n+d>>2];G[p>>2]=r;G[p+4>>2]=r>>31;k=k+o|0;n=G[e+n>>2];G[k>>2]=n;G[k+4>>2]=n>>31;u=u+2|0;q=q+2|0;if((c|0)!=(q|0)){continue}break}}if(b&1){b=u<<3;c=b+(j+32|0)|0;k=d;d=u<<2;k=G[k+d>>2];G[c>>2]=k;G[c+4>>2]=k>>31;b=b+(j+128|0)|0;c=G[d+e>>2];G[b>>2]=c;G[b+4>>2]=c>>31}E[j+352|0]=0;md(a,11,j+32|0,j+128|0,f,1,j+352|0,g,0,h,i);break a}if((Dc(a,j+124|0,i)|0)>0){break a}w=G[j+124>>2];b:{if(!w){r=1;na=2;p=1;o=1;break b}k=b<<2;r=G[k+f>>2];p=G[e+k>>2];o=G[d+k>>2]}if(h){G[h>>2]=0}G[j+352>>2]=1;G[j+356>>2]=1;k=1;G[j+128>>2]=1;G[j+132>>2]=0;G[j+304>>2]=1;G[j+308>>2]=1;G[j+256>>2]=1;G[j+260>>2]=1;G[j+136>>2]=1;G[j+140>>2]=0;G[j+208>>2]=1;G[j+212>>2]=1;G[j+360>>2]=1;G[j+144>>2]=1;G[j+148>>2]=0;G[j+312>>2]=1;G[j+316>>2]=1;G[j+264>>2]=1;G[j+268>>2]=1;G[j+152>>2]=1;G[j+156>>2]=0;G[j+216>>2]=1;G[j+220>>2]=1;G[j+364>>2]=1;G[j+368>>2]=1;G[j+320>>2]=1;G[j+272>>2]=1;G[j+160>>2]=1;G[j+164>>2]=0;G[j+224>>2]=1;G[j+372>>2]=1;G[j+376>>2]=1;G[j+168>>2]=1;G[j+172>>2]=0;G[j+324>>2]=1;G[j+328>>2]=1;G[j+276>>2]=1;G[j+280>>2]=1;G[j+176>>2]=1;G[j+180>>2]=0;G[j+228>>2]=1;G[j+232>>2]=1;G[j+184>>2]=1;G[j+188>>2]=0;G[j+380>>2]=1;G[j+384>>2]=1;G[j+332>>2]=1;G[j+336>>2]=1;G[j+284>>2]=1;G[j+288>>2]=1;G[j+192>>2]=1;G[j+196>>2]=0;G[j+236>>2]=1;G[j+240>>2]=1;c:{while(1){m=q<<2;t=G[m+e>>2];s=G[d+m>>2];d:{if((t|0)>=(s|0)){v=G[m+(j+208|0)>>2];break d}if(w){break c}G[m+(j+208|0)>>2]=-1;v=-1}G[m+(j+304|0)>>2]=t;G[m+(j+352|0)>>2]=s;G[m+(j+256|0)>>2]=G[f+m>>2];x=j+128|0;t=q+1|0;s=x+(t<<3)|0;m=G[c+m>>2];m=Au(k,n,m,m>>31);G[s>>2]=m;P=s;s=Ia;G[P+4>>2]=s;q=x+(q<<3)|0;Db=q,Eb=Au(k,n,v,v>>31),G[Db>>2]=Eb;G[q+4>>2]=Ia;k=m;n=s;q=t;if((q|0)!=(b|0)){continue}break}d=(j+128|0)+(b<<3)|0;e=G[d>>2];k=e;e=G[(j+208|0)+(b<<2)>>2];Db=d,Eb=Au(k,G[d+4>>2],e,e>>31),G[Db>>2]=Eb;G[d+4>>2]=Ia;e:{if(!((b|0)!=1|G[c>>2]!=1)){u=(p-o|0)/(r|0)|0;p=o;e=r;break e}b=G[j+208>>2];e=M(b,G[j+256>>2]);u=(M(b,G[j+304>>2]-G[j+352>>2]|0)|0)/G[f>>2]|0}if((p|0)<(o|0)){break a}F=G[j+240>>2];oa=M(F,G[j+384>>2]);b=M(F,G[j+336>>2]);if((oa|0)>(b|0)){break a}x=G[j+236>>2];pa=M(x,G[j+380>>2]);c=M(x,G[j+332>>2]);if((pa|0)>(c|0)){break a}y=G[j+232>>2];Q=M(y,G[j+376>>2]);d=M(y,G[j+328>>2]);if((Q|0)>(d|0)){break a}z=G[j+228>>2];R=M(z,G[j+372>>2]);f=M(z,G[j+324>>2]);if((R|0)>(f|0)){break a}A=G[j+224>>2];S=M(A,G[j+368>>2]);k=M(A,G[j+320>>2]);if((S|0)>(k|0)){break a}B=G[j+220>>2];T=M(B,G[j+364>>2]);n=M(B,G[j+316>>2]);if((T|0)>(n|0)){break a}C=G[j+216>>2];U=M(C,G[j+360>>2]);q=M(C,G[j+312>>2]);if((U|0)>(q|0)){break a}D=G[j+212>>2];V=M(D,G[j+356>>2]);t=M(D,G[j+308>>2]);if((V|0)>(t|0)){break a}H=u+1|0;xa=H>>31;ub=G[j+192>>2];vb=G[j+196>>2];ya=G[j+184>>2];za=G[j+188>>2];Aa=G[j+176>>2];Ba=G[j+180>>2];Ca=G[j+168>>2];Da=G[j+172>>2];Ea=G[j+160>>2];Ga=G[j+164>>2];Ha=G[j+152>>2];Ja=G[j+156>>2];Ka=G[j+144>>2];La=G[j+148>>2];Ma=G[j+136>>2];Na=G[j+140>>2];m=G[j+352>>2];W=m;Oa=m>>31;wb=p;Pa=p>>31;Qa=r;xb=r>>31;X=o;Y=o>>31;yb=b;Ra=b>>31;zb=F>>31;Ab=oa>>31;Sa=c;Z=c>>31;Ta=x>>31;Bb=pa>>31;Va=d;_=d>>31;Wa=y>>31;Xa=Q>>31;Za=f;$=f>>31;_a=z>>31;$a=R>>31;ab=k;aa=k>>31;bb=A>>31;cb=S>>31;db=n;ba=n>>31;eb=B>>31;fb=T>>31;gb=q;ca=q>>31;hb=C>>31;ib=U>>31;jb=t;da=t>>31;kb=D>>31;P=V>>31;b=G[j+288>>2];lb=b;Cb=b>>31;b=G[j+284>>2];ea=b;mb=b>>31;b=G[j+280>>2];fa=b;nb=b>>31;b=G[j+276>>2];ga=b;ob=b>>31;b=G[j+272>>2];ha=b;pb=b>>31;b=G[j+268>>2];ia=b;qb=b>>31;b=G[j+264>>2];ja=b;rb=b>>31;b=G[j+260>>2];ka=b;sb=b>>31;u=0;while(1){la=oa;qa=Ab;while(1){ma=Au(ub,vb,la-F|0,qa-((F>>>0>la>>>0)+zb|0)|0);tb=Ia;c=pa;v=c;d=Bb;w=d;f:{if(h){while(1){I=Au(ya,za,c-x|0,d-((c>>>0>>0)+Ta|0)|0);ra=Ia;f=Q;o=Xa;while(1){J=Au(Aa,Ba,f-y|0,o-((f>>>0>>0)+Wa|0)|0);sa=Ia;p=R;r=$a;while(1){K=Au(Ca,Da,p-z|0,r-((p>>>0>>0)+_a|0)|0);ta=Ia;q=S;t=cb;while(1){L=Au(Ea,Ga,q-A|0,t-((q>>>0>>0)+bb|0)|0);ua=Ia;v=T;w=fb;while(1){N=Au(Ha,Ja,v-B|0,w-((v>>>0>>0)+eb|0)|0);va=Ia;m=U;s=ib;while(1){O=Au(Ka,La,m-C|0,s-((m>>>0>>0)+hb|0)|0);wa=Ia;k=V;n=P;while(1){l=Au(Ma,Na,k-D|0,n-((k>>>0>>0)+kb|0)|0)+W|0;b=Oa+Ia|0;b=l>>>0>>0?b+1|0:b;l=l+O|0;b=b+wa|0;b=l>>>0>>0?b+1|0:b;l=l+N|0;b=b+va|0;b=l>>>0>>0?b+1|0:b;l=l+L|0;b=b+ua|0;b=l>>>0>>0?b+1|0:b;l=l+K|0;b=b+ta|0;b=l>>>0>>0?b+1|0:b;l=l+J|0;b=b+sa|0;b=l>>>0>>0?b+1|0:b;l=l+I|0;b=b+ra|0;b=l>>>0>>0?b+1|0:b;l=l+ma|0;b=b+tb|0;if((Re(a,na,X,Y,l,l>>>0>>0?b+1|0:b,H,xa,e,1,0,g+u|0,j+123|0,j+32|0,i)|0)>0){break a}if(G[j+32>>2]){G[h>>2]=1}u=u+H|0;b=n+sb|0;k=k+ka|0;b=k>>>0>>0?b+1|0:b;n=b;if(k>>>0<=jb>>>0&(da|0)>=(b|0)|(b|0)<(da|0)){continue}break}b=s+rb|0;k=m+ja|0;b=k>>>0>>0?b+1|0:b;m=k;s=b;if(k>>>0<=gb>>>0&(ca|0)>=(b|0)|(b|0)<(ca|0)){continue}break}b=w+qb|0;k=v+ia|0;b=k>>>0>>0?b+1|0:b;v=k;w=b;if(k>>>0<=db>>>0&(ba|0)>=(b|0)|(b|0)<(ba|0)){continue}break}b=t+pb|0;k=q+ha|0;b=k>>>0>>0?b+1|0:b;q=k;t=b;if(k>>>0<=ab>>>0&(aa|0)>=(b|0)|(b|0)<(aa|0)){continue}break}b=r+ob|0;k=p+ga|0;b=k>>>0>>0?b+1|0:b;p=k;r=b;if(k>>>0<=Za>>>0&($|0)>=(b|0)|(b|0)<($|0)){continue}break}b=o+nb|0;f=f+fa|0;b=f>>>0>>0?b+1|0:b;o=b;if(f>>>0<=Va>>>0&(_|0)>=(b|0)|(b|0)<(_|0)){continue}break}b=d+mb|0;c=c+ea|0;b=c>>>0>>0?b+1|0:b;d=b;if(c>>>0<=Sa>>>0&(Z|0)>=(b|0)|(b|0)<(Z|0)){continue}break f}}while(1){I=Au(ya,za,v-x|0,w-((v>>>0>>0)+Ta|0)|0);ra=Ia;f=Q;o=Xa;while(1){J=Au(Aa,Ba,f-y|0,o-((f>>>0>>0)+Wa|0)|0);sa=Ia;p=R;r=$a;while(1){K=Au(Ca,Da,p-z|0,r-((p>>>0>>0)+_a|0)|0);ta=Ia;q=S;t=cb;while(1){L=Au(Ea,Ga,q-A|0,t-((q>>>0>>0)+bb|0)|0);ua=Ia;c=T;d=fb;while(1){N=Au(Ha,Ja,c-B|0,d-((c>>>0>>0)+eb|0)|0);va=Ia;m=U;s=ib;while(1){O=Au(Ka,La,m-C|0,s-((m>>>0>>0)+hb|0)|0);wa=Ia;k=V;n=P;while(1){l=Au(Ma,Na,k-D|0,n-((k>>>0>>0)+kb|0)|0)+W|0;b=Oa+Ia|0;b=l>>>0>>0?b+1|0:b;l=l+O|0;b=b+wa|0;b=l>>>0>>0?b+1|0:b;l=l+N|0;b=b+va|0;b=l>>>0>>0?b+1|0:b;l=l+L|0;b=b+ua|0;b=l>>>0>>0?b+1|0:b;l=l+K|0;b=b+ta|0;b=l>>>0>>0?b+1|0:b;l=l+J|0;b=b+sa|0;b=l>>>0>>0?b+1|0:b;l=l+I|0;b=b+ra|0;b=l>>>0>>0?b+1|0:b;l=l+ma|0;b=b+tb|0;if((Re(a,na,X,Y,l,l>>>0>>0?b+1|0:b,H,xa,e,1,0,g+u|0,j+123|0,j+32|0,i)|0)>0){break a}u=u+H|0;b=n+sb|0;k=k+ka|0;b=k>>>0>>0?b+1|0:b;n=b;if(k>>>0<=jb>>>0&(da|0)>=(b|0)|(b|0)<(da|0)){continue}break}b=s+rb|0;k=m+ja|0;b=k>>>0>>0?b+1|0:b;m=k;s=b;if(k>>>0<=gb>>>0&(ca|0)>=(b|0)|(b|0)<(ca|0)){continue}break}b=d+qb|0;c=c+ia|0;b=c>>>0>>0?b+1|0:b;d=b;if(c>>>0<=db>>>0&(ba|0)>=(b|0)|(b|0)<(ba|0)){continue}break}b=t+pb|0;c=q+ha|0;b=c>>>0>>0?b+1|0:b;q=c;t=b;if(c>>>0<=ab>>>0&(aa|0)>=(b|0)|(b|0)<(aa|0)){continue}break}b=r+ob|0;c=p+ga|0;b=c>>>0>>0?b+1|0:b;p=c;r=b;if(c>>>0<=Za>>>0&($|0)>=(b|0)|(b|0)<($|0)){continue}break}b=o+nb|0;c=f+fa|0;b=c>>>0>>0?b+1|0:b;f=c;o=b;if(c>>>0<=Va>>>0&(_|0)>=(b|0)|(b|0)<(_|0)){continue}break}b=w+mb|0;c=v+ea|0;b=c>>>0>>0?b+1|0:b;v=c;w=b;if(c>>>0<=Sa>>>0&(Z|0)>=(b|0)|(b|0)<(Z|0)){continue}break}}b=qa+Cb|0;c=la+lb|0;b=c>>>0>>0?b+1|0:b;la=c;qa=b;if(c>>>0<=yb>>>0&(Ra|0)>=(b|0)|(b|0)<(Ra|0)){continue}break}b=Y+xb|0;c=X+Qa|0;b=c>>>0>>0?b+1|0:b;X=c;Y=b;if(c>>>0<=wb>>>0&(Pa|0)>=(b|0)|(b|0)<(Pa|0)){continue}break}break a}G[j+16>>2]=q+1;a=j+32|0;Ya(a,81,27239,j+16|0);Ua(a);G[i>>2]=321}Fa=j+400|0}function $n(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;d=Fa-256|0;Fa=d;a:{if(G[b>>2]>0){break a}k=a;q=d+224|0;j=d+216|0;s=d+236|0;e=Fa-144|0;Fa=e;l=b;b:{if(G[b>>2]>0){break b}a=G[k>>2];c:{if((a|0)!=G[G[k+4>>2]+76>>2]){mb(k,a+1|0,0,l);break c}if((Rb(k,l)|0)>0){break b}}if(s){G[s>>2]=1}if(q){G[q>>2]=0;G[q+4>>2]=0}if(j){G[j>>2]=0;G[j+4>>2]=0}b=G[k+4>>2];if(G[b+80>>2]!=2){break b}g=G[b+984>>2];a=G[b+988>>2];if(!(g|a)){break b}d:{if((a|0)>=0&g>>>0>=2147483648|(a|0)>0){tb(5,52964);break d}o=lb(1,g);if(o){e:{if(G[b+936>>2]<=0){break e}c=g;i=c>>31;t=c;p=i;a=1;while(1){if(G[l>>2]>0){break e}h=a;qk(k,a,e+124|0,e+136|0,e+128|0,l);b=G[e+124>>2];f:{if((b|0)>0){f=G[k+4>>2];break f}m=1;i=0;f=G[k+4>>2];c=f;a=G[c+956>>2];if(!G[c+952>>2]&(a|0)<=0|(a|0)<0){break f}v=(0-b>>>0)/10|0;while(1){Le(k,h,m,i,e+112|0,e+104|0,l);a=G[e+112>>2];c=G[e+124>>2]==-1?(a+7|0)/8|0:M(a,v);a=G[e+104>>2];g:{h:{b=G[e+108>>2];if((b|0)<0){break h}b=(c>>31)+b|0;f=a+c|0;b=f>>>0>>0?b+1|0:b;if(f>>>0>t>>>0&(b|0)>=(p|0)|(b|0)>(p|0)){break h}if((c|0)<=0){break g}b=a;r=0;f=0;if(c-1>>>0>=3){u=c&-4;a=0;while(1){n=o+(b+f|0)|0;E[n|0]=H[n|0]+1;n=o+(b+(f|1)|0)|0;E[n|0]=H[n|0]+1;n=o+(b+(f|2)|0)|0;E[n|0]=H[n|0]+1;n=o+(b+(f|3)|0)|0;E[n|0]=H[n|0]+1;f=f+4|0;a=a+4|0;if((u|0)!=(a|0)){continue}break}}a=c&3;if(!a){break g}while(1){c=o+(b+f|0)|0;E[c|0]=H[c|0]+1;f=f+1|0;r=r+1|0;if((a|0)!=(r|0)){continue}break}break g}if(s){G[s>>2]=0}G[e+4>>2]=h;G[e>>2]=m;a=e+16|0;Ya(a,81,5800,e);tb(5,a)}c=i;a=m+1|0;c=a?c:c+1|0;m=a;f=G[k+4>>2];b=f;r=G[b+952>>2];i=c;b=G[b+956>>2];if((c|0)<=(b|0)&a>>>0<=r>>>0|(b|0)>(c|0)){continue}break}}a=h+1|0;if((h|0)>2]){continue}break}}i:{if((g|0)<=0){m=0;i=0;h=0;g=0;break i}p=g&1;j:{if((g|0)==1){f=0;h=0;g=0;m=0;i=0;break j}s=g&-2;f=0;h=0;g=0;m=0;i=0;a=0;while(1){b=h;t=E[f+o|0];h=(t|0)>1;c=b+h|0;b=g;b=c>>>0>>0?b+1|0:b;g=c;r=E[o+(f|1)|0];c=c+((r|0)>1)|0;h=c;g=c>>>0>>0?b+1|0:b;b=m;m=!(t&255);b=b+m|0;c=i;c=b>>>0>>0?c+1|0:c;m=b;b=b+!(r&255)|0;i=b>>>0>>0?c+1|0:c;m=b;f=f+2|0;a=a+2|0;if((s|0)!=(a|0)){continue}break}}if(!p){break i}b=g;c=E[f+o|0];f=(c|0)>1;a=f+h|0;h=a;g=a>>>0>>0?b+1|0:b;b=i;c=!(c&255);a=c+m|0;m=a;i=a>>>0>>0?b+1|0:b}if(q){G[q>>2]=m;G[q+4>>2]=i}if(j){G[j>>2]=h;G[j+4>>2]=g}Wa(o);break b}a=H[13452]|H[13453]<<8|(H[13454]<<16|H[13455]<<24);E[e+55|0]=a;E[e+56|0]=a>>>8;E[e+57|0]=a>>>16;E[e+58|0]=a>>>24;a=H[13449]|H[13450]<<8|(H[13451]<<16|H[13452]<<24);G[e+48>>2]=H[13445]|H[13446]<<8|(H[13447]<<16|H[13448]<<24);G[e+52>>2]=a;a=H[13441]|H[13442]<<8|(H[13443]<<16|H[13444]<<24);G[e+40>>2]=H[13437]|H[13438]<<8|(H[13439]<<16|H[13440]<<24);G[e+44>>2]=a;a=H[13433]|H[13434]<<8|(H[13435]<<16|H[13436]<<24);G[e+32>>2]=H[13429]|H[13430]<<8|(H[13431]<<16|H[13432]<<24);G[e+36>>2]=a;a=H[13425]|H[13426]<<8|(H[13427]<<16|H[13428]<<24);G[e+24>>2]=H[13421]|H[13422]<<8|(H[13423]<<16|H[13424]<<24);G[e+28>>2]=a;a=H[13417]|H[13418]<<8|(H[13419]<<16|H[13420]<<24);G[e+16>>2]=H[13413]|H[13414]<<8|(H[13415]<<16|H[13416]<<24);G[e+20>>2]=a;tb(5,e+16|0)}G[l>>2]=113}Fa=e+144|0;if(!G[d+236>>2]){G[l>>2]=264;break a}a=G[k+4>>2];k:{if(G[a+80>>2]!=2|!(G[a+984>>2]|G[a+988>>2])|(!(G[d+224>>2]|G[d+216>>2]|(G[d+228>>2]|G[d+220>>2]))|G[l>>2]>0)){break k}if(sd(d+244|0,21808,l)){a=H[13497]|H[13498]<<8|(H[13499]<<16|H[13500]<<24);b=H[13493]|H[13494]<<8|(H[13495]<<16|H[13496]<<24);E[d+53|0]=b;E[d+54|0]=b>>>8;E[d+55|0]=b>>>16;E[d+56|0]=b>>>24;E[d+57|0]=a;E[d+58|0]=a>>>8;E[d+59|0]=a>>>16;E[d+60|0]=a>>>24;a=H[13492]|H[13493]<<8|(H[13494]<<16|H[13495]<<24);G[d+48>>2]=H[13488]|H[13489]<<8|(H[13490]<<16|H[13491]<<24);G[d+52>>2]=a;a=H[13484]|H[13485]<<8|(H[13486]<<16|H[13487]<<24);G[d+40>>2]=H[13480]|H[13481]<<8|(H[13482]<<16|H[13483]<<24);G[d+44>>2]=a;a=H[13476]|H[13477]<<8|(H[13478]<<16|H[13479]<<24);G[d+32>>2]=H[13472]|H[13473]<<8|(H[13474]<<16|H[13475]<<24);G[d+36>>2]=a;a=H[13468]|H[13469]<<8|(H[13470]<<16|H[13471]<<24);G[d+24>>2]=H[13464]|H[13465]<<8|(H[13466]<<16|H[13467]<<24);G[d+28>>2]=a;a=H[13460]|H[13461]<<8|(H[13462]<<16|H[13463]<<24);G[d+16>>2]=H[13456]|H[13457]<<8|(H[13458]<<16|H[13459]<<24);G[d+20>>2]=a;tb(5,d+16|0);break k}if(ne(k,G[d+244>>2],l)){F[d+48>>1]=H[13533]|H[13534]<<8;a=H[13529]|H[13530]<<8|(H[13531]<<16|H[13532]<<24);G[d+40>>2]=H[13525]|H[13526]<<8|(H[13527]<<16|H[13528]<<24);G[d+44>>2]=a;a=H[13521]|H[13522]<<8|(H[13523]<<16|H[13524]<<24);G[d+32>>2]=H[13517]|H[13518]<<8|(H[13519]<<16|H[13520]<<24);G[d+36>>2]=a;a=H[13513]|H[13514]<<8|(H[13515]<<16|H[13516]<<24);G[d+24>>2]=H[13509]|H[13510]<<8|(H[13511]<<16|H[13512]<<24);G[d+28>>2]=a;a=H[13505]|H[13506]<<8|(H[13507]<<16|H[13508]<<24);G[d+16>>2]=H[13501]|H[13502]<<8|(H[13503]<<16|H[13504]<<24);G[d+20>>2]=a;tb(5,d+16|0);Qb(G[d+244>>2],l);break k}f=1e4;a=ab(1e4);if(!a){a=H[13409]|H[13410]<<8|(H[13411]<<16|H[13412]<<24);E[d+55|0]=a;E[d+56|0]=a>>>8;E[d+57|0]=a>>>16;E[d+58|0]=a>>>24;a=H[13406]|H[13407]<<8|(H[13408]<<16|H[13409]<<24);G[d+48>>2]=H[13402]|H[13403]<<8|(H[13404]<<16|H[13405]<<24);G[d+52>>2]=a;a=H[13398]|H[13399]<<8|(H[13400]<<16|H[13401]<<24);G[d+40>>2]=H[13394]|H[13395]<<8|(H[13396]<<16|H[13397]<<24);G[d+44>>2]=a;a=H[13390]|H[13391]<<8|(H[13392]<<16|H[13393]<<24);G[d+32>>2]=H[13386]|H[13387]<<8|(H[13388]<<16|H[13389]<<24);G[d+36>>2]=a;a=H[13382]|H[13383]<<8|(H[13384]<<16|H[13385]<<24);G[d+24>>2]=H[13378]|H[13379]<<8|(H[13380]<<16|H[13381]<<24);G[d+28>>2]=a;a=H[13374]|H[13375]<<8|(H[13376]<<16|H[13377]<<24);G[d+16>>2]=H[13370]|H[13371]<<8|(H[13372]<<16|H[13373]<<24);G[d+20>>2]=a;tb(5,d+16|0);Qb(G[d+244>>2],l);G[l>>2]=113;break a}c=G[k+4>>2];b=c;s=G[b+984>>2];r=G[b+988>>2];b=G[G[d+244>>2]+4>>2];h=G[b+976>>2];p=G[b+980>>2];i=G[b+128>>2];q=G[b+132>>2];G[c+984>>2]=0;G[c+988>>2]=0;e=G[c+128>>2];g=e+G[c+976>>2]|0;b=G[c+980>>2]+G[c+132>>2]|0;b=e>>>0>g>>>0?b+1|0:b;e=g;o=b;b=1;l:{if(G[c+936>>2]<=0){break l}c=p+q|0;g=i+h|0;c=g>>>0>>0?c+1|0:c;t=g;q=c;while(1){if(G[l>>2]>0){break l}p=b;qk(G[d+244>>2],b,d+240|0,d+112|0,d+248|0,l);m:{h=G[d+240>>2];if((h|0)>0){j=G[k+4>>2];break m}m=1;i=0;b=f;g=a;j=G[k+4>>2];c=G[j+956>>2];if(!G[j+952>>2]&(c|0)<=0|(c|0)<0){break m}v=(0-h>>>0)/10|0;while(1){Le(G[d+244>>2],p,m,i,d+208|0,d+200|0,l);a=G[d+208>>2];h=G[d+240>>2]==-1?(a+7|0)/8|0:M(a,v);n:{if((h|0)>(b|0)){a=ub(g,h);f=h;if(a){break n}G[l>>2]=113}a=g;f=b}c=G[k+4>>2];o:{if(G[c+48>>2]){g=h>>31;break o}u=G[c+988>>2];g=h>>31;b=g+o|0;j=e+h|0;b=j>>>0>>0?b+1|0:b;n=j;j=j+G[c+984>>2]|0;b=b+u|0;b=j>>>0>>0?b+1|0:b;c=G[c+96>>2]+(G[c+76>>2]<<3)|0;u=G[c+8>>2];n=G[c+12>>2];c=n;if(j>>>0<=u>>>0&(c|0)>=(b|0)|(b|0)<(c|0)){break o}b=(n^-1)+b|0;c=j;j=u^-1;c=c+j|0;b=Bu(c,c>>>0>>0?b+1|0:b,2880,0)+1|0;if((Bf(k,b,1,l)|0)<=0){break o}G[d>>2]=b;b=d+16|0;Ya(b,81,42616,d);tb(5,b)}c=G[d+204>>2]+q|0;j=G[d+200>>2];b=j+t|0;Jb(G[d+244>>2],b,b>>>0>>0?c+1|0:c,0,l);ic(G[d+244>>2],h,g,a,l);c=G[k+4>>2];b=e+G[c+984>>2]|0;c=o+G[c+988>>2]|0;Jb(k,b,b>>>0>>0?c+1|0:c,1,l);Wb(k,h,g,a,l);b=G[k+4>>2];ph(k,p,m,i,G[d+208>>2],G[d+212>>2],G[b+984>>2],G[b+988>>2],l);j=G[k+4>>2];b=g+G[j+988>>2]|0;c=h+G[j+984>>2]|0;b=c>>>0>>0?b+1|0:b;G[j+984>>2]=c;G[j+988>>2]=b;if(G[l>>2]<=0){b=f;g=a;c=i;i=m+1|0;c=i?c:c+1|0;m=i;i=c;c=G[j+956>>2];if(m>>>0>J[j+952>>2]&(i|0)>=(c|0)|(c|0)<(i|0)){break m}continue}break}Wa(a);Qb(G[d+244>>2],l);break k}b=p+1|0;if((p|0)>2]){continue}break}}Wa(a);Qb(G[d+244>>2],l);b=G[k+4>>2];i=(G[b+76>>2]<<3)+G[b+96>>2]|0;a=G[i+8>>2];g=G[i+12>>2];f=G[b+984>>2];c=f+e|0;h=G[b+988>>2];i=h+o|0;i=c>>>0>>0?i+1|0:i;a=Bu(a-c|0,g-(i+(a>>>0>>0)|0)|0,2880,0);if((a|0)>0){G[b+984>>2]=s;G[b+988>>2]=r;oh(k,a,l);a=G[k+4>>2];G[a+984>>2]=f;G[a+988>>2]=h}ef(k,2,l);_f(k,33303,d+248|0,d+112|0,l);a=G[k+4>>2];b=G[a+984>>2];a=G[a+988>>2];if((b|0)!=G[d+248>>2]|(a|0)!=G[d+252>>2]){Ad(k,33303,b,a,d+112|0,l)}Rb(k,l)}}Fa=d+256|0}function Ff(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;n=Fa-29104|0;Fa=n;l=G[j>>2];a:{if((l|0)>0){break a}b:{c:{if((yc(a,b,c,d,e,f,g,h,1,n+29032|0,n+29024|0,n+28992|0,n+29088|0,n+29100|0,n+29096|0,n+29064|0,n+29056|0,n+29084|0,n+29072|0,n+29048|0,n+29092|0,n+29040|0,n+28832|0,j)|0)>0){break c}c=G[n+29096>>2];x=c;y=c>>31;if(G[n+29100>>2]==16){Ne(n+28992|0,n+28960|0)}if(!(g|h)){l=G[j>>2];break b}e=0;f=0;c=0;d=0;while(1){p=G[n+29072>>2];q=G[n+29076>>2];o=G[n+29068>>2];k=G[n+29064>>2];l=Au(G[n+29048>>2],G[n+29052>>2],c,d);k=k+l|0;o=Ia+o|0;o=l>>>0>k>>>0?o+1|0:o;u=k;l=G[n+29056>>2];r=G[n+29060>>2];k=G[n+29084>>2];t=Au(l,r,k,k>>31);u=u+t|0;k=Ia+o|0;Jb(a,u,t>>>0>u>>>0?k+1|0:k,1,j);k=g>>>0>>0&(h|0)<=(y|0)|(h|0)<(y|0)?g:x;o=k>>31;u=k;k=q-((l>>>0>p>>>0)+r|0)|0;p=p-l|0;l=p;p=(o|0)<=(k|0)&p>>>0>u>>>0|(o|0)<(k|0);u=p?u:l;o=u;d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{p:{k=G[n+29100>>2];switch(k-11|0){case 10:break h;case 30:break i;case 31:break j;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break k;case 5:break l;case 0:break o;default:break p}}q:{switch(k-81|0){case 0:break m;case 1:break q;default:break k}}k=(e<<3)+i|0;m=L[n+29032>>3];s=L[n+29024>>3];if(m==1&s==0){break n}if((o|0)<=0){break e}l=0;if((o|0)!=1){t=o&-2;q=0;while(1){r=l<<3;p=n+32|0;L[r+p>>3]=(L[k+r>>3]-s)/m;r=r|8;L[r+p>>3]=(L[k+r>>3]-s)/m;l=l+2|0;q=q+2|0;if((t|0)!=(q|0)){continue}break}}if(!(o&1)){break e}l=l<<3;L[l+(n+32|0)>>3]=(L[l+k>>3]-s)/m;break e}q=(e<<3)+i|0;s=L[n+29032>>3];v=L[n+29024>>3];if(s==1&v==0){break g}l=0;if((o|0)<=0){break f}while(1){p=(n+32|0)+l|0;r:{s:{m=(L[q+(l<<3)>>3]-v)/s;if(m<-.49){G[j>>2]=-11;break s}if(m>255.49){G[j>>2]=-11;k=255;break r}m=m+.5;if(!(m<4294967296&m>=0)){break s}k=~~m>>>0;break r}k=0}E[p|0]=k;l=l+1|0;if((o|0)!=(l|0)){continue}break}break f}bb(n+32|0,k,o<<3);break e}t=(e<<3)+i|0;q=n+32|0;v=L[n+29032>>3];k=v!=1;s=L[n+29024>>3];t:{if(!(k|s!=0x8000000000000000)){if((o|0)<=0){break t}l=0;while(1){p=l<<3;m=L[p+t>>3];u:{if(m<-.49){G[j>>2]=-11;k=0;r=-2147483648;break u}if(m>0x10000000000000000){G[j>>2]=-11;k=-1;r=2147483647;break u}v:{if(O(m)<0x8000000000000000){r=O(m)>=1?~~(m>0?Q(S(m*2.3283064365386963e-10),4294967295):T((m-+(~~m>>>0>>>0))*2.3283064365386963e-10))>>>0:0;k=~~m>>>0;break v}r=-2147483648;k=0}r=r^-2147483648}p=q+p|0;G[p>>2]=k;G[p+4>>2]=r;l=l+1|0;if((o|0)!=(l|0)){continue}break}break t}if(!(!k&s==0)){l=0;if((o|0)<=0){break t}while(1){w:{x:{p=l<<3;m=(L[p+t>>3]-s)/v;if(m<-0x8000000000000000){G[j>>2]=-11;break x}if(m>0x8000000000000000){G[j>>2]=-11;r=2147483647;k=-1;break w}if(m>=0){m=m+.5;if(!(O(m)<0x8000000000000000)){break x}r=O(m)>=1?~~(m>0?Q(S(m*2.3283064365386963e-10),4294967295):T((m-+(~~m>>>0>>>0))*2.3283064365386963e-10))>>>0:0;k=~~m>>>0;break w}m=m+-.5;if(!(O(m)<0x8000000000000000)){break x}r=O(m)>=1?~~(m>0?Q(S(m*2.3283064365386963e-10),4294967295):T((m-+(~~m>>>0>>>0))*2.3283064365386963e-10))>>>0:0;k=~~m>>>0;break w}r=-2147483648;k=0}p=q+p|0;G[p>>2]=k;G[p+4>>2]=r;l=l+1|0;if((o|0)!=(l|0)){continue}break}break t}if((o|0)<=0){break t}l=0;while(1){y:{z:{p=l<<3;m=L[p+t>>3];if(m<-0x8000000000000000){G[j>>2]=-11;break z}if(m>0x8000000000000000){G[j>>2]=-11;r=2147483647;k=-1;break y}if(!(O(m)<0x8000000000000000)){break z}r=O(m)>=1?~~(m>0?Q(S(m*2.3283064365386963e-10),4294967295):T((m-+(~~m>>>0>>>0))*2.3283064365386963e-10))>>>0:0;k=~~m>>>0;break y}r=-2147483648;k=0}p=q+p|0;G[p>>2]=k;G[p+4>>2]=r;l=l+1|0;if((o|0)!=(l|0)){continue}break}}_c(a,o,G[n+29084>>2],q,j);break d}if(H[n+28961|0]==115){break k}t=(e<<3)+i|0;l=o;p=n+28960|0;w=G[n+29088>>2];k=n+32|0;q=0;r=Fa-32|0;Fa=r;m=L[n+29032>>3];s=L[n+29024>>3];A:{if(!(m==1&s==0)){if((l|0)<=0){break A}o=k;while(1){L[r+16>>3]=(L[t+(q<<3)>>3]-s)/m;Eb(o,p,r+16|0);o=o+w|0;if(H[o|0]){G[j>>2]=-11}q=q+1|0;if((l|0)!=(q|0)){continue}break}break A}if((l|0)<=0){break A}o=k;while(1){L[r>>3]=L[t+(q<<3)>>3];Eb(o,p,r);o=o+w|0;if(H[o|0]){G[j>>2]=-11}q=q+1|0;if((l|0)!=(q|0)){continue}break}}q=jb(k,44);if(q){while(1){E[q|0]=46;q=jb(q,44);if(q){continue}break}}Fa=r+32|0;o=G[n+29084>>2];k=G[n+29088>>2];if((o|0)==(k|0)){o=M(l,o);Wb(a,o,o>>31,n+32|0,j);break d}wd(a,k,l,o-k|0,n+32|0,j);break d}G[n>>2]=b;G[n+4>>2]=n+28992;a=n+28864|0;Ya(a,81,8813,n);Ua(a);if(G[n+29092>>2]==1){l=311;G[j>>2]=311;break a}l=312;G[j>>2]=312;break a}k=(e<<3)+i|0;m=L[n+29032>>3];s=L[n+29024>>3];B:{if(!(m==1&s==0)){if((o|0)<=0){break B}l=0;if((o|0)!=1){q=o&-2;r=0;while(1){t=n+32|0;K[t+(l<<2)>>2]=(L[k+(l<<3)>>3]-s)/m;p=l|1;K[t+(p<<2)>>2]=(L[k+(p<<3)>>3]-s)/m;l=l+2|0;r=r+2|0;if((q|0)!=(r|0)){continue}break}}if(!(o&1)){break B}K[(n+32|0)+(l<<2)>>2]=(L[k+(l<<3)>>3]-s)/m;break B}if((o|0)<=0){break B}r=0;l=0;if(o-1>>>0>=3){p=o&-4;q=0;while(1){t=n+32|0;K[t+(l<<2)>>2]=L[k+(l<<3)>>3];w=l|1;K[t+(w<<2)>>2]=L[k+(w<<3)>>3];w=l|2;K[t+(w<<2)>>2]=L[k+(w<<3)>>3];w=t;t=l|3;K[w+(t<<2)>>2]=L[k+(t<<3)>>3];l=l+4|0;q=q+4|0;if((p|0)!=(q|0)){continue}break}}q=o&3;if(!q){break B}while(1){K[(n+32|0)+(l<<2)>>2]=L[k+(l<<3)>>3];l=l+1|0;r=r+1|0;if((q|0)!=(r|0)){continue}break}}$c(a,o,G[n+29084>>2],n+32|0,j);break d}q=(e<<3)+i|0;s=L[n+29032>>3];v=L[n+29024>>3];C:{if(!(s==1&v==0)){l=0;if((o|0)<=0){break C}while(1){p=(n+32|0)+(l<<2)|0;D:{E:{m=(L[q+(l<<3)>>3]-v)/s;if(m<-2147483648.49){G[j>>2]=-11;break E}if(m>2147483647.49){G[j>>2]=-11;k=2147483647;break D}if(m>=0){m=m+.5;if(!(O(m)<2147483648)){break E}k=~~m;break D}m=m+-.5;if(!(O(m)<2147483648)){break E}k=~~m;break D}k=-2147483648}G[p>>2]=k;l=l+1|0;if((o|0)!=(l|0)){continue}break}break C}l=0;if((o|0)<=0){break C}while(1){p=(n+32|0)+(l<<2)|0;F:{G:{m=L[q+(l<<3)>>3];if(m<-2147483648.49){G[j>>2]=-11;break G}if(m>2147483647.49){G[j>>2]=-11;k=2147483647;break F}if(!(O(m)<2147483648)){break G}k=~~m;break F}k=-2147483648}G[p>>2]=k;l=l+1|0;if((o|0)!=(l|0)){continue}break}}$c(a,o,G[n+29084>>2],n+32|0,j);break d}q=(e<<3)+i|0;s=L[n+29032>>3];v=L[n+29024>>3];H:{if(!(s==1&v==0)){l=0;if((o|0)<=0){break H}while(1){p=(n+32|0)+(l<<1)|0;m=(L[q+(l<<3)>>3]-v)/s;I:{if(m<-32768.49){G[j>>2]=-11;k=32768;break I}if(m>32767.49){G[j>>2]=-11;k=32767;break I}J:{if(m>=0){m=m+.5;if(!(O(m)<2147483648)){break J}k=~~m;break I}m=m+-.5;if(!(O(m)<2147483648)){break J}k=~~m;break I}k=-2147483648}F[p>>1]=k;l=l+1|0;if((o|0)!=(l|0)){continue}break}break H}l=0;if((o|0)<=0){break H}while(1){p=(n+32|0)+(l<<1)|0;m=L[q+(l<<3)>>3];K:{if(m<-32768.49){G[j>>2]=-11;k=32768;break K}if(m>32767.49){G[j>>2]=-11;k=32767;break K}k=~~m;if(O(m)<2147483648){break K}k=-2147483648}F[p>>1]=k;l=l+1|0;if((o|0)!=(l|0)){continue}break}}Oe(a,o,G[n+29084>>2],n+32|0,j);break d}l=0;if((o|0)<=0){break f}while(1){p=(n+32|0)+l|0;L:{M:{m=L[q+(l<<3)>>3];if(m<-.49){G[j>>2]=-11;break M}if(m>255.49){G[j>>2]=-11;k=255;break L}if(!(m<4294967296&m>=0)){break M}k=~~m>>>0;break L}k=0}E[p|0]=k;l=l+1|0;if((o|0)!=(l|0)){continue}break}}we(a,o,G[n+29084>>2],n+32|0,j);break d}_c(a,o,G[n+29084>>2],n+32|0,j)}l=G[j>>2];if((l|0)>0){k=f;a=e+1|0;k=a?k:k+1|0;L[n+16>>3]=+(a>>>0)+ +(k|0)*4294967296;o=u;k=o>>31;a=e+o|0;k=f+k|0;L[n+24>>3]=+(a>>>0)+ +((a>>>0>>0?k+1|0:k)|0)*4294967296;a=n+28864|0;Ya(a,81,47586,n+16|0);Ua(a);break c}o=u;k=o>>31;p=k;h=h-(k+(g>>>0>>0)|0)|0;g=g-o|0;if(!(h|g)){break b}k=f+p|0;e=e+o|0;k=e>>>0>>0?k+1|0:k;f=k;k=p+G[n+29060>>2]|0;l=o+G[n+29056>>2]|0;k=l>>>0>>0?k+1|0:k;G[n+29056>>2]=l;G[n+29060>>2]=k;if(G[n+29072>>2]!=(l|0)|G[n+29076>>2]!=(k|0)){continue}G[n+29056>>2]=0;G[n+29060>>2]=0;o=d;c=c+1|0;o=c?o:o+1|0;d=o;continue}}l=G[j>>2];break a}if((l|0)!=-11){break a}Ua(44927);l=412;G[j>>2]=412}Fa=n+29104|0;return l}function Kg(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=N(0),t=0,u=0,v=0,w=0,x=0,y=0,z=0;m=Fa-29104|0;Fa=m;l=G[j>>2];a:{if((l|0)>0){break a}b:{c:{if((yc(a,b,c,d,e,f,g,h,1,m+29032|0,m+29024|0,m+28992|0,m+29088|0,m+29100|0,m+29096|0,m+29064|0,m+29056|0,m+29084|0,m+29072|0,m+29048|0,m+29092|0,m+29040|0,m+28832|0,j)|0)>0){break c}c=G[m+29096>>2];y=c;z=c>>31;if(G[m+29100>>2]==16){Ne(m+28992|0,m+28960|0)}if(!(g|h)){l=G[j>>2];break b}e=0;f=0;c=0;d=0;while(1){r=G[m+29072>>2];q=G[m+29076>>2];n=G[m+29068>>2];k=G[m+29064>>2];l=Au(G[m+29048>>2],G[m+29052>>2],c,d);k=k+l|0;n=Ia+n|0;n=l>>>0>k>>>0?n+1|0:n;v=k;l=G[m+29056>>2];p=G[m+29060>>2];k=G[m+29084>>2];u=Au(l,p,k,k>>31);v=v+u|0;k=Ia+n|0;Jb(a,v,u>>>0>v>>>0?k+1|0:k,1,j);k=g>>>0>>0&(h|0)<=(z|0)|(h|0)<(z|0)?g:y;n=k>>31;v=k;k=q-((l>>>0>r>>>0)+p|0)|0;r=r-l|0;l=r;r=(n|0)<=(k|0)&r>>>0>v>>>0|(n|0)<(k|0);v=r?v:l;n=v;d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{p:{q:{k=G[m+29100>>2];switch(k-11|0){case 10:break h;case 30:break i;case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break k;case 5:break l;case 0:break o;case 31:break p;default:break q}}switch(k-81|0){case 1:break j;case 0:break m;default:break k}}k=(e<<2)+i|0;o=L[m+29032>>3];t=L[m+29024>>3];if(o==1&t==0){break n}if((n|0)<=0){break e}l=0;if((n|0)!=1){u=n&-2;q=0;while(1){p=l<<2;r=m+32|0;K[p+r>>2]=(+K[k+p>>2]-t)/o;p=p|4;K[p+r>>2]=(+K[k+p>>2]-t)/o;l=l+2|0;q=q+2|0;if((u|0)!=(q|0)){continue}break}}if(!(n&1)){break e}l=l<<2;K[l+(m+32|0)>>2]=(+K[l+k>>2]-t)/o;break e}q=(e<<2)+i|0;t=L[m+29032>>3];w=L[m+29024>>3];if(t==1&w==0){break g}l=0;if((n|0)<=0){break f}while(1){r=(m+32|0)+l|0;r:{s:{o=(+K[q+(l<<2)>>2]-w)/t;if(o<-.49){G[j>>2]=-11;break s}if(o>255.49){G[j>>2]=-11;k=255;break r}o=o+.5;if(!(o<4294967296&o>=0)){break s}k=~~o>>>0;break r}k=0}E[r|0]=k;l=l+1|0;if((n|0)!=(l|0)){continue}break}break f}bb(m+32|0,k,n<<2);break e}u=(e<<2)+i|0;q=m+32|0;w=L[m+29032>>3];k=w!=1;t=L[m+29024>>3];t:{if(!(k|t!=0x8000000000000000)){if((n|0)<=0){break t}l=0;while(1){r=q+(l<<3)|0;s=K[u+(l<<2)>>2];u:{if(+s<-.49){G[j>>2]=-11;k=0;p=-2147483648;break u}if(s>N(0x10000000000000000)){G[j>>2]=-11;k=-1;p=2147483647;break u}v:{if(N(O(s))=N(1)?~~(s>N(0)?N(Q(N(S(N(s*N(2.3283064365386963e-10)))),N(4294967296))):N(T(N(N(s-N(~~s>>>0>>>0))*N(2.3283064365386963e-10)))))>>>0:0;k=~~s>>>0;break v}p=-2147483648;k=0}p=p^-2147483648}G[r>>2]=k;G[r+4>>2]=p;l=l+1|0;if((n|0)!=(l|0)){continue}break}break t}if(!(!k&t==0)){l=0;if((n|0)<=0){break t}while(1){r=q+(l<<3)|0;w:{x:{o=(+K[u+(l<<2)>>2]-t)/w;if(o<-0x8000000000000000){G[j>>2]=-11;break x}if(o>0x8000000000000000){G[j>>2]=-11;p=2147483647;k=-1;break w}if(o>=0){o=o+.5;if(!(O(o)<0x8000000000000000)){break x}p=O(o)>=1?~~(o>0?Q(S(o*2.3283064365386963e-10),4294967295):T((o-+(~~o>>>0>>>0))*2.3283064365386963e-10))>>>0:0;k=~~o>>>0;break w}o=o+-.5;if(!(O(o)<0x8000000000000000)){break x}p=O(o)>=1?~~(o>0?Q(S(o*2.3283064365386963e-10),4294967295):T((o-+(~~o>>>0>>>0))*2.3283064365386963e-10))>>>0:0;k=~~o>>>0;break w}p=-2147483648;k=0}G[r>>2]=k;G[r+4>>2]=p;l=l+1|0;if((n|0)!=(l|0)){continue}break}break t}if((n|0)<=0){break t}l=0;while(1){r=q+(l<<3)|0;s=K[u+(l<<2)>>2];y:{if(s>2]=-11;k=0;p=-2147483648;break y}if(s>N(0x8000000000000000)){G[j>>2]=-11;k=-1;p=2147483647;break y}if(N(O(s))>31}G[r>>2]=k;G[r+4>>2]=p;l=l+1|0;if((n|0)!=(l|0)){continue}break}}_c(a,n,G[m+29084>>2],q,j);break d}if(H[m+28961|0]==115){break k}u=(e<<2)+i|0;l=n;r=m+28960|0;x=G[m+29088>>2];k=m+32|0;q=0;p=Fa-32|0;Fa=p;o=L[m+29032>>3];t=L[m+29024>>3];z:{if(!(o==1&t==0)){if((l|0)<=0){break z}n=k;while(1){L[p+16>>3]=(+K[u+(q<<2)>>2]-t)/o;Eb(n,r,p+16|0);n=n+x|0;if(H[n|0]){G[j>>2]=-11}q=q+1|0;if((l|0)!=(q|0)){continue}break}break z}if((l|0)<=0){break z}n=k;while(1){L[p>>3]=K[u+(q<<2)>>2];Eb(n,r,p);n=n+x|0;if(H[n|0]){G[j>>2]=-11}q=q+1|0;if((l|0)!=(q|0)){continue}break}}q=jb(k,44);if(q){while(1){E[q|0]=46;q=jb(q,44);if(q){continue}break}}Fa=p+32|0;n=G[m+29084>>2];k=G[m+29088>>2];if((n|0)==(k|0)){n=M(l,n);Wb(a,n,n>>31,m+32|0,j);break d}wd(a,k,l,n-k|0,m+32|0,j);break d}G[m>>2]=b;G[m+4>>2]=m+28992;a=m+28864|0;Ya(a,81,8813,m);Ua(a);if(G[m+29092>>2]==1){l=311;G[j>>2]=311;break a}l=312;G[j>>2]=312;break a}k=(e<<2)+i|0;o=L[m+29032>>3];t=L[m+29024>>3];A:{if(!(o==1&t==0)){if((n|0)<=0){break A}l=0;if((n|0)!=1){q=n&-2;p=0;while(1){u=m+32|0;L[u+(l<<3)>>3]=(+K[k+(l<<2)>>2]-t)/o;r=l|1;L[u+(r<<3)>>3]=(+K[k+(r<<2)>>2]-t)/o;l=l+2|0;p=p+2|0;if((q|0)!=(p|0)){continue}break}}if(!(n&1)){break A}L[(m+32|0)+(l<<3)>>3]=(+K[k+(l<<2)>>2]-t)/o;break A}if((n|0)<=0){break A}p=0;l=0;if(n-1>>>0>=3){r=n&-4;q=0;while(1){u=m+32|0;L[u+(l<<3)>>3]=K[k+(l<<2)>>2];x=l|1;L[u+(x<<3)>>3]=K[k+(x<<2)>>2];x=l|2;L[u+(x<<3)>>3]=K[k+(x<<2)>>2];x=u;u=l|3;L[x+(u<<3)>>3]=K[k+(u<<2)>>2];l=l+4|0;q=q+4|0;if((r|0)!=(q|0)){continue}break}}q=n&3;if(!q){break A}while(1){L[(m+32|0)+(l<<3)>>3]=K[k+(l<<2)>>2];l=l+1|0;p=p+1|0;if((q|0)!=(p|0)){continue}break}}_c(a,n,G[m+29084>>2],m+32|0,j);break d}q=(e<<2)+i|0;t=L[m+29032>>3];w=L[m+29024>>3];B:{if(!(t==1&w==0)){l=0;if((n|0)<=0){break B}while(1){C:{D:{p=l<<2;o=(+K[p+q>>2]-w)/t;if(o<-2147483648.49){G[j>>2]=-11;break D}if(o>2147483647.49){G[j>>2]=-11;k=2147483647;break C}if(o>=0){o=o+.5;if(!(O(o)<2147483648)){break D}k=~~o;break C}o=o+-.5;if(!(O(o)<2147483648)){break D}k=~~o;break C}k=-2147483648}G[p+(m+32|0)>>2]=k;l=l+1|0;if((n|0)!=(l|0)){continue}break}break B}l=0;if((n|0)<=0){break B}while(1){E:{F:{p=l<<2;s=K[p+q>>2];o=+s;if(o<-2147483648.49){G[j>>2]=-11;break F}if(o>2147483647.49){G[j>>2]=-11;k=2147483647;break E}if(!(N(O(s))>2]=k;l=l+1|0;if((n|0)!=(l|0)){continue}break}}$c(a,n,G[m+29084>>2],m+32|0,j);break d}q=(e<<2)+i|0;t=L[m+29032>>3];w=L[m+29024>>3];G:{if(!(t==1&w==0)){l=0;if((n|0)<=0){break G}while(1){r=(m+32|0)+(l<<1)|0;o=(+K[q+(l<<2)>>2]-w)/t;H:{if(o<-32768.49){G[j>>2]=-11;k=32768;break H}if(o>32767.49){G[j>>2]=-11;k=32767;break H}I:{if(o>=0){o=o+.5;if(!(O(o)<2147483648)){break I}k=~~o;break H}o=o+-.5;if(!(O(o)<2147483648)){break I}k=~~o;break H}k=-2147483648}F[r>>1]=k;l=l+1|0;if((n|0)!=(l|0)){continue}break}break G}l=0;if((n|0)<=0){break G}while(1){r=(m+32|0)+(l<<1)|0;s=K[q+(l<<2)>>2];o=+s;J:{if(o<-32768.49){G[j>>2]=-11;k=32768;break J}if(o>32767.49){G[j>>2]=-11;k=32767;break J}k=~~s;if(N(O(s))>1]=k;l=l+1|0;if((n|0)!=(l|0)){continue}break}}Oe(a,n,G[m+29084>>2],m+32|0,j);break d}l=0;if((n|0)<=0){break f}while(1){r=(m+32|0)+l|0;K:{L:{s=K[q+(l<<2)>>2];o=+s;if(o<-.49){G[j>>2]=-11;break L}if(o>255.49){G[j>>2]=-11;k=255;break K}if(!(s=N(0))){break L}k=~~s>>>0;break K}k=0}E[r|0]=k;l=l+1|0;if((n|0)!=(l|0)){continue}break}}we(a,n,G[m+29084>>2],m+32|0,j);break d}$c(a,n,G[m+29084>>2],m+32|0,j)}l=G[j>>2];if((l|0)>0){k=f;a=e+1|0;k=a?k:k+1|0;L[m+16>>3]=+(a>>>0)+ +(k|0)*4294967296;n=v;k=n>>31;a=e+n|0;k=f+k|0;L[m+24>>3]=+(a>>>0)+ +((a>>>0>>0?k+1|0:k)|0)*4294967296;a=m+28864|0;Ya(a,81,47312,m+16|0);Ua(a);break c}n=v;k=n>>31;r=k;h=h-(k+(g>>>0>>0)|0)|0;g=g-n|0;if(!(h|g)){break b}k=f+r|0;e=e+n|0;k=e>>>0>>0?k+1|0:k;f=k;k=r+G[m+29060>>2]|0;l=n+G[m+29056>>2]|0;k=l>>>0>>0?k+1|0:k;G[m+29056>>2]=l;G[m+29060>>2]=k;if(G[m+29072>>2]!=(l|0)|G[m+29076>>2]!=(k|0)){continue}G[m+29056>>2]=0;G[m+29060>>2]=0;n=d;c=c+1|0;n=c?n:n+1|0;d=n;continue}}l=G[j>>2];break a}if((l|0)!=-11){break a}Ua(44927);l=412;G[j>>2]=412}Fa=m+29104|0;return l}function Rh(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;f=Fa-400|0;Fa=f;G[925783]=0;G[925774]=0;G[925775]=0;G[925776]=0;G[925763]=0;G[925764]=0;G[925765]=0;G[925778]=0;G[925777]=0;G[925766]=0;G[925769]=0;if(G[925767]){G[f+304>>2]=a;kb(85403,f+304|0);$a(G[29763])}while(1){c=ab(1e5);if(!c){continue}break}b=ac(a,G[925768]?49013:13287);G[925769]=b;h=-2;a:{if(!b){break a}l=G[29763];while(1){if(!vc(c,1e5,G[925769])){h=-4;break a}if(G[925767]){G[f+288>>2]=c;kb(85677,f+288|0);$a(l)}if(H[c|0]!=124){continue}break}b=Va(c)<<1;G[925766]=b;if(G[925767]){G[f+272>>2]=b;kb(85508,f+272|0);$a(l);b=G[925766]}b:{if((b|0)>1023){break b}G[925766]=1024;if(!G[925767]){break b}G[f+256>>2]=1024;kb(85445,f+256|0);$a(l)}Wa(c);lm(G[925769]);Hb(G[925769]);if(G[925767]){G[f+240>>2]=G[925766];kb(85550,f+240|0);$a(l)}b=G[925766];c:{if((b|0)<=G[925770]){d=G[925771];break c}if(G[925767]){G[f+224>>2]=b;kb(86064,f+224|0);$a(l);b=G[925766]}n=3703032,o=ub(G[925758],b),G[n>>2]=o;n=3703036,o=ub(G[925759],b),G[n>>2]=o;n=3703040,o=ub(G[925760],b),G[n>>2]=o;n=3703044,o=ub(G[925761],b),G[n>>2]=o;n=3703048,o=ub(G[925762],b),G[n>>2]=o;d=ub(G[925771],b);G[925770]=b;G[925771]=d}E[G[925758]]=0;E[G[925759]]=0;E[G[925760]]=0;E[G[925761]]=0;E[G[925762]]=0;E[d|0]=0;if(!G[925772]){G[925772]=1024;n=3703092,o=ab(4206592),G[n>>2]=o;c=0;while(1){d=0;while(1){e=M(c,4108);E[(e+G[925773]|0)+d|0]=0;E[((e+G[925773]|0)+d|0)+1024|0]=0;E[((e+G[925773]|0)+d|0)+2048|0]=0;E[((e+G[925773]|0)+d|0)+3072|0]=0;b=d|1;E[b+(e+G[925773]|0)|0]=0;E[(b+(e+G[925773]|0)|0)+1024|0]=0;E[(b+(e+G[925773]|0)|0)+2048|0]=0;E[(b+(e+G[925773]|0)|0)+3072|0]=0;d=d+2|0;if((d|0)!=1024){continue}break}b=e+G[925773]|0;G[b+4100>>2]=0;G[b+4104>>2]=0;c=c+1|0;if((c|0)!=1024){continue}break}}b=ac(a,G[925768]?49013:13287);G[925769]=b;if(!b){break a}G[925776]=-1;G[925775]=0;G[925774]=0;G[925777]=0;G[925778]=0;G[925763]=0;G[925764]=0;G[925765]=0;d:{if(!vc(G[925771],G[925766],b)){break d}while(1){if(G[925767]){G[f+208>>2]=G[925771];kb(85704,f+208|0);$a(l)}j=G[925771];b=Va(j);G[925775]=b;G[925774]=b+G[925774];b=(b+j|0)-1|0;if(H[b|0]==10){E[b|0]=0}b=(Va(j)+j|0)-1|0;if(H[b|0]==13){E[b|0]=0}b=0;e=Va(j);e:{if(!e){break e}while(1){c=H[b+j|0];if(!((c|0)!=32&(c|0)!=9)){b=b+1|0;if((e|0)!=(b|0)){continue}break e}break}if(H[j|0]!=92){break d}}b=G[925779];g=G[925777];f:{if((b|0)>(g|0)){c=G[925780];break f}i=b+1024|0;G[925779]=i;b=i<<2;c=ub(G[925780],b);G[925780]=c;h=ub(G[925781],b);G[925781]=h;e=ub(G[925782],b);G[925782]=e;b=g;if((i|0)<=(b|0)){break f}while(1){k=b<<2;n=k+c|0,o=ab(256),G[n>>2]=o;n=h+k|0,o=ab(256),G[n>>2]=o;n=e+k|0,o=ab(256),G[n>>2]=o;b=b+1|0;if((i|0)!=(b|0)){continue}break}}b=G[925778];Za(G[(b<<2)+c>>2],j);G[925778]=b+1;k=j+1|0;b=k;while(1){d=H[b|0];if(!(!d|(d|0)==61|(d|0)==32)){b=b+1|0;continue}break}while(1){c=d&255;if((c|0)==32){E[b|0]=0;d=H[b+1|0];b=b+1|0;continue}break}g:{if((c|0)!=61){break g}E[b|0]=0;while(1){e=b;b=b+1|0;if(H[e+1|0]==32){continue}break}h=Va(b);c=h-1|0;h:{if((c|0)<0){break h}while(1){h=e+h|0;if(H[h|0]!=32){break h}E[h|0]=0;h=c;c=c-1|0;if((c|0)>=0){continue}break}}if(!H[k|0]){break g}c=g<<2;Za(G[c+G[925781]>>2],k);Za(G[c+G[925782]>>2],b);G[925777]=g+1}if(vc(j,G[925766],G[925769])){continue}break}}j=G[925771];Za(G[925759],j);if(H[j|0]==124){E[j|0]=32}b=(G[925775]+G[925759]|0)-1|0;if(H[b|0]==10){E[b|0]=0}G[925783]=0;k=Va(j);i:{if((k|0)<=0){b=G[925773];G[b+4104>>2]=G[b+4100>>2]+1;break i}c=G[925772];i=0;d=0;g=0;while(1){j:{k:{l:{b=H[i+j|0];m:{if(b>>>0<=91){if((b|0)==32){break k}if((b|0)!=10){break m}break j}if((b|0)==124){break l}if((b|0)==92){break j}}E[(G[925773]+M(g,4108)|0)+d|0]=b;d=d+1|0;break k}b=G[925773]+M(g,4108)|0;G[b+4100>>2]=i;E[b+d|0]=0;b=g+1|0;G[925783]=b;if((c|0)<=(g|0)){e=c+1024|0;G[925772]=e;n=3703092,o=ub(G[925773],M(e,4108)),G[n>>2]=o;while(1){d=0;while(1){m=M(c,4108);E[(m+G[925773]|0)+d|0]=0;E[((G[925773]+m|0)+d|0)+1024|0]=0;E[((G[925773]+m|0)+d|0)+2048|0]=0;E[((G[925773]+m|0)+d|0)+3072|0]=0;h=d|1;E[h+(G[925773]+m|0)|0]=0;E[(h+(G[925773]+m|0)|0)+1024|0]=0;E[(h+(G[925773]+m|0)|0)+2048|0]=0;E[(h+(G[925773]+m|0)|0)+3072|0]=0;d=d+2|0;if((d|0)!=1024){continue}break}h=G[925773]+m|0;G[h+4100>>2]=0;G[h+4104>>2]=0;c=c+1|0;if((e|0)>(c|0)){continue}break}c=e}d=0;if(i){g=b;break k}G[925783]=g}i=i+1|0;if((k|0)!=(i|0)){continue}}break}d=1;k=G[925773];e=G[k+4100>>2];G[k+4104>>2]=e+1;if((g|0)<2){break i}b=g-1|0;h=b&3;if(g-2>>>0>=3){g=b&-4;c=0;while(1){i=k+M(d,4108)|0;b=G[i+4100>>2];G[i+4104>>2]=b-e;e=G[i+8208>>2];G[i+8212>>2]=e-b;b=G[i+12316>>2];G[i+12320>>2]=b-e;e=G[i+16424>>2];G[i+16428>>2]=e-b;d=d+4|0;c=c+4|0;if((g|0)!=(c|0)){continue}break}}if(!h){break i}b=0;while(1){g=k+M(d,4108)|0;c=G[g+4100>>2];G[g+4104>>2]=c-e;d=d+1|0;e=c;b=b+1|0;if((h|0)!=(b|0)){continue}break}}n:{if(!vc(j,G[925766],G[925769])){break n}while(1){if(G[925767]){G[f+192>>2]=G[925771];kb(85636,f+192|0);$a(l)}g=G[925771];if(H[g|0]!=124){break n}b=Va(g);G[925775]=b;G[925774]=b+G[925774];o:{if(!G[925763]){b=(Va(g)+g|0)-1|0;if(H[b|0]==10){E[b|0]=0}b=(Va(g)+g|0)-1|0;if(H[b|0]==13){E[b|0]=0}d=0;G[925763]=1;Za(G[925760],g);c=0;h=0;b=Va(g);if((b|0)<=0){break o}while(1){p:{q:{e=H[d+g|0];r:{if(e>>>0<=91){if((e|0)==32){break p}if((e|0)!=10){break r}break o}if((e|0)==124){break q}if((e|0)==92){break o}}E[((G[925773]+M(h,4108)|0)+c|0)+1024|0]=e;c=c+1|0;break p}if((h|0)>1023){h=-3;break a}c=0;h=((d|0)!=0)+h|0}d=d+1|0;if((b|0)!=(d|0)){continue}break}break o}if(!G[925764]){b=(Va(g)+g|0)-1|0;if(H[b|0]==10){E[b|0]=0}b=(Va(g)+g|0)-1|0;if(H[b|0]==13){E[b|0]=0}d=0;G[925764]=1;Za(G[925761],g);c=0;h=0;b=Va(g);if((b|0)<=0){break o}while(1){s:{t:{e=H[d+g|0];u:{if(e>>>0<=91){if((e|0)==32){break s}if((e|0)!=10){break u}break o}if((e|0)==124){break t}if((e|0)==92){break o}}E[((G[925773]+M(h,4108)|0)+c|0)+2048|0]=e;c=c+1|0;break s}if((h|0)>1023){h=-3;break a}c=0;h=((d|0)!=0)+h|0}d=d+1|0;if((b|0)!=(d|0)){continue}break}break o}if(G[925765]){break o}b=(Va(g)+g|0)-1|0;if(H[b|0]==10){E[b|0]=0}b=(Va(g)+g|0)-1|0;if(H[b|0]==13){E[b|0]=0}d=0;G[925765]=1;Za(G[925762],g);c=0;h=0;b=Va(g);if((b|0)<=0){break o}while(1){v:{w:{e=H[d+g|0];x:{if(e>>>0<=91){if((e|0)==32){break v}if((e|0)!=10){break x}break o}if((e|0)==124){break w}if((e|0)==92){break o}}E[((G[925773]+M(h,4108)|0)+c|0)+3072|0]=e;c=c+1|0;break v}if((h|0)>1023){h=-3;break a}c=0;h=((d|0)!=0)+h|0}d=d+1|0;if((b|0)!=(d|0)){continue}break}}if(vc(g,G[925766],G[925769])){continue}break}}if(vc(G[925771],G[925766],G[925769])){if(G[925767]){G[f+176>>2]=G[925771];kb(85747,f+176|0);$a(l)}n=3703100,o=Va(G[925771]),G[n>>2]=o}b=0;y:{if(!G[925767]){break y}G[f+160>>2]=G[925759];kb(85780,f+160|0);G[f+144>>2]=G[925760];kb(85815,f+144|0);G[f+128>>2]=G[925761];kb(85885,f+128|0);G[f+112>>2]=G[925762];kb(85850,f+112|0);G[f+96>>2]=G[925771];G[f+100>>2]=G[925775];kb(86025,f+96|0);$a(l);if(G[925783]<=0){break y}while(1){yb(36149);c=b+1|0;G[f+80>>2]=c;kb(86001,f+80|0);b=M(b,4108);G[f+64>>2]=b+G[925773];kb(85974,f- -64|0);G[f+48>>2]=(b+G[925773]|0)+1024;kb(85947,f+48|0);G[f+32>>2]=(b+G[925773]|0)+2048;kb(85920,f+32|0);G[f+16>>2]=G[(b+G[925773]|0)+4100>>2];kb(85584,f+16|0);G[f>>2]=G[(b+G[925773]|0)+4104>>2];kb(85610,f);$a(l);b=c;if((b|0)>2];b=G[925774];a=Bu(c-b|0,G[f+356>>2]-((b>>31)+(b>>>0>c>>>0)|0)|0,e,0)}G[925776]=a;He(G[925769],b,0);G[925756]=G[925774];G[925757]=G[925775];h=G[925783]}Fa=f+400|0;return h}function Nm(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,H=0,I=0,K=0,L=0,M=0,N=0;l=Fa-336|0;Fa=l;m=i&65535;p=d;q=e&65535;s=(e^i)&-2147483648;k=h;x=i>>>16&32767;y=e>>>16&32767;a:{b:{if(x-32767>>>0>4294934529&y-32767>>>0>=4294934530){break b}j=e&2147483647;if(!(!d&(j|0)==2147418112?!(b|c):j>>>0<2147418112)){o=d;s=e|32768;break a}e=i&2147483647;if(!(!h&(e|0)==2147418112?!(f|g):e>>>0<2147418112)){o=h;s=i|32768;b=f;c=g;break a}if(!(b|d|(j^2147418112|c))){if(!(f|h|(e^2147418112|g))){b=0;c=0;s=2147450880;break a}s=s|2147418112;b=0;c=0;break a}if(!(f|h|(e^2147418112|g))){b=0;c=0;break a}if(!(b|d|(c|j))){b=!(f|h|(e|g));o=b?0:o;s=b?2147450880:s;b=0;c=0;break a}if(!(f|h|(e|g))){s=s|2147418112;b=0;c=0;break a}if((j|0)==65535|j>>>0<65535){i=b;d=!(p|q);h=d<<6;j=P(d?b:p)+32|0;b=P(d?c:q);b=h+((b|0)==32?j:b)|0;od(l+320|0,i,c,p,q,b-15|0);n=16-b|0;p=G[l+328>>2];q=G[l+332>>2];c=G[l+324>>2];b=G[l+320>>2]}if(e>>>0>65535){break b}d=!(k|m);e=d<<6;h=P(d?f:k)+32|0;d=P(d?g:m);d=e+((d|0)==32?h:d)|0;od(l+304|0,f,g,k,m,d-15|0);n=(d+n|0)-16|0;k=G[l+312>>2];m=G[l+316>>2];f=G[l+304>>2];g=G[l+308>>2]}e=m|65536;z=e;A=k;d=k;k=e<<15|d>>>17;d=d<<15|g>>>17;h=0-d|0;e=k;i=1963258675-(e+((d|0)!=0)|0)|0;ed(l+288|0,d,e,0,0,h,i,0,0);j=G[l+296>>2];ed(l+272|0,0-j|0,0-(G[l+300>>2]+((j|0)!=0)|0)|0,0,0,h,i,0,0);h=G[l+280>>2];i=h<<1|G[l+276>>2]>>>31;h=G[l+284>>2]<<1|h>>>31;ed(l+256|0,i,h,0,0,d,e,0,0);j=h;h=G[l+264>>2];ed(l+240|0,i,j,0,0,0-h|0,0-(G[l+268>>2]+((h|0)!=0)|0)|0,0,0);h=G[l+248>>2];i=h<<1|G[l+244>>2]>>>31;h=G[l+252>>2]<<1|h>>>31;ed(l+224|0,i,h,0,0,d,e,0,0);j=h;h=G[l+232>>2];ed(l+208|0,i,j,0,0,0-h|0,0-(G[l+236>>2]+((h|0)!=0)|0)|0,0,0);h=G[l+216>>2];i=h<<1|G[l+212>>2]>>>31;h=G[l+220>>2]<<1|h>>>31;ed(l+192|0,i,h,0,0,d,e,0,0);e=h;h=G[l+200>>2];ed(l+176|0,i,e,0,0,0-h|0,0-(G[l+204>>2]+((h|0)!=0)|0)|0,0,0);i=d;h=G[l+184>>2];d=h<<1|G[l+180>>2]>>>31;e=d-1|0;h=(G[l+188>>2]<<1|h>>>31)-!d|0;ed(l+160|0,i,k,0,0,e,h,0,0);d=f;j=g<<15|d>>>17;ed(l+144|0,d<<15,j,0,0,e,h,0,0);k=G[l+172>>2];m=G[l+160>>2];B=G[l+152>>2];d=m+B|0;i=G[l+164>>2];j=i+G[l+156>>2]|0;j=d>>>0>>0?j+1|0:j;m=(i|0)==(j|0)&d>>>0>>0|i>>>0>j>>>0;i=m+G[l+168>>2]|0;k=i>>>0>>0?k+1|0:k;m=!j&d>>>0>1|(j|0)!=0;i=m+i|0;k=i>>>0>>0?k+1|0:k;ed(l+112|0,e,h,0,0,0-i|0,0-(((i|0)!=0)+k|0)|0,0,0);ed(l+128|0,1-d|0,0-((d>>>0>1)+j|0)|0,0,0,e,h,0,0);H=(y-x|0)+n|0;e=G[l+116>>2];w=e;d=G[l+112>>2];j=e<<1|d>>>31;m=d<<1;n=j;d=j;h=G[l+140>>2];u=h;e=G[l+136>>2];j=h<<1|e>>>31;i=e<<1|G[l+132>>2]>>>31;h=i+m|0;j=d+j|0;j=h>>>0>>0?j+1|0:j;i=h;e=j;j=j-(h>>>0<13927)|0;r=j;k=q|65536;L=k;B=p;j=p;k=k<<1|j>>>31;p=j<<1|c>>>31;d=0;j=d|k;q=j;v=Au(r,d,j,0);d=Ia;t=d;j=b;d=c<<1|j>>>31;x=j<<1;y=d;h=h-13927|0;j=(e|0)==(r|0)&h>>>0>>0|e>>>0>r>>>0;e=(e|0)==(n|0)&i>>>0>>0|e>>>0>>0;d=G[l+120>>2];k=G[l+124>>2]<<1|d>>>31;i=d<<1;m=j;n=e;e=u>>>31|0;d=e+(w>>>31|i)|0;j=k;j=d>>>0>>0?j+1|0:j;e=d;d=n+d|0;j=d>>>0>>0?j+1|0:j;e=d;d=m+d|0;k=d>>>0>>0?j+1|0:j;e=d;d=d-1|0;C=k-!e|0;D=0;i=Au(y,o,C,D);e=i+v|0;k=Ia+t|0;k=e>>>0>>0?k+1|0:k;m=(k|0)==(t|0)&e>>>0>>0|k>>>0>>0;v=d;i=Au(d,0,p,0);d=i+e|0;j=Ia+k|0;j=d>>>0>>0?j+1|0:j;n=d;i=j;e=(j|0)==(k|0)&d>>>0>>0|j>>>0>>0;d=m+e|0;k=0;k=d>>>0>>0?1:k;e=Au(q,o,C,D);d=e+d|0;j=Ia+k|0;u=d;d=d>>>0>>0?j+1|0:j;m=Au(q,o,v,o);k=Ia;w=Au(C,D,p,o);e=w+m|0;j=Ia+k|0;j=e>>>0>>0?j+1|0:j;w=e;e=j;j=(k|0)==(j|0)&m>>>0>w>>>0|j>>>0>>0;m=u+e|0;d=d+j|0;j=m;m=j>>>0>>0?d+1|0:d;u=j;e=0;d=e+n|0;j=i+w|0;j=d>>>0>>0?j+1|0:j;e=j;k=(j|0)==(i|0)&d>>>0>>0|i>>>0>j>>>0;i=u+k|0;j=m;u=i;i=i>>>0>>0?j+1|0:j;n=d;m=e;w=h;h=Au(h,0,p,o);e=Ia;t=Au(r,o,y,o);d=t+h|0;j=Ia+e|0;j=d>>>0>>0?j+1|0:j;e=(e|0)==(j|0)&d>>>0>>0|e>>>0>j>>>0;h=j;E=u;t=e;F=x&-2;k=Au(v,o,F,0);e=k+d|0;j=Ia+j|0;j=e>>>0>>0?j+1|0:j;u=e;k=e;e=j;h=(j|0)==(h|0)&d>>>0>k>>>0|h>>>0>j>>>0;d=t+h|0;k=0;k=d>>>0>>0?1:k;j=d;h=n+d|0;d=k+m|0;d=h>>>0>>0?d+1|0:d;t=h;j=h;h=d;k=(d|0)==(m|0)&j>>>0>>0|d>>>0>>0;d=E+k|0;j=i;M=d;n=d>>>0>>0?j+1|0:j;I=Au(q,o,w,o);E=Ia;i=Au(C,D,F,o);d=i+I|0;j=Ia+E|0;j=d>>>0>>0?j+1|0:j;C=d;k=Au(r,o,p,o);i=d+k|0;m=j;d=j+Ia|0;d=i>>>0>>0?d+1|0:d;K=i;j=Au(y,o,v,o);i=i+j|0;k=Ia+d|0;D=i;k=i>>>0>>0?k+1|0:k;i=k;v=0;N=(d|0)==(k|0)&D>>>0>>0|d>>>0>k>>>0;j=(d|0)==(m|0)&C>>>0>K>>>0|d>>>0>>0;d=j+((m|0)==(E|0)&C>>>0>>0|m>>>0>>0)|0;k=0;d=N+d|0;m=i|0;k=m+t|0;j=(d|v)+h|0;v=k;d=k;j=d>>>0>>0?j+1|0:j;m=j;h=(h|0)==(j|0)&d>>>0>>0|h>>>0>j>>>0;d=h+M|0;j=n;E=d;h=d>>>0>>0?j+1|0:j;t=Au(r,o,F,o);r=Ia;k=Au(y,o,w,o);d=k+t|0;j=Ia+r|0;j=d>>>0>>0?j+1|0:j;n=0;k=(j|0)==(r|0)&d>>>0>>0|j>>>0>>0;r=j;d=j+u|0;j=(k|n)+e|0;n=d;j=d>>>0>>0?j+1|0:j;u=(e|0)==(j|0)&d>>>0>>0|e>>>0>j>>>0;i=0;e=i+d|0;d=j;k=D+d|0;k=e>>>0>>0?k+1|0:k;e=(d|0)==(k|0)&e>>>0>>0|d>>>0>k>>>0;d=u+e|0;j=0;j=d>>>0>>0?1:j;e=d;d=d+v|0;j=j+m|0;j=d>>>0>>0?j+1|0:j;e=j;j=(m|0)==(j|0)&d>>>0>>0|j>>>0>>0;i=j+E|0;k=h;h=i;k=h>>>0>>0?k+1|0:k;i=k;c:{if((k|0)==131071|k>>>0<131071){ed(l+80|0,d,e,h,i,f,g,A,z);j=b<<17;b=0;c=G[l+88>>2];n=b-c|0;k=G[l+80>>2];m=G[l+84>>2];B=(k|m)!=0;r=n-B|0;n=(j-(G[l+92>>2]+(b>>>0>>0)|0)|0)-(n>>>0>>0)|0;b=k;k=0-k|0;m=0-(((b|0)!=0)+m|0)|0;b=H+16382|0;break c}k=h<<31;d=(e&1)<<31|d>>>1;e=e>>>1|k;h=(i&1)<<31|h>>>1;i=i>>>1|0;ed(l+96|0,d,e,h,i,f,g,A,z);q=0;m=G[l+104>>2];n=q-m|0;k=G[l+96>>2];p=G[l+100>>2];x=(k|p)!=0;r=n-x|0;n=((b<<16)-(G[l+108>>2]+(m>>>0>q>>>0)|0)|0)-(n>>>0>>0)|0;j=k;k=0-j|0;m=0-(((j|0)!=0)+p|0)|0;x=b;y=c;p=B;q=L;b=H+16383|0}if((b|0)>=32767){s=s|2147418112;b=0;c=0;break a}d:{if((b|0)>0){c=r;j=n<<1|c>>>31;r=c<<1|m>>>31;n=j;p=h;q=i&65535|b<<16;j=m<<1|k>>>31;b=k<<1;break d}if((b|0)<=-113){b=0;c=0;break a}eg(l- -64|0,d,e,h,i,1-b|0);od(l+48|0,x,y,p,q,b+112|0);d=G[l+64>>2];e=G[l+68>>2];p=G[l+72>>2];q=G[l+76>>2];ed(l+32|0,f,g,A,z,d,e,p,q);c=G[l+40>>2];i=c<<1;c=G[l+44>>2]<<1|c>>>31;b=G[l+56>>2];h=G[l+36>>2];n=h>>>31|i;i=b-n|0;n=G[l+60>>2]-((b>>>0>>0)+c|0)|0;c=G[l+32>>2];k=h<<1|c>>>31;c=c<<1;j=G[l+52>>2];b=G[l+48>>2];h=(k|0)==(j|0)&c>>>0>b>>>0|j>>>0>>0;r=i-h|0;n=n-(h>>>0>i>>>0)|0;h=b;b=h-c|0;j=j-((c>>>0>h>>>0)+k|0)|0}ed(l+16|0,f,g,A,z,3,0,0,0);ed(l,f,g,A,z,5,0,0,0);h=d;m=p;p=d&1;c=b+p|0;d=0;k=j+d|0;k=b>>>0>c>>>0?k+1|0:k;i=c;c=k;g=(k|0)==(g|0)&i>>>0>f>>>0|g>>>0>>0;d=(d|0)==(k|0)&i>>>0

>>0|d>>>0>k>>>0;b=d+r|0;j=n;j=b>>>0>>0?j+1|0:j;f=b;d=b;b=j;g=(d|0)==(A|0)&(j|0)==(z|0)?g:(z|0)==(j|0)&d>>>0>A>>>0|j>>>0>z>>>0;d=h+g|0;k=e;k=d>>>0>>0?k+1|0:k;g=(e|0)==(k|0)&d>>>0>>0|e>>>0>k>>>0;e=m+g|0;j=q;j=e>>>0>>0?j+1|0:j;g=e;e=d;m=g;d=G[l+20>>2];h=(d|0)==(c|0)&J[l+16>>2]>>0|c>>>0>d>>>0;d=G[l+28>>2];g=G[l+24>>2];h=j>>>0<2147418112&((f|0)==(g|0)&(b|0)==(d|0)?h:(d|0)==(b|0)&g>>>0>>0|b>>>0>d>>>0);g=e+h|0;d=k;d=g>>>0>>0?d+1|0:d;h=(d|0)==(k|0)&e>>>0>g>>>0|d>>>0>>0;e=m+h|0;k=e>>>0>>0?j+1|0:j;h=e;e=G[l+4>>2];i=(e|0)==(c|0)&J[l>>2]>>0|c>>>0>e>>>0;c=G[l+12>>2];e=G[l+8>>2];c=k>>>0<2147418112&((e|0)==(f|0)&(b|0)==(c|0)?i:(c|0)==(b|0)&e>>>0>>0|b>>>0>c>>>0);b=c+g|0;j=b>>>0>>0?d+1|0:d;c=j;f=(d|0)==(j|0)&b>>>0>>0|d>>>0>j>>>0;e=h+f|0;d=k;o=e|o;s=s|(e>>>0>>0?d+1|0:d)}G[a>>2]=b;G[a+4>>2]=c;G[a+8>>2]=o;G[a+12>>2]=s;Fa=l+336|0}function eh(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;e=Fa+-64|0;Fa=e;a:{b=G[309830];if((b|0)<=0){G[47524]=5;break a}c=365;if(b>>>0>10){break a}if(!G[(b<<2)+1239340>>2]){c=362;break a}while(1){h=G[(b<<2)+1239340>>2];c=G[309816];if(c){Wa(c);G[309820]=0;G[309821]=0;G[309818]=0;G[309819]=0;G[309816]=0;G[309817]=0}if(G[309823]){G[309822]=1;c=0;a=G[309824];G[309816]=G[309823];G[309817]=a;G[309823]=0;G[309824]=0;G[309829]=0;a=G[309828];G[309820]=G[309827];G[309821]=a;a=G[309826];G[309818]=G[309825];G[309819]=a;G[309825]=0;G[309826]=0;G[309827]=0;G[309828]=0;break a}G[309822]=0;b:{c=0;b=362;c:{d:{if(!h){break d}f=1;d=ab(1);G[309816]=d;b=360;if(!d){break c}e:{while(1){i=en(h);if((i|0)==13){continue}f:{switch(i+1|0){case 0:if(G[h+76>>2]<0){b=G[h>>2]}else{b=G[h>>2]}d=b>>>5&1?361:0;if(c){break e}b=367;break c;default:b=c+1|0;d=G[309816];g=c+1001|0;g=g-((g|0)%1e3|0)|0;if((g|0)>(f|0)){d=ub(d,g);if(!d){c=b;d=360;break e}G[309816]=d;f=g}E[c+d|0]=i;c=b;continue;case 11:break f}}break}d=0}b=G[309816];g=f;f=c+1|0;g:{if((g|0)!=(f|0)){b=ub(b,f);if(!b){d=360;break g}G[309816]=b}E[c+b|0]=0;b=0;if(!d){break d}}Wa(G[309816]);G[309816]=0;b=d}}c=b;if(c){if((c|0)!=367){break a}c=G[309830]-1|0;G[309830]=c;b=G[(c<<2)+1239344>>2];if(b){Hb(b);c=G[309830]}G[(c<<2)+1239344>>2]=0;if((c|0)>0){break b}c=0;G[47524]=5;break a}if(E[1239288]&1){c=0;break a}c=E[G[309816]];if((c|0)==35|!(a?c:1)){break b}f=0;c=362;b=G[309816];h:{if(!b){break h}G[309817]=0;G[309818]=0;G[309821]=0;G[309819]=0;G[309820]=0;c=b;i:{j:{k:{l:{m:{switch(H[b|0]){case 0:case 10:break j;case 9:case 32:break m;default:break l}}c=b+1|0;n:{switch(H[b+1|0]){case 0:case 10:break j;case 9:case 32:break n;default:break l}}c=b+2|0;o:{switch(H[b+2|0]){case 0:case 10:break j;case 9:case 32:break o;default:break l}}c=b+3|0;p:{switch(H[b+3|0]){case 0:case 10:break j;case 9:case 32:break p;default:break l}}c=b+4|0;q:{switch(H[b+4|0]){case 0:case 10:break j;case 9:case 32:break q;default:break l}}c=b+5|0;r:{switch(H[b+5|0]){case 0:case 10:break j;case 9:case 32:break r;default:break l}}c=b+6|0;s:{switch(H[b+6|0]){case 0:case 10:break j;case 9:case 32:break s;default:break l}}c=b+7|0;switch(H[b+7|0]){case 0:case 10:break j;case 9:case 32:break k;default:break l}}G[309817]=c;t:{u:{v:{w:{while(1){x:{b=c;switch(H[b|0]){case 0:case 10:break u;default:break x}}y:{if(!gc(34939,c,8)){b=jb(c,61);if(b){break y}}b=H[c|0];if((b|0)==9|(b|0)==32){break w}d=1;if((b|0)==61){break v}c=c+1|0;continue}break}c=b;f=1;d=1;if(H[b|0]){break v}break t}d=0}f=d;b=c+1|0}E[c|0]=0}z:{A:{if(!Ib(32708,G[309817])){break A}if(!Ib(33332,G[309817])){break A}if(Ib(35367,G[309817])){break z}}G[309820]=b;B:{while(1){C:{switch(H[b|0]){default:b=b+1|0;continue;case 0:break B;case 10:break C}}break}E[b|0]=0}G[309819]=7;c=0;break h}if(!Ib(35684,G[309817])){while(1){c=H[b|0];if(!((c|0)!=32&(c|0)!=9)){b=b+1|0;continue}break}G[309818]=b;D:{while(1){E:{switch(H[b|0]){default:b=b+1|0;continue;case 0:break D;case 10:break E}}break}E[b|0]=0}G[309819]=0;c=0;break h}while(1){F:{c=0;G:{H:{d=H[b|0];switch(d|0){case 0:case 10:break h;case 9:case 32:break G;default:break H}}if(f&1){break F}f=1;if((d|0)!=61){break F}}b=b+1|0;continue}break}I:{J:{K:{switch(d-39|0){case 8:c=H[b+1|0];if((c|0)==32|(c|0)==9){b=b+2|0}else{b=b+1|0}G[309820]=b;while(1){L:{c=H[b|0];switch(c|0){case 0:break h;case 10:break i;default:break L}}b=b+1|0;continue};case 0:G[309819]=2;c=b+1|0;G[309818]=c;b=c;while(1){d=H[c|0];M:{if((d|0)!=39){switch(d|0){case 0:case 10:break I;default:break M}}f=c+1|0;N:{switch(H[c+1|0]){case 0:case 10:break I;case 9:case 32:break J;case 39:break N;default:break M}}c=f}E[b|0]=d;b=b+1|0;c=c+1|0;continue};default:break K}}G[309819]=0;G[309818]=b;while(1){O:{switch(H[b|0]){default:b=b+1|0;continue;case 0:case 10:break I;case 9:case 32:break O}}break}f=b+1|0}c=0;E[b|0]=0;P:{while(1){Q:{switch(H[f|0]){case 9:case 32:f=f+1|0;continue;case 0:case 10:break h;case 47:break Q;default:break P}}break}c=H[f+1|0];if((c|0)==32|(c|0)==9){b=f+2|0}else{b=f+1|0}G[309820]=b;while(1){R:{c=H[b|0];switch(c|0){case 0:break h;case 10:break i;default:break R}}b=b+1|0;continue}}G[309821]=1;break h}break i}c=b+8|0;G[309820]=c;S:{while(1){T:{switch(H[c|0]){default:c=c+1|0;continue;case 0:break S;case 10:break T}}break}E[c|0]=0;b=G[309816]}E[b|0]=0;G[309819]=7;G[309817]=G[309816];c=0;break h}E[b|0]=0;G[309819]=7;c=G[309816];G[309820]=c;G[309817]=c;c=0;break h}E[b|0]=0;c=0}if(c){break a}c=G[309817];if(!c){break b}b=H[c|0];U:{if(!b){break U}if((b-97&255)>>>0<26){E[c|0]=b-32;c=G[309817]}if(Va(c)>>>0<=1){break U}b=H[c+1|0];if((b-97&255)>>>0<=25){E[c+1|0]=b-32;c=G[309817]}if(Va(c)>>>0<3){break U}b=H[c+2|0];if((b-97&255)>>>0<=25){E[c+2|0]=b-32;c=G[309817]}if(Va(c)>>>0<4){break U}b=H[c+3|0];if((b-97&255)>>>0<=25){E[c+3|0]=b-32;c=G[309817]}if(Va(c)>>>0<5){break U}b=H[c+4|0];if((b-97&255)>>>0<=25){E[c+4|0]=b-32;c=G[309817]}if(Va(c)>>>0<6){break U}b=H[c+5|0];if((b-97&255)>>>0<=25){E[c+5|0]=b-32;c=G[309817]}if(Va(c)>>>0<7){break U}b=H[c+6|0];if((b-97&255)>>>0<=25){E[c+6|0]=b-32;c=G[309817]}if(Va(c)>>>0<8){break U}b=H[c+7|0];if((b-97&255)>>>0>25){break U}E[c+7|0]=b-32}V:{W:{b=G[47529];if((b|0)==-1){break W}c=0;f=G[309817];if(Xa(f,G[47528])){while(1){c=c+1|0;d=(c<<3)+190112|0;b=G[d+4>>2];if((b|0)==-1){break W}if(Xa(f,G[d>>2])){continue}break}}G[47524]=b;if(b){break V}c=dn(G[309818]);if(!c){break b}break a}G[47524]=-1}G[310098]=0;a=G[309819];c=G[309818];X:{if(c){if((a|0)==2){G[310118]=c;G[310098]=2;break X}Y:{if(Ib(33560,c)){if(Ib(35337,G[309818])){break Y}}G[310098]=1;j=1240472,k=!Ib(33560,G[309818]),E[j|0]=k}if(G[310098]){break X}G[e+48>>2]=1240472;G[e+52>>2]=1240480;G[e+56>>2]=e+60;Z:{if((Qc(G[309818],16222,e+48|0)|0)!=2){break Z}_:{switch(H[G[309818]+G[e+60>>2]|0]){case 0:case 9:case 10:case 32:break _;default:break Z}}G[310098]=5;break X}if(G[310098]){break X}a=G[309818];$:{if(!jb(a,46)){break $}G[e+32>>2]=1240472;G[e+36>>2]=e+60;if((Qc(a,16211,e+32|0)|0)!=1){break $}aa:{ba:{ca:{a=G[e+60>>2];c=a+G[309818]|0;b=H[c|0];switch(b|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:break $;case 0:case 9:case 10:case 32:break ba;default:break ca}}if((b|0)!=68){break $}E[c|0]=69;G[e+16>>2]=1240472;G[e+20>>2]=e+60;Qc(G[309818],16211,e+16|0);da:{c=G[309818];switch(H[c+G[e+60>>2]|0]){case 0:case 9:case 10:case 32:break da;default:break aa}}G[310098]=4;break X}G[310098]=4;break X}E[a+c|0]=68}if(G[310098]){break X}G[e>>2]=1240472;G[e+4>>2]=e+60;ea:{if((Qc(G[309818],16217,e)|0)!=1){break ea}fa:{switch(H[G[309818]+G[e+60>>2]|0]){case 0:case 9:case 10:case 32:break fa;default:break ea}}G[310098]=3;break X}if(G[310098]){break X}G[310098]=2;G[310118]=G[309818];break X}if((a|0)==7){G[310098]=7;break X}G[310098]=6}a=G[309820];ga:{if(a){rb(1240488,a,80);E[1240567]=0;break ga}E[1240488]=0}rb(1240396,G[309817],75);E[1240470]=0;c=Va(1240396)>>>0>75?368:0;break a}b=G[309830];continue}}Fa=e- -64|0;return c} -function Wd(){var a=0,b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;c=Fa-8496|0;Fa=c;a:{b:{c:{d:{e:{b=G[948156];switch(b-2|0){case 5:case 7:break b;case 6:case 8:break c;case 2:break d;case 0:break e;default:break a}}if(!(E[3788484]&1)){if(!G[950330]){Lb()}a=Xb(5);Yb(41684,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a);G[947121]=G[947121]+1;break a}if(!H[3792672]){break a}a=G[950330];b=Uf(G[G[(G[950332]+(a<<2)|0)-4>>2]+24>>2],44);if(!b){break a}E[b|0]=0;if(!H[3792672]){break a}if(!a){Lb()}a=Xb(Va(3792672)+1|0);Yb(3792672,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a);break a}if(!(E[3788484]&1)){if(!G[950330]){Lb()}a=Xb(5);Yb(41684,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a);G[947121]=G[947121]+1;break a}if(!H[3792672]){break a}a=G[950330];b=Uf(G[G[(G[950332]+(a<<2)|0)-4>>2]+24>>2],44);if(!b){break a}E[b|0]=0;if(!H[3792672]){break a}if(!a){Lb()}a=Xb(Va(3792672)+1|0);Yb(3792672,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a);break a}if(E[3788484]&1){break b}if(!G[950330]){Lb()}a=Xb(5);Yb(41684,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a);G[947121]=G[947121]+1;b=G[948156]}b=b-7|0;f:{if(b>>>0>=4){b=G[24367];g:{if(H[3780288]){G[c+276>>2]=3780288;G[c+272>>2]=4094;Tb(b,69475,c+272|0);break g}G[c+256>>2]=4094;Tb(b,68751,c+256|0)}b=0;a=G[945062];h:{if(!a){break h}d=a+(G[945063]<<2)|0;a=G[d>>2];if(!a){break h}G[a+16>>2]=0;E[G[a+4>>2]]=0;E[G[a+4>>2]+1|0]=0;G[a+44>>2]=0;G[a+28>>2]=1;e=G[a+4>>2];G[a+8>>2]=e;if((a|0)!=G[d>>2]){break h}a=G[a+16>>2];G[945064]=e;G[950324]=a;G[945070]=e;G[945057]=G[G[d>>2]>>2];E[3780260]=H[e|0]}E[3801300]=1;break f}b=G[(b<<2)+188988>>2]}r=Lc(G[G[(G[950332]+(G[950330]<<2)|0)-4>>2]+24>>2]);i:{while(1){a=Uf(r,44);if(!a){break i}E[a|0]=0;a=a+1|0;s=(c+288|0)+(b<<3)|0,t=vb(a,c+4396|0),L[s>>3]=t;if((a|0)==G[c+4396>>2]){break i}a=(b|0)<=0;b=b-1|0;if(!a){continue}break}j:{k:{l:{switch(G[948156]-7|0){case 1:case 3:l=L[c+304>>3];i=L[c+320>>3];p=(L[c+312>>3]-l)/i;m=L[c+328>>3];j=L[c+360>>3];q=(L[c+344>>3]-m)/j;break k;default:b=G[24367];m:{if(H[3780288]){G[c+212>>2]=3780288;G[c+208>>2]=4094;Tb(b,69475,c+208|0);break m}G[c+192>>2]=4094;Tb(b,68751,c+192|0)}b=0;a=G[945062];n:{if(!a){break n}d=a+(G[945063]<<2)|0;a=G[d>>2];if(!a){break n}G[a+16>>2]=0;E[G[a+4>>2]]=0;E[G[a+4>>2]+1|0]=0;G[a+44>>2]=0;G[a+28>>2]=1;e=G[a+4>>2];G[a+8>>2]=e;if((a|0)!=G[d>>2]){break n}a=G[a+16>>2];G[945064]=e;G[950324]=a;G[945070]=e;G[945057]=G[G[d>>2]>>2];E[3780260]=H[e|0]}E[3801300]=1;break j;case 0:case 2:break l}}l=L[c+304>>3];i=L[c+320>>3];p=(L[c+312>>3]-l)/i;m=L[c+328>>3];j=L[c+344>>3];q=(L[c+336>>3]-m)/j}n=1;if(O(i)<2147483648){e=~~i}else{e=-2147483648}a=(e|0)<=0;if(O(j)<2147483648){d=~~j}else{d=-2147483648}b=0;if((d|0)<=0|a){break j}while(1){i=+(n|0)*p+l;j=+(n-1|0)*p+l;o=1;while(1){L[c+248>>3]=i;L[c+240>>3]=j;L[c+232>>3]=+(o|0)*q+m;L[c+224>>3]=+(o-1|0)*q+m;Ya(c+4400|0,4096,19673,c+224|0);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];if(H[c+4400|0]){a=Va(c+4400|0);g=0;h=G[b+52>>2];if(!(!h|!H[h|0])){g=Va(h)}f=G[b+56>>2];a=a+g|0;if((f|0)<=(a+1|0)){a=a+2|0;k=f+1024|0;f=((f^-1)+((a|0)>(k|0)?a:k)&-1024)+k|0;G[b+56>>2]=f}o:{if(!g){a=Ic(f,1);break o}a=lf(h,f)}G[b+52>>2]=a;Gb(a,c+4400|0);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2]}f=0;h=G[b+52>>2];if(!(!h|!H[h|0])){f=Va(h)}g=G[b+56>>2];if((g|0)<=(f+2|0)){a=f+3|0;k=g+1024|0;g=((g^-1)+((a|0)>(k|0)?a:k)&-1024)+k|0;G[b+56>>2]=g}a=b;p:{if(!f){b=Ic(g,1);break p}b=lf(h,g)}G[a+52>>2]=b;b=Va(b)+b|0;E[b|0]=10;E[b+1|0]=0;b=(d|0)!=(o|0);o=o+1|0;if(b){continue}break}b=(e|0)!=(n|0);n=n+1|0;if(b){continue}break}b=M(d,e)}G[c+176>>2]=b;d=c+4400|0;Ya(d,4096,66542,c+176|0);a=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(d,a+32|0,a+36|0);G[c+160>>2]=b<<1;Ya(d,4096,66542,c+160|0);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(d,b+40|0,b+44|0);b=G[950330];if(!b){Lb();b=G[950330]}b=G[(G[950332]+(b<<2)|0)-4>>2];G[b+4>>2]=G[b+4>>2]|32}pb(r);E[3805456]=1}a=G[947121];b=El(a);if((b|0)>0){G[c+152>>2]=a;d=b-1|0;a=d<<2;G[c+144>>2]=G[a+188864>>2];G[c+148>>2]=G[a+188928>>2];E[3780288]=0;Ya(c+4400|0,4096,(d&-3)==1?62159:b-9>>>0<2?62110:62077,c+144|0);a=G[24367];q:{if(H[3780288]){G[c+132>>2]=3780288;G[c+128>>2]=c+4400;Tb(a,69475,c+128|0);break q}G[c+112>>2]=c+4400;Tb(a,68751,c+112|0)}a=G[945062];r:{if(!a){break r}d=a+(G[945063]<<2)|0;a=G[d>>2];if(!a){break r}G[a+16>>2]=0;E[G[a+4>>2]]=0;E[G[a+4>>2]+1|0]=0;G[a+44>>2]=0;G[a+28>>2]=1;e=G[a+4>>2];G[a+8>>2]=e;if((a|0)!=G[d>>2]){break r}a=G[a+16>>2];G[945064]=e;G[950324]=a;G[945070]=e;G[945057]=G[G[d>>2]>>2];E[3780260]=H[e|0]}E[3801300]=1}s:{if(G[948156]!=13&(b|0)>=0){break s}if(H[G[(G[950332]+(G[950330]<<2)|0)-4>>2]+4|0]&32){a=G[24367];t:{if(H[3780288]){G[c+100>>2]=3780288;G[c+96>>2]=48740;Tb(a,69475,c+96|0);break t}G[c+80>>2]=48740;Tb(a,68751,c+80|0)}a=G[945062];u:{if(!a){break u}d=a+(G[945063]<<2)|0;a=G[d>>2];if(!a){break u}G[a+16>>2]=0;E[G[a+4>>2]]=0;E[G[a+4>>2]+1|0]=0;G[a+44>>2]=0;G[a+28>>2]=1;e=G[a+4>>2];G[a+8>>2]=e;if((a|0)!=G[d>>2]){break u}a=G[a+16>>2];G[945064]=e;G[950324]=a;G[945070]=e;G[945057]=G[G[d>>2]>>2];E[3780260]=H[e|0]}E[3801300]=1}G[c+72>>2]=0;G[c+76>>2]=1128267776;G[c+64>>2]=0;G[c+68>>2]=1128267776;Ya(3788528,4096,19679,c- -64|0);if(H[3788528]){if(!G[950330]){Lb()}d=Xb(Va(3788528)+1|0);Yb(3788528,d);a=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(d,a+24|0,a+12|0);pb(d)}if(G[948156]==13){break s}d=G[(G[950332]+(G[950330]<<2)|0)-4>>2];a=G[d+28>>2];if(a){e=Lc(a+G[d+24>>2]|0);if(e){d=G[950330];a=G[(G[950332]+(d<<2)|0)-4>>2];E[G[a+24>>2]+G[a+28>>2]|0]=0;if(!d){Lb()}d=Xb(2);Yb(4031,d);a=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(d,a+24|0,a+12|0);pb(d);if(H[e|0]){if(!G[950330]){Lb()}d=Xb(Va(e)+1|0);Yb(e,d);a=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(d,a+24|0,a+12|0);pb(d)}v:{w:{switch(G[948156]-1|0){case 0:b=G[947121]-3|0;break v;case 1:b=(G[947121]-5|0)/2|0;break v;case 2:b=G[947121]-3|0;break v;case 3:b=(G[947121]-5|0)/2|0;break v;case 10:b=G[947121]-3|0;break v;case 11:b=G[947121]/2|0;break v;default:break w}}_i(36230)}G[c+48>>2]=b;a=c+288|0;Ya(a,4096,66542,c+48|0);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+32|0,b+36|0);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+40|0,b+44|0);E[3805456]=1;Wa(e)}b=G[950330];if(!b){Lb();b=G[950330]}b=G[(G[950332]+(b<<2)|0)-4>>2];G[b+4>>2]=G[b+4>>2]|64;break s}b=G[24367];x:{if(H[3780288]){G[c+36>>2]=3780288;G[c+32>>2]=7128;Tb(b,69475,c+32|0);break x}G[c+16>>2]=7128;Tb(b,68751,c+16|0)}b=G[945062];y:{if(!b){break y}a=b+(G[945063]<<2)|0;b=G[a>>2];if(!b){break y}G[b+16>>2]=0;E[G[b+4>>2]]=0;E[G[b+4>>2]+1|0]=0;G[b+44>>2]=0;G[b+28>>2]=1;d=G[b+4>>2];G[b+8>>2]=d;if((b|0)!=G[a>>2]){break y}b=G[b+16>>2];G[945064]=d;G[950324]=b;G[945070]=d;G[945057]=G[G[a>>2]>>2];E[3780260]=H[d|0]}E[3801300]=1}if(!H[3805456]){G[c>>2]=1;a=c+288|0;Ya(a,4096,66542,c);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+32|0,b+36|0);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+40|0,b+44|0)}a=G[950220];if(a){b=G[a+156>>2];if(b){b=Ja[b|0](a,64244)|0}else{b=64244}}else{b=0}Te(b);E[3792672]=0;E[3805456]=0;Fa=c+8496|0}function _j(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;p=Fa-496|0;Fa=p;r=G[o>>2];a:{if((r|0)>0){break a}if((b|0)>=5){Ua(28364);r=320;G[o>>2]=320;break a}r=G[a>>2];if((r|0)!=G[G[a+4>>2]+76>>2]){mb(a,r+1|0,0,o)}E[p+421|0]=0;E[p+350|0]=0;E[p+279|0]=0;E[p+208|0]=0;G[p+28>>2]=0;Cb(a,16,35146,p+208|0,0,p+28|0);b:{if(G[p+28>>2]){break b}q=p+421|0;s=p+350|0;t=p+279|0;r=p+208|0;while(1){w=H[r|0];if(!w){break b}if((w|0)!=44){r=r+1|0;continue}break}E[r|0]=0;while(1){w=H[r+1|0];r=r+1|0;if((w|0)==32){continue}break}r=Za(t,r);while(1){t=H[r|0];if(!t){break b}if((t|0)!=44){r=r+1|0;continue}break}E[r|0]=0;while(1){t=H[r+1|0];r=r+1|0;if((t|0)==32){continue}break}r=Za(s,r);while(1){s=H[r|0];if(!s){break b}if((s|0)!=44){r=r+1|0;continue}break}E[r|0]=0;while(1){s=H[r+1|0];r=r+1|0;if((s|0)==32){continue}break}Za(q,r)}c:{d:{if((b|0)<=0){break d}r=0;while(1){w=M(r,71);s=w+c|0;e:{if(H[s|0]){break e}q=Za(s,w+(p+208|0)|0);if(H[q|0]|r>>>0>3){break e}z=r<<4;t=z&31;t=(z&63)>>>0>=32?5505114>>>t|0:((1<>>t;E[q|0]=t;E[q+1|0]=t>>>8}z=r<<2;t=z+j|0;if((dc(a,0,s,t,o)|0)>0){F[p+152>>1]=H[66839]|H[66840]<<8;a=H[66835]|H[66836]<<8|(H[66837]<<16|H[66838]<<24);G[p+144>>2]=H[66831]|H[66832]<<8|(H[66833]<<16|H[66834]<<24);G[p+148>>2]=a;a=H[66827]|H[66828]<<8|(H[66829]<<16|H[66830]<<24);G[p+136>>2]=H[66823]|H[66824]<<8|(H[66825]<<16|H[66826]<<24);G[p+140>>2]=a;a=H[66819]|H[66820]<<8|(H[66821]<<16|H[66822]<<24);G[p+128>>2]=H[66815]|H[66816]<<8|(H[66817]<<16|H[66818]<<24);G[p+132>>2]=a;a=H[66811]|H[66812]<<8|(H[66813]<<16|H[66814]<<24);G[p+120>>2]=H[66807]|H[66808]<<8|(H[66809]<<16|H[66810]<<24);G[p+124>>2]=a;a=H[66803]|H[66804]<<8|(H[66805]<<16|H[66806]<<24);G[p+112>>2]=H[66799]|H[66800]<<8|(H[66801]<<16|H[66802]<<24);G[p+116>>2]=a;a=p+112|0;Ua(qb(a,s,80-Va(a)|0));break d}q=G[t>>2];if(G[(G[G[a+4>>2]+968>>2]+M(q,160)|0)-72>>2]>=2){G[p+136>>2]=H[67342]|H[67343]<<8|(H[67344]<<16|H[67345]<<24);a=H[67338]|H[67339]<<8|(H[67340]<<16|H[67341]<<24);G[p+128>>2]=H[67334]|H[67335]<<8|(H[67336]<<16|H[67337]<<24);G[p+132>>2]=a;a=H[67330]|H[67331]<<8|(H[67332]<<16|H[67333]<<24);G[p+120>>2]=H[67326]|H[67327]<<8|(H[67328]<<16|H[67329]<<24);G[p+124>>2]=a;a=H[67322]|H[67323]<<8|(H[67324]<<16|H[67325]<<24);G[p+112>>2]=H[67318]|H[67319]<<8|(H[67320]<<16|H[67321]<<24);G[p+116>>2]=a;break c}eo(a,q,p+24|0,o);q=G[p+24>>2];if(!((q|0)>=0&(q|0)!=16)){a=H[67314]|H[67315]<<8|(H[67316]<<16|H[67317]<<24);G[p+152>>2]=H[67310]|H[67311]<<8|(H[67312]<<16|H[67313]<<24);G[p+156>>2]=a;a=H[67306]|H[67307]<<8|(H[67308]<<16|H[67309]<<24);G[p+144>>2]=H[67302]|H[67303]<<8|(H[67304]<<16|H[67305]<<24);G[p+148>>2]=a;a=H[67298]|H[67299]<<8|(H[67300]<<16|H[67301]<<24);G[p+136>>2]=H[67294]|H[67295]<<8|(H[67296]<<16|H[67297]<<24);G[p+140>>2]=a;a=H[67290]|H[67291]<<8|(H[67292]<<16|H[67293]<<24);G[p+128>>2]=H[67286]|H[67287]<<8|(H[67288]<<16|H[67289]<<24);G[p+132>>2]=a;a=H[67282]|H[67283]<<8|(H[67284]<<16|H[67285]<<24);G[p+120>>2]=H[67278]|H[67279]<<8|(H[67280]<<16|H[67281]<<24);G[p+124>>2]=a;a=H[67274]|H[67275]<<8|(H[67276]<<16|H[67277]<<24);G[p+112>>2]=H[67270]|H[67271]<<8|(H[67272]<<16|H[67273]<<24);G[p+116>>2]=a;break c}G[p+8>>2]=1589294263;G[p+12>>2]=-1196933592;G[p+16>>2]=1589294263;G[p+20>>2]=-1196933592;f:{q=g+w|0;if(!H[q|0]){break f}if(!Cb(a,82,q,(r<<3)+d|0,0,o)){break f}Ua(25703);Ua(q);break d}g:{q=r<<3;u=L[q+d>>3];if(u!=-91191291391491e-49){L[l+q>>3]=u;break g}v=p+32|0;zb(34547,G[t>>2],v,o);A=v;v=l+q|0;if((Cb(a,82,A,v,0,o)|0)<=0){break g}G[o>>2]=0;if((Cn(a,G[t>>2],v,p+8|0,o)|0)<=0){break g}a=H[67393]|H[67394]<<8|(H[67395]<<16|H[67396]<<24);E[p+159|0]=a;E[p+160|0]=a>>>8;E[p+161|0]=a>>>16;E[p+162|0]=a>>>24;a=H[67390]|H[67391]<<8|(H[67392]<<16|H[67393]<<24);G[p+152>>2]=H[67386]|H[67387]<<8|(H[67388]<<16|H[67389]<<24);G[p+156>>2]=a;a=H[67382]|H[67383]<<8|(H[67384]<<16|H[67385]<<24);G[p+144>>2]=H[67378]|H[67379]<<8|(H[67380]<<16|H[67381]<<24);G[p+148>>2]=a;a=H[67374]|H[67375]<<8|(H[67376]<<16|H[67377]<<24);G[p+136>>2]=H[67370]|H[67371]<<8|(H[67372]<<16|H[67373]<<24);G[p+140>>2]=a;a=H[67366]|H[67367]<<8|(H[67368]<<16|H[67369]<<24);G[p+128>>2]=H[67362]|H[67363]<<8|(H[67364]<<16|H[67365]<<24);G[p+132>>2]=a;a=H[67358]|H[67359]<<8|(H[67360]<<16|H[67361]<<24);G[p+120>>2]=H[67354]|H[67355]<<8|(H[67356]<<16|H[67357]<<24);G[p+124>>2]=a;a=H[67350]|H[67351]<<8|(H[67352]<<16|H[67353]<<24);G[p+112>>2]=H[67346]|H[67347]<<8|(H[67348]<<16|H[67349]<<24);G[p+116>>2]=a;a=p+112|0;Ua(qb(a,s,80-Va(a)|0));break d}h:{v=h+w|0;if(!H[v|0]){break h}if(!Cb(a,82,v,e+q|0,0,o)){break h}Ua(25659);Ua(v);break d}i:{u=L[e+q>>3];if(u!=-91191291391491e-49){L[m+q>>3]=u;break i}v=p+32|0;zb(33036,G[t>>2],v,o);C=1;A=v;v=m+q|0;if((Cb(a,82,A,v,0,o)|0)<=0){break i}G[o>>2]=0;u=L[p+8>>3];if(u!=-91191291391491e-49){L[v>>3]=u;break i}if((Cn(a,G[t>>2],p+16|0,v,o)|0)<=0){break i}a=H[67393]|H[67394]<<8|(H[67395]<<16|H[67396]<<24);E[p+159|0]=a;E[p+160|0]=a>>>8;E[p+161|0]=a>>>16;E[p+162|0]=a>>>24;a=H[67390]|H[67391]<<8|(H[67392]<<16|H[67393]<<24);G[p+152>>2]=H[67386]|H[67387]<<8|(H[67388]<<16|H[67389]<<24);G[p+156>>2]=a;a=H[67382]|H[67383]<<8|(H[67384]<<16|H[67385]<<24);G[p+144>>2]=H[67378]|H[67379]<<8|(H[67380]<<16|H[67381]<<24);G[p+148>>2]=a;a=H[67374]|H[67375]<<8|(H[67376]<<16|H[67377]<<24);G[p+136>>2]=H[67370]|H[67371]<<8|(H[67372]<<16|H[67373]<<24);G[p+140>>2]=a;a=H[67366]|H[67367]<<8|(H[67368]<<16|H[67369]<<24);G[p+128>>2]=H[67362]|H[67363]<<8|(H[67364]<<16|H[67365]<<24);G[p+132>>2]=a;a=H[67358]|H[67359]<<8|(H[67360]<<16|H[67361]<<24);G[p+120>>2]=H[67354]|H[67355]<<8|(H[67356]<<16|H[67357]<<24);G[p+124>>2]=a;a=H[67350]|H[67351]<<8|(H[67352]<<16|H[67353]<<24);G[p+112>>2]=H[67346]|H[67347]<<8|(H[67348]<<16|H[67349]<<24);G[p+116>>2]=a;a=p+112|0;Ua(qb(a,s,80-Va(a)|0));break d}j:{s=i+w|0;if(!H[s|0]){break j}if(!Cb(a,82,s,f+q|0,0,o)){break j}Ua(25747);Ua(s);break d}s=f+q|0;u=L[s>>3];if(u==0){Ua(41873);r=322;G[o>>2]=322;break a}k:{if(u!=-91191291391491e-49){L[n+q>>3]=u;break k}G[p+28>>2]=0;v=G[t>>2];t=p+32|0;w=p+28|0;zb(34579,v,t,w);if((Cb(a,82,t,s,0,w)|0)<=0){break k}s=n+q|0;u=(L[m+q>>3]-L[l+q>>3])/10;L[s>>3]=u;if(!(u>1)){break k}G[s>>2]=0;G[s+4>>2]=1072693248}v=l+q|0;u=L[v>>3];w=m+q|0;y=L[w>>3];l:{m:{if(u>y){x=L[n+q>>3];if(x>0){break m}}x=L[n+q>>3];if(!(u>3]=x;y=L[w>>3];u=L[v>>3]}t=G[p+24>>2];if(O(x)<2147483648){q=~~x}else{q=-2147483648}if(O(y)<2147483648){s=~~y}else{s=-2147483648}A=(t|0)>41;if(O(u)<2147483648){t=~~u}else{t=-2147483648}n:{if(!(A|+(t|0)!=u|(+(s|0)!=y|+(q|0)!=x))){G[k+z>>2]=((s-t|0)/(q|0)|0)+1;if(u>3]=u+-.5;L[w>>3]=L[w>>3]+.5;break n}L[v>>3]=u+.5;L[w>>3]=L[w>>3]+-.5;break n}B=(y-u)/x;if(C){q=k+z|0;u=B+1;if(O(u)<2147483648){G[q>>2]=~~u;break n}G[q>>2]=-2147483648;break n}s=k+z|0;if(O(B)<2147483648){q=~~B}else{q=-2147483648}G[s>>2]=q;x=+(q|0)*x+u;if(u>2]=q+1;break n}if(!(x>y)){break n}G[s>>2]=q+1}r=r+1|0;if((r|0)!=(b|0)){continue}break}}r=G[o>>2];break a}a=p+112|0;Ua(qb(a,s,80-Va(a)|0));r=410;G[o>>2]=410}Fa=p+496|0;return r}function Vp(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,H=0,I=0,J=0,K=0,L=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Ga=0,Ha=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Va=0,Wa=0,Xa=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,kb=0,lb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0;ga=1;j=Fa-400|0;Fa=j;a:{if(b-10>>>0<=4294967286){G[j>>2]=b;a=j+32|0;Ya(a,81,23817,j);Ua(a);G[i>>2]=320;break a}if(Nb(a,i)){if((b|0)!=1){c=b&-2;while(1){l=k<<3;m=j+32|0;t=l+m|0;o=k<<2;s=G[o+d>>2];G[t>>2]=s;G[t+4>>2]=s>>31;r=l;l=j+128|0;t=r+l|0;o=G[e+o>>2];G[t>>2]=o;G[t+4>>2]=o>>31;r=m;m=k|1;t=m<<3;o=r+t|0;m=m<<2;s=G[m+d>>2];G[o>>2]=s;G[o+4>>2]=s>>31;l=l+t|0;m=G[e+m>>2];G[l>>2]=m;G[l+4>>2]=m>>31;k=k+2|0;p=p+2|0;if((c|0)!=(p|0)){continue}break}}if(b&1){b=k<<3;c=b+(j+32|0)|0;m=d;d=k<<2;l=G[m+d>>2];G[c>>2]=l;G[c+4>>2]=l>>31;b=b+(j+128|0)|0;c=G[d+e>>2];G[b>>2]=c;G[b+4>>2]=c>>31}G[j+352>>2]=0;md(a,31,j+32|0,j+128|0,f,1,j+352|0,g,0,h,i);break a}if((Dc(a,j+124|0,i)|0)>0){break a}v=G[j+124>>2];b:{if(!v){m=1;ga=2;o=1;l=1;break b}k=b<<2;m=G[k+f>>2];o=G[d+k>>2];l=G[e+k>>2]}if(h){G[h>>2]=0}G[j+352>>2]=1;G[j+356>>2]=1;k=1;G[j+128>>2]=1;G[j+132>>2]=0;G[j+304>>2]=1;G[j+308>>2]=1;G[j+256>>2]=1;G[j+260>>2]=1;G[j+136>>2]=1;G[j+140>>2]=0;G[j+208>>2]=1;G[j+212>>2]=1;G[j+360>>2]=1;G[j+144>>2]=1;G[j+148>>2]=0;G[j+312>>2]=1;G[j+316>>2]=1;G[j+264>>2]=1;G[j+268>>2]=1;G[j+152>>2]=1;G[j+156>>2]=0;G[j+216>>2]=1;G[j+220>>2]=1;G[j+364>>2]=1;G[j+368>>2]=1;G[j+320>>2]=1;G[j+272>>2]=1;G[j+160>>2]=1;G[j+164>>2]=0;G[j+224>>2]=1;G[j+372>>2]=1;G[j+376>>2]=1;G[j+168>>2]=1;G[j+172>>2]=0;G[j+324>>2]=1;G[j+328>>2]=1;G[j+276>>2]=1;G[j+280>>2]=1;G[j+176>>2]=1;G[j+180>>2]=0;G[j+228>>2]=1;G[j+232>>2]=1;G[j+184>>2]=1;G[j+188>>2]=0;G[j+380>>2]=1;G[j+384>>2]=1;G[j+332>>2]=1;G[j+336>>2]=1;G[j+284>>2]=1;G[j+288>>2]=1;G[j+192>>2]=1;G[j+196>>2]=0;G[j+236>>2]=1;G[j+240>>2]=1;c:{while(1){q=p<<2;s=G[q+e>>2];r=G[d+q>>2];d:{if((s|0)>=(r|0)){u=G[q+(j+208|0)>>2];break d}if(v){break c}G[q+(j+208|0)>>2]=-1;u=-1}G[q+(j+304|0)>>2]=s;G[q+(j+352|0)>>2]=r;G[q+(j+256|0)>>2]=G[f+q>>2];w=j+128|0;s=p+1|0;r=w+(s<<3)|0;q=G[c+q>>2];q=Au(k,t,q,q>>31);G[r>>2]=q;x=r;r=Ia;G[x+4>>2]=r;p=w+(p<<3)|0;Cb=p,Db=Au(k,t,u,u>>31),G[Cb>>2]=Db;G[p+4>>2]=Ia;k=q;t=r;p=s;if((p|0)!=(b|0)){continue}break}d=(j+128|0)+(b<<3)|0;e=G[d>>2];k=e;e=G[(j+208|0)+(b<<2)>>2];Cb=d,Db=Au(k,G[d+4>>2],e,e>>31),G[Cb>>2]=Db;G[d+4>>2]=Ia;e:{if(!((b|0)!=1|G[c>>2]!=1)){k=(l-o|0)/(m|0)|0;l=o;d=m;break e}b=G[j+208>>2];d=M(b,G[j+256>>2]);k=(M(b,G[j+304>>2]-G[j+352>>2]|0)|0)/G[f>>2]|0}if((l|0)<(o|0)){break a}y=G[j+240>>2];$=M(y,G[j+384>>2]);b=M(y,G[j+336>>2]);if(($|0)>(b|0)){break a}z=G[j+236>>2];v=M(z,G[j+380>>2]);P=M(z,G[j+332>>2]);if((v|0)>(P|0)){break a}A=G[j+232>>2];w=M(A,G[j+376>>2]);Q=M(A,G[j+328>>2]);if((w|0)>(Q|0)){break a}B=G[j+228>>2];R=M(B,G[j+372>>2]);S=M(B,G[j+324>>2]);if((R|0)>(S|0)){break a}C=G[j+224>>2];s=M(C,G[j+368>>2]);T=M(C,G[j+320>>2]);if((s|0)>(T|0)){break a}D=G[j+220>>2];q=M(D,G[j+364>>2]);U=M(D,G[j+316>>2]);if((q|0)>(U|0)){break a}E=G[j+216>>2];r=M(E,G[j+360>>2]);V=M(E,G[j+312>>2]);if((r|0)>(V|0)){break a}F=G[j+212>>2];u=M(F,G[j+356>>2]);W=M(F,G[j+308>>2]);if((u|0)>(W|0)){break a}X=k+1|0;Aa=X>>31;Ba=G[j+192>>2];Ca=G[j+196>>2];Da=G[j+184>>2];Ea=G[j+188>>2];Ga=G[j+176>>2];Ha=G[j+180>>2];Ja=G[j+168>>2];Ka=G[j+172>>2];La=G[j+160>>2];Ma=G[j+164>>2];Na=G[j+152>>2];Oa=G[j+156>>2];Pa=G[j+144>>2];Qa=G[j+148>>2];c=G[j+352>>2];ha=c;Ra=c>>31;Sa=G[j+136>>2];Ta=G[j+140>>2];Va=l;ia=l>>31;ja=m;Wa=m>>31;aa=o;ba=o>>31;Xa=b;ka=b>>31;Za=y>>31;_a=$>>31;la=P>>31;$a=z>>31;H=G[j+284>>2];b=H;H=b;ab=b>>31;bb=v>>31;ma=Q>>31;cb=A>>31;I=G[j+280>>2];b=I;I=b;db=b>>31;eb=w>>31;na=S>>31;fb=B>>31;J=G[j+276>>2];b=J;J=b;gb=b>>31;hb=R>>31;oa=T>>31;ib=C>>31;K=G[j+272>>2];b=K;K=b;jb=b>>31;kb=s>>31;pa=U>>31;lb=D>>31;L=G[j+268>>2];b=L;L=b;mb=b>>31;nb=q>>31;qa=V>>31;ob=E>>31;N=G[j+264>>2];b=N;N=b;pb=b>>31;qb=r>>31;ra=W>>31;rb=F>>31;O=G[j+260>>2];b=O;O=b;sb=b>>31;tb=u>>31;b=G[j+288>>2];sa=b;ub=b>>31;e=0;while(1){o=$;ca=_a;while(1){f:{if(X){ta=Au(Ba,Ca,o-y|0,ca-((o>>>0>>0)+Za|0)|0);vb=Ia;c=v;f=bb;while(1){ua=Au(Da,Ea,c-z|0,f-((c>>>0>>0)+$a|0)|0);wb=Ia;l=w;m=eb;while(1){va=Au(Ga,Ha,l-A|0,m-((l>>>0>>0)+cb|0)|0);xb=Ia;p=R;da=hb;while(1){wa=Au(Ja,Ka,p-B|0,da-((p>>>0>>0)+fb|0)|0);yb=Ia;Y=s;ea=kb;while(1){xa=Au(La,Ma,Y-C|0,ea-((C>>>0>Y>>>0)+ib|0)|0);zb=Ia;Z=q;fa=nb;while(1){ya=Au(Na,Oa,Z-D|0,fa-((D>>>0>Z>>>0)+lb|0)|0);Ab=Ia;_=r;x=qb;while(1){za=Au(Pa,Qa,_-E|0,x-((E>>>0>_>>>0)+ob|0)|0);Bb=Ia;k=u;t=tb;while(1){if(G[i>>2]>0){break a}n=Au(Sa,Ta,k-F|0,t-((k>>>0>>0)+rb|0)|0)+ha|0;b=Ra+Ia|0;b=n>>>0>>0?b+1|0:b;n=n+za|0;b=b+Bb|0;b=n>>>0>>0?b+1|0:b;n=n+ya|0;b=b+Ab|0;b=n>>>0>>0?b+1|0:b;n=n+xa|0;b=b+zb|0;b=n>>>0>>0?b+1|0:b;n=n+wa|0;b=b+yb|0;b=n>>>0>>0?b+1|0:b;n=n+va|0;b=b+xb|0;b=n>>>0>>0?b+1|0:b;n=n+ua|0;b=b+wb|0;b=n>>>0>>0?b+1|0:b;n=n+ta|0;b=b+vb|0;Ud(a,ga,aa,ba,n,n>>>0>>0?b+1|0:b,X,Aa,d,1,0,(e<<2)+g|0,j+123|0,j+32|0,i);if(G[i>>2]>0){break a}if(!(!h|!G[j+32>>2])){G[h>>2]=1}e=e+X|0;b=t+sb|0;k=k+O|0;b=k>>>0>>0?b+1|0:b;t=b;if(k>>>0<=W>>>0&(ra|0)>=(b|0)|(b|0)<(ra|0)){continue}break}b=x+pb|0;k=N+_|0;b=k>>>0>>0?b+1|0:b;_=k;x=b;if(k>>>0<=V>>>0&(qa|0)>=(b|0)|(b|0)<(qa|0)){continue}break}b=fa+mb|0;k=L+Z|0;b=k>>>0>>0?b+1|0:b;Z=k;fa=b;if(k>>>0<=U>>>0&(pa|0)>=(b|0)|(b|0)<(pa|0)){continue}break}b=ea+jb|0;k=K+Y|0;b=k>>>0>>0?b+1|0:b;Y=k;ea=b;if(k>>>0<=T>>>0&(oa|0)>=(b|0)|(b|0)<(oa|0)){continue}break}b=da+gb|0;k=p+J|0;b=k>>>0>>0?b+1|0:b;p=k;da=b;if(k>>>0<=S>>>0&(na|0)>=(b|0)|(b|0)<(na|0)){continue}break}b=m+db|0;l=l+I|0;b=l>>>0>>0?b+1|0:b;m=b;if(l>>>0<=Q>>>0&(ma|0)>=(b|0)|(b|0)<(ma|0)){continue}break}b=f+ab|0;c=c+H|0;b=c>>>0>>0?b+1|0:b;f=b;if(c>>>0<=P>>>0&(la|0)>=(b|0)|(b|0)<(la|0)){continue}break}break f}g:{if(!h){break g}m=v;if(!G[j+32>>2]){break g}while(1){k=w;while(1){l=R;while(1){f=s;while(1){b=q;while(1){c=r;while(1){p=u;while(1){if(G[i>>2]>0){break a}G[h>>2]=1;p=p+O|0;if((W|0)>=(p|0)){continue}break}c=c+N|0;if((V|0)>=(c|0)){continue}break}b=b+L|0;if((U|0)>=(b|0)){continue}break}f=f+K|0;if((T|0)>=(f|0)){continue}break}l=l+J|0;if((S|0)>=(l|0)){continue}break}k=k+I|0;if((Q|0)>=(k|0)){continue}break}m=m+H|0;if((P|0)>=(m|0)){continue}break}break f}if(G[i>>2]>0){break a}}b=ca+ub|0;c=o+sa|0;b=c>>>0>>0?b+1|0:b;o=c;ca=b;if(c>>>0<=Xa>>>0&(ka|0)>=(b|0)|(b|0)<(ka|0)){continue}break}b=ba+Wa|0;c=aa+ja|0;b=c>>>0>>0?b+1|0:b;aa=c;ba=b;if(c>>>0<=Va>>>0&(ia|0)>=(b|0)|(b|0)<(ia|0)){continue}break}break a}G[j+16>>2]=p+1;a=j+32|0;Ya(a,81,26876,j+16|0);Ua(a);G[i>>2]=321}Fa=j+400|0}function Un(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;d=Fa-10176|0;Fa=d;G[d+9108>>2]=0;G[d+9104>>2]=0;G[d+9100>>2]=0;G[d+9096>>2]=6;G[d+9076>>2]=0;G[d+9072>>2]=0;G[d+9068>>2]=0;G[d+9064>>2]=0;G[d+9060>>2]=0;G[d+9056>>2]=0;G[d+6652>>2]=5001813;E[d+1119|0]=0;G[d+1112>>2]=0;if(!G[c>>2]){G[d+9080>>2]=G[G[a+4>>2]+84>>2];a:{if(G[d+9080>>2]!=1){Ua(58442);G[c>>2]=349;b=0;break a}j=c,k=Mj(a,d+1112|0,c),G[j>>2]=k;e=mb(G[d+1112>>2],b,d+9100|0,c);G[c>>2]=e;b=0;if(e){break a}b=Fc(G[d+1112>>2],34516,d+6736|0,d+1120|0,c);G[c>>2]=b;b:{if((b|0)==202){G[d+6736>>2]=1296650832;G[d+6740>>2]=5853761;G[c>>2]=0;break b}b=Va(d+6736|0);if(H[d+6736|0]!=39|H[(b+d|0)+6735|0]!=39){break b}b=b-2|0;if((b|0)>0){e=d+6736|0;yd(e,e|1,b)}E[b+(d+6736|0)|0]=0}b=0;c:{d:{e=Va(d+6736|0)-1|0;if((e|0)<=0){break d}while(1){if(H[(d+6736|0)+b|0]!=32){break d}b=b+1|0;if((e|0)!=(b|0)){continue}break}break c}if((b|0)==(e|0)|(e|0)<0){break c}while(1){b=(d+6736|0)+e|0;if(H[b|0]!=32){break c}E[b|0]=0;b=(e|0)>0;e=e-1|0;if(b){continue}break}}b=Ec(G[d+1112>>2],33996,d+9076|0,d+1120|0,c);G[c>>2]=b;if((b|0)==202){G[d+9076>>2]=1;G[c>>2]=0}b=Fc(G[d+1112>>2],35480,d+6656|0,d+1120|0,c);G[c>>2]=b;e:{if((b|0)==202){E[d+6656|0]=0;G[c>>2]=0;break e}b=Va(d+6656|0);if(H[d+6656|0]!=39|H[(b+d|0)+6655|0]!=39){break e}b=b-2|0;if((b|0)>0){e=d+6656|0;yd(e,e|1,b)}E[b+(d+6656|0)|0]=0}b=0;f:{g:{e=Va(d+6656|0)-1|0;if((e|0)<=0){break g}while(1){if(H[(d+6656|0)+b|0]!=32){break g}b=b+1|0;if((e|0)!=(b|0)){continue}break}break f}if((b|0)==(e|0)|(e|0)<0){break f}while(1){b=(d+6656|0)+e|0;if(H[b|0]!=32){break f}E[b|0]=0;b=(e|0)>0;e=e-1|0;if(b){continue}break}}G[d+9108>>2]=G[G[d+1112>>2]>>2]+1;j=c,k=yf(G[d+1112>>2],d+7856|0,d+6816|0,d+8976|0,d+8896|0,d+9088|0,c),G[j>>2]=k;if(!H[d+7856|0]){Za(d+7856|0,d+6816|0);Za(d+8976|0,d+8896|0)}e=yf(a,d+5456|0,d+4416|0,d+6576|0,d+6496|0,d+9084|0,c);G[c>>2]=e;b=0;if(e){break a}if(!G[d+9084>>2]){Ua(58442);G[c>>2]=349;break a}h:{i:{if(!Ib(d+6576|0,42185)){break i}if(!Ib(d+8976|0,42185)){break i}E[d+1296|0]=0;break h}e=G[c>>2];j:{if(e){break j}if(!ui(d+9136|0,1025)){E[d+1296|0]=0;Ua(61910);e=125;break j}bf(d+9136|0,1025,d+1296|0,c);e=G[c>>2]}G[c>>2]=e;if(!Ib(d+8976|0,42185)){k:{if(H[d+7856|0]==47){Za(d+6816|0,d+7856|0);break k}e=Za(d+6816|0,d+1296|0);if((Va(e)+Va(d+7856|0)|0)-1024>>>0<=4294966270){Ua(58292);G[c>>2]=125;break a}g=Va(e)+e|0;E[g|0]=47;E[g+1|0]=0;Gb(e,d+7856|0)}j=c,k=_d(d+6816|0,d+7856|0,c),G[j>>2]=k}if(!Ib(d+6576|0,42185)){l:{if(H[d+5456|0]==47){Za(d+4416|0,d+5456|0);break l}e=Za(d+4416|0,d+1296|0);if((Va(e)+Va(d+5456|0)|0)-1024>>>0<=4294966270){Ua(58338);G[c>>2]=125;break a}g=Va(e)+e|0;E[g|0]=47;E[g+1|0]=0;Gb(e,d+5456|0)}j=c,k=_d(d+4416|0,d+5456|0,c),G[j>>2]=k}if(Ib(d+6576|0,42185)){break h}if(Ib(d+8976|0,42185)){break h}e=d+7856|0;g=d+5456|0;f=d+4416|0;Tn(e,g,f,c);h=d+6816|0;Tn(g,e,h,c);Za(e,h);Za(g,f)}j=c,k=Ec(a,33996,d+9072|0,d+1120|0,c),G[j>>2]=k;se(G[G[G[d+1112>>2]+4>>2]+12>>2],d+3376|0,c);se(G[G[a+4>>2]+12>>2],d+2336|0,c);m:{if(G[G[d+1112>>2]+4>>2]==G[a+4>>2]){break m}if(!fb(d+3376|0,d+2336|0,1025)){break m}G[d+9072>>2]=0-G[d+9072>>2]}j=c,k=ik(a,d+9064|0,c),G[j>>2]=k;e=hk(a,d+6736|0,d+6656|0,G[d+9076>>2],G[d+9108>>2],d+7856|0,d+9068|0,c);G[c>>2]=e;n:{if(e){if((e|0)!=342){break a}G[c>>2]=0;b=G[d+9064>>2];j=c,k=Ig(a,b,b>>31,1,0,c),G[j>>2]=k;G[d+9064>>2]=G[d+9064>>2]+1;j=c,k=jk(a,d+9132|0,d+9128|0,d+9124|0,d+9120|0,d+9116|0,d+9112|0,d+9104|0,c),G[j>>2]=k;G[d+1292>>2]=d+6736;b=G[d+9132>>2];if(b){e=b;b=G[d+9064>>2];dg(a,e,b,b>>31,1,0,1,0,d+1292|0,c)}G[d+1292>>2]=d+6656;b=G[d+9128>>2];o:{if(!b){break o}e=G[d+9064>>2];g=e>>31;if(H[d+6656|0]){dg(a,b,e,g,1,0,1,0,d+1292|0,c);break o}pe(a,b,e,g,1,0,1,0,d+1119|0,c)}b=G[d+9124>>2];if(b){e=b;b=G[d+9064>>2];xe(a,e,b,b>>31,1,0,1,0,d+9076|0,c)}b=G[d+9120>>2];if(b){e=b;b=G[d+9064>>2];Jo(a,e,b,b>>31,1,0,1,0,d+9108|0,c)}G[d+1292>>2]=d+7856;p:{if(!G[d+9116>>2]){break p}se(G[G[G[d+1112>>2]+4>>2]+12>>2],d+3376|0,c);se(G[G[a+4>>2]+12>>2],d+2336|0,c);q:{if(G[G[d+1112>>2]+4>>2]==G[a+4>>2]){break q}if(!fb(d+3376|0,d+2336|0,1025)){break q}b=G[d+9064>>2];dg(a,G[d+9116>>2],b,b>>31,1,0,1,0,d+1292|0,c);break p}b=G[d+9064>>2];pe(a,G[d+9116>>2],b,b>>31,1,0,1,0,d+1119|0,c)}G[d+1292>>2]=d+6652;b=0;if(!G[d+9112>>2]){break n}se(G[G[G[d+1112>>2]+4>>2]+12>>2],d+3376|0,c);se(G[G[a+4>>2]+12>>2],d+2336|0,c);r:{if(G[G[d+1112>>2]+4>>2]==G[a+4>>2]){break r}if(!fb(d+3376|0,d+2336|0,1025)){break r}e=G[d+9064>>2];dg(a,G[d+9112>>2],e,e>>31,1,0,1,0,d+1292|0,c);break n}e=G[d+9064>>2];pe(a,G[d+9112>>2],e,e>>31,1,0,1,0,d+1119|0,c);break n}Ua(58480);b=341}if(G[c>>2]){break a}G[d+9080>>2]=G[G[G[d+1112>>2]+4>>2]+84>>2];if(!(G[d+9080>>2]==1?G[d+9088>>2]:0)){Ua(58588);Ua(d+7856|0);break a}j=c,k=lh(G[d+1112>>2],d+9060|0,c),G[j>>2]=k;G[d+9092>>2]=1;s:{g=G[d+9060>>2];if((g|0)<=0){break s}h=H[d+1296|0];t:{while(1){if(G[c>>2]){break s}G[d+64>>2]=g;e=d+1216|0;Ya(e,75,30030,d- -64|0);j=c,k=Ec(G[d+1112>>2],e,d+9056|0,d+1120|0,c),G[j>>2]=k;e=0;f=G[d+9056>>2];u:{if((f|0)!=G[d+9072>>2]){break u}if((f|0)>=0){G[d+9092>>2]=G[d+9092>>2]+1;break t}G[d+48>>2]=g;f=d+1216|0;Ya(f,75,30038,d+48|0);f=Di(0,f,d+6812|0,d+1120|0,c);G[c>>2]=f;if(!f){f=G[d+6812>>2];Za(d+9136|0,f);Wa(f)}v:{w:{if(!h){break w}x:{if(ad(d+9136|0)){break x}bf(d+9136|0,1025,d+4416|0,c);if(H[d+4416|0]==47){break x}f=Za(d+80|0,d+1296|0);if((Va(f)+Va(d+4416|0)|0)-1024>>>0<4294966271){break v}i=Va(f)+f|0;E[i|0]=47;E[i+1|0]=0;_d(Gb(f,d+4416|0),d+9136|0,c)}if(ad(d+5456|0)){break w}bf(d+5456|0,1025,d+4416|0,c);if(H[d+4416|0]==47){break w}f=Za(d+80|0,d+1296|0);if((Va(f)+Va(d+4416|0)|0)-1024>>>0<4294966271){break v}e=Va(f)+f|0;E[e|0]=47;E[e+1|0]=0;e=d+4416|0;_d(Gb(f,e),e,c)}e=!Xa(d+9136|0,d+4416|0);break u}Ua(58247);G[c>>2]=125}f=G[d+9092>>2];G[d+9092>>2]=f+1;if(!e&(f|0)<(g|0)){continue}break}if(!e){break s}}Ua(58383);break a}if(!g){e=0;G[d+9092>>2]=0;f=202;G[c>>2]=202;h=G[d+9096>>2];y:{if((h|0)>0){while(1){if((f|0)!=202){break y}G[c>>2]=0;f=kc(G[d+1112>>2],G[(e<<2)+120048>>2],d+1120|0,c);G[c>>2]=f;e=e+1|0;G[d+9092>>2]=e;if((e|0)<(h|0)){continue}break}if((f|0)!=202){break y}}G[c>>2]=0;Td(G[d+1112>>2],d+9096|0,d+9092|0,c);Sd(G[d+1112>>2],G[d+9096>>2],d+1120|0,c);f=G[c>>2]}if(f){break a}}e=g+1|0;G[d+9060>>2]=e;se(G[G[G[d+1112>>2]+4>>2]+12>>2],d+3376|0,c);se(G[G[a+4>>2]+12>>2],d+2336|0,c);z:{if(G[G[d+1112>>2]+4>>2]!=G[a+4>>2]){if(fb(d+3376|0,d+2336|0,1025)){break z}}G[d>>2]=e;a=d+1216|0;Ya(a,75,30030,d);e=a;a=G[d+9072>>2];Fh(G[d+1112>>2],e,a,a>>31,33159,c);break a}G[d+32>>2]=e;a=d+1216|0;Ya(a,75,30030,d+32|0);g=G[d+9072>>2];Fh(G[d+1112>>2],a,g,g>>31,33159,c);G[d+16>>2]=e;Ya(a,75,30038,d+16|0);uq(G[d+1112>>2],a,d+5456|0,13320,c);nq(G[d+1112>>2],c)}a=Qb(G[d+1112>>2],c);G[c>>2]=a?a:b}Fa=d+10176|0}function qf(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,H=0;w=Fa-16|0;Fa=w;a:{if(!a){break a}g=d|e;if((g|0)<0){hb(86572,46,1,G[24367]);break a}if(!g){h=Ee(a,b,c);break a}k=ab(64);g=G[a+36>>2];f=G[a+40>>2];i=G[a+32>>2];G[k+32>>2]=i;b:{c:{if(i-1>>>0<=2){i=f-1|0;o=(e|0)>(i|0)?i:e;e=g-1|0;l=(d|0)>(e|0)?e:d;d=G[a+44>>2];G[k+44>>2]=d;d:{e:{f:{switch(d|0){case 0:d=(l|0)<=0;if(!(d|(o|0)<=0)){G[k+36>>2]=1;G[k+40>>2]=1;g=1;f=1;d=1;break e}if(!d){f=1;G[k+40>>2]=1;d=g-l|0;g=(d|0)>1?d:1;G[k+36>>2]=g;d=g;break e}d=1;if((o|0)<=0){break d}G[k+36>>2]=1;e=f-o|0;g=(e|0)>1?e:1;G[k+40>>2]=g;f=g;break e;case 2:d=((g|0)>(f|0)?g:f)-(l+o|0)|0;e=f-o|0;e=(d|0)<(e|0)?d:e;f=(e|0)>1?e:1;G[k+40>>2]=f;e=g-l|0;d=(d|0)<(e|0)?d:e;d=(d|0)>1?d:1;G[k+36>>2]=d;e=d>>>0>>0?d:f;g=M(d,f)+((M(e-1|0,e)|0)/-2|0)|0;break e;default:break f}}d=f-o|0;f=(d|0)>1?d:1;G[k+40>>2]=f;d=g-l|0;d=(d|0)>1?d:1;G[k+36>>2]=d;g=M(d,f)}G[k+48>>2]=g}L[k>>3]=L[a>>3];L[k+8>>3]=L[a+8>>3];L[k+16>>3]=L[a+16>>3];L[k+24>>3]=L[a+24>>3];F=k,H=ab(g<<3),G[F+52>>2]=H;F=k,H=ab(d<<3),G[F+56>>2]=H;F=k,H=ab(f<<3),G[F+60>>2]=H;f=G[a+48>>2];d=f<<3;e=G[321349];if((d|0)>(e|0)){break c}g=G[321350];break b}G[w>>2]=i;_a(G[24367],75005,w);break a}g:{if((e|0)>0){g=ub(G[321350],d);f=G[a+48>>2];break g}g=ab(d)}G[321349]=d;G[321350]=g}h:{if((f|0)<=0){break h}i=G[a+52>>2];e=0;d=0;if(f-1>>>0>=3){n=f&-4;while(1){j=d<<3;L[j+g>>3]=L[i+j>>3];q=j|8;L[q+g>>3]=L[i+q>>3];q=j|16;L[q+g>>3]=L[i+q>>3];j=j|24;L[j+g>>3]=L[i+j>>3];d=d+4|0;m=m+4|0;if((n|0)!=(m|0)){continue}break}}m=f&3;if(!m){break h}while(1){j=d<<3;L[j+g>>3]=L[i+j>>3];d=d+1|0;e=e+1|0;if((m|0)!=(e|0)){continue}break}}i:{j:{switch(G[k+44>>2]-1|0){case 0:d=G[a+40>>2];if((d|0)<=(o|0)){break i}e=G[k+36>>2];v=(e|0)<=0;t=v|(o|0)<=0;r=e&-4;q=e&3;u=e-1|0;d=d-1|0;m=G[a+36>>2];g=(M(d,m)<<3)+g|0;n=G[k+52>>2]+(M(e,G[k+40>>2]-1|0)<<3)|0;z=0-m<<3;A=0-e<<3;while(1){e=d;if(!t){i=e-o|0;a=e;while(1){h=+(a|0);f=0;d=0;j=0;if(u>>>0>=3){while(1){p=(d+l<<3)+g|0;L[p>>3]=L[p>>3]*h;p=((d|1)+l<<3)+g|0;L[p>>3]=L[p>>3]*h;p=((d|2)+l<<3)+g|0;L[p>>3]=L[p>>3]*h;p=((d|3)+l<<3)+g|0;L[p>>3]=L[p>>3]*h;d=d+4|0;j=j+4|0;if((r|0)!=(j|0)){continue}break}}if(q){while(1){j=(d+l<<3)+g|0;L[j>>3]=L[j>>3]*h;d=d+1|0;f=f+1|0;if((q|0)!=(f|0)){continue}break}}a=a-1|0;if((i|0)<(a|0)){continue}break}}i=0;a=m;if((l|0)<(a|0)){while(1){j=a-1|0;if((l|0)>0){f=m-(l+i|0)|0;d=m+(i^-1)|0;p=(d|0)>(f|0)?f:d;B=d-p|0;x=(j<<3)+g|0;h=L[x>>3];f=0;d=a;p=d-p&7;if(p){while(1){d=d-1|0;h=h*+(d|0);f=f+1|0;if((p|0)!=(f|0)){continue}break}}if(B>>>0>=7){a=a-l|0;while(1){h=h*+(d-1|0)*+(d-2|0)*+(d-3|0)*+(d-4|0)*+(d-5|0)*+(d-6|0)*+(d-7|0);d=d-8|0;h=h*+(d|0);if((a|0)<(d|0)){continue}break}}L[x>>3]=h}i=i+1|0;a=j;if((l|0)<(a|0)){continue}break}}k:{if(v){break k}f=0;d=0;j=0;if(u>>>0>=3){while(1){L[(d<<3)+n>>3]=L[(d+l<<3)+g>>3];a=d|1;L[(a<<3)+n>>3]=L[(a+l<<3)+g>>3];a=d|2;L[(a<<3)+n>>3]=L[(a+l<<3)+g>>3];a=d|3;L[(a<<3)+n>>3]=L[(a+l<<3)+g>>3];d=d+4|0;j=j+4|0;if((r|0)!=(j|0)){continue}break}}if(!q){break k}while(1){L[(d<<3)+n>>3]=L[(d+l<<3)+g>>3];d=d+1|0;f=f+1|0;if((q|0)!=(f|0)){continue}break}}d=e-1|0;g=g+z|0;n=n+A|0;if((e|0)>(o|0)){continue}break};break i;default:d=(l|0)<=0;if(!(d|(o|0)<=0)){a=G[k+52>>2];G[a>>2]=0;G[a+4>>2]=0;break i}if(!d){a=G[a+36>>2];if((a|0)<=(l|0)){break i}j=G[k+52>>2]+(G[k+48>>2]<<3)|0;m=0;e=a;while(1){f=a-(l+m|0)|0;d=a+(m^-1)|0;n=(d|0)>(f|0)?f:d;q=d-n|0;i=e-1|0;r=(i<<3)+g|0;h=L[r>>3];f=0;d=e;n=d-n&7;if(n){while(1){d=d-1|0;h=h*+(d|0);f=f+1|0;if((n|0)!=(f|0)){continue}break}}j=j-8|0;if(q>>>0>=7){e=e-l|0;while(1){h=h*+(d-1|0)*+(d-2|0)*+(d-3|0)*+(d-4|0)*+(d-5|0)*+(d-6|0)*+(d-7|0);d=d-8|0;h=h*+(d|0);if((d|0)>(e|0)){continue}break}}L[r>>3]=h;L[j>>3]=h;m=m+1|0;e=i;if((l|0)<(e|0)){continue}break}break i}if((o|0)<=0){break i}f=(f<<3)+g|0;g=G[k+52>>2];a=G[a+40>>2];l:{if((a|0)<=(o|0)){break l}i=o+1|0;e=a-o|0;if(e&1){f=f-8|0;h=L[f>>3];d=a;while(1){d=d-1|0;h=h*+(d|0);if((d|0)>(e|0)){continue}break}L[f>>3]=h;e=a-1|0}else{e=a}if((a|0)==(i|0)){break l}while(1){a=e-o|0;i=f-8|0;h=L[i>>3];d=e;while(1){d=d-1|0;h=h*+(d|0);if((a|0)<(d|0)){continue}break}L[i>>3]=h;d=e-1|0;a=d-o|0;f=f-16|0;h=L[f>>3];while(1){d=d-1|0;h=h*+(d|0);if((a|0)<(d|0)){continue}break}L[f>>3]=h;e=e-2|0;if((o|0)<(e|0)){continue}break}}i=G[k+48>>2];if((i|0)<=0){break i}e=0;d=0;if(i-1>>>0>=3){j=i&-4;m=0;while(1){a=d<<3;L[a+g>>3]=L[a+f>>3];n=a|8;L[n+g>>3]=L[f+n>>3];n=a|16;L[n+g>>3]=L[f+n>>3];a=a|24;L[a+g>>3]=L[a+f>>3];d=d+4|0;m=m+4|0;if((j|0)!=(m|0)){continue}break}}a=i&3;if(!a){break i}while(1){i=d<<3;L[i+g>>3]=L[f+i>>3];d=d+1|0;e=e+1|0;if((a|0)!=(e|0)){continue}break};break i;case 1:break j}}e=G[a+40>>2];if((o|0)>=(e|0)){break i}r=G[a+36>>2];a=(e|0)<(r|0)?r:e;z=a+1|0;A=1-o|0;B=(a-e|0)+1|0;g=(f<<3)+g|0;n=G[k+52>>2]+(G[k+48>>2]<<3)|0;q=G[k+36>>2];a=G[k+40>>2];a=((a|0)<(q|0)?q:a)+o|0;x=a+1|0;D=(a-e|0)+1|0;u=D;while(1){a=x-e|0;p=(a|0)<(q|0)?a:q;E=(p|0)>0?p:0;a=z-e|0;a=(a|0)<(r|0)?a:r;a=(a|0)>0?a:0;g=g-(a<<3)|0;t=e+A|0;if(!((p|0)<=0|(t|0)>=(e|0))){d=v+D|0;d=(d|0)>(q|0)?q:d;d=(d|0)>0?d:0;C=d-1|0;y=d&2147483644;m=d&3;i=e;while(1){i=i-1|0;h=+(i|0);f=0;d=0;j=0;if(C>>>0>=3){while(1){s=(d+l<<3)+g|0;L[s>>3]=L[s>>3]*h;s=((d|1)+l<<3)+g|0;L[s>>3]=L[s>>3]*h;s=((d|2)+l<<3)+g|0;L[s>>3]=L[s>>3]*h;s=((d|3)+l<<3)+g|0;L[s>>3]=L[s>>3]*h;d=d+4|0;j=j+4|0;if((y|0)!=(j|0)){continue}break}}if(m){while(1){j=(d+l<<3)+g|0;L[j>>3]=L[j>>3]*h;d=d+1|0;f=f+1|0;if((m|0)!=(f|0)){continue}break}}if((i|0)>(t|0)){continue}break}}if((a|0)>(l|0)){d=v+B|0;d=(d|0)>(r|0)?r:d;j=(d|0)>0?d:0;m=0;while(1){i=a-1|0;if((l|0)>0){f=j-(l+m|0)|0;d=j+(m^-1)|0;t=(d|0)>(f|0)?f:d;C=d-t|0;y=(i<<3)+g|0;h=L[y>>3];f=0;d=a;t=d-t&7;if(t){while(1){d=d-1|0;h=h*+(d|0);f=f+1|0;if((t|0)!=(f|0)){continue}break}}if(C>>>0>=7){a=a-l|0;while(1){h=h*+(d-1|0)*+(d-2|0)*+(d-3|0)*+(d-4|0)*+(d-5|0)*+(d-6|0)*+(d-7|0);d=d-8|0;h=h*+(d|0);if((a|0)<(d|0)){continue}break}}L[y>>3]=h}m=m+1|0;a=i;if((l|0)<(a|0)){continue}break}}n=n-(E<<3)|0;m:{if((p|0)<=0){break m}a=(q|0)<(u|0)?q:u;a=(a|0)>0?a:0;i=a&3;f=0;d=0;if(a-1>>>0>=3){a=a&2147483644;j=0;while(1){L[(d<<3)+n>>3]=L[(d+l<<3)+g>>3];m=d|1;L[(m<<3)+n>>3]=L[(l+m<<3)+g>>3];m=d|2;L[(m<<3)+n>>3]=L[(l+m<<3)+g>>3];m=d|3;L[(m<<3)+n>>3]=L[(l+m<<3)+g>>3];d=d+4|0;j=j+4|0;if((a|0)!=(j|0)){continue}break}}if(!i){break m}while(1){L[(d<<3)+n>>3]=L[(d+l<<3)+g>>3];d=d+1|0;f=f+1|0;if((i|0)!=(f|0)){continue}break}}v=v+1|0;u=u+1|0;e=e-1|0;if((o|0)<(e|0)){continue}break}}h=Ee(k,b,c);if(G[k+32>>2]!=3){b=L[k+16>>3];h=h*($b(L[k>>3],+(l|0))*$b(b,+(o|0)))}a=G[k+56>>2];if(a){Wa(a)}a=G[k+60>>2];if(a){Wa(a)}a=G[k+52>>2];if(a){Wa(a)}Wa(k)}Fa=w+16|0;return h}function Wl(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,H=0,I=0,J=0,K=0,M=0,N=0,P=0;g=Fa-544|0;Fa=g;if(a){j=G[935573];n=G[29763];y=1e99;k=a;while(1){a:{if((j|0)<=1){z=G[k+4>>2];s=z?z:a;break a}yb(48596);G[g+528>>2]=C;kb(86337,g+528|0);$a(n);z=G[k+4>>2];s=z?z:a;j=G[935573];if((j|0)<2){break a}j=G[G[k>>2]+48>>2];G[g+516>>2]=G[G[s>>2]+48>>2];G[g+512>>2]=j;kb(74948,g+512|0);$a(n);j=G[935573]}k=G[k>>2];b=L[k+16>>3];s=G[s>>2];e=L[s+24>>3];c=L[k+24>>3];f=L[s+16>>3];i=b*e-c*f;h=c;c=L[s+32>>3];d=L[k+32>>3];q=h*c-d*e;o=d*f-b*c;b=V(i*i+(q*q+o*o));if(!(!(b>3]=b;gb(73024,g+496|0);$a(n)}if(!(b<=0)){o=o/b;q=q/b;i=i/b}C=C+1|0;j=G[935573];l=L[23878];p=-q;v=-o;f=999;h=-999;s=a;while(1){A=G[s>>2];c=L[A+16>>3];e=L[A+24>>3];b=c*o+e*p;d=L[A+32>>3];e=e*i+d*v;c=q*d-c*i;d=V(b*b+(e*e+c*c));if(!(!(d>3]=d;gb(73024,g+480|0);$a(n)}if(!(d<=0)){c=c/d;e=e/d;b=b/d}d=L[k+32>>3];r=L[k+16>>3];m=L[k+24>>3];t=b*d+(e*r+c*m);l=L[23878];u=e*m-c*r;m=c*d-b*m;d=b*r-e*d;d=V(u*u+(m*m+d*d));j=G[935573];if(!(!(l>d)|(j|0)<3)){L[g+464>>3]=d;gb(73024,g+464|0);$a(n);l=L[23878];j=G[935573]}d=Db(d<=0?0:d,t);if(dh){D=e;E=c;F=b;h=d}s=G[s+4>>2];if(s){continue}break}if((j|0)>=2){L[g+448>>3]=f;gb(72101,g+448|0);L[g+432>>3]=h;gb(72086,g+432|0);$a(n);j=G[935573]}b=q*x-o*w;e=o*B-i*x;c=i*w-q*B;f=V(b*b+(e*e+c*c));if(!(!(f>3]=f;gb(73024,g+416|0);$a(n)}if(!(f<=0)){c=c/f;e=e/f;b=b/f}f=q*E-o*D;l=o*F-i*E;d=p*F+i*D;h=V(f*f+(l*l+d*d));if(!(!(h>3]=h;gb(73024,g+400|0);$a(n)}if(!(h<=0)){d=d/h;l=l/h;f=f/h}h=b+f;r=e+l;m=c+d;b=V(h*h+(r*r+m*m));if(!(!(b>3]=b;gb(73024,g+384|0);$a(n)}if(!(b<=0)){m=m/b;r=r/b;h=h/b}b=Db(m,r);e=fc(h);c=L[467827];b=b/c;if(b>=360){while(1){b=b+-360;if(b>=360){continue}break}}if(b<0){while(1){b=b+360;if(b<0){continue}break}}if(G[935573]>=2){yb(86384);L[g+376>>3]=e/c;L[g+368>>3]=b;gb(71544,g+368|0);$a(n)}v=r*o+m*p;t=m*i-h*o;u=q*h-r*i;p=V(v*v+(t*t+u*u));A=p<=0;b=A?1:p;H=u/b;I=v/b;J=t/b;P=-J;s=G[935573];l=L[23878];f=999;k=a;while(1){j=G[k>>2];if(!(!(l>p)|(s|0)<3)){L[g+352>>3]=p;gb(73024,g+352|0);$a(n);l=L[23878];s=G[935573]}e=L[j+24>>3];c=L[j+16>>3];b=J*e-H*c;d=L[j+32>>3];e=H*d-I*e;c=P*d+I*c;d=V(b*b+(e*e+c*c));if(!(!(d>3]=d;gb(73024,g+336|0);$a(n);l=L[23878];s=G[935573]}if(!(d<=0)){c=c/d;e=e/d;b=b/d}d=i*b+(q*e+o*c);if(d>2];if(k){continue}break}if(!(!(l>p)|(s|0)<3)){L[g+320>>3]=p;gb(73024,g+320|0);$a(n)}if(!A){t=t/p;u=u/p;v=v/p}e=K*u-M*t;c=M*v-N*u;f=N*t-K*v;b=V(e*e+(c*c+f*f));if(!(!(b>3]=b;gb(73024,g+304|0);$a(n)}if(!(b<=0)){f=f/b;c=c/b;e=e/b}b=Db(f,c);d=fc(e);i=L[467827];b=b/i;if(b>=360){while(1){b=b+-360;if(b>=360){continue}break}}if(b<0){while(1){b=b+360;if(b<0){continue}break}}j=G[935573];if((j|0)>=2){yb(86378);L[g+296>>3]=d/i;L[g+288>>3]=b;gb(71544,g+288|0);$a(n);j=G[935573]}o=h+e;q=r+c;p=m+f;b=V(o*o+(q*q+p*p));if(!(!(b>3]=b;gb(73024,g+272|0);$a(n)}if(!(b<=0)){p=p/b;q=q/b;o=o/b}b=Db(p,q);d=fc(o);u=b;b=L[467827];l=u/b;if(l>=360){while(1){l=l+-360;if(l>=360){continue}break}}if(l<0){while(1){l=l+360;if(l<0){continue}break}}v=d/b;j=G[935573];if((j|0)>=2){yb(86169);L[g+264>>3]=v;L[g+256>>3]=l;gb(71544,g+256|0);$a(n);j=G[935573]}i=c*m+f*-r;f=f*h-e*m;c=r*e-c*h;b=V(i*i+(f*f+c*c));if(!(!(b>3]=b;gb(73024,g+240|0);$a(n)}if(!(b<=0)){i=i/b;f=f/b;c=c/b}b=Db(c,f);d=fc(i);e=L[467827];b=b/e;if(b>=360){while(1){b=b+-360;if(b>=360){continue}break}}if(b<0){while(1){b=b+360;if(b<0){continue}break}}j=G[935573];if((j|0)>=2){yb(86373);L[g+232>>3]=d/e;L[g+224>>3]=b;gb(71544,g+224|0);$a(n);j=G[935573];e=L[467827]}d=Sc(i+(f*0+c*0));b=Sc(o+(q*0+p*0));c=Sc(o*i+(q*f+p*c));f=ib(b);h=ib(c);b=eb(b);c=eb(c);d=Sc((eb(d)-b*c)/(f*h))/e;if((j|0)>=2){yb(86236);L[g+208>>3]=d;gb(70953,g+208|0);$a(n);e=L[467827]}f=v*e;b=ib(f);L[467844]=b;L[467858]=b;i=d*e;c=eb(i);h=eb(f);r=c*h;L[467850]=r;f=ib(i);i=h*f;L[467847]=i;m=l*e;e=ib(m);t=h*e;L[467843]=t;u=h;h=eb(m);m=u*h;L[467842]=m;L[467860]=r;L[467859]=i;L[467855]=t;L[467852]=m;i=b*-c;r=f*h;L[467849]=e*i-r;m=f*e;L[467848]=m+h*i;i=c*h;t=b*-f;L[467846]=i+e*t;u=h*t;t=c*e;L[467845]=u-t;e=b*-e;L[467857]=c*e-r;L[467856]=e*f+i;b=b*-h;L[467854]=c*b+m;L[467853]=b*f-t;e=1e20;c=-1e20;f=-1e20;i=1e20;j=a;while(1){k=G[j>>2];Vl(L[k>>3],L[k+8>>3]);b=L[467839];c=b>c?b:c;e=bf?b:f;i=b>2];if(j){continue}break}j=G[935573];if((j|0)>=2){L[g+192>>3]=i;gb(71604,g+192|0);L[g+176>>3]=f;gb(71574,g+176|0);L[g+160>>3]=e;gb(71589,g+160|0);L[g+144>>3]=c;gb(71559,g+144|0);$a(n);j=G[935573]}b=O(i);f=O(f);b=b>f?b:f;b=b+b;e=O(e);c=O(c);e=c=2){L[g+128>>3]=e;gb(71619,g+128|0);$a(n);j=G[935573]}if(e=180){while(1){d=d+-360;if(d>=180){continue}break}}f=d>90?d+-180:d;f=f<-90?f+180:f;k=f>45;d=k?c:b;c=k?b:c;b=k?f+-90:f;k=b<-45;f=k?d:c;b=k?b+90:b;if(b<=0){while(1){b=b+360;if(b<=0){continue}break}}L[467823]=f;L[467822]=k?c:d;L[467819]=o;L[467818]=p;L[467817]=q;L[467816]=v;L[467815]=l;L[467824]=b;y=e}k=z;if(k){continue}break}}f=L[467827];c=L[467816]*f;b=ib(c);L[467844]=b;L[467858]=b;h=f*L[467824];e=eb(h);d=eb(c);y=e*d;L[467850]=y;c=ib(h);h=d*c;L[467847]=h;w=f*L[467815];f=ib(w);x=d*f;L[467843]=x;B=d;d=eb(w);w=B*d;L[467842]=w;L[467860]=y;L[467859]=h;L[467855]=x;L[467852]=w;h=b*-e;y=c*d;L[467849]=f*h-y;w=c*f;L[467848]=w+d*h;h=e*d;x=b*-c;L[467846]=h+f*x;B=d*x;x=e*f;L[467845]=B-x;f=b*-f;L[467857]=e*f-y;L[467856]=f*c+h;b=b*-d;L[467854]=e*b+w;L[467853]=b*c-x;mf(L[467822]*-.5,L[467823]*-.5);L[467787]=L[467840];L[467788]=L[467841];mf(L[467822]*.5,L[467823]*-.5);L[467794]=L[467840];L[467795]=L[467841];mf(L[467822]*.5,L[467823]*.5);L[467801]=L[467840];L[467802]=L[467841];mf(L[467822]*-.5,L[467823]*.5);L[467808]=L[467840];L[467809]=L[467841];if(G[935573]>=2){L[g+112>>3]=L[467815];L[g+120>>3]=L[467816];gb(71674,g+112|0);L[g+96>>3]=L[467822];gb(71917,g+96|0);L[g+80>>3]=L[467823];gb(71843,g+80|0);L[g+64>>3]=L[467824];gb(71823,g- -64|0);L[g+48>>3]=L[467787];L[g+56>>3]=L[467788];gb(71782,g+48|0);L[g+32>>3]=L[467794];L[g+40>>3]=L[467795];gb(71755,g+32|0);L[g+16>>3]=L[467801];L[g+24>>3]=L[467802];gb(71728,g+16|0);L[g>>3]=L[467808];L[g+8>>3]=L[467809];gb(71701,g);$a(G[29763])}Fa=g+544|0}function gt(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;f=Fa-1088|0;Fa=f;G[f+1072>>2]=G[30076];e=G[30075];G[f+1064>>2]=G[30074];G[f+1068>>2]=e;e=G[30073];G[f+1056>>2]=G[30072];G[f+1060>>2]=e;G[f+1052>>2]=0;G[f+8>>2]=0;a:{if(b){Ua(55927);Ua(a);a=112;break a}b:{e=jb(a,91);if(!e){Ua(55992);break b}E[f+16|0]=0;l=qb(f+16|0,a,e-a|0);q=1;n=32;j=4;while(1){b=e;e=b+1|0;i=H[b+1|0];if((i|0)==32){continue}break}c:{d:{e:{f:{switch(i-66|0){case 4:case 16:case 36:case 48:n=-32;t=1;break d;case 2:case 34:j=8;n=-64;u=1;q=0;break c;default:Ua(56104);break b;case 0:case 32:j=1;n=8;p=0;break e;case 7:case 39:j=2;n=16;v=1;p=0;break e;case 8:case 40:break c;case 19:case 51:break f}}j=2;n=20;p=1}}q=0}a=b+2|0;G[f+12>>2]=a;e=1;r=1;g:{h:{i:{j:{i=H[b+2|0];switch(i-66|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:break g;case 10:break h;case 0:break i;default:break j}}switch(i-98|0){case 10:break h;case 0:break i;default:break g}}a=b+3|0;G[f+12>>2]=a;r=0;w=1;break g}a=b+3|0;G[f+12>>2]=a}m=nc(a,f+8|0,10);G[f+1056>>2]=m;b=G[f+8>>2];k:{if(!b){g=1;h=1;k=1;b=0;i=1;break k}if(H[b|0]!=44){g=1;h=1;k=1;i=1;break k}k=nc(b+1|0,f+12|0,10);G[f+1060>>2]=k;i=2;l:{a=G[f+12>>2];m:{if(!a){a=0;break m}if(H[a|0]==44){break l}}g=1;h=1;break k}h=nc(a+1|0,f+8|0,10);G[f+1064>>2]=h;i=3;b=G[f+8>>2];if(!b){b=0;g=1;break k}if(H[b|0]!=44){g=1;break k}g=nc(b+1|0,f+12|0,10);G[f+1068>>2]=g;a=G[f+12>>2];if(a){b=H[a|0]==44?5:4}else{b=4}i=b;e=nc(a+1|0,f+8|0,10);G[f+1072>>2]=e;b=G[f+8>>2]}a=a>>>0>b>>>0?a:b;G[f+12>>2]=a;if(H[a|0]==58){s=nc(a+1|0,0,10)}a=j;j=M(M(M(M(k,m),h),g),e);m=M(a,j);g=m+5759|0;k=(m+2879>>>0)%2880|0;h=g-k|0;G[f+1052>>2]=h;a=ce(l,0,f+1084|0);if(a){Ua(56205);Ua(l);break a}G[c>>2]=-1;a=0;n:{o:{p:{while(1){b=M(a,48)+757232|0;if(!G[b>>2]){e=a;break p}e=a+1|0;b=M(e,48)+757232|0;if(!G[b>>2]){break p}e=a+2|0;b=M(e,48)+757232|0;if(!G[b>>2]){break p}e=a+3|0;b=M(e,48)+757232|0;if(!G[b>>2]){break p}e=a+4|0;b=M(e,48)+757232|0;if(!G[b>>2]){break p}a=a+5|0;if((a|0)!=1e4){continue}break}a=103;break o}G[c>>2]=e;o=b;a=M(e,48);b=a+757236|0;G[o>>2]=b;e=a+757244|0;G[a+757240>>2]=e;if((g|0)==(k|0)){break n}o=b;b=ab(h);G[o>>2]=b;if(b){break n}Ua(57797);a=104}G[f+1076>>2]=a;Ua(56157);Hb(G[f+1084>>2]);a=G[f+1076>>2];break a}G[e>>2]=h;b=a+757256|0;G[b>>2]=0;G[b+4>>2]=0;G[a+757248>>2]=2880;b=a+757264|0;G[b>>2]=0;G[b+4>>2]=0;G[a+757252>>2]=17;G[f+1076>>2]=0;e=f+1080|0;b=G[M(G[c>>2],48)+757232>>2];o=f+1052|0;g=Fa-48|0;Fa=g;k=f+1076|0;q:{if(G[k>>2]>0){break q}G[e>>2]=0;if(G[47541]){a=ji();G[k>>2]=a;if((a|0)>0){break q}}a=H[141383]|H[141384]<<8|(H[141385]<<16|H[141386]<<24);E[g+23|0]=a;E[g+24|0]=a>>>8;E[g+25|0]=a>>>16;E[g+26|0]=a>>>24;a=G[35345];G[g+16>>2]=G[35344];G[g+20>>2]=a;h=G[310142];r:{s:{while(1){if((h|0)<=0){break s}h=h-1|0;if(Xa(M(h,84)+1240576|0,g+16|0)){continue}break}G[k>>2]=0;a=Hn(b,o,g+12|0);G[k>>2]=a;if((a|0)>0){Ua(57747);break q}l=lb(1,8);G[e>>2]=l;if(!l){Ja[G[(M(h,84)+1240576|0)+56>>2]](G[g+12>>2])|0;Ua(57631);break r}b=lb(1,1736);G[l+4>>2]=b;if(!b){Ja[G[(M(h,84)+1240576|0)+56>>2]](G[g+12>>2])|0;Ua(57631);Wa(G[e>>2]);G[e>>2]=0;break r}a=ab(32);G[b+12>>2]=a;if(!a){Ja[G[(M(h,84)+1240576|0)+56>>2]](G[g+12>>2])|0;Ua(57582);Wa(G[G[e>>2]+4>>2]);Wa(G[e>>2]);G[e>>2]=0;break r}d=lb(1001,8);G[b+96>>2]=d;if(!d){Ja[G[(M(h,84)+1240576|0)+56>>2]](G[g+12>>2])|0;Ua(57471);Wa(G[G[G[e>>2]+4>>2]+12>>2]);Wa(G[G[e>>2]+4>>2]);Wa(G[e>>2]);G[e>>2]=0;break r}d=lb(40,2880);G[b+1252>>2]=d;t:{if(d){cb(b+1256|0,255,160);d=b+1728|0;G[d>>2]=38;G[d+4>>2]=39;d=b+1720|0;G[d>>2]=36;G[d+4>>2]=37;d=b+1712|0;G[d>>2]=34;G[d+4>>2]=35;d=b+1704|0;G[d>>2]=32;G[d+4>>2]=33;d=b+1696|0;G[d>>2]=30;G[d+4>>2]=31;d=b+1688|0;G[d>>2]=28;G[d+4>>2]=29;d=b+1680|0;G[d>>2]=26;G[d+4>>2]=27;d=b+1672|0;G[d>>2]=24;G[d+4>>2]=25;d=b+1664|0;G[d>>2]=22;G[d+4>>2]=23;d=b+1656|0;G[d>>2]=20;G[d+4>>2]=21;d=b+1648|0;G[d>>2]=18;G[d+4>>2]=19;d=b+1640|0;G[d>>2]=16;G[d+4>>2]=17;d=b+1632|0;G[d>>2]=14;G[d+4>>2]=15;d=b+1624|0;G[d>>2]=12;G[d+4>>2]=13;d=b+1616|0;G[d>>2]=10;G[d+4>>2]=11;d=b+1608|0;G[d>>2]=8;G[d+4>>2]=9;d=b+1600|0;G[d>>2]=6;G[d+4>>2]=7;d=b+1592|0;G[d>>2]=4;G[d+4>>2]=5;d=b+1584|0;G[d>>2]=2;G[d+4>>2]=3;G[b+1576>>2]=0;G[b+1580>>2]=1;G[b+92>>2]=1e3;d=G[g+12>>2];G[b+4>>2]=h;G[b>>2]=d;E[a|0]=109;E[a+1|0]=101;E[a+2|0]=109;E[a+3|0]=102;E[a+4|0]=105;E[a+5|0]=108;E[a+6|0]=101;E[a+7|0]=0;a=G[o>>2];G[b+128>>2]=-1;G[b+132>>2]=-1;G[b+84>>2]=1;G[b+40>>2]=a;G[b+44>>2]=0;G[b+32>>2]=a;G[b+36>>2]=0;G[b+72>>2]=-1;h=0;G[b+24>>2]=0;G[b+16>>2]=555;G[b+8>>2]=1;Hc(l,0,1,k);if(G[k>>2]>0){break q}e=G[G[e>>2]+4>>2];break t}Ja[G[(M(h,84)+1240576|0)+56>>2]](G[g+12>>2])|0;Ua(57527);Wa(G[G[G[e>>2]+4>>2]+96>>2]);Wa(G[G[G[e>>2]+4>>2]+12>>2]);Wa(G[G[e>>2]+4>>2]);Wa(G[e>>2]);G[e>>2]=0;break r}while(1){u:{b=h<<2;a=b+1243184|0;if(!G[a>>2]){break u}b=b+1243184|0;a=b+4|0;if(!G[a>>2]){break u}a=b+8|0;if(!G[a>>2]){break u}a=b+12|0;if(!G[a>>2]){break u}a=b+16|0;if(!G[a>>2]){break u}h=h+5|0;if((h|0)!=1e4){continue}break q}break}G[a>>2]=e;break q}G[k>>2]=124;Ua(57686);break q}G[k>>2]=113}Fa=g+48|0;pd(G[f+1080>>2],n,i,f+1056|0,k);Qb(G[f+1080>>2],k);if(G[f+1076>>2]>0){Ua(56050);Hb(G[f+1084>>2]);a=M(G[c>>2],48)+757232|0;Wa(G[G[a>>2]>>2]);G[a>>2]=0;G[a+4>>2]=0;a=G[f+1076>>2];break a}if((s|0)>0){He(G[f+1084>>2],s,0)}e=G[G[M(G[c>>2],48)+757232>>2]>>2]+2880|0;if((zc(e,1,m,G[f+1084>>2])|0)!=(m|0)){G[f+1076>>2]=108}Hb(G[f+1084>>2]);if(G[f+1076>>2]){a=M(G[c>>2],48)+757232|0;Wa(G[G[a>>2]>>2]);G[a>>2]=0;G[a+4>>2]=0;Ua(55867);a=G[f+1076>>2];break a}v:{if(!p){break v}if(!r){if((j|0)<=0){break v}a=e;if(j-1>>>0>=3){i=j&-4;b=0;while(1){F[a>>1]=I[a>>1]^128;F[a+2>>1]=I[a+2>>1]^128;F[a+4>>1]=I[a+4>>1]^128;F[a+6>>1]=I[a+6>>1]^128;a=a+8|0;b=b+4|0;if((i|0)!=(b|0)){continue}break}}i=j&3;if(!i){break v}b=0;while(1){F[a>>1]=I[a>>1]^128;a=a+2|0;b=b+1|0;if((i|0)!=(b|0)){continue}break}break v}if((j|0)<=0){break v}a=e;if(j-1>>>0>=3){i=j&-4;b=0;while(1){F[a>>1]=I[a>>1]^32768;F[a+2>>1]=I[a+2>>1]^32768;F[a+4>>1]=I[a+4>>1]^32768;F[a+6>>1]=I[a+6>>1]^32768;a=a+8|0;b=b+4|0;if((i|0)!=(b|0)){continue}break}}i=j&3;if(!i){break v}b=0;while(1){F[a>>1]=I[a>>1]^32768;a=a+2|0;b=b+1|0;if((i|0)!=(b|0)){continue}break}}w:{if(w){break w}if(p|v){Af(e,j);break w}if(q|t){ke(e,j);break w}if(!u){break w}Ge(e,j)}a=M(G[c>>2],48);b=a+757256|0;G[b>>2]=0;G[b+4>>2]=0;a=a+757264|0;G[a>>2]=G[f+1052>>2];G[a+4>>2]=0;a=0;break a}Ua(a);a=125}Fa=f+1088|0;return a|0}function Yq(a,b,c,d,e,f,g,h,i){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=+g;h=h|0;i=i|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=N(0),q=0,r=0,s=0,t=0,u=0,v=0,w=N(0),x=0,y=0,z=0,A=0,B=0,C=0,D=0,I=0,J=N(0),P=0,Q=N(0),R=0,S=0,T=0,U=N(0),W=0,X=N(0),Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=N(0),ka=N(0);n=Fa-128|0;Fa=n;J=N(g);G[n+116>>2]=0;if(G[968812]){G[n+108>>2]=i;G[n+104>>2]=h;L[n+96>>3]=J;G[n+88>>2]=d;G[n+84>>2]=c;G[n+80>>2]=b;gb(74134,n+80|0)}s=Fa-32|0;Fa=s;m=b-1|0;k=(b|0)<(i|0)?b:i;r=(k|0)>1?k:1;k=(m+r|0)/(r|0)|0;A=(k|0)>2?k:2;P=(m+A|0)/(A|0)|0;k=(P|0)>1?P:1;m=1;if(G[968812]){G[s+24>>2]=k;G[s+20>>2]=A;G[s+16>>2]=r;kb(74182,s+16|0);m=!G[968812]}i=(h|0)/(i|0)|0;i=(i|0)>1?i:1;h=((h+k|0)-1|0)/(k|0)|0;h=(c|0)>(h|0)?h:c;r=(h|0)<(i|0)?i:h;h=(c|0)/(r|0)|0;y=(h|0)>2?h:2;h=((y+c|0)-1|0)/(y|0)|0;if(!m){G[s+12>>2]=h;G[s+8>>2]=y;G[s+4>>2]=r;G[s>>2]=i;kb(74078,s)}Z=M(h,k);m=ab(Z<<2);G[n+116>>2]=m;R=b<<2;h=ab(R);u=y+1>>>1|0;a:{if((u|0)>=(c|0)){break a}aa=k&2147483646;ba=k&1;z=b&-4;r=b&3;v=b-1|0;ca=b<<1;da=b<<3;ea=M(b,y)<<2;fa=M(u-1|0,b)<<2;ga=d-8|0;ha=(d|0)==-64;ia=(d|0)==-32;while(1){b:{c:{d:{switch(ga|0){default:if(ha){break c}if(!ia|(b|0)<=0){break b}bb(h,(M(S,ea)+fa|0)+a|0,R);break b;case 0:if((b|0)<=0){break b}l=M(u-1|0,b)+a|0;i=0;d=0;k=0;if(v>>>0>=3){while(1){K[h+(d<<2)>>2]=E[d+l|0];o=d|1;K[h+(o<<2)>>2]=E[l+o|0];o=d|2;K[h+(o<<2)>>2]=E[l+o|0];o=d|3;K[h+(o<<2)>>2]=E[l+o|0];d=d+4|0;k=k+4|0;if((z|0)!=(k|0)){continue}break}}if(!r){break b}while(1){K[h+(d<<2)>>2]=E[d+l|0];d=d+1|0;i=i+1|0;if((r|0)!=(i|0)){continue}break};break b;case 8:if((b|0)<=0){break b}l=M(u+2147483647|0,ca)+a|0;i=0;d=0;k=0;if(v>>>0>=3){while(1){K[h+(d<<2)>>2]=F[l+(d<<1)>>1];o=d|1;K[h+(o<<2)>>2]=F[l+(o<<1)>>1];o=d|2;K[h+(o<<2)>>2]=F[l+(o<<1)>>1];o=d|3;K[h+(o<<2)>>2]=F[l+(o<<1)>>1];d=d+4|0;k=k+4|0;if((z|0)!=(k|0)){continue}break}}if(!r){break b}while(1){K[h+(d<<2)>>2]=F[l+(d<<1)>>1];d=d+1|0;i=i+1|0;if((r|0)!=(i|0)){continue}break};break b;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:break b;case 24:break d}}if((b|0)<=0){break b}i=M(R,u+1073741823|0)+a|0;k=0;d=0;o=0;if(v>>>0>=3){while(1){l=d<<2;K[l+h>>2]=G[i+l>>2];T=l|4;K[T+h>>2]=G[i+T>>2];T=l|8;K[T+h>>2]=G[i+T>>2];l=l|12;K[l+h>>2]=G[i+l>>2];d=d+4|0;o=o+4|0;if((z|0)!=(o|0)){continue}break}}if(!r){break b}while(1){l=d<<2;K[l+h>>2]=G[i+l>>2];d=d+1|0;k=k+1|0;if((r|0)!=(k|0)){continue}break}break b}if((b|0)<=0){break b}l=M(u+536870911|0,da)+a|0;i=0;d=0;k=0;if(v>>>0>=3){while(1){K[h+(d<<2)>>2]=L[l+(d<<3)>>3];o=d|1;K[h+(o<<2)>>2]=L[l+(o<<3)>>3];o=d|2;K[h+(o<<2)>>2]=L[l+(o<<3)>>3];o=d|3;K[h+(o<<2)>>2]=L[l+(o<<3)>>3];d=d+4|0;k=k+4|0;if((z|0)!=(k|0)){continue}break}}if(!r){break b}while(1){K[h+(d<<2)>>2]=L[l+(d<<3)>>3];d=d+1|0;i=i+1|0;if((r|0)!=(i|0)){continue}break}}d=0;k=0;i=0;if((P|0)>=2){while(1){l=h+(k<<2)|0;w=K[l>>2];if((G[l>>2]&2139095040)!=2139095040){K[(d<<2)+m>>2]=w;d=d+1|0}k=k+A|0;l=h+(k<<2)|0;w=K[l>>2];if((G[l>>2]&2139095040)!=2139095040){K[(d<<2)+m>>2]=w;d=d+1|0}k=k+A|0;i=i+2|0;if((aa|0)!=(i|0)){continue}break}}e:{if(!ba){break e}i=h+(k<<2)|0;w=K[i>>2];if((G[i>>2]&2139095040)==2139095040){break e}K[(d<<2)+m>>2]=w;d=d+1|0}j=d+j|0;if((Z|0)<(j|0)){break a}S=S+1|0;m=(d<<2)+m|0;u=u+y|0;if((u|0)<(c|0)){continue}break}}Wa(h);Fa=s+32|0;c=G[n+116>>2];b=j;oe(c,b,4,143);d=1;h=(c+(b<<2)|0)-4|0;a=c;U=K[c>>2];Q=U;f:{if((b|0)<=0){break f}d=b+1>>>1|0;_=d-1|0;a=c+(_<<2)|0;Q=K[a>>2];if((b&-2147483647)==1|b>>>0<=d>>>0){break f}Q=N(N(Q+K[c+(d<<2)>>2])*N(.5))}w=K[h>>2];g=+(b|0);x=g*.5;g:{if(O(x)<2147483648){h=~~x;break g}h=-2147483648}P=(h|0)>5?h:5;i=c;g=g*.01+.5;h:{if(O(g)<2147483648){c=~~g;break h}c=-2147483648}A=(c|0)>1?c:1;j=0;m=0;g=0;x=0;y=0;c=0;i:{if((b|0)<=0){break i}if((b|0)==1){K[n+124>>2]=K[i+4>>2];G[n+120>>2]=0;c=1;break i}u=b-1|0;D=2/+(u|0);c=b<<2;s=ab(c);k=ab(c);r=lb(b,1);if(u>>>0>=3){h=b&-4;c=0;while(1){K[k+(j<<2)>>2]=+(j|0)*D+-1;l=j|1;K[k+(l<<2)>>2]=+(l|0)*D+-1;l=j|2;K[k+(l<<2)>>2]=+(l|0)*D+-1;l=j|3;K[k+(l<<2)>>2]=+(l|0)*D+-1;j=j+4|0;c=c+4|0;if((h|0)!=(c|0)){continue}break}}c=b&3;if(c){while(1){K[k+(j<<2)>>2]=+(j|0)*D+-1;j=j+1|0;m=m+1|0;if((c|0)!=(m|0)){continue}break}}m=b&1;j:{if(!u){j=0;break j}l=b&-2;j=0;c=0;while(1){h=j<<2;z=h|4;B=+K[z+i>>2];q=+K[k+z>>2];C=+K[h+i>>2];t=+K[h+k>>2];x=B*q+(C*t+x);I=I+C+B;g=q*q+(t*t+g);j=j+2|0;c=c+2|0;if((l|0)!=(c|0)){continue}break}}if(m){c=j<<2;t=+K[c+i>>2];q=+K[c+k>>2];x=t*q+x;I=I+t;g=q*q+g}q=+(b|0);t=q*.5;k:{if(O(t)<2147483648){c=~~t;break k}c=-2147483648}C=I/q;R=(c|0)>5?c:5;l=b&-2;z=b&1;h=b;$=x/g;B=$;while(1){l:{m=0;c=0;if(u){while(1){j=m<<2;K[j+s>>2]=+K[i+j>>2]-(+K[j+k>>2]*B+C);j=j|4;K[j+s>>2]=+K[i+j>>2]-(+K[j+k>>2]*B+C);m=m+2|0;c=c+2|0;if((l|0)!=(c|0)){continue}break}}if(z){c=m<<2;K[c+s>>2]=+K[c+i>>2]-(+K[c+k>>2]*B+C)}t=0;j=0;q=0;c=0;m=0;if(u){while(1){if(!H[j+r|0]){p=K[s+(j<<2)>>2];q=q+ +p;t=t+ +N(p*p);c=c+1|0}v=j|1;if(!H[v+r|0]){p=K[s+(v<<2)>>2];q=q+ +p;t=t+ +N(p*p);c=c+1|0}j=j+2|0;m=m+2|0;if((l|0)!=(m|0)){continue}break}}if(!(H[j+r|0]|!z)){p=K[s+(j<<2)>>2];q=q+ +p;t=t+ +N(p*p);c=c+1|0}W=-999;m:{if(c>>>0<2){break m}j=c-1|0;q=t/+(j|0)-q*q/+(M(c,j)|0);W=0;if(q<0){break m}W=V(q)}p=N(W*2.5);ja=N(-p);m=0;c=b;while(1){n:{if(H[m+r|0]!=1){X=K[s+(m<<2)>>2];if(!(X0?j:0;v=m+A|0;S=(b|0)>(v|0)?v:b;if((j|0)>=(S|0)){break n}while(1){v=j+r|0;o:{if(H[v|0]==1){break o}if(j>>>0<=m>>>0){o=j<<2;X=K[o+i>>2];ka=K[k+o>>2];E[v|0]=1;t=+X;q=+ka;x=x-t*q;c=c-1|0;I=I-t;Y=Y-q;g=g-q*q;break o}E[v|0]=2}j=j+1|0;if((S|0)>(j|0)){continue}break}break n}c=c-1|0}m=m+1|0;if((b|0)!=(m|0)){continue}break}if((c|0)>0){q=-Y/g;C=(q*x+I)/(q*Y+ +(c|0));B=(x-C*Y)/g}if((c|0)<(R|0)|(c|0)>=(h|0)){break l}h=c;y=y+1|0;if((y|0)<5){continue}}break}K[n+124>>2]=C-B;p=N(D*B);K[n+120>>2]=+(p>=N(0)?p:N(-p))<.001?N(D*$):p;Wa(s);Wa(k);Wa(r)}p:{if((c|0)<(P|0)){K[e>>2]=U;p=w;break p}p=K[n+120>>2];if(J>N(0)){p=N(p/J);K[n+120>>2]=p}J=N(Q-N(N(_|0)*p));K[e>>2]=Jw?w:p}K[f>>2]=p;if(G[968812]){p=K[a>>2];L[n+72>>3]=Q;L[n- -64>>3]=p;L[n+56>>3]=w;L[n+48>>3]=U;gb(70958,n+48|0);G[n+40>>2]=c;G[n+36>>2]=A;G[n+32>>2]=P;kb(74033,n+32|0);w=K[f>>2];L[n+16>>3]=K[e>>2];L[n+24>>3]=w;G[n+8>>2]=d;L[n>>3]=K[n+120>>2];gb(71049,n)}Wa(i);Fa=n+128|0}function rn(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;e=G[309722];f=G[a+12>>2];n=e+M(f,344)|0;a:{if(G[n>>2]==-1e3){b:{c:{switch(G[a>>2]-258|0){case 2:case 30:d:{e:{b=M(f,344)+e|0;switch(G[b+52>>2]-258|0){case 1:break e;case 0:break d;default:break b}}L[a+88>>3]=G[b+88>>2];break b}L[a+88>>3]=H[b+88|0]?1:0;break b;case 1:case 29:f:{g:{b=M(f,344)+e|0;switch(G[b+52>>2]-258|0){case 0:break f;case 2:break g;default:break b}}k=L[b+88>>3];if(O(k)<2147483648){G[a+88>>2]=~~k;break b}G[a+88>>2]=-2147483648;break b}G[a+88>>2]=H[b+88|0]!=0;break b;case 0:h:{i:{b=M(f,344)+e|0;switch(G[b+52>>2]-259|0){case 0:break h;case 1:break i;default:break b}}E[a+88|0]=L[b+88>>3]!=0;break b}E[a+88|0]=G[b+88>>2]!=0;break b;case 31:j:{k:{b=M(f,344)+e|0;switch(G[b+52>>2]-259|0){case 0:break j;case 1:break k;default:break b}}L[a+88>>3]=-L[b+88>>3];break b}G[a+88>>2]=0-G[b+88>>2];break b;case 28:break c;default:break b}}l:{m:{b=M(f,344)+e|0;switch(G[b+52>>2]-258|0){case 4:break l;case 0:break m;default:break b}}E[a+88|0]=!H[b+88|0];break b}c=a+88|0;g=b+88|0;h=Va(g);n:{if(!h){break n}d=h-1|0;b=h&3;if(b){while(1){i=H[g|0];E[c|0]=(i|0)==49?48:(i|0)==48?49:i;c=c+1|0;g=g+1|0;h=h-1|0;l=l+1|0;if((b|0)!=(l|0)){continue}break}}if(d>>>0<3){break n}while(1){b=H[g|0];E[c|0]=(b|0)==49?48:(b|0)==48?49:b;b=H[g+1|0];E[c+1|0]=(b|0)==49?48:(b|0)==48?49:b;b=H[g+2|0];E[c+2|0]=(b|0)==49?48:(b|0)==48?49:b;b=H[g+3|0];E[c+3|0]=(b|0)==49?48:(b|0)==48?49:b;c=c+4|0;g=g+4|0;h=h-4|0;if(h){continue}break}}E[c|0]=0}G[a>>2]=-1e3;break a}Nd(a);if(G[309737]){break a}b=G[a+52>>2];o:{if((b|0)==262){break o}c=G[309727];c=(b|0)!=261?M(G[a+56>>2],c):c;if(!c){break o}d=c-1|0;i=M(f,344)+e|0;b=c&3;if(b){while(1){c=c-1|0;E[c+G[a+84>>2]|0]=H[G[i+84>>2]+c|0];h=h+1|0;if((b|0)!=(h|0)){continue}break}}if(d>>>0<3){break o}while(1){b=c-1|0;E[b+G[a+84>>2]|0]=H[b+G[i+84>>2]|0];b=c-2|0;E[b+G[a+84>>2]|0]=H[b+G[i+84>>2]|0];b=c-3|0;E[b+G[a+84>>2]|0]=H[b+G[i+84>>2]|0];c=c-4|0;E[c+G[a+84>>2]|0]=H[G[i+84>>2]+c|0];if(c){continue}break}}j=G[309727];b=M(j,G[a+56>>2]);p:{switch(G[a>>2]-258|0){case 0:q:{switch(G[(M(f,344)+e|0)+52>>2]-259|0){case 0:if(!b){break a}d=M(f,344)+e|0;c=b;if(b&1){c=b-1|0;E[c+G[a+88>>2]|0]=G[G[d+88>>2]+(c<<2)>>2]!=0}if((b|0)==1){break a}while(1){b=c-1|0;E[b+G[a+88>>2]|0]=G[G[d+88>>2]+(b<<2)>>2]!=0;c=c-2|0;E[c+G[a+88>>2]|0]=G[G[d+88>>2]+(c<<2)>>2]!=0;if(c){continue}break};break a;case 1:break q;default:break a}}if(!b){break a}d=M(f,344)+e|0;c=b;if(b&1){c=b-1|0;E[c+G[a+88>>2]|0]=L[G[d+88>>2]+(c<<3)>>3]!=0}if((b|0)==1){break a}while(1){b=c-1|0;E[b+G[a+88>>2]|0]=L[G[d+88>>2]+(b<<3)>>3]!=0;c=c-2|0;E[c+G[a+88>>2]|0]=L[G[d+88>>2]+(c<<3)>>3]!=0;if(c){continue}break};break a;case 2:case 30:r:{switch(G[(M(f,344)+e|0)+52>>2]-258|0){case 0:if(!b){break a}d=M(f,344)+e|0;c=b;if(b&1){c=b-1|0;L[G[a+88>>2]+(c<<3)>>3]=H[G[d+88>>2]+c|0]?1:0}if((b|0)==1){break a}while(1){b=c-1|0;L[G[a+88>>2]+(b<<3)>>3]=H[b+G[d+88>>2]|0]?1:0;c=c-2|0;L[G[a+88>>2]+(c<<3)>>3]=H[G[d+88>>2]+c|0]?1:0;if(c){continue}break};break a;case 1:break r;default:break a}}if(!b){break a}d=M(f,344)+e|0;c=b;if(b&1){c=b-1|0;L[G[a+88>>2]+(c<<3)>>3]=G[G[d+88>>2]+(c<<2)>>2]}if((b|0)==1){break a}while(1){b=c-1|0;L[G[a+88>>2]+(b<<3)>>3]=G[G[d+88>>2]+(b<<2)>>2];c=c-2|0;L[G[a+88>>2]+(c<<3)>>3]=G[G[d+88>>2]+(c<<2)>>2];if(c){continue}break};break a;case 1:case 29:s:{switch(G[(M(f,344)+e|0)+52>>2]-258|0){case 0:if(!b){break a}d=M(f,344)+e|0;c=b;if(b&1){c=b-1|0;G[G[a+88>>2]+(c<<2)>>2]=H[G[d+88>>2]+c|0]!=0}if((b|0)==1){break a}while(1){b=c-1|0;G[G[a+88>>2]+(b<<2)>>2]=H[b+G[d+88>>2]|0]!=0;c=c-2|0;G[G[a+88>>2]+(c<<2)>>2]=H[G[d+88>>2]+c|0]!=0;if(c){continue}break};break a;case 2:break s;default:break a}}if(!b){break a}m=M(f,344)+e|0;c=b;if(b&1){c=b-1|0;j=G[a+88>>2]+(c<<2)|0;k=L[G[m+88>>2]+(c<<3)>>3];t:{if(O(k)<2147483648){l=~~k;break t}l=-2147483648}G[j>>2]=l}if((b|0)==1){break a}while(1){d=c-1|0;b=G[a+88>>2]+(d<<2)|0;k=L[G[m+88>>2]+(d<<3)>>3];u:{if(O(k)<2147483648){j=~~k;break u}j=-2147483648}G[b>>2]=j;c=c-2|0;b=G[a+88>>2]+(c<<2)|0;k=L[G[m+88>>2]+(c<<3)>>3];v:{if(O(k)<2147483648){j=~~k;break v}j=-2147483648}G[b>>2]=j;if(c){continue}break};break a;case 31:w:{switch(G[(M(f,344)+e|0)+52>>2]-259|0){case 0:if(!b){break a}i=M(f,344)+e|0;c=b;if(b&1){c=b-1|0;d=c<<2;G[d+G[a+88>>2]>>2]=0-G[d+G[i+88>>2]>>2]}if((b|0)==1){break a}while(1){b=(c<<2)-4|0;G[b+G[a+88>>2]>>2]=0-G[b+G[i+88>>2]>>2];c=c-2|0;b=c<<2;G[b+G[a+88>>2]>>2]=0-G[b+G[i+88>>2]>>2];if(c){continue}break};break a;case 1:break w;default:break a}}if(!b){break a}i=M(f,344)+e|0;c=b;if(b&1){c=b-1|0;d=c<<3;L[d+G[a+88>>2]>>3]=-L[d+G[i+88>>2]>>3]}if((b|0)==1){break a}while(1){b=(c<<3)-8|0;L[b+G[a+88>>2]>>3]=-L[b+G[i+88>>2]>>3];c=c-2|0;b=c<<3;L[b+G[a+88>>2]>>3]=-L[b+G[i+88>>2]>>3];if(c){continue}break};break a;case 28:break p;default:break a}}x:{switch(G[(M(f,344)+e|0)+52>>2]-258|0){case 4:if(!j){break a}i=M(f,344)+e|0;while(1){j=j-1|0;b=j<<2;c=G[b+G[a+88>>2]>>2];g=G[b+G[i+88>>2]>>2];h=Va(g);y:{if(!h){break y}d=h-1|0;l=0;b=h&3;if(b){while(1){m=H[g|0];E[c|0]=(m|0)==49?48:(m|0)==48?49:m;c=c+1|0;g=g+1|0;h=h-1|0;l=l+1|0;if((b|0)!=(l|0)){continue}break}}if(d>>>0<3){break y}while(1){b=H[g|0];E[c|0]=(b|0)==49?48:(b|0)==48?49:b;b=H[g+1|0];E[c+1|0]=(b|0)==49?48:(b|0)==48?49:b;b=H[g+2|0];E[c+2|0]=(b|0)==49?48:(b|0)==48?49:b;b=H[g+3|0];E[c+3|0]=(b|0)==49?48:(b|0)==48?49:b;c=c+4|0;g=g+4|0;h=h-4|0;if(h){continue}break}}E[c|0]=0;if(j){continue}break};break a;case 0:break x;default:break a}}if(!b){break a}d=M(f,344)+e|0;c=b;if(b&1){c=b-1|0;E[c+G[a+88>>2]|0]=!H[G[d+88>>2]+c|0]}if((b|0)==1){break a}while(1){b=c-1|0;E[b+G[a+88>>2]|0]=!H[b+G[d+88>>2]|0];c=c-2|0;E[c+G[a+88>>2]|0]=!H[G[d+88>>2]+c|0];if(c){continue}break}}if(G[n>>2]>0){Wa(G[(M(f,344)+e|0)+88>>2])}}function wj(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;E[a|0]=90;E[a+1|0]=80;E[a+2|0]=78;E[a+3|0]=0;G[a+16>>2]=0;G[a+20>>2]=1079410688;G[a+8>>2]=0;G[a+12>>2]=0;G[a+4>>2]=G[a+4>>2]<0?-107:107;g=L[a+24>>3];if(g==0){G[a+24>>2]=442745336;G[a+28>>2]=1078765020;g=57.29577951308232}a:{b:{c:{if(L[a+104>>3]!=0){h=9;break c}if(L[a+96>>3]!=0){h=8;break c}if(L[a+88>>3]!=0){h=7;break c}if(L[a+80>>3]!=0){h=6;break c}if(L[a+72>>3]!=0){h=5;break c}if(L[a- -64>>3]!=0){h=4;break c}if(L[a+56>>3]!=0){h=3;break c}d:{if(L[a+48>>3]!=0){b=2;break d}if(L[a+40>>3]!=0){b=1;break d}if(L[a+32>>3]!=0){break d}G[a+16>>2]=0;G[a+20>>2]=1079410688;G[a+8>>2]=0;G[a+12>>2]=0;E[a|0]=65;E[a+1|0]=82;E[a+2|0]=67;E[a+3|0]=0;E[a+4|0]=106;E[a+5|0]=0;E[a+6|0]=0;E[a+7|0]=0;e:{if(g==0){G[a+24>>2]=442745336;G[a+28>>2]=1078765020;g=1;j=1;break e}g=g*3.141592653589793/180;j=1/g}G[a+1892>>2]=91;G[a+1888>>2]=92;L[a+112>>3]=g;L[a+120>>3]=j;break b}G[a+1892>>2]=113;G[a+1888>>2]=114;G[a+272>>2]=b;break b}G[a+1892>>2]=113;G[a+1888>>2]=114;G[a+272>>2]=h;l=L[a+40>>3];b=1;if(l<=0){break a}d=h&3;o=h-1|0;p=a+32|0;f:{g:{h:{while(1){i=+(q|0)*3.141592653589793/180;f=0;b=h;c=0;if(d){while(1){f=f*i+L[((b<<3)+a|0)+32>>3]*+(b|0);b=b-1|0;c=c+1|0;if((d|0)!=(c|0)){continue}break}}if(o>>>0>=3){while(1){c=b-1|0;f=((f*i+L[(b<<3)+p>>3]*+(b|0))*i+L[(c<<3)+p>>3]*+(c|0))*i;c=b-2|0;f=(f+L[(c<<3)+p>>3]*+(c|0))*i;c=b-3|0;f=f+L[(c<<3)+p>>3]*+(c|0);c=(b|0)>4;b=b-4|0;if(c){continue}break}}if(f<=0){e=3.141592653589793;if((q|0)==180){break f}e=j-l*(i-j)/(f-l);g=0;c=h&3;if(c){break h}b=h;break g}j=i;l=f;q=q+1|0;if((q|0)!=180){continue}break}e=3.141592653589793;break f}d=0;b=h;while(1){g=g*e+L[((b<<3)+a|0)+32>>3]*+(b|0);b=b-1|0;d=d+1|0;if((c|0)!=(d|0)){continue}break}}if(o>>>0>=3){d=a+32|0;while(1){c=b-1|0;m=((g*e+L[d+(b<<3)>>3]*+(b|0))*e+L[d+(c<<3)>>3]*+(c|0))*e;c=b-2|0;m=(m+L[d+(c<<3)>>3]*+(c|0))*e;c=b-3|0;g=m+L[d+(c<<3)>>3]*+(c|0);c=(b|0)>4;b=b-4|0;if(c){continue}break}}if(O(g)<1e-13){break f}b=g<0;k=b?j:e;m=b?l:g;l=b?e:i;j=b?g:f;e=k-m*(l-k)/(j-m);c=h&3;i:{if(!c){b=h;break i}d=0;b=h;while(1){n=n*e+L[((b<<3)+a|0)+32>>3]*+(b|0);b=b-1|0;d=d+1|0;if((c|0)!=(d|0)){continue}break}}if(o>>>0>=3){d=a+32|0;while(1){c=b-1|0;f=((n*e+L[d+(b<<3)>>3]*+(b|0))*e+L[d+(c<<3)>>3]*+(c|0))*e;c=b-2|0;f=(f+L[d+(c<<3)>>3]*+(c|0))*e;c=b-3|0;n=f+L[d+(c<<3)>>3]*+(c|0);c=(b|0)>4;b=b-4|0;if(c){continue}break}}if(O(n)<1e-13){break f}g=0;b=n<0;k=b?k:e;i=b?m:n;l=b?e:l;j=b?n:j;e=k-i*(l-k)/(j-i);c=h&3;j:{if(!c){b=h;break j}d=0;b=h;while(1){g=g*e+L[((b<<3)+a|0)+32>>3]*+(b|0);b=b-1|0;d=d+1|0;if((c|0)!=(d|0)){continue}break}}if(o>>>0>=3){d=a+32|0;while(1){c=b-1|0;f=((g*e+L[d+(b<<3)>>3]*+(b|0))*e+L[d+(c<<3)>>3]*+(c|0))*e;c=b-2|0;f=(f+L[d+(c<<3)>>3]*+(c|0))*e;c=b-3|0;g=f+L[d+(c<<3)>>3]*+(c|0);c=(b|0)>4;b=b-4|0;if(c){continue}break}}if(O(g)<1e-13){break f}f=0;b=g<0;k=b?k:e;i=b?i:g;l=b?e:l;j=b?g:j;e=k-i*(l-k)/(j-i);c=h&3;k:{if(!c){b=h;break k}d=0;b=h;while(1){f=f*e+L[((b<<3)+a|0)+32>>3]*+(b|0);b=b-1|0;d=d+1|0;if((c|0)!=(d|0)){continue}break}}if(o>>>0>=3){d=a+32|0;while(1){c=b-1|0;f=((f*e+L[d+(b<<3)>>3]*+(b|0))*e+L[d+(c<<3)>>3]*+(c|0))*e;c=b-2|0;f=(f+L[d+(c<<3)>>3]*+(c|0))*e;c=b-3|0;f=f+L[d+(c<<3)>>3]*+(c|0);c=(b|0)>4;b=b-4|0;if(c){continue}break}}if(O(f)<1e-13){break f}g=0;b=f<0;k=b?k:e;i=b?i:f;l=b?e:l;j=b?f:j;e=k-i*(l-k)/(j-i);c=h&3;l:{if(!c){b=h;break l}d=0;b=h;while(1){g=g*e+L[((b<<3)+a|0)+32>>3]*+(b|0);b=b-1|0;d=d+1|0;if((c|0)!=(d|0)){continue}break}}if(o>>>0>=3){d=a+32|0;while(1){c=b-1|0;f=((g*e+L[d+(b<<3)>>3]*+(b|0))*e+L[d+(c<<3)>>3]*+(c|0))*e;c=b-2|0;f=(f+L[d+(c<<3)>>3]*+(c|0))*e;c=b-3|0;g=f+L[d+(c<<3)>>3]*+(c|0);c=(b|0)>4;b=b-4|0;if(c){continue}break}}if(O(g)<1e-13){break f}f=0;b=g<0;k=b?k:e;i=b?i:g;l=b?e:l;j=b?g:j;e=k-i*(l-k)/(j-i);c=h&3;m:{if(!c){b=h;break m}d=0;b=h;while(1){f=f*e+L[((b<<3)+a|0)+32>>3]*+(b|0);b=b-1|0;d=d+1|0;if((c|0)!=(d|0)){continue}break}}if(o>>>0>=3){d=a+32|0;while(1){c=b-1|0;f=((f*e+L[d+(b<<3)>>3]*+(b|0))*e+L[d+(c<<3)>>3]*+(c|0))*e;c=b-2|0;f=(f+L[d+(c<<3)>>3]*+(c|0))*e;c=b-3|0;f=f+L[d+(c<<3)>>3]*+(c|0);c=(b|0)>4;b=b-4|0;if(c){continue}break}}if(O(f)<1e-13){break f}g=0;b=f<0;k=b?k:e;i=b?i:f;l=b?e:l;j=b?f:j;e=k-i*(l-k)/(j-i);c=h&3;n:{if(!c){b=h;break n}d=0;b=h;while(1){g=g*e+L[((b<<3)+a|0)+32>>3]*+(b|0);b=b-1|0;d=d+1|0;if((c|0)!=(d|0)){continue}break}}if(o>>>0>=3){d=a+32|0;while(1){c=b-1|0;f=((g*e+L[d+(b<<3)>>3]*+(b|0))*e+L[d+(c<<3)>>3]*+(c|0))*e;c=b-2|0;f=(f+L[d+(c<<3)>>3]*+(c|0))*e;c=b-3|0;g=f+L[d+(c<<3)>>3]*+(c|0);c=(b|0)>4;b=b-4|0;if(c){continue}break}}if(O(g)<1e-13){break f}f=0;b=g<0;k=b?k:e;i=b?i:g;l=b?e:l;j=b?g:j;e=k-i*(l-k)/(j-i);c=h&3;o:{if(!c){b=h;break o}d=0;b=h;while(1){f=f*e+L[((b<<3)+a|0)+32>>3]*+(b|0);b=b-1|0;d=d+1|0;if((c|0)!=(d|0)){continue}break}}if(o>>>0>=3){d=a+32|0;while(1){c=b-1|0;f=((f*e+L[d+(b<<3)>>3]*+(b|0))*e+L[d+(c<<3)>>3]*+(c|0))*e;c=b-2|0;f=(f+L[d+(c<<3)>>3]*+(c|0))*e;c=b-3|0;f=f+L[d+(c<<3)>>3]*+(c|0);c=(b|0)>4;b=b-4|0;if(c){continue}break}}if(O(f)<1e-13){break f}g=0;b=f<0;n=b?k:e;m=b?i:f;k=b?e:l;i=b?f:j;e=n-m*(k-n)/(i-m);c=h&3;p:{if(!c){b=h;break p}d=0;b=h;while(1){g=g*e+L[((b<<3)+a|0)+32>>3]*+(b|0);b=b-1|0;d=d+1|0;if((c|0)!=(d|0)){continue}break}}if(o>>>0>=3){d=a+32|0;while(1){c=b-1|0;j=((g*e+L[d+(b<<3)>>3]*+(b|0))*e+L[d+(c<<3)>>3]*+(c|0))*e;c=b-2|0;j=(j+L[d+(c<<3)>>3]*+(c|0))*e;c=b-3|0;g=j+L[d+(c<<3)>>3]*+(c|0);c=(b|0)>4;b=b-4|0;if(c){continue}break}}if(O(g)<1e-13){break f}b=g<0;l=b?n:e;j=b?m:g;e=l-j*((b?e:k)-l)/((b?g:i)-j)}g=0;c=h+1&3;if(c){b=0;while(1){g=g*e+L[((h<<3)+a|0)+32>>3];h=h-1|0;b=b+1|0;if((c|0)!=(b|0)){continue}break}}while(1){b=(h<<3)+a|0;g=(((g*e+L[b+32>>3])*e+L[b+24>>3])*e+L[b+16>>3])*e+L[b+8>>3];b=(h|0)>3;h=h-4|0;if(b){continue}break}L[a+112>>3]=e;L[a+120>>3]=g}b=0}return b}function $j(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,w=0,y=0,B=0,C=0,D=0,E=0;n=Fa-48|0;Fa=n;A(+a);o=v(1)|0;d=v(0)|0;a:{b:{c=o;g=c&2147483647;c:{if(g>>>0<=1074752122){if((c&1048575)==598523){break c}if(g>>>0<=1073928572){if((o|0)>0|(o|0)>=0){a=a+-1.5707963267341256;f=a+-6077100506506192e-26;L[b>>3]=f;L[b+8>>3]=a-f+-6077100506506192e-26;d=1;break a}a=a+1.5707963267341256;f=a+6077100506506192e-26;L[b>>3]=f;L[b+8>>3]=a-f+6077100506506192e-26;d=-1;break a}if((o|0)>0|(o|0)>=0){a=a+-3.1415926534682512;f=a+-1.2154201013012384e-10;L[b>>3]=f;L[b+8>>3]=a-f+-1.2154201013012384e-10;d=2;break a}a=a+3.1415926534682512;f=a+1.2154201013012384e-10;L[b>>3]=f;L[b+8>>3]=a-f+1.2154201013012384e-10;d=-2;break a}if(g>>>0<=1075594811){if(g>>>0<=1075183036){if((g|0)==1074977148){break c}if((o|0)>0|(o|0)>=0){a=a+-4.712388980202377;f=a+-1.8231301519518578e-10;L[b>>3]=f;L[b+8>>3]=a-f+-1.8231301519518578e-10;d=3;break a}a=a+4.712388980202377;f=a+1.8231301519518578e-10;L[b>>3]=f;L[b+8>>3]=a-f+1.8231301519518578e-10;d=-3;break a}if((g|0)==1075388923){break c}if((o|0)>0|(o|0)>=0){a=a+-6.2831853069365025;f=a+-2.430840202602477e-10;L[b>>3]=f;L[b+8>>3]=a-f+-2.430840202602477e-10;d=4;break a}a=a+6.2831853069365025;f=a+2.430840202602477e-10;L[b>>3]=f;L[b+8>>3]=a-f+2.430840202602477e-10;d=-4;break a}if(g>>>0>1094263290){break b}}j=a*.6366197723675814+6755399441055744+-6755399441055744;f=a+j*-1.5707963267341256;q=j*6077100506506192e-26;s=f-q;c=s<-.7853981633974483;if(O(j)<2147483648){d=~~j}else{d=-2147483648}d:{if(c){d=d-1|0;j=j+-1;q=j*6077100506506192e-26;f=a+j*-1.5707963267341256;break d}if(!(s>.7853981633974483)){break d}d=d+1|0;j=j+1;q=j*6077100506506192e-26;f=a+j*-1.5707963267341256}a=f-q;L[b>>3]=a;A(+a);e=v(1)|0;v(0)|0;c=g>>>20|0;e:{if((c-(e>>>20&2047)|0)<17){break e}s=f;a=j*6077100506303966e-26;f=f-a;q=j*20222662487959506e-37-(s-f-a);a=f-q;L[b>>3]=a;e=c;A(+a);c=v(1)|0;v(0)|0;if((e-(c>>>20&2047)|0)<50){break e}s=f;a=j*20222662487111665e-37;f=f-a;q=j*84784276603689e-45-(s-f-a);a=f-q;L[b>>3]=a}L[b+8>>3]=f-a-q;break a}if(g>>>0>=2146435072){a=a-a;L[b>>3]=a;L[b+8>>3]=a;d=0;break a}x(0,d|0);x(1,o&1048575|1096810496);a=+z();d=0;c=1;while(1){e=(n+16|0)+(d<<3)|0;if(O(a)<2147483648){d=~~a}else{d=-2147483648}f=+(d|0);L[e>>3]=f;a=(a-f)*16777216;d=1;e=c;c=0;if(e){continue}break}L[n+32>>3]=a;d=2;while(1){c=d;d=c-1|0;if(L[(n+16|0)+(c<<3)>>3]==0){continue}break}w=n+16|0;e=0;h=Fa-560|0;Fa=h;d=(g>>>20|0)-1046|0;g=(d-3|0)/24|0;u=(g|0)>0?g:0;g=M(u,-24)+d|0;m=G[30113];r=c+1|0;i=r-1|0;if((m+i|0)>=0){d=m+r|0;c=u-i|0;while(1){L[(h+320|0)+(e<<3)>>3]=(c|0)<0?0:+G[(c<<2)+120464>>2];c=c+1|0;e=e+1|0;if((d|0)!=(e|0)){continue}break}}p=g-24|0;d=0;e=(m|0)>0?m:0;l=(r|0)<=0;while(1){f:{if(l){a=0;break f}k=d+i|0;c=0;a=0;while(1){a=L[(c<<3)+w>>3]*L[(h+320|0)+(k-c<<3)>>3]+a;c=c+1|0;if((r|0)!=(c|0)){continue}break}}L[(d<<3)+h>>3]=a;c=(d|0)==(e|0);d=d+1|0;if(!c){continue}break}D=47-g|0;y=48-g|0;E=g-25|0;d=m;g:{while(1){a=L[(d<<3)+h>>3];c=0;e=d;k=(d|0)<=0;if(!k){while(1){t=(h+480|0)+(c<<2)|0;f=a*5.960464477539063e-8;h:{if(O(f)<2147483648){l=~~f;break h}l=-2147483648}f=+(l|0);a=f*-16777216+a;i:{if(O(a)<2147483648){l=~~a;break i}l=-2147483648}G[t>>2]=l;e=e-1|0;a=L[(e<<3)+h>>3]+f;c=c+1|0;if((d|0)!=(c|0)){continue}break}}a=Qf(a,p);a=a+S(a*.125)*-8;j:{if(O(a)<2147483648){c=~~a;break j}c=-2147483648}l=c;a=a-+(l|0);k:{l:{m:{B=(p|0)<=0;n:{if(!B){e=(d<<2)+h|0;i=G[e+476>>2];c=i>>y;t=e;e=i-(c<>2]=e;l=c+l|0;c=e>>D;break n}if(p){break m}c=G[((d<<2)+h|0)+476>>2]>>23}i=c;if((i|0)<=0){break k}break l}i=2;if(a>=.5){break l}i=0;break k}c=0;e=0;if(!k){while(1){C=(h+480|0)+(c<<2)|0;t=G[C>>2];k=16777215;o:{p:{if(e){break p}k=16777216;if(t){break p}e=0;break o}G[C>>2]=k-t;e=1}c=c+1|0;if((d|0)!=(c|0)){continue}break}}q:{if(B){break q}c=8388607;r:{switch(E|0){case 1:c=4194303;break;case 0:break r;default:break q}}k=(d<<2)+h|0;G[k+476>>2]=G[k+476>>2]&c}l=l+1|0;if((i|0)!=2){break k}a=1-a;i=2;if(!e){break k}a=a-Qf(1,p)}if(a==0){e=0;s:{c=d;if((m|0)>=(c|0)){break s}while(1){c=c-1|0;e=G[(h+480|0)+(c<<2)>>2]|e;if((c|0)>(m|0)){continue}break}if(!e){break s}g=p;while(1){g=g-24|0;d=d-1|0;if(!G[(h+480|0)+(d<<2)>>2]){continue}break}break g}c=1;while(1){e=c;c=c+1|0;if(!G[(h+480|0)+(m-e<<2)>>2]){continue}break}e=d+e|0;while(1){i=d+r|0;d=d+1|0;L[(h+320|0)+(i<<3)>>3]=G[(u+d<<2)+120464>>2];c=0;a=0;if((r|0)>0){while(1){a=L[(c<<3)+w>>3]*L[(h+320|0)+(i-c<<3)>>3]+a;c=c+1|0;if((r|0)!=(c|0)){continue}break}}L[(d<<3)+h>>3]=a;if((d|0)<(e|0)){continue}break}d=e;continue}break}a=Qf(a,24-g|0);t:{if(a>=16777216){e=(h+480|0)+(d<<2)|0;f=a*5.960464477539063e-8;u:{if(O(f)<2147483648){c=~~f;break u}c=-2147483648}a=+(c|0)*-16777216+a;v:{if(O(a)<2147483648){p=~~a;break v}p=-2147483648}G[e>>2]=p;d=d+1|0;break t}if(O(a)<2147483648){c=~~a}else{c=-2147483648}g=p}G[(h+480|0)+(d<<2)>>2]=c}a=Qf(1,g);w:{if((d|0)<0){break w}c=d;while(1){e=c;L[(c<<3)+h>>3]=a*+G[(h+480|0)+(c<<2)>>2];c=c-1|0;a=a*5.960464477539063e-8;if(e){continue}break}k=0;if((d|0)<0){break w}g=(m|0)>0?m:0;e=d;while(1){p=g>>>0>>0?g:k;m=d-e|0;c=0;a=0;while(1){a=L[(c<<3)+123232>>3]*L[(c+e<<3)+h>>3]+a;r=(c|0)!=(p|0);c=c+1|0;if(r){continue}break}L[(h+160|0)+(m<<3)>>3]=a;e=e-1|0;c=(d|0)!=(k|0);k=k+1|0;if(c){continue}break}}a=0;if((d|0)>=0){c=d;while(1){e=c;c=c-1|0;a=a+L[(h+160|0)+(e<<3)>>3];if(e){continue}break}}L[n>>3]=i?-a:a;a=L[h+160>>3]-a;c=1;if((d|0)>0){while(1){a=a+L[(h+160|0)+(c<<3)>>3];e=(c|0)!=(d|0);c=c+1|0;if(e){continue}break}}L[n+8>>3]=i?-a:a;Fa=h+560|0;d=l&7;a=L[n>>3];if((o|0)<0){L[b>>3]=-a;L[b+8>>3]=-L[n+8>>3];d=0-d|0;break a}L[b>>3]=a;L[b+8>>3]=L[n+8>>3]}Fa=n+48|0;return d}function Lt(a,b,c,d,e,f){a=a|0;b=+b;c=c|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,w=0,x=0,y=0,z=0;l=Fa-560|0;Fa=l;G[l+44>>2]=0;A(+b);g=v(1)|0;v(0)|0;a:{if((g|0)<0){s=1;w=3848;b=-b;A(+b);g=v(1)|0;v(0)|0;break a}if(e&2048){s=1;w=3851;break a}s=e&1;w=s?3854:3849;z=!s}b:{if((g&2146435072)==2146435072){d=s+3|0;nd(a,32,c,d,e&-65537);gd(a,w,s);f=f&32;gd(a,b!=b?f?16008:34610:f?18603:35135,3);nd(a,32,c,d,e^8192);i=(c|0)<(d|0)?d:c;break b}u=l+16|0;c:{d:{e:{b=Lp(b,l+44|0);b=b+b;if(b!=0){g=G[l+44>>2];G[l+44>>2]=g-1;r=f|32;if((r|0)!=97){break e}break c}r=f|32;if((r|0)==97){break c}k=G[l+44>>2];m=(d|0)<0?6:d;break d}k=g-29|0;G[l+44>>2]=k;b=b*268435456;m=(d|0)<0?6:d}p=(l+48|0)+((k|0)<0?0:288)|0;h=p;while(1){if(b<4294967296&b>=0){d=~~b>>>0}else{d=0}G[h>>2]=d;h=h+4|0;b=(b-+(d>>>0))*1e9;if(b!=0){continue}break}f:{if((k|0)<=0){d=k;g=h;j=p;break f}j=p;d=k;while(1){d=(d|0)<29?d:29;g=h-4|0;g:{if(j>>>0>g>>>0){break g}i=0;while(1){o=G[g>>2];n=d&31;x=i;if((d&63)>>>0>=32){i=o<>>32-n;o=o<>>0>>0?i+1|0:i;i=Du(n,i,1e9,0);o=Au(i,Ia,1e9,0);G[g>>2]=n-o;g=g-4|0;if(j>>>0<=g>>>0){continue}break}if(!i){break g}j=j-4|0;G[j>>2]=i}while(1){g=h;if(j>>>0>>0){h=g-4|0;if(!G[h>>2]){continue}}break}d=G[l+44>>2]-d|0;G[l+44>>2]=d;h=g;if((d|0)>0){continue}break}}if((d|0)<0){t=((m+25>>>0)/9|0)+1|0;n=(r|0)==102;while(1){d=0-d|0;i=(d|0)<9?d:9;h:{if(g>>>0<=j>>>0){h=G[j>>2];break h}o=1e9>>>i|0;y=-1<>2];G[h>>2]=x+(d>>>i|0);d=M(o,d&y);h=h+4|0;if(h>>>0>>0){continue}break}h=G[j>>2];if(!d){break h}G[g>>2]=d;g=g+4|0}d=i+G[l+44>>2]|0;G[l+44>>2]=d;j=(!h<<2)+j|0;h=n?p:j;g=g-h>>2>(t|0)?h+(t<<2)|0:g;if((d|0)<0){continue}break}}d=0;i:{if(g>>>0<=j>>>0){break i}d=M(p-j>>2,9);h=10;i=G[j>>2];if(i>>>0<10){break i}while(1){d=d+1|0;h=M(h,10);if(i>>>0>=h>>>0){continue}break}}h=(m-((r|0)==102?0:d)|0)-((r|0)==103&(m|0)!=0)|0;if((h|0)<(M(g-p>>2,9)-9|0)){i=h+9216|0;n=(i|0)/9|0;k=((((k|0)<0?4:292)+l|0)+(n<<2)|0)-4048|0;h=10;i=i-M(n,9)|0;if((i|0)<=7){while(1){h=M(h,10);i=i+1|0;if((i|0)!=8){continue}break}}n=G[k>>2];t=(n>>>0)/(h>>>0)|0;i=n-M(h,t)|0;o=k+4|0;j:{if(!i&(o|0)==(g|0)){break j}k:{if(!(t&1)){b=9007199254740992;if(!(E[k-4|0]&1)|((h|0)!=1e9|j>>>0>=k>>>0)){break k}}b=9007199254740994}q=(g|0)==(o|0)?1:1.5;o=h>>>1|0;q=i>>>0>>0?.5:(o|0)==(i|0)?q:1.5;if(!(H[w|0]!=45|z)){q=-q;b=-b}i=n-i|0;G[k>>2]=i;if(b+q==b){break j}d=h+i|0;G[k>>2]=d;if(d>>>0>=1e9){while(1){G[k>>2]=0;k=k-4|0;if(k>>>0>>0){j=j-4|0;G[j>>2]=0}d=G[k>>2]+1|0;G[k>>2]=d;if(d>>>0>999999999){continue}break}}d=M(p-j>>2,9);h=10;i=G[j>>2];if(i>>>0<10){break j}while(1){d=d+1|0;h=M(h,10);if(i>>>0>=h>>>0){continue}break}}h=k+4|0;g=g>>>0>h>>>0?h:g}while(1){h=g;i=g>>>0<=j>>>0;if(!i){g=h-4|0;if(!G[g>>2]){continue}}break}l:{if((r|0)!=103){k=e&8;break l}g=m?m:1;k=(g|0)>(d|0)&(d|0)>-5;m=(k?d^-1:-1)+g|0;f=(k?-1:-2)+f|0;k=e&8;if(k){break l}g=-9;m:{if(i){break m}n=G[h-4>>2];if(!n){break m}i=10;g=0;if((n>>>0)%10|0){break m}while(1){k=g;g=g+1|0;i=M(i,10);if(!((n>>>0)%(i>>>0)|0)){continue}break}g=k^-1}i=M(h-p>>2,9);if((f&-33)==70){k=0;g=(g+i|0)-9|0;g=(g|0)>0?g:0;m=(g|0)>(m|0)?m:g;break l}k=0;g=((d+i|0)+g|0)-9|0;g=(g|0)>0?g:0;m=(g|0)>(m|0)?m:g}i=-1;r=k|m;if(((r?2147483645:2147483646)|0)<(m|0)){break b}n=(((r|0)!=0)+m|0)+1|0;o=f&-33;n:{if((o|0)==70){if((2147483647-n|0)<(d|0)){break b}g=(d|0)>0?d:0;break n}g=d>>31;g=Lg((g^d)-g|0,0,u);if((u-g|0)<=1){while(1){g=g-1|0;E[g|0]=48;if((u-g|0)<2){continue}break}}t=g-2|0;E[t|0]=f;E[g-1|0]=(d|0)<0?45:43;g=u-t|0;if((g|0)>(2147483647-n|0)){break b}}d=g+n|0;if((d|0)>(s^2147483647)){break b}f=d+s|0;nd(a,32,c,f,e);gd(a,w,s);nd(a,48,c,f,e^65536);o:{p:{q:{if((o|0)==70){g=l+16|0;d=g|8;k=g|9;i=j>>>0>p>>>0?p:j;j=i;while(1){g=Lg(G[j>>2],0,k);r:{if((i|0)!=(j|0)){if(l+16>>>0>=g>>>0){break r}while(1){g=g-1|0;E[g|0]=48;if(l+16>>>0>>0){continue}break}break r}if((g|0)!=(k|0)){break r}E[l+24|0]=48;g=d}gd(a,g,k-g|0);j=j+4|0;if(p>>>0>=j>>>0){continue}break}if(r){gd(a,48504,1)}if((m|0)<=0|h>>>0<=j>>>0){break q}while(1){g=Lg(G[j>>2],0,k);if(g>>>0>l+16>>>0){while(1){g=g-1|0;E[g|0]=48;if(l+16>>>0>>0){continue}break}}gd(a,g,(m|0)<9?m:9);g=m-9|0;j=j+4|0;if(h>>>0<=j>>>0){break p}d=(m|0)>9;m=g;if(d){continue}break}break p}s:{if((m|0)<0){break s}i=h>>>0>j>>>0?h:j+4|0;g=l+16|0;d=g|8;p=g|9;h=j;while(1){g=Lg(G[h>>2],0,p);if((p|0)==(g|0)){E[l+24|0]=48;g=d}t:{if((h|0)!=(j|0)){if(l+16>>>0>=g>>>0){break t}while(1){g=g-1|0;E[g|0]=48;if(l+16>>>0>>0){continue}break}break t}gd(a,g,1);g=g+1|0;if(!(k|m)){break t}gd(a,48504,1)}x=g;g=p-g|0;gd(a,x,(g|0)>(m|0)?m:g);m=m-g|0;h=h+4|0;if(i>>>0<=h>>>0){break s}if((m|0)>=0){continue}break}}nd(a,48,m+18|0,18,0);gd(a,t,u-t|0);break o}g=m}nd(a,48,g+9|0,9,0)}nd(a,32,c,f,e^8192);i=(c|0)<(f|0)?f:c;break b}m=(f<<26>>31&9)+w|0;u:{if(d>>>0>11){break u}g=12-d|0;q=16;while(1){q=q*16;g=g-1|0;if(g){continue}break}if(H[m|0]==45){b=-(q+(-b-q));break u}b=b+q-q}h=G[l+44>>2];g=h>>31;g=Lg((g^h)-g|0,0,u);if((u|0)==(g|0)){E[l+15|0]=48;g=l+15|0}k=s|2;j=f&32;h=G[l+44>>2];p=g-2|0;E[p|0]=f+15;E[g-1|0]=(h|0)<0?45:43;i=e&8;h=l+16|0;while(1){f=h;if(O(b)<2147483648){g=~~b}else{g=-2147483648}E[h|0]=j|H[g+92512|0];b=(b-+(g|0))*16;h=f+1|0;if(!(!((d|0)>0|i)&b==0|(h-(l+16|0)|0)!=1)){E[f+1|0]=46;h=f+2|0}if(b!=0){continue}break}i=-1;n=u-p|0;f=n+k|0;if((2147483645-f|0)<(d|0)){break b}v:{w:{if(!d){break w}j=h-(l+16|0)|0;if((j-2|0)>=(d|0)){break w}g=d+2|0;break v}j=h-(l+16|0)|0;g=j}d=g+f|0;nd(a,32,c,d,e);gd(a,m,k);nd(a,48,c,d,e^65536);gd(a,l+16|0,j);nd(a,48,g-j|0,0,0);gd(a,p,n);nd(a,32,c,d,e^8192);i=(c|0)<(d|0)?d:c}Fa=l+560|0;return i|0}function fg(a,b,c,d,e,f,g,h,i,j,k,l,m,n){var o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;o=Fa-29056|0;Fa=o;a:{if(!(g|h)|G[n>>2]>0){break a}if(m){G[m>>2]=0}if((i|0)==2){cb(l,0,g)}if((yc(a,b,c,d,e,f,g,h,0,o+28984|0,o+28976|0,o+28944|0,o+29040|0,o+29052|0,o+29048|0,o+29016|0,o+29008|0,o+29036|0,o+29024|0,o+28992|0,o+29044|0,o+29e3|0,o+28816|0,n)|0)>0){break a}b:{c:{d:{if(G[o+29052>>2]==14){b=g;if(!b){break a}if((i|0)!=2){break d}e=0;f=0;if(m){break c}while(1){d=G[o+29020>>2];c=G[o+29016>>2];m=Au(G[o+28992>>2],G[o+28996>>2],s,t);c=c+m|0;i=Ia+d|0;i=c>>>0>>0?i+1|0:i;p=c;c=G[o+29008>>2];m=G[o+29012>>2];r=G[o+29036>>2];d=r;q=Au(c,m,d,d>>31);d=p+q|0;p=Ia+i|0;p=d>>>0>>0?p+1|0:p;i=d;d=m;m=G[o+29024>>2];d=G[o+29028>>2]-(d+(c>>>0>m>>>0)|0)|0;c=m-c|0;m=G[o+29048>>2];m=(b|0)>(m|0)?m:b;b=m>>31;q=m;m=c>>>0>>0&(b|0)>=(d|0)|(b|0)>(d|0);c=m?c:q;$d(a,i,p,c,r,o+16|0,n);if((c|0)>0){b=c+e|0;p=o+16|0;while(1){e:{f:{g:{h:{i:{j:{k:{i=H[p|0];switch(i|0){case 0:break i;case 1:break j;default:break k}}m=i-70|0;if(!m){break h}if((m|0)==14){break g}break f}E[e+k|0]=49;break e}E[e+k|0]=j;E[e+l|0]=1;break e}E[e+k|0]=0;break e}E[e+k|0]=1;break e}E[e+k|0]=i}p=p+1|0;i=f;e=e+1|0;i=e?i:i+1|0;f=i;if((b|0)!=(e|0)){continue}break}}if(G[n>>2]>0){break b}i=c>>31;b=c;h=h-((b>>>0>g>>>0)+i|0)|0;g=g-b|0;if(!(h|g)){break a}p=i+G[o+29012>>2]|0;c=b+G[o+29008>>2]|0;p=c>>>0>>0?p+1|0:p;b=c;G[o+29008>>2]=b;G[o+29012>>2]=p;if((b|0)==G[o+29024>>2]&(p|0)==G[o+29028>>2]){G[o+29008>>2]=0;G[o+29012>>2]=0;i=t;b=s+1|0;i=b?i:i+1|0;s=b;t=i}b=g;if(b){continue}break}break a}G[n>>2]=310;break a}if(m){e=0;f=0;while(1){d=G[o+29020>>2];c=G[o+29016>>2];l=Au(G[o+28992>>2],G[o+28996>>2],s,t);c=c+l|0;i=Ia+d|0;i=c>>>0>>0?i+1|0:i;d=c;c=G[o+29008>>2];l=G[o+29012>>2];p=G[o+29036>>2];r=Au(c,l,p,p>>31);d=d+r|0;i=Ia+i|0;i=d>>>0>>0?i+1|0:i;r=d;d=l;l=G[o+29024>>2];d=G[o+29028>>2]-(d+(c>>>0>l>>>0)|0)|0;c=l-c|0;l=G[o+29048>>2];l=(b|0)>(l|0)?l:b;b=l>>31;q=l;l=c>>>0>>0&(b|0)>=(d|0)|(b|0)>(d|0);c=l?c:q;$d(a,r,i,c,p,o+16|0,n);if((c|0)>0){b=c+e|0;p=o+16|0;while(1){l:{m:{n:{o:{p:{i=H[p|0];switch(i|0){case 1:break n;case 0:break o;default:break p}}l=i-70|0;if(l){if((l|0)!=14){break m}E[e+k|0]=1;break l}E[e+k|0]=0;break l}E[e+k|0]=j;G[m>>2]=1;break l}E[e+k|0]=49;break l}E[e+k|0]=i}p=p+1|0;i=f;e=e+1|0;i=e?i:i+1|0;f=i;if((b|0)!=(e|0)){continue}break}}if(G[n>>2]>0){break b}i=c;p=i>>31;b=i;h=h-((i>>>0>g>>>0)+p|0)|0;g=g-i|0;if(!(h|g)){break a}p=p+G[o+29012>>2]|0;c=b+G[o+29008>>2]|0;p=c>>>0>>0?p+1|0:p;b=c;G[o+29008>>2]=b;G[o+29012>>2]=p;if((b|0)==G[o+29024>>2]&(p|0)==G[o+29028>>2]){G[o+29008>>2]=0;G[o+29012>>2]=0;i=t;b=s+1|0;i=b?i:i+1|0;s=b;t=i}b=g;if(b){continue}break}break a}l=o+16|1;e=0;f=0;while(1){d=G[o+29020>>2];c=G[o+29016>>2];m=Au(G[o+28992>>2],G[o+28996>>2],s,t);c=c+m|0;i=Ia+d|0;i=c>>>0>>0?i+1|0:i;p=c;c=G[o+29008>>2];m=G[o+29012>>2];r=G[o+29036>>2];d=r;q=Au(c,m,d,d>>31);d=p+q|0;p=Ia+i|0;p=d>>>0>>0?p+1|0:p;i=d;d=m;m=G[o+29024>>2];d=G[o+29028>>2]-(d+(c>>>0>m>>>0)|0)|0;c=m-c|0;m=G[o+29048>>2];m=(b|0)>(m|0)?m:b;b=m>>31;q=m;m=c>>>0>>0&(b|0)>=(d|0)|(b|0)>(d|0);c=m?c:q;$d(a,i,p,c,r,o+16|0,n);q:{if((c|0)<=0){break q}b=e;p=o+16|0;if(c&1){p=49;r:{s:{t:{u:{v:{w:{i=H[o+16|0];switch(i|0){case 1:break r;case 0:break v;default:break w}}m=i-70|0;if(!m){break u}if((m|0)==14){break t}break s}p=j;break r}p=0;break r}p=1;break r}p=i}E[b+k|0]=p;p=l;i=f;e=e+1|0;i=e?i:i+1|0;f=i}if((c|0)==1){break q}r=b+c|0;while(1){b=49;m=49;x:{y:{z:{A:{B:{C:{i=H[p|0];switch(i|0){case 1:break x;case 0:break B;default:break C}}m=i-70|0;if(!m){break A}if((m|0)==14){break z}break y}m=j;break x}m=0;break x}m=1;break x}m=i}q=e+k|0;E[q|0]=m;D:{E:{F:{G:{H:{I:{i=H[p+1|0];switch(i|0){case 1:break D;case 0:break H;default:break I}}b=i-70|0;if(!b){break G}if((b|0)==14){break F}break E}b=j;break D}b=0;break D}b=1;break D}b=i}E[q+1|0]=b;p=p+2|0;i=f;b=e+2|0;i=b>>>0<2?i+1|0:i;e=b;f=i;if((b|0)!=(r|0)){continue}break}}if(G[n>>2]>0){break b}i=c>>31;b=c;h=h-((b>>>0>g>>>0)+i|0)|0;g=g-b|0;if(!(h|g)){break a}p=i+G[o+29012>>2]|0;c=b+G[o+29008>>2]|0;p=c>>>0>>0?p+1|0:p;b=c;G[o+29008>>2]=b;G[o+29012>>2]=p;if((b|0)==G[o+29024>>2]&(p|0)==G[o+29028>>2]){G[o+29008>>2]=0;G[o+29012>>2]=0;i=t;b=s+1|0;i=b?i:i+1|0;s=b;t=i}b=g;if(b){continue}break}break a}while(1){d=G[o+29020>>2];c=G[o+29016>>2];p=Au(G[o+28992>>2],G[o+28996>>2],s,t);c=c+p|0;i=Ia+d|0;i=c>>>0

>>0?i+1|0:i;u=c;c=G[o+29008>>2];p=G[o+29012>>2];r=G[o+29036>>2];d=r;q=Au(c,p,d,d>>31);d=u+q|0;i=Ia+i|0;i=d>>>0>>0?i+1|0:i;q=d;d=p;p=G[o+29024>>2];d=G[o+29028>>2]-(d+(c>>>0>p>>>0)|0)|0;c=p-c|0;p=G[o+29048>>2];p=(b|0)>(p|0)?p:b;b=p>>31;u=p;p=c>>>0

>>0&(b|0)>=(d|0)|(b|0)>(d|0);c=p?c:u;$d(a,q,i,c,r,o+16|0,n);if((c|0)>0){b=c+e|0;p=o+16|0;while(1){J:{K:{L:{M:{N:{O:{P:{i=H[p|0];switch(i|0){case 0:break N;case 1:break O;default:break P}}r=i-70|0;if(!r){break M}if((r|0)==14){break L}break K}E[e+k|0]=49;break J}E[e+k|0]=j;G[m>>2]=1;E[e+l|0]=1;break J}E[e+k|0]=0;break J}E[e+k|0]=1;break J}E[e+k|0]=i}p=p+1|0;i=f;e=e+1|0;i=e?i:i+1|0;f=i;if((b|0)!=(e|0)){continue}break}}if(G[n>>2]>0){break b}i=c;p=i>>31;b=i;h=h-((i>>>0>g>>>0)+p|0)|0;g=g-i|0;if(!(h|g)){break a}p=p+G[o+29012>>2]|0;c=b+G[o+29008>>2]|0;p=c>>>0>>0?p+1|0:p;b=c;G[o+29008>>2]=b;G[o+29012>>2]=p;if((b|0)==G[o+29024>>2]&(p|0)==G[o+29028>>2]){G[o+29008>>2]=0;G[o+29012>>2]=0;i=t;b=s+1|0;i=b?i:i+1|0;s=b;t=i}b=g;if(b){continue}break}break a}v=+(e>>>0)+ +(f|0)*4294967296;L[o>>3]=v+1;L[o+8>>3]=+(c|0)+v;a=o+28848|0;Ya(a,81,46369,o);Ua(a)}Fa=o+29056|0}function Bm(a,b,c,d,e,f,g){var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;h=Fa-112|0;Fa=h;n=(b|0)==11;j=c==0?(a|0)==2?1950:2e3:c;i=n&(a|0)==1&j==2e3;q=i?11:a;c=i?j:d==0?(b|0)==2?1950:2e3:d;c=(a|0)==11?n?j:c:c;n=(b|0)==1&(q|0)==11&c==2e3;a=n?1:q;d=n?c:j;a:{if((a|0)==(b|0)&d==c){break a}q=c==d;b:{if(q){break b}if(!((a|0)!=2|d==1950)){Fm(d,1950,e,f);break b}if((a|0)!=1|d==2e3){break b}ai(d,2e3,e,f)}c:{if((b|0)==2){d:{switch(a-1|0){case 0:if(g>0){G[h+16>>2]=0;G[h+20>>2]=0;G[h+8>>2]=0;G[h+12>>2]=0;G[h+32>>2]=0;G[h+36>>2]=0;$h(e,f,h+16|0,h+8|0,h+32|0,h+24|0);d=g+-1950;L[e>>3]=L[h+16>>3]*d+L[e>>3];L[f>>3]=L[h+8>>3]*d+L[f>>3];break c}G[h+16>>2]=0;G[h+20>>2]=0;G[h+8>>2]=0;G[h+12>>2]=0;G[h+32>>2]=0;G[h+36>>2]=0;$h(e,f,h+16|0,h+8|0,h+32|0,h+24|0);break c;case 2:a=Fa-80|0;Fa=a;g=L[e>>3];p=L[f>>3];j=p*3.141592653589793/180;d=eb(j);k=g*3.141592653589793/180;l=ib(k);k=eb(k);j=ib(j);k=k*d;d=l*d;l=j*-.188374601723+(k*-.872755765852+d*-.45034695802);m=j*-.867600811151+(k*-.066988739415+d*.492728466075);o=Db(l,m);o=o<0?o+6.283185307179586:o;o=(o>6.283185307179586?o+-6.283185307179586:o)*180/3.141592653589793;L[e>>3]=o;d=Db(j*.460199784784+(k*-.483538914632+d*.744584633283),V(m*m+l*l))*180/3.141592653589793;L[f>>3]=d;if(G[321348]){L[a+72>>3]=p;L[a+64>>3]=g;r=G[24367];xb(r,72215,a- -64|0);n=ab(32);s=d<0;d=s?-d:d;e:{if(O(d)<2147483648){i=~~d;break e}i=-2147483648}G[a+36>>2]=i;G[a+32>>2]=s?45:43;d=(d-+(i|0))*60;f:{if(O(d)<2147483648){i=~~d;break f}i=-2147483648}G[a+40>>2]=i;L[a+48>>3]=(d-+(i|0))*60;d=o/15;g:{if(O(d)<2147483648){i=~~d;break g}i=-2147483648}G[a+16>>2]=i;d=(d-+(i|0))*60;h:{if(O(d)<2147483648){i=~~d;break h}i=-2147483648}G[a+20>>2]=i;L[a+24>>3]=(d-+(i|0))*60;Eb(n,19241,a+16|0);if(H[n+6|0]==32){E[n+6|0]=48}if(H[n+20|0]==32){E[n+20|0]=48}G[a>>2]=n;_a(r,69295,a);Wa(n)}Fa=a+80|0;break c;case 3:break d;default:break c}}if(g>0){_h(e,f,g);G[h+16>>2]=0;G[h+20>>2]=0;G[h+8>>2]=0;G[h+12>>2]=0;G[h+32>>2]=0;G[h+36>>2]=0;$h(e,f,h+16|0,h+8|0,h+32|0,h+24|0);d=g+-1950;L[e>>3]=L[h+16>>3]*d+L[e>>3];L[f>>3]=L[h+8>>3]*d+L[f>>3];break c}d=L[f>>3];g=L[e>>3]*3.141592653589793/180;k=eb(g);j=d*3.141592653589793/180;d=eb(j);l=ib(g);g=ib(j);j=l*d;k=k*d;m=k*0+0;d=g*-.3978812701051372+(j*.9174369160326626+m);k=g*0+(j*0+(k+0));l=Db(d,k);l=l<0?l+6.283185307179586:l;L[e>>3]=(l>6.283185307179586?l+-6.283185307179586:l)*180/3.141592653589793;d=Db(g*.9174369160326626+(j*.3978812701051372+m),V(k*k+d*d))*180/3.141592653589793;L[f>>3]=d;j=L[e>>3];a=h+32|0;Cj(-.005589114674240335,.004859078490463986,-.005590075450722788,a);d=d*3.141592653589793/180;g=eb(d);j=j*3.141592653589793/180;k=ib(j);l=L[h+40>>3];m=eb(j);o=L[h+32>>3];p=L[h+48>>3];d=ib(d);t=L[h+96>>3];u=L[h+80>>3];v=L[h+88>>3];j=g*k;g=g*m;k=d*L[h+72>>3]+(j*L[h+64>>3]+(g*L[h+56>>3]+0));l=d*p+(j*l+(g*o+0));m=Db(k,l);m=m<0?m+6.283185307179586:m;L[e>>3]=(m>6.283185307179586?m+-6.283185307179586:m)*180/3.141592653589793;w=f,x=Db(d*t+(j*v+(g*u+0)),V(l*l+k*k))*180/3.141592653589793,L[w>>3]=x;G[h+16>>2]=0;G[h+20>>2]=0;G[h+8>>2]=0;G[h+12>>2]=0;G[h+32>>2]=0;G[h+36>>2]=0;$h(e,f,h+16|0,h+8|0,a,h+24|0);L[e>>3]=L[h+16>>3]*0+L[e>>3];L[f>>3]=L[h+8>>3]*0+L[f>>3];break c}if((b|0)==1){i:{switch(a-2|0){case 0:if(g>0){a=Fa-32|0;Fa=a;G[a+8>>2]=0;G[a+12>>2]=0;G[a>>2]=0;G[a+4>>2]=0;G[a+24>>2]=0;G[a+28>>2]=0;G[a+16>>2]=0;G[a+20>>2]=0;Dj(e,f,a+8|0,a,a+24|0,a+16|0);d=g+-2e3;L[e>>3]=L[a+8>>3]*d+L[e>>3];L[f>>3]=L[a>>3]*d+L[f>>3];Fa=a+32|0;break c}a=Fa-32|0;Fa=a;G[a+8>>2]=0;G[a+12>>2]=0;G[a>>2]=0;G[a+4>>2]=0;G[a+24>>2]=0;G[a+28>>2]=0;G[a+16>>2]=0;G[a+20>>2]=0;Dj(e,f,a+8|0,a,a+24|0,a+16|0);Fa=a+32|0;break c;case 1:Em(e,f);break c;case 2:break i;default:break c}}if(g>0){_h(e,f,g);break c}_h(e,f,2e3);break c}j:{switch(b-3|0){case 0:k:{switch(a-1|0){case 1:a=Fa-80|0;Fa=a;g=L[e>>3];d=L[f>>3];k=d*3.141592653589793/180;j=eb(k);l=g*3.141592653589793/180;m=ib(l);l=eb(l);k=ib(k);l=l*j;j=m*j;m=k*.744584633283+(l*.492728466075+j*-.45034695802);o=k*-.483538914632+(l*-.066988739415+j*-.872755765852);p=Db(m,o);p=p<0?p+6.283185307179586:p;p=(p>6.283185307179586?p+-6.283185307179586:p)*180/3.141592653589793;L[e>>3]=p;j=Db(k*.460199784784+(l*-.867600811151+j*-.188374601723),V(o*o+m*m))*180/3.141592653589793;L[f>>3]=j;if(G[321348]){n=ab(32);i=d<0;G[a+48>>2]=i?45:43;d=i?-d:d;l:{if(O(d)<2147483648){i=~~d;break l}i=-2147483648}G[a+52>>2]=i;d=(d-+(i|0))*60;m:{if(O(d)<2147483648){i=~~d;break m}i=-2147483648}G[a+56>>2]=i;L[a- -64>>3]=(d-+(i|0))*60;d=g/15;n:{if(O(d)<2147483648){i=~~d;break n}i=-2147483648}G[a+32>>2]=i;d=(d-+(i|0))*60;o:{if(O(d)<2147483648){i=~~d;break o}i=-2147483648}G[a+36>>2]=i;L[a+40>>3]=(d-+(i|0))*60;Eb(n,19241,a+32|0);if(H[n+6|0]==32){E[n+6|0]=48}if(H[n+20|0]==32){E[n+20|0]=48}G[a+16>>2]=n;i=G[24367];_a(i,69268,a+16|0);L[a+8>>3]=j;L[a>>3]=p;xb(i,72149,a);Wa(n)}Fa=a+80|0;break c;case 0:Dm(e,f);break c;case 3:break k;default:break c}}_h(e,f,g>0?g:2e3);Dm(e,f);break c;case 1:break j;default:break c}}p:{switch(a-1|0){case 1:if(g>0){Cm(e,f,g);break c}Cm(e,f,1950);break c;case 0:if(g>0){_g(e,f,g);break c}_g(e,f,2e3);break c;case 2:break p;default:break c}}Em(e,f);if(g>0){_g(e,f,g);break c}_g(e,f,2e3)}q:{if(q){break q}if(!((b|0)!=2|c==1950)){Fm(1950,c,e,f)}if((b|0)!=1|c==2e3){break q}ai(2e3,c,e,f)}c=L[f>>3];r:{if(c>90){L[f>>3]=180-c;c=L[e>>3]+180;L[e>>3]=c;break r}if(c<-90){L[f>>3]=-180-c;c=L[e>>3]+180;L[e>>3]=c;break r}c=L[e>>3]}d=-360;if(!(c>360)){d=360;if(!(c<0)){break a}}L[e>>3]=c+d}Fa=h+112|0}function tu(a,b,c){a=a|0;b=+b;c=+c;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;a:{if((a|0)<=0|G[968816]<=(a|0)){break a}d=G[968817];if(!d){break a}a=d+M(a,65544)|0;e=G[a>>2];if(!e){break a}E[a+8|0]=0;f=a+8|0;h=65536;g=Fa-144|0;Fa=g;b:{if(!(G[e+3312>>2]?e:0)){E[f|0]=0;break b}cc(e,b,c,g+136|0,g+128|0);if(G[e+3308>>2]){E[f|0]=79;E[f+1|0]=102;E[f+2|0]=102;E[f+3|0]=32;E[f+4|0]=109;E[f+5|0]=97;E[f+6|0]=112;E[f+7|0]=0;break b}c:{d:{e:{switch(G[e+3292>>2]){case 1:a=G[e+3288>>2];d=(a<<1)+9|0;if((d|0)<65536){h=g+96|0;zm(h,L[g+136>>3],a);a=g- -64|0;zm(a,L[g+128>>3],G[e+3288>>2]);j=G[e+3296>>2];G[g+36>>2]=a;G[g+32>>2]=h;db(f,j?10358:9032,g+32|0);h=65536-d|0;break c}if(G[e+3296>>2]){rb(f,49098,65536);break d}rb(f,49050,65536);break d;case 0:break e;default:break c}}a=G[e+3288>>2];d=(a<<1)+18|0;if((d|0)<65536){b=L[g+136>>3];f:{if(G[e+3968>>2]-1>>>0<=1){Bj(g+96|0,32,b,a);Mf(g- -64|0,32,L[g+128>>3],G[e+3288>>2]-1|0);break f}Mf(g+96|0,32,b,a);Mf(g- -64|0,32,L[g+128>>3],G[e+3288>>2])}a=G[e+3296>>2];G[g+52>>2]=g- -64;G[g+48>>2]=g+96;db(f,a?10358:9032,g+48|0);h=65536-d|0;break c}if(G[e+3296>>2]){rb(f,49070,65536);break d}rb(f,49043,65536)}h=0}g:{switch(G[e+3968>>2]-1|0){case 2:if(!G[e+3284>>2]|(h|0)<10){break b}a=Va(f)+f|0;if(G[e+3296>>2]){d=H[30684]|H[30685]<<8;E[a+8|0]=d;E[a+9|0]=d>>>8;d=H[30680]|H[30681]<<8|(H[30682]<<16|H[30683]<<24);e=H[30676]|H[30677]<<8|(H[30678]<<16|H[30679]<<24);E[a|0]=e;E[a+1|0]=e>>>8;E[a+2|0]=e>>>16;E[a+3|0]=e>>>24;E[a+4|0]=d;E[a+5|0]=d>>>8;E[a+6|0]=d>>>16;E[a+7|0]=d>>>24;break b}d=H[30674]|H[30675]<<8;E[a+8|0]=d;E[a+9|0]=d>>>8;d=H[30670]|H[30671]<<8|(H[30672]<<16|H[30673]<<24);e=H[30666]|H[30667]<<8|(H[30668]<<16|H[30669]<<24);E[a|0]=e;E[a+1|0]=e>>>8;E[a+2|0]=e>>>16;E[a+3|0]=e>>>24;E[a+4|0]=d;E[a+5|0]=d>>>8;E[a+6|0]=d>>>16;E[a+7|0]=d>>>24;break b;case 3:if(!G[e+3284>>2]|(h|0)<10){break b}a=Va(f)+f|0;if(G[e+3296>>2]){d=H[30664]|H[30665]<<8;E[a+8|0]=d;E[a+9|0]=d>>>8;d=H[30660]|H[30661]<<8|(H[30662]<<16|H[30663]<<24);e=H[30656]|H[30657]<<8|(H[30658]<<16|H[30659]<<24);E[a|0]=e;E[a+1|0]=e>>>8;E[a+2|0]=e>>>16;E[a+3|0]=e>>>24;E[a+4|0]=d;E[a+5|0]=d>>>8;E[a+6|0]=d>>>16;E[a+7|0]=d>>>24;break b}d=H[30654]|H[30655]<<8;E[a+8|0]=d;E[a+9|0]=d>>>8;d=H[30650]|H[30651]<<8|(H[30652]<<16|H[30653]<<24);e=H[30646]|H[30647]<<8|(H[30648]<<16|H[30649]<<24);E[a|0]=e;E[a+1|0]=e>>>8;E[a+2|0]=e>>>16;E[a+3|0]=e>>>24;E[a+4|0]=d;E[a+5|0]=d>>>8;E[a+6|0]=d>>>16;E[a+7|0]=d>>>24;break b;case 8:if(!G[e+3284>>2]|(h|0)<10){break b}a=Va(f)+f|0;if(G[e+3296>>2]){E[a|0]=9;E[a+1|0]=112;E[a+2|0]=108;E[a+3|0]=97;E[a+4|0]=110;E[a+5|0]=101;E[a+6|0]=116;E[a+7|0]=0;break b}E[a|0]=32;E[a+1|0]=112;E[a+2|0]=108;E[a+3|0]=97;E[a+4|0]=110;E[a+5|0]=101;E[a+6|0]=116;E[a+7|0]=0;break b;case 4:if(!G[e+3284>>2]|(h|0)<8){break b}a=Va(f)+f|0;if(G[e+3296>>2]){E[a|0]=9;E[a+1|0]=97;E[a+2|0]=108;E[a+3|0]=116;E[a+4|0]=45;E[a+5|0]=97;E[a+6|0]=122;E[a+7|0]=0;break b}E[a|0]=32;E[a+1|0]=97;E[a+2|0]=108;E[a+3|0]=116;E[a+4|0]=45;E[a+5|0]=97;E[a+6|0]=122;E[a+7|0]=0;break b;case 6:if(!G[e+3284>>2]|(h|0)<8){break b}a=Va(f)+f|0;if(G[e+3296>>2]){d=H[31029]|H[31030]<<8;E[a+8|0]=d;E[a+9|0]=d>>>8;d=H[31025]|H[31026]<<8|(H[31027]<<16|H[31028]<<24);e=H[31021]|H[31022]<<8|(H[31023]<<16|H[31024]<<24);E[a|0]=e;E[a+1|0]=e>>>8;E[a+2|0]=e>>>16;E[a+3|0]=e>>>24;E[a+4|0]=d;E[a+5|0]=d>>>8;E[a+6|0]=d>>>16;E[a+7|0]=d>>>24;break b}d=H[31019]|H[31020]<<8;E[a+8|0]=d;E[a+9|0]=d>>>8;d=H[31015]|H[31016]<<8|(H[31017]<<16|H[31018]<<24);e=H[31011]|H[31012]<<8|(H[31013]<<16|H[31014]<<24);E[a|0]=e;E[a+1|0]=e>>>8;E[a+2|0]=e>>>16;E[a+3|0]=e>>>24;E[a+4|0]=d;E[a+5|0]=d>>>8;E[a+6|0]=d>>>16;E[a+7|0]=d>>>24;break b;case 7:if(!G[e+3284>>2]|(h|0)<8){break b}a=Va(f)+f|0;if(G[e+3296>>2]){d=H[31009]|H[31010]<<8;E[a+8|0]=d;E[a+9|0]=d>>>8;d=H[31005]|H[31006]<<8|(H[31007]<<16|H[31008]<<24);e=H[31001]|H[31002]<<8|(H[31003]<<16|H[31004]<<24);E[a|0]=e;E[a+1|0]=e>>>8;E[a+2|0]=e>>>16;E[a+3|0]=e>>>24;E[a+4|0]=d;E[a+5|0]=d>>>8;E[a+6|0]=d>>>16;E[a+7|0]=d>>>24;break b}d=H[30999]|H[31e3]<<8;E[a+8|0]=d;E[a+9|0]=d>>>8;d=H[30995]|H[30996]<<8|(H[30997]<<16|H[30998]<<24);e=H[30991]|H[30992]<<8|(H[30993]<<16|H[30994]<<24);E[a|0]=e;E[a+1|0]=e>>>8;E[a+2|0]=e>>>16;E[a+3|0]=e>>>24;E[a+4|0]=d;E[a+5|0]=d>>>8;E[a+6|0]=d>>>16;E[a+7|0]=d>>>24;break b;case 0:case 1:a=e+3880|0;if((Va(a)+1|0)>=(h|0)|!G[e+3284>>2]){break b}d=Va(f)+f|0;e=G[e+3296>>2]?9:32;E[d|0]=e;E[d+1|0]=e>>>8;Gb(f,a);break b;default:break g}}a=g+96|0;ym(a,L[g+136>>3],G[e+3288>>2]);d=g- -64|0;ym(d,L[g+128>>3],G[e+3288>>2]);a=Va(a);d=Va(d);k=e+3560|0;i=Va(k);j=e+3592|0;l=(i+Va(j)|0)+2|0;a=(a+d|0)+1|0;h:{if(G[e+3964>>2]!=6|G[e+3328>>2]!=1){break h}d=a+l|0;if((d|0)>=(h|0)){break h}if(i){a=g+96|0;i=Va(a)+a|0;E[i|0]=32;E[i+1|0]=0;Gb(a,k)}if(H[j|0]){a=g- -64|0;i=Va(a)+a|0;E[i|0]=32;E[i+1|0]=0;Gb(a,j)}a=d}d=G[e+3296>>2];i:{if((a|0)<(h|0)){if(d){G[g+20>>2]=g- -64;G[g+16>>2]=g+96;db(f,10358,g+16|0);break i}G[g+4>>2]=g- -64;G[g>>2]=g+96;db(f,9032,g);break i}if(d){rb(f,49119,h);break i}rb(f,49050,h)}if(G[e+3964>>2]!=6){break b}d=a+7|0;a=G[e+3328>>2];if(!((a|0)==1|(d|0)>=(h|0))){a=Va(f)+f|0;E[a|0]=32;E[a+1|0]=108;E[a+2|0]=105;E[a+3|0]=110;E[a+4|0]=101;E[a+5|0]=97;E[a+6|0]=114;E[a+7|0]=0;if(G[e+3964>>2]!=6){break b}a=G[e+3328>>2]}if((a|0)!=2|(d+l|0)>=(h|0)){break b}if(H[k|0]){a=Va(f)+f|0;E[a|0]=32;E[a+1|0]=0;Gb(f,k)}if(!H[j|0]){break b}a=Va(f)+f|0;E[a|0]=32;E[a+1|0]=0;Gb(f,j)}Fa=g+144|0}return f|0}function Hc(a,b,c,d){var e=0,f=0,g=0,h=0,i=0;h=G[a>>2];e=G[a+4>>2];if((h|0)!=G[e+76>>2]){mb(a,h+1|0,0,d);e=G[a+4>>2]}a:{b:{c:{f=G[e+1732>>2];if(G[((f<<2)+e|0)+1256>>2]!=(b|0)){g=38;f=G[e+1728>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=37;f=G[e+1724>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=36;f=G[e+1720>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=35;f=G[e+1716>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=34;f=G[e+1712>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=33;f=G[e+1708>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=32;f=G[e+1704>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=31;f=G[e+1700>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=30;f=G[e+1696>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=29;f=G[e+1692>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=28;f=G[e+1688>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=27;f=G[e+1684>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=26;f=G[e+1680>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=25;f=G[e+1676>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=24;f=G[e+1672>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=23;f=G[e+1668>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=22;f=G[e+1664>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=21;f=G[e+1660>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=20;f=G[e+1656>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=19;f=G[e+1652>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=18;f=G[e+1648>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=17;f=G[e+1644>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=16;f=G[e+1640>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=15;f=G[e+1636>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=14;f=G[e+1632>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=13;f=G[e+1628>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=12;f=G[e+1624>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=11;f=G[e+1620>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=10;f=G[e+1616>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=9;f=G[e+1612>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=8;f=G[e+1608>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=7;f=G[e+1604>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=6;f=G[e+1600>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=5;f=G[e+1596>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=4;f=G[e+1592>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=3;f=G[e+1588>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=2;f=G[e+1584>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=1;f=G[e+1580>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}g=0;f=G[e+1576>>2];if(G[((f<<2)+e|0)+1256>>2]==(b|0)){break c}i=Au(b,b>>31,2880,0);h=Ia;d:{if(c){break d}c=G[e+44>>2];if(J[e+40>>2]>i>>>0&(c|0)>=(h|0)|(c|0)>(h|0)){break d}G[d>>2]=107;return}if((f|0)<0){G[d>>2]=103;return}if(G[((f<<2)+e|0)+1416>>2]){Hg(e,f,d);e=G[a+4>>2]}c=G[e+36>>2];e:{if((h|0)>=(c|0)&i>>>0>=J[e+32>>2]|(c|0)<(h|0)){c=G[e+1252>>2]+M(f,2880)|0;f:{if(G[e+80>>2]==1){cb(c,32,2880);break f}cb(c,0,2880)}e=G[a+4>>2];c=G[e+44>>2];i=i+2880|0;h=i>>>0<2880?h+1|0:h;d=G[e+40>>2];a=d;d=d>>>0>i>>>0&(c|0)>=(h|0)|(c|0)>(h|0);G[e+40>>2]=d?a:i;G[e+44>>2]=d?c:h;G[((f<<2)+e|0)+1416>>2]=1;break e}if(G[e+64>>2]!=(i|0)|G[e+68>>2]!=(h|0)){Ja[G[(M(G[e+4>>2],84)+1240576|0)+72>>2]](G[e>>2],i,h)|0;e=G[a+4>>2]}Lj(e,2880,G[e+1252>>2]+M(f,2880)|0,d);c=i+2880|0;h=c>>>0<2880?h+1|0:h;e=G[a+4>>2];G[e+64>>2]=c;G[e+68>>2]=h}G[((f<<2)+e|0)+1256>>2]=b;G[e+72>>2]=f;if(G[e+1576>>2]==(f|0)){break b}g=1;if(G[e+1580>>2]==(f|0)){break b}g=2;if(G[e+1584>>2]==(f|0)){break b}g=3;if(G[e+1588>>2]==(f|0)){break b}g=4;if(G[e+1592>>2]==(f|0)){break b}g=5;if(G[e+1596>>2]==(f|0)){break b}g=6;if(G[e+1600>>2]==(f|0)){break b}g=7;if(G[e+1604>>2]==(f|0)){break b}g=8;if(G[e+1608>>2]==(f|0)){break b}g=9;if(G[e+1612>>2]==(f|0)){break b}g=10;if(G[e+1616>>2]==(f|0)){break b}g=11;if(G[e+1620>>2]==(f|0)){break b}g=12;if(G[e+1624>>2]==(f|0)){break b}g=13;if(G[e+1628>>2]==(f|0)){break b}g=14;if(G[e+1632>>2]==(f|0)){break b}g=15;if(G[e+1636>>2]==(f|0)){break b}g=16;if(G[e+1640>>2]==(f|0)){break b}g=17;if(G[e+1644>>2]==(f|0)){break b}g=18;if(G[e+1648>>2]==(f|0)){break b}g=19;if(G[e+1652>>2]==(f|0)){break b}g=20;if(G[e+1656>>2]==(f|0)){break b}g=21;if(G[e+1660>>2]==(f|0)){break b}g=22;if(G[e+1664>>2]==(f|0)){break b}g=23;if(G[e+1668>>2]==(f|0)){break b}g=24;if(G[e+1672>>2]==(f|0)){break b}g=25;if(G[e+1676>>2]==(f|0)){break b}g=26;if(G[e+1680>>2]==(f|0)){break b}g=27;if(G[e+1684>>2]==(f|0)){break b}g=28;if(G[e+1688>>2]==(f|0)){break b}g=29;if(G[e+1692>>2]==(f|0)){break b}g=30;if(G[e+1696>>2]==(f|0)){break b}g=31;if(G[e+1700>>2]==(f|0)){break b}g=32;if(G[e+1704>>2]==(f|0)){break b}g=33;if(G[e+1708>>2]==(f|0)){break b}g=34;if(G[e+1712>>2]==(f|0)){break b}g=35;if(G[e+1716>>2]==(f|0)){break b}g=36;if(G[e+1720>>2]==(f|0)){break b}g=37;if(G[e+1724>>2]==(f|0)){break b}g=38;if(G[e+1728>>2]==(f|0)){break b}break a}G[e+72>>2]=f;break a}G[e+72>>2]=f}a=g;d=3-a&3;if(d){b=0;c=e+1576|0;while(1){h=c+(a<<2)|0;a=a+1|0;G[h>>2]=G[c+(a<<2)>>2];b=b+1|0;if((d|0)!=(b|0)){continue}break}}if(g-36>>>0<3){break a}c=e+1576|0;while(1){b=c+(a<<2)|0;d=G[b+4>>2];h=G[b+8>>2];G[b+8>>2]=G[b+12>>2];G[b>>2]=d;G[b+4>>2]=h;a=a+4|0;G[b+12>>2]=G[c+(a<<2)>>2];if((a|0)!=39){continue}break}}G[e+1732>>2]=f}function fp(a,b,c,d,e,f,g){var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;h=Fa-80|0;Fa=h;G[h+76>>2]=b;x=h+55|0;s=h+56|0;b=0;a:{b:{c:{d:{e:while(1){if((2147483647-o|0)<(b|0)){break d}o=b+o|0;f:{g:{h:{j=G[h+76>>2];b=j;l=H[b|0];if(l){while(1){i:{i=l&255;j:{if(!i){l=b;break j}if((i|0)!=37){break i}l=b;while(1){if(H[b+1|0]!=37){break j}i=b+2|0;G[h+76>>2]=i;l=l+1|0;k=H[b+2|0];b=i;if((k|0)==37){continue}break}}b=l-j|0;w=2147483647-o|0;if((b|0)>(w|0)){break d}if(a){gd(a,j,b)}if(b){continue e}r=-1;i=1;b=G[h+76>>2];if(!(E[b+1|0]-48>>>0>=10|H[b+2|0]!=36)){r=E[b+1|0]-48|0;u=1;i=3}b=i+b|0;G[h+76>>2]=b;p=0;m=E[b|0];l=m-32|0;k:{if(l>>>0>31){i=b;break k}i=b;k=1<>2]=i;p=k|p;m=E[b+1|0];l=m-32|0;if(l>>>0>=32){break k}b=i;k=1<>>0>=10){break n}b=G[h+76>>2];if(H[b+2|0]!=36){break n}G[((E[b+1|0]<<2)+e|0)-192>>2]=10;q=G[((E[b+1|0]<<3)+d|0)-384>>2];u=1;b=b+3|0;break m}if(u){break h}u=0;q=0;if(a){b=G[c>>2];G[c>>2]=b+4;q=G[b>>2]}b=G[h+76>>2]+1|0}G[h+76>>2]=b;if((q|0)>=0){break l}q=0-q|0;p=p|8192;break l}q=Wo(h+76|0);if((q|0)<0){break d}b=G[h+76>>2]}i=0;k=-1;n=0;o:{if(H[b|0]!=46){break o}if(H[b+1|0]==42){p:{q:{if(E[b+2|0]-48>>>0>=10){break q}b=G[h+76>>2];if(H[b+3|0]!=36){break q}G[((E[b+2|0]<<2)+e|0)-192>>2]=10;k=G[((E[b+2|0]<<3)+d|0)-384>>2];b=b+4|0;break p}if(u){break h}if(a){b=G[c>>2];G[c>>2]=b+4;k=G[b>>2]}else{k=0}b=G[h+76>>2]+2|0}G[h+76>>2]=b;n=(k^-1)>>>31|0;break o}G[h+76>>2]=b+1;k=Wo(h+76|0);b=G[h+76>>2];n=1}v=n;while(1){t=i;l=28;if(E[b|0]-123>>>0<4294967238){break c}m=b+1|0;G[h+76>>2]=m;i=E[b|0];b=m;i=H[(i+M(t,58)|0)+91983|0];if(i-1>>>0<8){continue}break}r:{s:{if((i|0)!=27){if(!i){break c}if((r|0)>=0){G[(r<<2)+e>>2]=i;b=(r<<3)+d|0;i=G[b+4>>2];G[h+64>>2]=G[b>>2];G[h+68>>2]=i;break s}if(!a){break f}Oo(h- -64|0,i,c,g);m=G[h+76>>2];break r}if((r|0)>=0){break c}}b=0;if(!a){continue e}}n=p&-65537;i=p&8192?n:p;p=0;r=3838;l=s;t:{u:{v:{w:{x:{y:{z:{A:{B:{C:{D:{E:{F:{G:{H:{I:{b=E[m-1|0];b=t?(b&15)==3?b&-33:b:b;switch(b-88|0){case 11:break t;case 9:case 13:case 14:case 15:break u;case 27:break z;case 12:case 17:break C;case 23:break D;case 0:case 32:break E;case 24:break F;case 22:break G;case 29:break H;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 10:case 16:case 18:case 19:case 20:case 21:case 25:case 26:case 28:case 30:case 31:break g;default:break I}}J:{switch(b-65|0){case 0:case 4:case 5:case 6:break u;case 2:break x;case 1:case 3:break g;default:break J}}if((b|0)==83){break y}break g}m=G[h+64>>2];j=G[h+68>>2];r=3838;break B}b=0;K:{switch(t&255){case 0:G[G[h+64>>2]>>2]=o;continue e;case 1:G[G[h+64>>2]>>2]=o;continue e;case 2:i=G[h+64>>2];G[i>>2]=o;G[i+4>>2]=o>>31;continue e;case 3:F[G[h+64>>2]>>1]=o;continue e;case 4:E[G[h+64>>2]]=o;continue e;case 6:G[G[h+64>>2]>>2]=o;continue e;case 7:break K;default:continue e}}i=G[h+64>>2];G[i>>2]=o;G[i+4>>2]=o>>31;continue e}k=k>>>0>8?k:8;i=i|8;b=120}n=s;y=b&32;m=G[h+64>>2];j=G[h+68>>2];if(m|j){while(1){n=n-1|0;E[n|0]=y|H[(m&15)+92512|0];z=!j&m>>>0>15|(j|0)!=0;t=j;j=j>>>4|0;m=(t&15)<<28|m>>>4;if(z){continue}break}}j=n;if(!(G[h+64>>2]|G[h+68>>2])|!(i&8)){break A}r=(b>>>4|0)+3838|0;p=2;break A}b=s;m=G[h+64>>2];j=G[h+68>>2];if(m|j){while(1){b=b-1|0;E[b|0]=m&7|48;t=!j&m>>>0>7|(j|0)!=0;n=j;j=j>>>3|0;m=(n&7)<<29|m>>>3;if(t){continue}break}}j=b;if(!(i&8)){break A}b=s-j|0;k=(b|0)<(k|0)?k:b+1|0;break A}b=G[h+68>>2];j=b;m=G[h+64>>2];if((b|0)<0){j=0-(j+((m|0)!=0)|0)|0;m=0-m|0;G[h+64>>2]=m;G[h+68>>2]=j;p=1;r=3838;break B}if(i&2048){p=1;r=3839;break B}p=i&1;r=p?3840:3838}j=Lg(m,j,s)}if((k|0)<0?v:0){break d}i=v?i&-65537:i;n=G[h+64>>2];b=G[h+68>>2];if(!(k|(n|b)!=0)){j=s;l=j;k=0;break g}b=!(b|n)+(s-j|0)|0;k=(b|0)<(k|0)?k:b;break g}b=G[h+64>>2];j=b?b:59377;b=k>>>0<2147483647?k:2147483647;i=Vi(j,0,b);b=i?i-j|0:b;l=b+j|0;if((k|0)>=0){i=n;k=b;break g}i=n;k=b;if(H[l|0]){break d}break g}if(k){l=G[h+64>>2];break w}b=0;nd(a,32,q,0,i);break v}G[h+12>>2]=0;G[h+8>>2]=G[h+64>>2];l=h+8|0;G[h+64>>2]=l;k=-1}b=0;L:{while(1){j=G[l>>2];if(!j){break L}j=Sp(h+4|0,j);n=(j|0)<0;if(!(n|j>>>0>k-b>>>0)){l=l+4|0;b=b+j|0;if(k>>>0>b>>>0){continue}break L}break}if(n){break b}}l=61;if((b|0)<0){break c}nd(a,32,q,b,i);if(!b){b=0;break v}k=0;l=G[h+64>>2];while(1){j=G[l>>2];if(!j){break v}j=Sp(h+4|0,j);k=j+k|0;if(k>>>0>b>>>0){break v}gd(a,h+4|0,j);l=l+4|0;if(b>>>0>k>>>0){continue}break}}nd(a,32,q,b,i^8192);b=(b|0)<(q|0)?q:b;continue e}if((k|0)<0?v:0){break d}l=61;b=Ja[f|0](a,L[h+64>>3],q,k,i,b)|0;if((b|0)>=0){continue e}break c}E[h+55|0]=G[h+64>>2];k=1;j=x;i=n;break g}i=b+1|0;G[h+76>>2]=i;l=H[b+1|0];b=i;continue}}if(a){break a}if(!u){break f}b=1;while(1){a=G[(b<<2)+e>>2];if(a){Oo((b<<3)+d|0,a,c,g);o=1;b=b+1|0;if((b|0)!=10){continue}break a}break}o=1;if(b>>>0>=10){break a}while(1){if(G[(b<<2)+e>>2]){break h}b=b+1|0;if((b|0)!=10){continue}break}break a}l=28;break c}n=l-j|0;m=(k|0)>(n|0)?k:n;if((m|0)>(2147483647-p|0)){break d}l=61;k=m+p|0;b=(k|0)<(q|0)?q:k;if((w|0)<(b|0)){break c}nd(a,32,b,k,i);gd(a,r,p);nd(a,48,b,k,i^65536);nd(a,48,m,n,0);gd(a,j,n);nd(a,32,b,k,i^8192);continue}break}o=0;break a}l=61}G[48624]=l}o=-1}Fa=h+80|0;return o}function Ok(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;l=Fa-32|0;k=G[b>>2];c=G[b+8>>2];d=G[c>>2];j=G[c+12>>2];G[a+5200>>2]=0;G[a+5204>>2]=573;q=-1;c=0;a:{if((j|0)>0){while(1){e=(c<<2)+k|0;b:{if(I[e>>1]){e=G[a+5200>>2]+1|0;G[a+5200>>2]=e;G[((e<<2)+a|0)+2908>>2]=c;E[(a+c|0)+5208|0]=0;q=c;break b}F[e+2>>1]=0}c=c+1|0;if((j|0)!=(c|0)){continue}break}c=G[a+5200>>2];if((c|0)>1){break a}}while(1){c=c+1|0;G[a+5200>>2]=c;f=((c<<2)+a|0)+2908|0;e=q+1|0;i=(q|0)<2;c=i?e:0;G[f>>2]=c;f=c<<2;F[f+k>>1]=1;E[(a+c|0)+5208|0]=0;G[a+5800>>2]=G[a+5800>>2]-1;if(d){G[a+5804>>2]=G[a+5804>>2]-I[(d+f|0)+2>>1]}q=i?e:q;c=G[a+5200>>2];if((c|0)<2){continue}break}}G[b+4>>2]=q;c=c>>>1|0;while(1){i=c;h=G[((c<<2)+a|0)+2908>>2];d=c<<1;f=G[a+5200>>2];c:{if((d|0)>(f|0)){break c}g=(a+h|0)+5208|0;n=(h<<2)+k|0;e=i;while(1){d:{if((d|0)>=(f|0)){c=d;break d}c=a+2908|0;f=d|1;m=G[c+(f<<2)>>2];o=I[(m<<2)+k>>1];p=G[c+(d<<2)>>2];c=I[(p<<2)+k>>1];if(o>>>0>=c>>>0){if((c|0)!=(o|0)){c=d;break d}c=d;d=a+5208|0;if(H[d+m|0]>H[d+p|0]){break d}}c=f}f=I[n>>1];d=G[((c<<2)+a|0)+2908>>2];m=I[(d<<2)+k>>1];if(f>>>0>>0){c=e;break c}if(!((f|0)!=(m|0)|H[g|0]>H[(a+d|0)+5208|0])){c=e;break c}G[((e<<2)+a|0)+2908>>2]=d;e=c;d=c<<1;f=G[a+5200>>2];if((d|0)<=(f|0)){continue}break}}G[((c<<2)+a|0)+2908>>2]=h;c=i-1|0;if((i|0)>1){continue}break}d=G[a+5200>>2];while(1){i=j;f=d-1|0;G[a+5200>>2]=f;g=G[a+2912>>2];h=G[((d<<2)+a|0)+2908>>2];G[a+2912>>2]=h;c=1;e:{if((d|0)<3){break e}n=(a+h|0)+5208|0;d=2;m=(h<<2)+k|0;e=1;while(1){f:{if((d|0)>=(f|0)){c=d;break f}c=a+2908|0;j=d|1;f=G[c+(j<<2)>>2];o=I[(f<<2)+k>>1];p=G[c+(d<<2)>>2];c=I[(p<<2)+k>>1];if(o>>>0>=c>>>0){if((c|0)!=(o|0)){c=d;break f}c=d;d=a+5208|0;if(H[d+f|0]>H[d+p|0]){break f}}c=j}j=I[m>>1];d=G[((c<<2)+a|0)+2908>>2];f=I[(d<<2)+k>>1];if(j>>>0>>0){c=e;break e}if(!((f|0)!=(j|0)|H[n|0]>H[(a+d|0)+5208|0])){c=e;break e}G[((e<<2)+a|0)+2908>>2]=d;e=c;d=c<<1;f=G[a+5200>>2];if((d|0)<=(f|0)){continue}break}}d=2;j=a+2908|0;G[j+(c<<2)>>2]=h;e=G[a+5204>>2]-1|0;G[a+5204>>2]=e;c=G[a+2912>>2];G[j+(e<<2)>>2]=g;e=G[a+5204>>2]-1|0;G[a+5204>>2]=e;G[j+(e<<2)>>2]=c;n=(i<<2)+k|0;e=(c<<2)+k|0;f=(g<<2)+k|0;F[n>>1]=I[e>>1]+I[f>>1];h=a+5208|0;m=h+i|0;g=H[h+g|0];c=H[c+h|0];E[m|0]=(c>>>0>>0?g:c)+1;F[e+2>>1]=i;F[f+2>>1]=i;G[a+2912>>2]=i;e=1;c=1;f=G[a+5200>>2];g:{if((f|0)<2){break g}while(1){h:{if((d|0)>=(f|0)){break h}c=d|1;f=G[j+(c<<2)>>2];g=I[(f<<2)+k>>1];o=G[j+(d<<2)>>2];p=I[(o<<2)+k>>1];if(g>>>0>=p>>>0){if((g|0)!=(p|0)|H[f+h|0]>H[h+o|0]){break h}}d=c}f=I[n>>1];c=d;d=G[((c<<2)+a|0)+2908>>2];g=I[(d<<2)+k>>1];if(f>>>0>>0){c=e;break g}if(!((f|0)!=(g|0)|H[m|0]>H[(a+d|0)+5208|0])){c=e;break g}G[((e<<2)+a|0)+2908>>2]=d;e=c;d=c<<1;f=G[a+5200>>2];if((d|0)<=(f|0)){continue}break}}j=i+1|0;G[((c<<2)+a|0)+2908>>2]=i;d=G[a+5200>>2];if((d|0)>1){continue}break}c=G[a+5204>>2]-1|0;G[a+5204>>2]=c;e=a+2908|0;G[e+(c<<2)>>2]=G[a+2912>>2];f=G[b+4>>2];c=G[b+8>>2];d=G[c+16>>2];n=G[c+8>>2];p=G[c+4>>2];m=G[c>>2];i=G[b>>2];r=a+2900|0;b=r;F[b>>1]=0;F[b+2>>1]=0;F[b+4>>1]=0;F[b+6>>1]=0;s=a+2892|0;b=s;F[b>>1]=0;F[b+2>>1]=0;F[b+4>>1]=0;F[b+6>>1]=0;t=a+2884|0;b=t;F[b>>1]=0;F[b+2>>1]=0;F[b+4>>1]=0;F[b+6>>1]=0;u=a+2876|0;b=u;F[b>>1]=0;F[b+2>>1]=0;F[b+4>>1]=0;F[b+6>>1]=0;j=0;F[(i+(G[e+(G[a+5204>>2]<<2)>>2]<<2)|0)+2>>1]=0;b=G[a+5204>>2];i:{if((b|0)>571){break i}c=b+1|0;e=0;while(1){b=G[((c<<2)+a|0)+2908>>2];v=b<<2;o=i+v|0;g=I[(i+(I[o+2>>1]<<2)|0)+2>>1];h=(d|0)>(g|0)?g+1|0:d;F[o+2>>1]=h;w=(d|0)<=(g|0);j:{if((b|0)>(f|0)){break j}g=((h<<1)+a|0)+2876|0;F[g>>1]=I[g>>1]+1;g=0;g=(b|0)>=(n|0)?G[p+(b-n<<2)>>2]:g;b=I[o>>1];G[a+5800>>2]=G[a+5800>>2]+M(h+g|0,b);if(!m){break j}G[a+5804>>2]=G[a+5804>>2]+M(b,I[(m+v|0)+2>>1]+g|0)}e=e+w|0;c=c+1|0;if((c|0)!=573){continue}break}if(!e){break i}h=((d<<1)+a|0)+2876|0;while(1){c=d;while(1){b=c;c=b-1|0;g=((c<<1)+a|0)+2876|0;n=I[g>>1];if(!n){continue}break}F[g>>1]=n-1;b=((b<<1)+a|0)+2876|0;F[b>>1]=I[b>>1]+2;F[h>>1]=I[h>>1]-1;b=(e|0)>2;e=e-2|0;if(b){continue}break}if(!d){break i}c=573;while(1){e=I[((d<<1)+a|0)+2876>>1];if(e){while(1){c=c-1|0;b=G[((c<<2)+a|0)+2908>>2];if((b|0)>(f|0)){continue}b=i+(b<<2)|0;h=I[b+2>>1];if((h|0)!=(d|0)){G[a+5800>>2]=G[a+5800>>2]+M(I[b>>1],d-h|0);F[b+2>>1]=d}e=e-1|0;if(e){continue}break}}d=d-1|0;if(d){continue}break}}b=I[u>>1]<<1;F[l+2>>1]=b;b=b+I[a+2878>>1]<<1;F[l+4>>1]=b;b=b+I[a+2880>>1]<<1;F[l+6>>1]=b;b=b+I[a+2882>>1]<<1;F[l+8>>1]=b;b=b+I[t>>1]<<1;F[l+10>>1]=b;b=b+I[a+2886>>1]<<1;F[l+12>>1]=b;b=b+I[a+2888>>1]<<1;F[l+14>>1]=b;b=b+I[a+2890>>1]<<1;F[l+16>>1]=b;b=b+I[s>>1]<<1;F[l+18>>1]=b;b=b+I[a+2894>>1]<<1;F[l+20>>1]=b;b=b+I[a+2896>>1]<<1;F[l+22>>1]=b;b=b+I[a+2898>>1]<<1;F[l+24>>1]=b;b=b+I[r>>1]<<1;F[l+26>>1]=b;b=b+I[a+2902>>1]<<1;F[l+28>>1]=b;F[l+30>>1]=b+I[a+2904>>1]<<1;if((q|0)>=0){while(1){i=(j<<2)+k|0;a=I[i+2>>1];if(a){b=(a<<1)+l|0;c=I[b>>1];F[b>>1]=c+1;b=a&3;d=0;k:{if(a-1>>>0<3){a=0;break k}h=a&65532;a=0;e=0;while(1){f=c>>>3&1|(c>>>2&1|(c&2|(c&1|a)<<2))<<1;a=f<<1;c=c>>>4|0;e=e+4|0;if((h|0)!=(e|0)){continue}break}}if(b){while(1){f=c&1|a;a=f<<1;c=c>>>1|0;d=d+1|0;if((b|0)!=(d|0)){continue}break}}F[i>>1]=f}a=(j|0)!=(q|0);j=j+1|0;if(a){continue}break}}}function qu(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;d=Fa-196992|0;Fa=d;k=G[968816];j=G[968817];G[d+380>>2]=0;G[d+376>>2]=0;a:{if(!j|((a|0)<=0|(a|0)>=(k|0))){break a}m=j+M(a,65544)|0;if(!G[m>>2]){break a}k=ul(a,0);a=j+M(a,65544)|0;p=G[a+4>>2];r=0;b:{if(!Xc(k,30677)){break b}r=0;if(!Xc(k,30657)){break b}p=Xc(k,13234)?p:1;r=1}E[a+8|0]=0;s=a+8|0;t=le(b);g=pc(t,36383);if(g){k=d+131456|1;while(1){a=jb(g,32);c:{if(a){G[d+380>>2]=a+1;E[a|0]=0;a=G[d+380>>2];break c}G[d+380>>2]=92041;g=0;a=92041}l=vb(a,d+376|0);d:{if(l==0){break d}e=vb(G[d+376>>2],d+380|0);if(e==0){break d}cc(G[m>>2],l,e,d+368|0,d+360|0);if(g){G[d+304>>2]=g;b=d+131456|0;Ya(b,65536,64286,d+304|0);qb(s,b,65535)}e:{f:{switch(p|0){case 1:L[d+272>>3]=L[d+368>>3];L[d+280>>3]=L[d+360>>3];Ya(d+131456|0,65536,18883,d+272|0);break e;case 0:e=L[d+368>>3];g:{if(!r){Mf(d+65920|0,65535,e,3);break g}Bj(d+65920|0,65535,e,3)}b=d+384|0;Mf(b,65535,L[d+360>>3],3);G[d+292>>2]=b;G[d+288>>2]=d+65920;Ya(d+131456|0,65536,8807,d+288|0);break e;default:break f}}L[d+256>>3]=L[d+368>>3];L[d+264>>3]=L[d+360>>3];Ya(d+131456|0,65536,18883,d+256|0)}i=qb(s,d+131456|0,65535);h:{if(!Xa(g,4316)){E[d+131456|0]=44;a=G[d+380>>2];q=H[a|0];i:{if(!q){j=k;b=a;break i}j:{while(1){b=q<<24>>24;if(!((b|0)==32|b-9>>>0<5)){break j}b=a+1|0;G[d+380>>2]=b;q=H[a+1|0];a=b;if(q){continue}break}j=k;break i}j=k;b=a;if((u|0)>1){break i}while(1){b=a+1|0;G[d+380>>2]=b;E[j|0]=H[a|0];j=j+1|0;u=((q|0)==34)+u|0;q=H[a+1|0];if(!q){break i}a=b;if((u|0)<2){continue}break}}E[j|0]=0;qb(i,d+131456|0,65535);vb(b,d+376|0);break h}k:{if(Xa(g,15727)){if(Xa(g,21330)){break k}}f=vb(G[d+380>>2],d+376|0);l:{if(f==0){break l}while(1){e=vb(G[d+376>>2],d+380|0);if(e==0){break l}cc(G[m>>2],f,e,d+368|0,d+360|0);m:{n:{switch(p|0){case 1:L[d+96>>3]=L[d+368>>3];L[d+104>>3]=L[d+360>>3];Ya(d+131456|0,65536,18882,d+96|0);break m;case 0:e=L[d+368>>3];o:{if(!r){Mf(d+65920|0,65535,e,3);break o}Bj(d+65920|0,65535,e,3)}b=d+384|0;Mf(b,65535,L[d+360>>3],3);G[d+116>>2]=b;G[d+112>>2]=d+65920;Ya(d+131456|0,65536,8806,d+112|0);break m;default:break n}}L[d+80>>3]=L[d+368>>3];L[d+88>>3]=L[d+360>>3];Ya(d+131456|0,65536,18882,d+80|0)}qb(i,d+131456|0,65535);f=vb(G[d+380>>2],d+376|0);if(f!=0){continue}break}}if(Xa(g,21330)){break h}G[d+380>>2]=a;n=vb(a,d+376|0);if(n==0){break h}l=vb(G[d+376>>2],d+380|0);if(l==0){break h}f=vb(G[d+380>>2],d+376|0);if(f==0){break h}while(1){e=vb(G[d+376>>2],d+380|0);if(e==0){break h}cc(G[m>>2],n,l,d+368|0,d+360|0);cc(G[m>>2],f,e,d+352|0,d+344|0);h=h+pg(L[d+368>>3],L[d+360>>3],L[d+352>>3],L[d+344>>3]);l=e;n=f;f=vb(G[d+380>>2],d+376|0);if(f!=0){continue}break}break h}p:{q:{if(c){f=vb(G[d+380>>2],d+376|0);if(f==0){break p}n=vb(G[d+376>>2],d+380|0);if(n!=0){break q}break p}b=G[m>>2];a=G[b+3304>>2];e=L[(a?768:760)+b>>3];L[d+328>>3]=O(L[b+(a?760:768)>>3]);L[d+320>>3]=O(e);a=G[d+380>>2];if(!a|!H[a|0]){break h}while(1){e=vb(a,d+376|0);if(G[d+380>>2]==G[d+376>>2]){break h}h=e*L[(d+320|0)+((o|0)%2<<3)>>3];r:{s:{switch(p|0){case 1:L[d+144>>3]=h;Ya(d+131456|0,65536,18887,d+144|0);break r;case 0:if(h<1){L[d+160>>3]=h*3600;Ya(d+131456|0,65536,65564,d+160|0);break r}L[d+176>>3]=h;Ya(d+131456|0,65536,27743,d+176|0);break r;default:break s}}L[d+128>>3]=h;Ya(d+131456|0,65536,18887,d+128|0)}qb(i,d+131456|0,65535);a=G[d+376>>2];G[d+380>>2]=a;b=o+1|0;t:{if(!Xa(g,3720)){o=2;if((b|0)!=2){break t}break h}if(!Xa(g,22631)){if(o){break t}o=1;break h}if(!Xa(g,5777)){o=2;if((b|0)==2){break h}break t}if(Xa(g,20708)|(b|0)!=2){break t}o=2;break h}if(!a){o=b;break h}o=b;if(H[a|0]){continue}break}break h}while(1){l=vb(G[d+380>>2],d+376|0);if(l==0){break p}e=vb(G[d+376>>2],d+380|0);if(e==0){break p}cc(G[m>>2],f,n,d+368|0,d+360|0);cc(G[m>>2],l,e,d+352|0,d+344|0);h=pg(L[d+368>>3],L[d+360>>3],L[d+352>>3],L[d+344>>3]);f=vb(G[d+380>>2],d+376|0);if(f==0){break p}n=vb(G[d+376>>2],d+380|0);if(n!=0){continue}break}}u:{switch(p|0){case 1:L[d+208>>3]=h;a=d+131456|0;Ya(a,65536,18887,d+208|0);qb(i,a,65535);break h;case 0:if(h<1){L[d+224>>3]=h*3600;a=d+131456|0;Ya(a,65536,65564,d+224|0);qb(i,a,65535);break h}L[d+240>>3]=h;a=d+131456|0;Ya(a,65536,27743,d+240|0);qb(i,a,65535);break h;default:break u}}L[d+192>>3]=h;a=d+131456|0;Ya(a,65536,18887,d+192|0);qb(i,a,65535)}v:{w:{if(!Xa(g,3720)){break w}if(!Xa(g,5777)){break w}if(!Xa(g,20708)){break w}if(Xa(g,4316)){break v}}f=vb(G[d+380>>2],d+376|0);if(f==0|G[d+380>>2]==G[d+376>>2]){break v}if(f<0){while(1){f=f+6.283185307179586;if(f<0){continue}break}}L[d+64>>3]=f*57.29577951308232;a=d+131456|0;Ya(a,65536,18887,d- -64|0);qb(i,a,65535)}if(g){F[d+131456>>1]=41;qb(i,d+131456|0,65535)}if(!Xa(g,21330)){x:{y:{switch(p|0){case 1:L[d+16>>3]=h;Ya(d+131456|0,65536,1533,d+16|0);break x;case 0:if(h<1){L[d+32>>3]=h*3600;Ya(d+131456|0,65536,1750,d+32|0);break x}L[d+48>>3]=h;Ya(d+131456|0,65536,1533,d+48|0);break x;default:break y}}L[d>>3]=h;Ya(d+131456|0,65536,1533,d)}qb(i,d+131456|0,65535)}F[d+131456>>1]=59;qb(i,d+131456|0,65535)}g=pc(0,36383);if(g){continue}break}}if(!t){break a}Wa(t)}Fa=d+196992|0;return s|0}function Xi(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;j=Fa-448|0;Fa=j;e=G[c>>2];a:{if((e|0)>0){break a}l=ac(b,13287);if(l){b:{if(!vc(j+176|0,160,l)){break b}o=j+392|0;while(1){E[j+336|0]=0;b=j+176|0;p=Va(b)+j|0,q=0,E[p+175|0]=q;g=j+352|0;i=Fa-528|0;Fa=i;e=G[c>>2];c:{if((e|0)>0){break c}E[g|0]=0;G[j+12>>2]=0;d:{e:{f:{if(H[b|0]!=32){break f}if(fb(b,68289,8)){break f}qb(g,b,80);G[j+12>>2]=1;break e}E[i+304|0]=0;E[i+448|0]=0;E[i+160|0]=0;b=Me(b,68332)+b|0;if(!fb(b,48648,20)){break d}if(H[b|0]==45){G[j+12>>2]=-1;b=b+1|0;f=Me(b,68332)+b|0;b=qc(f,49016);if((b|0)>=75){break d}h=qb(g,f,b);g:{if((b|0)>8){break g}d=Va(h);if(d){e=0;while(1){k=e+h|0;g=E[k|0];E[k|0]=g-97>>>0<26?g&95:g;e=e+1|0;if((d|0)!=(e|0)){continue}break}}G[i+12>>2]=0;if((ve(h,i+12|0)|0)<=0){break g}E[h|0]=0;qb(h,f,b)}e=b+f|0;if(H[e|0]==43){b=Va(h)+h|0;E[b|0]=43;E[b+1|0]=0;break e}f=Me(e,68332)+e|0;e=H[f|0];if((e|0)==61|!e){break e}G[j+12>>2]=-2;e=qc(f,68332);if((b|0)>=41){E[h|0]=0;break d}if((e|0)>=41){E[h|0]=0;break d}b=Va(h)+h|0;g=H[68261]|H[68262]<<8|(H[68263]<<16|H[68264]<<24);d=H[68257]|H[68258]<<8|(H[68259]<<16|H[68260]<<24);E[b|0]=d;E[b+1|0]=d>>>8;E[b+2|0]=d>>>16;E[b+3|0]=d>>>24;E[b+4|0]=g;E[b+5|0]=g>>>8;E[b+6|0]=g>>>16;E[b+7|0]=g>>>24;E[b+40|0]=H[68297];g=H[68293]|H[68294]<<8|(H[68295]<<16|H[68296]<<24);d=H[68289]|H[68290]<<8|(H[68291]<<16|H[68292]<<24);E[b+32|0]=d;E[b+33|0]=d>>>8;E[b+34|0]=d>>>16;E[b+35|0]=d>>>24;E[b+36|0]=g;E[b+37|0]=g>>>8;E[b+38|0]=g>>>16;E[b+39|0]=g>>>24;g=H[68285]|H[68286]<<8|(H[68287]<<16|H[68288]<<24);d=H[68281]|H[68282]<<8|(H[68283]<<16|H[68284]<<24);E[b+24|0]=d;E[b+25|0]=d>>>8;E[b+26|0]=d>>>16;E[b+27|0]=d>>>24;E[b+28|0]=g;E[b+29|0]=g>>>8;E[b+30|0]=g>>>16;E[b+31|0]=g>>>24;g=H[68277]|H[68278]<<8|(H[68279]<<16|H[68280]<<24);d=H[68273]|H[68274]<<8|(H[68275]<<16|H[68276]<<24);E[b+16|0]=d;E[b+17|0]=d>>>8;E[b+18|0]=d>>>16;E[b+19|0]=d>>>24;E[b+20|0]=g;E[b+21|0]=g>>>8;E[b+22|0]=g>>>16;E[b+23|0]=g>>>24;g=H[68269]|H[68270]<<8|(H[68271]<<16|H[68272]<<24);d=H[68265]|H[68266]<<8|(H[68267]<<16|H[68268]<<24);E[b+8|0]=d;E[b+9|0]=d>>>8;E[b+10|0]=d>>>16;E[b+11|0]=d>>>24;E[b+12|0]=g;E[b+13|0]=g>>>8;E[b+14|0]=g>>>16;E[b+15|0]=g>>>24;b=rb(h+40|0,f,e);E[h+80|0]=0;if((e|0)>8){break e}Yf(b);G[i+12>>2]=0;if((ve(b,i+12|0)|0)<=0){break e}rb(b,f,e);break e}f=qc(b,36177);if((f|0)>=75){break d}h=qb(i+448|0,b,f);h:{if((f|0)>8){break h}k=Va(h);if(k){e=0;while(1){n=e+h|0;d=E[n|0];E[n|0]=d-97>>>0<26?d&95:d;e=e+1|0;if((k|0)!=(e|0)){continue}break}}G[i+12>>2]=0;if((ve(h,i+12|0)|0)<=0){break h}E[h|0]=0;qb(h,b,f)}d=G[h>>2];if(!(H[h|0]!=69|(d|0)!=4476485)){E[g|0]=69;E[g+1|0]=78;E[g+2|0]=68;E[g+3|0]=0;G[j+12>>2]=2;break e}e=b+f|0;i:{b=G[h>>2];f=G[h+4>>2];if(!((b|0)==1296912195&(f|0)==5525061&(d&255)==67|(b|0)==1414744392&(f|0)==5853775&(b&255)==72)){if((b&255)!=72){break i}if(nb(h,34939,9)){break i}}G[j+12>>2]=1;qb(Za(g,h),e,72);break e}b=139;j:{k:{l:{m:{n:{e=Me(e,36177)+e|0;d=H[e|0];switch(d-39|0){case 8:break k;case 1:case 2:case 3:case 4:case 5:case 6:case 7:break l;case 0:break n;default:break m}}while(1){d=qc(e+1|0,65322);f=d+2|0;if((f|0)>(b|0)){break d}qb(i+304|0,e,f);d=(e+d|0)+1|0;if(H[d|0]==39){e=d+1|0;b=b-f|0;if(H[d+1|0]!=39){break j}continue}break}e=205;G[c>>2]=205;break c}if(!d){break k}}b=qc(e,42204);if((b|0)>=140){break d}f=qb(i+304|0,e,b);d=d-70|0;o:{p:{if((d|0)!=14?d:0){break p}q:{d=H[e+1|0];switch(d-32|0){case 0:case 15:break o;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:break p;default:break q}}if(!d){break o}}m=vb(f,i+156|0);r:{s:{t:{d=H[G[i+156>>2]];switch(d-32|0){case 0:case 15:break r;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:break s;default:break t}}if(!d){break r}}d=Za(i+16|0,f);k=jb(d,68);u:{if(k){E[k|0]=69;break u}k=jb(d,100);if(k){E[k|0]=69;break u}k=jb(d,46);if(!k){break r}E[k|0]=44}m=vb(d,i+156|0)}v:{w:{x:{d=H[G[i+156>>2]];switch(d-32|0){case 0:case 15:break v;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:break w;default:break x}}if(!d){break v}}if((b|0)>=138){break d}F[f>>1]=39;f=qb(f,e,b);f=Va(f)+f|0;E[f|0]=39;E[f+1|0]=0;if(m!=0){break o}if(O(m)<2147483648){b=~~m+b|0;break o}b=b- -2147483648|0;break o}d=jb(f,101);if(d){E[d|0]=69;break o}f=jb(f,100);if(!f){break o}E[f|0]=68}e=b+e|0;break j}b=i+304|0;b=Va(b)+b|0;E[b|0]=32;E[b+1|0]=0}b=Me(e,42204)+e|0;e=Va(i+304|0);f=e-1|0;if(!(f>>>0>8|H[i+304|0]!=39)){d=f;f=i+304|0;E[d+f|0]=0;e=qb(f,68289,10-e|0)+9|0;e=Va(e)+e|0;E[e|0]=39;E[e+1|0]=0}Ob(h,i+304|0,qb(i+160|0,b,70),g,c)}e=G[c>>2];break c}e=207;G[c>>2]=207}Fa=i+528|0;if((e|0)>0){break b}b=rb(j+96|0,j+352|0,8);E[j+104|0]=0;y:{z:{switch(G[j+12>>2]+2|0){case 0:e=rb(j+16|0,o,8);E[j+24|0]=0;pl(a,b,e,c);break y;case 1:kf(a,b,c);break y;case 2:Dq(a,b,j+352|0,c);break y;case 3:break z;default:break b}}wb(a,j+352|0,c)}if(vc(j+176|0,160,l)){continue}break}}Hb(l);e=G[c>>2];break a}Ua(38301);Ua(b);e=104;G[c>>2]=104}Fa=j+448|0;return e}function Lf(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;d=Fa-2528|0;Fa=d;G[d+2484>>2]=0;e=G[321443];if(!e){e=ab(8e4);G[321442]=8e4;G[321443]=e}G[321445]=0;G[321444]=0;G[321446]=0;G[321447]=0;G[321448]=0;G[321449]=0;G[321450]=0;G[321451]=0;G[321452]=0;G[321453]=0;G[321454]=0;G[321455]=0;G[321456]=0;G[321457]=0;G[321458]=0;G[321459]=0;G[321460]=0;G[321461]=0;G[321462]=0;G[321464]=0;G[321463]=0;G[321465]=0;G[321466]=0;G[321440]=0;a:{b:{c:{d:{f=G[321438];if(f){e=ac(f,49010);G[321467]=e;if(!e){break d}e=G[321443]}E[e|0]=0;f=Rc(d+188|0,a,0,d+2484|0);e=G[321439];e:{f:{g:{h:{if(!f){if(e){yb(22598);$a(G[29763])}if((b|0)==1){break e}if((c|0)>0){if(mb(G[d+188>>2],c+1|0,0,d+2484|0)){break f}}if(Td(G[d+188>>2],d+2492|0,d+2488|0,d+2484|0)){break g}a=G[d+2492>>2];if((a|0)>=1001){n=1285772,o=ub(G[321443],M(a,80)+1024|0),G[n>>2]=o}if(G[321439]){G[d+80>>2]=G[d+2492>>2];kb(75434,d+80|0);$a(G[29763])}if(G[d+2492>>2]>0){l=d+2400|1;g=1;while(1){if(Cf(G[d+188>>2],g,d+192|0,d+2400|0,d+2320|0,d+2484|0)){break h}i:{if(H[d+2400|0]==39){a=Za(d+2240|0,l);a=(Va(a)+a|0)-1|0;if(H[a|0]!=39){break i}E[a|0]=0;break i}Za(d+2240|0,d+2400|0)}a=d+192|0;mm(a,d+2240|0);G[d+52>>2]=d+2400;G[d+48>>2]=a;a=d+1216|0;db(a,8711,d+48|0);if(nb(a,33332,7)){a=G[321443];b=Va(a);f=Va(d+1216|0);j:{if((f|0)>0){j=0;e=0;if(f-1>>>0>=3){k=f&-4;c=0;while(1){m=d+1216|0;h=m;E[a+(b+e|0)|0]=H[h+e|0];i=e|1;E[a+(b+i|0)|0]=H[h+i|0];i=e|2;E[a+(i+b|0)|0]=H[h+i|0];h=e|3;E[a+(h+b|0)|0]=H[h+m|0];e=e+4|0;c=c+4|0;if((k|0)!=(c|0)){continue}break}}c=f&3;if(c){while(1){E[a+(b+e|0)|0]=H[(d+1216|0)+e|0];e=e+1|0;j=j+1|0;if((c|0)!=(j|0)){continue}break}}if((f|0)>79){break j}}cb(a+(b+f|0)|0,32,80-f|0)}E[(a+b|0)+80|0]=0}a=G[d+2492>>2]>(g|0);g=g+1|0;if(a){continue}break}}a=G[321443];a=Va(a)+a|0;E[a|0]=69;E[a+1|0]=78;E[a+2|0]=68;cb(a+3|0,32,77);E[a+80|0]=0;if(!Qb(G[d+188>>2],d+2484|0)){break b}a=G[d+2484>>2];b=d+2496|0;uc(a,b);G[d+32>>2]=a;G[d+36>>2]=b;_a(G[321435],80427,d+32|0);break a}if(e){yb(22187);$a(G[29763])}f=ac(a,13287);k:{if(!b){if(!f){break k}Hb(f);G[d+144>>2]=a;_a(G[321435],82961,d+144|0);break a}if(f){if(!vc(d+1216|0,1024,f)){break c}l:while(1){a=(Va(d+1216|0)+d|0)+1215|0;if(H[a|0]==10){E[a|0]=0}a=(Va(d+1216|0)+d|0)+1215|0;if(H[a|0]==13){E[a|0]=0}a=d+1216|0;b=Za(d+192|0,a);if((Va(a)|0)<81){g=Va(b)+b|0;while(1){a=b;e=H[a|0];if((e|0)==32){b=a+1|0;if(a>>>0>>0){continue}}break}c=a;while(1){b=e&255;if(!(!((b|0)==32|(b|0)==61)&c>>>0>>0)){b=c;while(1){e=(e&255)-32|0;if(!(e>>>0>29|!(1<>>0>=g>>>0)){e=H[b+1|0];b=b+1|0;continue}break}E[c|0]=0;e=(H[b|0]==39)+b|0;while(1){m:{n:{switch(H[e|0]-32|0){case 0:case 7:break m;default:break n}}if(e>>>0>=g>>>0){break m}e=e+1|0;continue}break}E[e|0]=0;mm(a,b);a=G[321443];b=Va(a);g=Va(d+1216|0);o:{if((g|0)>0){j=0;e=0;if(g-1>>>0>=3){l=g&-4;c=0;while(1){i=d+1216|0;E[a+(b+e|0)|0]=H[i+e|0];h=e|1;E[a+(h+b|0)|0]=H[h+i|0];h=e|2;E[a+(h+b|0)|0]=H[h+i|0];k=e|3;E[a+(k+b|0)|0]=H[k+i|0];e=e+4|0;c=c+4|0;if((l|0)!=(c|0)){continue}break}}c=g&3;if(c){while(1){E[a+(b+e|0)|0]=H[(d+1216|0)+e|0];e=e+1|0;j=j+1|0;if((c|0)!=(j|0)){continue}break}}if((g|0)>79){break o}}cb(a+(b+g|0)|0,32,80-g|0)}E[(a+b|0)+80|0]=0;c=Va(a)+160|0;b=G[321442];if((c|0)>(b|0)){b=b+8e4|0;G[321442]=b;n=1285772,o=ub(a,b),G[n>>2]=o}if(vc(d+1216|0,1024,f)){continue l}break c}e=H[c+1|0];c=c+1|0;continue}}break}hb(83460,85,1,G[321435]);break a}G[d+160>>2]=a;_a(G[321435],84274,d+160|0);break a}G[d+128>>2]=a;_a(G[321435],84274,d+128|0);break a}a=G[d+2484>>2];b=d+2496|0;uc(a,b);G[d+64>>2]=a;G[d+68>>2]=b;_a(G[321435],80427,d- -64|0);break a}a=G[d+2484>>2];b=d+1216|0;uc(a,b);G[d+96>>2]=a;G[d+100>>2]=b;_a(G[321435],80427,d+96|0);break a}a=G[d+2484>>2];b=d+1216|0;uc(a,b);G[d+112>>2]=a;G[d+116>>2]=b;_a(G[321435],80427,d+112|0);break a}G[d>>2]=a;_a(G[321435],82751,d);break a}G[d+176>>2]=G[321438];_a(G[321435],83763,d+176|0);break a}Hb(f)}if(!G[321446]){hc(11884)}if(!G[321447]){hc(11917)}if(!G[321448]){hc(12114)}if(!G[321449]){hc(11982)}p:{q:{if(G[321444]){Wa(G[321443]);G[321443]=0;G[321442]=0;break q}if(!G[321450]){hc(12180)}if(!G[321451]){hc(12048)}if(!G[321452]){hc(12081)}if(!G[321453]){hc(11949)}if(!G[321460]){hc(12147)}if(!G[321461]){hc(12015)}r:{if(G[321456]|G[321457]|(G[321458]|G[321459])){break r}if(G[321454]){if(G[321455]){break r}a=12213}else{a=12272}hc(a)}if(Va(1285872)>>>0<=7){hc(6352)}if(Va(1286896)>>>0<=7){hc(6315)}e=1285872;while(1){a=H[e|0];if(!((a|0)==45|!a)){e=e+1|0;continue}break}while(1){a=e;e=a+1|0;c=H[a|0];if((c|0)==45){continue}break}e=1286896;while(1){b=H[e|0];if(!((b|0)==45|!b)){e=e+1|0;continue}break}while(1){b=e;e=b+1|0;f=H[b|0];if((f|0)==45){continue}break}if(!(f?c:0)){hc(14710)}if(Xa(a,b)){hc(17467)}s:{if(!G[321441]){break s}if((Va(a)|0)!=3){hc(14796)}if((Va(b)|0)==3){break s}hc(14758)}a=rd(G[321443]);G[321980]=a;Wg(a,0);a=G[321980];if(a){Ce(a)}a=G[321440];if((a|0)>0){break p}}Fa=d+2528|0;return}G[d+16>>2]=a;_a(G[321435],79975,d+16|0)}$a(G[321435]);Hb(G[321435]);sc(1);W()}function xg(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;g=Fa-512|0;Fa=g;a:{b:{if(!((a|0)!=1032|(c|0)!=-99)){if((mi(35455,g)|0)==269){c=xf(G[g>>2]);break b}if(!G[309737]){G[309737]=431}a=g+368|0;bb(a,136341,80);E[g+447|0]=0;Ua(a);h=-1;break a}if((a|0)!=1047){break b}if(!((c|0)!=-99&(d|0)!=-99)){if(!G[309737]){G[309737]=431}a=bb(g,136260,80);E[a+79|0]=0;Ua(a);h=-1;break a}i=1;d=Fb(260,0,d);if((d|0)>=0){break b}h=-1;break a}o=Fb(260,0,c);c:{j=G[309723];if((j|0)==G[309724]){c=G[309722];d:{if(c){G[309724]=j<<1;c=ub(c,M(j,688));break d}G[309724]=100;c=ab(34400)}if(!c){break c}G[309722]=c;j=G[309723]}G[309723]=j+1;h=-1;if((o|j)<0){break a}c=G[309712];G[g+508>>2]=c;G[g+484>>2]=G[c>>2]+1;G[g+472>>2]=0;e:{if(Kc(G[g+508>>2],34368,g+336|0,g+472|0)){G[g+472>>2]=0;if(Kc(G[g+508>>2],34889,g+336|0,g+472|0)){G[g+336>>2]=0;G[g+340>>2]=0;G[g+320>>2]=0;G[g+324>>2]=0;break e}if(!Kc(G[g+508>>2],35126,g+320|0,g+472|0)){break e}G[g+320>>2]=0;G[g+324>>2]=0;break e}G[g+320>>2]=0;G[g+324>>2]=0}f:{g:{h:{i:{j:{c=E[b|0];if((c|0)==91){c=1;while(1){k=b+c|0;n=H[k|0];if(!n){break i}if((n|0)==93){break j}c=c+1|0;continue}}if((c|0)==43){break h}if(c){break g}G[g+488>>2]=1;break f}G[g+504>>2]=c;n=0;E[k|0]=0;Pj(b+1|0,g+488|0,g+368|0,g+480|0,g+476|0,g+288|0,g+256|0,1238948);if(H[g+368|0]){Je(G[g+508>>2],G[g+476>>2],g+368|0,G[g+480>>2],1238948);G[g+488>>2]=G[G[g+508>>2]>>2]+1;break f}b=G[g+488>>2];if(b){b=b+1|0;G[g+488>>2]=b;mb(G[g+508>>2],b,g+492|0,1238948);break f}if(G[309737]){break a}wc(11017);break a}G[g+504>>2]=c;if(!G[309737]){G[309737]=431}a=g+368|0;bb(a,136179,80);E[g+447|0]=0;Ua(a);break a}b=_b(b);c=b+1|0;G[g+488>>2]=c;if((b|0)>0){mb(G[g+508>>2],c,g+492|0,1238948);break f}if(!G[309737]){G[309737]=431}a=g+368|0;bb(a,136098,80);E[g+447|0]=0;Ua(a);break a}n=1;if(ch(g+508|0,b,0,1238948)){break f}G[g+488>>2]=G[G[g+508>>2]>>2]+1}if(G[309737]){break a}k:{if(G[g+488>>2]!=1){break k}G[g+488>>2]=2;l:{if(mb(G[g+508>>2],2,g+492|0,1238948)){break l}while(1){m:{if(!G[g+492>>2]){break m}G[g+472>>2]=0;if(Fc(G[g+508>>2],35480,g+368|0,0,g+472|0)){break m}b=g+368|0;Yf(b);if(Sb(b,34885)){break l}}b=G[g+488>>2]+1|0;G[g+488>>2]=b;if(!mb(G[g+508>>2],b,g+492|0,1238948)){continue}break}}b=G[309737];if(!b){break k}if((b|0)!=107){break a}wc(21984);break a}dc(G[g+508>>2],0,e,g+500|0,1238948);dc(G[g+508>>2],0,f,g+496|0,1238948);if(G[309737]){break a}G[g+472>>2]=0;c=g+336|8;n:{o:{if(Kc(G[g+508>>2],34368,c,g+472|0)){G[g+472>>2]=0;if(Kc(G[g+508>>2],34889,c,g+472|0)){G[g+328>>2]=0;G[g+332>>2]=0;break o}c=g+320|8;if(Kc(G[g+508>>2],35126,c,g+472|0)){break o}break n}c=g+320|8}G[c>>2]=0;G[c+4>>2]=0}c=0;p:{q:{b=G[309723];if((b|0)==G[309724]){e=G[309722];r:{if(e){G[309724]=b<<1;b=ub(e,M(b,688));break r}G[309724]=100;b=ab(34400)}if(!b){break q}G[309722]=b;b=G[309723]}G[309723]=b+1;break p}G[309737]=113;b=-1}s:{if((b|0)<0){break s}k=G[309722];f=k+M(b,344)|0;e=(a|0)==1032;G[f+8>>2]=e?2:3;G[f>>2]=a;G[f+52>>2]=e?258:260;G[f+4>>2]=e?27:28;G[f+16>>2]=o;e=k+M(o,344)|0;G[f+56>>2]=G[e+56>>2];G[f+60>>2]=G[e+60>>2];G[g+504>>2]=0;if(G[e+60>>2]>0){while(1){l=c<<2;G[(l+f|0)- -64>>2]=G[(e+l|0)- -64>>2];c=c+1|0;G[g+504>>2]=c;if(G[e+60>>2]>(c|0)){continue}break}}t:{if(!i){break t}G[(k+M(b,344)|0)+20>>2]=d;if(G[e+56>>2]==G[(k+M(d,344)|0)+56>>2]){break t}wc(34245);break a}G[f+12>>2]=j;e=k+M(j,344)|0;G[e>>2]=-1e3;G[e+4>>2]=0;G[e+88>>2]=0;if(Ec(G[g+508>>2],40853,g+364|0,0,1238948)){break a}G[e+56>>2]=G[g+364>>2];c=G[g+364>>2];u:{if(!c){break u}c=ab(c<<4);G[e+88>>2]=c;if(!c){G[309737]=113;break a}l=G[g+364>>2];p=l;q=l>>31;l=g+504|0;Hf(G[g+508>>2],G[g+500>>2],1,0,1,0,p,q,0,c,l,1238948);c=G[g+364>>2];Hf(G[g+508>>2],G[g+496>>2],1,0,1,0,c,c>>31,0,G[e+88>>2]+(c<<3)|0,l,1238948);if(G[309737]){Wa(G[e+88>>2]);break a}l=k+M(j,344)|0;G[l+52>>2]=1;h=G[g+364>>2];j=h;v:{w:{while(1){c=j-1|0;G[g+504>>2]=c;if(!c){break w}k=G[e+88>>2];j=j-2|0;if(!(L[k+(j<<3)>>3]>=L[k+(c<<3)>>3])){m=L[k+(h+j<<3)>>3];j=c;if(!(m>=L[k+(c+h<<3)>>3])){continue}}break}G[l+52>>2]=0;c=1;break v}c=G[l+52>>2]!=1}if(c&i){wc(34304);h=-1;break a}m=L[g+344>>3]-L[g+336>>3]+(L[g+328>>3]-L[g+320>>3]);c=G[e+88>>2];if(!(O(m/(L[(c+(h<<4)|0)-8>>3]-L[c>>3]))>1e-12)){break u}c=0;G[g+504>>2]=0;if((h|0)<=0){break u}h=h<<1;h=(h|0)>1?h:1;j=h&3;if(h-1>>>0>=3){k=h&2147483644;h=0;while(1){i=G[e+88>>2]+(c<<3)|0;L[i>>3]=m+L[i>>3];i=c|1;G[g+504>>2]=i;i=G[e+88>>2]+(i<<3)|0;L[i>>3]=m+L[i>>3];i=c|2;G[g+504>>2]=i;i=G[e+88>>2]+(i<<3)|0;L[i>>3]=m+L[i>>3];i=c|3;G[g+504>>2]=i;i=G[e+88>>2]+(i<<3)|0;L[i>>3]=m+L[i>>3];c=c+4|0;G[g+504>>2]=c;h=h+4|0;if((k|0)!=(h|0)){continue}break}}if(!j){break u}h=0;while(1){k=G[e+88>>2]+(c<<3)|0;L[k>>3]=m+L[k>>3];c=c+1|0;G[g+504>>2]=c;h=h+1|0;if((j|0)!=(h|0)){continue}break}}c=G[309722];if(G[c+M(o,344)>>2]!=-1e3|(a|0)!=1032&G[c+M(d,344)>>2]!=-1e3){break s}Ja[G[f+4>>2]](f)}a=G[g+508>>2];x:{if(!n){mb(a,G[g+484>>2],g+492|0,1238948);break x}Qb(a,1238948)}h=b;break a}G[309737]=113;h=-1}Fa=g+512|0;return h}function Rs(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;h=G[309722];k=G[a+16>>2];q=h+M(k,344)|0;l=G[a+12>>2];o=M(l,344)+h|0;a:{if(G[o>>2]!=-1e3){i=G[o+56>>2];d=0;break a}d=G[o+88>>2]}b:{if(G[q>>2]!=-1e3){j=G[(M(k,344)+h|0)+56>>2];b=0;break b}b=G[(M(k,344)+h|0)+88>>2]}c=G[a>>2];c:{if(!(i|j)){d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{p:{q:{r:{s:{t:{u:{v:{switch(c-37|0){case 10:break h;case 0:break i;case 57:break j;case 87:break k;case 1:break l;case 5:break m;case 8:break n;case 6:break o;case 89:break u;case 2:case 3:case 4:case 7:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 65:case 66:case 67:case 68:case 69:case 70:case 71:case 72:case 73:case 74:case 75:case 76:case 77:case 78:case 79:case 80:case 81:case 82:case 83:case 84:case 85:case 86:case 88:break d;default:break v}}switch(c-278|0){case 7:break g;case 5:break p;case 4:break q;case 3:break r;case 2:break s;case 1:break t;case 0:break u;case 13:break e;case 12:break f;default:break d}}E[a+88|0]=(b|0)==(d|0);break d}E[a+88|0]=(b|0)!=(d|0);break d}E[a+88|0]=(b|0)<(d|0);break d}E[a+88|0]=(b|0)>(d|0);break d}E[a+88|0]=(b|0)>=(d|0);break d}E[a+88|0]=(b|0)<=(d|0);break d}G[a+88>>2]=b+d;break d}G[a+88>>2]=d-b;break d}G[a+88>>2]=M(b,d);break d}G[a+88>>2]=b&d;break d}G[a+88>>2]=b|d;break d}G[a+88>>2]=b^d;break d}if(b){G[a+88>>2]=(d|0)%(b|0);break d}wc(13540);break d}if(b){G[a+88>>2]=(d|0)/(b|0);break d}wc(13540);break d}m=$b(+(d|0),+(b|0));if(O(m)<2147483648){G[a+88>>2]=~~m;break d}G[a+88>>2]=-2147483648;break d}G[a+88>>2]=d;break d}G[a+88>>2]=0}G[a>>2]=-1e3;break c}e=G[a+56>>2];f=G[309727];if((c&-2)==290){Nd(a);if(G[309737]){break c}d=M(e,f);f=M(k,344)+h|0;g=G[f+84>>2];e=G[f+88>>2];w:{if(G[a>>2]!=290){if((d|0)<=0){break w}i=M(l,344)+h|0;j=G[i+84>>2];c=0;while(1){n=c<<2;b=G[n+G[i+88>>2]>>2];p=b-e|0;e=H[c+j|0]|g;G[n+G[a+88>>2]>>2]=e?0:p;E[G[a+84>>2]+c|0]=(e|0)!=0;j=G[i+84>>2];g=E[j+c|0];e=b;b=c+1|0;c=b;if((b|0)!=(d|0)){continue}break}break w}if((d|0)<=0){break w}b=M(l,344)+h|0;c=0;while(1){e=H[G[b+84>>2]+c|0]?e:G[G[b+88>>2]+(c<<2)>>2]+e|0;G[G[a+88>>2]+(c<<2)>>2]=e;E[G[a+84>>2]+c|0]=0;c=c+1|0;if((d|0)!=(c|0)){continue}break}}G[f+88>>2]=e;G[f+84>>2]=g;break c}Nd(a);if(G[309737]|!f){break c}c=M(e,f);n=M(k,344)+h|0;p=M(l,344)+h|0;r=(i|0)>1;while(1){f=f-1|0;g=0;x:{if(!e){break x}while(1){c=c-1|0;if(i){d=r?c:f;s=H[d+G[p+84>>2]|0];d=G[G[p+88>>2]+(d<<2)>>2]}if(j){b=(j|0)>1?c:f;t=H[b+G[n+84>>2]|0];b=G[G[n+88>>2]+(b<<2)>>2]}e=e-1|0;E[G[a+84>>2]+c|0]=(s|t)!=0;y:{z:{A:{B:{C:{D:{E:{F:{G:{H:{I:{J:{K:{L:{M:{N:{O:{g=G[a>>2];switch(g-37|0){case 2:case 3:case 4:case 7:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 65:case 66:case 67:case 68:case 69:case 70:case 71:case 72:case 73:case 74:case 75:case 76:case 77:case 78:case 79:case 80:case 81:case 82:case 83:case 84:case 85:case 86:case 88:break y;case 10:break A;case 0:break B;case 57:break C;case 87:break D;case 1:break E;case 5:break F;case 8:break G;case 6:break H;case 89:break N;default:break O}}switch(g-278|0){case 7:break z;case 5:break I;case 4:break J;case 3:break K;case 2:break L;case 1:break M;case 0:break N;default:break y}}E[G[a+88>>2]+c|0]=(b|0)==(d|0);break y}E[G[a+88>>2]+c|0]=(b|0)!=(d|0);break y}E[G[a+88>>2]+c|0]=(b|0)<(d|0);break y}E[G[a+88>>2]+c|0]=(b|0)>(d|0);break y}E[G[a+88>>2]+c|0]=(b|0)>=(d|0);break y}E[G[a+88>>2]+c|0]=(b|0)<=(d|0);break y}G[G[a+88>>2]+(c<<2)>>2]=b+d;break y}G[G[a+88>>2]+(c<<2)>>2]=d-b;break y}G[G[a+88>>2]+(c<<2)>>2]=M(b,d);break y}G[G[a+88>>2]+(c<<2)>>2]=b&d;break y}G[G[a+88>>2]+(c<<2)>>2]=b|d;break y}G[G[a+88>>2]+(c<<2)>>2]=b^d;break y}if(b){G[G[a+88>>2]+(c<<2)>>2]=(d|0)%(b|0);break y}G[G[a+88>>2]+(c<<2)>>2]=0;E[G[a+84>>2]+c|0]=1;break y}if(b){G[G[a+88>>2]+(c<<2)>>2]=(d|0)/(b|0);break y}G[G[a+88>>2]+(c<<2)>>2]=0;E[G[a+84>>2]+c|0]=1;break y}u=G[a+88>>2]+(c<<2)|0;m=$b(+(d|0),+(b|0));P:{if(O(m)<2147483648){g=~~m;break P}g=-2147483648}G[u>>2]=g}g=G[309737];if(!e){break x}if(!g){continue}break}}if(!f){break c}e=G[a+56>>2];if(!g){continue}break}}if(G[o>>2]>0){Wa(G[(M(l,344)+h|0)+88>>2])}if(G[q>>2]>0){Wa(G[(M(k,344)+h|0)+88>>2])}}function uk(a,b,c,d,e,f,g){var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,I=0,J=0,K=0,L=0,N=0;i=Fa-224|0;Fa=i;G[i+124>>2]=0;G[i+120>>2]=0;G[i+116>>2]=0;G[i+112>>2]=0;G[i+108>>2]=0;a:{if(G[g>>2]>0){break a}Td(a,i+220|0,i+216|0,g);if(G[g>>2]|G[i+220>>2]<(c|0)){break a}N=i+16|1;while(1){E[i+16|0]=0;h=i+128|0;Sd(a,c,h,g);l=Va(h);b:{if((l|0)<9){break b}h=8;if((l|0)!=9){j=l-8&-2;k=0;while(1){m=(i+128|0)+h|0;if((H[m|0]-127&255)>>>0<=160){E[m|0]=32}m=(i+128|0)+(h|1)|0;if((H[m|0]-127&255)>>>0<=160){E[m|0]=32}h=h+2|0;k=k+2|0;if((j|0)!=(k|0)){continue}break}}if(!(l&1)){break b}h=(i+128|0)+h|0;if((H[h|0]-127&255)>>>0>160){break b}E[h|0]=32}n=i+128|0;v=i+16|0;D=i+108|0;F=i+124|0;I=i+120|0;J=i+112|0;K=i+116|0;j=0;r=0;m=0;s=0;u=0;w=0;x=0;z=0;c:{if(G[g>>2]>0){break c}if(!(v?n:0)){G[g>>2]=115;break c}E[v|0]=0;if(!H[n|0]){E[n+8|0]=H[68297];h=H[68293]|H[68294]<<8|(H[68295]<<16|H[68296]<<24);l=H[68289]|H[68290]<<8|(H[68291]<<16|H[68292]<<24);E[n|0]=l;E[n+1|0]=l>>>8;E[n+2|0]=l>>>16;E[n+3|0]=l>>>24;E[n+4|0]=h;E[n+5|0]=h>>>8;E[n+6|0]=h>>>16;E[n+7|0]=h>>>24}d:{if((e|0)<=0){A=32;break d}r=-1;A=32;e:{while(1){L=G[(u<<3)+d>>2];t=H[L|0];if((t|0)==42){w=1;m=0;s=-1;break d}f:{g:{if(!(!x|(t|0)!=(j&255))){x=1;B=32;h=-1;k=0;l=0;s=-1;break g}x=1;k=0;B=32;s=-1;C=0;o=-1;m=0;q=0;l=0;h=-1;j=0;w=0;p=t;if(!p){break f}h:{while(1){j=E[k+n|0];l=k;h=o;i:{j:{k:{l:{m:{n:{o:{p:{q:{r:{s:{y=p&255;switch(y-63|0){case 0:break i;case 46:case 47:break k;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 44:case 45:break n;case 34:break q;case 43:break r;case 42:break s;default:break o}}j=j-48|0;if(j>>>0>=10){break p}q=j;break i}j=j-48|0;if(j>>>0>=10){break p}m=j;break i}if((j|0)==32|j-65>>>0<26){break l}}if(x){break h}break m}if((y|0)==35){break k}}if((j&255)==(y|0)){break m}break h}l=k;break j}B=j;break j}p=0;if(j-48>>>0>9){break h}while(1){t:{h=(j<<24>>24)-48|0;if(h>>>0>9){l=k;break t}p=h+M(p,10)|0;l=8;k=k+1|0;j=H[n+k|0];if((k|0)!=8){continue}}break}l=l-1|0;h=o;u:{switch(y-109|0){case 1:if(p-1>>>0>998){break h}if((f|0)==(p|0)){h=p;break i}break h;case 0:break u;default:break i}}s=p}h=o}k=l+1|0;C=C+1|0;p=H[L+C|0];if(p){x=0;o=h;if((l|0)<7){continue}}break}x=0;if(!t){k=q;l=m;j=0;break g}v:{if((l|0)>6){w=1;break v}o=k+n|0;w=1;k=q;l=m;j=t;if(H[o|0]!=32){break f}}k=q;break e}k=q;l=m;h=o;j=t;break f}w=0}u=u+1|0;if((u|0)!=(e|0)){continue}break}u=e;m=l}z=k;r=h;A=B}if(F){G[F>>2]=z}if(I){G[I>>2]=m}if(K){G[K>>2]=r}if(J){G[J>>2]=s}if(D){G[D>>2]=u}k=0;if(!w){break c}q=G[((u<<3)+d|0)+4>>2];if(!Xa(q,48737)){E[v|0]=45;E[v+1|0]=0;h=qb(v,n,8);E[h+9|0]=0;if(H[h+8|0]!=32){break c}E[h+8|0]=0;if(H[h+7|0]!=32){break c}E[h+7|0]=0;if(H[h+6|0]!=32){break c}E[h+6|0]=0;if(H[h+5|0]!=32){break c}E[h+5|0]=0;if(H[h+4|0]!=32){break c}E[h+4|0]=0;if(H[h+3|0]!=32){break c}E[h+3|0]=0;if(H[h+2|0]!=32){break c}E[h+2|0]=0;break c}if(!H[q|0]){break c}if(!Xa(q,48783)){break c}o=Za(v,n);j=H[q|0];if((j|0)==43){break c}p=z+48|0;t=m+48|0;h=0;while(1){w:{x:{y:{z:{A:{B:{l=j&255;switch(l-105|0){case 2:case 3:case 4:break x;case 5:break y;case 1:break z;case 0:break A;default:break B}}if(l){break x}if((k|0)<=7){cb(k+o|0,32,8-k|0)}break c}E[k+o|0]=p;break w}E[k+o|0]=t;break w}r=(r|0)==-1?f:r;if((r|0)<=0){break w}j=1;C:{if((r|0)<=0){break C}while(1){j=M(j,10);if(((r|0)/(j|0)|0)>0){continue}break}if(j>>>0<10){break C}while(1){l=(j>>>0)/10|0;E[k+o|0]=(((r|0)/(l|0)|0)%10|0)+48;k=k+1|0;m=j>>>0>99;j=l;if(m){continue}break}}k=k-1|0;break w}if(!((l|0)!=109|(s|0)<0)){j=1;D:{if((s|0)<=0){break D}while(1){j=M(j,10);if(((s|0)/(j|0)|0)>0){continue}break}if(j>>>0<10){break D}while(1){l=(j>>>0)/10|0;E[k+o|0]=(((s|0)/(l|0)|0)%10|0)+48;k=k+1|0;m=j>>>0>99;j=l;if(m){continue}break}}k=k-1|0;break w}m=k+o|0;if((l|0)==97){E[m|0]=A;break w}E[m|0]=j}k=k+1|0;h=h+1|0;j=H[q+h|0];continue}}E:{F:{if(G[g>>2]){break F}h=H[i+16|0];if(!h){break F}if((h|0)==45){E[i+25|0]=0;G:{if(H[i+24|0]!=32){break G}E[i+24|0]=0;if(H[i+23|0]!=32){break G}E[i+23|0]=0;if(H[i+22|0]!=32){break G}E[i+22|0]=0;if(H[i+21|0]!=32){break G}E[i+21|0]=0;if(H[i+20|0]!=32){break G}E[i+20|0]=0;if(H[i+19|0]!=32){break G}E[i+19|0]=0;if(H[i+18|0]!=32){break G}E[i+18|0]=0}tb(6,0);kf(b,N,g);H:{if(G[g>>2]){break H}Td(a,i+12|0,i+216|0,g);h=G[i+12>>2];if((h|0)==G[i+220>>2]){break H}G[i+220>>2]=h;c=c-1|0}l=c;G[g>>2]=0;h=G[50359];if((h|0)<=0){break E}while(1){I:{c=h-1|0;k=G[(c<<2)+199296>>2];j=H[k|0];E[k|0]=0;if((j|0)==27){break I}k=h>>>0>1;h=c;if(k){continue}}break}G[50359]=c;break E}wb(b,i+16|0,g)}l=c}E[i+24|0]=0;E[i+136|0]=0;if(G[g>>2]){break a}c=l+1|0;if(G[i+220>>2]>(l|0)){continue}break}}Fa=i+224|0}function wk(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,H=0,I=0,J=0,K=0,L=0,N=0,O=0,P=0,Q=0;r=Fa-176|0;Fa=r;g=G[c>>2];a:{if((g|0)>0){break a}e=G[a>>2];d=G[a+4>>2];b:{c:{if((e|0)!=G[d+76>>2]){mb(a,e+1|0,0,c);break c}if((G[d+128>>2]&G[d+132>>2])!=-1){break c}if((Rb(a,c)|0)>0){break b}}f=G[a+4>>2];i=G[f+80>>2];if(!i){Ua(59312);g=235;G[c>>2]=235;break a}d:{if((b|0)>0){d=G[f+936>>2];if((d|0)>=(b|0)){break d}}g=302;G[c>>2]=302;break a}e=G[f+968>>2];j=e+M(b-1|0,160)|0;m=G[j+72>>2];u=G[j+76>>2];e:{if((i|0)==1){i=G[j+152>>2];n=i>>31;if((b|0)<(d|0)){d=G[(e+M(b,160)|0)+72>>2];j=i+m|0;e=i+((d-j|0)>0)|0;d=n;d=e>>>0>>0?d+1|0:d;i=e;n=d;break e}if(b>>>0<2){break e}d=j-160|0;j=G[d+152>>2];e=G[d+72>>2]+j|0;if((m-e|0)<=0){break e}d=m;m=d-1|0;u=u-!d|0;d=n;e=i+1|0;d=e?d:d+1|0;i=e;n=d;break e}if((b|0)<(d|0)){d=e+M(b,160)|0;e=G[d+72>>2];i=e-m|0;n=G[d+76>>2]-((e>>>0>>0)+u|0)|0;break e}d=G[f+960>>2];i=d-m|0;n=G[f+964>>2]-((d>>>0>>0)+u|0)|0}d=f;I=G[d+984>>2];J=G[d+988>>2];E=G[d+976>>2];K=G[d+980>>2];j=G[d+960>>2];v=G[d+964>>2];e=G[d+956>>2];q=e;o=Fa-1e4|0;Fa=o;s=G[d+952>>2];if(!(!(e|s)|G[c>>2]>0)){f:{k=v-((i>>>0>j>>>0)+n|0)|0;t=j-i|0;if((k|0)<=0&t>>>0<=1e4|(k|0)<0){d=u;e=m+1|0;d=e?d:d+1|0;p=e;e=i+e|0;g=d;d=n+d|0;w=e;l=e>>>0>>0?d+1|0:d;if((q|0)>=0&s>>>0>=2|(q|0)>0){h=1;e=0;while(1){ee(a,h,e,w,l,t,k,o,c);d=G[a+4>>2];G[d+960>>2]=t;G[d+964>>2]=k;ld(a,h,e,p,g,t,k,o,c);d=G[a+4>>2];G[d+960>>2]=j;G[d+964>>2]=v;d=e;e=h+1|0;d=e?d:d+1|0;h=e;e=d;if((s|0)!=(h|0)|(q|0)!=(d|0)){continue}break}}f=n+u|0;d=i+m|0;f=d>>>0>>0?f+1|0:f;y=d;d=j;e=v-((y>>>0>d>>>0)+f|0)|0;f=d-y|0;d=e;if(!f&(d|0)<=0|(d|0)<0){break f}ee(a,s,q,w,l,f,d,o,c);e=G[a+4>>2];G[e+960>>2]=t;G[e+964>>2]=k;ld(a,s,q,p,g,f,d,o,c);d=G[a+4>>2];G[d+960>>2]=j;G[d+964>>2]=v;break f}d=k;e=t+9999|0;d=e>>>0<9999?d+1|0:d;F=Du(e,d,1e4,0);H=Ia;if((q|0)>=0&s>>>0>=2|(q|0)>0){f=Au(F,H,-1e4,-1);e=f+t|0;d=Ia+k|0;d=e>>>0>>0?d+1|0:d;e=e+1e4|0;d=e>>>0<1e4?d+1|0:d;A=e;l=d;e=d;d=u;f=m+1|0;d=f?d:d+1|0;B=f;g=f;f=f+A|0;C=d;d=d+e|0;L=f;w=f>>>0>>0?d+1|0:d;f=n+C|0;d=i+g|0;f=d>>>0>>0?f+1|0:f;N=d;g=d;e=d+A|0;O=f;d=f+l|0;P=e;y=e>>>0>>0?d+1|0:d;Q=!k&t>>>0<10001;x=1;g=0;while(1){ee(a,x,g,N,O,A,l,o,c);d=G[a+4>>2];G[d+960>>2]=t;G[d+964>>2]=k;ld(a,x,g,B,C,A,l,o,c);d=G[a+4>>2];G[d+960>>2]=j;G[d+964>>2]=v;D=1;p=0;h=P;e=y;z=L;f=w;if(!Q){while(1){ee(a,x,g,h,e,1e4,0,o,c);d=G[a+4>>2];G[d+960>>2]=t;G[d+964>>2]=k;ld(a,x,g,z,f,1e4,0,o,c);d=G[a+4>>2];G[d+960>>2]=j;G[d+964>>2]=v;d=e;e=h+1e4|0;d=e>>>0<1e4?d+1|0:d;h=e;e=d;d=f;f=z+1e4|0;d=f>>>0<1e4?d+1|0:d;z=f;f=d;d=p;p=D+1|0;d=p?d:d+1|0;D=p;p=d;if((F|0)!=(D|0)|(H|0)!=(d|0)){continue}break}}e=g;d=x+1|0;e=d?e:e+1|0;x=d;g=e;if((s|0)!=(d|0)|(q|0)!=(e|0)){continue}break}}f=n+u|0;d=i+m|0;f=d>>>0>>0?f+1|0:f;e=d;d=j;g=v-((e>>>0>d>>>0)+f|0)|0;l=d-e|0;if(!l&(g|0)<=0|(g|0)<0){break f}e=u;d=m+1|0;e=d?e:e+1|0;y=d;f=i+d|0;d=e+n|0;p=f;d=f>>>0>>0?d+1|0:d;w=d;d=g;h=l+9999|0;d=h>>>0<9999?d+1|0:d;B=Du(h,d,1e4,0);d=Ia;C=d;h=Au(B,d,-1e4,-1);f=h+l|0;d=Ia+g|0;d=f>>>0>>0?d+1|0:d;h=f+1e4|0;f=d;d=h;f=d>>>0<1e4?f+1|0:f;ee(a,s,q,p,w,d,f,o,c);h=G[a+4>>2];G[h+960>>2]=t;G[h+964>>2]=k;ld(a,s,q,y,e,d,f,o,c);h=G[a+4>>2];G[h+960>>2]=j;G[h+964>>2]=v;if(!g&l>>>0<10001){break f}e=e+f|0;g=d+y|0;e=g>>>0>>0?e+1|0:e;h=g;g=d;l=d+p|0;d=f+w|0;z=l;f=g>>>0>l>>>0?d+1|0:d;x=1;g=0;while(1){ee(a,s,q,z,f,1e4,0,o,c);d=G[a+4>>2];G[d+960>>2]=t;G[d+964>>2]=k;ld(a,s,q,h,e,1e4,0,o,c);d=G[a+4>>2];G[d+960>>2]=j;G[d+964>>2]=v;d=z+1e4|0;f=d>>>0<1e4?f+1|0:f;z=d;d=e;e=h+1e4|0;d=e>>>0<1e4?d+1|0:d;h=e;e=d;d=g;g=x+1|0;d=g?d:d+1|0;x=g;g=d;if((B|0)!=(x|0)|(C|0)!=(d|0)){continue}break}}}Fa=o+1e4|0;f=Au(i,n,s,q);d=Ia;l=d;g=d;e=J+K|0;d=E+I|0;e=d>>>0>>0?e+1|0:e;k=d+2879|0;d=e;d=Cu(k,k>>>0<2879?d+1|0:d);e=(f-d|0)+2879|0;d=g-(Ia+(d>>>0>f>>>0)|0)|0;e=Bu(e,e>>>0<2879?d+1|0:d,2880,0);g=G[a+4>>2];d=G[g+988>>2];p=G[g+984>>2];k=d;if(!!p&(d|0)>=0|(d|0)>0){d=g;w=G[d+128>>2];g=G[d+976>>2]+w|0;d=G[d+980>>2]+G[d+132>>2]|0;if((Ci(a,g,g>>>0>>0?d+1|0:d,p,k,0-f|0,0-(((f|0)!=0)+l|0)|0,c)|0)>0){break b}}g=1;if((e|0)>0){oh(a,e,c)}d=G[a+4>>2];e=G[d+976>>2];k=G[d+980>>2]-((e>>>0>>0)+l|0)|0;e=e-f|0;G[d+976>>2]=e;G[d+980>>2]=k;G[r+172>>2]=0;Ad(a,34350,e,e>>31,65398,r+172|0);e=G[a+4>>2];d=G[e+936>>2];if(!(G[e+80>>2]!=1|(d|0)<=0)){while(1){d=r+80|0;zb(34749,g,d,c);_f(a,d,r+160|0,r,c);d=G[r+160>>2];e=G[r+164>>2];if(d>>>0>m>>>0&(e|0)>=(u|0)|(e|0)>(u|0)){e=e-((d>>>0>>0)+n|0)|0;d=d-i|0;G[r+160>>2]=d;G[r+164>>2]=e;Ad(a,r+80|0,d,e,65398,c)}d=G[G[a+4>>2]+936>>2];e=(g|0)<(d|0);g=g+1|0;if(e){continue}break}}d=d-1|0;Ad(a,33837,d,d>>31,65398,c);Ad(a,41261,j-i|0,v-((i>>>0>j>>>0)+n|0)|0,65398,c);ko(a,b,G[G[a+4>>2]+936>>2],-1,c);Rb(a,c)}g=G[c>>2]}Fa=r+176|0;return g}function du(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;g=Fa-1114256|0;Fa=g;h=ab(40);G[h>>2]=0;G[g+852016>>2]=5609;j=4;l=1;a:{b:{c:{if(!d|!H[d|0]){break c}G[321387]=0;m=aa(158,d|0)|0;d=G[321387];G[321387]=0;e=-1;d:{if(!d){break d}f=G[321388];if(!f){break d}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[321387]=0;k=pc(m,92039);d=G[321387];G[321387]=0;e=-1;e:{if(!d){break e}f=G[321388];if(!f){break e}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}f:{if(!k){break f}e=0;while(1){G[321387]=0;i=rb((g+196656|0)+(e<<16)|0,k,65535);d=G[321387];G[321387]=0;k=-1;g:{if(!d){break g}f=G[321388];if(!f){break g}k=Ab(G[d>>2],h,4);if(!k){break a}_(f|0)}d=Z()|0;if((k|0)==1){break b}G[(g+852016|0)+(l<<2)>>2]=i;G[321387]=0;k=pc(0,92039);d=G[321387];G[321387]=0;i=-1;h:{if(!d){break h}f=G[321388];if(!f){break h}i=Ab(G[d>>2],h,4);if(!i){break a}_(f|0)}d=Z()|0;if((i|0)==1){break b}l=l+1|0;if(!k){break f}d=e>>>0<9;e=e+1|0;if(d){continue}break}}if(!m){break c}Wa(m)}G[(g+852016|0)+(l<<2)>>2]=25581;d=G[968813];G[968813]=d+1;G[321387]=0;G[g+32>>2]=42205;G[g+36>>2]=d;$(156,g+131120|0,65535,4292,g+32|0)|0;d=G[321387];G[321387]=0;e=-1;i:{if(!d){break i}f=G[321388];if(!f){break i}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}d=G[968813];G[968813]=d+1;e=(l<<2)+g|0;G[e+852020>>2]=g+131120;G[e+852024>>2]=13578;G[321387]=0;G[g+16>>2]=42205;G[g+20>>2]=d;$(156,g+65584|0,65535,4275,g+16|0)|0;d=G[321387];G[321387]=0;e=-1;j:{if(!d){break j}f=G[321388];if(!f){break j}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[321387]=0;G[g>>2]=42205;G[g+4>>2]=a;G[((l<<2)+g|0)+852028>>2]=g+65584;$(156,g+48|0,65535,8740,g|0)|0;d=G[321387];G[321387]=0;e=-1;k:{if(!d){break k}f=G[321388];if(!f){break k}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}a=l<<2;G[(a+g|0)+852032>>2]=g+48;a=a+(g+852016|0)|0;G[a+24>>2]=c;G[a+20>>2]=b;h=We(1285568,1,h,4);j=Z()|0;d=0}l:{while(1){if(!d){G[321387]=0;ba(171,l+7|0,g+852016|0)|0;d=G[321387];G[321387]=0;e=-1;m:{if(!d){break m}f=G[321388];if(!f){break m}e=Ab(G[d>>2],h,j);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}}G[321387]=0;a=ba(162,g+131120|0,13287)|0;d=G[321387];G[321387]=0;e=-1;n:{if(!d){break n}f=G[321388];if(!f){break n}e=Ab(G[d>>2],h,j);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}o:{if(!a){break o}G[321387]=0;b=$(163,3809712,1,65535,a|0)|0;d=G[321387];G[321387]=0;e=-1;p:{if(!d){break p}f=G[321388];if(!f){break p}e=Ab(G[d>>2],h,j);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}G[321387]=0;aa(164,a|0)|0;d=G[321387];G[321387]=0;e=-1;q:{if(!d){break q}f=G[321388];if(!f){break q}e=Ab(G[d>>2],h,j);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}E[b+3809712|0]=0;if((b|0)<=0){break o}G[321387]=0;aa(165,g+131120|0)|0;d=G[321387];G[321387]=0;e=-1;r:{if(!d){break r}f=G[321388];if(!f){break r}e=Ab(G[d>>2],h,j);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}G[321387]=0;aa(165,g+65584|0)|0;d=G[321387];G[321387]=0;e=-1;s:{if(!d){break s}f=G[321388];if(!f){break s}e=Ab(G[d>>2],h,j);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}a=3809712;break l}G[321387]=0;a=ba(172,g+65584|0,g+1114168|0)|0;d=G[321387];G[321387]=0;e=-1;t:{if(!d){break t}f=G[321388];if(!f){break t}e=Ab(G[d>>2],h,j);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}u:{v:{if((a|0)<0){break v}e=G[968814];k=G[968815];a=G[g+1114208>>2];if((k|0)<=(a|0)){if(e){Wa(e)}G[321387]=0;k=a+1|0;e=ba(173,k|0,1)|0;d=G[321387];G[321387]=0;i=-1;w:{if(!d){break w}f=G[321388];if(!f){break w}i=Ab(G[d>>2],h,j);if(!i){break a}_(f|0)}d=Z()|0;if((i|0)==1){continue}G[968814]=e;if(!e){break v}G[968815]=k}G[321387]=0;a=ba(162,g+65584|0,13287)|0;d=G[321387];G[321387]=0;i=-1;x:{if(!d){break x}f=G[321388];if(!f){break x}i=Ab(G[d>>2],h,j);if(!i){break a}_(f|0)}d=Z()|0;if((i|0)==1){continue}if(a){break u}}a=28734;break l}G[321387]=0;i=-1;b=$(163,e|0,1,k-1|0,a|0)|0;d=G[321387];G[321387]=0;y:{if(!d){break y}f=G[321388];if(!f){break y}i=Ab(G[d>>2],h,j);if(!i){break a}_(f|0)}d=Z()|0;if((i|0)==1){continue}G[321387]=0;aa(164,a|0)|0;d=G[321387];G[321387]=0;i=-1;z:{if(!d){break z}f=G[321388];if(!f){break z}i=Ab(G[d>>2],h,j);if(!i){break a}_(f|0)}d=Z()|0;if((i|0)==1){continue}E[b+e|0]=0;a=28734;if((b|0)<0){break l}G[321387]=0;aa(165,g+131120|0)|0;d=G[321387];G[321387]=0;e=-1;A:{if(!d){break A}f=G[321388];if(!f){break A}e=Ab(G[d>>2],h,j);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}G[321387]=0;aa(165,g+65584|0)|0;d=G[321387];G[321387]=0;e=-1;B:{if(!d){break B}f=G[321388];if(!f){break B}e=Ab(G[d>>2],h,j);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}break}a=G[968814]}Wa(h);Fa=g+1114256|0;return a|0}Wa(h);Ve(d,f);W()}function sn(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;f=Fa-176|0;Fa=f;p=G[a+8>>2];g=p-2|0;k=G[a+12>>2];j=G[309722];c=1;l=p-1|0;a:{if(!l){d=1;break a}e=g;i=l;while(1){b=e;n=b<<2;h=M(G[((i<<2)+a|0)+12>>2],344)+j|0;G[n+(f- -64|0)>>2]=h;e=G[h>>2];G[n+(f+32|0)>>2]=(e|0)==-1e3;d=0;if((e|0)==-1e3){G[f+n>>2]=G[h+88>>2];d=c}e=b-1|0;c=d;i=b;if(b){continue}break}}e=0;c=G[a+52>>2]-258|0;if(c>>>0<=2){e=G[(c<<2)+137092>>2]}s=M(k,344)+j|0;Nd(a);b:{if(G[309737]){break b}c:{if(!d){b=G[(M(k,344)+j|0)+60>>2];break c}c=M(k,344)+j|0;i=c;b=G[c+60>>2];if((l|0)==(b|0)){d:{if(!l){d=0;break d}d=0;b=l;e=G[(g<<2)+f>>2];e:{if((e|0)<=0){break e}h=M(k,344)+j|0;c=l;while(1){b=g;g=G[(h+(b<<2)|0)- -64>>2];if((g|0)<(e|0)){b=c;break e}d=(M(d,g)+e|0)-1|0;if(!b){break d}c=b;g=b-1|0;e=G[(g<<2)+f>>2];if((e|0)>0){continue}break}}if((b|0)<=0){break d}G[309737]=431;c=f+96|0;bb(c,135693,80);E[f+175|0]=0;Ua(c);Wa(G[a+88>>2]);break b}if(G[309727]<=0){break b}g=M(k,344)+j|0;b=0;while(1){e=b;f:{g:{h:{switch(G[a+52>>2]-261|0){default:e=d;break;case 1:break g;case 0:break h}}E[G[a+84>>2]+b|0]=H[G[g+84>>2]+e|0];i:{switch(G[a+52>>2]-258|0){case 2:L[G[a+88>>2]+(b<<3)>>3]=L[G[g+88>>2]+(d<<3)>>3];break f;case 1:G[G[a+88>>2]+(b<<2)>>2]=G[G[g+88>>2]+(d<<2)>>2];break f;case 0:break i;default:break g}}E[G[a+88>>2]+b|0]=H[G[g+88>>2]+d|0];break f}c=b<<2;E[G[c+G[a+88>>2]>>2]]=H[G[G[g+88>>2]>>2]+(b+d|0)|0];E[G[c+G[a+88>>2]>>2]+1|0]=0}d=G[i+56>>2]+d|0;b=b+1|0;if((b|0)>2];if(!((d|0)>0&(d|0)<=G[((M(k,344)+j|0)+(b<<2)|0)+60>>2])){G[309737]=431;c=f+96|0;bb(c,135693,80);E[f+175|0]=0;Ua(c);Wa(G[a+88>>2]);break b}c=G[309727];if(G[a+52>>2]-261>>>0<=1){if((c|0)<=0){break b}d=M(G[a+56>>2],d-1|0);e=M(k,344)+j|0;b=0;while(1){c=G[a+84>>2];if(c){E[b+c|0]=H[G[e+84>>2]+b|0]}c=G[a+56>>2];bb(G[G[a+88>>2]>>2]+M(c+1|0,b)|0,G[G[e+88>>2]>>2]+d|0,c);E[G[G[a+88>>2]+(b<<2)>>2]+G[a+56>>2]|0]=0;d=(G[i+56>>2]+d|0)+1|0;b=b+1|0;if((b|0)>2],d-1|0);g=M(k,344)+j|0;d=0;while(1){c=G[a+56>>2];bb(G[a+84>>2]+M(c,d)|0,G[g+84>>2]+b|0,c);c=M(G[a+56>>2],e);bb(G[a+88>>2]+M(c,d)|0,G[g+88>>2]+M(b,e)|0,c);b=G[i+56>>2]+b|0;d=d+1|0;if((d|0)>2];j:{if(G[309727]<=0){break j}q=G[f+64>>2];if(!H[G[q+84>>2]]){o=M(k,344)+j|0;b=0;while(1){h=b<<2;d=G[h+G[q+88>>2]>>2];k:{if(!((d|0)>0&G[((G[i+60>>2]<<2)+o|0)+60>>2]>=(d|0))){if(!G[309737]){G[309737]=431}c=f+96|0;bb(c,135693,80);E[f+175|0]=0;Ua(c);Wa(G[a+88>>2]);break k}c=G[a+56>>2];m=M(c,d-1|0);n=G[r+56>>2];if(G[a+52>>2]-261>>>0<=1){g=G[a+84>>2];if(g){E[b+g|0]=H[G[o+84>>2]+b|0];c=G[a+56>>2]}bb(G[G[a+88>>2]>>2]+M(c+1|0,b)|0,G[G[o+88>>2]>>2]+(m+M(n+1|0,b)|0)|0,c);E[G[h+G[a+88>>2]>>2]+G[a+56>>2]|0]=0;break k}g=m+M(b,n)|0;bb(G[a+84>>2]+M(b,c)|0,g+G[o+84>>2]|0,c);c=M(G[a+56>>2],e);bb(G[a+88>>2]+M(c,b)|0,G[o+88>>2]+M(e,g)|0,c)}b=b+1|0;if((b|0)>=G[309727]){break j}if(!H[G[q+84>>2]+b|0]){continue}break}}G[f>>2]=d;if(!G[309737]){G[309737]=431}c=f+96|0;bb(c,135612,80);E[f+175|0]=0;Ua(c);Wa(G[a+88>>2]);break b}G[f>>2]=d;break b}if(G[309727]<=0){break b}m=M(k,344)+j|0;n=(g<<2)+f|0;e=0;while(1){b=0;l:{if((p|0)<2){break l}while(1){d=b<<2;if(!G[d+(f+32|0)>>2]){c=G[d+(f- -64|0)>>2];if(H[G[c+84>>2]+e|0]){if(!G[309737]){G[309737]=431}c=f+96|0;bb(c,135612,80);E[f+175|0]=0;Ua(c);Wa(G[a+88>>2]);break l}G[d+f>>2]=G[G[c+88>>2]+(e<<2)>>2]}b=b+1|0;if((l|0)!=(b|0)){continue}break}}if(G[309737]){break b}m:{n:{o:{if(!l){i=0;break o}i=0;h=g;c=l;b=c;d=G[n>>2];p:{if((d|0)<=0){break p}while(1){b=h;h=G[(m+(b<<2)|0)- -64>>2];if((h|0)>=(d|0)){i=(M(i,h)+d|0)-1|0;if(!b){break o}c=b;h=b-1|0;d=G[(h<<2)+f>>2];if((d|0)>0){continue}break p}break}b=c}if((b|0)>0){break n}}c=M(G[r+56>>2],e)+i|0;d=e;q:{r:{switch(G[a+52>>2]-261|0){default:d=c;break;case 1:break q;case 0:break r}}E[G[a+84>>2]+e|0]=H[G[m+84>>2]+d|0];s:{switch(G[a+52>>2]-258|0){case 2:L[G[a+88>>2]+(e<<3)>>3]=L[G[m+88>>2]+(c<<3)>>3];break m;case 1:G[G[a+88>>2]+(e<<2)>>2]=G[G[m+88>>2]+(c<<2)>>2];break m;case 0:break s;default:break q}}E[G[a+88>>2]+e|0]=H[c+G[m+88>>2]|0];break m}b=e<<2;E[G[b+G[a+88>>2]>>2]]=H[G[G[m+88>>2]>>2]+(c+e|0)|0];E[G[b+G[a+88>>2]>>2]+1|0]=0;break m}G[309737]=431;c=f+96|0;bb(c,135693,80);E[f+175|0]=0;Ua(c);Wa(G[a+88>>2])}e=e+1|0;if((e|0)>2]>0){c=M(k,344)+j|0;a=G[c+88>>2];if(G[c+52>>2]-261>>>0<=1){a=G[a>>2]}Wa(a)}if((p|0)>=2){b=0;while(1){a=G[(f- -64|0)+(b<<2)>>2];if(G[a>>2]>0){Wa(G[a+88>>2])}b=b+1|0;if((l|0)!=(b|0)){continue}break}}Fa=f+176|0}function ji(){var a=0,b=0,c=0,d=0;a:{if(G[47541]){b:{d=G[310142];c:{if((d|0)<0){Ua(65667);Ua(43041);a=122;break c}a=122;if(d>>>0>30){break c}a=Rn();if(!a){break b}}Ua(53700);return a}c=G[310142];a=M(c,84)+1240576|0;d=H[142020]|H[142021]<<8|(H[142022]<<16|H[142023]<<24);E[a+16|0]=d;E[a+17|0]=d>>>8;E[a+18|0]=d>>>16;E[a+19|0]=d>>>24;d=H[142008]|H[142009]<<8|(H[142010]<<16|H[142011]<<24);b=H[142004]|H[142005]<<8|(H[142006]<<16|H[142007]<<24);E[a|0]=b;E[a+1|0]=b>>>8;E[a+2|0]=b>>>16;E[a+3|0]=b>>>24;E[a+4|0]=d;E[a+5|0]=d>>>8;E[a+6|0]=d>>>16;E[a+7|0]=d>>>24;G[a+80>>2]=38;G[a+76>>2]=39;G[a+72>>2]=40;G[a+68>>2]=41;G[a+64>>2]=42;G[a+60>>2]=43;G[a+56>>2]=44;G[a+52>>2]=45;G[a+48>>2]=46;G[a+44>>2]=47;G[a+40>>2]=48;G[a+36>>2]=49;G[a+32>>2]=50;G[a+28>>2]=51;G[a+24>>2]=52;G[a+20>>2]=53;d=H[142016]|H[142017]<<8|(H[142018]<<16|H[142019]<<24);b=H[142012]|H[142013]<<8|(H[142014]<<16|H[142015]<<24);E[a+8|0]=b;E[a+9|0]=b>>>8;E[a+10|0]=b>>>16;E[a+11|0]=b>>>24;E[a+12|0]=d;E[a+13|0]=d>>>8;E[a+14|0]=d>>>16;E[a+15|0]=d>>>24;E[a+19|0]=0;d=c+1|0;G[310142]=d;d:{e:{if((c|0)<=-2){Ua(65667);Ua(43041);a=122;break e}a=122;if(d>>>0>30){break e}a=In();if(!a){break d}}Ua(53354);return a}d=G[310142];a=M(d,84)+1240576|0;b=H[142041]|H[142042]<<8|(H[142043]<<16|H[142044]<<24);E[a+16|0]=b;E[a+17|0]=b>>>8;E[a+18|0]=b>>>16;E[a+19|0]=b>>>24;G[a+40>>2]=0;G[a+44>>2]=0;b=H[142029]|H[142030]<<8|(H[142031]<<16|H[142032]<<24);c=H[142025]|H[142026]<<8|(H[142027]<<16|H[142028]<<24);E[a|0]=c;E[a+1|0]=c>>>8;E[a+2|0]=c>>>16;E[a+3|0]=c>>>24;E[a+4|0]=b;E[a+5|0]=b>>>8;E[a+6|0]=b>>>16;E[a+7|0]=b>>>24;G[a+80>>2]=54;G[a+76>>2]=55;G[a+72>>2]=56;G[a+68>>2]=0;G[a+64>>2]=57;G[a+60>>2]=0;G[a+56>>2]=58;G[a+52>>2]=59;G[a+48>>2]=60;G[a+36>>2]=61;G[a+32>>2]=62;G[a+28>>2]=63;G[a+24>>2]=64;G[a+20>>2]=65;b=H[142037]|H[142038]<<8|(H[142039]<<16|H[142040]<<24);c=H[142033]|H[142034]<<8|(H[142035]<<16|H[142036]<<24);E[a+8|0]=c;E[a+9|0]=c>>>8;E[a+10|0]=c>>>16;E[a+11|0]=c>>>24;E[a+12|0]=b;E[a+13|0]=b>>>8;E[a+14|0]=b>>>16;E[a+15|0]=b>>>24;E[a+19|0]=0;a=d+1|0;G[310142]=a;f:{g:{if((d|0)<=-2){Ua(65667);Ua(43041);break g}if(a>>>0<31){break f}}Ua(53128);return 122}a=M(a,84)+1240576|0;b=H[142062]|H[142063]<<8|(H[142064]<<16|H[142065]<<24);E[a+16|0]=b;E[a+17|0]=b>>>8;E[a+18|0]=b>>>16;E[a+19|0]=b>>>24;b=H[142050]|H[142051]<<8|(H[142052]<<16|H[142053]<<24);c=H[142046]|H[142047]<<8|(H[142048]<<16|H[142049]<<24);E[a|0]=c;E[a+1|0]=c>>>8;E[a+2|0]=c>>>16;E[a+3|0]=c>>>24;E[a+4|0]=b;E[a+5|0]=b>>>8;E[a+6|0]=b>>>16;E[a+7|0]=b>>>24;G[a+80>>2]=54;G[a+76>>2]=55;G[a+72>>2]=56;G[a+68>>2]=0;G[a+64>>2]=57;G[a+60>>2]=0;G[a+56>>2]=66;G[a+52>>2]=59;G[a+48>>2]=0;G[a+40>>2]=0;G[a+44>>2]=0;G[a+36>>2]=61;G[a+32>>2]=62;G[a+28>>2]=63;G[a+24>>2]=64;G[a+20>>2]=0;b=H[142058]|H[142059]<<8|(H[142060]<<16|H[142061]<<24);c=H[142054]|H[142055]<<8|(H[142056]<<16|H[142057]<<24);E[a+8|0]=c;E[a+9|0]=c>>>8;E[a+10|0]=c>>>16;E[a+11|0]=c>>>24;E[a+12|0]=b;E[a+13|0]=b>>>8;E[a+14|0]=b>>>16;E[a+15|0]=b>>>24;E[a+19|0]=0;a=d+2|0;G[310142]=a;if(a>>>0>=31){Ua(53184);return 122}a=M(a,84)+1240576|0;b=H[142083]|H[142084]<<8|(H[142085]<<16|H[142086]<<24);E[a+16|0]=b;E[a+17|0]=b>>>8;E[a+18|0]=b>>>16;E[a+19|0]=b>>>24;b=H[142071]|H[142072]<<8|(H[142073]<<16|H[142074]<<24);c=H[142067]|H[142068]<<8|(H[142069]<<16|H[142070]<<24);E[a|0]=c;E[a+1|0]=c>>>8;E[a+2|0]=c>>>16;E[a+3|0]=c>>>24;E[a+4|0]=b;E[a+5|0]=b>>>8;E[a+6|0]=b>>>16;E[a+7|0]=b>>>24;G[a+80>>2]=54;G[a+76>>2]=55;G[a+72>>2]=56;G[a+68>>2]=0;G[a+64>>2]=57;G[a+60>>2]=0;G[a+56>>2]=58;G[a+52>>2]=59;G[a+48>>2]=0;G[a+44>>2]=67;G[a+40>>2]=68;G[a+36>>2]=61;G[a+32>>2]=62;G[a+28>>2]=63;G[a+24>>2]=64;G[a+20>>2]=0;b=H[142079]|H[142080]<<8|(H[142081]<<16|H[142082]<<24);c=H[142075]|H[142076]<<8|(H[142077]<<16|H[142078]<<24);E[a+8|0]=c;E[a+9|0]=c>>>8;E[a+10|0]=c>>>16;E[a+11|0]=c>>>24;E[a+12|0]=b;E[a+13|0]=b>>>8;E[a+14|0]=b>>>16;E[a+15|0]=b>>>24;E[a+19|0]=0;G[310142]=d+3;a=$e(42180,64,63,62,61,67,0,45,44,43,42,41,40,39,38);if(a){Ua(53642);break a}a=$e(41976,64,63,62,61,0,60,59,69,0,57,0,56,55,54);if(a){Ua(53016);break a}a=$e(42090,64,63,62,61,70,0,59,58,0,57,0,56,55,54);if(a){Ua(53298);break a}a=$e(42111,64,63,62,61,71,0,59,58,0,57,0,56,55,54);if(a){Ua(53461);break a}a=$e(42013,64,63,62,61,72,0,59,58,0,57,0,56,55,54);if(a){Ua(53071);break a}a=$e(42066,64,63,62,61,73,0,59,58,0,57,0,56,55,54);if(a){Ua(53238);break a}a=$e(42141,52,51,50,49,74,46,45,44,43,42,41,40,39,38);if(a){Ua(53581);break a}a=$e(42122,64,63,62,61,0,75,59,76,43,57,0,56,55,54);if(a){Ua(53517);break a}a=$e(42101,0,0,0,0,77,78,0,79,0,80,81,82,83,84);if(a){Ua(53406);break a}G[47541]=0}return 0}return a}function hm(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;d=Fa-384|0;Fa=d;G[d+140>>2]=0;G[d+304>>2]=H[41295]|H[41296]<<8|(H[41297]<<16|H[41298]<<24);f=H[41298]|H[41299]<<8|(H[41300]<<16|H[41301]<<24);E[d+307|0]=f;E[d+308|0]=f>>>8;E[d+309|0]=f>>>16;E[d+310|0]=f>>>24;i=d+224|0;g=Fa-96|0;Fa=g;e=Za(g+6|0,d+304|0);f=Va(e);if((f|0)<=7){while(1){h=Va(e)+e|0;E[h|0]=32;E[h+1|0]=0;f=f+1|0;if((f|0)!=8){continue}break}}f=Va(e)+e|0;E[f|0]=61;E[f+1|0]=0;f=1;e=Sb(a,e);a:{if(!e){break a}e=jb(e,61);if(!e){break a}while(1){f=H[e+1|0];e=e+1|0;if((f|0)==32){continue}break}f=1;h=qc(e,68332);if((h|0)>79){break a}f=0;e=rb(g+16|0,e,h);E[e+h|0]=0;Za(i,e)}Fa=g+96|0;b:{c:{if(f){G[d+128>>2]=d+304;_a(G[24367],76211,d+128|0);break c}if((Va(d+224|0)|0)==8){break b}f=rb(d+144|0,d+224|9,4);E[f+4|0]=0;c=-1;if(nb(f,34221,5)){break b}G[d+304>>2]=1380933441;G[d+308>>2]=5391684;if(Vh(a,d+140|0,d+304|0)){G[d+112>>2]=d+304;_a(G[24367],76211,d+112|0)}g=G[d+140>>2];G[b>>2]=g;c=0;d:{if((g|0)<0){break d}f=g+1|0;h=f&3;e=(g<<3)+8|0;if(g>>>0>=3){i=f&-4;f=0;while(1){cb((M(c,80)+b|0)+8|0,0,e);cb((M(c|1,80)+b|0)+8|0,0,e);cb((M(c|2,80)+b|0)+8|0,0,e);cb((M(c|3,80)+b|0)+8|0,0,e);c=c+4|0;f=f+4|0;if((i|0)!=(f|0)){continue}break}}if(h){f=0;while(1){cb((M(c,80)+b|0)+8|0,0,e);c=c+1|0;f=f+1|0;if((h|0)!=(f|0)){continue}break}}e=0;if((g|0)<0){break d}f=g+1|0;while(1){c=0;if((e|0)<=(g|0)){while(1){G[d+96>>2]=e;G[d+100>>2]=c;h=d+304|0;db(h,29871,d+96|0);og(a,((M(e,80)+b|0)+(c<<3)|0)+8|0,h);c=c+1|0;if((f|0)!=(c|0)){continue}break}}f=f-1|0;c=(e|0)!=(g|0);e=e+1|0;if(c){continue}break}}G[d+304>>2]=1380933442;G[d+308>>2]=5391684;if(Vh(a,d+140|0,d+304|0)){G[d+80>>2]=d+304;_a(G[24367],76211,d+80|0)}g=G[d+140>>2];G[b+808>>2]=g;c=0;e:{if((g|0)<0){break e}f=g+1|0;h=f&3;e=(g<<3)+8|0;if(g>>>0>=3){i=f&-4;f=0;while(1){cb((M(c,80)+b|0)+816|0,0,e);cb((M(c|1,80)+b|0)+816|0,0,e);cb((M(c|2,80)+b|0)+816|0,0,e);cb((M(c|3,80)+b|0)+816|0,0,e);c=c+4|0;f=f+4|0;if((i|0)!=(f|0)){continue}break}}if(h){f=0;while(1){cb((M(c,80)+b|0)+816|0,0,e);c=c+1|0;f=f+1|0;if((h|0)!=(f|0)){continue}break}}e=0;if((g|0)<0){break e}f=g+1|0;while(1){c=0;if((e|0)<=(g|0)){while(1){G[d+64>>2]=e;G[d+68>>2]=c;h=d+304|0;db(h,29863,d- -64|0);og(a,((M(e,80)+b|0)+(c<<3)|0)+816|0,h);c=c+1|0;if((f|0)!=(c|0)){continue}break}}f=f-1|0;c=(e|0)!=(g|0);e=e+1|0;if(c){continue}break}}E[d+312|0]=H[34117];c=H[34113]|H[34114]<<8|(H[34115]<<16|H[34116]<<24);G[d+304>>2]=H[34109]|H[34110]<<8|(H[34111]<<16|H[34112]<<24);G[d+308>>2]=c;if(Vh(a,d+140|0,d+304|0)){G[d+48>>2]=d+304;_a(G[24367],76211,d+48|0)}g=G[d+140>>2];G[b+1616>>2]=g;f:{if((g|0)<0){break f}h=g+1|0;i=h&3;e=(g<<3)+8|0;f=0;c=0;if(g>>>0>=3){j=h&-4;h=0;while(1){cb((M(c,80)+b|0)+1624|0,0,e);cb((M(c|1,80)+b|0)+1624|0,0,e);cb((M(c|2,80)+b|0)+1624|0,0,e);cb((M(c|3,80)+b|0)+1624|0,0,e);c=c+4|0;h=h+4|0;if((j|0)!=(h|0)){continue}break}}if(i){while(1){cb((M(c,80)+b|0)+1624|0,0,e);c=c+1|0;f=f+1|0;if((i|0)!=(f|0)){continue}break}}if((g|0)<0){break f}f=g+1|0;e=0;while(1){c=0;if((e|0)<=(g|0)){while(1){E[d+304|0]=0;G[d+32>>2]=e;G[d+36>>2]=c;h=d+304|0;db(h,29854,d+32|0);og(a,((M(e,80)+b|0)+(c<<3)|0)+1624|0,h);c=c+1|0;if((f|0)!=(c|0)){continue}break}}f=f-1|0;c=(e|0)!=(g|0);e=e+1|0;if(c){continue}break}}E[d+312|0]=H[34108];c=H[34104]|H[34105]<<8|(H[34106]<<16|H[34107]<<24);G[d+304>>2]=H[34100]|H[34101]<<8|(H[34102]<<16|H[34103]<<24);G[d+308>>2]=c;if(Vh(a,d+140|0,d+304|0)){G[d+16>>2]=d+304;_a(G[24367],76211,d+16|0)}g=G[d+140>>2];G[b+2424>>2]=g;g:{if((g|0)<0){break g}h=g+1|0;i=h&3;e=(g<<3)+8|0;f=0;c=0;if(g>>>0>=3){j=h&-4;h=0;while(1){cb((M(c,80)+b|0)+2432|0,0,e);cb((M(c|1,80)+b|0)+2432|0,0,e);cb((M(c|2,80)+b|0)+2432|0,0,e);cb((M(c|3,80)+b|0)+2432|0,0,e);c=c+4|0;h=h+4|0;if((j|0)!=(h|0)){continue}break}}if(i){while(1){cb((M(c,80)+b|0)+2432|0,0,e);c=c+1|0;f=f+1|0;if((i|0)!=(f|0)){continue}break}}e=0;if((g|0)<0){break g}f=g+1|0;while(1){c=0;if((e|0)<=(g|0)){while(1){G[d>>2]=e;G[d+4>>2]=c;h=d+304|0;db(h,29845,d);og(a,((M(e,80)+b|0)+(c<<3)|0)+2432|0,h);c=c+1|0;if((f|0)!=(c|0)){continue}break}}f=f-1|0;c=(e|0)!=(g|0);e=e+1|0;if(c){continue}break}}c=H[41204]|H[41205]<<8|(H[41206]<<16|H[41207]<<24);E[d+307|0]=c;E[d+308|0]=c>>>8;E[d+309|0]=c>>>16;E[d+310|0]=c>>>24;G[d+304>>2]=H[41201]|H[41202]<<8|(H[41203]<<16|H[41204]<<24);if(og(a,b+3232|0,d+304|0)){hb(86511,21,1,G[24367]);break c}c=H[40802]|H[40803]<<8|(H[40804]<<16|H[40805]<<24);E[d+307|0]=c;E[d+308|0]=c>>>8;E[d+309|0]=c>>>16;E[d+310|0]=c>>>24;G[d+304>>2]=H[40799]|H[40800]<<8|(H[40801]<<16|H[40802]<<24);c=1;if(!og(a,b+3240|0,d+304|0)){break b}hb(86511,21,1,G[24367])}c=-1}Fa=d+384|0;return c}function Iq(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;l=Fa-32|0;Fa=l;G[l+28>>2]=0;a:{i=G[b+68>>2];b:{if(i){if(G[b+76>>2]<=0){break b}o=G[b+84>>2];m=G[b+112>>2];while(1){e=(n<<4)+m|0;a=G[e+4>>2];c=G[b+20>>2];h=(o+(G[e>>2]<<2)|0)-4|0;G[h>>2]=(G[h>>2]+(G[e+12>>2]-G[e+8>>2]|0)|0)+1;h=M(c,a-1|0);c:{d:{switch(Eu(G[b+24>>2]- -64|0,29)|0){case 9:g=G[e+12>>2];f=G[e+8>>2];if((g|0)<(f|0)){break c}a=f-1|0;c=(G[b+104>>2]+(G[e>>2]<<3)|0)-8|0;d=L[c>>3];e=0;f=g-f|0;j=f+1&3;if(j){while(1){d=d+ +E[i+(a+h|0)|0];L[c>>3]=d;a=a+1|0;e=e+1|0;if((j|0)!=(e|0)){continue}break}}if(f>>>0<3){break c}while(1){e=i+(a+h|0)|0;d=d+ +E[e|0];L[c>>3]=d;d=d+ +E[e+1|0];L[c>>3]=d;d=d+ +E[e+2|0];L[c>>3]=d;d=d+ +E[e+3|0];L[c>>3]=d;a=a+4|0;if((g|0)!=(a|0)){continue}break};break c;case 10:g=G[e+12>>2];f=G[e+8>>2];if((g|0)<(f|0)){break c}a=f-1|0;e=(G[b+104>>2]+(G[e>>2]<<3)|0)-8|0;d=L[e>>3];c=0;f=g-f|0;j=f+1&3;if(j){while(1){d=d+ +F[i+(a+h<<1)>>1];a=a+1|0;c=c+1|0;if((j|0)!=(c|0)){continue}break}}if(f>>>0>=3){while(1){c=i+(a+h<<1)|0;d=d+ +F[c>>1]+ +F[c+2>>1]+ +F[c+4>>1]+ +F[c+6>>1];a=a+4|0;if((g|0)!=(a|0)){continue}break}}L[e>>3]=d;break c;case 6:g=G[e+12>>2];f=G[e+8>>2];if((g|0)<(f|0)){break c}a=f-1|0;e=(G[b+104>>2]+(G[e>>2]<<3)|0)-8|0;d=L[e>>3];c=0;f=g-f|0;j=f+1&3;if(j){while(1){d=d+ +I[i+(a+h<<1)>>1];a=a+1|0;c=c+1|0;if((j|0)!=(c|0)){continue}break}}if(f>>>0>=3){while(1){c=i+(a+h<<1)|0;d=d+ +I[c>>1]+ +I[c+2>>1]+ +I[c+4>>1]+ +I[c+6>>1];a=a+4|0;if((g|0)!=(a|0)){continue}break}}L[e>>3]=d;break c;case 12:g=G[e+12>>2];f=G[e+8>>2];if((g|0)<(f|0)){break c}a=f-1|0;e=(G[b+104>>2]+(G[e>>2]<<3)|0)-8|0;d=L[e>>3];c=0;f=g-f|0;j=f+1&3;if(j){while(1){d=d+ +G[i+(a+h<<2)>>2];a=a+1|0;c=c+1|0;if((j|0)!=(c|0)){continue}break}}if(f>>>0>=3){while(1){c=i+(a+h<<2)|0;d=d+ +G[c>>2]+ +G[c+4>>2]+ +G[c+8>>2]+ +G[c+12>>2];a=a+4|0;if((g|0)!=(a|0)){continue}break}}L[e>>3]=d;break c;case 16:g=G[e+12>>2];f=G[e+8>>2];if((g|0)<(f|0)){break c}a=f-1|0;e=(G[b+104>>2]+(G[e>>2]<<3)|0)-8|0;d=L[e>>3];c=0;f=g-f|0;j=f+1&3;if(j){while(1){p=i+(a+h<<3)|0;d=d+(+J[p>>2]+ +G[p+4>>2]*4294967296);a=a+1|0;c=c+1|0;if((j|0)!=(c|0)){continue}break}}if(f>>>0>=3){while(1){c=i+(a+h<<3)|0;d=d+(+J[c>>2]+ +G[c+4>>2]*4294967296)+(+J[c+8>>2]+ +G[c+12>>2]*4294967296)+(+J[c+16>>2]+ +G[c+20>>2]*4294967296)+(+J[c+24>>2]+ +G[c+28>>2]*4294967296);a=a+4|0;if((g|0)!=(a|0)){continue}break}}L[e>>3]=d;break c;case 4:g=G[e+12>>2];c=G[e+8>>2];if((g|0)<(c|0)){break c}a=c-1|0;e=(G[b+104>>2]+(G[e>>2]<<3)|0)-8|0;d=L[e>>3];if((g-c|0)+1&1){a=i+(a+h<<2)|0;d=d+((G[a>>2]&2147483647)>>>0>2139095040?0:+K[a>>2]);a=c}if((c|0)!=(g|0)){while(1){c=i+(a+h<<2)|0;d=d+((G[c>>2]&2147483647)>>>0>2139095040?0:+K[c>>2])+((G[c+4>>2]&2147483647)>>>0>2139095040?0:+K[c+4>>2]);a=a+2|0;if((g|0)!=(a|0)){continue}break}}L[e>>3]=d;break c;case 0:break d;default:break c}}g=G[e+12>>2];c=G[e+8>>2];if((g|0)<(c|0)){break c}a=c-1|0;e=(G[b+104>>2]+(G[e>>2]<<3)|0)-8|0;d=L[e>>3];if((g-c|0)+1&1){k=d;d=L[i+(a+h<<3)>>3];A(+d);a=v(1)|0;f=v(0)|0;a=a&2147483647;d=k+((a|0)==2146435072&(f|0)!=0|a>>>0>2146435072?0:d);L[e>>3]=d;a=c}if((c|0)==(g|0)){break c}while(1){k=d;c=i+(a+h<<3)|0;d=L[c>>3];A(+d);f=v(1)|0;j=v(0)|0;f=f&2147483647;d=k+((f|0)==2146435072&(j|0)!=0|f>>>0>2146435072?0:d);L[e>>3]=d;k=d;d=L[c+8>>3];A(+d);c=v(1)|0;f=v(0)|0;c=c&2147483647;d=k+((c|0)==2146435072&(f|0)!=0|c>>>0>2146435072?0:d);L[e>>3]=d;a=a+2|0;if((g|0)!=(a|0)){continue}break}}n=n+1|0;if((n|0)>2]){continue}break}break b}g=Xb((G[b+8>>2]-G[b+4>>2]<<3)+8|0);if(G[b+76>>2]>0){f=G[b+112>>2];i=-1;while(1){h=n<<4;c=G[(h+f|0)+4>>2];if((c|0)!=(i|0)){G[l+8>>2]=1;G[l+12>>2]=1;G[l+4>>2]=c;G[l>>2]=1;e=G[b+8>>2];cg(G[b+124>>2],82,l,e,e>>31,0,g,0,l+28|0);e=G[l+28>>2];if(e){break a}f=G[b+112>>2];i=c}h=f+h|0;c=(G[b+84>>2]+(G[h>>2]<<2)|0)-4|0;G[c>>2]=(G[c>>2]+(G[h+12>>2]-G[h+8>>2]|0)|0)+1;o=G[h+12>>2];e=G[h+8>>2];e:{if((o|0)<(e|0)){break e}c=e-1|0;h=(G[b+104>>2]+(G[h>>2]<<3)|0)-8|0;d=L[h>>3];if((o-e|0)+1&1){k=d;d=L[g+(c<<3)>>3];A(+d);c=v(1)|0;m=v(0)|0;c=c&2147483647;d=k+((c|0)==2146435072&(m|0)!=0|c>>>0>2146435072?0:d);L[h>>3]=d;c=e}if((e|0)==(o|0)){break e}while(1){k=d;e=g+(c<<3)|0;d=L[e>>3];A(+d);m=v(1)|0;j=v(0)|0;m=m&2147483647;d=k+((m|0)==2146435072&(j|0)!=0|m>>>0>2146435072?0:d);L[h>>3]=d;k=d;d=L[e+8>>3];A(+d);e=v(1)|0;m=v(0)|0;e=e&2147483647;d=k+((e|0)==2146435072&(m|0)!=0|e>>>0>2146435072?0:d);L[h>>3]=d;c=c+2|0;if((o|0)!=(c|0)){continue}break}}n=n+1|0;if((n|0)>2]){continue}break}}pb(g)}Fa=l+32|0;return}a=G[(a?a+68|0:97468)>>2];wf(a,e);$a(a);Gh();sc(e);W()}function pm(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0;d=Fa-176|0;Fa=d;G[d+172>>2]=0;E[d+128|0]=0;E[d+96|0]=0;f=E[c|0];a:{if(f){G[d+16>>2]=f;db(d- -64|0,30760,d+16|0);G[d>>2]=E[c|0];db(d+80|0,30770,d);break a}G[d+64>>2]=1230328133;G[d+68>>2]=5787470;c=H[33588]|H[33589]<<8|(H[33590]<<16|H[33591]<<24);G[d+80>>2]=H[33584]|H[33585]<<8|(H[33586]<<16|H[33587]<<24);G[d+84>>2]=c;E[d+88|0]=H[33592]}b:{if(ie(a,d- -64|0,31,d+96|0)){break b}if(!ie(a,32863,31,d+96|0)){break b}G[d+64>>2]=1230328133;G[d+68>>2]=5787470}c:{if(ie(a,d+80|0,31,d+128|0)){break c}if(!ie(a,33584,31,d+128|0)){break c}E[d+88|0]=H[33592];c=H[33588]|H[33589]<<8|(H[33590]<<16|H[33591]<<24);G[d+80>>2]=H[33584]|H[33585]<<8|(H[33586]<<16|H[33587]<<24);G[d+84>>2]=c}d:{e:{f:{switch(H[d+96|0]-66|0){case 8:f=1;c=d+96|1;h=b,i=sb(c),L[h+120>>3]=i;c=_b(c);G[d+128>>2]=3492678;G[d+172>>2]=c;break e;case 0:f=1;c=d+96|1;h=b,i=sb(c),L[h+120>>3]=i;e=sb(c);G[d+128>>2]=3427142;if(O(e)<2147483648){c=~~e;G[d+172>>2]=c;break e}c=-2147483648;G[d+172>>2]=-2147483648;break e;default:break f}}g:{h:{c=d- -64|0;if(Md(a,c,d+172|0)){break h}c=34948;if(Md(a,34948,d+172|0)){if(G[d+172>>2]){break h}G[d+172>>2]=1950;G[b+120>>2]=0;G[b+124>>2]=1084127232;f=1;break d}f=1;if(!H[d+128|0]){break g}if(!nb(d+128|0,40370,3)){G[b+120>>2]=0;G[b+124>>2]=1084127232;G[d+172>>2]=1950;break d}if(G[d+128>>2]==1397900105){G[b+120>>2]=0;G[b+124>>2]=1084178432;G[d+172>>2]=2e3;break d}if(!nb(d+128|0,40253,3)){G[b+120>>2]=0;G[b+124>>2]=1084178432;G[d+172>>2]=2e3;break d}if(!nb(d+128|0,34820,3)){G[b+120>>2]=0;G[b+124>>2]=1084178432;G[d+172>>2]=2e3;break d}if(nb(d+128|0,34809,3)){break g}G[b+120>>2]=0;G[b+124>>2]=1084178432;G[d+172>>2]=2e3;break d}ob(a,c,b+120|0);f=0}c=G[d+172>>2]}if(c){break d}G[b+120>>2]=0;G[b+124>>2]=1084178432;G[d+172>>2]=2e3;c=b+3512|0;if(fb(c,35967,2)){if(fb(c,35895,3)){break d}}G[d+128>>2]=3492678}i:{j:{c=b+128|0;if(!vg(a,33923,c)){if(vg(a,35389,c)){break j}if(ob(a,34948,c)){break j}e=L[b+120>>3];L[b+128>>3]=e;break i}g=d+32|0;ie(a,33923,32,g);if(jb(g,84)){break j}if(ob(a,33299,d+24|0)){e=L[c>>3]+L[d+24>>3]/8765.812770744;L[c>>3]=e;break i}if(!ob(a,35806,d+24|0)){break j}e=L[c>>3]+L[d+24>>3]/8765.812770744;L[c>>3]=e;break i}e=L[c>>3]}if(e==0){L[b+128>>3]=L[b+120>>3]}k:{l:{if(!H[d+128|0]){ie(a,d+80|0,31,d+128|0);if(!H[d+128|0]){break l}}a=Za(b+3848|0,d+128|0);if(!f){break k}if(!fb(a,40370,3)){G[b+120>>2]=0;G[b+124>>2]=1084127232;break k}if(!fb(a,40253,3)){G[b+120>>2]=0;G[b+124>>2]=1084178432;break k}if(!fb(a,33747,4)){G[b+120>>2]=0;G[b+124>>2]=1084178432;break k}if(fb(a,34820,3)|G[d+172>>2]){break k}G[b+120>>2]=0;G[b+124>>2]=1084178432;break k}if(G[b+3964>>2]==7){break k}if(G[d+172>>2]>=1981){E[b+3848|0]=70;E[b+3849|0]=75;E[b+3850|0]=53;E[b+3851|0]=0;break k}E[b+3848|0]=70;E[b+3849|0]=75;E[b+3850|0]=52;E[b+3851|0]=0}m:{n:{switch(H[b+3512|0]-65|0){case 6:E[b+3856|0]=H[35894];a=H[35890]|H[35891]<<8|(H[35892]<<16|H[35893]<<24);c=H[35886]|H[35887]<<8|(H[35888]<<16|H[35889]<<24);E[b+3848|0]=c;E[b+3849|0]=c>>>8;E[b+3850|0]=c>>>16;E[b+3851|0]=c>>>24;E[b+3852|0]=a;E[b+3853|0]=a>>>8;E[b+3854|0]=a>>>16;E[b+3855|0]=a>>>24;break m;case 4:E[b+3856|0]=H[35885];a=H[35881]|H[35882]<<8|(H[35883]<<16|H[35884]<<24);c=H[35877]|H[35878]<<8|(H[35879]<<16|H[35880]<<24);E[b+3848|0]=c;E[b+3849|0]=c>>>8;E[b+3850|0]=c>>>16;E[b+3851|0]=c>>>24;E[b+3852|0]=a;E[b+3853|0]=a>>>8;E[b+3854|0]=a>>>16;E[b+3855|0]=a>>>24;break m;case 18:E[b+3856|0]=H[35860];a=H[35856]|H[35857]<<8|(H[35858]<<16|H[35859]<<24);c=H[35852]|H[35853]<<8|(H[35854]<<16|H[35855]<<24);E[b+3848|0]=c;E[b+3849|0]=c>>>8;E[b+3850|0]=c>>>16;E[b+3851|0]=c>>>24;E[b+3852|0]=a;E[b+3853|0]=a>>>8;E[b+3854|0]=a>>>16;E[b+3855|0]=a>>>24;break m;case 7:E[b+3856|0]=H[34812];a=H[34808]|H[34809]<<8|(H[34810]<<16|H[34811]<<24);c=H[34804]|H[34805]<<8|(H[34806]<<16|H[34807]<<24);E[b+3848|0]=c;E[b+3849|0]=c>>>8;E[b+3850|0]=c>>>16;E[b+3851|0]=c>>>24;E[b+3852|0]=a;E[b+3853|0]=a>>>8;E[b+3854|0]=a>>>16;E[b+3855|0]=a>>>24;break m;case 0:a=b+3852|0;c=H[32686]|H[32687]<<8;E[a|0]=c;E[a+1|0]=c>>>8;a=H[32682]|H[32683]<<8|(H[32684]<<16|H[32685]<<24);E[b+3848|0]=a;E[b+3849|0]=a>>>8;E[b+3850|0]=a>>>16;E[b+3851|0]=a>>>24;break m;case 11:break n;default:break m}}a=b+3851|0;c=H[34145]|H[34146]<<8|(H[34147]<<16|H[34148]<<24);E[a|0]=c;E[a+1|0]=c>>>8;E[a+2|0]=c>>>16;E[a+3|0]=c>>>24;a=H[34142]|H[34143]<<8|(H[34144]<<16|H[34145]<<24);E[b+3848|0]=a;E[b+3849|0]=a>>>8;E[b+3850|0]=a>>>16;E[b+3851|0]=a>>>24}h=b,j=Nf(b+3848|0),G[h+3964>>2]=j;Fa=d+176|0}function ge(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=!b;a:{if(G[a+132>>2]>0){f=G[a>>2];if(G[f+44>>2]==2){e=-201342849;b:{while(1){if(!(!(e&1)|!I[((g<<2)+a|0)+148>>1])){e=0;break b}if(!(!(e&2)|!I[((g<<2|4)+a|0)+148>>1])){e=0;break b}e=e>>>2|0;g=g+2|0;if((g|0)!=32){continue}break}c:{if(I[a+200>>1]|(I[a+184>>1]|I[a+188>>1])){break c}g=32;while(1){e=g<<2;if(I[(e+a|0)+148>>1]|I[((e|4)+a|0)+148>>1]|(I[((e|8)+a|0)+148>>1]|I[((e|12)+a|0)+148>>1])){break c}e=0;g=g+4|0;if((g|0)!=256){continue}break}break b}e=1}G[f+44>>2]=e}Ok(a,a+2840|0);Ok(a,a+2852|0);e=I[a+150>>1];n=a+148|0;l=G[a+2844>>2];F[(n+(l<<2)|0)+6>>1]=65535;if((l|0)>=0){i=e?7:138;m=e?4:3;k=-1;f=0;while(1){g=e;o=f;f=f+1|0;e=I[(n+(f<<2)|0)+2>>1];j=h+1|0;d:{if(!((g|0)!=(e|0)|(j|0)>=(i|0))){h=j;break d}e:{if((m|0)>(j|0)){h=((g<<2)+a|0)+2684|0;F[h>>1]=j+I[h>>1];break e}if(g){if((g|0)!=(k|0)){h=((g<<2)+a|0)+2684|0;F[h>>1]=I[h>>1]+1}F[a+2748>>1]=I[a+2748>>1]+1;break e}if((h|0)<=9){F[a+2752>>1]=I[a+2752>>1]+1;break e}F[a+2756>>1]=I[a+2756>>1]+1}h=0;f:{if(!e){m=3;i=138;break f}i=(e|0)==(g|0);m=i?3:4;i=i?6:7}k=g}if((l|0)!=(o|0)){continue}break}}e=I[a+2442>>1];n=a+2440|0;l=G[a+2856>>2];F[(n+(l<<2)|0)+6>>1]=65535;h=0;if((l|0)>=0){i=e?7:138;m=e?4:3;k=-1;f=0;while(1){g=e;o=f;f=f+1|0;e=I[(n+(f<<2)|0)+2>>1];j=h+1|0;g:{if(!((g|0)!=(e|0)|(j|0)>=(i|0))){h=j;break g}h:{if((m|0)>(j|0)){h=((g<<2)+a|0)+2684|0;F[h>>1]=j+I[h>>1];break h}if(g){if((g|0)!=(k|0)){h=((g<<2)+a|0)+2684|0;F[h>>1]=I[h>>1]+1}F[a+2748>>1]=I[a+2748>>1]+1;break h}if((h|0)<=9){F[a+2752>>1]=I[a+2752>>1]+1;break h}F[a+2756>>1]=I[a+2756>>1]+1}h=0;i:{if(!e){m=3;i=138;break i}i=(e|0)==(g|0);m=i?3:4;i=i?6:7}k=g}if((l|0)!=(o|0)){continue}break}}Ok(a,a+2864|0);g=G[a+5800>>2];f=18;j:{if(I[a+2746>>1]){break j}f=17;if(I[a+2690>>1]){break j}f=16;if(I[a+2742>>1]){break j}f=15;if(I[a+2694>>1]){break j}f=14;if(I[a+2738>>1]){break j}f=13;if(I[a+2698>>1]){break j}f=12;if(I[a+2734>>1]){break j}f=11;if(I[a+2702>>1]){break j}f=10;if(I[a+2730>>1]){break j}f=9;if(I[a+2706>>1]){break j}f=8;if(I[a+2726>>1]){break j}f=7;if(I[a+2710>>1]){break j}f=6;if(I[a+2722>>1]){break j}f=5;if(I[a+2714>>1]){break j}f=4;if(I[a+2718>>1]){break j}f=I[a+2686>>1]?3:2}e=g+M(f,3)|0;G[a+5800>>2]=e+17;g=G[a+5804>>2]+10>>>3|0;e=e+27>>>3|0;e=e>>>0>g>>>0?g:e;break a}g=c+5|0;e=g}k:{if(!(p|e>>>0>>0)){Si(a,b,c,d);break k}b=G[a+5820>>2];if(!(G[a+136>>2]!=4&(e|0)!=(g|0))){c=d+2|0;l:{if((b|0)>=14){b=I[a+5816>>1]|c<>1]=b;e=G[a+20>>2];G[a+20>>2]=e+1;E[e+G[a+8>>2]|0]=b;b=G[a+20>>2];G[a+20>>2]=b+1;E[b+G[a+8>>2]|0]=H[a+5817|0];b=G[a+5820>>2];F[a+5816>>1]=(c&65535)>>>16-b;b=b-13|0;break l}F[a+5816>>1]=I[a+5816>>1]|c<>2]=b;mp(a,116528,117680);break k}c=d+4|0;m:{if((b|0)>=14){b=I[a+5816>>1]|c<>1]=b;e=G[a+20>>2];G[a+20>>2]=e+1;E[e+G[a+8>>2]|0]=b;b=G[a+20>>2];G[a+20>>2]=b+1;E[b+G[a+8>>2]|0]=H[a+5817|0];b=G[a+5820>>2];h=(c&65535)>>>16-b|0;b=b-13|0;break m}h=I[a+5816>>1]|c<>2]=b;k=G[a+2844>>2];c=k+65280|0;i=G[a+2856>>2];n:{if((b|0)>=12){b=c<>1]=b;e=G[a+20>>2];G[a+20>>2]=e+1;E[e+G[a+8>>2]|0]=b;b=G[a+20>>2];G[a+20>>2]=b+1;E[b+G[a+8>>2]|0]=H[a+5817|0];b=G[a+5820>>2];e=(c&65535)>>>16-b|0;g=b-11|0;break n}e=c<>2]=g;b=i+65536|0;o:{if((g|0)>=12){b=b<>1]=b;c=G[a+20>>2];G[a+20>>2]=c+1;E[c+G[a+8>>2]|0]=b;b=G[a+20>>2];G[a+20>>2]=b+1;E[b+G[a+8>>2]|0]=H[a+5817|0];b=G[a+5820>>2];h=(i&65535)>>>16-b|0;b=b-11|0;break o}h=b<>2]=b;c=f+65533|0;p:{if((b|0)>=13){b=c<>1]=b;e=G[a+20>>2];G[a+20>>2]=e+1;E[e+G[a+8>>2]|0]=b;b=G[a+20>>2];G[a+20>>2]=b+1;E[b+G[a+8>>2]|0]=H[a+5817|0];b=c&65535;c=G[a+5820>>2];b=b>>>16-c|0;e=c-12|0;break p}e=b+4|0;b=c<>2]=e;g=0;c=a+5817|0;while(1){h=I[((H[g+118144|0]<<2)+a|0)+2686>>1];b=h<>1]=b;q:{if((e|0)>=14){e=G[a+20>>2];G[a+20>>2]=e+1;E[e+G[a+8>>2]|0]=b;b=G[a+20>>2];G[a+20>>2]=b+1;E[b+G[a+8>>2]|0]=H[c|0];e=G[a+5820>>2];b=h>>>16-e|0;F[a+5816>>1]=b;e=e-13|0;break q}e=e+3|0}G[a+5820>>2]=e;h=(g|0)!=(f|0);g=g+1|0;if(h){continue}break}b=a+148|0;lp(a,b,k);c=a+2440|0;lp(a,c,i);mp(a,b,c)}np(a);if(d){b=G[a+5820>>2];r:{if((b|0)>=9){b=G[a+20>>2];G[a+20>>2]=b+1;E[b+G[a+8>>2]|0]=H[a+5816|0];b=G[a+20>>2];G[a+20>>2]=b+1;E[b+G[a+8>>2]|0]=H[a+5817|0];break r}if((b|0)<=0){break r}b=G[a+20>>2];G[a+20>>2]=b+1;E[b+G[a+8>>2]|0]=H[a+5816|0]}G[a+5820>>2]=0;F[a+5816>>1]=0}}function yf(a,b,c,d,e,f,g){var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;h=Fa-6240|0;Fa=h;j=G[g>>2];if(!j){E[h+1040|0]=0;E[h|0]=0;E[h+2080|0]=0;E[h+3120|0]=0;j=h+3120|0;p=g,q=io(a,j,g),G[p>>2]=q;l=h+2080|0;k=h+1040|0;p=g,q=dh(j,0,h+5200|0,h+4160|0,0,l,k,h,0,0,g),G[p>>2]=q;m=H[h|0];n=H[h+1040|0];o=H[h+2080|0];p=g,q=Ym(a,k,g),G[p>>2]=q;i=Za(h,k);p=g,q=se(j,l,g),G[p>>2]=q;j=Za(j,l);a:{b:{if(!Ib(k,42185)){c:{if(H[h+4160|0]){Za(j,h+4160|0);break c}E[h+2080|0]=0}a=Sb(j,42197);if(a){Za(j,Za(h+5200|0,a+3|0))}k=1;a=Sb(h+2080|0,42197);if(!a){break b}Za(h+2080|0,Za(h+5200|0,a+3|0));break b}a=n|o|m;if(!Ib(h+1040|0,42094)){if(a){Ua(58879);G[g>>2]=125;break a}E[h+2080|0]=0;k=1;break b}if(!Ib(h+1040|0,42043)){a=H[42097]|H[42098]<<8|(H[42099]<<16|H[42100]<<24);E[h+1043|0]=a;E[h+1044|0]=a>>>8;E[h+1045|0]=a>>>16;E[h+1046|0]=a>>>24;G[h+1040>>2]=H[42094]|H[42095]<<8|(H[42096]<<16|H[42097]<<24);E[i|0]=0;E[h+2080|0]=0;k=1;break b}if(!Ib(h+1040|0,42081)){E[i|0]=0;E[h+2080|0]=0;k=1;break b}if(!Ib(h+1040|0,41986)){E[i|0]=0;E[h+2080|0]=0;k=1;break b}if(!Ib(h+1040|0,42141)){Za(j,h+4160|0);Za(h+2080|0,h+5200|0);G[h+1040>>2]=1701603686;G[h+1044>>2]=3092282;G[i>>2]=1701603686;G[i+4>>2]=3092282;k=1;break b}if(!Ib(h+1040|0,42157)){Za(j,h+4160|0);G[h+1040>>2]=1701603686;G[h+1044>>2]=3092282;G[i>>2]=1886680168;G[i+4>>2]=3092282;k=1;break b}if(!Ib(h+1040|0,42169)){Za(j,h+4160|0);G[h+1040>>2]=1701603686;G[h+1044>>2]=3092282;a=H[42039]|H[42040]<<8|(H[42041]<<16|H[42042]<<24);E[i+3|0]=a;E[i+4|0]=a>>>8;E[i+5|0]=a>>>16;E[i+6|0]=a>>>24;a=H[42036]|H[42037]<<8|(H[42038]<<16|H[42039]<<24);E[i|0]=a;E[i+1|0]=a>>>8;E[i+2|0]=a>>>16;E[i+3|0]=a>>>24;k=1;break b}if(!Ib(h+1040|0,42180)){Za(j,h+4160|0);G[h+1040>>2]=1701603686;G[h+1044>>2]=3092282;E[i+8|0]=H[42065];a=H[42061]|H[42062]<<8|(H[42063]<<16|H[42064]<<24);k=H[42057]|H[42058]<<8|(H[42059]<<16|H[42060]<<24);E[i|0]=k;E[i+1|0]=k>>>8;E[i+2|0]=k>>>16;E[i+3|0]=k>>>24;E[i+4|0]=a;E[i+5|0]=a>>>8;E[i+6|0]=a>>>16;E[i+7|0]=a>>>24;k=1;break b}if(!Ib(h+1040|0,42013)){k=0;E[j|0]=0;Za(h+2080|0,h+5200|0);a=H[42097]|H[42098]<<8|(H[42099]<<16|H[42100]<<24);E[h+1043|0]=a;E[h+1044|0]=a>>>8;E[h+1045|0]=a>>>16;E[h+1046|0]=a>>>24;G[h+1040>>2]=H[42094]|H[42095]<<8|(H[42096]<<16|H[42097]<<24);G[i>>2]=1701603686;G[i+4>>2]=3092282;break b}if(!Ib(h+1040|0,42025)){k=0;E[j|0]=0;a=H[42097]|H[42098]<<8|(H[42099]<<16|H[42100]<<24);E[h+1043|0]=a;E[h+1044|0]=a>>>8;E[h+1045|0]=a>>>16;E[h+1046|0]=a>>>24;G[h+1040>>2]=H[42094]|H[42095]<<8|(H[42096]<<16|H[42097]<<24);G[i>>2]=1886680168;G[i+4>>2]=3092282;break b}if(!Ib(h+1040|0,41994)){k=0;E[j|0]=0;a=H[42097]|H[42098]<<8|(H[42099]<<16|H[42100]<<24);E[h+1043|0]=a;E[h+1044|0]=a>>>8;E[h+1045|0]=a>>>16;E[h+1046|0]=a>>>24;G[h+1040>>2]=H[42094]|H[42095]<<8|(H[42096]<<16|H[42097]<<24);G[i>>2]=1886680168;G[i+4>>2]=3092282;break b}if(!Ib(h+1040|0,42036)){k=0;E[j|0]=0;a=H[42097]|H[42098]<<8|(H[42099]<<16|H[42100]<<24);E[h+1043|0]=a;E[h+1044|0]=a>>>8;E[h+1045|0]=a>>>16;E[h+1046|0]=a>>>24;G[h+1040>>2]=H[42094]|H[42095]<<8|(H[42096]<<16|H[42097]<<24);a=H[42039]|H[42040]<<8|(H[42041]<<16|H[42042]<<24);E[i+3|0]=a;E[i+4|0]=a>>>8;E[i+5|0]=a>>>16;E[i+6|0]=a>>>24;a=H[42036]|H[42037]<<8|(H[42038]<<16|H[42039]<<24);E[i|0]=a;E[i+1|0]=a>>>8;E[i+2|0]=a>>>16;E[i+3|0]=a>>>24;break b}if(!Ib(h+1040|0,42010)){k=0;E[j|0]=0;a=H[42097]|H[42098]<<8|(H[42099]<<16|H[42100]<<24);E[h+1043|0]=a;E[h+1044|0]=a>>>8;E[h+1045|0]=a>>>16;E[h+1046|0]=a>>>24;G[h+1040>>2]=H[42094]|H[42095]<<8|(H[42096]<<16|H[42097]<<24);a=H[42039]|H[42040]<<8|(H[42041]<<16|H[42042]<<24);E[i+3|0]=a;E[i+4|0]=a>>>8;E[i+5|0]=a>>>16;E[i+6|0]=a>>>24;a=H[42036]|H[42037]<<8|(H[42038]<<16|H[42039]<<24);E[i|0]=a;E[i+1|0]=a>>>8;E[i+2|0]=a>>>16;E[i+3|0]=a>>>24;break b}k=a?-1:0;if(!Ib(h+1040|0,42057)){G[g>>2]=125;Ua(58984);E[h+2080|0]=0;E[j|0]=0;break b}if(!Ib(h+1040|0,41976)){G[g>>2]=125;Ua(58932);E[h+2080|0]=0;E[j|0]=0;break b}if(Ib(h+1040|0,42090)){break b}G[g>>2]=125;Ua(59035);E[h+2080|0]=0;E[j|0]=0}if(G[g>>2]){break a}d:{if(!b){break d}if(!H[j|0]){E[b|0]=0;break d}a=Sb(j,42197);e:{if(!a){l=0;break e}a=a+3|0;l=a-j|0;rb(b,j,l);j=a}p=g,q=bf(j,1025-l|0,b+l|0,g),G[p>>2]=q}f:{if(!c){break f}if(!H[h+2080|0]){E[c|0]=0;break f}a=Sb(h+2080|0,42197);g:{if(!a){b=h+2080|0;j=0;break g}b=a+3|0;a=h+2080|0;j=b-a|0;rb(c,a,j)}p=g,q=bf(b,1025-j|0,c+j|0,g),G[p>>2]=q}if(d){Za(d,h+1040|0)}if(e){Za(e,i)}if(!f){break a}G[f>>2]=k}j=G[g>>2]}Fa=h+6240|0;return j}function jg(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;f=Fa-4208|0;Fa=f;Bl(f+112|0,4096);b=G[948156];a:{b:{if(a){c:{d:{d=G[947121];if((d|0)<3){break d}switch(b-6|0){case 0:case 7:break d;default:break c}}c=oj(f+112|0);if((d&-2147483647)==1){L[473562]=c;break b}e:{f:{switch(a-1|0){default:c=L[473564];i=L[473563];break e;case 0:L[473564]=c;i=L[473562];L[473563]=i;break e;case 1:break f}}m=L[473562];i=L[475688]+(m*L[475684]+c*L[475686]);L[473563]=i;c=L[475689]+(m*L[475685]+c*L[475687]);L[473564]=c}L[f+40>>3]=c;L[f+32>>3]=i;Ya(3788528,4096,19679,f+32|0);if(!H[3788528]){break b}if(!G[950330]){Lb()}a=Xb(Va(3788528)+1|0);Yb(3788528,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a);break b}g:{e=d-3|0;if(!((b|0)==7&e>>>0<2|(b|0)==8&e>>>0<2|((b|0)==9&e>>>0<2|(b|0)==11))){if(!((b|0)==10&e>>>0<2)){break g}}c=vb(f+112|0,0);L[474079]=c;a=G[948160];h:{if(!a){break h}if(!Xa(a,25125)){break h}if(Xa(a,16977)){c=c+L[474081];L[474079]=c}if(!Xa(a,16977)|!G[G[947122]+3256>>2]){break h}c=-c;L[474079]=c}L[f+48>>3]=c;Ya(3788528,4096,19682,f+48|0);if(!H[3788528]){break b}if(!G[950330]){Lb()}a=Xb(Va(3788528)+1|0);Yb(3788528,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a);break b}i:{e=(b|0)==7;j:{if((b|0)==8&(d|0)==5|(e&(d|0)==5|(d|0)==8&e)){break j}e=(b|0)==9;if(e&(d|0)==8){break j}g=(d|0)==10;if(g&(b|0)==8){break j}h=e;e=(d|0)==5;if(h&e){break j}h=e;e=(b|0)==10;if(h&e){break j}if(!(e&g)){break i}}c=vb(f+112|0,0);L[474079]=c;L[f+64>>3]=c;Ya(3788528,4096,19682,f- -64|0);Te(3788528);break b}k:{switch(b-2|0){case 0:case 2:c=vb(f+112|0,0);L[474079]=c;b=G[948160];l:{if(!b){break l}if(!Xa(b,25125)){break l}if(Xa(b,16977)){c=c+L[474081];L[474079]=c}if(!Xa(b,16977)|!G[G[947122]+3256>>2]){break l}c=-c;L[474079]=c}L[f+96>>3]=c;Ya(3792672,4096,19682,f+96|0);d=G[947121];break;default:break k}}m:{if((d&-2147483647)==1){c=vb(f+112|0,0);i=vb(f+112|0,0);c=c<0?-i:i;L[473562]=c;n:{switch(a-1|0){default:c=L[473563];a=3788504;break m;case 0:L[473563]=c;a=3788504;break m;case 1:break n}}c=c*L[475684];L[473563]=c;L[473564]=L[475687]*0;a=3788504;break m}G[947124]=0;G[947125]=0;c=vb(f+112|0,0);i=vb(f+112|0,0);c=c<0?-i:i;o:{p:{switch(a-1|0){default:c=L[473564];break o;case 1:L[473563]=L[473562]*L[475684];c=c*L[475687];break;case 0:break p}}L[473564]=c}a=3788512}L[f+80>>3]=c;Ya(3788528,4096,19682,f+80|0);Tg(L[a>>3]);Te(3788528);break b}q:{d=(b|0)!=7;a=G[947121];r:{if(!d&(a|0)==3|!d&(a|0)==4){break r}d=(b|0)==8;if(d&(a|0)==3|d&(a|0)==4){break r}d=(b|0)==9;if(d&(a|0)==3|d&(a|0)==4){break r}d=(b|0)==10;if(d&(a|0)==3|d&(a|0)==4){break r}if((b|0)!=11|(a|0)<3){break q}}c=vb(f+112|0,0);L[474079]=c;a=G[948160];s:{if(!a){break s}if(!Xa(a,25125)){break s}if(Xa(a,16977)){c=c+L[474081];L[474079]=c}if(!Xa(a,16977)|!G[G[947122]+3256>>2]){break s}c=-c;L[474079]=c}L[f>>3]=c;Ya(3788528,4096,19682,f);if(!H[3788528]){break b}if(!G[950330]){Lb()}a=Xb(Va(3788528)+1|0);Yb(3788528,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a);break b}t:{e=(b|0)==7;u:{if((b|0)==8&(a|0)==5|(e&(a|0)==5|(a|0)==8&e)){break u}d=(a|0)==10;if(d&(b|0)==8){break u}e=(b|0)==9;g=(a|0)==5;if(e&g|e&(a|0)==8){break u}a=(b|0)==10;if(a&g){break u}if(!(a&d)){break t}}c=vb(f+112|0,0);L[474079]=c;L[f+16>>3]=c;Ya(3788528,4096,19682,f+16|0);Te(3788528);break b}n=Lc(f+112|0);g=G[945070];a=G[945064];E[a|0]=H[3780260];v:{w:{k=G[945062]+(G[945063]<<2)|0;b=G[k>>2];d=G[b+4>>2];if(d+2>>>0>a>>>0){l=G[950324]+2|0;e=l+d|0;h=G[b+12>>2];j=(h+d|0)+2|0;if((l|0)>0){while(1){j=j-1|0;e=e-1|0;E[j|0]=H[e|0];b=G[k>>2];d=G[b+4>>2];if(e>>>0>d>>>0){continue}break}h=G[b+12>>2]}G[950324]=h;G[b+16>>2]=h;b=j-e|0;a=b+a|0;if(a>>>0>>0){break w}g=b+g|0}a=a-1|0;E[a|0]=100;G[945070]=g;b=H[a|0];G[945064]=a;E[3780260]=b;break v}qd(3987);W()}h=G[945071]-1|0;if((h|0)>=0){l=G[945062]+(G[945063]<<2)|0;j=G[945070];b=G[945064];a=H[3780260];e=G[950324];while(1){p=H[h+n|0];E[b|0]=a;g=G[l>>2];d=G[g+4>>2];if(d+2>>>0>b>>>0){o=e+2|0;a=o+d|0;e=G[g+12>>2];k=(e+d|0)+2|0;if((o|0)>0){while(1){k=k-1|0;a=a-1|0;E[k|0]=H[a|0];g=G[l>>2];d=G[g+4>>2];if(d>>>0>>0){continue}break}e=G[g+12>>2]}G[950324]=e;G[g+16>>2]=e;a=k-a|0;b=a+b|0;if(b>>>0>>0){break a}j=a+j|0}b=b-1|0;E[b|0]=p;G[945070]=j;a=H[b|0];G[945064]=b;E[3780260]=a;h=h-1|0;if((h|0)>=0){continue}break}}pb(n);G[947121]=G[947121]-1}Fa=f+4208|0;return}qd(3987);W()}function tc(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,Q=0,R=0;k=Fa-96|0;Fa=k;t=h;u=i&65535;m=(e^i)&-2147483648;l=e&65535;p=l;z=l;J=i>>>16&32767;K=e>>>16&32767;a:{b:{if(J-32767>>>0>4294934529&K-32767>>>0>=4294934530){break b}l=e&2147483647;j=d;if(!(!d&(l|0)==2147418112?!(b|c):l>>>0<2147418112)){o=d;m=e|32768;break a}e=i&2147483647;if(!(!h&(e|0)==2147418112?!(f|g):e>>>0<2147418112)){o=h;m=i|32768;b=f;c=g;break a}if(!(b|j|(l^2147418112|c))){if(!(f|h|(e|g))){m=2147450880;b=0;c=0;break a}m=m|2147418112;b=0;c=0;break a}if(!(f|h|(e^2147418112|g))){d=b|j;e=c|l;b=0;c=0;if(!(d|e)){m=2147450880;break a}m=m|2147418112;break a}if(!(b|j|(c|l))){b=0;c=0;break a}if(!(f|h|(e|g))){b=0;c=0;break a}if((l|0)==65535|l>>>0<65535){j=b;h=!(d|p);i=h<<6;l=P(h?b:d)+32|0;b=P(h?c:p);b=i+((b|0)==32?l:b)|0;od(k+80|0,j,c,d,p,b-15|0);s=16-b|0;d=G[k+88>>2];z=G[k+92>>2];c=G[k+84>>2];b=G[k+80>>2]}if(e>>>0>65535){break b}e=!(t|u);h=e<<6;i=P(e?f:t)+32|0;e=P(e?g:u);e=h+((e|0)==32?i:e)|0;od(k- -64|0,f,g,t,u,e-15|0);s=(s-e|0)+16|0;t=G[k+72>>2];u=G[k+76>>2];f=G[k+64>>2];g=G[k+68>>2]}e=f;j=g<<15|e>>>17;h=e<<15;e=j;p=h&-32768;q=c;A=Au(p,0,c,0);c=Ia;w=c;B=e;i=0;j=Au(e,0,b,i);e=j+A|0;h=Ia+c|0;h=e>>>0>>0?h+1|0:h;c=e;j=e;n=Au(b,i,p,i);l=0+n|0;e=Ia+e|0;e=l>>>0>>0?e+1|0:e;x=l;n=l;l=e;C=(j|0)==(e|0)&r>>>0>n>>>0|e>>>0>>0;r=d;L=Au(p,i,d,0);F=Ia;e=Au(q,i,B,i);d=e+L|0;j=Ia+F|0;n=d;d=d>>>0>>0?j+1|0:j;e=t;j=u<<15|e>>>17;y=e<<15|g>>>17;g=j;j=Au(y,0,b,i);e=j+n|0;f=Ia+d|0;H=e;f=e>>>0>>0?f+1|0:f;u=f;e=f;f=(h|0)==(w|0)&c>>>0>>0|h>>>0>>0;c=h+H|0;f=e+f|0;A=c;f=c>>>0>>0?f+1|0:f;t=f;c=f;D=z|65536;z=v;M=Au(p,i,D,v);I=Ia;h=Au(r,o,B,i);f=h+M|0;e=Ia+I|0;N=f;e=f>>>0>>0?e+1|0:e;v=e;E=g|-2147483648;w=0;g=Au(E,w,b,i);b=g+f|0;f=Ia+e|0;f=b>>>0>>0?f+1|0:f;O=b;e=Au(y,o,q,i);b=b+e|0;p=f;j=f+Ia|0;Q=b;g=b>>>0>>0?j+1|0:j;f=0;b=f+A|0;e=c+Q|0;e=b>>>0>>0?e+1|0:e;R=b;c=b;b=b+C|0;C=e;f=b>>>0>>0?e+1|0:e;c=f;s=((K+J|0)+s|0)-16383|0;j=Au(E,w,q,i);h=Ia;i=Au(D,z,B,i);e=i+j|0;f=Ia+h|0;f=e>>>0>>0?f+1|0:f;i=(f|0)==(h|0)&e>>>0>>0|f>>>0>>0;h=e;q=i;i=Au(y,o,r,o);e=i+e|0;j=Ia+f|0;j=e>>>0>>0?j+1|0:j;i=(f|0)==(j|0)&e>>>0>>0|f>>>0>j>>>0;f=q+i|0;h=0;h=f>>>0>>0?1:h;q=Au(E,w,D,z);i=q+f|0;f=Ia+h|0;f=i>>>0>>0?f+1|0:f;q=e;h=j;B=i;e=(d|0)==(u|0)&n>>>0>H>>>0|d>>>0>u>>>0;d=e+((d|0)==(F|0)&n>>>0>>0|d>>>0>>0)|0;j=0;j=d>>>0>>0?1:j;i=d;d=q+d|0;e=h+j|0;e=d>>>0>>0?e+1|0:e;n=d;i=e;e=(e|0)==(h|0)&d>>>0>>0|e>>>0>>0;d=B+e|0;h=d>>>0>>0?f+1|0:f;q=d;j=Au(y,o,D,z);e=Ia;r=Au(E,w,r,o);d=r+j|0;f=Ia+e|0;f=d>>>0>>0?f+1|0:f;r=d;d=f;f=(e|0)==(f|0)&j>>>0>r>>>0|e>>>0>f>>>0;y=d+q|0;e=f+h|0;e=d>>>0>y>>>0?e+1|0:e;h=0;d=h+n|0;f=i+r|0;f=d>>>0>>0?f+1|0:f;h=f;j=(i|0)==(f|0)&d>>>0>>0|f>>>0>>0;i=j+y|0;n=i;i=i>>>0>>0?e+1|0:e;r=d;e=d;d=h;j=(p|0)==(v|0)&N>>>0>O>>>0|p>>>0>>0;f=j+((v|0)==(I|0)&N>>>0>>0|v>>>0>>0)|0;h=0;j=f+((g|0)==(p|0)&O>>>0>Q>>>0|g>>>0

>>0)|0;f=g+e|0;e=d+j|0;e=f>>>0>>0?e+1|0:e;g=f;h=(d|0)==(e|0)&f>>>0>>0|d>>>0>e>>>0;d=h+n|0;f=i;f=d>>>0>>0?f+1|0:f;h=e;n=d;i=(t|0)==(C|0)&A>>>0>R>>>0|t>>>0>C>>>0;d=i+((t|0)==(u|0)&A>>>0>>0|t>>>0>>0)|0;j=0;j=d>>>0>>0?1:j;i=d;d=d+g|0;e=e+j|0;e=d>>>0>>0?e+1|0:e;h=(e|0)==(h|0)&d>>>0>>0|e>>>0>>0;g=n+h|0;f=g>>>0>>0?f+1|0:f;h=g;i=f;c:{if(f&65536){s=s+1|0;break c}v=l>>>31|0;f=i<<1|h>>>31;h=g<<1|e>>>31;i=f;f=e<<1|d>>>31;d=d<<1|c>>>31;e=f;g=x;f=l<<1|g>>>31;x=g<<1;l=f;f=c<<1|b>>>31;b=b<<1|v;c=f}if((s|0)>=32767){m=m|2147418112;b=0;c=0;break a}d:{if((s|0)<=0){f=1-s|0;if(f>>>0>=128){b=0;c=0;break a}g=s+127|0;od(k+48|0,x,l,b,c,g);od(k+32|0,d,e,h,i,g);eg(k+16|0,x,l,b,c,f);eg(k,d,e,h,i,f);x=G[k+32>>2]|G[k+16>>2]|(G[k+48>>2]|G[k+56>>2]|(G[k+52>>2]|G[k+60>>2]))!=0;l=G[k+36>>2]|G[k+20>>2];b=G[k+40>>2]|G[k+24>>2];c=G[k+44>>2]|G[k+28>>2];d=G[k>>2];e=G[k+4>>2];f=G[k+8>>2];g=G[k+12>>2];break d}f=h;g=i&65535|s<<16}o=f|o;m=g|m;if(!(!b&(c|0)==-2147483648?!(l|x):(c|0)>0|(c|0)>=0)){b=d+1|0;j=b?e:e+1|0;c=j;f=(e|0)==(j|0)&b>>>0>>0|e>>>0>j>>>0;d=f+o|0;e=m;o=d;m=d>>>0>>0?e+1|0:e;break a}if(b|x|(c^-2147483648|l)){b=d;c=e;break a}j=m;c=d&1;b=c+d|0;f=b>>>0>>0?e+1|0:e;c=f;e=(e|0)==(f|0)&b>>>0>>0|e>>>0>f>>>0;d=e+o|0;o=d;m=d>>>0>>0?j+1|0:j}G[a>>2]=b;G[a+4>>2]=c;G[a+8>>2]=o;G[a+12>>2]=m;Fa=k+96|0}function yn(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;f=a+48|0;d=1;a:{b:{c:{d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{p:{q:{r:{s:{t:{u:{v:{w:{x:{y:{z:{A:{B:{C:{D:{E:{F:{g=G[a+4>>2];switch(g|0){case 1:break k;case 11:break l;case 8:break m;case 9:break r;case 7:break t;case 6:break v;case 5:break x;case 4:break z;case 3:break B;case 13:case 14:break D;case 10:break E;case 12:break F;case 0:break g;case 2:break i;default:break a}}b=L[a- -64>>3];if(b>180){while(1){b=b+-360;if(b>180){continue}break}L[a+64>>3]=b}if(b<=-180){while(1){b=b+360;if(b<=-180){continue}break}L[a+64>>3]=b}c=L[a+72>>3];if(c>180){while(1){c=c+-360;if(c>180){continue}break}L[a+72>>3]=c}if(c<=-180){while(1){c=c+360;if(c<=-180){continue}break}L[a+72>>3]=c}e=L[a+88>>3];L[a+152>>3]=e*e;e=L[a+96>>3];L[a+160>>3]=e*e;break C}b=L[a- -64>>3];if(b>180){while(1){b=b+-360;if(b>180){continue}break}L[a+64>>3]=b}if(b<=-180){while(1){b=b+360;if(b<=-180){continue}break}L[a+64>>3]=b}c=L[a+72>>3];if(c>180){while(1){c=c+-360;if(c>180){continue}break}L[a+72>>3]=c}if(!(c<=-180)){break C}while(1){c=c+360;if(c<=-180){continue}break}L[a+72>>3]=c;break C}b=L[a- -64>>3];if(b>180){while(1){b=b+-360;if(b>180){continue}break}L[a+64>>3]=b}if(b<=-180){while(1){b=b+360;if(b<=-180){continue}break}L[a+64>>3]=b}c=L[a+72>>3];if(c>180){while(1){c=c+-360;if(c>180){continue}break}L[a+72>>3]=c}if(c<=-180){while(1){c=c+360;if(c<=-180){continue}break}L[a+72>>3]=c}e=L[a+128>>3]/180*3.141592653589793;m=a,n=eb(e),L[m+144>>3]=n;m=a,n=ib(e),L[m+136>>3]=n}switch(g|0){case 1:break j;case 14:break n;case 13:break o;case 12:break p;case 9:break q;case 7:break s;case 6:break u;case 5:break w;case 4:break y;case 3:break A;case 10:break c;case 11:break d;case 8:break e;case 0:break g;case 2:break h;default:break a}}b=L[a- -64>>3];L[a+152>>3]=b*b;c=L[a+72>>3];L[a+160>>3]=c*c}b=c;break h}b=L[a+80>>3]/180*3.141592653589793;m=a,n=eb(b),L[m+144>>3]=n;m=a,n=ib(b),L[m+136>>3]=n;c=L[a+72>>3];b=L[a- -64>>3]}b=b>c?b:c;break h}b=L[a+96>>3]/180*3.141592653589793;m=a,n=eb(b),L[m+160>>3]=n;m=a,n=ib(b),L[m+152>>3]=n;b=L[a+104>>3]/180*3.141592653589793;m=a,n=eb(b),L[m+144>>3]=n;m=a,n=ib(b),L[m+136>>3]=n}b=L[a+80>>3];d=L[a+88>>3];b=b>d?b:d;break h}b=L[a+80>>3]/180*3.141592653589793;m=a,n=eb(b),L[m+144>>3]=n;m=a,n=ib(b),L[m+136>>3]=n;c=L[a+72>>3];b=L[a- -64>>3]}b=V(b*b+c*c)*.5;break h}b=L[a+96>>3]/180*3.141592653589793;m=a,n=eb(b),L[m+160>>3]=n;m=a,n=ib(b),L[m+152>>3]=n;b=L[a+104>>3]/180*3.141592653589793;m=a,n=eb(b),L[m+144>>3]=n;m=a,n=ib(b),L[m+136>>3]=n}b=L[a+80>>3]*L[a+88>>3];b=V(b+b)*.5;break h}b=L[a+80>>3]/180*3.141592653589793;m=a,n=eb(b),L[m+144>>3]=n;m=a,n=ib(b),L[m+136>>3]=n;c=L[a+72>>3];b=L[a- -64>>3]}if(b>c){b=b*.5;break h}b=c*.5;break h}b=L[a+96>>3];break h}b=L[a+104>>3];d=L[a+112>>3];b=b>d?b:d;break h}b=L[a+104>>3]*L[a+112>>3];b=V(b+b)*.5;break h}c=L[a+72>>3];e=L[a+56>>3];L[a+96>>3]=(c+e)*.5;h=L[a- -64>>3];j=L[a+48>>3];L[a+88>>3]=(h+j)*.5;d=L[a+80>>3]/180*3.141592653589793;b=eb(d);L[a+144>>3]=b;d=ib(d);L[a+136>>3]=d;c=(c-e)*.5;e=(h-j)*.5;L[a+160>>3]=O(b*c-d*e);L[a+152>>3]=O(e*b+d*c);break e}f=G[f+4>>2];break d}b=L[a- -64>>3];c=b-L[a+48>>3];e=L[a+72>>3]-L[a+56>>3];d=V(c*c+e*e);L[a+152>>3]=d+.5;f=d!=0;L[a+144>>3]=f?c/d:1;L[a+136>>3]=f?e/d:0}d=L[a+48>>3];f=d>b;L[a+24>>3]=f?d:b;L[a+16>>3]=f?b:d;b=L[a+56>>3];d=L[a+72>>3];if(b>d){L[a+32>>3]=d;break b}L[a+32>>3]=b;b=d;break b}b=L[a- -64>>3];L[a+152>>3]=b*b}d=b;if(!(b>0)){break f}}b=L[a+48>>3];L[a+24>>3]=d+b;L[a+16>>3]=b-d;b=L[a+56>>3];L[a+32>>3]=b-d;b=d+b;break b}switch(g-8|0){case 2:break c;case 3:break d;case 0:break e;default:break a}}d=L[a+88>>3];b=d-L[a+48>>3];e=b*b;c=L[a+96>>3];b=c-L[a+56>>3];b=V(e+b*b);L[a+32>>3]=c-b;L[a+24>>3]=d+b;L[a+16>>3]=d-b;b=c+b;break b}d=L[f>>3];L[a+16>>3]=d;c=L[f>>3];L[a+24>>3]=c;h=L[f+8>>3];L[a+32>>3]=h;e=L[f+8>>3];L[a+40>>3]=e;k=G[a+48>>2];if((k|0)<3){break a}g=2;while(1){i=g<<3;l=i+f|0;b=L[l>>3];if(d>b){L[a+16>>3]=b;d=b;b=L[l>>3]}if(b>c){L[a+24>>3]=b;c=b}i=(i|8)+f|0;b=L[i>>3];if(h>b){L[a+32>>3]=b;h=b;b=L[i>>3]}if(b>e){L[a+40>>3]=b;e=b}g=g+2|0;if((k|0)>(g|0)){continue}break}break a}G[a+32>>2]=0;G[a+36>>2]=1072693248;G[a+24>>2]=0;G[a+28>>2]=-1074790400;G[a+16>>2]=0;G[a+20>>2]=1072693248;b=-1}L[a+40>>3]=b}}function Wg(a,b){var c=0,d=0;c=Fa-816|0;Fa=c;a:{b:{c:{if(!a){d=1;if(b){break c}hb(84487,69,1,G[321435]);break a}if(G[321437]){G[c+800>>2]=G[a+3260>>2];kb(75671,c+800|0);G[c+784>>2]=a+3544;kb(76709,c+784|0);L[c+768>>3]=L[a+136>>3];gb(70763,c+768|0);L[c+752>>3]=L[a+144>>3];gb(70745,c+752|0);G[c+736>>2]=a+3512;kb(76668,c+736|0);G[c+720>>2]=a+3528;kb(76649,c+720|0);G[c+704>>2]=G[a+3316>>2];kb(75688,c+704|0);if(G[a+3316>>2]>0){while(1){L[c+696>>3]=L[((d<<3)+a|0)+688>>3];G[c+688>>2]=d;gb(70635,c+688|0);d=d+1|0;if((d|0)>2]){continue}break}}L[c+672>>3]=L[a>>3];gb(70836,c+672|0);L[c+656>>3]=L[a+8>>3];gb(70818,c+656|0);if(G[a+3316>>2]>0){d=0;while(1){L[c+648>>3]=L[((d<<3)+a|0)+616>>3];G[c+640>>2]=d;gb(70597,c+640|0);d=d+1|0;if((d|0)>2]){continue}break}}L[c+624>>3]=L[a+16>>3];gb(70690,c+624|0);L[c+608>>3]=L[a+24>>3];gb(70672,c+608|0);d:{if(G[a+3300>>2]){L[c+600>>3]=L[a+56>>3];G[c+592>>2]=0;gb(70799,c+592|0);L[c+584>>3]=L[a- -64>>3];G[c+576>>2]=1;gb(70799,c+576|0);L[c+568>>3]=L[a+72>>3];G[c+560>>2]=2;gb(70799,c+560|0);L[c+552>>3]=L[a+80>>3];G[c+544>>2]=3;gb(70799,c+544|0);break d}if(G[a+3316>>2]<=0){break d}d=0;while(1){L[c+536>>3]=L[((d<<3)+a|0)+760>>3];G[c+528>>2]=d;gb(70616,c+528|0);d=d+1|0;if((d|0)>2]){continue}break}}L[c+512>>3]=L[a+32>>3];gb(70872,c+512|0);L[c+496>>3]=L[a+40>>3];gb(70854,c+496|0);L[c+480>>3]=L[a+48>>3];gb(70890,c+480|0);L[c+464>>3]=L[a+120>>3];gb(70654,c+464|0);L[c+448>>3]=L[a+128>>3];gb(70781,c+448|0);L[c+440>>3]=L[a+832>>3];G[c+432>>2]=0;gb(70726,c+432|0);L[c+424>>3]=L[a+840>>3];G[c+416>>2]=1;gb(70726,c+416|0);L[c+408>>3]=L[a+848>>3];G[c+400>>2]=2;gb(70726,c+400|0);L[c+392>>3]=L[a+856>>3];G[c+384>>2]=3;gb(70726,c+384|0);L[c+376>>3]=L[a+864>>3];G[c+368>>2]=4;gb(70726,c+368|0);L[c+360>>3]=L[a+872>>3];G[c+352>>2]=5;gb(70726,c+352|0);L[c+344>>3]=L[a+880>>3];G[c+336>>2]=6;gb(70726,c+336|0);L[c+328>>3]=L[a+888>>3];G[c+320>>2]=7;gb(70726,c+320|0);L[c+312>>3]=L[a+896>>3];G[c+304>>2]=8;gb(70726,c+304|0);L[c+296>>3]=L[a+904>>3];G[c+288>>2]=9;gb(70726,c+288|0);L[c+280>>3]=L[a+912>>3];G[c+272>>2]=10;gb(70726,c+272|0);L[c+264>>3]=L[a+920>>3];G[c+256>>2]=11;gb(70726,c+256|0);L[c+248>>3]=L[a+928>>3];G[c+240>>2]=12;gb(70726,c+240|0);L[c+232>>3]=L[a+936>>3];G[c+224>>2]=13;gb(70726,c+224|0);L[c+216>>3]=L[a+944>>3];G[c+208>>2]=14;gb(70726,c+208|0);L[c+200>>3]=L[a+952>>3];G[c+192>>2]=15;gb(70726,c+192|0);L[c+184>>3]=L[a+1480>>3];G[c+176>>2]=0;gb(70560,c+176|0);L[c+168>>3]=L[a+1488>>3];G[c+160>>2]=1;gb(70560,c+160|0);L[c+152>>3]=L[a+1496>>3];G[c+144>>2]=2;gb(70560,c+144|0);L[c+136>>3]=L[a+1504>>3];G[c+128>>2]=3;gb(70560,c+128|0);L[c+120>>3]=L[a+1512>>3];G[c+112>>2]=4;gb(70560,c+112|0);L[c+104>>3]=L[a+1520>>3];G[c+96>>2]=5;gb(70560,c+96|0);L[c+88>>3]=L[a+1528>>3];G[c+80>>2]=6;gb(70560,c+80|0);L[c+72>>3]=L[a+1536>>3];G[c+64>>2]=7;gb(70560,c- -64|0);L[c+56>>3]=L[a+1544>>3];G[c+48>>2]=8;gb(70560,c+48|0);L[c+40>>3]=L[a+1552>>3];G[c+32>>2]=9;gb(70560,c+32|0);L[c+16>>3]=L[a+3176>>3];gb(70579,c+16|0);L[c>>3]=L[a+3184>>3];gb(70708,c)}d=1;if(G[a+3316>>2]<=1){if(b){break c}hb(80015,63,1,G[321435]);break a}if(G[a+3260>>2]<=0){if(b){break c}hb(82316,48,1,G[321435]);break a}if(L[a+136>>3]<=0){if(b){break c}hb(83370,44,1,G[321435]);break a}if(L[a+144>>3]<=0){if(b){break c}hb(83280,44,1,G[321435]);break a}e:{d=a+3512|0;if(!Xa(d,35967)){if(!Xa(a+3528|0,35895)){break e}d=1;if(b){break c}break b}if(!Xa(d,35895)){if(!Xa(a+3528|0,35967)){break e}d=1;if(b){break c}break b}if(!Xa(d,34433)){if(!Xa(a+3528|0,33498)){break e}d=1;if(b){break c}break b}if(!Xa(d,33498)){if(!Xa(a+3528|0,34433)){break e}d=1;if(b){break c}break b}if(!Xa(d,34438)){if(!Xa(a+3528|0,33503)){break e}d=1;if(b){break c}break b}if(!Xa(d,33503)){if(!Xa(a+3528|0,34438)){break e}d=1;if(b){break c}break b}d=1;if(b){break c}hb(83415,44,1,G[321435]);break a}if(G[a+3300>>2]){if(!(L[a+56>>3]==0&L[a- -64>>3]==0)){d=0;if(L[a+72>>3]!=0|L[a+80>>3]!=0){break c}}d=1;if(b){break c}hb(79614,47,1,G[321435]);break a}if(L[a+32>>3]==0){d=1;if(b){break c}hb(83325,44,1,G[321435]);break a}if(L[a+40>>3]!=0){d=0;break c}d=1;if(b){break c}hb(83235,44,1,G[321435]);break a}Fa=c+816|0;return d}hb(82624,59,1,G[321435])}$a(G[321435]);Hb(G[321435]);sc(1);W()}function Oh(a,b,c,d,e,f,g){var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0;if(!H[3707e3]){G[926752]=-1571644103;G[926753]=1066524486;p=bb(3728656,145760,724);q=bb(3729392,146496,724);s=bb(3730128,147232,724);y=bb(3730864,147968,724);bb(3731600,148704,500);bb(3732100,149216,500);bb(3732600,149728,500);bb(3733100,150240,400);bb(3733504,150640,500);bb(3734004,151152,500);bb(3734504,151664,500);bb(3735004,152176,400);bb(3735408,152576,500);bb(3735908,153088,500);bb(3736408,153600,500);bb(3736908,154112,400);bb(3737312,154512,500);bb(3737812,155024,500);bb(3738312,155536,500);bb(3738812,156048,400);bb(3739216,156448,140);bb(3739360,156592,140);while(1){h=i<<3;j=i<<2;L[h+3707024>>3]=+G[j+p>>2]*.001;L[h+3708480>>3]=+G[j+q>>2]*.001;L[h+3709936>>3]=+G[j+s>>2]*.01;L[h+3711392>>3]=+G[j+y>>2]*.01;i=i+1|0;if((i|0)!=181){continue}break}while(1){i=0;while(1){h=M(n,200)+(i<<3)|0;j=M(n,100)+(i<<2)|0;L[h+3712848>>3]=+G[j+3731600>>2]*.001;L[h+3716656>>3]=+G[j+3733504>>2]*.001;L[h+3720464>>3]=+G[j+3735408>>2]*.01;L[h+3724272>>3]=+G[j+3737312>>2]*.01;i=i+1|0;if((i|0)!=25){continue}break}n=n+1|0;if((n|0)!=19){continue}break}j=0;while(1){i=M(j,56);h=M(j,28);L[i+3728080>>3]=+G[h+3739216>>2]*.001;L[i+3728368>>3]=+G[h+3739360>>2]*.001;L[i+3728088>>3]=+G[h+3739220>>2]*.001;L[i+3728376>>3]=+G[h+3739364>>2]*.001;L[i+3728096>>3]=+G[h+3739224>>2]*.001;L[i+3728384>>3]=+G[h+3739368>>2]*.001;L[i+3728104>>3]=+G[h+3739228>>2]*.001;L[i+3728392>>3]=+G[h+3739372>>2]*.001;L[i+3728112>>3]=+G[h+3739232>>2]*.001;L[i+3728400>>3]=+G[h+3739376>>2]*.001;L[i+3728120>>3]=+G[h+3739236>>2]*.001;L[i+3728408>>3]=+G[h+3739380>>2]*.001;L[i+3728128>>3]=+G[h+3739240>>2]*.001;L[i+3728416>>3]=+G[h+3739384>>2]*.001;j=j+1|0;if((j|0)!=5){continue}break}E[3707e3]=1}G[d>>2]=0;G[d+4>>2]=0;G[e>>2]=0;G[e+4>>2]=0;G[f>>2]=0;G[f+4>>2]=0;G[g>>2]=0;G[g+4>>2]=0;a:{if(O(b)>89.999){break a}if(a<0){while(1){a=a+360;if(a<0){continue}break}}if(a>360){while(1){a=a+-360;if(a>360){continue}break}}i=1;l=91-b;b:{if(O(l)<2147483648){h=~~l;break b}h=-2147483648}h=(h|0)<180?h:180;j=(h|0)>1?h:1;h=j<<3;u=L[h+3711384>>3];k=+(91-j|0);l=+(90-j|0)-k;k=b-k;z=(L[h+3711392>>3]-u)/l*k;v=L[h+3709928>>3];A=(L[h+3709936>>3]-v)/l*k;w=L[h+3708472>>3];B=(L[h+3708480>>3]-w)/l*k;x=L[h+3707016>>3];C=(L[h+3707024>>3]-x)/l*k;h=1;c:{if(b>=80){break c}h=2;if(b>=70){break c}h=3;if(b>=60){break c}h=4;if(b>=50){break c}h=5;if(b>=40){break c}h=6;if(b>=30){break c}h=7;if(b>=20){break c}h=8;if(b>=10){break c}h=9;if(b>=0){break c}h=10;if(b>=-10){break c}h=11;if(b>=-20){break c}h=12;if(b>=-30){break c}h=13;if(b>=-40){break c}h=14;if(b>=-50){break c}h=15;if(b>=-60){break c}h=16;if(b>=-70){break c}h=17;if(b>=-80){break c}h=18;if(b>=-85){break c}h=19}p=h>>>0<18?h:18;q=p-1|0;d:{if(a<=15){break d}i=2;if(a<=30){break d}i=3;if(a<=45){break d}i=4;if(a<=60){break d}i=5;if(a<=75){break d}i=6;if(a<=90){break d}i=7;if(a<=105){break d}i=8;if(a<=120){break d}i=9;if(a<=135){break d}i=10;if(a<=150){break d}i=11;if(a<=165){break d}i=12;if(a<=180){break d}i=13;if(a<=195){break d}i=14;if(a<=210){break d}i=15;if(a<=225){break d}i=16;if(a<=240){break d}i=17;if(a<=255){break d}i=18;if(a<=270){break d}i=19;if(a<=285){break d}i=20;if(a<=300){break d}i=21;if(a<=315){break d}i=22;if(a<=330){break d}i=23;if(a<=345){break d}i=24;if(a<=360){break d}i=25}i=(i>>>0<24?i:24)<<3;j=M(q,200);h=j+3724272|0;r=L[i+h>>3];n=h;h=i-8|0;o=L[n+h>>3];n=M(p,200);s=n+3724272|0;k=L[(q<<3)+145392>>3];l=L[(p<<3)+145392>>3]-k;k=b-k;o=(L[h+s>>3]-o)/l*k+o;t=(L[i+s>>3]-r)/l*k+r-o;m=L[i+145544>>3];r=L[i+145552>>3]-m;a=a-m;t=t/r*a+o;p=j+3720464|0;o=L[p+i>>3];q=n+3720464|0;m=L[h+p>>3];m=(L[q+h>>3]-m)/l*k+m;D=((L[i+q>>3]-o)/l*k+o-m)/r*a+m;p=j+3712848|0;o=L[p+i>>3];q=n+3712848|0;m=L[h+p>>3];m=(L[q+h>>3]-m)/l*k+m;F=((L[i+q>>3]-o)/l*k+o-m)/r*a+m;j=j+3716656|0;o=L[j+i>>3];n=n+3716656|0;m=L[h+j>>3];m=(L[n+h>>3]-m)/l*k+m;k=B+w+(((L[i+n>>3]-o)/l*k+o-m)/r*a+m)+0;a=eb(L[463376]*b);k=k/a;l=(C+x+F+0)/a;r=z+u+t;a=A+v+D;if(!(!(c>0)|c==1950)){c=(c+-1950)*.01;a=r*c+a;l=k*c+l}a=a/3600;e:{if(G[47600]>=0){if(!(O(a+b)>89.999)){break e}break a}if(O(b-a)>89.999){break a}}L[e>>3]=a;L[d>>3]=l*15/3600;L[f>>3]=k;L[g>>3]=r}}function rk(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0;h=Fa-288|0;Fa=h;d=cb(h,0,81);i=G[b>>2];a:{if((i|0)>0){break a}e=G[a+4>>2];f=e;h=G[f+104>>2];m=G[f+108>>2];g=G[f+132>>2];n=g;t=G[f+128>>2];if((g&t)==-1){f=Cu(h,m);g=(h-f|0)+2880|0;f=m-(Ia+(f>>>0>h>>>0)|0)|0;t=g;G[e+128>>2]=g;f=g>>>0<2880?f+1|0:f;G[e+132>>2]=f;n=f}i=0;u=H[68297];E[d+232|0]=u;e=H[68293]|H[68294]<<8|(H[68295]<<16|H[68296]<<24);p=e;f=H[68289]|H[68290]<<8|(H[68291]<<16|H[68292]<<24);G[d+224>>2]=f;G[d+228>>2]=e;g=H[68285]|H[68286]<<8|(H[68287]<<16|H[68288]<<24);q=g;e=H[68281]|H[68282]<<8|(H[68283]<<16|H[68284]<<24);G[d+216>>2]=e;G[d+220>>2]=g;j=H[68277]|H[68278]<<8|(H[68279]<<16|H[68280]<<24);r=j;g=H[68273]|H[68274]<<8|(H[68275]<<16|H[68276]<<24);G[d+208>>2]=g;G[d+212>>2]=j;k=H[68269]|H[68270]<<8|(H[68271]<<16|H[68272]<<24);s=k;j=H[68265]|H[68266]<<8|(H[68267]<<16|H[68268]<<24);G[d+200>>2]=j;G[d+204>>2]=k;o=H[68261]|H[68262]<<8|(H[68263]<<16|H[68264]<<24);k=H[68257]|H[68258]<<8|(H[68259]<<16|H[68260]<<24);G[d+192>>2]=k;G[d+196>>2]=o;c=d+192|0;c=Va(c)+c|0;E[c|0]=k;v=k>>>8|0;E[c+1|0]=v;w=k>>>16|0;E[c+2|0]=w;x=k>>>24|0;E[c+3|0]=x;E[c+4|0]=o;y=o>>>8|0;E[c+5|0]=y;z=o>>>16|0;E[c+6|0]=z;A=o>>>24|0;E[c+7|0]=A;l=H[68115]|H[68116]<<8|(H[68117]<<16|H[68118]<<24);G[d+112>>2]=H[68111]|H[68112]<<8|(H[68113]<<16|H[68114]<<24);G[d+116>>2]=l;l=H[68123]|H[68124]<<8|(H[68125]<<16|H[68126]<<24);G[d+120>>2]=H[68119]|H[68120]<<8|(H[68121]<<16|H[68122]<<24);G[d+124>>2]=l;l=H[68131]|H[68132]<<8|(H[68133]<<16|H[68134]<<24);G[d+128>>2]=H[68127]|H[68128]<<8|(H[68129]<<16|H[68130]<<24);G[d+132>>2]=l;E[d+136|0]=H[68135];E[c+40|0]=u;E[c+32|0]=f;l=f>>>8|0;E[c+33|0]=l;B=f>>>16|0;E[c+34|0]=B;C=f>>>24|0;E[c+35|0]=C;E[c+36|0]=p;D=p>>>8|0;E[c+37|0]=D;F=p>>>16|0;E[c+38|0]=F;I=p>>>24|0;E[c+39|0]=I;E[c+24|0]=e;J=e>>>8|0;E[c+25|0]=J;K=e>>>16|0;E[c+26|0]=K;L=e>>>24|0;E[c+27|0]=L;E[c+28|0]=q;M=q>>>8|0;E[c+29|0]=M;N=q>>>16|0;E[c+30|0]=N;O=q>>>24|0;E[c+31|0]=O;E[c+16|0]=g;P=g>>>8|0;E[c+17|0]=P;Q=g>>>16|0;E[c+18|0]=Q;R=g>>>24|0;E[c+19|0]=R;E[c+20|0]=r;S=r>>>8|0;E[c+21|0]=S;T=r>>>16|0;E[c+22|0]=T;U=r>>>24|0;E[c+23|0]=U;E[c+8|0]=j;V=j>>>8|0;E[c+9|0]=V;W=j>>>16|0;E[c+10|0]=W;X=j>>>24|0;E[c+11|0]=X;E[c+12|0]=s;Y=s>>>8|0;E[c+13|0]=Y;Z=s>>>16|0;E[c+14|0]=Z;_=s>>>24|0;E[c+15|0]=_;c=H[68099]|H[68100]<<8|(H[68101]<<16|H[68102]<<24);G[d+96>>2]=H[68095]|H[68096]<<8|(H[68097]<<16|H[68098]<<24);G[d+100>>2]=c;c=H[68107]|H[68108]<<8|(H[68109]<<16|H[68110]<<24);G[d+104>>2]=H[68103]|H[68104]<<8|(H[68105]<<16|H[68106]<<24);G[d+108>>2]=c;c=d+96|0;c=Va(c)+c|0;E[c|0]=k;E[c+1|0]=v;E[c+2|0]=w;E[c+3|0]=x;E[c+4|0]=o;E[c+5|0]=y;E[c+6|0]=z;E[c+7|0]=A;E[c+40|0]=u;E[c+32|0]=f;E[c+33|0]=l;E[c+34|0]=B;E[c+35|0]=C;E[c+36|0]=p;E[c+37|0]=D;E[c+38|0]=F;E[c+39|0]=I;E[c+24|0]=e;E[c+25|0]=J;E[c+26|0]=K;E[c+27|0]=L;E[c+28|0]=q;E[c+29|0]=M;E[c+30|0]=N;E[c+31|0]=O;E[c+16|0]=g;E[c+17|0]=P;E[c+18|0]=Q;E[c+19|0]=R;E[c+20|0]=r;E[c+21|0]=S;E[c+22|0]=T;E[c+23|0]=U;E[c+8|0]=j;E[c+9|0]=V;E[c+10|0]=W;E[c+11|0]=X;E[c+12|0]=s;E[c+13|0]=Y;E[c+14|0]=Z;E[c+15|0]=_;G[d+284>>2]=0;Jb(a,h,m,0,d+284|0);b:{c:{f=Bu(t-h|0,n-((h>>>0>t>>>0)+m|0)|0,80,0);d:{if((f|0)>0){while(1){ic(a,80,0,d,d+284|0);if(G[d+284>>2]){break c}e:{if(!fb(d,d+192|0,80)){break e}if(!fb(d,d+96|0,80)){break e}e=0;break d}i=i+1|0;if((f|0)!=(i|0)){continue}break}i=f;e=0;break d}e=G[d+284>>2]!=0}if(e|(f|0)!=(i|0)){break c}e=G[a+4>>2];g=G[e+128>>2];j=g-2880|0;n=h>>>0>j>>>0;e=G[e+132>>2]-(g>>>0<2880)|0;g=n&(e|0)<=(m|0)|(e|0)<(m|0);h=g?h:j;e=g?m:e;g=d+284|0;Jb(a,h,e,0,g);ic(a,80,0,d,g);if(fb(d,d+96|0,80)|G[d+284>>2]){break c}a=G[a+4>>2];G[a+112>>2]=h;G[a+116>>2]=e;break b}e=G[a+4>>2];h=G[e+108>>2];e=G[e+104>>2];Jb(a,e,h,1,b);if((f|0)>0){i=0;while(1){Wb(a,80,0,d+192|0,b);i=i+1|0;if((f|0)!=(i|0)){continue}break}}n=e;f=G[a+4>>2];g=G[f+128>>2];j=g-2880|0;f=G[f+132>>2]-(g>>>0<2880)|0;e=(f|0)<=(h|0)&e>>>0>j>>>0|(f|0)<(h|0);g=e?n:j;h=e?h:f;Jb(a,g,h,0,b);Wb(a,80,0,d+96|0,b);a=G[a+4>>2];G[a+112>>2]=g;G[a+116>>2]=h;i=G[b>>2];if((i|0)<=0){break a}tb(5,47547)}i=G[b>>2]}Fa=d+288|0;return i}function wo(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0;d=Fa-96|0;Fa=d;e=G[c>>2];a:{if((e|0)>0){break a}if((a|0)==(b|0)){e=101;G[c>>2]=101;break a}e=G[a>>2];if((e|0)!=G[G[a+4>>2]+76>>2]){mb(a,e+1|0,0,c)}b:{if((Td(a,d+92|0,0,c)|0)<=0){f=G[d+92>>2];g=ab(M(f,81));if(!g){break b}e=0;if((f|0)>0){while(1){f=e+1|0;Sd(a,f,M(e,81)+g|0,c);e=f;if((e|0)>2]){continue}break}}h=G[a>>2];G[d+88>>2]=-1;if(!G[G[a+4>>2]+80>>2]){Ec(a,33788,d+88|0,0,c)}e=G[b>>2];a=G[b+4>>2];if((e|0)!=G[a+76>>2]){mb(b,e+1|0,0,c);a=G[b+4>>2];e=G[a+76>>2]}e=G[a+96>>2]+(e<<3)|0;if(G[a+104>>2]!=G[e>>2]|G[a+108>>2]!=G[e+4>>2]){Ke(b,c)}f=1;c:{if(G[b>>2]){break c}if(G[d+88>>2]>=0){i=1;f=0;break c}pd(b,8,0,d+84|0,c);Ke(b,c);f=1}e=G[c>>2];if((e|0)>0){Wa(g);break a}a=1;d:{if(!(f^1|(h|0)!=0)){e=H[15459]|H[15460]<<8|(H[15461]<<16|H[15462]<<24);G[d+8>>2]=H[15455]|H[15456]<<8|(H[15457]<<16|H[15458]<<24);G[d+12>>2]=e;e=H[15451]|H[15452]<<8|(H[15453]<<16|H[15454]<<24);G[d>>2]=H[15447]|H[15448]<<8|(H[15449]<<16|H[15450]<<24);G[d+4>>2]=e;lc(b,34516,35678,d,c);if(G[d+88>>2]>=-1){while(1){wb(b,M(a,81)+g|0,c);e=(G[d+88>>2]+2|0)>(a|0);a=a+1|0;if(e){continue}break}}F[d+32>>1]=H[6071]|H[6072]<<8;a=H[6067]|H[6068]<<8|(H[6069]<<16|H[6070]<<24);G[d+24>>2]=H[6063]|H[6064]<<8|(H[6065]<<16|H[6066]<<24);G[d+28>>2]=a;a=H[6059]|H[6060]<<8|(H[6061]<<16|H[6062]<<24);G[d+16>>2]=H[6055]|H[6056]<<8|(H[6057]<<16|H[6058]<<24);G[d+20>>2]=a;a=H[6051]|H[6052]<<8|(H[6053]<<16|H[6054]<<24);G[d+8>>2]=H[6047]|H[6048]<<8|(H[6049]<<16|H[6050]<<24);G[d+12>>2]=a;a=H[6043]|H[6044]<<8|(H[6045]<<16|H[6046]<<24);G[d>>2]=H[6039]|H[6040]<<8|(H[6041]<<16|H[6042]<<24);G[d+4>>2]=a;hd(b,33303,0,0,d,c);a=H[6512]|H[6513]<<8|(H[6514]<<16|H[6515]<<24);G[d+16>>2]=H[6508]|H[6509]<<8|(H[6510]<<16|H[6511]<<24);G[d+20>>2]=a;a=H[6504]|H[6505]<<8|(H[6506]<<16|H[6507]<<24);G[d+8>>2]=H[6500]|H[6501]<<8|(H[6502]<<16|H[6503]<<24);G[d+12>>2]=a;a=H[6496]|H[6497]<<8|(H[6498]<<16|H[6499]<<24);G[d>>2]=H[6492]|H[6493]<<8|(H[6494]<<16|H[6495]<<24);G[d+4>>2]=a;hd(b,33311,1,0,d,c);a=G[d+88>>2]+3|0;e=G[d+92>>2];if((a|0)>=(e|0)){break d}while(1){e:{f:{g:{h:{f=M(a,81)+g|0;switch(H[f|0]-67|0){case 0:break g;case 2:break h;default:break f}}if(fb(f,67980,8)){break f}break e}if(!fb(f,7011,58)){break e}if(!fb(f,40528,47)){break e}}wb(b,f,c);e=G[d+92>>2]}a=a+1|0;if((e|0)>(a|0)){continue}break}break d}if(!((h|0)!=0&i)){a=0;if(G[d+92>>2]<=0){break d}while(1){wb(b,M(a,81)+g|0,c);a=a+1|0;if((a|0)>2]){continue}break}break d}e=H[26031]|H[26032]<<8|(H[26033]<<16|H[26034]<<24);E[d+31|0]=e;E[d+32|0]=e>>>8;E[d+33|0]=e>>>16;E[d+34|0]=e>>>24;e=H[26028]|H[26029]<<8|(H[26030]<<16|H[26031]<<24);G[d+24>>2]=H[26024]|H[26025]<<8|(H[26026]<<16|H[26027]<<24);G[d+28>>2]=e;e=H[26020]|H[26021]<<8|(H[26022]<<16|H[26023]<<24);G[d+16>>2]=H[26016]|H[26017]<<8|(H[26018]<<16|H[26019]<<24);G[d+20>>2]=e;e=H[26012]|H[26013]<<8|(H[26014]<<16|H[26015]<<24);G[d+8>>2]=H[26008]|H[26009]<<8|(H[26010]<<16|H[26011]<<24);G[d+12>>2]=e;e=H[26004]|H[26005]<<8|(H[26006]<<16|H[26007]<<24);G[d>>2]=H[26e3]|H[26001]<<8|(H[26002]<<16|H[26003]<<24);G[d+4>>2]=e;Rg(b,35530,1,d,c);if(G[d+88>>2]>=-1){while(1){wb(b,M(a,81)+g|0,c);e=(G[d+88>>2]+2|0)>(a|0);a=a+1|0;if(e){continue}break}}G[d+32>>2]=H[6580]|H[6581]<<8|(H[6582]<<16|H[6583]<<24);a=H[6576]|H[6577]<<8|(H[6578]<<16|H[6579]<<24);G[d+24>>2]=H[6572]|H[6573]<<8|(H[6574]<<16|H[6575]<<24);G[d+28>>2]=a;a=H[6568]|H[6569]<<8|(H[6570]<<16|H[6571]<<24);G[d+16>>2]=H[6564]|H[6565]<<8|(H[6566]<<16|H[6567]<<24);G[d+20>>2]=a;a=H[6560]|H[6561]<<8|(H[6562]<<16|H[6563]<<24);G[d+8>>2]=H[6556]|H[6557]<<8|(H[6558]<<16|H[6559]<<24);G[d+12>>2]=a;a=H[6552]|H[6553]<<8|(H[6554]<<16|H[6555]<<24);G[d>>2]=H[6548]|H[6549]<<8|(H[6550]<<16|H[6551]<<24);G[d+4>>2]=a;Rg(b,35787,1,d,c);wb(b,3277,c);wb(b,34961,c);a=G[d+88>>2]+3|0;e=G[d+92>>2];if((a|0)>=(e|0)){break d}while(1){i:{j:{k:{l:{f=M(a,81)+g|0;switch(H[f|0]-71|0){case 0:break k;case 9:break l;default:break j}}if(fb(f,67895,8)){break j}break i}if(!fb(f,67904,8)){break i}}wb(b,f,c);e=G[d+92>>2]}a=a+1|0;if((e|0)>(a|0)){continue}break}}Wa(g)}e=G[c>>2];break a}e=113;G[c>>2]=113}Fa=d+96|0;return e}function Jr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,H=0,I=0,J=0,K=0,N=0,O=0,P=0;f=Fa-160|0;Fa=f;if(G[c+4>>2]!=803){G[c+1892>>2]=107;G[c+1888>>2]=108;E[c|0]=84;E[c+1|0]=79;E[c+2|0]=65;E[c+3|0]=0;E[c+4|0]=35;E[c+5|0]=3;E[c+6|0]=0;E[c+7|0]=0}if(a<0){while(1){a=a+360;if(a<0){continue}break}}if(a>=360){while(1){a=a+-360;if(a>=360){continue}break}}j=90;a:{if(b>90){break a}j=b;if(!(b<-90)){break a}j=-90}j=j*.017453292519943295;t=eb(j);b=a*.017453292519943295;h=ib(b);g=eb(b);w=ib(j);b:{if(a<90){G[f+48>>2]=0;G[f+52>>2]=0;G[f+128>>2]=0;G[f+132>>2]=0;G[f+88>>2]=0;G[f+92>>2]=-1068072960;G[f+80>>2]=0;G[f+84>>2]=0;G[f+8>>2]=0;G[f+12>>2]=1079410688;G[f>>2]=0;G[f+4>>2]=0;G[f+40>>2]=0;G[f+44>>2]=0;G[f+120>>2]=0;G[f+124>>2]=1079410688;c=1;j=0;b=1.5707963267948966;q=1.5707963267948966;a=-1.5707963267948966;break b}c:{if(a<180){G[f+128>>2]=0;G[f+132>>2]=-1068072960;G[f+88>>2]=0;G[f+92>>2]=0;G[f+48>>2]=0;G[f+52>>2]=1079410688;G[f+120>>2]=0;G[f+124>>2]=0;G[f+80>>2]=0;G[f+84>>2]=1079410688;G[f+40>>2]=0;G[f+44>>2]=0;G[f+8>>2]=0;G[f+12>>2]=0;G[f>>2]=0;G[f+4>>2]=1080459264;c=0;r=3.141592653589793;l=1.5707963267948966;j=-1.5707963267948966;k=1.5707963267948966;b=0;break c}if(a<270){G[f+128>>2]=0;G[f+132>>2]=0;G[f+88>>2]=0;G[f+92>>2]=1079410688;G[f+48>>2]=0;G[f+52>>2]=0;G[f+120>>2]=0;G[f+124>>2]=1080459264;G[f+80>>2]=0;G[f+84>>2]=0;G[f+40>>2]=0;G[f+44>>2]=1081139200;G[f+8>>2]=0;G[f+12>>2]=-1068072960;G[f>>2]=0;G[f+4>>2]=0;c=1;i=4.71238898038469;j=0;b=3.141592653589793;q=-1.5707963267948966;a=1.5707963267948966;break b}G[f+48>>2]=0;G[f+52>>2]=-1068072960;G[f+88>>2]=0;G[f+92>>2]=0;G[f+128>>2]=0;G[f+132>>2]=1079410688;G[f+120>>2]=0;G[f+124>>2]=0;G[f+40>>2]=0;G[f+44>>2]=0;G[f+8>>2]=0;G[f+12>>2]=0;G[f>>2]=0;G[f+4>>2]=1081139200;G[f+80>>2]=0;G[f+84>>2]=0;c=0;r=4.71238898038469;k=-1.5707963267948966;j=1.5707963267948966;b=0}a=0}x=h*t;y=g*t;O=f,P=ib(j),L[O+152>>3]=P;O=f,P=ib(a),L[O+112>>3]=P;O=f,P=ib(k),L[O+72>>3]=P;j=eb(j);O=f,P=j*ib(b),L[O+144>>3]=P;O=f,P=j*eb(b),L[O+136>>3]=P;a=eb(a);O=f,P=a*ib(l),L[O+104>>3]=P;O=f,P=a*eb(l),L[O+96>>3]=P;a=eb(k);O=f- -64|0,P=a*ib(i),L[O>>3]=P;O=f,P=a*eb(i),L[O+56>>3]=P;O=f,P=ib(q),L[O+32>>3]=P;a=eb(q);O=f,P=a*ib(r),L[O+24>>3]=P;O=f,P=a*eb(r),L[O+16>>3]=P;J=1;while(1){q=L[f+32>>3];j=L[f+152>>3];m=q+j;r=L[f+16>>3];b=L[f+136>>3];t=r+b;k=L[f+24>>3];h=L[f+144>>3];l=k+h;a=V(m*m+(t*t+l*l));u=a==0?1:a;K=M(c,40)+f|0;v=(c+2|0)%4|0;N=M(v,40)+f|0;a=L[K+16>>3]+L[N+16>>3];s=a;i=L[K+32>>3]+L[N+32>>3];g=L[K+24>>3]+L[N+24>>3];a=V(i*i+(a*a+g*g));a=a==0?1:a;n=s/a;z=l/u;o=g/a;A=t/u;B=m/u;p=i/a;u=(n*z-o*A)*w+((o*B-p*z)*y+x*(A*p-n*B));g=L[f+112>>3];l=g+j;j=L[f+96>>3];i=j+b;b=L[f+104>>3];h=b+h;a=V(l*l+(i*i+h*h));a=a==0?1:a;C=l/a;D=h/a;F=i/a;t=(o*C-p*D)*y+x*(F*p-n*C);l=(n*D-o*F)*w;i=L[f+72>>3];m=i+g;h=L[f+56>>3];j=h+j;g=L[f+64>>3];b=g+b;a=V(m*m+(j*j+b*b));a=a==0?1:a;H=b/a;I=m/a;m=j/a;j=(H*p-I*o)*y+x*(I*n-m*p);b=(m*o-H*n)*w;i=i+q;h=h+r;g=g+k;a=V(i*i+(h*h+g*g));k=a==0?1:a;q=h/k;r=g/k;a=q*o-r*n;s=a;k=i/k;h=r*p-k*o;i=k*n-q*p;a=V(a*a+(h*h+i*i));g=a==0?1:a;a=s/g;s=a;h=h/g;i=i/g;a=V(a*a+(h*h+i*i));g=a==0?1:a;a=s/g;s=a;h=h/g;i=i/g;a=V(a*a+(h*h+i*i));g=a==0?1:a;a=s/g;s=a;h=h/g;g=i/g;a=V(a*a+(h*h+g*g));a=a==0?1:a;a=s/a*w+(h/a*y+x*(g/a));if(!(!(a>=0)|!(u>=0))){L[f+152>>3]=B;L[f+144>>3]=z;L[f+136>>3]=A;L[f+112>>3]=p;L[f+104>>3]=o;L[f+96>>3]=n;L[f+72>>3]=k;L[f+64>>3]=r;L[f+56>>3]=q;c=(c|0)!=0&(v|0)!=0}g=l+t;b=b+j;if(!(!(a<0)|!(b>=0))){L[f+152>>3]=p;L[f+144>>3]=o;L[f+136>>3]=n;L[f+112>>3]=I;L[f+104>>3]=H;L[f+96>>3]=m;L[f+32>>3]=k;L[f+24>>3]=r;L[f+16>>3]=q;c=(c|0)==1|(v|0)==1}if(!(!(g>=0)|!(u<0))){L[f+112>>3]=C;L[f+104>>3]=D;L[f+96>>3]=F;L[f+72>>3]=p;L[f+64>>3]=o;L[f+56>>3]=n;L[f+32>>3]=B;L[f+24>>3]=z;L[f+16>>3]=A;c=(c|0)==3?3:(v|0)==3?3:0}if(!(!(g<0)|!(b<0))){L[f+152>>3]=C;L[f+144>>3]=D;L[f+136>>3]=F;L[f+72>>3]=I;L[f+64>>3]=H;L[f+56>>3]=m;L[f+32>>3]=p;L[f+24>>3]=o;L[f+16>>3]=n;c=(c|0)==2?2:(v|0)==2?2:1}J=J+1|0;if((J|0)!=27){continue}break}L[d>>3]=L[d>>3]+1;L[e>>3]=L[e>>3]+1;Fa=f+160|0;return 0}function Fl(){var a=0,b=0,c=0,d=0,e=0,f=0,g=0;c=Fa-4144|0;Fa=c;G[947121]=0;E[3805456]=0;b=1;e=Xb(Va(3780288)+1|0);Yb(3780288,e);a:{b:{switch(H[e|0]-33|0){case 10:b=4;G[951365]=4;d=e+1|0;break a;case 12:G[951365]=1;d=e+1|0;break a;case 0:b=2;G[951365]=2;d=e+1|0;break a;default:break b}}b=4;G[951365]=4;d=e}Za(3796768,d);a=G[950330];if(!a){Lb();a=G[950330]}a=G[(G[950332]+(a<<2)|0)-4>>2];G[a+4>>2]=G[a+4>>2]|b;a=jb(3796768,40);if(a){E[a|0]=0;d=1}else{d=0}G[950216]=d;Rl(3796768);Yb(3796768,e);Za(3796768,e);c:{d:{if(!nb(3796768,15735,3)){G[949192]=1970171489;G[949193]=7566700;b=1;break d}if(!nb(3796768,3720,3)){G[949192]=7892834;b=2;break d}b=3;if(!nb(3796768,10939,3)){a=H[22634]|H[22635]<<8|(H[22636]<<16|H[22637]<<24);E[3796771]=a;E[3796772]=a>>>8;E[3796773]=a>>>16;E[3796774]=a>>>24;G[949192]=H[22631]|H[22632]<<8|(H[22633]<<16|H[22634]<<24);break d}if(!nb(3796768,16766,3)){G[949192]=1768713317;G[949193]=6648688;b=4;break d}if(!nb(3796768,23671,3)){F[1898386]=H[26857]|H[26858]<<8;G[949192]=H[26853]|H[26854]<<8|(H[26855]<<16|H[26856]<<24);b=5;break d}if(!nb(3796768,15932,3)){E[3796772]=H[21334];G[949192]=H[21330]|H[21331]<<8|(H[21332]<<16|H[21333]<<24);b=6;break d}if(!nb(3796768,16003,3)){F[1898386]=H[31653]|H[31654]<<8;G[949192]=H[31649]|H[31650]<<8|(H[31651]<<16|H[31652]<<24);b=7;break d}if(!nb(3796768,31039,3)){a=H[31651]|H[31652]<<8|(H[31653]<<16|H[31654]<<24);E[3796771]=a;E[3796772]=a>>>8;E[3796773]=a>>>16;E[3796774]=a>>>24;G[949192]=H[31648]|H[31649]<<8|(H[31650]<<16|H[31651]<<24);b=8;break d}if(!nb(3796768,31035,3)){a=H[31644]|H[31645]<<8|(H[31646]<<16|H[31647]<<24);E[3796771]=a;E[3796772]=a>>>8;E[3796773]=a>>>16;E[3796774]=a>>>24;G[949192]=H[31641]|H[31642]<<8|(H[31643]<<16|H[31644]<<24);b=9;break d}if(!nb(3796768,31031,3)){a=H[31637]|H[31638]<<8|(H[31639]<<16|H[31640]<<24);E[3796771]=a;E[3796772]=a>>>8;E[3796773]=a>>>16;E[3796774]=a>>>24;G[949192]=H[31634]|H[31635]<<8|(H[31636]<<16|H[31637]<<24);b=10;break d}if(!nb(3796768,23667,3)){G[949192]=6646128;b=11;break d}if(!nb(3796768,13354,3)){F[1898386]=H[23669]|H[23670]<<8;G[949192]=H[23665]|H[23666]<<8|(H[23667]<<16|H[23668]<<24);b=11;break d}if(!nb(3796768,17346,3)){F[1898386]=H[4714]|H[4715]<<8;G[949192]=H[4710]|H[4711]<<8|(H[4712]<<16|H[4713]<<24);b=12;break d}if(nb(3796768,16721,3)){break c}G[949192]=2037149552;G[949193]=7237479;b=13}G[948156]=b}a=G[G[950220]+104>>2];if(!(!a|!H[a|0])){if(!G[950330]){Lb()}d=a;a=Xb(Va(a)+1|0);Yb(d,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a)}if(!G[950330]){Lb()}a=Xb(3);Yb(16241,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a);a=G[(G[950332]+(G[950330]<<2)|0)-4>>2];G[a+48>>2]=0;f=a,g=Va(G[a+24>>2]),G[f+28>>2]=g;a=G[950220];if(a){b=G[a+152>>2];if(b){d=Ja[b|0](a,3796768)|0}else{d=3796768}}else{d=0}Te(d);if(!G[950330]){Lb()}a=Xb(8);Yb(48929,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a);e:{f:{g:{h:{switch(G[951365]-1|0){case 3:G[c>>2]=4;Ya(c+48|0,4096,30095,c);if(!H[c+48|0]){break e}if(!G[950330]){break g}break f;case 1:G[c+16>>2]=2;Ya(c+48|0,4096,30100,c+16|0);if(!H[c+48|0]){break e}if(!G[950330]){break g}break f;case 0:break h;default:break e}}G[c+32>>2]=1;Ya(c+48|0,4096,30100,c+32|0);if(!H[c+48|0]){break e}if(G[950330]){break f}}Lb()}b=c+48|0;a=Xb(Va(b)+1|0);Yb(b,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a)}if(!G[950330]){Lb()}a=Xb(2);Yb(49008,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a);if(G[G[950220]+4>>2]==1){if(!G[950330]){Lb()}a=Xb(9);Yb(60969,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a)}if(!G[950330]){Lb()}a=Xb(2);Yb(3870,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a);if(!G[950330]){Lb()}a=Xb(2);Yb(49008,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a);if(G[G[950220]+4>>2]==1){if(!G[950330]){Lb()}a=Xb(9);Yb(60969,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a)}if(!G[950330]){Lb()}a=Xb(2);Yb(3696,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a);pb(e);Fa=c+4144|0}function Cb(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0;g=Fa-192|0;Fa=g;h=G[f>>2];if((h|0)<=0){a:{b:{switch(b-11|0){case 5:E[g+16|0]=0;c:{if(e){E[e|0]=0;if(G[f>>2]>0){break c}}if((kc(a,c,g+96|0,f)|0)>0){break c}mc(g+96|0,g+16|0,e,f)}E[d|0]=0;fd(g+16|0,d,f);break a;case 0:E[g+16|0]=0;d:{if(e){E[e|0]=0;if(G[f>>2]>0){break d}}if((kc(a,c,g+96|0,f)|0)>0){break d}mc(g+96|0,g+16|0,e,f)}Ie(g+16|0,g+8|0,f);if(G[f>>2]>0){break a}a=G[g+12>>2];b=G[g+8>>2];if(!a&b>>>0>=256|a){G[f>>2]=412;break a}E[d|0]=b;break a;case 1:E[g+16|0]=0;e:{if(e){E[e|0]=0;if(G[f>>2]>0){break e}}if((kc(a,c,g+96|0,f)|0)>0){break e}mc(g+96|0,g+16|0,e,f)}Ie(g+16|0,g+8|0,f);if(G[f>>2]>0){break a}b=G[g+8>>2];a=G[g+12>>2]-(b>>>0<128)|0;c=b-128|0;if((a|0)==-1&c>>>0<=4294967039|(a|0)!=-1){G[f>>2]=412;break a}E[d|0]=b;break a;case 9:E[g+16|0]=0;f:{if(e){E[e|0]=0;if(G[f>>2]>0){break f}}if((kc(a,c,g+96|0,f)|0)>0){break f}mc(g+96|0,g+16|0,e,f)}Ie(g+16|0,g+8|0,f);if(G[f>>2]>0){break a}a=G[g+12>>2];b=G[g+8>>2];if(!a&b>>>0>=65536|a){G[f>>2]=412;break a}F[d>>1]=b;break a;case 10:E[g+16|0]=0;g:{if(e){E[e|0]=0;if(G[f>>2]>0){break g}}if((kc(a,c,g+96|0,f)|0)>0){break g}mc(g+96|0,g+16|0,e,f)}Ie(g+16|0,g+8|0,f);if(G[f>>2]>0){break a}b=G[g+8>>2];a=G[g+12>>2]-(b>>>0<32768)|0;c=b-32768|0;if((a|0)==-1&c>>>0<=4294901759|(a|0)!=-1){G[f>>2]=412;break a}F[d>>1]=b;break a;case 19:E[g+16|0]=0;h:{if(e){E[e|0]=0;if(G[f>>2]>0){break h}}if((kc(a,c,g+96|0,f)|0)>0){break h}mc(g+96|0,g+16|0,e,f)}Ie(g+16|0,g+8|0,f);if(G[f>>2]>0){break a}G[f>>2]=412;break a;case 20:E[g+16|0]=0;i:{if(e){E[e|0]=0;if(G[f>>2]>0){break i}}if((kc(a,c,g+96|0,f)|0)>0){break i}mc(g+96|0,g+16|0,e,f)}Ie(g+16|0,g+8|0,f);if(G[f>>2]>0){break a}b=G[g+8>>2];a=G[g+12>>2]-(b>>>0<2147483648)|0;if((a|0)==-2|a>>>0<4294967294){G[f>>2]=412;break a}G[d>>2]=b;break a;case 3:E[g+16|0]=0;j:{if(e){E[e|0]=0;if(G[f>>2]>0){break j}}if((kc(a,c,g+96|0,f)|0)>0){break j}mc(g+96|0,g+16|0,e,f)}Wn(g+16|0,d,f);break a;case 29:E[g+16|0]=0;k:{if(e){E[e|0]=0;if(G[f>>2]>0){break k}}if((kc(a,c,g+96|0,f)|0)>0){break k}mc(g+96|0,g+16|0,e,f)}Xn(g+16|0,g+96|0,f);if(G[f>>2]>0){break a}b=G[g+96>>2];a=G[g+100>>2];if((a|0)==1|a>>>0>1){G[f>>2]=412;break a}G[d>>2]=b;break a;case 30:E[g+16|0]=0;l:{if(e){E[e|0]=0;if(G[f>>2]>0){break l}}if((kc(a,c,g+96|0,f)|0)>0){break l}mc(g+96|0,g+16|0,e,f)}Ie(g+16|0,g+8|0,f);if(G[f>>2]>0){break a}h=G[g+8>>2];b=G[g+12>>2]-(h>>>0<2147483648)|0;if((b|0)==-2|b>>>0<4294967294){G[f>>2]=412;break a}G[d>>2]=h;if(G[f>>2]>0){break a}E[g+16|0]=0;m:{if(e){E[e|0]=0;if(G[f>>2]>0){break m}}if((kc(a,c,g+96|0,f)|0)>0){break m}mc(g+96|0,g+16|0,e,f)}lk(g+16|0,d,f);break a;case 69:E[g+16|0]=0;n:{if(e){E[e|0]=0;if(G[f>>2]>0){break n}}if((kc(a,c,g+96|0,f)|0)>0){break n}mc(g+96|0,g+16|0,e,f)}Xn(g+16|0,d,f);break a;case 70:E[g+16|0]=0;o:{if(e){E[e|0]=0;if(G[f>>2]>0){break o}}if((kc(a,c,g+96|0,f)|0)>0){break o}mc(g+96|0,g+16|0,e,f)}Ie(g+16|0,d,f);break a;case 31:E[g+16|0]=0;p:{if(e){E[e|0]=0;if(G[f>>2]>0){break p}}if((kc(a,c,g+96|0,f)|0)>0){break p}mc(g+96|0,g+16|0,e,f)}kk(g+16|0,d,f);break a;case 71:E[g+16|0]=0;q:{if(e){E[e|0]=0;if(G[f>>2]>0){break q}}if((kc(a,c,g+96|0,f)|0)>0){break q}mc(g+96|0,g+16|0,e,f)}wi(g+16|0,d,f);break a;case 72:b=Fa-192|0;Fa=b;r:{if(G[f>>2]>0){break r}E[b+16|0]=0;s:{t:{if(e){E[e|0]=0;if(G[f>>2]>0){break t}}if((kc(a,c,b+96|0,f)|0)>0){break t}mc(b+96|0,b+16|0,e,f);if(H[b+16|0]==40){break s}}G[b>>2]=c;a=b+96|0;Ya(a,81,39915,b);Ua(a);Ua(b+16|0);G[f>>2]=408;break r}E[b+16|0]=32;a=b+16|0;i=qc(a,64244)+a|0,j=0,E[i|0]=j;c=qc(a,49008)+a|0;E[c|0]=0;kk(a,d,f);kk(c+1|0,d+4|0,f)}Fa=b+192|0;break a;case 152:b=Fa-192|0;Fa=b;u:{if(G[f>>2]>0){break u}E[b+16|0]=0;v:{w:{if(e){E[e|0]=0;if(G[f>>2]>0){break w}}if((kc(a,c,b+96|0,f)|0)>0){break w}mc(b+96|0,b+16|0,e,f);if(H[b+16|0]==40){break v}}G[b>>2]=c;a=b+96|0;Ya(a,81,39864,b);Ua(a);Ua(b+16|0);G[f>>2]=409;break u}E[b+16|0]=32;a=b+16|0;i=qc(a,64244)+a|0,j=0,E[i|0]=j;c=qc(a,49008)+a|0;E[c|0]=0;wi(a,d,f);wi(c+1|0,d+8|0,f)}Fa=b+192|0;break a;default:break b}}G[f>>2]=410}h=G[f>>2]}Fa=g+192|0;return h|0}function _s(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;a:{if((c|0)!=1){break a}bb(1238296,g,168);G[309616]=G[309614];G[309565]=G[f+88>>2];c=G[309576];b:{if((c|0)<2){break b}G[309566]=G[f+332>>2];G[309570]=G[309582];c=G[309576];if((c|0)<3){break b}G[309567]=G[f+576>>2];G[309571]=M(G[309583],G[309570]);c=G[309576];if((c|0)<4){break b}G[309568]=G[f+820>>2];G[309572]=M(G[309584],G[309571]);c=G[309576]}if((c|0)>=(e|0)){break a}G[309569]=G[(M(c,244)+f|0)+88>>2]}if((d|0)>0){f=G[309569];l=G[309572];m=G[309568];n=G[309571];o=G[309567];p=G[309570];q=G[309566];r=G[309565];c=G[309616];g=1;while(1){a=g;g=0;c:{if(c){b=H[c|0];g=c+1|0;G[309616]=g;c=g;if(!b){break c}}c=g;e=a<<3;h=L[e+r>>3];if(h==-91191291391491e-49){break c}h=(h-L[154793])/L[154801];k=h+1;d:{if(O(k)<2147483648){g=~~k;break d}g=-2147483648}if((g|0)<=0|G[309582]<(g|0)|h>L[154797]){break c}i=G[309576];e:{if((i|0)<2){break e}h=L[e+q>>3];if(h==-91191291391491e-49){break c}h=(h-L[154794])/L[154802];j=h<0;if(O(h)<2147483648){b=~~h}else{b=-2147483648}if((b|0)>=G[309583]|h>L[154798]|j){break c}g=M(b,p)+g|0;if(i>>>0<3){break e}h=L[e+o>>3];if(h==-91191291391491e-49){break c}h=(h-L[154795])/L[154803];j=h<0;if(O(h)<2147483648){b=~~h}else{b=-2147483648}if((b|0)>=G[309584]|h>L[154799]|j){break c}g=M(b,n)+g|0;if(i>>>0<4){break e}h=L[e+m>>3];if(h==-91191291391491e-49){break c}h=(h-L[154796])/L[154804];i=h<0;if(O(h)<2147483648){b=~~h}else{b=-2147483648}if((b|0)>=G[309585]|h>L[154800]|i){break c}g=M(b,l)+g|0}h=L[154806];if(h!=-91191291391491e-49){f:{g:{h:{i:{j:{b=G[309581];switch(b-11|0){case 0:break f;case 31:break g;case 10:break h;case 20:break i;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:break c;default:break j}}if((b|0)!=82){break c}b=G[309574]+(g<<3)|0;L[b>>3]=h+L[b>>3];break c}b=G[309574]+(g<<2)|0;g=G[b>>2];if(O(h)<2147483648){e=~~h}else{e=-2147483648}G[b>>2]=e+g;break c}b=G[309574]+(g<<1)|0;g=I[b>>1];if(O(h)<2147483648){e=~~h}else{e=-2147483648}F[b>>1]=e+g;break c}b=G[309574]+(g<<2)|0;K[b>>2]=h+ +K[b>>2];break c}b=G[309574]+g|0;g=H[b|0];if(O(h)<2147483648){e=~~h}else{e=-2147483648}E[b|0]=e+g;break c}b=G[309581];if(G[309610]){k:{switch(b-11|0){default:if((b|0)!=82){break c}b=G[309574]+(g<<3)|0;L[b>>3]=1/L[e+f>>3]+L[b>>3];break c;case 20:b=G[309574]+(g<<2)|0;g=G[b>>2];h=1/L[e+f>>3];l:{if(O(h)<2147483648){e=~~h;break l}e=-2147483648}G[b>>2]=e+g;break c;case 10:b=G[309574]+(g<<1)|0;g=I[b>>1];h=1/L[e+f>>3];m:{if(O(h)<2147483648){e=~~h;break m}e=-2147483648}F[b>>1]=e+g;break c;case 31:b=G[309574]+(g<<2)|0;K[b>>2]=K[b>>2]+N(1/L[e+f>>3]);break c;case 0:break k;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:break c}}b=G[309574]+g|0;g=H[b|0];h=1/L[e+f>>3];n:{if(O(h)<2147483648){e=~~h;break n}e=-2147483648}E[b|0]=e+g;break c}o:{switch(b-11|0){default:if((b|0)!=82){break c}b=G[309574]+(g<<3)|0;L[b>>3]=L[e+f>>3]+L[b>>3];break c;case 20:b=G[309574]+(g<<2)|0;g=G[b>>2];h=L[e+f>>3];p:{if(O(h)<2147483648){e=~~h;break p}e=-2147483648}G[b>>2]=e+g;break c;case 10:b=G[309574]+(g<<1)|0;g=I[b>>1];h=L[e+f>>3];q:{if(O(h)<2147483648){e=~~h;break q}e=-2147483648}F[b>>1]=e+g;break c;case 31:b=G[309574]+(g<<2)|0;K[b>>2]=L[e+f>>3]+ +K[b>>2];break c;case 0:break o;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:break c}}b=G[309574]+g|0;g=H[b|0];h=L[e+f>>3];r:{if(O(h)<2147483648){e=~~h;break r}e=-2147483648}E[b|0]=e+g}g=a+1|0;if((a|0)!=(d|0)){continue}break}}return 0}function Pl(a,b){var c=0,d=0,e=0,f=0,g=0,h=0;c=Fa-864|0;Fa=c;G[c+460>>2]=0;g=G[29763];d=g;a:{if(!Rc(c+860|0,a,0,c+460|0)){d=g;b:{if(!b|!H[b|0]){break b}d=ac(b,4017);if(d){break b}G[c+352>>2]=b;_a(G[24367],69497,c+352|0);break a}mb(G[c+860>>2],1,c+452|0,c+460|0);G[c+456>>2]=G[G[c+860>>2]>>2]+1;G[c+456>>2]=G[c+456>>2]-1;Ub(91,d);c:{if(G[c+460>>2]){break c}while(1){Ub(123,d);a=c+460|0;Dc(G[c+860>>2],c+452|0,a);G[c+336>>2]=G[c+456>>2];_a(d,30059,c+336|0);Cb(G[c+860>>2],16,35480,c+784|0,0,a);if(!G[c+460>>2]){G[c+320>>2]=c+784;_a(d,65529,c+320|0)}G[c+460>>2]=0;a=G[c+860>>2];d:{if(!G[c+452>>2]){mh(a,10,c+448|0,c+444|0,c+384|0,c+460|0);G[c+240>>2]=G[c+444>>2];_a(d,30068,c+240|0);hb(32644,10,1,d);e:{if(G[c+444>>2]<=0){break e}G[c+224>>2]=G[c+384>>2];_a(d,27698,c+224|0);a=1;if(G[c+444>>2]<2){break e}while(1){Ub(44,d);G[c+208>>2]=G[(c+384|0)+(a<<2)>>2];_a(d,27698,c+208|0);a=a+1|0;if((a|0)>2]){continue}break}}Ub(93,d);G[c+192>>2]=G[c+448>>2];_a(d,30046,c+192|0);a=1;while(1){G[c+436>>2]=0;b=c+544|0;e=c+436|0;zb(35417,a,b,e);Cb(G[c+860>>2],16,b,c+624|0,0,e);if(!G[c+436>>2]){G[c+180>>2]=c+624;G[c+176>>2]=c+544;_a(d,65493,c+176|0)}G[c+436>>2]=0;b=c+544|0;e=c+436|0;zb(33363,a,b,e);Cb(G[c+860>>2],16,b,c+624|0,0,e);if(!G[c+436>>2]){G[c+164>>2]=c+624;G[c+160>>2]=c+544;_a(d,65493,c+160|0)}G[c+436>>2]=0;b=c+544|0;e=c+436|0;zb(32948,a,b,e);Cb(G[c+860>>2],82,b,c+368|0,0,e);if(!G[c+436>>2]){L[c+152>>3]=L[c+368>>3];G[c+144>>2]=c+544;xb(d,19664,c+144|0)}G[c+436>>2]=0;b=c+544|0;e=c+436|0;zb(34813,a,b,e);Cb(G[c+860>>2],82,b,c+368|0,0,e);if(!G[c+436>>2]){L[c+136>>3]=L[c+368>>3];G[c+128>>2]=c+544;xb(d,19664,c+128|0)}G[c+436>>2]=0;b=c+544|0;e=c+436|0;zb(33351,a,b,e);Cb(G[c+860>>2],82,b,c+368|0,0,e);if(!G[c+436>>2]){L[c+120>>3]=L[c+368>>3];G[c+112>>2]=c+544;xb(d,19664,c+112|0)}G[c+436>>2]=0;b=c+544|0;e=c+436|0;zb(35922,a,b,e);Cb(G[c+860>>2],82,b,c+368|0,0,e);if(!G[c+436>>2]){L[c+104>>3]=L[c+368>>3];G[c+96>>2]=c+544;xb(d,19664,c+96|0)}G[c+80>>2]=a;G[c+436>>2]=0;b=c+464|0;Ya(b,75,31909,c+80|0);f=b;b=c+544|0;e=c+436|0;zb(f,1,b,e);Cb(G[c+860>>2],82,b,c+368|0,0,e);if(!G[c+436>>2]){L[c+72>>3]=L[c+368>>3];G[c+64>>2]=c+544;xb(d,19664,c- -64|0)}G[c+48>>2]=a;G[c+436>>2]=0;b=c+464|0;Ya(b,75,31909,c+48|0);f=b;b=c+544|0;e=c+436|0;zb(f,2,b,e);Cb(G[c+860>>2],82,b,c+368|0,0,e);if(!G[c+436>>2]){L[c+40>>3]=L[c+368>>3];G[c+32>>2]=c+544;xb(d,19664,c+32|0)}a=a+1|0;if((a|0)!=3){continue}break}G[c+436>>2]=0;a=H[33588]|H[33589]<<8|(H[33590]<<16|H[33591]<<24);G[c+544>>2]=H[33584]|H[33585]<<8|(H[33586]<<16|H[33587]<<24);G[c+548>>2]=a;E[c+552|0]=H[33592];Cb(G[c+860>>2],16,c+544|0,c+624|0,0,c+436|0);if(!G[c+436>>2]){G[c+20>>2]=c+624;G[c+16>>2]=c+544;_a(d,65493,c+16|0)}G[c+544>>2]=1230328133;G[c+548>>2]=5787470;G[c+436>>2]=0;Cb(G[c+860>>2],16,c+544|0,c+624|0,0,c+436|0);if(G[c+436>>2]){break d}G[c+4>>2]=c+624;G[c>>2]=c+544;_a(d,65493,c);break d}b=a;a=c+460|0;zi(b,c+380|0,a);pk(G[c+860>>2],c+440|0,a);a=1;hb(G[c+452>>2]==1?65548:65571,15,1,d);G[c+304>>2]=G[c+380>>2];_a(d,26864,c+304|0);hb(32634,9,1,d);if(G[c+440>>2]>0){while(1){b=c+544|0;e=c+460|0;zb(35402,a,b,e);f=c+784|0;Cb(G[c+860>>2],16,b,f,0,e);zb(34641,a,b,e);h=c+704|0;Cb(G[c+860>>2],16,b,h,0,e);G[c+292>>2]=h;G[c+288>>2]=f;_a(d,65504,c+288|0);G[c+436>>2]=0;e=c+436|0;zb(34547,a,b,e);Cb(G[c+860>>2],16,b,c+624|0,0,e);if(!G[c+436>>2]){G[c+272>>2]=c+624;_a(d,8768,c+272|0)}G[c+436>>2]=0;b=c+544|0;e=c+436|0;zb(33036,a,b,e);Cb(G[c+860>>2],16,b,c+624|0,0,e);if(!G[c+436>>2]){G[c+256>>2]=c+624;_a(d,8758,c+256|0)}Ub(125,d);if(G[c+440>>2]!=(a|0)){Ub(44,d);b=G[c+440>>2]}else{b=a}b=(b|0)>(a|0);a=a+1|0;if(b){continue}break}}Ub(93,d)}Ub(125,d);xi(G[c+860>>2],0,c+460|0);if(G[c+460>>2]){G[c+456>>2]=G[c+456>>2]+1;break c}Ub(44,d);G[c+456>>2]=G[c+456>>2]+1;if(!G[c+460>>2]){continue}break}}Ub(93,d);if(G[c+460>>2]==107){G[c+460>>2]=0}Qb(G[c+860>>2],c+460|0)}a=G[c+460>>2];if(a){wf(G[24367],a)}f:{if((d|0)==(g|0)){$a(g);break f}Hb(d)}}Fa=c+864|0}function Pk(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;i=Fa+-64|0;G[i+48>>2]=0;G[i+52>>2]=0;G[i+56>>2]=0;G[i+60>>2]=0;G[i+32>>2]=0;G[i+36>>2]=0;G[i+40>>2]=0;G[i+44>>2]=0;a:{b:{c:{d:{e:{if(c){if(c-1>>>0>=3){n=c&-4;while(1){m=i+32|0;l=k<<1;h=m+(I[l+b>>1]<<1)|0;F[h>>1]=I[h>>1]+1;h=m+(I[(l|2)+b>>1]<<1)|0;F[h>>1]=I[h>>1]+1;h=m+(I[(l|4)+b>>1]<<1)|0;F[h>>1]=I[h>>1]+1;h=m+(I[(l|6)+b>>1]<<1)|0;F[h>>1]=I[h>>1]+1;k=k+4|0;g=g+4|0;if((n|0)!=(g|0)){continue}break}}h=c&3;if(h){while(1){g=(i+32|0)+(I[(k<<1)+b>>1]<<1)|0;F[g>>1]=I[g>>1]+1;k=k+1|0;j=j+1|0;if((h|0)!=(j|0)){continue}break}}k=G[e>>2];l=15;g=I[i+62>>1];if(g){break d}break e}k=G[e>>2]}l=14;g=0;if(I[i+60>>1]){break d}l=13;if(I[i+58>>1]){break d}l=12;if(I[i+56>>1]){break d}l=11;if(I[i+54>>1]){break d}l=10;if(I[i+52>>1]){break d}l=9;if(I[i+50>>1]){break d}l=8;if(I[i+48>>1]){break d}l=7;if(I[i+46>>1]){break d}l=6;if(I[i+44>>1]){break d}l=5;if(I[i+42>>1]){break d}l=4;if(I[i+40>>1]){break d}l=3;if(I[i+38>>1]){break d}l=2;if(I[i+36>>1]){break d}if(!I[i+34>>1]){a=G[d>>2];G[d>>2]=a+4;F[a>>1]=320;F[a+2>>1]=0;a=G[d>>2];G[d>>2]=a+4;F[a>>1]=320;F[a+2>>1]=0;m=1;break b}r=(k|0)!=0;l=1;k=1;break c}r=k>>>0>>0?k:l;p=1;k=1;while(1){if(I[(i+32|0)+(k<<1)>>1]){break c}k=k+1|0;if((l|0)!=(k|0)){continue}break}k=l}j=-1;o=I[i+34>>1];if(o>>>0>2){break a}s=I[i+36>>1];h=4-(s+(o<<1)|0)|0;if((h|0)<0){break a}q=I[i+38>>1];h=(h<<1)-q|0;if((h|0)<0){break a}t=I[i+40>>1];h=(h<<1)-t|0;if((h|0)<0){break a}u=I[i+42>>1];h=(h<<1)-u|0;if((h|0)<0){break a}w=I[i+44>>1];h=(h<<1)-w|0;if((h|0)<0){break a}x=I[i+46>>1];h=(h<<1)-x|0;if((h|0)<0){break a}z=I[i+48>>1];h=(h<<1)-z|0;if((h|0)<0){break a}A=I[i+50>>1];h=(h<<1)-A|0;if((h|0)<0){break a}y=I[i+52>>1];h=(h<<1)-y|0;if((h|0)<0){break a}B=I[i+54>>1];h=(h<<1)-B|0;if((h|0)<0){break a}v=I[i+56>>1];h=(h<<1)-v|0;if((h|0)<0){break a}m=I[i+58>>1];h=(h<<1)-m|0;if((h|0)<0){break a}n=I[i+60>>1];h=(h<<1)-n|0;if((h|0)<0){break a}h=h<<1;if(h>>>0>>0|(!a|p?(g|0)!=(h|0):0)){break a}C=k>>>0>>0;j=0;F[i+2>>1]=0;F[i+4>>1]=o;g=o+s|0;F[i+6>>1]=g;g=g+q|0;F[i+8>>1]=g;g=g+t|0;F[i+10>>1]=g;g=g+u|0;F[i+12>>1]=g;g=g+w|0;F[i+14>>1]=g;g=g+x|0;F[i+16>>1]=g;g=g+z|0;F[i+18>>1]=g;g=g+A|0;F[i+20>>1]=g;g=g+y|0;F[i+22>>1]=g;g=g+B|0;F[i+24>>1]=g;g=g+v|0;F[i+26>>1]=g;g=g+m|0;F[i+28>>1]=g;F[i+30>>1]=g+n;f:{if(!c){break f}if((c|0)!=1){m=c&-2;g=0;while(1){h=I[(j<<1)+b>>1];if(h){h=(h<<1)+i|0;n=I[h>>1];F[h>>1]=n+1;F[(n<<1)+f>>1]=j}n=j|1;h=I[(n<<1)+b>>1];if(h){h=(h<<1)+i|0;v=I[h>>1];F[h>>1]=v+1;F[(v<<1)+f>>1]=n}j=j+2|0;g=g+2|0;if((m|0)!=(g|0)){continue}break}}if(!(c&1)){break f}c=I[(j<<1)+b>>1];if(!c){break f}c=(c<<1)+i|0;g=I[c>>1];F[c>>1]=g+1;F[(g<<1)+f>>1]=j}m=C?r:k;s=20;z=0;n=f;w=n;A=0;g:{h:{switch(a|0){case 1:j=1;if(m>>>0>9){break a}s=257;w=113280;n=113216;A=1;break g;case 0:break g;default:break h}}z=(a|0)==2;s=0;w=113408;n=113344;if((a|0)!=2){break g}j=1;if(m>>>0>9){break a}}q=1<>2];u=0;g=m;o=0;p=0;a=-1;while(1){h=1<>1];c=0;j:{if(g+1>>>0>>0){break j}if(g>>>0>>0){g=0;c=96;break j}c=g-s<<1;g=I[c+n>>1];c=H[c+w|0]}v=p>>>o|0;C=-1<>1]=g;E[y+1|0]=x;E[y|0]=c;if(j){continue}break}g=1<>>1|0;if(c&p){continue}break}g=(i+32|0)+(k<<1)|0;j=I[g>>1]-1|0;F[g>>1]=j;p=c?c+(c-1&p)|0:0;u=u+1|0;if(!(j&65535)){if((k|0)==(l|0)){break i}k=I[(I[(u<<1)+f>>1]<<1)+b>>1]}if(k>>>0<=m>>>0){continue}c=p&B;if((c|0)==(a|0)){continue}break}o=o?o:m;g=k-o|0;r=1<>>0>>0){a=l-o|0;j=k;k:{while(1){j=r-I[(i+32|0)+(j<<1)>>1]|0;if((j|0)<=0){break k}r=j<<1;g=g+1|0;j=o+g|0;if(l>>>0>j>>>0){continue}break}g=a}r=1<>>0>852&A|q>>>0>592&z){break a}a=G[d>>2];j=a+(c<<2)|0;E[j+1|0]=m;E[j|0]=g;t=(h<<2)+t|0;F[j+2>>1]=t-a>>>2;a=c;continue}break}if(p){a=(p<<2)+t|0;F[a+2>>1]=0;E[a+1|0]=x;E[a|0]=64}G[d>>2]=G[d>>2]+(q<<2)}G[e>>2]=m;j=0}return j}function Kr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,H=0,I=0,J=0;f=Fa-160|0;Fa=f;if(G[c+4>>2]!=803){G[c+1892>>2]=107;G[c+1888>>2]=108;E[c|0]=84;E[c+1|0]=79;E[c+2|0]=65;E[c+3|0]=0;E[c+4|0]=35;E[c+5|0]=3;E[c+6|0]=0;E[c+7|0]=0}g=L[c+40>>3];a:{if(O(g)<2147483648){t=~~g;break a}t=-2147483648}c=2;b:{if(a<0){break b}t=1<g){break b}g=+(t|0);b=(b+-1)/g*134217728+.5;c:{if(O(b)<2147483648){c=~~b;break c}c=-2147483648}J=c;n=J>>>26&1;a=(a+-1)/g*134217728+.5;d:{if(O(a)<2147483648){t=~~a;break d}t=-2147483648}c=t>>>26&1;e:{if(!(n|c)){G[f+128>>2]=0;G[f+132>>2]=0;G[f+88>>2]=0;G[f+92>>2]=1079410688;G[f+48>>2]=0;G[f+52>>2]=0;G[f+120>>2]=0;G[f+124>>2]=1080459264;G[f+80>>2]=0;G[f+84>>2]=0;G[f+40>>2]=0;G[f+44>>2]=1081139200;G[f+8>>2]=0;G[f+12>>2]=-1068072960;G[f>>2]=0;G[f+4>>2]=0;c=1;b=4.71238898038469;r=1.5707963267948966;m=3.141592653589793;g=-1.5707963267948966;a=0;break e}if(!(n|!c)){G[f+48>>2]=0;G[f+52>>2]=-1068072960;G[f+88>>2]=0;G[f+92>>2]=0;G[f+128>>2]=0;G[f+132>>2]=1079410688;G[f+120>>2]=0;G[f+124>>2]=0;G[f+40>>2]=0;G[f+44>>2]=0;G[f+8>>2]=0;G[f+12>>2]=0;G[f>>2]=0;G[f+4>>2]=1081139200;G[f+80>>2]=0;G[f+84>>2]=0;c=0;l=4.71238898038469;j=-1.5707963267948966;b=0;g=0;a=1.5707963267948966;break e}if(!(!n|c)){G[f+128>>2]=0;G[f+132>>2]=-1068072960;G[f+88>>2]=0;G[f+92>>2]=0;G[f+48>>2]=0;G[f+52>>2]=1079410688;G[f+120>>2]=0;G[f+124>>2]=0;G[f+80>>2]=0;G[f+84>>2]=1079410688;G[f+40>>2]=0;G[f+44>>2]=0;G[f+8>>2]=0;G[f+12>>2]=0;G[f>>2]=0;G[f+4>>2]=1080459264;c=0;l=3.141592653589793;h=1.5707963267948966;b=0;j=1.5707963267948966;g=0;a=-1.5707963267948966;break e}G[f+48>>2]=0;G[f+52>>2]=0;G[f+128>>2]=0;G[f+132>>2]=0;G[f+88>>2]=0;G[f+92>>2]=-1068072960;G[f+80>>2]=0;G[f+84>>2]=0;G[f+8>>2]=0;G[f+12>>2]=1079410688;G[f>>2]=0;G[f+4>>2]=0;G[f+40>>2]=0;G[f+44>>2]=0;G[f+120>>2]=0;G[f+124>>2]=1079410688;c=1;r=-1.5707963267948966;m=1.5707963267948966;b=0;g=1.5707963267948966;a=0}u=ib(a);L[f+152>>3]=u;v=ib(r);L[f+112>>3]=v;k=ib(j);L[f+72>>3]=k;a=eb(a);w=a*ib(m);L[f+144>>3]=w;x=a*eb(m);L[f+136>>3]=x;a=eb(r);y=a*ib(h);L[f+104>>3]=y;s=a*eb(h);L[f+96>>3]=s;a=eb(j);r=a*ib(b);L[f- -64>>3]=r;m=a*eb(b);L[f+56>>3]=m;j=ib(g);L[f+32>>3]=j;a=eb(g);h=a*ib(l);L[f+24>>3]=h;l=a*eb(l);L[f+16>>3]=l;H=27;I=1;while(1){z=M(c,40)+f|0;A=c+2&3;n=M(A,40)+f|0;a=L[z+32>>3]+L[n+32>>3];g=a;i=L[z+16>>3]+L[n+16>>3];b=L[z+24>>3]+L[n+24>>3];a=V(a*a+(i*i+b*b));a=a==0?1:a;g=g/a;b=b/a;a=i/a;o=j+u;p=l+x;q=h+w;i=V(o*o+(p*p+q*q));i=i==0?1:i;B=o/i;C=q/i;D=p/i;o=k+j;p=m+l;q=r+h;i=V(o*o+(p*p+q*q));i=i==0?1:i;F=o/i;o=q/i;p=p/i;n=H-2|0;z=J>>>n&1;n=t>>>n&1;f:{if(!(z|n)){L[f+152>>3]=B;L[f+144>>3]=C;L[f+136>>3]=D;L[f+112>>3]=g;L[f+104>>3]=b;L[f+96>>3]=a;L[f+72>>3]=F;L[f+64>>3]=o;L[f+56>>3]=p;u=B;w=C;x=D;v=g;y=b;s=a;k=F;r=o;m=p;c=(c|0)!=0&(A|0)!=0;break f}l=k+v;i=m+s;j=r+y;h=V(l*l+(i*i+j*j));h=h==0?1:h;q=l/h;l=j/h;i=i/h;if(!(!n|z)){L[f+152>>3]=g;L[f+144>>3]=b;L[f+136>>3]=a;L[f+112>>3]=q;L[f+104>>3]=l;L[f+96>>3]=i;L[f+32>>3]=F;L[f+24>>3]=o;L[f+16>>3]=p;u=g;w=b;x=a;v=q;y=l;s=i;j=F;h=o;l=p;c=(c|0)==1|(A|0)==1;break f}j=v+u;m=s+x;h=y+w;k=V(j*j+(m*m+h*h));k=k==0?1:k;j=j/k;h=h/k;k=m/k;if(!(n|!z)){L[f+112>>3]=j;L[f+104>>3]=h;L[f+96>>3]=k;L[f+72>>3]=g;L[f+64>>3]=b;L[f+56>>3]=a;L[f+32>>3]=B;L[f+24>>3]=C;L[f+16>>3]=D;v=j;y=h;s=k;j=B;k=g;h=C;r=b;l=D;m=a;c=(c|0)==3?3:(A|0)==3?3:0;break f}L[f+152>>3]=j;L[f+144>>3]=h;L[f+136>>3]=k;L[f+72>>3]=q;L[f+64>>3]=l;L[f+56>>3]=i;L[f+32>>3]=g;L[f+24>>3]=b;L[f+16>>3]=a;u=j;w=h;x=k;j=g;k=q;h=b;r=l;l=a;m=i;c=(c|0)==2?2:(A|0)==2?2:1}H=H-1|0;I=I+1|0;if((I|0)!=27){continue}break}k=j+k+v+u;g=l+m+s+x;b=h+r+y+w;a=V(k*k+(g*g+b*b));s=a==0?1:a;a=Db(b/s,g/s);b=fc(k/s);a=a/.017453292519943295;if(a>=360){while(1){a=a+-360;if(a>=360){continue}break}}if(a<0){while(1){a=a+360;if(a<0){continue}break}}L[d>>3]=a;L[e>>3]=b/.017453292519943295;c=0}Fa=f+160|0;return c|0}function pi(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;q=G[c>>2];if((q|0)>0){c=G[c+4>>2];r=G[c+8>>2];while(1){k=G[c+8>>2];if(!((k|0)==(r|0)?p:0)){s=(g|s)!=0;g=!H[c|0];r=k}k=H[c|0];a:{b:{if(!g){if(k){break b}g=0;break a}g=1;if(k){break a}k=0}g=1;c:{d:{switch(G[c+4>>2]){case 6:f=a-L[c+48>>3];e=L[c+144>>3];h=b-L[c+56>>3];i=L[c+136>>3];j=f*e+h*i;d=L[c- -64>>3]*.5;g=(j<-d^-1)&(d>3]*.5;g=g&(f<-d^-1)&!(d>3];h=L[c+144>>3];f=b-L[c+56>>3];i=L[c+136>>3];j=d*h+f*i;e=L[c+80>>3]*.5;if(j<-e|e>3]*.5;if(h<-e|e>3];i=L[c+152>>3];j=d*h+f*i;e=L[c- -64>>3]*.5;g=!(j>=-e)|!(e>=j);d=-d*i+f*h;e=L[c+72>>3]*.5;g=g|!(d>=-e)|!(d<=e);break c;case 8:f=a-L[c+88>>3];e=L[c+144>>3];h=b-L[c+96>>3];i=L[c+136>>3];j=f*e+h*i;d=L[c+152>>3];g=(j<-d^-1)&(d>3];g=g&(f<-d^-1)&!(d>3];f=L[c+144>>3];e=b-L[c+56>>3];h=L[c+136>>3];if(!(O((d*f+e*h)/(L[c- -64>>3]*.5))+O((e*f-d*h)/(L[c+72>>3]*.5))>1)){break c}g=0;break c;case 2:d=a-L[c+48>>3];e=d*d;d=b-L[c+56>>3];if(!(L[c+152>>3]>3];e=d*d;d=b-L[c+56>>3];d=e+d*d;if(!(d>L[c+160>>3]?1:d>3])){break c}g=0;break c;case 10:f=a-L[c+48>>3];d=b-L[c+56>>3];if(f==0&d==0){break c}d=Db(d,f)*180/3.141592653589793;f=L[c- -64>>3];e=L[c+72>>3];if(f<=e){g=!(d>e)&(de);break c;case 4:d=a-L[c+48>>3];f=L[c+144>>3];e=b-L[c+56>>3];h=L[c+136>>3];i=(d*f+e*h)/L[c- -64>>3];d=(e*f-d*h)/L[c+72>>3];if(!(i*i+d*d>1)){break c}g=0;break c;case 5:g=0;d=a-L[c+48>>3];e=L[c+144>>3];f=b-L[c+56>>3];h=L[c+136>>3];i=(d*e+f*h)/L[c+80>>3];e=(f*e-d*h)/L[c+88>>3];if(i*i+e*e>1){break c}g=1;e=L[c+160>>3];h=L[c+152>>3];i=(d*e+f*h)/L[c- -64>>3];d=(-d*h+f*e)/L[c+72>>3];if(!(i*i+d*d<1)){break c}g=0;break c;case 1:d=b-L[c+56>>3];f=L[c+144>>3];e=a-L[c+48>>3];h=L[c+136>>3];i=d*f-e*h;e:{if(i<-.5|i>=.5){break e}d=e*f+d*h;if(d<-.5){break e}if(!(d>=L[c+152>>3])){break c}}g=0;break c;case 0:d=a-L[c+48>>3];g=(d<-.5^-1)&(d>=.5^-1);d=b-L[c+56>>3];g=g&(d<-.5^-1)&!(d>=.5);break c;case 11:g=0;if(L[c+24>>3]>3]>a|(L[c+40>>3]>3]>b)){break c}o=G[c+48>>2];if((o|0)<=0){break c}l=G[c+52>>2];t=o-1|0;d=L[l+(t<<3)>>3];f=L[((o<<3)+l|0)-16>>3];m=0;while(1){e=f;f=L[(m<<3)+l>>3];h=d;n=m|1;d=L[(n<<3)+l>>3];f:{if(a>e&a>=f|(hf|a>=e)){break g}i=b-h;j=d-h;if(O(j)<1e-10){if(!(O(i)<1e-10)){break f}g=1;break c}e=(f-e)/j*i+e-a;if(e<-1e-10){break f}if(!(e<1e-10)){break g}g=1;break c}if(b==h){while(1){n=(n|0)>1?n-2|0:t;e=L[(n<<3)+l>>3];if(e==b){continue}break}if(!((d-b)*(b-e)>0)){break f}}g=1-g|0}m=m+2|0;if((o|0)>(m|0)){continue}break};break c;case 12:g=0;d=a-L[c+48>>3];f=b-L[c+56>>3];e=d*d+f*f;if(e>3]|e>L[c+160>>3]){break c}if(d==0){g=1;if(f==0){break c}}d=Db(f,d)*180/3.141592653589793;f=L[c- -64>>3];e=L[c+72>>3];if(f<=e){g=!(d>e)&(de);break c;case 13:g=0;f=a-L[c+48>>3];e=L[c+144>>3];h=b-L[c+56>>3];i=L[c+136>>3];d=f*e+h*i;j=d/L[c+104>>3];f=h*e-f*i;e=f/L[c+112>>3];if(j*j+e*e>1){break c}e=d/L[c+88>>3];h=e*e;e=f/L[c+96>>3];if(h+e*e<1){break c}if(d==0){g=1;if(f==0){break c}}d=Db(f,d)*180/3.141592653589793;f=L[c- -64>>3];e=L[c+72>>3];if(f<=e){g=!(d>e)&(de);break c;case 14:break d;default:break c}}g=0;e=a-L[c+48>>3];h=L[c+144>>3];i=b-L[c+56>>3];j=L[c+136>>3];d=e*h+i*j;f=L[c+104>>3]*.5;if(d<-f|d>f){break c}f=i*h-e*j;e=L[c+112>>3]*.5;if(f<-e|f>e){break c}e=L[c+88>>3]*.5;h:{if(!(d>=-e)|!(d<=e)){break h}e=L[c+96>>3]*.5;if(!(f>=-e)){break h}if(e>=f){break c}}if(d==0){g=1;if(f==0){break c}}d=Db(f,d)*180/3.141592653589793;f=L[c- -64>>3];e=L[c+72>>3];if(f<=e){g=!(d>e)&(de)}if(k){break a}g=!g}c=c+168|0;p=p+1|0;if((q|0)!=(p|0)){continue}break}}return(g|s)!=0}function Nt(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0;while(1){a:{b:{c:{if(J[a+116>>2]>261){break c}Ri(a);c=G[a+116>>2];if(!(c>>>0>=262|b)){return 0}if(!c){break a}if(c>>>0>2){break c}d=G[a+96>>2];G[a+120>>2]=d;G[a+100>>2]=G[a+112>>2];g=2;G[a+96>>2]=2;break b}g=2;f=G[a+108>>2];c=G[a+84>>2]&(H[(f+G[a+56>>2]|0)+2|0]^G[a+72>>2]<>2]);G[a+72>>2]=c;c=G[a+68>>2]+(c<<1)|0;e=I[c>>1];F[G[a+64>>2]+((f&G[a+52>>2])<<1)>>1]=e;F[c>>1]=f;d=G[a+96>>2];G[a+120>>2]=d;G[a+100>>2]=G[a+112>>2];G[a+96>>2]=2;if(!e){break b}d:{if(G[a+44>>2]-262>>>0>>0|J[a+128>>2]<=d>>>0){break d}g=ip(a,e);G[a+96>>2]=g;if(g>>>0>5){break d}if(G[a+136>>2]!=1){if((g|0)!=3){break d}g=3;if(G[a+108>>2]-G[a+112>>2]>>>0<4097){break d}}g=2;G[a+96>>2]=2}d=G[a+120>>2]}if(!(d>>>0<3|d>>>0>>0)){h=G[a+116>>2];c=G[a+5792>>2];f=G[a+108>>2];e=f+(G[a+100>>2]^-1)|0;F[G[a+5796>>2]+(c<<1)>>1]=e;G[a+5792>>2]=c+1;i=c+G[a+5784>>2]|0;c=d-3|0;E[i|0]=c;c=((H[(c&255)+116208|0]<<2)+a|0)+1176|0;F[c>>1]=I[c>>1]+1;c=e-1&65535;c=((H[(c>>>0<256?c:(c>>>7|0)+256|0)+115696|0]<<2)+a|0)+2440|0;F[c>>1]=I[c>>1]+1;c=G[a+120>>2];g=c-2|0;G[a+120>>2]=g;G[a+116>>2]=(G[a+116>>2]-c|0)+1;i=(f+h|0)-3|0;h=G[a+5788>>2]-1|0;d=G[a+108>>2];f=G[a+5792>>2];while(1){c=d;d=c+1|0;G[a+108>>2]=d;if(d>>>0<=i>>>0){e=G[a+84>>2]&(H[(c+G[a+56>>2]|0)+3|0]^G[a+72>>2]<>2]);G[a+72>>2]=e;e=G[a+68>>2]+(e<<1)|0;F[G[a+64>>2]+((G[a+52>>2]&d)<<1)>>1]=I[e>>1];F[e>>1]=d}g=g-1|0;G[a+120>>2]=g;if(g){continue}break}G[a+96>>2]=2;G[a+104>>2]=0;c=c+2|0;G[a+108>>2]=c;if((f|0)!=(h|0)){continue}e=G[a+92>>2];if((e|0)>=0){d=e+G[a+56>>2]|0}else{d=0}ge(a,d,c-e|0,0);G[a+92>>2]=G[a+108>>2];f=G[a>>2];e=G[f+28>>2];cd(e);d=G[e+20>>2];c=G[f+16>>2];d=c>>>0>d>>>0?d:c;e:{if(!d){break e}bb(G[f+12>>2],G[e+16>>2],d);G[f+12>>2]=d+G[f+12>>2];G[e+16>>2]=d+G[e+16>>2];G[f+20>>2]=d+G[f+20>>2];G[f+16>>2]=G[f+16>>2]-d;c=G[e+20>>2];G[e+20>>2]=c-d;if((c|0)!=(d|0)){break e}G[e+16>>2]=G[e+8>>2]}if(G[G[a>>2]+16>>2]){continue}return 0}if(G[a+104>>2]){d=H[(G[a+108>>2]+G[a+56>>2]|0)-1|0];c=G[a+5792>>2];F[G[a+5796>>2]+(c<<1)>>1]=0;G[a+5792>>2]=c+1;E[c+G[a+5784>>2]|0]=d;c=(d<<2)+a|0;F[c+148>>1]=I[c+148>>1]+1;f:{if(G[a+5792>>2]!=(G[a+5788>>2]-1|0)){break f}d=G[a+92>>2];if((d|0)>=0){c=d+G[a+56>>2]|0}else{c=0}ge(a,c,G[a+108>>2]-d|0,0);G[a+92>>2]=G[a+108>>2];f=G[a>>2];e=G[f+28>>2];cd(e);d=G[e+20>>2];c=G[f+16>>2];d=c>>>0>d>>>0?d:c;if(!d){break f}bb(G[f+12>>2],G[e+16>>2],d);G[f+12>>2]=d+G[f+12>>2];G[e+16>>2]=d+G[e+16>>2];G[f+20>>2]=d+G[f+20>>2];G[f+16>>2]=G[f+16>>2]-d;c=G[e+20>>2];G[e+20>>2]=c-d;if((c|0)!=(d|0)){break f}G[e+16>>2]=G[e+8>>2]}G[a+108>>2]=G[a+108>>2]+1;G[a+116>>2]=G[a+116>>2]-1;if(G[G[a>>2]+16>>2]){continue}return 0}else{G[a+104>>2]=1;G[a+108>>2]=G[a+108>>2]+1;G[a+116>>2]=G[a+116>>2]-1;continue}}break}if(G[a+104>>2]){d=H[(G[a+108>>2]+G[a+56>>2]|0)-1|0];c=G[a+5792>>2];F[G[a+5796>>2]+(c<<1)>>1]=0;G[a+5792>>2]=c+1;E[c+G[a+5784>>2]|0]=d;c=(d<<2)+a|0;F[c+148>>1]=I[c+148>>1]+1;G[a+104>>2]=0}d=G[a+108>>2];G[a+5812>>2]=d>>>0<2?d:2;if((b|0)==4){c=G[a+92>>2];if((c|0)>=0){b=c+G[a+56>>2]|0}else{b=0}ge(a,b,d-c|0,1);G[a+92>>2]=G[a+108>>2];e=G[a>>2];d=G[e+28>>2];cd(d);c=G[d+20>>2];b=G[e+16>>2];c=b>>>0>c>>>0?c:b;g:{if(!c){break g}bb(G[e+12>>2],G[d+16>>2],c);G[e+12>>2]=c+G[e+12>>2];G[d+16>>2]=c+G[d+16>>2];G[e+20>>2]=c+G[e+20>>2];G[e+16>>2]=G[e+16>>2]-c;b=G[d+20>>2];G[d+20>>2]=b-c;if((b|0)!=(c|0)){break g}G[d+16>>2]=G[d+8>>2]}return(G[G[a>>2]+16>>2]?3:2)|0}h:{if(!G[a+5792>>2]){break h}c=G[a+92>>2];if((c|0)>=0){b=c+G[a+56>>2]|0}else{b=0}ge(a,b,d-c|0,0);G[a+92>>2]=G[a+108>>2];e=G[a>>2];d=G[e+28>>2];cd(d);c=G[d+20>>2];b=G[e+16>>2];c=b>>>0>c>>>0?c:b;i:{if(!c){break i}bb(G[e+12>>2],G[d+16>>2],c);G[e+12>>2]=c+G[e+12>>2];G[d+16>>2]=c+G[d+16>>2];G[e+20>>2]=c+G[e+20>>2];G[e+16>>2]=G[e+16>>2]-c;b=G[d+20>>2];G[d+20>>2]=b-c;if((b|0)!=(c|0)){break i}G[d+16>>2]=G[d+8>>2]}if(G[G[a>>2]+16>>2]){break h}return 0}return 1}function tm(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0;g=Fa-192|0;Fa=g;G[g+176>>2]=4280148;e=g;G[e+168>>2]=5787738;G[e+172>>2]=5656660;G[e+160>>2]=5524560;G[e+164>>2]=5787220;G[e+152>>2]=5459015;G[e+156>>2]=5460804;G[e+144>>2]=4739160;G[e+148>>2]=5260110;G[e+136>>2]=4412244;G[e+140>>2]=5787720;G[e+128>>2]=4412227;G[e+132>>2]=4412241;G[e+120>>2]=5523777;G[e+124>>2]=5001037;G[e+112>>2]=4998739;G[e+116>>2]=5390672;G[e+104>>2]=5132098;G[e+108>>2]=5194576;G[e+96>>2]=4542275;G[e+100>>2]=5197635;G[e+88>>2]=5263171;G[e+92>>2]=4476739;G[e+80>>2]=5391693;G[e+84>>2]=4277571;G[e+72>>2]=5265731;G[e+76>>2]=5390659;G[e+64>>2]=4277594;G[e+68>>2]=5392705;G[e+56>>2]=4411969;G[e+60>>2]=5132378;G[e+48>>2]=5130579;G[e+52>>2]=4674643;G[e+40>>2]=5266003;G[e+44>>2]=5128532;G[e+32>>2]=5130572;G[e+36>>2]=5265985;if(!fb(b,35076,4)){E[b|0]=88;E[b+1|0]=76;E[b+2|0]=79;E[b+3|0]=78}f=Za(a+3368|0,b);i=Za(a+3512|0,b);e=Za(a+3544|0,b);a:{b:{if(!fb(b,34142,6)){G[a+3260>>2]=0;break b}if(!fb(b,34781,6)){G[a+3260>>2]=-1;break b}if(ug(b,33404)){G[a+3260>>2]=-1;break b}c:{d=H[b|0];h=d-65|0;if(!(!(1<>>0<=17:0)&H[b+1|0]!=76)){E[i|0]=d;E[a+3513|0]=H[b+1|0];d=H[b+2|0];d:{if((d|0)==45){E[a+3514|0]=0;d=3;break d}E[a+3514|0]=d;d=H[b+3|0];e:{if((d|0)==45){E[a+3515|0]=0;break e}E[a+3515|0]=d;E[a+3516|0]=0}d=4}d=(H[d+b|0]==45)+d|0;d=(H[d+b|0]==45)+d|0;d=(H[d+b|0]==45)+d|0;d=((H[d+b|0]==45)+d|0)+b|0;E[e|0]=H[d|0];E[a+3545|0]=H[d+1|0];d=H[d+2|0];E[a+3547|0]=0;E[a+3546|0]=d;G[g+20>>2]=e;G[g+16>>2]=i;db(f,8692,g+16|0);if(H[f|0]==32){E[f|0]=45}if(H[a+3369|0]==32){E[a+3369|0]=45}if(H[a+3370|0]==32){E[a+3370|0]=45}if(H[a+3371|0]==32){E[a+3371|0]=45}if(H[a+3372|0]==32){E[a+3372|0]=45}if(H[a+3373|0]==32){E[a+3373|0]=45}if(H[a+3374|0]==32){E[a+3374|0]=45}if(H[a+3375|0]==32){E[a+3375|0]=45}d=0;G[a+3260>>2]=0;f=1;while(1){if(!fb(e,(g+32|0)+(f<<2)|0,3)){G[a+3260>>2]=f;d=f}f=f+1|0;if((f|0)!=37){continue}break}f:{switch(G[a+3324>>2]){case 1:G[a+3324>>2]=2;break;case 2:break f;case 0:break c;default:break b}}g:{switch(d-33|0){case 0:G[a+3260>>2]=3;F[a+3374>>1]=20033;break b;case 1:break g;default:break b}}G[a+3260>>2]=7;F[a+3374>>1]=20048;break b}G[a+3260>>2]=0;break a}G[a+3324>>2]=3}h:{if(!fb(c,34740,4)){E[c|0]=H[b|0];f=H[33504]|H[33505]<<8;E[c+1|0]=f;E[c+2|0]=f>>>8;E[c+3|0]=H[33506];G[a+3264>>2]=90;f=H[35547]|H[35548]<<8|(H[35549]<<16|H[35550]<<24);E[a+3848|0]=f;E[a+3849|0]=f>>>8;E[a+3850|0]=f>>>16;E[a+3851|0]=f>>>24;f=a+3852|0;d=H[35551]|H[35552]<<8;E[f|0]=d;E[f+1|0]=d>>>8;G[a+3964>>2]=7;break h}if(!fb(c,48511,4)){E[c|0]=H[b|0];f=H[33504]|H[33505]<<8;E[c+1|0]=f;E[c+2|0]=f>>>8;E[c+3|0]=H[33506];G[a+3964>>2]=8;E[a+3848|0]=83;E[a+3849|0]=80;E[a+3850|0]=65;E[a+3851|0]=0;G[a+3264>>2]=-90;break h}G[a+3264>>2]=0}f=Za(a+3384|0,c);i=Za(a+3528|0,c);i:{if(!fb(c,34142,6)){G[a+3260>>2]=0;break i}if(!fb(c,34781,6)){G[a+3260>>2]=-1;break i}d=H[c|0];h=d-65|0;if(!(!(1<>>0<=17:0)&H[c+1|0]!=76)){E[i|0]=d;E[a+3529|0]=H[c+1|0];d=H[c+2|0];j:{if((d|0)==45){E[a+3530|0]=0;d=3;break j}E[a+3530|0]=d;d=H[c+3|0];k:{if((d|0)==45){E[a+3531|0]=0;break k}E[a+3531|0]=d;E[a+3532|0]=0}d=4}d=(H[d+c|0]==45)+d|0;d=(H[d+c|0]==45)+d|0;d=(H[d+c|0]==45)+d|0;d=((H[d+c|0]==45)+d|0)+c|0;E[e|0]=H[d|0];h=1;E[a+3545|0]=H[d+1|0];d=H[d+2|0];E[a+3547|0]=0;E[a+3546|0]=d;if(fb(b,35895,3)){d=fb(b+1|0,33504,3)}else{d=0}G[a+3304>>2]=!d;if(H[c+1|0]!=76){h=H[c|0]==65;c=h?5:3}else{c=5}G[a+3288>>2]=c;G[a+3292>>2]=h;G[g+4>>2]=e;G[g>>2]=i;db(f,8692,g);if(H[f|0]==32){E[f|0]=45}if(H[a+3385|0]==32){E[a+3385|0]=45}if(H[a+3386|0]==32){E[a+3386|0]=45}if(H[a+3387|0]==32){E[a+3387|0]=45}if(H[a+3388|0]==32){E[a+3388|0]=45}if(H[a+3389|0]==32){E[a+3389|0]=45}if(H[a+3390|0]==32){E[a+3390|0]=45}if(H[a+3391|0]!=32){break i}E[a+3391|0]=45;break i}G[a+3260>>2]=0}l:{if((Va(b)|0)<=8){G[a+6048>>2]=0;break l}if(!fb(b+8|0,34221,4)){G[a+6048>>2]=1;break l}G[a+6048>>2]=0}}Fa=g+192|0;return 0}function xp(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;n=Fa-16|0;Fa=n;a:{if(!g&(h|0)<=0|(h|0)<0|G[j>>2]>0){break a}if(!c&(d|0)<=0|(d|0)<0){G[j>>2]=307;break a}b:{if(!e&(f|0)<=0|(f|0)<0){break b}k=G[a>>2];m=G[a+4>>2];c:{d:{if((k|0)!=G[m+76>>2]){mb(a,k+1|0,0,j);break d}if((G[m+128>>2]&G[m+132>>2])!=-1){break d}if((Rb(a,j)|0)>0){break c}}l=G[a+4>>2];s=G[l+968>>2];o=b-1|0;p=G[(s+M(o,160)|0)+80>>2];k=p>>31;if((k^p)-k>>>0>=12){G[j>>2]=310;break a}t=c-1|0;u=d-!c|0;k=f;m=e+7|0;k=m>>>0<7?k+1|0:k;q=(k&7)<<29|m>>>3;e:{if((p|0)>0){b=G[(M(o,160)+s|0)+88>>2];b=(p|0)==1?(b+7|0)/8|0:b;G[n+8>>2]=b;if((b|0)<(q|0)){break b}b=(M(o,160)+s|0)+72|0;d=G[l+132>>2];f=G[l+128>>2];c=Au(G[l+960>>2],G[l+964>>2],t,u);k=f+c|0;f=Ia+d|0;f=c>>>0>k>>>0?f+1|0:f;c=k;break e}nh(a,b,c,d,n+8|0,n+12|0,j);b=G[n+8>>2];if((p|0)==-1){b=(b+7|0)/8|0;G[n+8>>2]=b}c=b>>31;k=b;d=f+h|0;b=e+g|0;d=b>>>0>>0?d+1|0:d;b=b+6|0;d=b>>>0<6?d+1|0:d;f=d>>>3|0;if(k>>>0<((d&7)<<29|b>>>3)>>>0&(f|0)>=(c|0)|(c|0)<(f|0)){break b}f=G[a+4>>2];b=f+976|0;c=G[n+12>>2];d=c+G[f+128>>2]|0;k=G[f+132>>2]+(c>>31)|0;k=c>>>0>d>>>0?k+1|0:k;c=d;f=k}d=q-1|0;k=d>>31;r=d;q=k;d=c;c=G[b>>2];d=d+c|0;f=G[b+4>>2]+f|0;f=c>>>0>d>>>0?f+1|0:f;b=d;c=d+r|0;d=f+k|0;if((Jb(a,c,b>>>0>c>>>0?d+1|0:d,0,j)|0)>0){break c}if((ic(a,1,0,n+7|0,j)|0)>0){break c}b=e-1&7;l=0;if((p|0)>0){o=M(o,160)+s|0;while(1){e=l>>31;c=e;f:{if(g>>>0<=l>>>0&(c|0)>=(h|0)|(c|0)>(h|0)){c=l;d=e;break f}f=H[n+7|0];E[i+l|0]=(f&H[b+103800|0])!=0;k=e;c=l+1|0;k=c?k:k+1|0;d=k;g:{if((h|0)<=(d|0)&c>>>0>=g>>>0|(d|0)>(h|0)|(b|0)==7){break g}E[c+i|0]=(f&H[b+103801|0])!=0;c=l+2|0;m=c>>>0<2?e+1|0:e;d=m;if((h|0)<=(d|0)&c>>>0>=g>>>0|(d|0)>(h|0)|b>>>0>5){break g}E[c+i|0]=(f&H[b+103802|0])!=0;d=e;c=l+3|0;d=c>>>0<3?d+1|0:d;if((d|0)>=(h|0)&c>>>0>=g>>>0|(d|0)>(h|0)|b>>>0>4){break g}E[c+i|0]=(f&H[b+103803|0])!=0;k=e;c=l+4|0;k=c>>>0<4?k+1|0:k;d=k;if((h|0)<=(d|0)&c>>>0>=g>>>0|(d|0)>(h|0)|b>>>0>3){break g}E[c+i|0]=(f&H[b+103804|0])!=0;c=l+5|0;m=c>>>0<5?e+1|0:e;d=m;if((h|0)<=(d|0)&c>>>0>=g>>>0|(d|0)>(h|0)|b>>>0>2){break g}E[c+i|0]=(f&H[b+103805|0])!=0;d=e;c=l+6|0;d=c>>>0<6?d+1|0:d;if((d|0)>=(h|0)&c>>>0>=g>>>0|(d|0)>(h|0)|b>>>0>1){break g}E[c+i|0]=(f&H[b+103806|0])!=0;k=e;c=l+7|0;k=c>>>0<7?k+1|0:k;d=k;if((h|0)<=(d|0)&c>>>0>=g>>>0|(d|0)>(h|0)|b){break g}E[c+i|0]=(f&H[b+103807|0])!=0;b=l+8|0;m=b>>>0<8?e+1|0:e;c=b;d=m}l=c}if((c|0)==(g|0)&(d|0)==(h|0)){break c}d=q;b=r+1|0;d=b?d:d+1|0;r=b;b=G[n+8>>2];q=d;if((r|0)==(b|0)&(d|0)==b>>31){c=G[o+76>>2];f=G[o+72>>2];k=u;b=t+1|0;k=b?k:k+1|0;t=b;u=k;e=G[a+4>>2];d=Au(b,k,G[e+960>>2],G[e+964>>2]);b=G[e+128>>2];d=d+b|0;m=Ia+G[e+132>>2]|0;m=b>>>0>d>>>0?m+1|0:m;b=d;d=f+d|0;f=c+m|0;Jb(a,d,b>>>0>d>>>0?f+1|0:f,0,j);r=0;q=0}b=0;if((ic(a,1,0,n+7|0,j)|0)<=0){continue}break}break c}while(1){e=l>>31;c=e;h:{if(g>>>0<=l>>>0&(c|0)>=(h|0)|(c|0)>(h|0)){c=l;d=e;break h}k=H[n+7|0];E[i+l|0]=(k&H[b+103800|0])!=0;d=e;c=l+1|0;d=c?d:d+1|0;i:{if((d|0)>=(h|0)&c>>>0>=g>>>0|(d|0)>(h|0)|(b|0)==7){break i}E[c+i|0]=(k&H[b+103801|0])!=0;d=e;c=l+2|0;d=c>>>0<2?d+1|0:d;if((d|0)>=(h|0)&c>>>0>=g>>>0|(d|0)>(h|0)|b>>>0>5){break i}E[c+i|0]=(k&H[b+103802|0])!=0;c=l+3|0;f=c>>>0<3?e+1|0:e;d=f;if((h|0)<=(d|0)&c>>>0>=g>>>0|(d|0)>(h|0)|b>>>0>4){break i}E[c+i|0]=(k&H[b+103803|0])!=0;d=e;c=l+4|0;d=c>>>0<4?d+1|0:d;if((d|0)>=(h|0)&c>>>0>=g>>>0|(d|0)>(h|0)|b>>>0>3){break i}E[c+i|0]=(k&H[b+103804|0])!=0;d=e;c=l+5|0;d=c>>>0<5?d+1|0:d;if((d|0)>=(h|0)&c>>>0>=g>>>0|(d|0)>(h|0)|b>>>0>2){break i}E[c+i|0]=(k&H[b+103805|0])!=0;c=l+6|0;f=c>>>0<6?e+1|0:e;d=f;if((h|0)<=(d|0)&c>>>0>=g>>>0|(d|0)>(h|0)|b>>>0>1){break i}E[c+i|0]=(k&H[b+103806|0])!=0;d=e;c=l+7|0;d=c>>>0<7?d+1|0:d;if((d|0)>=(h|0)&c>>>0>=g>>>0|(d|0)>(h|0)|b){break i}E[c+i|0]=(k&H[b+103807|0])!=0;d=e;b=l+8|0;d=b>>>0<8?d+1|0:d;c=b}l=c}if((c|0)==(g|0)&(d|0)==(h|0)){break c}b=0;if((ic(a,1,0,n+7|0,j)|0)<=0){continue}break}}break a}G[j>>2]=308}Fa=n+16|0}function Ys(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;n=G[309722];o=G[(n+M(G[a+16>>2],344)|0)+88>>2];p=G[a+12>>2];Nd(a);g=G[309726]+o|0;h=1;j=G[a+52>>2];h=j-261>>>0>=2?G[a+56>>2]:h;a:{b:{c:{d=G[309732];if((d|0)>(g|0)){d=d-g|0;b=G[309727];d=(b|0)>(d|0)?d:b;k=b-d|0;if((d|0)<=0|(g|0)>0){break b}i=h&3;j=h-1>>>0<3;while(1){d:{if(G[a+52>>2]!=262){if(!h){break d}c=0;b=h;if(i){while(1){E[G[a+84>>2]+e|0]=1;e=e+1|0;b=b-1|0;c=c+1|0;if((i|0)!=(c|0)){continue}break}}if(j){break d}while(1){E[G[a+84>>2]+e|0]=1;E[(G[a+84>>2]+e|0)+1|0]=1;E[(G[a+84>>2]+e|0)+2|0]=1;E[(G[a+84>>2]+e|0)+3|0]=1;e=e+4|0;b=b-4|0;if(b){continue}break}break d}b=G[a+56>>2];c=e<<2;E[b+G[c+G[a+88>>2]>>2]|0]=0;e:{if(!b){break e}l=b-1|0;f=0;m=b&3;if(m){while(1){b=b-1|0;E[b+G[c+G[a+88>>2]>>2]|0]=48;f=f+1|0;if((m|0)!=(f|0)){continue}break}}if(l>>>0<3){break e}while(1){E[(G[c+G[a+88>>2]>>2]+b|0)-1|0]=48;E[(G[c+G[a+88>>2]>>2]+b|0)-2|0]=48;E[(G[c+G[a+88>>2]>>2]+b|0)-3|0]=48;b=b-4|0;E[b+G[c+G[a+88>>2]>>2]|0]=48;if(b){continue}break}}e=e+1|0}b=d-1|0;c=g+1|0;if((g|0)>=0){break c}f=(d|0)>1;g=c;d=b;if(f){continue}break}break c}b=G[309727];c=b+g|0;f=d+G[309733]|0;if((c|0)<=(f|0)){k=b;break a}c=c-f|0;g=(c|0)>(b|0)?g:f;d=(b|0)>(c|0)?c:b;k=b-d|0;e=M(k,h);if((d|0)<=0){break b}i=G[309734];if((i|0)>=(d+g|0)){break b}if(h){i=h&3;b=M(b,h);l=h-1>>>0<3;while(1){f:{if(G[a+52>>2]!=262){f=0;c=h;if(i){while(1){b=b-1|0;E[b+G[a+84>>2]|0]=1;c=c-1|0;f=f+1|0;if((i|0)!=(f|0)){continue}break}}if(l){break f}while(1){E[(G[a+84>>2]+b|0)-1|0]=1;E[(G[a+84>>2]+b|0)-2|0]=1;E[(G[a+84>>2]+b|0)-3|0]=1;b=b-4|0;E[b+G[a+84>>2]|0]=1;c=c-4|0;if(c){continue}break}break f}c=G[a+56>>2];b=b-1|0;f=b<<2;E[c+G[f+G[a+88>>2]>>2]|0]=0;if(!c){break f}m=c-1|0;j=0;q=c&3;if(q){while(1){c=c-1|0;E[c+G[f+G[a+88>>2]>>2]|0]=48;j=j+1|0;if((q|0)!=(j|0)){continue}break}}if(m>>>0<3){break f}while(1){E[(G[f+G[a+88>>2]>>2]+c|0)-1|0]=48;E[(G[f+G[a+88>>2]>>2]+c|0)-2|0]=48;E[(G[f+G[a+88>>2]>>2]+c|0)-3|0]=48;c=c-4|0;E[c+G[f+G[a+88>>2]>>2]|0]=48;if(c){continue}break}}c=d-1|0;if((d|0)>=2){d=c;if(G[309734]<(c+g|0)){continue}}break}d=c;break b}if((j|0)==262){i=0;while(1){g:{if(G[a+52>>2]!=262){break g}b=G[a+56>>2];i=i-1|0;c=i<<2;E[b+G[c+G[a+88>>2]>>2]|0]=0;if(!b){break g}j=b-1|0;f=0;l=b&3;if(l){while(1){b=b-1|0;E[b+G[c+G[a+88>>2]>>2]|0]=48;f=f+1|0;if((l|0)!=(f|0)){continue}break}}if(j>>>0<3){break g}while(1){E[(G[c+G[a+88>>2]>>2]+b|0)-1|0]=48;E[(G[c+G[a+88>>2]>>2]+b|0)-2|0]=48;E[(G[c+G[a+88>>2]>>2]+b|0)-3|0]=48;b=b-4|0;E[b+G[c+G[a+88>>2]>>2]|0]=48;if(b){continue}break}}b=d-1|0;if((d|0)<2){d=b;break b}d=b;if(G[309734]<(b+g|0)){continue}break}break b}e=0;b=((d+f|0)+((b|0)>(c|0)?b:c)|0)+(b^-1)|0;d=d-1|0;b=(((b|0)>(i|0)?i:b)-b|0)+d|0;d=b>>>0>d>>>0?0:b;break b}d=b;g=c}if((d|0)<=0){break a}b=M(p,344)+n|0;h:{switch(G[a+52>>2]-258|0){case 3:case 4:Ja[G[309714]](0-G[b>>2]|0,g,d,G[a+88>>2]+(e<<2)|0,G[a+84>>2]+e|0)|0;break a;case 0:Ja[G[309714]](0-G[b>>2]|0,g,d,G[a+88>>2]+e|0,G[a+84>>2]+e|0)|0;break a;case 1:Ja[G[309714]](0-G[b>>2]|0,g,d,G[a+88>>2]+(e<<2)|0,G[a+84>>2]+e|0)|0;break a;case 2:break h;default:break a}}Ja[G[309714]](0-G[b>>2]|0,g,d,G[a+88>>2]+(e<<3)|0,G[a+84>>2]+e|0)|0}i:{if(!h|(G[309737]|(k|0)<=0)){break i}g=M(h,o);d=M(p,344)+n|0;e=M((o|0)>0?k:G[309727],h);while(1){k=k-1|0;b=h;while(1){e=e-1|0;b=b-1|0;j:{k:{if(G[a+52>>2]==262){c=e+g|0;break k}c=e+g|0;E[G[a+84>>2]+e|0]=H[c+G[d+84>>2]|0];l:{switch(G[a+52>>2]-258|0){case 2:L[G[a+88>>2]+(e<<3)>>3]=L[G[d+88>>2]+(c<<3)>>3];break j;case 1:G[G[a+88>>2]+(e<<2)>>2]=G[G[d+88>>2]+(c<<2)>>2];break j;case 0:E[G[a+88>>2]+e|0]=H[G[d+88>>2]+c|0];break j;case 4:break k;case 3:break l;default:break j}}Za(G[G[a+88>>2]+(e<<2)>>2],G[G[d+88>>2]+(c<<2)>>2]);break j}Za(G[G[a+88>>2]+(e<<2)>>2],G[G[d+88>>2]+(c<<2)>>2])}c=G[309737];if(c?0:b){continue}break}if(!k){break i}if(!c){continue}break}}}function Ls(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0;d=Fa-16|0;Fa=d;i=21833;h=Fa-7648|0;Fa=h;a:{if(G[f>>2]>0){break a}G[d+12>>2]=0;if(G[47541]){j=ji();G[f>>2]=j;if((j|0)>0){break a}}while(1){j=i;i=i+1|0;if(H[j|0]==32){continue}break}dh(j,h+7520|0,h+6480|0,h+5440|0,h+4400|0,h+3360|0,h+2320|0,h+1280|0,0,0,f);i=H[141383]|H[141384]<<8|(H[141385]<<16|H[141386]<<24);E[h+7527|0]=i;E[h+7528|0]=i>>>8;E[h+7529|0]=i>>>16;E[h+7530|0]=i>>>24;i=G[35345];G[h+7520>>2]=G[35344];G[h+7524>>2]=i;i=G[310142];b:{c:{while(1){if((i|0)<=0){break c}i=i-1|0;if(Xa(M(i,84)+1240576|0,h+7520|0)){continue}break}G[f>>2]=0;a=Hn(a,b,h+7644|0);G[f>>2]=a;if((a|0)>0){Ua(57248);break a}a=M(i,84)+1240576|0;b=Ja[G[a+64>>2]](G[h+7644>>2],h+7544|0)|0;G[f>>2]=b;if((b|0)>0){Ja[G[a+56>>2]](G[h+7644>>2])|0;Ua(57298);break a}b=lb(1,8);G[d+12>>2]=b;if(!b){Ja[G[(M(i,84)+1240576|0)+56>>2]](G[h+7644>>2])|0;Ua(57347);Ua(j);break b}a=lb(1,1736);G[b+4>>2]=a;if(!a){Ja[G[(M(i,84)+1240576|0)+56>>2]](G[h+7644>>2])|0;Ua(57347);Ua(j);Wa(G[d+12>>2]);G[d+12>>2]=0;break b}k=Va(j)+1|0;k=ab((k|0)>32?k:32);G[a+12>>2]=k;if(!k){Ja[G[(M(i,84)+1240576|0)+56>>2]](G[h+7644>>2])|0;Ua(57138);Ua(j);Wa(G[G[d+12>>2]+4>>2]);Wa(G[d+12>>2]);G[d+12>>2]=0;break b}g=lb(1001,8);G[a+96>>2]=g;if(!g){Ja[G[(M(i,84)+1240576|0)+56>>2]](G[h+7644>>2])|0;Ua(57027);Ua(j);Wa(G[G[G[d+12>>2]+4>>2]+12>>2]);Wa(G[G[d+12>>2]+4>>2]);Wa(G[d+12>>2]);G[d+12>>2]=0;break b}g=lb(40,2880);G[a+1252>>2]=g;d:{e:{if(g){cb(a+1256|0,255,160);g=a+1728|0;G[g>>2]=38;G[g+4>>2]=39;g=a+1720|0;G[g>>2]=36;G[g+4>>2]=37;g=a+1712|0;G[g>>2]=34;G[g+4>>2]=35;g=a+1704|0;G[g>>2]=32;G[g+4>>2]=33;g=a+1696|0;G[g>>2]=30;G[g+4>>2]=31;g=a+1688|0;G[g>>2]=28;G[g+4>>2]=29;g=a+1680|0;G[g>>2]=26;G[g+4>>2]=27;g=a+1672|0;G[g>>2]=24;G[g+4>>2]=25;g=a+1664|0;G[g>>2]=22;G[g+4>>2]=23;g=a+1656|0;G[g>>2]=20;G[g+4>>2]=21;g=a+1648|0;G[g>>2]=18;G[g+4>>2]=19;g=a+1640|0;G[g>>2]=16;G[g+4>>2]=17;g=a+1632|0;G[g>>2]=14;G[g+4>>2]=15;g=a+1624|0;G[g>>2]=12;G[g+4>>2]=13;g=a+1616|0;G[g>>2]=10;G[g+4>>2]=11;g=a+1608|0;G[g>>2]=8;G[g+4>>2]=9;g=a+1600|0;G[g>>2]=6;G[g+4>>2]=7;g=a+1592|0;G[g>>2]=4;G[g+4>>2]=5;g=a+1584|0;G[g>>2]=2;G[g+4>>2]=3;G[a+1576>>2]=0;G[a+1580>>2]=1;G[a+92>>2]=1e3;g=G[h+7644>>2];G[a+4>>2]=i;G[a>>2]=g;Za(k,j);i=G[h+7544>>2];k=G[h+7548>>2];G[a+128>>2]=-1;G[a+132>>2]=-1;G[a+84>>2]=1;G[a+40>>2]=i;G[a+44>>2]=k;G[a+32>>2]=i;G[a+36>>2]=k;G[a+72>>2]=-1;G[a+24>>2]=0;G[a+16>>2]=555;G[a+8>>2]=1;Hc(b,0,0,f);a=G[d+12>>2];if(G[f>>2]>0){break d}k=G[a+4>>2];break e}Ja[G[(M(i,84)+1240576|0)+56>>2]](G[h+7644>>2])|0;Ua(57083);Ua(j);Wa(G[G[G[d+12>>2]+4>>2]+96>>2]);Wa(G[G[G[d+12>>2]+4>>2]+12>>2]);Wa(G[G[d+12>>2]+4>>2]);Wa(G[d+12>>2]);G[d+12>>2]=0;break b}while(1){f:{b=l<<2;i=b+1243184|0;if(!G[i>>2]){break f}b=b+1243184|0;i=b+4|0;if(!G[i>>2]){break f}i=b+8|0;if(!G[i>>2]){break f}i=b+12|0;if(!G[i>>2]){break f}i=b+16|0;if(!G[i>>2]){break f}l=l+5|0;if((l|0)!=1e4){continue}break d}break}G[i>>2]=k;a=G[d+12>>2]}if((Wf(a,h+7640|0,f)|0)>0){Ua(57405);Ua(j);if(G[f>>2]==252){Ua(44068)}Qb(G[d+12>>2],f);G[d+12>>2]=0}E[h+160|0]=0;E[h+1200|0]=0;if(!H[h+4400|0]){break a}Pj(h+4400|0,h+7628|0,h+7552|0,h+7632|0,h+7636|0,h+1200|0,h+160|0,f);if(G[f>>2]>0){break a}a=G[h+7628>>2];g:{if(a){mb(G[d+12>>2],a+1|0,h+7640|0,f);break g}if(!H[h+7552|0]){break g}Je(G[d+12>>2],G[h+7636>>2],h+7552|0,G[h+7632>>2],f)}if(G[f>>2]<=0){break a}Ua(37257);h:{if((a|0)>0){G[h>>2]=a;i=h- -64|0;Ya(i,81,44578,h);break h}G[h+48>>2]=h+7552;a=h- -64|0;Ya(a,81,48820,h+48|0);Ua(a);a=G[h+7632>>2];if(a){G[h+32>>2]=a;a=h- -64|0;Ya(a,81,48850,h+32|0);Ua(a)}i=44598;a=G[h+7636>>2];if((a|0)==-1){break h}G[h+16>>2]=G[(a<<2)+141388>>2];a=h- -64|0;Ya(a,81,48785,h+16|0);Ua(a)}Ua(i);break a}G[f>>2]=124;Ua(57187);break a}G[f>>2]=113}Fa=h+7648|0;if(!G[f>>2]){m=Um(G[d+12>>2],c,e,f)}Fa=d+16|0;return m|0}function ou(a,b,c){a=+a;b=b|0;c=c|0;var d=0,e=0,f=N(0),g=0,h=0,i=0,j=0,k=0,l=N(0),m=N(0),n=0;e=Fa-240|0;Fa=e;a:{b:{c:{d:{e:{f:{g:{h=E[b|0];b=h;switch(b-58|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 41:case 43:case 44:case 45:case 47:case 48:case 49:case 50:case 52:case 54:case 55:case 56:case 57:case 58:case 59:case 60:case 61:break a;case 0:case 51:break b;case 42:case 46:break c;case 62:break d;case 53:break e;case 40:break f;default:break g}}if((h|0)==32){break b}break a}E[3809712]=48;E[3809713]=98;h:{i:{j:{k:{l:{m:{n:{o:{p:{q:{r:{s:{t:{u:{v:{w:{x:{y:{z:{A:{B:{C:{D:{E:{F:{G:{H:{I:{J:{if(O(a)<2147483648){b=~~a}else{b=-2147483648}c=b&32768;K:{if(c){E[3809714]=49;d=3;c=(b&16384)>>>14|0;break K}d=c;c=b&16384;if(!(d|c)){break J}d=2;c=c>>>14|0}E[d+3809712|0]=c?49:48;d=d+1|0;c=(b&8192)>>>13|0;break I}c=b&8192;if(!c){break H}d=2;c=c>>>13|0}E[d+3809712|0]=c?49:48;d=d+1|0;c=(b&4096)>>>12|0;break G}c=b&4096;if(!c){break F}d=2;c=c>>>12|0}E[d+3809712|0]=c?49:48;d=d+1|0;c=(b&2048)>>>11|0;break E}c=b&2048;if(!c){break D}d=2;c=c>>>11|0}E[d+3809712|0]=c?49:48;d=d+1|0;c=(b&1024)>>>10|0;break C}c=b&1024;if(!c){break B}d=2;c=c>>>10|0}E[d+3809712|0]=c?49:48;d=d+1|0;c=(b&512)>>>9|0;break A}c=b&512;if(!c){break z}d=2;c=c>>>9|0}E[d+3809712|0]=c?49:48;d=d+1|0;c=(b&256)>>>8|0;break y}c=b&256;if(!c){break x}d=2;c=c>>>8|0}E[d+3809712|0]=c?49:48;d=d+1|0;c=(b&128)>>>7|0;break w}c=b&128;if(!c){break v}d=2;c=c>>>7|0}E[d+3809712|0]=c?49:48;d=d+1|0;c=(b&64)>>>6|0;break u}c=b&64;if(!c){break t}d=2;c=c>>>6|0}E[d+3809712|0]=c?49:48;d=d+1|0;c=(b&32)>>>5|0;break s}c=b&32;if(!c){break r}d=2;c=c>>>5|0}E[d+3809712|0]=c?49:48;d=d+1|0;c=(b&16)>>>4|0;break q}c=b&16;if(!c){break p}d=2;c=c>>>4|0}E[d+3809712|0]=c?49:48;d=d+1|0;c=(b&8)>>>3|0;break o}c=b&8;if(!c){break n}d=2;c=c>>>3|0}E[d+3809712|0]=c?49:48;d=d+1|0;c=(b&4)>>>2|0;break m}c=b&4;if(!c){break l}d=2;c=c>>>2|0}E[d+3809712|0]=c?49:48;d=d+1|0;c=(b&2)>>>1|0;break k}d=2;c=b&2;if(!c){break j}c=c>>>1|0}E[d+3809712|0]=c?49:48;b=b&1;d=d+1|0;break i}b=b&1;c=2;if(!b){break h}}E[d+3809712|0]=b?49:48;c=d+1|0}E[c+3809712|0]=0;break a}if(O(a)<2147483648){b=~~a}else{b=-2147483648}G[e>>2]=b;db(3809712,13581,e);break a}if(O(a)<2147483648){b=~~a}else{b=-2147483648}G[e+16>>2]=b;db(3809712,3867,e+16|0);break a}b=109}f=N(a);g=f>3]=a;G[e+40>>2]=b;G[e+36>>2]=c;G[e+32>>2]=g;Eb(3809712,18593,e+32|0);break a}L[e+80>>3]=a;G[e+72>>2]=b;G[e+68>>2]=c;G[e+64>>2]=g;Eb(3809712,18568,e- -64|0);break a}if(f>3]=a;G[e+112>>2]=b;G[e+108>>2]=d;G[e+104>>2]=h;G[e+100>>2]=i;G[e+96>>2]=g;Eb(3809712,18577,e+96|0);break a}L[e+152>>3]=a;G[e+144>>2]=b;G[e+140>>2]=d;G[e+136>>2]=h;G[e+132>>2]=i;G[e+128>>2]=g;Eb(3809712,18554,e+128|0);break a}a=$b(10,+(c|0));j=+f*a+.5;O:{if(O(j)<2147483648){k=~~j;break O}k=-2147483648}if(+(k|0)/a>=60){k=(d|0)>58;d=k?0:d+1|0;f=N(0);i=i+k|0}G[e+200>>2]=c;G[e+196>>2]=b;G[e+192>>2]=h;c=e+208|0;j=+f;n=j*a+.5;P:{if(O(n)<2147483648){b=~~n;break P}b=-2147483648}db(c,+(b|0)/a<10?18643:18620,e+192|0);L[e+176>>3]=j;G[e+168>>2]=d;G[e+164>>2]=i;G[e+160>>2]=g;Eb(3809712,c,e+160|0)}Fa=e+240|0;return 3809712}function Bk(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;l=G[k>>2];if((l|0)<=0){a:{b:{switch(b-1|0){case 0:i=Fa-128|0;Fa=i;m=h;c:{if((h|0)<=0|G[k>>2]>0){break c}if(!d&(e|0)<=0|(e|0)<0){G[k>>2]=307;break c}d:{if((f|0)<=0){break d}e:{g=G[a>>2];b=G[a+4>>2];f:{if((g|0)!=G[b+76>>2]){mb(a,g+1|0,0,k);break f}if((G[b+128>>2]&G[b+132>>2])!=-1){break f}if((Rb(a,k)|0)>0){break e}}r=f+7|0;p=r>>>3|0;h=f+m|0;b=((h+6>>>3|0)-p|0)+1|0;f=b;g=b>>31;b=i+56|0;if((yc(a,c,d,e,p,0,f,g,1,b,b,i+44|0,i+84|0,i+76|0,i+72|0,i+120|0,i+96|0,i+80|0,i+112|0,i+104|0,i+68|0,i+88|0,i+32|0,k)|0)>0){break e}b=G[a+4>>2];n=G[b+968>>2];l=c-1|0;o=G[(n+M(l,160)|0)+80>>2];G[i+76>>2]=o;f=o>>31;if((o^f)-f>>>0>=12){G[k>>2]=310;break c}f=d-1|0;g=e-!d|0;g:{if((o|0)>0){d=n+M(l,160)|0;c=G[d+92>>2];d=G[d+88>>2];e=d+7|0;h=e>>>0<7?c+1|0:c;q=d;d=(o|0)==1;e=(s=Bu(e,h,8,0),t=q,u=d,u?s:t);G[i+112>>2]=e;c=d?Ia:c;G[i+116>>2]=c;if(e>>>0

>>0&(c|0)<=0|(c|0)<0){break d}c=n+M(l,160)|0;d=G[c+72>>2];h=G[c+76>>2];e=G[b+132>>2];q=G[b+128>>2];c=Au(G[b+960>>2],G[b+964>>2],f,g);b=q+c|0;e=Ia+e|0;e=b>>>0>>0?e+1|0:e;c=d;d=b;c=c+b|0;b=e+h|0;b=c>>>0>>0?b+1|0:b;h=c;break g}G[i+112>>2]=h-1;G[i+116>>2]=0;if((o|0)==-1){Le(a,c,d,e,i+8|0,i+16|0,k);b=G[i+112>>2];ph(a,c,d,e,b,b>>31,G[i+16>>2],G[i+20>>2],k)}b=G[i+124>>2];h=G[i+120>>2]}c=r&7;e=0;d=p-1|0;h=h+d|0;b=d>>>0>h>>>0?b+1|0:b;G[i+120>>2]=h;G[i+124>>2]=b;Jb(a,h,b,1,k);n=n+M(l,160)|0;l=0;while(1){if((ic(a,1,0,i+31|0,k)|0)==107){G[k>>2]=0;E[i+31|0]=0}Jb(a,G[i+120>>2],G[i+124>>2],1,k);if((l|0)<(m|0)){b=H[i+31|0];if(H[j+l|0]){b=b|H[c+118756|0]}else{b=b&H[c+118764|0]}h=l+1|0;h:{if(c>>>0>6|(h|0)>=(m|0)){break h}if(H[h+j|0]){b=H[c+118757|0]|b}else{b=H[c+118765|0]&b}h=l+2|0;if(c>>>0>5|(h|0)>=(m|0)){break h}if(H[h+j|0]){b=H[c+118758|0]|b}else{b=H[c+118766|0]&b}h=l+3|0;if(c>>>0>4|(h|0)>=(m|0)){break h}if(H[h+j|0]){b=H[c+118759|0]|b}else{b=H[c+118767|0]&b}h=l+4|0;if(c>>>0>3|(h|0)>=(m|0)){break h}if(H[h+j|0]){b=H[c+118760|0]|b}else{b=H[c+118768|0]&b}h=l+5|0;if(c>>>0>2|(h|0)>=(m|0)){break h}if(H[h+j|0]){b=H[c+118761|0]|b}else{b=H[c+118769|0]&b}h=l+6|0;if(c>>>0>1|(h|0)>=(m|0)){break h}if(H[h+j|0]){b=H[c+118762|0]|b}else{b=H[c+118770|0]&b}h=l+7|0;if((h|0)>=(m|0)|c){break h}if(H[h+j|0]){b=H[c+118763|0]|b}else{b=H[c+118771|0]&b}h=l+8|0}E[i+31|0]=b;l=h}Wb(a,1,0,i+31|0,k);if((l|0)==(m|0)){break e}h=G[i+124>>2];b=G[i+120>>2]+1|0;h=b?h:h+1|0;G[i+120>>2]=b;G[i+124>>2]=h;c=0;if((o|0)<=0){continue}b=d+1|0;e=b?e:e+1|0;d=b;if((b|0)!=G[i+112>>2]|G[i+116>>2]!=(e|0)){continue}e=G[n+76>>2];q=G[n+72>>2];b=g;d=f+1|0;b=d?b:b+1|0;f=d;g=b;b=G[a+4>>2];d=Au(d,g,G[b+960>>2],G[b+964>>2]);h=G[b+128>>2];d=d+h|0;b=Ia+G[b+132>>2]|0;b=d>>>0>>0?b+1|0:b;p=d;d=q+d|0;h=b+e|0;b=d;G[i+120>>2]=b;h=b>>>0

>>0?h+1|0:h;G[i+124>>2]=h;Jb(a,b,h,1,k);d=0;e=0;continue}}break c}G[k>>2]=308}Fa=i+128|0;break a;case 10:pe(a,c,d,e,f,g,h,i,j,k);break a;case 11:Bh(a,c,d,e,f,g,h,i,j,k);break a;case 19:Ah(a,c,d,e,f,g,h,i,j,k);break a;case 20:Ng(a,c,d,e,f,g,h,i,j,k);break a;case 29:if(G[k>>2]<=0){Qe(a,c,d,e,f,g,h,i,j,k)}break a;case 30:Jo(a,c,d,e,f,g,h,i,j,k);break a;case 39:Qe(a,c,d,e,f,g,h,i,j,k);break a;case 40:xe(a,c,d,e,f,g,h,i,j,k);break a;case 79:zh(a,c,d,e,f,g,h,i,j,k);break a;case 80:yh(a,c,d,e,f,g,h,i,j,k);break a;case 41:Kg(a,c,d,e,f,g,h,i,j,k);break a;case 81:Ff(a,c,d,e,f,g,h,i,j,k);break a;case 82:l=a;a=f;b=g<<1|a>>>31;a=a<<1;f=a-1|0;b=b-!a|0;a=h;h=i<<1|h>>>31;Kg(l,c,d,e,f,b,a<<1,h,j,k);break a;case 162:l=a;a=f;b=g<<1|a>>>31;a=a<<1;f=a-1|0;a=b-!a|0;b=i<<1|h>>>31;Ff(l,c,d,e,f,a,h<<1,b,j,k);break a;case 13:Go(a,c,d,e,f,g,h,i,j,k);break a;case 15:dg(a,c,d,e,f,g,h,i,j,k);break a;default:break b}}G[k>>2]=410}l=G[k>>2]}return l}function Qj(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;d=Fa-4160|0;Fa=d;E[d+4048|0]=0;g=eh(0);a:{if(g){break a}f=G[47524];b:{if(!(c&1)){g=369;if((f|0)==3){break b}break a}g=369;if((f|0)!=4){break a}}g=360;f=ab(176);if(!f){break a}i=bb(f,1240392,176);c:{if(G[310098]!=2){break c}e=G[310118];if(!e){break c}h=i;i=ab(Va(e)+1|0);G[h+80>>2]=i;if(!i){break a}Za(i,e)}i=1;d:{e:{f:{g:{g=eh(0);if(!g){while(1){g=369;h:{i:{j:{k:{l:{switch(G[47524]-1|0){case 0:case 1:case 2:G[d+44>>2]=f;G[d+40>>2]=i;if(G[309816]){break g}G[d+4156>>2]=363;break e;case 4:break j;case 3:break k;default:break l}}g=Va(1240396);m:{if(g-2>>>0>4){break m}e=g-1|0;if(H[e+1240396|0]!=35){break m}if(!H[d+4048|0]){h=d+4048|0;bb(h,1240396,e);E[e+h|0]=0}if((Va(d+4048|0)|0)==(e|0)){k=!nb(d+4048|0,1240396,e)+k|0}G[d>>2]=k;Ya(g+1240395|0,76-g|0,30633,d)}g=360;h=M(i,176);e=ub(f,h+176|0);if(!e){break k}h=bb(e+h|0,1240392,176);if(G[310098]!=2){break h}f=G[310118];if(!f){break h}l=h;h=ab(Va(f)+1|0);G[l+80>>2]=h;if(h){break i}f=e}G[d+44>>2]=f;G[d+40>>2]=i;G[d+4156>>2]=g;break e}G[d+44>>2]=f;G[d+40>>2]=i;G[d+4156>>2]=0;break f}Za(h,f)}i=i+1|0;f=e;g=eh(0);if(!g){continue}break}}G[d+40>>2]=i;break a}if(G[309823]){G[d+4156>>2]=364;break e}e=G[309817];G[309823]=G[309816];G[309824]=e;G[309829]=G[309822];e=G[309821];G[309827]=G[309820];G[309828]=e;e=G[309819];G[309825]=G[309818];G[309826]=e;G[d+4156>>2]=0;G[309816]=0}cb(d+48|0,0,3996);k=0;g=0;while(1){l=M(g,176);e=l+f|0;h=e+4|0;n:{if(!Xa(34516,h)){if(G[e>>2]!=2){break n}k=(o=(r=gc(35618,G[e+80>>2],8)?k:3,s=2,t=gc(35630,G[(f+l|0)+80>>2],5),t?r:s),p=1,q=gc(35678,G[(f+l|0)+80>>2],5),q?o:p);break n}if(!Xa(35530,h)){if(G[e>>2]!=1){break n}k=H[e+80|0]?1:k;break n}if(!Xa(32941,h)){if(G[e>>2]!=3){break n}n=G[e+80>>2];break n}if(!Xa(33788,h)){if(G[e>>2]!=3){break n}j=G[e+80>>2];break n}if(!Xa(35480,h)){if(G[e>>2]!=2){break n}m=G[e+80>>2];break n}G[d+20>>2]=d+4047;G[d+16>>2]=d+4144;if((Qc(h,30730,d+16|0)|0)!=1){break n}e=f+l|0;if(G[e>>2]!=3){break n}h=G[d+4144>>2]-1|0;if(h>>>0>998){break n}G[(d+48|0)+(h<<2)>>2]=G[e+80>>2]}g=g+1|0;if(i>>>0>g>>>0){continue}break}o:{p:{q:{switch(k-1|0){case 0:if((c&3)==2){pd(a,16,0,0,d+4156|0)}pd(a,n,j,d+48|0,d+4156|0);if(G[d+4156>>2]){break e}g=Rj(d+40|0,a);G[d+4156>>2]=g;break p;case 1:case 2:break q;default:break o}}nl(a,(k|0)==2?1:2,0,0,0,0,0,0,0,d+4156|0);if(G[d+4156>>2]){break e}c=cn(a,d+40|0,0);G[d+4156>>2]=c;if(c){break e}g=Rj(d+40|0,a);G[d+4156>>2]=g;if(g){break p}c=G[d+52>>2];if((c|0)<=0){break p}Ig(a,0,0,c,0,d+4156|0);g=G[d+4156>>2]}if(!(!m|g)){j=368;e=d+4140|0;r:{if(!m|!e){break r}c=G[309833];f=G[309832];if(!c&(f|0)>0|((f|0)<=0?c:0)){break r}if((f|0)>0){j=0;while(1){if(!Xa(m,G[c+(j<<3)>>2])){f=c+(j<<3)|0;c=G[f+4>>2]+1|0;G[f+4>>2]=c;G[e>>2]=c;j=0;break r}j=j+1|0;if((f|0)!=(j|0)){continue}break}}j=360;s:{if(!c){c=ab(8);break s}c=ub(c,(f<<3)+8|0)}if(!c){break r}f=ab(Va(m)+1|0);if(!f){Wa(c);break r}j=0;f=Za(f,m);G[309833]=c;c=c+(G[309832]<<3)|0;G[c+4>>2]=1;G[c>>2]=f;G[e>>2]=1;G[309832]=G[309832]+1}G[d+4156>>2]=j;G[d+36>>2]=G[d+4140>>2];xd(a,41,33996,d+36|0,11175,d+4156|0);g=G[d+4156>>2]}if(!(g|(b|0)<=0)){G[d+4152>>2]=G[a>>2]+1;e=b;c=d+4148|0;b=d+4156|0;mb(a,e,c,b);Un(a,G[d+4152>>2],b);mb(a,G[d+4152>>2],c,b);g=G[d+4156>>2];if(!g){break d}break a}if(!g){break d}break e}G[d+4156>>2]=368}G[d+4148>>2]=0;vo(a,0,d+4148|0)}b=0;a=d+40|0;if(a){c=G[a>>2];if((c|0)>0){while(1){f=M(b,176);e=f+G[a+4>>2]|0;t:{if(G[e>>2]!=2){break t}e=G[e+80>>2];if(!e){break t}Wa(e);G[(f+G[a+4>>2]|0)+80>>2]=0;c=G[a>>2]}b=b+1|0;if((b|0)<(c|0)){continue}break}}b=G[a+4>>2];if(b){Wa(b)}G[a>>2]=0;G[a+4>>2]=0}g=G[d+4156>>2]}Fa=d+4160|0;return g}function dg(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;k=Fa-29072|0;Fa=k;m=G[j>>2];a:{if((m|0)>0){break a}b:{n=G[a>>2];l=G[a+4>>2];c:{if((n|0)!=G[l+76>>2]){mb(a,n+1|0,0,j);break c}if((G[l+128>>2]&G[l+132>>2])!=-1){break c}if((Rb(a,j)|0)>0){break b}}d:{if((b|0)>0){l=G[a+4>>2];if(G[l+936>>2]>=(b|0)){break d}}G[k>>2]=b;a=k+28864|0;Ya(a,81,30457,k);Ua(a);m=302;G[j>>2]=302;break a}l=G[(G[l+968>>2]+M(b,160)|0)-80>>2];G[k+29068>>2]=l;e:{if((l|0)!=16){if((l|0)!=-16){break e}e=b;f=c;b=Va(G[i>>2]);b=b?b:1;c=b>>31;if((yc(a,e,f,d,1,0,b,c,1,k+29e3|0,k+28992|0,k+28960|0,k+29056|0,k+29068|0,k+29064|0,k+29032|0,k+29024|0,k+29052|0,k+29040|0,k+29016|0,k+29060|0,k+29008|0,k+28832|0,j)|0)>0){break b}Jb(a,G[k+29032>>2],G[k+29036>>2],1,j);Wb(a,b,c,G[i>>2],j);m=G[j>>2];if((m|0)<=0){break a}E[k+28920|0]=H[46002];b=H[45998]|H[45999]<<8|(H[46e3]<<16|H[46001]<<24);a=k+28912|0;G[a>>2]=H[45994]|H[45995]<<8|(H[45996]<<16|H[45997]<<24);G[a+4>>2]=b;b=H[45990]|H[45991]<<8|(H[45992]<<16|H[45993]<<24);a=k+28904|0;G[a>>2]=H[45986]|H[45987]<<8|(H[45988]<<16|H[45989]<<24);G[a+4>>2]=b;b=H[45982]|H[45983]<<8|(H[45984]<<16|H[45985]<<24);a=k+28896|0;G[a>>2]=H[45978]|H[45979]<<8|(H[45980]<<16|H[45981]<<24);G[a+4>>2]=b;b=H[45974]|H[45975]<<8|(H[45976]<<16|H[45977]<<24);a=k+28888|0;G[a>>2]=H[45970]|H[45971]<<8|(H[45972]<<16|H[45973]<<24);G[a+4>>2]=b;b=H[45966]|H[45967]<<8|(H[45968]<<16|H[45969]<<24);a=k+28880|0;G[a>>2]=H[45962]|H[45963]<<8|(H[45964]<<16|H[45965]<<24);G[a+4>>2]=b;a=H[45958]|H[45959]<<8|(H[45960]<<16|H[45961]<<24);G[k+28872>>2]=H[45954]|H[45955]<<8|(H[45956]<<16|H[45957]<<24);G[k+28876>>2]=a;a=H[45950]|H[45951]<<8|(H[45952]<<16|H[45953]<<24);G[k+28864>>2]=H[45946]|H[45947]<<8|(H[45948]<<16|H[45949]<<24);G[k+28868>>2]=a;Ua(k+28864|0);break b}if((yc(a,b,c,d,e,f,g,h,1,k+29e3|0,k+28992|0,k+28960|0,k+29056|0,k+29068|0,k+29064|0,k+29032|0,k+29024|0,k+29052|0,k+29040|0,k+29016|0,k+29060|0,k+29008|0,k+28832|0,j)|0)>0){break b}b=G[k+29056>>2];if((b|0)>=2881){G[k+29052>>2]=b;G[k+29064>>2]=1;G[k+29040>>2]=1;G[k+29044>>2]=0}c=0;d=0;if(!(g|h)){break b}e=0;f=0;while(1){b=G[k+29064>>2];o=b;m=b>>31;n=G[k+29040>>2];r=G[k+29044>>2];l=G[k+29036>>2];b=G[k+29032>>2];p=Au(G[k+29016>>2],G[k+29020>>2],e,f);b=b+p|0;l=Ia+l|0;l=b>>>0

>>0?l+1|0:l;q=b;p=G[k+29024>>2];s=G[k+29028>>2];b=G[k+29052>>2];t=Au(p,s,b,b>>31);q=q+t|0;b=Ia+l|0;Jb(a,q,q>>>0>>0?b+1|0:b,1,j);l=g>>>0>>0&(h|0)<=(m|0)|(h|0)<(m|0)?g:o;b=l;l=b>>31;m=b;b=r-((n>>>0

>>0)+s|0)|0;n=n-p|0;p=m>>>0>>0&(b|0)>=(l|0)|(b|0)>(l|0);n=p?m:n;f:{if((n|0)<=0){o=G[k+29056>>2];break f}p=c+n|0;m=k+32|0;o=G[k+29056>>2];while(1){g:{if((o|0)<=0){b=0;break g}b=0;q=G[(c<<2)+i>>2];r=H[q|0];if(!r){break g}while(1){E[m|0]=r;m=m+1|0;b=b+1|0;o=G[k+29056>>2];if((b|0)>=(o|0)){break g}r=H[q+1|0];q=q+1|0;if(r){continue}break}}if((b|0)<(o|0)){while(1){E[m|0]=32;m=m+1|0;b=b+1|0;o=G[k+29056>>2];if((b|0)<(o|0)){continue}break}}b=d;c=c+1|0;b=c?b:b+1|0;d=b;if((c|0)!=(p|0)){continue}break}}b=G[k+29052>>2];h:{if((b|0)==(o|0)){b=M(n,o);Wb(a,b,b>>31,k+32|0,j);break h}wd(a,o,n,b-o|0,k+32|0,j)}m=G[j>>2];if((m|0)>0){b=d;a=c+1|0;b=a?b:b+1|0;L[k+16>>3]=+(a>>>0)+ +(b|0)*4294967296;l=n;b=l>>31;a=c+l|0;b=b+d|0;L[k+24>>3]=+(a>>>0)+ +((a>>>0>>0?b+1|0:b)|0)*4294967296;a=k+28864|0;Ya(a,81,45816,k+16|0);Ua(a);break b}l=n;b=l>>31;h=h-((g>>>0>>0)+b|0)|0;g=g-l|0;if(!(h|g)){break a}b=b+G[k+29028>>2]|0;n=l+G[k+29024>>2]|0;b=n>>>0>>0?b+1|0:b;l=n;G[k+29024>>2]=l;G[k+29028>>2]=b;if(G[k+29040>>2]!=(l|0)|G[k+29044>>2]!=(b|0)){continue}G[k+29024>>2]=0;G[k+29028>>2]=0;b=f;e=e+1|0;b=e?b:b+1|0;f=b;continue}}m=309;G[j>>2]=309;break a}m=G[j>>2]}Fa=k+29072|0;return m}function Ie(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;d=Fa-208|0;Fa=d;a:{if(G[c>>2]>0){break a}if(!H[a|0]){G[c>>2]=204;break a}i=d+112|0;e=Fa-96|0;Fa=e;b:{c:{d:{e:{f:{if(G[c>>2]<=0){f=67;g:{h=H[a|0];switch(h-39|0){case 0:break c;case 1:break e;default:break g}}h:{switch(h-70|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:break d;case 0:case 14:break f;default:break h}}if(h){break d}G[c>>2]=204}f=H[d+207|0];break b}f=76;break c}f=88;break c}f=70;if(jb(a,46)){break c}if(jb(a,69)){break c}f=jb(a,68)?70:73}E[d+207|0]=f}i:{j:{switch((f&255)-70|0){case 3:if(G[c>>2]>0){break i}G[48624]=0;G[b>>2]=0;G[b+4>>2]=0;j=b,k=Fn(a,e+92|0),G[j>>2]=k;G[b+4>>2]=Ia;if((H[G[e+92>>2]]|32)!=32){G[c>>2]=407}if(G[48624]!=68){break i}F[e+56>>1]=H[66897]|H[66898]<<8;f=H[66893]|H[66894]<<8|(H[66895]<<16|H[66896]<<24);G[e+48>>2]=H[66889]|H[66890]<<8|(H[66891]<<16|H[66892]<<24);G[e+52>>2]=f;f=H[66885]|H[66886]<<8|(H[66887]<<16|H[66888]<<24);G[e+40>>2]=H[66881]|H[66882]<<8|(H[66883]<<16|H[66884]<<24);G[e+44>>2]=f;f=H[66877]|H[66878]<<8|(H[66879]<<16|H[66880]<<24);G[e+32>>2]=H[66873]|H[66874]<<8|(H[66875]<<16|H[66876]<<24);G[e+36>>2]=f;f=H[66869]|H[66870]<<8|(H[66871]<<16|H[66872]<<24);G[e+24>>2]=H[66865]|H[66866]<<8|(H[66867]<<16|H[66868]<<24);G[e+28>>2]=f;f=H[66861]|H[66862]<<8|(H[66863]<<16|H[66864]<<24);G[e+16>>2]=H[66857]|H[66858]<<8|(H[66859]<<16|H[66860]<<24);G[e+20>>2]=f;f=H[66853]|H[66854]<<8|(H[66855]<<16|H[66856]<<24);G[e+8>>2]=H[66849]|H[66850]<<8|(H[66851]<<16|H[66852]<<24);G[e+12>>2]=f;f=H[66845]|H[66846]<<8|(H[66847]<<16|H[66848]<<24);G[e>>2]=H[66841]|H[66842]<<8|(H[66843]<<16|H[66844]<<24);G[e+4>>2]=f;tb(5,qb(e,a,23));G[c>>2]=412;G[48624]=0;break i;case 0:me(a,d,c);break i;case 6:if(G[c>>2]>0){break i}G[d+12>>2]=H[a|0]==84;break i;default:break j}}fd(a,i,c)}Fa=e+96|0;e=403;k:{l:{m:{n:{o:{switch(H[d+207|0]-67|0){case 0:if((me(d+112|0,d,c)|0)>0){break m}e=412;g=L[d>>3];if(g>0x8000000000000000|g<-0x8000000000000000){break l}if(O(g)<0x8000000000000000){e=~~g>>>0;f=O(g)>=1?~~(g>0?Q(S(g*2.3283064365386963e-10),4294967295):T((g-+(~~g>>>0>>>0))*2.3283064365386963e-10))>>>0:0;break n}e=0;f=-2147483648;break n;case 3:e=412;g=L[d>>3];if(g>0x8000000000000000|g<-0x8000000000000000){break l}if(O(g)<0x8000000000000000){e=~~g>>>0;f=O(g)>=1?~~(g>0?Q(S(g*2.3283064365386963e-10),4294967295):T((g-+(~~g>>>0>>>0))*2.3283064365386963e-10))>>>0:0;break n}e=0;f=-2147483648;break n;case 21:break l;case 9:break o;default:break m}}e=G[d+12>>2];f=e>>31}G[b>>2]=e;G[b+4>>2]=f}if(G[c>>2]>0){break k}break a}G[c>>2]=e}G[b>>2]=0;G[b+4>>2]=0;b=H[67242]|H[67243]<<8|(H[67244]<<16|H[67245]<<24);c=H[67238]|H[67239]<<8|(H[67240]<<16|H[67241]<<24);E[d+61|0]=c;E[d+62|0]=c>>>8;E[d+63|0]=c>>>16;E[d+64|0]=c>>>24;E[d+65|0]=b;E[d+66|0]=b>>>8;E[d+67|0]=b>>>16;E[d+68|0]=b>>>24;b=H[67237]|H[67238]<<8|(H[67239]<<16|H[67240]<<24);G[d+56>>2]=H[67233]|H[67234]<<8|(H[67235]<<16|H[67236]<<24);G[d+60>>2]=b;b=H[67229]|H[67230]<<8|(H[67231]<<16|H[67232]<<24);G[d+48>>2]=H[67225]|H[67226]<<8|(H[67227]<<16|H[67228]<<24);G[d+52>>2]=b;b=H[67221]|H[67222]<<8|(H[67223]<<16|H[67224]<<24);G[d+40>>2]=H[67217]|H[67218]<<8|(H[67219]<<16|H[67220]<<24);G[d+44>>2]=b;b=H[67213]|H[67214]<<8|(H[67215]<<16|H[67216]<<24);G[d+32>>2]=H[67209]|H[67210]<<8|(H[67211]<<16|H[67212]<<24);G[d+36>>2]=b;b=H[67205]|H[67206]<<8|(H[67207]<<16|H[67208]<<24);G[d+24>>2]=H[67201]|H[67202]<<8|(H[67203]<<16|H[67204]<<24);G[d+28>>2]=b;b=H[67197]|H[67198]<<8|(H[67199]<<16|H[67200]<<24);G[d+16>>2]=H[67193]|H[67194]<<8|(H[67195]<<16|H[67196]<<24);G[d+20>>2]=b;tb(5,qb(d+16|0,a,30))}Fa=d+208|0}function rc(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;j=Fa-304|0;Fa=j;E[j+206|0]=0;G[j+40>>2]=-1;G[j+44>>2]=-1;m=G[i>>2];a:{if((m|0)>0){break a}m=j+300|0;vd(a,b,m,0,0,i);k=G[j+300>>2];n=k>>31;b:{q=c;o=d;l=f<<1|e>>>31;d=e<<1;c=(k^n)-n>>>0>82;p=c?d-1|0:e;l=c?l-!d|0:f;e=g;d=c&31;if((c&63)>>>0>=32){h=e<>>32-d|h<>>30^-1)&2,j+216|0,j+208|0,j+176|0,j+280|0,m,j+296|0,j+240|0,j+232|0,j+276|0,j+248|0,j+224|0,j+292|0,j+264|0,j+48|0,i)|0)>0){break c}m=0;d:{e:{f:{g:{d=G[j+300>>2];switch(d-11|0){case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break d;case 0:case 10:case 30:break e;case 5:break g;default:break f}}if(H[j+48|0]==1){Ua(48313);break b}c=G[j+280>>2];c=(c|0)>20?c:20;d=ab(c);if(!d){m=113;G[i>>2]=113;break a}c=cb(d,32,c);d=j+48|0;e=Va(d);m=rb(c,d,(G[j+292>>2]==2)+e|0);break d}if((d|0)!=81){break d}}e=G[j+268>>2];c=G[j+264>>2];if(!e&(c|0)==1234554321){Ua(48252);break b}h:{i:{switch(d-11|0){case 0:E[j+207|0]=c;break d;case 10:F[j+290>>1]=c;Af(j+290|0,1);break d;default:if((d|0)==41){break h}break;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:break i}}G[j+256>>2]=c;G[j+260>>2]=e;Ge(j+256|0,1);break d}G[j+284>>2]=c;ke(j+284|0,1)}j:{k:{if(!(f|n)){break k}c=0;d=0;while(1){e=G[j+248>>2];k=G[j+252>>2];h=G[j+244>>2];g=G[j+240>>2];l=Au(G[j+224>>2],G[j+228>>2],r,s);g=g+l|0;h=Ia+h|0;h=g>>>0>>0?h+1|0:h;q=g;g=G[j+232>>2];o=G[j+236>>2];l=G[j+276>>2];p=Au(g,o,l,l>>31);l=q+p|0;h=Ia+h|0;Jb(a,l,l>>>0

>>0?h+1|0:h,1,i);h=k-((e>>>0>>0)+o|0)|0;e=e-g|0;g=(f|0)<=(h|0)&e>>>0>n>>>0|(f|0)<(h|0);e=g?n:e;k=g?f:h;l:{m:{switch(G[j+300>>2]-11|0){case 0:g=0;h=0;if(!e&(k|0)<=0|(k|0)<0){break l}while(1){Wb(a,1,0,j+207|0,i);g=g+1|0;h=g?h:h+1|0;if((e|0)!=(g|0)|(h|0)!=(k|0)){continue}break};break l;case 10:g=0;h=0;if(!e&(k|0)<=0|(k|0)<0){break l}while(1){Wb(a,2,0,j+290|0,i);g=g+1|0;h=g?h:h+1|0;if((e|0)!=(g|0)|(h|0)!=(k|0)){continue}break};break l;case 30:g=0;h=0;if(!e&(k|0)<=0|(k|0)<0){break l}while(1){Wb(a,4,0,j+284|0,i);g=g+1|0;l=g?h:h+1|0;h=l;if((e|0)!=(g|0)|(k|0)!=(h|0)){continue}break};break l;case 70:g=0;h=0;if(!e&(k|0)<=0|(k|0)<0){break l}while(1){Wb(a,8,0,j+256|0,i);g=g+1|0;h=g?h:h+1|0;if((e|0)!=(g|0)|(h|0)!=(k|0)){continue}break};break l;case 31:g=0;h=0;if(!e&(k|0)<=0|(k|0)<0){break l}while(1){Wb(a,4,0,j+40|0,i);g=g+1|0;h=g?h:h+1|0;if((e|0)!=(g|0)|(h|0)!=(k|0)){continue}break};break l;case 71:g=0;h=0;if(!e&(k|0)<=0|(k|0)<0){break l}while(1){Wb(a,8,0,j+40|0,i);g=g+1|0;h=g?h:h+1|0;if((e|0)!=(g|0)|(h|0)!=(k|0)){continue}break};break l;case 5:g=G[j+280>>2];Wb(a,g,g>>31,m,i);break l;default:G[j>>2]=b;G[j+4>>2]=j+176;a=j+80|0;Ya(a,81,8867,j);Ua(a);break c;case 3:break m}}g=0;h=0;if(!e&(k|0)<=0|(k|0)<0){break l}while(1){Wb(a,1,0,j+206|0,i);g=g+1|0;h=g?h:h+1|0;if((e|0)!=(g|0)|(h|0)!=(k|0)){continue}break}}if(G[i>>2]>0){l=d+k|0;a=c+e|0;l=a>>>0>>0?l+1|0:l;L[j+24>>3]=+(a>>>0)+ +(l|0)*4294967296;h=d;a=c+1|0;h=a?h:h+1|0;L[j+16>>3]=+(a>>>0)+ +(h|0)*4294967296;a=j+80|0;Ya(a,81,45314,j+16|0);Ua(a);if(m){break j}break c}f=f-((e>>>0>n>>>0)+k|0)|0;n=n-e|0;if(!(f|n)){break k}h=d+k|0;c=c+e|0;h=c>>>0>>0?h+1|0:h;d=h;h=k+G[j+236>>2]|0;g=e+G[j+232>>2]|0;h=g>>>0>>0?h+1|0:h;e=g;G[j+232>>2]=e;G[j+236>>2]=h;if(G[j+248>>2]!=(e|0)|G[j+252>>2]!=(h|0)){continue}G[j+232>>2]=0;G[j+236>>2]=0;l=s;e=r+1|0;l=e?l:l+1|0;r=e;s=l;continue}}if(!m){break c}}Wa(m)}m=G[i>>2];break a}m=314;G[i>>2]=314}Fa=j+304|0;return m}function lt(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;if(H[1237232]){a=ck(1237232,c);if(a){Ua(39807);Ua(1237232);return a|0}i=G[c>>2];e=Fa-1008|0;Fa=e;a:{b:{h=G[30060];g=Tf(h);if((g|0)!=-1){while(1){a=0;c:{if(E[d+35530|0]!=(g|0)){break c}a=d+1|0;if((a|0)!=6){break c}F[e+4>>1]=H[35534]|H[35535]<<8;G[e>>2]=H[35530]|H[35531]<<8|(H[35532]<<16|H[35533]<<24);break b}g=Tf(h);if((g|0)!=-1){j=f>>>0<1999;f=f+1|0;d=a;if(j){continue}}break}if((a|0)==6){break b}}Ua(16450);f=104;break a}f=bk(i,e,zc(e|6,1,994,h)+6|0);if(f){break a}while(1){a=zc(e,1,1e3,h);if(!a){f=0;break a}f=bk(i,e,a);if(!f){continue}break}}Fa=e+1008|0;On(G[c>>2]);if(f){Ua(55718);Ua(1237232);return f|0}return dk(1237232,b,c)|0}f=G[30060];d=Tf(f)<<24;ak(d>>24,f);if(!((d|0)!=1258291200&(d|0)!=520093696)){f=Fa-16|0;Fa=f;d:{if(b){Ua(55362);d=112;break d}G[c>>2]=-1;d=0;e:{f:{g:{while(1){e=M(d,48)+757232|0;if(!G[e>>2]){b=d;break g}b=d+1|0;e=M(b,48)+757232|0;if(!G[e>>2]){break g}b=d+2|0;e=M(b,48)+757232|0;if(!G[e>>2]){break g}b=d+3|0;e=M(b,48)+757232|0;if(!G[e>>2]){break g}b=d+4|0;e=M(b,48)+757232|0;if(!G[e>>2]){break g}d=d+5|0;if((d|0)!=1e4){continue}break}d=103;break f}G[c>>2]=b;b=M(b,48);d=b+757236|0;G[e>>2]=d;e=b+757244|0;G[b+757240>>2]=e;g=d;d=ab(28800);G[g>>2]=d;if(d){break e}Ua(57797);d=104}Ua(55567);break d}G[e>>2]=28800;d=b+757256|0;G[d>>2]=0;G[d+4>>2]=0;G[b+757248>>2]=2880;d=b+757264|0;G[d>>2]=0;G[d+4>>2]=0;G[b+757252>>2]=17;b=G[c>>2];G[f+8>>2]=0;e=M(b,48);d=G[e+757240>>2];e=G[e+757232>>2];h=G[30060];h:{if(Sb(a,32688)){Ln(a,h,e,d,f+12|0,f+8|0);break h}hp(h,e,d,f+12|0,f+8|0)}a=M(b,48);b=a+757256|0;G[b>>2]=0;G[b+4>>2]=0;a=a+757264|0;G[a>>2]=G[f+12>>2];G[a+4>>2]=0;a=G[c>>2];d=G[f+8>>2];if(d){a=M(a,48)+757232|0;Wa(G[G[a>>2]>>2]);G[a>>2]=0;G[a+4>>2]=0;Ua(55442);break d}d=0;e=M(a,48);b=G[e+757264>>2];if(J[G[e+757240>>2]>>2]<=b+256>>>0){break d}b=ub(G[G[M(a,48)+757232>>2]>>2],b);if(!b){Ua(55503);d=113;break d}a=M(G[c>>2],48);G[G[a+757232>>2]>>2]=b;G[G[a+757240>>2]>>2]=G[a+757264>>2]}Fa=f+16|0;return d|0}if(b){Ua(5895);return 112}G[c>>2]=-1;b=0;i:{j:{k:{while(1){a=M(b,48)+757232|0;if(!G[a>>2]){d=b;break k}d=b+1|0;a=M(d,48)+757232|0;if(!G[a>>2]){break k}d=b+2|0;a=M(d,48)+757232|0;if(!G[a>>2]){break k}d=b+3|0;a=M(d,48)+757232|0;if(!G[a>>2]){break k}d=b+4|0;a=M(d,48)+757232|0;if(!G[a>>2]){break k}b=b+5|0;if((b|0)!=1e4){continue}break}a=103;break j}G[c>>2]=d;g=a;a=M(d,48);b=a+757236|0;G[g>>2]=b;d=a+757244|0;G[a+757240>>2]=d;g=b;b=ab(2880);G[g>>2]=b;if(b){break i}Ua(57797);a=104}Ua(55670);return a|0}G[d>>2]=2880;b=a+757256|0;G[b>>2]=0;G[b+4>>2]=0;G[a+757248>>2]=2880;b=a+757264|0;G[b>>2]=0;G[b+4>>2]=0;G[a+757252>>2]=17;i=G[c>>2];a=M(i,48);e=G[a+757248>>2];k=a+757240|0;f=G[G[k>>2]>>2];l=a+757232|0;d=G[G[l>>2]>>2];l:{m:{h=G[30060];g=Tf(h);n:{if((g|0)==-1){break n}b=0;while(1){a=0;o:{if(E[b+35530|0]!=(g|0)){break o}a=b+1|0;if((a|0)!=6){break o}a=H[35534]|H[35535]<<8;E[d+4|0]=a;E[d+5|0]=a>>>8;a=H[35530]|H[35531]<<8|(H[35532]<<16|H[35533]<<24);E[d|0]=a;E[d+1|0]=a>>>8;E[d+2|0]=a>>>16;E[d+3|0]=a>>>24;a=0;b=zc(d+6|0,1,f-6|0,h)+6|0;if(b>>>0>=f>>>0){break m}a=M(i,48)+757264|0;G[a>>2]=b;G[a+4>>2]=0;a=0;break l}g=Tf(h);if((g|0)==-1){break n}m=j>>>0<1999;j=j+1|0;b=a;if(m){continue}break}}Ua(43331);Ua(44068);a=104;break l}while(1){f=e+f|0;d=ub(d,f);if(!d){Ua(57845);a=113;break l}g=zc(b+d|0,1,e,h);b=b+g|0;a=b>>>0>>0?a+1|0:a;if(e>>>0<=g>>>0){continue}break}e=M(i,48)+757264|0;G[e>>2]=b;G[e+4>>2]=a;G[G[l>>2]>>2]=d;G[G[k>>2]>>2]=f;a=0}if(!a){return 0}Ua(55624);Wa(G[M(G[c>>2],48)+757236>>2]);return a|0}function mj(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;c=Fa-800736|0;Fa=c;if(G[323091]>=3){G[c+208>>2]=a;kb(76323,c+208|0);$a(G[29763])}a:{b:{l=ac(a,13287);if(l){E[c+224|0]=0;n=b&-3;i=G[29763];c:while(1){if(!vc(c+800224|0,256,l)){break b}a=(Va(c+800224|0)+c|0)+800223|0;if(H[a|0]==10){E[a|0]=0}a=(Va(c+800224|0)+c|0)+800223|0;if(H[a|0]==13){E[a|0]=0}if(G[323091]>=3){G[c+192>>2]=c+800224;kb(76800,c+192|0);$a(i)}e=Za(c+800480|0,c+800224|0);j=e+Va(e)|0;while(1){g=e;a=H[e|0];if((a|0)==32){e=g+1|0;if(g>>>0>>0){continue}}break}f=g;while(1){e=a&255;if(!(!((e|0)==61|(e|0)==32)&f>>>0>>0)){e=f;while(1){a=(a&255)-32|0;if(!(a>>>0>29|!(1<>>0>=j>>>0)){a=H[e+1|0];e=e+1|0;continue}break}E[f|0]=0;a=(H[e|0]==39)+e|0;while(1){d:{e:{switch(H[a|0]-32|0){case 0:case 7:break d;default:break e}}if(a>>>0>=j>>>0){break d}a=a+1|0;continue}break}E[a|0]=0;if(G[323091]>=2){G[c+180>>2]=e;G[c+176>>2]=g;kb(76184,c+176|0);$a(i)}f:{if(n){break f}if(!Xa(g,41261)){d=L[161745];d=d+d;h=d+ +(_b(e)|0);g:{if(O(h)<2147483648){a=~~h;break g}a=-2147483648}G[323493]=a;d=d+ +(_b(e)|0);h:{if(O(d)<2147483648){f=~~d;break h}f=-2147483648}G[925223]=f;G[c+160>>2]=a;db(c+800224|0,27455,c+160|0)}if(!Xa(g,40853)){d=L[161745];d=d+d;h=d+ +(_b(e)|0);i:{if(O(h)<2147483648){a=~~h;break i}a=-2147483648}G[323494]=a;d=d+ +(_b(e)|0);j:{if(O(d)<2147483648){f=~~d;break j}f=-2147483648}G[925224]=f;G[c+144>>2]=a;db(c+800224|0,27441,c+144|0)}if(!Xa(g,41201)){d=sb(e)+L[161745];L[462616]=d;L[c+128>>3]=d;Eb(c+800224|0,18850,c+128|0)}if(!Xa(g,40799)){d=sb(e)+L[161745];L[462617]=d;L[c+112>>3]=d;Eb(c+800224|0,18818,c+112|0)}if(!Xa(g,41229)){d=sb(e)+L[161745];L[462618]=d;L[c+96>>3]=d;Eb(c+800224|0,18867,c+96|0)}if(Xa(g,40821)){break f}d=sb(e)+L[161745];L[462619]=d;L[c+80>>3]=d;Eb(c+800224|0,18835,c+80|0)}e=Va(c+224|0);a=Va(c+800224|0);k:{if((a|0)>0){bb(e+(c+224|0)|0,c+800224|0,a);if(a>>>0>79){break k}}cb(c+224+(a+e)|0,32,80-a|0)}E[(c+e|0)+304|0]=0;m=m+1|0;if((m|0)!=1e4){continue c}break b}a=H[f+1|0];f=f+1|0;continue}}}G[c+16>>2]=a;a=c+800224|0;db(a,44404,c+16|0);G[c>>2]=a;_a(G[321435],80471,c);break a}a=G[323091];l:{m:{n:{if((b|0)==1){if((a|0)>=3){G[c+32>>2]=c+224;kb(69844,c+32|0);$a(i)}a=c+224|0;Za(1300832,a);b=rd(a);G[323483]=b;if(!b){break l}d=2e3;a=4;o:{p:{switch(G[b+3964>>2]-1|0){case 0:a=0;if(L[b+120>>3]!=1950){break o}d=1950;break o;case 1:a=1;if(L[b+120>>3]==2e3){break o}d=1950;break o;case 3:if(L[b+120>>3]!=1950){a=2;break o}a=3;d=1950;break o;case 2:break o;default:break p}}a=0}L[161743]=d;G[323484]=a;G[323488]=0;d=L[b+32>>3];if(!(d<0&L[b+40>>3]<0|d>0&L[b+40>>3]>0)){G[323488]=1;a=43704;if(G[323091]>2){break n}break m}a=43640;if(G[323091]>2){break n}break m}q:{r:{if((a|0)>=3){if((b|0)==2){G[c+48>>2]=c+224;kb(69735,c+48|0);$a(i);e=2100832;break q}G[c+64>>2]=c+224;kb(69790,c- -64|0);$a(i);break r}e=2100832;if((b|0)==2){break q}}e=2900832}a=c+224|0;Za(e,a);b=rd(a);G[323495]=b;if(!b){break l}G[925225]=b;h=L[b+32>>3];k=L[b+40>>3];L[462610]=O(h*k)*.017453292519943295*.017453292519943295;d=2e3;a=4;s:{t:{switch(G[b+3964>>2]-1|0){case 0:a=0;if(L[b+120>>3]!=1950){break s}d=1950;break s;case 1:a=1;if(L[b+120>>3]==2e3){break s}d=1950;break s;case 3:if(L[b+120>>3]!=1950){a=2;break s}a=3;d=1950;break s;case 2:break s;default:break t}}a=0}L[161749]=d;G[323496]=a;L[462614]=d;G[925226]=a;G[323500]=0;if(!(h<0&k<0|h>0&k>0)){a=43604;if(G[323091]>2){break n}break m}G[323500]=1;a=43675;if(G[323091]<3){break m}}yb(a)}Fa=c+800736|0;return}hb(84378,54,1,G[321435])}$a(G[321435]);Hb(G[321435]);sc(1);W()}function vf(a,b,c,d,e,f,g,h,i,j,k){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;if(j==0){Gj(a,a,c,d,e,k,k,h,i,k);return}r=G[a+16>>2];f=+G[a+32>>2];g=k/f;k=(i-+G[a+24>>2])/f+1;i=g+k;a:{if(O(i)<2147483648){m=~~i;break a}m=-2147483648}o=m-1|0;q=i==+(m|0);n=q?o:m;i=k-g;b:{if(O(i)<2147483648){b=~~i;break b}b=-2147483648}l=b+1|0;c:{if((n|0)>(l|0)){p=G[a+8>>2];b=G[a+44>>2];L[(p+M(c,168)|0)+8>>3]=((b|0)>(l|0)?b:l)|0;b=G[a+48>>2];l=(n|0)>(b|0);m=l?b:m;m=l?m:q?o:m;break c}b=G[a+48>>2];n=(n|0)>(b|0);p=G[a+8>>2];m=n?b:m;L[(p+M(c,168)|0)+8>>3]=(n?m:q?o:m)|0;m=G[a+44>>2];m=(l|0)<(m|0)?m:l}l=M(c,168);o=l+p|0;L[o+16>>3]=m|0;q=lb(b+1|0,4);G[o+24>>2]=q;Pf(a,c,d,e);b=l+G[a+8>>2]|0;s=L[b+16>>3];i=L[b+8>>3];d:{if(O(i)<2147483648){m=~~i;break d}m=-2147483648}i=+(m|0);if(s>=i){j=j/f;f=(h-+(r|0))/f+1;t=M(c,168);while(1){h=i-k;i=h*-h;h=g*g+i;e:{if(!(h>0)){break e}s=V(h);h=f+s;f:{if(O(h)<2147483648){b=~~h;break f}b=-2147483648}o=b-(h==+(b|0))|0;h=f-s;g:{if(O(h)<2147483648){l=~~h;break g}l=-2147483648}h:{if((o|0)<=(l|0)){break h}b=G[a+48>>2];c=G[a+44>>2];r=lb(1,8);n=l+1|0;G[r+4>>2]=n;i:{if(!q){break i}c=(c|0)>(m|0)?c:m;p=((b|0)>(c|0)?c:b)<<2;b=p+q|0;c=G[b>>2];j:{if(!c){c=0;break j}if((n|0)>2]){break j}while(1){b=c;c=G[b>>2];if(!c){c=0;break j}if((l|0)>=G[c+4>>2]){continue}break}}G[r>>2]=c;G[b>>2]=r;if((e|0)==1){break i}if(d){b=p+G[a+56>>2]|0;if((l|0)>2]){c=b;b=G[a+36>>2];G[c>>2]=(b|0)>(n|0)?b:n}b=p+G[a+60>>2]|0;if((n|0)>2]){break i}c=b;b=G[a+40>>2];G[c>>2]=(b|0)<(n|0)?b:n;break i}G[p+G[a+56>>2]>>2]=G[a+36>>2];G[p+G[a+60>>2]>>2]=G[a+40>>2]}b=G[a+48>>2];c=G[a+44>>2];n=lb(1,8);G[n+4>>2]=o;if(!q){break h}c=(c|0)>(m|0)?c:m;l=((b|0)>(c|0)?c:b)<<2;b=l+q|0;c=G[b>>2];k:{if(!c){c=0;break k}if((o|0)>2]){break k}while(1){b=c;c=G[b>>2];if(!c){c=0;break k}if((o|0)>G[c+4>>2]){continue}break}}G[n>>2]=c;G[b>>2]=n;if((e|0)==1){break h}if(d){b=l+G[a+56>>2]|0;if((o|0)<=G[b>>2]){c=b;b=G[a+36>>2];G[c>>2]=(b|0)>(o|0)?b:o}b=l+G[a+60>>2]|0;if((o|0)>2]){break h}c=b;b=G[a+40>>2];G[c>>2]=(b|0)<(o|0)?b:o;break h}G[l+G[a+56>>2]>>2]=G[a+36>>2];G[l+G[a+60>>2]>>2]=G[a+40>>2]}h=j*j+i;if(!(h>0)){break e}i=V(h);h=f+i;l:{if(O(h)<2147483648){b=~~h;break l}b=-2147483648}o=b-(h==+(b|0))|0;h=f-i;m:{if(O(h)<2147483648){l=~~h;break m}l=-2147483648}if((o|0)<=(l|0)){break e}b=G[a+48>>2];c=G[a+44>>2];r=lb(1,8);n=l+1|0;G[r+4>>2]=n;n:{if(!q){break n}c=(c|0)>(m|0)?c:m;p=((b|0)>(c|0)?c:b)<<2;b=p+q|0;c=G[b>>2];o:{if(!c){c=0;break o}if((n|0)>2]){break o}while(1){b=c;c=G[b>>2];if(!c){c=0;break o}if((l|0)>=G[c+4>>2]){continue}break}}G[r>>2]=c;G[b>>2]=r;if((e|0)==1){break n}if(d){b=p+G[a+56>>2]|0;if((l|0)>2]){c=b;b=G[a+36>>2];G[c>>2]=(b|0)>(n|0)?b:n}b=p+G[a+60>>2]|0;if((n|0)>2]){break n}c=b;b=G[a+40>>2];G[c>>2]=(b|0)<(n|0)?b:n;break n}G[p+G[a+56>>2]>>2]=G[a+36>>2];G[p+G[a+60>>2]>>2]=G[a+40>>2]}b=G[a+48>>2];c=G[a+44>>2];n=lb(1,8);G[n+4>>2]=o;if(!q){break e}c=(c|0)>(m|0)?c:m;l=((b|0)>(c|0)?c:b)<<2;b=l+q|0;c=G[b>>2];p:{if(!c){c=0;break p}if((o|0)>2]){break p}while(1){b=c;c=G[b>>2];if(!c){c=0;break p}if((o|0)>G[c+4>>2]){continue}break}}G[n>>2]=c;G[b>>2]=n;if((e|0)==1){break e}if(d){b=l+G[a+56>>2]|0;if((o|0)<=G[b>>2]){c=b;b=G[a+36>>2];G[c>>2]=(b|0)>(o|0)?b:o}b=l+G[a+60>>2]|0;if((o|0)>2]){break e}c=b;b=G[a+40>>2];G[c>>2]=(b|0)<(o|0)?b:o;break e}G[l+G[a+56>>2]>>2]=G[a+36>>2];G[l+G[a+60>>2]>>2]=G[a+40>>2]}m=m+1|0;i=+(m|0);if(i<=L[(G[a+8>>2]+t|0)+16>>3]){continue}break}}}function jp(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;c=G[a+12>>2]-5|0;d=G[a+44>>2];m=c>>>0>>0?c:d;g=G[G[a>>2]+4>>2];n=(b|0)!=4;a:{while(1){f=1;d=G[a>>2];c=G[d+16>>2];i=G[a+5820>>2]+42>>3;if(c>>>0>>0){break a}j=G[a+108>>2];k=G[a+92>>2];h=j-k|0;e=h+G[d+4>>2]|0;c=c-i|0;c=c>>>0>e>>>0?e:c;c=c>>>0<65535?c:65535;if(m>>>0>c>>>0){if(!b|!c&n|(c|0)!=(e|0)){break a}}i=(b|0)==4&(c|0)==(e|0);Si(a,0,0,i);E[(G[a+20>>2]+G[a+8>>2]|0)-4|0]=c;E[(G[a+20>>2]+G[a+8>>2]|0)-3|0]=c>>>8;d=c^-1;E[(G[a+20>>2]+G[a+8>>2]|0)-2|0]=d;E[(G[a+20>>2]+G[a+8>>2]|0)-1|0]=d>>>8;d=G[a>>2];e=G[d+28>>2];cd(e);f=G[e+20>>2];l=G[d+16>>2];f=f>>>0>>0?f:l;b:{if(!f){break b}bb(G[d+12>>2],G[e+16>>2],f);G[d+12>>2]=f+G[d+12>>2];G[e+16>>2]=f+G[e+16>>2];G[d+20>>2]=f+G[d+20>>2];G[d+16>>2]=G[d+16>>2]-f;d=G[e+20>>2];G[e+20>>2]=d-f;if((d|0)!=(f|0)){break b}G[e+16>>2]=G[e+8>>2]}if((j|0)!=(k|0)){d=c>>>0>h>>>0?h:c;bb(G[G[a>>2]+12>>2],G[a+56>>2]+G[a+92>>2]|0,d);e=G[a>>2];G[e+12>>2]=d+G[e+12>>2];G[e+16>>2]=G[e+16>>2]-d;G[e+20>>2]=d+G[e+20>>2];G[a+92>>2]=d+G[a+92>>2];c=c-d|0}if(c){e=G[a>>2];f=G[e+12>>2];h=G[e+4>>2];d=c>>>0>h>>>0?h:c;if(d){G[e+4>>2]=h-d;f=bb(f,G[e>>2],d);c:{d:{switch(G[G[e+28>>2]+24>>2]-1|0){case 0:o=e,p=gf(G[e+48>>2],f,d),G[o+48>>2]=p;break c;case 1:break d;default:break c}}o=e,p=Oc(G[e+48>>2],f,d),G[o+48>>2]=p}G[e>>2]=d+G[e>>2];G[e+8>>2]=d+G[e+8>>2];e=G[a>>2];f=G[e+12>>2]}G[e+12>>2]=c+f;G[e+16>>2]=G[e+16>>2]-c;G[e+20>>2]=G[e+20>>2]+c}if(!i){continue}break}d=G[a>>2];f=0}c=G[d+4>>2];e:{if((c|0)==(g|0)){c=G[a+108>>2];break e}e=g-c|0;c=G[a+44>>2];f:{if(e>>>0>=c>>>0){G[a+5808>>2]=2;bb(G[a+56>>2],G[d>>2]-c|0,c);d=G[a+44>>2];G[a+108>>2]=d;c=d;break f}d=G[a+108>>2];g:{if(e>>>0>2]-d>>>0){break g}d=d-c|0;G[a+108>>2]=d;g=G[a+56>>2];bb(g,c+g|0,d);c=G[a+5808>>2];if(c>>>0>1){break g}G[a+5808>>2]=c+1}bb(G[a+56>>2]+G[a+108>>2]|0,G[G[a>>2]>>2]-e|0,e);c=e+G[a+108>>2]|0;G[a+108>>2]=c;d=G[a+44>>2]}G[a+92>>2]=c;g=d;d=G[a+5812>>2];g=g-d|0;G[a+5812>>2]=(e>>>0>>0?e:g)+d}if(J[a+5824>>2]>>0){G[a+5824>>2]=c}e=3;h:{if(!f){break h}i:{j:{switch(b|0){case 0:case 4:break i;default:break j}}if(G[G[a>>2]+4>>2]){break i}e=1;if(G[a+92>>2]==(c|0)){break h}}e=G[a>>2];d=G[e+4>>2];f=G[a+60>>2]+(c^-1)|0;k:{if(d>>>0<=f>>>0){break k}h=G[a+92>>2];g=G[a+44>>2];if((h|0)<(g|0)){break k}c=c-g|0;G[a+108>>2]=c;G[a+92>>2]=h-g;d=G[a+56>>2];bb(d,d+g|0,c);c=G[a+5808>>2];if(c>>>0<=1){G[a+5808>>2]=c+1}f=G[a+44>>2]+f|0;e=G[a>>2];d=G[e+4>>2]}c=d>>>0>f>>>0?f:d;l:{if(!c){c=G[a+108>>2];break l}f=G[a+108>>2];g=G[a+56>>2];G[e+4>>2]=d-c;d=bb(f+g|0,G[e>>2],c);m:{n:{switch(G[G[e+28>>2]+24>>2]-1|0){case 0:o=e,p=gf(G[e+48>>2],d,c),G[o+48>>2]=p;break m;case 1:break n;default:break m}}o=e,p=Oc(G[e+48>>2],d,c),G[o+48>>2]=p}G[e>>2]=c+G[e>>2];G[e+8>>2]=c+G[e+8>>2];c=c+G[a+108>>2]|0;G[a+108>>2]=c}if(J[a+5824>>2]>>0){G[a+5824>>2]=c}g=G[a+92>>2];f=c-g|0;d=G[a+12>>2]-(G[a+5820>>2]+42>>3)|0;d=d>>>0<65535?d:65535;e=G[a+44>>2];if(f>>>0<(e>>>0>d>>>0?d:e)>>>0){e=0;if(!b|!((b|0)==4|(c|0)!=(g|0))|(G[G[a>>2]+4>>2]|d>>>0>>0)){break h}}e=0;e=(b|0)==4?!G[G[a>>2]+4>>2]&d>>>0>=f>>>0:e;b=d>>>0>f>>>0?f:d;Si(a,g+G[a+56>>2]|0,b,e);G[a+92>>2]=b+G[a+92>>2];a=G[a>>2];b=G[a+28>>2];cd(b);c=G[b+20>>2];d=G[a+16>>2];c=c>>>0>>0?c:d;o:{if(!c){break o}bb(G[a+12>>2],G[b+16>>2],c);G[a+12>>2]=c+G[a+12>>2];G[b+16>>2]=c+G[b+16>>2];G[a+20>>2]=c+G[a+20>>2];G[a+16>>2]=G[a+16>>2]-c;a=G[b+20>>2];G[b+20>>2]=a-c;if((a|0)!=(c|0)){break o}G[b+16>>2]=G[b+8>>2]}e=e?2:0}return e|0}function km(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;l=Fa-112|0;Fa=l;a:{b:{c:{d=b<<2;u=ab(d);if(u){v=ab(d);if(v){x=ab(d);if(x){if((b|0)<=0){break b}q=cb(x,0,d);A=b&-2;B=b&1;z=b&-4;r=b&3;w=b-1|0;while(1){g=0;e=0;d:{e:{f:{g:{while(1){d=g<<2;if(G[d+q>>2]!=1){h=a+d|0;d=0;while(1){j=G[q+(d<<2)>>2];h:{if(!j){t=O(L[G[h>>2]+(d<<3)>>3]);if(!(t>=e)){break h}e=t;s=g;p=d;break h}if((j|0)>=2){break g}}d=d+1|0;if((d|0)!=(b|0)){continue}break}}g=g+1|0;if((g|0)!=(b|0)){continue}break}m=p<<2;d=m+q|0;G[d>>2]=G[d>>2]+1;if((p|0)==(s|0)){break d}j=G[a+m>>2];n=s<<2;f=G[n+a>>2];h=0;d=0;g=0;if(w>>>0>2){break f}break e}G[l+96>>2]=41380;_a(G[321435],80504,l+96|0);break a}while(1){i=d<<3;k=i+f|0;e=L[k>>3];o=k;k=j+i|0;L[o>>3]=L[k>>3];L[k>>3]=e;k=i|8;o=k+f|0;e=L[o>>3];k=j+k|0;L[o>>3]=L[k>>3];L[k>>3]=e;k=i|16;o=k+f|0;e=L[o>>3];k=j+k|0;L[o>>3]=L[k>>3];L[k>>3]=e;i=i|24;k=i+f|0;e=L[k>>3];i=j+i|0;L[k>>3]=L[i>>3];L[i>>3]=e;d=d+4|0;g=g+4|0;if((z|0)!=(g|0)){continue}break}}if(r){while(1){g=d<<3;i=g+f|0;e=L[i>>3];g=g+j|0;L[i>>3]=L[g>>3];L[g>>3]=e;d=d+1|0;h=h+1|0;if((r|0)!=(h|0)){continue}break}}g=G[c+m>>2];j=G[c+n>>2];h=0;d=0;while(1){f=d<<3;i=f+j|0;e=L[i>>3];f=g+f|0;L[i>>3]=L[f>>3];L[f>>3]=e;d=d+1|0;h=h+1|0;if((h|0)!=1){continue}break}}d=y<<2;G[d+v>>2]=s;G[d+u>>2]=p;i:{j:{j=G[a+m>>2];i=p<<3;d=j+i|0;e=L[d>>3];if(e!=0){G[d>>2]=0;G[d+4>>2]=1072693248;e=1/e;g=0;d=0;h=0;if(w>>>0>2){break j}break i}G[l+48>>2]=40903;_a(G[321435],80504,l+48|0);break a}while(1){f=d<<3;n=f+j|0;L[n>>3]=e*L[n>>3];n=j+(f|8)|0;L[n>>3]=e*L[n>>3];n=j+(f|16)|0;L[n>>3]=e*L[n>>3];f=j+(f|24)|0;L[f>>3]=e*L[f>>3];d=d+4|0;h=h+4|0;if((z|0)!=(h|0)){continue}break}}if(r){while(1){h=j+(d<<3)|0;L[h>>3]=e*L[h>>3];d=d+1|0;g=g+1|0;if((r|0)!=(g|0)){continue}break}}g=G[c+m>>2];h=0;d=0;while(1){f=g+(d<<3)|0;L[f>>3]=e*L[f>>3];d=d+1|0;h=h+1|0;if((h|0)!=1){continue}break}n=c+m|0;g=0;while(1){if((g|0)!=(p|0)){k=g<<2;m=G[k+a>>2];d=m+i|0;e=L[d>>3];G[d>>2]=0;G[d+4>>2]=0;d=0;h=0;if(w){while(1){f=d<<3;o=f+m|0;L[o>>3]=L[o>>3]-L[f+j>>3]*e;f=f|8;o=f+m|0;L[o>>3]=L[o>>3]-L[f+j>>3]*e;d=d+2|0;h=h+2|0;if((A|0)!=(h|0)){continue}break}}if(B){d=d<<3;h=d+m|0;L[h>>3]=L[h>>3]-L[d+j>>3]*e}d=G[c+k>>2];L[d>>3]=L[d>>3]-L[G[n>>2]>>3]*e}g=g+1|0;if((g|0)!=(b|0)){continue}break}y=y+1|0;if((y|0)!=(b|0)){continue}break}break c}G[l+32>>2]=63787;_a(G[321435],80504,l+32|0);break a}G[l+16>>2]=63787;_a(G[321435],80504,l+16|0);break a}G[l>>2]=63787;_a(G[321435],80504,l);break a}if((b|0)<=0){break b}j=b&-2;m=b&1;p=b;while(1){g=p;p=g-1|0;c=p<<2;s=G[c+v>>2];h=G[c+u>>2];k:{if((s|0)==(h|0)){break k}d=0;c=0;if(w){while(1){f=d<<2;r=G[f+a>>2];i=s<<3;q=r+i|0;e=L[q>>3];k=q;q=r;r=h<<3;q=q+r|0;L[k>>3]=L[q>>3];L[q>>3]=e;f=G[(f|4)+a>>2];i=f+i|0;e=L[i>>3];f=f+r|0;L[i>>3]=L[f>>3];L[f>>3]=e;d=d+2|0;c=c+2|0;if((j|0)!=(c|0)){continue}break}}if(!m){break k}c=G[(d<<2)+a>>2];d=c+(s<<3)|0;e=L[d>>3];c=c+(h<<3)|0;L[d>>3]=L[c>>3];L[c>>3]=e}if((g|0)>1){continue}break}}if(H[1287936]){yb(36476);p=-1;e=0;l:{if((b|0)<=0){g=-1;break l}c=0;g=-1;while(1){s=(c<<2)+a|0;d=0;while(1){h=G[(d<<2)+a>>2];j=c<<3;t=L[h+j>>3]/V(O(L[h+(d<<3)>>3]*L[j+G[s>>2]>>3]));L[l+80>>3]=t;gb(66395,l+80|0);m:{if((c|0)==(d|0)){break m}t=O(t);if(!(t>e)){break m}g=d;p=c;e=t}d=d+1|0;if((d|0)!=(b|0)){continue}break}id();c=c+1|0;if((c|0)!=(b|0)){continue}break}}G[l+76>>2]=p;G[l+72>>2]=g;L[l+64>>3]=e;gb(91999,l- -64|0)}Wa(x);Wa(v);Wa(u);Fa=l+112|0;return}$a(G[321435]);Hb(G[321435]);sc(1);W()}function Og(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;j=Fa-304|0;Fa=j;E[j+206|0]=0;G[j+40>>2]=-1;G[j+44>>2]=-1;k=G[i>>2];a:{if((k|0)>0){break a}k=j+300|0;vd(a,b,k,0,0,i);b:{c:{if((yc(a,b,c,d,e,f,g,h,(G[j+300>>2]>>>30^-1)&2,j+216|0,j+208|0,j+176|0,j+280|0,k,j+296|0,j+240|0,j+232|0,j+276|0,j+248|0,j+224|0,j+292|0,j+264|0,j+48|0,i)|0)>0){break c}k=0;d:{e:{f:{g:{d=G[j+300>>2];switch(d-11|0){case 1:case 2:case 3:case 4:case 6:case 7:case 8:case 9:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break d;case 0:case 10:case 30:break e;case 5:break g;default:break f}}if(H[j+48|0]==1){Ua(48313);break b}c=G[j+280>>2];c=(c|0)>20?c:20;d=ab(c);if(!d){k=113;G[i>>2]=113;break a}c=cb(d,32,c);d=j+48|0;e=Va(d);k=rb(c,d,(G[j+292>>2]==2)+e|0);break d}if((d|0)!=81){break d}}e=G[j+268>>2];c=G[j+264>>2];if(!e&(c|0)==1234554321){Ua(48252);break b}h:{i:{switch(d-11|0){case 0:E[j+207|0]=c;break d;case 10:F[j+290>>1]=c;Af(j+290|0,1);break d;default:if((d|0)==41){break h}break;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:break i}}G[j+256>>2]=c;G[j+260>>2]=e;Ge(j+256|0,1);break d}G[j+284>>2]=c;ke(j+284|0,1)}j:{k:{if(!(g|h)){break k}while(1){c=G[j+248>>2];r=G[j+252>>2];d=G[j+244>>2];e=G[j+240>>2];f=Au(G[j+224>>2],G[j+228>>2],n,o);e=e+f|0;d=Ia+d|0;d=e>>>0>>0?d+1|0:d;s=e;e=G[j+232>>2];p=G[j+236>>2];f=G[j+276>>2];q=Au(e,p,f,f>>31);f=s+q|0;d=Ia+d|0;Jb(a,f,f>>>0>>0?d+1|0:d,1,i);d=r-((c>>>0>>0)+p|0)|0;c=c-e|0;e=c;c=c>>>0>g>>>0&(d|0)>=(h|0)|(d|0)>(h|0);e=c?g:e;f=c?h:d;l:{m:{switch(G[j+300>>2]-11|0){case 0:c=0;d=0;if(!e&(f|0)<=0|(f|0)<0){break l}while(1){Wb(a,1,0,j+207|0,i);c=c+1|0;d=c?d:d+1|0;if((e|0)!=(c|0)|(d|0)!=(f|0)){continue}break};break l;case 10:c=0;d=0;if(!e&(f|0)<=0|(f|0)<0){break l}while(1){Wb(a,2,0,j+290|0,i);c=c+1|0;d=c?d:d+1|0;if((e|0)!=(c|0)|(d|0)!=(f|0)){continue}break};break l;case 30:c=0;d=0;if(!e&(f|0)<=0|(f|0)<0){break l}while(1){Wb(a,4,0,j+284|0,i);c=c+1|0;d=c?d:d+1|0;if((e|0)!=(c|0)|(d|0)!=(f|0)){continue}break};break l;case 70:c=0;d=0;if(!e&(f|0)<=0|(f|0)<0){break l}while(1){Wb(a,8,0,j+256|0,i);c=c+1|0;d=c?d:d+1|0;if((e|0)!=(c|0)|(d|0)!=(f|0)){continue}break};break l;case 31:c=0;d=0;if(!e&(f|0)<=0|(f|0)<0){break l}while(1){Wb(a,4,0,j+40|0,i);c=c+1|0;d=c?d:d+1|0;if((e|0)!=(c|0)|(d|0)!=(f|0)){continue}break};break l;case 71:c=0;d=0;if(!e&(f|0)<=0|(f|0)<0){break l}while(1){Wb(a,8,0,j+40|0,i);c=c+1|0;d=c?d:d+1|0;if((e|0)!=(c|0)|(d|0)!=(f|0)){continue}break};break l;case 5:c=G[j+280>>2];Wb(a,c,c>>31,k,i);break l;default:G[j>>2]=b;G[j+4>>2]=j+176;a=j+80|0;Ya(a,81,8867,j);Ua(a);break c;case 3:break m}}c=0;d=0;if(!e&(f|0)<=0|(f|0)<0){break l}while(1){Wb(a,1,0,j+206|0,i);c=c+1|0;d=c?d:d+1|0;if((e|0)!=(c|0)|(d|0)!=(f|0)){continue}break}}if(G[i>>2]>0){d=f+m|0;a=e+l|0;d=a>>>0>>0?d+1|0:d;L[j+24>>3]=+(a>>>0)+ +(d|0)*4294967296;d=m;a=l+1|0;d=a?d:d+1|0;L[j+16>>3]=+(a>>>0)+ +(d|0)*4294967296;a=j+80|0;Ya(a,81,45314,j+16|0);Ua(a);if(k){break j}break c}h=h-((e>>>0>g>>>0)+f|0)|0;g=g-e|0;if(!(h|g)){break k}d=f+m|0;c=e+l|0;d=c>>>0>>0?d+1|0:d;l=c;m=d;d=f+G[j+236>>2]|0;c=e+G[j+232>>2]|0;d=c>>>0>>0?d+1|0:d;G[j+232>>2]=c;G[j+236>>2]=d;if(G[j+248>>2]!=(c|0)|G[j+252>>2]!=(d|0)){continue}G[j+232>>2]=0;G[j+236>>2]=0;d=o;c=n+1|0;d=c?d:d+1|0;n=c;o=d;continue}}if(!k){break c}}Wa(k)}k=G[i>>2];break a}k=314;G[i>>2]=314}Fa=j+304|0;return k}function Li(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0;u=(d|0)>(e|0)?d:e;x=oc(+N(u|0))/.6931471805599453+.5;a:{if(O(x)<2147483648){g=~~x;break a}g=-2147483648}h=e+1|0;j=d+1|0;y=M((h|0)/2|0,(j|0)/2|0);v=(y+1|0)/2|0;k=ab(v<<1);t=ab(v);if(!(!k|!t)){if((f|0)>0){z=g+((u|0)>1<>1;B=j>>1;C=M(A,B);while(1){u=f;f=f-1|0;bp(b,c,d,e,k,f);q=0;i=0;j=0;r=0;b:{c:{if((C|0)>0){while(1){g=H[i+k|0];d:{if(!g){break d}g=g<<2;r=G[g+118592>>2]<>2]+j|0;if((j|0)<8){break d}E[q+t|0]=r;q=q+1|0;if((v|0)<=(q|0)){break c}j=j-8|0;r=r>>8}i=i+1|0;if((C|0)!=(i|0)){continue}break}}w=1;m=A;o=B;if((z|0)>1){while(1){g=0;e:{if((o|0)<2){n=0;break e}if((m|0)>=2){D=o-1|0;F=m&-2;s=(m-2>>>1|0)+1|0;n=0;while(1){p=g+s|0;i=M(m,n);l=m+i|0;while(1){h=k+l|0;E[g+k|0]=(H[h|0]!=0)<<1|H[h+1|0]!=0|(H[(i|1)+k|0]!=0)<<2|(H[i+k|0]!=0)<<3;l=l+2|0;i=i+2|0;h=g;g=g+1|0;if((p|0)!=(g|0)){continue}break}f:{if(m>>>0>F>>>0){E[k+p|0]=(H[i+k|0]!=0)<<3|(H[k+l|0]!=0)<<1;g=h+2|0;break f}g=p}n=n+2|0;if((D|0)>(n|0)){continue}break}break e}if((m|0)!=1){n=o&-2;break e}h=o-2|0;g=(h>>>1|0)+1|0;p=g&1;i=0;n=0;if(h>>>0>=2){h=g&-2;l=0;while(1){E[i+k|0]=(H[k+n|0]!=0)<<3|(H[(n|1)+k|0]!=0)<<1;E[(i|1)+k|0]=(H[(n|2)+k|0]!=0)<<3|(H[(n|3)+k|0]!=0)<<1;n=n+4|0;i=i+2|0;l=l+2|0;if((h|0)!=(l|0)){continue}break}}if(!p){break e}E[i+k|0]=(H[k+n|0]!=0)<<3|(H[(n|1)+k|0]!=0)<<1;n=n+2|0}g:{if((n|0)>=(o|0)){break g}i=M(m,n);l=0;if((m|0)>=2){h=m-1|0;while(1){E[g+k|0]=(H[i+k|0]!=0)<<3|(H[(i|1)+k|0]!=0)<<2;i=i+2|0;g=g+1|0;l=l+2|0;if((h|0)>(l|0)){continue}break}h=m&-2}else{h=0}if((h|0)>=(m|0)){break g}E[g+k|0]=(H[i+k|0]!=0)<<3}i=0;m=m+1>>1;o=o+1>>1;h=M(m,o);if((h|0)>0){while(1){g=H[i+k|0];h:{if(!g){break h}g=g<<2;r=G[g+118592>>2]<>2]+j|0;if((j|0)<8){break h}E[q+t|0]=r;q=q+1|0;if((v|0)<=(q|0)){break c}j=j-8|0;r=r>>8}i=i+1|0;if((h|0)!=(i|0)){continue}break}}w=w+1|0;if((w|0)!=(z|0)){continue}break}}h=G[48830];i=h-4|0;G[48830]=i;l=G[48829]<<4|15;G[48829]=l;if((h|0)<=4){g=G[48828];E[g+a|0]=l>>4-h;if((g|0)>>0<4?g+1|0:g;s=p;G[48832]=p;G[48833]=g;if(!q){if((j|0)>0){o=i-j|0;G[48830]=o;h=G[(j<<2)+118720>>2]&((-1<>0-o;if((p|0)>>0>>0?g+1|0:g;G[48832]=h;G[48833]=g;break b}G[48830]=i-6;g=l<<6|62;G[48829]=g;if((i|0)<=6){j=G[48828];E[j+a|0]=g>>6-i;if((j|0)>>0<10?h+1|0:h;G[48832]=g;G[48833]=h;break b}if((j|0)>0){i=i-j|0;G[48830]=i;l=G[(j<<2)+118720>>2]&((-1<>0-i;if((h|0)>>0>>0?g+1|0:g;s=h;G[48832]=h;G[48833]=g}if((q|0)<=0){break b}p=G[48827];m=G[48828];while(1){j=q;q=j-1|0;l=H[t+q|0]|l<<8;i:{if((i|0)>8){i=i-8|0;break i}E[a+m|0]=l>>8-i;if((m|0)>=(p|0)){break i}m=m+1|0;G[48828]=m}h=s+8|0;g=h>>>0<8?g+1|0:g;s=h;if(j>>>0>1){continue}break}G[48830]=i;G[48829]=l;G[48832]=s;G[48833]=g;break b}g=G[48829]<<4;G[48829]=g;h=G[48830];G[48830]=h-4;if((h|0)<=4){j=G[48828];E[j+a|0]=g>>4-h;if((j|0)>>0<4?g+1|0:g;G[48832]=j;G[48833]=g;bp(b,c,d,e,k,f);ap(a,y,k)}if((u|0)>1){continue}break}}Wa(t);Wa(k);return 0}Ua(3023);return 413}function Ki(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0;u=(d|0)>(e|0)?d:e;x=oc(+N(u|0))/.6931471805599453+.5;a:{if(O(x)<2147483648){g=~~x;break a}g=-2147483648}h=e+1|0;j=d+1|0;y=M((h|0)/2|0,(j|0)/2|0);v=(y+1|0)/2|0;k=ab(v<<1);t=ab(v);if(!(!k|!t)){if((f|0)>0){z=g+((u|0)>1<>1;B=j>>1;C=M(A,B);while(1){u=f;f=f-1|0;$o(b,c,d,e,k,f);q=0;i=0;j=0;r=0;b:{c:{if((C|0)>0){while(1){g=H[i+k|0];d:{if(!g){break d}g=g<<2;r=G[g+118592>>2]<>2]+j|0;if((j|0)<8){break d}E[q+t|0]=r;q=q+1|0;if((v|0)<=(q|0)){break c}j=j-8|0;r=r>>8}i=i+1|0;if((C|0)!=(i|0)){continue}break}}w=1;m=A;o=B;if((z|0)>1){while(1){g=0;e:{if((o|0)<2){n=0;break e}if((m|0)>=2){D=o-1|0;F=m&-2;s=(m-2>>>1|0)+1|0;n=0;while(1){p=g+s|0;i=M(m,n);l=m+i|0;while(1){h=k+l|0;E[g+k|0]=(H[h|0]!=0)<<1|H[h+1|0]!=0|(H[(i|1)+k|0]!=0)<<2|(H[i+k|0]!=0)<<3;l=l+2|0;i=i+2|0;h=g;g=g+1|0;if((p|0)!=(g|0)){continue}break}f:{if(m>>>0>F>>>0){E[k+p|0]=(H[i+k|0]!=0)<<3|(H[k+l|0]!=0)<<1;g=h+2|0;break f}g=p}n=n+2|0;if((D|0)>(n|0)){continue}break}break e}if((m|0)!=1){n=o&-2;break e}h=o-2|0;g=(h>>>1|0)+1|0;p=g&1;i=0;n=0;if(h>>>0>=2){h=g&-2;l=0;while(1){E[i+k|0]=(H[k+n|0]!=0)<<3|(H[(n|1)+k|0]!=0)<<1;E[(i|1)+k|0]=(H[(n|2)+k|0]!=0)<<3|(H[(n|3)+k|0]!=0)<<1;n=n+4|0;i=i+2|0;l=l+2|0;if((h|0)!=(l|0)){continue}break}}if(!p){break e}E[i+k|0]=(H[k+n|0]!=0)<<3|(H[(n|1)+k|0]!=0)<<1;n=n+2|0}g:{if((n|0)>=(o|0)){break g}i=M(m,n);l=0;if((m|0)>=2){h=m-1|0;while(1){E[g+k|0]=(H[i+k|0]!=0)<<3|(H[(i|1)+k|0]!=0)<<2;i=i+2|0;g=g+1|0;l=l+2|0;if((h|0)>(l|0)){continue}break}h=m&-2}else{h=0}if((h|0)>=(m|0)){break g}E[g+k|0]=(H[i+k|0]!=0)<<3}i=0;m=m+1>>1;o=o+1>>1;h=M(m,o);if((h|0)>0){while(1){g=H[i+k|0];h:{if(!g){break h}g=g<<2;r=G[g+118592>>2]<>2]+j|0;if((j|0)<8){break h}E[q+t|0]=r;q=q+1|0;if((v|0)<=(q|0)){break c}j=j-8|0;r=r>>8}i=i+1|0;if((h|0)!=(i|0)){continue}break}}w=w+1|0;if((w|0)!=(z|0)){continue}break}}h=G[48830];i=h-4|0;G[48830]=i;l=G[48829]<<4|15;G[48829]=l;if((h|0)<=4){g=G[48828];E[g+a|0]=l>>4-h;if((g|0)>>0<4?g+1|0:g;s=p;G[48832]=p;G[48833]=g;if(!q){if((j|0)>0){o=i-j|0;G[48830]=o;h=G[(j<<2)+118720>>2]&((-1<>0-o;if((p|0)>>0>>0?g+1|0:g;G[48832]=h;G[48833]=g;break b}G[48830]=i-6;g=l<<6|62;G[48829]=g;if((i|0)<=6){j=G[48828];E[j+a|0]=g>>6-i;if((j|0)>>0<10?h+1|0:h;G[48832]=g;G[48833]=h;break b}if((j|0)>0){i=i-j|0;G[48830]=i;l=G[(j<<2)+118720>>2]&((-1<>0-i;if((h|0)>>0>>0?g+1|0:g;s=h;G[48832]=h;G[48833]=g}if((q|0)<=0){break b}p=G[48827];m=G[48828];while(1){j=q;q=j-1|0;l=H[t+q|0]|l<<8;i:{if((i|0)>8){i=i-8|0;break i}E[a+m|0]=l>>8-i;if((m|0)>=(p|0)){break i}m=m+1|0;G[48828]=m}h=s+8|0;g=h>>>0<8?g+1|0:g;s=h;if(j>>>0>1){continue}break}G[48830]=i;G[48829]=l;G[48832]=s;G[48833]=g;break b}g=G[48829]<<4;G[48829]=g;h=G[48830];G[48830]=h-4;if((h|0)<=4){j=G[48828];E[j+a|0]=g>>4-h;if((j|0)>>0<4?g+1|0:g;G[48832]=j;G[48833]=g;$o(b,c,d,e,k,f);ap(a,y,k)}if((u|0)>1){continue}break}}Wa(t);Wa(k);return 0}Ua(3149);return 413}function Qs(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;h=G[309722];k=G[a+16>>2];p=h+M(k,344)|0;l=G[a+12>>2];o=M(l,344)+h|0;a:{if(G[o>>2]!=-1e3){j=G[o+56>>2];d=0;break a}d=L[o+88>>3]}b:{if(G[p>>2]!=-1e3){i=G[(M(k,344)+h|0)+56>>2];c=0;break b}c=L[(M(k,344)+h|0)+88>>3]}b=G[a>>2];c:{if(!(i|j)){d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{switch(b-278|0){default:n:{switch(b-37|0){case 10:break h;case 0:break i;case 5:break j;case 8:break k;case 6:break l;case 1:case 2:case 3:case 4:case 7:case 9:break d;default:break n}}if((b|0)!=126){break d}E[a+88|0]=O(d-c)<1e-7;break d;case 0:E[a+88|0]=c==d;break d;case 1:E[a+88|0]=c!=d;break d;case 2:E[a+88|0]=cd;break d;case 4:E[a+88|0]=c>=d;break d;case 7:break g;case 5:break m;case 6:case 8:case 9:case 10:case 11:break d;case 13:break e;case 12:break f}}E[a+88|0]=c<=d;break d}L[a+88>>3]=d+c;break d}L[a+88>>3]=d-c;break d}L[a+88>>3]=d*c;break d}if(c!=0){m=d/c;o:{if(O(m)<2147483648){b=~~m;break o}b=-2147483648}L[a+88>>3]=d-c*+(b|0);break d}wc(13540);break d}if(c!=0){L[a+88>>3]=d/c;break d}wc(13540);break d}v=a,w=$b(d,c),L[v+88>>3]=w;break d}L[a+88>>3]=d;break d}G[a+88>>2]=0;G[a+92>>2]=0}G[a>>2]=-1e3;break c}g=G[a+56>>2];f=G[309727];if((b&-2)==290){Nd(a);if(G[309737]){break c}f=M(f,g);g=M(k,344)+h|0;e=G[g+84>>2];c=L[g+88>>3];p:{if(G[a>>2]!=290){if((f|0)<=0){break p}j=M(l,344)+h|0;i=G[j+84>>2];b=0;while(1){n=b<<3;d=L[n+G[j+88>>2]>>3];e=H[b+i|0]|e;L[n+G[a+88>>2]>>3]=e?0:d-c;E[G[a+84>>2]+b|0]=(e|0)!=0;i=G[j+84>>2];e=E[i+b|0];c=d;b=b+1|0;if((f|0)!=(b|0)){continue}break}break p}if((f|0)<=0){break p}i=M(l,344)+h|0;b=0;while(1){c=H[G[i+84>>2]+b|0]?c:c+L[G[i+88>>2]+(b<<3)>>3];L[G[a+88>>2]+(b<<3)>>3]=c;E[G[a+84>>2]+b|0]=0;b=b+1|0;if((f|0)!=(b|0)){continue}break}}L[g+88>>3]=c;G[g+84>>2]=e;break c}Nd(a);if(G[309737]|!f){break c}b=M(f,g);n=M(k,344)+h|0;q=M(l,344)+h|0;r=(j|0)>1;while(1){f=f-1|0;e=0;q:{if(!g){break q}while(1){b=b-1|0;if(j){e=r?b:f;s=H[e+G[q+84>>2]|0];d=L[G[q+88>>2]+(e<<3)>>3]}if(i){e=(i|0)>1?b:f;t=H[e+G[n+84>>2]|0];c=L[G[n+88>>2]+(e<<3)>>3]}g=g-1|0;E[G[a+84>>2]+b|0]=(s|t)!=0;r:{s:{t:{u:{v:{w:{x:{y:{z:{A:{B:{C:{D:{E:{e=G[a>>2];switch(e-278|0){case 6:break r;case 7:break s;case 5:break y;case 4:break z;case 3:break A;case 2:break B;case 1:break C;case 0:break D;default:break E}}F:{switch(e-37|0){case 1:case 2:case 3:case 4:case 7:case 9:break r;case 10:break t;case 0:break u;case 5:break v;case 8:break w;case 6:break x;default:break F}}if((e|0)!=126){break r}E[G[a+88>>2]+b|0]=O(d-c)<1e-7;break r}E[G[a+88>>2]+b|0]=c==d;break r}E[G[a+88>>2]+b|0]=c!=d;break r}E[G[a+88>>2]+b|0]=c>2]+b|0]=c>d;break r}E[G[a+88>>2]+b|0]=c>=d;break r}E[G[a+88>>2]+b|0]=c<=d;break r}L[G[a+88>>2]+(b<<3)>>3]=d+c;break r}L[G[a+88>>2]+(b<<3)>>3]=d-c;break r}L[G[a+88>>2]+(b<<3)>>3]=d*c;break r}if(c!=0){u=G[a+88>>2]+(b<<3)|0;m=d/c;G:{if(O(m)<2147483648){e=~~m;break G}e=-2147483648}L[u>>3]=d-c*+(e|0);break r}e=G[a+88>>2]+(b<<3)|0;G[e>>2]=0;G[e+4>>2]=0;E[G[a+84>>2]+b|0]=1;break r}if(c!=0){L[G[a+88>>2]+(b<<3)>>3]=d/c;break r}e=G[a+88>>2]+(b<<3)|0;G[e>>2]=0;G[e+4>>2]=0;E[G[a+84>>2]+b|0]=1;break r}v=G[a+88>>2]+(b<<3)|0,w=$b(d,c),L[v>>3]=w}e=G[309737];if(!g){break q}if(!e){continue}break}}if(!f){break c}g=G[a+56>>2];if(!e){continue}break}}if(G[o>>2]>0){Wa(G[(M(l,344)+h|0)+88>>2])}if(G[p>>2]>0){Wa(G[(M(k,344)+h|0)+88>>2])}}function Nc(a,b,c,d,e,f,g,h,i,j,k,l){var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;m=Fa-208|0;Fa=m;a:{if(G[l>>2]>0){break a}w=vk(b);G[m+88>>2]=0;G[m+92>>2]=0;G[m+80>>2]=0;G[m+84>>2]=0;G[m+72>>2]=0;G[m+76>>2]=0;n=m- -64|0;G[n>>2]=0;G[n+4>>2]=0;G[m+16>>2]=0;G[m+20>>2]=0;G[m+24>>2]=0;G[m+28>>2]=0;G[m+32>>2]=0;G[m+36>>2]=0;G[m+40>>2]=0;G[m+44>>2]=0;G[m+56>>2]=0;G[m+60>>2]=0;G[m+48>>2]=0;G[m+52>>2]=0;G[m>>2]=0;G[m+4>>2]=0;G[m+8>>2]=0;G[m+12>>2]=0;G[m+176>>2]=1;G[m+144>>2]=1;G[m+180>>2]=1;G[m+184>>2]=1;G[m+148>>2]=1;G[m+152>>2]=1;G[m+188>>2]=1;G[m+156>>2]=1;G[m+192>>2]=1;G[m+196>>2]=1;G[m+160>>2]=1;G[m+164>>2]=1;Qd(a,m+204|0,l);de(a,6,m+176|0,l);G[m+96>>2]=1;G[m+100>>2]=0;s=G[m+180>>2];x=G[m+176>>2];p=x;n=p>>31;G[m+104>>2]=p;G[m+108>>2]=n;n=Au(p,n,s,s>>31);G[m+112>>2]=n;p=Ia;G[m+116>>2]=p;o=n;n=G[m+184>>2];n=Au(o,p,n,n>>31);G[m+120>>2]=n;p=Ia;G[m+124>>2]=p;o=n;n=G[m+188>>2];n=Au(o,p,n,n>>31);G[m+128>>2]=n;p=Ia;G[m+132>>2]=p;o=n;n=G[m+192>>2];A=m,B=Au(o,p,n,n>>31),G[A+136>>2]=B;G[m+140>>2]=Ia;p=G[m+204>>2];if((p|0)>0){n=e;e=c;c=c-1|0;n=n+c|0;d=d-!e|0;f=d+f|0;f=c>>>0>n>>>0?f+1|0:f;e=n-1|0;f=f-!n|0;n=p;while(1){v=n-1|0;o=v<<3;t=o+(m+96|0)|0;q=G[t>>2];t=G[t+4>>2];y=Bu(c,d,q,t);r=Ia;z=r;u=o+(m+48|0)|0;G[u>>2]=y;G[u+4>>2]=r;o=m+o|0;r=Bu(e,f,q,t);G[o>>2]=r;u=Ia;G[o+4>>2]=u;o=e;r=Au(q,t,r,u);e=e-r|0;f=f-(Ia+(o>>>0>>0)|0)|0;o=c;q=Au(q,t,y,z);c=c-q|0;d=d-(Ia+(o>>>0>>0)|0)|0;o=n>>>0>1;n=v;if(o){continue}break}}b:{c:{switch(p-1|0){case 1:qo(a,b,w,0,m+48|0,m,m+144|0,m+176|0,g,h,i,j,k,m+172|0,l);break b;case 2:d:{if(G[m+48>>2]|G[m+56>>2]|(G[m+52>>2]|G[m+60>>2])){break d}d=G[m>>2];e=x-1|0;c=G[m+4>>2];if((d|0)!=(e|0)|(c|0)!=e>>31){break d}e=G[m+8>>2];n=s-1|0;f=G[m+12>>2];if((e|0)!=(n|0)|(f|0)!=n>>31){break d}G[m+48>>2]=1;G[m+52>>2]=0;G[m+56>>2]=1;G[m+60>>2]=0;d=d+1|0;c=d?c:c+1|0;G[m>>2]=d;G[m+4>>2]=c;c=e+1|0;f=c?f:f+1|0;G[m+8>>2]=c;G[m+12>>2]=f;c=G[m+68>>2];d=G[m+64>>2]+1|0;c=d?c:c+1|0;G[m+64>>2]=d;G[m+68>>2]=c;d=G[m+20>>2];c=G[m+16>>2]+1|0;d=c?d:d+1|0;G[m+16>>2]=c;G[m+20>>2]=d;f=G[m+76>>2];c=G[m+72>>2]+1|0;f=c?f:f+1|0;G[m+72>>2]=c;G[m+76>>2]=f;c=G[m+28>>2];d=G[m+24>>2]+1|0;c=d?c:c+1|0;G[m+24>>2]=d;G[m+28>>2]=c;d=G[m+84>>2];c=G[m+80>>2]+1|0;d=c?d:d+1|0;G[m+80>>2]=c;G[m+84>>2]=d;f=G[m+36>>2];c=G[m+32>>2]+1|0;f=c?f:f+1|0;G[m+32>>2]=c;G[m+36>>2]=f;c=G[m+92>>2];d=G[m+88>>2]+1|0;c=d?c:c+1|0;G[m+88>>2]=d;G[m+92>>2]=c;d=G[m+44>>2];c=G[m+40>>2]+1|0;d=c?d:d+1|0;G[m+40>>2]=c;G[m+44>>2]=d;md(a,b,m+48|0,m,m+144|0,g,h,i,j,k,l);break b}if(k){G[k>>2]=0}p=G[m+8>>2];v=G[m+12>>2];o=G[m>>2];q=G[m+4>>2];e=G[m+64>>2];n=G[m+16>>2];d=G[m+68>>2];c=G[m+20>>2];if(e>>>0>>0&(d|0)<=(c|0)|(c|0)>(d|0)){f=s-1|0;G[m+8>>2]=f;G[m+12>>2]=f>>31;f=x-1|0;G[m>>2]=f;G[m+4>>2]=f>>31}d=e;f=d>>31;if((c|0)<=(f|0)&d>>>0>n>>>0|(c|0)<(f|0)){break b}d=(g|0)==2;while(1){if((e|0)==(n|0)&(c|0)==(f|0)){G[m+8>>2]=p;G[m+12>>2]=v;G[m>>2]=o;G[m+4>>2]=q}qo(a,b,w,e,m+48|0,m,m+144|0,m+176|0,g,h,i,j,m+200|0,m+172|0,l);if(!(!k|!G[m+200>>2])){G[k>>2]=1}G[m+56>>2]=0;G[m+60>>2]=0;G[m+48>>2]=0;G[m+52>>2]=0;s=G[m+172>>2];j=(d?j?s:0:0)+j|0;i=M(s,w)+i|0;e=e+1|0;f=e?f:f+1|0;if(e>>>0<=n>>>0&(c|0)>=(f|0)|(c|0)>(f|0)){continue}break};break b;default:Ua(28010);G[l>>2]=414;break a;case 0:break c}}c=G[m+52>>2];d=G[m+48>>2]+1|0;c=d?c:c+1|0;G[m+48>>2]=d;G[m+52>>2]=c;d=G[m+4>>2];c=G[m>>2]+1|0;d=c?d:d+1|0;G[m>>2]=c;G[m+4>>2]=d;md(a,b,m+48|0,m,m+144|0,g,h,i,j,k,l)}}Fa=m+208|0}function Rq(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;c=Fa-752|0;Fa=c;G[47589]=1;f=G[29763];G[321435]=f;G[47590]=0;G[926536]=0;e=200;a:{b:{while(1){c:{d:{e:{f:{g:{d=of(a,b,38930);switch(d-100|0){case 15:break c;case 0:break e;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:break f;default:break g}}if((d|0)==83){break d}if((d|0)==-1){break b}}G[c>>2]=G[b>>2];_a(G[321435],81902,c);break a}G[926536]=1;continue}e=+(_b(G[321433])|0);continue}d=ac(G[321433],49010);G[321435]=d;if(d){continue}break}G[c+224>>2]=G[321433];_a(0,80991,c+224|0);break a}h:{d=a;a=G[47589];if((d-a|0)>1){b=(a<<2)+b|0;a=Za(c+496|0,G[b>>2]);d=ac(Za(c+240|0,G[b+4>>2]),49010);if(!d){break h}Lf(a,1,0);if(G[926536]){yb(44716);$a(f)}b=Fa-80384|0;Fa=b;i:{j:{l=ac(a,13287);if(l){E[b+32|0]=0;while(1){if(vc(b+80032|0,256,l)){a=(Va(b+80032|0)+b|0)+80031|0;if(H[a|0]==10){E[a|0]=0}a=(Va(b+80032|0)+b|0)+80031|0;if(H[a|0]==13){E[a|0]=0}f=Va(b+32|0);a=Va(b+80032|0);k:{if((a|0)>0){bb(f+(b+32|0)|0,b+80032|0,a);if(a>>>0>79){break k}}cb(b+32+(a+f)|0,32,80-a|0)}E[(b+f|0)+112|0]=0;j=j+1|0;if((j|0)!=1e3){continue}}break}if(G[926536]){yb(86179);n=G[29763];$a(n);j=Va(b+32|0);f=0;while(1){a=0;cb(b+80288|0,0,80);g=M(f,80);while(1){l:{h=a+g|0;k=(h|0)>(j|0);if(k){break l}E[(b+80288|0)+a|0]=H[h+(b+32|0)|0];h=a|1;o=h+g|0;k=(j|0)<(o|0);if(k){break l}E[h+(b+80288|0)|0]=H[(b+32|0)+o|0];a=a+2|0;if((a|0)!=80){continue}}break}E[b+80368|0]=0;a=80;while(1){m:{g=(b+80288|0)+a|0;if((H[g|0]|32)!=32){break m}E[g|0]=0;g=(a+b|0)+80287|0;if((H[g|0]|32)!=32){break m}E[g|0]=0;g=a-2|0;h=g+(b+80288|0)|0;if((H[h|0]|32)!=32){break m}E[h|0]=0;a=a-3|0;if(g){continue}}break}f=f+1|0;if(H[b+80288|0]){G[b+16>>2]=f;G[b+20>>2]=b+80288;kb(69623,b+16|0)}if(!k){continue}break}id();$a(n)}a=rd(b+32|0);G[926537]=a;if(!a){break j}a=a+3512|0;if(!fb(a,35967,2)){G[926538]=0}if(!fb(a,34801,2)){G[926538]=2}if(!fb(a,34774,2)){G[926538]=4}if(G[926536]){yb(73546);$a(G[29763])}Hb(l);Fa=b+80384|0;break i}G[b>>2]=a;_a(G[321435],80820,b);break a}hb(84378,54,1,G[321435]);break a}a=G[926537];i=L[a+144>>3];m=L[a+136>>3];e=e/(i>m?i:m);L[a+32>>3]=L[a+32>>3]/e;L[a+40>>3]=L[a+40>>3]/e;L[a+16>>3]=L[a+16>>3]*e+2.5;L[a+24>>3]=L[a+24>>3]*e+2.5;i=i*e;n:{if(O(i)<2147483648){b=~~i;break n}b=-2147483648}L[a+144>>3]=+(b|0)+5;e=m*e;o:{if(O(e)<2147483648){b=~~e;break o}b=-2147483648}L[a+136>>3]=+(b|0)+5;hb(85307,12,1,d);hb(86411,14,1,d);hb(86498,12,1,d);e=L[G[926537]+136>>3];p:{if(O(e)<2147483648){a=~~e;break p}a=-2147483648}G[c+208>>2]=a;_a(d,75530,c+208|0);e=L[G[926537]+144>>3];q:{if(O(e)<2147483648){a=~~e;break q}a=-2147483648}G[c+192>>2]=a;_a(d,75516,c+192|0);G[c+176>>2]=G[926537]+3368;_a(d,89614,c+176|0);G[c+160>>2]=G[926537]+3384;_a(d,89598,c+160|0);L[c+144>>3]=L[G[926537]+688>>3];xb(d,71955,c+144|0);L[c+128>>3]=L[G[926537]+696>>3];xb(d,71881,c+128|0);L[c+112>>3]=L[G[926537]+16>>3];xb(d,71937,c+112|0);L[c+96>>3]=L[G[926537]+24>>3];xb(d,71863,c+96|0);L[c+80>>3]=L[G[926537]+32>>3];xb(d,71355,c+80|0);L[c+64>>3]=L[G[926537]+40>>3];xb(d,71301,c- -64|0);L[c+48>>3]=L[G[926537]+48>>3];xb(d,71899,c+48|0);L[c+32>>3]=L[G[926537]+120>>3];xb(d,72284,c+32|0);hb(85385,4,1,d);Hb(d);hb(83215,19,1,G[321435]);$a(G[321435]);Hb(G[321435]);sc(0);W()}G[c+16>>2]=G[b>>2];_a(G[321435],81902,c+16|0);break a}hb(82898,62,1,G[321435])}$a(G[321435]);Hb(G[321435]);sc(1);W()} -function Jj(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0;j=Fa-16|0;Fa=j;if(G[d>>2]<=0){a:{if(Nb(a,d)){if((sd(j+12|0,42094,d)|0)>0){break a}f=G[j+12>>2];g=Fa-256|0;Fa=g;e=G[d>>2];b:{if((e|0)>0){break b}if((e|0)==-1){G[d>>2]=0}if(!Nb(a,d)){Ua(50428);e=414;G[d>>2]=414;break b}G[g+136>>2]=G[a>>2]+1;G[g+140>>2]=G[f>>2]+1;Td(f,g+132|0,0,d);G[g+128>>2]=0;c:{d:{e:{if(kc(a,35504,g+32|0,g+128|0)){break e}k=1;if(G[g+140>>2]!=1){break e}if(!G[g+132>>2]){break d}mh(f,6,g+24|0,g+28|0,g,d);if(G[g+28>>2]){break e}k=G[g+136>>2]!=2;e=G[g+132>>2];if((e|0)<=0){break d}while(1){ig(f,e,d);h=e>>>0>1;e=e-1|0;if(h){continue}break}break d}G[g+128>>2]=0;if(kc(a,34458,g+32|0,g+128|0)){k=1;e=G[a+4>>2];if((pd(f,G[e+1104>>2],G[e+1108>>2],e+1112|0,d)|0)<=0){i=1;break d}Ua(33195);break c}if((e|0)==-1){k=1;e=G[a+4>>2];if((pd(f,G[e+1104>>2],G[e+1108>>2],e+1112|0,d)|0)<=0){i=1;break d}Ua(33195);break c}if(!G[g+132>>2]){pd(f,8,0,g,d);k=1;if((Ke(f,d)|0)<=0){break d}Ua(33195);break c}Ke(f,d);k=1}if(G[d>>2]>0){Ua(33195);break c}e=Fa-432|0;Fa=e;F[e+14>>1]=45;G[e+8>>2]=0;h=G[d>>2];if((h|0)<=0){G[e+276>>2]=49026;G[e+268>>2]=49026;G[e+260>>2]=48783;G[e+252>>2]=48783;G[e+244>>2]=48783;G[e+236>>2]=48783;G[e+228>>2]=48783;G[e+220>>2]=48783;G[e+212>>2]=48783;G[e+204>>2]=48783;G[e+196>>2]=48783;G[e+188>>2]=48783;G[e+180>>2]=48783;G[e+172>>2]=48783;G[e+164>>2]=48783;G[e+156>>2]=48783;G[e+148>>2]=48783;G[e+140>>2]=48783;G[e+132>>2]=48783;G[e+124>>2]=48783;G[e+116>>2]=48783;G[e+108>>2]=48783;h=e+14|0;G[e+68>>2]=i?h:35828;G[e+60>>2]=i?h:35787;G[e+256>>2]=34633;G[e+100>>2]=i?h:34633;G[e+248>>2]=34623;G[e+92>>2]=i?h:34623;G[e+144>>2]=33311;G[e+84>>2]=i?h:33311;G[e+136>>2]=33303;G[e+76>>2]=i?h:33303;G[e+128>>2]=16595;G[e+52>>2]=i?h:16595;G[e+120>>2]=33788;G[e+44>>2]=i?h:33788;G[e+112>>2]=32941;G[e+36>>2]=i?h:32941;G[e+272>>2]=49138;G[e+264>>2]=35480;G[e+240>>2]=16623;G[e+232>>2]=16649;G[e+224>>2]=34861;G[e+216>>2]=35408;G[e+208>>2]=16656;G[e+200>>2]=41550;G[e+192>>2]=32673;G[e+184>>2]=35668;G[e+176>>2]=34350;G[e+168>>2]=16609;G[e+160>>2]=16642;G[e+152>>2]=33837;G[e+96>>2]=34632;G[e+88>>2]=34614;G[e+80>>2]=33310;G[e+72>>2]=33302;G[e+64>>2]=35827;G[e+56>>2]=35786;G[e+48>>2]=16594;G[e+40>>2]=33763;G[e+32>>2]=32893;G[e+24>>2]=34458;G[e+16>>2]=35504;G[e+20>>2]=i?h:35530;G[e+104>>2]=34516;G[e+28>>2]=i?h:34516;kc(a,35480,e+336|0,e+8|0);f:{if(G[e+8>>2]){break f}if(nb(e+336|0,65168,28)){break f}G[e+268>>2]=e+14}h=0;uk(a,f,1,e+16|0,33,0,d);Td(a,e+4|0,e,d);i=G[e>>2];G[e>>2]=(i|0)/36;if((i|0)>=36){while(1){wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);wb(f,68293,d);h=h+1|0;if((h|0)>2]){continue}break}}h=G[d>>2]}Fa=e+432|0;if((h|0)>0){Ua(24771)}if(k){break c}mb(a,1,0,d);Rb(f,d);bb(g+144|0,119088,104);g:{if(G[d>>2]<=0){uk(a,f,1,g+144|0,13,0,d);if(G[d>>2]<=0){break g}}Ua(22429)}mb(a,2,0,d)}e=G[d>>2]}Fa=g+256|0;a=G[j+12>>2];if((e|0)>0){Xm(a,d);break a}lo(a,b,c,d);Qb(G[j+12>>2],d);break a}lo(a,b,c,d)}}Fa=j+16|0}function sg(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;a:{b:{d=a<<2;n=ab(d);if(n){q=ab(d);if(!q){Wa(n);return 1}l=a<<3;s=ab(l);if(!s){Wa(n);Wa(q);return 1}j=ab(M(a,l));if(!j){break a}c:{if((a|0)<=0){break c}k=a&-4;p=a&3;v=a-1|0;while(1){G[(e<<2)+n>>2]=e;d=h<<3;bb(d+j|0,b+d|0,l);i=0;d=h;g=0;if(v>>>0>=3){while(1){o=(d<<3)+b|0;w=O(L[o+24>>3]);x=O(L[o+16>>3]);t=O(L[o+8>>3]);f=O(L[o>>3]);f=f>i?f:i;f=f>3]);i=f>i?f:i;d=d+1|0;g=g+1|0;if((p|0)!=(g|0)){continue}break}}L[(e<<3)+s>>3]=i;if(i==0){break b}h=a+h|0;e=e+1|0;if((e|0)!=(a|0)){continue}break}if((a|0)<=0){break c}z=a&-2;A=a&1;B=a-2|0;e=0;while(1){k=e;e=e+1|0;o=(e|0)>=(a|0);d:{if(o){break d}p=M(a,k);y=(p+k<<3)+j|0;l=(k<<3)+s|0;t=L[l>>3];i=O(L[y>>3])/t;d=e;g=k;while(1){f=O(L[(k+M(a,d)<<3)+j>>3])/L[(d<<3)+s>>3];b=f>i;i=b?f:i;g=b?d:g;d=d+1|0;if((d|0)!=(a|0)){continue}break}if((g|0)>(k|0)){d=M(a,g);h=0;b=p;if(v){while(1){r=(d<<3)+j|0;f=L[r>>3];m=(b<<3)+j|0;L[r>>3]=L[m>>3];L[m>>3]=f;f=L[r+8>>3];L[r+8>>3]=L[m+8>>3];L[m+8>>3]=f;b=b+2|0;d=d+2|0;h=h+2|0;if((z|0)!=(h|0)){continue}break}}if(A){d=(d<<3)+j|0;f=L[d>>3];b=(b<<3)+j|0;L[d>>3]=L[b>>3];L[b>>3]=f}b=(g<<3)+s|0;f=L[b>>3];L[b>>3]=t;L[l>>3]=f;b=(g<<2)+n|0;d=G[b>>2];h=b;b=(k<<2)+n|0;G[h>>2]=G[b>>2];G[b>>2]=d}if(o){break d}b=k+2|0;m=v-k&1;o=(e+p<<3)+j|0;h=e;while(1){r=M(a,h);u=(r+k<<3)+j|0;f=L[u>>3];e:{if(f==0){break e}L[u>>3]=f/L[y>>3];d=e;if(m){d=(e+r<<3)+j|0;L[d>>3]=L[d>>3]-L[u>>3]*L[o>>3];d=b}if((k|0)==(B|0)){break e}while(1){g=(d+r<<3)+j|0;L[g>>3]=L[g>>3]-L[u>>3]*L[(d+p<<3)+j>>3];l=d+1|0;g=(l+r<<3)+j|0;L[g>>3]=L[g>>3]-L[u>>3]*L[(l+p<<3)+j>>3];d=d+2|0;if((d|0)!=(a|0)){continue}break}}h=h+1|0;if((h|0)!=(a|0)){continue}break}}if((a|0)!=(e|0)){continue}break}if((a|0)<=0){break c}g=0;d=0;if(v>>>0>=3){h=a&-4;b=0;while(1){G[(G[(d<<2)+n>>2]<<2)+q>>2]=d;e=d|1;G[(G[(e<<2)+n>>2]<<2)+q>>2]=e;e=d|2;G[(G[(e<<2)+n>>2]<<2)+q>>2]=e;e=d|3;G[(G[(e<<2)+n>>2]<<2)+q>>2]=e;d=d+4|0;b=b+4|0;if((h|0)!=(b|0)){continue}break}}b=a&3;if(b){while(1){G[(G[(d<<2)+n>>2]<<2)+q>>2]=d;d=d+1|0;g=g+1|0;if((b|0)!=(g|0)){continue}break}}b=0;if((a|0)<=0){break c}m=cb(c,0,M(a,a)<<3);while(1){c=G[(b<<2)+q>>2];g=m+(M(c,a)+b<<3)|0;G[g>>2]=0;G[g+4>>2]=1072693248;d=c+1|0;if((d|0)<(a|0)){p=c+1|0;h=0;e=c;while(1){k=e;e=d;f:{if((c|0)>(k|0)){break f}o=M(a,e);l=m+(o+b<<3)|0;i=L[l>>3];if(h&1){d=c}else{i=i-L[(c+o<<3)+j>>3]*L[g>>3];L[l>>3]=i;d=p}if(!h){break f}while(1){f=i-L[(d+o<<3)+j>>3]*L[m+(M(a,d)+b<<3)>>3];L[l>>3]=f;k=d+1|0;i=f-L[(k+o<<3)+j>>3]*L[m+(M(a,k)+b<<3)>>3];L[l>>3]=i;d=d+2|0;if((e|0)!=(d|0)){continue}break}}h=h+1|0;d=e+1|0;if((d|0)!=(a|0)){continue}break}}e=0;h=a;while(1){c=h;h=h-1|0;l=M(h,a);p=l+b|0;g:{if((a|0)<=(c|0)){break g}g=m+(p<<3)|0;i=L[g>>3];if(e&1){i=i-L[(c+l<<3)+j>>3]*L[m+(M(a,c)+b<<3)>>3];L[g>>3]=i;d=c+1|0}else{d=c}if((e|0)==1){break g}while(1){f=i-L[(d+l<<3)+j>>3]*L[m+(M(a,d)+b<<3)>>3];L[g>>3]=f;k=d+1|0;i=f-L[(k+l<<3)+j>>3]*L[m+(M(a,k)+b<<3)>>3];L[g>>3]=i;d=d+2|0;if((d|0)!=(a|0)){continue}break}}d=m+(p<<3)|0;L[d>>3]=L[d>>3]/L[(h+l<<3)+j>>3];e=e+1|0;if((c|0)>1){continue}break}b=b+1|0;if((b|0)!=(a|0)){continue}break}}Wa(n);Wa(q);Wa(s);Wa(j);a=0}else{a=1}return a}Wa(n);Wa(q);Wa(s);Wa(j);return 2}Wa(n);Wa(q);Wa(s);return 1}function Os(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;j=Fa-128|0;Fa=j;f=G[309729];G[j+44>>2]=0;g=f+M(a,244)|0;a:{if(!G[309736]){f=G[g>>2];k=G[g+80>>2];h=b>>31;i=j+48|0;g=c>>31;a=j+44|0;if(!(!(g|c)|G[a>>2]>0)){b:{c:{switch(k-11|0){case 0:d:{if(Nb(f,a)){Nc(f,11,b,h,c,g,2,0,d,e,i,a);break d}Re(f,2,1,0,b,h,c,g,1,2,0,d,e,i,a)}break b;case 1:e:{if(Nb(f,a)){Nc(f,12,b,h,c,g,2,0,d,e,i,a);break e}Ef(f,2,1,0,b,h,c,g,1,2,0,d,e,i,a)}break b;case 9:f:{if(Nb(f,a)){Nc(f,20,b,h,c,g,2,0,d,e,i,a);break f}Gf(f,2,1,0,b,h,c,g,1,2,0,d,e,i,a)}break b;case 10:g:{if(Nb(f,a)){Nc(f,21,b,h,c,g,2,0,d,e,i,a);break g}jf(f,2,1,0,b,h,c,g,1,2,0,d,e,i,a)}break b;case 19:h:{if(Nb(f,a)){Nc(f,30,b,h,c,g,2,0,d,e,i,a);break h}if(!(!(c|g)|G[a>>2]>0)){qe(f,2,1,0,b,h,c,g,1,2,0,d,e,i,a)}}break b;case 20:i:{if(Nb(f,a)){Nc(f,31,b,h,c,g,2,0,d,e,i,a);break i}if(!(!(c|g)|G[a>>2]>0)){Ud(f,2,1,0,b,h,c,g,1,2,0,d,e,i,a)}}break b;case 29:j:{if(Nb(f,a)){Nc(f,40,b,h,c,g,2,0,d,e,i,a);break j}qe(f,2,1,0,b,h,c,g,1,2,0,d,e,i,a)}break b;case 30:k:{if(Nb(f,a)){Nc(f,41,b,h,c,g,2,0,d,e,i,a);break k}Ud(f,2,1,0,b,h,c,g,1,2,0,d,e,i,a)}break b;case 69:l:{if(Nb(f,a)){Nc(f,80,b,h,c,g,2,0,d,e,i,a);break l}hf(f,2,1,0,b,h,c,g,1,2,0,0,d,e,i,a)}break b;case 70:m:{if(Nb(f,a)){Nc(f,81,b,h,c,g,2,0,d,e,i,a);break m}Se(f,2,1,0,b,h,c,g,1,2,0,0,d,e,i,a)}break b;case 31:n:{if(Nb(f,a)){Nc(f,42,b,h,c,g,2,0,d,e,i,a);break n}ae(f,2,1,0,b,h,c,g,1,2,N(0),d,e,i,a)}break b;case 71:o:{if(Nb(f,a)){Nc(f,82,b,h,c,g,2,0,d,e,i,a);break o}Id(f,2,1,0,b,h,c,g,1,2,0,d,e,i,a)}break b;default:break c}}G[a>>2]=410}}if(!G[309801]){break a}G[j>>2]=b;G[j+4>>2]=c;G[j+8>>2]=G[j+44>>2];kb(75163,j);break a}k=G[g+92>>2];h=M(k,c);p:{q:{r:{s:{t:{u:{v:{w:{i=G[g+80>>2];switch(i-11|0){case 1:case 2:case 4:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:break r;case 30:break t;case 3:break u;case 5:break v;case 0:break w;default:break s}}e=M((k+7|0)/8|0,c);h=ab(e);i=0;k=Fa-16|0;Fa=k;Re(G[g>>2],G[(f+M(a,244)|0)+4>>2],b,b>>31,1,0,e,e>>31,1,1,0,h,k+15|0,j+48|0,j+44|0);Fa=k+16|0;x:{if((c|0)<=0){break x}b=G[g+92>>2];g=(b+7|0)/8|0;if((b|0)>0){while(1){f=(i<<2)+d|0;a=M(g,i)+1|0;e=0;while(1){k=e&7;E[G[f>>2]+e|0]=H[a+h|0]>>>(k^7)&1?49:48;a=((k|0)==7)+a|0;e=e+1|0;if((b|0)!=(e|0)){continue}break}E[b+G[f>>2]|0]=0;i=i+1|0;if((i|0)!=(c|0)){continue}break p}}f=0;e=0;if(c-1>>>0>=3){g=c&-4;b=0;while(1){a=e<<2;E[G[a+d>>2]]=0;E[G[(a|4)+d>>2]]=0;E[G[(a|8)+d>>2]]=0;E[G[(a|12)+d>>2]]=0;e=e+4|0;b=b+4|0;if((g|0)!=(b|0)){continue}break}}a=c&3;if(!a){break x}while(1){E[G[(e<<2)+d>>2]]=0;e=e+1|0;f=f+1|0;if((a|0)!=(f|0)){continue}break}}if(h){break p}G[j+36>>2]=2563;G[j+32>>2]=30721;kb(74236,j+32|0);break a}h=Fa-16|0;Fa=h;xh(G[g>>2],G[(f+M(a,244)|0)+4>>2],b,b>>31,1,0,c,c>>31,2,h+14|0,d,e,j+48|0,j+44|0);Fa=h+16|0;break a}fg(G[g>>2],G[(f+M(a,244)|0)+4>>2],b,b>>31,1,0,h,h>>31,2,0,d,e,j+48|0,j+44|0);break a}Ud(G[g>>2],G[(f+M(a,244)|0)+4>>2],b,b>>31,1,0,h,h>>31,1,2,0,d,e,j+48|0,j+44|0);break a}if((i|0)==82){break q}}G[j+16>>2]=i;a=j+48|0;Ya(a,80,30174,j+16|0);Ua(a);break a}Id(G[g>>2],G[(f+M(a,244)|0)+4>>2],b,b>>31,1,0,h,h>>31,1,2,0,d,e,j+48|0,j+44|0);break a}Wa(h)}Fa=j+128|0;a=G[j+44>>2];if(a){G[309737]=a;a=-1}else{a=0}return a|0}function nl(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0;o=Fa-160|0;Fa=o;if(G[j>>2]<=0){m=G[a>>2];l=G[a+4>>2];if((m|0)!=G[l+76>>2]){mb(a,m+1|0,0,j);l=G[a+4>>2];m=G[l+76>>2]}k=G[l+96>>2]+(m<<3)|0;if(G[l+104>>2]!=G[k>>2]|G[l+108>>2]!=G[k+4>>2]){Ke(a,j);l=G[a+4>>2];m=G[l+76>>2]}if(!m){m=0;if(G[j>>2]<=0){k=G[a>>2];if(k){mb(a,k+1|0,0,j);l=G[a+4>>2];m=G[l+76>>2]}m=G[l+96>>2]+(m<<3)|0;if(G[l+104>>2]!=G[m>>2]|G[l+108>>2]!=G[m+4>>2]){Ke(a,j)}Yi(a,16,0,o,j)}Ke(a,j)}a:{b:{switch(b-1|0){case 1:qq(a,c,d,e,f,g,h,i,j);break a;case 0:k=Fa-624|0;Fa=k;b=G[a>>2];if((b|0)!=G[G[a+4>>2]+76>>2]){mb(a,b+1|0,0,j)}c:{if(G[j>>2]>0){break c}b=G[a+4>>2];m=G[b+96>>2]+(G[b+76>>2]<<3)|0;if(G[b+104>>2]!=G[m>>2]|G[b+108>>2]!=G[m+4>>2]){G[j>>2]=201;break c}if((d|0)<0){G[j>>2]=218;break c}if(e>>>0>=1e3){G[j>>2]=216;break c}E[k+160|0]=0;if(i){qb(k+160|0,i,70)}G[k+444>>2]=0;m=lb((e|0)>5?e:5,4);d:{if(!m){m=0;b=1;break d}l=0;b=Fa-16|0;Fa=b;e:{if(G[j>>2]>0){break e}G[k+444>>2]=0;if((e|0)<=0){break e}G[m>>2]=1;i=G[k+444>>2];while(1){n=l<<2;G[n+m>>2]=i+1;Gd(G[g+n>>2],b+12|0,b+4|0,b+8|0,j);i=G[k+444>>2]+(G[b+4>>2]+1|0)|0;G[k+444>>2]=i;l=l+1|0;if((l|0)!=(e|0)){continue}break}G[k+444>>2]=i-1}Fa=b+16|0;b=0}lc(a,34516,35630,15365,j);f:{if(G[j>>2]>0){break f}G[k+144>>2]=8;G[k+148>>2]=0;E[k+320|0]=0;if((db(k+320|0,26741,k+144|0)|0)<0){Ua(17884);G[j>>2]=401}i=k+448|0;Ob(32941,k+320|0,6292,i,j);wb(a,i,j);if(G[j>>2]>0){break f}G[k+128>>2]=2;G[k+132>>2]=0;E[k+320|0]=0;if((db(k+320|0,26741,k+128|0)|0)<0){Ua(17884);G[j>>2]=401}i=k+448|0;Ob(33788,k+320|0,23481,i,j);wb(a,i,j);if(G[j>>2]>0){break f}i=G[k+444>>2];G[k+112>>2]=i;G[k+116>>2]=i>>31;E[k+320|0]=0;if((db(k+320|0,26741,k+112|0)|0)<0){Ua(17884);G[j>>2]=401}i=k+448|0;Ob(41261,k+320|0,6217,i,j);wb(a,i,j);if(G[j>>2]>0){break f}G[k+96>>2]=c;G[k+100>>2]=d;E[k+320|0]=0;if((db(k+320|0,26741,k+96|0)|0)<0){Ua(17884);G[j>>2]=401}c=k+448|0;Ob(40853,k+320|0,23289,c,j);wb(a,c,j);if(G[j>>2]>0){break f}G[k+80>>2]=0;G[k+84>>2]=0;E[k+320|0]=0;if((db(k+320|0,26741,k+80|0)|0)<0){Ua(17884);G[j>>2]=401}c=k+448|0;Ob(33303,k+320|0,61953,c,j);wb(a,c,j);if(G[j>>2]>0){break f}G[k+64>>2]=1;G[k+68>>2]=0;E[k+320|0]=0;if((db(k+320|0,26741,k- -64|0)|0)<0){Ua(17884);G[j>>2]=401}c=k+448|0;Ob(33311,k+320|0,61992,c,j);wb(a,c,j);if(G[j>>2]>0){break f}E[k+320|0]=0;G[k+48>>2]=e;G[k+52>>2]=0;if((db(k+320|0,26741,k+48|0)|0)<0){Ua(17884);G[j>>2]=401}c=k+448|0;Ob(33837,k+320|0,3872,c,j);wb(a,c,j)}i=0;while(1){g:{if((e|0)==(i|0)){break g}c=i<<2;d=c+f|0;if(H[G[d>>2]]){l=i+1|0;G[k+32>>2]=l;n=k+240|0;Ya(n,73,29741,k+32|0);p=l;l=k+320|0;zb(35402,p,l,j);lc(a,l,G[d>>2],n,j)}d=c+m|0;l=G[d>>2];if(!((l|0)>0&(l|0)<=G[k+444>>2])){G[j>>2]=234}i=i+1|0;G[k+16>>2]=i;Ya(k+240|0,73,29761,k+16|0);zb(34749,i,k+320|0,j);if(G[j>>2]<=0){d=G[d>>2];G[k>>2]=d;G[k+4>>2]=d>>31;E[k+544|0]=0;if((db(k+544|0,26741,k)|0)<0){Ua(17884);G[j>>2]=401}d=k+448|0;Ob(k+320|0,k+544|0,k+240|0,d,j);wb(a,d,j)}d=G[c+g>>2];if(Va(d)>>>0>=30){Ua(63127);G[j>>2]=261;break g}d=Za(k+400|0,d);Yf(d);l=k+320|0;zb(34641,i,l,j);lc(a,l,d,26806,j);h:{if(!h){break h}c=c+h|0;d=G[c>>2];if(!d|!H[d|0]){break h}d=k+320|0;zb(33357,i,d,j);lc(a,d,G[c>>2],26762,j)}if(G[j>>2]<=0){continue}}break}if(H[k+160|0]){lc(a,35480,k+160|0,15352,j)}if(G[j>>2]>0){Ua(63074)}if(!b){Wa(m)}}Fa=k+624|0;break a;default:break b}}G[j>>2]=235}}Fa=o+160|0}function Bf(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;g=Fa-5872|0;Fa=g;h=G[d>>2];a:{if((b|0)<=0){e=h;break a}if((h|0)>0){e=h;break a}l=G[a+4>>2];b:{c:{d:{e:{f:{g:{if(c){m=(G[l+80>>2]==1)<<5;if((c|0)==-1){break g}i=G[l+984>>2];e=G[l+988>>2];j=G[l+976>>2];n=G[l+980>>2];f=G[l+128>>2];o=G[l+132>>2];cb(g+96|0,m,2880);m=i;i=n+o|0;j=f+j|0;i=j>>>0>>0?i+1|0:i;f=m+j|0;e=e+i|0;e=f>>>0>>0?e+1|0:e;f=f+2879|0;e=f>>>0<2879?e+1|0:e;i=Cu(f,e);j=f-i|0;i=e-(Ia+(f>>>0>>0)|0)|0;if((b|0)==1){break d}break f}j=G[l+128>>2];i=G[l+132>>2];cb(g+96|0,32,2880);if((b|0)==1){break d}break f}e=H[15459]|H[15460]<<8|(H[15461]<<16|H[15462]<<24);G[g+40>>2]=H[15455]|H[15456]<<8|(H[15457]<<16|H[15458]<<24);G[g+44>>2]=e;e=H[15451]|H[15452]<<8|(H[15453]<<16|H[15454]<<24);G[g+32>>2]=H[15447]|H[15448]<<8|(H[15449]<<16|H[15450]<<24);G[g+36>>2]=e;e=H[15443]|H[15444]<<8|(H[15445]<<16|H[15446]<<24);G[g+24>>2]=H[15439]|H[15440]<<8|(H[15441]<<16|H[15442]<<24);G[g+28>>2]=e;e=H[15435]|H[15436]<<8|(H[15437]<<16|H[15438]<<24);G[g+16>>2]=H[15431]|H[15432]<<8|(H[15433]<<16|H[15434]<<24);G[g+20>>2]=e;e=H[15427]|H[15428]<<8|(H[15429]<<16|H[15430]<<24);G[g+8>>2]=H[15423]|H[15424]<<8|(H[15425]<<16|H[15426]<<24);G[g+12>>2]=e;e=H[15419]|H[15420]<<8|(H[15421]<<16|H[15422]<<24);G[g>>2]=H[15415]|H[15416]<<8|(H[15417]<<16|H[15418]<<24);G[g+4>>2]=e;cb(g+96|0,m,2880);if((b|0)==1){break e}}e=G[l+76>>2];while(1){mb(a,G[a>>2]+2|0,g+5868|0,d);f=G[d>>2];if((f|0)<=0){continue}break}if((f|0)==107){G[d>>2]=h}mb(a,e+1|0,g+5868|0,d);if((c|0)==-1){rl(a,1,g,d)}e=G[a+4>>2];e=(G[e+88>>2]<<3)+G[e+96>>2]|0;f=G[e+8>>2];h=G[e+12>>2];n=Bu(f-j|0,h-((f>>>0>>0)+i|0)|0,2880,0);if((n|0)>0){l=Au(b,b>>31,2880,0);o=Ia;while(1){h=h-(f>>>0<2880)|0;f=f-2880|0;if((Jb(a,f,h,0,d)|0)>0){break b}p=g+2976|0;ic(a,2880,0,p,d);e=h+o|0;m=f+l|0;e=m>>>0>>0?e+1|0:e;Jb(a,m,e,1,d);Wb(a,2880,0,p,d);k=k+1|0;if((n|0)!=(k|0)){continue}break}}Jb(a,j,i,1,d);if((b|0)<=0){break c}k=0;while(1){Wb(a,2880,0,g+96|0,d);k=k+1|0;if((k|0)!=(b|0)){continue}break}break c}rl(a,1,g,d)}Jb(a,j,i,0,d);ic(a,2880,0,g+2976|0,d);e=g+96|0;h:{if(G[d>>2]>0){f=e;break h}k=g+2976|0;while(1){f=k;Jb(a,j,i,0,d);k=e;Wb(a,2880,0,e,d);e=G[d>>2];if((e|0)>0){break a}e=i;i=j+2880|0;e=i>>>0<2880?e+1|0:e;j=i;i=e;Jb(a,j,e,0,d);ic(a,2880,0,k,d);e=f;if(G[d>>2]<=0){continue}break}}G[d>>2]=h;Jb(a,j,i,1,d);Wb(a,2880,0,f,d)}i:{if(c){k=G[a+4>>2];break i}k=G[a+4>>2];a=k;e=G[a+132>>2];c=G[a+128>>2];f=Au(b,b>>31,2880,0);c=c+f|0;e=Ia+e|0;G[a+128>>2]=c;G[a+132>>2]=c>>>0>>0?e+1|0:e}a=G[k+76>>2];i=G[k+88>>2];if((a|0)>(i|0)){break b}c=Au(b,b>>31,2880,0);f=Ia;k=G[k+96>>2];j=i-a|0;l=j+1&3;if(l){b=0;while(1){a=a+1|0;e=k+(a<<3)|0;m=e;h=c+G[e>>2]|0;e=f+G[e+4>>2]|0;G[m>>2]=h;G[m+4>>2]=c>>>0>h>>>0?e+1|0:e;b=b+1|0;if((l|0)!=(b|0)){continue}break}}if(j>>>0<3){break b}while(1){b=k+(a<<3)|0;j=b+8|0;e=f+G[b+12>>2]|0;h=c+G[b+8>>2]|0;e=h>>>0>>0?e+1|0:e;G[j>>2]=h;G[j+4>>2]=e;e=f+G[b+20>>2]|0;h=c+G[b+16>>2]|0;e=h>>>0>>0?e+1|0:e;G[b+16>>2]=h;G[b+20>>2]=e;j=a+3|0;b=k+(j<<3)|0;e=f+G[b+4>>2]|0;h=c+G[b>>2]|0;e=h>>>0>>0?e+1|0:e;G[b>>2]=h;G[b+4>>2]=e;a=a+4|0;b=k+(a<<3)|0;e=f+G[b+4>>2]|0;h=c+G[b>>2]|0;e=h>>>0>>0?e+1|0:e;G[b>>2]=h;G[b+4>>2]=e;if((i|0)!=(j|0)){continue}break}}e=G[d>>2]}Fa=g+5872|0;return e}function iu(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;g=Fa-1179712|0;Fa=g;h=ab(40);G[h>>2]=0;G[g+917568>>2]=16921;k=4;i=1;a:{b:{c:{if(!d|!H[d|0]){break c}G[321387]=0;m=aa(158,d|0)|0;d=G[321387];G[321387]=0;e=-1;d:{if(!d){break d}f=G[321388];if(!f){break d}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[321387]=0;j=pc(m,92039);d=G[321387];G[321387]=0;e=-1;e:{if(!d){break e}f=G[321388];if(!f){break e}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}f:{if(!j){break f}e=0;while(1){G[321387]=0;l=rb((g+262208|0)+(e<<16)|0,j,65535);d=G[321387];G[321387]=0;j=-1;g:{if(!d){break g}f=G[321388];if(!f){break g}j=Ab(G[d>>2],h,4);if(!j){break a}_(f|0)}d=Z()|0;if((j|0)==1){break b}G[(g+917568|0)+(i<<2)>>2]=l;G[321387]=0;j=pc(0,92039);d=G[321387];G[321387]=0;l=-1;h:{if(!d){break h}f=G[321388];if(!f){break h}l=Ab(G[d>>2],h,4);if(!l){break a}_(f|0)}d=Z()|0;if((l|0)==1){break b}i=i+1|0;if(!j){break f}d=e>>>0<9;e=e+1|0;if(d){continue}break}}if(!m){break c}Wa(m)}G[(g+917568|0)+(i<<2)>>2]=8722;d=G[968813];G[968813]=d+1;G[321387]=0;G[g+48>>2]=42205;G[g+52>>2]=d;$(156,g+196672|0,65535,4259,g+48|0)|0;d=G[321387];G[321387]=0;e=-1;i:{if(!d){break i}f=G[321388];if(!f){break i}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}d=(i<<2)+g|0;G[d+917572>>2]=g+196672;G[d+917576>>2]=5329;G[321387]=0;G[g+32>>2]=42205;G[g+36>>2]=a;$(156,g+131136|0,65535,8740,g+32|0)|0;d=G[321387];G[321387]=0;e=-1;j:{if(!d){break j}f=G[321388];if(!f){break j}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[321387]=0;G[g+16>>2]=42205;G[g+20>>2]=b;G[((i<<2)+g|0)+917580>>2]=g+131136;$(156,g+65600|0,65535,8740,g+16|0)|0;d=G[321387];G[321387]=0;e=-1;k:{if(!d){break k}f=G[321388];if(!f){break k}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[321387]=0;G[g>>2]=42205;G[g+4>>2]=c;G[((i<<2)+g|0)+917584>>2]=g+65600;$(156,g- -64|0,65535,8740,g|0)|0;d=G[321387];G[321387]=0;e=-1;l:{if(!d){break l}f=G[321388];if(!f){break l}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[((i<<2)+g|0)+917588>>2]=g- -64;h=We(1285568,1,h,4);k=Z()|0;d=0}m:{while(1){if(!d){G[321387]=0;ba(168,i+6|0,g+917568|0)|0;d=G[321387];G[321387]=0;e=-1;n:{if(!d){break n}f=G[321388];if(!f){break n}e=Ab(G[d>>2],h,k);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}}G[321387]=0;b=ba(162,g+196672|0,13287)|0;d=G[321387];G[321387]=0;e=-1;o:{if(!d){break o}f=G[321388];if(!f){break o}e=Ab(G[d>>2],h,k);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}a=29011;if(!b){break m}G[321387]=0;c=$(163,3809712,1,65535,b|0)|0;d=G[321387];G[321387]=0;e=-1;p:{if(!d){break p}f=G[321388];if(!f){break p}e=Ab(G[d>>2],h,k);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}G[321387]=0;aa(164,b|0)|0;d=G[321387];G[321387]=0;e=-1;q:{if(!d){break q}f=G[321388];if(!f){break q}e=Ab(G[d>>2],h,k);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}E[c+3809712|0]=0;if((c|0)<=0){break m}G[321387]=0;aa(165,g+196672|0)|0;d=G[321387];G[321387]=0;e=-1;r:{if(!d){break r}f=G[321388];if(!f){break r}e=Ab(G[d>>2],h,k);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}break}a=3809712}Wa(h);Fa=g+1179712|0;return a|0}Wa(h);Ve(d,f);W()}function gu(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;g=Fa-1179712|0;Fa=g;h=ab(40);G[h>>2]=0;G[g+917568>>2]=13173;l=4;i=1;a:{b:{c:{if(!d|!H[d|0]){break c}G[321387]=0;m=aa(158,d|0)|0;d=G[321387];G[321387]=0;e=-1;d:{if(!d){break d}f=G[321388];if(!f){break d}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[321387]=0;j=pc(m,92039);d=G[321387];G[321387]=0;e=-1;e:{if(!d){break e}f=G[321388];if(!f){break e}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}f:{if(!j){break f}e=0;while(1){G[321387]=0;k=rb((g+262208|0)+(e<<16)|0,j,65535);d=G[321387];G[321387]=0;j=-1;g:{if(!d){break g}f=G[321388];if(!f){break g}j=Ab(G[d>>2],h,4);if(!j){break a}_(f|0)}d=Z()|0;if((j|0)==1){break b}G[(g+917568|0)+(i<<2)>>2]=k;G[321387]=0;j=pc(0,92039);d=G[321387];G[321387]=0;k=-1;h:{if(!d){break h}f=G[321388];if(!f){break h}k=Ab(G[d>>2],h,4);if(!k){break a}_(f|0)}d=Z()|0;if((k|0)==1){break b}i=i+1|0;if(!j){break f}d=e>>>0<9;e=e+1|0;if(d){continue}break}}if(!m){break c}Wa(m)}G[(g+917568|0)+(i<<2)>>2]=33947;G[321387]=0;G[g+48>>2]=a;$(156,g+196672|0,65535,30633,g+48|0)|0;d=G[321387];G[321387]=0;e=-1;i:{if(!d){break i}f=G[321388];if(!f){break i}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}a=G[968813];G[968813]=a+1;d=(i<<2)+g|0;G[d+917572>>2]=g+196672;G[d+917576>>2]=8722;G[321387]=0;G[g+32>>2]=42205;G[g+36>>2]=a;$(156,g+131136|0,65535,4259,g+32|0)|0;d=G[321387];G[321387]=0;e=-1;j:{if(!d){break j}f=G[321388];if(!f){break j}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[321387]=0;G[g+16>>2]=42205;G[g+20>>2]=b;G[((i<<2)+g|0)+917580>>2]=g+131136;$(156,g+65600|0,65535,8740,g+16|0)|0;d=G[321387];G[321387]=0;e=-1;k:{if(!d){break k}f=G[321388];if(!f){break k}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[321387]=0;G[g>>2]=42205;G[g+4>>2]=c;G[((i<<2)+g|0)+917584>>2]=g+65600;$(156,g- -64|0,65535,8740,g|0)|0;d=G[321387];G[321387]=0;e=-1;l:{if(!d){break l}f=G[321388];if(!f){break l}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[((i<<2)+g|0)+917588>>2]=g- -64;h=We(1285568,1,h,4);l=Z()|0;d=0}m:{while(1){if(!d){G[321387]=0;ba(170,i+6|0,g+917568|0)|0;d=G[321387];G[321387]=0;e=-1;n:{if(!d){break n}f=G[321388];if(!f){break n}e=Ab(G[d>>2],h,l);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}}G[321387]=0;a=ba(162,g+131136|0,13287)|0;d=G[321387];G[321387]=0;e=-1;o:{if(!d){break o}f=G[321388];if(!f){break o}e=Ab(G[d>>2],h,l);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}k=28917;if(!a){break m}G[321387]=0;b=$(163,3809712,1,65535,a|0)|0;d=G[321387];G[321387]=0;e=-1;p:{if(!d){break p}f=G[321388];if(!f){break p}e=Ab(G[d>>2],h,l);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}G[321387]=0;aa(164,a|0)|0;d=G[321387];G[321387]=0;e=-1;q:{if(!d){break q}f=G[321388];if(!f){break q}e=Ab(G[d>>2],h,l);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}E[b+3809712|0]=0;if((b|0)<=0){break m}G[321387]=0;aa(165,g+131136|0)|0;d=G[321387];G[321387]=0;e=-1;r:{if(!d){break r}f=G[321388];if(!f){break r}e=Ab(G[d>>2],h,l);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}break}k=3809712}Wa(h);Fa=g+1179712|0;return k|0}Wa(h);Ve(d,f);W()}function ud(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;i=Fa-176|0;Fa=i;l=Va(b);j=Va(c);a:{b:{if((l|0)!=7){break b}if(fb(b,33332,7)){if(fb(b,32708,7)){break b}}c:{d:{e:{while(1){f=a+d|0;if(!H[f|0]){e=d;break e}e=1;g=a+d|0;f=g+1|0;if(!H[f|0]){break e}f=g+2|0;if(!H[f|0]){break e}f=g+3|0;if(!H[f|0]){break e}f=g+4|0;if(!H[f|0]){break e}d=d+5|0;if((d|0)!=57600){continue}break}f=a+57600|0;break d}if(e){break d}break c}e=a;while(1){g=ec(e,35790,f-e|0);if(!g){break c}d=(g-a|0)%80|0;f:{if((d|0)>=8){e=g+1|0;break f}h=H[g+3|0];if(!((h|0)==61|(h-33&255)>>>0>93)){e=g+1|0;break f}h=g-d|0;if((d|0)>0){l=g+1|0;d=h;while(1){e=H[d|0]==32?e:l;d=d+1|0;if(g>>>0>d>>>0){continue}break}}if(e>>>0<=g>>>0){break c}}h=0;if(e>>>0>>0){continue}break}}rb(h+80|0,h,80);a=rb(h,b,7);cb(a+7|0,32,73);rb(a+9|0,c,j);break a}g:{h:{i:{j:{k:{l:{m:{n:{o:{p:{while(1){f=a+d|0;if(!H[f|0]){e=d;break p}e=1;h=a+d|0;f=h+1|0;if(!H[f|0]){break p}f=h+2|0;if(!H[f|0]){break p}f=h+3|0;if(!H[f|0]){break p}f=h+4|0;if(!H[f|0]){break p}d=d+5|0;if((d|0)!=57600){continue}break}f=a+57600|0;break o}if(!e){break n}}e=a;while(1){g=ec(e,b,f-e|0);if(!g){break n}d=(g-a|0)%80|0;q:{if((d|0)>=8){e=g+1|0;break q}h=H[Va(b)+g|0];if(!((h|0)==61|(h-33&255)>>>0>93)){e=g+1|0;break q}h=g-d|0;if((d|0)>0){k=g+1|0;d=h;while(1){e=H[d|0]==32?e:k;d=d+1|0;if(g>>>0>d>>>0){continue}break}}if(e>>>0<=g>>>0){break m}}if(e>>>0>>0){continue}break}}d=0;while(1){f=a+d|0;if(!H[f|0]){e=d;break l}e=1;h=a+d|0;f=h+1|0;if(!H[f|0]){break l}f=h+2|0;if(!H[f|0]){break l}f=h+3|0;if(!H[f|0]){break l}f=h+4|0;if(!H[f|0]){break l}d=d+5|0;if((d|0)!=57600){continue}break}f=a+57600|0;break k}d=rb(i- -64|0,h,80);E[d+80|0]=0;e=h+80|0;a=d;g=jb(d,39);if(g){a=jb(g+1|0,39)}g=a;g=jb(g,47);if(!g){break h}d=(d-g|0)+80|0;a=rb(i,g+1|0,d);d=(a+d|0)-1|0;r:{if(a>>>0>=d>>>0){break r}while(1){d=d-1|0;if(H[d|0]!=32){break r}E[d|0]=0;if(a>>>0>>0){continue}break}}a=Va(a);break g}if(!e){break j}}e=a;while(1){h=ec(e,35790,f-e|0);if(!h){break j}s:{d=(h-a|0)%80|0;t:{if((d|0)>=8){e=h+1|0;break t}g=H[h+3|0];if(!((g|0)==61|(g-33&255)>>>0>93)){e=h+1|0;break t}g=h-d|0;if((d|0)>0){k=h+1|0;d=g;while(1){e=H[d|0]==32?e:k;d=d+1|0;if(h>>>0>d>>>0){continue}break}}if(e>>>0<=h>>>0){break s}}if(e>>>0>>0){continue}break j}break}if((a|0)==(g|0)){break j}d=g;while(1){h=d;d=d-80|0;if(!fb(d,68289,8)){continue}break}if(g>>>0>h>>>0){break i}}d=0;u:{while(1){f=a+d|0;if(!H[f|0]){break u}e=a+d|0;f=e+1|0;if(!H[f|0]){break u}f=e+2|0;if(!H[f|0]){break u}f=e+3|0;if(!H[f|0]){break u}f=e+4|0;if(!H[f|0]){break u}d=d+5|0;if((d|0)!=57600){continue}break}f=a+57600|0}e=a;while(1){g=ec(e,35790,f-e|0);d=(g-a|0)%80|0;if((d|0)>=8){e=g+1|0;continue}h=H[g+3|0];if(!((h|0)==61|(h-33&255)>>>0>93)){e=g+1|0;continue}h=g-d|0;if((d|0)>0){k=g+1|0;d=h;while(1){e=H[d|0]==32?e:k;d=d+1|0;if(g>>>0>d>>>0){continue}break}}if(e>>>0>g>>>0){continue}break}e=rb(h+80|0,h,80);break h}e=h+80|0}E[i|0]=0;a=0}h=cb(h,32,e-h|0);d=rb(h,b,l);E[d+8|0]=61;E[d+9|0]=32;v:{if(H[c|0]==39){rb(d+10|0,c,j);b=(j|0)>19?j+12|0:30;break v}rb((d-j|0)+30|0,c,j);b=30}if((a|0)<=0){break a}c=b+d|0;E[c+2|0]=47;d=a;a=(a+b|0)+2|0;b=a>>>0>80?78-b|0:d;b=rb(c+3|0,i,b)+b|0;if(b>>>0>=e>>>0){break a}cb(b,32,((h^-1)+e|0)-(a>>>0<80?a:80)|0)}Fa=i+176|0}function ju(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;g=Fa-1179712|0;Fa=g;h=ab(40);G[h>>2]=0;G[g+917568>>2]=29524;k=4;i=1;a:{b:{c:{if(!d|!H[d|0]){break c}G[321387]=0;m=aa(158,d|0)|0;d=G[321387];G[321387]=0;e=-1;d:{if(!d){break d}f=G[321388];if(!f){break d}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[321387]=0;j=pc(m,92039);d=G[321387];G[321387]=0;e=-1;e:{if(!d){break e}f=G[321388];if(!f){break e}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}f:{if(!j){break f}e=0;while(1){G[321387]=0;l=rb((g+262208|0)+(e<<16)|0,j,65535);d=G[321387];G[321387]=0;j=-1;g:{if(!d){break g}f=G[321388];if(!f){break g}j=Ab(G[d>>2],h,4);if(!j){break a}_(f|0)}d=Z()|0;if((j|0)==1){break b}G[(g+917568|0)+(i<<2)>>2]=l;G[321387]=0;j=pc(0,92039);d=G[321387];G[321387]=0;l=-1;h:{if(!d){break h}f=G[321388];if(!f){break h}l=Ab(G[d>>2],h,4);if(!l){break a}_(f|0)}d=Z()|0;if((l|0)==1){break b}i=i+1|0;if(!j){break f}d=e>>>0<9;e=e+1|0;if(d){continue}break}}if(!m){break c}Wa(m)}G[(g+917568|0)+(i<<2)>>2]=8722;d=G[968813];G[968813]=d+1;G[321387]=0;G[g+48>>2]=42205;G[g+52>>2]=d;$(156,g+196672|0,65535,4259,g+48|0)|0;d=G[321387];G[321387]=0;e=-1;i:{if(!d){break i}f=G[321388];if(!f){break i}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[321387]=0;G[g+32>>2]=42205;G[g+36>>2]=a;G[((i<<2)+g|0)+917572>>2]=g+196672;$(156,g+131136|0,65535,8740,g+32|0)|0;d=G[321387];G[321387]=0;e=-1;j:{if(!d){break j}f=G[321388];if(!f){break j}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[321387]=0;G[g+16>>2]=42205;G[g+20>>2]=b;G[((i<<2)+g|0)+917576>>2]=g+131136;$(156,g+65600|0,65535,8740,g+16|0)|0;d=G[321387];G[321387]=0;e=-1;k:{if(!d){break k}f=G[321388];if(!f){break k}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[321387]=0;G[g>>2]=42205;G[g+4>>2]=c;G[((i<<2)+g|0)+917580>>2]=g+65600;$(156,g- -64|0,65535,8740,g|0)|0;d=G[321387];G[321387]=0;e=-1;l:{if(!d){break l}f=G[321388];if(!f){break l}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[((i<<2)+g|0)+917584>>2]=g- -64;h=We(1285568,1,h,4);k=Z()|0;d=0}m:{while(1){if(!d){G[321387]=0;ba(167,i+5|0,g+917568|0)|0;d=G[321387];G[321387]=0;e=-1;n:{if(!d){break n}f=G[321388];if(!f){break n}e=Ab(G[d>>2],h,k);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}}G[321387]=0;b=ba(162,g+196672|0,13287)|0;d=G[321387];G[321387]=0;e=-1;o:{if(!d){break o}f=G[321388];if(!f){break o}e=Ab(G[d>>2],h,k);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}a=29056;if(!b){break m}G[321387]=0;c=$(163,3809712,1,65535,b|0)|0;d=G[321387];G[321387]=0;e=-1;p:{if(!d){break p}f=G[321388];if(!f){break p}e=Ab(G[d>>2],h,k);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}G[321387]=0;aa(164,b|0)|0;d=G[321387];G[321387]=0;e=-1;q:{if(!d){break q}f=G[321388];if(!f){break q}e=Ab(G[d>>2],h,k);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}E[c+3809712|0]=0;if((c|0)<=0){break m}G[321387]=0;aa(165,g+196672|0)|0;d=G[321387];G[321387]=0;e=-1;r:{if(!d){break r}f=G[321388];if(!f){break r}e=Ab(G[d>>2],h,k);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}break}a=3809712}Wa(h);Fa=g+1179712|0;return a|0}Wa(h);Ve(d,f);W()}function ku(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;g=Fa-1179712|0;Fa=g;h=ab(40);G[h>>2]=0;G[g+917568>>2]=34197;k=4;i=1;a:{b:{c:{if(!d|!H[d|0]){break c}G[321387]=0;m=aa(158,d|0)|0;d=G[321387];G[321387]=0;e=-1;d:{if(!d){break d}f=G[321388];if(!f){break d}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[321387]=0;j=pc(m,92039);d=G[321387];G[321387]=0;e=-1;e:{if(!d){break e}f=G[321388];if(!f){break e}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}f:{if(!j){break f}e=0;while(1){G[321387]=0;l=rb((g+262208|0)+(e<<16)|0,j,65535);d=G[321387];G[321387]=0;j=-1;g:{if(!d){break g}f=G[321388];if(!f){break g}j=Ab(G[d>>2],h,4);if(!j){break a}_(f|0)}d=Z()|0;if((j|0)==1){break b}G[(g+917568|0)+(i<<2)>>2]=l;G[321387]=0;j=pc(0,92039);d=G[321387];G[321387]=0;l=-1;h:{if(!d){break h}f=G[321388];if(!f){break h}l=Ab(G[d>>2],h,4);if(!l){break a}_(f|0)}d=Z()|0;if((l|0)==1){break b}i=i+1|0;if(!j){break f}d=e>>>0<9;e=e+1|0;if(d){continue}break}}if(!m){break c}Wa(m)}G[(g+917568|0)+(i<<2)>>2]=8722;d=G[968813];G[968813]=d+1;G[321387]=0;G[g+48>>2]=42205;G[g+52>>2]=d;$(156,g+196672|0,65535,4259,g+48|0)|0;d=G[321387];G[321387]=0;e=-1;i:{if(!d){break i}f=G[321388];if(!f){break i}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[321387]=0;G[g+32>>2]=42205;G[g+36>>2]=a;G[((i<<2)+g|0)+917572>>2]=g+196672;$(156,g+131136|0,65535,8740,g+32|0)|0;d=G[321387];G[321387]=0;e=-1;j:{if(!d){break j}f=G[321388];if(!f){break j}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[321387]=0;G[g+16>>2]=42205;G[g+20>>2]=b;G[((i<<2)+g|0)+917576>>2]=g+131136;$(156,g+65600|0,65535,8740,g+16|0)|0;d=G[321387];G[321387]=0;e=-1;k:{if(!d){break k}f=G[321388];if(!f){break k}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[321387]=0;G[g>>2]=42205;G[g+4>>2]=c;G[((i<<2)+g|0)+917580>>2]=g+65600;$(156,g- -64|0,65535,8740,g|0)|0;d=G[321387];G[321387]=0;e=-1;l:{if(!d){break l}f=G[321388];if(!f){break l}e=Ab(G[d>>2],h,4);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){break b}G[((i<<2)+g|0)+917584>>2]=g- -64;h=We(1285568,1,h,4);k=Z()|0;d=0}m:{while(1){if(!d){G[321387]=0;ba(166,i+5|0,g+917568|0)|0;d=G[321387];G[321387]=0;e=-1;n:{if(!d){break n}f=G[321388];if(!f){break n}e=Ab(G[d>>2],h,k);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}}G[321387]=0;b=ba(162,g+196672|0,13287)|0;d=G[321387];G[321387]=0;e=-1;o:{if(!d){break o}f=G[321388];if(!f){break o}e=Ab(G[d>>2],h,k);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}a=28824;if(!b){break m}G[321387]=0;c=$(163,3809712,1,65535,b|0)|0;d=G[321387];G[321387]=0;e=-1;p:{if(!d){break p}f=G[321388];if(!f){break p}e=Ab(G[d>>2],h,k);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}G[321387]=0;aa(164,b|0)|0;d=G[321387];G[321387]=0;e=-1;q:{if(!d){break q}f=G[321388];if(!f){break q}e=Ab(G[d>>2],h,k);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}E[c+3809712|0]=0;if((c|0)<0){break m}G[321387]=0;aa(165,g+196672|0)|0;d=G[321387];G[321387]=0;e=-1;r:{if(!d){break r}f=G[321388];if(!f){break r}e=Ab(G[d>>2],h,k);if(!e){break a}_(f|0)}d=Z()|0;if((e|0)==1){continue}break}a=3809712}Wa(h);Fa=g+1179712|0;return a|0}Wa(h);Ve(d,f);W()}function Xf(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;m=Fa-112|0;Fa=m;e=G[a>>2];c=G[a+4>>2];a:{if((e|0)!=G[c+76>>2]){mb(a,e+1|0,0,b);break a}if(G[c+84>>2]!=1){break a}an(m+12|0);c=G[a+4>>2];if(G[c+4>>2]!=G[m+12>>2]){Rb(a,b);c=G[a+4>>2]}e=!!G[c+984>>2];c=G[c+988>>2];if(e&(c|0)>=0|(c|0)>0){d=Fa-608|0;Fa=d;ef(a,2,b);c=d+496|0;_f(a,40853,d+584|0,c,b);Ec(a,33837,d+596|0,c,b);b:{if(G[d+596>>2]<=0){break b}o=1;while(1){c=d+416|0;zb(34641,o,c,b);if((Fc(a,c,d+336|0,d+496|0,b)|0)>0){c=d+16|0;bb(c,47203,68);tb(5,c);break b}c:{d:{if((H[d+336|0]&254)==80){break d}c=H[d+337|0];if((c|0)==80){break d}if((c|0)!=81){break c}}g=G[d+584>>2];c=G[d+588>>2];e:{if(!g&(c|0)<=0|(c|0)<0){j=0;i=0;break e}if(G[b>>2]<=0){p=o-1|0;j=0;i=0;f=1;c=0;while(1){g=f;e=c;G[d+600>>2]=0;G[d+604>>2]=0;G[d+24>>2]=0;G[d+28>>2]=0;G[d+16>>2]=0;G[d+20>>2]=0;f:{if(G[b>>2]>0){break f}f=G[a>>2];c=G[a+4>>2];g:{if((f|0)!=G[c+76>>2]){mb(a,f+1|0,0,b);break g}if((G[c+128>>2]&G[c+132>>2])!=-1){break g}if((Rb(a,b)|0)>0){break f}}c=G[a+4>>2];f=G[c+968>>2]+M(p,160)|0;if(G[f+80>>2]>=0){G[b>>2]=317;break f}q=G[f+76>>2];n=G[c+132>>2];s=G[f+72>>2];h=G[c+128>>2];r=Au(G[c+960>>2],G[c+964>>2],g-1|0,e-!g|0);h=h+r|0;c=Ia+n|0;c=h>>>0>>0?c+1|0:c;n=h;h=s+h|0;c=c+q|0;c=h>>>0>>0?c+1|0:c;if(!(H[f+140|0]!=80&H[f+141|0]!=80)){if((Uc(a,h,c,2,4,d+600|0,b)|0)>0){break f}l=G[d+600>>2];k=0;break f}c=Tc(a,h,c,2,8,d+16|0,b);c=(c|0)<=0;l=c?G[d+16>>2]:l;k=c?G[d+20>>2]:k}c=j>>>0>>0&(i|0)<=(k|0)|(i|0)<(k|0);j=c?l:j;i=c?k:i;c=e;f=g+1|0;c=f?c:c+1|0;h=J[d+584>>2]>g>>>0;g=G[d+588>>2];if(h&(g|0)>=(e|0)|(e|0)<(g|0)){continue}break}break e}p=0;e=0;j=0;i=0;f=c-!g|0;if(!f&g-1>>>0>=7|f){q=g&-8;h=c;f=0;c=0;while(1){n=j>>>0>>0&(i|0)<=(k|0)|(i|0)<(k|0);j=n?l:j;i=n?k:i;f=f+8|0;c=f>>>0<8?c+1|0:c;if((q|0)!=(f|0)|(c|0)!=(h|0)){continue}break}}c=0;f=c;g=g&7;if(!(c|g)){break e}while(1){c=j>>>0>>0&(i|0)<=(k|0)|(i|0)<(k|0);j=c?l:j;i=c?k:i;c=e;e=p+1|0;c=e?c:c+1|0;p=e;e=c;if((g|0)!=(p|0)|(f|0)!=(c|0)){continue}break}}F[d+256>>1]=39;c=jb(d+336|0,40);if(c){E[c|0]=0}c=Va(d+336|0);L[d>>3]=+(j>>>0)+ +(i|0)*4294967296;e=d+208|0;Ya(e,40,59992,d);if((Va(e)+c|0)-69>>>0<=4294967224){tb(5,47271);G[b>>2]=261;break b}c=Gb(Gb(d+256|0,d+336|0),d+208|0);if(Va(c)>>>0<=8){while(1){e=Va(c)+c|0;E[e|0]=32;E[e+1|0]=0;if(Va(c)>>>0<9){continue}break}}e=Va(c)+c|0;E[e|0]=39;E[e+1|0]=0;e=c;c=d+112|0;Ob(d+416|0,e,d+496|0,c,b);Hd(a,c,b)}c=G[d+596>>2]>(o|0);o=o+1|0;if(c){continue}break}}Fa=d+608|0}_n(a,b)}c=G[a+4>>2];h:{if(G[c+8>>2]!=1){break h}e=G[c+968>>2];if(!e){break h}Wa(e);e=0;c=G[a+4>>2];G[c+968>>2]=0;if(!G[c+1228>>2]){break h}g=(G[c+1112>>2]-1|0)/G[c+1052>>2]|0;if((g|0)>=0){while(1){f=e<<2;c=G[a+4>>2];h=G[f+G[c+1240>>2]>>2];if(h){Wa(h);c=G[a+4>>2]}c=G[G[c+1244>>2]+f>>2];if(c){Wa(c)}c=(e|0)!=(g|0);e=e+1|0;if(c){continue}break}c=G[a+4>>2]}Wa(G[c+1248>>2]);Wa(G[G[a+4>>2]+1236>>2]);Wa(G[G[a+4>>2]+1232>>2]);Wa(G[G[a+4>>2]+1244>>2]);Wa(G[G[a+4>>2]+1240>>2]);Wa(G[G[a+4>>2]+1228>>2]);c=G[a+4>>2];G[c+1228>>2]=0;G[c+1232>>2]=0;a=c+1244|0;G[a>>2]=0;G[a+4>>2]=0;a=c+1236|0;G[a>>2]=0;G[a+4>>2]=0}e=G[b>>2];if(!((e|0)<=0|(e|0)==999)){G[m>>2]=G[c+76>>2];a=m+16|0;Ya(a,81,45414,m);tb(5,a);e=G[b>>2]}Fa=m+112|0;return e}function Rj(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;f=Fa-224|0;Fa=f;c=362;a:{if(!a|!b){break a}G[f+220>>2]=0;g=G[a>>2];if((g|0)>0){while(1){d=G[a+4>>2]+M(q,176)|0;c=362;b:{if(!d){break b}c:{e=d+4|0;if(!Xa(35530,e)){break c}if(!Xa(34516,e)){break c}if(!Xa(32941,e)){break c}if(!Xa(33788,e)){break c}if(!Xa(33303,e)){break c}if(!Xa(33311,e)){break c}if(!Xa(33837,e)){break c}if(!Xa(34350,e)){break c}if(!Xa(35787,e)){break c}if(!Xa(33996,e)){break c}d:{e:{if(!fb(33788,e,5)){break e}if(!fb(34641,e,5)){break e}c=0;if(fb(35402,e,5)){break d}}c=0;if((H[d+9|0]-58&255)>>>0<247){break d}c=1;f:{e=H[d+10|0];g:{if((e-48&255)>>>0>=10){if(!e){break c}c=0;if((e|0)!=32){break g}}e=H[d+11|0];if(c){break f}c=368;if((e|0)==32){break d}}c=0;break b}c=368;if((e-48&255)>>>0<10){break d}c=e&223?0:368}break b}c=368}G[f+220>>2]=c;h:{i:{j:{if(!c){k:{switch(G[d>>2]-1|0){case 0:G[f+216>>2]=E[d+80|0];xd(b,14,d+4|0,f+216|0,d+96|0,f+220|0);break j;case 1:t=d+4|0;m=G[d+80>>2];n=d+96|0;i=0;r=0;o=0;k=0;h=Fa-400|0;Fa=h;G[h+12>>2]=-1;l=f+220|0;if(G[l>>2]<=0){c=Va(m);if(n){d=Va(n);r=(d|0)<47?d:47}E[h+16|0]=0;s=qb(h+16|0,m,68);d=jb(s,39);if(d){while(1){i=i+1|0;d=jb(d+1|0,39);if(d){continue}break}}j=c>>>0>1?c:1;c=rb(h+112|0,t,80);E[c+80|0]=0;while(1){d=c;c=d+1|0;if(H[d|0]==32){continue}break}l:{m:{c=Va(d);if((c|0)>8){break m}if((ve(d,h+12|0)|0)>0){break m}c=68-i|0;break l}c=75-(c+i|0)|0}e=c;if((j|0)>0){u=1;while(1){E[s|0]=0;p=qb(s,m+o|0,e);if(G[l>>2]<=0){E[h+304|0]=39;c=0;d=1;n:{o:{p:{g=Va(p);v=g>>>0<68?g:68;if(v){while(1){g=H[c+p|0];E[(h+304|0)+d|0]=g;q:{if((g|0)!=39){g=d;break q}g=d+1|0;E[g+(h+304|0)|0]=39}d=g+1|0;c=c+1|0;if(g>>>0<68&v>>>0>c>>>0){continue}break}if(g>>>0>7){break p}}c=9;cb((h+304|0)+d|0,32,9-d|0);break o}c=d;g=69;if((d|0)==70){break n}}E[(h+304|0)+c|0]=39;g=c+1|0}E[g+(h+304|0)|0]=0}r:{if((e|0)>=(j|0)){break r}e=e-1|0;c=h+304|0;c=Va(c)+c|0;d=c-2|0;if(H[d|0]!=39){E[d|0]=38;break r}E[c-1|0]=0;E[c-3|0]=38}s:{if(!u){Ob(35367,h+304|0,k?0:n,h+208|0,l);F[h+216>>1]=8224;break s}Ob(t,h+304|0,n,h+208|0,l)}wb(b,h+208|0,l);o=e+o|0;j=j-e|0;if((j|0)>0){i=0;E[p|0]=0;d=jb(qb(p,m+o|0,68),39);if(d){while(1){i=i+1|0;d=jb(d+1|0,39);if(d){continue}break}}e=68-i|0}u=0;t:{if((r|0)<=0){k=0;break t}c=i+j|0;if((c|0)>68){k=0;break t}k=(c+r|0)>65&(e|0)>18;e=k?j-15|0:e}if((j|0)>0){continue}break}}}Fa=h+400|0;break j;case 2:G[f+12>>2]=G[d+80>>2];xd(b,41,d+4|0,f+12|0,d+96|0,f+220|0);break j;case 3:xd(b,82,d+4|0,d+80|0,d+96|0,f+220|0);break j;case 4:xd(b,163,d+4|0,d+80|0,d+96|0,f+220|0);break j;case 5:e=d+4|0;g=d+96|0;c=Fa-176|0;Fa=c;d=f+220|0;if(G[d>>2]<=0){F[c+96>>1]=32;Ob(e,c+96|0,g,c,d);wb(b,c,d)}Fa=c+176|0;break j;case 6:break k;default:break i}}c=d+4|0;if(!Xa(32708,c)){ze(b,d+96|0,f+220|0);break j}d=d+96|0;if(!Xa(33332,c)){Pg(b,d,f+220|0);break j}G[f+4>>2]=d;G[f>>2]=c;c=f+16|0;Ya(c,200,8729,f);wb(b,c,f+220|0);break j}G[f+220>>2]=0;if(!H[d+96|0]|(c|0)!=368){break h}e=d+4|0;g=d+96|0;c=Fa-256|0;Fa=c;d=f+220|0;if(G[d>>2]<=0){if((Vc(b,e,c+96|0,c+176|0,d)|0)<=0){Ob(e,c+96|0,g,c,d);Hd(b,c,d)}}Fa=c+256|0}c=G[f+220>>2]}if(c){break a}g=G[a>>2]}q=q+1|0;if((q|0)<(g|0)){continue}break}}Rb(b,f+220|0);c=G[f+220>>2]}Fa=f+224|0;return c}function Bo(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;j=Fa-208|0;Fa=j;bb(j+48|0,118784,72);G[j+32>>2]=G[29724];l=G[29723];G[j+24>>2]=G[29722];G[j+28>>2]=l;l=G[29721];G[j+16>>2]=G[29720];G[j+20>>2]=l;l=G[29719];G[j+8>>2]=G[29718];G[j+12>>2]=l;l=G[29717];G[j>>2]=G[29716];G[j+4>>2]=l;a:{if(!(d|e)|G[i>>2]>0){break a}Qd(a,j+204|0,i);nk(a,9,j+128|0,i);b:{c:{d:{l=G[j+204>>2];if(!(!l|!(G[j+128>>2]|G[j+132>>2]))){if((l|0)<=0){break b}bb(j+48|0,c,l<<3);x=l&1;if((l|0)!=1){break d}o=1;break c}G[i>>2]=320;break a}y=l&-2;l=1;while(1){m=t<<3;o=m|8;s=o+c|0;q=G[s>>2];r=q-1|0;u=G[s+4>>2]-!q|0;s=j+128|0;q=s+m|0;q=Au(G[q>>2],G[q+4>>2],l,n);v=Ia;r=Au(r,u,q,v);z=Ia;u=r;m=c+m|0;r=G[m>>2];l=Au(r-1|0,G[m+4>>2]-!r|0,l,n)+p|0;k=k+Ia|0;k=l>>>0

>>0?k+1|0:k;m=l;l=u+m|0;k=k+z|0;k=m>>>0>l>>>0?k+1|0:k;p=l;t=t+2|0;l=o+s|0;o=Au(G[l>>2],G[l+4>>2],q,v);n=Ia;m=n;l=o;w=w+2|0;if((w|0)!=(y|0)){continue}break}}if(!x){break b}l=(t<<3)+c|0;n=G[l>>2];l=Au(n-1|0,G[l+4>>2]-!n|0,o,m)+p|0;k=k+Ia|0;k=l>>>0

>>0?k+1|0:k;p=l}l=p+1|0;k=l?k:k+1|0;m=l;e:{if(Nb(a,i)){f:{if(G[c>>2]!=1|G[c+4>>2]|(G[j+204>>2]&-2)!=2){break f}p=G[j+128>>2];o=G[j+132>>2];l=Bu(d,e,p,o);n=Ia;if((Au(l,n,p,o)|0)!=(d|0)|(Ia|0)!=(e|0)){break f}G[j+48>>2]=p;G[j+52>>2]=o;k=n+G[c+12>>2]|0;d=l+G[c+8>>2]|0;k=d>>>0>>0?k+1|0:k;e=d;l=e-1|0;d=G[j+136>>2];n=k-!e|0;e=n;k=G[j+140>>2];if(l>>>0>d>>>0&(e|0)>=(k|0)|(e|0)>(k|0)){o=G[j+64>>2];m=G[j+68>>2];while(1){e=o+1|0;m=e?m:m+1|0;o=e;e=l;l=e-d|0;n=n-((d>>>0>e>>>0)+k|0)|0;e=n;if(d>>>0>>0&(k|0)<=(e|0)|(e|0)>(k|0)){continue}break}G[j+64>>2]=o;G[j+68>>2]=m}G[j+56>>2]=l;G[j+60>>2]=n;md(a,b,c,j+48|0,j,1,f,g,0,h,i);break e}Nc(a,b,m,k,d,e,1,f,g,0,h,i);break e}g:{switch(b-11|0){case 0:if(!f){Re(a,2,1,0,m,k,d,e,1,1,0,g,j+203|0,h,i);break e}Re(a,2,1,0,m,k,d,e,1,1,H[f|0],g,j+203|0,h,i);break e;case 1:if(!f){Ef(a,2,1,0,m,k,d,e,1,1,0,g,j+203|0,h,i);break e}Ef(a,2,1,0,m,k,d,e,1,1,E[f|0],g,j+203|0,h,i);break e;case 9:if(!f){Gf(a,2,1,0,m,k,d,e,1,1,0,g,j+203|0,h,i);break e}Gf(a,2,1,0,m,k,d,e,1,1,I[f>>1],g,j+203|0,h,i);break e;case 10:if(!f){jf(a,2,1,0,m,k,d,e,1,1,0,g,j+203|0,h,i);break e}jf(a,2,1,0,m,k,d,e,1,1,F[f>>1],g,j+203|0,h,i);break e;case 19:if(!f){Dh(a,2,1,0,m,k,d,e,1,0,g,j+203|0,h,i);break e}Dh(a,2,1,0,m,k,d,e,1,G[f>>2],g,j+203|0,h,i);break e;case 20:if(!f){Eh(a,2,1,0,m,k,d,e,1,0,g,j+203|0,h,i);break e}Eh(a,2,1,0,m,k,d,e,1,G[f>>2],g,j+203|0,h,i);break e;case 29:if(!f){qe(a,2,1,0,m,k,d,e,1,1,0,g,j+203|0,h,i);break e}qe(a,2,1,0,m,k,d,e,1,1,G[f>>2],g,j+203|0,h,i);break e;case 30:if(!f){Ud(a,2,1,0,m,k,d,e,1,1,0,g,j+203|0,h,i);break e}Ud(a,2,1,0,m,k,d,e,1,1,G[f>>2],g,j+203|0,h,i);break e;case 69:if(!f){hf(a,2,1,0,m,k,d,e,1,1,0,0,g,j+203|0,h,i);break e}hf(a,2,1,0,m,k,d,e,1,1,G[f>>2],G[f+4>>2],g,j+203|0,h,i);break e;case 70:if(!f){Se(a,2,1,0,m,k,d,e,1,1,0,0,g,j+203|0,h,i);break e}Se(a,2,1,0,m,k,d,e,1,1,G[f>>2],G[f+4>>2],g,j+203|0,h,i);break e;case 31:if(!f){ae(a,2,1,0,m,k,d,e,1,1,N(0),g,j+203|0,h,i);break e}ae(a,2,1,0,m,k,d,e,1,1,K[f>>2],g,j+203|0,h,i);break e;case 71:if(!f){Id(a,2,1,0,m,k,d,e,1,1,0,g,j+203|0,h,i);break e}Id(a,2,1,0,m,k,d,e,1,1,L[f>>3],g,j+203|0,h,i);break e;default:break g}}G[i>>2]=410}}Fa=j+208|0}function Nn(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;G[119132]=b;a:{b:{b=G[110920];c:{d:{if(b>>>0>>0<2){break f}b=b+d|0;G[110921]=b;if(b>>>0<32768){continue}break e}break}if(b){break e}Ua(443536);Ua(22164);G[47520]=1;G[47519]=0;b=2;break c}G[110920]=1;G[110923]=G[110923]+b;b=443696}b=H[b|0];G[47520]=b;G[47519]=b&128;if(b&96){Ua(443536);Ua(15074);b=G[47520]}d=b&31;G[47520]=d;if(d>>>0>=17){break b}b=1<>3;d=e-h|0;h:{if((d|0)<=0){break h}i=0;b=0;if(e+(h^-1)>>>0>=3){m=d&-4;l=0;while(1){E[b+443696|0]=H[(b+h|0)+443696|0];e=b|1;E[e+443696|0]=H[(e+h|0)+443696|0];e=b|2;E[e+443696|0]=H[(e+h|0)+443696|0];e=b|3;E[e+443696|0]=H[(e+h|0)+443696|0];b=b+4|0;l=l+4|0;if((m|0)!=(l|0)){continue}break}}e=d&3;if(!e){break h}while(1){E[b+443696|0]=H[(b+h|0)+443696|0];b=b+1|0;i=i+1|0;if((e|0)!=(i|0)){continue}break}}G[110921]=d;if(d>>>0<=63){n=zc(d+443696|0,1,32768,a);if((n|0)==-1){Ua(443536);Ua(22164);return 1}d=G[110921]+n|0;G[110921]=d;G[110923]=G[110923]+n}f=0;if(n){h=d-((d>>>0)%(k>>>0)|0)<<3}else{h=(d<<3)+t|0}i:{if((h|0)<=0){break i}while(1){if((j|0)>(r|0)){b=k+1|0;o=-1<>3;b=d+443696|0;d=(H[b|0]|H[b+1|0]<<8|H[d+443698|0]<<16)>>>(f&7)&o;f=f+k|0;j:{if((g|0)!=-1){m=d;d=g;e=c;break j}if(d>>>0>=256){break a}E[c+673152|0]=d;e=c+1|0;if((f|0)>=(h|0)){c=e;g=d;p=d;break i}c=f>>3;b=c+443696|0;m=(H[b|0]|H[b+1|0]<<8|H[c+443698|0]<<16)>>>(f&7)&o;f=f+k|0;p=d}if(!(!G[47519]|(m|0)!=256)){j=256;cb(476544,0,256);c=k<<3;b=(c+f|0)-1|0;f=b-((b|0)%(c|0)|0)|0;g=d;c=e;o=511;r=511;k=9;continue g}c=757118;b=m;if((j|0)<=(b|0)){if((j|0)<(m|0)){if((e|0)>0){Mn(e);G[110922]=G[110922]+e}break a}E[757117]=p;c=757117;b=d}if(b>>>0>=256){while(1){c=c-1|0;E[c|0]=H[b+607616|0];b=I[(b<<1)+476544>>1];if(b>>>0>255){continue}break}}i=c-1|0;p=H[b+607616|0];E[i|0]=p;b=757119-c|0;c=e+b|0;k:{if((c|0)>=16384){c=e;while(1){g=16384-c|0;q=(b|0)<(g|0)?b:g;if((q|0)>0){bb(c+673152|0,i,q);c=c+q|0}b=c;l:{if((b|0)<16384){break l}e=G[110919];m:{if(!e){if((hb(673152,1,b,G[119132])|0)==(b|0)){break m}Ua(443536);Ua(59704);break m}c=G[G[110917]>>2];n:{l=G[110922];g=b+l|0;if(g>>>0<=J[G[110918]>>2]){break n}c=Ja[e|0](c,g)|0;G[G[110917]>>2]=c;l=G[110922];G[G[110918]>>2]=b+l;if(c){break n}Ua(443536);Ua(59658);break m}bb(c+l|0,673152,b)}G[110922]=b+G[110922];b=0}c=b;i=i+q|0;b=757118-i|0;if((b|0)>0){continue}break}break k}bb(e+673152|0,i,b)}if((j|0)<(s|0)){F[(j<<1)+476544>>1]=d;E[j+607616|0]=p;j=j+1|0}g=m;if((f|0)<(h|0)){continue}break}}if(n){continue}break}break}if((c|0)<=0){return 0}Mn(c);G[110922]=G[110922]+c;return 0}Ua(443536);Ua(22202);return 1}Ua(443536);Ua(42389);return 1}function tk(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,F=0,I=0,J=0,K=0;w=9;f=Fa-1008|0;Fa=f;G[f+812>>2]=0;i=bb(f,119248,792);g=G[d>>2];if((g|0)<=0){Td(a,i+1004|0,i+1e3|0,d);if(G[i+1004>>2]>=9){while(1){E[i+816|0]=0;l=i+912|0;Sd(a,w,l,d);x=i+816|0;z=i+812|0;A=i+808|0;B=i+804|0;C=i+800|0;D=i+796|0;F=i+792|0;g=0;o=0;m=0;p=0;s=0;t=0;u=0;a:{if(G[d>>2]>0){break a}if(!(x?l:0)){G[d>>2]=115;break a}E[x|0]=0;if(!H[l|0]){break a}I=32;b:{c:{while(1){J=G[(m<<3)+i>>2];k=H[J|0];if((k|0)==42){v=1;q=0;break b}d:{e:{if(!(!p|(k|0)!=(g&255))){p=1;n=32;f=0;q=0;break e}p=1;f=0;n=32;e=0;y=0;j=0;q=0;g=0;v=0;h=k;if(!h){break d}f:{while(1){g=e;e=E[l+e|0];g:{h:{i:{j:{k:{r=h&255;switch(r-105|0){case 1:break j;case 0:break k;default:break i}}e=e-48|0;if(e>>>0>=10){break h}j=e;break g}e=e-48|0;if(e>>>0>=10){break h}q=e;break g}l:{m:{n:{switch(r-63|0){default:if((r|0)!=35){break m}case 45:case 46:case 47:if(e-48>>>0>9){break f}K=h-109|0;h=0;while(1){o:{f=(e<<24>>24)-48|0;if(f>>>0>9){f=g;break o}h=f+M(h,10)|0;f=8;g=g+1|0;e=H[l+g|0];if((g|0)!=8){continue}}break};g=f-1|0;if((K&255)>>>0>1){break l}if(h-1>>>0>998){break f}f=1;e=1;p:{if(G[c>>2]==(h|0)){break p}e=2;if(G[c+4>>2]==(h|0)){break p}e=3;if(G[c+8>>2]==(h|0)){break p}f=G[c+12>>2]==(h|0);e=f<<2}h=(r|0)==110;s=h?s:e;t=h?e:t;break h;case 0:break g;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:break m;case 34:break n}}if(e-65>>>0<26){n=e;break g}if((e|0)!=32){break h}n=e;break g}if((e&255)==(r|0)){break g}break f}o=(r|0)==108?h:o;break g}if(f){break g}break f}f=1;e=g+1|0;y=y+1|0;h=H[J+y|0];if(h){p=0;if((g|0)<7){continue}}break}p=0;if(!k){f=j;g=0;break e}q:{if((g|0)>6){v=1;break q}v=1;f=j;g=k;if(H[e+l|0]!=32){break d}}f=j;break c}f=j;g=k;break d}v=0}m=m+1|0;if((m|0)!=99){continue}break}m=99}u=f;I=n}if(A){G[A>>2]=u}if(B){G[B>>2]=q}if(C){G[C>>2]=t}if(D){G[D>>2]=s}if(F){G[F>>2]=o}if(z){G[z>>2]=m}g=0;if(!v){break a}k=G[((m<<3)+i|0)+4>>2];f=H[k|0];if(!f|(f|0)==45){break a}j=Za(x,l);e=H[k|0];if((e|0)==43){break a}u=u+48|0;q=q+48|0;l=(t>>>0)%10|48;m=(s>>>0)%10|48;p=(t|0)<=0;h=0;while(1){r:{s:{t:{u:{v:{f=e&255;switch(f-105|0){case 1:break t;case 0:break u;default:break v}}if(f){break s}if((g|0)<=7){cb(g+j|0,32,8-g|0)}break a}E[g+j|0]=u;break r}E[g+j|0]=q;break r}if(!(p|(f|0)!=110)){E[g+j|0]=l;break r}if(!((f|0)!=109|(s|0)<=0)){E[g+j|0]=m;break r}if(!((f|0)!=108|(o|0)<0)){e=1;w:{if((o|0)<=0){break w}while(1){e=M(e,10);if(((o|0)/(e|0)|0)>0){continue}break}if(e>>>0<10){break w}while(1){f=(e>>>0)/10|0;E[g+j|0]=(((o|0)/(f|0)|0)%10|0)+48;g=g+1|0;n=e>>>0>99;e=f;if(n){continue}break}}g=g-1|0;break r}n=g+j|0;if((f|0)==97){E[n|0]=I;break r}E[n|0]=e}g=g+1|0;h=h+1|0;e=H[k+h|0];continue}}if(H[i+816|0]){wb(b,i+816|0,d)}E[i+824|0]=0;E[i+920|0]=0;f=G[i+1004>>2]>(w|0);w=w+1|0;if(f){continue}break}}g=G[d>>2]}Fa=i+1008|0;return g}function Th(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,w=0,x=0,y=0,z=0,B=0,C=0,D=0,E=0,F=0,H=0,I=0,J=0,K=0,M=0,N=0,P=0,Q=0;J=1;f=rd(a);g=rd(b);k=Fa-48|0;Fa=k;m=G[g+3304>>2];w=L[(m?72:56)+g>>3];x=L[(m?80:64)+g>>3];o=L[(m?56:72)+g>>3];n=L[(m?64:80)+g>>3];d=G[f+3304>>2];y=L[f+(d?72:56)>>3];l=L[f+(d?80:64)>>3];q=L[f+(d?56:72)>>3];r=L[f+(d?64:80)>>3];s=L[(!m<<3)+g>>3];D=L[f+(!d<<3)>>3];t=L[(((m|0)!=0)<<3)+g>>3];E=L[f+(((d|0)!=0)<<3)>>3];z=L[g+24>>3];u=L[g+16>>3];B=L[f+24>>3];C=L[f+16>>3];K=L[g+40>>3];F=L[g+32>>3];M=L[f+40>>3];H=L[f+32>>3];i=L[g+48>>3];h=L[f+48>>3];c=L[f+136>>3];a:{if(O(c)<2147483648){d=~~c;break a}d=-2147483648}G[323532]=d;c=L[f+144>>3];b:{if(O(c)<2147483648){d=~~c;break b}d=-2147483648}G[323534]=d;c=L[g+136>>3];c:{if(O(c)<2147483648){d=~~c;break c}d=-2147483648}G[323533]=d;c=L[g+144>>3];d:{if(O(c)<2147483648){d=~~c;break d}d=-2147483648}G[323535]=d;G[f+6048>>2]=0;G[g+6048>>2]=0;e:{f:{if(!(t!=E|s!=D)){L[162598]=n;L[162597]=o;L[162596]=x;L[162595]=w;L[162589]=r;L[162588]=q;L[162587]=l;L[162586]=y;L[162590]=L[f+88>>3];L[162591]=L[f+96>>3];L[162592]=L[f+104>>3];L[162593]=L[f+112>>3];L[162599]=L[g+88>>3];L[162600]=L[g+96>>3];L[162601]=L[g+104>>3];L[162602]=L[g+112>>3];e=i*.0174532925199433;j=h*.0174532925199433;c=0;break f}Bd(g,E,D,k+24|0,k+16|0,k+12|0);h=L[k+16>>3];c=L[k+24>>3];g:{if(c!=u){h=h-z;j=c-u;I=Pd(K*h/F/j);break g}I=h!=z?1.5707963267948966:0;h=h-z;j=c-u}c=Db(o*j+n*h,w*j+x*h);e=ib(c);c=eb(c);p=n*c-e*x;L[162598]=p;i=o*c-e*w;L[162597]=i;h=c*x+n*e;L[162596]=h;c=c*w+o*e;L[162595]=c;e=1/(c*p-i*h);A(+e);d=v(1)|0;m=v(0)|0;d=d&2147483647;if((d|0)==2146435072&(m|0)!=0|d>>>0>2146435072){hb(72731,72,1,G[24367]);d=1;break e}L[162602]=c*e;L[162600]=e*-h;L[162599]=p*e;L[162601]=e*-i;Bd(f,t,s,k+40|0,k+32|0,k+12|0);h=L[k+32>>3];c=L[k+40>>3];h:{if(c!=C){e=h-B;j=c-C;h=Pd(M*e/H/j);break h}e=h-B;j=c-C;h=h!=B?1.5707963267948966:0}p=L[k+24>>3];c=Db(q*j+r*e,y*j+l*e)+3.141592653589793;i=ib(c);c=eb(c);o=r*c-i*l;L[162589]=o;n=q*c-i*y;L[162588]=n;e=c*l+r*i;L[162587]=e;c=c*y+q*i;L[162586]=c;i=1;l=1/(c*o-n*e);A(+l);d=v(1)|0;m=v(0)|0;d=d&2147483647;if((d|0)==2146435072&(m|0)!=0|d>>>0>2146435072){hb(72659,71,1,G[24367]);d=1;break e}q=h+3.141592653589793;m=H*j>0;r=I+3.141592653589793;d=F*(p-u)<0;L[162593]=c*l;L[162591]=l*-e;L[162590]=o*l;L[162592]=l*-n;s=s*.0174532925199433;l=eb(s);p=t*.0174532925199433;o=ib(p);n=D*.0174532925199433;t=eb(n);c=E*.0174532925199433;e=ib(c);p=eb(p);c=eb(c);c=ib(s)*ib(n)+(c*(t*(p*l))+e*(t*(o*l)));i:{if(c>1){break i}i=c;if(!(c<-1)){break i}i=-1}j=m?q:h;e=d?r:I;c=Sc(i)}L[161765]=K;L[161764]=F;L[161763]=M;L[161762]=H;L[161755]=z;L[161754]=u;L[161753]=B;L[161752]=C;N=1294088,P=ib(c),L[N>>3]=P;N=1294080,P=eb(c),L[N>>3]=P;N=1294072,P=ib(e),L[N>>3]=P;N=1294064,P=eb(e),L[N>>3]=P;N=1294056,P=ib(j),L[N>>3]=P;N=1294048,P=eb(j),L[N>>3]=P;d=Za(1294008,f+3544|0);Za(d+4|0,g+3544|0);G[d+6744>>2]=1;G[d+6664>>2]=0;G[d+6668>>2]=0;G[d+6672>>2]=1;G[d+6676>>2]=1;d=0}Fa=k+48|0;j:{if(d){break j}N=1300672,Q=hm(a,1294144),G[N>>2]=Q;N=1300676,Q=hm(b,1297408),G[N>>2]=Q;if(g){Wa(g)}J=0;if(!f){break j}Wa(f)}return J}function ve(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;j=Fa-128|0;Fa=j;k=G[b>>2];a:{if((k|0)>0){d=k;break a}d=Va(a);f=d>>>0<8?d:8;if(!f){d=k;break a}b:{c:{d:{if(k){while(1){e:{f:{h=a+e|0;i=E[h|0];d=i;d=d-97>>>0<26?d&95:d;g:{if((d-65&255)>>>0<26|(d-48&255)>>>0<10){break g}d=d&255;if((d|0)==95){break g}if((d|0)!=45){break f}}d=0;if(g){break b}break e}d=1;if((i|0)!=32){break d}}g=d;e=e+1|0;if((f|0)!=(e|0)){continue}break}d=k;break a}d=H[a|0];h:{i:{if((d-65&255)>>>0<26|(d-48&255)>>>0<10){break i}h=a;j:{switch(d-32|0){case 0:break h;case 13:break i;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:break d;default:break j}}if((d|0)!=95){break d}}e=1}d=0;if((f|0)==1){break a}g=e;c=H[a+1|0];k:{l:{m:{if((c-65&255)>>>0<26|(c-48&255)>>>0<10){break m}h=a+1|0;e=1;n:{switch(c-32|0){case 0:break l;case 13:break m;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:break d;default:break n}}if((c|0)!=95){break d}}i=1;if(!g){break k}}if((f|0)==2){break a}c=H[a+2|0];o:{p:{if((c-65&255)>>>0<26|(c-48&255)>>>0<10){break p}h=a+2|0;g=0;e=2;q:{switch(c-32|0){case 0:break o;case 13:break p;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:break d;default:break q}}if((c|0)!=95){break d}}g=1;if(!i){break k}}if((f|0)==3){break a}c=H[a+3|0];r:{s:{if((c-65&255)>>>0<26|(c-48&255)>>>0<10){break s}h=a+3|0;i=0;e=3;t:{switch(c-32|0){case 0:break r;case 13:break s;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:break d;default:break t}}if((c|0)!=95){break d}}i=1;if(!g){break k}}if((f|0)==4){break a}c=H[a+4|0];u:{v:{if((c-65&255)>>>0<26|(c-48&255)>>>0<10){break v}h=a+4|0;g=0;e=4;w:{switch(c-32|0){case 0:break u;case 13:break v;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:break d;default:break w}}if((c|0)!=95){break d}}g=1;if(!i){break k}}if((f|0)==5){break a}c=H[a+5|0];x:{y:{if((c-65&255)>>>0<26|(c-48&255)>>>0<10){break y}h=a+5|0;i=0;e=5;z:{switch(c-32|0){case 0:break x;case 13:break y;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:break d;default:break z}}if((c|0)!=95){break d}}i=1;if(!g){break k}}if((f|0)==6){break a}c=H[a+6|0];A:{B:{if((c-65&255)>>>0<26|(c-48&255)>>>0<10){break B}h=a+6|0;g=0;e=6;C:{switch(c-32|0){case 0:break A;case 13:break B;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:break d;default:break C}}if((c|0)!=95){break d}}g=1;if(!i){break k}}if((f|0)==7){break a}f=H[a+7|0];D:{if((f-65&255)>>>0<26|(f-48&255)>>>0<10){break D}h=a+7|0;e=7;E:{switch(f-32|0){case 0:break a;case 13:break D;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:break d;default:break E}}if((f|0)!=95){break d}}if(g){break a}}G[j>>2]=a;e=j+32|0;Ya(e,81,8605,j);break c}if(k){break b}G[j+20>>2]=a;G[j+16>>2]=e+1;a=j+32|0;Ya(a,81,8559,j+16|0);tb(5,a);e=46083;F:{switch(H[h|0]){case 9:break F;case 0:break c;default:break b}}e=46047}tb(5,e)}d=207;G[b>>2]=207}Fa=j+128|0;return d}function tb(a,b){var c=0,d=0,e=0,f=0,g=0;a:{b:{c:{switch(a-1|0){case 4:if(H[b|0]){a=G[50359];while(1){d:{e:{f:{g:{if((a|0)!=25){if(H[199408]){break g}c=199408;break f}c=G[49824];G[49849]=c;E[c|0]=0;yd(199296,199300,96);G[49848]=c;a=24;break d}c=199489;if(!H[199489]){break f}c=199570;if(!H[199570]){break f}c=199651;if(!H[199651]){break f}c=199732;if(!H[199732]){break f}c=199813;if(!H[199813]){break f}c=199894;if(!H[199894]){break f}c=199975;if(!H[199975]){break f}c=200056;if(!H[200056]){break f}c=200137;if(!H[200137]){break f}c=200218;if(!H[200218]){break f}c=200299;if(!H[200299]){break f}c=200380;if(!H[200380]){break f}c=200461;if(!H[200461]){break f}c=200542;if(!H[200542]){break f}c=200623;if(!H[200623]){break f}c=200704;if(!H[200704]){break f}c=200785;if(!H[200785]){break f}c=200866;if(!H[200866]){break f}c=200947;if(!H[200947]){break f}c=201028;if(!H[201028]){break f}c=201109;if(!H[201109]){break f}c=201190;if(!H[201190]){break f}c=201271;if(!H[201271]){break f}if(H[201352]){break e}c=201352}G[(a<<2)+199296>>2]=c;break d}c=G[(a<<2)+199296>>2]}qb(c,b,80);a=a+1|0;c=b;b=Va(b);b=c+(b>>>0<80?b:80)|0;if(H[b|0]){continue}break}G[50359]=a}G[49850]=b;return;case 5:h:{i:{j:{k:{a=G[50359];if((a|0)!=25){if(H[199408]){break k}b=199408;break j}b=G[49824];G[49849]=b;E[b|0]=0;yd(199296,199300,96);G[49848]=b;a=24;break h}b=199489;if(!H[199489]){break j}b=199570;if(!H[199570]){break j}b=199651;if(!H[199651]){break j}b=199732;if(!H[199732]){break j}b=199813;if(!H[199813]){break j}b=199894;if(!H[199894]){break j}b=199975;if(!H[199975]){break j}b=200056;if(!H[200056]){break j}b=200137;if(!H[200137]){break j}b=200218;if(!H[200218]){break j}b=200299;if(!H[200299]){break j}b=200380;if(!H[200380]){break j}b=200461;if(!H[200461]){break j}b=200542;if(!H[200542]){break j}b=200623;if(!H[200623]){break j}b=200704;if(!H[200704]){break j}b=200785;if(!H[200785]){break j}b=200866;if(!H[200866]){break j}b=200947;if(!H[200947]){break j}b=201028;if(!H[201028]){break j}b=201109;if(!H[201109]){break j}b=201190;if(!H[201190]){break j}b=201271;if(!H[201271]){break j}if(H[201352]){break i}b=201352}G[(a<<2)+199296>>2]=b;break h}b=G[(a<<2)+199296>>2]}E[b|0]=27;E[b+1|0]=0;G[50359]=a+1;break b;case 3:c=G[50359];e=(c<<2)-4|0;f=(c>>31^-1)&c;a=0;while(1){if((a|0)!=(f|0)){d=G[49824];g=Za(b,d);E[d|0]=0;d=c-1|0;G[50359]=d;if((c|0)!=1){yd(199296,199300,e-(a<<2)|0)}a=a+1|0;c=d;if(H[g|0]==27){continue}break b}break};E[b|0]=0;return;case 2:a=G[50359];if((a|0)<=0){break b}a=a-1|0;G[50359]=a;E[G[(a<<2)+199296>>2]]=0;return;case 0:break a;case 1:break c;default:break b}}b=G[50359];if((b|0)<=0){break b}while(1){l:{a=b-1|0;c=G[(a<<2)+199296>>2];d=H[c|0];E[c|0]=0;if((d|0)==27){break l}c=b>>>0>1;b=a;if(c){continue}}break}G[50359]=a;return}return}a=G[50359];m:{if((a|0)<=0){break m}b=0;if(a-1>>>0>=3){e=a&-4;while(1){d=b<<2;E[G[d+199296>>2]]=0;E[G[(d|4)+199296>>2]]=0;E[G[(d|8)+199296>>2]]=0;E[G[(d|12)+199296>>2]]=0;b=b+4|0;c=c+4|0;if((e|0)!=(c|0)){continue}break}}c=a&3;if(!c){break m}a=0;while(1){E[G[(b<<2)+199296>>2]]=0;b=b+1|0;a=a+1|0;if((c|0)!=(a|0)){continue}break}}G[50359]=0}function _m(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=N(0),j=0,k=0,l=0,m=0,n=N(0),o=0,p=0;f=Fa-32|0;Fa=f;G[f+16>>2]=0;G[f+20>>2]=0;G[f+8>>2]=0;G[f+12>>2]=0;G[f>>2]=0;G[f+4>>2]=0;while(1){d=b;b=d+1|0;if(H[d|0]==32){continue}break}a:{b:{if(fb(d,5791,8)){if(fb(d,33720,8)){break b}}b=d+8|0;h=11;c:{d:{e:{f:{while(1){g:{G[f+28>>2]=b;e=H[b|0];if((e|0)!=32){switch(e-71|0){case 11:case 43:break g;case 1:case 33:break d;case 9:case 41:break e;case 0:case 32:break f;default:break c}}else{b=b+1|0;continue}}break}while(1){d=e&255;if(!d|(d|0)==32|(d|0)==59){break c}d=b+1|0;G[f+28>>2]=d;e=H[b+1|0];b=d;continue}}while(1){h=21;d=e&255;if(!d|(d|0)==32|(d|0)==59){break c}d=b+1|0;G[f+28>>2]=d;e=H[b+1|0];b=d;continue}}while(1){h=31;d=e&255;if(!d|(d|0)==32|(d|0)==59){break c}d=b+1|0;G[f+28>>2]=d;e=H[b+1|0];b=d;continue}}d=b+1|0;G[f+28>>2]=d;e=H[b+1|0];g=e-83&-33;b=d;while(1){d=e&255;if(!(!d|(d|0)==32|(d|0)==59)){d=b+1|0;G[f+28>>2]=d;e=H[b+1|0];b=d;continue}break}l=!(g&255);h=41;m=1}h:{if((e&255)!=32){d=b;break h}while(1){d=b+1|0;G[f+28>>2]=d;e=H[b+1|0];b=d;if((e|0)==32){continue}break}}i:{if((e<<24>>24)-48>>>0>=10){break i}g=0;while(1){o=(g<<2)+f|0,p=_b(d),G[o>>2]=p;e=E[d|0];if(e-48>>>0<=9){while(1){b=d+1|0;G[f+28>>2]=b;e=E[d+1|0];d=b;if(e-48>>>0<10){continue}break}}if((e|0)==44){b=d+1|0;G[f+28>>2]=b;e=H[d+1|0];d=b}if((e&255)==32){while(1){b=d+1|0;G[f+28>>2]=b;e=H[d+1|0];d=b;if((e|0)==32){continue}break}}if((e<<24>>24)-48>>>0>9){break i}b=g>>>0>7;g=g+1|0;if(!b){continue}break}}j:{if((e&255)!=59){i=N(-99);g=1;break j}while(1){g=1;e=d+1|0;G[f+28>>2]=e;b=H[d+1|0];d=e;if((b|0)==32){continue}break}i=N(-99);while(1){k:{l:{m:{n:{o:{b=b&255;switch(b-81|0){case 1:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 33:break b;case 0:case 32:break n;case 2:case 34:break o;default:break k}}while(1){b=e+1|0;G[f+28>>2]=b;d=H[e+1|0];e=b;if((d|0)==32){continue}break}j=vb(e,f+28|0);e=G[f+28>>2];while(1){b=H[e|0];d=b-32|0;if(!(!d|(d|0)==12)){break m}e=e+1|0;G[f+28>>2]=e;continue}}b=e+1|0;G[f+28>>2]=b;k=2;d=H[e+1|0];p:{if(!((d|0)==122|(d|0)==90)){k=g;if((d|0)!=48){break p}k=-1}b=e+2|0;G[f+28>>2]=b;d=H[e+2|0]}if((d&255)==32){while(1){d=b+1|0;G[f+28>>2]=d;g=H[b+1|0];b=d;if((g|0)==32){continue}break}}j=vb(b,f+28|0);e=G[f+28>>2];while(1){b=H[e|0];d=b-32|0;if(!(!d|(d|0)==12)){break l}e=e+1|0;G[f+28>>2]=e;continue}}n=N(j);continue}i=N(j);g=k;continue}break}if(b){break b}}q:{r:{switch(h+1|0){default:Ua(60223);G[c>>2]=413;break q;case 0:case 1:case 12:case 22:case 23:case 32:case 42:case 52:break r}}G[G[a+4>>2]+992>>2]=h}b=G[a+4>>2];G[b+996>>2]=G[f>>2];G[b+1e3>>2]=G[f+4>>2];G[b+1004>>2]=G[f+8>>2];G[b+1008>>2]=G[f+12>>2];G[b+1012>>2]=G[f+16>>2];G[b+1016>>2]=G[f+20>>2];if(m){K[G[a+4>>2]+1040>>2]=n;G[G[a+4>>2]+1044>>2]=l}if(i!=N(-99)){K[G[a+4>>2]+1020>>2]=i==N(0)?N(9999):i;s:{if(g-3>>>0<=4294967291){Ua(62026);G[c>>2]=413;break s}G[G[a+4>>2]+1024>>2]=g?g:1}}break a}G[c>>2]=125}Fa=f+32|0}function sk(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=N(0);d=Fa-176|0;Fa=d;e=G[c>>2];a:{if((e|0)>0){break a}e=H[201440];if(!e){e=H[G[29798]];E[201440]=e}G[48624]=0;G[b>>2]=0;b:{if(!(!jb(a,68)&(e&255)!=44)){if(Va(a)>>>0>=73){E[d+120|0]=H[10453];a=H[10449]|H[10450]<<8|(H[10451]<<16|H[10452]<<24);G[d+112>>2]=H[10445]|H[10446]<<8|(H[10447]<<16|H[10448]<<24);G[d+116>>2]=a;a=H[10441]|H[10442]<<8|(H[10443]<<16|H[10444]<<24);G[d+104>>2]=H[10437]|H[10438]<<8|(H[10439]<<16|H[10440]<<24);G[d+108>>2]=a;a=H[10433]|H[10434]<<8|(H[10435]<<16|H[10436]<<24);G[d+96>>2]=H[10429]|H[10430]<<8|(H[10431]<<16|H[10432]<<24);G[d+100>>2]=a;a=H[10425]|H[10426]<<8|(H[10427]<<16|H[10428]<<24);G[d+88>>2]=H[10421]|H[10422]<<8|(H[10423]<<16|H[10424]<<24);G[d+92>>2]=a;a=H[10417]|H[10418]<<8|(H[10419]<<16|H[10420]<<24);G[d+80>>2]=H[10413]|H[10414]<<8|(H[10415]<<16|H[10416]<<24);G[d+84>>2]=a;tb(5,d+80|0);e=408;G[c>>2]=408;break a}f=Za(d,a);g=jb(f,68);G[d+172>>2]=g;if(g){E[g|0]=69}c:{if((e&255)!=44){break c}e=jb(f,46);G[d+172>>2]=e;if(!e){break c}E[e|0]=44}h=vb(f,d+172|0);break b}h=vb(a,d+172|0)}i=N(h);K[b>>2]=i;if((H[G[d+172>>2]]|32)==32){e=(B(i),v(2))>>>16|0}else{e=H[67094]|H[67095]<<8|(H[67096]<<16|H[67097]<<24);f=H[67090]|H[67091]<<8|(H[67092]<<16|H[67093]<<24);E[d+117|0]=f;E[d+118|0]=f>>>8;E[d+119|0]=f>>>16;E[d+120|0]=f>>>24;E[d+121|0]=e;E[d+122|0]=e>>>8;E[d+123|0]=e>>>16;E[d+124|0]=e>>>24;e=H[67089]|H[67090]<<8|(H[67091]<<16|H[67092]<<24);G[d+112>>2]=H[67085]|H[67086]<<8|(H[67087]<<16|H[67088]<<24);G[d+116>>2]=e;e=H[67081]|H[67082]<<8|(H[67083]<<16|H[67084]<<24);G[d+104>>2]=H[67077]|H[67078]<<8|(H[67079]<<16|H[67080]<<24);G[d+108>>2]=e;e=H[67073]|H[67074]<<8|(H[67075]<<16|H[67076]<<24);G[d+96>>2]=H[67069]|H[67070]<<8|(H[67071]<<16|H[67072]<<24);G[d+100>>2]=e;e=H[67065]|H[67066]<<8|(H[67067]<<16|H[67068]<<24);G[d+88>>2]=H[67061]|H[67062]<<8|(H[67063]<<16|H[67064]<<24);G[d+92>>2]=e;e=H[67057]|H[67058]<<8|(H[67059]<<16|H[67060]<<24);G[d+80>>2]=H[67053]|H[67054]<<8|(H[67055]<<16|H[67056]<<24);G[d+84>>2]=e;tb(5,qb(d+80|0,a,30));G[c>>2]=408;e=I[b+2>>1]}if(!(G[48624]!=68&(e&32640)!=32640)){e=H[67094]|H[67095]<<8|(H[67096]<<16|H[67097]<<24);f=H[67090]|H[67091]<<8|(H[67092]<<16|H[67093]<<24);E[d+117|0]=f;E[d+118|0]=f>>>8;E[d+119|0]=f>>>16;E[d+120|0]=f>>>24;E[d+121|0]=e;E[d+122|0]=e>>>8;E[d+123|0]=e>>>16;E[d+124|0]=e>>>24;e=H[67089]|H[67090]<<8|(H[67091]<<16|H[67092]<<24);G[d+112>>2]=H[67085]|H[67086]<<8|(H[67087]<<16|H[67088]<<24);G[d+116>>2]=e;e=H[67081]|H[67082]<<8|(H[67083]<<16|H[67084]<<24);G[d+104>>2]=H[67077]|H[67078]<<8|(H[67079]<<16|H[67080]<<24);G[d+108>>2]=e;e=H[67073]|H[67074]<<8|(H[67075]<<16|H[67076]<<24);G[d+96>>2]=H[67069]|H[67070]<<8|(H[67071]<<16|H[67072]<<24);G[d+100>>2]=e;e=H[67065]|H[67066]<<8|(H[67067]<<16|H[67068]<<24);G[d+88>>2]=H[67061]|H[67062]<<8|(H[67063]<<16|H[67064]<<24);G[d+92>>2]=e;e=H[67057]|H[67058]<<8|(H[67059]<<16|H[67060]<<24);G[d+80>>2]=H[67053]|H[67054]<<8|(H[67055]<<16|H[67056]<<24);G[d+84>>2]=e;tb(5,qb(d+80|0,a,30));G[b>>2]=0;G[c>>2]=412;G[48624]=0}e=G[c>>2]}Fa=d+176|0;return e}function $b(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,w=0,y=0,B=0,C=0,D=0,E=0,F=0;p=Fa-16|0;Fa=p;A(+b);g=v(1)|0;j=v(0)|0;A(+a);d=v(1)|0;c=v(0)|0;s=g>>>20|0;t=s&2047;u=t-1086|0;k=d>>>20|0;a:{b:{if(u>>>0>4294967167&k-2047>>>0>=4294965250){break b}i=j;f=g<<1|i>>>31;i=i<<1;q=f-!i|0;if((q|0)==-2097153&(i-1|0)==-1|q>>>0>4292870143){e=1;if(!(f|i)|!c&(d|0)==1072693248){break a}i=!i&(f|0)==-2097152|f>>>0<4292870144;f=c;c=d<<1|c>>>31;d=f<<1;if(!(i&(!d&(c|0)==-2097152|c>>>0<4292870144))){e=a+b;break a}if(!d&(c|0)==2145386496){break a}e=((g|0)>0|(g|0)>=0)^c>>>0>2145386495?0:b*b;break a}f=d<<1|c>>>31;i=c<<1;q=i-1|0;f=f-!i|0;if((f|0)==-2097153&(q|0)==-1|f>>>0>4292870143){e=a*a;if((d|0)<0){e=(kq(j,g)|0)==1?-e:e}if((g|0)>0|(g|0)>=0){break a}L[p+8>>3]=1/e;e=L[p+8>>3];break a}if((d|0)<0){f=kq(j,g);if(!f){a=a-a;e=a/a;break a}k=k&2047;r=((f|0)==1)<<18;d=d&2147483647}if(u>>>0<=4294967167){e=1;if(!c&(d|0)==1072693248){break a}if(t>>>0<=957){e=((d|0)==1072693248&(c|0)!=0|d>>>0>1072693248?b:-b)+1;break a}if((!c&(d|0)==1072693248|d>>>0<1072693248)!=(s>>>0<2048|0)){c=Fa-16|0;L[c+8>>3]=3105036184601418e216;e=L[c+8>>3]*3105036184601418e216;break a}c=Fa-16|0;L[c+8>>3]=12882297539194267e-247;e=L[c+8>>3]*12882297539194267e-247;break a}if(k){break b}A(+(a*4503599627370496));d=v(1)|0;c=v(0)|0;d=(d&2147483647)-54525952|0}x(0,j&-134217728);x(1,g|0);w=+z();f=d;g=d-1072076117|0;d=0;f=f-((g&-1048576)+(d>>>0>c>>>0)|0)|0;j=c-d|0;d=f;x(0,0);x(1,(j- -2147483648>>>0<2147483648?d+1|0:d)|0);e=+z();f=(g>>>13&127)<<5;h=L[f+97544>>3];a=e*h+-1;o=L[12186];l=a*o;y=a*l;B=+(g>>20);C=B*L[12184]+L[f+97560>>3];x(0,j|0);x(1,d|0);m=h*(+z()-e);a=a+m;n=C+a;e=y+n;o=o*a;h=a*o;n=y+(n-e)+(m*(l+o)+(B*L[12185]+L[f+97568>>3]+(a+(C-n))))+a*h*(h*(h*(a*L[12192]+L[12191])+(a*L[12190]+L[12189]))+(a*L[12188]+L[12187]));h=e+n;A(+h);c=v(1)|0;x(0,v(0)&-134217728);x(1,c|0);l=+z();a=w*l;A(+a);c=v(1)|0;v(0)|0;c:{k=c>>>20&2047;if(k-969>>>0<63){break c}if(k>>>0<=968){a=a+1;e=r?-a:a;break a}d=k>>>0<1033;k=0;if(d){break c}if((c|0)<0){c=Fa-16|0;L[c+8>>3]=r?-12882297539194267e-247:12882297539194267e-247;e=L[c+8>>3]*12882297539194267e-247;break a}c=Fa-16|0;L[c+8>>3]=r?-3105036184601418e216:3105036184601418e216;e=L[c+8>>3]*3105036184601418e216;break a}m=(b-w)*l+(n+(e-h)+(h-l))*b;b=L[12706];e=a*L[12705]+b;b=e-b;a=m+(b*L[12708]+(b*L[12707]+a));b=a*a;m=b*b*(a*L[12712]+L[12711]);b=b*(a*L[12710]+L[12709]);A(+e);v(1)|0;j=v(0)|0;c=j<<4&2032;a=m+(b+(L[c+101752>>3]+a));c=c+101760|0;d=G[c>>2];g=G[c+4>>2];c=j+r|0;c=c<<13;f=0;d=f+d|0;c=c+g|0;c=d>>>0>>0?c+1|0:c;g=d;if(!k){d=Fa-16|0;Fa=d;d:{if(!(j&-2147483648)){x(0,g|0);x(1,c-1058013184|0);b=+z();a=(b*a+b)*5486124068793689e288;break d}c=c+1071644672|0;f=c;x(0,g|0);x(1,c|0);b=+z();h=b*a;a=h+b;if(O(a)<1){c=d;G[c+8>>2]=0;G[c+12>>2]=1048576;L[c+8>>3]=L[c+8>>3]*22250738585072014e-324;x(0,0);x(1,f&-2147483648);e=a<0?-1:1;l=a+e;a=l+(h+(b-a)+(a+(e-l)))-e;a=(D=+z(),E=a,F=a==0,F?D:E)}a=a*22250738585072014e-324}e=a;Fa=d+16|0;break a}x(0,g|0);x(1,c|0);b=+z();e=b*a+b}Fa=p+16|0;return e}function Ot(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;a:{while(1){b:{c:{if(J[a+116>>2]<=261){Ri(a);c=G[a+116>>2];if(!(c>>>0>=262|b)){return 0}if(!c){break a}if(c>>>0<3){break c}}e=G[a+108>>2];c=G[a+84>>2]&(H[(e+G[a+56>>2]|0)+2|0]^G[a+72>>2]<>2]);G[a+72>>2]=c;c=G[a+68>>2]+(c<<1)|0;d=I[c>>1];F[G[a+64>>2]+((e&G[a+52>>2])<<1)>>1]=d;F[c>>1]=e;if(!d|G[a+44>>2]-262>>>0>>0){break c}d=ip(a,d);G[a+96>>2]=d;break b}d=G[a+96>>2]}d:{if(d>>>0>=3){c=G[a+5792>>2];e=G[a+108>>2]-G[a+112>>2]|0;F[G[a+5796>>2]+(c<<1)>>1]=e;G[a+5792>>2]=c+1;i=c+G[a+5784>>2]|0;c=d-3|0;E[i|0]=c;c=((H[(c&255)+116208|0]<<2)+a|0)+1176|0;F[c>>1]=I[c>>1]+1;c=e-1&65535;c=((H[(c>>>0<256?c:(c>>>7|0)+256|0)+115696|0]<<2)+a|0)+2440|0;F[c>>1]=I[c>>1]+1;d=G[a+96>>2];c=G[a+116>>2]-d|0;G[a+116>>2]=c;j=G[a+5788>>2]-1|0;k=G[a+5792>>2];if(!(c>>>0<3|d>>>0>J[a+128>>2])){g=d-1|0;G[a+96>>2]=g;h=G[a+72>>2];d=G[a+108>>2];l=G[a+52>>2];m=G[a+64>>2];n=G[a+68>>2];o=G[a+84>>2];i=G[a+56>>2];f=G[a+88>>2];while(1){c=d;d=c+1|0;G[a+108>>2]=d;h=(H[(c+i|0)+3|0]^h<>2]=h;e=(h<<1)+n|0;F[((d&l)<<1)+m>>1]=I[e>>1];F[e>>1]=d;g=g-1|0;G[a+96>>2]=g;if(g){continue}break}d=c+2|0;G[a+108>>2]=d;if((j|0)!=(k|0)){continue}break d}G[a+96>>2]=0;d=d+G[a+108>>2]|0;G[a+108>>2]=d;e=G[a+56>>2]+d|0;c=H[e|0];G[a+72>>2]=c;G[a+72>>2]=G[a+84>>2]&(H[e+1|0]^c<>2]);if((j|0)!=(k|0)){continue}break d}d=H[G[a+56>>2]+G[a+108>>2]|0];c=G[a+5792>>2];F[G[a+5796>>2]+(c<<1)>>1]=0;G[a+5792>>2]=c+1;E[c+G[a+5784>>2]|0]=d;c=(d<<2)+a|0;F[c+148>>1]=I[c+148>>1]+1;G[a+116>>2]=G[a+116>>2]-1;d=G[a+108>>2]+1|0;G[a+108>>2]=d;if(G[a+5792>>2]!=(G[a+5788>>2]-1|0)){continue}}e=G[a+92>>2];if((e|0)>=0){c=e+G[a+56>>2]|0}else{c=0}ge(a,c,d-e|0,0);G[a+92>>2]=G[a+108>>2];f=G[a>>2];e=G[f+28>>2];cd(e);d=G[e+20>>2];c=G[f+16>>2];d=c>>>0>d>>>0?d:c;e:{if(!d){break e}bb(G[f+12>>2],G[e+16>>2],d);G[f+12>>2]=d+G[f+12>>2];G[e+16>>2]=d+G[e+16>>2];G[f+20>>2]=d+G[f+20>>2];G[f+16>>2]=G[f+16>>2]-d;c=G[e+20>>2];G[e+20>>2]=c-d;if((c|0)!=(d|0)){break e}G[e+16>>2]=G[e+8>>2]}if(G[G[a>>2]+16>>2]){continue}break}return 0}d=G[a+108>>2];G[a+5812>>2]=d>>>0<2?d:2;if((b|0)==4){c=G[a+92>>2];if((c|0)>=0){b=c+G[a+56>>2]|0}else{b=0}ge(a,b,d-c|0,1);G[a+92>>2]=G[a+108>>2];e=G[a>>2];d=G[e+28>>2];cd(d);c=G[d+20>>2];b=G[e+16>>2];c=b>>>0>c>>>0?c:b;f:{if(!c){break f}bb(G[e+12>>2],G[d+16>>2],c);G[e+12>>2]=c+G[e+12>>2];G[d+16>>2]=c+G[d+16>>2];G[e+20>>2]=c+G[e+20>>2];G[e+16>>2]=G[e+16>>2]-c;b=G[d+20>>2];G[d+20>>2]=b-c;if((b|0)!=(c|0)){break f}G[d+16>>2]=G[d+8>>2]}return(G[G[a>>2]+16>>2]?3:2)|0}g:{if(!G[a+5792>>2]){break g}c=G[a+92>>2];if((c|0)>=0){b=c+G[a+56>>2]|0}else{b=0}ge(a,b,d-c|0,0);G[a+92>>2]=G[a+108>>2];e=G[a>>2];d=G[e+28>>2];cd(d);c=G[d+20>>2];b=G[e+16>>2];c=b>>>0>c>>>0?c:b;h:{if(!c){break h}bb(G[e+12>>2],G[d+16>>2],c);G[e+12>>2]=c+G[e+12>>2];G[d+16>>2]=c+G[d+16>>2];G[e+20>>2]=c+G[e+20>>2];G[e+16>>2]=G[e+16>>2]-c;b=G[d+20>>2];G[d+20>>2]=b-c;if((b|0)!=(c|0)){break h}G[d+16>>2]=G[d+8>>2]}if(G[G[a>>2]+16>>2]){break g}return 0}return 1}function Wa(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;a:{if(!a){break a}d=a-8|0;b=G[a-4>>2];a=b&-8;f=d+a|0;b:{if(b&1){break b}if(!(b&3)){break a}b=G[d>>2];d=d-b|0;if(d>>>0>>0<=255){e=G[d+8>>2];b=b>>>3|0;c=G[d+12>>2];if((c|0)==(e|0)){i=194500,j=G[48625]&Eu(-2,b),G[i>>2]=j;break b}G[e+12>>2]=c;G[c+8>>2]=e;break b}h=G[d+24>>2];b=G[d+12>>2];c:{if((d|0)!=(b|0)){c=G[d+8>>2];G[c+12>>2]=b;G[b+8>>2]=c;break c}d:{e=d+20|0;c=G[e>>2];if(c){break d}e=d+16|0;c=G[e>>2];if(c){break d}b=0;break c}while(1){g=e;b=c;e=b+20|0;c=G[e>>2];if(c){continue}e=b+16|0;c=G[b+16>>2];if(c){continue}break}G[g>>2]=0}if(!h){break b}e=G[d+28>>2];c=(e<<2)+194804|0;e:{if(G[c>>2]==(d|0)){G[c>>2]=b;if(b){break e}i=194504,j=G[48626]&Eu(-2,e),G[i>>2]=j;break b}G[h+(G[h+16>>2]==(d|0)?16:20)>>2]=b;if(!b){break b}}G[b+24>>2]=h;c=G[d+16>>2];if(c){G[b+16>>2]=c;G[c+24>>2]=b}c=G[d+20>>2];if(!c){break b}G[b+20>>2]=c;G[c+24>>2]=b;break b}b=G[f+4>>2];if((b&3)!=3){break b}G[48627]=a;G[f+4>>2]=b&-2;G[d+4>>2]=a|1;G[a+d>>2]=a;return}if(d>>>0>=f>>>0){break a}b=G[f+4>>2];if(!(b&1)){break a}f:{if(!(b&2)){if(G[48631]==(f|0)){G[48631]=d;a=G[48628]+a|0;G[48628]=a;G[d+4>>2]=a|1;if(G[48630]!=(d|0)){break a}G[48627]=0;G[48630]=0;return}if(G[48630]==(f|0)){G[48630]=d;a=G[48627]+a|0;G[48627]=a;G[d+4>>2]=a|1;G[a+d>>2]=a;return}a=(b&-8)+a|0;g:{if(b>>>0<=255){e=G[f+8>>2];b=b>>>3|0;c=G[f+12>>2];if((c|0)==(e|0)){i=194500,j=G[48625]&Eu(-2,b),G[i>>2]=j;break g}G[e+12>>2]=c;G[c+8>>2]=e;break g}h=G[f+24>>2];b=G[f+12>>2];h:{if((f|0)!=(b|0)){c=G[f+8>>2];G[c+12>>2]=b;G[b+8>>2]=c;break h}i:{e=f+20|0;c=G[e>>2];if(c){break i}e=f+16|0;c=G[e>>2];if(c){break i}b=0;break h}while(1){g=e;b=c;e=b+20|0;c=G[e>>2];if(c){continue}e=b+16|0;c=G[b+16>>2];if(c){continue}break}G[g>>2]=0}if(!h){break g}e=G[f+28>>2];c=(e<<2)+194804|0;j:{if(G[c>>2]==(f|0)){G[c>>2]=b;if(b){break j}i=194504,j=G[48626]&Eu(-2,e),G[i>>2]=j;break g}G[h+(G[h+16>>2]==(f|0)?16:20)>>2]=b;if(!b){break g}}G[b+24>>2]=h;c=G[f+16>>2];if(c){G[b+16>>2]=c;G[c+24>>2]=b}c=G[f+20>>2];if(!c){break g}G[b+20>>2]=c;G[c+24>>2]=b}G[d+4>>2]=a|1;G[a+d>>2]=a;if(G[48630]!=(d|0)){break f}G[48627]=a;return}G[f+4>>2]=b&-2;G[d+4>>2]=a|1;G[a+d>>2]=a}if(a>>>0<=255){b=(a&-8)+194540|0;c=G[48625];a=1<<(a>>>3);k:{if(!(c&a)){G[48625]=a|c;a=b;break k}a=G[b+8>>2]}G[b+8>>2]=d;G[a+12>>2]=d;G[d+12>>2]=b;G[d+8>>2]=a;return}e=31;if(a>>>0<=16777215){b=a>>>8|0;g=b+1048320>>>16&8;b=b<>>16&4;b=b<>>16&2;b=(b<>>15|0)-(c|(e|g))|0;e=(b<<1|a>>>b+21&1)+28|0}G[d+28>>2]=e;G[d+16>>2]=0;G[d+20>>2]=0;g=(e<<2)+194804|0;l:{m:{c=G[48626];b=1<>2]=d;G[d+24>>2]=g;break n}e=a<<((e|0)==31?0:25-(e>>>1|0)|0);b=G[g>>2];while(1){c=b;if((G[b+4>>2]&-8)==(a|0)){break m}b=e>>>29|0;e=e<<1;g=c+(b&4)|0;b=G[g+16>>2];if(b){continue}break}G[g+16>>2]=d;G[d+24>>2]=c}G[d+12>>2]=d;G[d+8>>2]=d;break l}a=G[c+8>>2];G[a+12>>2]=d;G[c+8>>2]=d;G[d+24>>2]=0;G[d+12>>2]=c;G[d+8>>2]=a}a=G[48633]-1|0;G[48633]=a?a:-1}}function is(a,b,c,d,e,f,g,h,i,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;s=Fa-16|0;Fa=s;G[s+12>>2]=j;a:{m=G[a+8>>2];q=G[a>>2]+M(c,3)|0;r=q-2|0;o=M(r,168);e=m+o|0;j=G[e+32>>2];if(j){break a}l=lb(1e3,8);G[e+32>>2]=l;j=0;G[e+28>>2]=0;k=1e3;while(1){if((j|0)>=(k|0)){k=k+1e3|0;e=ub(l,k<<3);m=G[a+8>>2];G[(o+m|0)+32>>2]=e}e=G[s+12>>2]+7&-8;G[s+12>>2]=e+8;p=m+o|0;l=G[p+32>>2];j=G[p+28>>2];h=L[e>>3];L[l+(j<<3)>>3]=h;b:{if(!(O(h+-9007199254740992)<=1e-15)){break b}e=j-1|0;if(!(O(L[(e<<3)+l>>3]+-9007199254740992)<=1e-15)){break b}G[p+28>>2]=e;p=M(r,168);e=p+G[a+8>>2]|0;j=ub(G[e+32>>2],G[e+28>>2]<<3);m=G[a+8>>2];G[(p+m|0)+32>>2]=j;break a}j=j+1|0;G[p+28>>2]=j;continue}}t=G[(m+o|0)+28>>2];l=t-1|0;c:{if((l|0)==2){d:{if(L[j>>3]==0&L[j+8>>3]==0){break d}h=L[(M(c,168)+m|0)+8>>3];if(d){if(g>3]=h)|!(L[(M(c,168)+m|0)+16>>3]>=g)){break d}l=0;e=G[(M(c,168)+m|0)+24>>2];if(O(g)<2147483648){c=~~g}else{c=-2147483648}j=G[e+(c<<2)>>2];e:{if(!j){break e}while(1){if(!(+G[j+4>>2]<=f)){break e}l=l+1|0;j=G[j>>2];if(j){continue}break}}if((l&1)!=(d|0)){break c}if(!b){n=1;break c}if(!d){n=1;break c}G[a+12>>2]=b;n=1;break c}n=!d;break c}e=(t<<3)+j|0;e=L[e-24>>3]==0&L[e-16>>3]==0;if(d){if(e){break c}e=M(r,168)+m|0;i=L[e+8>>3];if(i>g){break c}h=L[e+16>>3];if(!(g>=i)|h>2];if(O(g)<2147483648){p=~~g}else{p=-2147483648}k=G[o+(p<<2)>>2];f:{if(!k){break f}while(1){if(!(+G[k+4>>2]<=f)){break f}e=e+1|0;k=G[k>>2];if(k){continue}break}}if((e&1)!=(d|0)){break c}g:{h:{if(L[j>>3]==0&L[j+8>>3]==0){break h}o=q-1|0;e=M(o,168)+m|0;i=L[e+8>>3];if(i>g){break h}h=L[e+16>>3];if(!(g>=i)|h>2]+(p<<2)>>2];i:{if(!k){break i}while(1){if(!(+G[k+4>>2]<=f)){break i}e=e+1|0;k=G[k>>2];if(k){continue}break}}if((e&1)==(d|0)){break c}if((t|0)>3){break g}break c}if((t|0)<4){break c}}l=((l|0)>4?l:4)-3>>>1|0;e=0;k=2;while(1){o=e;j:{e=k<<3;if(L[e+j>>3]==0&L[(e|8)+j>>3]==0){break j}q=M(c+o|0,168)+m|0;i=L[q+8>>3];if(i>g){break j}h=L[q+16>>3];if(!(g>=i)|h>2]+(p<<2)>>2];k:{if(!n){break k}while(1){if(!(+G[n+4>>2]<=f)){break k}e=e+1|0;n=G[n>>2];if(n){continue}break}}if((e&1)!=(d|0)){break j}n=1;b=b+o|0;if(!b){break c}G[a+12>>2]=b;break c}e=o+1|0;k=k+2|0;n=0;if((l|0)!=(o|0)){continue}break}break c}n=1;if(e){break c}a=M(r,168)+m|0;i=L[a+8>>3];if(i>g){break c}h=L[a+16>>3];if(!(g>=i)|(!(h>=g)|g>h)){break c}b=G[(M(r,168)+m|0)+24>>2];if(O(g)<2147483648){a=~~g}else{a=-2147483648}l=G[b+(a<<2)>>2];if(!l){break c}k=0;while(1){if(+G[l+4>>2]<=f){k=k+1|0;l=G[l>>2];if(l){continue}}break}if(!(k&1)){break c}n=0;if(L[j>>3]==0&L[j+8>>3]==0){break c}c=q-1|0;b=M(c,168)+m|0;i=L[b+8>>3];if(i>g){break c}h=L[b+16>>3];if(!(g>=i)|(!(h>=g)|g>h)){break c}j=G[G[(M(c,168)+m|0)+24>>2]+(a<<2)>>2];if(!j){break c}while(1){if(+G[j+4>>2]<=f){n=n+1|0;j=G[j>>2];if(j){continue}}break}n=n&1}Fa=s+16|0;return n|0}function hk(a,b,c,d,e,f,g,h){var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;i=Fa-10448|0;Fa=i;G[i+9380>>2]=0;G[i+9368>>2]=0;G[i+9364>>2]=0;E[i+15|0]=0;k=G[h>>2];a:{if(k){break a}G[g>>2]=0;G[i+8>>2]=i+7296;G[i+4>>2]=i+8336;b:{if(!f){E[i+6256|0]=0;break b}if(!H[f|0]){E[i+6256|0]=0;break b}if(!ad(f)){bf(f,1025,i+6256|0,h);if(H[i+6256|0]==47){break b}k=i+16|0;cf(k,h);if((Va(k)+Va(i+6256|0)|0)-1024>>>0<=4294966270){Ua(59913);k=125;G[h>>2]=125;break a}k=i+16|0;j=Va(k)+k|0;E[j|0]=47;E[j+1|0]=0;j=k;k=i+6256|0;_d(Gb(j,k),k,h);break b}Za(i+6256|0,f)}q=h,r=jk(a,i+9404|0,i+9400|0,i+9396|0,i+9392|0,i+9388|0,i+9384|0,i+9376|0,h),G[q>>2]=r;q=h,r=ik(a,i+9368|0,h),G[q>>2]=r;c:{if(G[i+9368>>2]>0){p=G[i+9376>>2]-2|0;l=1;j=0;while(1){if(G[g>>2]|G[h>>2]){break c}n=l;k=j;j=G[i+9404>>2];d:{if(j){Df(a,j,n,k,i+15|0,i+4|0,i+9372|0,h);if(Ib(G[i+4>>2],b)){break d}}j=G[i+9400>>2];if(j){Df(a,j,n,k,i+15|0,i+4|0,i+9372|0,h);if(Ib(G[i+4>>2],c)){break d}}j=G[i+9396>>2];if(j){Zk(a,j,n,k,i+9364|0,i+9372|0,h);if(G[i+9364>>2]!=(d|0)){break d}}j=G[i+9392>>2];e:{if(!j){break e}f:{switch(p|0){case 0:case 10:break f;default:break e}}Up(a,j,n,k,i+9380|0,i+9372|0,h);if(G[i+9380>>2]!=(e|0)){break d}}g:{h:{i:{if(!f){Ua(59767);break i}j:{k:{j=G[i+9388>>2];l:{if(!j){E[i+5216|0]=0;break l}Df(a,j,n,k,i+15|0,i+4|0,i+9372|0,h);j=Za(i+5216|0,G[i+4>>2]);E[i+4176|0]=0;l=H[j|0];if(l){break k}}j=yf(a,i+5216|0,i+4176|0,0,0,0,h);G[h>>2]=j;l=H[i+5216|0];m:{if(!l){break m}if(ad(i+5216|0)|(l|0)==47){break m}n:{if(j){break n}if(!ui(i+9408|0,1025)){E[i+16|0]=0;Ua(61910);G[h>>2]=125;break n}bf(i+9408|0,1025,i+16|0,h)}if((Va(i+16|0)+Va(i+5216|0)|0)-1024>>>0<=4294966270){break g}j=i+16|0;l=Va(j)+j|0;E[l|0]=47;E[l+1|0]=0;o=j;j=i+5216|0;_d(Gb(o,j),j,h)}j=H[i+4176|0];if(!j){break j}if(ad(i+4176|0)|(j|0)==47){break j}j=i+16|0;cf(j,h);if((Va(j)+Va(i+4176|0)|0)-1024>>>0<=4294966270){break g}j=i+16|0;l=Va(j)+j|0;E[l|0]=47;E[l+1|0]=0;o=j;j=i+4176|0;_d(Gb(o,j),j,h);break j}if(ad(j)|(l|0)==47){break j}l=Za(i+4176|0,j);q=h,r=yf(a,i+2096|0,i+1056|0,0,0,0,h),G[q>>2]=r;m=H[i+2096|0];o:{if(m){if(!(ad(i+2096|0)|(m|0)==47)){m=i+16|0;cf(m,h);if((Va(m)+Va(i+2096|0)|0)-1024>>>0<=4294966270){break h}m=i+16|0;o=Va(m)+m|0;E[o|0]=47;E[o+1|0]=0;o=m;m=i+2096|0;_d(Gb(o,m),m,h)}Dg(i+2096|0,j,i+3136|0,h);m=G[h>>2];if((m|0)!=125){if(m){break o}Za(j,i+3136|0);break o}G[h>>2]=0}E[j|0]=0}j=H[i+1056|0];if(j){if(!(ad(i+1056|0)|(j|0)==47)){j=i+16|0;cf(j,h);if((Va(j)+Va(i+1056|0)|0)-1024>>>0<=4294966270){break h}j=i+16|0;m=Va(j)+j|0;E[m|0]=47;E[m+1|0]=0;o=j;j=i+1056|0;_d(Gb(o,j),j,h)}Dg(i+1056|0,l,i+3136|0,h);j=G[h>>2];if((j|0)!=125){if(j){break j}Za(l,i+3136|0);break j}G[h>>2]=0}E[l|0]=0}if(!Xa(i+5216|0,i+6256|0)){break i}if(Xa(i+4176|0,i+6256|0)){break d}}G[g>>2]=n;break d}Ua(59868);G[h>>2]=125;break d}Ua(59822);G[h>>2]=125}j=k;l=n+1|0;j=l?j:j+1|0;o=n;n=G[i+9368>>2];o=o>>>0>>0;n=n>>31;if(o&(n|0)>=(k|0)|(k|0)<(n|0)){continue}break}}if(G[g>>2]|G[h>>2]){break c}G[h>>2]=342;Ua(59951)}k=G[h>>2]}Fa=i+10448|0;return k}function xo(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;h=f&31;if((f&63)>>>0>=32){k=1<>>32-h}l=f;if((b|0)>=2){r=b-1|0;p=c&-2;s=c-1|0;t=(c-2>>>1|0)+1|0;u=(c|0)<2;while(1){f=M(e,o);h=m;n=0;if(u){h=0}else{while(1){g=f;a:{b:{c:{d:{switch(H[a+h|0]-1|0){case 0:g=(e+f|0)+1|0;break b;case 1:g=e+f|0;break b;case 2:g=e+f|0;i=(g<<3)+d|0;j=G[i+8>>2];q=i+8|0;i=k|G[i+12>>2];G[q>>2]=j|l;G[q+4>>2]=i;break b;case 3:g=f|1;break b;case 4:g=(e+f<<3)+d|0;i=G[g+8>>2];j=g+8|0;g=k|G[g+12>>2];G[j>>2]=i|l;G[j+4>>2]=g;g=f|1;break b;case 5:g=(e+f<<3)+d|0;i=G[g>>2];j=k|G[g+4>>2];G[g>>2]=i|l;G[g+4>>2]=j;g=f|1;break b;case 6:g=(e+f<<3)+d|0;i=G[g>>2];j=k|G[g+4>>2];G[g>>2]=i|l;G[g+4>>2]=j;i=k|G[g+12>>2];G[g+8>>2]=l|G[g+8>>2];G[g+12>>2]=i;g=f|1;break b;case 8:g=(e+f<<3)+d|0;i=G[g+8>>2];j=g+8|0;g=k|G[g+12>>2];G[j>>2]=i|l;G[j+4>>2]=g;break c;case 9:g=(e+f<<3)+d|0;i=G[g>>2];j=k|G[g+4>>2];G[g>>2]=i|l;G[g+4>>2]=j;break c;case 10:g=(e+f<<3)+d|0;i=G[g>>2];j=k|G[g+4>>2];G[g>>2]=i|l;G[g+4>>2]=j;i=k|G[g+12>>2];G[g+8>>2]=l|G[g+8>>2];G[g+12>>2]=i;break c;case 11:g=(f<<3|8)+d|0;i=G[g>>2];j=k|G[g+4>>2];G[g>>2]=i|l;G[g+4>>2]=j;break c;case 12:g=(e+f<<3)+d|0;i=G[g+8>>2];j=g+8|0;g=k|G[g+12>>2];G[j>>2]=i|l;G[j+4>>2]=g;g=(f<<3|8)+d|0;i=G[g>>2];j=k|G[g+4>>2];G[g>>2]=i|l;G[g+4>>2]=j;break c;case 13:g=(e+f<<3)+d|0;i=G[g>>2];j=k|G[g+4>>2];G[g>>2]=i|l;G[g+4>>2]=j;g=(f<<3|8)+d|0;i=G[g>>2];j=k|G[g+4>>2];G[g>>2]=i|l;G[g+4>>2]=j;break c;case 7:break b;case 14:break d;default:break a}}g=(e+f<<3)+d|0;i=G[g>>2];j=k|G[g+4>>2];G[g>>2]=i|l;G[g+4>>2]=j;i=k|G[g+12>>2];G[g+8>>2]=l|G[g+8>>2];G[g+12>>2]=i;g=(f<<3|8)+d|0;i=G[g>>2];j=k|G[g+4>>2];G[g>>2]=i|l;G[g+4>>2]=j}g=f}g=(g<<3)+d|0;i=G[g>>2];j=k|G[g+4>>2];G[g>>2]=i|l;G[g+4>>2]=j}h=h+1|0;f=f+2|0;n=n+2|0;if((s|0)>(n|0)){continue}break}m=m+t|0;h=p}if((h|0)<(c|0)){e:{f:{g:{switch(H[a+m|0]-2|0){case 0:case 1:case 4:case 5:f=e+f|0;break f;case 8:h=(e+f<<3)+d|0;g=G[h>>2];n=k|G[h+4>>2];G[h>>2]=g|l;G[h+4>>2]=n;break f;case 9:h=(e+f<<3)+d|0;g=G[h>>2];n=k|G[h+4>>2];G[h>>2]=g|l;G[h+4>>2]=n;break f;case 12:h=(e+f<<3)+d|0;g=G[h>>2];n=k|G[h+4>>2];G[h>>2]=g|l;G[h+4>>2]=n;break f;case 6:case 7:case 10:case 11:break f;case 13:break g;default:break e}}h=(e+f<<3)+d|0;g=G[h>>2];n=k|G[h+4>>2];G[h>>2]=g|l;G[h+4>>2]=n}f=(f<<3)+d|0;h=G[f>>2];g=k|G[f+4>>2];G[f>>2]=h|l;G[f+4>>2]=g}m=m+1|0}o=o+2|0;if((r|0)>(o|0)){continue}break}}h:{if((b|0)<=(o|0)){break h}f=M(e,o);if((c|0)>=2){e=c-1|0;p=(c-2>>>1|0)+m|0;g=0;while(1){h=f;i:{j:{k:{switch(H[a+m|0]-4|0){case 0:case 1:case 2:case 3:h=f|1;break j;case 4:case 5:case 6:case 7:break j;case 8:case 9:case 10:case 11:break k;default:break i}}b=(f<<3|8)+d|0;h=G[b>>2];o=k|G[b+4>>2];G[b>>2]=h|l;G[b+4>>2]=o;h=f}b=(h<<3)+d|0;h=G[b>>2];o=k|G[b+4>>2];G[b>>2]=h|l;G[b+4>>2]=o}m=m+1|0;f=f+2|0;g=g+2|0;if((e|0)>(g|0)){continue}break}m=p+1|0;b=c&-2}else{b=0}if((b|0)>=(c|0)|(H[a+m|0]&248)!=8){break h}a=(f<<3)+d|0;b=G[a>>2];c=k|G[a+4>>2];G[a>>2]=b|l;G[a+4>>2]=c}}function Zc(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;j=Fa-112|0;Fa=j;k=i&2147483647;l=e&2147483647;m=l;a:{b:{p=!(b|c);if(!(d|l?l-2147418112>>>0<2147549184:p)){n=k-2147418112|0;if(!h&(n|0)==-2147418112?f|g:(n|0)==-2147418112&(h|0)!=0|n>>>0>2147549184){break b}}if(!(!d&(m|0)==2147418112?p:m>>>0<2147418112)){h=d;i=e|32768;f=b;g=c;break a}if(!(!h&(k|0)==2147418112?!(f|g):k>>>0<2147418112)){i=i|32768;break a}if(!(b|d|(m^2147418112|c))){m=d;d=!(b^f|d^h|(c^g|e^i^-2147483648));h=d?0:m;i=d?2147450880:e;f=d?0:b;g=d?0:c;break a}if(!(f|h|(k^2147418112|g))){break a}if(!(b|d|(c|m))){if(f|h|(g|k)){break a}f=b&f;g=c&g;h=d&h;i=e&i;break a}if(f|h|(g|k)){break b}f=b;g=c;h=d;i=e;break a}l=(k|0)==(m|0);k=l&(d|0)==(h|0)?(c|0)==(g|0)&b>>>0>>0|c>>>0>>0:l&d>>>0>>0|k>>>0>m>>>0;o=k?f:b;l=k?g:c;m=k?i:e;r=m;q=k?h:d;n=m&65535;e=k?e:i;s=e;h=k?d:h;m=e>>>16&32767;p=r>>>16&32767;if(!p){d=!(n|q);e=d<<6;i=P(d?o:q)+32|0;d=P(d?l:n);d=e+((d|0)==32?i:d)|0;od(j+96|0,o,l,q,n,d-15|0);q=G[j+104>>2];n=G[j+108>>2];o=G[j+96>>2];p=16-d|0;l=G[j+100>>2]}f=k?b:f;g=k?c:g;i=s&65535;if(!m){b=!(h|i);c=b<<6;d=P(b?f:h)+32|0;b=P(b?g:i);b=c+((b|0)==32?d:b)|0;od(j+80|0,f,g,h,i,b-15|0);m=16-b|0;h=G[j+88>>2];i=G[j+92>>2];g=G[j+84>>2];f=G[j+80>>2]}b=h;k=i<<3|b>>>29;d=b<<3|g>>>29;e=k|524288;b=q;c=n<<3|b>>>29;h=b<<3|l>>>29;i=c;b=f;c=g<<3|b>>>29;b=b<<3;g=r^s;c:{if((m|0)==(p|0)){break c}f=p-m|0;if(f>>>0>127){d=0;e=0;b=1;c=0;break c}od(j- -64|0,b,c,d,e,128-f|0);eg(j+48|0,b,c,d,e,f);b=G[j+48>>2]|(G[j+64>>2]|G[j+72>>2]|(G[j+68>>2]|G[j+76>>2]))!=0;c=G[j+52>>2];d=G[j+56>>2];e=G[j+60>>2]}m=h;q=i|524288;f=o;k=l<<3|f>>>29;n=f<<3;d:{if((g|0)<0){f=0;g=0;h=0;i=0;if(!(b^n|d^m|(c^k|e^q))){break a}o=n-b|0;l=k-((b>>>0>n>>>0)+c|0)|0;f=m-d|0;b=(c|0)==(k|0)&b>>>0>n>>>0|c>>>0>k>>>0;i=(q-((d>>>0>m>>>0)+e|0)|0)-(f>>>0>>0)|0;h=f-b|0;if(i>>>0>524287){break d}b=!(h|i);c=b<<6;d=P(b?o:h)+32|0;b=P(b?l:i);b=c+((b|0)==32?d:b)|0;b=b-12|0;od(j+32|0,o,l,h,i,b);p=p-b|0;h=G[j+40>>2];i=G[j+44>>2];o=G[j+32>>2];l=G[j+36>>2];break d}k=c+k|0;f=b+n|0;k=f>>>0>>0?k+1|0:k;o=f;l=k;f=(c|0)==(k|0)&b>>>0>f>>>0|c>>>0>k>>>0;c=e+q|0;b=d+m|0;c=b>>>0>>0?c+1|0:c;d=b;b=f+b|0;h=b;i=b>>>0>>0?c+1|0:c;if(!(i&1048576)){break d}o=o&1|((l&1)<<31|o>>>1);c=h;l=c<<31|l>>>1;p=p+1|0;h=(i&1)<<31|c>>>1;i=i>>>1|0}d=0;e=r&-2147483648;if((p|0)>=32767){h=d;i=e|2147418112;f=0;g=0;break a}m=0;e:{if((p|0)>0){m=p;break e}od(j+16|0,o,l,h,i,p+127|0);eg(j,o,l,h,i,1-p|0);o=G[j>>2]|(G[j+16>>2]|G[j+24>>2]|(G[j+20>>2]|G[j+28>>2]))!=0;l=G[j+4>>2];h=G[j+8>>2];i=G[j+12>>2]}c=h<<29;b=l>>>3|0;n=(l&7)<<29|o>>>3;l=o&7;g=l>>>0>4;f=n+g|0;b=b|c;k=f>>>0>>0?b+1|0:b;c=f;g=k;b=(b|0)==(k|0)&c>>>0>>0|b>>>0>k>>>0;c=d|((i&7)<<29|h>>>3);b=b+c|0;i=e|(i>>>3&65535|m<<16);i=b>>>0>>0?i+1|0:i;h=b;f:{if((l|0)==4){c=g+0|0;e=f&1;b=f+e|0;c=b>>>0>>0?c+1|0:c;f=b;g=c;c=(d|0)==(c|0)&b>>>0>>0|c>>>0>>0;b=c+h|0;i=b>>>0>>0?i+1|0:i;h=b;break f}if(!l){break a}}}G[a>>2]=f;G[a+4>>2]=g;G[a+8>>2]=h;G[a+12>>2]=i;Fa=j+112|0}function Zp(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=N(0),q=0,r=0,s=0,t=0;a:{b:{if(!e){if(c==1&d==0){break b}if((b|0)<=0){break a}while(1){g=(q<<3)+j|0;c:{d:{o=+K[(q<<2)+a>>2]*c+d;if(o<-0x8000000000000000){G[k>>2]=-11;break d}if(o>0x8000000000000000){G[k>>2]=-11;f=2147483647;e=-1;break c}if(!(O(o)<0x8000000000000000)){break d}f=O(o)>=1?~~(o>0?Q(S(o*2.3283064365386963e-10),4294967295):T((o-+(~~o>>>0>>>0))*2.3283064365386963e-10))>>>0:0;e=~~o>>>0;break c}f=-2147483648;e=0}G[g>>2]=e;G[g+4>>2]=f;q=q+1|0;if((q|0)!=(b|0)){continue}break}break a}q=a+2|0;e:{f:{if(!(c==1&d==0)){if((b|0)<=0){break a}if(!(O(d)<0x8000000000000000)){break f}r=O(d)>=1?~~(d>0?Q(S(d*2.3283064365386963e-10),4294967295):T((d-+(~~d>>>0>>>0))*2.3283064365386963e-10))>>>0:0;n=~~d>>>0;break e}if((b|0)<=0){break a}while(1){g:{h:{i:{j:{n=I[q>>1]&32640;switch(((n|0)==32640?1:!n<<1)|0){case 0:break h;case 1:break j;default:break i}}G[i>>2]=1;if((e|0)==1){n=(m<<3)+j|0;G[n>>2]=f;G[n+4>>2]=g;break g}E[h+m|0]=1;break g}n=(m<<3)+j|0;G[n>>2]=0;G[n+4>>2]=0;break g}p=K[(m<<2)+a>>2];if(p>2]=-11;n=(m<<3)+j|0;G[n>>2]=0;G[n+4>>2]=-2147483648;break g}if(p>N(0x8000000000000000)){G[k>>2]=-11;n=(m<<3)+j|0;G[n>>2]=-1;G[n+4>>2]=2147483647;break g}n=(m<<3)+j|0;k:{if(N(O(p))=N(1)?~~(p>N(0)?N(Q(N(S(N(p*N(2.3283064365386963e-10)))),N(4294967296))):N(T(N(N(p-N(~~p>>>0>>>0))*N(2.3283064365386963e-10)))))>>>0:0;r=~~p>>>0;break k}l=-2147483648;r=0}G[n>>2]=r;G[n+4>>2]=l}q=q+4|0;m=m+1|0;if((m|0)!=(b|0)){continue}break}break a}r=-2147483648;n=0}while(1){l:{m:{n:{o:{l=I[q>>1]&32640;switch(((l|0)==32640?1:!l<<1)|0){case 0:break m;case 1:break o;default:break n}}G[i>>2]=1;if((e|0)==1){l=(m<<3)+j|0;G[l>>2]=f;G[l+4>>2]=g;break l}E[h+m|0]=1;break l}if(d<-0x8000000000000000){G[k>>2]=-11;l=(m<<3)+j|0;G[l>>2]=0;G[l+4>>2]=-2147483648;break l}if(d>0x8000000000000000){G[k>>2]=-11;l=(m<<3)+j|0;G[l>>2]=-1;G[l+4>>2]=2147483647;break l}l=(m<<3)+j|0;G[l>>2]=n;G[l+4>>2]=r;break l}o=+K[(m<<2)+a>>2]*c+d;if(o<-0x8000000000000000){G[k>>2]=-11;l=(m<<3)+j|0;G[l>>2]=0;G[l+4>>2]=-2147483648;break l}if(o>0x8000000000000000){G[k>>2]=-11;l=(m<<3)+j|0;G[l>>2]=-1;G[l+4>>2]=2147483647;break l}l=(m<<3)+j|0;p:{if(O(o)<0x8000000000000000){s=O(o)>=1?~~(o>0?Q(S(o*2.3283064365386963e-10),4294967295):T((o-+(~~o>>>0>>>0))*2.3283064365386963e-10))>>>0:0;t=~~o>>>0;break p}s=-2147483648;t=0}G[l>>2]=t;G[l+4>>2]=s}q=q+4|0;m=m+1|0;if((m|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}while(1){g=(q<<3)+j|0;q:{r:{p=K[(q<<2)+a>>2];if(p>2]=-11;break r}if(p>N(0x8000000000000000)){G[k>>2]=-11;f=2147483647;e=-1;break q}if(!(N(O(p))=N(1)?~~(p>N(0)?N(Q(N(S(N(p*N(2.3283064365386963e-10)))),N(4294967296))):N(T(N(N(p-N(~~p>>>0>>>0))*N(2.3283064365386963e-10)))))>>>0:0;e=~~p>>>0;break q}f=-2147483648;e=0}G[g>>2]=e;G[g+4>>2]=f;q=q+1|0;if((q|0)!=(b|0)){continue}break}}}function Or(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=N(0),g=N(0),h=0,i=N(0),j=0,k=N(0),l=N(0),m=0,n=0,o=0,p=0,q=0;a:{if(G[c+4>>2]==702){h=L[c+120>>3];break a}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=67;E[c+1|0]=83;E[c+2|0]=67;E[c+3|0]=0;E[c+4|0]=190;E[c+5|0]=2;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;h=L[c+24>>3];b:{if(h==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;j=45;h=.022222222222222223;break b}j=h*3.141592653589793*.25;h=1/j}G[c+1892>>2]=103;G[c+1888>>2]=104;L[c+112>>3]=j;L[c+120>>3]=h}k=N(h*b);i=N(h*a);f=N(O(i));c:{d:{if(f<=N(1)){c=2;if(!(N(O(k))>N(3))){break d}break c}c=2;if(f>N(7)|N(O(k))>N(1)){break c}}i=iN(5)){f=N(i+N(-6));break h}if(i>N(3)){f=N(i+N(-4));c=0;m=1;break e}if(i>N(1)){f=N(i+N(-2));c=0;n=1;break f}if(k>N(1)){k=N(k+N(-2));f=i;c=1;break g}if(!(kN(5)){b=h*+N(-f);j=h;h=h*+N(-l);break i}j=h*+N(-l);b=h;h=h*+N(-f)}if(h==0&j==0){a=0}else{a=Ac(j,h)}L[d>>3]=a;p=e,q=Bc(b),L[p>>3]=q;c=0}return c|0}function me(a,b,c){var d=0,e=0,f=0,g=0,h=0;d=Fa-176|0;Fa=d;e=G[c>>2];a:{if((e|0)>0){break a}e=H[201441];if(!e){e=H[G[29798]];E[201441]=e}G[48624]=0;G[b>>2]=0;G[b+4>>2]=0;b:{if(!(!jb(a,68)&(e&255)!=44)){if(Va(a)>>>0>=73){F[d+120>>1]=H[29569]|H[29570]<<8;a=H[29565]|H[29566]<<8|(H[29567]<<16|H[29568]<<24);G[d+112>>2]=H[29561]|H[29562]<<8|(H[29563]<<16|H[29564]<<24);G[d+116>>2]=a;a=H[29557]|H[29558]<<8|(H[29559]<<16|H[29560]<<24);G[d+104>>2]=H[29553]|H[29554]<<8|(H[29555]<<16|H[29556]<<24);G[d+108>>2]=a;a=H[29549]|H[29550]<<8|(H[29551]<<16|H[29552]<<24);G[d+96>>2]=H[29545]|H[29546]<<8|(H[29547]<<16|H[29548]<<24);G[d+100>>2]=a;a=H[29541]|H[29542]<<8|(H[29543]<<16|H[29544]<<24);G[d+88>>2]=H[29537]|H[29538]<<8|(H[29539]<<16|H[29540]<<24);G[d+92>>2]=a;a=H[29533]|H[29534]<<8|(H[29535]<<16|H[29536]<<24);G[d+80>>2]=H[29529]|H[29530]<<8|(H[29531]<<16|H[29532]<<24);G[d+84>>2]=a;tb(5,d+80|0);e=409;G[c>>2]=409;break a}f=Za(d,a);g=jb(f,68);G[d+172>>2]=g;if(g){E[g|0]=69}c:{if((e&255)!=44){break c}e=jb(f,46);G[d+172>>2]=e;if(!e){break c}E[e|0]=44}h=vb(f,d+172|0);break b}h=vb(a,d+172|0)}L[b>>3]=h;if((H[G[d+172>>2]]|32)==32){A(+h);e=v(1)|0;v(0)|0;e=e>>>16|0}else{e=H[67545]|H[67546]<<8|(H[67547]<<16|H[67548]<<24);f=H[67541]|H[67542]<<8|(H[67543]<<16|H[67544]<<24);F[d+118>>1]=f;F[d+120>>1]=f>>>16;F[d+122>>1]=e;F[d+124>>1]=e>>>16;e=H[67539]|H[67540]<<8|(H[67541]<<16|H[67542]<<24);G[d+112>>2]=H[67535]|H[67536]<<8|(H[67537]<<16|H[67538]<<24);G[d+116>>2]=e;e=H[67531]|H[67532]<<8|(H[67533]<<16|H[67534]<<24);G[d+104>>2]=H[67527]|H[67528]<<8|(H[67529]<<16|H[67530]<<24);G[d+108>>2]=e;e=H[67523]|H[67524]<<8|(H[67525]<<16|H[67526]<<24);G[d+96>>2]=H[67519]|H[67520]<<8|(H[67521]<<16|H[67522]<<24);G[d+100>>2]=e;e=H[67515]|H[67516]<<8|(H[67517]<<16|H[67518]<<24);G[d+88>>2]=H[67511]|H[67512]<<8|(H[67513]<<16|H[67514]<<24);G[d+92>>2]=e;e=H[67507]|H[67508]<<8|(H[67509]<<16|H[67510]<<24);G[d+80>>2]=H[67503]|H[67504]<<8|(H[67505]<<16|H[67506]<<24);G[d+84>>2]=e;tb(5,qb(d+80|0,a,30));G[c>>2]=409;e=I[b+6>>1]}if(!(G[48624]!=68&(e&32752)!=32752)){e=H[67545]|H[67546]<<8|(H[67547]<<16|H[67548]<<24);f=H[67541]|H[67542]<<8|(H[67543]<<16|H[67544]<<24);F[d+118>>1]=f;F[d+120>>1]=f>>>16;F[d+122>>1]=e;F[d+124>>1]=e>>>16;e=H[67539]|H[67540]<<8|(H[67541]<<16|H[67542]<<24);G[d+112>>2]=H[67535]|H[67536]<<8|(H[67537]<<16|H[67538]<<24);G[d+116>>2]=e;e=H[67531]|H[67532]<<8|(H[67533]<<16|H[67534]<<24);G[d+104>>2]=H[67527]|H[67528]<<8|(H[67529]<<16|H[67530]<<24);G[d+108>>2]=e;e=H[67523]|H[67524]<<8|(H[67525]<<16|H[67526]<<24);G[d+96>>2]=H[67519]|H[67520]<<8|(H[67521]<<16|H[67522]<<24);G[d+100>>2]=e;e=H[67515]|H[67516]<<8|(H[67517]<<16|H[67518]<<24);G[d+88>>2]=H[67511]|H[67512]<<8|(H[67513]<<16|H[67514]<<24);G[d+92>>2]=e;e=H[67507]|H[67508]<<8|(H[67509]<<16|H[67510]<<24);G[d+80>>2]=H[67503]|H[67504]<<8|(H[67505]<<16|H[67506]<<24);G[d+84>>2]=e;tb(5,qb(d+80|0,a,30));G[b>>2]=0;G[b+4>>2]=0;G[c>>2]=412;G[48624]=0}e=G[c>>2]}Fa=d+176|0;return e}function lu(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;f=Fa-1114160|0;Fa=f;g=ab(40);G[g>>2]=0;G[f+852016>>2]=13193;j=4;i=1;a:{b:{c:{if(!c|!H[c|0]){break c}G[321387]=0;l=aa(158,c|0)|0;c=G[321387];G[321387]=0;d=-1;d:{if(!c){break d}e=G[321388];if(!e){break d}d=Ab(G[c>>2],g,4);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){break b}G[321387]=0;h=pc(l,92039);c=G[321387];G[321387]=0;d=-1;e:{if(!c){break e}e=G[321388];if(!e){break e}d=Ab(G[c>>2],g,4);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){break b}f:{if(!h){break f}d=0;while(1){G[321387]=0;k=rb((f+196656|0)+(d<<16)|0,h,65535);c=G[321387];G[321387]=0;h=-1;g:{if(!c){break g}e=G[321388];if(!e){break g}h=Ab(G[c>>2],g,4);if(!h){break a}_(e|0)}c=Z()|0;if((h|0)==1){break b}G[(f+852016|0)+(i<<2)>>2]=k;G[321387]=0;h=pc(0,92039);c=G[321387];G[321387]=0;k=-1;h:{if(!c){break h}e=G[321388];if(!e){break h}k=Ab(G[c>>2],g,4);if(!k){break a}_(e|0)}c=Z()|0;if((k|0)==1){break b}i=i+1|0;if(!h){break f}c=d>>>0<9;d=d+1|0;if(c){continue}break}}if(!l){break c}Wa(l)}G[(f+852016|0)+(i<<2)>>2]=8722;c=G[968813];G[968813]=c+1;G[321387]=0;G[f+32>>2]=42205;G[f+36>>2]=c;$(156,f+131120|0,65535,4259,f+32|0)|0;c=G[321387];G[321387]=0;d=-1;i:{if(!c){break i}e=G[321388];if(!e){break i}d=Ab(G[c>>2],g,4);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){break b}G[321387]=0;G[f+16>>2]=42205;G[f+20>>2]=a;G[((i<<2)+f|0)+852020>>2]=f+131120;$(156,f+65584|0,65535,8740,f+16|0)|0;c=G[321387];G[321387]=0;d=-1;j:{if(!c){break j}e=G[321388];if(!e){break j}d=Ab(G[c>>2],g,4);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){break b}G[321387]=0;G[f>>2]=42205;G[f+4>>2]=b;G[((i<<2)+f|0)+852024>>2]=f+65584;$(156,f+48|0,65535,8740,f|0)|0;c=G[321387];G[321387]=0;d=-1;k:{if(!c){break k}e=G[321388];if(!e){break k}d=Ab(G[c>>2],g,4);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){break b}G[((i<<2)+f|0)+852028>>2]=f+48;g=We(1285568,1,g,4);j=Z()|0;c=0}l:{while(1){if(!c){G[321387]=0;ba(161,i+4|0,f+852016|0)|0;c=G[321387];G[321387]=0;d=-1;m:{if(!c){break m}e=G[321388];if(!e){break m}d=Ab(G[c>>2],g,j);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){continue}}G[321387]=0;b=ba(162,f+131120|0,13287)|0;c=G[321387];G[321387]=0;d=-1;n:{if(!c){break n}e=G[321388];if(!e){break n}d=Ab(G[c>>2],g,j);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){continue}a=28872;if(!b){break l}G[321387]=0;h=$(163,3809712,1,65535,b|0)|0;c=G[321387];G[321387]=0;d=-1;o:{if(!c){break o}e=G[321388];if(!e){break o}d=Ab(G[c>>2],g,j);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){continue}G[321387]=0;aa(164,b|0)|0;c=G[321387];G[321387]=0;d=-1;p:{if(!c){break p}e=G[321388];if(!e){break p}d=Ab(G[c>>2],g,j);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){continue}E[h+3809712|0]=0;if((h|0)<=0){break l}G[321387]=0;aa(165,f+131120|0)|0;c=G[321387];G[321387]=0;d=-1;q:{if(!c){break q}e=G[321388];if(!e){break q}d=Ab(G[c>>2],g,j);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){continue}break}a=3809712}Wa(g);Fa=f+1114160|0;return a|0}Wa(g);Ve(c,e);W()}function hu(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;f=Fa-1114160|0;Fa=f;g=ab(40);G[g>>2]=0;G[f+852016>>2]=13184;j=4;i=1;a:{b:{c:{if(!c|!H[c|0]){break c}G[321387]=0;l=aa(158,c|0)|0;c=G[321387];G[321387]=0;d=-1;d:{if(!c){break d}e=G[321388];if(!e){break d}d=Ab(G[c>>2],g,4);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){break b}G[321387]=0;h=pc(l,92039);c=G[321387];G[321387]=0;d=-1;e:{if(!c){break e}e=G[321388];if(!e){break e}d=Ab(G[c>>2],g,4);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){break b}f:{if(!h){break f}d=0;while(1){G[321387]=0;k=rb((f+196656|0)+(d<<16)|0,h,65535);c=G[321387];G[321387]=0;h=-1;g:{if(!c){break g}e=G[321388];if(!e){break g}h=Ab(G[c>>2],g,4);if(!h){break a}_(e|0)}c=Z()|0;if((h|0)==1){break b}G[(f+852016|0)+(i<<2)>>2]=k;G[321387]=0;h=pc(0,92039);c=G[321387];G[321387]=0;k=-1;h:{if(!c){break h}e=G[321388];if(!e){break h}k=Ab(G[c>>2],g,4);if(!k){break a}_(e|0)}c=Z()|0;if((k|0)==1){break b}i=i+1|0;if(!h){break f}c=d>>>0<9;d=d+1|0;if(c){continue}break}}if(!l){break c}Wa(l)}G[(f+852016|0)+(i<<2)>>2]=8722;c=G[968813];G[968813]=c+1;G[321387]=0;G[f+32>>2]=42205;G[f+36>>2]=c;$(156,f+131120|0,65535,4259,f+32|0)|0;c=G[321387];G[321387]=0;d=-1;i:{if(!c){break i}e=G[321388];if(!e){break i}d=Ab(G[c>>2],g,4);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){break b}G[321387]=0;G[f+16>>2]=42205;G[f+20>>2]=a;G[((i<<2)+f|0)+852020>>2]=f+131120;$(156,f+65584|0,65535,8740,f+16|0)|0;c=G[321387];G[321387]=0;d=-1;j:{if(!c){break j}e=G[321388];if(!e){break j}d=Ab(G[c>>2],g,4);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){break b}G[321387]=0;G[f>>2]=42205;G[f+4>>2]=b;G[((i<<2)+f|0)+852024>>2]=f+65584;$(156,f+48|0,65535,8740,f|0)|0;c=G[321387];G[321387]=0;d=-1;k:{if(!c){break k}e=G[321388];if(!e){break k}d=Ab(G[c>>2],g,4);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){break b}G[((i<<2)+f|0)+852028>>2]=f+48;g=We(1285568,1,g,4);j=Z()|0;c=0}l:{while(1){if(!c){G[321387]=0;ba(169,i+4|0,f+852016|0)|0;c=G[321387];G[321387]=0;d=-1;m:{if(!c){break m}e=G[321388];if(!e){break m}d=Ab(G[c>>2],g,j);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){continue}}G[321387]=0;b=ba(162,f+131120|0,13287)|0;c=G[321387];G[321387]=0;d=-1;n:{if(!c){break n}e=G[321388];if(!e){break n}d=Ab(G[c>>2],g,j);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){continue}a=28965;if(!b){break l}G[321387]=0;h=$(163,3809712,1,65535,b|0)|0;c=G[321387];G[321387]=0;d=-1;o:{if(!c){break o}e=G[321388];if(!e){break o}d=Ab(G[c>>2],g,j);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){continue}G[321387]=0;aa(164,b|0)|0;c=G[321387];G[321387]=0;d=-1;p:{if(!c){break p}e=G[321388];if(!e){break p}d=Ab(G[c>>2],g,j);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){continue}E[h+3809712|0]=0;if((h|0)<=0){break l}G[321387]=0;aa(165,f+131120|0)|0;c=G[321387];G[321387]=0;d=-1;q:{if(!c){break q}e=G[321388];if(!e){break q}d=Ab(G[c>>2],g,j);if(!d){break a}_(e|0)}c=Z()|0;if((d|0)==1){continue}break}a=3809712}Wa(g);Fa=f+1114160|0;return a|0}Wa(g);Ve(c,e);W()}function Ee(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;a:{b:{c:{d:{e:{switch(G[a+32>>2]-1|0){case 0:f=L[a>>3];n=L[a+8>>3];i=G[a+36>>2];h=G[a+56>>2];G[h>>2]=0;G[h+4>>2]=1072693248;f:{if((i|0)==1){break f}b=(n+b)*f;L[h+8>>3]=b;if((i|0)<3){break f}f=b+b;d=2;if((i|0)!=3){l=i-2&-2;while(1){m=d<<3;e=m+h|0;b=f*b-L[e-16>>3];L[e>>3]=b;b=f*b-L[e-8>>3];L[(m|8)+h>>3]=b;d=d+2|0;k=k+2|0;if((l|0)!=(k|0)){continue}break}}if(!(i&1)){break f}d=(d<<3)+h|0;L[d>>3]=f*b-L[d-16>>3]}b=L[a+16>>3];f=L[a+24>>3];g=G[a+40>>2];j=G[a+60>>2];G[j>>2]=0;G[j+4>>2]=1072693248;if((g|0)==1){break d}b=(f+c)*b;L[j+8>>3]=b;if((g|0)<3){break c}c=b+b;d=2;if((g|0)!=3){l=g-2&-2;k=0;while(1){m=d<<3;e=m+j|0;b=c*b-L[e-16>>3];L[e>>3]=b;b=c*b-L[e-8>>3];L[(m|8)+j>>3]=b;d=d+2|0;k=k+2|0;if((l|0)!=(k|0)){continue}break}}if(!(g&1)){break c}d=(d<<3)+j|0;L[d>>3]=c*b-L[d-16>>3];break c;case 1:f=L[a>>3];n=L[a+8>>3];i=G[a+36>>2];h=G[a+56>>2];G[h>>2]=0;G[h+4>>2]=1072693248;g:{if((i|0)==1){break g}b=(n+b)*f;L[h+8>>3]=b;if((i|0)<3){break g}d=2;f=b;while(1){n=+(d|0);e=(d<<3)+h|0;f=(b*(n+n+-1)*f-L[e-16>>3]*(n+-1))/n;L[e>>3]=f;d=d+1|0;if((i|0)!=(d|0)){continue}break}}b=L[a+16>>3];f=L[a+24>>3];g=G[a+40>>2];j=G[a+60>>2];G[j>>2]=0;G[j+4>>2]=1072693248;if((g|0)==1){break d}b=(f+c)*b;L[j+8>>3]=b;if((g|0)<3){break c}d=2;c=b;while(1){f=+(d|0);e=(d<<3)+j|0;c=(b*(f+f+-1)*c-L[e-16>>3]*(f+-1))/f;L[e>>3]=c;d=d+1|0;if((g|0)!=(d|0)){continue}break};break c;case 2:i=G[a+36>>2];h=G[a+56>>2];G[h>>2]=0;G[h+4>>2]=1072693248;h:{if((i|0)==1){break h}L[h+8>>3]=b;if((i|0)<3){break h}e=i-2|0;l=e&3;d=2;f=b;if(i-3>>>0>=3){m=e&-4;while(1){g=d<<3;e=g+h|0;f=f*b;L[e>>3]=f;f=f*b;L[(g|8)+h>>3]=f;n=f*b;f=n*b;L[e+24>>3]=f;L[e+16>>3]=n;d=d+4|0;k=k+4|0;if((m|0)!=(k|0)){continue}break}}if(!l){break h}e=0;while(1){f=f*b;L[(d<<3)+h>>3]=f;d=d+1|0;e=e+1|0;if((l|0)!=(e|0)){continue}break}}g=G[a+40>>2];j=G[a+60>>2];G[j>>2]=0;G[j+4>>2]=1072693248;if((g|0)==1){break d}L[j+8>>3]=c;if((g|0)<3){break c}e=g-2|0;l=e&3;d=2;b=c;if(g-3>>>0>=3){m=e&-4;k=0;while(1){o=d<<3;e=o+j|0;b=b*c;L[e>>3]=b;b=b*c;L[(o|8)+j>>3]=b;f=b*c;b=f*c;L[e+24>>3]=b;L[e+16>>3]=f;d=d+4|0;k=k+4|0;if((m|0)!=(k|0)){continue}break}}if(!l){break c}e=0;while(1){b=b*c;L[(d<<3)+j>>3]=b;d=d+1|0;e=e+1|0;if((l|0)!=(e|0)){continue}break};break c;default:break e}}hb(72625,33,1,G[24367]);break b}g=1;o=(i|0)>1?i:1;break a}if((g|0)<=0){break b}o=(g|0)<(i|0)?i:g;break a}return 0}t=G[a+44>>2];c=0;m=0;d=i;while(1){l=d;if((d|0)<=0){b=0}else{u=l&1;q=G[a+52>>2];i:{if((l|0)==1){b=0;d=0;e=m;break i}v=l&-2;b=0;d=0;e=m;k=0;while(1){r=(e<<3)+q|0;s=d<<3;b=L[r+8>>3]*L[(s|8)+h>>3]+(L[r>>3]*L[h+s>>3]+b);d=d+2|0;e=e+2|0;k=k+2|0;if((v|0)!=(k|0)){continue}break}}m=l+m|0;if(u){b=L[(e<<3)+q>>3]*L[(d<<3)+h>>3]+b}}b=b*L[(p<<3)+j>>3];d=1;j:{k:{switch(t|0){case 2:d=l-(((i+p|0)+1|0)>(o|0))|0;break j;case 0:break j;default:break k}}d=l}c=c+b;p=p+1|0;if((p|0)!=(g|0)){continue}break}return c}function xm(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;f=a+b|0;c=G[a+4>>2];a:{b:{if(c&1){break b}if(!(c&3)){break a}c=G[a>>2];b=c+b|0;c:{a=a-c|0;if((a|0)!=G[48630]){if(c>>>0<=255){e=G[a+8>>2];c=c>>>3|0;d=G[a+12>>2];if((d|0)!=(e|0)){break c}i=194500,j=G[48625]&Eu(-2,c),G[i>>2]=j;break b}h=G[a+24>>2];c=G[a+12>>2];d:{if((c|0)!=(a|0)){d=G[a+8>>2];G[d+12>>2]=c;G[c+8>>2]=d;break d}e:{e=a+20|0;d=G[e>>2];if(d){break e}e=a+16|0;d=G[e>>2];if(d){break e}c=0;break d}while(1){g=e;c=d;e=c+20|0;d=G[e>>2];if(d){continue}e=c+16|0;d=G[c+16>>2];if(d){continue}break}G[g>>2]=0}if(!h){break b}e=G[a+28>>2];d=(e<<2)+194804|0;f:{if(G[d>>2]==(a|0)){G[d>>2]=c;if(c){break f}i=194504,j=G[48626]&Eu(-2,e),G[i>>2]=j;break b}G[h+(G[h+16>>2]==(a|0)?16:20)>>2]=c;if(!c){break b}}G[c+24>>2]=h;d=G[a+16>>2];if(d){G[c+16>>2]=d;G[d+24>>2]=c}d=G[a+20>>2];if(!d){break b}G[c+20>>2]=d;G[d+24>>2]=c;break b}c=G[f+4>>2];if((c&3)!=3){break b}G[48627]=b;G[f+4>>2]=c&-2;G[a+4>>2]=b|1;G[f>>2]=b;return}G[e+12>>2]=d;G[d+8>>2]=e}c=G[f+4>>2];g:{if(!(c&2)){if(G[48631]==(f|0)){G[48631]=a;b=G[48628]+b|0;G[48628]=b;G[a+4>>2]=b|1;if(G[48630]!=(a|0)){break a}G[48627]=0;G[48630]=0;return}if(G[48630]==(f|0)){G[48630]=a;b=G[48627]+b|0;G[48627]=b;G[a+4>>2]=b|1;G[a+b>>2]=b;return}b=(c&-8)+b|0;h:{if(c>>>0<=255){e=G[f+8>>2];c=c>>>3|0;d=G[f+12>>2];if((d|0)==(e|0)){i=194500,j=G[48625]&Eu(-2,c),G[i>>2]=j;break h}G[e+12>>2]=d;G[d+8>>2]=e;break h}h=G[f+24>>2];c=G[f+12>>2];i:{if((f|0)!=(c|0)){d=G[f+8>>2];G[d+12>>2]=c;G[c+8>>2]=d;break i}j:{d=f+20|0;e=G[d>>2];if(e){break j}d=f+16|0;e=G[d>>2];if(e){break j}c=0;break i}while(1){g=d;c=e;d=c+20|0;e=G[d>>2];if(e){continue}d=c+16|0;e=G[c+16>>2];if(e){continue}break}G[g>>2]=0}if(!h){break h}e=G[f+28>>2];d=(e<<2)+194804|0;k:{if(G[d>>2]==(f|0)){G[d>>2]=c;if(c){break k}i=194504,j=G[48626]&Eu(-2,e),G[i>>2]=j;break h}G[h+(G[h+16>>2]==(f|0)?16:20)>>2]=c;if(!c){break h}}G[c+24>>2]=h;d=G[f+16>>2];if(d){G[c+16>>2]=d;G[d+24>>2]=c}d=G[f+20>>2];if(!d){break h}G[c+20>>2]=d;G[d+24>>2]=c}G[a+4>>2]=b|1;G[a+b>>2]=b;if(G[48630]!=(a|0)){break g}G[48627]=b;return}G[f+4>>2]=c&-2;G[a+4>>2]=b|1;G[a+b>>2]=b}if(b>>>0<=255){c=(b&-8)+194540|0;d=G[48625];b=1<<(b>>>3);l:{if(!(d&b)){G[48625]=b|d;b=c;break l}b=G[c+8>>2]}G[c+8>>2]=a;G[b+12>>2]=a;G[a+12>>2]=c;G[a+8>>2]=b;return}e=31;if(b>>>0<=16777215){c=b>>>8|0;g=c+1048320>>>16&8;c=c<>>16&4;c=c<>>16&2;c=(c<>>15|0)-(d|(e|g))|0;e=(c<<1|b>>>c+21&1)+28|0}G[a+28>>2]=e;G[a+16>>2]=0;G[a+20>>2]=0;g=(e<<2)+194804|0;m:{d=G[48626];c=1<>2]=a;G[a+24>>2]=g;break n}e=b<<((e|0)==31?0:25-(e>>>1|0)|0);c=G[g>>2];while(1){d=c;if((G[c+4>>2]&-8)==(b|0)){break m}c=e>>>29|0;e=e<<1;g=d+(c&4)|0;c=G[g+16>>2];if(c){continue}break}G[g+16>>2]=a;G[a+24>>2]=d}G[a+12>>2]=a;G[a+8>>2]=a;return}b=G[d+8>>2];G[b+12>>2]=a;G[d+8>>2]=a;G[a+24>>2]=0;G[a+12>>2]=d;G[a+8>>2]=b}}function Yp(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;a:{b:{if(!e){if(c==1&d==0){break b}if((b|0)<=0){break a}while(1){c:{d:{g=p<<3;n=L[g+a>>3]*c+d;if(n<-0x8000000000000000){G[k>>2]=-11;break d}if(n>0x8000000000000000){G[k>>2]=-11;f=2147483647;e=-1;break c}if(!(O(n)<0x8000000000000000)){break d}f=O(n)>=1?~~(n>0?Q(S(n*2.3283064365386963e-10),4294967295):T((n-+(~~n>>>0>>>0))*2.3283064365386963e-10))>>>0:0;e=~~n>>>0;break c}f=-2147483648;e=0}g=g+j|0;G[g>>2]=e;G[g+4>>2]=f;p=p+1|0;if((p|0)!=(b|0)){continue}break}break a}p=a+6|0;e:{f:{if(!(c==1&d==0)){if((b|0)<=0){break a}if(!(O(d)<0x8000000000000000)){break f}q=O(d)>=1?~~(d>0?Q(S(d*2.3283064365386963e-10),4294967295):T((d-+(~~d>>>0>>>0))*2.3283064365386963e-10))>>>0:0;m=~~d>>>0;break e}if((b|0)<=0){break a}while(1){g:{h:{i:{j:{m=I[p>>1]&32752;switch(((m|0)==32752?1:!m<<1)|0){case 0:break h;case 1:break j;default:break i}}G[i>>2]=1;if((e|0)==1){m=(o<<3)+j|0;G[m>>2]=f;G[m+4>>2]=g;break g}E[h+o|0]=1;break g}m=(o<<3)+j|0;G[m>>2]=0;G[m+4>>2]=0;break g}m=o<<3;c=L[m+a>>3];if(c<-0x8000000000000000){G[k>>2]=-11;m=j+m|0;G[m>>2]=0;G[m+4>>2]=-2147483648;break g}if(c>0x8000000000000000){G[k>>2]=-11;m=j+m|0;G[m>>2]=-1;G[m+4>>2]=2147483647;break g}m=j+m|0;k:{if(O(c)<0x8000000000000000){l=O(c)>=1?~~(c>0?Q(S(c*2.3283064365386963e-10),4294967295):T((c-+(~~c>>>0>>>0))*2.3283064365386963e-10))>>>0:0;q=~~c>>>0;break k}l=-2147483648;q=0}G[m>>2]=q;G[m+4>>2]=l}p=p+8|0;o=o+1|0;if((o|0)!=(b|0)){continue}break}break a}q=-2147483648;m=0}while(1){l:{m:{n:{o:{l=I[p>>1]&32752;switch(((l|0)==32752?1:!l<<1)|0){case 0:break m;case 1:break o;default:break n}}G[i>>2]=1;if((e|0)==1){l=(o<<3)+j|0;G[l>>2]=f;G[l+4>>2]=g;break l}E[h+o|0]=1;break l}if(d<-0x8000000000000000){G[k>>2]=-11;l=(o<<3)+j|0;G[l>>2]=0;G[l+4>>2]=-2147483648;break l}if(d>0x8000000000000000){G[k>>2]=-11;l=(o<<3)+j|0;G[l>>2]=-1;G[l+4>>2]=2147483647;break l}l=(o<<3)+j|0;G[l>>2]=m;G[l+4>>2]=q;break l}l=o<<3;n=L[l+a>>3]*c+d;if(n<-0x8000000000000000){G[k>>2]=-11;l=j+l|0;G[l>>2]=0;G[l+4>>2]=-2147483648;break l}if(n>0x8000000000000000){G[k>>2]=-11;l=(o<<3)+j|0;G[l>>2]=-1;G[l+4>>2]=2147483647;break l}l=(o<<3)+j|0;p:{if(O(n)<0x8000000000000000){r=O(n)>=1?~~(n>0?Q(S(n*2.3283064365386963e-10),4294967295):T((n-+(~~n>>>0>>>0))*2.3283064365386963e-10))>>>0:0;s=~~n>>>0;break p}r=-2147483648;s=0}G[l>>2]=s;G[l+4>>2]=r}p=p+8|0;o=o+1|0;if((o|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}while(1){q:{r:{g=p<<3;c=L[g+a>>3];if(c<-0x8000000000000000){G[k>>2]=-11;break r}if(c>0x8000000000000000){G[k>>2]=-11;f=2147483647;e=-1;break q}if(!(O(c)<0x8000000000000000)){break r}f=O(c)>=1?~~(c>0?Q(S(c*2.3283064365386963e-10),4294967295):T((c-+(~~c>>>0>>>0))*2.3283064365386963e-10))>>>0:0;e=~~c>>>0;break q}f=-2147483648;e=0}g=g+j|0;G[g>>2]=e;G[g+4>>2]=f;p=p+1|0;if((p|0)!=(b|0)){continue}break}}}function se(a,b,c){var d=0,e=0,f=0,g=0,h=0;f=Fa-1072|0;Fa=f;d=G[c>>2];a:{if((d|0)>0){break a}E[b|0]=0;E[f|0]=0;E[f+1040|0]=0;b:{c:{if(H[a|0]==45){d=f+1040|0;d=Va(d)+d|0;E[d|0]=45;E[d+1|0]=0;a=a+1|0;break c}d:{if(fb(a,15936,5)){if(fb(a,34568,5)){break d}}d=f+1040|0;d=Va(d)+d|0;E[d|0]=45;E[d+1|0]=0;a=a+5|0;break c}d=Sb(a,42197);e=jb(a,40);if(!(!d|(e|0)!=0&d>>>0>e>>>0)){e=d-a|0;if((e|0)>=17){break b}qb(f+1040|0,a,e+3|0);a=d+3|0;break c}if(!fb(a,36983,4)){d=f+1040|0;d=Va(d)+d|0;e=H[42036]|H[42037]<<8|(H[42038]<<16|H[42039]<<24);E[d|0]=e;E[d+1|0]=e>>>8;E[d+2|0]=e>>>16;E[d+3|0]=e>>>24;e=H[42039]|H[42040]<<8|(H[42041]<<16|H[42042]<<24);E[d+3|0]=e;E[d+4|0]=e>>>8;E[d+5|0]=e>>>16;E[d+6|0]=e>>>24;a=a+4|0;break c}if(!fb(a,36980,7)){d=f+1040|0;d=Va(d)+d|0;e=H[42037]|H[42038]<<8|(H[42039]<<16|H[42040]<<24);g=H[42033]|H[42034]<<8|(H[42035]<<16|H[42036]<<24);E[d|0]=g;E[d+1|0]=g>>>8;E[d+2|0]=g>>>16;E[d+3|0]=g>>>24;E[d+4|0]=e;E[d+5|0]=e>>>8;E[d+6|0]=e>>>16;E[d+7|0]=e>>>24;e=H[42041]|H[42042]<<8;E[d+8|0]=e;E[d+9|0]=e>>>8;a=a+7|0;break c}if(!fb(a,36974,5)){d=f+1040|0;d=Va(d)+d|0;E[d|0]=104;E[d+1|0]=116;E[d+2|0]=116;E[d+3|0]=112;E[d+4|0]=58;E[d+5|0]=47;E[d+6|0]=47;E[d+7|0]=0;a=a+5|0;break c}if(!fb(a,37360,4)){d=f+1040|0;d=Va(d)+d|0;e=H[42094]|H[42095]<<8|(H[42096]<<16|H[42097]<<24);E[d|0]=e;E[d+1|0]=e>>>8;E[d+2|0]=e>>>16;E[d+3|0]=e>>>24;e=H[42097]|H[42098]<<8|(H[42099]<<16|H[42100]<<24);E[d+3|0]=e;E[d+4|0]=e>>>8;E[d+5|0]=e>>>16;E[d+6|0]=e>>>24;a=a+4|0;break c}if(!fb(a,37358,6)){d=f+1040|0;d=Va(d)+d|0;e=H[42085]|H[42086]<<8|(H[42087]<<16|H[42088]<<24);g=H[42081]|H[42082]<<8|(H[42083]<<16|H[42084]<<24);E[d|0]=g;E[d+1|0]=g>>>8;E[d+2|0]=g>>>16;E[d+3|0]=g>>>24;E[d+4|0]=e;E[d+5|0]=e>>>8;E[d+6|0]=e>>>16;E[d+7|0]=e>>>24;E[d+8|0]=H[42089];a=a+6|0;break c}a=(fb(a,38404,5)?0:5)+a|0}e=jb(a,40);g=jb(a,91);e:{if(!e){e=0;break e}d=jb(e,41);if(!d){break e}while(1){h=H[d+1|0];d=d+1|0;if((h|0)==32){continue}if(!h|(h|0)==91){break e}e=jb(e+1|0,40);d=jb(d,41);if(!d){break e}if(e){continue}break}}f:{if((e|0)==(g|0)){if(Va(a)>>>0>=1025){break b}Gb(f,a);break f}if(!g){d=e-a|0;if((d|0)>=1025){break b}qb(f,a,d);if(!jb(e+1|0,41)){break b}break f}if(!(!e|e>>>0>=g>>>0)){d=e-a|0;if((d|0)>=1025){break b}qb(f,a,d);if(!jb(e+1|0,41)){break b}break f}d=g-a|0;if((d|0)>=1025){break b}qb(f,a,d)}d=Va(f);g:{if((d|0)<2){break g}while(1){a=d-1|0;e=a+f|0;if(H[e|0]!=32){break g}E[e|0]=0;e=d>>>0>2;d=a;if(e){continue}break}}e=Va(f);a=e;h:{while(1){d=a;if((d|0)<=0){break h}a=d-1|0;g=f+a|0;if(H[g|0]!=43){continue}break}if(d>>>0<2|(e-a|0)>4){break h}i:{j:{if((d|0)>=(e|0)){break j}while(1){if(E[d+f|0]-48>>>0>9){break j}d=d+1|0;if((e|0)!=(d|0)){continue}break}break i}if((d|0)!=(e|0)){break h}}E[g|0]=0}if(Va(f+1040|0)+Va(f)>>>0>=1025){break b}Gb(Gb(b,f+1040|0),f);d=G[c>>2];break a}d=125;G[c>>2]=125}Fa=f+1072|0;return d}function Ts(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;d=G[309722];b=G[a+12>>2];l=d+M(b,344)|0;e=G[l>>2];f=(e|0)==-1e3?l+88|0:0;h=G[a+16>>2];m=d+M(h,344)|0;n=G[m>>2];g=(n|0)==-1e3?m+88|0:0;a:{if(!((e|0)!=-1e3|(n|0)!=-1e3)){b:{c:{d:{e:{f:{g:{h:{c=G[a>>2];switch(c-278|0){case 4:break d;case 5:break e;case 3:break f;case 2:break g;case 0:case 1:break h;default:break c}}if(H[f|0]==H[g|0]){b=Xa(f,g)}else{b=1}E[a+88|0]=!b^(c|0)!=278;break b}d=E[f|0];e=E[g|0];b=0;i:{if((d|0)<(e|0)){break i}b=1;if((e|0)<(d|0)){break i}b=(Xa(f,g)|0)>0}E[a+88|0]=b;break b}d=E[f|0];e=E[g|0];b=1;j:{if((d|0)<(e|0)){break j}b=0;if((e|0)<(d|0)){break j}b=Xa(f,g)>>>31|0}E[a+88|0]=b;break b}d=E[f|0];e=E[g|0];b=0;k:{if((d|0)<(e|0)){break k}b=1;if((e|0)<(d|0)){break k}b=(Xa(f,g)|0)>=0}E[a+88|0]=b;break b}d=E[f|0];e=E[g|0];b=1;l:{if((d|0)<(e|0)){break l}b=0;if((e|0)<(d|0)){break l}b=(Xa(f,g)|0)<=0}E[a+88|0]=b;break b}if((c|0)!=43){break b}Gb(Za(a+88|0,f),g)}G[a>>2]=-1e3;break a}Nd(a);if(G[309737]){break a}c=G[309727];j=G[a>>2];i=j-278|0;if(i>>>0>5){if(!c|(j|0)!=43){break a}h=d+M(h,344)|0;j=d+M(b,344)|0;b=(e|0)==-1e3;d=0;e=0;while(1){c=c-1|0;e=b?e:H[G[j+84>>2]+c|0];i=(n|0)==-1e3;d=i?d:H[G[h+84>>2]+c|0];E[G[a+84>>2]+c|0]=(e|d)!=0;if(!H[G[a+84>>2]+c|0]){f=b?f:G[G[l+88>>2]+(c<<2)>>2];g=i?g:G[G[m+88>>2]+(c<<2)>>2];i=c<<2;Za(G[i+G[a+88>>2]>>2],f);Gb(G[i+G[a+88>>2]>>2],g)}if(c){continue}break}break a}m:{j=1<>2]+c|0];b=(n|0)==-1e3;d=b?d:H[G[j+84>>2]+c|0];E[G[a+84>>2]+c|0]=(e|d)!=0;if(!H[G[a+84>>2]+c|0]){f=h?f:G[G[l+88>>2]+(c<<2)>>2];g=b?g:G[G[m+88>>2]+(c<<2)>>2];o=E[f|0];b=E[g|0];k=-1;n:{if((o|0)<(b|0)){break n}k=1;if((b|0)<(o|0)){break n}k=Xa(f,g)}b=k;E[G[a+88>>2]+c|0]=G[a>>2]==280?(b|0)>0:b>>>31|0}if(c){continue}break}break a}if(!c){break a}j=d+M(h,344)|0;i=d+M(b,344)|0;b=(e|0)==-1e3;d=0;e=0;while(1){c=c-1|0;e=b?e:H[G[i+84>>2]+c|0];h=(n|0)==-1e3;d=h?d:H[G[j+84>>2]+c|0];E[G[a+84>>2]+c|0]=(e|d)!=0;if(!H[G[a+84>>2]+c|0]){f=b?f:G[G[l+88>>2]+(c<<2)>>2];g=h?g:G[G[m+88>>2]+(c<<2)>>2];h=-1;if(H[f|0]==H[g|0]){h=Xa(f,g)}E[G[a+88>>2]+c|0]=!h^G[a>>2]!=278}if(c){continue}break}break a}if(!c){break a}j=d+M(h,344)|0;i=d+M(b,344)|0;h=(e|0)==-1e3;d=0;e=0;while(1){c=c-1|0;e=h?e:H[G[i+84>>2]+c|0];b=(n|0)==-1e3;d=b?d:H[G[j+84>>2]+c|0];E[G[a+84>>2]+c|0]=(e|d)!=0;if(!H[G[a+84>>2]+c|0]){f=h?f:G[G[l+88>>2]+(c<<2)>>2];g=b?g:G[G[m+88>>2]+(c<<2)>>2];o=E[f|0];b=E[g|0];k=-1;o:{if((o|0)<(b|0)){break o}k=1;if((b|0)<(o|0)){break o}k=Xa(f,g)}b=k;E[G[a+88>>2]+c|0]=G[a>>2]==283?(b|0)>=0:(b|0)<=0}if(c){continue}break}}if(G[l>>2]>0){Wa(G[G[l+88>>2]>>2]);Wa(G[l+88>>2])}if(G[m>>2]>0){Wa(G[G[m+88>>2]>>2]);Wa(G[m+88>>2])}}function Co(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0;l=c==1&d==-128;a:{b:{if(!e){if(l){if((b|0)<=0){break a}g=b&3;e=0;f=0;if(b-1>>>0>=3){h=b&-4;b=0;while(1){E[f+j|0]=H[a+f|0]^128;i=f|1;E[i+j|0]=H[a+i|0]^128;i=f|2;E[i+j|0]=H[a+i|0]^128;i=f|3;E[i+j|0]=H[a+i|0]^128;f=f+4|0;b=b+4|0;if((h|0)!=(b|0)){continue}break}}if(!g){break a}while(1){E[f+j|0]=H[a+f|0]^128;f=f+1|0;e=e+1|0;if((g|0)!=(e|0)){continue}break}break a}if(c==1&d==0){break b}f=0;if((b|0)<=0){break a}while(1){g=f+j|0;n=+H[a+f|0]*c+d;c:{if(n<-128.49){G[k>>2]=-11;e=128;break c}if(n>127.49){G[k>>2]=-11;e=127;break c}e=~~n;if(O(n)<2147483648){break c}e=-2147483648}E[g|0]=e;f=f+1|0;if((f|0)!=(b|0)){continue}break}break a}d:{e:{f:{g:{if(l){if((b|0)<=0){break a}if((e|0)==1){break d}l=b&1;e=0;if((b|0)!=1){m=b&-2;b=0;while(1){g=H[a+e|0];h:{if((g|0)==(f|0)){G[i>>2]=1;k=h;g=1;break h}k=j;g=g^-128}E[e+k|0]=g;o=e|1;g=H[o+a|0];i:{if((g|0)!=(f|0)){k=g^-128;g=j;break i}k=1;G[i>>2]=1;g=h}E[g+o|0]=k;e=e+2|0;b=b+2|0;if((m|0)!=(b|0)){continue}break}}if(!l){break a}a=H[a+e|0];if((a|0)==(f|0)){break g}a=a^-128;break f}if(c==1&d==0){break e}if((b|0)<=0){break a}e=(e|0)==1;l=e?g:1;m=e?j:h;e=0;while(1){g=H[a+e|0];j:{if((g|0)==(f|0)){G[i>>2]=1;h=l;g=m;break j}n=+(g>>>0)*c+d;k:{if(n<-128.49){G[k>>2]=-11;h=128;break k}if(n>127.49){G[k>>2]=-11;h=127;break k}h=~~n;if(O(n)<2147483648){break k}h=-2147483648}g=j}E[g+e|0]=h;e=e+1|0;if((e|0)!=(b|0)){continue}break}break a}G[i>>2]=1;j=h;a=1}E[e+j|0]=a;break a}if((b|0)<=0){break a}if((e|0)!=1){e=0;if((b|0)!=1){m=b&-2;k=0;while(1){g=H[a+e|0];if((g|0)==(f|0)){g=1;G[i>>2]=1;l=h}else{l=j}E[l+e|0]=g;o=e|1;g=H[o+a|0];if((g|0)==(f|0)){g=1;G[i>>2]=1;l=h}else{l=j}E[l+o|0]=g;e=e+2|0;k=k+2|0;if((m|0)!=(k|0)){continue}break}}if(!(b&1)){break a}a=H[a+e|0];if((f|0)==(a|0)){G[i>>2]=1;j=h;a=1}E[e+j|0]=a;break a}k=b&1;e=0;if((b|0)!=1){l=b&-2;h=0;while(1){m=e+j|0;b=H[a+e|0];if((b|0)==(f|0)){G[i>>2]=1;b=g}E[m|0]=b;m=e|1;b=H[m+a|0];if((f|0)==(b|0)){G[i>>2]=1;b=g}E[j+m|0]=b;e=e+2|0;h=h+2|0;if((l|0)!=(h|0)){continue}break}}if(!k){break a}b=e+j|0;a=H[a+e|0];if((a|0)==(f|0)){G[i>>2]=1}else{g=a}E[b|0]=g;break a}k=b&1;e=0;if((b|0)!=1){l=b&-2;b=0;while(1){m=e+j|0;h=H[a+e|0];l:{if((h|0)!=(f|0)){h=h^-128;break l}G[i>>2]=1;h=g}E[m|0]=h;m=e|1;h=H[m+a|0];m:{if((h|0)!=(f|0)){h=h^-128;break m}G[i>>2]=1;h=g}E[j+m|0]=h;e=e+2|0;b=b+2|0;if((l|0)!=(b|0)){continue}break}}if(!k){break a}a=H[a+e|0];n:{if((a|0)!=(f|0)){g=a^-128;break n}G[i>>2]=1}E[e+j|0]=g;break a}if((b|0)<=0){break a}g=b&1;f=0;if((b|0)!=1){h=b&-2;b=0;while(1){i=f+j|0;e=E[a+f|0];if((e|0)<0){G[k>>2]=-11;e=127}E[i|0]=e;i=f|1;e=E[i+a|0];if((e|0)<0){G[k>>2]=-11;e=127}E[i+j|0]=e;f=f+2|0;b=b+2|0;if((h|0)!=(b|0)){continue}break}}if(!g){break a}b=f+j|0;a=E[a+f|0];if((a|0)<0){G[k>>2]=-11;a=127}E[b|0]=a}}function $g(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;c=Fa-320|0;Fa=c;r=G[a+12>>2];g=G[a+4>>2];j=G[a>>2];p=G[a+16>>2];a:{if(!p){break a}h=G[a+20>>2];f=p-1|0;b:{if(!f){break b}cb(c+240|4,0,(p<<2)-4|0);d=c+272|0;k=f&7;if(k){while(1){G[d+8>>2]=0;G[d+12>>2]=1072693248;f=f-1|0;d=d+8|0;i=i+1|0;if((k|0)!=(i|0)){continue}break}}if(p-2>>>0<7){break b}while(1){G[d+64>>2]=0;G[d+68>>2]=1072693248;G[d+56>>2]=0;G[d+60>>2]=1072693248;G[d+48>>2]=0;G[d+52>>2]=1072693248;G[d+40>>2]=0;G[d+44>>2]=1072693248;G[d+32>>2]=0;G[d+36>>2]=1072693248;G[d+24>>2]=0;G[d+28>>2]=1072693248;G[d+16>>2]=0;G[d+20>>2]=1072693248;G[d+8>>2]=0;G[d+12>>2]=1072693248;d=d- -64|0;f=f-8|0;if(f){continue}break}}d=G[a+24>>2];if(d){bb(c+208|0,h,d<<2)}d=(c+208|0)+(G[r>>2]<<2)|0;f=G[d>>2];if(!f){break a}G[d>>2]=f-1}td(c+192|0,L[g>>3]);G[j>>2]=0;G[j+4>>2]=1072693248;G[c+240>>2]=1;e=L[b>>3];L[c+272>>3]=e;k=G[c+200>>2];m=G[c+204>>2];n=G[c+192>>2];o=G[c+196>>2];a=G[a+8>>2];l=a-1|0;c:{if(!l){break c}h=j+8|0;g=g+8|0;d=0;if((p|0)>0){while(1){e=L[c+272>>3];L[h>>3]=e;td(c+16|0,e*L[g>>3]);Zc(c,n,o,k,m,G[c+16>>2],G[c+20>>2],G[c+24>>2],G[c+28>>2]);k=G[c+8>>2];m=G[c+12>>2];f=c+240|0;d=c+272|0;n=G[c>>2];o=G[c+4>>2];a=b;i=0;j=r;d:{while(1){e:{q=(c+208|0)+(G[j>>2]<<2)|0;s=G[q>>2];G[q>>2]=s-1;t=G[f>>2];if(s){break e}G[q>>2]=t;G[f>>2]=0;G[d>>2]=0;G[d+4>>2]=1072693248;j=j+4|0;a=a+8|0;d=d+8|0;f=f+4|0;i=i+1|0;if((p|0)!=(i|0)){continue}break d}break}G[f>>2]=t+1;e=L[a>>3]*L[d>>3];L[d>>3]=e;if(!i){break d}a=i-1|0;f=0;j=i&7;if(j){while(1){d=d-8|0;L[d>>3]=e;i=i-1|0;f=f+1|0;if((j|0)!=(f|0)){continue}break}}if(a>>>0<7){break d}while(1){L[d-16>>3]=e;L[d-8>>3]=e;L[d-24>>3]=e;L[d-32>>3]=e;L[d-40>>3]=e;L[d-48>>3]=e;L[d-56>>3]=e;d=d+-64|0;L[d>>3]=e;i=i-8|0;if(i){continue}break}}g=g+8|0;h=h+8|0;l=l-1|0;if(l){continue}break c}}b=l&3;if(b){while(1){L[h>>3]=e;td(c+176|0,e*L[g>>3]);Zc(c+160|0,n,o,k,m,G[c+176>>2],G[c+180>>2],G[c+184>>2],G[c+188>>2]);l=l-1|0;g=g+8|0;h=h+8|0;k=G[c+168>>2];m=G[c+172>>2];n=G[c+160>>2];o=G[c+164>>2];d=d+1|0;if((b|0)!=(d|0)){continue}break}}if(a-2>>>0<3){break c}while(1){L[h>>3]=e;td(c+144|0,e*L[g>>3]);Zc(c+80|0,n,o,k,m,G[c+144>>2],G[c+148>>2],G[c+152>>2],G[c+156>>2]);L[h+8>>3]=e;td(c+128|0,e*L[g+8>>3]);Zc(c- -64|0,G[c+80>>2],G[c+84>>2],G[c+88>>2],G[c+92>>2],G[c+128>>2],G[c+132>>2],G[c+136>>2],G[c+140>>2]);L[h+16>>3]=e;td(c+112|0,e*L[g+16>>3]);Zc(c+48|0,G[c+64>>2],G[c+68>>2],G[c+72>>2],G[c+76>>2],G[c+112>>2],G[c+116>>2],G[c+120>>2],G[c+124>>2]);L[h+24>>3]=e;td(c+96|0,e*L[g+24>>3]);Zc(c+32|0,G[c+48>>2],G[c+52>>2],G[c+56>>2],G[c+60>>2],G[c+96>>2],G[c+100>>2],G[c+104>>2],G[c+108>>2]);g=g+32|0;h=h+32|0;k=G[c+40>>2];m=G[c+44>>2];n=G[c+32>>2];o=G[c+36>>2];l=l-4|0;if(l){continue}break}}e=Ui(n,o,k,m);Fa=c+320|0;return e}function Xn(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;d=Fa-208|0;Fa=d;a:{if(G[c>>2]>0){break a}if(!H[a|0]){G[c>>2]=204;break a}i=d+112|0;g=Fa-96|0;Fa=g;b:{c:{d:{e:{f:{if(G[c>>2]<=0){f=67;g:{h=H[a|0];switch(h-39|0){case 0:break c;case 1:break e;default:break g}}h:{switch(h-70|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:break d;case 0:case 14:break f;default:break h}}if(h){break d}G[c>>2]=204}f=H[d+207|0];break b}f=76;break c}f=88;break c}f=70;if(jb(a,46)){break c}if(jb(a,69)){break c}f=jb(a,68)?70:73}E[d+207|0]=f}i:{j:{switch((f&255)-70|0){case 3:if(G[c>>2]>0){break i}G[48624]=0;G[b>>2]=0;G[b+4>>2]=0;j=b,k=ti(a,g+92|0,10,-1,-1),G[j>>2]=k;G[b+4>>2]=Ia;if((H[G[g+92>>2]]|32)!=32){G[c>>2]=407}if(G[48624]!=68){break i}tb(5,qb(bb(g,66899,68),a,25));G[c>>2]=412;G[48624]=0;break i;case 0:me(a,d,c);break i;case 6:if(G[c>>2]>0){break i}G[d+12>>2]=H[a|0]==84;break i;default:break j}}fd(a,i,c)}Fa=g+96|0;f=403;k:{l:{m:{n:{o:{switch(H[d+207|0]-67|0){case 0:if((me(d+112|0,d,c)|0)>0){break m}f=412;e=L[d>>3];if(e>0x10000000000000000|e<-.49){break l}if(e<0x10000000000000000&e>=0){f=~~e>>>0;g=O(e)>=1?~~(e>0?Q(S(e*2.3283064365386963e-10),4294967295):T((e-+(~~e>>>0>>>0))*2.3283064365386963e-10))>>>0:0;break n}f=0;g=0;break n;case 3:f=412;e=L[d>>3];if(e>0x10000000000000000|e<-.49){break l}if(e<0x10000000000000000&e>=0){f=~~e>>>0;g=O(e)>=1?~~(e>0?Q(S(e*2.3283064365386963e-10),4294967295):T((e-+(~~e>>>0>>>0))*2.3283064365386963e-10))>>>0:0;break n}f=0;g=0;break n;case 21:break l;case 9:break o;default:break m}}f=G[d+12>>2];g=f>>31}G[b>>2]=f;G[b+4>>2]=g}if(G[c>>2]>0){break k}break a}G[c>>2]=f}G[b>>2]=0;G[b+4>>2]=0;b=H[67242]|H[67243]<<8|(H[67244]<<16|H[67245]<<24);c=H[67238]|H[67239]<<8|(H[67240]<<16|H[67241]<<24);E[d+61|0]=c;E[d+62|0]=c>>>8;E[d+63|0]=c>>>16;E[d+64|0]=c>>>24;E[d+65|0]=b;E[d+66|0]=b>>>8;E[d+67|0]=b>>>16;E[d+68|0]=b>>>24;b=H[67237]|H[67238]<<8|(H[67239]<<16|H[67240]<<24);G[d+56>>2]=H[67233]|H[67234]<<8|(H[67235]<<16|H[67236]<<24);G[d+60>>2]=b;b=H[67229]|H[67230]<<8|(H[67231]<<16|H[67232]<<24);G[d+48>>2]=H[67225]|H[67226]<<8|(H[67227]<<16|H[67228]<<24);G[d+52>>2]=b;b=H[67221]|H[67222]<<8|(H[67223]<<16|H[67224]<<24);G[d+40>>2]=H[67217]|H[67218]<<8|(H[67219]<<16|H[67220]<<24);G[d+44>>2]=b;b=H[67213]|H[67214]<<8|(H[67215]<<16|H[67216]<<24);G[d+32>>2]=H[67209]|H[67210]<<8|(H[67211]<<16|H[67212]<<24);G[d+36>>2]=b;b=H[67205]|H[67206]<<8|(H[67207]<<16|H[67208]<<24);G[d+24>>2]=H[67201]|H[67202]<<8|(H[67203]<<16|H[67204]<<24);G[d+28>>2]=b;b=H[67197]|H[67198]<<8|(H[67199]<<16|H[67200]<<24);G[d+16>>2]=H[67193]|H[67194]<<8|(H[67195]<<16|H[67196]<<24);G[d+20>>2]=b;tb(5,qb(d+16|0,a,30))}Fa=d+208|0}function zn(a,b,c,d,e,f,g,h,i,j,k,l){var m=0,n=0,o=0,p=0,q=0,r=0;a:{b:{if(G[309737]<=0){m=(b-f)*h;f=(a-e)*g;a=i*.01745329252;o=ib(a);p=eb(a);c:{if(i==0){b=m;break c}b=m*p+f*o;f=f*p-o*m}r=H[j|0];i=d*.01745329252;m=ib(i);e=eb(i);if((r|0)!=45){break a}f=f*.01745329252;q=f*f;b=b*.01745329252;n=q+b*b;a=c*.01745329252;d:{e:{f:{switch(H[j+1|0]-65|0){case 2:if(H[j+2|0]!=65|H[j+3|0]!=82){break a}i=i+b;h=a+f;break d;case 19:if(H[j+2|0]!=65|H[j+3|0]!=78){break a}c=eb(a);d=ib(a);g=e*d+c*f-d*b*m;c=e*c-d*f-c*b*m;h=Db(g,c);i=Pd((b*e+m)/V(c*c+g*g));break d;case 18:g:{switch(H[j+2|0]-73|0){case 0:if(H[j+3|0]!=78){break a}if(n>1){break b}d=V(1-n);c=m*d+e*b;if(c>1|c<-1){break b}b=e*d-b*m;if(b==0&f==0){break b}i=fc(c);h=a+Db(f,b);break d;case 11:break g;default:break a}}if(H[j+3|0]!=71){break a}c=(4-n)/(n+4);if(O(c)>1){break b}d=c+1;c=c*m+e*b*d*.5;if(O(c)>1){break b}i=fc(c);c=eb(i);if(O(c)<1e-5){break b}f=f*d/(c+c);if(O(f)>1){break b}d=ib(i);f=fc(f);g=eb(f);h=e*c*g+(d*m+1);if(O(h)<1e-5){break b}c=d*e-m*c*g;h=a+(O((c+c)/h-b)>1e-5?3.141592653589795-f:f);break d;case 0:h:{switch(H[j+2|0]-73|0){case 9:if(H[j+3|0]!=67){break a}if(n>=9.869604401089369){break b}c=V(n);d=eb(c);h=1;if(c!=0){h=ib(c)/c}b=e*b*h+m*d;if(b>1|b<-1){break b}c=d-b*m;d=e*(f*h);if(c==0&d==0){break b}i=fc(b);h=a+Db(d,c);break d;case 0:break h;default:break a}}if(H[j+3|0]!=84){break a}c=g*p-o*h;c=c==0?.01745329252:c*.01745329252;d=c*.5;n=ib(d);d=eb(d);g=h*p+o*g;g=g==0?.01745329252:g*.01745329252;h=i+g;o=eb(h);p=ib(h);if(f==0){h=a;if(b==0){break d}}d=c*V((e*d+1)*.5);c=(e+e)*n;c=d/(c==0?1:c);e=V((e+1)*.5);d=p/V((o+1)*.5)-m/e;d=g/(d==0?1:d);e=m*d/e+b;b=e/d;b=4-q/(c*(c*4))-b*b;if(b>4|b<2){break b}b=V(b)*.5;d=e*b/d;if(O(d)>1){break b}i=fc(d);d=eb(i);if(O(d)<1e-5){break b}b=f*b/((c+c)*d);if(O(b)>1){break b}b=fc(b);h=b+b+a;break d;case 13:if(H[j+2|0]!=67|H[j+3|0]!=80){break a}b=e-b*m;if(b==0){break b}h=a+Db(f,b);c=eb(h-a);if(c==0){break b}b=b/c;if(b>1|b<-1){break b}j=i<0;i=Sc(b);if(!j){break d}i=-i;break d;case 6:if(H[j+2|0]!=76|H[j+3|0]!=83){break a}i=i+b;if(O(i)>1.5707963267948974){break b}b=eb(i);if(O(f)>b*6.28318530717959*.5){break b}if(b>1e-5){break e}h=a;break d;case 12:break f;default:break a}}if(H[j+2|0]!=69|H[j+3|0]!=82){break a}c=(d*.5+45)*.01745329252;d=Mc(c);g=h*p+o*g;g=g==0?1:g;i=oc(Mc(g*.5*.01745329252+c));c=oc(d);h=a+f/(e<=0?1:e);if(O(h-a)>6.28318530717959){break b}d=g*.01745329252/(i-c);if(d!=0){b=(b+c*d)/d}else{b=0}b=Pd(af(b));i=b+b+-1.5707963267948974;break d}h=a+f/b}b=h-a>3.141592653589795?h+-6.28318530717959:h;a=b-a<-3.141592653589795?b+6.28318530717959:b;L[k>>3]=(a<0?a+6.28318530717959:a)/.01745329252;L[l>>3]=i/.01745329252}return}G[309737]=501;return}G[309737]=504} -function lp(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;if((c|0)>=0){j=I[b+2>>1];g=j?4:3;e=j?7:138;i=a+5817|0;h=-1;while(1){o=n;k=j;n=n+1|0;j=I[((n<<2)+b|0)+2>>1];d=f+1|0;a:{if(!((k|0)!=(j|0)|(e|0)<=(d|0))){f=d;break a}b:{if((d|0)<(g|0)){f=(k<<2)+a|0;g=f+2686|0;h=f+2684|0;f=G[a+5820>>2];while(1){e=I[g>>1];l=I[h>>1];m=I[a+5816>>1]|l<>1]=m;c:{if((16-e|0)<(f|0)){f=G[a+20>>2];G[a+20>>2]=f+1;E[f+G[a+8>>2]|0]=m;f=G[a+20>>2];G[a+20>>2]=f+1;E[f+G[a+8>>2]|0]=H[i|0];f=G[a+5820>>2];F[a+5816>>1]=l>>>16-f;f=(e+f|0)-16|0;break c}f=e+f|0}G[a+5820>>2]=f;d=d-1|0;if(d){continue}break}break b}m=a;d:{if(k){e:{if((h|0)==(k|0)){e=G[a+5820>>2];f=d;break e}d=(k<<2)+a|0;e=I[d+2686>>1];h=I[d+2684>>1];g=G[a+5820>>2];l=I[a+5816>>1]|h<>1]=l;f:{if((g|0)>(16-e|0)){g=G[a+20>>2];G[a+20>>2]=g+1;E[g+G[a+8>>2]|0]=l;g=G[a+20>>2];G[a+20>>2]=g+1;E[g+G[a+8>>2]|0]=H[i|0];g=G[a+5820>>2];F[a+5816>>1]=h>>>16-g;d=(e+g|0)-16|0;break f}d=e+g|0}e=d;G[a+5820>>2]=e}h=I[a+2748>>1];d=I[a+5816>>1]|h<>1];g:{if((16-g|0)<(e|0)){F[a+5816>>1]=d;e=G[a+20>>2];G[a+20>>2]=e+1;E[e+G[a+8>>2]|0]=d;d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=H[i|0];d=G[a+5820>>2];e=(d+g|0)-16|0;d=h>>>16-d|0;break g}e=e+g|0}G[a+5820>>2]=e;f=f+65533|0;if((e|0)>=15){d=f<>1]=d;e=G[a+20>>2];G[a+20>>2]=e+1;E[e+G[a+8>>2]|0]=d;d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=H[i|0];d=f&65535;f=G[a+5820>>2];F[a+5816>>1]=d>>>16-f;f=f-14|0;break d}F[a+5816>>1]=f<>1];e=G[a+5820>>2];d=I[a+5816>>1]|h<>1];h:{if((e|0)>(16-g|0)){F[a+5816>>1]=d;e=G[a+20>>2];G[a+20>>2]=e+1;E[e+G[a+8>>2]|0]=d;d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=H[i|0];d=G[a+5820>>2];e=(d+g|0)-16|0;d=h>>>16-d|0;break h}e=e+g|0}G[a+5820>>2]=e;f=f+65534|0;if((e|0)>=14){d=f<>1]=d;e=G[a+20>>2];G[a+20>>2]=e+1;E[e+G[a+8>>2]|0]=d;d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=H[i|0];d=f&65535;f=G[a+5820>>2];F[a+5816>>1]=d>>>16-f;f=f-13|0;break d}F[a+5816>>1]=f<>1];e=G[a+5820>>2];d=I[a+5816>>1]|h<>1];i:{if((e|0)>(16-g|0)){F[a+5816>>1]=d;e=G[a+20>>2];G[a+20>>2]=e+1;E[e+G[a+8>>2]|0]=d;d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=H[i|0];d=G[a+5820>>2];e=(d+g|0)-16|0;d=h>>>16-d|0;break i}e=e+g|0}G[a+5820>>2]=e;f=f+65526|0;if((e|0)>=10){d=f<>1]=d;e=G[a+20>>2];G[a+20>>2]=e+1;E[e+G[a+8>>2]|0]=d;d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=H[i|0];d=f&65535;f=G[a+5820>>2];F[a+5816>>1]=d>>>16-f;f=f-9|0;break d}F[a+5816>>1]=f<>2]=f}f=0;j:{if(!j){e=138;d=3;break j}d=(k|0)==(j|0);e=d?6:7;d=d?3:4}g=d;h=k}if((c|0)!=(o|0)){continue}break}}}function Sb(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;c=E[b|0];if(!c){return a}a=jb(a,c);a:{if(!a){break a}if(!H[b+1|0]){return a}if(!H[a+1|0]){break a}if(!H[b+2|0]){c=H[a+1|0];e=(c|0)!=0;b:{if(!c){break b}c=c|H[a|0]<<8;h=H[b+1|0]|H[b|0]<<8;if((c|0)==(h|0)){break b}b=a+1|0;while(1){a=b;d=H[a+1|0];e=(d|0)!=0;if(!d){break b}b=a+1|0;c=d|c<<8&65280;if((h|0)!=(c|0)){continue}break}}return e?a:0}if(!H[a+2|0]){break a}if(!H[b+3|0]){d=b;b=a+2|0;c=H[a+2|0];e=(c|0)!=0;c:{d:{if(!c){break d}c=H[a+1|0]<<16|H[a|0]<<24|c<<8;h=H[d+1|0]<<16|H[d|0]<<24|H[d+2|0]<<8;if((c|0)==(h|0)){break d}while(1){a=b+1|0;d=H[b+1|0];e=(d|0)!=0;if(!d){break c}b=a;c=(c|d)<<8;if((h|0)!=(c|0)){continue}break}break c}a=b}return e?a-2|0:0}if(!H[a+3|0]){break a}if(!H[b+4|0]){d=b;b=a+3|0;c=H[a+3|0];e=(c|0)!=0;e:{f:{if(!c){break f}c=c|(H[a+1|0]<<16|H[a|0]<<24|H[a+2|0]<<8);a=H[d|0]|H[d+1|0]<<8|(H[d+2|0]<<16|H[d+3|0]<<24);h=a<<24|a<<8&16711680|(a>>>8&65280|a>>>24);if((c|0)==(h|0)){break f}while(1){a=b+1|0;d=H[b+1|0];e=(d|0)!=0;if(!d){break e}b=a;c=d|c<<8;if((h|0)!=(c|0)){continue}break}break e}a=b}return e?a-3|0:0}h=a;i=Fa-1056|0;Fa=i;a=i+1048|0;G[a>>2]=0;G[a+4>>2]=0;a=i+1040|0;G[a>>2]=0;G[a+4>>2]=0;G[i+1032>>2]=0;G[i+1036>>2]=0;G[i+1024>>2]=0;G[i+1028>>2]=0;k=b;g:{h:{i:{j:{c=H[b|0];k:{if(!c){j=-1;a=1;break k}while(1){if(!H[f+h|0]){break h}a=c&255;f=f+1|0;G[(a<<2)+i>>2]=f;a=(i+1024|0)+(a>>>3&28)|0;G[a>>2]=G[a>>2]|1<>>0>1){break j}}g=-1;d=1;break i}b=1;c=1;while(1){g=H[(c+j|0)+k|0];e=H[a+k|0];l:{if((g|0)==(e|0)){if((b|0)==(c|0)){d=b+d|0;c=1;break l}c=c+1|0;break l}if(e>>>0>>0){b=a-j|0;d=a;c=1;break l}j=d;d=d+1|0;b=1;c=1}a=c+d|0;if(f>>>0>a>>>0){continue}break}d=1;g=-1;if(f>>>0<=1){a=b;break i}a=0;e=1;c=1;while(1){m=H[(c+g|0)+k|0];l=H[d+k|0];m:{if((m|0)==(l|0)){if((c|0)==(e|0)){a=a+e|0;c=1;break m}c=c+1|0;break m}if(l>>>0>m>>>0){e=d-g|0;a=d;c=1;break m}g=a;a=a+1|0;e=1;c=1}d=a+c|0;if(f>>>0>d>>>0){continue}break}a=b;d=e}b=a;a=g+1>>>0>j+1>>>0;e=a?d:b;l=a?g:j;m=l+1|0;n:{if(nb(k,e+k|0,m)){a=(l^-1)+f|0;e=(a>>>0>>0?l:a)+1|0;b=0;break n}b=f-e|0}o=f-1|0;n=f|63;g=0;a=h;while(1){o:{if(h-a>>>0>=f>>>0){break o}c=Vi(h,0,n);if(c){h=c;if(c-a>>>0>>0){break h}break o}h=h+n|0}d=H[a+o|0];c=f;p:{q:{if(!(G[(i+1024|0)+(d>>>3&28)>>2]>>>d&1)){break q}c=G[(d<<2)+i>>2];if((c|0)!=(f|0)){c=f-c|0;c=c>>>0>g>>>0?c:g;break q}r:{c=m;d=c>>>0>g>>>0?c:g;j=H[k+d|0];if(j){while(1){if(H[a+d|0]!=(j&255)){break r}d=d+1|0;j=H[k+d|0];if(j){continue}break}}while(1){if(c>>>0<=g>>>0){break g}c=c-1|0;if(H[k+c|0]==H[a+c|0]){continue}break}c=e;g=b;break p}c=d-l|0}g=0}a=a+c|0;continue}}a=0}Fa=i+1056|0;d=a}return d}function vm(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;g=L[a+288>>3]*c+L[a+280>>3];v=d;f=L[a+1088>>3]*b+L[a+1080>>3];d=G[a+276>>2];a:{if((d|0)==1){break a}g=L[a+296>>3]*b+g;f=L[a+1096>>3]*c+f;if((d|0)==2){break a}h=b*b;i=c*c;l=V(h+i);g=L[a+304>>3]*l+g;f=L[a+1104>>3]*l+f;if((d|0)==3){break a}g=L[a+312>>3]*i+g;f=L[a+1112>>3]*h+f;if((d|0)==4){break a}j=b*c;g=L[a+320>>3]*j+g;f=L[a+1120>>3]*j+f;if((d|0)==5){break a}g=L[a+328>>3]*h+g;f=L[a+1128>>3]*i+f;if((d|0)==6){break a}j=i*c;g=L[a+336>>3]*j+g;k=h*b;f=L[a+1136>>3]*k+f;if((d|0)==7){break a}g=i*L[a+344>>3]*b+g;f=h*L[a+1144>>3]*c+f;if((d|0)==8){break a}g=L[a+352>>3]*c*h+g;f=L[a+1152>>3]*b*i+f;if((d|0)==9){break a}g=L[a+360>>3]*k+g;f=L[a+1160>>3]*j+f;if((d|0)==10){break a}m=l*(l*l);g=L[a+368>>3]*m+g;f=L[a+1168>>3]*m+f;if((d|0)==11){break a}n=i*i;g=L[a+376>>3]*n+g;o=h*h;f=L[a+1176>>3]*o+f;if((d|0)==12){break a}g=j*L[a+384>>3]*b+g;f=k*L[a+1184>>3]*c+f;if((d|0)==13){break a}g=h*L[a+392>>3]*i+g;f=h*L[a+1192>>3]*i+f;if((d|0)==14){break a}g=L[a+400>>3]*c*k+g;f=L[a+1200>>3]*b*j+f;if((d|0)==15){break a}g=L[a+408>>3]*o+g;f=L[a+1208>>3]*n+f;if((d|0)==16){break a}p=n*c;g=L[a+416>>3]*p+g;q=o*b;f=L[a+1216>>3]*q+f;if((d|0)==17){break a}g=n*L[a+424>>3]*b+g;f=o*L[a+1224>>3]*c+f;if((d|0)==18){break a}g=j*L[a+432>>3]*h+g;f=k*L[a+1232>>3]*i+f;if((d|0)==19){break a}g=i*L[a+440>>3]*k+g;f=h*L[a+1240>>3]*j+f;if((d|0)==20){break a}g=L[a+448>>3]*c*o+g;f=L[a+1248>>3]*b*n+f;if((d|0)==21){break a}g=L[a+456>>3]*q+g;f=L[a+1256>>3]*p+f;if((d|0)==22){break a}s=l*(l*m);g=L[a+464>>3]*s+g;f=L[a+1264>>3]*s+f;if((d|0)==23){break a}m=p*c;g=L[a+472>>3]*m+g;r=q*b;f=L[a+1272>>3]*r+f;if((d|0)==24){break a}g=p*L[a+480>>3]*b+g;f=q*L[a+1280>>3]*c+f;if((d|0)==25){break a}g=n*L[a+488>>3]*h+g;f=o*L[a+1288>>3]*i+f;if((d|0)==26){break a}g=j*L[a+496>>3]*k+g;f=k*L[a+1296>>3]*j+f;if((d|0)==27){break a}g=i*L[a+504>>3]*o+g;f=h*L[a+1304>>3]*n+f;if((d|0)==28){break a}g=L[a+512>>3]*c*q+g;f=L[a+1312>>3]*b*p+f;if((d|0)==29){break a}g=L[a+520>>3]*r+g;f=L[a+1320>>3]*m+f;if((d|0)==30){break a}t=m*c;g=L[a+528>>3]*t+g;u=r*b;f=L[a+1328>>3]*u+f;if((d|0)==31){break a}g=m*L[a+536>>3]*b+g;f=r*L[a+1336>>3]*c+f;if((d|0)==32){break a}g=p*L[a+544>>3]*h+g;f=q*L[a+1344>>3]*i+f;if((d|0)==33){break a}g=n*L[a+552>>3]*k+g;f=o*L[a+1352>>3]*j+f;if((d|0)==34){break a}g=j*L[a+560>>3]*o+g;f=k*L[a+1360>>3]*n+f;if((d|0)==35){break a}g=i*L[a+568>>3]*q+g;f=h*L[a+1368>>3]*p+f;if((d|0)==36){break a}g=L[a+576>>3]*c*r+g;b=L[a+1376>>3]*b*m+f;f=b;if((d|0)==37){break a}g=L[a+584>>3]*u+g;b=L[a+1384>>3]*t+b;f=b;if((d|0)==38){break a}c=l*(l*s);g=L[a+592>>3]*c+g;f=L[a+1392>>3]*c+b}L[v>>3]=f;L[e>>3]=g}function Es(a,b,c,d,e,f,g,h,i,j,k){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;o=G[a+16>>2];b=G[a+8>>2]+M(c,168)|0;f=+G[a+24>>2];g=k-f;k=+G[a+32>>2];g=g/k+1;i=(i-f)/k+1;l=g>i;f=l?g:i;q=f+.5;a:{if(O(q)<2147483648){m=~~q;break a}m=-2147483648}L[b+16>>3]=m|0;g=l?i:g;i=g+.5;b:{if(O(i)<2147483648){m=~~i;break b}m=-2147483648}L[b+8>>3]=m|0;s=b,t=lb(G[a+48>>2]+1|0,4),G[s+24>>2]=t;Pf(a,c,d,e);i=h;h=+(o|0);i=(i-h)/k+1;h=(j-h)/k+1;k=l?i:h;h=l?h:i;i=g-f;c:{if(O(i)<=1e-15){b=G[(G[a+8>>2]+M(c,168)|0)+24>>2];l=G[a+48>>2];n=G[a+44>>2];p=lb(1,8);f=h>k?k:h;d:{if(O(f)<2147483648){m=~~f;break d}m=-2147483648}G[p+4>>2]=m;if(O(g)<2147483648){o=~~g}else{o=-2147483648}e:{if(!b){break e}n=(o|0)<(n|0)?n:o;n=(l|0)>(n|0)?n:l;l=b+(n<<2)|0;b=G[l>>2];f:{if(!b){b=0;break f}if((m|0)>2]){break f}while(1){l=b;b=G[b>>2];if(!b){b=0;break f}if((m|0)>G[b+4>>2]){continue}break}}G[p>>2]=b;G[l>>2]=p;if((e|0)==1){break e}if(d){b=n<<2;l=b+G[a+56>>2]|0;if((m|0)<=G[l>>2]){n=l;l=G[a+36>>2];G[n>>2]=(l|0)>(m|0)?l:m}b=b+G[a+60>>2]|0;if((m|0)>2]){break e}l=b;b=G[a+40>>2];G[l>>2]=(b|0)<(m|0)?b:m;break e}b=n<<2;G[b+G[a+56>>2]>>2]=G[a+36>>2];G[b+G[a+60>>2]>>2]=G[a+40>>2]}b=G[(G[a+8>>2]+M(c,168)|0)+24>>2];c=G[a+48>>2];m=G[a+44>>2];n=lb(1,8);f=h>2]=l;if(!b){break c}m=(m|0)>(o|0)?m:o;m=(c|0)>(m|0)?m:c;c=b+(m<<2)|0;b=G[c>>2];h:{if(!b){b=0;break h}if((l|0)>2]){break h}while(1){c=b;b=G[b>>2];if(!b){b=0;break h}if((l|0)>G[b+4>>2]){continue}break}}G[n>>2]=b;G[c>>2]=n;if((e|0)==1){break c}if(d){b=m<<2;c=b+G[a+56>>2]|0;if((l|0)<=G[c>>2]){d=c;c=G[a+36>>2];G[d>>2]=(c|0)>(l|0)?c:l}b=b+G[a+60>>2]|0;if((l|0)>2]){break c}a=G[a+40>>2];G[b>>2]=(a|0)<(l|0)?a:l;return}b=m<<2;G[b+G[a+56>>2]>>2]=G[a+36>>2];G[b+G[a+60>>2]>>2]=G[a+40>>2];return}if(O(g)<2147483648){l=~~g}else{l=-2147483648}if(!(+(l|0)<=f)){break c}p=M(c,168);if(!G[(p+G[a+8>>2]|0)+24>>2]){break c}g=(k-h)/i;while(1){b=G[(p+G[a+8>>2]|0)+24>>2];c=G[a+48>>2];o=G[a+44>>2];n=lb(1,8);if(O(k)<2147483648){m=~~k}else{m=-2147483648}G[n+4>>2]=m;i:{if(!b){break i}r=b;b=(l|0)<(o|0)?o:l;o=((b|0)<(c|0)?b:c)<<2;c=r+o|0;b=G[c>>2];j:{if(!b){b=0;break j}if((m|0)>2]){break j}while(1){c=b;b=G[b>>2];if(!b){b=0;break j}if((m|0)>G[b+4>>2]){continue}break}}G[n>>2]=b;G[c>>2]=n;if((e|0)==1){break i}if(d){b=o+G[a+56>>2]|0;if((m|0)<=G[b>>2]){c=b;b=G[a+36>>2];G[c>>2]=(b|0)>(m|0)?b:m}b=o+G[a+60>>2]|0;if((m|0)>2]){break i}c=b;b=G[a+40>>2];G[c>>2]=(b|0)<(m|0)?b:m;break i}G[o+G[a+56>>2]>>2]=G[a+36>>2];G[o+G[a+60>>2]>>2]=G[a+40>>2]}k=g+k;l=l+1|0;if(f>=+(l|0)){continue}break}}}function yt(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0;d=Fa-1040|0;Fa=d;a:{b:{if(!ce(b,0,d+1036|0)){break b}if(Va(b)>>>0>1020){break a}g=Za(d,b);e=Va(b)+b|0;E[e|0]=46;E[e+1|0]=103;E[e+2|0]=122;E[e+3|0]=0;if(!ce(b,0,d+1036|0)){break b}b=Za(b,g);e=Va(b)+b|0;f=H[32688]|H[32689]<<8;E[e|0]=f;E[e+1|0]=f>>>8;E[e+2|0]=H[32690];if(!ce(b,0,d+1036|0)){break b}b=Za(b,g);e=Va(b)+b|0;f=H[2803]|H[2804]<<8;E[e|0]=f;E[e+1|0]=f>>>8;E[e+2|0]=H[2805];if(!ce(b,0,d+1036|0)){break b}e=Za(b,g);b=Va(e)+e|0;f=H[13365]|H[13366]<<8|(H[13367]<<16|H[13368]<<24);E[b|0]=f;E[b+1|0]=f>>>8;E[b+2|0]=f>>>16;E[b+3|0]=f>>>24;E[b+4|0]=H[13369];if(!ce(e,0,d+1036|0)){break b}b=Za(e,g);e=Va(b)+b|0;f=H[2806]|H[2807]<<8;E[e|0]=f;E[e+1|0]=f>>>8;E[e+2|0]=H[2808];if(!ce(b,0,d+1036|0)){break b}b=Za(b,g);e=Va(b)+b|0;E[e|0]=45;E[e+1|0]=103;E[e+2|0]=122;E[e+3|0]=0;if(!ce(b,0,d+1036|0)){break b}Za(b,g);break a}b=G[d+1036>>2];g=zc(d+1034|0,1,2,b);Hb(b);if((g|0)!=2){break a}if((H[d+1034|0]|H[d+1035|0]<<8)==35615){h=1;break a}if((H[d+1034|0]|H[d+1035|0]<<8)==19280){h=1;break a}if((H[d+1034|0]|H[d+1035|0]<<8)==7711){h=1;break a}h=1;if((H[d+1034|0]|H[d+1035|0]<<8)==40223){break a}h=(H[d+1034|0]|H[d+1035|0]<<8)==40991}Fa=d+1040|0;b=H[c|0];if(h){if(b){if(!fb(c,37360,4)){b=H[42077]|H[42078]<<8|(H[42079]<<16|H[42080]<<24);c=H[42073]|H[42074]<<8|(H[42075]<<16|H[42076]<<24);E[a+7|0]=c;E[a+8|0]=c>>>8;E[a+9|0]=c>>>16;E[a+10|0]=c>>>24;E[a+11|0]=b;E[a+12|0]=b>>>8;E[a+13|0]=b>>>16;E[a+14|0]=b>>>24;b=H[42070]|H[42071]<<8|(H[42072]<<16|H[42073]<<24);c=H[42066]|H[42067]<<8|(H[42068]<<16|H[42069]<<24);E[a|0]=c;E[a+1|0]=c>>>8;E[a+2|0]=c>>>16;E[a+3|0]=c>>>24;E[a+4|0]=b;E[a+5|0]=b>>>8;E[a+6|0]=b>>>16;E[a+7|0]=b>>>24;E[442496]=0;return 0}b=H[42153]|H[42154]<<8|(H[42155]<<16|H[42156]<<24);d=H[42149]|H[42150]<<8|(H[42151]<<16|H[42152]<<24);E[a+8|0]=d;E[a+9|0]=d>>>8;E[a+10|0]=d>>>16;E[a+11|0]=d>>>24;E[a+12|0]=b;E[a+13|0]=b>>>8;E[a+14|0]=b>>>16;E[a+15|0]=b>>>24;b=H[42145]|H[42146]<<8|(H[42147]<<16|H[42148]<<24);d=H[42141]|H[42142]<<8|(H[42143]<<16|H[42144]<<24);E[a|0]=d;E[a+1|0]=d>>>8;E[a+2|0]=d>>>16;E[a+3|0]=d>>>24;E[a+4|0]=b;E[a+5|0]=b>>>8;E[a+6|0]=b>>>16;E[a+7|0]=b>>>24;if(!fb(c,42185,7)){Za(442496,c+7|0);return 0}Za(442496,c);return 0}b=H[42021]|H[42022]<<8|(H[42023]<<16|H[42024]<<24);E[a+8|0]=b;E[a+9|0]=b>>>8;E[a+10|0]=b>>>16;E[a+11|0]=b>>>24;b=H[42017]|H[42018]<<8|(H[42019]<<16|H[42020]<<24);c=H[42013]|H[42014]<<8|(H[42015]<<16|H[42016]<<24);E[a|0]=c;E[a+1|0]=c>>>8;E[a+2|0]=c>>>16;E[a+3|0]=c>>>24;E[a+4|0]=b;E[a+5|0]=b>>>8;E[a+6|0]=b>>>16;E[a+7|0]=b>>>24;E[442496]=0;return 0}if(b){E[442496]=0;qb(442496,c,1024)}return 0}function tf(a,b,c,d,e,f,g,h,i,j,k,l){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;l=+l;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;if(j==k){Gj(a,c,c,d,e,l,l,h,i,j);return}f=k;k=+G[a+32>>2];f=f/k;t=(i-+G[a+24>>2])/k+1;if(l>=360){while(1){l=l+-360;if(l>=360){continue}break}}u=G[a+16>>2];l=l/180*3.141592653589793;g=eb(l);i=j/k;j=ib(l);l=O(i*j)+O(f*g);q=f>i?f:i;q=l(o|0)){s=G[a+8>>2];m=G[a+44>>2];L[(s+M(c,168)|0)+8>>3]=((m|0)>(o|0)?m:o)|0;m=G[a+48>>2];o=(p|0)>(m|0);b=o?m:b;b=o?b:r?n:b;break c}m=G[a+48>>2];p=(p|0)>(m|0);s=G[a+8>>2];b=p?m:b;L[(s+M(c,168)|0)+8>>3]=(p?b:r?n:b)|0;b=G[a+44>>2];b=(b|0)>(o|0)?b:o}o=M(c,168);n=o+s|0;L[n+16>>3]=b|0;r=lb(m+1|0,4);G[n+24>>2]=r;Pf(a,c,d,e);b=o+G[a+8>>2]|0;q=L[b+16>>3];l=L[b+8>>3];d:{if(O(l)<2147483648){o=~~l;break d}o=-2147483648}l=+(o|0);if(q>=l){q=(h-+(u|0))/k+1;k=j*j;h=i*i;i=g*g;f=f*f;v=k/h+i/f;w=(j+j)*(g/h-g/f);g=i/h+k/f;x=g*-4;u=O(g)<=1e-15;y=M(c,168);while(1){f=l-t;h=v*f*f+-1;f=w*f;e:{f:{g:{h:{if(u){if(O(f)<=1e-15){break e}j=-h/f;break h}i=f*f+x*h;if(i>0){j=h;h=V(i);f=(f+(f<0?-h:h))*-.5;j=j/f;k=j;l=f/g;if(l>j){break g}break f}if(!(O(i)<=1e-15)){break e}j=f*-.5/g}l=j}k=l;l=j}c=G[a+48>>2];p=G[a+44>>2];s=lb(1,8);f=q+l;i:{if(O(f)<2147483648){m=~~f;break i}m=-2147483648}n=m+1|0;G[s+4>>2]=n;j:{if(!r){break j}b=(p|0)>(o|0)?p:o;p=((b|0)<(c|0)?b:c)<<2;b=p+r|0;c=G[b>>2];k:{if(!c){c=0;break k}if((n|0)>2]){break k}while(1){b=c;c=G[b>>2];if(!c){c=0;break k}if((m|0)>=G[c+4>>2]){continue}break}}G[s>>2]=c;G[b>>2]=s;if((e|0)==1){break j}if(d){b=p+G[a+56>>2]|0;if((m|0)>2]){c=b;b=G[a+36>>2];G[c>>2]=(b|0)>(n|0)?b:n}b=p+G[a+60>>2]|0;if((n|0)>2]){break j}c=b;b=G[a+40>>2];G[c>>2]=(b|0)<(n|0)?b:n;break j}G[p+G[a+56>>2]>>2]=G[a+36>>2];G[p+G[a+60>>2]>>2]=G[a+40>>2]}c=G[a+48>>2];n=G[a+44>>2];p=lb(1,8);f=q+k;l:{if(O(f)<2147483648){b=~~f;break l}b=-2147483648}m=b-(f==+(b|0))|0;G[p+4>>2]=m;if(!r){break e}b=(n|0)>(o|0)?n:o;n=((b|0)<(c|0)?b:c)<<2;b=n+r|0;c=G[b>>2];m:{if(!c){c=0;break m}if((m|0)>2]){break m}while(1){b=c;c=G[b>>2];if(!c){c=0;break m}if((m|0)>G[c+4>>2]){continue}break}}G[p>>2]=c;G[b>>2]=p;if((e|0)==1){break e}if(d){b=n+G[a+56>>2]|0;if((m|0)<=G[b>>2]){c=b;b=G[a+36>>2];G[c>>2]=(b|0)>(m|0)?b:m}b=n+G[a+60>>2]|0;if((m|0)>2]){break e}c=b;b=G[a+40>>2];G[c>>2]=(b|0)<(m|0)?b:m;break e}G[n+G[a+56>>2]>>2]=G[a+36>>2];G[n+G[a+60>>2]>>2]=G[a+40>>2]}o=o+1|0;l=+(o|0);if(l<=L[(G[a+8>>2]+y|0)+16>>3]){continue}break}}}function Hk(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;a:{if(G[k>>2]>0){break a}b:{m=G[a>>2];l=G[a+4>>2];if((m|0)!=G[l+76>>2]){mb(a,m+1|0,0,k);break b}if((G[l+128>>2]&G[l+132>>2])!=-1){break b}if((Rb(a,k)|0)<=0){break b}return}l=G[G[a+4>>2]+968>>2]+M(b-1|0,160)|0;x=G[l+80>>2];c:{if((x|0)<=0){d:{if((x|0)>=0){break d}if((Ff(a,b,c,d,e,f,g,h,i,k)|0)<=0){break d}if(G[k>>2]!=412){break a}G[k>>2]=0}if(!g&(h|0)<=0|(h|0)<0){break a}l=f+h|0;m=e+g|0;l=m>>>0>>0?l+1|0:l;n=m-1|0;l=l-!m|0;s=x-1>>>0<4294967213;m=s;if((m&63)>>>0>=32){l=n<>>32-m|l<>>0>>0?l+1|0:l;e=0;f=0;c=0;d=0;while(1){e:{if(L[(r<<3)+i>>3]==j){l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0;break e}if(e|f){l=s+(o-((e>>>0>r>>>0)+f|0)|0)|0;p=m+(r-e|0)|0;l=p>>>0>>0?l+1|0:l;u=l;t=Bu(p-1|0,l-!p|0,q,n);l=Ia;w=l;v=t+1|0;l=v?l:l+1|0;y=l;l=Au(q,n,t,w);if((Og(a,b,v,y,p-l|0,u-(Ia+(l>>>0>p>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;l=d;c=c+1|0;l=c?l:l+1|0;d=l}l=o;o=r+1|0;l=o?l:l+1|0;r=o;o=l;if((g|0)!=(r|0)|(h|0)!=(l|0)){continue}break}break c}if(!g&(h|0)<=0|(h|0)<0){break a}s=G[l+92>>2];n=G[l+88>>2];l=x>>>0>82;m=l;if((l&63)>>>0>=32){l=n<>>32-m|s<>>0>>0?l+1|0:l;e=0;f=0;c=0;d=0;while(1){f:{if(L[(r<<3)+i>>3]!=j){if(e|f){l=s+(o-((e>>>0>r>>>0)+f|0)|0)|0;p=m+(r-e|0)|0;l=p>>>0>>0?l+1|0:l;u=l;t=Bu(p-1|0,l-!p|0,q,n);l=Ia;w=l;v=t+1|0;l=v?l:l+1|0;y=l;l=Au(q,n,t,w);if((Og(a,b,v,y,p-l|0,u-(Ia+(l>>>0>p>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;l=d;c=c+1|0;l=c?l:l+1|0;d=l;break f}g:{if(!(c|d)){break g}l=s+(o-((c>>>0>r>>>0)+d|0)|0)|0;w=r-c|0;p=m+w|0;l=p>>>0>>0?l+1|0:l;u=l;t=Bu(p-1|0,l-!p|0,q,n);l=Ia;v=l;z=t+1|0;l=z?l:l+1|0;y=l;l=Au(q,n,t,v);if((Ff(a,b,z,y,p-l|0,u-(Ia+(l>>>0>p>>>0)|0)|0,c,d,(w<<3)+i|0,k)|0)<=0){break g}if(G[k>>2]!=412){break a}G[k>>2]=0;A=1}l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0}l=o;o=r+1|0;l=o?l:l+1|0;r=o;o=l;if((g|0)!=(r|0)|(h|0)!=(l|0)){continue}break}}h:{if(c|d){if((x|0)<=0){break h}e=a;l=s+(h-((c>>>0>g>>>0)+d|0)|0)|0;o=g-c|0;a=m+o|0;l=a>>>0>>0?l+1|0:l;f=l;g=Bu(a-1|0,l-!a|0,q,n);l=Ia;h=l;m=b;b=g+1|0;l=b?l:l+1|0;u=b;b=Au(q,n,g,h);Ff(e,m,u,l,a-b|0,f-(Ia+(a>>>0>>0)|0)|0,c,d,(o<<3)+i|0,k);break h}if(!(e|f)){break h}c=a;l=s+(h-((e>>>0>g>>>0)+f|0)|0)|0;a=m+(g-e|0)|0;l=a>>>0>>0?l+1|0:l;d=l;g=Bu(a-1|0,l-!a|0,q,n);l=Ia;h=l;i=b;b=g+1|0;l=b?l:l+1|0;o=b;b=Au(g,h,q,n);Og(c,i,o,l,a-b|0,d-(Ia+(a>>>0>>0)|0)|0,e,f,k)}if(!A|G[k>>2]>0){break a}G[k>>2]=412}}function Dk(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;a:{if(G[k>>2]>0){break a}b:{m=G[a>>2];l=G[a+4>>2];if((m|0)!=G[l+76>>2]){mb(a,m+1|0,0,k);break b}if((G[l+128>>2]&G[l+132>>2])!=-1){break b}if((Rb(a,k)|0)<=0){break b}return}l=G[G[a+4>>2]+968>>2]+M(b-1|0,160)|0;x=G[l+80>>2];c:{if((x|0)<=0){d:{if((x|0)>=0){break d}if((Kg(a,b,c,d,e,f,g,h,i,k)|0)<=0){break d}if(G[k>>2]!=412){break a}G[k>>2]=0}if(!g&(h|0)<=0|(h|0)<0){break a}l=f+h|0;m=e+g|0;l=m>>>0>>0?l+1|0:l;n=m-1|0;l=l-!m|0;s=x-1>>>0<4294967213;m=s;if((m&63)>>>0>=32){l=n<>>32-m|l<>>0>>0?l+1|0:l;e=0;f=0;c=0;d=0;while(1){e:{if(K[(r<<2)+i>>2]==j){l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0;break e}if(e|f){l=s+(o-((e>>>0>r>>>0)+f|0)|0)|0;p=m+(r-e|0)|0;l=p>>>0>>0?l+1|0:l;u=l;t=Bu(p-1|0,l-!p|0,q,n);l=Ia;w=l;v=t+1|0;l=v?l:l+1|0;y=l;l=Au(q,n,t,w);if((Og(a,b,v,y,p-l|0,u-(Ia+(l>>>0>p>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;l=d;c=c+1|0;l=c?l:l+1|0;d=l}l=o;o=r+1|0;l=o?l:l+1|0;r=o;o=l;if((g|0)!=(r|0)|(h|0)!=(l|0)){continue}break}break c}if(!g&(h|0)<=0|(h|0)<0){break a}s=G[l+92>>2];n=G[l+88>>2];l=x>>>0>82;m=l;if((l&63)>>>0>=32){l=n<>>32-m|s<>>0>>0?l+1|0:l;e=0;f=0;c=0;d=0;while(1){f:{if(K[(r<<2)+i>>2]!=j){if(e|f){l=s+(o-((e>>>0>r>>>0)+f|0)|0)|0;p=m+(r-e|0)|0;l=p>>>0>>0?l+1|0:l;u=l;t=Bu(p-1|0,l-!p|0,q,n);l=Ia;w=l;v=t+1|0;l=v?l:l+1|0;y=l;l=Au(q,n,t,w);if((Og(a,b,v,y,p-l|0,u-(Ia+(l>>>0>p>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;l=d;c=c+1|0;l=c?l:l+1|0;d=l;break f}g:{if(!(c|d)){break g}l=s+(o-((c>>>0>r>>>0)+d|0)|0)|0;w=r-c|0;p=m+w|0;l=p>>>0>>0?l+1|0:l;u=l;t=Bu(p-1|0,l-!p|0,q,n);l=Ia;v=l;z=t+1|0;l=z?l:l+1|0;y=l;l=Au(q,n,t,v);if((Kg(a,b,z,y,p-l|0,u-(Ia+(l>>>0>p>>>0)|0)|0,c,d,(w<<2)+i|0,k)|0)<=0){break g}if(G[k>>2]!=412){break a}G[k>>2]=0;A=1}l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0}l=o;o=r+1|0;l=o?l:l+1|0;r=o;o=l;if((g|0)!=(r|0)|(h|0)!=(l|0)){continue}break}}h:{if(c|d){if((x|0)<=0){break h}e=a;l=s+(h-((c>>>0>g>>>0)+d|0)|0)|0;o=g-c|0;a=m+o|0;l=a>>>0>>0?l+1|0:l;f=l;g=Bu(a-1|0,l-!a|0,q,n);l=Ia;h=l;m=b;b=g+1|0;l=b?l:l+1|0;u=b;b=Au(q,n,g,h);Kg(e,m,u,l,a-b|0,f-(Ia+(a>>>0>>0)|0)|0,c,d,(o<<2)+i|0,k);break h}if(!(e|f)){break h}c=a;l=s+(h-((e>>>0>g>>>0)+f|0)|0)|0;a=m+(g-e|0)|0;l=a>>>0>>0?l+1|0:l;d=l;g=Bu(a-1|0,l-!a|0,q,n);l=Ia;h=l;i=b;b=g+1|0;l=b?l:l+1|0;o=b;b=Au(g,h,q,n);Og(c,i,o,l,a-b|0,d-(Ia+(a>>>0>>0)|0)|0,e,f,k)}if(!A|G[k>>2]>0){break a}G[k>>2]=412}}function Xt(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;c=a;a=0;g=Fa-16|0;Fa=g;F[g+8>>1]=0;G[g>>2]=0;G[g+4>>2]=0;a:{if(!b){break a}f=9;d=H[b|0];if(d){while(1){a=0;b:{c:{d:{e:{f:{d=d<<24>>24;switch(d-114|0){case 0:break b;case 1:break e;case 5:break f;default:break d}}a=1;break b}h=1;break c}a=d-48|0;f=a>>>0<10?a:f}a=e}d=H[b+1|0];b=b+1|0;e=a;if(d){continue}break}}b=Va(g)+g|0;e=a?119:114;E[b|0]=e;E[b+1|0]=e>>>8;b=Va(g)+g|0;E[b|0]=98;E[b+1|0]=0;if(H[c|0]?c:0){b=ac(c,g)}else{b=G[(a?119052:120240)>>2]}if(!b){d=0;break a}g:{h:{if(a){if(G[b+76>>2]<0){a=G[b>>2]}else{a=G[b>>2]}if(a>>>5&1){break g}d=ab(5068);if(!d){break g}E[d+5064|0]=0;G[d+5004>>2]=0;E[d+5008|0]=1;G[d>>2]=b;a=d+5056|0;G[a>>2]=0;G[a+4>>2]=0;a=d+5048|0;G[a>>2]=0;G[a+4>>2]=0;c=d+5012|0;a=(f|0)>1?f:1;f=a>>>0<9?a:9;e=-2;i:{if(!c|f-10>>>0<4294967287){break i}a=G[c+36>>2];if(!a){G[c+36>>2]=174;a=174}if(!G[c+40>>2]){G[c+40>>2]=175}a=Ja[a|0](G[c+44>>2],55728,1)|0;e=-3;if(!a){break i}G[a+24>>2]=0;G[a+16>>2]=0;G[a+20>>2]=0;G[a>>2]=c;e=M(f,4e5);j=a,k=Ja[G[c+36>>2]](G[c+44>>2],e,1)|0,G[j+16>>2]=k;j=a,k=Ja[G[c+36>>2]](G[c+44>>2],e+136|0,1)|0,G[j+20>>2]=k;e=Ja[G[c+36>>2]](G[c+44>>2],262148,1)|0;G[a+24>>2]=e;j:{h=G[a+16>>2];if(h){i=G[a+20>>2];if(e?i:0){break j}Ja[G[c+40>>2]](G[c+44>>2],h)}e=G[a+20>>2];if(e){Ja[G[c+40>>2]](G[c+44>>2],e)}e=G[a+24>>2];if(e){Ja[G[c+40>>2]](G[c+44>>2],e)}Ja[G[c+40>>2]](G[c+44>>2],a);e=-3;break i}G[a+624>>2]=f;G[a+612>>2]=0;G[a+4>>2]=2;G[a+8>>2]=2;G[a+616>>2]=0;G[a+48>>2]=30;G[a+44>>2]=0;G[a+40>>2]=h;G[a+36>>2]=i;G[a+32>>2]=h;G[a+72>>2]=M(f,1e5)-19;G[c+8>>2]=0;G[c+12>>2]=0;G[c+24>>2]=0;G[c+28>>2]=0;G[c+32>>2]=a;G[a+608>>2]=-1;G[a+76>>2]=0;G[a+80>>2]=0;G[a+68>>2]=0;G[a+52>>2]=256;G[a+56>>2]=0;cb(a+88|0,0,256);G[a+620>>2]=1;e=0}if(e){break h}E[d+5064|0]=1;G[d+5016>>2]=0;break a}if(G[b+76>>2]<0){a=G[b>>2]}else{a=G[b>>2]}if(a>>>5&1){break g}d=ab(5068);if(!d){break g}E[d+5064|0]=0;E[d+5008|0]=0;G[d+5004>>2]=0;G[d>>2]=b;a=d+5056|0;G[a>>2]=0;G[a+4>>2]=0;a=d+5048|0;G[a>>2]=0;G[a+4>>2]=0;a=-2;f=d+5012|0;k:{if(!(!f|h>>>0>1)){a=G[f+36>>2];if(!a){G[f+36>>2]=174;a=174}if(!G[f+40>>2]){G[f+40>>2]=175}c=Ja[a|0](G[f+44>>2],64116,1)|0;a=-3;if(!c){break k}G[c>>2]=f;G[f+32>>2]=c;G[c+4>>2]=10;G[c+3172>>2]=0;G[c+28>>2]=0;G[c+32>>2]=0;G[f+24>>2]=0;G[f+28>>2]=0;G[f+8>>2]=0;G[f+12>>2]=0;G[c+3156>>2]=0;E[c+40|0]=h;G[c+3148>>2]=0;G[c+3152>>2]=0;G[c+48>>2]=0;G[c+44>>2]=0;a=0}}if(a){break h}E[d+5064|0]=1;G[d+5016>>2]=G[d+5004>>2];G[d+5012>>2]=d+4;break a}Wa(d)}d=0;if((b|0)==G[30060]|(b|0)==G[29763]){break a}Hb(b)}Fa=g+16|0;return d|0}function Jc(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=N(0);k=G[f>>2];if((k|0)<=0){a:{b:{c:{switch(b-11|0){case 5:if((gj(a,c,d,e,f)|0)!=202){break a}G[f>>2]=k;lc(a,c,d,e,f);break a;case 0:Gc(a,c,H[d|0],0,e,f);break a;case 1:b=a;a=E[d|0];Gc(b,c,a,a>>31,e,f);break a;case 9:Gc(a,c,I[d>>1],0,e,f);break a;case 10:b=a;a=F[d>>1];Gc(b,c,a,a>>31,e,f);break a;case 20:b=a;a=G[d>>2];Gc(b,c,a,a>>31,e,f);break a;case 19:Sl(a,c,+J[d>>2],e,f);break a;case 3:Kh(a,c,G[d>>2],e,f);break a;case 29:Sl(a,c,+J[d>>2],e,f);break a;case 30:b=a;a=G[d>>2];Gc(b,c,a,a>>31,e,f);break a;case 70:Gc(a,c,G[d>>2],G[d+4>>2],e,f);break a;case 31:l=K[d>>2];d=Fa-256|0;Fa=d;g=G[f>>2];d:{if((g|0)>0){break d}if((Vc(a,c,d+176|0,d+96|0,f)|0)<=0){b=d+176|0;hg(l,-7,b,f);Ob(c,b,e?H[e|0]==38?d+96|0:e:d+96|0,d,f);Hd(a,d,f)}if(G[f>>2]!=202){break d}G[f>>2]=g;Qg(a,c,l,-7,e,f)}Fa=d+256|0;break a;case 71:Kd(a,c,L[d>>3],-15,e,f);break a;case 72:g=Fa-336|0;Fa=g;b=G[f>>2];e:{if((b|0)>0){break e}f:{if((Vc(a,c,g+256|0,g+96|0,f)|0)<=0){F[g+256>>1]=40;b=g+176|0;hg(K[d>>2],-7,b,f);if(Va(b)-68>>>0<=4294967224){break f}h=g+176|0;b=Gb(g+256|0,h);i=Va(b)+b|0;j=H[67812]|H[67813]<<8;E[i|0]=j;E[i+1|0]=j>>>8;E[i+2|0]=H[67814];hg(K[d+4>>2],-7,h,f);if((Va(b)+Va(h)|0)-70>>>0<=4294967224){break f}b=Gb(b,g+176|0);h=Va(b)+b|0;E[h|0]=41;E[h+1|0]=0;Ob(c,b,e?H[e|0]==38?g+96|0:e:g+96|0,g,f);Hd(a,g,f)}b=G[f>>2];break e}Ua(62685);b=402;G[f>>2]=402}Fa=g+336|0;if((b|0)!=202){break a}G[f>>2]=k;pq(a,c,d,e,f);break a;default:if((b|0)==163){break b}break;case 2:case 4:case 6:case 7:case 8:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 32:case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 65:case 66:case 67:case 68:case 69:break c}}G[f>>2]=410;break a}g=Fa-336|0;Fa=g;b=G[f>>2];g:{if((b|0)>0){break g}h:{if((Vc(a,c,g+256|0,g+96|0,f)|0)<=0){F[g+256>>1]=40;b=g+176|0;If(L[d>>3],-15,b,f);if(Va(b)-68>>>0<=4294967224){break h}h=g+176|0;b=Gb(g+256|0,h);i=Va(b)+b|0;j=H[67812]|H[67813]<<8;E[i|0]=j;E[i+1|0]=j>>>8;E[i+2|0]=H[67814];If(L[d+8>>3],-15,h,f);if((Va(b)+Va(h)|0)-70>>>0<=4294967224){break h}b=Gb(b,g+176|0);h=Va(b)+b|0;E[h|0]=41;E[h+1|0]=0;Ob(c,b,e?H[e|0]==38?g+96|0:e:g+96|0,g,f);Hd(a,g,f)}b=G[f>>2];break g}Ua(56403);b=402;G[f>>2]=402}Fa=g+336|0;if((b|0)!=202){break a}G[f>>2]=k;oq(a,c,d,e,f)}}}function Uk(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0;l=c==1&d==2147483648;a:{b:{if(!e){if(l){if((b|0)<=0){break a}f=0;if(b-1>>>0>=3){g=b&-4;i=0;while(1){e=f<<2;G[e+j>>2]=G[a+e>>2]^-2147483648;h=e|4;G[h+j>>2]=G[a+h>>2]^-2147483648;h=e|8;G[h+j>>2]=G[a+h>>2]^-2147483648;e=e|12;G[e+j>>2]=G[a+e>>2]^-2147483648;f=f+4|0;i=i+4|0;if((g|0)!=(i|0)){continue}break}}b=b&3;if(!b){break a}while(1){e=f<<2;G[e+j>>2]=G[a+e>>2]^-2147483648;f=f+1|0;m=m+1|0;if((b|0)!=(m|0)){continue}break}break a}if(c==1&d==0){break b}f=0;if((b|0)<=0){break a}while(1){c:{d:{g=f<<2;n=+G[g+a>>2]*c+d;if(n<-.49){G[k>>2]=-11;break d}if(n>0xfffffffffffff800){G[k>>2]=-11;e=-1;break c}if(!(n<4294967296&n>=0)){break d}e=~~n>>>0;break c}e=0}G[g+j>>2]=e;f=f+1|0;if((f|0)!=(b|0)){continue}break}break a}e:{f:{g:{if(l){if((b|0)<=0){break a}if((e|0)==1){break e}e=b&1;if((b|0)!=1){g=b&-2;b=0;while(1){k=m<<2;l=G[k+a>>2];h:{if((l|0)==(f|0)){G[i>>2]=1;E[h+m|0]=1;break h}G[j+k>>2]=l^-2147483648}k=m|1;l=k<<2;o=G[l+a>>2];i:{if((o|0)!=(f|0)){G[j+l>>2]=o^-2147483648;break i}G[i>>2]=1;E[h+k|0]=1}m=m+2|0;b=b+2|0;if((g|0)!=(b|0)){continue}break}}if(!e){break a}b=a;a=m<<2;b=G[b+a>>2];if((b|0)==(f|0)){break g}G[a+j>>2]=b^-2147483648;break a}if(c==1&d==0){break f}if((b|0)<=0){break a}while(1){l=m<<2;o=G[l+a>>2];j:{if((o|0)==(f|0)){G[i>>2]=1;if((e|0)==1){G[j+l>>2]=g;break j}E[h+m|0]=1;break j}n=+(o|0)*c+d;if(n<-.49){G[k>>2]=-11;G[j+l>>2]=0;break j}if(n>0xfffffffffffff800){G[k>>2]=-11;G[j+l>>2]=-1;break j}o=j+l|0;if(n<4294967296&n>=0){l=~~n>>>0}else{l=0}G[o>>2]=l}m=m+1|0;if((m|0)!=(b|0)){continue}break}break a}G[i>>2]=1;E[h+m|0]=1;break a}if((b|0)<=0){break a}while(1){l=m<<2;o=G[l+a>>2];k:{if((o|0)==(f|0)){G[i>>2]=1;if((e|0)==1){G[j+l>>2]=g;break k}E[h+m|0]=1;break k}if((o|0)<0){G[k>>2]=-11;G[j+l>>2]=0;break k}G[j+l>>2]=o}m=m+1|0;if((m|0)!=(b|0)){continue}break}break a}h=b&1;if((b|0)!=1){k=b&-2;b=0;while(1){l=m<<2;e=G[l+a>>2];l:{if((e|0)!=(f|0)){e=e^-2147483648;break l}G[i>>2]=1;e=g}G[j+l>>2]=e;l=(m|1)<<2;e=G[l+a>>2];m:{if((e|0)!=(f|0)){e=e^-2147483648;break m}G[i>>2]=1;e=g}G[j+l>>2]=e;m=m+2|0;b=b+2|0;if((k|0)!=(b|0)){continue}break}}if(!h){break a}a=G[(m<<2)+a>>2];n:{if((a|0)!=(f|0)){g=a^-2147483648;break n}G[i>>2]=1}G[(m<<2)+j>>2]=g;break a}if((b|0)<=0){break a}e=b&1;f=0;if((b|0)!=1){g=b&-2;while(1){h=f<<2;b=G[h+a>>2];if((b|0)<0){G[k>>2]=-11;b=0}G[h+j>>2]=b;h=(f|1)<<2;b=G[h+a>>2];if((b|0)<0){G[k>>2]=-11;b=0}G[h+j>>2]=b;f=f+2|0;m=m+2|0;if((g|0)!=(m|0)){continue}break}}if(!e){break a}b=f<<2;a=G[b+a>>2];if((a|0)<0){G[k>>2]=-11;a=0}G[b+j>>2]=a}}function yp(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0;l=c==1&d==2147483648;a:{b:{if(!e){if(l){if((b|0)<=0){break a}f=0;if(b-1>>>0>=3){g=b&-4;i=0;while(1){e=f<<2;G[e+j>>2]=G[a+e>>2]^-2147483648;h=e|4;G[h+j>>2]=G[a+h>>2]^-2147483648;h=e|8;G[h+j>>2]=G[a+h>>2]^-2147483648;e=e|12;G[e+j>>2]=G[a+e>>2]^-2147483648;f=f+4|0;i=i+4|0;if((g|0)!=(i|0)){continue}break}}b=b&3;if(!b){break a}while(1){e=f<<2;G[e+j>>2]=G[a+e>>2]^-2147483648;f=f+1|0;m=m+1|0;if((b|0)!=(m|0)){continue}break}break a}if(c==1&d==0){break b}f=0;if((b|0)<=0){break a}while(1){c:{d:{g=f<<2;n=+G[g+a>>2]*c+d;if(n<-.49){G[k>>2]=-11;break d}if(n>4294967295.49){G[k>>2]=-11;e=-1;break c}if(!(n<4294967296&n>=0)){break d}e=~~n>>>0;break c}e=0}G[g+j>>2]=e;f=f+1|0;if((f|0)!=(b|0)){continue}break}break a}e:{f:{g:{if(l){if((b|0)<=0){break a}if((e|0)==1){break e}e=b&1;if((b|0)!=1){g=b&-2;b=0;while(1){k=m<<2;l=G[k+a>>2];h:{if((l|0)==(f|0)){G[i>>2]=1;E[h+m|0]=1;break h}G[j+k>>2]=l^-2147483648}k=m|1;l=k<<2;o=G[l+a>>2];i:{if((o|0)!=(f|0)){G[j+l>>2]=o^-2147483648;break i}G[i>>2]=1;E[h+k|0]=1}m=m+2|0;b=b+2|0;if((g|0)!=(b|0)){continue}break}}if(!e){break a}b=a;a=m<<2;b=G[b+a>>2];if((b|0)==(f|0)){break g}G[a+j>>2]=b^-2147483648;break a}if(c==1&d==0){break f}if((b|0)<=0){break a}while(1){l=m<<2;o=G[l+a>>2];j:{if((o|0)==(f|0)){G[i>>2]=1;if((e|0)==1){G[j+l>>2]=g;break j}E[h+m|0]=1;break j}n=+(o|0)*c+d;if(n<-.49){G[k>>2]=-11;G[j+l>>2]=0;break j}if(n>4294967295.49){G[k>>2]=-11;G[j+l>>2]=-1;break j}o=j+l|0;if(n<4294967296&n>=0){l=~~n>>>0}else{l=0}G[o>>2]=l}m=m+1|0;if((m|0)!=(b|0)){continue}break}break a}G[i>>2]=1;E[h+m|0]=1;break a}if((b|0)<=0){break a}while(1){l=m<<2;o=G[l+a>>2];k:{if((o|0)==(f|0)){G[i>>2]=1;if((e|0)==1){G[j+l>>2]=g;break k}E[h+m|0]=1;break k}if((o|0)<0){G[k>>2]=-11;G[j+l>>2]=0;break k}G[j+l>>2]=o}m=m+1|0;if((m|0)!=(b|0)){continue}break}break a}h=b&1;if((b|0)!=1){k=b&-2;b=0;while(1){l=m<<2;e=G[l+a>>2];l:{if((e|0)!=(f|0)){e=e^-2147483648;break l}G[i>>2]=1;e=g}G[j+l>>2]=e;l=(m|1)<<2;e=G[l+a>>2];m:{if((e|0)!=(f|0)){e=e^-2147483648;break m}G[i>>2]=1;e=g}G[j+l>>2]=e;m=m+2|0;b=b+2|0;if((k|0)!=(b|0)){continue}break}}if(!h){break a}a=G[(m<<2)+a>>2];n:{if((a|0)!=(f|0)){g=a^-2147483648;break n}G[i>>2]=1}G[(m<<2)+j>>2]=g;break a}if((b|0)<=0){break a}e=b&1;f=0;if((b|0)!=1){g=b&-2;while(1){h=f<<2;b=G[h+a>>2];if((b|0)<0){G[k>>2]=-11;b=0}G[h+j>>2]=b;h=(f|1)<<2;b=G[h+a>>2];if((b|0)<0){G[k>>2]=-11;b=0}G[h+j>>2]=b;f=f+2|0;m=m+2|0;if((g|0)!=(m|0)){continue}break}}if(!e){break a}b=f<<2;a=G[b+a>>2];if((a|0)<0){G[k>>2]=-11;a=0}G[b+j>>2]=a}}function Ns(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;c=Fa-224|0;Fa=c;if(G[309801]){G[c+80>>2]=a;kb(87511,c+80|0)}a:{if(H[a|0]==35){d=gn(a+1|0,b);break a}h=G[309728];G[c+220>>2]=0;b:{if(!G[309736]){f=G[309731];if(!f){G[309737]=219;Ua(11057);d=-1;break a}e=-1;G[c+216>>2]=-1;c:{if(G[f>>2]>0){while(1){if(!Ib(a,G[G[f+8>>2]+(d<<2)>>2])){G[c+216>>2]=d;e=d}d=d+1|0;f=G[309731];if((d|0)>2]){continue}break}d=-1;if((e|0)>=0){break c}}G[c>>2]=a;a=c+112|0;Ya(a,80,26096,c);Ua(a);G[309737]=219;d=-1;break a}if(ki(h,1238948)){break a}g=G[309729];f=G[G[G[309731]+12>>2]+(e<<2)>>2];e=G[309730]+M(h,124)|0;mh(f,5,c+212|0,e+92|0,e+96|0,c+220|0);G[e+88>>2]=1;g=g+M(h,244)|0;if(fn(f,a,G[c+212>>2],e,g)){break a}G[g>>2]=f;G[g+84>>2]=0;break b}f=G[309712];d:{if(G[309715]){d=G[309718];G[c+216>>2]=d;break d}if(!dc(f,0,a,c+216|0,c+220|0)){d=G[c+216>>2];break d}d=G[c+220>>2];if((d|0)==219){d=-1;a=gn(a,b);if((a|0)==-1){break a}df();d=a;break a}G[309737]=d;d=-1;break a}if(vd(f,d,c+212|0,c+208|0,c+204|0,c+220|0)){G[309737]=G[c+220>>2];d=-1;break a}d=-1;if(ki(h,1238948)){break a}e=G[309730];j=G[c+216>>2];g=G[309729]+M(h,244)|0;d=g;G[d+84>>2]=0;G[d+80>>2]=0;G[d+4>>2]=j;G[d>>2]=f;e=e+M(h,124)|0}a=rb(e,a,80);E[a+80|0]=0;e=G[309736];e:{if(!e){d=269;break e}f:{g:{h:{i:{j:{k:{l:{d=G[c+212>>2];switch(d-1|0){case 0:break g;case 15:break i;case 13:break j;case 41:case 80:case 81:break k;case 10:case 20:case 40:break l;default:break h}}G[c+48>>2]=G[c+216>>2];d=c+112|0;Ya(d,80,29949,c+48|0);G[c+92>>2]=0;if(Cb(f,82,d,c+104|0,0,c+92|0)){G[c+104>>2]=0;G[c+108>>2]=0}G[c+32>>2]=G[c+216>>2];d=c+112|0;Ya(d,80,29979,c+32|0);G[c+92>>2]=0;m:{n:{if(Cb(f,82,d,c+96|0,0,c+92|0)){G[c+96>>2]=0;G[c+100>>2]=1072693248;break n}if(L[c+96>>3]!=1){break m}}i=L[c+104>>3];if(i!=0&i!=32768){break m}G[a+84>>2]=259;G[g+80>>2]=41;d=269;break f}G[a+84>>2]=260;G[g+80>>2]=82;d=269;break f}G[a+84>>2]=260;G[g+80>>2]=82;d=269;break f}G[a+84>>2]=258;G[g+80>>2]=14;d=270;break f}G[a+84>>2]=261;G[g+80>>2]=16;g=G[c+204>>2];if((g|0)>=256){G[c+64>>2]=G[c+216>>2];G[c+68>>2]=255;a=c+112|0;Ya(a,80,6246,c- -64|0);Ua(a);G[309737]=433;d=-1;break a}d=271;if((e|0)!=1){break f}G[c+208>>2]=g;break f}if((d|0)<0){G[c+16>>2]=d;a=c+112|0;Ya(a,80,30276,c+16|0);Ua(a)}G[309737]=432;d=-1;break a}G[a+84>>2]=262;G[g+80>>2]=11;d=272}e=G[c+208>>2];G[a+88>>2]=e;if(!(G[c+212>>2]==16|(e|0)<2)){if(!Zf(f,G[c+216>>2],5,a+92|0,a+96|0,c+220|0)){break e}G[309737]=G[c+220>>2];d=-1;break a}G[a+92>>2]=1;G[a+96>>2]=1}G[309728]=G[309728]+1;G[b>>2]=h}Fa=c+224|0;return d|0}function Gp(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0;n=c==1&d==32768;a:{b:{if(!e){if(n){if((b|0)<=0){break a}i=0;if(b-1>>>0>=3){g=b&-4;e=0;while(1){f=l<<1;F[f+j>>1]=I[a+f>>1]^32768;h=f|2;F[h+j>>1]=I[a+h>>1]^32768;h=f|4;F[h+j>>1]=I[a+h>>1]^32768;f=f|6;F[f+j>>1]=I[a+f>>1]^32768;l=l+4|0;e=e+4|0;if((g|0)!=(e|0)){continue}break}}b=b&3;if(!b){break a}while(1){e=l<<1;F[e+j>>1]=I[a+e>>1]^32768;l=l+1|0;i=i+1|0;if((b|0)!=(i|0)){continue}break}break a}if(c==1&d==0){break b}if((b|0)<=0){break a}while(1){c:{d:{f=l<<1;o=+F[f+a>>1]*c+d;if(o<-.49){G[k>>2]=-11;break d}if(o>65535.49){G[k>>2]=-11;e=65535;break c}if(!(o<4294967296&o>=0)){break d}e=~~o>>>0;break c}e=0}F[f+j>>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}e:{f:{g:{if(n){if((b|0)<=0){break a}if((e|0)==1){break e}if((b|0)!=1){k=b&-2;g=f&65535;e=0;while(1){n=l<<1;m=I[n+a>>1];h:{if((m|0)==(g|0)){G[i>>2]=1;E[h+l|0]=1;break h}F[j+n>>1]=m^32768}n=l|1;m=n<<1;p=I[m+a>>1];i:{if((g|0)!=(p|0)){F[j+m>>1]=p^32768;break i}G[i>>2]=1;E[h+n|0]=1}l=l+2|0;e=e+2|0;if((k|0)!=(e|0)){continue}break}}if(!(b&1)){break a}b=a;a=l<<1;b=I[b+a>>1];if((b|0)==(f&65535)){break g}F[a+j>>1]=b^32768;break a}if(c==1&d==0){break f}if((b|0)<=0){break a}n=f&65535;while(1){f=l<<1;m=I[f+a>>1];j:{if((m|0)==(n|0)){G[i>>2]=1;if((e|0)==1){F[f+j>>1]=g;break j}E[h+l|0]=1;break j}o=+(m<<16>>16)*c+d;if(o<-.49){G[k>>2]=-11;F[f+j>>1]=0;break j}if(o>65535.49){G[k>>2]=-11;F[f+j>>1]=65535;break j}m=f+j|0;if(o<4294967296&o>=0){f=~~o>>>0}else{f=0}F[m>>1]=f}l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}G[i>>2]=1;E[h+l|0]=1;break a}if((b|0)<=0){break a}n=f&65535;while(1){f=l<<1;m=I[f+a>>1];k:{if((m|0)==(n|0)){G[i>>2]=1;if((e|0)==1){F[f+j>>1]=g;break k}E[h+l|0]=1;break k}m=m<<16>>16;if((m|0)<0){G[k>>2]=-11;F[f+j>>1]=0;break k}F[f+j>>1]=m}l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)!=1){n=b&-2;k=f&65535;e=0;while(1){m=l<<1;h=I[m+a>>1];l:{if((h|0)!=(k|0)){h=h^-32768;break l}G[i>>2]=1;h=g}F[j+m>>1]=h;m=(l|1)<<1;h=I[m+a>>1];m:{if((h|0)!=(k|0)){h=h^-32768;break m}G[i>>2]=1;h=g}F[j+m>>1]=h;l=l+2|0;e=e+2|0;if((n|0)!=(e|0)){continue}break}}if(!(b&1)){break a}a=I[(l<<1)+a>>1];n:{if((a|0)!=(f&65535)){g=a^-32768;break n}G[i>>2]=1}F[(l<<1)+j>>1]=g;break a}if((b|0)<=0){break a}e=b&1;if((b|0)!=1){f=b&-2;i=0;while(1){g=l<<1;b=F[g+a>>1];if((b|0)<0){G[k>>2]=-11;b=0}F[g+j>>1]=b;g=(l|1)<<1;b=F[g+a>>1];if((b|0)<0){G[k>>2]=-11;b=0}F[g+j>>1]=b;l=l+2|0;i=i+2|0;if((f|0)!=(i|0)){continue}break}}if(!e){break a}b=l<<1;a=F[b+a>>1];if((a|0)<0){G[k>>2]=-11;a=0}F[b+j>>1]=a}}function Bn(a,b,c,d,e,f,g,h,i,j,k,l){var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;p=Fa-32|0;Fa=p;m=G[l>>2];a:{if((m|0)>0){break a}G[p+28>>2]=c;G[p+24>>2]=b;G[p+16>>2]=10;G[p+20>>2]=10;sd(p+12|0,42094,l);pd(G[p+12>>2],32,2,p+16|0,l);b=p+24|0;tk(a,G[p+12>>2],b,l);Zj(a,G[p+12>>2],2,b,l);m=G[l>>2];if((m|0)>0){break a}c=G[p+12>>2];m=Fa-144|0;Fa=m;G[m+140>>2]=0;G[m+56>>2]=0;G[m+60>>2]=0;G[m+48>>2]=0;G[m+52>>2]=0;G[m+40>>2]=0;G[m+44>>2]=0;G[m+32>>2]=0;G[m+36>>2]=0;G[m+24>>2]=0;G[m+28>>2]=1072693248;G[m+16>>2]=0;G[m+20>>2]=0;G[m+8>>2]=0;G[m+12>>2]=1072693248;G[m>>2]=0;G[m+4>>2]=0;if(G[l>>2]<=0){G[m+140>>2]=0;if(Kc(c,41279,d,m+140|0)){G[d>>2]=0;G[d+4>>2]=0}G[m+140>>2]=0;if(Kc(c,40866,e,m+140|0)){G[e>>2]=0;G[e+4>>2]=0}G[m+140>>2]=0;if(Kc(c,41201,f,m+140|0)){G[f>>2]=0;G[f+4>>2]=0}G[m+140>>2]=0;if(Kc(c,40799,g,m+140|0)){G[g>>2]=0;G[g+4>>2]=0}G[m+140>>2]=0;b:{c:{if(Kc(c,41234,h,m+140|0)){G[m+140>>2]=0;a=1;b=1;if(Kc(c,41174,m+56|0,m+140|0)){G[m+140>>2]=0;b=0}if(Kc(c,41149,m+48|0,m+140|0)){G[m+140>>2]=0;a=b}d:{if(!Kc(c,40778,m+32|0,m+140|0)){a=1;break d}G[m+140>>2]=0}if(!(t=0,u=Kc(c,40759,m+40|0,m+140|0),v=a,v?t:u)){n=L[m+56>>3];s=Db(L[m+48>>3],n);r=L[m+40>>3];q=Db(-L[m+32>>3],r);o=q>s?s:q;q=q1.5707963267948966?o+3.141592653589793:o;if(O(o-q)>2e-4){G[l>>2]=506}s=n;n=(q+o)*.5;o=eb(n);L[h>>3]=s/o;L[i>>3]=r/o;L[j>>3]=n*180/3.141592653589793;if(!(L[i>>3]<0)){break b}L[h>>3]=-L[h>>3];L[i>>3]=-L[i>>3];n=L[j>>3]+-180;break c}G[h>>2]=0;G[h+4>>2]=1072693248;G[m+140>>2]=0;if(Kc(c,40826,i,m+140|0)){G[i>>2]=0;G[i+4>>2]=1072693248}G[m+140>>2]=0;n=0;if(Kc(c,40896,j,m+140|0)){break c}break b}if(Kc(c,40826,i,m+140|0)){G[i>>2]=0;G[i+4>>2]=1072693248}G[m+140>>2]=0;if(!Kc(c,40896,j,m+140|0)){break b}G[j>>2]=0;G[j+4>>2]=0;G[m+140>>2]=0;a=1;b=1;if(Kc(c,41180,m+24|0,m+140|0)){G[m+140>>2]=0;b=0}if(Kc(c,41155,m+16|0,m+140|0)){G[m+140>>2]=0;a=b}e:{if(!Kc(c,40784,m,m+140|0)){a=1;break e}G[m+140>>2]=0}if(t=0,u=Kc(c,40765,m+8|0,m+140|0),v=a,v?t:u){break b}r=Db(L[m+16>>3],L[m+24>>3]);n=Db(-L[m>>3],L[m+8>>3]);o=n>r?r:n;n=n1.5707963267948966?o+3.141592653589793:o;if(O(o-n)>2e-4){G[l>>2]=506}n=(n+o)*.5*180/3.141592653589793}L[j>>3]=n}G[m+140>>2]=0;f:{if(Fc(c,41295,m- -64|0,0,m+140|0)){E[k|0]=0;break f}t=rb(k,m- -64|4,4),u=0,E[t+4|0]=u;if(G[m+64>>2]!=759383364){if(nb(m- -64|1,33504,3)){break f}}L[j>>3]=90-L[j>>3];L[i>>3]=-L[i>>3];o=L[d>>3];L[d>>3]=L[e>>3];L[e>>3]=o}}Fa=m+144|0;if(G[l>>2]>0){Ua(8157);m=505;G[l>>2]=505;break a}Xm(G[p+12>>2],l);m=G[l>>2]}Fa=p+32|0;return m}function Ob(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;k=Fa-176|0;Fa=k;G[k+12>>2]=-1;a:{if(G[e>>2]>0){break a}E[k+16|0]=0;E[k+96|0]=0;E[d|0]=0;while(1){f=a+i|0;i=i+1|0;if(H[f|0]==32){continue}break}j=qb(k+96|0,f,74);n=Va(b);b:{c:{d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{f=Va(j);if(f){i=(f+j|0)-1|0;if(H[i|0]==32){while(1){E[i|0]=0;i=i-1|0;if(H[i|0]==32){continue}break}}if(!jb(j,61)){break o}break c}if(jb(j,61)){break c}break n}l=(i-j|0)+1|0;if(l>>>0>8){break m}}if((ve(j,k+12|0)|0)>0){break m}f=Gb(d,j);if(l>>>0<=7){cb(f+l|0,32,8-l|0)}E[f+10|0]=0;E[f+8|0]=61;E[f+9|0]=32;i=0;if(!n){break h}g=10;f=0;if(H[b|0]!=39){break l}break g}p:{q:{r:{f=H[j|0];s:{if((f|0)!=104){if((f|0)!=72){break r}if(!nb(j,66642,9)){break s}break r}if(nb(j,66365,9)){break r}}f=Gb(d,j);h=Va(f)+f|0;g=l+3|0;if(n+g>>>0>=81){i=0;E[h+2|0]=H[66742];f=H[66740]|H[66741]<<8;E[h|0]=f;E[h+1|0]=f>>>8;g=l+2|0;break q}E[h|0]=32;E[h+1|0]=61;E[h+2|0]=32;E[h+3|0]=0;i=0;break q}t:{g=pc(qb(k+16|0,j,74),68332);if(g){i=0;while(1){G[k+12>>2]=-1;i=(ve(g,k+12|0)|0)<=0?i:1;m=m+1|0;g=pc(0,68332);if(g){continue}break}if(l-70>>>0<=4294967214){tb(5,38782);tb(5,a);break b}g=Va(d)+d|0;f=H[66646]|H[66647]<<8|(H[66648]<<16|H[66649]<<24);h=H[66642]|H[66643]<<8|(H[66644]<<16|H[66645]<<24);E[g|0]=h;E[g+1|0]=h>>>8;E[g+2|0]=h>>>16;E[g+3|0]=h>>>24;E[g+4|0]=f;E[g+5|0]=f>>>8;E[g+6|0]=f>>>16;E[g+7|0]=f>>>24;f=H[66650]|H[66651]<<8;E[g+8|0]=f;E[g+9|0]=f>>>8;f=Gb(d,j);h=Va(f)+f|0;g=l+12|0;if(n+g>>>0<81){break t}E[h+2|0]=H[66742];f=H[66740]|H[66741]<<8;E[h|0]=f;E[h+1|0]=f>>>8;g=l+11|0;if(!n){break i}break p}G[k+12>>2]=-1;i=0;if((ve(j,k+12|0)|0)<=0){f=qb(d,j,74);h=Va(f)+f|0;f=H[66740]|H[66741]<<8;E[h|0]=f;E[h+1|0]=f>>>8;E[h+2|0]=H[66742];g=l+2|0;break q}tb(5,37813);tb(5,j);break b}E[h|0]=32;E[h+1|0]=61;E[h+2|0]=32;E[h+3|0]=0;if(n){break p}break i}if(!n){break i}}if(H[b|0]==39){break k}f=m}m=g+n|0;if(m>>>0<81){break j}tb(5,38722);tb(5,a);tb(5,b);break b}f=i;if(g>>>0<78){break g}tb(5,38722);tb(5,a);tb(5,b);break b}if(m>>>0<=29){qb(d,68277,30-m|0)}qb(d,b,80-g|0);a=m>>>0>30?m:30;m=f;break f}if((g|0)!=10){break d}}E[d+8|0]=32;a=70;if(!c){break d}break e}e=qb(d,b,80-g|0);b=g+n|0;a=b>>>0<80;if(!a){E[e+79|0]=39}if(!c){i=f;break d}b=a?b:80;if(!(!H[c|0]|b>>>0>29)){a=30;cb(b+e|0,32,30-b|0);E[e+30|0]=0;i=f;break f}i=f;a=b}if(!H[c|0]|(!c|a>>>0>76)){break d}b=Va(d)+d|0;E[b|0]=32;E[b+1|0]=47;E[b+2|0]=32;E[b+3|0]=0;a=77-a|0}qb(d,c,a)}if(!((m|0)!=1&(i|0)!=1)){tb(5,13872);tb(5,d)}break a}tb(5,63296);tb(5,j)}G[e>>2]=207}Fa=k+176|0}function No(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;a:{if(G[k>>2]>0){break a}b:{m=G[a>>2];l=G[a+4>>2];if((m|0)!=G[l+76>>2]){mb(a,m+1|0,0,k);break b}if((G[l+128>>2]&G[l+132>>2])!=-1){break b}if((Rb(a,k)|0)<=0){break b}return}l=G[G[a+4>>2]+968>>2]+M(b-1|0,160)|0;y=G[l+80>>2];c:{d:{if((y|0)<=0){e:{if((y|0)>=0){break e}l=G[k>>2];if((l|0)<=0){Qe(a,b,c,d,e,f,g,h,i,k);l=G[k>>2];if((l|0)<=0){break e}}if((l|0)!=412){break a}G[k>>2]=0}if(!g&(h|0)<=0|(h|0)<0){break a}l=f+h|0;m=e+g|0;l=m>>>0>>0?l+1|0:l;p=m-1|0;q=l-!m|0;c=Au(p,q,c-1|0,d-!c|0)+e|0;l=f+Ia|0;m=c;t=c>>>0>>0?l+1|0:l;if((y|0)>0){break d}e=0;f=0;c=0;d=0;while(1){f:{if(G[(r<<2)+i>>2]!=(j|0)){if(e|f){l=t+(o-((e>>>0>r>>>0)+f|0)|0)|0;n=m+(r-e|0)|0;l=n>>>0>>0?l+1|0:l;u=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;w=l;v=s+1|0;l=v?l:l+1|0;x=l;l=Au(p,q,s,w);if((rc(a,b,v,x,n-l|0,u-(Ia+(l>>>0>n>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;l=d;c=c+1|0;l=c?l:l+1|0;d=l;break f}l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0}l=r+1|0;o=l?o:o+1|0;r=l;if((g|0)!=(l|0)|(h|0)!=(o|0)){continue}break}break c}if(!g&(h|0)<=0|(h|0)<0){break a}p=G[l+88>>2];q=G[l+92>>2];c=Au(p,q,c-1|0,d-!c|0)+e|0;l=f+Ia|0;m=c;t=c>>>0>>0?l+1|0:l}e=0;f=0;c=0;d=0;while(1){g:{if(G[(r<<2)+i>>2]!=(j|0)){if(e|f){l=t+(o-((e>>>0>r>>>0)+f|0)|0)|0;n=m+(r-e|0)|0;l=n>>>0>>0?l+1|0:l;u=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;w=l;v=s+1|0;l=v?l:l+1|0;x=l;l=Au(p,q,s,w);if((rc(a,b,v,x,n-l|0,u-(Ia+(l>>>0>n>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;l=d;c=c+1|0;l=c?l:l+1|0;d=l;break g}h:{if(!(c|d)){break h}l=G[k>>2];if((l|0)<=0){l=t+(o-((c>>>0>r>>>0)+d|0)|0)|0;w=r-c|0;n=m+w|0;l=n>>>0>>0?l+1|0:l;u=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;v=l;z=s+1|0;l=z?l:l+1|0;x=l;l=Au(p,q,s,v);Qe(a,b,z,x,n-l|0,u-(Ia+(l>>>0>n>>>0)|0)|0,c,d,(w<<2)+i|0,k);l=G[k>>2];if((l|0)<=0){break h}}if((l|0)!=412){break a}G[k>>2]=0;A=1}l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0}l=o;o=r+1|0;l=o?l:l+1|0;r=o;o=l;if((g|0)!=(r|0)|(h|0)!=(l|0)){continue}break}}i:{if(c|d){if((y|0)<=0|G[k>>2]>0){break i}e=a;l=t+(h-((c>>>0>g>>>0)+d|0)|0)|0;j=g-c|0;a=m+j|0;l=a>>>0>>0?l+1|0:l;f=Bu(a-1|0,l-!a|0,p,q);o=Ia;g=o;h=b;b=f+1|0;o=b?g:g+1|0;u=b;b=Au(p,q,f,g);Qe(e,h,u,o,a-b|0,l-(Ia+(a>>>0>>0)|0)|0,c,d,(j<<2)+i|0,k);break i}if(!(e|f)){break i}c=a;l=t+(h-((e>>>0>g>>>0)+f|0)|0)|0;a=m+(g-e|0)|0;l=a>>>0>>0?l+1|0:l;d=l;g=Bu(a-1|0,l-!a|0,p,q);l=Ia;h=l;i=b;b=g+1|0;l=b?l:l+1|0;j=b;b=Au(g,h,p,q);rc(c,i,j,l,a-b|0,d-(Ia+(a>>>0>>0)|0)|0,e,f,k)}if(!A|G[k>>2]>0){break a}G[k>>2]=412}}function Io(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;a:{if(G[k>>2]>0){break a}b:{m=G[a>>2];l=G[a+4>>2];if((m|0)!=G[l+76>>2]){mb(a,m+1|0,0,k);break b}if((G[l+128>>2]&G[l+132>>2])!=-1){break b}if((Rb(a,k)|0)<=0){break b}return}l=G[G[a+4>>2]+968>>2]+M(b-1|0,160)|0;y=G[l+80>>2];c:{d:{if((y|0)<=0){e:{if((y|0)>=0){break e}l=G[k>>2];if((l|0)<=0){xe(a,b,c,d,e,f,g,h,i,k);l=G[k>>2];if((l|0)<=0){break e}}if((l|0)!=412){break a}G[k>>2]=0}if(!g&(h|0)<=0|(h|0)<0){break a}l=f+h|0;m=e+g|0;l=m>>>0>>0?l+1|0:l;p=m-1|0;q=l-!m|0;c=Au(p,q,c-1|0,d-!c|0)+e|0;l=f+Ia|0;m=c;t=c>>>0>>0?l+1|0:l;if((y|0)>0){break d}e=0;f=0;c=0;d=0;while(1){f:{if(G[(r<<2)+i>>2]!=(j|0)){if(e|f){l=t+(o-((e>>>0>r>>>0)+f|0)|0)|0;n=m+(r-e|0)|0;l=n>>>0>>0?l+1|0:l;u=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;w=l;v=s+1|0;l=v?l:l+1|0;x=l;l=Au(p,q,s,w);if((rc(a,b,v,x,n-l|0,u-(Ia+(l>>>0>n>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;l=d;c=c+1|0;l=c?l:l+1|0;d=l;break f}l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0}l=r+1|0;o=l?o:o+1|0;r=l;if((g|0)!=(l|0)|(h|0)!=(o|0)){continue}break}break c}if(!g&(h|0)<=0|(h|0)<0){break a}p=G[l+88>>2];q=G[l+92>>2];c=Au(p,q,c-1|0,d-!c|0)+e|0;l=f+Ia|0;m=c;t=c>>>0>>0?l+1|0:l}e=0;f=0;c=0;d=0;while(1){g:{if(G[(r<<2)+i>>2]!=(j|0)){if(e|f){l=t+(o-((e>>>0>r>>>0)+f|0)|0)|0;n=m+(r-e|0)|0;l=n>>>0>>0?l+1|0:l;u=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;w=l;v=s+1|0;l=v?l:l+1|0;x=l;l=Au(p,q,s,w);if((rc(a,b,v,x,n-l|0,u-(Ia+(l>>>0>n>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;l=d;c=c+1|0;l=c?l:l+1|0;d=l;break g}h:{if(!(c|d)){break h}l=G[k>>2];if((l|0)<=0){l=t+(o-((c>>>0>r>>>0)+d|0)|0)|0;w=r-c|0;n=m+w|0;l=n>>>0>>0?l+1|0:l;u=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;v=l;z=s+1|0;l=z?l:l+1|0;x=l;l=Au(p,q,s,v);xe(a,b,z,x,n-l|0,u-(Ia+(l>>>0>n>>>0)|0)|0,c,d,(w<<2)+i|0,k);l=G[k>>2];if((l|0)<=0){break h}}if((l|0)!=412){break a}G[k>>2]=0;A=1}l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0}l=o;o=r+1|0;l=o?l:l+1|0;r=o;o=l;if((g|0)!=(r|0)|(h|0)!=(l|0)){continue}break}}i:{if(c|d){if((y|0)<=0|G[k>>2]>0){break i}e=a;l=t+(h-((c>>>0>g>>>0)+d|0)|0)|0;j=g-c|0;a=m+j|0;l=a>>>0>>0?l+1|0:l;f=Bu(a-1|0,l-!a|0,p,q);o=Ia;g=o;h=b;b=f+1|0;o=b?g:g+1|0;u=b;b=Au(p,q,f,g);xe(e,h,u,o,a-b|0,l-(Ia+(a>>>0>>0)|0)|0,c,d,(j<<2)+i|0,k);break i}if(!(e|f)){break i}c=a;l=t+(h-((e>>>0>g>>>0)+f|0)|0)|0;a=m+(g-e|0)|0;l=a>>>0>>0?l+1|0:l;d=l;g=Bu(a-1|0,l-!a|0,p,q);l=Ia;h=l;i=b;b=g+1|0;l=b?l:l+1|0;j=b;b=Au(g,h,p,q);rc(c,i,j,l,a-b|0,d-(Ia+(a>>>0>>0)|0)|0,e,f,k)}if(!A|G[k>>2]>0){break a}G[k>>2]=412}}function mm(a,b){var c=0,d=0;c=Fa-16|0;Fa=c;if(G[321439]){G[c+4>>2]=b;G[c>>2]=a;kb(76362,c);$a(G[29763])}a:{if(!Xa(a,35530)){G[321445]=1;if(!Xa(b,33560)){break a}if(!Xa(b,35337)){break a}hc(35309);break a}b:{c:{d:{if(!Xa(a,32941)){G[321446]=1;a=nc(b,c+12|0,0);if(J[c+12>>2]>>0){hc(11287)}if((a|0)<=7){if((a|0)==-64){break a}if((a|0)!=-32){break b}break a}b=a-8|0;if(b>>>0<=24){break d}break c}if(!Xa(a,33788)){G[321447]=1;a=nc(b,c+12|0,0);if(J[c+12>>2]>>0){hc(11332)}if((a|0)>1){break a}hc(40921);break a}if(!Xa(a,41261)){G[321448]=1;a=nc(b,c+12|0,0);if(J[c+12>>2]>>0){hc(11421)}if((a|0)>=0){break a}hc(41766);break a}if(!Xa(a,40853)){G[321449]=1;a=nc(b,c+12|0,0);if(J[c+12>>2]>>0){hc(11376)}if((a|0)>=0){break a}hc(41724);break a}if(!Xa(a,34954)){G[321444]=1;break a}if(!Xa(a,41295)){G[321450]=1;Za(1285872,b);break a}if(!Xa(a,40882)){G[321451]=1;Za(1286896,b);break a}if(!Xa(a,41201)){G[321452]=1;vb(b,c+12|0);if(J[c+12>>2]>=Va(b)+b>>>0){break a}hc(12994);break a}if(!Xa(a,40799)){G[321453]=1;vb(b,c+12|0);if(J[c+12>>2]>=Va(b)+b>>>0){break a}hc(12755);break a}if(!Xa(a,41279)){G[321460]=1;vb(b,c+12|0);if(J[c+12>>2]>=Va(b)+b>>>0){break a}hc(13090);break a}if(!Xa(a,40866)){G[321461]=1;vb(b,c+12|0);if(J[c+12>>2]>=Va(b)+b>>>0){break a}hc(12851);break a}if(!Xa(a,41234)){G[321454]=1;vb(b,c+12|0);if(J[c+12>>2]>=Va(b)+b>>>0){break a}hc(13042);break a}if(!Xa(a,40826)){G[321455]=1;vb(b,c+12|0);if(J[c+12>>2]>=Va(b)+b>>>0){break a}hc(12803);break a}if(!Xa(a,40896)){vb(b,c+12|0);if(J[c+12>>2]>=Va(b)+b>>>0){break a}hc(12899);break a}if(!Xa(a,41174)){G[321456]=1;vb(b,c+12|0);if(J[c+12>>2]>=Va(b)+b>>>0){break a}hc(12947);break a}if(!Xa(a,40778)){G[321457]=1;vb(b,c+12|0);if(J[c+12>>2]>=Va(b)+b>>>0){break a}hc(12708);break a}if(!Xa(a,41149)){G[321458]=1;vb(b,c+12|0);if(J[c+12>>2]>=Va(b)+b>>>0){break a}hc(12708);break a}if(!Xa(a,40759)){G[321459]=1;vb(b,c+12|0);if(J[c+12>>2]>=Va(b)+b>>>0){break a}hc(12661);break a}if(!Xa(a,35661)){vb(b,c+12|0);if(J[c+12>>2]>=Va(b)+b>>>0){break a}hc(12613);break a}if(!Xa(a,34377)){vb(b,c+12|0);if(J[c+12>>2]>=Va(b)+b>>>0){break a}hc(12472);break a}if(!Xa(a,34862)){vb(b,c+12|0);if(J[c+12>>2]>=Va(b)+b>>>0){break a}hc(12519);break a}if(!Xa(a,34948)){vb(b,c+12|0);if(J[c+12>>2]>=Va(b)+b>>>0){break a}hc(12566);break a}if(Xa(a,32863)){break a}d=vb(b,c+12|0);if(!(d<1900|d>2050)|J[c+12>>2]>=Va(b)+b>>>0){break a}hc(12423);break a}if(1<>2]>0){break a}b:{n=G[a>>2];m=G[a+4>>2];if((n|0)!=G[m+76>>2]){mb(a,n+1|0,0,l);break b}if((G[m+128>>2]&G[m+132>>2])!=-1){break b}if((Rb(a,l)|0)<=0){break b}return}m=G[G[a+4>>2]+968>>2]+M(b-1|0,160)|0;z=G[m+80>>2];c:{if((z|0)<=0){d:{if((z|0)>=0){break d}if((yh(a,b,c,d,e,f,g,h,i,l)|0)<=0){break d}if(G[l>>2]!=412){break a}G[l>>2]=0}if(!g&(h|0)<=0|(h|0)<0){break a}m=f+h|0;n=e+g|0;m=n>>>0>>0?m+1|0:m;q=n-1|0;r=m-!n|0;c=Au(q,r,c-1|0,d-!c|0)+e|0;m=f+Ia|0;n=c;v=c>>>0>>0?m+1|0:m;e=0;f=0;c=0;d=0;while(1){m=(s<<3)+i|0;e:{if(G[m>>2]!=(j|0)|G[m+4>>2]!=(k|0)){if(e|f){m=v+(p-((e>>>0>s>>>0)+f|0)|0)|0;o=n+(s-e|0)|0;m=o>>>0>>0?m+1|0:m;x=m;t=Bu(o-1|0,m-!o|0,q,r);m=Ia;w=m;u=t+1|0;m=u?m:m+1|0;y=m;m=Au(q,r,t,w);if((rc(a,b,u,y,o-m|0,x-(Ia+(m>>>0>o>>>0)|0)|0,e,f,l)|0)>0){break a}}e=0;f=0;m=d;c=c+1|0;m=c?m:m+1|0;d=m;break e}m=f;c=e+1|0;m=c?m:m+1|0;e=c;f=m;c=0;d=0}m=p;p=s+1|0;m=p?m:m+1|0;s=p;p=m;if((g|0)!=(s|0)|(h|0)!=(m|0)){continue}break}break c}if(!g&(h|0)<=0|(h|0)<0){break a}q=G[m+88>>2];r=G[m+92>>2];c=Au(q,r,c-1|0,d-!c|0)+e|0;m=f+Ia|0;n=c;v=c>>>0>>0?m+1|0:m;e=0;f=0;c=0;d=0;while(1){m=(s<<3)+i|0;f:{if(G[m>>2]!=(j|0)|G[m+4>>2]!=(k|0)){if(e|f){m=v+(p-((e>>>0>s>>>0)+f|0)|0)|0;o=n+(s-e|0)|0;m=o>>>0>>0?m+1|0:m;x=m;t=Bu(o-1|0,m-!o|0,q,r);m=Ia;w=m;u=t+1|0;m=u?m:m+1|0;y=m;m=Au(q,r,t,w);if((rc(a,b,u,y,o-m|0,x-(Ia+(m>>>0>o>>>0)|0)|0,e,f,l)|0)>0){break a}}e=0;f=0;m=d;c=c+1|0;m=c?m:m+1|0;d=m;break f}g:{if(!(c|d)){break g}m=v+(p-((c>>>0>s>>>0)+d|0)|0)|0;w=s-c|0;o=n+w|0;m=o>>>0>>0?m+1|0:m;x=m;t=Bu(o-1|0,m-!o|0,q,r);m=Ia;u=m;A=t+1|0;m=A?m:m+1|0;y=m;m=Au(q,r,t,u);if((yh(a,b,A,y,o-m|0,x-(Ia+(m>>>0>o>>>0)|0)|0,c,d,(w<<3)+i|0,l)|0)<=0){break g}if(G[l>>2]!=412){break a}G[l>>2]=0;B=1}m=f;c=e+1|0;m=c?m:m+1|0;e=c;f=m;c=0;d=0}m=p;p=s+1|0;m=p?m:m+1|0;s=p;p=m;if((g|0)!=(s|0)|(h|0)!=(m|0)){continue}break}}h:{if(c|d){if((z|0)<=0){break h}e=a;m=v+(h-((c>>>0>g>>>0)+d|0)|0)|0;j=g-c|0;a=n+j|0;m=a>>>0>>0?m+1|0:m;f=m;g=Bu(a-1|0,m-!a|0,q,r);m=Ia;h=m;k=b;b=g+1|0;m=b?m:m+1|0;p=b;b=Au(g,h,q,r);yh(e,k,p,m,a-b|0,f-(Ia+(a>>>0>>0)|0)|0,c,d,(j<<3)+i|0,l);break h}if(!(e|f)){break h}c=a;m=v+(h-((e>>>0>g>>>0)+f|0)|0)|0;a=n+(g-e|0)|0;m=a>>>0>>0?m+1|0:m;d=m;g=Bu(a-1|0,m-!a|0,q,r);m=Ia;h=m;i=b;b=g+1|0;m=b?m:m+1|0;j=b;b=Au(g,h,q,r);rc(c,i,j,m,a-b|0,d-(Ia+(a>>>0>>0)|0)|0,e,f,l)}if(!B|G[l>>2]>0){break a}G[l>>2]=412}} -function Qo(a,b,c,d,e,f,g,h,i,j,k,l){var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;a:{if(G[l>>2]>0){break a}b:{n=G[a>>2];m=G[a+4>>2];if((n|0)!=G[m+76>>2]){mb(a,n+1|0,0,l);break b}if((G[m+128>>2]&G[m+132>>2])!=-1){break b}if((Rb(a,l)|0)<=0){break b}return}m=G[G[a+4>>2]+968>>2]+M(b-1|0,160)|0;z=G[m+80>>2];c:{if((z|0)<=0){d:{if((z|0)>=0){break d}if((zh(a,b,c,d,e,f,g,h,i,l)|0)<=0){break d}if(G[l>>2]!=412){break a}G[l>>2]=0}if(!g&(h|0)<=0|(h|0)<0){break a}m=f+h|0;n=e+g|0;m=n>>>0>>0?m+1|0:m;q=n-1|0;r=m-!n|0;c=Au(q,r,c-1|0,d-!c|0)+e|0;m=f+Ia|0;n=c;v=c>>>0>>0?m+1|0:m;e=0;f=0;c=0;d=0;while(1){m=(s<<3)+i|0;e:{if(G[m>>2]!=(j|0)|G[m+4>>2]!=(k|0)){if(e|f){m=v+(p-((e>>>0>s>>>0)+f|0)|0)|0;o=n+(s-e|0)|0;m=o>>>0>>0?m+1|0:m;x=m;t=Bu(o-1|0,m-!o|0,q,r);m=Ia;w=m;u=t+1|0;m=u?m:m+1|0;y=m;m=Au(q,r,t,w);if((rc(a,b,u,y,o-m|0,x-(Ia+(m>>>0>o>>>0)|0)|0,e,f,l)|0)>0){break a}}e=0;f=0;m=d;c=c+1|0;m=c?m:m+1|0;d=m;break e}m=f;c=e+1|0;m=c?m:m+1|0;e=c;f=m;c=0;d=0}m=p;p=s+1|0;m=p?m:m+1|0;s=p;p=m;if((g|0)!=(s|0)|(h|0)!=(m|0)){continue}break}break c}if(!g&(h|0)<=0|(h|0)<0){break a}q=G[m+88>>2];r=G[m+92>>2];c=Au(q,r,c-1|0,d-!c|0)+e|0;m=f+Ia|0;n=c;v=c>>>0>>0?m+1|0:m;e=0;f=0;c=0;d=0;while(1){m=(s<<3)+i|0;f:{if(G[m>>2]!=(j|0)|G[m+4>>2]!=(k|0)){if(e|f){m=v+(p-((e>>>0>s>>>0)+f|0)|0)|0;o=n+(s-e|0)|0;m=o>>>0>>0?m+1|0:m;x=m;t=Bu(o-1|0,m-!o|0,q,r);m=Ia;w=m;u=t+1|0;m=u?m:m+1|0;y=m;m=Au(q,r,t,w);if((rc(a,b,u,y,o-m|0,x-(Ia+(m>>>0>o>>>0)|0)|0,e,f,l)|0)>0){break a}}e=0;f=0;m=d;c=c+1|0;m=c?m:m+1|0;d=m;break f}g:{if(!(c|d)){break g}m=v+(p-((c>>>0>s>>>0)+d|0)|0)|0;w=s-c|0;o=n+w|0;m=o>>>0>>0?m+1|0:m;x=m;t=Bu(o-1|0,m-!o|0,q,r);m=Ia;u=m;A=t+1|0;m=A?m:m+1|0;y=m;m=Au(q,r,t,u);if((zh(a,b,A,y,o-m|0,x-(Ia+(m>>>0>o>>>0)|0)|0,c,d,(w<<3)+i|0,l)|0)<=0){break g}if(G[l>>2]!=412){break a}G[l>>2]=0;B=1}m=f;c=e+1|0;m=c?m:m+1|0;e=c;f=m;c=0;d=0}m=p;p=s+1|0;m=p?m:m+1|0;s=p;p=m;if((g|0)!=(s|0)|(h|0)!=(m|0)){continue}break}}h:{if(c|d){if((z|0)<=0){break h}e=a;m=v+(h-((c>>>0>g>>>0)+d|0)|0)|0;j=g-c|0;a=n+j|0;m=a>>>0>>0?m+1|0:m;f=m;g=Bu(a-1|0,m-!a|0,q,r);m=Ia;h=m;k=b;b=g+1|0;m=b?m:m+1|0;p=b;b=Au(g,h,q,r);zh(e,k,p,m,a-b|0,f-(Ia+(a>>>0>>0)|0)|0,c,d,(j<<3)+i|0,l);break h}if(!(e|f)){break h}c=a;m=v+(h-((e>>>0>g>>>0)+f|0)|0)|0;a=n+(g-e|0)|0;m=a>>>0>>0?m+1|0:m;d=m;g=Bu(a-1|0,m-!a|0,q,r);m=Ia;h=m;i=b;b=g+1|0;m=b?m:m+1|0;j=b;b=Au(g,h,q,r);rc(c,i,j,m,a-b|0,d-(Ia+(a>>>0>>0)|0)|0,e,f,l)}if(!B|G[l>>2]>0){break a}G[l>>2]=412}}function Gn(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0;e=Fa-16|0;Fa=e;a:{if(b){Ua(54912);Ua(a);b=112;break a}b=ce(a,0,e+4|0);if(b){Ua(55310);Ua(a);break a}if((zc(e,1,2,G[e+4>>2])|0)!=2){Hb(G[e+4>>2]);b=108;break a}b:{c:{d:{e:{if((H[e|0]|H[e+1|0]<<8)==35615){He(G[e+4>>2],0,2);ek(G[e+4>>2]);He(G[e+4>>2],-4,1);break e}if((H[e|0]|H[e+1|0]<<8)!=19280){break d}He(G[e+4>>2],22,0)}zc(e,1,4,G[e+4>>2]);g=H[e|0]|H[e+1|0]<<8|(H[e+2|0]<<16|H[e+3|0]<<24);if(g){break b}break c}i=1;b=H[e|0]|H[e+1|0]<<8;if((b|0)==7711|(b|0)==40223|(H[e|0]|H[e+1|0]<<8)==40991){break c}Hb(G[e+4>>2]);b=1;break a}He(G[e+4>>2],0,2);g=M(ek(G[e+4>>2]),3)}b=0;He(G[e+4>>2],0,0);G[c>>2]=-1;f:{g:{h:{i:{j:{k:{l:{while(1){d=M(b,48)+757232|0;if(!G[d>>2]){f=b;break l}f=b+1|0;d=M(f,48)+757232|0;if(!G[d>>2]){break l}f=b+2|0;d=M(f,48)+757232|0;if(!G[d>>2]){break l}f=b+3|0;d=M(f,48)+757232|0;if(!G[d>>2]){break l}f=b+4|0;d=M(f,48)+757232|0;if(!G[d>>2]){break l}b=b+5|0;if((b|0)!=1e4){continue}break}b=103;break k}G[c>>2]=f;h=d;b=M(f,48);d=b+757236|0;G[h>>2]=d;h=b+757240|0;b=b+757244|0;G[h>>2]=b;if(!g){break j}h=d;d=ab(g);G[h>>2]=d;if(d){break j}Ua(57797);b=104}if(!i){break h}G[c>>2]=-1;i=(g>>>0)/3|0;b=0;while(1){d=M(b,48)+757232|0;if(!G[d>>2]){f=b;break i}f=b+1|0;d=M(f,48)+757232|0;if(!G[d>>2]){break i}f=b+2|0;d=M(f,48)+757232|0;if(!G[d>>2]){break i}f=b+3|0;d=M(f,48)+757232|0;if(!G[d>>2]){break i}f=b+4|0;d=M(f,48)+757232|0;if(!G[d>>2]){break i}b=b+5|0;if((b|0)!=1e4){continue}break}b=103;break h}G[b>>2]=g;break f}G[c>>2]=f;h=d;b=M(f,48);d=b+757236|0;G[h>>2]=d;h=b+757240|0;b=b+757244|0;G[h>>2]=b;if(g>>>0<3){break g}h=d;d=ab(i);G[h>>2]=d;if(d){break g}Ua(57797);b=104}Hb(G[e+4>>2]);Ua(55259);break a}G[b>>2]=i}b=M(f,48);f=b+757256|0;G[f>>2]=0;G[f+4>>2]=0;G[b+757248>>2]=2880;f=b+757264|0;G[f>>2]=0;G[f+4>>2]=0;G[b+757252>>2]=17;b=G[c>>2];f=G[e+4>>2];G[e+8>>2]=0;g=M(b,48);d=G[g+757240>>2];g=G[g+757232>>2];m:{if(Sb(a,32688)){Ln(a,f,g,d,e+12|0,e+8|0);break m}hp(f,g,d,e+12|0,e+8|0)}a=M(b,48);b=a+757256|0;G[b>>2]=0;G[b+4>>2]=0;a=a+757264|0;G[a>>2]=G[e+12>>2];G[a+4>>2]=0;b=G[e+8>>2];Hb(G[e+4>>2]);a=G[c>>2];if(b){a=M(a,48)+757232|0;Wa(G[G[a>>2]>>2]);G[a>>2]=0;G[a+4>>2]=0;Ua(55147);break a}b=0;d=M(a,48);f=G[d+757264>>2];if(J[G[d+757240>>2]>>2]<=f+256>>>0){break a}f=ub(G[G[M(a,48)+757232>>2]>>2],f);if(!f){Ua(55201);b=113;break a}a=M(G[c>>2],48);G[G[a+757232>>2]>>2]=f;G[G[a+757240>>2]>>2]=G[a+757264>>2]}Fa=e+16|0;return b|0}function ul(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;a:{if((a|0)<=0|G[968816]<=(a|0)){break a}e=G[968817];if(!e){break a}h=e+M(a,65544)|0;f=G[h>>2];if(!f){break a}a=e+M(a,65544)|0;E[a+8|0]=0;a=a+8|0;b:{if(!b|!H[b|0]){break b}c:{if(!Xc(b,30677)){break c}if(!Xc(b,30657)){break c}if(!Xc(b,13234)){break c}if(!(Zh(b)>0)){break b}f=G[h>>2]}sm(f,b);f=Fa-32|0;Fa=f;e=G[h>>2];d:{if(!e|!G[e+3312>>2]){break d}e:{if(H[b|0]?b:0){break e}G[e+3960>>2]=G[e+3964>>2];c=Za(e+3912|0,e+3848|0);g=L[e+120>>3];L[e+3944>>3]=g;f:{switch(G[e+3960>>2]-1|0){case 1:if(g!=1950){E[c|0]=66;L[f>>3]=g;Eb(e+3913|0,18949,f);d=(Va(c)+e|0)+3911|0;if(H[d|0]==48){E[d|0]=0}d=(Va(c)+e|0)+3911|0;if(H[d|0]==48){E[d|0]=0}c=(Va(c)+e|0)+3911|0;if(H[c|0]!=48){break e}E[c|0]=0;break e}d=H[41563]|H[41564]<<8;E[c+4|0]=d;E[c+5|0]=d>>>8;d=H[41559]|H[41560]<<8|(H[41561]<<16|H[41562]<<24);E[c|0]=d;E[c+1|0]=d>>>8;E[c+2|0]=d>>>16;E[c+3|0]=d>>>24;break e;case 0:break f;default:break e}}if(g!=2e3){E[c|0]=74;L[f+16>>3]=g;Eb(e+3913|0,18949,f+16|0);d=(Va(c)+e|0)+3911|0;if(H[d|0]==48){E[d|0]=0}d=(Va(c)+e|0)+3911|0;if(H[d|0]==48){E[d|0]=0}c=(Va(c)+e|0)+3911|0;if(H[c|0]!=48){break e}E[c|0]=0;break e}d=H[41649]|H[41650]<<8;E[c+4|0]=d;E[c+5|0]=d>>>8;d=H[41645]|H[41646]<<8|(H[41647]<<16|H[41648]<<24);E[c|0]=d;E[c+1|0]=d>>>8;E[c+2|0]=d>>>16;E[c+3|0]=d>>>24}c=Nf(b);if((c|0)<0){break d}G[e+3960>>2]=c;i=e,j=Zh(b),L[i+3944>>3]=j;Za(e+3912|0,b)}Fa=f+32|0}b=G[h>>2];if(b){b=G[b+3312>>2]?b+3880|0:0}else{b=0}c=rb(a,b,65536);if(!Xc(c,30677)){E[c+8|0]=H[30685];a=H[30681]|H[30682]<<8|(H[30683]<<16|H[30684]<<24);b=H[30677]|H[30678]<<8|(H[30679]<<16|H[30680]<<24);E[c|0]=b;E[c+1|0]=b>>>8;E[c+2|0]=b>>>16;E[c+3|0]=b>>>24;E[c+4|0]=a;E[c+5|0]=a>>>8;E[c+6|0]=a>>>16;E[c+7|0]=a>>>24;return c|0}if(!Xc(c,30657)){E[c+8|0]=H[30665];a=H[30661]|H[30662]<<8|(H[30663]<<16|H[30664]<<24);b=H[30657]|H[30658]<<8|(H[30659]<<16|H[30660]<<24);E[c|0]=b;E[c+1|0]=b>>>8;E[c+2|0]=b>>>16;E[c+3|0]=b>>>24;E[c+4|0]=a;E[c+5|0]=a>>>8;E[c+6|0]=a>>>16;E[c+7|0]=a>>>24;return c|0}if(!Xc(c,13234)){a=H[13237]|H[13238]<<8|(H[13239]<<16|H[13240]<<24);E[c+3|0]=a;E[c+4|0]=a>>>8;E[c+5|0]=a>>>16;E[c+6|0]=a>>>24;a=H[13234]|H[13235]<<8|(H[13236]<<16|H[13237]<<24);E[c|0]=a;E[c+1|0]=a>>>8;E[c+2|0]=a>>>16;E[c+3|0]=a>>>24;return c|0}b=H[c|0];if(!b){break a}a=c;while(1){b=b<<24>>24;if(b-97>>>0<26){E[a|0]=b-97>>>0<26?b&95:b}b=H[a+1|0];a=a+1|0;if(b){continue}break}}return c|0}function pp(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;a:{if(G[k>>2]>0){break a}b:{m=G[a>>2];l=G[a+4>>2];if((m|0)!=G[l+76>>2]){mb(a,m+1|0,0,k);break b}if((G[l+128>>2]&G[l+132>>2])!=-1){break b}if((Rb(a,k)|0)<=0){break b}return}l=G[G[a+4>>2]+968>>2]+M(b-1|0,160)|0;x=G[l+80>>2];c:{if((x|0)<=0){d:{if((x|0)>=0){break d}if((Ng(a,b,c,d,e,f,g,h,i,k)|0)<=0){break d}if(G[k>>2]!=412){break a}G[k>>2]=0}if(!g&(h|0)<=0|(h|0)<0){break a}l=f+h|0;m=e+g|0;l=m>>>0>>0?l+1|0:l;n=m-1|0;o=l-!m|0;c=Au(n,o,c-1|0,d-!c|0)+e|0;l=f+Ia|0;m=c;u=c>>>0>>0?l+1|0:l;y=j&65535;e=0;f=0;c=0;d=0;while(1){e:{if((y|0)!=I[(q<<1)+i>>1]){if(e|f){l=u+(p-((e>>>0>q>>>0)+f|0)|0)|0;j=m+(q-e|0)|0;l=j>>>0>>0?l+1|0:l;r=l;s=Bu(j-1|0,l-!j|0,n,o);l=Ia;v=l;t=s+1|0;l=t?l:l+1|0;w=l;l=Au(n,o,s,v);if((rc(a,b,t,w,j-l|0,r-(Ia+(j>>>0>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;j=d;c=c+1|0;j=c?j:j+1|0;d=j;break e}l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0}j=q+1|0;p=j?p:p+1|0;q=j;if((g|0)!=(j|0)|(h|0)!=(p|0)){continue}break}break c}if(!g&(h|0)<=0|(h|0)<0){break a}n=G[l+88>>2];o=G[l+92>>2];c=Au(n,o,c-1|0,d-!c|0)+e|0;l=f+Ia|0;m=c;u=c>>>0>>0?l+1|0:l;y=j&65535;e=0;f=0;c=0;d=0;while(1){f:{if((y|0)!=I[(q<<1)+i>>1]){if(e|f){j=u+(p-((e>>>0>q>>>0)+f|0)|0)|0;l=m+(q-e|0)|0;j=l>>>0>>0?j+1|0:j;r=l;s=Bu(l-1|0,j-!l|0,n,o);l=Ia;v=l;t=s+1|0;l=t?l:l+1|0;w=l;l=Au(n,o,s,v);if((rc(a,b,t,w,r-l|0,j-(Ia+(l>>>0>r>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;j=d;c=c+1|0;j=c?j:j+1|0;d=j;break f}g:{if(!(c|d)){break g}l=u+(p-((c>>>0>q>>>0)+d|0)|0)|0;v=q-c|0;j=m+v|0;l=j>>>0>>0?l+1|0:l;r=l;s=Bu(j-1|0,l-!j|0,n,o);l=Ia;t=l;z=s+1|0;l=z?l:l+1|0;w=l;l=Au(n,o,s,t);if((Ng(a,b,z,w,j-l|0,r-(Ia+(j>>>0>>0)|0)|0,c,d,(v<<1)+i|0,k)|0)<=0){break g}if(G[k>>2]!=412){break a}G[k>>2]=0;A=1}j=f;c=e+1|0;j=c?j:j+1|0;e=c;f=j;c=0;d=0}l=p;j=q+1|0;l=j?l:l+1|0;q=j;p=l;if((g|0)!=(j|0)|(h|0)!=(l|0)){continue}break}}h:{if(c|d){if((x|0)<=0){break h}e=a;j=u+(h-((c>>>0>g>>>0)+d|0)|0)|0;l=g-c|0;a=m+l|0;j=a>>>0>>0?j+1|0:j;f=Bu(a-1|0,j-!a|0,n,o);p=Ia;g=p;h=b;b=f+1|0;p=b?g:g+1|0;r=b;b=Au(n,o,f,g);Ng(e,h,r,p,a-b|0,j-(Ia+(a>>>0>>0)|0)|0,c,d,(l<<1)+i|0,k);break h}if(!(e|f)){break h}c=a;j=u+(h-((e>>>0>g>>>0)+f|0)|0)|0;a=m+(g-e|0)|0;j=a>>>0>>0?j+1|0:j;d=j;g=Bu(a-1|0,j-!a|0,n,o);j=Ia;h=j;i=b;b=g+1|0;j=b?j:j+1|0;l=b;b=Au(g,h,n,o);rc(c,i,l,j,a-b|0,d-(Ia+(a>>>0>>0)|0)|0,e,f,k)}if(!A|G[k>>2]>0){break a}G[k>>2]=412}}function Uo(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;a:{if(G[k>>2]>0){break a}b:{m=G[a>>2];l=G[a+4>>2];if((m|0)!=G[l+76>>2]){mb(a,m+1|0,0,k);break b}if((G[l+128>>2]&G[l+132>>2])!=-1){break b}if((Rb(a,k)|0)<=0){break b}return}l=G[G[a+4>>2]+968>>2]+M(b-1|0,160)|0;y=G[l+80>>2];c:{if((y|0)<=0){d:{if((y|0)>=0){break d}if((Ah(a,b,c,d,e,f,g,h,i,k)|0)<=0){break d}if(G[k>>2]!=412){break a}G[k>>2]=0}if(!g&(h|0)<=0|(h|0)<0){break a}l=f+h|0;m=e+g|0;l=m>>>0>>0?l+1|0:l;p=m-1|0;q=l-!m|0;c=Au(p,q,c-1|0,d-!c|0)+e|0;l=f+Ia|0;m=c;v=c>>>0>>0?l+1|0:l;e=0;f=0;c=0;d=0;while(1){e:{if(I[(r<<1)+i>>1]!=(j|0)){if(e|f){l=v+(o-((e>>>0>r>>>0)+f|0)|0)|0;n=m+(r-e|0)|0;l=n>>>0>>0?l+1|0:l;t=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;w=l;u=s+1|0;l=u?l:l+1|0;x=l;l=Au(p,q,s,w);if((rc(a,b,u,x,n-l|0,t-(Ia+(l>>>0>n>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;l=d;c=c+1|0;l=c?l:l+1|0;d=l;break e}l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0}l=r+1|0;o=l?o:o+1|0;r=l;if((g|0)!=(l|0)|(h|0)!=(o|0)){continue}break}break c}if(!g&(h|0)<=0|(h|0)<0){break a}p=G[l+88>>2];q=G[l+92>>2];c=Au(p,q,c-1|0,d-!c|0)+e|0;l=f+Ia|0;m=c;v=c>>>0>>0?l+1|0:l;e=0;f=0;c=0;d=0;while(1){f:{if(I[(r<<1)+i>>1]!=(j|0)){if(e|f){l=v+(o-((e>>>0>r>>>0)+f|0)|0)|0;n=m+(r-e|0)|0;l=n>>>0>>0?l+1|0:l;t=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;w=l;u=s+1|0;l=u?l:l+1|0;x=l;l=Au(p,q,s,w);if((rc(a,b,u,x,n-l|0,t-(Ia+(l>>>0>n>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;l=d;c=c+1|0;l=c?l:l+1|0;d=l;break f}g:{if(!(c|d)){break g}l=v+(o-((c>>>0>r>>>0)+d|0)|0)|0;w=r-c|0;n=m+w|0;l=n>>>0>>0?l+1|0:l;t=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;u=l;z=s+1|0;l=z?l:l+1|0;x=l;l=Au(p,q,s,u);if((Ah(a,b,z,x,n-l|0,t-(Ia+(l>>>0>n>>>0)|0)|0,c,d,(w<<1)+i|0,k)|0)<=0){break g}if(G[k>>2]!=412){break a}G[k>>2]=0;A=1}l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0}l=o;o=r+1|0;l=o?l:l+1|0;r=o;o=l;if((g|0)!=(r|0)|(h|0)!=(l|0)){continue}break}}h:{if(c|d){if((y|0)<=0){break h}e=a;l=v+(h-((c>>>0>g>>>0)+d|0)|0)|0;j=g-c|0;a=m+j|0;l=a>>>0>>0?l+1|0:l;f=Bu(a-1|0,l-!a|0,p,q);o=Ia;g=o;h=b;b=f+1|0;o=b?g:g+1|0;t=b;b=Au(p,q,f,g);Ah(e,h,t,o,a-b|0,l-(Ia+(a>>>0>>0)|0)|0,c,d,(j<<1)+i|0,k);break h}if(!(e|f)){break h}c=a;l=v+(h-((e>>>0>g>>>0)+f|0)|0)|0;a=m+(g-e|0)|0;l=a>>>0>>0?l+1|0:l;d=l;g=Bu(a-1|0,l-!a|0,p,q);l=Ia;h=l;i=b;b=g+1|0;l=b?l:l+1|0;j=b;b=Au(g,h,p,q);rc(c,i,j,l,a-b|0,d-(Ia+(a>>>0>>0)|0)|0,e,f,k)}if(!A|G[k>>2]>0){break a}G[k>>2]=412}}function So(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;a:{if(G[k>>2]>0){break a}b:{m=G[a>>2];l=G[a+4>>2];if((m|0)!=G[l+76>>2]){mb(a,m+1|0,0,k);break b}if((G[l+128>>2]&G[l+132>>2])!=-1){break b}if((Rb(a,k)|0)<=0){break b}return}l=G[G[a+4>>2]+968>>2]+M(b-1|0,160)|0;y=G[l+80>>2];c:{if((y|0)<=0){d:{if((y|0)>=0){break d}if((Qe(a,b,c,d,e,f,g,h,i,k)|0)<=0){break d}if(G[k>>2]!=412){break a}G[k>>2]=0}if(!g&(h|0)<=0|(h|0)<0){break a}l=f+h|0;m=e+g|0;l=m>>>0>>0?l+1|0:l;p=m-1|0;q=l-!m|0;c=Au(p,q,c-1|0,d-!c|0)+e|0;l=f+Ia|0;m=c;v=c>>>0>>0?l+1|0:l;e=0;f=0;c=0;d=0;while(1){e:{if(G[(r<<2)+i>>2]!=(j|0)){if(e|f){l=v+(o-((e>>>0>r>>>0)+f|0)|0)|0;n=m+(r-e|0)|0;l=n>>>0>>0?l+1|0:l;t=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;w=l;u=s+1|0;l=u?l:l+1|0;x=l;l=Au(p,q,s,w);if((rc(a,b,u,x,n-l|0,t-(Ia+(l>>>0>n>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;l=d;c=c+1|0;l=c?l:l+1|0;d=l;break e}l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0}l=r+1|0;o=l?o:o+1|0;r=l;if((g|0)!=(l|0)|(h|0)!=(o|0)){continue}break}break c}if(!g&(h|0)<=0|(h|0)<0){break a}p=G[l+88>>2];q=G[l+92>>2];c=Au(p,q,c-1|0,d-!c|0)+e|0;l=f+Ia|0;m=c;v=c>>>0>>0?l+1|0:l;e=0;f=0;c=0;d=0;while(1){f:{if(G[(r<<2)+i>>2]!=(j|0)){if(e|f){l=v+(o-((e>>>0>r>>>0)+f|0)|0)|0;n=m+(r-e|0)|0;l=n>>>0>>0?l+1|0:l;t=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;w=l;u=s+1|0;l=u?l:l+1|0;x=l;l=Au(p,q,s,w);if((rc(a,b,u,x,n-l|0,t-(Ia+(l>>>0>n>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;l=d;c=c+1|0;l=c?l:l+1|0;d=l;break f}g:{if(!(c|d)){break g}l=v+(o-((c>>>0>r>>>0)+d|0)|0)|0;w=r-c|0;n=m+w|0;l=n>>>0>>0?l+1|0:l;t=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;u=l;z=s+1|0;l=z?l:l+1|0;x=l;l=Au(p,q,s,u);if((Qe(a,b,z,x,n-l|0,t-(Ia+(l>>>0>n>>>0)|0)|0,c,d,(w<<2)+i|0,k)|0)<=0){break g}if(G[k>>2]!=412){break a}G[k>>2]=0;A=1}l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0}l=o;o=r+1|0;l=o?l:l+1|0;r=o;o=l;if((g|0)!=(r|0)|(h|0)!=(l|0)){continue}break}}h:{if(c|d){if((y|0)<=0){break h}e=a;l=v+(h-((c>>>0>g>>>0)+d|0)|0)|0;j=g-c|0;a=m+j|0;l=a>>>0>>0?l+1|0:l;f=Bu(a-1|0,l-!a|0,p,q);o=Ia;g=o;h=b;b=f+1|0;o=b?g:g+1|0;t=b;b=Au(p,q,f,g);Qe(e,h,t,o,a-b|0,l-(Ia+(a>>>0>>0)|0)|0,c,d,(j<<2)+i|0,k);break h}if(!(e|f)){break h}c=a;l=v+(h-((e>>>0>g>>>0)+f|0)|0)|0;a=m+(g-e|0)|0;l=a>>>0>>0?l+1|0:l;d=l;g=Bu(a-1|0,l-!a|0,p,q);l=Ia;h=l;i=b;b=g+1|0;l=b?l:l+1|0;j=b;b=Au(g,h,p,q);rc(c,i,j,l,a-b|0,d-(Ia+(a>>>0>>0)|0)|0,e,f,k)}if(!A|G[k>>2]>0){break a}G[k>>2]=412}}function Lo(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;a:{if(G[k>>2]>0){break a}b:{m=G[a>>2];l=G[a+4>>2];if((m|0)!=G[l+76>>2]){mb(a,m+1|0,0,k);break b}if((G[l+128>>2]&G[l+132>>2])!=-1){break b}if((Rb(a,k)|0)<=0){break b}return}l=G[G[a+4>>2]+968>>2]+M(b-1|0,160)|0;y=G[l+80>>2];c:{if((y|0)<=0){d:{if((y|0)>=0){break d}if((xe(a,b,c,d,e,f,g,h,i,k)|0)<=0){break d}if(G[k>>2]!=412){break a}G[k>>2]=0}if(!g&(h|0)<=0|(h|0)<0){break a}l=f+h|0;m=e+g|0;l=m>>>0>>0?l+1|0:l;p=m-1|0;q=l-!m|0;c=Au(p,q,c-1|0,d-!c|0)+e|0;l=f+Ia|0;m=c;v=c>>>0>>0?l+1|0:l;e=0;f=0;c=0;d=0;while(1){e:{if(G[(r<<2)+i>>2]!=(j|0)){if(e|f){l=v+(o-((e>>>0>r>>>0)+f|0)|0)|0;n=m+(r-e|0)|0;l=n>>>0>>0?l+1|0:l;t=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;w=l;u=s+1|0;l=u?l:l+1|0;x=l;l=Au(p,q,s,w);if((rc(a,b,u,x,n-l|0,t-(Ia+(l>>>0>n>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;l=d;c=c+1|0;l=c?l:l+1|0;d=l;break e}l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0}l=r+1|0;o=l?o:o+1|0;r=l;if((g|0)!=(l|0)|(h|0)!=(o|0)){continue}break}break c}if(!g&(h|0)<=0|(h|0)<0){break a}p=G[l+88>>2];q=G[l+92>>2];c=Au(p,q,c-1|0,d-!c|0)+e|0;l=f+Ia|0;m=c;v=c>>>0>>0?l+1|0:l;e=0;f=0;c=0;d=0;while(1){f:{if(G[(r<<2)+i>>2]!=(j|0)){if(e|f){l=v+(o-((e>>>0>r>>>0)+f|0)|0)|0;n=m+(r-e|0)|0;l=n>>>0>>0?l+1|0:l;t=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;w=l;u=s+1|0;l=u?l:l+1|0;x=l;l=Au(p,q,s,w);if((rc(a,b,u,x,n-l|0,t-(Ia+(l>>>0>n>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;l=d;c=c+1|0;l=c?l:l+1|0;d=l;break f}g:{if(!(c|d)){break g}l=v+(o-((c>>>0>r>>>0)+d|0)|0)|0;w=r-c|0;n=m+w|0;l=n>>>0>>0?l+1|0:l;t=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;u=l;z=s+1|0;l=z?l:l+1|0;x=l;l=Au(p,q,s,u);if((xe(a,b,z,x,n-l|0,t-(Ia+(l>>>0>n>>>0)|0)|0,c,d,(w<<2)+i|0,k)|0)<=0){break g}if(G[k>>2]!=412){break a}G[k>>2]=0;A=1}l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0}l=o;o=r+1|0;l=o?l:l+1|0;r=o;o=l;if((g|0)!=(r|0)|(h|0)!=(l|0)){continue}break}}h:{if(c|d){if((y|0)<=0){break h}e=a;l=v+(h-((c>>>0>g>>>0)+d|0)|0)|0;j=g-c|0;a=m+j|0;l=a>>>0>>0?l+1|0:l;f=Bu(a-1|0,l-!a|0,p,q);o=Ia;g=o;h=b;b=f+1|0;o=b?g:g+1|0;t=b;b=Au(p,q,f,g);xe(e,h,t,o,a-b|0,l-(Ia+(a>>>0>>0)|0)|0,c,d,(j<<2)+i|0,k);break h}if(!(e|f)){break h}c=a;l=v+(h-((e>>>0>g>>>0)+f|0)|0)|0;a=m+(g-e|0)|0;l=a>>>0>>0?l+1|0:l;d=l;g=Bu(a-1|0,l-!a|0,p,q);l=Ia;h=l;i=b;b=g+1|0;l=b?l:l+1|0;j=b;b=Au(g,h,p,q);rc(c,i,j,l,a-b|0,d-(Ia+(a>>>0>>0)|0)|0,e,f,k)}if(!A|G[k>>2]>0){break a}G[k>>2]=412}}function nq(a,b){var c=0,d=0,e=0,f=0,g=0;f=Fa-272|0;Fa=f;a:{if(G[b>>2]>0){break a}G[f+12>>2]=0;if(Fc(a,34409,f+96|0,f+16|0,f+12|0)){lc(a,34409,41661,44530,b);if(G[b>>2]>0){break a}E[f+184|0]=H[66595];c=H[66591]|H[66592]<<8|(H[66593]<<16|H[66594]<<24);G[f+176>>2]=H[66587]|H[66588]<<8|(H[66589]<<16|H[66590]<<24);G[f+180>>2]=c;c=f+176|0;bb(Va(c)+c|0,20722,65);wb(a,c,b);if(G[b>>2]>0){break a}d=H[66595];E[f+184|0]=d;g=H[66591]|H[66592]<<8|(H[66593]<<16|H[66594]<<24);c=H[66587]|H[66588]<<8|(H[66589]<<16|H[66590]<<24);G[f+176>>2]=c;G[f+180>>2]=g;e=f+176|0;bb(Va(e)+e|0,65329,71);wb(a,e,b);if(G[b>>2]>0){break a}E[f+184|0]=d;G[f+176>>2]=c;G[f+180>>2]=g;c=f+176|0;bb(Va(c)+c|0,27920,65);wb(a,c,b);if(G[b>>2]>0){break a}E[f+184|0]=H[66595];c=H[66591]|H[66592]<<8|(H[66593]<<16|H[66594]<<24);G[f+176>>2]=H[66587]|H[66588]<<8|(H[66589]<<16|H[66590]<<24);G[f+180>>2]=c;g=f+176|0;c=Va(g)+g|0;e=H[45194]|H[45195]<<8|(H[45196]<<16|H[45197]<<24);d=H[45190]|H[45191]<<8|(H[45192]<<16|H[45193]<<24);E[c|0]=d;E[c+1|0]=d>>>8;E[c+2|0]=d>>>16;E[c+3|0]=d>>>24;E[c+4|0]=e;E[c+5|0]=e>>>8;E[c+6|0]=e>>>16;E[c+7|0]=e>>>24;d=H[45237]|H[45238]<<8|(H[45239]<<16|H[45240]<<24);E[c+47|0]=d;E[c+48|0]=d>>>8;E[c+49|0]=d>>>16;E[c+50|0]=d>>>24;e=H[45234]|H[45235]<<8|(H[45236]<<16|H[45237]<<24);d=H[45230]|H[45231]<<8|(H[45232]<<16|H[45233]<<24);E[c+40|0]=d;E[c+41|0]=d>>>8;E[c+42|0]=d>>>16;E[c+43|0]=d>>>24;E[c+44|0]=e;E[c+45|0]=e>>>8;E[c+46|0]=e>>>16;E[c+47|0]=e>>>24;e=H[45226]|H[45227]<<8|(H[45228]<<16|H[45229]<<24);d=H[45222]|H[45223]<<8|(H[45224]<<16|H[45225]<<24);E[c+32|0]=d;E[c+33|0]=d>>>8;E[c+34|0]=d>>>16;E[c+35|0]=d>>>24;E[c+36|0]=e;E[c+37|0]=e>>>8;E[c+38|0]=e>>>16;E[c+39|0]=e>>>24;e=H[45218]|H[45219]<<8|(H[45220]<<16|H[45221]<<24);d=H[45214]|H[45215]<<8|(H[45216]<<16|H[45217]<<24);E[c+24|0]=d;E[c+25|0]=d>>>8;E[c+26|0]=d>>>16;E[c+27|0]=d>>>24;E[c+28|0]=e;E[c+29|0]=e>>>8;E[c+30|0]=e>>>16;E[c+31|0]=e>>>24;e=H[45210]|H[45211]<<8|(H[45212]<<16|H[45213]<<24);d=H[45206]|H[45207]<<8|(H[45208]<<16|H[45209]<<24);E[c+16|0]=d;E[c+17|0]=d>>>8;E[c+18|0]=d>>>16;E[c+19|0]=d>>>24;E[c+20|0]=e;E[c+21|0]=e>>>8;E[c+22|0]=e>>>16;E[c+23|0]=e>>>24;e=H[45202]|H[45203]<<8|(H[45204]<<16|H[45205]<<24);d=H[45198]|H[45199]<<8|(H[45200]<<16|H[45201]<<24);E[c+8|0]=d;E[c+9|0]=d>>>8;E[c+10|0]=d>>>16;E[c+11|0]=d>>>24;E[c+12|0]=e;E[c+13|0]=e>>>8;E[c+14|0]=e>>>16;E[c+15|0]=e>>>24;wb(a,g,b)}}Fa=f+272|0}function Xo(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;a:{if(G[k>>2]>0){break a}b:{m=G[a>>2];l=G[a+4>>2];if((m|0)!=G[l+76>>2]){mb(a,m+1|0,0,k);break b}if((G[l+128>>2]&G[l+132>>2])!=-1){break b}if((Rb(a,k)|0)<=0){break b}return}l=G[G[a+4>>2]+968>>2]+M(b-1|0,160)|0;x=G[l+80>>2];c:{if((x|0)<=0){d:{if((x|0)>=0){break d}if((Bh(a,b,c,d,e,f,g,h,i,k)|0)<=0){break d}if(G[k>>2]!=412){break a}G[k>>2]=0}if(!g&(h|0)<=0|(h|0)<0){break a}l=f+h|0;m=e+g|0;l=m>>>0>>0?l+1|0:l;n=m-1|0;o=l-!m|0;c=Au(n,o,c-1|0,d-!c|0)+e|0;l=f+Ia|0;m=c;u=c>>>0>>0?l+1|0:l;y=j&255;e=0;f=0;c=0;d=0;while(1){e:{if((y|0)!=H[i+q|0]){if(e|f){l=u+(p-((e>>>0>q>>>0)+f|0)|0)|0;j=m+(q-e|0)|0;l=j>>>0>>0?l+1|0:l;r=l;s=Bu(j-1|0,l-!j|0,n,o);l=Ia;v=l;t=s+1|0;l=t?l:l+1|0;w=l;l=Au(n,o,s,v);if((rc(a,b,t,w,j-l|0,r-(Ia+(j>>>0>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;j=d;c=c+1|0;j=c?j:j+1|0;d=j;break e}l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0}j=q+1|0;p=j?p:p+1|0;q=j;if((g|0)!=(j|0)|(h|0)!=(p|0)){continue}break}break c}if(!g&(h|0)<=0|(h|0)<0){break a}n=G[l+88>>2];o=G[l+92>>2];c=Au(n,o,c-1|0,d-!c|0)+e|0;l=f+Ia|0;m=c;u=c>>>0>>0?l+1|0:l;y=j&255;e=0;f=0;c=0;d=0;while(1){f:{if((y|0)!=H[i+q|0]){if(e|f){j=u+(p-((e>>>0>q>>>0)+f|0)|0)|0;l=m+(q-e|0)|0;j=l>>>0>>0?j+1|0:j;r=l;s=Bu(l-1|0,j-!l|0,n,o);l=Ia;v=l;t=s+1|0;l=t?l:l+1|0;w=l;l=Au(n,o,s,v);if((rc(a,b,t,w,r-l|0,j-(Ia+(l>>>0>r>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;j=d;c=c+1|0;j=c?j:j+1|0;d=j;break f}g:{if(!(c|d)){break g}l=u+(p-((c>>>0>q>>>0)+d|0)|0)|0;v=q-c|0;j=m+v|0;l=j>>>0>>0?l+1|0:l;r=l;s=Bu(j-1|0,l-!j|0,n,o);l=Ia;t=l;z=s+1|0;l=z?l:l+1|0;w=l;l=Au(n,o,s,t);if((Bh(a,b,z,w,j-l|0,r-(Ia+(j>>>0>>0)|0)|0,c,d,i+v|0,k)|0)<=0){break g}if(G[k>>2]!=412){break a}G[k>>2]=0;A=1}j=f;c=e+1|0;j=c?j:j+1|0;e=c;f=j;c=0;d=0}l=p;j=q+1|0;l=j?l:l+1|0;q=j;p=l;if((g|0)!=(j|0)|(h|0)!=(l|0)){continue}break}}h:{if(c|d){if((x|0)<=0){break h}e=a;j=u+(h-((c>>>0>g>>>0)+d|0)|0)|0;l=g-c|0;a=m+l|0;j=a>>>0>>0?j+1|0:j;f=Bu(a-1|0,j-!a|0,n,o);p=Ia;g=p;h=b;b=f+1|0;p=b?g:g+1|0;r=b;b=Au(n,o,f,g);Bh(e,h,r,p,a-b|0,j-(Ia+(a>>>0>>0)|0)|0,c,d,i+l|0,k);break h}if(!(e|f)){break h}c=a;j=u+(h-((e>>>0>g>>>0)+f|0)|0)|0;a=m+(g-e|0)|0;j=a>>>0>>0?j+1|0:j;d=j;g=Bu(a-1|0,j-!a|0,n,o);j=Ia;h=j;i=b;b=g+1|0;j=b?j:j+1|0;l=b;b=Au(g,h,n,o);rc(c,i,l,j,a-b|0,d-(Ia+(a>>>0>>0)|0)|0,e,f,k)}if(!A|G[k>>2]>0){break a}G[k>>2]=412}}function qp(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;a:{if(G[k>>2]>0){break a}b:{m=G[a>>2];l=G[a+4>>2];if((m|0)!=G[l+76>>2]){mb(a,m+1|0,0,k);break b}if((G[l+128>>2]&G[l+132>>2])!=-1){break b}if((Rb(a,k)|0)<=0){break b}return}l=G[G[a+4>>2]+968>>2]+M(b-1|0,160)|0;y=G[l+80>>2];c:{if((y|0)<=0){d:{if((y|0)>=0){break d}if((pe(a,b,c,d,e,f,g,h,i,k)|0)<=0){break d}if(G[k>>2]!=412){break a}G[k>>2]=0}if(!g&(h|0)<=0|(h|0)<0){break a}l=f+h|0;m=e+g|0;l=m>>>0>>0?l+1|0:l;p=m-1|0;q=l-!m|0;c=Au(p,q,c-1|0,d-!c|0)+e|0;l=f+Ia|0;m=c;v=c>>>0>>0?l+1|0:l;e=0;f=0;c=0;d=0;while(1){e:{if(H[i+r|0]!=(j|0)){if(e|f){l=v+(o-((e>>>0>r>>>0)+f|0)|0)|0;n=m+(r-e|0)|0;l=n>>>0>>0?l+1|0:l;t=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;w=l;u=s+1|0;l=u?l:l+1|0;x=l;l=Au(p,q,s,w);if((rc(a,b,u,x,n-l|0,t-(Ia+(l>>>0>n>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;l=d;c=c+1|0;l=c?l:l+1|0;d=l;break e}l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0}l=r+1|0;o=l?o:o+1|0;r=l;if((g|0)!=(l|0)|(h|0)!=(o|0)){continue}break}break c}if(!g&(h|0)<=0|(h|0)<0){break a}p=G[l+88>>2];q=G[l+92>>2];c=Au(p,q,c-1|0,d-!c|0)+e|0;l=f+Ia|0;m=c;v=c>>>0>>0?l+1|0:l;e=0;f=0;c=0;d=0;while(1){f:{if(H[i+r|0]!=(j|0)){if(e|f){l=v+(o-((e>>>0>r>>>0)+f|0)|0)|0;n=m+(r-e|0)|0;l=n>>>0>>0?l+1|0:l;t=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;w=l;u=s+1|0;l=u?l:l+1|0;x=l;l=Au(p,q,s,w);if((rc(a,b,u,x,n-l|0,t-(Ia+(l>>>0>n>>>0)|0)|0,e,f,k)|0)>0){break a}}e=0;f=0;l=d;c=c+1|0;l=c?l:l+1|0;d=l;break f}g:{if(!(c|d)){break g}l=v+(o-((c>>>0>r>>>0)+d|0)|0)|0;w=r-c|0;n=m+w|0;l=n>>>0>>0?l+1|0:l;t=l;s=Bu(n-1|0,l-!n|0,p,q);l=Ia;u=l;z=s+1|0;l=z?l:l+1|0;x=l;l=Au(p,q,s,u);if((pe(a,b,z,x,n-l|0,t-(Ia+(l>>>0>n>>>0)|0)|0,c,d,i+w|0,k)|0)<=0){break g}if(G[k>>2]!=412){break a}G[k>>2]=0;A=1}l=f;c=e+1|0;l=c?l:l+1|0;e=c;f=l;c=0;d=0}l=o;o=r+1|0;l=o?l:l+1|0;r=o;o=l;if((g|0)!=(r|0)|(h|0)!=(l|0)){continue}break}}h:{if(c|d){if((y|0)<=0){break h}e=a;l=v+(h-((c>>>0>g>>>0)+d|0)|0)|0;j=g-c|0;a=m+j|0;l=a>>>0>>0?l+1|0:l;f=Bu(a-1|0,l-!a|0,p,q);o=Ia;g=o;h=b;b=f+1|0;o=b?g:g+1|0;t=b;b=Au(p,q,f,g);pe(e,h,t,o,a-b|0,l-(Ia+(a>>>0>>0)|0)|0,c,d,i+j|0,k);break h}if(!(e|f)){break h}c=a;l=v+(h-((e>>>0>g>>>0)+f|0)|0)|0;a=m+(g-e|0)|0;l=a>>>0>>0?l+1|0:l;d=l;g=Bu(a-1|0,l-!a|0,p,q);l=Ia;h=l;i=b;b=g+1|0;l=b?l:l+1|0;j=b;b=Au(g,h,p,q);rc(c,i,j,l,a-b|0,d-(Ia+(a>>>0>>0)|0)|0,e,f,k)}if(!A|G[k>>2]>0){break a}G[k>>2]=412}}function Gd(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=N(0);f=Fa-208|0;Fa=f;g=G[e>>2];a:{if((g|0)>0){break a}if(b){G[b>>2]=0}if(c){G[c>>2]=0}if(d){G[d>>2]=0}g=0;while(1){h=a+g|0;g=g+1|0;if(H[h|0]==32){continue}break}b:{if(Va(h)>>>0>=71){tb(5,56692);break b}j=Za(f+32|0,h);i=Va(j);if(i){g=0;while(1){h=g+j|0;k=E[h|0];E[h|0]=k-97>>>0<26?k&95:k;g=g+1|0;if((i|0)!=(g|0)){continue}break}}g=H[j|0];if(!g){tb(5,17083);break b}h=16;c:{if((g|0)==65){break c}h=41;l=1;d:{e:{switch(g-68|0){case 0:h=82;break d;default:G[f+16>>2]=a;a=f+112|0;Ya(a,81,64785,f+16|0);tb(5,a);g=262;G[e>>2]=262;break a;case 5:break c;case 1:case 2:break e}}h=42}l=0}if(b){G[b>>2]=h}k=j+1|0;f:{g:{h:{if(!(!l&(g|0)!=65)){if(G[e>>2]>0){break g}G[48624]=0;g=nc(k,f+204|0,10);if((H[G[f+204>>2]]|32)!=32){G[e>>2]=407}if(G[48624]==68){i=H[67017]|H[67018]<<8|(H[67019]<<16|H[67020]<<24);d=H[67013]|H[67014]<<8|(H[67015]<<16|H[67016]<<24);F[f+158>>1]=d;F[f+160>>1]=d>>>16;F[f+162>>1]=i;F[f+164>>1]=i>>>16;d=H[67011]|H[67012]<<8|(H[67013]<<16|H[67014]<<24);G[f+152>>2]=H[67007]|H[67008]<<8|(H[67009]<<16|H[67010]<<24);G[f+156>>2]=d;d=H[67003]|H[67004]<<8|(H[67005]<<16|H[67006]<<24);G[f+144>>2]=H[66999]|H[67e3]<<8|(H[67001]<<16|H[67002]<<24);G[f+148>>2]=d;d=H[66995]|H[66996]<<8|(H[66997]<<16|H[66998]<<24);G[f+136>>2]=H[66991]|H[66992]<<8|(H[66993]<<16|H[66994]<<24);G[f+140>>2]=d;d=H[66987]|H[66988]<<8|(H[66989]<<16|H[66990]<<24);G[f+128>>2]=H[66983]|H[66984]<<8|(H[66985]<<16|H[66986]<<24);G[f+132>>2]=d;d=H[66979]|H[66980]<<8|(H[66981]<<16|H[66982]<<24);G[f+120>>2]=H[66975]|H[66976]<<8|(H[66977]<<16|H[66978]<<24);G[f+124>>2]=d;d=H[66971]|H[66972]<<8|(H[66973]<<16|H[66974]<<24);G[f+112>>2]=H[66967]|H[66968]<<8|(H[66969]<<16|H[66970]<<24);G[f+116>>2]=d;tb(5,qb(f+112|0,k,25));G[e>>2]=412;G[48624]=0}if(G[e>>2]>0){break g}if((g|0)<=0){g=0;break g}h=l?g>>>0<5?21:h:h;break h}if((sk(k,f+108|0,e)|0)>0){break h}m=K[f+108>>2];if(m<=N(0)){break g}l=H[j|0]==70?82:h;if(N(O(m))7?l:h;i=(g|0)<10;if(H[(i?2:3)+j|0]!=46){break h}if((ue((i?3:4)+j|0,f+204|0,e)|0)>0){break h}i=G[f+204>>2];if(d){G[d>>2]=i}if((g|0)<=(i|0)){G[e>>2]=261}h=(i|0)>6?H[j|0]==69?82:h:h}if(G[e>>2]<=0){break f}}G[e>>2]=261;G[f>>2]=a;a=f+112|0;Ya(a,81,64827,f);tb(5,a)}if(b){G[b>>2]=h}if(c){G[c>>2]=g}g=G[e>>2];break a}g=261;G[e>>2]=261}Fa=f+208|0;return g}function vg(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;g=Ye(a,b);a:{if(!g){break a}a=jb(g,47);b=jb(g,45);b:{if(a>>>0>g>>>0){E[a|0]=0;e=sb(g);E[a|0]=47;d=a+1|0;if(O(e)<2147483648){a=~~e}else{a=-2147483648}b=jb(d,47);if(!b){b=jb(d,45)}if(b>>>0<=g>>>0){break a}E[b|0]=0;e=sb(d);E[b|0]=47;f=(a|0)>31;k=sb(b+1|0);c:{if(O(k)<2147483648){d=~~k;break c}d=-2147483648}b=f?a:d;g=b>>>0<50?b+2e3|0:(b|0)<100?b+1900|0:b;b=(((g|0)%100|0)!=0|!((g|0)%400|0))&!(g&3);G[47545]=b?29:28;d=f?d:a;h=(d|0)>1?d:1;if(O(e)<2147483648){a=~~e}else{a=-2147483648}e=b?366:365;b=a;f=b-1|0;a=G[(f<<2)+190176>>2];a=((a|0)<(d|0)?a:h)-1|0;d:{if((b|0)<2){break d}h=f&3;e:{if(b-2>>>0<3){b=0;break e}i=f&-4;b=0;f=0;while(1){d=b<<2;a=G[(d|12)+190176>>2]+(G[(d|8)+190176>>2]+(G[(d|4)+190176>>2]+(G[d+190176>>2]+a|0)|0)|0)|0;b=b+4|0;f=f+4|0;if((i|0)!=(f|0)){continue}break}}if(!h){break d}while(1){a=G[(b<<2)+190176>>2]+a|0;b=b+1|0;j=j+1|0;if((h|0)!=(j|0)){continue}break}}e=+(a|0)/e+ +(g|0);break b}if(b>>>0<=g>>>0){break a}E[b|0]=0;e=sb(g);E[b|0]=45;d=1;f=b+1|0;b=jb(f,45);i=b>>>0<=g>>>0;if(O(e)<2147483648){a=~~e}else{a=-2147483648}h=1;f:{if(i){break f}E[b|0]=0;e=sb(f);E[b|0]=45;b=b+1|0;j=jb(b,84);f=g>>>0>>0;if(O(e)<2147483648){d=~~e}else{d=-2147483648}g:{if(!f){e=sb(b);if(!(O(e)<2147483648)){break g}h=~~e;break f}E[j|0]=0;e=sb(b);E[j|0]=84;if(!(O(e)<2147483648)){break g}h=~~e;break f}h=-2147483648}b=0;m=(a|0)<32;i=m?h+1900|0:a;f=(((i|0)%100|0)!=0|!((i|0)%400|0))&!(i&3);G[47545]=f?29:28;k=f?366:365;f=1;n=d-1|0;o=G[(n<<2)+190176>>2];a=m?a:h;a=((a|0)>(o|0)?o:(a|0)>1?a:1)-1|0;h:{if((d|0)<2){break h}if(d-2>>>0>=3){m=n&-4;h=0;while(1){d=b<<2;a=G[(d|12)+190176>>2]+(G[(d|8)+190176>>2]+(G[(d|4)+190176>>2]+(G[d+190176>>2]+a|0)|0)|0)|0;b=b+4|0;h=h+4|0;if((m|0)!=(h|0)){continue}break}}h=n&3;if(!h){break h}d=0;while(1){a=G[(b<<2)+190176>>2]+a|0;b=b+1|0;d=d+1|0;if((h|0)!=(d|0)){continue}break}}L[c>>3]=+(a|0)/k+ +(i|0);if(g>>>0>=j>>>0){break a}b=0;e=0;d=j+1|0;a=jb(d,58);i:{if(a>>>0<=g>>>0){a=0;break i}E[a|0]=0;l=sb(d);E[a|0]=58;d=a+1|0;a=jb(d,58);g=a>>>0<=g>>>0;if(O(l)<2147483648){b=~~l}else{b=-2147483648}if(!g){E[a|0]=0;e=sb(d);E[a|0]=58;d=a+1|0;if(O(e)<2147483648){a=~~e;e=sb(d);break i}a=-2147483648;e=sb(d);break i}l=sb(d);if(O(l)<2147483648){a=~~l;break i}a=-2147483648}e=L[c>>3]+(e+(+(b|0)*3600+ +(a|0)*60))/86400/k}L[c>>3]=e;f=1}return f}function Sm(a,b,c,d,e,f,g,h){var i=0,j=0,k=0,l=0;i=Fa-112|0;Fa=i;g=g!=0?g:1;a:{if(!h){break a}k=L[h+8>>3];l=L[h>>3];E[i|0]=0;G[i+96>>2]=0;G[i+100>>2]=0;G[i+108>>2]=0;Cb(a,82,41201,i+96|0,i,i+108|0);if(!G[i+108>>2]){L[i+96>>3]=(L[i+96>>3]+1-l+-.5)/g+.5;Jc(b,82,41201,i+96|0,i,i+108|0)}E[i|0]=0;G[i+96>>2]=0;G[i+100>>2]=0;G[i+108>>2]=0;Cb(a,82,40799,i+96|0,i,i+108|0);if(!G[i+108>>2]){L[i+96>>3]=(L[i+96>>3]+1-k+-.5)/g+.5;Jc(b,82,40799,i+96|0,i,i+108|0)}E[i|0]=0;G[i+96>>2]=0;G[i+100>>2]=0;G[i+108>>2]=0;Cb(a,82,41234,i+96|0,i,i+108|0);if(!G[i+108>>2]){L[i+96>>3]=g*L[i+96>>3];Jc(b,82,41234,i+96|0,i,i+108|0)}E[i|0]=0;G[i+96>>2]=0;G[i+100>>2]=0;G[i+108>>2]=0;Cb(a,82,40826,i+96|0,i,i+108|0);if(!G[i+108>>2]){L[i+96>>3]=g*L[i+96>>3];Jc(b,82,40826,i+96|0,i,i+108|0)}E[i|0]=0;G[i+96>>2]=0;G[i+100>>2]=0;G[i+108>>2]=0;Cb(a,82,41174,i+96|0,i,i+108|0);if(!G[i+108>>2]){L[i+96>>3]=g*L[i+96>>3];Jc(b,82,41174,i+96|0,i,i+108|0)}E[i|0]=0;G[i+96>>2]=0;G[i+100>>2]=0;G[i+108>>2]=0;Cb(a,82,40778,i+96|0,i,i+108|0);if(!G[i+108>>2]){L[i+96>>3]=g*L[i+96>>3];Jc(b,82,40778,i+96|0,i,i+108|0)}E[i|0]=0;G[i+96>>2]=0;G[i+100>>2]=0;G[i+108>>2]=0;Cb(a,82,41149,i+96|0,i,i+108|0);if(!G[i+108>>2]){L[i+96>>3]=g*L[i+96>>3];Jc(b,82,41149,i+96|0,i,i+108|0)}E[i|0]=0;G[i+96>>2]=0;G[i+100>>2]=0;G[i+108>>2]=0;Cb(a,82,40759,i+96|0,i,i+108|0);if(G[i+108>>2]){break a}L[i+96>>3]=g*L[i+96>>3];Jc(b,82,40759,i+96|0,i,i+108|0)}if(!(!e|!f)){E[i|0]=0;G[i+96>>2]=0;G[i+100>>2]=1072693248;G[i+108>>2]=0;h=i+96|0;j=i+108|0;Cb(a,82,41167,h,i,j);G[i+108>>2]=0;L[i+96>>3]=L[i+96>>3]/g;Jc(b,82,41167,h,i,j);E[i|0]=0;G[i+96>>2]=0;G[i+100>>2]=0;G[i+108>>2]=0;Cb(a,82,40771,h,i,j);G[i+108>>2]=0;L[i+96>>3]=L[i+96>>3]/g;Jc(b,82,40771,h,i,j);E[i|0]=0;G[i+96>>2]=0;G[i+100>>2]=0;G[i+108>>2]=0;Cb(a,82,41142,h,i,j);G[i+108>>2]=0;L[i+96>>3]=L[i+96>>3]/g;Jc(b,82,41142,h,i,j);E[i|0]=0;G[i+96>>2]=0;G[i+100>>2]=1072693248;G[i+108>>2]=0;Cb(a,82,40752,h,i,j);G[i+108>>2]=0;L[i+96>>3]=L[i+96>>3]/g;Jc(b,82,40752,h,i,j);E[i|0]=0;G[i+96>>2]=0;G[i+100>>2]=0;G[i+108>>2]=0;Cb(a,82,41229,h,i,j);G[i+108>>2]=0;L[i+96>>3]=(L[i+96>>3]-(+(c|0)+ +(e|0)*-.5)+-.5)/g+.5;Jc(b,82,41229,h,i,j);E[i|0]=0;G[i+96>>2]=0;G[i+100>>2]=0;G[i+108>>2]=0;Cb(a,82,40821,h,i,j);G[i+108>>2]=0;L[i+96>>3]=(L[i+96>>3]-(+(d|0)+ +(f|0)*-.5)+-.5)/g+.5;Jc(b,82,40821,h,i,j)}Fa=i+112|0}function Xs(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;c=G[309722];i=c+M(G[a+12>>2],344)|0;e=G[i>>2];d=(e|0)==-1e3?i+88|0:0;g=c+M(G[a+16>>2],344)|0;h=G[g>>2];c=(h|0)==-1e3?g+88|0:0;a:{b:{c:{if(!((e|0)!=-1e3|(h|0)!=-1e3)){d:{e:{f:{g:{h:{i:{j:{k:{b=G[a>>2];switch(b-278|0){case 0:break i;case 1:break j;case 6:case 7:case 8:case 9:case 10:case 11:break b;case 12:break e;case 2:case 3:case 4:case 5:break h;default:break k}}switch(b-38|0){case 1:case 2:case 3:case 4:break b;case 5:break f;case 0:break g;default:break d}}k=a,l=!ni(d,c),E[k+88|0]=l;break b}k=a,l=ni(d,c),E[k+88|0]=l;break b}k=a,l=nn(d,b,c),E[k+88|0]=l;break b}mn(a+88|0,d,c);break b}Gb(Za(a+88|0,d),c);break b}c=0;G[a+88>>2]=0;while(1){b=H[d|0];l:{if((b|0)!=49){if(b){break l}break b}c=c+1|0;G[a+88>>2]=c}d=d+1|0;continue}}if((b|0)==124){break c}break b}Nd(a);if(G[309737]){break a}b=G[309727];m:{n:{o:{p:{q:{f=G[a>>2];switch(f-278|0){case 6:case 7:case 8:case 9:case 10:case 11:break a;case 12:break m;case 0:case 1:case 2:case 3:case 4:case 5:break p;default:break q}}switch(f-38|0){case 1:case 2:case 3:case 4:break a;case 0:case 5:break n;default:break o}}if(!b){break a}f=(e|0)==-1e3;while(1){b=b-1|0;d=f?d:G[G[i+88>>2]+(b<<2)>>2];c=(h|0)!=-1e3?G[G[g+88>>2]+(b<<2)>>2]:c;r:{s:{t:{u:{v:{e=G[a>>2];switch(e-278|0){case 2:case 3:case 4:case 5:break t;case 0:break u;case 1:break v;default:break r}}e=!ni(d,c);break s}e=ni(d,c);break s}e=nn(d,e,c)}E[G[a+88>>2]+b|0]=e}E[G[a+84>>2]+b|0]=0;if(b){continue}break}break a}if((f|0)!=124){break a}}if(!b){break a}e=(e|0)==-1e3;while(1){b=b-1|0;d=e?d:G[G[i+88>>2]+(b<<2)>>2];c=(h|0)!=-1e3?G[G[g+88>>2]+(b<<2)>>2]:c;w:{f=G[a>>2];if((f|0)!=38){if((f|0)!=124){break w}ln(G[G[a+88>>2]+(b<<2)>>2],d,c);if(b){continue}break a}mn(G[G[a+88>>2]+(b<<2)>>2],d,c);if(b){continue}break a}f=b<<2;Za(G[f+G[a+88>>2]>>2],d);Gb(G[f+G[a+88>>2]>>2],c);if(b){continue}break}break a}h=G[g+88>>2];x:{if((b|0)<=0){break x}e=0;y:while(1){f=e<<2;d=G[f+G[i+88>>2]>>2];c=0;while(1){j=H[d|0];z:{if((j|0)!=49){if(j){break z}h=c+h|0;G[f+G[a+88>>2]>>2]=h;E[G[a+84>>2]+e|0]=0;e=e+1|0;if((e|0)!=(b|0)){continue y}break x}c=c+1|0}d=d+1|0;continue}}}G[g+88>>2]=h;break a}ln(a+88|0,d,c)}G[a>>2]=-1e3}if(G[i>>2]>0){Wa(G[G[i+88>>2]>>2]);Wa(G[i+88>>2])}if(G[g>>2]>0){Wa(G[G[g+88>>2]>>2]);Wa(G[g+88>>2])}}function ri(a,b,c,d,e,f,g,h,i,j,k,l){var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;a:{if(H[j|0]!=45){break a}i=i*.01745329252;q=ib(i);r=eb(i);b:{c:{d:{e:{f:{g:{if(!(g!=0&h!=0)){G[k>>2]=0;G[k+4>>2]=0;G[l>>2]=0;G[l+4>>2]=0;break g}o=a+-360;i=a;a=a-c;i=a>180?o:i;i=a<-180?i+360:i;a=i-c;n=b-d;L[k>>3]=(a*r+n*q)/g+e;L[l>>3]=(n*r-q*a)/h+f;x=H[j+1|0];if((x|0)==67){if(H[j+2|0]!=65|H[j+3|0]!=82){break a}break c}p=b*.01745329252;b=eb(p);o=d*.01745329252;a=eb(o);v=i*.01745329252;u=c*.01745329252;t=v-u;c=eb(t);s=ib(p);i=ib(o);w=s*i;y=c*(b*a);m=w+y;n=b*ib(t);h:{switch(x-65|0){case 19:if(H[j+2|0]!=65|H[j+3|0]!=78){break a}if(m<=0){break b}i:{if(a<.001){c=b*c/w;c=(a*(c*c+1)-c)/i;break i}c=(s/m-i)/a}d=ib(u);if(!(O(d)<.3)){break e}n=(d*c*i+(b*ib(v)/m-a*d))/eb(u);break d;case 18:j:{switch(H[j+2|0]-73|0){case 0:if(H[j+3|0]!=78){break a}if(m<0){break b}c=s*a-i*b*c;break d;case 11:break j;default:break a}}if(H[j+3|0]!=71){break a}if(O(p)>1.5707963267948974){break b}d=y+(w+1);if(O(d)<1e-5){break b}d=2/d;c=d*(s*a-i*b*c);n=n*d;break d;case 0:k:{switch(H[j+2|0]-73|0){case 9:if(H[j+3|0]!=67){break a}d=1;m=Sc(Q(R(m,-1),1));if(m!=0){d=m/ib(m)}c=(s*a-i*b*c)*d;n=n*d;break d;case 0:break k;default:break a}}if(H[j+3|0]!=84){break a}d=t*.5;if(O(d)>1.5707963267948974){break b}n=V((b*eb(d)+1)*.5);if(O(n)<1e-5){G[309737]=503;return 503}c=h*r+q*g;c=c==0?.01745329252:c*.01745329252;m=o+c;p=eb(m);o=c;c=V((a+1)*.5);m=ib(m)/V((p+1)*.5)-i/c;m=o/(m==0?1:m);c=s*m/n-i*m/c;i=g*r-q*h;i=i==0?.01745329252:i*.01745329252;m=i*.5;p=ib(m);i=i*V((a*eb(m)+1)*.5);a=p*(a+a);a=i/(a==0?1:a);n=ib(d)*(b*(a+a))/n;break d;case 13:if(H[j+2|0]!=67|H[j+3|0]!=80){break a}if(o==0){break b}c=(a-b*c)/i;break d;case 6:if(H[j+2|0]!=76|H[j+3|0]!=83){break a}if(O(p)>1.5707963267948974|O(o)>1.5707963267948974){break b}n=b*t;c=p-o;break d;case 12:break h;default:break a}}if(H[j+2|0]!=69|H[j+3|0]!=82){break a}b=Mc(p*.5+.7853981633974487);if(!(b<1e-5)){break f}}G[309737]=502;return 502}c=h*r+q*g;c=c==0?1:c;d=(d*.5+45)*.01745329252;i=oc(Mc(c*.5*.01745329252+d));o=c*.01745329252;c=oc(Mc(d));d=o/(i-c);c=d*oc(b)-c*d;n=(a<=0?1:a)*t;break d}n=eb(u);n=(n*c*i+(b*eb(v)/m-a*n))/-d}a=n/.01745329252;b=c/.01745329252;L[k>>3]=(a*r+q*b)/g+e;L[l>>3]=(b*r-q*a)/h+f}return G[309737]}G[309737]=501;return 501}G[309737]=504;return 504}function Od(a,b,c,d,e,f,g){var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;h=Fa-112|0;Fa=h;l=-1;a:{if((a|c|d|e|f|g)<0){break a}i=G[309722];j=i+M(a,344)|0;if(!(G[j>>2]!=-1e3&G[j+56>>2]!=1)){if(!G[309737]){G[309737]=431}a=h+32|0;bb(a,135936,80);E[h+111|0]=0;Ua(a);break a}b:{j=G[309723];if((j|0)==G[309724]){G[309724]=j<<1;i=ub(i,M(j,688));if(!i){break b}G[309722]=i;j=G[309723]}G[309723]=j+1;c:{d:{if((j|0)<0){break d}k=M(j,344)+i|0;G[k+12>>2]=a;G[k+8>>2]=b+1;G[k+16>>2]=c;G[h>>2]=M(c,344)+i;G[k+20>>2]=d;G[h+4>>2]=M(d,344)+i;G[k+24>>2]=e;G[h+8>>2]=M(e,344)+i;G[k+28>>2]=f;G[h+12>>2]=M(f,344)+i;G[k+32>>2]=g;G[h+16>>2]=M(g,344)+i;m=M(a,344)+i|0;c=G[m>>2]==-1e3;e:{if((b|0)<=0){break e}n=b&3;e=0;f:{if(b-1>>>0<3){d=0;break f}p=b&-4;d=0;f=0;while(1){g=0;g:{if(!(c&1)){break g}c=d<<2;g=0;if(G[G[c+h>>2]>>2]!=-1e3){break g}g=0;if(G[G[(c|4)+h>>2]>>2]!=-1e3){break g}g=0;if(G[G[(c|8)+h>>2]>>2]!=-1e3){break g}g=G[G[(c|12)+h>>2]>>2]==-1e3}c=g;d=d+4|0;f=f+4|0;if((p|0)!=(f|0)){continue}break}}if(n){while(1){f=c&1;c=0;c=f?G[G[(d<<2)+h>>2]>>2]==-1e3:c;d=d+1|0;e=e+1|0;if((n|0)!=(e|0)){continue}break}}d=0;while(1){e=G[(d<<2)+h>>2];if(G[e+56>>2]>=2){a=G[309723];if(a){G[309723]=a-1}if(!G[309737]){G[309737]=431}a=h+32|0;bb(a,135855,80);E[h+111|0]=0;Ua(a);break a}if(G[e+52>>2]==259){d=d+1|0;if((d|0)==(b|0)){break e}continue}break}a=G[309723];if(a){G[309723]=a-1}if(!G[309737]){G[309737]=431}a=h+32|0;bb(a,135774,80);E[h+111|0]=0;Ua(a);break a}G[k>>2]=91;G[k+4>>2]=24;G[k+52>>2]=G[m+52>>2];d=G[m+60>>2];h:{if((d|0)==(b|0)){a=M(j,344)+i|0;G[a+56>>2]=1;G[a+60>>2]=1;G[a- -64>>2]=1;break h}f=1;if((b|0)!=1){break c}r=M(j,344)+i|0;e=d-1|0;G[r+60>>2]=e;i:{if((d|0)<2){break i}m=e&3;b=0;j:{if(d-2>>>0<3){d=0;break j}t=e&-4;d=0;n=0;while(1){e=d<<2;g=(M(a,344)+i|0)- -64|0;p=G[e+g>>2];l=(M(j,344)+i|0)- -64|0;G[e+l>>2]=p;o=e|4;s=G[o+g>>2];G[l+o>>2]=s;q=e|8;o=G[q+g>>2];G[l+q>>2]=o;q=g;g=e|12;e=G[q+g>>2];G[g+l>>2]=e;f=M(e,M(o,M(s,M(f,p))));d=d+4|0;n=n+4|0;if((t|0)!=(n|0)){continue}break}}if(!m){break i}while(1){g=d<<2;e=G[(g+(M(a,344)+i|0)|0)- -64>>2];G[(g+(M(j,344)+i|0)|0)- -64>>2]=e;f=M(e,f);d=d+1|0;b=b+1|0;if((m|0)!=(b|0)){continue}break}}G[r+56>>2]=f}if(!(c&1)){break d}sn(k)}l=j;break a}a=G[309723];if(a){G[309723]=a-1}wc(10454);break a}G[309737]=113}Fa=h+112|0;return l}function Ye(a,b){var c=0,d=0,e=0,f=0,g=0,h=0;d=Fa-208|0;Fa=d;E[d+204|0]=39;E[d+205|0]=0;E[d+202|0]=34;E[d+203|0]=0;E[d+200|0]=91;E[d+201|0]=0;E[d+198|0]=93;E[d+199|0]=0;E[d+196|0]=47;E[d+197|0]=0;E[d+194|0]=44;E[d+195|0]=0;b=rb(d+112|0,b,80);e=Va(b);a:{b:{c=ec(b,d+200|0,e);if(c){break b}c=ec(b,d+194|0,e);if(c){break b}e=0;break a}E[c|0]=0;e=c+1|0}c:{d:{a=Pc(a,b);e:{if(!a){break e}f=cb(d,0,100);g=rb(f,a,80);b=Va(g);a=ec(g,f+204|0,b);c=ec(g,f+196|0,b);f:{g:{h:{if(a){if(!(!c|a>>>0>=c>>>0)){b=a+1|0;b=ec(b,f+204|0,Va(b));if(!b){while(1){b=c;c=b-1|0;if(H[c|0]==32){continue}break h}}if(b>>>0<=c>>>0){break h}ec(b,f+196|0,Va(b));break h}if(c){break g}b=a+1|0;b=ec(b,f+204|0,Va(b));if(b){break h}b=g+79|0;while(1){c=b;b=b-1|0;if(H[c|0]==32){continue}break}b=c+1|0;break h}a=ec(g,f+202|0,b);if(!a){break g}if(!(!c|a>>>0>=c>>>0)){b=a+1|0;b=ec(b,f+202|0,Va(b));if(!b){while(1){b=c;c=b-1|0;if(H[c|0]==32){continue}break h}}if(b>>>0<=c>>>0){break h}ec(b,f+196|0,Va(b));break h}if(c){break g}b=a+1|0;b=ec(b,f+202|0,Va(b));if(b){break h}b=g+79|0;while(1){c=b;b=b-1|0;if(H[c|0]==32){continue}break}b=c+1|0}a=a+1|0;break f}a=ec(g,36178,b);a=a?a+1|0:g+9|0;b=ec(g,42205,b);b=b?b:g+79|0}i:{if(H[1285300]){c=a;break i}while(1){c=a;if(H[c|0]!=32){break i}a=c+1|0;if(b>>>0>c>>>0){continue}break}}E[b|0]=0;j:{if(H[1285300]){break j}while(1){b=b-1|0;a=H[b|0]-13|0;if(((a|0)!=19?a:0)|b>>>0<=c>>>0){break j}E[b|0]=0;continue}}b=1285312;a=!Xa(c,41689)+c|0;Za(1285312,a);if(!e){break c}c=ec(e,f+198|0,Va(e));if(c){E[c|0]=0}if(ah(e)){c=_b(e);E[f+206|0]=32;E[f+207|0]=0;if((c|0)>0){a=pc(a,f+206|0);if((c|0)!=1){b=2;while(1){e=(b|0)!=(c|0);a=pc(0,f+206|0);b=b+1|0;if(e){continue}break}}if(a){break d}break e}if((c|0)>=0){break c}if((c|0)!=-1){b=0;c=0-c|0;e=(c|0)>2?c:2;c=1;while(1){a=jb(a,32);if(!a){break c}a=a+1|0;c=c+1|0;if((e|0)!=(c|0)){continue}break}break d}if(a){break d}break e}a=Va(e);k:{if((a|0)<=0){break k}b=0;if((a|0)!=1){f=a&-2;c=0;while(1){g=b+e|0;h=H[g|0];if((h-65&255)>>>0<=25){E[g|0]=h+32}g=e+(b|1)|0;h=H[g|0];if((h-65&255)>>>0<=25){E[g|0]=h+32}b=b+2|0;c=c+2|0;if((f|0)!=(c|0)){continue}break}}if(!(a&1)){break k}a=b+e|0;b=H[a|0];if((b-65&255)>>>0>25){break k}E[a|0]=b+32}a=ci(1285312,e);if(a){break d}}b=0;break c}b=1285312;Za(1285312,a)}Fa=d+208|0;return b}function rj(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;L[a+760>>3]=b;L[a+32>>3]=b;f=c!=0?c:b;L[a+768>>3]=f;L[a+40>>3]=f;g=G[a+3316>>2];if((g|0)>0){e=a+832|0;k=(g|0)==1?1:2;l=k-1>>>0<3;while(1){g=0;h=0;if(!l){while(1){L[e>>3]=(g|0)==(i|0)?1:0;L[e+24>>3]=(g|3)==(i|0)?1:0;L[e+16>>3]=(g|2)==(i|0)?1:0;L[e+8>>3]=(g|1)==(i|0)?1:0;g=g+4|0;e=e+32|0;h=h+4|0;if(h){continue}break}}h=0;while(1){L[e>>3]=(g|0)==(i|0)?1:0;g=g+1|0;e=e+8|0;h=h+1|0;if((k|0)!=(h|0)){continue}break}i=i+1|0;if((k|0)!=(i|0)){continue}break}}G[a+3300>>2]=0;d=d<0?d+360:d;f=d>=360?d+-360:d;L[a+48>>3]=f;d=L[a+760>>3];j=f*3.141592653589793/180;f=eb(j);L[a+56>>3]=d*f;m=f;f=L[a+768>>3];L[a+80>>3]=m*f;j=ib(j);b=b*c>0?-j:j;c=O(d);L[a+72>>3]=b*(f<0?c:-c);c=b;b=O(f);L[a- -64>>3]=c*(d<0?-b:b);sg(2,a+56|0,a+88|0);rm(a);b=L[a+760>>3];a:{b:{if(G[a+3304>>2]){if(!(!(b<0)|!(L[a+768>>3]>0))){G[a+3256>>2]=1;b=L[a+48>>3];L[a+3208>>3]=b;b=b+-90;L[a+3216>>3]=b;c=b+360;e=b<-180;L[a+3200>>3]=e?c:b;if(!e){break b}L[a+3216>>3]=c;return}c:{if(!(b>0)){break c}c=L[a+768>>3];if(c<0){G[a+3256>>2]=1;b=L[a+48>>3];L[a+3208>>3]=b;c=b+-90;L[a+3216>>3]=c;b=b+90;L[a+3200>>3]=b>180?b+-360:b;if(!(c<-180)){break b}L[a+3216>>3]=c+360;return}if(!(c>0)){break c}G[a+3256>>2]=0;b=L[a+48>>3]+90;L[a+3216>>3]=b;c=b+-360;e=b>180;b=e?c:b;L[a+3208>>3]=b;L[a+3200>>3]=b;if(!e){break b}L[a+3216>>3]=c;return}if(!(b<0)|!(L[a+768>>3]<0)){break b}G[a+3256>>2]=0;c=L[a+48>>3];b=c+90;L[a+3216>>3]=b;c=c+-90;c=c<-180?c+360:c;L[a+3208>>3]=c;L[a+3200>>3]=c;if(!(b>180)){break b}L[a+3216>>3]=b+-360;return}if(!(!(b<0)|!(L[a+768>>3]>0))){G[a+3256>>2]=0;b=L[a+48>>3];L[a+3200>>3]=b;c=b+180;L[a+3216>>3]=c;b=b+90;L[a+3208>>3]=b>180?b+-360:b;if(!(c>180)){break b}break a}d:{if(!(b>0)){break d}c=L[a+768>>3];if(c<0){G[a+3256>>2]=0;b=L[a+48>>3]+180;b=b>180?b+-360:b;L[a+3200>>3]=b;c=b+180;L[a+3216>>3]=c;b=b+90;L[a+3208>>3]=b>180?b+-360:b;if(!(c>180)){break b}break a}if(!(c>0)){break d}G[a+3256>>2]=1;b=L[a+48>>3];L[a+3216>>3]=b;L[a+3200>>3]=-b;b=90-b;L[a+3208>>3]=b>180?b+-360:b;return}if(!(b<0)|!(L[a+768>>3]<0)){break b}G[a+3256>>2]=1;c=L[a+48>>3];b=c+90;L[a+3216>>3]=b;c=c+180;c=c>180?c+-360:c;L[a+3200>>3]=c;c=c+90;L[a+3208>>3]=c>180?c+-360:c;if(!(b>180)){break b}L[a+3216>>3]=b+-360}return}L[a+3216>>3]=c+-360}function Ri(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;j=G[a+44>>2];m=j-262|0;e=G[a+116>>2];while(1){h=G[a+108>>2];i=G[a+60>>2]-(h+e|0)|0;if(G[a+44>>2]+m>>>0<=h>>>0){b=G[a+56>>2];bb(b,b+j|0,j-i|0);G[a+112>>2]=G[a+112>>2]-j;h=G[a+108>>2]-j|0;G[a+108>>2]=h;G[a+92>>2]=G[a+92>>2]-j;b=G[a+76>>2];g=b-1|0;d=G[a+68>>2]+(b<<1)|0;c=G[a+44>>2];e=0;k=b&3;if(k){while(1){d=d-2|0;l=I[d>>1];f=l-c|0;F[d>>1]=f>>>0>l>>>0?0:f;b=b-1|0;e=e+1|0;if((k|0)!=(e|0)){continue}break}}if(g>>>0>=3){while(1){f=d-2|0;g=I[f>>1];e=g-c|0;F[f>>1]=e>>>0>g>>>0?0:e;f=d-4|0;g=I[f>>1];e=g-c|0;F[f>>1]=e>>>0>g>>>0?0:e;f=d-6|0;g=I[f>>1];e=g-c|0;F[f>>1]=e>>>0>g>>>0?0:e;d=d-8|0;f=I[d>>1];e=f-c|0;F[d>>1]=e>>>0>f>>>0?0:e;b=b-4|0;if(b){continue}break}}d=G[a+64>>2]+(c<<1)|0;e=0;b=c;g=c&3;if(g){while(1){d=d-2|0;k=I[d>>1];f=k-c|0;F[d>>1]=f>>>0>k>>>0?0:f;b=b-1|0;e=e+1|0;if((g|0)!=(e|0)){continue}break}}if(c-1>>>0>=3){while(1){f=d-2|0;g=I[f>>1];e=g-c|0;F[f>>1]=e>>>0>g>>>0?0:e;f=d-4|0;g=I[f>>1];e=g-c|0;F[f>>1]=e>>>0>g>>>0?0:e;f=d-6|0;g=I[f>>1];e=g-c|0;F[f>>1]=e>>>0>g>>>0?0:e;d=d-8|0;f=I[d>>1];e=f-c|0;F[d>>1]=e>>>0>f>>>0?0:e;b=b-4|0;if(b){continue}break}}i=i+j|0}c=G[a>>2];e=G[c+4>>2];a:{if(!e){break a}b=G[a+116>>2];d=e>>>0>>0?e:i;if(d){i=G[a+56>>2];G[c+4>>2]=e-d;b=bb(b+(i+h|0)|0,G[c>>2],d);b:{c:{switch(G[G[c+28>>2]+24>>2]-1|0){case 0:n=c,o=gf(G[c+48>>2],b,d),G[n+48>>2]=o;break b;case 1:break c;default:break b}}n=c,o=Oc(G[c+48>>2],b,d),G[n+48>>2]=o}G[c>>2]=d+G[c>>2];G[c+8>>2]=d+G[c+8>>2];b=G[a+116>>2]}e=b+d|0;G[a+116>>2]=e;d=G[a+5812>>2];d:{if(d+e>>>0<3){break d}c=G[a+108>>2]-d|0;i=G[a+56>>2];b=c+i|0;h=H[b|0];G[a+72>>2]=h;f=G[a+84>>2];g=h;h=G[a+88>>2];b=f&(H[b+1|0]^g<>2]=b;while(1){if(!d){break d}b=f&(H[(c+i|0)+2|0]^b<>2]=b;g=G[a+68>>2]+(b<<1)|0;F[G[a+64>>2]+((G[a+52>>2]&c)<<1)>>1]=I[g>>1];F[g>>1]=c;d=d-1|0;G[a+5812>>2]=d;c=c+1|0;if(e+d>>>0>2){continue}break}}if(e>>>0>261){break a}if(G[G[a>>2]+4>>2]){continue}}break}d=G[a+60>>2];b=G[a+5824>>2];e:{if(d>>>0<=b>>>0){break e}c=G[a+116>>2]+G[a+108>>2]|0;f:{if(c>>>0>b>>>0){b=d-c|0;b=b>>>0<258?b:258;cb(c+G[a+56>>2]|0,0,b);b=b+c|0;break f}c=c+258|0;if(c>>>0<=b>>>0){break e}h=b+G[a+56>>2]|0;c=c-b|0;b=d-b|0;b=b>>>0>c>>>0?c:b;cb(h,0,b);b=b+G[a+5824>>2]|0}G[a+5824>>2]=b}}function fo(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;g=Fa-112|0;Fa=g;k=G[f>>2];a:{b:{if((k|0)<=0){h=G[a+4>>2]+940|0;break b}n=237;h=f;if((k|0)!=237){break a}}G[h>>2]=0;E[d|0]=0;G[e>>2]=0;i=G[a>>2];h=G[a+4>>2];c:{d:{if((i|0)!=G[h+76>>2]){mb(a,i+1|0,0,f);break d}if((G[h+128>>2]&G[h+132>>2])!=-1){break d}if((Rb(a,f)|0)>0){break c}}e:{f:{h=G[a+4>>2];j=G[h+940>>2];if((j|0)>=G[h+936>>2]){break f}h=G[h+968>>2]+M(j,160)|0;i=0;while(1){Fg(c,h,b,g+12|0,g+8|0);g:{if(!G[g+12>>2]){break g}l=G[g+8>>2];if(!(!i|!l)){G[G[a+4>>2]+940>>2]=G[e>>2];G[f>>2]=237;break a}if(i){i=1;break g}if(l){Za(d,h);i=1;G[e>>2]=j+1;break g}i=0;if(m){m=1;o=0;break g}Za(d,h);m=1;l=j+1|0;G[e>>2]=l;G[G[a+4>>2]+940>>2]=l;o=1}h=h+160|0;j=j+1|0;if((j|0)>2]+936>>2]){continue}break}if(i){if((k|0)<=0){break e}G[f>>2]=237;break e}if(!m){break f}if(!(!o|(k|0)>0)){break e}G[f>>2]=237;break e}h:{i:{if((k|0)<=0){G[48624]=0;b=nc(c,g+108|0,10);j:{if((H[G[g+108>>2]]|32)==32){if(G[48624]==68){break j}if((b|0)<=0){break i}h=G[a+4>>2];if((b|0)>G[h+936>>2]){break i}G[e>>2]=b;Za(d,(G[h+968>>2]+M(b,160)|0)-160|0);break e}if(G[48624]!=68){break i}}b=H[67017]|H[67018]<<8|(H[67019]<<16|H[67020]<<24);d=H[67013]|H[67014]<<8|(H[67015]<<16|H[67016]<<24);F[g+62>>1]=d;F[g+64>>1]=d>>>16;F[g+66>>1]=b;F[g+68>>1]=b>>>16;b=H[67011]|H[67012]<<8|(H[67013]<<16|H[67014]<<24);G[g+56>>2]=H[67007]|H[67008]<<8|(H[67009]<<16|H[67010]<<24);G[g+60>>2]=b;b=H[67003]|H[67004]<<8|(H[67005]<<16|H[67006]<<24);G[g+48>>2]=H[66999]|H[67e3]<<8|(H[67001]<<16|H[67002]<<24);G[g+52>>2]=b;b=H[66995]|H[66996]<<8|(H[66997]<<16|H[66998]<<24);G[g+40>>2]=H[66991]|H[66992]<<8|(H[66993]<<16|H[66994]<<24);G[g+44>>2]=b;b=H[66987]|H[66988]<<8|(H[66989]<<16|H[66990]<<24);G[g+32>>2]=H[66983]|H[66984]<<8|(H[66985]<<16|H[66986]<<24);G[g+36>>2]=b;b=H[66979]|H[66980]<<8|(H[66981]<<16|H[66982]<<24);G[g+24>>2]=H[66975]|H[66976]<<8|(H[66977]<<16|H[66978]<<24);G[g+28>>2]=b;b=H[66971]|H[66972]<<8|(H[66973]<<16|H[66974]<<24);G[g+16>>2]=H[66967]|H[66968]<<8|(H[66969]<<16|H[66970]<<24);G[g+20>>2]=b;tb(5,qb(g+16|0,c,25));G[48624]=0;n=412}G[f>>2]=219;if((n|0)!=237){break h}break e}G[f>>2]=219}G[g>>2]=c;b=g+16|0;Ya(b,81,8656,g);tb(5,b)}G[G[a+4>>2]+940>>2]=G[e>>2]}}Fa=g+112|0}function bg(a,b,c,d,e,f,g,h,i,j,k,l,m){var n=0,o=0;n=Fa-16|0;Fa=n;o=G[m>>2];if((o|0)<=0){a:{b:{switch(b-1|0){case 0:xp(a,c,d,e,f,g,h,i,k,m);break a;case 10:if(!j){Re(a,c,d,e,f,g,h,i,1,1,0,k,n+14|0,l,m);break a}Re(a,c,d,e,f,g,h,i,1,1,H[j|0],k,n+14|0,l,m);break a;case 11:if(!j){Ef(a,c,d,e,f,g,h,i,1,1,0,k,n+14|0,l,m);break a}Ef(a,c,d,e,f,g,h,i,1,1,E[j|0],k,n+14|0,l,m);break a;case 19:if(!j){Gf(a,c,d,e,f,g,h,i,1,1,0,k,n+14|0,l,m);break a}Gf(a,c,d,e,f,g,h,i,1,1,I[j>>1],k,n+14|0,l,m);break a;case 20:if(!j){jf(a,c,d,e,f,g,h,i,1,1,0,k,n+14|0,l,m);break a}jf(a,c,d,e,f,g,h,i,1,1,F[j>>1],k,n+14|0,l,m);break a;case 29:if(!j){Dh(a,c,d,e,f,g,h,i,1,0,k,n+14|0,l,m);break a}Dh(a,c,d,e,f,g,h,i,1,G[j>>2],k,n+14|0,l,m);break a;case 30:if(!j){Eh(a,c,d,e,f,g,h,i,1,0,k,n+14|0,l,m);break a}Eh(a,c,d,e,f,g,h,i,1,G[j>>2],k,n+14|0,l,m);break a;case 39:if(!j){qe(a,c,d,e,f,g,h,i,1,1,0,k,n+14|0,l,m);break a}qe(a,c,d,e,f,g,h,i,1,1,G[j>>2],k,n+14|0,l,m);break a;case 40:if(!j){Ud(a,c,d,e,f,g,h,i,1,1,0,k,n+14|0,l,m);break a}Ud(a,c,d,e,f,g,h,i,1,1,G[j>>2],k,n+14|0,l,m);break a;case 79:if(!j){hf(a,c,d,e,f,g,h,i,1,1,0,0,k,n+14|0,l,m);break a}hf(a,c,d,e,f,g,h,i,1,1,G[j>>2],G[j+4>>2],k,n+14|0,l,m);break a;case 80:if(!j){Se(a,c,d,e,f,g,h,i,1,1,0,0,k,n+14|0,l,m);break a}Se(a,c,d,e,f,g,h,i,1,1,G[j>>2],G[j+4>>2],k,n+14|0,l,m);break a;case 41:if(!j){ae(a,c,d,e,f,g,h,i,1,1,N(0),k,n+14|0,l,m);break a}ae(a,c,d,e,f,g,h,i,1,1,K[j>>2],k,n+14|0,l,m);break a;case 81:if(!j){Id(a,c,d,e,f,g,h,i,1,1,0,k,n+14|0,l,m);break a}Id(a,c,d,e,f,g,h,i,1,1,L[j>>3],k,n+14|0,l,m);break a;case 82:b=i<<1|h>>>31;h=h<<1;i=f;f=g<<1|i>>>31;i=i<<1;g=i-1|0;f=f-!i|0;if(!j){ae(a,c,d,e,g,f,h,b,1,1,N(0),k,n+14|0,l,m);break a}ae(a,c,d,e,g,f,h,b,1,1,K[j>>2],k,n+14|0,l,m);break a;case 162:b=i<<1|h>>>31;h=h<<1;i=f;f=g<<1|i>>>31;i=i<<1;g=i-1|0;f=f-!i|0;if(!j){Id(a,c,d,e,g,f,h,b,1,1,0,k,n+14|0,l,m);break a}Id(a,c,d,e,g,f,h,b,1,1,L[j>>3],k,n+14|0,l,m);break a;case 13:if(!j){fg(a,c,d,e,f,g,h,i,1,0,k,n+14|0,l,m);break a}fg(a,c,d,e,f,g,h,i,1,E[j|0],k,n+14|0,l,m);break a;case 15:if(!j){E[n+14|0]=0;b=a;a=n+14|0;xh(b,c,d,e,f,g,h,i,1,a,k,a,l,m);break a}xh(a,c,d,e,f,g,h,i,1,j,k,n+14|0,l,m);break a;default:break b}}G[m>>2]=410}o=G[m>>2]}Fa=n+16|0;return o}function Dn(a,b,c,d,e,f,g,h,i,j,k,l,m,n){var o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;o=Fa-560|0;Fa=o;p=G[n>>2];a:{if((p|0)>0){break a}if((d|0)>=5){Ua(6766);p=320;G[n>>2]=320;break a}p=11;b:{c:{d:{e:{f:{switch(c-8|0){case 0:break b;case 24:break c;case 8:break d;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:break e;default:break f}}if((c|0)!=-64){if((c|0)!=-32){break e}p=42;break b}p=82;break b}p=410;G[n>>2]=410;break a}p=21;break b}p=31}s=G[a>>2];if((s|0)!=G[G[a+4>>2]+76>>2]){mb(a,s+1|0,0,n)}G[o+396>>2]=k;L[o+400>>3]=j;G[o+392>>2]=l;G[o+276>>2]=p;G[o+252>>2]=a;G[o+408>>2]=m;G[o+256>>2]=d;if((d|0)>0){c=0;while(1){k=c<<3;m=c<<2;t=+G[m+e>>2];L[k+(o+512|0)>>3]=t;l=k+(o+480|0)|0;q=L[g+k>>3];L[l>>3]=q;r=L[h+k>>3];g:{h:{if(r>3];if(j>0){break h}}j=L[i+k>>3];if(!(q>3]=j;eo(a,G[f+m>>2],o+556|0,n);i:{j:{if(G[o+556>>2]>41){break j}if(O(q)<2147483648){m=~~q}else{m=-2147483648}u=+(m|0);if(O(j)<2147483648){m=~~j}else{m=-2147483648}v=q!=u;if(O(r)<2147483648){s=~~r}else{s=-2147483648}if(v|r!=+(s|0)|+(m|0)!=j){break j}L[k+(o+416|0)>>3]=t+1;if(q>3]=q+-.5;break i}L[l>>3]=q+.5;break i}L[k+(o+416|0)>>3]=(r-q)/j}c=c+1|0;if((d|0)!=(c|0)){continue}break}j=L[o+512>>3];k:{if(O(j)<2147483648){c=~~j;break k}c=-2147483648}j=L[o+448>>3];q=L[o+416>>3];r=L[o+480>>3];d=G[o+256>>2]}a=G[f>>2];L[o+360>>3]=j;L[o+328>>3]=q;L[o+296>>3]=r;G[o+260>>2]=a;G[o+280>>2]=c;l:{if((d|0)<2){break l}G[o+264>>2]=G[f+4>>2];L[o+304>>3]=L[o+488>>3];L[o+336>>3]=L[o+424>>3];L[o+368>>3]=L[o+456>>3];j=L[o+520>>3];m:{if(O(j)<2147483648){a=~~j;break m}a=-2147483648}G[o+284>>2]=a;if((d|0)==2){break l}G[o+268>>2]=G[f+8>>2];L[o+312>>3]=L[o+496>>3];L[o+344>>3]=L[o+432>>3];L[o+376>>3]=L[o+464>>3];j=L[o+528>>3];n:{if(O(j)<2147483648){a=~~j;break n}a=-2147483648}G[o+288>>2]=a;if(d>>>0<4){break l}G[o+272>>2]=G[f+12>>2];L[o+320>>3]=L[o+504>>3];L[o+352>>3]=L[o+440>>3];L[o+384>>3]=L[o+472>>3];j=L[o+536>>3];o:{if(O(j)<2147483648){a=~~j;break o}a=-2147483648}G[o+292>>2]=a}G[o>>2]=b;G[o+80>>2]=p;G[o+84>>2]=2;$f(1,o,0,-1,19,o+248|0,n);p=G[n>>2]}Fa=o+560|0;return p}function jq(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=N(0),o=0,p=0;k=c==1&d==0;a:{if(!e){if(!k){if((b|0)<=0){break a}e=0;if((b|0)!=1){f=b&-2;i=0;while(1){K[(e<<2)+j>>2]=+F[(e<<1)+a>>1]*c+d;h=e|1;K[(h<<2)+j>>2]=+F[(h<<1)+a>>1]*c+d;e=e+2|0;i=i+2|0;if((f|0)!=(i|0)){continue}break}}if(!(b&1)){break a}K[(e<<2)+j>>2]=+F[(e<<1)+a>>1]*c+d;break a}if((b|0)<=0){break a}f=b&3;i=0;e=0;if(b-1>>>0>=3){h=b&-4;b=0;while(1){K[(e<<2)+j>>2]=F[(e<<1)+a>>1];k=e|1;K[(k<<2)+j>>2]=F[(k<<1)+a>>1];k=e|2;K[(k<<2)+j>>2]=F[(k<<1)+a>>1];k=e|3;K[(k<<2)+j>>2]=F[(k<<1)+a>>1];e=e+4|0;b=b+4|0;if((h|0)!=(b|0)){continue}break}}if(!f){break a}while(1){K[(e<<2)+j>>2]=F[(e<<1)+a>>1];e=e+1|0;i=i+1|0;if((f|0)!=(i|0)){continue}break}break a}b:{if(!k){if((b|0)<=0){break a}if((e|0)==1){break b}e=0;f=f&65535;while(1){k=I[(e<<1)+a>>1];c:{if((k|0)==(f|0)){G[i>>2]=1;E[e+h|0]=1;break c}K[(e<<2)+j>>2]=+(k<<16>>16)*c+d}e=e+1|0;if((e|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)!=1){e=0;if((b|0)!=1){m=b&-2;o=f&65535;k=0;while(1){l=I[(e<<1)+a>>1];d:{if((l|0)==(o|0)){G[i>>2]=1;E[e+h|0]=1;break d}K[(e<<2)+j>>2]=l<<16>>16}l=e|1;p=I[(l<<1)+a>>1];e:{if((o|0)!=(p|0)){K[(l<<2)+j>>2]=p<<16>>16;break e}G[i>>2]=1;E[h+l|0]=1}e=e+2|0;k=k+2|0;if((m|0)!=(k|0)){continue}break}}if(!(b&1)){break a}a=I[(e<<1)+a>>1];if((a|0)!=(f&65535)){K[(e<<2)+j>>2]=a<<16>>16;break a}G[i>>2]=1;E[e+h|0]=1;break a}e=0;if((b|0)!=1){o=b&-2;h=f&65535;k=0;while(1){m=(e<<2)+j|0;l=I[(e<<1)+a>>1];f:{if((l|0)!=(h|0)){n=N(l<<16>>16);break f}G[i>>2]=1;n=g}K[m>>2]=n;l=e|1;m=I[(l<<1)+a>>1];g:{if((m|0)!=(h|0)){n=N(m<<16>>16);break g}G[i>>2]=1;n=g}K[(l<<2)+j>>2]=n;e=e+2|0;k=k+2|0;if((o|0)!=(k|0)){continue}break}}if(!(b&1)){break a}a=I[(e<<1)+a>>1];h:{if((a|0)!=(f&65535)){g=N(a<<16>>16);break h}G[i>>2]=1}K[(e<<2)+j>>2]=g;break a}e=0;if((b|0)!=1){o=b&-2;h=f&65535;k=0;while(1){m=(e<<2)+j|0;l=I[(e<<1)+a>>1];i:{if((l|0)!=(h|0)){n=N(+(l<<16>>16)*c+d);break i}G[i>>2]=1;n=g}K[m>>2]=n;l=e|1;m=I[(l<<1)+a>>1];j:{if((m|0)!=(h|0)){n=N(+(m<<16>>16)*c+d);break j}G[i>>2]=1;n=g}K[(l<<2)+j>>2]=n;e=e+2|0;k=k+2|0;if((o|0)!=(k|0)){continue}break}}if(!(b&1)){break a}a=I[(e<<1)+a>>1];k:{if((a|0)!=(f&65535)){g=N(+(a<<16>>16)*c+d);break k}G[i>>2]=1}K[(e<<2)+j>>2]=g}}function fq(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0;k=c==1&d==0;a:{if(!e){if(!k){if((b|0)<=0){break a}e=0;if((b|0)!=1){f=b&-2;i=0;while(1){L[(e<<3)+j>>3]=+F[(e<<1)+a>>1]*c+d;h=e|1;L[(h<<3)+j>>3]=+F[(h<<1)+a>>1]*c+d;e=e+2|0;i=i+2|0;if((f|0)!=(i|0)){continue}break}}if(!(b&1)){break a}L[(e<<3)+j>>3]=+F[(e<<1)+a>>1]*c+d;break a}if((b|0)<=0){break a}f=b&3;i=0;e=0;if(b-1>>>0>=3){h=b&-4;b=0;while(1){L[(e<<3)+j>>3]=F[(e<<1)+a>>1];k=e|1;L[(k<<3)+j>>3]=F[(k<<1)+a>>1];k=e|2;L[(k<<3)+j>>3]=F[(k<<1)+a>>1];k=e|3;L[(k<<3)+j>>3]=F[(k<<1)+a>>1];e=e+4|0;b=b+4|0;if((h|0)!=(b|0)){continue}break}}if(!f){break a}while(1){L[(e<<3)+j>>3]=F[(e<<1)+a>>1];e=e+1|0;i=i+1|0;if((f|0)!=(i|0)){continue}break}break a}b:{if(!k){if((b|0)<=0){break a}if((e|0)==1){break b}e=0;f=f&65535;while(1){k=I[(e<<1)+a>>1];c:{if((k|0)==(f|0)){G[i>>2]=1;E[e+h|0]=1;break c}L[(e<<3)+j>>3]=+(k<<16>>16)*c+d}e=e+1|0;if((e|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)!=1){e=0;if((b|0)!=1){m=b&-2;n=f&65535;k=0;while(1){l=I[(e<<1)+a>>1];d:{if((l|0)==(n|0)){G[i>>2]=1;E[e+h|0]=1;break d}L[(e<<3)+j>>3]=l<<16>>16}l=e|1;p=I[(l<<1)+a>>1];e:{if((n|0)!=(p|0)){L[(l<<3)+j>>3]=p<<16>>16;break e}G[i>>2]=1;E[h+l|0]=1}e=e+2|0;k=k+2|0;if((m|0)!=(k|0)){continue}break}}if(!(b&1)){break a}a=I[(e<<1)+a>>1];if((a|0)!=(f&65535)){L[(e<<3)+j>>3]=a<<16>>16;break a}G[i>>2]=1;E[e+h|0]=1;break a}e=0;if((b|0)!=1){n=b&-2;h=f&65535;k=0;while(1){m=(e<<3)+j|0;l=I[(e<<1)+a>>1];f:{if((l|0)!=(h|0)){c=+(l<<16>>16);break f}G[i>>2]=1;c=g}L[m>>3]=c;l=e|1;m=I[(l<<1)+a>>1];g:{if((m|0)!=(h|0)){c=+(m<<16>>16);break g}G[i>>2]=1;c=g}L[(l<<3)+j>>3]=c;e=e+2|0;k=k+2|0;if((n|0)!=(k|0)){continue}break}}if(!(b&1)){break a}a=I[(e<<1)+a>>1];h:{if((a|0)!=(f&65535)){g=+(a<<16>>16);break h}G[i>>2]=1}L[(e<<3)+j>>3]=g;break a}e=0;if((b|0)!=1){n=b&-2;h=f&65535;k=0;while(1){m=(e<<3)+j|0;l=I[(e<<1)+a>>1];i:{if((l|0)!=(h|0)){o=+(l<<16>>16)*c+d;break i}G[i>>2]=1;o=g}L[m>>3]=o;l=e|1;m=I[(l<<1)+a>>1];j:{if((m|0)!=(h|0)){o=+(m<<16>>16)*c+d;break j}G[i>>2]=1;o=g}L[(l<<3)+j>>3]=o;e=e+2|0;k=k+2|0;if((n|0)!=(k|0)){continue}break}}if(!(b&1)){break a}a=I[(e<<1)+a>>1];k:{if((a|0)!=(f&65535)){g=+(a<<16>>16)*c+d;break k}G[i>>2]=1}L[(e<<3)+j>>3]=g}}function ig(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;f=Fa-208|0;Fa=f;a:{if(G[c>>2]>0){break a}e=G[a>>2];if((e|0)!=G[G[a+4>>2]+76>>2]){mb(a,e+1|0,0,c)}b:{if((b|0)<=0){break b}h=G[a+4>>2];i=G[h+96>>2]+(G[h+76>>2]<<3)|0;e=G[i+4>>2];k=G[i>>2];l=Bu(k,e,-80,-1);i=G[h+104>>2];j=l+i|0;l=G[h+108>>2];g=l+Ia|0;g=j>>>0>>0?g+1|0:g;if((g|0)<=0&b>>>0>j>>>0|(g|0)<0){break b}j=M(b,80)-80|0;k=j+k|0;g=(j>>31)+e|0;e=k;G[h+120>>2]=e;g=j>>>0>e>>>0?g+1|0:g;G[h+124>>2]=g;r=Bu(i-e|0,l-((e>>>0>i>>>0)+g|0)|0,80,0);if((r|0)<=0){G[f>>2]=b;a=f+112|0;Ya(a,81,42454,f);Ua(a);break b}s=H[68297];E[f+56|0]=s;m=H[68293]|H[68294]<<8|(H[68295]<<16|H[68296]<<24);g=H[68289]|H[68290]<<8|(H[68291]<<16|H[68292]<<24);G[f+48>>2]=g;G[f+52>>2]=m;n=H[68285]|H[68286]<<8|(H[68287]<<16|H[68288]<<24);k=H[68281]|H[68282]<<8|(H[68283]<<16|H[68284]<<24);G[f+40>>2]=k;G[f+44>>2]=n;o=H[68277]|H[68278]<<8|(H[68279]<<16|H[68280]<<24);j=H[68273]|H[68274]<<8|(H[68275]<<16|H[68276]<<24);G[f+32>>2]=j;G[f+36>>2]=o;p=H[68269]|H[68270]<<8|(H[68271]<<16|H[68272]<<24);h=H[68265]|H[68266]<<8|(H[68267]<<16|H[68268]<<24);G[f+24>>2]=h;G[f+28>>2]=p;q=H[68261]|H[68262]<<8|(H[68263]<<16|H[68264]<<24);e=H[68257]|H[68258]<<8|(H[68259]<<16|H[68260]<<24);G[f+16>>2]=e;G[f+20>>2]=q;b=f+16|0;d=b+Va(b)|0;E[d|0]=e;E[d+1|0]=e>>>8;E[d+2|0]=e>>>16;E[d+3|0]=e>>>24;E[d+4|0]=q;E[d+5|0]=q>>>8;E[d+6|0]=q>>>16;E[d+7|0]=q>>>24;E[d+40|0]=s;E[d+32|0]=g;E[d+33|0]=g>>>8;E[d+34|0]=g>>>16;E[d+35|0]=g>>>24;E[d+36|0]=m;E[d+37|0]=m>>>8;E[d+38|0]=m>>>16;E[d+39|0]=m>>>24;E[d+24|0]=k;E[d+25|0]=k>>>8;E[d+26|0]=k>>>16;E[d+27|0]=k>>>24;E[d+28|0]=n;E[d+29|0]=n>>>8;E[d+30|0]=n>>>16;E[d+31|0]=n>>>24;E[d+16|0]=j;E[d+17|0]=j>>>8;E[d+18|0]=j>>>16;E[d+19|0]=j>>>24;E[d+20|0]=o;E[d+21|0]=o>>>8;E[d+22|0]=o>>>16;E[d+23|0]=o>>>24;E[d+8|0]=h;E[d+9|0]=h>>>8;E[d+10|0]=h>>>16;E[d+11|0]=h>>>24;E[d+12|0]=p;E[d+13|0]=p>>>8;E[d+14|0]=p>>>16;E[d+15|0]=p>>>24;h=f+112|0;while(1){e=l-(i>>>0<80)|0;i=i-80|0;Jb(a,i,e,0,c);ic(a,80,0,h,c);l=e;Jb(a,i,e,0,c);e=b;Wb(a,80,0,e,c);b=h;h=e;t=t+1|0;if((t|0)!=(r|0)){continue}break}a=G[a+4>>2];c=a;b=G[a+104>>2];a=G[a+108>>2]-(b>>>0<80)|0;G[c+104>>2]=b-80;G[c+108>>2]=a;break a}G[c>>2]=203}Fa=f+208|0}function Gj(a,b,c,d,e,f,g,h,i,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;a:{if(j==0){break a}q=G[a+16>>2];g=+G[a+32>>2];f=j/g;j=(i-+G[a+24>>2])/g+1;i=f+j;b:{if(O(i)<2147483648){k=~~i;break b}k=-2147483648}m=k-1|0;n=i==+(k|0);o=n?m:k;i=j-f;c:{if(O(i)<2147483648){b=~~i;break c}b=-2147483648}l=b+1|0;d:{if((o|0)>(l|0)){p=G[a+8>>2];b=G[a+44>>2];L[(p+M(c,168)|0)+8>>3]=((b|0)>(l|0)?b:l)|0;b=G[a+48>>2];l=(o|0)>(b|0);k=l?b:k;k=l?k:n?m:k;break d}b=G[a+48>>2];o=(o|0)>(b|0);p=G[a+8>>2];k=o?b:k;L[(p+M(c,168)|0)+8>>3]=(o?k:n?m:k)|0;k=G[a+44>>2];k=(k|0)>(l|0)?k:l}l=M(c,168);m=l+p|0;L[m+16>>3]=k|0;o=lb(b+1|0,4);G[m+24>>2]=o;Pf(a,c,d,e);b=l+G[a+8>>2]|0;r=L[b+16>>3];i=L[b+8>>3];e:{if(O(i)<2147483648){k=~~i;break e}k=-2147483648}i=+(k|0);if(!(r>=i)){break a}g=(h-+(q|0))/g+1;s=M(c,168);while(1){h=i-j;h=f*f-h*h;f:{if(!(h>=0)){break f}i=V(h);h=g+i;g:{if(O(h)<2147483648){b=~~h;break g}b=-2147483648}m=b-(h==+(b|0))|0;h=g-i;h:{if(O(h)<2147483648){l=~~h;break h}l=-2147483648}if((m|0)<=(l|0)){break f}b=G[a+48>>2];c=G[a+44>>2];q=lb(1,8);n=l+1|0;G[q+4>>2]=n;i:{if(!o){break i}c=(c|0)>(k|0)?c:k;p=((b|0)>(c|0)?c:b)<<2;b=p+o|0;c=G[b>>2];j:{if(!c){c=0;break j}if((n|0)>2]){break j}while(1){b=c;c=G[b>>2];if(!c){c=0;break j}if((l|0)>=G[c+4>>2]){continue}break}}G[q>>2]=c;G[b>>2]=q;if((e|0)==1){break i}if(d){b=p+G[a+56>>2]|0;if((l|0)>2]){c=b;b=G[a+36>>2];G[c>>2]=(b|0)>(n|0)?b:n}b=p+G[a+60>>2]|0;if((n|0)>2]){break i}c=b;b=G[a+40>>2];G[c>>2]=(b|0)<(n|0)?b:n;break i}G[p+G[a+56>>2]>>2]=G[a+36>>2];G[p+G[a+60>>2]>>2]=G[a+40>>2]}b=G[a+48>>2];c=G[a+44>>2];n=lb(1,8);G[n+4>>2]=m;if(!o){break f}c=(c|0)>(k|0)?c:k;l=((b|0)>(c|0)?c:b)<<2;b=l+o|0;c=G[b>>2];k:{if(!c){c=0;break k}if((m|0)>2]){break k}while(1){b=c;c=G[b>>2];if(!c){c=0;break k}if((m|0)>G[c+4>>2]){continue}break}}G[n>>2]=c;G[b>>2]=n;if((e|0)==1){break f}if(d){b=l+G[a+56>>2]|0;if((m|0)<=G[b>>2]){c=b;b=G[a+36>>2];G[c>>2]=(b|0)>(m|0)?b:m}b=l+G[a+60>>2]|0;if((m|0)>2]){break f}c=b;b=G[a+40>>2];G[c>>2]=(b|0)<(m|0)?b:m;break f}G[l+G[a+56>>2]>>2]=G[a+36>>2];G[l+G[a+60>>2]>>2]=G[a+40>>2]}k=k+1|0;i=+(k|0);if(i<=L[(G[a+8>>2]+s|0)+16>>3]){continue}break}}}function Zl(a){var b=0,c=0,d=0,e=0,f=0,g=0;b=Fa-20672|0;Fa=b;f=em(a);if(G[926536]){G[b+96>>2]=a;kb(77093,b+96|0);$a(G[29763])}if(f){c=Ph(f);if(c){g=G[29763];while(1){if(G[926536]){G[b+80>>2]=c+19;kb(76135,b+80|0);$a(g)}G[b+64>>2]=a;c=c+19|0;G[b+68>>2]=c;d=b+16576|0;db(d,8778,b- -64|0);Za(3739772,d+(I[b+16576>>1]==12078?2:G[935265])|0);if(G[926536]){G[b+52>>2]=3739772;G[b+48>>2]=b+16576;kb(76239,b+48|0);$a(g)}a:{if(Be(b+16576|0,b+104|0)){break a}if((G[b+116>>2]&61440)==16384){if(!G[935257]){break a}if(!Xa(c,48504)){break a}if(!Xa(c,45311)){break a}if(G[926536]){G[b>>2]=b+16576;kb(76155,b);$a(g)}Zl(b+16576|0);break a}d=Va(b+16576|0);if(G[926536]){G[b+32>>2]=b+16576;kb(77122,b+32|0);$a(g)}if(!G[935258]){c=d+(b+16576|0)|0;e=c-9|0;if(!fb(e,4996,9)){break a}if(!fb(e,33375,9)){break a}e=c-10|0;if(!fb(e,5641,10)){break a}if(!fb(e,33593,10)){break a}e=c-12|0;if(!fb(e,2685,12)){break a}if(!fb(e,2722,12)){break a}c=c-13|0;if(!fb(c,2698,13)){break a}if(!fb(c,2735,13)){break a}}c=d+(b+16576|0)|0;d=c-4|0;b:{if(!fb(d,5001,4)){break b}if(!fb(d,33380,4)){break b}d=c-5|0;if(!fb(d,5646,5)){break b}if(!fb(d,33598,5)){break b}d=c-7|0;if(!fb(d,2754,7)){break b}if(!fb(d,2771,7)){break b}if(!fb(d,2690,7)){break b}if(!fb(d,2727,7)){break b}d=c-8|0;if(!fb(d,2762,8)){break b}if(!fb(d,2779,8)){break b}if(!fb(d,2703,8)){break b}if(fb(d,2740,8)){break a}}E[b+12480|0]=0;c:{d=c-7|0;d:{if(!fb(d,2690,7)){break d}if(!fb(d,2727,7)){break d}c=c-8|0;if(!fb(c,2703,8)){break d}if(fb(c,2740,8)){break c}}c=H[32839]|H[32840]<<8|(H[32841]<<16|H[32842]<<24);d=H[32835]|H[32836]<<8|(H[32837]<<16|H[32838]<<24);E[b+8391|0]=d;E[b+8392|0]=d>>>8;E[b+8393|0]=d>>>16;E[b+8394|0]=d>>>24;E[b+8395|0]=c;E[b+8396|0]=c>>>8;E[b+8397|0]=c>>>16;E[b+8398|0]=c>>>24;c=H[32832]|H[32833]<<8|(H[32834]<<16|H[32835]<<24);G[b+8384>>2]=H[32828]|H[32829]<<8|(H[32830]<<16|H[32831]<<24);G[b+8388>>2]=c;c=Za(b+4288|0,kj(b+8384|0));G[b+20>>2]=c;G[b+16>>2]=b+16576;d=b+192|0;db(d,9290,b+16|0);ka(d|0)|0;d=Mh(c,3739768,b+12480|0);Vg(c);if(!d){break a}G[935248]=d+G[935248];break a}c=Mh(b+16576|0,3739768,b+12480|0);if(!c){break a}G[935248]=c+G[935248]}c=Ph(f);if(c){continue}break}}_l(f)}Fa=b+20672|0}function Wb(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;g=G[e>>2];if((g|0)<=0){g=G[a>>2];if((g|0)!=G[G[a+4>>2]+76>>2]){mb(a,g+1|0,0,e)}if((c|0)>=0&b>>>0>=2147483648|(c|0)>0){Ua(45458);G[e>>2]=106;return 106}g=G[a+4>>2];if(G[g+72>>2]<0){Hc(a,Bu(G[g+56>>2],G[g+60>>2],2880,0),0,e)}g=b;a:{if((c|0)>=0&b>>>0>=8640|(c|0)>0){j=b;b=G[a+4>>2];h=G[b+56>>2];k=j+h|0;j=c;c=G[b+60>>2];f=j+c|0;f=h>>>0>k>>>0?f+1|0:f;k=Bu(k-1|0,f-!k|0,2880,0);l=G[b+72>>2];j=l<<2;m=G[(j+b|0)+1256>>2];f=Au(m,0,-2880,0)+h|0;if((f|0)!=2880){b=f+(G[b+1252>>2]+M(l,2880)|0)|0;f=2880-f|0;bb(b,d,f);b=G[a+4>>2];G[(j+b|0)+1416>>2]=1;g=g-f|0;c=(f>>31)+c|0;h=f+h|0;c=h>>>0>>0?c+1|0:c;d=d+f|0}while(1){f=i<<2;j=f+b|0;n=G[j+1256>>2];if(!((n|0)<(m|0)|(k|0)<(n|0))){if(G[j+1416>>2]){Hg(b,i,e);b=G[a+4>>2]}G[(b+f|0)+1256>>2]=-1}i=i+1|0;if((i|0)!=40){continue}break}if(G[b+64>>2]!=(h|0)|G[b+68>>2]!=(c|0)){Ja[G[(M(G[b+4>>2],84)+1240576|0)+72>>2]](G[b>>2],h,c)|0;b=G[a+4>>2]}j=b;b=g-1|0;f=b-((b|0)%2880|0)|0;fi(j,f,d,e);b=(f>>31)+c|0;h=f+h|0;b=h>>>0>>0?b+1|0:b;i=G[a+4>>2];G[i+64>>2]=h;G[i+68>>2]=b;j=d+f|0;c=g-f|0;d=G[i+36>>2];b:{if((b|0)>=(d|0)&h>>>0>=J[i+32>>2]|(b|0)>(d|0)){G[i+32>>2]=h;G[i+36>>2]=b;d=M(l,2880);g=d+G[i+1252>>2]|0;if(G[i+80>>2]==1){cb(g,32,2880);break b}cb(g,0,2880);break b}d=M(l,2880);Lj(i,2880,d+G[i+1252>>2]|0,e);g=G[a+4>>2];f=G[g+68>>2];i=G[g+64>>2]+2880|0;f=i>>>0<2880?f+1|0:f;G[g+64>>2]=i;G[g+68>>2]=f}bb(G[G[a+4>>2]+1252>>2]+d|0,j,c);a=G[a+4>>2];d=a+(l<<2)|0;G[d+1256>>2]=k;G[d+1416>>2]=1;b=(c>>31)+b|0;d=c+h|0;b=d>>>0>>0?b+1|0:b;G[a+56>>2]=d;G[a+60>>2]=b;c=G[a+44>>2];d=k+1|0;b=d>>31;g=G[a+40>>2];b=Au(d,b,2880,0);j=b;d=b>>>0>>0;b=Ia;d=d&(c|0)>=(b|0)|(b|0)<(c|0);G[a+40>>2]=d?g:j;G[a+44>>2]=d?c:b;break a}if(!g){break a}b=G[a+4>>2];b=Au(G[((G[b+72>>2]<<2)+b|0)+1256>>2],0,-2880,0)+G[b+56>>2]|0;i=2880-b|0;while(1){j=b;b=G[a+4>>2];c=(g|0)<(i|0)?g:i;bb(j+(G[b+1252>>2]+M(G[b+72>>2],2880)|0)|0,d,c);h=G[a+4>>2];f=c+G[h+56>>2]|0;b=G[h+60>>2]+(c>>31)|0;b=c>>>0>f>>>0?b+1|0:b;G[h+56>>2]=f;G[h+60>>2]=b;G[(h+(G[h+72>>2]<<2)|0)+1416>>2]=1;g=g-c|0;if(!g){break a}Hc(a,Bu(f,b,2880,0),1,e);d=c+d|0;b=0;i=2880;continue}}g=G[e>>2]}return g}function Lr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;if(G[c+4>>2]!=703){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=81;E[c+1|0]=83;E[c+2|0]=67;E[c+3|0]=0;E[c+4|0]=191;E[c+5|0]=2;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];a:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=45;j=.022222222222222223;break a}f=f*3.141592653589793*.25;j=1/f}G[c+1892>>2]=105;G[c+1888>>2]=106;L[c+112>>3]=f;L[c+120>>3]=j}r=e;b:{c:{if(O(b)==90){G[d>>2]=0;G[d+4>>2]=0;a=L[c+112>>3];a=O(a+a);a=b<0?-a:a;break c}f=Mb(b);k=Mb(a);h=Kb(a);j=Kb(b);g=-j;h=f*h;l=-h;k=f*k;f=-k;n=j180?a+-360:a)*.017453292519943295;f=a*a;a=b*3.141592653589793/180;g=(f+a*a)*.5;break e;case 2:i=0;m=2;if(!(g<1e-8)){break f}a=Yc(a,360);a=(90-(a<-180?a+360:a))*3.141592653589793/180;h=a*a;a=b*3.141592653589793/180;g=(h+a*a)*.5;break f;case 3:i=0;m=4;if(!(g<1e-8)){break g}a=Yc(a,360);a=(180-(a<0?a+360:a))*3.141592653589793/180;f=a*a;a=b*3.141592653589793/180;g=(f+a*a)*.5;break g;case 4:i=0;m=6;if(!(g<1e-8)){break h}a=Yc(a,360);a=a>180?a+-360:a;a=a*((a+90)*3.141592653589793/180);f=a*a;a=b*3.141592653589793/180;g=(f+a*a)*.5;break h;default:break i}}i=-2;if(g<1e-8){a=(b+90)*3.141592653589793/180;g=a*a*.5}f=k;break d}h=k;f=j;break d}h=l;f=j;break d}h=f;f=j;break d}f=j;i=0}b=0;j:{if(!(h!=0|f!=0)){a=0;break j}a=O(f);if(a<=-h){a=f/h;b=a*a+1;f=V(g/(1-1/V(b+1)));a=f/-15*(De(a)-Bc(a/V(b+b)));b=-f;break j}if(a<=h){a=f/h;f=a*a+1;b=V(g/(1-1/V(f+1)));a=b/15*(De(a)-Bc(a/V(f+f)));break j}j=O(h);if(j<-f){a=h/f;b=a*a+1;f=V(g/(1-1/V(b+1)));b=f/-15*(De(a)-Bc(a/V(b+b)));a=-f;break j}a=0;if(!(f>j)){break j}b=h/f;f=b*b+1;a=V(g/(1-1/V(f+1)));b=a/15*(De(b)-Bc(b/V(f+f)))}f=O(b);if(f>1){e=2;if(f>1.000000000001){break b}b=b<0?-1:1}f=O(a);if(f>1){e=2;if(f>1.000000000001){break b}a=a<0?-1:1}L[d>>3]=(m+b)*L[c+112>>3];a=(i+a)*L[c+112>>3]}L[r>>3]=a;e=0}return e|0}function Ck(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0;f=Fa-176|0;Fa=f;a:{if(G[d>>2]>0){break a}e=G[a>>2];if((e|0)!=G[G[a+4>>2]+76>>2]){mb(a,e+1|0,0,d)}b:{if((b|0)>0){e=G[a+4>>2];if(G[e+936>>2]>=(b|0)){break b}}G[f>>2]=b;a=f+80|0;Ya(a,81,30457,f);Ua(a);G[d>>2]=302;break a}e=G[(G[e+968>>2]+M(b,160)|0)-80>>2];h=f+80|0;zb(34187,b,h,d);G[c>>2]=0;G[f+40>>2]=0;g=e;e=e>>31;g=(g^e)-e|0;c:{d:{e:{if(Fc(a,h,f+48|0,0,f+40|0)){break e}e=f+48|0;while(1){f:{switch(H[e|0]-32|0){case 0:e=e+1|0;continue;case 33:case 36:case 37:case 38:case 39:case 41:case 47:case 58:case 65:case 68:case 69:case 70:case 71:case 73:case 79:case 90:break f;default:break e}}break}while(1){h=e;i=E[e|0];if(i-48>>>0>=10){e=h+1|0;if(i){continue}}break}e=_b(h);G[c>>2]=e;if(g>>>0<83){break d}G[c>>2]=(e<<1)+3;break c}e=G[c>>2]}if(e){break c}e=f+80|0;zb(34641,b,e,d);Fc(a,e,f+48|0,0,d);zb(34838,b,e,d);G[f+40>>2]=0;e=!Kc(a,e,f+32|0,f+40|0)&L[f+32>>3]!=1;if(!(!e|g>>>0>21)){G[c>>2]=14;break c}if(e&(g|0)==41){G[c>>2]=23;break c}if(e&(g|0)==81){G[c>>2]=23;break c}Dc(a,f+44|0,d);if(G[f+44>>2]==1){e=f+48|0;while(1){a=e;b=E[e|0];if(b-48>>>0>=10){e=a+1|0;if(b){continue}}break}j=c,k=_b(a),G[j>>2]=k;break c}g:{switch(g-1|0){case 0:G[c>>2]=8;break c;case 10:G[c>>2]=4;break c;case 20:G[c>>2]=6;break c;default:break g}}if((g|0)==41){G[c>>2]=11;break c}if((g|0)==81){G[c>>2]=20;break c}h:{i:{j:{k:{l:{m:{switch(g-14|0){default:switch(g-82|0){case 1:break k;case 0:break l;default:break j};case 2:break h;case 0:break i;case 28:break m;case 1:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:break c}}G[c>>2]=14;break c}G[c>>2]=23;break c}G[c>>2]=31;break c}if((g|0)!=163){break c}G[c>>2]=49;break c}G[c>>2]=1;break c}G[f+24>>2]=0;G[f+20>>2]=0;G[f+16>>2]=0;e=f+48|0;n:{o:{if(vd(a,b,f+28|0,f+24|0,f+20|0,f+16|0)){break o}a=G[f+20>>2];if((a|0)<=0){break o}if(G[f+24>>2]>(a|0)){break n}}while(1){a=e;b=E[e|0];if(b-48>>>0>=10){e=a+1|0;if(b){continue}}break}a=_b(a)}G[c>>2]=(a|0)>1?a:1}}Fa=f+176|0}function mp(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;a:{if(!G[a+5792>>2]){e=G[a+5820>>2];break a}l=a+5817|0;while(1){m=d+1|0;h=H[G[a+5784>>2]+d|0];n=a;k=I[G[a+5796>>2]+(d<<1)>>1];b:{c:{if(!k){d=(h<<2)+b|0;f=I[d+2>>1];g=I[d>>1];d=G[a+5820>>2];e=I[a+5816>>1]|g<>1]=e;if((d|0)>(16-f|0)){d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=e;d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=H[l|0];d=G[a+5820>>2];F[a+5816>>1]=g>>>16-d;e=(d+f|0)-16|0;break c}e=d+f|0;break c}f=H[h+116208|0];j=f<<2;d=j+b|0;i=I[d+1030>>1];g=I[d+1028>>1];d=G[a+5820>>2];e=I[a+5816>>1]|g<>1]=e;d:{if((d|0)>(16-i|0)){d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=e;d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=H[l|0];d=G[a+5820>>2];e=g>>>16-d|0;F[a+5816>>1]=e;d=(d+i|0)-16|0;break d}d=d+i|0}G[a+5820>>2]=d;if(f-28>>>0>=4294967276){f=h-G[j+118176>>2]|0;g=G[j+117808>>2];e:{if((16-g|0)<(d|0)){e=f<>1]=e;d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=e;d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=H[l|0];d=G[a+5820>>2];e=(f&65535)>>>16-d|0;F[a+5816>>1]=e;d=(d+g|0)-16|0;break e}e=f<>1]=e;d=d+g|0}G[a+5820>>2]=d}i=k-1|0;f=H[(i>>>0<256?i:(i>>>7|0)+256|0)+115696|0];k=f<<2;g=k+c|0;j=I[g+2>>1];h=e;e=I[g>>1];h=h|e<>1]=h;f:{if((16-j|0)<(d|0)){d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=h;d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=H[l|0];d=G[a+5820>>2];h=e>>>16-d|0;F[a+5816>>1]=h;e=(d+j|0)-16|0;break f}e=d+j|0}G[a+5820>>2]=e;if(f>>>0<4){break b}f=i-G[k+118304>>2]|0;g=G[k+117936>>2];if((16-g|0)<(e|0)){e=f<>1]=e;d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=e;d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=H[l|0];d=G[a+5820>>2];F[a+5816>>1]=(f&65535)>>>16-d;e=(d+g|0)-16|0;break c}F[a+5816>>1]=f<>2]=e}d=m;if(d>>>0>2]){continue}break}}m=I[b+1026>>1];d=I[b+1024>>1];c=I[a+5816>>1]|d<>1]=c;if((16-m|0)<(e|0)){b=G[a+20>>2];G[a+20>>2]=b+1;E[b+G[a+8>>2]|0]=c;b=G[a+20>>2];G[a+20>>2]=b+1;E[b+G[a+8>>2]|0]=H[a+5817|0];b=G[a+5820>>2];F[a+5816>>1]=d>>>16-b;G[a+5820>>2]=(b+m|0)-16;return}G[a+5820>>2]=e+m}function mc(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;e=G[d>>2];if((e|0)<=0){E[b|0]=0;if(c){E[c|0]=0}f=Va(a);a:{b:{c:{d:{e:{f:{g:{h:{e=H[a|0];if((e|0)==72){if(fb(a,66642,9)){break h}e=qc(a,36178);if((e|0)==(f|0)){if(!c|f>>>0<9){break a}c=Za(c,a+8|0);a=f-9|0;if((a|0)<0){break a}while(1){b=a+c|0;if(H[b|0]!=32){break a}E[b|0]=0;b=(a|0)>0;a=a-1|0;if(b){continue}break}break a}e=e+1|0;break b}if(f>>>0<9){break a}switch(e-67|0){case 1:break c;case 0:break f;case 2:break g;default:break e}}if(f>>>0<9){break a}if(!fb(a,66546,8)){break d}break c}if(!fb(a,68041,8)){break d}break c}if(!fb(a,66587,8)){break d}if(!fb(a,35367,8)){break d}break c}if((e|0)!=32){break c}if(fb(a,68289,8)){break c}}if(!c){break a}c=Za(c,a+8|0);a=f-9|0;if((a|0)<0){break a}while(1){b=a+c|0;if(H[b|0]!=32){break a}E[b|0]=0;b=(a|0)>0;a=a-1|0;if(b){continue}break}break a}g=a+8|0;i:{if(H[a+8|0]!=61){break i}if(fb(g,66740,2)){break i}e=10;break b}e=qc(a,36178);if((e|0)==(f|0)){if(!c){break a}c=Za(c,g);a=f-9|0;if((a|0)<0){break a}while(1){b=a+c|0;if(H[b|0]!=32){break a}E[b|0]=0;b=(a|0)>0;a=a-1|0;if(b){continue}break}break a}e=e+1|0}h=Me(a+e|0,68332)+e|0;if((h|0)==(f|0)){break a}j:{k:{l:{m:{n:{g=a+h|0;switch(H[g|0]-39|0){case 1:break l;case 0:break m;case 8:break n;default:break k}}f=h+1|0;break j}E[b|0]=39;i=1;g=h+1|0;o:{if(g>>>0>=f>>>0){break o}while(1){j=H[a+g|0];if((j|0)!=39){e=g}else{e=h+2|0;k=e+a|0;j=H[k|0];E[b+i|0]=39;if((j|0)!=39){break o}i=i+1|0;j=H[k|0]}E[b+i|0]=j;i=i+1|0;h=e;g=e+1|0;if(g>>>0>>0){continue}break}}if((f|0)==(g|0)){b=((i|0)<69?i:69)+b|0;E[b|0]=39;E[b+1|0]=0;tb(5,37677);tb(5,a);break j}E[(b+i|0)+1|0]=0;f=h+2|0;break j}e=qc(g,64244);if((Va(g)|0)==(e|0)){tb(5,40121);tb(5,a);G[d>>2]=205;return 205}f=b;b=e+1|0;l=rb(f,g,b)+b|0,m=0,E[l|0]=m;f=b+h|0;break j}e=b;b=qc(g,42204);l=rb(e,g,b)+b|0,m=0,E[l|0]=m;f=b+h|0}if(!c){break a}b=Me(a+f|0,68332)+f|0;if(b>>>0>79){break a}if(H[a+b|0]==47){e=b+2|0;b=b+1|0;b=H[a+b|0]==32?e:b}e=Gb(c,a+b|0);a=Va(e);if((a|0)<=0){break a}while(1){b=a-1|0;c=b+e|0;if(H[c|0]!=32){break a}E[c|0]=0;c=a>>>0>1;a=b;if(c){continue}break}}e=G[d>>2]}return e}function bc(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;t=Fa-80|0;Fa=t;n=-1;a:{if((b|d)<0){break a}b:{i=G[309723];if((i|0)==G[309724]){g=G[309722];c:{if(g){G[309724]=i<<1;g=ub(g,M(i,688));break c}G[309724]=100;g=ab(34400)}if(!g){break b}G[309722]=g;i=G[309723]}G[309723]=i+1;d:{if((i|0)<0){break d}f=G[309722];o=f+M(i,344)|0;G[o+52>>2]=a;G[o+12>>2]=b;G[o+8>>2]=2;G[o>>2]=c;G[o+16>>2]=d;g=M(d,344)+f|0;a=M(b,344);l=a+f|0;v=G[l>>2]==-1e3?G[g>>2]==-1e3:v;a=a+f|0;u=G[a+56>>2];e:{f:{g:{j=G[a+52>>2];if(j-261>>>0<2){break g}if((u|0)==1){break f}e=M(d,344)+f|0;a=G[e+56>>2];if((a|0)==1){break e}h:{if((j|0)!=G[e+52>>2]|(a|0)!=(u|0)){break h}p=G[(M(b,344)+f|0)+60>>2];if((p|0)!=G[(M(d,344)+f|0)+60>>2]){break h}h=1;if((p|0)<=0){break e}a=0;if(p-1>>>0>=3){j=p&-4;while(1){q=a<<2;e=q|4;r=h;s=(M(b,344)+f|0)- -64|0;h=(M(d,344)+f|0)- -64|0;r=G[e+s>>2]==G[e+h>>2]?G[s+q>>2]==G[h+q>>2]?r:0:0;e=q|8;r=G[e+s>>2]==G[e+h>>2]?r:0;e=q|12;h=G[e+s>>2]==G[e+h>>2]?r:0;a=a+4|0;k=k+4|0;if((j|0)!=(k|0)){continue}break}}e=p&3;if(e){while(1){k=a<<2;h=G[(k+(M(b,344)+f|0)|0)- -64>>2]==G[(k+(M(d,344)+f|0)|0)- -64>>2]?h:0;a=a+1|0;m=m+1|0;if((e|0)!=(m|0)){continue}break}}if(h){break g}}a=G[309723];if(a){G[309723]=a-1}if(!G[309737]){G[309737]=431}a=bb(t,135531,80);E[a+79|0]=0;Ua(a);break a}if((u|0)!=1){break e}}l=g}e=M(i,344)+f|0;G[e+56>>2]=G[l+56>>2];G[e+60>>2]=G[l+60>>2];k=G[l+60>>2];i:{if((k|0)<=0){break i}n=0;d=0;if(k-1>>>0>=3){b=k&-4;h=(M(i,344)+f|0)- -64|0;g=0;while(1){j=d<<2;m=l- -64|0;G[j+h>>2]=G[m+j>>2];a=j|4;G[a+h>>2]=G[a+m>>2];a=j|8;G[a+h>>2]=G[a+m>>2];a=j|12;G[a+h>>2]=G[a+m>>2];d=d+4|0;g=g+4|0;if((b|0)!=(g|0)){continue}break}}g=k&3;if(!g){break i}b=M(i,344)+f|0;while(1){a=d<<2;G[(a+b|0)- -64>>2]=G[(a+l|0)- -64>>2];d=d+1|0;n=n+1|0;if((g|0)!=(n|0)){continue}break}}b=M(i,344)+f|0;a=G[l+52>>2];j:{k:{if(!((c|0)!=290|(a|0)!=262)){G[e+56>>2]=1;G[e+60>>2]=1;G[(M(i,344)+f|0)- -64>>2]=1;a=23;break k}a=a-258|0;if(a>>>0>4){break j}a=G[(a<<2)+137072>>2]}G[b+4>>2]=a}if(!v){break d}Ja[G[(M(i,344)+f|0)+4>>2]](o)}n=i;break a}G[309737]=113}Fa=t+80|0;return n}function yo(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;h=1<=2){o=b-1|0;l=c&-2;p=c-1|0;q=(c-2>>>1|0)+1|0;r=(c|0)<2;while(1){f=M(e,k);i=j;m=0;if(r){g=0}else{while(1){g=f;a:{b:{c:{d:{switch(H[a+i|0]-1|0){case 0:g=(e+f|0)+1|0;break b;case 1:g=e+f|0;break b;case 2:g=e+f|0;n=(g<<2)+d|0;G[n+4>>2]=G[n+4>>2]|h;break b;case 3:g=f|1;break b;case 4:g=(e+f<<2)+d|0;G[g+4>>2]=G[g+4>>2]|h;g=f|1;break b;case 5:g=(e+f<<2)+d|0;G[g>>2]=G[g>>2]|h;g=f|1;break b;case 6:g=(e+f<<2)+d|0;G[g>>2]=G[g>>2]|h;G[g+4>>2]=G[g+4>>2]|h;g=f|1;break b;case 8:g=(e+f<<2)+d|0;G[g+4>>2]=G[g+4>>2]|h;break c;case 9:g=(e+f<<2)+d|0;G[g>>2]=G[g>>2]|h;break c;case 10:g=(e+f<<2)+d|0;G[g>>2]=G[g>>2]|h;G[g+4>>2]=G[g+4>>2]|h;break c;case 11:g=(f<<2|4)+d|0;G[g>>2]=G[g>>2]|h;break c;case 12:g=(e+f<<2)+d|0;G[g+4>>2]=G[g+4>>2]|h;g=(f<<2|4)+d|0;G[g>>2]=G[g>>2]|h;break c;case 13:g=(e+f<<2)+d|0;G[g>>2]=G[g>>2]|h;g=(f<<2|4)+d|0;G[g>>2]=G[g>>2]|h;break c;case 7:break b;case 14:break d;default:break a}}g=(e+f<<2)+d|0;G[g>>2]=G[g>>2]|h;G[g+4>>2]=G[g+4>>2]|h;g=(f<<2|4)+d|0;G[g>>2]=G[g>>2]|h}g=f}g=(g<<2)+d|0;G[g>>2]=G[g>>2]|h}i=i+1|0;f=f+2|0;m=m+2|0;if((p|0)>(m|0)){continue}break}j=j+q|0;g=l}if((g|0)<(c|0)){e:{f:{g:{switch(H[a+j|0]-2|0){case 0:case 1:case 4:case 5:f=e+f|0;break f;case 8:i=(e+f<<2)+d|0;G[i>>2]=G[i>>2]|h;break f;case 9:i=(e+f<<2)+d|0;G[i>>2]=G[i>>2]|h;break f;case 12:i=(e+f<<2)+d|0;G[i>>2]=G[i>>2]|h;break f;case 6:case 7:case 10:case 11:break f;case 13:break g;default:break e}}i=(e+f<<2)+d|0;G[i>>2]=G[i>>2]|h}f=(f<<2)+d|0;G[f>>2]=G[f>>2]|h}j=j+1|0}k=k+2|0;if((o|0)>(k|0)){continue}break}}h:{if((b|0)<=(k|0)){break h}f=M(e,k);if((c|0)>=2){l=c-1|0;e=(c-2>>>1|0)+j|0;g=0;while(1){i=f;i:{j:{k:{switch(H[a+j|0]-4|0){case 0:case 1:case 2:case 3:i=f|1;break j;case 4:case 5:case 6:case 7:break j;case 8:case 9:case 10:case 11:break k;default:break i}}b=(f<<2|4)+d|0;G[b>>2]=G[b>>2]|h}b=(i<<2)+d|0;G[b>>2]=G[b>>2]|h}j=j+1|0;f=f+2|0;g=g+2|0;if((l|0)>(g|0)){continue}break}j=e+1|0;b=c&-2}else{b=0}if((b|0)>=(c|0)|(H[a+j|0]&248)!=8){break h}a=(f<<2)+d|0;G[a>>2]=G[a>>2]|h}}function xd(a,b,c,d,e,f){var g=0;g=Fa-336|0;Fa=g;if(G[f>>2]<=0){a:{b:{switch(b-11|0){case 5:lc(a,c,d,e,f);break a;case 0:G[g+16>>2]=H[d|0];G[g+20>>2]=0;E[g+256|0]=0;if((db(g+256|0,26741,g+16|0)|0)<0){Ua(17884);G[f>>2]=401}b=g+160|0;Ob(c,g+256|0,e,b,f);wb(a,b,f);break a;case 1:b=E[d|0];G[g+32>>2]=b;G[g+36>>2]=b>>31;E[g+256|0]=0;if((db(g+256|0,26741,g+32|0)|0)<0){Ua(17884);G[f>>2]=401}b=g+160|0;Ob(c,g+256|0,e,b,f);wb(a,b,f);break a;case 9:G[g+48>>2]=I[d>>1];G[g+52>>2]=0;E[g+256|0]=0;if((db(g+256|0,26741,g+48|0)|0)<0){Ua(17884);G[f>>2]=401}b=g+160|0;Ob(c,g+256|0,e,b,f);wb(a,b,f);break a;case 10:b=F[d>>1];G[g+64>>2]=b;G[g+68>>2]=b>>31;E[g+256|0]=0;if((db(g+256|0,26741,g- -64|0)|0)<0){Ua(17884);G[f>>2]=401}b=g+160|0;Ob(c,g+256|0,e,b,f);wb(a,b,f);break a;case 19:b=g+256|0;ml(+J[d>>2],b,f);d=b;b=g+160|0;Ob(c,d,e,b,f);wb(a,b,f);break a;case 20:b=G[d>>2];G[g+80>>2]=b;G[g+84>>2]=b>>31;E[g+256|0]=0;if((db(g+256|0,26741,g+80|0)|0)<0){Ua(17884);G[f>>2]=401}b=g+160|0;Ob(c,g+256|0,e,b,f);wb(a,b,f);break a;case 3:F[g+256>>1]=G[d>>2]?84:70;b=g+160|0;Ob(c,g+256|0,e,b,f);wb(a,b,f);break a;case 29:G[g+96>>2]=G[d>>2];G[g+100>>2]=0;E[g+256|0]=0;if((db(g+256|0,4040,g+96|0)|0)<0){Ua(17840);G[f>>2]=401}b=g+160|0;Ob(c,g+256|0,e,b,f);wb(a,b,f);break a;case 69:b=G[d+4>>2];G[g+112>>2]=G[d>>2];G[g+116>>2]=b;E[g+256|0]=0;if((db(g+256|0,4040,g+112|0)|0)<0){Ua(17840);G[f>>2]=401}b=g+160|0;Ob(c,g+256|0,e,b,f);wb(a,b,f);break a;case 30:b=G[d>>2];G[g+128>>2]=b;G[g+132>>2]=b>>31;E[g+256|0]=0;if((db(g+256|0,26741,g+128|0)|0)<0){Ua(17884);G[f>>2]=401}b=g+160|0;Ob(c,g+256|0,e,b,f);wb(a,b,f);break a;case 70:b=G[d+4>>2];G[g+144>>2]=G[d>>2];G[g+148>>2]=b;E[g+256|0]=0;if((db(g+256|0,26741,g+144|0)|0)<0){Ua(17884);G[f>>2]=401}b=g+160|0;Ob(c,g+256|0,e,b,f);wb(a,b,f);break a;case 31:b=g+256|0;hg(K[d>>2],-7,b,f);d=b;b=g+160|0;Ob(c,d,e,b,f);wb(a,b,f);break a;case 71:b=g+256|0;If(L[d>>3],-15,b,f);d=b;b=g+160|0;Ob(c,d,e,b,f);wb(a,b,f);break a;case 72:pq(a,c,d,e,f);break a;case 152:oq(a,c,d,e,f);break a;default:break b}}G[g>>2]=b;a=g+160|0;Ya(a,81,49140,g);Ua(a);G[f>>2]=410}}Fa=g+336|0}function cl(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0;k=c==1&d==0;a:{if(!e){if(!k){if((b|0)<=0){break a}f=0;if((b|0)!=1){h=b&-2;e=0;while(1){L[(f<<3)+j>>3]=+G[(f<<2)+a>>2]*c+d;i=f|1;L[(i<<3)+j>>3]=+G[(i<<2)+a>>2]*c+d;f=f+2|0;e=e+2|0;if((h|0)!=(e|0)){continue}break}}if(!(b&1)){break a}L[(f<<3)+j>>3]=+G[(f<<2)+a>>2]*c+d;break a}if((b|0)<=0){break a}e=0;f=0;if(b-1>>>0>=3){h=b&-4;i=0;while(1){L[(f<<3)+j>>3]=G[(f<<2)+a>>2];k=f|1;L[(k<<3)+j>>3]=G[(k<<2)+a>>2];k=f|2;L[(k<<3)+j>>3]=G[(k<<2)+a>>2];k=f|3;L[(k<<3)+j>>3]=G[(k<<2)+a>>2];f=f+4|0;i=i+4|0;if((h|0)!=(i|0)){continue}break}}b=b&3;if(!b){break a}while(1){L[(f<<3)+j>>3]=G[(f<<2)+a>>2];f=f+1|0;e=e+1|0;if((b|0)!=(e|0)){continue}break}break a}b:{if(!k){if((b|0)<=0){break a}if((e|0)==1){break b}e=0;while(1){k=G[(e<<2)+a>>2];c:{if((k|0)==(f|0)){G[i>>2]=1;E[e+h|0]=1;break c}L[(e<<3)+j>>3]=+(k|0)*c+d}e=e+1|0;if((e|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)!=1){l=b&1;e=0;if((b|0)!=1){m=b&-2;b=0;while(1){k=G[(e<<2)+a>>2];d:{if((k|0)==(f|0)){G[i>>2]=1;E[e+h|0]=1;break d}L[(e<<3)+j>>3]=k|0}k=e|1;o=G[(k<<2)+a>>2];e:{if((o|0)!=(f|0)){L[(k<<3)+j>>3]=o|0;break e}G[i>>2]=1;E[h+k|0]=1}e=e+2|0;b=b+2|0;if((m|0)!=(b|0)){continue}break}}if(!l){break a}a=G[(e<<2)+a>>2];if((a|0)!=(f|0)){L[(e<<3)+j>>3]=a|0;break a}G[i>>2]=1;E[e+h|0]=1;break a}h=b&1;e=0;if((b|0)!=1){k=b&-2;b=0;while(1){m=(e<<3)+j|0;l=G[(e<<2)+a>>2];f:{if((l|0)!=(f|0)){c=+(l|0);break f}G[i>>2]=1;c=g}L[m>>3]=c;l=e|1;m=G[(l<<2)+a>>2];g:{if((m|0)!=(f|0)){c=+(m|0);break g}G[i>>2]=1;c=g}L[(l<<3)+j>>3]=c;e=e+2|0;b=b+2|0;if((k|0)!=(b|0)){continue}break}}if(!h){break a}a=G[(e<<2)+a>>2];h:{if((a|0)!=(f|0)){g=+(a|0);break h}G[i>>2]=1}L[(e<<3)+j>>3]=g;break a}h=b&1;e=0;if((b|0)!=1){k=b&-2;b=0;while(1){m=(e<<3)+j|0;l=G[(e<<2)+a>>2];i:{if((l|0)!=(f|0)){n=+(l|0)*c+d;break i}G[i>>2]=1;n=g}L[m>>3]=n;l=e|1;m=G[(l<<2)+a>>2];j:{if((m|0)!=(f|0)){n=+(m|0)*c+d;break j}G[i>>2]=1;n=g}L[(l<<3)+j>>3]=n;e=e+2|0;b=b+2|0;if((k|0)!=(b|0)){continue}break}}if(!h){break a}a=G[(e<<2)+a>>2];k:{if((a|0)!=(f|0)){g=+(a|0)*c+d;break k}G[i>>2]=1}L[(e<<3)+j>>3]=g}}function bd(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;k=Fa-160|0;Fa=k;a:{if(G[j>>2]>0){break a}s=vk(b);G[k+48>>2]=0;G[k+52>>2]=0;G[k+16>>2]=0;G[k+20>>2]=0;G[k+40>>2]=0;G[k+44>>2]=0;G[k+32>>2]=0;G[k+36>>2]=0;G[k>>2]=0;G[k+4>>2]=0;G[k+8>>2]=0;G[k+12>>2]=0;G[k+144>>2]=1;G[k+148>>2]=1;G[k+136>>2]=1;G[k+140>>2]=1;G[k+128>>2]=1;G[k+132>>2]=1;Qd(a,k+156|0,j);de(a,6,k+128|0,j);G[k+64>>2]=1;G[k+68>>2]=0;p=G[k+132>>2];t=G[k+128>>2];m=t;l=m>>31;G[k+72>>2]=m;G[k+76>>2]=l;l=Au(m,l,p,p>>31);G[k+80>>2]=l;m=Ia;G[k+84>>2]=m;n=l;l=G[k+136>>2];l=Au(n,m,l,l>>31);G[k+88>>2]=l;m=Ia;G[k+92>>2]=m;n=l;l=G[k+140>>2];l=Au(n,m,l,l>>31);G[k+96>>2]=l;m=Ia;G[k+100>>2]=m;n=l;l=G[k+144>>2];x=k,y=Au(n,m,l,l>>31),G[x+104>>2]=y;G[k+108>>2]=Ia;u=G[k+156>>2];if((u|0)>0){l=e;e=c;c=c-1|0;l=l+c|0;d=d-!e|0;o=d+f|0;e=l-1|0;f=(c>>>0>l>>>0?o+1|0:o)-!l|0;l=u;while(1){v=l-1|0;m=v<<2;o=(k- -64|0)+(v<<3)|0;q=G[o>>2];r=G[o+4>>2];w=Bu(c,d,q,r);G[m+(k+32|0)>>2]=w;n=k+m|0;m=Bu(e,f,q,r);G[n>>2]=m;o=m>>31;n=e;m=Au(q,r,m,o);e=e-m|0;f=f-(Ia+(m>>>0>n>>>0)|0)|0;m=w;o=m>>31;n=c;m=Au(q,r,m,o);c=c-m|0;d=d-(Ia+(m>>>0>n>>>0)|0)|0;m=l>>>0>1;l=v;if(m){continue}break}}b:{c:{switch(u-1|0){case 1:ro(a,b,s,0,k+32|0,k,k+128|0,g,h,i,k+124|0,j);break b;case 2:c=G[k>>2];d:{if(G[k+32>>2]|G[k+36>>2]|(c|0)!=(t-1|0)){break d}d=G[k+4>>2];if((d|0)!=(p-1|0)){break d}G[k+32>>2]=1;G[k+36>>2]=1;G[k>>2]=c+1;G[k+4>>2]=d+1;G[k+40>>2]=G[k+40>>2]+1;G[k+8>>2]=G[k+8>>2]+1;G[k+44>>2]=G[k+44>>2]+1;G[k+12>>2]=G[k+12>>2]+1;G[k+48>>2]=G[k+48>>2]+1;G[k+16>>2]=G[k+16>>2]+1;G[k+52>>2]=G[k+52>>2]+1;G[k+20>>2]=G[k+20>>2]+1;uh(a,b,k+32|0,k,g,h,i,j);break b}e=G[k+4>>2];l=G[k+40>>2];d=G[k+8>>2];if((l|0)<(d|0)){G[k+4>>2]=p-1;G[k>>2]=t-1}if((d|0)<(l|0)){break b}while(1){if((d|0)==(l|0)){G[k+4>>2]=e;G[k>>2]=c}ro(a,b,s,l,k+32|0,k,k+128|0,g,h,i,k+124|0,j);G[k+32>>2]=0;G[k+36>>2]=0;h=M(G[k+124>>2],s)+h|0;f=(d|0)==(l|0);l=l+1|0;if(!f){continue}break};break b;default:Ua(28010);G[j>>2]=413;break a;case 0:break c}}G[k+32>>2]=G[k+32>>2]+1;G[k>>2]=G[k>>2]+1;uh(a,b,k+32|0,k,g,h,i,j)}}Fa=k+160|0}function kc(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;i=Fa-176|0;Fa=i;e=G[d>>2];a:{if((e|0)>0){break a}E[i+80|0]=0;while(1){g=b+f|0;f=f+1|0;if(H[g|0]==32){continue}break}h=qb(i+80|0,g,74);e=Va(h);b=e&e>>31;b:{c:{while(1){g=e;if((e|0)<=0){break c}e=g-1|0;if(H[h+e|0]==32){continue}break}e=0;E[g+h|0]=0;while(1){k=e+h|0;b=E[k|0];E[k|0]=b-97>>>0<26?b&95:b;e=e+1|0;if((g|0)!=(e|0)){continue}break}b=g;break b}E[b+h|0]=0}d:{e:{f:{if(H[h|0]!=72){g=b;break f}if(G[h>>2]!=1380272456|G[h+4>>2]!=1212371521){g=b;break f}g=8;if((b|0)==8){break e}b=h+8|0;while(1){f=b;b=f+1|0;e=H[f|0];if((e|0)==32){continue}break}g=e;b=h;if(e){g=0;while(1){E[b|0]=e;g=g+1|0;b=b+1|0;e=H[f+1|0];f=f+1|0;if(e){continue}break}}E[b|0]=0}r=1;o=1;b=g;if((g|0)>8){break d}}o=0;g:{if(jb(h,63)){break g}m=jb(h,42);if(m){break g}m=0;if(jb(h,35)){break g}o=1;b=g;break d}b=m?g-2|0:g;m=1}e=G[a>>2];f=G[a+4>>2];if((e|0)!=G[f+76>>2]){mb(a,e+1|0,0,d);f=G[a+4>>2];e=G[f+76>>2]}k=G[f+104>>2];j=G[f+96>>2]+(e<<3)|0;e=G[j>>2];j=G[j+4>>2];l=Bu(k-e|0,G[f+108>>2]-(j+(e>>>0>k>>>0)|0)|0,80,0);k=G[f+120>>2];k=Bu(k-e|0,G[f+124>>2]-((e>>>0>k>>>0)+j|0)|0,80,0);e=l-k|0;s=!o;p=((g|0)>2?g:2)-1|0;t=p+h|0;u=i+p|0;h:{while(1){i:{if((e|0)<=0){break i}j=0;if(r){while(1){Jg(a,c,d);Fi(c,i,i+172|0);j:{n=G[i+172>>2];if((n|0)<(b|0)|!((g|0)==(n|0)|s)){break j}f=0;if((n|0)>0){while(1){l=f+i|0;q=E[l|0];if((q|0)>=97){v=l;l=q&255;E[v|0]=l-97>>>0<26?l&95:l}f=f+1|0;if((n|0)!=(f|0)){continue}break}}if(!o){Fg(h,i,1,i+168|0,i+164|0);if(!G[i+168>>2]){break j}break h}k:{if(H[t|0]!=H[u|0]){if(g|n){break j}break k}if(H[h|0]!=H[i|0]){break j}if(fb(h,i,p)){break j}}e=G[d>>2];break a}j=j+1|0;if((j|0)!=(e|0)){continue}break i}}while(1){Jg(a,c,d);if(H[c|0]==72){if(!fb(34939,c,8)){break h}}j=j+1|0;if((j|0)!=(e|0)){continue}break}}if(!((m|w)&1)){e=G[a>>2];f=G[a+4>>2];if((e|0)!=G[f+76>>2]){mb(a,e+1|0,0,d);f=G[a+4>>2];e=G[f+76>>2]}e=G[f+96>>2]+(e<<3)|0;j=G[e+4>>2];G[f+120>>2]=G[e>>2];G[f+124>>2]=j;w=1;e=k;continue}break}e=202;G[d>>2]=202;break a}e=G[d>>2]}Fa=i+176|0;return e}function Mm(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;j=Fa-128|0;Fa=j;a:{b:{c:{if(!Sf(f,g,h,i,0,0,0,0)){break c}m=i&65535;n=i>>>16&32767;d:{e:{if((n|0)!=32767){l=4;if(n){break e}l=f|h|(g|m)?3:2;break d}l=!(f|h|(g|m))}}r=e>>>16|0;o=r&32767;if((o|0)==32767){break c}if(l){break b}}tc(j+16|0,b,c,d,e,f,g,h,i);e=G[j+16>>2];d=G[j+20>>2];c=G[j+24>>2];b=G[j+28>>2];Nm(j,e,d,c,b,e,d,c,b);d=G[j+8>>2];e=G[j+12>>2];h=G[j>>2];i=G[j+4>>2];break a}m=e&65535|o<<16;p=m;l=d;m=h;q=i>>>16&32767;k=i&65535|q<<16;if((Sf(b,c,l,p,f,g,h,k)|0)<=0){if(Sf(b,c,l,p,f,g,m,k)){h=b;i=c;break a}tc(j+112|0,b,c,d,e,0,0,0,0);d=G[j+120>>2];e=G[j+124>>2];h=G[j+112>>2];i=G[j+116>>2];break a}if(o){i=c;h=b}else{tc(j+96|0,b,c,l,p,0,0,0,1081540608);h=G[j+108>>2];p=h;l=G[j+104>>2];o=(h>>>16|0)-120|0;i=G[j+100>>2];h=G[j+96>>2]}if(!q){tc(j+80|0,f,g,m,k,0,0,0,1081540608);f=G[j+92>>2];k=f;m=G[j+88>>2];q=(k>>>16|0)-120|0;g=G[j+84>>2];f=G[j+80>>2]}s=k&65535|65536;p=p&65535|65536;if((o|0)>(q|0)){while(1){t=l-m|0;k=(g|0)==(i|0)&f>>>0>h>>>0|g>>>0>i>>>0;n=(p-((l>>>0>>0)+s|0)|0)-(t>>>0>>0)|0;k=t-k|0;f:{if((n|0)>0|(n|0)>=0){l=h;h=h-f|0;i=i-((f>>>0>l>>>0)+g|0)|0;if(!(h|k|(i|n))){tc(j+32|0,b,c,d,e,0,0,0,0);d=G[j+40>>2];e=G[j+44>>2];h=G[j+32>>2];i=G[j+36>>2];break a}n=n<<1|k>>>31;l=k<<1|i>>>31;p=n;break f}n=p<<1|l>>>31;l=l<<1|i>>>31;p=n}n=i<<1|h>>>31;h=h<<1;i=n;o=o-1|0;if((q|0)<(o|0)){continue}break}o=q}q=l-m|0;n=(g|0)==(i|0)&f>>>0>h>>>0|g>>>0>i>>>0;k=(p-((l>>>0>>0)+s|0)|0)-(q>>>0>>0)|0;m=q-n|0;g:{if((k|0)<0){m=l;k=p;break g}l=h;h=h-f|0;i=i-((f>>>0>l>>>0)+g|0)|0;if(h|m|(i|k)){break g}tc(j+48|0,b,c,d,e,0,0,0,0);d=G[j+56>>2];e=G[j+60>>2];h=G[j+48>>2];i=G[j+52>>2];break a}if((k|0)==65535|k>>>0<65535){while(1){b=i>>>31|0;o=o-1|0;p=i<<1|h>>>31;h=h<<1;i=p;c=b;b=m;k=k<<1|b>>>31;m=c|b<<1;if(k>>>0<65536){continue}break}}b=r&32768;if((o|0)<=0){tc(j- -64|0,h,i,m,k&65535|(b|o+120)<<16,0,0,0,1065811968);d=G[j+72>>2];e=G[j+76>>2];h=G[j+64>>2];i=G[j+68>>2];break a}d=m;e=k&65535|(b|o)<<16}G[a>>2]=h;G[a+4>>2]=i;G[a+8>>2]=d;G[a+12>>2]=e;Fa=j+128|0}function sj(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;d=Fa-256|0;Fa=d;E[c+4|0]=0;E[d+240|0]=0;G[c+28>>2]=-1;G[c+20>>2]=-1;G[c+24>>2]=-1;g=c+4|0;a:{if((a|0)>0){m=c+24|0;n=c+20|0;h=c+13|0;k=c+8|0;while(1){b:{c:{d:{e:{e=(l<<4)+b|0;if(H[e+4|0]==45){i=e+5|0;j=0;o=G[47556];if((o|0)<=0){break e}while(1){if(!fb(i,(j<<2)+190240|0,3)){break e}j=j+1|0;if((o|0)!=(j|0)){continue}break}break d}if(Xa(e,35723)){break b}i=1;if(G[c+28>>2]!=-1){break a}G[c+28>>2]=l;break b}if((j|0)!=(o|0)){break c}}if(!fb(i,145328,3)){break c}if(fb(i,145332,3)){break b}}if(!H[g|0]){G[d+224>>2]=i;db(g,8706,d+224|0);if(!fb(e,48516,4)){G[n>>2]=l;E[k+2|0]=H[35969];f=H[35967]|H[35968]<<8;E[k|0]=f;E[k+1|0]=f>>>8;E[h|0]=68;E[h+1|0]=69;E[h+2|0]=67;E[h+3|0]=0;G[d>>2]=g;db(d+240|0,8790,d);f=m;break b}if(!fb(e,48506,4)){G[m>>2]=l;E[k+2|0]=H[35969];f=H[35967]|H[35968]<<8;E[k|0]=f;E[k+1|0]=f>>>8;E[h|0]=68;E[h+1|0]=69;E[h+2|0]=67;E[h+3|0]=0;G[d+16>>2]=g;db(d+240|0,8798,d+16|0);f=n;break b}f=e+1|0;if(!fb(f,34439,3)){G[n>>2]=l;G[d+64>>2]=E[e|0];db(k,34422,d- -64|0);G[d+48>>2]=E[e|0];db(h,33487,d+48|0);G[d+36>>2]=g;G[d+32>>2]=h;db(d+240|0,8784,d+32|0);f=m;break b}if(!fb(f,33504,3)){G[m>>2]=l;G[d+112>>2]=E[e|0];db(k,34422,d+112|0);G[d+96>>2]=E[e|0];db(h,33487,d+96|0);G[d+84>>2]=g;G[d+80>>2]=k;db(d+240|0,8784,d+80|0);f=n;break b}j=e+2|0;if(!fb(j,34540,2)){G[n>>2]=l;j=E[e|0];G[d+164>>2]=E[f|0];G[d+160>>2]=j;db(k,34536,d+160|0);e=E[e|0];G[d+148>>2]=E[f|0];G[d+144>>2]=e;db(h,33344,d+144|0);G[d+132>>2]=g;G[d+128>>2]=h;db(d+240|0,8784,d+128|0);f=m;break b}i=1;if(fb(j,33354,2)){break a}G[m>>2]=l;j=E[e|0];G[d+212>>2]=E[f|0];G[d+208>>2]=j;db(k,34536,d+208|0);e=E[e|0];G[d+196>>2]=E[f|0];G[d+192>>2]=e;db(h,33344,d+192|0);G[d+180>>2]=g;G[d+176>>2]=k;db(d+240|0,8784,d+176|0);f=n;break b}i=1;if(fb(e,d+240|0,8)|!f){break a}G[f>>2]=l;E[d+240|0]=0}l=l+1|0;if((l|0)!=(a|0)){continue}break}i=1;if(H[d+240|0]){break a}}f:{if(fb(g,33759,3)){a=H[g|0]?137:999;break f}E[g|0]=83;E[g+1|0]=70;E[g+2|0]=76;E[g+3|0]=0;a=137}G[c>>2]=a;i=0}j=i;Fa=d+256|0;return j}function Nr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=N(0),g=N(0),h=0,i=0,j=0,k=N(0),l=0,m=N(0),n=0,o=N(0),p=N(0),q=N(0),r=0,s=N(0),t=0,u=0,v=0,w=0,x=N(0),y=N(0),z=N(0),A=N(0);if(G[c+4>>2]!=702){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=67;E[c+1|0]=83;E[c+2|0]=67;E[c+3|0]=0;E[c+4|0]=190;E[c+5|0]=2;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;h=L[c+24>>3];a:{if(h==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;h=45;j=.022222222222222223;break a}h=h*3.141592653589793*.25;j=1/h}G[c+1892>>2]=103;G[c+1888>>2]=104;L[c+112>>3]=h;L[c+120>>3]=j}j=Mb(b);i=Mb(a);a=Kb(a);h=Kb(b);n=-h;b=j*a;r=-b;j=j*i;a=-j;l=h1e-16?N(f*f):N(0);y=+g>1e-16?N(g*g):N(0);z=N((+N(O(N(k*o)))>1e-16?N(g*f):N(0))*N(.15384112298488617));k=N(N(N(q*N(N(g*N(N(-.15959623456001282)-N(q*N(N(g*N(-.021776249632239342))+N(.07591962069272995)))))+N(N(f*N(N(p*N(N(x*N(.10695946961641312))+N(N(y*N(-.1782512068748474))+N(z+N(N(f*N(-.2815285325050354))+N(N(g*N(.08097013086080551))+N(.14118963479995728)))))))+N(N(q*N(-.1316167116165161))+N(g*N(.004869491793215275)))))+N(1.374848484992981))))+g)*k);A=N(O(k));d:{if(A>N(1)){l=2;if(+A>1.0000001000000012){break d}k=kN(1)){l=2;if(+g>1.0000001000000012){break d}f=f>3]=L[c+112>>3]*+N(s+k);L[e>>3]=L[c+112>>3]*+N(m+f);l=0}return l|0}function xl(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;c=Fa+-64|0;Fa=c;G[c+4>>2]=0;d=Kj(G[b+56>>2],0,33281,0,c+56|0,c+4|0);G[b+124>>2]=d;a:{b:{c:{d:{e:{e=G[c+4>>2];if(!e){f:{if(!G[c+56>>2]){Qd(d,c+52|0,c+4|0);g:{h:{i:{d=G[c+52>>2];switch(d-2|0){case 1:break i;case 0:break g;default:break h}}if(G[a+48>>2]){break g}G[a+48>>2]=16840;G[a+12>>2]=1;G[a+16>>2]=1;break g}G[c>>2]=d;Tb(G[24367],88360,c)}Jj(G[b+124>>2],b+60|0,c+60|0,c+4|0);d=G[c+4>>2];if(d){break e}if(G[a+16>>2]){d=0;j:{k:{switch(G[b>>2]){case 1:if(!G[b+28>>2]){break j}break;case 0:break k;default:break j}}d=G[a+48>>2]}i=b,j=ei(G[b+124>>2],0,0,1,0,d,0,c+32|0,c+16|0,b+24|0,c+4|0),G[i+68>>2]=j;d=G[c+4>>2];if(d){break b}e=(G[c+20>>2]-G[c+36>>2]|0)+1|0;d=(G[c+16>>2]-G[c+32>>2]|0)+1|0}G[b+32>>2]=e;G[b+20>>2]=d;if(!G[a+12>>2]){break f}l:{switch(G[b>>2]){case 1:if(!G[b+28>>2]){break f}break;case 0:break l;default:break f}}G[b+36>>2]=0;f=G[c+40>>2];g=G[c+24>>2];G[b+64>>2]=G[b+68>>2];G[b+40>>2]=(g-f|0)+1;g=G[b+24>>2];f=g>>31;G[b+44>>2]=(M((f^g)-f|0,M(d,e))|0)/8;break f}d=Ij(d,0,0,0,0,L[a+56>>3],0,c+4|0);e=G[c+4>>2];if(e){break d}Jj(d,b+60|0,c+60|0,c+4|0);e=G[c+4>>2];if(e){break d}if(G[a+16>>2]){i=b,j=ei(d,0,0,1,0,0,0,c+32|0,c+16|0,b+24|0,c+4|0),G[i+68>>2]=j;e=G[c+4>>2];if(e){break d}G[b+20>>2]=(G[c+16>>2]-G[c+32>>2]|0)+1;G[b+32>>2]=(G[c+20>>2]-G[c+36>>2]|0)+1;_e(d,c+4|0);break f}_e(G[b+124>>2],c+4|0);e=G[c+4>>2];if(e){break d}G[b+124>>2]=d}bi(G[b+60>>2],256e3);d=rd(G[b+60>>2]);G[b+120>>2]=d;m:{if(G[a+16>>2]){G[b+4>>2]=1;G[b+12>>2]=1;G[b+72>>2]=1;G[b+8>>2]=G[b+20>>2];G[b+16>>2]=G[b+32>>2];break m}de(G[b+124>>2],2,c+8|0,c+4|0);d=G[c+4>>2];if(d){break b}G[b+4>>2]=1;a=G[c+8>>2];G[b+12>>2]=1;G[b+8>>2]=a;a=G[c+12>>2];G[b+72>>2]=1;G[b+16>>2]=a;d=G[b+120>>2]}if(!(!d|!(d?G[d+3312>>2]:0))){a=G[b+120>>2];h=L[(G[a+3304>>2]?768:760)+a>>3];L[b+96>>3]=(h<0?-h:h)*+G[b+72>>2]}Fa=c- -64|0;return}a=G[(a?a+68|0:97468)>>2];wf(a,e);break c}a=G[(a?a+68|0:97468)>>2];wf(a,d);break a}a=G[a+68>>2];wf(a,e)}$a(a);Gh();sc(e);W()}a=G[a+68>>2];wf(a,d)}$a(a);Gh();sc(d);W()}function Ss(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;h=G[309722];l=G[a+16>>2];r=h+M(l,344)|0;n=G[a+12>>2];o=M(n,344)+h|0;a:{if(G[o>>2]!=-1e3){p=G[o+56>>2];e=0;break a}e=H[o+88|0]}b:{if(G[r>>2]!=-1e3){q=G[(M(l,344)+h|0)+56>>2];f=0;break b}f=H[(M(l,344)+h|0)+88|0]}b=G[a>>2];c:{if(!(p|q)){d:{e:{switch(b-276|0){case 0:E[a+88|0]=(e|f)!=0;break d;case 1:E[a+88|0]=(e|0)!=0&(f|0)!=0;break d;case 2:f:{if(e){b=1;if(f){break f}}b=!(e|f)}E[a+88|0]=b;break d;case 3:b=!e;d=(f|0)!=0;E[a+88|0]=!(b|d)|b&d;break d;case 14:break e;default:break d}}G[a+88>>2]=e<<24>>24}G[a>>2]=-1e3;break c}g=G[a+56>>2];m=G[309727];Nd(a);i=M(g,m);d=G[309737];if((b|0)==290){if(d){break c}d=M(l,344)+h|0;c=G[d+88>>2];if((i|0)>0){b=M(n,344)+h|0;g=0;while(1){c=H[G[b+84>>2]+g|0]?c:E[G[b+88>>2]+g|0]+c|0;G[G[a+88>>2]+(g<<2)>>2]=c;E[G[a+84>>2]+g|0]=0;g=g+1|0;if((i|0)!=(g|0)){continue}break}}G[d+88>>2]=c;break c}if(d){break c}if(G[a>>2]==290){d=M(l,344)+h|0;k=G[d+88>>2];if((i|0)>0){b=M(n,344)+h|0;while(1){k=H[G[b+84>>2]+c|0]?k:E[G[b+88>>2]+c|0]+k|0;G[G[a+88>>2]+(c<<2)>>2]=k;E[G[a+84>>2]+c|0]=0;c=c+1|0;if((i|0)!=(c|0)){continue}break}}G[d+88>>2]=k}if(!m){break c}d=a+88|0;s=a+84|0;t=M(l,344)+h|0;u=M(n,344)+h|0;v=(p|0)>1;c=0;k=0;while(1){m=m-1|0;if(g){while(1){i=i-1|0;if(p){b=v?i:m;k=H[b+G[u+84>>2]|0];e=H[b+G[u+88>>2]|0]}if(q){b=(q|0)>1?i:m;c=H[b+G[t+84>>2]|0];f=H[b+G[t+88>>2]|0]}g=g-1|0;j=((c|k)&255)!=0;E[G[a+84>>2]+i|0]=j;g:{h:{i:{j:{switch(G[a>>2]-276|0){case 0:b=(e|f)!=0;if(!j){break i}b=k&255;if(f?!b|c&255:1){if(!e|(!(c&255)|b)){break g}}E[G[d>>2]+i|0]=1;j=0;b=s;break h;case 1:b=(e|0)!=0&(f|0)!=0;if(!j){break i}b=k&255;if(f?1:!b|c&255){if(e|(!(c&255)|b)){break g}}j=0;E[G[d>>2]+i|0]=0;b=s;break h;case 2:if(e){j=1;b=d;if(f){break h}}b=!(e|f);break i;case 3:break j;default:break g}}b=!e;j=(f|0)!=0;b=!(b|j)|b&j}j=b;b=d}E[G[b>>2]+i|0]=j}if(g){continue}break}}g=G[a+56>>2];if(m){continue}break}}if(G[o>>2]>0){Wa(G[(M(n,344)+h|0)+88>>2])}if(G[r>>2]>0){Wa(G[(M(l,344)+h|0)+88>>2])}}function aq(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0;l=c==1&d==0;a:{b:{if(!e){if(l){break b}l=0;if((b|0)<=0){break a}while(1){f=(l<<2)+j|0;c:{d:{n=+F[(l<<1)+a>>1]*c+d;if(n<-0x7ffffffffffffc00){G[k>>2]=-11;break d}if(n>0x7ffffffffffffc00){G[k>>2]=-11;e=2147483647;break c}if(!(O(n)<2147483648)){break d}e=~~n;break c}e=-2147483648}G[f>>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if(!l){if((b|0)<=0){break a}l=0;m=f&65535;while(1){f=I[(l<<1)+a>>1];e:{if((f|0)==(m|0)){G[i>>2]=1;if((e|0)==1){G[(l<<2)+j>>2]=g;break e}E[h+l|0]=1;break e}n=+(f<<16>>16)*c+d;if(n<-0x7ffffffffffffc00){G[k>>2]=-11;G[(l<<2)+j>>2]=-2147483648;break e}if(n>0x7ffffffffffffc00){G[k>>2]=-11;G[(l<<2)+j>>2]=2147483647;break e}o=(l<<2)+j|0;if(O(n)<2147483648){f=~~n}else{f=-2147483648}G[o>>2]=f}l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)!=1){l=0;if((b|0)!=1){k=b&-2;e=f&65535;while(1){g=I[(l<<1)+a>>1];f:{if((g|0)==(e|0)){G[i>>2]=1;E[h+l|0]=1;break f}G[(l<<2)+j>>2]=g<<16>>16}g=l|1;o=I[(g<<1)+a>>1];g:{if((o|0)!=(e|0)){G[(g<<2)+j>>2]=o<<16>>16;break g}G[i>>2]=1;E[g+h|0]=1}l=l+2|0;m=m+2|0;if((k|0)!=(m|0)){continue}break}}if(!(b&1)){break a}a=I[(l<<1)+a>>1];if((a|0)!=(f&65535)){G[(l<<2)+j>>2]=a<<16>>16;return}G[i>>2]=1;E[h+l|0]=1;break a}l=0;if((b|0)!=1){k=b&-2;h=f&65535;while(1){o=(l<<2)+j|0;e=I[(l<<1)+a>>1];h:{if((e|0)!=(h|0)){e=e<<16>>16;break h}G[i>>2]=1;e=g}G[o>>2]=e;o=l|1;e=I[(o<<1)+a>>1];i:{if((e|0)!=(h|0)){e=e<<16>>16;break i}G[i>>2]=1;e=g}G[(o<<2)+j>>2]=e;l=l+2|0;m=m+2|0;if((k|0)!=(m|0)){continue}break}}if(!(b&1)){break a}a=I[(l<<1)+a>>1];j:{if((a|0)!=(f&65535)){g=a<<16>>16;break j}G[i>>2]=1}G[(l<<2)+j>>2]=g;return}if((b|0)<=0){break a}e=b&3;l=0;if(b-1>>>0>=3){f=b&-4;b=0;while(1){G[(l<<2)+j>>2]=F[(l<<1)+a>>1];g=l|1;G[(g<<2)+j>>2]=F[(g<<1)+a>>1];g=l|2;G[(g<<2)+j>>2]=F[(g<<1)+a>>1];g=l|3;G[(g<<2)+j>>2]=F[(g<<1)+a>>1];l=l+4|0;b=b+4|0;if((f|0)!=(b|0)){continue}break}}if(!e){break a}while(1){G[(l<<2)+j>>2]=F[(l<<1)+a>>1];l=l+1|0;m=m+1|0;if((e|0)!=(m|0)){continue}break}}}function $o(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;j=f;f=f&31;if((j&63)>>>0>=32){g=8<>>32-f;p=8<>>0>=32){g=4<>>32-f;f=4<>>0>=32){g=2<>>32-f;s=2<=2){y=c-1|0;f=j&31;if((j&63)>>>0>=32){g=1<>>32-f}z=m;m=g;A=(d-2>>>1|0)+1|0;B=(d&-2)<(d|0);while(1){i=h+A|0;f=M(b,n);l=f+b|0;while(1){o=h;C=e+h|0;x=f<<3;g=(x|8)+a|0;k=G[g+4>>2];h=G[g>>2];g=k<<2|h>>>30;h=v&h<<2;t=g&w;u=h;h=(l<<3)+a|0;g=h;k=G[g>>2];g=G[g+4>>2]<<1|k>>>31;k=u|(s&k<<1|z&G[h+8>>2]);t=g&r|m&G[h+12>>2]|t;u=k;g=a+x|0;k=G[g+4>>2];h=G[g>>2];g=k<<3|h>>>29;k=u|p&h<<3;h=g&q|t;g=j&31;E[C|0]=(j&63)>>>0>=32?h>>g:((1<>>g;l=l+2|0;f=f+2|0;h=o+1|0;if((i|0)!=(h|0)){continue}break}b:{if(B){h=e+i|0;f=(f<<3)+a|0;g=G[f+4>>2];f=G[f>>2];g=g<<3|f>>>29;f=p&f<<3;i=g&q;k=h;h=f;f=(l<<3)+a|0;g=G[f+4>>2];f=G[f>>2];g=g<<1|f>>>31;h=h|s&f<<1;g=g&r|i;f=j&31;E[k|0]=(j&63)>>>0>=32?g>>f:((1<>>f;h=o+2|0;break b}h=i}n=n+2|0;if((y|0)>(n|0)){continue}break}break a}if((d|0)!=1){n=c&-2;break a}o=c-2>>>1|0;h=o+1|0;f=0;while(1){l=M(b,n);g=(l<<3)+a|0;k=G[g+4>>2];i=G[g>>2];g=k<<3|i>>>29;i=p&i<<3;k=g&q;m=i;g=(b+l<<3)+a|0;l=G[g+4>>2];i=G[g>>2];g=l<<1|i>>>31;m=m|s&i<<1;i=g&r|k;g=j&31;E[e+f|0]=(j&63)>>>0>=32?i>>g:((1<>>g;n=n+2|0;g=(f|0)!=(o|0);f=f+1|0;if(g){continue}break}}c:{if((c|0)<=(n|0)){break c}f=M(b,n);l=0;if((d|0)>=2){r=d-1|0;while(1){i=f<<3;b=i+a|0;g=G[b+4>>2];b=G[b>>2];g=g<<3|b>>>29;b=p&b<<3;o=g&q;c=b;b=(i|8)+a|0;g=G[b+4>>2];b=G[b>>2];g=g<<2|b>>>30;b=c|v&b<<2;c=g&w|o;g=b;b=j&31;E[e+h|0]=(j&63)>>>0>=32?c>>b:((1<>>b;f=f+2|0;h=h+1|0;l=l+2|0;if((r|0)>(l|0)){continue}break}b=d&-2}else{b=0}if((b|0)>=(d|0)){break c}a=(f<<3)+a|0;c=G[a+4>>2];a=G[a>>2];g=c<<3|a>>>29;c=p&a<<3;b=g&q;a=j&31;E[e+h|0]=(j&63)>>>0>=32?b>>a:((1<>>a}}function fl(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=N(0),o=0,p=0;m=c==1&d==0;a:{if(!e){if(!m){if((b|0)<=0){break a}f=0;if((b|0)!=1){h=b&-2;i=0;while(1){e=f<<2;K[e+j>>2]=+G[a+e>>2]*c+d;e=e|4;K[e+j>>2]=+G[a+e>>2]*c+d;f=f+2|0;i=i+2|0;if((h|0)!=(i|0)){continue}break}}if(!(b&1)){break a}b=f<<2;K[b+j>>2]=+G[a+b>>2]*c+d;break a}if((b|0)<=0){break a}h=b&3;i=0;f=0;if(b-1>>>0>=3){m=b&-4;b=0;while(1){e=f<<2;K[e+j>>2]=G[a+e>>2];k=e|4;K[k+j>>2]=G[a+k>>2];k=e|8;K[k+j>>2]=G[a+k>>2];e=e|12;K[e+j>>2]=G[a+e>>2];f=f+4|0;b=b+4|0;if((m|0)!=(b|0)){continue}break}}if(!h){break a}while(1){b=f<<2;K[b+j>>2]=G[a+b>>2];f=f+1|0;i=i+1|0;if((h|0)!=(i|0)){continue}break}break a}b:{if(!m){if((b|0)<=0){break a}if((e|0)==1){break b}e=0;while(1){m=e<<2;k=G[m+a>>2];c:{if((k|0)==(f|0)){G[i>>2]=1;E[e+h|0]=1;break c}K[j+m>>2]=+(k|0)*c+d}e=e+1|0;if((e|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)!=1){m=b&1;e=0;if((b|0)!=1){k=b&-2;b=0;while(1){l=e<<2;o=G[l+a>>2];d:{if((o|0)==(f|0)){G[i>>2]=1;E[e+h|0]=1;break d}K[j+l>>2]=o|0}l=e|1;o=l<<2;p=G[o+a>>2];e:{if((p|0)!=(f|0)){K[j+o>>2]=p|0;break e}G[i>>2]=1;E[h+l|0]=1}e=e+2|0;b=b+2|0;if((k|0)!=(b|0)){continue}break}}if(!m){break a}b=e<<2;a=G[a+b>>2];if((a|0)!=(f|0)){K[b+j>>2]=a|0;break a}G[i>>2]=1;E[e+h|0]=1;break a}h=b&1;e=0;if((b|0)!=1){m=b&-2;b=0;while(1){k=e<<2;l=G[k+a>>2];f:{if((l|0)!=(f|0)){n=N(l|0);break f}G[i>>2]=1;n=g}K[j+k>>2]=n;k=(e|1)<<2;l=G[k+a>>2];g:{if((l|0)!=(f|0)){n=N(l|0);break g}G[i>>2]=1;n=g}K[j+k>>2]=n;e=e+2|0;b=b+2|0;if((m|0)!=(b|0)){continue}break}}if(!h){break a}a=G[(e<<2)+a>>2];h:{if((a|0)!=(f|0)){g=N(a|0);break h}G[i>>2]=1}K[(e<<2)+j>>2]=g;break a}h=b&1;e=0;if((b|0)!=1){m=b&-2;b=0;while(1){k=e<<2;l=G[k+a>>2];i:{if((l|0)!=(f|0)){n=N(+(l|0)*c+d);break i}G[i>>2]=1;n=g}K[j+k>>2]=n;k=(e|1)<<2;l=G[k+a>>2];j:{if((l|0)!=(f|0)){n=N(+(l|0)*c+d);break j}G[i>>2]=1;n=g}K[j+k>>2]=n;e=e+2|0;b=b+2|0;if((m|0)!=(b|0)){continue}break}}if(!h){break a}a=G[(e<<2)+a>>2];k:{if((a|0)!=(f|0)){g=N(+(a|0)*c+d);break k}G[i>>2]=1}K[(e<<2)+j>>2]=g}}function iq(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=N(0),o=0;k=c==1&d==0;a:{if(!e){if(!k){if((b|0)<=0){break a}f=0;if((b|0)!=1){h=b&-2;e=0;while(1){K[(f<<2)+j>>2]=+H[a+f|0]*c+d;i=f|1;K[(i<<2)+j>>2]=+H[a+i|0]*c+d;f=f+2|0;e=e+2|0;if((h|0)!=(e|0)){continue}break}}if(!(b&1)){break a}K[(f<<2)+j>>2]=+H[a+f|0]*c+d;break a}if((b|0)<=0){break a}e=0;f=0;if(b-1>>>0>=3){h=b&-4;i=0;while(1){K[(f<<2)+j>>2]=H[a+f|0];k=f|1;K[(k<<2)+j>>2]=H[a+k|0];k=f|2;K[(k<<2)+j>>2]=H[a+k|0];k=f|3;K[(k<<2)+j>>2]=H[a+k|0];f=f+4|0;i=i+4|0;if((h|0)!=(i|0)){continue}break}}b=b&3;if(!b){break a}while(1){K[(f<<2)+j>>2]=H[a+f|0];f=f+1|0;e=e+1|0;if((b|0)!=(e|0)){continue}break}break a}b:{if(!k){if((b|0)<=0){break a}if((e|0)==1){break b}e=0;while(1){k=H[a+e|0];c:{if((k|0)==(f|0)){G[i>>2]=1;E[e+h|0]=1;break c}K[(e<<2)+j>>2]=+(k>>>0)*c+d}e=e+1|0;if((e|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)!=1){l=b&1;e=0;if((b|0)!=1){m=b&-2;b=0;while(1){k=H[a+e|0];d:{if((k|0)==(f|0)){G[i>>2]=1;E[e+h|0]=1;break d}K[(e<<2)+j>>2]=k>>>0}k=e|1;o=H[k+a|0];e:{if((o|0)!=(f|0)){K[(k<<2)+j>>2]=o>>>0;break e}G[i>>2]=1;E[h+k|0]=1}e=e+2|0;b=b+2|0;if((m|0)!=(b|0)){continue}break}}if(!l){break a}a=H[a+e|0];if((a|0)!=(f|0)){K[(e<<2)+j>>2]=a>>>0;break a}G[i>>2]=1;E[e+h|0]=1;break a}h=b&1;e=0;if((b|0)!=1){k=b&-2;b=0;while(1){m=(e<<2)+j|0;l=H[a+e|0];f:{if((l|0)!=(f|0)){n=N(l>>>0);break f}G[i>>2]=1;n=g}K[m>>2]=n;l=e|1;m=H[l+a|0];g:{if((m|0)!=(f|0)){n=N(m>>>0);break g}G[i>>2]=1;n=g}K[(l<<2)+j>>2]=n;e=e+2|0;b=b+2|0;if((k|0)!=(b|0)){continue}break}}if(!h){break a}a=H[a+e|0];h:{if((a|0)!=(f|0)){g=N(a>>>0);break h}G[i>>2]=1}K[(e<<2)+j>>2]=g;break a}h=b&1;e=0;if((b|0)!=1){k=b&-2;b=0;while(1){m=(e<<2)+j|0;l=H[a+e|0];i:{if((l|0)!=(f|0)){n=N(+(l>>>0)*c+d);break i}G[i>>2]=1;n=g}K[m>>2]=n;l=e|1;m=H[l+a|0];j:{if((m|0)!=(f|0)){n=N(+(m>>>0)*c+d);break j}G[i>>2]=1;n=g}K[(l<<2)+j>>2]=n;e=e+2|0;b=b+2|0;if((k|0)!=(b|0)){continue}break}}if(!h){break a}a=H[a+e|0];k:{if((a|0)!=(f|0)){g=N(+(a>>>0)*c+d);break k}G[i>>2]=1}K[(e<<2)+j>>2]=g}}function eq(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0;k=c==1&d==0;a:{if(!e){if(!k){if((b|0)<=0){break a}f=0;if((b|0)!=1){h=b&-2;e=0;while(1){L[(f<<3)+j>>3]=+H[a+f|0]*c+d;i=f|1;L[(i<<3)+j>>3]=+H[a+i|0]*c+d;f=f+2|0;e=e+2|0;if((h|0)!=(e|0)){continue}break}}if(!(b&1)){break a}L[(f<<3)+j>>3]=+H[a+f|0]*c+d;break a}if((b|0)<=0){break a}e=0;f=0;if(b-1>>>0>=3){h=b&-4;i=0;while(1){L[(f<<3)+j>>3]=H[a+f|0];k=f|1;L[(k<<3)+j>>3]=H[a+k|0];k=f|2;L[(k<<3)+j>>3]=H[a+k|0];k=f|3;L[(k<<3)+j>>3]=H[a+k|0];f=f+4|0;i=i+4|0;if((h|0)!=(i|0)){continue}break}}b=b&3;if(!b){break a}while(1){L[(f<<3)+j>>3]=H[a+f|0];f=f+1|0;e=e+1|0;if((b|0)!=(e|0)){continue}break}break a}b:{if(!k){if((b|0)<=0){break a}if((e|0)==1){break b}e=0;while(1){k=H[a+e|0];c:{if((k|0)==(f|0)){G[i>>2]=1;E[e+h|0]=1;break c}L[(e<<3)+j>>3]=+(k>>>0)*c+d}e=e+1|0;if((e|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)!=1){l=b&1;e=0;if((b|0)!=1){m=b&-2;b=0;while(1){k=H[a+e|0];d:{if((k|0)==(f|0)){G[i>>2]=1;E[e+h|0]=1;break d}L[(e<<3)+j>>3]=k>>>0}k=e|1;o=H[k+a|0];e:{if((o|0)!=(f|0)){L[(k<<3)+j>>3]=o>>>0;break e}G[i>>2]=1;E[h+k|0]=1}e=e+2|0;b=b+2|0;if((m|0)!=(b|0)){continue}break}}if(!l){break a}a=H[a+e|0];if((a|0)!=(f|0)){L[(e<<3)+j>>3]=a>>>0;break a}G[i>>2]=1;E[e+h|0]=1;break a}h=b&1;e=0;if((b|0)!=1){k=b&-2;b=0;while(1){m=(e<<3)+j|0;l=H[a+e|0];f:{if((l|0)!=(f|0)){c=+(l>>>0);break f}G[i>>2]=1;c=g}L[m>>3]=c;l=e|1;m=H[l+a|0];g:{if((m|0)!=(f|0)){c=+(m>>>0);break g}G[i>>2]=1;c=g}L[(l<<3)+j>>3]=c;e=e+2|0;b=b+2|0;if((k|0)!=(b|0)){continue}break}}if(!h){break a}a=H[a+e|0];h:{if((a|0)!=(f|0)){g=+(a>>>0);break h}G[i>>2]=1}L[(e<<3)+j>>3]=g;break a}h=b&1;e=0;if((b|0)!=1){k=b&-2;b=0;while(1){m=(e<<3)+j|0;l=H[a+e|0];i:{if((l|0)!=(f|0)){n=+(l>>>0)*c+d;break i}G[i>>2]=1;n=g}L[m>>3]=n;l=e|1;m=H[l+a|0];j:{if((m|0)!=(f|0)){n=+(m>>>0)*c+d;break j}G[i>>2]=1;n=g}L[(l<<3)+j>>3]=n;e=e+2|0;b=b+2|0;if((k|0)!=(b|0)){continue}break}}if(!h){break a}a=H[a+e|0];k:{if((a|0)!=(f|0)){g=+(a>>>0)*c+d;break k}G[i>>2]=1}L[(e<<3)+j>>3]=g}}function he(a,b,c,d){var e=0,f=0,g=0,h=0,i=0;i=Fa-6528|0;Fa=i;G[c>>2]=0;G[c+4>>2]=0;G[d>>2]=0;G[d+4>>2]=0;g=-1;a:{if(G[325170]!=1){break a}if(G[325168]>0){g=i+3264|0;bb(g,1294144,3264);jm(a,b,g,c,d);b=L[d>>3];a=L[c>>3]}b:{if(G[325171]){e=a-L[161752];b=b-L[161753];a=L[162588]*e+b*L[162589];b=L[162586]*e+L[162587]*b;break b}e=L[161756];b=L[161763]*(b-L[161753]);f=L[161762]*(a-L[161752]);h=L[161757];a=e*b-f*h;b=f*e+h*b}b=b*.0174532925199433;c:{if(!Xa(1294008,34606)){break c}if(!Xa(1294008,34543)){g=2;e=b*b+a*a*.0174532925199433*.0174532925199433;if(e>1){break a}e=e<1?V(1-e):0;a=a/e;b=b/e;break c}if(!Xa(1294008,35981)){g=2;e=(b*b+a*a*.0174532925199433*.0174532925199433)*.25;if(e>.5){break a}e=V(1-e)*.5/(1-(e+e));a=a*e;b=b*e;break c}if(!Xa(1294008,35072)){g=2;e=(b*b+a*a*.0174532925199433*.0174532925199433)*.25;if(e>=1){break a}e=1-e;a=a*e;b=b*e;break c}if(!Xa(1294008,35873)){g=2;e=a*a+b*b/.00030461741978670873;if(e<=0){break a}f=a;a=V(e);e=Mc(a)/a;a=f*e;b=b*e;break c}g=2;if(L[161760]-b*L[161761]<=0){break a}}f=L[161760];h=L[161761];e=f-b*h;b=(b*f+h)/e/.0174532925199433;a=a/e;d:{if(!Xa(1294012,34606)){break d}if(!Xa(1294012,34543)){e=1/V((b*b+a*a)*.0174532925199433*.0174532925199433+1);a=a*e;b=b*e;break d}if(!Xa(1294012,35981)){e=(b*b+a*a)*.0174532925199433*.0174532925199433;if(!(e>1e-23)){break d}f=a;a=1-1/V(e+1);e=V(a+a)/V(e);a=f*e;b=b*e;break d}if(!Xa(1294012,35072)){e=1/(V((b*b+a*a)*.0174532925199433*.0174532925199433+1)+1);a=a*e;b=b*e;break d}if(Xa(1294012,35873)){break d}g=2;e=(b*b+a*a)*.0174532925199433*.0174532925199433;if(e<=0){break a}f=a;a=V(e);e=Pd(a)/a;a=f*e;b=b*e}e:{if(G[325188]){e=L[162601]*b+a*L[162602];a=L[162599]*b+a*L[162600];break e}f=L[161759];h=L[161758];e=(b*f+a*h)/L[161765];a=(b*h-f*a)/L[161764]}b=e+L[161755];a=a+L[161754];f:{if(G[325169]>0){im(a,b,bb(i,1297408,3264),c,d);break f}L[c>>3]=a;L[d>>3]=b}g=1;a=L[c>>3];if(a<.5|a>+G[323533]+.5){break a}a=L[d>>3];if(a<.5|a>+G[323535]+.5){break a}g=0}Fa=i+6528|0;return g}function co(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;m=Fa-16|0;Fa=m;a:{if(G[f>>2]>0){break a}j=G[a>>2];h=G[a+4>>2];b:{c:{if((j|0)!=G[h+76>>2]){mb(a,j+1|0,0,f);break c}if((G[h+128>>2]&G[h+132>>2])!=-1){break c}if((Rb(a,f)|0)>0){break b}}d:{if((b|0)>0){h=G[a+4>>2];if(G[h+936>>2]>=(b|0)){break d}}G[f>>2]=302;break a}if(G[f>>2]>0){break a}b=b-1|0;j=G[h+968>>2];e:{f:{g:{n=G[a>>2];if(!(G[h+104>>2]|G[h+108>>2]?1:n)){break g}h:{i:{if(G[h+76>>2]!=(n|0)){mb(a,n+1|0,0,f);break i}if((G[h+128>>2]&G[h+132>>2])!=-1){break i}if((Rb(a,f)|0)>0){break h}}a=G[a+4>>2];h=G[a+1088>>2]?0:G[a+80>>2]}if(G[f>>2]>0){break a}if((h|0)!=1){break g}Gd((j+M(b,160)|0)+140|0,c,m+8|0,m+12|0,f);if(e){a=G[m+8>>2];G[e>>2]=a;G[e+4>>2]=a>>31}a=1;e=0;if(d){break f}break e}if(c){G[c>>2]=G[(j+M(b,160)|0)+80>>2]}if(e){a=G[(j+M(b,160)|0)+152>>2];G[e>>2]=a;G[e+4>>2]=a>>31}if(!d){break e}e=j+M(b,160)|0;a=G[e+88>>2];e=G[e+92>>2]}G[d>>2]=a;G[d+4>>2]=e}if(!c){break b}a=j+M(b,160)|0;g=L[a+104>>3];k=L[a+96>>3];if(k==1&g==0){break b}i=255;b=G[c>>2];a=b>>31;j:{k:{l:{m:{a=(a^b)-a|0;switch(a-11|0){case 0:break j;case 10:break l;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:break b;default:break m}}if((a|0)==41){break k}if((a|0)!=81){break b}i=0x8000000000000000;l=-0x8000000000000000;break j}i=32767;l=-32768;break j}i=2147483647;l=-2147483648}n:{o:{if(g==2147483648|g==0x8000000000000000){break o}e=g<2147483648;if(O(g)<2147483648){d=~~g}else{d=-2147483648}e=(e?+(d|0):0)==g;if(O(k)<2147483648){d=~~k}else{d=-2147483648}if(e&+(d|0)==k){break o}a=(a|0)==21?42:(a|0)==11?42:82;break n}l=k*l+g;a=k>=0;i=a?k*i+g:l;g=a?l:k*l+g;if(g==-128){a=12;if(i==127){break n}}if(g>=-32768){a=21;if(i<=32767){break n}}if(g>=0){a=20;if(i<=65535){break n}}if(g>=-2147483648){a=41;if(i<=2147483647){break n}}if(g>=0){a=40;if(i<4294967296){break n}}if(g>=-0x8000000000000000){a=81;if(i<=0x8000000000000000){break n}}a=g>=0?i<=0x10000000000000000?80:82:82}G[c>>2]=(b|0)<0?0-a|0:a}}Fa=m+16|0}function Pc(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;d=G[321300];d=d?d:256e3;a:{if((d|0)<=0){break a}b:{while(1){if(E[a+c|0]<=0){break b}c=c+1|0;if((d|0)!=(c|0)){continue}break}c=d}c:{if((c|0)<=0){break c}n=a+c|0;h=a;while(1){i=n-h|0;d=0;j=0;c=h;d:{e:{if(!c|!b){break e}e=Va(b);if(!e){break d}if(!i){break e}f:{if((e|0)<=2){d=H[b|0];g:{if((d-97&255)>>>0<=25){f=d-32|0;break g}f=(d-65&255)>>>0<26?d+32|0:d}g=32;if((e|0)<2){k=32;break f}g=H[b+1|0];if((g-97&255)>>>0<=25){k=g-32|0;break f}k=(g-65&255)>>>0<26?g+32|0:g;break f}j=lb(e,1);while(1){g=d+j|0;f=H[b+d|0];h:{if((f-97&255)>>>0<=25){f=f-32|0;break h}f=(f-65&255)>>>0<26?f+32|0:f}E[g|0]=f;d=d+1|0;if((e|0)!=(d|0)){continue}break}d=e-1|0;k=H[d+j|0];g=H[b+d|0];d=H[b|0];f=H[j|0]}i:{j:{i=(c+i|0)-e|0;k:{if(i+1>>>0<=c>>>0){break k}l:{m:{n:{m=e-1|0;switch(m|0){case 1:break m;case 0:break n;default:break l}}while(1){e=H[c|0];if((e|0)==(d&255)|(e|0)==(f&255)){break j}e=c>>>0>>0;c=c+1|0;if(e){continue}break}break k}while(1){e=H[c|0];if(!((e|0)!=(d&255)&(e|0)!=(f&255))){e=H[c+m|0];if((e|0)==(g|0)|(e|0)==(k&255)){break j}}e=c>>>0>>0;c=c+1|0;if(e){continue}break}break k}if((e|0)>=2){o=d&255;while(1){d=c;o:{c=H[c|0];if((c|0)!=(o|0)&(c|0)!=(f&255)){break o}c=1;l=H[d+m|0];if((l|0)!=(g|0)&(l|0)!=(k&255)){break o}while(1){l=H[c+d|0];if((l|0)!=H[b+c|0]&(l|0)!=H[c+j|0]){break o}c=c+1|0;if((e|0)!=(c|0)){continue}break}break i}c=d+1|0;if(d>>>0>>0){continue}break}break k}d=d&255;while(1){e=H[c|0];if(!((e|0)!=(d|0)&(e|0)!=(f&255))){e=H[c+m|0];if((e|0)==(g|0)|(e|0)==(k&255)){break j}}e=c>>>0>>0;c=c+1|0;if(e){continue}break}}d=0;break i}d=c}if(!j){break e}Wa(j)}c=d}f=c;if(!c){break c}d=(f-a|0)%80|0;p:{if((d|0)>=8){h=f+1|0;break p}c=H[Va(b)+f|0];if(!((c|0)==61|(c-33&255)>>>0>93)){h=f+1|0;break p}c=f-d|0;if((d|0)>0){e=f+1|0;d=c;while(1){h=H[d|0]==32?h:e;d=d+1|0;if(f>>>0>d>>>0){continue}break}}if(f>>>0>=h>>>0){break a}}if(h>>>0>>0){continue}break}}c=0}return c}function $k(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0;a:{b:{if(!e){if(c==1&d==0){break b}if((b|0)<=0){break a}while(1){f=(l<<2)+i|0;c:{d:{m=L[(l<<3)+a>>3]*c+d;if(m<-0x7ffffffffffffc00){G[j>>2]=-11;break d}if(m>0x7ffffffffffffc00){G[j>>2]=-11;e=2147483647;break c}if(!(O(m)<2147483648)){break d}e=~~m;break c}e=-2147483648}G[f>>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}l=a+6|0;e:{f:{if(!(c==1&d==0)){if((b|0)<=0){break a}if(!(O(d)<2147483648)){break f}n=~~d;break e}if((b|0)<=0){break a}while(1){g:{h:{i:{j:{n=I[l>>1]&32752;switch(((n|0)==32752?1:!n<<1)|0){case 0:break h;case 1:break j;default:break i}}G[h>>2]=1;if((e|0)==1){G[(k<<2)+i>>2]=f;break g}E[g+k|0]=1;break g}G[(k<<2)+i>>2]=0;break g}c=L[(k<<3)+a>>3];if(c<-0x7ffffffffffffc00){G[j>>2]=-11;G[(k<<2)+i>>2]=-2147483648;break g}if(c>0x7ffffffffffffc00){G[j>>2]=-11;G[(k<<2)+i>>2]=2147483647;break g}o=(k<<2)+i|0;if(O(c)<2147483648){n=~~c}else{n=-2147483648}G[o>>2]=n}l=l+8|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}n=-2147483648}while(1){k:{l:{m:{n:{o=I[l>>1]&32752;switch(((o|0)==32752?1:!o<<1)|0){case 0:break l;case 1:break n;default:break m}}G[h>>2]=1;if((e|0)==1){G[(k<<2)+i>>2]=f;break k}E[g+k|0]=1;break k}if(d<-0x7ffffffffffffc00){G[j>>2]=-11;G[(k<<2)+i>>2]=-2147483648;break k}if(d>0x7ffffffffffffc00){G[j>>2]=-11;G[(k<<2)+i>>2]=2147483647;break k}G[(k<<2)+i>>2]=n;break k}m=L[(k<<3)+a>>3]*c+d;if(m<-0x7ffffffffffffc00){G[j>>2]=-11;G[(k<<2)+i>>2]=-2147483648;break k}if(m>0x7ffffffffffffc00){G[j>>2]=-11;G[(k<<2)+i>>2]=2147483647;break k}p=(k<<2)+i|0;if(O(m)<2147483648){o=~~m}else{o=-2147483648}G[p>>2]=o}l=l+8|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}while(1){f=(l<<2)+i|0;o:{p:{c=L[(l<<3)+a>>3];if(c<-0x7ffffffffffffc00){G[j>>2]=-11;break p}if(c>0x7ffffffffffffc00){G[j>>2]=-11;e=2147483647;break o}if(!(O(c)<2147483648)){break p}e=~~c;break o}e=-2147483648}G[f>>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}}}function al(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=N(0),q=0;a:{b:{if(!e){if(c==1&d==0){break b}if((b|0)<=0){break a}while(1){c:{d:{f=l<<2;o=+K[f+a>>2]*c+d;if(o<-0x7ffffffffffffc00){G[j>>2]=-11;break d}if(o>0x7ffffffffffffc00){G[j>>2]=-11;e=2147483647;break c}if(!(O(o)<2147483648)){break d}e=~~o;break c}e=-2147483648}G[f+i>>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}l=a+2|0;e:{f:{if(!(c==1&d==0)){if((b|0)<=0){break a}if(!(O(d)<2147483648)){break f}m=~~d;break e}if((b|0)<=0){break a}while(1){g:{h:{i:{j:{m=I[l>>1]&32640;switch(((m|0)==32640?1:!m<<1)|0){case 0:break h;case 1:break j;default:break i}}G[h>>2]=1;if((e|0)==1){G[(k<<2)+i>>2]=f;break g}E[g+k|0]=1;break g}G[(k<<2)+i>>2]=0;break g}m=k<<2;p=K[m+a>>2];c=+p;if(c<-0x7ffffffffffffc00){G[j>>2]=-11;G[i+m>>2]=-2147483648;break g}if(c>0x7ffffffffffffc00){G[j>>2]=-11;G[i+m>>2]=2147483647;break g}n=i+m|0;if(N(O(p))>2]=m}l=l+4|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}m=-2147483648}while(1){k:{l:{m:{n:{n=I[l>>1]&32640;switch(((n|0)==32640?1:!n<<1)|0){case 0:break l;case 1:break n;default:break m}}G[h>>2]=1;if((e|0)==1){G[(k<<2)+i>>2]=f;break k}E[g+k|0]=1;break k}if(d<-0x7ffffffffffffc00){G[j>>2]=-11;G[(k<<2)+i>>2]=-2147483648;break k}if(d>0x7ffffffffffffc00){G[j>>2]=-11;G[(k<<2)+i>>2]=2147483647;break k}G[(k<<2)+i>>2]=m;break k}n=k<<2;o=+K[n+a>>2]*c+d;if(o<-0x7ffffffffffffc00){G[j>>2]=-11;G[i+n>>2]=-2147483648;break k}if(o>0x7ffffffffffffc00){G[j>>2]=-11;G[(k<<2)+i>>2]=2147483647;break k}q=(k<<2)+i|0;if(O(o)<2147483648){n=~~o}else{n=-2147483648}G[q>>2]=n}l=l+4|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}while(1){o:{p:{f=l<<2;p=K[f+a>>2];c=+p;if(c<-0x7ffffffffffffc00){G[j>>2]=-11;break p}if(c>0x7ffffffffffffc00){G[j>>2]=-11;e=2147483647;break o}if(!(N(O(p))>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}}}function ub(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;if(!a){return ab(b)|0}if(b>>>0>=4294967232){G[48624]=48;return 0}g=b>>>0<11?16:b+11&-8;f=a-8|0;j=G[f+4>>2];e=j&-8;a:{if(!(j&3)){if(g>>>0<256){break a}if(e>>>0>=g+4>>>0){c=f;if(e-g>>>0<=G[48745]<<1>>>0){break a}}c=0;break a}h=e+f|0;b:{if(e>>>0>=g>>>0){d=e-g|0;if(d>>>0<16){break b}G[f+4>>2]=j&1|g|2;c=f+g|0;G[c+4>>2]=d|3;G[h+4>>2]=G[h+4>>2]|1;xm(c,d);break b}if(G[48631]==(h|0)){e=e+G[48628]|0;if(e>>>0<=g>>>0){break a}G[f+4>>2]=j&1|g|2;d=f+g|0;c=e-g|0;G[d+4>>2]=c|1;G[48628]=c;G[48631]=d;break b}if(G[48630]==(h|0)){d=e+G[48627]|0;if(d>>>0>>0){break a}c=d-g|0;c:{if(c>>>0>=16){G[f+4>>2]=j&1|g|2;e=f+g|0;G[e+4>>2]=c|1;d=d+f|0;G[d>>2]=c;G[d+4>>2]=G[d+4>>2]&-2;break c}G[f+4>>2]=d|j&1|2;c=d+f|0;G[c+4>>2]=G[c+4>>2]|1;c=0;e=0}G[48630]=e;G[48627]=c;break b}d=G[h+4>>2];if(d&2){break a}k=e+(d&-8)|0;if(k>>>0>>0){break a}m=k-g|0;d:{if(d>>>0<=255){e=G[h+8>>2];c=d>>>3|0;d=G[h+12>>2];if((d|0)==(e|0)){n=194500,o=G[48625]&Eu(-2,c),G[n>>2]=o;break d}G[e+12>>2]=d;G[d+8>>2]=e;break d}l=G[h+24>>2];i=G[h+12>>2];e:{if((i|0)!=(h|0)){c=G[h+8>>2];G[c+12>>2]=i;G[i+8>>2]=c;break e}f:{e=h+20|0;c=G[e>>2];if(c){break f}e=h+16|0;c=G[e>>2];if(c){break f}i=0;break e}while(1){d=e;i=c;e=c+20|0;c=G[e>>2];if(c){continue}e=i+16|0;c=G[i+16>>2];if(c){continue}break}G[d>>2]=0}if(!l){break d}d=G[h+28>>2];c=(d<<2)+194804|0;g:{if(G[c>>2]==(h|0)){G[c>>2]=i;if(i){break g}n=194504,o=G[48626]&Eu(-2,d),G[n>>2]=o;break d}G[(G[l+16>>2]==(h|0)?16:20)+l>>2]=i;if(!i){break d}}G[i+24>>2]=l;c=G[h+16>>2];if(c){G[i+16>>2]=c;G[c+24>>2]=i}c=G[h+20>>2];if(!c){break d}G[i+20>>2]=c;G[c+24>>2]=i}if(m>>>0<=15){G[f+4>>2]=j&1|k|2;c=f+k|0;G[c+4>>2]=G[c+4>>2]|1;break b}G[f+4>>2]=j&1|g|2;d=f+g|0;G[d+4>>2]=m|3;c=f+k|0;G[c+4>>2]=G[c+4>>2]|1;xm(d,m)}c=f}if(c){return c+8|0}f=ab(b);if(!f){return 0}c=G[a-4>>2];c=(c&3?-4:-8)+(c&-8)|0;bb(f,a,b>>>0>c>>>0?c:b);Wa(a);return f|0}function Dp(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0;l=c==1&d==0;a:{b:{if(!e){if(l){break b}l=0;if((b|0)<=0){break a}while(1){f=(l<<2)+j|0;c:{d:{m=+F[(l<<1)+a>>1]*c+d;if(m<-.49){G[k>>2]=-11;break d}if(m>0xfffffffffffff800){G[k>>2]=-11;e=-1;break c}if(!(m<4294967296&m>=0)){break d}e=~~m>>>0;break c}e=0}G[f>>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if(!l){if((b|0)<=0){break a}o=f&65535;l=0;while(1){f=I[(l<<1)+a>>1];e:{if((f|0)==(o|0)){G[i>>2]=1;if((e|0)==1){G[(l<<2)+j>>2]=g;break e}E[h+l|0]=1;break e}m=+(f<<16>>16)*c+d;if(m<-.49){G[k>>2]=-11;G[(l<<2)+j>>2]=0;break e}if(m>0xfffffffffffff800){G[k>>2]=-11;G[(l<<2)+j>>2]=-1;break e}n=(l<<2)+j|0;if(m<4294967296&m>=0){f=~~m>>>0}else{f=0}G[n>>2]=f}l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)!=1){l=0;e=f&65535;while(1){f=I[(l<<1)+a>>1];f:{if((f|0)==(e|0)){G[i>>2]=1;E[h+l|0]=1;break f}f=f<<16>>16;if((f|0)<0){G[k>>2]=-11;G[(l<<2)+j>>2]=0;break f}G[(l<<2)+j>>2]=f}l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}o=b&1;l=0;if((b|0)!=1){p=b&-2;e=f&65535;h=0;while(1){b=I[(l<<1)+a>>1];g:{if((b|0)!=(e|0)){b=b<<16>>16;if((b|0)>=0){break g}G[k>>2]=-11;b=0;break g}G[i>>2]=1;b=g}G[(l<<2)+j>>2]=b;n=l|1;b=I[(n<<1)+a>>1];h:{if((b|0)!=(e|0)){b=b<<16>>16;if((b|0)>=0){break h}G[k>>2]=-11;b=0;break h}G[i>>2]=1;b=g}G[(n<<2)+j>>2]=b;l=l+2|0;h=h+2|0;if((p|0)!=(h|0)){continue}break}}if(!o){break a}a=I[(l<<1)+a>>1];i:{if((a|0)!=(f&65535)){g=a<<16>>16;if((g|0)>=0){break i}G[k>>2]=-11;g=0;break i}G[i>>2]=1}G[(l<<2)+j>>2]=g;break a}if((b|0)<=0){break a}f=b&1;l=0;if((b|0)!=1){g=b&-2;b=0;while(1){h=(l<<2)+j|0;e=F[(l<<1)+a>>1];j:{if((e|0)<0){G[k>>2]=-11;e=0;break j}e=e&65535}G[h>>2]=e;h=l|1;e=F[(h<<1)+a>>1];k:{if((e|0)>=0){e=e&65535;break k}G[k>>2]=-11;e=0}G[(h<<2)+j>>2]=e;l=l+2|0;b=b+2|0;if((g|0)!=(b|0)){continue}break}}if(!f){break a}b=0;a=F[(l<<1)+a>>1];l:{if((a|0)>=0){b=a&65535;break l}G[k>>2]=-11}G[(l<<2)+j>>2]=b}}function Fe(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;d=Fa-208|0;Fa=d;E[d+204|0]=39;E[d+205|0]=0;E[d+202|0]=34;E[d+203|0]=0;E[d+200|0]=91;E[d+201|0]=0;E[d+198|0]=93;E[d+199|0]=0;E[d+196|0]=47;E[d+197|0]=0;E[d+194|0]=44;E[d+195|0]=0;h=rb(d+112|0,b,80);E[h+80|0]=0;c=Va(h);b=ec(h,d+200|0,c);a:{if(!b){b=ec(h,d+194|0,c);if(!b){break a}}E[b|0]=0;i=b+1|0}b=0;b:{c:{d:{while(1){f=a+b|0;if(!H[f|0]){c=b;break d}c=1;e=a+b|0;f=e+1|0;if(!H[f|0]){break d}f=e+2|0;if(!H[f|0]){break d}f=e+3|0;if(!H[f|0]){break d}f=e+4|0;if(!H[f|0]){break d}b=b+5|0;if((b|0)!=57600){continue}break}f=a+57600|0;break c}if(c){break c}break b}c=a;while(1){g=ec(c,h,f-c|0);if(!g){break b}e:{f:{b=(g-a|0)%80|0;if((b|0)<8){e=H[Va(h)+g|0];if((e|0)==61|(e-33&255)>>>0>93){break f}}c=g+1|0;break e}e=g-b|0;if((b|0)>0){k=g+1|0;b=e;while(1){c=H[b|0]==32?c:k;b=b+1|0;if(g>>>0>b>>>0){continue}break}}if(c>>>0>g>>>0){break e}G[d+96>>2]=0;G[d+88>>2]=0;G[d+92>>2]=0;G[d+80>>2]=0;G[d+84>>2]=0;a=rb(d,e,80);e=Va(a);b=ec(a,d+204|0,e);c=ec(a,d+196|0,e);g:{h:{i:{if(b){if(!(!c|b>>>0>=c>>>0)){a=b+1|0;c=ec(a,d+204|0,Va(a));break i}if(c){break h}a=b+1|0;c=ec(a,d+204|0,Va(a));break i}b=ec(a,d+202|0,e);if(!b){break h}if(!(!c|b>>>0>=c>>>0)){a=b+1|0;c=ec(a,d+202|0,Va(a));break i}if(c){break h}a=b+1|0;c=ec(a,d+202|0,Va(a))}ec(c,42205,Va(c));break g}b=ec(a,36178,e);c=ec(a,42205,e);c=c?c:a+79|0}while(1){j:{a=b;b=b+1|0;if(H[a+1|0]!=32){break j}if(b>>>0>>0){continue}}break}E[c|0]=0;c=c-1|0;k:{if(H[c|0]!=32|b>>>0>=c>>>0){break k}while(1){E[c|0]=0;c=c-1|0;if(H[c|0]!=32){break k}if(b>>>0>>0){continue}break}}j=757136;b=Xa(b,41689)?b:a+2|0;Za(757136,b);if(!i){break b}a=ec(i,d+198|0,Va(i));if(a){E[a|0]=0}a=_b(i);if((a|0)<=0){break b}E[d+206|0]=32;E[d+207|0]=0;c=pc(b,d+206|0);if((a|0)!=1){b=2;while(1){e=(a|0)!=(b|0);c=pc(0,d+206|0);b=b+1|0;if(e){continue}break}}if(!c){j=0;break b}Za(757136,c);break b}if(c>>>0>>0){continue}break}}Fa=d+208|0;return j}function Uh(a,b,c,d){var e=0,f=0,g=0,h=0,i=0;h=Fa-6528|0;Fa=h;G[c>>2]=0;G[c+4>>2]=0;G[d>>2]=0;G[d+4>>2]=0;a:{if(G[325170]!=1){break a}if(G[325169]>0){i=h+3264|0;bb(i,1297408,3264);jm(a,b,i,c,d);b=L[d>>3];a=L[c>>3]}b:{if(G[325188]){e=a-L[161754];b=b-L[161755];a=L[162597]*e+b*L[162598];b=L[162595]*e+L[162596]*b;break b}e=L[161758];b=L[161765]*(b-L[161755]);f=L[161764]*(a-L[161754]);g=L[161759];a=e*b-f*g;b=f*e+g*b}b=b*.0174532925199433;c:{if(!Xa(1294012,34606)){break c}if(!Xa(1294012,34543)){e=b*b+a*a*.0174532925199433*.0174532925199433;if(e>1){break a}e=e<1?V(1-e):0;a=a/e;b=b/e;break c}if(!Xa(1294012,35981)){e=(b*b+a*a*.0174532925199433*.0174532925199433)*.25;if(e>.5){break a}e=V(1-e)*.5/(1-(e+e));a=a*e;b=b*e;break c}if(!Xa(1294012,35072)){e=(b*b+a*a*.0174532925199433*.0174532925199433)*.25;if(e>=1){break a}e=1-e;a=a*e;b=b*e;break c}if(Xa(1294012,35873)){break c}e=a*a+b*b/.00030461741978670873;if(e<=0){break a}f=a;a=V(e);e=Mc(a)/a;a=f*e;b=b*e}f=L[161761];g=L[161760];e=b*f+g;if(e<=0){break a}a=a/e;b=(b*g-f)/e/.0174532925199433;d:{if(!Xa(1294008,34606)){break d}if(!Xa(1294008,34543)){e=1/V((b*b+a*a)*.0174532925199433*.0174532925199433+1);a=a*e;b=b*e;break d}if(!Xa(1294008,35981)){e=(b*b+a*a)*.0174532925199433*.0174532925199433;if(!(e>1e-23)){break d}f=a;a=1-1/V(e+1);e=V(a+a)/V(e);a=f*e;b=b*e;break d}if(!Xa(1294008,35072)){e=1/(V((b*b+a*a)*.0174532925199433*.0174532925199433+1)+1);a=a*e;b=b*e;break d}if(Xa(1294008,35873)){break d}e=(b*b+a*a)*.0174532925199433*.0174532925199433;if(e<=0){break a}f=a;a=V(e);e=Pd(a)/a;a=f*e;b=b*e}e:{if(G[325171]){e=L[162592]*b+a*L[162593];a=L[162590]*b+a*L[162591];break e}f=L[161757];g=L[161756];e=(b*f+a*g)/L[161763];a=(b*g-f*a)/L[161762]}b=e+L[161753];a=a+L[161752];f:{if(G[325168]>0){im(a,b,bb(h,1294144,3264),c,d);break f}L[c>>3]=a;L[d>>3]=b}a=L[c>>3];if(a<.5|a>+G[323532]+.5){break a}a=L[d>>3];if(a<.5|a>+G[323534]+.5){break a}}Fa=h+6528|0}function Oc(a,b,c){var d=0,e=0;if(b){d=a^-1;a:{if(!c|!(b&3)){break a}d=G[((H[b|0]^d&255)<<2)+105024>>2]^d>>>8;e=c-1|0;a=b+1|0;if(!(!e|!(a&3))){d=G[((H[b+1|0]^d&255)<<2)+105024>>2]^d>>>8;e=c-2|0;a=b+2|0;if(!(!e|!(a&3))){d=G[((H[b+2|0]^d&255)<<2)+105024>>2]^d>>>8;e=c-3|0;a=b+3|0;if(!(!e|!(a&3))){d=G[((H[b+3|0]^d&255)<<2)+105024>>2]^d>>>8;c=c-4|0;b=b+4|0;break a}b=a;c=e;break a}b=a;c=e;break a}b=a;c=e}if(c>>>0>31){while(1){a=G[b>>2]^d;a=G[b+4>>2]^(G[(a>>>6&1020)+107072>>2]^G[((a&255)<<2)+108096>>2]^G[(a>>>14&1020)+106048>>2]^G[(a>>>22&1020)+105024>>2]);a=G[b+8>>2]^(G[(a>>>6&1020)+107072>>2]^G[((a&255)<<2)+108096>>2]^G[(a>>>14&1020)+106048>>2]^G[(a>>>22&1020)+105024>>2]);a=G[b+12>>2]^(G[(a>>>6&1020)+107072>>2]^G[((a&255)<<2)+108096>>2]^G[(a>>>14&1020)+106048>>2]^G[(a>>>22&1020)+105024>>2]);a=G[b+16>>2]^(G[(a>>>6&1020)+107072>>2]^G[((a&255)<<2)+108096>>2]^G[(a>>>14&1020)+106048>>2]^G[(a>>>22&1020)+105024>>2]);a=G[b+20>>2]^(G[(a>>>6&1020)+107072>>2]^G[((a&255)<<2)+108096>>2]^G[(a>>>14&1020)+106048>>2]^G[(a>>>22&1020)+105024>>2]);a=G[b+24>>2]^(G[(a>>>6&1020)+107072>>2]^G[((a&255)<<2)+108096>>2]^G[(a>>>14&1020)+106048>>2]^G[(a>>>22&1020)+105024>>2]);a=G[b+28>>2]^(G[(a>>>6&1020)+107072>>2]^G[((a&255)<<2)+108096>>2]^G[(a>>>14&1020)+106048>>2]^G[(a>>>22&1020)+105024>>2]);d=G[(a>>>6&1020)+107072>>2]^G[((a&255)<<2)+108096>>2]^G[(a>>>14&1020)+106048>>2]^G[(a>>>22&1020)+105024>>2];b=b+32|0;c=c-32|0;if(c>>>0>31){continue}break}}if(c>>>0>3){while(1){a=G[b>>2]^d;d=G[(a>>>6&1020)+107072>>2]^G[((a&255)<<2)+108096>>2]^G[(a>>>14&1020)+106048>>2]^G[(a>>>22&1020)+105024>>2];b=b+4|0;c=c-4|0;if(c>>>0>3){continue}break}}b:{if(!c){break b}if(c&1){d=G[((H[b|0]^d&255)<<2)+105024>>2]^d>>>8;b=b+1|0;a=c-1|0}else{a=c}if((c|0)==1){break b}while(1){c=G[((H[b|0]^d&255)<<2)+105024>>2]^d>>>8;d=G[((H[b+1|0]^c&255)<<2)+105024>>2]^c>>>8;b=b+2|0;a=a-2|0;if(a){continue}break}}a=d^-1}else{a=0}return a}function gf(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;d=a&65535;e=a>>>16|0;a:{if((c|0)==1){a=H[b|0]+d|0;a=a>>>0>65520?a-65521|0:a;b=a+e|0;c=b<<16;a=(b>>>0>65520?c+983040|0:c)|a;break a}if(b){if(c>>>0>=16){b:{c:{d:{if(c>>>0>5551){while(1){c=c-5552|0;f=347;a=b;while(1){g=H[a|0]+d|0;h=g+H[a+1|0]|0;i=h+H[a+2|0]|0;j=i+H[a+3|0]|0;k=j+H[a+4|0]|0;l=k+H[a+5|0]|0;m=l+H[a+6|0]|0;n=m+H[a+7|0]|0;o=n+H[a+8|0]|0;p=o+H[a+9|0]|0;q=p+H[a+10|0]|0;r=q+H[a+11|0]|0;s=r+H[a+12|0]|0;t=s+H[a+13|0]|0;u=t+H[a+14|0]|0;d=u+H[a+15|0]|0;e=d+(u+(t+(s+(r+(q+(p+(o+(n+(m+(l+(k+(j+(i+(h+(e+g|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0;a=a+16|0;f=f-1|0;if(f){continue}break}e=(e>>>0)%65521|0;d=(d>>>0)%65521|0;b=b+5552|0;if(c>>>0>5551){continue}break}if(!c){break b}if(c>>>0<16){break d}}while(1){a=H[b|0]+d|0;f=a+H[b+1|0]|0;g=f+H[b+2|0]|0;h=g+H[b+3|0]|0;i=h+H[b+4|0]|0;j=i+H[b+5|0]|0;k=j+H[b+6|0]|0;l=k+H[b+7|0]|0;m=l+H[b+8|0]|0;n=m+H[b+9|0]|0;o=n+H[b+10|0]|0;p=o+H[b+11|0]|0;q=p+H[b+12|0]|0;r=q+H[b+13|0]|0;s=r+H[b+14|0]|0;d=s+H[b+15|0]|0;e=d+(s+(r+(q+(p+(o+(n+(m+(l+(k+(j+(i+(h+(g+(f+(a+e|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0)|0;b=b+16|0;c=c-16|0;if(c>>>0>15){continue}break}if(!c){break c}}g=c-1|0;h=c&3;if(h){f=0;a=b;while(1){c=c-1|0;d=H[a|0]+d|0;e=e+d|0;b=a+1|0;a=b;f=f+1|0;if((h|0)!=(f|0)){continue}break}}if(g>>>0<3){break c}while(1){a=H[b|0]+d|0;f=a+H[b+1|0]|0;g=f+H[b+2|0]|0;d=g+H[b+3|0]|0;e=d+(g+(f+(a+e|0)|0)|0)|0;b=b+4|0;c=c-4|0;if(c){continue}break}}e=(e>>>0)%65521|0;d=(d>>>0)%65521|0}a=e<<16|d;break a}e:{if(!c){break e}g=c-1|0;h=c&3;if(h){a=b;while(1){c=c-1|0;d=H[a|0]+d|0;e=e+d|0;b=a+1|0;a=b;f=f+1|0;if((h|0)!=(f|0)){continue}break}}if(g>>>0<3){break e}while(1){a=H[b|0]+d|0;f=a+H[b+1|0]|0;g=f+H[b+2|0]|0;d=g+H[b+3|0]|0;e=d+(g+(f+(a+e|0)|0)|0)|0;b=b+4|0;c=c-4|0;if(c){continue}break}}a=(e>>>0)%65521<<16|(d>>>0>65520?d-65521|0:d)}else{a=1}}return a}function Qp(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0;a:{b:{if(!e){if(c==1&d==0){break b}if((b|0)<=0){break a}while(1){f=(l<<2)+i|0;c:{d:{m=L[(l<<3)+a>>3]*c+d;if(m<-2147483648.49){G[j>>2]=-11;break d}if(m>2147483647.49){G[j>>2]=-11;e=2147483647;break c}if(!(O(m)<2147483648)){break d}e=~~m;break c}e=-2147483648}G[f>>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}l=a+6|0;e:{f:{if(!(c==1&d==0)){if((b|0)<=0){break a}if(!(O(d)<2147483648)){break f}n=~~d;break e}if((b|0)<=0){break a}while(1){g:{h:{i:{j:{n=I[l>>1]&32752;switch(((n|0)==32752?1:!n<<1)|0){case 0:break h;case 1:break j;default:break i}}G[h>>2]=1;if((e|0)==1){G[(k<<2)+i>>2]=f;break g}E[g+k|0]=1;break g}G[(k<<2)+i>>2]=0;break g}c=L[(k<<3)+a>>3];if(c<-2147483648.49){G[j>>2]=-11;G[(k<<2)+i>>2]=-2147483648;break g}if(c>2147483647.49){G[j>>2]=-11;G[(k<<2)+i>>2]=2147483647;break g}o=(k<<2)+i|0;if(O(c)<2147483648){n=~~c}else{n=-2147483648}G[o>>2]=n}l=l+8|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}n=-2147483648}while(1){k:{l:{m:{n:{o=I[l>>1]&32752;switch(((o|0)==32752?1:!o<<1)|0){case 0:break l;case 1:break n;default:break m}}G[h>>2]=1;if((e|0)==1){G[(k<<2)+i>>2]=f;break k}E[g+k|0]=1;break k}if(d<-2147483648.49){G[j>>2]=-11;G[(k<<2)+i>>2]=-2147483648;break k}if(d>2147483647.49){G[j>>2]=-11;G[(k<<2)+i>>2]=2147483647;break k}G[(k<<2)+i>>2]=n;break k}m=L[(k<<3)+a>>3]*c+d;if(m<-2147483648.49){G[j>>2]=-11;G[(k<<2)+i>>2]=-2147483648;break k}if(m>2147483647.49){G[j>>2]=-11;G[(k<<2)+i>>2]=2147483647;break k}p=(k<<2)+i|0;if(O(m)<2147483648){o=~~m}else{o=-2147483648}G[p>>2]=o}l=l+8|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}while(1){f=(l<<2)+i|0;o:{p:{c=L[(l<<3)+a>>3];if(c<-2147483648.49){G[j>>2]=-11;break p}if(c>2147483647.49){G[j>>2]=-11;e=2147483647;break o}if(!(O(c)<2147483648)){break p}e=~~c;break o}e=-2147483648}G[f>>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}}}function Rp(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=N(0),q=0;a:{b:{if(!e){if(c==1&d==0){break b}if((b|0)<=0){break a}while(1){c:{d:{f=l<<2;o=+K[f+a>>2]*c+d;if(o<-2147483648.49){G[j>>2]=-11;break d}if(o>2147483647.49){G[j>>2]=-11;e=2147483647;break c}if(!(O(o)<2147483648)){break d}e=~~o;break c}e=-2147483648}G[f+i>>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}l=a+2|0;e:{f:{if(!(c==1&d==0)){if((b|0)<=0){break a}if(!(O(d)<2147483648)){break f}m=~~d;break e}if((b|0)<=0){break a}while(1){g:{h:{i:{j:{m=I[l>>1]&32640;switch(((m|0)==32640?1:!m<<1)|0){case 0:break h;case 1:break j;default:break i}}G[h>>2]=1;if((e|0)==1){G[(k<<2)+i>>2]=f;break g}E[g+k|0]=1;break g}G[(k<<2)+i>>2]=0;break g}m=k<<2;p=K[m+a>>2];c=+p;if(c<-2147483648.49){G[j>>2]=-11;G[i+m>>2]=-2147483648;break g}if(c>2147483647.49){G[j>>2]=-11;G[i+m>>2]=2147483647;break g}n=i+m|0;if(N(O(p))>2]=m}l=l+4|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}m=-2147483648}while(1){k:{l:{m:{n:{n=I[l>>1]&32640;switch(((n|0)==32640?1:!n<<1)|0){case 0:break l;case 1:break n;default:break m}}G[h>>2]=1;if((e|0)==1){G[(k<<2)+i>>2]=f;break k}E[g+k|0]=1;break k}if(d<-2147483648.49){G[j>>2]=-11;G[(k<<2)+i>>2]=-2147483648;break k}if(d>2147483647.49){G[j>>2]=-11;G[(k<<2)+i>>2]=2147483647;break k}G[(k<<2)+i>>2]=m;break k}n=k<<2;o=+K[n+a>>2]*c+d;if(o<-2147483648.49){G[j>>2]=-11;G[i+n>>2]=-2147483648;break k}if(o>2147483647.49){G[j>>2]=-11;G[(k<<2)+i>>2]=2147483647;break k}q=(k<<2)+i|0;if(O(o)<2147483648){n=~~o}else{n=-2147483648}G[q>>2]=n}l=l+4|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}while(1){o:{p:{f=l<<2;p=K[f+a>>2];c=+p;if(c<-2147483648.49){G[j>>2]=-11;break p}if(c>2147483647.49){G[j>>2]=-11;e=2147483647;break o}if(!(N(O(p))>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}}}function gs(a,b,c,d,e,f,g,h,i,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0;p=Fa-16|0;Fa=p;G[p+12>>2]=j;a:{k=G[a+8>>2];q=(G[a>>2]+M(c,3)|0)-2|0;o=M(q,168);e=k+o|0;if(G[e+32>>2]){break a}m=lb(1e3,8);G[e+32>>2]=m;j=0;G[e+28>>2]=0;l=1e3;while(1){if((j|0)>=(l|0)){l=l+1e3|0;e=ub(m,l<<3);k=G[a+8>>2];G[(o+k|0)+32>>2]=e}e=G[p+12>>2]+7&-8;G[p+12>>2]=e+8;n=k+o|0;m=G[n+32>>2];j=G[n+28>>2];h=L[e>>3];L[m+(j<<3)>>3]=h;b:{if(!(O(h+-9007199254740992)<=1e-15)){break b}e=j-1|0;if(!(O(L[(e<<3)+m>>3]+-9007199254740992)<=1e-15)){break b}G[n+28>>2]=e;j=M(q,168);e=j+G[a+8>>2]|0;e=ub(G[e+32>>2],G[e+28>>2]<<3);k=G[a+8>>2];G[(j+k|0)+32>>2]=e;break a}j=j+1|0;G[n+28>>2]=j;continue}}o=G[(k+o|0)+28>>2];c:{if((o|0)==2){h=L[(M(c,168)+k|0)+8>>3];if(d){l=0;if(g>3]=h)|!(L[(M(c,168)+k|0)+16>>3]>=g))){l=0;e=0;j=G[(M(c,168)+k|0)+24>>2];if(O(g)<2147483648){c=~~g}else{c=-2147483648}j=G[j+(c<<2)>>2];d:{if(!j){break d}while(1){if(!(+G[j+4>>2]<=f)){break d}e=e+1|0;j=G[j>>2];if(j){continue}break}}if((e&1)!=(d|0)){break c}if(!b){l=1;break c}if(!d){l=1;break c}G[a+12>>2]=b;l=1;break c}l=!d;break c}e=!d;l=e;if(e){break c}i=L[(M(q,168)+k|0)+8>>3];if(i>g){break c}l=0;h=L[(M(q,168)+k|0)+16>>3];if(!(g>=i)|h>2];if(O(g)<2147483648){n=~~g}else{n=-2147483648}j=G[j+(n<<2)>>2];e:{if(!j){break e}while(1){if(!(+G[j+4>>2]<=f)){break e}e=e+1|0;j=G[j>>2];if(j){continue}break}}if((e&1)!=(d|0)|(o|0)<=0){break c}n=n<<2;m=0;while(1){f:{j=M(c+m|0,168)+k|0;i=L[j+8>>3];if(i>g){break f}h=L[j+16>>3];if(!(g>=i)|h>2]>>2];g:{if(!j){break g}while(1){if(!(+G[j+4>>2]<=f)){break g}e=e+1|0;j=G[j>>2];if(j){continue}break}}if((e&1)!=(d|0)){break f}l=1;b=b+m|0;if(!b){break c}G[a+12>>2]=b;break c}m=m+1|0;if((o|0)!=(m|0)){continue}break}}Fa=p+16|0;return l|0}function ss(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;l=+l;m=+m;n=n|0;o=+o;var p=0,q=0,r=0,s=0,t=0;e=l==0&m==0;s=G[a>>2]+M(c,3)|0;q=s-2|0;a:{if(d){if(e){break a}t=G[a+8>>2];e=t+M(q,168)|0;i=L[e+8>>3];if(i>g){break a}h=L[e+16>>3];if(!(g>=i)|h>2];if(O(g)<2147483648){q=~~g}else{q=-2147483648}e=G[e+(q<<2)>>2];b:{if(!e){break b}while(1){if(!(+G[e+4>>2]<=f)){break b}r=r+1|0;e=G[e>>2];if(e){continue}break}}if((r&1)!=(d|0)){break a}c:{d:{if(j==0&k==0){break d}s=s-1|0;e=M(s,168)+t|0;i=L[e+8>>3];if(i>g){break d}h=L[e+16>>3];if(!(g>=i)|h>2]+(q<<2)>>2];e:{if(!e){break e}while(1){if(!(+G[e+4>>2]<=f)){break e}r=r+1|0;e=G[e>>2];if(e){continue}break}}if((r&1)==(d|0)){break a}if((n|0)>0){break c}break a}if((n|0)<=0){break a}}h=+(n|0);m=(m-k)/h;l=(l-j)/h;e=0;s=q<<2;while(1){q=e;f:{e=e+1|0;h=+(e|0);if(h*l+j==0&h*m+k==0){break f}p=M(c+q|0,168)+t|0;i=L[p+8>>3];if(i>g){break f}h=L[p+16>>3];if(!(g>=i)|h>2]>>2];g:{if(!p){break g}while(1){if(!(+G[p+4>>2]<=f)){break g}r=r+1|0;p=G[p>>2];if(p){continue}break}}if((r&1)!=(d|0)){break f}p=1;b=b+q|0;if(!b){break a}G[a+12>>2]=b;return 1}p=0;if((e|0)!=(n|0)){continue}break}break a}p=1;if(e){break a}d=G[a+8>>2];a=d+M(q,168)|0;i=L[a+8>>3];if(i>g){break a}h=L[a+16>>3];if(!(g>=i)|(!(h>=g)|g>h)){break a}a=G[(d+M(q,168)|0)+24>>2];if(O(g)<2147483648){b=~~g}else{b=-2147483648}a=G[a+(b<<2)>>2];if(!a){break a}e=0;while(1){if(+G[a+4>>2]<=f){e=e+1|0;a=G[a>>2];if(a){continue}}break}if(!(e&1)){break a}p=0;if(j==0&k==0){break a}c=s-1|0;a=d+M(c,168)|0;i=L[a+8>>3];if(i>g){break a}h=L[a+16>>3];if(!(g>=i)|(!(h>=g)|g>h)){break a}a=G[G[(d+M(c,168)|0)+24>>2]+(b<<2)>>2];if(!a){break a}while(1){if(+G[a+4>>2]<=f){p=p+1|0;a=G[a>>2];if(a){continue}}break}p=p&1}return p|0}function Ws(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;j=G[309722];b=j+M(G[a+12>>2],344)|0;g=G[b+88>>2];c=G[b+56>>2];h=g+(c<<3)|0;b=G[b+52>>2];l=G[a+16>>2];k=M(l,344)+j|0;a:{if(G[k>>2]==-1e3){f=L[k+88>>3];b:{if(!(!b|(c|0)<16)){if(!(f>=L[g>>3])){c=-1;break b}if(!(f<=L[((c<<3)+h|0)-8>>3])){c=-1;break b}c=c>>>1|0;d=c;while(1){d=d>>>(d>>>0>1)|0;b=c<<3;e=b+h|0;if(f>L[e>>3]){if(!(f>=L[(b+g|0)+8>>3])){c=-1;break b}c=c+d|0;continue}if(!(f>3])){break b}if(f<=L[e-8>>3]){c=c-d|0;continue}else{c=-1;break b}}}while(1){if(!c){c=-1;break b}c=c-1|0;b=c<<3;if(!(f>=L[b+g>>3])|!(f<=L[b+h>>3])){continue}break}}G[a>>2]=-1e3;E[a+88|0]=(c|0)>=0;break a}Nd(a);if(G[309737]){break a}d=M(G[a+56>>2],G[309727]);if(c){o=G[k+88>>2];p=(b|0)!=0&(c|0)>15;q=c>>>1|0;r=((c<<3)+h|0)-8|0;s=M(l,344)+j|0;b=-1;while(1){if(!d){break a}d=d-1|0;e=H[d+G[s+84>>2]|0];E[G[a+84>>2]+d|0]=e;if(e){continue}f=L[(d<<3)+o>>3];c:{d:{if((b|0)<0){break d}e=b<<3;if(f>3]){break d}if(!(f>L[e+h>>3])){break c}}b=c;if(p){b=-1;if(!(f>=L[g>>3])){break c}e=q;i=e;if(!(f<=L[r>>3])){break c}while(1){i=i>>>(i>>>0>1)|0;m=e<<3;n=m+h|0;if(f>L[n>>3]){if(!(f>=L[(g+m|0)+8>>3])){break c}e=e+i|0;continue}if(!(f>3])){b=e;break c}if(!(f<=L[n-8>>3])){break c}e=e-i|0;continue}}while(1){if(!b){b=-1;break c}b=b-1|0;e=b<<3;if(!(f>=L[e+g>>3])|!(f<=L[e+h>>3])){continue}break}}E[G[a+88>>2]+d|0]=(b|0)>=0;continue}}if(!d){break a}b=d-1|0;e=d&3;if(e){c=0;while(1){d=d-1|0;E[d+G[a+88>>2]|0]=0;E[G[a+84>>2]+d|0]=0;c=c+1|0;if((e|0)!=(c|0)){continue}break}}if(b>>>0<3){break a}while(1){b=d-1|0;E[b+G[a+88>>2]|0]=0;E[b+G[a+84>>2]|0]=0;b=d-2|0;E[b+G[a+88>>2]|0]=0;E[b+G[a+84>>2]|0]=0;b=d-3|0;E[b+G[a+88>>2]|0]=0;E[b+G[a+84>>2]|0]=0;d=d-4|0;E[d+G[a+88>>2]|0]=0;E[G[a+84>>2]+d|0]=0;if(d){continue}break}}if(G[k>>2]>0){Wa(G[(M(l,344)+j|0)+88>>2])}}function tl(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0;a:{b:{c:{h=a+c|0;g=H[h|0];k=b+c|0;i=H[k|0];if((g|0)!=(i|0)){break c}g=H[h+1|0];i=H[k+1|0];if((g|0)!=(i|0)){break c}g=H[h+2|0];i=H[k+2|0];if((g|0)!=(i|0)){break c}g=H[h+3|0];i=H[k+3|0];if((g|0)!=(i|0)){break c}g=H[h+4|0];i=H[k+4|0];if((g|0)!=(i|0)){break c}g=H[h+5|0];i=H[k+5|0];if((g|0)!=(i|0)){break c}g=H[h+6|0];i=H[k+6|0];if((g|0)!=(i|0)){break c}g=H[h+7|0];i=H[k+7|0];if((g|0)!=(i|0)){break c}g=H[h+8|0];i=H[k+8|0];if((g|0)!=(i|0)){break c}g=H[h+9|0];i=H[k+9|0];if((g|0)!=(i|0)){break c}g=H[h+10|0];i=H[k+10|0];if((g|0)!=(i|0)){break c}g=H[h+11|0];h=H[k+11|0];if((g|0)!=(h|0)){return g>>>0>h>>>0}k=e+8|0;b=b+12|0;a=a+12|0;while(1){g=H[b+c|0];h=H[a+c|0];if((g|0)!=(h|0)){break b}g=I[(b<<1)+d>>1];h=I[(a<<1)+d>>1];if((g|0)!=(h|0)){break b}i=a+1|0;g=H[i+c|0];j=b+1|0;h=H[j+c|0];if((g|0)!=(h|0)){break a}g=I[(j<<1)+d>>1];h=I[(i<<1)+d>>1];if((g|0)!=(h|0)){break b}i=a+2|0;g=H[i+c|0];j=b+2|0;h=H[j+c|0];if((g|0)!=(h|0)){break a}g=I[(j<<1)+d>>1];h=I[(i<<1)+d>>1];if((g|0)!=(h|0)){break b}i=a+3|0;g=H[i+c|0];j=b+3|0;h=H[j+c|0];if((g|0)!=(h|0)){break a}g=I[(j<<1)+d>>1];h=I[(i<<1)+d>>1];if((g|0)!=(h|0)){break b}i=a+4|0;g=H[i+c|0];j=b+4|0;h=H[j+c|0];if((g|0)!=(h|0)){break a}g=I[(j<<1)+d>>1];h=I[(i<<1)+d>>1];if((g|0)!=(h|0)){break b}i=a+5|0;g=H[i+c|0];j=b+5|0;h=H[j+c|0];if((g|0)!=(h|0)){break a}g=I[(j<<1)+d>>1];h=I[(i<<1)+d>>1];if((g|0)!=(h|0)){break b}i=a+6|0;g=H[i+c|0];j=b+6|0;h=H[j+c|0];if((g|0)!=(h|0)){break a}g=I[(j<<1)+d>>1];h=I[(i<<1)+d>>1];if((g|0)!=(h|0)){break b}i=a+7|0;g=H[i+c|0];j=b+7|0;h=H[j+c|0];if((g|0)!=(h|0)){break a}g=I[(j<<1)+d>>1];h=I[(i<<1)+d>>1];if((g|0)!=(h|0)){break b}G[f>>2]=G[f>>2]-1;b=b+8|0;b=b-(b>>>0>>0?0:e)|0;a=a+8|0;a=a-(a>>>0>>0?0:e)|0;g=(k|0)>7;k=k-8|0;if(g){continue}break}return 0}return g>>>0>i>>>0}return g>>>0>>0}return g>>>0>h>>>0}function bq(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0;l=c==1&d==0;a:{b:{if(!e){if(l){break b}l=0;if((b|0)<=0){break a}while(1){f=(l<<2)+j|0;c:{d:{n=+H[a+l|0]*c+d;if(n<-0x7ffffffffffffc00){G[k>>2]=-11;break d}if(n>0x7ffffffffffffc00){G[k>>2]=-11;e=2147483647;break c}if(!(O(n)<2147483648)){break d}e=~~n;break c}e=-2147483648}G[f>>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if(!l){if((b|0)<=0){break a}l=0;while(1){m=H[a+l|0];e:{if((m|0)==(f|0)){G[i>>2]=1;if((e|0)==1){G[(l<<2)+j>>2]=g;break e}E[h+l|0]=1;break e}n=+(m>>>0)*c+d;if(n<-0x7ffffffffffffc00){G[k>>2]=-11;G[(l<<2)+j>>2]=-2147483648;break e}if(n>0x7ffffffffffffc00){G[k>>2]=-11;G[(l<<2)+j>>2]=2147483647;break e}o=(l<<2)+j|0;if(O(n)<2147483648){m=~~n}else{m=-2147483648}G[o>>2]=m}l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)!=1){g=b&1;l=0;if((b|0)!=1){k=b&-2;b=0;while(1){e=H[a+l|0];f:{if((e|0)==(f|0)){G[i>>2]=1;E[h+l|0]=1;break f}G[(l<<2)+j>>2]=e}e=l|1;m=H[e+a|0];g:{if((m|0)!=(f|0)){G[(e<<2)+j>>2]=m;break g}G[i>>2]=1;E[e+h|0]=1}l=l+2|0;b=b+2|0;if((k|0)!=(b|0)){continue}break}}if(!g){break a}a=H[a+l|0];if((a|0)!=(f|0)){G[(l<<2)+j>>2]=a;return}G[i>>2]=1;E[h+l|0]=1;break a}h=b&1;l=0;if((b|0)!=1){k=b&-2;e=0;while(1){m=(l<<2)+j|0;b=H[a+l|0];if((b|0)==(f|0)){G[i>>2]=1;b=g}G[m>>2]=b;m=l|1;b=H[m+a|0];if((f|0)==(b|0)){G[i>>2]=1;b=g}G[(m<<2)+j>>2]=b;l=l+2|0;e=e+2|0;if((k|0)!=(e|0)){continue}break}}if(!h){break a}b=(l<<2)+j|0;a=H[a+l|0];if((a|0)==(f|0)){G[i>>2]=1}else{g=a}G[b>>2]=g;return}if((b|0)<=0){break a}e=b&3;f=0;l=0;if(b-1>>>0>=3){g=b&-4;b=0;while(1){G[(l<<2)+j>>2]=H[a+l|0];h=l|1;G[(h<<2)+j>>2]=H[a+h|0];h=l|2;G[(h<<2)+j>>2]=H[a+h|0];h=l|3;G[(h<<2)+j>>2]=H[a+h|0];l=l+4|0;b=b+4|0;if((g|0)!=(b|0)){continue}break}}if(!e){break a}while(1){G[(l<<2)+j>>2]=H[a+l|0];l=l+1|0;f=f+1|0;if((e|0)!=(f|0)){continue}break}}}function Xk(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=N(0),p=0,q=0;a:{b:{if(!e){if(c==1&d==0){break b}if((b|0)<=0){break a}while(1){f=(l<<1)+i|0;m=+K[(l<<2)+a>>2]*c+d;c:{if(m<-32768.49){G[j>>2]=-11;e=32768;break c}if(m>32767.49){G[j>>2]=-11;e=32767;break c}e=~~m;if(O(m)<2147483648){break c}e=-2147483648}F[f>>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}l=a+2|0;d:{e:{if(!(c==1&d==0)){if((b|0)<=0){break a}if(!(O(d)<2147483648)){break e}n=~~d;break d}if((b|0)<=0){break a}while(1){f:{g:{h:{i:{n=I[l>>1]&32640;switch(((n|0)==32640?1:!n<<1)|0){case 0:break g;case 1:break i;default:break h}}G[h>>2]=1;if((e|0)==1){F[(k<<1)+i>>1]=f;break f}E[g+k|0]=1;break f}F[(k<<1)+i>>1]=0;break f}o=K[(k<<2)+a>>2];c=+o;if(c<-32768.49){G[j>>2]=-11;F[(k<<1)+i>>1]=32768;break f}if(c>32767.49){G[j>>2]=-11;F[(k<<1)+i>>1]=32767;break f}p=(k<<1)+i|0;if(N(O(o))>1]=n}l=l+4|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}n=-2147483648}while(1){j:{k:{l:{m:{p=I[l>>1]&32640;switch(((p|0)==32640?1:!p<<1)|0){case 0:break k;case 1:break m;default:break l}}G[h>>2]=1;if((e|0)==1){F[(k<<1)+i>>1]=f;break j}E[g+k|0]=1;break j}if(d<-32768.49){G[j>>2]=-11;F[(k<<1)+i>>1]=32768;break j}if(d>32767.49){G[j>>2]=-11;F[(k<<1)+i>>1]=32767;break j}F[(k<<1)+i>>1]=n;break j}m=+K[(k<<2)+a>>2]*c+d;if(m<-32768.49){G[j>>2]=-11;F[(k<<1)+i>>1]=32768;break j}if(m>32767.49){G[j>>2]=-11;F[(k<<1)+i>>1]=32767;break j}q=(k<<1)+i|0;if(O(m)<2147483648){p=~~m}else{p=-2147483648}F[q>>1]=p}l=l+4|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}while(1){f=(l<<1)+i|0;o=K[(l<<2)+a>>2];c=+o;n:{if(c<-32768.49){G[j>>2]=-11;e=32768;break n}if(c>32767.49){G[j>>2]=-11;e=32767;break n}e=~~o;if(N(O(o))>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}}}function zq(a){var b=0,c=0,d=0,e=0,f=0;a:{while(1){b:{c:{d:{switch(G[a+48>>2]){case 0:e=-1;c=a+100|0;e:{f:{g:{if(G[a+28>>2]){break g}b=G[a+32>>2];d=ab(b);G[a+36>>2]=d;f=ab(b<<1);G[a+40>>2]=f;if(!(f?d:0)){Wa(f);Wa(d);break f}G[a+28>>2]=b;G[a+100>>2]=0;G[a+104>>2]=0;G[a+140>>2]=0;G[a+132>>2]=0;G[a+136>>2]=0;if(!Ti(c)){break g}Wa(G[a+40>>2]);Wa(G[a+36>>2]);G[a+28>>2]=0;break f}h:{i:{j:{b=G[a+104>>2];if(b>>>0>1){break j}b=-1;if((xq(a)|0)==-1){break h}b=G[a+104>>2];switch(b|0){case 0:break h;case 1:break i;default:break j}}d=G[c>>2];if(H[d|0]!=31|H[d+1|0]!=139){break i}k:{if(!G[c+36>>2]|(!c|!G[c+32>>2])){break k}b=G[c+28>>2];if(!b|(c|0)!=G[b>>2]|G[b+4>>2]-16180>>>0>31){break k}G[b+52>>2]=0;G[b+44>>2]=0;G[b+48>>2]=0;G[b+32>>2]=0;G[c+8>>2]=0;G[c+20>>2]=0;G[c+24>>2]=0;d=G[b+12>>2];if(d){G[c+48>>2]=d&1}G[b+60>>2]=0;G[b+64>>2]=0;G[b+36>>2]=0;G[b+24>>2]=32768;G[b+16>>2]=0;G[b+4>>2]=16180;G[b+8>>2]=0;G[b+7108>>2]=1;G[b+7112>>2]=-1;c=b+1332|0;G[b+112>>2]=c;G[b+84>>2]=c;G[b+80>>2]=c}G[a+44>>2]=0;G[a+48>>2]=2;b=0;break e}if(!G[a+44>>2]){G[a+64>>2]=1;G[a+104>>2]=0;G[a>>2]=0;b=0;break e}c=G[a+40>>2];G[a+4>>2]=c;bb(c,G[a+100>>2],b);G[a+44>>2]=1;G[a+48>>2]=1;c=G[a+104>>2];b=0;G[a+104>>2]=0;G[a>>2]=c}break e}Vd(a,-4,3221);b=-1}if((b|0)==-1){break b}if(G[a+48>>2]){break c}return 0;case 1:G[a>>2]=0;b=G[a+28>>2]<<1;d=G[a+40>>2];l:{while(1){c=b-e|0;c=ql(G[a+20>>2],d+e|0,c>>>0<1073741824?c:1073741824);if((c|0)>0){e=c+G[a>>2]|0;G[a>>2]=e;if(b>>>0>e>>>0){continue}break l}break}if((c|0)<0){break a}G[a+64>>2]=1}G[a+4>>2]=G[a+40>>2];return 0;case 2:break d;default:break c}}G[a+112>>2]=G[a+40>>2];G[a+116>>2]=G[a+28>>2]<<1;e=-1;if((yq(a)|0)==-1){break b}}e=0;if(G[a>>2]){break b}if(G[a+104>>2]|!G[a+64>>2]){continue}}break}return e}b=a;a=G[48624];Vd(b,-1,I[((a>>>0>149?0:a)<<1)+143920>>1]+142088|0);return-1}function _k(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0;l=c==1&d==0;a:{b:{c:{if(!e){if(l){break c}l=0;if((b|0)<=0){break b}while(1){d:{e:{f=l<<2;n=+G[f+a>>2]*c+d;if(n<-0x7ffffffffffffc00){G[k>>2]=-11;break e}if(n>0x7ffffffffffffc00){G[k>>2]=-11;e=2147483647;break d}if(!(O(n)<2147483648)){break e}e=~~n;break d}e=-2147483648}G[f+j>>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break b}if(!l){if((b|0)<=0){break b}l=0;while(1){m=l<<2;o=G[m+a>>2];f:{if((o|0)==(f|0)){G[i>>2]=1;if((e|0)==1){G[j+m>>2]=g;break f}E[h+l|0]=1;break f}n=+(o|0)*c+d;if(n<-0x7ffffffffffffc00){G[k>>2]=-11;G[j+m>>2]=-2147483648;break f}if(n>0x7ffffffffffffc00){G[k>>2]=-11;G[j+m>>2]=2147483647;break f}o=j+m|0;if(O(n)<2147483648){m=~~n}else{m=-2147483648}G[o>>2]=m}l=l+1|0;if((l|0)!=(b|0)){continue}break}break b}if((b|0)<=0){break b}if((e|0)!=1){e=b&1;l=0;if((b|0)!=1){g=b&-2;b=0;while(1){k=l<<2;m=G[k+a>>2];g:{if((m|0)==(f|0)){G[i>>2]=1;E[h+l|0]=1;break g}G[j+k>>2]=m}k=l|1;m=k<<2;o=G[m+a>>2];h:{if((o|0)!=(f|0)){G[j+m>>2]=o;break h}G[i>>2]=1;E[h+k|0]=1}l=l+2|0;b=b+2|0;if((g|0)!=(b|0)){continue}break}}if(!e){break b}b=l<<2;a=G[b+a>>2];if((f|0)!=(a|0)){break a}G[i>>2]=1;E[h+l|0]=1;break b}h=b&1;l=0;if((b|0)!=1){k=b&-2;e=0;while(1){m=l<<2;b=G[m+a>>2];if((f|0)==(b|0)){G[i>>2]=1;b=g}G[j+m>>2]=b;m=(l|1)<<2;b=G[m+a>>2];if((f|0)==(b|0)){G[i>>2]=1;b=g}G[j+m>>2]=b;l=l+2|0;e=e+2|0;if((k|0)!=(e|0)){continue}break}}if(!h){break b}b=l<<2;a=G[b+a>>2];if((f|0)==(a|0)){G[i>>2]=1;a=g}break a}if((b|0)<=0){break b}g=b&3;e=0;l=0;if(b-1>>>0>=3){h=b&-4;b=0;while(1){f=l<<2;G[f+j>>2]=G[a+f>>2];i=f|4;G[i+j>>2]=G[a+i>>2];i=f|8;G[i+j>>2]=G[a+i>>2];f=f|12;G[f+j>>2]=G[a+f>>2];l=l+4|0;b=b+4|0;if((h|0)!=(b|0)){continue}break}}if(!g){break b}while(1){b=l<<2;G[b+j>>2]=G[a+b>>2];l=l+1|0;e=e+1|0;if((g|0)!=(e|0)){continue}break}}return}G[b+j>>2]=a}function qo(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;p=Fa-112|0;Fa=p;if(m){G[m>>2]=0}G[n>>2]=0;q=d+1|0;d=q>>31;G[p+32>>2]=q;G[p+36>>2]=d;G[p+80>>2]=q;G[p+84>>2]=d;q=G[e>>2];d=G[e+4>>2];a:{b:{if(!(q|d)){t=G[e+8>>2];e=G[e+12>>2];break b}q=q+1|0;d=q?d:d+1|0;G[p+64>>2]=q;G[p+68>>2]=d;r=G[e+12>>2];d=r;s=G[e+8>>2];v=s+1|0;d=v?d:d+1|0;G[p+24>>2]=v;G[p+28>>2]=d;G[p+72>>2]=v;G[p+76>>2]=d;c:{if((s|0)==G[f+8>>2]&(r|0)==G[f+12>>2]){d=G[f+4>>2];r=G[f>>2]+1|0;d=r?d:d+1|0;break c}d=G[h>>2];r=d;d=d>>31}s=d;d=r;G[p+16>>2]=d;G[p+20>>2]=s;md(a,b,p- -64|0,p+16|0,g,i,j,k,l,p+12|0,o);r=(d-q|0)+1|0;G[n>>2]=r+G[n>>2];if(!(!m|!G[p+12>>2])){G[m>>2]=1}s=G[e+8>>2];d=G[e+12>>2];if((s|0)==G[f+8>>2]&(d|0)==G[f+12>>2]){break a}G[e>>2]=0;G[e+4>>2]=0;q=e;e=d;d=s+1|0;e=d?e:e+1|0;t=d;G[q+8>>2]=d;G[q+12>>2]=e;l=((i|0)==2?l?r:0:0)+l|0;k=M(c,r)+k|0}G[p+64>>2]=1;G[p+68>>2]=0;d=e;q=t+1|0;d=q?d:d+1|0;r=q;G[p+72>>2]=q;G[p+76>>2]=d;q=G[h>>2];d=q>>31;u=q;G[p+16>>2]=q;G[p+20>>2]=d;q=G[f+12>>2];v=q;s=d;w=G[f+8>>2];x=u;d=G[f+4>>2];u=G[f>>2]+1|0;d=u?d:d+1|0;u=(x|0)==(u|0)&(d|0)==(s|0);s=w+u|0;d=q;q=s;G[p+24>>2]=q;d=q>>>0>>0?d+1|0:d;G[p+28>>2]=d;s=d;d:{if((d|0)<=(e|0)&q>>>0<=t>>>0|(d|0)<(e|0)){d=v;c=w+1|0;d=c?d:d+1|0;t=c;e=d;break d}md(a,b,p- -64|0,p+16|0,g,i,j,k,l,p+12|0,o);r=(q-r|0)+1|0;G[n>>2]=G[n>>2]+M(r,G[h>>2]);if(!(!m|!G[p+12>>2])){G[m>>2]=1}d=G[f+12>>2];e=G[f+8>>2]+1|0;d=e?d:d+1|0;t=e;e=d;if((q|0)==(t|0)&(s|0)==(d|0)){break a}d=M(r,G[h>>2]);l=((i|0)==2?l?d:0:0)+l|0;k=M(c,d)+k|0}if((q|0)==(t|0)&(e|0)==(s|0)){break a}d=G[f>>2];c=G[f+4>>2];G[p+24>>2]=t;G[p+28>>2]=e;G[p+72>>2]=t;G[p+76>>2]=e;e=c;c=d+1|0;e=c?e:e+1|0;G[p+16>>2]=c;G[p+20>>2]=e;md(a,b,p- -64|0,p+16|0,g,i,j,k,l,p+12|0,o);if(!(!m|!G[p+12>>2])){G[m>>2]=1}a=G[p+16>>2];b=G[p+64>>2];G[n>>2]=(G[n>>2]+(a-b|0)|0)+1}Fa=p+112|0}function Op(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0,p=0;l=c==1&d==0;a:{b:{c:{if(!e){if(l){break c}l=0;if((b|0)<=0){break a}while(1){f=l<<1;m=+F[f+a>>1]*c+d;d:{if(m<-32768.49){G[k>>2]=-11;e=32768;break d}if(m>32767.49){G[k>>2]=-11;e=32767;break d}e=~~m;if(O(m)<2147483648){break d}e=-2147483648}F[f+j>>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}e:{f:{if(!l){if((b|0)<=0){break a}l=0;if((e|0)!=1){break f}f=f&65535;while(1){h=l<<1;e=I[h+a>>1];g:{if((e|0)!=(f|0)){m=+(e<<16>>16)*c+d;if(!(m<-32768.49)){if(!(m>32767.49)){e=~~m;if(O(m)<2147483648){break g}e=-2147483648;break g}G[k>>2]=-11;e=32767;break g}G[k>>2]=-11;e=32768;break g}G[i>>2]=1;e=g}F[h+j>>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)==1){break b}l=0;if((b|0)!=1){k=b&-2;g=f&65535;e=0;while(1){o=l<<1;n=I[o+a>>1];h:{if((n|0)==(g|0)){G[i>>2]=1;E[h+l|0]=1;break h}F[j+o>>1]=n}o=l|1;n=o<<1;p=I[n+a>>1];i:{if((g|0)!=(p|0)){F[j+n>>1]=p;break i}G[i>>2]=1;E[h+o|0]=1}l=l+2|0;e=e+2|0;if((k|0)!=(e|0)){continue}break}}if(!(b&1)){break a}b=a;a=l<<1;b=I[b+a>>1];if((b|0)==(f&65535)){break e}F[a+j>>1]=b;break a}f=f&65535;while(1){e=l<<1;g=I[e+a>>1];j:{if((g|0)==(f|0)){G[i>>2]=1;E[h+l|0]=1;break j}m=+(g<<16>>16)*c+d;if(m<-32768.49){G[k>>2]=-11;F[e+j>>1]=32768;break j}if(m>32767.49){G[k>>2]=-11;F[e+j>>1]=32767;break j}g=e+j|0;if(O(m)<2147483648){e=~~m}else{e=-2147483648}F[g>>1]=e}l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}G[i>>2]=1;E[h+l|0]=1;break a}yd(j,a,b<<1);break a}k=b&1;l=0;if((b|0)!=1){o=b&-2;h=f&65535;e=0;while(1){n=l<<1;b=I[n+a>>1];if((h|0)==(b|0)){G[i>>2]=1;b=g}F[j+n>>1]=b;n=(l|1)<<1;b=I[n+a>>1];if((h|0)==(b|0)){G[i>>2]=1;b=g}F[j+n>>1]=b;l=l+2|0;e=e+2|0;if((o|0)!=(e|0)){continue}break}}if(!k){break a}b=a;a=l<<1;l=I[b+a>>1];if((l|0)==(f&65535)){G[i>>2]=1;l=g}F[a+j>>1]=l}}function Vf(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0;g=Fa-224|0;Fa=g;f=G[e>>2];a:{if((f|0)>0){break a}if(b){G[b>>2]=0}if(c){G[c>>2]=0}if(d){G[d>>2]=0}b:{c:{h=Va(a);d:{if(!h){break d}f=0;while(1){i=a+f|0;if(H[i|0]==32){f=f+1|0;if((h|0)!=(f|0)){continue}break d}break}if((f|0)!=(h|0)){break c}}tb(5,46113);break b}if(h-f>>>0>=71){tb(5,46163);break b}l=Za(g+144|0,i);h=Va(l);if(h){f=0;while(1){i=f+l|0;j=E[i|0];E[i|0]=j-97>>>0<26?j&95:j;f=f+1|0;if((h|0)!=(f|0)){continue}break}}f=0;while(1){i=f;f=f+1|0;k=i+l|0;h=E[k|0];if(h-48>>>0<10){continue}break}e:{f:{if(!i){G[g+220>>2]=1;break f}G[g+32>>2]=g+220;if((Qc(l,27698,g+32|0)|0)!=1){break e}h=H[k|0]}f=80;g:{h:{i:{j:{k:{l:{m:{n:{o:{p:{q:{r:{s:{t:{u:{v:{w:{j=h&254;h=(j|0)==80;switch(H[h+k|0]-65|0){case 20:break h;case 12:break j;case 2:break k;case 18:break l;case 1:break m;case 23:break n;case 11:break o;case 0:break p;case 3:break q;case 4:break r;case 10:break s;case 9:break t;case 22:break u;case 21:break v;case 8:break w;default:break i}}G[g+48>>2]=2;f=21;break g}G[g+48>>2]=4;f=40;break g}G[g+48>>2]=8;break g}G[g+48>>2]=4;f=41;break g}G[g+48>>2]=8;f=81;break g}G[g+48>>2]=4;f=42;break g}G[g+48>>2]=8;f=82;break g}f=k+1|0;i=f+((j|0)==80)|0;a=H[i|0];x:{if(!a){break x}G[g+16>>2]=g+48;if((Qc(((a|0)!=40?h?f:k:i)+1|0,27698,g+16|0)|0)!=1){break x}f=16;if((j|0)==80|G[g+48>>2]<=G[g+220>>2]){break g}}G[g+48>>2]=G[g+220>>2];f=16;break g}G[g+48>>2]=1;f=14;break g}G[g+48>>2]=1;f=1;break g}G[g+48>>2]=1;f=11;break g}G[g+48>>2]=1;f=12;break g}G[g+48>>2]=8;f=83;break g}G[g+48>>2]=16;f=163;break g}G[g>>2]=a;a=g+48|0;Ya(a,81,67815,g);tb(5,a);f=262;G[e>>2]=262;break a}G[g+48>>2]=2;f=20}if(b){G[b>>2]=(j|0)==80?0-f|0:f}if(c){G[c>>2]=G[g+220>>2]}if(d){G[d>>2]=G[g+48>>2]}f=G[e>>2];break a}tb(5,46216)}f=261;G[e>>2]=261}Fa=g+224|0;return f}function Wk(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0;a:{b:{if(!e){if(c==1&d==0){break b}if((b|0)<=0){break a}while(1){f=(l<<1)+i|0;m=L[(l<<3)+a>>3]*c+d;c:{if(m<-32768.49){G[j>>2]=-11;e=32768;break c}if(m>32767.49){G[j>>2]=-11;e=32767;break c}e=~~m;if(O(m)<2147483648){break c}e=-2147483648}F[f>>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}l=a+6|0;d:{e:{if(!(c==1&d==0)){if((b|0)<=0){break a}if(!(O(d)<2147483648)){break e}n=~~d;break d}if((b|0)<=0){break a}while(1){f:{g:{h:{i:{n=I[l>>1]&32752;switch(((n|0)==32752?1:!n<<1)|0){case 0:break g;case 1:break i;default:break h}}G[h>>2]=1;if((e|0)==1){F[(k<<1)+i>>1]=f;break f}E[g+k|0]=1;break f}F[(k<<1)+i>>1]=0;break f}c=L[(k<<3)+a>>3];if(c<-32768.49){G[j>>2]=-11;F[(k<<1)+i>>1]=32768;break f}if(c>32767.49){G[j>>2]=-11;F[(k<<1)+i>>1]=32767;break f}o=(k<<1)+i|0;if(O(c)<2147483648){n=~~c}else{n=-2147483648}F[o>>1]=n}l=l+8|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}n=-2147483648}while(1){j:{k:{l:{m:{o=I[l>>1]&32752;switch(((o|0)==32752?1:!o<<1)|0){case 0:break k;case 1:break m;default:break l}}G[h>>2]=1;if((e|0)==1){F[(k<<1)+i>>1]=f;break j}E[g+k|0]=1;break j}if(d<-32768.49){G[j>>2]=-11;F[(k<<1)+i>>1]=32768;break j}if(d>32767.49){G[j>>2]=-11;F[(k<<1)+i>>1]=32767;break j}F[(k<<1)+i>>1]=n;break j}m=L[(k<<3)+a>>3]*c+d;if(m<-32768.49){G[j>>2]=-11;F[(k<<1)+i>>1]=32768;break j}if(m>32767.49){G[j>>2]=-11;F[(k<<1)+i>>1]=32767;break j}p=(k<<1)+i|0;if(O(m)<2147483648){o=~~m}else{o=-2147483648}F[p>>1]=o}l=l+8|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}while(1){f=(l<<1)+i|0;c=L[(l<<3)+a>>3];n:{if(c<-32768.49){G[j>>2]=-11;e=32768;break n}if(c>32767.49){G[j>>2]=-11;e=32767;break n}e=~~c;if(O(c)<2147483648){break n}e=-2147483648}F[f>>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}}}function Tp(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0;l=c==1&d==0;a:{b:{c:{if(!e){if(l){break c}l=0;if((b|0)<=0){break b}while(1){d:{e:{f=l<<2;n=+G[f+a>>2]*c+d;if(n<-2147483648.49){G[k>>2]=-11;break e}if(n>2147483647.49){G[k>>2]=-11;e=2147483647;break d}if(!(O(n)<2147483648)){break e}e=~~n;break d}e=-2147483648}G[f+j>>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break b}if(!l){if((b|0)<=0){break b}l=0;while(1){m=l<<2;o=G[m+a>>2];f:{if((o|0)==(f|0)){G[i>>2]=1;if((e|0)==1){G[j+m>>2]=g;break f}E[h+l|0]=1;break f}n=+(o|0)*c+d;if(n<-2147483648.49){G[k>>2]=-11;G[j+m>>2]=-2147483648;break f}if(n>2147483647.49){G[k>>2]=-11;G[j+m>>2]=2147483647;break f}o=j+m|0;if(O(n)<2147483648){m=~~n}else{m=-2147483648}G[o>>2]=m}l=l+1|0;if((l|0)!=(b|0)){continue}break}break b}if((b|0)<=0){break b}if((e|0)!=1){e=b&1;l=0;if((b|0)!=1){g=b&-2;b=0;while(1){k=l<<2;m=G[k+a>>2];g:{if((m|0)==(f|0)){G[i>>2]=1;E[h+l|0]=1;break g}G[j+k>>2]=m}k=l|1;m=k<<2;o=G[m+a>>2];h:{if((o|0)!=(f|0)){G[j+m>>2]=o;break h}G[i>>2]=1;E[h+k|0]=1}l=l+2|0;b=b+2|0;if((g|0)!=(b|0)){continue}break}}if(!e){break b}b=l<<2;a=G[b+a>>2];if((f|0)!=(a|0)){break a}G[i>>2]=1;E[h+l|0]=1;break b}h=b&1;l=0;if((b|0)!=1){k=b&-2;e=0;while(1){m=l<<2;b=G[m+a>>2];if((f|0)==(b|0)){G[i>>2]=1;b=g}G[j+m>>2]=b;m=(l|1)<<2;b=G[m+a>>2];if((f|0)==(b|0)){G[i>>2]=1;b=g}G[j+m>>2]=b;l=l+2|0;e=e+2|0;if((k|0)!=(e|0)){continue}break}}if(!h){break b}b=l<<2;a=G[b+a>>2];if((f|0)==(a|0)){G[i>>2]=1;a=g}break a}if((b|0)<=0){break b}g=b&3;e=0;l=0;if(b-1>>>0>=3){h=b&-4;b=0;while(1){f=l<<2;G[f+j>>2]=G[a+f>>2];i=f|4;G[i+j>>2]=G[a+i>>2];i=f|8;G[i+j>>2]=G[a+i>>2];f=f|12;G[f+j>>2]=G[a+f>>2];l=l+4|0;b=b+4|0;if((h|0)!=(b|0)){continue}break}}if(!g){break b}while(1){b=l<<2;G[b+j>>2]=G[a+b>>2];l=l+1|0;e=e+1|0;if((g|0)!=(e|0)){continue}break}}return}G[b+j>>2]=a}function Yk(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0;l=c==1&d==0;a:{b:{if(!e){if(l){break b}l=0;if((b|0)<=0){break a}while(1){f=(l<<1)+j|0;m=+G[(l<<2)+a>>2]*c+d;c:{if(m<-32768.49){G[k>>2]=-11;e=32768;break c}if(m>32767.49){G[k>>2]=-11;e=32767;break c}e=~~m;if(O(m)<2147483648){break c}e=-2147483648}F[f>>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if(!l){if((b|0)<=0){break a}l=0;while(1){n=G[(l<<2)+a>>2];d:{if((n|0)==(f|0)){G[i>>2]=1;if((e|0)==1){F[(l<<1)+j>>1]=g;break d}E[h+l|0]=1;break d}m=+(n|0)*c+d;if(m<-32768.49){G[k>>2]=-11;F[(l<<1)+j>>1]=32768;break d}if(m>32767.49){G[k>>2]=-11;F[(l<<1)+j>>1]=32767;break d}o=(l<<1)+j|0;if(O(m)<2147483648){n=~~m}else{n=-2147483648}F[o>>1]=n}l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}l=0;if((e|0)==1){while(1){e=G[(l<<2)+a>>2];e:{if((f|0)!=(e|0)){if((e|0)>=-32768){if((e|0)<=32767){break e}G[k>>2]=-11;e=32767;break e}G[k>>2]=-11;e=32768;break e}G[i>>2]=1;e=g}F[(l<<1)+j>>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break a}}while(1){e=G[(l<<2)+a>>2];f:{if((e|0)==(f|0)){G[i>>2]=1;E[h+l|0]=1;break f}if((e|0)<=-32769){G[k>>2]=-11;F[(l<<1)+j>>1]=32768;break f}if((e|0)>=32768){G[k>>2]=-11;F[(l<<1)+j>>1]=32767;break f}F[(l<<1)+j>>1]=e}l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}e=b&1;l=0;if((b|0)!=1){g=b&-2;f=0;while(1){b=G[(l<<2)+a>>2];g:{if((b|0)<=-32769){G[k>>2]=-11;b=32768;break g}if((b|0)<32768){break g}G[k>>2]=-11;b=32767}F[(l<<1)+j>>1]=b;h=l|1;b=G[(h<<2)+a>>2];h:{if((b|0)>=-32768){if((b|0)<=32767){break h}G[k>>2]=-11;b=32767;break h}G[k>>2]=-11;b=32768}F[(h<<1)+j>>1]=b;l=l+2|0;f=f+2|0;if((g|0)!=(f|0)){continue}break}}if(!e){break a}a=G[(l<<2)+a>>2];i:{if((a|0)>=-32768){if((a|0)<=32767){break i}G[k>>2]=-11;a=32767;break i}G[k>>2]=-11;a=32768}F[(l<<1)+j>>1]=a}}function Bp(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0;a:{b:{if(!e){if(c==1&d==0){break b}if((b|0)<=0){break a}while(1){f=(l<<2)+i|0;c:{d:{m=L[(l<<3)+a>>3]*c+d;if(m<-.49){G[j>>2]=-11;break d}if(m>0xfffffffffffff800){G[j>>2]=-11;e=-1;break c}if(!(m<4294967296&m>=0)){break d}e=~~m>>>0;break c}e=0}G[f>>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}l=a+6|0;e:{f:{if(!(c==1&d==0)){if((b|0)<=0){break a}if(!(d<4294967296&d>=0)){break f}n=~~d>>>0;break e}if((b|0)<=0){break a}while(1){g:{h:{i:{j:{n=I[l>>1]&32752;switch(((n|0)==32752?1:!n<<1)|0){case 0:break h;case 1:break j;default:break i}}G[h>>2]=1;if((e|0)==1){G[(k<<2)+i>>2]=f;break g}E[g+k|0]=1;break g}G[(k<<2)+i>>2]=0;break g}c=L[(k<<3)+a>>3];if(c<-.49){G[j>>2]=-11;G[(k<<2)+i>>2]=0;break g}if(c>0xfffffffffffff800){G[j>>2]=-11;G[(k<<2)+i>>2]=-1;break g}o=(k<<2)+i|0;if(c<4294967296&c>=0){n=~~c>>>0}else{n=0}G[o>>2]=n}l=l+8|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}n=0}while(1){k:{l:{m:{n:{o=I[l>>1]&32752;switch(((o|0)==32752?1:!o<<1)|0){case 0:break l;case 1:break n;default:break m}}G[h>>2]=1;if((e|0)==1){G[(k<<2)+i>>2]=f;break k}E[g+k|0]=1;break k}if(d<-.49){G[j>>2]=-11;G[(k<<2)+i>>2]=0;break k}if(d>0xfffffffffffff800){G[j>>2]=-11;G[(k<<2)+i>>2]=-1;break k}G[(k<<2)+i>>2]=n;break k}m=L[(k<<3)+a>>3]*c+d;if(m<-.49){G[j>>2]=-11;G[(k<<2)+i>>2]=0;break k}if(m>0xfffffffffffff800){G[j>>2]=-11;G[(k<<2)+i>>2]=-1;break k}p=(k<<2)+i|0;if(m<4294967296&m>=0){o=~~m>>>0}else{o=0}G[p>>2]=o}l=l+8|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}while(1){f=(l<<2)+i|0;o:{p:{c=L[(l<<3)+a>>3];if(c<-.49){G[j>>2]=-11;break p}if(c>0xfffffffffffff800){G[j>>2]=-11;e=-1;break o}if(!(c<4294967296&c>=0)){break p}e=~~c>>>0;break o}e=0}G[f>>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}}}function Cp(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=N(0),q=0;a:{b:{if(!e){if(c==1&d==0){break b}if((b|0)<=0){break a}while(1){c:{d:{f=l<<2;n=+K[f+a>>2]*c+d;if(n<-.49){G[j>>2]=-11;break d}if(n>0xfffffffffffff800){G[j>>2]=-11;e=-1;break c}if(!(n<4294967296&n>=0)){break d}e=~~n>>>0;break c}e=0}G[f+i>>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}l=a+2|0;e:{f:{if(!(c==1&d==0)){if((b|0)<=0){break a}if(!(d<4294967296&d>=0)){break f}m=~~d>>>0;break e}if((b|0)<=0){break a}while(1){g:{h:{i:{j:{m=I[l>>1]&32640;switch(((m|0)==32640?1:!m<<1)|0){case 0:break h;case 1:break j;default:break i}}G[h>>2]=1;if((e|0)==1){G[(k<<2)+i>>2]=f;break g}E[g+k|0]=1;break g}G[(k<<2)+i>>2]=0;break g}m=k<<2;p=K[m+a>>2];c=+p;if(c<-.49){G[j>>2]=-11;G[i+m>>2]=0;break g}if(c>0xfffffffffffff800){G[j>>2]=-11;G[i+m>>2]=-1;break g}o=i+m|0;if(p=N(0)){m=~~p>>>0}else{m=0}G[o>>2]=m}l=l+4|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}m=0}while(1){k:{l:{m:{n:{o=I[l>>1]&32640;switch(((o|0)==32640?1:!o<<1)|0){case 0:break l;case 1:break n;default:break m}}G[h>>2]=1;if((e|0)==1){G[(k<<2)+i>>2]=f;break k}E[g+k|0]=1;break k}if(d<-.49){G[j>>2]=-11;G[(k<<2)+i>>2]=0;break k}if(d>0xfffffffffffff800){G[j>>2]=-11;G[(k<<2)+i>>2]=-1;break k}G[(k<<2)+i>>2]=m;break k}o=k<<2;n=+K[o+a>>2]*c+d;if(n<-.49){G[j>>2]=-11;G[i+o>>2]=0;break k}if(n>0xfffffffffffff800){G[j>>2]=-11;G[(k<<2)+i>>2]=-1;break k}q=(k<<2)+i|0;if(n<4294967296&n>=0){o=~~n>>>0}else{o=0}G[q>>2]=o}l=l+4|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}while(1){o:{p:{f=l<<2;p=K[f+a>>2];c=+p;if(c<-.49){G[j>>2]=-11;break p}if(c>0xfffffffffffff800){G[j>>2]=-11;e=-1;break o}if(!(p=N(0))){break p}e=~~p>>>0;break o}e=0}G[f+i>>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}}}function Wi(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=N(0),m=N(0);a:{if(!e){if(!(c==1&d==0)){if((b|0)<=0){break a}if((b|0)!=1){e=b&-2;while(1){K[(j<<2)+i>>2]=L[(j<<3)+a>>3]*c+d;g=j|1;K[(g<<2)+i>>2]=L[(g<<3)+a>>3]*c+d;j=j+2|0;k=k+2|0;if((e|0)!=(k|0)){continue}break}}if(!(b&1)){break a}K[(j<<2)+i>>2]=L[(j<<3)+a>>3]*c+d;return}if((b|0)<=0){break a}e=b&3;if(b-1>>>0>=3){g=b&-4;b=0;while(1){K[(j<<2)+i>>2]=L[(j<<3)+a>>3];h=j|1;K[(h<<2)+i>>2]=L[(h<<3)+a>>3];h=j|2;K[(h<<2)+i>>2]=L[(h<<3)+a>>3];h=j|3;K[(h<<2)+i>>2]=L[(h<<3)+a>>3];j=j+4|0;b=b+4|0;if((g|0)!=(b|0)){continue}break}}if(!e){break a}while(1){K[(j<<2)+i>>2]=L[(j<<3)+a>>3];j=j+1|0;k=k+1|0;if((e|0)!=(k|0)){continue}break}break a}j=a+6|0;b:{if(!(c==1&d==0)){if((b|0)<=0){break a}m=N(d);if((e|0)!=1){break b}while(1){l=m;c:{d:{e:{e=I[j>>1]&32752;switch(((e|0)==32752?1:!e<<1)|0){case 0:break d;case 1:break e;default:break c}}G[h>>2]=1;l=f;break c}l=N(L[(k<<3)+a>>3]*c+d)}K[(k<<2)+i>>2]=l;j=j+8|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)==1){while(1){l=N(0);f:{g:{h:{e=I[j>>1]&32752;switch(((e|0)==32752?1:!e<<1)|0){case 0:break g;case 1:break h;default:break f}}G[h>>2]=1;l=f;break f}l=N(L[(k<<3)+a>>3])}K[(k<<2)+i>>2]=l;j=j+8|0;k=k+1|0;if((k|0)!=(b|0)){continue}break a}}while(1){i:{j:{k:{l:{e=I[j>>1]&32752;switch(((e|0)==32752?1:!e<<1)|0){case 0:break j;case 1:break l;default:break k}}G[h>>2]=1;E[g+k|0]=1;break i}G[(k<<2)+i>>2]=0;break i}K[(k<<2)+i>>2]=L[(k<<3)+a>>3]}j=j+8|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}while(1){m:{n:{o:{p:{e=I[j>>1]&32752;switch(((e|0)==32752?1:!e<<1)|0){case 0:break n;case 1:break p;default:break o}}G[h>>2]=1;E[g+k|0]=1;break m}K[(k<<2)+i>>2]=m;break m}K[(k<<2)+i>>2]=L[(k<<3)+a>>3]*c+d}j=j+8|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}}}function Ip(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=N(0),o=0,p=0,q=0;a:{b:{if(!e){if(c==1&d==0){break b}if((b|0)<=0){break a}while(1){f=(l<<1)+i|0;c:{d:{m=+K[(l<<2)+a>>2]*c+d;if(m<-.49){G[j>>2]=-11;break d}if(m>65535.49){G[j>>2]=-11;e=65535;break c}if(!(m<4294967296&m>=0)){break d}e=~~m>>>0;break c}e=0}F[f>>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}l=a+2|0;e:{f:{if(!(c==1&d==0)){if((b|0)<=0){break a}if(!(d<4294967296&d>=0)){break f}o=~~d>>>0;break e}if((b|0)<=0){break a}while(1){g:{h:{i:{j:{o=I[l>>1]&32640;switch(((o|0)==32640?1:!o<<1)|0){case 0:break h;case 1:break j;default:break i}}G[h>>2]=1;if((e|0)==1){F[(k<<1)+i>>1]=f;break g}E[g+k|0]=1;break g}F[(k<<1)+i>>1]=0;break g}n=K[(k<<2)+a>>2];c=+n;if(c<-.49){G[j>>2]=-11;F[(k<<1)+i>>1]=0;break g}if(c>65535.49){G[j>>2]=-11;F[(k<<1)+i>>1]=65535;break g}p=(k<<1)+i|0;if(n=N(0)){o=~~n>>>0}else{o=0}F[p>>1]=o}l=l+4|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}o=0}while(1){k:{l:{m:{n:{p=I[l>>1]&32640;switch(((p|0)==32640?1:!p<<1)|0){case 0:break l;case 1:break n;default:break m}}G[h>>2]=1;if((e|0)==1){F[(k<<1)+i>>1]=f;break k}E[g+k|0]=1;break k}if(d<-.49){G[j>>2]=-11;F[(k<<1)+i>>1]=0;break k}if(d>65535.49){G[j>>2]=-11;F[(k<<1)+i>>1]=65535;break k}F[(k<<1)+i>>1]=o;break k}m=+K[(k<<2)+a>>2]*c+d;if(m<-.49){G[j>>2]=-11;F[(k<<1)+i>>1]=0;break k}if(m>65535.49){G[j>>2]=-11;F[(k<<1)+i>>1]=65535;break k}q=(k<<1)+i|0;if(m<4294967296&m>=0){p=~~m>>>0}else{p=0}F[q>>1]=p}l=l+4|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}while(1){f=(l<<1)+i|0;o:{p:{n=K[(l<<2)+a>>2];c=+n;if(c<-.49){G[j>>2]=-11;break p}if(c>65535.49){G[j>>2]=-11;e=65535;break o}if(!(n=N(0))){break p}e=~~n>>>0;break o}e=0}F[f>>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}}}function bl(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0;a:{if(!e){if(!(c==1&d==0)){if((b|0)<=0){break a}if((b|0)!=1){e=b&-2;while(1){L[(j<<3)+i>>3]=+K[(j<<2)+a>>2]*c+d;g=j|1;L[(g<<3)+i>>3]=+K[(g<<2)+a>>2]*c+d;j=j+2|0;k=k+2|0;if((e|0)!=(k|0)){continue}break}}if(!(b&1)){break a}L[(j<<3)+i>>3]=+K[(j<<2)+a>>2]*c+d;return}if((b|0)<=0){break a}e=b&3;if(b-1>>>0>=3){g=b&-4;b=0;while(1){L[(j<<3)+i>>3]=K[(j<<2)+a>>2];h=j|1;L[(h<<3)+i>>3]=K[(h<<2)+a>>2];h=j|2;L[(h<<3)+i>>3]=K[(h<<2)+a>>2];h=j|3;L[(h<<3)+i>>3]=K[(h<<2)+a>>2];j=j+4|0;b=b+4|0;if((g|0)!=(b|0)){continue}break}}if(!e){break a}while(1){L[(j<<3)+i>>3]=K[(j<<2)+a>>2];j=j+1|0;k=k+1|0;if((e|0)!=(k|0)){continue}break}break a}j=a+2|0;b:{if(!(c==1&d==0)){if((b|0)<=0){break a}if((e|0)!=1){break b}while(1){l=d;c:{d:{e:{e=I[j>>1]&32640;switch(((e|0)==32640?1:!e<<1)|0){case 0:break d;case 1:break e;default:break c}}G[h>>2]=1;l=f;break c}l=+K[(k<<2)+a>>2]*c+d}L[(k<<3)+i>>3]=l;j=j+4|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)==1){while(1){d=0;f:{g:{h:{e=I[j>>1]&32640;switch(((e|0)==32640?1:!e<<1)|0){case 0:break g;case 1:break h;default:break f}}G[h>>2]=1;d=f;break f}d=+K[(k<<2)+a>>2]}L[(k<<3)+i>>3]=d;j=j+4|0;k=k+1|0;if((k|0)!=(b|0)){continue}break a}}while(1){i:{j:{k:{l:{e=I[j>>1]&32640;switch(((e|0)==32640?1:!e<<1)|0){case 0:break j;case 1:break l;default:break k}}G[h>>2]=1;E[g+k|0]=1;break i}e=(k<<3)+i|0;G[e>>2]=0;G[e+4>>2]=0;break i}L[(k<<3)+i>>3]=K[(k<<2)+a>>2]}j=j+4|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}while(1){m:{n:{o:{p:{e=I[j>>1]&32640;switch(((e|0)==32640?1:!e<<1)|0){case 0:break n;case 1:break p;default:break o}}G[h>>2]=1;E[g+k|0]=1;break m}L[(k<<3)+i>>3]=d;break m}L[(k<<3)+i>>3]=+K[(k<<2)+a>>2]*c+d}j=j+4|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}}}function Np(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0;l=c==1&d==0;a:{b:{if(!e){if(l){break b}l=0;if((b|0)<=0){break a}while(1){f=(l<<1)+j|0;n=+H[a+l|0]*c+d;c:{if(n<-32768.49){G[k>>2]=-11;e=32768;break c}if(n>32767.49){G[k>>2]=-11;e=32767;break c}e=~~n;if(O(n)<2147483648){break c}e=-2147483648}F[f>>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if(!l){if((b|0)<=0){break a}l=0;while(1){m=H[a+l|0];d:{if((m|0)==(f|0)){G[i>>2]=1;if((e|0)==1){F[(l<<1)+j>>1]=g;break d}E[h+l|0]=1;break d}n=+(m>>>0)*c+d;if(n<-32768.49){G[k>>2]=-11;F[(l<<1)+j>>1]=32768;break d}if(n>32767.49){G[k>>2]=-11;F[(l<<1)+j>>1]=32767;break d}o=(l<<1)+j|0;if(O(n)<2147483648){m=~~n}else{m=-2147483648}F[o>>1]=m}l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)!=1){g=b&1;l=0;if((b|0)!=1){k=b&-2;b=0;while(1){e=H[a+l|0];e:{if((e|0)==(f|0)){G[i>>2]=1;E[h+l|0]=1;break e}F[(l<<1)+j>>1]=e}e=l|1;m=H[e+a|0];f:{if((m|0)!=(f|0)){F[(e<<1)+j>>1]=m;break f}G[i>>2]=1;E[e+h|0]=1}l=l+2|0;b=b+2|0;if((k|0)!=(b|0)){continue}break}}if(!g){break a}a=H[a+l|0];if((a|0)!=(f|0)){F[(l<<1)+j>>1]=a;return}G[i>>2]=1;E[h+l|0]=1;break a}h=b&1;l=0;if((b|0)!=1){k=b&-2;e=0;while(1){m=(l<<1)+j|0;b=H[a+l|0];if((b|0)==(f|0)){G[i>>2]=1;b=g}F[m>>1]=b;m=l|1;b=H[m+a|0];if((f|0)==(b|0)){G[i>>2]=1;b=g}F[(m<<1)+j>>1]=b;l=l+2|0;e=e+2|0;if((k|0)!=(e|0)){continue}break}}if(!h){break a}b=(l<<1)+j|0;a=H[a+l|0];if((a|0)==(f|0)){G[i>>2]=1}else{g=a}F[b>>1]=g;return}if((b|0)<=0){break a}e=b&3;f=0;l=0;if(b-1>>>0>=3){g=b&-4;b=0;while(1){F[(l<<1)+j>>1]=H[a+l|0];h=l|1;F[(h<<1)+j>>1]=H[a+h|0];h=l|2;F[(h<<1)+j>>1]=H[a+h|0];h=l|3;F[(h<<1)+j>>1]=H[a+h|0];l=l+4|0;b=b+4|0;if((g|0)!=(b|0)){continue}break}}if(!e){break a}while(1){F[(l<<1)+j>>1]=H[a+l|0];l=l+1|0;f=f+1|0;if((e|0)!=(f|0)){continue}break}}}function Ep(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0;l=c==1&d==0;a:{b:{if(!e){if(l){break b}l=0;if((b|0)<=0){break a}while(1){f=(l<<2)+j|0;c:{d:{n=+H[a+l|0]*c+d;if(n<-.49){G[k>>2]=-11;break d}if(n>0xfffffffffffff800){G[k>>2]=-11;e=-1;break c}if(!(n<4294967296&n>=0)){break d}e=~~n>>>0;break c}e=0}G[f>>2]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if(!l){if((b|0)<=0){break a}l=0;while(1){m=H[a+l|0];e:{if((m|0)==(f|0)){G[i>>2]=1;if((e|0)==1){G[(l<<2)+j>>2]=g;break e}E[h+l|0]=1;break e}n=+(m>>>0)*c+d;if(n<-.49){G[k>>2]=-11;G[(l<<2)+j>>2]=0;break e}if(n>0xfffffffffffff800){G[k>>2]=-11;G[(l<<2)+j>>2]=-1;break e}o=(l<<2)+j|0;if(n<4294967296&n>=0){m=~~n>>>0}else{m=0}G[o>>2]=m}l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)!=1){g=b&1;l=0;if((b|0)!=1){k=b&-2;b=0;while(1){e=H[a+l|0];f:{if((e|0)==(f|0)){G[i>>2]=1;E[h+l|0]=1;break f}G[(l<<2)+j>>2]=e}e=l|1;m=H[e+a|0];g:{if((m|0)!=(f|0)){G[(e<<2)+j>>2]=m;break g}G[i>>2]=1;E[e+h|0]=1}l=l+2|0;b=b+2|0;if((k|0)!=(b|0)){continue}break}}if(!g){break a}a=H[a+l|0];if((a|0)!=(f|0)){G[(l<<2)+j>>2]=a;return}G[i>>2]=1;E[h+l|0]=1;break a}h=b&1;l=0;if((b|0)!=1){k=b&-2;e=0;while(1){m=(l<<2)+j|0;b=H[a+l|0];if((b|0)==(f|0)){G[i>>2]=1;b=g}G[m>>2]=b;m=l|1;b=H[m+a|0];if((f|0)==(b|0)){G[i>>2]=1;b=g}G[(m<<2)+j>>2]=b;l=l+2|0;e=e+2|0;if((k|0)!=(e|0)){continue}break}}if(!h){break a}b=(l<<2)+j|0;a=H[a+l|0];if((a|0)==(f|0)){G[i>>2]=1}else{g=a}G[b>>2]=g;return}if((b|0)<=0){break a}e=b&3;f=0;l=0;if(b-1>>>0>=3){g=b&-4;b=0;while(1){G[(l<<2)+j>>2]=H[a+l|0];h=l|1;G[(h<<2)+j>>2]=H[a+h|0];h=l|2;G[(h<<2)+j>>2]=H[a+h|0];h=l|3;G[(h<<2)+j>>2]=H[a+h|0];l=l+4|0;b=b+4|0;if((g|0)!=(b|0)){continue}break}}if(!e){break a}while(1){G[(l<<2)+j>>2]=H[a+l|0];l=l+1|0;f=f+1|0;if((e|0)!=(f|0)){continue}break}}}function Cj(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;i=Fa-48|0;Fa=i;G[d+8>>2]=0;G[d+12>>2]=0;G[d>>2]=0;G[d+4>>2]=1072693248;G[d+16>>2]=0;G[d+20>>2]=0;G[d+24>>2]=0;G[d+28>>2]=0;G[d+40>>2]=0;G[d+44>>2]=0;G[d+32>>2]=0;G[d+36>>2]=1072693248;G[d+48>>2]=0;G[d+52>>2]=0;G[d+56>>2]=0;G[d+60>>2]=0;G[d+64>>2]=0;G[d+68>>2]=1072693248;G[i+4>>2]=3;p=i+4|0;G[p+4>>2]=2;G[p+8>>2]=3;L[i+32>>3]=c;L[i+24>>3]=b;L[i+16>>3]=a;p=G[i+4>>2];q=L[d+40>>3];k=L[d+16>>3];r=L[d+56>>3];s=L[d+32>>3];l=L[d+8>>3];t=L[d+24>>3];u=L[d>>3];b=L[i+16>>3];a=eb(b);c=ib(b);a:{b:{c:{switch(p-1|0){case 0:g=-c;e=c;f=a;b=a;c=0;a=1;break a;case 1:m=-c;f=a;j=c;c=0;b=1;break b;default:break c}}h=-c;f=1;b=a}}v=f+(g*q+(j*k+0));w=f*r+(g*s+(j*l+0));x=f*0+(g*t+(j*u+0));y=e+(b*q+(h*k+0));z=e*r+(b*s+(h*l+0));n=e*0+(b*t+(h*u+0));k=m+(c*q+(a*k+0));l=m*r+(c*s+(a*l+0));m=m*0+(c*t+(a*u+0));p=G[i+8>>2];a=L[i+24>>3];c=eb(a);e=ib(a);d:{e:{switch(p-1|0){case 1:o=-e;f=1;g=0;a=c;b=e;h=0;e=0;j=0;break d;case 0:g=-e;b=0;h=e;a=c;f=c;e=0;c=1;j=0;break d;default:break e}}g=0;a=1;b=0;h=0;f=c;j=-e}A=a*v+(g*y+(b*k+0));q=a*w+(g*z+(b*l+0));r=a*x+(g*n+(b*m+0));a=j;s=h*v+(f*y+(a*k+0));t=h*w+(f*z+(a*l+0));u=h*x+(f*n+(a*m+0));k=o*v+(e*y+(c*k+0));l=o*w+(e*z+(c*l+0));m=o*x+(e*n+(c*m+0));p=G[i+12>>2];a=L[i+32>>3];c=eb(a);e=ib(a);f:{g:{switch(p-1|0){case 1:o=-e;h=1;n=0;g=c;j=e;f=0;e=0;a=0;break f;case 0:n=-e;j=0;f=e;g=c;h=c;o=0;e=0;c=1;a=0;break f;default:break g}}n=0;g=1;j=0;f=0;h=c;o=0;a=-e}L[d+24>>3]=f*r+(h*u+(a*m+0));L[d>>3]=o*r+(e*u+(c*m+0));L[d+56>>3]=g*q+(n*t+(j*l+0));L[d+32>>3]=f*q+(h*t+(a*l+0));L[d+8>>3]=o*q+(e*t+(c*l+0));L[d+64>>3]=g*A+(n*s+(j*k+0));L[d+48>>3]=g*r+(n*u+(j*m+0));L[d+40>>3]=f*A+(h*s+(a*k+0));L[d+16>>3]=o*A+(e*s+(c*k+0));Fa=i+48|0}function Rm(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0;a:{p=h+1;b:{if(O(p)<2147483648){k=~~p;break b}k=-2147483648}k=(k|0)>1?k:1;l=!b;p=j+1;c:{if(O(p)<2147483648){o=~~p;break c}o=-2147483648}n=o-1|0;n=(d|0)>(n|0)?n:d;if(l|((k|0)>(n|0)|(n|0)<=0)){break a}i=(g-i)/(h-j);h=(+(k|0)-h)*i+g;o=c+1|0;if((f|0)==1){f=G[a+48>>2];l=G[a+44>>2];while(1){a=k;k=lb(1,8);g=h+1;d:{if(O(g)<2147483648){d=~~g;break d}d=-2147483648}d=(d|0)>1?d:1;m=(c|0)<(d|0)?o:d;G[k+4>>2]=m;d=(a|0)<(l|0)?l:a;e=(((d|0)<(f|0)?d:f)<<2)+b|0;d=G[e>>2];e:{if(!d){d=0;break e}if((m|0)>2]){break e}while(1){e=d;d=G[d>>2];if(!d){d=0;break e}if((m|0)>G[d+4>>2]){continue}break}}G[k>>2]=d;G[e>>2]=k;k=a+1|0;h=i+h;if((a|0)!=(n|0)){continue}break}break a}if(!e){while(1){f=k;e=G[a+48>>2];k=G[a+44>>2];l=lb(1,8);g=h+1;f:{if(O(g)<2147483648){d=~~g;break f}d=-2147483648}d=(d|0)>1?d:1;m=(c|0)<(d|0)?o:d;G[l+4>>2]=m;d=(f|0)<(k|0)?k:f;k=((d|0)<(e|0)?d:e)<<2;e=k+b|0;d=G[e>>2];g:{if(!d){d=0;break g}if((m|0)>2]){break g}while(1){e=d;d=G[d>>2];if(!d){d=0;break g}if((m|0)>G[d+4>>2]){continue}break}}G[l>>2]=d;G[e>>2]=l;G[k+G[a+56>>2]>>2]=G[a+36>>2];G[k+G[a+60>>2]>>2]=G[a+40>>2];k=f+1|0;h=i+h;if((f|0)!=(n|0)){continue}break a}}while(1){f=G[a+48>>2];l=G[a+44>>2];m=lb(1,8);g=h+1;h:{if(O(g)<2147483648){d=~~g;break h}d=-2147483648}d=(d|0)>1?d:1;e=(c|0)<(d|0)?o:d;G[m+4>>2]=e;d=(k|0)<(l|0)?l:k;l=((d|0)<(f|0)?d:f)<<2;f=l+b|0;d=G[f>>2];i:{if(!d){d=0;break i}if((e|0)>2]){break i}while(1){f=d;d=G[d>>2];if(!d){d=0;break i}if((e|0)>G[d+4>>2]){continue}break}}G[m>>2]=d;G[f>>2]=m;d=l+G[a+56>>2]|0;if((e|0)<=G[d>>2]){f=d;d=G[a+36>>2];G[f>>2]=(d|0)>(e|0)?d:e}d=l+G[a+60>>2]|0;if((e|0)>=G[d>>2]){f=d;d=G[a+40>>2];G[f>>2]=(d|0)<(e|0)?d:e}h=i+h;d=(k|0)!=(n|0);k=k+1|0;if(d){continue}break}}}function Jp(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0;l=c==1&d==0;a:{b:{if(!e){if(l){break b}l=0;if((b|0)<=0){break a}while(1){f=(l<<1)+j|0;c:{d:{n=+H[a+l|0]*c+d;if(n<-.49){G[k>>2]=-11;break d}if(n>65535.49){G[k>>2]=-11;e=65535;break c}if(!(n<4294967296&n>=0)){break d}e=~~n>>>0;break c}e=0}F[f>>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if(!l){if((b|0)<=0){break a}l=0;while(1){m=H[a+l|0];e:{if((m|0)==(f|0)){G[i>>2]=1;if((e|0)==1){F[(l<<1)+j>>1]=g;break e}E[h+l|0]=1;break e}n=+(m>>>0)*c+d;if(n<-.49){G[k>>2]=-11;F[(l<<1)+j>>1]=0;break e}if(n>65535.49){G[k>>2]=-11;F[(l<<1)+j>>1]=65535;break e}o=(l<<1)+j|0;if(n<4294967296&n>=0){m=~~n>>>0}else{m=0}F[o>>1]=m}l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)!=1){g=b&1;l=0;if((b|0)!=1){k=b&-2;b=0;while(1){e=H[a+l|0];f:{if((e|0)==(f|0)){G[i>>2]=1;E[h+l|0]=1;break f}F[(l<<1)+j>>1]=e}e=l|1;m=H[e+a|0];g:{if((m|0)!=(f|0)){F[(e<<1)+j>>1]=m;break g}G[i>>2]=1;E[e+h|0]=1}l=l+2|0;b=b+2|0;if((k|0)!=(b|0)){continue}break}}if(!g){break a}a=H[a+l|0];if((a|0)!=(f|0)){F[(l<<1)+j>>1]=a;return}G[i>>2]=1;E[h+l|0]=1;break a}h=b&1;l=0;if((b|0)!=1){k=b&-2;e=0;while(1){m=(l<<1)+j|0;b=H[a+l|0];if((b|0)==(f|0)){G[i>>2]=1;b=g}F[m>>1]=b;m=l|1;b=H[m+a|0];if((f|0)==(b|0)){G[i>>2]=1;b=g}F[(m<<1)+j>>1]=b;l=l+2|0;e=e+2|0;if((k|0)!=(e|0)){continue}break}}if(!h){break a}b=(l<<1)+j|0;a=H[a+l|0];if((a|0)==(f|0)){G[i>>2]=1}else{g=a}F[b>>1]=g;return}if((b|0)<=0){break a}e=b&3;f=0;l=0;if(b-1>>>0>=3){g=b&-4;b=0;while(1){F[(l<<1)+j>>1]=H[a+l|0];h=l|1;F[(h<<1)+j>>1]=H[a+h|0];h=l|2;F[(h<<1)+j>>1]=H[a+h|0];h=l|3;F[(h<<1)+j>>1]=H[a+h|0];l=l+4|0;b=b+4|0;if((g|0)!=(b|0)){continue}break}}if(!e){break a}while(1){F[(l<<1)+j>>1]=H[a+l|0];l=l+1|0;f=f+1|0;if((e|0)!=(f|0)){continue}break}}}function Hp(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0,p=0;a:{b:{if(!e){if(c==1&d==0){break b}if((b|0)<=0){break a}while(1){f=(l<<1)+i|0;c:{d:{m=L[(l<<3)+a>>3]*c+d;if(m<-.49){G[j>>2]=-11;break d}if(m>65535.49){G[j>>2]=-11;e=65535;break c}if(!(m<4294967296&m>=0)){break d}e=~~m>>>0;break c}e=0}F[f>>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}l=a+6|0;e:{f:{if(!(c==1&d==0)){if((b|0)<=0){break a}if(!(d<4294967296&d>=0)){break f}n=~~d>>>0;break e}if((b|0)<=0){break a}while(1){g:{h:{i:{j:{n=I[l>>1]&32752;switch(((n|0)==32752?1:!n<<1)|0){case 0:break h;case 1:break j;default:break i}}G[h>>2]=1;if((e|0)==1){F[(k<<1)+i>>1]=f;break g}E[g+k|0]=1;break g}F[(k<<1)+i>>1]=0;break g}c=L[(k<<3)+a>>3];if(c<-.49){G[j>>2]=-11;F[(k<<1)+i>>1]=0;break g}if(c>65535.49){G[j>>2]=-11;F[(k<<1)+i>>1]=65535;break g}o=(k<<1)+i|0;if(c<4294967296&c>=0){n=~~c>>>0}else{n=0}F[o>>1]=n}l=l+8|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}n=0}while(1){k:{l:{m:{n:{o=I[l>>1]&32752;switch(((o|0)==32752?1:!o<<1)|0){case 0:break l;case 1:break n;default:break m}}G[h>>2]=1;if((e|0)==1){F[(k<<1)+i>>1]=f;break k}E[g+k|0]=1;break k}if(d<-.49){G[j>>2]=-11;F[(k<<1)+i>>1]=0;break k}if(d>65535.49){G[j>>2]=-11;F[(k<<1)+i>>1]=65535;break k}F[(k<<1)+i>>1]=n;break k}m=L[(k<<3)+a>>3]*c+d;if(m<-.49){G[j>>2]=-11;F[(k<<1)+i>>1]=0;break k}if(m>65535.49){G[j>>2]=-11;F[(k<<1)+i>>1]=65535;break k}p=(k<<1)+i|0;if(m<4294967296&m>=0){o=~~m>>>0}else{o=0}F[p>>1]=o}l=l+8|0;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}while(1){f=(l<<1)+i|0;o:{p:{c=L[(l<<3)+a>>3];if(c<-.49){G[j>>2]=-11;break p}if(c>65535.49){G[j>>2]=-11;e=65535;break o}if(!(c<4294967296&c>=0)){break p}e=~~c>>>0;break o}e=0}F[f>>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}}}function Yn(a,b,c,d,e,f,g){var h=0,i=0,j=0,k=0,l=0;h=Fa-96|0;Fa=h;a:{b:{c:{d:{e:{if(G[g>>2]<=0){i=67;f:{j=H[a|0];switch(j-39|0){case 0:break b;case 1:break d;default:break f}}g:{switch(j-70|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:break c;case 0:case 14:break e;default:break g}}if(j){break c}G[g>>2]=204}i=H[b|0];break a}i=76;break b}i=88;break b}i=70;if(jb(a,46)){break b}if(jb(a,69)){break b}i=jb(a,68)?70:73}E[b|0]=i}h:{i:{switch((i&255)-70|0){case 3:if(G[g>>2]>0){break h}G[48624]=0;G[c>>2]=0;k=c,l=nc(a,h+92|0,10),G[k>>2]=l;if((H[G[h+92>>2]]|32)!=32){G[g>>2]=407}if(G[48624]!=68){break h}b=H[67017]|H[67018]<<8|(H[67019]<<16|H[67020]<<24);c=H[67013]|H[67014]<<8|(H[67015]<<16|H[67016]<<24);F[h+46>>1]=c;F[h+48>>1]=c>>>16;F[h+50>>1]=b;F[h+52>>1]=b>>>16;b=H[67011]|H[67012]<<8|(H[67013]<<16|H[67014]<<24);G[h+40>>2]=H[67007]|H[67008]<<8|(H[67009]<<16|H[67010]<<24);G[h+44>>2]=b;b=H[67003]|H[67004]<<8|(H[67005]<<16|H[67006]<<24);G[h+32>>2]=H[66999]|H[67e3]<<8|(H[67001]<<16|H[67002]<<24);G[h+36>>2]=b;b=H[66995]|H[66996]<<8|(H[66997]<<16|H[66998]<<24);G[h+24>>2]=H[66991]|H[66992]<<8|(H[66993]<<16|H[66994]<<24);G[h+28>>2]=b;b=H[66987]|H[66988]<<8|(H[66989]<<16|H[66990]<<24);G[h+16>>2]=H[66983]|H[66984]<<8|(H[66985]<<16|H[66986]<<24);G[h+20>>2]=b;b=H[66979]|H[66980]<<8|(H[66981]<<16|H[66982]<<24);G[h+8>>2]=H[66975]|H[66976]<<8|(H[66977]<<16|H[66978]<<24);G[h+12>>2]=b;b=H[66971]|H[66972]<<8|(H[66973]<<16|H[66974]<<24);G[h>>2]=H[66967]|H[66968]<<8|(H[66969]<<16|H[66970]<<24);G[h+4>>2]=b;tb(5,qb(h,a,25));G[g>>2]=412;G[48624]=0;break h;case 0:me(a,f,g);break h;case 6:if(G[g>>2]>0){break h}G[d>>2]=H[a|0]==84;break h;default:break i}}fd(a,e,g)}Fa=h+96|0}function Ug(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;p=Fa-16|0;Fa=p;if(G[321436]){m=G[24367];hb(88965,23,1,m);$a(m)}if(G[321436]){m=G[24367];hb(88746,39,1,m);$a(m)}a:{if(a==d){L[e>>3]=b;L[f>>3]=c;break a}if(L[23801]!=a|L[23802]!=d){G[934876]=442745336;G[934877]=1078765020;G[934878]=-1571644103;G[934879]=1066524486;G[934882]=-1291874403;G[934883]=1054102949;L[23801]=a;L[23802]=d;d=(d-a)*.01;L[467440]=d;a=(a+-2e3)*.01;g=(d*(d*-.041833)*d+((a*-217e-6*a+(a*-.8533+2004.3109))*d-d*(d*(a*217e-6+.42665))))/3600*.017453292519943295;h=eb(g);L[467458]=h;l=(a*-139e-6*a+(a*1.39656+2306.2181))*d;i=(d*(d*.017998)*d+(l+d*(d*(a*-344e-6+.30188))))/3600*.017453292519943295;j=eb(i);g=ib(g);L[467454]=j*g;i=ib(i);k=-i;L[467456]=g*k;d=(d*(d*.018203)*d+(l+d*(d*(a*66e-6+1.09468))))/3600*.017453292519943295;a=eb(d);g=-g;L[467446]=a*g;d=ib(d);L[467452]=d*g;g=j*h;L[467442]=a*g-d*i;L[467448]=g*d+i*a;h=h*k;L[467444]=a*h-d*j;L[467450]=h*d+j*a;a=.017453292519943295}else{a=L[467439]}d=a*b;b=ib(d);a=a*c;h=eb(a);j=h*0;g=eb(d);l=ib(a);k=l*-0;c=L[467441];a=(j*g+b*k)*c;n=L[467452];d=j*c;i=L[467440];l=d*i+l;q=L[467448];j=(g*k-j*b)*c;g=j*i+h*g;r=L[467450];b=a*i+b*h;i=n*l+(q*g+r*b);s=L[467446];t=L[467442];u=L[467444];k=s*l+(t*g+u*b);h=Db(i,k);o=L[467458];v=L[467454];w=L[467456];g=o*l+(v*g+w*b);k=k*k+i*i;i=Db(g,V(k));b=eb(i);l=ib(h);g=V(g*g+k);k=(o*d+(v*j+a*w))/g;o=eb(h);n=(n*d+(q*j+a*r))/g;a=(s*d+(t*j+a*u))/g;d=k*0+(b*o*n-a*(l*b));g=a;a=ib(i);j=g*(o*-a)-l*a*n;a=h;h=L[467438];a=a*h;if(a<0){while(1){a=a+360;if(a<0){continue}break}}L[e>>3]=a;if(a>360){while(1){a=a+-360;if(a>360){continue}break}L[e>>3]=a}j=(k*b+j)/c;L[f>>3]=R(Q(i*h,90),-90);h=d/(b*(b*c))/15}L[p+8>>3]=h;L[p>>3]=j;Fa=p+16|0}function Vk(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0;l=c==1&d==0;a:{b:{if(!e){if(l){break b}l=0;if((b|0)<=0){break a}while(1){f=(l<<1)+j|0;c:{d:{m=+G[(l<<2)+a>>2]*c+d;if(m<-.49){G[k>>2]=-11;break d}if(m>65535.49){G[k>>2]=-11;e=65535;break c}if(!(m<4294967296&m>=0)){break d}e=~~m>>>0;break c}e=0}F[f>>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if(!l){if((b|0)<=0){break a}l=0;while(1){n=G[(l<<2)+a>>2];e:{if((n|0)==(f|0)){G[i>>2]=1;if((e|0)==1){F[(l<<1)+j>>1]=g;break e}E[h+l|0]=1;break e}m=+(n|0)*c+d;if(m<-.49){G[k>>2]=-11;F[(l<<1)+j>>1]=0;break e}if(m>65535.49){G[k>>2]=-11;F[(l<<1)+j>>1]=65535;break e}o=(l<<1)+j|0;if(m<4294967296&m>=0){n=~~m>>>0}else{n=0}F[o>>1]=n}l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}l=0;if((e|0)==1){while(1){e=G[(l<<2)+a>>2];f:{if((f|0)!=(e|0)){if((e|0)>=0){if(e>>>0<=65535){break f}G[k>>2]=-11;e=65535;break f}G[k>>2]=-11;e=0;break f}G[i>>2]=1;e=g}F[(l<<1)+j>>1]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break a}}while(1){e=G[(l<<2)+a>>2];g:{if((e|0)==(f|0)){G[i>>2]=1;E[h+l|0]=1;break g}if((e|0)<0){G[k>>2]=-11;F[(l<<1)+j>>1]=0;break g}if(e>>>0>=65536){G[k>>2]=-11;F[(l<<1)+j>>1]=65535;break g}F[(l<<1)+j>>1]=e}l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}e=b&1;l=0;if((b|0)!=1){g=b&-2;f=0;while(1){b=G[(l<<2)+a>>2];h:{if((b|0)<0){G[k>>2]=-11;b=0;break h}if(b>>>0<65536){break h}G[k>>2]=-11;b=65535}F[(l<<1)+j>>1]=b;h=l|1;b=G[(h<<2)+a>>2];i:{if((b|0)>=0){if(b>>>0<=65535){break i}G[k>>2]=-11;b=65535;break i}G[k>>2]=-11;b=0}F[(h<<1)+j>>1]=b;l=l+2|0;f=f+2|0;if((g|0)!=(f|0)){continue}break}}if(!e){break a}a=G[(l<<2)+a>>2];j:{if((a|0)>=0){if(a>>>0<=65535){break j}G[k>>2]=-11;a=65535;break j}G[k>>2]=-11;a=0}F[(l<<1)+j>>1]=a}}function ng(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;p=Fa-16|0;Fa=p;if(G[321436]){m=G[24367];hb(89024,26,1,m);$a(m)}if(G[321436]){m=G[24367];hb(88786,42,1,m);$a(m)}a:{if(a==d){L[e>>3]=b;L[f>>3]=c;break a}if(L[23798]!=a|L[23799]!=d){G[926706]=442745336;G[926707]=1078765020;G[926708]=-1571644103;G[926709]=1066524486;G[926712]=-1291874403;G[926713]=1054102949;L[23798]=a;L[23799]=d;d=(d-a)*.01;L[463355]=d;a=(a+-1900)*.01;g=(d*(d*-.0418)*d+((a*-37e-5*a+(a*-.8533+2004.685))*d-d*(d*(a*37e-5+.4267))))/3600*.017453292519943295;h=eb(g);L[463374]=h;l=(a*6e-5*a+(a*1.3975+2304.253))*d;i=(d*(d*.018)*d+(l+d*(d*(a*-27e-5+.3023))))/3600*.017453292519943295;j=eb(i);g=ib(g);L[463370]=j*g;i=ib(i);k=-i;L[463372]=g*k;d=(d*(d*.01832)*d+(l+d*(d*(a*39e-5+1.095))))/3600*.017453292519943295;a=eb(d);g=-g;L[463362]=a*g;d=ib(d);L[463368]=d*g;g=j*h;L[463358]=a*g-d*i;L[463364]=g*d+i*a;h=h*k;L[463360]=a*h-d*j;L[463366]=h*d+j*a;a=.017453292519943295}else{a=L[463354]}d=a*b;b=ib(d);a=a*c;h=eb(a);j=h*0;g=eb(d);l=ib(a);k=l*-0;c=L[463356];a=(j*g+b*k)*c;n=L[463368];d=j*c;i=L[463355];l=d*i+l;q=L[463364];j=(g*k-j*b)*c;g=j*i+h*g;r=L[463366];b=a*i+b*h;i=n*l+(q*g+r*b);s=L[463362];t=L[463358];u=L[463360];k=s*l+(t*g+u*b);h=Db(i,k);o=L[463374];v=L[463370];w=L[463372];g=o*l+(v*g+w*b);k=k*k+i*i;i=Db(g,V(k));b=eb(i);l=ib(h);g=V(g*g+k);k=(o*d+(v*j+a*w))/g;o=eb(h);n=(n*d+(q*j+a*r))/g;a=(s*d+(t*j+a*u))/g;d=k*0+(b*o*n-a*(l*b));g=a;a=ib(i);j=g*(o*-a)-l*a*n;a=h;h=L[463353];a=a*h;if(a<0){while(1){a=a+360;if(a<0){continue}break}}L[e>>3]=a;if(a>360){while(1){a=a+-360;if(a>360){continue}break}L[e>>3]=a}j=(k*b+j)/c;L[f>>3]=R(Q(i*h,90),-90);h=d/(b*(b*c))/15}L[p+8>>3]=h;L[p>>3]=j;Fa=p+16|0}function im(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;m=Fa-80|0;n=b-L[c+3240>>3];o=a-L[c+3232>>3];k=G[c+2424>>2];l=G[c+1616>>2];a:{if((l|0)<0){break a}while(1){q=M(l-f|0,80)+c|0;j=f<<3;g=L[(q+j|0)+1624>>3];r=j+m|0;j=f;b:{if(!f){break b}h=0;i=j&3;if(i){while(1){f=f-1|0;g=n*g+L[(q+(f<<3)|0)+1624>>3];h=h+1|0;if((i|0)!=(h|0)){continue}break}}if(j-1>>>0<3){break b}while(1){h=q+1624|0;i=h+(f<<3)|0;g=n*(n*(n*(n*g+L[i-8>>3])+L[i-16>>3])+L[i-24>>3]);i=f-4|0;g=g+L[h+(i<<3)>>3];h=(f|0)>4;f=i;if(h){continue}break}}L[r>>3]=g;f=j+1|0;if((j|0)!=(l|0)){continue}break}g=L[m>>3];if((l|0)<=0){p=g;break a}j=l-1|0;i=l+1|0;f=l&3;c:{if(!f){p=g;break c}h=0;p=g;while(1){p=o*p+L[(i-l<<3)+m>>3];l=l-1|0;h=h+1|0;if((f|0)!=(h|0)){continue}break}}if(j>>>0<3){break a}while(1){f=(i-l<<3)+m|0;p=o*(o*(o*(o*p+L[f>>3])+L[f+8>>3])+L[f+16>>3]);f=l-3|0;p=p+L[(i-f<<3)+m>>3];l=l-4|0;if(f>>>0>1){continue}break}}L[d>>3]=p;f=0;d:{if((k|0)<0){break d}while(1){q=M(k-f|0,80)+c|0;j=f<<3;g=L[(q+j|0)+2432>>3];r=j+m|0;j=f;e:{if(!f){break e}h=0;i=j&3;if(i){while(1){f=f-1|0;g=n*g+L[(q+(f<<3)|0)+2432>>3];h=h+1|0;if((i|0)!=(h|0)){continue}break}}if(j-1>>>0<3){break e}while(1){h=q+2432|0;i=h+(f<<3)|0;g=n*(n*(n*(n*g+L[i-8>>3])+L[i-16>>3])+L[i-24>>3]);i=f-4|0;g=g+L[h+(i<<3)>>3];h=(f|0)>4;f=i;if(h){continue}break}}L[r>>3]=g;f=j+1|0;if((j|0)!=(k|0)){continue}break}g=L[m>>3];if((k|0)<=0){break d}f=k-1|0;j=k+1|0;c=k&3;if(c){h=0;while(1){g=o*g+L[(j-k<<3)+m>>3];k=k-1|0;h=h+1|0;if((c|0)!=(h|0)){continue}break}}if(f>>>0<3){break d}while(1){c=(j-k<<3)+m|0;g=o*(o*(o*(o*g+L[c>>3])+L[c+8>>3])+L[c+16>>3]);c=k-3|0;g=g+L[(j-c<<3)+m>>3];k=k-4|0;if(c>>>0>1){continue}break}}L[e>>3]=g;L[d>>3]=L[d>>3]+a;L[e>>3]=L[e>>3]+b}function Mq(a,b){a=a|0;b=b|0;var c=0,d=0,e=0;c=Fa-4240|0;Fa=c;G[c+4236>>2]=0;a:{if(Xa(a,33749)|!H[3805536]&(E[b+4|0]&1)){break a}b:{c:{if(Ld(G[b+32>>2],c+128|0,c+4236|0)){a=_b(c+128|0);d=Lc(G[b+32>>2]+G[c+4236>>2]|0);pb(G[b+32>>2]);G[b+32>>2]=d;if(H[b+4|0]&96?0:H[3805528]){break c}d=G[b+48>>2];G[c+112>>2]=d?d:G[951383]+1|0;Ya(3805552,4096,48880,c+112|0);G[951383]=a+G[951383];G[b+20>>2]=a+G[b+20>>2];E[3805528]=1;break b}a=G[24367];d:{if(H[3780288]){G[c+20>>2]=3780288;G[c+16>>2]=29439;Tb(a,69475,c+16|0);break d}G[c>>2]=29439;Tb(a,68751,c)}a=G[945062];e:{if(!a){break e}d=a+(G[945063]<<2)|0;a=G[d>>2];if(!a){break e}G[a+16>>2]=0;E[G[a+4>>2]]=0;E[G[a+4>>2]+1|0]=0;G[a+44>>2]=0;G[a+28>>2]=1;b=G[a+4>>2];G[a+8>>2]=b;if((a|0)!=G[d>>2]){break e}a=G[a+16>>2];G[945064]=b;G[950324]=a;G[945070]=b;G[945057]=G[G[d>>2]>>2];E[3780260]=H[b|0]}E[3801300]=1;break a}a=G[b+48>>2];if(a){G[c+96>>2]=a;Ya(3805552,4096,48880,c+96|0);break b}G[c+80>>2]=G[951383];Ya(3805552,4096,48880,c+80|0)}G[c+4236>>2]=0;if(Ld(G[b+40>>2],c+128|0,c+4236|0)){a=c+128|0;d=_b(a);e=Lc(G[b+40>>2]+G[c+4236>>2]|0);pb(G[b+40>>2]);G[b+40>>2]=e;b=G[950328]+1|0;G[950328]=b;G[c+64>>2]=b;Ya(a,4096,30633,c- -64|0);e=3805552;Gb(3805552,a);G[950328]=(d+G[950328]|0)-1;break a}a=G[24367];f:{if(H[3780288]){G[c+52>>2]=3780288;G[c+48>>2]=29482;Tb(a,69475,c+48|0);break f}G[c+32>>2]=29482;Tb(a,68751,c+32|0)}a=G[945062];g:{if(!a){break g}d=a+(G[945063]<<2)|0;a=G[d>>2];if(!a){break g}G[a+16>>2]=0;E[G[a+4>>2]]=0;E[G[a+4>>2]+1|0]=0;G[a+44>>2]=0;G[a+28>>2]=1;b=G[a+4>>2];G[a+8>>2]=b;if((a|0)!=G[d>>2]){break g}a=G[a+16>>2];G[945064]=b;G[950324]=a;G[945070]=b;G[945057]=G[G[d>>2]>>2];E[3780260]=H[b|0]}E[3801300]=1}Fa=c+4240|0;return e|0}function Eo(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0;l=c==1&d==0;a:{b:{if(!e){if(l){break b}l=0;if((b|0)<=0){break a}while(1){f=j+l|0;m=+F[(l<<1)+a>>1]*c+d;c:{if(m<-128.49){G[k>>2]=-11;e=128;break c}if(m>127.49){G[k>>2]=-11;e=127;break c}e=~~m;if(O(m)<2147483648){break c}e=-2147483648}E[f|0]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if(!l){if((b|0)<=0){break a}e=(e|0)==1;g=e?g:1;h=e?j:h;l=0;n=f&65535;while(1){e=I[(l<<1)+a>>1];d:{if((e|0)==(n|0)){G[i>>2]=1;f=g;e=h;break d}m=+(e<<16>>16)*c+d;e:{if(m<-128.49){G[k>>2]=-11;f=128;break e}if(m>127.49){G[k>>2]=-11;f=127;break e}f=~~m;if(O(m)<2147483648){break e}f=-2147483648}e=j}E[e+l|0]=f;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}l=0;if((e|0)==1){f=f&65535;while(1){e=I[(l<<1)+a>>1];f:{if((e|0)!=(f|0)){e=e<<16>>16;if((e|0)>=-128){if((e|0)<=127){break f}G[k>>2]=-11;e=127;break f}G[k>>2]=-11;e=128;break f}G[i>>2]=1;e=g}E[j+l|0]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}g=f&65535;while(1){e=I[(l<<1)+a>>1];g:{if((e|0)==(g|0)){e=1;G[i>>2]=1;f=h;break g}e=e<<16>>16;h:{if((e|0)<=-129){G[k>>2]=-11;e=128;break h}if((e|0)<128){break h}G[k>>2]=-11;e=127}f=j}E[f+l|0]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}f=b&1;l=0;if((b|0)!=1){g=b&-2;e=0;while(1){b=F[(l<<1)+a>>1];i:{if((b|0)<=-129){G[k>>2]=-11;b=128;break i}if((b|0)<128){break i}G[k>>2]=-11;b=127}E[j+l|0]=b;h=l|1;b=F[(h<<1)+a>>1];j:{if((b|0)>=-128){if((b|0)<=127){break j}G[k>>2]=-11;b=127;break j}G[k>>2]=-11;b=128}E[h+j|0]=b;l=l+2|0;e=e+2|0;if((g|0)!=(e|0)){continue}break}}if(!f){break a}a=F[(l<<1)+a>>1];k:{if((a|0)>=-128){if((a|0)<=127){break k}G[k>>2]=-11;a=127;break k}G[k>>2]=-11;a=128}E[j+l|0]=a}}function jm(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;m=Fa-80|0;n=b-L[c+3240>>3];o=a-L[c+3232>>3];k=G[c+808>>2];l=G[c>>2];a:{if((l|0)<0){break a}while(1){q=M(l-f|0,80)+c|0;j=f<<3;g=L[(q+j|0)+8>>3];r=j+m|0;j=f;b:{if(!f){break b}h=0;i=j&3;if(i){while(1){f=f-1|0;g=n*g+L[(q+(f<<3)|0)+8>>3];h=h+1|0;if((i|0)!=(h|0)){continue}break}}if(j-1>>>0<3){break b}while(1){h=q+8|0;i=h+(f<<3)|0;g=n*(n*(n*(n*g+L[i-8>>3])+L[i-16>>3])+L[i-24>>3]);i=f-4|0;g=g+L[h+(i<<3)>>3];h=(f|0)>4;f=i;if(h){continue}break}}L[r>>3]=g;f=j+1|0;if((j|0)!=(l|0)){continue}break}g=L[m>>3];if((l|0)<=0){p=g;break a}j=l-1|0;i=l+1|0;f=l&3;c:{if(!f){p=g;break c}h=0;p=g;while(1){p=o*p+L[(i-l<<3)+m>>3];l=l-1|0;h=h+1|0;if((f|0)!=(h|0)){continue}break}}if(j>>>0<3){break a}while(1){f=(i-l<<3)+m|0;p=o*(o*(o*(o*p+L[f>>3])+L[f+8>>3])+L[f+16>>3]);f=l-3|0;p=p+L[(i-f<<3)+m>>3];l=l-4|0;if(f>>>0>1){continue}break}}L[d>>3]=p;f=0;d:{if((k|0)<0){break d}while(1){q=M(k-f|0,80)+c|0;j=f<<3;g=L[(q+j|0)+816>>3];r=j+m|0;j=f;e:{if(!f){break e}h=0;i=j&3;if(i){while(1){f=f-1|0;g=n*g+L[(q+(f<<3)|0)+816>>3];h=h+1|0;if((i|0)!=(h|0)){continue}break}}if(j-1>>>0<3){break e}while(1){h=q+816|0;i=h+(f<<3)|0;g=n*(n*(n*(n*g+L[i-8>>3])+L[i-16>>3])+L[i-24>>3]);i=f-4|0;g=g+L[h+(i<<3)>>3];h=(f|0)>4;f=i;if(h){continue}break}}L[r>>3]=g;f=j+1|0;if((j|0)!=(k|0)){continue}break}g=L[m>>3];if((k|0)<=0){break d}f=k-1|0;j=k+1|0;c=k&3;if(c){h=0;while(1){g=o*g+L[(j-k<<3)+m>>3];k=k-1|0;h=h+1|0;if((c|0)!=(h|0)){continue}break}}if(f>>>0<3){break d}while(1){c=(j-k<<3)+m|0;g=o*(o*(o*(o*g+L[c>>3])+L[c+8>>3])+L[c+16>>3]);c=k-3|0;g=g+L[(j-c<<3)+m>>3];k=k-4|0;if(c>>>0>1){continue}break}}L[e>>3]=g;L[d>>3]=L[d>>3]+a;L[e>>3]=L[e>>3]+b}function Ze(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;j=Fa-128|0;Fa=j;n=G[a+48>>2];p=G[a+40>>2];k=G[a+16>>2];l=g-+G[a+24>>2];g=+G[a+32>>2];l=l/g+1;L[j>>3]=l;f=(f-+(k|0))/g+1;L[j+64>>3]=f;g=i-h;if(!(O(g)<1e-24)){if(h<0){while(1){h=h+360;if(h<0){continue}break}}if(h>=360){while(1){h=h+-360;if(h>=360){continue}break}}a:{if(O(h+-180)<1e-24){L[j+8>>3]=l;G[j+72>>2]=0;G[j+76>>2]=0;k=2;break a}if(O(h)<1e-24){L[j+8>>3]=l;L[j+72>>3]=p+1|0;k=4;break a}b:{if(h<180){k=1;m=+(n+1|0);L[j+8>>3]=m;if(!(O(h+-90)<1e-24)){break b}L[j+72>>3]=f;break a}G[j+8>>2]=0;G[j+12>>2]=0;if(!(O(h+-270)<1e-24)){break b}L[j+72>>3]=f;k=3;break a}h=Mc(h/180*3.141592653589793);q=f+(m-l)/h;L[j+72>>3]=q;if(q<0){G[j+72>>2]=0;G[j+76>>2]=0;L[j+8>>3]=l-f*h;k=2;break a}s=+(p+1|0);if(q>s){L[j+72>>3]=s;L[j+8>>3]=(s-f)*h+l;k=4;break a}k=+(n|0)>m?3:1}if(i<0){while(1){i=i+360;if(i<0){continue}break}}if(i>=360){while(1){i=i+-360;if(i>=360){continue}break}}q=g<0?g+360:g;r=2;m=0;c:{if(O(i+-180)<1e-24){o=2;break c}if(O(i)<1e-24){m=+(p+1|0);o=4;break c}d:{e:{if(i<180){o=1;g=+(n+1|0);if(!(O(i+-90)<1e-24)){break e}break d}o=3;g=0;if(!(O(i+-270)<1e-24)){break e}m=f;l=0;break c}i=Mc(i/180*3.141592653589793);h=f+(g-l)/i;if(h<0){l=l-f*i;o=2;break c}m=+(p+1|0);if(h>m){l=(m-f)*i+l;o=4;break c}o=+(n|0)>g?3:1;f=h}m=f;l=g}if(!(!(q>180)&(k|0)==(o|0))){g=+(n+1|0);f=+(p+1|0);while(1){i=0;h=g;f:{g:{h:{switch(k-1|0){case 1:h=0;break g;case 2:h=0;i=f;break g;case 0:break g;case 3:break h;default:break f}}i=f}n=r<<3;L[n+(j- -64|0)>>3]=i;L[j+n>>3]=h}r=r+1|0;k=(k|0)>3?1:k+1|0;if((o|0)!=(k|0)){continue}break}}k=r<<3;L[k+j>>3]=l;p=k;k=j- -64|0;L[p+k>>3]=m;Hj(a,b,c,d,e,k,j,r+1|0)}Fa=j+128|0}function fu(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0;f=Fa-393248|0;Fa=f;G[f+131108>>2]=17399;G[f+131104>>2]=11208;G[f+16>>2]=42205;G[f+20>>2]=a;a=f+65568|0;Ya(a,65535,8740,f+16|0);G[f+131116>>2]=14072;G[f>>2]=42205;G[f+4>>2]=b;G[f+131112>>2]=a;a=f+32|0;Ya(a,65535,8740,f);G[f+131128>>2]=d;G[f+131124>>2]=c;G[f+131120>>2]=a;a=f+131104|0;b=0;d=0;e=Fa-8224|0;Fa=e;G[e+8220>>2]=0;Tl();G[47589]=1;while(1){c=of(7,a,4029);if((c|0)!=-1){if((c|0)!=105){continue}b=G[321433];continue}break}G[e+8>>2]=b;a:{b:{c:{d:{if(b){e:{f:{c=7-G[47589]|0;switch(c|0){case 0:break d;case 1:break f;default:break e}}d=1;if(Kf(31902,e+8|0,1,0,0)){break a}if(!Kf(G[a+(G[47589]<<2)>>2],0,0,0,0)){break c}break a}d=1;if(Kf(31902,e+8|0,1,0,0)){break a}a=a+(G[47589]<<2)|0;if(!Kf(G[a>>2],a+4|0,c-1|0,0,0)){break c}break a}a=Vj(1);if(a){b=G[29763];hb(66692,11,1,b);$a(b)}b=G[30060];g:{if(!vc(e+4112|0,4095,b)){break g}c=(a|0)!=0;if(!a){while(1){G[e+8220>>2]=0;if(Ld(e+4112|0,e+16|0,e+8220|0)){G[e+12>>2]=G[e+8220>>2]+(e+4112|0);Kf(e+16|0,e+12|0,1,1,c)}if(vc(e+4112|0,4095,b)){continue}break g}}a=G[29763];while(1){G[e+8220>>2]=0;if(Ld(e+4112|0,e+16|0,e+8220|0)){if(!Xc(e+16|0,4991)){break g}G[e+12>>2]=G[e+8220>>2]+(e+4112|0);Kf(e+16|0,e+12|0,1,0,c);hb(66692,11,1,a);$a(a)}if(vc(e+4112|0,4095,b)){continue}break}}b=G[936854];if(!b){break a}a=b;while(1){c=G[a>>2];h:{if(!b){break h}i:{if((a|0)==(b|0)){d=3747416;break i}while(1){d=b;if(!b){break h}b=G[d>>2];if((b|0)!=(a|0)){continue}break}}G[d>>2]=c}pb(G[a+4>>2]);pb(G[a+16>>2]);b=G[a+12>>2];if(b){Hb(b)}pb(a);if(!c){break b}b=G[936854];a=c;continue}}d=1;if(Kf(25125,e+8|0,1,0,0)){break a}}Jl(b)}d=0}Fa=e+8224|0;Fa=f+393248|0;return d|0}function Qt(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0;e=c;c=b;h=-1;g=-1;a:{b:{if(!a){break b}f=G[a+16>>2];if((f|0)!=31153&(f|0)!=7247){break b}c:{switch(G[a+92>>2]+5|0){case 0:case 5:break c;default:break b}}if(d>>>0>1){break b}d:{if(!d){d=G[a+8>>2];c=c-d|0;e=e-(G[a+12>>2]+(b>>>0>>0)|0)|0;break d}if(!G[a+88>>2]){break d}e=e+G[a+84>>2]|0;b=c+G[a+80>>2]|0;e=b>>>0>>0?e+1|0:e;c=b}G[a+88>>2]=0;e:{if((f|0)==7247){f:{if(G[a+48>>2]!=1){break f}f=e+G[a+12>>2]|0;if(((c+G[a+8>>2]>>>0>>0?f+1|0:f)|0)<0){break f}b=G[a>>2];if((Xg(G[a+20>>2],c-b|0,e-(b>>>0>c>>>0)|0,1)&Ia)==-1){break b}G[a+88>>2]=0;G[a+64>>2]=0;G[a+68>>2]=0;G[a>>2]=0;b=G[a+96>>2];if(b){if(G[a+92>>2]!=-4){Wa(b)}G[a+96>>2]=0}G[a+92>>2]=0;G[a+104>>2]=0;e=e+G[a+12>>2]|0;b=c+G[a+8>>2]|0;e=b>>>0>>0?e+1|0:e;G[a+8>>2]=b;G[a+12>>2]=e;a=e;break a}if((e|0)<0){e=e+G[a+12>>2]|0;b=c+G[a+8>>2]|0;e=b>>>0>>0?e+1|0:e;c=b;if((e|0)<0){break b}b=-1;g:{if(!a|G[a+16>>2]!=7247){break g}h:{switch(G[a+92>>2]+5|0){case 0:case 5:break h;default:break g}}if((Xg(G[a+20>>2],G[a+56>>2],G[a+60>>2],0)&Ia)==-1){break g}G[a>>2]=0;if(G[a+16>>2]==7247){G[a+48>>2]=0;G[a+64>>2]=0;G[a+68>>2]=0}b=0;G[a+88>>2]=0;d=G[a+96>>2];if(d){if(G[a+92>>2]!=-4){Wa(d)}G[a+96>>2]=0}G[a+8>>2]=0;G[a+12>>2]=0;G[a+92>>2]=0;G[a+104>>2]=0}if((b|0)==-1){break b}if(G[a+16>>2]!=7247){break e}}d=G[a>>2];b=!e&c>>>0>>0?c:d;G[a>>2]=d-b;G[a+4>>2]=b+G[a+4>>2];f=G[a+12>>2];d=G[a+8>>2];g=d+b|0;G[a+8>>2]=g;G[a+12>>2]=d>>>0>g>>>0?f+1|0:f;d=c;c=c-b|0;e=e-(b>>>0>d>>>0)|0;break e}if((e|0)<0){break b}}if(c|e){G[a+80>>2]=c;G[a+84>>2]=e;G[a+88>>2]=1}g=e+G[a+12>>2]|0;b=c+G[a+8>>2]|0;g=b>>>0>>0?g+1|0:g;h=b}b=h;a=g}_(a|0);return b|0}function il(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0;f=Fa-368|0;Fa=f;a:{if(G[e>>2]>0){break a}if(b-1e3>>>0<=4294966296){Ua(58025);G[e>>2]=302;break a}if((c|0)<=0){Ua(58072);G[e>>2]=320;break a}h=G[a>>2];i=G[a+4>>2];b:{if((h|0)!=G[i+76>>2]){mb(a,h+1|0,0,e);break b}if((G[i+128>>2]&G[i+132>>2])!=-1){break b}if((Rb(a,e)|0)>0){break a}}if(G[G[a+4>>2]+80>>2]!=2){Ua(57922);G[e>>2]=227;break a}F[f+208>>1]=40;h=0;i=1;c:{while(1){if(h){g=f+208|0;g=Va(g)+g|0;E[g|0]=44;E[g+1|0]=0}j=(h<<2)+d|0;g=G[j>>2];if((g|0)<0){Ua(58102);break c}G[f+16>>2]=g;g=f+128|0;Ya(g,80,27698,f+16|0);if((Va(f+208|0)+Va(g)|0)-70>>>0<=4294967224){Ua(57995);break c}g=Gb(f+208|0,f+128|0);i=M(G[j>>2],i);h=h+1|0;if((h|0)!=(c|0)){continue}break}d:{c=(G[G[a+4>>2]+968>>2]+M(b,160)|0)-72|0;if(G[c>>2]==(i|0)){break d}d=f+288|0;zb(34641,b,d,e);h=d;d=f+128|0;Fc(a,h,d,0,e);Vf(d,0,f+28|0,0,e);if(G[f+28>>2]==(i|0)&G[e>>2]<=0){break d}a=G[c>>2];G[f+4>>2]=i;G[f>>2]=a;a=f+32|0;Ya(a,81,27638,f);Ua(a);break c}c=Va(g)+g|0;E[c|0]=41;E[c+1|0]=0;c=H[3670]|H[3671]<<8|(H[3672]<<16|H[3673]<<24);E[f+63|0]=c;E[f+64|0]=c>>>8;E[f+65|0]=c>>>16;E[f+66|0]=c>>>24;c=H[3667]|H[3668]<<8|(H[3669]<<16|H[3670]<<24);G[f+56>>2]=H[3663]|H[3664]<<8|(H[3665]<<16|H[3666]<<24);G[f+60>>2]=c;c=H[3659]|H[3660]<<8|(H[3661]<<16|H[3662]<<24);G[f+48>>2]=H[3655]|H[3656]<<8|(H[3657]<<16|H[3658]<<24);G[f+52>>2]=c;c=H[3651]|H[3652]<<8|(H[3653]<<16|H[3654]<<24);G[f+40>>2]=H[3647]|H[3648]<<8|(H[3649]<<16|H[3650]<<24);G[f+44>>2]=c;c=H[3643]|H[3644]<<8|(H[3645]<<16|H[3646]<<24);G[f+32>>2]=H[3639]|H[3640]<<8|(H[3641]<<16|H[3642]<<24);G[f+36>>2]=c;c=b;b=f+288|0;zb(34647,c,b,e);lc(a,b,g,f+32|0,e);break a}G[e>>2]=263}Fa=f+368|0}function Tk(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0;l=c==1&d==0;a:{b:{if(!e){if(l){break b}l=0;if((b|0)<=0){break a}while(1){f=j+l|0;c:{d:{m=+F[(l<<1)+a>>1]*c+d;if(m<-.49){G[k>>2]=-11;break d}if(m>255.49){G[k>>2]=-11;e=255;break c}if(!(m<4294967296&m>=0)){break d}e=~~m>>>0;break c}e=0}E[f|0]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if(!l){if((b|0)<=0){break a}e=(e|0)==1;g=e?g:1;h=e?j:h;l=0;n=f&65535;while(1){e=I[(l<<1)+a>>1];e:{if((e|0)==(n|0)){G[i>>2]=1;f=g;e=h;break e}f:{g:{m=+(e<<16>>16)*c+d;if(m<-.49){G[k>>2]=-11;break g}if(m>255.49){G[k>>2]=-11;f=255;break f}if(!(m<4294967296&m>=0)){break g}f=~~m>>>0;break f}f=0}e=j}E[e+l|0]=f;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}l=0;if((e|0)==1){f=f&65535;while(1){e=I[(l<<1)+a>>1];h:{if((f|0)!=(e|0)){if(e<<16>>16>=0){if(e>>>0<=255){break h}G[k>>2]=-11;e=255;break h}G[k>>2]=-11;e=0;break h}G[i>>2]=1;e=g}E[j+l|0]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}g=f&65535;while(1){e=I[(l<<1)+a>>1];i:{if((g|0)==(e|0)){e=1;G[i>>2]=1;f=h;break i}j:{if(e<<16>>16<0){G[k>>2]=-11;e=0;break j}if(e>>>0<256){break j}G[k>>2]=-11;e=255}f=j}E[f+l|0]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}f=b&1;l=0;if((b|0)!=1){g=b&-2;e=0;while(1){b=F[(l<<1)+a>>1];k:{if((b|0)<0){G[k>>2]=-11;b=0;break k}if(b>>>0<256){break k}G[k>>2]=-11;b=255}E[j+l|0]=b;h=l|1;b=F[(h<<1)+a>>1];l:{if((b|0)>=0){if(b>>>0<=255){break l}G[k>>2]=-11;b=255;break l}G[k>>2]=-11;b=0}E[h+j|0]=b;l=l+2|0;e=e+2|0;if((g|0)!=(e|0)){continue}break}}if(!f){break a}a=F[(l<<1)+a>>1];m:{if((a|0)>=0){if(a>>>0<=255){break m}G[k>>2]=-11;a=255;break m}G[k>>2]=-11;a=0}E[j+l|0]=a}}function Us(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;g=G[309722];m=G[a+20>>2];r=g+M(m,344)|0;h=G[a+12>>2];o=G[a+16>>2];n=M(o,344)+g|0;a:{if(G[n>>2]!=-1e3){f=G[n+56>>2];break a}i=L[n+88>>3];f=0}if(G[r>>2]!=-1e3){d=G[(M(m,344)+g|0)+56>>2]}else{j=L[(M(m,344)+g|0)+88>>3];d=0}b:{if(!(f|d)){c=pi(i,j,G[(M(h,344)+g|0)+88>>2]);G[a>>2]=-1e3;E[a+88|0]=(c|0)!=0;break b}Nd(a);if(G[309737]){break b}b=G[309727];if(!b){break b}e=b-1|0;c=G[a+56>>2];b=M(b,c);p=M(h,344)+g|0;k=M(m,344)+g|0;l=M(o,344)+g|0;if((f|0)<=1){s=(d|0)>1;t=s|(d|0)!=0;while(1){d=e;h=0;if(c){while(1){if(f){u=H[d+G[l+84>>2]|0];i=L[G[l+88>>2]+(d<<3)>>3]}b=b-1|0;if(t){e=s?b:d;q=H[e+G[k+84>>2]|0];j=L[G[k+88>>2]+(e<<3)>>3]}c=c-1|0;E[G[a+84>>2]+b|0]=(q|u)!=0;if(!H[G[a+84>>2]+b|0]){e=pi(i,j,G[p+88>>2]);E[G[a+88>>2]+b|0]=(e|0)!=0}if(c){continue}break}h=G[a+56>>2]}e=d-1|0;c=h;if(d){continue}break}break b}if((d|0)>=2){while(1){d=e;e=d-1|0;if(c){while(1){b=b-1|0;f=b<<3;j=L[f+G[k+88>>2]>>3];i=L[f+G[l+88>>2]>>3];E[G[a+84>>2]+b|0]=(H[G[l+84>>2]+b|0]|H[G[k+84>>2]+b|0])!=0;c=c-1|0;if(!H[G[a+84>>2]+b|0]){f=pi(i,j,G[p+88>>2]);E[G[a+88>>2]+b|0]=(f|0)!=0}if(c){continue}break}c=G[a+56>>2]}else{c=0}if(d){continue}break b}}while(1){f=e;h=0;if(c){while(1){b=b-1|0;e=H[b+G[l+84>>2]|0];h=G[l+88>>2]+(b<<3)|0;if(d){q=H[f+G[k+84>>2]|0];j=L[G[k+88>>2]+(f<<3)>>3]}c=c-1|0;i=L[h>>3];E[G[a+84>>2]+b|0]=(e|q)!=0;if(!H[G[a+84>>2]+b|0]){e=pi(i,j,G[p+88>>2]);E[G[a+88>>2]+b|0]=(e|0)!=0}if(c){continue}break}h=G[a+56>>2]}e=f-1|0;c=h;if(f){continue}break}}if(G[n>>2]>0){Wa(G[(M(o,344)+g|0)+88>>2])}if(G[r>>2]>0){Wa(G[(M(m,344)+g|0)+88>>2])}}function Vs(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;h=Fa-16|0;Fa=h;e=G[309722];b=e+M(G[a+12>>2],344)|0;d=G[b+88>>2];g=G[b+56>>2];i=d+(g<<3)|0;j=G[a+20>>2];o=M(j,344)+e|0;b=G[o>>2];m=G[a+16>>2];n=M(m,344)+e|0;a:{b:{if(G[n>>2]==-1e3){f=L[n+88>>3];if((b|0)!=-1e3){break b}f=jn(f,L[(M(j,344)+e|0)+88>>3],g,d,i,h+12|0);G[a>>2]=-1e3;L[a+88>>3]=f;break a}if((b|0)!=-1e3){break b}k=L[(M(j,344)+e|0)+88>>3]}Nd(a);if(G[309737]){break a}b=M(G[a+56>>2],G[309727]);if(!g){if(!b){break a}d=b-1|0;g=b&3;if(g){while(1){b=b-1|0;i=G[a+88>>2]+(b<<3)|0;G[i>>2]=0;G[i+4>>2]=0;E[G[a+84>>2]+b|0]=0;c=c+1|0;if((g|0)!=(c|0)){continue}break}}if(d>>>0<3){break a}while(1){d=b-1|0;c=G[a+88>>2]+(d<<3)|0;G[c>>2]=0;G[c+4>>2]=0;E[d+G[a+84>>2]|0]=0;d=b-2|0;c=G[a+88>>2]+(d<<3)|0;G[c>>2]=0;G[c+4>>2]=0;E[d+G[a+84>>2]|0]=0;d=b-3|0;c=G[a+88>>2]+(d<<3)|0;G[c>>2]=0;G[c+4>>2]=0;E[d+G[a+84>>2]|0]=0;b=b-4|0;d=G[a+88>>2]+(b<<3)|0;G[d>>2]=0;G[d+4>>2]=0;E[G[a+84>>2]+b|0]=0;if(b){continue}break}break a}s=G[(M(j,344)+e|0)+88>>2];t=G[(M(m,344)+e|0)+88>>2];G[h+12>>2]=-1;if(!b){break a}u=M(j,344)+e|0;v=M(m,344)+e|0;while(1){b=b-1|0;if(G[n>>2]!=-1e3){p=H[G[v+84>>2]+b|0];f=L[(b<<3)+t>>3]}if(G[o>>2]!=-1e3){c=H[G[u+84>>2]+b|0];k=L[(b<<3)+s>>3]}q=(c|p)&255;E[G[a+84>>2]+b|0]=(q|0)!=0;if(!q){c:{d:{c=G[h+12>>2];e:{if((c|0)<0){break e}c=c<<3;l=L[c+d>>3];if(l>f){break e}r=L[c+i>>3];if(rr)){break d}}l=jn(f,k,g,d,i,h+12|0);break c}l=k-f}L[G[a+88>>2]+(b<<3)>>3]=l;p=0;c=0}if(b){continue}break}}if(G[n>>2]>0){Wa(G[(M(m,344)+e|0)+88>>2])}if(G[o>>2]>0){Wa(G[(M(j,344)+e|0)+88>>2])}Fa=h+16|0}function Tg(a){var b=0,c=0,d=0;c=Fa-4112|0;Fa=c;a:{if(G[947121]<3){break a}L[c>>3]=a;Ya(c+16|0,4096,19682,c);b:{if(G[947121]!=3){break b}G[951360]=0;G[951361]=0;G[951362]=0;G[951363]=0;E[3801344]=0;b=G[G[(G[950332]+(G[950330]<<2)|0)-4>>2]+52>>2];if(!b){break b}pb(b);b=(G[950332]+(G[950330]<<2)|0)-4|0;G[G[b>>2]+52>>2]=0;G[G[b>>2]+56>>2]=0}c:{switch(G[948156]-1|0){case 0:case 2:if(H[3801344]){b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(3801344,b+52|0,b+56|0)}b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c+16|0,b+52|0,b+56|0);if(G[947121]>=4){b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(85395,b+52|0,b+56|0);Za(3801344,c+16|0)}L[475680]=L[475681];L[475681]=a;break a;case 1:case 3:if((G[947121]&-2147483647)!=1){break a}if(H[3801344]){b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(3801344,b+52|0,b+56|0)}b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c+16|0,b+52|0,b+56|0);if(G[947121]>=4){b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(85395,b+52|0,b+56|0);Za(3801344,c+16|0)}L[475680]=L[475681];L[475681]=a;break a;case 10:d:{if(G[947121]!=3){if(!H[3801344]){break d}b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(48937,b+52|0,b+56|0);d=3801344}else{d=35975}b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(d,b+52|0,b+56|0)}b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(c+16|0,b+52|0,b+56|0);if(G[947121]>=4){b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(92037,b+52|0,b+56|0);Za(3801344,c+16|0)}L[475680]=L[475681];L[475681]=a;break a;case 11:break c;default:break a}}b=G[947121];if((b|0)==3){b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(85390,b+52|0,b+56|0);break a}if(b&1){break a}b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(85390,b+52|0,b+56|0)}Fa=c+4112|0}function Cg(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0;j=Fa-16|0;Fa=j;G[j+12>>2]=0;G[j+8>>2]=0;a:{if(G[i>>2]>0){break a}l=Rf(a,36364,j+8|0,j+12|0,i);if(G[i>>2]){break a}b:{if(l){break b}c:{k=H[G[a>>2]];switch(k-44|0){case 0:case 15:break a;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:break b;default:break c}}if(!k){break a}}d:{e:{if(G[j+12>>2]){break e}k=G[a>>2];if(H[k|0]==58){break e}l=G[j+8>>2];if(l){if(Va(l)>>>0>=71){Ua(51285);break d}f:{if(!(H[l|0]!=35|E[l+1|0]-48>>>0>9)){Za(b,l+1|0);break f}Za(b,l)}Wa(l);G[j+8>>2]=0;k=G[a>>2]}while(1){b=H[k|0];if((b|0)!=32){if((b|0)!=61){break a}while(1){b=k+1|0;G[a>>2]=b;l=H[k+1|0];k=b;if((l|0)==32){continue}break}l=Rf(a,36370,j+8|0,j+12|0,i);if(G[i>>2]){break a}}else{k=k+1|0;G[a>>2]=k;continue}break}}b=G[a>>2];if(H[b|0]!=58){a=G[j+8>>2];if(!a){break a}if(!G[j+12>>2]){if(Va(a)>>>0>=71){Ua(51259);break d}Za(h,a);Wa(a);break a}m=e,n=vb(a,0),L[m>>3]=n;Wa(G[j+8>>2]);break a}if(l){k=G[j+8>>2];g:{if(!G[j+12>>2]){if(Va(k)>>>0>=71){Ua(51233);break d}Za(f,k);break g}m=c,n=vb(k,0),L[m>>3]=n;k=G[j+8>>2]}Wa(k);G[j+8>>2]=0;b=G[a>>2]}G[a>>2]=b+1;b=Rf(a,36370,j+8|0,j+12|0,i);if(G[i>>2]){break a}if(b){k=G[j+8>>2];h:{if(!G[j+12>>2]){if(Va(k)>>>0>=71){Ua(51207);break d}Za(g,k);break h}m=d,n=vb(k,0),L[m>>3]=n;k=G[j+8>>2]}Wa(k);G[j+8>>2]=0}b=G[a>>2];if(H[b|0]!=58){Wa(G[j+8>>2]);break a}G[a>>2]=b+1;a=Rf(a,36370,j+8|0,j+12|0,i);if(G[i>>2]|!a){break a}k=G[j+8>>2];i:{if(!G[j+12>>2]){if(Va(k)>>>0>=71){Ua(51259);break d}Za(h,k);break i}m=e,n=vb(k,0),L[m>>3]=n;k=G[j+8>>2]}Wa(k);break a}Wa(G[j+8>>2]);G[i>>2]=431}Fa=j+16|0}function tp(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=N(0),n=0,o=0,p=0;a:{b:{if(!e){if(c==1&d==0){break b}if((b|0)<=0){break a}while(1){f=i+k|0;c:{d:{l=+K[(k<<2)+a>>2]*c+d;if(l<-.49){G[j>>2]=-11;break d}if(l>255.49){G[j>>2]=-11;e=255;break c}if(!(l<4294967296&l>=0)){break d}e=~~l>>>0;break c}e=0}E[f|0]=e;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}k=a+2|0;e:{f:{if(!(c==1&d==0)){if((b|0)<=0){break a}e=(e|0)==1;p=e?f:1;n=e?i:g;if(!(d<4294967296&d>=0)){break f}o=~~d>>>0;break e}if((b|0)<=0){break a}e=(e|0)==1;o=e?f:1;p=e?i:g;e=0;while(1){g=i;f=0;g:{h:{i:{n=I[k>>1]&32640;switch(((n|0)==32640?1:!n<<1)|0){case 0:break h;case 1:break i;default:break g}}G[h>>2]=1;g=p;f=o;break g}m=K[(e<<2)+a>>2];c=+m;if(c<-.49){G[j>>2]=-11;break g}j:{if(c>255.49){G[j>>2]=-11;f=255;break j}f=~~m>>>0;if(m=N(0)){break j}f=0}}E[e+g|0]=f;k=k+4|0;e=e+1|0;if((e|0)!=(b|0)){continue}break}break a}o=0}e=0;while(1){k:{l:{m:{n:{o:{p:{f=I[k>>1]&32640;switch(((f|0)==32640?1:!f<<1)|0){case 0:break n;case 1:break p;default:break o}}G[h>>2]=1;f=p;g=n;break k}if(d<-.49){G[j>>2]=-11;break m}f=o;g=i;if(!(d>255.49)){break k}G[j>>2]=-11;f=255;break l}l=+K[(e<<2)+a>>2]*c+d;if(l<-.49){G[j>>2]=-11;f=0;break l}if(l>255.49){G[j>>2]=-11;f=255;break l}if(!(l<4294967296&l>=0)){break m}f=~~l>>>0;break l}f=0}g=i}E[g+e|0]=f;k=k+4|0;e=e+1|0;if((e|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}while(1){f=i+k|0;q:{r:{m=K[(k<<2)+a>>2];c=+m;if(c<-.49){G[j>>2]=-11;break r}if(c>255.49){G[j>>2]=-11;e=255;break q}if(!(m=N(0))){break r}e=~~m>>>0;break q}e=0}E[f|0]=e;k=k+1|0;if((k|0)!=(b|0)){continue}break}}}function Ml(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;e=Fa-16480|0;Fa=e;c=e- -8192|0;Nl(a,c);a=0;a:{if(Be(c,e+16392|0)){break a}b:{if(!b){break b}d=jb(b,114);f=jb(b,119);g=jb(b,120);c=G[e+16404>>2];h=c&16384;c:{if(jb(b,100)){if(h){break c}break a}if(h){break a}}if(!G[e+16412>>2]){if((c&256?0:d)|(c&128?0:f)){break a}if(!g|c&64){break b}break a}b=(d|0)!=0;if(!G[e+16416>>2]){if(b&!(c&32)|(c&16?0:f)){break a}if(!g|c&8){break b}break a}if(b&!(c&4)|(c&2?0:f)){break a}if(!g){break b}if(!(c&1)){break a}}c=Fa-40960|0;Fa=c;a=e- -8192|0;d:{if(!jb(a,47)){i=rb(e,a,8191)+8191|0,j=0,E[i|0]=j;break d}e:{if(Xa(a,42205)){if(Xa(a,45308)){break e}}i=rb(e,42205,8191)+8191|0,j=0,E[i|0]=j;break d}f:{if(H[a|0]!=47){ui(c+32768|0,8192);break f}E[c+32768|0]=0}b=Va(c+32768|0)+Va(a)|0;g=Xb(b+2|0);g:{if(H[c+32768|0]){f=Za(g,c+32768|0);d=Va(f)+f|0;E[d|0]=47;E[d+1|0]=0;Gb(f,a);break g}Za(g,a)}h:{i:{if(b>>>0>=2147483647){break i}a=b+1|0;f=0;b=0;while(1){d=b+g|0;j:{if(H[d|0]!=47){b=b+1|0;break j}E[d|0]=0;b=b+1|0;d=g+b|0;if(H[d|0]==47){break j}G[c+(f<<2)>>2]=d;f=f+1|0}if((a|0)!=(b|0)){continue}break}a=0;if((f|0)<=0){break i}while(1){d=c+(a<<2)|0;b=G[d>>2];k:{if(Xa(b,48504)){if(Xa(b,45311)){break k}G[d>>2]=0;b=a;while(1){if((b|0)<=0){break k}b=b-1|0;d=c+(b<<2)|0;if(!G[d>>2]){continue}break}}G[d>>2]=0}a=a+1|0;if((f|0)!=(a|0)){continue}break}a=0;E[e|0]=0;if((f|0)<=0){break h}b=0;while(1){d=G[c+(b<<2)>>2];if(d){if((Va(d)+a|0)>=8191){break h}h=Va(e)+e|0;E[h|0]=47;E[h+1|0]=0;Gb(e,d);a=(Va(d)+a|0)+1|0}b=b+1|0;if((f|0)!=(b|0)){continue}break}break h}E[e|0]=0}if(!g){break d}Wa(g)}Fa=c+40960|0;a=Lc(e)}Fa=e+16480|0;return a}function Do(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0;n=c==1&d==0;a:{b:{if(!e){if(n){break b}if((b|0)<=0){break a}while(1){f=j+l|0;m=+G[(l<<2)+a>>2]*c+d;c:{if(m<-128.49){G[k>>2]=-11;e=128;break c}if(m>127.49){G[k>>2]=-11;e=127;break c}e=~~m;if(O(m)<2147483648){break c}e=-2147483648}E[f|0]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if(!n){if((b|0)<=0){break a}e=(e|0)==1;n=e?g:1;h=e?j:h;while(1){e=G[(l<<2)+a>>2];d:{if((e|0)==(f|0)){G[i>>2]=1;g=n;e=h;break d}m=+(e|0)*c+d;e:{if(m<-128.49){G[k>>2]=-11;g=128;break e}if(m>127.49){G[k>>2]=-11;g=127;break e}g=~~m;if(O(m)<2147483648){break e}g=-2147483648}e=j}E[e+l|0]=g;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)==1){while(1){e=G[(l<<2)+a>>2];f:{if((f|0)!=(e|0)){if((e|0)>=-128){if((e|0)<=127){break f}G[k>>2]=-11;e=127;break f}G[k>>2]=-11;e=128;break f}G[i>>2]=1;e=g}E[j+l|0]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break a}}while(1){e=G[(l<<2)+a>>2];g:{if((f|0)==(e|0)){e=1;G[i>>2]=1;g=h;break g}h:{if((e|0)<=-129){G[k>>2]=-11;e=128;break h}if((e|0)<128){break h}G[k>>2]=-11;e=127}g=j}E[g+l|0]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}e=b&1;if((b|0)!=1){g=b&-2;f=0;while(1){b=G[(l<<2)+a>>2];i:{if((b|0)<=-129){G[k>>2]=-11;b=128;break i}if((b|0)<128){break i}G[k>>2]=-11;b=127}E[j+l|0]=b;h=l|1;b=G[(h<<2)+a>>2];j:{if((b|0)>=-128){if((b|0)<=127){break j}G[k>>2]=-11;b=127;break j}G[k>>2]=-11;b=128}E[h+j|0]=b;l=l+2|0;f=f+2|0;if((g|0)!=(f|0)){continue}break}}if(!e){break a}a=G[(l<<2)+a>>2];k:{if((a|0)>=-128){if((a|0)<=127){break k}G[k>>2]=-11;a=127;break k}G[k>>2]=-11;a=128}E[j+l|0]=a}}function ps(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;l=+l;m=+m;n=+n;o=+o;var p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;s=M(c,3);r=G[a>>2];if(O(o)<2147483648){q=~~o}else{q=-2147483648}z=q;q=r+s|0;if(O(l)<2147483648){s=~~l}else{s=-2147483648}r=q-2|0;a:{if(d){if(!re(a,0,r,d,e,f,g,h,i,m,n)){break a}p=G[a+8>>2];t=q-1|0;r=p+M(t,168)|0;k=L[r+8>>3];if(k>g){break a}j=L[r+16>>3];if(!(g>=k)|j>2];if(O(g)<2147483648){r=~~g}else{r=-2147483648}p=G[p+(r<<2)>>2];b:{if(!p){break b}while(1){if(!(+G[p+4>>2]<=f)){break b}q=q+1|0;p=G[p>>2];if(p){continue}break}}w=1;if((q&1)!=(d|0)|(s|0)<=0|(z|0)<=0){break a}l=(n-m)/o;t=r<<2;q=0;while(1){r=q+z|0;u=1;while(1){c:{x=b+q|0;p=q<<1;if(!re(a,x,p+c|0,d,e,f,g,h,i,+(u-1|0)*l+m,+(u|0)*l+m)){break c}p=G[a+8>>2]+M((p|1)+c|0,168)|0;k=L[p+8>>3];if(k>g){break c}j=L[p+16>>3];if(!(g>=k)|j>2]>>2];d:{if(!p){break d}while(1){if(!(+G[p+4>>2]<=f)){break d}y=y+1|0;p=G[p>>2];if(p){continue}break}}if((y&1)!=(d|0)){break c}v=1;if(!x){break a}G[a+12>>2]=x;return 1}u=u+1|0;q=q+1|0;if((r|0)!=(q|0)){continue}break}p=(s|0)==(w|0);q=r;w=w+1|0;if(!p){continue}break}break a}v=1;if(!re(a,0,r,1,e,f,g,h,i,m,n)){break a}b=G[a+8>>2];c=q-1|0;a=b+M(c,168)|0;i=L[a+8>>3];e:{if(i>g){break e}h=L[a+16>>3];if(!(g>=i)|(!(h>=g)|g>h)){break e}b=G[(b+M(c,168)|0)+24>>2];if(O(g)<2147483648){a=~~g}else{a=-2147483648}p=G[b+(a<<2)>>2];if(!p){break e}q=0;while(1){if(+G[p+4>>2]<=f){q=q+1|0;p=G[p>>2];if(p){continue}}break}v=0;if(q&1){break a}}v=1}return v|0}function vp(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0;l=c==1&d==0;a:{if(!e){if(!l){l=0;if((b|0)<=0){break a}while(1){f=j+l|0;b:{c:{m=+H[a+l|0]*c+d;if(m<-.49){G[k>>2]=-11;break c}if(m>255.49){G[k>>2]=-11;e=255;break b}if(!(m<4294967296&m>=0)){break c}e=~~m>>>0;break b}e=0}E[f|0]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}yd(j,a,b);break a}d:{if(!l){if((b|0)<=0){break a}l=0;if((e|0)!=1){break d}while(1){h=j+l|0;e=H[a+l|0];e:{if((e|0)!=(f|0)){m=+(e>>>0)*c+d;if(!(m<-.49)){if(!(m>255.49)){e=~~m>>>0;if(m<4294967296&m>=0){break e}e=0;break e}G[k>>2]=-11;e=255;break e}G[k>>2]=-11;e=0;break e}G[i>>2]=1;e=g}E[h|0]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)!=1){l=0;if((b|0)!=1){n=b&-2;g=0;while(1){e=H[a+l|0];if((f|0)==(e|0)){e=1;G[i>>2]=1;k=h}else{k=j}E[k+l|0]=e;k=l|1;e=H[k+a|0];if((f|0)==(e|0)){e=1;G[i>>2]=1;o=h}else{o=j}E[o+k|0]=e;l=l+2|0;g=g+2|0;if((n|0)!=(g|0)){continue}break}}if(!(b&1)){break a}a=H[a+l|0];if((f|0)==(a|0)){G[i>>2]=1;j=h;a=1}E[j+l|0]=a;break a}h=b&1;l=0;if((b|0)!=1){k=b&-2;e=0;while(1){n=j+l|0;b=H[a+l|0];if((b|0)==(f|0)){G[i>>2]=1;b=g}E[n|0]=b;n=l|1;b=H[n+a|0];if((f|0)==(b|0)){G[i>>2]=1;b=g}E[j+n|0]=b;l=l+2|0;e=e+2|0;if((k|0)!=(e|0)){continue}break}}if(!h){break a}b=j+l|0;a=H[a+l|0];if((a|0)==(f|0)){G[i>>2]=1}else{g=a}E[b|0]=g;break a}while(1){e=H[a+l|0];f:{if((e|0)==(f|0)){g=1;G[i>>2]=1;e=h;break f}g:{h:{m=+(e>>>0)*c+d;if(m<-.49){G[k>>2]=-11;break h}if(m>255.49){G[k>>2]=-11;g=255;break g}if(!(m<4294967296&m>=0)){break h}g=~~m>>>0;break g}g=0}e=j}E[e+l|0]=g;l=l+1|0;if((l|0)!=(b|0)){continue}break}}}function Im(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;c=Fa-688|0;Fa=c;a:{b:{c:{d:{e:{f:{g:{g=lb(1,28);if(g){G[g+16>>2]=2;f=ab(8);G[g+12>>2]=f;if(!f){break g}e=2;d=f;while(1){G[d>>2]=G[a>>2]-1;d=d+4|0;a=a+4|0;e=e-1|0;h=h+1|0;if((h|0)!=2){continue}break}G[g+24>>2]=1;i=ab(4);G[g+20>>2]=i;if(!i){break f}a=0;cb(c+160|0,0,4);d=1;while(1){e=G[f+(a<<2)>>2];if((e|0)>0){break e}e=(c+160|0)+(e<<2)|0;G[e>>2]=G[e>>2]+1;a=a+1|0;if((a|0)!=2){continue}break}G[g+8>>2]=1;while(1){f=j<<2;a=G[b>>2];G[f+i>>2]=a;if((a|0)>=11){break d}b=b+4|0;o=d;if(a){f=G[f+(c+160|0)>>2];k=a&3;e=1;h:{if(a-1>>>0<3){h=1;break h}p=a&-4;d=0;h=1;while(1){l=a-3|0;m=a-2|0;n=a-1|0;e=M(l,M(m,M(n,M(a,e))));h=M(f+l|0,M(f+m|0,M(f+n|0,M(a+f|0,h))));a=a-4|0;d=d+4|0;if((p|0)!=(d|0)){continue}break}}d=0;if(k){while(1){e=M(a,e);h=M(a+f|0,h);a=a-1|0;d=d+1|0;if((k|0)!=(d|0)){continue}break}}a=(h|0)/(e|0)|0}else{a=1}d=M(o,a);G[g+8>>2]=d;j=j+1|0;if((j|0)!=1){continue}break}a=ab(d<<3);G[g>>2]=a;if(!a){break c}a=lb(d,8);G[g+4>>2]=a;if(!a){break b}Fa=c+688|0;return g}G[c+4>>2]=66012;G[c>>2]=66133;_a(G[24367],90100,c);break a}G[c+148>>2]=65848;G[c+144>>2]=66133;_a(G[24367],90100,c+144|0);break a}G[c+84>>2]=65729;G[c+80>>2]=66133;_a(G[24367],90100,c+80|0);break a}G[c+132>>2]=92041;G[c+128>>2]=24180;_a(G[24367],90100,c+128|0);break a}G[c+116>>2]=10;G[c+112>>2]=a;a=c+176|0;db(a,62519,c+112|0);G[c+96>>2]=67642;G[c+100>>2]=a;_a(G[24367],90100,c+96|0);break a}G[c+52>>2]=65884;G[c+48>>2]=66133;_a(G[24367],90100,c+48|0);break a}G[c+68>>2]=65922;G[c+64>>2]=66133;_a(G[24367],90100,c- -64|0)}ca(-1);W()}function up(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0;n=c==1&d==0;a:{b:{if(!e){if(n){break b}if((b|0)<=0){break a}while(1){f=j+l|0;c:{d:{m=+G[(l<<2)+a>>2]*c+d;if(m<-.49){G[k>>2]=-11;break d}if(m>255.49){G[k>>2]=-11;e=255;break c}if(!(m<4294967296&m>=0)){break d}e=~~m>>>0;break c}e=0}E[f|0]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if(!n){if((b|0)<=0){break a}e=(e|0)==1;n=e?g:1;h=e?j:h;while(1){e=G[(l<<2)+a>>2];e:{if((e|0)==(f|0)){G[i>>2]=1;g=n;e=h;break e}f:{g:{m=+(e|0)*c+d;if(m<-.49){G[k>>2]=-11;break g}if(m>255.49){G[k>>2]=-11;g=255;break f}if(!(m<4294967296&m>=0)){break g}g=~~m>>>0;break f}g=0}e=j}E[e+l|0]=g;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}if((e|0)==1){while(1){e=G[(l<<2)+a>>2];h:{if((f|0)!=(e|0)){if((e|0)>=0){if(e>>>0<=255){break h}G[k>>2]=-11;e=255;break h}G[k>>2]=-11;e=0;break h}G[i>>2]=1;e=g}E[j+l|0]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break a}}while(1){e=G[(l<<2)+a>>2];i:{if((f|0)==(e|0)){e=1;G[i>>2]=1;g=h;break i}j:{if((e|0)<0){G[k>>2]=-11;e=0;break j}if(e>>>0<256){break j}G[k>>2]=-11;e=255}g=j}E[g+l|0]=e;l=l+1|0;if((l|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}e=b&1;if((b|0)!=1){g=b&-2;f=0;while(1){b=G[(l<<2)+a>>2];k:{if((b|0)<0){G[k>>2]=-11;b=0;break k}if(b>>>0<256){break k}G[k>>2]=-11;b=255}E[j+l|0]=b;h=l|1;b=G[(h<<2)+a>>2];l:{if((b|0)>=0){if(b>>>0<=255){break l}G[k>>2]=-11;b=255;break l}G[k>>2]=-11;b=0}E[h+j|0]=b;l=l+2|0;f=f+2|0;if((g|0)!=(f|0)){continue}break}}if(!e){break a}a=G[(l<<2)+a>>2];m:{if((a|0)>=0){if(a>>>0<=255){break m}G[k>>2]=-11;a=255;break m}G[k>>2]=-11;a=0}E[j+l|0]=a}}function Mr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;a:{if(G[c+4>>2]==703){g=L[c+120>>3];break a}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=81;E[c+1|0]=83;E[c+2|0]=67;E[c+3|0]=0;E[c+4|0]=191;E[c+5|0]=2;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;g=L[c+24>>3];b:{if(g==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=45;g=.022222222222222223;break b}f=g*3.141592653589793*.25;g=1/f}G[c+1892>>2]=105;G[c+1888>>2]=106;L[c+112>>3]=f;L[c+120>>3]=g}b=g*b;a=g*a;g=O(a);c:{d:{if(g<=1){c=2;if(!(O(b)>3)){break d}break c}c=2;if(g>7|O(b)>1){break c}}e:{f:{h=a<-1?a+8:a;g:{if(h>5){a=h+-6;break g}if(h>3){n=1;a=h+-4;break g}if(h>1){o=1;a=h+-2;break g}h:{if(b>1){b=b+-2;m=1;break h}if(!(b<-1)){p=1;m=0;break h}b=b+2;m=0}a=h}j=a;k=O(j)>O(b);i:{j:{if(k){f=0;l=1;a=1;if(j==0){break i}a=b*15/j;i=Kb(a)/(Mb(a)+-.7071067811865475);l=i*i+1;g=j*j;break j}f=0;l=1;a=1;if(b==0){break i}a=j*15/b;i=Kb(a)/(Mb(a)+-.7071067811865475);l=i*i+1;g=b*b}a=-1;f=g*(-1/V(l+1)+1);g=1-f;if(g<-1){break f}a=g}f=V(f*(2-f)/l);break e}f=0;if(g<-1.000000000001){break c}}k:{if(m){if(k){h=j<0?-f:f;b=i*-h;break k}b=b>0?-f:f;h=i*-b;break k}if(p){if(k){b=a;h=j<0?-f:f;a=i*h;break k}g=b<0?-f:f;h=i*g;b=a;a=g;break k}if(o){if(k){h=a;b=j>0?-f:f;a=i*-b;break k}g=b<0?-f:f;b=i*-g;h=a;a=g;break k}g=-a;if(n){if(k){h=j>0?-f:f;a=i*-h;b=g;break k}a=b<0?-f:f;h=i*-a;b=g;break k}if(h>5){if(k){b=j<0?-f:f;a=i*b;h=g;break k}a=b<0?-f:f;b=i*a;h=g;break k}l:{if(k){h=j<0?-f:f;b=i*h;break l}b=b<0?-f:f;h=i*b}a=g}if(b==0&h==0){b=0}else{b=Ac(h,b)}L[d>>3]=b;q=e,r=Bc(a),L[q>>3]=r;c=0}return c|0}function sp(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0,o=0;a:{b:{if(!e){if(c==1&d==0){break b}if((b|0)<=0){break a}while(1){f=i+k|0;c:{d:{l=L[(k<<3)+a>>3]*c+d;if(l<-.49){G[j>>2]=-11;break d}if(l>255.49){G[j>>2]=-11;e=255;break c}if(!(l<4294967296&l>=0)){break d}e=~~l>>>0;break c}e=0}E[f|0]=e;k=k+1|0;if((k|0)!=(b|0)){continue}break}break a}k=a+6|0;e:{f:{if(!(c==1&d==0)){if((b|0)<=0){break a}e=(e|0)==1;o=e?f:1;m=e?i:g;if(!(d<4294967296&d>=0)){break f}n=~~d>>>0;break e}if((b|0)<=0){break a}e=(e|0)==1;n=e?f:1;o=e?i:g;e=0;while(1){g=i;f=0;g:{h:{i:{m=I[k>>1]&32752;switch(((m|0)==32752?1:!m<<1)|0){case 0:break h;case 1:break i;default:break g}}G[h>>2]=1;g=o;f=n;break g}c=L[(e<<3)+a>>3];if(c<-.49){G[j>>2]=-11;break g}j:{if(c>255.49){G[j>>2]=-11;f=255;break j}f=~~c>>>0;if(c<4294967296&c>=0){break j}f=0}}E[e+g|0]=f;k=k+8|0;e=e+1|0;if((e|0)!=(b|0)){continue}break}break a}n=0}e=0;while(1){k:{l:{m:{n:{o:{p:{f=I[k>>1]&32752;switch(((f|0)==32752?1:!f<<1)|0){case 0:break n;case 1:break p;default:break o}}G[h>>2]=1;f=o;g=m;break k}if(d<-.49){G[j>>2]=-11;break m}f=n;g=i;if(!(d>255.49)){break k}G[j>>2]=-11;f=255;break l}l=L[(e<<3)+a>>3]*c+d;if(l<-.49){G[j>>2]=-11;f=0;break l}if(l>255.49){G[j>>2]=-11;f=255;break l}if(!(l<4294967296&l>=0)){break m}f=~~l>>>0;break l}f=0}g=i}E[g+e|0]=f;k=k+8|0;e=e+1|0;if((e|0)!=(b|0)){continue}break}break a}if((b|0)<=0){break a}while(1){f=i+k|0;q:{r:{c=L[(k<<3)+a>>3];if(c<-.49){G[j>>2]=-11;break r}if(c>255.49){G[j>>2]=-11;e=255;break q}if(!(c<4294967296&c>=0)){break r}e=~~c>>>0;break q}e=0}E[f|0]=e;k=k+1|0;if((k|0)!=(b|0)){continue}break}}}function Xh(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;j=Fa-16|0;Fa=j;if(H[a+1|0]){d=ab(160);G[j+12>>2]=a;a:{if(!H[a|0]){break a}e=20;while(1){g=vb(a,j+12|0);a=G[j+12>>2];c=H[a|0];b:{if((c|0)!=46){b=a;break b}b=a+1|0;G[j+12>>2]=b;c=H[a+1|0]}if(!c){break a}c=i+1|0;if((c|0)>=(e|0)){e=e+20|0;d=ub(d,e<<3)}L[(i<<3)+d>>3]=g;i=b;while(1){a=i;i=a+1|0;if(H[a|0]==32){continue}break}i=c;if(H[b|0]){continue}break}i=1}b=0;f=Fa-80|0;Fa=f;e=d;g=L[e+8>>3]+.5;c:{if(O(g)<2147483648){d=~~g;break c}d=-2147483648}d:{if((d|0)<=0){G[f>>2]=d;_a(G[24367],74914,f);break d}g=L[e+16>>3]+.5;e:{if(O(g)<2147483648){c=~~g;break e}c=-2147483648}if((c|0)<=0){G[f+16>>2]=c;_a(G[24367],74880,f+16|0);break d}l=L[e+32>>3];m=L[e+40>>3];if(l>=m){L[f+72>>3]=m;L[f+64>>3]=l;xb(G[24367],72443,f- -64|0);break d}n=L[e+56>>3];o=L[e+48>>3];if(n<=o){L[f+56>>3]=n;L[f+48>>3]=o;xb(G[24367],72406,f+48|0);break d}f:{g:{h:{g=L[e>>3]+.5;i:{if(O(g)<2147483648){a=~~g;break i}a=-2147483648}if(a-1>>>0<=2){b=ab(64);G[b+40>>2]=c;G[b+36>>2]=d;L[b+8>>3]=(l+m)*-.5;L[b>>3]=2/(m-l);L[b+24>>3]=(o+n)*-.5;L[b+16>>3]=2/(n-o);g=L[e+24>>3];j:{if(O(g)<2147483648){k=~~g;break j}k=-2147483648}G[b+44>>2]=k;k:{switch(k|0){case 2:h=(d|0)<(c|0)?d:c;h=M(d,c)+((M(h-1|0,h)|0)/-2|0)|0;break g;case 0:break h;case 1:break k;default:break f}}h=M(d,c);break g}G[f+32>>2]=a;_a(G[24367],74966,f+32|0);break d}h=(d+c|0)-1|0}G[b+48>>2]=h}G[b+32>>2]=a;k=h<<3;a=ab(k);G[b+52>>2]=a;if((h|0)>0){bb(a,e- -64|0,k)}p=b,q=ab(d<<3),G[p+56>>2]=q;p=b,q=ab(c<<3),G[p+60>>2]=q}Fa=f+80|0;Wa(e);a=i?b:0}else{a=0}Fa=j+16|0;return a}function ne(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;k=Fa-16|0;Fa=k;d=G[c>>2];a:{if((d|0)>0){break a}if((a|0)==(b|0)){d=101;G[c>>2]=101;break a}b:{if((wo(a,b,c)|0)>0){break b}if((Td(a,0,k+12|0,c)|0)>0){break b}e=G[k+12>>2];c:{if((e|0)<=0){break c}if(!((e|0)<=0|G[c>>2]>0)){d:{h=G[b>>2];d=G[b+4>>2];if((h|0)!=G[d+76>>2]){mb(b,h+1|0,0,c);break d}if((G[d+128>>2]&G[d+132>>2])!=-1){break d}Rb(b,c);i=G[b+4>>2];d=i;h=G[d+128>>2];l=G[d+132>>2];f=M(e,80);e=f+G[d+104>>2]|0;g=G[d+108>>2]+(f>>31)|0;g=f>>>0>e>>>0?g+1|0:g;f=Cu(e,g);j=(e-f|0)+2880|0;f=g-(Ia+(f>>>0>e>>>0)|0)|0;e=j;G[d+128>>2]=e;f=e>>>0<2880?f+1|0:f;G[d+132>>2]=f;d=G[d+96>>2]+(G[d+76>>2]<<3)|0;i=d;j=e-h|0;g=j+G[d+8>>2]|0;d=G[d+12>>2]+(f-((e>>>0>>0)+l|0)|0)|0;G[i+8>>2]=g;G[i+12>>2]=g>>>0>>0?d+1|0:d}}if(G[k+12>>2]<35){break c}rk(b,c)}e=0;d=Fa-2912|0;Fa=d;e:{if(G[c>>2]>0){break e}if((a|0)==(b|0)){G[c>>2]=101;break e}ok(a,0,d+2904|0,d+2896|0,c);ok(b,0,d+2888|0,0,c);g=G[d+2896>>2];f=G[d+2904>>2];h=G[d+2908>>2];i=Bu(g-f|0,G[d+2900>>2]-(h+(f>>>0>g>>>0)|0)|0,2880,0);f:{if((i|0)<=0){break f}if(G[a+4>>2]==G[b+4>>2]){while(1){Jb(a,f,h,0,c);ic(a,2880,0,d,c);Jb(b,G[d+2888>>2],G[d+2892>>2],1,c);Wb(b,2880,0,d,c);h=G[d+2908>>2];f=G[d+2904>>2]+2880|0;h=f>>>0<2880?h+1|0:h;G[d+2904>>2]=f;G[d+2908>>2]=h;g=G[d+2892>>2];j=G[d+2888>>2]+2880|0;g=j>>>0<2880?g+1|0:g;G[d+2888>>2]=j;G[d+2892>>2]=g;e=e+1|0;if((i|0)!=(e|0)){continue}break f}}Jb(a,f,h,0,c);Jb(b,G[d+2888>>2],G[d+2892>>2],1,c);while(1){ic(a,2880,0,d,c);Wb(b,2880,0,d,c);e=e+1|0;if((i|0)!=(e|0)){continue}break}}}Fa=d+2912|0}d=G[c>>2]}Fa=k+16|0;return d}function ap(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;a:{b:{if((b|0)==1){c=H[c|0];b=G[48830];G[48830]=b-4;c=c&15|G[48829]<<4;G[48829]=c;if((b|0)<=4){d=a;a=G[48828];E[d+a|0]=c>>4-b;if((a|0)>>0<4?d+1|0:d;b=a;a=d;break b}c:{d=G[48830];if((d|0)>4){k=d;break c}g=H[c|0]&15|G[48829]<<4;G[48829]=g;e=G[48828];E[e+a|0]=g>>4-d;i=G[48827];if((i|0)>(e|0)){e=e+1|0;G[48828]=e}k=d+4|0;G[48830]=k;f=G[48833];j=f;l=G[48832];h=l+4|0;f=h>>>0<4?f+1|0:f;G[48832]=h;G[48833]=f;h=1;if((b|0)!=2){break c}b=H[c+1|0];G[48830]=d;b=b&15|g<<4;G[48829]=b;if((d|0)<=0){E[a+e|0]=b>>0-d;if((e|0)<(i|0)){G[48828]=e+1}G[48830]=d+8}a=j;b=l+8|0;a=b>>>0<8?a+1|0:a;break b}g=b-h|0;j=(g|0)/2|0;d:{e:{if((k|0)!=8){d=0;f=G[48828];e=G[48829];i=-8;l=-1;if((g|0)<=1){break d}g=8-k|0;while(1){i=c+h|0;e=H[i|0]<<4&240|e<<8|H[i+1|0]&15;E[a+f|0]=e>>g;f=f+1|0;h=h+2|0;d=d+1|0;if((j|0)!=(d|0)){continue}break}G[48829]=e;break e}e=0;G[48829]=0;f=G[48828];i=-8;l=-1;if((g|0)<2){break d}if((g&-2)!=2){g=j&-2;d=0;while(1){i=a+f|0;e=c+h|0;E[i|0]=H[e+1|0]&15|H[e|0]<<4;E[i+1|0]=H[e+3|0]&15|H[e+2|0]<<4;f=f+2|0;h=h+4|0;d=d+2|0;if((g|0)!=(d|0)){continue}break}}e=0;if(!(j&1)){break e}d=c+h|0;E[a+f|0]=H[d+1|0]&15|H[d|0]<<4;f=f+1|0;h=h+2|0}G[48828]=f;d=(j<<3)-8|0;i=d;l=d>>31}g=G[48832];j=g+i|0;d=G[48833]+l|0;d=g>>>0>j>>>0?d+1|0:d;G[48832]=j;G[48833]=d;if((b|0)==(h|0)){break a}b=H[(b+c|0)-1|0];G[48830]=k-4;b=b&15|e<<4;G[48829]=b;if((k|0)<=4){E[a+f|0]=b>>4-k;if(G[48827]>(f|0)){G[48828]=f+1}G[48830]=k+4}b=j+4|0;a=b>>>0<4?d+1|0:d}G[48832]=b;G[48833]=a}}function zo(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;h=(d+1|0)/2|0;a:{if((c|0)<=0){break a}if((d|0)>0){j=c+1>>>1|0;k=M(h,j)-1|0;while(1){i=j-1|0;l=h+M(i,d)<<1;f=h;while(1){l=l-2|0;E[l+e|0]=H[b+k|0];k=k-1|0;m=(f|0)>1;f=f-1|0;if(m){continue}break}f=(j|0)>1;j=i;if(f){continue}break}}if((c|0)<2){break a}if((d|0)>=2){j=c-1|0;i=d-1|0;k=(d&-2)>>>0>>0;while(1){f=M(d,g);l=f+d|0;h=0;while(1){m=e+f|0;b=E[m|0];if(b>>>0<=15){n=e+l|0;E[n|0]=H[b+119004|0];E[n+1|0]=H[b+118988|0];E[(f|1)+e|0]=H[b+119020|0];E[m|0]=H[b+119036|0]}l=l+2|0;f=f+2|0;h=h+2|0;if((i|0)>(h|0)){continue}break}if(k){b=e+f|0;f=H[b|0];E[e+l|0]=f>>>1&1;E[b|0]=f>>>3&1}g=g+2|0;if((j|0)>(g|0)){continue}break}break a}b:{c:{if((d|0)==1){b=c-2|0;f=(b>>>1|0)+1|0;h=f&1;if(b>>>0>=2){break c}break b}g=c&-2;break a}b=f&-2;f=0;while(1){j=e+g|0;i=H[j|0];E[(g|1)+e|0]=i>>>1&1;E[j|0]=i>>>3&1;j=(g|2)+e|0;i=H[j|0];E[(g|3)+e|0]=i>>>1&1;E[j|0]=i>>>3&1;g=g+4|0;f=f+2|0;if((b|0)!=(f|0)){continue}break}}if(!h){break a}b=e+g|0;f=H[b|0];E[(g|1)+e|0]=f>>>1&1;E[b|0]=f>>>3&1;g=g+2|0}d:{if((c|0)<=(g|0)){break d}f=M(d,g);k=0;if((d|0)>=2){b=d-2|0;h=(b>>>1|0)+1|0;j=h&1;if(b>>>0>=2){h=h&-2;while(1){b=e+f|0;i=H[b|0];E[(f|1)+e|0]=i>>>2&1;E[b|0]=i>>>3&1;i=f+2|0;g=i+e|0;b=H[g|0];E[(i|1)+e|0]=b>>>2&1;E[g|0]=b>>>3&1;f=f+4|0;k=k+2|0;if((h|0)!=(k|0)){continue}break}}k=d&-2;if(j){b=e+f|0;h=H[b|0];E[(f|1)+e|0]=h>>>2&1;E[b|0]=h>>>3&1;f=f+2|0}}if((d|0)<=(k|0)){break d}b=e+f|0;E[b|0]=H[b|0]>>>3&1}f=M(c,d);if((f|0)>0){while(1){b=f-1|0;c=b+e|0;if(H[c|0]){o=c,p=wh(a),E[o|0]=p}c=f>>>0>1;f=b;if(c){continue}break}}}function _d(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0;a:{f=G[c>>2];if(!f){d=ab(8);if(d){G[d>>2]=0;G[d+4>>2]=0}E[b|0]=0;b:{c:{d:{e:{f:{f=Sb(a,42197);g:{if(!f){f=a;break g}f=jb(f+3|0,47);if(!f){break f}e=a;a=f-a|0;i=rb(b,e,a)+a|0,j=0,E[i|0]=j}if(H[f|0]==47){a=Va(b)+b|0;E[a|0]=47;E[a+1|0]=0}a=pc(f,42205);if(!a){break e}while(1){h:{if(!Xa(a,45311)){if(G[d>>2]){e=G[d+4>>2];if(!e){break h}a=G[e+8>>2];G[a+4>>2]=G[e+4>>2];G[G[e+4>>2]+8>>2]=a;Wa(e);G[d+4>>2]=a;a=G[d>>2]-1|0;G[d>>2]=a;if(a){break h}G[d+4>>2]=0;break h}if(H[f|0]==47){break h}g=G[d+4>>2];e=ab(12);G[e>>2]=a;i:{if(g){a=G[g+4>>2];G[e+8>>2]=g;G[a+8>>2]=e;g=g+4|0;break i}a=e;g=a+8|0}G[g>>2]=e;G[e+4>>2]=a;G[d>>2]=1;G[d+4>>2]=e;break h}if(!d|!Xa(a,48504)){break h}g=G[d+4>>2];e=ab(12);G[e>>2]=a;j:{if(g){a=G[g+4>>2];G[e+8>>2]=g;G[a+8>>2]=e;g=g+4|0;break j}a=e;g=a+8|0}G[g>>2]=e;G[e+4>>2]=a;G[d+4>>2]=e;G[d>>2]=G[d>>2]+1}a=pc(0,42205);if(a){continue}break}break e}Za(b,a);break d}if(G[d>>2]){h=G[d>>2];a=G[d+4>>2];while(1){g=G[a+4>>2];e=G[g>>2];f=G[g+8>>2];G[f+4>>2]=G[g+4>>2];G[G[g+4>>2]+8>>2]=f;Wa(g);h=h-1|0;a=h?a:0;if((Va(b)+Va(e)|0)-1024>>>0<=4294966270){G[d>>2]=h;G[d+4>>2]=a;E[b|0]=0;Ua(59088);G[c>>2]=125;if(!h){break c}a=G[d+4>>2];if(!a){break a}while(1){b=a;a=0;if(!b){continue}a=G[b+8>>2];G[a+4>>2]=G[b+4>>2];G[G[b+4>>2]+8>>2]=a;Wa(b);G[d+4>>2]=a;b=G[d>>2]-1|0;G[d>>2]=b;if(b){continue}break}G[d+4>>2]=0;break c}f=Gb(b,e);f=Va(f)+f|0;E[f|0]=47;E[f+1|0]=0;if(h){continue}break}G[d>>2]=h;G[d+4>>2]=a}i=(Va(b)+b|0)-1|0,j=0,E[i|0]=j}if(!d){break b}}Wa(d)}f=G[c>>2]}return f}while(1)continue}function $h(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;g=L[b>>3];h=L[a>>3]*3.141592653589793/180;i=ib(h);g=g*3.141592653589793/180;j=eb(g);m=i*j;k=eb(h);n=j*k;s=L[d>>3]*36e4;o=L[c>>3];h=ib(g);t=o*36e4;a:{if(t==0){g=0;if(s==0){break a}}l=h*-k*s-m*t;q=j*s;g=t*n-s*(h*i)}i=q*-242404995e-14+(g*6585e-14+(l*1.177742e-8+(h*.9999881946+(m*-271557e-10+(n*-.004859004+0)))));k=q*-1.177742e-8+(g*-2.710544e-8+(l*-24238984e-13+(h*.0048590039+(m*.0111814828+(n*.9999256795+0)))));o=q*6585e-14+(g*-242392702e-14+(l*2.710544e-8+(h*-271771e-10+(m*.9999374849+(n*-.0111814828+0)))));j=-(i*-1.3843e-7+(k*-162557e-11+o*-3.1919e-7));u=j*i;p=V(i*i+(k*k+o*o));r=u+(p*-1.3843e-7+i);w=r*r;x=j*k;r=x+(p*-162557e-11+k);y=j*o;j=y+(p*-3.1919e-7+o);j=V(w+(r*r+j*j));z=j*-659e-6+(q*.99996684+(g*-2716e-8+(l*-.00485852+(h*.002117+(m*-.008541+(n*.43573+0))))));r=i*-659e-6+(k*.001245+o*-.00158);p=u+(j*-1.3843e-7+i);u=r*p;w=j*-.00158+(q*-2717e-8+(g*.99991613+(l*-.01118145+(h*.012254+(m*-.002667+(n*-.23856+0))))));i=y+(j*-3.1919e-7+o);o=r*i;l=j*.001245+(q*.00485852+(g*.01118145+(l*.99990432+(h*-.435614+(m*.238509+(n*-551e-6+0))))));g=x+(j*-162557e-11+k);k=r*g;h=g*g+i*i;m=V(h);b:{if(g==0&i==0){break b}v=Db(i,g);if(!(v<0)){break b}v=v+6.283185307179586}q=z-u;n=w-o;l=l-k;if(m>1e-30){t=(g*n-l*i)/h;s=(q*h-(g*l+i*n)*p)/((p*p+h)*m)}h=L[e>>3];if(h>1e-30){L[f>>3]=(p*q+(g*l+i*n))/(j*(h*21.095));L[e>>3]=L[e>>3]/j}L[a>>3]=v*180/3.141592653589793;A=b,B=Db(p,m)*180/3.141592653589793,L[A>>3]=B;L[c>>3]=t/36e4;L[d>>3]=s/36e4}function dl(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0;a:{b:{if(!e){if(c==1&d==0){break a}if((b|0)<=0){break b}h=b&3;e=0;if(b-1>>>0>=3){j=b&-4;b=0;while(1){g=k<<3;L[g+i>>3]=L[a+g>>3]*c+d;m=g|8;L[m+i>>3]=L[a+m>>3]*c+d;m=g|16;L[m+i>>3]=L[a+m>>3]*c+d;g=g|24;L[g+i>>3]=L[a+g>>3]*c+d;k=k+4|0;b=b+4|0;if((j|0)!=(b|0)){continue}break}}if(!h){break b}while(1){b=k<<3;L[b+i>>3]=L[a+b>>3]*c+d;k=k+1|0;e=e+1|0;if((h|0)!=(e|0)){continue}break}break b}k=a+6|0;c:{if(!(c==1&d==0)){if((b|0)<=0){break b}if((e|0)!=1){break c}while(1){l=d;d:{e:{f:{e=I[k>>1]&32752;switch(((e|0)==32752?1:!e<<1)|0){case 0:break e;case 1:break f;default:break d}}G[h>>2]=1;l=f;break d}l=L[(j<<3)+a>>3]*c+d}L[(j<<3)+i>>3]=l;k=k+8|0;j=j+1|0;if((j|0)!=(b|0)){continue}break}break b}if((b|0)<=0){break b}if((e|0)==1){while(1){d=0;g:{h:{i:{e=I[k>>1]&32752;switch(((e|0)==32752?1:!e<<1)|0){case 0:break h;case 1:break i;default:break g}}G[h>>2]=1;d=f;break g}d=L[(j<<3)+a>>3]}L[(j<<3)+i>>3]=d;k=k+8|0;j=j+1|0;if((j|0)!=(b|0)){continue}break b}}while(1){d=0;j:{k:{l:{e=I[k>>1]&32752;switch(((e|0)==32752?1:!e<<1)|0){case 0:break k;case 1:break l;default:break j}}G[h>>2]=1;E[g+j|0]=1;d=-91191291391491e-49;break j}d=L[(j<<3)+a>>3]}L[(j<<3)+i>>3]=d;k=k+8|0;j=j+1|0;if((j|0)!=(b|0)){continue}break}break b}while(1){l=d;m:{n:{o:{e=I[k>>1]&32752;switch(((e|0)==32752?1:!e<<1)|0){case 0:break n;case 1:break o;default:break m}}G[h>>2]=1;E[g+j|0]=1;l=-91191291391491e-49;break m}l=L[(j<<3)+a>>3]*c+d}L[(j<<3)+i>>3]=l;k=k+8|0;j=j+1|0;if((j|0)!=(b|0)){continue}break}}return}yd(i,a,b<<3)}function xk(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;j=Fa-96|0;Fa=j;h=G[f>>2];a:{if((h|0)>0){break a}b:{k=G[a>>2];h=G[a+4>>2];c:{d:{if((k|0)!=G[h+76>>2]){mb(a,k+1|0,0,f);break d}if((G[h+128>>2]&G[h+132>>2])!=-1){break d}if((Rb(a,f)|0)>0){break c}}if(!G[G[a+4>>2]+80>>2]){Ua(49395);h=235;G[f>>2]=235;break a}if((e|0)<0){h=306;G[f>>2]=306;break a}if(!(d|e)){break c}_f(a,41261,j+80|0,j,f);g=G[a+4>>2];h=G[g+952>>2];k=G[g+956>>2];if(h>>>0>>0&(k|0)<=(c|0)|(c|0)>(k|0)){Ua(49509);break b}if(!b&(c|0)<=0|(c|0)<0){Ua(49579);break b}c=c+e|0;b=b+d|0;c=b>>>0>>0?c+1|0:c;i=b-1|0;b=c-!b|0;if(i>>>0>h>>>0&(b|0)>=(k|0)|(b|0)>(k|0)){Ua(49456);break b}m=G[j+80>>2];o=G[j+84>>2];i=Au(i,b,m,o);l=G[g+128>>2];c=i+l|0;n=Ia;b=n+G[g+132>>2]|0;p=c;q=c>>>0>>0?b+1|0:b;l=G[g+976>>2];b=l+G[g+984>>2]|0;c=G[g+988>>2]+G[g+980>>2]|0;c=b>>>0>>0?c+1|0:c;g=b;l=b-i|0;n=c-((b>>>0>>0)+n|0)|0;b=Au(m,o,d,e);m=Ia;i=m;Ci(a,p,q,l,n,0-b|0,0-(i+((b|0)!=0)|0)|0,f);g=g+2879|0;c=g>>>0<2879?c+1|0:c;c=Cu(g,c);g=(b-c|0)+2879|0;c=i-(Ia+(b>>>0>>0)|0)|0;c=Bu(g,g>>>0<2879?c+1|0:c,2880,0);if((c|0)>0){oh(a,c,f)}c=G[a+4>>2];i=G[c+976>>2];g=G[c+980>>2]-((b>>>0>i>>>0)+m|0)|0;b=i-b|0;G[c+976>>2]=b;G[c+980>>2]=g;G[j+92>>2]=0;Ad(a,34350,b,b>>31,65398,j+92|0);Ad(a,40853,h-d|0,k-((d>>>0>h>>>0)+e|0)|0,65398,f);c=G[a+4>>2];b=G[c+952>>2];h=G[c+956>>2]-((b>>>0>>0)+e|0)|0;G[c+952>>2]=b-d;G[c+956>>2]=h;b=G[c+944>>2];e=G[c+948>>2]-((d>>>0>b>>>0)+e|0)|0;G[c+944>>2]=b-d;G[c+948>>2]=e;$n(a,f)}h=G[f>>2];break a}h=307;G[f>>2]=307}Fa=j+96|0;return h}function Pj(a,b,c,d,e,f,g,h){var i=0,j=0,k=0,l=0,m=0;k=Fa-96|0;Fa=k;G[b>>2]=0;E[c|0]=0;G[d>>2]=0;G[e>>2]=-1;E[f|0]=0;E[g|0]=0;a:{if(G[h>>2]>0){break a}j=a;while(1){i=j;j=i+1|0;l=E[i|0];if((l|0)==32){continue}break}b:{c:{d:{if(l-48>>>0>9){break d}G[48624]=0;m=nc(i,k+12|0,10);G[b>>2]=m;j=G[k+12>>2];while(1){l=H[j|0];if((l|0)!=32){e:{f:{if(!((l|0)!=59?l:0)){G[k+12>>2]=j;if(G[48624]==68){break f}if(m>>>0>99999){break e}break c}G[k+12>>2]=j}G[b>>2]=0;G[48624]=0;if(J[b>>2]<1e5){break d}}G[b>>2]=0;Ua(38530);Ua(a);break b}else{j=j+1|0;continue}}}j=qc(i,36371);if((j|0)>=71){break b}c=qb(c,i,j);g:{if((j|0)<=0){b=j;break g}l=c-1|0;while(1){m=j+l|0;if(H[m|0]!=32){b=j;break g}b=0;E[m|0]=0;m=(j|0)>1;j=j-1|0;if(m){continue}break}}b=b+i|0;i=Me(b,39477)+b|0;b=qc(i,36370);if(b){G[k>>2]=d;if((Qc(i,30633,k)|0)!=1){Ua(39050);Ua(a);break b}b=b+i|0;i=Me(b,39477)+b|0;if(!qc(i,36383)){break c}h:{switch(H[i|0]-65|0){case 1:case 33:G[e>>2]=2;break c;case 0:case 19:case 32:case 51:G[e>>2]=1;break c;case 8:case 40:G[e>>2]=0;break c;default:break h}}Ua(39085);Ua(a);break b}b=Za(k+16|0,c);Yf(b);if((G[b>>2]!=1296650832|G[b+4>>2]!=5853761)&(H[b|0]|H[b+1|0]<<8)!=80){break c}E[c|0]=0}i=jb(i,59);if(i){while(1){c=H[i+1|0];b=i+1|0;i=b;if((c|0)==32){continue}break}i=jb(b,40);if(!i){Ua(38991);Ua(64199);Ua(a);break b}c=i-b|0;if((c|0)>=1025){break b}qb(f,b,c);while(1){c=H[i+1|0];b=i+1|0;i=b;if((c|0)==32){continue}break}c=jb(b,41);if(!c){Ua(38991);Ua(14859);Ua(a);break b}a=c-b|0;if((a|0)>=1025){break b}qb(g,b,a)}break a}G[h>>2]=125}Fa=k+96|0}function jn(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;g=-1;G[f>>2]=-1;a:{if(a>=b){break a}b:{c:{d:{if((c|0)<16){h=c;while(1){if(!h){h=-1;i=g;break d}h=h-1|0;i=h<<3;k=L[i+e>>3]>=a;g=k?h:g;if(!(L[d+i>>3]<=a)){continue}i=h;if(!k){continue}break}break d}j=L[d>>3];if(!(!(j<=a)|!(L[((c<<3)+e|0)-8>>3]>=a))){g=c>>>1|0;h=g;while(1){h=h>>>(h>>>0>1)|0;i=g<<3;k=i+e|0;if(L[k>>3]>3]<=a)){h=-1;break d}g=g+h|0;continue}if(!(L[d+i>>3]>a)){h=g;i=g;break d}if(L[k-8>>3]>=a){g=g-h|0;continue}else{h=-1;i=g;break d}}}h=-1;g=a(g|0)?g:-1;break c}k=-1;m=(c|0)>(i|0)?i:-1;if((c|0)<16){i=-1;g=c;while(1){if(!g){break b}g=g-1|0;p=g<<3;l=L[p+e>>3]>=b;k=l?g:k;if(!(L[d+p>>3]<=b)|!l){continue}break}i=g;k=g;break b}j=L[d>>3]}if(!(!(b>=j)|!(L[((c<<3)+e|0)-8>>3]>=b))){l=c>>>1|0;g=l;while(1){g=g>>>(g>>>0>1)|0;i=l<<3;k=i+e|0;if(L[k>>3]>3]<=b)){i=-1;break b}l=g+l|0;continue}if(!(L[d+i>>3]>b)){i=l;k=i;break b}if(L[k-8>>3]>=b){l=l-g|0;continue}else{i=-1;k=l;break b}}}i=-1;k=b=0){G[f>>2]=h}f=(c|0)>(k|0)?k:-1;if((f&m)<0|(f|0)==(m|0)&(h&i)<0){break a}if(!((h|0)!=(i|0)|(h|0)<0)){return b-a}c=(f|0)<0?c-1|0:f+(i>>31)|0;if((c|0)<(m|0)){break a}if((c-m|0)+1&1){f=m<<3;j=L[f+e>>3];n=b>3];n=n-(a>j?a:j)+0;h=m+1|0}else{h=m}if((c|0)==(m|0)){break a}while(1){f=h<<3;j=L[f+e>>3];o=b>3];n=n+(o-(a>j?a:j));f=h+1|0;g=f<<3;j=L[g+e>>3];o=b>3];n=n+(o-(a>j?a:j));h=h+2|0;if((c|0)!=(f|0)){continue}break}}return n}function oh(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;i=Fa-2896|0;Fa=i;d=G[c>>2];if(!((b|0)<=0|(d|0)>0)){G[i+12>>2]=0;d=G[a+4>>2];h=G[d+128>>2];f=G[d+976>>2]+h|0;e=G[d+980>>2]+G[d+132>>2]|0;e=f>>>0>>0?e+1|0:e;h=G[d+984>>2];f=h+f|0;d=G[d+988>>2]+e|0;d=f>>>0>>0?d+1|0:d;e=f+2879|0;d=e>>>0<2879?d+1|0:d;f=Cu(e,d);d=d-(Ia+(e>>>0>>0)|0)|0;g=e-f|0;e=Au(b,0,2880,0);h=g-e|0;k=Ia;f=d-(k+(e>>>0>g>>>0)|0)|0;a:{b:{if(Jb(a,g,d,0,i+12|0)){break b}while(1){if(ic(a,2880,0,i+16|0,i+12|0)){break b}Jb(a,h,f,0,c);Wb(a,2880,0,i+16|0,c);if(G[c>>2]>0){tb(5,59384);break a}h=h+2880|0;f=h>>>0<2880?f+1|0:f;g=g+2880|0;d=g>>>0<2880?d+1|0:d;if(!Jb(a,g,d,0,i+12|0)){continue}break}}d=0;cb(i+16|0,0,2880);Jb(a,h,f,0,c);if((b|0)>0){while(1){Wb(a,2880,0,i+16|0,c);d=d+1|0;if((d|0)!=(b|0)){continue}break}}b=0;Jb(a,h-1|0,f-!h|0,0,c);Wm(a,h,f,c);d=G[a+4>>2];h=G[d+88>>2];a=G[d+76>>2];if((h|0)<(a|0)){break a}f=G[d+96>>2];j=h-a|0;l=j+1&3;if(l){while(1){a=a+1|0;g=f+(a<<3)|0;d=G[g>>2];m=G[g+4>>2]-((d>>>0>>0)+k|0)|0;G[g>>2]=d-e;G[g+4>>2]=m;b=b+1|0;if((l|0)!=(b|0)){continue}break}}if(j>>>0<3){break a}while(1){d=f+(a<<3)|0;b=G[d+8>>2];j=G[d+12>>2]-((b>>>0>>0)+k|0)|0;g=d+8|0;G[g>>2]=b-e;G[g+4>>2]=j;b=G[d+16>>2];g=G[d+20>>2]-((e>>>0>b>>>0)+k|0)|0;G[d+16>>2]=b-e;G[d+20>>2]=g;g=a+3|0;d=f+(g<<3)|0;b=G[d>>2];j=G[d+4>>2]-((b>>>0>>0)+k|0)|0;G[d>>2]=b-e;G[d+4>>2]=j;a=a+4|0;d=f+(a<<3)|0;b=G[d>>2];j=G[d+4>>2]-((b>>>0>>0)+k|0)|0;G[d>>2]=b-e;G[d+4>>2]=j;if((h|0)!=(g|0)){continue}break}}d=G[c>>2]}Fa=i+2896|0;return d}function Dj(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;g=L[b>>3];h=L[a>>3]*3.141592653589793/180;n=ib(h);g=g*3.141592653589793/180;j=eb(g);k=n*j;o=eb(h);h=j*o;q=L[d>>3]*36e4;i=L[f>>3];s=L[e>>3];l=L[c>>3];g=ib(g);r=l*36e4;a:{if(!(r!=0|q!=0)){l=659e-6;p=-.001245;m=.00158;if(i==0|s==0){break a}}i=i*21.095*s;l=j*q+g*i+659e-6;p=i*h+(j*-n*r-q*(g*o))+-.001245;m=i*k+(h*r-q*(g*n))+.00158}o=0;i=g*-659e-6+(h*.001245+k*-.00158);j=i*g+l;n=i*k+m;i=i*h+p;l=g*-1.3843e-7+(h*-162557e-11+k*-3.1919e-7);g=l*g+(g+1.3843e-7);k=l*k+(k+3.1919e-7);h=l*h+(h+162557e-11);l=j*-6587e-14+(n*242397878e-14+(i*2.710663e-8+(g*-271765e-10+(k*.9999374784+(h*.011182061+0)))));u=j*-2718e-8+(n*.99995883+(i*.01118251+(g*-.008541+(k*-.002667+(h*.238514+0)))));w=l*u;m=j*-1.177656e-8+(n*-2.710663e-8+(i*242395018e-14+(g*-.0048579477+(k*-.0111820611+(h*.9999256782+0)))));v=j*-.00485767+(n*-.01118251+(i*.99994704+(g*.435739+(k*-.238565+(h*-551e-6+0)))));x=m*v;y=n*-2714e-8+(i*.00485767+(g*.002117+(k*.012254+(h*-.435623+0))));z=j*1.00000956;p=m*m+l*l;t=V(p);g=j*242410173e-14+(n*-6582e-14+(i*1.177656e-8+(g*.9999881997+(k*-271474e-10+(h*.0048579479+0)))));j=g*g;b:{if(m==0&l==0){break b}o=Db(l,m);if(!(o<0)){break b}o=o+6.283185307179586}h=z+y;k=x+w;j=j+p;if(t>1e-30){r=(m*u-v*l)/p;q=(h*p-k*g)/(j*t)}if(s>1e-30){m=g*h+k;h=V(j);L[f>>3]=m/(s*h*21.095);L[e>>3]=L[e>>3]/h}L[a>>3]=o*180/3.141592653589793;A=b,B=Db(g,t)*180/3.141592653589793,L[A>>3]=B;L[c>>3]=r/36e4;L[d>>3]=q/36e4}function Yc(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;A(+b);g=v(1)|0;a:{i=v(0)|0;e=i<<1;c=g<<1|i>>>31;b:{if(!(e|c)){break b}d=g&2147483647;if((d|0)==2146435072&(i|0)!=0|d>>>0>2146435072){break b}A(+a);k=v(1)|0;f=v(0)|0;h=k>>>20&2047;if((h|0)!=2047){break a}}a=a*b;return a/a}d=k<<1|f>>>31;j=f<<1;if((c|0)==(d|0)&e>>>0>=j>>>0|c>>>0>d>>>0){return(e|0)==(j|0)&(c|0)==(d|0)?a*0:a}j=g>>>20&2047;c:{if(!h){h=0;d=f;c=k<<12|d>>>20;e=d<<12;d=c;if((c|0)>0|(c|0)>=0){while(1){h=h-1|0;c=d<<1|e>>>31;e=e<<1;d=c;if((c|0)>0|(c|0)>=0){continue}break}}e=f;c=1-h|0;d=c&31;if((c&63)>>>0>=32){c=e<>>32-d|k<>>20;f=f<<12;if((c|0)>0|(c|0)>=0){while(1){j=j-1|0;c=c<<1|f>>>31;f=f<<1;if((c|0)>0|(c|0)>=0){continue}break}}c=1-j|0;f=c&31;if((c&63)>>>0>=32){c=i<>>32-f|g<(j|0)){while(1){i=e-c|0;e:{g=d-((c>>>0>e>>>0)+f|0)|0;if((g|0)<0){break e}e=i;d=g;if(e|d){break e}return a*0}d=d<<1|e>>>31;e=e<<1;h=h-1|0;if((j|0)<(h|0)){continue}break}h=j}g=c;c=d-((c>>>0>e>>>0)+f|0)|0;g=e-g|0;f:{if((c|0)<0){break f}e=g;d=c;if(e|c){break f}return a*0}g:{if(d>>>0>1048575){f=e;c=d;break g}while(1){h=h-1|0;g=d>>>0<524288;c=e;d=d<<1|c>>>31;f=c<<1;c=d;e=f;if(g){continue}break}}g=0;k=k&-2147483648;if((h|0)>0){c=c+-1048576|h<<20}else{d=c;c=1-h|0;e=c&31;if((c&63)>>>0>=32){c=0;f=d>>>e|0}else{c=d>>>e|0;f=((1<>>e}}x(0,f|g);x(1,c|k);return+z()}function Vb(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0,n=0,o=0;l=-1;a:{b:{if((d|e|f|g|h|i|j)<0){break b}l=G[309723];if((l|0)==G[309724]){m=G[309722];c:{if(m){G[309724]=l<<1;l=ub(m,M(l,688));break c}G[309724]=100;l=ab(34400)}if(!l){break a}G[309722]=l;l=G[309723]}G[309723]=l+1;if((l|0)<0){break b}m=G[309722];n=m+M(l,344)|0;G[n+12>>2]=d;G[n+8>>2]=c;G[n+4>>2]=26;G[n>>2]=b;G[n+36>>2]=j;G[n+32>>2]=i;G[n+28>>2]=h;G[n+24>>2]=g;G[n+20>>2]=f;G[n+16>>2]=e;f=(b|0)==1043?0:c;d:{if(!c){break d}e=c;e:{if(!(c&1)){break e}e=c-1|0;f=0;if((b|0)==1043){break e}f=G[M(G[((M(l,344)+m|0)+(e<<2)|0)+12>>2],344)+m>>2]==-1e3}if((c|0)==1){break d}g=f;while(1){f=0;c=0;c=g?G[M(G[((M(l,344)+m|0)+(e<<2)|0)+8>>2],344)+m>>2]==-1e3:c;e=e-2|0;f=c?G[M(G[((M(l,344)+m|0)+(e<<2)|0)+12>>2],344)+m>>2]==-1e3:f;g=f;if(e){continue}break}}f:{if(a){b=M(l,344)+m|0;G[b+56>>2]=1;G[b+60>>2]=1;G[b+52>>2]=a;G[b- -64>>2]=1;break f}b=M(l,344)+m|0;a=M(d,344)+m|0;G[b+52>>2]=G[a+52>>2];G[b+56>>2]=G[a+56>>2];G[b+60>>2]=G[a+60>>2];b=G[a+60>>2];if((b|0)<=0){break f}i=0;e=0;if(b-1>>>0>=3){h=b&-4;j=0;while(1){c=(M(l,344)+m|0)- -64|0;a=e<<2;g=(M(d,344)+m|0)- -64|0;G[c+a>>2]=G[g+a>>2];o=a|4;G[o+c>>2]=G[g+o>>2];o=a|8;G[o+c>>2]=G[g+o>>2];a=a|12;G[a+c>>2]=G[a+g>>2];e=e+4|0;j=j+4|0;if((h|0)!=(j|0)){continue}break}}a=b&3;if(!a){break f}while(1){b=e<<2;G[(b+(M(l,344)+m|0)|0)- -64>>2]=G[(b+(M(d,344)+m|0)|0)- -64>>2];e=e+1|0;i=i+1|0;if((a|0)!=(i|0)){continue}break}}if((k|0)>0){G[(M(l,344)+m|0)+56>>2]=k}if(!f){break b}qn(n)}return l}G[309737]=113;return-1}function Dd(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0;j=Fa-112|0;Fa=j;a:{b:{c:{if((Va(b)|0)!=7){break c}if(fb(b,33332,7)){if(fb(b,32708,7)){break c}}d:{while(1){f=a+d|0;if(!H[f|0]){break d}g=a+d|0;f=g+1|0;if(!H[f|0]){break d}f=g+2|0;if(!H[f|0]){break d}f=g+3|0;if(!H[f|0]){break d}f=g+4|0;if(!H[f|0]){break d}d=d+5|0;if((d|0)!=57600){continue}break}f=a+57600|0}e=a;while(1){h=ec(e,35790,f-e|0);i=(h-a|0)%80|0;if((i|0)>=8){e=h+1|0;continue}d=H[h+3|0];if(!((d|0)==61|(d-33&255)>>>0>93)){e=h+1|0;continue}g=h-i|0;if((i|0)>0){i=h+1|0;d=g;while(1){e=H[d|0]==32?e:i;d=d+1|0;if(h>>>0>d>>>0){continue}break}}if(e>>>0>h>>>0){continue}break}e=rb(g+80|0,g,80);rb(cb(g,32,80),b,7);g=0;break b}e:{f:{while(1){f=a+d|0;if(!H[f|0]){g=d;break f}g=1;e=a+d|0;f=e+1|0;if(!H[f|0]){break f}f=e+2|0;if(!H[f|0]){break f}f=e+3|0;if(!H[f|0]){break f}f=e+4|0;if(!H[f|0]){break f}d=d+5|0;if((d|0)!=57600){continue}break}f=a+57600|0;break e}if(!g){break a}}e=a;while(1){h=ec(e,b,f-e|0);if(!h){break a}g:{i=(h-a|0)%80|0;h:{if((i|0)>=8){e=h+1|0;break h}d=H[Va(b)+h|0];if(!((d|0)==61|(d-33&255)>>>0>93)){e=h+1|0;break h}g=h-i|0;if((i|0)>0){i=h+1|0;d=g;while(1){e=H[d|0]==32?e:i;d=d+1|0;if(h>>>0>d>>>0){continue}break}}if(e>>>0<=h>>>0){break g}}if(e>>>0>>0){continue}break a}break}e=g+80|0;i:{j:{b=rb(j,g,80);a=jb(b,39);k:{if(!a){break k}a=jb(a+1|0,39);if(!a){break k}a=a-b|0;if((a|0)>30){break j}}g=g+31|0;break i}g=(a+g|0)+2|0}E[g|0]=47;E[g+1|0]=32}b=Va(c);if((b|0)<=0){break a}a=g+2|0;rb(a,c,a+b>>>0>e>>>0?e-a|0:b)}Fa=j+112|0}function jk(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0;k=Fa-160|0;Fa=k;j=G[i>>2];a:{if(j){break a}j=Fc(a,35480,k+80|0,k,i);G[i>>2]=j;if((j|0)==202){G[i>>2]=340;Ua(62904);j=G[i>>2]}b:{c:{if(j){break c}j=Va(k+80|0);if(!(H[k+80|0]!=39|H[(j+k|0)+79|0]!=39)){j=j-2|0;if((j|0)>0){l=k+80|0;yd(l,l|1,j)}E[j+(k+80|0)|0]=0}l=0;d:{e:{j=Va(k+80|0)-1|0;if((j|0)<=0){break e}while(1){if(H[(k+80|0)+l|0]!=32){break e}l=l+1|0;if((l|0)!=(j|0)){continue}break}break d}if((j|0)==(l|0)|(j|0)<0){break d}while(1){l=(k+80|0)+j|0;if(H[l|0]!=32){break d}E[l|0]=0;l=(j|0)>0;j=j-1|0;if(l){continue}break}}if(Ib(k+80|0,35090)){break b}j=dc(a,1,120080,b,i);G[i>>2]=j;if((j|0)==219){G[i>>2]=0;G[b>>2]=0;j=G[i>>2]}if(j){break c}j=dc(a,1,35460,c,i);G[i>>2]=j;if((j|0)==219){G[i>>2]=0;G[c>>2]=0;j=G[i>>2]}if(j){break c}j=dc(a,1,34443,d,i);G[i>>2]=j;if((j|0)==219){G[i>>2]=0;G[d>>2]=0;j=G[i>>2]}if(j){break c}j=dc(a,1,120096,e,i);G[i>>2]=j;if((j|0)==219){G[i>>2]=0;G[e>>2]=0;j=G[i>>2]}if(j){break c}j=dc(a,1,120128,f,i);G[i>>2]=j;if((j|0)==219){G[i>>2]=0;G[f>>2]=0;j=G[i>>2]}if(j){break c}a=dc(a,1,120112,g,i);G[i>>2]=a;if((a|0)==219){G[i>>2]=0;G[g>>2]=0;a=G[i>>2]}if(a){break c}f:{if(!(!G[d>>2]|(!G[b>>2]|!G[c>>2]))){a=G[f>>2];if(G[e>>2]){if(a){a=0;if(G[g>>2]){break f}}a=3;break f}if(a){a=11;if(G[g>>2]){break f}}a=1;break f}if(!G[e>>2]){break b}if(G[f>>2]){a=12;if(G[g>>2]){break f}}a=2}G[h>>2]=a}j=G[i>>2];if((j|0)!=237){break a}G[i>>2]=340;Ua(62951);j=G[i>>2];break a}j=340;G[i>>2]=340}Fa=k+160|0;return j}function Bq(a,b,c){var d=0,e=0,f=0,g=0;a:{b:{if(!b){if(!a){break b}G[a>>2]=0;return}if(!H[b+5008|0]){if(a){G[a>>2]=-1}G[b+5060>>2]=-1;return}d=G[b>>2];c:{if(G[d+76>>2]<0){e=G[d>>2];break c}e=G[d>>2]}if(e>>>5&1){break a}d:{if(c){break d}if(!G[b+5060>>2]){f=b+4|0;g=b+5012|0;while(1){G[b+5028>>2]=f;G[b+5032>>2]=5e3;c=-2;e:{e=G[b+5044>>2];f:{if(!e|G[e>>2]!=(g|0)){break f}d=G[e+4>>2];g:{while(1){if((d|0)!=2){h:{c=-1;switch(d-1|0){case 0:case 2:break f;case 3:break h;default:break g}}}else{c=G[b+5016>>2];d=4;G[e+4>>2]=4;G[e+12>>2]=c;continue}break}if(G[e+12>>2]!=G[b+5016>>2]){break f}if(!Eq(g)){break f}c=0;i:{if(G[e+12>>2]){break i}if(J[e+52>>2]<=255){c=0;if(G[e+56>>2]>0){break i}}c=0;if(G[e+80>>2]>2]){break i}G[e+4>>2]=1;c=1}d=G[b+5032>>2];if(d>>>0>4999){break e}d=5e3-d|0;if((hb(f,1,d,G[b>>2])|0)==(d|0)){d=G[b>>2];j:{if(G[d+76>>2]<0){d=G[d>>2];break j}d=G[d>>2]}if(!(d>>>5&1)){break e}}break a}c=0}if(a){G[a>>2]=c}G[b+5060>>2]=c;return}if(!c){continue}break}d=G[b>>2]}k:{if(G[d+76>>2]<0){c=G[d>>2];break k}c=G[d>>2]}if(c>>>5&1){break d}$a(d);c=G[b>>2];l:{if(G[c+76>>2]<0){c=G[c>>2];break l}c=G[c>>2]}if(!(c>>>5&1)){break d}break a}if(a){G[a>>2]=0}G[b+5060>>2]=0;a=G[b+5044>>2];if(!(!a|G[a>>2]!=(b+5012|0))){c=G[a+16>>2];if(c){Ja[G[b+5052>>2]](G[b+5056>>2],c)}c=G[a+20>>2];if(c){Ja[G[b+5052>>2]](G[b+5056>>2],c)}a=G[a+24>>2];if(a){Ja[G[b+5052>>2]](G[b+5056>>2],a)}Ja[G[b+5052>>2]](G[b+5056>>2],G[b+5044>>2])}Wa(b)}return}if(a){G[a>>2]=-6}G[b+5060>>2]=-6}function ko(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0;g=Fa-272|0;Fa=g;Td(a,g+268|0,g+264|0,e);i=9;if(G[g+268>>2]>=9){k=g+160|1;while(1){Sd(a,i,g+160|0,e);a:{b:{if(H[g+160|0]!=84){break b}j=5;h=rb(g+80|0,k,4);f=G[h>>2];c:{d:{if((f|0)<=1330791769){if((f|0)<=1280725570){if((f|0)<=1279345490){if((f|0)==1162893652){break c}if((f|0)!=1229870403){break d}break c}if((f|0)==1279345491|(f|0)==1280070990){break c}if((f|0)!=1280262978){break d}break c}e:{switch(f-1313426756|0){case 0:case 8:break c;case 1:case 2:case 3:case 4:case 5:case 6:case 7:break d;default:break e}}if((f|0)==1280725571){break c}if((f|0)!=1297239878){break d}break c}if((f|0)<=1414484546){if((f|0)<=1348031554){if((f|0)==1330791770){break c}if((f|0)!=1347635524){break d}break c}if((f|0)==1348031555|(f|0)==1414090325){break c}if((f|0)!=1414284355){break d}break c}f:{switch(f-1480674628|0){case 0:case 8:break c;case 1:case 2:case 3:case 4:case 5:case 6:case 7:break d;default:break f}}if((f|0)==1414484547|(f|0)==1481658947){break c}}j=4;if(G[g+160>>2]!=1296647252){break b}}E[h|0]=0;f=qb(h,g+160|j,8-j|0);G[g+260>>2]=0;ue(f,g+256|0,g+260|0);if(G[g+260>>2]){break b}h=G[g+256>>2];if((h|0)<(b|0)|(c|0)<(h|0)){break b}if(!((b|0)!=(h|0)|(d|0)>0)){ig(a,i,e);G[g+268>>2]=G[g+268>>2]-1;f=i-1|0;break a}h=d+h|0;G[g+256>>2]=h;E[f|0]=0;l=f;f=g+160|0;zb(qb(l,f,j),h,g,e);G[g+160>>2]=538976288;G[g+164>>2]=538976288;rl(a,i,rb(f,g,Va(g)),e)}f=i}i=f+1|0;if((f|0)>2]){continue}break}}Fa=g+272|0}function vl(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0;j=Fa-192|0;Fa=j;if(G[c>>2]<=0){a:{e=G[a>>2];d=G[a+4>>2];if((e|0)!=G[d+76>>2]){mb(a,e+1|0,0,c);d=G[a+4>>2]}e=G[d+128>>2];g=G[d+104>>2];i=e-g|0;f=G[d+108>>2];if(G[d+132>>2]==(f+(e>>>0>>0)|0)&(i|0)==80){if((Bf(a,1,0,c)|0)>0){break a}d=G[a+4>>2];g=G[d+104>>2];f=G[d+108>>2]}h=G[d+120>>2];i=G[d+124>>2];e=0;d=rb(j,b,80);E[d+80|0]=0;i=Bu(g-h|0,f-((h>>>0>g>>>0)+i|0)|0,80,0);f=Va(d);b:{if((f|0)>0){if((f|0)!=1){h=f&-2;b=0;while(1){g=d+e|0;if((H[g|0]-127&255)>>>0<=160){E[g|0]=32}g=(e|1)+d|0;if((H[g|0]-127&255)>>>0<=160){E[g|0]=32}e=e+2|0;b=b+2|0;if((h|0)!=(b|0)){continue}break}}c:{if(!(f&1)){break c}b=d+e|0;if((H[b|0]-127&255)>>>0>160){break c}E[b|0]=32}if((f|0)>79){break b}}cb(d+f|0,32,80-f|0)}b=qc(d,36178);d:{e:{if(!gc(66587,d,8)){h=8;break e}h=8;if(!gc(66546,d,8)){break e}if(!gc(68289,d,8)){break e}if(!gc(35367,d,8)){break e}h=(b|0)==80?8:b;if((h|0)<=0){break d}}e=0;while(1){f=d+e|0;b=E[f|0];E[f|0]=b-97>>>0<26?b&95:b;e=e+1|0;if((h|0)!=(e|0)){continue}break}}ve(d,c);b=0;e=G[a+4>>2];f=G[e+124>>2];g=G[e+120>>2];Jb(a,g,f,0,c);f:{if((i|0)<=0){e=d;break f}h=j+96|0;while(1){e=h;ic(a,80,0,e,c);Jb(a,g,f,0,c);h=d;Wb(a,80,0,d,c);d=g+80|0;f=d>>>0<80?f+1|0:f;g=d;d=e;b=b+1|0;if((i|0)!=(b|0)){continue}break}}Wb(a,80,0,e,c);a=G[a+4>>2];b=G[a+108>>2];c=G[a+104>>2]+80|0;b=c>>>0<80?b+1|0:b;G[a+104>>2]=c;G[a+108>>2]=b;b=G[a+124>>2];c=G[a+120>>2]+80|0;b=c>>>0<80?b+1|0:b;G[a+120>>2]=c;G[a+124>>2]=b}}Fa=j+192|0}function St(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;i=-1;a:{if(!a|G[a+16>>2]!=7247){break a}b:{switch(G[a+92>>2]+5|0){case 0:case 5:break b;default:break a}}if((c|0)<0){Vd(a,-2,4759);return-1}c:{d=0;d:{if(!c){break d}e:{if(!G[a+88>>2]){break e}G[a+88>>2]=0;d=G[a+84>>2];g=d;e=G[a+80>>2];if(!(d|e)){break e}while(1){f:{d=G[a>>2];if(d){f=d;d=(g|0)<=0&d>>>0>e>>>0|(g|0)<0?e:d;G[a>>2]=f-d;G[a+4>>2]=d+G[a+4>>2];f=G[a+12>>2];j=G[a+8>>2];k=j+d|0;G[a+8>>2]=k;G[a+12>>2]=j>>>0>k>>>0?f+1|0:f;f=e;e=e-d|0;g=g-(d>>>0>f>>>0)|0;break f}if(G[a+104>>2]?0:G[a+64>>2]){break e}if((zq(a)|0)!=-1){break f}d=0;break d}if(e|g){continue}break}}while(1){d=G[a>>2];g:{h:{if(d){d=c>>>0>d>>>0?d:c;bb(b,G[a+4>>2],d);G[a+4>>2]=G[a+4>>2]+d;G[a>>2]=G[a>>2]-d;break h}if(!(G[a+104>>2]|!G[a+64>>2])){G[a+68>>2]=1;d=h;break d}e=G[a+48>>2];if(!(G[a+28>>2]<<1>>>0<=c>>>0?e:0)){if((zq(a)|0)!=-1){break g}d=0;break d}d=0;if((e|0)==1){while(1){e=c-d|0;e=ql(G[a+20>>2],b+d|0,e>>>0<1073741824?e:1073741824);if((e|0)>0){d=d+e|0;if(d>>>0>>0){continue}break h}break}if((e|0)>=0){G[a+64>>2]=1;break h}b=G[48624];Vd(a,-1,I[((b>>>0>149?0:b)<<1)+143920>>1]+142088|0);d=0;break d}G[a+112>>2]=b;G[a+116>>2]=c;d=0;if((yq(a)|0)==-1){break d}d=G[a>>2];G[a>>2]=0}e=G[a+12>>2];f=d+G[a+8>>2]|0;e=f>>>0>>0?e+1|0:e;G[a+8>>2]=f;G[a+12>>2]=e;h=d+h|0;b=b+d|0;c=c-d|0}if(c){continue}break}d=h}if(d){break c}switch(G[a+92>>2]+5|0){case 0:case 5:break c;default:break a}}i=d}return i|0}function Hg(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;if(!G[a+84>>2]){Ua(44027);if(G[a+4>>2]==8){Ua(43975)}G[((b<<2)+a|0)+1416>>2]=0;G[c>>2]=112;return}h=G[a+64>>2];f=G[a+68>>2];m=((b<<2)+a|0)+1256|0;d=G[m>>2];g=Au(d,d>>31,2880,0);d=Ia;e=G[a+36>>2];i=G[a+32>>2];if((d|0)<=(e|0)&i>>>0>=g>>>0|(d|0)<(e|0)){if((g|0)!=(h|0)|(d|0)!=(f|0)){Ja[G[(M(G[a+4>>2],84)+1240576|0)+72>>2]](G[a>>2],g,d)|0}fi(a,2880,G[a+1252>>2]+M(b,2880)|0,c);h=g+2880|0;c=h>>>0<2880?d+1|0:d;G[a+64>>2]=h;G[a+68>>2]=c;if((g|0)==G[a+32>>2]&(d|0)==G[a+36>>2]){G[a+32>>2]=h;G[a+36>>2]=c}G[((b<<2)+a|0)+1416>>2]=0;return}if((h|0)!=(i|0)|(f|0)!=(e|0)){Ja[G[(M(G[a+4>>2],84)+1240576|0)+72>>2]](G[a>>2],i,e)|0}a:{if((b|0)==40){g=G[a+32>>2];d=G[a+36>>2];break a}g=G[a+32>>2];d=G[a+36>>2];i=a+1256|0;while(1){j=Bu(g,d,2880,0);f=G[m>>2];e=0;h=b;while(1){k=G[(e<<2)+i>>2];n=(k|0)<(f|0)&(j|0)<=(k|0);o=e|1;l=G[(o<<2)+i>>2];f=n?k:f;k=(l|0)<(f|0)&(j|0)<=(l|0);f=k?l:f;h=k?o:n?e:h;e=e+2|0;if((e|0)!=40){continue}break}f=Au(f,f>>31,2880,0);j=Ia;e=j;if(f>>>0>g>>>0&(e|0)>=(d|0)|(d|0)<(e|0)){e=0;d=Bu(f-g|0,j-(d+(g>>>0>f>>>0)|0)|0,2880,0);b:{if((d|0)<=0){break b}while(1){if(G[c>>2]){break b}fi(a,2880,196400,c);e=e+1|0;if((d|0)!=(e|0)){continue}break}}G[a+32>>2]=f;G[a+36>>2]=j}fi(a,2880,G[a+1252>>2]+M(h,2880)|0,c);G[((h<<2)+a|0)+1416>>2]=0;d=G[a+36>>2];g=G[a+32>>2]+2880|0;d=g>>>0<2880?d+1|0:d;G[a+32>>2]=g;G[a+36>>2]=d;if((b|0)!=(h|0)){continue}break}}G[a+64>>2]=g;G[a+68>>2]=d}function gl(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=N(0),m=N(0);a:{b:{if(!e){if(c==1&d==0){break a}if((b|0)<=0){break b}g=b&1;if((b|0)!=1){h=b&-2;b=0;while(1){e=k<<2;K[e+i>>2]=+K[a+e>>2]*c+d;e=e|4;K[e+i>>2]=+K[a+e>>2]*c+d;k=k+2|0;b=b+2|0;if((h|0)!=(b|0)){continue}break}}if(!g){break b}b=k<<2;K[b+i>>2]=+K[a+b>>2]*c+d;return}k=a+2|0;c:{if(!(c==1&d==0)){if((b|0)<=0){break b}m=N(d);if((e|0)!=1){break c}while(1){l=m;d:{e:{f:{e=I[k>>1]&32640;switch(((e|0)==32640?1:!e<<1)|0){case 0:break e;case 1:break f;default:break d}}G[h>>2]=1;l=f;break d}l=N(+K[(j<<2)+a>>2]*c+d)}K[(j<<2)+i>>2]=l;k=k+4|0;j=j+1|0;if((j|0)!=(b|0)){continue}break}break b}if((b|0)<=0){break b}if((e|0)==1){while(1){l=N(0);g:{h:{i:{e=I[k>>1]&32640;switch(((e|0)==32640?1:!e<<1)|0){case 0:break h;case 1:break i;default:break g}}G[h>>2]=1;l=f;break g}l=K[(j<<2)+a>>2]}K[(j<<2)+i>>2]=l;k=k+4|0;j=j+1|0;if((j|0)!=(b|0)){continue}break b}}while(1){l=N(0);j:{k:{l:{e=I[k>>1]&32640;switch(((e|0)==32640?1:!e<<1)|0){case 0:break k;case 1:break l;default:break j}}G[h>>2]=1;E[g+j|0]=1;l=N(-9119119840596153e-51);break j}l=K[(j<<2)+a>>2]}K[(j<<2)+i>>2]=l;k=k+4|0;j=j+1|0;if((j|0)!=(b|0)){continue}break}break b}while(1){l=m;m:{n:{o:{e=I[k>>1]&32640;switch(((e|0)==32640?1:!e<<1)|0){case 0:break n;case 1:break o;default:break m}}G[h>>2]=1;E[g+j|0]=1;l=N(-9119119840596153e-51);break m}l=N(+K[(j<<2)+a>>2]*c+d)}K[(j<<2)+i>>2]=l;k=k+4|0;j=j+1|0;if((j|0)!=(b|0)){continue}break}}return}yd(i,a,b<<2)}function au(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;e=Fa-32|0;Fa=e;a:{if(!a){break a}c=ab(160);if(!c){break a}G[c+96>>2]=0;G[c+28>>2]=0;G[c+32>>2]=8192;G[c+72>>2]=-1;G[c+76>>2]=0;G[c+16>>2]=0;G[c+44>>2]=0;b:{c:{d:{d=H[b|0];e:{if(!d){break e}while(1){g=b;b=d<<24>>24;f:{if((d-48&255)>>>0<=9){G[c+72>>2]=b-48;break f}g:{switch(b-43|0){case 71:f=7247;G[c+16>>2]=7247;break f;case 76:f=31153;G[c+16>>2]=31153;break f;case 54:f=1;G[c+16>>2]=1;break f;case 58:h=1;break f;case 77:i=1;break f;case 59:G[c+76>>2]=1;break f;case 61:G[c+76>>2]=2;break f;case 39:G[c+76>>2]=3;break f;case 27:G[c+76>>2]=4;break f;case 0:break e;case 41:break g;default:break f}}j=1;G[c+44>>2]=1}b=g+1|0;d=H[g+1|0];if(d){continue}break}h:{if((f|0)!=7247){if(f){break h}break e}if(j){break e}G[c+44>>2]=1}d=Va(a)+1|0;b=ab(d);G[c+24>>2]=b;if(!b){break e}G[e+16>>2]=a;Ya(b,d,10361,e+16|0);b=0;d=G[c+16>>2];if((d|0)!=7247){b=((d|0)==31153?512:1024)|(i?193:65)}G[e>>2]=438;b=fm(a,(h?557056:32768)|b,e);G[c+20>>2]=b;if((b|0)!=-1){d=G[c+16>>2];if((d|0)==7247){break d}a=c;if((d|0)!=1){break c}Xg(b,0,0,2);G[c+16>>2]=31153;a=c;break c}Wa(G[c+24>>2])}Wa(c);d=0;break a}a=Xg(b,0,0,1);G[c>>2]=0;d=a;a=Ia;b=(d&a)==-1;G[c+56>>2]=b?0:d;G[c+60>>2]=b?0:a;if(G[c+16>>2]!=7247){break b}G[c+64>>2]=0;G[c+68>>2]=0;a=c+48|0}G[a>>2]=0}G[c+88>>2]=0;a=G[c+96>>2];if(a){if(G[c+92>>2]!=-4){Wa(a)}G[c+96>>2]=0}G[c+8>>2]=0;G[c+12>>2]=0;G[c+92>>2]=0;G[c+104>>2]=0;d=c}Fa=e+32|0;return d|0}function nf(){var a=0,b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;i=Fa-16|0;Fa=i;d=G[925771];a=G[925766];if((a|0)>0){cb(d,0,a)}b=-4;a:{if(!vc(d,a,G[925769])){break a}a=G[29763];while(1){if(G[925767]){G[i>>2]=G[925771];kb(85747,i);$a(a)}d=G[925771];if((H[d|0]|32)==124){if(vc(d,G[925766],G[925769])){continue}break a}break}b=(Va(d)+d|0)-1|0;if(H[b|0]==10){E[b|0]=0}b=(Va(d)+d|0)-1|0;if(H[b|0]==13){E[b|0]=0}b=0;Za(G[925758],d);E[d+G[G[925773]+4100>>2]|0]=0;G[G[925773]+4096>>2]=d;g=G[925783];b:{if((g|0)<2){break b}a=1;e=d+1|0;c=g-1|0;h=c&1;if((g|0)!=2){j=c&-2;while(1){c=M(a,4108);E[d+G[(c+G[925773]|0)+4100>>2]|0]=0;f=c+G[925773]|0;G[f+4096>>2]=e+G[f-8>>2];f=c+4108|0;E[d+G[(f+G[925773]|0)+4100>>2]|0]=0;l=f;f=G[925773];G[(l+f|0)+4096>>2]=e+G[(c+f|0)+4100>>2];a=a+2|0;k=k+2|0;if((j|0)!=(k|0)){continue}break}}if(!h){break b}a=M(a,4108);E[d+G[(a+G[925773]|0)+4100>>2]|0]=0;a=a+G[925773]|0;G[a+4096>>2]=e+G[a-8>>2]}if((g|0)<=0){break a}c=G[925773];e=0;while(1){h=M(e,4108);b=G[(h+c|0)+4100>>2];c:{if(e){a=e-1|0;while(1){c=b+d|0;j=H[c|0];if(!b|(j?(j|0)!=32:0)|G[(G[925773]+M(a,4108)|0)+4100>>2]==(b|0)){break c}E[c|0]=0;b=b-1|0;continue}}while(1){a=b+d|0;c=H[a|0];if(!b|(c?(c|0)!=32:0)){break c}E[a|0]=0;b=b-1|0;continue}}c=G[925773];a=h+c|0;b=G[a+4096>>2];if(H[b|0]==32){a=a+4096|0;while(1){G[a>>2]=b+1;c=G[925773];b=h+c|0;a=b+4096|0;b=G[b+4096>>2];if(H[b|0]==32){continue}break}}e=e+1|0;if((g|0)>(e|0)){continue}break}b=0}Fa=i+16|0;return b}function ld(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;n=Fa-112|0;Fa=n;a:{if(!f&(g|0)<=0|(g|0)<0|G[i>>2]>0){break a}if(!b&(c|0)<=0|(c|0)<0){G[i>>2]=307;break a}if(!d&(e|0)<=0|(e|0)<0){G[i>>2]=308;break a}l=G[a>>2];j=G[a+4>>2];b:{if((l|0)!=G[j+76>>2]){mb(a,l+1|0,0,i);break b}j=G[j+132>>2];if((j|0)>0|(j|0)>=0){break b}Rb(a,i)}k=G[a+4>>2];p=G[k+960>>2];j=e+g|0;l=d+f|0;j=l>>>0>>0?j+1|0:j;q=G[k+964>>2];j=Bu(l-2|0,j-(l>>>0<2)|0,p,q)+b|0;m=c+Ia|0;m=b>>>0>j>>>0?m+1|0:m;o=G[k+956>>2];l=G[k+952>>2];c:{d:{if((o|0)>=(m|0)&l>>>0>=j>>>0|(m|0)<(o|0)){break d}e:{if(G[k+48>>2]){r=G[k+988>>2];if(!G[k+984>>2]&(r|0)<=0|(r|0)<0){break e}}k=j-l|0;j=m-((j>>>0>>0)+o|0)|0;if((Ig(a,l,o,k,j,i)|0)<=0){k=G[a+4>>2];j=k;p=G[j+960>>2];q=G[j+964>>2];break d}L[n>>3]=+(k>>>0)+ +(j|0)*4294967296;a=n+16|0;Ya(a,81,44181,n);Ua(a);break c}G[k+952>>2]=j;G[k+956>>2]=m;r=G[k+980>>2];s=G[k+976>>2];m=Au(j-l|0,m-((j>>>0>>0)+o|0)|0,p,q);l=s+m|0;j=Ia+r|0;G[k+976>>2]=l;G[k+980>>2]=l>>>0>>0?j+1|0:j}f:{if(G[i>>2]>0){break f}e=e+G[k+132>>2]|0;j=d+G[k+128>>2]|0;e=j>>>0>>0?e+1|0:e;c=Au(p,q,b-1|0,c-!b|0);b=c+j|0;j=Ia+e|0;j=b>>>0>>0?j+1|0:j;if(!b&(j|0)<=0|(j|0)<0){G[i>>2]=304;break f}c=G[a>>2];if((c|0)!=G[k+76>>2]){mb(a,c+1|0,0,i);k=G[a+4>>2]}c=b;b=j-!c|0;c=c-1|0;d=Du(c,b,2880,0);e=G[k+72>>2];if(!((e|0)>=0&(d|0)==G[((e<<2)+k|0)+1256>>2])){Hc(a,d,1,i)}if(G[i>>2]>0){break f}d=G[a+4>>2];G[d+56>>2]=c;G[d+60>>2]=b}Wb(a,f,g,h,i)}}Fa=n+112|0}function mb(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;h=Fa-112|0;Fa=h;f=G[d>>2];a:{if((f|0)>0){break a}if((b|0)<=0){f=301;G[d>>2]=301;break a}e=G[a+4>>2];if(G[e+92>>2]<=(b|0)){f=ub(G[e+96>>2],(b<<3)+8008|0);if(!f){f=113;G[d>>2]=113;break a}e=G[a+4>>2];G[e+96>>2]=f;G[e+92>>2]=b+1e3}G[a>>2]=G[e+76>>2];l=b-1|0;b:{c:{d:{while(1){e=G[a+4>>2];f=G[e+76>>2];if((f+1|0)==(b|0)){break d}f=G[e+88>>2]+1|0;f=(b|0)>(f|0)?f:l;i=f<<3;g=i+G[e+96>>2]|0;k=G[g>>2];g=G[g+4>>2];j=G[e+44>>2];if(J[e+40>>2]<=k>>>0&(g|0)>=(j|0)|(g|0)>(j|0)){break b}e:{if((Xf(a,d)|0)<=0){if(G[d>>2]<=0){e=i+G[G[a+4>>2]+96>>2]|0;f:{if((Jb(a,G[e>>2],G[e+4>>2],0,d)|0)>0){break f}e=G[a+4>>2];g=G[e+76>>2];G[e+76>>2]=f;k=G[e+104>>2];j=G[e+108>>2];i=G[e+88>>2];G[a>>2]=f;G[e+88>>2]=(f|0)<(i|0)?i:f;f=G[e+44>>2];G[e+104>>2]=G[e+40>>2];G[e+108>>2]=f;if((Wf(a,c,d)|0)<=0){break f}e=G[a+4>>2];G[e+76>>2]=g;G[a>>2]=g;G[e+104>>2]=k;G[e+108>>2]=j;G[e+88>>2]=i}e=G[d>>2];if((e|0)<=0){break e}}G[h+108>>2]=0;Wf(a,c,h+108|0)}e=G[d>>2]}if((e|0)<=0){continue}break}f=107;if((e|0)==107){break a}G[h>>2]=b;a=h+16|0;Ya(a,81,47827,h);tb(5,a);break c}if(!c|G[d>>2]>0){break c}b=G[a>>2];if(b|!!(G[e+104>>2]|G[e+108>>2])){g:{if((b|0)!=(f|0)){mb(a,b+1|0,0,d);break g}if((G[e+128>>2]&G[e+132>>2])!=-1){break g}if((Rb(a,d)|0)>0){break c}}a=G[a+4>>2];b=G[a+80>>2];G[c>>2]=b;a=G[a+1088>>2]?0:b}else{a=0}G[c>>2]=a}f=G[d>>2];break a}f=107;G[d>>2]=107}Fa=h+112|0;return f|0}function Gs(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;var h=0,i=0,j=0,k=0,l=0,m=0;i=M(c,168);b=i+G[a+8>>2]|0;L[b+8>>3]=G[a+44>>2];h=G[a+48>>2];L[b+16>>3]=h|0;l=lb(h+1|0,4);G[b+24>>2]=l;Pf(a,c,d,e);b=i+G[a+8>>2]|0;f=L[b+16>>3];g=L[b+8>>3];a:{if(O(g)<2147483648){i=~~g;break a}i=-2147483648}if(f>=+(i|0)){m=M(c,168);while(1){b=G[a+48>>2];c=G[a+44>>2];h=G[a+36>>2];k=lb(1,8);G[k+4>>2]=h;b:{if(!l){break b}c=(c|0)>(i|0)?c:i;j=((b|0)>(c|0)?c:b)<<2;b=j+l|0;c=G[b>>2];c:{if(!c){c=0;break c}if((h|0)>2]){break c}while(1){b=c;c=G[b>>2];if(!c){c=0;break c}if((h|0)>G[c+4>>2]){continue}break}}G[k>>2]=c;G[b>>2]=k;if((e|0)==1){break b}b=j+G[a+56>>2]|0;if(d){if((h|0)<=G[b>>2]){G[b>>2]=h}b=j+G[a+60>>2]|0;if((h|0)>2]){break b}c=b;b=G[a+40>>2];G[c>>2]=(b|0)<(h|0)?b:h;break b}G[b>>2]=h;G[j+G[a+60>>2]>>2]=G[a+40>>2]}b=G[a+48>>2];c=G[a+44>>2];h=G[a+40>>2];k=lb(1,8);G[k+4>>2]=h;d:{if(!l){break d}c=(c|0)>(i|0)?c:i;j=((b|0)>(c|0)?c:b)<<2;b=j+l|0;c=G[b>>2];e:{if(!c){c=0;break e}if((h|0)>2]){break e}while(1){b=c;c=G[b>>2];if(!c){c=0;break e}if((h|0)>G[c+4>>2]){continue}break}}G[k>>2]=c;G[b>>2]=k;if((e|0)==1){break d}if(d){b=j+G[a+56>>2]|0;if((h|0)<=G[b>>2]){c=b;b=G[a+36>>2];G[c>>2]=(b|0)>(h|0)?b:h}b=j+G[a+60>>2]|0;if((h|0)>2]){break d}c=b;b=G[a+40>>2];G[c>>2]=(b|0)<(h|0)?b:h;break d}G[j+G[a+56>>2]>>2]=G[a+36>>2];G[j+G[a+60>>2]>>2]=G[a+40>>2]}i=i+1|0;if(L[(G[a+8>>2]+m|0)+16>>3]>=+(i|0)){continue}break}}}function kp(a){var b=0,c=0,d=0;c=-2;a:{if(!G[a+36>>2]|(!a|!G[a+32>>2])){break a}b=G[a+28>>2];if(!b|G[b>>2]!=(a|0)){break a}b:{c:{d=G[b+4>>2];switch(d-57|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 13:case 14:case 15:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 47:case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:break a;case 0:case 12:case 16:case 34:case 46:case 56:break b;default:break c}}if((d|0)==666){break b}if((d|0)!=42){break a}}G[a+44>>2]=2;G[a+8>>2]=0;G[a+20>>2]=0;G[a+24>>2]=0;G[b+20>>2]=0;G[b+16>>2]=G[b+8>>2];c=G[b+24>>2];if((c|0)<0){c=0-c|0;G[b+24>>2]=c}d=c?42:113;c=(c|0)==2;G[b+4>>2]=c?57:d;d:{if(c){c=Oc(0,0,0);break d}c=gf(0,0,0)}G[a+48>>2]=c;c=0;G[b+40>>2]=0;G[b+5820>>2]=0;F[b+5816>>1]=0;G[b+2872>>2]=116504;G[b+2864>>2]=b+2684;G[b+2860>>2]=116484;G[b+2852>>2]=b+2440;G[b+2848>>2]=116464;G[b+2840>>2]=b+148;np(b)}if(!c){a=G[a+28>>2];G[a+60>>2]=G[a+44>>2]<<1;b=G[a+68>>2];d=(G[a+76>>2]<<1)-2|0;F[b+d>>1]=0;cb(b,0,d);G[a+5812>>2]=0;G[a+116>>2]=0;G[a+120>>2]=2;G[a+104>>2]=0;G[a+108>>2]=0;G[a+92>>2]=0;G[a+96>>2]=2;G[a+72>>2]=0;b=M(G[a+132>>2],12);G[a+144>>2]=I[b+118436>>1];G[a+140>>2]=I[b+118432>>1];G[a+128>>2]=I[b+118434>>1];G[a+124>>2]=I[b+118438>>1]}return c}function Jh(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;i=Fa-2016|0;Fa=i;f=ab(5001);E[f|0]=0;e=5e3;while(1){a:{b:{c:{d=H[a|0];if((d|0)!=36){if(!d){break c}E[i+2015|0]=0;E[i+2014|0]=d;h=(Va(i+2014|0)+h|0)+1|0;if((h|0)>=(e|0)){while(1){e=e+5e3|0;f=ub(f,e);if((e|0)<=(h|0)){continue}break}}f=Gb(f,i+2014|0);a=a+1|0;continue}g=H[a+1|0];if((g|0)==123){d=125}else{if((g|0)!=40){break b}d=41}g=H[a+2|0];k=0;E[i+1008|0]=0;j=a+2|0;if(!g){break a}while(1){l=g<<24>>24;if((l|0)==(d|0)){j=j+1|0;break a}if(!(l-48>>>0<10|(l|32)-97>>>0<26|(g|0)==95)){break a}l=i+1008|0;E[l+k|0]=g;k=k+1|0;E[l+k|0]=0;g=H[j+1|0];j=j+1|0;if(g){continue}break}break a}E[f+h|0]=0;a=ub(f,h+1|0);Fa=i+2016|0;return a}k=0;E[i+1008|0]=0;j=a+1|0;if(!g){break a}while(1){d=g<<24>>24;if(!(d-48>>>0<10|(d|32)-97>>>0<26|(g|0)==95)){break a}d=i+1008|0;E[d+k|0]=g;k=k+1|0;E[d+k|0]=0;g=H[j+1|0];j=j+1|0;if(g){continue}break}}g=j-1|0;d:{e:{if(!b){break e}d=Ja[b|0](i+1008|0,c)|0;if(!d){break e}if(!H[d|0]){break d}h=(Va(d)+h|0)+1|0;if((h|0)>=(e|0)){while(1){e=e+5e3|0;f=ub(f,e);if((e|0)<=(h|0)){continue}break}}f=Gb(f,d);break d}d=Fd(i+1008|0);if(d){if(!H[d|0]){break d}h=(Va(d)+h|0)+1|0;if((h|0)>=(e|0)){while(1){e=e+5e3|0;f=ub(f,e);if((e|0)<=(h|0)){continue}break}}f=Gb(f,d);break d}d=(g-a|0)+1|0;a=rb(i,a,d);E[a+d|0]=0;if(!H[a|0]){break d}h=(Va(a)+h|0)+1|0;if((h|0)>=(e|0)){while(1){e=e+5e3|0;f=ub(f,e);if((e|0)<=(h|0)){continue}break}}f=Gb(f,a)}a=g+1|0;continue}}function mu(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=N(e);f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;j=Fa-65568|0;Fa=j;h=ab(40);G[h>>2]=0;E[j+16|0]=0;n=We(1285568,1,h,4);o=Z()|0;a:{b:while(1){h=3809712;c:{if(i){break c}G[321387]=0;ta(155,a|0,b|0,c|0,d|0,j+65564|0,j+65560|0,+e,f|0,g|0);i=G[321387];G[321387]=0;h=-1;d:{if(!i){break d}k=G[321388];if(!k){break d}h=Ab(G[i>>2],n,o);if(!h){break a}_(k|0)}i=Z()|0;if((h|0)==1){continue}G[321387]=0;L[j>>3]=K[j+65564>>2];L[j+8>>3]=K[j+65560>>2];$(156,j+16|0,65535,19686,j|0)|0;i=G[321387];G[321387]=0;h=-1;e:{if(!i){break e}k=G[321388];if(!k){break e}h=Ab(G[i>>2],n,o);if(!h){break a}_(k|0)}i=Z()|0;if((h|0)==1){continue}l=j+16|0;h=3809712;m=H[j+16|0];if(!m){break c}while(1){G[321387]=0;i=G[321387];G[321387]=0;h=-1;f:{if(!i){break f}k=G[321388];if(!k){break f}h=Ab(G[i>>2],n,o);if(!h){break a}_(k|0)}i=Z()|0;if((h|0)==1){continue b}h=m<<24>>24;if(!((h|0)==32|h-9>>>0<5)){h=3809712;while(1){E[h|0]=m;h=h+1|0;m=H[l+1|0];l=l+1|0;if(m){continue}break}break c}m=H[l+1|0];h=3809712;l=l+1|0;if(m){continue}break}}E[h|0]=0;l=h-3809712|0;g:{if(!l){break g}while(1){m=-1;h=h-1|0;p=E[h|0];G[321387]=0;i=G[321387];G[321387]=0;h:{if(!i){break h}k=G[321388];if(!k){break h}m=Ab(G[i>>2],n,o);if(!m){break a}_(k|0)}i=Z()|0;if((m|0)==1){continue b}if(!((p|0)==32|p-9>>>0<5)){break g}E[h|0]=0;l=l-1|0;if(l){continue}break}}break}Wa(n);Fa=j+65568|0;return 3809712}Wa(n);Ve(i,k);W()}function Ig(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;m=Fa-16|0;Fa=m;h=G[f>>2];a:{if((h|0)>0){break a}b:{g=G[a>>2];j=G[a+4>>2];c:{d:{if((g|0)!=G[j+76>>2]){mb(a,g+1|0,0,f);break d}if((G[j+128>>2]&G[j+132>>2])!=-1){break d}if((Rb(a,f)|0)>0){break c}}h=G[a+4>>2];if(!G[h+80>>2]){Ua(49227);h=235;G[f>>2]=235;break a}if((e|0)<0){h=306;G[f>>2]=306;break a}if(!(d|e)){break c}p=G[h+952>>2];r=G[h+956>>2];j=r;if(p>>>0>>0&(j|0)<=(c|0)|(c|0)>(j|0)){Ua(49285);break b}if((c|0)<0){Ua(49355);break b}k=G[h+960>>2];s=G[h+964>>2];j=Au(k,s,d,e);i=Ia;q=i;n=G[h+976>>2];o=n+G[h+984>>2]|0;g=G[h+988>>2]+G[h+980>>2]|0;g=o>>>0>>0?g+1|0:g;n=g;l=o+2879|0;g=l>>>0<2879?g+1|0:g;g=Cu(l,g);l=Ia;t=0-(l+(g>>>0>2879)|0)|0;if(2879-g>>>0>>0&(t|0)<=(i|0)|(i|0)>(t|0)){i=q+l|0;h=g+j|0;i=h>>>0>>0?i+1|0:i;Bf(a,Bu(h,i,2880,0),1,f);h=G[a+4>>2]}b=Au(b,c,k,s);i=G[h+128>>2];g=b+i|0;k=Ia;c=k+G[h+132>>2]|0;Ci(a,g,g>>>0>>0?c+1|0:c,o-b|0,n-((b>>>0>o>>>0)+k|0)|0,j,q,f);b=G[a+4>>2];i=q+G[b+980>>2]|0;c=j+G[b+976>>2]|0;i=c>>>0>>0?i+1|0:i;G[b+976>>2]=c;G[b+980>>2]=i;G[m+12>>2]=0;Ad(a,34350,c,i,65398,m+12|0);g=e+r|0;b=d+p|0;g=b>>>0

>>0?g+1|0:g;Ad(a,40853,b,g,65398,f);a=G[a+4>>2];c=e+G[a+956>>2]|0;b=d+G[a+952>>2]|0;c=b>>>0>>0?c+1|0:c;G[a+952>>2]=b;G[a+956>>2]=c;b=e+G[a+948>>2]|0;c=d+G[a+944>>2]|0;b=c>>>0>>0?b+1|0:b;G[a+944>>2]=c;G[a+948>>2]=b}h=G[f>>2];break a}h=307;G[f>>2]=307}Fa=m+16|0;return h}function di(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;a:{if(!a|!b|(!H[a|0]|!H[b|0])){break a}i=le(a);E[d|0]=0;b:{if(!H[i|0]){break b}a=i;c:{d:{while(1){h=Sb(a,b);if(!h){break b}e:{f:{g:{if((h|0)==(i|0)){break g}a=H[h-1|0];if((a|0)==91){break g}if((a|0)!=44){break f}}e=Va(b)+h|0;while(1){a=e;e=a+1|0;g=E[a|0];if((g|0)==32|g-9>>>0<5){continue}break}if((g|0)!=61){break f}while(1){b=a;a=a+1|0;g=E[b+1|0];e=g;if((e|0)==32|e-9>>>0<5){continue}break}e=g&255;f=e-34|0;if(f>>>0>6|!(1<>>0<=i>>>0){break n}a=h-1|0;if(H[a|0]!=44){break n}h=a;break m}e=(H[e|0]==44)+e|0}yd(h,e,Va(e)+1|0)}Wa(i);if(f|!c){break a}a=Fd(c);if(!a){return 0}f=Va(rb(d,a,1023))}return f} -function Mf(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0;e=Fa-272|0;Fa=e;h=c<0;c=Yc(h?-c:c,360);c=h?-c:c;c=c<=-180?c+360:c;g=c<0;c=g?-c:c;a:{if(O(c)<2147483648){h=~~c;break a}h=-2147483648}c=(c-+(h|0))*60;b:{if(O(c)<2147483648){f=~~c;break b}f=-2147483648}c=(c-+(f|0))*60;g=g?45:43;c:{if((d|0)>=6){d=c>59.999999;L[e+16>>3]=d?0:c;G[e>>2]=g;f=d+f|0;d=(f|0)>59;G[e+8>>2]=d?0:f;G[e+4>>2]=d+h;Eb(e+208|0,18799,e);break c}if((d|0)==5){d=c>59.99999;L[e+48>>3]=d?0:c;G[e+32>>2]=g;f=d+f|0;d=(f|0)>59;G[e+40>>2]=d?0:f;G[e+36>>2]=d+h;Eb(e+208|0,18903,e+32|0);break c}if((d|0)>=4){d=c>59.9999;L[e+80>>3]=d?0:c;G[e+64>>2]=g;f=d+f|0;d=(f|0)>59;G[e+72>>2]=d?0:f;G[e+68>>2]=d+h;Eb(e+208|0,18930,e- -64|0);break c}if((d|0)==3){d=c>59.999;L[e+112>>3]=d?0:c;G[e+96>>2]=g;f=d+f|0;d=(f|0)>59;G[e+104>>2]=d?0:f;G[e+100>>2]=d+h;Eb(e+208|0,19117,e+96|0);break c}if((d|0)>=2){d=c>59.99;L[e+144>>3]=d?0:c;G[e+128>>2]=g;f=d+f|0;d=(f|0)>59;G[e+136>>2]=d?0:f;G[e+132>>2]=d+h;Eb(e+208|0,19258,e+128|0);break c}if((d|0)==1){d=c>59.9;L[e+176>>3]=d?0:c;G[e+160>>2]=g;f=d+f|0;d=(f|0)>59;G[e+168>>2]=d?0:f;G[e+164>>2]=d+h;Eb(e+208|0,19277,e+160|0);break c}G[e+192>>2]=g;c=c+.5;d:{if(O(c)<2147483648){g=~~c;break d}g=-2147483648}d=g;d=(d|0)>59;G[e+204>>2]=d?0:g;f=d+f|0;d=(f|0)>59;G[e+200>>2]=d?0:f;G[e+196>>2]=d+h;db(e+208|0,29791,e+192|0)}b=b-1|0;e:{if((Va(e+208|0)|0)<(b|0)){Za(a,e+208|0);break e}i=rb(a,e+208|0,b)+b|0,j=0,E[i|0]=j}Fa=e+272|0}function fs(a,b,c,d,e,f,g,h){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;p=Fa-16|0;Fa=p;G[p+12>>2]=h;a:{j=G[a+8>>2];k=(G[a>>2]+M(c,3)|0)-2|0;n=M(k,168);e=j+n|0;if(G[e+32>>2]){break a}o=lb(1e3,8);G[e+32>>2]=o;h=0;G[e+28>>2]=0;l=1e3;while(1){if((h|0)>=(l|0)){l=l+1e3|0;e=ub(o,l<<3);j=G[a+8>>2];G[(n+j|0)+32>>2]=e}e=G[p+12>>2]+7&-8;G[p+12>>2]=e+8;i=j+n|0;o=G[i+32>>2];h=G[i+28>>2];m=L[e>>3];L[o+(h<<3)>>3]=m;b:{if(!(O(m+-9007199254740992)<=1e-15)){break b}e=h-1|0;if(!(O(L[(e<<3)+o>>3]+-9007199254740992)<=1e-15)){break b}G[i+28>>2]=e;h=M(k,168);e=h+G[a+8>>2]|0;e=ub(G[e+32>>2],G[e+28>>2]<<3);j=G[a+8>>2];G[(h+j|0)+32>>2]=e;break a}h=h+1|0;G[i+28>>2]=h;continue}}c:{d:{n=G[(j+n|0)+28>>2];if((n|0)<=0){break d}if(O(g)<2147483648){k=~~g}else{k=-2147483648}e=0;e:{if(!d){l=k<<2;h=0;while(1){i=M(c+h|0,168)+j|0;k=G[l+G[i+24>>2]>>2];if(!k){break e}m=L[i+8>>3];f:{if(O(m)<2147483648){i=~~m;break f}i=-2147483648}if(+(i|0)!=g|+G[k+4>>2]!=f){break e}h=h+1|0;e=e+2|0;if((n|0)>(e|0)){continue}break}break d}h=0;while(1){i=M(c+h|0,168)+j|0;m=L[i+8>>3];if(!(m>g|L[i+16>>3]>2]+(k<<2)>>2];q=!i;if(O(m)<2147483648){l=~~m}else{l=-2147483648}if(!(q|+(l|0)!=g)){o=+G[i+4>>2]==f}if((d|0)==(o|0)){break e}}h=h+1|0;e=e+2|0;if((n|0)>(e|0)){continue}break}break d}e=1;if(!d){break c}b=b+h|0;if(!b){break c}G[a+12>>2]=b;break c}e=0}Fa=p+16|0;return e|0}function Fg(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;l=Fa-160|0;Fa=l;G[d>>2]=0;G[e>>2]=1;f=rb(l+80|0,a,71);h=rb(l,b,71);E[f+70|0]=0;E[h+70|0]=0;b=Va(f)-1|0;a:{if((b|0)<0){break a}while(1){a=b+f|0;if(H[a|0]!=32){break a}E[a|0]=0;b=b-1|0;if((b|0)>=0){continue}break}}b=Va(h)-1|0;b:{if((b|0)<0){break b}while(1){a=b+h|0;if(H[a|0]!=32){break b}E[a|0]=0;b=b-1|0;if((b|0)>=0){continue}break}}c:{if(c){break c}c=Va(f);if(c){b=0;while(1){i=b+f|0;a=E[i|0];E[i|0]=a-97>>>0<26?a&95:a;b=b+1|0;if((c|0)!=(b|0)){continue}break}}c=Va(h);if(!c){break c}b=0;while(1){i=b+h|0;a=E[i|0];E[i|0]=a-97>>>0<26?a&95:a;b=b+1|0;if((c|0)!=(b|0)){continue}break}}d:{e:{g=H[f|0];if((g|0)==H[h|0]){if(!Xa(f,h)){break e}}G[e>>2]=0;b=0;e=0;while(1){c=H[b+h|0];f:{if(!g){if(!(c&255)){break e}if(!m){break d}g=H[e+f|0];a=k+1|0;c=H[h+a|0];i=e;break f}if(c&255){i=j;a=b;break f}if(H[(f+j|0)+1|0]|(g|0)!=42){break d}break e}g:{h:{if((g|0)!=63){n=c&255;if((n|0)!=(g|0)){break h}}j=i+1|0;b=a+1|0;break g}if(!((g|0)!=35|(c<<24>>24)-48>>>0>9)){b=a;while(1){b=b+1|0;if(E[h+b|0]-48>>>0<10){continue}break}j=i+1|0;break g}if((g|0)==42){j=i+1|0;if((H[j+f|0]|32)==32){break e}b=a;if(!n){break d}while(1){i:{e=H[f+j|0];k=c&255;g=(e|0)==(k|0);j=g+j|0;b=b+1|0;c=H[h+b|0];if(!c){break i}if((e|0)!=(k|0)){continue}}break}m=1;e=i;k=a;if(g){break g}break d}if(!m){break d}m=1;b=k+1|0;j=e}g=H[f+j|0];continue}}G[d>>2]=1}Fa=l+160|0}function vo(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;i=Fa-16|0;Fa=i;G[i+12>>2]=0;e=G[c>>2];if((e|0)<=0){e=G[a>>2];f=G[a+4>>2];if((e|0)!=G[f+76>>2]){mb(a,e+1|0,0,c);f=G[a+4>>2];e=G[f+76>>2]}a:{b:{if(!e){G[f+120>>2]=0;G[f+124>>2]=0;G[f+104>>2]=0;G[f+108>>2]=0;d=Fa-160|0;Fa=d;Yi(a,8,0,d,c);Fa=d+160|0;d=G[a+4>>2];e=(G[d+76>>2]<<3)+G[d+96>>2]|0;f=G[e+8>>2];e=Bu(f-2880|0,G[e+12>>2]-(f>>>0<2880)|0,2880,0);if((e|0)>0){if((oh(a,e,c)|0)>0){break a}d=G[a+4>>2]}G[d+128>>2]=-1;G[d+132>>2]=-1;Rb(a,c);break b}d=G[f+96>>2]+(e<<3)|0;e=G[d+8>>2];f=G[d>>2];if((oh(a,Bu(e-f|0,G[d+12>>2]-(G[d+4>>2]+(e>>>0>>0)|0)|0,2880,0),c)|0)>0){break a}l=G[a+4>>2];j=G[l+88>>2];d=G[l+76>>2];c:{if((j|0)<=(d|0)){f=G[l+96>>2];break c}e=d+1|0;f=G[l+96>>2];g=j-d&3;if(g){while(1){h=(e<<3)+f|0;e=e+1|0;k=(e<<3)+f|0;n=G[k+4>>2];G[h>>2]=G[k>>2];G[h+4>>2]=n;m=m+1|0;if((g|0)!=(m|0)){continue}break}}if((d^-1)+j>>>0<3){break c}while(1){d=(e<<3)+f|0;g=G[d+12>>2];h=G[d+8>>2];G[d>>2]=h;G[d+4>>2]=g;g=G[d+20>>2];G[d+8>>2]=G[d+16>>2];G[d+12>>2]=g;h=e+3|0;g=(h<<3)+f|0;k=G[g+4>>2];G[d+16>>2]=G[g>>2];G[d+20>>2]=k;e=e+4|0;d=(e<<3)+f|0;k=G[d+4>>2];G[g>>2]=G[d>>2];G[g+4>>2]=k;if((j|0)!=(h|0)){continue}break}}d=(j<<3)+f|0;G[d+8>>2]=0;G[d+12>>2]=0;G[l+88>>2]=j-1;if((Wf(a,i+12|0,c)|0)<=0){break b}G[c>>2]=0;df();Zn(a,G[G[a+4>>2]+76>>2]-1|0,i+12|0,c)}if(!b){break a}G[b>>2]=G[i+12>>2]}e=G[c>>2]}Fa=i+16|0;return e}function nk(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;if(G[d>>2]<=0){a:{h=G[a>>2];i=G[a+4>>2];b:{if((h|0)!=G[i+76>>2]){mb(a,h+1|0,0,d);break b}if((G[i+128>>2]&G[i+132>>2])!=-1){break b}if((Rb(a,d)|0)>0){break a}}i=G[a+4>>2];if(!G[i+80>>2]){a=G[i+136>>2];g=(a|0)<(b|0)?a:b;if((g|0)<=0){break a}h=0;a=0;if(g-1>>>0>=3){j=g&-4;b=i+144|0;while(1){e=a<<3;d=e+c|0;f=b+e|0;k=G[f+4>>2];G[d>>2]=G[f>>2];G[d+4>>2]=k;d=e|8;f=d+c|0;d=b+d|0;k=G[d+4>>2];G[f>>2]=G[d>>2];G[f+4>>2]=k;d=e|16;f=d+c|0;d=b+d|0;k=G[d+4>>2];G[f>>2]=G[d>>2];G[f+4>>2]=k;e=e|24;d=e+c|0;e=b+e|0;f=G[e+4>>2];G[d>>2]=G[e>>2];G[d+4>>2]=f;a=a+4|0;l=l+4|0;if((j|0)!=(l|0)){continue}break}}b=g&3;if(!b){break a}while(1){e=a<<3;g=e+c|0;e=e+i|0;j=G[e+148>>2];G[g>>2]=G[e+144>>2];G[g+4>>2]=j;a=a+1|0;h=h+1|0;if((b|0)!=(h|0)){continue}break}break a}if(G[i+1088>>2]){a=G[i+1108>>2];g=(a|0)<(b|0)?a:b;if((g|0)<=0){break a}b=0;a=0;if(g-1>>>0>=3){j=g&-4;e=i+1112|0;h=0;while(1){d=(a<<3)+c|0;f=G[e+(a<<2)>>2];G[d>>2]=f;G[d+4>>2]=f>>31;d=a|1;f=(d<<3)+c|0;d=G[e+(d<<2)>>2];G[f>>2]=d;G[f+4>>2]=d>>31;d=a|2;f=(d<<3)+c|0;d=G[e+(d<<2)>>2];G[f>>2]=d;G[f+4>>2]=d>>31;d=a|3;f=(d<<3)+c|0;d=G[e+(d<<2)>>2];G[f>>2]=d;G[f+4>>2]=d>>31;a=a+4|0;h=h+4|0;if((j|0)!=(h|0)){continue}break}}h=g&3;if(!h){break a}while(1){e=(a<<3)+c|0;g=G[(i+(a<<2)|0)+1112>>2];G[e>>2]=g;G[e+4>>2]=g>>31;a=a+1|0;b=b+1|0;if((h|0)!=(b|0)){continue}break}break a}G[d>>2]=233}}}function lk(a,b,c){var d=0,e=0,f=0;d=Fa-208|0;Fa=d;a:{if(G[c>>2]>0){break a}if(!H[a|0]){G[c>>2]=204;break a}Yn(a,d+207|0,b,d+12|0,d+112|0,d,c);e=403;b:{c:{d:{e:{f:{switch(H[d+207|0]-67|0){case 0:if((me(d+112|0,d,c)|0)>0){break d}e=412;f=L[d>>3];if(f>2147483647|f<-2147483648){break c}e=~~f;if(O(f)<2147483648){break e}e=-2147483648;break e;case 3:e=412;f=L[d>>3];if(f>2147483647|f<-2147483648){break c}e=~~f;if(O(f)<2147483648){break e}e=-2147483648;break e;case 21:break c;case 9:break f;default:break d}}e=G[d+12>>2]}G[b>>2]=e}if(G[c>>2]>0){break b}break a}G[c>>2]=e}G[b>>2]=0;E[d- -64|0]=H[67192];b=H[67188]|H[67189]<<8|(H[67190]<<16|H[67191]<<24);G[d+56>>2]=H[67184]|H[67185]<<8|(H[67186]<<16|H[67187]<<24);G[d+60>>2]=b;b=H[67180]|H[67181]<<8|(H[67182]<<16|H[67183]<<24);G[d+48>>2]=H[67176]|H[67177]<<8|(H[67178]<<16|H[67179]<<24);G[d+52>>2]=b;b=H[67172]|H[67173]<<8|(H[67174]<<16|H[67175]<<24);G[d+40>>2]=H[67168]|H[67169]<<8|(H[67170]<<16|H[67171]<<24);G[d+44>>2]=b;b=H[67164]|H[67165]<<8|(H[67166]<<16|H[67167]<<24);G[d+32>>2]=H[67160]|H[67161]<<8|(H[67162]<<16|H[67163]<<24);G[d+36>>2]=b;b=H[67156]|H[67157]<<8|(H[67158]<<16|H[67159]<<24);G[d+24>>2]=H[67152]|H[67153]<<8|(H[67154]<<16|H[67155]<<24);G[d+28>>2]=b;b=H[67148]|H[67149]<<8|(H[67150]<<16|H[67151]<<24);G[d+16>>2]=H[67144]|H[67145]<<8|(H[67146]<<16|H[67147]<<24);G[d+20>>2]=b;tb(5,qb(d+16|0,a,30))}Fa=d+208|0}function ci(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;f=Fa-2032|0;Fa=f;E[f+2022|0]=91;E[f+2023|0]=0;E[f+2020|0]=93;E[f+2021|0]=0;e=Za(f+2e3|0,b);h=ug(e,f+2022|0);if(h){E[h|0]=0}a:{b:{c:{while(1){b=a+c|0;if(!H[b|0]){d=c;break c}d=1;g=a+c|0;b=g+1|0;if(!H[b|0]){break c}b=g+2|0;if(!H[b|0]){break c}b=g+3|0;if(!H[b|0]){break c}b=g+4|0;if(!H[b|0]){break c}c=c+5|0;if((c|0)!=57600){continue}break}b=a+57600|0;g=Va(e);break b}g=Va(e);if(d){break b}d=0;break a}c=a;while(1){d=0;c=ec(c,e,b-c|0);if(!c){break a}i=H[c-1|0];d:{j=H[c+g|0];if((j|0)!=61&(j-33&255)>>>0<94){break d}if((a|0)!=(c|0)){if((i|0)!=9&(i|0)!=32){break d}a=c}b=a+g|0;e:{while(1){a=H[b|0];if((a|0)==32|(a|0)==61){b=b+1|0;continue}else{f:{a=cb(f,0,2e3);c=H[b|0];if((c|0)==34){break f}while(1){e=c&255;if((e|0)==9|(e|0)==32|(c<<24>>24<=0|d>>>0>1999)){break e}E[a+d|0]=c;d=d+1|0;c=H[b+1|0];b=b+1|0;continue}}}break}c=H[b+1|0];if(!c){break e}d=b+1|0;b=0;while(1){if((c&255)==34|b>>>0>1999){break e}E[a+b|0]=c;b=b+1|0;c=H[d+1|0];d=d+1|0;if(c){continue}break}}g:{if(!h){c=a;break g}d=1283200;b=h+1|0;c=ug(b,a+2020|0);if(!c){break a}E[c|0]=0;e=_b(b);if((e|0)<=0){break a}E[a+2026|0]=0;E[a+2024|0]=32;E[a+2025|0]=44;b=1;c=pc(a,a+2024|0);if((e|0)!=1){while(1){c=pc(0,a+2024|0);b=b+1|0;if((e|0)!=(b|0)){continue}break}}if(!c){break a}}d=1283200;Za(1283200,c);break a}c=c+1|0;if(c>>>0>>0){continue}break}}Fa=f+2032|0;return d}function Ik(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;h=b-1|0;m=(h|0)/2|0;a:{if((b|0)<2){break a}while(1){b=k+1|0;if((h|0)==(b|0)){b=(k<<3)+a|0;e=G[b>>2];d=(h<<3)+a|0;h=G[d>>2];f=G[b+4>>2];c=G[d+4>>2];if((f|0)<=(c|0)&e>>>0<=h>>>0|(c|0)>(f|0)){break a}G[b>>2]=h;G[b+4>>2]=c;G[d>>2]=e;G[d+4>>2]=f;break a}g=((h+k|0)/2<<3)+a|0;d=g;e=G[d>>2];i=(h<<3)+a|0;c=i;f=G[c>>2];d=G[d+4>>2];c=G[c+4>>2];b:{if((d|0)<=(c|0)&e>>>0<=f>>>0|(c|0)>(d|0)){e=f;d=c;break b}G[g>>2]=f;G[g+4>>2]=c;G[i>>2]=e;G[i+4>>2]=d}f=(k<<3)+a|0;j=G[f>>2];c=G[f+4>>2];if(j>>>0>e>>>0&(c|0)>=(d|0)|(c|0)>(d|0)){G[f>>2]=e;G[f+4>>2]=d;G[i>>2]=j;G[i+4>>2]=c;j=G[f>>2];c=G[f+4>>2]}e=G[g>>2];d=G[g+4>>2];if(e>>>0>j>>>0&(d|0)>=(c|0)|(c|0)<(d|0)){G[g>>2]=j;G[g+4>>2]=c;G[f>>2]=e;G[f+4>>2]=d;e=G[g>>2];d=G[g+4>>2]}c=(b<<3)+a|0;i=G[c+4>>2];G[g>>2]=G[c>>2];G[g+4>>2]=i;G[c>>2]=e;G[c+4>>2]=d;d=h;while(1){i=G[f>>2];c=G[f+4>>2];while(1){b=b+1|0;j=(b<<3)+a|0;e=j;o=G[e>>2];p=G[e+4>>2];e=p;if(o>>>0>>0&(e|0)<=(c|0)|(c|0)>(e|0)){continue}break}while(1){e=d;d=d-1|0;g=(d<<3)+a|0;n=G[g>>2];l=G[g+4>>2];if(i>>>0>>0&(c|0)<=(l|0)|(c|0)<(l|0)){continue}break}if((b|0)<(e|0)){G[j>>2]=n;G[j+4>>2]=l;G[g>>2]=o;G[g+4>>2]=p;continue}break}G[f>>2]=n;G[f+4>>2]=l;G[g>>2]=i;G[g+4>>2]=c;h=(e|0)>(m|0)?e-2|0:h;k=(d|0)>(m|0)?k:b;if((h|0)>(k|0)){continue}break}}a=(m<<3)+a|0;b=G[a>>2];Ia=G[a+4>>2];return b}function wi(a,b,c){var d=0,e=0;d=Fa-192|0;Fa=d;a:{if(G[c>>2]>0){break a}b:{c:{d:{e:{f:{g:{e=H[a|0];switch(e-39|0){case 1:break e;case 0:break f;default:break g}}h:{switch(e-70|0){default:if(e){break d}G[c>>2]=204;break a;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:break d;case 0:case 14:break h}}L[b>>3]=(e|0)==84?1:0;break c}e=d+96|0;fd(a,e,c);me(e,b,c);break c}G[c>>2]=406;break b}me(a,b,c)}if(G[c>>2]<=0){break a}}G[b>>2]=0;G[b+4>>2]=0;b=H[67592]|H[67593]<<8|(H[67594]<<16|H[67595]<<24);c=H[67588]|H[67589]<<8|(H[67590]<<16|H[67591]<<24);E[d+39|0]=c;E[d+40|0]=c>>>8;E[d+41|0]=c>>>16;E[d+42|0]=c>>>24;E[d+43|0]=b;E[d+44|0]=b>>>8;E[d+45|0]=b>>>16;E[d+46|0]=b>>>24;b=H[67585]|H[67586]<<8|(H[67587]<<16|H[67588]<<24);G[d+32>>2]=H[67581]|H[67582]<<8|(H[67583]<<16|H[67584]<<24);G[d+36>>2]=b;b=H[67577]|H[67578]<<8|(H[67579]<<16|H[67580]<<24);G[d+24>>2]=H[67573]|H[67574]<<8|(H[67575]<<16|H[67576]<<24);G[d+28>>2]=b;b=H[67569]|H[67570]<<8|(H[67571]<<16|H[67572]<<24);G[d+16>>2]=H[67565]|H[67566]<<8|(H[67567]<<16|H[67568]<<24);G[d+20>>2]=b;b=H[67561]|H[67562]<<8|(H[67563]<<16|H[67564]<<24);G[d+8>>2]=H[67557]|H[67558]<<8|(H[67559]<<16|H[67560]<<24);G[d+12>>2]=b;b=H[67553]|H[67554]<<8|(H[67555]<<16|H[67556]<<24);G[d>>2]=H[67549]|H[67550]<<8|(H[67551]<<16|H[67552]<<24);G[d+4>>2]=b;tb(5,qb(d,a,30))}Fa=d+192|0}function zt(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;f=Fa-16|0;Fa=f;e=ce(a,0,f+12|0);G[f+8>>2]=e;a:{if(e){Ua(54978);Ua(a);break a}b:{if(H[442496]==33){e=442497;Ed(442497);break b}e=442496;d=ac(442496,13287);if(!d){break b}Ua(55035);Ua(442496);Hb(d);E[442496]=0;e=105;break a}k=ac(e,30825);if(!k){Ua(55090);Ua(442496);E[442496]=0;e=105;break a}g=G[f+12>>2];d=Fa+-64|0;Fa=d;c:{if(G[f+8>>2]>0){break c}d:{j=ab(115200);if(!j){break d}i=ab(115200);if(!i){break d}G[d+48>>2]=0;G[d+40>>2]=0;G[d+44>>2]=0;G[d+24>>2]=115200;G[d+20>>2]=i;e:{if(Ti(d+8|0)){break e}f:{while(1){h=zc(j,1,115200,g);if(G[g+76>>2]<0){m=G[g>>2]}else{m=G[g>>2]}if(m>>>5&1){break f}if(h){G[d+12>>2]=h;G[d+8>>2]=j;g:{while(1){h:{switch(Ch(d+8|0)+5|0){case 0:case 5:if(!G[d+12>>2]){break g}if((hb(i,1,115200,k)|0)!=115200){break f}G[d+20>>2]=i;G[d+24>>2]=115200;l=l+115200|0;continue;case 6:break g;default:break h}}break}break f}if(G[g+76>>2]<0){h=G[g>>2]}else{h=G[g>>2]}if(!(h>>>4&1)){continue}}break}i:{h=G[d+28>>2];if(h>>>0<=l>>>0){break i}if((hb(i,1,h-l|0,k)|0)==(G[d+28>>2]-l|0)){break i}break f}Wa(j);Wa(i);if(ye(d+8|0)){break e}break c}ye(d+8|0);Wa(j);Wa(i)}G[f+8>>2]=414;break c}G[f+8>>2]=113}Fa=d- -64|0;Hb(g);Hb(k);if(G[f+8>>2]){Ua(38352);Ua(a);Ua(37853);Ua(442496);E[442496]=0;e=G[f+8>>2];break a}a=Za(a,e);E[442496]=0;e=dk(a,b,c)}Fa=f+16|0;return e|0}function sm(a,b){var c=0,d=0,e=0,f=0,g=0,h=0;d=Fa-32|0;Fa=d;a:{if(!a|!G[a+3312>>2]){break a}b:{c:{d:{if(!b|!H[b|0]){break d}if(!Xa(b,33562)){break d}if(Xa(b,5332)){break c}}c=G[a+3964>>2];b=Za(a+3880|0,a+3848|0);e=L[a+120>>3];L[a+3952>>3]=e;e:{switch(c-1|0){case 1:if(e!=1950){E[b|0]=66;L[d>>3]=e;Eb(a+3881|0,18949,d);c=(Va(b)+a|0)+3879|0;if(H[c|0]==48){E[c|0]=0}c=(Va(b)+a|0)+3879|0;if(H[c|0]==48){E[c|0]=0}c=2;b=(Va(b)+a|0)+3879|0;if(H[b|0]!=48){break b}E[b|0]=0;break b}c=H[41563]|H[41564]<<8;E[b+4|0]=c;E[b+5|0]=c>>>8;c=H[41559]|H[41560]<<8|(H[41561]<<16|H[41562]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;c=2;break b;case 0:break e;default:break b}}if(e!=2e3){E[b|0]=74;L[d+16>>3]=e;Eb(a+3881|0,18949,d+16|0);c=(Va(b)+a|0)+3879|0;if(H[c|0]==48){E[c|0]=0}c=(Va(b)+a|0)+3879|0;if(H[c|0]==48){E[c|0]=0}c=1;b=(Va(b)+a|0)+3879|0;if(H[b|0]!=48){break b}E[b|0]=0;break b}c=H[41649]|H[41650]<<8;E[b+4|0]=c;E[b+5|0]=c>>>8;c=H[41645]|H[41646]<<8|(H[41647]<<16|H[41648]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24;c=1;break b}c=Nf(b);if((c|0)<0){break a}f=G[a+3964>>2];if((f|0)!=(c|0)&f-5>>>0<2){break a}Za(a+3880|0,b);g=a,h=Zh(b),L[g+3952>>3]=h}G[a+3968>>2]=c;if(!G[a+3312>>2]){break a}b=c-3|0;f:{if(b>>>0>6){b=3;c=0;break f}c=b<<2;b=G[c+145364>>2];c=G[c+145336>>2]}G[a+3288>>2]=b;G[a+3292>>2]=c}Fa=d+32|0}function Cr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;a:{b:{if(G[c+4>>2]==109){i=L[c+112>>3];break b}G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=65;E[c+1|0]=73;E[c+2|0]=82;E[c+3|0]=0;E[c+4|0]=109;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;f=L[c+24>>3];if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=57.29577951308232}i=f+f;L[c+112>>3]=i;f=L[c+40>>3];c:{if(f==90){G[c+128>>2]=0;G[c+132>>2]=1072693248;G[c+120>>2]=0;G[c+124>>2]=-1075838976;f=1;break c}l=1;if(!(f>-90)){break a}g=Mb((90-f)*.5);f=g*g;f=oc(g)*f/(1-f);L[c+120>>3]=f;f=.5-f;L[c+128>>3]=f;i=L[c+112>>3]}G[c+1892>>2]=115;G[c+1888>>2]=116;L[c+160>>3]=57.29577951308232/f;L[c+152>>3]=f*1e-4;G[c+144>>2]=-350469331;G[c+148>>2]=1058682594;L[c+136>>3]=f*i}f=0;j=V(a*a+b*b)/i;if(j!=0){d:{if(!(L[c+152>>3]>j)){m=L[c+120>>3];c=0;k=1;e:{while(1){f=k*.5;g=V(1-f*f)/f;i=-(m*g+oc(f)/g);if(j<=i){break e}k=f;n=i;c=c+1|0;if((c|0)!=30){continue}break}return 2}l=2;if((c|0)==30){break a}c=0;while(1){f:{g=(i-j)/(i-n);h=.1;g:{if(g<.1){break g}h=g;if(!(g>.9)){break g}h=.9}h=f-h*(f-k);g=V(1-h*h)/h;o=m*g+oc(h)/g;g=-o;h:{if(g>3]}a=Ac(a,-b)}else{a=0}L[d>>3]=a;L[e>>3]=90-(f+f);l=0}return l|0}function Er(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;m=G[c+4>>2];h=m>>31;a:{if(((h^m)-h|0)!=107){h=1;if(wj(c)){break a}}h=1;m=G[c+272>>2];if((m|0)<=0){break a}j=V(a*a+b*b)/L[c+24>>3];b:{c:{switch(m-1|0){case 0:g=(j-L[c+32>>3])/L[c+40>>3];break b;case 1:h=2;k=L[c+40>>3];i=L[c+48>>3];g=k*k+i*-4*(L[c+32>>3]-j);if(g<0){break a}f=V(g);g=i+i;i=(f-k)/g;f=(-k-f)/g;g=f>i?i:f;f=g<-1e-13?f3.141592653589793)){g=f;break b}if(!(f>3.141592653589893)){break b}break a;default:break c}}n=L[c+32>>3];if(n>j){h=2;if(!(n+-1e-13>j)){break b}break a}g=L[c+112>>3];k=L[c+120>>3];if(!(k.9)){break d}g=.9}g=i-g*(i-p);l=0;f=0;h=m;if(o){while(1){f=f*g+L[((h<<3)+c|0)+32>>3];h=h-1|0;l=l+1|0;if((o|0)!=(l|0)){continue}break}}if(m>>>0>=3){while(1){l=(h<<3)+c|0;f=(((f*g+L[l+32>>3])*g+L[l+24>>3])*g+L[l+16>>3])*g+L[l+8>>3];l=(h|0)>3;h=h-4|0;if(l){continue}break}}e:{if(!(f>>0<99;k=f;q=q+1|0;if(h){continue}break}break b}h=2;if(k+1e-13>3]=a;L[e>>3]=g*-180/3.141592653589793+90;h=0}return h|0}function Lh(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;a:{b:{c:{d:{if(!a|!H[a|0]){break d}E[c|0]=0;if(!H[a|0]){break d}f=a;while(1){h=Sb(f,b);if(!h){break d}e:{f:{if((a|0)==(h|0)){break f}f=H[h-1|0];if((f|0)==91){break f}if((f|0)!=44){break e}}d=Va(b)+h|0;while(1){f=d;d=d+1|0;e=E[f|0];if((e|0)==32|e-9>>>0<5){continue}break}if((e|0)!=61){break e}while(1){b=f;f=b+1|0;e=E[b+1|0];d=e;if((d|0)==32|d-9>>>0<5){continue}break}g=e&255;d=g-34|0;if(d>>>0>6|!(1<4095?4095:b;j=rb(c,f,b)+b|0,k=0,E[j|0]=k;l:{m:{if(a>>>0>=h>>>0){break m}a=h-1|0;if(H[a|0]!=44){break m}h=a;break l}d=(H[d|0]==44)+d|0}yd(h,d,Va(d)+1|0);return b}function Bj(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0;e=Fa-176|0;Fa=e;g=c<0;c=Yc(g?-c:c,360);c=g?-c:c;c=(c<0?c+360:c)/15;a:{if(O(c)<2147483648){g=~~c;break a}g=-2147483648}c=(c-+(g|0))*60;b:{if(O(c)<2147483648){f=~~c;break b}f=-2147483648}c=(c-+(f|0))*60;c:{if((d|0)>=6){d=c>59.999999;L[e+8>>3]=d?0:c;f=d+f|0;d=(f|0)>59;G[e+4>>2]=d?0:f;G[e>>2]=(d+g|0)%24;Eb(e+112|0,18801,e);break c}if((d|0)==5){d=c>59.99999;L[e+24>>3]=d?0:c;f=d+f|0;d=(f|0)>59;G[e+20>>2]=d?0:f;G[e+16>>2]=(d+g|0)%24;Eb(e+112|0,18905,e+16|0);break c}if((d|0)>=4){d=c>59.9999;L[e+40>>3]=d?0:c;f=d+f|0;d=(f|0)>59;G[e+36>>2]=d?0:f;G[e+32>>2]=(d+g|0)%24;Eb(e+112|0,18932,e+32|0);break c}if((d|0)==3){d=c>59.999;L[e+56>>3]=d?0:c;f=d+f|0;d=(f|0)>59;G[e+52>>2]=d?0:f;G[e+48>>2]=(d+g|0)%24;Eb(e+112|0,19119,e+48|0);break c}if((d|0)>=2){d=c>59.99;L[e+72>>3]=d?0:c;f=d+f|0;d=(f|0)>59;G[e+68>>2]=d?0:f;G[e+64>>2]=(d+g|0)%24;Eb(e+112|0,19260,e- -64|0);break c}if((d|0)==1){d=c>59.9;L[e+88>>3]=d?0:c;f=d+f|0;d=(f|0)>59;G[e+84>>2]=d?0:f;G[e+80>>2]=(d+g|0)%24;Eb(e+112|0,19279,e+80|0);break c}c=c+.5;d:{if(O(c)<2147483648){h=~~c;break d}h=-2147483648}d=h;d=(d|0)>59;G[e+104>>2]=d?0:h;f=d+f|0;d=(f|0)>59;G[e+100>>2]=d?0:f;G[e+96>>2]=(d+g|0)%24;db(e+112|0,29793,e+96|0)}b=b-1|0;e:{if((Va(e+112|0)|0)<(b|0)){Za(a,e+112|0);break e}i=rb(a,e+112|0,b)+b|0,j=0,E[i|0]=j}Fa=e+176|0}function Je(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;f=Fa-112|0;Fa=f;h=G[e>>2];a:{if((h|0)>0){break a}m=G[a>>2];k=1;if(G[G[a+4>>2]+20>>2]){k=H[(Va(c)+c|0)-1|0]==35}G[f+24>>2]=0;if(!mb(a,1,f+28|0,f+24|0)){n=(b|0)==-1;h=1;while(1){b:{if(G[e>>2]<=0){c:{d:{i=G[a>>2];g=G[a+4>>2];if((i|0)!=G[g+76>>2]){mb(a,i+1|0,0,e);break d}if((G[g+128>>2]&G[g+132>>2])!=-1){break d}if((Rb(a,e)|0)<=0){break d}i=G[e>>2];break c}i=G[G[a+4>>2]+1088>>2]!=0}g=2;if(i){break b}}g=-1}e:{f:{if(n){break f}i=G[f+28>>2];if((i|0)==(b|0)){break f}if((g|0)!=(i|0)){break e}}ef(a,2,e);if((Fc(a,35480,f+32|0,0,f+24|0)|0)<=0){g:{if(k){break g}j=0;g=Va(f+32|0)+f|0;if(H[g+31|0]!=35){break g}E[g+31|0]=0;j=1}Fg(c,f+32|0,0,f+20|0,f+16|0);l=G[f+16>>2]}h:{if(!(l?G[f+24>>2]:1)){break h}G[f+24>>2]=0;if((Fc(a,35472,f+32|0,0,f+24|0)|0)>0){break h}i:{if(k){break i}j=0;g=Va(f+32|0)+f|0;if(H[g+31|0]!=35){break i}E[g+31|0]=0;j=1}Fg(c,f+32|0,0,f+20|0,f+16|0);l=G[f+16>>2]}if(G[f+24>>2]|!l){break e}if(d){j:{if((Ec(a,33996,f+12|0,0,f+24|0)|0)<=0){g=G[f+12>>2];break j}G[f+12>>2]=1;g=1}if((g|0)!=(d|0)){break e}if(j){G[G[a+4>>2]+20>>2]=0}h=G[e>>2];break a}if(j){G[G[a+4>>2]+20>>2]=0}h=G[e>>2];break a}G[f+24>>2]=0;h=h+1|0;if(!mb(a,h,f+28|0,f+24|0)){continue}break}}mb(a,m+1|0,0,e);h=301;G[e>>2]=301}Fa=f+112|0;return h|0}function Il(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0;f=Fa-16|0;Fa=f;a:{if(a){c=G[936854];if(c){while(1){b=G[c+4>>2];d=Sb(b,a);b:{if(!d){break b}if((Va(d)|0)!=(Va(a)|0)){break b}if((b|0)==(d|0)|H[b+(d+(b^-1)|0)|0]==47){break a}}c=G[c>>2];if(c){continue}break}}c=Ic(24,1);if(!c){c=0;hb(72898,36,1,G[24367]);break a}h=c,i=Lc(a),G[h+4>>2]=i;c:{d:{e:{b=Uf(a,46);if(!b){break e}f:{if(!Xc(b,17583)){break f}if(!Xc(b,17549)){break f}if(Xc(b,18022)){break e}}G[c+8>>2]=1;break d}G[c+8>>2]=2;b=0;d=ab(Va(a)+1|0);while(1){e=H[a+b|0];if(!(!e|(e|0)==91)){E[b+d|0]=e;b=b+1|0;continue}break}E[b+d|0]=0;b=Fd(34915);G[936856]=b;g=Ll(d,13287,0,b);pb(d);if(!g|!H[g|0]){break c}d=Va(g)+1|0;b=jb(a,91);if(b){a=Va(b);b=Za(ab(a+1|0),b);g:{while(1){e=a;if((a|0)<=0){break g}a=e-1|0;if(H[b+a|0]!=93){continue}break}E[b+e|0]=0}a=b}else{a=0}if(a){d=Va(a)+d|0}b=Xb(d);G[c+16>>2]=b;Za(b,g);if(a){Gb(G[c+16>>2],a)}pb(a);pb(g)}a=G[936854];if(!a){G[936854]=c;break a}while(1){b=a;a=G[a>>2];if(a){continue}break}G[b>>2]=c;break a}G[f>>2]=a;a=G[936856];G[f+4>>2]=a?a:21273;_a(G[24367],77151,f);if(c){a=G[936854];h:{if(!a){break h}i:{if((a|0)==(c|0)){b=3747416;break i}while(1){b=a;if(!a){break h}a=G[b>>2];if((c|0)!=(a|0)){continue}break}}G[b>>2]=G[c>>2]}pb(G[c+4>>2]);pb(G[c+16>>2]);a=G[c+12>>2];if(a){Hb(a)}pb(c)}}c=0}Fa=f+16|0;return c}function kk(a,b,c){var d=0,e=0;d=Fa-192|0;Fa=d;a:{if(G[c>>2]>0){break a}b:{c:{d:{e:{f:{g:{e=H[a|0];switch(e-39|0){case 1:break e;case 0:break f;default:break g}}h:{switch(e-70|0){default:if(e){break d}G[c>>2]=204;break a;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:break d;case 0:case 14:break h}}K[b>>2]=(e|0)==84?N(1):N(0);break c}e=d+96|0;fd(a,e,c);sk(e,b,c);break c}G[c>>2]=405;break b}sk(a,b,c)}if(G[c>>2]<=0){break a}}G[b>>2]=0;b=H[67140]|H[67141]<<8|(H[67142]<<16|H[67143]<<24);c=H[67136]|H[67137]<<8|(H[67138]<<16|H[67139]<<24);F[d+38>>1]=c;F[d+40>>1]=c>>>16;F[d+42>>1]=b;F[d+44>>1]=b>>>16;b=H[67134]|H[67135]<<8|(H[67136]<<16|H[67137]<<24);G[d+32>>2]=H[67130]|H[67131]<<8|(H[67132]<<16|H[67133]<<24);G[d+36>>2]=b;b=H[67126]|H[67127]<<8|(H[67128]<<16|H[67129]<<24);G[d+24>>2]=H[67122]|H[67123]<<8|(H[67124]<<16|H[67125]<<24);G[d+28>>2]=b;b=H[67118]|H[67119]<<8|(H[67120]<<16|H[67121]<<24);G[d+16>>2]=H[67114]|H[67115]<<8|(H[67116]<<16|H[67117]<<24);G[d+20>>2]=b;b=H[67110]|H[67111]<<8|(H[67112]<<16|H[67113]<<24);G[d+8>>2]=H[67106]|H[67107]<<8|(H[67108]<<16|H[67109]<<24);G[d+12>>2]=b;b=H[67102]|H[67103]<<8|(H[67104]<<16|H[67105]<<24);G[d>>2]=H[67098]|H[67099]<<8|(H[67100]<<16|H[67101]<<24);G[d+4>>2]=b;tb(5,qb(d,a,30))}Fa=d+192|0}function lh(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0;e=Fa-416|0;Fa=e;G[e+408>>2]=65473;a:{d=G[c>>2];if(d){break a}G[b>>2]=0;d=Sd(a,0,e+144|0,c);G[c>>2]=d;while(1){if(d){if((d|0)==202){G[c>>2]=0;d=0}g=1;if(G[b>>2]<=0){break a}f=1;while(1){if(d){break a}G[e+48>>2]=f;d=e+320|0;Ya(d,75,30030,e+48|0);d=Ec(a,d,e+412|0,e+144|0,c);G[c>>2]=d;b:{if((d|0)==202){d=0;G[c>>2]=0;j=j+1|0;break b}g=g+1|0;if((j|0)<=0){break b}h=f-j|0;G[e+32>>2]=h;d=e+240|0;Ya(d,75,30030,e+32|0);i=e+320|0;pl(a,i,d,c);G[e+16>>2]=f;Ya(i,75,30038,e+16|0);G[e>>2]=h;Ya(d,75,30038,e);d=Di(a,i,e+60|0,e- -64|0,c);G[c>>2]=d;if(!d){kf(a,e+320|0,c);uq(a,e+240|0,G[e+60>>2],e- -64|0,c);nq(a,c);Wa(G[e+60>>2]);d=G[c>>2]}if((d|0)!=202){break b}d=0;G[c>>2]=0}f=f+1|0;if(G[b>>2]>=(g|0)){continue}break}break a}i=e+408|0;d=Fa-176|0;Fa=d;h=e+144|0;E[h|0]=0;f=G[c>>2];if((f|0)<=0){c:{if((kc(a,49138,d+80|0,c)|0)>0){break c}while(1){Fi(d+80|0,d,d+164|0);g=0;d:{while(1){Fg(G[i+(g<<2)>>2],d,0,d+172|0,d+168|0);f=-1;if(G[d+172>>2]){while(1){if((f|0)==-1){break d}f=f+1|0;Fg(G[f<<2>>2],d,0,d+172|0,d+168|0);if(!G[d+172>>2]){continue}break}}g=g+1|0;if((g|0)!=1){continue}break}if((kc(a,49138,d+80|0,c)|0)<=0){continue}break c}break}Gb(h,d+80|0)}f=G[c>>2]}Fa=d+176|0;d=f;G[c>>2]=d;if(d){continue}G[b>>2]=G[b>>2]+1;continue}}Fa=e+416|0;return d}function cm(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;if(G[321436]){k=G[24367];hb(88619,25,1,k);$a(k)}a:{if(H[3706504]){g=L[463332];f=L[463330];h=L[463328];e=L[463314];break a}G[926630]=442745336;G[926631]=1078765020;G[926628]=-1571644103;G[926629]=1066524486;G[926632]=-1929575474;G[926633]=-1078909396;G[926636]=-102333635;G[926637]=1071614172;G[926640]=-960750452;G[926641]=-1075068062;G[926644]=2146916876;G[926645]=-1075057251;G[926648]=203628506;G[926649]=-1076047236;G[926652]=-1327103221;G[926653]=-1077404504;G[926656]=875303292;G[926657]=-1075908019;G[926660]=656523441;G[926661]=1072157603;G[926664]=-867076380;G[926665]=1071477737;E[3706504]=1;h=-.48353891463218424;f=.7445846332830311;g=.4601997847838517;e=.017453292519943295}i=e*b;b=eb(i);a=e*a;j=ib(a);e=eb(a);a=ib(i);e=e*b;b=j*b;g=g*a+(h*e+f*b);f=O(g);b:{if(f>=1){n=d,o=fc(g/f),L[n>>3]=o;a=0;break b}f=L[463326];h=L[463322];i=L[463324];j=L[463320];l=L[463316];m=L[463318];n=d,o=fc(g),L[n>>3]=o;a=Db(f*a+(h*e+b*i),j*a+(l*e+b*m))}b=L[463315];a=a*b;if(a<0){while(1){a=a+360;if(a<0){continue}break}}L[c>>3]=a;if(a>360){while(1){a=a+-360;if(a>360){continue}break}L[c>>3]=a}a=b*L[d>>3];L[d>>3]=a;b=90;c:{if(!(O(a)>=90)){break c}G[c>>2]=0;G[c+4>>2]=0;a=L[d>>3];if(!(a>90)){b=-90;if(!(a<-90)){break c}}L[d>>3]=b}}function gh(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0;a:{b:{c:{A(+a);b=v(1)|0;v(0)|0;d:{e:{e=b&2147483647;if(e>>>0>=1078159482){A(+a);e=v(1)|0;e=e&2147483647;if((e|0)==2146435072&(v(0)|0)!=0|e>>>0>2146435072){break a}if((b|0)<0){return-1}if(!(a>709.782712893384)){break e}return a*898846567431158e293}if(e>>>0<1071001155){break c}if(e>>>0>1072734897){break e}if((b|0)>0|(b|0)>=0){b=1;c=1.9082149292705877e-10;g=a+-.6931471803691238;break d}b=-1;c=-1.9082149292705877e-10;g=a+.6931471803691238;break d}A(.5);b=v(1)|0;h=v(0)|0;A(+a);e=v(1)|0;v(0)|0;x(0,h|0);x(1,b&2147483647|e&-2147483648);c=a*1.4426950408889634+ +z();f:{if(O(c)<2147483648){b=~~c;break f}b=-2147483648}d=+(b|0);c=d*1.9082149292705877e-10;g=a+d*-.6931471803691238}a=g;a=a-c;c=g-a-c;break b}if(e>>>0<1016070144){break a}b=0}f=a*.5;d=a*f;g=d*(d*(d*(d*(d*-2.0109921818362437e-7+4008217827329362e-21)+-793650757867488e-19)+.0015873015872548146)+-.03333333333333313)+1;f=3-g*f;f=d*((g-f)/(6-a*f));if(!b){return a-(a*f-d)}c=a*(f-c)-c-d;g:{switch(b+1|0){case 0:return(a-c)*.5+-.5;case 2:if(a<-.25){return(c-(a+.5))*-2}a=a-c;return a+a+1;default:break g}}x(0,0);x(1,b+1023<<20);d=+z();if(b>>>0>=57){a=a-c+1;return((b|0)==1024?(a+a)*898846567431158e293:a*d)+-1}x(0,0);x(1,1023-b<<20);f=+z();a=(b>>>0<=19?1-f+(a-c):a-(c+f)+1)*d}return a}function dr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;a:{if(G[c+4>>2]==801){j=L[c+152>>3];k=L[c+120>>3];break a}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=72;E[c+1|0]=80;E[c+2|0]=88;E[c+3|0]=0;E[c+4|0]=33;E[c+5|0]=3;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;g=L[c+48>>3];b:{if(O(g)<2147483648){h=~~g;break b}h=-2147483648}G[c+272>>2]=(h|0)%2;f=L[c+24>>3];c:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;k=1;f=1;break c}k=57.29577951308232/f;f=f*3.141592653589793/180}L[c+112>>3]=f;G[c+1892>>2]=139;G[c+1888>>2]=140;L[c+120>>3]=k;j=g+-1;L[c+128>>3]=j/g;L[c+144>>3]=(g+1)*.5;i=L[c+40>>3];L[c+168>>3]=i/360;l=180/i;L[c+160>>3]=l;j=j*90/i;L[c+152>>3]=j;g=g*90/i;L[c+136>>3]=g;L[c+184>>3]=f*l;L[c+176>>3]=f*g}f=k*b;i=O(f);d:{e:{if(i<=j){L[d>>3]=k*a;h=2;a=f/L[c+136>>3];if(a<-1|a>1){break d}a=Bc(a);break e}h=2;if(!(i<=90)){break d}m=f<=0;g=L[c+168>>3];f=L[c+40>>3];f:{if(O(f)<2147483648){h=~~f;break f}h=-2147483648}h=(h|0)%2|0;g:{if(G[c+272>>2]?h:m?1-h|0:h){g=S(g*a+0);f=g+g+f;g=L[c+160>>3];f=f*g+-180;break g}g=S(g*a);f=g+g+f+1;g=L[c+160>>3];f=f*g+-180}h=2;i=L[c+144>>3]-i/g;if(i==0){break d}a=(a-f)/i;if(!(O(a)<=g)){break d}L[d>>3]=k*(f+a);a=1-i*i/L[c+48>>3];if(a<-1|a>1){break d}a=Bc(a);L[e>>3]=a;h=0;if(!(b<0)){break d}a=-a}L[e>>3]=a;h=0}return h|0}function br(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0;a:{if(G[c+4>>2]==802){g=L[c+120>>3];break a}E[c|0]=88;E[c+1|0]=80;E[c+2|0]=72;E[c+3|0]=0;E[c+4|0]=34;E[c+5|0]=3;E[c+6|0]=0;E[c+7|0]=0;f=L[c+24>>3];b:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;g=1;f=1;break b}g=57.29577951308232/f;f=f*3.141592653589793/180}G[c+1892>>2]=141;G[c+1888>>2]=142;G[c+160>>2]=-1279502567;G[c+164>>2]=1066787723;G[c+152>>2]=1514773339;G[c+156>>2]=1079410611;G[c+144>>2]=1232524644;G[c+148>>2]=1078420498;G[c+136>>2]=-350469331;G[c+140>>2]=1058682594;G[c+128>>2]=1431655765;G[c+132>>2]=1071994197;g=g/1.4142135623730951;L[c+120>>3]=g;L[c+112>>3]=f/1.4142135623730951}a=g*a;b=g*b;c:{if(!(!(a<=0)|!(b>0))){j=-180;f=a-b;g=-a-b;break c}if(!(!(a<0)|!(b<=0))){j=-90;f=a+b;g=a-b;break c}if(!(!(a>=0)|!(b<0))){f=b-a;g=a+b;break c}j=90;f=-a-b;g=b-a}h=f+90;f=O(h);if(f<=90){d:{e:{if(f<=45){L[d>>3]=g+45+j;k=e,l=Bc(h/67.5),L[k>>3]=l;c=2;if(!(O(g)>45.000000000001)){break e}break d}f=(90-f)/45;i=b<=0?0:180;f:{if(a==0){break f}i=a<0?-90:90;if(b==0){break f}i=g/f+45+j}L[d>>3]=i;if(f>3]){a=90-f*L[c+144>>3]}else{a=Bc(f*f/-3+1)}L[e>>3]=h<0?-a:a;if(!(h<-45)){break e}c=2;if(O(g)>h+90+1e-12){break d}}c=0}return c|0}G[d>>2]=0;G[d+4>>2]=0;G[e>>2]=0;G[e+4>>2]=0;return 2}function hs(a,b,c,d,e,f,g,h,i,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;q=Fa-16|0;Fa=q;G[q+12>>2]=j;a:{k=G[a+8>>2];s=G[a>>2]+M(c,3)|0;p=s-2|0;l=M(p,168);n=k+l|0;e=G[n+32>>2];if(e){break a}m=lb(1e3,8);G[n+32>>2]=m;j=0;G[n+28>>2]=0;e=1e3;while(1){if((e|0)<=(j|0)){e=e+1e3|0;j=ub(m,e<<3);k=G[a+8>>2];G[(l+k|0)+32>>2]=j}o=G[q+12>>2]+7&-8;G[q+12>>2]=o+8;j=k+l|0;m=G[j+32>>2];n=G[j+28>>2];r=L[o>>3];L[m+(n<<3)>>3]=r;b:{if(!(O(r+-9007199254740992)<=1e-15)){break b}o=n-1|0;if(!(O(L[(o<<3)+m>>3]+-9007199254740992)<=1e-15)){break b}G[j+28>>2]=o;j=M(p,168);e=j+G[a+8>>2]|0;e=ub(G[e+32>>2],G[e+28>>2]<<3);k=G[a+8>>2];G[(j+k|0)+32>>2]=e;break a}o=j;j=n+1|0;G[o+28>>2]=j;continue}}j=G[(k+l|0)+28>>2];c:{if((j|0)==3){k=je(a,b,c,d,j,f,g,r,r,L[e>>3],L[e+8>>3],r);break c}k=(j<<3)+e|0;h=L[k-16>>3];i=L[k-24>>3];if(d){k=0;if(!je(a,0,p,d,j,f,g,h,h,i,h,h)){break c}if(je(a,0,s-1|0,d,j,f,g,h,h,L[e>>3],L[e+8>>3],h)|(j|0)<4){break c}k=1;p=j-4>>>1|0;j=0;m=2;while(1){l=m<<3;if(je(a,b+j|0,c+j|0,d,j,f,g,h,h,L[l+e>>3],L[(l|8)+e>>3],h)){break c}m=m+2|0;l=(j|0)==(p|0);j=j+1|0;if(!l){continue}break}k=0;break c}k=1;if(!je(a,0,p,1,j,f,g,h,h,i,h,h)){break c}k=(je(a,0,s-1|0,1,j,f,g,h,h,L[e>>3],L[e+8>>3],h)|0)!=0}Fa=q+16|0;return k|0}function Zs(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0;Nd(a);d=G[a+8>>2];a:{if(!G[309737]){if((d|0)<=0){break a}while(1){e=G[309727];c=G[309722]+M(G[((g<<2)+a|0)+12>>2],344)|0;b:{if(G[c>>2]==-1e3){b=G[a+56>>2];b=(M(b,e)+h|0)-b|0;if((b|0)<0){break b}while(1){E[G[a+84>>2]+b|0]=0;c:{d:{switch(G[a+52>>2]-258|0){case 0:E[G[a+88>>2]+b|0]=H[c+88|0];break c;case 1:G[G[a+88>>2]+(b<<2)>>2]=G[c+88>>2];break c;case 2:break d;default:break c}}L[G[a+88>>2]+(b<<3)>>3]=L[c+88>>3]}b=b-G[a+56>>2]|0;if((b|0)>=0){continue}break}break b}if(!e){break b}b=G[c+56>>2];if(!b){break b}d=M(b,e);while(1){e=e-1|0;b=G[c+56>>2];e:{if(!b){break e}i=M(G[a+56>>2],e)+h|0;while(1){b=b-1|0;f=i+b|0;d=d-1|0;E[f+G[a+84>>2]|0]=H[d+G[c+84>>2]|0];f:{switch(G[a+52>>2]-258|0){case 0:E[G[a+88>>2]+f|0]=H[G[c+88>>2]+d|0];if(!b){break e}continue;case 1:G[G[a+88>>2]+(f<<2)>>2]=G[G[c+88>>2]+(d<<2)>>2];if(!b){break e}continue;case 2:L[G[a+88>>2]+(f<<3)>>3]=L[G[c+88>>2]+(d<<3)>>3];break;default:break f}}if(b){continue}break}}if(e){continue}break}}h=G[c+56>>2]+h|0;d=G[a+8>>2];g=g+1|0;if((d|0)>(g|0)){continue}break}}if((d|0)<=0){break a}c=G[309722];b=0;while(1){e=M(G[((b<<2)+a|0)+12>>2],344)+c|0;if(G[e>>2]>0){Wa(G[e+88>>2]);c=G[309722];d=G[a+8>>2]}b=b+1|0;if((d|0)>(b|0)){continue}break}}}function Pq(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0;c=Fa-144|0;Fa=c;d=G[935658];e=L[d+32>>3];g=L[d+16>>3];f=L[d+24>>3];g=L[a+32>>3]*e+(L[a+16>>3]*g+L[a+24>>3]*f)-(L[b+32>>3]*e+(L[b+16>>3]*g+f*L[b+24>>3]));a:{if(G[935573]<3){break a}id();G[c+128>>2]=G[a+48>>2];kb(75228,c+128|0);G[c+112>>2]=G[b+48>>2];kb(75213,c+112|0);L[c+96>>3]=L[a+40>>3];gb(72046,c+96|0);L[c+80>>3]=L[b+40>>3];gb(72026,c+80|0);L[c+64>>3]=g;gb(72066,c- -64|0);d=G[29763];$a(d);if(G[935573]<3){break a}f=L[b+40>>3];e=L[a+40>>3];if(f>3];e=L[a+40>>3]}if(e>3];f=L[b+40>>3];b:{if(e>f){break b}d=-1;if(e>2]=1;if(G[935573]>=3){G[c>>2]=G[b+48>>2];kb(87856,c);yb(5931);$a(G[29763])}G[935659]=G[935659]+1;break b}if(g<-e){d=1;G[a+52>>2]=1;if(G[935573]>=3){G[c+16>>2]=G[a+48>>2];kb(87872,c+16|0);yb(11117);$a(G[29763])}G[935659]=G[935659]+1;break b}h=G[b+48>>2];d=G[a+48>>2];if((h|0)<(d|0)){d=1;G[b+52>>2]=1;if(G[935573]>=3){G[c+32>>2]=h;kb(87856,c+32|0);yb(11117);$a(G[29763])}G[935659]=G[935659]+1;break b}if(!G[a+52>>2]){G[a+52>>2]=1;if(G[935573]>=3){G[c+48>>2]=d;kb(87872,c+48|0);$a(G[29763])}G[935659]=G[935659]+1}d=0;if(G[935573]<3){break b}yb(16929);$a(G[29763])}Fa=c+144|0;return d|0}function hr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;i=G[c+4>>2];g=L[c+40>>3];if(g==0){a:{if((i|0)==301){g=L[c+24>>3];break a}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=83;E[c+1|0]=70;E[c+2|0]=76;E[c+3|0]=0;E[c+4|0]=45;E[c+5|0]=1;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;g=L[c+24>>3];b:{if(g==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=1;g=57.29577951308232;h=1;break b}f=g*3.141592653589793/180;h=1/f}G[c+1892>>2]=99;G[c+1888>>2]=100;L[c+112>>3]=f;L[c+120>>3]=h}f=eb(b/g);if(f!=0){a=L[c+120>>3]*a/f}else{a=0}L[d>>3]=a;L[e>>3]=L[c+120>>3]*b;return 0}c:{if((i|0)==601){f=L[c+128>>3];break c}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=66;E[c+1|0]=79;E[c+2|0]=78;E[c+3|0]=0;E[c+4|0]=89;E[c+5|0]=2;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];d:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;G[c+120>>2]=0;G[c+124>>2]=1072693248;f=Mb(g)*57.29577951308232/Kb(L[c+40>>3]);g=L[c+40>>3];f=f+g;break d}L[c+120>>3]=f*3.141592653589793/180;h=Mb(g)/Kb(L[c+40>>3]);g=L[c+40>>3];f=f*(h+g*3.141592653589793/180)}G[c+1892>>2]=135;G[c+1888>>2]=136;L[c+128>>3]=f}h=f-b;b=V(a*a+h*h);b=g<0?-b:b;if(b!=0){j=Ac(a/b,h/b);f=L[c+128>>3]}a=(f-b)/L[c+120>>3];L[e>>3]=a;a=Mb(a);if(a!=0){a=j*(b/L[c+24>>3])/a}else{a=0}L[d>>3]=a;return 0}function ti(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;l=Fa-16|0;Fa=l;a:{b:{c:{if((c|0)<=36){f=H[a|0];if(f){break c}g=a;break b}G[48624]=28;d=0;e=0;break a}g=a;d:{while(1){f=f<<24>>24;if(!((f|0)==32|f-9>>>0<5)){break d}f=H[g+1|0];g=g+1|0;if(f){continue}break}break b}e:{f=H[g|0];switch(f-43|0){case 0:case 2:break e;default:break b}}m=(f|0)==45?-1:0;g=g+1|0}f:{if(!((c|16)!=16|H[g|0]!=48)){o=1;if((H[g+1|0]&223)==88){g=g+2|0;j=16;break f}g=g+1|0;j=c?c:8;break f}j=c?c:10}p=j>>31;c=0;while(1){g:{f=-48;i=E[g|0];h:{if((i-48&255)>>>0<10){break h}f=-87;if((i-97&255)>>>0<26){break h}f=-55;if((i-65&255)>>>0>25){break g}}i=f+i|0;if((i|0)>=(j|0)){break g}ed(l,j,p,0,0,k,h,0,0);f=1;i:{if(G[l+8>>2]|G[l+12>>2]){break i}q=Au(k,h,j,p);n=Ia;r=i>>31;s=r^-1;if((n|0)==(s|0)&(i^-1)>>>0>>0|n>>>0>s>>>0){break i}h=n+r|0;f=i+q|0;h=f>>>0>>0?h+1|0:h;k=f;o=1;f=c}g=g+1|0;c=f;continue}break}if(b){G[b>>2]=o?g:a}j:{k:{if(c){G[48624]=68;a=d&1;m=a?0:m;k=d;h=e;break k}if((e|0)==(h|0)&d>>>0>k>>>0|e>>>0>h>>>0){break j}a=d&1}if(!(a|m)){G[48624]=68;a=d;d=a-1|0;e=e-!a|0;break a}if((e|0)==(h|0)&d>>>0>=k>>>0|e>>>0>h>>>0){break j}G[48624]=68;break a}a=m;b=a^k;d=b-a|0;c=a>>31;e=(c^h)-((a>>>0>b>>>0)+c|0)|0}Fa=l+16|0;Ia=e;return d}function ar(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;if(G[c+4>>2]!=802){E[c|0]=88;E[c+1|0]=80;E[c+2|0]=72;E[c+3|0]=0;E[c+4|0]=34;E[c+5|0]=3;E[c+6|0]=0;E[c+7|0]=0;f=L[c+24>>3];a:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;g=1;f=1;break a}g=57.29577951308232/f;f=f*3.141592653589793/180}G[c+1892>>2]=141;G[c+1888>>2]=142;G[c+160>>2]=-1279502567;G[c+164>>2]=1066787723;G[c+152>>2]=1514773339;G[c+156>>2]=1079410611;G[c+144>>2]=1232524644;G[c+148>>2]=1078420498;G[c+136>>2]=-350469331;G[c+140>>2]=1058682594;G[c+128>>2]=1431655765;G[c+132>>2]=1071994197;L[c+120>>3]=g/1.4142135623730951;L[c+112>>3]=f/1.4142135623730951}b:{if(!(O(a)>=180)){break b}a=Yc(a,360);if(a<-180){a=a+360;break b}if(!(a>=180)){break b}a=a+-360}a=a+180;h=d,i=Yc(a,90),L[h>>3]=i;L[e>>3]=a+-180;f=Kb(b);a=O(f);c:{if(a<=L[c+128>>3]){a=f*67.5;f=L[d>>3];break c}f=L[c+152>>3]>b?V((1-a)*3):(90-b)*L[c+160>>3];a=(2-f)*45;f=(L[d>>3]+-45)*f+45;if(!(b<0)){break c}a=-a}a=a+-90;b=f+-45;f=L[e>>3];d:{if(f<-90){L[d>>3]=(a-b)*L[c+112>>3];a=(-b-a)*L[c+112>>3];break d}if(f<0){L[d>>3]=(a+b)*L[c+112>>3];a=(a-b)*L[c+112>>3];break d}g=L[c+112>>3];if(f<90){L[d>>3]=(b-a)*g;a=(a+b)*L[c+112>>3];break d}L[d>>3]=(-b-a)*g;a=(b-a)*L[c+112>>3]}L[e>>3]=a;return 0}function Hm(a,b){var c=0,d=0,e=0,f=0,g=0;a:{b:{c:{d:{e:{c=G[a+4>>2];f:{if((c|0)!=G[a+104>>2]){G[a+4>>2]=c+1;c=H[c|0];break f}c=jc(a)}switch(c-43|0){case 0:case 2:break e;default:break d}}f=(c|0)==45;g=!b;c=G[a+4>>2];g:{if((c|0)!=G[a+104>>2]){G[a+4>>2]=c+1;c=H[c|0];break g}c=jc(a)}b=c-58|0;if(g|b>>>0>4294967285){break c}if(G[a+116>>2]<0){break b}G[a+4>>2]=G[a+4>>2]-1;break b}b=c-58|0}if(b>>>0<4294967286){break b}b=c-48|0;if(b>>>0<10){while(1){d=M(d,10)+c|0;d=d-48|0;e=(d|0)<214748364;b=G[a+4>>2];h:{if((b|0)!=G[a+104>>2]){G[a+4>>2]=b+1;c=H[b|0];break h}c=jc(a)}b=c-48|0;if(e&b>>>0<=9){continue}break}e=d>>31}i:{if(b>>>0>=10){break i}while(1){d=Au(d,e,10,0);c=d+c|0;b=Ia;b=c>>>0>>0?b+1|0:b;d=c-48|0;e=b-(c>>>0<48)|0;b=G[a+4>>2];j:{if((b|0)!=G[a+104>>2]){G[a+4>>2]=b+1;c=H[b|0];break j}c=jc(a)}b=c-48|0;if(b>>>0>9){break i}if(d>>>0<2061584302&(e|0)<=21474836|(e|0)<21474836){continue}break}}if(b>>>0<10){while(1){b=G[a+4>>2];k:{if((b|0)!=G[a+104>>2]){G[a+4>>2]=b+1;b=H[b|0];break k}b=jc(a)}if(b-48>>>0<10){continue}break}}b=G[a+116>>2];if((b|0)>0|(b|0)>=0){G[a+4>>2]=G[a+4>>2]-1}a=d;d=f?0-a|0:a;e=f?0-(((a|0)!=0)+e|0)|0:e;break a}e=-2147483648;if(G[a+116>>2]<0){break a}G[a+4>>2]=G[a+4>>2]-1;Ia=-2147483648;return 0}Ia=e;return d}function dm(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;if(G[321436]){k=G[24367];hb(89112,26,1,k);$a(k)}a:{if(H[3706216]){g=L[463294];f=L[463292];h=L[463290];e=L[463278];break a}G[926558]=442745336;G[926559]=1078765020;G[926556]=-1571644103;G[926557]=1066524486;G[926560]=52553840;G[926561]=-1075344588;G[926564]=-505530574;G[926565]=1072016415;G[926568]=-673237620;G[926569]=-1078782476;G[926572]=1753527554;G[926573]=-1078674469;G[926576]=-1081034383;G[926577]=1072680502;G[926580]=71334806;G[926581]=1072007784;G[926584]=-910810613;G[926585]=1072129682;G[926588]=489187355;G[926589]=1069297225;E[3706216]=1;h=.6731453021092075;f=.7312711658169645;g=.11008126222478191;e=.017453292519943295}i=e*a;j=ib(i);b=e*b;a=eb(b);e=eb(i);b=ib(b);e=e*a;a=j*a;g=g*b+(h*e+f*a);f=O(g);b:{if(f>=1){m=d,n=fc(g/f),L[m>>3]=n;a=0;break b}f=L[463288];h=L[463284];i=L[463286];j=L[463280];l=L[463282];m=d,n=fc(g),L[m>>3]=n;a=Db(f*b+(h*e+a*i),b*0+(j*e+a*l))}b=L[463279];a=a*b;if(a<0){while(1){a=a+360;if(a<0){continue}break}}L[c>>3]=a;if(a>360){while(1){a=a+-360;if(a>360){continue}break}L[c>>3]=a}a=b*L[d>>3];L[d>>3]=a;b=90;c:{if(!(O(a)>=90)){break c}G[c>>2]=0;G[c+4>>2]=0;a=L[d>>3];if(!(a>90)){b=-90;if(!(a<-90)){break c}}L[d>>3]=b}}function zu(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;a:{b:{c:{d:{e:{f:{g:{h:{i:{j:{e=b;if(e){if(!c){break j}f=d;if(!f){break i}e=P(f)-P(e)|0;if(e>>>0<=31){break h}break b}if((d|0)==1|d>>>0>1){break b}b=(a>>>0)/(c>>>0)|0;Ga=a-M(b,c)|0;Ha=0;Ia=0;return b}f=d;if(!a){break g}if(!f){break f}g=f-1|0;if(g&f){break f}Ga=a;Ha=e&g;a=e>>>Gu(f)|0;Ia=0;return a}f=c-1|0;if(!(f&c)){break e}h=(P(c)+33|0)-P(e)|0;g=0-h|0;break c}h=e+1|0;g=63-e|0;break c}Ga=0;a=(e>>>0)/(f>>>0)|0;Ha=e-M(a,f)|0;Ia=0;return a}e=P(f)-P(e)|0;if(e>>>0<31){break d}break b}Ga=a&f;Ha=0;if((c|0)==1){break a}d=a;c=Gu(c);a=c&31;if((c&63)>>>0>=32){e=0;a=b>>>a|0}else{e=b>>>a|0;a=((1<>>a}Ia=e;return a}h=e+1|0;g=63-e|0}i=a;e=h&63;f=e&31;if((e&63)>>>0>=32){e=0;k=b>>>f|0}else{e=b>>>f|0;k=((1<>>f}f=e;e=g&63;a=e&31;if((e&63)>>>0>=32){e=i<>>32-a|b<>>31;f=j<<1;j=e;f=b>>>31|f;e=i-((f>>>0>g>>>0)+e|0)>>31;l=e;m=c&e;k=f-m|0;f=j-((d&e)+(f>>>0>>0)|0)|0;e=b<<1|a>>>31;a=n|a<<1;b=e|o;j=0;l=l&1;n=l;h=h-1|0;if(h){continue}break}}Ga=k;Ha=f;e=b<<1|a>>>31;a=l|a<<1;Ia=e|j;return a}Ga=a;Ha=b;a=0;b=0}Ia=b;return a}function dk(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;f=Fa-2896|0;Fa=f;a:{b:{c:{d:{if(H[442496]){d=ce(a,0,f+2892|0);if(d){E[442496]=0;break a}d=ck(442496,c);if(d){break d}i=G[f+2892>>2];d=zc(f,1,2880,i);if(d){while(1){h=M(G[c>>2],24);k=h+202496|0;e:{l=h+202512|0;f:{if(G[l>>2]==1){g=h+202504|0;a=g;e=G[a+4>>2];a=G[a>>2];j=116;if(zf(G[k>>2],a,a>>31,0)){break f}G[g>>2]=a;G[g+4>>2]=e}if((hb(f,1,d,G[k>>2])|0)==(d|0)){break e}j=106}d=j;E[442496]=0;break a}a=h+202504|0;g=G[a+4>>2]+(d>>31)|0;e=d+G[a>>2]|0;g=e>>>0>>0?g+1|0:g;G[a>>2]=e;G[a+4>>2]=g;G[l>>2]=2;d=zc(f,1,2880,i);if(d){continue}break}}Hb(i);d=G[c>>2];a=M(d,24)+202496|0;if(!Hb(G[a>>2])){G[a>>2]=0}G[c>>2]=d;d=ce(442496,b,f+2892|0);E[442496]=0;break b}G[c>>2]=-1;while(1){if(!G[M(d,24)+202496>>2]){e=d;break c}e=d+1|0;if(!G[M(e,24)+202496>>2]){break c}e=d+2|0;if(!G[M(e,24)+202496>>2]){break c}e=d+3|0;if(!G[M(e,24)+202496>>2]){break c}e=d+4|0;if(!G[M(e,24)+202496>>2]){break c}d=d+5|0;if((d|0)!=1e4){continue}break}d=103;break a}Ua(37915);Ua(442496);E[442496]=0;break a}G[c>>2]=e;d=ce(a,b,f+2892|0)}b=G[f+2892>>2];c=M(G[c>>2],24);G[c+202512>>2]=0;a=c+202504|0;G[a>>2]=0;G[a+4>>2]=0;G[c+202496>>2]=b}Fa=f+2896|0;return d|0}function Fb(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;e=-1;a:{b:{if((c|0)<0){break b}d=G[309722];c:{d:{e:{f:{b=b?b:a;switch(b-258|0){case 0:break d;case 1:case 29:break e;case 2:case 30:break f;default:break c}}if(G[(M(c,344)+d|0)+52>>2]==260){return c}if((b|0)!=287){break c}}if(G[(M(c,344)+d|0)+52>>2]!=259){break c}return c}if(G[(M(c,344)+d|0)+52>>2]!=258){break c}return c}e=G[309723];if((e|0)==G[309724]){g:{if(d){G[309724]=e<<1;d=ub(d,M(e,688));break g}G[309724]=100;d=ab(34400)}if(!d){break a}G[309722]=d;e=G[309723]}G[309723]=e+1;if((e|0)<0){break b}f=M(e,344)+d|0;G[f+52>>2]=a;G[f+12>>2]=c;G[f+8>>2]=1;G[f+4>>2]=25;G[f>>2]=b;i=M(c,344)+d|0;G[f+56>>2]=G[i+56>>2];G[f+60>>2]=G[i+60>>2];g=G[i+60>>2];h:{if((g|0)<=0){break h}b=0;if(g-1>>>0>=3){n=g&-4;while(1){j=(M(e,344)+d|0)- -64|0;a=b<<2;k=(M(c,344)+d|0)- -64|0;G[j+a>>2]=G[a+k>>2];h=a|4;G[h+j>>2]=G[k+h>>2];h=a|8;G[h+j>>2]=G[k+h>>2];a=a|12;G[a+j>>2]=G[a+k>>2];b=b+4|0;l=l+4|0;if((n|0)!=(l|0)){continue}break}}a=g&3;if(!a){break h}while(1){g=b<<2;G[(g+(M(e,344)+d|0)|0)- -64>>2]=G[(g+(M(c,344)+d|0)|0)- -64>>2];b=b+1|0;m=m+1|0;if((a|0)!=(m|0)){continue}break}}if(G[i>>2]!=-1e3){break b}rn(f)}return e}G[309737]=113;return-1}function ck(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;d=Fa-5712|0;Fa=d;G[d+5704>>2]=0;a:{b:{e=Fd(32716);if(!e){break b}f=105;if(Va(e)>>>0>200){break a}e=Za(d+3376|0,e);c=jb(e,59);c:{if(c){E[c|0]=0;Za(d+3120|0,c+1|0);break c}E[d+3120|0]=0}c=d+4672|0;cf(c,d+5704|0);c=Va(c);if(!((c|0)>1024|H[(d+c|0)+4671|0]==47)){c=d+4672|0;c=Va(c)+c|0;E[c|0]=47;E[c+1|0]=0}c=Va(e);if(fb(e,d+4672|0,c)){Ua(2889);break a}c=rb(d+2080|0,c+(d+4672|0)|0,50);E[c+50|0]=0;h=jb(c,47);if(!h){Ua(21390);break a}E[h+1|0]=0;e=Gb(Za(d+1040|0,e),c);h=Va(e);c=Gb(Za(d,d+3120|0),c);j=Va(c);i=d+3632|0;Dg(d+4672|0,a,i,d+5704|0);if(!fb(e,i,h)){break b}if(!fb(c,d+3632|0,j)){break b}Ua(2840);break a}G[b>>2]=-1;d:{while(1){f=M(g,24)+202496|0;if(!G[f>>2]){e=g;break d}e=g+1|0;f=M(e,24)+202496|0;if(!G[f>>2]){break d}e=g+2|0;f=M(e,24)+202496|0;if(!G[f>>2]){break d}e=g+3|0;f=M(e,24)+202496|0;if(!G[f>>2]){break d}e=g+4|0;f=M(e,24)+202496|0;if(!G[f>>2]){break d}g=g+5|0;if((g|0)!=1e4){continue}break}f=103;break a}G[b>>2]=e;G[d+5708>>2]=6433655;b=ac(a,13287);if(b){Hb(b);f=105;break a}a=ac(a,d+5708|0);if(!a){f=105;break a}G[f>>2]=a;f=0;a=M(e,24);G[a+202512>>2]=0;a=a+202504|0;G[a>>2]=0;G[a+4>>2]=0}Fa=d+5712|0;return f|0}function wd(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;if(G[f>>2]<=0){h=G[a>>2];g=G[a+4>>2];if((h|0)!=G[g+76>>2]){mb(a,h+1|0,0,f);g=G[a+4>>2]}j=G[g+72>>2];if((j|0)<0){Hc(a,Bu(G[g+56>>2],G[g+60>>2],2880,0),0,f);g=G[a+4>>2];j=G[g+72>>2]}k=G[((j<<2)+g|0)+1256>>2];h=G[g+56>>2]+Au(k,0,-2880,0)|0;i=h+(G[g+1252>>2]+M(j,2880)|0)|0;g=2880-h|0;if((c|0)>=2){m=1;while(1){h=i;l=(b|0)>(g|0);i=l?g:b;n=bb(h,e,i);h=e+i|0;a:{if(l){G[(G[a+4>>2]+(j<<2)|0)+1416>>2]=1;k=k+1|0;Hc(a,k,1,f);l=G[a+4>>2];j=G[l+72>>2];i=b-i|0;g=i+d|0;i=bb(G[l+1252>>2]+M(j,2880)|0,h,i)+g|0;g=2880-g|0;e=b+e|0;break a}e=d+i|0;g=g-e|0;i=e+n|0;e=h}if((g|0)<=0){G[(G[a+4>>2]+(j<<2)|0)+1416>>2]=1;k=((2880-g>>>0)/2880|0)+k|0;Hc(a,k,1,f);h=G[a+4>>2];j=G[h+72>>2];i=G[h+1252>>2]+M(j,2880)|0;h=(0-g>>>0)%2880|0;i=i+h|0;g=2880-h|0}m=m+1|0;if((m|0)!=(c|0)){continue}break}}h=g;g=(b|0)>(g|0);h=g?h:b;bb(i,e,h);if(g){G[(G[a+4>>2]+(j<<2)|0)+1416>>2]=1;Hc(a,k+1|0,1,f);g=G[a+4>>2];j=G[g+72>>2];bb(G[g+1252>>2]+M(j,2880)|0,e+h|0,b-h|0)}a=G[a+4>>2];G[(a+(j<<2)|0)+1416>>2]=1;e=G[a+60>>2];d=M(c-1|0,d);b=M(b,c);h=b;c=d+b|0;b=(d>>31)+(b>>31)|0;b=c>>>0>>0?b+1|0:b;d=c;c=c+G[a+56>>2]|0;b=b+e|0;G[a+56>>2]=c;G[a+60>>2]=c>>>0>>0?b+1|0:b}}function Tt(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0;if(!(G[a+92>>2]|(!a|G[a+16>>2]!=31153))){if((c|0)<0){Vd(a,-3,4722);return 0}g=b;b=0;a:{b:{if(!c){break b}if(!G[a+28>>2]){if((Aq(a)|0)==-1){break b}}c:{if(!G[a+88>>2]){break c}G[a+88>>2]=0;f=G[a+80>>2];h=G[a+84>>2];if(G[a+104>>2]){if((Jf(a,0)|0)==-1){break b}}if(!(f|h)){break c}while(1){d=G[a+28>>2];d=(h|0)<=0&d>>>0>f>>>0|(h|0)<0?f:d;if(!(b&1)){cb(G[a+36>>2],0,d)}G[a+104>>2]=d;G[a+100>>2]=G[a+36>>2];b=G[a+12>>2];i=G[a+8>>2];j=i+d|0;G[a+8>>2]=j;G[a+12>>2]=i>>>0>j>>>0?b+1|0:b;if((Jf(a,0)|0)==-1){break b}b=1;h=h-(d>>>0>f>>>0)|0;f=f-d|0;if(h|f){continue}break}}if(J[a+28>>2]>c>>>0){b=c;while(1){f=G[a+104>>2];d:{if(f){e=G[a+36>>2];d=G[a+100>>2];break d}e=G[a+36>>2];G[a+100>>2]=e;d=e}d=d+f|0;e=G[a+28>>2]+(e-d|0)|0;e=b>>>0>e>>>0?e:b;bb(d,g,e);G[a+104>>2]=e+G[a+104>>2];d=G[a+12>>2];f=e+G[a+8>>2]|0;d=f>>>0>>0?d+1|0:d;G[a+8>>2]=f;G[a+12>>2]=d;b=b-e|0;if(!b){break a}g=e+g|0;e=0;if((Jf(a,0)|0)!=-1){continue}break}break b}if(G[a+104>>2]){if((Jf(a,0)|0)==-1){break b}}G[a+104>>2]=c;G[a+100>>2]=g;b=G[a+12>>2];g=c+G[a+8>>2]|0;b=g>>>0>>0?b+1|0:b;G[a+8>>2]=g;G[a+12>>2]=b;e=(Jf(a,0)|0)==-1?0:c}c=e}g=c}return g|0}function Hj(a,b,c,d,e,f,g,h){var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;i=L[g>>3];a:{if((h|0)<=0){j=i;break a}m=h&3;b:{if(h-1>>>0<3){j=i;break b}o=h&-4;j=i;while(1){l=k<<3;n=L[(l|24)+g>>3];q=L[(l|16)+g>>3];r=L[(l|8)+g>>3];s=L[g+l>>3];j=j>s?s:j;j=j>r?r:j;j=j>q?q:j;j=j>n?n:j;i=i>3];j=j>n?n:j;i=i>2];k=b+M(c,168)|0;l=k-168|0;L[k+8>>3]=L[l+8>>3];L[k+16>>3]=L[l+16>>3];k=G[a+48>>2];break c}b=G[a+8>>2];k=b+M(c,168)|0;m=G[a+44>>2];j=j+1;d:{if(O(j)<2147483648){l=~~j;break d}l=-2147483648}L[k+8>>3]=((l|0)<(m|0)?m:l)|0;m=k;k=G[a+48>>2];i=i+1;e:{if(O(i)<2147483648){l=~~i;break e}l=-2147483648}l=l-1|0;L[m+16>>3]=((k|0)<(l|0)?k:l)|0}p=M(c,168);u=p+b|0,v=lb(k+1|0,4),G[u+24>>2]=v;Pf(a,c,d,e);if((h|0)>0){b=h-1|0;k=0;while(1){c=G[(p+G[a+8>>2]|0)+24>>2];l=G[a+48>>2];m=G[a+40>>2];o=k<<3;i=L[o+g>>3];b=b<<3;j=L[b+g>>3];f:{if(i>j){Rm(a,c,m,l,d,e,L[b+f>>3],j,L[f+o>>3],i);break f}Rm(a,c,m,l,d,e,L[f+o>>3],i,L[b+f>>3],j)}b=k;k=k+1|0;if((k|0)!=(h|0)){continue}break}}}function mi(a,b){var c=0,d=0,e=0;c=Fa-112|0;Fa=c;a:{b:{if(G[309728]>0){while(1){if(!gc(G[309730]+M(d,124)|0,a,80)){break b}d=d+1|0;if((d|0)>2]=H[67620]|H[67621]<<8|(H[67622]<<16|H[67623]<<24);G[c+4>>2]=b;b=H[67632]|H[67633]<<8|(H[67634]<<16|H[67635]<<24);G[c+8>>2]=H[67628]|H[67629]<<8|(H[67630]<<16|H[67631]<<24);G[c+12>>2]=b;b=H[67638]|H[67639]<<8|(H[67640]<<16|H[67641]<<24);d=H[67634]|H[67635]<<8|(H[67636]<<16|H[67637]<<24);F[c+14>>1]=d;F[c+16>>1]=d>>>16;F[c+18>>1]=b;F[c+20>>1]=b>>>16;Ua(qb(c,a,80));a=-1;break a}e=G[(G[309730]+M(d,124)|0)+84>>2]-258|0;c:{if(e>>>0>=5){G[309737]=431;e=H[67616]|H[67617]<<8|(H[67618]<<16|H[67619]<<24);G[c+16>>2]=H[67612]|H[67613]<<8|(H[67614]<<16|H[67615]<<24);G[c+20>>2]=e;e=H[67600]|H[67601]<<8|(H[67602]<<16|H[67603]<<24);G[c>>2]=H[67596]|H[67597]<<8|(H[67598]<<16|H[67599]<<24);G[c+4>>2]=e;e=H[67608]|H[67609]<<8|(H[67610]<<16|H[67611]<<24);G[c+8>>2]=H[67604]|H[67605]<<8|(H[67606]<<16|H[67607]<<24);G[c+12>>2]=e;Ua(qb(c,a,80));a=-1;break c}a=G[(e<<2)+141344>>2]}G[b>>2]=d}Fa=c+112|0;return a}function yi(a,b,c){var d=0,e=0,f=0,g=0;d=Fa-96|0;Fa=d;e=G[c>>2];if((e|0)<=0){G[48624]=0;G[b>>2]=0;G[b+4>>2]=0;f=b,g=Fn(a,d+92|0),G[f>>2]=g;G[b+4>>2]=Ia;if((H[G[d+92>>2]]|32)!=32){G[c>>2]=407}if(G[48624]==68){F[d+56>>1]=H[66897]|H[66898]<<8;b=H[66893]|H[66894]<<8|(H[66895]<<16|H[66896]<<24);G[d+48>>2]=H[66889]|H[66890]<<8|(H[66891]<<16|H[66892]<<24);G[d+52>>2]=b;b=H[66885]|H[66886]<<8|(H[66887]<<16|H[66888]<<24);G[d+40>>2]=H[66881]|H[66882]<<8|(H[66883]<<16|H[66884]<<24);G[d+44>>2]=b;b=H[66877]|H[66878]<<8|(H[66879]<<16|H[66880]<<24);G[d+32>>2]=H[66873]|H[66874]<<8|(H[66875]<<16|H[66876]<<24);G[d+36>>2]=b;b=H[66869]|H[66870]<<8|(H[66871]<<16|H[66872]<<24);G[d+24>>2]=H[66865]|H[66866]<<8|(H[66867]<<16|H[66868]<<24);G[d+28>>2]=b;b=H[66861]|H[66862]<<8|(H[66863]<<16|H[66864]<<24);G[d+16>>2]=H[66857]|H[66858]<<8|(H[66859]<<16|H[66860]<<24);G[d+20>>2]=b;b=H[66853]|H[66854]<<8|(H[66855]<<16|H[66856]<<24);G[d+8>>2]=H[66849]|H[66850]<<8|(H[66851]<<16|H[66852]<<24);G[d+12>>2]=b;b=H[66845]|H[66846]<<8|(H[66847]<<16|H[66848]<<24);G[d>>2]=H[66841]|H[66842]<<8|(H[66843]<<16|H[66844]<<24);G[d+4>>2]=b;tb(5,qb(d,a,23));G[c>>2]=412;G[48624]=0}e=G[c>>2]}Fa=d+96|0;return e}function as(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;h=G[c+4>>2];k=h>>31;a:{if(((k^h)-k|0)==105){g=L[c+120>>3];f=L[c+112>>3];break a}G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=83;E[c+1|0]=73;E[c+2|0]=78;E[c+3|0]=0;G[c+4>>2]=(h|0)<0?-105:105;f=L[c+24>>3];if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=57.29577951308232}G[c+1892>>2]=89;G[c+1888>>2]=90;f=1/f;L[c+112>>3]=f;g=L[c+40>>3];i=g*g;g=L[c+48>>3];g=i+g*g;L[c+120>>3]=g;L[c+136>>3]=g+-1;L[c+128>>3]=g+1}i=f*a;b=f*b;a=i*i+b*b;b:{c:{if(g==0){if(a!=0){b=Ac(i,-b)}else{b=0}L[d>>3]=b;if(a<.5){l=e,m=Yg(V(a)),L[l>>3]=m;break c}h=2;if(!(a<=1)){break b}l=e,m=Bc(V(1-a)),L[l>>3]=m;break c}f=i*L[c+40>>3]+b*L[c+48>>3];d:{if(a<1e-10){L[e>>3]=V(a/(f+1))*-57.29577951308232+90;a=a*.5;break d}h=2;g=f-g;a=a-f-f+L[c+136>>3];f=L[c+128>>3];a=g*g-a*f;if(a<0){break b}j=V(a);a=(j-g)/f;g=(-g-j)/f;f=a>g?a:g;e:{if(!(f>1)){break e}j=f+-1;f=1;if(j<1e-13){break e}f=a-1e-13?-1:f:f;if(a>1|a<-1){break b}l=e,m=Bc(a),L[l>>3]=m;a=1-a}f=i-L[c+40>>3]*a;a=L[c+48>>3]*a-b;if(!(a!=0|f!=0)){G[d>>2]=0;G[d+4>>2]=0;break c}l=d,m=Ac(f,a),L[l>>3]=m}h=0}return h|0}function of(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0;g=Fa-16|0;Fa=g;f=-1;d=G[47589];if(!(G[321431]?0:d)){G[47589]=1;G[321432]=0;G[321431]=0;d=1}a:{if((a|0)<=(d|0)){break a}e=G[(d<<2)+b>>2];if(!e){break a}if(H[e|0]!=45){if(H[c|0]!=45){break a}G[321433]=e;f=1;G[47589]=d+1;break a}h=H[e+1|0];if(!h){break a}if(!(H[e+2|0]|(h|0)!=45)){G[47589]=d+1;break a}f=g+12|0;d=G[321432];if(!d){G[321432]=1;d=1}h=om(f,d+e|0);if((h|0)<0){G[g+12>>2]=65533;h=1}e=G[47589];d=G[(e<<2)+b>>2];f=G[321432];j=f+h|0;G[321432]=j;if(!H[d+j|0]){G[47589]=e+1;G[321432]=0}b:{switch(H[c|0]-43|0){case 0:case 2:c=c+1|0;break;default:break b}}j=d+f|0;d=0;G[g+8>>2]=0;while(1){c:{i=om(g+8|0,c+d|0);d=((i|0)>1?i:1)+d|0;e=G[g+12>>2];f=G[g+8>>2];if(!i){break c}if((e|0)!=(f|0)){continue}}break}if(!((e|0)==(f|0)&(e|0)!=58)){G[321434]=e;f=63;if(!G[47590]|H[c|0]==58){break a}nm(G[b>>2],67246,j,h);break a}d=c+d|0;if(H[d|0]!=58){break a}G[321433]=0;e=G[47589];i=G[321432];d:{if(!(i|H[d+1|0]!=58)){d=e;break d}d=e+1|0;G[47589]=d;G[321433]=i+G[(e<<2)+b>>2];G[321432]=0}if((a|0)>=(d|0)){break a}G[321434]=f;f=58;if(H[c|0]==58){break a}f=63;if(!G[47590]){break a}nm(G[b>>2],67021,j,h)}Fa=g+16|0;return f}function ue(a,b,c){var d=0,e=0,f=0,g=0;d=Fa-96|0;Fa=d;e=G[c>>2];if((e|0)<=0){G[48624]=0;G[b>>2]=0;f=b,g=nc(a,d+92|0,10),G[f>>2]=g;if((H[G[d+92>>2]]|32)!=32){G[c>>2]=407}if(G[48624]==68){b=H[67017]|H[67018]<<8|(H[67019]<<16|H[67020]<<24);e=H[67013]|H[67014]<<8|(H[67015]<<16|H[67016]<<24);F[d+46>>1]=e;F[d+48>>1]=e>>>16;F[d+50>>1]=b;F[d+52>>1]=b>>>16;b=H[67011]|H[67012]<<8|(H[67013]<<16|H[67014]<<24);G[d+40>>2]=H[67007]|H[67008]<<8|(H[67009]<<16|H[67010]<<24);G[d+44>>2]=b;b=H[67003]|H[67004]<<8|(H[67005]<<16|H[67006]<<24);G[d+32>>2]=H[66999]|H[67e3]<<8|(H[67001]<<16|H[67002]<<24);G[d+36>>2]=b;b=H[66995]|H[66996]<<8|(H[66997]<<16|H[66998]<<24);G[d+24>>2]=H[66991]|H[66992]<<8|(H[66993]<<16|H[66994]<<24);G[d+28>>2]=b;b=H[66987]|H[66988]<<8|(H[66989]<<16|H[66990]<<24);G[d+16>>2]=H[66983]|H[66984]<<8|(H[66985]<<16|H[66986]<<24);G[d+20>>2]=b;b=H[66979]|H[66980]<<8|(H[66981]<<16|H[66982]<<24);G[d+8>>2]=H[66975]|H[66976]<<8|(H[66977]<<16|H[66978]<<24);G[d+12>>2]=b;b=H[66971]|H[66972]<<8|(H[66973]<<16|H[66974]<<24);G[d>>2]=H[66967]|H[66968]<<8|(H[66969]<<16|H[66970]<<24);G[d+4>>2]=b;tb(5,qb(d,a,25));G[c>>2]=412;G[48624]=0}e=G[c>>2]}Fa=d+96|0;return e}function ag(a,b,c,d,e,f,g){var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;m=Fa-80|0;Fa=m;k=G[g>>2];if((k|0)<=0){Qd(a,m+76|0,g);nk(a,9,m,g);i=G[m+76>>2];if((i|0)<=0){c=1}else{r=i&1;a:{if((i|0)==1){k=0;l=1;break a}s=i&-2;k=0;l=1;while(1){i=G[(k<<2)+c>>2]-1|0;n=Au(l,o,i,i>>31);i=h;n=n+h|0;h=j+Ia|0;h=i>>>0>n>>>0?h+1|0:h;i=n;j=(k<<3)+m|0;l=Au(G[j>>2],G[j+4>>2],l,o);o=Ia;n=k|1;j=G[(n<<2)+c>>2]-1|0;p=Au(l,o,j,j>>31);i=i+p|0;j=Ia+h|0;j=i>>>0

>>0?j+1|0:j;h=i;k=k+2|0;i=(n<<3)+m|0;l=Au(G[i>>2],G[i+4>>2],l,o);o=Ia;q=q+2|0;if((s|0)!=(q|0)){continue}break}}if(r){c=G[(k<<2)+c>>2]-1|0;i=Au(l,o,c,c>>31)+h|0;c=j+Ia|0;c=h>>>0>i>>>0?c+1|0:c}else{c=j;i=h}h=c;c=i+1|0;h=c?h:h+1|0}b:{c:{switch(b-11|0){case 0:Sk(a,c,h,d,e,f,g);break b;case 1:Yo(a,c,h,d,e,f,g);break b;case 9:Vo(a,c,h,d,e,f,g);break b;case 10:Rk(a,c,h,d,e,f,g);break b;case 19:Po(a,c,h,d,e,f,g);break b;case 20:Fk(a,c,h,d,e,f,g);break b;case 29:To(a,c,h,d,e,f,g);break b;case 30:Mo(a,c,h,d,e,f,g);break b;case 69:Ro(a,c,h,d,e,f,g);break b;case 70:Gk(a,c,h,d,e,f,g);break b;case 31:Ho(a,c,h,d,e,f,g);break b;case 71:_o(a,c,h,d,e,f,g);break b;default:break c}}G[g>>2]=410}k=G[g>>2]}Fa=m+80|0;return k}function ah(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;a:{if(!a){break a}b:{switch(H[a|0]-68|0){case 0:case 1:case 32:case 33:break a;default:break b}}b=Va(a);while(1){h=b;b=b-1|0;if(H[b+a|0]==32){continue}break}i=1;if((h|0)<=0){return 0}while(1){g=a+e|0;c=H[g|0];d=c;if((d|0)!=10){c:{if(!(f|(d|0)!=32)){f=0;break c}d:{e:{if((c-58&255)>>>0<=245){b=0;f:{switch(d-43|0){case 0:case 2:g:{switch(H[g+1|0]-43|0){case 0:case 2:break a;default:break g}}if(!e){break d}h:{c=H[g-1|0];switch(c-58|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:break a;case 0:case 10:case 11:case 42:case 43:break d;default:break h}}if((c|0)==32){break d}break a;case 3:case 15:case 25:case 26:case 57:case 58:break f;default:break a}}if((c-47&255)>>>0>10){break e}}f=f+1|0;break d}j=((d|0)==58)+j|0}if((d|0)!=46&d-100>>>0>=2){break c}i=2}e=e+1|0;if((h|0)!=(e|0)){continue}}break}b=0;if((f|0)<=0){break a}b=j?3:i}return b}function oj(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;i=Fa-16|0;Fa=i;G[321386]=0;while(1){c=a;a=a+1|0;if(H[c|0]==32){continue}break}d=i+12|0;e=vb(c,d);f=G[d>>2];if(jb(c,46)){G[321386]=46}b=E[f|0];g=b&255;a:{if(!g){break a}b:{c:{d:{switch(g-32|0){case 1:case 3:case 4:case 5:case 6:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:break a;case 2:case 7:break b;case 0:case 26:break c;default:break d}}switch(g-100|0){case 14:break b;case 0:case 4:case 9:break c;default:break a}}e:{if((f-c|0)>4){break e}a=E[f+1|0];if(a-48>>>0>=10&((a|0)!=32|E[f+2|0]-48>>>0>9)){break e}G[321386]=b;a=f+1|0;G[d>>2]=a;c=H[c|0]==45;e=c?-e:e;h=vb(a,d);f:{if((b|0)==109){j=h;break f}b=G[d>>2];a=H[b|0];g:{if(!((a|0)==32|(a|0)==109)&(a|0)!=58|(b-f|0)>3){break g}a=E[b+1|0];if(a-48>>>0>=10&((a|0)!=32|E[b+2|0]-48>>>0>9)){break g}a=b+1|0;G[d>>2]=a;j=vb(a,d)}k=e;e=h}h=k+e/60+j/3600;e=c?-h:h;break a}h:{switch(g-34|0){case 1:case 2:case 3:case 4:break a;case 0:case 5:break b;default:break h}}if((g|0)!=100){break a}}if(H[f+1|0]){break a}G[321386]=b;G[d>>2]=f+1}Fa=i+16|0;return e}function Rd(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0;if(G[f>>2]<=0){h=G[a>>2];g=G[a+4>>2];if((h|0)!=G[g+76>>2]){mb(a,h+1|0,0,f);g=G[a+4>>2]}h=G[g+72>>2];if((h|0)<0){Hc(a,Bu(G[g+56>>2],G[g+60>>2],2880,0),0,f);g=G[a+4>>2];h=G[g+72>>2]}j=G[((h<<2)+g|0)+1256>>2];i=G[g+56>>2]+Au(j,0,-2880,0)|0;h=i+(G[g+1252>>2]+M(h,2880)|0)|0;g=2880-i|0;if((c|0)>=2){k=1;while(1){l=(b|0)>(g|0);i=l?g:b;m=bb(e,h,i);e=m+i|0;a:{if(l){j=j+1|0;Hc(a,j,0,f);h=e;e=G[a+4>>2];e=G[e+1252>>2]+M(G[e+72>>2],2880)|0;g=b-i|0;bb(h,e,g);g=d+g|0;h=g+e|0;e=b+m|0;g=2880-g|0;break a}i=d+i|0;g=g-i|0;h=h+i|0}if(g-2881>>>0<=4294964415){b:{if((g|0)<=0){j=((2880-g>>>0)/2880|0)+j|0;h=(0-g>>>0)%2880|0;break b}j=j-((g-1>>>0)/2880|0)|0;h=2880-((g>>>0)%2880|0)|0}Hc(a,j,0,f);g=2880-h|0;i=G[a+4>>2];h=h+(G[i+1252>>2]+M(G[i+72>>2],2880)|0)|0}k=k+1|0;if((k|0)!=(c|0)){continue}break}}i=e;e=g;g=(b|0)>(g|0);e=g?e:b;h=bb(i,h,e);if(g){Hc(a,j+1|0,0,f);g=G[a+4>>2];bb(e+h|0,G[g+1252>>2]+M(G[g+72>>2],2880)|0,b-e|0)}a=G[a+4>>2];e=G[a+60>>2];d=M(c-1|0,d);b=M(b,c);g=b;c=d+g|0;b=(d>>31)+(g>>31)|0;b=c>>>0>>0?b+1|0:b;d=c;c=c+G[a+56>>2]|0;b=b+e|0;G[a+56>>2]=c;G[a+60>>2]=c>>>0>>0?b+1|0:b}}function qs(a,b,c,d,e,f,g,h,i,j,k,l){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;l=l|0;var m=0,n=0,o=0,p=0,q=0;o=G[a+8>>2];n=(G[a>>2]+M(c,3)|0)-2|0;h=L[(o+M(n,168)|0)+8>>3];a:{if(d){if(g>3];if(!(g>=h)|i>2];if(O(g)<2147483648){n=~~g}else{n=-2147483648}m=G[m+(n<<2)>>2];b:{if(!m){break b}while(1){if(!(+G[m+4>>2]<=f)){break b}e=e+1|0;m=G[m>>2];if(m){continue}break}}if((e&1)!=(d|0)|(l|0)<=0){break a}q=n<<2;n=0;while(1){c:{m=M(c+n|0,168)+o|0;h=L[m+8>>3];if(h>g){break c}i=L[m+16>>3];if(!(g>=h)|i>2]+q>>2];d:{if(!m){break d}while(1){if(!(+G[m+4>>2]<=f)){break d}e=e+1|0;m=G[m>>2];if(m){continue}break}}if((e&1)!=(d|0)){break c}p=1;b=b+n|0;if(!b){break a}G[a+12>>2]=b;return 1}n=n+1|0;if((n|0)!=(l|0)){continue}break}break a}e:{if(g>3];if(!(g>=h)|(!(i>=g)|g>i)){break e}b=G[(M(n,168)+o|0)+24>>2];if(O(g)<2147483648){a=~~g}else{a=-2147483648}m=G[b+(a<<2)>>2];if(!m){break e}e=0;while(1){if(+G[m+4>>2]<=f){e=e+1|0;m=G[m>>2];if(m){continue}}break}if(e&1){break a}}p=1}return p|0} -function wb(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0;i=Fa-96|0;Fa=i;d=G[c>>2];a:{if((d|0)>0){break a}e=G[a>>2];d=G[a+4>>2];if((e|0)!=G[d+76>>2]){mb(a,e+1|0,0,c);d=G[a+4>>2]}b:{e=G[d+128>>2];f=G[d+104>>2];if((e-f|0)!=80|G[d+132>>2]!=(G[d+108>>2]+(e>>>0>>0)|0)){break b}if((Bf(a,1,0,c)|0)<=0){break b}d=G[c>>2];break a}d=0;e=rb(i,b,80);E[e+80|0]=0;f=Va(e);c:{if(f){if((f|0)!=1){h=f&-2;b=0;while(1){g=d+e|0;if((H[g|0]-127&255)>>>0<=160){E[g|0]=32}g=e+(d|1)|0;if((H[g|0]-127&255)>>>0<=160){E[g|0]=32}d=d+2|0;b=b+2|0;if((h|0)!=(b|0)){continue}break}}d:{if(!(f&1)){break d}b=d+e|0;if((H[b|0]-127&255)>>>0>160){break d}E[b|0]=32}if(f>>>0>79){break c}}cb(e+f|0,32,80-f|0)}d=qc(e,36178);e:{f:{if(!gc(66587,e,8)){b=8;break f}b=8;if(!gc(66546,e,8)){break f}if(!gc(68289,e,8)){break f}if(!gc(35367,e,8)){break f}b=(d|0)==80?8:d;if(!b){break e}}d=0;while(1){h=d+e|0;f=E[h|0];E[h|0]=f-97>>>0<26?f&95:f;d=d+1|0;if((d|0)!=(b|0)){continue}break}}ve(e,c);b=G[a+4>>2];Jb(a,G[b+104>>2],G[b+108>>2],1,c);Wb(a,80,0,e,c);d=G[c>>2];if((d|0)>0){break a}b=G[a+4>>2];a=G[b+108>>2];c=G[b+104>>2]+80|0;a=c>>>0<80?a+1|0:a;G[b+104>>2]=c;G[b+108>>2]=a}Fa=i+96|0;return d}function ip(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;f=G[a+124>>2];d=f;c=f>>>2|0;f=G[a+120>>2];j=f>>>0>2]?d:c;d=G[a+108>>2];c=(d-G[a+44>>2]|0)+262|0;n=c>>>0>d>>>0?0:c;c=G[a+144>>2];i=G[a+116>>2];o=c>>>0>>0?c:i;k=G[a+56>>2];h=d+k|0;p=h+258|0;d=f+h|0;l=H[d|0];m=H[d-1|0];q=G[a+52>>2];r=G[a+64>>2];while(1){a:{e=b+k|0;d=f+e|0;b:{if(H[d|0]!=(l|0)|H[d-1|0]!=(m|0)|H[e|0]!=H[h|0]){break b}d=2;if(H[e+1|0]!=H[h+1|0]){break b}c:{d:{e:{f:{g:{h:{i:{while(1){c=d+h|0;if(H[c+1|0]!=H[e+3|0]){break d}if(H[c+2|0]!=H[e+4|0]){break e}if(H[c+3|0]!=H[e+5|0]){break f}if(H[c+4|0]!=H[e+6|0]){break g}if(H[c+5|0]!=H[e+7|0]){break h}if(H[c+6|0]!=H[e+8|0]){break i}if(H[c+7|0]==H[e+9|0]){c=d+8|0;g=c+h|0;if(H[g|0]!=H[e+10|0]){break c}e=e+8|0;s=d>>>0<250;d=c;if(s){continue}break c}break}g=c+7|0;break c}g=c+6|0;break c}g=c+5|0;break c}g=c+4|0;break c}g=c+3|0;break c}g=c+2|0;break c}g=c+1|0}c=g-p|0;d=c+258|0;if((d|0)<=(f|0)){break b}G[a+112>>2]=b;if((d|0)>=(o|0)){f=d;break a}l=H[d+h|0];m=H[(c+h|0)+257|0];f=d}b=I[((b&q)<<1)+r>>1];if(n>>>0>=b>>>0){break a}j=j-1|0;if(j){continue}}break}return f>>>0>>0?f:i}function Wn(a,b,c){var d=0,e=0;d=Fa-208|0;Fa=d;a:{if(G[c>>2]>0){break a}if(!H[a|0]){G[c>>2]=204;break a}Yn(a,d+207|0,d+12|0,b,d+112|0,d,c);b:{c:{e=H[d+207|0];d:{if(!((e|0)!=88&(e|0)!=67)){G[c>>2]=404;break d}if(G[c>>2]<=0){break c}}G[b>>2]=0;b=H[67441]|H[67442]<<8|(H[67443]<<16|H[67444]<<24);G[d+56>>2]=H[67437]|H[67438]<<8|(H[67439]<<16|H[67440]<<24);G[d+60>>2]=b;b=H[67433]|H[67434]<<8|(H[67435]<<16|H[67436]<<24);G[d+48>>2]=H[67429]|H[67430]<<8|(H[67431]<<16|H[67432]<<24);G[d+52>>2]=b;b=H[67425]|H[67426]<<8|(H[67427]<<16|H[67428]<<24);G[d+40>>2]=H[67421]|H[67422]<<8|(H[67423]<<16|H[67424]<<24);G[d+44>>2]=b;b=H[67417]|H[67418]<<8|(H[67419]<<16|H[67420]<<24);G[d+32>>2]=H[67413]|H[67414]<<8|(H[67415]<<16|H[67416]<<24);G[d+36>>2]=b;b=H[67409]|H[67410]<<8|(H[67411]<<16|H[67412]<<24);G[d+24>>2]=H[67405]|H[67406]<<8|(H[67407]<<16|H[67408]<<24);G[d+28>>2]=b;b=H[67401]|H[67402]<<8|(H[67403]<<16|H[67404]<<24);G[d+16>>2]=H[67397]|H[67398]<<8|(H[67399]<<16|H[67400]<<24);G[d+20>>2]=b;tb(5,qb(d+16|0,a,30));break b}e:{f:{switch(e-70|0){case 3:a=G[d+12>>2]!=0;break e;case 0:break f;default:break b}}a=L[d>>3]!=0}G[b>>2]=a}}Fa=d+208|0}function gr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;h=G[c+4>>2];g=L[c+40>>3];a:{if(g==0){b:{if((h|0)==301){f=L[c+112>>3];break b}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=83;E[c+1|0]=70;E[c+2|0]=76;E[c+3|0]=0;E[c+4|0]=45;E[c+5|0]=1;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];c:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=1;g=1;break c}f=f*3.141592653589793/180;g=1/f}G[c+1892>>2]=99;G[c+1888>>2]=100;L[c+112>>3]=f;L[c+120>>3]=g}i=d,j=f*a*Mb(b),L[i>>3]=j;a=L[c+112>>3]*b;break a}d:{if((h|0)==601){f=L[c+128>>3];break d}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=66;E[c+1|0]=79;E[c+2|0]=78;E[c+3|0]=0;E[c+4|0]=89;E[c+5|0]=2;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];e:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;G[c+120>>2]=0;G[c+124>>2]=1072693248;f=Mb(g)*57.29577951308232/Kb(L[c+40>>3])+L[c+40>>3];break e}L[c+120>>3]=f*3.141592653589793/180;f=f*(Mb(g)/Kb(L[c+40>>3])+L[c+40>>3]*3.141592653589793/180)}G[c+1892>>2]=135;G[c+1888>>2]=136;L[c+128>>3]=f}f=f-b*L[c+120>>3];a=L[c+24>>3]*a*Mb(b)/f;i=d,j=f*Kb(a),L[i>>3]=j;a=L[c+128>>3]-f*Mb(a)}L[e>>3]=a;return 0}function cr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;if(G[c+4>>2]!=801){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=72;E[c+1|0]=80;E[c+2|0]=88;E[c+3|0]=0;E[c+4|0]=33;E[c+5|0]=3;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;h=L[c+48>>3];a:{if(O(h)<2147483648){i=~~h;break a}i=-2147483648}G[c+272>>2]=(i|0)%2;f=L[c+24>>3];b:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;g=1;f=1;break b}g=57.29577951308232/f;f=f*3.141592653589793/180}L[c+112>>3]=f;G[c+1892>>2]=139;G[c+1888>>2]=140;L[c+120>>3]=g;j=h+-1;L[c+128>>3]=j/h;L[c+144>>3]=(h+1)*.5;g=L[c+40>>3];L[c+168>>3]=g/360;k=180/g;L[c+160>>3]=k;L[c+152>>3]=j*90/g;h=h*90/g;L[c+136>>3]=h;L[c+184>>3]=f*k;L[c+176>>3]=f*h}f=Kb(b);h=O(f);c:{d:{if(h<=L[c+128>>3]){L[d>>3]=L[c+112>>3]*a;a=f*L[c+176>>3];break d}g=L[c+168>>3];i=d;k=L[c+112>>3];j=a;f=L[c+40>>3];e:{if(O(f)<2147483648){d=~~f;break e}d=-2147483648}d=(d|0)%2|0;f:{if(b<=0?G[c+272>>2]?d:1-d|0:d){g=S(g*a+0);a=g+g+f;break f}g=S(g*a);a=g+g+f+1}a=a*L[c+160>>3]+-180;f=V((1-h)*L[c+48>>3]);L[i>>3]=k*((j-a)*f+a);a=L[c+184>>3]*(L[c+144>>3]-f);L[e>>3]=a;if(!(b<0)){break c}a=-a}L[e>>3]=a}return 0}function js(a,b,c,d,e,f,g,h,i,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;q=Fa-16|0;Fa=q;G[q+12>>2]=j;a:{m=G[a+8>>2];r=(G[a>>2]+M(c,3)|0)-2|0;s=M(r,168);n=m+s|0;k=G[n+32>>2];if(k){break a}l=lb(1e3,8);G[n+32>>2]=l;j=0;G[n+28>>2]=0;k=1e3;while(1){if((j|0)>=(k|0)){k=k+1e3|0;j=ub(l,k<<3);m=G[a+8>>2];G[(s+m|0)+32>>2]=j}o=G[q+12>>2]+7&-8;G[q+12>>2]=o+8;j=m+s|0;l=G[j+32>>2];n=G[j+28>>2];p=L[o>>3];L[l+(n<<3)>>3]=p;b:{if(!(O(p+-9007199254740992)<=1e-15)){break b}o=n-1|0;if(!(O(L[(o<<3)+l>>3]+-9007199254740992)<=1e-15)){break b}G[j+28>>2]=o;j=M(r,168);k=j+G[a+8>>2]|0;k=ub(G[k+32>>2],G[k+28>>2]<<3);m=G[a+8>>2];G[(j+m|0)+32>>2]=k;break a}o=j;j=n+1|0;G[o+28>>2]=j;continue}}j=G[(m+s|0)+28>>2];c:{if((j|0)==2){l=re(a,b,c,d,e,f,g,h,i,L[k>>3],L[k+8>>3]);break c}p=L[((j<<3)+k|0)-8>>3];t=L[k>>3];if(d){l=0;if(!re(a,0,r,d,e,f,g,h,i,t,p)){break c}m=(j|0)>0?j:0;j=0;while(1){if((j|0)==(m|0)){l=0;break c}l=1;o=b+j|0;n=c+j|0;p=L[(j<<3)+k>>3];j=j+1|0;if(!re(a,o,n,d,e,f,g,h,i,p,L[(j<<3)+k>>3])){continue}break}break c}l=!re(a,0,r,1,e,f,g,h,i,t,p)}Fa=q+16|0;return l|0}function ic(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;f=G[e>>2];if((f|0)<=0){f=G[a>>2];if((f|0)!=G[G[a+4>>2]+76>>2]){mb(a,f+1|0,0,e)}f=G[a+4>>2];a:{if((c|0)>=0&b>>>0>=8640|(c|0)>0){g=G[f+60>>2];k=g;f=G[f+56>>2];m=Bu(f,g,2880,0);c=c+g|0;g=b+f|0;c=g>>>0>>0?c+1|0:c;j=c;c=Bu(g-1|0,c-!g|0,2880,0);while(1){l=G[a+4>>2];i=l+(h<<2)|0;b:{if(!G[i+1416>>2]){break b}i=G[i+1256>>2];if((i|0)<(m|0)|(c|0)<(i|0)){break b}Hg(l,h,e)}h=h+1|0;if((h|0)!=40){continue}break}c=G[a+4>>2];if(G[c+64>>2]!=(f|0)|G[c+68>>2]!=(k|0)){Ja[G[(M(G[c+4>>2],84)+1240576|0)+72>>2]](G[c>>2],f,k)|0;c=G[a+4>>2]}Lj(c,b,d,e);a=G[a+4>>2];G[a+64>>2]=g;G[a+68>>2]=j;break a}g=G[f+72>>2];if((g|0)<0){Hc(a,Bu(G[f+56>>2],G[f+60>>2],2880,0),0,e);f=G[a+4>>2];g=G[f+72>>2]}h=b;if(!b){break a}b=G[f+56>>2]+Au(G[((g<<2)+f|0)+1256>>2],0,-2880,0)|0;g=b;f=2880-b|0;while(1){b=G[a+4>>2];c=(G[b+1252>>2]+M(G[b+72>>2],2880)|0)+g|0;b=(f|0)>(h|0)?h:f;j=bb(d,c,b);c=G[a+4>>2];d=c;f=b+G[c+56>>2]|0;c=G[c+60>>2]+(b>>31)|0;c=b>>>0>f>>>0?c+1|0:c;G[d+56>>2]=f;G[d+60>>2]=c;h=h-b|0;if(!h){break a}g=0;Hc(a,Bu(f,c,2880,0),0,e);d=b+j|0;f=2880;continue}}f=G[e>>2]}return f}function Zf(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0;i=Fa-336|0;Fa=i;G[i+156>>2]=0;g=G[f>>2];if((g|0)<=0){g=i+80|0;zb(34647,b,g,f);E[i+160|0]=0;if((kc(a,g,i+240|0,i+156|0)|0)<=0){mc(i+240|0,i+160|0,0,i+156|0)}E[i|0]=0;fd(i+160|0,i,i+156|0);g=Fa-144|0;Fa=g;a:{if(G[f>>2]>0){break a}b:{c:{if(b){h=G[a>>2];if((h|0)!=G[G[a+4>>2]+76>>2]){mb(a,h+1|0,0,f)}d:{if((b|0)>0){h=G[a+4>>2];if(G[h+936>>2]>=(b|0)){break d}}a=302;break b}a=b-1|0;h=G[h+968>>2];if(!H[i|0]){break c}k=h+M(a,160)|0}G[d>>2]=0;h=jb(i,40);if(h){a=1;while(1){h=h+1|0;G[g+140>>2]=h;j=nc(h,g+140|0,10);h=G[d>>2];if((h|0)<(c|0)){G[(h<<2)+e>>2]=j}if((j|0)<0){Ua(58200);Ua(i);a=263;break b}G[d>>2]=h+1;l=G[g+140>>2];h=jb(l,44);G[g+140>>2]=h;a=M(a,j);if(h){continue}break}if(!jb(l,41)){G[g+16>>2]=i;Ya(g+48|0,81,9451,g+16|0);a=263;break b}if(!b|G[k+80>>2]<=0){break a}b=G[k+88>>2];if((b|0)==(a|0)){break a}G[g+36>>2]=a;G[g+32>>2]=b;a=g+48|0;Ya(a,81,27638,g+32|0);Ua(a);Ua(i);a=263;break b}G[g>>2]=i;Ya(g+48|0,81,9451,g);a=263;break b}G[d>>2]=1;if((c|0)<=0){break a}G[e>>2]=G[(h+M(a,160)|0)+88>>2];break a}G[f>>2]=a}Fa=g+144|0;g=G[f>>2]}Fa=i+336|0;return g}function Ji(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;h=(d|0)>(e|0)?d:e;q=oc(+N(h|0))/.6931471805599453+.5;a:{if(O(q)<2147483648){g=~~q;break a}g=-2147483648}b:{c:{d:{l=M((e+1|0)/2|0,(d+1|0)/2|0);i=ab(l);if(i){if((f|0)<=0){break c}j=f-1|0;m=g+((h|0)>1<>g&15;e:{if(f){if((f|0)!=15){break b}r=i,s=wh(a),E[r|0]=s;k=1;f=n;g=e;h=d;o=1;p=1;while(1){f=f>>1;p=(p<<1)-((h|0)<=(f|0))|0;o=(o<<1)-((f|0)>=(g|0))|0;zo(a,i,p,o,i);g=g-((f|0)<(g|0)?f:0)|0;h=h-((f|0)<(h|0)?f:0)|0;k=k+1|0;if((m|0)!=(k|0)){continue}break}break e}Hi(a,l,i)}yo(i,d,e,b,c,j);f=(j|0)>0;j=j-1|0;if(f){continue}break}break c}Ua(3057);return 414}while(1){f=G[48836];g=G[48835];if((g|0)<=3){h=G[48834];n=H[h+a|0];G[48834]=h+1;f=n|f<<8;G[48836]=f;g=g+8|0}g=g-4|0;G[48835]=g;f:{g:{f=f>>g&15;if(f){if((f|0)==15){break g}else{break b}}Hi(a,l,i);break f}r=i,s=wh(a),E[r|0]=s}yo(i,d,e,b,c,j);f=(j|0)>0;j=j-1|0;if(f){continue}break}}Wa(i);return 0}Ua(25234);return 414}function Ii(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;h=(d|0)>(e|0)?d:e;q=oc(+N(h|0))/.6931471805599453+.5;a:{if(O(q)<2147483648){g=~~q;break a}g=-2147483648}b:{c:{d:{l=M((e+1|0)/2|0,(d+1|0)/2|0);i=ab(l);if(i){if((f|0)<=0){break c}j=f-1|0;m=g+((h|0)>1<>g&15;e:{if(f){if((f|0)!=15){break b}r=i,s=wh(a),E[r|0]=s;k=1;f=n;g=e;h=d;o=1;p=1;while(1){f=f>>1;p=(p<<1)-((h|0)<=(f|0))|0;o=(o<<1)-((f|0)>=(g|0))|0;zo(a,i,p,o,i);g=g-((f|0)<(g|0)?f:0)|0;h=h-((f|0)<(h|0)?f:0)|0;k=k+1|0;if((m|0)!=(k|0)){continue}break}break e}Hi(a,l,i)}xo(i,d,e,b,c,j);f=(j|0)>0;j=j-1|0;if(f){continue}break}break c}Ua(3185);return 414}while(1){f=G[48836];g=G[48835];if((g|0)<=3){h=G[48834];n=H[h+a|0];G[48834]=h+1;f=n|f<<8;G[48836]=f;g=g+8|0}g=g-4|0;G[48835]=g;f:{g:{f=f>>g&15;if(f){if((f|0)==15){break g}else{break b}}Hi(a,l,i);break f}r=i,s=wh(a),E[r|0]=s}xo(i,d,e,b,c,j);f=(j|0)>0;j=j-1|0;if(f){continue}break}}Wa(i);return 0}Ua(25264);return 414}function ns(a,b,c,d,e,f,g,h,i,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;o=Fa-16|0;Fa=o;G[o+12>>2]=j;a:{k=G[a+8>>2];r=G[a>>2]+M(c,3)|0;p=r-2|0;n=M(p,168);l=k+n|0;b=G[l+32>>2];if(b){break a}b=lb(1e3,8);G[l+32>>2]=b;j=0;G[l+28>>2]=0;l=1e3;while(1){if((j|0)>=(l|0)){l=l+1e3|0;b=ub(b,l<<3);k=G[a+8>>2];G[(n+k|0)+32>>2]=b}m=G[o+12>>2]+7&-8;G[o+12>>2]=m+8;j=k+n|0;b=G[j+32>>2];q=G[j+28>>2];f=L[m>>3];L[b+(q<<3)>>3]=f;b:{if(!(O(f+-9007199254740992)<=1e-15)){break b}m=q-1|0;if(!(O(L[(m<<3)+b>>3]+-9007199254740992)<=1e-15)){break b}G[j+28>>2]=m;j=M(p,168);b=j+G[a+8>>2]|0;b=ub(G[b+32>>2],G[b+28>>2]<<3);k=G[a+8>>2];G[(j+k|0)+32>>2]=b;break a}m=j;j=q+1|0;G[m+28>>2]=j;continue}}j=G[(k+n|0)+28>>2];k=j-1|0;f=L[(k<<3)+b>>3];c:{if((k|0)==2){uf(a,j,c,d,e,f,f,h,i,L[b>>3],L[b+8>>3],f);break c}k=(j<<3)+b|0;uf(a,j,p,d,e,f,f,h,i,L[k-24>>3],L[k-16>>3],f);uf(a,j,r-1|0,d,e,f,f,h,i,L[b>>3],L[b+8>>3],f);if((j|0)<4){break c}n=j-4>>>1|0;j=0;k=2;while(1){l=k<<3;uf(a,j,c+j|0,d,e,f,f,h,i,L[l+b>>3],L[(l|8)+b>>3],f);k=k+2|0;l=(j|0)!=(n|0);j=j+1|0;if(l){continue}break}}Fa=o+16|0}function ms(a,b,c,d,e,f,g,h,i,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;o=Fa-16|0;Fa=o;G[o+12>>2]=j;a:{k=G[a+8>>2];r=G[a>>2]+M(c,3)|0;p=r-2|0;n=M(p,168);l=k+n|0;b=G[l+32>>2];if(b){break a}b=lb(1e3,8);G[l+32>>2]=b;j=0;G[l+28>>2]=0;l=1e3;while(1){if((j|0)>=(l|0)){l=l+1e3|0;b=ub(b,l<<3);k=G[a+8>>2];G[(n+k|0)+32>>2]=b}m=G[o+12>>2]+7&-8;G[o+12>>2]=m+8;j=k+n|0;b=G[j+32>>2];q=G[j+28>>2];f=L[m>>3];L[b+(q<<3)>>3]=f;b:{if(!(O(f+-9007199254740992)<=1e-15)){break b}m=q-1|0;if(!(O(L[(m<<3)+b>>3]+-9007199254740992)<=1e-15)){break b}G[j+28>>2]=m;j=M(p,168);b=j+G[a+8>>2]|0;b=ub(G[b+32>>2],G[b+28>>2]<<3);k=G[a+8>>2];G[(j+k|0)+32>>2]=b;break a}m=j;j=q+1|0;G[m+28>>2]=j;continue}}j=G[(k+n|0)+28>>2];k=j-1|0;f=L[(k<<3)+b>>3];c:{if((k|0)==2){tf(a,j,c,d,e,f,f,h,i,L[b>>3],L[b+8>>3],f);break c}k=(j<<3)+b|0;tf(a,j,p,d,e,f,f,h,i,L[k-24>>3],L[k-16>>3],f);tf(a,j,r-1|0,d,e,f,f,h,i,L[b>>3],L[b+8>>3],f);if((j|0)<4){break c}n=j-4>>>1|0;j=0;k=2;while(1){l=k<<3;tf(a,j,c+j|0,d,e,f,f,h,i,L[l+b>>3],L[(l|8)+b>>3],f);k=k+2|0;l=(j|0)!=(n|0);j=j+1|0;if(l){continue}break}}Fa=o+16|0}function fr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;a:{if(G[c+4>>2]==602){g=L[c+120>>3];break a}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=80;E[c+1|0]=67;E[c+2|0]=79;E[c+3|0]=0;E[c+4|0]=90;E[c+5|0]=2;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];b:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;h=1;g=1;f=114.59155902616465;break b}h=f*3.141592653589793/180;g=1/h;f=f+f}G[c+1892>>2]=137;G[c+1888>>2]=138;L[c+112>>3]=h;L[c+128>>3]=f;L[c+120>>3]=g}f=O(g*b);if(f<1e-12){L[d>>3]=g*a;G[e>>2]=0;G[e+4>>2]=0;return 0}if(O(f+-90)<1e-12){G[d>>2]=0;G[d+4>>2]=0;L[e>>3]=b<0?-90:90;return 0}g=b>0?90:-90;f=b-L[c+112>>3]*g;n=a*a;k=f*f+n;l=-999;h=0;while(1){if(l<-100){f=(h+g)*.5}else{f=.1;i=k/(k-l);c:{if(i<.1){break c}f=i;if(!(f>.9)){break c}f=.9}f=g-f*(g-h)}L[e>>3]=f;j=L[c+112>>3];i=Xe(f);j=b-j*f;f=j*(j-L[c+128>>3]/i)+n;if(!(O(f)<1e-12|O(g-h)<1e-12)){m=f>0;l=m?l:f;k=m?f:k;f=L[e>>3];g=m?f:g;h=m?h:f;o=o+1|0;if((o|0)!=64){continue}}break}b=L[c+24>>3]-j*i;a=i*a;if(!(b!=0|a!=0)){G[d>>2]=0;G[d+4>>2]=0;return 0}p=d,q=Ac(a,b)/Kb(L[e>>3]),L[p>>3]=q;return 0}function de(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0;e=G[d>>2];if((e|0)<=0){e=G[a>>2];g=G[a+4>>2];a:{b:{if((e|0)!=G[g+76>>2]){mb(a,e+1|0,0,d);break b}if((G[g+128>>2]&G[g+132>>2])!=-1){break b}if((Rb(a,d)|0)>0){break a}}h=G[a+4>>2];if(!G[h+80>>2]){a=G[h+136>>2];i=(a|0)<(b|0)?a:b;if((i|0)<=0){break a}b=0;if(i-1>>>0>=3){e=i&-4;g=h+144|0;while(1){G[(f<<2)+c>>2]=G[g+(f<<3)>>2];a=f|1;G[(a<<2)+c>>2]=G[g+(a<<3)>>2];a=f|2;G[(a<<2)+c>>2]=G[g+(a<<3)>>2];a=f|3;G[(a<<2)+c>>2]=G[g+(a<<3)>>2];f=f+4|0;j=j+4|0;if((e|0)!=(j|0)){continue}break}}e=i&3;if(!e){break a}while(1){G[(f<<2)+c>>2]=G[(h+(f<<3)|0)+144>>2];f=f+1|0;b=b+1|0;if((e|0)!=(b|0)){continue}break}break a}if(G[h+1088>>2]){a=G[h+1108>>2];e=(a|0)<(b|0)?a:b;if((e|0)<=0){break a}if(e-1>>>0>=3){b=e&-4;k=h+1112|0;while(1){g=f<<2;G[g+c>>2]=G[g+k>>2];a=g|4;G[a+c>>2]=G[a+k>>2];a=g|8;G[a+c>>2]=G[a+k>>2];a=g|12;G[a+c>>2]=G[a+k>>2];f=f+4|0;i=i+4|0;if((b|0)!=(i|0)){continue}break}}b=e&3;if(!b){break a}while(1){a=f<<2;G[a+c>>2]=G[(a+h|0)+1112>>2];f=f+1|0;j=j+1|0;if((b|0)!=(j|0)){continue}break}break a}G[d>>2]=233}e=G[d>>2]}return e|0}function bb(a,b,c){var d=0,e=0,f=0;if(c>>>0>=512){Da(a|0,b|0,c|0);return a}e=a+c|0;a:{if(!((a^b)&3)){b:{if(!(a&3)){c=a;break b}if(!c){c=a;break b}c=a;while(1){E[c|0]=H[b|0];b=b+1|0;c=c+1|0;if(!(c&3)){break b}if(c>>>0>>0){continue}break}}d=e&-4;c:{if(d>>>0<64){break c}f=d+-64|0;if(f>>>0>>0){break c}while(1){G[c>>2]=G[b>>2];G[c+4>>2]=G[b+4>>2];G[c+8>>2]=G[b+8>>2];G[c+12>>2]=G[b+12>>2];G[c+16>>2]=G[b+16>>2];G[c+20>>2]=G[b+20>>2];G[c+24>>2]=G[b+24>>2];G[c+28>>2]=G[b+28>>2];G[c+32>>2]=G[b+32>>2];G[c+36>>2]=G[b+36>>2];G[c+40>>2]=G[b+40>>2];G[c+44>>2]=G[b+44>>2];G[c+48>>2]=G[b+48>>2];G[c+52>>2]=G[b+52>>2];G[c+56>>2]=G[b+56>>2];G[c+60>>2]=G[b+60>>2];b=b- -64|0;c=c- -64|0;if(f>>>0>=c>>>0){continue}break}}if(c>>>0>=d>>>0){break a}while(1){G[c>>2]=G[b>>2];b=b+4|0;c=c+4|0;if(d>>>0>c>>>0){continue}break}break a}if(e>>>0<4){c=a;break a}d=e-4|0;if(d>>>0>>0){c=a;break a}c=a;while(1){E[c|0]=H[b|0];E[c+1|0]=H[b+1|0];E[c+2|0]=H[b+2|0];E[c+3|0]=H[b+3|0];b=b+4|0;c=c+4|0;if(d>>>0>=c>>>0){continue}break}}if(c>>>0>>0){while(1){E[c|0]=H[b|0];b=b+1|0;c=c+1|0;if((e|0)!=(c|0)){continue}break}}return a}function Em(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;d=Fa-80|0;Fa=d;j=L[a>>3];k=L[b>>3];g=k*3.141592653589793/180;c=eb(g);f=j*3.141592653589793/180;h=ib(f);f=eb(f);g=ib(g);f=f*c;c=h*c;h=g*-.198076386122+(f*-.87343710801+c*-.444829589425);i=g*-.867666135858+(f*-.054875539726+c*.494109453312);e=Db(h,i);e=e<0?e+6.283185307179586:e;e=(e>6.283185307179586?e+-6.283185307179586:e)*180/3.141592653589793;L[a>>3]=e;c=Db(g*.455983795705+(f*-.483834985808+c*.74698225181),V(i*i+h*h))*180/3.141592653589793;L[b>>3]=c;if(G[321348]){L[d+72>>3]=k;L[d+64>>3]=j;l=G[24367];xb(l,72182,d- -64|0);a=ab(32);m=c<0;c=m?-c:c;a:{if(O(c)<2147483648){b=~~c;break a}b=-2147483648}G[d+36>>2]=b;G[d+32>>2]=m?45:43;c=(c-+(b|0))*60;b:{if(O(c)<2147483648){b=~~c;break b}b=-2147483648}G[d+40>>2]=b;L[d+48>>3]=(c-+(b|0))*60;c=e/15;c:{if(O(c)<2147483648){b=~~c;break c}b=-2147483648}G[d+16>>2]=b;c=(c-+(b|0))*60;d:{if(O(c)<2147483648){b=~~c;break d}b=-2147483648}G[d+20>>2]=b;L[d+24>>3]=(c-+(b|0))*60;Eb(a,19241,d+16|0);if(H[a+6|0]==32){E[a+6|0]=48}if(H[a+20|0]==32){E[a+20|0]=48}G[d>>2]=a;_a(l,69349,d);Wa(a)}Fa=d+80|0}function Dm(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;d=Fa-80|0;Fa=d;k=L[a>>3];c=L[b>>3];h=c*3.141592653589793/180;f=eb(h);g=k*3.141592653589793/180;i=ib(g);g=eb(g);h=ib(h);g=g*f;f=i*f;i=h*.74698225181+(g*.494109453312+f*-.444829589425);j=h*-.483834985808+(g*-.054875539726+f*-.87343710801);e=Db(i,j);e=e<0?e+6.283185307179586:e;e=(e>6.283185307179586?e+-6.283185307179586:e)*180/3.141592653589793;L[a>>3]=e;f=Db(h*.455983795705+(g*-.867666135858+f*-.198076386122),V(j*j+i*i))*180/3.141592653589793;L[b>>3]=f;if(G[321348]){a=ab(32);b=c<0;G[d+48>>2]=b?45:43;c=b?-c:c;a:{if(O(c)<2147483648){b=~~c;break a}b=-2147483648}G[d+52>>2]=b;c=(c-+(b|0))*60;b:{if(O(c)<2147483648){b=~~c;break b}b=-2147483648}G[d+56>>2]=b;L[d- -64>>3]=(c-+(b|0))*60;c=k/15;c:{if(O(c)<2147483648){b=~~c;break c}b=-2147483648}G[d+32>>2]=b;c=(c-+(b|0))*60;d:{if(O(c)<2147483648){b=~~c;break d}b=-2147483648}G[d+36>>2]=b;L[d+40>>3]=(c-+(b|0))*60;Eb(a,19241,d+32|0);if(H[a+6|0]==32){E[a+6|0]=48}if(H[a+20|0]==32){E[a+20|0]=48}G[d+16>>2]=a;b=G[24367];_a(b,69322,d+16|0);L[d+8>>3]=f;L[d>>3]=e;xb(b,72116,d);Wa(a)}Fa=d+80|0}function qg(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;c=Fa+-64|0;Fa=c;a:{if(L[a+144>>3]<1.5?1:L[a+136>>3]<1.5){b=L[a+48>>3];L[a+3200>>3]=b;L[a+3216>>3]=b+180;L[a+3208>>3]=b+90;break a}if(G[a+3964>>2]==6){break a}L[a+32>>3]=O(L[a+32>>3]);L[a+40>>3]=O(L[a+40>>3]);d=L[a+16>>3];h=L[a+24>>3];cc(a,d,h,c+48|0,c+40|0);i=a+40|0;j=a+32|0;b=L[c+48>>3];b:{if(G[a+3304>>2]){e=L[c+40>>3];f=a+3912|0;pf(a,b+L[a+40>>3],e,f,c+24|0,c+8|0,c+60|0);g=j;break b}e=L[c+40>>3];f=a+3912|0;pf(a,b+L[a+32>>3],e,f,c+24|0,c+8|0,c+60|0);g=i}pf(a,b,e+L[g>>3],f,c+32|0,c+16|0,c+60|0);b=Db(L[c+16>>3]-h,L[c+32>>3]-d)*180/3.141592653589793;e=b<-90?b+360:b;L[a+3208>>3]=e;k=L[c+24>>3];l=L[c+8>>3];b=e+(e<-90?270:-90);L[a+3200>>3]=b;d=Db(l-h,k-d)*180/3.141592653589793;d=d<-90?d+360:d;L[a+3216>>3]=d;g=G[a+3304>>2];c:{if(g){b=b+90;L[a+48>>3]=b;if(!(b<0)){break c}b=b+360}L[a+48>>3]=b}f=b<0;b=f?b+360:b;if(b>=360|f){L[a+48>>3]=b>=360?b+-360:b}f=a;b=e-d;a=b>80&b<100;b=d-e;a=a|(b<280&b>260|b<-80&b>-100);G[f+3256>>2]=a;if(g){if(!a){break a}L[i>>3]=-L[i>>3];break a}if(a){break a}L[j>>3]=-L[j>>3]}Fa=c- -64|0}function re(a,b,c,d,e,f,g,h,i,j,k){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;var l=0,m=0,n=0,o=0;a:{b:{if(j==0){if(k==0){return!d|0}m=G[a+8>>2];if(d){e=m+M(c,168)|0;if(L[e+8>>3]>g|L[e+16>>3]>2];if(O(g)<2147483648){e=~~g}else{e=-2147483648}e=G[l+(e<<2)>>2];l=0;c:{if(!e){break c}l=0;if(!(L[n+8>>3]<=g)){break c}l=0;if(!(L[(m+M(c,168)|0)+16>>3]>=g)){break c}l=0;if(!(+G[e+4>>2]<=f)){break c}l=+G[G[e>>2]+4>>2]>=f}if((l|0)!=(d|0)){break a}o=1;if(!b){break a}if(d){break b}break a}m=G[a+8>>2];if(d){e=m+M(c,168)|0;if(L[e+8>>3]>g|L[e+16>>3]>2];if(O(g)<2147483648){e=~~g}else{e=-2147483648}e=G[l+(e<<2)>>2];l=0;d:{if(!e){break d}l=0;if(!(L[n+8>>3]<=g)){break d}l=0;if(!(L[(m+M(c,168)|0)+16>>3]>=g)){break d}g=+G[e+4>>2];c=G[e>>2];m=G[c>>2];if(m){l=0;if(!(f>=g)){break d}l=0;if(!(+G[G[m>>2]+4>>2]>=f)){break d}l=1;if(!(+G[c+4>>2]<=f)){break d}l=!(+G[m+4>>2]>=f);break d}l=0;if(!(f>=g)){break d}l=+G[c+4>>2]>=f}if((l|0)!=(d|0)){break a}o=1;if(!b|!d){break a}}G[a+12>>2]=b}return o|0}function En(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;f=Fa-176|0;Fa=f;if(!((b|0)<=0|G[e>>2]>0)){while(1){G[f+172>>2]=0;e=k;k=e+1|0;g=f+96|0;h=f+172|0;zb(34813,k,g,h);i=f+8|0;Cb(a,82,g,i,0,h);l=G[f+172>>2];G[f+172>>2]=0;j=L[f+8>>3];zb(32948,k,g,h);Cb(a,82,g,i,0,h);g=0;if(!G[f+172>>2]){m=L[f+8>>3];g=e<<3;n=(m-L[g+c>>3])/L[d+g>>3]+.5;L[f+8>>3]=n;Jd(a,f+96|0,n,-14,f+172|0);g=!l&m==1&j==1}G[f+172>>2]=0;h=f+96|0;i=f+172|0;zb(33351,k,h,i);Cb(a,82,h,f+8|0,0,i);a:{if(G[f+172>>2]){i=(e<<3)+d|0;e=0;while(1){G[f+172>>2]=0;e=e+1|0;g=f+16|0;h=f+172|0;zb(35841,e,g,h);l=Va(g)+g|0;E[l|0]=95;E[l+1|0]=0;l=g;g=f+96|0;zb(l,k,g,h);Cb(a,82,g,f+8|0,0,h);if(!G[f+172>>2]){j=L[f+8>>3]*L[i>>3];L[f+8>>3]=j;Jd(a,f+96|0,j,-14,f+172|0)}if((b|0)!=(e|0)){continue}break}break a}j=L[f+8>>3];h=e<<3;i=h+d|0;m=j*L[i>>3];L[f+8>>3]=m;Jd(a,f+96|0,m,-14,f+172|0);if(!g|j!=1){break a}G[f+8>>2]=0;G[f+12>>2]=1072693248;e=f+96|0;g=f+172|0;zb(32948,k,e,g);Jd(a,e,L[f+8>>3],-14,g);zb(34813,k,e,g);j=L[c+h>>3]+L[i>>3]*.5;L[f+8>>3]=j;Jd(a,e,j,-14,g)}if((b|0)!=(k|0)){continue}break}}Fa=f+176|0}function gn(a,b){var c=0,d=0,e=0,f=0,g=0;c=Fa-112|0;Fa=c;G[c+108>>2]=0;e=G[309712];a:{b:{if(Vc(e,a,c+32|0,0,c+108|0)){b=G[c+108>>2];if((b|0)!=202){break b}G[c>>2]=a;a=c+32|0;Ya(a,71,10075,c);Ua(a);b=G[c+108>>2];break b}f=c+32|0;d=G[c+108>>2];if((d|0)<=0){c:{d=67;d:{e:{f:{g:{g=H[f|0];switch(g-39|0){case 0:break d;case 1:break f;default:break g}}h:{switch(g-70|0){default:if(g){break e}G[c+108>>2]=204;d=204;break c;case 0:case 14:break h;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:break e}}d=76;break d}d=88;break d}d=70;if(jb(f,46)){break d}if(jb(f,69)){break d}d=jb(f,68)?70:73}E[c+31|0]=d;d=G[c+108>>2]}}if(d){b=G[c+108>>2];break b}d=-1;i:{j:{switch(E[c+31|0]-67|0){case 0:d=a;a=c+32|0;Fc(e,d,a,0,c+108|0);Za(b,a);d=261;break i;case 9:po(e,a,c+16|0,0,c+108|0);E[b|0]=G[c+16>>2];d=258;break i;case 6:Ec(e,a,c+16|0,0,c+108|0);G[b>>2]=G[c+16>>2];d=259;break i;case 3:break j;default:break i}}Kc(e,a,c+16|0,c+108|0);L[b>>3]=L[c+16>>3];d=260}b=G[c+108>>2];if(!b){break a}}G[309737]=b;d=-1}Fa=c+112|0;return d}function Fq(a,b){var c=0,d=0,e=0,f=0,g=0;g=b>>>24|0;d=G[a+604>>2];a:{if((d|0)<=7){c=G[a+600>>2];break a}f=G[a+76>>2];c=G[a+600>>2];while(1){E[G[a+44>>2]+f|0]=c>>>24;f=G[a+76>>2]+1|0;G[a+76>>2]=f;c=G[a+600>>2]<<8;G[a+600>>2]=c;e=G[a+604>>2];d=e-8|0;G[a+604>>2]=d;if((e|0)>15){continue}break}}e=d+8|0;G[a+604>>2]=e;c=g<<24-d|c;G[a+600>>2]=c;if((d|0)>=0){f=G[a+76>>2];while(1){E[G[a+44>>2]+f|0]=c>>>24;f=G[a+76>>2]+1|0;G[a+76>>2]=f;c=G[a+600>>2]<<8;G[a+600>>2]=c;d=G[a+604>>2];e=d-8|0;G[a+604>>2]=e;if((d|0)>15){continue}break}}d=e+8|0;G[a+604>>2]=d;c=(b>>>16&255)<<24-e|c;G[a+600>>2]=c;if((e|0)>=0){f=G[a+76>>2];while(1){E[G[a+44>>2]+f|0]=c>>>24;f=G[a+76>>2]+1|0;G[a+76>>2]=f;c=G[a+600>>2]<<8;G[a+600>>2]=c;e=G[a+604>>2];d=e-8|0;G[a+604>>2]=d;if((e|0)>15){continue}break}}e=d+8|0;G[a+604>>2]=e;c=(b>>>8&255)<<24-d|c;G[a+600>>2]=c;if((d|0)>=0){f=G[a+76>>2];while(1){E[G[a+44>>2]+f|0]=c>>>24;f=G[a+76>>2]+1|0;G[a+76>>2]=f;c=G[a+600>>2]<<8;G[a+600>>2]=c;d=G[a+604>>2];e=d-8|0;G[a+604>>2]=e;if((d|0)>15){continue}break}}G[a+604>>2]=e+8;G[a+600>>2]=(b&255)<<24-e|c}function Kl(a,b,c,d,e,f,g,h){var i=0,j=0,k=0,l=0;i=Fa-4192|0;Fa=i;G[i+32>>2]=1;G[i+36>>2]=1;a:{b:{j=1;c:{if(e==0){break c}j=e;if(!(e<0)){break c}j=1/O(e)}k=ei(a,c,d,j,f,g,0,i- -64|0,i+48|0,i+88|0,h);c=G[h>>2];d:{if(!(c?0:k)){a=i+96|0;uc(c,a);G[i>>2]=a;_a(G[24367],69532,i);break d}e=+((G[i+52>>2]-G[i+68>>2]|0)+1|0)/j;e:{if(O(e)<2147483648){d=~~e;break e}d=-2147483648}G[i+44>>2]=d;e=+((G[i+48>>2]-G[i+64>>2]|0)+1|0)/j;f:{if(O(e)<2147483648){c=~~e;break f}c=-2147483648}G[i+40>>2]=c;f=G[i+88>>2];l=Eu(f- -64|0,29);if(l>>>0>=17|!(71249>>>l&1)){break b}pd(b,f,2,i+40|0,h);Td(a,i+92|0,0,h);g=4;if(G[i+92>>2]>=4){while(1){f=i+96|0;Sd(a,g,f,h);if((mk(f)|0)>=21){wb(b,i+96|0,h)}f=G[i+92>>2]>(g|0);g=g+1|0;if(f){continue}break}}if(G[h>>2]>0){hb(14082,59,1,G[24367]);break d}c=M(c,d);ag(b,G[(l<<2)+156884>>2],i+32|0,c,c>>31,k,h);d=G[i+64>>2];L[i+16>>3]=N(d|0);c=G[i+68>>2];L[i+24>>3]=N(c|0);f=a;g=b;b=G[i+48>>2];a=G[i+52>>2];Sm(f,g,(b+d|0)/2|0,(a+c|0)/2|0,(b-d|0)+1|0,(a-c|0)+1|0,j,i+16|0);Wa(k)}a=G[h>>2];break a}hb(70173,43,1,G[24367]);a=-1}Fa=i+4192|0;return a}function gi(a){var b=0,c=0,d=0,e=0;c=Fa-16|0;Fa=c;b=a;a:{b:while(1){c:{d=1;d:{e:{f:{g:{h:{i:{b=G[b>>2];e=H[b|0];switch(e|0){case 0:break a;case 41:break c;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 35:case 36:case 37:case 38:break d;case 39:break e;case 34:break f;case 40:break h;default:break i}}if((e|0)==91){break g}if((e|0)!=123){break d}G[c+12>>2]=b+1;b=c+12|0;if(!ii(b)){continue}break a}G[c+12>>2]=b+1;b=c+12|0;if(!gi(b)){continue}break a}G[c+12>>2]=b+1;b=c+12|0;if(!hi(b)){continue}break a}b=b+1|0;G[c+12>>2]=b;while(1){d=H[b|0];if(!d){d=1;break a}if((d|0)==34){G[c+12>>2]=b+1;b=c+12|0;continue b}else{b=b+1|0;continue}}}b=b+1|0;G[c+12>>2]=b;while(1){d=H[b|0];if(!d){d=1;break a}if((d|0)==39){G[c+12>>2]=b+1;b=c+12|0;continue b}else{b=b+1|0;continue}}}G[c+12>>2]=b+1;b=c+12|0;continue}break}G[a>>2]=b+1;d=0}Fa=c+16|0;return d}function Ti(a){var b=0,c=0,d=0,e=0,f=0;b=-6;a:{if(H[41336]!=49){break a}if(!a){return-2}G[a+24>>2]=0;d=G[a+32>>2];if(!d){G[a+40>>2]=0;G[a+32>>2]=9;d=9}if(!G[a+36>>2]){G[a+36>>2]=10}e=Ja[d|0](G[a+40>>2],1,7120)|0;if(!e){return-4}G[a+28>>2]=e;G[e+56>>2]=0;G[e>>2]=a;G[e+4>>2]=16180;d=-2;b:{if(!a|!G[a+32>>2]){break b}c=G[a+36>>2];if(!c){break b}b=G[a+28>>2];if(!b|G[b>>2]!=(a|0)|G[b+4>>2]-16180>>>0>31){break b}f=G[b+56>>2];c:{if(!(G[b+40>>2]!=15?f:0)){G[b+40>>2]=15;G[b+12>>2]=6;break c}Ja[c|0](G[a+40>>2],f);G[b+56>>2]=0;c=G[a+32>>2];G[b+40>>2]=15;G[b+12>>2]=6;if(!c){break b}}if(!G[a+36>>2]){break b}b=G[a+28>>2];if(!b|G[b>>2]!=(a|0)|G[b+4>>2]-16180>>>0>31){break b}d=0;G[b+52>>2]=0;G[b+44>>2]=0;G[b+48>>2]=0;G[b+32>>2]=0;G[a+8>>2]=0;G[a+20>>2]=0;G[a+24>>2]=0;c=G[b+12>>2];if(c){G[a+48>>2]=c&1}G[b+60>>2]=0;G[b+64>>2]=0;G[b+36>>2]=0;G[b+24>>2]=32768;G[b+16>>2]=0;G[b+4>>2]=16180;G[b+8>>2]=0;G[b+7108>>2]=1;G[b+7112>>2]=-1;c=b+1332|0;G[b+112>>2]=c;G[b+84>>2]=c;G[b+80>>2]=c}b=0;if(!d){break a}Ja[G[a+36>>2]](G[a+40>>2],e);G[a+28>>2]=0;b=d}return b}function jj(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0;if(G[321436]){i=G[24367];hb(88593,25,1,i);$a(i)}if(!H[3706156]){G[926542]=442745336;G[926543]=1078765020;G[926540]=-1571644103;G[926541]=1066524486;E[3706156]=1}a:{if(!(G[47593]!=(f|0)|L[23797]!=e)){e=L[463272];g=L[463273];h=L[463270];break a}if(G[321436]){i=G[24367];hb(89165,24,1,i);$a(i)}L[23797]=e;G[47593]=f;b:{if(f){e=(e+-1950)*.01;g=e*e;e=e*g*.00182+(g*-.0033+(e*-46.85+84404.84));break b}e=(e+-2e3)*.01;g=e*e;e=e*g*.001813+(g*-59e-5+(e*-46.815+84381.448))}h=L[463270];g=e/3600*h;e=eb(g);L[463272]=e;g=ib(g);L[463273]=g}j=h*b;b=eb(j);a=h*a;h=eb(a);a=b*-ib(a);k=a*g;j=ib(j);l=e*j;a=Db(-(g*j+e*a),h*b);b=L[463271];e=a*b;if(e<0){while(1){e=e+360;if(e<0){continue}break}}L[c>>3]=e;if(e>360){while(1){e=e+-360;if(e>360){continue}break}L[c>>3]=e}a=l-k;e=O(a);if(e>1){L[d>>3]=a*90/e;G[c>>2]=0;G[c+4>>2]=0;return}a=b*fc(a);L[d>>3]=a;c:{if(!(O(a)>=90)){break c}G[c>>2]=0;G[c+4>>2]=0;a=L[d>>3];if(a>90){G[d>>2]=0;G[d+4>>2]=1079410688;return}if(!(a<-90)){break c}G[d>>2]=0;G[d+4>>2]=-1068072960}}function sl(a){var b=0,c=0,d=0,e=0,f=0,g=0;c=G[a+52>>2];d=G[a+56>>2];a:{if((d|0)<=0){break a}e=c&255;b=G[a+608>>2];if((d|0)!=1){g=d&-2;while(1){b=G[((b>>>24^e)<<2)+191040>>2]^b<<8;G[a+608>>2]=b;b=G[((b>>>24^e)<<2)+191040>>2]^b<<8;G[a+608>>2]=b;f=f+2|0;if((g|0)!=(f|0)){continue}break}}if(!(d&1)){break a}G[a+608>>2]=G[((b>>>24^e)<<2)+191040>>2]^b<<8}E[(a+c|0)+88|0]=1;b:{c:{d:{e:{f:{b=G[a+56>>2];switch(b-1|0){case 2:break d;case 1:break e;case 0:break f;default:break c}}E[G[a+36>>2]+G[a+68>>2]|0]=c;a=a+68|0;break b}E[G[a+36>>2]+G[a+68>>2]|0]=c;b=G[a+68>>2]+1|0;G[a+68>>2]=b;E[b+G[a+36>>2]|0]=c;a=a+68|0;break b}E[G[a+36>>2]+G[a+68>>2]|0]=c;b=G[a+68>>2]+1|0;G[a+68>>2]=b;E[b+G[a+36>>2]|0]=c;b=G[a+68>>2]+1|0;G[a+68>>2]=b;E[b+G[a+36>>2]|0]=c;a=a+68|0;break b}E[(a+b|0)+84|0]=1;E[G[a+36>>2]+G[a+68>>2]|0]=c;b=G[a+68>>2]+1|0;G[a+68>>2]=b;E[b+G[a+36>>2]|0]=c;b=G[a+68>>2]+1|0;G[a+68>>2]=b;E[b+G[a+36>>2]|0]=c;b=G[a+68>>2]+1|0;G[a+68>>2]=b;E[b+G[a+36>>2]|0]=c;c=G[a+68>>2]+1|0;G[a+68>>2]=c;E[c+G[a+36>>2]|0]=H[a+56|0]-4;a=a+68|0}G[a>>2]=G[a>>2]+1}function af(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;A(+a);c=v(1)|0;d=v(0)|0;a:{b:{e=c>>>20&2047;if(e-969>>>0<63){j=e;break b}if(e>>>0<=968){return a+1}if(e>>>0<1033){break b}b=0;if(!d&(c|0)==-1048576){break a}if((e|0)==2047){return a+1}if((c|0)<0){c=Fa-16|0;L[c+8>>3]=12882297539194267e-247;return L[c+8>>3]*12882297539194267e-247}c=Fa-16|0;L[c+8>>3]=3105036184601418e216;return L[c+8>>3]*3105036184601418e216}b=L[12706];f=L[12705]*a+b;b=f-b;b=b*L[12708]+(b*L[12707]+a);a=b*b;g=a*a*(b*L[12712]+L[12711]);a=a*(b*L[12710]+L[12709]);A(+f);v(1)|0;h=v(0)|0;d=h<<4&2032;b=g+(a+(L[d+101752>>3]+b));e=d+101760|0;d=h<<13;c=0;i=G[e>>2]+c|0;d=d+G[e+4>>2]|0;d=c>>>0>i>>>0?d+1|0:d;e=i;if(!j){c:{if(!(h&-2147483648)){x(0,e|0);x(1,d-1058013184|0);a=+z();a=(a*b+a)*5486124068793689e288;break c}c=Fa-16|0;x(0,e|0);x(1,d+1071644672|0);g=+z();f=g*b;a=f+g;if(a<1){G[c+8>>2]=0;G[c+12>>2]=1048576;L[c+8>>3]=L[c+8>>3]*22250738585072014e-324;b=a+1;a=b+(f+(g-a)+(a+(1-b)))+-1;a=a==0?0:a}a=a*22250738585072014e-324}return a}x(0,e|0);x(1,d|0);a=+z();b=a*b+a}return b}function ac(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0;f=Fa-16|0;Fa=f;a:{b:{if(!jb(30829,E[b|0])){G[48624]=28;break b}d=2;if(!jb(b,43)){d=H[b|0]!=114}d=jb(b,120)?d|128:d;d=jb(b,101)?d|524288:d;e=d;g=d|64;d=H[b|0];e=(d|0)==114?e:g;e=(d|0)==119?e|512:e;G[f>>2]=438;G[f+4>>2]=0;a=ja(-100,a|0,((d|0)==97?e|1024:e)|32768,f|0)|0;if(a>>>0>=4294963201){G[48624]=0-a;a=-1}if((a|0)<0){break a}d=Fa-32|0;Fa=d;c:{d:{e:{if(!jb(30829,E[b|0])){G[48624]=28;break e}c=ab(1176);if(c){break d}}b=0;break c}cb(c,0,144);if(!jb(b,43)){G[c>>2]=H[b|0]==114?8:4}f:{if(H[b|0]!=97){b=G[c>>2];break f}b=ia(a|0,3,0)|0;if(!(b&1024)){b=b|1024;G[d+16>>2]=b;G[d+20>>2]=b>>31;ia(a|0,4,d+16|0)|0}b=G[c>>2]|128;G[c>>2]=b}G[c+80>>2]=-1;G[c+48>>2]=1024;G[c+60>>2]=a;G[c+44>>2]=c+152;g:{if(b&8){break g}G[d>>2]=d+24;G[d+4>>2]=0;if(oa(a|0,21523,d|0)|0){break g}G[c+80>>2]=10}G[c+40>>2]=5;G[c+36>>2]=6;G[c+32>>2]=7;G[c+12>>2]=8;if(!H[195005]){G[c+76>>2]=-1}G[c+56>>2]=G[48750];b=G[48750];if(b){G[b+52>>2]=c}G[48750]=c;b=c}Fa=d+32|0;c=b;if(c){break a}da(a|0)|0}c=0}Fa=f+16|0;return c|0}function Bg(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;d=R(a,0);a:{if(d<15){a=1;d=af(-d);while(1){b=g;g=b+1|0;c=Au(G[309618],G[309619],1284865837,1481765933)+1|0;e=Ia;e=c?e:e+1|0;G[309618]=c;G[309619]=e;a=a*(+(e>>>1|0)*4.656612873077393e-10);if(d>3]=j}d=oc(a);while(1){b=Au(G[309618],G[309619],1284865837,1481765933)+1|0;c=Ia;c=b?c:c+1|0;G[309618]=b;G[309619]=c;a=+(c>>>1|0)*4.656612873077393e-10;a=(L[154813]-oc((1-a)/a))/L[154812];f=S(a+.5);b:{if(O(f)<2147483648){b=~~f;break b}b=-2147483648}c:{if((b|0)<0){b=3;break c}c=Au(G[309618],G[309619],1284865837,1481765933)+1|0;e=Ia;e=c?e:e+1|0;G[309618]=c;G[309619]=e;f=L[154813]-L[154812]*a;a=af(f)+1;c=b;f=f+oc(+(e>>>1|0)*4.656612873077393e-10/(a*a));h=+(b|0)*d+L[154814];d:{if(b>>>0>=255){a=+(b+1|0);a=1/(a*12)+((a+-.5)*oc(a)-a+.9189385332046727);break d}a=L[(b<<3)+125008>>3]}b=f<=h-a;g=b?c:g}if((b|0)!=1){continue}break}b=g}return b}function Pr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;if(G[c+4>>2]!=701){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=84;E[c+1|0]=83;E[c+2|0]=67;E[c+3|0]=0;E[c+4|0]=189;E[c+5|0]=2;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];a:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=45;g=.022222222222222223;break a}f=f*3.141592653589793*.25;g=1/f}G[c+1892>>2]=101;G[c+1888>>2]=102;L[c+112>>3]=f;L[c+120>>3]=g}f=Mb(b);j=Mb(a);h=Kb(a);g=Kb(b);a=-g;h=f*h;l=-h;j=f*j;k=-j;i=g1){i=2;if(a>1.000000000001){break e}b=b<0?-1:1}a=O(f);if(a>1){i=2;if(a>1.000000000001){break e}f=f<0?-1:1}L[d>>3]=(m+b)*L[c+112>>3];L[e>>3]=(r+f)*L[c+112>>3];i=0}return i|0}function Jg(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;g=Fa-112|0;Fa=g;d=G[c>>2];a:{if((d|0)>0){break a}d=G[a>>2];if((d|0)!=G[G[a+4>>2]+76>>2]){mb(a,d+1|0,0,c)}E[b|0]=0;d=G[a+4>>2];l=G[d+96>>2]+(G[d+76>>2]<<3)|0;j=G[l>>2];e=G[d+124>>2];h=G[d+120>>2];i=G[d+104>>2];f=G[d+128>>2];m=f-2880|0;k=G[d+108>>2];f=G[d+132>>2]-(f>>>0<2880)|0;d=f;d=i>>>0>m>>>0&(k|0)>=(d|0)|(d|0)<(k|0);i=d?i:m;d=d?k:f;f=h>>>0<=i>>>0&(d|0)>=(e|0)|(d|0)>(e|0);d=G[l+4>>2];if(!(f&((d|0)<=(e|0)&h>>>0>=j>>>0|(d|0)<(e|0)))){n=g,o=Bu(h-j|0,e-((h>>>0>>0)+d|0)|0,80,0)+1|0,G[n>>2]=o;a=g+16|0;Ya(a,81,42404,g);Ua(a);d=203;G[c>>2]=203;break a}Jb(a,h,e,0,c);E[b+80|0]=0;if((ic(a,80,0,b,c)|0)<=0){d=G[a+4>>2];a=G[d+124>>2];e=G[d+120>>2]+80|0;a=e>>>0<80?a+1|0:a;G[d+120>>2]=e;G[d+124>>2]=a;a=79;b:{while(1){if(H[a+b|0]!=32){d=a;break b}d=a-1|0;if(H[d+b|0]!=32){break b}d=a-2|0;if(H[d+b|0]!=32){break b}d=a-3|0;if(H[d+b|0]!=32){break b}d=a-4|0;if(H[d+b|0]!=32){break b}a=a-5|0;if(d){continue}break}d=-1}E[(b+d|0)+1|0]=0}d=G[c>>2]}Fa=g+112|0;return d}function Db(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0;A(+a);c=v(1)|0;c=c&2147483647;d=!(v(0)|0)&(c|0)==2146435072|c>>>0<2146435072;A(+b);c=v(1)|0;c=c&2147483647;if(!(d&(!(v(0)|0)&(c|0)==2146435072|c>>>0<2146435072))){return a+b}A(+b);d=v(1)|0;h=v(0)|0;e=d;if(!(h|d-1072693248)){return Pd(a)}A(+a);c=v(1)|0;d=v(0)|0;i=e>>>30&2;f=i|c>>>31;a:{c=c&2147483647;b:{if(!(d|c)){c:{switch(f-2|0){case 0:return 3.141592653589793;case 1:break c;default:break b}}return-3.141592653589793}d=e&2147483647;if(!(d|h)){break a}d:{if((d|0)==2146435072){if((c|0)!=2146435072){break d}return L[(f<<3)+120384>>3]}if(!((c|0)!=2146435072&d+67108864>>>0>=c>>>0)){break a}e:{if(i){g=0;if(d>>>0>c+67108864>>>0){break e}}g=Pd(O(a/b))}a=g;f:{switch(f|0){case 1:return-a;case 2:return 3.141592653589793-(a+-12246467991473532e-32);case 0:break b;default:break f}}return a+-12246467991473532e-32+-3.141592653589793}a=L[(f<<3)+120416>>3]}return a}A(1.5707963267948966);c=v(1)|0;e=v(0)|0;A(+a);d=v(1)|0;v(0)|0;x(0,e|0);x(1,c&2147483647|d&-2147483648);return+z()}function Vt(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0;g=Fa-16|0;Fa=g;e=g+12|0;if(e){G[e>>2]=0}a:{b:{c:{if(!a){break c}G[a+5060>>2]=0;if(!b){break c}if((c|0)>=0){break b}}if(e){G[e>>2]=-2}if(!a){break a}G[a+5060>>2]=-2;break a}if(!H[a+5008|0]){if(e){G[e>>2]=-1}G[a+5060>>2]=-1;break a}d:{d=G[a>>2];e:{if(G[d+76>>2]<0){d=G[d>>2];break e}d=G[d>>2]}if(d>>>5&1){break d}if(!c){if(e){G[e>>2]=0}G[a+5060>>2]=0;break a}G[a+5012>>2]=b;G[a+5016>>2]=c;h=a+4|0;i=a+5012|0;b=-1;while(1){G[a+5028>>2]=h;G[a+5032>>2]=5e3;d=-2;f:{f=G[a+5044>>2];g:{h:{if(!f|G[f>>2]!=(i|0)){break h}f=G[f+4>>2];if((f|0)!=2){d=0;if(!(1<>>0>4){break h}break g}if(Eq(i)){break f}}b=d}if(e){G[e>>2]=b}G[a+5060>>2]=b;break a}i:{d=G[a+5032>>2];if(d>>>0>4999){break i}d=5e3-d|0;if((hb(h,1,d,G[a>>2])|0)==(d|0)){d=G[a>>2];j:{if(G[d+76>>2]<0){d=G[d>>2];break j}d=G[d>>2]}if(!(d>>>5&1)){break i}}break d}if(G[a+5016>>2]){continue}break}if(e){G[e>>2]=0}G[a+5060>>2]=0;break a}if(e){G[e>>2]=-6}G[a+5060>>2]=-6}Fa=g+16|0;return(G[g+12>>2]?-1:c)|0} -function Xm(a,b){var c=0,d=0,e=0,f=0;e=Fa-16|0;Fa=e;G[e+12>>2]=999;G[e+8>>2]=0;a:{if(!a){G[b>>2]=115;break a}if(G[G[a+4>>2]+16>>2]!=555){G[b>>2]=114;break a}b:{if(G[b>>2]>0){Xf(a,e+12|0);break b}Xf(a,b)}sh(a,1,b);c=G[a+4>>2];if(!(!(Ja[G[(M(G[c+4>>2],84)+1240576|0)+56>>2]](G[c>>2])|0)|G[b>>2]>0)){G[b>>2]=110;Ua(49731);Ua(G[G[a+4>>2]+12>>2])}c=G[a+4>>2];if(G[(M(G[c+4>>2],84)+1240576|0)+60>>2]){d=G[c+12>>2];c=ab(Va(d)+1|0);if(!c){G[b>>2]=113;break a}dh(d,0,c,0,0,0,0,0,0,0,e+8|0);c:{if(!(Ja[G[(M(G[G[a+4>>2]+4>>2],84)+1240576|0)+60>>2]](c)|0)){break c}Ua(49685);Ua(G[G[a+4>>2]+12>>2]);if(G[b>>2]){break c}G[b>>2]=110}Wa(c);c=G[a+4>>2]}d:{while(1){e:{d=f<<2;b=d+1243184|0;if(G[b>>2]==(c|0)){break e}d=d+1243184|0;b=d+4|0;if(G[b>>2]==(c|0)){break e}b=d+8|0;if(G[b>>2]==(c|0)){break e}b=d+12|0;if(G[b>>2]==(c|0)){break e}b=d+16|0;if(G[b>>2]==(c|0)){break e}f=f+5|0;if((f|0)!=1e4){continue}break d}break}G[b>>2]=0;c=G[a+4>>2]}Wa(G[c+1252>>2]);Wa(G[G[a+4>>2]+96>>2]);Wa(G[G[a+4>>2]+12>>2]);Wa(G[a+4>>2]);Wa(a)}Fa=e+16|0}function Go(a,b,c,d,e,f,g,h,i,j){var k=0,l=0,m=0,n=0;k=Fa-256|0;Fa=k;E[k+143|0]=84;E[k+142|0]=70;l=G[j>>2];a:{if((l|0)>0){break a}b:{if((yc(a,b,c,d,e,f,g,h,1,k+184|0,k+176|0,k+144|0,k+240|0,k+252|0,k+248|0,k+216|0,k+208|0,k+236|0,k+224|0,k+200|0,k+244|0,k+192|0,k+16|0,j)|0)>0){break b}if(G[k+252>>2]==14){e=0;f=0;if(!(g|h)){break b}c=0;d=0;while(1){b=G[k+220>>2];l=G[k+216>>2];m=Au(G[k+200>>2],G[k+204>>2],c,d);l=l+m|0;b=Ia+b|0;b=l>>>0>>0?b+1|0:b;n=l;l=G[k+236>>2];m=Au(G[k+208>>2],G[k+212>>2],l,l>>31);l=n+m|0;b=Ia+b|0;Jb(a,l,l>>>0>>0?b+1|0:b,1,j);Wb(a,1,0,H[e+i|0]?k+143|0:k+142|0,j);l=G[j>>2];if((l|0)>0){a=e+1|0;f=a?f:f+1|0;L[k>>3]=+(a>>>0)+ +(f|0)*4294967296;a=k+48|0;Ya(a,81,46260,k);Ua(a);break b}h=h-!g|0;g=g-1|0;if(!(h|g)){break a}b=e+1|0;f=b?f:f+1|0;e=b;b=G[k+212>>2];l=G[k+208>>2]+1|0;b=l?b:b+1|0;G[k+208>>2]=l;G[k+212>>2]=b;if(G[k+224>>2]!=(l|0)|G[k+228>>2]!=(b|0)){continue}G[k+208>>2]=0;G[k+212>>2]=0;b=d;c=c+1|0;b=c?b:b+1|0;d=b;continue}}l=310;G[j>>2]=310;break a}l=G[j>>2]}Fa=k+256|0;return l}function sr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0;if(G[c+4>>2]!=303){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=77;E[c+1|0]=79;E[c+2|0]=76;E[c+3|0]=0;E[c+4|0]=47;E[c+5|0]=1;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=57.29577951308232}G[c+1892>>2]=123;G[c+1888>>2]=124;G[c+144>>2]=1841940611;G[c+148>>2]=1071931184;L[c+136>>3]=90/f;f=f*1.4142135623730951;L[c+112>>3]=f;L[c+128>>3]=1/f;L[c+120>>3]=f/90}a:{if(O(b)==90){G[d>>2]=0;G[d+4>>2]=0;a=O(L[c+112>>3]);f=b<0?-a:a;break a}f=0;if(b==0){L[d>>3]=L[c+120>>3]*a;break a}f=3.141592653589793;h=-3.141592653589793;i=Kb(b)*3.141592653589793;b=i;while(1){b:{g=b-i+ib(b);c:{if(g<0){h=b;if(!(g>-1e-13)){break c}break b}f=b;if(g<1e-13){break b}}b=(h+f)*.5;g=b-i+ib(b);d:{if(!(g<0)){f=b;if(!(g<1e-13)){break d}break b}h=b;if(g>-1e-13){break b}}b=(h+f)*.5;j=j+2|0;if((j|0)!=100){continue}}break}f=L[c+120>>3];b=b*.5;k=d,l=eb(b)*(f*a),L[k>>3]=l;f=L[c+112>>3]*ib(b)}L[e>>3]=f;return 0}function os(a,b,c,d,e,f,g,h,i,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;q=Fa-16|0;Fa=q;G[q+12>>2]=j;a:{l=G[a+8>>2];r=(G[a>>2]+M(c,3)|0)-2|0;o=M(r,168);n=l+o|0;k=G[n+32>>2];if(k){break a}k=lb(1e3,8);G[n+32>>2]=k;j=0;G[n+28>>2]=0;n=1e3;while(1){if((j|0)>=(n|0)){n=n+1e3|0;j=ub(k,n<<3);l=G[a+8>>2];G[(o+l|0)+32>>2]=j}m=G[q+12>>2]+7&-8;G[q+12>>2]=m+8;j=l+o|0;k=G[j+32>>2];s=G[j+28>>2];p=L[m>>3];L[k+(s<<3)>>3]=p;b:{if(!(O(p+-9007199254740992)<=1e-15)){break b}m=s-1|0;if(!(O(L[(m<<3)+k>>3]+-9007199254740992)<=1e-15)){break b}G[j+28>>2]=m;j=M(r,168);k=j+G[a+8>>2]|0;k=ub(G[k+32>>2],G[k+28>>2]<<3);l=G[a+8>>2];G[(j+l|0)+32>>2]=k;break a}m=j;j=s+1|0;G[m+28>>2]=j;continue}}p=L[k>>3];l=G[(l+o|0)+28>>2];c:{if((l|0)==2){vf(a,b,c,d,e,f,g,h,i,p,L[k+8>>3]);break c}j=0;o=l-1|0;vf(a,0,r,d,e,f,g,h,i,p,L[(o<<3)+k>>3]);if((l|0)<2){break c}while(1){m=b+j|0;l=c+j|0;p=L[(j<<3)+k>>3];j=j+1|0;vf(a,m,l,d,e,f,g,h,i,p,L[(j<<3)+k>>3]);if((j|0)!=(o|0)){continue}break}}Fa=q+16|0}function Nl(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;g=Fa+-8192|0;Fa=g;a:{i=Ic(8192,1);if(!i){break a}while(1){b:{c:{d:{c=H[a|0];if((c|0)!=36){if(!c){break d}E[i+e|0]=c;e=e+1|0;E[e+i|0]=0;a=a+1|0;continue}c=H[a+1|0];e:{f:{if((c|0)!=40){j=125;if((c|0)!=123){c=a+1|0;f=0;break e}c=a+2|0;break f}j=41;c=a+2|0}f=1}E[g|0]=0;d=E[c|0];if((d|0)==32|d-9>>>0<5){break b}h=0;if(f){break c}while(1){j=d&255;f=j-34|0;if(!(f>>>0>13|!(1<>>0<5)){continue}break}break b}rb(b,i,8192);pb(i);break a}while(1){g:{h:{f=d&255;switch(f-34|0){case 1:case 2:case 3:case 4:break g;case 0:case 5:break b;default:break h}}if(!f){break b}}if((d|0)==(j|0)){c=c+1|0;break b}if((f|0)==47){break b}E[g+h|0]=d;h=h+1|0;E[h+g|0]=0;d=E[c+1|0];c=c+1|0;if(!((d|0)==32|d-9>>>0<5)){continue}break}}c=c-1|0;d=Fd(g);i:{if(d){e=Va(d)+e|0;if((e|0)>8192){break i}Gb(i,d);break i}d=(c-a|0)+1|0;e=d+e|0;if((e|0)>8192){break i}qb(i,a,d)}a=c+1|0;continue}}Fa=g- -8192|0}function ff(a){var b=0,c=0,d=0,e=0;b=-2;a:{if(!a|!G[a+32>>2]){break a}e=G[a+36>>2];if(!e){break a}c=G[a+28>>2];if(!c|G[c>>2]!=(a|0)){break a}b:{c:{d=G[c+4>>2];switch(d-57|0){case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 13:case 14:case 15:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 47:case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:break a;case 0:case 12:case 16:case 34:case 46:case 56:break b;default:break c}}if((d|0)==666){break b}if((d|0)!=42){break a}}b=G[c+8>>2];if(b){Ja[e|0](G[a+40>>2],b);c=G[a+28>>2]}b=G[c+68>>2];if(b){Ja[G[a+36>>2]](G[a+40>>2],b);c=G[a+28>>2]}b=G[c+64>>2];if(b){Ja[G[a+36>>2]](G[a+40>>2],b);c=G[a+28>>2]}b=G[c+56>>2];if(b){Ja[G[a+36>>2]](G[a+40>>2],b);c=G[a+28>>2]}Ja[G[a+36>>2]](G[a+40>>2],c);G[a+28>>2]=0;b=(d|0)==113?-3:0}return b}function Tn(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;if(!G[d>>2]){E[c|0]=0;a:{b:{if(!(!ad(a)&H[a|0]!=47)){if(ad(b)|H[b|0]==47){break b}}G[d>>2]=125;Ua(58787);break a}g=Va(a);i=Va(b);if((g|0)<=0|(i|0)<=0){break a}while(1){h=e;c:{if((e|0)>=(i|0)){break c}while(1){if(H[b+h|0]!=47){break c}h=h+1|0;if((i|0)!=(h|0)){continue}break}h=i}d:{if((e|0)>=(g|0)){break d}while(1){if(H[a+e|0]!=47){break d}e=e+1|0;if((g|0)!=(e|0)){continue}break}e=g}f=h;while(1){e:{j=f;f=f+1|0;if(H[b+j|0]==47){break e}if((i|0)>(j|0)){continue}}break}l=e;while(1){k=l;if(H[k+a|0]!=47){l=k+1|0;if((g|0)>(k|0)){continue}}break}f:{if((j|0)==(k|0)){if(!fb(b+h|0,a+e|0,j-e|0)){break f}}if((e|0)<(g|0)){while(1){if(H[a+e|0]==47){if(Va(c)-1022>>>0<=4294966270){G[d>>2]=125;Ua(58845);break a}f=Va(c)+c|0;E[f|0]=46;E[f+1|0]=46;E[f+2|0]=47;E[f+3|0]=0}e=e+1|0;if((g|0)!=(e|0)){continue}break}}a=b+h|0;if(Va(c)+Va(a)>>>0>=1025){G[d>>2]=125;Ua(58845);break a}Gb(c,a);break a}if((f|0)>=(g|0)){break a}e=f;if((i|0)>(e|0)){continue}break}}}}function Ui(a,b,c,d){var e=0,f=0,g=0,h=0;g=Fa-32|0;Fa=g;e=d&2147483647;h=e;f=e-1006698496|0;e=e-1140785152|0;a:{if((f|0)==(e|0)&0|e>>>0>f>>>0){e=d<<4|c>>>28;f=c<<4|b>>>28;c=e;b=b&268435455;if((b|0)==134217728&(a|0)!=0|b>>>0>134217728){e=c+1073741824|0;a=f+1|0;e=a?e:e+1|0;f=a;break a}e=c+1073741824|0;if(a|(b|0)!=134217728){break a}b=f&1;a=b+f|0;e=a>>>0>>0?e+1|0:e;f=a;break a}if(!(!c&(h|0)==2147418112?!(a|b):h>>>0<2147418112)){e=c;c=d<<4|e>>>28;f=e<<4|b>>>28;e=c&524287|2146959360;break a}f=0;e=2146435072;if(h>>>0>1140785151){break a}e=0;h=h>>>16|0;if(h>>>0<15249){break a}e=d&65535|65536;od(g+16|0,a,b,c,e,h-15233|0);eg(g,a,b,c,e,15361-h|0);e=G[g+4>>2];h=e;a=G[g+8>>2];c=G[g+12>>2]<<4|a>>>28;f=a<<4|e>>>28;e=c;a=h&268435455;b=G[g>>2]|(G[g+16>>2]|G[g+24>>2]|(G[g+20>>2]|G[g+28>>2]))!=0;if((a|0)==134217728&(b|0)!=0|a>>>0>134217728){a=f+1|0;e=a?e:e+1|0;f=a;break a}if(b|(a|0)!=134217728){break a}a=f+(f&1)|0;e=a>>>0>>0?e+1|0:e;f=a}Fa=g+32|0;x(0,f|0);x(1,d&-2147483648|e);return+z()}function qm(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;if(d){g=G[a+3316>>2];if(g-10>>>0<=4294967286){g=G[a+3320>>2];G[a+3316>>2]=g}L[a+760>>3]=b;L[a+32>>3]=b;b=c!=0?c:b;L[a+768>>3]=b;L[a+40>>3]=b;a:{b:{if((g|0)<=0){break b}k=g&-8;i=g&7;e=a+832|0;l=g-1>>>0<7;f=d;while(1){h=0;if(!l){while(1){L[e>>3]=L[f>>3];L[e+8>>3]=L[f+8>>3];L[e+16>>3]=L[f+16>>3];L[e+24>>3]=L[f+24>>3];L[e+32>>3]=L[f+32>>3];L[e+40>>3]=L[f+40>>3];L[e+48>>3]=L[f+48>>3];L[e+56>>3]=L[f+56>>3];f=f- -64|0;e=e- -64|0;h=h+8|0;if((k|0)!=(h|0)){continue}break}}h=0;if(i){while(1){L[e>>3]=L[f>>3];f=f+8|0;e=e+8|0;h=h+1|0;if((i|0)!=(h|0)){continue}break}}j=j+1|0;if((j|0)!=(g|0)){continue}break}if((g|0)<2){break b}b=L[a+760>>3];L[a+56>>3]=L[d>>3]*b;L[a- -64>>3]=b*L[d+8>>3];d=(g<<3)+d|0;b=L[a+768>>3];L[a+72>>3]=L[d>>3]*b;b=b*L[d+8>>3];break a}b=L[d>>3];d=a- -64|0;G[d>>2]=0;G[d+4>>2]=0;G[a+72>>2]=0;G[a+76>>2]=0;L[a+56>>3]=b*L[a+760>>3];b=1}L[a+80>>3]=b;sg(2,a+56|0,a+88|0);G[a+3300>>2]=1;Aj(a+4036|0);G[a+3312>>2]=1;qg(a)}}function ls(a,b,c,d,e,f,g,h,i,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0;o=Fa-16|0;Fa=o;G[o+12>>2]=j;a:{k=G[a+8>>2];p=(G[a>>2]+M(c,3)|0)-2|0;n=M(p,168);m=k+n|0;b=G[m+32>>2];if(b){break a}b=lb(1e3,8);G[m+32>>2]=b;j=0;G[m+28>>2]=0;m=1e3;while(1){if((j|0)>=(m|0)){m=m+1e3|0;b=ub(b,m<<3);k=G[a+8>>2];G[(n+k|0)+32>>2]=b}l=G[o+12>>2]+7&-8;G[o+12>>2]=l+8;j=k+n|0;b=G[j+32>>2];q=G[j+28>>2];f=L[l>>3];L[b+(q<<3)>>3]=f;b:{if(!(O(f+-9007199254740992)<=1e-15)){break b}l=q-1|0;if(!(O(L[(l<<3)+b>>3]+-9007199254740992)<=1e-15)){break b}G[j+28>>2]=l;j=M(p,168);b=j+G[a+8>>2]|0;b=ub(G[b+32>>2],G[b+28>>2]<<3);k=G[a+8>>2];G[(j+k|0)+32>>2]=b;break a}l=j;j=q+1|0;G[l+28>>2]=j;continue}}f=L[b>>3];k=G[(k+n|0)+28>>2];c:{if((k|0)==2){Ze(a,0,c,d,e,h,i,f,L[b+8>>3]);break c}j=0;n=k-1|0;Ze(a,0,p,d,e,h,i,f,L[(n<<3)+b>>3]);if((k|0)<2){break c}while(1){l=c+j|0;f=L[(j<<3)+b>>3];j=j+1|0;Ze(a,0,l,d,e,h,i,f,L[(j<<3)+b>>3]);if((j|0)!=(n|0)){continue}break}}Fa=o+16|0}function Br(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;a:{if(G[c+4>>2]!=109){G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=65;E[c+1|0]=73;E[c+2|0]=82;E[c+3|0]=0;E[c+4|0]=109;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;f=L[c+24>>3];if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=57.29577951308232}g=f+f;L[c+112>>3]=g;f=L[c+40>>3];b:{if(f==90){G[c+128>>2]=0;G[c+132>>2]=1072693248;G[c+120>>2]=0;G[c+124>>2]=-1075838976;f=1;break b}h=1;if(!(f>-90)){break a}f=Mb((90-f)*.5);g=f*f;f=oc(f)*g/(1-g);L[c+120>>3]=f;f=.5-f;L[c+128>>3]=f;g=L[c+112>>3]}G[c+1892>>2]=115;G[c+1888>>2]=116;L[c+160>>3]=57.29577951308232/f;L[c+152>>3]=f*1e-4;G[c+144>>2]=-350469331;G[c+148>>2]=1058682594;L[c+136>>3]=f*g}f=0;c:{if(b==90){break c}h=2;if(!(b>-90)){break a}b=90-b;f=b*.017453292519943295*.5;if(f>3]){f=f*L[c+136>>3];break c}b=Mb(b*.5);f=oc(b);b=V(1-b*b)/b;f=(L[c+120>>3]*b+f/b)*-L[c+112>>3]}i=d,j=f*Kb(a),L[i>>3]=j;i=e,j=Mb(a)*-f,L[i>>3]=j;h=0}return h|0}function Hi(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;f=G[48835];if((b|0)==1){d=G[48836];if((f|0)<=3){b=a;a=G[48834];b=H[b+a|0];G[48834]=a+1;d=b|d<<8;G[48836]=d;f=f+8|0}a=f-4|0;G[48835]=a;E[c|0]=d>>a&15;return}a:{b:{c:{if((f|0)==8){G[48834]=G[48834]-1;G[48835]=0;break c}if(!f){break c}i=(b|0)/2|0;d=G[48834];e=G[48836];if((b|0)<=1){i=0;break a}k=f+4|0;while(1){e=H[a+d|0]|e<<8;E[c+g|0]=e>>k&15;E[(g|1)+c|0]=e>>f&15;g=g+2|0;d=d+1|0;h=h+1|0;if((i|0)!=(h|0)){continue}break}break b}i=(b|0)/2|0;f=0;d=G[48834];e=G[48836];if((b|0)<2){i=0;break a}l=i&1;if((b&-2)!=2){m=i&-2;while(1){j=a+d|0;k=H[j|0];E[c+g|0]=k>>>4;E[(g|1)+c|0]=k&15;j=H[j+1|0];E[(g|2)+c|0]=j>>>4;E[(g|3)+c|0]=j&15;e=j|(e<<16|k<<8);g=g+4|0;d=d+2|0;h=h+2|0;if((m|0)!=(h|0)){continue}break}}if(!l){break b}h=H[a+d|0];E[c+g|0]=h>>>4;E[(g|1)+c|0]=h&15;e=h|e<<8;d=d+1|0}G[48834]=d;G[48836]=e}if(i<<1!=(b|0)){if((f|0)<=3){a=H[a+d|0];G[48834]=d+1;e=a|e<<8;G[48836]=e;f=f+8|0}a=f-4|0;G[48835]=a;E[(b+c|0)-1|0]=e>>a&15}}function oe(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0;e=Fa-208|0;Fa=e;G[e+8>>2]=1;G[e+12>>2]=0;i=M(b,c);a:{if(!i){break a}G[e+16>>2]=c;G[e+20>>2]=c;j=0-c|0;b=c;f=b;h=2;while(1){g=b;b=(c+f|0)+b|0;G[(e+16|0)+(h<<2)>>2]=b;h=h+1|0;f=g;if(b>>>0>>0){continue}break}g=(a+i|0)+j|0;b:{if(g>>>0<=a>>>0){b=1;break b}h=1;b=1;while(1){c:{if((h&3)==3){Kk(a,c,d,b,e+16|0);Pi(e+8|0,2);b=b+2|0;break c}f=b-1|0;d:{if(J[(e+16|0)+(f<<2)>>2]>=g-a>>>0){Oi(a,c,d,e+8|0,b,0,e+16|0);break d}Kk(a,c,d,b,e+16|0)}if((b|0)==1){Ni(e+8|0,1);b=0;break c}Ni(e+8|0,f);b=1}h=G[e+8>>2]|1;G[e+8>>2]=h;a=a+c|0;if(g>>>0>a>>>0){continue}break}}Oi(a,c,d,e+8|0,b,0,e+16|0);if(!(G[e+12>>2]?1:(b|0)!=1|G[e+8>>2]!=1)){break a}while(1){e:{if((b|0)<=1){f=e+8|0;g=ep(f);Pi(f,g);b=b+g|0;break e}f=e+8|0;Ni(f,2);G[e+8>>2]=G[e+8>>2]^7;Pi(f,1);i=a+j|0;h=e+16|0;g=b-2|0;Oi(i-G[h+(g<<2)>>2]|0,c,d,f,b-1|0,1,h);Ni(f,1);G[e+8>>2]=G[e+8>>2]|1;Oi(i,c,d,f,g,1,h);b=g}a=a+j|0;if(G[e+12>>2]|((b|0)!=1|G[e+8>>2]!=1)){continue}break}}Fa=e+208|0}function rg(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;a=a-L[c+616>>3];f=a*a;k=a*f;b=b-L[c+624>>3];g=b*b;h=f+g;l=b*g;m=G[c+3272>>2];i=a*L[c+296>>3]*b+(L[c+288>>3]*g+(L[c+280>>3]*f+(L[c+272>>3]*b+(L[c+264>>3]*a+L[c+256>>3]))));n=G[c+3268>>2];a:{if((n|0)<7){break a}i=L[c+312>>3]*l+(L[c+304>>3]*k+i);if(n>>>0<9){break a}i=b*L[c+352>>3]*h+(a*L[c+344>>3]*h+(L[c+336>>3]*h+(a*L[c+328>>3]*g+(f*L[c+320>>3]*b+i))))}j=a*L[c+456>>3]*b+(L[c+448>>3]*g+(L[c+440>>3]*f+(L[c+432>>3]*b+(L[c+424>>3]*a+L[c+416>>3]))));b:{if((m|0)<7){break b}j=L[c+472>>3]*l+(L[c+464>>3]*k+j);if(m>>>0<9){break b}j=b*L[c+512>>3]*h+(a*L[c+504>>3]*h+(L[c+496>>3]*h+(g*L[c+488>>3]*a+(f*L[c+480>>3]*b+j))))}a=L[c+696>>3]*3.141592653589793/180;b=eb(a);k=L[c+688>>3]*3.141592653589793/180;i=i*3.141592653589793/180/b;b=j*3.141592653589793/180;g=Mc(a);f=1-b*g;h=Db(i,f);a=k+h;L[d>>3]=(a<0?a+6.28318530717959:a)*180/3.141592653589793;o=e,p=Pd(eb(h)/(f/(b+g)))*180/3.141592653589793,L[o>>3]=p;return 0}function Nk(a,b,c){var d=0,e=0,f=0,g=0,h=0;d=-6;a:{if(H[41336]!=49){break a}d=-2;if(!a){break a}G[a+24>>2]=0;e=G[a+32>>2];if(!e){G[a+40>>2]=0;G[a+32>>2]=9;e=9}if(!G[a+36>>2]){G[a+36>>2]=10}if(c>>>0>4){break a}f=(b|0)==-1?6:b;if(f>>>0>9){break a}d=-4;b=Ja[e|0](G[a+40>>2],1,5828)|0;if(!b){break a}G[a+28>>2]=b;G[b+28>>2]=0;G[b+24>>2]=2;G[b+4>>2]=42;G[b>>2]=a;G[b+80>>2]=15;G[b+76>>2]=32768;G[b+48>>2]=15;G[b+84>>2]=32767;G[b+44>>2]=32768;G[b+88>>2]=5;G[b+52>>2]=32767;g=b,h=Ja[G[a+32>>2]](G[a+40>>2],32768,2)|0,G[g+56>>2]=h;g=b,h=Ja[G[a+32>>2]](G[a+40>>2],G[b+44>>2],2)|0,G[g+64>>2]=h;d=Ja[G[a+32>>2]](G[a+40>>2],G[b+76>>2],2)|0;G[b+5824>>2]=0;G[b+68>>2]=d;G[b+5788>>2]=16384;d=Ja[G[a+32>>2]](G[a+40>>2],16384,4)|0;G[b+8>>2]=d;e=G[b+5788>>2];G[b+12>>2]=e<<2;b:{if(!(!G[b+68>>2]|(!G[b+56>>2]|!G[b+64>>2]))){if(d){break b}}G[b+4>>2]=666;G[a+24>>2]=G[26250];ff(a);return-4}G[b+136>>2]=c;G[b+132>>2]=f;E[b+36|0]=8;G[b+5784>>2]=d+M(e,3);G[b+5796>>2]=d+(e&-2);d=kp(a)}return d}function Qr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;a:{if(G[c+4>>2]==701){f=L[c+120>>3];break a}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=84;E[c+1|0]=83;E[c+2|0]=67;E[c+3|0]=0;E[c+4|0]=189;E[c+5|0]=2;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];b:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;g=45;f=.022222222222222223;break b}g=f*3.141592653589793*.25;f=1/g}G[c+1892>>2]=101;G[c+1888>>2]=102;L[c+112>>3]=g;L[c+120>>3]=f}b=f*b;a=f*a;f=O(a);c:{d:{if(f<=1){c=2;if(!(O(b)>3)){break d}break c}c=2;if(f>7|O(b)>1){break c}}f=a<-1?a+8:a;e:{if(f>5){a=f+-6;g=-1/V(b*b+(a*a+1));f=-g;a=a*f;b=b*f;break e}if(f>3){f=f+-4;a=-1/V(b*b+(f*f+1));g=f*a;b=b*-a;break e}if(f>1){a=f+-2;g=1/V(b*b+(a*a+1));a=a*-g;b=b*g;break e}if(b>1){a=b+-2;b=1/V(a*a+(f*f+1));g=f*b;a=a*-b;break e}if(b<-1){g=f;a=b+2;b=-1/V(a*a+(f*f+1));f=-b;g=g*f;a=a*f;break e}a=1/V(b*b+(f*f+1));b=b*a;g=f*a}if(a==0&g==0){a=0}else{a=Ac(g,a)}L[d>>3]=a;h=e,i=Bc(b),L[h>>3]=i;c=0}return c|0}function hp(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0;f=Fa+-64|0;Fa=f;a:{if(G[e>>2]>0){break a}g=G[c>>2];h=ab(115200);if(!h){G[e>>2]=113;break a}G[f+48>>2]=0;G[f+40>>2]=0;G[f+44>>2]=0;i=G[b>>2];G[f+24>>2]=g;G[f+20>>2]=i;b:{if(Ti(f+8|0)){break b}k=(g|0)==-1;c:{d:{e:{while(1){g=zc(h,1,115200,a);if(G[a+76>>2]<0){i=G[a>>2]}else{i=G[a>>2]}if(i>>>5&1){break c}if(!g){break d}G[f+12>>2]=g;G[f+8>>2]=h;f:while(1){i=k&!l;while(1){g:{h:{switch(Ch(f+8|0)+5|0){case 6:break g;case 0:case 5:break h;default:break e}}if(!G[f+12>>2]){break g}g=G[b>>2];if(i){G[f+20>>2]=g-1;g=G[c>>2];G[f+24>>2]=(g|0)==-1?0:g;l=1;continue f}g=Ja[17](g,G[c>>2]+28800|0)|0;G[b>>2]=g;if(g){G[f+24>>2]=28800;j=G[c>>2];G[f+20>>2]=g+j;G[c>>2]=j+28800;continue}else{ye(f+8|0);Wa(h);break b}}break}break}if(G[a+76>>2]<0){g=G[a>>2]}else{g=G[a>>2]}if(!(g>>>4&1)){continue}break}break d}ye(f+8|0);Wa(h);break b}G[d>>2]=G[f+28>>2];Wa(h);if(ye(f+8|0)){break b}break a}ye(f+8|0);Wa(h)}G[e>>2]=414}Fa=f- -64|0}function Ln(a,b,c,d,e,f){var g=0;g=Fa-16|0;Fa=g;a:{if(G[f>>2]>0){break a}E[443536]=0;qb(443536,a,127);G[110917]=c;G[110916]=b;G[110918]=d;G[110919]=17;G[110920]=0;G[110922]=0;G[110923]=0;G[110921]=0;b=0;b:{c:{while(1){d:{a=zc(b+443696|0,1,32768-b|0,G[110916]);b=G[110921];if(a+1>>>0<2){break d}b=a+b|0;G[110921]=b;if(b>>>0<32768){continue}break c}break}if(b){break c}Ua(443536);Ua(22164);b=G[110921];c=1;a=G[110920];break b}G[110920]=1;G[110923]=G[110923]+b;c=H[443696];a=1}E[g+14|0]=c;e:{if(a>>>0>>0){G[110920]=a+1;a=H[a+443696|0];break e}G[110921]=0;b=0;f:{while(1){g:{a=zc(b+443696|0,1,32768-b|0,G[110916]);b=G[110921];if(a+1>>>0<2){break g}b=a+b|0;G[110921]=b;if(b>>>0<32768){continue}break f}break}if(b){break f}Ua(443536);Ua(22164);a=1;break e}G[110920]=1;G[110923]=G[110923]+b;a=H[443696]}E[g+15|0]=a;if((H[g+14|0]|H[g+15|0]<<8)!=40223){Ua(443536);Ua(86619);break a}G[47518]=18;if(Nn(G[110916],G[119132])){G[f>>2]=414}if(e){G[e>>2]=G[110922]}}Fa=g+16|0}function Pm(a,b,c,d,e,f,g,h,i){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;var j=0,k=0,l=0,m=0,n=0,o=0;k=G[a+16>>2];l=M(c,168);j=l+G[a+8>>2]|0;f=+G[a+32>>2];g=(i-+G[a+24>>2])/f+1+.5;a:{if(O(g)<2147483648){b=~~g;break a}b=-2147483648}g=+(b|0);L[j+16>>3]=g;L[j+8>>3]=g;n=j,o=lb(G[a+48>>2]+1|0,4),G[n+24>>2]=o;Pf(a,c,d,e);j=G[(l+G[a+8>>2]|0)+24>>2];f=(h-+(k|0))/f+1+.5;b:{if(O(f)<2147483648){c=~~f;break b}c=-2147483648}k=G[a+48>>2];l=G[a+44>>2];m=lb(1,8);G[m+4>>2]=c;c:{if(!j){break c}b=(b|0)<(l|0)?l:b;k=(b|0)<(k|0)?b:k;b=j+(k<<2)|0;j=G[b>>2];d:{if(!j){j=0;break d}if((c|0)>2]){break d}while(1){b=j;j=G[b>>2];if(!j){j=0;break d}if((c|0)>G[j+4>>2]){continue}break}}G[m>>2]=j;G[b>>2]=m;if((e|0)==1){break c}if(d){b=k<<2;d=b+G[a+56>>2]|0;if((c|0)<=G[d>>2]){e=d;d=G[a+36>>2];G[e>>2]=(c|0)<(d|0)?d:c}b=b+G[a+60>>2]|0;if((c|0)>2]){break c}a=G[a+40>>2];G[b>>2]=(a|0)<(c|0)?a:c;return}b=k<<2;G[b+G[a+56>>2]>>2]=G[a+36>>2];G[b+G[a+60>>2]>>2]=G[a+40>>2]}}function Nd(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;e=1;h=G[a+52>>2];if(h-261>>>0<=1){c=G[309727];b=ab(c<<2);G[a+88>>2]=b;if(b){d=b;f=G[a+56>>2];b=ab(M(c,f+2|0));G[d>>2]=b;if(b){b=0;a:{if((c|0)<2){break a}b=c-1|0;i=b&3;b:{if(c-2>>>0<3){b=0;break b}g=b&-4;b=0;while(1){d=G[a+88>>2];c=e<<2;G[d+c>>2]=(G[d+(b<<2)>>2]+f|0)+1;b=G[a+88>>2];d=c+4|0;G[b+d>>2]=(G[b+c>>2]+f|0)+1;b=G[a+88>>2];c=c+8|0;G[b+c>>2]=(G[b+d>>2]+f|0)+1;d=G[a+88>>2];b=e+3|0;G[d+(b<<2)>>2]=(G[c+d>>2]+f|0)+1;e=e+4|0;j=j+4|0;if((g|0)!=(j|0)){continue}break}}if(!i){break a}c=b;while(1){g=G[a+88>>2];b=e;G[g+(b<<2)>>2]=(G[g+(c<<2)>>2]+f|0)+1;e=b+1|0;c=b;k=k+1|0;if((k|0)!=(i|0)){continue}break}}if((h|0)==261){G[a+84>>2]=(G[G[a+88>>2]+(b<<2)>>2]+f|0)+1;return}G[a+84>>2]=0;return}G[309737]=113;Wa(G[a+88>>2]);return}G[309737]=113;return}b=M(G[309727],G[a+56>>2]);c=h-258|0;if(c>>>0<=2){e=G[(c<<2)+137092>>2]}c=lb(e+1|0,b);G[a+88>>2]=c;if(!c){G[309737]=113;return}G[a+84>>2]=c+M(b,e)}function Lq(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;e=Fa-32|0;Fa=e;a:{b:{c=G[a>>2];if(c){a=G[b>>2];if(a){break b}}a=G[24367];c:{if(H[3780288]){G[e+20>>2]=3780288;G[e+16>>2]=4045;Tb(a,69475,e+16|0);break c}G[e>>2]=4045;Tb(a,68751,e)}b=0;a=G[945062];d:{if(!a){break d}d=a+(G[945063]<<2)|0;a=G[d>>2];if(!a){break d}G[a+16>>2]=0;E[G[a+4>>2]]=0;E[G[a+4>>2]+1|0]=0;G[a+44>>2]=0;G[a+28>>2]=1;c=G[a+4>>2];G[a+8>>2]=c;if((a|0)!=G[d>>2]){break d}a=G[a+16>>2];G[945064]=c;G[950324]=a;G[945070]=c;G[945057]=G[G[d>>2]>>2];E[3780260]=H[c|0]}E[3801300]=1;break a}d=G[a+24>>2];if(!G[c+24>>2]){b=(d|0)!=0;break a}b=-1;if(!d){break a}d=G[c+4>>2];if(G[G[950220]+8>>2]){if(!(!(d&7)|!(H[a+4|0]&7))){b=1;c=G[c>>2];a=G[a>>2];if((c|0)<(a|0)){break a}b=(a|0)<(c|0)?-1:0;break a}c=G[c>>2];a=G[a>>2];if((c|0)<(a|0)){break a}b=(a|0)<(c|0);break a}f=G[a+4>>2]&1;d=d&1;if((f|0)==(d|0)){c=G[c>>2];a=G[a>>2];if((c|0)<(a|0)){break a}b=(a|0)<(c|0);break a}b=d?1:0-f|0}Fa=e+32|0;return b|0}function aj(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0;f=Fa-32768|0;Fa=f;a:{e=jb(b,62);i=jb(b,60);if(i?e:0){break a}b:{c:{if(!c){break c}d:{switch(H[a|0]-46|0){case 1:break c;case 0:break d;default:break b}}if(H[a+1|0]!=47){break b}}d=Ml(a,b);break a}d=rb(f+24576|0,c,8191);E[d+8191|0]=0;c=Ih(d);if(c){h=E[c|0];E[c|0]=0;c=c+1|0}else{c=0}g=(e|0)!=0;while(1){e=c;e:{f:{g:{if(jb(d,36)){c=f- -8192|0;Nl(d,c);if(jb(c,36)){break g}d=aj(a,b,f- -8192|0);if(d){break a}break g}if(g){break g}if(!Xa(48504,d)){E[d|0]=0}d=rb(f+16384|0,d,8191);E[f+24575|0]=0;c=Va(d);if(!(!H[d|0]|H[(c+d|0)-1|0]==47)){if((c|0)>8190){d=0;break a}g=Va(d)+d|0;E[g|0]=47;E[g+1|0]=0;c=c+1|0}if(c+Va(a)>>>0>8191){d=0;break a}d=Ml(Gb(d,a),b);if(d){break a}g=0;if((h|0)==59){break f}break e}if((h|0)!=59){break e}if(!g){break f}b=rb(f,b,8191);E[f+8191|0]=0}g=0;if(!i){break e}d=0;break a}if(!e){d=0;break a}c=0;d=e;e=Ih(d);if(!e){continue}h=E[e|0];E[e|0]=0;c=e+1|0;continue}}Fa=f+32768|0;return d}function bp(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;m=8<=2){q=c-1|0;r=1<>>1|0)+1|0;t=(d&-2)<(d|0);while(1){l=h+s|0;g=M(b,i);k=g+b|0;while(1){p=g<<2;j=(k<<2)+a|0;E[e+h|0]=(G[(p|4)+a>>2]<<2&o|(G[j>>2]<<1&n|G[j+4>>2]&r)|G[a+p>>2]<<3&m)>>f;k=k+2|0;g=g+2|0;j=h;h=h+1|0;if((l|0)!=(h|0)){continue}break}b:{if(t){E[e+l|0]=(G[(g<<2)+a>>2]<<3&m|G[(k<<2)+a>>2]<<1&n)>>f;h=j+2|0;break b}h=l}i=i+2|0;if((q|0)>(i|0)){continue}break}break a}if((d|0)!=1){i=c&-2;break a}l=c-2>>>1|0;h=l+1|0;while(1){j=M(b,i);E[e+g|0]=(G[(j<<2)+a>>2]<<3&m|G[(b+j<<2)+a>>2]<<1&n)>>f;i=i+2|0;j=(g|0)!=(l|0);g=g+1|0;if(j){continue}break}}c:{if((c|0)<=(i|0)){break c}g=M(b,i);k=0;if((d|0)>=2){c=d-1|0;while(1){b=g<<2;E[e+h|0]=(G[b+a>>2]<<3&m|G[(b|4)+a>>2]<<2&o)>>f;g=g+2|0;h=h+1|0;k=k+2|0;if((c|0)>(k|0)){continue}break}b=d&-2}else{b=0}if((b|0)>=(d|0)){break c}E[e+h|0]=(G[(g<<2)+a>>2]<<3&m)>>f}}function Ci(a,b,c,d,e,f,g,h){var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;n=Fa-1e5|0;Fa=n;i=G[h>>2];if((i|0)<=0){i=c+e|0;j=b+d|0;i=j>>>0>>0?i+1|0:i;p=j;s=i;a:{if(d|e){q=!!f&(g|0)>=0|(g|0)>0;i=q;m=i?p:b;i=i?s:c;j=g>>31;r=j;r=j;while(1){j=m;m=i;k=d>>>0<1e5&(e|0)<=0|(e|0)<0?d:1e5;i=k>>31;l=q?k:0;m=m-((j>>>0>>0)+(q?i:0)|0)|0;l=j-l|0;Jb(a,l,m,0,h);j=i;ic(a,k,i,n,h);i=g+m|0;o=f+l|0;i=o>>>0>>0?i+1|0:i;Jb(a,o,i,1,h);if((Wb(a,k,j,n,h)|0)>0){Ua(50392);break a}o=k&r;l=o+l|0;i=(j&r)+m|0;i=l>>>0>>0?i+1|0:i;m=l;e=e-((d>>>0>>0)+j|0)|0;d=d-k|0;if(e|d){continue}break}}b:{if(G[G[a+4>>2]+80>>2]==1){cb(n,32,1e5);break b}cb(n,0,1e5)}d=g+s|0;e=f+p|0;d=e>>>0

>>0?d+1|0:d;i=b;b=(g|0)<0;Jb(a,b?e:i,b?d:c,0,h);if(!(f|g)){break a}b=g>>31;i=b;e=i^f;b=e-i|0;c=(g^i)-((i>>>0>e>>>0)+i|0)|0;while(1){e=b>>>0<1e5&(c|0)<=0|(c|0)<0?b:1e5;i=e;k=i>>31;Wb(a,i,k,n,h);c=c-((b>>>0>>0)+k|0)|0;b=b-i|0;if(c|b){continue}break}}i=G[h>>2]}Fa=n+1e5|0;return i}function oc(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;A(+a);c=v(1)|0;e=v(0)|0;d=c-1072562176|0;if((d|0)==198911|d>>>0<198911){if(!e&(c|0)==1072693248){return 0}a=a+-1;b=a*134217728;b=a+b-b;h=L[11600];j=b*b*h;k=a+j;f=a*a;g=a*f;return k+(g*(g*(g*(g*L[11610]+(f*L[11609]+(a*L[11608]+L[11607])))+(f*L[11606]+(a*L[11605]+L[11604])))+(f*L[11603]+(a*L[11602]+L[11601])))+((a-b)*h*(a+b)+(j+(a-k))))}d=c>>>16|0;a:{if(d-32752>>>0<=4294934559){if(!(c&2147483647|e)){e=Fa-16|0;L[e+8>>3]=-1;return L[e+8>>3]/0}if(!e&(c|0)==2146435072){break a}if(!(!(d&32768)&(d&32752)!=32752)){a=a-a;return a/a}A(+(a*4503599627370496));c=v(1)|0;e=v(0)|0;c=c-54525952|0}d=c-1072037888|0;f=+(d>>20);i=(d>>>13&127)<<4;g=f*L[11593]+L[i+92896>>3];a=L[i+92888>>3];x(0,e-0|0);x(1,c-((d&-1048576)+(e>>>0>>0)|0)|0);a=a*(+z()-L[i+94936>>3]-L[i+94944>>3]);h=g+a;b=a*a;a=h+(a*b*(b*(a*L[11599]+L[11598])+(a*L[11597]+L[11596]))+(b*L[11595]+(f*L[11594]+(a+(g-h)))))}return a}function Le(a,b,c,d,e,f,g){var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;h=Fa-32|0;Fa=h;G[h+24>>2]=0;G[h+28>>2]=0;G[h+8>>2]=0;G[h+12>>2]=0;G[h>>2]=0;G[h+4>>2]=0;i=G[g>>2];a:{if((i|0)>0){break a}j=G[a>>2];i=G[a+4>>2];b:{c:{if((j|0)!=G[i+76>>2]){mb(a,j+1|0,0,g);break c}if((G[i+128>>2]&G[i+132>>2])!=-1){break c}if((Rb(a,g)|0)>0){break b}}j=b-1|0;b=G[a+4>>2];k=G[b+968>>2];i=M(j,160)+k|0;if(G[i+80>>2]>=0){i=317;G[g>>2]=317;break a}l=G[i+76>>2];m=G[b+132>>2];n=G[i+72>>2];o=G[b+128>>2];d=Au(G[b+960>>2],G[b+964>>2],c-1|0,d-!c|0);c=o+d|0;b=Ia+m|0;b=c>>>0>>0?b+1|0:b;d=c;c=n+c|0;b=b+l|0;b=c>>>0>>0?b+1|0:b;d:{if(!(H[i+140|0]!=80&H[(k+M(j,160)|0)+141|0]!=80)){if((Uc(a,c,b,2,4,h+24|0,g)|0)>0){break b}if(e){G[e>>2]=G[h+24>>2];G[e+4>>2]=0}if(!f){break b}b=0;a=G[h+28>>2];break d}if((Tc(a,c,b,2,8,h,g)|0)>0){break b}if(e){a=G[h+4>>2];G[e>>2]=G[h>>2];G[e+4>>2]=a}if(!f){break b}b=G[h+12>>2];a=G[h+8>>2]}G[f>>2]=a;G[f+4>>2]=b}i=G[g>>2]}Fa=h+32|0;return i}function dt(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;c=Fa-16|0;Fa=c;G[c+12>>2]=0;a=M(a,48);j=a+757232|0;g=a+757236|0;d=G[g>>2];k=G[a+757264>>2];h=a+757272|0;e=G[h>>2];i=c+8|0;a=Fa+-64|0;Fa=a;b=G[c+12>>2];a:{if((b|0)>0){break a}b=ab(115200);if(!b){b=113;G[c+12>>2]=113;break a}G[a+48>>2]=0;G[a+40>>2]=0;G[a+44>>2]=0;b:{if(Nk(a+8|0,1,0)){break b}G[a+20>>2]=b;G[a+12>>2]=k;G[a+8>>2]=d;while(1){c:{G[a+24>>2]=115200;d=Mk(a+8|0,4);if(d){if((d|0)==1){break c}ff(a+8|0);Wa(b);break b}if((hb(b,1,115200,e)|0)!=115200){ff(a+8|0);Wa(b);break b}else{G[a+20>>2]=b;f=f+115200|0;continue}}break}d:{d=G[a+28>>2];if(f>>>0>=d>>>0){break d}e=hb(b,1,d-f|0,e);d=G[a+28>>2];if((e|0)==(d-f|0)){break d}ff(a+8|0);Wa(b);break b}Wa(b);if(i){G[i>>2]=d}if(ff(a+8|0)){break b}b=G[c+12>>2];break a}b=413;G[c+12>>2]=413}Fa=a- -64|0;if(b){Ua(52912);G[c+12>>2]=106}Wa(G[g>>2]);G[j>>2]=0;G[g>>2]=0;a=G[h>>2];if((a|0)!=G[29763]){Hb(a)}Fa=c+16|0;return G[c+12>>2]}function Pd(a){var b=0,c=0,d=0,e=0,f=0,g=0;A(+a);e=v(1)|0;v(0)|0;d=e&2147483647;if(d>>>0>=1141899264){A(1.5707963267948966);e=v(1)|0;d=v(0)|0;A(+a);b=v(1)|0;v(0)|0;x(0,d|0);x(1,e&2147483647|b&-2147483648);g=+z();A(+a);b=v(1)|0;e=v(0)|0;b=b&2147483647;return(b|0)==2146435072&(e|0)!=0|b>>>0>2146435072?a:g}a:{b:{if(d>>>0<=1071382527){b=-1;if(d>>>0>=1044381696){break b}break a}a=O(a);if(d>>>0<=1072889855){if(d>>>0<=1072037887){a=(a+a+-1)/(a+2);b=0;break b}a=(a+-1)/(a+1);b=1;break b}if(d>>>0<=1073971199){a=(a+-1.5)/(a*1.5+1);b=2;break b}a=-1/a;b=3}f=a*a;c=f*f;g=c*(c*(c*(c*(c*-.036531572744216916+-.058335701337905735)+-.0769187620504483)+-.11111110405462356)+-.19999999999876483);f=f*(c*(c*(c*(c*(c*.016285820115365782+.049768779946159324)+.06661073137387531)+.09090887133436507)+.14285714272503466)+.3333333333333293);if(d>>>0<=1071382527){return a-a*(g+f)}b=b<<3;a=L[b+120320>>3]-(a*(g+f)-L[b+120352>>3]-a);a=(e|0)<0?-a:a}return a}function np(a){var b=0,c=0,d=0;c=a+148|0;while(1){d=b<<2;F[d+c>>1]=0;F[(d|4)+c>>1]=0;b=b+2|0;if((b|0)!=286){continue}break}F[a+2684>>1]=0;F[a+2440>>1]=0;F[a+2756>>1]=0;F[a+2752>>1]=0;F[a+2748>>1]=0;F[a+2744>>1]=0;F[a+2740>>1]=0;F[a+2736>>1]=0;F[a+2732>>1]=0;F[a+2728>>1]=0;F[a+2724>>1]=0;F[a+2720>>1]=0;F[a+2716>>1]=0;F[a+2712>>1]=0;F[a+2708>>1]=0;F[a+2704>>1]=0;F[a+2700>>1]=0;F[a+2696>>1]=0;F[a+2692>>1]=0;F[a+2688>>1]=0;F[a+2556>>1]=0;F[a+2552>>1]=0;F[a+2548>>1]=0;F[a+2544>>1]=0;F[a+2540>>1]=0;F[a+2536>>1]=0;F[a+2532>>1]=0;F[a+2528>>1]=0;F[a+2524>>1]=0;F[a+2520>>1]=0;F[a+2516>>1]=0;F[a+2512>>1]=0;F[a+2508>>1]=0;F[a+2504>>1]=0;F[a+2500>>1]=0;F[a+2496>>1]=0;F[a+2492>>1]=0;F[a+2488>>1]=0;F[a+2484>>1]=0;F[a+2480>>1]=0;F[a+2476>>1]=0;F[a+2472>>1]=0;F[a+2468>>1]=0;F[a+2464>>1]=0;F[a+2460>>1]=0;F[a+2456>>1]=0;F[a+2452>>1]=0;F[a+2448>>1]=0;F[a+2444>>1]=0;G[a+5804>>2]=0;G[a+5808>>2]=0;F[a+1172>>1]=1;G[a+5800>>2]=0;G[a+5792>>2]=0}function Rt(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0;if(!a){return-2}if(G[a+16>>2]==7247){b=-2;if(!(!a|G[a+16>>2]!=7247)){if(G[a+28>>2]){ye(a+100|0);Wa(G[a+40>>2]);Wa(G[a+36>>2])}b=G[a+92>>2];Vd(a,0,0);Wa(G[a+24>>2]);c=fj(G[a+20>>2]);Wa(a);b=c?-1:(b|0)==-5?-5:0}return b|0}b=-2;if(!(!a|G[a+16>>2]!=31153)){a:{if(!G[a+88>>2]){b=0;break a}b=0;G[a+88>>2]=0;c=G[a+80>>2];d=G[a+84>>2];b:{if(G[a+104>>2]){if((Jf(a,0)|0)==-1){break b}}if(!(c|d)){break a}while(1){b=G[a+28>>2];b=(d|0)<=0&b>>>0>c>>>0|(d|0)<0?c:b;if(!e){cb(G[a+36>>2],0,b)}G[a+104>>2]=b;G[a+100>>2]=G[a+36>>2];e=G[a+12>>2];f=G[a+8>>2];g=f+b|0;G[a+8>>2]=g;G[a+12>>2]=f>>>0>g>>>0?e+1|0:e;if((Jf(a,0)|0)==-1){break b}e=1;d=d-(b>>>0>c>>>0)|0;c=c-b|0;if(d|c){continue}break}b=0;break a}b=G[a+92>>2]}if((Jf(a,4)|0)==-1){b=G[a+92>>2]}if(G[a+28>>2]){if(!G[a+44>>2]){ff(a+100|0);Wa(G[a+40>>2])}Wa(G[a+36>>2])}Vd(a,0,0);Wa(G[a+24>>2]);c=fj(G[a+20>>2]);Wa(a);b=(c|0)==-1?-1:b}return b|0}function oi(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;a:{e=xf(a);if((e|0)>=0){d=G[309723];if((d|0)==G[309724]){c=G[309722];b:{if(c){G[309724]=d<<1;d=ub(c,M(d,688));break b}G[309724]=100;d=ab(34400)}if(!d){break a}G[309722]=d;d=G[309723]}G[309723]=d+1;c:{if((d|0)<0){break c}i=G[309722];c=i+M(d,344)|0;G[c+12>>2]=e;G[c+8>>2]=2;G[c+4>>2]=22;G[c>>2]=123;G[c+16>>2]=b;j=G[309730];b=j+M(a,124)|0;G[c+52>>2]=G[b+84>>2];G[c+56>>2]=G[b+88>>2];e=c;c=G[b+92>>2];G[e+60>>2]=c;if((c|0)<=0){break c}b=0;if(c-1>>>0>=3){m=c&-4;e=(M(d,344)+i|0)- -64|0;g=(M(a,124)+j|0)+96|0;while(1){f=b<<2;G[f+e>>2]=G[g+f>>2];h=f|4;G[h+e>>2]=G[g+h>>2];h=f|8;G[h+e>>2]=G[g+h>>2];f=f|12;G[f+e>>2]=G[g+f>>2];b=b+4|0;k=k+4|0;if((m|0)!=(k|0)){continue}break}}c=c&3;if(!c){break c}e=M(d,344)+i|0;a=M(a,124)+j|0;while(1){g=b<<2;G[(g+e|0)- -64>>2]=G[(a+g|0)+96>>2];b=b+1|0;l=l+1|0;if((c|0)!=(l|0)){continue}break}}}else{d=-1}return d}G[309737]=113;return-1}function je(a,b,c,d,e,f,g,h,i,j,k,l){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;l=+l;var m=0,n=0,o=0,p=0;a:{b:{if(j==k){if(j==0){return!d|0}n=G[a+8>>2];if(d){e=n+M(c,168)|0;if(L[e+8>>3]>g|L[e+16>>3]>2];if(O(g)<2147483648){e=~~g}else{e=-2147483648}e=G[m+(e<<2)>>2];m=0;c:{if(!e){break c}m=0;if(!(L[o+8>>3]<=g)){break c}m=0;if(!(L[(n+M(c,168)|0)+16>>3]>=g)){break c}m=0;if(!(+G[e+4>>2]<=f)){break c}m=+G[G[e>>2]+4>>2]>=f}if((m|0)!=(d|0)){break a}p=1;if(!b){break a}if(d){break b}break a}n=G[a+8>>2];if(d){e=n+M(c,168)|0;if(L[e+8>>3]>g|L[e+16>>3]>2];if(O(g)<2147483648){e=~~g}else{e=-2147483648}e=G[m+(e<<2)>>2];m=0;d:{if(!e){break d}m=0;if(!(L[o+8>>3]<=g)){break d}m=0;if(!(L[(n+M(c,168)|0)+16>>3]>=g)){break d}m=0;if(!(+G[e+4>>2]<=f)){break d}m=+G[G[e>>2]+4>>2]>=f}if((m|0)!=(d|0)){break a}p=1;if(!b|!d){break a}}G[a+12>>2]=b}return p|0}function Rb(a,b){var c=0,d=0,e=0,f=0,g=0,h=0;d=Fa-288|0;Fa=d;G[d+280>>2]=0;c=G[b>>2];if((c|0)<=0){e=G[a>>2];c=G[a+4>>2];a:{if((e|0)!=G[c+76>>2]){mb(a,e+1|0,0,b);break a}if(G[c+84>>2]!=1){break a}b:{if((G[c+128>>2]&G[c+132>>2])==-1){break b}c:{if(!G[c+80>>2]){break c}ef(a,2,b);g=_f(a,40853,d+272|0,d+96|0,d+280|0);c=G[a+4>>2];h=G[c+952>>2];e=G[c+956>>2];if((g|0)>0){G[d+272>>2]=h;G[d+276>>2]=e;break c}g=G[d+276>>2];f=G[d+272>>2];if((g|0)>=(e|0)&f>>>0>=h>>>0|(e|0)<(g|0)|((f|0)!=G[c+944>>2]|(g|0)!=G[c+948>>2])){break c}L[d>>3]=+(h>>>0)+ +(e|0)*4294967296;c=d+16|0;Ya(c,71,19648,d);f=c;c=d+176|0;Ob(40853,f,d+96|0,c,b);Hd(a,c,b);c=G[a+4>>2]}f=!G[c+984>>2];c=G[c+988>>2];if(f&(c|0)<=0|(c|0)<0){break b}ef(a,2,b);_f(a,33303,d+264|0,d+96|0,b);c=G[a+4>>2];e=G[c+984>>2];c=G[c+988>>2];if((e|0)==G[d+264>>2]&(c|0)==G[d+268>>2]){break b}Ad(a,33303,e,c,d+96|0,b)}if((rk(a,b)|0)>0){break a}Wf(a,d+284|0,b)}c=G[b>>2]}Fa=d+288|0;return c}function ee(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0,p=0;a:{if(!(!f&(g|0)<=0|(g|0)<0|G[i>>2]>0)){if(!b&(c|0)<=0|(c|0)<0){break a}if(!d&(e|0)<=0|(e|0)<0){G[i>>2]=308;return}j=G[a>>2];k=G[a+4>>2];if((j|0)!=G[k+76>>2]){mb(a,j+1|0,0,i);k=G[a+4>>2]}m=G[k+956>>2];n=G[k+960>>2];p=G[k+952>>2];j=e+g|0;l=d+f|0;j=l>>>0>>0?j+1|0:j;o=G[k+964>>2];l=Bu(l-2|0,j-(l>>>0<2)|0,n,o)+b|0;j=c+Ia|0;j=b>>>0>l>>>0?j+1|0:j;if(p>>>0>>0&(j|0)>=(m|0)|(j|0)>(m|0)){Ua(63178);break a}b:{if(G[i>>2]>0){break b}j=G[k+132>>2];l=G[k+128>>2];c=Au(n,o,b-1|0,c-!b|0)+d|0;b=e+Ia|0;b=c>>>0>>0?b+1|0:b;d=c;c=l+c|0;b=b+j|0;b=c>>>0>>0?b+1|0:b;if(!c&(b|0)<=0|(b|0)<0){G[i>>2]=304;break b}d=G[a>>2];if((d|0)!=G[k+76>>2]){mb(a,d+1|0,0,i);k=G[a+4>>2]}b=b-!c|0;c=c-1|0;d=Du(c,b,2880,0);e=G[k+72>>2];if(!((e|0)>=0&(d|0)==G[((e<<2)+k|0)+1256>>2])){Hc(a,d,0,i)}if(G[i>>2]>0){break b}d=G[a+4>>2];G[d+56>>2]=c;G[d+60>>2]=b}ic(a,f,g,h,i)}return}G[i>>2]=307}function Ce(a){var b=0;if(a){a:{if(!G[a+3312>>2]){break a}b=G[a+9392>>2];if(b){Ce(b);G[a+9392>>2]=0}b=G[321376];if(b){Wa(b);G[321376]=0}b=G[321377];if(b){Wa(b);G[321377]=0}b=G[321378];if(b){Wa(b);G[321378]=0}b=G[321379];if(b){Wa(b);G[321379]=0}b=G[321380];if(b){Wa(b);G[321380]=0}b=G[321381];if(b){Wa(b);G[321381]=0}b=G[321382];if(b){Wa(b);G[321382]=0}b=G[321383];if(b){Wa(b);G[321383]=0}b=G[321384];if(b){Wa(b);G[321384]=0}b=G[321385];if(b){Wa(b);G[321385]=0}b:{if(!a|!G[a+3312>>2]){break b}b=G[a+9288>>2];if(b){Wa(b)}b=G[a+9292>>2];if(b){Wa(b)}b=G[a+9296>>2];if(b){Wa(b)}b=G[a+9300>>2];if(b){Wa(b)}b=G[a+9304>>2];if(b){Wa(b)}b=G[a+9308>>2];if(b){Wa(b)}b=G[a+9312>>2];if(b){Wa(b)}b=G[a+9316>>2];if(b){Wa(b)}b=G[a+9320>>2];if(b){Wa(b)}b=G[a+9324>>2];if(!b){break b}Wa(b)}b=G[a+9400>>2];if(b){Wa(b)}b=G[a+4060>>2];if(b){Wa(b)}b=G[a+4056>>2];if(b){Wa(b)}b=G[a+3168>>2];if(b){tg(b)}b=G[a+3172>>2];if(!b){break a}tg(b)}Wa(a)}}function zj(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;f=G[b+4>>2];a:{if(G[b>>2]!=137){j=1;if(Aj(b)){break a}}if((f|0)<=0){return 0}o=f&-2;p=f&1;d=f-1|0;i=G[b+24>>2];while(1){g=(l<<3)+c|0;G[g>>2]=0;G[g+4>>2]=0;k=0;j=0;h=0;if(d){while(1){m=(e<<3)+i|0;n=j<<3;k=L[m>>3]*L[n+a>>3]+k;L[g>>3]=k;k=L[m+8>>3]*L[(n|8)+a>>3]+k;L[g>>3]=k;e=e+2|0;j=j+2|0;h=h+2|0;if((o|0)!=(h|0)){continue}break}}if(p){L[g>>3]=L[(e<<3)+i>>3]*L[(j<<3)+a>>3]+k;e=e+1|0}l=l+1|0;if((f|0)!=(l|0)){continue}break}if((f|0)<=0){return 0}a=G[b+8>>2];j=0;e=0;if(d>>>0>=3){g=f&-4;h=0;while(1){b=e<<3;d=b+c|0;L[d>>3]=L[a+b>>3]+L[d>>3];d=b|8;i=d+c|0;L[i>>3]=L[a+d>>3]+L[i>>3];d=b|16;i=d+c|0;L[i>>3]=L[a+d>>3]+L[i>>3];b=b|24;d=b+c|0;L[d>>3]=L[a+b>>3]+L[d>>3];e=e+4|0;h=h+4|0;if((g|0)!=(h|0)){continue}break}}f=f&3;if(!f){break a}b=0;while(1){h=e<<3;g=h+c|0;L[g>>3]=L[a+h>>3]+L[g>>3];e=e+1|0;b=b+1|0;if((f|0)!=(b|0)){continue}break}}return j}function ij(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0;if(G[321436]){h=G[24367];hb(89086,25,1,h);$a(h)}if(!H[3706192]){G[926552]=442745336;G[926553]=1078765020;G[926550]=-1571644103;G[926551]=1066524486;E[3706192]=1}if(G[321436]){h=G[24367];hb(89165,24,1,h);$a(h)}a:{if(f){e=(e+-1950)*.01;g=e*e;g=e*g*.00182+(g*-.0033+(e*-46.85+84404.84));break a}e=(e+-2e3)*.01;g=e*e;g=e*g*.001813+(g*-59e-5+(e*-46.815+84381.448))}e=L[463275];g=g/3600*e;j=eb(g);b=e*b;k=ib(b);l=j*k;e=e*a;i=ib(e);a=eb(b);b=ib(g);g=a*-i;i=b*g;a=Db(-(j*g-b*k),a*eb(e));b=L[463276];e=a*b;if(e<0){while(1){e=e+360;if(e<0){continue}break}}L[c>>3]=e;if(e>360){while(1){e=e+-360;if(e>360){continue}break}L[c>>3]=e}a=l+i;e=O(a);if(e>1){L[d>>3]=a*90/e;G[c>>2]=0;G[c+4>>2]=0;return}a=b*fc(a);L[d>>3]=a;b:{if(!(O(a)>=90)){break b}G[c>>2]=0;G[c+4>>2]=0;a=L[d>>3];if(a>90){G[d>>2]=0;G[d+4>>2]=1079410688;return}if(!(a<-90)){break b}G[d>>2]=0;G[d+4>>2]=-1068072960}}function Jf(a,b){var c=0,d=0,e=0,f=0,g=0;a:{b:{if(!G[a+28>>2]){c=-1;if((Aq(a)|0)==-1){break b}}if(G[a+44>>2]){c=0;d=G[a+104>>2];if(!d){break b}e=G[a+100>>2];while(1){b=lg(G[a+20>>2],e,d>>>0<1073741824?d:1073741824);if((b|0)<0){break a}d=G[a+104>>2]-b|0;G[a+104>>2]=d;e=b+G[a+100>>2]|0;G[a+100>>2]=e;if(d){continue}break}break b}f=a+100|0;c=G[a+116>>2];g=(b|0)!=4;while(1){c:{if(!b|!((d|0)==1|g)?c:0){break c}e=G[a+112>>2];d=G[a+4>>2];if(e>>>0>d>>>0){while(1){c=e-d|0;c=lg(G[a+20>>2],d,(c|0)<1073741824?c:1073741824);if((c|0)<0){break a}d=c+G[a+4>>2]|0;G[a+4>>2]=d;e=G[a+112>>2];if(d>>>0>>0){continue}break}c=G[a+116>>2]}if(c){break c}c=G[a+28>>2];G[a+116>>2]=c;e=G[a+40>>2];G[a+112>>2]=e;G[a+4>>2]=e}d=Mk(f,b);if((d|0)==-2){Vd(a,-2,4605);return-1}e=c;c=G[a+116>>2];if((e|0)!=(c|0)){continue}break}c=0;if((b|0)!=4){break b}kp(f)}return c}b=a;a=G[48624];Vd(b,-1,I[((a>>>0>149?0:a)<<1)+143920>>1]+142088|0);return-1}function ot(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0,g=0;e=Fa-16|0;Fa=e;a:{b:{c:{d:{if(!Xa(a,2749)){break d}if(!Xa(a,2675)){break d}if(Xa(a,2712)){break c}}f=G[29763];break b}G[e+12>>2]=6433655;c=ac(a,13287);if(c){Hb(c);a=105;break a}f=ac(a,e+12|0);if(f){break b}a=105;break a}G[b>>2]=-1;a=0;e:{f:{g:{while(1){d=M(a,48)+757232|0;if(!G[d>>2]){c=a;break g}c=a+1|0;d=M(c,48)+757232|0;if(!G[d>>2]){break g}c=a+2|0;d=M(c,48)+757232|0;if(!G[d>>2]){break g}c=a+3|0;d=M(c,48)+757232|0;if(!G[d>>2]){break g}c=a+4|0;d=M(c,48)+757232|0;if(!G[d>>2]){break g}a=a+5|0;if((a|0)!=1e4){continue}break}a=103;break f}G[b>>2]=c;a=M(c,48);c=a+757236|0;G[d>>2]=c;d=a+757244|0;G[a+757240>>2]=d;g=c;c=ab(2880);G[g>>2]=c;if(c){break e}Ua(57797);a=104}Ua(52859);break a}G[d>>2]=2880;c=a+757256|0;G[c>>2]=0;G[c+4>>2]=0;G[a+757248>>2]=2880;c=a+757264|0;G[c>>2]=0;G[c+4>>2]=0;G[a+757252>>2]=17;G[M(G[b>>2],48)+757272>>2]=f;a=0}Fa=e+16|0;return a|0}function qk(a,b,c,d,e,f){var g=0,h=0,i=0,j=0;i=Fa-16|0;Fa=i;a:{if(G[f>>2]>0){break a}h=G[a>>2];g=G[a+4>>2];b:{c:{if((h|0)!=G[g+76>>2]){mb(a,h+1|0,0,f);break c}if((G[g+128>>2]&G[g+132>>2])!=-1){break c}if((Rb(a,f)|0)>0){break b}}d:{if((b|0)>0){g=G[a+4>>2];if(G[g+936>>2]>=(b|0)){break d}}G[f>>2]=302;break a}if(G[f>>2]>0){break a}b=b-1|0;h=G[g+968>>2];e:{f:{j=G[a>>2];if(!(G[g+104>>2]|G[g+108>>2]?1:j)){break f}g:{h:{if(G[g+76>>2]!=(j|0)){mb(a,j+1|0,0,f);break h}if((G[g+128>>2]&G[g+132>>2])!=-1){break h}if((Rb(a,f)|0)>0){break g}}a=G[a+4>>2];g=G[a+1088>>2]?0:G[a+80>>2]}if(G[f>>2]>0){break a}if((g|0)!=1){break f}Gd((h+M(b,160)|0)+140|0,c,i+8|0,i+12|0,f);a=G[i+8>>2];G[e>>2]=a;G[e+4>>2]=a>>31;a=1;b=0;if(d){break e}break b}if(c){G[c>>2]=G[(h+M(b,160)|0)+80>>2]}if(e){a=G[(h+M(b,160)|0)+152>>2];G[e>>2]=a;G[e+4>>2]=a>>31}if(!d){break b}b=h+M(b,160)|0;a=G[b+88>>2];b=G[b+92>>2]}G[d>>2]=a;G[d+4>>2]=b}}Fa=i+16|0}function tr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;a:{if(G[c+4>>2]==303){g=L[c+24>>3];break a}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=77;E[c+1|0]=79;E[c+2|0]=76;E[c+3|0]=0;E[c+4|0]=47;E[c+5|0]=1;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;g=L[c+24>>3];if(g==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;g=57.29577951308232}G[c+1892>>2]=123;G[c+1888>>2]=124;G[c+144>>2]=1841940611;G[c+148>>2]=1071931184;L[c+136>>3]=90/g;f=g*1.4142135623730951;L[c+112>>3]=f;L[c+128>>3]=1/f;L[c+120>>3]=f/90}i=d;g=b/g;f=2-g*g;b:{c:{if(f<=1e-12){d=2;if(f<-1e-12){break b}f=0;h=0;if(!(O(a)>1e-12)){break c}break b}f=V(f);h=L[c+136>>3]*a/f}L[i>>3]=h;a=L[c+128>>3]*b;b=O(a);d:{if(b>1){d=2;if(b>1.000000000001){break b}a=g*f/3.141592653589793+(a<0?-1:1);break d}a=fc(a)*L[c+144>>3]+g*f/3.141592653589793}b=O(a);if(b>1){d=2;if(b>1.000000000001){break b}a=a<0?-1:1}j=e,k=Bc(a),L[j>>3]=k;d=0}return d|0}function yl(a,b,c,d){var e=0,f=0;f=Fa-16|0;Fa=f;G[f+12>>2]=0;e=G[a+68>>2];a:{if(!e){break a}$a(e);e=G[a+68>>2];if((e|0)==G[24367]|(e|0)==G[29763]){break a}Hb(e)}e=G[a+64>>2];b:{if(!e){break b}$a(e);e=G[a+64>>2];if((e|0)==G[29763]|(e|0)==G[24367]){break b}Hb(e)}pb(a);pb(G[c+104>>2]);pb(G[c+108>>2]);pb(G[c+84>>2]);pb(G[c+88>>2]);pb(G[c+112>>2]);pb(G[c+52>>2]);pb(G[c+56>>2]);a=G[c+68>>2];if((a|0)!=G[b+68>>2]){pb(a)}a=G[c+60>>2];if((a|0)!=G[b+60>>2]){pb(a)}Ce(G[c+120>>2]);Hh(G[c+116>>2]);c:{if(!G[c+56>>2]){break c}a=G[c+124>>2];if(!a){break c}_e(a,f+12|0)}pb(c);pb(G[b+104>>2]);pb(G[b+108>>2]);pb(G[b+84>>2]);pb(G[b+88>>2]);pb(G[b+112>>2]);pb(G[b+52>>2]);pb(G[b+56>>2]);pb(G[b+60>>2]);pb(G[b+68>>2]);Ce(G[b+120>>2]);Hh(G[b+116>>2]);d:{if(!G[b+56>>2]){break d}a=G[b+124>>2];if(!a){break d}_e(a,f+12|0)}pb(b);pb(G[d+8>>2]);pb(G[d+12>>2]);pb(G[d+16>>2]);pb(G[d+20>>2]);pb(G[d>>2]);pb(d);Fa=f+16|0}function Sh(a,b,c,d,e,f,g){var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;if((a|0)<=0){return 0}l=L[b>>3];h=!(g?l>=f:f>=l);i=(a<<3)-8|0;o=i+c|0;j=L[b+i>>3];a:{if(g?j>=f:f>=j){if(!h){L[d>>3]=l;L[e>>3]=L[c>>3];k=1;i=1;break a}p=L[c>>3];m=L[o>>3];L[d>>3]=f;L[e>>3]=m+(p-m)*(f-j)/(l-j);i=1;break a}i=0;if(h){break a}p=L[c>>3];m=L[o>>3];L[d>>3]=f;L[e>>3]=m+(p-m)*(f-j)/(l-j);L[d+8>>3]=L[b>>3];L[e+8>>3]=L[c>>3];k=1;i=2}o=1;if((a|0)!=1){while(1){h=o<<3;q=h+b|0;j=L[q>>3];n=(g?j>=f:f>=j)^1;b:{c:{if(k){if(!n){L[(i<<3)+d>>3]=j;j=L[c+h>>3];h=i;n=1;k=1;break c}k=h-8|0;l=L[k+b>>3];p=L[c+h>>3];m=L[c+k>>3];L[(i<<3)+d>>3]=f;j=m+(p-m)*(f-l)/(j-l);h=i;n=1;k=0;break c}k=0;if(n){break b}k=h-8|0;l=L[k+b>>3];n=c+h|0;p=L[n>>3];m=L[c+k>>3];h=i<<3;L[h+d>>3]=f;L[e+h>>3]=m+(p-m)*(f-l)/(j-l);h=i+1|0;L[(h<<3)+d>>3]=L[q>>3];j=L[n>>3];n=2;k=1}L[(h<<3)+e>>3]=j;i=i+n|0}o=o+1|0;if((o|0)!=(a|0)){continue}break}}return i}function Yd(){var a=0,b=0,c=0,d=0,e=0,f=0;c=Fa-48|0;Fa=c;if(G[309728]>0){a=G[309729];a:{if(a){Wa(a);break a}G[c+36>>2]=955;G[c+32>>2]=30721;kb(74522,c+32|0)}b=G[309730];d=G[309728];if((d|0)>0){a=0;while(1){f=M(a,124);e=f+b|0;if(G[e+116>>2]){b:{if(G[e+84>>2]!=262){break b}b=G[G[e+120>>2]>>2];if(b){Wa(b);break b}G[c+20>>2]=959;G[c+16>>2]=30721;kb(74700,c+16|0)}Wa(G[(G[309730]+f|0)+116>>2]);d=G[309728];b=G[309730]}a=a+1|0;if((d|0)>(a|0)){continue}break}}c:{if(b){Wa(b);break c}G[c+4>>2]=962;G[c>>2]=30721;kb(74483,c)}G[309728]=0}a=G[309723];if((a|0)>0){while(1){d:{e:{f:{b=G[309722];a=a-1|0;d=b+M(a,344)|0;switch(G[d>>2]-1032|0){case 1:break e;case 0:break f;default:break d}}b=G[(b+M(G[d+12>>2],344)|0)+88>>2];if(!b){break d}Wa(b);break d}qi(G[(b+M(G[d+12>>2],344)|0)+88>>2])}if(a){continue}break}G[309723]=0}a=G[309722];if(a){Wa(a)}G[309736]=-1;G[309722]=0;G[309731]=0;Fa=c+48|0}function tn(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;A(+a);b=v(1)|0;d=v(0)|0;a:{b:{c:{d:{if((b|0)>0|(b|0)>=0){e=b;if(b>>>0>1048575){break d}}if(!(b&2147483647|d)){return-1/(a*a)}if((b|0)>0|(b|0)>=0){break c}return(a-a)/0}if(e>>>0>2146435071){break a}b=1072693248;k=-1023;if((e|0)!=1072693248){b=e;break b}if(d){break b}return 0}A(+(a*0x40000000000000));b=v(1)|0;d=v(0)|0;k=-1077}b=b+614242|0;l=+((b>>>20|0)+k|0);f=l*.30102999566361177;x(0,d|0);x(1,(b&1048575)+1072079006|0);c=+z()+-1;g=c*(c*.5);h=c/(c+2);i=h*h;a=i*i;A(+(c-g));b=v(1)|0;v(0)|0;x(0,0);x(1,b|0);j=+z();m=j*.4342944818781689;n=f+m;a=h*(g+(a*(a*(a*.15313837699209373+.22222198432149784)+.3999999999940942)+i*(a*(a*(a*.14798198605116586+.1818357216161805)+.2857142874366239)+.6666666666666735)))+(c-j-g);a=n+(m+(f-n)+(a*.4342944818781689+(l*3694239077158931e-28+(a+j)*25082946711645275e-27)))}return a}function Nj(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;e=Fa-272|0;Fa=e;a:{d=G[c>>2];if((d|0)>0){break a}f=ab(1024);if(!f){Ua(42562);d=113;G[c>>2]=113;break a}E[f|0]=0;b:{k=ac(a,13287);if(k){j=1024;a=1;break b}G[e>>2]=a;a=e+16|0;Ya(a,256,42992,e);Ua(a);Wa(f);d=104;G[c>>2]=104;break a}while(1){c:{if(vc(e+16|0,256,k)){d=Va(e+16|0);if(!(!a|(d|0)<2|H[e+16|0]!=47)){a=1;if(H[e+17|0]==47){continue}}l=1;a=0;d:{if((d|0)<=0){break d}e:{g=d-1|0;h=g+(e+16|0)|0;switch(H[h|0]-10|0){case 0:case 3:break e;default:break d}}l=0;E[h|0]=0;a=1;if((d|0)<2){d=0;break d}h=d-2|0;d=g;f:{g=h+(e+16|0)|0;switch(H[g|0]-10|0){case 0:case 3:break f;default:break d}}E[g|0]=0;d=h}d=d+i|0;if((d+3|0)<(j|0)){break c}j=j+256|0;f=ub(f,j);if(f){break c}Ua(42562);G[c>>2]=113;f=0}Hb(k);G[b>>2]=f;d=G[c>>2];break a}Za(f+i|0,e+16|0);if(!l){i=d+f|0;E[i|0]=32;E[i+1|0]=0;d=d+1|0}i=d;continue}}Fa=e+272|0;return d}function wu(a,b){a=a|0;b=b|0;var c=0,d=0,e=0;a:{if((b|0)>0){c=Fa-16|0;Fa=c;E[c+15|0]=0;bi(a,b);e=qj(a,c+15|0);Fa=c+16|0;break a}bi(a,256e3);e=rd(a)}b:{if(!e){b=G[968816];if(b){a=G[968817];break b}b=10;G[968816]=10;a=ab(655440);G[968817]=a;if(a){break b}return-4}sm(e,e?G[e+3312>>2]?e+3848|0:0:0);c:{b=G[968816];if(b){a=G[968817];break c}b=10;G[968816]=10;a=ab(655440);G[968817]=a;if(a){break c}return-4}d=G[47759];while(1){if((b|0)>(d|0)){b=1;c=d;d:{if((d|0)<=1){break d}while(1){c=b;if(!G[M(b,65544)+a>>2]){break d}b=b+1|0;if((d|0)!=(b|0)){continue}break}c=d}a=M(c,65544)+a|0;E[a+8|0]=0;G[a+4>>2]=0;G[a>>2]=e;if((d|0)==(c|0)){G[47759]=d+1}else{d=c}return d|0}b=b+10|0;G[968816]=b;a=ub(a,M(b,65544));G[968817]=a;if(a){continue}break}return-3}c=G[47759];while(1){if((b|0)>(c|0)){return-1}b=b+10|0;G[968816]=b;a=ub(a,M(b,65544));G[968817]=a;if(a){continue}break}return-3}function ii(a){var b=0,c=0,d=0;d=Fa-16|0;Fa=d;b=a;a:while(1){b:{c:{d:{e:{f:{g:{h:{i:{j:{b=G[b>>2];c=H[b|0];if(c>>>0<=90){k:{switch(c-34|0){case 6:break j;case 1:case 2:case 3:case 4:break e;case 5:break g;case 0:break h;default:break k}}if(c){break e}c=1;break b}switch(c-123|0){case 2:break d;case 1:break e;case 0:break i;default:break f}}c=1;G[d+12>>2]=b+1;b=d+12|0;if(!gi(b)){continue}break b}c=1;G[d+12>>2]=b+1;b=d+12|0;if(!ii(b)){continue}break b}b=b+1|0;G[d+12>>2]=b;while(1){c=H[b|0];if(!c){c=1;break b}if((c|0)==34){G[d+12>>2]=b+1;b=d+12|0;continue a}else{b=b+1|0;continue}}}b=b+1|0;G[d+12>>2]=b;while(1){c=H[b|0];if(!c){c=1;break b}if((c|0)==39){G[d+12>>2]=b+1;b=d+12|0;continue a}else{b=b+1|0;continue}}}if((c|0)==91){break c}}G[d+12>>2]=b+1;b=d+12|0;continue}G[a>>2]=b+1;c=0;break b}c=1;G[d+12>>2]=b+1;b=d+12|0;if(!hi(b)){continue}}break}Fa=d+16|0;return c}function hi(a){var b=0,c=0,d=0;d=Fa-16|0;Fa=d;b=a;a:while(1){b:{c:{d:{e:{f:{g:{h:{i:{j:{b=G[b>>2];c=H[b|0];if(c>>>0<=90){k:{switch(c-34|0){case 6:break j;case 1:case 2:case 3:case 4:break e;case 5:break g;case 0:break h;default:break k}}if(c){break e}c=1;break b}switch(c-91|0){case 2:break d;case 1:break e;case 0:break i;default:break f}}c=1;G[d+12>>2]=b+1;b=d+12|0;if(!gi(b)){continue}break b}c=1;G[d+12>>2]=b+1;b=d+12|0;if(!hi(b)){continue}break b}b=b+1|0;G[d+12>>2]=b;while(1){c=H[b|0];if(!c){c=1;break b}if((c|0)==34){G[d+12>>2]=b+1;b=d+12|0;continue a}else{b=b+1|0;continue}}}b=b+1|0;G[d+12>>2]=b;while(1){c=H[b|0];if(!c){c=1;break b}if((c|0)==39){G[d+12>>2]=b+1;b=d+12|0;continue a}else{b=b+1|0;continue}}}if((c|0)==123){break c}}G[d+12>>2]=b+1;b=d+12|0;continue}G[a>>2]=b+1;c=0;break b}c=1;G[d+12>>2]=b+1;b=d+12|0;if(!ii(b)){continue}}break}Fa=d+16|0;return c}function go(a,b){var c=0,d=0,e=0,f=0,g=0,h=0;e=Fa-112|0;Fa=e;f=G[b>>2];a:{if((f|0)>0){break a}g=Va(a);if(g>>>0<9){break a}c=8;while(1){d=c+1|0;h=a+c|0;c=E[h|0];if((c-127&255)>>>0<=160){G[e+4>>2]=c;G[e>>2]=d;Ya(e+16|0,81,33087,e);c=63637;b:{c:{d:{e:{f:{g:{h:{i:{j:{d=H[h|0];switch(d|0){case 11:break h;case 10:break i;case 9:break j;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:break b;case 0:break c;case 27:break e;case 13:break f;case 12:break g;default:break d}}c=63651;break c}c=63618;break c}c=63221;break c}c=63599;break c}c=53753;break c}c=63583;break c}if((d|0)!=127){break b}c=63567}d=e+16|0;qb(d,c,80-Va(d)|0)}d=e+16|0;tb(5,d);a=rb(d,a,80);E[a+80|0]=0;tb(5,a);f=207;G[b>>2]=207;break a}c=d;if((d|0)!=(g|0)){continue}break}}Fa=e+112|0;return f}function xf(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;a:{c=G[309723];if((c|0)==G[309724]){b=G[309722];b:{if(b){G[309724]=c<<1;c=ub(b,M(c,688));break b}G[309724]=100;c=ab(34400)}if(!c){break a}G[309722]=c;c=G[309723]}G[309723]=c+1;c:{if((c|0)<0){break c}i=G[309722];b=i+M(c,344)|0;G[b+4>>2]=0;G[b+8>>2]=0;G[b>>2]=0-a;j=G[309730];d=j+M(a,124)|0;G[b+52>>2]=G[d+84>>2];G[b+56>>2]=G[d+88>>2];d=G[d+92>>2];G[b+60>>2]=d;if((d|0)<=0){break c}b=0;if(d-1>>>0>=3){m=d&-4;g=(M(c,344)+i|0)- -64|0;f=(M(a,124)+j|0)+96|0;while(1){e=b<<2;G[e+g>>2]=G[f+e>>2];h=e|4;G[h+g>>2]=G[f+h>>2];h=e|8;G[h+g>>2]=G[f+h>>2];e=e|12;G[e+g>>2]=G[f+e>>2];b=b+4|0;k=k+4|0;if((m|0)!=(k|0)){continue}break}}d=d&3;if(!d){break c}g=M(c,344)+i|0;a=M(a,124)+j|0;while(1){f=b<<2;G[(f+g|0)- -64>>2]=G[(a+f|0)+96>>2];b=b+1|0;l=l+1|0;if((d|0)!=(l|0)){continue}break}}return c}G[309737]=113;return-1}function ks(a,b,c,d,e,f,g,h){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;m=Fa-16|0;Fa=m;G[m+12>>2]=h;a:{i=G[a+8>>2];p=(G[a>>2]+M(c,3)|0)-2|0;k=M(p,168);j=i+k|0;b=G[j+32>>2];if(b){break a}b=lb(1e3,8);G[j+32>>2]=b;h=0;G[j+28>>2]=0;j=1e3;while(1){if((h|0)>=(j|0)){j=j+1e3|0;b=ub(b,j<<3);i=G[a+8>>2];G[(k+i|0)+32>>2]=b}l=G[m+12>>2]+7&-8;G[m+12>>2]=l+8;h=i+k|0;b=G[h+32>>2];o=G[h+28>>2];n=L[l>>3];L[b+(o<<3)>>3]=n;b:{if(!(O(n+-9007199254740992)<=1e-15)){break b}l=o-1|0;if(!(O(L[(l<<3)+b>>3]+-9007199254740992)<=1e-15)){break b}G[h+28>>2]=l;h=M(p,168);b=h+G[a+8>>2]|0;b=ub(G[b+32>>2],G[b+28>>2]<<3);i=G[a+8>>2];G[(h+i|0)+32>>2]=b;break a}l=h;h=o+1|0;G[l+28>>2]=h;continue}}k=G[(i+k|0)+28>>2];if((k|0)>0){h=0;i=0;while(1){j=h<<3;Pm(a,h,c+i|0,d,e,n,n,L[j+b>>3],L[(j|8)+b>>3]);i=i+1|0;h=h+2|0;if((k|0)>(h|0)){continue}break}}Fa=m+16|0}function Cn(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;g=Fa-8032|0;Fa=g;Cb(a,41,40853,g+8024|0,0,e);G[g+8>>2]=1589294263;G[g+12>>2]=-1196933592;G[c>>2]=157828351;G[c+4>>2]=1201345881;G[d>>2]=157828351;G[d+4>>2]=-946137767;h=G[g+8024>>2];if(h){m=1;while(1){k=(h|0)<100?h:100;bg(a,82,b,m,m>>31,1,0,k,k>>31,g+8|0,g+16|0,g+8028|0,e);a:{if((h|0)<=0){break a}l=(k|0)>1?k:1;o=l&1;h=0;j=L[g+8>>3];if((k|0)>=2){p=l&2147483646;l=0;while(1){n=h<<3;f=L[n+(g+16|0)>>3];if(f!=j){i=L[c>>3];L[c>>3]=f>i?i:f;i=L[d>>3];L[d>>3]=f>3];if(f!=j){i=L[c>>3];L[c>>3]=f>i?i:f;i=L[d>>3];L[d>>3]=f>3];if(f==j){break a}j=L[c>>3];L[c>>3]=f>j?j:f;j=L[d>>3];L[d>>3]=f>2]-k|0;G[g+8024>>2]=h;m=k+m|0;if(h){continue}break}}Fa=g+8032|0;return G[e>>2]}function xq(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0;c=-1;a:{b:{c:{switch(G[a+92>>2]+5|0){case 0:case 5:break c;default:break b}}c=0;if(G[a+64>>2]){break b}d=G[a+104>>2];if(d){h=d-1|0;c=G[a+100>>2];b=G[a+36>>2];f=d&7;if(f){while(1){E[b|0]=H[c|0];d=d-1|0;b=b+1|0;c=c+1|0;g=g+1|0;if((g|0)!=(f|0)){continue}break}}if(h>>>0>=7){while(1){E[b|0]=H[c|0];E[b+1|0]=H[c+1|0];E[b+2|0]=H[c+2|0];E[b+3|0]=H[c+3|0];E[b+4|0]=H[c+4|0];E[b+5|0]=H[c+5|0];E[b+6|0]=H[c+6|0];E[b+7|0]=H[c+7|0];b=b+8|0;c=c+8|0;d=d-8|0;if(d){continue}break}}b=G[a+104>>2]}c=G[a+28>>2]-b|0;d=G[a+36>>2]+b|0;d:{while(1){b=c-e|0;b=ql(G[a+20>>2],d+e|0,b>>>0<1073741824?b:1073741824);if((b|0)>0){e=b+e|0;if(c>>>0>e>>>0){continue}break d}break}if((b|0)<0){break a}G[a+64>>2]=1}G[a+100>>2]=G[a+36>>2];G[a+104>>2]=G[a+104>>2]+e;c=0}return c}b=a;a=G[48624];Vd(b,-1,I[((a>>>0>149?0:a)<<1)+143920>>1]+142088|0);return-1}function Qb(a,b){var c=0,d=0,e=0,f=0,g=0;f=Fa-16|0;Fa=f;G[f+12>>2]=999;G[f+8>>2]=0;a:{if(!a){G[b>>2]=115;a=115;break a}if(G[G[a+4>>2]+16>>2]!=555){G[b>>2]=114;a=114;break a}b:{if(G[b>>2]>0){Xf(a,f+12|0);break b}Xf(a,b)}c=G[a+4>>2];d=G[c+8>>2]-1|0;G[c+8>>2]=d;c:{if(!d){sh(a,1,b);d=G[a+4>>2];if(!(!(Ja[G[(M(G[d+4>>2],84)+1240576|0)+56>>2]](G[d>>2])|0)|G[b>>2]>0)){G[b>>2]=110;Ua(50509);Ua(G[G[a+4>>2]+12>>2])}d=G[a+4>>2];d:{while(1){e:{e=g<<2;c=e+1243184|0;if(G[c>>2]==(d|0)){break e}e=e+1243184|0;c=e+4|0;if(G[c>>2]==(d|0)){break e}c=e+8|0;if(G[c>>2]==(d|0)){break e}c=e+12|0;if(G[c>>2]==(d|0)){break e}c=e+16|0;if(G[c>>2]==(d|0)){break e}g=g+5|0;if((g|0)!=1e4){continue}break d}break}G[c>>2]=0;d=G[a+4>>2]}Wa(G[d+1252>>2]);Wa(G[G[a+4>>2]+96>>2]);Wa(G[G[a+4>>2]+12>>2]);Wa(G[a+4>>2]);break c}sh(a,0,G[b>>2]>0?f+8|0:b)}Wa(a);a=G[b>>2]}Fa=f+16|0;return a}function Bl(a,b){var c=0,d=0,e=0,f=0,g=0;d=Fa+-64|0;Fa=d;G[d+60>>2]=0;a:{if(Va(3780288)>>>0<=1){if((a|0)==3780288){break a}rb(a,3780288,b-1|0);break a}if(!(H[3780288]!=48|H[3780289]!=98)){g=ti(3780290,d+60|0,2,-1,0);if(H[G[d+60>>2]]){c=G[24367];b:{if(H[3780288]){G[d+52>>2]=3780288;G[d+48>>2]=19850;Tb(c,69475,d+48|0);break b}G[d+32>>2]=19850;Tb(c,68751,d+32|0)}c=G[945062];c:{if(!c){break c}f=c+(G[945063]<<2)|0;c=G[f>>2];if(!c){break c}G[c+16>>2]=0;E[G[c+4>>2]]=0;E[G[c+4>>2]+1|0]=0;G[c+44>>2]=0;G[c+28>>2]=1;e=G[c+4>>2];G[c+8>>2]=e;if((c|0)!=G[f>>2]){break c}c=G[c+16>>2];G[945064]=e;G[950324]=c;G[945070]=e;G[945057]=G[G[f>>2]>>2];E[3780260]=H[e|0]}E[3801300]=1}G[d+16>>2]=g;Ya(a,b,3726,d+16|0);if(!(Va(a)>>>0<2|H[a|0]!=48)&(H[a+1|0]|32)==120){break a}G[d>>2]=g;Ya(a,b,3724,d);break a}if((a|0)==3780288){break a}rb(a,3780288,b-1|0)}Fa=d- -64|0}function El(a){var b=0,c=0,d=0;a:{b:{if(G[949192]==1970171489&G[949193]==7566700){break b}b=1;if(G[949192]==7892834){break b}if(!nb(3796768,22631,7)){b=2;break b}b=3;if(G[949192]==1768713317&G[949193]==6648688){break b}b=5;if(!nb(3796768,21330,5)){b=4;break b}if(!nb(3796768,31649,6)){break b}b=6;if(G[949192]==6646128){break b}if(!nb(3796768,23665,6)){b=7;break b}if(!nb(3796768,4710,6)){b=8;break b}b=9;if(G[949192]==2037149552&G[949193]==7237479){break b}if(!nb(3796768,26853,6)){b=10;break b}if(!nb(3796768,31648,7)){b=11;break b}if(!nb(3796768,31641,7)){b=12;break b}if(nb(3796768,31634,7)){break a}b=13}c=G[(b<<2)+188928>>2];if((c|0)==(a|0)){break a}if((a|0)<(c|0)){return b+1|0}d=-1;c:{switch(G[(b<<2)+188800>>2]-101|0){case 10:return(a&-2147483647)==1?-1:b+1|0;default:return b+1|0;case 20:break a;case 0:break c}}d=a&1?b+1|0:-1}return d}function Zj(a,b,c,d,e){var f=0,g=0,h=0,i=0;f=Fa-176|0;Fa=f;if(!((c|0)<=0|G[e>>2]>0)){while(1){G[f+172>>2]=0;e=h+1|0;g=f+96|0;i=f+172|0;zb(35417,e,g,i);Cb(b,16,g,f+16|0,0,i);if(G[f+172>>2]){G[f+172>>2]=0;h=(h<<2)+d|0;g=f+96|0;i=f+172|0;zb(35402,G[h>>2],g,i);Cb(a,16,g,f+16|0,0,i);if(!G[f+172>>2]){g=f+96|0;i=f+172|0;zb(35417,e,g,i);xd(b,16,g,f+16|0,21257,i)}G[f+172>>2]=0;i=G[h>>2];h=f+96|0;g=f+172|0;zb(33357,i,h,g);Cb(a,16,h,f+16|0,0,g);if(!G[f+172>>2]){h=f+96|0;g=f+172|0;zb(33363,e,h,g);xd(b,16,h,f+16|0,5624,g)}G[f+172>>2]=0;G[f+8>>2]=0;G[f+12>>2]=1072693248;h=f+96|0;g=f+172|0;zb(32948,e,h,g);i=f+8|0;xd(b,82,h,i,16901,g);G[f+172>>2]=0;G[f+8>>2]=0;G[f+12>>2]=1072693248;zb(34813,e,h,g);xd(b,82,h,i,20205,g);G[f+8>>2]=0;G[f+12>>2]=1072693248;G[f+172>>2]=0;zb(33351,e,h,g);xd(b,82,h,i,19744,g)}h=e;if((h|0)!=(c|0)){continue}break}}Fa=f+176|0}function Zg(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;a=(L[c+224>>3]-(L[c+176>>3]+a+-1+.5)*L[c+192>>3])/1e3;g=a*a;b=((L[c+184>>3]+b+-1+.5)*L[c+200>>3]-L[c+248>>3])/1e3;h=b*b;f=g+h;i=b*h;j=a*g;k=L[c+160>>3];l=(f*(a*L[c+352>>3])*f+(a*L[c+344>>3]*f+(L[c+336>>3]*i+(a*L[c+328>>3]*h+(g*L[c+320>>3]*b+(L[c+312>>3]*j+(L[c+304>>3]*f+(L[c+296>>3]*h+(a*L[c+288>>3]*b+(L[c+280>>3]*g+(L[c+272>>3]+(L[c+256>>3]*a+L[c+264>>3]*b))))))))))))/206264.8062470964/eb(k);b=(f*(b*L[c+512>>3])*f+(b*L[c+504>>3]*f+(L[c+496>>3]*j+(b*L[c+488>>3]*g+(h*L[c+480>>3]*a+(L[c+472>>3]*i+(L[c+464>>3]*f+(L[c+456>>3]*g+(a*L[c+448>>3]*b+(L[c+440>>3]*h+(L[c+432>>3]+(L[c+416>>3]*b+a*L[c+424>>3]))))))))))))/206264.8062470964;f=Mc(k);g=1-b*f;h=Db(l,g);a=h+L[c+152>>3];L[d>>3]=(a<0?a+6.28318530717959:a)/.01745329252;m=e,n=Pd(eb(h)*((f+b)/g))/.01745329252,L[m>>3]=n;return 0}function kj(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;g=Fa-96|0;Fa=g;a:{b:{b=Va(a);if(b>>>0<6){break b}h=(a+b|0)-6|0;if(nb(h,32850,6)){break b}i=100;while(1){e=0;f=Fa-16|0;Fa=f;if(!H[195208]){b=za()|0;E[195208]=1;E[195209]=b}b=f+8|0;j=+fa();c=j/1e3;c:{if(O(c)<0x8000000000000000){k=O(c)>=1?~~(c>0?Q(S(c*2.3283064365386963e-10),4294967295):T((c-+(~~c>>>0>>>0))*2.3283064365386963e-10))>>>0:0;d=~~c>>>0;break c}k=-2147483648;d=0}G[b>>2]=d;c=(j-(+(Au(d,k,1e3,0)>>>0)+ +(Ia|0)*4294967296))*1e3*1e3;d:{if(O(c)<2147483648){d=~~c;break d}d=-2147483648}G[b+4>>2]=d;b=h+(b>>>4|0)^M(G[f+12>>2],65537);while(1){E[e+h|0]=(b&15|b<<1&32)+65;b=b>>>5|0;e=e+1|0;if((e|0)!=6){continue}break}Fa=f+16|0;if(Be(a,g+8|0)){if(G[48624]==44){break a}E[a|0]=0;break a}i=i-1|0;if(i){continue}break}E[a|0]=0;G[48624]=20;break a}G[48624]=28;E[a|0]=0}Fa=g+96|0;return a}function Dg(a,b,c,d){var e=0,f=0,g=0,h=0;g=Fa-1040|0;Fa=g;e=G[d>>2];if(!e){a:{if(Va(a)>>>0>=1025){E[c|0]=0;Ua(59218);e=125;break a}b:{f=Za(g,a);if(gc(f,38938,4)){if(gc(f,38936,6)){break b}}Ua(59256);Ua(66489);Ua(34688);e=125;break a}c:{if(H[b|0]!=47){a=Uf(f,47);d:{if(a){E[a+1|0]=0;break d}E[f|0]=0}if(Va(f)+Va(b)>>>0<1025){break c}E[c|0]=0;Ua(59212);e=125;break a}E[c|0]=47;E[c+1|0]=0;if(H[b|0]==47){e=0;while(1){if(Va(c)-1024>>>0<=4294966270){E[c|0]=0;Ua(59174);e=125;break a}a=Va(c)+c|0;E[a|0]=47;E[a+1|0]=0;e=e+1|0;if(H[e+b|0]==47){continue}break}}h=Va(c);a=f;e=Sb(a,c);if(e){while(1){a=e+h|0;e=Sb(a,c);if(e){continue}break}}E[(c+h|0)-1|0]=0;e=Sb(a,c);e:{if(!e){a=Uf(a,47);if(a){E[a|0]=0;break e}E[f|0]=0;break e}E[e|0]=0}if(Va(f)+Va(b)>>>0<1025){break c}E[c|0]=0;Ua(59212);e=125;break a}e=_d(Gb(f,b),c,d)}G[d>>2]=e}Fa=g+1040|0;return e}function _n(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;e=Fa-2896|0;Fa=e;a:{if(G[b>>2]>0){break a}c=G[a+4>>2];if(G[a>>2]!=G[c+76>>2]){break a}d=G[c+976>>2];j=G[c+980>>2];if(!(d|j)){break a}l=G[c+984>>2];f=G[c+988>>2];g=G[c+128>>2];m=G[c+132>>2];c=G[c+80>>2];G[e+12>>2]=0;h=1;k=((c|0)==1)<<5;c=j+m|0;d=g+d|0;c=d>>>0>>0?c+1|0:c;g=d+l|0;f=c+f|0;f=g>>>0>>0?f+1|0:f;c=f;d=g+2879|0;c=d>>>0<2879?c+1|0:c;d=Cu(d,c);c=2879-d|0;d=0-(Ia+(d>>>0>2879)|0)|0;b:{c:{if(!c){f=f-!g|0;g=g-1|0;c=e+12|0;Jb(a,g,f,0,c);ic(a,1,0,e+16|0,c);if(G[e+12>>2]){break c}break b}h=e+12|0;Jb(a,g,f,0,h);ic(a,c,d,e+16|0,h);if(G[e+12>>2]){h=c;break c}while(1){if(H[(e+16|0)+i|0]==(k|0)){i=i+1|0;if((c|0)!=(i|0)){continue}break b}break}h=c;if((c|0)==(i|0)){break b}}c=e+16|0;cb(c,k,h);Jb(a,g,f,1,b);Wb(a,h,0,c,b);if(G[b>>2]<=0){break a}tb(5,46324)}}Fa=e+2896|0}function Cc(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;if((a|b)<0){return 0}c=1;e=G[309722];d=G[(e+M(a,344)|0)+56>>2];a:{if((d|0)==1){break a}f=G[(M(b,344)+e|0)+56>>2];if((f|0)==1){break a}if(G[(M(a,344)+e|0)+52>>2]!=G[(M(b,344)+e|0)+52>>2]){return 0}if((d|0)!=(f|0)){return 0}c=0;d=G[(M(a,344)+e|0)+60>>2];if((d|0)!=G[(M(b,344)+e|0)+60>>2]){break a}c=1;if((d|0)<=0){break a}j=d&3;b:{if(d-1>>>0<3){d=0;break b}m=d&-4;d=0;while(1){f=d<<2;g=f|4;h=c;c=(M(a,344)+e|0)- -64|0;i=(M(b,344)+e|0)- -64|0;h=G[c+g>>2]==G[g+i>>2]?G[f+c>>2]==G[f+i>>2]?h:0:0;g=f|8;g=G[g+c>>2]==G[g+i>>2]?h:0;h=c;c=f|12;c=G[h+c>>2]==G[c+i>>2]?g:0;d=d+4|0;k=k+4|0;if((m|0)!=(k|0)){continue}break}}if(!j){break a}while(1){h=c;c=d<<2;c=G[(c+(M(a,344)+e|0)|0)- -64>>2]==G[(c+(M(b,344)+e|0)|0)- -64>>2]?h:0;d=d+1|0;l=l+1|0;if((l|0)!=(j|0)){continue}break}}return c}function pj(a){var b=0,c=0,d=0,e=0,f=0;b=a+3848|0;c=G[a+3260>>2];a:{if(H[a+3848|0]){if(c){break a}c=0}d=H[34145]|H[34146]<<8|(H[34147]<<16|H[34148]<<24);E[b+3|0]=d;E[b+4|0]=d>>>8;E[b+5|0]=d>>>16;E[b+6|0]=d>>>24;d=H[34142]|H[34143]<<8|(H[34144]<<16|H[34145]<<24);E[b|0]=d;E[b+1|0]=d>>>8;E[b+2|0]=d>>>16;E[b+3|0]=d>>>24}if((c|0)==-1){c=H[34785]|H[34786]<<8;E[b+4|0]=c;E[b+5|0]=c>>>8;c=H[34781]|H[34782]<<8|(H[34783]<<16|H[34784]<<24);E[b|0]=c;E[b+1|0]=c>>>8;E[b+2|0]=c>>>16;E[b+3|0]=c>>>24}c=Nf(b);G[a+3964>>2]=c;b:{c:{switch(c-1|0){case 1:E[a+3880|0]=70;E[a+3881|0]=75;E[a+3882|0]=52;E[a+3883|0]=0;break b;case 0:E[a+3880|0]=70;E[a+3881|0]=75;E[a+3882|0]=53;E[a+3883|0]=0;break b;default:break c}}Za(a+3880|0,b)}e=a,f=Nf(a+3880|0),G[e+3968>>2]=f;L[a+3952>>3]=L[a+120>>3];e=a,f=Nf(Za(a+3912|0,b)),G[e+3960>>2]=f;L[a+3944>>3]=L[a+120>>3]} -function Of(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;g=2e3;d=Fa-80|0;Fa=d;G[d+48>>2]=b;e=d- -64|0;db(e,41064,d+48|0);a:{b:{if(Pc(a,e)){F[d+60>>1]=H[29843]|H[29844]<<8;G[d+56>>2]=H[29839]|H[29840]<<8|(H[29841]<<16|H[29842]<<24);break b}G[d+32>>2]=b;e=d- -64|0;db(e,41343,d+32|0);if(Pc(a,e)){G[d+56>>2]=627012389;G[d+60>>2]=6566448;break b}G[d+16>>2]=b;e=d- -64|0;db(e,41359,d+16|0);if(Pc(a,e)){G[d+56>>2]=627012389;G[d+60>>2]=6566704;break b}e=0;if(!Pc(a,d- -64|0)){break a}G[d+56>>2]=627012389;G[d+60>>2]=6566704}E[1285300]=1;e=1;h=c;c:{d:{while(1){G[d+4>>2]=e;G[d>>2]=b;f=d- -64|0;db(f,d+56|0,d);f=Ye(a,f);if(!f){break d}i=Va(f);if((i|0)<(g|0)){g=g-i|0;h=Za(h,f)+i|0;f=500;e=e+1|0;if((e|0)!=500){continue}break c}break}if((g|0)>=2){j=rb(h,f,g-1|0)+g|0,k=0,E[j|0]=k;break d}E[c|0]=H[f|0]}f=e}E[1285300]=0;e=f>>>0>1}Fa=d+80|0;return e}function Uc(a,b,c,d,e,f,g){var h=0,i=0,j=0;a:{if((e|0)==4){e=d<<2;if((d|0)<=2159){b:{if(G[g>>2]>0){break b}if((c|0)<0){G[g>>2]=304;break b}i=G[a>>2];h=G[a+4>>2];if((i|0)!=G[h+76>>2]){mb(a,i+1|0,0,g);h=G[a+4>>2]}i=Du(b,c,2880,0);j=G[h+72>>2];if(!((j|0)>=0&(i|0)==G[((j<<2)+h|0)+1256>>2])){Hc(a,i,0,g)}if(G[g>>2]>0){break b}h=G[a+4>>2];G[h+56>>2]=b;G[h+60>>2]=c}ic(a,e,e>>31,f,g);break a}h=G[a+4>>2];i=G[h+56>>2];j=G[h+60>>2];G[h+56>>2]=b;G[h+60>>2]=c;ic(a,e,e>>31,f,g);a=G[a+4>>2];G[a+56>>2]=i;G[a+60>>2]=j;break a}c:{if(G[g>>2]>0){break c}if((c|0)<0){G[g>>2]=304;break c}i=G[a>>2];h=G[a+4>>2];if((i|0)!=G[h+76>>2]){mb(a,i+1|0,0,g);h=G[a+4>>2]}i=Du(b,c,2880,0);j=G[h+72>>2];if(!((j|0)>=0&(i|0)==G[((j<<2)+h|0)+1256>>2])){Hc(a,i,0,g)}if(G[g>>2]>0){break c}h=G[a+4>>2];G[h+56>>2]=b;G[h+60>>2]=c}Rd(a,4,d,e-4|0,f,g)}ke(f,d);return G[g>>2]}function Tc(a,b,c,d,e,f,g){var h=0,i=0,j=0;a:{if((e|0)==8){e=d<<3;if((d|0)<=1079){b:{if(G[g>>2]>0){break b}if((c|0)<0){G[g>>2]=304;break b}i=G[a>>2];h=G[a+4>>2];if((i|0)!=G[h+76>>2]){mb(a,i+1|0,0,g);h=G[a+4>>2]}i=Du(b,c,2880,0);j=G[h+72>>2];if(!((j|0)>=0&(i|0)==G[((j<<2)+h|0)+1256>>2])){Hc(a,i,0,g)}if(G[g>>2]>0){break b}h=G[a+4>>2];G[h+56>>2]=b;G[h+60>>2]=c}ic(a,e,e>>31,f,g);break a}h=G[a+4>>2];i=G[h+56>>2];j=G[h+60>>2];G[h+56>>2]=b;G[h+60>>2]=c;ic(a,e,e>>31,f,g);a=G[a+4>>2];G[a+56>>2]=i;G[a+60>>2]=j;break a}c:{if(G[g>>2]>0){break c}if((c|0)<0){G[g>>2]=304;break c}i=G[a>>2];h=G[a+4>>2];if((i|0)!=G[h+76>>2]){mb(a,i+1|0,0,g);h=G[a+4>>2]}i=Du(b,c,2880,0);j=G[h+72>>2];if(!((j|0)>=0&(i|0)==G[((j<<2)+h|0)+1256>>2])){Hc(a,i,0,g)}if(G[g>>2]>0){break c}h=G[a+4>>2];G[h+56>>2]=b;G[h+60>>2]=c}Rd(a,8,d,e-8|0,f,g)}Ge(f,d);return G[g>>2]}function pd(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;k=Fa-160|0;Fa=k;f=G[e>>2];if((f|0)<=0){h=G[a>>2];f=G[a+4>>2];if((h|0)!=G[f+76>>2]){mb(a,h+1|0,0,e);f=G[a+4>>2];h=G[f+76>>2]}h=G[f+96>>2]+(h<<3)|0;if(G[f+104>>2]!=G[h>>2]|G[f+108>>2]!=G[h+4>>2]){Ke(a,e)}a:{if((c|0)<=0){break a}f=c-1|0;j=f>>>0<19?f:19;l=j+1|0;m=l&3;h=0;f=0;if(j>>>0>=3){l=l&60;j=0;while(1){g=(f<<3)+k|0;i=G[(f<<2)+d>>2];G[g>>2]=i;G[g+4>>2]=i>>31;g=f|1;i=(g<<3)+k|0;g=G[(g<<2)+d>>2];G[i>>2]=g;G[i+4>>2]=g>>31;g=f|2;i=(g<<3)+k|0;g=G[(g<<2)+d>>2];G[i>>2]=g;G[i+4>>2]=g>>31;g=f|3;i=(g<<3)+k|0;g=G[(g<<2)+d>>2];G[i>>2]=g;G[i+4>>2]=g>>31;f=f+4|0;j=j+4|0;if((l|0)!=(j|0)){continue}break}}if(!m){break a}while(1){j=(f<<3)+k|0;l=G[(f<<2)+d>>2];G[j>>2]=l;G[j+4>>2]=l>>31;f=f+1|0;h=h+1|0;if((m|0)!=(h|0)){continue}break}}Yi(a,b,c,k,e);f=G[e>>2]}Fa=k+160|0;return f}function gm(a,b,c,d,e,f,g){var h=0,i=0,j=0,k=0,l=0,m=0;j=Fa-1600|0;Fa=j;a:{b:{i=Sh(4,a,b,1289136,1289936,c,1);if((i|0)<=0){break b}i=Sh(i,1289136,1289936,1290736,1291536,d,0);if((i|0)<=0){break b}k=Sh(i,1291536,1290736,1289936,1289136,e,1);if((k|0)<=0){break b}i=0;k=Sh(k,1289936,1289136,j,j+800|0,f,0);if((k|0)<=2){break b}c=0;while(1){a=j+800|0;b=i<<3;i=i+1|0;m=((i|0)==(k|0)?0:i)<<3;c=c+(L[a+b>>3]*L[m+j>>3]-L[b+j>>3]*L[a+m>>3]);if((i|0)!=(k|0)){continue}break}c=O(c)*.5*g;break a}l=L[a>>3];a=0;h=L[b>>3];b=h>=e;c:{d:{if(b){a=!(e>h)|!((h-e)/(e-e)*(d-c)+c>l)?a:1;if(f>h){break d}}if(!(e>h)|!(f<=h)){break c}}if(!((h-e)/(f-e)*(d-d)+d>l)){break c}a=a+1|0}e:{f:{if(f<=h){a=!(f>h)|!((h-f)/(f-f)*(c-d)+d>l)?a:a+1|0;if(e>h){break f}}if(!(f>h)|!b){break e}}if(!((h-f)/(e-f)*(c-c)+c>l)){break e}a=a+1|0}c=a&1?g:0}Fa=j+1600|0;return c}function ds(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;h=Fa-16|0;Fa=h;f=G[c+4>>2];g=f>>31;if(((f^g)-g|0)!=103){G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=84;E[c+1|0]=65;E[c+2|0]=78;E[c+3|0]=0;G[c+4>>2]=(f|0)<0?-103:103;if(L[c+24>>3]==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020}G[c+1892>>2]=85;G[c+1888>>2]=86;f=99;a:{while(1){i=(f<<3)+c|0;if(L[i+280>>3]!=0|L[i+1080>>3]!=0){break a}g=f-1|0;if(L[((g<<3)+c|0)+280>>3]!=0){f=g;break a}if(L[i+1072>>3]!=0){f=g;break a}f=f-2|0;if(g){continue}break}f=-1}G[c+276>>2]=(f|0)>0?f:0}f=2;j=Kb(b);if(!(j<=0)){k=L[c+24>>3]*Mb(b)/j;b=Kb(a)*k;L[h>>3]=b;l=h,m=Mb(a)*-k,L[l+8>>3]=m;g=G[c+1880>>2];if(g){b=$g(g,h)}L[d>>3]=b;d=G[c+1884>>2];b:{if(d){a=$g(d,h);break b}a=L[h+8>>3]}L[e>>3]=a;f=G[c+4>>2]>0?(j<0)<<1:0}Fa=h+16|0;return f|0}function Pe(a,b,c,d,e,f,g){var h=0,i=0,j=0;a:{if((e|0)==2){e=d<<1;if((d|0)<=4319){b:{if(G[g>>2]>0){break b}if((c|0)<0){G[g>>2]=304;break b}i=G[a>>2];h=G[a+4>>2];if((i|0)!=G[h+76>>2]){mb(a,i+1|0,0,g);h=G[a+4>>2]}i=Du(b,c,2880,0);j=G[h+72>>2];if(!((j|0)>=0&(i|0)==G[((j<<2)+h|0)+1256>>2])){Hc(a,i,0,g)}if(G[g>>2]>0){break b}h=G[a+4>>2];G[h+56>>2]=b;G[h+60>>2]=c}ic(a,e,e>>31,f,g);break a}h=G[a+4>>2];i=G[h+56>>2];j=G[h+60>>2];G[h+56>>2]=b;G[h+60>>2]=c;ic(a,e,e>>31,f,g);a=G[a+4>>2];G[a+56>>2]=i;G[a+60>>2]=j;break a}c:{if(G[g>>2]>0){break c}if((c|0)<0){G[g>>2]=304;break c}i=G[a>>2];h=G[a+4>>2];if((i|0)!=G[h+76>>2]){mb(a,i+1|0,0,g);h=G[a+4>>2]}i=Du(b,c,2880,0);j=G[h+72>>2];if(!((j|0)>=0&(i|0)==G[((j<<2)+h|0)+1256>>2])){Hc(a,i,0,g)}if(G[g>>2]>0){break c}h=G[a+4>>2];G[h+56>>2]=b;G[h+60>>2]=c}Rd(a,2,d,e-2|0,f,g)}Af(f,d)}function ro(a,b,c,d,e,f,g,h,i,j,k,l){var m=0,n=0,o=0;m=Fa+-64|0;Fa=m;G[k>>2]=0;d=d+1|0;G[m+8>>2]=d;G[m+40>>2]=d;n=G[e>>2];a:{b:{if(!n){d=G[e+4>>2];break b}G[m+32>>2]=n+1;d=G[e+4>>2];o=d+1|0;G[m+4>>2]=o;G[m+36>>2]=o;if((d|0)==G[f+4>>2]){d=G[f>>2]+1|0}else{d=G[g>>2]}G[m>>2]=d;uh(a,b,m+32|0,m,h,i,j,l);n=d-n|0;G[k>>2]=n+G[k>>2];d=G[e+4>>2];if((d|0)==G[f+4>>2]){break a}G[e>>2]=0;d=d+1|0;G[e+4>>2]=d;i=M(c,n)+i|0}G[m+32>>2]=1;n=d+1|0;G[m+36>>2]=n;e=G[g>>2];G[m>>2]=e;o=G[f+4>>2];e=o+((e|0)==(G[f>>2]+1|0))|0;G[m+4>>2]=e;c:{if((d|0)>=(e|0)){d=o+1|0;break c}uh(a,b,m+32|0,m,h,i,j,l);n=(e-n|0)+1|0;G[k>>2]=G[k>>2]+M(n,G[g>>2]);d=G[f+4>>2]+1|0;if((e|0)==(d|0)){break a}i=M(G[g>>2],M(c,n))+i|0}if((d|0)==(e|0)){break a}c=G[f>>2];G[m+4>>2]=d;G[m+36>>2]=d;c=c+1|0;G[m>>2]=c;uh(a,b,m+32|0,m,h,i,j,l);G[k>>2]=c+G[k>>2]}Fa=m- -64|0}function hn(a,b,c,d,e,f,g){var h=0,i=0;h=Fa+-64|0;Fa=h;i=G[g>>2];a:{if(i){break a}b:{if(fh(a,b,h+40|0,h+32|0,h+36|0,h,g)){break b}a=G[h+40>>2];c:{b=G[h+32>>2];d:{if((b|0)<0){if((a|0)!=14|(b|0)!=-1){break d}a=H[(G[309722]+M(G[309725],344)|0)+88|0];G[e>>2]=d;if((d|0)<=0){break b}cb(f,a,d);break b}if((a|0)!=14){break d}if((b|0)==1){break c}}Yd();Ua(43091);i=432;G[g>>2]=432;break a}G[h+52>>2]=d;G[h+48>>2]=0;G[h+44>>2]=f;e:{if(($f(G[309728],G[309729],((c|0)>1?c:1)-1|0,0,34,h+40|0,g)|0)==-1){G[g>>2]=0;break e}if(G[g>>2]){break b}}b=0;G[e>>2]=0;c=G[h+52>>2];if((c|0)<=0){break b}i=0;if((c|0)!=1){d=c&-2;a=0;while(1){if(H[f+i|0]==1){b=b+1|0;G[e>>2]=b}if(H[(i|1)+f|0]==1){b=b+1|0;G[e>>2]=b}i=i+2|0;a=a+2|0;if((d|0)!=(a|0)){continue}break}}if(!(c&1)|H[f+i|0]!=1){break b}G[e>>2]=b+1}Yd();i=G[g>>2]}Fa=h- -64|0;return i}function bu(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;b=Fa-65712|0;Fa=b;a:{b:{c:{a=(H[a|0]?a:0)?a:42205;f=em(a);if(f){c=Ph(f);if(c){break c}break b}G[b>>2]=a;a=G[29763];_a(a,69677,b);$a(a);break a}j=b+152|0;k=b+160|0;d=G[29763];while(1){c=c+19|0;d:{if(!Xa(c,48504)){break d}if(!Xa(c,45311)){break d}e=H[(Va(a)+a|0)-1|0];G[b+84>>2]=c;G[b+80>>2]=a;g=b+176|0;Ya(g,65536,(e|0)==47?8740:8778,b+80|0);if((Be(g,b+88|0)|0)>=0){g=wl(ol(k));l=wl(ol(j));e=36147;h=(G[b+100>>2]&61440)-4096|0;if(h>>>0<=40959){e=G[(h>>>10|0)+189500>>2]}e:{if(!Xa(e,10935)){G[b+16>>2]=c;_a(d,87573,b+16|0);break e}G[b+48>>2]=l;G[b+32>>2]=c;G[b+36>>2]=e;G[b+40>>2]=G[b+128>>2];G[b+44>>2]=g;_a(d,69586,b+32|0)}$a(d);i=i+1|0;break d}G[b+64>>2]=c;_a(d,87655,b- -64|0);$a(d)}c=Ph(f);if(c){continue}break}}_l(f)}Fa=b+65712|0;return i|0}function Jk(a,b){var c=0,d=N(0),e=N(0),f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=N(0);f=b-1|0;j=(f|0)/2|0;a:{if((b|0)<2){break a}while(1){b=h+1|0;if((f|0)==(b|0)){b=(h<<2)+a|0;d=K[b>>2];c=(f<<2)+a|0;e=K[c>>2];if(!(d>e)){break a}K[b>>2]=e;K[c>>2]=d;break a}c=((f+h|0)/2<<2)+a|0;d=K[c>>2];g=(f<<2)+a|0;e=K[g>>2];b:{if(!(d>e)){d=e;break b}K[c>>2]=e;K[g>>2]=d}i=(h<<2)+a|0;e=K[i>>2];if(e>d){K[i>>2]=d;K[g>>2]=e;e=K[i>>2]}d=K[c>>2];if(e>2]=e;K[i>>2]=d;d=K[c>>2]}g=c;c=(b<<2)+a|0;K[g>>2]=K[c>>2];K[c>>2]=d;c=f;while(1){d=K[i>>2];while(1){b=b+1|0;l=(b<<2)+a|0;m=K[l>>2];if(d>m){continue}break}while(1){g=c;c=c-1|0;k=(c<<2)+a|0;e=K[k>>2];if(e>d){continue}break}if((b|0)<(g|0)){K[l>>2]=e;K[k>>2]=m;continue}break}K[i>>2]=e;K[k>>2]=d;f=(g|0)>(j|0)?g-2|0:f;h=(c|0)>(j|0)?h:b;if((f|0)>(h|0)){continue}break}}return K[(j<<2)+a>>2]}function Km(a){var b=0,c=0,d=0,e=0,f=0,g=0;a:{if(!a){break a}c=H[a|0];if(!c){break a}d=1;b:{c:{while(1){b=c&255;if((b|0)!=32){d:{switch(b-43|0){case 0:break c;case 2:break d;default:break b}}}else{c=H[a+1|0];a=a+1|0;continue}break}a=a+1|0;d=-1;break b}a=a+1|0}b=ec(a,49008,Va(a));if(b){E[b|0]=32}c=Va(a);while(1){b=c;c=b-1|0;if(H[c+a|0]==32){continue}break}e:{c=ec(a,40241,Va(a));if(!c){c=ec(a,68332,b);if(!c){break e}}E[c|0]=0;a=_b(a);E[c|0]=58;f=+(a|0);b=c+1|0;a=Va(b);f:{g:{c=ec(b,40241,a);if(!c){c=ec(b,68332,a);if(!c){break g}}E[c|0]=0;a=_b(b);E[c|0]=58;e=+(a|0);g=sb(c+1|0);break f}if(ec(b,48504,a)){e=sb(b)}if(!H[b|0]){break f}e=+(_b(b)|0)}return d*(e/60+f+g/3600)}if((ah(a)|0)==2){b=jb(a,68);if(b){E[b|0]=101}b=jb(a,100);if(b){E[b|0]=101}b=jb(a,69);if(b){E[b|0]=101}return d*sb(a)}d=d*+(_b(a)|0)}return d}function $r(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;h=G[c+4>>2];i=h>>31;if(((h^i)-i|0)!=105){G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=83;E[c+1|0]=73;E[c+2|0]=78;E[c+3|0]=0;G[c+4>>2]=(h|0)<0?-105:105;f=L[c+24>>3];if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=57.29577951308232}G[c+1892>>2]=89;G[c+1888>>2]=90;L[c+112>>3]=1/f;f=L[c+40>>3];g=f*f;f=L[c+48>>3];f=g+f*f;L[c+120>>3]=f;L[c+136>>3]=f+-1;L[c+128>>3]=f+1}f=(90-O(b))*3.141592653589793/180;a:{if(f<1e-5){g=f*f*.5;if(b>0){break a}g=2-g;break a}g=1-Kb(b);f=Mb(b)}j=Mb(a);a=Kb(a);L[d>>3]=L[c+24>>3]*(f*a+g*L[c+40>>3]);L[e>>3]=(f*j-g*L[c+48>>3])*-L[c+24>>3];b:{c:{if(G[c+4>>2]<=0){break c}if(L[c+120>>3]==0){d=2;if(!(b<0)){break c}break b}d=2;if(-De(L[c+40>>3]*a-j*L[c+48>>3])>b){break b}}d=0}return d|0}function Ke(a,b){var c=0,d=0,e=0,f=0,g=0;e=Fa-16|0;Fa=e;G[e+12>>2]=0;c=G[b>>2];a:{if((c|0)>0){break a}d=G[a>>2];c=G[a+4>>2];if((d|0)!=G[c+76>>2]){mb(a,d+1|0,0,b);c=G[a+4>>2];d=G[c+76>>2]}d=G[c+96>>2]+(d<<3)|0;b:{if(G[c+104>>2]==G[d>>2]&G[c+108>>2]==G[d+4>>2]){break b}while(1){mb(a,G[a>>2]+2|0,0,e+12|0);if(!G[e+12>>2]){continue}break}c=G[a+4>>2];d=G[c+92>>2];if((d|0)==G[c+88>>2]){d=ub(G[c+96>>2],(d<<3)+8008|0);if(!d){c=113;G[b>>2]=113;break a}c=G[a+4>>2];G[c+96>>2]=d;G[c+92>>2]=G[c+92>>2]+1e3}if((Xf(a,b)|0)>0){break b}c=G[a+4>>2];c=(G[c+88>>2]<<3)+G[c+96>>2]|0;d=G[c+12>>2];f=G[c+8>>2];Jb(a,f,d,1,b);c=G[a+4>>2];g=G[c+88>>2]+1|0;G[c+76>>2]=g;G[c+88>>2]=g;G[a>>2]=g;G[c+128>>2]=-1;G[c+132>>2]=-1;G[c+104>>2]=f;G[c+108>>2]=d;G[c+120>>2]=f;G[c+124>>2]=d;G[c+1084>>2]=G[c+1028>>2]}c=G[b>>2]}Fa=e+16|0;return c}function yr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;a:{b:{if(G[c+4>>2]==202){f=L[c+136>>3];break b}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=67;E[c+1|0]=69;E[c+2|0]=65;E[c+3|0]=0;E[c+4|0]=202;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];c:{if(f==0){G[c+112>>2]=0;G[c+116>>2]=1072693248;G[c+24>>2]=442745336;G[c+28>>2]=1078765020;G[c+120>>2]=0;G[c+124>>2]=1072693248;f=L[c+40>>3];g=1;if(f<=0|f>1){break a}L[c+128>>3]=57.29577951308232/f;f=f/57.29577951308232;break c}L[c+120>>3]=57.29577951308232/f;L[c+112>>3]=f*3.141592653589793/180;h=L[c+40>>3];g=1;if(h<=0|h>1){break a}L[c+128>>3]=f/h;f=h/f}G[c+1892>>2]=119;G[c+1888>>2]=120;L[c+136>>3]=f}b=f*b;f=O(b);if(f>1){g=2;if(f>1.0000000000001){break a}b=b<0?-1:1}L[d>>3]=L[c+120>>3]*a;i=e,j=Bc(b),L[i>>3]=j;g=0}return g|0}function Si(a,b,c,d){var e=0,f=0;e=G[a+5820>>2];a:{if((e|0)>=14){e=I[a+5816>>1]|d<>1]=e;f=G[a+20>>2];G[a+20>>2]=f+1;E[f+G[a+8>>2]|0]=e;e=G[a+20>>2];G[a+20>>2]=e+1;E[e+G[a+8>>2]|0]=H[a+5817|0];e=d&65535;d=G[a+5820>>2];f=e>>>16-d|0;F[a+5816>>1]=f;d=d-13|0;break a}f=I[a+5816>>1]|d<>1]=f;d=e+3|0}b:{if((d|0)>=9){d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=f;d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=H[a+5817|0];break b}if((d|0)<=0){break b}d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=f}G[a+5820>>2]=0;F[a+5816>>1]=0;d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=c;d=G[a+20>>2];G[a+20>>2]=d+1;E[d+G[a+8>>2]|0]=c>>>8;d=G[a+20>>2];G[a+20>>2]=d+1;e=d+G[a+8>>2]|0;d=c^-1;E[e|0]=d;e=G[a+20>>2];G[a+20>>2]=e+1;E[e+G[a+8>>2]|0]=d>>>8;bb(G[a+8>>2]+G[a+20>>2]|0,b,c);G[a+20>>2]=G[a+20>>2]+c}function Mi(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;f=b-1|0;j=(f|0)/2|0;a:{if((b|0)<2){break a}while(1){b=h+1|0;if((f|0)==(b|0)){b=(h<<3)+a|0;d=L[b>>3];c=(f<<3)+a|0;e=L[c>>3];if(!(d>e)){break a}L[b>>3]=e;L[c>>3]=d;break a}c=((f+h|0)/2<<3)+a|0;d=L[c>>3];g=(f<<3)+a|0;e=L[g>>3];b:{if(!(d>e)){d=e;break b}L[c>>3]=e;L[g>>3]=d}i=(h<<3)+a|0;e=L[i>>3];if(e>d){L[i>>3]=d;L[g>>3]=e;e=L[i>>3]}d=L[c>>3];if(e>3]=e;L[i>>3]=d;d=L[c>>3]}g=c;c=(b<<3)+a|0;L[g>>3]=L[c>>3];L[c>>3]=d;c=f;while(1){d=L[i>>3];while(1){b=b+1|0;l=(b<<3)+a|0;m=L[l>>3];if(d>m){continue}break}while(1){g=c;c=c-1|0;k=(c<<3)+a|0;e=L[k>>3];if(e>d){continue}break}if((b|0)<(g|0)){L[l>>3]=e;L[k>>3]=m;continue}break}L[i>>3]=e;L[k>>3]=d;f=(g|0)>(j|0)?g-2|0:f;h=(c|0)>(j|0)?h:b;if((f|0)>(h|0)){continue}break}}return L[(j<<3)+a>>3]}function Vl(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0;f=Fa-48|0;Fa=f;c=L[467827];e=c*b;b=eb(e);a=c*a;d=ib(a);g=L[467846];c=eb(a);h=L[467845];i=L[467847];a=ib(e);c=c*b;d=d*b;b=a*L[467850]+(L[467848]*c+d*L[467849]);e=a*L[467844]+(L[467842]*c+L[467843]*d);c=i*a+(h*c+d*g);a=V(b*b+(e*e+c*c));if(!(!(a>3]=a;gb(73024,f+32|0);$a(G[29763])}if(!(a<=0)){c=c/a;e=e/a;b=b/a}d=e*0;a=c-d;c=b*0+c*-0;d=d-b;b=V(a*a+(c*c+d*d));if(!(!(b>3]=b;gb(73024,f+16|0);$a(G[29763])}if(!(b<=0)){d=d/b;c=c/b;a=a/b}b=d*0;g=b-c;h=a-b;i=a*-0+c*0;b=V(g*g+(h*h+i*i));if(!(!(b>3]=b;gb(73024,f);$a(G[29763])}a:{if(b<=0){b=0;break a}g=g/b;i=i/b;h=h/b}d=a*0+(c*0+d);a=Mc(Sc(e));c=L[467827];L[467839]=d*-a/c;L[467838]=a*(g*0+(h+i*0)<0?-b:b)/c;Fa=f+48|0}function uq(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;g=Fa-368|0;Fa=g;G[g+12>>2]=-1;a:{if(G[e>>2]>0){break a}k=Va(c);f=jb(c,39);if(f){while(1){i=i+1|0;f=jb(f+1|0,39);if(f){continue}break}}j=rb(g+96|0,b,80);E[j+80|0]=0;while(1){f=j;j=f+1|0;if(H[f|0]==32){continue}break}b:{c:{l=Va(f);if((l|0)>8){break c}if((ve(f,g+12|0)|0)>0){break c}f=68-i|0;break b}f=75-(i+l|0)|0}if((k|0)>0){l=68-i|0;i=1;j=0;while(1){if((f|0)>=71){Ua(50861);G[e>>2]=207;break a}h=rb(g+16|0,c+j|0,f);E[h+f|0]=0;kl(h,g+288|0,e);d:{if((f|0)>=(k|0)){break d}f=f-1|0;h=g+288|0;m=Va(h)+h|0;h=m-2|0;if(H[h|0]!=39){E[h|0]=38;break d}E[m-1|0]=0;E[m-3|0]=38}e:{if(!(i&1)){Ob(35367,g+288|0,d,g+192|0,e);F[g+200>>1]=8224;break e}Ob(b,g+288|0,d,g+192|0,e)}vl(a,g+192|0,e);j=f+j|0;k=k-f|0;i=0;f=l;if((k|0)>0){continue}break}}}Fa=g+368|0}function $d(a,b,c,d,e,f,g){var h=0,i=0,j=0;if((e|0)==1){if((d|0)<=8639){a:{if(G[g>>2]>0){break a}if((c|0)<0){G[g>>2]=304;break a}h=G[a>>2];e=G[a+4>>2];if((h|0)!=G[e+76>>2]){mb(a,h+1|0,0,g);e=G[a+4>>2]}h=Du(b,c,2880,0);i=G[e+72>>2];if(!((i|0)>=0&(h|0)==G[((i<<2)+e|0)+1256>>2])){Hc(a,h,0,g)}if(G[g>>2]>0){break a}e=G[a+4>>2];G[e+56>>2]=b;G[e+60>>2]=c}ic(a,d,d>>31,f,g);return}e=G[a+4>>2];h=G[e+56>>2];i=G[e+60>>2];G[e+56>>2]=b;G[e+60>>2]=c;ic(a,d,0,f,g);a=G[a+4>>2];G[a+56>>2]=h;G[a+60>>2]=i;return}b:{if(G[g>>2]>0){break b}if((c|0)<0){G[g>>2]=304;break b}i=G[a>>2];h=G[a+4>>2];if((i|0)!=G[h+76>>2]){mb(a,i+1|0,0,g);h=G[a+4>>2]}i=Du(b,c,2880,0);j=G[h+72>>2];if(!((j|0)>=0&(i|0)==G[((j<<2)+h|0)+1256>>2])){Hc(a,i,0,g)}if(G[g>>2]>0){break b}h=G[a+4>>2];G[h+56>>2]=b;G[h+60>>2]=c}Rd(a,1,d,e-1|0,f,g)}function am(a,b,c){var d=0,e=0,f=0;d=G[934940];if(d){Wa(d)}d=le(a);e=H[d|0];if(e){a=d;while(1){e=e<<24>>24;if(e-65>>>0<26){E[a|0]=e-65>>>0<26?e|32:e}e=H[a+1|0];a=a+1|0;if(e){continue}break}}G[934940]=d;a=0;e=0;a:{b:{if(!Xa(d,29574)){break b}if(!Xa(d,13163)){break b}if(!Xa(d,10364)){a=1;break b}c:{if(!Xa(d,29578)){break c}if(!Xa(d,13168)){break c}d:{if(!Xa(d,29577)){break d}if(!Xa(d,13167)){break d}e:{if(!Xa(d,8506)){break e}if(!Xa(d,10375)){break e}a=5;if(!Xa(d,8440)){break b}if(!Xa(d,10374)){break b}if(!Xa(d,30711)){e=1;a=0;break b}e=1;if(!Xa(d,3779)){a=1;break b}if(!Xa(d,30636)){a=1;break b}if(!Xa(d,30716)){a=2;break b}if(!Xa(d,30715)){a=3;break b}if(!Xa(d,30642)){a=4;break b}f=-1;if(Xa(d,30641)){break a}break b}a=4;break b}a=3;break b}a=2}G[c>>2]=a;if(b){G[b>>2]=e}f=0}return f}function rm(a){var b=0,c=0,d=0,e=0,f=0;c=G[a+3316>>2];d=(c|0)<2?c:2;if((d|0)<=0){d=G[a+3320>>2];G[a+3316>>2]=d}b=M(d,d)<<3;c=G[a+4056>>2];a:{if(!c){c=ab(b);G[a+4056>>2]=c;if(!c){break a}}e=G[a+4060>>2];if(!e){e=ab(b);G[a+4060>>2]=e;if(!e){break a}}G[a+4036>>2]=137;b:{c:{d:{switch(d-2|0){case 2:b=cb(c,0,128);L[b>>3]=L[a+56>>3];L[b+8>>3]=L[a- -64>>3];L[b+32>>3]=L[a+72>>3];f=L[a+80>>3];G[b+80>>2]=0;G[b+84>>2]=1072693248;L[b+40>>3]=f;b=15;f=1;break c;case 1:b=cb(c,0,72);L[b>>3]=L[a+56>>3];L[b+8>>3]=L[a- -64>>3];L[b+24>>3]=L[a+72>>3];L[b+32>>3]=L[a+80>>3];b=8;f=1;break c;case 0:break d;default:break b}}L[c>>3]=L[a+56>>3];L[c+8>>3]=L[a- -64>>3];L[c+16>>3]=L[a+72>>3];b=3;f=L[a+80>>3]}L[(b<<3)+c>>3]=f}sg(d,c,e);G[a+4052>>2]=a+760;G[a+4044>>2]=a+616;G[a+4048>>2]=a+832;G[a+4036>>2]=137}}function _q(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0;f=Fa-32|0;Fa=f;d=G[a+28>>2];G[f+16>>2]=d;g=G[a+20>>2];G[f+28>>2]=c;G[f+24>>2]=b;b=g-d|0;G[f+20>>2]=b;g=b+c|0;i=2;a:{b:{b=f+16|0;d=ga(G[a+60>>2],b|0,2,f+12|0)|0;if(d){G[48624]=d;d=-1}else{d=0}c:{d:{if(d){d=b;break d}while(1){e=G[f+12>>2];if((e|0)==(g|0)){break c}if((e|0)<0){d=b;break b}h=G[b+4>>2];j=h>>>0>>0;d=(j<<3)+b|0;h=e-(j?h:0)|0;G[d>>2]=h+G[d>>2];b=(j?12:4)+b|0;G[b>>2]=G[b>>2]-h;g=g-e|0;b=d;i=i-j|0;e=ga(G[a+60>>2],b|0,i|0,f+12|0)|0;if(e){G[48624]=e;e=-1}else{e=0}if(!e){continue}break}}if((g|0)!=-1){break b}}b=G[a+44>>2];G[a+28>>2]=b;G[a+20>>2]=b;G[a+16>>2]=b+G[a+48>>2];a=c;break a}G[a+28>>2]=0;G[a+16>>2]=0;G[a+20>>2]=0;G[a>>2]=G[a>>2]|32;a=0;if((i|0)==2){break a}a=c-G[d+4>>2]|0}Fa=f+32|0;return a|0}function jc(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;b=G[a+112>>2];d=G[a+116>>2];e=!!(b|d);c=b;a:{i=e;f=G[a+4>>2];e=G[a+44>>2];b=f-e|0;h=b;g=b+G[a+120>>2]|0;b=G[a+124>>2]+(b>>31)|0;b=g>>>0>>0?b+1|0:b;if(!(i&(c>>>0<=g>>>0&(b|0)>=(d|0)|(b|0)>(d|0)))){h=Ag(a);if((h|0)>=0){break a}f=G[a+4>>2];e=G[a+44>>2]}G[a+112>>2]=-1;G[a+116>>2]=-1;G[a+104>>2]=f;c=e-f|0;d=c+g|0;b=(c>>31)+b|0;G[a+120>>2]=d;G[a+124>>2]=d>>>0>>0?b+1|0:b;return-1}d=g+1|0;b=d?b:b+1|0;f=G[a+4>>2];e=G[a+8>>2];c=G[a+112>>2];g=G[a+116>>2];b:{if(!(c|g)){break b}i=c-d|0;c=g-(b+(d>>>0>c>>>0)|0)|0;j=e-f|0;g=j>>31;if((c|0)>=(g|0)&i>>>0>=j>>>0|(c|0)>(g|0)){break b}e=f+i|0}G[a+104>>2]=e;c=G[a+44>>2];e=c-f|0;d=e+d|0;b=(e>>31)+b|0;G[a+120>>2]=d;G[a+124>>2]=d>>>0>>0?b+1|0:b;if(c>>>0>=f>>>0){E[f-1|0]=h}return h}function Fi(a,b,c){var d=0,e=0,f=0;E[b|0]=0;G[c>>2]=0;a:{b:{c:{d:{e:{if(H[a|0]==72){if(!fb(a,66642,9)){break e}}while(1){d=H[a+e|0];if(!d|(d|0)==32|(d|0)==61){break c}E[b+e|0]=d;d=e|1;f=H[d+a|0];if(!f|(f|0)==32|(f|0)==61){break b}E[b+d|0]=f;d=74;e=e+2|0;if((e|0)!=74){continue}break}break d}f=jb(a,61);if(!f){a=Va(b)+b|0;b=H[34943]|H[34944]<<8|(H[34945]<<16|H[34946]<<24);d=H[34939]|H[34940]<<8|(H[34941]<<16|H[34942]<<24);E[a|0]=d;E[a+1|0]=d>>>8;E[a+2|0]=d>>>16;E[a+3|0]=d>>>24;E[a+4|0]=b;E[a+5|0]=b>>>8;E[a+6|0]=b>>>16;E[a+7|0]=b>>>24;d=8;E[a+8|0]=H[34947];break a}d=a+9|0;while(1){e=d;d=d+1|0;if(H[e|0]==32){continue}break}a=f-e|0;f=a&a>>31;e=qb(b,e,a);while(1){d=a;if((a|0)<=0){d=f;break d}a=d-1|0;if(H[e+a|0]==32){continue}break}}E[b+d|0]=0;break a}d=e}E[b+d|0]=0}G[c>>2]=d}function zr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;a:{b:{if(G[c+4>>2]==201){g=L[c+40>>3];break b}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=67;E[c+1|0]=89;E[c+2|0]=80;E[c+3|0]=0;E[c+4|0]=201;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];c:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=L[c+48>>3];L[c+112>>3]=f;h=1;if(f==0){break a}L[c+120>>3]=1/f;g=L[c+40>>3];f=(f+g)*57.29577951308232;L[c+128>>3]=f;if(f!=0){break c}break a}i=L[c+48>>3];g=f*i*3.141592653589793/180;L[c+112>>3]=g;h=1;if(g==0){break a}L[c+120>>3]=1/g;g=L[c+40>>3];f=f*(i+g);L[c+128>>3]=f;if(f==0){break a}}G[c+1892>>2]=117;G[c+1888>>2]=118;L[c+136>>3]=1/f}h=2;f=g+Mb(b);if(f==0){break a}L[d>>3]=L[c+112>>3]*a;j=e,k=L[c+128>>3]*Kb(b)/f,L[j>>3]=k;h=0}return h|0}function An(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0;A(+a);f=v(1)|0;v(0)|0;h=f;i=(f&2147483640)>>>0<1072010280;if(!i){f=(f|0)>0|(f|0)>=0;a=.7853981633974483-(f?a:-a)+(3061616997868383e-32-(f?b:-b));h=h>>>31|0;b=0}e=a*a;d=a*e;j=d*.3333333333333341;g=d;d=e*e;e=j+(e*(g*(d*(d*(d*(d*(d*-18558637485527546e-21+7817944429395571e-20)+.0005880412408202641)+.0035920791075913124)+.021869488294859542)+.13333333333320124+e*(d*(d*(d*(d*(d*2590730518636337e-20+7140724913826082e-20)+.0002464631348184699)+.0014562094543252903)+.0088632398235993)+.05396825397622605))+b)+b);b=a+e;if(!i){g=b*b;d=b;b=+(1-(c<<1)|0);a=a+(e-g/(d+b));a=b-(a+a);return h?-a:a}if(c){g=-1/b;A(+g);c=v(1)|0;v(0)|0;x(0,0);x(1,c|0);d=+z();A(+b);c=v(1)|0;v(0)|0;x(0,0);x(1,c|0);b=+z();b=g*(d*(e-(b-a))+(d*b+1))+d}return b}function Fm(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;f=Fa-80|0;Fa=f;i=L[d>>3];g=L[c>>3];e=(a+-1850)/100;h=(e*59e-6+1.3972)*e+2303.5548;a=(b-a)/100;b=a*48481368110953e-19;j=e*-365e-6;Cj(b*-((a*.017996+(e*-269e-6+.30242))*a+h),b*((a*-.041802+(j+-.42647))*a+((j+-.85294)*e+2005.1125)),b*-((a*.018324+(e*387e-6+1.09478))*a+h),f);a=i*3.141592653589793/180;b=eb(a);e=g*3.141592653589793/180;h=ib(e);i=L[f+8>>3];g=eb(e);j=L[f>>3];k=L[f+16>>3];a=ib(a);l=L[f+64>>3];m=L[f+48>>3];n=L[f+56>>3];e=h*b;b=g*b;h=a*L[f+40>>3]+(L[f+32>>3]*e+(L[f+24>>3]*b+0));i=k*a+(i*e+(j*b+0));g=Db(h,i);g=g<0?g+6.283185307179586:g;L[c>>3]=(g>6.283185307179586?g+-6.283185307179586:g)*180/3.141592653589793;o=d,p=Db(l*a+(n*e+(m*b+0)),V(i*i+h*h))*180/3.141592653589793,L[o>>3]=p;Fa=f+80|0} -function ai(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;f=Fa-80|0;Fa=f;i=L[d>>3];g=L[c>>3];e=(a+-2e3)/100;h=(e*-139e-6+1.39656)*e+2306.2181;a=(b-a)/100;b=a*48481368110953e-19;j=e*-217e-6;Cj(b*-((a*.017998+(e*-344e-6+.30188))*a+h),b*((a*-.041833+(j+-.42665))*a+((j+-.8533)*e+2004.3109)),b*-((a*.018203+(e*66e-6+1.09468))*a+h),f);a=i*3.141592653589793/180;b=eb(a);e=g*3.141592653589793/180;h=ib(e);i=L[f+8>>3];g=eb(e);j=L[f>>3];k=L[f+16>>3];a=ib(a);l=L[f+64>>3];m=L[f+48>>3];n=L[f+56>>3];e=h*b;b=g*b;h=a*L[f+40>>3]+(e*L[f+32>>3]+(b*L[f+24>>3]+0));i=a*k+(e*i+(b*j+0));g=Db(h,i);g=g<0?g+6.283185307179586:g;L[c>>3]=(g>6.283185307179586?g+-6.283185307179586:g)*180/3.141592653589793;o=d,p=Db(a*l+(e*n+(b*m+0)),V(i*i+h*h))*180/3.141592653589793,L[o>>3]=p;Fa=f+80|0}function mo(a,b,c,d,e,f){var g=0;a:{g=G[f>>2];b:{if((g|0)>0){break b}if((yk(a,2,32941,40247,f)|0)==208){G[f>>2]=222;return 222}if(G[f>>2]==209){G[f>>2]=211;return 211}if((yk(a,3,33788,40973,f)|0)==208){G[f>>2]=223;return 223}if(G[f>>2]==209){G[f>>2]=212;return 212}if((th(a,4,41261,b,f)|0)==208){break a}g=0;if(G[f>>2]==209){break b}if((th(a,5,40853,c,f)|0)==208){break a}if(G[f>>2]==209){break b}if((th(a,6,33303,d,f)|0)==208){G[f>>2]=228;return 228}if(G[f>>2]==209){G[f>>2]=214;return 214}if((yk(a,7,33311,41541,f)|0)==208){G[f>>2]=229;return 229}if(G[f>>2]==209){G[f>>2]=215;return 215}if((no(a,8,33837,e,f)|0)==208){G[f>>2]=230;return 230}g=G[f>>2];if(!((g|0)!=209&G[e>>2]<1e3)){return(g|0)==216}if((g|0)<=0){break b}Ua(48379);g=G[f>>2]}return g}G[f>>2]=224;return 224}function Ar(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;a:{b:{if(G[c+4>>2]==201){g=L[c+120>>3];break b}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=67;E[c+1|0]=89;E[c+2|0]=80;E[c+3|0]=0;E[c+4|0]=201;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];c:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=L[c+48>>3];L[c+112>>3]=f;h=1;if(f==0){break a}g=1/f;L[c+120>>3]=g;f=(f+L[c+40>>3])*57.29577951308232;L[c+128>>3]=f;if(f!=0){break c}break a}i=L[c+48>>3];g=f*i*3.141592653589793/180;L[c+112>>3]=g;h=1;if(g==0){break a}g=1/g;L[c+120>>3]=g;f=f*(i+L[c+40>>3]);L[c+128>>3]=f;if(f==0){break a}}G[c+1892>>2]=117;G[c+1888>>2]=118;L[c+136>>3]=1/f}L[d>>3]=g*a;a=L[c+136>>3]*b;j=e,k=Ac(a,1)+Bc(a*L[c+40>>3]/V(a*a+1)),L[j>>3]=k;h=0}return h|0}function xr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;a:{b:{if(G[c+4>>2]==202){g=L[c+112>>3];break b}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=67;E[c+1|0]=69;E[c+2|0]=65;E[c+3|0]=0;E[c+4|0]=202;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];c:{if(f==0){G[c+112>>2]=0;G[c+116>>2]=1072693248;G[c+24>>2]=442745336;G[c+28>>2]=1078765020;G[c+120>>2]=0;G[c+124>>2]=1072693248;i=1;f=L[c+40>>3];if(f<=0){break a}g=1;if(f>1){break a}L[c+128>>3]=57.29577951308232/f;f=f/57.29577951308232;break c}L[c+120>>3]=57.29577951308232/f;g=f*3.141592653589793/180;L[c+112>>3]=g;i=1;h=L[c+40>>3];if(h<=0|h>1){break a}L[c+128>>3]=f/h;f=h/f}G[c+1892>>2]=119;G[c+1888>>2]=120;L[c+136>>3]=f}L[d>>3]=g*a;j=e,k=L[c+128>>3]*Kb(b),L[j>>3]=k;i=0}return i|0}function rr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;a:{if(G[c+4>>2]==401){f=L[c+120>>3];i=L[c+128>>3];break a}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=65;E[c+1|0]=73;E[c+2|0]=84;E[c+3|0]=0;E[c+4|0]=145;E[c+5|0]=1;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=57.29577951308232}G[c+1892>>2]=125;G[c+1888>>2]=126;g=f+f;L[c+136>>3]=1/g;g=f*g;L[c+112>>3]=g;f=1/(g+g);L[c+120>>3]=f;i=f*.25;L[c+128>>3]=i}g=0;f=1-a*a*i-b*b*f;b:{c:{if(!(f<0)){g=f;break c}h=2;if(f<-1e-13){break b}}g=V(g);b=g*b/L[c+24>>3];f=O(b);if(f>1){h=2;if(f>1.0000000000001){break b}b=b<0?-1:1}f=(g+g)*g+-1;a=g*a*L[c+136>>3];if(f==0&a==0){a=0}else{a=Ac(a,f);a=a+a}L[d>>3]=a;j=e,k=Bc(b),L[j>>3]=k;h=0}return h|0}function es(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0;h=Fa-16|0;Fa=h;f=G[c+4>>2];g=f>>31;a:{if(((f^g)-g|0)==103){f=G[c+276>>2];break a}G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=84;E[c+1|0]=65;E[c+2|0]=78;E[c+3|0]=0;G[c+4>>2]=(f|0)<0?-103:103;if(L[c+24>>3]==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020}G[c+1892>>2]=85;G[c+1888>>2]=86;f=99;b:{while(1){i=(f<<3)+c|0;if(L[i+280>>3]!=0|L[i+1080>>3]!=0){break b}g=f-1|0;if(L[((g<<3)+c|0)+280>>3]!=0){f=g;break b}if(L[i+1072>>3]!=0){f=g;break b}f=f-2|0;if(g){continue}break}f=-1}f=(f|0)>0?f:0;G[c+276>>2]=f}if(f){vm(c,a,b,h+8|0,h);b=L[h>>3];a=L[h+8>>3]}j=V(a*a+b*b);if(j!=0){a=Ac(a,-b)}else{a=0}L[d>>3]=a;k=e,l=Ac(L[c+24>>3],j),L[k>>3]=l;Fa=h+16|0;return 0}function Ld(a,b,c){var d=0,e=0,f=0,g=0,h=0;E[3743024]=0;E[b|0]=0;a:{if(!a){break a}e=G[c>>2];d=H[e+a|0];if(!d){break a}b:{while(1){g=d<<24>>24;if(!(!((g|0)==32|g-9>>>0<5)&E[g+3743040|0]<=0)){g=0;if(!d){break b}e=e+1|0;d=H[e+a|0];continue}break}g=d;c:{d:{e:{switch(d-34|0){case 5:g=39;case 0:E[3743024]=d;h=e+1|0;d=H[h+a|0];if(!d){break c}while(1){if(!(H[a+e|0]==92|d<<24>>24!=(g|0))){break c}E[b+f|0]=d;f=f+1|0;e=h;h=e+1|0;d=H[h+a|0];if(d){continue}break};break c;default:f=g;if(!f){break d}break;case 1:case 2:case 3:case 4:break e}}f:{while(1){f=d<<24>>24;if((f|0)==32|f-9>>>0<5|H[f+3743040|0]){break f}E[b+h|0]=d;h=h+1|0;e=e+1|0;d=H[e+a|0];if(d){continue}break}d=0}f=h}h=e;E[3743024]=d}a=H[a+h|0];E[b+f|0]=0;e=((a|0)!=0)+h|0;g=1}f=g;G[c>>2]=e}return f}function cn(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0;d=Fa-48|0;Fa=d;f=362;a:{if(!a|!b){break a}if(!G[b>>2]){f=0;break a}f=0;G[d+44>>2]=0;if((c|0)>998){break a}while(1){c=c+1|0;i=92041;f=0;h=0;while(1){e=G[b+4>>2];G[d+20>>2]=d+39;G[d+16>>2]=d+40;g=e;e=M(f,176);j=Qc((g+e|0)+4|0,30740,d+16|0);g=G[b+4>>2];b:{if((j|0)==1){e=e+g|0;if(G[e>>2]!=2|G[d+40>>2]!=(c|0)){break b}h=G[e+80>>2];break b}G[d+4>>2]=d+39;G[d>>2]=d+40;if((Qc((e+g|0)+4|0,30750,d)|0)!=1){break b}e=e+G[b+4>>2]|0;if(G[e>>2]!=2|G[d+40>>2]!=(c|0)){break b}i=G[e+80>>2]}c:{if(!(!h|!H[i|0])){e=0;break c}e=1;g=(G[b>>2]-1|0)>(f|0);f=f+1|0;if(g){continue}}break}f=G[d+44>>2];if(!(f|!h)){Bi(a,c,i,h,d+44|0);f=G[d+44>>2]}if(!(!f&(e^-1))){break a}if((c|0)!=999){continue}break}f=0}Fa=d+48|0;return f}function or(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;g=G[c+4>>2];h=g>>31;a:{if(((h^g)-h|0)!=501){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=67;E[c+1|0]=79;E[c+2|0]=80;E[c+3|0]=0;G[c+4>>2]=(g|0)<0?-501:501;f=L[c+40>>3];L[c+16>>3]=f;if(L[c+24>>3]==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020}f=Kb(f);L[c+112>>3]=f;g=1;if(f==0){break a}L[c+120>>3]=1/f;f=L[c+24>>3]*Mb(L[c+48>>3]);L[c+136>>3]=f;if(f==0){break a}L[c+144>>3]=1/f;f=Xe(L[c+40>>3]);G[c+1892>>2]=127;G[c+1888>>2]=128;f=1/f;L[c+152>>3]=f;L[c+128>>3]=f*L[c+136>>3]}g=2;b=b-L[c+40>>3];f=Mb(b);if(f==0){break a}i=L[c+112>>3];b=L[c+128>>3]-L[c+136>>3]*Kb(b)/f;a=i*a;j=d,k=Kb(a)*b,L[j>>3]=k;j=e,k=L[c+128>>3]-b*Mb(a),L[j>>3]=k;if(G[c+4>>2]>0&b*L[c+112>>3]<0){break a}g=0}return g|0}function ph(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;j=Fa-16|0;Fa=j;a:{if(G[i>>2]>0){break a}l=G[a>>2];k=G[a+4>>2];b:{c:{if((l|0)!=G[k+76>>2]){mb(a,l+1|0,0,i);break c}if((G[k+128>>2]&G[k+132>>2])!=-1){break c}if((Rb(a,i)|0)>0){break b}}l=b-1|0;b=G[a+4>>2];m=G[b+968>>2];k=M(l,160)+m|0;if(G[k+80>>2]>=0){G[i>>2]=317}n=G[k+76>>2];o=G[b+132>>2];p=G[k+72>>2];q=G[b+128>>2];d=Au(G[b+960>>2],G[b+964>>2],c-1|0,d-!c|0);c=q+d|0;b=Ia+o|0;b=c>>>0>>0?b+1|0:b;d=c;c=p+c|0;b=b+n|0;Jb(a,c,c>>>0>>0?b+1|0:b,1,i);if(!(H[k+140|0]!=80&H[(m+M(l,160)|0)+141|0]!=80)){b=f|h;if((b|0)==1|b>>>0>1){tb(5,23719);G[i>>2]=412;break a}G[j+4>>2]=g;G[j>>2]=e;$c(a,2,4,j,i);break b}G[j+8>>2]=g;G[j+12>>2]=h;G[j>>2]=e;G[j+4>>2]=f;_c(a,2,8,j,i)}}Fa=j+16|0}function fn(a,b,c,d,e){var f=0,g=0,h=0,i=0;f=Fa-144|0;Fa=f;a:{b:{c:{if((c|0)<=7){if((c|0)==-64|(c|0)==-32){break c}break b}h=c-8|0;if(!(h>>>0>24|!(1<>2]=0;if(Cb(a,82,34377,f+128|0,0,f+140|0)){G[f+128>>2]=0;G[f+132>>2]=0}G[f+140>>2]=0;d:{e:{if(Cb(a,82,35661,f+48|0,0,f+140|0)){G[f+48>>2]=0;G[f+52>>2]=1072693248;break e}g=L[f+48>>3];if(g!=1){break d}}i=L[f+128>>3];if(i!=0){g=1;if(i!=32768){break d}}G[d+84>>2]=259;G[e+80>>2]=41;c=0;break a}G[d+84>>2]=260;G[e+80>>2]=82;c=0;if(!G[309801]){break a}L[f+32>>3]=L[f+128>>3];G[f+16>>2]=b;L[f+24>>3]=g;gb(71006,f+16|0);break a}if((c|0)!=64){break b}}G[d+84>>2]=260;G[e+80>>2]=82;c=0;break a}G[f>>2]=c;a=f+48|0;Ya(a,80,78197,f);Ua(a);c=432;G[309737]=432}Fa=f+144|0;return c}function ec(a,b,c){var d=0,e=0,f=0,g=0,h=0;a:{if(!a|!b){break a}d=Va(b);if(!d){return a}if(!c){break a}e=(a+c|0)-d|0;if(e+1>>>0<=a>>>0){break a}f=d-1|0;h=H[f+b|0];g=H[b|0];b:{switch(f|0){case 0:while(1){if((g|0)!=H[a|0]){b=a>>>0>>0;a=a+1|0;if(b){continue}break a}break};return a;case 1:while(1){if(!((g|0)==H[a|0]&H[a+f|0]==(h|0))){b=a>>>0>>0;a=a+1|0;if(b){continue}break a}break};return a;default:break b}}if((d|0)>=2){while(1){c=a;c:{if((g|0)!=H[a|0]){break c}a=1;if(H[c+f|0]!=(h|0)){break c}while(1){if(H[a+c|0]!=H[a+b|0]){break c}a=a+1|0;if((d|0)!=(a|0)){continue}break}return c}a=c+1|0;if(c>>>0>>0){continue}break a}}while(1){if(!((g|0)!=H[a|0]|H[a+f|0]!=(h|0))){return a}b=a>>>0>>0;a=a+1|0;if(b){continue}break}}return 0}function dn(a){var b=0,c=0,d=0,e=0;d=Fa-1e4|0;Fa=d;a:{if(!a){b=362;break a}b=365;if(G[309830]>9){break a}b=ac(a,13287);c=G[309830];G[(c<<2)+1239344>>2]=b;b:{if(b){break b}b=Fd(33802);c:{if(!b){break c}b=rb(d,b,9999);E[b+9999|0]=0;b=pc(b,40241);if(!b){break c}while(1){c=ab((Va(a)+Va(b)|0)+2|0);if(!c){b=360;break a}b=Za(c,b);c=Va(b)+b|0;E[c|0]=47;E[c+1|0]=0;c=Gb(b,a);b=ac(c,13287);G[(G[309830]<<2)+1239344>>2]=b;Wa(c);if(b){break c}b=pc(0,40241);if(b){continue}break}}c=G[309830];if(G[(c<<2)+1239344>>2]){break b}b=366;if(!H[1239392]|H[a|0]==47){break a}c=ab((Va(a)+Va(1239392)|0)+1|0);if(!c){b=360;break a}e=Gb(Za(c,1239392),a);a=ac(e,13287);c=G[309830];G[(c<<2)+1239344>>2]=a;Wa(e);if(!a){break a}}b=0;G[309830]=c+1}Fa=d+1e4|0;return b}function Oo(a,b,c,d){a:{switch(b-9|0){case 0:b=G[c>>2];G[c>>2]=b+4;G[a>>2]=G[b>>2];return;case 6:b=G[c>>2];G[c>>2]=b+4;b=F[b>>1];G[a>>2]=b;G[a+4>>2]=b>>31;return;case 7:b=G[c>>2];G[c>>2]=b+4;G[a>>2]=I[b>>1];G[a+4>>2]=0;return;case 8:b=G[c>>2];G[c>>2]=b+4;b=E[b|0];G[a>>2]=b;G[a+4>>2]=b>>31;return;case 9:b=G[c>>2];G[c>>2]=b+4;G[a>>2]=H[b|0];G[a+4>>2]=0;return;case 16:b=G[c>>2]+7&-8;G[c>>2]=b+8;L[a>>3]=L[b>>3];return;case 17:Ja[d|0](a,c);default:return;case 1:case 4:case 14:b=G[c>>2];G[c>>2]=b+4;b=G[b>>2];G[a>>2]=b;G[a+4>>2]=b>>31;return;case 2:case 5:case 11:case 15:b=G[c>>2];G[c>>2]=b+4;G[a>>2]=G[b>>2];G[a+4>>2]=0;return;case 3:case 10:case 12:case 13:break a}}b=G[c>>2]+7&-8;G[c>>2]=b+8;c=G[b+4>>2];G[a>>2]=G[b>>2];G[a+4>>2]=c}function pn(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0;if(!H[1238788]){h=1238472,i=Wc(0)-1|0,G[h>>2]=i;G[309619]=0;E[1238788]=1}G[309727]=b;G[309726]=a;if(G[309723]>0){c=a-G[309732]|0;while(1){f=M(e,344);a=f+G[309722]|0;b=G[a>>2];a:{if((b|0)>0|(b|0)==-1e3){break a}g=M(b,-124);b=g+G[309730]|0;d=M(G[b+88>>2],c);G[a+84>>2]=d+G[b+116>>2];b:{switch(G[a+52>>2]-258|0){case 4:G[a+88>>2]=G[b+120>>2]+(c<<2);G[(G[309722]+f|0)+84>>2]=0;break a;case 3:G[a+88>>2]=G[b+120>>2]+(c<<2);G[(G[309722]+f|0)+84>>2]=G[(G[309730]+g|0)+116>>2]+c;break a;case 0:G[a+88>>2]=G[b+120>>2]+d;break a;case 1:G[a+88>>2]=G[b+120>>2]+(d<<2);break a;case 2:break b;default:break a}}G[a+88>>2]=G[b+120>>2]+(d<<3)}e=e+1|0;if((e|0)>2];h=g>>31;a:{b:{if(((h^g)-h|0)==501){f=L[c+128>>3];break b}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=67;E[c+1|0]=79;E[c+2|0]=80;E[c+3|0]=0;G[c+4>>2]=(g|0)<0?-501:501;f=L[c+40>>3];L[c+16>>3]=f;if(L[c+24>>3]==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020}f=Kb(f);L[c+112>>3]=f;g=1;if(f==0){break a}L[c+120>>3]=1/f;f=L[c+24>>3]*Mb(L[c+48>>3]);L[c+136>>3]=f;if(f==0){break a}L[c+144>>3]=1/f;f=Xe(L[c+40>>3]);G[c+1892>>2]=127;G[c+1888>>2]=128;f=1/f;L[c+152>>3]=f;f=f*L[c+136>>3];L[c+128>>3]=f}f=f-b;b=V(a*a+f*f);b=L[c+40>>3]<0?-b:b;if(b!=0){a=Ac(a/b,f/b)}else{a=0}L[d>>3]=a*L[c+120>>3];i=e,j=L[c+40>>3]+De(L[c+152>>3]-b*L[c+144>>3]),L[i>>3]=j;g=0}return g|0}function yd(a,b,c){var d=0,e=0;a:{if((a|0)==(b|0)){break a}e=a+c|0;if(b-e>>>0<=0-(c<<1)>>>0){bb(a,b,c);return}d=(a^b)&3;b:{c:{if(a>>>0>>0){if(d){break b}if(!(a&3)){break c}while(1){if(!c){break a}E[a|0]=H[b|0];b=b+1|0;c=c-1|0;a=a+1|0;if(a&3){continue}break}break c}d:{if(d){break d}if(e&3){while(1){if(!c){break a}c=c-1|0;d=c+a|0;E[d|0]=H[b+c|0];if(d&3){continue}break}}if(c>>>0<=3){break d}while(1){c=c-4|0;G[c+a>>2]=G[b+c>>2];if(c>>>0>3){continue}break}}if(!c){break a}while(1){c=c-1|0;E[c+a|0]=H[b+c|0];if(c){continue}break}break a}if(c>>>0<=3){break b}while(1){G[a>>2]=G[b>>2];b=b+4|0;a=a+4|0;c=c-4|0;if(c>>>0>3){continue}break}}if(!c){break a}while(1){E[a|0]=H[b|0];a=a+1|0;b=b+1|0;c=c-1|0;if(c){continue}break}}}function Om(a,b,c,d,e,f){var g=0;g=Fa-80|0;Fa=g;a:{if((f|0)>=16384){tc(g+32|0,b,c,d,e,0,0,0,2147352576);d=G[g+40>>2];e=G[g+44>>2];b=G[g+32>>2];c=G[g+36>>2];if(f>>>0<32767){f=f-16383|0;break a}tc(g+16|0,b,c,d,e,0,0,0,2147352576);f=((f|0)<49149?f:49149)-32766|0;d=G[g+24>>2];e=G[g+28>>2];b=G[g+16>>2];c=G[g+20>>2];break a}if((f|0)>-16383){break a}tc(g- -64|0,b,c,d,e,0,0,0,7471104);d=G[g+72>>2];e=G[g+76>>2];b=G[g+64>>2];c=G[g+68>>2];if(f>>>0>4294934644){f=f+16269|0;break a}tc(g+48|0,b,c,d,e,0,0,0,7471104);f=((f|0)>-48920?f:-48920)+32538|0;d=G[g+56>>2];e=G[g+60>>2];b=G[g+48>>2];c=G[g+52>>2]}tc(g,b,c,d,e,0,0,0,f+16383<<16);b=G[g+12>>2];G[a+8>>2]=G[g+8>>2];G[a+12>>2]=b;b=G[g+4>>2];G[a>>2]=G[g>>2];G[a+4>>2]=b;Fa=g+80|0}function cg(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;n=Fa-816|0;Fa=n;k=G[i>>2];if(!(!(d|e)|(k|0)>0)){Qd(a,n+12|0,i);o=G[n+12>>2];a:{if((o|0)<=0){break a}k=0;if(o-1>>>0>=3){p=o&-4;while(1){l=n+16|0;j=l+(k<<3)|0;m=G[(k<<2)+c>>2];G[j>>2]=m;G[j+4>>2]=m>>31;j=k|1;m=(j<<3)+l|0;j=G[(j<<2)+c>>2];G[m>>2]=j;G[m+4>>2]=j>>31;j=k|2;m=(j<<3)+l|0;j=G[(j<<2)+c>>2];G[m>>2]=j;G[m+4>>2]=j>>31;j=l;l=k|3;j=j+(l<<3)|0;l=G[(l<<2)+c>>2];G[j>>2]=l;G[j+4>>2]=l>>31;k=k+4|0;q=q+4|0;if((p|0)!=(q|0)){continue}break}}o=o&3;if(!o){break a}while(1){l=(n+16|0)+(k<<3)|0;p=G[(k<<2)+c>>2];G[l>>2]=p;G[l+4>>2]=p>>31;k=k+1|0;r=r+1|0;if((o|0)!=(r|0)){continue}break}}Bo(a,b,n+16|0,d,e,f,g,h,i);k=G[i>>2]}Fa=n+816|0;return k}function cb(a,b,c){var d=0,e=0,f=0;a:{if(!c){break a}E[a|0]=b;e=a+c|0;E[e-1|0]=b;if(c>>>0<3){break a}E[a+2|0]=b;E[a+1|0]=b;E[e-3|0]=b;E[e-2|0]=b;if(c>>>0<7){break a}E[a+3|0]=b;E[e-4|0]=b;if(c>>>0<9){break a}e=0-a&3;f=e+a|0;d=M(b&255,16843009);G[f>>2]=d;b=c-e&-4;c=b+f|0;G[c-4>>2]=d;if(b>>>0<9){break a}G[f+8>>2]=d;G[f+4>>2]=d;G[c-8>>2]=d;G[c-12>>2]=d;if(b>>>0<25){break a}G[f+24>>2]=d;G[f+20>>2]=d;G[f+16>>2]=d;G[f+12>>2]=d;G[c-16>>2]=d;G[c-20>>2]=d;G[c-24>>2]=d;G[c-28>>2]=d;c=b;b=f&4|24;c=c-b|0;if(c>>>0<32){break a}d=Au(d,0,1,1);e=Ia;b=b+f|0;while(1){G[b+24>>2]=d;G[b+28>>2]=e;G[b+16>>2]=d;G[b+20>>2]=e;G[b+8>>2]=d;G[b+12>>2]=e;G[b>>2]=d;G[b+4>>2]=e;b=b+32|0;c=c-32|0;if(c>>>0>31){continue}break}}return a}function bf(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0;i=Fa-1040|0;Fa=i;f=G[d>>2];if((f|0)<=0){while(1){a:{g=H[a+e|0];b:{if((g|0)!=47){if(!g){break a}e=e+1|0;break b}e=e+1|0;if(H[e+a|0]==47){continue}}E[h+i|0]=g;h=h+1|0;continue}break}E[h+i|0]=0;if(!f){a=H[i|0];f=(a|0)!=0;g=b-1|0;c:{d:{e:{if((b|0)<2){e=c;break e}if(!a){e=c;break e}h=i;e=c;while(1){b=a&255;f:{if(!(H[b+120112|0]?a<<24>>24>=32:0)){if((g|0)<=(j+2|0)){break d}E[e|0]=37;E[e+2|0]=H[(b&15)+35292|0];E[e+1|0]=H[(b>>>4|0)+35292|0];a=3;break f}E[e|0]=a;a=1}e=a+e|0;j=a+j|0;a=H[h+1|0];f=(a|0)!=0;if(!a){break e}h=h+1|0;if((g|0)>(j|0)){continue}break}}if(!f|(g|0)!=(j|0)){break c}}Ua(59124);G[d>>2]=125;e=c}E[e|0]=0;f=G[d>>2]}G[d>>2]=f}Fa=i+1040|0;return f}function lo(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;i=Fa-256|0;Fa=i;G[c>>2]=0;h=G[d>>2];a:{if((h|0)>0){break a}e=G[a>>2];f=G[a+4>>2];if((e|0)!=G[f+76>>2]){mb(a,e+1|0,0,d);h=G[d>>2];f=G[a+4>>2];e=G[f+76>>2]}g=G[f+104>>2];e=G[f+96>>2]+(e<<3)|0;j=G[e>>2];f=Bu(g-j|0,G[f+108>>2]-(G[e+4>>2]+(g>>>0>>0)|0)|0,80,0);if((h|0)>0){break a}e=lb(M(f,80)+81|0,1);G[b>>2]=e;b:{c:{d:{if(e){if((f|0)<=0){break c}break d}G[d>>2]=113;Ua(8075);break b}h=1;while(1){g=i+80|0;Sd(a,h,g,d);bb(Va(g)+g|0,68217,81);E[i|0]=0;qb(i,g,8);e=Za(e,g);G[c>>2]=G[c>>2]+1;e=e+80|0;g=(f|0)==(h|0);h=h+1|0;if(!g){continue}break}}a=bb(e,68136,81);G[c>>2]=G[c>>2]+1;E[a+80|0]=0;k=b,l=ub(G[b>>2],M(G[c>>2],80)|1),G[k>>2]=l}}Fa=i+256|0}function Hd(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0;i=Fa-96|0;Fa=i;d=G[a>>2];if((d|0)!=G[G[a+4>>2]+76>>2]){mb(a,d+1|0,0,c)}d=0;e=rb(i,b,80);E[e+80|0]=0;f=Va(e);a:{if(f){if((f|0)!=1){h=f&-2;b=0;while(1){g=d+e|0;if((H[g|0]-127&255)>>>0<=160){E[g|0]=32}g=(d|1)+e|0;if((H[g|0]-127&255)>>>0<=160){E[g|0]=32}d=d+2|0;b=b+2|0;if((h|0)!=(b|0)){continue}break}}b:{if(!(f&1)){break b}b=d+e|0;if((H[b|0]-127&255)>>>0>160){break b}E[b|0]=32}if(f>>>0>79){break a}}cb(e+f|0,32,80-f|0)}b=qc(e,36178);f=(b|0)==80?8:b;if(f){d=0;while(1){h=d+e|0;b=E[h|0];E[h|0]=b-97>>>0<26?b&95:b;d=d+1|0;if((f|0)!=(d|0)){continue}break}}ve(e,c);b=G[a+4>>2];d=G[b+120>>2];Jb(a,d-80|0,G[b+124>>2]-(d>>>0<80)|0,0,c);Wb(a,80,0,e,c);Fa=i+96|0}function zl(){var a=0,b=0,c=0,d=0,e=0;G[950222]=0;G[947120]=0;G[950221]=0;G[950328]=0;G[950217]=0;E[3801300]=0;G[951380]=0;G[951381]=0;G[948156]=0;G[951365]=0;E[3805528]=0;E[3796768]=0;E[3792672]=0;pb(G[950326]);G[950326]=0;pb(G[950327]);G[950327]=0;Ce(G[947122]);G[947122]=0;pb(G[948160]);G[948160]=0;b=G[950332];if(b){c=G[950330];if((c|0)>0){while(1){a=d<<2;e=G[a+b>>2];if(e){pb(G[e+24>>2]);pb(G[G[G[950332]+a>>2]+32>>2]);pb(G[G[G[950332]+a>>2]+40>>2]);pb(G[G[G[950332]+a>>2]+52>>2]);pb(G[G[950332]+a>>2]);c=G[950330];b=G[950332]}d=d+1|0;if((c|0)>(d|0)){continue}break}}pb(b);G[950332]=0}G[948164]=0;G[948165]=0;G[948166]=0;G[948167]=0;G[948162]=0;G[948163]=0;G[950330]=0;G[950331]=0}function Di(a,b,c,d,e){var f=0,g=0,h=0;g=Fa-176|0;Fa=g;f=G[e>>2];a:{if((f|0)>0){break a}G[c>>2]=0;E[g|0]=0;if(d){E[d|0]=0;f=G[e>>2];if((f|0)>0){break a}}if((kc(a,b,g+80|0,e)|0)<=0){mc(g+80|0,g,d,e)}f=G[e>>2];if((f|0)>0){break a}if(d){b=71-Va(d)|0}else{b=0}if(!H[g|0]){a=ab(1);G[c>>2]=a;E[a|0]=0;break a}f=ab(Va(g)+1|0);G[c>>2]=f;fd(g,f,e);f=Va(G[c>>2]);b:{if(!f){break b}while(1){if(H[(G[c>>2]+f|0)-1|0]!=38){break b}Ei(a,g,g+80|0,e);if(!H[g|0]){E[g+80|0]=0;break b}E[(G[c>>2]+f|0)-1|0]=0;h=G[c>>2];f=Va(g)+f|0;h=ub(h,f);G[c>>2]=h;Gb(h,g);f=f-1|0;if(!(!H[g+80|0]|(b|0)<=0)){h=Va(d)+d|0;E[h|0]=32;E[h+1|0]=0;b=71-Va(qb(d,g+80|0,b))|0}if(f){continue}break}}f=G[e>>2]}Fa=g+176|0;return f}function Aj(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;e=G[a+4>>2];g=M(e,e)<<3;d=ab(g);G[a+20>>2]=d;a:{b=1;b:{if(!d){break b}j=ab(g);G[a+24>>2]=j;if(!j){break a}if((e|0)>0){l=e&3;h=G[a+12>>2];m=G[a+16>>2];n=e-1>>>0<3;g=0;while(1){i=(k<<3)+m|0;b=g;c=0;if(l){while(1){f=b<<3;L[f+d>>3]=L[i>>3]*L[h+f>>3];b=b+1|0;c=c+1|0;if((l|0)!=(c|0)){continue}break}}g=e+g|0;if(!n){while(1){c=b<<3;L[c+d>>3]=L[i>>3]*L[c+h>>3];f=c+8|0;L[f+d>>3]=L[i>>3]*L[h+f>>3];f=c+16|0;L[f+d>>3]=L[i>>3]*L[h+f>>3];c=c+24|0;L[c+d>>3]=L[i>>3]*L[c+h>>3];b=b+4|0;if((b|0)!=(g|0)){continue}break}}k=k+1|0;if((k|0)!=(e|0)){continue}break}}b=2;if(sg(e,d,j)){break b}G[a>>2]=137;b=0}return b}Wa(d);return 1}function at(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;g=M(a,48);i=g+757232|0;e=g+757256|0;f=G[e>>2];h=c+f|0;j=c>>31;d=j+G[e+4>>2]|0;d=c>>>0>h>>>0?d+1|0:d;k=g+757240|0;l=G[G[k>>2]>>2];if(l>>>0>>0){f=G[g+757252>>2];if(!f){Ua(60039);return 106}m=G[G[i>>2]>>2];d=M(Bu(h-1|0,d-!h|0,2880,0),2880)+2880|0;a=l+G[M(a,48)+757248>>2]|0;a=a>>>0>>0?d:a;d=Ja[f|0](m,a)|0;if(!d){Ua(59999);return 113}G[G[i>>2]>>2]=d;G[G[k>>2]>>2]=a;f=G[e>>2]}bb(f+G[G[i>>2]>>2]|0,b,c);a=j+G[e+4>>2]|0;b=c+G[e>>2]|0;a=b>>>0>>0?a+1|0:a;c=b;G[e>>2]=c;G[e+4>>2]=a;e=g+757264|0;b=G[e+4>>2];d=G[e>>2];f=c;c=c>>>0>>0&(a|0)<=(b|0)|(a|0)<(b|0);G[e>>2]=c?d:f;G[e+4>>2]=c?b:a;return 0}function Yj(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0;g=Fa-16|0;Fa=g;e=G[c>>2];a:{if((e|0)>0){break a}Dc(a,g+12|0,c);if(G[g+12>>2]){Ua(8217);e=233;G[c>>2]=233;break a}e=Fa-16|0;Fa=e;d=G[c>>2];b:{if((d|0)>0){break b}d=G[a>>2];if((d|0)!=G[G[a+4>>2]+76>>2]){mb(a,d+1|0,0,c);d=G[c>>2];if((d|0)>0){break b}}d=G[a+4>>2];f=G[d+104>>2];h=G[d+96>>2]+(G[d+76>>2]<<3)|0;i=G[h>>2];d=M((Bu(f-i|0,G[d+108>>2]-(G[h+4>>2]+(f>>>0>>0)|0)|0,80,0)|0)/36|0,2880);f=lb(d+2881|0,1);G[b>>2]=f;c:{if(!f){G[c>>2]=113;Ua(8075);break c}ok(a,e+8|0,0,0,c);Jb(a,G[e+8>>2],G[e+12>>2],0,c);f=a;a=d+2880|0;ic(f,a,a>>31,G[b>>2],c);E[a+G[b>>2]|0]=0}d=G[c>>2]}Fa=e+16|0;if((d|0)>0){Ua(51004)}e=G[c>>2]}Fa=g+16|0;return e}function Qi(a,b,c,d,e,f,g){var h=0,i=0;h=Fa+-64|0;Fa=h;i=G[g>>2];a:{if((i|0)>0){break a}G[h+48>>2]=0;G[h+40>>2]=0;G[h+44>>2]=0;b:{if(Ti(h+8|0)){break b}G[h+12>>2]=b;G[h+8>>2]=a;G[h+20>>2]=G[c>>2];G[h+24>>2]=G[d>>2];c:{d:{e:{if(e){while(1){f:{switch(Ch(h+8|0)+5|0){case 6:break e;case 0:case 5:break f;default:break d}}a=Ja[e|0](G[c>>2],G[d>>2]+28800|0)|0;G[c>>2]=a;if(a){G[h+24>>2]=28800;b=a;a=G[d>>2];G[h+20>>2]=b+a;G[d>>2]=a+28800;continue}else{ye(h+8|0);break b}}}switch(Ch(h+8|0)+5|0){case 0:case 5:break c;case 6:break e;default:break d}}if(f){G[f>>2]=G[h+28>>2]}if(ye(h+8|0)){break b}i=G[g>>2];break a}ye(h+8|0);break b}ye(h+8|0)}i=414;G[g>>2]=414}Fa=h- -64|0;return i}function Nf(a){var b=0,c=0,d=0;b=1;c=H[a|0];a:{if((c|32)==106){break a}if(!Xa(a,41646)){break a}if(!Xa(a,41677)){break a}if(!Xa(a,33747)){break a}if(!Xa(a,6487)){break a}if(!fb(a,40253,3)){break a}if(!fb(a,40249,3)){break a}b=2;if((c|32)==98){break a}if(!Xa(a,41560)){break a}if(!Xa(a,41670)){break a}if(!fb(a,40370,3)){break a}if(!fb(a,40333,3)){break a}b=11;b:{switch(c-65|0){case 6:case 38:return 3;case 4:case 36:return 4;case 0:case 32:return 5;case 13:case 45:return 7;case 11:case 43:return 6;case 8:case 40:break a;default:break b}}if(!Ej(a,16895,5)){return 10}b=9;if((c|32)==112){break a}if(!ah(a)){return-1}b=1;d=sb(a);if(d>1980){break a}b=d>1900?2:-1}return b}function Pf(a,b,c,d){var e=0,f=0,g=0,h=0;a:{if((d|0)==1){break a}d=G[a+44>>2];if(c){e=+G[a+48>>2];b=G[a+8>>2]+M(b,168)|0;f=L[b+16>>3];h=e>3];e=e>g?e:g;b:{if(O(e)<2147483648){d=~~e;break b}d=-2147483648}if(!(h>=+(d|0))){break a}b=G[a+52>>2];while(1){G[b+(d<<2)>>2]=1;d=d+1|0;e=+G[a+48>>2];if(+(d|0)<=(e>2]+M(b,168)|0;f=L[b+8>>3]+-1;if(f>=+(d|0)){c=G[a+52>>2];while(1){G[c+(d<<2)>>2]=1;d=d+1|0;if(f>=+(d|0)){continue}break}}f=L[b+16>>3]+1;c:{if(O(f)<2147483648){d=~~f;break c}d=-2147483648}if((d|0)>G[a+48>>2]){break a}b=G[a+52>>2];while(1){G[b+(d<<2)>>2]=1;c=G[a+48>>2]>(d|0);d=d+1|0;if(c){continue}break}}}function xj(a){var b=0,c=0,d=0,e=0,f=0;E[a|0]=83;E[a+1|0]=90;E[a+2|0]=80;E[a+3|0]=0;G[a+16>>2]=0;G[a+20>>2]=1079410688;G[a+8>>2]=0;G[a+12>>2]=0;G[a+4>>2]=G[a+4>>2]<0?-102:102;b=L[a+24>>3];if(b==0){G[a+24>>2]=442745336;G[a+28>>2]=1078765020;b=57.29577951308232}L[a+112>>3]=1/b;b=L[a+40>>3]*Kb(L[a+56>>3])+1;L[a+136>>3]=b;if(b!=0){b=L[a+40>>3];e=a,f=Mb(L[a+56>>3])*-b*Kb(L[a+48>>3]),L[e+120>>3]=f;b=L[a+40>>3]*Mb(L[a+56>>3])*Mb(L[a+48>>3]);L[a+128>>3]=b;c=b;b=L[a+24>>3];L[a+152>>3]=c*b;L[a+144>>3]=b*L[a+120>>3];c=b;b=L[a+136>>3];L[a+160>>3]=c*b;c=b+-1;L[a+168>>3]=b*c+-1;d=-90;if(O(c)<1){d=Bc(1-b)}G[a+1892>>2]=111;G[a+1888>>2]=112;L[a+176>>3]=d;a=0}else{a=1}return a}function wr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0;a:{if(G[c+4>>2]==302){f=L[c+136>>3];break a}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=80;E[c+1|0]=65;E[c+2|0]=82;E[c+3|0]=0;E[c+4|0]=46;E[c+5|0]=1;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];b:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=.005555555555555556;g=180;h=1;i=1;break b}g=f*3.141592653589793;f=1/g;h=g/180;i=1/h}G[c+1892>>2]=121;G[c+1888>>2]=122;L[c+112>>3]=h;L[c+136>>3]=f;L[c+128>>3]=g;L[c+120>>3]=i}j=2;f=f*b;c:{if(f>1|f<-1){break c}b=0;g=f*-4*f+1;d:{if(g==0){if(a==0){break d}break c}b=L[c+120>>3]*a/g}L[d>>3]=b;k=e,l=Bc(f)*3,L[k>>3]=l;j=0}return j|0}function vc(a,b,c){var d=0,e=0,f=0,g=0,h=0;f=b-1|0;a:{if((b|0)>=2){b=a;b:{while(1){c:{d:{e:{d=G[c+4>>2];e=G[c+8>>2];if((d|0)==(e|0)){break e}g=Vi(d,10,e-d|0);f:{if(g){d=G[c+4>>2];e=(g-d|0)+1|0;break f}d=G[c+4>>2];e=G[c+8>>2]-d|0}h=d;d=e>>>0>>0?e:f;bb(b,h,d);e=d+G[c+4>>2]|0;G[c+4>>2]=e;b=b+d|0;if(g){break c}f=f-d|0;if(!f){break c}if((e|0)==G[c+8>>2]){break e}G[c+4>>2]=e+1;d=H[e|0];break d}d=Ag(c);if((d|0)>=0){break d}d=0;if((a|0)==(b|0)){break b}if(H[c|0]&16){break c}break b}E[b|0]=d;b=b+1|0;if((d&255)==10){break c}f=f-1|0;if(f){continue}}break}if(!a){d=0;break b}E[b|0]=0;d=a}break a}b=G[c+72>>2];G[c+72>>2]=b-1|b;if(f){break a}E[a|0]=0;return a}return d}function nn(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;e=Va(a);d=Va(c);h=(d|0)<(e|0)?e:d;g=ab(h+1|0);a:{b:{if((d|0)>(e|0)){f=d-e|0;if(f){cb(g,48,f)}if(!e){d=f;a=g;break b}bb(g+f|0,a,e);a=g;break b}if((d|0)>=(e|0)){break a}f=e-d|0;if(f){cb(g,48,f)}if(d){bb(g+f|0,c,d);c=e}else{c=f}d=c;c=g}E[d+g|0]=0}d=0;e=0;if(h){f=1;while(1){h=h-1|0;j=H[h+a|0];c:{if((j&223)==88){break c}i=H[c+h|0];if((i|0)==120|(i|0)==88){break c}d=((j|0)==49?f:0)+d|0;e=((i|0)==49?f:0)+e|0;f=f<<1}if(h){continue}break}}d:{switch(b-280|0){case 1:Wa(g);return(d|0)<(e|0);case 2:Wa(g);return(d|0)<=(e|0);case 0:Wa(g);return(d|0)>(e|0);case 3:k=(d|0)>=(e|0);break;default:break d}}Wa(g);return k}function Dq(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0;i=G[d>>2];if((i|0)<=0){e=Fa-464|0;Fa=e;f=G[d>>2];a:{if((f|0)>0){break a}b:{if((kc(a,b,e+368|0,d)|0)>0){break b}Hd(a,c,d);b=G[a+4>>2];g=G[b+96>>2]+(G[b+76>>2]<<3)|0;h=G[g>>2];j=G[g+4>>2];g=G[b+120>>2];k=G[b+124>>2];mc(e+368|0,e+272|0,e+176|0,d);f=G[d>>2];if((f|0)>0){break a}rh();fd(e+272|0,e+80|0,d);f=G[d>>2];if((f|0)==204){qh();f=0;G[d>>2]=0;break a}b=Va(e+80|0);if(!b){break a}h=Bu(g-h|0,k-(j+(g>>>0>>0)|0)|0,80,0)+1|0;while(1){if(H[(b+e|0)+79|0]!=38){break b}Ei(a,e+80|0,e,d);if(!H[e+80|0]){break b}ig(a,h,d);b=Va(e+80|0);if(b){continue}break}}f=G[d>>2]}Fa=e+464|0;if((f|0)==202){G[d>>2]=i;wb(a,c,d)}}}function us(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;l=+l;m=+m;n=+n;o=+o;var p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;if(j>k){while(1){j=j+-360;if(k>2]+M(c,3)|0;vf(a,0,q-2|0,d,e,f,g,h,i,m,n);Ze(a,1,q-1|0,d,e,h,i,j,k);if(O(l)<2147483648){q=~~l}else{q=-2147483648}p=(q|0)<=0;if(O(o)<2147483648){s=~~o}else{s=-2147483648}if(!(p|(s|0)<=0)){o=(n-m)/o;n=(k-j)/l;v=c+1|0;while(1){l=+(r|0)*n+j;r=r+1|0;k=+(r|0)*n+j;p=0;while(1){u=t<<1;w=+(p|0)*o+m;p=p+1|0;vf(a,b+t|0,u+c|0,d,e,f,g,h,i,w,+(p|0)*o+m);Ze(a,1,v+u|0,d,e,h,i,l,k);t=t+1|0;if((p|0)!=(s|0)){continue}break}if((q|0)!=(r|0)){continue}break}}}function su(a,b,c){a=a|0;b=+b;c=+c;var d=0,e=0,f=0,g=0;e=Fa-65584|0;Fa=e;a:{if((a|0)<=0|G[968816]<=(a|0)){break a}d=G[968817];if(!d){break a}a=d+M(a,65544)|0;d=G[a>>2];if(!d){break a}Bd(d,b,c,e+40|0,e+32|0,e+28|0);L[e>>3]=L[e+40>>3];L[e+8>>3]=L[e+32>>3];Ya(e+48|0,65535,18893,e);g=a+8|0;a=g;d=H[e+48|0];b:{if(!d){break b}f=e+48|0;while(1){a=d<<24>>24;if(!((a|0)==32|a-9>>>0<5)){a=g;while(1){E[a|0]=d;a=a+1|0;d=H[f+1|0];f=f+1|0;if(d){continue}break}break b}d=H[f+1|0];f=f+1|0;if(d){continue}break}a=g}E[a|0]=0;d=a-g|0;if(!d){break a}while(1){a=a-1|0;f=E[a|0];if(!((f|0)==32|f-9>>>0<5)){break a}E[a|0]=0;d=d-1|0;if(d){continue}break}}Fa=e+65584|0;return g|0}function gj(a,b,c,d,e){var f=0,g=0;f=Fa-416|0;Fa=f;g=G[e>>2];a:{if((g|0)>0){break a}b:{if((Vc(a,b,f+336|0,f+176|0,e)|0)>0){break b}g=f+256|0;kl(c,g,e);c=b;b=f+80|0;Ob(c,g,d?H[d|0]==38?f+176|0:d:f+176|0,b,e);Hd(a,b,e);b=G[a+4>>2];c=G[b+120>>2];d=G[b+96>>2]+(G[b+76>>2]<<3)|0;g=G[d>>2];c=Bu(c-g|0,G[b+124>>2]-(G[d+4>>2]+(c>>>0>>0)|0)|0,80,0);g=G[e>>2];if((g|0)>0){break a}rh();fd(f+336|0,f+256|0,e);g=G[e>>2];if((g|0)==204){qh();g=0;G[e>>2]=0;break a}b=Va(f+256|0);if(!b){break a}c=c+1|0;while(1){if(H[(b+f|0)+255|0]!=38){break b}Ei(a,f+256|0,f,e);if(!H[f+256|0]){break b}ig(a,c,e);b=Va(f+256|0);if(b){continue}break}}g=G[e>>2]}Fa=f+416|0;return g}function Ai(a,b){var c=0,d=0,e=0;E[b|0]=0;a:{while(1){c=a+d|0;e=H[c|0];if((e|0)!=32){b:{if(!e){break b}if(jb(c,37)){break b}E[b|0]=37;Za(b+1|0,c+1|0);c:{switch(H[c|0]-65|0){case 0:case 32:a=Va(b)+b|0;E[a|0]=115;E[a+1|0]=0;return;case 8:case 40:a=Va(b)+b|0;E[a|0]=100;E[a+1|0]=0;return;case 14:case 46:a=Va(b)+b|0;E[a|0]=111;E[a+1|0]=0;return;case 25:case 57:a=Va(b)+b|0;E[a|0]=88;E[a+1|0]=0;return;case 5:case 37:a=Va(b)+b|0;E[a|0]=102;E[a+1|0]=0;return;case 6:case 38:a=Va(b)+b|0;E[a|0]=71;E[a+1|0]=0;return;case 3:case 4:case 35:case 36:break a;default:break c}}E[b|0]=0}}else{d=d+1|0;continue}break}return}a=Va(b)+b|0;E[a|0]=69;E[a+1|0]=0}function pt(a,b){a=a|0;b=b|0;var c=0,d=0;G[b>>2]=-1;a=0;a:{b:{c:{while(1){d=M(a,48)+757232|0;if(!G[d>>2]){c=a;break c}c=a+1|0;d=M(c,48)+757232|0;if(!G[d>>2]){break c}c=a+2|0;d=M(c,48)+757232|0;if(!G[d>>2]){break c}c=a+3|0;d=M(c,48)+757232|0;if(!G[d>>2]){break c}c=a+4|0;d=M(c,48)+757232|0;if(!G[d>>2]){break c}a=a+5|0;if((a|0)!=1e4){continue}break}a=103;break b}G[b>>2]=c;a=M(c,48);b=a+757236|0;G[d>>2]=b;c=a+757244|0;G[a+757240>>2]=c;d=b;b=ab(2880);G[d>>2]=b;if(b){break a}Ua(57797);a=104}Ua(60080);return a|0}G[c>>2]=2880;b=a+757256|0;G[b>>2]=0;G[b+4>>2]=0;G[a+757248>>2]=2880;b=a+757264|0;G[b>>2]=0;G[b+4>>2]=0;G[a+757252>>2]=17;return 0}function Al(a){var b=0,c=0,d=0,e=0;a:{b:{c=G[945062];c:{if(!c){c=ab(4);G[945062]=c;if(!c){break b}G[c>>2]=0;G[950329]=1;G[945063]=0;break c}e=G[945063];b=G[950329];if(e>>>0>>0){break c}d=b+8|0;c=ub(c,d<<2);G[945062]=c;if(!c){break a}b=(b<<2)+c|0;G[b>>2]=0;G[b+4>>2]=0;G[b+24>>2]=0;G[b+28>>2]=0;G[b+16>>2]=0;G[b+20>>2]=0;G[b+8>>2]=0;G[b+12>>2]=0;G[950329]=d}b=(e<<2)+c|0;d=G[b>>2];if((d|0)!=(a|0)){if(d){d=G[945064];E[d|0]=H[3780260];G[G[b>>2]+8>>2]=d;G[G[b>>2]+16>>2]=G[950324]}c=(e<<2)+c|0;G[c>>2]=a;G[950324]=G[a+16>>2];a=G[a+8>>2];G[945070]=a;G[945064]=a;G[945057]=G[G[c>>2]>>2];E[3780260]=H[a|0]}return}qd(64041);W()}qd(64041);W()}function ru(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;a:{if((a|0)<=0|G[968816]<=(a|0)){break a}d=G[968817];if(!d){break a}e=M(a,65544)+d|0;if(!G[e>>2]){break a}f=M(a,65544)+d|0;E[f+8|0]=0;c=Xc(ul(a,0),13234)?b:8039;if(!(!c|!H[c|0])){b=G[e>>2];d=M(a,65544)+d|0;b:{if(!Xc(c,8039)){if(b){wq(b,1)}a=1;break b}if(b){wq(b,0)}a=G[e>>2];if(!(!a|!G[a+3312>>2])){G[a+3288>>2]=3}a=0}G[d+4>>2]=a}c=f+8|0;c:{d:{switch(G[f+4>>2]){case 1:rb(c,8039,65535);break c;case 0:break d;default:break c}}rb(c,16935,65535)}b=H[c|0];if(!b){break a}a=c;while(1){b=b<<24>>24;if(b-65>>>0<26){E[a|0]=b-65>>>0<26?b|32:b}b=H[a+1|0];a=a+1|0;if(b){continue}break}}return c|0}function Wm(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;if(G[(M(G[G[a+4>>2]+4>>2],84)+1240576|0)+52>>2]){sh(a,0,d);e=G[a+4>>2];G[e+64>>2]=b;G[e+68>>2]=c;G[e+32>>2]=b;G[e+36>>2]=c;G[e+56>>2]=b;G[e+60>>2]=c;G[e+40>>2]=b;G[e+44>>2]=c;i=G[a+4>>2];e=i;k=G[e+32>>2];e=G[e+36>>2];while(1){h=j<<2;f=(h+i|0)+1256|0;g=G[f>>2];g=Au(g,g>>31,2880,0);l=Ia;if((l|0)>=(e|0)&g>>>0>=k>>>0|(e|0)<(l|0)){G[f>>2]=-1}h=((h|4)+i|0)+1256|0;f=G[h>>2];f=Au(f,f>>31,2880,0);g=Ia;if((g|0)>=(e|0)&f>>>0>=k>>>0|(e|0)<(g|0)){G[h>>2]=-1}j=j+2|0;if((j|0)!=40){continue}break}a=G[a+4>>2];m=d,n=Ja[G[(M(G[a+4>>2],84)+1240576|0)+52>>2]](G[a>>2],b,c)|0,G[m>>2]=n}}function Ql(a){var b=0,c=0,d=0;if(!(!a|!H[a|0])){c=Xb(Va(a)+1|0);b=c;d=H[a|0];a:{if(!d){break a}while(1){b=d<<24>>24;if(!((b|0)==32|b-9>>>0<5)){b=c;while(1){E[b|0]=d;b=b+1|0;d=H[a+1|0];a=a+1|0;if(d){continue}break}break a}d=H[a+1|0];a=a+1|0;if(d){continue}break}b=c}E[b|0]=0;a=b-c|0;b:{if(!a){break b}while(1){b=b-1|0;d=E[b|0];if(!((d|0)==32|d-9>>>0<5)){break b}E[b|0]=0;a=a-1|0;if(a){continue}break}}b=H[c|0];if(b){a=c;while(1){b=b<<24>>24;if(b-65>>>0<26){E[a|0]=b-65>>>0<26?b|32:b}b=H[a+1|0];a=a+1|0;if(b){continue}break}}b=1;c:{if(!Xa(c,19834)){break c}if(!Xa(c,7232)){break c}if(!Xa(c,15732)){break c}b=!Xa(c,41541)}pb(c)}return b}function er(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;if(G[c+4>>2]!=602){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=80;E[c+1|0]=67;E[c+2|0]=79;E[c+3|0]=0;E[c+4|0]=90;E[c+5|0]=2;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];a:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;g=1;h=1;f=114.59155902616465;break a}g=f*3.141592653589793/180;h=1/g;f=f+f}G[c+1892>>2]=137;G[c+1888>>2]=138;L[c+112>>3]=g;L[c+128>>3]=f;L[c+120>>3]=h}f=0;h=Mb(b);g=Kb(b);b:{if(g==0){L[d>>3]=L[c+112>>3]*a;break b}f=h/g;a=g*a;i=d,j=f*L[c+24>>3]*Kb(a),L[i>>3]=j;f=L[c+24>>3]*(f*(1-Mb(a))+b*3.141592653589793/180)}L[e>>3]=f;return 0}function Gr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;h=G[c+4>>2];l=h>>31;a:{if(((h^l)-l|0)!=102){h=1;if(xj(c)){break a}}g=L[c+112>>3];i=g*a;f=L[c+136>>3];a=(i-L[c+120>>3])/f;j=g*b;k=(j-L[c+128>>3])/f;b=i*a+j*k;m=a;f=i*i+j*j;b:{if(f<1e-10){L[e>>3]=V(f/(b+1))*-57.29577951308232+90;a=f*.5;break b}h=2;a=a*a+k*k;g=b-a;b=a+(f-b-b)+-1;f=a+1;a=g*g-b*f;if(a<0){break a}a=V(a);b=(a-g)/f;g=(-g-a)/f;a=b>g?b:g;c:{if(!(a>1)){break c}f=a+-1;a=1;if(f<1e-13){break c}a=b-1e-13?-1:a:a;if(a>1|a<-1){break a}n=e,o=Bc(a),L[n>>3]=o;a=1-a}n=d,o=Ac(i-m*a,-(j-k*a)),L[n>>3]=o;h=0}return h|0}function wh(a){var b=0,c=0,d=0,e=0;c=G[48836];b=G[48835];if((b|0)<=2){d=G[48834];e=H[d+a|0];G[48834]=d+1;c=e|c<<8;G[48836]=c;b=b+8|0}d=b-3|0;G[48835]=d;e=c>>d&7;if(e>>>0<=3){return 1<>>b&1|e<<1;if(d>>>0<=12){e=d-8|0;if(e>>>0<5){break b}}if(b){b=b-1|0}else{b=G[48834];c=H[b+a|0];G[48836]=c;G[48834]=b+1;b=7}G[48835]=b;d=c>>>b&1|d<<1;e=d-26|0;if(e>>>0<5){break a}if(b){a=b-1|0}else{b=a;a=G[48834];c=H[b+a|0];G[48836]=c;G[48834]=a+1;a=7}G[48835]=a;return(c>>>a&1|d<<1)==62?0:14}return G[(e<<2)+118948>>2]}return G[(e<<2)+118968>>2]}function Lk(a,b,c,d,e){var f=0,g=0,h=0,i=0;f=Fa-208|0;Fa=f;G[f+204>>2]=c;c=f+160|0;cb(c,0,40);G[f+200>>2]=G[f+204>>2];a:{if((fp(0,b,f+200|0,f+80|0,c,d,e)|0)<0){e=-1;break a}i=G[a+76>>2]>=0;g=G[a>>2];if(G[a+72>>2]<=0){G[a>>2]=g&-33}b:{c:{d:{if(!G[a+48>>2]){G[a+48>>2]=80;G[a+28>>2]=0;G[a+16>>2]=0;G[a+20>>2]=0;h=G[a+44>>2];G[a+44>>2]=f;break d}if(G[a+16>>2]){break c}}c=-1;if(el(a)){break b}}c=fp(a,b,f+200|0,f+80|0,f+160|0,d,e)}if(h){Ja[G[a+36>>2]](a,0,0)|0;G[a+48>>2]=0;G[a+44>>2]=h;G[a+28>>2]=0;b=G[a+20>>2];G[a+16>>2]=0;G[a+20>>2]=0;c=b?c:-1}b=a;a=G[a>>2];G[b>>2]=a|g&32;e=a&32?-1:c;if(!i){break a}}Fa=f+208|0;return e}function tj(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0;G[a+8>>2]=0;G[a+12>>2]=0;E[a|0]=67;E[a+1|0]=79;E[a+2|0]=79;E[a+3|0]=0;E[a+4|0]=248;E[a+5|0]=1;E[a+6|0]=0;E[a+7|0]=0;c=L[a+40>>3];L[a+16>>3]=c;if(L[a+24>>3]==0){G[a+24>>2]=442745336;G[a+28>>2]=1078765020}b=L[a+48>>3];d=c-b;e=Xe((90-d)*.5);f=Mb(d);c=c+b;a:{if(c==d){b=Kb(d);break a}b=Xe((90-c)*.5);b=oc(Mb(c)/f)/oc(b/e)}L[a+112>>3]=b;g=1;b:{if(b==0){break b}L[a+120>>3]=1/b;c=f/b*L[a+24>>3]/$b(e,b);L[a+136>>3]=c;if(c==0){break b}b=Xe((90-L[a+40>>3])*.5);G[a+1892>>2]=133;G[a+1888>>2]=134;L[a+144>>3]=1/L[a+136>>3];h=a,i=c*$b(b,L[a+112>>3]),L[h+128>>3]=i;g=0}return g}function kf(a,b,c){var d=0,e=0,f=0,g=0;d=Fa-352|0;Fa=d;e=G[c>>2];a:{if((e|0)>0){break a}b:{if((Vc(a,b,d+272|0,d+192|0,c)|0)>0){G[d>>2]=b;a=d+16|0;Ya(a,81,49178,d);Ua(a);break b}b=G[a+4>>2];e=G[b+120>>2];f=G[b+96>>2]+(G[b+76>>2]<<3)|0;g=G[f>>2];f=Bu(e-g|0,G[b+124>>2]-(G[f+4>>2]+(e>>>0>>0)|0)|0,80,0);ig(a,f,c);e=G[c>>2];if((e|0)>0){break a}rh();fd(d+272|0,d+112|0,c);e=G[c>>2];if((e|0)==204){qh();e=0;G[c>>2]=0;break a}b=Va(d+112|0);if(!b){break a}while(1){if(H[(b+d|0)+111|0]!=38){break b}Ei(a,d+112|0,d+16|0,c);if(!H[d+112|0]){break b}ig(a,f,c);b=Va(d+112|0);if(b){continue}break}}e=G[c>>2]}Fa=d+352|0;return e}function hg(a,b,c,d){var e=0,f=0;e=Fa-48|0;Fa=e;a:{if(G[d>>2]>0){break a}E[c|0]=0;b:{c:{if((b|0)<0){f=+a;L[e+24>>3]=f;G[e+16>>2]=0-b;if((Ya(c,71,35121,e+16|0)|0)<0){Ua(17756);G[d>>2]=402;break b}if(jb(c,46)){break c}if(!jb(c,69)){break c}L[e>>3]=f;if((Ya(c,71,35739,e)|0)>=0){break b}Ua(17756);G[d>>2]=402;break a}G[e+32>>2]=b;L[e+40>>3]=a;if((Ya(c,71,35744,e+32|0)|0)>=0){break c}Ua(17756);G[d>>2]=402;break b}if(G[d>>2]>0){break b}b=jb(c,44);if(b){E[b|0]=46}if(jb(c,78)){Ua(35152);G[d>>2]=402;break b}if(jb(c,46)){break b}if(jb(c,69)){break b}if(Va(c)>>>0>69){break b}b=Va(c)+c|0;E[b|0]=46;E[b+1|0]=0}}Fa=e+48|0}function yj(a){var b=0,c=0,d=0,e=0;E[a|0]=65;E[a+1|0]=90;E[a+2|0]=80;E[a+3|0]=0;G[a+16>>2]=0;G[a+20>>2]=1079410688;G[a+8>>2]=0;G[a+12>>2]=0;G[a+4>>2]=G[a+4>>2]<0?-101:101;b=L[a+24>>3];if(b==0){G[a+24>>2]=442745336;G[a+28>>2]=1078765020;b=57.29577951308232}b=b*(L[a+40>>3]+1);L[a+112>>3]=b;d=1;a:{if(b==0){break a}b=Mb(L[a+48>>3]);L[a+136>>3]=b;if(b==0){break a}L[a+128>>3]=1/b;b=Kb(L[a+48>>3]);L[a+144>>3]=b;c=L[a+136>>3];L[a+120>>3]=b/c;e=-90;b=L[a+40>>3];if(O(b)>1){e=Bc(-1/b);c=L[a+136>>3];b=L[a+40>>3]}G[a+1892>>2]=109;G[a+1888>>2]=110;b=b*c;L[a+160>>3]=b;L[a+152>>3]=e;L[a+168>>3]=O(b)<1?1:0;d=0}return d}function Yr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0;if(G[c+4>>2]!=108){G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=90;E[c+1|0]=69;E[c+2|0]=65;E[c+3|0]=0;E[c+4|0]=108;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;f=L[c+24>>3];a:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=114.59155902616465;g=.008726646259971648;break a}f=f+f;g=1/f}G[c+1892>>2]=93;G[c+1888>>2]=94;L[c+112>>3]=f;L[c+120>>3]=g}f=V(a*a+b*b);if(f!=0){a=Ac(a,-b)}else{a=0}L[d>>3]=a;a=f*L[c+120>>3];b:{c:{if(O(a)>1){d=2;a=-90;if(O(f-L[c+112>>3])<1e-12){break c}break b}a=Bc(a);a=90-(a+a)}L[e>>3]=a;d=0}return d|0}function If(a,b,c,d){var e=0;e=Fa-48|0;Fa=e;a:{if(G[d>>2]>0){break a}E[c|0]=0;b:{c:{if((b|0)<0){L[e+24>>3]=a;G[e+16>>2]=0-b;if((Ya(c,71,35121,e+16|0)|0)<0){Ua(17798);G[d>>2]=402;break b}if(jb(c,46)){break c}if(!jb(c,69)){break c}L[e>>3]=a;if((Ya(c,71,35739,e)|0)>=0){break b}Ua(17798);G[d>>2]=402;break a}L[e+40>>3]=a;G[e+32>>2]=b;if((Ya(c,71,35744,e+32|0)|0)>=0){break c}Ua(17798);G[d>>2]=402;break b}if(G[d>>2]>0){break b}b=jb(c,44);if(b){E[b|0]=46}if(jb(c,78)){Ua(35245);G[d>>2]=402;break b}if(jb(c,46)){break b}if(jb(c,69)){break b}if(Va(c)>>>0>69){break b}b=Va(c)+c|0;E[b|0]=46;E[b+1|0]=0}}Fa=e+48|0}function vj(a){var b=0,c=0,d=0,e=0;G[a+8>>2]=0;G[a+12>>2]=0;E[a|0]=67;E[a+1|0]=79;E[a+2|0]=69;E[a+3|0]=0;E[a+4|0]=246;E[a+5|0]=1;E[a+6|0]=0;E[a+7|0]=0;b=L[a+40>>3];L[a+16>>3]=b;if(L[a+24>>3]==0){G[a+24>>2]=442745336;G[a+28>>2]=1078765020}c=L[a+48>>3];d=b-c;c=b+c;b=(Kb(d)+Kb(c))*.5;L[a+112>>3]=b;if(b!=0){L[a+120>>3]=1/b;L[a+136>>3]=L[a+24>>3]/b;c=Kb(d)*Kb(c)+1;L[a+144>>3]=c;b=L[a+112>>3];d=b+b;L[a+152>>3]=d;b=L[a+136>>3];L[a+160>>3]=c*(b*b);e=L[a+24>>3];L[a+168>>3]=1/(b*(e+e));L[a+176>>3]=b*V(c+d);e=Kb(L[a+40>>3]);G[a+1892>>2]=129;G[a+1888>>2]=130;L[a+128>>3]=b*V(c-d*e);a=0}else{a=1}return a}function ce(a,b,c){var d=0,e=0,f=0;d=Fa-1120|0;Fa=d;a:{if((b|0)==1){G[d+1116>>2]=6433650;break a}E[d+1118|0]=H[30819];F[d+1116>>1]=H[30817]|H[30818]<<8}b:{c:{if(H[a|0]!=126){break c}b=a+1|0;d:{e=H[a+1|0];if((e|0)!=47){a=0;while(1){if(!e|(e|0)==47){break d}E[a+d|0]=e;a=a+1|0;e=H[b+1|0];b=b+1|0;continue}}e=Fd(35450);if(e){f=104;if(Va(e)+Va(b)>>>0>1023){break b}a=Gb(Za(d+80|0,e),b);break c}f=104;if(Va(a)>>>0>1023){break b}a=Za(d+80|0,a);break c}E[a+d|0]=0;G[48624]=44;a=G[5];f=104;if(Va(a)+Va(b)>>>0>1023){break b}a=Gb(Za(d+80|0,a),b)}a=ac(a,d+1116|0);G[c>>2]=a;f=a?0:104}e=f;Fa=d+1120|0;return e}function ik(a,b,c){var d=0,e=0,f=0;f=Fa-160|0;Fa=f;d=G[c>>2];if(!d){e=Vc(a,35480,f+80|0,f,c);G[c>>2]=e;d=340;if((e|0)!=202){d=Va(f+80|0);if(!(H[f+80|0]!=39|H[(d+f|0)+79|0]!=39)){d=d-2|0;if((d|0)>0){e=f+80|0;yd(e,e|1,d)}E[d+(f+80|0)|0]=0}e=0;a:{b:{d=Va(f+80|0)-1|0;if((d|0)<=0){break b}while(1){if(H[(f+80|0)+e|0]!=32){break b}e=e+1|0;if((e|0)!=(d|0)){continue}break}break a}if((d|0)==(e|0)|(d|0)<0){break a}while(1){e=(f+80|0)+d|0;if(H[e|0]!=32){break a}E[e|0]=0;e=(d|0)>0;d=d-1|0;if(e){continue}break}}if(Ib(f+80|0,35090)){G[c>>2]=340;Ua(56591)}d=Ec(a,40853,b,f,c)}G[c>>2]=d}Fa=f+160|0;return d}function xc(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;a:{if((b|0)<0){break a}f=G[309722];c=f+M(a,344)|0;d=M(b,344)+f|0;G[c+56>>2]=G[d+56>>2];G[c+60>>2]=G[d+60>>2];e=G[d+60>>2];if((e|0)<=0){break a}d=0;if(e-1>>>0>=3){l=e&-4;while(1){h=(M(a,344)+f|0)- -64|0;c=d<<2;i=(M(b,344)+f|0)- -64|0;G[h+c>>2]=G[c+i>>2];g=c|4;G[g+h>>2]=G[i+g>>2];g=c|8;G[g+h>>2]=G[i+g>>2];c=c|12;G[c+h>>2]=G[c+i>>2];d=d+4|0;j=j+4|0;if((l|0)!=(j|0)){continue}break}}c=e&3;if(!c){break a}while(1){e=d<<2;G[(e+(M(a,344)+f|0)|0)- -64>>2]=G[(e+(M(b,344)+f|0)|0)- -64>>2];d=d+1|0;k=k+1|0;if((c|0)!=(k|0)){continue}break}}} -function $s(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;a=Fa-1248|0;Fa=a;G[a+12>>2]=0;b=G[g+28>>2];c=b-11|0;if(!(!(1<>>0<=31:0)&(b|0)!=82)){G[g>>2]=G[f+88>>2]}b=G[g+8>>2];if((b|0)>0){f=0;while(1){c=G[g+4>>2];d=G[((f<<2)+g|0)+12>>2];b=(a+16|0)+M(f,244)|0;G[b+84>>2]=0;G[b+80>>2]=82;G[b+4>>2]=d;G[b>>2]=c;b=G[g+8>>2];f=f+1|0;if((b|0)>(f|0)){continue}break}}if(L[g+152>>3]==-91191291391491e-49){c=G[g+4>>2];d=G[g+148>>2];b=(a+16|0)+M(b,244)|0;G[b+84>>2]=0;G[b+80>>2]=82;G[b+4>>2]=d;G[b>>2]=c;b=G[g+8>>2]+1|0}$f(b,a+16|0,0,0,20,g,a+12|0);Fa=a+1248|0;return G[a+12>>2]}function uu(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;b=Fa-80|0;Fa=b;a:{if((a|0)<=0|G[968816]<=(a|0)){break a}c=G[968817];if(!c){break a}d=c+M(a,65544)|0;a=G[d>>2];b:{if(!a){c=0;a=0;break b}e=L[a+48>>3];e=G[a+3256>>2]?-e:e;c=G[a+3304>>2];f=L[a+(c?768:760)>>3];g=L[a+(c?760:768)>>3];c=a+3848|0;h=a+3528|0;i=a+3512|0;j=L[a+624>>3];k=L[a+696>>3];l=L[a+616>>3];m=L[a+688>>3];a=a+3544|0}G[b+68>>2]=c;G[b- -64>>2]=a;G[b+60>>2]=h;G[b+56>>2]=i;L[b+48>>3]=e;L[b+40>>3]=g;L[b+32>>3]=f;L[b+24>>3]=j;L[b+16>>3]=l;L[b+8>>3]=k;L[b>>3]=m;d=d+8|0;Ya(d,65535,1566,b)}Fa=b+80|0;return d|0}function Sf(a,b,c,d,e,f,g,h){var i=0,j=0,k=0,l=0;i=1;j=d&2147483647;l=j;k=(j|0)==2147418112;a:{if(k&!c?a|b:k&(c|0)!=0|j>>>0>2147418112){break a}j=h&2147483647;k=(j|0)==2147418112;if(k&!g?e|f:k&(g|0)!=0|j>>>0>2147418112){break a}if(!(a|e|(c|g)|(b|f|(j|l)))){return 0}i=d&h;if((i|0)>0|(i|0)>=0){i=-1;if((c|0)==(g|0)&(d|0)==(h|0)?(b|0)==(f|0)&a>>>0>>0|b>>>0>>0:c>>>0>>0&(d|0)<=(h|0)|(d|0)<(h|0)){break a}return(a^e|c^g|(b^f|d^h))!=0}i=-1;if((c|0)==(g|0)&(d|0)==(h|0)?(b|0)==(f|0)&a>>>0>e>>>0|b>>>0>f>>>0:c>>>0>g>>>0&(d|0)>=(h|0)|(d|0)>(h|0)){break a}i=(a^e|c^g|(b^f|d^h))!=0}return i}function Sj(a,b){var c=0,d=0,e=0,f=0;f=G[48624];a:{b:{c:{if(!a){c=G[309704];break c}G[a+16>>2]=0;E[G[a+4>>2]]=0;E[G[a+4>>2]+1|0]=0;G[a+44>>2]=0;G[a+28>>2]=1;G[a+8>>2]=G[a+4>>2];c=G[309704];if(c){d=G[(G[309705]<<2)+c>>2]}else{d=0}if((d|0)!=(a|0)){break c}e=(G[309705]<<2)+c|0;d=G[e>>2];G[309738]=G[d+16>>2];d=G[d+8>>2];G[309706]=d;G[309710]=d;G[309700]=G[G[e>>2]>>2];E[1238828]=H[d|0];G[a+40>>2]=1;G[a>>2]=b;break b}G[a+40>>2]=1;G[a>>2]=b;if(c){break b}c=0;break a}c=G[(G[309705]<<2)+c>>2]}if((c|0)!=(a|0)){G[a+32>>2]=1;G[a+36>>2]=0}if(b){b=(Vj(gk(b))|0)>0}else{b=0}G[a+24>>2]=b;G[48624]=f}function $i(a,b){var c=0,d=0,e=0,f=0;f=G[48624];a:{b:{c:{if(!a){c=G[945062];break c}G[a+16>>2]=0;E[G[a+4>>2]]=0;E[G[a+4>>2]+1|0]=0;G[a+44>>2]=0;G[a+28>>2]=1;G[a+8>>2]=G[a+4>>2];c=G[945062];if(c){d=G[(G[945063]<<2)+c>>2]}else{d=0}if((d|0)!=(a|0)){break c}e=(G[945063]<<2)+c|0;d=G[e>>2];G[950324]=G[d+16>>2];d=G[d+8>>2];G[945064]=d;G[945070]=d;G[945057]=G[G[e>>2]>>2];E[3780260]=H[d|0];G[a+40>>2]=1;G[a>>2]=b;break b}G[a+40>>2]=1;G[a>>2]=b;if(c){break b}c=0;break a}c=G[(G[945063]<<2)+c>>2]}if((c|0)!=(a|0)){G[a+32>>2]=1;G[a+36>>2]=0}if(b){b=(Vj(gk(b))|0)>0}else{b=0}G[a+24>>2]=b;G[48624]=f}function zs(a,b,c,d,e,f,g,h){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;j=Fa-16|0;Fa=j;G[j+12>>2]=h;h=0;l=lb(1e3,8);m=lb(1e3,8);n=1e3;while(1){b=h+1|0;if((b|0)>=(n|0)){n=n+1e3|0;i=n<<3;l=ub(l,i);m=ub(m,i)}k=h<<3;o=k+l|0;i=G[j+12>>2]+7&-8;f=L[i>>3];L[o>>3]=f;G[j+12>>2]=i+16;k=m+k|0;g=L[i+8>>3];L[k>>3]=g;if(!(O(f+-9007199254740992)<=1e-15&O(g+-9007199254740992)<=1e-15)){p=f-+G[a+16>>2];f=+G[a+32>>2];L[o>>3]=p/f+1;L[k>>3]=(g-+G[a+24>>2])/f+1;h=b;continue}break}i=a;b=h<<3;a=ub(l,b);b=ub(m,b);Hj(i,0,c,d,e,a,b,h);if(a){Wa(a)}if(b){Wa(b)}Fa=j+16|0}function Fr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;j=G[c+4>>2];g=j>>31;a:{if(((g^j)-g|0)!=102){g=1;if(xj(c)){break a}}f=Mb(a);h=Kb(a);k=Mb(b);g=2;a=1-Kb(b);i=L[c+136>>3]-a;if(i==0){break a}L[d>>3]=(k*L[c+160>>3]*h-a*L[c+144>>3])/i;L[e>>3]=-(k*L[c+160>>3]*f+a*L[c+152>>3])/i;b:{if(G[c+4>>2]<=0){break b}if(L[c+176>>3]>b){break a}if(!(O(L[c+40>>3])>1)){break b}a=L[c+120>>3]*h-f*L[c+128>>3];f=1/V(a*a+L[c+168>>3]);if(!(O(f)<=1)){break b}i=b;b=Ac(a,L[c+136>>3]+-1);f=Bc(f);a=b-f;h=a>90?a+-360:a;a=b+f+180;a=a>90?a+-360:a;if(i<(a>2]==2){e=116;f=d+202504|0;d=f;i=G[d+4>>2];d=G[d>>2];if(zf(G[g>>2],d,d>>31,0)){break a}G[f>>2]=d;G[f+4>>2]=i}d=zc(b,1,c,G[g>>2]);if((d|0)==1){e=107;b:{c:{a=H[b|0];switch(a|0){case 0:case 10:break a;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:break b;default:break c}}if((a|0)==32){break a}}return 108}e=108;if((c|0)!=(d|0)){break a}a=M(a,24)+202504|0;d=a;b=c+G[d>>2]|0;a=G[d+4>>2]+(c>>31)|0;G[d>>2]=b;G[d+4>>2]=b>>>0>>0?a+1|0:a;G[h>>2]=1;e=0}return e|0}function _g(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;if(c!=2e3){ai(2e3,c,a,b)}c=(c+-2e3)*.01;f=(((c*.001813+-59e-5)*c+-46.815)*c+84381.448)*48481368110953e-19;c=eb(f);f=ib(f);e=L[b>>3];g=L[a>>3]*3.141592653589793/180;j=ib(g);h=e*3.141592653589793/180;e=eb(h);k=eb(g);g=c*0;i=g+0;h=ib(h);l=f*0;j=j*e;e=k*e;k=(f+i)*h+((l+(c+0))*j+((l+i)*e+0));i=h*0+(j*0+(e+0));d=Db(k,i);d=d<0?d+6.283185307179586:d;L[a>>3]=(d>6.283185307179586?d+-6.283185307179586:d)*180/3.141592653589793;d=c;c=0-l;m=b,n=Db(h*(d+c)+((g+(0-f))*j+((g+c)*e+0)),V(i*i+k*k))*180/3.141592653589793,L[m>>3]=n}function Ll(a,b,c,d){var e=0,f=0,g=0,h=0,i=0;g=Fa-16384|0;Fa=g;a:{if(!a|!H[a|0]){break a}b:{if(fb(a,42036,6)){if(fb(a,42025,7)){break b}}e=Lc(a);break a}if(!c){e=aj(a,b,d);break a}e=rb(g- -8192|0,c,8191);E[e+8191|0]=0;c=Ih(e);if(c){E[c|0]=0;f=c+1|0}while(1){c=f;c:{if(H[e|0]==36){e=Fd(e+1|0);if(!e){break c}e=Ll(a,b,e,d);if(!e){break c}break a}h=Sb(a,e);f=rb(g,a,8191);E[g+8191|0]=0;i=h;h=Va(f);if(!(H[i+h|0]?0:i)){if(Va(e)+h>>>0>8191){e=0;break a}Gb(f,e)}e=aj(f,b,d);if(e){break a}}if(!c){e=0;break a}f=0;e=c;c=Ih(e);if(!c){continue}E[c|0]=0;f=c+1|0;continue}}Fa=g+16384|0;return e}function _h(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;f=(c+-2e3)*.01;h=(((f*.001813+-59e-5)*f+-46.815)*f+84381.448)*48481368110953e-19;f=ib(h);h=eb(h);i=L[b>>3]*3.141592653589793/180;k=ib(i);e=L[a>>3];g=h*0;d=f*0;j=eb(i);e=e*3.141592653589793/180;i=j*ib(e);j=j*eb(e);l=j*0+0;e=k*(g+(0-f))+((d+(h+0))*i+l);m=0-d;n=g+0;g=k*(g+m)+((d+n)*i+(j+0));d=Db(e,g);d=d<0?d+6.283185307179586:d;L[a>>3]=(d>6.283185307179586?d+-6.283185307179586:d)*180/3.141592653589793;o=b,p=Db(k*(h+m)+((f+n)*i+l),V(g*g+e*e))*180/3.141592653589793,L[o>>3]=p;if(c!=2e3){ai(c,2e3,a,b)}}function fd(a,b,c){var d=0,e=0,f=0,g=0,h=0;a:{d=G[c>>2];if((d|0)<=0){d=H[a|0];b:{if((d|0)!=39){if(!d){E[b|0]=0;d=204;break b}Za(b,a);return G[c>>2]}g=Va(a);c:{if(g>>>0>=2){d=0;f=1;while(1){d:{h=H[a+f|0];e:{if((h|0)!=39){e=f;break e}e=f+1|0;if(H[e+a|0]!=39){break d}}E[b+d|0]=h;d=d+1|0;f=e+1|0;if(g>>>0>f>>>0){continue}}break}E[b+d|0]=0;if((f|0)==(g|0)){break c}if((d|0)<=0){break a}while(1){a=d-1|0;e=a+b|0;if(H[e|0]!=32){break a}E[e|0]=0;e=d>>>0>1;d=a;if(e){continue}break}break a}E[b|0]=0;if((g|0)!=1){break a}}tb(5,39759);tb(5,a);d=205}G[c>>2]=d}return d}return G[c>>2]}function fc(a){var b=0,c=0,d=0,e=0,f=0,g=0;A(+a);f=v(1)|0;e=v(0)|0;c=f&2147483647;if(c>>>0>=1072693248){if(!(c-1072693248|e)){return a*1.5707963267948966+752316384526264e-51}return 0/(a-a)}a:{if(c>>>0<=1071644671){if(c+-1048576>>>0<1044381696){break a}return a*hh(a*a)+a}b=(1-O(a))*.5;a=V(b);g=hh(b);b:{if(c>>>0>=1072640819){a=a*g+a;a=1.5707963267948966-(a+a+-6123233995736766e-32);break b}A(+a);e=v(1)|0;v(0)|0;x(0,0);x(1,e|0);d=b;b=+z();d=(d-b*b)/(a+b);a=.7853981633974483-(b+b)-((a+a)*g-(6123233995736766e-32-(d+d)))+.7853981633974483}a=(f|0)<0?-a:a}return a}function to(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;f=b;k=b<<2;g=ab(k);if(g){a:{if(!b&(c|0)<=0|(c|0)<0){break a}l=b&1;h=M(f,3);i=f<<1;d=a;e=g;if((b|0)!=1|c){m=b&-2;n=c;b=0;c=0;while(1){E[e|0]=H[d|0];E[e+f|0]=H[d+1|0];E[e+i|0]=H[d+2|0];E[e+h|0]=H[d+3|0];E[e+1|0]=H[d+4|0];j=e+1|0;E[j+f|0]=H[d+5|0];E[i+j|0]=H[d+6|0];E[h+j|0]=H[d+7|0];e=e+2|0;d=d+8|0;b=b+2|0;c=b>>>0<2?c+1|0:c;if((m|0)!=(b|0)|(c|0)!=(n|0)){continue}break}}if(!(l|o)){break a}E[e|0]=H[d|0];E[e+f|0]=H[d+1|0];E[e+i|0]=H[d+2|0];E[e+h|0]=H[d+3|0]}bb(a,g,k);Wa(g);return}Ua(73667)}function Is(a,b,c,d,e,f,g,h,i,j,k,l){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;l=+l;var m=0,n=0;a:{b:{if(j==0&k==0){break b}m=G[a+8>>2];h=L[(m+M(c,168)|0)+8>>3];if(g>3]=h)|!(L[(M(c,168)+m|0)+16>>3]>=g)){break b}e=0;m=G[(M(c,168)+m|0)+24>>2];if(O(g)<2147483648){c=~~g}else{c=-2147483648}c=G[m+(c<<2)>>2];c:{if(!c){break c}while(1){if(!(+G[c+4>>2]<=f)){break c}e=e+1|0;c=G[c>>2];if(c){continue}break}}if((e&1)!=(d|0)){break a}if(!b){return 1}if(!d){return 1}G[a+12>>2]=b;return 1}n=!d}return n|0}function uj(a){var b=0,c=0,d=0;G[a+8>>2]=0;G[a+12>>2]=0;E[a|0]=67;E[a+1|0]=79;E[a+2|0]=68;E[a+3|0]=0;E[a+4|0]=247;E[a+5|0]=1;E[a+6|0]=0;E[a+7|0]=0;c=L[a+40>>3];L[a+16>>3]=c;b=L[a+24>>3];if(b==0){G[a+24>>2]=442745336;G[a+28>>2]=1078765020;b=57.29577951308232}d=L[a+48>>3];b=b*Kb(c);if(d==0){b=b*3.141592653589793/180}else{b=b*Kb(L[a+48>>3])/L[a+48>>3]}L[a+112>>3]=b;if(b!=0){L[a+120>>3]=1/b;b=L[a+24>>3];c=Mb(L[a+48>>3]);d=Mb(L[a+40>>3]);G[a+1892>>2]=131;G[a+1888>>2]=132;b=d*(b*c)/L[a+112>>3];L[a+128>>3]=b;L[a+136>>3]=b+L[a+40>>3];a=0}else{a=1}return a}function vr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;if(G[c+4>>2]!=302){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=80;E[c+1|0]=65;E[c+2|0]=82;E[c+3|0]=0;E[c+4|0]=46;E[c+5|0]=1;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];a:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;h=.005555555555555556;f=180;g=1;i=1;break a}f=f*3.141592653589793;h=1/f;g=f/180;i=1/g}G[c+1892>>2]=121;G[c+1888>>2]=122;L[c+112>>3]=g;L[c+136>>3]=h;L[c+128>>3]=f;L[c+120>>3]=i}b=Kb(b/3);L[d>>3]=L[c+112>>3]*a*(b*(b*-4)+1);L[e>>3]=b*L[c+128>>3];return 0}function om(a,b){var c=0,d=0,e=0;c=Fa-16|0;Fa=c;Fa=c+16|0;d=0;a:{if(!b){break a}a=a?a:c+12|0;c=H[b|0];d=c<<24>>24;if((d|0)>=0){G[a>>2]=c;d=(d|0)!=0;break a}c=E[b|0];if(!G[G[48787]>>2]){G[a>>2]=c&57343;d=1;break a}b:{c=(c&255)-194|0;if(c>>>0>50){break b}d=H[b+1|0];e=d>>>3|0;c=G[(c<<2)+97264>>2];if((e-16|(c>>26)+e)>>>0>7){break b}c=d-128|c<<6;if((c|0)>=0){G[a>>2]=c;d=2;break a}d=H[b+2|0]-128|0;if(d>>>0>63){break b}c=d|c<<6;if((c|0)>=0){G[a>>2]=c;d=3;break a}b=H[b+3|0]-128|0;if(b>>>0>63){break b}G[a>>2]=b|c<<6;d=4;break a}G[48624]=25;d=-1}return d}function rs(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;l=+l;m=+m;n=n|0;o=+o;var p=0,q=0,r=0,s=0;p=G[a>>2]+M(c,3)|0;e=p-2|0;a:{if(d){if(!je(a,0,e,d,e,f,g,g,g,l,m,g)){break a}if(je(a,0,p-1|0,d,e,f,g,g,g,j,k,g)){break a}h=+(n|0);i=(m-k)/h;h=(l-j)/h;n=(n|0)>0?n:0;e=0;while(1){if((e|0)==(n|0)){return 0}q=1;r=b+e|0;s=c+e|0;p=e;e=e+1|0;l=+(e|0);if(!je(a,r,s,d,p,f,g,g,g,l*h+j,l*i+k,g)){continue}break}break a}q=1;if(!je(a,0,e,1,e,f,g,g,g,l,m,g)){break a}q=(je(a,0,p-1|0,1,e,f,g,g,g,j,k,g)|0)!=0}return q|0}function rb(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;e=a;a:{b:{c:{d:{if((e^b)&3){break d}d=(c|0)!=0;e:{if(!(b&3)|!c){break e}while(1){d=H[b|0];E[e|0]=d;if(!d){break a}e=e+1|0;c=c-1|0;d=(c|0)!=0;b=b+1|0;if(!(b&3)){break e}if(c){continue}break}}if(!d){break b}if(!H[b|0]){break a}if(c>>>0<4){break d}while(1){d=G[b>>2];if((d^-1)&d-16843009&-2139062144){break c}G[e>>2]=d;e=e+4|0;b=b+4|0;c=c-4|0;if(c>>>0>3){continue}break}}if(!c){break b}}while(1){d=H[b|0];E[e|0]=d;if(!d){break a}e=e+1|0;b=b+1|0;c=c-1|0;if(c){continue}break}}c=0}cb(e,0,c);return a|0}function bs(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;if(G[c+4>>2]!=104){G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=83;E[c+1|0]=84;E[c+2|0]=71;E[c+3|0]=0;E[c+4|0]=104;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;f=L[c+24>>3];a:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=114.59155902616465;g=.008726646259971648;break a}f=f+f;g=1/f}G[c+1892>>2]=87;G[c+1888>>2]=88;L[c+112>>3]=f;L[c+120>>3]=g}f=Kb(b)+1;if(f!=0){b=L[c+112>>3]*Mb(b)/f;h=d,i=Kb(a)*b,L[h>>3]=i;h=e,i=Mb(a)*-b,L[h>>3]=i;c=0}else{c=2}return c|0}function Oi(a,b,c,d,e,f,g){var h=0,i=0,j=0,k=0,l=0;i=Fa-240|0;Fa=i;h=G[d>>2];G[i+232>>2]=h;d=G[d+4>>2];G[i>>2]=a;G[i+236>>2]=d;k=1;a:{b:{c:{if(!(d|(h|0)!=1)){d=a;break c}l=0-b|0;h=a;while(1){j=(e<<2)+g|0;d=h-G[j>>2]|0;if((Ja[c|0](d,a)|0)<=0){d=h;break c}d:{if(!((e|0)<2|f)){f=G[j-8>>2];j=h+l|0;if((Ja[c|0](j,d)|0)>=0){break d}if((Ja[c|0](j-f|0,d)|0)>=0){break d}}G[(k<<2)+i>>2]=d;h=i+232|0;f=ep(h);Pi(h,f);k=k+1|0;e=e+f|0;f=0;h=d;if(G[i+236>>2]|G[i+232>>2]!=1){continue}break b}break}d=h;break b}if(f){break a}}dp(b,i,k);Kk(d,b,c,e,g)}Fa=i+240|0}function qr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;if(G[c+4>>2]!=401){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=65;E[c+1|0]=73;E[c+2|0]=84;E[c+3|0]=0;E[c+4|0]=145;E[c+5|0]=1;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=57.29577951308232}G[c+1892>>2]=125;G[c+1888>>2]=126;g=f+f;L[c+136>>3]=1/g;f=f*g;L[c+112>>3]=f;f=1/(f+f);L[c+120>>3]=f;L[c+128>>3]=f*.25}f=Mb(b);g=a*.5;a=V(L[c+112>>3]/(f*Mb(g)+1));h=d,i=Kb(g)*(f*(a+a)),L[h>>3]=i;h=e,i=a*Kb(b),L[h>>3]=i;return 0}function Md(a,b,c){var d=0,e=0;a=Ye(a,b);if(!a){return 0}a=a+(H[a|0]==35)|0;a:{if((Va(a)|0)>=82){rb(1285216,a,81);E[1285297]=0;break a}Za(1285216,a)}b:{if((ah(1285216)|0)!=2){break b}a=jb(1285216,68);if(a){E[a|0]=101}a=jb(1285216,100);if(a){E[a|0]=101}a=jb(1285216,69);if(!a){break b}E[a|0]=101}d=sb(1285216);e=d+.001;a=2147483647;c:{if(e>2147483647){break c}d:{if(d>=0){if(!(O(e)<2147483648)){break d}a=~~e;break c}d=d+-.001;a=-2147483648;if(d<-2147483648){break c}if(!(O(d)<2147483648)){break d}a=~~d;break c}a=-2147483648}G[c>>2]=a;return 1}function ej(){var a=0,b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;a=Fa-96|0;Fa=a;yb(36671);G[a+92>>2]=20397;G[a+88>>2]=16234;G[a+84>>2]=17989;G[a+80>>2]=2807;G[a+76>>2]=3696;G[a+72>>2]=3870;G[a+68>>2]=5251;G[a+64>>2]=13594;kb(68979,a- -64|0);if(G[935653]>0){while(1){b=G[935658]+M(c,56)|0;d=L[b+8>>3];e=L[b>>3];f=G[b+52>>2];g=G[b+48>>2];h=L[b+40>>3];i=L[b+32>>3];j=L[b+24>>3];L[a+16>>3]=L[b+16>>3];L[a+24>>3]=j;L[a+32>>3]=i;L[a+40>>3]=h;G[a+48>>2]=g;G[a+52>>2]=f;L[a>>3]=e;L[a+8>>3]=d;gb(73773,a);c=c+1|0;if((c|0)>16;b=a&65535;if(!((b|0)!=65535|(a|0)>393215)){a=G[(d<<2)+189004>>2];return a?a+8|0:35897}c=92041;a:{b:{c:{d:{switch(d-1|0){case 0:a=189028;if(b>>>0<=1){break c}break a;case 1:a=189040;if(b>>>0<=49){break c}break a;case 3:if(!b){break b}break a;case 4:break d;default:break a}}a=189360;if(b>>>0>3){break a}}e:{if(!b){c=a;break e}while(1){e=H[a|0];c=a+1|0;a=c;if(e){continue}a=c;b=b-1|0;if(b){continue}break}}if((d|0)==1){break a}}if(!H[c|0]){break a}}return c}function Ei(a,b,c,d){var e=0;e=Fa-176|0;Fa=e;if(G[d>>2]<=0){G[e+172>>2]=0;E[b|0]=0;a:{if((Jg(a,e+80|0,e+172|0)|0)>0){break a}if(!nb(e+80|0,67945,10)){F[e+88>>1]=H[67997]|H[67998]<<8;a=H[67993]|H[67994]<<8|(H[67995]<<16|H[67996]<<24);G[e+80>>2]=H[67989]|H[67990]<<8|(H[67991]<<16|H[67992]<<24);G[e+84>>2]=a;a=e+172|0;mc(e+80|0,e,c,a);fd(e,b,a);if(!G[e+172>>2]){break a}E[b|0]=0;break a}c=G[a>>2];b=G[a+4>>2];if((c|0)!=G[b+76>>2]){mb(a,c+1|0,0,d);b=G[a+4>>2]}a=G[b+120>>2];c=G[b+124>>2]-(a>>>0<80)|0;G[b+120>>2]=a-80;G[b+124>>2]=c}}Fa=e+176|0}function Rf(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0;g=Fa-80|0;Fa=g;a:{if(G[e>>2]){break a}f=G[a>>2];b:{if(H[f|0]!=32){h=f;break b}while(1){h=f+1|0;G[a>>2]=h;i=H[f+1|0];f=h;if((i|0)==32){continue}break}}b=qc(h,b);if(!b){break a}f=lb(b+1|0,1);G[c>>2]=f;if(!f){Ua(48441);G[e>>2]=113;break a}e=G[a>>2];qb(f,e,b);G[a>>2]=b+e;c:{if(!d){break c}G[d>>2]=1;a=G[c>>2];if(jb(a,68)){a=rb(g,a,72);E[a+72|0]=0;c=jb(a,68);G[g+76>>2]=c;if(c){E[c|0]=69}}vb(a,g+76|0);if((H[G[g+76>>2]]|32)!=32){G[d>>2]=0}if(G[48624]!=68){break c}G[d>>2]=0}j=b}Fa=g+80|0;return j}function yq(a){var b=0,c=0,d=0,e=0;d=a+100|0;e=G[a+116>>2];a:{while(1){b:{c:{if(G[a+104>>2]){break c}b=-1;if((xq(a)|0)==-1){break a}if(G[a+104>>2]){break c}Vd(a,-5,22164);b=G[a+116>>2];break b}d:{e:{f:{g:{c=Ch(d);switch(c+4|0){case 1:break e;case 0:break f;case 2:case 6:break g;default:break d}}Vd(a,-2,4566);return-1}Vd(a,-4,3221);return-1}b=a;a=G[a+124>>2];Vd(b,-3,a?a:10829);return-1}b=G[a+116>>2];if(!b){break b}if((c|0)!=1){continue}}break}b=e-b|0;G[a>>2]=b;G[a+4>>2]=G[a+112>>2]-b;b=0;if((c|0)!=1){break a}G[a+48>>2]=0;b=0}return b}function Ut(a){a=a|0;var b=0,c=0,d=0,e=0;c=Fa-16|0;Fa=c;a:{if(!a){break a}e=G[a>>2];b:{if(H[a+5008|0]){Bq(c+12|0,a,0);if(!G[c+12>>2]){break b}Bq(0,a,1);break b}G[c+12>>2]=0;G[a+5060>>2]=0;c:{if(!H[a+5064|0]){break c}b=G[a+5044>>2];if(!b|G[b>>2]!=(a+5012|0)){break c}d=G[b+3148>>2];if(d){Ja[G[a+5052>>2]](G[a+5056>>2],d)}d=G[b+3152>>2];if(d){Ja[G[a+5052>>2]](G[a+5056>>2],d)}b=G[b+3156>>2];if(b){Ja[G[a+5052>>2]](G[a+5056>>2],b)}Ja[G[a+5052>>2]](G[a+5056>>2],G[a+5044>>2])}Wa(a)}if(G[30060]==(e|0)|G[29763]==(e|0)){break a}Hb(e)}Fa=c+16|0}function lc(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0;f=Fa-176|0;Fa=f;if(G[e>>2]<=0){a:{if(!c){E[f+98|0]=H[65204];F[f+96>>1]=H[65202]|H[65203]<<8;break a}E[f+96|0]=39;h=1;b:{c:{d:{g=Va(c);j=g>>>0<68?g:68;if(j){while(1){g=H[c+i|0];E[(f+96|0)+h|0]=g;e:{if((g|0)!=39){g=h;break e}g=h+1|0;E[g+(f+96|0)|0]=39}h=g+1|0;i=i+1|0;if(g>>>0<68&j>>>0>i>>>0){continue}break}if(g>>>0>7){break d}c=h}else{c=1}h=9;cb(c+(f+96|0)|0,32,9-c|0);break c}c=69;if((h|0)==70){break b}}E[(f+96|0)+h|0]=39;c=h+1|0}E[c+(f+96|0)|0]=0}Ob(b,f+96|0,d,f,e);wb(a,f,e)}Fa=f+176|0}function Hr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;j=G[c+4>>2];h=j>>31;a:{if(((h^j)-h|0)!=101){h=1;if(yj(c)){break a}}i=Mb(a);h=2;f=Mb(b);g=i*L[c+120>>3];k=f*g+(L[c+40>>3]+Kb(b));if(k==0){break a}f=f*L[c+112>>3]/k;l=d,m=Kb(a)*f,L[l>>3]=m;L[e>>3]=i*-f*L[c+128>>3];b:{if(G[c+4>>2]<=0){break b}if(L[c+152>>3]>b){break a}if(!(L[c+168>>3]>0)){break b}a=L[c+40>>3]/V(g*g+1);if(!(O(a)<=1)){break b}f=b;b=De(-g);g=Bc(a);a=b-g;i=a>90?a+-360:a;a=b+g+180;a=a>90?a+-360:a;if(f<(a>2]==301){f=L[c+24>>3];break a}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=83;E[c+1|0]=70;E[c+2|0]=76;E[c+3|0]=0;E[c+4|0]=45;E[c+5|0]=1;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];b:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;g=1;f=57.29577951308232;h=1;break b}g=f*3.141592653589793/180;h=1/g}G[c+1892>>2]=99;G[c+1888>>2]=100;L[c+112>>3]=g;L[c+120>>3]=h}f=eb(b/f);if(f!=0){a=L[c+120>>3]*a/f}else{a=0}L[d>>3]=a;L[e>>3]=L[c+120>>3]*b;return 0}function Jn(a,b){var c=0,d=0,e=0,f=0;d=lb(511,1);if(!d){Ua(21335);return d}if(!fb(a,65400,4)){c=rb(d,b,255);b=Va(c);f=b&b>>31;while(1){a:{e=b;if((b|0)<=0){e=f;break a}b=e-1|0;if(H[c+b|0]!=47){continue}}break}E[c+e|0]=0;qb(c,a+4|0,255);return d}b:{if(jb(a,47)){break b}if(jb(a,36)){break b}c=rb(d,b,255);b=Va(c);f=b&b>>31;while(1){c:{e=b;if((b|0)<=0){e=f;break c}b=e-1|0;if(H[c+b|0]!=47){continue}}break}E[c+e|0]=0;qb(c,a,255);return d}if(!fb(a,34134,3)){a=rb(d,b,255);a=Va(a)+a|0;E[a-1|0]=120;a=a-3|0;E[a|0]=112;E[a+1|0]=105}return d}function Ao(a,b,c,d,e,f,g,h){var i=0;i=G[h>>2];if((i|0)<=0){a:{b:{switch(b-11|0){case 0:Sk(a,c,d,e,f,g,h);break a;case 1:Yo(a,c,d,e,f,g,h);break a;case 9:Vo(a,c,d,e,f,g,h);break a;case 10:Rk(a,c,d,e,f,g,h);break a;case 19:Po(a,c,d,e,f,g,h);break a;case 20:Fk(a,c,d,e,f,g,h);break a;case 29:To(a,c,d,e,f,g,h);break a;case 30:Mo(a,c,d,e,f,g,h);break a;case 69:Ro(a,c,d,e,f,g,h);break a;case 70:Gk(a,c,d,e,f,g,h);break a;case 31:Ho(a,c,d,e,f,g,h);break a;case 71:_o(a,c,d,e,f,g,h);break a;default:break b}}G[h>>2]=410}i=G[h>>2]}return i}function kh(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0;g=Fa-1040|0;Fa=g;e=G[c>>2];if(!e){h=Za(g,a);f=h;while(1){a:{e=a;a=H[a|0];if((a|0)!=37){if(!a){break a}E[f|0]=a;a=e+1|0;f=f+1|0;continue}a=e+1|0;d=H[e+1|0];if(!d){continue}a=d-48|0;b:{if((a&255)>>>0<10){break b}if((d-65&255)>>>0<=5){a=d-55|0;break b}a=d-87|0}i=a<<4;E[f|0]=i;a=e+2|0;d=H[e+2|0];if(!d){continue}a=d-48|0;c:{if((a&255)>>>0<10){break c}if((d-65&255)>>>0<=5){a=d-55|0;break c}a=d-87|0}E[f|0]=a+i;a=e+3|0;f=f+1|0;continue}break}E[f|0]=0;Za(b,h);e=G[c>>2]}Fa=g+1040|0;return e}function Xr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;a:{if(G[c+4>>2]==108){f=L[c+112>>3];break a}G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=90;E[c+1|0]=69;E[c+2|0]=65;E[c+3|0]=0;E[c+4|0]=108;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;f=L[c+24>>3];b:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=114.59155902616465;g=.008726646259971648;break b}f=f+f;g=1/f}G[c+1892>>2]=93;G[c+1888>>2]=94;L[c+112>>3]=f;L[c+120>>3]=g}b=f*Kb((90-b)*.5);h=d,i=b*Kb(a),L[h>>3]=i;h=e,i=Mb(a)*-b,L[h>>3]=i;return 0}function mt(a,b,c){a=a|0;b=b|0;c=c|0;b=H[c|0];E[1237232]=0;if(b){qb(1237232,c,1024);b=H[42189]|H[42190]<<8|(H[42191]<<16|H[42192]<<24);c=H[42185]|H[42186]<<8|(H[42187]<<16|H[42188]<<24);E[a+5|0]=c;E[a+6|0]=c>>>8;E[a+7|0]=c>>>16;E[a+8|0]=c>>>24;E[a+9|0]=b;E[a+10|0]=b>>>8;E[a+11|0]=b>>>16;E[a+12|0]=b>>>24;b=H[42184]|H[42185]<<8|(H[42186]<<16|H[42187]<<24);c=H[42180]|H[42181]<<8|(H[42182]<<16|H[42183]<<24);E[a|0]=c;E[a+1|0]=c>>>8;E[a+2|0]=c>>>16;E[a+3|0]=c>>>24;E[a+4|0]=b;E[a+5|0]=b>>>8;E[a+6|0]=b>>>16;E[a+7|0]=b>>>24}return 0}function Sc(a){var b=0,c=0,d=0,e=0,f=0,g=0;A(+a);b=v(1)|0;f=v(0)|0;e=b&2147483647;if(e>>>0>=1072693248){if(!(e-1072693248|f)){return(b|0)>0|(b|0)>=0?0:3.141592653589793}return 0/(a-a)}a:{if(e>>>0<=1071644671){d=1.5707963267948966;if(e>>>0<1012924417){break a}return 6123233995736766e-32-a*hh(a*a)-a+1.5707963267948966}if((b|0)<0){a=(a+1)*.5;c=V(a);a=1.5707963267948966-(c+(c*hh(a)+-6123233995736766e-32));return a+a}a=(1-a)*.5;c=V(a);g=c*hh(a);A(+c);b=v(1)|0;v(0)|0;x(0,0);x(1,b|0);d=a;a=+z();a=g+(d-a*a)/(c+a)+a;d=a+a}return d}function uf(a,b,c,d,e,f,g,h,i,j,k,l){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;l=+l;var m=0,n=0;b=Fa+-64|0;Fa=b;if(!(j==0&k==0)){f=+G[a+32>>2];k=k/f;i=(i-+G[a+24>>2])/f+1;h=(h-+G[a+16>>2])/f+1;if(l>=360){while(1){l=l+-360;if(l>=360){continue}break}}l=l/180*3.141592653589793;g=ib(l);k=k*.5;l=eb(l);m=k*l;n=i-m;j=j/f*.5;f=g*j;L[b>>3]=n-f;g=k*g;j=j*l;k=h-j;L[b+32>>3]=g+k;L[b+40>>3]=k-g;i=i+m;L[b+8>>3]=i-f;h=h+j;L[b+48>>3]=h-g;L[b+16>>3]=f+i;L[b+56>>3]=g+h;L[b+24>>3]=f+n;Hj(a,0,c,d,e,b+32|0,b,4)}Fa=b- -64|0}function td(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0;f=Fa-16|0;Fa=f;A(+b);g=v(1)|0;d=v(0)|0;c=g&2147483647;e=c+-1048576|0;a:{if((e|0)==2145386495|e>>>0<2145386495){h=d<<28;e=c>>>4|0;c=(c&15)<<28|d>>>4;d=e+1006632960|0;break a}if((c|0)==2146435072|c>>>0>2146435072){h=d<<28;c=(g&15)<<28|d>>>4;d=g>>>4|2147418112;break a}if(!(c|d)){c=0;d=0;break a}e=c;c=c?P(c):P(d)+32|0;od(f,d,e,0,0,c+49|0);i=G[f>>2];h=G[f+4>>2];e=15372-c<<16;c=G[f+8>>2];d=e|G[f+12>>2]^65536}G[a>>2]=i;G[a+4>>2]=h;G[a+8>>2]=c;G[a+12>>2]=g&-2147483648|d;Fa=f+16|0}function mf(a,b){var c=0,d=0,e=0,f=0,g=0,h=0;d=Fa-32|0;Fa=d;f=1;c=L[467827];b=c*b;a=c*a;c=V(b*b+(a*a+1));if(!(!(c>3]=c;gb(73024,d+16|0);$a(G[29763])}if(!(c<=0)){b=b/c;f=1/c;a=a/c}c=L[467860]*b+(L[467858]*f+a*L[467859]);e=L[467854]*b+(L[467852]*f+a*L[467853]);a=L[467857]*b+(L[467855]*f+a*L[467856]);b=V(c*c+(e*e+a*a));if(!(!(b>3]=b;gb(73024,d);$a(G[29763])}if(!(b<=0)){c=c/b;e=e/b;a=a/b}b=Db(a,e);a=L[467827];L[467840]=b/a;g=3742728,h=fc(c)/a,L[g>>3]=h;Fa=d+32|0}function hj(a,b,c,d){var e=0,f=0,g=0,h=0,i=0;if(G[321436]){e=G[24367];hb(88897,31,1,e);$a(e)}if(!H[3739720]){G[934934]=-1124855371;G[934935]=1064784320;G[934932]=-1571644103;G[934933]=1066524486;E[3739720]=1}G[c>>2]=0;G[c+4>>2]=0;G[d>>2]=0;G[d+4>>2]=0;if(L[23803]!=1949.9997905544149){L[23803]=1949.9997905544149;L[467468]=.016729604687785764;L[467469]=L[467466]*102.57769849393962}if(!(O(b)>89.999)){f=L[467468]*L[467467];g=L[467466];a=L[467469]-g*a;b=g*b;h=c,i=f*eb(a)/eb(b),L[h>>3]=i;a=ib(a);h=d,i=ib(b)*(f*a),L[h>>3]=i}}function Yh(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;e=G[b+4>>2];a:{if(G[b>>2]!=137){d=1;if(Aj(b)){break a}}if((e|0)>0){h=cb(c,0,e<<3);l=e&-2;m=e&1;i=G[b+20>>2];n=G[b+8>>2];while(1){b=g<<3;j=L[b+a>>3]-L[b+n>>3];b=0;d=g;c=0;if((e|0)!=1){while(1){f=b<<3;k=f+h|0;L[k>>3]=L[(d<<3)+i>>3]*j+L[k>>3];f=(f|8)+h|0;d=e+d|0;L[f>>3]=L[(d<<3)+i>>3]*j+L[f>>3];b=b+2|0;d=e+d|0;c=c+2|0;if((l|0)!=(c|0)){continue}break}}if(m){b=(b<<3)+h|0;L[b>>3]=L[(d<<3)+i>>3]*j+L[b>>3]}g=g+1|0;if((g|0)!=(e|0)){continue}break}}d=0}return d}function cs(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0;if(G[c+4>>2]!=104){G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=83;E[c+1|0]=84;E[c+2|0]=71;E[c+3|0]=0;E[c+4|0]=104;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;f=L[c+24>>3];a:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=114.59155902616465;g=.008726646259971648;break a}f=f+f;g=1/f}G[c+1892>>2]=87;G[c+1888>>2]=88;L[c+112>>3]=f;L[c+120>>3]=g}f=V(a*a+b*b);if(f!=0){a=Ac(a,-b)}else{a=0}L[d>>3]=a;a=De(f*L[c+120>>3]);L[e>>3]=90-(a+a);return 0}function Ne(a,b){var c=0,d=0,e=0;E[b|0]=0;while(1){d=a+c|0;e=H[d|0];if((e|0)!=32){a:{if(!e){break a}E[b|0]=37;Za(b+1|0,d+1|0);b:{c:{d:{e:{c=H[d|0];switch(c-65|0){case 8:break d;case 0:break e;default:break b}}a=Va(b)+b|0;E[a|0]=115;E[a+1|0]=0;break c}a=Va(b)+b|0;E[a|0]=46;E[a+1|0]=48;E[a+2|0]=102;E[a+3|0]=0}c=H[d|0]}if((c&255)==70){a=Va(b)+b|0;E[a|0]=102;E[a+1|0]=0;c=H[d|0]}if((c&255)==69){a=Va(b)+b|0;E[a|0]=69;E[a+1|0]=0;c=H[d|0]}if((c&255)!=68){break a}a=Va(b)+b|0;E[a|0]=69;E[a+1|0]=0}}else{c=c+1|0;continue}break}}function Qm(a,b,c,d,e,f,g,h,i,j,k){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;var l=0,m=0;l=G[a+8>>2];h=L[(l+M(c,168)|0)+8>>3];a:{if(g>3]=h)|!(L[(M(c,168)+l|0)+16>>3]>=g))){e=0;l=G[(M(c,168)+l|0)+24>>2];if(O(g)<2147483648){c=~~g}else{c=-2147483648}c=G[l+(c<<2)>>2];b:{if(!c){break b}while(1){if(!(+G[c+4>>2]<=f)){break b}e=e+1|0;c=G[c>>2];if(c){continue}break}}if((e&1)!=(d|0)){break a}if(!b){return 1}if(!d){return 1}G[a+12>>2]=b;return 1}m=!d}return m|0}function Wj(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0;f=G[a+8>>2];a:{if(!f){a=G[a>>2];if((a|0)>0|(a|0)==-1e3){break a}return G[(G[309729]+M(a,-244)|0)+4>>2]}if((f|0)<=0){return 0}h=G[309729];i=G[309722];while(1){g=M(G[((d<<2)+a|0)+12>>2],344)+i|0;b=G[g>>2];b:{if((b|0)>0){b=Wj(g);if((b|0)<=0){c=c-b|0;break b}if(!c){c=1;e=b;break b}c=((b|0)!=(e|0))+c|0;break b}if((b|0)==-1e3){break b}b=G[(M(b,-244)+h|0)+4>>2];if(!c){c=1;e=b;break b}c=((b|0)!=(e|0))+c|0}d=d+1|0;if((f|0)!=(d|0)){continue}break}d=(c|0)==1?e:0-c|0}return d}function Tr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;if(G[c+4>>2]!=204){G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=77;E[c+1|0]=69;E[c+2|0]=82;E[c+3|0]=0;E[c+4|0]=204;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];a:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=1;g=1;break a}f=f*3.141592653589793/180;g=1/f}G[c+1892>>2]=97;G[c+1888>>2]=98;L[c+112>>3]=f;L[c+120>>3]=g}h=2;if(!(b<=-90|b>=90)){L[d>>3]=L[c+112>>3]*a;i=e,j=L[c+24>>3]*oc(Xe((b+90)*.5)),L[i>>3]=j;h=0}return h|0}function Js(a,b,c,d,e,f,g,h,i,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;var k=0,l=0,m=0,n=0;if(j==0){return!d|0}l=G[a+8>>2];a:{if(d){e=M(c,168)+l|0;if(L[e+8>>3]>g|L[e+16>>3]>2];if(O(g)<2147483648){e=~~g}else{e=-2147483648}e=G[k+(e<<2)>>2];k=0;b:{if(!e){break b}k=0;if(!(L[m+8>>3]<=g)){break b}k=0;if(!(L[(M(c,168)+l|0)+16>>3]>=g)){break b}k=0;if(!(+G[e+4>>2]<=f)){break b}k=+G[G[e>>2]+4>>2]>=f}if((k|0)!=(d|0)){break a}n=1;if(!b|!d){break a}G[a+12>>2]=b}return n|0}function Cl(a){var b=0,c=0,d=0;b=a;a=Va(a);c=Ic(a+4096|0,1);Yb(b,c);a=H[(a+c|0)-1|0];if(!((a|0)==10|(a|0)==59)){a=Va(c)+c|0;E[a|0]=10;E[a+1|0]=0}a:{b:{c:{d:{b=Va(c);d=ab(b+2|0);if(d){if(b){break d}a=b+d|0;E[a|0]=0;E[a+1|0]=0;break c}qd(63716);W()}a=bb(d,c,b)+b|0;E[a|0]=0;E[a+1|0]=0;if(b>>>0>4294967293){break b}}a=ab(48);if(a){break a}qd(63911);W()}qd(63757);W()}G[a+20>>2]=0;G[a+8>>2]=d;G[a+4>>2]=d;G[a+12>>2]=b;G[a+40>>2]=0;G[a+44>>2]=0;G[a+24>>2]=0;G[a+28>>2]=1;G[a+16>>2]=b;G[a>>2]=0;Al(a);G[a+20>>2]=1;pb(c)}function Hn(a,b,c){var d=0,e=0,f=0;G[c>>2]=-1;a:{while(1){d=M(f,48)+757232|0;if(!G[d>>2]){e=f;break a}e=f+1|0;d=M(e,48)+757232|0;if(!G[d>>2]){break a}e=f+2|0;d=M(e,48)+757232|0;if(!G[d>>2]){break a}e=f+3|0;d=M(e,48)+757232|0;if(!G[d>>2]){break a}e=f+4|0;d=M(e,48)+757232|0;if(!G[d>>2]){break a}f=f+5|0;if((f|0)!=1e4){continue}break}return 103}G[c>>2]=e;G[d>>2]=a;c=M(e,48);G[c+757248>>2]=0;G[c+757240>>2]=b;b=G[b>>2];a=c+757256|0;G[a>>2]=0;G[a+4>>2]=0;a=c+757264|0;G[a>>2]=b;G[a+4>>2]=0;G[c+757252>>2]=0;return 0}function gp(a,b,c,d,e,f){var g=0;g=Fa+-64|0;Fa=g;a:{if(G[f>>2]>0){break a}G[g+48>>2]=0;G[g+40>>2]=0;G[g+44>>2]=0;b:{if(Nk(g+8|0,1,0)){break b}G[g+12>>2]=b;G[g+8>>2]=a;G[g+20>>2]=G[c>>2];G[g+24>>2]=G[d>>2];c:{while(1){d:{a=Mk(g+8|0,4);if(a){if((a|0)==1){break d}break c}a=Ja[17](G[c>>2],G[d>>2]+28800|0)|0;G[c>>2]=a;if(a){G[g+24>>2]=28800;b=a;a=G[d>>2];G[g+20>>2]=b+a;G[d>>2]=a+28800;continue}else{ff(g+8|0);break b}}break}if(e){G[e>>2]=G[g+28>>2]}if(ff(g+8|0)){break b}break a}ff(g+8|0)}G[f>>2]=413}Fa=g- -64|0}function Zr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;a:{if(G[c+4>>2]==106){f=L[c+112>>3];break a}G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=65;E[c+1|0]=82;E[c+2|0]=67;E[c+3|0]=0;E[c+4|0]=106;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;f=L[c+24>>3];b:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=1;g=1;break b}f=f*3.141592653589793/180;g=1/f}G[c+1892>>2]=91;G[c+1888>>2]=92;L[c+112>>3]=f;L[c+120>>3]=g}b=(90-b)*f;h=d,i=b*Kb(a),L[h>>3]=i;h=e,i=Mb(a)*-b,L[h>>3]=i;return 0}function Sd(a,b,c,d){var e=0,f=0,g=0;e=G[d>>2];if((e|0)<=0){a:{if(!b){b=G[a>>2];e=G[a+4>>2];if((b|0)!=G[e+76>>2]){mb(a,b+1|0,0,d);e=G[a+4>>2];b=G[e+76>>2]}b=G[e+96>>2]+(b<<3)|0;a=G[b+4>>2];G[e+120>>2]=G[b>>2];G[e+124>>2]=a;if(!c){break a}E[c|0]=0;break a}if((b|0)<=0){break a}f=G[a>>2];e=G[a+4>>2];if((f|0)!=G[e+76>>2]){mb(a,f+1|0,0,d);e=G[a+4>>2];f=G[e+76>>2]}g=M(b,80)-80|0;b=G[e+96>>2]+(f<<3)|0;f=g+G[b>>2]|0;b=G[b+4>>2]+(g>>31)|0;G[e+120>>2]=f;G[e+124>>2]=f>>>0>>0?b+1|0:b;Jg(a,c,d)}e=G[d>>2]}return e}function eg(a,b,c,d,e,f){var g=0,h=0,i=0,j=0;a:{if(f&64){c=f+-64|0;b=c&31;if((c&63)>>>0>=32){c=0;b=e>>>b|0}else{c=e>>>b|0;b=((1<>>b}d=0;e=0;break a}if(!f){break a}i=d;h=64-f|0;g=h&31;if((h&63)>>>0>=32){h=i<>>32-g|e<>>0>=32){g=0;b=c>>>b|0}else{g=c>>>b|0;b=((1<>>b}b=j|b;c=g|h;g=d;d=f&31;if((f&63)>>>0>=32){h=0;d=e>>>d|0}else{h=e>>>d|0;d=((1<>>d}e=h}G[a>>2]=b;G[a+4>>2]=c;G[a+8>>2]=d;G[a+12>>2]=e}function Tl(){var a=0,b=0,c=0,d=0,e=0;a:{a=Gg(19818,61);if((a|0)!=19818){a=a-19818|0;if(H[a+19818|0]){break a}}b:{c:{a=Gg(19818,61);if((a|0)!=19818){e=a-19818|0;if(!H[e+19818|0]){break c}}G[48624]=28;break b}b=G[50361];d:{if(!b){break d}d=G[b>>2];if(!d){break d}a=b;while(1){c=a;e:{f:{if(fb(19818,d,e)){break f}a=G[c>>2];if(H[a+e|0]!=61){break f}bj(a,0);break e}if((b|0)!=(c|0)){G[b>>2]=G[c>>2]}b=b+4|0}a=c+4|0;d=G[c+4>>2];if(d){continue}break}if((a|0)==(b|0)){break d}G[b>>2]=0}}return}Ul(19818,a,0)}function Hs(a,b,c,d,e,f,g,h){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=h|0;var i=0,j=0;h=G[a+8>>2];i=L[(h+M(c,168)|0)+8>>3];a:{if(g>3]=i)|!(L[(M(c,168)+h|0)+16>>3]>=g))){e=0;h=G[(M(c,168)+h|0)+24>>2];if(O(g)<2147483648){c=~~g}else{c=-2147483648}c=G[h+(c<<2)>>2];b:{if(!c){break b}while(1){if(!(+G[c+4>>2]<=f)){break b}e=e+1|0;c=G[c>>2];if(c){continue}break}}if((e&1)!=(d|0)){break a}if(!b){return 1}if(!d){return 1}G[a+12>>2]=b;return 1}j=!d}return j|0}function _r(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0;if(G[c+4>>2]!=106){G[c+16>>2]=0;G[c+20>>2]=1079410688;G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=65;E[c+1|0]=82;E[c+2|0]=67;E[c+3|0]=0;E[c+4|0]=106;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;f=L[c+24>>3];a:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=1;g=1;break a}f=f*3.141592653589793/180;g=1/f}G[c+1892>>2]=91;G[c+1888>>2]=92;L[c+112>>3]=f;L[c+120>>3]=g}f=V(a*a+b*b);if(f!=0){a=Ac(a,-b)}else{a=0}L[d>>3]=a;L[e>>3]=90-f*L[c+120>>3];return 0}function dj(a){var b=0,c=0,d=0,e=0;b=G[935824];if((b|0)>=1024){hb(72855,42,1,G[24367]);return}G[935824]=b+1;e=Xb(256);G[(G[935824]<<2)+3743308>>2]=e;b=0;while(1){c=b+3743040|0;E[b+e|0]=H[c|0];E[c|0]=0;d=b|1;c=d+3743040|0;E[e+d|0]=H[c|0];E[c|0]=0;d=b|2;c=d+3743040|0;E[e+d|0]=H[c|0];E[c|0]=0;d=b|3;c=d+3743040|0;E[e+d|0]=H[c|0];E[c|0]=0;b=b+4|0;if((b|0)!=256){continue}break}a:{if(!a){break a}b=H[a|0];if(!b){break a}while(1){E[(b<<24>>24)+3743040|0]=1;b=H[a+1|0];a=a+1|0;if(b){continue}break}}}function _i(a){var b=0,c=0;b=Fa-32|0;Fa=b;a=a?a:92041;c=G[24367];a:{if(H[3780288]){G[b+20>>2]=3780288;G[b+16>>2]=a;Tb(c,69475,b+16|0);break a}G[b>>2]=a;Tb(c,68751,b)}a=G[945062];b:{if(!a){break b}c=a+(G[945063]<<2)|0;a=G[c>>2];if(!a){break b}G[a+16>>2]=0;E[G[a+4>>2]]=0;E[G[a+4>>2]+1|0]=0;G[a+44>>2]=0;G[a+28>>2]=1;G[a+8>>2]=G[a+4>>2];if((a|0)!=G[c>>2]){break b}a=G[c>>2];G[950324]=G[a+16>>2];a=G[a+8>>2];G[945070]=a;G[945064]=a;G[945057]=G[G[c>>2]>>2];E[3780260]=H[a|0]}E[3801300]=1;Fa=b+32|0}function $a(a){var b=0,c=0,d=0;if(!a){if(G[47480]){b=$a(G[47480])}if(G[47442]){b=$a(G[47442])|b}a=G[48750];if(a){while(1){if(G[a+20>>2]!=G[a+28>>2]){b=$a(a)|b}a=G[a+56>>2];if(a){continue}break}}return b}d=G[a+76>>2]>=0;a:{b:{if(G[a+20>>2]==G[a+28>>2]){break b}Ja[G[a+36>>2]](a,0,0)|0;if(G[a+20>>2]){break b}b=-1;break a}b=G[a+8>>2];c=G[a+4>>2];if((b|0)!=(c|0)){b=c-b|0;Ja[G[a+40>>2]](a,b,b>>31,1)|0}b=0;G[a+28>>2]=0;G[a+16>>2]=0;G[a+20>>2]=0;G[a+4>>2]=0;G[a+8>>2]=0;if(!d){break a}}return b}function Rr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;a:{if(G[c+4>>2]==301){f=L[c+112>>3];break a}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=83;E[c+1|0]=70;E[c+2|0]=76;E[c+3|0]=0;E[c+4|0]=45;E[c+5|0]=1;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];b:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=1;g=1;break b}f=f*3.141592653589793/180;g=1/f}G[c+1892>>2]=99;G[c+1888>>2]=100;L[c+112>>3]=f;L[c+120>>3]=g}h=d,i=f*a*Mb(b),L[h>>3]=i;L[e>>3]=L[c+112>>3]*b;return 0}function cp(a,b,c){var d=0,e=0;d=G[48828];e=G[48827];if((d|0)<(e|0)){E[a+d|0]=c>>>24;d=d+1|0;G[48828]=d}if((d|0)<(e|0)){E[a+d|0]=c>>>16;d=d+1|0;G[48828]=d}if((d|0)<(e|0)){E[a+d|0]=c>>>8;d=d+1|0;G[48828]=d}if((d|0)<(e|0)){E[a+d|0]=c;d=d+1|0;G[48828]=d}if((d|0)<(e|0)){E[a+d|0]=(c&16777215)<<8|b>>>24;d=d+1|0;G[48828]=d}if((d|0)<(e|0)){E[a+d|0]=(c&65535)<<16|b>>>16;d=d+1|0;G[48828]=d}if((d|0)<(e|0)){E[a+d|0]=(c&255)<<24|b>>>8;d=d+1|0;G[48828]=d}if((d|0)<(e|0)){E[a+d|0]=b;G[48828]=d+1}}function Ur(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0;a:{if(G[c+4>>2]==204){f=L[c+120>>3];break a}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=77;E[c+1|0]=69;E[c+2|0]=82;E[c+3|0]=0;E[c+4|0]=204;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];b:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;g=1;f=1;break b}g=f*3.141592653589793/180;f=1/g}G[c+1892>>2]=97;G[c+1888>>2]=98;L[c+112>>3]=g;L[c+120>>3]=f}L[d>>3]=f*a;a=De(af(b/L[c+24>>3]));L[e>>3]=a+a+-90;return 0}function Jl(a){var b=0,c=0,d=0,e=0;a:{if(!a){break a}c=G[936854];if(!c){break a}b=c;while(1){b:{d=G[b+4>>2];e=Sb(d,a);c:{if(!e){break c}if((Va(e)|0)!=(Va(a)|0)){break c}if((d|0)==(e|0)|H[((d^-1)+e|0)+d|0]==47){break b}}b=G[b>>2];if(b){continue}break a}break}if(G[936855]==(b|0)){G[936855]=0}d:{e:{if((b|0)==(c|0)){a=3747416;break e}while(1){a=c;if(!a){break d}c=G[a>>2];if((c|0)!=(b|0)){continue}break}}G[a>>2]=G[b>>2];d=G[b+4>>2]}pb(d);pb(G[b+16>>2]);a=G[b+12>>2];if(a){Hb(a)}pb(b)}}function Uj(){var a=0,b=0,c=0,d=0;b=Fa-32|0;Fa=b;a:{b:{c=G[309704];c:{if(!c){a=ab(4);G[309704]=a;if(!a){break b}G[a>>2]=0;G[309739]=1;G[309705]=0;break c}a=G[309739];if(J[309705]>>0){break c}d=a+8|0;c=ub(c,d<<2);G[309704]=c;if(!c){break a}a=c+(a<<2)|0;G[a>>2]=0;G[a+4>>2]=0;G[a+24>>2]=0;G[a+28>>2]=0;G[a+16>>2]=0;G[a+20>>2]=0;G[a+8>>2]=0;G[a+12>>2]=0;G[309739]=d}Fa=b+32|0;return}G[b>>2]=64090;_a(G[24367],70017,b);ca(2);W()}G[b+16>>2]=64090;_a(G[24367],70017,b+16|0);ca(2);W()}function od(a,b,c,d,e,f){var g=0,h=0,i=0;a:{if(f&64){d=b;e=f+-64|0;b=e&31;if((e&63)>>>0>=32){e=d<>>32-b|c<>>0>=32){h=g<>>32-d|e<>>0>=32){e=0;b=c>>>d|0}else{e=c>>>d|0;b=((1<>>d}d=i|b;e=e|h;b=f&31;if((f&63)>>>0>=32){h=g<>>32-b|c<>2]=b;G[a+4>>2]=c;G[a+8>>2]=d;G[a+12>>2]=e}function Wq(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0;e=Fa-32|0;Fa=e;G[e+16>>2]=b;d=G[a+48>>2];G[e+20>>2]=c-((d|0)!=0);f=G[a+44>>2];G[e+28>>2]=d;G[e+24>>2]=f;a:{b:{d=ha(G[a+60>>2],e+16|0,2,e+12|0)|0;if(d){G[48624]=d;d=-1}else{d=0}if(d){b=32}else{d=G[e+12>>2];if((d|0)>0){break b}b=d?32:16}G[a>>2]=b|G[a>>2];break a}g=d;f=G[e+20>>2];if(f>>>0>=d>>>0){break a}d=G[a+44>>2];G[a+4>>2]=d;G[a+8>>2]=d+(g-f|0);if(G[a+48>>2]){G[a+4>>2]=d+1;E[(b+c|0)-1|0]=H[d|0]}g=c}Fa=e+32|0;return g|0}function $l(a,b){var c=0,d=0,e=0,f=0;f=Fa-16|0;Fa=f;e=G[934941];if(e){Wa(e)}d=le(5330);c=H[d|0];if(c){e=d;while(1){c=c<<24>>24;if(c-65>>>0<26){E[e|0]=c-65>>>0<26?c|32:c}c=H[e+1|0];e=e+1|0;if(c){continue}break}}c=0;G[934941]=d;e=nc(d,f+12|0,10);d=G[f+12>>2];a:{if(H[d|0]?0:d){break a}d=G[934941];b:{if(!Xa(d,31900)){break b}if(!Xa(d,5330)){c=1;break b}if(!Xa(d,17538)){c=2;break b}e=-1;if(Xa(d,16674)){break a}c=3}e=G[(a<<4|c<<2)+156736>>2]+((a|0)==1&(b|0)!=0)|0}Fa=f+16|0;return e}function Me(a,b){var c=0,d=0,e=0;c=Fa-32|0;G[c+24>>2]=0;G[c+28>>2]=0;G[c+16>>2]=0;G[c+20>>2]=0;G[c+8>>2]=0;G[c+12>>2]=0;G[c>>2]=0;G[c+4>>2]=0;d=H[b|0];if(!d){return 0}if(!H[b+1|0]){b=a;while(1){c=b;b=c+1|0;if(H[c|0]==(d|0)){continue}break}return c-a|0}while(1){e=c+(d>>>3&28)|0;G[e>>2]=G[e>>2]|1<>>3&28)>>2]>>>d&1)){break a}d=H[b+1|0];b=b+1|0;if(d){continue}break}}return b-a|0}function oq(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0;f=Fa-256|0;Fa=f;a:{if(G[e>>2]>0){break a}F[f+176>>1]=40;g=f+96|0;If(L[c>>3],-15,g,e);b:{if((Va(f+176|0)+Va(g)|0)-69>>>0<=4294967224){break b}h=f+96|0;g=Gb(f+176|0,h);i=Va(g)+g|0;j=H[67812]|H[67813]<<8;E[i|0]=j;E[i+1|0]=j>>>8;E[i+2|0]=H[67814];If(L[c+8>>3],-15,h,e);if((Va(g)+Va(h)|0)-70>>>0<=4294967224){break b}c=Gb(g,f+96|0);g=Va(c)+c|0;E[g|0]=41;E[g+1|0]=0;Ob(b,c,d,f,e);wb(a,f,e);break a}Ua(56359);G[e>>2]=402}Fa=f+256|0}function Sp(a,b){if(!a){return 0}a:{b:{if(a){if(b>>>0<=127){break b}c:{if(!G[G[48787]>>2]){if((b&-128)==57216){break b}break c}if(b>>>0<=2047){E[a+1|0]=b&63|128;E[a|0]=b>>>6|192;a=2;break a}if(!((b&-8192)!=57344&b>>>0>=55296)){E[a+2|0]=b&63|128;E[a|0]=b>>>12|224;E[a+1|0]=b>>>6&63|128;a=3;break a}if(b-65536>>>0<=1048575){E[a+3|0]=b&63|128;E[a|0]=b>>>18|240;E[a+2|0]=b>>>6&63|128;E[a+1|0]=b>>>12&63|128;a=4;break a}}G[48624]=25;a=-1}else{a=1}break a}E[a|0]=b;a=1}return a}function pq(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0;f=Fa-256|0;Fa=f;a:{if(G[e>>2]>0){break a}F[f+176>>1]=40;g=f+96|0;hg(K[c>>2],-7,g,e);b:{if((Va(f+176|0)+Va(g)|0)-69>>>0<=4294967224){break b}h=f+96|0;g=Gb(f+176|0,h);i=Va(g)+g|0;j=H[67812]|H[67813]<<8;E[i|0]=j;E[i+1|0]=j>>>8;E[i+2|0]=H[67814];hg(K[c+4>>2],-7,h,e);if((Va(g)+Va(h)|0)-70>>>0<=4294967224){break b}c=Gb(g,f+96|0);g=Va(c)+c|0;E[g|0]=41;E[g+1|0]=0;Ob(b,c,d,f,e);wb(a,f,e);break a}Ua(62641);G[e>>2]=402}Fa=f+256|0}function ok(a,b,c,d,e){var f=0,g=0;if(G[e>>2]<=0){a:{g=G[a>>2];f=G[a+4>>2];b:{if((g|0)!=G[f+76>>2]){if((mb(a,g+1|0,0,e)|0)<=0){break b}break a}if((G[f+128>>2]&G[f+132>>2])!=-1){break b}if((Rb(a,e)|0)>0){break a}}if(b){f=G[a+4>>2];f=G[f+96>>2]+(G[f+76>>2]<<3)|0;g=G[f+4>>2];G[b>>2]=G[f>>2];G[b+4>>2]=g}if(c){b=G[a+4>>2];f=G[b+132>>2];G[c>>2]=G[b+128>>2];G[c+4>>2]=f}if(!d){break a}a=G[a+4>>2];a=(G[a+76>>2]<<3)+G[a+96>>2]|0;b=G[a+12>>2];G[d>>2]=G[a+8>>2];G[d+4>>2]=b}}}function Wr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0;a:{if(G[c+4>>2]==203){f=L[c+120>>3];break a}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=67;E[c+1|0]=65;E[c+2|0]=82;E[c+3|0]=0;E[c+4|0]=203;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];b:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;g=1;f=1;break b}g=f*3.141592653589793/180;f=1/g}G[c+1892>>2]=95;G[c+1888>>2]=96;L[c+112>>3]=g;L[c+120>>3]=f}L[d>>3]=f*a;L[e>>3]=L[c+120>>3]*b;return 0}function Vr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0;a:{if(G[c+4>>2]==203){f=L[c+112>>3];break a}G[c+8>>2]=0;G[c+12>>2]=0;E[c|0]=67;E[c+1|0]=65;E[c+2|0]=82;E[c+3|0]=0;E[c+4|0]=203;E[c+5|0]=0;E[c+6|0]=0;E[c+7|0]=0;G[c+16>>2]=0;G[c+20>>2]=0;f=L[c+24>>3];b:{if(f==0){G[c+24>>2]=442745336;G[c+28>>2]=1078765020;f=1;g=1;break b}f=f*3.141592653589793/180;g=1/f}G[c+1892>>2]=95;G[c+1888>>2]=96;L[c+112>>3]=f;L[c+120>>3]=g}L[d>>3]=f*a;L[e>>3]=L[c+112>>3]*b;return 0}function Vi(a,b,c){var d=0,e=0;d=(c|0)!=0;a:{b:{c:{if(!(a&3)|!c){break c}e=b&255;while(1){if((e|0)==H[a|0]){break b}c=c-1|0;d=(c|0)!=0;a=a+1|0;if(!(a&3)){break c}if(c){continue}break}}if(!d){break a}}d:{if(!(H[a|0]==(b&255)|c>>>0<4)){d=M(b&255,16843009);while(1){e=d^G[a>>2];if((e^-1)&e-16843009&-2139062144){break d}a=a+4|0;c=c-4|0;if(c>>>0>3){continue}break}}if(!c){break a}}b=b&255;while(1){if((b|0)==H[a|0]){return a}a=a+1|0;c=c-1|0;if(c){continue}break}}return 0}function ed(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0;h=Au(b,c,h,i);i=Ia;j=h;h=Au(d,e,f,g);e=j+h|0;d=Ia+i|0;i=e;h=i>>>0>>0?d+1|0:d;j=i;k=g;e=0;l=c;d=0;i=Au(g,e,c,d);g=j+i|0;c=Ia+h|0;j=g;g=g>>>0>>0?c+1|0:c;h=f;i=b;f=Au(h,0,i,0);b=Ia;c=0;d=Au(h,c,l,d);b=b+d|0;c=Ia+c|0;c=b>>>0>>0?c+1|0:c;h=c;c=c+j|0;d=g;d=c>>>0>>0?d+1|0:d;h=c;c=d;d=Au(i,m,k,e)+b|0;e=Ia;e=b>>>0>d>>>0?e+1|0:e;g=a;i=e;h=i+h|0;G[g+8>>2]=h;G[g+12>>2]=h>>>0>>0?c+1|0:c;G[g>>2]=f;G[g+4>>2]=d}function As(a,b,c,d,e,f,g,h,i){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;var j=0,k=0,l=0;j=G[a+8>>2];a:{if(d){e=0;k=j+M(c,168)|0;if(L[k+8>>3]>g|L[k+16>>3]>2];if(O(g)<2147483648){c=~~g}else{c=-2147483648}c=G[l+(c<<2)>>2];b:{if(!c){break b}h=L[j+8>>3];c:{if(O(h)<2147483648){j=~~h;break c}j=-2147483648}if(+(j|0)!=g){break b}k=+G[c+4>>2]==f}if((d|0)!=(k|0)){break a}e=1;if(!b|!d){break a}G[a+12>>2]=b}return e|0}function yk(a,b,c,d,e){var f=0,g=0;f=Fa-384|0;Fa=f;g=G[e>>2];a:{if((g|0)>0){break a}E[f+224|0]=0;E[f+304|0]=0;b:{c:{if((Cf(a,b,f+304|0,f+224|0,f+144|0,e)|0)>0){break c}if(Xa(f+304|0,c)){G[e>>2]=208}if(!Xa(d,f+224|0)){break c}G[e>>2]=209;break b}g=G[e>>2];if((g|0)<=0){break a}}G[f+32>>2]=b;a=f+48|0;Ya(a,81,44742,f+32|0);Ua(a);G[f+20>>2]=d;G[f+16>>2]=c;Ya(a,81,4384,f+16|0);Ua(a);G[f+4>>2]=f+224;G[f>>2]=f+304;Ya(a,81,9122,f);Ua(a);g=G[e>>2]}Fa=f+384|0;return g}function Td(a,b,c,d){var e=0,f=0,g=0,h=0,i=0;e=G[d>>2];if((e|0)<=0){e=G[a>>2];if((e|0)!=G[G[a+4>>2]+76>>2]){mb(a,e+1|0,0,d)}f=G[a+4>>2];if(b){g=b;e=G[f+104>>2];b=G[f+96>>2]+(G[f+76>>2]<<3)|0;a=G[b>>2];h=g,i=Bu(e-a|0,G[f+108>>2]-(G[b+4>>2]+(a>>>0>e>>>0)|0)|0,80,0),G[h>>2]=i}a=G[f+128>>2];e=G[f+132>>2];a:{b:{if((a&e)==-1){a=-1;if(c){break b}break a}if(!c){break a}b=G[f+104>>2];a=Bu(a-b|0,e-(G[f+108>>2]+(a>>>0>>0)|0)|0,80,0)-1|0}G[c>>2]=a}e=G[d>>2]}return e}function Ul(a,b,c){var d=0,e=0,f=0;a:{b:{d=G[50361];c:{if(!d){d=0;break c}e=G[d>>2];if(e){break b}}b=0;break a}f=b+1|0;b=0;while(1){if(!fb(a,e,f)){b=G[d>>2];G[d>>2]=a;bj(b,c);return}b=b+1|0;e=G[d+4>>2];d=d+4|0;if(e){continue}break}d=G[50361]}f=b<<2;e=f+8|0;d:{e:{if(G[935755]==(d|0)){d=ub(d,e);if(d){break e}break d}d=ab(e);if(!d){break d}if(b){bb(d,G[50361],f)}Wa(G[935755])}b=(b<<2)+d|0;G[b>>2]=a;G[b+4>>2]=0;G[50361]=d;G[935755]=d;if(c){bj(0,c)}return}Wa(c)}function th(a,b,c,d,e){var f=0,g=0;f=Fa-384|0;Fa=f;g=G[e>>2];if((g|0)<=0){E[f+224|0]=0;E[f+304|0]=0;a:{if((Cf(a,b,f+304|0,f+224|0,f+144|0,e)|0)>0){break a}g=208;b:{if(Xa(f+304|0,c)){break b}yi(f+224|0,d,e);g=209;if(G[e>>2]>0){break b}a=G[d+4>>2];if((a|0)>0|(a|0)>=0){break a}}G[e>>2]=g;G[f+32>>2]=b;a=f+48|0;Ya(a,81,44864,f+32|0);Ua(a);G[f+16>>2]=c;Ya(a,81,29582,f+16|0);Ua(a);G[f+4>>2]=f+224;G[f>>2]=f+304;Ya(a,81,9122,f);Ua(a)}g=G[e>>2]}Fa=f+384|0;return g} -function mn(a,b,c){var d=0,e=0,f=0,g=0;e=Va(b);d=Va(c);f=ab(((d|0)<(e|0)?e:d)+1|0);a:{b:{if((d|0)>(e|0)){g=d-e|0;if(g){cb(f,48,g)}if(!e){d=g;b=f;break b}bb(f+g|0,b,e);b=f;break b}if((d|0)>=(e|0)){break a}g=e-d|0;if(g){cb(f,48,g)}if(d){bb(f+g|0,c,d);c=e}else{c=g}d=c;c=f}E[d+f|0]=0}d=H[b|0];if(d){while(1){e=H[c|0];d=d&255;E[a|0]=(d|0)==120?120:(e|0)==120?120:(d|0)==49?(e|0)==49?49:48:48;a=a+1|0;c=c+1|0;d=H[b+1|0];b=b+1|0;if(d){continue}break}}Wa(f);E[a|0]=0}function qi(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0;d=ab(40);if(G[a>>2]>0){f=10;while(1){b=G[a+4>>2]+M(g,168)|0;a:{if(G[b+4>>2]!=11){break a}c=G[b+52>>2];if(H[b|0]){Wa(c);break a}b=0;if((e|0)>0){while(1){b:{h=G[(b<<2)+d>>2];b=b+1|0;if((e|0)<=(b|0)){break b}if((c|0)!=(h|0)){continue}}break}if((c|0)==(h|0)){break a}}Wa(c);if((f|0)==(e|0)){d=ub(d,f<<3);f=f<<1}G[(e<<2)+d>>2]=c;e=e+1|0}g=g+1|0;if((g|0)>2]){continue}break}}c=G[a+4>>2];if(c){Wa(c)}Wa(a);Wa(d)}function ln(a,b,c){var d=0,e=0,f=0,g=0;e=Va(b);d=Va(c);f=ab(((d|0)<(e|0)?e:d)+1|0);a:{b:{if((d|0)>(e|0)){g=d-e|0;if(g){cb(f,48,g)}if(!e){d=g;b=f;break b}bb(f+g|0,b,e);b=f;break b}if((d|0)>=(e|0)){break a}g=e-d|0;if(g){cb(f,48,g)}if(d){bb(f+g|0,c,d);c=e}else{c=g}d=c;c=f}E[d+f|0]=0}d=H[b|0];if(d){while(1){e=H[c|0];d=d&255;E[a|0]=(d|0)==49?49:(e|0)==49?49:(d|0)==48?48:(e|0)==48?48:120;a=a+1|0;c=c+1|0;d=H[b+1|0];b=b+1|0;if(d){continue}break}}Wa(f);E[a|0]=0}function Xl(){var a=0;a=Fa-96|0;Fa=a;yb(20356);yb(13586);L[a+80>>3]=L[467787];L[a+88>>3]=L[467788];gb(71518,a+80|0);yb(4674);L[a+64>>3]=L[467794];L[a+72>>3]=L[467795];gb(71456,a- -64|0);L[a+48>>3]=L[467801];L[a+56>>3]=L[467802];gb(71456,a+48|0);L[a+32>>3]=L[467808];L[a+40>>3]=L[467809];gb(71456,a+32|0);L[a+16>>3]=L[467787];L[a+24>>3]=L[467788];gb(71456,a+16|0);L[a>>3]=L[467815];L[a+8>>3]=L[467816];gb(71518,a);yb(49020);yb(40576);yb(4674);Fa=a+96|0}function Dr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0;f=G[c+4>>2];g=f>>31;a:{if(((g^f)-g|0)!=107){f=1;if(wj(c)){break a}}b=(90-b)*3.141592653589793/180;h=((((((((((b*0+L[c+104>>3])*b+L[c+96>>3])*b+L[c+88>>3])*b+L[c+80>>3])*b+L[c+72>>3])*b+L[c- -64>>3])*b+L[c+56>>3])*b+L[c+48>>3])*b+L[c+40>>3])*b+L[c+32>>3])*L[c+24>>3];i=d,j=h*Kb(a),L[i>>3]=j;i=e,j=Mb(a)*-h,L[i>>3]=j;if(G[c+4>>2]>0){f=2;if(b>L[c+112>>3]){break a}}f=0}return f|0}function kl(a,b,c){var d=0,e=0,f=0;if(G[c>>2]<=0){a:{if(!a){E[b+2|0]=H[65204];a=H[65202]|H[65203]<<8;E[b|0]=a;E[b+1|0]=a>>>8;break a}E[b|0]=39;c=1;b:{c:{d:{d=Va(a);f=d>>>0<68?d:68;if(f){while(1){d=a+e|0;E[b+c|0]=H[d|0];e:{if(H[d|0]!=39){d=c;break e}d=c+1|0;E[d+b|0]=39}c=d+1|0;e=e+1|0;if(d>>>0<68&f>>>0>e>>>0){continue}break}if(d>>>0>7){break d}a=c}else{a=1}c=9;cb(a+b|0,32,9-a|0);break c}a=69;if((c|0)==70){break b}}E[b+c|0]=39;a=c+1|0}E[a+b|0]=0}}}function Ds(a,b,c,d,e,f,g,h,i,j,k){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;var l=0,m=0;l=G[a+8>>2];a:{if(d){e=M(c,168)+l|0;if(L[e+8>>3]>g|L[e+16>>3]>2];if(O(g)<2147483648){c=~~g}else{c=-2147483648}c=G[l+(c<<2)>>2];b:{if(!c){break b}e=1;g=+G[c+4>>2];if(g==f){break b}e=0;c=G[c>>2];if(!c|!(f>=g)){break b}e=+G[c+4>>2]>=f}if((d|0)!=(e|0)){break a}m=1;if(!b|!d){break a}G[a+12>>2]=b}return m|0}function Zi(a,b){var c=0,d=0;a:{b:{if(!b){break b}b=E[b|0];if(!b){break b}c=b-33|0;if((b|0)==124|(1<>>0<=29:0)){break a}}if((a|0)<=0){return 0}d=G[950332];c:{while(1){b=a;a=b-1|0;c=G[(a<<2)+d>>2];d:{if(!c){break d}c=G[c+24>>2];if(!c){break d}if(!Xa(c,64753)){break d}if(Xa(c,64244)){break c}}if(b>>>0>1){continue}break}return 0}a=E[(Va(c)+c|0)-1|0];b=a-33|0;if((1<>>0<=29:0)|(a|0)==124){break a}return 1}return 0}function Um(a,b,c,d){var e=0,f=0;e=Fa-32|0;Fa=e;G[e+8>>2]=0;G[e+12>>2]=0;G[e>>2]=0;G[e+4>>2]=0;G[e+28>>2]=G[a>>2]+1;G[d>>2]=0;Qd(a,e+24|0,d);G[d>>2]=0;f=G[e+24>>2];de(a,(f|0)<4?f:4,e,d);G[d>>2]=0;a:{if(G[e+28>>2]!=1|(G[e>>2]?G[e+24>>2]:0)){break a}b:{if(b){b=le(b);f=pc(b,68332);if(f){while(1){Je(a,-1,f,0,d);if(!G[d>>2]){break b}G[d>>2]=0;f=pc(0,68332);if(f){continue}break}}Wa(b)}mb(a,2,e+20|0,d);break a}Wa(b)}Dc(a,c,d);Fa=e+32|0;return a}function Kn(a,b){var c=0,d=0,e=0,f=0;e=lb(161,1);a:{if(e){while(1){d=H[(b+c|0)+a|0];E[c+e|0]=(d-1&255)>>>0<31?32:d;f=c|1;d=H[(f+b|0)+a|0];E[e+f|0]=(d-1&255)>>>0<31?32:d;c=c+2|0;if((c|0)!=160){continue}break}break a}Ua(23559)}b:{a=lb(80,1);if(!a){Ua(23507);break b}b=!H[e|0];c=0;while(1){d=b+e|0;E[a+c|0]=H[d|0];E[a+(c|1)|0]=H[d+2|0];E[a+(c|2)|0]=H[d+4|0];f=c|3;if((f|0)==79){break b}E[a+f|0]=H[d+6|0];c=c+4|0;b=b+8|0;continue}}Wa(e);return a}function Af(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0;a:{if((b|0)<=0){break a}if(b-1>>>0>=3){i=b&-4;while(1){d=f<<1;e=d+a|0;c=I[e>>1];F[e>>1]=c<<8|c>>>8;e=(d|2)+a|0;c=I[e>>1];F[e>>1]=c<<8|c>>>8;e=(d|4)+a|0;c=I[e>>1];F[e>>1]=c<<8|c>>>8;c=(d|6)+a|0;d=I[c>>1];F[c>>1]=d<<8|d>>>8;f=f+4|0;g=g+4|0;if((i|0)!=(g|0)){continue}break}}d=b&3;if(!d){break a}while(1){c=(f<<1)+a|0;b=I[c>>1];F[c>>1]=b<<8|b>>>8;f=f+1|0;h=h+1|0;if((d|0)!=(h|0)){continue}break}}}function no(a,b,c,d,e){var f=0,g=0;f=Fa-384|0;Fa=f;g=G[e>>2];if((g|0)<=0){E[f+224|0]=0;E[f+304|0]=0;a:{if((Cf(a,b,f+304|0,f+224|0,f+144|0,e)|0)>0){break a}g=208;b:{if(Xa(f+304|0,c)){break b}ue(f+224|0,d,e);g=209;if(G[e>>2]>0){break b}if(G[d>>2]>=0){break a}}G[e>>2]=g;G[f+32>>2]=b;a=f+48|0;Ya(a,81,44803,f+32|0);Ua(a);G[f+16>>2]=c;Ya(a,81,29582,f+16|0);Ua(a);G[f+4>>2]=f+224;G[f>>2]=f+304;Ya(a,81,9122,f);Ua(a)}g=G[e>>2]}Fa=f+384|0;return g}function Gg(a,b){var c=0,d=0;a:{d=b&255;if(d){if(a&3){while(1){c=H[a|0];if(!c|(c|0)==(b&255)){break a}a=a+1|0;if(a&3){continue}break}}c=G[a>>2];b:{if((c^-1)&c-16843009&-2139062144){break b}d=M(d,16843009);while(1){c=c^d;if((c^-1)&c-16843009&-2139062144){break b}c=G[a+4>>2];a=a+4|0;if(!(c-16843009&(c^-1)&-2139062144)){continue}break}}while(1){c=a;d=H[c|0];if(d){a=c+1|0;if((d|0)!=(b&255)){continue}}break}return c}return Va(a)+a|0}return a}function zm(a,b,c){var d=0,e=0,f=0,g=0;d=Fa-144|0;Fa=d;e=b<0;b=Yc(e?-b:b,360);b=e?-b:b;b=b<=-180?b+360:b;e=c+4|0;a:{if((c|0)>0){G[d+20>>2]=c;G[d+16>>2]=e;c=d+136|0;db(c,18611,d+16|0);L[d>>3]=b;Eb(d- -64|0,c,d);break a}G[d+48>>2]=e;db(d+136|0,29735,d+48|0);if(O(b)<2147483648){c=~~b}else{c=-2147483648}G[d+32>>2]=c;db(d- -64|0,d+136|0,d+32|0)}b:{if((Va(d- -64|0)|0)<31){Za(a,d- -64|0);break b}f=rb(a,d- -64|0,31),g=0,E[f+31|0]=g}Fa=d+144|0}function Zn(a,b,c,d){var e=0,f=0,g=0,h=0,i=0;f=G[d>>2];if((f|0)<=0){f=G[G[a+4>>2]+96>>2]+(b<<3)|0;a:{if((Jb(a,G[f>>2],G[f+4>>2],0,d)|0)>0){break a}e=G[a+4>>2];h=G[e+76>>2];G[e+76>>2]=b;i=G[e+104>>2];f=G[e+108>>2];g=G[e+88>>2];G[a>>2]=b;G[e+88>>2]=(b|0)<(g|0)?g:b;b=G[e+44>>2];G[e+104>>2]=G[e+40>>2];G[e+108>>2]=b;if((Wf(a,c,d)|0)<=0){break a}b=G[a+4>>2];G[b+76>>2]=h;G[a>>2]=h;G[b+104>>2]=i;G[b+108>>2]=f;G[b+88>>2]=g}f=G[d>>2]}return f}function og(a,b,c){var d=0,e=0,f=0,g=0,h=0;e=Fa-96|0;Fa=e;c=Za(e+6|0,c);d=Va(c);if((d|0)<=7){while(1){f=Va(c)+c|0;E[f|0]=32;E[f+1|0]=0;d=d+1|0;if((d|0)!=8){continue}break}}d=Va(c)+c|0;E[d|0]=61;E[d+1|0]=0;d=1;a=Sb(a,c);a:{if(!a){break a}c=jb(a,61);if(!c){break a}while(1){d=H[c+1|0];a=c+1|0;c=a;if((d|0)==32){continue}break}d=1;c=qc(a,68332);if((c|0)>79){break a}d=0;a=rb(e+16|0,a,c);E[a+c|0]=0;g=b,h=sb(a),L[g>>3]=h}Fa=e+96|0;return d}function Vh(a,b,c){var d=0,e=0,f=0,g=0,h=0;e=Fa-96|0;Fa=e;c=Za(e+6|0,c);d=Va(c);if((d|0)<=7){while(1){f=Va(c)+c|0;E[f|0]=32;E[f+1|0]=0;d=d+1|0;if((d|0)!=8){continue}break}}d=Va(c)+c|0;E[d|0]=61;E[d+1|0]=0;d=1;a=Sb(a,c);a:{if(!a){break a}c=jb(a,61);if(!c){break a}while(1){d=H[c+1|0];a=c+1|0;c=a;if((d|0)==32){continue}break}d=1;c=qc(a,68332);if((c|0)>79){break a}d=0;a=rb(e+16|0,a,c);E[a+c|0]=0;g=b,h=_b(a),G[g>>2]=h}Fa=e+96|0;return d}function ke(a,b){var c=0,d=0,e=0,f=0,g=0,h=0;a:{if((b|0)<=0){break a}if((b|0)!=1){h=b&-2;while(1){d=e<<2;c=d+a|0;f=H[c+3|0];E[c+3|0]=H[c|0];E[c|0]=f;f=H[c+1|0];E[c+1|0]=H[c+2|0];E[c+2|0]=f;c=(d|4)+a|0;d=H[c+3|0];E[c+3|0]=H[c|0];E[c|0]=d;d=H[c+1|0];E[c+1|0]=H[c+2|0];E[c+2|0]=d;e=e+2|0;g=g+2|0;if((h|0)!=(g|0)){continue}break}}if(!(b&1)){break a}a=(e<<2)+a|0;b=H[a+3|0];E[a+3|0]=H[a|0];E[a|0]=b;b=H[a+1|0];E[a+1|0]=H[a+2|0];E[a+2|0]=b}}function ad(a){var b=0,c=0;c=jb(a,58);a:{b:{if(!c){break b}b=jb(a,59);if(b>>>0<=c>>>0?b:0){break b}b=jb(a,47);if(b>>>0<=c>>>0?b:0){break b}b=jb(a,63);if(b>>>0<=c>>>0?b:0){break b}b=jb(a,64);if(b>>>0<=c>>>0?b:0){break b}b=jb(a,38);if(b>>>0<=c>>>0?b:0){break b}b=jb(a,61);if(b>>>0<=c>>>0?b:0){break b}b=jb(a,43);if(b>>>0<=c>>>0?b:0){break b}b=jb(a,36);if(b>>>0<=c>>>0?b:0){break b}a=jb(a,44);b=1;if(!a|a>>>0>c>>>0){break a}}b=0}return b}function mg(a){var b=0,c=0,d=0,e=0;b=Va(a);while(1){e=b;b=b-1|0;if(H[a+e|0]==32){continue}break}b=0;while(1){a:{switch(H[a+b|0]-32|0){case 0:case 11:b=b+1|0;continue;default:break a}}break}while(1){c=b;b=b+1|0;d=E[a+c|0];if(d-48>>>0<10){continue}break}b=c+((d|0)==46)|0;while(1){c=b;b=b+1|0;d=E[a+c|0];if(d-48>>>0<10){continue}break}b=(d&255|32)==101?b:c;while(1){c=b;b=b+1|0;if(E[a+c|0]-48>>>0<10){continue}break}return(c|0)==(e|0)}function Ir(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0;f=G[c+4>>2];i=f>>31;a:{if(((i^f)-i|0)!=101){f=1;if(yj(c)){break a}}g=L[c+136>>3]*b;h=V(a*a+g*g);b:{if(h==0){G[d>>2]=0;G[d+4>>2]=0;a=90;break b}j=d,k=Ac(a,-g),L[j>>3]=k;g=L[c+40>>3];a=h/(b*L[c+144>>3]+L[c+112>>3]);b=Ac(1,a);a=g*a/V(a*a+1);f=2;if(O(a)>1){break a}g=Bc(a);a=b-g;h=a>90?a+-360:a;a=b+g+180;a=a>90?a+-360:a;a=a>3]=a;f=0}return f|0}function $e(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p=0,q=0;q=G[310142];if((q|0)<0){Ua(65667);Ua(43041);return 122}if(q>>>0<=30){if(!a){return 121}p=M(q,84)+1240576|0;rb(p,a,20);G[p+80>>2]=o;G[p+76>>2]=n;G[p+72>>2]=m;G[p+68>>2]=l;G[p+64>>2]=k;G[p+60>>2]=j;G[p+56>>2]=i;G[p+52>>2]=h;G[p+48>>2]=g;G[p+44>>2]=f;G[p+40>>2]=0;G[p+36>>2]=e;G[p+32>>2]=d;G[p+28>>2]=c;G[p+24>>2]=b;G[p+20>>2]=0;E[p+19|0]=0;G[310142]=q+1;a=0}else{a=122}return a}function sh(a,b,c){var d=0,e=0,f=0;a:{if(!b){b=0;while(1){d=G[a+4>>2];e=d+(b<<2)|0;if(!(G[e+1256>>2]<0|!G[e+1416>>2])){Hg(d,b,c)}b=b+1|0;if((b|0)!=40){continue}break}break a}d=G[a+4>>2];b=0;while(1){e=b<<2;f=e+d|0;if(!(G[f+1256>>2]<0|!G[f+1416>>2])){Hg(d,b,c);d=G[a+4>>2]}G[(d+e|0)+1256>>2]=-1;b=b+1|0;if((b|0)!=40){continue}break}}if(G[c>>2]!=112){a=G[a+4>>2];b=G[(M(G[a+4>>2],84)+1240576|0)+68>>2];if(b){Ja[b|0](G[a>>2])|0}}}function ni(a,b){var c=0,d=0,e=0,f=0;d=Va(a);c=Va(b);e=ab(((c|0)<(d|0)?d:c)+1|0);a:{b:{if((c|0)>(d|0)){f=c-d|0;if(f){cb(e,48,f)}if(!d){c=f;a=e;break b}bb(e+f|0,a,d);a=e;break b}if((c|0)>=(d|0)){break a}f=d-c|0;if(f){cb(e,48,f)}if(c){bb(e+f|0,b,c);b=d}else{b=f}c=b;b=e}E[c+e|0]=0}while(1){c=H[a|0];if(!c){Wa(e);return 1}d=H[b|0];if(!((c|0)==48&(d|0)==49)){a=a+1|0;b=b+1|0;if((c|0)!=49|(d|0)!=48){continue}}break}Wa(e);return 0}function Zm(a,b,c,d,e){var f=0,g=0,h=0,i=0;h=-1;f=d&2147483647;i=f;g=(f|0)==2147418112;a:{if(g&!c?a|b:g&(c|0)!=0|f>>>0>2147418112){break a}f=e&2147483647;g=(f|0)==2147418112;if(g?0:g&0|f>>>0>2147418112){break a}if(!(a|c|(f|i|b))){return 0}f=d&e;if((f|0)>0|(f|0)>=0){if(!c&(d|0)==(e|0)?0:(d|0)<(e|0)){break a}return(a|c|(d^e|b))!=0}if(!c&(d|0)==(e|0)?a|b:(c|0)!=0&(d|0)>=(e|0)|(d|0)>(e|0)){break a}h=(a|c|(d^e|b))!=0}return h}function Aq(a){var b=0,c=0;b=G[a+32>>2];c=ab(b<<1);G[a+36>>2]=c;a:{if(!c){break a}if(G[a+44>>2]){G[a+28>>2]=b;return 0}b=ab(b);G[a+40>>2]=b;if(!b){Wa(c);break a}G[a+140>>2]=0;G[a+132>>2]=0;G[a+136>>2]=0;if(Nk(a+100|0,G[a+72>>2],G[a+76>>2])){Wa(G[a+40>>2]);Wa(G[a+36>>2]);break a}G[a+100>>2]=0;b=G[a+32>>2];G[a+28>>2]=b;if(!G[a+44>>2]){G[a+116>>2]=b;b=G[a+40>>2];G[a+112>>2]=b;G[a+4>>2]=b}return 0}Vd(a,-4,3221);return-1} -function Za(a,b){var c=0,d=0;d=a;a:{b:{if((d^b)&3){c=H[b|0];break b}if(b&3){while(1){c=H[b|0];E[d|0]=c;if(!c){break a}d=d+1|0;b=b+1|0;if(b&3){continue}break}}c=G[b>>2];if((c^-1)&c-16843009&-2139062144){break b}while(1){G[d>>2]=c;c=G[b+4>>2];d=d+4|0;b=b+4|0;if(!(c-16843009&(c^-1)&-2139062144)){continue}break}}E[d|0]=c;if(!(c&255)){break a}while(1){c=H[b+1|0];E[d+1|0]=c;d=d+1|0;b=b+1|0;if(c){continue}break}}return a}function ts(a,b,c,d,e,f,g,h,i,j,k,l){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;l=l|0;var m=0,n=0,o=0,p=0,q=0;m=(G[a>>2]+M(c,3)|0)-2|0;a:{if(d){if(!re(a,0,m,d,e,f,g,h,i,j,k)){break a}k=(k-j)/+(l|0);m=(l|0)>0?l:0;l=0;while(1){if((l|0)==(m|0)){return 0}n=1;o=b+l|0;p=c+l|0;q=+(l|0)*k+j;l=l+1|0;if(!re(a,o,p,d,e,f,g,h,i,q,+(l|0)*k+j)){continue}break}break a}n=!re(a,0,m,1,e,f,g,h,i,j,k)}return n|0}function nr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0;a:{if(G[c+4>>2]!=502){f=1;if(vj(c)){break a}}g=L[c+128>>3]-b;b=V(a*a+g*g);b=L[c+40>>3]<0?-b:b;if(b!=0){a=Ac(a/b,g/b)}else{a=0}L[d>>3]=a*L[c+120>>3];a=-90;b:{if(O(b-L[c+176>>3])<1e-12){break b}b=(L[c+160>>3]-b*b)*L[c+168>>3];if(O(b)>1){a=90;if(O(b+-1)<1e-12){break b}f=2;a=-90;if(O(b+1)<1e-12){break b}break a}a=Bc(b)}L[e>>3]=a;f=0}return f|0}function eb(a){var b=0,c=0,d=0;b=Fa-16|0;Fa=b;A(+a);d=v(1)|0;v(0)|0;d=d&2147483647;a:{if(d>>>0<=1072243195){c=1;if(d>>>0<1044816030){break a}c=jh(a,0);break a}c=a-a;if(d>>>0>=2146435072){break a}b:{switch($j(a,b)&3){case 0:c=jh(L[b>>3],L[b+8>>3]);break a;case 1:c=-ih(L[b>>3],L[b+8>>3],1);break a;case 2:c=-jh(L[b>>3],L[b+8>>3]);break a;default:break b}}c=ih(L[b>>3],L[b+8>>3],1)}a=c;Fa=b+16|0;return a}function Ub(a,b){var c=0,d=0;c=G[b+76>>2];if(!((c|0)>=0&(!c|G[48769]!=(c&-1073741825)))){a:{d=a&255;if((d|0)==G[b+80>>2]){break a}c=G[b+20>>2];if((c|0)==G[b+16>>2]){break a}G[b+20>>2]=c+1;E[c|0]=a;return}vh(b,d);return}c=G[b+76>>2];G[b+76>>2]=c?c:1073741823;b:{c:{d=a&255;if((d|0)==G[b+80>>2]){break c}c=G[b+20>>2];if((c|0)==G[b+16>>2]){break c}G[b+20>>2]=c+1;E[c|0]=a;break b}vh(b,d)}G[b+76>>2]=0}function uo(){var a=0,b=0,c=0,d=0,e=0,f=0;a=0;a:{if(G[49098]){break a}a=lb(1e4,4);G[49098]=a;if(!a){return 113}b=1;while(1){f=(c<<2)+a|0;b=b*16807;d=b/2147483647;b:{if(O(d)<2147483648){e=~~d;break b}e=-2147483648}b=+(e|0)*-2147483647+b;K[f>>2]=b/2147483647;c=c+1|0;if((c|0)!=1e4){continue}break}if(O(b)<2147483648){c=~~b}else{c=-2147483648}a=0;if((c|0)==1043618065){break a}Ua(25400);a=1}return a}function Cd(a,b,c){var d=0,e=0;a:{e=G[309723];if((e|0)==G[309724]){d=G[309722];b:{if(d){G[309724]=e<<1;d=ub(d,M(e,688));break b}G[309724]=100;d=ab(34400)}if(!d){break a}G[309722]=d;e=G[309723]}G[309723]=e+1;if((e|0)>=0){d=G[309722]+M(e,344)|0;G[d+52>>2]=a;G[d+8>>2]=0;G[d>>2]=-1e3;G[d+4>>2]=0;bb(d+88|0,b,c);G[d- -64>>2]=1;G[d+56>>2]=1;G[d+60>>2]=1;G[d+84>>2]=0}return e}G[309737]=113;return-1}function ib(a){var b=0,c=0;b=Fa-16|0;Fa=b;A(+a);c=v(1)|0;v(0)|0;c=c&2147483647;a:{if(c>>>0<=1072243195){if(c>>>0<1045430272){break a}a=ih(a,0,0);break a}if(c>>>0>=2146435072){a=a-a;break a}b:{switch($j(a,b)&3){case 0:a=ih(L[b>>3],L[b+8>>3],1);break a;case 1:a=jh(L[b>>3],L[b+8>>3]);break a;case 2:a=-ih(L[b>>3],L[b+8>>3],1);break a;default:break b}}a=-jh(L[b>>3],L[b+8>>3])}Fa=b+16|0;return a}function jo(a,b,c){var d=0,e=0,f=0;f=Fa-16|0;Fa=f;e=G[a>>2];d=G[a+4>>2];a:{b:{if((e|0)!=G[d+76>>2]){mb(a,e+1|0,0,c);break b}if((G[d+128>>2]&G[d+132>>2])!=-1){break b}if((Rb(a,c)|0)>0){break a}}d=G[a+4>>2];c:{if(!G[d+80>>2]){vd(a,2,f+12|0,0,0,c);a=112320/(G[f+12>>2]/10|0)|0;break c}e=G[d+960>>2];a=G[d+964>>2];c=e>>>0>1&(a|0)>=0|(a|0)>0;a=Du(112320,0,c?e:1,c?a:0);a=a?a:1}G[b>>2]=a}Fa=f+16|0}function mh(a,b,c,d,e,f){var g=0;g=G[f>>2];if((g|0)<=0){if(c){Eg(a,c,f)}a:{if(!d|G[f>>2]>0){break a}c=G[a>>2];g=G[a+4>>2];b:{if((c|0)!=G[g+76>>2]){mb(a,c+1|0,0,f);break b}if((G[g+128>>2]&G[g+132>>2])!=-1){break b}if((Rb(a,f)|0)>0){break a}}c=G[a+4>>2];if(!G[c+80>>2]){G[d>>2]=G[c+136>>2];break a}if(G[c+1088>>2]){G[d>>2]=G[c+1108>>2];break a}G[f>>2]=233}if(e){de(a,b,e,f)}g=G[f>>2]}return g}function bk(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0;d=M(a,24);g=d+202496|0;h=d+202512|0;a:{if(G[h>>2]==1){f=d+202504|0;d=f;i=G[d+4>>2];d=G[d>>2];e=116;if(zf(G[g>>2],d,d>>31,0)){break a}G[f>>2]=d;G[f+4>>2]=i}e=106;if((hb(b,1,c,G[g>>2])|0)!=(c|0)){break a}a=M(a,24)+202504|0;d=a;b=c+G[d>>2]|0;a=G[d+4>>2]+(c>>31)|0;G[d>>2]=b;G[d+4>>2]=b>>>0>>0?a+1|0:a;G[h>>2]=2;e=0}return e|0}function Qk(a,b,c){var d=0,e=0,f=0;d=G[c+16>>2];a:{if(!d){if(el(c)){break a}d=G[c+16>>2]}f=G[c+20>>2];if(d-f>>>0>>0){return Ja[G[c+36>>2]](c,a,b)|0}b:{if(G[c+80>>2]<0){d=0;break b}e=b;while(1){d=e;if(!d){d=0;break b}e=d-1|0;if(H[e+a|0]!=10){continue}break}e=Ja[G[c+36>>2]](c,a,d)|0;if(e>>>0>>0){break a}a=a+d|0;b=b-d|0;f=G[c+20>>2]}bb(f,a,b);G[c+20>>2]=G[c+20>>2]+b;e=b+d|0}return e}function Lb(){var a=0,b=0,c=0;a=G[950330];b=G[950331];if((a|0)>=(b|0)){a:{if(!b){G[950331]=1024;a=Xb(4096);break a}a=b+1024|0;G[950331]=a;a=lf(G[950332],a<<2)}G[950332]=a;c=G[950331];if((b|0)<(c|0)){cb(a+(b<<2)|0,0,c-b<<2)}a=G[950330]}b:{if(a){b=a-1|0;a=G[G[950332]+(b<<2)>>2];if(!G[a+24>>2]){break b}}a=Ic(1,60);b=G[950330];G[G[950332]+(b<<2)>>2]=a;G[950330]=b+1}G[a+20>>2]=0;G[a>>2]=b}function Ej(a,b,c){var d=0,e=0,f=0;if(!c){return 0}d=H[a|0];a:{if(!d){break a}while(1){b:{e=H[b|0];if(!e){break b}c=c-1|0;if(!c){break b}c:{if((d|0)==(e|0)){break c}e=d-65>>>0<26?d|32:d;d=H[b|0];if((e|0)==((d-65>>>0<26?d|32:d)|0)){break c}f=H[a|0];break a}b=b+1|0;d=H[a+1|0];a=a+1|0;if(d){continue}break a}break}f=d}a=f&255;c=a-65>>>0<26?a|32:a;a=H[b|0];return c-(a-65>>>0<26?a|32:a)|0}function zc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0;g=M(b,c);e=G[d+72>>2];G[d+72>>2]=e-1|e;e=G[d+4>>2];f=G[d+8>>2];if((e|0)==(f|0)){e=g}else{h=e;e=f-e|0;e=e>>>0>>0?e:g;bb(a,h,e);G[d+4>>2]=e+G[d+4>>2];a=a+e|0;e=g-e|0}if(e){while(1){a:{if(!si(d)){f=Ja[G[d+32>>2]](d,a,e)|0;if(f){break a}}return(g-e>>>0)/(b>>>0)|0}a=a+f|0;e=e-f|0;if(e){continue}break}}return(b?c:0)|0}function ki(a,b){var c=0,d=0,e=0,f=0;a:{if((a|0)%25|0){c=G[309730];break a}b:{if(a){c=a+25|0;e=1238916,f=ub(G[309729],M(c,244)),G[e>>2]=f;c=ub(G[309730],M(c,124));d=G[309729];break b}d=ab(6100);G[309729]=d;c=ab(3100)}G[309730]=c;if(c?d:0){break a}if(d){Wa(d);c=G[309730]}if(c){Wa(c)}G[309729]=0;G[309730]=0;G[b>>2]=113;return 113}a=M(a,124)+c|0;G[a+116>>2]=0;G[a+120>>2]=0;return 0}function Vd(a,b,c){var d=0,e=0,f=0;d=Fa-16|0;Fa=d;e=G[a+96>>2];if(e){if(G[a+92>>2]!=-4){Wa(e)}G[a+96>>2]=0}a:{switch(b+5|0){default:G[a>>2]=0;break;case 0:case 5:break a}}G[a+92>>2]=b;b:{if(!c|(b|0)==-4){break b}b=G[a+24>>2];e=ab((Va(b)+Va(c)|0)+3|0);G[a+96>>2]=e;if(!e){G[a+92>>2]=-4;break b}a=Va(b);f=Va(c);G[d+8>>2]=c;G[d+4>>2]=67697;G[d>>2]=b;Ya(e,(a+f|0)+3|0,8738,d)}Fa=d+16|0}function Ms(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;pn(c,d);a=G[309737];if(!a){a:{b=G[309722];a=G[309725];e=b+M(a,344)|0;b:{if(G[e>>2]!=-1e3){if((d|0)<=0){break a}a=b+M(a,344)|0;b=a;e=G[a+88>>2];a=0;while(1){if(!(H[G[b+84>>2]+a|0]|!H[a+e|0])){c=a+c|0;break b}a=a+1|0;if((d|0)!=(a|0)){continue}break}break a}if(!H[e+88|0]){break a}}G[g>>2]=c;return-1}a=0}return a|0}function rf(a,b,c,d,e){var f=0,g=0;f=Fa-16|0;Fa=f;c=E[c|0];a:{b:{if((c|0)<=63){a=Ye(a,b);c=0;if(!a){break a}if((Va(a)|0)<(d|0)){Za(e,a);break b}if((d|0)>=2){rb(e,a,d-1|0);break b}E[e|0]=H[a|0];break b}g=Za(f,b);b=g+Va(b)|0;E[b|0]=c;E[b+1|0]=0;a=Ye(a,g);c=0;if(!a){break a}if((Va(a)|0)<(d|0)){Za(e,a);break b}if((d|0)>=2){rb(e,a,d-1|0);break b}E[e|0]=H[a|0]}c=1}Fa=f+16|0;return c}function yg(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0;d=G[309722];c=d+M(a,344)|0;e=G[c+8>>2];if((e|0)>0){while(1){i=b;g=G[c+52>>2];h=(f<<2)+c|0;b=G[h+12>>2];if((g|0)!=G[(M(b,344)+d|0)+52>>2]){b=Fb(g,0,b);G[h+12>>2]=b;if((b|0)<0){return-1}e=G[c+8>>2];d=G[309722]}b=i+G[(M(b,344)+d|0)+56>>2]|0;f=f+1|0;if((e|0)>(f|0)){continue}break}}G[c+56>>2]=b;G[c- -64>>2]=b;G[c+60>>2]=1;return a}function xs(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;l=+l;m=+m;n=n|0;o=+o;var p=0,q=0;b=G[a>>2]+M(c,3)|0;uf(a,0,b-2|0,d,e,m,m,h,i,l,m,o);uf(a,b,b-1|0,d,e,m,m,h,i,j,k,o);if((n|0)>0){f=m-k;m=+(n|0);f=f/m;g=(l-j)/m;b=0;while(1){p=b;q=b+c|0;l=m;b=b+1|0;m=+(b|0);uf(a,p,q,d,e,l,l,h,i,m*g+j,m*f+k,o);if((b|0)!=(n|0)){continue}break}}}function ws(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;l=+l;m=+m;n=n|0;o=+o;var p=0,q=0;b=G[a>>2]+M(c,3)|0;tf(a,0,b-2|0,d,e,m,m,h,i,l,m,o);tf(a,b,b-1|0,d,e,m,m,h,i,j,k,o);if((n|0)>0){f=m-k;m=+(n|0);f=f/m;g=(l-j)/m;b=0;while(1){p=b;q=b+c|0;l=m;b=b+1|0;m=+(b|0);tf(a,p,q,d,e,l,l,h,i,m*g+j,m*f+k,o);if((b|0)!=(n|0)){continue}break}}}function vb(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0;d=Fa-16|0;Fa=d;c=Fa-160|0;Fa=c;G[c+60>>2]=a;G[c+20>>2]=a;G[c+24>>2]=-1;e=c+16|0;te(e,0,0);Jm(c,e,1,1);f=G[c+8>>2];g=G[c+12>>2];h=G[c>>2];e=G[c+4>>2];if(b){G[b>>2]=((G[c+20>>2]+G[c+136>>2]|0)-G[c+60>>2]|0)+a}G[d+8>>2]=f;G[d+12>>2]=g;G[d>>2]=h;G[d+4>>2]=e;Fa=c+160|0;i=Ui(G[d>>2],G[d+4>>2],G[d+8>>2],G[d+12>>2]);Fa=d+16|0;return i}function df(){var a=0,b=0,c=0,d=0,e=0;a=G[50359];a:{if((a|0)<=0){break a}if(a-1>>>0>=3){e=a&-4;while(1){b=c<<2;E[G[b+199296>>2]]=0;E[G[(b|4)+199296>>2]]=0;E[G[(b|8)+199296>>2]]=0;E[G[(b|12)+199296>>2]]=0;c=c+4|0;d=d+4|0;if((e|0)!=(d|0)){continue}break}}b=a&3;if(!b){break a}a=0;while(1){E[G[(c<<2)+199296>>2]]=0;c=c+1|0;a=a+1|0;if((b|0)!=(a|0)){continue}break}}G[50359]=0}function vi(a,b,c,d){var e=0,f=0;a:{if((d|0)!=1){break a}e=G[a+8>>2];if(!e){break a}f=b;e=e-G[a+4>>2]|0;b=b-e|0;c=c-((e>>31)+(e>>>0>f>>>0)|0)|0}b:{if(G[a+20>>2]!=G[a+28>>2]){Ja[G[a+36>>2]](a,0,0)|0;if(!G[a+20>>2]){break b}}G[a+28>>2]=0;G[a+16>>2]=0;G[a+20>>2]=0;Ja[G[a+40>>2]](a,b,c,d)|0;if((Ia|0)<0){break b}G[a+4>>2]=0;G[a+8>>2]=0;G[a>>2]=G[a>>2]&-17;return 0}return-1}function zg(a){var b=0,c=0,d=0;a:{b=G[309723];if((b|0)==G[309724]){c=G[309722];b:{if(c){G[309724]=b<<1;b=ub(c,M(b,688));break b}G[309724]=100;b=ab(34400)}if(!b){break a}G[309722]=b;b=G[309723]}G[309723]=b+1;if((b|0)>=0){c=G[309722];d=G[(c+M(a,344)|0)+52>>2];c=c+M(b,344)|0;G[c+12>>2]=a;G[c+8>>2]=1;G[c+52>>2]=d;G[c+4>>2]=21;G[c>>2]=123}return b}G[309737]=113;return-1}function wl(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;b=Fa-32|0;Fa=b;c=Gq(G[a+24>>2]+131072|0);d=Gq(G[a+16>>2]+131086|0);e=G[a+8>>2];f=G[a+12>>2];g=G[a+4>>2];h=G[a>>2];G[b+24>>2]=G[a+20>>2]+1900;i=b,j=Fu(h,g),G[i+16>>2]=j;G[b+20>>2]=Ia;G[b+4>>2]=d;G[b>>2]=c;i=b,j=Fu(e,f),G[i+8>>2]=j;G[b+12>>2]=Ia;if((Ya(3809680,26,75077,b)|0)>=26){W()}Fa=b+32|0;return 3809680}function Vn(a){var b=0,c=0;b=Va(a);if(!(H[a|0]!=39|H[(a+b|0)-1|0]!=39)){b=b-2|0;if((b|0)>0){yd(a,a+1|0,b)}E[a+b|0]=0}a:{b:{b=Va(a)-1|0;if((b|0)<=0){break b}while(1){if(H[a+c|0]!=32){break b}c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)==(c|0)|(b|0)<0){break a}while(1){c=a+b|0;if(H[c|0]!=32){break a}E[c|0]=0;c=(b|0)>0;b=b-1|0;if(c){continue}break}}}function ze(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0;d=Fa-96|0;Fa=d;a:{if(G[c>>2]>0){break a}e=Va(b);if((e|0)<=0){break a}g=H[66554];h=H[66546]|H[66547]<<8|(H[66548]<<16|H[66549]<<24);i=H[66550]|H[66551]<<8|(H[66552]<<16|H[66553]<<24);while(1){E[d+8|0]=g;G[d>>2]=h;G[d+4>>2]=i;wb(a,qb(d,b+f|0,72),c);f=f+72|0;j=e>>>0>72;e=e-72|0;if(j){continue}break}}Fa=d+96|0}function id(){var a=0;a=G[47463];if(!((a|0)>=0&(!a|G[48769]!=(a&-1073741825)))){a:{if(G[47464]==10){break a}a=G[47449];if((a|0)==G[47448]){break a}G[47449]=a+1;E[a|0]=10;return}vh(189776,10);return}a=G[47463];G[47463]=a?a:1073741823;b:{c:{if(G[47464]==10){break c}a=G[47449];if((a|0)==G[47448]){break c}G[47449]=a+1;E[a|0]=10;break b}vh(189776,10)}G[47463]=0}function Pg(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0;d=Fa-96|0;Fa=d;a:{if(G[c>>2]>0){break a}e=Va(b);if((e|0)<=0){break a}g=H[66595];h=H[66587]|H[66588]<<8|(H[66589]<<16|H[66590]<<24);i=H[66591]|H[66592]<<8|(H[66593]<<16|H[66594]<<24);while(1){E[d+8|0]=g;G[d>>2]=h;G[d+4>>2]=i;wb(a,qb(d,b+f|0,72),c);f=f+72|0;j=e>>>0>72;e=e-72|0;if(j){continue}break}}Fa=d+96|0}function Hh(a){var b=0;if(!(!a|G[952412]==(a|0))){Hl(a);a:{if(!a){break a}if(G[a+12>>2]>=2){hb(73270,18,1,G[24367])}b=G[a+136>>2];if(!b){break a}Ja[b|0](a)|0}pb(G[a+64>>2]);pb(G[a>>2]);pb(G[a+44>>2]);pb(G[a+48>>2]);pb(G[a+52>>2]);pb(G[a+56>>2]);pb(G[a+60>>2]);pb(G[a+32>>2]);pb(G[a+36>>2]);pb(G[a+16>>2]);pb(G[a+28>>2]);pb(G[a+176>>2]);pb(G[a+160>>2]);pb(a)}}function bt(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0;g=M(a,48);a=g+757256|0;h=G[a>>2];f=c+h|0;i=c>>31;d=i+G[a+4>>2]|0;d=c>>>0>f>>>0?d+1|0:d;e=g+757264|0;f=f>>>0<=J[e>>2];e=G[e+4>>2];if(f&(e|0)>=(d|0)|(d|0)<(e|0)){bb(b,h+G[G[g+757232>>2]>>2]|0,c);b=i+G[a+4>>2]|0;d=c+G[a>>2]|0;b=d>>>0>>0?b+1|0:b;G[a>>2]=d;G[a+4>>2]=b;a=0}else{a=107}return a|0}function nt(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0;e=M(a,48);d=G[e+757252>>2];if(d){f=e+757232|0;d=Ja[d|0](G[G[f>>2]>>2],b)|0;if(!d){Ua(60128);return 113}g=M(a,48)+757240|0;a=G[G[g>>2]>>2];if(b>>>0>a>>>0&(c|0)>=0|(c|0)>0){cb(a+d|0,0,b-a|0)}G[G[f>>2]>>2]=d;G[G[g>>2]>>2]=b}a=e+757264|0;G[a>>2]=b;G[a+4>>2]=c;a=e+757256|0;G[a>>2]=b;G[a+4>>2]=c;return 0}function jr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;a:{if(G[c+4>>2]!=504){f=1;if(tj(c)){break a}}g=L[c+128>>3]-b;b=V(a*a+g*g);b=L[c+40>>3]<0?-b:b;b:{if(b==0){L[d>>3]=L[c+120>>3]*0;f=2;a=-90;if(L[c+112>>3]<0){break b}break a}h=d,i=Ac(a/b,g/b)*L[c+120>>3],L[h>>3]=i;a=De($b(b*L[c+144>>3],L[c+120>>3]));a=90-(a+a)}L[e>>3]=a;f=0}return f|0}function qc(a,b){var c=0,d=0,e=0;d=Fa-32|0;Fa=d;c=E[b|0];a:{if(!(H[b+1|0]?c:0)){b=Gg(a,c);break a}cb(d,0,32);c=H[b|0];if(c){while(1){e=(c>>>3&28)+d|0;G[e>>2]=G[e>>2]|1<>>3&28)+d>>2]>>>c&1){break a}c=H[b+1|0];b=b+1|0;if(c){continue}break}}Fa=d+32|0;return b-a|0}function Yb(a,b){var c=0,d=0,e=0;c=b;d=H[a|0];a:{if(!d){break a}while(1){e=d<<24>>24;if(!((e|0)==32|e-9>>>0<5)){while(1){E[c|0]=d;c=c+1|0;d=H[a+1|0];a=a+1|0;if(d){continue}break}break a}d=H[a+1|0];a=a+1|0;if(d){continue}break}}E[c|0]=0;a=c-b|0;if(a){while(1){c=c-1|0;b=E[c|0];if(!((b|0)==32|b-9>>>0<5)){return}E[c|0]=0;a=a-1|0;if(a){continue}break}}}function Zh(a){var b=0,c=0,d=0;d=H[a|0];b=d-66|0;b=(b<<5|(b&248)>>>3)&255;a:{b:{if(!(b>>>0>5|!(1<>>0>1){break a}}c=sb(a)}return c}function Ht(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0;e=G[a+84>>2];f=G[e+4>>2];g=G[a+28>>2];d=G[a+20>>2]-g|0;d=d>>>0>f>>>0?f:d;if(d){bb(G[e>>2],g,d);G[e>>2]=d+G[e>>2];f=G[e+4>>2]-d|0;G[e+4>>2]=f}d=G[e>>2];f=c>>>0>f>>>0?f:c;if(f){bb(d,b,f);d=f+G[e>>2]|0;G[e>>2]=d;G[e+4>>2]=G[e+4>>2]-f}E[d|0]=0;b=G[a+44>>2];G[a+28>>2]=b;G[a+20>>2]=b;return c|0}function Cf(a,b,c,d,e,f){var g=0,h=0;g=Fa-208|0;Fa=g;E[c|0]=0;E[d|0]=0;if(e){E[e|0]=0}h=G[f>>2];if((h|0)<=0){a:{if((Sd(a,b,g+112|0,f)|0)>0){break a}a=g+112|0;Fi(a,c,g+12|0);if((mc(a,d,e,f)|0)>0){break a}if((go(c,f)|0)<=0){break a}G[g+4>>2]=c;G[g>>2]=b;a=g+16|0;Ya(a,81,10301,g);Ua(a);if((b|0)%36|0){break a}Ua(47502)}h=G[f>>2]}Fa=g+208|0;return h}function wn(a){var b=0,c=0,d=0,e=0,f=0;A(.5);d=v(1)|0;f=v(0)|0;A(+a);c=v(1)|0;v(0)|0;x(0,f|0);x(1,d&2147483647|c&-2147483648);e=+z();A(+a);c=v(1)|0;x(0,v(0)|0);c=c&2147483647;x(1,c|0);b=+z();d=c;a:{if(c>>>0<=1082535489){b=gh(b);if(d>>>0<=1072693247){if(d>>>0<1045430272){break a}return e*(b+b-b*b/(b+1))}return e*(b+b/(b+1))}a=xn(b,e+e)}return a}function Ge(a,b){var c=0,d=0,e=0,f=0;if((b|0)>0){f=b<<3;b=0;while(1){c=a+b|0;d=H[c|0];e=c;c=(b|7)+a|0;E[e|0]=H[c|0];E[c|0]=d;c=(b|1)+a|0;d=H[c|0];e=c;c=(b|6)+a|0;E[e|0]=H[c|0];E[c|0]=d;c=(b|2)+a|0;d=H[c|0];e=c;c=(b|5)+a|0;E[e|0]=H[c|0];E[c|0]=d;c=(b|3)+a|0;d=H[c|0];e=c;c=(b|4)+a|0;E[e|0]=H[c|0];E[c|0]=d;b=b+8|0;if((f|0)>(b|0)){continue}break}}}function Jb(a,b,c,d,e){var f=0,g=0,h=0;f=G[e>>2];a:{if((f|0)>0){break a}if((c|0)<0){G[e>>2]=304;return 304}g=G[a>>2];f=G[a+4>>2];if((g|0)!=G[f+76>>2]){mb(a,g+1|0,0,e);f=G[a+4>>2]}g=Du(b,c,2880,0);h=G[f+72>>2];if(!((h|0)>=0&(g|0)==G[((h<<2)+f|0)+1256>>2])){Hc(a,g,d,e)}f=G[e>>2];if((f|0)>0){break a}a=G[a+4>>2];G[a+56>>2]=b;G[a+60>>2]=c}return f}function Kk(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0;h=Fa-240|0;Fa=h;G[h>>2]=a;i=1;a:{if((d|0)<2){break a}k=0-b|0;f=a;while(1){f=f+k|0;j=d-2|0;g=f-G[(j<<2)+e>>2]|0;if((Ja[c|0](a,g)|0)>=0){if((Ja[c|0](a,f)|0)>=0){break a}}l=g;g=(Ja[c|0](g,f)|0)>=0;f=g?l:f;G[(i<<2)+h>>2]=f;i=i+1|0;d=g?d-1|0:j;if((d|0)>1){continue}break}}dp(b,h,i);Fa=h+240|0}function Dc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;d=G[c>>2];if((d|0)<=0){d=G[a>>2];e=G[a+4>>2];a:{if(d|!!(G[e+104>>2]|G[e+108>>2])){b:{if(G[e+76>>2]!=(d|0)){mb(a,d+1|0,0,c);break b}if((G[e+128>>2]&G[e+132>>2])!=-1){break b}if((Rb(a,c)|0)>0){break a}}d=G[a+4>>2];a=G[d+80>>2];G[b>>2]=a;a=G[d+1088>>2]?0:a}else{a=0}G[b>>2]=a}d=G[c>>2]}return d|0}function Eg(a,b,c){var d=0,e=0;d=G[c>>2];if((d|0)<=0){d=G[a>>2];e=G[a+4>>2];a:{b:{if((d|0)!=G[e+76>>2]){mb(a,d+1|0,0,c);break b}if((G[e+128>>2]&G[e+132>>2])!=-1){break b}if((Rb(a,c)|0)>0){break a}}ef(a,1,c);d=G[a+4>>2];if(!G[d+80>>2]){Cb(a,31,32941,b,0,c);break a}if(G[d+1088>>2]){Cb(a,31,32893,b,0,c);break a}G[c>>2]=233}d=G[c>>2]}return d}function vs(a,b,c,d,e,f,g,h,i,j,k,l){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;l=l|0;var m=0;if(j>k){while(1){j=j+-360;if(k>2]+M(c,3)|0)-2|0,d,e,h,i,j,k);if((l|0)>0){f=(k-j)/+(l|0);while(1){m=b+c|0;g=+(b|0)*f+j;b=b+1|0;Ze(a,0,m,d,e,h,i,g,+(b|0)*f+j);if((b|0)!=(l|0)){continue}break}}}function Qf(a,b){a:{if((b|0)>=1024){a=a*898846567431158e293;if(b>>>0<2047){b=b-1023|0;break a}a=a*898846567431158e293;b=((b|0)<3069?b:3069)-2046|0;break a}if((b|0)>-1023){break a}a=a*2004168360008973e-307;if(b>>>0>4294965304){b=b+969|0;break a}a=a*2004168360008973e-307;b=((b|0)>-2960?b:-2960)+1938|0}x(0,0);x(1,b+1023<<20);return a*+z()}function Mn(a){var b=0,c=0,d=0,e=0;a:{d=G[110919];if(!d){if((hb(673152,1,a,G[119132])|0)==(a|0)){break a}Ua(443536);Ua(59704);return}b=G[G[110917]>>2];b:{c=G[110922];e=c+a|0;if(e>>>0<=J[G[110918]>>2]){break b}b=Ja[d|0](b,e)|0;G[G[110917]>>2]=b;c=G[110922];G[G[110918]>>2]=c+a;if(b){break b}Ua(443536);Ua(59658);return}bb(b+c|0,673152,a)}}function kn(a,b,c,d,e){var f=0,g=0;f=Fa-80|0;Fa=f;if(!d){d=Va(c)}a:{if((e|0)<0){if(!G[309737]){G[309737]=431}a=bb(f,136017,80);E[a+79|0]=0;Ua(a);a=-1;break a}b:{if(!((d|0)>=(e|0)?e:0)){cb(a,0,b);break b}if((b+e|0)>(d|0)){g=(c+e|0)-1|0;c=(d-e|0)+1|0;cb(bb(a,g,c)+c|0,0,b-c|0);break b}bb(a,(c+e|0)-1|0,b)}E[a+b|0]=0;a=0}Fa=f+80|0;return a}function eu(a){a=a|0;var b=0,c=0,d=0;b=Fa-131104|0;Fa=b;G[b+16>>2]=42205;G[b+20>>2]=a;d=b+65568|0;Ya(d,65535,8740,b+16|0);G[b+4>>2]=a;G[b>>2]=42205;c=b+32|0;Ya(c,65535,4424,b);Pl(d,c);a=28780;c=ac(c,13287);a:{if(!c){break a}d=zc(3809712,1,65535,c);Hb(c);E[d+3809712|0]=0;if((d|0)<0){break a}Vg(b+32|0);a=3809712}Fa=b+131104|0;return a|0}function Tb(a,b,c){var d=0;d=Fa-4112|0;Fa=d;G[d+12>>2]=c;if(G[47758]==-1){c=Fd(33977);if(c){c=_b(c)}else{c=2}G[47758]=c}G[d>>2]=b;b=d+16|0;Ya(b,4095,10196,d);oo(3747440,4095,b,G[d+12>>2]);b=G[945052];a=b?b:a;c=G[47758];if(!(!a|!c)){fe(3747440,a);$a(a);c=G[47758]}if((c|0)>=2){a=G[945053];if(a){Ja[a|0]();c=G[47758]}sc(c);W()}Fa=d+4112|0}function cd(a){var b=0;a:{b=G[a+5820>>2];b:{if((b|0)==16){b=G[a+20>>2];G[a+20>>2]=b+1;E[b+G[a+8>>2]|0]=H[a+5816|0];b=G[a+20>>2];G[a+20>>2]=b+1;E[b+G[a+8>>2]|0]=H[a+5817|0];F[a+5816>>1]=0;b=0;break b}if((b|0)<8){break a}b=G[a+20>>2];G[a+20>>2]=b+1;E[b+G[a+8>>2]|0]=H[a+5816|0];F[a+5816>>1]=H[a+5817|0];b=G[a+5820>>2]-8|0}G[a+5820>>2]=b}}function Xc(a,b){var c=0,d=0,e=0;c=H[a|0];a:{if(!c){break a}while(1){d=H[b|0];if(!d){e=c;break a}b:{if((c|0)==(d|0)){break b}d=c-65>>>0<26?c|32:c;c=H[b|0];if((d|0)==((c-65>>>0<26?c|32:c)|0)){break b}e=H[a|0];break a}b=b+1|0;c=H[a+1|0];a=a+1|0;if(c){continue}break}}a=e&255;e=a-65>>>0<26?a|32:a;a=H[b|0];return e-(a-65>>>0<26?a|32:a)|0}function ob(a,b,c){var d=0,e=0;a=Ye(a,b);if(!a){return 0}a=a+(H[a|0]==35)|0;a:{if((Va(a)|0)>=82){rb(1285216,a,81);E[1285297]=0;break a}Za(1285216,a)}b:{if((ah(1285216)|0)!=2){break b}a=jb(1285216,68);if(a){E[a|0]=101}a=jb(1285216,100);if(a){E[a|0]=101}a=jb(1285216,69);if(!a){break b}E[a|0]=101}d=c,e=sb(1285216),L[d>>3]=e;return 1}function Ib(a,b){var c=0,d=0,e=0;c=E[b|0];d=(c-97>>>0<26?c&95:c)<<24>>24;c=E[a|0];c=(c-97>>>0<26?c&95:c)<<24;e=c>>24;if((d|0)<=(e|0)){while(1){if((d|0)<(e|0)){return 1}if(!c){return 0}c=E[a+1|0];d=E[b+1|0];b=b+1|0;a=a+1|0;d=(d-97>>>0<26?d&95:d)<<24>>24;c=(c-97>>>0<26?c&95:c)<<24;e=c>>24;if((d|0)<=(e|0)){continue}break}}return-1}function Nh(a,b,c){var d=0,e=0;while(1){d=a;a=d+1|0;if(H[d|0]==32){continue}break}G[b>>2]=d;a=H[d|0];if(a){while(1){a=a&255;if(a){if(!((a|0)==32|(a|0)==58)){a=H[d+1|0];d=d+1|0;continue}E[d|0]=0;a=d+1|0}else{a=d}while(1){d=a;a=d+1|0;if(H[d|0]==32){continue}break}e=e+1|0;G[(e<<2)+b>>2]=d;a=H[d|0];if(a){continue}break}}G[c>>2]=e}function bj(a,b){var c=0,d=0,e=0,f=0,g=0;c=G[936853];if(c){g=G[936852];while(1){e=(d<<2)+g|0;f=G[e>>2];if((f|0)==(a|0)){G[e>>2]=b;Wa(a);return}if(!(!b|f)){G[e>>2]=b;b=0}d=d+1|0;if((c|0)!=(d|0)){continue}break}}a:{if(!b){break a}a=ub(G[936852],(c<<2)+4|0);if(!a){break a}G[936852]=a;c=G[936853];G[936853]=c+1;G[a+(c<<2)>>2]=b}}function dp(a,b,c){var d=0,e=0,f=0,g=0,h=0;f=Fa-256|0;Fa=f;a:{if((c|0)<2){break a}h=(c<<2)+b|0;G[h>>2]=f;if(!a){break a}while(1){e=a>>>0<256?a:256;bb(G[h>>2],G[b>>2],e);d=0;while(1){g=(d<<2)+b|0;d=d+1|0;bb(G[g>>2],G[(d<<2)+b>>2],e);G[g>>2]=G[g>>2]+e;if((c|0)!=(d|0)){continue}break}a=a-e|0;if(a){continue}break}}Fa=f+256|0}function nh(a,b,c,d,e,f,g){var h=0;h=Fa-16|0;Fa=h;a:{if((Le(a,b,c,d,h+8|0,h,g)|0)>0){break a}b:{if(!e){break b}a=G[h+12>>2];b=G[h+8>>2];if((a|0)>=0&b>>>0>=2147483648|(a|0)>0){G[g>>2]=412;break b}G[e>>2]=b}if(!f){break a}a=G[h+4>>2];b=G[h>>2];if((a|0)>=0&b>>>0>=2147483648|(a|0)>0){G[g>>2]=412;break a}G[f>>2]=b}Fa=h+16|0}function ui(a,b){var c=0,d=0,e=0,f=0;c=Fa;f=c;e=4096;d=c-(a?16:4096)|0;Fa=d;c=d;a:{b:{if(!a){break b}c=a;e=b;if(b){break b}G[48624]=28;a=0;break a}a=0;b=wa(c|0,e|0)|0;if(b>>>0>=4294963201){G[48624]=0-b;b=-1}if((b|0)<0){break a}if(!(H[c|0]==47?b:0)){G[48624]=44;break a}a=c;if((d|0)!=(c|0)){break a}a=le(d)}Fa=f;return a}function _b(a){var b=0,c=0,d=0,e=0;while(1){b=a;a=b+1|0;c=E[b|0];if((c|0)==32|c-9>>>0<5){continue}break}a:{b:{c:{c=E[b|0];switch(c-43|0){case 0:break b;case 2:break c;default:break a}}e=1}c=E[a|0];b=a}if(c-48>>>0<10){while(1){d=(M(d,10)-E[b|0]|0)+48|0;a=E[b+1|0];b=b+1|0;if(a-48>>>0<10){continue}break}}return e?d:0-d|0}function ys(a,b,c,d,e,f,g,h,i,j,k,l){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;l=l|0;var m=0,n=0,o=0,p=0;vf(a,0,(G[a>>2]+M(c,3)|0)-2|0,d,e,f,g,h,i,j,k);if((l|0)>0){k=(k-j)/+(l|0);while(1){n=b+m|0;o=c+m|0;p=+(m|0)*k+j;m=m+1|0;vf(a,n,o,d,e,f,g,h,i,p,+(m|0)*k+j);if((l|0)!=(m|0)){continue}break}}}function db(a,b,c){var d=0,e=0,f=0,g=0;f=Fa-16|0;Fa=f;G[f+12>>2]=c;d=Fa-160|0;Fa=d;g=d+8|0;bb(g,92528,144);G[d+52>>2]=a;G[d+28>>2]=a;e=-2-a|0;e=e>>>0>2147483647?2147483647:e;G[d+56>>2]=e;a=a+e|0;G[d+36>>2]=a;G[d+24>>2]=a;a=Ak(g,b,c);if(e){b=G[d+28>>2];E[b-((b|0)==G[d+24>>2])|0]=0}Fa=d+160|0;Fa=f+16|0;return a}function Mg(a){var b=0,c=0,d=0;c=G[a+28>>2];cd(c);b=G[c+20>>2];d=G[a+16>>2];b=b>>>0>>0?b:d;a:{if(!b){break a}bb(G[a+12>>2],G[c+16>>2],b);G[a+12>>2]=b+G[a+12>>2];G[c+16>>2]=b+G[c+16>>2];G[a+20>>2]=b+G[a+20>>2];G[a+16>>2]=G[a+16>>2]-b;a=G[c+20>>2];G[c+20>>2]=a-b;if((a|0)!=(b|0)){break a}G[c+16>>2]=G[c+8>>2]}}function Hq(a,b){a:{if(!a){break a}cb(G[a+104>>2],0,G[a+80>>2]<<3);cb(G[a+108>>2],0,G[a+80>>2]<<3);cb(G[a+84>>2],0,G[a+80>>2]<<2);cb(G[a+88>>2],0,G[a+80>>2]<<2);if(G[a>>2]|!b){break a}cb(G[b+8>>2],0,G[a+80>>2]<<3);cb(G[b+12>>2],0,G[a+80>>2]<<3);cb(G[b+16>>2],0,G[a+80>>2]<<3);cb(G[b+20>>2],0,G[a+80>>2]<<3)}}function Qd(a,b,c){var d=0,e=0;if(G[c>>2]<=0){a:{e=G[a>>2];d=G[a+4>>2];b:{if((e|0)!=G[d+76>>2]){mb(a,e+1|0,0,c);break b}if((G[d+128>>2]&G[d+132>>2])!=-1){break b}if((Rb(a,c)|0)>0){break a}}a=G[a+4>>2];if(!G[a+80>>2]){G[b>>2]=G[a+136>>2];break a}if(G[a+1088>>2]){G[b>>2]=G[a+1108>>2];break a}G[c>>2]=233}}}function $m(a){var b=0;b=1;a:{if(!fb(a,16398,3)){break a}if(!fb(a,5791,8)){break a}if(!fb(a,13349,4)){break a}if(!fb(a,13361,3)){break a}if(!fb(a,13358,6)){break a}E[a+4|0]=H[15940];b=H[15936]|H[15937]<<8|(H[15938]<<16|H[15939]<<24);E[a|0]=b;E[a+1|0]=b>>>8;E[a+2|0]=b>>>16;E[a+3|0]=b>>>24;b=!a}return b}function Tf(a){var b=0;b=G[a+76>>2];a:{if(!((b|0)>=0&(!b|G[48769]!=(b&-1073741825)))){b=G[a+4>>2];if((b|0)!=G[a+8>>2]){G[a+4>>2]=b+1;b=H[b|0];break a}b=Ag(a);break a}b=G[a+76>>2];G[a+76>>2]=b?b:1073741823;b=G[a+4>>2];b:{if((b|0)!=G[a+8>>2]){G[a+4>>2]=b+1;b=H[b|0];break b}b=Ag(a)}G[a+76>>2]=0}return b}function ir(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;a:{if(G[c+4>>2]!=504){f=1;if(tj(c)){break a}}g=L[c+112>>3];b:{if(b==-90){f=2;b=0;if(g<0){break b}break a}b=L[c+136>>3]*$b(Xe((90-b)*.5),L[c+112>>3])}a=g*a;h=d,i=b*Kb(a),L[h>>3]=i;h=e,i=L[c+128>>3]-b*Mb(a),L[h>>3]=i;f=0}return f|0}function Eb(a,b,c){var d=0,e=0,f=0,g=0;f=Fa-16|0;Fa=f;G[f+12>>2]=c;d=Fa-160|0;Fa=d;g=d+8|0;bb(g,92528,144);G[d+52>>2]=a;G[d+28>>2]=a;e=-2-a|0;e=e>>>0>2147483647?2147483647:e;G[d+56>>2]=e;a=a+e|0;G[d+36>>2]=a;G[d+24>>2]=a;zk(g,b,c);if(e){a=G[d+28>>2];E[a-((a|0)==G[d+24>>2])|0]=0}Fa=d+160|0;Fa=f+16|0}function Bb(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0;if(!(!a|!H[a|0])){h=Va(a);f=h+1|0;e=G[b>>2];if(!(!e|!H[e|0])){g=Va(e)}d=G[c>>2];if((d|0)<=(g+f|0)){i=c;f=d;j=d^-1;c=(g+h|0)+2|0;d=d+1024|0;d=(f+(j+((c|0)>(d|0)?c:d)&-1024)|0)+1024|0;G[i>>2]=d}a:{if(!g){c=Ic(d,1);break a}c=lf(e,d)}G[b>>2]=c;Gb(c,a)}}function Kh(a,b,c,d,e){var f=0,g=0,h=0,i=0;f=Fa-256|0;Fa=f;h=G[e>>2];a:{if((h|0)>0){break a}if((Vc(a,b,f+176|0,f+96|0,e)|0)<=0){g=f+176|0;if(G[e>>2]<=0){i=c?84:70;E[g|0]=i;E[g+1|0]=i>>>8}Ob(b,g,d?H[d|0]==38?f+96|0:d:f+96|0,f,e);Hd(a,f,e)}if(G[e>>2]!=202){break a}G[e>>2]=h;Rg(a,b,c,d,e)}Fa=f+256|0}function nb(a,b,c){var d=0,e=0;a:{b:{if(c>>>0>=4){if((a|b)&3){break b}while(1){if(G[a>>2]!=G[b>>2]){break b}b=b+4|0;a=a+4|0;c=c-4|0;if(c>>>0>3){continue}break}}if(!c){break a}}while(1){d=H[a|0];e=H[b|0];if((d|0)==(e|0)){b=b+1|0;a=a+1|0;c=c-1|0;if(c){continue}break a}break}return d-e|0}return 0}function Zd(a,b){var c=0,d=0,e=0,f=0;d=Fa-16|0;Fa=d;a:{if(!b){b=0;break a}c=b>>31;e=(c^b)-c|0;c=P(e);od(d,e,0,0,0,c+81|0);e=0+G[d+8>>2]|0;c=(G[d+12>>2]^65536)+(16414-c<<16)|0;c=e>>>0>>0?c+1|0:c;f=b&-2147483648|c;c=G[d+4>>2];b=G[d>>2]}G[a>>2]=b;G[a+4>>2]=c;G[a+8>>2]=e;G[a+12>>2]=f;Fa=d+16|0}function Oj(a,b){var c=0,d=0;c=Fa-2080|0;Fa=c;a:{if(!bf(a,1025,c+1040|0,b)){if(H[c+1040|0]!=47){cf(c,b);if((Va(c)+Va(c+1040|0)|0)-1024>>>0<=4294966270){Ua(59420);G[b>>2]=104;a=104;break a}d=Va(c)+c|0;E[d|0]=47;E[d+1|0]=0;d=c+1040|0;_d(Gb(c,d),d,b)}Za(a,c+1040|0)}a=G[b>>2]}Fa=c+2080|0;return a}function en(a){var b=0;b=G[a+76>>2];if(!((b|0)>=0&(!b|G[48769]!=(b&-1073741825)))){b=G[a+4>>2];if((b|0)!=G[a+8>>2]){G[a+4>>2]=b+1;return H[b|0]}return Ag(a)}b=G[a+76>>2];G[a+76>>2]=b?b:1073741823;b=G[a+4>>2];a:{if((b|0)!=G[a+8>>2]){G[a+4>>2]=b+1;b=H[b|0];break a}b=Ag(a)}G[a+76>>2]=0;return b}function un(a){var b=0,c=0;A(+a);c=v(1)|0;x(0,v(0)|0);b=c&2147483647;x(1,b|0);a=+z();a:{if(b>>>0>=1071748075){if(b>>>0>=1077149697){a=-0/a+1;break a}a=1-2/(gh(a+a)+2);break a}if(b>>>0>=1070618799){a=gh(a+a);a=a/(a+2);break a}if(b>>>0<1048576){break a}a=gh(a*-2);a=-a/(a+2)}return(c|0)<0?-a:a}function Kd(a,b,c,d,e,f){var g=0,h=0,i=0;g=Fa-256|0;Fa=g;i=G[f>>2];a:{if((i|0)>0){h=i;break a}if((Vc(a,b,g+176|0,g+96|0,f)|0)<=0){h=g+176|0;If(c,d,h,f);Ob(b,h,e?H[e|0]==38?g+96|0:e:g+96|0,g,f);Hd(a,g,f)}h=G[f>>2];if((h|0)!=202){break a}G[f>>2]=i;ll(a,b,c,d,e,f);h=G[f>>2]}Fa=g+256|0;return h}function Gc(a,b,c,d,e,f){var g=0,h=0,i=0;g=Fa-256|0;Fa=g;i=G[f>>2];a:{if((i|0)>0){h=i;break a}if((Vc(a,b,g+176|0,g+96|0,f)|0)<=0){h=g+176|0;jl(c,d,h,f);Ob(b,h,e?H[e|0]==38?g+96|0:e:g+96|0,g,f);Hd(a,g,f)}h=G[f>>2];if((h|0)!=202){break a}G[f>>2]=i;hd(a,b,c,d,e,f);h=G[f>>2]}Fa=g+256|0;return h}function zb(a,b,c,d){var e=0,f=0;e=Fa-32|0;Fa=e;E[c|0]=0;a:{b:{f=Va(a);if(!f|(b|0)<0){break b}G[e>>2]=b;Ya(e+16|0,16,30633,e);a=Za(c,a);while(1){f=f-1|0;b=a+f|0;if(H[b|0]==32){E[b|0]=0;if(f){continue}}break}if(Va(e+16|0)+Va(a)>>>0>=9){break b}Gb(a,e+16|0);break a}G[d>>2]=206}Fa=e+32|0}function Fd(a){var b=0,c=0,d=0,e=0;b=Gg(a,61);if((b|0)==(a|0)){return 0}d=b-a|0;a:{if(H[d+a|0]){break a}b=G[50361];if(!b){break a}c=G[b>>2];if(!c){break a}while(1){b:{if(!fb(a,c,d)){c=G[b>>2]+d|0;if(H[c|0]==61){break b}}c=G[b+4>>2];b=b+4|0;if(c){continue}break a}break}e=c+1|0}return e}function Sn(a){var b=0,c=0,d=0,e=0;b=G[a+40>>2];b=Ja[b|0](a,0,0,H[a|0]&128?G[a+20>>2]==G[a+28>>2]?1:2:1)|0;c=Ia;a:{if((c|0)<0){break a}e=b;d=G[a+8>>2];if(d){a=a+4|0}else{d=G[a+28>>2];if(!d){break a}a=a+20|0}b=G[a>>2]-d|0;a=e+b|0;c=(b>>31)+c|0;c=a>>>0>>0?c+1|0:c;b=a}Ia=c;return b}function mr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0;a:{if(G[c+4>>2]!=502){f=1;if(vj(c)){break a}}a=L[c+112>>3]*a;if(b==-90){b=L[c+176>>3]}else{b=L[c+136>>3]*V(L[c+144>>3]-L[c+152>>3]*Kb(b))}g=d,h=b*Kb(a),L[g>>3]=h;g=e,h=L[c+128>>3]-b*Mb(a),L[g>>3]=h;f=0}return f|0}function ho(a){var b=0,c=0,d=0,e=0,f=0,g=0;c=G[50359];f=c&(c>>31^-1);d=c;a:{while(1){if((e|0)==(f|0)){break a}b=G[49824];g=Za(a,b);E[b|0]=0;b=d-1|0;G[50359]=b;if((d|0)!=1){yd(199296,199300,(c-e<<2)-4|0)}e=e+1|0;d=b;b=E[g|0];if((b|0)==27){continue}break}return b}E[a|0]=0;return 0}function Ft(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0;e=M(a,24);f=e+202496|0;a=b;d=a>>31;g=d;d=pa(gk(G[f>>2])|0,a|0,d|0)|0;if(d>>>0>=4294963201){G[48624]=0-d}if(!zf(G[f>>2],a,g,0)){a=e+202504|0;G[a>>2]=b;G[a+4>>2]=c}G[e+202512>>2]=0;a=e+202504|0;G[a>>2]=b;G[a+4>>2]=c;return 0}function Rn(){var a=0;while(1){G[M(a,24)+202496>>2]=0;G[M(a|1,24)+202496>>2]=0;G[M(a|2,24)+202496>>2]=0;G[M(a|3,24)+202496>>2]=0;G[M(a|4,24)+202496>>2]=0;G[M(a|5,24)+202496>>2]=0;G[M(a|6,24)+202496>>2]=0;G[M(a|7,24)+202496>>2]=0;a=a+8|0;if((a|0)!=1e4){continue}break}return 0}function ye(a){var b=0,c=0,d=0;c=-2;a:{if(!a|!G[a+32>>2]){break a}d=G[a+36>>2];if(!d){break a}b=G[a+28>>2];if(!b|G[b>>2]!=(a|0)|G[b+4>>2]-16180>>>0>31){break a}c=G[b+56>>2];if(c){Ja[d|0](G[a+40>>2],c);d=G[a+36>>2];b=G[a+28>>2]}Ja[d|0](G[a+40>>2],b);c=0;G[a+28>>2]=0}return c}function oo(a,b,c,d){var e=0,f=0;e=Fa-160|0;Fa=e;f=-1;G[e+148>>2]=b?b-1|0:0;a=b?a:e+158|0;G[e+144>>2]=a;e=cb(e,0,144);G[e+76>>2]=-1;G[e+36>>2]=3;G[e+80>>2]=-1;G[e+44>>2]=e+159;G[e+84>>2]=e+144;a:{if((b|0)<0){G[48624]=61;break a}E[a|0]=0;f=Lk(e,c,d,1,2)}Fa=e+160|0;return f}function We(a,b,c,d){var e=0,f=0,g=0;f=G[321389]+1|0;G[321389]=f;G[a>>2]=f;if(d){while(1){g=(e<<3)+c|0;if(!G[g>>2]){G[g>>2]=f;a=(e<<3)+c|0;G[a+4>>2]=b;G[a+8>>2]=0;_(d|0);return c}e=e+1|0;if((e|0)!=(d|0)){continue}break}}e=a;a=d<<1;b=We(e,b,ub(c,d<<4|8),a);_(a|0);return b}function bh(a){var b=0,c=0,d=0;A(+a);b=v(1)|0;v(0)|0;d=b>>>20&2047;if(d>>>0<=1074){if(d>>>0<=1021){return a*0}a=(b|0)>0|(b|0)>=0?a:-a;c=a+4503599627370496+-4503599627370496-a;a:{if(c>.5){a=a+c+-1;break a}a=a+c;if(!(c<=-.5)){break a}a=a+1}a=(b|0)>0|(b|0)>=0?a:-a}return a}function Ph(a){var b=0,c=0;c=G[a+12>>2];a:{if((c|0)>=G[a+16>>2]){c=0;b=ra(G[a+8>>2],a+24|0,2048)|0;if((b|0)<=0){a=0;if(!b|(b|0)==-44){break a}G[48624]=0-b;return 0}G[a+16>>2]=b}b=a+c|0;G[a+12>>2]=I[b+40>>1]+c;c=G[b+36>>2];G[a>>2]=G[b+32>>2];G[a+4>>2]=c;a=b+24|0}return a}function In(){var a=0,b=0,c=0;while(1){b=M(c,48);a=b+757232|0;G[a>>2]=0;G[a+4>>2]=0;a=b+757280|0;G[a>>2]=0;G[a+4>>2]=0;a=b+757328|0;G[a>>2]=0;G[a+4>>2]=0;a=b+757376|0;G[a>>2]=0;G[a+4>>2]=0;b=b+757424|0;G[b>>2]=0;G[b+4>>2]=0;c=c+5|0;if((c|0)!=1e4){continue}break}return 0}function wg(a,b){var c=0,d=0,e=0,f=0;c=Fa-16|0;Fa=c;a:{if(!b){b=0;break a}d=b;b=P(b);od(c,d,0,0,0,b+81|0);e=16414-b<<16;b=0;d=b+G[c+8>>2]|0;e=e+(G[c+12>>2]^65536)|0;e=b>>>0>d>>>0?e+1|0:e;f=d;d=G[c>>2];b=G[c+4>>2]}G[a>>2]=d;G[a+4>>2]=b;G[a+8>>2]=f;G[a+12>>2]=e;Fa=c+16|0}function ih(a,b,c){var d=0,e=0,f=0;d=a*a;f=d*(d*d)*(d*1.58969099521155e-10+-2.5050760253406863e-8)+(d*(d*27557313707070068e-22+-.0001984126982985795)+.00833333333332249);e=d*a;if(!c){return e*(d*f+-.16666666666666632)+a}return a-(d*(b*.5-f*e)-b+e*.16666666666666632)}function gc(a,b,c){var d=0,e=0,f=0;a:{if(!c){break a}while(1){d=E[a|0];e=(d-97>>>0<26?d&95:d)<<24;f=e>>24;d=E[b|0];d=(d-97>>>0<26?d&95:d)<<24>>24;if((f|0)<(d|0)){return-1}if((d|0)<(f|0)){return 1}if(!e){break a}b=b+1|0;a=a+1|0;c=c-1|0;if(c){continue}break}}return 0}function Lg(a,b,c){var d=0,e=0,f=0;a:{if(!b){d=a;break a}while(1){d=Du(a,b,10,0);f=Ia;e=Au(d,f,10,0);c=c-1|0;E[c|0]=a-e|48;e=b>>>0>9;a=d;b=f;if(e){continue}break}}if(d){while(1){c=c-1|0;a=(d>>>0)/10|0;E[c|0]=d-M(a,10)|48;b=d>>>0>9;d=a;if(b){continue}break}}return c}function Kq(){var a=0,b=0;a=Fa-16|0;Fa=a;a:{if(ya(a+12|0,a+8|0)|0){break a}b=ab((G[a+12>>2]<<2)+4|0);G[50361]=b;if(!b){break a}b=ab(G[a+8>>2]);if(b){G[G[50361]+(G[a+12>>2]<<2)>>2]=0;if(!(xa(G[50361],b|0)|0)){break a}}G[50361]=0}Fa=a+16|0;G[48787]=195036;G[48769]=42}function Dt(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;d=116;c=G[M(a,24)+202496>>2];a=fk(c);a:{if(a&-2147483648){break a}if(zf(c,0,0,2)){break a}e=fk(c);if(e&-2147483648){break a}f=c;c=a>>31;if(zf(f,a,c,0)){break a}c=b;b=e;a=b>>31;G[c>>2]=b;G[c+4>>2]=a;d=0}return d|0}function vh(a,b){var c=0,d=0,e=0;d=Fa-16|0;Fa=d;E[d+15|0]=b;c=G[a+16>>2];a:{if(!c){if(el(a)){break a}c=G[a+16>>2]}e=c;c=G[a+20>>2];if(!((e|0)==(c|0)|G[a+80>>2]==(b&255))){G[a+20>>2]=c+1;E[c|0]=b;break a}if((Ja[G[a+36>>2]](a,d+15|0,1)|0)!=1){break a}}Fa=d+16|0}function zi(a,b,c){var d=0,e=0;if(G[c>>2]<=0){a:{e=G[a>>2];d=G[a+4>>2];b:{if((e|0)!=G[d+76>>2]){mb(a,e+1|0,0,c);break b}if((G[d+128>>2]&G[d+132>>2])!=-1){break b}if((Rb(a,c)|0)>0){break a}}a=G[a+4>>2];if(!G[a+80>>2]){G[c>>2]=235;return}G[b>>2]=G[a+952>>2]}}}function pk(a,b,c){var d=0,e=0;if(G[c>>2]<=0){a:{e=G[a>>2];d=G[a+4>>2];b:{if((e|0)!=G[d+76>>2]){mb(a,e+1|0,0,c);break b}if((G[d+128>>2]&G[d+132>>2])!=-1){break b}if((Rb(a,c)|0)>0){break a}}a=G[a+4>>2];if(!G[a+80>>2]){G[c>>2]=235;return}G[b>>2]=G[a+936>>2]}}}function Tj(a){var b=0,c=0,d=0;b=Fa-32|0;Fa=b;a:{c=ab(48);if(c){G[c+12>>2]=16384;d=ab(16386);G[c+4>>2]=d;if(!d){break a}G[c+20>>2]=1;Sj(c,a);Fa=b+32|0;return c}G[b>>2]=63997;_a(G[24367],70017,b);ca(2);W()}G[b+16>>2]=63997;_a(G[24367],70017,b+16|0);ca(2);W()}function Cm(a,b,c){var d=0,e=0;d=Fa-32|0;Fa=d;G[d+8>>2]=0;G[d+12>>2]=0;G[d>>2]=0;G[d+4>>2]=0;G[d+24>>2]=0;G[d+28>>2]=0;G[d+16>>2]=0;G[d+20>>2]=0;Dj(a,b,d+8|0,d,d+24|0,d+16|0);e=c+-2e3;L[a>>3]=L[d+8>>3]*e+L[a>>3];L[b>>3]=L[d>>3]*e+L[b>>3];_g(a,b,c);Fa=d+32|0}function lq(a,b,c,d){var e=0,f=0;e=Fa-16|0;Fa=e;f=G[d>>2];a:{if((f|0)>0){break a}b:{if((Dc(a,e+12|0,d)|0)>0){break b}if(G[e+12>>2]){f=233;G[d>>2]=233;break a}if(Nb(a,d)){break b}a=G[G[a+4>>2]+968>>2];G[a+272>>2]=b;G[a+276>>2]=c}f=G[d>>2]}Fa=e+16|0;return f}function hh(a){return(a*(a*(a*(a*(a*3479331075960212e-20+.0007915349942898145)+-.04005553450067941)+.20121253213486293)+-.3255658186224009)+.16666666666666666)*a/(a*(a*(a*(a*.07703815055590194+-.6882839716054533)+2.0209457602335057)+-2.403394911734414)+1)}function mq(a,b){var c=0;c=Fa-16|0;Fa=c;a:{if(G[b>>2]>0){break a}b:{if((Dc(a,c+12|0,b)|0)>0){break b}if(G[c+12>>2]){G[b>>2]=233;break a}b=Nb(a,b);a=G[a+4>>2];if(b){L[a+1192>>3]=0;L[a+1184>>3]=1;break b}a=G[a+968>>2];L[a+264>>3]=0;L[a+256>>3]=1}}Fa=c+16|0}function Sl(a,b,c,d,e){var f=0,g=0,h=0;f=Fa-256|0;Fa=f;g=G[e>>2];a:{if((g|0)>0){break a}if((Vc(a,b,f+176|0,f+96|0,e)|0)<=0){h=f+176|0;ml(c,h,e);Ob(b,h,d?H[d|0]==38?f+96|0:d:f+96|0,f,e);Hd(a,f,e)}if(G[e>>2]!=202){break a}G[e>>2]=g;be(a,b,c,d,e)}Fa=f+256|0}function si(a){var b=0,c=0;b=G[a+72>>2];G[a+72>>2]=b-1|b;if(G[a+20>>2]!=G[a+28>>2]){Ja[G[a+36>>2]](a,0,0)|0}G[a+28>>2]=0;G[a+16>>2]=0;G[a+20>>2]=0;b=G[a>>2];if(b&4){G[a>>2]=b|32;return-1}c=G[a+44>>2]+G[a+48>>2]|0;G[a+8>>2]=c;G[a+4>>2]=c;return b<<27>>31}function Va(a){var b=0,c=0,d=0;b=a;a:{if(b&3){while(1){if(!H[b|0]){break a}b=b+1|0;if(b&3){continue}break}}while(1){c=b;b=b+4|0;d=G[c>>2];if(!((d^-1)&d-16843009&-2139062144)){continue}break}while(1){b=c;c=b+1|0;if(H[b|0]){continue}break}}return b-a|0}function te(a,b,c){var d=0,e=0,f=0,g=0;G[a+112>>2]=b;G[a+116>>2]=c;e=G[a+4>>2];d=G[a+44>>2]-e|0;G[a+120>>2]=d;G[a+124>>2]=d>>31;d=G[a+8>>2];a:{if(!(b|c)){break a}f=d-e|0;g=f>>31;if((c|0)>=(g|0)&b>>>0>=f>>>0|(c|0)>(g|0)){break a}d=b+e|0}G[a+104>>2]=d}function lr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0;a:{if(G[c+4>>2]!=503){f=1;if(uj(c)){break a}}g=L[c+128>>3]-b;b=V(a*a+g*g);b=L[c+40>>3]<0?-b:b;if(b!=0){a=Ac(a/b,g/b)}else{a=0}L[d>>3]=a*L[c+120>>3];L[e>>3]=L[c+136>>3]-b;f=0}return f|0}function Lp(a,b){var c=0,d=0,e=0;A(+a);d=v(1)|0;e=v(0)|0;c=d>>>20&2047;if((c|0)!=2047){if(!c){if(a==0){c=0}else{a=Lp(a*0x10000000000000000,b);c=G[b>>2]+-64|0}G[b>>2]=c;return a}G[b>>2]=c-1022;x(0,e|0);x(1,d&-2146435073|1071644672);a=+z()}return a}function Mc(a){var b=0,c=0;c=Fa-16|0;Fa=c;A(+a);b=v(1)|0;v(0)|0;b=b&2147483647;a:{if(b>>>0<=1072243195){if(b>>>0<1044381696){break a}a=An(a,0,0);break a}if(b>>>0>=2146435072){a=a-a;break a}b=$j(a,c);a=An(L[c>>3],L[c+8>>3],b&1)}Fa=c+16|0;return a}function Nb(a,b){var c=0,d=0;a:{if(G[b>>2]<=0){d=G[a>>2];c=G[a+4>>2];if((d|0)!=G[c+76>>2]){mb(a,d+1|0,0,b);break a}if((G[c+128>>2]&G[c+132>>2])!=-1){break a}if((Rb(a,b)|0)<=0){break a}a=G[b>>2]}else{a=0}return a}return G[G[a+4>>2]+1088>>2]!=0}function vn(a){var b=0,c=0;A(+a);b=v(1)|0;x(0,v(0)|0);b=b&2147483647;x(1,b|0);a=+z();a:{if(b>>>0<=1072049729){c=1;if(b>>>0<1045430272){break a}a=gh(a);c=a+1;return a*a/(c+c)+1}if(b>>>0<=1082535489){a=af(a);return(a+1/a)*.5}c=xn(a,1)}return c}function jh(a,b){var c=0,d=0,e=0,f=0;c=a*a;d=c*.5;e=1-d;f=1-e-d;d=c*c;return e+(f+(c*(c*(c*(c*2480158728947673e-20+-.001388888888887411)+.0416666666666666)+d*d*(c*(c*-11359647557788195e-27+2.087572321298175e-9)+-2.7557314351390663e-7))-a*b))}function pg(a,b,c,d){var e=0;e=Fa+-64|0;Fa=e;Am(a,b,e+32|0);Am(c,d,e);a=L[e+48>>3]-L[e+16>>3];b=a*a;a=L[e+40>>3]-L[e+8>>3];c=a*a;a=L[e+32>>3]-L[e>>3];a=Q((b+(c+(a*a+0)))*.25,1);a=Db(V(a),V(1-a));Fa=e- -64|0;return(a+a)*180/3.141592653589793}function nj(a){var b=0,c=0;b=Fa-16|0;Fa=b;c=nc(a,b+12|0,0);a:{b:{if((G[b+12>>2]-a|0)>=(Va(a)|0)){if((c|0)<0){break b}Fa=b+16|0;return c}G[b>>2]=a;_a(G[321435],85055,b);break a}hb(82684,66,1,G[321435])}$a(G[321435]);Hb(G[321435]);sc(1);W()}function ef(a,b,c){var d=0,e=0;d=G[a>>2];e=G[a+4>>2];if((d|0)!=G[e+76>>2]){mb(a,d+1|0,0,c);e=G[a+4>>2];d=G[e+76>>2]}a=M(b,80)-80|0;c=a;d=G[e+96>>2]+(d<<3)|0;b=a+G[d>>2]|0;a=G[d+4>>2]+(a>>31)|0;G[e+120>>2]=b;G[e+124>>2]=b>>>0>>0?a+1|0:a}function cu(a,b){a=a|0;b=b|0;var c=0;c=Fa-65552|0;Fa=c;G[c>>2]=42205;G[c+4>>2]=a;a=c+16|0;Ya(a,65535,8740,c);E[3809712]=0;a=ac(a,13287);if(a){b=b-1|0;b=zc(3809712,1,b>>>0<65534?b:65534,a);Hb(a);E[b+3809712|0]=0}Fa=c+65552|0;return 3809712}function ak(a,b){var c=0,d=0;a:{if((a|0)==-1){break a}d=G[b+76>>2]>=0;b:{c=G[b+4>>2];c:{if(!c){si(b);c=G[b+4>>2];if(!c){break c}}if(G[b+44>>2]-8>>>0>>0){break b}}if(!d){break a}return}c=c-1|0;G[b+4>>2]=c;E[c|0]=a;G[b>>2]=G[b>>2]&-17}}function on(a){var b=0,c=0,d=0;a:{if(G[309737]){break a}d=G[309722];b=d+M(a,344)|0;if(G[b>>2]<=0){break a}c=G[b+8>>2];while(1){if(c){c=c-1|0;on(G[((c<<2)+b|0)+12>>2]);if(!G[309737]){continue}break a}break}Ja[G[(M(a,344)+d|0)+4>>2]](b)}}function kq(a,b){var c=0,d=0,e=0,f=0;c=b>>>20&2047;a:{if(c>>>0<1023){break a}e=2;if(c>>>0>1075){break a}e=0;c=1075-c|0;d=c&31;if((c&63)>>>0>=32){c=1<>>32-d;d=f}if(a&d-1|b&c-!d){break a}e=a&d|b&c?1:2}return e}function fm(a,b,c){var d=0,e=0;d=Fa-16|0;Fa=d;a:{if(!(b&64)){e=0;if((b&4259840)!=4259840){break a}}G[d+12>>2]=c+4;e=G[c>>2]}G[d>>2]=e;G[d+4>>2]=0;a=ja(-100,a|0,b|32768,d|0)|0;if(a>>>0>=4294963201){G[48624]=0-a;a=-1}Fa=d+16|0;return a}function fb(a,b,c){var d=0,e=0,f=0;if(!c){return 0}d=H[a|0];a:{if(!d){break a}while(1){b:{e=H[b|0];if(!e){break b}c=c-1|0;if(!c|(d|0)!=(e|0)){break b}b=b+1|0;d=H[a+1|0];a=a+1|0;if(d){continue}break a}break}f=d}return(f&255)-H[b|0]|0}function Sg(a,b){var c=0,d=0;while(1){a:{b:{c:{c=Sb(b,16007);if(!c){c=Sb(b,34391);if(!c){break c}}d=c+4|0;break b}c=Sb(b,16008);if(!c){c=Sb(b,34392);if(!c){break a}}d=c+3|0}E[c|0]=0;fe(b,a);hb(65587,5,1,a);b=d;continue}break}fe(b,a)}function ml(a,b,c){var d=0,e=0;d=Fa-16|0;Fa=d;a:{if(G[c>>2]>0){break a}E[b|0]=0;L[d+8>>3]=a;G[d>>2]=0;if((Ya(b,71,19659,d)|0)<0){Ua(17928);G[c>>2]=402}e=jb(b,44);if(e){E[e|0]=46}if(!jb(b,78)){break a}Ua(35198);G[c>>2]=402}Fa=d+16|0}function Wo(a){var b=0,c=0,d=0;if(E[G[a>>2]]-48>>>0>=10){return 0}while(1){d=G[a>>2];c=-1;if(b>>>0<=214748364){c=E[d|0]-48|0;b=M(b,10);c=(c|0)>(2147483647-b|0)?-1:c+b|0}G[a>>2]=d+1;b=c;if(E[d+1|0]-48>>>0<10){continue}break}return b}function Vm(){var a=0,b=0,c=0;a=G[48624];a=I[((a>>>0>149?0:a)<<1)+143920>>1]+142088|0;b=G[47424];c=G[47440];if(H[4321]){hb(4321,Va(4321),1,189624);Ub(58,189624);Ub(32,189624)}hb(a,Va(a),1,189624);Ub(10,189624);G[47440]=c;G[47424]=b}function wf(a,b){var c=0,d=0;c=Fa-160|0;Fa=c;a:{if(!b){break a}d=c+128|0;uc(b,d);G[c+16>>2]=b;G[c+20>>2]=d;_a(a,69652,c+16|0);if(!ho(c+32|0)){break a}while(1){b=c+32|0;G[c>>2]=b;_a(a,70017,c);if(ho(b)){continue}break}}Fa=c+160|0}function ym(a,b,c){var d=0;d=Fa-112|0;Fa=d;a:{if((c|0)>0){G[d+80>>2]=c;c=d+104|0;db(c,18660,d+80|0);L[d+64>>3]=b;Eb(a,c,d- -64|0);break a}if(O(b)<2147483648){c=~~b}else{c=-2147483648}G[d+96>>2]=c;db(a,30633,d+96|0)}Fa=d+112|0}function Fc(a,b,c,d,e){var f=0,g=0;f=Fa-176|0;Fa=f;g=G[e>>2];if((g|0)<=0){E[f|0]=0;a:{if(d){E[d|0]=0;if(G[e>>2]>0){break a}}if((kc(a,b,f+80|0,e)|0)>0){break a}mc(f+80|0,f,d,e)}E[c|0]=0;fd(f,c,e);g=G[e>>2]}Fa=f+176|0;return g}function Bu(a,b,c,d){var e=0,f=0,g=0,h=0;f=b^d;g=f>>31;e=b>>31;a=a^e;h=a-e|0;e=(b^e)-((a>>>0>>0)+e|0)|0;a=d>>31;b=c^a;f=f>>31;a=Du(h,e,b-a|0,(a^d)-((a>>>0>b>>>0)+a|0)|0)^f;b=a-f|0;Ia=(g^Ia)-((a>>>0>>0)+g|0)|0;return b}function Hb(a){a=a|0;var b=0,c=0,d=0,e=0;d=$a(a);e=Ja[G[a+12>>2]](a)|0;if(!(E[a|0]&1)){b=G[a+52>>2];if(b){G[b+56>>2]=G[a+56>>2]}c=G[a+56>>2];if(c){G[c+52>>2]=b}if(G[48750]==(a|0)){G[48750]=c}Wa(G[a+96>>2]);Wa(a)}return d|e}function Dl(){var a=0,b=0;if(H[3780288]){if(!G[950330]){Lb()}a=Xb(Va(3780288)+1|0);Yb(3780288,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a)}a=G[(G[950332]+(G[950330]<<2)|0)-4>>2];G[a+8>>2]=G[a+8>>2]+1}function Mj(a,b,c){var d=0;d=G[c>>2];if((d|0)<=0){if(!a){G[c>>2]=115;return 115}if(G[G[a+4>>2]+16>>2]!=555){G[c>>2]=114;return 114}d=b;b=lb(1,8);G[d>>2]=b;a=G[a+4>>2];G[b+4>>2]=a;G[a+8>>2]=G[a+8>>2]+1;d=G[c>>2]}return d}function kr(a,b,c,d,e){a=+a;b=+b;c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0;a:{if(G[c+4>>2]!=503){f=1;if(uj(c)){break a}}b=L[c+136>>3]-b;a=L[c+112>>3]*a;g=d,h=b*Kb(a),L[g>>3]=h;g=e,h=L[c+128>>3]-b*Mb(a),L[g>>3]=h;f=0}return f|0}function po(a,b,c,d,e){var f=0,g=0;f=Fa-176|0;Fa=f;g=G[e>>2];if((g|0)<=0){E[f|0]=0;a:{if(d){E[d|0]=0;if(G[e>>2]>0){break a}}if((kc(a,b,f+80|0,e)|0)>0){break a}mc(f+80|0,f,d,e)}Wn(f,c,e);g=G[e>>2]}Fa=f+176|0;return g}function _f(a,b,c,d,e){var f=0,g=0;f=Fa-176|0;Fa=f;g=G[e>>2];if((g|0)<=0){E[f|0]=0;a:{if(d){E[d|0]=0;if(G[e>>2]>0){break a}}if((kc(a,b,f+80|0,e)|0)>0){break a}mc(f+80|0,f,d,e)}Ie(f,c,e);g=G[e>>2]}Fa=f+176|0;return g}function Ec(a,b,c,d,e){var f=0,g=0;f=Fa-176|0;Fa=f;g=G[e>>2];if((g|0)<=0){E[f|0]=0;a:{if(d){E[d|0]=0;if(G[e>>2]>0){break a}}if((kc(a,b,f+80|0,e)|0)>0){break a}mc(f+80|0,f,d,e)}lk(f,c,e);g=G[e>>2]}Fa=f+176|0;return g}function Au(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0;e=c>>>16|0;f=a>>>16|0;j=M(e,f);g=c&65535;h=a&65535;i=M(g,h);f=(i>>>16|0)+M(f,g)|0;e=(f&65535)+M(e,h)|0;Ia=(M(b,c)+j|0)+M(a,d)+(f>>>16)+(e>>>16)|0;return i&65535|e<<16}function hc(a){var b=0;b=Fa-32|0;Fa=b;if(G[321438]){G[b+16>>2]=a;_a(G[321467],70017,b+16|0);$a(G[321467]);G[321440]=G[321440]+1;Fa=b+32|0;return}G[b>>2]=a;_a(G[321435],80471,b);$a(G[321435]);Hb(G[321435]);sc(1);W()}function hd(a,b,c,d,e,f){var g=0;g=Fa-192|0;Fa=g;if(G[f>>2]<=0){G[g>>2]=c;G[g+4>>2]=d;E[g+112|0]=0;if((db(g+112|0,26741,g)|0)<0){Ua(17884);G[f>>2]=401}c=b;b=g+16|0;Ob(c,g+112|0,e,b,f);wb(a,b,f)}Fa=g+192|0}function Ol(a){var b=0,c=0,d=0,e=0;b=Fa-96|0;Fa=b;a=Jh(a,0,0);a:{if((Be(a,b+8|0)|0)<0){break a}d=ac(a,13287);if(!d){break a}c=G[b+48>>2];e=ab(c+1|0);c=zc(e,1,c,d);Hb(d);E[c+e|0]=0}Wa(a);Fa=b+96|0;return e}function nd(a,b,c,d,e){var f=0;f=Fa-256|0;Fa=f;if(!(e&73728|(c|0)<=(d|0))){d=c-d|0;c=d>>>0<256;cb(f,b&255,c?d:256);if(!c){while(1){gd(a,f,256);d=d-256|0;if(d>>>0>255){continue}break}}gd(a,f,d)}Fa=f+256|0}function zp(a,b,c,d,e,f,g,h,i){var j=0;j=Fa-16|0;Fa=j;a:{if(Nb(a,i)){G[j+8>>2]=f;Nc(a,30,b,c,d,e,1,j+8|0,g,0,h,i);break a}if(!(d|e)|G[i>>2]>0){break a}qe(a,2,1,0,b,c,d,e,1,1,f,g,j+15|0,h,i)}Fa=j+16|0}function pc(a,b){a=a|0;b=b|0;var c=0;a:{if(!a){a=G[48793];if(!a){break a}}c=Me(a,b)+a|0;if(!H[c|0]){G[48793]=0;return 0}a=qc(c,b)+c|0;if(H[a|0]){G[48793]=a+1;E[a|0]=0;return c|0}G[48793]=0}return c|0}function Wp(a,b,c,d,e,f,g,h,i){var j=0;j=Fa-16|0;Fa=j;a:{if(Nb(a,i)){G[j+8>>2]=f;Nc(a,31,b,c,d,e,1,j+8|0,g,0,h,i);break a}if(!(d|e)|G[i>>2]>0){break a}Ud(a,2,1,0,b,c,d,e,1,1,f,g,j+15|0,h,i)}Fa=j+16|0}function hl(a,b,c,d,e,f,g,h,i,j){var k=0;k=Fa-16|0;Fa=k;a:{if(Nb(a,j)){K[k+8>>2]=g;Nc(a,42,c,d,e,f,1,k+8|0,h,0,i,j);break a}ae(a,2,(b|0)>1?b:1,0,c,d,e,f,1,1,g,h,k+15|0,i,j)}Fa=k+16|0;return G[j>>2]}function wq(a,b){var c=0;if(!G[a+3312>>2]){return}c=G[a+3292>>2];G[a+3292>>2]=b;if(!(c|(b|0)!=1)){if(G[a+3288>>2]!=3){return}G[a+3288>>2]=6;return}if(!((c|0)!=1|b)&G[a+3288>>2]==5){G[a+3288>>2]=3}}function ct(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;a=M(a,48);d=a+757264|0;e=b>>>0<=J[d>>2];d=G[d+4>>2];if(e&(d|0)>=(c|0)|(c|0)<(d|0)){a=a+757256|0;G[a>>2]=b;G[a+4>>2]=c;a=0}else{a=107}return a|0}function Ad(a,b,c,d,e,f){var g=0,h=0;g=Fa-256|0;Fa=g;if(G[f>>2]<=0){if((Vc(a,b,g+176|0,g+96|0,f)|0)<=0){h=c;c=g+176|0;jl(h,d,c,f);Ob(b,c,e?H[e|0]==38?g+96|0:e:g+96|0,g,f);Hd(a,g,f)}}Fa=g+256|0}function wm(a,b,c,d){a:{if(!a){break a}b:{switch(b+2|0){case 0:E[a|0]=c;return;case 1:F[a>>1]=c;return;case 2:case 3:G[a>>2]=c;return;case 5:break b;default:break a}}G[a>>2]=c;G[a+4>>2]=d}}function el(a){var b=0;b=G[a+72>>2];G[a+72>>2]=b-1|b;b=G[a>>2];if(b&8){G[a>>2]=b|32;return-1}G[a+4>>2]=0;G[a+8>>2]=0;b=G[a+44>>2];G[a+28>>2]=b;G[a+20>>2]=b;G[a+16>>2]=b+G[a+48>>2];return 0}function Fj(a,b,c,d,e,f,g,h,i){var j=0;j=Fa-16|0;Fa=j;Zc(j,b,c,d,e,f,g,h,i^-2147483648);d=G[j>>2];c=G[j+4>>2];b=G[j+12>>2];G[a+8>>2]=G[j+8>>2];G[a+12>>2]=b;G[a>>2]=d;G[a+4>>2]=c;Fa=j+16|0}function Ac(a,b){var c=0;a:{b:{if(a==0){if(b>=0){break a}c=180;if(!(b<0)){break b}break a}if(b!=0){break b}c=90;if(a>0){break a}c=-90;if(a<0){break a}}c=Db(a,b)*57.29577951308232}return c}function qh(){var a=0,b=0,c=0,d=0;a=G[50359];if((a|0)>0){while(1){a:{b=a-1|0;d=G[(b<<2)+199296>>2];c=H[d|0];E[d|0]=0;if((c|0)==27){break a}c=a>>>0>1;a=b;if(c){continue}}break}G[50359]=b}}function kt(a){a=a|0;var b=0,c=0,d=0;a=M(a,48);b=a+757236|0;c=a+757264|0;if((hb(G[b>>2],1,G[c>>2],G[29763])|0)!=G[c>>2]){Ua(60171);d=106}Wa(G[b>>2]);G[a+757232>>2]=0;G[b>>2]=0;return d|0}function vk(a){var b=0;b=1;a:{switch(a-11|0){case 9:case 10:return 2;case 19:case 20:case 29:case 30:case 31:return 4;case 71:return 8;default:b=0;break;case 0:case 3:break a}}return b} -function ur(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0;e=G[a+84>>2];d=c+256|0;f=Vi(e,0,d);d=f?f-e|0:d;c=c>>>0>d>>>0?d:c;bb(b,e,c);b=e+d|0;G[a+84>>2]=b;G[a+8>>2]=b;G[a+4>>2]=c+e;return c|0}function Xa(a,b){var c=0,d=0;c=H[a|0];d=H[b|0];a:{if(!c|(c|0)!=(d|0)){break a}while(1){d=H[b+1|0];c=H[a+1|0];if(!c){break a}b=b+1|0;a=a+1|0;if((c|0)==(d|0)){continue}break}}return c-d|0}function Ab(a,b,c){var d=0,e=0;a:{if(!c){break a}while(1){e=G[(d<<3)+b>>2];if(!e){break a}if((a|0)==(e|0)){return G[((d<<3)+b|0)+4>>2]}d=d+1|0;if((d|0)!=(c|0)){continue}break}}return 0}function Xd(a){var b=0,c=0,d=0;c=G[925777];if((c|0)>0){d=G[925781];while(1){if(!Xa(a,G[(b<<2)+d>>2])){return G[G[925782]+(b<<2)>>2]}b=b+1|0;if((c|0)!=(b|0)){continue}break}}return 0}function _p(a,b,c,d,e,f,g,h,i,j){var k=0;k=Fa-16|0;Fa=k;a:{if(Nb(a,j)){G[k>>2]=f;G[k+4>>2]=g;Nc(a,81,b,c,d,e,1,k,h,0,i,j);break a}Se(a,2,1,0,b,c,d,e,1,1,f,g,h,k+15|0,i,j)}Fa=k+16|0}function Ek(a,b,c,d,e,f,g,h,i){var j=0;j=Fa-16|0;Fa=j;a:{if(Nb(a,i)){K[j+12>>2]=h;bd(a,42,c,d,e,f,1,g,j+12|0,i);break a}Dk(a,2,(b|0)>1?b:1,0,c,d,e,f,g,h,i)}Fa=j+16|0;return G[i>>2]}function Ap(a,b,c,d,e,f,g,h,i,j){var k=0;k=Fa-16|0;Fa=k;a:{if(Nb(a,j)){G[k>>2]=f;G[k+4>>2]=g;Nc(a,80,b,c,d,e,1,k,h,0,i,j);break a}hf(a,2,1,0,b,c,d,e,1,1,f,g,h,k+15|0,i,j)}Fa=k+16|0}function cf(a,b){var c=0,d=0;c=Fa-1040|0;Fa=c;d=G[b>>2];a:{if(d){break a}if(!ui(c,1025)){E[a|0]=0;Ua(61910);d=125;G[b>>2]=125;break a}bf(c,1025,a,b);d=G[b>>2]}Fa=c+1040|0;return d}function Yg(a){var b=0;a:{b:{if(a>=1){if(!(a+-1<1e-10)){break b}break a}b=90;if(a==0){break a}if(!(a<=-1)){break b}b=180;if(a+1>-1e-10){break a}}b=Sc(a)*57.29577951308232}return b}function Bc(a){var b=0;a:{b:{if(a<=-1){b=-90;if(!(a+1>-1e-10)){break b}break a}if(a==0){break a}if(!(a>=1)){break b}b=90;if(a+-1<1e-10){break a}}b=fc(a)*57.29577951308232}return b}function gg(a){var b=0,c=0;b=G[47404];c=a+3&-4;a=b+c|0;a:{if(a>>>0<=b>>>0?c:0){break a}if(a>>>0>Ka()<<16>>>0){if(!(Ea(a|0)|0)){break a}}G[47404]=a;return b}G[48624]=48;return-1}function Am(a,b,c){var d=0,e=0,f=0;b=b*3.141592653589793/180;e=c,f=ib(b)*1,L[e+16>>3]=f;a=a*3.141592653589793/180;d=ib(a);b=eb(b);L[c+8>>3]=b*(d*1);e=c,f=b*(eb(a)*1),L[e>>3]=f}function vd(a,b,c,d,e,f){var g=0;g=Fa-16|0;Fa=g;qk(a,b,c,g+8|0,g,f);a=G[f>>2];a:{if((a|0)>0){break a}if(d){G[d>>2]=G[g+8>>2]}if(!e){break a}G[e>>2]=G[g>>2]}Fa=g+16|0;return a}function pl(a,b,c,d){var e=0,f=0;e=Fa-256|0;Fa=e;f=G[d>>2];if((f|0)<=0){if((Vc(a,b,e+96|0,e+176|0,d)|0)<=0){Ob(c,e+96|0,e+176|0,e,d);Hd(a,e,d)}f=G[d>>2]}Fa=e+256|0;return f}function Pp(a,b,c,d,e,f,g,h,i){var j=0;j=Fa-16|0;Fa=j;a:{if(Nb(a,i)){F[j+12>>1]=f;Nc(a,21,b,c,d,e,1,j+12|0,g,0,h,i);break a}jf(a,2,1,0,b,c,d,e,1,1,f,g,j+15|0,h,i)}Fa=j+16|0}function Mb(a){var b=0,c=0;c=Yc(a,360);b=1;a:{if(c==0){break a}c=O(c);if(c==90){return 0}b=-1;if(c==180){break a}b=0;if(c==270){break a}b=eb(a*.017453292519943295)}return b}function Kp(a,b,c,d,e,f,g,h,i){var j=0;j=Fa-16|0;Fa=j;a:{if(Nb(a,i)){F[j+12>>1]=f;Nc(a,20,b,c,d,e,1,j+12|0,g,0,h,i);break a}Gf(a,2,1,0,b,c,d,e,1,1,f,g,j+15|0,h,i)}Fa=j+16|0}function wp(a,b,c,d,e,f,g,h,i){var j=0;j=Fa-16|0;Fa=j;a:{if(Nb(a,i)){E[j+14|0]=f;Nc(a,11,b,c,d,e,1,j+14|0,g,0,h,i);break a}Re(a,2,1,0,b,c,d,e,1,1,f,g,j+15|0,h,i)}Fa=j+16|0}function Fo(a,b,c,d,e,f,g,h,i){var j=0;j=Fa-16|0;Fa=j;a:{if(Nb(a,i)){E[j+14|0]=f;Nc(a,12,b,c,d,e,1,j+14|0,g,0,h,i);break a}Ef(a,2,1,0,b,c,d,e,1,1,f,g,j+15|0,h,i)}Fa=j+16|0}function cq(a,b,c,d,e,f,g,h,i){var j=0;j=Fa-16|0;Fa=j;a:{if(Nb(a,i)){G[j+8>>2]=f;Nc(a,41,b,c,d,e,1,j+8|0,g,0,h,i);break a}Ud(a,2,1,0,b,c,d,e,1,1,f,g,j+15|0,h,i)}Fa=j+16|0}function Fp(a,b,c,d,e,f,g,h,i){var j=0;j=Fa-16|0;Fa=j;a:{if(Nb(a,i)){G[j+8>>2]=f;Nc(a,40,b,c,d,e,1,j+8|0,g,0,h,i);break a}qe(a,2,1,0,b,c,d,e,1,1,f,g,j+15|0,h,i)}Fa=j+16|0}function Kb(a){var b=0,c=0;c=Yc(a+-90,360);b=1;a:{if(c==0){break a}if(c==90){return 0}b=-1;if(c==180){break a}b=0;if(c==270){break a}b=ib(a*.017453292519943295)}return b}function Jd(a,b,c,d,e){var f=0,g=0;f=Fa-256|0;Fa=f;if(G[e>>2]<=0){if((Vc(a,b,f+176|0,f+96|0,e)|0)<=0){g=d;d=f+176|0;If(c,g,d,e);Ob(b,d,f+96|0,f,e);Hd(a,f,e)}}Fa=f+256|0}function lb(a,b){a=a|0;b=b|0;var c=0,d=0;a:{if(!a){break a}c=Au(a,0,b,0);d=Ia;if((a|b)>>>0<65536){break a}c=d?-1:c}a=ab(c);if(!(!a|!(H[a-4|0]&3))){cb(a,0,c)}return a|0}function Xe(a){var b=0,c=0;b=Yc(a,360);a:{if(b==0|O(b)==180){break a}c=1;if(b==45|b==225){break a}c=-1;if(b==-135|b==-315){break a}c=Mc(a*.017453292519943295)}return c}function Hl(a){var b=0;if(!a){return 0}a:{if(G[a+12>>2]>=2){hb(72565,20,1,G[24367]);b=1;if(G[a+12>>2]>1){break a}}b=G[a+128>>2];if(!b){return 1}b=Ja[b|0](a)|0}return b}function qb(a,b,c){var d=0,e=0;d=Va(a)+a|0;a:{if(!c){break a}while(1){e=H[b|0];if(!e){break a}E[d|0]=e;d=d+1|0;b=b+1|0;c=c-1|0;if(c){continue}break}}E[d|0]=0;return a}function Zb(a,b,c,d){var e=0,f=0;e=Fa-16|0;Fa=e;c=E[c|0];a:{if((c|0)<=63){a=ob(a,b,d);break a}f=Za(e,b);b=f+Va(b)|0;E[b|0]=c;E[b+1|0]=0;a=ob(a,f,d)}Fa=e+16|0;return a}function Lj(a,b,c,d){b=Ja[G[(M(G[a+4>>2],84)+1240576|0)+76>>2]](G[a>>2],c,b)|0;if((b|0)!=107){if((b|0)<=0){return}Ua(38146);Ua(G[a+12>>2]);a=108}else{a=107}G[d>>2]=a}function Kc(a,b,c,d){var e=0,f=0;e=Fa-176|0;Fa=e;f=G[d>>2];if((f|0)<=0){E[e|0]=0;if((kc(a,b,e+80|0,d)|0)<=0){mc(e+80|0,e,0,d)}wi(e,c,d);f=G[d>>2]}Fa=e+176|0;return f}function jl(a,b,c,d){var e=0;e=Fa-16|0;Fa=e;a:{if(G[d>>2]>0){break a}E[c|0]=0;G[e>>2]=a;G[e+4>>2]=b;if((db(c,26741,e)|0)>=0){break a}Ua(17884);G[d>>2]=401}Fa=e+16|0}function gq(a,b,c,d,e,f,g,h,i){var j=0;j=Fa-16|0;Fa=j;a:{if(Nb(a,i)){L[j>>3]=f;Nc(a,82,b,c,d,e,1,j,g,0,h,i);break a}Id(a,2,1,0,b,c,d,e,1,1,f,g,j+15|0,h,i)}Fa=j+16|0}function Lm(a,b,c){var d=0,e=0;d=b;b=ab(2e3);a:{if(!Of(a,d,b)){break a}a=ci(b,5618);if(!a){break a}b:{if((Va(a)|0)<16){Za(c,a);break b}rb(c,a,15)}e=1}Wa(b);return e}function yb(a){a:{if((fe(a,189776)|0)<0){break a}b:{if(G[47464]==10){break b}a=G[47449];if((a|0)==G[47448]){break b}G[47449]=a+1;E[a|0]=10;break a}vh(189776,10)}}function ep(a){var b=0;b=G[a>>2]-1|0;b=E[(M(0-b&b,124511785)>>>27|0)+118560|0];if(!b){a=G[a+4>>2];a=E[(M(0-a&a,124511785)>>>27|0)+118560|0];b=a?a+32|0:0}return b}function Vc(a,b,c,d,e){var f=0,g=0;f=Fa-96|0;Fa=f;E[c|0]=0;if(d){E[d|0]=0}g=G[e>>2];if((g|0)<=0){if((kc(a,b,f,e)|0)<=0){mc(f,c,d,e)}g=G[e>>2]}Fa=f+96|0;return g}function Pb(a){var b=0,c=0,d=0;c=G[925783];if((c|0)>0){d=G[925773];while(1){if(!Xa(M(b,4108)+d|0,a)){return b}b=b+1|0;if((c|0)!=(b|0)){continue}break}}return-1}function Po(a,b,c,d,e,f,g){var h=0;h=Fa-16|0;Fa=h;a:{if(Nb(a,g)){bd(a,30,b,c,d,e,0,f,h+12|0,g);break a}if(G[g>>2]>0){break a}Qe(a,2,1,0,b,c,d,e,f,g)}Fa=h+16|0}function Fk(a,b,c,d,e,f,g){var h=0;h=Fa-16|0;Fa=h;a:{if(Nb(a,g)){bd(a,31,b,c,d,e,0,f,h+12|0,g);break a}if(G[g>>2]>0){break a}xe(a,2,1,0,b,c,d,e,f,g)}Fa=h+16|0}function Xg(a,b,c,d){var e=0;e=Fa-16|0;Fa=e;a=qa(a|0,b|0,c|0,d&255,e+8|0)|0;if(a){G[48624]=a;a=-1}else{a=0}Fa=e+16|0;Ia=a?-1:G[e+12>>2];return a?-1:G[e+8>>2]}function ql(a,b,c){var d=0;d=Fa-16|0;Fa=d;G[d+12>>2]=c;G[d+8>>2]=b;a=ha(a|0,d+8|0,1,d+4|0)|0;if(a){G[48624]=a;a=-1}else{a=0}Fa=d+16|0;return a?-1:G[d+4>>2]}function lg(a,b,c){var d=0;d=Fa-16|0;Fa=d;G[d+12>>2]=c;G[d+8>>2]=b;a=ga(a|0,d+8|0,1,d+4|0)|0;if(a){G[48624]=a;a=-1}else{a=0}Fa=d+16|0;return a?-1:G[d+4>>2]}function Te(a){var b=0;if(!(!a|!H[a|0])){if(!G[950330]){Lb()}b=a;a=Xb(Va(a)+1|0);Yb(b,a);b=G[(G[950332]+(G[950330]<<2)|0)-4>>2];Bb(a,b+24|0,b+12|0);pb(a)}}function Fh(a,b,c,d,e,f){var g=0,h=0;g=Fa-176|0;Fa=g;h=G[f>>2];if((h|0)<=0){h=c;c=g+96|0;jl(h,d,c,f);Ob(b,c,e,g,f);vl(a,g,f);h=G[f>>2]}Fa=g+176|0;return h}function Kj(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;d=Fa-16|0;Fa=d;Rc(d+12|0,a,b,f);b=0;if(!G[f>>2]){b=Um(G[d+12>>2],c,e,f)}Fa=d+16|0;return b|0}function Et(a,b,c){a=a|0;b=b|0;c=c|0;var d=0;d=M(a,24);a=b;if(zf(G[d+202496>>2],a,a>>31,0)){a=116}else{a=d+202504|0;G[a>>2]=b;G[a+4>>2]=c;a=0}return a|0}function Zo(a,b,c,d,e,f,g,h){var i=0;i=Fa-16|0;Fa=i;a:{if(Nb(a,h)){L[i+8>>3]=g;bd(a,82,b,c,d,e,1,f,i+8|0,h);break a}Hk(a,2,1,0,b,c,d,e,f,g,h)}Fa=i+16|0}function Ue(a){var b=0;b=0;a:{if(!G[925765]){break a}b=1;if(G[925783]<=(a|0)){break a}a=G[925773]+M(a,4108)|0;b=!Xa(G[a+4096>>2],a+3072|0)}return b}function vu(a){a=a|0;var b=0,c=0;if((a|0)<0|G[47759]<=(a|0)){a=b}else{b=M(a,65544);c=G[b+G[968817]>>2];if(c){Ce(c);G[b+G[968817]>>2]=0}}return a|0}function cj(){var a=0;a=G[935824];if((a|0)<=0){hb(72586,38,1,G[24367]);return}a=G[(a<<2)+3743308>>2];bb(3743040,a,256);pb(a);G[935824]=G[935824]-1}function Cu(a,b){var c=0;c=b>>31;a=a^c;zu(a-c|0,(b^c)-((a>>>0>>0)+c|0)|0,2880,0);Ia=Ha;a=c^Ga;b=a-c|0;Ia=(c^Ia)-((a>>>0>>0)+c|0)|0;return b}function Ag(a){var b=0,c=0;b=Fa-16|0;Fa=b;c=-1;a:{if(si(a)){break a}if((Ja[G[a+32>>2]](a,b+15|0,1)|0)!=1){break a}c=H[b+15|0]}Fa=b+16|0;return c}function sq(){var a=0,b=0,c=0;if(L[24400]==0){b=195200,c=+fa(),L[b>>3]=c}a=(+fa()-L[24400])*1e3;if(O(a)<2147483648){return~~a}return-2147483648}function nm(a,b,c,d){a:{if((fe(a,189624)|0)<0){break a}if(!hb(b,Va(b),1,189624)){break a}if((hb(c,1,d,189624)|0)!=(d|0)){break a}Ub(10,189624)}}function hb(a,b,c,d){var e=0;e=M(b,c);a:{if(G[d+76>>2]<0){a=Qk(a,e,d);break a}a=Qk(a,e,d)}if((e|0)==(a|0)){return b?c:0}return(a>>>0)/(b>>>0)|0}function ie(a,b,c,d){a=Ye(a,b);if(!a){return 0}if((Va(a)|0)<(c|0)){Za(d,a);return 1}if((c|0)>=2){rb(d,a,c-1|0);return 1}E[d|0]=H[a|0];return 1}function Yf(a){var b=0,c=0,d=0,e=0;d=Va(a);if(d){while(1){e=a+b|0;c=E[e|0];E[e|0]=c-97>>>0<26?c&95:c;b=b+1|0;if((d|0)!=(b|0)){continue}break}}}function Rl(a){var b=0;b=H[a|0];if(b){while(1){b=b<<24>>24;if(b-65>>>0<26){E[a|0]=b-65>>>0<26?b|32:b}b=H[a+1|0];a=a+1|0;if(b){continue}break}}}function Vj(a){var b=0,c=0;b=Fa-32|0;Fa=b;a=na(a|0,b+8|0)|0;a:{if(!a){a=59;c=1;if(H[b+8|0]==2){break a}}G[48624]=a;c=0}a=c;Fa=b+32|0;return a}function Uf(a,b){var c=0,d=0;c=Va(a)+1|0;d=b&255;while(1){a:{b=0;if(!c){break a}c=c-1|0;b=c+a|0;if((d|0)!=H[b|0]){continue}}break}return b}function Cq(a,b){var c=0,d=0,e=0,f=0;c=256;while(1){e=c+d>>1;f=G[(e<<2)+b>>2]>(a|0);c=f?e:c;d=f?d:e;if((c-d|0)!=1){continue}break}return d}function zd(a){var b=0,c=0;b=Fa-16|0;Fa=b;G[b+4>>2]=41606;G[b>>2]=a;c=G[24367];_a(c,91416,b);if((a|0)==1007){hb(90359,1056,1,c)}ca(3);W()}function Yo(a,b,c,d,e,f,g){var h=0;h=Fa-16|0;Fa=h;a:{if(Nb(a,g)){bd(a,12,b,c,d,e,0,f,h+15|0,g);break a}Bh(a,2,1,0,b,c,d,e,f,g)}Fa=h+16|0}function Vo(a,b,c,d,e,f,g){var h=0;h=Fa-16|0;Fa=h;a:{if(Nb(a,g)){bd(a,20,b,c,d,e,0,f,h+14|0,g);break a}Ah(a,2,1,0,b,c,d,e,f,g)}Fa=h+16|0}function To(a,b,c,d,e,f,g){var h=0;h=Fa-16|0;Fa=h;a:{if(Nb(a,g)){bd(a,40,b,c,d,e,0,f,h+12|0,g);break a}Qe(a,2,1,0,b,c,d,e,f,g)}Fa=h+16|0}function Sk(a,b,c,d,e,f,g){var h=0;h=Fa-16|0;Fa=h;a:{if(Nb(a,g)){bd(a,11,b,c,d,e,0,f,h+15|0,g);break a}pe(a,2,1,0,b,c,d,e,f,g)}Fa=h+16|0}function Rk(a,b,c,d,e,f,g){var h=0;h=Fa-16|0;Fa=h;a:{if(Nb(a,g)){bd(a,21,b,c,d,e,0,f,h+14|0,g);break a}Ng(a,2,1,0,b,c,d,e,f,g)}Fa=h+16|0}function Mo(a,b,c,d,e,f,g){var h=0;h=Fa-16|0;Fa=h;a:{if(Nb(a,g)){bd(a,41,b,c,d,e,0,f,h+12|0,g);break a}xe(a,2,1,0,b,c,d,e,f,g)}Fa=h+16|0}function Ho(a,b,c,d,e,f,g){var h=0;h=Fa-16|0;Fa=h;a:{if(Nb(a,g)){bd(a,42,b,c,d,e,0,f,h+12|0,g);break a}Kg(a,2,1,0,b,c,d,e,f,g)}Fa=h+16|0}function _o(a,b,c,d,e,f,g){var h=0;h=Fa-16|0;Fa=h;a:{if(Nb(a,g)){bd(a,82,b,c,d,e,0,f,h+8|0,g);break a}Ff(a,2,1,0,b,c,d,e,f,g)}Fa=h+16|0}function Kt(a,b){a=a|0;b=b|0;var c=0,d=0,e=0;c=b;b=G[b>>2]+7&-8;G[c>>2]=b+16;d=a,e=Ui(G[b>>2],G[b+4>>2],G[b+8>>2],G[b+12>>2]),L[d>>3]=e}function Pi(a,b){var c=0,d=0;a:{if(b>>>0<=31){d=G[a+4>>2];c=a;break a}b=b-32|0;c=a+4|0}c=G[c>>2];G[a+4>>2]=d>>>b;G[a>>2]=d<<32-b|c>>>b}function Ni(a,b){var c=0,d=0;a:{if(b>>>0<=31){d=G[a>>2];c=a+4|0;break a}b=b-32|0;c=a}c=G[c>>2];G[a>>2]=d<>2]=c<>>32-b}function an(a){var b=0;b=G[310142];while(1){if((b|0)<=0){return}b=b-1|0;if(Xa(M(b,84)+1240576|0,42101)){continue}break}G[a>>2]=b}function ll(a,b,c,d,e,f){var g=0,h=0;g=Fa-176|0;Fa=g;if(G[f>>2]<=0){h=d;d=g+96|0;If(c,h,d,f);Ob(b,d,e,g,f);wb(a,g,f)}Fa=g+176|0}function fi(a,b,c,d){if(!(Ja[G[(M(G[a+4>>2],84)+1240576|0)+80>>2]](G[a>>2],c,b)|0)){return}Ua(38001);Ua(G[a+12>>2]);G[d>>2]=106}function Qg(a,b,c,d,e,f){var g=0,h=0;g=Fa-176|0;Fa=g;if(G[f>>2]<=0){h=d;d=g+96|0;hg(c,h,d,f);Ob(b,d,e,g,f);wb(a,g,f)}Fa=g+176|0}function De(a){var b=0;b=-45;a:{if(a==-1){break a}b=0;if(a==0){break a}b=45;if(a==1){break a}b=Pd(a)*57.29577951308232}return b}function lf(a,b){a:{b:{if(!a){a=ab(b);if(a){break b}break a}a=ub(a,b);if(a){break b}break a}return a}lg(1,88508,38);sc(1);W()}function kd(a,b,c){var d=0,e=0,f=0;d=Fa-32|0;Fa=d;a=ci(a,b);if(a){e=c,f=sb(Za(d,a)),L[e>>3]=f;a=1}else{a=0}Fa=d+32|0;return a}function vq(a,b,c,d,e){var f=0,g=0;f=Fa-176|0;Fa=f;if(G[e>>2]<=0){g=c;c=f+96|0;kl(g,c,e);Ob(b,c,d,f,e);vl(a,f,e)}Fa=f+176|0}function Hf(a,b,c,d,e,f,g,h,i,j,k,l){var m=0;m=Fa-16|0;Fa=m;Id(a,b,c,d,e,f,g,h,1,1,i,j,m+15|0,k,l);Fa=m+16|0;return G[l>>2]}function Ae(a){var b=0;b=Fa-16|0;Fa=b;G[b>>2]=a;_a(G[321435],83707,b);$a(G[321435]);$a(G[321435]);Hb(G[321435]);sc(1);W()}function Rg(a,b,c,d,e){var f=0;f=Fa-176|0;Fa=f;if(G[e>>2]<=0){F[f+96>>1]=c?84:70;Ob(b,f+96|0,d,f,e);wb(a,f,e)}Fa=f+176|0}function be(a,b,c,d,e){var f=0,g=0;f=Fa-176|0;Fa=f;if(G[e>>2]<=0){g=f+96|0;ml(c,g,e);Ob(b,g,d,f,e);wb(a,f,e)}Fa=f+176|0}function Cs(a,b,c,d,e,f,g,h,i,j,k){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;Ze(a,0,c,d,e,h,i,j,k)}function Bs(a,b,c,d,e,f,g,h,i,j,k){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;h=+h;i=+i;j=+j;k=+k;Ze(a,1,c,d,e,h,i,j,k)}function Ya(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=Fa-16|0;Fa=e;G[e+12>>2]=d;a=oo(a,b,c,d);Fa=e+16|0;return a|0}function Tm(a,b,c,d,e,f,g,h,i){G[a>>2]=b;G[a+4>>2]=c;G[a+8>>2]=d;G[a+12>>2]=e&65535|(i>>>16&32768|e>>>16&32767)<<16}function Wc(a){var b=0,c=0;c=+fa()/1e3;a:{if(O(c)<2147483648){b=~~c;break a}b=-2147483648}if(a){G[a>>2]=b}return b}function Df(a,b,c,d,e,f,g,h){var i=0;i=Fa-16|0;Fa=i;xh(a,b,c,d,1,0,1,0,1,e,f,i+14|0,g,h);Fa=i+16|0;return G[h>>2]} -function Zk(a,b,c,d,e,f,g){var h=0;h=Fa-16|0;Fa=h;Ud(a,b,c,d,1,0,1,0,1,1,0,e,h+15|0,f,g);Fa=h+16|0;return G[g>>2]}function Up(a,b,c,d,e,f,g){var h=0;h=Fa-16|0;Fa=h;if(G[g>>2]<=0){Ud(a,b,c,d,1,0,1,0,1,1,0,e,h+15|0,f,g)}Fa=h+16|0}function em(a){var b=0;a=fm(a,589824,0);if((a|0)>=0){b=lb(1,2072);if(!b){da(a|0)|0;return 0}G[b+8>>2]=a}return b}function Fs(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=+f;g=+g;if(!d){return 0}if(b){G[a+12>>2]=b}return 1}function wc(a){var b=0;b=Fa-80|0;Fa=b;if(!G[309737]){G[309737]=431}a=rb(b,a,80);E[a+79|0]=0;Ua(a);Fa=b+80|0}function st(a,b,c){a=a|0;b=b|0;c=c|0;if((a|0)==1){a=(zc(b,1,c,G[30060])|0)==(c|0)?0:107}else{a=1}return a|0}function rt(a,b,c){a=a|0;b=b|0;c=c|0;if((a|0)==2){a=(hb(b,1,c,G[29763])|0)==(c|0)?0:106}else{a=1}return a|0}function lj(a){var b=0;b=Fa-16|0;Fa=b;G[b>>2]=a;_a(G[321435],80471,b);$a(G[321435]);Hb(G[321435]);sc(1);W()}function Nq(a){a=a|0;var b=0;a:{if(!a){break a}a=G[a+160>>2];if(!a){break a}b=(Xa(a,64156)|0)!=0}return b|0}function Gl(a,b,c,d,e){var f=0;f=G[e>>2];if((f|0)<=0){if((gj(a,b,c,d,e)|0)==202){G[e>>2]=f;lc(a,b,c,d,e)}}}function ft(a,b){a=a|0;b=b|0;var c=0;a=M(a,48)+757264|0;c=G[a+4>>2];G[b>>2]=G[a>>2];G[b+4>>2]=c;return 0}function ek(a){var b=0;a=fk(a);b=Ia;if((b|0)>=0&a>>>0>=2147483648|(b|0)>0){G[48624]=61;return-1}return a}function Ed(a){var b=0;b=la(-100,a|0,0)|0;if((b|0)==-31){b=va(a|0)|0}if(b>>>0>=4294963201){G[48624]=0-b}}function lm(a){if(G[a+76>>2]>=0){vi(a,0,0,0);G[a>>2]=G[a>>2]&-33;return}vi(a,0,0,0);G[a>>2]=G[a>>2]&-33}function sf(a,b,c){a=ci(a,b);if(!a){return 0}if((Va(a)|0)<2e3){Za(c,a);return 1}rb(c,a,1999);return 1}function Lc(a){var b=0;if(!a){return 0}b=ab(Va(a)+1|0);if(b){return Za(b,a)}lg(1,88508,38);sc(1);W()}function gk(a){if(G[a+76>>2]<0){a=G[a+60>>2]}else{a=G[a+60>>2]}if((a|0)<0){G[48624]=8;a=-1}return a}function _c(a,b,c,d,e){Ge(d,b);if((c|0)==8){c=a;a=b<<3;Wb(c,a,a>>31,d,e);return}wd(a,8,b,c-8|0,d,e)}function Oe(a,b,c,d,e){Af(d,b);if((c|0)==2){c=a;a=b<<1;Wb(c,a,a>>31,d,e);return}wd(a,2,b,c-2|0,d,e)}function Eh(a,b,c,d,e,f,g,h,i,j,k,l,m,n){if(!(!(g|h)|G[n>>2]>0)){Ud(a,b,c,d,e,f,g,h,1,i,j,k,l,m,n)}}function Dh(a,b,c,d,e,f,g,h,i,j,k,l,m,n){if(!(!(g|h)|G[n>>2]>0)){qe(a,b,c,d,e,f,g,h,1,i,j,k,l,m,n)}}function $c(a,b,c,d,e){ke(d,b);if((c|0)==4){c=a;a=b<<2;Wb(c,a,a>>31,d,e);return}wd(a,4,b,c-4|0,d,e)}function Be(a,b){a=a|0;b=b|0;a=sa(a|0,b|0)|0;if(a>>>0>=4294963201){G[48624]=0-a;a=-1}return a|0}function xn(a,b){return b*2247116418577895e292*af(a+-1416.0996898839683)*2247116418577895e292}function Vg(a){a=a|0;a=la(-100,a|0,0)|0;if(a>>>0>=4294963201){G[48624]=0-a;a=-1}return a|0} -function Ro(a,b,c,d,e,f,g){if(Nb(a,g)){Ua(28105);G[g>>2]=413;return}zh(a,2,1,0,b,c,d,e,f,g)}function On(a){a=a|0;a=M(a,24)+202496|0;if(Hb(G[a>>2])){a=110}else{G[a>>2]=0;a=0}return a|0}function It(a,b){a=a|0;b=b|0;var c=0;c=G[b>>2];if(!(!a|(c|0)>0)){Wa(a);c=G[b>>2]}return c|0}function Gk(a,b,c,d,e,f,g){if(Nb(a,g)){Ua(28161);G[g>>2]=413;return}yh(a,2,1,0,b,c,d,e,f,g)}function xi(a,b,c){var d=0;d=G[c>>2];if((d|0)<=0){mb(a,G[a>>2]+2|0,b,c);d=G[c>>2]}return d}function rq(a){tq();Ba(a|0,195256);G[48824]=G[(G[48822]?195192:195188)>>2];return 195256}function it(a){a=a|0;a=M(a,48)+757232|0;Wa(G[G[a>>2]>>2]);G[a>>2]=0;G[a+4>>2]=0;return 0}function le(a){a=a|0;var b=0,c=0;b=Va(a)+1|0;c=ab(b);if(!c){return 0}return bb(c,a,b)|0}function bm(a,b){var c=0;c=$b(10,+(b|0));if(a<0){return T(a*c+-.5)/c}return S(a*c+.5)/c}function Eu(a,b){var c=0,d=0;c=b&31;d=(-1>>>c&a)<>>a}function dc(a,b,c,d,e){var f=0;f=Fa-80|0;Fa=f;fo(a,b,c,f,d,e);Fa=f+80|0;return G[e>>2]}function ol(a){tq();Aa(a|0,195212);G[48813]=33340;G[48811]=0;G[48812]=0;return 195212}function tg(a){if(a){Wa(G[a+4>>2]);Wa(G[a>>2]);Wa(G[a+20>>2]);Wa(G[a+12>>2]);Wa(a)}}function rd(a){var b=0;b=Fa-16|0;Fa=b;E[b+15|0]=0;a=qj(a,b+15|0);Fa=b+16|0;return a}function fj(a){a=da(a|0)|0;a=(a|0)==27?0:a;if(a){G[48624]=a;a=-1}else{a=0}return a}function Mt(a,b){a=a|0;b=b|0;var c=0,d=0;c=L[a>>3];d=L[b>>3];return(cd)|0}function we(a,b,c,d,e){if((c|0)==1){Wb(a,b,b>>31,d,e);return}wd(a,1,b,c-1|0,d,e)}function Rc(a,b,c,d){var e=0;e=Fa-32|0;Fa=e;ch(a,b,c,d);Fa=e+32|0;return G[d>>2]}function qd(a){var b=0;b=Fa-16|0;Fa=b;G[b>>2]=a;_a(G[24367],70017,b);sc(2);W()}function bi(a,b){if((b|0)<=0){G[321300]=0;b=(Pc(a,35790)-a|0)+80|0}G[321300]=b}function $q(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;a=Xg(G[a+60>>2],b,c,d);return a|0}function kb(a,b){var c=0;c=Fa-16|0;Fa=c;G[c+12>>2]=b;Ak(189776,a,b);Fa=c+16|0}function gb(a,b){var c=0;c=Fa-16|0;Fa=c;G[c+12>>2]=b;zk(189776,a,b);Fa=c+16|0}function zf(a,b,c,d){if(G[a+76>>2]<0){return vi(a,b,c,d)}return vi(a,b,c,d)}function xb(a,b,c){var d=0;d=Fa-16|0;Fa=d;G[d+12>>2]=c;zk(a,b,c);Fa=d+16|0}function _a(a,b,c){var d=0;d=Fa-16|0;Fa=d;G[d+12>>2]=c;Ak(a,b,c);Fa=d+16|0}function eo(a,b,c,d){var e=0;e=Fa-16|0;Fa=e;co(a,b,c,e+8|0,e,d);Fa=e+16|0}function Ym(a,b,c){Za(b,M(G[G[a+4>>2]+4>>2],84)+1240576|0);return G[c>>2]}function Jo(a,b,c,d,e,f,g,h,i,j){if(G[j>>2]<=0){xe(a,b,c,d,e,f,g,h,i,j)}}function fe(a,b){var c=0;c=a;a=Va(a);return(hb(c,1,a,b)|0)!=(a|0)?-1:0}function et(a){a=a|0;a=M(a,48)+757232|0;G[a>>2]=0;G[a+4>>2]=0;return 0}function vt(a,b){a=a|0;b=b|0;G[b>>2]=2147483647;G[b+4>>2]=0;return 0}function Zq(a,b){a=a|0;b=b|0;if(!G[321387]){G[321388]=b;G[321387]=a}}function Ks(a){a=a|0;var b=0;b=G[47542];if(a){G[47542]=a}return b|0}function Ic(a,b){a=lb(a,b);if(!a){lg(1,88508,38);sc(1);W()}return a}function fk(a){if(G[a+76>>2]<0){a=Sn(a);return a}a=Sn(a);return a}function Xb(a){a=ab(a);if(!a){lg(1,88508,38);sc(1);W()}return a}function Gt(a,b){a=a|0;b=b|0;a=G[a>>2]+1|0;G[b>>2]=a;return a|0}function Bt(a){a=a|0;return($a(G[M(a,24)+202496>>2])?106:0)|0}function rl(a,b,c,d){if(G[d>>2]<=0){ef(a,b+1|0,d);Hd(a,c,d)}}function Xq(a,b){a=a|0;b=b|0;return(K[a>>2]<=K[b>>2]?-1:1)|0}function Ve(a,b){if(!G[321387]){G[321388]=b;G[321387]=a}ua()}function io(a,b,c){Za(b,G[G[a+4>>2]+12>>2]);return G[c>>2]}function Jt(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;Ia=0;return 0}function Gh(){yl(G[952413],G[952414],G[952415],G[952416])}function op(a,b,c){a=a|0;b=b|0;c=c|0;return ab(M(b,c))|0}function xt(a,b,c){a=a|0;b=b|0;c=c|0;G[c>>2]=1;return 0}function ut(a){a=a|0;if((a|0)==2){$a(G[29763])}return 0}function jt(a,b,c){a=a|0;b=b|0;c=c|0;return Gn(a,0,c)|0}function jb(a,b){a=Gg(a,b);return H[a|0]==(b&255)?a:0}function Gu(a){if(a){return 31-P(a-1^a)|0}return 32} -function Fn(a,b){a=ti(a,b,10,0,-2147483648);return a}function Ih(a){a=qc(a,36372)+a|0;return H[a|0]?a:0}function nc(a,b,c){return ti(a,b,c,-2147483648,0)}function Bd(a,b,c,d,e,f){pf(a,b,c,a+3912|0,d,e,f)}function wt(a,b){a=a|0;b=b|0;G[b>>2]=2;return 0}function Zt(a){a=a|0;a=Fa-a&-16;Fa=a;return a|0}function qt(a){a=a|0;return(a|0)==32|a-9>>>0<5}function gd(a,b,c){if(!(H[a|0]&32)){Qk(b,c,a)}}function Qh(){var a=0;a=G[925769];if(a){Hb(a)}}function tt(a,b,c){a=a|0;b=b|0;c=c|0;return 1}function Uq(a){a=a|0;return da(G[a+60>>2])|0}function Du(a,b,c,d){a=zu(a,b,c,d);return a}function Yt(a,b){a=a|0;b=b|0;if(b){Wa(b)}}function He(a,b,c){return zf(a,b,b>>31,c)}function Gb(a,b){Za(Va(a)+a|0,b);return a}function Pn(a){a=a|0;G[a>>2]=10;return 0}function Qn(a){a=a|0;G[a>>2]=0;return 0}function Ak(a,b,c){return Lk(a,b,c,0,0)}function tq(){Ca(195180,195184,195188)}function ug(a,b){return ec(a,b,Va(a))}function kg(a){a=a|0;return(a|0)!=0|0}function sc(a){Ve(1285568,a?a:1);W()}function _e(a,b){a=a|0;b=b|0;Qb(a,b)}function Ct(a){a=a|0;Ed(a);return 0}function _l(a){fj(G[a+8>>2]);Wa(a)}function Pt(a,b){a=a|0;b=b|0;Wa(b)}function pu(a){a=a|0;return+oj(a)}function zk(a,b,c){Lk(a,b,c,1,0)}function nu(){return G[321386]}function Fu(a,b){Ia=a;return b}function sb(a){return vb(a,0)}function Gi(a){a=a|0;return 0}function jd(a){Za(1285424,a)}function yu(){return 194496}function pb(a){if(a){Wa(a)}}function _t(a){a=a|0;Fa=a}function $t(){return Fa|0}function Ua(a){tb(5,a)}function $p(){return 0}function rh(){tb(6,0)} -// EMSCRIPTEN_END_FUNCS -e=H;p(Sa);var Ja=c([null,Lt,Kt,Ht,ur,$q,_q,Wq,Uq,op,Pt,jp,Ot,Nt,Mt,Gi,Jt,ub,Nn,$s,_s,Zs,Ys,Xs,sn,rn,qn,Ws,Vs,Us,Ss,Rs,Qs,Ts,Ps,Os,Ns,Ms,bk,At,Et,Bt,Dt,Ct,On,Ft,ck,dk,yt,Pn,Qn,Gi,$p,Rn,at,bt,ct,ft,it,nt,pt,Pn,Qn,Gi,$p,In,et,lt,mt,kt,ht,gt,Gn,jt,zt,ot,dt,xt,wt,Gi,vt,ut,tt,st,rt,es,ds,cs,bs,as,$r,_r,Zr,Yr,Xr,Wr,Vr,Ur,Tr,Sr,Rr,Qr,Pr,Or,Nr,Mr,Lr,Kr,Jr,Ir,Hr,Gr,Fr,Er,Dr,Cr,Br,Ar,zr,yr,xr,wr,vr,tr,sr,rr,qr,pr,or,nr,mr,lr,kr,jr,ir,hr,gr,fr,er,dr,cr,br,ar,Xq,Pq,kg,kg,kg,kg,Nq,kg,kg,Mq,Lq,Gh,Yq,Ya,qt,le,pc,rb,Vq,ac,zc,Hb,Vg,Tq,Sq,Qq,Oq,Rq,xu,Be,lb,op,Yt]);function Ka(){return D.byteLength/65536|0}function Pa(Qa){Qa=Qa|0;var La=Ka()|0;var Ma=La+Qa|0;if(La=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}function allocateUTF8(str){var size=lengthBytesUTF8(str)+1;var ret=_malloc(size);if(ret)stringToUTF8Array(str,HEAP8,ret,size);return ret}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||67108864;if(Module["wasmMemory"]){wasmMemory=Module["wasmMemory"]}else{wasmMemory=new WebAssembly.Memory({"initial":INITIAL_MEMORY/65536,"maximum":2147483648/65536})}if(wasmMemory){buffer=wasmMemory.buffer}INITIAL_MEMORY=buffer.byteLength;updateGlobalBufferAndViews(buffer);var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function keepRuntimeAlive(){return noExitRuntime}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();FS.ignorePermissions=false;TTY.init();callRuntimeCallbacks(__ATINIT__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){{if(Module["onAbort"]){Module["onAbort"](what)}}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}function isFileURI(filename){return filename.startsWith("file://")}var wasmBinaryFile;wasmBinaryFile="astroem.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}var binary=tryParseAsDataURI(file);if(binary){return binary}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch=="function"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary(wasmBinaryFile)})}else{if(readAsync){return new Promise(function(resolve,reject){readAsync(wasmBinaryFile,function(response){resolve(new Uint8Array(response))},reject)})}}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmTable=Module["asm"]["wb"];addOnInit(Module["asm"]["J"]);removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(function(instance){return instance}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&!ENVIRONMENT_IS_NODE&&typeof fetch=="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiationResult,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiationResult)})})}else{return instantiateArrayBuffer(receiveInstantiationResult)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync();return{}}var tempDouble;var tempI64;var ASM_CONSTS={194112:()=>{return self.Regions.NSHAPE()},194144:($0,$1,$2)=>{self.Regions.FINIT($0,$1,$2)},194176:($0,$1,$2)=>{return self.Regions.FILTER($0,$1,$2)},194216:($0,$1,$2)=>{if(typeof self.Regions!=="object"){self.Regions={}}self.Regions.NSHAPE=function(){return $0};self.Regions.FINIT=new Function("g","x","y",UTF8ToString($1));self.Regions.FILTER=new Function("g","x","y","return ("+UTF8ToString($2)+")")}};function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func=="number"){if(callback.arg===undefined){getWasmTableEntry(func)()}else{getWasmTableEntry(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function getValue(ptr,type="i8"){if(type.endsWith("*"))type="i32";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP32[ptr>>2];case"float":return HEAPF32[ptr>>2];case"double":return Number(HEAPF64[ptr>>3]);default:abort("invalid type for getValue: "+type)}return null}var wasmTableMirror=[];function getWasmTableEntry(funcPtr){var func=wasmTableMirror[funcPtr];if(!func){if(funcPtr>=wasmTableMirror.length)wasmTableMirror.length=funcPtr+1;wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func}function setValue(ptr,value,type="i8"){if(type.endsWith("*"))type="i32";switch(type){case"i1":HEAP8[ptr>>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}function setErrNo(value){HEAP32[___errno_location()>>2]=value;return value}var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(p=>!!p),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:path=>{if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:(l,r)=>{return PATH.normalize(l+"/"+r)}};function getRandomDevice(){if(typeof crypto=="object"&&typeof crypto["getRandomValues"]=="function"){var randomBuffer=new Uint8Array(1);return function(){crypto.getRandomValues(randomBuffer);return randomBuffer[0]}}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");return function(){return crypto_module["randomBytes"](1)[0]}}catch(e){}}return function(){abort("randomDevice")}}var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(p=>!!p),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}tty.input=intArrayFromString(result,true)}return tty.input.shift()},put_char:function(tty,val){if(val===null||val===10){out(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};function mmapAlloc(size){abort()}var MEMFS={ops_table:null,mount:function(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode:function(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node;parent.timestamp=node.timestamp}return node},getFileDataAsTypedArray:function(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage:function(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage:function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr:function(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr:function(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup:function(parent,name){throw FS.genericErrors[44]},mknod:function(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename:function(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.parent.timestamp=Date.now();old_node.name=new_name;new_dir.contents[new_name]=old_node;new_dir.timestamp=old_node.parent.timestamp;old_node.parent=new_dir},unlink:function(parent,name){delete parent.contents[name];parent.timestamp=Date.now()},rmdir:function(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.timestamp=Date.now()},readdir:function(node){var entries=[".",".."];for(var key in node.contents){if(!node.contents.hasOwnProperty(key)){continue}entries.push(key)}return entries},symlink:function(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink:function(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read:function(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{NODEFS.isWindows=!!process.platform.match(/^win/);var flags=process["binding"]("constants");if(flags["fs"]){flags=flags["fs"]}NODEFS.flagsForNodeMap={1024:flags["O_APPEND"],64:flags["O_CREAT"],128:flags["O_EXCL"],256:flags["O_NOCTTY"],0:flags["O_RDONLY"],2:flags["O_RDWR"],4096:flags["O_SYNC"],512:flags["O_TRUNC"],1:flags["O_WRONLY"],131072:flags["O_NOFOLLOW"]}},convertNodeCode:e=>{var code=e.code;return ERRNO_CODES[code]},mount:mount=>{return NODEFS.createNode(null,"/",NODEFS.getMode(mount.opts.root),0)},createNode:(parent,name,mode,dev)=>{if(!FS.isDir(mode)&&!FS.isFile(mode)&&!FS.isLink(mode)){throw new FS.ErrnoError(28)}var node=FS.createNode(parent,name,mode);node.node_ops=NODEFS.node_ops;node.stream_ops=NODEFS.stream_ops;return node},getMode:path=>{var stat;try{stat=fs.lstatSync(path);if(NODEFS.isWindows){stat.mode=stat.mode|(stat.mode&292)>>2}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}return stat.mode},realPath:node=>{var parts=[];while(node.parent!==node){parts.push(node.name);node=node.parent}parts.push(node.mount.opts.root);parts.reverse();return PATH.join.apply(null,parts)},flagsForNode:flags=>{flags&=~2097152;flags&=~2048;flags&=~32768;flags&=~524288;flags&=~65536;var newFlags=0;for(var k in NODEFS.flagsForNodeMap){if(flags&k){newFlags|=NODEFS.flagsForNodeMap[k];flags^=k}}if(!flags){return newFlags}else{throw new FS.ErrnoError(28)}},node_ops:{getattr:node=>{var path=NODEFS.realPath(node);var stat;try{stat=fs.lstatSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}if(NODEFS.isWindows&&!stat.blksize){stat.blksize=4096}if(NODEFS.isWindows&&!stat.blocks){stat.blocks=(stat.size+stat.blksize-1)/stat.blksize|0}return{dev:stat.dev,ino:stat.ino,mode:stat.mode,nlink:stat.nlink,uid:stat.uid,gid:stat.gid,rdev:stat.rdev,size:stat.size,atime:stat.atime,mtime:stat.mtime,ctime:stat.ctime,blksize:stat.blksize,blocks:stat.blocks}},setattr:(node,attr)=>{var path=NODEFS.realPath(node);try{if(attr.mode!==undefined){fs.chmodSync(path,attr.mode);node.mode=attr.mode}if(attr.timestamp!==undefined){var date=new Date(attr.timestamp);fs.utimesSync(path,date,date)}if(attr.size!==undefined){fs.truncateSync(path,attr.size)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},lookup:(parent,name)=>{var path=PATH.join2(NODEFS.realPath(parent),name);var mode=NODEFS.getMode(path);return NODEFS.createNode(parent,name,mode)},mknod:(parent,name,mode,dev)=>{var node=NODEFS.createNode(parent,name,mode,dev);var path=NODEFS.realPath(node);try{if(FS.isDir(node.mode)){fs.mkdirSync(path,node.mode)}else{fs.writeFileSync(path,"",{mode:node.mode})}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}return node},rename:(oldNode,newDir,newName)=>{var oldPath=NODEFS.realPath(oldNode);var newPath=PATH.join2(NODEFS.realPath(newDir),newName);try{fs.renameSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}oldNode.name=newName},unlink:(parent,name)=>{var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.unlinkSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},rmdir:(parent,name)=>{var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.rmdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},readdir:node=>{var path=NODEFS.realPath(node);try{return fs.readdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},symlink:(parent,newName,oldPath)=>{var newPath=PATH.join2(NODEFS.realPath(parent),newName);try{fs.symlinkSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},readlink:node=>{var path=NODEFS.realPath(node);try{path=fs.readlinkSync(path);path=nodePath.relative(nodePath.resolve(node.mount.opts.root),path);return path}catch(e){if(!e.code)throw e;if(e.code==="UNKNOWN")throw new FS.ErrnoError(28);throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}}},stream_ops:{open:stream=>{var path=NODEFS.realPath(stream.node);try{if(FS.isFile(stream.node.mode)){stream.nfd=fs.openSync(path,NODEFS.flagsForNode(stream.flags))}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},close:stream=>{try{if(FS.isFile(stream.node.mode)&&stream.nfd){fs.closeSync(stream.nfd)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},read:(stream,buffer,offset,length,position)=>{if(length===0)return 0;try{return fs.readSync(stream.nfd,Buffer.from(buffer.buffer),offset,length,position)}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},write:(stream,buffer,offset,length,position)=>{try{return fs.writeSync(stream.nfd,Buffer.from(buffer.buffer),offset,length,position)}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},llseek:(stream,offset,whence)=>{var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(FS.isFile(stream.node.mode)){try{var stat=fs.fstatSync(stream.nfd);position+=stat.size}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}}}if(position<0){throw new FS.ErrnoError(28)}return position},mmap:(stream,length,position,prot,flags)=>{if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}var ptr=mmapAlloc(length);NODEFS.stream_ops.read(stream,HEAP8,ptr,length,position);return{ptr:ptr,allocated:true}},msync:(stream,buffer,offset,length,mmapFlags)=>{if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(mmapFlags&2){return 0}var bytesWritten=NODEFS.stream_ops.write(stream,buffer,0,length,offset,false);return 0}}};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath:(path,opts={})=>{path=PATH_FS.resolve(FS.cwd(),path);if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};opts=Object.assign(defaults,opts);if(opts.recurse_count>8){throw new FS.ErrnoError(32)}var parts=PATH.normalizeArray(path.split("/").filter(p=>!!p),false);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:node=>{var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}},hashName:(parentid,name)=>{var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:node=>{var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:node=>{var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:(parent,name)=>{var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:(parent,name,mode,rdev)=>{var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:node=>{FS.hashRemoveNode(node)},isRoot:node=>{return node===node.parent},isMountpoint:node=>{return!!node.mounted},isFile:mode=>{return(mode&61440)===32768},isDir:mode=>{return(mode&61440)===16384},isLink:mode=>{return(mode&61440)===40960},isChrdev:mode=>{return(mode&61440)===8192},isBlkdev:mode=>{return(mode&61440)===24576},isFIFO:mode=>{return(mode&61440)===4096},isSocket:mode=>{return(mode&49152)===49152},flagModes:{"r":0,"r+":2,"w":577,"w+":578,"a":1089,"a+":1090},modeStringToFlags:str=>{var flags=FS.flagModes[str];if(typeof flags=="undefined"){throw new Error("Unknown file open mode: "+str)}return flags},flagsToPermissionString:flag=>{var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:(node,perms)=>{if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup:dir=>{var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:(dir,name)=>{try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:(dir,name,isdir)=>{var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:(node,flags)=>{if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:(fd_start=0,fd_end=FS.MAX_OPEN_FDS)=>{for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStream:fd=>FS.streams[fd],createStream:(stream,fd_start,fd_end)=>{if(!FS.FSStream){FS.FSStream=function(){this.shared={}};FS.FSStream.prototype={object:{get:function(){return this.node},set:function(val){this.node=val}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}},flags:{get:function(){return this.shared.flags},set:function(val){this.shared.flags=val}},position:{get function(){return this.shared.position},set:function(val){this.shared.position=val}}}}stream=Object.assign(new FS.FSStream,stream);var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:fd=>{FS.streams[fd]=null},chrdev_stream_ops:{open:stream=>{var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:()=>{throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice:(dev,ops)=>{FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts:mount=>{var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:(populate,callback)=>{if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err("warning: "+FS.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work")}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(mount=>{if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount:(type,opts,mountpoint)=>{var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:mountpoint=>{var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(hash=>{var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup:(parent,name)=>{return parent.node_ops.lookup(parent,name)},mknod:(path,mode,dev)=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:(path,mode)=>{mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:(path,mode)=>{mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:(path,mode)=>{var dirs=path.split("/");var d="";for(var i=0;i{if(typeof dev=="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink:(oldpath,newpath)=>{if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename:(old_path,new_path)=>{var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node;if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name)}catch(e){throw e}finally{FS.hashAddNode(old_node)}},rmdir:path=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node)},readdir:path=>{var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;if(!node.node_ops.readdir){throw new FS.ErrnoError(54)}return node.node_ops.readdir(node)},unlink:path=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.unlink(parent,name);FS.destroyNode(node)},readlink:path=>{var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return PATH_FS.resolve(FS.getPath(link.parent),link.node_ops.readlink(link))},stat:(path,dontFollow)=>{var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;if(!node){throw new FS.ErrnoError(44)}if(!node.node_ops.getattr){throw new FS.ErrnoError(63)}return node.node_ops.getattr(node)},lstat:path=>{return FS.stat(path,true)},chmod:(path,mode,dontFollow)=>{var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{mode:mode&4095|node.mode&~4095,timestamp:Date.now()})},lchmod:(path,mode)=>{FS.chmod(path,mode,true)},fchmod:(fd,mode)=>{var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}FS.chmod(stream.node,mode)},chown:(path,uid,gid,dontFollow)=>{var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{timestamp:Date.now()})},lchown:(path,uid,gid)=>{FS.chown(path,uid,gid,true)},fchown:(fd,uid,gid)=>{var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}FS.chown(stream.node,uid,gid)},truncate:(path,len)=>{if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}node.node_ops.setattr(node,{size:len,timestamp:Date.now()})},ftruncate:(fd,len)=>{var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.truncate(stream.node,len)},utime:(path,atime,mtime)=>{var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;node.node_ops.setattr(node,{timestamp:Math.max(atime,mtime)})},open:(path,flags,mode)=>{if(path===""){throw new FS.ErrnoError(44)}flags=typeof flags=="string"?FS.modeStringToFlags(flags):flags;mode=typeof mode=="undefined"?438:mode;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;if(typeof path=="object"){node=path}else{path=PATH.normalize(path);try{var lookup=FS.lookupPath(path,{follow:!(flags&131072)});node=lookup.node}catch(e){}}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else{node=FS.mknod(path,mode,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512&&!created){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node:node,path:FS.getPath(node),flags:flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false});if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(Module["logReadFiles"]&&!(flags&1)){if(!FS.readFiles)FS.readFiles={};if(!(path in FS.readFiles)){FS.readFiles[path]=1}}return stream},close:stream=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed:stream=>{return stream.fd===null},llseek:(stream,offset,whence)=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read:(stream,buffer,offset,length,position)=>{if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write:(stream,buffer,offset,length,position,canOwn)=>{if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;return bytesWritten},allocate:(stream,offset,length)=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(offset<0||length<=0){throw new FS.ErrnoError(28)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(!FS.isFile(stream.node.mode)&&!FS.isDir(stream.node.mode)){throw new FS.ErrnoError(43)}if(!stream.stream_ops.allocate){throw new FS.ErrnoError(138)}stream.stream_ops.allocate(stream,offset,length)},mmap:(stream,length,position,prot,flags)=>{if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}return stream.stream_ops.mmap(stream,length,position,prot,flags)},msync:(stream,buffer,offset,length,mmapFlags)=>{if(!stream||!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},munmap:stream=>0,ioctl:(stream,cmd,arg)=>{if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile:(path,opts={})=>{opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error('Invalid encoding type "'+opts.encoding+'"')}var ret;var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){ret=UTF8ArrayToString(buf,0)}else if(opts.encoding==="binary"){ret=buf}FS.close(stream);return ret},writeFile:(path,data,opts={})=>{opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){var buf=new Uint8Array(lengthBytesUTF8(data)+1);var actualNumBytes=stringToUTF8Array(data,buf,0,buf.length);FS.write(stream,buf,0,actualNumBytes,undefined,opts.canOwn)}else if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir:path=>{var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories:()=>{FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices:()=>{FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var random_device=getRandomDevice();FS.createDevice("/dev","random",random_device);FS.createDevice("/dev","urandom",random_device);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories:()=>{FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount:()=>{var node=FS.createNode(proc_self,"fd",16384|511,73);node.node_ops={lookup:(parent,name)=>{var fd=+name;var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path}};ret.parent=ret;return ret}};return node}},{},"/proc/self/fd")},createStandardStreams:()=>{if(Module["stdin"]){FS.createDevice("/dev","stdin",Module["stdin"])}else{FS.symlink("/dev/tty","/dev/stdin")}if(Module["stdout"]){FS.createDevice("/dev","stdout",null,Module["stdout"])}else{FS.symlink("/dev/tty","/dev/stdout")}if(Module["stderr"]){FS.createDevice("/dev","stderr",null,Module["stderr"])}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1)},ensureErrnoError:()=>{if(FS.ErrnoError)return;FS.ErrnoError=function ErrnoError(errno,node){this.node=node;this.setErrno=function(errno){this.errno=errno};this.setErrno(errno);this.message="FS error"};FS.ErrnoError.prototype=new Error;FS.ErrnoError.prototype.constructor=FS.ErrnoError;[44].forEach(code=>{FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack=""})},staticInit:()=>{FS.ensureErrnoError();FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={"MEMFS":MEMFS,"NODEFS":NODEFS}},init:(input,output,error)=>{FS.init.initialized=true;FS.ensureErrnoError();Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()},quit:()=>{FS.init.initialized=false;for(var i=0;i{var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode},findObject:(path,dontResolveLastLink)=>{var ret=FS.analyzePath(path,dontResolveLastLink);if(ret.exists){return ret.object}else{return null}},analyzePath:(path,dontResolveLastLink)=>{try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createPath:(parent,path,canRead,canWrite)=>{parent=typeof parent=="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){}parent=current}return current},createFile:(parent,name,properties,canRead,canWrite)=>{var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS.getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile:(parent,name,data,canRead,canWrite,canOwn)=>{var path=name;if(parent){parent=typeof parent=="string"?parent:FS.getPath(parent);path=name?PATH.join2(parent,name):parent}var mode=FS.getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data=="string"){var arr=new Array(data.length);for(var i=0,len=data.length;i{var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS.getMode(!!input,!!output);if(!FS.createDevice.major)FS.createDevice.major=64;var dev=FS.makedev(FS.createDevice.major++,0);FS.registerDevice(dev,{open:stream=>{stream.seekable=false},close:stream=>{if(output&&output.buffer&&output.buffer.length){output(10)}},read:(stream,buffer,offset,length,pos)=>{var bytesRead=0;for(var i=0;i{for(var i=0;i{if(obj.isDevice||obj.isFolder||obj.link||obj.contents)return true;if(typeof XMLHttpRequest!="undefined"){throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.")}else if(read_){try{obj.contents=intArrayFromString(read_(obj.url),true);obj.usedBytes=obj.contents.length}catch(e){throw new FS.ErrnoError(29)}}else{throw new Error("Cannot load without read() or XMLHttpRequest.")}},createLazyFile:(parent,name,url,canRead,canWrite)=>{function LazyUint8Array(){this.lengthKnown=false;this.chunks=[]}LazyUint8Array.prototype.get=function LazyUint8Array_get(idx){if(idx>this.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}};var lazyArray=this;lazyArray.setDataGetter(chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(key=>{var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){FS.forceLoadFile(node);return fn.apply(null,arguments)}});function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr:ptr,allocated:true}};node.stream_ops=stream_ops;return node},createPreloadedFile:(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish)=>{var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency("cp "+fullname);function processData(byteArray){function finish(byteArray){if(preFinish)preFinish();if(!dontCreateFile){FS.createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}if(onload)onload();removeRunDependency(dep)}if(Browser.handledByPreloadPlugin(byteArray,fullname,finish,()=>{if(onerror)onerror();removeRunDependency(dep)})){return}finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){asyncLoad(url,byteArray=>processData(byteArray),onerror)}else{processData(url)}},indexedDB:()=>{return window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB},DB_NAME:()=>{return"EM_FS_"+window.location.pathname},DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:(paths,onload,onerror)=>{onload=onload||(()=>{});onerror=onerror||(()=>{});var indexedDB=FS.indexedDB();try{var openRequest=indexedDB.open(FS.DB_NAME(),FS.DB_VERSION)}catch(e){return onerror(e)}openRequest.onupgradeneeded=()=>{out("creating db");var db=openRequest.result;db.createObjectStore(FS.DB_STORE_NAME)};openRequest.onsuccess=()=>{var db=openRequest.result;var transaction=db.transaction([FS.DB_STORE_NAME],"readwrite");var files=transaction.objectStore(FS.DB_STORE_NAME);var ok=0,fail=0,total=paths.length;function finish(){if(fail==0)onload();else onerror()}paths.forEach(path=>{var putRequest=files.put(FS.analyzePath(path).object.contents,path);putRequest.onsuccess=()=>{ok++;if(ok+fail==total)finish()};putRequest.onerror=()=>{fail++;if(ok+fail==total)finish()}});transaction.onerror=onerror};openRequest.onerror=onerror},loadFilesFromDB:(paths,onload,onerror)=>{onload=onload||(()=>{});onerror=onerror||(()=>{});var indexedDB=FS.indexedDB();try{var openRequest=indexedDB.open(FS.DB_NAME(),FS.DB_VERSION)}catch(e){return onerror(e)}openRequest.onupgradeneeded=onerror;openRequest.onsuccess=()=>{var db=openRequest.result;try{var transaction=db.transaction([FS.DB_STORE_NAME],"readonly")}catch(e){onerror(e);return}var files=transaction.objectStore(FS.DB_STORE_NAME);var ok=0,fail=0,total=paths.length;function finish(){if(fail==0)onload();else onerror()}paths.forEach(path=>{var getRequest=files.get(path);getRequest.onsuccess=()=>{if(FS.analyzePath(path).exists){FS.unlink(path)}FS.createDataFile(PATH.dirname(path),PATH.basename(path),getRequest.result,true,true,true);ok++;if(ok+fail==total)finish()};getRequest.onerror=()=>{fail++;if(ok+fail==total)finish()}});transaction.onerror=onerror};openRequest.onerror=onerror}};var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt:function(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=FS.getStream(dirfd);if(!dirstream)throw new FS.ErrnoError(8);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return PATH.join2(dir,path)},doStat:function(func,path,buf){try{var stat=func(path)}catch(e){if(e&&e.node&&PATH.normalize(path)!==PATH.normalize(FS.getPath(e.node))){return-54}throw e}HEAP32[buf>>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAP32[buf+48>>2]=4096;HEAP32[buf+52>>2]=stat.blocks;HEAP32[buf+56>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+76>>2]=0;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+80>>2]=tempI64[0],HEAP32[buf+84>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags,offset){var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);return stream}};function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.createStream(stream,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 5:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 6:case 7:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function convertI32PairToI53Checked(lo,hi){return hi+2097152>>>0<4194305-!!lo?(lo>>>0)+hi*4294967296:NaN}function ___syscall_ftruncate64(fd,length_low,length_high){try{var length=convertI32PairToI53Checked(length_low,length_high);if(isNaN(length))return-61;FS.ftruncate(fd,length);return 0}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_getcwd(buf,size){try{if(size===0)return-28;var cwd=FS.cwd();var cwdLengthInBytes=lengthBytesUTF8(cwd)+1;if(size>>0,(tempDouble=id,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[dirp+pos>>2]=tempI64[0],HEAP32[dirp+pos+4>>2]=tempI64[1];tempI64=[(idx+1)*struct_size>>>0,(tempDouble=(idx+1)*struct_size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[dirp+pos+8>>2]=tempI64[0],HEAP32[dirp+pos+12>>2]=tempI64[1];HEAP16[dirp+pos+16>>1]=280;HEAP8[dirp+pos+18>>0]=type;stringToUTF8(name,dirp+pos+19,256);pos+=struct_size;idx+=1}FS.llseek(stream,idx*struct_size,0);return pos}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:case 21505:{if(!stream.tty)return-59;return 0}case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:{if(!stream.tty)return-59;return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;return 0}case 21524:{if(!stream.tty)return-59;return 0}default:abort("bad ioctl syscall "+op)}}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_openat(dirfd,path,flags,varargs){SYSCALLS.varargs=varargs;try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);var mode=varargs?SYSCALLS.get():0;return FS.open(path,flags,mode).fd}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_rmdir(path){try{path=SYSCALLS.getStr(path);FS.rmdir(path);return 0}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_stat64(path,buf){try{path=SYSCALLS.getStr(path);return SYSCALLS.doStat(FS.stat,path,buf)}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_unlinkat(dirfd,path,flags){try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);if(flags===0){FS.unlink(path)}else if(flags===512){FS.rmdir(path)}else{abort("Invalid flags passed to unlinkat")}return 0}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function __emscripten_date_now(){return Date.now()}var nowIsMonotonic=true;function __emscripten_get_now_is_monotonic(){return nowIsMonotonic}function __emscripten_throw_longjmp(){throw Infinity}function __gmtime_js(time,tmPtr){var date=new Date(HEAP32[time>>2]*1e3);HEAP32[tmPtr>>2]=date.getUTCSeconds();HEAP32[tmPtr+4>>2]=date.getUTCMinutes();HEAP32[tmPtr+8>>2]=date.getUTCHours();HEAP32[tmPtr+12>>2]=date.getUTCDate();HEAP32[tmPtr+16>>2]=date.getUTCMonth();HEAP32[tmPtr+20>>2]=date.getUTCFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getUTCDay();var start=Date.UTC(date.getUTCFullYear(),0,1,0,0,0,0);var yday=(date.getTime()-start)/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday}function __localtime_js(time,tmPtr){var date=new Date(HEAP32[time>>2]*1e3);HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getDay();var start=new Date(date.getFullYear(),0,1);var yday=(date.getTime()-start.getTime())/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr+36>>2]=-(date.getTimezoneOffset()*60);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dst=(summerOffset!=winterOffset&&date.getTimezoneOffset()==Math.min(winterOffset,summerOffset))|0;HEAP32[tmPtr+32>>2]=dst}function _tzset_impl(timezone,daylight,tzname){var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);var winterOffset=winter.getTimezoneOffset();var summerOffset=summer.getTimezoneOffset();var stdTimezoneOffset=Math.max(winterOffset,summerOffset);HEAP32[timezone>>2]=stdTimezoneOffset*60;HEAP32[daylight>>2]=Number(winterOffset!=summerOffset);function extractZone(date){var match=date.toTimeString().match(/\(([A-Za-z ]+)\)$/);return match?match[1]:"GMT"}var winterName=extractZone(winter);var summerName=extractZone(summer);var winterNamePtr=allocateUTF8(winterName);var summerNamePtr=allocateUTF8(summerName);if(summerOffset>2]=winterNamePtr;HEAPU32[tzname+4>>2]=summerNamePtr}else{HEAPU32[tzname>>2]=summerNamePtr;HEAPU32[tzname+4>>2]=winterNamePtr}}function __tzset_js(timezone,daylight,tzname){if(__tzset_js.called)return;__tzset_js.called=true;_tzset_impl(timezone,daylight,tzname)}var readAsmConstArgsArray=[];function readAsmConstArgs(sigPtr,buf){readAsmConstArgsArray.length=0;var ch;buf>>=2;while(ch=HEAPU8[sigPtr++]){buf+=ch!=105&buf;readAsmConstArgsArray.push(ch==105?HEAP32[buf]:HEAPF64[buf++>>1]);++buf}return readAsmConstArgsArray}function _emscripten_asm_const_int(code,sigPtr,argbuf){var args=readAsmConstArgs(sigPtr,argbuf);return ASM_CONSTS[code].apply(null,args)}var _emscripten_get_now;if(ENVIRONMENT_IS_NODE){_emscripten_get_now=()=>{var t=process["hrtime"]();return t[0]*1e3+t[1]/1e6}}else _emscripten_get_now=()=>performance.now();function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function getHeapMax(){return 2147483648}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){var oldSize=HEAPU8.length;requestedSize=requestedSize>>>0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}let alignUp=(x,multiple)=>x+(multiple-x%multiple)%multiple;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var ENV={};function getExecutableName(){return thisProgram||"./this.program"}function getEnvStrings(){if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(x+"="+env[x])}getEnvStrings.strings=strings}return getEnvStrings.strings}function _environ_get(__environ,environ_buf){var bufSize=0;getEnvStrings().forEach(function(string,i){var ptr=environ_buf+bufSize;HEAPU32[__environ+i*4>>2]=ptr;writeAsciiToMemory(string,ptr);bufSize+=string.length+1});return 0}function _environ_sizes_get(penviron_count,penviron_buf_size){var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(function(string){bufSize+=string.length+1});HEAPU32[penviron_buf_size>>2]=bufSize;return 0}function _exit(status){exit(status)}function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function _fd_fdstat_get(fd,pbuf){try{var stream=SYSCALLS.getStreamFromFD(fd);var type=stream.tty?2:FS.isDir(stream.mode)?3:FS.isLink(stream.mode)?7:4;HEAP8[pbuf>>0]=type;return 0}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function doReadv(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){try{var offset=convertI32PairToI53Checked(offset_low,offset_high);if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function doWritev(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret}function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=doWritev(stream,iov,iovcnt);HEAPU32[pnum>>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function __isLeapYear(year){return year%4===0&&(year%100!==0||year%400===0)}function __arraySum(array,index){var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum}var __MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var __MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];function __addDays(date,days){var newDate=new Date(date.getTime());while(days>0){var leap=__isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate}function _strftime(s,maxsize,format,tm){var tm_zone=HEAP32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value=="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}else{return thisDate.getFullYear()}}else{return thisDate.getFullYear()-1}}var EXPANSION_RULES_2={"%a":function(date){return WEEKDAYS[date.tm_wday].substring(0,3)},"%A":function(date){return WEEKDAYS[date.tm_wday]},"%b":function(date){return MONTHS[date.tm_mon].substring(0,3)},"%B":function(date){return MONTHS[date.tm_mon]},"%C":function(date){var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":function(date){return leadingNulls(date.tm_mday,2)},"%e":function(date){return leadingSomething(date.tm_mday,2," ")},"%g":function(date){return getWeekBasedYear(date).toString().substring(2)},"%G":function(date){return getWeekBasedYear(date)},"%H":function(date){return leadingNulls(date.tm_hour,2)},"%I":function(date){var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":function(date){return leadingNulls(date.tm_mday+__arraySum(__isLeapYear(date.tm_year+1900)?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,date.tm_mon-1),3)},"%m":function(date){return leadingNulls(date.tm_mon+1,2)},"%M":function(date){return leadingNulls(date.tm_min,2)},"%n":function(){return"\n"},"%p":function(date){if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}else{return"PM"}},"%S":function(date){return leadingNulls(date.tm_sec,2)},"%t":function(){return"\t"},"%u":function(date){return date.tm_wday||7},"%U":function(date){var days=date.tm_yday+7-date.tm_wday;return leadingNulls(Math.floor(days/7),2)},"%V":function(date){var val=Math.floor((date.tm_yday+7-(date.tm_wday+6)%7)/7);if((date.tm_wday+371-date.tm_yday-2)%7<=2){val++}if(!val){val=52;var dec31=(date.tm_wday+7-date.tm_yday-1)%7;if(dec31==4||dec31==5&&__isLeapYear(date.tm_year%400-1)){val++}}else if(val==53){var jan1=(date.tm_wday+371-date.tm_yday)%7;if(jan1!=4&&(jan1!=3||!__isLeapYear(date.tm_year)))val=1}return leadingNulls(val,2)},"%w":function(date){return date.tm_wday},"%W":function(date){var days=date.tm_yday+7-(date.tm_wday+6)%7;return leadingNulls(Math.floor(days/7),2)},"%y":function(date){return(date.tm_year+1900).toString().substring(2)},"%Y":function(date){return date.tm_year+1900},"%z":function(date){var off=date.tm_gmtoff;var ahead=off>=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":function(date){return date.tm_zone},"%%":function(){return"%"}};pattern=pattern.replace(/%%/g,"\0\0");for(var rule in EXPANSION_RULES_2){if(pattern.includes(rule)){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}pattern=pattern.replace(/\0\0/g,"%");var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1}function _system(command){if(ENVIRONMENT_IS_NODE){if(!command)return 1;var cmdstr=UTF8ToString(command);if(!cmdstr.length)return 0;var cp=require("child_process");var ret=cp.spawnSync(cmdstr,[],{shell:true,stdio:"inherit"});var _W_EXITCODE=(ret,sig)=>ret<<8|sig;if(ret.status===null){var signalToNumber=sig=>{switch(sig){case"SIGHUP":return 1;case"SIGINT":return 2;case"SIGQUIT":return 3;case"SIGFPE":return 8;case"SIGKILL":return 9;case"SIGALRM":return 14;case"SIGTERM":return 15}return 2};return _W_EXITCODE(0,signalToNumber(ret.signal))}return _W_EXITCODE(ret.status,0)}if(!command)return 0;setErrNo(52);return-1}var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.staticInit();if(ENVIRONMENT_IS_NODE){requireNodeFS();NODEFS.staticInit()}ERRNO_CODES={"EPERM":63,"ENOENT":44,"ESRCH":71,"EINTR":27,"EIO":29,"ENXIO":60,"E2BIG":1,"ENOEXEC":45,"EBADF":8,"ECHILD":12,"EAGAIN":6,"EWOULDBLOCK":6,"ENOMEM":48,"EACCES":2,"EFAULT":21,"ENOTBLK":105,"EBUSY":10,"EEXIST":20,"EXDEV":75,"ENODEV":43,"ENOTDIR":54,"EISDIR":31,"EINVAL":28,"ENFILE":41,"EMFILE":33,"ENOTTY":59,"ETXTBSY":74,"EFBIG":22,"ENOSPC":51,"ESPIPE":70,"EROFS":69,"EMLINK":34,"EPIPE":64,"EDOM":18,"ERANGE":68,"ENOMSG":49,"EIDRM":24,"ECHRNG":106,"EL2NSYNC":156,"EL3HLT":107,"EL3RST":108,"ELNRNG":109,"EUNATCH":110,"ENOCSI":111,"EL2HLT":112,"EDEADLK":16,"ENOLCK":46,"EBADE":113,"EBADR":114,"EXFULL":115,"ENOANO":104,"EBADRQC":103,"EBADSLT":102,"EDEADLOCK":16,"EBFONT":101,"ENOSTR":100,"ENODATA":116,"ETIME":117,"ENOSR":118,"ENONET":119,"ENOPKG":120,"EREMOTE":121,"ENOLINK":47,"EADV":122,"ESRMNT":123,"ECOMM":124,"EPROTO":65,"EMULTIHOP":36,"EDOTDOT":125,"EBADMSG":9,"ENOTUNIQ":126,"EBADFD":127,"EREMCHG":128,"ELIBACC":129,"ELIBBAD":130,"ELIBSCN":131,"ELIBMAX":132,"ELIBEXEC":133,"ENOSYS":52,"ENOTEMPTY":55,"ENAMETOOLONG":37,"ELOOP":32,"EOPNOTSUPP":138,"EPFNOSUPPORT":139,"ECONNRESET":15,"ENOBUFS":42,"EAFNOSUPPORT":5,"EPROTOTYPE":67,"ENOTSOCK":57,"ENOPROTOOPT":50,"ESHUTDOWN":140,"ECONNREFUSED":14,"EADDRINUSE":3,"ECONNABORTED":13,"ENETUNREACH":40,"ENETDOWN":38,"ETIMEDOUT":73,"EHOSTDOWN":142,"EHOSTUNREACH":23,"EINPROGRESS":26,"EALREADY":7,"EDESTADDRREQ":17,"EMSGSIZE":35,"EPROTONOSUPPORT":66,"ESOCKTNOSUPPORT":137,"EADDRNOTAVAIL":4,"ENETRESET":39,"EISCONN":30,"ENOTCONN":53,"ETOOMANYREFS":141,"EUSERS":136,"EDQUOT":19,"ESTALE":72,"ENOTSUP":138,"ENOMEDIUM":148,"EILSEQ":25,"EOVERFLOW":61,"ECANCELED":11,"ENOTRECOVERABLE":56,"EOWNERDEAD":62,"ESTRPIPE":135};var ASSERTIONS=false;function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}function intArrayToString(array){var ret=[];for(var i=0;i255){if(ASSERTIONS){assert(false,"Character code "+chr+" ("+String.fromCharCode(chr)+") at offset "+i+" not in 0x00-0xFF.")}chr&=255}ret.push(String.fromCharCode(chr))}return ret.join("")}var decodeBase64=typeof atob=="function"?atob:function(input){var keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");do{enc1=keyStr.indexOf(input.charAt(i++));enc2=keyStr.indexOf(input.charAt(i++));enc3=keyStr.indexOf(input.charAt(i++));enc4=keyStr.indexOf(input.charAt(i++));chr1=enc1<<2|enc2>>4;chr2=(enc2&15)<<4|enc3>>2;chr3=(enc3&3)<<6|enc4;output=output+String.fromCharCode(chr1);if(enc3!==64){output=output+String.fromCharCode(chr2)}if(enc4!==64){output=output+String.fromCharCode(chr3)}}while(i0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;function exit(status,implicit){EXITSTATUS=status;procExit(status)}function procExit(code){EXITSTATUS=code;if(!keepRuntimeAlive()){if(Module["onExit"])Module["onExit"](code);ABORT=true}quit_(code,new ExitStatus(code))}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run();Module["print"]=function(text){console.log(text)};Module["rootdir"]="/";Module["vfile"]=function(filename,buf,canOwn){let size;if(buf){try{FS.unlink(Module["rootdir"]+filename)}catch(e){}FS.createDataFile(Module["rootdir"],filename,buf,true,true,canOwn);if(buf.length!==undefined){size=buf.length}else if(buf.byteLength!==undefined){size=buf.byteLength}else if(buf.size!==undefined){size=buf.size}else{size=-1}return{path:filename,size:size}}return FS.readFile(Module["rootdir"]+filename,{encoding:"binary"})};Module["vread"]=function(filename,mode){mode=mode||"utf8";return FS.readFile(Module["rootdir"]+filename,{encoding:mode})};Module["vsize"]=function(filename){let buf={size:-1};try{buf=FS.stat(Module["rootdir"]+filename)}catch(e){}return buf.size};Module["vunlink"]=function(filename){try{FS.unlink(Module["rootdir"]+filename)}catch(e){}};Module["vmount"]=function(root,mntpnt){let got=1;try{FS.mkdir(mntpnt);FS.mount(NODEFS,{root:root},mntpnt)}catch(e){got=0;FS.rmdir(mntpnt)}return got};Module["arrfile"]=function(filename,arr){Module["vunlink"](filename);FS.createDataFile(Module["rootdir"],filename,arr,true,true,false);return{path:filename,size:arr.byteLength}};Module["gzcompress"]=function(data){let ret;const gzFile=ccall("gzopen","number",["string","string"],["output.gz","wb"]);const buffer=_malloc(data.length);HEAPU8.set(data,buffer);ccall("gzwrite","number",["number","number","number"],[gzFile,buffer,data.length]);ccall("gzclose","number",["number"],[gzFile]);_free(buffer);ret=new Uint8Array(FS.root.contents["output.gz"].contents);FS.unlink("output.gz");return ret};Module["gzdecompress"]=function(data,filename,canOwn){let i,ret,curr,len,gzFile;let total=0;const BUFSIZE=1024*1024;const buffer=_malloc(BUFSIZE);const chunks=[];FS.createDataFile(Module["rootdir"],"input.gz",data,true,true,false);gzFile=ccall("gzopen","number",["string","string"],["input.gz","rb"]);while(true){len=ccall("gzread","number",["number","number","number"],[gzFile,buffer,BUFSIZE]);if(len<=0){break}chunks.push(new Uint8Array(len));chunks[chunks.length-1].set(HEAPU8.subarray(buffer,buffer+len));total+=len}ccall("gzclose","number",["number"],[gzFile]);FS.unlink("input.gz");_free(buffer);ret=new Uint8Array(total);curr=0;for(i=0;i0?bin:1/Math.abs(bin);hdu.x1=getValue(hptr+24,"i32");hdu.y1=getValue(hptr+28,"i32");hdu.x2=getValue(hptr+40,"i32");hdu.y2=getValue(hptr+44,"i32");hdu.naxis1=Math.floor((hdu.x2-hdu.x1+1)/xbin);hdu.naxis2=Math.floor((hdu.y2-hdu.y1+1)/xbin);hdu.bitpix=getValue(hptr+56,"i32");if(opts.filter){hdu.filter=opts.filter}if(slice){hdu.slice=slice}status=getValue(hptr+60,"i32");_free(hptr);Module["errchk"](status);if(!bufptr||doerr){Module["error"]("can't convert image to array (image too large?)")}datalen=hdu.naxis1*hdu.naxis2;switch(hdu.bitpix){case 8:hdu.image=new Uint8Array(HEAPU8.subarray(bufptr,bufptr+datalen));break;case 16:hdu.image=new Int16Array(HEAP16.subarray(bufptr/2,bufptr/2+datalen));break;case-16:hdu.image=new Uint16Array(HEAPU16.subarray(bufptr/2,bufptr/2+datalen));break;case 32:hdu.image=new Int32Array(HEAP32.subarray(bufptr/4,bufptr/4+datalen));break;case-32:hdu.image=new Float32Array(HEAPF32.subarray(bufptr/4,bufptr/4+datalen));break;case-64:hdu.image=new Float64Array(HEAPF64.subarray(bufptr/8,bufptr/8+datalen));break;default:Module["error"](`${hdu.bitpix}-bit FITS data is not supported`);break}hptr=_malloc(20);setValue(hptr+12,0,"i32");ccall("getHeaderToString",null,["number","number","number","number"],[ofptr,hptr,hptr+8,hptr+12]);hdu.ncard=getValue(hptr+8,"i32");bufptr2=getValue(hptr,"*");buf=new Uint8Array(HEAPU8.subarray(bufptr2,bufptr2+hdu.ncard*80));buflen=buf.byteLength;hdu.cardstr="";for(i=0;i{throw toThrow};var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;function logExceptionOnExit(e){if(e instanceof ExitStatus)return;let toLog=e;err("exiting due to exception: "+toLog)}var fs;var nodePath;var requireNodeFS;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}requireNodeFS=()=>{if(!nodePath){fs=require("fs");nodePath=require("path")}};read_=function shell_read(filename,binary){requireNodeFS();filename=nodePath["normalize"](filename);return fs.readFileSync(filename,binary?undefined:"utf8")};readBinary=filename=>{var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}return ret};readAsync=(filename,onload,onerror)=>{requireNodeFS();filename=nodePath["normalize"](filename);fs.readFile(filename,function(err,data){if(err)onerror(err);else onload(data.buffer)})};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);if(typeof module!="undefined"){module["exports"]=Module}process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",function(reason){throw reason});quit_=(status,toThrow)=>{if(keepRuntimeAlive()){process["exitCode"]=status;throw toThrow}logExceptionOnExit(toThrow);process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=title=>document.title=title}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var tempRet0=0;var setTempRet0=value=>{tempRet0=value};var getTempRet0=()=>tempRet0;var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||true;if(typeof WebAssembly!="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort(text)}}function getCFunc(ident){var func=Module["_"+ident];return func}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret},"array":function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}function allocateUTF8(str){var size=lengthBytesUTF8(str)+1;var ret=_malloc(size);if(ret)stringToUTF8Array(str,HEAP8,ret,size);return ret}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||67108864;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function keepRuntimeAlive(){return noExitRuntime}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();FS.ignorePermissions=false;TTY.init();callRuntimeCallbacks(__ATINIT__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){{if(Module["onAbort"]){Module["onAbort"](what)}}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}function isFileURI(filename){return filename.startsWith("file://")}var wasmBinaryFile;wasmBinaryFile="astroemw.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch=="function"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary(wasmBinaryFile)})}else{if(readAsync){return new Promise(function(resolve,reject){readAsync(wasmBinaryFile,function(response){resolve(new Uint8Array(response))},reject)})}}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["I"];updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["wb"];addOnInit(Module["asm"]["J"]);removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(function(instance){return instance}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&!ENVIRONMENT_IS_NODE&&typeof fetch=="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiationResult,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiationResult)})})}else{return instantiateArrayBuffer(receiveInstantiationResult)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync();return{}}var tempDouble;var tempI64;var ASM_CONSTS={194112:()=>{return self.Regions.NSHAPE()},194144:($0,$1,$2)=>{self.Regions.FINIT($0,$1,$2)},194176:($0,$1,$2)=>{return self.Regions.FILTER($0,$1,$2)},194216:($0,$1,$2)=>{if(typeof self.Regions!=="object"){self.Regions={}}self.Regions.NSHAPE=function(){return $0};self.Regions.FINIT=new Function("g","x","y",UTF8ToString($1));self.Regions.FILTER=new Function("g","x","y","return ("+UTF8ToString($2)+")")}};function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func=="number"){if(callback.arg===undefined){getWasmTableEntry(func)()}else{getWasmTableEntry(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function getValue(ptr,type="i8"){if(type.endsWith("*"))type="i32";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP32[ptr>>2];case"float":return HEAPF32[ptr>>2];case"double":return Number(HEAPF64[ptr>>3]);default:abort("invalid type for getValue: "+type)}return null}var wasmTableMirror=[];function getWasmTableEntry(funcPtr){var func=wasmTableMirror[funcPtr];if(!func){if(funcPtr>=wasmTableMirror.length)wasmTableMirror.length=funcPtr+1;wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func}function setValue(ptr,value,type="i8"){if(type.endsWith("*"))type="i32";switch(type){case"i1":HEAP8[ptr>>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}function setErrNo(value){HEAP32[___errno_location()>>2]=value;return value}var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(p=>!!p),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:path=>{if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:(l,r)=>{return PATH.normalize(l+"/"+r)}};function getRandomDevice(){if(typeof crypto=="object"&&typeof crypto["getRandomValues"]=="function"){var randomBuffer=new Uint8Array(1);return function(){crypto.getRandomValues(randomBuffer);return randomBuffer[0]}}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");return function(){return crypto_module["randomBytes"](1)[0]}}catch(e){}}return function(){abort("randomDevice")}}var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(p=>!!p),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}tty.input=intArrayFromString(result,true)}return tty.input.shift()},put_char:function(tty,val){if(val===null||val===10){out(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};function mmapAlloc(size){abort()}var MEMFS={ops_table:null,mount:function(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode:function(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node;parent.timestamp=node.timestamp}return node},getFileDataAsTypedArray:function(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage:function(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage:function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr:function(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr:function(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup:function(parent,name){throw FS.genericErrors[44]},mknod:function(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename:function(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.parent.timestamp=Date.now();old_node.name=new_name;new_dir.contents[new_name]=old_node;new_dir.timestamp=old_node.parent.timestamp;old_node.parent=new_dir},unlink:function(parent,name){delete parent.contents[name];parent.timestamp=Date.now()},rmdir:function(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.timestamp=Date.now()},readdir:function(node){var entries=[".",".."];for(var key in node.contents){if(!node.contents.hasOwnProperty(key)){continue}entries.push(key)}return entries},symlink:function(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink:function(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read:function(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{NODEFS.isWindows=!!process.platform.match(/^win/);var flags=process["binding"]("constants");if(flags["fs"]){flags=flags["fs"]}NODEFS.flagsForNodeMap={1024:flags["O_APPEND"],64:flags["O_CREAT"],128:flags["O_EXCL"],256:flags["O_NOCTTY"],0:flags["O_RDONLY"],2:flags["O_RDWR"],4096:flags["O_SYNC"],512:flags["O_TRUNC"],1:flags["O_WRONLY"],131072:flags["O_NOFOLLOW"]}},convertNodeCode:e=>{var code=e.code;return ERRNO_CODES[code]},mount:mount=>{return NODEFS.createNode(null,"/",NODEFS.getMode(mount.opts.root),0)},createNode:(parent,name,mode,dev)=>{if(!FS.isDir(mode)&&!FS.isFile(mode)&&!FS.isLink(mode)){throw new FS.ErrnoError(28)}var node=FS.createNode(parent,name,mode);node.node_ops=NODEFS.node_ops;node.stream_ops=NODEFS.stream_ops;return node},getMode:path=>{var stat;try{stat=fs.lstatSync(path);if(NODEFS.isWindows){stat.mode=stat.mode|(stat.mode&292)>>2}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}return stat.mode},realPath:node=>{var parts=[];while(node.parent!==node){parts.push(node.name);node=node.parent}parts.push(node.mount.opts.root);parts.reverse();return PATH.join.apply(null,parts)},flagsForNode:flags=>{flags&=~2097152;flags&=~2048;flags&=~32768;flags&=~524288;flags&=~65536;var newFlags=0;for(var k in NODEFS.flagsForNodeMap){if(flags&k){newFlags|=NODEFS.flagsForNodeMap[k];flags^=k}}if(!flags){return newFlags}else{throw new FS.ErrnoError(28)}},node_ops:{getattr:node=>{var path=NODEFS.realPath(node);var stat;try{stat=fs.lstatSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}if(NODEFS.isWindows&&!stat.blksize){stat.blksize=4096}if(NODEFS.isWindows&&!stat.blocks){stat.blocks=(stat.size+stat.blksize-1)/stat.blksize|0}return{dev:stat.dev,ino:stat.ino,mode:stat.mode,nlink:stat.nlink,uid:stat.uid,gid:stat.gid,rdev:stat.rdev,size:stat.size,atime:stat.atime,mtime:stat.mtime,ctime:stat.ctime,blksize:stat.blksize,blocks:stat.blocks}},setattr:(node,attr)=>{var path=NODEFS.realPath(node);try{if(attr.mode!==undefined){fs.chmodSync(path,attr.mode);node.mode=attr.mode}if(attr.timestamp!==undefined){var date=new Date(attr.timestamp);fs.utimesSync(path,date,date)}if(attr.size!==undefined){fs.truncateSync(path,attr.size)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},lookup:(parent,name)=>{var path=PATH.join2(NODEFS.realPath(parent),name);var mode=NODEFS.getMode(path);return NODEFS.createNode(parent,name,mode)},mknod:(parent,name,mode,dev)=>{var node=NODEFS.createNode(parent,name,mode,dev);var path=NODEFS.realPath(node);try{if(FS.isDir(node.mode)){fs.mkdirSync(path,node.mode)}else{fs.writeFileSync(path,"",{mode:node.mode})}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}return node},rename:(oldNode,newDir,newName)=>{var oldPath=NODEFS.realPath(oldNode);var newPath=PATH.join2(NODEFS.realPath(newDir),newName);try{fs.renameSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}oldNode.name=newName},unlink:(parent,name)=>{var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.unlinkSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},rmdir:(parent,name)=>{var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.rmdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},readdir:node=>{var path=NODEFS.realPath(node);try{return fs.readdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},symlink:(parent,newName,oldPath)=>{var newPath=PATH.join2(NODEFS.realPath(parent),newName);try{fs.symlinkSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},readlink:node=>{var path=NODEFS.realPath(node);try{path=fs.readlinkSync(path);path=nodePath.relative(nodePath.resolve(node.mount.opts.root),path);return path}catch(e){if(!e.code)throw e;if(e.code==="UNKNOWN")throw new FS.ErrnoError(28);throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}}},stream_ops:{open:stream=>{var path=NODEFS.realPath(stream.node);try{if(FS.isFile(stream.node.mode)){stream.nfd=fs.openSync(path,NODEFS.flagsForNode(stream.flags))}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},close:stream=>{try{if(FS.isFile(stream.node.mode)&&stream.nfd){fs.closeSync(stream.nfd)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},read:(stream,buffer,offset,length,position)=>{if(length===0)return 0;try{return fs.readSync(stream.nfd,Buffer.from(buffer.buffer),offset,length,position)}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},write:(stream,buffer,offset,length,position)=>{try{return fs.writeSync(stream.nfd,Buffer.from(buffer.buffer),offset,length,position)}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},llseek:(stream,offset,whence)=>{var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(FS.isFile(stream.node.mode)){try{var stat=fs.fstatSync(stream.nfd);position+=stat.size}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}}}if(position<0){throw new FS.ErrnoError(28)}return position},mmap:(stream,length,position,prot,flags)=>{if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}var ptr=mmapAlloc(length);NODEFS.stream_ops.read(stream,HEAP8,ptr,length,position);return{ptr:ptr,allocated:true}},msync:(stream,buffer,offset,length,mmapFlags)=>{if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(mmapFlags&2){return 0}var bytesWritten=NODEFS.stream_ops.write(stream,buffer,0,length,offset,false);return 0}}};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath:(path,opts={})=>{path=PATH_FS.resolve(FS.cwd(),path);if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};opts=Object.assign(defaults,opts);if(opts.recurse_count>8){throw new FS.ErrnoError(32)}var parts=PATH.normalizeArray(path.split("/").filter(p=>!!p),false);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:node=>{var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}},hashName:(parentid,name)=>{var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:node=>{var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:node=>{var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:(parent,name)=>{var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:(parent,name,mode,rdev)=>{var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:node=>{FS.hashRemoveNode(node)},isRoot:node=>{return node===node.parent},isMountpoint:node=>{return!!node.mounted},isFile:mode=>{return(mode&61440)===32768},isDir:mode=>{return(mode&61440)===16384},isLink:mode=>{return(mode&61440)===40960},isChrdev:mode=>{return(mode&61440)===8192},isBlkdev:mode=>{return(mode&61440)===24576},isFIFO:mode=>{return(mode&61440)===4096},isSocket:mode=>{return(mode&49152)===49152},flagModes:{"r":0,"r+":2,"w":577,"w+":578,"a":1089,"a+":1090},modeStringToFlags:str=>{var flags=FS.flagModes[str];if(typeof flags=="undefined"){throw new Error("Unknown file open mode: "+str)}return flags},flagsToPermissionString:flag=>{var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:(node,perms)=>{if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup:dir=>{var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:(dir,name)=>{try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:(dir,name,isdir)=>{var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:(node,flags)=>{if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:(fd_start=0,fd_end=FS.MAX_OPEN_FDS)=>{for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStream:fd=>FS.streams[fd],createStream:(stream,fd_start,fd_end)=>{if(!FS.FSStream){FS.FSStream=function(){this.shared={}};FS.FSStream.prototype={object:{get:function(){return this.node},set:function(val){this.node=val}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}},flags:{get:function(){return this.shared.flags},set:function(val){this.shared.flags=val}},position:{get function(){return this.shared.position},set:function(val){this.shared.position=val}}}}stream=Object.assign(new FS.FSStream,stream);var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:fd=>{FS.streams[fd]=null},chrdev_stream_ops:{open:stream=>{var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:()=>{throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice:(dev,ops)=>{FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts:mount=>{var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:(populate,callback)=>{if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err("warning: "+FS.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work")}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(mount=>{if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount:(type,opts,mountpoint)=>{var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:mountpoint=>{var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(hash=>{var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup:(parent,name)=>{return parent.node_ops.lookup(parent,name)},mknod:(path,mode,dev)=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:(path,mode)=>{mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:(path,mode)=>{mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:(path,mode)=>{var dirs=path.split("/");var d="";for(var i=0;i{if(typeof dev=="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink:(oldpath,newpath)=>{if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename:(old_path,new_path)=>{var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node;if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name)}catch(e){throw e}finally{FS.hashAddNode(old_node)}},rmdir:path=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node)},readdir:path=>{var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;if(!node.node_ops.readdir){throw new FS.ErrnoError(54)}return node.node_ops.readdir(node)},unlink:path=>{var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}parent.node_ops.unlink(parent,name);FS.destroyNode(node)},readlink:path=>{var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return PATH_FS.resolve(FS.getPath(link.parent),link.node_ops.readlink(link))},stat:(path,dontFollow)=>{var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;if(!node){throw new FS.ErrnoError(44)}if(!node.node_ops.getattr){throw new FS.ErrnoError(63)}return node.node_ops.getattr(node)},lstat:path=>{return FS.stat(path,true)},chmod:(path,mode,dontFollow)=>{var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{mode:mode&4095|node.mode&~4095,timestamp:Date.now()})},lchmod:(path,mode)=>{FS.chmod(path,mode,true)},fchmod:(fd,mode)=>{var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}FS.chmod(stream.node,mode)},chown:(path,uid,gid,dontFollow)=>{var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{timestamp:Date.now()})},lchown:(path,uid,gid)=>{FS.chown(path,uid,gid,true)},fchown:(fd,uid,gid)=>{var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}FS.chown(stream.node,uid,gid)},truncate:(path,len)=>{if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path=="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}node.node_ops.setattr(node,{size:len,timestamp:Date.now()})},ftruncate:(fd,len)=>{var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.truncate(stream.node,len)},utime:(path,atime,mtime)=>{var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;node.node_ops.setattr(node,{timestamp:Math.max(atime,mtime)})},open:(path,flags,mode)=>{if(path===""){throw new FS.ErrnoError(44)}flags=typeof flags=="string"?FS.modeStringToFlags(flags):flags;mode=typeof mode=="undefined"?438:mode;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;if(typeof path=="object"){node=path}else{path=PATH.normalize(path);try{var lookup=FS.lookupPath(path,{follow:!(flags&131072)});node=lookup.node}catch(e){}}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else{node=FS.mknod(path,mode,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512&&!created){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node:node,path:FS.getPath(node),flags:flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false});if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(Module["logReadFiles"]&&!(flags&1)){if(!FS.readFiles)FS.readFiles={};if(!(path in FS.readFiles)){FS.readFiles[path]=1}}return stream},close:stream=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed:stream=>{return stream.fd===null},llseek:(stream,offset,whence)=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read:(stream,buffer,offset,length,position)=>{if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write:(stream,buffer,offset,length,position,canOwn)=>{if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;return bytesWritten},allocate:(stream,offset,length)=>{if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(offset<0||length<=0){throw new FS.ErrnoError(28)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(!FS.isFile(stream.node.mode)&&!FS.isDir(stream.node.mode)){throw new FS.ErrnoError(43)}if(!stream.stream_ops.allocate){throw new FS.ErrnoError(138)}stream.stream_ops.allocate(stream,offset,length)},mmap:(stream,length,position,prot,flags)=>{if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}return stream.stream_ops.mmap(stream,length,position,prot,flags)},msync:(stream,buffer,offset,length,mmapFlags)=>{if(!stream||!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},munmap:stream=>0,ioctl:(stream,cmd,arg)=>{if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile:(path,opts={})=>{opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error('Invalid encoding type "'+opts.encoding+'"')}var ret;var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){ret=UTF8ArrayToString(buf,0)}else if(opts.encoding==="binary"){ret=buf}FS.close(stream);return ret},writeFile:(path,data,opts={})=>{opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){var buf=new Uint8Array(lengthBytesUTF8(data)+1);var actualNumBytes=stringToUTF8Array(data,buf,0,buf.length);FS.write(stream,buf,0,actualNumBytes,undefined,opts.canOwn)}else if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir:path=>{var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories:()=>{FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices:()=>{FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var random_device=getRandomDevice();FS.createDevice("/dev","random",random_device);FS.createDevice("/dev","urandom",random_device);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories:()=>{FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount:()=>{var node=FS.createNode(proc_self,"fd",16384|511,73);node.node_ops={lookup:(parent,name)=>{var fd=+name;var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path}};ret.parent=ret;return ret}};return node}},{},"/proc/self/fd")},createStandardStreams:()=>{if(Module["stdin"]){FS.createDevice("/dev","stdin",Module["stdin"])}else{FS.symlink("/dev/tty","/dev/stdin")}if(Module["stdout"]){FS.createDevice("/dev","stdout",null,Module["stdout"])}else{FS.symlink("/dev/tty","/dev/stdout")}if(Module["stderr"]){FS.createDevice("/dev","stderr",null,Module["stderr"])}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1)},ensureErrnoError:()=>{if(FS.ErrnoError)return;FS.ErrnoError=function ErrnoError(errno,node){this.node=node;this.setErrno=function(errno){this.errno=errno};this.setErrno(errno);this.message="FS error"};FS.ErrnoError.prototype=new Error;FS.ErrnoError.prototype.constructor=FS.ErrnoError;[44].forEach(code=>{FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack=""})},staticInit:()=>{FS.ensureErrnoError();FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={"MEMFS":MEMFS,"NODEFS":NODEFS}},init:(input,output,error)=>{FS.init.initialized=true;FS.ensureErrnoError();Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()},quit:()=>{FS.init.initialized=false;for(var i=0;i{var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode},findObject:(path,dontResolveLastLink)=>{var ret=FS.analyzePath(path,dontResolveLastLink);if(ret.exists){return ret.object}else{return null}},analyzePath:(path,dontResolveLastLink)=>{try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createPath:(parent,path,canRead,canWrite)=>{parent=typeof parent=="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){}parent=current}return current},createFile:(parent,name,properties,canRead,canWrite)=>{var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS.getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile:(parent,name,data,canRead,canWrite,canOwn)=>{var path=name;if(parent){parent=typeof parent=="string"?parent:FS.getPath(parent);path=name?PATH.join2(parent,name):parent}var mode=FS.getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data=="string"){var arr=new Array(data.length);for(var i=0,len=data.length;i{var path=PATH.join2(typeof parent=="string"?parent:FS.getPath(parent),name);var mode=FS.getMode(!!input,!!output);if(!FS.createDevice.major)FS.createDevice.major=64;var dev=FS.makedev(FS.createDevice.major++,0);FS.registerDevice(dev,{open:stream=>{stream.seekable=false},close:stream=>{if(output&&output.buffer&&output.buffer.length){output(10)}},read:(stream,buffer,offset,length,pos)=>{var bytesRead=0;for(var i=0;i{for(var i=0;i{if(obj.isDevice||obj.isFolder||obj.link||obj.contents)return true;if(typeof XMLHttpRequest!="undefined"){throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.")}else if(read_){try{obj.contents=intArrayFromString(read_(obj.url),true);obj.usedBytes=obj.contents.length}catch(e){throw new FS.ErrnoError(29)}}else{throw new Error("Cannot load without read() or XMLHttpRequest.")}},createLazyFile:(parent,name,url,canRead,canWrite)=>{function LazyUint8Array(){this.lengthKnown=false;this.chunks=[]}LazyUint8Array.prototype.get=function LazyUint8Array_get(idx){if(idx>this.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}};var lazyArray=this;lazyArray.setDataGetter(chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(key=>{var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){FS.forceLoadFile(node);return fn.apply(null,arguments)}});function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr:ptr,allocated:true}};node.stream_ops=stream_ops;return node},createPreloadedFile:(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish)=>{var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency("cp "+fullname);function processData(byteArray){function finish(byteArray){if(preFinish)preFinish();if(!dontCreateFile){FS.createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}if(onload)onload();removeRunDependency(dep)}if(Browser.handledByPreloadPlugin(byteArray,fullname,finish,()=>{if(onerror)onerror();removeRunDependency(dep)})){return}finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){asyncLoad(url,byteArray=>processData(byteArray),onerror)}else{processData(url)}},indexedDB:()=>{return window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB},DB_NAME:()=>{return"EM_FS_"+window.location.pathname},DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:(paths,onload,onerror)=>{onload=onload||(()=>{});onerror=onerror||(()=>{});var indexedDB=FS.indexedDB();try{var openRequest=indexedDB.open(FS.DB_NAME(),FS.DB_VERSION)}catch(e){return onerror(e)}openRequest.onupgradeneeded=()=>{out("creating db");var db=openRequest.result;db.createObjectStore(FS.DB_STORE_NAME)};openRequest.onsuccess=()=>{var db=openRequest.result;var transaction=db.transaction([FS.DB_STORE_NAME],"readwrite");var files=transaction.objectStore(FS.DB_STORE_NAME);var ok=0,fail=0,total=paths.length;function finish(){if(fail==0)onload();else onerror()}paths.forEach(path=>{var putRequest=files.put(FS.analyzePath(path).object.contents,path);putRequest.onsuccess=()=>{ok++;if(ok+fail==total)finish()};putRequest.onerror=()=>{fail++;if(ok+fail==total)finish()}});transaction.onerror=onerror};openRequest.onerror=onerror},loadFilesFromDB:(paths,onload,onerror)=>{onload=onload||(()=>{});onerror=onerror||(()=>{});var indexedDB=FS.indexedDB();try{var openRequest=indexedDB.open(FS.DB_NAME(),FS.DB_VERSION)}catch(e){return onerror(e)}openRequest.onupgradeneeded=onerror;openRequest.onsuccess=()=>{var db=openRequest.result;try{var transaction=db.transaction([FS.DB_STORE_NAME],"readonly")}catch(e){onerror(e);return}var files=transaction.objectStore(FS.DB_STORE_NAME);var ok=0,fail=0,total=paths.length;function finish(){if(fail==0)onload();else onerror()}paths.forEach(path=>{var getRequest=files.get(path);getRequest.onsuccess=()=>{if(FS.analyzePath(path).exists){FS.unlink(path)}FS.createDataFile(PATH.dirname(path),PATH.basename(path),getRequest.result,true,true,true);ok++;if(ok+fail==total)finish()};getRequest.onerror=()=>{fail++;if(ok+fail==total)finish()}});transaction.onerror=onerror};openRequest.onerror=onerror}};var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt:function(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=FS.getStream(dirfd);if(!dirstream)throw new FS.ErrnoError(8);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return PATH.join2(dir,path)},doStat:function(func,path,buf){try{var stat=func(path)}catch(e){if(e&&e.node&&PATH.normalize(path)!==PATH.normalize(FS.getPath(e.node))){return-54}throw e}HEAP32[buf>>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAP32[buf+48>>2]=4096;HEAP32[buf+52>>2]=stat.blocks;HEAP32[buf+56>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+76>>2]=0;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+80>>2]=tempI64[0],HEAP32[buf+84>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags,offset){var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);return stream}};function ___syscall_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.createStream(stream,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 5:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 6:case 7:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function convertI32PairToI53Checked(lo,hi){return hi+2097152>>>0<4194305-!!lo?(lo>>>0)+hi*4294967296:NaN}function ___syscall_ftruncate64(fd,length_low,length_high){try{var length=convertI32PairToI53Checked(length_low,length_high);if(isNaN(length))return-61;FS.ftruncate(fd,length);return 0}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_getcwd(buf,size){try{if(size===0)return-28;var cwd=FS.cwd();var cwdLengthInBytes=lengthBytesUTF8(cwd)+1;if(size>>0,(tempDouble=id,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[dirp+pos>>2]=tempI64[0],HEAP32[dirp+pos+4>>2]=tempI64[1];tempI64=[(idx+1)*struct_size>>>0,(tempDouble=(idx+1)*struct_size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[dirp+pos+8>>2]=tempI64[0],HEAP32[dirp+pos+12>>2]=tempI64[1];HEAP16[dirp+pos+16>>1]=280;HEAP8[dirp+pos+18>>0]=type;stringToUTF8(name,dirp+pos+19,256);pos+=struct_size;idx+=1}FS.llseek(stream,idx*struct_size,0);return pos}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:case 21505:{if(!stream.tty)return-59;return 0}case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:{if(!stream.tty)return-59;return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;return 0}case 21524:{if(!stream.tty)return-59;return 0}default:abort("bad ioctl syscall "+op)}}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_openat(dirfd,path,flags,varargs){SYSCALLS.varargs=varargs;try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);var mode=varargs?SYSCALLS.get():0;return FS.open(path,flags,mode).fd}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_rmdir(path){try{path=SYSCALLS.getStr(path);FS.rmdir(path);return 0}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_stat64(path,buf){try{path=SYSCALLS.getStr(path);return SYSCALLS.doStat(FS.stat,path,buf)}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function ___syscall_unlinkat(dirfd,path,flags){try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);if(flags===0){FS.unlink(path)}else if(flags===512){FS.rmdir(path)}else{abort("Invalid flags passed to unlinkat")}return 0}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return-e.errno}}function __emscripten_date_now(){return Date.now()}var nowIsMonotonic=true;function __emscripten_get_now_is_monotonic(){return nowIsMonotonic}function __emscripten_throw_longjmp(){throw Infinity}function __gmtime_js(time,tmPtr){var date=new Date(HEAP32[time>>2]*1e3);HEAP32[tmPtr>>2]=date.getUTCSeconds();HEAP32[tmPtr+4>>2]=date.getUTCMinutes();HEAP32[tmPtr+8>>2]=date.getUTCHours();HEAP32[tmPtr+12>>2]=date.getUTCDate();HEAP32[tmPtr+16>>2]=date.getUTCMonth();HEAP32[tmPtr+20>>2]=date.getUTCFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getUTCDay();var start=Date.UTC(date.getUTCFullYear(),0,1,0,0,0,0);var yday=(date.getTime()-start)/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday}function __localtime_js(time,tmPtr){var date=new Date(HEAP32[time>>2]*1e3);HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getDay();var start=new Date(date.getFullYear(),0,1);var yday=(date.getTime()-start.getTime())/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr+36>>2]=-(date.getTimezoneOffset()*60);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dst=(summerOffset!=winterOffset&&date.getTimezoneOffset()==Math.min(winterOffset,summerOffset))|0;HEAP32[tmPtr+32>>2]=dst}function _tzset_impl(timezone,daylight,tzname){var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);var winterOffset=winter.getTimezoneOffset();var summerOffset=summer.getTimezoneOffset();var stdTimezoneOffset=Math.max(winterOffset,summerOffset);HEAP32[timezone>>2]=stdTimezoneOffset*60;HEAP32[daylight>>2]=Number(winterOffset!=summerOffset);function extractZone(date){var match=date.toTimeString().match(/\(([A-Za-z ]+)\)$/);return match?match[1]:"GMT"}var winterName=extractZone(winter);var summerName=extractZone(summer);var winterNamePtr=allocateUTF8(winterName);var summerNamePtr=allocateUTF8(summerName);if(summerOffset>2]=winterNamePtr;HEAPU32[tzname+4>>2]=summerNamePtr}else{HEAPU32[tzname>>2]=summerNamePtr;HEAPU32[tzname+4>>2]=winterNamePtr}}function __tzset_js(timezone,daylight,tzname){if(__tzset_js.called)return;__tzset_js.called=true;_tzset_impl(timezone,daylight,tzname)}var readAsmConstArgsArray=[];function readAsmConstArgs(sigPtr,buf){readAsmConstArgsArray.length=0;var ch;buf>>=2;while(ch=HEAPU8[sigPtr++]){buf+=ch!=105&buf;readAsmConstArgsArray.push(ch==105?HEAP32[buf]:HEAPF64[buf++>>1]);++buf}return readAsmConstArgsArray}function _emscripten_asm_const_int(code,sigPtr,argbuf){var args=readAsmConstArgs(sigPtr,argbuf);return ASM_CONSTS[code].apply(null,args)}var _emscripten_get_now;if(ENVIRONMENT_IS_NODE){_emscripten_get_now=()=>{var t=process["hrtime"]();return t[0]*1e3+t[1]/1e6}}else _emscripten_get_now=()=>performance.now();function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function getHeapMax(){return 2147483648}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){var oldSize=HEAPU8.length;requestedSize=requestedSize>>>0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}let alignUp=(x,multiple)=>x+(multiple-x%multiple)%multiple;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var ENV={};function getExecutableName(){return thisProgram||"./this.program"}function getEnvStrings(){if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(x+"="+env[x])}getEnvStrings.strings=strings}return getEnvStrings.strings}function _environ_get(__environ,environ_buf){var bufSize=0;getEnvStrings().forEach(function(string,i){var ptr=environ_buf+bufSize;HEAPU32[__environ+i*4>>2]=ptr;writeAsciiToMemory(string,ptr);bufSize+=string.length+1});return 0}function _environ_sizes_get(penviron_count,penviron_buf_size){var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(function(string){bufSize+=string.length+1});HEAPU32[penviron_buf_size>>2]=bufSize;return 0}function _exit(status){exit(status)}function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function _fd_fdstat_get(fd,pbuf){try{var stream=SYSCALLS.getStreamFromFD(fd);var type=stream.tty?2:FS.isDir(stream.mode)?3:FS.isLink(stream.mode)?7:4;HEAP8[pbuf>>0]=type;return 0}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function doReadv(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){try{var offset=convertI32PairToI53Checked(offset_low,offset_high);if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function doWritev(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i>2];var len=HEAPU32[iov+4>>2];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret}function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=doWritev(stream,iov,iovcnt);HEAPU32[pnum>>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e instanceof FS.ErrnoError))throw e;return e.errno}}function _getTempRet0(){return getTempRet0()}function _setTempRet0(val){setTempRet0(val)}function __isLeapYear(year){return year%4===0&&(year%100!==0||year%400===0)}function __arraySum(array,index){var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum}var __MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var __MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];function __addDays(date,days){var newDate=new Date(date.getTime());while(days>0){var leap=__isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate}function _strftime(s,maxsize,format,tm){var tm_zone=HEAP32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value=="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}else{return thisDate.getFullYear()}}else{return thisDate.getFullYear()-1}}var EXPANSION_RULES_2={"%a":function(date){return WEEKDAYS[date.tm_wday].substring(0,3)},"%A":function(date){return WEEKDAYS[date.tm_wday]},"%b":function(date){return MONTHS[date.tm_mon].substring(0,3)},"%B":function(date){return MONTHS[date.tm_mon]},"%C":function(date){var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":function(date){return leadingNulls(date.tm_mday,2)},"%e":function(date){return leadingSomething(date.tm_mday,2," ")},"%g":function(date){return getWeekBasedYear(date).toString().substring(2)},"%G":function(date){return getWeekBasedYear(date)},"%H":function(date){return leadingNulls(date.tm_hour,2)},"%I":function(date){var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":function(date){return leadingNulls(date.tm_mday+__arraySum(__isLeapYear(date.tm_year+1900)?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,date.tm_mon-1),3)},"%m":function(date){return leadingNulls(date.tm_mon+1,2)},"%M":function(date){return leadingNulls(date.tm_min,2)},"%n":function(){return"\n"},"%p":function(date){if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}else{return"PM"}},"%S":function(date){return leadingNulls(date.tm_sec,2)},"%t":function(){return"\t"},"%u":function(date){return date.tm_wday||7},"%U":function(date){var days=date.tm_yday+7-date.tm_wday;return leadingNulls(Math.floor(days/7),2)},"%V":function(date){var val=Math.floor((date.tm_yday+7-(date.tm_wday+6)%7)/7);if((date.tm_wday+371-date.tm_yday-2)%7<=2){val++}if(!val){val=52;var dec31=(date.tm_wday+7-date.tm_yday-1)%7;if(dec31==4||dec31==5&&__isLeapYear(date.tm_year%400-1)){val++}}else if(val==53){var jan1=(date.tm_wday+371-date.tm_yday)%7;if(jan1!=4&&(jan1!=3||!__isLeapYear(date.tm_year)))val=1}return leadingNulls(val,2)},"%w":function(date){return date.tm_wday},"%W":function(date){var days=date.tm_yday+7-(date.tm_wday+6)%7;return leadingNulls(Math.floor(days/7),2)},"%y":function(date){return(date.tm_year+1900).toString().substring(2)},"%Y":function(date){return date.tm_year+1900},"%z":function(date){var off=date.tm_gmtoff;var ahead=off>=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":function(date){return date.tm_zone},"%%":function(){return"%"}};pattern=pattern.replace(/%%/g,"\0\0");for(var rule in EXPANSION_RULES_2){if(pattern.includes(rule)){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}pattern=pattern.replace(/\0\0/g,"%");var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1}function _system(command){if(ENVIRONMENT_IS_NODE){if(!command)return 1;var cmdstr=UTF8ToString(command);if(!cmdstr.length)return 0;var cp=require("child_process");var ret=cp.spawnSync(cmdstr,[],{shell:true,stdio:"inherit"});var _W_EXITCODE=(ret,sig)=>ret<<8|sig;if(ret.status===null){var signalToNumber=sig=>{switch(sig){case"SIGHUP":return 1;case"SIGINT":return 2;case"SIGQUIT":return 3;case"SIGFPE":return 8;case"SIGKILL":return 9;case"SIGALRM":return 14;case"SIGTERM":return 15}return 2};return _W_EXITCODE(0,signalToNumber(ret.signal))}return _W_EXITCODE(ret.status,0)}if(!command)return 0;setErrNo(52);return-1}var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.staticInit();if(ENVIRONMENT_IS_NODE){requireNodeFS();NODEFS.staticInit()}ERRNO_CODES={"EPERM":63,"ENOENT":44,"ESRCH":71,"EINTR":27,"EIO":29,"ENXIO":60,"E2BIG":1,"ENOEXEC":45,"EBADF":8,"ECHILD":12,"EAGAIN":6,"EWOULDBLOCK":6,"ENOMEM":48,"EACCES":2,"EFAULT":21,"ENOTBLK":105,"EBUSY":10,"EEXIST":20,"EXDEV":75,"ENODEV":43,"ENOTDIR":54,"EISDIR":31,"EINVAL":28,"ENFILE":41,"EMFILE":33,"ENOTTY":59,"ETXTBSY":74,"EFBIG":22,"ENOSPC":51,"ESPIPE":70,"EROFS":69,"EMLINK":34,"EPIPE":64,"EDOM":18,"ERANGE":68,"ENOMSG":49,"EIDRM":24,"ECHRNG":106,"EL2NSYNC":156,"EL3HLT":107,"EL3RST":108,"ELNRNG":109,"EUNATCH":110,"ENOCSI":111,"EL2HLT":112,"EDEADLK":16,"ENOLCK":46,"EBADE":113,"EBADR":114,"EXFULL":115,"ENOANO":104,"EBADRQC":103,"EBADSLT":102,"EDEADLOCK":16,"EBFONT":101,"ENOSTR":100,"ENODATA":116,"ETIME":117,"ENOSR":118,"ENONET":119,"ENOPKG":120,"EREMOTE":121,"ENOLINK":47,"EADV":122,"ESRMNT":123,"ECOMM":124,"EPROTO":65,"EMULTIHOP":36,"EDOTDOT":125,"EBADMSG":9,"ENOTUNIQ":126,"EBADFD":127,"EREMCHG":128,"ELIBACC":129,"ELIBBAD":130,"ELIBSCN":131,"ELIBMAX":132,"ELIBEXEC":133,"ENOSYS":52,"ENOTEMPTY":55,"ENAMETOOLONG":37,"ELOOP":32,"EOPNOTSUPP":138,"EPFNOSUPPORT":139,"ECONNRESET":15,"ENOBUFS":42,"EAFNOSUPPORT":5,"EPROTOTYPE":67,"ENOTSOCK":57,"ENOPROTOOPT":50,"ESHUTDOWN":140,"ECONNREFUSED":14,"EADDRINUSE":3,"ECONNABORTED":13,"ENETUNREACH":40,"ENETDOWN":38,"ETIMEDOUT":73,"EHOSTDOWN":142,"EHOSTUNREACH":23,"EINPROGRESS":26,"EALREADY":7,"EDESTADDRREQ":17,"EMSGSIZE":35,"EPROTONOSUPPORT":66,"ESOCKTNOSUPPORT":137,"EADDRNOTAVAIL":4,"ENETRESET":39,"EISCONN":30,"ENOTCONN":53,"ETOOMANYREFS":141,"EUSERS":136,"EDQUOT":19,"ESTALE":72,"ENOTSUP":138,"ENOMEDIUM":148,"EILSEQ":25,"EOVERFLOW":61,"ECANCELED":11,"ENOTRECOVERABLE":56,"EOWNERDEAD":62,"ESTRPIPE":135};function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var asmLibraryArg={"l":___syscall_fcntl64,"s":___syscall_ftruncate64,"z":___syscall_getcwd,"u":___syscall_getdents64,"r":___syscall_ioctl,"m":___syscall_openat,"y":___syscall_rmdir,"v":___syscall_stat64,"o":___syscall_unlinkat,"i":__emscripten_date_now,"C":__emscripten_get_now_is_monotonic,"x":__emscripten_throw_longjmp,"D":__gmtime_js,"E":__localtime_js,"F":__tzset_js,"h":_emscripten_asm_const_int,"G":_emscripten_memcpy_big,"H":_emscripten_resize_heap,"A":_environ_get,"B":_environ_sizes_get,"f":_exit,"g":_fd_close,"q":_fd_fdstat_get,"k":_fd_read,"t":_fd_seek,"j":_fd_write,"a":_getTempRet0,"d":invoke_ii,"e":invoke_iii,"c":invoke_iiiii,"w":invoke_viiiiiidii,"b":_setTempRet0,"p":_strftime,"n":_system};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["J"]).apply(null,arguments)};var _initwcs=Module["_initwcs"]=function(){return(_initwcs=Module["_initwcs"]=Module["asm"]["K"]).apply(null,arguments)};var _freewcs=Module["_freewcs"]=function(){return(_freewcs=Module["_freewcs"]=Module["asm"]["L"]).apply(null,arguments)};var _wcsinfo=Module["_wcsinfo"]=function(){return(_wcsinfo=Module["_wcsinfo"]=Module["asm"]["M"]).apply(null,arguments)};var _pix2wcsstr=Module["_pix2wcsstr"]=function(){return(_pix2wcsstr=Module["_pix2wcsstr"]=Module["asm"]["N"]).apply(null,arguments)};var _wcs2pixstr=Module["_wcs2pixstr"]=function(){return(_wcs2pixstr=Module["_wcs2pixstr"]=Module["asm"]["O"]).apply(null,arguments)};var _wcssys=Module["_wcssys"]=function(){return(_wcssys=Module["_wcssys"]=Module["asm"]["P"]).apply(null,arguments)};var _wcsunits=Module["_wcsunits"]=function(){return(_wcsunits=Module["_wcsunits"]=Module["asm"]["Q"]).apply(null,arguments)};var _reg2wcsstr=Module["_reg2wcsstr"]=function(){return(_reg2wcsstr=Module["_reg2wcsstr"]=Module["asm"]["R"]).apply(null,arguments)};var _saostrtod=Module["_saostrtod"]=function(){return(_saostrtod=Module["_saostrtod"]=Module["asm"]["S"]).apply(null,arguments)};var _saodtostr=Module["_saodtostr"]=function(){return(_saodtostr=Module["_saodtostr"]=Module["asm"]["T"]).apply(null,arguments)};var _saodtype=Module["_saodtype"]=function(){return(_saodtype=Module["_saodtype"]=Module["asm"]["U"]).apply(null,arguments)};var _zscale=Module["_zscale"]=function(){return(_zscale=Module["_zscale"]=Module["asm"]["V"]).apply(null,arguments)};var _tanhdr=Module["_tanhdr"]=function(){return(_tanhdr=Module["_tanhdr"]=Module["asm"]["W"]).apply(null,arguments)};var _reproject=Module["_reproject"]=function(){return(_reproject=Module["_reproject"]=Module["asm"]["X"]).apply(null,arguments)};var _madd=Module["_madd"]=function(){return(_madd=Module["_madd"]=Module["asm"]["Y"]).apply(null,arguments)};var _imgtbl=Module["_imgtbl"]=function(){return(_imgtbl=Module["_imgtbl"]=Module["asm"]["Z"]).apply(null,arguments)};var _makehdr=Module["_makehdr"]=function(){return(_makehdr=Module["_makehdr"]=Module["asm"]["_"]).apply(null,arguments)};var _shrinkhdr=Module["_shrinkhdr"]=function(){return(_shrinkhdr=Module["_shrinkhdr"]=Module["asm"]["$"]).apply(null,arguments)};var _imsection=Module["_imsection"]=function(){return(_imsection=Module["_imsection"]=Module["asm"]["aa"]).apply(null,arguments)};var _listhdu=Module["_listhdu"]=function(){return(_listhdu=Module["_listhdu"]=Module["asm"]["ba"]).apply(null,arguments)};var _regcnts=Module["_regcnts"]=function(){return(_regcnts=Module["_regcnts"]=Module["asm"]["ca"]).apply(null,arguments)};var _vcat=Module["_vcat"]=function(){return(_vcat=Module["_vcat"]=Module["asm"]["da"]).apply(null,arguments)};var _vls=Module["_vls"]=function(){return(_vls=Module["_vls"]=Module["asm"]["ea"]).apply(null,arguments)};var _openFITSFile=Module["_openFITSFile"]=function(){return(_openFITSFile=Module["_openFITSFile"]=Module["asm"]["fa"]).apply(null,arguments)};var _openFITSMem=Module["_openFITSMem"]=function(){return(_openFITSMem=Module["_openFITSMem"]=Module["asm"]["ga"]).apply(null,arguments)};var _getHeaderToString=Module["_getHeaderToString"]=function(){return(_getHeaderToString=Module["_getHeaderToString"]=Module["asm"]["ha"]).apply(null,arguments)};var _getImageToArray=Module["_getImageToArray"]=function(){return(_getImageToArray=Module["_getImageToArray"]=Module["asm"]["ia"]).apply(null,arguments)};var _filterTableToImage=Module["_filterTableToImage"]=function(){return(_filterTableToImage=Module["_filterTableToImage"]=Module["asm"]["ja"]).apply(null,arguments)};var _closeFITSFile=Module["_closeFITSFile"]=function(){return(_closeFITSFile=Module["_closeFITSFile"]=Module["asm"]["ka"]).apply(null,arguments)};var _maxFITSMemory=Module["_maxFITSMemory"]=function(){return(_maxFITSMemory=Module["_maxFITSMemory"]=Module["asm"]["la"]).apply(null,arguments)};var _ffgerr=Module["_ffgerr"]=function(){return(_ffgerr=Module["_ffgerr"]=Module["asm"]["ma"]).apply(null,arguments)};var _ffmahd=Module["_ffmahd"]=function(){return(_ffmahd=Module["_ffmahd"]=Module["asm"]["na"]).apply(null,arguments)};var _ffghdt=Module["_ffghdt"]=function(){return(_ffghdt=Module["_ffghdt"]=Module["asm"]["oa"]).apply(null,arguments)};var _ffghdn=Module["_ffghdn"]=function(){return(_ffghdn=Module["_ffghdn"]=Module["asm"]["pa"]).apply(null,arguments)};var _ffgisz=Module["_ffgisz"]=function(){return(_ffgisz=Module["_ffgisz"]=Module["asm"]["qa"]).apply(null,arguments)};var _ffmnhd=Module["_ffmnhd"]=function(){return(_ffmnhd=Module["_ffmnhd"]=Module["asm"]["ra"]).apply(null,arguments)};var _ffgky=Module["_ffgky"]=function(){return(_ffgky=Module["_ffgky"]=Module["asm"]["sa"]).apply(null,arguments)};var _fffree=Module["_fffree"]=function(){return(_fffree=Module["_fffree"]=Module["asm"]["ta"]).apply(null,arguments)};var _imannulusi=Module["_imannulusi"]=function(){return(_imannulusi=Module["_imannulusi"]=Module["asm"]["ua"]).apply(null,arguments)};var _imcirclei=Module["_imcirclei"]=function(){return(_imcirclei=Module["_imcirclei"]=Module["asm"]["va"]).apply(null,arguments)};var _imannulus=Module["_imannulus"]=function(){return(_imannulus=Module["_imannulus"]=Module["asm"]["wa"]).apply(null,arguments)};var _imcircle=Module["_imcircle"]=function(){return(_imcircle=Module["_imcircle"]=Module["asm"]["xa"]).apply(null,arguments)};var _imboxi=Module["_imboxi"]=function(){return(_imboxi=Module["_imboxi"]=Module["asm"]["ya"]).apply(null,arguments)};var _imbox=Module["_imbox"]=function(){return(_imbox=Module["_imbox"]=Module["asm"]["za"]).apply(null,arguments)};var _impolygon=Module["_impolygon"]=function(){return(_impolygon=Module["_impolygon"]=Module["asm"]["Aa"]).apply(null,arguments)};var _imellipsei=Module["_imellipsei"]=function(){return(_imellipsei=Module["_imellipsei"]=Module["asm"]["Ba"]).apply(null,arguments)};var _imellipse=Module["_imellipse"]=function(){return(_imellipse=Module["_imellipse"]=Module["asm"]["Ca"]).apply(null,arguments)};var _imfieldi=Module["_imfieldi"]=function(){return(_imfieldi=Module["_imfieldi"]=Module["asm"]["Da"]).apply(null,arguments)};var _imfield=Module["_imfield"]=function(){return(_imfield=Module["_imfield"]=Module["asm"]["Ea"]).apply(null,arguments)};var _imlinei=Module["_imlinei"]=function(){return(_imlinei=Module["_imlinei"]=Module["asm"]["Fa"]).apply(null,arguments)};var _imline=Module["_imline"]=function(){return(_imline=Module["_imline"]=Module["asm"]["Ga"]).apply(null,arguments)};var _impiei=Module["_impiei"]=function(){return(_impiei=Module["_impiei"]=Module["asm"]["Ha"]).apply(null,arguments)};var _impie=Module["_impie"]=function(){return(_impie=Module["_impie"]=Module["asm"]["Ia"]).apply(null,arguments)};var _imqtpiei=Module["_imqtpiei"]=function(){return(_imqtpiei=Module["_imqtpiei"]=Module["asm"]["Ja"]).apply(null,arguments)};var _imqtpie=Module["_imqtpie"]=function(){return(_imqtpie=Module["_imqtpie"]=Module["asm"]["Ka"]).apply(null,arguments)};var _impointi=Module["_impointi"]=function(){return(_impointi=Module["_impointi"]=Module["asm"]["La"]).apply(null,arguments)};var _impoint=Module["_impoint"]=function(){return(_impoint=Module["_impoint"]=Module["asm"]["Ma"]).apply(null,arguments)};var _impolygoni=Module["_impolygoni"]=function(){return(_impolygoni=Module["_impolygoni"]=Module["asm"]["Na"]).apply(null,arguments)};var _imnannulusi=Module["_imnannulusi"]=function(){return(_imnannulusi=Module["_imnannulusi"]=Module["asm"]["Oa"]).apply(null,arguments)};var _imnboxi=Module["_imnboxi"]=function(){return(_imnboxi=Module["_imnboxi"]=Module["asm"]["Pa"]).apply(null,arguments)};var _imnellipsei=Module["_imnellipsei"]=function(){return(_imnellipsei=Module["_imnellipsei"]=Module["asm"]["Qa"]).apply(null,arguments)};var _imnpiei=Module["_imnpiei"]=function(){return(_imnpiei=Module["_imnpiei"]=Module["asm"]["Ra"]).apply(null,arguments)};var _impandai=Module["_impandai"]=function(){return(_impandai=Module["_impandai"]=Module["asm"]["Sa"]).apply(null,arguments)};var _imnannulus=Module["_imnannulus"]=function(){return(_imnannulus=Module["_imnannulus"]=Module["asm"]["Ta"]).apply(null,arguments)};var _imnbox=Module["_imnbox"]=function(){return(_imnbox=Module["_imnbox"]=Module["asm"]["Ua"]).apply(null,arguments)};var _imnellipse=Module["_imnellipse"]=function(){return(_imnellipse=Module["_imnellipse"]=Module["asm"]["Va"]).apply(null,arguments)};var _imnpie=Module["_imnpie"]=function(){return(_imnpie=Module["_imnpie"]=Module["asm"]["Wa"]).apply(null,arguments)};var _impanda=Module["_impanda"]=function(){return(_impanda=Module["_impanda"]=Module["asm"]["Xa"]).apply(null,arguments)};var _imvannulusi=Module["_imvannulusi"]=function(){return(_imvannulusi=Module["_imvannulusi"]=Module["asm"]["Ya"]).apply(null,arguments)};var _imvboxi=Module["_imvboxi"]=function(){return(_imvboxi=Module["_imvboxi"]=Module["asm"]["Za"]).apply(null,arguments)};var _imvellipsei=Module["_imvellipsei"]=function(){return(_imvellipsei=Module["_imvellipsei"]=Module["asm"]["_a"]).apply(null,arguments)};var _imvpiei=Module["_imvpiei"]=function(){return(_imvpiei=Module["_imvpiei"]=Module["asm"]["$a"]).apply(null,arguments)};var _imvpointi=Module["_imvpointi"]=function(){return(_imvpointi=Module["_imvpointi"]=Module["asm"]["ab"]).apply(null,arguments)};var _imvannulus=Module["_imvannulus"]=function(){return(_imvannulus=Module["_imvannulus"]=Module["asm"]["bb"]).apply(null,arguments)};var _imvbox=Module["_imvbox"]=function(){return(_imvbox=Module["_imvbox"]=Module["asm"]["cb"]).apply(null,arguments)};var _imvellipse=Module["_imvellipse"]=function(){return(_imvellipse=Module["_imvellipse"]=Module["asm"]["db"]).apply(null,arguments)};var _imvpie=Module["_imvpie"]=function(){return(_imvpie=Module["_imvpie"]=Module["asm"]["eb"]).apply(null,arguments)};var _imvpoint=Module["_imvpoint"]=function(){return(_imvpoint=Module["_imvpoint"]=Module["asm"]["fb"]).apply(null,arguments)};var _gzclose=Module["_gzclose"]=function(){return(_gzclose=Module["_gzclose"]=Module["asm"]["gb"]).apply(null,arguments)};var _gzopen=Module["_gzopen"]=function(){return(_gzopen=Module["_gzopen"]=Module["asm"]["hb"]).apply(null,arguments)};var _gzseek=Module["_gzseek"]=function(){return(_gzseek=Module["_gzseek"]=Module["asm"]["ib"]).apply(null,arguments)};var _gzread=Module["_gzread"]=function(){return(_gzread=Module["_gzread"]=Module["asm"]["jb"]).apply(null,arguments)};var _gzwrite=Module["_gzwrite"]=function(){return(_gzwrite=Module["_gzwrite"]=Module["asm"]["kb"]).apply(null,arguments)};var _BZ2_bzopen=Module["_BZ2_bzopen"]=function(){return(_BZ2_bzopen=Module["_BZ2_bzopen"]=Module["asm"]["lb"]).apply(null,arguments)};var _BZ2_bzread=Module["_BZ2_bzread"]=function(){return(_BZ2_bzread=Module["_BZ2_bzread"]=Module["asm"]["mb"]).apply(null,arguments)};var _BZ2_bzwrite=Module["_BZ2_bzwrite"]=function(){return(_BZ2_bzwrite=Module["_BZ2_bzwrite"]=Module["asm"]["nb"]).apply(null,arguments)};var _BZ2_bzclose=Module["_BZ2_bzclose"]=function(){return(_BZ2_bzclose=Module["_BZ2_bzclose"]=Module["asm"]["ob"]).apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){return(___errno_location=Module["___errno_location"]=Module["asm"]["pb"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["qb"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["rb"]).apply(null,arguments)};var _setThrew=Module["_setThrew"]=function(){return(_setThrew=Module["_setThrew"]=Module["asm"]["sb"]).apply(null,arguments)};var stackSave=Module["stackSave"]=function(){return(stackSave=Module["stackSave"]=Module["asm"]["tb"]).apply(null,arguments)};var stackRestore=Module["stackRestore"]=function(){return(stackRestore=Module["stackRestore"]=Module["asm"]["ub"]).apply(null,arguments)};var stackAlloc=Module["stackAlloc"]=function(){return(stackAlloc=Module["stackAlloc"]=Module["asm"]["vb"]).apply(null,arguments)};function invoke_viiiiiidii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6,a7,a8,a9)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_iiiii(index,a1,a2,a3,a4){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_ii(index,a1){var sp=stackSave();try{return getWasmTableEntry(index)(a1)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_iii(index,a1,a2){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}Module["ccall"]=ccall;Module["cwrap"]=cwrap;Module["writeArrayToMemory"]=writeArrayToMemory;Module["writeAsciiToMemory"]=writeAsciiToMemory;var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;function exit(status,implicit){EXITSTATUS=status;procExit(status)}function procExit(code){EXITSTATUS=code;if(!keepRuntimeAlive()){if(Module["onExit"])Module["onExit"](code);ABORT=true}quit_(code,new ExitStatus(code))}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run();Module["print"]=function(text){console.log(text)};Module["rootdir"]="/";Module["vfile"]=function(filename,buf,canOwn){let size;if(buf){try{FS.unlink(Module["rootdir"]+filename)}catch(e){}FS.createDataFile(Module["rootdir"],filename,buf,true,true,canOwn);if(buf.length!==undefined){size=buf.length}else if(buf.byteLength!==undefined){size=buf.byteLength}else if(buf.size!==undefined){size=buf.size}else{size=-1}return{path:filename,size:size}}return FS.readFile(Module["rootdir"]+filename,{encoding:"binary"})};Module["vread"]=function(filename,mode){mode=mode||"utf8";return FS.readFile(Module["rootdir"]+filename,{encoding:mode})};Module["vsize"]=function(filename){let buf={size:-1};try{buf=FS.stat(Module["rootdir"]+filename)}catch(e){}return buf.size};Module["vunlink"]=function(filename){try{FS.unlink(Module["rootdir"]+filename)}catch(e){}};Module["vmount"]=function(root,mntpnt){let got=1;try{FS.mkdir(mntpnt);FS.mount(NODEFS,{root:root},mntpnt)}catch(e){got=0;FS.rmdir(mntpnt)}return got};Module["arrfile"]=function(filename,arr){Module["vunlink"](filename);FS.createDataFile(Module["rootdir"],filename,arr,true,true,false);return{path:filename,size:arr.byteLength}};Module["gzcompress"]=function(data){let ret;const gzFile=ccall("gzopen","number",["string","string"],["output.gz","wb"]);const buffer=_malloc(data.length);HEAPU8.set(data,buffer);ccall("gzwrite","number",["number","number","number"],[gzFile,buffer,data.length]);ccall("gzclose","number",["number"],[gzFile]);_free(buffer);ret=new Uint8Array(FS.root.contents["output.gz"].contents);FS.unlink("output.gz");return ret};Module["gzdecompress"]=function(data,filename,canOwn){let i,ret,curr,len,gzFile;let total=0;const BUFSIZE=1024*1024;const buffer=_malloc(BUFSIZE);const chunks=[];FS.createDataFile(Module["rootdir"],"input.gz",data,true,true,false);gzFile=ccall("gzopen","number",["string","string"],["input.gz","rb"]);while(true){len=ccall("gzread","number",["number","number","number"],[gzFile,buffer,BUFSIZE]);if(len<=0){break}chunks.push(new Uint8Array(len));chunks[chunks.length-1].set(HEAPU8.subarray(buffer,buffer+len));total+=len}ccall("gzclose","number",["number"],[gzFile]);FS.unlink("input.gz");_free(buffer);ret=new Uint8Array(total);curr=0;for(i=0;i0?bin:1/Math.abs(bin);hdu.x1=getValue(hptr+24,"i32");hdu.y1=getValue(hptr+28,"i32");hdu.x2=getValue(hptr+40,"i32");hdu.y2=getValue(hptr+44,"i32");hdu.naxis1=Math.floor((hdu.x2-hdu.x1+1)/xbin);hdu.naxis2=Math.floor((hdu.y2-hdu.y1+1)/xbin);hdu.bitpix=getValue(hptr+56,"i32");if(opts.filter){hdu.filter=opts.filter}if(slice){hdu.slice=slice}status=getValue(hptr+60,"i32");_free(hptr);Module["errchk"](status);if(!bufptr||doerr){Module["error"]("can't convert image to array (image too large?)")}datalen=hdu.naxis1*hdu.naxis2;switch(hdu.bitpix){case 8:hdu.image=new Uint8Array(HEAPU8.subarray(bufptr,bufptr+datalen));break;case 16:hdu.image=new Int16Array(HEAP16.subarray(bufptr/2,bufptr/2+datalen));break;case-16:hdu.image=new Uint16Array(HEAPU16.subarray(bufptr/2,bufptr/2+datalen));break;case 32:hdu.image=new Int32Array(HEAP32.subarray(bufptr/4,bufptr/4+datalen));break;case-32:hdu.image=new Float32Array(HEAPF32.subarray(bufptr/4,bufptr/4+datalen));break;case-64:hdu.image=new Float64Array(HEAPF64.subarray(bufptr/8,bufptr/8+datalen));break;default:Module["error"](`${hdu.bitpix}-bit FITS data is not supported`);break}hptr=_malloc(20);setValue(hptr+12,0,"i32");ccall("getHeaderToString",null,["number","number","number","number"],[ofptr,hptr,hptr+8,hptr+12]);hdu.ncard=getValue(hptr+8,"i32");bufptr2=getValue(hptr,"*");buf=new Uint8Array(HEAPU8.subarray(bufptr2,bufptr2+hdu.ncard*80));buflen=buf.byteLength;hdu.cardstr="";for(i=0;i i, .context-menu-icon.context-menu-icon--fa5.context-menu-hover > svg { - color: #fff; -} -.context-menu-icon.context-menu-icon--fa5.context-menu-disabled i, .context-menu-icon.context-menu-icon--fa5.context-menu-disabled svg { - color: #bbb; -} - -.context-menu-list { - position: absolute; - display: inline-block; - min-width: 13em; - max-width: 26em; - padding: .25em 0; - margin: .3em; - font-family: inherit; - font-size: inherit; - list-style-type: none; - background: #fff; - border: 1px solid #bebebe; - border-radius: .2em; - -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, .5); - box-shadow: 0 2px 5px rgba(0, 0, 0, .5); -} - -.context-menu-item { - position: relative; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - padding: .2em 2em; - color: #2f2f2f; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - background-color: #fff; -} - -.context-menu-separator { - padding: 0; - margin: .35em 0; - border-bottom: 1px solid #e6e6e6; -} - -.context-menu-item > label > input, -.context-menu-item > label > textarea { - -webkit-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; -} - -.context-menu-item.context-menu-hover { - color: #fff; - cursor: pointer; - background-color: #2980b9; -} - -.context-menu-item.context-menu-disabled { - color: #bbb; - cursor: default; - background-color: #fff; -} - -.context-menu-input.context-menu-hover { - color: #2f2f2f; - cursor: default; -} - -.context-menu-submenu:after { - position: absolute; - top: 50%; - right: .5em; - z-index: 1; - width: 0; - height: 0; - content: ''; - border-color: transparent transparent transparent #2f2f2f; - border-style: solid; - border-width: .25em 0 .25em .25em; - -webkit-transform: translateY(-50%); - -ms-transform: translateY(-50%); - -o-transform: translateY(-50%); - transform: translateY(-50%); -} - -/** - * Inputs - */ -.context-menu-item.context-menu-input { - padding: .3em .6em; -} - -/* vertically align inside labels */ -.context-menu-input > label > * { - vertical-align: top; -} - -/* position checkboxes and radios as icons */ -.context-menu-input > label > input[type="checkbox"], -.context-menu-input > label > input[type="radio"] { - position: relative; - top: .12em; - margin-right: .4em; -} - -.context-menu-input > label { - margin: 0; -} - -.context-menu-input > label, -.context-menu-input > label > input[type="text"], -.context-menu-input > label > textarea, -.context-menu-input > label > select { - display: block; - width: 100%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -.context-menu-input > label > textarea { - height: 7em; -} - -.context-menu-item > .context-menu-list { - top: .3em; - /* re-positioned by js */ - right: -.3em; - display: none; -} - -.context-menu-item.context-menu-visible > .context-menu-list { - display: block; -} - -.context-menu-accesskey { - text-decoration: underline; -} diff --git a/web/static/js9_old/css/jquery.contextMenu.css b/web/static/js9_old/css/jquery.contextMenu.css deleted file mode 100644 index fa4abd80d1e572f3a4249d5ecc5ff36679ce8c8e..0000000000000000000000000000000000000000 --- a/web/static/js9_old/css/jquery.contextMenu.css +++ /dev/null @@ -1,309 +0,0 @@ -@charset "UTF-8"; -/*! - * jQuery contextMenu - Plugin for simple contextMenu handling - * - * Version: v2.8.0 - * - * Authors: Björn Brala (SWIS.nl), Rodney Rehm, Addy Osmani (patches for FF) - * Web: http://swisnl.github.io/jQuery-contextMenu/ - * - * Copyright (c) 2011-2019 SWIS BV and contributors - * - * Licensed under - * MIT License http://www.opensource.org/licenses/mit-license - * - * Date: 2019-01-16T15:45:48.418Z - */ -@-webkit-keyframes cm-spin { - 0% { - -webkit-transform: translateY(-50%) rotate(0deg); - transform: translateY(-50%) rotate(0deg); - } - 100% { - -webkit-transform: translateY(-50%) rotate(359deg); - transform: translateY(-50%) rotate(359deg); - } -} -@-o-keyframes cm-spin { - 0% { - -webkit-transform: translateY(-50%) rotate(0deg); - -o-transform: translateY(-50%) rotate(0deg); - transform: translateY(-50%) rotate(0deg); - } - 100% { - -webkit-transform: translateY(-50%) rotate(359deg); - -o-transform: translateY(-50%) rotate(359deg); - transform: translateY(-50%) rotate(359deg); - } -} -@keyframes cm-spin { - 0% { - -webkit-transform: translateY(-50%) rotate(0deg); - -o-transform: translateY(-50%) rotate(0deg); - transform: translateY(-50%) rotate(0deg); - } - 100% { - -webkit-transform: translateY(-50%) rotate(359deg); - -o-transform: translateY(-50%) rotate(359deg); - transform: translateY(-50%) rotate(359deg); - } -} - -@font-face { - font-family: "context-menu-icons"; - font-style: normal; - font-weight: normal; - - src: url("font/context-menu-icons.eot?2lkho"); - src: url("font/context-menu-icons.eot?2lkho#iefix") format("embedded-opentype"), url("font/context-menu-icons.woff2?2lkho") format("woff2"), url("font/context-menu-icons.woff?2lkho") format("woff"), url("font/context-menu-icons.ttf?2lkho") format("truetype"); -} - -.context-menu-icon-add:before { - content: "\EA01"; -} - -.context-menu-icon-copy:before { - content: "\EA02"; -} - -.context-menu-icon-cut:before { - content: "\EA03"; -} - -.context-menu-icon-delete:before { - content: "\EA04"; -} - -.context-menu-icon-edit:before { - content: "\EA05"; -} - -.context-menu-icon-loading:before { - content: "\EA06"; -} - -.context-menu-icon-paste:before { - content: "\EA07"; -} - -.context-menu-icon-quit:before { - content: "\EA08"; -} - -.context-menu-icon::before { - position: absolute; - top: 50%; - left: 0; - width: 2em; - font-family: "context-menu-icons"; - font-size: 1em; - font-style: normal; - font-weight: normal; - line-height: 1; - color: #2980b9; - text-align: center; - -webkit-transform: translateY(-50%); - -ms-transform: translateY(-50%); - -o-transform: translateY(-50%); - transform: translateY(-50%); - - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.context-menu-icon.context-menu-hover:before { - color: #fff; -} - -.context-menu-icon.context-menu-disabled::before { - color: #bbb; -} - -.context-menu-icon.context-menu-icon-loading:before { - -webkit-animation: cm-spin 2s infinite; - -o-animation: cm-spin 2s infinite; - animation: cm-spin 2s infinite; -} - -.context-menu-icon.context-menu-icon--fa { - display: list-item; - font-family: inherit; - line-height: inherit; -} -.context-menu-icon.context-menu-icon--fa::before { - position: absolute; - top: 50%; - left: 0; - width: 2em; - font-family: FontAwesome; - font-size: 1em; - font-style: normal; - font-weight: normal; - line-height: 1; - color: #2980b9; - text-align: center; - -webkit-transform: translateY(-50%); - -ms-transform: translateY(-50%); - -o-transform: translateY(-50%); - transform: translateY(-50%); - - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} -.context-menu-icon.context-menu-icon--fa.context-menu-hover:before { - color: #fff; -} -.context-menu-icon.context-menu-icon--fa.context-menu-disabled::before { - color: #bbb; -} - -.context-menu-icon.context-menu-icon--fa5 { - display: list-item; - font-family: inherit; - line-height: inherit; -} -.context-menu-icon.context-menu-icon--fa5 i, .context-menu-icon.context-menu-icon--fa5 svg { - position: absolute; - top: .3em; - left: .5em; - color: #2980b9; -} -.context-menu-icon.context-menu-icon--fa5.context-menu-hover > i, .context-menu-icon.context-menu-icon--fa5.context-menu-hover > svg { - color: #fff; -} -.context-menu-icon.context-menu-icon--fa5.context-menu-disabled i, .context-menu-icon.context-menu-icon--fa5.context-menu-disabled svg { - color: #bbb; -} - -.context-menu-list { - position: absolute; - display: inline-block; - min-width: 13em; - max-width: 26em; - padding: .25em 0; - margin: .3em; - font-family: inherit; - font-size: inherit; - list-style-type: none; - background: #fff; - border: 1px solid #bebebe; - border-radius: .2em; - -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, .5); - box-shadow: 0 2px 5px rgba(0, 0, 0, .5); -} - -.context-menu-item { - position: relative; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - padding: .2em 2em; - color: #2f2f2f; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - background-color: #fff; -} - -.context-menu-separator { - padding: 0; - margin: .35em 0; - border-bottom: 1px solid #e6e6e6; -} - -.context-menu-item > label > input, -.context-menu-item > label > textarea { - -webkit-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; -} - -.context-menu-item.context-menu-hover { - color: #fff; - cursor: pointer; - background-color: #2980b9; -} - -.context-menu-item.context-menu-disabled { - color: #bbb; - cursor: default; - background-color: #fff; -} - -.context-menu-input.context-menu-hover { - color: #2f2f2f; - cursor: default; -} - -.context-menu-submenu:after { - position: absolute; - top: 50%; - right: .5em; - z-index: 1; - width: 0; - height: 0; - content: ''; - border-color: transparent transparent transparent #2f2f2f; - border-style: solid; - border-width: .25em 0 .25em .25em; - -webkit-transform: translateY(-50%); - -ms-transform: translateY(-50%); - -o-transform: translateY(-50%); - transform: translateY(-50%); -} - -/** - * Inputs - */ -.context-menu-item.context-menu-input { - padding: .3em .6em; -} - -/* vertically align inside labels */ -.context-menu-input > label > * { - vertical-align: top; -} - -/* position checkboxes and radios as icons */ -.context-menu-input > label > input[type="checkbox"], -.context-menu-input > label > input[type="radio"] { - position: relative; - top: .12em; - margin-right: .4em; -} - -.context-menu-input > label { - margin: 0; -} - -.context-menu-input > label, -.context-menu-input > label > input[type="text"], -.context-menu-input > label > textarea, -.context-menu-input > label > select { - display: block; - width: 100%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -.context-menu-input > label > textarea { - height: 7em; -} - -.context-menu-item > .context-menu-list { - top: .3em; - /* re-positioned by js */ - right: -.3em; - display: none; -} - -.context-menu-item.context-menu-visible > .context-menu-list { - display: block; -} - -.context-menu-accesskey { - text-decoration: underline; -} diff --git a/web/static/js9_old/css/spectrum.css b/web/static/js9_old/css/spectrum.css deleted file mode 100644 index a8ad9e4f82ff5f9737ba1fdb7d23ea1acdc9d0d3..0000000000000000000000000000000000000000 --- a/web/static/js9_old/css/spectrum.css +++ /dev/null @@ -1,507 +0,0 @@ -/*** -Spectrum Colorpicker v1.8.0 -https://github.com/bgrins/spectrum -Author: Brian Grinstead -License: MIT -***/ - -.sp-container { - position:absolute; - top:0; - left:0; - display:inline-block; - *display: inline; - *zoom: 1; - /* https://github.com/bgrins/spectrum/issues/40 */ - z-index: 9999994; - overflow: hidden; -} -.sp-container.sp-flat { - position: relative; -} - -/* Fix for * { box-sizing: border-box; } */ -.sp-container, -.sp-container * { - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; -} - -/* http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio */ -.sp-top { - position:relative; - width: 100%; - display:inline-block; -} -.sp-top-inner { - position:absolute; - top:0; - left:0; - bottom:0; - right:0; -} -.sp-color { - position: absolute; - top:0; - left:0; - bottom:0; - right:20%; -} -.sp-hue { - position: absolute; - top:0; - right:0; - bottom:0; - left:84%; - height: 100%; -} - -.sp-clear-enabled .sp-hue { - top:33px; - height: 77.5%; -} - -.sp-fill { - padding-top: 80%; -} -.sp-sat, .sp-val { - position: absolute; - top:0; - left:0; - right:0; - bottom:0; -} - -.sp-alpha-enabled .sp-top { - margin-bottom: 18px; -} -.sp-alpha-enabled .sp-alpha { - display: block; -} -.sp-alpha-handle { - position:absolute; - top:-4px; - bottom: -4px; - width: 6px; - left: 50%; - cursor: pointer; - border: 1px solid black; - background: white; - opacity: .8; -} -.sp-alpha { - display: none; - position: absolute; - bottom: -14px; - right: 0; - left: 0; - height: 8px; -} -.sp-alpha-inner { - border: solid 1px #333; -} - -.sp-clear { - display: none; -} - -.sp-clear.sp-clear-display { - background-position: center; -} - -.sp-clear-enabled .sp-clear { - display: block; - position:absolute; - top:0px; - right:0; - bottom:0; - left:84%; - height: 28px; -} - -/* Don't allow text selection */ -.sp-container, .sp-replacer, .sp-preview, .sp-dragger, .sp-slider, .sp-alpha, .sp-clear, .sp-alpha-handle, .sp-container.sp-dragging .sp-input, .sp-container button { - -webkit-user-select:none; - -moz-user-select: -moz-none; - -o-user-select:none; - user-select: none; -} - -.sp-container.sp-input-disabled .sp-input-container { - display: none; -} -.sp-container.sp-buttons-disabled .sp-button-container { - display: none; -} -.sp-container.sp-palette-buttons-disabled .sp-palette-button-container { - display: none; -} -.sp-palette-only .sp-picker-container { - display: none; -} -.sp-palette-disabled .sp-palette-container { - display: none; -} - -.sp-initial-disabled .sp-initial { - display: none; -} - - -/* Gradients for hue, saturation and value instead of images. Not pretty... but it works */ -.sp-sat { - background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#FFF), to(rgba(204, 154, 129, 0))); - background-image: -webkit-linear-gradient(left, #FFF, rgba(204, 154, 129, 0)); - background-image: -moz-linear-gradient(left, #fff, rgba(204, 154, 129, 0)); - background-image: -o-linear-gradient(left, #fff, rgba(204, 154, 129, 0)); - background-image: -ms-linear-gradient(left, #fff, rgba(204, 154, 129, 0)); - background-image: linear-gradient(to right, #fff, rgba(204, 154, 129, 0)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)"; - filter : progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr='#FFFFFFFF', endColorstr='#00CC9A81'); -} -.sp-val { - background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0))); - background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0)); - background-image: -moz-linear-gradient(bottom, #000, rgba(204, 154, 129, 0)); - background-image: -o-linear-gradient(bottom, #000, rgba(204, 154, 129, 0)); - background-image: -ms-linear-gradient(bottom, #000, rgba(204, 154, 129, 0)); - background-image: linear-gradient(to top, #000, rgba(204, 154, 129, 0)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)"; - filter : progid:DXImageTransform.Microsoft.gradient(startColorstr='#00CC9A81', endColorstr='#FF000000'); -} - -.sp-hue { - background: -moz-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); - background: -ms-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); - background: -o-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); - background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000)); - background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); - background: linear-gradient(to bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); -} - -/* IE filters do not support multiple color stops. - Generate 6 divs, line them up, and do two color gradients for each. - Yes, really. - */ -.sp-1 { - height:17%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000', endColorstr='#ffff00'); -} -.sp-2 { - height:16%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff00', endColorstr='#00ff00'); -} -.sp-3 { - height:17%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ff00', endColorstr='#00ffff'); -} -.sp-4 { - height:17%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffff', endColorstr='#0000ff'); -} -.sp-5 { - height:16%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0000ff', endColorstr='#ff00ff'); -} -.sp-6 { - height:17%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff', endColorstr='#ff0000'); -} - -.sp-hidden { - display: none !important; -} - -/* Clearfix hack */ -.sp-cf:before, .sp-cf:after { content: ""; display: table; } -.sp-cf:after { clear: both; } -.sp-cf { *zoom: 1; } - -/* Mobile devices, make hue slider bigger so it is easier to slide */ -@media (max-device-width: 480px) { - .sp-color { right: 40%; } - .sp-hue { left: 63%; } - .sp-fill { padding-top: 60%; } -} -.sp-dragger { - border-radius: 5px; - height: 5px; - width: 5px; - border: 1px solid #fff; - background: #000; - cursor: pointer; - position:absolute; - top:0; - left: 0; -} -.sp-slider { - position: absolute; - top:0; - cursor:pointer; - height: 3px; - left: -1px; - right: -1px; - border: 1px solid #000; - background: white; - opacity: .8; -} - -/* -Theme authors: -Here are the basic themeable display options (colors, fonts, global widths). -See http://bgrins.github.io/spectrum/themes/ for instructions. -*/ - -.sp-container { - border-radius: 0; - background-color: #ECECEC; - border: solid 1px #f0c49B; - padding: 0; -} -.sp-container, .sp-container button, .sp-container input, .sp-color, .sp-hue, .sp-clear { - font: normal 12px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - -ms-box-sizing: border-box; - box-sizing: border-box; -} -.sp-top { - margin-bottom: 3px; -} -.sp-color, .sp-hue, .sp-clear { - border: solid 1px #666; -} - -/* Input */ -.sp-input-container { - float:right; - width: 100px; - margin-bottom: 4px; -} -.sp-initial-disabled .sp-input-container { - width: 100%; -} -.sp-input { - font-size: 12px !important; - border: 1px inset; - padding: 4px 5px; - margin: 0; - width: 100%; - background:transparent; - border-radius: 3px; - color: #222; -} -.sp-input:focus { - border: 1px solid orange; -} -.sp-input.sp-validation-error { - border: 1px solid red; - background: #fdd; -} -.sp-picker-container , .sp-palette-container { - float:left; - position: relative; - padding: 10px; - padding-bottom: 300px; - margin-bottom: -290px; -} -.sp-picker-container { - width: 172px; - border-left: solid 1px #fff; -} - -/* Palettes */ -.sp-palette-container { - border-right: solid 1px #ccc; -} - -.sp-palette-only .sp-palette-container { - border: 0; -} - -.sp-palette .sp-thumb-el { - display: block; - position:relative; - float:left; - width: 24px; - height: 15px; - margin: 3px; - cursor: pointer; - border:solid 2px transparent; -} -.sp-palette .sp-thumb-el:hover, .sp-palette .sp-thumb-el.sp-thumb-active { - border-color: orange; -} -.sp-thumb-el { - position:relative; -} - -/* Initial */ -.sp-initial { - float: left; - border: solid 1px #333; -} -.sp-initial span { - width: 30px; - height: 25px; - border:none; - display:block; - float:left; - margin:0; -} - -.sp-initial .sp-clear-display { - background-position: center; -} - -/* Buttons */ -.sp-palette-button-container, -.sp-button-container { - float: right; -} - -/* Replacer (the little preview div that shows up instead of the ) */ -.sp-replacer { - margin:0; - overflow:hidden; - cursor:pointer; - padding: 4px; - display:inline-block; - *zoom: 1; - *display: inline; - border: solid 1px #91765d; - background: #eee; - color: #333; - vertical-align: middle; -} -.sp-replacer:hover, .sp-replacer.sp-active { - border-color: #F0C49B; - color: #111; -} -.sp-replacer.sp-disabled { - cursor:default; - border-color: silver; - color: silver; -} -.sp-dd { - padding: 2px 0; - height: 16px; - line-height: 16px; - float:left; - font-size:10px; -} -.sp-preview { - position:relative; - width:25px; - height: 20px; - border: solid 1px #222; - margin-right: 5px; - float:left; - z-index: 0; -} - -.sp-palette { - *width: 220px; - max-width: 220px; -} -.sp-palette .sp-thumb-el { - width:16px; - height: 16px; - margin:2px 1px; - border: solid 1px #d0d0d0; -} - -.sp-container { - padding-bottom:0; -} - - -/* Buttons: http://hellohappy.org/css3-buttons/ */ -.sp-container button { - background-color: #eeeeee; - background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc); - background-image: -moz-linear-gradient(top, #eeeeee, #cccccc); - background-image: -ms-linear-gradient(top, #eeeeee, #cccccc); - background-image: -o-linear-gradient(top, #eeeeee, #cccccc); - background-image: linear-gradient(to bottom, #eeeeee, #cccccc); - border: 1px solid #ccc; - border-bottom: 1px solid #bbb; - border-radius: 3px; - color: #333; - font-size: 14px; - line-height: 1; - padding: 5px 4px; - text-align: center; - text-shadow: 0 1px 0 #eee; - vertical-align: middle; -} -.sp-container button:hover { - background-color: #dddddd; - background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb); - background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb); - background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb); - background-image: -o-linear-gradient(top, #dddddd, #bbbbbb); - background-image: linear-gradient(to bottom, #dddddd, #bbbbbb); - border: 1px solid #bbb; - border-bottom: 1px solid #999; - cursor: pointer; - text-shadow: 0 1px 0 #ddd; -} -.sp-container button:active { - border: 1px solid #aaa; - border-bottom: 1px solid #888; - -webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; - -moz-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; - -ms-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; - -o-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; - box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; -} -.sp-cancel { - font-size: 11px; - color: #d93f3f !important; - margin:0; - padding:2px; - margin-right: 5px; - vertical-align: middle; - text-decoration:none; - -} -.sp-cancel:hover { - color: #d93f3f !important; - text-decoration: underline; -} - - -.sp-palette span:hover, .sp-palette span.sp-thumb-active { - border-color: #000; -} - -.sp-preview, .sp-alpha, .sp-thumb-el { - position:relative; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==); -} -.sp-preview-inner, .sp-alpha-inner, .sp-thumb-inner { - display:block; - position:absolute; - top:0;left:0;bottom:0;right:0; -} - -.sp-palette .sp-thumb-inner { - background-position: 50% 50%; - background-repeat: no-repeat; -} - -.sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=); -} - -.sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=); -} - -.sp-clear-display { - background-repeat:no-repeat; - background-position: center; - background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==); -} diff --git a/web/static/js9_old/css/tabcontent.css b/web/static/js9_old/css/tabcontent.css deleted file mode 100644 index 7c4306d75ff8e9314cc0319f6eaf1009a8a7732a..0000000000000000000000000000000000000000 --- a/web/static/js9_old/css/tabcontent.css +++ /dev/null @@ -1,176 +0,0 @@ -/* ######### CSS for Shade Tabs. Remove if not using ######### */ - -.shadetabs{ -padding: 3px 0; -margin-left: 0; -margin-top: 1px; -margin-bottom: 0; -font: bold 12px Verdana; -list-style-type: none; -text-align: left; /*set to left, center, or right to align the menu as desired*/ -} - -.shadetabs li{ -display: inline; -margin: 0; -} - -.shadetabs li a{ -text-decoration: none; -position: relative; -z-index: 1; -padding: 3px 7px; -margin-right: 3px; -border: 1px solid #778; -color: #2d2b2b; -background: white url(images/shade.gif) top left repeat-x; -} - -.shadetabs li a:visited{ -color: #2d2b2b; -} - -.shadetabs li a:hover{ -text-decoration: underline; -color: #2d2b2b; -} - -.shadetabs li a.selected{ /*selected main tab style */ -position: relative; -top: 1px; -} - -.shadetabs li a.selected{ /*selected main tab style */ -background-image: url(images/shadeactive.gif); -border-bottom-color: white; -} - -.shadetabs li a.selected:hover{ /*selected main tab style */ -text-decoration: none; -} - -.tabcontent{ -display:none; -} - -@media print { -.tabcontent { -display:block !important; -} -} - -/* ######### CSS for Inverted Modern Bricks II Tabs. Remove if not using ######### */ - -.modernbricksmenu2{ -padding: 0; -width: 362px; -border-top: 5px solid #D25A0B; /*Brown color theme*/ -background: transparent; -voice-family: "\"}\""; -voice-family: inherit; -} - -.modernbricksmenu2 ul{ -margin:0; -margin-left: 10px; /*margin between first menu item and left browser edge*/ -padding: 0; -list-style: none; -} - -.modernbricksmenu2 li{ -display: inline; -margin: 0 2px 0 0; -padding: 0; -text-transform:uppercase; -} - -.modernbricksmenu2 a{ -float: left; -display: block; -font: bold 11px Arial; -color: white; -text-decoration: none; -margin: 0 1px 0 0; /*Margin between each menu item*/ -padding: 5px 10px; -background-color: black; /*Brown color theme*/ -border-top: 1px solid white; -} - -.modernbricksmenu2 a:hover{ -background-color: #D25A0B; /*Brown color theme*/ -color: white; -} - -.modernbricksmenu2 a.selected{ /*currently selected tab*/ -background-color: #D25A0B; /*Brown color theme*/ -color: white; -border-color: #D25A0B; /*Brown color theme*/ -} - -.tabcontent{ -display:none; -} - -@media print { -.tabcontent { -display:block !important; -} -} - -/* ######### CSS for Indented CSS Tabs. Remove if not using ######### */ - - -.indentmenu{ -font: bold 13px Arial; -width: 100%; /*leave this value as is in most cases*/ -} - -.indentmenu ul{ -margin: 0; -padding: 0; -float: left; -/* width: 80%; width of menu*/ -border-top: 1px solid navy; /*navy border*/ -background: black url(images/indentbg.gif) center center repeat-x; -} - -.indentmenu ul li{ -display: inline; -} - -.indentmenu ul li a{ -float: left; -color: white; /*text color*/ -padding: 5px 11px; -text-decoration: none; -border-right: 1px solid navy; /*navy divider between menu items*/ -} - -.indentmenu ul li a:visited{ -color: white; -} - -.indentmenu ul li a.selected{ -color: white !important; -padding-top: 6px; /*shift text down 1px*/ -padding-bottom: 4px; -background: black url(images/indentbg2.gif) center center repeat-x; -} - - -.tabcontentstyle{ /*style of tab content oontainer*/ -border: 1px solid gray; -width: 450px; -margin-bottom: 1em; -padding: 10px; -} - -.tabcontent{ -display:none; -} - -@media print { -.tabcontent { -display:block !important; -} -} diff --git a/web/static/js9_old/favicon.ico b/web/static/js9_old/favicon.ico deleted file mode 100644 index 8636d9b26b6a3a84cbd73ebf4b7e1c859f0001fe..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/favicon.ico and /dev/null differ diff --git a/web/static/js9_old/font/context-menu-icons.eot b/web/static/js9_old/font/context-menu-icons.eot deleted file mode 100644 index 9bedb88428917382857af90d0225a26d4bcbda5f..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/font/context-menu-icons.eot and /dev/null differ diff --git a/web/static/js9_old/font/context-menu-icons.ttf b/web/static/js9_old/font/context-menu-icons.ttf deleted file mode 100644 index 175ff5cea64ebdf965ec91e18ad06999e9549be0..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/font/context-menu-icons.ttf and /dev/null differ diff --git a/web/static/js9_old/font/context-menu-icons.woff b/web/static/js9_old/font/context-menu-icons.woff deleted file mode 100644 index a9a7618a1866811ddf595b4bd3e8cba12a7988e8..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/font/context-menu-icons.woff and /dev/null differ diff --git a/web/static/js9_old/font/context-menu-icons.woff2 b/web/static/js9_old/font/context-menu-icons.woff2 deleted file mode 100644 index b914efeddde2b5bc405469e7c9aa01b658be3f34..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/font/context-menu-icons.woff2 and /dev/null differ diff --git a/web/static/js9_old/help/archives.html b/web/static/js9_old/help/archives.html deleted file mode 100644 index 5a244d96fd404dcca044c33eef0e36ac932869ba..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/archives.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - -Accessing Data Archives with JS9 - - -

-
-

Accessing Data Archives with JS9

- -JS9 can display data in any astronomical archive where a query -produces a downloadable URL to a FITS file. The load proxy mechanism -is used, so accessing archives assumes that the JS9 web site has been -configured to support proxy loads. - -

Examples of data archives that generate FITS URLS for use with JS9

-
    -
  • NASA/HEASARC Browse: in the Browse Query Results, the D option ("Preview data products for this row") in the Services column will give FITS URLs. -
  • NASA/HEASARC SkyView: in the search results, copy the FITS URL from the Download FITS or quick look jpeg image option. -
  • The Unofficial Chandra Archive: in the search results, drag the Title url onto a JS9 display to retrieve a representation image backed by the event file (for server-side analysis) or click ObsId to get the Chandra HTTP directory for this observation. The *.evt2.fits.gz file contains the raw event data. -
- -

Summary: how to access data archives with JS9

-
    -
  • visit a data archive web page in your browser -
  • execute a search for the desired observation (e.g., type in 'M87' or 'Crab Nebula' in the Chandra Archive's Name box listed above) -
  • once the link to a FITS file has been created: -
      -
    • drag and drop the FITS link onto your JS9 display -
    -
  • or: -
      -
    • copy the resulting FITS file link -
    • in JS9, select the File:open link via proxy ... menu option -
    • paste the FITS URL link into the dialog box -
    • click the Load button -
    -
- -

Details: using a proxy server to access data archives

-

-For security reasons, JavaScript contained in one web page can -access data in another web page only if both web pages have the -same origin (i.e., basically coming from the same host). This -policy is called the - -Same Origin Policy. This means that JS9 cannot load a FITS file from -an arbitrary URL without using special techniques. -

-One such technique is to use a proxy server: the URL is not loaded -directly into JS9, but instead is copied back to the server from which -JS9 itself was loaded. The file is then retrieved by JS9 so that the -"same origin" rules are not violated. -

-When the back-end server associated with a JS9 web page supports the -proxy service, you will see a menu option in the File menu -called open link via proxy ... -

-Enter a FITS URL into the proxy dialog box and press the Load -button. The data file will be retrieved by the server and stored in a -directory specifically tied to the web page. (The directory and its -contents will be deleted when the page is unloaded.) JS9 then will -load the file from this directory. Note that since the file resides on -the back-end server, all back-end analysis defined on that server is -available. -

-You also can drag and drop the link directly onto the JS9 display. -The open link via proxy ... menu option is mentioned first, -because it can sometimes require less dexterity (e.g., the archive web -page is displayed on a different desktop from JS9) and also because it -contains a visual cue regarding proxy loads: the option will be greyed -out if JS9 has not been configured to allow proxy loads. -

-This proxy load technique can also be used FITS links from other -sources. For example, if you have a FITS file on Google Drive, iCloud, -Dropbox or even a static web page, you can generate/copy the link and -paste it into the proxy dialog box for display. (Dropbox files also -can utilize the open link via CORS ... option, which downloads -the data directly to JS9, bypassing the proxy server.) - -

Last updated: August 6, 2021
-
- - - diff --git a/web/static/js9_old/help/changelog.html b/web/static/js9_old/help/changelog.html deleted file mode 100644 index 1a97fac9ded683d91c11146c6e284d4db9dcfa9c..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/changelog.html +++ /dev/null @@ -1,934 +0,0 @@ - - - - - -JS9 ChangeLog - - - -
-

JS9 ChangeLog

- -

Public Release 3.8 (June 21, 2022)

-
    -
  • fix bug preventing flip, rotate, rot90 from working in Load() opts -
  • update emscripten to v3.1.13 -
  • update socket.io to v4.5.1 -
  • update astroem/cfitsio library to v4.1.0 -
- -

Public Release 3.7 (May 16, 2022)

-
    -
  • add color change option to shape layers plugin -
  • ?renamedisplay=[old:]new will rename a display when loading the web page -
  • add experimental support for getting remote FITS URLs via CGI-based proxy -
  • add cgi proxy support to 'load remote ...' dialog box -
  • drag/drop url will try cgi proxy if proxy server is not available -
  • js9.js: private sockopts to JS9.socketioOpts to support user configuration -
  • js9Helper: helperOpts to socketioOpts, use Object.assign to merge obj prefs -
  • make cubecol's id more akin to a filename (i.e., without parens) -
  • remove gz:: and bz:: from saved virtual filename -
  • evcube: generated cube file cannot be a gzip'ed file (re: cfitsio) -
  • when saving a section, use the real section instead of recalculating it -
  • fix bug changing position of a selected region after pan/zoom/flip -
  • fix regions bug where stack order (send to back) was reset after pan/zoom -
  • fix bug changing position of a selected region after pan/zoom/flip -
  • fix bugs in handling text children of grouped regions -
  • fix bug when saving one slice of a cube, naxis was not always set to 2 -
  • astroem: rearrange a few source files -
  • add Quit() public access routine (Desktop app only) -
  • es6: use for( key of Object.keys(opts) ){ ... where possible -
  • es6: change a few functions to arrow functions -
  • update astroem/post.js to es6 to match emscripten v3.1.x -
  • update emscripten to v3.1.10 -
  • update socket.io to v4.5.0 -
  • update fabric.js to v5.2.1 -
- -

Patch Release 3.6.2 (January 3, 2022)

-
    -
  • add experimental support for converting event tables to 3D cubes -
  • add Counts in Each Cube Slice analysis task for files with NAXIS == 3 -
  • optimize psList search for js9 helper -
  • add UI to change val/pos display color -
  • region editor: fix annulus edit (width, dashes not always processed) -
  • improve smoke tests -
  • update emscripten to v3.0.0 -
  • update socket.io to v4.4.0 -
  • update fabric.js to v4.6.0 -
  • update open to v8.4.0 -
- -

Patch Release 3.6.1 (August 16, 2021)

-
    -
  • fix various problems with placement of panner rectangle -
  • edit annuli: don't multiply by scale factor when generating circles -
  • update astroem/cfitsio library to v4.0.0 -
- -

Public Release 3.6 (July 30, 2021)

-
    -
  • globalOpts.arrowIncrement: parameterize increment used by arrow keys -
  • selectShapes: if selecting a single shape, don't make a group selection -
  • add support for fabricOpts in js9prefs.js -
  • fix display of rotated non-square image in a non-square display -
  • fix bug that allowed arrow keys to move locked regions -
  • fix regression when adding/removing polygon points -
  • improve support for proxying js9 helper through a web server -
  • change the size of annulus region annuli graphically (meta-click to edit) -
  • change annulus defaults from 2 rings (0->15,15->30) to 1 ring (15->30) -
  • globalOpts.editRegions controls GUI region editing (def: true) -
  • fix magnifier jitter when moving a region with the arrow keys -
  • changeShapes: fix v3.4 regression that sometimes changed annuli incorrectly -
  • rearrange npm modules by uninstalling and installing socket.io -
  • clean up emscripten init in preparation for worker-based experiments -
  • update open to v8.2.1 -
  • update fabric.js to v4.5.1 -
  • update socket.io to v4.1.2 -
  • update emscripten to v2.0.26 -
- -

Public Release 3.5 (June 1, 2021)

-
    -
  • remove the long-deprecated fits2png code -
  • fix bug in js9helper sometimes preventing fits2fits size check -
  • add support for displaying the actual png/jpeg image ("overlay" param) -
  • add overlay parameter to preferences plugin -
  • add reset to image filter plugin (overlays can't reset via contrast/bias) -
  • optimize static colormap cell lookup using binary search -
  • fix bug in JS9.eventToCharStr assigning 46 to delete instead of a dot -
  • js9prefs.js: add support for a config object to allow merging obj prefs -
  • update emscripten to v2.0.23 -
- -

Public Release 3.4 (May 5, 2021)

-
    -
  • maintain selection when switching between images, panning/zooming images -
  • ensure infobox displays correctly formatted val string -
  • add support for bitpix == 64 FITS data -
  • reg2wcsstr should not perform size calculation, use "cdelt" instead -
  • changing a region now shows immediately in the magnifier -
  • push unchangeable regions to back of fabric stack -
  • add 'locked' as opposite alias to 'changeable' for locking regions -
  • add support for 'locked' in region editor -
  • add support for binning tables on alt columns -
  • make mouseTouchZoom global instead of tied to a display -
  • turn off clickToFocus by default, way too many clicks (e.g. using menus) -
  • GetImage: don't throw if named image not available (return null instead) -
  • changing a region now shows immediately in the magnifier -
  • region editor now permits parent to change child's text -
  • changeShapes syncs child text color to main color (via regSyncTextColor) -
  • getShapes: now returns shapes in order in which they were loaded -
  • loadproxy: add support for ms-dos gzip files -
  • handle Infinity when getting scale min,max -
  • js9helper: change html error message to avoid 'Invalid character' error -
  • parameterize direction of mouse wheel zoom -
  • add skip factor to wheel zoom to avoid pileup -
  • globalOpts.mousetouchLimit limits zoom-out to size of image (def: true) -
  • don't display regions when GUI zooming an image with many (>500) regions -
  • don't display regions when GUI panning an image with many (>500) regions -
  • redesign region multi-selection dialog box to support groups -
  • add JS9.GroupRegions() and JS9.UngroupRegions() public routines -
  • add JS9.GroupShapes() and JS9.UngroupShapes() public routines -
  • add JS9.ListGroups() public routine -
  • add JS9.UnselectRegions() and JS9.UnselectShapes() public routines -
  • extend shape (region) selections to support boolean expressions (&&,||,!) -
  • add "onarrowkey" event for plugins, enable its use with pixel table plugin -
  • prefs: only save schema props (e.g. not all globalOpts when saving globals) -
  • fix regression in js9helper limiting size of file transfer -
  • remove support for fabric.js v1, it's ancient and incompatible with groups -
  • add deepscan.io checks when pushing to repository -
  • update eslint to 7.21.0 and make it happy -
  • update socket.io 3.1.2, then 4.0.1, remove 2.4.1 (now supported by v3+) -
  • update npm dependencies: uuid, rimraf, open, ps-node, table-parser -
  • update emscripten to v2.0.18 -
- -

Patch Release 3.3.1 (December 15, 2020)

-
    -
  • fix old bug appending "//" to helperProtocol, even if present (breaks socket.io when saving prefs) -
  • add regMenuCreate property to prefs plugin, remove useless regConfigSize -
- -

Public Release 3.3 (December 14, 2020)

-
    -
  • listRegions: add format='regions' to parallel saveRegions output -
  • regions config: change color, width, pattern as colorpicker, menus change -
  • regions: fix regression when panning a grouped polygon or line -
  • js9Helper: fix regression in uploading FITS files -
  • fix bug to re-establish focus on js9 display after clipboard copy -
  • js9worker: worker socketio connection can now be restarted automatically -
  • update emscripten to v2.0.10 -
  • add support for socket.io v3.0.3, while maintaining support for v2 -
  • update fabric.js to v4.2.0 -
- -

Public Release 3.2 (November 6, 2020, a day of hope)

-
    -
  • add js9 shell scripting and desktop hostfs smoke tests -
  • add checks on filename and id to guard against xss attack -
  • add js9msg script to send messages using wget or curl (node not required) -
  • js9 script will now use faster js9msg script, if appropriate -
  • make JS9's returned data consistent between js9Msg.js, js9Helper.js httpd -
  • allow --with-cfitsio (without a dir arg) if lib is in a system dir -
  • desktop: add dialog box for exported script -
  • desktop: in script, look for webpage in current dir, then in install dir -
  • desktop: pass resize info if specified width or height is <= 0 -
  • desktop: save cmdline opts on close (use same width, height next time) -
  • fix problems passing very large FITS headers (> approx. 1Mb) to initwcs() -
  • fix regression in desktop when using default web page -
  • fix regression in mouseup cb: updateShapes mode is "update", not "mouseup" -
  • various changes to generate Linux desktop app as well as macOS app -
  • js9Electron.js: add support for js9Electron.json file -
  • add support for editing cmd line opts in preferences plugin -
  • refactor desktop app to support editing cmd line opts -
  • modify js/FileSaver.js so that Jupyter notebooks put saveAs() on window -
  • update FileSaver.js to 2.0.4 -
  • update emscripten to 2.0.5 -
- -

Public Release 3.1 (September 8, 2020)

-
    -
  • regions menu: list, remove act on selected or all regions -
  • edit menu: edit, copy act on selected or all regions -
  • add GUI inputs to configure style (color, strokewidth, stroke pattern) -
  • add selection criteria input to multi-selection dialog -
  • add SelectShapes() and SelectRegions() public routines -
  • console plugin can now execute public routines -
  • add ability to turn off auto-create of regions from the Regions menu -
  • 'a' key creates a region using the last one selected from Regions menu -
  • set globalOpts.regionsToClipboard to false (breaks copy selected support) -
  • display (screen) coords can be specified prefixing 'd' to x, y -
  • display coords can be preserved by specifying preservedcoords property -
  • view menu option to show display coords in val/pos string in image sys -
  • add JS9.DisplayNextImage() public access routine -
  • add 'sticky' property to regions (no change on pan, zoom, rotate, flip) -
  • refactor dataminmax, mkColorData to avoid Chrome multi-sec delays in for loops -
  • add support for rotating to North Is Up in current wcssys in SetRotate("northisup") -
  • add north is up rotation to Zoom menu and zoomcontrols dialog -
  • rotate/flip panner image as displayed image rotates/flips -
  • N/E marker now tracks current wcssys, not file's wcssys -
  • JS9.SetFlip(), JS9.SetRot90() use transform instead of changing image data -
  • add JS9.SetRotation(), JS9.GetRotation() to rotate image by arbitrary angle -
  • add JS9.ChangeRegionTags() public routine to add/remove region tags -
  • reorganize github site (new build directory, src in src, demos in demos) -
  • make install does not load demos, use make install-demos explicitly -
  • remove deprecated fitsy code from top level -
  • add JS9.ListRegions(), JS9.EditRegions() public routines -
  • regions menu: options to save regions using different wcs, also save csv -
  • separate: add ability to use a CSS Grid instead of light windows -
  • sync: add GUI for plugin and change menu GUI to match -
  • desktop: add searchbar to analysis light windows (ctl-f or cmd-f) -
  • inline voyager images (remove dax versions from js9inline.js) -
  • JS9Titlebar plugin adds image id to title (uses globalOpts.updateTitlebar) -
  • add onregionsmove callback to Magnifier plugin (if intensivePlugins) -
  • add CopyShapes() to copy shape layers to another image (cf CopyRegions) -
  • add CopyParams() routine to copy params from one image to another -
  • add ColorControls plugin to color menu -
  • rgb mode is now associated with each display separately (not global) -
  • move rgb info when moving images between displays -
  • resort preloaded files into their original order -
  • update node minimist package to avoid prototype pollution bug -
  • don't use centered scaling for line and box regions -
  • add length/angle options to line configuration dialog box -
  • add statusbar plugin -
  • globalOpts.menuPosition to set menu position (def: below the menu button) -
  • add sum/avg option to binning plugin -
  • add support for fractional binning -
  • add GetOpacity(), SetOpacity() -
  • add support for opacity floor: an opacity assigned if pixval <= floorval -
  • extend opacity in menu to include floor opacity support -
  • sync images: sync all images to facilitate blinking -
  • sync images: add syncwcs option to force sync using image coords -
  • desktop: options can now be passed via --switches (e.g., --scale log) -
  • Load: add ra,dec, px,py, wcs properties to support panning -
  • Load: regions property can load a region file or add a region -
  • syncImages: add rot90, flip, and sync blended images -
  • CloseDisplay now takes an optional regexp of images to close -
  • add source, destination in/out/over/atop methods to blend plugin -
  • static colormaps: specify color/opacity and pixel range -
  • expand MaskImage to support "overlay" as well as "mask" of image data -
  • add MaskImage() routine to allow one image to mask another -
  • remove experimental LoadAuxFile() (too fragile, subsumed elsewhere) -
  • fix region parser to check for exclude regions -
  • fix bug when sortable GUI changed the image stack with multiple displays -
  • fix annulus radii text box in regions config -
  • update uuid and rimraf modules for js9Helper -
  • update jquery to v3.5.0 -
  • update emscripten to v1.40.1 -
  • update fabric.js to v3.6.3 and enable strokeUniform -
  • update cfitsio to v3.48 (via astroem repository) -
  • update ResizeSensor to v1.2.2 -
- -

Public Release 3.0 (January 6, 2020)

-
    -
  • improve menu placement for Jupyter support -
  • replace image filter menu with plugin that supports parameter adjustments -
  • just redisplay already-loaded slices -
  • added PanZoom controls to Zoom menu, containing "pan to" support -
  • wcs menu: don't show wcs options if image has no wcs -
  • add Google's new turbo colormap -
  • add analysis plot configuration dialog box to set data range and scale -
  • improve panner to show display area (not image area) -
  • infobox: fix bug displaying image coords instead of phys if sys was image -
  • webworker init: avoid CORS problems when webworker is on a remote location -
  • add array-based x,y flip and +/- 90 degree rotation to the Zoom menu -
  • add JS9.SetRot90() and JS9.SetFlip() public access routines -
  • improve LTM/LTV support, various bug fixes -
  • avoid weakness in wcslib causing the wrong header length to be used -
  • fix error handling when called from external message -
  • update emscripten to v1.39.3 (required several changes to montage) -
  • upgrade code to use ES6 -
- -

Public Release 2.5 (August 30, 2019)

-
    -
  • re-displaying an image now calls the onload callback -
  • JS9.BlendDisplay('reset') unsets blended images -
  • JS9.DisplayExtension('all') loads all image extensions -
  • JS9.ReprojectData('all') uses the current image to reproject others -
  • JS9.Load('foo.fits', {allext: true}) loads foo.fits, then all extensions -
  • add 'Display all images' button to Extensions plugin -
  • add support for loading all images in a multi-extension FITS file at once -
  • fix typo that made incorrect sections of non-rectangular images at zoom < 1 -
  • fix bug when zooming image with a selected region -
  • fix bug when loading multiple annuli at once -
  • fix regression in DisplaySection: new ext was not added to FITS filename -
- -

Public Release 2.4 (July 15, 2019)

-
    -
  • fix double tap to close capability on iPhones -
  • fix internal regcnts tasks using annuli on iOS devices and re-enable them -
  • wcs grid: fix high limit display coordinates -
  • analysis menu: only display 3d analysis menu options for 3d images -
  • refactor LoadWindow so load waits for the lightwin to be fully created -
  • desktop app: support merging analysis tasks and loading foreign web pages -
  • add JS9.GetAnalysis() to return analysis task definitions -
  • add missing routine in internal CountsInRegions() and RadialProfile() -
  • add support for "All" selection of regions to include text children -
  • GetRegions: return text child region id -
  • desktop app: enabling node mounts local file system for direct FITS access -
  • desktop app: add security checks -
  • fix overly-aggressive .gitignore and add missing files -
  • fix typo that broke createMosaic("all") -
  • fix bugs in imexam plugins using a rotated line to define the image section -
  • fix spinner when using open local file dialog -
  • update emscripten to v1.38.37 -
  • update contextMenu to v2.8.0 -
- -

Public Release 2.3 (May 1, 2019)

-
    -
  • support for Mac app, a bit of Windows app: see github/ericmandel/js9app -
  • Electron desktop app: use internal colorpicker if Electron version >= 5 -
  • add logo support -
  • add AlignPanZoom() public routine -
  • add --cmds [cmds] and --cmdfile [file] switches to js9Electron.js -
  • add --node switch to js9Electron.js, allowing nodeIntegration -
  • add JS9.globalOpts.onpreload property -
  • fix wcs alignment of blended images during pan and zoom operations -
  • fix mosaic code, which needed area mosaic file after all -
  • redesign Menubar to use more submenus, especially File menu -
  • fix bug in the supermenu sometimes not displaying the File sub-menus -
  • work around invalidation of emscripten heap pointers when memory increases -
  • add ability to change child text options via the parent shape -
  • add ability to push selected region to bottom of overlapping stack ('d') -
  • add ability to select all regions ('S' and Regions menu option) -
  • add SaveDir public routine (desktop app only) to set the save directory -
  • SavePNG,SaveJPEG: add option to save image RGB pixels instead of display -
  • SavePNG,SaveJPEG: add option to skip saving the layers (e.g. regions) -
  • shape layers (incl. regions) can now be exported in SVG format -
  • closing a light window that displays images now supports: close, move, ask -
  • add support for unconstrained panning -
  • dynamically select a JS9 display (supports one plugin for many displays) -
  • SaveColormap: allow multiple colormaps to be save at once -
  • add ability to change color, width, dash lines, tags of selected regions -
  • fix bug in "north is up" rotation: take CDELT values into account -
  • add direction vector to panner -
  • display regions in lightwin instead of on display or in infobox -
  • add region copyToClipboard capability (so 'p' always pastes last region) -
  • add ability to specify display opts in a FITS header (IMOPTS param) -
  • add ability to specify colormaps in a FITS header (IMCMAP param) -
  • add ability to create image cutouts of selected region(s) -
  • add ability to rename a JS9 display via JS9.RenameDisplay() api call -
  • ensure saved order of images after session load -
  • add --title and --renameid options to desktop app to rename display ids -
  • parameterize initial blending params -
  • Preload() loads .cmap files as colormaps -
  • colormaps: specify m colorwheel slices, from which n colormaps are assigned -
  • add ability to specify {display: id} param to external api calls -
  • add ability to unremove previously removed regions -
  • add ability to select regions based on the file from which they were loaded -
  • calling LoadRegions() twice removes previous regions loaded from the file -
  • add globalOpts.quietReturn to silence 'OK' messages -
  • Desktop (Electron.js) version: add --savedir option to skip save dialog -
  • JS9.Load(): globalOpts.reloadRefresh property to control reloading an image -
  • add 'revert' option to wcs reproject submenu -
  • wcs menu: each wcs system has own current units (based on initial defaults) -
  • fix region parser to see 'linear' as wcs, not a 'line' region -
  • cmaps: allow color choice via text input in fallback colorpicker -
  • fix memory leaks in reproject code -
  • LoadColormap: support file containing array of colormaps -
  • Infobox: for long filenames, click to see right hand side -
  • addColormaps now replaces a cmap with same name -
  • add 3D plot capabilities for data cubes in Analysis menu -
  • many improvements to user-defined menus -
  • turn on wasm in js9 Electron.js Desktop app -
  • menu: allow load/save of cmaps without a loaded image -
  • when blending, only sync zoom/pan reprojected images that are wcs aligned -
  • reproject: use float32 instead of float64 if datatype allows (less memory) -
  • reproject: correctly align images when wcs ref image is panned or zoomed -
  • reproject: fix memory leaks, always go back to original image -
  • js9 helper: increase ping timeout to avoid Chrome disconnects -
  • improve header generation and FITS card handling -
  • allow DisplaySection() to display the new section in a different display -
  • add colormaps plugin to create (complementary) colormaps -
  • fine-tune positioning: arrow keys display small crosshair cursor -
  • fine-tune positioning: arrow keys change magnifier display center -
  • regions menu: listonchange can act on "selected" (default) or "all" regions -
  • preferences plugin: image parameter for "all" or "selected" listonchange -
  • Meta (or Ctrl) now used for keyboard shortcuts displaying a light window -
  • edit, region menus: add option to display region configuration window -
  • add 'M-e' keyboard shortcut to display region configuration window -
  • add 'M-o' keyboard shortcut to open a local file -
  • add 'p' keyboard shortcut to paste regions at current mouse position -
  • (joining 'P' keyboard shortcut to paste regions at their own position) -
  • add 's' keyboard shortcut to select region that contains the mouse -
  • fix bug when saving/copying regions inside a rotated group -
  • Meta key during mouse move no longer updates internal image position -
  • update emscripten to v1.38.28 -
  • update fabric.js to v2.7.0 -
- -

Public Release 2.2 (October 9, 2018)

-
    -
  • add sync plugin: synchronize operations between two or more images -
  • add JS9.SyncImages() and JS9.UnsyncImages() public access routines -
  • SetParam(): setting a core param calls the core function -
  • add support for disabling colormap, pan, regions, scale, wcs, or zoom for a given image -
  • add Scale Clipping Limits plugin (with pixel distribution plot) -
  • add support for setting up a proxy from Apache to the Node.js helper -
  • add Separate/Gather Images plugin -
  • desktop app: add support for printing entire window -
  • desktop app: add support for saving entire window to a pdf file -
  • add support for loading all slices of a data cube separately into JS9 -
  • add support for user-defined menus in the Menubar -
  • add support for averaging pixels when binning (def: summing) -
  • add support for Mac-style menubars -
  • add Edit menu to Menubar (copy/paste regions, positions, values) -
  • add JS9.DisplayCoordGrid() and associated client-side task to Analysis menu -
  • add JS9.CountsInRegions() and associated client-side task to Analysis menu -
  • add JS9.RadialProfile(), and associated client-side task to Analysis menu -
  • reproject will try to bin large images to avoid memory limits -
  • add support for wcs-based cross-hair tracking of images -
  • add support for displaying mosaic images -
  • add CreateMosaic() public routine -
  • remove .fz suffix in various places where it breaks things -
  • fix bug where binning an image was not updating the CD matrix -
  • update emscripten to v1.38.5 -
  • update socket.io to v2.1.1 -
- -

Public Release 2.1 (May 10, 2018)

-
    -
  • allow JS9.SetPan() to accept a single object with x and y properties -
  • allow JS9.WCSToPix() to accept a single object with ra and dec properties -
  • allow JS9.PixToWCS() to accept a single object with x and y properties -
  • add support for Toolbar plugin -
  • add JS9.SetParam() and JS9.GetParam() public routines -
  • add JS9.SetToolbar() and JS9.GetToolbar() public routines -
  • add JS9.SeparateDisplay() public routine to separate images in a display -
  • add JS9.GatherDisplay() public routine to gather images into a display -
  • add JS9.LoadColormap() public routine -
  • add JS9.LightWindow() public routine -
  • JS9.GetImageData() now returns display size, bin factor -
  • JS9.RunAnalysis() return types now include "regions" and "catalog" -
  • include comments and history in display of FITS header -
  • iOS 11.2.2,5 disable wasm: github.com/kripken/emscripten/issues/6042 -
  • add refresh property to JS9.Load() to re-retrieve data -
  • add support for refreshing a file/url in JS9.RefreshImage() -
  • add support for displaying full image to JS9.DisplaySection() -
  • add 'f' (full) and 'r' (refresh) keyboard actions -
  • change 'r' (raise region layer) to '^' in keyboard actions -
  • add refresh and section commands to Console plugin (and js9 script) -
  • binning plugin: add button to load full image -
  • sessions: save/re-run dataLayer routines (e.g. reproject, rotate) -
  • sessions: save/restore blend mode -
  • sessions: save/restore wcsim from reprojection -
  • sessions: save/restore display parameters -
  • SaveSession saves either current image or all images -
  • ensure correct extension for Save{Session,PNG,JPEG} -
  • image blending: update GUI when changes are made via API -
  • image blending: support sizing of static div -
  • fix imexam routines needing integer section limits -
  • update emscripten to v1.37.28 -
  • update fabric.js to v1.7.22 -
  • update contextMenu to v2.6.3 -
- -

Minor Patch Release 2.0.2 (December 15, 2017)

-
    -
  • add zscale, zmax to SetScale() -
  • improve display-based routines (separate, gather, resize, center, select) -
  • improve alignment of differently sized images -
  • allow zoom during image blending -
  • add menu support for closing all images -
  • add support for selecting a target display in a supermenu -
  • add support for dispersing images from one display into new displays -
  • add support for gathering images from multiple displays into one -
  • add support for new image inheriting params from current image -
  • fix allinone (dont use wasm) -
  • fix bug loading wasm file in LoadWindow('new') -
- -

Minor Patch Release 2.0.1 (September 29, 2017)

-
    -
  • move helper log file outside www directory -
  • improve fetchURL() error messages -
  • fix bug in load catalog menu option -
  • allow json opts in Load* family of routines -
  • fix bug in JS9.Preload by saving a copy of opts -
- -

Public Release 2.0 (September 27, 2017)

-
    -
  • add support for emscripten-based WebAssembly -
  • add support for HPX projection -
  • add wcs selection menu to regions config dialog -
  • aesthetic improvements to regions config dialog -
  • fix race condition in Electron startup if not codesigned -
  • fix binning when manually specifying parent file -
  • fix wcs system display in infobox -
  • fix bug in js9Helper.js where localhost was not upgrading to use ws -
  • update emscripten to v1.37.20 -
  • update fabric.js to v1.7.19 -
  • update socket.io to v2.0.3 -
  • update jquery to v3.2.1 -
  • update jquery-ui to v1.12.1 -
- -

Public Release 1.12 (July 25, 2017)

-
    -
  • refactor astroem to use astroem repository of emscripten library byte-code -
  • add DisplaySection() public routine -
  • add ability to extract a section from images (as well as tables) -
  • add fits2fits configuration params for large files support -
  • add large file support in which large files can be handled externally -
  • allow infoBox to be configured via JS9.globalOpts.infoBox and preferences -
  • add wcs center and wcs fov display to infoBox -
  • add js9.app Mac desktops to run js9 script (drag/drop images onto it, etc.) -
  • add support for specifying URLs on js9 command line (uses proxy load) -
  • JS9.Preload() will now call JS9.ProxyLoad(), if required -
  • proxy load now turned on by default (needed for Desktop use) -
  • add support for drag/drop URLs onto JS9 display (uses proxy load) -
  • add support for uploading FITS files to a remove server -
  • add support for displaying bzip2 files -
  • add support for drag drop of region, catalogs, sessions (by file extension) -
  • add text, fonts, stroke options to region configuration dialog box -
  • add support for specifying a text region as a child of a region -
  • add js9-to-ds9 region conversion to js9 script (-r) -
  • add support for importing ds9 regions, including properties in comments -
  • sort overlapping regions so smallest is on top -
  • fix memory leaks in mef support -
  • add Divs plugin to show/hide in-page JS9 plugin divs -
  • allow shape size controls to match shape color at border, corner, or both -
  • use file extensions when opening local files (fits, regions, catalogs, etc) -
  • add keyboard action to move selected region in back of other shapes (not a default) -
  • JS9.RegisterPlugins() will instantiate plugins if scripts load asynchronously -
  • add JS9.InstantiatePlugins() public routine -
  • deprecate auto load of js9Prefs.son (load js9prefs.js explicitly instead) -
  • update emscripten to v1.37.9 -
  • update socket.io to v1.7.3 (big change in module directory structure) -
- -

Public Release 1.11 (January 9, 2017)

-
    -
  • add support for displaying HEALPix files -
  • add initial support for memory management of internal FITS files -
  • add menu support for clearing FITS files from internal memory -
  • add support for running JS9 on the Desktop using Electron.js -
  • integrate Desktop Electron support into into js9 script -
  • add ability to load local catalogs and save catalogs to disk -
  • add JS9.LoadCatalog() and JS9.SaveCatalog() public routines -
  • add Shape Layer plugin to turn on/off layers and set the active layer -
  • remove list of shape layers from View menu in favor of Shape Layer plugin -
  • add JS9.ActiveShapeLayer() public routine -
  • improve onimagedisplay processing for mef, cube, imarith plugins -
  • fix bug in cube plugin blink support -
  • update fabric.js to v1.6.6 -
  • update socket.io to v1.5.1 -
  • update closure-compiler to v20160911 -
- -

Public Release 1.10 (October 11, 2016)

-
    -
  • add support for full-display mode -
  • add support for keyboard actions and shortcuts -
  • add JS9.SetRGBMode(), JS9.GetRGBMode() public routines -
  • unclutter the position/value display -
  • dont update value/position if "special key" is pressed -
  • buttons and menu/titlebars are now beautiful and Mac-like -
  • buttons can be beautiful and flat (change via class specification) -
  • add support for copying regions to another image (JS9.CopyRegions()) -
  • add initial support for plotly plotting library -
  • improvements to energyplot, evfilter, binning plugins -
  • add support for alternate WCS (including JS9.GetWCS, JS9.SetWCS routines) -
  • add JS9.LookupImage() public routine -
  • generalize and extend plugin callback capability -
  • extend range of FITS files that can be WCS-projected using Montage -
  • add support in the File menu for saving and loading sessions -
  • add JS9.LoadSession() and JS9.SaveSession() public routines -
  • update imexam,fitsy, archive plugins -
  • update fabric.js to v1.6.3 -
  • update cfitsio to v3.39 -
  • update socket.io to v1.4.5 -
- -

Public Release 1.9 (June 8, 2016)

-
    -
  • add standard RGB image processing functions to the Analysis menu -
  • add support for gesture-based zoom (scroll wheel and pinch) -
  • add MouseTouch plugin to change mouse/touch actions -
  • image id now contains extension name or number for FITS extensions -
  • add support for histogram equalization scaling -
  • add support in js9 script for starting up a browser/web page -
  • add support for displaying slices of a FITS data cube -
  • add support for image arithmetic (between 2 images or image & constant) -
  • add support moving images between JS9 displays -
  • add support for displaying HDUs in multi-extension FITS files -
  • add 'magma', 'inferno', 'plasma', 'viridis' colormaps from matplotlib -
  • deprecate the use of funtools when building JS9; please use cfitsio -
- -

Public Release 1.8 (March 21, 2016)

-
    -
  • add image blending plugin to support blending operations between images -
  • add ability to blend images using W3C composite/blending modes -
  • add colorbar plugin to display colormap vs intensity information -
  • add blink plugin to blink images -
  • add line region (with support for multiple line segments) -
  • add raw data layers to allow manipulation of underlying raw data -
  • add JS9.FilterRGBImage() to support RGB image processing routines -
  • add JS9.GaussBlurData public routine to perform Gaussian blur on data layer -
  • add JS9.RawDataLayer() public routine for raw data layer manipulation -
  • add JS9.ShiftData() public routine to shift raw data in x and y -
  • add JS9.GetDisplayData(), returning data for all images in a given display -
  • add JS9.SaveJPEG() public routine to save image and overlays as JPEG -
  • add JS9.AddColormap() public routine to add a colormap to JS9 -
  • add JS9.SaveColormap(), JS9.OpenColormapMenu() public routines -
  • JS9.SavePNG() public routine now saves image and graphical overlays -
  • add support for reprojecting images using Montage/mProjectPP -
  • add JS9.Reproject() public access routine -
  • change menu option Color->alpha (0 to 255) to Color->opacity (0.0 to 1.0) -
  • fix bug when interactively changing panner for non-square images -
  • fix bug in lut colormap, which truncated the first color -
  • refactor emscripten astroem package into sub-packages -
  • update emscripten to v1.35.0 -
- -

Public Release 1.7 (January 12, 2016)

-
    -
  • add Jupyter/IPython support for iframes -
  • add keyboard focus support for Jupyter/IPython -
  • add timeouts to avoid back-end connect() hangs -
  • add support for using rgb file as the display over a data file -
  • default helper is "none" (for Jupyter, where js9Prefs.json is not loaded) -
  • add lower right handle to change width and height of display -
  • add View menu option to change width and height of display -
  • add JS9.ResizeDisplay() to change the size of a JS9 display element -
  • add JS9.DisplayPlugin() public routine for custom menus -
  • add JS9.GetFITSHeader() (as a string) public routine for custom menus -
  • add resize handle to display (lower right corner) -
  • add View menu option to change the display width and height -
  • add support for handling group events in shape layers (i.e. catalogs) -
  • add support for handling mouse events in shape layers (i.e. catalogs) -
  • add support for tooltips to shape layers (i.e. catalogs) -
  • add return values to saveFITS() and savePNG() -
  • add spinner while waiting -
  • fix OpenFileMenu() and OpenRegionMenu() when using multiple displays -
  • fix text region printing -
  • fix bug in panner box when panner image does not fill panner width -
  • fix region configure to "delete" only itself (not all regions) -
  • fix one pixel bug in WCS region conversion -
  • update fabric.js to v1.5.0 -
  • update socket.io to v1.3.7 -
  • updated jquery to v1.11.3 -
- -

Public Release 1.6 (November 7, 2015)

-
    -
  • add support for extracting image/table sections from "parent" files -
  • add JS9.LoadProxy() public routine to load FITS URLs via proxy server -
  • add support for loading Dropbox (and other CORS enabled) shared links -
  • add support for loading links by proxy through the back-end server -
  • add SetValPos and DisplayMessage public routines -
  • add options to create new JS9 windows from the file menu -
  • add experimental support for JS9 in an iframe, using postMessage -
  • remove starting "_" from SUPERMENU id (not legal syntax) -
  • fix various iOS foibles (scrolling, double-click to close) -
  • fix memory leak in cfitsio RefreshImage() support -
  • fix bug in lut colormap limit check -
  • fix bug in JS9.RefreshImage() blob handler -
  • fix overflow bug in cfitsio bscale/bzero support -
  • fix bug in zscale by properly exposing emscripten methods -
  • update emscripten to 1.34.1 -
  • update wcs library to 3.9.0 -
- -

Public Release 1.5 (July 9, 2015)

-
    -
  • add support for specifying regions using Funtools/DS9 syntax -
  • add support for loading Funtools/DS9 region files -
  • add support for running the Node.js helper using https protocol -
- -

Public Release 1.4 (May 3, 2015)

-
    -
  • add Preferences plugin to set image and region user prefs -
  • add ability to save image to FITS and PNG files (limited Safari support) -
  • add ability to save regions to a text file -
  • fix bugs in Binning plugin (mainly for cfitsio, but some general bug fixes) -
- -

Public Release 1.3 (March 30, 2015)

-
    -
  • add cfitsio library support to JS9 (emscripten compile to javascript) -
  • add data-width and data-height attributes to change the size of JS9 divs -
  • extend tpos and js9helper to use cfitsio (or funtools) -
  • update tpos js9Protocol to 1.1 to include header comments in the header -
  • default WCS is now determined in the browser, not by the back-end server -
  • ensure that section info is maintained during JS9.RefreshImage() -
  • prevent preload from happening more than once -
  • fix broken File->Open menu option -
  • update emscripten to v1.27, add new optimizations to astroem -
- -

Public Release 1.2 (January 4, 2015)

-
    -
  • concurrent release of pyjs9 1.0 on github -
  • update socket.io to the Engine.IO-driven v1.x (specifically v1.2.1) -
  • add ability to reconnect to node.js server automatically if latter restarts -
  • add support for specifying a temp work dir for back-end analysis -
  • add http support to js9Helper.js so messages can be sent via GET, POST -
  • JS9.Load: accepts FITS files as blobs and base64-encoded strings -
  • JS9.RefreshImage: accepts blobs (FITS files), js arrays and typed arrays -
  • JS9.GetImageData(): returned data can be array or base64-encoded string -
  • fix bug in arguments to public api routines sent via external message -
  • fix bug in File List: clicking on same file multiple times now redisplays -
- -

Public Release 1.1 (November 15, 2014)

-
    -
  • NB: api change: added errcode to argument list of RunAnalysis() callback -
  • new api: AddDivs() to add JS9 displays and/or plugins to the web page -
  • new api: Send() sends msgs programmatically (useful for 3rd party helpers) -
  • add support for super-menus that can control multiple JS9 displays -
  • add support for onload callback when displaying FITS files -
  • allow xcen, ycen (in image coords), zoom to be passed in obj to JS9.Load() -
  • re-factor js9Helper.js: each analysis task is its own top-level msg -
  • allow user-defined msgs to be added to analysis tasks more easily -
  • ensure correct region size during RefreshImage() and table binning -
  • add contour plugin to default plugins in js9plugins.js -
  • add checks for NaN values to imexam plugins -
  • fix imexam plugins bug when regions are rotated and resized -
  • fix bug in encircled energy preventing calculation for non-integer radii -
  • properly handle FITS TFORM cards without a repeat value (XMM data) -
  • resize regions properly when tables are binned by a block factor -
  • ensure that datamin and datmamax are updated when a binary table is binned -
  • dont send image notify events to back-end during contrast/bias changes -
- -

Public Release 1.0 (September 30, 2014)

-
    -
  • NB: change to the Public API: id is no longer first argument. See API doc. -
  • infobox plugin upgraded to a tabular display -
  • node.js server sends unique pageid back to JS9 -
  • JS9 menus now cover light windows (higher zindex) -
  • improved accuracy of polygon points for contours -
  • moving a polygon point now calls listRegion -
  • added missing commas in WCS display of polygon points -
  • corrected WCS for drag/drop of sections of FITS binary tables -
  • fixed incorrect region size when binning FITS binary tables -
  • fixed memory leak in astroem reg2wcs routine -
  • plugin divs can now set height and width using CSS -
  • added defensive code to remove bash functions from CGI and node calls -
  • updated fabric.js to 1.4.11 -
- -

Release 1-epsilon (July 28, 2014)

-
    -
  • JS9.Load() can now load FITS files directly (rather than converting to PNG) -
  • added support for FITS binary tables, including binning and filtering -
  • added support for gzip'ed FITS files -
  • added support for "physical" coordinates (i.e., tied to original data file) -
  • changed 2D graphics subsystem from Kinetic.js to fabric.js -
  • added generalized shape layer support for regions, catalogs, contours, etc. -
  • region context menu is now a light-weight web page with many new features -
  • added text and point regions -
  • position of a pixel is now in the center of the pixel -
  • accelerator key changed from shift key to meta key (command on Mac, control elsewhere) -
  • reduced number of js9 files to load in a web page -
  • redesigned and flattened returned region object -
  • redesigned public API -
  • changed Public routines JS9.Pix2WCS and JS9.WCS2Pix to be 1-indexed -
  • added ability to group and move regions -
  • box rotation is now around the center of the region -
  • all image coordinate are now 1-indexed throughout -
  • fixed bug where adding a polygon pt didn't show until region was selected -
  • changed polygon points to an array of objects {x, y} instead of just x, y -
  • fixed various layout bugs in plugins -
  • updated emscripten to latest version -
  • updated flot to latest version -
  • updated jquery to 1.11.1 -
- -

Beta Release 13 (April 6, 2014)

-
    -
  • added support for handling NaN values -
- -

Beta Release 12 (March 10, 2014)

-
    -
  • added support for browser-based analysis via plugins (JS9.RegisterPlugin) -
  • converted Menubar, Info, Panner, Magnifier to plugins -
  • initial version of imexam plugin available (in plugins directory) -
  • initial version of archive/catalog server plugin available -
  • added support for zscale (IRAF min/max algorithm for scaling) -
  • added support for user scale limits -
  • regions can now be moved off the image -
  • shift key disables mouse plugin callbacks -
  • zooming a small image will use all of the available display canvas -
  • added support for sub-pixel zooming -
  • added ability to process all keys in keypress callback -
  • added arrow key support for moving regions -
  • added fractional pixel positions for zoomed images -
  • fixed bug which reset pan when changing colormaps on a zoomed image -
  • added strict mode -
  • update emscripten to 1.8.2 -
- -

Beta Release 11 (December 18, 2013)

-
    -
  • initial port to iPad -
  • removed notifyHelper message when mouse enters image window -
  • fixed tpos crash when converting really large images -
  • updated jquery.contextMenu.js -
- -

Beta Release 10 (December 9, 2013)

-
    -
  • added support for RGB composite display -
  • added support for reading in auxiliary files via auxFiles preference -
  • added support for overlaying FITS image masks -
  • added support so that drag and drop files can be found by local analysis -
  • added analOpts.dataPath to specify where to look for drag and drop files -
  • box regions need to rotate around upper left point to ensure consistency -
  • changed name of fitshelper to js9helper -
  • changed JS9.submitAnalysis() to JS9.SubmitAnalysis() -
  • changed analOpts.datadir to analOpts.dataDir -
  • removed wcs event processing from node and CGI helper (use browser wcs) -
  • js9helper not run as a server from js9Helper.js any more (scales better) -
  • added ability to turn off redraw when creating a large number of regions -
  • fixed bug in panner display for non-square images -
  • added work-around for Google Chrome v31 bug (regions not drawn) -
- -

Beta Release 9 (October 23, 2013)

-
    -
  • added support for client-based WCS using emscripten 1.5.6 -
  • added drag and drop of FITS images (binary tables are coming) -
  • added support for region callbacks (executed when a region changes) -
  • added JS9.Regions() public routine to retrieve and modify selected regions -
  • added Close Image button to File menu -
  • reduced size of panner when created by View menu -
  • updated Kinetic.js to v4.7.2 -
  • minor bug fixes (e.g., annuli strokeWidth not resizing properly) -
- -

Beta Release 8 (September 23, 2013)

-
    -
  • fixed security in node.js support by requiring use of wrapper scripts -
  • added support for CGI-based back-end helpers -
  • implemented automatic discovery of analysis definitions -
  • added timer-based management of WCS update requests -
  • updated socket.io to 0.9.16 -
  • changed routine name from JS9.preloadImages() back to JS9.Preload()! -
- -

Beta Release 7 (August 19, 2013)

-
    -
  • fits2png: added support for "%cookie" in odir specification -
  • js9.js and js9Helper.js both now use js9Prefs.json for setting preferences -
  • fixed bug in display/manipulation of panner when image is zoomed -
  • added "none" as an analysis return type to support hidden analysis -
  • changed routine name JS9.Preload() to JS9.preloadImages() -
  • added clipping to region manipulation -
  • fixed region strokewidth problem when zooming image -
  • fixed magnifier and panner where multiple instances of js9 are present -
  • numerous changes to pass new JSLint rules -
  • updated jquery to 1.10.2 -
  • updated jquery.flot to 0.8.2 -
  • removed references to of jquery-ui in demo files (its not used) -
- -

Beta Release 6 (July 22, 2013)

-
    -
  • added support for panner window, including ability to zoom the panner -
  • added support for magnifier window, including ability to change magnification -
  • implemented zoom menu (zoomIn, zoomOut, zoom1, zoom2, zoom4, zoom8) -
  • added support for all FITS data types (silrd) in js9.js and tpos.c -
  • png file now contains FITS header in json format -
  • NB: the format of the PNG representation file has changed substantially! -
  • raw arrays now implemented as a typed array, using DataView to unpack it -
  • updated Kinetic.js to v4.5.4 (multiple changes required to code) -
- -

Beta Release 5 (May 20, 2013)

-
    -
  • added support for dynamic creation of js9 instances (new or light window) -
  • added support for pre-loading images into a js9 on page load -
  • added support for running analysis web page buttons, forms, etc. -
  • added support for printing the image -
  • added new demo pages -
  • changed js9msg script name to js9 -
  • loading javascript files is "generic" (no version numbers in filenames) -
  • updated Kinetic.js to v4.5.1 -
- -

Beta Release 4 (April 26, 2013)

-
    -
  • added support for polygon regions -
  • added support for fixing (i.e. freezing) regions in place -
  • added support for container regions (constrain position of other regions) -
  • added support for shift key accelerator -
  • fixed multiple bugs in region listOnChange support -
  • updated Kinetic.js to v4.4.3 -
- -

Beta Release 3 (April 2, 2013)

-
    -
  • updated Kinetic.js to v4.4.0 to fix new chrome v26.0.1410.43 (whoah!) -
- -

Beta Release 2 (April 1, 2013)

-
    -
  • added support for executing analysis from console window -
  • added support for messaging to js9 via Node-based js9Msg.js -
  • added ability to specify params to region creation -
  • added server mode and input from stdin to js9Msg.js -
- -

Beta Release 1 (February 27, 2013)

-
    -
  • initial beta release with support for displaying FITS images, scaling, -colormaps, external analysis, regions, wcs -
- -
- - - diff --git a/web/static/js9_old/help/desktop.html b/web/static/js9_old/help/desktop.html deleted file mode 100644 index 8874b8381ef03ea92c4a44f5834146289c4e3fa6..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/desktop.html +++ /dev/null @@ -1,585 +0,0 @@ - - - - - -JS9 on the Desktop - - - -
-

JS9 on the Desktop

- -

-JS9 can be used as a desktop replacement for -SAOimage DS9: you can load images into -the app's configurable web page (or your own custom web page) and use -the full power of JS9, including external messaging. - -

-Advantages of using JS9 on the desktop include: -

    -
  • built using today's web-based technology -
  • fully configurable user interface using standard web pages -
  • support for adding your own browser-based analysis plugins -
  • complete programming interface via a rich public API -
  • external messaging with full access to the public API (Python and shell) -
  • flexibility of having multiple images associated with separate displays -
  • support for image blending -
  • support for image reprojection -
- -

-Advantages of using DS9 include: -

    -
  • the de facto standard astronomical image display for nearly three decades -
  • full access to virtual memory (no memory limits when loading huge files) -
  • support for nearly all WCS systems via the AST library -
  • support for 3D rendering -
  • advanced access to external catalogs and archives -
  • XPA-based messaging integrated with CIAO, ftools, and Python -
  • support for VO/SAMP -
- -

Installing a Pre-built Desktop App

- -Pre-built desktop apps for Linux (for Ubuntu 20.04 and compatible -systems) and Mac (for Catalina 10.15.x) are available on the -main JS9 web site: - -
    -
  • js9app: offers a basic user interface -
  • Voyager: coming soon ... offers an advanced user interface patterned after the Mac -
- -

-For Linux, download and unzip the zip file to create a directory -called <app>-linux-x64 containing a number of files, including a -js9app executable. Put this directory in your Linux PATH (or -use a link to the executable) and run the program. For Mac, download -the zip file and unzip it into your /Applications or ~/Applications -directory to create a Mac application, which you can start by -double-clicking or by using the open command: -

-  # open Mac app, load FITS file and region file, set colormap and scale
-  open /Applications/js9.app --args ~/data/casa.fits --regions ~/data/casa.reg --colormap viridis --scale log
-
- -

-Once the app is started, you can drag and drop a FITS file to display -it (or use the File->open menu option, etc). -The File->export messaging script menu option will bring up a dialog -box to create a script called js9msg that you can use to control the app -externally (see External Communication with JS9 -for details.) - -

Installing Electron.js for a Fully Configurable Desktop App

- -

-The pre-build apps described above are built using -Electron.js, a widely-used -framework for creating native applications with web technologies like -JavaScript, HTML, and CSS. You can easily configure your own JS9 app -(giving you complete control over the display web page, server-side -analysis, etc.) by installing Electron.js. - -

-Install Electron.js by visiting the Electron.js release page: - -https://github.com/electron/electron/releases to download the -latest available stable (not beta) release for your platform. On a -Mac, the Electron.app should be installed in the /Applications or -~/Applications folder. On Linux, the electron program should be placed -in your PATH. Electron.js also is available for Windows, -so desktop JS9 should also run on that OS, although we have not done -any work in this direction. If you get desktop JS9 running under -Windows, please let us know! - -

-Once the Electron.js is installed, you can build JS9 as usual, taking -care to configure use of the Node.js helper. Note that there is no need -to actually install Node.js: desktop JS9 has its helper integrated into -Electron.js already. - -

-If you are not planning to utilize server-side analysis tasks or large -file support, you can even skip the standard build: edit the supplied -js9prefs.js file (for the browser) and a js9Prefs.json file (for the -JS9 helper) to add your preferred JS9 properties, and use the supplied -js9 script to start the desktop. - -

-Note for macOS users: if you plan to use Electron.app with JS9 on a Mac, -consider codesign'ing the Electron.js app: -

-  sudo codesign --force --deep --sign - /Applications/Electron.app/Contents/MacOS/Electron
-
-to avoid repeated requests to allow incoming connections. - -

Running JS9 on the Desktop

- -

-The js9 script is normally made accessible by adding the JS9 install -directory (when fully building JS9) or the source directory (for quick -install) to your user PATH. - -

-Run the js9 script with the -a switch to start the desktop app, display -the default JS9 web page, and load one or more FITS files: -

-  # the -a switch tells the script to bring up the desktop js9 app
-  js9 -a ~/data/casa.fits
-
-  # opts can be passed via json format
-  js9 -a fits/casa.fits '{"scale":"log","scalemin":3,"colormap":"cool"}'
-
-  # opts can be passed via switch format
-  js9 -a fits/casa.fits --scale log --scalemin 3 --colormap cool
-
-  # opts can be passed via mixed format
-  js9 -a fits/casa.fits --colormap cool '{"scale":"log","scalemin":3}'
-
-  # multiple files can have different opts
-  js9 -a fits/casa.fits.gz --colormap heat --scale log fits/casa.fits --colormap cool --ra 350.8667 --dec 58.812
-
-  # load a colormap file, then use the newly loaded colormap for the image
-  # also load a regions file
-  js9 -a cmaps/purple.cmap fits/casa.fits --colormap purplish --regions casa/casa.reg
-
-In the desktop app, all relative paths are relative to current working -directory, as would be expected with files passed to any desktop -program. For consistency, this behavior extends to the case of files -specified in web pages: relative files are still relative to the -current directory, not the web page (as would be the case with browsers). -It is controlled globally by the JS9.globalOpts.currentPath -property and locally by the fixpath property. For example, if -the desktop app loads a webpage, then the default call to JS9.Load(): -
-<a href='javascript:JS9.Load("fits/casa.fits", {scale:"log", colormap: "cool"});'>CAS-A</a>
-
-specifies that the FITS file is relative to the current working directory, -while use of fixpath:false: -
-<a href='javascript:JS9.Load("fits/casa.fits", {scale:"log", colormap: "cool", fixpath:false});'>CAS-A</a>
-
-specifies that the FITS file is relative to the web page. -

-You also can use the ${JS9_INSTALLDIR} and ${JS9_PAGEDIR} "macros" -to specify that the path of the FITS file is relative to the JS9 install -directory or the web page directory, respectively. For example: -

-<a href='javascript:JS9.Load("${JS9_PAGEDIR}/fits/casa.fits", {scale:"log", colormap: "cool"});'>CAS-A</a>
-
-specifies that the FITS file is relative to the web page (just -like fixpath), while: -
-<a href='javascript:JS9.Load("${JS9_INSTALLDIR}/fits/casa.fits", {scale:"log", colormap: "cool"});'>CAS-A</a>
-
-specifies that the FITS file is relative to the JS9 install directory. -

-Note that path specification using fixpath, ${JS9_INSTALLDIR}, or ${JS9_PAGEDIR} applies to the "Load" routines: -

    -
  • JS9.Load() -
  • JS9.LoadCatalog() -
  • JS9.LoadColormap() -
  • JS9.LoadRegions() -
  • JS9.LoadSession() -
- -

-The same js9 script (without the -a switch) can now be used to interact -with the JS9 page (or any other JS9-enabled web page): -

-  # without -a, the script sends commands to the JS9 display
-  js9 SetColormap cool
-  js9 AddRegions 'ICRS;ellipse(23:23:18.76, +58:47:27.252, 31.8", 15.9", 40)'
-
-See: External Messaging for more details. - -

-You can also load remote images, as the script will call LoadProxy as -needed: -

-  js9 -a http://hea-www.cfa.harvard.edu/~eric/coma.fits.gz
-
- -

-A number of desktop-specific switches are available in the js9 script. Perhaps -the most important is the --webpage switch, which allows you to -specify a custom web page to display, so that you can tailor the desktop app -to your specific needs: -

-  js9 -a --webpage ~/myjs9/myjs9.html ~/data/casa.fits
-
-When configuring your own web page, one simple possibility is to create a -separate directory, parallel to the JS9 source (or install) directory, -in which you can maintain your custom web page(s) and your customized -js9prefs.js file. You might also create a myjs9 script that runs the -js9 script. For example, this myjs9.html file might be stored in a myjs9 -directory parallel to the js9 directory: -
-  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-     "http://www.w3.org/TR/html4/loose.dtd">
-  <html>
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-    <meta http-equiv="X-UA-Compatible" content="IE=Edge;chrome=1" > 
-    <meta name="viewport" content="width=device-width, initial-scale=1">
-    <link type="image/x-icon" rel="shortcut icon" href="../js9/favicon.ico">
-    <link type="text/css" rel="stylesheet" href="../js9/js9support.css">
-    <link type="text/css" rel="stylesheet" href="../js9/js9.css">
-    <script type="text/javascript" src="js9prefs.js"></script>
-    <script type="text/javascript" src="../js9/js9support.min.js"></script>
-    <script type="text/javascript" src="../js9/js9.min.js"></script>
-    <script type="text/javascript" src="../js9/js9plugins.js"></script>
-    <title>my JS9 app</title>
-  </head>
-  <body>
-      <div class="JS9Menubar" data-width="100%"></div>
-      <p style="margin-top: -14px;">
-      <table cellspacing="0" style="width:100%;">
-      <tr valign="top">
-      <td align="left">
-      <div class="JS9" data-width="768px" data-height="768px"></div>
-      <div style="margin-top: 2px;">
-      <div class="JS9Colorbar" data-width="768px" id="JS9Colorbar" data-showTicks="false" data-height="10px"></div>
-      </div>
-      </td>
-      <td align="right">
-      <table cellspacing="0">
-      <tr valign="top">
-      <td>
-      <div class="JS9Magnifier" data-width="250px" data-height="250px"></div>
-      </td>
-      </tr>   
-      <tr valign="top">
-      <td>
-      <div class="JS9Panner" data-width="250px" data-height="250px"></div>
-      </td>
-      </tr>   
-      <tr valign="top">
-      <td>
-      <div class="JS9Info" data-height="250px" style="margin-top: 2px;"></div>
-      </td>
-      </tr>   
-      </table>    
-      </td>
-      </tr>
-      </table>
-  </body>
-  </html>
-
-Note that the JavaScript and CSS files are loaded from the js9 -source (or install) directory, but the js9prefs.js is loaded from the -myjs9 directory. This separation allows you to configure site-wide js9 -parameters without changing the any of the files in the source -directory, and allows you to update the source directory very easily -by executing "git pull". - -

-A script such as the following can then be used to use this web page -in the JS9 desktop: -

-  #!/bin/bash
-
-  WEBPAGE="$HOME/myjs9/myjs9.html";
-
-  WIDTH=1130;
-  HEIGHT=860;
-
-  if [ x${JS9_WEBPAGE} != x ]; then
-    WEBPAGE=${JS9_WEBPAGE}
-  fi
-
-  if [ x${JS9_WEBPAGE_WIDTH} != x ]; then
-    WIDTH=${JS9_WEBPAGE_WIDTH}
-  fi
-
-  if [ x${JS9_WEBPAGE_HEIGHT} != x ]; then
-    HEIGHT=${JS9_WEBPAGE_HEIGHT}
-  fi
-
-  exec $HOME/js9/js9 -a --width $WIDTH --height $HEIGHT --webpage $WEBPAGE $*
-
-As shown above, the --width and --height switches are available -to set the width and height of the Electron.js window which will contain the -web page. - -

-Another important switch is --title (and its generalized -cousin, --renameid). This switch will rename the main JS9 -display id in the web page (whose default is "JS9") to the specified -id. It is useful in cases where you want to start up multiple desktops -using the same web page, and communicate with each one separately. In -such cases, the --title switch will change the id of the JS9 -display element and its auxiliary elements (e.g. menubar, colorbar, -etc) to the specified title: -

-  js9 -a --title foo1 ~/data/casa.fits
-
-You will then be able to communicate with this web page using the specified id: -
-  js9 --id foo1 GetColormap
-  {"colormap":"heat","contrast":1,"bias":0.5}
-
-The --renameid switch allows you to specify multiple JS9 -displays to rename, in cases where more than one JS9 display is part of a -web page: -
-  js9 -a --renameid "JS9:foo1,myJS9:foo2" ~/data/casa.fits
-
-will rename the default "JS9" element to "foo1" and the "myJS9" -element to "foo2". - -

-The --savedir switch will set the directory into which files -are saved, avoiding the display of an interactive dialog box when -saving images: -

-  js9 -a --savedir /Users/eric/Desktop ~/data/casa.fits
-  ...
-  js9 --id foo1 SavePNG casa.png
-
-will save the casa.png file on the desktop without a dialog box. This is -especially useful in automatic scripting. - -

-You can use the --cmds [cmds] and/or --cmdfile [file] switches -to pass Javascript commands that will be executed when JS9 is ready -and all files have been loaded. The former takes a string of commands -as an argument: -

-  # load a file and set the colormap and scale
-  js9 -a --cmds 'JS9.SetColormap("cool");JS9.SetScale("log")' ~/data/casa.fits
-
-The latter takes a file containing commands, allowing you to perform -more sophisticated processing. For example, the following script -will load the Chandra image of the Kes 75 supernova remnant, display -three energy cuts as separate images, assign red, green, and blue -colormaps to the three energy cuts, and then blend them into a single display: -
-  # run the script in the command file 
-  js9 -a --cmdfile eband.js
-
-  // where eband.js contains the following Javascript:
-  JS9.Load("kes75/kes75_evt2.fits.gz", {onload: function(im){
-      var i;
-      // colormaps
-      var c = ["red", "green", "blue"];
-      // energy filters
-      var f = ["energy=500:1500", "energy=1500:2500", "energy=2500:8000"];
-      // set final configuration after each image is loaded
-      var mkdo = function(i){
-  	return function(xim){
-  	    JS9.SetScale("log",   {display: xim});
-  	    if( c[i] ){ JS9.SetColormap(c[i], {display: xim}); }
-  	};
-      };
-      // turn blending off on the main image
-      JS9.BlendImage(false);
-      // process each of the event filters to make a separate image
-      for(i=0; i<f.length; i++){
-  	// display filtered image in a separate displayed
-  	JS9.DisplaySection({filter:f[i], separate:true,
-  			    ondisplaysection: mkdo(i)}, {display: im});
-      }
-      //  blend the filtered images
-      JS9.BlendDisplay(true);
-  }});
-
-

-The --merge switch allows you to utilize another user's setup, -including their JS9 web page and analysis routines. Say, for example, -a colleague has used Dropbox to share her JS9-enabled zhjs9 directory, -containing the following files and sub-directories: -

-  zhjs9.html js9prefs.js js9addons.js
-
-  analysis-plugins:
-  zhtools.json
-
-  analysis-wrappers:
-  zhjs9
-
-  params:
-  adapt.html	imexam.html	mexhat.html
-  atrous.html	imsmo.html	refinepos.html
-
-where zhjs9.html has a header in which the paths to JS9's files are matched to -your colleague's setup, but not your own: -
-  <head>
-  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-  <meta http-equiv="X-UA-Compatible" content="IE=Edge;chrome=1" > 
-  <meta name="viewport" content="width=device-width, initial-scale=1">
-  <link type="image/x-icon" rel="shortcut icon" href="../../js9/favicon.ico">
-  <link type="text/css" rel="stylesheet" href="../../js9/js9support.css">
-  <link type="text/css" rel="stylesheet" href="../../js9/js9.css">
-  <link rel="apple-touch-icon" href="../../js9/images/js9-apple-touch-icon.png">
-  <script type="text/javascript" src="js9prefs.js"></script>
-  <script type="text/javascript" src="../../js9/js9support.min.js"></script>
-  <script type="text/javascript" src="../../js9/js9.js"></script>
-  <script type="text/javascript" src="../../js9/js9plugins.js"></script>
-  <script type="text/javascript" src="js9addons.js"></script>
-  </head>
-
-Also note the presence of analysis tool definitions and scripts in the -analysis-plugins, analysis-wrappers, and params sub-directories. Normally, -in order to use the zhjs9 web page and associated analysis tools, you -would need to edit the former and change the JS9 paths, and move the -contents of the three analysis tools sub-directories into the appropriate -sub-directories in the main JS9 install directory. - -

-Instead, you can simply merge this directory into your desktop app, e.g. -

-  js9 -a --merge ~/Dropbox/zhjs9/zhjs9.html
-
-This will generate and load a temporary webpage using correct paths to -the JS9 install directory and load the analysis tools into the JS9 -helper. You can also merge the analysis tools without loading the web -page by specifying only the directory: -
-  js9 -a --merge ~/Dropbox/zhjs9
-
-In addition, if a bin directory is present, it will be added to the PATH -used when processing analysis commands. - -

-A merged web page can, of course, include its own javascript and css -files, as shown in the example above. It can also -include JS9.Load() commands, for example, to load files from a -subdirectory. In this case, you should set the fixpath property -to false so that the paths of the data files are not changed -into paths relative to the current working directory (which is the -default behavior for desktop JS9.Load() calls): -

-<a href='javascript:JS9.Load("fits/casa.fits", {scale:"log", colormap: "cool", fixpath:false});'>CAS-A</a>
-
- -

-Finally, the --hostfs switch (NB: was --node prior to v3.1) -allows you to access the host file system in a local (only, not remote) -web page environment. By default, this feature is turned off because -it requires turning off the Electron's - -Context Isolation security feature, providing a greater attack -surface for hackers. But since this host access is permitted only for -local web pages, an attacker would have to be on your system ... so -you're probably in big trouble anyway. - -

-That said, there are two good reasons for turning on host file system access: -

    -
  • to enable direct access to data files in the local file system -
  • to run scripts that require access to system resources -
- -

-When access to the host file system is enabled, the JS9 app will -(subject to the boolean value of the JS9.globalOpts.localAccess -property) mount the local file system inside the web page and access -FITS files directly, instead of fetching and storing them in browser -memory. This can speed up the load/display time considerably, while -minimizing the use of a browser memory. The list of file extensions -which are accessed directly in this way is specified by the -JS9.globalOpts.localTemplates property, which defaults -to .fits and .fts. Note that bzip'ed (.bz2) and gzip'ed -(.gz) files are not accessed directly: the former are not supported by -the CFITSIO FITS access library, while the latter are supported by -uncompressing the file in memory, which is done more efficiently by -JS9 itself. Also, symbolic links currently are not accessed directly. -We expect to remove this restriction in the near future. - -

-You can also run scripts that access local system resources. For -example, the following script will load the Chandra image of the Kes -75 supernova remnant, display three energy cuts as separate images, -find the total number of counts in each image, and write the results -to a log file, using the Node.js 'fs' module. -

-  # enable host file system support and run the script in the command file 
-  js9 -a --hostfs true --cmdfile ecnts.js
-
-  // where ecnts.js contains the following Javascript:
-  var fs;
-  try{
-      fs = require("fs");
-  }
-  catch(e){
-      JS9.error("Node.js 'fs' module is unavailable. Did you enable hostfs?");
-  }
-  JS9.Load("kes75/kes75_evt2.fits.gz", {onload: function(im){
-      let i;
-      let s = "";
-      let got = 0;
-      // energy filters
-      const f = ["energy=500:1500", "energy=1500:2500", "energy=2500:8000"];
-      // get counts in regions as each image is displayed
-      const getcnts = function(i){
-    	return function(xim){
-  	    s += xim.countsInRegions();
-  	    got++;
-  	    if( got === 3 ){
-                // write the results to a log file
-  		fs.writeFile("countsInRegions.log", s, function(err) {
-		    if( err ) { JS9.error(err); }
-  		}); 
-  	    }
-    	};
-      };
-      // process each of the event filters to make a separate image
-      for(i=0; i<f.length; i++){
-    	// display filtered image in a separate displayed
-    	JS9.DisplaySection({filter:f[i], separate:true,
-    			    ondisplaysection: getcnts(i)}, {display: im});
-      }
-  }});
-
- -

-For a list of all js9 script switches, use the --help switch: -

-  js9 --help
-
- -

-The JS9 File menu contains two options only available for Desktop use: -

    -
  • print window ... print the entire Electron.js window -
  • save window to pdf save the entire Electron.js windows to a PDF file -called js9.pdf in the current directory -
-The print command always brings up a dialog box. The save command will save the -window as a PDF in the current directory, without bringing up a dialog box. - -

Security Notes

- -

-It is important to note that Electron.js is not a web -browser, and web pages you load are not sandboxed. Our JS9 desktop -application code takes additional precautions to enhance security: -

    -
  • http protocol is disabled for remote pages -
  • Javascript eval is disabled in web pages -
  • the ability to click a link to navigate to a new web page is disabled -
  • the ability to click a link to display to a new web page in a different tab or window is enabled, but the new web page is displayed in your default browser -
  • context isolation is turned on, unless host file system support is explicitly enabled (--hostfs) -
- -

-Even with these safeguards in place, it is important that you load -only local or trusted remote web pages into the JS9 desktop app. -See: -Electron.js security for more information. - -

-You should update your copy of Electron.js periodically to ensure that you -have the latest security fixes in place. - -

Last updated: October 30, 2020
-
- - - diff --git a/web/static/js9_old/help/extmsg.html b/web/static/js9_old/help/extmsg.html deleted file mode 100644 index e5af3b90d8fb5d0191fc0561c22763330f1b21f9..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/extmsg.html +++ /dev/null @@ -1,363 +0,0 @@ - - - - - -External Communication with JS9 - - - -
-

External Communication with JS9

- -

-External communication with a JS9 display is supported by the js9 -script, which is supplied with the JS9 source code. Alternatively, -if you have installed a pre-built JS9 app (js9app or Voyager), -you can export a messaging script using the -File->export messaging script menu option. The script will be called -js9msg for js9app and vger for Voyager. -Note that it is not strictly necessary to install Node.js or -Electron.js to send external messages: the js9 script utilizes wget -or curl under the hood. - -

-To display the js9 script options, type: -

-  sh> js9 --help
-
- -

-The js9 script supports two types of syntax: -

    -
  • console: a lightweight set of commands from the JS9 Console plugin -
  • public api: all of the routines available in the -JS9 Public API -
- -

-The console syntax offers a restricted set of commands suitable for quick -interactive use. Results are returned as simple strings: -

-  sh> js9 cmap heat        # change colormap to heat
-  OK
-  sh> js9 cmap             # return the current colormap
-  heat
-
-The console commands include: -
-  analysis	list/run analysis for current image (run)
-  colormap	set/get colormap for current image (cmap)
-  colormaps	get list of available colormaps (cmaps)
-  global	set/get a JS9.globalOpts parameter
-  grid		set/get coordinate grid for current image
-  help		get list of available commands
-  helper	set/get helper connection
-  image		get name of current image or display specified image
-  images	get list of currently loaded images
-  load		load image(s)
-  pan		set/get pan location for current image
-  pix2wcs	get image pixel value for specified wcs position
-  print		print image window
-  refresh	refresh image using specified file (def: use last file)
-  regcnts	counts in regions for current image
-  regions	add or list region(s) (reg, region)
-  resize	set/get display size for current image
-  scale		set/get scaling for current image
-  scales	get list of available scales
-  section	display section of current image
-  status	get status for specified (or current) image
-  url		display a url
-  wcssys	set/get wcs system for current image
-  wcsu		set/get wcs units used for current image
-  wcssystems	get list of available wcs systems
-  wcsunits	get list of available wcs units
-  wcs2pix	get wcs position for specified image pixel
-  zoom		set/get zoom for current image
-
- -

-The JS9 Public API syntax offers the full -power of the public API. It passes and returns JSON-formatted strings -with a richer set of options than is available via the console syntax: -

-  # add a red circle region
-  sh> js9 AddRegions circle '{"color":"red", "tags": "foo"}'
-  # change color of all regions to violet and change the tags too
-  sh> js9 ChangeRegions all '{"color":"violet","tags":"goo"}'
-  # change color of selected regions to violet and change the tags too
-  sh> js9 ChangeRegions selected '{"color":"violet","tags":"goo"}'
-  # change color of red regions to violet
-  sh> js9 ChangeRegions red '{"color":"violet"}'
-  # change color of regions with "source" tag to violet
-  sh> js9 ChangeRegions source '{"color":"violet"}'
-  # get colormap
-  sh> js9 GetColormap
-  {"colormap":"grey","contrast":"3","bias":"0.8"}
-  # set colormap
-  sh> js9 SetColormap viridis 1 0.5
-  # get scale parameters
-  sh> js9 GetScale 
-  {"scale":"log","scalemin":0,"scalemax":51}
-  # set scale in a different display
-  sh> js9 SetScale linear '{"display":"myJS9"}'
-
-Passed arguments are the same as the public API arguments, -except that objects are passed as JSON strings. Returned objects -are also in JSON format. Note in the last example above that the -display object argument of the public API calls is supported. -See JS9 Public API for more information. - -

-An example of the use of the public API is given in the shell script -below, where we load the Chandra image of the Kes 75 supernova -remnant, display three energy cuts as separate images, assign red, -green, and blue colormaps to the three energy cuts, and then blend -them into a single display: -

-  #!/bin/bash
-  # Chandra event file of the Kes75 SNR
-  file="kes75/kes75_evt2.fits.gz"
-
-  # some Chandra energy filters
-  filter[1]="energy=500:1500"
-  filter[2]="energy=1500:2500"
-  filter[3]="energy=2500:8000"
-
-  # RGB colormaps
-  cmap[1]="red"
-  cmap[2]="green"
-  cmap[3]="blue"
-
-  # load event file
-  echo "loading event file: $file"
-  js9load $file
-  # turn blending off (since default is on)
-  js9 BlendImage false
-
-  # process each of the event filters
-  for i in {1..3}; do
-    echo "filter: ${filter[$i]}"
-    # generate section using event filter into a separately displayed image
-    js9 DisplaySection '{"filter":"'${filter[$i]}'","separate":true}'
-    # this actually takes a bit of time
-    sleep 4
-    j=`expr $i + 1`
-    # the new file with have a <n> string appended to the original id
-    id="kes75_evt2.fits.gz[EVENTS]<$j>"
-    # set image scale and assign one of the RGB colormaps
-    js9 SetScale "log"            '{"display":"'$id'"}'
-    js9 SetColormap "${cmap[$i]}" '{"display":"'$id'"}'
-  done
-
-  # blend all the images
-  js9 BlendDisplay true
-  echo "all done!"
-
-Note the use of the js9load script to load an image. This -auxiliary script uses the Load and GetLoadStatus API -calls to load an image and wait for completion before returning. -The default wait time is 10 seconds, but is configurable on -the command line. - -

-The rules governing whether a js9 script can talk to a JS9 instance -are determined by the globalOpts.remoteMsgs property supplied to the -back-end helper at start-up. The options are: -

    -
  • < 0: no external communication is allowed -
  • ≥ 0: localhost can send to localhost -
  • ≥ 1: and same host can send to same host -
  • ≥ 2: and localhost can send to any host -
  • ≥ 3: and any host can send to any host -
-The default is 1: a message from a given host can be sent to instances started -on that same host. - -

-If a JS9 instance is connected to a helper on a remote host, you can -use the --host or --helper switch to specify the remote -host to contact. For example, if the helper is running on -js9.cfa.harvard.edu, you can send a command to your instance of JS9 -this way: -

-  sh> js9 --host https://js9.si.edu:443 region circle
-  OK
-
-(Note that the main JS9 web site uses a reverse proxy to communicate -with an internal-facing JS9 helper. You send a message to the main web -server port 443, and it is relayed to the helper listening internally -on port 2718.) -

-If more than one instance of JS9 appears on a single web page, the ---id switch can differentiate between instances. The value of -the id switch is the div id for that JS9 instance. For example, if -two instances of JS9 having div ids of "JS9" and "myJS9" are defined -on the same page, then js9 can communicate with the latter in this way: -

-  sh> js9 --id myJS9 region circle
-  OK
-  sh> js9 --id myJS9 region 
-  ICRS; circle(23:23:26.929, +58:48:50.381, 14.76")
-
-or, from the readline loop: -
-  sh> js9 --id myJS9
-  JS9> region circle(23:23:26.929, +58:48:50.381, 14.76")
-  OK
-  JS9> region
-  ICRS; circle(23:23:26.929, +58:48:50.381, 14.76")
-
-

-Putting the last two techniques together, you can talk to one of many JS9 -instances on a page connected to a remote helper this way: -

-  sh> js9 --host https://js9.si.edu:443 --id myJS9 cmap heat
-  OK
-
- -

-NB: The following options are available with the canonical js9 script, -but not with the script that is exported from a pre-built JS9 app using -the File->export messaging script menu option. These options -require you to have installed the Node.js or Electron.js, since they call -js9Msg.js under the hood. - -

-If the -p or --pipe switch is supplied, the script will read -commands from stdin. You can send multiple commands to the script's -standard input (comments and blank lines are ignored): -

-  sh> cat test.cmds
-  # colormap
-  cmap heat
-  # scale
-  scale log
-  # regions using image coords
-  region circle {"x":588, "y":590, "radius":30, "tags":"source"}
-  region circle {"x":390, "y":430, "radius":50, "tags":"background"}
-  sh> cat test.cmds | js9 -
-
-

-DS9/Funtools region syntax can also be used for regions: -

-  sh> cat test2.cmds
-  cmap heat
-  scale log
-  wcssys fk5
-  region box(23:23:35.236,+58:50:00.95,39.352",20.1679",24.0163)
-  region ellipse(23:23:33.323,+58:47:41.50,29.6394",11.0139",25.7599)
-  region polygon(23:23:19.379,+58:49:30.02,23:23:17.270,+58:49:40.93,23:23:14.834,+58:49:38.59,23:23:17.974,+58:49:13.64) {"tags": "background"}
-  sh> cat test2.cmds | js9 -
-
- -

-The -p or --pipe switch also allows you to specify a -string on the JS9 command line that will prefix all lines read from -stdin. This allows you to send a regions file to JS9: -

-  sh> cat ds9.reg
-  # Region file format: DS9 version 4.1
-  global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1
-  fk5
-  box(23:23:35.236,+58:50:00.95,39.352",20.1679",24.0163)
-  ellipse(23:23:33.323,+58:47:41.50,29.6394",11.0139",25.7599)
-  polygon(23:23:19.379,+58:49:30.02,23:23:17.270,+58:49:40.93,23:23:14.834,+58:49:38.59,23:23:17.974,+58:49:13.64) # background
-  sh> cat ds9.reg | js9 - region
-
-Without the - ("dash") argument, standard input will not be read and -the "region" command will be executed to return current regions. - -

-Ordinarily, the js9 script talks to a displayed JS9 web page. It also can be -used to start the JS9 Desktop app and load an image into the app's web page. -The JS9 Desktop app simply requires that you install Electron.js, which is -available here: -

-  https://www.electronjs.org/
-
-Once this is done, use the -a switch to specify the app startup and -the -w or --webpage switch to specify a web page (default is a -nice, basic JS9 web page). -
-  sh> js9 -a ~/data/casa.fits
-
-will start the JS9 Desktop app with a basic JS9 web page and load the -Cas-A FITS files into the page, while: -
-  sh> js9 -a --webpage ~/js9/js9basics.html ~/data/casa.fits
-
-will display the same image in one of the JS9 demo pages. -For more details, see: Desktop JS9. - -

-The js9 script also can be used to start up a new browser, display a -JS9 web page, and then load an image into that page. To do this, use -the -b or --browser switch to specify the browser (chrome, -safari, or firefox) and the -w or --webpage switch to specify a -web page (default is a basic JS9 web page). For example: -

-  sh> js9 -b chrome ~/data/casa.fits
-
-will start a Chrome browser with a basic JS9 web page and load the -Cas-A FITS files into the page, while: -
-  sh> js9 -b firefox -w ~/js9/js9basics.html ~/data/casa.fits
-
-will use Firefox to display the same image in one of the JS9 demo pages. - -

-Instead of supplying the browser name each time on the command line, you -can set the environment variable JS9_BROWSER and just use the --b switch with no argument. (Note that you still must supply the -b -switch, which tells the script to start a browser.) Similarly, the default -web page can be configured using the JS9_WEBPAGE environment variable: -

-  sh> export JS9_BROWSER=chrome
-  sh> export JS9_WEBPAGE=$HOME/js9/js9basics.html
-  sh> js9 -b ~/data/casa.fits
-
- -

-Care must be taken that no JS9 web page is already being displayed when the --b or --browser switch is utilized, or else the specified image -will be loaded into the existing web page (and no new browser will be started). -Also, it is important to note that the Google Chrome browser must be -started by the js9 script or it must be started by you using the ---allow-file-access-from-files switch. Without this switch, -Chrome will not permit a local HTML file to read other files. Finally, -Mac OSX Safari occasionally experiences delayed data transfers when -the js9 messaging script is located in a different Space (desktop) -from the browser window, so keep these in the same Space. - -

-If you do not have access to the js9 script, you can still send -messages to a JS9 web page using wget or curl. This is possible -because the JS9 helper also listens for HTTP connections. The syntax -for HTTP-based commands is analogous to the scripting syntax, if -somewhat more primitive: you pass a JSON-formatted string to the -helper in a GET or POST request, as show below. -

-  export MYHOST="https://js9.si.edu:443"
-  export ID="JS9"
-  export WARGS="-q -O-"
-  # GET request, using public api:
-  wget $WARGS $MYHOST'/msg?{"id": "'$ID'", "cmd": "GetColormap"}'
-  wget $WARGS $MYHOST'/msg?{"id": "'$ID'", "cmd": "SetColormap", "args": ["red"]}'
-  wget $WARGS $MYHOST'/msg?{"id": "'$ID'", "cmd": "RunAnalysis", "args": ["counts"]}'
-  # GET request, using command line api:
-  wget $WARGS $MYHOST'/msg?{"id": "'$ID'", "cmd": "zoom"}'
-  wget $WARGS $MYHOST'/msg?{"id": "'$ID'", "cmd": "zoom", "args": [2]}'
-  wget $WARGS $MYHOST'/msg?{"id": "'$ID'", "cmd": "analysis", "args": ["counts"]}'
-  # POST request, using public api:
-  wget $WARGS --post-data='{"id": "'$ID'", "cmd": "GetColormap"}' $MYHOST/msg
-  wget $WARGS --post-data='{"id": "'$ID'", "cmd": "SetColormap", "args": ["red"]}' $MYHOST/msg
-  wget $WARGS --post-data='{"id": "'$ID'", "cmd": "RunAnalysis", "args": ["counts"]}' $MYHOST/msg
-
- -
Last updated: September 2, 2021
-
- - - diff --git a/web/static/js9_old/help/helper.html b/web/static/js9_old/help/helper.html deleted file mode 100644 index 08e1a1b413150cf5ac1ea78823c103ef65b8a33d..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/helper.html +++ /dev/null @@ -1,319 +0,0 @@ - - - - - -Adding a JS9 Server-side Helper - - - -
-

Adding a JS9 Server-side Helper

- -

Do You Need a Server-side Helper? Which One?

- -

-JS9 supports server-side analysis on FITS data, allowing you to -execute virtually any command-line analysis program from JS9, run that -analysis command on the server, and view results on your web page. It -also can support external communication with JS9 (via the shell and -Python) and handle the display of large files. - -

-The server-side analysis capability is useful for archive centers and -individual users who want to integrate their own data analysis -programs into JS9. You configure a JS9 server-side helper by adding -additional switches to the configure command described in -Installing JS9. - -

-JS9 supports two mechanisms for server-side analysis: you can run a -separate Node.js-based server to process requests -using socket.io, or use CGI calls to your own web server. The -Node.js server-side helper is the recommended method: it is faster and -more flexible than the CGI helper: in addition to analysis tasks, -Node-js-based helper also supports: -

- -

Add Switches to Configure the Server-side Helper

-

-JS9 is built using the standard GNU ./configure; make; make -install method. To configure server-side analysis, you -add switches to the configure command line. The most important switches are: -

---with-helper=[type]    type of helper: nodejs (for Node.js) , get (for CGI)
---prefix=[path]         location to install the non-web programs and scripts
---with-cfitsio=[path]   cfitsio location for building js9helper, e.g., /usr/local
-
-Other less-used switches are: -
---with-cgidir=[path]     cgi install directory e.g., /var/www/public_html/cgi-bin
---with-cgiurl=[url]      cgi url relative to the web root, e.g.. ./cgi-bin/js9
---with-cgixpath=[dirs]   directories to add to cgi path
-
- -

-Both the Node.js and CGI helpers make use of a C program called -js9helper to handle certain types of JS9 requests. To support -extraction of FITS representation files from large FITS files, -js9helper must be linked against the cfitsio library (version 3.39 or -later is preferred). Cfitsio is the de facto standard FITS library -and is available from NASA/HEASARC at the Goddard Space Flight Center: -

-    https://heasarc.gsfc.nasa.gov/fitsio/fitsio.html
-
-To tell configure where cfitsio libraries are located, use the ---with-cfitsio=[dir] switch, e.g., --with-cfitsio=/usr/local will find -the cfitsio libraries in /usr/local/lib and include files in -/usr/local/include. If cfitsio is not used in the build, the js9helper will -still support server-side analysis, but will not support representation files. - -

-Note that the non-web files, programs, and scripts (e.g., js9helper) -will be installed in accordance with the standard GNU ---prefix=[dir] switch. The default is /usr/local. - -

-Example configure commands are shown below for a typical Linux Apache setup -(using CGI) and for a personal Mac setup (using Node.js): -

-  linux-cgi)
-  ./configure 	--prefix=/soft/saord					\
-		--with-helper=get					\
-		--with-webdir=/var/www/htdocs/js9			\
-		--with-cgidir=/var/www/cgi-bin/js9			\
-		--with-cgiurl=./cgi-bin/js9				\
-		--with-cgixpath=/soft/saord/bin				\
-		--with-cfitsio=/soft/saord				\
-  		CC=gcc $*
-
-  mac-nodejs)
-  ./configure 	--prefix=$HOME						\
-		--with-helper=nodejs					\
-		--with-webdir=/Users/me/Sites/js9			\
-		--with-cfitsio=/Users/me/soft				\
-		CC=gcc $*
-
-
-In these examples, the JS9 web files (JavaScript, CSS etc.) will be -installed in a js9 sub-directory of htdocs in the /var/www directory -or in the Mac user's personal Sites directory. JS9 CGI files will be -installed in a subdirectory of the cgi-bin directory. C programs and -shell scripts will be installed in sub-directories of the user's home -directory or the system-wide /soft/saord directory. - -

Build the JS9 System

-

Once the configure arguments are set up, you run configure, etc. -as described in the basic install instructions at: -Installing JS9. -

-Some additional notes on getting the server-side helpers working are -added below. - -

Adding Analysis Tasks

-

-When configuring server-side analysis, you add server-side analysis tasks -to JS9 (or change the default analysis tasks) by adding or modifying -json files in the analysis-plugins directory (and optionally, -by adding wrapper files to the analysis-wrappers directory.) -See Server-based Tasks for a description of -how to configure server-side analysis tasks for your site. - -

Notes on Installing the Node.js-based Server-side Helper

-

-The Node.js server-side helper is noticeably faster than CGI. It also -offers more power and flexibility, e.g., the node server supports -external control of the browser from the command line via the -js9 script and it's underlying js9Msg facility -(see External Messaging with JS9 for more -information). However, use of the Node.js helper requires that you -open another internet port to the outside world or configure your web -server to proxy all server-side helper communication to a -non-public-facing Node.js server. - - -Node is available at: -

-    https://nodejs.org/
-
-Please install the most up-to-date version of Node.js available. Once -installed, you must start the server-side JS9 helper from the JS9 web -install directory, i.e. the location where you installed (among other -things) js9.js and the node_modules directory: -
-    # in the bash shell:
-    node js9Helper.js 1>~/logs/js9node.log 2>&1 &
-    # or, in the tcsh shell:
-    node js9Helper.js >& ~/logs/js9node.log &
-
-Unlike CGI, Node can be run as any user: it does not have to be run as -the http daemon user. It certainly should not be run as root! We run -it as a non-privileged user with sufficient permissions to run -analysis programs. In any case, it should be run with its Unix PATH -set to include the directory containing the JS9 helper program, as -well as any analysis programs that will be executed by the JS9 -server-side helper when requested by the client. The PATH also should -include the directories housing standard Unix tools such as awk, sed, -grep, and echo. - -

-Communication between the JS9 helper and the browser (or desktop) -utilizes the socket.io protocol and library -(see socket.io for -more information). - -

-For security reasons, the log file should be created outside the web -server directory structure. - -

-Clients will automatically connect to the Node.js-based JS9 helper -when an image is loaded into JS9. The server-side helper listens on a -port specified in the js9Prefs.json file by -the globalOpts.helperPort value. The default is 2718, but you -can change this to any open port. - -

-For example, some institutions do not allow non-standard ports to be -open on public-facing hosts. In such a case, the Node.js-based helper -can change its port to a standard port allowed by that institution -(e.g., 8080 or 8000). This can be done by simply changing -the helperPort property in js9prefs.js (for the client) and -js9Prefs.json (for the helper). - -

Installing in a Secure Environment

- -

-If you are running in a secure environment (i.e. your web pages use -https protocol instead of http), then node server also -must be run securely. This is because modern browsers block "active -mixed content". To run the Node.js helper using https protocol -instead of http, create a js9Secure.json file containing path names to -your private key, certificate, and certificate authority files: -

-  {
-      "key":  "/path/to/private.key",
-      "cert": "/path/to/server.certificate",
-      "ca":   "/path/to//certifcate.authority"
-  }
-
-This file will reside in the directory in which the Node.js helper is started. -

-It is imperative that you keep your private key file secure! If -this key is accessed by unauthorized parties, they can masquerade as -your site. The standard recommendation is to change files permission so -that only the Node.js user can read it: -

-   chmod 400 private.key
-
-and keep that user's password safe! - -

Setting up a Web Proxy for the Node.js-based Helper

- -Instead of opening the JS9 helper port on a public-facing server, you can -set up your web server as a reverse proxy to pass requests to a helper -running on a non-public host. Reverse proxy is a standard web server -technique, and is used on the main JS9 web site. - -

-Documentation concerning setting up a proxy for the helper's -underlying socket.io -library can be found in the - -behind a reverse proxy page. Additional information can be found in these -(slightly out of date) - -socket.io issue and -stackoverflow pages. - -

-A variation of the following httpd.conf (or ssl.conf for https) -configuration should work on Apache web servers: - -

-  # js9 client connects to main server => rewrites to js9 helper on 2718
-  # NB: helper does not use ssl (ssl-based proxy doesn't work, afaik)
-  RewriteEngine    on
-
-  # new style:
-  # https://socket.io/docs/v4/reverse-proxy/
-  RewriteCond      %{HTTP:Upgrade}    websocket                 [NC]
-  RewriteCond      %{HTTP:Connection} upgrade                   [NC]
-  RewriteRule      ^/?(.*)            ws://localhost:2718/$1    [P]
-
-  # old style:
-  # https://stackoverflow.com/questions/36472920/apache-proxy-configuration-for-socket-io-project-not-in-root
-  # RewriteCond    %{REQUEST_URI}     ^/socket.io               [NC]
-  # RewriteCond    %{QUERY_STRING}    transport=websocket       [NC]
-  # RewriteRule    ^/?(.*)            ws://localhost:2718/$1    [P]
-
-  ProxyPass        /socket.io         http://localhost:2718/socket.io
-  ProxyPassReverse /socket.io         http://localhost:2718/socket.io
-
-  # required to handle js9msg requests to the helper's httpd support:
-  RewriteCond      %{REQUEST_URI}     ^/msg                     [NC]
-  RewriteRule      ^/?(.*)            http://localhost:2718/$1  [P]
-
-The optional ProxyPass of msg allows you to send commands using wget -or curl to the helper. - -

-When configuring a proxy, set the "helperPort" in js9prefs.js to 80 or -443 (or whatever port your web server listens on) so that the browser -connects to the helper via the public-facing web server. Continue to -set the "helperPort" in js9Prefs.json to 2718 (or whatever port you -choose), so that the helper listens on its own port. This is a special -situation where the ports will be different for the client and the helper. - -

Notes on the CGI-based Server-side helper

- -

-If you want to utilize a CGI-based -helper, you must specify the --with-cgidir -and --with-cgiurl switches on the configure command -line. Optionally, you also can specify the ---with-cgixpath switch if you want to add directories to the CGI path: - -

    -
  • The --with-cgidir switch specifies the directory into which to -install the js9Helper.cgi wrapper script. That script is generated by -the build. All CGI requests are processed through this js9Helper.cgi wrapper. - -
  • The --with-cgiurl switch specifies the URL of the -js9Helper.cgi script relative to your web document root. The -value of this switch is combined with the CGI wrapper filename and the -result stored in the js9Prefs.json file, telling JS9 how to call the -CGI helper script. - -
  • The --with-cgxpath switch specifies a semi-colon delimited -list of directories to add to the CGI path. You can use this switch to -make accessible the executables that will be used in your CGI -processing. Of course, setting up the CGI path also can be done in -many ways, e.g., inside your analysis wrapper scripts or even in the -web server itself. -
- -

-After the build is complete, the globalOpts.helperType variable -in the js9Prefs.json file should have a value of "get" and JS9 -will send messages via the specified CGI command, utilizing the -js9Helper.cgi script. - -

-Of course, you must now ensure that your web server can run the -js9Helper.cgi script successfully to execute JS9 CGI commands. Normal -web debugging techniques come into play here: check the CGI section of -your web server's configuration file and review the web access and -error logs. If you continue to have problems, please let us know and -we will try to help. - -

Last updated: July 13, 2021
-
- - - diff --git a/web/static/js9_old/help/install.html b/web/static/js9_old/help/install.html deleted file mode 100644 index 8e2d78332e488cffda0539bf984e4b06325b7b02..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/install.html +++ /dev/null @@ -1,389 +0,0 @@ - - - - - -Installing JS9 - - - -
-

Installing JS9

- -

Summary for the Impatient

-
    -
  • retrieve and unpack the source code tar file or clone the js9 repository -
  • run a simple web server in the js9 dir: python3 -u -m http.server 8000 -
  • load localhost:8080/js9.html -
  • JS9 is now ready for drag-and-drop image files -
  • run "./mkjs9 -q" to set up the js9 command-line script in its simplest form -
  • to install JS9 into a web server tree, run configure with this switch: -
    -  # location to install the JS9 web files:
    -  ./configure --with-webdir=[path_to_web_install]
    -
    -
  • to add large file support, build the helper with these switches: -
    -  # where to find cfitsio and install binaries, what sort of helper to build:
    -  ./configure  --with-cfitsio=[path_to_cfitsio] --prefix=[path_to_prog_install] --with-helper=nodejs
    -
    -
  • edit the js9prefs.js to set up your site-specific JS9 parameters -
  • build, install, clean up: make; make install; make clean -
- -

Retrieve and Unpack the Source Code Tar File

-

-The current release of the JS9 source tar file is available at: -

-    https://js9.si.edu
-
-The source tar file will unpack into a js9-[version] directory with -the usual tar command, e.g: -
-    tar xfz js9-[version].tar.gz
-
-The most up to date version of JS9 is available on GitHub: -
-    git clone https://github.com/ericmandel/js9
-
-The GitHub version will contain the latest bug fixes and improvements. -Once you have cloned JS9, you can retrieve the latest update: -
-    git pull
-
-Note that the main JS9 web site runs the latest software from GitHub. - -

Run JS9 using a simple web server or maybe using the file:// URI

-After the source code is retrieved, you can start using JS9 immediately -by running a Python3 web server in the js9 directory, e.g.: -
-  # web pages are loaded relative to the directory in which the server is run
-  # use any port number of your choice, above 1024
-  python3 -u -m http.server 8000
-
-You then can load web pages using localhost:8000 as the domain, e.g.: -
-  # basic js9 web page
-  http://localhost:8000/js9.html
-  # demo web page with imexam plugins
-  http://localhost:8000/demos/js9imexam.html
-
-You can drag any FITS image file onto the JS9 display and view -it, change contrast/bias, colormaps, scale, create regions, etc. - -

-You also should be able to load any of the JS9 web pages into your -browser using the file:// URI and no web server. For example, if you -unpacked the tar file into /Users/me on a Mac, then you should be able -to point your browser to: -

-    file:///Users/me/js9-[version]/js9.html
-
-to see the basic JS9 page without starting a web server. -

-Unfortunately, browser developers are making use of the file://URI -increasingly difficult. By default, it does not work in Google Chrome, -since default Chrome doesn't permit a local HTML file to read other -local files. Instead, you must start Chrome with the ---allow-file-access-from-files switch: -

-    # Linux:
-    chrome --allow-file-access-from-files
-    # Mac:
-    open /Applications/Google\ Chrome.app --args --allow-file-access-from-files
-
-

-Firefox now also restricts use of the file:// URI, as documented -here. For Firefox, the work-around is turn off -the privacy.file_unique_origin preference in about:config. -

-If you want to use the file:// URL, please glance at -Known Issues to check the latest -reports about using the file:// URI. It seems that browser developers -are slowly adding more and more restrictions ... - -

-If you just want to run JS9 in this simple way, you are done. However, -you might want to edit the js9prefs.js file to set up default values -for colormaps, scaling, etc. See: -JS9 Site Preferences for a -description of the available parameters. - -

Do You Want to Run JS9 as a Desktop Program from the Command Line?

-JS9 can be used as a desktop replacement for SAOimage DS9: you can -load images into the app's (Chrome) web page (or your own custom web -page) instead of a browser, and use the full power of JS9, including -external messaging. - -

-Running JS9 on the desktop simply requires that you install -Electron.js, an app building -platform that combines Node.js and the Chrome libraries. To install -Electron, go to the - -Electron GitHub release page, choose the latest available -stable release, and download the zip file for your platform. On a -Mac, Electron.app should be installed in the /Applications or -~/Applications directory. On Linux, the electron program should be placed -in your PATH. Note that Electron requires a relatively recent version -of Linux: Ubuntu 12.04, Fedora 21, Debian 8, CentOS 7 (not CentOS 6). - -

-Once the Electron app is installed, generate the JS9 quick-start files: -

-  ./mkjs9 -q
-  Editing js9Prefs.json for Node.js helper ...
-  Editing js9prefs.js for Node.js helper ...
-  Generating js9 script for JS9 messaging and desktop use ...
-
-  If you plan to use Electron.app with JS9, consider codesign'ing it:
-
-  sudo codesign --force --deep --sign - /Applications/Electron.app/Contents/MacOS/Electron/
-
-  This will avoid repeated requests to allow incoming connections.
-
-The mkjs9 script will create a js9prefs.js file (for the browser) and -a js9Prefs.json file (for the JS9 helper), which you can edit to add -preferred JS9 properties, as well as a js9 script to start the JS9 -app. On a Mac, you probably will want to codesign the Electron.app -application to avoid repeated requests about incoming connections (see -example above). - -

-Run the js9 script to start the app and load data files: -

-  # the -a switch tells the script to bring up the desktop js9 app
-  js9 -a ~/data/casa.fits &
-
-and then use the same script to interact with the JS9 page (or any -other JS9-enabled web page): -
-  # without -a, the script sends commands to the JS9 display
-  js9 cmap cool
-  js9 regions circle
-
- -

-For more details, see: Desktop JS9. - -

Do You Want to Install JS9 in a Web Server?

-If you want to run JS9 in a "real" web server, build and install -the JS9 tools and files using the standard GNU procedure: -
-  ./configure --with-webdir=[path] ... other switches ...
-  make
-  make install
-
-At a minimum, you should run configure with the --with-webdir=[path] -switch, which specifies the directory into which the JS9 web files -(JavaScript, CSS, etc.) will be installed. We recommend that this -directory only contain the installed JS9 files, i.e. that you install -JS9 into its own self-contained directory. This will make upgrading to -new versions much easier. - -

-Furthermore, we recommend that you not split up the JS9 files or -install them outside the JS9 install directory. Not only is this -difficult to update, but it actually will break JS9: at runtime, it is -assumed that js9.css is located in the JS9 install directory, and its -actual location is used to determine the JS9 install location relative -to the main web page. If you must move the js9.css file, you will also -need to add the installDir property to the globalOpts -object within js9prefs.js, specifying the relative path from the web -page to the JS9 install directory. Failure to do this correctly will -cause a host of problems, starting with JS9 not loading astroem.js and -js9worker.js. Please contact us if you have problems (the first -indication of which probably will be JavaScript error messages when -failing to load astroem.js and js9worker.js.) - -

-As described in Creating a JS9 Web Page, -a few JavaScript and CSS files must be loaded into a JS9-enabled web page. -Ordinarily this is done in the page's header, which typically will -look something like this: -

-  <head>
-  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-  <meta http-equiv="X-UA-Compatible" content="IE=Edge;chrome=1" >
-  <meta name="viewport" content="width=device-width, initial-scale=1" >
-  <link type="image/x-icon" rel="shortcut icon" href="./favicon.ico">
-  <link type="text/css" rel="stylesheet" href="js9support.css">
-  <link type="text/css" rel="stylesheet" href="js9.css">
-  <script type="text/javascript" src="js9prefs.js"></script>
-  <script type="text/javascript" src="js9support.min.js"></script>
-  <script type="text/javascript" src="js9.min.js"></script>
-  <script type="text/javascript" src="js9plugins.js"></script>
-  </head>
-
-Also during startup, JS9 will asynchronously load -the js9worker.js file in order to create a worker process and -will load either the astroem.js file or the astroemw.js -and astroemw.wasm files, depending on whether -WebAssembly is supported on your browser. - -

-Although none of these files are large, it always is worthwhile making -downloaded files smaller to shorten the web page load time. One -straight-forward way to do this, if you have control of the Apache web -server, is to use the Apache rewrite capability to serve gzip'ed files -in place of requested (uncompressed) files, if the former exist. Using -this technique, your header can remain as shown above, but the Apache -server will send gzip'ed versions when available. To do this, you can -add code such as the following to the Apache httpd.conf: -

-  <IfModule mod_headers.c>
-    # turn on rewrite
-    RewriteEngine on
-
-    # Serve gzip compressed CSS files if they exist
-    # and the client accepts gzip.
-    RewriteCond "%{HTTP:Accept-encoding}" "gzip"
-    RewriteCond "%{REQUEST_FILENAME}\.gz" -s
-    RewriteRule "^(.*)\.css" "$1\.css\.gz" [QSA]
-
-    # Serve gzip compressed JS files if they exist
-    # and the client accepts gzip.
-    RewriteCond "%{HTTP:Accept-encoding}" "gzip"
-    RewriteCond "%{REQUEST_FILENAME}\.gz" -s
-    RewriteRule "^(.*)\.js" "$1\.js\.gz" [QSA]
-
-    # Serve gzip compressed wasm files if they exist
-    # and the client accepts gzip.
-    RewriteCond "%{HTTP:Accept-encoding}" "gzip"
-    RewriteCond "%{REQUEST_FILENAME}\.gz" -s
-    RewriteRule "^(.*)\.wasm" "$1\.wasm\.gz" [QSA]
-
-    # Serve correct content types, and prevent mod_deflate double gzip.
-    RewriteRule "\.css\.gz$" "-" [T=text/css,E=no-gzip:1]
-    RewriteRule "\.js\.gz$" "-" [T=text/javascript,E=no-gzip:1]
-    RewriteRule "\.wasm\.gz$" "-" [T=application/octet-stream,E=no-gzip:1]
-
-    <FilesMatch "(\.js\.gz|\.css\.gz|\.wasm\.gz)$">
-    # Serve correct encoding type.
-    Header append Content-Encoding gzip
-    # Force proxies to cache gzipped &
-    # non-gzipped css/js files separately.
-    Header append Vary Accept-Encoding
-    </FilesMatch>
-  </IfModule>
-
- -

-Note that the JS9 Makefile contains a rule called install-gzip which -will install gzip'ed copies of several JS9 files along side the uncompressed -versions: -

-  ./configure ...
-  make
-  make install
-  make install-gzip
-
- -

Do You Want to Configure Server-side Analysis or External Messaging?

-

-JS9 supports server-side ("back-end") analysis on FITS data using a -server-side helper. This capability allows you to execute virtually -any command-line analysis program from JS9. The analysis command is -run on the back-end server and results viewed on your web page. You can -utilize your own web server as the JS9 back-end helper using CGI -calls, or you can run a separate Node.js-based server to process JS9 -back-end requests. The server-side analysis capability is especially -useful for archive centers, but also can be attractive to individual -users who want to integrate their own data analysis programs into JS9. -

-In addition, JS9 supports -command-line messaging -between the shell and JS9, -pyjs9 Python messaging -between the Python and JS9, -and also has large-file support via the use of -representation files. -These capabilities requires the configuration of a -Node.js-based server-side helper. -

-You configure a JS9 helper by adding additional switches to -the configure command, e.g.: -

-  # where to find cfitsio and install binaries, what sort of helper to build:
-  ./configure  --with-cfitsio=[path_to_cfitsio] --prefix=$HOME --with-helper=nod
-  make
-  make install
-
-See: -Installing a Server-side Helper -for details. - -

Build the JS9 System

-Once you have decided on the configuration of your JS9 system, run -configure to generate various build files: -
-  ./configure [your JS9 switches]
-
-

-and then build the JS9 system using the make command: -

-   make
-
-Minor note: the cloned js9 script will be modified by the build to -include knowledge of the source and install directories. This change -allows you to run using the installed code instead of the source code. -But since this modification will prevent subsequent "git pull" -calls from completing, it will be reset by install or clean. - -

Finalize Your Site Preferences

-

-The js9prefs.js file and js9Prefs.json file contain various default -settings for JS9, e.g. default colormap and scale for image display. -Feel free to edit this file to set up your own site-specific -parameters. See -JS9 Site Preferences for a -description of the available parameters. - -

Install the JS9 System

-

When the build is completed, you can install the JS9 into your web tree: -

-    make install
-
-

-The first time you install JS9, your preference files will also be -installed. After that, the install command will not install these -files in order to avoid overwriting custom files. You can explicitly -re-install preference files using: -

-    make install-prefs
-
-or simply copy them into the install directory. -

-In addition, the install procedure will rename an existing node_modules -directory to onode_modules before installing the node_modules directory. -This action prevents the accumulation of unneeded and possibly conflicting -modules after multiple installs. If you need one or more modules from the -original modules directory, please copy them from onode_modules or -re-install them. - -

-Clean up the build directory using the command: -

-    make clean
-
-

Optionally Install the JS9 Test Data Files

-

-If you want to display our test data files in the JS9 demo pages, -you must retrieve the JS9 data file tar file from the JS9 web site: -

-    https://js9.si.edu
-
-and untar it into the JS9 web install directory. This will create -sub-directories containing the image data. These data files also are -available on GitHub: -
-    https://github.com/ericmandel/js9data
-
- - -
Last updated: July 19, 2021
-
- - - diff --git a/web/static/js9_old/help/knownissues.html b/web/static/js9_old/help/knownissues.html deleted file mode 100644 index a3256e4c8f06e1060aa81aba1fbec8bd57087c9c..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/knownissues.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - -JS9 Known Issues - - - -
-

JS9 Known Issues

- -Unresolved Issues: - -
    - -
  1. All platforms (Always : unresolved) -

    -One of the simplest ways to use JS9 locally is by means of the file:// -URI scheme, e.g., point your browser to file:///home/me/js9/js9.html. -

    -This does not work in Google Chrome because Chrome does not permit a -local HTML file to read other local files. You can read a relatively -emotional argument about this restriction at: -

    -    https://code.google.com/p/chromium/issues/detail?id=37586
    -
    -

    -The workaround is to start Chrome with the ---allow-file-access-from-files switch. On Linux: -

    -    chrome --allow-file-access-from-files
    -
    -On a Mac: -
    -    open /Applications/Google\ Chrome.app --args --allow-file-access-from-files
    -
    -It also does not work on Firefox starting with version 68. See: -
    -https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSRequestNotHttp
    -
    -for details. The workaround (as discussed in that security page) is to -turn off the privacy.file_unique_origin preference in -about:config. -

    -It also doesn't work with Safari for some versions of JS9, i.e., it -seems to work with v3.3 and v3.4 but not v3.3.1. No idea why, but if -you have enabled the Develop menu in Safari, you can -choose Disable Local File Restrictions. (For Develop menu: -choose Safari -> Preferences, click Advanced, then select "Show -Develop menu in menu bar"). -

    -You can bypass the whole file:// CORS problem by using a Python web -server instead. For example, if you start the server in the js9 directory: -

    -  python3 -u -m http.server 8000
    -
    -you then can load the js9.html page at: -
    -  http://localhost:8000/js9.html
    -
    - -
  2. Desktop app (February 11, 2021 : unresolved) -

    -When the js9 script is run with the -b (start a browser) switch on a Mac: -

    -    js9 -b --webpage js9.html
    -
    -we would like to use Safari as the target browser. But executing this command -under the hood: -
    -    open -a Safari --webpage js9.html
    -
    -causes both Safari and your default browser to start up. We therefore use -Chrome instead. If you really want to use Safari, you can run: -
    -    js9 -b safari --webpage js9.html
    -
    -or set the JS9_BROWSER environment variable to "safari". In either case, -try to ensure that Safari is actually running before running js9 with -b, -as this seems to work properly. -

    - -

  3. Desktop app (July 9, 2019 : unresolved) -

    -The Electron.js-based -JS9 desktop app has some limitations when a second instance is started up. -The most obvious concerns the Preferences plugin, which uses -localStorage to save parameters between sessions. -Unfortunately, -Electron.js apps do not properly return localStorage values for -the second (and subsequent) instance. We therefore have disabled the ability -to load and store preferences via localStorage in all but the first -running instance of the JS9 app. - -

  4. Chrome (January 20, 2019 : unresolved) -

    -Chrome's memory restrictions remain more stringent than those of -Firefox or Safari. On a Macbook Pro, it is possible to reproject a -4096x4096 32-bit image in Firefox and Safari, whereas Chrome gets the -"snap" error for 32-bit images larger than approximately 3800x3800. -We will continue to try to reduce memory usage, while hoping for less -restrictive limits (or even full support for unlimited memory via mmap()). - -

  5. Linux platforms using Firefox (February 20, 2018 : unresolved) -

    -One of the simplest ways to use JS9 locally is by means of the file:// -URL scheme, e.g., point your browser to file:///home/me/js9/js9basics.html. -

    -On Linux, although this works in Firefox for files in the web page's -domain, it does not work for files outside the domain: -

    -    JS9.Load("foo.fits")         # works
    -    JS9.Load("fits/foo.fits")    # works
    -    JS9.Load("../foo.fits")      # does not work
    -
    -Firefox does appear to load files outside the web domain properly on a Mac. -

    - -

  6. Webkit (Safari and Chrome) (December 3, 2015 : unresolved) -

    -Webkit browsers such as Safari and Chrome implement resizeable divs in -an unintuitive way, which required several hacks in order to allow us -to resize the JS9 display on the fly. The resizeable (enclosing) div -must be larger than the JS9 display canvas, or else the resize handle -cannot be seen. As a result, the resize handle juts out from the -JS9 display in an unappealing way. Also, the resize operation can only -increase the size of the display, not decrease it. To work around this, -you can first decrease the display size using the View menu, which -sets a new minimum size for GUI-based resize. Finally, the cursor is -not changed to a resize cursor. I couldn't figure out how to work -around this in a fool-proof way. We hope Webkit will implement more -intuitive behavior in the near future. - -

  7. Safari Mobile platforms (April 9, 2015 : unresolved) -

    -A maximum image size is enforced by Apple on Safari mobile devices. -(See https://discussions.apple.com/thread/4975106 for a discussion.) -Images should be restricted to a size of less than -approximately 1900x1900, depending on the size of the FITS header. So -an image file of size 1024x1024 should be fine, while a file of size -2048x2048 certainly will be too large. - -

- -

-Resolved Issues: - -

    - -
  1. Safari (October 4, 2016 : resolved) -

    -On Mac OSX, if the Terminal running the js9 messaging script is -located in a different Space (i.e. desktop) from the Safari browser -with which it is communicating, the transfer of results from the -browser to the script can be delayed up to several seconds. It does -not happen all the time and it does not happen if the two applications -share the same Space. The data transfer also will resume immediately -if you switch to the Space containing the browser. The obvious -work-around is to make sure that the Terminal and browser share the -same Space. -

    -The problems appears to have gone away with MacOS 10.14 (Mojave). - -

  2. All platforms, especially Chrome (June 21, 2014 : resolved) -

    -Available memory can be a problem when loading very large gzip'ed FITS -files, especially in 32-bit Chrome. JS9 currently reads the entire -FITS file or gzip'ed file and inflates parts as needed. It can process -files up to approx. 200Mb in size before Chrome runs out of heap -space. Note that Chrome often will load an ungzip'ed FITS file in -cases where the gzip'ed file fails (though there still are upper -limits on the total space available). We hope that the 64-bit version -of Chrome (in early Canary release as of 7/1/2014) will alleviate -these problems. Otherwise, we will take a more drastic approach to -memory management within JS9 (at the expense of speed). -

    -The 64-bit Chrome can make use of 2Gb of memory. - -

  3. All platforms (June 13, 2014 : resolved) -

    -When resizing a box region in one direction only (i.e., width or -height), the width of the region's border will be different in each -direction. This is due to the underlying graphics algorithm used to -resize the region, which changes the scale factor in each direction -individually and ties the border width to that scale factor. We will -fix this in a future release. -

    -Fixed in Fabric.js v4.x - -

  4. All platforms (May 20, 2013: resolved) -

    -If the "load image" command is part of a group of commands passed to -the js9 script, a race condition can occur when subsequent commands -are executed before the image is fully loaded. To avoid this problem, -images should be loaded in a separate js9 command and the load status -checked for completion before proceeding to manipulate the image. See -the js9load script for details (or just use the script itself -to load images). (Technical details: images are loaded asynchronously, -so that other parts of the web page are available during the load -process. A synchronous load could freeze the web page while -loading. To avoid this situation, external processes should use the -"status load" command to check for a completed load before sending -further processing commands). - -

- -
Last updated: June 1, 2021
-
- - - diff --git a/web/static/js9_old/help/localtasks.html b/web/static/js9_old/help/localtasks.html deleted file mode 100644 index 2a5f3e723e6f02f018053369877724dd36cb1aec..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/localtasks.html +++ /dev/null @@ -1,342 +0,0 @@ - - - - - -Local (Browser-Based) Analysis Tasks and Plugins - - - -
-

Adding Local (Browser-Based) Analysis Tasks and Plugins to JS9

- -

-JS9 supports the ability to perform local analysis, i.e. tasks -executed in your browser (not on the back-end server). This is -accomplished by offering access to the image data and region -information via a -JS9 Public API. Obviously, all of JS9 -JavaScript code is available to you within a web page, but the public -API is designed to stable and well-documented. - -

-

Adding Simple Analysis Tasks to Your Web Page

-

-For simple analysis (i.e., no mouse or keyboard event processing), it -often is sufficient to define GUI elements directly on the web page, -adding Javascript code to interact with these elements and call the -public JS9 functions as needed. In particular, -the JS9.GetImage() function will return a handle for the -currently displayed image and the the various JS9.Region -functions allow you to manipulate regions. These routines are -described in the JS9 Public API. - -

-The js9onchange.html demo web page illustrates these simple -capabilities. It shows how to run a task every time a region -changes, i.e. when it is moved, resized, or deleted. This is -accomplished by setting the JS9.Regions.opts.onchange -parameter to a function (if you are setting via JavaScript) or a -string routine name (if you are setting via json in the prefs file): -

-    // via JavaScript    
-    JS9.Regions.opts.onchange = myRegionChanged;
-
-or: -
-    // from within js9prefs.js
-    { ... "Regions.opts":  {"onchange": "myRegionChanged"} ... }
-
-The calling sequence of the xeqonchange function is: -
-    function myRegionChanged(im, xreg)
-
-where im is the image handle of the currently displayed image, and -xreg is an object containing information about the changed region: -
-  function myRegionChanged(im, xreg){
-    var obj, v;
-    obj = JS9.GetImageData(true, {display: im});
-    # get data value at the center of the region
-    v = obj.data[Math.floor(xreg.y-0.5) * obj.width + Math.floor(xreg.x-0.5)];
-    console.log("cen: %s,%s val: %s", xreg.x.toFixed(2), xreg.y.toFixed(2), v);
-  };
-
-Note that you can turn off region change processing for -individual regions or for all regions by means of the xeqonchange -menu option in a given region's context menu or the global Regions menu, -respectively. - -

-The js9onchange.html demo web page also shows how -server-side JS9 analysis tasks can be executed directly from the -web page using HTML elements (buttons, forms, etc.) instead of the -Analysis menu. See Server-side -Analysis Tasks for more information. - -

-

Adding Plugins to Your Web Page

-

-For anything other than the simplest analysis, you can write a JS9 -Plugin module. A plugin is a Javascript module that contains -a constructor function to create a plugin GUI, and, optionally, -one or more event callbacks to process desired events. When -the file is loaded, the plugin should call RegisterPlugin() to -make itself known to JS9. Plugin modules should be stored in the -js9/plugins directory (or in a sub-directory therein) and should be -loaded into JS9-enabled web pages after js9.js itself is loaded. - -

-To create instances of the plugin GUI, the constructor function gets -called for each plugin div defined on the web page. -The this context is seeded with a few JS9 properties, including: -

    -
  • this.div: the DOM element representing the div for this plugin -
  • this.divjq: the jquery object representing the div for this plugin -
  • this.id: the id of the div (or the plugin name as a default) -
  • this.winType: "div" (in-page div element) or "light" (from view menu) -
  • this.winHandle: handle returned from light window create routine -
  • this.display: the display object associated with this plugin -
  • this.plugin: plugin class object (contains user opts in opts sub-object) -
  • this.status: "active" or "inactive" or undefined -
-The most important of these properties is the div property -specifying the DOM element of the containing div. You add your GUI -(HTML elements) to this.div and use the events to control -the action. The type property tells you whether the instance is -being created for an in-page div element or from the View menu, in -case configuration is different for these cases. -The plugintest.js module -provides a fairly complete example and should be studied in -conjunction with this help page. - -

-A JS9 plugin is registered at the end of the module using -the JS9.RegisterPlugin() public routine: -

-  JS9.RegisterPlugin(xclass, xname, func, opts)
-
-where: -
    -
  • xclass: class of the plugin -
  • xname: name of plugin -
  • func: the constructor function -
  • opts: an object containing plugin options -
-The xclass and xname values together make up -the class of the div element. Thus, if the plugin xclass -is "JS9" and the plugin xname is "Menubar", then the div which -will hold the menubar has a class of "JS9Menubar". Note that these -strings must adhere to CSS grammar rules, e.g., start with a letter, -followed by letters, numbers, dashes and underscores, no spaces allowed. -

-This class/name separation has been made so that multiple plugins can -be written as part of one class and processed together as part of that -class, e.g., displayed together in the View and Help menus. -

-The optional opts object contains the following optional elements: -

    -
  • divArgs: [arg1, arg2, ...] arguments passed to div-based constructor -
  • menuItem: menuname in specified menu (default is View menu) -
  • menu: add plugin to this menu (only View or Analysis right now!) -
  • winDims: [width, height] -
  • winTitle: string -
  • toolbarHTML: string -
  • toolbarSeparate: boolean -
  • help: path html file for help, relative to js9/plugins directory -
- -

-The opts object allows you to specify callback functions that -get triggered by various JS9 events. The calling sequence of these -functions depends on the callback type. The defined callback -types and their standard callbacks are: -

    -
  • image: function(im) -
      -
    • onimageload: an image is loaded -
    • onimageclose: an image is closed -
    • onimagedisplay: an image is (re)displayed -
    • onimagerefresh: an image is refreshed (i.e., new data is supplied) -
    • onplugindisplay: a plugin window is re-displayed -
    • onrawdata: low-level support for when the raw data array is produced -
    -
  • mouse: function(im, ipos, evt) -
      -
    • onmouseup: mouse up events -
    • onmousedown: mouse down events -
    • onmousemove: mouse move events -
    • onmouseover: mouse over events -
    • onmouseout: mouse out events -
    • onclick: click events (down/up with only tiny movement) -
    -
  • keypress: function(im, ipos, evt) -
      -
    • onkeydown: keydown events -
    • onkeypress: keypress events (keydown + keyup) -
    -
  • shape: function(im, xreg) -
      -
    • on[layer]change: a shapes changes in a layer (e.g., "onregionschange" for region changes) -
    -
-

-You can globally toggle execution of all plugin callbacks by setting -the value of the JS9.globalOpts.xeqPlugins property to true or false. -

-In addition to these standard callbacks, JS9 also supports an extended set of -image callbacks that get triggered when internal JS9 routines are called. -These callbacks are only active if the JS9.globalOpts.extendedPlugins -property is set to true (which is the default). -

    -
  • onsetpan: called when pan value is set by im.setPan() -
  • onsetzoom called when zoom value is set by im.setZoom() -
  • onsetwcssys called when wcs system is set by im.setWCSSys() -
  • onsetunits called when wcs units is set by im.setWCSUnits() -
  • onsetcolormap called when colormap is set by im.setColormap() -
  • onsetscale called when scale is set by im.setScale() -
  • onrawdatalayer called when a raw data layer is created or modified by im.rawDataLayer() -
  • onfilterrgbimage called when an RGB image is filtered by im.filterRGBImage() -
  • onchangecontrastbias called when the "change contrast/bias" -mouse/touch gesture changes the contrast/bias -
-

-Finally, JS9 supports the onregionsmove callback if the -JS9.globalOpts.intensivePlugins property is set to true (the -default is false). Executing this callback requires that the region -parameters be updated continually as the mouse moves. Such an update -is a relatively intensive operation, so the intensivePlugins property -should only be enabled if you need it. -

-Please let us know if you require a callback to be associated with -another JS9 function. - -

-Each callback function gets executed when the specified event takes -place. The im object is the JS9 image handle, which can be passed to -the display parameter of public API calls to specify the JS9 display -(necessary when there is more than one display on the page); -

-  function onimdisplay(im){
-    arr = JS9.GetRegions({display: im});
-  }
-
-The ipos object contains the one-indexed image position of the mouse: -
-  function onmousemove(im, ipos){
-    var obj, v;
-    obj = JS9.GetImageData(true, {display: im});
-    # get data value at the mouse position
-    v = obj.data[Math.floor(ipos.y-0.5) * obj.width + Math.floor(ipos.x-0.5)];
-    console.log("ipos=%s,%s val=%s", ipos.x.toFixed(2), ipos.y.toFixed(2), v);
-  };
-
-The evt object is the jQuery event that triggered the callback. - -

-The on[layer]change callback gets passed the same xreg -object as is used for the JS9.GetRegions() routine and -the JS9.Regions.opts.onchange parameter: -

-  function myRegionChanged(im, xreg){
-    var obj, v;
-    obj = JS9.GetImageData(true, {display: im});
-    # get data value at the center of the region
-    v = obj.data[Math.floor(xreg.y-0.5) * obj.width + Math.floor(xreg.x-0.5)];
-    console.log("cen: %s,%s val: %s", xreg.x.toFixed(2), xreg.y.toFixed(2), v);
-  };
-
- -

-Holding down the Shift key (where available) will turn off execution of all -mouse event callbacks. This allows you to move the mouse to a specific -location, and then move away without triggering a callback. The -xeqonchange menu option in the Regions menu and each region's -context menu can be used to turn off execution of the region onchange callback. -The former does this globally, the latter only for the specific region. - -

-The divArgs is an array specifying arguments to pass to the constructor -function, when a div element is found in the web page. For example, the Panner -and Magnifier plugins pass a width and height to the constructor in this way. - -

-The menuItem is a string which specifies the name that will be -used in the View menu when a plugin div is not found on the web -page. If no menuItem is specified, the plugin will not appear -in the View menu. - -

-Furthermore, the menu property can be used to change the menu -in which the above-mentioned menuItem plugin will be -placed. For example, an Imexam plugin situates -its plugins in the Analysis menu instead of the View menu. NB: At the -moment, only the View and Analysis menus are supported -for placement. - -

-The winDims is an array specifying the width and height of the -light window that will get created for this plugin via the View -menu. If the winDims dimensions is specified as [0, 0], the plugin is -virtual and is active all the time. This is useful in cases -where you simply want to define callback routines for one or more JS9 -actions. See the example below. - -

-The winTitle is a string specifying the title of the light window. -The default is no title. - -

-You can add HTML (e.g., command buttons) to the light window titlebar -by putting an HTML string into the toolbarHTML property. The -panner and magnifier use this technique to add zoom buttons. You also -can add HTML onto a web page plugin div, but in this case, where the -HTML is placed depends on the value of the toolbarSeparate -property. If the value of toolbarSeparate is true, then a -titlebar is created above the plugin and the HTML is added to it. -Otherwise, the HTML is placed in top of the plugin itself. - -

-The help property specifies the pathname of an html file that will -be placed in the Help menu. This pathname should be relative to -the plugins directory. - -

-Within a callback, you can use the JS9 Public API to manipulate data, as -detailed in the JS9 Public API. - -

-A final example: if you want changes of contrast/bias in one JS9 display -to trigger similar changes in all other displays, you can do this: -

-JS9.RegisterPlugin("MyPlugins", "allconstrastbias",
-		   function(){return;},
-		   {onchangecontrastbias: function(im){
-		       var i, tim, obj;
-		       JS9.globalOpts.xeqPlugins = false;
-		       obj = JS9.GetColormap({display: im});
-		       for(i=0; i<JS9.displays.length; i++){
-			   tim = JS9.displays[i].image;
-			   if( tim && (tim !== im) ){
-			       JS9.SetColormap(obj.contrast, obj.bias,
-					      {display: tim});
-			   }
-		       }
-		       JS9.globalOpts.xeqPlugins = true;
-		   },
-		   winDims: [0, 0]});
-
-Here, a virtual plugin is created with no user interface. It thus is -active all of the time. The plugin defines a single action that gets -triggered when the contrast/bias is changed. This action changes the -contrast/bias of all other displays. Note that the -JS9.globalOpts.xeqPlugins property is set to false temporarily -to avoid recursion. - -

-

Last updated: July 10, 2018
-
- - - diff --git a/web/static/js9_old/help/memory.html b/web/static/js9_old/help/memory.html deleted file mode 100644 index 513fc8dbc1de59e91830b4c0084c0187b4461584..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/memory.html +++ /dev/null @@ -1,207 +0,0 @@ - - - - - -Dealing with Memory Limitations - - - -
-

Dealing with Memory Limitations

- -

-Desktop application developers count on a semi-infinite amount of -memory for applications. This is a luxury not afforded to browser -application developers. Browsers have two memory-related issues that -must kept in mind when developing applications: -

    -
  • browsers often impose per-tab memory limitations -
  • browser memory is managed automatically by garbage collection -(GC) algorithms -
- -

Per-tab memory limits

- -Browser limitations on per-tab memory are not well documented. The -64-bit Chrome browsers are known to have a 4Gb per-tab memory limit. -iOS devices have more stringent limitations: -empirical evidence indicates that the iPhone 6 is limited to 645Mb, the -iPhone 6s to 1Gb, and the iPhone 7 to 2Gb. - -

-To better deal with memory limits, JS9 offers a number of global -parameters in the JS9.globalOpts object. New values for these -parameters can be added to the JS9 preference file. (See -Configuring JS9 Site Preferences -for more information about preferences.) - -The JS9.globalOpts.maxMemory parameter specifies the largest -array size (in bytes) that can be allocated in the heap to hold a FITS -image. The default is currently set to 750000000 (i.e., 750Mb). It is -automatically set to lower values for Chrome (500000000 or 500Mb) and -mobile (300000000). - -

-Similarly, the JS9.globalOpts.image object allows you to set -the max size image section that will be created from a FITS image. -The general default values are {x: 0, y: 0}, where 0 values specify -unlimited section size. For Chrome, the limits are set to {x: 6144, -y: 6144} while for mobile devices, they are set to {x: 4096, y: -4096}. Obviously, these are just empirical guesses on our part! - -

-When a FITS files is displayed by JS9, the file itself is maintained in memory, -which is useful in many cases: -

    -
  • displaying multi-extension FITS files (use the Extensions plugin -to switch between extensions) -
  • displaying data cubes (use the Data Cube plugin to display a different -slice of the image) -
  • binning and filtering X-ray binary tables (use the Binning/Filtering -plugin for binning and filtering) -
  • performing wcs reprojections, including image rotation -
-If none of the above apply to your use of JS9, you can save memory by -removing the virtual FITS file. This can be done manually by choosing -the File -> free image memory option. - -

-Alternatively, the JS9.globalOpts.clearImageMemory parameter -can be used to specify when JS9 should automatically remove the FITS -virtual file after displaying each image. Options include: -

    -
  • never: no automatic removal of the virtual FITS file (default) -
  • always: always remove the virtual FITS file -
  • auto: remove the virtual file if the displayed image is a 2D image (not a table or cube) and there are no other HDU extensions -
  • noExt: remove the virtual file if there are no other HDU extensions -
  • noCube: remove the file is the displayed image is not a cube -
  • size,[x]: remove the file is its size is greater than [x] Mb -
- -

Garbage collection

- -

-In the early days of desktop programming, memory was allocated and -freed explicitly. This allowed fine-grained control over the amount of -memory being used at any one time, but often led to memory leaks if -the developer forgot to free previously allocated memory. - -

-Modern languages, including Javascript, use automatic techniques such as -garbage collection (GC) to manage memory. In principle, memory gets -freed when it is "no longer needed". But since the concept of "no -longer needed" cannot be decided unambiguously, approximate algorithms -are used. - -

-Problems then arise because these garbage collection algorithms are only -run periodically and they do not always identify all of the memory -objects that can be freed. Developers often supply "hints" to the -garbage collector by setting object to null or deleting large -properties of an object. - -

-Because JS9 deals with large chunks of data, garbage collection delays -and misses can lead to larger than expected memory utilization. In May -2017, we found that continuously loading and closing an image was not -freeing memory properly. The problem was traced to two different -factors. First, especially in Chrome, the garbage -collector was not properly sensing that the fileReader result memory -was available for clearing. To remedy the situation, we had to delete -the fileReader result object explicitly: -

-  fileReader = new FileReader();
-  fileReader.onload(function(){
-    ... do work on the fileReader.result array ...
-    // give the garbage collector a hint that we're done with the array
-    delete fileReader.result;
-  });
-  // start reading the file as a an array
-  fileReader.readAsArrayBuffer(fits);
-
-See -http://stackoverflow.com/questions/32102361/filereader-memory-leak for discussion of a similar problem. - -

-Second, we found that if a continuous Javascript loop was too tight, -the GC might not be run. This was especially true of Firefox. In the -example below, each LoadFITS() call is making an xhr() call to check -status of a FITS file, and loading the file using JS9.Load() if necessary. -Since JS9.Load() runs asynchronously, there never was enough -idle time to start the GC, and memory was not released properly. This -situation actually could be seen using the Performance tab in the -Firefox Developer Tools: the GC was run at the start of the loop, but -never run again: -

-  var timeout = 1000;
-  setInterval(function() {
-    LoadFITS("foo1");
-    LoadFITS("foo2");
-  }, timeout);
-
-

-As a remedy, we used a longer timeout and also skipped processing for -a few several cycles over time, to try to ensure that the browser had enough -idle time to start the GC. -

-  var nloop = 0;
-  var modcycle = 1;
-  var loopcycle = 10;
-  var timeout = 3000;
-  setInterval(function() {
-    nloop++;
-    nmod = nloop % loopcycle;
-    // skip modcycle loops to give the GC time to be run
-    if( nmod > modcycle ) {
-      LoadFITS("foo1");
-      LoadFITS("foo2");
-    }
-    // timeout should be long enough to give the GC time to be run
-  }, timeout);
-
-

-Another possible remedy is to reload the page periodically in order to -reset browser memory: -

-  var nloop = 0;
-  var modcycle = 1;
-  var loopcycle = 10;
-  var timeout = 3000;
-  var maxloop = 1800 * 1000 / timeout;
-  setInterval(function() {
-    nloop++;
-    nmod = nloop % loopcycle;
-    // reload page, approx every half hour
-    if( nloop > maxloop ){
-        window.location.href = window.location.href;
-    }
-    // skip modcycle loops to give the GC time to be run
-    if( nmod > modcycle ) {
-      LoadFITS("foo1");
-      LoadFITS("foo2");
-    }
-    // timeout should be long enough to give the GC time to be run
-  }, timeout);
-
-

-If you find that JS9 is taking much more memory than you expect, -especially in situations where images are being loaded in a loop -please let us know and we will try to help diagnose the problem. Note -that Chrome and Firefox Memory both have Memory and Performance -utilities in their Developer Tools that are very useful in -understanding memory allocation issues. - -

-Alternatively, in situations where loading images in a loop is -utilizing more memory than expected, you might consider embedding JS9 -inside an iframe in your web page, and reloading the JS9 page -periodically. This should prevent garbage collection-related memory -problems, because memory is reset each time the page is loaded. - -

Last updated: May 29, 2017
-
- - - diff --git a/web/static/js9_old/help/preferences.html b/web/static/js9_old/help/preferences.html deleted file mode 100644 index 785ac4c1a2f0ddc65cb22e53ef254536b53cda64..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/preferences.html +++ /dev/null @@ -1,171 +0,0 @@ - - - - - -Site Preferences - - - -
-

Configuring JS9 Site Preferences

- -

-JS9 supports a site configuration file that is read after the -JavaScript variables are loaded but before JavaScript code is compiled -and executed. This file allow you to tailor JS9 to meet the needs of -your site without having to modify the js9.js file directly. - -

-To support site configuration, load the JS9 json preference file -file (referred to here as js9prefs-local.js, but it can be named -anything, of course) into your web page before loading other JS9 javascript: -

-  <script type="text/javascript" src="js9prefs-local.js"></script>
-  <script type="text/javascript" src="js9support.min.js"></script>
-  <script type="text/javascript" src="js9.min.js"></script>
-  ...
-
-

-The following example shows the current js9prefs.js file: -

-var JS9Prefs = {
-    "globalOpts": {
-        "helperType":       "nodejs",
-        "helperPort":       2718,
-        "helperCGI":        "./cgi-bin/js9/js9Helper.cgi",
-        "debug":            0,
-        "loadProxy":        true,
-        "workDir":          "./tmp",
-        "workDirQuota":     100,
-        "dataPath":         "$HOME/Desktop:$HOME/data",
-        "analysisPlugins":  "./analysis-plugins",
-        "analysisWrappers": "./analysis-wrappers"
-    },
-    "imageOpts": {
-	"colormap":         "grey",
-	"scale":            "linear"
-    }
-}
-
- -

-This preference file can be used to override the default parameter -settings for JS9. A look through the beginning of JS9 code will show -a number of Javascript objects containing these default -parameters. They all have names ending in Opts, -i.e. JS9.imageOpts, JS9.analysisOpts, etc. A description of some of -these objects is given below: - -

    -
  1. JS9.globalOpts: this JavaScript object contains global -information, including parameters concerned with the back-end services -used by JS9. Many of the most useful JS9 configuration parameters are -contained in this object, including mouse/touch/keyboard actions, -click to focus, catalog properties, image/table default -dimensions/binning, and a host of other properties. - -

    -

  2. JS9.imageOpts: This JavaScript object contains initial -values for parameters associated with individual images, such -as: contrast, bias, whether to invert the -colormap, colormap, scale, WCS system , WCS -units, whether to display value/position, and whether to -list regions when they change (listonchange). - -

  3. JS9.Regions.opts: This JavaScript object contains -default values for individual regions, including the initial size of -various regions, initial inner and outer radii for annuli, initial -angle, etc. You can set or override properties for this object by -adding them to the regionOpts object in the js9prefs.js file. - -

  4. JS9.menuButtonOptsArr: this JavaScript array of objects allows -you to change and re-arrange which menu options are provided. If you -prefix the name of a menu option with '#', that option is disabled. - -

  5. Module: a global JavaScript object with attributes that -Emscripten-generated code calls at various points in its execution. -You can set or override properties for this object by adding them to -the emscriptenOpts object in the js9prefs.js file. One -important case occurs when you have installed the astroemw.wasm binary -file in a location other than the JS9 install directory. You would -then use Emscripten's wasmBinaryFile property to specify a path -to this file, relative to the JS9 install directory. For example, if -the JS9 install directory and the resources directory are at the same -level in the directory hierarchy: -

    -var JS9Prefs = {
    -  "emscriptenOpts": {
    -     "wasmBinaryFile": "../resources/js/astroemw.wasm"
    -  },
    -  # other preferences ...
    -}
    -
    -See Emscripten's -Module Object -documentation for more information, and please let us know if you have problems. - -
-In addition to the above-mentioned objects, the preference file can be -used to set some internal variables. The JS9.DEBUG parameter is an -example, as shown in the default preference file. Ordinarily, users -need not be concerned with these variables. - -

-When a property (e.g. scale) is added to one of the top-level objects -in the JS9Prefs object (e.g. imageOpts), it generally replaces the -existing value on the specified JS9 option. In the previous example, -both the default colormap and default scale will be replaced by the -values specified in the prefs file. Arrays and objects are also -completely replaced. This, in this example, after specifying a new -keyboardActions object, the entire keyboardActions object in JS9.globalOpts -will be replaced by a new object containing two actions only: -

-var JS9Prefs = {
-    "globalOpts": {
-        "keyboardActions": {
-            z: "zoom in",
-            x: "zoom out",
-      },
-    }
-}
-
-In this case, however, you probably wanted to merge the new keyboard -actions into the existing actions object. To perform object merging -instead of replacing, add the special config object: -
-var JS9Prefs = {
-    "config": {
-        "objects": "merge"
-    },
-    "globalOpts": {
-        "keyboardActions": {
-            z: "zoom in",
-            x: "zoom out",
-        },
-    }
-}
-
-This will result in a deep (recursive) copy being performed to merge -the two new keyboardActions properties with the existing properties. - -

-Finally, note that the JS9 Node.js helper utilizes -the js9Prefs.json file for configuration. Please ensure that -the following shared properties defined in these two files are consistent -with one another: -

    -
  • helperType -
  • helperPort -
  • helperCGI -
  • loadProxy -
  • workDir -
  • dataPath -
- -
Last updated: February 15, 2022
-
- - - diff --git a/web/static/js9_old/help/publicapi.html b/web/static/js9_old/help/publicapi.html deleted file mode 100644 index 6333c1c9e519869f394e93ffb218e3a4e0c12f3a..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/publicapi.html +++ /dev/null @@ -1,6418 +0,0 @@ - - - -The JS9 Public API - - - - - -
-

The JS9 Public API

- -

-The JS9 Public API provides a JavaScript programming interface for -interacting with JS9. Obviously, all of JS9 JavaScript code is -available to you within a web page, but the public API is designed to -stable and well-documented for users and web designers. It also will -provide the basis for planned language bindings (Python, perhaps C/Fortran.) -

-In general, the public API routines act on the current image being -displayed in the default JS9 display (i.e., the HTML div element that -defines the JS9 display.) Since most web pages will have only a single -JS9 display, this behavior is usually what you want. It parallels -DS9's behavior in which XPA commands act on the currently displayed -image. For example, to change the colormap of the current image, use: -

-    JS9.SetColormap("cool");
-
- -

-However, for cases where multiple JS9 displays are defined on a -single page, you can specify the specific display to process by -adding an display object argument to the calling sequence with -a single display property: -

-    {display: [display_id]}
-
-where [display_id] is the id of the target JS9 display (i.e. the id of -the HTML div element.) For example, if two JS9 displays with ids "JS9" -and "myJS9", respectively, are present on a single web page, you can -set the colormap of the second one this way: -
-    JS9.SetColormap("cool", {display: "myJS9"})
-
-Note that this display object contains only the display -property and always is specified as the final argument in a call. -

-For image-based API routines (not display-based routines with names ending in -Display, e.g., -JS9.ResizeDisplay or -JS9.BlendDisplay), the -display property can specify an image handle or image id instead of a -JS9 display id. When the image handle in question points to the currently -displayed image, this alternate usage is nothing more than a trivial -optimization. Thus, to call a routine such as -JS9.WCSToPix() -or -JS9.PixtoWCS(): -

-    var im = JS9.GetImage({display: "myJS9"});
-    for(i=0; i<1000; i++){
-      x = ...
-      y = ... 
-      wcs = JS9.PixtoWCS(x, y, {display: im});
-      console.log("%s %s -> %s %s", x, y, wcs.ra, wcs.dec);
-    }
-
-However, the image handle does not need to point to the currently -displayed image. When it does not, the public routine will act on the -image associated with the image handle, not the current image. In -particular, you can use -JS9.LookupImage() -to get the image -handle of any image, and then act on that image. For example, if two -images, foo1.fits and foo2.fits, are loaded into a JS9 display, and -foo1.fits is currently being displayed, you can close foo2.fits this way: -
-    var im = JS9.LookupImage("foo2.fits");
-    if( im ){
-        JS9.CloseImage({display: im});
-    }
-
-

-The optional display object argument generally is not -mentioned in the routines below, but it is always available. - -

-Choose from the following sections: -

- -


-

Loading Images

- -
Load an image into JS9
-

-JS9.Load(url, opts) -

-where: -

    -
  • url: url, in-memory FITS, FITS blob, data object -
  • opts: optional object or JSON string containing image parameters -
-

-Load a FITS file (or a PNG/JPEG file) into JS9. You also can pass -an in-memory buffer containing a FITS file, a blob containing a FITS -file, or a string containing a base64-encoded FITS file. Finally, you -can pass a generic data object containing the following properties: -

    -
  • naxis: number of axes in the image -
  • axis: array of image dimensions for each axis or ... -
  • naxis[n] image dimensions of each axis (naxis1, naxis2, ...) -
  • bitpix: FITS bitpix value -
  • head: object containing header keywords as properties -
  • image: typed data array containing image data (native format) -
  • dmin: data min (optional) -
  • dmax: data max (optional) -
  • refresh: refresh data when reloading image? -
  • allext: load all image extensions? -
  • file: set the file property in cases where the url is a script -
  • id: set the id property -
  • proxy: use experimental CGI proxy to load a remote URL -
-An image URL can only be loaded from the same origin as the JS9 JavaScript code, -which is called the - -Same Origin Policy. This means that this routine cannot load an -image file (i.e., FITS, PNG, or JPG) from an arbitrary URL. You can, -however, load remove URLs using the -JS9.LoadProxy() routine, which -retrieves the image into a temp directory before loading it locally. -

-For FITS files, we are experimenting with a second way to retrieve -remote URLs: using a CGI script that adds the required CORS header to -the retrieved FITS data on the fly. The CGI script is controlled by -the JS9.globalOpts.cgiProxy global property and has the -default value https://js9.si.edu/cgi-bin/FITS-proxy.cgi. If -you pass proxy: true in opts, this CGI script will be used -to retrieve the FITS file and return it with the required CORS header. -

-The JS9.RefreshImage() -and JS9.Load() routines differ in that -the former always updates the data into an existing image, while the -latter generally adds a completely new image to the display. - -

-However, in the case where an image already is loaded, -JS9.Load() does not reload the image -into a new display: this would initiate another (often time-consuming) -download, resulting in two identical images. Instead, behavior is -dependent on the value of the refresh property passed in opts -(or, if that is not set, by the JS9.globalOpts.reloadRefresh -property), as follows: -

    -
  • if refresh is true, the existing image is refreshed -
  • if refresh is false, the existing image is redisplayed -
-The global default is to redisplay instead of refreshing. Site authors can -change this property in js9prefs.js, while users can change this via -the Global tab of the Preferences plugin. -

-To override default image parameters, pass the image opts argument: -

-    JS9.Load("data/fits/casa.fits", {scale:"linear", colormap:"sls"});
-
-You can also pass a regions property to add regions or load a region file: -
-    # but oh my, its dicey mixing quotes and wcs arcsec/arcmin delims
-    JS9.Load("data/fits/casa.fits", {regions:'ICRS; box(23:23:40.340, +58:47:04.059, 29.5", 29.5", 0)'});
-    # much easier to pass a filename, if possible
-    JS9.Load("data/fits/casa.fits", {regions:"casa/casa.reg"});
-
-or a pan position: -
-    # pan to physical coords (usually file coords)
-    JS9.Load("data/fits/casa.fits", {px: 4009, py: 3926});
-    # pan to ra, dec using file's wcs
-    JS9.Load("data/fits/casa.fits", {ra: 350.866689, dec: 58.811671});
-    # pan to ra, dec using specified wcs
-    JS9.Load("data/fits/casa.fits", {wcs: "23:23:27.942 +58:48:42.02 ICRS"});
-
-

-If an onload callback function is specified in opts, it will be called -after the image is loaded. By default, the image handle is passed as -the first argument to the callback: -

-    JS9.Load("data/fits/3c273.fits", {scale: "linear", onload: func});
-#    function func(im){
-#        JS9.SetColormap("rainbow", {display: im});
-#        JS9.SetScale("log", {display: im});
-#    }
-
-

-You can specify the name of a routine as a string (instead of the function -itself): -

-    JS9.Load("data/fits/3c273.fits", {scale: "linear", onload: "myfunc"});'
-
-Assuming the function "myfunc" is defined in the window context, it will be -called with the image handle as the first argument. -

-Note that you can supply arguments along with a string-name function: -

-    JS9.Load("data/fits/3c273.fits", {scale: "linear", onload: "docmap('viridis')"});'
-
-As a convenience, you can also pass a JS9 public routine name: -
-    JS9.Load("data/fits/3c273.fits", {scale: "linear", onload: "SetColormap('viridis')"});'
-
-

-The string-name capability is especially valuable when calling Load() -from the shell or Python using External Messaging: -

-    js9 Load ~/data/coma.fits '{"onload":"SetColormap(viridis,4.5,0.35)"}'
-
-Note that you don't need to quote the string arguments ('viridis' in -the example above), but also note that all arguments are passed as -strings and must be converted to the correct data type in your own -bespoke functions (as is done in JS9 public routines). -

-If your url is a function returning a FITS file (e.g. CGI or PHP -script accessing an archive), the filename will end up being the name -of the script, which probably is not what you want. In this case, you -can set the file property explicitly: -

-    JS9.Load("mycgi?FITSFILE=acisf00361N003_evt2.fits", {file:"acisf00361N003_evt2.fits"})
-
-Similarly, you can set the id property explicitly (without setting the file) to tailor the id for special needs. -

-To load an image into a specified display, pass the display object as the last argument: -

-    JS9.Load("data/fits/3c273.fits", {scale: "linear"}, {display: "myJS9"});
-
-

-See Displaying Your Data for further discussion of -how to use this routine. - -

Load an image into a light window or a new (separate) window
-

-JS9.LoadWindow(url, opts, type, html, winopts) -

-where: -

    -
  • url: url to load -
  • opts: optional object or JSON string containing image parameters and/or the display id -
  • type: "light" or "new" -
  • html: html for the new page (default is to display a menubar above the image and a colorbar below) -
  • winopts: for "light", optional dhtml window options -
-returns: -
    -
  • id: the id of the JS9 display div -
-This routine will load an image into a light-weight window or an entirely new -window. The url and opts arguments are identical to the standard -JS9.Load() call, -except that opts can contain: -
    -
  • id: string specifying the id of the JS9 display being created. -If no id is specified, a unique id is generated. -
  • clone: the id of a display to clone: -the menubar, colorbar, statusbar will be created if and only if they are -present in the cloned display (for light window creation only.) -
-

-The type argument determines whether to create a light-weight -window ("light", which is the default) or a new, separate window ("new".) -

-By default, the created window will contain a Menubar above a JS9 -Display area and a Colorbar below: -

-    <div class='JS9Menubar' id='[id]Menubar'></div>
-    <div class='JS9' id='[id]'></div>
-    <div style="margin-top: 2px;">
-    <div class='JS9Colorbar' id='[id]Colorbar'></div>
-    <div>
-
-You can use the html argument to supply different web page elements -for the window. Furthermore, if you create a light window, a default -set of DynamicDrive dhtmlwindow parameters will be used to make the -window the correct size for the default html: -
-    "width=512px,height=542px,center=1,resize=1,scrolling=1"
-
-You can supply your own parameters for the new dhtmlwindow using the -winOpts argument. See: - -DynamicDrive for more information about their light-weight window. -

-To create a new light window without loading an image, use: -

-    JS9.LoadWindow(null, null, "light");
-
-

-See js9create.html for examples of how to use this routine. - -

Load an image URL into JS9 using a proxy server
-

-JS9.LoadProxy(url, opts) -

-where: -

    -
  • url: remote URL link to load -
  • opts: optional object or JSON string containing image parameters -
-

-Load a FITS, PNG, or JPEG file specified by an arbitrary URL into JS9 using the -JS9 back-end helper as a proxy server. -

-For security reasons, JavaScript contained in one web page can -access data in another web page only if both web pages have the -same origin (i.e., basically coming from the same host.) This -policy is called the - -Same Origin Policy. This means that JS9 cannot load a image files -(i.e., FITS, PNG, or JPG) from an arbitrary URL without using special -techniques. -

-One such technique is - -Cross-Origin Resource Sharing, by which the second server grants -permission to access its image data. Dropbox is CORS-enabled, so that -image files can be loaded directly into JS9. But obviously this requires -that explicit permission be granted by the other server. -

-A second technique is to use a proxy server: the URL is not -loaded directly into JS9, but instead is copied back to the -server from which JS9 itself was loaded. The file is then retrieved by -JS9 from this server so that the "same origin" rules are not violated. -

-The JS9 Node.js back-end helper can be configured to support -proxy server mode by setting the JS9.globalOpts.loadProxy -property. In addition, the back-end server must be configured to -support temporary working directories for each loaded page by setting -the JS9.globalOpts.workDir property. If the back-end server is -thus configured as a proxy server, JS9 will support the JS9.LoadProxy() -call and allow you to load FITS, PNG, and JPG files from arbitrary URLs. -JS9 also will display a open link via proxy menu option in the -File menu. -

-The JS9.LoadProxy() call takes a URL as its first -argument. This URL will be retrieved using curl or wget and stored on -the back-end server in a directory specifically tied to the web -page. (The directory and its contents will be deleted when the page is -unloaded.) JS9 then will load the file from this directory. Note that -since the file resides on the back-end server, all back-end analysis -defined on that server is available. -

-To override default image parameters, pass the image opts argument: -

-    JS9.LoadProxy("http://hea-www.cfa.harvard.edu/~eric/coma.fits", {scale:"linear", colormap:"sls"});'
-
-

-By default, the retrieved file is given a filename based on the base of -the URL. When a gzip'ed file is retrieved, the filename is taken from -the original ungzip'ed file, with a .gz extension added. As an -alternative, you can specify the name of the output file using the ofile -property. -

-    JS9.LoadProxy("http://nxsa.esac.esa.int/nxsa-sl/servlet/data-action-aio?obsno=0801931101&name=OEXPMP&level=MT_PPS&extension=FTZ",
-                  {ofile: "MP_P0801931101EPX000OEXPMP8000.FIT.gz"})
-
- -

-If an onload callback function is specified in opts, it will be called -after the image is loaded: -

-    JS9.LoadProxy("http://hea-www.cfa.harvard.edu/~eric/coma.fits", {scale: "linear", onload: func});'
-
-The image handle is passed as the first argument to the callback. -

-To load an image into a specified display, pass the display object as the last argument: -

-    JS9.LoadProxy("http://hea-www.cfa.harvard.edu/~eric/coma.fits", {scale: "linear"}, {display: "myJS9"});'
-
-

-Note again that not all back-end servers support the proxy functionality. -The main -JS9 web site does support proxy service, and -can be used to view images from arbitrary URLs. - -

Load one or more images when the web page is ready
-

-JS9.Preload(url1, opts1, url2, opts2, ... url2, optsn) -

-where: -

    -
  • url: url to load -
  • opts: optional object or JSON string containing image parameters -
-This routine will pre-load images into a JS9 display. It can be added -to the web page body element using the onload() JavaScript call or -called in a JavaScript init routine tied to onload. See index.html and -js9preload.html for examples. -

-It is worth emphasizing that JS9.Preload() should not be called -until the web page is fully loaded, since JS9 itself is not fully -initialized until then. It is for this reason that JS9.Preload() -generally is called using an onload routine tied to the web page body. - -

-You can load URLs outside the current web page domain if you are running a -JS9 helper which has enabled the server side Proxy Load capability. -See Server-side Analysis Tasks for more information. - -

Get Processing Status
-

-status = JS9.GetStatus(type, id) -

-where: -

    -
  • type: the type of status -
  • id: the id or image handle of the image -
-returns: -
    -
  • status: status of processing -
-This routine returns the status of one of the following specified -asynchronous processing types: "Load", "CreateMosaic", -"DisplaySection", "LoadCatalog", "LoadRegions", "ReprojectData", -"RotateData", "RunAnalysis". -

-A status of "complete" means that the image is fully processed. Other -statuses include: -

    -
  • processing: the image is being processed -
  • loading: the image is in process of loading ("Load" only, for backward compatibility) -
  • error: processing did not complete, due to an error -
  • other: another image is loaded into this display -
  • none: no image is loaded into this display -
-Thus, to check for image load, one can do this in Python: -
-    tfits = "foo.fits"
-    hdul = fits.open(tfits)
-    ...
-    j = JS9()
-    j.Load(hdul, tfits)
-    while j.GetStatus("load", tfits).strip() != "complete":
-        time.sleep(0.1)
-    j.SetZoom(2)
-
- -
Get Load Status
-

-status = JS9.GetLoadStatus(id) -

-where: -

    -
  • id: the id or image handle of the file that was loaded into JS9 -
-returns: -
    -
  • status: status of the load -
-This routine returns the status of the load of this image. -Provided for backward compatibility, it simply calls the more general -JS9.GetStatus() routine with -"Load" as the first argument. -

-A status of "complete" means that the image is fully loaded. Other -statuses include: -

    -
  • loading: the image is in process of loading -
  • error: image did not load due to an error -
  • other: another image is loaded into this display -
  • none: no image is loaded into this display -
-Thus, to check for image load, one can do this in Python: -
-    tfits = "foo.fits"
-    hdul = fits.open(tfits)
-    ...
-    j = JS9()
-    j.Load(hdul, tfits)
-    while j.GetLoadStatus(tfits) != "complete":
-        time.sleep(0.1)
-    j.SetZoom(2)
-
- -


-

Working with Images

- -
Get image handle for the current image
-

-im = JS9.GetImage() -

-returns: -

    -
  • im: image handle -
-

-The routine returns the image handle associated with the current image. -

-The returned image handle can be passed in the display object. This -is marginally more efficient than the default behavior, which is to -determine the current image for each call. - -

Lookup an image by id
-

-im = JS9.LookupImage(id) -

-where: -

    -
  • id: image id -
-

-returns: -

    -
  • im: image handle -
-

-The JS9.LookupImage() routine takes a string id as input and -returns the image handle of the image having that id (or null.) The id -is the same as is found in the File menu list of displayed images. -This routine is similar to the standard -JS9.GetImage() -routine, but returns an image by name, regardless of whether it is -currently being displayed. - -

-You can use this routine, for example, so close an image that is not -currently being displayed. If two images, foo1.fits and foo2.fits, are -loaded into a JS9 display, and foo1.fits is currently being displayed, -you can close foo2.fits this way: -

-    var im = JS9.LookupImage("foo2.fits");
-    if( im ){
-        JS9.CloseImage({display: im});
-    }
-
- -
Get image data and auxiliary info for the specified image
-

-imdata = JS9.GetImageData(dflag) -

-where: -

    -
  • dflag: specifies whether the data should also be returned -
-

-returns: -

    -
  • imdata: image data object -
-

-The image data object contains the following information: -

    -
  • id: the id of the file that was loaded into JS9 -
  • file: the file or URL that was loaded into JS9 -
  • fits: the FITS file associated with this image -
  • source: "fits" if a FITS file was loaded, "img" if PNG or JPEG -
  • imtab: "image" for FITS images and PNG/JPEG files, "table" for FITS binary tables -
  • width: x dimension of image -
  • height: y dimension of image -
  • fwidth: x dimension of image or fully binned table in original file -
  • fheight: y dimension of image or fully binned table in original file -
  • dwidth: width of JS9 display (div element) -
  • dheight: height of JS9 display (div element) -
  • bitpix: FITS bits/pixel of each image element (8 for unsigned char, 16, 32 for signed integer, -32 or -64 for float) -
  • bin: current binning factor -
  • header: JavaScript object containing FITS header values -
  • hdus: JavaScript array containing objects that describe the FITS HDU structure (FITS files only) -
  • data: buffer containing raw data values -
-This call can return raw data for subsequent use in local analysis -tasks. The format of the returned data depends on the exact value -of dflag. If dflag is the boolean value true, an HTML5 -typed array is returned. In JavaScript, typed arrays are more -efficient than ordinary JavaScript arrays, and, in this case, the -returned data is actually just reference to the real JS9 image data -(so be careful about changing values.) -

-If dflag is the string "array", a JavaScript array is returned. -This is not a reference to the real data and will utilize -additional memory, but the values can be manipulated safely. -

-If dflag is the string "base64", a base64-encoded string is -returned. Early on, this seems to be the fastest method of -transferring data via socket.io an external process such as -Python. Currently, the "array" method should generally be used (this -is now the default for the pyjs9 interface to Python.) - -

-The file the path of the FITS file associated with -this image. - -

-The header object contains FITS header keywords. Note that all -HISTORY and COMMENT keywords have two underscores and a numeric value -appended, in order to make them unique within the object. - -

-If you are calling JS9.GetImageData() from an external process (via -the msg protocol), you almost certainly want to set dflag to "array". -Doing so will serialize the data as an array instead of as an object, saving -a considerable amount of transfer data. -

-Given a FITS-standard 1-indexed image pixel x,y, you can find the data value -at that location using: -

-    val = obj.data[Math.floor(y-0.5) * obj.width + Math.floor(x-0.5)];
-
-Note the need to integerize the x and y values: JavaScript arrays are -objects and so floating point array indices do not get truncated -automatically as in C. They will return null values. - -
Get image data for all images loaded into the specified display
-

-imarr = JS9.GetDisplayData() -

-returns: -

    -
  • imdataArr: array of image data objects -
-

-The JS9.GetDisplayData() routine returns an array of image data -objects, one for each images loaded into the specified display. -That is, it returns the same type of information as -JS9.GetImageData(), -but does so for each image associated -with the display, not just the current image. - -

Display an image
-

-JS9.DisplayImage(step) -

-where: -

    -
  • step: starting step to take when displaying the image -
-The display steps are: "colors" (remake color data when cmap has changed), -"scaled" (rescale data values), "primary" (convert scaled data values -to color values), and "display" (write color values to the web page.) -

-The default step is "primary", which displays the image without recalculating -color data, scaled data, etc. This generally is what you want, unless you have -explicitly changed parameter(s) used in a prior step. - -

Re-read the image data and redisplay
-

-JS9.RefreshImage(input, opts) -

-where: -

    -
  • input: object, javascript array, typed array, FITS blob, or string -
  • opts: optional options or function to call when refresh is complete -
-The RefreshImage routine re-reads image data and updates the -the current image. It can be used, for example, in laboratory settings -where data is being gathered in real-time and the JS9 display needs to -be refreshed periodically. The first input argument can be one -of the following: -
    -
  • a text string specifying a new URL to retrieve -
  • a javascript array containing raw image data -
  • a typed array containing raw image data -
  • a blob containing a FITS image file -
  • an object containing a required image property and any of the -following optional properties: -
      -
    • naxis: number of axes in the image -
    • axis: array of image dimensions for each axis or ... -
    • naxis[n]: image dimensions of each axis (naxis1, naxis2, ...) -
    • bitpix: FITS bitpix value -
    • head: object containing header keywords as properties -
    • dmin: data min (optional) -
    • dmax: data max (optional) -
    -
-A text string passed to the input argument is assumed to be a -URL (or local file pathname) to retrieve and utilize when refreshing -the data in the current image. This option is used, for example, where -an external program rewrites the image file, and the new data are then -used to refresh the display. Note that the specified file becomes the -current image file and will be used for subsequent server-based -analysis request as well as refreshImage() calls with a null input -argument (see next paragraph.) -

-If the input argument is null, the current image file is -reloaded, assuming its file path (or URL) is known. For security -reasons, browsers do not expose the path of files loaded via Drag -and Drop or Open Local File. On a local web page, you can -safely use the File -> set this image file's path menu option -to enter the image path here for subsequent reloading (or analysis.) -

-When passing an object as input, the required image -property containing the image data can be a javascript array or a -typed data array. It also can contain a base64-encoded string -containing an array. This latter can be useful when calling -JS9.RefreshImage() via HTTP. -

-Ordinarily, when refreshing an image, there is no need to specify the -optional axis, bitpix, or header properties. But note that you actually -can change these values on the fly, and JS9 will process the new data -correctly. Also, if you do not pass dmin or dmax, they -will be calculated by JS9. -

-Note that you can pass a blob containing a complete FITS image to this -routine. The blob will be passed to the underlying FITS-handler before -being displayed. Thus, processing time is slightly greater than if you just -pass the image data directly. -

-The second optional argument can be an object containing the following: -

    -
  • onrefresh: function to perform when refresh is complete -
-For backwards compatibility, the onrefresh function can be specified directly -by this argument. In both cases, the image handle is passed to the function: -
-    # preferred method
-    JS9.RefreshImage(blob, {onrefresh: xrefresh});
-    # for backwards compatibility
-    JS9.RefreshImage(blob, xrefresh);
-    # both call this function
-    function xrefresh(im){ ... };
-
-

-Advanced use: it is possible to load several images into an instance -of JS9 and then refresh any of them regardless of which image is -currently displayed. To do this, you pass the display property in a -trailing object, with the id of the image to refresh. For example, if -foo1.fits and foo2.fits are loaded and foo2.fits is currently displayed: -

-    # refresh foo2.fits using foo2.fits as the new image
-    JS9.RefreshImage();
-    # refresh foo2.fits using foo3.fits as the new image
-    JS9.RefreshImage("foo3.fits");
-
-    # refresh foo1.fits (even though its not currently displayed)
-    # it will be currently displayed once this operation is complete
-    JS9.RefreshImage({display:"foo1.fits"});
-    # refresh foo1.fits using foo4.fits as the new image
-    JS9.RefreshImage("foo4.fits", {display:"foo1.fits"});
-
-    # warning: this refreshes foo2.fits using foo1.fits as the new image,
-    # rather than refreshing foo1.fits!!
-    JS9.RefreshImage("foo1.fits");
-
-

-The main difference between JS9.RefreshImage() and -JS9.Load() -is that the former updates the data in the currently displayed image, -while the latter adds a completely new image to the display. - -

Extract and display a section of a FITS file
-

-JS9.DisplaySection(opts) -

-where: -

    -
  • opts: object containing section options or "full" -
-This routine allows you to extract and display a section of FITS file. -If the first argument is the text string "full", the full image is -displayed (assuming there is sufficient memory available.) Otherwise -the opts object contains properties specifying how to generate and -display the section: -
    -
  • xcen: x center of the section in file (physical) coords -
  • ycen: y center of the section in file (physical) coords -
  • xdim: x dimension of section to extract before binning -
  • ydim: y dimension of section to extract before binning -
  • bin: floating bin factor or bin directive string -
  • binMode: "a" to average binned pixels, "s" to sum binned pixels -
  • filter: for tables, row/event filter to apply when extracting section -
  • columns: alternate columns for binning a table (def: "X Y") -
  • cubecol: table to cube conversion column (col[:min:max][:bitpix]) -
  • separate: display as a separate image (default is to refresh the current image) -
  • refresh: display as a refreshed image in a different display (default is to refresh the current image) -
  • ondisplaysection: function to perform after section is displayed -
-

-Numeric bin values are floating point numbers. A negative bin value means -1 / abs(bin), i.e. bin value of -4 means to bin at 0.25. The string-valued -bin directives are: -

    -
  • x[n]|X[n]|*[n]: multiply the current bin by n (e.g., "x2") -
  • /[n]: divide the current bin by n (e.g., "/2") -
  • in|In: multiply the current bin by 2 -
  • out|Out: divide the current bin by 2 -
  • [n]a: bin by n, averaging the binned pixels -
  • [n]s: bin by n, summing the binned pixels -
-Note that the JS9.globalOpts.binMode property specifies the -default action for whether the binned pixels are summed together (if -the global binMode is "s") or averaged (if the global binMode is -"a".) This behavior can be overridden by the binMode option or by -last two bin directives listed above. - -

-All properties are optional: if a property is not specified, -the routine will use - -the center of the file, with dimensions and binning -specified by JS9.globalOpts.table and JS9.globalOpts.image objects. - -the image's current settings. This allows you to set up the section once, -and then repeatedly change a property such as the center or filter, -without having to specify the other properties. - -

-For example, if an image has dimensions 4096 x 4096, then specifying: -

    -
  • center: 1024, 1024 -
  • dimensions: 1024, 1024 -
  • bin: 2 -
-will bin the upper left 1024 x 1024 section of the image by 2 to -produce a 512 x 512 image. Subsequent calls to change the center -values will pan the image using the same bin factor and dimension. - -

-Note that setting xcen,ycen to 0,0 will specify the file center. - -

-By default, the new section replaces the data in the currently displayed -image. You can display the section as a separate image in the current display -by supplying an opts object with the separate property -set to true. For example: -

-  JS9.DisplaySection({ ... separate: true});
-
-will display the new section separately from the original file, -allowing blinking, image blending, etc. between the two "files". - -

-You also can display the section as a separate image in a different display by -supplying a string value to the opts.separate property. The string value -takes two forms: -

    -
  • [display]: display the image in the specified JS9 display, using the same image id -
  • [display]:[id]: display the image in the specified JS9 display, using the specified image id -
-For example: -
-  # separate into a new display, same image id
-  JS9.DisplaySection({ ... separate: "myJS9"});
-  # separate into a new display, and with a new image id
-  JS9.DisplaySection({ ... separate: "myJS9:newsection.fits"});
-
-Both of these commands will display the new section "myJS9" display. -The first will retain the original image id, while the second will -use "newsection.fits" as the image id. - -Alternatively, you can display the section by refreshing the image in a -different display by supplying a string value to the opts.refresh -property. Again, the string value takes two forms: -
    -
  • [display]: refresh the image in the specified JS9 display, -using the same image id -
  • [display]:[id]: refresh the image in the specified JS9 -display, using the specified image id -
-For example: -
-  # refresh image in a new display, same image id
-  JS9.DisplaySection({ ... refresh: "myJS9"});
-  # refresh the new display, and change to a new image id
-  JS9.DisplaySection({ ... refresh: "myJS9:newsection.fits"});
-
-If no image is currently loaded in the specified display, the first call -to this routine using the refresh property will create a new -image in that display. Subsequent calls will refresh that image. - -

-Table filtering allows you to select rows from an FITS binary table -(e.g., an X-ray event list) by checking each row against an expression -involving the columns in the table. When a table is filtered, only -valid rows satisfying these expressions are used to make the image. - -

-A filter expression consists of an arithmetic or logical operation -involving one or more column values from a table. Columns can be -compared to other columns or to numeric constants. Standard JavaScript -math functions can be applied to columns. JavaScript (or C) semantics -are used when constructing expressions, with the usual precedence and -associativity rules holding sway: -

-  Operator                                Associativity
-  --------                                -------------
-  ()                                      left to right
-  !  (bitwise not) - (unary minus)        right to left
-  *  /                                    left to right
-  +  -                                    left to right
-  < <= > >=                               left to right
-  == !=                                   left to right
-  &  (bitwise and)                        left to right
-  ^  (bitwise exclusive or)               left to right
-  |  (bitwise inclusive or)               left to right
-  && (logical and)                        left to right
-  || (logical or)                         left to right
-  =                                       right to left
-
-For example, if energy and pha are columns in a table, then the -following are valid expressions: -
-  pha > 1
-  energy == pha
-  pha > 1 && energy ≤ 2
-  max(pha,energy) ≥ 2.5
-
- -

-NB: JS9 uses cfitsio by default (you can, but should not, use the -deprecated fitsy.js), and therefore follows cfitsio filtering -conventions, which are documented -here. - -

-By default, tables are binned into an image using the "X" and "Y" columns. You -can specify different binning columns using the opts.columns property: -

-  JS9.DisplaySection({ ... columns: "DX DY"});
-
- -

-Tables can be converted into 3D cubes by specifying the opts.cubecol -property. The cubecol value should be a string containing the column name and, -optionally, the min and max values and/or the bin size: -

-  # each image in the cube has an width of 100 energy units
-  JS9.DisplaySection({ ... cubecol: "energy:100"});
-  # image cube 3rd dimension is 60 ... each image having a bin width of 100
-  JS9.DisplaySection({ ... cubecol: "energy:1000:7000:100"});
-
-By default, when opts.cubecol is specified, the opts.separate -property is set to true, i.e. a separate image is displayed, leaving the -original intact. -

-Obviously, cube generation will require a considerable amount of -memory since the resulting file is maintained in -the Emscripten -heap. Because browser memory generally is limited, JS9 enforces a -memory limit on the size of the cube, specified by JS9.globalOpts.maxMemory -(and currently set to 2Gb). To avoid exceeding this limit, you usually try -adjusting the xdim, ydim, and/or bitpix values as well as the binsize of the -specified cube column: -

-  # each image utilizes approx 2Mb, so that 400 slices should fit ...
-  JS9.DisplaySection({xdim:1024, ydim:1024, bitpix:16, cubecol:"energy:1000:7000:20"});
-
- -

-Once a cube has been created, you can use the Cube plugin to blink each -image slice. You can also run external analysis on individual slices. - -

Display an extension from a multi-extension FITS file
-

-JS9.DisplayExtension(extid, opts) -

-where: -

    -
  • extid: HDU extension number or the HDU's EXTNAME string or "all" -
  • opts: object containing options -
-This routine allows you to display images and binary tables from -a multi-extension FITS file. The first argument is the 0-indexed HDU -number or the EXTNAME name value of the HDU extension to display. If "all" -is specified, then all 2D image extensions are loaded in order and displayed -as separate images. -

-The optional opts object can contain: -

    -
  • separate: boolean determining whether images are loaded separately -
-If separate is true, the new extension is displayed as a separate image. -Otherwise, the new extension replaces the current display. -

-See the FITS -Primer for more information about HDUs and multi-extension FITS. - -

Display a slice of a FITS data cube
-

-JS9.DisplaySlice(slice, opts) -

-where: -

    -
  • slice: slice description, slice number, or "all" -
  • opts: object containing options -
-This routine allows you to display a 2D slice of a 3D or 4D FITS data -cube, i.e., a FITS image containing 3 or 4 axes. - -

-The slice parameter can either be the numeric value of the -slice in the third (or fourth) image dimension (starting -with 1) or it can be a slice description string: a combination -of asterisks (or commas) and a numeric value defines the slice -axis. Thus, for example, in a 1024 x 1024 x 16 cube, you can display -the sixth slice along the third axis in one of two ways: -

-  JS9.DisplaySlice(6);
-
-or: -
-  # sixth slice along third axis
-  JS9.DisplaySlice("*:*:6");
-  # comma separators also can be used
-  JS9.DisplaySlice("*,*,6");
-
-If the image was organized as 16 x 1024 x 1024, you would use the -string description: -
-  JS9.DisplaySlice("6:*:*");
-
-

-By default, the new slice replaces the data in the currently displayed -image. You can display the slice as a separate image in the current display -by supplying an opts object with the separate property -set to true. For example: -

-  JS9.DisplaySlice("6:*:*", {separate: true});
-
-will display the sixth slice of the first image dimension separately -from the original file, allowing blinking, image blending, etc. between -the two "files". Note that the new id and filename are adjusted to be -the original file's values with the cfitsio image section [6:6:*:*] -appended. -

-If the first argument is "all", then all slices will be loaded into JS9 separately. - -

Blend the image in an image stack using W3C composite/blend modes
-

-JS9.BlendImage(blendMode, opacity) -

-Calling sequences: -

-    JS9.BlendImage()                   # return current blend params
-    JS9.BlendImage(true||false)        # turn on/off blending
-    JS9.BlendImage(mode, opacity)      # set blend mode and/or opacity
-
-

-where: -

    -
  • mode: one of the W3C bend modes -
  • opacity: the opacity of the blended image (percent from 0 to 1) -
-Image processing programs such as Adobe Photoshop and Gimp allow you to blend -a stack of images together by mixing the RGB colors. The W3C has defined a -number of composite and blending modes which have been implemented by Firefox, Chrome, and Safari (what about Edge?): -
    -
  • normal -
  • multiply -
  • screen -
  • overlay -
  • darken -
  • lighten -
  • color-dodge -
  • color-burn -
  • hard-light -
  • soft-light -
  • difference -
  • exclusion -
  • hue -
  • saturation -
  • color -
  • luminosity -
-In addition, the following Porter-Duff compositing modes are available -(though its unclear how useful they are in JS9 image processing): -
    -
  • clear -
  • copy -
  • source-over -
  • destination-over -
  • source-in -
  • destination-in -
  • source-out -
  • destination-out -
  • source-atop -
  • destination-atop -
  • xor -
  • lighter -
-Blending and compositing modes are described in detail in this W3C candidate recommendation -and in this Mozilla document. - -

-JS9 allows you to use these modes to blend images together. If you load two -images of the same object into JS9, you can use the -JS9.ReprojectData() -routine to align them by WCS. You then can blend one image into the other by -specifying a blend mode and an optional opacity. For example, if chandra.fits -and spitzer.fits are two aligned images of the same object, and chandra.fits is -currently being displayed, you can blend spitzer into chandra using -the "screen" blend and opacity 0.9 mode this way: -

-    JS9.BlendImage("screen", 0.9);
-
-After the spitzer image is blended, both images will be displayed as -part of the chandra.fits display. However, changing the colormap, -scale, contrast, or bias will only affect the current chandra image, -not the blended spitzer part. In this way, you can continue to -manipulate the current image and the image blending will update automatically. - -

-Also note that the spitzer image is still available separately for -display and manipulation. You can switch to displaying spitzer and -change colormap, scale, bias, contrast, etc. But since the images are -now blended, changes to spitzer will be reflected in the spitzer part -of the blended chandra display. Thus, if you change the colormap on -the display of spitzer, and change back to chandra, the blended -chandra image will utilize the new colormap. - -

-This linkage is maintained during zoom and pan operations. If you -display the blended chandra image and then zoom or pan it, both images -will be updated correctly to maintain alignment. But note that this -means when you go back to the spitzer display, its zoom and/or pan -values will have been updated. In this way, the spitzer image always -is correctly linked to the blended version. - -The JS9.BlendImage() call accepts a variable number of -arguments to perform a variety of functions: -

    -
  • JS9.BlendImage() returns an object containing the following properties: -
      -
    • active: boolean specifying whether this image is to be blended -
    • mode: string specifying the blend mode -
    • opacity: opacity value (0 to 1) -
    -
  • JS9.BlendImage() returns a blend object for the current image -
  • JS9.BlendImage(true||false) turns on/off blending of -
  • JS9.BlendImage(blend, opacity) set or modify the blend mode and/or opacity -
-Other actions will be added as we gain experience with blending operations - -
Set the global image blend more for the specified display
-

-mode = JS9.BlendDisplay(true|false) -

-returns: -

    -
  • mode: current blend mode -
-This routine will turn on/off the global image blend mode for the specified -display. If no argument is specified, it returns the current blend mode. -

-If the first argument is "reset", the blend mode for all images in -this display will be set to false, along with the display's blend -mode. This is useful if you have loaded/blended a number of images, and -want to load/blend another set of images. -

-If the first argument is "list", an array is returned containing the image -id's of all images that have blend mode turned on for this display. This is -useful for changing the blend modes of all active images at once. - -

Synchronize operations between two or more images
-

-JS9.SyncImages(ops, images, opts) -

-Calling sequences: -

-    JS9.SyncImages([ops], [images], [opts])  # set up synchronization
-    JS9.SyncImages(true||false)              # turn on/off synchronization
-
-

-where: -

    -
  • ops: operation or array of operations on which to sync -
  • images: image or array of images to sync with this image -
  • opts: options for sync'ing -
-Synchronize two or more images, so that when an operation is performed -on one image, it also is performed on the other(s). For example, when -the colormap or scale is changed on an image, it also is changed on -the sync'ed images. Or, when a region is created, moved, resized, or -removed on an image, the same happens on the sync'ed images. - -

-When the JS9.SyncImages() call is invoked, the current image is -configured to synchronize the specified images. In addition, if -the reciprocate property is set in the opts object (see below), -the other images are also configured to synchronize one another (as -well as the current image.) Once configuration is complete, a sync -command is executed immediately. If the current image already -displays one or more regions, these will be created in the target images. - -

-The operations that can be specified for sync'ing are: "alignment", -"colormap", "contrastbias" (i.e., both "contrast" and "bias"), "flip", -"pan", "regions", "rot90", "rotate", "scale", "wcs" (i.e., both -"wcssys" and "wcsunits"), and "zoom". If no array is specified, the -default array in JS9.globalOpts.syncOps is used. - -

-Regions calls the -JS9.CopyRegions() routine. -Alignment calls -JS9.AlignPanZoom() in order to -keep the pixel size and displayed center position constant between the -sync'ed images. It assumes no rotation between the two images. - -

-Images to synchronize can be specified singly or as an array of image -handles or image ids. If no array is specified, all currently -displayed images are sync'ed. - -

-The optional opts object can contain: -

    -
  • reverse: boolean to reverse this image and target images (def: false) -
  • reciprocate: boolean determining whether images sync one another -
  • syncwcs: use WCS header params to sync (e.g., pan), where available - -
-If the opts object is not specified, the default values of -reciprocate and syncwcs are the values of the -JS9.globalOpts.syncReciprocate and JS9.globalOpts.syncWCS, -respectively. - -

-Examples: -

-    # the current image will sync all operations for all images
-    # this will happen reciprocally, so that changing any image syncs the others
-    JS9.SyncImages()
-
-    # the current image will sync the specified ops for foo1.fits, foo2.fits:
-    JS9.SyncImages(["scale", "colormap"], ["foo1.fits", "foo2.fits"])
-
-    # the current image will sync two images with default ops,
-    # but the two images themselves will not sync images reciprocally
-    JS9.SyncImages(null, ["foo1.fits", "foo2.fits"], {reciprocate: false});
-
- -

-Note that if the pan operation syncs two images having differently -sized fields of view, the smaller image will stop panning when it -reaches its edge, rather than displaying a blank field. - -

-You can turn on/off syncing for a given image by specifying a single boolean -argument: -

-    # turn off sync'ing temporarily
-    JS9.SyncImages(false);
-
-This is different from unsync'ing in that you can turn sync'ing back on without -having to re-sync the images. - -
Unsynchronize two or more previously synchronized images
-

-JS9.UnsyncImages(ops, images, opts) -

-Calling sequence: -

-    JS9.UnsyncImages([ops], [images], [opts])  # clear synchronization
-
-

-where: -

    -
  • ops: array of operations to unsync -
  • images: array of images to unsync with this image -
  • opts: options for unsync'ing -
-Unsynchronize previously sync'ed images. - -

-The operations that can be specified for unsync'ing are: -"alignment", "colormap", "contrastbias" (i.e., both "contrast" and "bias"), -"flip", "pan", "regions", "rot90", "rotate", "scale", "wcs" (i.e., both "wcssys" and -"wcsunits"), and "zoom". -If no array is specified, the default array in JS9.globalOpts.syncOps is -used. Thus, you can turn off sync'ing for specified operations, while leaving -others to be sync'ed. - -

-Images to be unsync'ed can be specified as an array of image handles or -image ids. If no array is specified, all currently displayed images -are unsync'ed. - -

-The optional opts object can contain: -

    -
  • reciprocate: boolean determining whether images sync one another -
  • reverse: boolean to reverse this image and target images (def: false) -
-If the opts object is not specified, the default is to reciprocate based -on the value of the JS9.globalOpts.syncReciprocate property. - -

-Examples: -

-    # this image will no longer sync on scale for foo1.fits and foo2.fits,
-    # and they also will stop sync'ing
-    JS9.UnsyncImages(["scale"], ["foo1.fits", "foo2.fits"])
-
-    # this image will still sync foo1.fits and foo2.fits, but
-    # foo1.fits and foo2.fits will no longer sync this image:
-    JS9.UnsyncImages(null, ["foo1.fits", "foo2.fits"], {reverse: true, reciprocal: false})
-
- -
Mask an image using values in another image
-

-JS9.MaskImage(image, opts) -

-Calling sequences: -

-    JS9.MaskImage()                   # return current mask params
-    JS9.MaskImage(true||false)        # turn on/off masking
-    JS9.MaskImage(image, opts)        # set mask and optionally, its params
-    JS9.MaskImage(opts)               # set mask params
-
-

-where: -

    -
  • image: image handle or image id to use as a mask -
  • opts: optional mask properties -
-and where the mask properties are: -
    -
  • mode: "mask", "opacity", or "overlay" -
  • value: mask value that triggers masking (def: 0) for "mask" mode -
  • invert: whether to invert the mask (def: false) for "mask" mode -
  • sync: true or false for "overlay" mode -
  • opacity: opacity to use when masking (def: 0, range 0 to 1) -for "mask" and "overlay" mode -
-

-The pixel values in one image can be used to mask the pixels in -another image if the two images have the same image dimensions. -The type of masking depends on the mode: "overlay" (default) or "mask". -

-For "mask" mode, if the value of a pixel in the mask is less than or -equal to the value property, the opacity of the displayed pixel -is set to the opacity property. You can also invert the mask -using the invert property. In effect, this mode displays only -the image pixels "covered" by a mask. -

-For "opacity" mode, each image pixel is assigned an opacity equal to the -value of the mask pixel (whose values are assumed to range from 0 to 1.) -

-For "overlay" mode, if the mask pixel has a non-zero alpha, its color -is blended with the image pixel using source-atop -composition. Otherwise, the image pixel color alone is used in the -display. This is one way you can display a mask overlay on top of an -image. A static colormap is usually used in conjunction with an -overlay mask, since pixel values not explicitly assigned a color are -transparent. Note that, when blending a mask and image pixel, the -global mask opacity and the individual pixel opacity are multiplied to -get the final pixel opacity. If "sync" is not explicitly false, this -mode will call JS9.SyncImages() -to keep the mask and image file in sync. The maskOpts property sync -contains the array of operations to sync. -

-To set up a mask initially, call the routine with an already-loaded -mask image as the first parameter, and an optional opts object as the -second parameter: -

-    # default is "overlay"
-    JS9.ImageMask("casa_mask.fits");
-    JS9.ImageMask("casa_mask.fits", {mode: "overlay"});
-
-    # "mask" mode: set lower threshold for masking and masked opacity
-    JS9.ImageMask("casa_mask.fits", {mode: "mask", value: 5, opacity: 0.2});
-
-You can change the mask parameters at any time: -
-    JS9.ImageMask({value: 2, opacity: 0});
-
-or temporarily turn off and on the mask: -
-    JS9.ImageMask(false);
-    ...
-    JS9.ImageMask(true);
-
- -
Clear the image from the display and mark resources for release
-

-JS9.CloseImage(opts) -

-where: -

    -
  • opts: optional object or JSON string containing image parameters -
-

-

-Each loaded image claims a non-trivial amount of memory from a finite -amount of browser heap space. For example, the default 32-bit version -of Google Chrome has a memory limit of approximately 500Mb. If you are -finished viewing an image, closing it tells the browser that the -image's memory can be freed. In principle, this is can help reduce -overall memory usage as successive images are loaded and -discarded. Note, however, that closing an image only provides a hint -to the browser, since this sort of garbage collection is not directly -accessible to JavaScript programming and happens when it happens. -

-The optional first argument is an opts object (or a JSON-formatted -string) containing: -

    -
  • clear: if explicitly set to false, the image will not be cleared -
-The clear option is useful if you are repeatedly loading the same image -and want to avoid the image blink associated with the clear. - -
Get the image colormap
-

-cmap = JS9.GetColormap() -

-returns: -

    -
  • cmap: object containing colormap information -
-The returned cmap object will contain the following properties: -
    -
  • colormap: colormap name -
  • contrast: contrast value (range: 0 to 10) -
  • bias: bias value (range 0 to 1) -
- -
Set the image colormap
-

-JS9.SetColormap(colormap, [contrast, bias]) -Calling sequences: -

-    JS9.SetColormap(colormap)
-    JS9.SetColormap(colormap, contrast, bias)
-    JS9.SetColormap(colormap, staticOpts)
-    JS9.SetColormap(contrast, bias)
-    JS9.SetColormap(staticOpts)
-
-

-where: -

    -
  • colormap: colormap name -
  • contrast: contrast value (range: 0 to 10) -
  • bias: bias value (range 0 to 1) -
  • staticOpts: static colormap opts -
-Set the current colormap, contrast/bias, or both. This call takes one -(colormap), two (contrast, bias) or three (colormap, contrast, bias) -arguments. It also takes the following single arguments: -
    -
  • rgb: toggle RGB mode -
  • invert: toggle inversion of the colormap -
  • overlay: toggle image overlay mode (PNG and JPEG files only) -
  • reset: reset contrast, bias, and invert values -
  • staticOpts: opts for a static colormap -
-The staticOpts argument is an array of parameters to change in a static -colormap. Each parameter can take one of two forms: -
    -
  • [color, min, max] -
  • [color, opacity|alpha] -
  • [color, true|false] -
-The color parameter must match one of the colors specified when the -static colormap was created. The min and max properties replace -the originally specified min and max values. Specifying a number between 0 -and 1 (inclusive) will change the opacity, while specifying a number greater -than 1 will change the alpha (i.e., opacity * 255.) Specifying true or -false will set or unset the active flag for that color, i.e. -it will turn on or off use of that color. When turned off, the pixels in that -range will be transparent. For example: -
-  SetColormap([["red", 0.5], ["green", true], ["blue", false]]);
-
-sets the opacity of red pixels to 0.5, turns on the green pixels, and turns -off the blue pixels in the currently active static colormap. -

-Finally, note that PNG and JPEG images have a "private" colormap -associated with them, which is an approximation of the original colors -used in these images. You can set this colormap by specifying -"private": -

-  SetColormap("private");
-
-This private colormap is static: you cannot change contrast and -bias. It also cannot be modified using staticOpts because there is -no color string value associated with each entry in the colormap. - -
Save colormap(s)
-

-JS9.SaveColormap(fname, cmapArray) -

-Calling sequences: -

-    JS9.SaveColormap()                 # save current colormap to "js9.cmap"
-    JS9.SaveColormap(fname)            # save current colormap to fname
-    JS9.SaveColormap(cmapArray)        # save array of colormaps to "js9.cmap"
-    JS9.SaveColormap(fname, cmapArray) # save array of colormaps to fname
-
-

-where: -

    -
  • fname: output file name -
  • cmapArray: optional array of colormap names to save -
-As shown by the calling sequences above, you can use this routine to -save either the current colormap or a list of colormaps taken from the -specified array. You also can choose to save to a particular filename -or the default "js9.cmap": -
-  # save the current colormap in js9.cmap
-  JS9.SaveColormap()
-  # save the current colormap in foo.cmap
-  JS9.SaveColormap("foo.cmap")
-  # save the foo1 and foo2 colormaps in js9.cmap
-  JS9.SaveColormap(["foo1", "foo2"])
-  # save the user-defined foo1 and foo2 colormaps in foo.cmap
-  JS9.SaveColormap("foo.cmap", ["foo1", "foo2"])
-
-

-The colormaps are saved in JSON format. Multiple saved colormaps will -be stored in a JSON array, while a single saved colormap will be saved -at the top level. -

-Don't forget that the file is saved by the browser, in whatever location -you have set up for downloads. -

- -
Add a colormap to JS9
-

-JS9.AddColormap(name, aa|rr,gg,bb|ss|obj|json, opts) -

-where: -

    -
  • name: colormap name -
  • aa: an array containing RGB color triplets -
  • rr,gg,bb: 3 arrays of vertices specifying color changes -
  • ss: an array static color assignments -
  • obj: object containing one of the three colormap definition formats -
  • json: JSON string containing one of the colormap definition formats -
  • opts: optional object to set toplevel property to false -
-You can add new colormaps to JS9 using one of three formats. The first -is an array of RGB triplets (i.e., an array of 3-D arrays), where each -triplet defines a color. The elements of the colormap are divided -evenly between these 3-D triplets. For example, the i8 -colormap is defined as: -
-    JS9.AddColormap("i8", [[0,0,0], [0,1,0], [0,0,1], [0,1,1], [1,0,0], [1,1,0], [1,0,1], [1,1,1]]));
-
-Here, the colormap is divided into 8 sections having the following -colors: black, green, blue, cyan (green + blue), red, yellow (red + -green), purple (red + blue), and white. A colormap such as sls -also utilizes an array of RGB triplets, but it has 200 entries, -leading to much more gradual transitions between colors. -

-The second colormap format consists three arrays of vertices defining -the change in intensity of red, green, and blue, respectively. For -each of these three color triplets, the first coordinate of each -vertex is the x-distance along the colormap axis (scaled from 0 to 1) -and the second coordinate is the y-intensity of the color. Colors are -interpolated between the vertices. For example, consider the following: -

-    JS9.AddColormap("red", [[0,0],[1,1]], [[0,0], [0,0]], [[0,0],[0,0]]);
-    JS9.AddColormap("blue", [[0,0],[0,0]], [[0,0], [0,0]], [[0,0],[1,1]]);
-    JS9.AddColormap("purple", [[0,0],[1,1]], [[0,0], [0,0]], [[0,0],[1,1]]);
-
-In the red (blue) colormap, the red (blue) array contains two -vertices, whose color ranges from no intensity (0) to full intensity -(1) over the whole range of the colormap (0 to 1.) The same holds true -for the purple colormap, except that both red and blue change from zero -to full intensity. -

-The third colormap format consists of an array of color and pixel range -specifications: color, min, max. This defines a static colormap in which -colors are assigned based on whether an image pixel is within a range. -For example: -

-  JS9.AddColormap("mask",
-                  [["#ff000080", 1, 31],
-		   ["cyan", 32, 32],
-		   ["rgba(0,255,0,0.5)", 37, 99],
-		   ["blue", 100, Infinity]]);
-
-Image pixel values between 1 and 31 (inclusive) are assigned a -red color (#ff0000) with an opacity of approximately 0.5. The image -pixel value 32 is assigned the color cyan. Image pixel values between -37 and 99 are assigned the color green with opacity 0.5. All image -pixel values greater than or equal to 100 are blue. (You can also specify -the string "Infinity".) If an image pixel value is not within any -range, it is assigned the color specified -by JS9.imageOpts.nocolor. By default, this is black with an -opacity of 0, so nothing is displayed at all (you'll probably see the -default grey background of the JS9 display element.) Static colormaps -are mostly used as image masks. See -JS9.MaskImage() for more information. - -

-Note the different ways in which colors can be specified: more information -about accepted color formats is available on the -TinyColor -website. - - -

-For a more complicated example, consider the a colormap, which is -defined as: -

-    JS9.AddColormap("a",
-      [[0,0], [0.25,0], [0.5,1], [1,1]],
-      [[0,0], [0.25,1], [0.5,0], [0.77,0], [1,1]],
-      [[0,0], [0.125,0], [0.5, 1], [0.64,0.5], [0.77, 0], [1,0]]);
-
-Here we see that red is absent for the first quarter of the colormap, -then gradually increases to full intensity by the half mark, after -which it stays at full intensity to the end. Green ramps up to full -intensity in the first quarter, then drops to zero by the half and -stays that way until a bit more than three-quarters along, after which -it gradually increases again. Blue starts off at no intensity for an -eighth, then gradually increases to full intensity by the half-way -mark, decreasing gradually to zero by the three-quarter mark. The -result is that you see, for example, green at the beginning and yellow -(red + green) at the end, with some purple (red + blue) in the middle -of the colormap. -

-As a convenience, you also can pass an object or JSON string containing the -colormap definition: -

-    # RGB color triplets for the I8 colormap in a "colors" property
-    {"name":"i8","colors":[[0,0,0],[0,1,0],[0,0,1],[0,1,1],[1,0,0],[1,1,0],[1,0,1],[1,1,1]]}
-
-    # all 3 vertex arrays for the purple colormap in one "vertices" property
-    {"name":"purple","vertices":[[[0,0],[1,1]],[[0,0],[0,0]],[[0,0],[1,1]]]}
-
-

-The colormap will be added to the toplevel of the Colormap -menu, unless you pass a final opts argument that sets -the toplevel property to false: -

-  JS9.AddColormap("cyan", [[0,0],[0,0]], [[0,0],[1,1]], [[0,0],[1,1]], {toplevel:false});
-
-Finally, note that JS9.AddColormap() adds its new colormap to -all JS9 displays on the given page. - -
Load a colormap file into JS9
-

-JS9.LoadColormap(filename, opts) -

-where: -

    -
  • filename: input file name or URL -
  • opts: optional object to set toplevel property to false -
-Load the specified colormap file into the web page. The filename, -which must be specified, can be a local file (with absolute path or a -path relative to the displayed web page) or a URL. It should contain a -JSON representation of a colormap (or an array of colormaps), either -in RGB color format or in vertex format (see -JS9.AddColormap() -above): -
-    # RGB color format
-    {
-      "name": "purplish",
-      "colors": [
-	[0.196, 0.196, 0.196],
-	[0.475, 0, 0.608],
-	[0, 0, 0.785],
-	[0.373, 0.655, 0.925],
-	[0, 0.596, 0],
-	[0, 0.965, 0],
-	[1, 1, 0],
-	[1, 0.694, 0],
-	[1, 0, 0]
-      ]
-    }
-
-    # vertex format
-    {
-      "name": "aips0",
-      "vertices": [
-	[
-	    [0.203, 0],
-	    [0.236, 0.245],
-	    [0.282, 0.5],
-	    [0.342, 0.706],
-	    [0.411, 0.882],
-	    [0.497, 1]
-	],
-	[
-	    [0.394, 0],
-	    [0.411, 0.196],
-	    [0.464, 0.48],
-	    [0.526, 0.696],
-	    [0.593, 0.882],
-	    [0.673, 1],
-	    [0.94, 1],
-	    [0.94, 0]
-	],
-	[
-	    [0.091, 0],
-	    [0.091, 0.373],
-	    [0.262, 1],
-	    [0.94, 1],
-	    [0.94, 0]
-	]
-      ]
-    }
-
- -

-The colormap will be added to the toplevel of the Colormap -menu, unless you pass a final opts argument that sets -the toplevel property to false: -

-  JS9.LoadColormap("secondary.cmap", {toplevel:false});
-
-As with -JS9.AddColormap(), -the new colormap will be available in all displays. - -
Get RGB Mode for this display
-

-JS9.GetRGBMode() -

-returns: -

    -
  • obj: object containing RGB mode information -
-The returned object will contain the following properties: -
    -
  • active: boolean specifying whether RGB mode is active -
  • rid: image id of "red" image -
  • gid: image id of "green" image -
  • bid: image id of "blue" image -
- -
Set RGB Mode for this display
-

-JS9.SetRGBMode(mode, [imobj]) -

-where: -

    -
  • mode: boolean true to activate RGB mode, false to disable -
  • imobj: optional object specifying three images to set to the -"red", "green", and "blue" colormaps -
-In RGB mode, three images assigned the "red", "green", and "blue" -colormaps are displayed as a single image. The RGB color of each -displayed pixel is a combination of the "red", "green", and "blue" -pixel value taken from the appropriate image. Note that all three -images are not required: you can display an RGB image using two of -the three colors simply by not assigning the third colormap. - -

-The JS9.SetRGBMode() call turns on or off RGB mode. The -boolean mode argument specifies whether to activate or -de-activate RGB mode. The optional imobj object specifies -(already-loaded) images to assign to the three colormaps: -

    -
  • rid: image id (or handle) to set to the "red" colormap -
  • gid: image id (or handle) to set to the "green" colormap -
  • bid: image id (or handle) to set to the "blue" colormap -
-If imobj is not specified, it is assumed that images have been -assigned the "red", "green", and "blue" colormaps by another means. -(Once again, it is not necessary to assign all three colormaps.) -

-If no arguments are specified, the current RGB mode is toggled; - -

Get the image scale
-

-scale = JS9.GetScale() -

-returns: -

    -
  • scale: object containing scale information -
-The returned scale object will contain the following properties: -
    -
  • scale: scale name -
  • scalemin: min value for scaling -
  • scalemax: max value for scaling -
- -
Get the image opacity
-

-opacity = JS9.GetOpacity() -

-returns: -

    -
  • opacity: object containing opacity information -
-The returned opacity object will contain the following properties: -
    -
  • opacity: opacity value assigned to image pixels -
  • flooropacity: opacity assigned when the image pixel value is less than or equal to the floor value (if defined) -
  • floorvalue: floor value to test image pixel values against (if defined) -
- -
Set the image opacity
-

-JS9.SetOpacity(opacity, floorvalue, flooropacity) -

-calling sequences: -

-    JS9.SetOpacity(opacity)      # set def opacity for all image pixels
-    JS9.SetOpacity(floorvalue, flooropacity) # pixels <= floorvalue get flooropacity
-    JS9.SetOpacity(opacity, floorvalue, flooropacity)  # set def and floor opacity
-    JS9.SetOpacity("reset")      # reset def opacity to 1
-    JS9.SetOpacity("resetfloor") # remove opacity floor
-    JS9.SetOpacity("resetall")   # reset def opacity to 1, remove floor opacity
-
-

-where: -

    -
  • opacity: opacity value for image pixels -
  • floorvalue: floor value to test image pixel values against -
  • flooropacity: floor opacity value to set if image pixel value is less than or equal to the floor opacity value -
-Set the current opacity, floor opacity, or both. This call takes one -(opacity), two (floorvalue, flooropacity) or three (opacity, floorvalue, flooropacity) arguments. -

-The floor value & opacity option allows you to set the opacity -for pixels whose image value is less then or equal to a specified -floor value. It takes two arguments: the floor pixel value to check, -and the floor opacity to apply. For example, when both arguments are 0, -pixels whose image values are less than or equal to 0 -will be transparent. Specifying 5 and 0.5, respectively, means that -pixels whose image values less than or equal to 5 will have an opacity -of 0.5. A useful case is to make the pixels transparent at a -given value, allowing features of one image to be blended into -another, without blending extraneous pixels. -

-The various reset options allow you to reset the default value, -floor values, or both. - -

Set the image scale
-

-JS9.SetScale(scale, smin, smax) -

-where: -

    -
  • scale: scale name, "zscale", "zmax", or "dataminmax" -
  • smin: scale min value -
  • smax: scale max value -
-Set the current scale, min/max, or both. This call takes one -(scale), two (smin, max) or three (scale, smin, smax) arguments. (If "zscale" -or "zmax" is specified, any supplied smin and smax values are ignored.) - -
Get the image zoom factor
-

-zoom = JS9.GetZoom() -

-returns: -

    -
  • zoom: floating point zoom factor -
-Get the zoom factor. - -
Set the image zoom factor
-

-JS9.SetZoom(zoom) -

-where: -

    -
  • zoom: floating or integer zoom factor or zoom directive string -
-The zoom directives are: -
    -
  • x[n]|X[n]|*[n]: multiply the current zoom by n (e.g., "x2") -
  • /[n]: divide the current zoom by n (e.g., "/2") -
  • in|In: multiply the current zoom by 2 -
  • out|Out: divide the current zoom by 2 -
  • toFit|ToFit: zoom to fit image in display -
- -
Get the image pan position
-

-ipos = JS9.GetPan() -

-returns: -

    -
  • ipos: object containing image information for pan -
-The returned ipos object will contain the following properties: -
    -
  • x: calculated (from section) x image coordinate of center -
  • y: calculated (from section) y image coordinate of center -
  • ox: original (input) x image coordinate of center -
  • oy: original (input) y image coordinate of center -
  • x0: x start of image section -
  • y0: y start of image section -
  • x1: x end of image section -
  • y1: y end of image section -
  • ix: x offset of center from center of display -
  • iy: y offset of center from center of display -
-Note that the x and y values are the center of the image section, which might -be different from the input x and y values passed -JS9.SetPan(). The latter are returned as ox -and oy. The image section parameters are also returned. Finally, the -ix and iy values will be non-zero in cases of unconstrained, -off-centered panning. - -
Set the image pan position
-

-JS9.SetPan(x, y) -

-where: -

    -
  • x: x image coordinate (or an object containing a position) -
  • y: y image coordinate -
-

-Set the current pan position using image coordinates. Note that you can use -JS9.WCSToPix() -and -JS9.PixToWCS() -to convert between image and WCS coordinates. -

-An object can also be supplied with a position specified in image, -physical, or WCS coordinates: -
    -
  • x: image x position -
  • y: image y position -
  • px: physical x position -
  • py: physical y position -
  • ra: RA in degrees -
  • dec: Dec in degrees -
  • wcs: sexagesimal WCS string with optional WCS system -
-For example: -
-    JS9.SetPan({wcs: "23:23:28.895 +58:49:43.50 ICRS"});
-
-will set the pan position to the specified RA and Dec using the ICRS -system. Note that the WCS string above is returned by the Edit -menu's "copy wcs pos" option (i.e., the "/" keystroke.) - -

-Finally, if you pass the string "mouse" as the sole argument, the -image is panned to the current mouse position. This is especially useful -in conjunction with keyboard shortcuts (where currently the "m" key uses this -routine to pan to the current mouse position.) - -

-By default, panning is unconstrained: you can pan the image so that -some (or even all) of the display does not contain image data (e.g., -if you pan an image to point 0,0, the image origin will be the -center of the display and only the upper right quadrant will contain -data.) If you want to avoid blank areas in the display, set the -JS9.globalOpts.panWithinDisplay property to true. Site authors -can change this property in js9prefs.js, while users can change -this via the Global tab of the Preferences plugin. - -

Align pan and zoom of the current image to a target image
-

-JS9.AlignPanZoom(im, opts) -

-where: -

    -
  • im: target image containing the WCS used to perform the alignment -
  • opts: optional object -
-

-This routine changes the pan and zoom of the current image to match a -target image. By default, it is assumed that both have WCS info -available. The image is panned to the RA, Dec at the center of the -target image's display. The zoom is also matched. The pixel size (as -specified by the FITS CDELT1 parameter) will be taken into account -when zooming, but not the image rotation or flip. This routine is -faster than -JS9.ReprojectData() -for aligning reasonably similar images. - -

-For specialized needs, you can set the syncwcs property to false in -the opts object so that WCS will not be used in the alignment. Instead, -the image will be panned to the target's current center (in image coordinates) -and the image zoom will be set to the target's zoom. Obviously, this assumes -identical image dimensions and pixel sizes. It can be useful when working with -lab data and simulations. - -

-No attempt is make to keep the images aligned after the call. This -allows you to make adjustments to the current and/or target images and -then re-align as needed. - -

Flip an image around the x or y axis
-

-JS9.SetFlip(flip) -

-where: -

    -
  • flip: "x", "y" -
-Flip an image around the specified axis. Flipping is relative to the -current state of the display, so flipping by x twice will return you -to the original orientation. -

-Since this operation is applied to the entire display canvas instead -of the image, image parameters such as the WCS are not affected. - -

Get flip state of an image
-

-flip = JS9.GetFlip() -

-returns: -

    -
  • flip: the current flip state -
-Possible returned flip states are: "x", "y", "xy", or "none". -The state is normalized, so that, for example, two "x" flips are -replaced by "none". - -
Rotate an image by a specified number of degrees
-

-JS9.SetRotate(rot) -

-where: -

    -
  • rot: rotation in degrees -
-Set the rotation of an image to the specified number of degrees. The -rotation is performed in terms of an absolute angle: if you rotate by -20 degrees and then do it again, there is no change. Also, setting the -rotation to 0 sets the angle to 0. -

-In the rotation argument is the string "north" or "northisup", the -rotation angle is calculated so that north is up in the current -coordinate system. -

-Since this operation is applied to the entire display canvas instead -of the image, image parameters such as the WCS are not affected. - -

Get rotate state of an image
-

-rot = JS9.GetRotate() -

-returns: -

    -
  • rot: current rotation value for this image -
-Return the current rotation. - -
Rotate an image by +/- 90 degrees
-

-JS9.SetRot90(rot90) -

-where: -

    -
  • rot90: a multiple of 90 degrees (+/-90) -
-Rotate an image by a multiple of 90 degrees. Rot90 rotations are -relative to the current state of the display, so four rotations will -return you to the original orientation. -

-Since this operation is applied to the entire display canvas instead -of the image, image parameters such as the WCS are not affected. - -

Get rotate state of an image
-

-rot = JS9.GetRot90() -

-returns: -

    -
  • rot: current rotation value for this image -
-The returned rotation value will be a multiple of 90, depending on how -many rotations have been executed and in which direction. - -
Get an image parameter value
-

-val = JS9.GetParam(param) -

-where: -

    -
  • param: name of the parameter or "all" -
-

-returns: -

    -
  • val: value of the parameter -
- -

-Return the value of an image parameter. The available parameters are listed -below in the -JS9.SetParam() -section. -

-In the value of param is "all", the entire param object is returned. - -
Set an image parameter value
-

-ovalue = JS9.SetParam(param, value) -

-where: -

    -
  • param: name of the parameter or "all" -
  • val: new value of the parameter or param object to merge -
-

-returns: -

    -
  • ovalue: the previous value of the parameter or the new param object -
-A number of miscellaneous image parameters are copied from the -JS9.imageOpts object to each image when it is first loaded. You can -use the JS9.SetParam() routine to modify these values -subsequently. The available parameters and their current default -values are listed below: -
    -
  • exp: 1000, default exp value for scaling -
  • disable: which core services to disable for this image -
  • listonchange: false, list regions after a region change? -
  • opacity: 1.0, image display opacity, between 0 and 1 -
  • overlay: whether PNG/JPEG display the image instead of using cmaps -
  • nancolor: "#000000", 6-digit #hex color for NaN values -
  • valpos: true, display value/position? -
  • wcsalign: true, align image using WCS after reproj? -
  • xeqonchange: true, xeq an onchange callback after a region change? -
  • zscalecontrast: 0.25, default zscale value from ds9 -
  • zscalesamples: 600, default zscale value from ds9 -
  • zscaleline: 120, default zscale value from ds9 -
-

-In addition, you can set the internal values associated with core functionality -("colormap", "pan", "regions", "scale", "wcs", or "zoom") and the -corresponding core function will be called. The core parameters that can be -set in this way are: -

    -
  • colormap: calls JS9.SetColormap() -
  • contrast: calls JS9.SetColormap() -
  • bias: calls JS9.SetColormap() -
  • flip: calls JS9.SetFlip() -
  • rot90: calls JS9.SetRot90() -
  • rot: calls JS9.SetRotate() -
  • scale: calls JS9.SetScale() -
  • scalemin: calls JS9.SetScale() -
  • scalemax: calls JS9.SetScale() -
  • scaleclipping: calls JS9.SetScale() -
  • wcssys: calls JS9.SetWCSSys() -
  • wcsunits: calls JS9.SetWCSUnits() -
  • zoom: calls JS9.SetZoom() -
-

-The routine returns the previous value of the parameter, which can -be useful when temporarily turning off a function. For example: -

-    oval = JS9.SetParam("xeqonchange", false);
-    .... processing ...
-    JS9.SetParam("xeqonchange", oval);
-
-will temporarily disable execution of the previously defined regions -onload callback, resetting it to the old value after processing -is complete. -

-If param is "all" and the second argument is an object, this object is -merged into the current param object. This allows you to save the params from -one image and restore them to another. If the object contains internal -core parameters (see above), the corresponding core function will be called. -

-If param is "disable", the specified value (or array of values) is -added to the disable array for this image, thereby disabling -core functionality. The resulting disable array is -returned. Thus, for example: -

-    JS9.SetParam("disable", ["zoom", "pan"]);
-
-will disable zoom and pan functionality for this image. Note that -disabling regions means that you cannot create new regions, -but you can still change and even remove existing regions. -

-If param is "enable", the specified value (or array of values) is -removed to the disable array for this image, thereby enabling core -functionality. The resulting disable array is returned. - -

Copy image parameter(s) to one or more images
-

-JS9.CopyParams(param, image, opts) -

-where: -

    -
  • param: name of the parameter or array or parameters to copy -
  • image: target image or array of image to copy to -
  • opts: optional object -
-

-Copy parameters from the current image to one or more images. Any -image parameter can be copied, but the most common ones are: -"alignment", "colormap", "contrastbias" (i.e., both "contrast" and -"bias"), "flip", "pan", "rot90", "rotate", "scale", "wcs" (i.e., both -"wcssys" and "wcsunits"), and "zoom". Note that copying a parameter -results in -JS9.SetParam() being called, -triggering the corresponding core function if necessary. Thus, for -example, copying the colormap will change the colormap of the target -image. See JS9.SetParam() for more -details about setting parameters. - -

-Regions calls the -JS9.CopyRegions() routine. -Alignment calls -JS9.AlignPanZoom() in order to -keep the pixel size and displayed center position constant between the -sync'ed images. It assumes no rotation between the two images. -Finally, you can also copy "shapes", which calls the -JS9.CopyShapes() routine. -In the latter case, you will need to pass the shape layer name in the -layer property of the opts argument. - -

-The target image(s) to copy to can be specified singly or as an array -of image handles or image ids. If no images are specified, all images -are used as targets. - -

Get the display coordinates from an event
-

-dpos = JS9.EventToDisplayPos(evt) -

-where: -

    -
  • evt: a JavaScript or jQuery event -
-returns: -
    -
  • dpos: display position object containing 0-indexed x and y display -coordinate values -
-If you define your own event callbacks, you can use this routine to convert -the event position to a display position, which can then be used to get the -image position (see below.) - -
Get the image coordinates from the display coordinates
-

-ipos = JS9.DisplayToImagePos(dpos) -

-where: -

    -
  • dpos: display position object containing 0-indexed x and y display -coordinate values -
-returns: -
    -
  • ipos: image position object containing 1-indexed x and y image -coordinate values -
-Note that image coordinates are one-indexed, as per FITS conventions, while -display coordinate are 0-indexed. - -
Get the display coordinates from the image coordinates
-

-dpos = JS9.ImageToDisplayPos(ipos) -

-where: -

    -
  • ipos: image position object containing 1-indexed x and y image -coordinate values -
-returns: -
    -
  • dpos: display position object containing 0-indexed x and y display -coordinate values -
-Get display (screen) coordinates from image coordinates. Note that -image coordinates are one-indexed, as per FITS conventions, while -display coordinate are 0-indexed. - -
Get the image coordinates from the logical coordinates
-

-ipos = JS9.LogicalToImagePos(lpos, lcs) -

-where: -

    -
  • lpos: logical position object containing 1-indexed x and y logical -coordinate values -
-returns: -
    -
  • ipos: image position object containing 1-indexed x and y image -coordinate values -
-Logical coordinate systems include: "physical" (defined by LTM/LTV keywords in a -FITS header), "detector" (DTM/DTV keywords), and "amplifier" (ATM/ATV keywords.) -Physical coordinates are the most common. In the world of X-ray astronomy, they -refer to the "zoom 1" coordinates of the data file. - -

-This routine will convert from logical to image coordinates. By default, the -current logical coordinate system is used. You can specify a different logical -coordinate system (assuming the appropriate keywords have been defined.) - -

Get the logical coordinates from the image coordinates
-

-lpos = JS9.ImageToLogicalPos(ipos, lcs) -

-where: -

    -
  • ipos: image position object containing 1-indexed x and y image -coordinate values -
-returns: -
    -
  • lpos: logical position object containing 1-indexed x and y logical -coordinate values -
-Logical coordinate systems include: "physical" (defined by LTM/LTV keywords in a -FITS header), "detector" (DTM/DTV keywords), and "amplifier" (ATM/ATV keywords.) -Physical coordinates are the most common. In the world of X-ray astronomy, they -refer to the "zoom 1" coordinates of the data file. -

-This routine will convert from image to logical coordinates. By default, the -current logical coordinate system is used. You can specify a different logical -coordinate system (assuming the appropriate keywords have been defined.) - -

Get value/position information
-

-valpos = JS9.GetValPos(ipos, display) -

-where: -

    -
  • ipos: image position object containing 1-indexed x and y image coord values -
  • display: boolean value specifying whether the info box display should be updated (default is true) -
-returns: -
    -
  • valpos: value/position object -
-This routine determines the data value at a given image position -and returns an object containing the following information: -
    -
  • ix: image x coordinate -
  • iy: image y coordinate -
  • isys: image system (i.e., "image") -
  • px: physical x coordinate -
  • py: physical y coordinate -
  • psys: currently selected pixel-based system (i.e., "image" -or "physical") for the above px, py values -
  • ra: ra in degrees (if WCS is available) -
  • dec: dec in degrees (if WCS is available) -
  • wcssys: wcs system (if WCS is available) -
  • val: floating point pixel value -
  • val3: pixel value as a string truncated to 3 decimal digits -
  • vstr: string containing value and position info -
  • id: id of the image -
  • file: filename of the image -
  • object: object name of the image from the FITS header -
- -
Set the value/position display mode
-

-JS9.SetValPos(mode) -

-where: -

    -
  • mode: true (show valpos display) or false (hide valpos display) -
-Set the display mode of the value/position display for the specified image. - -
Get the image inherit mode
-

-inherit = JS9.GetImageInherit() -

-returns: -

    -
  • inherit: true if new image inherits params from current image -
-The JS9.GetImageInherit() routine returns a boolean specifying whether -a new image grabs the image params (e.g., colormap, scale, zoom, etc.) -from the currently displayed image. If false, these params are taken -from the default JS9.imageOpts object. - -
Set the image inherit mode
-

-JS9.SetImageInherit(mode) -

-where: -

    -
  • mode: true (inherit params from currently displayed image) or false -
-The JS9.SetImageInherit() routine specifies whether -a new image grabs the image params (e.g., colormap, scale, zoom, etc.) -from the currently displayed image. If false, these params are taken -from the default JS9.imageOpts object. - -
Get information about the current WCS
-

-wcsobj = JS9.GetWCS() -

-returns: -

    -
  • wcsobj: object containing WCS info -
-

-Get information about the current WCS, including: -

    -
  • version: the WCS version ("default" or the letter "A"-"Z" for an alternate WCS) -
  • wcsname: the value of the WCSNAME header parameter associated -with this WCS, if present -
  • crot: crot value (i.e., the CROT1 value) from WCS library -
  • crpix[1,2]: crpix values from WCS library -
  • crval[1,2]: crval values from WCS library -
  • crdelt[1,2]: crdelt values from WCS library -
  • crtype[1,2]: crtype values (e.g., "RA" and "Dec") from WCS library -
  • ptype: ptype value (e.g., "TAN") from WCS library -
  • radecsys: radecsys value (e.g., "ICRS") from the WCS library -
- -
Set the current WCS
-

-JS9.SetWCS(which) -

-where: -

    -
  • which: WCS name or id -
-Set the current WCS, in cases where alternate WCS's are available. The -alternate WCS convention is described in the standard paper by Greisen -and Callebretta Representations of world coordinates in FITS -(A&A 395, 1061–1075 (2002).) If a FITS file contains alternate WCS -info, you can switch to an alternate using this routine or using -the File->alternate wcs menu option. -

-The which argument can be one of the following: -

    -
  • default: the default WCS from the original file -
  • [version]: the version letter of the alternate WCS, i.e., A-Z -
  • [wcsname]: the value of the WCSNAME header parameter associated -with this WCS, if present -
-If no argument is supplied, the default WCS is set up. - -
Get the current WCS units
-

-unitsstr = JS9.GetWCSUnits() -

-returns: -

    -
  • unitstr: "pixels", "degrees" or "sexagesimal" -
-Get the current WCS units. - -
Set the current WCS units
-

-JS9.SetWCSUnits(unitsstr) -

-where: -

    -
  • unitstr: "pixels", "degrees" or "sexagesimal" -
-Set the current WCS units. - -
Get the current World Coordinate System
-

-sysstr = JS9.GetWCSSys() -

-returns: -

    -
  • sysstr: current World Coordinate System ("FK4", "FK5", "ICRS", -"galactic", "ecliptic", "image", or "physical"); -
-Get current WCS system. - -
Set the current World Coordinate System
-

-JS9.SetWCSSys(sysstr) -

-where: -

    -
  • sysstr: World Coordinate System ("FK4", "FK5", "ICRS", -"galactic", "ecliptic", "image", or "physical") -
-Set current WCS system. The WCS systems are available only if WCS -information is contained in the FITS header. Also note that "physical" -coordinates are the coordinates tied to the original file. They are -mainly used in X-ray astronomy where individually detected photon -events are binned into an image, possibly using a blocking factor. -For optical images, image and physical coordinate usually are identical. - -
Convert image pixel position to WCS position
-

-wcsobj = JS9.PixToWCS(x, y) -

-where: -

    -
  • x: x image coordinate (or object containing x and y properties) -
  • y: y image coordinate -
-returns: -
    -
  • wcsobj: world coordinate system object -
-

-The returned WCS object contains the following properties: -

    -
  • ra: right ascension in floating point degrees -
  • dec: declination in floating point degrees -
  • sys: current world coordinate system being used -
  • str: string of WCS in current system ("[ra] [dec] [sys]") -
-You can either supply the x and y image coordinates as two numeric -arguments, or supply a single object containing numeric x and y properties. - -
Convert WCS position to image pixel position
-

-pixobj = JS9.WCSToPix(ra, dec) -

-where: -

    -
  • ra: right ascension in floating point degrees (or object containing ra and dec properties) -
  • dec: declination in floating point degrees -
-returns: -
    -
  • pixobj: pixel object -
-The returned pixel object contains the following properties: -
    -
  • x: x image coordinate -
  • y: y image coordinate -
  • str: string of pixel values ("[x]" "[y]") -
-You can either supply the RA and Dec as two numeric arguments, or supply a -single object containing numeric ra and dec properties. - -
Display a text message
-

-JS9.DisplayMessage(which, text) -

-where: -

    -
  • which: "info" or "regions" -
  • text: text to display -
-The text string is displayed in the "info" area (usually occupied by the -valpos display) or the "region" area (where regions are displayed.) The -empty string will clear the previous message. - -
Display a WCS-based coordinate grid
-

-JS9.DisplayCoordGrid(mode, opts) -

-where: -

    -
  • mode: true (display) or false (hide) -
  • opts: optional object or JSON string containing grid parameters -
-A coordinate grid displays lines of constant RA and constant Dec, with -the points of intersection labeled by their RA and Dec values. The -labels are in sexagesimal notation if the WCS units are sexagesimal, -otherwise they are in degrees. When using sexagesimal notation, labels -will be shortened if possible, e.g., if the RA hours are the same in -two successive labels but the minutes are different, only the minutes -are shown in the second label. - -

-If no arguments are supplied, the routine returns true if the -coordinate grid is currently being displayed, false otherwise. A -boolean first argument specifies whether to display the coordinate -grid or not. - -

-The optional second argument is an opts object (or a JSON-formatted -string) containing properties to override the default JS9.Grid.opts -properties. These properties include: -

    -
  • strokeWidth: grid stroke width -
  • lineColor: color of RA and Dec grid lines -
  • raLines: approx. number of RA grid lines -
  • raAngle: rotation for RA label -
  • raSkip: number of RA lines to skip -
  • decLines: approx. number of Dec grid lines -
  • decAngle: rotation for Dec label -
  • decSkip: number of Dec lines to skip -
  • labelColor: color of text labels -
  • labelFontFamily: label font -
  • labelFontSize: label font size -
  • labelFontStyle: label font style -
  • labelFontWeight: label font weight -
  • labelRAOffx: x offset of RA labels -
  • labelRAOffy: y offset of RA labels -
  • labelDecOffx: x offset of Dec labels -
  • labelDecOffy: y offset of Dec labels -
  • degPrec: precision for degree labels -
  • sexaPrec: precision for sexagesimal labels -
  • reduceDims: reduce lines of smaller image dim? -
  • stride: fineness of grid lines -
  • margin: edge margin for displaying a line -
  • labelMargin: edge margin for displaying RA, Dec label -
  • cover: grid lines cover: display or image -
-The strokeWidth property determines the width of the grid -lines. It also serves as a reminder that you can pass other standard -shape properties in the opts object. - -

-JS9's label placement algorithm puts labels close to the intersection -of RA and Dec lines. A number of properties can be useful in cases -where this simple algorithm is not sufficient: the raAngle -and decAngle properties allow you to rotate the labels with -respect to the grid lines. The four label[RA,Dec]Off[x,y] properties -allow you to move the label with respect to the grid lines. -The raSkip and decSkip properties allow you to skip -labelling the first available lines within the display. It can be -useful, for example, on a rotated image, when the labels are placed in -a corner. - -

-The degPrec and sexaPrec properties specify the precision for -degree values and sexagesimal values, respectively. Higher precision will -use more digits and take more space along each line. - -

-A number of properties are (more or less) internal but might be of -use: the reduceDims property will reduce the raLines -and decLines properties by the ratio of image dimensions if one -dimension is smaller than the other. This can prevent crowding in the -smaller dimension. The stride property specifies the length of -each line segment that together make up a grid line. A smaller stride -might make the grid lines smoother in some cases, at the price of more -processing time. The cover property determines whether the -grid is drawn over the entire image or just the displayed part of the -image. At the moment, drawing lines over the displayed part of the -image seems to be sufficient. - -

-Note that you can specify global site-wide values for all these parameters -(overriding the JS9.Grid.opts defaults) by supplying them in a grid -object within the globalOpts object in the js9prefs.js file. - -

-Example: display a coordinate grid, specifying the line color: -

-    JS9.DisplayCoordGrid(true, {lineColor: "pink"});
-
- -
Get background-subtracted counts in regions
-

-JS9.CountsInRegions(sregion, bregion, opts) -

-where: -

    -
  • sregion: any source region, or "$sregions" for displayed source regions -
  • bregion: any background region, or "$bregions" for displayed background regions -
  • opts: optional object or JSON string containing region parameters -
-The regcnts -program (and its predecessor, funcnts) counts photons in specified -source regions and optionally, in specified background regions. -Displayed results include the bkgd-subtracted counts in each region, -as well as the error on the counts, the area in each region, and the -surface brightness (cnts/area**2) calculated for each region. Regcnts -for desktop use is available on -GitHub. - -

-The regcnts program has been compiled into JS9 using -Emscripten. -Using this routine, it can be run on the FITS file stored in memory -for the currently displayed image. The first two arguments specify -the source region(s) and background region(s), -respectively. You can pass a standard region specifier as the source -or background region: -

-    JS9.CountsInRegions('ICRS; circle(23:23:18.76, +58:47:27.25, 31.8")');
-
-If the string "$sregions" ("$bregions") is -specified, the source (background) regions are taken from the -currently displayed image. You also can specify a region selector -using a regions selection string. -For example: -
-    # all regions
-    JS9.CountsInRegions('all');
-    # selected regions
-    JS9.CountsInRegions('selected');
-    # regions tagged with the "foo" tag
-    JS9.CountsInRegions('foo');
-
-Note that if you pass a region selector and no regions are returned, -the routine will throw an error. Also note that, in this context, text -and cross regions not valid regions (and are ignored). - -

-In keeping with how desktop regcnts works, if no argument or null or a -null string is specified as the source region, the entire field is -used as the source region. If no argument or null or a null string is -explicitly specified as a background region, no regions are used for -the background. In particular, if you pass only the source region -argument, or pass only the source region and opts arguments, no -background region is used. To recap: -

-    # use entire field, no background
-    JS9.CountsInRegions([opts])
-    JS9.CountsInRegions("field"||null||""[, opts])
-
-    # use displayed source and displayed background
-    JS9.CountsInRegions("$sregions", "$bregions"[, opts])
-
-    # use displayed source, no background
-    JS9.CountsInRegions("$sregions"[, opts])
-
-    # use displayed source and specified background
-    JS9.CountsInRegions("$sregions", bregions[, opts])
-
-    # use specified source, no background
-    JS9.CountsInRegions(sregions[, opts])
-
-    # use specified source and specified background
-    JS9.CountsInRegions(sregions, bregions[, opts])
-
-    # use specified source and displayed background
-    JS9.CountsInRegions(sregions, "$bregions"[, opts])
-
-   # use entire field and specified background
-    JS9.CountsInRegions("field"||null||"", bregions[, opts])
-
-    # use entire field and displayed background
-    JS9.CountsInRegions("field"||null||"", "$bregions"[, opts])
-
- -The third argument allows you to specify options to regcnts: -
    -
  • cmdswitches: command line switches passed to regcnts -
  • dim: size of reduced image (def: max of JS9.globalOpts.image.[xdim,ydim]) -
  • reduce: reduce image size? (def: true) -
  • lightwin: if true, results are displayed in a light window -
-The command line switches that can be specified in cmdswitches are -detailed in the -regcnts help -page. Aside from switches which control important aspects of the -analysis, the "-j" switch (which returns the output in JSON format) -might be useful in the browser environment. Some examples: -
-    # display results in a light window
-    JS9.CountsInRegions({lightwin: true})
-
-    # return JSON using maximum precision in output
-    JS9.CountsInRegions({cmdswitches: "-j -G"})
-
-Results are also returned as a text string. - -

-The regcnts code is memory (and cpu) intensive. In the desktop -environment, this is not typically a problem, but the -memory-constrained browser environment can present a challenge for -large images and binary tables. To avoid running out of memory (and -for large images, to speed up processing considerably), the -JS9.CountsInRegions() routine will bin the image to reduce its size, -unless the reduce option is explicitly set to false. The binned -image size can be specified by the dim option, defaulting to -the global value of the image dimension options. When a file is binned -in this manner, the returned resolution value (e.g., arcsec/pixel) -will reflect the applied binning. Note that the number of photons -found inside a binned and unbinned region differ slightly, due to the -difference in the pixel boundaries in the two cases. - -

-The Counts in Regions option of the Analysis -> Client-side -Analysis menu runs regcnts on the source and background regions of -the currently displayed image. The results are displayed in a light window. - -

-Finally, note that the main JS9 web -site also offers regcnts as a server-based analysis program in the -Analysis menu. The displayed source and background regions are passed -to the server for processing. Because this version runs the desktop -program, it runs on the original file and does no binning to reduce -the image size (which, by the way, could lengthen the processing -time.) But the server-side task also can be useful for -large file support, which involves -displaying a small representation file associated with a much larger -parent file stored on the server. In this case, you often want to run -the analysis on the larger (original) file. - -

Generate a radial profile plot
-

-JS9.RadialProfile(sregion, bregion, opts) -

-where: -

    -
  • sregion: annulus region, or "$sregions" to use displayed annulus -
  • bregion: any background region, or "$bregions" for displayed background regions -
  • opts: optional object or JSON string containing region and plot parameters -
-The JS9.RadialProfile() routine -uses JS9.CountsInRegions() -to produce a radial profile plot. The source region argument should be -an annulus region (or, when using "$sregions", the displayed source -region should be an annulus.) The background region can be any -region(s) (except text or cross regions), the same as for the counts -routine. - -

-The third argument allows you to specify options to the counts routine, -as well as the following options for the radial profile plot: -

    -
  • color: color of the plot line (default: "green") -
  • errorbars: show error bars? (default: true) -
  • errorcolor: color of the error bars (default: "red") -
-Note that "-j" (JSON format) and "-r" (output radii) are always added to -the cmdswitches property (and should not be overridden.) This means you can -retrieve the JSON output without generating the plot simply by calling -JS9.CountsInRegions() directly: -
-    JS9.CountsInRegions(sregions, bregions, {cmdswitches: "-j -r"})
-
-The return value is the id of the light window containing the plot. - -
Create or modify a raw data layer
-

-JS9.RawDataLayer(opts, func) -

-where: -

    -
  • opts: layer name or opts object -
  • func: function used to create or modify raw data -
-Each image has raw data associated with it, i.e., the underlying -astronomical image pixels that are scaled and displayed using the -chosen scale and colormap. You can manipulate the raw data by creating -a new raw data layer using JS9.RawDataLayer(), -setting -the image pixel values, and then making this layer the current -one. The original raw data (with id "raw0") will be maintained in -separate layer, so you can switch between layers (also using this -routine.) - -

-To create a new raw data layer (or edit an existing layer), call the -JS9.RawDataLayer() with two arguments: layer opts (or layer -name) and a function. The layer opts object can have the following properties: -

    -
  • rawid: id of new raw data layer (default: "alt") -
  • oraw: id of raw data layer to pass to func or "current" (default: "raw0", i.e., the original data) -
  • from: descriptive string describing origin of this raw data (def: "func") -
-Alternative, you can pass the id of the raw data layer as a string and -use the defaults for the other properties (which usually is sufficient.) - -

-The pixel modifying function should have the following calling sequence: -

-    func(oraw, nraw, opts)
-
-where: -
    -
  • oraw: the raw data object specified by the from property above (def: original raw data "raw0"); -
  • nraw: the raw data layer you are modifying -
  • opts: the original opts object along with any params you add to it -
-The function should return true is you want to switch to the new layer -and display it, or false to discard the new layer (in case of an error.) - -

-Note that the nraw object will contain the raw data for this -layer, if it already exists. Otherwise, it will contain a copy of -the from data. - -

-For example, the following routine creates a new "clip" layer and -clips the original raw data at the specified nmax level: -

-    im.rawData({rawid: "clip", nmax: n}, function (oraw, nraw, opts){
-        var i, len;
-        opts = opts || {};
-        if( opts.nmax === undefined ){ opts.nmax = 0; }
-        len = nraw.width * nraw.height;
-        for(i=0; i<len; i++){
-            if( oraw.data[i] < opts.nmax ){
-                nraw.data[i] = 0;
-            } else {
-                nraw.data[i] = oraw.data[i];
-            }
-        }
-        return true;
-    });
-
-When clipping, the nraw pixel values are taken from the oraw values, so -that you can clip to a value of 100, then clip to a value of 50, and -get the right result. This is different from the following example "add" -layer, which adds a constant value to the existing data: -
-    im.rawData({rawid: "add", val: n}, function (oraw, nraw, opts){
-        var i, len;
-        opts = opts || {};
-        if( opts.val === undefined ){
-            opts.val = 1;
-        }
-        len = nraw.width * nraw.height;
-        for(i=0; i<len; i++){
-            nraw.data[i] += opts.val;
-        }
-        return true;
-    });
-
-Here, the operation is performed on the existing "add" layer each time, so -that the addition is cumulative. - -

-The oraw and nraw objects contain a subset of the properties returned by -JS9.GetImageData(): -

    -
  • width: x dimension of image -
  • height: y dimension of image -
  • bitpix: FITS bits/pixel of each image element (8 for unsigned char, 16, 32 for signed integer, -32 or -64 for float) -
  • header: JavaScript object containing FITS header values -
  • data: buffer containing raw data values -
- -

-To switch to a layer, call JS9.RawDataLayer() -with a single argument, the layer name: -

-    JS9.RawDataLayer("raw0")   # switch to original data
-    JS9.RawDataLayer("clip")   # switch to clipped data
-    JS9.RawDataLayer("add")    # switch to add data
-
-To get the currently displayed layer, call the routine with no arguments: -
-    JS9.RawDataLayer()         # returns "clip"
-
- -
Gaussian blur of raw data
-

-JS9.GaussBlurData(sigma, opts) -

-where: -

    -
  • sigma: sigma of Gaussian function -
  • opts: options object -
-This routine creates a new raw data layer called "gaussBlur" in which -the image pixel values are blurred using a Gaussian function with the -specified sigma. The routine uses the fast Gaussian blur algorithm -(approximating a full Gaussian blur with three passes of a box blur) -described -here. -

-See JS9.RawDataLayer() for more -information about raw data layers. - -

Perform image arithmetic on raw data
-

-JS9.ImarithData(op, arg1, opts) -

-where: -

    -
  • op: image operation: "add", "sub", "mul", "div", "min", "max", and "reset" -
  • arg1: image handle, image id or numeric value -
  • opts: options object -
-The JS9.ImarithData() routine performs basic arithmetic -(addition, subtraction, multiplication, division, minimum, maximum, average) -between the currently displayed image and either another image or a -constant value. The first op argument is a string, as detailed -above. The second arg1 argument can be a numeric value or an -image id. In the former case, the constant value is applied to each -pixel in the image. In the latter case, the operation is performed -between the corresponding pixels in the two images. For example: -
-    JS9.ImarithData("max", "foo.fits");
-
-will make a new data layer of the currently displayed image, where -each pixel is the larger value from that image and the foo.fits image -(which can be in any display.) - -

-This routine creates a new raw data layer called "imarith" containing -the results of the operation. Successive calls to this routine are -cumulative, so that you can build up a more complex operation from -simple ones. For example: -

-    # foo.fits is displayed in the "myJS9" display
-    var myim = JS9.GetImage({display: "myJS9"});
-    JS9.ImarithData("max", myim);
-    JS9.ImarithData("add", 2.718);
-
-will make a new data layer where each pixel is the larger value from -the two images, after which an approximation of the irrational number -e is added to each pixel. - -

-The special reset operation deletes the "imarith" raw data -layer, allowing you to start afresh. - -

-The bitpix value of the new "imarith" layer is chosen as follows: -

    -
  • for operations between two images, bitpix the "larger" of the two -images (where float is "larger" than int.) -
  • for operations between an image and a constant, bitpix of -32 -(single float) is chosen unless the image itself has bitpix of -64, in -which case the double float bitpix is chosen. -
-You can override the choice of bitpix by passing a bitpix property -in the optional opts object. - -

-Finally, note that the two images must have the same dimensions. We -might be able to remove this restriction in the future, although -it is unclear how one lines up images of different dimensions. -

-See JS9.RawDataLayer() for more -information about raw data layers. - -

Shift raw data
-

-JS9.ShiftData(x, y, opts) -

-where: -

    -
  • x: number of pixels to shift in the x (width) direction -
  • y: number of pixels to shift in the y (height) direction -
  • opts: options object -
-This routine creates a new raw data layer called "shift" in which -the pixels are shifted from the original image array by the specified -amount in x and/or y. The results of successive shifts are -cumulative. The routine is used by the Harvard-Smithsonian Center for -Astrophysics MicroObservatory project interactively to align images -that are only slightly offset from one another. -

-See JS9.RawDataLayer() for more -information about raw data layers. - -

Reproject an image using a specified WCS
-

-JS9.ReprojectData(wcsim, opts) -

-where: -

    -
  • wcsim: image containing the WCS used to perform the reprojection -
  • opts: options object for raw data layer -
-JS9.ReprojectData() creates a new raw data layer (with default id -of "reproject") in which the pixels are reprojected using the WCS from -another image. The -mProjectPP -program from the -Montage software suite -is used to perform the reprojection. Please read the documentation on -mProjectPP from the Montage web site, which includes this explanation: -

-

-    mProjectPP performs a plane-to-plane transform on the input image, and
-    is an adaptation of the Mopex algorithm and developed in collaboration
-    with the Spitzer Space Telescope. It provides a speed increase of
-    approximately a factor of 30 over the general-purpose mProject. However,
-    mProjectPP is only suitable for projections which can be approximated
-    by tangent-plane projections (TAN, SIN, ZEA, STG, ARC), and is therefore
-    not suited for images covering large portions of the sky. Also note that
-    it does not directly support changes in coordinate system (i.e., equatorial
-    to galactic coordinates), though these changes can be facilitated by the
-    use of an alternate header.
-
-These Montage programs have been compiled into JS9 using -Emscripten. - -

-The wcsim argument is an image id, image filename, or image -object pointing to the WCS image. This is the image whose WCS will be used -for the reprojection. Alternatively, if the wcsim argument is set to -"all", the WCS from the currently displayed image will be used to reproject -all other images in the display. - -

-The opts object can contain the following reproject-specific properties: -

    -
  • rawid: the id of the raw data layer to create (default: "reproject") -
  • cmdswitches: a string containing mProjectPP command line switches -
-The cmdswitches will be prepended to the mProjectPP command line. For example: -
- {cmdswitches: "-d 1 -z .75"}
-
-will set the mProjectPP debugging and the drizzle factor, resulting in a -command line that looks like this: -
-  mProjectPP -d 1 -z .75 -s statusfile in.fits out.fits template.hdr
-
-See the -mProjectPP -documentation for more information about command switches. - -

-Reprojection is an intensive process which can take a considerable -amount of memory and processing time. It also (at least currently) -requires that the full reprojected image be displayed (so that the -reprojected image can be properly aligned with the WCS image used in -making the reprojection.) We therefore restrict the WCS image size to -be less than or equal to JS9.globalOpts.image.xdim by -JS9.globalOpts.image.ydim. If the WCS image exceeds this size, an -error is thrown. -

-See JS9.RawDataLayer() for more -information about raw data layers. - -

Rotate an image around the WCS CRPIX point
-

-JS9.RotateData(angle, opts) -

-where: -

    -
  • angle: rotation angle in degrees -
  • opts: options object -
-The JS9.RotateData() routine uses -JS9.ReprojectData() -to rotate image data by the specified angle (in degrees.) If the string -"northup" or "northisup" is specified, the rotation angle is set to 0. -By default, the rotation is performed about the WCS CRPIX1, CRPIX2 point. -To rotate about the center of the currently displayed image, pass -the opts.center property with a value of "current" or (globally) -set the JS9.globalOpts.rotationCenter property to "current". -

-Note that this rotation is not accumulative (as is the case with the -JS9.SetRotate() and -JS9.SetRot90() routines), so -calling JS9.RotateData() with an angle of 30 degrees followed by -45 degrees will result in a 45 degree rotation, not a 75 degree -rotation. - -

-The optional opts object is passed directly to the JS9.ReprojectData() -routine. See JS9.ReprojectData() above for more information. - -

Apply a filter to the RGB image
-

-JS9.FilterRGBImage(filter, args) -

-where: -

    -
  • filter: name of image filter to apply to the RGB data -
  • args: filter-specific arguments, where applicable -
-In JS9, you can change the raw data (and hence the displayed image) using -routines such as -JS9.GaussBlurData() -or the more general -JS9.RawDataLayer(). -You also can apply image processing -techniques directly to the displayed RGB image without changing the -underlying raw data, using this routine. The web has an overwhelming -amount of information about image processing. A good technical -article concerning the use of image filters with Javascript and the -HTML5 canvas is available at: - -http://www.html5rocks.com/en/tutorials/canvas/imagefilters/ - - -

-The JS9.FilterRGBImage() routine supports a number of image -processing routines, which are listed below. To call one of them -using JS9.FilterRGBImage(), supply the filter name, followed by any -filter-specific arguments, e.g.: -

-    JS9.FilterRGBImage("luminance", {display: "myJS9"});
-    JS9.FilterRGBImage("duotone", "g", {display: "myJS9"});
-    JS9.FilterRGBImage("convolve", [-1,-1,-1,-1,8,-1,-1,-1,-1]);
-
-You can, of course, use the default arguments where applicable. - -

-Note that the standard JS9 colormaps, scale, contrast and bias -selections are applied to the raw data to regenerate the RGB -image. Thus, if you use any of the image processing techniques listed -below and then change colormap, contrast, bias, or scale, you will -undo the applied image processing. This is a good way to reset the -displayed image. The same thing can be accomplished programmatically by -specifying "reset" as the filter name: -

-    JS9.FilterRGBImage("reset", {display: "myJS9"});
-
- -

-The following simple image processing filters are available: -

    -
  • luminance():convert to greyscale using the CIE luminance: -0.2126*r + 0.7152*g + 0.0722*b -
  • greyscale():convert to greyscale using the standard greyscale: -0.3*r + 0.59*g + 0.11*b -
  • greyscaleAvg():convert to greyscale using averaging: -(r+g+b) / 3 -
  • brighten(val): add constant value to each pixel to change the brightness: -[r + val, g + val, b + val] -
  • noise(v1, v2): add random noise: -pixel += Math.floor((Math.random()*(v2-v1)) - v2), -defaults are v1=-30, v2=30 -
  • duotone("r"|"g"|"b"): remove a color by setting it to -the avg of the two others: r=(g+b)/2, default color is "r" -
  • invert(): the RGB channels of the image are inverted: -[255-r, 255-g, 255-b, a] -
  • pixelate(size):make image look coarser by creating a square tiling -effect of the specified size, default size is 2 -
  • sepia(): image takes on shades of brown, like an antique photograph -
  • contrast(val): change the difference in brightness between the min -and max intensity of a pixel, default val is 2 -
  • threshold(thresh, low, high):create a two-color image in which pixels -less bright than thresh are assigned the low value (default 0 for black), -otherwise the high value (default: 255 for white) -
  • gamma(gcorr): apply the nonlinear gamma operation, used to code and -decode luminance values in video or still image systems: -out = pow(in, gcorr), default gcorr is 0.2 -
  • posterize(): convert a smooth gradation of tone to regions -of fewer tones, with abrupt changes between them -
  • scatter(): scatters the colors of a pixel in its neighborhood, akin -to viewing through brittle cracked glass -
  • solarize(): which image is wholly or partially reversed in -tone. Dark areas appear light or light areas appear dark. -
- -

-The following image convolutions are available: -

    -
  • convolve(weights, [opaque]) convolve the image using the weights array -as a square convolution matrix. If opaque is true (default), the image will -have an opaque alpha channel, otherwise the alpha is convolved as well. -
  • sobel(): use the Sobel operator to create an image that emphasizes the edges -
  • medianFilter(): noise reduction technique that replaces each pixel with -the median of neighboring pixels -
  • gaussBlur5(): image pixel values are blurred using a 5x5 Gaussian -
  • edgeDetect(): detect edges using the kernel -[ -1, -1, -1, -1, 8, -1, -1, -1, -1 ] -
  • sharpen(val): sharpen the image using the kernel -[ 0, -3, 0, -3, val, -3, 0, -3, 0 ] -
  • blur(): blur the image using the kernel -[ 1, 2, 1, 2, 1, 2, 1, 2, 1 ] -
  • emboss(val): produce embossing effect using the kernel -[-18, -9, 9, -9, 100 - val, 9, 0, 9, 18 ] -
  • lighten(val): apply the kernel -[ 0, 0, 0, 0, val, 0, 0, 0, 0 ], -default val of 12/9 lightens the image -
  • darken(val): apply the kernel -[ 0, 0, 0, 0, val, 0, 0, 0, 0], -default val of 6/9 darkens the image -
- -

-With no arguments, the routine returns an array of available filters: -

-    JS9.FilterRGBImage()
-    ["convolve", "luminance", ..., "blur", "emboss", "lighten", "darken"]
-
- -
Save an image session to a file
-

-JS9.SaveSession(session, opts) -

-where: -

    -
  • session: optional name of the file to create when saving this session -
  • opts: optional object or JSON string containing session parameters -
-

-This routine saves session information related to the currently -displayed image or all images in the specified display. The first -argument can be a filename or an options object. If a filename is -specified, the second argument can be the options object. -

-The opts options object supports a mode property -whose value can be "display" (save all images in the specified -display) or "image" (save the currently displayed image. If this -property is not specified, the default is to save all images in the display. -

-If no filename is specified, the default filename depends on the save mode. -If mode is "display", the default filename takes the form js9-[date].ses, -e.g., "js9-2018-01-09.ses". If mode is "image", the default filename is [im.id].ses, e.g., "casa.fits.ses". -

-Saved information (filename, scaling, colormap, contrast/bias, zoom, -regions, catalogs, etc) is stored in a JSON-formatted text file. You can -subsequently load this file into JS9 to restore the image session. -Don't forget that the file is saved by the browser in whatever location -you have set up for downloads. -

-The session file is a text file and can be edited, subject to the usual -rules of JSON formatting. For example, you can change the colormap, -scaling, etc. after the fact. -

-The session file contains a file property near the top that -specifies the location of the image. A local file usually will contain -an absolute path or a path relative to the web page being displayed. -However, if the image was originally opened using drag-and-drop, no -pathname information is available, in accordance with standard web -security protocols. In this case, you must edit the session file to -supply the path (either absolute or relative to the web page) before -re-loading the session. - -

Load a previously saved image session from a file
-

-JS9.LoadSession(session) -

-where: -

    -
  • session: name of the session file to load -
-

-Restore an image session by loading a JSON-formatted session file. The -image itself is retrieved and loaded, and all of the saved parameters -and graphics (scale, colormap, regions, catalogs etc) are applied to -the display. -

-The pathname of the session file should either be absolute or should be -relative to the web page. -

-The session file contains a file property near the top that -specifies the location of the image. For browser-based JS9, a local -file usually will contain an absolute path or a path relative to the -web page being displayed. - -

-On the desktop, session files and the associated data files often are -moved around or used with different web pages, breaking the connection -between the web page and the image path. To deal with this problem, -the JS9.desktoplOpts.sessionPath variable is provided: -

    -
  • if set to true, the image path is relative to the location -of the session file (this is the default) -
  • if set to false, the image path is relative to the web page -value (as with browser-based JS9) -
-This means that if you store your session file relative to the -contained image, you can move both files to any location on your disk. - -

-If the image was originally opened using drag-and-drop, no pathname -information is available, in accordance with standard web security -protocols. In this case, you may have to edit the session file to -supply the path (either absolute or relative) before re-loading the -session. - -

-Note that the raw data file itself is not saved (only its pathname), -so you must have access to that file in order to restore a session. However, -the data file need not be in the same location as it was originally: you -can adjust the path of the data file by editing the file property -as needed. - -


- -

Working with Regions

- -

-Spatial regions of interest are a crucial part of astronomical data -analysis, especially X-ray analysis. Programs having spatial region -support can select parts of a FITS image or binary table using simple -geometric shapes, so that only pixels found within these shapes are -processed. See -regions -for a general discussion of spatial region filtering in astronomy, and -regcnts -for an example program using spatial regions. - -

-JS9's support for spatial regions allows you to create and delete -regions, load them from an external file, change characteristics such as -size and color, use them as selection criteria in local analysis or -pass them to remote analysis, and export them a file. - -

-The regions layer in JS9 is a special case of the more generalized -Shape layers, but it is automatically created by -JS9 to support the options in the Regions menu, as well as -local and server-side data analysis using regions. As such, the -region routines are just a thin layer on top of the Shape routines, -calling the equivalent Shape routine with "region" as the first argument. - -

Selecting Regions
- -One of the most important aspects of using regions is the ability to assign -different characteristics to regions and then make selections based on -these characteristics. The -JS9.ChangeRegions(), -JS9.GetRegions(), -JS9.ListRegions(), -JS9.RemoveRegions(), -and -JS9.SelectRegions() -JS9.GroupRegions() -calls all take a region selection specification as the first argument, -which can be any of the following (in order of precedence): -
    -
  • selected: the selected region (or all regions in selected group) -
  • all: all regions, but not including child text regions (default) -
  • All: all regions, including child text regions -
  • [id]: a integer region id (or an array of ids), as -returned by JS9.AddRegions() -
  • [color]: all regions having the specified color (e.g., "red") -
  • [shape]: all regions having the specified shape (e.g., "circle") -
  • child: a child region (i.e. text child of another region) -
  • parent: a region that has a child (i.e. has a text child) -
  • [wcs]: regions whose initial wcs matches the specified wcs -
  • [tag]: all regions containing the specified tag (e.g., "source") -
  • /[regexp]/: all regions whose tags match the regexp (e.g. "/foo[1-4]/") -
  • dcoords: a region that preserves display coordinates -
  • nodcoords: a region that does not preserve display coordinates -
-Of these, all, selected, [color], [shape], and -[tag] are probably the most often used. Selections make it -possible to act on multiple regions at the same time. For example: -
-    # all currently selected regions
-    JS9.ListRegions("selected");
-
-    # all circles
-    JS9.ChangeRegions("circle", {"color": "red"});
-
-    # all red regions
-    JS9.GetRegions("red");
-  
-    # all regions with the tag 'foo1'
-    JS9.ChangeRegions("foo1", {"color": "red"});
-  
-    # all regions with a tag matching the regular expression foo.*
-    JS9.ListRegions("/foo.*/");
-
-    # region with id 7
-    JS9.SelectRegions(7, {"color": "red"});
-
-In addition, you can combine selections using the boolean operators, -with the usual precedence and associativity rules holding sway: -
-  Operator                                Associativity
-  --------                                -------------
-  !  (bitwise not)                        right to left
-  && (logical and)                        left to right
-  || (logical or)                         left to right
-
-For example: -
-    # circles or ellipses
-    JS9.ChangeRegions("circle || ellipse", {"color": "red"});
-
-    # circles or red regions
-    JS9.ListRegions("circle || red");
-
-    # circles having tag 'foo1'
-    JS9.ChangeRegions("circle && foo1", {"color": "red"});
-
-    # circles not having tag 'foo2'
-    JS9.SelectRegions("circle && !foo2");
-
-    # all regions except red ones
-    JS9.ChangeRegions("!red", {"color": "cyan"});
-
-    # not selected regions
-    JS9.ChangeRegions("!selected", {"color": "cyan"});
-
-    # circles having tag 'foo1' and ellipses having tag 'foo2'
-    JS9.GetRegions("(circle && foo1) || (ellipse && foo2)");
-
-When a region selection is made using the -JS9.ChangeRegions() or -JS9.SelectRegions() calls, the -selection is saved so that you can use it as part of subsequent selection -calls. You can specify use of the saved selection either in the opts object -or directly in the selection string: -
-    # select circle regions and save selection filter
-    JS9.SelectRegions("circle")
-
-    # select saved regions, along with ellipses that have a "foo1" tag
-    JS9.SelectRegions("ellipse && foo1", {"saved": true})
-
-    # select saved regions, along with ellipses that have a "foo1" tag
-    JS9.SelectRegions("ellipse && foo1", {"saved": "or"})
-
-    # select saved regions, along with ellipses that have a "foo1" tag
-    JS9.SelectRegions("saved || (ellipse && foo1)")
-
-    # select saved regions if they are ellipses that have a "foo1" tag
-    JS9.SelectRegions("ellipse && foo1", {"saved": "and"})
-
-    # select saved regions if they are ellipses that have a "foo1" tag
-    JS9.SelectRegions("saved && ellipse && foo1")
-
-    # retrieve currently saved regions
-    JS9.ListRegions('saved')
-
-Calling JS9.SelectRegions("reset") -will clear the saved selection. - -
Add one or more regions to the regions layer
-

-id = JS9.AddRegions(rarr, opts) -

-where: -

    -
  • rarr: a shape string, region object or an array of region objects -
  • opts: global values to apply to each created region -
-returns: -
    -
  • id: id of last region created -
-The rarr argument can be a region shape ("annulus", "box", -"circle", "cross", "ellipse", "point", "polygon", "text"), a single region -object, or an array of region objects. Region objects contain one or -more properties, of which the most important are: -
    -
  • shape: "annulus", "box", "circle", "cross", "ellipse", "point", "polygon", "text" [REQUIRED] -
  • x: image x position -
  • y: image y position -
  • px: physical x position -
  • py: physical y position -
  • ra: RA in degrees -
  • dec: Dec in degrees -
  • wcs: sexagesimal WCS string with optional WCS system -
  • lcs: object containing logical x, y and sys (e.g., "physical") -
  • deltax: increment from current image x position -
  • deltay: increment from current image y position -
  • tags: comma-separated list of tag strings or array of tag strings -
  • radii: array of radii for annulus region -
  • width: width for box or cross region -
  • height: height for box or cross region -
  • radius: radius value for circle region -
  • r1: x radius for ellipse region (misnomer noted) -
  • r2: y radius for ellipse region (misnomer noted) -
  • pts: array of objects containing x and y positions for polygons -
  • points: array of objects containing x and y offsets from the center for polygons -
  • angle: angle in degrees for box, ellipse, cross regions -
  • color: region color (string name or #rrggbb syntax) -
  • strokeWidth: line (stroke) width of the region -
  • strokeDashArray: array specifying dash pattern, e.g, [3,1] -
  • text: text associated with text region or for a child region of this region -
  • data: this property can be an object, string, number, -etc. and will be carried along with the region, and returned as a -property by the JS9.GetRegions() call. -
-Other available properties include: -
    -
  • changeable: if false, region cannot be moved, resized, rotated -
  • locked: 'opposite alias' of changeable -
  • movable: if false, region cannot be moved -
  • resizable: if false, region cannot be resized or rotated -
  • rotatable: if false, region cannot be rotated -
  • removable: if false, region cannot be removed -
  • selectable: if false, region can't be selected (no GUI-based changes) -
  • lockMovementX: if true, region cannot be moved in the x direction -
  • lockMovementY: if true, region cannot be moved in the y direction -
  • lockScalingX: if true, region cannot be resized in the x direction -
  • lockScalingY: if true, region cannot be resized in the y direction -
  • lockRotation: if true, region cannot be rotated -
  • fontFamily: font parameter for text region -
  • fontSize: font parameter for text region -
  • fontStyle: font parameter for text region -
  • fontWeight: font parameter for text region -
  • sticky: if true, region doesn't change during pan, zoom, rotate, flip -
  • preservedcoords: if true, the region is sticky, and display coordinates are preserved during save and copy operations (see below for more info) -
-Here are some examples of ways to create regions: -
-    # example 1: circular region in the center of the field
-    JS9.AddRegions("circle");
-
-    # example 2: red circular region in the center of the field
-    JS9.AddRegions("circle", {color: "red"});
-
-    # example 3: red circular region with dashed lines
-    JS9.AddRegions("circle", {color: "red", strokeDashArray: [3,1]});
-
-    # example 4: regions using an object in first arg
-    JS9.AddRegions({shape: "circle", color: "red", strokeDashArray: [3,1]})
-
-    # example 5: multiple regions using an array specification in first arg
-    JS9.AddRegions([{shape: "circle", color: "red", strokeDashArray: [3,1]},
-                    {shape: "box", color: "green", strokeDashArray: [6,1]}])
-
-    # example 6: js9 region syntax: properties in the second arg object
-    JS9.AddRegions('ellipse(23:23:22.179, +58:48:10.542, 40", 20", 60)', {text: "ellipse test", color: "violet", tags: "json tag, another tag", textOpts: {color: "yellow", fontSize: 16, fontStyle: "italic", fontWeight: "bold"}});
-
-    # example 7: js9 region syntax: JSON properties in the first arg string
-    JS9.AddRegions('ellipse(23:23:22.179, +58:48:10.542, 40", 20", 60) {"color": "violet", "text": "ellipse test", "textOpts": {"color": "yellow", "fontSize": 16, "fontStyle": "italic", "fontWeight": "bold"}} # json tag, another tag');
-
-    # example 8: ds9 region syntax: comment properties in the first arg string
-    JS9.AddRegions('box(23:23:35.486, +58:50:03.146, 40", 20", 30) # width=4 text={box test} dash=1 color=red rotate=0 tag="test tag"')
-
-    # example 9: create a region at the specified RA and Dec using ICRS
-    # Note that the WCS string is returned by the Edit menu's "copy wcs pos"
-    # option (i.e., the "/" keystroke.)
-    JS9.AddRegions("circle", {wcs: "23:23:28.895 +58:49:43.50 ICRS"});
-
-    # example 10: create a region by supplying display (screen) coordinates
-    image
-    text(d250, d100, "Using Display Coordinates")
-
-    # example 11: create a region by supplying display (screen) coordinates
-    # preserve the display coordinate when saving, copying
-    # and don't move the region when panning, zooming
-    image
-    text(d250, d100, "Using and Preserving Display Coordinates:") {"preservedcoords": true}
-
-
-In sum, you can specify a region using: -
    -
  • a shape in the first string arg, optional properties in the second object arg -
  • properties (including the shape) in the first object arg -
  • array of objects in the first arg -
  • full region syntax in the first string arg, optional properties in the second arg -
-Note the difference between examples 6 and 7: the former passes -properties in an object (second argument), so the key names -need not be quoted. The latter passes properties in a JSON -string as part of the first string argument: here the key names must be -quoted using double quotes, as per the JSON specification. - -

-Examples 6 and 7 also show the text property, which allows you -to associate a text string with a non-text region. JS9 will create a -separate text region as a child of the original region. You can -move this child text region around relative to the original region, -change its angle, etc. The child will then maintain its new position -relative to the original region as the latter is moved, resized, -etc. You also can double-click on the text child to bring up its -configuration dialog box and change its color, font, size, text string, -etc. - -

-Examples 10 and 11 show several features of regions that might be -useful for marking images with text and shapes that are tied to the -display rather than the image. When using the image coordinate system, -you can prefix the image positions with 'd' or 'D' to indicate that -they should be interpreted as display (also called "screen") -coordinates instead of image coordinates. The origin of the display is -in the upper left corner (image coordinates are in the lower left). By -default, a region specified with display coordinates is no different -from other regions: the region will change its screen position during -zoom and pan operations to stay aligned on the image, and its position -will be saved using the current coordinate system. That is, by default, -display coordinate are only used in the initial placement of the region. - -

-To preserve the region's display position during zoom and pan operations -and while saving regions, set the preservedcoords property -to true in the opts object. In this case, the region -is no longer a canonical astronomical region of interest, but is more -like a mark on the screen. By default, it will not be listed by the -Regions list menu option, nor will it be saved by default (although -you can set the save dcoords regions to true in the regions -save dialog box, or set savedcoords to true in the opts -property of the -JS9.SaveRegions() routine.) -It also will not be passed to back-end server analysis routines that -specify $regions, $sregions, $bregions in their command line. -However, it will be copied from one image to another when using the -JS9.CopyRegions() routine. -These behaviors are parameterized in the JS9.globalOpts object: -

    -
  • regListDCoords: list preserved display coords? (def: false) -
  • regSaveDCoords: save preserved display coords? (def: false) -
  • regExpandDCoords: pass preserved display coords? to analysis (def: false) -
  • regCopyDCoords: copy preserved display coords? (def: true) -
- -
Get information about one or more regions
-

-rarr = JS9.GetRegions(regions, opts) -

-where: -

    -
  • regions: which regions to retrieve -
  • opts: optional object -
-returns: -
    -
  • rarr: array of region objects (or text if opts.format is "text") -
-

-Get information about one or more regions. -The first argument is the regions selection. -If not specified, it defaults to "selected" if there are selected regions, -otherwise "all". - -

-Each returned region object contains the following properties: -

    -
  • id: numeric region id (assigned by JS9 automatically) -
  • mode: "add", "remove", "select", "update" -
  • shape: region shape ("annulus", "box", "circle", "cross", "ellipse", -"point", "polygon", "text") -
  • tags: comma delimited list of region tags (e.g., "source", "include") -
  • color: region color -
  • x,y: image coordinates of region -
  • radii: array of radii for annulus region -
  • width: width for box or cross region -
  • height: height for box or cross region -
  • radius: radius value for circle region -
  • r1: x radius for ellipse region (misnomer noted) -
  • r2: y radius for ellipse region (misnomer noted) -
  • pts: array of objects containing x and y positions, for polygons -
  • points: array of objects containing x and y offsets from the specified center, for polygons -
  • angle: angle in degrees for box, ellipse, cross regions -
  • ra: RA of center in degrees -
  • dec: Dec of center in degrees -
  • wcsstr: region string in WCS coordinates -
  • wcssys: WCS system (e.g., "FK5") -
  • imstr: region string in image or physical coordinates -
  • imsys: image system ("image" or "physical") -
  • lcs: object containing logical x, y and sys (e.g., "physical") -
  • parent: the id of the parent region, if this is a text child region -
  • child: the id of the child text region, if any -
  • data: data property passed in options object when this shape was created. -
-The x, y, radii, pts, radius, width, height, r1, r2 values are all -returned in the image coordinate system. The lcs object will contain x -and y in logical (i.e., physical) coordinates. Moreover, if the -imsys value is not "image" (i.e., the JS9 coordinate system is not -explicitly set to "image"), then the lcs object also will contain -radii, pts, radius, width, height, r1, r2 in the logical coordinate system. -

-The image position x, y can be used to access the image data returned by the -JS9.GetImageData() routine: -

-    obj = JS9.GetImageData();
-    xreg = JS9.GetRegions("selected")[0];
-    val = obj.data[Math.floor(xreg.y-0.5) * obj.width + Math.floor(xreg.x-0.5)];
-
-

-Note the need to integerize the x and y values: JavaScript arrays are -objects and so floating point array indices do not get truncated -automatically as in C. They will return null values. -

-In opts format property is set to "text", the regions are -returned as a string in standard regions format, using semi-colon -delimiters: -

-    JS9.GetRegions("all", {format: "text"})
-    ICRS; box(23:23:40.3, +58:47:04.05, 29.5\", 29.5\", 0.0) # background,include; ellipse(23:23:28.06, +58:48:40.5, 14.7\", 15.7\") # source,include
-
-By default, the region's json object and comments are passed based on
-the value of the globalOpts.regIncludeJSON
-and globalOpts.regIncludeComments properties, respectively.
-You can override this value by setting the includejson
-and includecomments properties in opts.
-
-

-You can pass wcssys and wcsunits in opts to return the wcs information in the desired format: -

- JS9.GetRegions("all", {format: "text"}) - ICRS; circle(23:23:35.300,+58:50:03.600,14") - - JS9.GetRegions("all", {format: "text", wcsunits: "degrees"}) - ICRS; circle(350.897083,58.834333,0.003889) - - JS9.GetRegions("all", {format: "text", wcssys: "FK4", wcsunits: "degrees"}) - FK4; circle(350.330969,58.559785,0.003889) - - JS9.GetRegions("all", {format: "text", wcsunits: "pixels"}) - physical; circle(3893.94,4091.92,28.46) -
- -

-If opts format property is set to "regions", the regions are -returned as a new-line separated list, similar to the output of -JS9.SaveRegions(). -By default, this will include the wcs keyword: -

-    JS9.GetRegions("all", {format: "regions"})
-    ICRS
-    circle(23:23:27.909,+58:48:42.880,14")
-    box(23:23:35.486,+58:50:03.146,40.001278,14",20.000000)
-
-

-If opts format property is set to "csv", the regions are -returned as a comma-separated value list, using new-line delimiters. -By default, this will not include the wcs keyword: -

-    JS9.GetRegions("all", {format: "csv"})
-    circle,23:23:27.909,+58:48:42.880,14"
-    box,23:23:35.486,+58:50:03.146,40.001278,14",20.000000
-
-

- -

List one or more regions
-

-rstr = JS9.ListRegions(regions, opts) -

-where: -

    -
  • regions: which regions to list -
  • opts: optional object -
-returns: -
    -
  • rstr: region string -
-

-List (and return) the specified regions. By default, a light window is -displayed listing all regions (i.e., as if the list option of the -Regions menu had been selected.) You can also list "selected" regions -or use any of the standard regions specifications (see introduction to the -Regions routines above.) -

-The opts object supports the following properties: -

    -
  • mode: display/return mode (1,2,3) -
  • wcssys: wcs system to use (ICRS, FK5, galactic, physical, etc.) -
  • wcsunits: units for wcs output (sexagesimal, degrees, pixels) -
  • includejson: include JSON object -
  • includecomments: include comments -
  • layer: which layer to display (default is "regions" layer) -
-The mode property accepts the following values: -
    -
  • 1: no display, return full region string including json and comments -
  • 2: display and return shortened region string (no json or comments) -
  • 3: display and return full region string (including json and comments) -
- -
List groups
-

-gstr = JS9.ListGroups(group, opts) -

-where: -

    -
  • group: which group to list or "all" -
  • opts: optional options object -
-returns: -
    -
  • gstr: group string -
-

-List the specified region/shape group(s) in the specified layer (default is -"regions"). The first argument is the groupid of the group to list, -or "all" to list all groups. - -

-The optional opts object can contain the following properties: -

    -
  • includeregions: display regions as well as the group name (default: true) -
  • layer: layer to list (default is "regions") -
-By default, the display will includes the name of the group and the -regions in the group. To skip the display of regions, supply -an opts object with the includeregions property set to false. - -For example: -
-    JS9.ListGroups("all", {"includeregions": false})
-    grp1
-    grp2
-    grp3
-
-    JS9.ListGroups("grp1")
-    grp1:
-    circle(3980.00,4120.00,20.00) # source,include,foo1
-    ellipse(4090.00,4120.00,25.00,15.00,0.0000) # source,include,foo1
-
-

-See JS9.GroupRegions() -for more information about region groups. - -

Edit one or more selected regions
-

-JS9.EditRegions() -

-Edit one or more selected regions using an Edit dialog box. If a -single region has been selected by clicking that region, all of its -properties can be edited via the displayed dialog box. If a group of -regions has been selected using Meta-mousemove to highlight one or -more regions, then properties such as color, stroke width, dash -pattern, and tags can be edited for all of the selected regions using -the displayed dialog box. In the latter case, use shift-click to add -additional regions to the edit group. - -

Change one or more regions
-

-JS9.ChangeRegions(regions, opts) -

-where: -

    -
  • regions: which regions to change -
  • opts: object containing options to change in each region -
-Change one or more regions. -The first argument is the regions selection. -If not specified, it defaults to "selected" if there are selected regions, -otherwise "all". - -

-The opts object can contain the parameters -described in the -JS9.AddRegions() -section. However, you cannot (yet) -change the shape itself (e.g., from "box" to "circle".) See js9onchange.html -for examples of how to use this routine. -

-By default, if you change the color of a region, the color of the text -associated with that region also will be changed: -

-    # color of text associated with this region also will be changed to red
-    JS9.ChangeRegions("circle", {"color": "red"});
-
-You can turn off synchronization of text colors either by setting the -JS9.globalOpts.regSyncTextColor site property to false or -by setting the synctextcolor option to false in the opts object: -
-    # color of text associated with this region will not be changed to red
-    JS9.ChangeRegions("circle", {"color":"red", "synctextcolor":false});
-
-Note that you also can change the JS9.globalOpts.regSyncTextColor -property via the Global tab of the Preferences plugin. -

-If you pass the empty string to color, strokeWidth, -or strokeDashArray, the specified property will be reset as follows: -

    -
  • color: reset based on source/bkgd include/exclude tags -
  • strokeWidth: reset to initial JS9.Fabric.opts.strokeWidth value -
  • strokeDashArray: reset to a solid line -
-For example: -
-    # change circles to be red with a dash pattern
-    JS9.ChangeRegions("circle", {color:"red", strokeDashArray:[3,1]});
-
-    # reset color and dash pattern
-    JS9.ChangeRegions("circle", {color:"", strokeDashArray:""});
-
- -

- -

Copy one or more regions to another image
-

-JS9.CopyRegions(to, regions) -

-where: -

    -
  • to: image id to which to copy regions -
  • regions: which regions to copy -
-Copy regions to a different image. If to is "all", then the regions are -copied to all images. -

-The first argument is the regions selection. -If not specified, it defaults to "selected" if there are selected regions, -otherwise "all". - -

Remove one or more regions from the region layer
-

-JS9.RemoveRegions(regions) -

-where: -

    -
  • regions: which regions to remove -
-The selected regions are removed. -The first argument is the regions selection. -If not specified, it defaults to "selected" if there are selected regions, -otherwise "all". - -

-If JS9.globalOpts.resetEmptyShapeId is set to true (default -is false), the region id counter will be reset to 0 whenever all the -regions are removed. - -

Unremove one or more previously removed regions
-

-JS9.UnremoveRegions() -

-If you accidentally remove one or more regions, you can use restore -them using this call. JS9 maintains a stack of removed regions (of -size JS9.globalOpts.unremoveReg, current default is 100.) Each -time one or more regions is removed, they are stored as a single entry -on this stack. The UnremoveRegions call pops the last entry off -the stack and calls AddRegions. - -

Save regions from the current image to a file
-

-JS9.SaveRegions(filename, which, layer) -

-where: -

    -
  • filename: output file name -
  • which: which regions to save (default is "all") -
  • layer: which layer to save (default is "regions") -
-Save the current regions for the displayed image as a JS9 regions text -file. If filename is not specified, the file will be saved as -"js9.reg". If the string "dialogbox" is passed in the filename and no -other arguments are specified, the Save Regions dialogbox is displayed -instead of actually saving regions to a file. - -

-Don't forget that the file is saved by the browser, in whatever location -you have set up for downloads. - -

-If the which argument is not specified, it defaults to "all". You -can specify "selected" to return information about the selected regions, or -a tag value to save regions having that tag. - -

-If the layer argument is not specified, it defaults to -"regions", i.e., the usual regions layer. You can specify a different -layer, e.g., if you want to save a catalog layer as a region file -(since JS9.SaveCatalog() -will save the data in table format instead of as regions.) - -

-The layer argument can also be an object or a JSON-formatted string -containing these properties: -

    -
  • layer: the name of the layer -
  • format: output format: reg, csv, or svg -
  • type: backward compatible alias for format (deprecated) -
  • wcssys: wcs system to use (ICRS, FK5, galactic, physical, etc.) -
  • wcsunits: units for wcs output (sexagesimal, degrees, pixels) -
  • includejson: for reg files, include JSON object in output -
  • includecomments: for reg files, include comments in output -
  • includewcs: for csv files, include wcs keyword(s) in output -
-If the format is svg, an SVG/XML file will be saved -instead of the standard astronomical regions file. This SVG file can -be imported into programs such as Photoshop for further processing. - -

-If the format is csv, a text file will be saved with -the regions output as comma separated values: -

-    JS9.SaveRegions("foo", "all", {"format":"csv", "wcsunits":"degrees"})
-
-    circle,350.866288,58.811911,0.004099
-    box,350.897858,58.834207,0.011111,0.005556,20.000000
-
-Note that the region's wcs keyword is not passed by default in order -to make processing easier. You can force its inclusion by setting -the includewcs property to true. - -

-If the output format is set to svg (or csv), the default filename -will be "js9.svg" ("js9.csv") instead of "js9.reg". Similarly, if a -filename is specified that ends in ".svg" (or ".csv"), the format will be -set to svg (csv). - -

Change region tags for the specified image(s)
-

-JS9.ChangeRegionTags(which, addreg, removereg) -

-where: -

    -
  • which: which regions to process (default is "all") -
  • addreg: array or comma-delimited string listing regions to add -
  • removereg: array or comma-delimited string listing regions to remove -
-While region tags can be changed wholesale using the -JS9.ChangeRegions() routine, -this routine allows you to add and/or remove specific tags. The first -argument specifies which regions to change. The second argument is a -list of tags to add, while the third argument is a list of tags to -remove. In each case, the tags argument can be an array of tag strings -or a single string containing a comma-separated list of tags: -
-    JS9.ChangeRegionTags("selected", ["foo1", "foo2"], ["goo1", "goo2"]);
-    JS9.ChangeRegionTags("selected", "foo1,foo2", "goo1,goo2");
-
-Each of the above routines adds two "foo" tags and removes two "goo" -tags from the selected region(s). - -
Gather Regions into a Temporary Selection
-

-JS9.SelectRegions(regions) -

-where: -

    -
  • regions: which regions to select -
-JS9 has a rich mouse-based interface for selecting regions: a single -region is selected by clicking on it. A number of regions can be -gathered into a temporary selection by pressing the left mouse button and -dragging the mouse over the desired regions. To add to an -already-existing selection, shift-click the mouse on a region. - -

-A regions selection can be moved, resized, or retrieved as a -single unit. The selection is destroyed when the mouse is clicked -outside the selection, or when -JS9.UnselectRegions() -is called. - -

-This routine allows you to create a selection programmatically by -specifying which regions make up the selection. The first argument is -the regions selection. If not -specified, it defaults to "all" (since it doesn't make sense to -default to the already-selected regions, does it?). The result of the -call will be a selection of regions which can be moved as one unit. - -

-For example: -

-    # select all circles
-    JS9.SelectRegions("circle");
-
-    # select all circles not having tag 'foo2'
-    JS9.SelectRegions("circle && !foo2");
-
- -

-Regions in a selection are processed individually, -i.e. a regions selection will match -the regions inside a group. Thus for example, if you create a -selection containing circles, changing the color using the "circle" -specification will also affect the circles within the selection. You -can, of course, process only the regions inside a selection using -the selected specification. - -

-To create more long-lived groups (i.e., which are not destroyed -when you click the mouse outside the region), see -JS9.GroupRegions(). - -

Remove Regions From a Selection
-

-JS9.UnselectRegions(regions) -

-where: -

    -
  • regions: which regions to unselect -
-JS9 has a rich mouse-based interface for selecting regions: a single -region is selected by clicking on it. A number of regions can be -gathered into a group selection by pressing the left mouse button and -dragging the mouse over the desired regions. To add to an -already-existing selection, shift-click the mouse on a region. - -

-This routine allows you to remove one or more regions from a region -selection programmatically by specifying which regions to remove. -The first argument is the regions selection. -If not specified, or specified as "all" or "selected", the selection is undone. -Otherwise, the result of the call will be a new selection, not containing -the unselected regions, which can be moved as one unit. - -

-For example: -

-    # select all circles and ellipses
-    JS9.SelectRegions("circle || ellipse");
-
-    # unselect circles not having tag 'foo2'
-    JS9.UnselectRegions("circle && !foo2");
-
- -
Gather Regions into a Long-lived Group
-

-JS9.GroupRegions(regions, opts) -

-where: -

    -
  • regions: which regions to group -
  • opts: optional object containing grouping options -
-returns: -
    -
  • groupid: the group id associated with the newly created group -
- -

-A region group can be moved and resized as a single unit. To -first order, it is a long-lived form of a region selection. -The latter gets dissolved when you click the mouse outside the -selection, but a region group is dissolved only by -calling JS9.UngroupRegions(). - -

-This routine allows you to create a group by specifying the regions -which will compose it. The first argument is -the regions selection. If not -specified, it defaults to either "selected" or "all", depending on -whether a region selection currently exits. - -

-The optional opts argument contains the following properties: -

    -
  • groupid: the group id to use, if possible (default: "group_[n]") -
  • select: if false, the group is not selected upon creation -
-

-By default, the groupid will be the string "group_" followed by -an integer chosen so that the groupid is unique. You can supply your -own groupid, but if it already is associated with an existing group, -an integer value will be appended to make it unique. Also, by default -the newly created group will be "selected". You can pass -the select property with a value of false in order to -avoid selecting the group (e.g., if you are creating a number of -groups and don't want to see each of them selected in turn.) - -

-The returned groupid string can be used to select and process all the -regions in that group. Thus, for example, you can use the groupid to -change the color of all grouped regions: -

-    # make a group from all circles having the tag foo1
-    gid = JS9.GroupRegions("circle && foo1");
-
-    # change color of all regions in the group
-    JS9.ChangeRegions(gid, {"color":"red"});
-
-Furthermore, when creating a regions file via -JS9.SaveRegions(), the groupid will -be stored in each grouped region's JSON object, and will be used to -reconstitute the group when the file is reloaded. - -

-Note however, that unlike the temporary region selections, -regions in a group are not available individually, -i.e., a regions selection using a -non-groupid does not match regions inside a group. Thus, for -example, if you have created a group of circles, changing the color -using a "circle" specification does not affect circles within the group: -

-    # make a group from all circles having the tag foo1
-    gid = JS9.GroupRegions("circle && foo1");
-
-    # change color of circle regions, but NOT including those in any group
-    JS9.ChangeRegions("circle", {"color":"cyan"});
-
-    # change color of all regions in the group
-    JS9.ChangeRegions(gid, {"color":"red"});
-
- -

-Furthermore, a given region can only be part of one group at a -time. In the case where a region already is part of an existing group, -the globalOpts.regGroupConflict property determines how that region -is processed. The default is skip, meaning that the region is -silently skipped over when creating the new group. The alternative -is error, which will throw an error. - -

-To create a more temporary selection, see -JS9.SelectRegions(). - -

Dissolve a Group of Regions
-

-JS9.UngroupRegions(groupid, opts) -

-where: -

    -
  • groupid: group id of the group to dissolve -
  • opts: optional object containing ungrouping options -
- -

-This routine allows you to dissolve an existing group, so that the -regions contained therein once again become separate. -The first argument is the groupid, previously returned by the -JS9.GroupRegions() call. - -

-The optional opts argument contains the following properties: -

    -
  • select: newly separate regions in the group are "selected"? -
-By default, the ungrouped regions unobtrusively take their place among -other regions on the display. You can make them be selected by -passing the select: true property in opts. Doing this, for -example, would allow you to remove them easily with the Delete key. -

-For example: -

-    # group all circles and ellipses
-    gid = JS9.GroupRegions("circle || ellipse");
-
-    # ungroup so the regions are again separate
-    JS9.UngroupRegions(gid)
-
-    # change color of circle regions, including the newly ungrouped ones
-    JS9.ChangeRegions("circle", {"color":"cyan"});
-
- -
Toggle two region tags for the specified image(s)
-

-JS9.ToggleRegionTags(which, t1, t2) -

-where: -

    -
  • which: which regions to process (default is "all") -
  • t1: tag #1 to toggle -
  • t2: tag #2 to toggle -
-While region tags can be changed wholesale using the -JS9.ChangeRegions() routine, -this routine allows you to toggle between two tags, e.g., a source -region and background region, or between include and -exclude. For example: -
-    JS9.ToggleRegionTags("selected", "source", "background");
-
-will change a background region into a source region -or vice-versa, depending on the state of the region, while: -
-    JS9.ToggleRegionTags("selected", "include", "exclude");
-
-will toggle between include and exclude. - -
Load regions from a file into the current image
-

-JS9.LoadRegions(filename, opts) -

-where: -

    -
  • filename: input file name or URL -
  • opts: global region options for all regions -
-Load the specified regions file into the displayed image. The filename, -which must be specified, can be a local file (with absolute path or a -path relative to the displayed web page) or a URL. -

-The opts property specifies global options that are applied to -all regions in the file. They will be over-ridden by individual region -properties attached to a given region. For example, if a region file -named "foo.reg" contains the following regions: -

-    # Region file format: JS9 version 1.0
-    image
-    circle(512.0, 512.0, 40) {"color": "red"}
-    box(512.0, 512.0, 40, 40)
-    annulus(512.0, 512.0, 0.0, 3.0, 12.0, 18.0, 27.0)
-
-then a command such as: -
-    JS9.LoadRegions("foo.reg", {color: "blue"});
-
-will create a red circle, a blue box, and a blue annulus. -

-The opts object also can include an onload property containing a -function to be called when the load is complete. The image handle is passed -as an argument to this function. - -

-If the same region file is loaded more than once, behavior is -determined by the JS9.globalOpts.reloadRefreshReg property. -If set to true (the default), all previous regions loaded from -the file are removed (regardless of their current position, size, -etc.) If set to false, the new regions are added to the -previous ones. Site authors can change this property in js9prefs.js, -while users can change this via the Global tab of the -Preferences plugin. - -


- -

Working with Shape Layers

- -

-JS9 supports individual layers for drawing 2D graphics. The ubiquitous -Regions layer is a special case of a shape -layer, created automatically by JS9. The Catalog plugin creates a -separate layer for each catalog. You can define your own shape layer -using the NewShapeLayer() call and then add geometric shapes to it. - -

-One of the most important aspects of using shapes is the ability to assign -different characteristics to shapes and then make selections based on -these characteristics. The -JS9.ChangeShapes(), -JS9.GetShapes(), -JS9.RemoveShapes(), -and -JS9.SelectShapes() -calls all take a -regions selection -as the second argument, which functions identically to the way in which -Regions selections are made. - -

Create a new shape layer
-

-lid = JS9.NewShapeLayer(layer, opts) -

-where: -

    -
  • layer: name of the layer to create -
  • opts: default options for this layer -
-returns: -
    -
  • lid: layer id -
-This routine creates a new named shape layer. You can then, add, change, -and remove shapes in this layer using the routines below. The catalogs -displayed by the Catalog plugin are examples of separate shape layers. -

-The opts parameter allows you to specify default options for -the new layer. Although this argument is optional, you generally will -want to set default values for various properties utilized by your -new shape layer. See JS9.Regions.opts in js9.js for example of the default -options for the regions layer. This is a good set of options to pass if -you want region-like behavior in your new layer. -

-The JS9.Catalogs.opts object is also supplied as a possible baseline -object for new shape layers. It differs from the JS9.Regions.opts in a -few important ways: -

    -
  • it makes the new layer non-interactive: individual shapes cannot be -moved, rotated, resized, or deleted, nor do they respond to events -
  • it sets the updateWCS property to false, so the relatively expensive operation of updating the WCS string is not performed when an object is modified -
  • it does not sort overlapping shapes so that the smallest is on top when a shape is moved -
  • it does not define regions-specific processing (e.g., double-click to edit a region parameters) -
-

-Starting with the JS9.Catalogs.opts object as a default, you can make -the new layer interactive in a few different ways. The first way is to -set the movable property in the opts object to true. -This will permit individual shapes to be moved, rotated, resized and -deleted. Shapes also will be movable and resizable as a group. -

-The second way is to supply one or more event callbacks as properties -to the opts object: -

    -
  • onmousedown: function(im, xreg, evt); -
  • onmouseup: function(im, xreg, evt); -
  • onmousemove: function(im, xreg, evt); -
  • onmouseover: function(im, xreg, evt); -
  • onmouseout: function(im, xreg, evt); -
-When the associated mouse event occurs on a shape, these functions -will be called with the following arguments: -
    -
  • im: the image handle for the currently displayed image -
  • xreg: the shape object, as described in JS9.GetShapes() -
  • evt: the original event object -
-For example, to define mouseover and mousedown callbacks: -
-    opts.onmouseover = function(im, xreg, evt){
-        console.log("mouseover: %s %s", im.id, xreg.data.tag);
-    };
-    opts.onmousedown = function(im, xreg, evt){
-        console.log("mousedown: %s %s", im.id, xreg.data.tag);
-
-Note that the shapes are still not movable unless you also set -the movable property. -

-In addition to firing callbacks on events for individual shapes, you -can set the ongroupcreate property in the opts object to a -function that will fire when two or more objects are selected into a -group (which is done using the Command key on a Mac, -or Control key everywhere else): -

    -
  • ongroupcreate: function(im, xreg, id); -
-The function will be called with the following arguments: -
    -
  • id: group id -
  • im: the image handle for the currently displayed image -
  • xreg: an array of shape objects within the group -
-Note that an array of xreg objects is passed in this case instead of -the single "current" object passed in the other event callbacks. -For example: -
-    opts.ongroupcreate = function(id, im, xreg){
-        var i, nshape, xcen, ycen;
-        var xtot=0, ytot=0;
-        nshape = xreg.length;
-        console.log("group: %s", id);
-        for(i=0; i<nshape; i++){
-          xtot += xreg[i].x; ytot += xreg[i].y;
-        }
-        xcen = xtot / nshape; ycen = ytot / nshape;
-        console.log("average pos for %s objects: %s,%s", nshape, xcen, ycen);
-    }
-
-

-The final way to make a shape layer interactive is to specify -a tooltip to display when hovering over objects in this shape -layer. This is done by assigning a tooltip format string to -the tooltip property of the opts object. This string can -contain HTML directives, and it also can contain references to -properties in the im, xreg, and evt objects. When the mouse hovers -over an object, a tooltip string is generated by macro-expanding the -values for these properties. The generated tooltip string is displayed -as the inner HTML of the tooltip. When the mouse leaves the object, -the tooltip is hidden. -

-For example, consider the following tooltip string: -

-    opts.tooltip = "<b>id: $im.id</b><br>pos: $xreg.x $xreg.y<br><i>$xreg.data.tag</i>";
-
-Note how properties of the im and xreg objects are -specified with a "$" prefix. When the mouse hovers over an object, the -generated tooltip will display current image id in bold, followed by -that object's x,y pixel position, followed by a user tag -property passed in the data object when the shape was added. -As a convenience, $data can be used as a shorthand for $xreg.data. - -
Show or hide the specified shape layer
-

-JS9.ShowShapeLayer(layer, mode) -

-where: -

    -
  • layer: name of layer -
  • mode: true (show layer) or false (hide layer) -
-Shape layers can be hidden from display. This could be useful, for -example, if you have several catalogs loaded into a display and -want to view one at a time. -

-If mode is true, a previously hidden shape layer will be displayed. If -mode is false, a displayed shape layer will be hidden. If the -mode argument is not supplied, the current mode is returned. - -

Toggle display of the active shape layers
-

-JS9.ToggleShapeLayers() -

-While JS9.ShowShapeLayer() allows you to -display or hide a single shape layer, this routine will toggle display -of all active layers in the current image. An active layer is one that -has not been turned off using the Shape Layers plugin or -JS9.ShowShapeLayer(). - -

-The routine remembers which layers were active at the moment when -layers are hidden and restores only those layers in the next toggle. -Thus, if you have two layers, "regions" and "catalog1", and the -"catalog1" layer has previously been turned off, calling this routine -repeatedly will turn on and off the "regions" layer only. - -

Make the specified shape layer the active layer
-

-JS9.ActiveShapeLayer(layer) -

-where: -

    -
  • layer: name of layer -
-returns: -
    -
  • active: the active shape layer (if no args are specified) -
- -For a given image, one shape layer at a time is active, -responding to mouse and touch events. Ordinarily, a shape layer -becomes the active layer when it is first created and shapes are -added to it. Thus, the first time you create a region, the regions -layer becomes active. If you then load a catalog into a catalog layer, -that layer becomes active. - -

-If no arguments are supplied, the JS9.ActiveShapeLayer() -routine returns the currently active layer. Specify the name of a -layer as the first argument to make it active. Note that the specified -layer must be visible. - -

-This routine forms the basis for the Shape Layer plugin, which -provides a graphical way to make a layer active (by moving it to the -top of the layer stack.) - -

Add one or more shapes to the specified layer
-

-JS9.AddShapes(layer, sarr, opts) -

-where: -

    -
  • layer: name of layer -
  • sarr: a shape string, shape object, or an array of shape objects -
  • opts: global values to apply to each created shape -
-returns: -
    -
  • id: id of last shape created -
-The sarr argument can be a shape ("annulus", "box", -"circle", "cross", "ellipse", "point", "polygon", "text"), a single shape -object, or an array of shape objects. Shape objects contain one or -more properties, of which the most important are: -
    -
  • shape: "annulus", "box", "circle", "cross", "ellipse", "point", "polygon", "text" [REQUIRED] -
  • x: image x position -
  • y: image y position -
  • deltax: increment from current image x position -
  • deltay: increment from current image y position -
  • tags: comma-separated list of tag strings or array of tag strings -
  • radii: array of radii for annulus shape -
  • width: width for box or cross shape -
  • height: height for box or cross shape -
  • radius: radius value for circle shape -
  • r1: x radius for ellipse shape (misnomer noted) -
  • r2: y radius for ellipse shape (misnomer noted) -
  • pts: array of objects containing x and y positions, for polygons -
  • points: array of objects containing x and y offsets from the specified center, for polygons -
  • angle: angle in degrees for box, ellipse, cross shapes -
  • color: shape color (string name or #rrggbb syntax) -
  • text: text associated with text shape -
  • data: this property can be an object, string, number, -etc. and will be carried along with the shape, and returned as a -property by the -JS9.GetShapes() call. -
-Other available properties include: -
    -
  • changeable: if false, region cannot be moved, resized, rotated -
  • locked: 'opposite alias' of changeable -
  • movable: if false, region cannot be moved -
  • resizable: if false, region cannot be resized or rotated -
  • rotatable: if false, region cannot be rotated -
  • removable: if false, region cannot be removed -
  • zoomable: if false, region is not resized when image is zoomed -
  • selectable: if false, region can't be selected (no GUI-based changes) -
  • lockMovementX: if true, region cannot be moved in the x direction -
  • lockMovementY: if true, region cannot be moved in the y direction -
  • lockScalingX: if true, region cannot be resized in the x direction -
  • lockScalingY: if true, region cannot be resized in the y direction -
  • lockRotation: if true, region cannot be rotated -
  • fontFamily: font parameter for text region -
  • fontSize: font parameter for text region -
  • fontStyle: font parameter for text region -
  • fontWeight: font parameter for text region -
- -
Remove one or more shapes from the specified shape layer
-

-JS9.RemoveShapes(layer, shapes) -

-where: -

    -
  • layer: name of layer -
  • shapes: which shapes to remove -
-The selected shapes are removed from the specified layer. -The second argument is the regions -selection. If not specified, it defaults to "all". - -

-If JS9.globalOpts.resetEmptyShapeId is set to true (default -is false), the shape id counter will be reset to 0 whenever all the -shapes are removed. - -

Get information about one or more shapes in the specified shape layer
-

-JS9.GetShapes(layer, shapes) -

-where: -

    -
  • layer: name of layer -
  • shapes: which shapes to retrieve -
-returns: -
    -
  • sarr: array of shape objects -
-

-Each returned shape object contains the following properties: -

    -
  • id: numeric region id (assigned by JS9 automatically) -
  • mode: "add", "remove", or "change" -
  • shape: region shape ("annulus", "box", "circle", "cross", "ellipse", -"point", "polygon", "text") -
  • tags: comma delimited list of region tags (e.g., "source", "include") -
  • color: region color -
  • x,y: image coordinates of region -
  • size: object containing width and height for box, cross region -
  • radius: radius value for circle region -
  • radii: array of radii for annulus region -
  • eradius: object containing x and y radii for ellipses -
  • pts: array of objects containing x and y positions, for polygons -
  • angle: angle in degrees for box, ellipse, cross -
  • data: data property passed in options object when this shape was created. -
- -
Change one or more shapes in the specified layer
-

-JS9.ChangeShapes(layer, shapes, opts) -

-where: -

    -
  • layer: name of layer -
  • shapes: which shapes to change -
  • opts: object containing options to change in each shape -
-Change one or more shapes in the specified layer. The opts object can -contain the parameters described in the -JS9.AddShapes() -section. However, you cannot (yet) -change the shape itself (e.g., from "box" to "circle".) - -

-The second argument is the regions -selection. If not specified, it defaults to "all". - -

Copy a shape layer to another image
-

-JS9.CopyShapes(to, layer) -

-where: -

    -
  • to: image id to which to copy shapes -
  • layer: shape layer to copy -
-Copy the shapes in a shape layer to a different image. If to is -"all", then the shapes are copied to all images. -

-All shapes in the shape layer are copied to the new image. - -

Group Shapes into a Selection
-

-JS9.SelectShapes(layer, shapes) -

-where: -

    -
  • layer: shape layer -
  • shapes: which shapes to select -
-JS9 has a rich mouse-based interface for selecting shapes: a single -shape is selected by clicking on it. A number of shapes can be -gathered into a group selection by pressing the left mouse button and -dragging the mouse over the desired shapes. To add to an -already-existing selection, shift-click the mouse on a shape. - -

-A selected group of regions can be moved, resized, or retrieved as a -single unit. The selected group is destroyed when the mouse is clicked -outside the selection, or when -JS9.UnselectShapes() -is called. - -

-This routine allows you to create a group selection programmatically by -specifying which shapes make up the selection. The first argument is the -shape layer. The second argument is the regions -selection. If not specified, it defaults to "all" (since it -doesn't make sense to default to the already-selected shapes, does it?). -The result of the call will be a selected group which can be moved as one unit. - -

Remove Shapes From a Selection
-

-JS9.UnselectShapes(layer, shapes) -

-where: -

    -
  • layer: shape layer -
  • shapes: which shapes to unselect -
-JS9 has a rich mouse-based interface for selecting shapes: a single -shape is selected by clicking on it. A number of shapes can be -gathered into a selection by pressing the left mouse button and -dragging the mouse over the desired shapes. To add to an -already-existing selection, shift-click the mouse on a shape. - -

-This routine allows you to remove one or more shapes from a group -selection programmatically by specifying which shapes to remove. The -first argument is the shape layer. The second argument is -the regions selection. If not -specified, or specified as "all" or "selected", the selection is -undone. The result of the call will be a new selected group, not -containing the unselected shapes, which can be moved as one unit. - -

Gather Shapes into a Long-lived Group
-

-JS9.GroupShapes(layer, shapes, opts) -

-where: -

    -
  • layer: shape layer -
  • shapes: which shapes to group -
  • opts: optional object containing grouping options -
-returns: -
    -
  • groupid: the group id associated with the newly created group -
- -

-A shape group can be moved and resized as a single unit. To -first order, it is a long-lived form of a region selection. -The latter gets dissolved when you click the mouse outside the -selection, but a shape group is dissolved only by -calling JS9.UngroupShapes(). - -

-This routine allows you to create a group by specifying the shapes -which will compose it. The first argument is the shape layer. The -second argument is the regions selection. -If not specified, it defaults to either "selected" or "all", -depending on whether a shape selection currently exits. - -

-The optional opts argument contains the following properties: -

    -
  • groupid: the group id to use, if possible (default: "group_[n]") -
  • select: if false, the group is not selected upon creation -
-

-By default, the groupid will be the string "group_" followed by -an integer chosen so that the groupid is unique. You can supply your -own groupid, but if it already is associated with an existing group, -an integer value will be appended to make it unique. Also, by default -the newly created group will be "selected". You can pass -the select property with a value of false in order to -avoid selecting the group (e.g., if you are creating a number of -groups and don't want to see each of them selected in turn.) - -

-The returned groupid string can be used to select and process all the -shapes in that group. Thus, for example, you can use the groupid to -change the color of all grouped shapes: -

-    # make a group from all circles having the tag foo1
-    gid = JS9.GroupShapes("myregions", "circle && foo1");
-
-    # change color of all shapes in the group
-    JS9.ChangeShapes("myregions", gid, {"color":"red"});
-
- -

-Note however, that unlike the temporary shape selections, -shapes in a group are not available individually, -i.e., a shapes selection using a -non-groupid does not match shapes inside a group. Thus, for -example, if you have created a group of circles, changing the color -using a "circle" specification does not affect circles within the group: -

-    # make a group from all circles having the tag foo1
-    gid = JS9.GroupShapes("myregions", "circle && foo1");
-
-    # change color of circle shapes, but NOT including those in any group
-    JS9.ChangeShapes("myregions", "circle", {"color":"cyan"});
-
-    # change color of all shapes in the group
-    JS9.ChangeShapes("myregions", gid, {"color":"red"});
-
- -

-Furthermore, a given shape can only be part of one group at a -time. In the case where a shape already is part of an existing group, -the globalOpts.regGroupConflict property determines how that shape -is processed. The default is skip, meaning that the shape is -silently skipped over when creating the new group. The alternative -is error, which will throw an error. - -

-To create a more temporary selection, see -JS9.SelectShapes(). - -

Dissolve a Group of Shapes
-

-JS9.UngroupShapes(layer, groupid, opts) -

-where: -

    -
  • layer: shape layer -
  • groupid: group id of the group to dissolve -
  • opts: optional object containing ungrouping options -
- -

-This routine allows you to dissolve an existing group, so that the -shapes contained therein once again become separate. The first -argument is the shape layer. The second argument is -the groupid, previously returned by the -JS9.GroupShapes() call. - -

-The optional opts argument contains the following properties: -

    -
  • select: newly separate shapes in the group are "selected"? -
-By default, the ungrouped shapes unobtrusively take their place among -other shapes on the display. You can make them be selected by -passing the select: true property in opts. Doing this, for -example, would allow you to remove them easily with the Delete key. - -

-For example: -

-    # group all circles and ellipses
-    gid = JS9.GroupShapes("myregions", "circle || ellipse");
-
-    # ungroup so the shapes are again separate
-    JS9.UngroupShapes("myregions", gid)
-
-    # change color of circle shapes, including the newly ungrouped ones
-    JS9.ChangeShapes("myregions", "circle", {"color":"cyan"});
-
- -
Load an astronomical catalog
-

-JS9.LoadCatalog(layer, table, opts) -

-where: -

    -
  • layer: name of shape layer into which to load the catalog -
  • table: string or blob containing the catalog table, or file name -
  • opts: catalog options -
-Astronomical catalogs are a special type of JS9 shape layer, in which -the shapes have been generated from a tab-delimited text file of -columns, including two columns that contain RA and Dec values. An -astronomical catalog can have a pre-amble of comments, which, by -default, have a '#' character in the first column. - -

-Two examples of catalog files are shown below: -

-  ra        	dec        	magj	magh	magk
-  -----------	------------	------	----	----
-  23:22:56.003	58:44:45.429	15.612	15.103	14.9
-  23:22:56.230	58:45:32.011	13.723	13.174	12.981
-  23:22:56.319	58:45:08.954	14.212	13.119	12.723
-  ...
-
-  #
-  #   VizieR Astronomical Server vizier.u-strasbg.fr
-  # ...
-  #Coosys	J2000:	eq_FK5 J2000
-  # ...
-  #Title: 2MASS All-Sky Catalog of Point Sources (Cutri+ 2003)
-  # ...
-  #Column	_RAJ2000	(A12)		[ucd=pos.eq.ra]
-  #Column	_DEJ2000	(A12)		[ucd=pos.eq.dec]
-  #Column	RAJ2000	(F10.6)		[ucd=pos.eq.ra;meta.main]
-  #Column	DEJ2000	(F10.6)		[ucd=pos.eq.dec;meta.main]
-  #Column	2MASS	(a17)		[ucd=meta.id;meta.main]
-  # ...
-  #Column	Aflg	(I1)		[ucd=meta.code]
-  _RAJ2000	_DEJ2000	RAJ2000	DEJ2000	2MASS	Jmag	e_Jmag	Hmag	  e_Hmag	Kmag	e_Kmag	Qflg	Rflg	Bflg	Cflg	Xflg	Aflg
-  ------------	------------	----------	----------	-----------------	------	------	------	------	------	------	---	---	---	---	-	-
-  23 22 56.002	+58 44 45.43	350.733342	+58.745953	23225600+5844454 	15.612	 0.064	15.103	 0.078	14.900	 0.121	AAB	222	111	ccc	0	0
-  23 22 59.647	+58 44 56.84	350.748531	+58.749123	23225964+5844568 	15.580	 0.063	14.922	 0.072	14.506	 0.079	AAA	222	111	c00	0	0
-  23 22 56.981	+58 44 44.61	350.737422	+58.745724	23225698+5844446 	14.920	 0.049	14.292	 0.049	14.002	 0.055	AAA	222	111	ccc	0	0
-  ...
-
-Notice that both files have a tab-delimited header, followed by a -tab-delimited line of dashes, followed by tab-delimited data rows. This file -format is sometimes called "tsv" or "tab-separated values". A very useful -astronomical package for manipulating tables is -Starbase, -written by John Roll. - -

-The JS9.LoadCatalog() routine will read a file in this format, -processing the data rows by converting the RA and Dec values into -image position values that will be displayed as shapes in a new -catalog layer. - -

-The first argument to the JS9.LoadCatalog() routine is the name -of the shape layer that will contain the objects in the catalog. Specifying -the name of an existing layer is valid: previous shapes in that layer will -be removed. - -

-The second argument is either a blob or a string containing the table -data described above. Blobs are the result of loading a local file -into the browser (e.g., the load catalog menu option), while -strings result from a remote XHR call (e.g., the Archives and -Catalogs plugin.) Alternatively, the second string argument can -be a file name or URL to load. File names are distinguished from -strings containing a table in that the latter must contain at least one -tab. - -

-The third argument is an optional object used to specify parameters, including: -

    -
  • xcol: name of the RA column in the table (default is a heuristic, see below) -
  • ycol: name of the Dec column in the table (default is a heuristic, see below) -
  • wcssys: WCS system (FK4, FK5, ICRS, galactic, ecliptic) (default is from globalOpts) -
  • shape: shape of catalog object (default is from globalOpts) -
  • color: color of catalog shapes (default is from globalOpts) -
  • width: width of box catalog shapes (default is from globalOpts) -
  • height: height of box catalog shapes (default is from globalOpts) -
  • radius: radius of circle catalog shapes (default is from globalOpts) -
  • r1: r1 of ellipse catalog shapes (default is from globalOpts) -
  • r2: r2 of ellipse catalog shapes (default is from globalOpts) -
  • save: save the catalog properties for each generated shape (default is from globalOpts) -
  • tooltip: format of tooltip string to display for each object (default is from globalOpts) -
  • skip: comment character in table file (default is from globalOpts) -
-Most of these properties have default values that are stored in -the JS9.globalOpts.catalogs object: manipulate that object as -needed. The values listed above also can be changed by users via -the Catalog tab in the Preferences plugin. - -

-The opts object also can include an onload property containing a -function to be called when the load is complete. The image handle is passed -as an argument to this function. - -

-Note the second (Vizier) example table above does not actually have a columns -called "RA" and "Dec". Instead, it has "_RAJ2000", "_DEJ2000", "RAJ2000", -and "DEJ2000" columns. In order to pick RA and Dec column, a heuristic is used -based on the values contained in the JS9.globalOpts.catalogs.ras and -JS9.globalOpts.catalogs.decs arrays: -

    -
  • the opts.xcol, if defined, specifies the RA column (similarly for opts.ycol and the Dec column) -
  • otherwise try to match exactly the catalog header against all the array elements in JS9.globalOpts.catalogs.ras to get the RA column (same for catalogs.decs) -
  • if no exact match, try a case-insensitive match of the catalog columns against a regular expression that begins with the first array element in JS9.globalOpts.catalogs.ras (e.g., "RA*") -
  • if no approximate match, try a case-insensitive match of the catalog columns against a regular expression containing the first array element in JS9.globalOpts.catalogs.ras (e.g., "*RA*") -
-The default global JS9.globalOpts.catalogs.ras contains: -
-  ras:  ["RA", "_RAJ2000", "RAJ2000"]
-  decs: ["Dec", "_DEJ2000", "DEJ2000"]
-
-These defaults make it easy to process simple catalogs and Vizier -catalogs. - -

-Once the RA and Dec columns are specified, the RA and Dec values from -each row are converted into image positions, and JS9 shapes are -generated to be displayed in the new catalog layer. The WCS system -used to convert RA and Dec into image coordinates can be specified -using the opts.wcssys or JS9.globalOpts.catalogs.wcssys -properties. - -

-The RA and Dec of the catalog object are always saved in the data -object of each generated shape, for use in the tooltip string. In -addition, if opts.save (or the default: JS9.globalOpts.catalogs.save) -property is not false, all of the catalog object properties will also be -save in the data object for use in the tooltip string, e.g.: -

-  opts.tooltip = "$xreg.data.ra $xreg.data.dec $xreg.data.Qflg $xreg.data.Rflg"
-
-in the above VizieR example. Caveat: any "." (dot) in any catalog property -name will be converted to "_" (underscore) automatically. For a more detailed -discussion of tooltips, please see -JS9.NewShapeLayer(). - -

-When catalog layer has been created, you can use the Shape Layers -plugin to toggle its visibility and also to change its position in the layer -stack. - -

Save an astronomical catalog to a file
-

-JS9.SaveCatalog(filename, which) -

-where: -

    -
  • filename: output file name -
  • which: layer containing catalog objects to save -
-Save the specified catalog-containing layer as a text file. If filename is not -specified, the file will be saved as [layer].cat. - -

-Don't forget that the file is saved by the browser, in whatever location -you have set up for downloads. - -

-If the which argument is not specified, the catalog associated -with the current active layer will be saved. In either case, the -layer to save must actually be a catalog created from a tab-delimited -file (or URL) of catalog objects (not, for example, the regions layer.) - -


- -

Mouse/Touch Gestures

- -

-JS9 supports the following configurable mouse and touch actions: -

    -
  • mouse movement with no buttons pressed -
  • mouse movement with one button pressed -
  • mouse movement with two buttons pressed -
  • touch with one finger -
  • touch with two fingers -
  • touch with three fingers -
-The initial actions are defined by the JS9.globalOpts.mouseActions -and JS9.globalOpts.touchActions arrays. In addition, the -JS9.globalOpts.mousetouchZoom property specifies whether a mouse wheel -or touch/pinch will zoom the image. The default actions are: -
    -
  • mouseActions: ["display value/position", "change contrast/bias", "pan the image"] -
  • touchActions: ["display value/position", "change contrast/bias", "pan the image"] -
  • mousetouchZoom: false -
-where the array elements map to an increasing numbers of -buttons/fingers. You can change the default actions of the elements -in either array in your js9prefs.js file. For example, to make pan -and zoom the default one-touch and pinch actions respectively: -
    -
  • touchActions: ["pan the image", "display value/position", "change contrast/bias"] -
  • mousetouchZoom: true -
-As usual, the defaults in js9prefs.js are used by all JS9 displays in -a web page. - -

-Users can change the action assignments using the MouseTouch -plugin, which displays the current mapping between mouse/touch gesture -and its action. Simply drag and drop an action to a different gesture -in order to change the mapping. You also can toggle the scroll/pinch -to zoom capability by clicking its button. - -

-Web page developers can extend the available mouse and touch actions -beyond the defaults contained in -the Mouse Touch plugin. To -add a new action, first write a function with the following calling sequence: -

-    gestureFunc(im, ipos, evt)
-
-where: -
    -
  • im: image handle -
  • ipos: image position object containing 1-indexed x and y image -coordinate values -
  • evt: a JavaScript or jQuery event -
-Add this new function to the JS9.MouseTouchActions array, using a -descriptive name as its array index, e.g.: -
-    JS9.MouseTouch.Actions["all contrast/bias"] = function(im, ipos, evt){
-      var i, myim;
-      for(i=0; i<JS9.displays.length; i++){
-        myim = JS9.displays[i].image;
-        if( myim ){
-          JS9.MouseTouch.Actions["change contrast/bias"](myim, ipos, evt);
-        }
-      }
-    };
-
-At this point, the Mouse Touch Plugin will display the new -function in its list of available actions. Users can move it into one -of the defined gestures to activate it. - -

-Of course, you can add the new action to the JS9.globalOpts.mouseActions -and/or JS9.globalOpts.touchActions arrays to make it active immediately: -

-    JS9.globalOpts.mouseActions[1] = "all contrast/bias";
-    JS9.globalOpts.touchActions[1] = "all contrast/bias";
-
-Here, we have replaced the one-button mouse move and two-button touch -move actions (whose defaults are to "change contrast/bias") with our -new action. - -


- -

Server-side Analysis

- -
Get server-side analysis task definitions
-

-JS9.GetAnalysis() -

-The JS9.GetAnalysis() routine returns an array of analysis task -definitions, each containing the following information: -

    -
  • name: a short identifier string (typically one word) -
  • title: a longer string that will be displayed in the Analysis menu -
  • files: a rule that will be matched against to determine -whether this task is available for the current image -
  • purl: a URL pointing to a web page containing a user parameter form -
  • action: the command to execute on the server side -
  • rtype: a return type, which can be text, plot, fits, regions, catalog, alert, or none -
  • hidden: if true, the analysis task is not shown in the Analysis menu -
-Not every property listed above will be present in every task definition -(e.g., purl is only present when there is a parameter form.) -Also note that hidden tasks are not returned by this call. - -
Run a server-side analysis task
-

-JS9.RunAnalysis(name, parr, func) -

-where: -

    -
  • name: name of analysis tool -
  • parr: optional array of macro-expansion options for command line -
  • func: optional routine to call when analysis is completed on server -
-The JS9.RunAnalysis() routine is used to execute a server-side -analysis task and return the results for further processing within the -web page. -The optional parr array of parameters is passed to the JS9 -analysis macro expander so that values can be added to the command -line. The array is in jQuery name/value serialized object format, -which is described here: -
-    http://api.jquery.com/serializeArray/
-
-

-The func() routine is a callback function to process the returned -results from the analysis task. The calling sequence is: -

-    func(stdout, stderr, errcode, aobj)
-
-where: -
    -
  • stdout: a string containing the standard output from the task -
  • stderr: a string containing the standard error from the task -
  • errcode: error code value from the task or 0 -
  • aobj: the analysis object from the js9Analysis.json file, - containing, among other things, the important rtype: - "text" or "plot" -
-Typically, you would check stderr string first and issue an error -message if there is an error. Otherwise, the stdout string can be -processed based on the return type (rtype) property of the output -(e.g., "text" or "plot".) For plotting, you can use flot -functionality already loaded into JS9, or you can use your own chosen -plotting package. -

-If no func callback is specified, the default processing will -display "text" in a new light window. If the return type is "plot", -the results are assumed to be in flot format and will be plotted. -

-Instead of passing a callback function each time, you can set the global -property JS9.globalOpts.analysisFunc to a function having the -same signature: -

-    func(stdout, stderr, errcode, aobj)
-
-The specified function will be called for each execution -of JS9.RunAnalysis -

-In addition, you can change the target of the analysis results display -from a light window to your own div element by setting the global -property JS9.globalOpts.analysisDiv to the id of your new -target div. The div must have CSS height and width properties if you -are going to plot results. - -

Run a server-side analysis task, utilizing -parameters in a form
-

-JS9.SubmitAnalysis(el, name, func) -

-where: -

    -
  • el: form element (unused at present) -
  • name: name of analysis tool -
  • func: optional routine to call when analysis is completed on server -
-The JS9.SubmitAnalysis() routine is used to run an analysis -task with input parameters from a form. Typically used as -the Run button action in a form, it automatically serializes -the form values and passes them to the JS9 analysis macro expander so -that these values can be integrated into the analysis command line. -See js9analysis.html for a simple example. -

-The func callback and global options are the same as -for -JS9.RunAnalysis() -above. - -


- -

Working with Displays

- -
Display the Next (or Previous) Image
-

-JS9DisplayNextImage(n) -

-where: -

    -
  • n: number of images beyond (or prior to) the one currently displayed -
-The JS9.DisplayNextImage() routine displays the nth image in -the display's image list beyond the currently displayed image. The -default value for n is 1. You can supply a negative number to -display an image prior to the current one in the display's image list. - -
Create a Mosaic Image
-

-JS9.CreateMosaic(which, opts) -

-where: -

    -
  • which: which images to use in the mosaic -
  • opts: mosaic options -
- -The JS9.CreateMosaic() creates a mosaic image from the -specified (previously-loaded) FITS images using the -mProjectPP -and -mAdd -programs from the -Montage software suite. -These Montage programs have been compiled into JS9 using -Emscripten. - -

-Because the browser environment is memory-limited, there are some -restrictions on generating mosaics in JS9. The FITS files must be -well-behaved, i.e., they must have WCS projections which can be -approximated by tangent-plane projections (TAN, SIN, ZEA, STG, ARC.) -This precludes creating mosaics from images covering large portions of -the sky. For large sky areas, please use Montage itself on your desktop -to create a mosaic. A simplified js9mosaic script is included in -the JS9 distribution or, for more control, use the Montage programs -directly. Of course, in either case, you must install Montage. - -

-The which parameter determine which images are used in the mosaic: -

    -
  • "current" or null: the current image in this display -
  • "all": all images in this display -
  • im: the image id or image handle of an image from any display -
  • [im1, im2, ...]: an array of image ids or handles from any display -
-In general, use "current" (or null) if you have loaded a multi-extension -FITS mosaic (e.g., a CFHT FITS file) into JS9. Use "all" if you have loaded -several FITS files into JS9 and want to create a mosaic. - -

-In order to keep the size of the resulting mosaic within memory -limits, JS9 reduces the size of each image before adding them all -together The options parameter determines how the reduction is -performed: -

    -
  • dim: size of mosaic (def: max of JS9.globalOpts.image.[xdim,ydim]) -
  • reduce: image size reduction technique: "js9" (def) or "shrink" -
  • verbose: if true, processing output is sent to the javascript console -
-The "dim" parameter is a target size: the larger of the resulting -mosaic dimensions will be approximately this value, depending on how -Montage processes the images. The "reduce" technique either runs -internal JS9 image sectioning code (to produce smaller internal -images, each of which are reprojected and added together) or runs the -Montage mShrinkHdr code (which reprojects the full images into smaller -files.) The former seems to be faster than the latter in most -cases. The "verbose" parameter will display output on the JavaScript -console to let you know that the CreateMosaic() call is running properly. - -

-The resulting mosaic will be loaded into the specified JS9 display as -a separate image. Because the mosaic is separate from the original -image(s), you can view each of the latter individually (or view each -image extension of a single image using the Extensions plugin.) -Internal analysis can be performed on the mosaic (e.g., ImExam functions) -but, of course, no external analysis tasks will be available. - -

Lookup a JS9 display
-

-dobj = JS9.LookupDisplay(dname, mustExist) -

-where: -

    -
  • dname: name of JS9 display to look up -
  • mustExist: whether to throw error if a dname display does not exist -
-returns: -
    -
  • dobj: the JS9 display object -
-The JS9.LookupDisplay() routine returns the display object associated -with the specified dname parameter. If no dname is specified, -the first available display is returned. -

-If dname is specified but does not exist, an error is thrown unless -the mustExist parameter is explicitly set to false (i.e., the default -is that the id must exist.) - -

Resize the JS9 Display
-

-JS9.ResizeDisplay(dname, width, height, opts) -

-where: -

    -
  • dname: optional name of JS9 display to resize -
  • width: new width of the display in HTML pixels (or "full" or "reset") -
  • height: new height of the display in HTML pixels -
  • opts: optional object containing resize parameters -
-You can resize the JS9 display by supplying new width and -height parameters. The div on the web page will be resized and the -image will be re-centered in the new display. If the display size has -been increased, more of the image will be displayed as needed (up to -the new size of the display.) For example, if the original display was -512x512 and you increase it to 1024x1024, a 1024x1024 image will now -be displayed in its entirety. - -

-If the first argument is full, the display is resized to match -the browser window.innerWidth and window.innerHeight variables, which -are the width and height (in pixels) of the browser window -viewport. You can then scroll the window so that the image fills the -entire browser window. Alternatively, if the first argument -is reset, the display is resized to match its original size. - -

-The opts object can contain the following properties: -

    -
  • resizeMenubar: change the width of the menubar as well -
-The default for resizeMenubar is true, so you only need -to pass this property if you do not want to perform the resize. -

-If no arguments are passed to this routine, it returns an object -containing the current display width and height. Otherwise, the -display object is returned. -

-You can supply a display name as the first argument, or the display object: -

-    JS9.ResizeDisplay("myJS9", 350, 400);
-
-or: -
-    JS9.ResizeDisplay(350, 400, {display: "myJS9"});
-
- -
Move an image to a new JS9 display
-

-JS9.MoveToDisplay(dname) -

-where: -

    -
  • dname: name of JS9 display to which the image will be moved -
-The JS9.MoveToDisplay() routine moves the current image to the -specified display: -
-    JS9.MoveToDisplay("myJS9", {display: "JS9"});
-
-will move the current image displayed in the "JS9" display window to -the "myJS9" window. -

-Note that the new JS9 display must already exist. New displays can be -created with the -JS9.LoadWindow() -public access routine or -the File:new JS9 light window menu option. - -

Gather other images to this JS9 Display
-

-JS9.GatherDisplay(dname, opts) -

-where: -

    -
  • dname: name of JS9 display to which the images will be gathered -
  • opts: optional object -
-

-This routine move all images in other displays to this display. -You can supply a display name or the display object: -

-    JS9.GatherDisplay("myJS9");
-
-or: -
-    JS9.GatherDisplay({display: "myJS9"});
-
-You can supply an opts object containing the properties: -
    -
  • images: array of image handles (or indexes into JS9.images array) to gather -
- -
Separate images in this JS9 Display into new displays
-

-JS9.SeparateDisplay(dname, opts) -

-where: -

    -
  • dname: name of JS9 display from which the images will be separated -
  • opts: optional object for layout properties -
-This routine moves each image in the specified display to a new display. -You can supply a display name or the display object: -
-    JS9.SeparateDisplay("myJS9");
-
-or: -
-    JS9.SeparateDisplay({display: "myJS9"});
-
-You also can supply an opts object containing the properties: -
    -
  • images: array of image handles (or indexes into JS9.images array) to separate -
  • layout: can be "horizontal", "vertical", "auto" (default: "auto") -
  • leftMargin: margin in pixels between horizontally separated images -
  • topMargin: margin in pixels between vertically separated images -
  • idbase: base string for ids of separated displays -
-By default, the new displays are all placed in light windows, whose -positions can be adjusted on the screen as needed. The "horizontal" -layout will generate a single row of images. The "vertical" layout -will generate a single column of images. The "auto" option will -layout the images in one or more rows. Each row will contain one or -more images such that at least one-half of the right-most image is -visible in the browser without the need for horizontal scrolling. -

-Note that you can supply the opts object without supplying the display -parameter, e.g: -

-    JS9.SeparateDisplay({layout: "horizontal"});
-
-will separate images from the default "JS9" display in a horizontal layout. -

-By default, the ids of the successive JS9 displays will consist of -the original display id, followed by the string "_sep", followed by an -increasing integer (not necessarily starting at 1.) If you pass -the idbase property in the opts object, the id of each successive -display will be the specified base id followed by an increasing integer -that does start from 1. In the latter case, it is your responsibility to -ensure that the new ids to not conflict with existing ids. - -

-Instead of light windows to hold the new displays, you can also use the -CSS Grid Layout to automatically position the new displays in -ordinary div elements. To do this, the layout is set to "auto" and the initial -display (along with its menubar, colorbar, statusbar) is wrapped in two divs: -

    -
  • an outer div of class JS9GridContainer -
  • an inner div of class JS9GridItem -
-If a browser supports CSS Grid Layout (most do as of 2017), a grid layout -will be used. Otherwise, light windows will be used. For example: -
-    <div class="JS9GridContainer">
-    <div class="JS9GridItem">
-        <div class="JS9Menubar" id="JS9Menubar"></div>
-        <div class="JS9" id="JS9"></div>
-        <div class="JS9Statusbar"></div>
-    </div>
-    </div>
-
-The outer JS9GridContainer div is associated with the CSS -Grid container (i.e. its display property is set to grid.) -The inner JS9GridItem div delineates the contents of the "item" that -will added to the container when the displays are separated. - -

-You can tailor the layout by adding Grid Layout CSS directives to -JS9GridContainer. In particular, style elements such as -grid-template-columns and grid-gap are applied to this div: -

-      div.JS9GridContainer {
-	  grid-template-columns: repeat(3, 1fr);
-	  grid-gap: 10px;
-      }
-
-See CSS Grid Layout for more information about CSS Grids. - -
Scroll the JS9 display to the center of the viewport
-

-JS9.CenterDisplay(dname) -

-where: -

    -
  • dname: name of JS9 display to center -
-

-This routine scrolls this display to the center of the viewport. -You can supply a display name or the display object: -

-    JS9.CenterDisplay("myJS9");
-
-or: -
-    JS9.CenterDisplay({display: "myJS9"});
-
- -
Rename the id of a JS9 display
-

-JS9.RenameDisplay(oid, nid) -

-Calling sequences: -

-    JS9.RenameDisplay(nid)        # change default id (usually "JS9") to nid
-    JS9.RenameDisplay(oid, nid)   # change oid to nid
-
-

-where: -

    -
  • oid: old name of JS9 display -
  • nid: new name of JS9 display -
-

-This routine is used by the Desktop version of JS9 to implement the ---title (and --renameid) switch(es), which change the id -of the JS9 display(s) to the specified id(s). Once an id has been -renamed, external communication (via the js9 script or pyjs9) should -target the new id instead of the original id. -

-If also can be used in the query part of a URL when loading a web page -in order to rename a display, e.g.: -

-  https://js9.si.edu?renamedisplay=myJS9
-
-will rename the default display. In cases where multiple displays are defined -on a page: -
-  https://js9.si.edu/js9/tests/js9debug.html?renamedisplay=myJS9:yourJS9
-
-will rename the myJS9 display (but not the JS9 display). -

-The original id is still available internally, so Javascript public -API calls (but not external scripts) on the web page itself can target -either the original or the new id using the {display: "id"} syntax. - -

Close all images in a display
-

-JS9.CloseDisplay(dname, regexp) -

-where: -

    -
  • dname: name of JS9 display whose images will be closed -
  • regexp: optional regular expression to specify which images to close -
-

-By default, his routine closes all images in the specified display. -You can supply a display name as the first argument or the display object: -

-    JS9.CloseDisplay("myJS9");
-
-or: -
-    JS9.CloseDisplay({display: "myJS9"});
-
-If a regular expression is specified as second argument, only images matching -that regular expression will be closed. For example: -
-  JS9.CloseDisplay("JS9", ".*mask.fits.gz");
-
-will close all mask files. As a convenience, you can omit the display argument -and specify the template as the first argument: -
-  JS9.CloseDisplay(".*mask.fits.gz");
-
- -
Close all images in a display and remove the display
-

-JS9.RemoveDisplay(dname) -

-where: -

    -
  • dname: name of JS9 display to remove -
-This routine will close all images in the specified display and then -remove the display. It is available for displays contained in -light windows and for displays contained in JS9 Grid Containers. When -removing the display inside a light window, the light window is -immediately closed without a confirmation dialog box (unlike a light -window being closed via its close button.) For a display inside -a JS9 Grid Container, the display is removed from the DOM, so that it -no longer is part of the grid layout. Note, however, that you cannot -remove all displays from a grid container: at least one display must be -left in the container. - -


- -

Miscellaneous

- -
Print an image
-

-JS9.Print(opts) -

-where: -

    -
  • opts: options for print -
-

-Print the currently displayed image. A new window is displayed -containing the image, along with regions and other graphical layers -(the 2D graphics having been converted to a re-scalable format.) The -standard Print dialog box also is displayed and can be used to print -this new window. Dismiss both windows when you are finished. - -

-By default, if a colorbar is active on the page, it will be placed -beneath the image. You can pass the colorbar: false option -in the opts object to avoid printing the active colorbar. - -

Print the desktop window (desktop app only)
-

-JS9.WindowPrint(opts) -

-where: -

    -
  • opts: options for print -
-

-The JS9 desktop application that utilizes -Electron.js has the ability to -print the whole application window. When executed, the system print -dialog box is displayed (unless the silent the option is passed in -opts) and the window will be printed according to your print configuration. -

-The first argument allows you to specify the following options: -

    -
  • silent: don't ask user for print settings (def: false) -
  • printBackground: prints the background color and image of the web page (def: true) -
  • deviceName: set the printer device name to use (def: "") -
- -
Save the desktop window to a PDF file (desktop app only)
-

-JS9.WindowToPDF(filename, opts) -

-where: -

    -
  • filename: PDF file name -
  • opts: options for save -
-

-The JS9 desktop application that utilizes -Electron.js has the ability to -save the whole application window to a PDF file. The first argument specifies -the name of the PDF file. -

-The second argument allows you to specify the following options: -

    -
  • marginsType: the type of margins to use: 0 for default margin, 1 for no margin, and 2 for minimum margin -
  • pageSize: page size of the generated PDF: A3, A4, A5, Legal, Letter, Tabloid (NB: might not work with all printers) -
  • printBackground: prints the background color and image of the web page (def: true) -
  • printSelectionOnly: whether to print selection only (NB: This seems to crash the application!) -
  • landscape: true for landscape, false for portrait -
- -
Set the save directory for downloads (desktop app only)
-

-JS9.SaveDir(dirname) -

-where: -

    -
  • dirname: directory name for downloads -
-The JS9 desktop application that utilizes -Electron.js has the ability to -specify a directory into which files will be saved (e.g., by routines such -JS9.SavePNG()) -without using a dialog box. This is especially useful in scripts. - -

-The savedir directory can be specified on the desktop command line using the ---savedir switch: -

-    js9 -a --savedir $HOME/tmp ~/data/casa.fits
-
-But you can use this routine to set or change the save directory at any time: -
-    js9 SaveDir "$HOME/tmp"
-
-Future downloads for this desktop session will then be saved (without -use of a dialog box) to the specified directory. - -

-It's worth remembering that relative paths are taken relative to the -directory in which the JS9 app was started, not the current directory in which -you are running the js9 SaveDir command. To avoid confusion, it is recommended -that you supply a full path. - -

Quit the JS9 app (desktop app only)
-

-JS9.Quit() -

-For the Desktop app only, this command will quit the app. - -

Save image as a FITS file
-

-JS9.SaveFITS(filename, opts) -

-where: -

    -
  • filename: output file name -
  • opts: optional opts or "display" -
-Save the currently displayed image as a FITS file. If filename is not -specified, the file will be saved as "js9.fits". -

-If a second argument is supplied, it can be the string "display" or an -object containing the property "source". If "display" or opts.source -is "display" is passed, the currently displayed image section is -saved. Otherwise, the full image (or extracted image section, if -appropriate) is saved. -

-Don't forget that the file is saved by the browser, in whatever location -you have set up for downloads. - -

Save image as a PNG file
-

-JS9.SavePNG(filename, opts) -

-where: -

    -
  • filename: output file name -
  • opts: optional save parameters -
-Save the currently displayed image as a PNG file. If filename is not -specified, the file will be saved as "js9.png". The image is saved -along with the graphical overlays (regions, etc..) - -

-The opts object can specify the following properties: -

    -
  • layers: save graphical layers (e.g., regions) (default is true) -
  • source: "image" or "display" (default is "display") -
-By default, SavePNG() will save all of the 2D graphics in the -shape layers (regions, catalogs, etc.) as well as the image. Set -the layers property to false to save only the image. - -

-Also by default, SavePNG() will save the RGB pixels from the -display. This means, for example, that a blended set of images will -save the blended pixels. If you want to save the RGB pixels from one -of the images in a blended image, you can specify the source -property to the image. For example, in the js9blend.html demo, -you can save the RGB pixels of the Chandra image by specifying use of -the "image" source and specifying the image's id in the display -parameter: -

-    JS9.SavePNG("chandra.png", {source:"image"}, {display:"chandra.fits"});
-
- -

-Don't forget that the file is saved by the browser, in whatever location -you have set up for downloads. - -

Save image as a JPEG file
-

-JS9.SaveJPEG(filename, opts) -

-where: -

    -
  • filename: output file name -
  • opts: optional save parameters or a number between 0 and 1 indicating image quality -
-Save the currently displayed image as a JPEG file. If filename is not -specified, the file will be saved as "js9.jpeg". The image is saved -along with the graphical overlays (regions, etc..) - -

-The opts object can specify the following properties: -

    -
  • layers: save graphical layers (e.g., regions) (default is true) -
  • source: "image" or "display" (default is "display") -
  • quality: JPEG encoder quality -
-By default, SaveJPEG() will save all of the 2D graphics in the -shape layers (regions, catalogs, etc.) as well as the image. Set -the layers property to false to save only the image. - -

-Also by default, SaveJPEG() will save the RGB pixels from the -display. This means, for example, that a blended set of images will -save the blended pixels. If you want to save the RGB pixels from one -of the images in a blended image, you can specify the source -property to the image. For example, in the js9blend.html demo, -you can save the RGB pixels of the Chandra image by specifying use of -the "image" source and specifying the image's id in the display -parameter: -

-    JS9.SaveJPEG("chandra.png", {source:"image"}, {display:"chandra.fits"});
-
- -

-If encoder quality parameter is not specified, a suitable default is -used. On FireFox (at least), this default values is 0.95 (I think.) - -

-Don't forget that the file is saved by the browser, in whatever location -you have set up for downloads. - -

Upload currently displayed FITS file to proxy server
-

-JS9.UploadFITSFile() -

-Upload the currently displayed FITS file to the proxy server, so that -back-end analysis can be performed. This routine requires that a Node.js-based -JS9 helper is running and that the helper has enabled the loadProxy -property and set up a workDir directory in which to store the FITS file. - -

Get FITS header as a string
-

-JS9.GetFITSHeader(nlflag) -

-where: -

    -
  • nlflag: true if newlines should added to each card -
-Return the FITS header as a string. By default, the returned string contains -the 80-character FITS cards all concatenated together. If nlflag -is true, each card will have a new-line appended. -

-Note that the -JS9.GetImageData() -routine also returns the -FITS header, but as an object whose properties contain the header -values. For example, obj.SIMPLE will usually have a value of true, -obj.BITPIX will have contain the bits/pixel, etc. This object is more -useful for programming tasks, but does not contain the FITS comments -associated with each header card. - -

Display help in a light window
-

-JS9.DisplayHelp(name) -

-where: -

    -
  • name: name of a help file or url of a web site to display -
-The help file names are the property names in JS9.helpOpts (e.g., "user" for -the user page, "install" for the install page, etc.) Alternatively, you can -specify an arbitrary URL to display (just because.) - -
Display plugin in a light window
-

-JS9.DisplayPlugin(name) -

-where: -

    -
  • name: name of the plugin -
-Toggle the light-window display of the named plugin, as is done by -the View and Analysis menus. That is, if the plugin is -not visible, make it visible. If the plugin is visible, hide it. -

-You can supply the full class and plugin name or just the name, using -exact case or lower case, e.g.: -

    -
  • JS9Panner or panner -
  • JS9Magnifier or magnifier -
  • JS9Info or info -
  • JS9Console or console -
  • DataSourcesArchivesCatalogs or archivescatalogs -
  • FitsBinning or binning -
  • ImExamEncEnergy or encenergy -
  • ImExamPxTabl or pxtabl -
  • ImExamRadialProj or radialproj -
  • ImExamHistogram or histogram -
  • ImExamRegionStats or regionstats -
  • ImExamXProj or xproj -
  • ImExamYProj or yproj -
  • ImExam3dPlot or 3dplot -
  • ImExamContours or contours -
-

-As with plugins in the View and Analysis menus, this routine does -nothing if the plugin is explicitly defined on the web page. -

-This routine is useful if you are building a web interface that -supports the JS9 menu functions. - -

Display content in a light window
-

-JS9.LightWindow(id, type, content, title, opts) -

-where: -

    -
  • id: unique id for light window div(default: "lightWindow" + uniqueID) -
  • type: content type: "inline", "div", "ajax", "iframe" (default: "inline") -
  • content: content of the light window (default: none) -
  • title: title (default: "JS9 light window") -
  • opts: configuration string (default: "width=830px,height=400px,center=1,resize=1,scrolling=1") -
-Display arbitrary content inside a light window. There are any number -of light window routines available on the Net. JS9 uses light window -routines developed by Dynamic Drive (http://www.dynamicdrive.com). -Their extensive documentation can be found -here. - -

-The content shown inside the window depends on the content parameter: -

    -
  • iframe: the URL of the page to display (ie: "http://www.google.com") -
  • inline: the HTML to display (back-slashing any special JavaScript characters, such as apostrophes) -
  • ajax: the relative path to the external page to display, relative to the current page (ie: "../external.htm") -
  • div: define a DIV element on the page with a unique ID attribute (probably hidden using style="display:none") and the use the DIV's id as the content value -
-JS9 typically uses the inline option. Note that web sites often -do not allow themselves to be embedded in an iframe, so this is an -unreliable option. - -

-The opts parameter specifies options for the light window, such -as its size. This parameter consists of a string with comma-separated -keywords, e.g.: -

-    "width=830px,height=400px,center=1,resize=1,scrolling=1"
-
-The opts keywords, defined in the Dynamic Drive documentation, are: -width, height, left, top, center, resize, and scrolling. The -JS9.lightOpts.dhtml object defines oft-used lightwin configurations, -and the JS9.lightOpts.dhtml.textWin property is used as the -default for this call. You can utilize these properties in your own call -to JS9.LightWindow() or make up your own configuration string. - -

-As an extension to the Dynamic Drive light window support, JS9 adds the ability -to double-click the title bar in order to close the window. - -

Use the file dialog box to load a FITS file
-

-JS9.OpenFileMenu() -

-Calling this routine brings up the browser's file dialog box. When a -FITS file is selected, if will be loaded into the JS9 display. -

-This routine is useful if you are building a web interface that -supports the JS9 menu functions. - -

Use the file dialog box to load a region file
-

-JS9.OpenRegionsMenu() -

-Calling this routine brings up the browser file menu. When a region file is -selected, if will be loaded into the JS9 display. -

-This routine is useful if you are building a web interface that -supports the JS9 menu functions. - -

Use the file dialog box to load a colormap file
-

-JS9.OpenColormapMenu() -

-Calling this routine brings up the browser file menu. When a -JSON-format colormap file is selected, it will be loaded into the JS9 -display. The colormap file can take one of two forms (without the comments): -

-    # RGB color triplets for the I8 colormap in a "colors" property
-    {"name":"i8","colors":[[0,0,0],[0,1,0],[0,0,1],[0,1,1],[1,0,0],[1,1,0],[1,0,1],[1,1,1]]}
-
-    # all 3 vertex arrays for the purple colormap in one "vertices" property
-    {"name":"purple","vertices":[[[0,0],[1,1]],[[0,0],[0,0]],[[0,0],[1,1]]]}
-
-This routine is useful if you are building a web interface that -supports the JS9 menu functions. See -JS9.AddColormap() for more -information about colormap formats. - -
Get toolbar values from the Toolbar plugin
-

-val = JS9.GetToolbar(type) -

-where: -

    -
  • type: type of information to retrieve -
-returns: -
    -
  • val: array of tool objects (or an argument-dependent return) -
-The JS9.GetToolbar() routine returns global information about the Toolbar -plugin. If the first argument is "showTooltips", the returned value specifies -whether tooltips are currently displayed. Otherwise an array of tool objects is -returned, one for each of the defined tools in the toolbar. - -
Set toolbar values for the Toolbar plugin
-

-JS9.SetToolbar(arg1, arg2) -

-where: -

    -
  • arg1: a type-dependent id or value to set -
  • arg2: a type-dependent value to set -
-The JS9.SetToolbar() routine sets global information about the Toolbar -plugin. The following values can be specified as the first argument: -
    -
  • init: the text "init" triggers a re-initialization of all -display Toolbar plugins, which is useful if you have changed -the JS9.globalOpts.toolBar array to specify a new set of -top-level tools. -
  • showTooltips: the text "showTooltips" uses the value of the -boolean arg2 to specify whether tooltips are displayed as the mouse hovers -over a tool. -
  • [text]: other text is assumed to be a JSON-formatted text -containing either a new tool to add to the toolbar, or an array of tools. -
  • [object]: an object is assumed to be new tool to add to the toolbar -
  • [array]: an array is assumed to be an array of new tools to add to the toolbar -
-New tools can be added to the toolbar at any time using this routine. The -text properties associated with a tool object are: -
    -
  • name: name of the tool -
  • tip: a tooltip to display when the mouse hovers over the tool -
  • image: url (relative to the install directory) containing a PNG -image file to display as the tool icon -
  • cmd: name of the JS9 public routine to execute when the tool is -clicked -
  • args: array of arguments to pass to the JS9 public routine -
-Only the name and cmd properties are required. If no image is -specified, a button labeled by the name value will be used. - -

-Examples of tool objects: -

-  {
-    "name": "linear",
-    "tip": "linear scale",
-    "image": "images/toolbar/dax_images/lin.png",
-    "cmd": "SetScale",
-    "args": ["linear"]
-  },
-  {
-    "name": "histeq",
-    "tip": "histogram equalization",
-    "cmd": "SetScale",
-    "args": ["histeq"]
-  },
-  {
-    "name": "annulus",
-    "tip": "annulus region",
-    "image": "images/toolbar/dax_images/annulus.png",
-    "cmd": "AddRegions",
-    "args": ["annulus"]
-  },
-  {
-    "name": "remove",
-    "tip": "remove selected region",
-    "image": "images/toolbar/dax_images/erase.png",
-    "cmd": "RemoveRegions",
-    "args": ["selected"]
-  },
-  {
-    "name": "zoom1",
-    "tip": "zoom 1",
-    "image": "images/toolbar/dax_images/mag_one.png",
-    "cmd": "SetZoom",
-    "args": [1]
-  },
-  {
-    "name": "magnifier",
-    "tip": "toggle magnifier display",
-    "image": "images/toolbar/dax_images/mag.png",
-    "cmd": "DisplayPlugin",
-    "args": ["JS9Magnifier"]
-  }
-
-Each time a tool is added to the list of available tools, the active -Toolbar plugins will be re-initialized to display that tool. By default, -the new tool not be added to the top-level list: you must also edit -the JS9.globalOpts.toolBar array to add the name of the -tool. If this is done after you add the tool, remember to re-initialize -active toolbars by calling: -
-    JS9.SetToolbar("init");
-
- -
Get location of JS9 installation directory
-

-rpath = JS9.InstallDir(file) -

-where: -

    -
  • file: file or directory to convert -
-returns: -
    -
  • rpath: path of the file relative to the JS9 install directory -
-Sometimes a plugin needs to load an auxiliary file inside the plugins -sub-directory. The web page loading the plugin has an arbitrary -location relative to the JS9 install directory, so this routine -returns a relative path to the js9 install directory. - -
Send a message to a back-end server
-

-JS9.Send(msg, obj, cb) -

-where: -

    -
  • msg: name of the msg, as defined in the back-end server -
  • obj: object containing msg parameters -
  • cb: callback to call when back-end server returns its results -
-JS9 sends various internal messages to the back-end server using either -socket.io protocol (in the Node.js implementation) or CGI. For -example, when a remote analysis call is made, JS9 sends a message to the -back-end server detailing the task to call, parameters to pass, etc. Results -are then returned to JS9 for display. JS9 also sends messages to the -back-end server when a new image is displayed. -

-Communication with the back-end is usually done behind the scenes and -need not concern users or application programmers. However, if you -write your own socket.io-based server, you might want to add -project-specific messages to your implementation. For example, a -Perl-based or Python-based server might add its own special messages -that execute Perl or Python commands within the server in response to -JS9 messages. In this case, you can use -JS9.Send() -to send a message to these message handlers. -

-The msg name is the name of the message, as defined by the -server. By convention, an object is usually passed to the -message handler. JS9 will add a dataPath property to this -object to indicate the current list of directories in which to -search for data. All other properties are specific to the message being handled. -You can pass a null instead of an object and -JS9.Send() -will generate -a temporary object to hold the dataPath. -

-The cb function will be called if the message sends an -acknowledgment. The arguments passed to this function call by the server -are specific to the message being handled. -

-For example, you can send a message to the back-end server to retrieve the -list of available analysis tasks and then display this list using the call: -

-    JS9.Send("getAnalysis", null, function(s){alert(s)});
-
-The "getAnalysis" message passes no parameters to the server. The -server returns a list of available analysis tasks in JSON format. - -
Add a JS9 display div and/or associated plugins
-

-JS9.AddDivs(id1, id2, ...) -

-where: -

    -
  • id1, id2, ...: optional name(s) of new JS9 display div(s) -
-You can add new JS9 displays and/or plugins dynamically. To do this, you -create the new divs, add them to the web page, and then call this routine to -incorporate them into JS9. -

-The routine will accept a list of JS9 display divs to initialize. If -all you are doing is adding one or more plugins to an existing display, -leave the argument list empty. -

-For example, to add a new JS9 display and menubar at the end of a web -page and load an image into that display: -

-    var html = "<div class='JS9Menubar' id='myJS9Menubar'></div><div class='JS9' id='myJS9'></div>";
-    // jquery append to end of page
-    $(html).appendTo($("body"));
-    // create the new JS9 display, with associated plugins
-    JS9.AddDivs("myJS9");
-    // just a standard load to that display
-    JS9.Load("foo.fits", {scale: "log"}, {display: "myJS9"});
-
-You can use JS9.LoadWindow() to -load images into a light-weight or completely new window. To do this -with your own routine, you should call JS9.AddDivs() after the window -has been created. You can use the jQuery -arrive -wrapper that implements support for the - MutationObserver: -
-    // once the window exists containing the div id, we can finish the set up
-    $("#window").arrive("#"+id, {onceOnly: true}, function(){
-        finishUp();
-    });
-    // (make-believe) create light win routine, where id is the window div id
-    myCreateLightWindow(id, html, title, opts);
-
- -
Instantiate plugins on this web page
-

-JS9.InstantiatePlugins() -

-Normally, JS9 will instantiate all of its plugins automatically once the page -is loaded and ready: internally, jQuery $(document).ready() calls JS9.init(). -However, module loaders such as Require.js -can load scripts asynchronously and cause jQuery $(document).ready() to fire -before all JS9 scripts are available. The -JS9.RegisterPlugin() -routine should deal properly with this situation. But just in case ... -the JS9.InstantiatePlugins() will perform the plugin instantiation -explicitly. -

-In you find you need to call this routine in order make your in-page -plugins display properly, please let us know the circumstances. - -


- -

Prototype Routines (not ready for prime time)

- -

-NB: The routines in this section are prototypes and therefore are -subject to change. Feel free to contact us to discuss your needs so -that we can gain a better understanding of what is required in these cases. - -


- -

API Change History

- -

-The JS9 Public API is meant to be stable and well-documented. If we are -forced to make an incompatible change to the API, it will be documented here. - -

-

20220408: Change the calling sequence to global ongroupcreate callback
-The global JS9.Regions.opts.ongroupcreate callback has the calling sequence: -
-
  • ongroupcreate: ongroupcreate(id, im, xreg); - -where: -
      -
    • id: group id -
    • im: the image handle for the currently displayed image -
    • xreg: an array of shape objects within the group -
    -
  • -The old calling sequence did not pass the group id, but instead passed -the event which triggered the group creation in the last argument ... -which doesn't make sense for an API call. - -

    -

    20200815: ChangeRegions, CopyRegions, GetRegions, RemoveRegions, SelectRegions, : default region changed
    -If the regions argument is not specified, it now defaults to -"selected" if there are selected regions, otherwise "all". Previously it only -default to "all". You can revert to the previous behavior by changing the -JS9.globalOpts.regWhichDefault from "auto" to "all". (Note: unless you are -writing a GUI, you almost certainly should be specifying the regions explicitly -for these calls). - -

    -

    20200720: ChangeRegions: dx, dy properties renamed to deltax, deltay
    - -The dx, dy properties of -JS9.ChangeRegions allowed you to specify a delta to add to the current -image position. For consistency, these properties were renamed to -deltax, deltay respectively. - -
    20200623: SetFlip and SetRot90 no longer manipulate the image data
    -The original implementation of JS9.SetFlip -and JS9.SetRot90 manipulated the -underlying image data, changing the WCS as needed. This behavior was -inconsistent with other routines: e.g. image processing routines -only change the displayed data, while explicit raw data routines such as -JS9.ReprojectData change the underlying -image in accordance with the rules for manipulating raw data. We therefore -re-implemented these routines (and added JS9.SetRotate) -so that they change the orientation of the canvas, rather than the -underlying image data. This implies that the WCS headers are no longer -changed by flipping and rotating. - -
    20200207: remove DisplaySection +N and -N binning options
    - -

    -The DisplaySection() routine originally supported "+N" and "-N" -binning options to change the current bin by "N". With the addition of -support for fractional binning, these two constructs conflict with the -use of negative bin values to indicate 1/abs(N) binning. - - -

    20200114: Remove experimental LoadAuxFile routine
    - -

    -Regions can be loaded using JS9.LoadRegions. -Masks are now supported by loading a mask image and calling -JS9.MaskImage. - -

    20180322: DisplaySection now uses current values for unspecified properties
    - -

    -Prior to JS9 version 2.1, -JS9.DisplaySection() always used -the center of the file, along with dimensions and binning specified by -the JS9.globalOpts.table and JS9.globalOpts.image objects, if these -properties were not explicitly specified. This was just wrong: it -meant that you could not set up a section and then repeated change the -filter or position without re-specifying the current section -parameters. We therefore changed the default behavior so that unspecified -properties take on the current values. To use the original defaults, -simply specify 0 for xcen and ycen, and use the globalOpts values -for dimensions and binning. - -

    20151218: OpenFileMenu and OpenRegionsMenu don't require a display argument
    - -

    -The routines -JS9.OpenFileMenu() -and -JS9.OpenRegionsMenu() -required a display argument, instead of utilizing the standard -optional display object. This mistake has been corrected, with the -result that both routines now target the default display, as expected, -if no display is passed. - -

    20141117: The Set routines now return "OK" instead of true on success
    - -

    -The public Set routines -(JS9.SetZoom(), -JS9.SetColormap(), etc) -were returning a boolean true when successful. This has been changed -to "OK", to make it clear that the return value is a status value, -not a boolean data value. - -

    20141028: callback function to RunAnalysis and SubmitAnalysis
    - -

    -Due to an oversight, the signature of the callback function supplied to -JS9.RunAnalysis() -(and its derivative function, -JS9.SubmitAnalysis()) -was missing the errcode argument. -To correct this mistake, the signature was changed from: -

    -    func(stdout, stderr, aobj)
    -
    -to: -
    -    func(stdout, stderr, errcode, aobj)
    -
    -See js9onchange.html for an example of using this callback function. - -


    - -

    Last updated: June 10, 2021
    -
    - - - diff --git a/web/static/js9_old/help/python.html b/web/static/js9_old/help/python.html deleted file mode 100644 index 4a1e40ef6949abb60eea4b80533dc40a38bd55b3..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/python.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - -JS9 with Python and Jupyter - - - -
    -

    JS9 with Python and Jupyter

    - -

    Connecting Python to JS9

    -

    -The pyjs9.py module connects Python and JS9. It is -available on GitHub:   -https://github.com/ericmandel/pyjs9. - -

    -The JS9 class constructor connects to a single JS9 instance in a -web page. Once the connection is made, the returned JS9 object -supports the JS9 Public API and a shorter command-line syntax. You -also can send/retrieve numpy arrays and astropy (or pyfits) hdulists -to/from JS9. - -

    -pyjs9 communicates with the JS9 back-end server (which communicates with -the browser itself). By default, pyjs9 utilizes the - -requests module to communicate with the back-end server. -However, if you install the - -socketIO_client, -pyjs9 will use the faster, -persistent socket.io protocol. - -

    -Install pyjs9 from the GitHub repository using pip, as usual: -

    -    > pip install git+https://github.com/ericmandel/pyjs9.git#egg=pyjs9
    -
    -or from a local copy: -
    -    > pip install /path/to/local/copy
    -
    - -

    -Mandatory dependencies for pyjs9 are: -

      -
    • six -
    • requests -
    - -

    -Optional dependencies for pyjs9 are: -

      -
    • numpy            # support for GetNumpy and SetNumpy methods -
    • astropy           # support for GetFITS and SetFITS methods -
    • socketIO-client  # fast, persistent socket.io protocol, instead of html -
    - -

    -To run pyjs9: -

    -    > # ensure JS9 node-server is running ...
    -    > # visit your local JS9 web page in your browser ...
    -    > python
    -    ... (startup messages) ...
    -    >>> import pyjs9
    -    >>>
    -    >>> j = pyjs9.JS9()        # default: connect to 'http://localhost'
    -    >>>
    -    >>> j.GetColormap()
    -    {'bias': 0.5, 'colormap': 'grey', 'contrast': 1}
    -    >>> j.SetColormap('red')
    -    >>> j.cmap()
    -    'red 1 0.5'
    -    >>>
    -    >>> hdul = j.GetFITS()
    -    >>> hdul.info()
    -    Filename: (No file associated with this HDUList)
    -    No.    Name         Type      Cards   Dimensions   Format
    -    0    PRIMARY     PrimaryHDU       6   (1024, 1024)   int32   
    -    >>>
    -    >>> narr = j.GetNumpy()
    -    >>> narr.shape
    -    (1024, 1024)
    -
    - -

    -If you have internet connectivity, visit the JS9 web page at -https://js9.si.edu with your browser and: -

    -    > python
    -    ... (startup messages) ...
    -    >>> import pyjs9
    -    >>>
    -    >>> j = pyjs9.JS9('js9.si.edu')        # connect to JS9 web site
    -    >>>
    -    >>> j.GetColormap()
    -    {'bias': 0.5, 'colormap': 'grey', 'contrast': 1}
    -    >>>
    -    >>> # etc ...
    -
    - -

    -

    Adding JS9 to Jupyter (aka IPython)

    -

    -We are working on integrating JS9 into Jupyter properly. For now, you -can utilize Jupyter's %%html construct to load JS9 into a -cell for display. You simply add JS9 divs to cell and load the JS9 -CSS and Javascript code. - -

    -To simplify matters, the JS9 CSS files are combined together into a -file called js9-allinone.css and the JS9 Javascript files are -combined into a file called js9-allinone.js. These can be loaded -in a cell after the JS9 divs are defined: -

    -    %%html
    -    <div class="JS9Menubar"></div>
    -    <div class="JS9"></div>
    -    <link type="text/css" rel="stylesheet" href="//js9.si.edu/jupyter/js9-allinone.css">
    -    <script type="text/javascript" src="//js9.si.edu/jupyter/js9-allinone.js"></script>
    -
    -In this example, the JS9 display and menubar will be loaded into the -Jupyter page. You can then drag and drop FITS images onto the display -or use the File:open local file... option to load FITS data. Once -an image is loaded, you can pan, zoom, scale, change colormaps, etc, -and also utilize JS9 plugins (panner, magnifier, browser analysis, -etc.) as usual. - -NB: Obviously, the JS9 install files and directories (other than -all-in-one .css and .js files) are not available in this mode, leading -to the following limitations: -
      -
    • no js9prefs.js for site-wide configuration -
    • no back-end helper will be run -
    • no server-side analysis (including proxy load) -
    • no help files will be available (and no Help menu option) -
    - -

    -Note that you also can use Jupyter's %%html syntax to define an -HTML iframe that will display an existing JS9 web page: -

    -    %%html
    -    <iframe src="https://js9.si.edu" width=1000 height=750></iframe>
    -
    -or perhaps better still: -
    -    %%html
    -    <iframe src="https://js9.si.edu/js9/js9.html" width=100% height=900></iframe>
    -
    -Since you are now accessing an existing web site, all JS9 functions -should work as expected ... except for the use of locally stored -preferences (i.e. the Preferences plugin) in Firefox. Currently, -Firefox throws a security exception when an iframe tries to access -local storage, so this function does not work. - -

    -We will continue to improve the Jupyter/JS9 connection. Please send us your -comments and suggestions. - -

    Last updated: June 8, 2016
    -
    - - - diff --git a/web/static/js9_old/help/regions.html b/web/static/js9_old/help/regions.html deleted file mode 100644 index df0695b0313ad11678386733f98d2489ae01f7dd..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/regions.html +++ /dev/null @@ -1,198 +0,0 @@ - - - - - -JS9/DS9/Funtools Spatial Regions - - - -
    - -

    JS9/DS9/Funtools Spatial Regions

    - -

    -In many X-ray astronomical analysis software suites (e.g., fitsio, ciao, -funtools), spatial regions allow one to select sections of an image or -rows of a table by means of simple geometric shapes. When an image is -filtered, only pixels found within these shapes are processed. When a -table is filtered, only rows found within these shapes are processed. - -

    -In these systems, spatial region filtering is accomplished by means -of region specifications. Typically, region specifications use -bracket notation appended to the filename of the data being processed: -

    -  funcnts "foo.fits[circle(512,512,100)]"
    -
    - -

    -JS9 implements a subset of the widely-used DS9/Funtools regions syntax, -as described below. - -

    Region Expressions

    - -Spatial region specifications consist of one or more lines containing: -
    -  # comment until end of line
    -  # each region expression contains shapes and optional local json objects
    -  [region_expression1] {local json object}  # tags
    -  [region_expression2] # tags
    -
    - -

    -A single region expression consists of: -

    -  # shape name and parens are required
    -  # arguments are separated by commas. spaces are optional, as is the + sign
    -  [+-]shape(val, val, ...)
    -
    -where regions shapes can be: - -
    -  shape:        arguments:
    -  -----         ----------------------------------------
    -  annulus       (xcenter, ycenter, inner_radius, outer_radius)
    -  box           (xcenter, ycenter, xwidth, yheight[, angle])
    -  circle        (xcenter, ycenter, radius)
    -  ellipse       (xcenter, ycenter, xwidth, yheight[, angle])
    -  text          (x1, x2, text)
    -  point         (x1, y1)
    -  polygon       (x1, y1, x2, y2, ..., xn yn)
    -
    -Note that other keyword keywords (e.g., the DS9 "global" keyword and -DS9/Funtools region shapes not yet implemented in JS9) are silently ignored. - -

    -All arguments to regions are real values; integer values are -automatically converted to real where necessary. All angles are in -degrees and run from the positive image x-axis to the positive image -y-axis. - -

    Region Exclusion

    -

    -Shapes also can be globally excluded from a region descriptor by using -a minus sign before a region: - -

    -  operator      arguments:
    -  --------      -----------
    -  -             Globally exclude the region expression following '-' sign
    -                from ALL regions specified in this file
    -
    - -

    Local Properties of Regions

    -DS9/Funtools regions utilize a key=value syntax within an in-line comment to -specify secondary properties such as color. It also uses single tokens -in the in-line comments to specify tags such as "source" and "background". -

    -JS9 retains the use of comments to specify tags, but utilizes a JSON -object to specify secondary properties. This optional object follows -the region specification: -

    -    point(4300.00, 4250.00) {"color": "red"} # background,include
    -    point(350.897859, 58.835164) {"ptshape": "circle", "ptsize": 5}
    -
    -See the JS9.Regions.opts object in the JS9 source code for a list of properties -that can be passed in this JSON object. - -

    Coordinate Systems

    - -For each region, it is important to specify the coordinate system -used to interpret the region, i.e., to set the context in which position and -size values are interpreted. For this purpose, the following keywords -are recognized: - -
    -  name                  description
    -  ----                  ------------------------------------------
    -  physical              pixel coords of original file using LTM/LTV
    -  image                 pixel coords of current file
    -  FK4                   sky coordinate system
    -  FK5                   sky coordinate system
    -  galactic              sky coordinate system
    -  ecliptic              sky coordinate system
    -  ICRS                  currently same as J2000
    -
    -If no coordinate system is specified, physical is assumed. The -coordinate system specifier should appear at the beginning of the -region description, separated by semi-colon, or on a separate line. -Note that multiple coordinate systems can be in the same -specifier. Each one pertains to the region following until the next -coordinate system is defined: -
    -  # Region file format: JS9 version 1.0
    -  ICRS
    -  point(23:23:27.815, +58:48:42.017)
    -  box(23:23:27.815, +58:48:42.017, 29.51", 29.51", 0.000)
    -  physical
    -  ellipse(4300.00, 4250.00, 30.00, 20.00, 0.00)
    -  box(4300.00, 4250.00, 60.00, 60.00, 0.00)
    -  ICRS
    -  circle(350.897859, 58.835164, 0.76')
    -  ellipse(350.897859, 58.835164, 14.76", 9.84", 0.000)
    -
    - -

    -

    Specifying Positions, Sizes, and Angles

    - -The arguments to region shapes can be floats or integers describing -positions and sizes. They can be specified as pure numbers or using -explicit formatting directives: - -
    -  position arguments    description
    -  ------------------    ------------------------------
    -  [num]                 context-dependent (see below)
    -  [num]d                degrees
    -  [num]r                radians
    -  [num]p                physical pixels
    -  [num]i                image pixels
    -  [num]:[num]:[num]     hms for 'odd' position arguments
    -  [num]:[num]:[num]     dms for 'even' position arguments
    -  [num]h[num]m[num]s    explicit hms
    -  [num]d[num]m[num]s    explicit dms
    -
    -  size arguments        description
    -  --------------        -----------
    -  [num]                 context-dependent (see below)
    -  [num]"                arc seconds
    -  [num]'                arc minutes
    -  [num]d                degrees
    -  [num]r                radians
    -
    -When a "pure number" (i.e. one without a format directive such as 'd' -for 'degrees') is specified, its interpretation depends on the context -defined by the 'coordsys' keyword. In general, the rule is: - -

    -All pure numbers have implied units corresponding to the current -coordinate system. - - -

    -If no such system is explicitly specified, the default system is -implicitly assumed to be PHYSICAL. In practice this all means that for -IMAGE and PHYSICAL systems, pure numbers are pixels. Otherwise, for -all systems, pure numbers are degrees. - -

    -

    Examples

    - -
    -    # js9 region format, properties contained in json
    -    ellipse(23:23:22.179, +58:48:10.542, 40", 20", 60) {"text": "json ellipse test", "textOpts": {"color": "yellow", "fontSize": 16, "fontStyle": "italic", "fontWeight": "bold"}, "color": "violet"} # json test tag, another tag
    -
    -    # ds9 format, properties contained in comment string
    -    box(23:23:35.486, +58:50:03.146, 40", 20", 30) # width=4 text={ds9 box test} dash=1 color=red fixed=1 rotate=0 tag="ds9 test tag"
    -
    -    # hybrid js9/ds9 format
    -    circle(23:23:29.526, +58:49:09.56, 14.756997") {"strokeWidth": 1, "strokeDashArray": [3,1], "transparentCorners": true} # text="hybrid circle test" tag="ds9 test tag" tag="json test tag"
    -
    - -
    Last updated: February 2, 2017
    -
    - - - diff --git a/web/static/js9_old/help/repfile.html b/web/static/js9_old/help/repfile.html deleted file mode 100644 index 128266b1614d29d217bd8a2c168190ac91f57747..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/repfile.html +++ /dev/null @@ -1,221 +0,0 @@ - - - - - -Dealing with Large Files - - - -
    -

    Dealing with Large Files

    - -

    -Large astronomical FITS -data files present a challenge for browser-based image display, in two ways: -

      -
    • downloading large files can take a long time, even on the fastest connections -
    • unlike desktop programs which enjoy quasi-unlimited memory via the -mmap() -system call, browsers enforce hard (usually per-tab) memory limits. -
    -The nightmare scenario is to run out of browser memory after taking a -long time to download the file! - -

    -One possibility for dealing with large files is to download a small -representation file for display and quick-look analysis, while -supporting detailed analysis and image extraction on the original -parent file. In JS9, you can: -

      -
    • install the -Server-side Helper -and set the JS9.globalOpts.fits2fits, -JS9.globalOpts.image, and JS9.globalOpts.table, -parameters to control how/when small FITS representation files are -automatically generated. -
    • load a small FITS file (presumably created off-line) and -manually associate a large parent file with it by passing -the parentFile property on the opts object. -
    -These schemes are described below. - -

    Automatic Generation of a FITS Representation File

    - -

    -Consider a 12000 x 12000 Hubble Deep Field image. Even using gzip -compression, this 300Mb file could take several minutes to download -and would require more than 500Mb of memory to display. But you can -bin this file by a factor of 24 into a gzip'ed 512 x 512 FITS image -with file size of approximately 500Kb. This FITS -representation file would download quickly and give a good -overview of the entire data set. You can perform quick-look analysis -on this file using JS9 plugins. But if you also could re-extract a -section from the original file at a higher resolution, you would, in -essence, be panning around the original image without the transmission -and memory overhead associated with processing the whole file. - -

    -JS9 supports FITS representation file generation and display, -as well as extraction of binned image sections from the original parent -file, using the fits2fits scheme. To utilize it at your site, -first configure a Node.js-based -Server-side Helper using the -standard GNU configure/make setup: -

    -  # where to find cfitsio and install binaries, what sort of helper to build
    -  ./configure  --with-cfitsio=/usr/local --prefix=$HOME --with-helper=nodejs
    -  make
    -  make install
    -
    - -

    -Once the js9Helper is running, configure fits2fits by -setting the following global parameters in your js9prefs.js file: -

      -
    • globalOpts.workDir: where to store temporary representation files -
    • globalOpts.workDirQuota: optional user quota on work directory -
    • globalOpts.fits2fits: when/how to generate FITS representation files -
    • globalOpts.image: image section parameters -
    • globalOpts.table: table section parameters -
    -The server-side helper must support temporary user work directories in -which to store the FITS representation files. This is accomplished by -setting the globalOpts.workDir property in js9prefs.js to a -top-level directory which will contain the individual work -sub-directories for each JS9 connection. The workDir path should -either be an absolute path, or one that is relative to the JS9 helper -directory. - -

    -Optionally, you probably will want to set the -globalOpts.workDirQuota property (current default value of -50Mb) to limit the amount of space that can be utilized by each -user. Note that the workDirQuota is not a hard quota: the -js9helper only checks whether the quota has been exceeded before -extracting the next section. This means that users can always extract -one section that will bring the total size above the quota. Thus, if -the quota is 10Mb and the work directory is empty, imsection will -extract a 50Mb file. But it will not extract any more files until -already-loaded files have been closed in order to bring the total -under the quota. - -The globalOpts.fits2fits property controls whether a FITS -representation file is automatically generated. It accepts the following values: -

      -
    • always: always generate a FITS representation file -
    • true: boolean value is same as "always" -
    • never: never generate a FITS representation file -
    • false: boolean value is same as "never" -
    • size>N: generate a representation file is this file's size is greater than N Mb -
    -Of course, this property is only checked if JS9 is connected to a server-side -helper which has a working directory configured, as described above. - -

    -The current default for fits2fits is "size>100", which means that -representation files will be generated if the original FITS file has a size -greater than 100 Mb. - -The globalOpts.image and globalOpts.table objects specify the -image dimensions and bin factor used to generate the FITS representation file: -

      -
    • xdim: x image dimension -
    • ydim: y image dimension -
    • bin: bin factor -
    -Binning is applied after the image section is extracted or the table -is binned into an image. Thus, dimensions of 4096 x 4096 and bin 4 will -produce a 1024 x 1024 image. - -

    -When fit2fits is set up in this way, JS9 will ask the helper to -check the file size when loading a FITS URL. If the check returns -false, the original FITS file will be loaded internally into JS9. If -true, the JS9 helper will extract a representation image (i.e, an -image section) from the parent file, store it in the temporary work -directory, and then tell JS9 to display the representation file. - -

    -The smaller in-memory representation file will be used when performing -browser-based analysis such as WCS reprojection, 3D plots, and -imexam. But the representation file knows its parent, and will send -the parent filename to run server-side analysis tasks. Thus JS9 -performs quick-look analysis on the smaller file and more detailed -server-side analysis on the original parent file. - -

    -In this context, perhaps the most important server-side task is -the Bin/Filter/Section plugin available in the View -menu. This plugin allows you to extract sections from FITS binary -tables and images, with options to choose the image center, image -dimensions, and bin factor. For tables, the plugin also allows you to -filter rows of the table by means of arithmetic and boolean operations -on the table columns. - -

    -The Bin/Filter/Section plugin works with both FITS -representation files and with in-memory FITS files. If the displayed -FITS file is a representation file (i.e., it has a parent file, a JS9 -helper is connected, etc.), the plugin will ask the JS9 helper to -extract the new image section from the parent. Otherwise, it extracts -the section from the in-memory FITS file. This behavior is meant to be -transparent to the user. See the -Bin/Filter/Section plugin for -more information. - -

    -NB: Unfortunately, the fits2fits scheme is not available with -FITS files that are drag/dropped onto JS9 or files that are opened -through the file menu dialog box. Both of these methods call for the -browser to load the whole file directly and pass it to JS9 for display. -There is some discussion within the browser development community of -supporting on-the-fly processing, but nothing definite is planned. - -

    Manual Specification of a FITS Parent File

    - -

    -Assuming the JS9 helper is set up, but fits2fits is set to -"never", you can load a small FITS file using JS9.Load() and manually -specify a parentFile property in the options object: -

    -    JS9.Load("js9/fits/f814w_bin24.fits.gz", {colormap:"cool", parentFile: "fits/f814w.fits.gz"})
    -
    -One important note: the pathname of the URL to load is (as usual) -relative to the web page, while the pathname of the parentFile must be -relative to the JS9 install directory (i.e., where the JS9 helper was -started). In the above example, the web page is one level up from the -JS9 install directory. Once the parentFile has been specified, the -in-memory file should act as a representation file. - -

    -Of course, the two files need to be tied to one another spatially. For -server-side data analysis, having agreement between WCS parameters is -sufficient. In order to use the Bin/Filter/Section plugin, -however, the representation file also must be connected to the parent -file using IRAF LTM/LTV keywords, so that the physical coordinates of -the representation file point to the file coordinates of the parent. -The js9helper program will generate a FITS image section with -the correct keywords. The syntax is: -

    -    js9helper -i parentFile imsection repFile section filter
    -
    -where section can be: -
      -
    • x1:x2,y1:y2[,bin] # specify lo and hi values of the image section -
    • xdim@xcen,ydim@ycen[,bin] # specify center and image dimensions -
    • xdim@0,ydim@0[,bin] # image dimensions taken around center -
    -and filter specifies a column filter for binary tables. For example: -
    -    js9helper -i f814w.fits.gz imsection f814_bin24.fits "12000@0,12000@0,24"
    -
    -was used to generate the binned representation image in the JS9 Large -demo. - -
    Last updated: May 8, 2021
    -
    - - - diff --git a/web/static/js9_old/help/securityissues.html b/web/static/js9_old/help/securityissues.html deleted file mode 100644 index b1af153e26f6da7c2922ec581a6ef2f1da0df489..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/securityissues.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - -JS9 Security Issues - - - -
    -

    JS9 Security Issues

    - -Unresolved Issues: -

    -None -

    - -Resolved Issues: - -

      - -
    1. All platforms (October 28, 2020 : resolved) -

      -A carefully crafted FITS filename could be used by an attacker to execute -arbitrary Javascript. If, for example, the following FITS file is loaded into -JS9: -

      -    JS9.Load("<svg onmouseover=alert(1)>.fits")
      -
      -then moving the mouse over the Statusbar plugin (where the image id is -displayed) will result in the alert being triggered. Similarly, -setting the id explicitly: -
      -    JS9.Load("foo.fits", {"id": "<svg onmouseover=alert(1)>.fits"})
      -
      -will trigger the alert. This vulnerability is present in any plugin -displaying the image id or filename (e.g., the Blend and Blink plugins). -

      -As of v3.2 (and the GitHub repository as of 10/28/2020), a check is -performed to sense dangerous strings in filenames and ids, and throw an error. -Patched versions of js9.js and js9.min.js for v3.1 are available: -

      -

      -Thanks to Marwan Ali albahar (Umm Alqura University) for reporting this issue. - -

    - -
    Last updated: October 28, 2020
    -
    - - - diff --git a/web/static/js9_old/help/serverside.html b/web/static/js9_old/help/serverside.html deleted file mode 100644 index b821d629c8552954b76a31671976a4fab9dd4976..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/serverside.html +++ /dev/null @@ -1,409 +0,0 @@ - - - - - -Server-side Analysis Tasks - - - -
    -

    Adding Server-side Analysis Tasks to JS9

    - -

    -A JS9 web site can define analysis tools that will be loaded into the -user's JS9 Analysis menu. These analysis tasks are then -executed by the back-end (CGI or node.js) server using the original -FITS data, with results sent back to the browser for display. - -

    To learn how to install the back-end helper, see: -Installing a Server-side Helper. - -

    -Analysis tools are defined within files contained in the -analysis-plugins directory. If a file in this directory -ends with a ".json" extension, it is assumed to be an analysis -definition file. The following sample analysis definition files will -be found in the analysis-plugins directory by default: -

      -
    • js9Analysis-fits.json: generic FITS tasks (e.g., display header) -
    • js9Analysis-funtools.json: funtools-based analysis tasks -
    - -

    -The analysis definition files are loaded by the Node.js-based helper on -startup and passed to each newly loaded image. In you change the -definition of a tool in one of these files, or add a new definition -file, you either need to restart the Node helper, or send it a SIGUSR2 -signal: -

    -  kill -USR2 `ps guwax | egrep js9Helper | egrep -v egrep | awk '{print $2}'`
    -
    -Re-initialization is not required for CGI-based support, since the analysis -tool definitions are sent to each image in raw form. - -

    -Analysis definition files are in JSON format -(http://www.json.org/) and consist of an array of JavaScript objects, -one for each analysis tool. The properties which define an analysis -tool are: -

      -
    • name: a short identifier string (typically one word) -
    • title: a longer string that will be displayed in the Analysis menu -
    • files: a rule that will be matched against to determine -whether this task is available for the current image -
    • purl: a URL pointing to a web page containing a user parameter form -
    • action: the command to execute on the server side -
    • rtype: a return type, which can be text, plot, fits, regions, catalog, alert, or none -
    • hidden: if true, the analysis task is not shown in the Analysis menu -
    -See the sample json files in the analysis-plugins directory for the -JSON syntax of this file. - -

    -The files property is a rule that determines whether an analysis task -is available for a particular file. The following rules are defined: -

      -
    • fits: true if the displayed image has an associated FITS file -
    • table: true if the displayed image is a binary table -
    • image: true if the displayed image is an image -
    • fitsHeader(pname,pvalue): true if the FITS header of the displayed image has the named parameter with the specified value -
    • imVar(name,value): true if a property of the displayed image has the specified value -
    • js9Var(name,value): true if the JS9 variable has the specified value -
    • winVar(name,value): true if a variable in the window context has the specified value -
    -Examples: -
      -
    • fitsHeader(INSTRUME,HRC): true if the FITS instrument parameter is "HRC" -
    • imVar(params.wcssys,FK5): true if the wcs system for the current image is FK5 -
    • js9Var(globalOpts.projectName,Chandra_EPO): true if the web page has set the JS9.globalOpts.projectName property to "Chandra_EPO" -
    • winVar(MyProject.name,foo): true if MyProject has a property "name" with the value "foo" -
    -Note that all checks are case-insensitive. - -

    -The action string contains the command to execute. For security -reasons, this action is never executed directly. Instead, the first -argument of the command must be a wrapper script contained in -the analysis-wrappers directory. The js9Xeq wrapper -script contained therein is the default script for running JS9 -analysis. The second argument in the action string is a command id, -which is executed within the command-processing case statement of -the js9Xeq. This wrapper script checks for valid commands and -arguments, and then executes the specified command in a way that -protects against malicious attack. You can modify this script to meet -your needs by adding case statements for each of the new tasks you -want to run. - -

    -Alternatively, you can run your analysis tasks through your own -wrapper script, by placing it in the analysis-wrappers -directory. Using your own wrapper script allows you to perform your -own special setup (e.g., setting environment variables, cd to work -directory) before executing a task. Obviously you can -use js9Xeq as an example and modify it to suit your needs. - -

    -In either case, note that execution of a wrapper script is -accomplished by pre-pending the path of the analysis wrapper directory -to the wrapper script name and executing that full pathname directly. -This prevents a would-be attacker from executing anything except the -wrapper itself. Of course, you still have to be careful to avoid -insecure shell coding in your wrapper script. -See The World -Wide Web Security FAQ for advice on writing CGI scripts. - -Note that JS9 scripts generally use bash or sh. Please make sure your -bash and sh programs are properly patched to protect against the bash -bug (CVE-2014-6271). - -

    -The action command line can contain macros (strings prefixed -with the $ character) that will be expanded by the browser before -the action is sent to the server for processing. Typically, these macros are -used to specify filenames, regions, and (possibly) user parameters. The -following intrinsic macros are defined: -

      -
    • $id: id of the JS9 display -
    • $image: name of the image file being displayed -
    • $filename: pathname of the parent file, if available, or the original FITS file -
    • $filename(this): pathname of the original FITS file, even if a parent is available -
    • $fits: pathname of the original FITS file -
    • $parent: pathname of the parent file, if available -
    • $regions: all currently defined regions -
    • $sregions: all source regions -
    • $bregions: all background regions -
    • $imcenter:center of displayed image in image coords (x,y) -
    • $wcscenter:center of displayed image in WCS coords (ra,dec) -
    -Note that $filename macro will return the pathname of the -parent by default, so that analysis can be done on the parent file. Use -$filename(this) or $fits to return the pathname of the -displayed FITS file, regardless of the presence of a parent. This is -useful if you want to run analysis on the representation file instead -of the parent. -

    -The three regions macros return region info in the current wcs -system. To specify an alternate wcs system, append "physical", -"image", or "wcs" in parentheses, e.g., $regions(physical). -

    -For example, to run the funcnts program, specifying the original FITS -file as well as source and background regions, use: -

    -    funcnts $filename $sregions $bregions
    -
    - -

    -Many analysis tasks do not require the user to select additional parameter -options and can can be executed immediately. Other command require -user-selected options. These latter options should be put into a web -form, whose location is specified by the purl option. See -the params/histplot.html file for an example. - -

    -Parameter options in a parameter form should have unique ids. These -ids can then be added as macros to the action command line by -prefixing them with a $. For example, the histplot command is: -

    -    js9Xeq histplot '$filename[$regions]' '$norm $bwidth' $column $bins
    -
    -Here, the norm, bwidth, column, and bins -parameters are taken from the web form for histplot. The $filename -and $regions macros are intrinsic to JS9. - -

    -The input element of the analysis form should run -the JS9.SubmitAnalysis() command, which will serialize the form, -pass it to the macro expander, and then send the resulting command string -to the server for execution. See histplot.html for sample syntax. - -

    -The rtype property determine how JS9 handles return values: -

      -
    • alert: call JavaScript alert() function on the returned string -
    • catalog: the returned URL to a catalog file is loaded on the current image -
    • fits: the returned URL to a FITS file is loaded (2nd argument can be a parent file) -
    • none: check for an error return, but otherwise do nothing -
    • plot: the returned plot data is plotted -
    • regions: the returned URL to a regions file is loaded on the current image -
    • text: the returned text is displayed in a lightweight window -
    -The text and plot returns are the most commonly used types. -

    -NB: when text is returned, be aware that file pathnames are often output -by programs. For security reasons, you should remove or modify these -pathnames before returning the text. For example, JS9 funtools -analysis routines use a sed command like this: -

    -  sed 's#'${JS9_DIR:-none}'#${JS9_DIR}#g;'
    -
    -to change pathnames containing the JS9 working directory so that they display -the string "${JS9_DIR}" instead. - -

    -Sample scripts such as funcnts2flot and funhist2plot -generate a JSON string that contains a valid flot object. For -example, the radial profile plot contains x, y, and error values: -

    -{
    -  "label" : "surf_bri(...) vs. avg_radius(...)", 
    -  "points" : {"errorbars" : "y", "yerr" : {"show" : "true", "color" : "red"}},
    -  "data": [[x1, y1, e1], [x2, y2, e2], ... [xn, xn, en]]
    -}
    -
    -while the histogram plot contains only x and y values: -
    -{
    -  "label" : "counts vs. ...bin", 
    -  "data": [[x1, y1], [x2, y2], ... [xn, xn]]
    -}
    -
    -If your analysis task generates one of these two plot formats, JS9 -will display the plot data. By default, the plot is generated using -the jQuery flot library (see http://www.flotcharts.org/), which -is supplied with JS9. - -

    -You also can use the plotly library for plotting. To do this, -set the JS9.globalOpts.plotLibrary property to "plotly" and -load the library in the web page header. (Due to its relatively large -size, plotly is not packaged in the JS9 support file.) - -

    -Plotting is still somewhat experimental and rudimentary. For example, -flot (but not plotly) simply uses the x -and y keys to toggle between linear and log scaling. We will -be adding features and improvements with time. Please work with us to -improve plotting support. - -

    -Finally, the hidden value determines whether or not a task is -displayed in the Analysis menu. If hidden value is true, the -analysis task is not shown. However, it still is available to the -JS9.RunAnalysis() routine. - -

    -

    Adding Analysis Tasks Directly to Your Web Page

    -

    -By default, server-side JS9 analysis tasks are executed using -the Analysis menu, but they also can be executed directly from -the web page by means of HTML elements (buttons, forms, etc.) To do -this, a web page author simply creates the desired interface and calls -either JS9.RunAnalysis() (for buttons, menus, etc.) -or JS9.SubmitAnalysis() (for forms). These are described -below. See the js9analysis.html page for an example. - -

    -The JS9.RunAnalysis() routine is used to execute an analysis task and -return the results for further processing within the web page. The -JS9.SubmitAnalysis() routine works similarly, but it is used -with a form: it automatically serializes the form values and passes -them to the analysis macro expander so that these values can be put -into the analysis command line. The calling sequences for these -routines are similar: -

    -    JS9.RunAnalysis(aname, [options], returnFunc);
    -    JS9.SubmitAnalysis(this, aname, returnFunc);
    -
    -where: -
      -
    • aname: the name value of the task (as defined in the js9Analysis.json file) -
    • options: an optional array of parameters to pass to the analysis -macro expander. The array is in jQuery name/value serialized object -format, which is described here: -
      -    http://api.jquery.com/serializeArray/
      -
      -
    • returnFunc: a function to process the returned data when the task is -completed -
    • this: the 'this' value of the form element -
    -

    -The returnFunc() routine is a callback function to process the returned -data from the analysis task. The calling sequence is: -

    -    returnFunc(stdout, stderr, errcode, aobj)
    -
    -where: -
      -
    • stdout: a string containing the standard output from the task -
    • stderr: a string containing the standard error from the task -
    • errcode: error code value from the task or 0 -
    • aobj: the analysis object from the js9Analysis.json file, containing - the rtype (e.g., "text" or "plot") property -
    -Typically, you would check the errcode and/or stderr string first and -issue an error message if there is an error. Otherwise, the stdout -string can be processed based on the return type (rtype) of output -(e.g., "text" or "plot"). For plotting, you can use the flot -functionality that is loaded into JS9, or you can use your own chosen -plotting package. See js9analysis.html for a simple example. - -

    -

    Temporary Work Directories for Users

    -

    -By default, server-side analysis is initiated in the directory in which -Node.js or the CGI script is run. For tasks not creating temp files, -this usually is sufficient. For other cases, it can be desirable to -isolate users in their own temporary work directories. To do this -automatically (i.e. without the task itself having to change -directories), set the following property in the globalOpts object of -the js9Prefs.json file: -

      -
    • workDir: set to the relative path of a directory which -will hold temporary working directories for each loaded web page (default: ./tmp) -
    -The workDir directory should be relative to the directory in -which the JS9 helper is run. This will ensure that you have access -permission to temporary retrieve files via the web server (e.g., -loading a remote file via the LoadProxy() command into a -temporary directory, so that JS9 can subsequently load it via the web -server). This restriction can be relaxed when using the file:// URI, -although some browsers on some operating systems (e.g., Firefox on -Linux) prevent you from loading files outside the web page domain even -with the file:// URI. - -

    -You also can set the following globalOpts configuration parameters in -js9Prefs.json: -

      -
    • workDirQuota: the disk quota on working directory (default: 100Mb) -
    • rmWorkDir: remove workdir when web page disconnects? (default: true) -
    -When workDir is configured, user sub-directories will be created -in the workDir directory to contain temporary files. Analysis -tasks will be started in the work sub-directory. -

    -For Node.js-base helpers, the work directory is removed when the web -page is unloaded. This can be changed by setting rmWorkDir to -false in the preference file. For CGI-based helpers, you must remove -the work directory manually (e.g., using a cron job that checks for -time-last-accessed of work directories). - -

    -Note that the workDirQuota is not a hard quota: JS9 tasks such -as load proxy enforce their own checks using this value. For -example, load proxy only checks whether the quota has been exceeded -before loading the next file. This means that users can load one file -that will bring the total size above the quota. Thus, if the -quota is 10Mb and the work directory is empty, the load proxy will -load a 50Mb file. But it will not more load files until already-loaded -files have been closed in JS9 (and thereby deleted in the temp -directory) so as to bring the total under the quota. - -

    -

    The Proxy Load Service

    -

    -NB: use this service with care. It allows users to consume disk resources! -

    -For security reasons, JavaScript contained in one web page can -access data in another web page only if both web pages have the -same origin (i.e., basically coming from the same host). This -policy is called the - -Same Origin Policy. This means that JS9 cannot load a FITS file from -an arbitrary URL without using special techniques. -

    -One such technique is to use a proxy server: the URL is not loaded -directly into JS9, but instead is copied back to the server from which -JS9 itself was loaded. The file is then retrieved by JS9 so that the -"same origin" rules are not violated. -

    -A CGI or Node.js back-end server can be set up as a proxy server by -setting the following globalOpts properties in the js9Prefs.json file -(before starting the server): -

      -
    • loadProxy: set to true to enable proxy load (default: true) -
    • workDir: see above -
    • workDirQuota: see above -
    • rmWorkDir: see above -
    -

    -When the back-end server supports the proxy service, you will see a -menu option in the File menu called open link via proxy ... -

    -Enter a FITS URL into the proxy dialog box and press the Load -button. The data file will be retrieved by the server and stored in a -directory specifically tied to the web page. (The directory and its -contents will be deleted when the page is unloaded.) JS9 then will -load the file from this directory. Note that since the file resides on -the back-end server, all back-end analysis defined on that server is -available. -

    -This technique can also be used FITS links from other sources. For -example, if you have a FITS file on Google Drive, Dropbox or even a -static web page, you can generate/copy the link and paste it into the -proxy dialog box for display. (Dropbox files also can utilize -the open link via CORS ... option, which downloads the data -directly to JS9, bypassing the proxy server.) -

    -Note that individual proxy FITS files are deleted from the working -directory when they are closed in JS9 using the File:close -image menu option. - -

    Last updated: June 1, 2021
    -
    - - - diff --git a/web/static/js9_old/help/user.html b/web/static/js9_old/help/user.html deleted file mode 100644 index 4b3d47e9ba3e49dfdef7050ed44eac9db765a1dc..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/user.html +++ /dev/null @@ -1,885 +0,0 @@ - - - - - -The JS9 Help Facility - - - -
    -
    -

    JS9: astronomical image display everywhere

    -Eric Mandel, Alexey Vikhlinin -
    -Center for Astrophysics | Harvard & Smithsonian -
    -Cambridge, MA 02138 -
    - -

    -

    Introduction to JS9

    -

    - -JS9 is the latest in the SAOimage line of astronomical image display -programs developed at -the Center for Astrophysics | -Harvard & Smithsonian (CfA.) Our previous effort, -SAOimage DS9, has been -the de facto standard desktop image display for more than 30 -years. Now, with JS9, you can view and manipulate astronomical image -data in your browser as well as on the desktop. -

    -Please choose from the following topics: -

    - -

    - -

    Getting Started with JS9

    -

    -JS9 provides astronomical image display capabilities both on the -desktop and in your browser. JS9 takes its name as well as its core -functionality from the de facto standard -DS9 image display -program for desktop use. JS9, on the other hand, can be run either on -the desktop or in a browser. It also can be used without any -installation at all by dragging/dropping a FITS file onto the -JS9 website. In all -three cases, the JS9 display consists of one or more HTML components -that are added to a web page. At a minimum, the JS9 display will -contain an image display canvas. It usually also will display a -menubar containing several pull-down menus and a -colorbar. Traditionally, the menubar is placed on top of the image -canvas and the colorbar below, but web page designers (as well as -individual users) have complete control over component placement. JS9 -also can display an info box, a command-line window, a pan window, a -zoom window, as well as other plugins. All of these plugin windows can -be brought up dynamically from the View menu. - -

    -Astronomical image data usually is offered on a JS9 web page as one or more -clickable URLs. When you click on a data URL, it is displayed on the JS9 image -canvas. Multiple images can be loaded into a single JS9 display. The File -menu allows you to switch between these images. - -

    -Once an image is loaded, you can move the mouse (or a single finger on -a touch screen) to display position and pixel value information. -Pressing the left mouse button and moving the mouse (or using two -fingers on a touch screen) will change the contrast/bias of the -displayed image, bringing image features into relief. - -

    -These mouse/touch actions are configurable, both by web page -developers and by users. See -the Mouse Touch plugin for -more information. - -

    -Menu options allow you to change the scaling algorithm and/or color -map, add geometric regions of interest, change world coordinate system -(WCS) parameters, and run site-specific astronomical analysis tasks on -the original FITS data. - -

    - -

    JS9 Menus

    -

    -The following menus are in the default JS9 menu bar. Of course, web -designers have control over which menus are displayed (or even whether -the menu bar itself is displayed.) Thus, not all of the menus listed below -will be found on all JS9-enabled web pages. - -

    -Some menu options have keystroke accelerators and these are shown on -the right-hand side of the menu option. Thus, for example, to open a -local file, you can select the File:open...:local file menu -option, or press the Meta-o key combination when the mouse is -inside the JS9 display. - -

    -Note that the default menubar has a style in which all of the -major menus are shown at the top-level of the menubar. This is -the classic style. JS9 also supports a mac style -menubar, in which the File, Edit and View menus -are placed on the left side of the menubar and the Help menu on the -right. The other main menus are displayed as submenus within -the View menu. - -

    -The default top-level JS9 menus are: -

      -
    • File: The File menu displays the currently loaded images, -either directly in the menu, or, if there "too many" images (as -defined by the JS9.globalOpts.imagesFileSubmenu variable), using -an images submenu. The displayed image is marked with a -starburst. To display a different image, simply choose it from the -menu. The File menu also contains the following submenus and options: -

        - -
      • open local... bring up a file browser dialog box to choose a FITS,PNG, or JPEG file for display - -
      • open remote ... bring up a dialog box to load a remote URL either using a JS9 proxy server (if configured), the cgi proxy on js9.si.edu, or directly using a CORS-enabled server (if available) - -
      • display ...: components and sections: -
          -
        • FITS header display FITS header of the current image -
        • FITS HDUs display a list of HDUs in a multi-extension FITS file -
        • refreshed image an advanced option that will call the -internal redisplay routine for the displayed image (useful, for -example, if you are reprocessing the image on disk and want to view -the new data) -
        • full image an advanced option that tries to -load and display the entire image (might cause the page to crash if -the image is too large) -
        • selected cutouts selected region(s) are used to define the center and size of new image section(s); note that image sections are always rectangles and region angles are ignored -
        • display pageid, a unique ID for this page that can be used to communicate externally with a JS9 instance when multiple JS9 instances are running (js9 --pageid [pageid]) -
        - -
      • move ... move the current image to an existing displays or -a new display. (The new display will either be a in a light window or -a CSS grid, depending on how the web page is constructed.) - -
      • separate ... separate/gather two or more images -
          -
        • separate these images move each image in this display to a -new display. (The new display will either be a in a light window or a -CSS grid, depending on how the web page is constructed.) -
        • gather all images here move all images from other displays to this display -
        - -
      • save ...the currently displayed image data. You can save -the currently loaded image (or the currently loaded image section, if -an image section was extracted) in standard FITS image format. Or you -can save only the currently displayed image section in any of the -following formats: -
          -
        • FITS (standard astronomical image file, without 2D graphics) -
        • JPEG (also includes 2D graphics, such as regions) -
        • PNG (also includes 2D graphics, such as regions) -
        - -
      • close ... one or more images (or internal image memory) -
          -
        • this image to clear the current image and release browser resources -
        • all images to clear all images and release browser resources -
        • free image's memory free up memory used to store the FITS file internally (which is needed for WCS reprojections, viewing FITS extensions and data cubes) -
        • proxy file to clear a server proxy file and release browser resources -
        - -
      • catalog ... load or save catalogs -
          -
        • load ... load a tab-delimited catalog file into the display -
        • save active save the currently active catalog (Shape Layers plugin has more general support) -
        - -
      • mosaic ... create a mosaic image using: -
          -
        • images in the current file -
        • images in this display -
        - -
      • session ... load or save sessions -
          -
        • load ... load a previously saved local session file into the display -
        • save ... save information about the current image or all images loaded into this display: filename, scaling, colormap, contrast/bias, zoom, regions, catalogs, etc. are stored in a json file -
        - -
      • window ... create a new JS9 display window: -
          -
        • light window create a light window containing a JS9 instance -
        • separate window create a separate window containing a JS9 instance -
        - -
      • remove this display close images and remove this display. This -option is available for displays contained in light windows and for displays -contained in JS9 Grid Containers (although the latter requires that at least -one display to remain in a container.) The display is removed immediately -and without a confirmation dialog box (unlike a light window being closed -via its close button.) - -
      • print ... print the current image display window (including 2D graphics) -
      - -
    • Edit: allows you to copy and paste regions, positions, -and pixel values to/from the clipboard: -

        -
      • edit if a single region is selected, display its edit window; -if multiple regions or no regions are selected, display the multi-region window; -
      • copy copy selected region(s) (or all regions, of none are -selected) to the system clipboard, so that you can transfer to other -JS9 displays or to programs outside of JS9 -
      • paste to current pos paste previously copied region(s) to -the current mouse (or arrow key) position in a JS9 display. Usually -you would use the keyboard shortcut (currently 'p') for this -sort of pasting, but you also can use the meta key to freeze the mouse -position and then use this menu option -
      • paste to original pos paste previously copied region(s) to -their original region position(s), usually in another JS9 display. -
      • undo remove restore the last removed region (or set of removed regions, if more than one was removed in a single operation) -
      • copy wcs pos copy the current WCS position to the system clipboard -
      • copy value/pos copy the current pixel value and WCS position to the system clipboard -
      - -
    • View: displays a list of available plugin, including the following core options: -

        -
      • Archive and Catalogs: allows you to display image data retrieved from various archives and overlay catalog information. -
      • Bin/Filter/Section: supports binning and column filtering on FITS binary tables. -
      • Blending: combine selected images using a specified blend -mode and optional opacity. -
      • Colormaps: create compatible colormaps from a specified color -
      • Console: will bring up a movable, light-weight -console window into which JS9 commands can be entered. -
      • Contours: generate contour maps -
      • Data Cube: display slices of a 3D FITS -data cube. -
      • Extensions: display images from a FITS multi-extension file. -
      • Imarith: simple image arithmetic between images -
      • InfoBox: allows you to display value and position -information in a separate light-weight window. -
      • Keyboard Actions: view the current mapping between keys and actions -
      • Magnifier: will bring up a movable, -light-weight window showing a blocked image of the data in an area -surrounding the mouse as it moves. The default magnification of four -can be changed using command buttons on the magnifier window. -
      • Mouse/Touch: allows you to change the -actions performed when you move the mouse over an image with zero, -one, or two buttons pressed. It also configures touch actions using -one, two, or three fingers. -
      • Panner: will bring up a movable, -light-weight panner window that displays the full image along with a -viewport rectangle showing the currently displayed image section in -the primary image window. The viewport can be moved around in order to pan -to different locations in the primary image. The panner also has -command button options to zoom the viewport itself. (This makes -the viewport rectangle larger at the expense of displaying only a -section of the full image. It is useful for panning in a very large -image.) -
      • Pixel Table: displays an array of pixel values around the current mouse position. -
      • Preferences: set preferences for this session (and/or save for future sessions) -
      • Separate/Gather: separate images in this display or gather images into this display -
      • Shape Layers: displays the layers defined for the current -image and allows you to turn on and off the display of any layer. -
      • Show/Hide Plugins: displays the currently active plugins and allows -you to hide plugins defined statically on the web page. -
      - -

      -The View menu also contains the following Display -Options submenus: -

        -
      • show ... options on the display: -
          -
        • value/position ... a submenu of options for displaying -the current value/position, including: -
            -
          • update value/position: specifies whether the image position -and pixel value is displayed as the mouse (or finger) moves over -the image. By default, this information is displayed in the upper left -of the image. The display can be moved anywhere inside the JS9 window by -clicking on it with the mouse and moving. You also can redirect the -display to a movable, light-weight window by choosing the -InfoBox menu option. -
          • value/pos color: allows you to change the color of the -value/pos display. You can enter color names (e.g., red, lightgreen, steelblue, -cyan) or values in #RRGGBB format (e.g., #00FF00 is the default bright green). -
          • also show display coords: specifies whether display coordinates -are shown in the value/position display when the WCS sys is set to "image". -
          -
        • active shape layers: toggles display of shape layers -
        • crosshair for this image: displays a -crosshair at the mouse position when the Shift key is held down -(without the Shift key on iOS devices.) It is turned off by default. -
        • match wcs crosshairs: displays a crosshair in -other JS9 displays, matching the WCS position of the mouse in this display -(assuming the other image has its own crosshair enabled.) -
        • toolbar tooltips: specifies whether tooltips -are displayed as the mouse hovers over an icon in the Toolbar -plugin. (For mobile devices, a single tap will display the tooltip, -requiring a second tap to execute the toolbar action.) -
        • new image inherits current params: specifies whether -a new image grabs the image params (e.g., colormap, scale, zoom, etc.) -from the currently displayed image. If false, these params are taken -from the default JS9.imageOpts object. -
        -
      • resize ... options to resize the display: -
          -
        • change width/height specify a new width and height for the -JS9 display. -
        • set to image size: set display to current image size -
        • set size to full window: set display to browser window size -
        • reset to original size: set display to its original size -
        -
      - -
    • Zoom: The zoomIn and zoomOut menu options -zoom the primary image in or out by a factor of -two. The zoomToFit options calculates a zoom factor that fits -the entire image into the JS9 display. You also can set the zoom -factor to a pre-specified value using menu options or you can specify -a floating point zoom factor in the other zoom text -box. The pan to center option pans to the center of the image, -while the reset pan/zoom sets the zoom to 1 and centers the -display. - -

      -The align pan/zoom ... submenu allows you to change the pan and -zoom of the current image to match a target image, assuming both have -WCS info available. Pixel size (i.e. as specified by the FITS CDELT1 -parameter) will be taken into account when zooming, but not image -rotation or flip (from the WCS params.) This is quicker than -the wcs reproject algorithm for aligning images that are -similar. - -

      -The Zoom menu also supports image flip around the x or y axes, -image rotation by +/- 90 degrees or by an arbitrary -angle. There also is an option to rotate the image so that north is up -in the current coordinate system. Flipping and rotation are performed -on the displayed pixels (so no change is made to the WCS). The -rotation is much faster than the more general WCS-based -rotation/reprojection in the WCS menu. Note that arbitrary -rotation is performed in terms of an absolute angle: if you rotate by -20 degrees and then do it again, there is no change. Also, setting the -rotation to 0 sets the angle to 0. Flipping and rot90, however, are -relative to the current state of the display. This differs from DS9, -where the actions are linked to the x and y axes. Thus, flipping by x -twice will return you to the original orientation, whereas flipping a -second time does nothing in DS9. - -

    • Scale: Each scale option specifies a different scaling -algorithm to use when converting image pixel values to RGB -values. (The procedure for doing this conversion is detailed in the -DS9 documentation titled "How It Works".) The log scale, for example, is -especially useful with X-ray data. Histogram equalization (histeq) -tries to maximize contrast across the range of data values and is -useful in a wide variety of cases. The current scale is marked with a -starburst. - -

      -You also can change the low and high values used to clip the image -data before scaling by changing the low and/or high -values in the text boxes of the Data Limits section. These values are -set initially with the data's min and max values or the z1,z2 values -calculated by the IRAF zscale algorithm (depending on the value -of the web site's JS9.imageOpts.scaleclipping parameter. The -default usually is "dataminmax".) Finally, you can use the -Scale Controls plugin to set the clipping values -to data min/max, zscale z1/z2 or zscale z1/max, or set the clipping -values using the pixel distribution plot. - -

    • Colormap: Each colormap option specifies a different -distribution of RGB values to use when converting image pixel values to RGB. -(The procedure for doing this conversion is detailed in the -DS9 documentation titled "How It Works".) Choose the colormap you like best, -or try different ones to see how data features can be brought to the fore -by color and contrast/bias. - -

      -The image filters menu option displays the JS9Filters -plugin, which offers a number of well-known image processing functions -that act directly on the displayed RGB image data (not the underlying -raw astronomical data, as with the Gaussian blur in the Analysis -menu.) Thus, when you can run one of these routines on an image, its -effect will be undone if you redraw the image by changing the -contrast/bias, colormap, etc. Also, since these functions act on the -current RGB image, their effect is cumulative. See the -JS9.FilterRGBImage() section in -the JS9 Public API for more information -about the individual functions. Note that not all functions in the -public API call are implemented here: some of them seemed pretty -useless for our data (they can be added easily.) - -

      -You can enter a floating point value into the contrast and -bias text boxes to set the contrast/bias. Note that the -contrast value ranges from 0 to 10 and the bias ranges from 0 to 1 -(following DS9 conventions.) - -

      -The reset contrast/bias option restores the original -contrast/bias value (which is especially useful if you changed the -contrast/bias or scale and now can't see any features at all!) - -

      -The opacity option allows you to set the overall opacity for all -pixels in the image. Values range from 0 (transparent) to 1 (opaque.) More -opacity options can be found in Color Controls (see below.) - -

      -The load option brings up a File menu from which you -can choose a user-defined colormap to load. - -

      -The save option saves the active colormap definition -for the currently displayed image to a file (useful for editing to -make a new colormap.) - -

      -The invert option inverts the colormap (e.g., in the gray map, -this will change white to black and vice versa.) - -

      -If you have three images of the same size, scale, and pointing -direction (e.g., three energy cuts of a Chandra data set), you can -display each one separately and assign to them one of the red, -green, or blue colormaps. If you then select the rgb mode -menu option, they will be displayed as one RGB composite image. The -current image (as shown in the File menu) determines which of -the three independent colormaps is changed by the contrast/bias -manipulation. To remove an image from the RGB composite, give it a -different colormap. Re-join (or add a new image) by assigning one of -the RGB colormaps. Simply turn off RGB mode to display the images -separately. - -

    • Regions: Astronomical regions format is described -here. -Choose the appropriate menu option to create a -region of type annulus, box, circle, ellipse, -line, point, polygon, text. -(see below for details on how to use regions.) One or more regions can -be created and manipulated on a single image. - -

      -By default, a region is created in the center of the image when it is -selected in the Regions menu. You can turn off auto-creation by -deselecting the menu adds region @ center option. With -auto-creation turned off, the 'a' key will add the last selected -region at the current mouse position. - -

      -The list menu option will display all regions. - -

      -The load ... menu option will load a file of regions and -display them on the current image. Regions can be specified using the -a dialect of the widely-used DS9/Funtools regions format, as described -here. - -

      -The save ... display a dialog box allowing you to save selected -or all regions in one of these formats: -

        -
      • regions text file in astronomical regions format -
      • csv comma-separated values -
      • SVG text file in SVG/XML format (useful for importing into -programs such as Photoshop for further processing) -
      -NB: The file will be saved in the folder where your other browser -downloads are stored. - -

      -The copy to ... menu option will copy regions from the -current image to a specified image (or to all images.) If one or more -regions are actively selected in the current image, they alone will be -copied. Otherwise, all regions will be copied. - -

      -The remove menu option will delete all regions. - -

      -The selected regions ... submenu contains options that apply to -the selected region(s), including the ability to edit, list, save, -remove, or copy the selected region(s). The submenu also allows you -to change the following properties of selected regions by entering text values: -

        -
      • color: the color of the region, using either a name -("wheat") or #rrggbb syntax ("#f5deb3".) -
      • width: the numeric width of a region -
      • dash: two comma or space-delimited numeric values specifying the -numeric width of a filled segment, followed by the width of a blank segment -
      • tags: replacement tags for this region -
      -

      -The selected regions submenu also supports the ability to toggle the -"source"/"background" or "include"/"exclude" tags (which is heavily -used in X-ray astronomy.) - -

      -The onchange submenu contains the following options: -

        -
      • list on change: all regions are listed whenever one changes -
      • xeq on change: toggle whether region onchange callbacks are called -
      - -
    • WCS: Use this menu option to select a world coordinate -system when displaying pixel positions and regions (assuming -the data file supports WCS.) Available systems are: FK4, FK5, -ICRS, galactic, or ecliptic. The native -option chooses the system stored in the data file. The image -and physical systems will display only image coordinates (not -WCS coordinates.) Physical coordinates are tied to the original -(block 1) file coordinates while image coordinates are tied to -the current image data being displayed. Server-side X-ray analysis -routines operating on the original file generally want physical coords -rather than image coords. Browser-based plugin routines generally use -image coordinates to operate on the in-memory image data. - -

      -You also can choose the units in which WCS information is displayed: -degrees, radians, or sexagesimal. Image and -physical coordinates are displayed in units of pixels. - -

      -The alternate wcs menu option allows you to choose an alternate -world coordinate system, if one or more are defined in the current -FITS file. The submenu lists the WCS version (i.e. the letter "A" - -"Z", or "default") and, if present, the WCSNAME header parameter -associated with this WCS. - -

      -The reproject menu option allows you to reproject the -image using the WCS associated with another displayed image. The -reprojected data is placed in a new raw data layer called -"reproject". You can switch between layers using the View->raw data -layers option. If the display wcs-aligned option is set, -the reprojected image will be aligned with the wcs reference image. If -you change the pan/zoom of the latter, the former will be re-aligned. -(The converse is not true: changing the reprojected image does not -change the wcs reference image.) You can also reproject other images -in this display using the WCS info from the currently displayed image. - -

    • Analysis: -JS9 supports both client-side analysis (i.e., -analysis in the browser) and server-side analysis (where requests are -made to a back-end server, and returned results are displayed in the -browser.) - -

      -Client-side analysis tasks can be written using the JS9 -Plugin capability, and -the Analysis menu lists the currently loaded Analysis -Plugins. For example, JS9 supplies the -Imexam plugin, which offers the following tasks: -

        -
      • 3dPlot -
      • Encircled Energy -
      • Histogram -
      • Radial Proj -
      • Region Stats -
      • X Proj -
      • Y Proj -
      - -

      -JS9 supplies a few other client-side analysis tasks: -

        -
      • Coordinate Grid: display a WCS-based coordinate grid. The -coordinate grid parameters can be changed using the Preferences -plugin in the View menu. -
      • Counts in Regions: Run the -regcnts -program (compiled into the browser using - -Emscripten) on the specified -source and background regions and return a text display. This is the -same task as the server-side task, but running on the internal FITS file. -(Currently disabled for iOS.) -
      • Radial Profile: Run the -regcnts -program (compiled into the browser using - -Emscripten) on the specified -source and background regions and return a plot display. The source -regions consist of circles. This is the same task as the server-side -task, but running on the internal FITS file. -(Currently disabled for iOS.) -
      • 3D Counts in Regions: Run the -regcnts -program (compiled into the browser using - -Emscripten) on the specified -source and background regions for each slice in a 3D data cube and return a -text display. -(Currently disabled for iOS.) -
      • 3D Plot using Regions : Run the -regcnts -program (compiled into the browser using - -Emscripten) on the specified source and background regions for -each slice in a 3D data cube and plot the background-subtracted results. -(Currently disabled for iOS.) -
      • Gaussian Blur: enter a sigma (radius) to create a new raw -data layer called "gaussBlur", in which the image pixel values are -blurred using a Gaussian function with the specified sigma. The -routine uses the fast Gaussian blur algorithm (approximating a full -Gaussian blur with three passes of a box blur) described -here. -
      - -

      -In addition, each JS9 site can define server-side analysis -tasks to be run from the Analysis menu. Server-side tasks are of two types: -

        -
      • immediate tasks: These tasks are executed directly and -immediately from the Analysis menu. No parameter setup is needed. -
      • parameter tasks: These tasks bring up a lightweight -parameter window allowing various parameters to be set before -executing the task. Parameter tasks are identified by the presence of -an ellipsis (...) after the task name. -
      -

      -For example, the JS9 web page at -https://js9.si.edu -offers the following tasks: -

        -
      • FITS Header(s): Display all FITS headers for this FITS file. -
      • Counts in Regions: Run the -regcnts -program on the specified -source and background regions and return a text display (immediate task.) -
      • Radial Profile: Run the -regcnts -program on the specified -source and background regions and return a plot display. The source regions -consist of circles or annuli (immediate task.) -
      • Energy Plot: Create a histogram of the pi column (or energy -column for Chandra data) of a binary table and return a plot display -(immediate task.) The column must exist in the data file (e.g., -Chandra ACIS data but not Chandra HRC data.) -
      • Light Curve:Create a histogram of the time column of a binary table -and return a plot display (immediate task.) The time column -must exist in the data file. -
      • Histogram Plot: Create a histogram of the user-specified -column of a binary table and return a plot display (parameter -task.) Parameters include: histogram column name, number of bins, use -bin width instead of bin size, and an option to normalize by bin -width. A help file is appended to the parameter display. -
      • Event Filter: filter the events of a binary table and return -an image representation of the filtered events. Note that when a FITS file -is loaded directly into JS9, you can use the Binning/Filtering plugin -to filter events instead. -
      -

      -If you drag and drop a FITS file onto a JS9 web page connected to a -remove server (such as -https://js9.si.edu), -the FITS file will, of course, not be accessible on the server (it's only -stored in the browser.) As a result, no server-side analysis tasks will -be available. But if the remote server supports proxy loading -of FITS data, the Analysis menu will display an option to upload FITS to -make tasks available. Select this option and your FITS file will -be sent to the server so that server-side analysis can be performed. - -

      -The server-side params submenu contains the following options: -

        -
      • set data analysis path ...: specify a colon-separated list -of directories for JS9 to search when looking for FITS data files that -have been dropped onto the display. This is used by JS9 when -performing server-side data analysis on local drag-and-drop FITS -files. It is necessary to specify data paths explicitly since web -pages are not allowed to determine the pathname of such files -automatically (for obvious security reasons.) -
      • set this image file's path: for local servers only, set the -path (absolute or relative to the displayed web page) of an image file -loaded via Drag and Drop or Open Local File. For -security reasons, browsers do not expose the path of files loaded in -these two ways. However, for a local web page, you can safely specify -the image path in order to refresh the image or run server-based -analysis. -
      - -
    • Help: Show this and other JS9 help pages. The Help menu -also contains help for Plugins, including the Imexam plugins -listed above. -

    - -

    - -

    JS9 Mouse Interaction

    -

    -In keeping with the needs of mobile devices, JS9 utilizes a single -mouse button for user interaction. Keyboard input also is minimized. -Moving the mouse (or a single finger on a tablet) over the image will -display the position/value of individual pixels. Pressing and moving -the mouse (or two fingers) will change the contrast and bias of the -image. A double-click (or double-tap) inside a region will bring up -the configuration menu for that region. - -

    - -

    JS9 Regions

    -

    -Regions are geometric shapes that can be used to mark part of an image -for analysis. JS9 allows you to create the following region -types: annulus, box, circle, ellipse, line, point, polygon. -A text region also can be created to annotate an image. When one -of these options is selected, the region is created in the center of -the image. It then can be dragged to the desired location. Arrow keys -also will move the region one screen pixel in the specified direction. -A selected region can be deleted by pressing the Delete key (where -available. On a tablet, use the delete option in the configuration menu.) - -

    -Click inside a region to select it and display the resize/rotate -controls around its perimeter. Grabbing a handle allows the size of -the region to be adjusted or rotated. In the case of the box and -ellipse regions, the width and height are controlled separately. Click -outside the region to de-select (or click another region to select -that one.) - -

    -For a line region, the end-points serve as both resize controls (arrow -icon) and stretch points (hand icon.) You might have to move the mouse -around a bit to switch from one to another. The control action is to -resize the region in both directions (i.e., the same as other regions.) -The stretch action allows you to move this end-point while the other one -remains fixed. - -

    -A double-click inside a region brings up a configuration menu. You can -change various values associated with a region by entering new values -in the appropriate text boxes and the clicking Apply. - -

    -The configuration menu has the following standard options: -

      -
    • id: the id of this region, which can be used programmatically to select it for processing (read-only) -
    • type: the type of region (read-only) -
    • image center: new image pixel values can be entered to change the region position -
    • WCS center: new WCS position values can be entered to change the region position (where WCS is available) -
    • Text: create a child text region with the specified text -
    • Color: change the color of the region (color name or #RRGGBB syntax) -
    • Tags: the default tags (source, background, include, exclude) -are used in X-ray astronomy but you can enter any string to tag this region and then select programmatically using tags -
    • WCS Region: the WCS representation of this region, where applicable (read-only) -
    • Image Region: the image representation of this region, where applicable (read-only) -
    • Misc Properties:use JSON format to specify shape properties not listed above (e.g., {"transparentCorners": true}, see Fabric.js for more info on shape properties.) -
    • Options: -
        -
      • Changeable: enable/disable move and resize capability -
      • List On Change: list this region when it's moved or resized -
      • Remove: remove this region. On an iPad, this currently is -the only way to delete a region. -
      -
    -

    -In addition, regions of different type support specific configuration -parameters in this menu. -
    -The annulus region supports: -

      -
    • Radii: change the radii of the region (in pixels) -
    -The box region supports: -
      -
    • Width: change the width of the region (in pixels) -
    • Height: change the height of the region (in pixels) -
    • Angle: change the angle of the region (in degrees, counter-clockwise) -
    -The circle region supports: -
      -
    • Radius: change the radius of the region (in pixels) -
    -The ellipse region supports: -
      -
    • Radii: change the r1 and r2 radii of the region (in pixels) -
    • Angle: change the angle of the region (in degrees, counter-clockwise) -
    -The polygon and line regions support: -
      -
    • Points: change the image points of the region (in pixels) -
    • Angle: change the angle of the region (in degrees, counter-clockwise) -
    -The text region supports: -
      -
    • Text: change the text of the region -
    • Angle: change the angle of the region (in degrees, counter-clockwise) -
    -A discussion of how JS9 implements DS9/Funtools regions syntax can be found -here. - -

    - -

    Meta Key Accelerator

    -

    -The meta key is the Command key on a Mac and the Control -key everywhere else. - -

    -Pressing the meta key disables the value/position display. -It also disables execution of plugin callbacks on -all mouse events. See Local Tasks for -more information about plugins and browser-based analysis. - -

    -When a keyboard is available, pressing the meta key while -clicking in the primary image window will pan the image so that the -mouse location is in the center of the display (this panning is -disabled inside a region.) - -

    -Within a polygon or a line, if you press meta and click the -mouse on the polygon or line border, a new point will be added at that -point. If you press the meta key and click on an existing -point, it will be deleted. - -

    -Within an annulus, if you press meta and click the mouse, the -annuli of the annulus region are replaced by an equivalent set of circles -which can be resized (or deleted) individually, but not moved. -Press meta and click the mouse again to finalize the region with the -new annuli. Press shift-meta and click the mouse to cancel -the edit and restore the original annuli. - -

    - -

    Drag and Drop Images

    -

    -You can drag and drop FITS images and binary tables, PNG images, and -JPEG images onto JS9 to display the image data. All browser-based -functions (scaling, colormap, pan, zoom, regions, WCS) should work as -expected. You can execute server-side analysis tasks on the FITS files -if the back-end server is running on your local host machine. In this -case, you probably will need to set your DataPath variable in the -Analysis menu to help JS9 locate the original data file. - -

    - -

    Resizing the JS9 Display

    -

    -The JS9 Display can be resized using the the View:resize:change -width/height menu option (or the JS9.ResizeDisplay() JavaScript -routine.) The View menu's resize parameter can be two values (width -and height) or a single value representing both. In addition, if an -image containing wcs info is being displayed, you can append a single -quote to specify a size in arc minutes (e.g., 5') or a double quote to -specify a size in arc seconds (e.g., 300".) -

    -The View:resize:set to image size option will set the display size to -the size of the current image. The View:resize:set size to full -window option will resize the JS9 display to the size of the -browser window's window.innerWidth and window.innerHeight properties, -and will scroll the display to the center of the window. (Note that -the rest of the web page is still available via scrolling, including -the menubar.) The View:resize:reset to original size option will set -the display size back to the original size. Display resize can be -turned off by setting the JS9.globalOpts.resize variable -to false in the js9prefs.js file. -

    -Also by default, the JS9 Display can be resized using a grab handle in -the lower right-hand corner of the display. This feature can be -turned off setting the JS9.globalOpts.resizeHandle variable -to false in the js9prefs.js file. -

    -See Known Issues -for a discussion of limitations imposed on resize by Webkit -browsers such as Chrome and Safari. - -

    Last updated: June 8, 2021
    -
    - - - diff --git a/web/static/js9_old/help/webpage.html b/web/static/js9_old/help/webpage.html deleted file mode 100644 index b6aa1ced798193f2cae5487bd6a63d8fcbea65fd..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/webpage.html +++ /dev/null @@ -1,473 +0,0 @@ - - - - - -Creating a JS9 Web Page - - - -
    -

    Creating a JS9 Web Page

    - -

    Intro to JS9-enabled Web Pages

    -

    -A JS9-enabled web page contains JS9 header directives to load JS9 -Javascript and CSS files, and at least one HTML "div" element of class -JS9 in the body to provide a JS9 display. Other div elements can be -supplied to define additional displays, menubars, statusbars, and -various other plugins. - -

    -When a JS9-enabled web page is loaded, a routine is called to -initialize the JS9-class divs and their underlying support -routines. You can arrange to load one or more images automatically -when JS9 is fully initialized. You can even specify an image to load -as part of the web page query parameters. - -

    Adding JS9 to Your Web Page

    -

    -The sample js9basics.html file shows how to add JS9 to a web page by -assigning JS9 CSS classes to div elements. The js9multi.html web -page goes further by showing how multiple instances of JS9 can be -added using unique IDs. - -

    -To start, a few JavaScript and CSS files must be loaded into the web -page. Ordinarily this is done in the page's header, which typically -will look something like this: -

    -  <head>
    -  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    -  <meta http-equiv="X-UA-Compatible" content="IE=Edge;chrome=1" > 
    -  <meta name="viewport" content="width=device-width, initial-scale=1" >
    -  <link type="image/x-icon" rel="shortcut icon" href="./favicon.ico">
    -  <link type="text/css" rel="stylesheet" href="js9support.css">
    -  <link type="text/css" rel="stylesheet" href="js9.css">
    -  <script type="text/javascript" src="js9prefs.js"></script>
    -  <script type="text/javascript" src="js9support.min.js"></script>
    -  <script type="text/javascript" src="js9.min.js"></script>
    -  <script type="text/javascript" src="js9plugins.js"></script>
    -  </head>
    -
    -The js9prefs.js file is optional. It contains a JS9Prefs object that -holds various default settings for JS9, e.g. default colormap and -scale for image display. Feel free to edit this file to set up your -own site-specific parameters. See -JS9 Site Preferences for a -description of the available parameters. - -

    -Order is important: The js9prefs.js file must be loaded first. The -js9support.min.js must be loaded before you load js9.min.js. You must -load the plugin files after you load js9.min.js. You can simply copy -the order of files as specified in the JS9 demo files. - -

    -You can, of course, arrange to have your web server gzip the javascript -files, using browser-based capabilities to ungzip them automatically. The -JS9 web site serves pre-compressed content, as described in the - -Apache Module mod_deflate page. - -

    -The text file js9support.txt is a list of the files contained -in js9support.css, js9support.js, js9support.min,js, and js9plugins.js. - -

    -The js9support.min.js file contains a number of required third-party -software modules, including jQuery, fabric.js (2D graphics), flot (for -plotting), dhtmlwindow (for light windows), etc. It is separated from -js9.min.js to optimize file caching. Although JS9 will not run -properly without these third-party modules, you are free to load them -manually, i.e., without loading js9support.min.js itself. A manual -load is useful in cases where you want a different version of one of -the third-party modules (e.g., js9support.min.js loads jQuery 1.12.2, -but you need to utilize jQuery 1.11.3). In such a case, we still -recommend creating a single file to hold third-party modules, in order -to minimize load latency. - -

    -JS9 will run without the js9plugins.js file, but with much -restricted functionality. In particular, core plugins such as -blending, blinking, colorbar, data cube, magnifier, panner, etc. are -loaded from this file, as are analysis plugins such as encircled -energy, radial projection, region statistics, and 3D plot. Note that -the regions and mouse/touch core plugins are always loaded from within -js9.min.js itself, since they are essential to almost all JS9 -functionality. - -

    -All of these Javascript plugin files are contained in the plugins -subdirectory, so you can load them individually, e.g.: -

    -  <script type="text/javascript" src="js9prefs.js"></script>
    -  <script type="text/javascript" src="js9support.min.js"></script>
    -  <script type="text/javascript" src="js9.min.js"></script>
    -  <script type="text/javascript" src="plugins/core/menubar.js"></script>
    -  <script type="text/javascript" src="plugins/core/info.js"></script>
    -
    -will load only the menubar and info display plugins. - -

    -During startup, JS9 will asynchronously load the js9worker.js -file in order to create a worker process. It also will load either -the astroem.js file or the astroemw.js -and astroemw.wasm files, depending on whether -WebAssembly is supported on your browser. -Therefore, if you install JS9 manually (i.e., not using the standard configure, -make, make install sequence), please ensure these files are installed as well. - -

    -The main JS9 display as well as JS9 plugins are placed on a web page -by assigning JS9 classes to ordinary div elements. Important JS9 classes -include: -

      -
    • JS9: this class will display the main JS9 image window -
    • JS9Menubar: this class will display the JS9 menubar -
    • JS9Statusbar: this class will display a nice JS9 statusbar -
    -Thus, for example, to place a menubar on top of a JS9 display, use: -
    -  <div class="JS9Menubar">
    -  <div class="JS9">
    -  <div class="JS9Statusbar">
    -
    -

    -Among the many JS9 plugins that you can add to your webpage are: -

      -
    • Archives & Catalogs: access to external archives and catalogs -
    • Bin/Filter/Section: support for extracting sections from images -
    • Blending: blend images using standard composite techniques -
    • Blinking: blink two or more images -
    • Colormaps: create colormaps -
    • Console: display a console window for executing commands -
    • Contours: create contour maps -
    • Data Cube: process 3D FITS data cubes -
    • Extensions: view FITS extensions -
    • Info: display position, value, and other information as mouse moves -
    • Keyboard Actions: configure keyboard actions -
    • Magnifier: display a magnifier window centered on the mouse position -
    • Mouse/Touch: configure mouse/touch actions -
    • Panner: display a panner window of the whole image -
    • Pixel Table: display a pixel value table centered on the mouse position -
    • Preferences: configure JS9 preferences -
    -

    -Any of these can be added to a web page by specifying a div element with the -appropriate class: -

    -    <div class="JS9Menubar"></div>
    -    <div class="JS9Toolbar"></div>
    -    <div class="JS9"></div>
    -    <div style="margin-top: 2px;">
    -    <div class="JS9Colorbar"></div>
    -
    - -

    -NB: all of these plugins can also be displayed at any time as light -windows, using the appropriate View menu options. Light windows -can moved around on the page and dismissed when no longer needed. Also -note that if a plugin is declared statically in a page, it will not be -made available in the View menu. - -

    -Placement of JS9 div elements should follow standard web page rules -and constraints. This means that div elements can be placed in any -order to create different graphical views. For example, the -js9basics.html page places the menubar above the image display, in -keeping with the traditional layout of DS9. The entire JS9 construct -is placed in a data cell of a table, next to a data cell containing -data URLs. - -

    -The JS9 display has a default width and height of 512x512. You can -change this by adding data-width and data-height -attributes to the div. For example, to create a display of size 256x256, use: -

    -  <div class="JS9" data-width="256px" data-height="256px">
    -
    -The data-width and data-height attributes can be applied -to the other JS9 divs (which can be especially useful for the menubar). -Thus, for example, if you shorten the width of the Js9 display, you might -also want to shorten the width of the menubar: -
    -  <div class="JS9Menubar" data-width="256px" data-height="48px">
    -
    - -

    -Multiple instances of JS9 (including the main JS9 display element -and secondary plugins elements) can be added to a single web page. This -is done by specifying multiple sets of JS9 elements. Each main JS9 display -element should have a unique HTML id associated with it: -

    -   <div class="JS9" id="JS9"></div>
    -   <div class="JS9" id="myJS9"></div>
    -
    - -

    -To connect a JS9 plugin element to a given JS9 display element, you -can either use an HTML id that obeys certain rules, or you can -use an HTML data attribute data-js9id, as described below. - -

    -To connect a JS9 display to one or more JS9 plugins using an -HTML id attribute, the plugin ids should be specified as follows: -

      -
    • start with a unique ID name, e.g. "myJS9" that matches the main JS9 id -
    • follow with an optional dash or underscore -
    • finish with the type of JS9 plugin, e.g. "Menubar", "Panner", "Magnifier" "Info", "3dPlot", "RegionStats", etc. -
    -For example: -
    -    <div class="JS9Menubar" id="myJS9Menubar"></div>
    -    <div class="JS9" id="myJS9"></div>
    -    <div class="JS9Colorbar" id="myJS9Colorbar"></div>
    -    <div class="ImExamRegionStats" id="myJS9RegionStats"></div>
    -
    -Note that the type of plugin is the simple name of the plugin, without the class prefix, e.g., "RegionStats" instead of "ImExamRegionStats". (Esoteric note: for -non-JS9 class plugins, you can prefix the class to avoid name collisions.) - -

    -To connect a JS9 display to one or more JS9 plugins using a -HTML data attribute js9id, specify the id of the main -JS9 display element as its value: -

    -    <div class="JS9Menubar" data-js9id="myJS9"></div>
    -    <div class="JS9" id="myJS9"></div>
    -    <div style="margin-top: 2px;">
    -    <div class="JS9Colorbar" data-js9id="myJS9"></div>
    -
    -These two connection methods are equivalent. However, the js9id -data attribute method also allows you to specify the single-character -token * as a target value for many plugins. In this case, the -display associated with the plugin is dynamically selected by clicking -the mouse in a JS9 display window. In this way, a single plugin can serve -several displays. - -

    -The plugins that support dynamic selection are: -

      -
    • Blend -
    • Blink -
    • Colorbar -
    • Info -
    • Magnifier -
    • Menubar -
    • Panner -
    • Separate -
    • EncEnergy -
    • RadialProj -
    • Histogram -
    • RegionStats -
    • XProj -
    • YProj -
    • 3dPlot -
    - -

    -Note that ids are not required at all if there is only one JS9 instance on -the web page: -

    -    <div class="JS9Menubar"></div>
    -    <div class="JS9Toolbar"></div>
    -    <div class="JS9"></div>
    -    <div style="margin-top: 2px;">
    -    <div class="JS9Colorbar"></div>
    -
    -However, if your site needs to communicate with clients using -the js9 script for external communication, you can -differentiate between clients loading the same JS9-enabled web page by -supplying a unique ID when the JS9 page is served. - -

    A full example of how to define multiple instances of JS9 with ids -is found, for example, in the js9multi.html file. Two DS9 instances -are defined, having IDs of "JS9" (the default) and "myJS9". When -"myJS9" is the display ID, "myJS9Menubar" specifies the associated -menubar and "myJS9Console" specifies the associated console. - -

    -The js9.css file contains CSS directives for various parts of -JS9. These can be modified (or overwritten) as needed, subject to -ordinary CSS rules. In general, we recommend overwriting CSS rules by -loading a site-specific CSS file after the js9.css file. This makes -updating much easier. - -

    -One CSS directive worth noting is the JS9Button class, which -defines the look and feel of the buttons found on the Menubar, inside -plugins, etc. The JS9Button class currently is set to -the JS9ClassicButton class, which mimics Mac OSX buttons in -shape and color. An alternative is the JS9FlatButton class -displays a flat blue button that highlights when the mouse hovers and -darkens when clicked. A lightblue background is often used with -this class of button. JS9 also defines a JS9BorderButton which -has a blue colored border and a white background. The JS9 Menubar -supports two data properties to make it easier to change the button -and background: -

      -
    • buttonClass: the class of button to use ("JS9ClassicButton", "JS9FlatButton", "JS9BorderButton" ... or your own class) -
    • backgroundColor: color of background (default: "lightblue") -
    -The JS9 Size Demo displays different button styles. - -

    -Normally, JS9 will initialize itself automatically once the page is -loaded and ready: internally, jQuery $(document).ready() calls -JS9.init(). If you need to delay JS9 initialization (e.g., you -are using a platform that fires $(document).ready() before the -platform is really ready), you can set data-js9init to "false" -on any JS9 div. In this case, you must call the init routine manually: -

    -  JS9.init();
    -
    -Until you do this, no JS9 div elements will be visible. - -

    -When JS9 is fully loaded and ready (including connection to the JS9 -helper, if necessary), it fires the JS9:ready event. You can -use this event to perform your own initialization: -

    -  $(document).on("JS9:ready", function(){
    -      myinit();
    -  });
    -
    - -

    -

    JS9 Query Parameters

    -You can supply a url query parameter to a JS9-enabled web page -in order to load a FITS image: -
    -https://js9.si.edu/?url=https://hea-www.cfa.harvard.edu/~eric/coma.fits.gz
    -
    -Here, a remote FITS file is loaded using the -JS9.LoadProxy() routine, -(regardless of whether the remote server supports CORS.) -

    -You can append query parameters to set various image options for the -loaded image (these options are contained in the JS9.imageOpts object): -

    -https://js9.si.edu/js9/js9.html?url=https://hea-www.cfa.harvard.edu/~eric/coma.fits.gz&flip=y&rotate=90
    -
    -Here, the same remote FITS file is loaded and then flipped along the y axis and -rotated by 90 degrees. -

    -Finally, you can rename the JS9 display using the display query -parameter: -

    -https://js9.si.edu/js9/js9.html?display=other
    -
    -Here, the display name of the standard JS9 web site is renamed to -"other". This feature can be useful in cases where you are loading the -same web page multiple times and want a different JS9 id for each so that -they can be controlled separately. - -

    -

    Menubar Styles

    The default menubar has a style in which all -of the major menus are shown at the top-level of the menubar. This is -the classic style. JS9 also supports a mac style -menubar, in which the File, Edit and View menus -are placed on the left side of the menubar and the Help menu on -the right. The other main menus are displayed as sub-menus within -the View menu. The mac style can be specified in two -ways: you can set the JS9globalOpts.menubarStyle property to "mac" in -your js9prefs.js file to set the default menubar style for all menus -in the page. Alternatively you can supply a data-style="mac" -attribute to the Menubar div element: -
    -  <div class="JS9Menubar" data-style="mac">
    -
    -This will set the menubar style for this element only. - -

    -

    Supermenus: One Menubar to Rule Them All

    By default, each -menubar controls one JS9 display. You can, however, create a menubar -that controls multiple displays, so that a given menu selection is -applied to each display (or to a specifically selected image). This is -done by creating a menubar div with two special characteristics: -
      -
    • the id of the menubar starts with SUPERMENU_ (it can end with anything, or nothing) -
    • an HTML5 data attribute called data-displays lists the JS9 displays to control or "*" for all displays -
    -For example, to control two JS9 displays: -
    -  <div class="JS9Menubar" id="SUPERMENU_" data-displays="JS9,myJS9"></div>
    -
    -As shown, the data-displays attribute is a comma-separated list -of JS9 display ids to control with this super-menu. -

    -A super-menu acts like an ordinary menu, except that it will control -all of the JS9 displays in the list. Thus, you can change multiple -colormaps at once, run analysis on all displays, etc. -

    -You also can click on an individual display to make it the selected -display for the supermenu. The selected display will be -highlighted, and the supermenu will target its actions at this display -alone, rather than at all of the displays. Click again in a selected -display (or clicking in another display) to unselect it. In this way, -a single supermenu can be used to control several displays -individually (akin to how the top-level Apple menu functions with -regard to applications). -

    -A supermenu displays an additional Super menu button on the -left side of the menubar. This button contains a list of all displays -controlled by the supermenu, with the selected display starred. You -can choose a new selected display from this menu, or choose "all -displays" to unselect. -

    -Of course, you also can define a menubar for each display in order to -control them individually. Since the actions of an ordinary menu and a -super-menu can be mixed for a given JS9 display, the displays will not -always be perfectly synchronized. In such a case, the super-menu's -selected values will be tied to the first display in the -data-displays list. For example, if the first display listed -is at zoom 2 and the second is at zoom 4, the Zoom menu will show -a current zoom value of 2. - -

    -

    Adding Server-side Analysis Tasks to Your Web Page

    -

    -Server-side JS9 analysis tasks can be executed using -the Analysis menu, but they also can be executed directly from -the web page using HTML elements (buttons, forms, etc.) To do this, a -web page author simply creates the web interface and calls -either JS9.RunAnalysis() (for buttons, menus, etc.) -or JS9.SubmitAnalysis() (for forms). These are described -in the Local Tasks web page. - -

    -

    Adding Local Analysis Tasks to Your Web Page

    -

    -JS9 also supports the ability to perform local analysis, i.e., -analysis tasks defined and executed right on your web page, rather -than being executed by a back-end server. This is accomplished by -offering access to the image data and region information via -a public JS9 API. See the -Local Tasks for more information. - -

    -

    Adding JS9 Display Windows Dynamically

    -

    -JS9 display windows can be created dynamically using the JS9 Public API call -JS9.LoadWindow(). You can create a light window to hold a new -JS9 display on the same page or you can create an entirely separate -pop-up window. See the -JS9 Public API for more information. - -

    -

    Adding Data Files to a Web Page

    -

    -Data file links are added to a web page by supplying URLs that call -the JS9.Load() routine. -You also can load images automatically when the web page loads using the -JS9.Preload() routine. -See: -Adding Data Files To a Web Page for more -information. - -

    Last updated: June 6, 2022
    -
    - - - diff --git a/web/static/js9_old/help/yourdata.html b/web/static/js9_old/help/yourdata.html deleted file mode 100644 index 9f49100a317cedbc521c1d19a18496eca581db6a..0000000000000000000000000000000000000000 --- a/web/static/js9_old/help/yourdata.html +++ /dev/null @@ -1,113 +0,0 @@ - - - - - -Displaying Your Data - - - -
    -

    Displaying Your Data With JS9

    - -

    Loading a FITS File From Your Web Page

    -

    -Once you have your web page set up, you can make your FITS data files -available on your JS9 web page by creating URLs that call -the JS9.Load() routine: -

    -    href='javascript:JS9.Load(filename, opts);'
    -
    -where opts can be: -
      -
    • filename is the path relative to the current web page location -
    • imageOpts: an object containing params to be merged with the -default JS9.imageOpts object -
    -

    -For example: -

    -    href='javascript:JS9.Load("fits/casa.fits");'
    -
    -Clicking on this URL will load the casa.fits file (here, stored in the -fits directory directly beneath the web page location). If the JS9 -server-side helper is running, it will be alerted about this new file -so that it can run analysis, etc. - -

    -As of version 1.3, the cfitsio library is used to process FITS files -in JS9. (Technical note: we used emscripten to compile cfitsio to -JavaScript, and then added thin C and JavaScript layers to provide an -interface to J9.) Thus, you can utilize the cfitsio extended file -name syntax to tailor the image data being displayed. For example: -

    -    href='javascript:JS9.Load("fits/snr.fits[events][pi==pha]");'
    -
    -will display display all photons in the EVENTS binary table having the -same pi and pha values. Cfitsio also supports display of arbitrary -image extensions, gzip'ed files, tile compressed files, image -sections, etc. See the - -cfitsio documentation for more information. - -

    -Note to users who are upgrading to version 1.3: to use cfitsio, simply -remove the load of fitsy.js (or fitsy.min.js) from your web page. - -

    -To override default image parameters, specify imgOpts parameters as the second argument: -

    -    href='javascript:JS9.Load("fits/m13.fits", {scale:"linear", colormap:"sls"});'
    -
    -

    -To load an image into a specified display, pass the display id in an object as -the last argument in the call. This can be the second or third argument, -depending whether the image object also is passed: -

    -    # the display object can be passed as the second argument ...
    -    href='javascript:JS9.Load("fits/casa.fits", {display: "myJS9"});'
    -    # but when image opts is also passed, it's the third argument  
    -    href='javascript:JS9.Load("fits/3c273.fits", {scale: "linear"}, {display: "myJS9"});'
    -
    - -

    -Web browsers do not support allocation of unlimited memory, regardless -of the amount available on the given host. It seems that 1Gb is a -limit often encountered; trying to allocate more memory can result in -browser hangs (e.g., the Mac spinning wheel being displayed -indefinitely.) To minimize these problems, JS9 enforces an image size limit -using the JS9.globalOpts.maxFITSMemory property. Its default value is -450000000, which supports images of size 10600 x 10600 x 4-bytes. -You can change this value in the js9Prefs.json file, or, once JS9 is -initialized, reset it via the JS9.fits.maxFITSMemory(bytes) routine. - -

    -Memory usage and availability is a fast-moving part of browser -technology and we will revise the JS9 limit as warranted. Keep in -mind that, in all cases, using a huge amount of memory to display data -will result in poor responsiveness. - -

    Pre-Loading a File From Your Web Page

    -

    -You can pre-load one or more data files into JS9 when the web page -itself is loaded by adding the JS9.Preload() routine to -the onload event in your web page body element: -

    -<body onload="JS9.Preload('fits/casa.fits', 
    -		          'fits/snr.fits[events][pi==pha]', {colormap:'heat'},
    -		          'fits/3c58.fits',
    -		          'fits/m13.fits', {scale:'linear', colormap:'sls'},
    -		          'fits/3c273.fits',
    -		          'fits/ngc1316.fits', {scale:'linear'},
    -		          'fits/ngkper.fits', {colormap:'grey'});">
    -
    -Note that this routine takes a list of images, each of which -optionally can have an associated imgOpts argument. The display -opts can be passed as the final argument and will apply to all images. - -
    Last updated: June 1, 2016
    -
    - - - diff --git a/web/static/js9_old/images/4arrow.png b/web/static/js9_old/images/4arrow.png deleted file mode 100644 index 36b875ad531cf0a6b9f9792b856ccd9d83f6797b..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/4arrow.png and /dev/null differ diff --git a/web/static/js9_old/images/checkmark.svg b/web/static/js9_old/images/checkmark.svg deleted file mode 100644 index bece135849109c7061b45cc5374f5dd8be8645b9..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/checkmark.svg +++ /dev/null @@ -1 +0,0 @@ -checkmark \ No newline at end of file diff --git a/web/static/js9_old/images/close.gif b/web/static/js9_old/images/close.gif deleted file mode 100644 index af01282c7dfc1b684acabe48d47f923c26d792ec..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/close.gif and /dev/null differ diff --git a/web/static/js9_old/images/empty.svg b/web/static/js9_old/images/empty.svg deleted file mode 100644 index 00f0aa2423843840a52a3641fa49ec2c7307f14d..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/empty.svg +++ /dev/null @@ -1 +0,0 @@ -empty \ No newline at end of file diff --git a/web/static/js9_old/images/gears.png b/web/static/js9_old/images/gears.png deleted file mode 100644 index 39c48795d973de9ba4c964bb7f0d375d08386719..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/gears.png and /dev/null differ diff --git a/web/static/js9_old/images/indentbg.gif b/web/static/js9_old/images/indentbg.gif deleted file mode 100644 index d78ffd5832435349861d9cf01827a651adc30aad..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/indentbg.gif and /dev/null differ diff --git a/web/static/js9_old/images/indentbg2.gif b/web/static/js9_old/images/indentbg2.gif deleted file mode 100644 index 5c81d84206bbac2f92113424fc6feeed8b1f4656..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/indentbg2.gif and /dev/null differ diff --git a/web/static/js9_old/images/indentbg2_grey.png b/web/static/js9_old/images/indentbg2_grey.png deleted file mode 100644 index a3ceb2a0e928419d2bee047689f047cd63954675..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/indentbg2_grey.png and /dev/null differ diff --git a/web/static/js9_old/images/indentbg_grey.png b/web/static/js9_old/images/indentbg_grey.png deleted file mode 100644 index a8723f17d774f45cd758cf2df2e36112d339499d..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/indentbg_grey.png and /dev/null differ diff --git a/web/static/js9_old/images/js9-apple-touch-icon.icns b/web/static/js9_old/images/js9-apple-touch-icon.icns deleted file mode 100644 index 17207dbb850f24fedb38b4457485615f9df1e256..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/js9-apple-touch-icon.icns and /dev/null differ diff --git a/web/static/js9_old/images/js9-apple-touch-icon.png b/web/static/js9_old/images/js9-apple-touch-icon.png deleted file mode 100644 index 03c9ef191a75ba5b8e231b03a9c3b665c1a6c4ad..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/js9-apple-touch-icon.png and /dev/null differ diff --git a/web/static/js9_old/images/js9Readme.png b/web/static/js9_old/images/js9Readme.png deleted file mode 100644 index 2b2339015974f472e1be292b3270d260a7cca5eb..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/js9Readme.png and /dev/null differ diff --git a/web/static/js9_old/images/js9logo.png b/web/static/js9_old/images/js9logo.png deleted file mode 100644 index c5594897a3f9eb86782cb93498068b1a4178807c..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/js9logo.png and /dev/null differ diff --git a/web/static/js9_old/images/js9logo/mac/js9logo-is32.icns b/web/static/js9_old/images/js9logo/mac/js9logo-is32.icns deleted file mode 100644 index 3b7c417309a875304766fef92c38b975a7809e75..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/js9logo/mac/js9logo-is32.icns and /dev/null differ diff --git a/web/static/js9_old/images/js9logo/mac/js9logo.icns b/web/static/js9_old/images/js9logo/mac/js9logo.icns deleted file mode 100644 index a4c12e20c2e63da197875f85b4ae5dfb89814d8f..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/js9logo/mac/js9logo.icns and /dev/null differ diff --git a/web/static/js9_old/images/js9logo/png/js9logo_128.png b/web/static/js9_old/images/js9logo/png/js9logo_128.png deleted file mode 100644 index b681894e6694912147c2c86b85cda1613cc5db29..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/js9logo/png/js9logo_128.png and /dev/null differ diff --git a/web/static/js9_old/images/js9logo/png/js9logo_256.png b/web/static/js9_old/images/js9logo/png/js9logo_256.png deleted file mode 100644 index 3033cc59c1bbedaceadf795b5b78d79d6c323826..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/js9logo/png/js9logo_256.png and /dev/null differ diff --git a/web/static/js9_old/images/js9logo/png/js9logo_48.png b/web/static/js9_old/images/js9logo/png/js9logo_48.png deleted file mode 100644 index edcff5c8b156123613feda830e4f485d5f85eae8..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/js9logo/png/js9logo_48.png and /dev/null differ diff --git a/web/static/js9_old/images/js9logo/png/js9logo_512.png b/web/static/js9_old/images/js9logo/png/js9logo_512.png deleted file mode 100644 index d73e085d29e2371f7def965e33273e2855257e4c..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/js9logo/png/js9logo_512.png and /dev/null differ diff --git a/web/static/js9_old/images/js9logo/png/js9logo_64.png b/web/static/js9_old/images/js9logo/png/js9logo_64.png deleted file mode 100644 index d892467030fc56eb642786b33282960f67ac1fef..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/js9logo/png/js9logo_64.png and /dev/null differ diff --git a/web/static/js9_old/images/js9logo/png/js9logo_96.png b/web/static/js9_old/images/js9logo/png/js9logo_96.png deleted file mode 100644 index e99ad1bff6726a8184e4b8f74a60e488f30efbce..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/js9logo/png/js9logo_96.png and /dev/null differ diff --git a/web/static/js9_old/images/js9logo/win/js9logo_512.ico b/web/static/js9_old/images/js9logo/win/js9logo_512.ico deleted file mode 100644 index 18bf696982f60162d0db660392c97970a585af99..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/js9logo/win/js9logo_512.ico and /dev/null differ diff --git a/web/static/js9_old/images/min.gif b/web/static/js9_old/images/min.gif deleted file mode 100644 index ce83aa823ef555bc75a3c7387cb231feccfb87dc..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/min.gif and /dev/null differ diff --git a/web/static/js9_old/images/resize.gif b/web/static/js9_old/images/resize.gif deleted file mode 100644 index 751ff64000a9a12c8307f2625157dbfe23ab0457..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/resize.gif and /dev/null differ diff --git a/web/static/js9_old/images/restore.gif b/web/static/js9_old/images/restore.gif deleted file mode 100644 index d00ca4f26b009adb5440328745e14fb4df01cfb6..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/restore.gif and /dev/null differ diff --git a/web/static/js9_old/images/shade.gif b/web/static/js9_old/images/shade.gif deleted file mode 100644 index 72b13c58747e6188fba684ea2505b265bec66e35..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/shade.gif and /dev/null differ diff --git a/web/static/js9_old/images/shadeactive.gif b/web/static/js9_old/images/shadeactive.gif deleted file mode 100644 index e5c8097e3cebb4b2012d43927848b06eaed6d230..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/shadeactive.gif and /dev/null differ diff --git a/web/static/js9_old/images/si-logo.png b/web/static/js9_old/images/si-logo.png deleted file mode 100644 index 038f677b1146ba4426f0842baf0a72fc8e8722ee..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/si-logo.png and /dev/null differ diff --git a/web/static/js9_old/images/sun.png b/web/static/js9_old/images/sun.png deleted file mode 100644 index 42e3fc8a753abbc2c47835d9248ac9691695e238..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/sun.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/10_4.png b/web/static/js9_old/images/toolbar/dax_images/10_4.png deleted file mode 100644 index f97b6e0e9cd7990bec6f5294b8040bf69a565e85..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/10_4.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/2_2.png b/web/static/js9_old/images/toolbar/dax_images/2_2.png deleted file mode 100644 index eafebaf7ac6d7e475e2e8e821c68798ba5f6f093..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/2_2.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/5_5.png b/web/static/js9_old/images/toolbar/dax_images/5_5.png deleted file mode 100644 index 320eee203539f94dd9ab3b4b2a5887a897d4072d..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/5_5.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/8_3.png b/web/static/js9_old/images/toolbar/dax_images/8_3.png deleted file mode 100644 index 730461b5fcd78db508fd3251d4d32eda185c64b8..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/8_3.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/annulus.png b/web/static/js9_old/images/toolbar/dax_images/annulus.png deleted file mode 100644 index 524120d99a85b6906e00d526ad0b33a5bec982b3..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/annulus.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/back.png b/web/static/js9_old/images/toolbar/dax_images/back.png deleted file mode 100644 index ce502f825c44583c04c0301f38cea36615edb684..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/back.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/bin_minus.png b/web/static/js9_old/images/toolbar/dax_images/bin_minus.png deleted file mode 100644 index d86fd763412f3fbaaff842d7ded0085848a52b52..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/bin_minus.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/bin_one.png b/web/static/js9_old/images/toolbar/dax_images/bin_one.png deleted file mode 100644 index 5c806c32c47d735b2f0c930d641146eb03064f69..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/bin_one.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/bin_plus.png b/web/static/js9_old/images/toolbar/dax_images/bin_plus.png deleted file mode 100644 index 4057c2d3757cae0c9fa34d5f5e6d1ecb9949f066..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/bin_plus.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/blank.png b/web/static/js9_old/images/toolbar/dax_images/blank.png deleted file mode 100644 index 871ee786d165e9d789822ca7586548dfcac8e87a..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/blank.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/blk.png b/web/static/js9_old/images/toolbar/dax_images/blk.png deleted file mode 100644 index 623ad269ef65622d5a3f88a4ad751dc0ac3ebd4e..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/blk.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/blu.png b/web/static/js9_old/images/toolbar/dax_images/blu.png deleted file mode 100644 index bb8e738d15e6056c9e6b0dc032d75ea53b4590bc..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/blu.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/box.png b/web/static/js9_old/images/toolbar/dax_images/box.png deleted file mode 100644 index 673abd14ba0828365013ba8b14ef9163ba14c49b..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/box.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/circle.png b/web/static/js9_old/images/toolbar/dax_images/circle.png deleted file mode 100644 index 1d23b22db6e567f8da97e8d164c8db7a90edc500..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/circle.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_a.png b/web/static/js9_old/images/toolbar/dax_images/cmap_a.png deleted file mode 100644 index 209a6b8992890a560bc4ce4859d7ad5406dd427a..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_a.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_aips0.png b/web/static/js9_old/images/toolbar/dax_images/cmap_aips0.png deleted file mode 100644 index 00a6eef83400aba426b7083c5d0b016132cabd74..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_aips0.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_b.png b/web/static/js9_old/images/toolbar/dax_images/cmap_b.png deleted file mode 100644 index 84efe32a5873c1a2a576c62fffcecda9a5630a97..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_b.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_bb.png b/web/static/js9_old/images/toolbar/dax_images/cmap_bb.png deleted file mode 100644 index 9e005eaa1cfc59fc842998c04d6ab900f784cb39..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_bb.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_blue.png b/web/static/js9_old/images/toolbar/dax_images/cmap_blue.png deleted file mode 100644 index 8c26079bc63815ac4c9799d7a9e92333f29329f2..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_blue.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_color.png b/web/static/js9_old/images/toolbar/dax_images/cmap_color.png deleted file mode 100644 index 88f6a20e9d0dcd700ff146b67d570af20aa638bd..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_color.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_cool.png b/web/static/js9_old/images/toolbar/dax_images/cmap_cool.png deleted file mode 100644 index 8e43a8cecdeb3ba95ba61373b7ec53a15dcf23f1..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_cool.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_green.png b/web/static/js9_old/images/toolbar/dax_images/cmap_green.png deleted file mode 100644 index 63dcac937129ef26062146cad43ca410de04e4cf..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_green.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_grey.png b/web/static/js9_old/images/toolbar/dax_images/cmap_grey.png deleted file mode 100644 index addfaad34f0fbb501c9dfd20cfe44f1450183454..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_grey.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_he.png b/web/static/js9_old/images/toolbar/dax_images/cmap_he.png deleted file mode 100644 index 1e9972ea67892eb9846b1cdc560f03420e32d467..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_he.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_heat.png b/web/static/js9_old/images/toolbar/dax_images/cmap_heat.png deleted file mode 100644 index 5b4512e347931cc7cbd8fa71356a6fe297e60f63..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_heat.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_hsv.png b/web/static/js9_old/images/toolbar/dax_images/cmap_hsv.png deleted file mode 100644 index 90c7fb7bb41fd77aa53b04d6c7d1d3cdb6891f80..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_hsv.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_i8.png b/web/static/js9_old/images/toolbar/dax_images/cmap_i8.png deleted file mode 100644 index 9a9976a6f290508ddff612dff6a101e392db8bd0..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_i8.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_inferno.png b/web/static/js9_old/images/toolbar/dax_images/cmap_inferno.png deleted file mode 100644 index 86bdceb58d6ec6b7dbea419021b12adfe1b76992..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_inferno.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_magma.png b/web/static/js9_old/images/toolbar/dax_images/cmap_magma.png deleted file mode 100644 index 4be28a369be8095c473684cf53a6711f741aa627..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_magma.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_parula.png b/web/static/js9_old/images/toolbar/dax_images/cmap_parula.png deleted file mode 100644 index d5bc95183022564f57df99cc28e815f5eef167af..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_parula.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_plasma.png b/web/static/js9_old/images/toolbar/dax_images/cmap_plasma.png deleted file mode 100644 index b9c842cfd085d1a4c4ea8e48472244493a44d6f5..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_plasma.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_rainbow.png b/web/static/js9_old/images/toolbar/dax_images/cmap_rainbow.png deleted file mode 100644 index 6f90fe50e500b899dbf5e5606a336e9bdab4b3a4..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_rainbow.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_red.png b/web/static/js9_old/images/toolbar/dax_images/cmap_red.png deleted file mode 100644 index 79af62e6c727cd4a17d38ae2cccb4ddb1396d8a5..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_red.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_sls.png b/web/static/js9_old/images/toolbar/dax_images/cmap_sls.png deleted file mode 100644 index 9f0b9d37232b6390fe14651fddfa8e9c06d5e082..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_sls.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_staircase.png b/web/static/js9_old/images/toolbar/dax_images/cmap_staircase.png deleted file mode 100644 index 2e8136280a67003931d27584577944c919690660..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_staircase.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_standard.png b/web/static/js9_old/images/toolbar/dax_images/cmap_standard.png deleted file mode 100644 index dfe88b8bbb2a3c9de2387a41f2667540253c4992..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_standard.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cmap_viridis.png b/web/static/js9_old/images/toolbar/dax_images/cmap_viridis.png deleted file mode 100644 index 785019a6f69b32e4fdb3c1722bc0357ce8b66a75..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cmap_viridis.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/contour.png b/web/static/js9_old/images/toolbar/dax_images/contour.png deleted file mode 100644 index 992877147a923b839cdad42609412e8f20e37ebf..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/contour.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/coords.png b/web/static/js9_old/images/toolbar/dax_images/coords.png deleted file mode 100644 index 360ec5c2273abf87a7234b236854321fdcd6e43c..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/coords.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/cyn.png b/web/static/js9_old/images/toolbar/dax_images/cyn.png deleted file mode 100644 index 0adfe0df04d08f2e310abcd7d5a8ad0a6389fd3f..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/cyn.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/ellipse.png b/web/static/js9_old/images/toolbar/dax_images/ellipse.png deleted file mode 100644 index ca6ebe309ed7a3ed2e4c8d07cf1fe79d68ebc7dc..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/ellipse.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/erase.png b/web/static/js9_old/images/toolbar/dax_images/erase.png deleted file mode 100644 index 6dc189c539e069cfaf7e9c0e24e32a137d60626f..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/erase.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/filter.png b/web/static/js9_old/images/toolbar/dax_images/filter.png deleted file mode 100644 index 88e4a90d25b5e808770927c033382fe6f8c82ca9..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/filter.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/front.png b/web/static/js9_old/images/toolbar/dax_images/front.png deleted file mode 100644 index 1c6a2d0d2bc5972cdc3321549d9b7f831b5a5462..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/front.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/glvary.png b/web/static/js9_old/images/toolbar/dax_images/glvary.png deleted file mode 100644 index 3b4f593095bd875cf6d678435cc7b193deaa198b..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/glvary.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/grn.png b/web/static/js9_old/images/toolbar/dax_images/grn.png deleted file mode 100644 index 4c83a3fd406dee8ac9a1f7d5d7328788127bbdec..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/grn.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/incexl.png b/web/static/js9_old/images/toolbar/dax_images/incexl.png deleted file mode 100644 index 28c971f40cce24a34ab16f65d3c42f0f3898d982..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/incexl.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/lightcurve.png b/web/static/js9_old/images/toolbar/dax_images/lightcurve.png deleted file mode 100644 index f57807c566712562450ba8e6b3ab70efa51cf4b9..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/lightcurve.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/lin.png b/web/static/js9_old/images/toolbar/dax_images/lin.png deleted file mode 100644 index 5e8a196d54368cd83edd2ad9e1514a7abbd8befa..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/lin.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/log.png b/web/static/js9_old/images/toolbar/dax_images/log.png deleted file mode 100644 index f942ea2e770054c0b6376690474821f2a17ba163..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/log.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/mag.png b/web/static/js9_old/images/toolbar/dax_images/mag.png deleted file mode 100644 index 242716a95b5e1ee722bf737405d0620b1846f26e..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/mag.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/mag_minus.png b/web/static/js9_old/images/toolbar/dax_images/mag_minus.png deleted file mode 100644 index fffe6ba64b15b2dfbdd36f62ae263fbe612a30b7..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/mag_minus.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/mag_one.png b/web/static/js9_old/images/toolbar/dax_images/mag_one.png deleted file mode 100644 index f6fa977bb41e44c2cf91966fe04276bb0ac449cd..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/mag_one.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/mag_plus.png b/web/static/js9_old/images/toolbar/dax_images/mag_plus.png deleted file mode 100644 index d324f4befd735a17644ba9ff6918e0a1c59f44a9..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/mag_plus.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/match.png b/web/static/js9_old/images/toolbar/dax_images/match.png deleted file mode 100644 index 680d4aa561da70ffa73afdf2e602ce5cbd6ab21f..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/match.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/minus.png b/web/static/js9_old/images/toolbar/dax_images/minus.png deleted file mode 100644 index df8db68d6d0a99ff754549f42e9b30918d48d5c4..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/minus.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/open.png b/web/static/js9_old/images/toolbar/dax_images/open.png deleted file mode 100644 index 6d964d23ad87d6dc6a2994ee5c7d982293035f8c..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/open.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/pan.png b/web/static/js9_old/images/toolbar/dax_images/pan.png deleted file mode 100644 index 066929e2b7a93d53c063cd17e0f3a44bb654e2fa..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/pan.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/plus.png b/web/static/js9_old/images/toolbar/dax_images/plus.png deleted file mode 100644 index 8098ba38eefc8a69c40fcfc887b2fbdfa5f6ead9..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/plus.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/poly.png b/web/static/js9_old/images/toolbar/dax_images/poly.png deleted file mode 100644 index a8f27d8cd0d8426449c420fe9ba48b44a4449b15..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/poly.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/pow.png b/web/static/js9_old/images/toolbar/dax_images/pow.png deleted file mode 100644 index 4664426a5657389576dfaf8f6d5ebeb2a3c91fd4..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/pow.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/pur.png b/web/static/js9_old/images/toolbar/dax_images/pur.png deleted file mode 100644 index f93c2e037583768797755fad053be37171a3de36..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/pur.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/red.png b/web/static/js9_old/images/toolbar/dax_images/red.png deleted file mode 100644 index dfe102a2a5b01c3a28f2f16c4cbcb89c52f94c63..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/red.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/smooth.png b/web/static/js9_old/images/toolbar/dax_images/smooth.png deleted file mode 100644 index 260862d8ef69f66cbfa844d2b564871218ab7339..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/smooth.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/spectrum.png b/web/static/js9_old/images/toolbar/dax_images/spectrum.png deleted file mode 100644 index f158e988aca73e572f2f37f46e9eb1428e20f99b..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/spectrum.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/srcbkg.png b/web/static/js9_old/images/toolbar/dax_images/srcbkg.png deleted file mode 100644 index 1ad534c7ca6283a90ddac01a00f7c5b9e8f07522..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/srcbkg.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/stats.png b/web/static/js9_old/images/toolbar/dax_images/stats.png deleted file mode 100644 index e12d554eab8b38c975fba83af4edaf56b1ded52c..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/stats.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/text.png b/web/static/js9_old/images/toolbar/dax_images/text.png deleted file mode 100644 index f6b7bfd640c23d01a0a3f07a84f80a5cf38dac13..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/text.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/wht.png b/web/static/js9_old/images/toolbar/dax_images/wht.png deleted file mode 100644 index d7119bf5f17cf83f321c2b4a4c08d728a15d688e..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/wht.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/dax_images/yel.png b/web/static/js9_old/images/toolbar/dax_images/yel.png deleted file mode 100644 index 31983b4f3316674cfb15bfbe40a83434bde97261..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/dax_images/yel.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/10_4.png b/web/static/js9_old/images/toolbar/odax_images/10_4.png deleted file mode 100644 index f97b6e0e9cd7990bec6f5294b8040bf69a565e85..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/10_4.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/2_2.png b/web/static/js9_old/images/toolbar/odax_images/2_2.png deleted file mode 100644 index eafebaf7ac6d7e475e2e8e821c68798ba5f6f093..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/2_2.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/5_5.png b/web/static/js9_old/images/toolbar/odax_images/5_5.png deleted file mode 100644 index 320eee203539f94dd9ab3b4b2a5887a897d4072d..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/5_5.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/8_3.png b/web/static/js9_old/images/toolbar/odax_images/8_3.png deleted file mode 100644 index 730461b5fcd78db508fd3251d4d32eda185c64b8..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/8_3.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/annulus.png b/web/static/js9_old/images/toolbar/odax_images/annulus.png deleted file mode 100644 index 99710f2be7ac0d5f94d8de7845523291e77034db..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/annulus.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/back.png b/web/static/js9_old/images/toolbar/odax_images/back.png deleted file mode 100644 index 787cc93bda142c3eb105b0bded4b45fabfe531f6..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/back.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/bin_minus.png b/web/static/js9_old/images/toolbar/odax_images/bin_minus.png deleted file mode 100644 index d86fd763412f3fbaaff842d7ded0085848a52b52..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/bin_minus.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/bin_one.png b/web/static/js9_old/images/toolbar/odax_images/bin_one.png deleted file mode 100644 index 5c806c32c47d735b2f0c930d641146eb03064f69..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/bin_one.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/bin_plus.png b/web/static/js9_old/images/toolbar/odax_images/bin_plus.png deleted file mode 100644 index 4057c2d3757cae0c9fa34d5f5e6d1ecb9949f066..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/bin_plus.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/blank.png b/web/static/js9_old/images/toolbar/odax_images/blank.png deleted file mode 100644 index 871ee786d165e9d789822ca7586548dfcac8e87a..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/blank.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/blk.png b/web/static/js9_old/images/toolbar/odax_images/blk.png deleted file mode 100644 index 623ad269ef65622d5a3f88a4ad751dc0ac3ebd4e..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/blk.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/blu.png b/web/static/js9_old/images/toolbar/odax_images/blu.png deleted file mode 100644 index 1add635cd1120d24cbd2530fc9aa3049158b774a..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/blu.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/box.png b/web/static/js9_old/images/toolbar/odax_images/box.png deleted file mode 100644 index b51a7f55fd39b2827135f454d3684302acde35dc..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/box.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/circle.png b/web/static/js9_old/images/toolbar/odax_images/circle.png deleted file mode 100644 index 937505a9d969cae3ffaa1f515c3e33da554f6fd8..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/circle.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_a.png b/web/static/js9_old/images/toolbar/odax_images/cmap_a.png deleted file mode 100644 index 209a6b8992890a560bc4ce4859d7ad5406dd427a..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_a.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_aips0.png b/web/static/js9_old/images/toolbar/odax_images/cmap_aips0.png deleted file mode 100644 index 00a6eef83400aba426b7083c5d0b016132cabd74..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_aips0.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_b.png b/web/static/js9_old/images/toolbar/odax_images/cmap_b.png deleted file mode 100644 index 84efe32a5873c1a2a576c62fffcecda9a5630a97..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_b.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_bb.png b/web/static/js9_old/images/toolbar/odax_images/cmap_bb.png deleted file mode 100644 index 9e005eaa1cfc59fc842998c04d6ab900f784cb39..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_bb.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_blue.png b/web/static/js9_old/images/toolbar/odax_images/cmap_blue.png deleted file mode 100644 index 8c26079bc63815ac4c9799d7a9e92333f29329f2..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_blue.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_color.png b/web/static/js9_old/images/toolbar/odax_images/cmap_color.png deleted file mode 100644 index 88f6a20e9d0dcd700ff146b67d570af20aa638bd..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_color.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_cool.png b/web/static/js9_old/images/toolbar/odax_images/cmap_cool.png deleted file mode 100644 index 8e43a8cecdeb3ba95ba61373b7ec53a15dcf23f1..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_cool.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_green.png b/web/static/js9_old/images/toolbar/odax_images/cmap_green.png deleted file mode 100644 index 63dcac937129ef26062146cad43ca410de04e4cf..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_green.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_grey.png b/web/static/js9_old/images/toolbar/odax_images/cmap_grey.png deleted file mode 100644 index addfaad34f0fbb501c9dfd20cfe44f1450183454..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_grey.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_he.png b/web/static/js9_old/images/toolbar/odax_images/cmap_he.png deleted file mode 100644 index 1e9972ea67892eb9846b1cdc560f03420e32d467..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_he.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_heat.png b/web/static/js9_old/images/toolbar/odax_images/cmap_heat.png deleted file mode 100644 index 5b4512e347931cc7cbd8fa71356a6fe297e60f63..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_heat.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_hsv.png b/web/static/js9_old/images/toolbar/odax_images/cmap_hsv.png deleted file mode 100644 index 90c7fb7bb41fd77aa53b04d6c7d1d3cdb6891f80..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_hsv.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_i8.png b/web/static/js9_old/images/toolbar/odax_images/cmap_i8.png deleted file mode 100644 index 9a9976a6f290508ddff612dff6a101e392db8bd0..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_i8.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_inferno.png b/web/static/js9_old/images/toolbar/odax_images/cmap_inferno.png deleted file mode 100644 index 86bdceb58d6ec6b7dbea419021b12adfe1b76992..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_inferno.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_magma.png b/web/static/js9_old/images/toolbar/odax_images/cmap_magma.png deleted file mode 100644 index 4be28a369be8095c473684cf53a6711f741aa627..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_magma.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_parula.png b/web/static/js9_old/images/toolbar/odax_images/cmap_parula.png deleted file mode 100644 index d5bc95183022564f57df99cc28e815f5eef167af..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_parula.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_plasma.png b/web/static/js9_old/images/toolbar/odax_images/cmap_plasma.png deleted file mode 100644 index b9c842cfd085d1a4c4ea8e48472244493a44d6f5..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_plasma.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_rainbow.png b/web/static/js9_old/images/toolbar/odax_images/cmap_rainbow.png deleted file mode 100644 index 6f90fe50e500b899dbf5e5606a336e9bdab4b3a4..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_rainbow.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_red.png b/web/static/js9_old/images/toolbar/odax_images/cmap_red.png deleted file mode 100644 index 79af62e6c727cd4a17d38ae2cccb4ddb1396d8a5..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_red.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_sls.png b/web/static/js9_old/images/toolbar/odax_images/cmap_sls.png deleted file mode 100644 index 9f0b9d37232b6390fe14651fddfa8e9c06d5e082..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_sls.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_staircase.png b/web/static/js9_old/images/toolbar/odax_images/cmap_staircase.png deleted file mode 100644 index 2e8136280a67003931d27584577944c919690660..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_staircase.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_standard.png b/web/static/js9_old/images/toolbar/odax_images/cmap_standard.png deleted file mode 100644 index dfe88b8bbb2a3c9de2387a41f2667540253c4992..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_standard.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cmap_viridis.png b/web/static/js9_old/images/toolbar/odax_images/cmap_viridis.png deleted file mode 100644 index 785019a6f69b32e4fdb3c1722bc0357ce8b66a75..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cmap_viridis.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/contour.png b/web/static/js9_old/images/toolbar/odax_images/contour.png deleted file mode 100644 index bbd52c2b2fd7572c0e07c224b3ba0542dd246cac..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/contour.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/coords.png b/web/static/js9_old/images/toolbar/odax_images/coords.png deleted file mode 100644 index cb068bde0b9b8801decd92edbd075320f2b6096e..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/coords.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/cyn.png b/web/static/js9_old/images/toolbar/odax_images/cyn.png deleted file mode 100644 index 0adfe0df04d08f2e310abcd7d5a8ad0a6389fd3f..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/cyn.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/ellipse.png b/web/static/js9_old/images/toolbar/odax_images/ellipse.png deleted file mode 100644 index a9c363ac09ed13283d4a9ffa3f9f9a2a7a9b9a73..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/ellipse.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/erase.png b/web/static/js9_old/images/toolbar/odax_images/erase.png deleted file mode 100644 index 6aff5875713befb2a1dfbf8dcd54923fedf5f847..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/erase.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/filter.png b/web/static/js9_old/images/toolbar/odax_images/filter.png deleted file mode 100644 index 88e4a90d25b5e808770927c033382fe6f8c82ca9..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/filter.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/front.png b/web/static/js9_old/images/toolbar/odax_images/front.png deleted file mode 100644 index dc3bab6fb139725a90b3da10de0c4959de2d946b..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/front.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/glvary.png b/web/static/js9_old/images/toolbar/odax_images/glvary.png deleted file mode 100644 index e722ebb91972db8c261cfe99dfd5c1b6cfc597bf..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/glvary.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/grn.png b/web/static/js9_old/images/toolbar/odax_images/grn.png deleted file mode 100644 index 4c83a3fd406dee8ac9a1f7d5d7328788127bbdec..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/grn.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/incexl.png b/web/static/js9_old/images/toolbar/odax_images/incexl.png deleted file mode 100644 index 3145cc3b81c7a0e339f4cdefce9c8764b8ad7ab8..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/incexl.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/lightcurve.png b/web/static/js9_old/images/toolbar/odax_images/lightcurve.png deleted file mode 100644 index a529f20d21e108ce8156530c74b7e30a1b704b67..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/lightcurve.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/lin.png b/web/static/js9_old/images/toolbar/odax_images/lin.png deleted file mode 100644 index 5e8a196d54368cd83edd2ad9e1514a7abbd8befa..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/lin.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/log.png b/web/static/js9_old/images/toolbar/odax_images/log.png deleted file mode 100644 index f942ea2e770054c0b6376690474821f2a17ba163..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/log.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/mag.png b/web/static/js9_old/images/toolbar/odax_images/mag.png deleted file mode 100644 index 242716a95b5e1ee722bf737405d0620b1846f26e..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/mag.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/mag_minus.png b/web/static/js9_old/images/toolbar/odax_images/mag_minus.png deleted file mode 100644 index fffe6ba64b15b2dfbdd36f62ae263fbe612a30b7..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/mag_minus.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/mag_one.png b/web/static/js9_old/images/toolbar/odax_images/mag_one.png deleted file mode 100644 index f6fa977bb41e44c2cf91966fe04276bb0ac449cd..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/mag_one.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/mag_plus.png b/web/static/js9_old/images/toolbar/odax_images/mag_plus.png deleted file mode 100644 index d324f4befd735a17644ba9ff6918e0a1c59f44a9..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/mag_plus.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/match.png b/web/static/js9_old/images/toolbar/odax_images/match.png deleted file mode 100644 index a74f09119065f1d5110382989a2233a42840832c..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/match.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/minus.png b/web/static/js9_old/images/toolbar/odax_images/minus.png deleted file mode 100644 index ce3fd03ccc6d3cf929451559e1ec62404f92c7c2..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/minus.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/open.png b/web/static/js9_old/images/toolbar/odax_images/open.png deleted file mode 100644 index 6d964d23ad87d6dc6a2994ee5c7d982293035f8c..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/open.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/pan.png b/web/static/js9_old/images/toolbar/odax_images/pan.png deleted file mode 100644 index 066929e2b7a93d53c063cd17e0f3a44bb654e2fa..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/pan.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/plus.png b/web/static/js9_old/images/toolbar/odax_images/plus.png deleted file mode 100644 index ac55941a9b90d953ceb8e1718194545fb0f319cb..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/plus.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/poly.png b/web/static/js9_old/images/toolbar/odax_images/poly.png deleted file mode 100644 index c9c9f234a4b85b2858262ae45af65684530b0309..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/poly.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/pow.png b/web/static/js9_old/images/toolbar/odax_images/pow.png deleted file mode 100644 index 4664426a5657389576dfaf8f6d5ebeb2a3c91fd4..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/pow.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/pur.png b/web/static/js9_old/images/toolbar/odax_images/pur.png deleted file mode 100644 index f93c2e037583768797755fad053be37171a3de36..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/pur.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/red.png b/web/static/js9_old/images/toolbar/odax_images/red.png deleted file mode 100644 index dfe102a2a5b01c3a28f2f16c4cbcb89c52f94c63..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/red.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/smooth.png b/web/static/js9_old/images/toolbar/odax_images/smooth.png deleted file mode 100644 index a221b0e3de8dab81ff5af6138ffc316af4c6f2cb..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/smooth.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/spectrum.png b/web/static/js9_old/images/toolbar/odax_images/spectrum.png deleted file mode 100644 index bcd74583a31736460fbcb609e1de20c18015a14c..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/spectrum.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/srcbkg.png b/web/static/js9_old/images/toolbar/odax_images/srcbkg.png deleted file mode 100644 index 3dde394ab5577f00d4444a390d28bf687d0d9078..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/srcbkg.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/stats.png b/web/static/js9_old/images/toolbar/odax_images/stats.png deleted file mode 100644 index 21b79d081e7911a372d1610cac0d3314702c6c8e..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/stats.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/text.png b/web/static/js9_old/images/toolbar/odax_images/text.png deleted file mode 100644 index 34269cbc856396547713d0e12c0dd503ebada788..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/text.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/wht.png b/web/static/js9_old/images/toolbar/odax_images/wht.png deleted file mode 100644 index d7119bf5f17cf83f321c2b4a4c08d728a15d688e..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/wht.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/odax_images/yel.png b/web/static/js9_old/images/toolbar/odax_images/yel.png deleted file mode 100644 index 31983b4f3316674cfb15bfbe40a83434bde97261..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/odax_images/yel.png and /dev/null differ diff --git a/web/static/js9_old/images/toolbar/svg b/web/static/js9_old/images/toolbar/svg deleted file mode 120000 index 4c4e1fbe59856a1f24dfd003f8083540c60f6c72..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/toolbar/svg +++ /dev/null @@ -1 +0,0 @@ -../voyager \ No newline at end of file diff --git a/web/static/js9_old/images/toolbar/threedots.png b/web/static/js9_old/images/toolbar/threedots.png deleted file mode 100644 index c7ac221b0d76a48dcf1f73e1b3a3bb60dfdba01d..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/toolbar/threedots.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager.icns b/web/static/js9_old/images/voyager.icns deleted file mode 100644 index 6c7e50c8c4e7f493c641a356c1d41b1a3d32181d..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager.icns and /dev/null differ diff --git a/web/static/js9_old/images/voyager/binning_bin1.svg b/web/static/js9_old/images/voyager/binning_bin1.svg deleted file mode 100644 index eebe0f8ad94a4c968d3e08bf1e02de73e56f842c..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/binning_bin1.svg +++ /dev/null @@ -1 +0,0 @@ -bin1 \ No newline at end of file diff --git a/web/static/js9_old/images/voyager/binning_bin12.svg b/web/static/js9_old/images/voyager/binning_bin12.svg deleted file mode 100644 index 90c8c7dfceb7ce6951d147200d500ac9b7d18a86..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/binning_bin12.svg +++ /dev/null @@ -1 +0,0 @@ -bin12 \ No newline at end of file diff --git a/web/static/js9_old/images/voyager/binning_bin2.svg b/web/static/js9_old/images/voyager/binning_bin2.svg deleted file mode 100644 index aae0f062093516d609a6a576c0874d485d814dc5..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/binning_bin2.svg +++ /dev/null @@ -1 +0,0 @@ -bin2 \ No newline at end of file diff --git a/web/static/js9_old/images/voyager/color_a.png b/web/static/js9_old/images/voyager/color_a.png deleted file mode 100644 index 209a6b8992890a560bc4ce4859d7ad5406dd427a..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_a.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_aips0.png b/web/static/js9_old/images/voyager/color_aips0.png deleted file mode 100644 index 00a6eef83400aba426b7083c5d0b016132cabd74..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_aips0.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_b.png b/web/static/js9_old/images/voyager/color_b.png deleted file mode 100644 index 84efe32a5873c1a2a576c62fffcecda9a5630a97..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_b.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_bb.png b/web/static/js9_old/images/voyager/color_bb.png deleted file mode 100644 index 9e005eaa1cfc59fc842998c04d6ab900f784cb39..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_bb.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_blue.png b/web/static/js9_old/images/voyager/color_blue.png deleted file mode 100644 index 8c26079bc63815ac4c9799d7a9e92333f29329f2..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_blue.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_color.png b/web/static/js9_old/images/voyager/color_color.png deleted file mode 100644 index 88f6a20e9d0dcd700ff146b67d570af20aa638bd..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_color.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_cool.png b/web/static/js9_old/images/voyager/color_cool.png deleted file mode 100644 index 8e43a8cecdeb3ba95ba61373b7ec53a15dcf23f1..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_cool.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_green.png b/web/static/js9_old/images/voyager/color_green.png deleted file mode 100644 index 63dcac937129ef26062146cad43ca410de04e4cf..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_green.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_grey.png b/web/static/js9_old/images/voyager/color_grey.png deleted file mode 100644 index addfaad34f0fbb501c9dfd20cfe44f1450183454..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_grey.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_he.png b/web/static/js9_old/images/voyager/color_he.png deleted file mode 100644 index 1e9972ea67892eb9846b1cdc560f03420e32d467..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_he.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_heat.png b/web/static/js9_old/images/voyager/color_heat.png deleted file mode 100644 index 5b4512e347931cc7cbd8fa71356a6fe297e60f63..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_heat.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_hsv.png b/web/static/js9_old/images/voyager/color_hsv.png deleted file mode 100644 index 90c7fb7bb41fd77aa53b04d6c7d1d3cdb6891f80..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_hsv.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_i8.png b/web/static/js9_old/images/voyager/color_i8.png deleted file mode 100644 index 9a9976a6f290508ddff612dff6a101e392db8bd0..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_i8.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_inferno.png b/web/static/js9_old/images/voyager/color_inferno.png deleted file mode 100644 index 86bdceb58d6ec6b7dbea419021b12adfe1b76992..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_inferno.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_magma.png b/web/static/js9_old/images/voyager/color_magma.png deleted file mode 100644 index 4be28a369be8095c473684cf53a6711f741aa627..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_magma.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_parula.png b/web/static/js9_old/images/voyager/color_parula.png deleted file mode 100644 index d5bc95183022564f57df99cc28e815f5eef167af..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_parula.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_plasma.png b/web/static/js9_old/images/voyager/color_plasma.png deleted file mode 100644 index b9c842cfd085d1a4c4ea8e48472244493a44d6f5..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_plasma.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_rainbow.png b/web/static/js9_old/images/voyager/color_rainbow.png deleted file mode 100644 index 6f90fe50e500b899dbf5e5606a336e9bdab4b3a4..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_rainbow.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_red.png b/web/static/js9_old/images/voyager/color_red.png deleted file mode 100644 index 79af62e6c727cd4a17d38ae2cccb4ddb1396d8a5..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_red.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_sls.png b/web/static/js9_old/images/voyager/color_sls.png deleted file mode 100644 index 9f0b9d37232b6390fe14651fddfa8e9c06d5e082..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_sls.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_staircase.png b/web/static/js9_old/images/voyager/color_staircase.png deleted file mode 100644 index 2e8136280a67003931d27584577944c919690660..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_staircase.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_standard.png b/web/static/js9_old/images/voyager/color_standard.png deleted file mode 100644 index dfe88b8bbb2a3c9de2387a41f2667540253c4992..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_standard.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_turbo.png b/web/static/js9_old/images/voyager/color_turbo.png deleted file mode 100644 index 0ef988d221f7a6eadae322f840f80973544e36d9..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_turbo.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/color_viridis.png b/web/static/js9_old/images/voyager/color_viridis.png deleted file mode 100644 index 785019a6f69b32e4fdb3c1722bc0357ce8b66a75..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyager/color_viridis.png and /dev/null differ diff --git a/web/static/js9_old/images/voyager/regions_annulus.svg b/web/static/js9_old/images/voyager/regions_annulus.svg deleted file mode 100644 index 841706aecfb5cf476514369c55c366e433885281..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/regions_annulus.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/web/static/js9_old/images/voyager/regions_box.svg b/web/static/js9_old/images/voyager/regions_box.svg deleted file mode 100644 index 1dbcd1fabbfb8466505849470a8ef8e3cede1698..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/regions_box.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/web/static/js9_old/images/voyager/regions_circle.svg b/web/static/js9_old/images/voyager/regions_circle.svg deleted file mode 100644 index 71e1a3a036ea6fc5f05011ffd7980b068e73bfa2..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/regions_circle.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/web/static/js9_old/images/voyager/regions_cross.svg b/web/static/js9_old/images/voyager/regions_cross.svg deleted file mode 100644 index 2188a624443c21da6d45d041ec4e482a39f1e04a..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/regions_cross.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/web/static/js9_old/images/voyager/regions_ellipse.svg b/web/static/js9_old/images/voyager/regions_ellipse.svg deleted file mode 100644 index 10e0bb298f4cca30b0d483509a284d231e071510..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/regions_ellipse.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/web/static/js9_old/images/voyager/regions_line.svg b/web/static/js9_old/images/voyager/regions_line.svg deleted file mode 100644 index edb396d3da14962fc3b32632995b48c8d9fbe511..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/regions_line.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/web/static/js9_old/images/voyager/regions_point.svg b/web/static/js9_old/images/voyager/regions_point.svg deleted file mode 100644 index 8f72841f99bbfb5be7d75b93ea123094c46774ed..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/regions_point.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/web/static/js9_old/images/voyager/regions_polygon.svg b/web/static/js9_old/images/voyager/regions_polygon.svg deleted file mode 100644 index 822100dd1f6fda72561b738a51c391e77b778ddd..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/regions_polygon.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/web/static/js9_old/images/voyager/regions_text.svg b/web/static/js9_old/images/voyager/regions_text.svg deleted file mode 100644 index cb892097c3024baba16792a4963aa89f6b0994bd..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/regions_text.svg +++ /dev/null @@ -1 +0,0 @@ -txt \ No newline at end of file diff --git a/web/static/js9_old/images/voyager/zoom_1.svg b/web/static/js9_old/images/voyager/zoom_1.svg deleted file mode 100644 index 18bb5fda888799327df7739ba9259ce5ad17e943..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/zoom_1.svg +++ /dev/null @@ -1 +0,0 @@ -mag1 \ No newline at end of file diff --git a/web/static/js9_old/images/voyager/zoom_in.svg b/web/static/js9_old/images/voyager/zoom_in.svg deleted file mode 100644 index 74ed81f985e7f38d6e1d97ede01036c89e250421..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/zoom_in.svg +++ /dev/null @@ -1 +0,0 @@ -magplus \ No newline at end of file diff --git a/web/static/js9_old/images/voyager/zoom_mag.svg b/web/static/js9_old/images/voyager/zoom_mag.svg deleted file mode 100644 index 4da9d2b10235efd4e2a59381e3821b53f52c9a96..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/zoom_mag.svg +++ /dev/null @@ -1 +0,0 @@ -mag \ No newline at end of file diff --git a/web/static/js9_old/images/voyager/zoom_out.svg b/web/static/js9_old/images/voyager/zoom_out.svg deleted file mode 100644 index c33604dbc5c9d17d67caf0ce67149bc2a6b4f05b..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/zoom_out.svg +++ /dev/null @@ -1 +0,0 @@ -magminus \ No newline at end of file diff --git a/web/static/js9_old/images/voyager/zoom_tofit.svg b/web/static/js9_old/images/voyager/zoom_tofit.svg deleted file mode 100644 index 8066e258c9dadefe6b9d61ef88e833ae35f0fb8c..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/zoom_tofit.svg +++ /dev/null @@ -1 +0,0 @@ -magtofit \ No newline at end of file diff --git a/web/static/js9_old/images/voyager/zoom_zoom.svg b/web/static/js9_old/images/voyager/zoom_zoom.svg deleted file mode 100644 index 4da9d2b10235efd4e2a59381e3821b53f52c9a96..0000000000000000000000000000000000000000 --- a/web/static/js9_old/images/voyager/zoom_zoom.svg +++ /dev/null @@ -1 +0,0 @@ -mag \ No newline at end of file diff --git a/web/static/js9_old/images/voyagerlogo.png b/web/static/js9_old/images/voyagerlogo.png deleted file mode 100644 index 56dd8792f0cb9c04916aad2853d23e434f8714d0..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/images/voyagerlogo.png and /dev/null differ diff --git a/web/static/js9_old/js/ElementQueries.js b/web/static/js9_old/js/ElementQueries.js deleted file mode 100755 index 4fe4298a629f0c8f412c282ba5b26f5afd8edbef..0000000000000000000000000000000000000000 --- a/web/static/js9_old/js/ElementQueries.js +++ /dev/null @@ -1,530 +0,0 @@ -'use strict'; - -/** - * Copyright Marc J. Schmidt. See the LICENSE file at the top-level - * directory of this distribution and at - * https://github.com/marcj/css-element-queries/blob/master/LICENSE. - */ -(function (root, factory) { - if (typeof define === "function" && define.amd) { - define(['./ResizeSensor.js'], factory); - } else if (typeof exports === "object") { - module.exports = factory(require('./ResizeSensor.js')); - } else { - root.ElementQueries = factory(root.ResizeSensor); - root.ElementQueries.listen(); - } -}(typeof window !== 'undefined' ? window : this, function (ResizeSensor) { - - /** - * - * @type {Function} - * @constructor - */ - var ElementQueries = function () { - //\n' - ].join(''); - } - - return markup; - }, - - /** - * @private - */ - _setSVGObjects: function(markup, reviver) { - var instance, i, len, objects = this._objects; - for (i = 0, len = objects.length; i < len; i++) { - instance = objects[i]; - if (instance.excludeFromExport) { - continue; - } - this._setSVGObject(markup, instance, reviver); - } - }, - - /** - * @private - */ - _setSVGObject: function(markup, instance, reviver) { - markup.push(instance.toSVG(reviver)); - }, - - /** - * @private - */ - _setSVGBgOverlayImage: function(markup, property, reviver) { - if (this[property] && !this[property].excludeFromExport && this[property].toSVG) { - markup.push(this[property].toSVG(reviver)); - } - }, - - /** - * @private - */ - _setSVGBgOverlayColor: function(markup, property) { - var filler = this[property + 'Color'], vpt = this.viewportTransform, finalWidth = this.width, - finalHeight = this.height; - if (!filler) { - return; - } - if (filler.toLive) { - var repeat = filler.repeat, iVpt = fabric.util.invertTransform(vpt), shouldInvert = this[property + 'Vpt'], - additionalTransform = shouldInvert ? fabric.util.matrixToSVG(iVpt) : ''; - markup.push( - '\n' - ); - } - else { - markup.push( - '\n' - ); - } - }, - /* _TO_SVG_END_ */ - - /** - * Moves an object or the objects of a multiple selection - * to the bottom of the stack of drawn objects - * @param {fabric.Object} object Object to send to back - * @return {fabric.Canvas} thisArg - * @chainable - */ - sendToBack: function (object) { - if (!object) { - return this; - } - var activeSelection = this._activeObject, - i, obj, objs; - if (object === activeSelection && object.type === 'activeSelection') { - objs = activeSelection._objects; - for (i = objs.length; i--;) { - obj = objs[i]; - removeFromArray(this._objects, obj); - this._objects.unshift(obj); - } - } - else { - removeFromArray(this._objects, object); - this._objects.unshift(object); - } - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * Moves an object or the objects of a multiple selection - * to the top of the stack of drawn objects - * @param {fabric.Object} object Object to send - * @return {fabric.Canvas} thisArg - * @chainable - */ - bringToFront: function (object) { - if (!object) { - return this; - } - var activeSelection = this._activeObject, - i, obj, objs; - if (object === activeSelection && object.type === 'activeSelection') { - objs = activeSelection._objects; - for (i = 0; i < objs.length; i++) { - obj = objs[i]; - removeFromArray(this._objects, obj); - this._objects.push(obj); - } - } - else { - removeFromArray(this._objects, object); - this._objects.push(object); - } - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * Moves an object or a selection down in stack of drawn objects - * An optional parameter, intersecting allows to move the object in behind - * the first intersecting object. Where intersection is calculated with - * bounding box. If no intersection is found, there will not be change in the - * stack. - * @param {fabric.Object} object Object to send - * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object - * @return {fabric.Canvas} thisArg - * @chainable - */ - sendBackwards: function (object, intersecting) { - if (!object) { - return this; - } - var activeSelection = this._activeObject, - i, obj, idx, newIdx, objs, objsMoved = 0; - - if (object === activeSelection && object.type === 'activeSelection') { - objs = activeSelection._objects; - for (i = 0; i < objs.length; i++) { - obj = objs[i]; - idx = this._objects.indexOf(obj); - if (idx > 0 + objsMoved) { - newIdx = idx - 1; - removeFromArray(this._objects, obj); - this._objects.splice(newIdx, 0, obj); - } - objsMoved++; - } - } - else { - idx = this._objects.indexOf(object); - if (idx !== 0) { - // if object is not on the bottom of stack - newIdx = this._findNewLowerIndex(object, idx, intersecting); - removeFromArray(this._objects, object); - this._objects.splice(newIdx, 0, object); - } - } - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * @private - */ - _findNewLowerIndex: function(object, idx, intersecting) { - var newIdx, i; - - if (intersecting) { - newIdx = idx; - - // traverse down the stack looking for the nearest intersecting object - for (i = idx - 1; i >= 0; --i) { - - var isIntersecting = object.intersectsWithObject(this._objects[i]) || - object.isContainedWithinObject(this._objects[i]) || - this._objects[i].isContainedWithinObject(object); - - if (isIntersecting) { - newIdx = i; - break; - } - } - } - else { - newIdx = idx - 1; - } - - return newIdx; - }, - - /** - * Moves an object or a selection up in stack of drawn objects - * An optional parameter, intersecting allows to move the object in front - * of the first intersecting object. Where intersection is calculated with - * bounding box. If no intersection is found, there will not be change in the - * stack. - * @param {fabric.Object} object Object to send - * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object - * @return {fabric.Canvas} thisArg - * @chainable - */ - bringForward: function (object, intersecting) { - if (!object) { - return this; - } - var activeSelection = this._activeObject, - i, obj, idx, newIdx, objs, objsMoved = 0; - - if (object === activeSelection && object.type === 'activeSelection') { - objs = activeSelection._objects; - for (i = objs.length; i--;) { - obj = objs[i]; - idx = this._objects.indexOf(obj); - if (idx < this._objects.length - 1 - objsMoved) { - newIdx = idx + 1; - removeFromArray(this._objects, obj); - this._objects.splice(newIdx, 0, obj); - } - objsMoved++; - } - } - else { - idx = this._objects.indexOf(object); - if (idx !== this._objects.length - 1) { - // if object is not on top of stack (last item in an array) - newIdx = this._findNewUpperIndex(object, idx, intersecting); - removeFromArray(this._objects, object); - this._objects.splice(newIdx, 0, object); - } - } - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * @private - */ - _findNewUpperIndex: function(object, idx, intersecting) { - var newIdx, i, len; - - if (intersecting) { - newIdx = idx; - - // traverse up the stack looking for the nearest intersecting object - for (i = idx + 1, len = this._objects.length; i < len; ++i) { - - var isIntersecting = object.intersectsWithObject(this._objects[i]) || - object.isContainedWithinObject(this._objects[i]) || - this._objects[i].isContainedWithinObject(object); - - if (isIntersecting) { - newIdx = i; - break; - } - } - } - else { - newIdx = idx + 1; - } - - return newIdx; - }, - - /** - * Moves an object to specified level in stack of drawn objects - * @param {fabric.Object} object Object to send - * @param {Number} index Position to move to - * @return {fabric.Canvas} thisArg - * @chainable - */ - moveTo: function (object, index) { - removeFromArray(this._objects, object); - this._objects.splice(index, 0, object); - return this.renderOnAddRemove && this.requestRenderAll(); - }, - - /** - * Clears a canvas element and dispose objects - * @return {fabric.Canvas} thisArg - * @chainable - */ - dispose: function () { - // cancel eventually ongoing renders - if (this.isRendering) { - fabric.util.cancelAnimFrame(this.isRendering); - this.isRendering = 0; - } - this.forEachObject(function(object) { - object.dispose && object.dispose(); - }); - this._objects = []; - if (this.backgroundImage && this.backgroundImage.dispose) { - this.backgroundImage.dispose(); - } - this.backgroundImage = null; - if (this.overlayImage && this.overlayImage.dispose) { - this.overlayImage.dispose(); - } - this.overlayImage = null; - this._iTextInstances = null; - this.contextContainer = null; - fabric.util.cleanUpJsdomNode(this.lowerCanvasEl); - this.lowerCanvasEl = undefined; - return this; - }, - - /** - * Returns a string representation of an instance - * @return {String} string representation of an instance - */ - toString: function () { - return '#'; - } - }); - - extend(fabric.StaticCanvas.prototype, fabric.Observable); - extend(fabric.StaticCanvas.prototype, fabric.Collection); - extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter); - - extend(fabric.StaticCanvas, /** @lends fabric.StaticCanvas */ { - - /** - * @static - * @type String - * @default - */ - EMPTY_JSON: '{"objects": [], "background": "white"}', - - /** - * Provides a way to check support of some of the canvas methods - * (either those of HTMLCanvasElement itself, or rendering context) - * - * @param {String} methodName Method to check support for; - * Could be one of "setLineDash" - * @return {Boolean | null} `true` if method is supported (or at least exists), - * `null` if canvas element or context can not be initialized - */ - supports: function (methodName) { - var el = createCanvasElement(); - - if (!el || !el.getContext) { - return null; - } - - var ctx = el.getContext('2d'); - if (!ctx) { - return null; - } - - switch (methodName) { - - case 'setLineDash': - return typeof ctx.setLineDash !== 'undefined'; - - default: - return null; - } - } - }); - - /** - * Returns Object representation of canvas - * this alias is provided because if you call JSON.stringify on an instance, - * the toJSON object will be invoked if it exists. - * Having a toJSON method means you can do JSON.stringify(myCanvas) - * @function - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} JSON compatible object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization} - * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo} - * @example JSON without additional properties - * var json = canvas.toJSON(); - * @example JSON with additional properties included - * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY']); - * @example JSON without default values - * canvas.includeDefaultValues = false; - * var json = canvas.toJSON(); - */ - fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject; - - if (fabric.isLikelyNode) { - fabric.StaticCanvas.prototype.createPNGStream = function() { - var impl = getNodeCanvas(this.lowerCanvasEl); - return impl && impl.createPNGStream(); - }; - fabric.StaticCanvas.prototype.createJPEGStream = function(opts) { - var impl = getNodeCanvas(this.lowerCanvasEl); - return impl && impl.createJPEGStream(opts); - }; - } -})(); - - -/** - * BaseBrush class - * @class fabric.BaseBrush - * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo} - */ -fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ { - - /** - * Color of a brush - * @type String - * @default - */ - color: 'rgb(0, 0, 0)', - - /** - * Width of a brush, has to be a Number, no string literals - * @type Number - * @default - */ - width: 1, - - /** - * Shadow object representing shadow of this shape. - * Backwards incompatibility note: This property replaces "shadowColor" (String), "shadowOffsetX" (Number), - * "shadowOffsetY" (Number) and "shadowBlur" (Number) since v1.2.12 - * @type fabric.Shadow - * @default - */ - shadow: null, - - /** - * Line endings style of a brush (one of "butt", "round", "square") - * @type String - * @default - */ - strokeLineCap: 'round', - - /** - * Corner style of a brush (one of "bevel", "round", "miter") - * @type String - * @default - */ - strokeLineJoin: 'round', - - /** - * Maximum miter length (used for strokeLineJoin = "miter") of a brush's - * @type Number - * @default - */ - strokeMiterLimit: 10, - - /** - * Stroke Dash Array. - * @type Array - * @default - */ - strokeDashArray: null, - - /** - * When `true`, the free drawing is limited to the whiteboard size. Default to false. - * @type Boolean - * @default false - */ - - limitedToCanvasSize: false, - - - /** - * Sets brush styles - * @private - */ - _setBrushStyles: function() { - var ctx = this.canvas.contextTop; - ctx.strokeStyle = this.color; - ctx.lineWidth = this.width; - ctx.lineCap = this.strokeLineCap; - ctx.miterLimit = this.strokeMiterLimit; - ctx.lineJoin = this.strokeLineJoin; - if (fabric.StaticCanvas.supports('setLineDash')) { - ctx.setLineDash(this.strokeDashArray || []); - } - }, - - /** - * Sets the transformation on given context - * @param {RenderingContext2d} ctx context to render on - * @private - */ - _saveAndTransform: function(ctx) { - var v = this.canvas.viewportTransform; - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - }, - - /** - * Sets brush shadow styles - * @private - */ - _setShadow: function() { - if (!this.shadow) { - return; - } - - var canvas = this.canvas, - shadow = this.shadow, - ctx = canvas.contextTop, - zoom = canvas.getZoom(); - if (canvas && canvas._isRetinaScaling()) { - zoom *= fabric.devicePixelRatio; - } - - ctx.shadowColor = shadow.color; - ctx.shadowBlur = shadow.blur * zoom; - ctx.shadowOffsetX = shadow.offsetX * zoom; - ctx.shadowOffsetY = shadow.offsetY * zoom; - }, - - needsFullRender: function() { - var color = new fabric.Color(this.color); - return color.getAlpha() < 1 || !!this.shadow; - }, - - /** - * Removes brush shadow styles - * @private - */ - _resetShadow: function() { - var ctx = this.canvas.contextTop; - - ctx.shadowColor = ''; - ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0; - }, - - /** - * Check is pointer is outside canvas boundaries - * @param {Object} pointer - * @private - */ - _isOutSideCanvas: function(pointer) { - return pointer.x < 0 || pointer.x > this.canvas.getWidth() || pointer.y < 0 || pointer.y > this.canvas.getHeight(); - } -}); - - -(function() { - /** - * PencilBrush class - * @class fabric.PencilBrush - * @extends fabric.BaseBrush - */ - fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.PencilBrush.prototype */ { - - /** - * Discard points that are less than `decimate` pixel distant from each other - * @type Number - * @default 0.4 - */ - decimate: 0.4, - - /** - * Constructor - * @param {fabric.Canvas} canvas - * @return {fabric.PencilBrush} Instance of a pencil brush - */ - initialize: function(canvas) { - this.canvas = canvas; - this._points = []; - }, - - /** - * Invoked inside on mouse down and mouse move - * @param {Object} pointer - */ - _drawSegment: function (ctx, p1, p2) { - var midPoint = p1.midPointFrom(p2); - ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y); - return midPoint; - }, - - /** - * Invoked on mouse down - * @param {Object} pointer - */ - onMouseDown: function(pointer, options) { - if (!this.canvas._isMainEvent(options.e)) { - return; - } - this._prepareForDrawing(pointer); - // capture coordinates immediately - // this allows to draw dots (when movement never occurs) - this._captureDrawingPath(pointer); - this._render(); - }, - - /** - * Invoked on mouse move - * @param {Object} pointer - */ - onMouseMove: function(pointer, options) { - if (!this.canvas._isMainEvent(options.e)) { - return; - } - if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) { - return; - } - if (this._captureDrawingPath(pointer) && this._points.length > 1) { - if (this.needsFullRender()) { - // redraw curve - // clear top canvas - this.canvas.clearContext(this.canvas.contextTop); - this._render(); - } - else { - var points = this._points, length = points.length, ctx = this.canvas.contextTop; - // draw the curve update - this._saveAndTransform(ctx); - if (this.oldEnd) { - ctx.beginPath(); - ctx.moveTo(this.oldEnd.x, this.oldEnd.y); - } - this.oldEnd = this._drawSegment(ctx, points[length - 2], points[length - 1], true); - ctx.stroke(); - ctx.restore(); - } - } - }, - - /** - * Invoked on mouse up - */ - onMouseUp: function(options) { - if (!this.canvas._isMainEvent(options.e)) { - return true; - } - this.oldEnd = undefined; - this._finalizeAndAddPath(); - return false; - }, - - /** - * @private - * @param {Object} pointer Actual mouse position related to the canvas. - */ - _prepareForDrawing: function(pointer) { - - var p = new fabric.Point(pointer.x, pointer.y); - - this._reset(); - this._addPoint(p); - this.canvas.contextTop.moveTo(p.x, p.y); - }, - - /** - * @private - * @param {fabric.Point} point Point to be added to points array - */ - _addPoint: function(point) { - if (this._points.length > 1 && point.eq(this._points[this._points.length - 1])) { - return false; - } - this._points.push(point); - return true; - }, - - /** - * Clear points array and set contextTop canvas style. - * @private - */ - _reset: function() { - this._points = []; - this._setBrushStyles(); - this._setShadow(); - }, - - /** - * @private - * @param {Object} pointer Actual mouse position related to the canvas. - */ - _captureDrawingPath: function(pointer) { - var pointerPoint = new fabric.Point(pointer.x, pointer.y); - return this._addPoint(pointerPoint); - }, - - /** - * Draw a smooth path on the topCanvas using quadraticCurveTo - * @private - */ - _render: function() { - var ctx = this.canvas.contextTop, i, len, - p1 = this._points[0], - p2 = this._points[1]; - - this._saveAndTransform(ctx); - ctx.beginPath(); - //if we only have 2 points in the path and they are the same - //it means that the user only clicked the canvas without moving the mouse - //then we should be drawing a dot. A path isn't drawn between two identical dots - //that's why we set them apart a bit - if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) { - var width = this.width / 1000; - p1 = new fabric.Point(p1.x, p1.y); - p2 = new fabric.Point(p2.x, p2.y); - p1.x -= width; - p2.x += width; - } - ctx.moveTo(p1.x, p1.y); - - for (i = 1, len = this._points.length; i < len; i++) { - // we pick the point between pi + 1 & pi + 2 as the - // end point and p1 as our control point. - this._drawSegment(ctx, p1, p2); - p1 = this._points[i]; - p2 = this._points[i + 1]; - } - // Draw last line as a straight line while - // we wait for the next point to be able to calculate - // the bezier control point - ctx.lineTo(p1.x, p1.y); - ctx.stroke(); - ctx.restore(); - }, - - /** - * Converts points to SVG path - * @param {Array} points Array of points - * @return {String} SVG path - */ - convertPointsToSVGPath: function(points) { - var path = [], i, width = this.width / 1000, - p1 = new fabric.Point(points[0].x, points[0].y), - p2 = new fabric.Point(points[1].x, points[1].y), - len = points.length, multSignX = 1, multSignY = 0, manyPoints = len > 2; - - if (manyPoints) { - multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1; - multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1; - } - path.push('M ', p1.x - multSignX * width, ' ', p1.y - multSignY * width, ' '); - for (i = 1; i < len; i++) { - if (!p1.eq(p2)) { - var midPoint = p1.midPointFrom(p2); - // p1 is our bezier control point - // midpoint is our endpoint - // start point is p(i-1) value. - path.push('Q ', p1.x, ' ', p1.y, ' ', midPoint.x, ' ', midPoint.y, ' '); - } - p1 = points[i]; - if ((i + 1) < points.length) { - p2 = points[i + 1]; - } - } - if (manyPoints) { - multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1; - multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1; - } - path.push('L ', p1.x + multSignX * width, ' ', p1.y + multSignY * width); - return path; - }, - - /** - * Creates fabric.Path object to add on canvas - * @param {String} pathData Path data - * @return {fabric.Path} Path to add on canvas - */ - createPath: function(pathData) { - var path = new fabric.Path(pathData, { - fill: null, - stroke: this.color, - strokeWidth: this.width, - strokeLineCap: this.strokeLineCap, - strokeMiterLimit: this.strokeMiterLimit, - strokeLineJoin: this.strokeLineJoin, - strokeDashArray: this.strokeDashArray, - }); - if (this.shadow) { - this.shadow.affectStroke = true; - path.shadow = new fabric.Shadow(this.shadow); - } - - return path; - }, - - /** - * Decimate points array with the decimate value - */ - decimatePoints: function(points, distance) { - if (points.length <= 2) { - return points; - } - var zoom = this.canvas.getZoom(), adjustedDistance = Math.pow(distance / zoom, 2), - i, l = points.length - 1, lastPoint = points[0], newPoints = [lastPoint], - cDistance; - for (i = 1; i < l - 1; i++) { - cDistance = Math.pow(lastPoint.x - points[i].x, 2) + Math.pow(lastPoint.y - points[i].y, 2); - if (cDistance >= adjustedDistance) { - lastPoint = points[i]; - newPoints.push(lastPoint); - } - } - /** - * Add the last point from the original line to the end of the array. - * This ensures decimate doesn't delete the last point on the line, and ensures the line is > 1 point. - */ - newPoints.push(points[l]); - return newPoints; - }, - - /** - * On mouseup after drawing the path on contextTop canvas - * we use the points captured to create an new fabric path object - * and add it to the fabric canvas. - */ - _finalizeAndAddPath: function() { - var ctx = this.canvas.contextTop; - ctx.closePath(); - if (this.decimate) { - this._points = this.decimatePoints(this._points, this.decimate); - } - var pathData = this.convertPointsToSVGPath(this._points).join(''); - if (pathData === 'M 0 0 Q 0 0 0 0 L 0 0') { - // do not create 0 width/height paths, as they are - // rendered inconsistently across browsers - // Firefox 4, for example, renders a dot, - // whereas Chrome 10 renders nothing - this.canvas.requestRenderAll(); - return; - } - - var path = this.createPath(pathData); - this.canvas.clearContext(this.canvas.contextTop); - this.canvas.fire('before:path:created', { path: path }); - this.canvas.add(path); - this.canvas.requestRenderAll(); - path.setCoords(); - this._resetShadow(); - - - // fire event 'path' created - this.canvas.fire('path:created', { path: path }); - } - }); -})(); - - -/** - * CircleBrush class - * @class fabric.CircleBrush - */ -fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.CircleBrush.prototype */ { - - /** - * Width of a brush - * @type Number - * @default - */ - width: 10, - - /** - * Constructor - * @param {fabric.Canvas} canvas - * @return {fabric.CircleBrush} Instance of a circle brush - */ - initialize: function(canvas) { - this.canvas = canvas; - this.points = []; - }, - - /** - * Invoked inside on mouse down and mouse move - * @param {Object} pointer - */ - drawDot: function(pointer) { - var point = this.addPoint(pointer), - ctx = this.canvas.contextTop; - this._saveAndTransform(ctx); - this.dot(ctx, point); - ctx.restore(); - }, - - dot: function(ctx, point) { - ctx.fillStyle = point.fill; - ctx.beginPath(); - ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false); - ctx.closePath(); - ctx.fill(); - }, - - /** - * Invoked on mouse down - */ - onMouseDown: function(pointer) { - this.points.length = 0; - this.canvas.clearContext(this.canvas.contextTop); - this._setShadow(); - this.drawDot(pointer); - }, - - /** - * Render the full state of the brush - * @private - */ - _render: function() { - var ctx = this.canvas.contextTop, i, len, - points = this.points; - this._saveAndTransform(ctx); - for (i = 0, len = points.length; i < len; i++) { - this.dot(ctx, points[i]); - } - ctx.restore(); - }, - - /** - * Invoked on mouse move - * @param {Object} pointer - */ - onMouseMove: function(pointer) { - if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) { - return; - } - if (this.needsFullRender()) { - this.canvas.clearContext(this.canvas.contextTop); - this.addPoint(pointer); - this._render(); - } - else { - this.drawDot(pointer); - } - }, - - /** - * Invoked on mouse up - */ - onMouseUp: function() { - var originalRenderOnAddRemove = this.canvas.renderOnAddRemove, i, len; - this.canvas.renderOnAddRemove = false; - - var circles = []; - - for (i = 0, len = this.points.length; i < len; i++) { - var point = this.points[i], - circle = new fabric.Circle({ - radius: point.radius, - left: point.x, - top: point.y, - originX: 'center', - originY: 'center', - fill: point.fill - }); - - this.shadow && (circle.shadow = new fabric.Shadow(this.shadow)); - - circles.push(circle); - } - var group = new fabric.Group(circles); - group.canvas = this.canvas; - - this.canvas.fire('before:path:created', { path: group }); - this.canvas.add(group); - this.canvas.fire('path:created', { path: group }); - - this.canvas.clearContext(this.canvas.contextTop); - this._resetShadow(); - this.canvas.renderOnAddRemove = originalRenderOnAddRemove; - this.canvas.requestRenderAll(); - }, - - /** - * @param {Object} pointer - * @return {fabric.Point} Just added pointer point - */ - addPoint: function(pointer) { - var pointerPoint = new fabric.Point(pointer.x, pointer.y), - - circleRadius = fabric.util.getRandomInt( - Math.max(0, this.width - 20), this.width + 20) / 2, - - circleColor = new fabric.Color(this.color) - .setAlpha(fabric.util.getRandomInt(0, 100) / 100) - .toRgba(); - - pointerPoint.radius = circleRadius; - pointerPoint.fill = circleColor; - - this.points.push(pointerPoint); - - return pointerPoint; - } -}); - - -/** - * SprayBrush class - * @class fabric.SprayBrush - */ -fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric.SprayBrush.prototype */ { - - /** - * Width of a spray - * @type Number - * @default - */ - width: 10, - - /** - * Density of a spray (number of dots per chunk) - * @type Number - * @default - */ - density: 20, - - /** - * Width of spray dots - * @type Number - * @default - */ - dotWidth: 1, - - /** - * Width variance of spray dots - * @type Number - * @default - */ - dotWidthVariance: 1, - - /** - * Whether opacity of a dot should be random - * @type Boolean - * @default - */ - randomOpacity: false, - - /** - * Whether overlapping dots (rectangles) should be removed (for performance reasons) - * @type Boolean - * @default - */ - optimizeOverlapping: true, - - /** - * Constructor - * @param {fabric.Canvas} canvas - * @return {fabric.SprayBrush} Instance of a spray brush - */ - initialize: function(canvas) { - this.canvas = canvas; - this.sprayChunks = []; - }, - - /** - * Invoked on mouse down - * @param {Object} pointer - */ - onMouseDown: function(pointer) { - this.sprayChunks.length = 0; - this.canvas.clearContext(this.canvas.contextTop); - this._setShadow(); - - this.addSprayChunk(pointer); - this.render(this.sprayChunkPoints); - }, - - /** - * Invoked on mouse move - * @param {Object} pointer - */ - onMouseMove: function(pointer) { - if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) { - return; - } - this.addSprayChunk(pointer); - this.render(this.sprayChunkPoints); - }, - - /** - * Invoked on mouse up - */ - onMouseUp: function() { - var originalRenderOnAddRemove = this.canvas.renderOnAddRemove; - this.canvas.renderOnAddRemove = false; - - var rects = []; - - for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) { - var sprayChunk = this.sprayChunks[i]; - - for (var j = 0, jlen = sprayChunk.length; j < jlen; j++) { - - var rect = new fabric.Rect({ - width: sprayChunk[j].width, - height: sprayChunk[j].width, - left: sprayChunk[j].x + 1, - top: sprayChunk[j].y + 1, - originX: 'center', - originY: 'center', - fill: this.color - }); - rects.push(rect); - } - } - - if (this.optimizeOverlapping) { - rects = this._getOptimizedRects(rects); - } - - var group = new fabric.Group(rects); - this.shadow && group.set('shadow', new fabric.Shadow(this.shadow)); - this.canvas.fire('before:path:created', { path: group }); - this.canvas.add(group); - this.canvas.fire('path:created', { path: group }); - - this.canvas.clearContext(this.canvas.contextTop); - this._resetShadow(); - this.canvas.renderOnAddRemove = originalRenderOnAddRemove; - this.canvas.requestRenderAll(); - }, - - /** - * @private - * @param {Array} rects - */ - _getOptimizedRects: function(rects) { - - // avoid creating duplicate rects at the same coordinates - var uniqueRects = { }, key, i, len; - - for (i = 0, len = rects.length; i < len; i++) { - key = rects[i].left + '' + rects[i].top; - if (!uniqueRects[key]) { - uniqueRects[key] = rects[i]; - } - } - var uniqueRectsArray = []; - for (key in uniqueRects) { - uniqueRectsArray.push(uniqueRects[key]); - } - - return uniqueRectsArray; - }, - - /** - * Render new chunk of spray brush - */ - render: function(sprayChunk) { - var ctx = this.canvas.contextTop, i, len; - ctx.fillStyle = this.color; - - this._saveAndTransform(ctx); - - for (i = 0, len = sprayChunk.length; i < len; i++) { - var point = sprayChunk[i]; - if (typeof point.opacity !== 'undefined') { - ctx.globalAlpha = point.opacity; - } - ctx.fillRect(point.x, point.y, point.width, point.width); - } - ctx.restore(); - }, - - /** - * Render all spray chunks - */ - _render: function() { - var ctx = this.canvas.contextTop, i, ilen; - ctx.fillStyle = this.color; - - this._saveAndTransform(ctx); - - for (i = 0, ilen = this.sprayChunks.length; i < ilen; i++) { - this.render(this.sprayChunks[i]); - } - ctx.restore(); - }, - - /** - * @param {Object} pointer - */ - addSprayChunk: function(pointer) { - this.sprayChunkPoints = []; - - var x, y, width, radius = this.width / 2, i; - - for (i = 0; i < this.density; i++) { - - x = fabric.util.getRandomInt(pointer.x - radius, pointer.x + radius); - y = fabric.util.getRandomInt(pointer.y - radius, pointer.y + radius); - - if (this.dotWidthVariance) { - width = fabric.util.getRandomInt( - // bottom clamp width to 1 - Math.max(1, this.dotWidth - this.dotWidthVariance), - this.dotWidth + this.dotWidthVariance); - } - else { - width = this.dotWidth; - } - - var point = new fabric.Point(x, y); - point.width = width; - - if (this.randomOpacity) { - point.opacity = fabric.util.getRandomInt(0, 100) / 100; - } - - this.sprayChunkPoints.push(point); - } - - this.sprayChunks.push(this.sprayChunkPoints); - } -}); - - -/** - * PatternBrush class - * @class fabric.PatternBrush - * @extends fabric.BaseBrush - */ -fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fabric.PatternBrush.prototype */ { - - getPatternSrc: function() { - - var dotWidth = 20, - dotDistance = 5, - patternCanvas = fabric.util.createCanvasElement(), - patternCtx = patternCanvas.getContext('2d'); - - patternCanvas.width = patternCanvas.height = dotWidth + dotDistance; - - patternCtx.fillStyle = this.color; - patternCtx.beginPath(); - patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false); - patternCtx.closePath(); - patternCtx.fill(); - - return patternCanvas; - }, - - getPatternSrcFunction: function() { - return String(this.getPatternSrc).replace('this.color', '"' + this.color + '"'); - }, - - /** - * Creates "pattern" instance property - */ - getPattern: function() { - return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), 'repeat'); - }, - - /** - * Sets brush styles - */ - _setBrushStyles: function() { - this.callSuper('_setBrushStyles'); - this.canvas.contextTop.strokeStyle = this.getPattern(); - }, - - /** - * Creates path - */ - createPath: function(pathData) { - var path = this.callSuper('createPath', pathData), - topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2); - - path.stroke = new fabric.Pattern({ - source: this.source || this.getPatternSrcFunction(), - offsetX: -topLeft.x, - offsetY: -topLeft.y - }); - return path; - } -}); - - -(function() { - - var getPointer = fabric.util.getPointer, - degreesToRadians = fabric.util.degreesToRadians, - abs = Math.abs, - supportLineDash = fabric.StaticCanvas.supports('setLineDash'), - isTouchEvent = fabric.util.isTouchEvent, - STROKE_OFFSET = 0.5; - - /** - * Canvas class - * @class fabric.Canvas - * @extends fabric.StaticCanvas - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas} - * @see {@link fabric.Canvas#initialize} for constructor definition - * - * @fires object:modified at the end of a transform or any change when statefull is true - * @fires object:rotating while an object is being rotated from the control - * @fires object:scaling while an object is being scaled by controls - * @fires object:moving while an object is being dragged - * @fires object:skewing while an object is being skewed from the controls - * - * @fires before:transform before a transform is is started - * @fires before:selection:cleared - * @fires selection:cleared - * @fires selection:updated - * @fires selection:created - * - * @fires path:created after a drawing operation ends and the path is added - * @fires mouse:down - * @fires mouse:move - * @fires mouse:up - * @fires mouse:down:before on mouse down, before the inner fabric logic runs - * @fires mouse:move:before on mouse move, before the inner fabric logic runs - * @fires mouse:up:before on mouse up, before the inner fabric logic runs - * @fires mouse:over - * @fires mouse:out - * @fires mouse:dblclick whenever a native dbl click event fires on the canvas. - * - * @fires dragover - * @fires dragenter - * @fires dragleave - * @fires drop - * @fires after:render at the end of the render process, receives the context in the callback - * @fires before:render at start the render process, receives the context in the callback - * - * the following events are deprecated: - * @fires object:rotated at the end of a rotation transform - * @fires object:scaled at the end of a scale transform - * @fires object:moved at the end of translation transform - * @fires object:skewed at the end of a skew transform - */ - fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, /** @lends fabric.Canvas.prototype */ { - - /** - * Constructor - * @param {HTMLElement | String} el <canvas> element to initialize instance on - * @param {Object} [options] Options object - * @return {Object} thisArg - */ - initialize: function(el, options) { - options || (options = { }); - this.renderAndResetBound = this.renderAndReset.bind(this); - this.requestRenderAllBound = this.requestRenderAll.bind(this); - this._initStatic(el, options); - this._initInteractive(); - this._createCacheCanvas(); - }, - - /** - * When true, objects can be transformed by one side (unproportionally) - * when dragged on the corners that normally would not do that. - * @type Boolean - * @default - * @since fabric 4.0 // changed name and default value - */ - uniformScaling: true, - - /** - * Indicates which key switches uniform scaling. - * values: 'altKey', 'shiftKey', 'ctrlKey'. - * If `null` or 'none' or any other string that is not a modifier key - * feature is disabled. - * totally wrong named. this sounds like `uniform scaling` - * if Canvas.uniformScaling is true, pressing this will set it to false - * and viceversa. - * @since 1.6.2 - * @type String - * @default - */ - uniScaleKey: 'shiftKey', - - /** - * When true, objects use center point as the origin of scale transformation. - * Backwards incompatibility note: This property replaces "centerTransform" (Boolean). - * @since 1.3.4 - * @type Boolean - * @default - */ - centeredScaling: false, - - /** - * When true, objects use center point as the origin of rotate transformation. - * Backwards incompatibility note: This property replaces "centerTransform" (Boolean). - * @since 1.3.4 - * @type Boolean - * @default - */ - centeredRotation: false, - - /** - * Indicates which key enable centered Transform - * values: 'altKey', 'shiftKey', 'ctrlKey'. - * If `null` or 'none' or any other string that is not a modifier key - * feature is disabled feature disabled. - * @since 1.6.2 - * @type String - * @default - */ - centeredKey: 'altKey', - - /** - * Indicates which key enable alternate action on corner - * values: 'altKey', 'shiftKey', 'ctrlKey'. - * If `null` or 'none' or any other string that is not a modifier key - * feature is disabled feature disabled. - * @since 1.6.2 - * @type String - * @default - */ - altActionKey: 'shiftKey', - - /** - * Indicates that canvas is interactive. This property should not be changed. - * @type Boolean - * @default - */ - interactive: true, - - /** - * Indicates whether group selection should be enabled - * @type Boolean - * @default - */ - selection: true, - - /** - * Indicates which key or keys enable multiple click selection - * Pass value as a string or array of strings - * values: 'altKey', 'shiftKey', 'ctrlKey'. - * If `null` or empty or containing any other string that is not a modifier key - * feature is disabled. - * @since 1.6.2 - * @type String|Array - * @default - */ - selectionKey: 'shiftKey', - - /** - * Indicates which key enable alternative selection - * in case of target overlapping with active object - * values: 'altKey', 'shiftKey', 'ctrlKey'. - * For a series of reason that come from the general expectations on how - * things should work, this feature works only for preserveObjectStacking true. - * If `null` or 'none' or any other string that is not a modifier key - * feature is disabled. - * @since 1.6.5 - * @type null|String - * @default - */ - altSelectionKey: null, - - /** - * Color of selection - * @type String - * @default - */ - selectionColor: 'rgba(100, 100, 255, 0.3)', // blue - - /** - * Default dash array pattern - * If not empty the selection border is dashed - * @type Array - */ - selectionDashArray: [], - - /** - * Color of the border of selection (usually slightly darker than color of selection itself) - * @type String - * @default - */ - selectionBorderColor: 'rgba(255, 255, 255, 0.3)', - - /** - * Width of a line used in object/group selection - * @type Number - * @default - */ - selectionLineWidth: 1, - - /** - * Select only shapes that are fully contained in the dragged selection rectangle. - * @type Boolean - * @default - */ - selectionFullyContained: false, - - /** - * Default cursor value used when hovering over an object on canvas - * @type String - * @default - */ - hoverCursor: 'move', - - /** - * Default cursor value used when moving an object on canvas - * @type String - * @default - */ - moveCursor: 'move', - - /** - * Default cursor value used for the entire canvas - * @type String - * @default - */ - defaultCursor: 'default', - - /** - * Cursor value used during free drawing - * @type String - * @default - */ - freeDrawingCursor: 'crosshair', - - /** - * Cursor value used for rotation point - * @type String - * @default - */ - rotationCursor: 'crosshair', - - /** - * Cursor value used for disabled elements ( corners with disabled action ) - * @type String - * @since 2.0.0 - * @default - */ - notAllowedCursor: 'not-allowed', - - /** - * Default element class that's given to wrapper (div) element of canvas - * @type String - * @default - */ - containerClass: 'canvas-container', - - /** - * When true, object detection happens on per-pixel basis rather than on per-bounding-box - * @type Boolean - * @default - */ - perPixelTargetFind: false, - - /** - * Number of pixels around target pixel to tolerate (consider active) during object detection - * @type Number - * @default - */ - targetFindTolerance: 0, - - /** - * When true, target detection is skipped. Target detection will return always undefined. - * click selection won't work anymore, events will fire with no targets. - * if something is selected before setting it to true, it will be deselected at the first click. - * area selection will still work. check the `selection` property too. - * if you deactivate both, you should look into staticCanvas. - * @type Boolean - * @default - */ - skipTargetFind: false, - - /** - * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing. - * After mousedown, mousemove creates a shape, - * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas. - * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing} - * @type Boolean - * @default - */ - isDrawingMode: false, - - /** - * Indicates whether objects should remain in current stack position when selected. - * When false objects are brought to top and rendered as part of the selection group - * @type Boolean - * @default - */ - preserveObjectStacking: false, - - /** - * Indicates the angle that an object will lock to while rotating. - * @type Number - * @since 1.6.7 - * @default - */ - snapAngle: 0, - - /** - * Indicates the distance from the snapAngle the rotation will lock to the snapAngle. - * When `null`, the snapThreshold will default to the snapAngle. - * @type null|Number - * @since 1.6.7 - * @default - */ - snapThreshold: null, - - /** - * Indicates if the right click on canvas can output the context menu or not - * @type Boolean - * @since 1.6.5 - * @default - */ - stopContextMenu: false, - - /** - * Indicates if the canvas can fire right click events - * @type Boolean - * @since 1.6.5 - * @default - */ - fireRightClick: false, - - /** - * Indicates if the canvas can fire middle click events - * @type Boolean - * @since 1.7.8 - * @default - */ - fireMiddleClick: false, - - /** - * Keep track of the subTargets for Mouse Events - * @type fabric.Object[] - */ - targets: [], - - /** - * Keep track of the hovered target - * @type fabric.Object - * @private - */ - _hoveredTarget: null, - - /** - * hold the list of nested targets hovered - * @type fabric.Object[] - * @private - */ - _hoveredTargets: [], - - /** - * @private - */ - _initInteractive: function() { - this._currentTransform = null; - this._groupSelector = null; - this._initWrapperElement(); - this._createUpperCanvas(); - this._initEventListeners(); - - this._initRetinaScaling(); - - this.freeDrawingBrush = fabric.PencilBrush && new fabric.PencilBrush(this); - - this.calcOffset(); - }, - - /** - * Divides objects in two groups, one to render immediately - * and one to render as activeGroup. - * @return {Array} objects to render immediately and pushes the other in the activeGroup. - */ - _chooseObjectsToRender: function() { - var activeObjects = this.getActiveObjects(), - object, objsToRender, activeGroupObjects; - - if (activeObjects.length > 0 && !this.preserveObjectStacking) { - objsToRender = []; - activeGroupObjects = []; - for (var i = 0, length = this._objects.length; i < length; i++) { - object = this._objects[i]; - if (activeObjects.indexOf(object) === -1 ) { - objsToRender.push(object); - } - else { - activeGroupObjects.push(object); - } - } - if (activeObjects.length > 1) { - this._activeObject._objects = activeGroupObjects; - } - objsToRender.push.apply(objsToRender, activeGroupObjects); - } - else { - objsToRender = this._objects; - } - return objsToRender; - }, - - /** - * Renders both the top canvas and the secondary container canvas. - * @return {fabric.Canvas} instance - * @chainable - */ - renderAll: function () { - if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) { - this.clearContext(this.contextTop); - this.contextTopDirty = false; - } - if (this.hasLostContext) { - this.renderTopLayer(this.contextTop); - } - var canvasToDrawOn = this.contextContainer; - this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender()); - return this; - }, - - renderTopLayer: function(ctx) { - ctx.save(); - if (this.isDrawingMode && this._isCurrentlyDrawing) { - this.freeDrawingBrush && this.freeDrawingBrush._render(); - this.contextTopDirty = true; - } - // we render the top context - last object - if (this.selection && this._groupSelector) { - this._drawSelection(ctx); - this.contextTopDirty = true; - } - ctx.restore(); - }, - - /** - * Method to render only the top canvas. - * Also used to render the group selection box. - * @return {fabric.Canvas} thisArg - * @chainable - */ - renderTop: function () { - var ctx = this.contextTop; - this.clearContext(ctx); - this.renderTopLayer(ctx); - this.fire('after:render'); - return this; - }, - - /** - * @private - */ - _normalizePointer: function (object, pointer) { - var m = object.calcTransformMatrix(), - invertedM = fabric.util.invertTransform(m), - vptPointer = this.restorePointerVpt(pointer); - return fabric.util.transformPoint(vptPointer, invertedM); - }, - - /** - * Returns true if object is transparent at a certain location - * @param {fabric.Object} target Object to check - * @param {Number} x Left coordinate - * @param {Number} y Top coordinate - * @return {Boolean} - */ - isTargetTransparent: function (target, x, y) { - // in case the target is the activeObject, we cannot execute this optimization - // because we need to draw controls too. - if (target.shouldCache() && target._cacheCanvas && target !== this._activeObject) { - var normalizedPointer = this._normalizePointer(target, {x: x, y: y}), - targetRelativeX = Math.max(target.cacheTranslationX + (normalizedPointer.x * target.zoomX), 0), - targetRelativeY = Math.max(target.cacheTranslationY + (normalizedPointer.y * target.zoomY), 0); - - var isTransparent = fabric.util.isTransparent( - target._cacheContext, Math.round(targetRelativeX), Math.round(targetRelativeY), this.targetFindTolerance); - - return isTransparent; - } - - var ctx = this.contextCache, - originalColor = target.selectionBackgroundColor, v = this.viewportTransform; - - target.selectionBackgroundColor = ''; - - this.clearContext(ctx); - - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - target.render(ctx); - ctx.restore(); - - target.selectionBackgroundColor = originalColor; - - var isTransparent = fabric.util.isTransparent( - ctx, x, y, this.targetFindTolerance); - - return isTransparent; - }, - - /** - * takes an event and determines if selection key has been pressed - * @private - * @param {Event} e Event object - */ - _isSelectionKeyPressed: function(e) { - var selectionKeyPressed = false; - - if (Object.prototype.toString.call(this.selectionKey) === '[object Array]') { - selectionKeyPressed = !!this.selectionKey.find(function(key) { return e[key] === true; }); - } - else { - selectionKeyPressed = e[this.selectionKey]; - } - - return selectionKeyPressed; - }, - - /** - * @private - * @param {Event} e Event object - * @param {fabric.Object} target - */ - _shouldClearSelection: function (e, target) { - var activeObjects = this.getActiveObjects(), - activeObject = this._activeObject; - - return ( - !target - || - (target && - activeObject && - activeObjects.length > 1 && - activeObjects.indexOf(target) === -1 && - activeObject !== target && - !this._isSelectionKeyPressed(e)) - || - (target && !target.evented) - || - (target && - !target.selectable && - activeObject && - activeObject !== target) - ); - }, - - /** - * centeredScaling from object can't override centeredScaling from canvas. - * this should be fixed, since object setting should take precedence over canvas. - * also this should be something that will be migrated in the control properties. - * as ability to define the origin of the transformation that the control provide. - * @private - * @param {fabric.Object} target - * @param {String} action - * @param {Boolean} altKey - */ - _shouldCenterTransform: function (target, action, altKey) { - if (!target) { - return; - } - - var centerTransform; - - if (action === 'scale' || action === 'scaleX' || action === 'scaleY' || action === 'resizing') { - centerTransform = this.centeredScaling || target.centeredScaling; - } - else if (action === 'rotate') { - centerTransform = this.centeredRotation || target.centeredRotation; - } - - return centerTransform ? !altKey : altKey; - }, - - /** - * should disappear before release 4.0 - * @private - */ - _getOriginFromCorner: function(target, corner) { - var origin = { - x: target.originX, - y: target.originY - }; - - if (corner === 'ml' || corner === 'tl' || corner === 'bl') { - origin.x = 'right'; - } - else if (corner === 'mr' || corner === 'tr' || corner === 'br') { - origin.x = 'left'; - } - - if (corner === 'tl' || corner === 'mt' || corner === 'tr') { - origin.y = 'bottom'; - } - else if (corner === 'bl' || corner === 'mb' || corner === 'br') { - origin.y = 'top'; - } - return origin; - }, - - /** - * @private - * @param {Boolean} alreadySelected true if target is already selected - * @param {String} corner a string representing the corner ml, mr, tl ... - * @param {Event} e Event object - * @param {fabric.Object} [target] inserted back to help overriding. Unused - */ - _getActionFromCorner: function(alreadySelected, corner, e, target) { - if (!corner || !alreadySelected) { - return 'drag'; - } - var control = target.controls[corner]; - return control.getActionName(e, control, target); - }, - - /** - * @private - * @param {Event} e Event object - * @param {fabric.Object} target - */ - _setupCurrentTransform: function (e, target, alreadySelected) { - if (!target) { - return; - } - - var pointer = this.getPointer(e), corner = target.__corner, - control = target.controls[corner], - actionHandler = (alreadySelected && corner) ? - control.getActionHandler(e, target, control) : fabric.controlsUtils.dragHandler, - action = this._getActionFromCorner(alreadySelected, corner, e, target), - origin = this._getOriginFromCorner(target, corner), - altKey = e[this.centeredKey], - transform = { - target: target, - action: action, - actionHandler: actionHandler, - corner: corner, - scaleX: target.scaleX, - scaleY: target.scaleY, - skewX: target.skewX, - skewY: target.skewY, - // used by transation - offsetX: pointer.x - target.left, - offsetY: pointer.y - target.top, - originX: origin.x, - originY: origin.y, - ex: pointer.x, - ey: pointer.y, - lastX: pointer.x, - lastY: pointer.y, - // unsure they are useful anymore. - // left: target.left, - // top: target.top, - theta: degreesToRadians(target.angle), - // end of unsure - width: target.width * target.scaleX, - shiftKey: e.shiftKey, - altKey: altKey, - original: fabric.util.saveObjectTransform(target), - }; - - if (this._shouldCenterTransform(target, action, altKey)) { - transform.originX = 'center'; - transform.originY = 'center'; - } - transform.original.originX = origin.x; - transform.original.originY = origin.y; - this._currentTransform = transform; - this._beforeTransform(e); - }, - - /** - * Set the cursor type of the canvas element - * @param {String} value Cursor type of the canvas element. - * @see http://www.w3.org/TR/css3-ui/#cursor - */ - setCursor: function (value) { - this.upperCanvasEl.style.cursor = value; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx to draw the selection on - */ - _drawSelection: function (ctx) { - var groupSelector = this._groupSelector, - left = groupSelector.left, - top = groupSelector.top, - aleft = abs(left), - atop = abs(top); - - if (this.selectionColor) { - ctx.fillStyle = this.selectionColor; - - ctx.fillRect( - groupSelector.ex - ((left > 0) ? 0 : -left), - groupSelector.ey - ((top > 0) ? 0 : -top), - aleft, - atop - ); - } - - if (!this.selectionLineWidth || !this.selectionBorderColor) { - return; - } - ctx.lineWidth = this.selectionLineWidth; - ctx.strokeStyle = this.selectionBorderColor; - - // selection border - if (this.selectionDashArray.length > 1 && !supportLineDash) { - - var px = groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft), - py = groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop); - - ctx.beginPath(); - - fabric.util.drawDashedLine(ctx, px, py, px + aleft, py, this.selectionDashArray); - fabric.util.drawDashedLine(ctx, px, py + atop - 1, px + aleft, py + atop - 1, this.selectionDashArray); - fabric.util.drawDashedLine(ctx, px, py, px, py + atop, this.selectionDashArray); - fabric.util.drawDashedLine(ctx, px + aleft - 1, py, px + aleft - 1, py + atop, this.selectionDashArray); - - ctx.closePath(); - ctx.stroke(); - } - else { - fabric.Object.prototype._setLineDash.call(this, ctx, this.selectionDashArray); - ctx.strokeRect( - groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft), - groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop), - aleft, - atop - ); - } - }, - - /** - * Method that determines what object we are clicking on - * the skipGroup parameter is for internal use, is needed for shift+click action - * 11/09/2018 TODO: would be cool if findTarget could discern between being a full target - * or the outside part of the corner. - * @param {Event} e mouse event - * @param {Boolean} skipGroup when true, activeGroup is skipped and only objects are traversed through - * @return {fabric.Object} the target found - */ - findTarget: function (e, skipGroup) { - if (this.skipTargetFind) { - return; - } - - var ignoreZoom = true, - pointer = this.getPointer(e, ignoreZoom), - activeObject = this._activeObject, - aObjects = this.getActiveObjects(), - activeTarget, activeTargetSubs, - isTouch = isTouchEvent(e), - shouldLookForActive = (aObjects.length > 1 && !skipGroup) || aObjects.length === 1; - - // first check current group (if one exists) - // active group does not check sub targets like normal groups. - // if active group just exits. - this.targets = []; - - // if we hit the corner of an activeObject, let's return that. - if (shouldLookForActive && activeObject._findTargetCorner(pointer, isTouch)) { - return activeObject; - } - if (aObjects.length > 1 && !skipGroup && activeObject === this._searchPossibleTargets([activeObject], pointer)) { - return activeObject; - } - if (aObjects.length === 1 && - activeObject === this._searchPossibleTargets([activeObject], pointer)) { - if (!this.preserveObjectStacking) { - return activeObject; - } - else { - activeTarget = activeObject; - activeTargetSubs = this.targets; - this.targets = []; - } - } - var target = this._searchPossibleTargets(this._objects, pointer); - if (e[this.altSelectionKey] && target && activeTarget && target !== activeTarget) { - target = activeTarget; - this.targets = activeTargetSubs; - } - return target; - }, - - /** - * Checks point is inside the object. - * @param {Object} [pointer] x,y object of point coordinates we want to check. - * @param {fabric.Object} obj Object to test against - * @param {Object} [globalPointer] x,y object of point coordinates relative to canvas used to search per pixel target. - * @return {Boolean} true if point is contained within an area of given object - * @private - */ - _checkTarget: function(pointer, obj, globalPointer) { - if (obj && - obj.visible && - obj.evented && - // http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html - // http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html - obj.containsPoint(pointer) - ) { - if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) { - var isTransparent = this.isTargetTransparent(obj, globalPointer.x, globalPointer.y); - if (!isTransparent) { - return true; - } - } - else { - return true; - } - } - }, - - /** - * Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted - * @param {Array} [objects] objects array to look into - * @param {Object} [pointer] x,y object of point coordinates we want to check. - * @return {fabric.Object} object that contains pointer - * @private - */ - _searchPossibleTargets: function(objects, pointer) { - // Cache all targets where their bounding box contains point. - var target, i = objects.length, subTarget; - // Do not check for currently grouped objects, since we check the parent group itself. - // until we call this function specifically to search inside the activeGroup - while (i--) { - var objToCheck = objects[i]; - var pointerToUse = objToCheck.group ? - this._normalizePointer(objToCheck.group, pointer) : pointer; - if (this._checkTarget(pointerToUse, objToCheck, pointer)) { - target = objects[i]; - if (target.subTargetCheck && target instanceof fabric.Group) { - subTarget = this._searchPossibleTargets(target._objects, pointer); - subTarget && this.targets.push(subTarget); - } - break; - } - } - return target; - }, - - /** - * Returns pointer coordinates without the effect of the viewport - * @param {Object} pointer with "x" and "y" number values - * @return {Object} object with "x" and "y" number values - */ - restorePointerVpt: function(pointer) { - return fabric.util.transformPoint( - pointer, - fabric.util.invertTransform(this.viewportTransform) - ); - }, - - /** - * Returns pointer coordinates relative to canvas. - * Can return coordinates with or without viewportTransform. - * ignoreZoom false gives back coordinates that represent - * the point clicked on canvas element. - * ignoreZoom true gives back coordinates after being processed - * by the viewportTransform ( sort of coordinates of what is displayed - * on the canvas where you are clicking. - * ignoreZoom true = HTMLElement coordinates relative to top,left - * ignoreZoom false, default = fabric space coordinates, the same used for shape position - * To interact with your shapes top and left you want to use ignoreZoom true - * most of the time, while ignoreZoom false will give you coordinates - * compatible with the object.oCoords system. - * of the time. - * @param {Event} e - * @param {Boolean} ignoreZoom - * @return {Object} object with "x" and "y" number values - */ - getPointer: function (e, ignoreZoom) { - // return cached values if we are in the event processing chain - if (this._absolutePointer && !ignoreZoom) { - return this._absolutePointer; - } - if (this._pointer && ignoreZoom) { - return this._pointer; - } - - var pointer = getPointer(e), - upperCanvasEl = this.upperCanvasEl, - bounds = upperCanvasEl.getBoundingClientRect(), - boundsWidth = bounds.width || 0, - boundsHeight = bounds.height || 0, - cssScale; - - if (!boundsWidth || !boundsHeight ) { - if ('top' in bounds && 'bottom' in bounds) { - boundsHeight = Math.abs( bounds.top - bounds.bottom ); - } - if ('right' in bounds && 'left' in bounds) { - boundsWidth = Math.abs( bounds.right - bounds.left ); - } - } - - this.calcOffset(); - pointer.x = pointer.x - this._offset.left; - pointer.y = pointer.y - this._offset.top; - if (!ignoreZoom) { - pointer = this.restorePointerVpt(pointer); - } - - var retinaScaling = this.getRetinaScaling(); - if (retinaScaling !== 1) { - pointer.x /= retinaScaling; - pointer.y /= retinaScaling; - } - - if (boundsWidth === 0 || boundsHeight === 0) { - // If bounds are not available (i.e. not visible), do not apply scale. - cssScale = { width: 1, height: 1 }; - } - else { - cssScale = { - width: upperCanvasEl.width / boundsWidth, - height: upperCanvasEl.height / boundsHeight - }; - } - - return { - x: pointer.x * cssScale.width, - y: pointer.y * cssScale.height - }; - }, - - /** - * @private - * @throws {CANVAS_INIT_ERROR} If canvas can not be initialized - */ - _createUpperCanvas: function () { - var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/, ''), - lowerCanvasEl = this.lowerCanvasEl, upperCanvasEl = this.upperCanvasEl; - - // there is no need to create a new upperCanvas element if we have already one. - if (upperCanvasEl) { - upperCanvasEl.className = ''; - } - else { - upperCanvasEl = this._createCanvasElement(); - this.upperCanvasEl = upperCanvasEl; - } - fabric.util.addClass(upperCanvasEl, 'upper-canvas ' + lowerCanvasClass); - - this.wrapperEl.appendChild(upperCanvasEl); - - this._copyCanvasStyle(lowerCanvasEl, upperCanvasEl); - this._applyCanvasStyle(upperCanvasEl); - this.contextTop = upperCanvasEl.getContext('2d'); - }, - - /** - * @private - */ - _createCacheCanvas: function () { - this.cacheCanvasEl = this._createCanvasElement(); - this.cacheCanvasEl.setAttribute('width', this.width); - this.cacheCanvasEl.setAttribute('height', this.height); - this.contextCache = this.cacheCanvasEl.getContext('2d'); - }, - - /** - * @private - */ - _initWrapperElement: function () { - this.wrapperEl = fabric.util.wrapElement(this.lowerCanvasEl, 'div', { - 'class': this.containerClass - }); - fabric.util.setStyle(this.wrapperEl, { - width: this.width + 'px', - height: this.height + 'px', - position: 'relative' - }); - fabric.util.makeElementUnselectable(this.wrapperEl); - }, - - /** - * @private - * @param {HTMLElement} element canvas element to apply styles on - */ - _applyCanvasStyle: function (element) { - var width = this.width || element.width, - height = this.height || element.height; - - fabric.util.setStyle(element, { - position: 'absolute', - width: width + 'px', - height: height + 'px', - left: 0, - top: 0, - 'touch-action': this.allowTouchScrolling ? 'manipulation' : 'none', - '-ms-touch-action': this.allowTouchScrolling ? 'manipulation' : 'none' - }); - element.width = width; - element.height = height; - fabric.util.makeElementUnselectable(element); - }, - - /** - * Copy the entire inline style from one element (fromEl) to another (toEl) - * @private - * @param {Element} fromEl Element style is copied from - * @param {Element} toEl Element copied style is applied to - */ - _copyCanvasStyle: function (fromEl, toEl) { - toEl.style.cssText = fromEl.style.cssText; - }, - - /** - * Returns context of canvas where object selection is drawn - * @return {CanvasRenderingContext2D} - */ - getSelectionContext: function() { - return this.contextTop; - }, - - /** - * Returns <canvas> element on which object selection is drawn - * @return {HTMLCanvasElement} - */ - getSelectionElement: function () { - return this.upperCanvasEl; - }, - - /** - * Returns currently active object - * @return {fabric.Object} active object - */ - getActiveObject: function () { - return this._activeObject; - }, - - /** - * Returns an array with the current selected objects - * @return {fabric.Object} active object - */ - getActiveObjects: function () { - var active = this._activeObject; - if (active) { - if (active.type === 'activeSelection' && active._objects) { - return active._objects.slice(0); - } - else { - return [active]; - } - } - return []; - }, - - /** - * @private - * @param {fabric.Object} obj Object that was removed - */ - _onObjectRemoved: function(obj) { - // removing active object should fire "selection:cleared" events - if (obj === this._activeObject) { - this.fire('before:selection:cleared', { target: obj }); - this._discardActiveObject(); - this.fire('selection:cleared', { target: obj }); - obj.fire('deselected'); - } - if (obj === this._hoveredTarget){ - this._hoveredTarget = null; - this._hoveredTargets = []; - } - this.callSuper('_onObjectRemoved', obj); - }, - - /** - * @private - * Compares the old activeObject with the current one and fires correct events - * @param {fabric.Object} obj old activeObject - */ - _fireSelectionEvents: function(oldObjects, e) { - var somethingChanged = false, objects = this.getActiveObjects(), - added = [], removed = []; - oldObjects.forEach(function(oldObject) { - if (objects.indexOf(oldObject) === -1) { - somethingChanged = true; - oldObject.fire('deselected', { - e: e, - target: oldObject - }); - removed.push(oldObject); - } - }); - objects.forEach(function(object) { - if (oldObjects.indexOf(object) === -1) { - somethingChanged = true; - object.fire('selected', { - e: e, - target: object - }); - added.push(object); - } - }); - if (oldObjects.length > 0 && objects.length > 0) { - somethingChanged && this.fire('selection:updated', { - e: e, - selected: added, - deselected: removed, - // added for backward compatibility - // deprecated - updated: added[0] || removed[0], - target: this._activeObject, - }); - } - else if (objects.length > 0) { - this.fire('selection:created', { - e: e, - selected: added, - target: this._activeObject, - }); - } - else if (oldObjects.length > 0) { - this.fire('selection:cleared', { - e: e, - deselected: removed, - }); - } - }, - - /** - * Sets given object as the only active object on canvas - * @param {fabric.Object} object Object to set as an active one - * @param {Event} [e] Event (passed along when firing "object:selected") - * @return {fabric.Canvas} thisArg - * @chainable - */ - setActiveObject: function (object, e) { - var currentActives = this.getActiveObjects(); - this._setActiveObject(object, e); - this._fireSelectionEvents(currentActives, e); - return this; - }, - - /** - * This is a private method for now. - * This is supposed to be equivalent to setActiveObject but without firing - * any event. There is commitment to have this stay this way. - * This is the functional part of setActiveObject. - * @private - * @param {Object} object to set as active - * @param {Event} [e] Event (passed along when firing "object:selected") - * @return {Boolean} true if the selection happened - */ - _setActiveObject: function(object, e) { - if (this._activeObject === object) { - return false; - } - if (!this._discardActiveObject(e, object)) { - return false; - } - if (object.onSelect({ e: e })) { - return false; - } - this._activeObject = object; - return true; - }, - - /** - * This is a private method for now. - * This is supposed to be equivalent to discardActiveObject but without firing - * any events. There is commitment to have this stay this way. - * This is the functional part of discardActiveObject. - * @param {Event} [e] Event (passed along when firing "object:deselected") - * @param {Object} object to set as active - * @return {Boolean} true if the selection happened - * @private - */ - _discardActiveObject: function(e, object) { - var obj = this._activeObject; - if (obj) { - // onDeselect return TRUE to cancel selection; - if (obj.onDeselect({ e: e, object: object })) { - return false; - } - this._activeObject = null; - } - return true; - }, - - /** - * Discards currently active object and fire events. If the function is called by fabric - * as a consequence of a mouse event, the event is passed as a parameter and - * sent to the fire function for the custom events. When used as a method the - * e param does not have any application. - * @param {event} e - * @return {fabric.Canvas} thisArg - * @chainable - */ - discardActiveObject: function (e) { - var currentActives = this.getActiveObjects(), activeObject = this.getActiveObject(); - if (currentActives.length) { - this.fire('before:selection:cleared', { target: activeObject, e: e }); - } - this._discardActiveObject(e); - this._fireSelectionEvents(currentActives, e); - return this; - }, - - /** - * Clears a canvas element and removes all event listeners - * @return {fabric.Canvas} thisArg - * @chainable - */ - dispose: function () { - var wrapper = this.wrapperEl; - this.removeListeners(); - wrapper.removeChild(this.upperCanvasEl); - wrapper.removeChild(this.lowerCanvasEl); - this.contextCache = null; - this.contextTop = null; - ['upperCanvasEl', 'cacheCanvasEl'].forEach((function(element) { - fabric.util.cleanUpJsdomNode(this[element]); - this[element] = undefined; - }).bind(this)); - if (wrapper.parentNode) { - wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl); - } - delete this.wrapperEl; - fabric.StaticCanvas.prototype.dispose.call(this); - return this; - }, - - /** - * Clears all contexts (background, main, top) of an instance - * @return {fabric.Canvas} thisArg - * @chainable - */ - clear: function () { - // this.discardActiveGroup(); - this.discardActiveObject(); - this.clearContext(this.contextTop); - return this.callSuper('clear'); - }, - - /** - * Draws objects' controls (borders/controls) - * @param {CanvasRenderingContext2D} ctx Context to render controls on - */ - drawControls: function(ctx) { - var activeObject = this._activeObject; - - if (activeObject) { - activeObject._renderControls(ctx); - } - }, - - /** - * @private - */ - _toObject: function(instance, methodName, propertiesToInclude) { - //If the object is part of the current selection group, it should - //be transformed appropriately - //i.e. it should be serialised as it would appear if the selection group - //were to be destroyed. - var originalProperties = this._realizeGroupTransformOnObject(instance), - object = this.callSuper('_toObject', instance, methodName, propertiesToInclude); - //Undo the damage we did by changing all of its properties - this._unwindGroupTransformOnObject(instance, originalProperties); - return object; - }, - - /** - * Realises an object's group transformation on it - * @private - * @param {fabric.Object} [instance] the object to transform (gets mutated) - * @returns the original values of instance which were changed - */ - _realizeGroupTransformOnObject: function(instance) { - if (instance.group && instance.group.type === 'activeSelection' && this._activeObject === instance.group) { - var layoutProps = ['angle', 'flipX', 'flipY', 'left', 'scaleX', 'scaleY', 'skewX', 'skewY', 'top']; - //Copy all the positionally relevant properties across now - var originalValues = {}; - layoutProps.forEach(function(prop) { - originalValues[prop] = instance[prop]; - }); - fabric.util.addTransformToObject(instance, this._activeObject.calcOwnMatrix()); - return originalValues; - } - else { - return null; - } - }, - - /** - * Restores the changed properties of instance - * @private - * @param {fabric.Object} [instance] the object to un-transform (gets mutated) - * @param {Object} [originalValues] the original values of instance, as returned by _realizeGroupTransformOnObject - */ - _unwindGroupTransformOnObject: function(instance, originalValues) { - if (originalValues) { - instance.set(originalValues); - } - }, - - /** - * @private - */ - _setSVGObject: function(markup, instance, reviver) { - //If the object is in a selection group, simulate what would happen to that - //object when the group is deselected - var originalProperties = this._realizeGroupTransformOnObject(instance); - this.callSuper('_setSVGObject', markup, instance, reviver); - this._unwindGroupTransformOnObject(instance, originalProperties); - }, - - setViewportTransform: function (vpt) { - if (this.renderOnAddRemove && this._activeObject && this._activeObject.isEditing) { - this._activeObject.clearContextTop(); - } - fabric.StaticCanvas.prototype.setViewportTransform.call(this, vpt); - } - }); - - // copying static properties manually to work around Opera's bug, - // where "prototype" property is enumerable and overrides existing prototype - for (var prop in fabric.StaticCanvas) { - if (prop !== 'prototype') { - fabric.Canvas[prop] = fabric.StaticCanvas[prop]; - } - } -})(); - - -(function() { - - var addListener = fabric.util.addListener, - removeListener = fabric.util.removeListener, - RIGHT_CLICK = 3, MIDDLE_CLICK = 2, LEFT_CLICK = 1, - addEventOptions = { passive: false }; - - function checkClick(e, value) { - return e.button && (e.button === value - 1); - } - - fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ { - - /** - * Contains the id of the touch event that owns the fabric transform - * @type Number - * @private - */ - mainTouchId: null, - - /** - * Adds mouse listeners to canvas - * @private - */ - _initEventListeners: function () { - // in case we initialized the class twice. This should not happen normally - // but in some kind of applications where the canvas element may be changed - // this is a workaround to having double listeners. - this.removeListeners(); - this._bindEvents(); - this.addOrRemove(addListener, 'add'); - }, - - /** - * return an event prefix pointer or mouse. - * @private - */ - _getEventPrefix: function () { - return this.enablePointerEvents ? 'pointer' : 'mouse'; - }, - - addOrRemove: function(functor, eventjsFunctor) { - var canvasElement = this.upperCanvasEl, - eventTypePrefix = this._getEventPrefix(); - functor(fabric.window, 'resize', this._onResize); - functor(canvasElement, eventTypePrefix + 'down', this._onMouseDown); - functor(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - functor(canvasElement, eventTypePrefix + 'out', this._onMouseOut); - functor(canvasElement, eventTypePrefix + 'enter', this._onMouseEnter); - functor(canvasElement, 'wheel', this._onMouseWheel); - functor(canvasElement, 'contextmenu', this._onContextMenu); - functor(canvasElement, 'dblclick', this._onDoubleClick); - functor(canvasElement, 'dragover', this._onDragOver); - functor(canvasElement, 'dragenter', this._onDragEnter); - functor(canvasElement, 'dragleave', this._onDragLeave); - functor(canvasElement, 'drop', this._onDrop); - if (!this.enablePointerEvents) { - functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions); - } - if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) { - eventjs[eventjsFunctor](canvasElement, 'gesture', this._onGesture); - eventjs[eventjsFunctor](canvasElement, 'drag', this._onDrag); - eventjs[eventjsFunctor](canvasElement, 'orientation', this._onOrientationChange); - eventjs[eventjsFunctor](canvasElement, 'shake', this._onShake); - eventjs[eventjsFunctor](canvasElement, 'longpress', this._onLongPress); - } - }, - - /** - * Removes all event listeners - */ - removeListeners: function() { - this.addOrRemove(removeListener, 'remove'); - // if you dispose on a mouseDown, before mouse up, you need to clean document to... - var eventTypePrefix = this._getEventPrefix(); - removeListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp); - removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions); - removeListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions); - }, - - /** - * @private - */ - _bindEvents: function() { - if (this.eventsBound) { - // for any reason we pass here twice we do not want to bind events twice. - return; - } - this._onMouseDown = this._onMouseDown.bind(this); - this._onTouchStart = this._onTouchStart.bind(this); - this._onMouseMove = this._onMouseMove.bind(this); - this._onMouseUp = this._onMouseUp.bind(this); - this._onTouchEnd = this._onTouchEnd.bind(this); - this._onResize = this._onResize.bind(this); - this._onGesture = this._onGesture.bind(this); - this._onDrag = this._onDrag.bind(this); - this._onShake = this._onShake.bind(this); - this._onLongPress = this._onLongPress.bind(this); - this._onOrientationChange = this._onOrientationChange.bind(this); - this._onMouseWheel = this._onMouseWheel.bind(this); - this._onMouseOut = this._onMouseOut.bind(this); - this._onMouseEnter = this._onMouseEnter.bind(this); - this._onContextMenu = this._onContextMenu.bind(this); - this._onDoubleClick = this._onDoubleClick.bind(this); - this._onDragOver = this._onDragOver.bind(this); - this._onDragEnter = this._simpleEventHandler.bind(this, 'dragenter'); - this._onDragLeave = this._simpleEventHandler.bind(this, 'dragleave'); - this._onDrop = this._simpleEventHandler.bind(this, 'drop'); - this.eventsBound = true; - }, - - /** - * @private - * @param {Event} [e] Event object fired on Event.js gesture - * @param {Event} [self] Inner Event object - */ - _onGesture: function(e, self) { - this.__onTransformGesture && this.__onTransformGesture(e, self); - }, - - /** - * @private - * @param {Event} [e] Event object fired on Event.js drag - * @param {Event} [self] Inner Event object - */ - _onDrag: function(e, self) { - this.__onDrag && this.__onDrag(e, self); - }, - - /** - * @private - * @param {Event} [e] Event object fired on wheel event - */ - _onMouseWheel: function(e) { - this.__onMouseWheel(e); - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onMouseOut: function(e) { - var target = this._hoveredTarget; - this.fire('mouse:out', { target: target, e: e }); - this._hoveredTarget = null; - target && target.fire('mouseout', { e: e }); - - var _this = this; - this._hoveredTargets.forEach(function(_target){ - _this.fire('mouse:out', { target: target, e: e }); - _target && target.fire('mouseout', { e: e }); - }); - this._hoveredTargets = []; - - if (this._iTextInstances) { - this._iTextInstances.forEach(function(obj) { - if (obj.isEditing) { - obj.hiddenTextarea.focus(); - } - }); - } - }, - - /** - * @private - * @param {Event} e Event object fired on mouseenter - */ - _onMouseEnter: function(e) { - // This find target and consequent 'mouse:over' is used to - // clear old instances on hovered target. - // calling findTarget has the side effect of killing target.__corner. - // as a short term fix we are not firing this if we are currently transforming. - // as a long term fix we need to separate the action of finding a target with the - // side effects we added to it. - if (!this._currentTransform && !this.findTarget(e)) { - this.fire('mouse:over', { target: null, e: e }); - this._hoveredTarget = null; - this._hoveredTargets = []; - } - }, - - /** - * @private - * @param {Event} [e] Event object fired on Event.js orientation change - * @param {Event} [self] Inner Event object - */ - _onOrientationChange: function(e, self) { - this.__onOrientationChange && this.__onOrientationChange(e, self); - }, - - /** - * @private - * @param {Event} [e] Event object fired on Event.js shake - * @param {Event} [self] Inner Event object - */ - _onShake: function(e, self) { - this.__onShake && this.__onShake(e, self); - }, - - /** - * @private - * @param {Event} [e] Event object fired on Event.js shake - * @param {Event} [self] Inner Event object - */ - _onLongPress: function(e, self) { - this.__onLongPress && this.__onLongPress(e, self); - }, - - /** - * prevent default to allow drop event to be fired - * @private - * @param {Event} [e] Event object fired on Event.js shake - */ - _onDragOver: function(e) { - e.preventDefault(); - var target = this._simpleEventHandler('dragover', e); - this._fireEnterLeaveEvents(target, e); - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onContextMenu: function (e) { - if (this.stopContextMenu) { - e.stopPropagation(); - e.preventDefault(); - } - return false; - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onDoubleClick: function (e) { - this._cacheTransformEventData(e); - this._handleEvent(e, 'dblclick'); - this._resetTransformEventData(e); - }, - - /** - * Return a the id of an event. - * returns either the pointerId or the identifier or 0 for the mouse event - * @private - * @param {Event} evt Event object - */ - getPointerId: function(evt) { - var changedTouches = evt.changedTouches; - - if (changedTouches) { - return changedTouches[0] && changedTouches[0].identifier; - } - - if (this.enablePointerEvents) { - return evt.pointerId; - } - - return -1; - }, - - /** - * Determines if an event has the id of the event that is considered main - * @private - * @param {evt} event Event object - */ - _isMainEvent: function(evt) { - if (evt.isPrimary === true) { - return true; - } - if (evt.isPrimary === false) { - return false; - } - if (evt.type === 'touchend' && evt.touches.length === 0) { - return true; - } - if (evt.changedTouches) { - return evt.changedTouches[0].identifier === this.mainTouchId; - } - return true; - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onTouchStart: function(e) { - e.preventDefault(); - if (this.mainTouchId === null) { - this.mainTouchId = this.getPointerId(e); - } - this.__onMouseDown(e); - this._resetTransformEventData(); - var canvasElement = this.upperCanvasEl, - eventTypePrefix = this._getEventPrefix(); - addListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions); - addListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions); - // Unbind mousedown to prevent double triggers from touch devices - removeListener(canvasElement, eventTypePrefix + 'down', this._onMouseDown); - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onMouseDown: function (e) { - this.__onMouseDown(e); - this._resetTransformEventData(); - var canvasElement = this.upperCanvasEl, - eventTypePrefix = this._getEventPrefix(); - removeListener(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - addListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp); - addListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onTouchEnd: function(e) { - if (e.touches.length > 0) { - // if there are still touches stop here - return; - } - this.__onMouseUp(e); - this._resetTransformEventData(); - this.mainTouchId = null; - var eventTypePrefix = this._getEventPrefix(); - removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions); - removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions); - var _this = this; - if (this._willAddMouseDown) { - clearTimeout(this._willAddMouseDown); - } - this._willAddMouseDown = setTimeout(function() { - // Wait 400ms before rebinding mousedown to prevent double triggers - // from touch devices - addListener(_this.upperCanvasEl, eventTypePrefix + 'down', _this._onMouseDown); - _this._willAddMouseDown = 0; - }, 400); - }, - - /** - * @private - * @param {Event} e Event object fired on mouseup - */ - _onMouseUp: function (e) { - this.__onMouseUp(e); - this._resetTransformEventData(); - var canvasElement = this.upperCanvasEl, - eventTypePrefix = this._getEventPrefix(); - if (this._isMainEvent(e)) { - removeListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp); - removeListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - addListener(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - } - }, - - /** - * @private - * @param {Event} e Event object fired on mousemove - */ - _onMouseMove: function (e) { - !this.allowTouchScrolling && e.preventDefault && e.preventDefault(); - this.__onMouseMove(e); - }, - - /** - * @private - */ - _onResize: function () { - this.calcOffset(); - }, - - /** - * Decides whether the canvas should be redrawn in mouseup and mousedown events. - * @private - * @param {Object} target - */ - _shouldRender: function(target) { - var activeObject = this._activeObject; - - if ( - !!activeObject !== !!target || - (activeObject && target && (activeObject !== target)) - ) { - // this covers: switch of target, from target to no target, selection of target - // multiSelection with key and mouse - return true; - } - else if (activeObject && activeObject.isEditing) { - // if we mouse up/down over a editing textbox a cursor change, - // there is no need to re render - return false; - } - return false; - }, - - /** - * Method that defines the actions when mouse is released on canvas. - * The method resets the currentTransform parameters, store the image corner - * position in the image object and render the canvas on top. - * @private - * @param {Event} e Event object fired on mouseup - */ - __onMouseUp: function (e) { - var target, transform = this._currentTransform, - groupSelector = this._groupSelector, shouldRender = false, - isClick = (!groupSelector || (groupSelector.left === 0 && groupSelector.top === 0)); - this._cacheTransformEventData(e); - target = this._target; - this._handleEvent(e, 'up:before'); - // if right/middle click just fire events and return - // target undefined will make the _handleEvent search the target - if (checkClick(e, RIGHT_CLICK)) { - if (this.fireRightClick) { - this._handleEvent(e, 'up', RIGHT_CLICK, isClick); - } - return; - } - - if (checkClick(e, MIDDLE_CLICK)) { - if (this.fireMiddleClick) { - this._handleEvent(e, 'up', MIDDLE_CLICK, isClick); - } - this._resetTransformEventData(); - return; - } - - if (this.isDrawingMode && this._isCurrentlyDrawing) { - this._onMouseUpInDrawingMode(e); - return; - } - - if (!this._isMainEvent(e)) { - return; - } - if (transform) { - this._finalizeCurrentTransform(e); - shouldRender = transform.actionPerformed; - } - if (!isClick) { - var targetWasActive = target === this._activeObject; - this._maybeGroupObjects(e); - if (!shouldRender) { - shouldRender = ( - this._shouldRender(target) || - (!targetWasActive && target === this._activeObject) - ); - } - } - if (target) { - if (target.selectable && target !== this._activeObject && target.activeOn === 'up') { - this.setActiveObject(target, e); - shouldRender = true; - } - else { - var corner = target._findTargetCorner( - this.getPointer(e, true), - fabric.util.isTouchEvent(e) - ); - var control = target.controls[corner], - mouseUpHandler = control && control.getMouseUpHandler(e, target, control); - if (mouseUpHandler) { - var pointer = this.getPointer(e); - mouseUpHandler(e, transform, pointer.x, pointer.y); - } - } - target.isMoving = false; - } - this._setCursorFromEvent(e, target); - this._handleEvent(e, 'up', LEFT_CLICK, isClick); - this._groupSelector = null; - this._currentTransform = null; - // reset the target information about which corner is selected - target && (target.__corner = 0); - if (shouldRender) { - this.requestRenderAll(); - } - else if (!isClick) { - this.renderTop(); - } - }, - - /** - * @private - * Handle event firing for target and subtargets - * @param {Event} e event from mouse - * @param {String} eventType event to fire (up, down or move) - * @return {Fabric.Object} target return the the target found, for internal reasons. - */ - _simpleEventHandler: function(eventType, e) { - var target = this.findTarget(e), - targets = this.targets, - options = { - e: e, - target: target, - subTargets: targets, - }; - this.fire(eventType, options); - target && target.fire(eventType, options); - if (!targets) { - return target; - } - for (var i = 0; i < targets.length; i++) { - targets[i].fire(eventType, options); - } - return target; - }, - - /** - * @private - * Handle event firing for target and subtargets - * @param {Event} e event from mouse - * @param {String} eventType event to fire (up, down or move) - * @param {fabric.Object} targetObj receiving event - * @param {Number} [button] button used in the event 1 = left, 2 = middle, 3 = right - * @param {Boolean} isClick for left button only, indicates that the mouse up happened without move. - */ - _handleEvent: function(e, eventType, button, isClick) { - var target = this._target, - targets = this.targets || [], - options = { - e: e, - target: target, - subTargets: targets, - button: button || LEFT_CLICK, - isClick: isClick || false, - pointer: this._pointer, - absolutePointer: this._absolutePointer, - transform: this._currentTransform - }; - if (eventType === 'up') { - options.currentTarget = this.findTarget(e); - options.currentSubTargets = this.targets; - } - this.fire('mouse:' + eventType, options); - target && target.fire('mouse' + eventType, options); - for (var i = 0; i < targets.length; i++) { - targets[i].fire('mouse' + eventType, options); - } - }, - - /** - * @private - * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event - */ - _finalizeCurrentTransform: function(e) { - - var transform = this._currentTransform, - target = transform.target, - eventName, - options = { - e: e, - target: target, - transform: transform, - action: transform.action, - }; - - if (target._scaling) { - target._scaling = false; - } - - target.setCoords(); - - if (transform.actionPerformed || (this.stateful && target.hasStateChanged())) { - if (transform.actionPerformed) { - // this is not friendly to the new control api. - // is deprecated. - eventName = this._addEventOptions(options, transform); - this._fire(eventName, options); - } - this._fire('modified', options); - } - }, - - /** - * Mutate option object in order to add by property and give back the event name. - * @private - * @deprecated since 4.2.0 - * @param {Object} options to mutate - * @param {Object} transform to inspect action from - */ - _addEventOptions: function(options, transform) { - // we can probably add more details at low cost - // scale change, rotation changes, translation changes - var eventName, by; - switch (transform.action) { - case 'scaleX': - eventName = 'scaled'; - by = 'x'; - break; - case 'scaleY': - eventName = 'scaled'; - by = 'y'; - break; - case 'skewX': - eventName = 'skewed'; - by = 'x'; - break; - case 'skewY': - eventName = 'skewed'; - by = 'y'; - break; - case 'scale': - eventName = 'scaled'; - by = 'equally'; - break; - case 'rotate': - eventName = 'rotated'; - break; - case 'drag': - eventName = 'moved'; - break; - } - options.by = by; - return eventName; - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onMouseDownInDrawingMode: function(e) { - this._isCurrentlyDrawing = true; - if (this.getActiveObject()) { - this.discardActiveObject(e).requestRenderAll(); - } - var pointer = this.getPointer(e); - this.freeDrawingBrush.onMouseDown(pointer, { e: e, pointer: pointer }); - this._handleEvent(e, 'down'); - }, - - /** - * @private - * @param {Event} e Event object fired on mousemove - */ - _onMouseMoveInDrawingMode: function(e) { - if (this._isCurrentlyDrawing) { - var pointer = this.getPointer(e); - this.freeDrawingBrush.onMouseMove(pointer, { e: e, pointer: pointer }); - } - this.setCursor(this.freeDrawingCursor); - this._handleEvent(e, 'move'); - }, - - /** - * @private - * @param {Event} e Event object fired on mouseup - */ - _onMouseUpInDrawingMode: function(e) { - var pointer = this.getPointer(e); - this._isCurrentlyDrawing = this.freeDrawingBrush.onMouseUp({ e: e, pointer: pointer }); - this._handleEvent(e, 'up'); - }, - - /** - * Method that defines the actions when mouse is clicked on canvas. - * The method inits the currentTransform parameters and renders all the - * canvas so the current image can be placed on the top canvas and the rest - * in on the container one. - * @private - * @param {Event} e Event object fired on mousedown - */ - __onMouseDown: function (e) { - this._cacheTransformEventData(e); - this._handleEvent(e, 'down:before'); - var target = this._target; - // if right click just fire events - if (checkClick(e, RIGHT_CLICK)) { - if (this.fireRightClick) { - this._handleEvent(e, 'down', RIGHT_CLICK); - } - return; - } - - if (checkClick(e, MIDDLE_CLICK)) { - if (this.fireMiddleClick) { - this._handleEvent(e, 'down', MIDDLE_CLICK); - } - return; - } - - if (this.isDrawingMode) { - this._onMouseDownInDrawingMode(e); - return; - } - - if (!this._isMainEvent(e)) { - return; - } - - // ignore if some object is being transformed at this moment - if (this._currentTransform) { - return; - } - - var pointer = this._pointer; - // save pointer for check in __onMouseUp event - this._previousPointer = pointer; - var shouldRender = this._shouldRender(target), - shouldGroup = this._shouldGroup(e, target); - if (this._shouldClearSelection(e, target)) { - this.discardActiveObject(e); - } - else if (shouldGroup) { - this._handleGrouping(e, target); - target = this._activeObject; - } - - if (this.selection && (!target || - (!target.selectable && !target.isEditing && target !== this._activeObject))) { - this._groupSelector = { - ex: pointer.x, - ey: pointer.y, - top: 0, - left: 0 - }; - } - - if (target) { - var alreadySelected = target === this._activeObject; - if (target.selectable && target.activeOn === 'down') { - this.setActiveObject(target, e); - } - var corner = target._findTargetCorner( - this.getPointer(e, true), - fabric.util.isTouchEvent(e) - ); - target.__corner = corner; - if (target === this._activeObject && (corner || !shouldGroup)) { - this._setupCurrentTransform(e, target, alreadySelected); - var control = target.controls[corner], - pointer = this.getPointer(e), - mouseDownHandler = control && control.getMouseDownHandler(e, target, control); - if (mouseDownHandler) { - mouseDownHandler(e, this._currentTransform, pointer.x, pointer.y); - } - } - } - this._handleEvent(e, 'down'); - // we must renderAll so that we update the visuals - (shouldRender || shouldGroup) && this.requestRenderAll(); - }, - - /** - * reset cache form common information needed during event processing - * @private - */ - _resetTransformEventData: function() { - this._target = null; - this._pointer = null; - this._absolutePointer = null; - }, - - /** - * Cache common information needed during event processing - * @private - * @param {Event} e Event object fired on event - */ - _cacheTransformEventData: function(e) { - // reset in order to avoid stale caching - this._resetTransformEventData(); - this._pointer = this.getPointer(e, true); - this._absolutePointer = this.restorePointerVpt(this._pointer); - this._target = this._currentTransform ? this._currentTransform.target : this.findTarget(e) || null; - }, - - /** - * @private - */ - _beforeTransform: function(e) { - var t = this._currentTransform; - this.stateful && t.target.saveState(); - this.fire('before:transform', { - e: e, - transform: t, - }); - }, - - /** - * Method that defines the actions when mouse is hovering the canvas. - * The currentTransform parameter will define whether the user is rotating/scaling/translating - * an image or neither of them (only hovering). A group selection is also possible and would cancel - * all any other type of action. - * In case of an image transformation only the top canvas will be rendered. - * @private - * @param {Event} e Event object fired on mousemove - */ - __onMouseMove: function (e) { - this._handleEvent(e, 'move:before'); - this._cacheTransformEventData(e); - var target, pointer; - - if (this.isDrawingMode) { - this._onMouseMoveInDrawingMode(e); - return; - } - - if (!this._isMainEvent(e)) { - return; - } - - var groupSelector = this._groupSelector; - - // We initially clicked in an empty area, so we draw a box for multiple selection - if (groupSelector) { - pointer = this._pointer; - - groupSelector.left = pointer.x - groupSelector.ex; - groupSelector.top = pointer.y - groupSelector.ey; - - this.renderTop(); - } - else if (!this._currentTransform) { - target = this.findTarget(e) || null; - this._setCursorFromEvent(e, target); - this._fireOverOutEvents(target, e); - } - else { - this._transformObject(e); - } - this._handleEvent(e, 'move'); - this._resetTransformEventData(); - }, - - /** - * Manage the mouseout, mouseover events for the fabric object on the canvas - * @param {Fabric.Object} target the target where the target from the mousemove event - * @param {Event} e Event object fired on mousemove - * @private - */ - _fireOverOutEvents: function(target, e) { - var _hoveredTarget = this._hoveredTarget, - _hoveredTargets = this._hoveredTargets, targets = this.targets, - length = Math.max(_hoveredTargets.length, targets.length); - - this.fireSyntheticInOutEvents(target, e, { - oldTarget: _hoveredTarget, - evtOut: 'mouseout', - canvasEvtOut: 'mouse:out', - evtIn: 'mouseover', - canvasEvtIn: 'mouse:over', - }); - for (var i = 0; i < length; i++){ - this.fireSyntheticInOutEvents(targets[i], e, { - oldTarget: _hoveredTargets[i], - evtOut: 'mouseout', - evtIn: 'mouseover', - }); - } - this._hoveredTarget = target; - this._hoveredTargets = this.targets.concat(); - }, - - /** - * Manage the dragEnter, dragLeave events for the fabric objects on the canvas - * @param {Fabric.Object} target the target where the target from the onDrag event - * @param {Event} e Event object fired on ondrag - * @private - */ - _fireEnterLeaveEvents: function(target, e) { - var _draggedoverTarget = this._draggedoverTarget, - _hoveredTargets = this._hoveredTargets, targets = this.targets, - length = Math.max(_hoveredTargets.length, targets.length); - - this.fireSyntheticInOutEvents(target, e, { - oldTarget: _draggedoverTarget, - evtOut: 'dragleave', - evtIn: 'dragenter', - }); - for (var i = 0; i < length; i++) { - this.fireSyntheticInOutEvents(targets[i], e, { - oldTarget: _hoveredTargets[i], - evtOut: 'dragleave', - evtIn: 'dragenter', - }); - } - this._draggedoverTarget = target; - }, - - /** - * Manage the synthetic in/out events for the fabric objects on the canvas - * @param {Fabric.Object} target the target where the target from the supported events - * @param {Event} e Event object fired - * @param {Object} config configuration for the function to work - * @param {String} config.targetName property on the canvas where the old target is stored - * @param {String} [config.canvasEvtOut] name of the event to fire at canvas level for out - * @param {String} config.evtOut name of the event to fire for out - * @param {String} [config.canvasEvtIn] name of the event to fire at canvas level for in - * @param {String} config.evtIn name of the event to fire for in - * @private - */ - fireSyntheticInOutEvents: function(target, e, config) { - var inOpt, outOpt, oldTarget = config.oldTarget, outFires, inFires, - targetChanged = oldTarget !== target, canvasEvtIn = config.canvasEvtIn, canvasEvtOut = config.canvasEvtOut; - if (targetChanged) { - inOpt = { e: e, target: target, previousTarget: oldTarget }; - outOpt = { e: e, target: oldTarget, nextTarget: target }; - } - inFires = target && targetChanged; - outFires = oldTarget && targetChanged; - if (outFires) { - canvasEvtOut && this.fire(canvasEvtOut, outOpt); - oldTarget.fire(config.evtOut, outOpt); - } - if (inFires) { - canvasEvtIn && this.fire(canvasEvtIn, inOpt); - target.fire(config.evtIn, inOpt); - } - }, - - /** - * Method that defines actions when an Event Mouse Wheel - * @param {Event} e Event object fired on mouseup - */ - __onMouseWheel: function(e) { - this._cacheTransformEventData(e); - this._handleEvent(e, 'wheel'); - this._resetTransformEventData(); - }, - - /** - * @private - * @param {Event} e Event fired on mousemove - */ - _transformObject: function(e) { - var pointer = this.getPointer(e), - transform = this._currentTransform; - - transform.reset = false; - transform.shiftKey = e.shiftKey; - transform.altKey = e[this.centeredKey]; - - this._performTransformAction(e, transform, pointer); - transform.actionPerformed && this.requestRenderAll(); - }, - - /** - * @private - */ - _performTransformAction: function(e, transform, pointer) { - var x = pointer.x, - y = pointer.y, - action = transform.action, - actionPerformed = false, - actionHandler = transform.actionHandler; - // this object could be created from the function in the control handlers - - - if (actionHandler) { - actionPerformed = actionHandler(e, transform, x, y); - } - if (action === 'drag' && actionPerformed) { - transform.target.isMoving = true; - this.setCursor(transform.target.moveCursor || this.moveCursor); - } - transform.actionPerformed = transform.actionPerformed || actionPerformed; - }, - - /** - * @private - */ - _fire: fabric.controlsUtils.fireEvent, - - /** - * Sets the cursor depending on where the canvas is being hovered. - * Note: very buggy in Opera - * @param {Event} e Event object - * @param {Object} target Object that the mouse is hovering, if so. - */ - _setCursorFromEvent: function (e, target) { - if (!target) { - this.setCursor(this.defaultCursor); - return false; - } - var hoverCursor = target.hoverCursor || this.hoverCursor, - activeSelection = this._activeObject && this._activeObject.type === 'activeSelection' ? - this._activeObject : null, - // only show proper corner when group selection is not active - corner = (!activeSelection || !activeSelection.contains(target)) - // here we call findTargetCorner always with undefined for the touch parameter. - // we assume that if you are using a cursor you do not need to interact with - // the bigger touch area. - && target._findTargetCorner(this.getPointer(e, true)); - - if (!corner) { - if (target.subTargetCheck){ - // hoverCursor should come from top-most subTarget, - // so we walk the array backwards - this.targets.concat().reverse().map(function(_target){ - hoverCursor = _target.hoverCursor || hoverCursor; - }); - } - this.setCursor(hoverCursor); - } - else { - this.setCursor(this.getCornerCursor(corner, target, e)); - } - }, - - /** - * @private - */ - getCornerCursor: function(corner, target, e) { - var control = target.controls[corner]; - return control.cursorStyleHandler(e, control, target); - } - }); -})(); - - -(function() { - - var min = Math.min, - max = Math.max; - - fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ { - - /** - * @private - * @param {Event} e Event object - * @param {fabric.Object} target - * @return {Boolean} - */ - _shouldGroup: function(e, target) { - var activeObject = this._activeObject; - return activeObject && this._isSelectionKeyPressed(e) && target && target.selectable && this.selection && - (activeObject !== target || activeObject.type === 'activeSelection') && !target.onSelect({ e: e }); - }, - - /** - * @private - * @param {Event} e Event object - * @param {fabric.Object} target - */ - _handleGrouping: function (e, target) { - var activeObject = this._activeObject; - // avoid multi select when shift click on a corner - if (activeObject.__corner) { - return; - } - if (target === activeObject) { - // if it's a group, find target again, using activeGroup objects - target = this.findTarget(e, true); - // if even object is not found or we are on activeObjectCorner, bail out - if (!target || !target.selectable) { - return; - } - } - if (activeObject && activeObject.type === 'activeSelection') { - this._updateActiveSelection(target, e); - } - else { - this._createActiveSelection(target, e); - } - }, - - /** - * @private - */ - _updateActiveSelection: function(target, e) { - var activeSelection = this._activeObject, - currentActiveObjects = activeSelection._objects.slice(0); - if (activeSelection.contains(target)) { - activeSelection.removeWithUpdate(target); - this._hoveredTarget = target; - this._hoveredTargets = this.targets.concat(); - if (activeSelection.size() === 1) { - // activate last remaining object - this._setActiveObject(activeSelection.item(0), e); - } - } - else { - activeSelection.addWithUpdate(target); - this._hoveredTarget = activeSelection; - this._hoveredTargets = this.targets.concat(); - } - this._fireSelectionEvents(currentActiveObjects, e); - }, - - /** - * @private - */ - _createActiveSelection: function(target, e) { - var currentActives = this.getActiveObjects(), group = this._createGroup(target); - this._hoveredTarget = group; - // ISSUE 4115: should we consider subTargets here? - // this._hoveredTargets = []; - // this._hoveredTargets = this.targets.concat(); - this._setActiveObject(group, e); - this._fireSelectionEvents(currentActives, e); - }, - - /** - * @private - * @param {Object} target - */ - _createGroup: function(target) { - var objects = this._objects, - isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target), - groupObjects = isActiveLower - ? [this._activeObject, target] - : [target, this._activeObject]; - this._activeObject.isEditing && this._activeObject.exitEditing(); - return new fabric.ActiveSelection(groupObjects, { - canvas: this - }); - }, - - /** - * @private - * @param {Event} e mouse event - */ - _groupSelectedObjects: function (e) { - - var group = this._collectObjects(e), - aGroup; - - // do not create group for 1 element only - if (group.length === 1) { - this.setActiveObject(group[0], e); - } - else if (group.length > 1) { - aGroup = new fabric.ActiveSelection(group.reverse(), { - canvas: this - }); - this.setActiveObject(aGroup, e); - } - }, - - /** - * @private - */ - _collectObjects: function(e) { - var group = [], - currentObject, - x1 = this._groupSelector.ex, - y1 = this._groupSelector.ey, - x2 = x1 + this._groupSelector.left, - y2 = y1 + this._groupSelector.top, - selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)), - selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)), - allowIntersect = !this.selectionFullyContained, - isClick = x1 === x2 && y1 === y2; - // we iterate reverse order to collect top first in case of click. - for (var i = this._objects.length; i--; ) { - currentObject = this._objects[i]; - - if (!currentObject || !currentObject.selectable || !currentObject.visible) { - continue; - } - - if ((allowIntersect && currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2)) || - currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) || - (allowIntersect && currentObject.containsPoint(selectionX1Y1)) || - (allowIntersect && currentObject.containsPoint(selectionX2Y2)) - ) { - group.push(currentObject); - // only add one object if it's a click - if (isClick) { - break; - } - } - } - - if (group.length > 1) { - group = group.filter(function(object) { - return !object.onSelect({ e: e }); - }); - } - - return group; - }, - - /** - * @private - */ - _maybeGroupObjects: function(e) { - if (this.selection && this._groupSelector) { - this._groupSelectedObjects(e); - } - this.setCursor(this.defaultCursor); - // clear selection and current transformation - this._groupSelector = null; - } - }); - -})(); - - -(function () { - fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { - - /** - * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately - * @param {Object} [options] Options object - * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png" - * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg. - * @param {Number} [options.multiplier=1] Multiplier to scale by, to have consistent - * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 - * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 - * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 - * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 - * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 2.0.0 - * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format - * @see {@link http://jsfiddle.net/fabricjs/NfZVb/|jsFiddle demo} - * @example Generate jpeg dataURL with lower quality - * var dataURL = canvas.toDataURL({ - * format: 'jpeg', - * quality: 0.8 - * }); - * @example Generate cropped png dataURL (clipping of canvas) - * var dataURL = canvas.toDataURL({ - * format: 'png', - * left: 100, - * top: 100, - * width: 200, - * height: 200 - * }); - * @example Generate double scaled png dataURL - * var dataURL = canvas.toDataURL({ - * format: 'png', - * multiplier: 2 - * }); - */ - toDataURL: function (options) { - options || (options = { }); - - var format = options.format || 'png', - quality = options.quality || 1, - multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? this.getRetinaScaling() : 1), - canvasEl = this.toCanvasElement(multiplier, options); - return fabric.util.toDataURL(canvasEl, format, quality); - }, - - /** - * Create a new HTMLCanvas element painted with the current canvas content. - * No need to resize the actual one or repaint it. - * Will transfer object ownership to a new canvas, paint it, and set everything back. - * This is an intermediary step used to get to a dataUrl but also it is useful to - * create quick image copies of a canvas without passing for the dataUrl string - * @param {Number} [multiplier] a zoom factor. - * @param {Object} [cropping] Cropping informations - * @param {Number} [cropping.left] Cropping left offset. - * @param {Number} [cropping.top] Cropping top offset. - * @param {Number} [cropping.width] Cropping width. - * @param {Number} [cropping.height] Cropping height. - */ - toCanvasElement: function(multiplier, cropping) { - multiplier = multiplier || 1; - cropping = cropping || { }; - var scaledWidth = (cropping.width || this.width) * multiplier, - scaledHeight = (cropping.height || this.height) * multiplier, - zoom = this.getZoom(), - originalWidth = this.width, - originalHeight = this.height, - newZoom = zoom * multiplier, - vp = this.viewportTransform, - translateX = (vp[4] - (cropping.left || 0)) * multiplier, - translateY = (vp[5] - (cropping.top || 0)) * multiplier, - originalInteractive = this.interactive, - newVp = [newZoom, 0, 0, newZoom, translateX, translateY], - originalRetina = this.enableRetinaScaling, - canvasEl = fabric.util.createCanvasElement(), - originalContextTop = this.contextTop; - canvasEl.width = scaledWidth; - canvasEl.height = scaledHeight; - this.contextTop = null; - this.enableRetinaScaling = false; - this.interactive = false; - this.viewportTransform = newVp; - this.width = scaledWidth; - this.height = scaledHeight; - this.calcViewportBoundaries(); - this.renderCanvas(canvasEl.getContext('2d'), this._objects); - this.viewportTransform = vp; - this.width = originalWidth; - this.height = originalHeight; - this.calcViewportBoundaries(); - this.interactive = originalInteractive; - this.enableRetinaScaling = originalRetina; - this.contextTop = originalContextTop; - return canvasEl; - }, - }); - -})(); - - -fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { - /** - * Populates canvas with data from the specified JSON. - * JSON format must conform to the one of {@link fabric.Canvas#toJSON} - * @param {String|Object} json JSON string or object - * @param {Function} callback Callback, invoked when json is parsed - * and corresponding objects (e.g: {@link fabric.Image}) - * are initialized - * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created. - * @return {fabric.Canvas} instance - * @chainable - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization} - * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo} - * @example loadFromJSON - * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas)); - * @example loadFromJSON with reviver - * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas), function(o, object) { - * // `o` = json object - * // `object` = fabric.Object instance - * // ... do some stuff ... - * }); - */ - loadFromJSON: function (json, callback, reviver) { - if (!json) { - return; - } - - // serialize if it wasn't already - var serialized = (typeof json === 'string') - ? JSON.parse(json) - : fabric.util.object.clone(json); - - var _this = this, - clipPath = serialized.clipPath, - renderOnAddRemove = this.renderOnAddRemove; - - this.renderOnAddRemove = false; - - delete serialized.clipPath; - - this._enlivenObjects(serialized.objects, function (enlivenedObjects) { - _this.clear(); - _this._setBgOverlay(serialized, function () { - if (clipPath) { - _this._enlivenObjects([clipPath], function (enlivenedCanvasClip) { - _this.clipPath = enlivenedCanvasClip[0]; - _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback); - }); - } - else { - _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback); - } - }); - }, reviver); - return this; - }, - - /** - * @private - * @param {Object} serialized Object with background and overlay information - * @param {Array} restored canvas objects - * @param {Function} cached renderOnAddRemove callback - * @param {Function} callback Invoked after all background and overlay images/patterns loaded - */ - __setupCanvas: function(serialized, enlivenedObjects, renderOnAddRemove, callback) { - var _this = this; - enlivenedObjects.forEach(function(obj, index) { - // we splice the array just in case some custom classes restored from JSON - // will add more object to canvas at canvas init. - _this.insertAt(obj, index); - }); - this.renderOnAddRemove = renderOnAddRemove; - // remove parts i cannot set as options - delete serialized.objects; - delete serialized.backgroundImage; - delete serialized.overlayImage; - delete serialized.background; - delete serialized.overlay; - // this._initOptions does too many things to just - // call it. Normally loading an Object from JSON - // create the Object instance. Here the Canvas is - // already an instance and we are just loading things over it - this._setOptions(serialized); - this.renderAll(); - callback && callback(); - }, - - /** - * @private - * @param {Object} serialized Object with background and overlay information - * @param {Function} callback Invoked after all background and overlay images/patterns loaded - */ - _setBgOverlay: function(serialized, callback) { - var loaded = { - backgroundColor: false, - overlayColor: false, - backgroundImage: false, - overlayImage: false - }; - - if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background && !serialized.overlay) { - callback && callback(); - return; - } - - var cbIfLoaded = function () { - if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) { - callback && callback(); - } - }; - - this.__setBgOverlay('backgroundImage', serialized.backgroundImage, loaded, cbIfLoaded); - this.__setBgOverlay('overlayImage', serialized.overlayImage, loaded, cbIfLoaded); - this.__setBgOverlay('backgroundColor', serialized.background, loaded, cbIfLoaded); - this.__setBgOverlay('overlayColor', serialized.overlay, loaded, cbIfLoaded); - }, - - /** - * @private - * @param {String} property Property to set (backgroundImage, overlayImage, backgroundColor, overlayColor) - * @param {(Object|String)} value Value to set - * @param {Object} loaded Set loaded property to true if property is set - * @param {Object} callback Callback function to invoke after property is set - */ - __setBgOverlay: function(property, value, loaded, callback) { - var _this = this; - - if (!value) { - loaded[property] = true; - callback && callback(); - return; - } - - if (property === 'backgroundImage' || property === 'overlayImage') { - fabric.util.enlivenObjects([value], function(enlivedObject){ - _this[property] = enlivedObject[0]; - loaded[property] = true; - callback && callback(); - }); - } - else { - this['set' + fabric.util.string.capitalize(property, true)](value, function() { - loaded[property] = true; - callback && callback(); - }); - } - }, - - /** - * @private - * @param {Array} objects - * @param {Function} callback - * @param {Function} [reviver] - */ - _enlivenObjects: function (objects, callback, reviver) { - if (!objects || objects.length === 0) { - callback && callback([]); - return; - } - - fabric.util.enlivenObjects(objects, function(enlivenedObjects) { - callback && callback(enlivenedObjects); - }, null, reviver); - }, - - /** - * @private - * @param {String} format - * @param {Function} callback - */ - _toDataURL: function (format, callback) { - this.clone(function (clone) { - callback(clone.toDataURL(format)); - }); - }, - - /** - * @private - * @param {String} format - * @param {Number} multiplier - * @param {Function} callback - */ - _toDataURLWithMultiplier: function (format, multiplier, callback) { - this.clone(function (clone) { - callback(clone.toDataURLWithMultiplier(format, multiplier)); - }); - }, - - /** - * Clones canvas instance - * @param {Object} [callback] Receives cloned instance as a first argument - * @param {Array} [properties] Array of properties to include in the cloned canvas and children - */ - clone: function (callback, properties) { - var data = JSON.stringify(this.toJSON(properties)); - this.cloneWithoutData(function(clone) { - clone.loadFromJSON(data, function() { - callback && callback(clone); - }); - }); - }, - - /** - * Clones canvas instance without cloning existing data. - * This essentially copies canvas dimensions, clipping properties, etc. - * but leaves data empty (so that you can populate it with your own) - * @param {Object} [callback] Receives cloned instance as a first argument - */ - cloneWithoutData: function(callback) { - var el = fabric.util.createCanvasElement(); - - el.width = this.width; - el.height = this.height; - - var clone = new fabric.Canvas(el); - if (this.backgroundImage) { - clone.setBackgroundImage(this.backgroundImage.src, function() { - clone.renderAll(); - callback && callback(clone); - }); - clone.backgroundImageOpacity = this.backgroundImageOpacity; - clone.backgroundImageStretch = this.backgroundImageStretch; - } - else { - callback && callback(clone); - } - } -}); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - clone = fabric.util.object.clone, - toFixed = fabric.util.toFixed, - capitalize = fabric.util.string.capitalize, - degreesToRadians = fabric.util.degreesToRadians, - supportsLineDash = fabric.StaticCanvas.supports('setLineDash'), - objectCaching = !fabric.isLikelyNode, - ALIASING_LIMIT = 2; - - if (fabric.Object) { - return; - } - - /** - * Root object class from which all 2d shape classes inherit from - * @class fabric.Object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects} - * @see {@link fabric.Object#initialize} for constructor definition - * - * @fires added - * @fires removed - * - * @fires selected - * @fires deselected - * @fires modified - * @fires modified - * @fires moved - * @fires scaled - * @fires rotated - * @fires skewed - * - * @fires rotating - * @fires scaling - * @fires moving - * @fires skewing - * - * @fires mousedown - * @fires mouseup - * @fires mouseover - * @fires mouseout - * @fires mousewheel - * @fires mousedblclick - * - * @fires dragover - * @fires dragenter - * @fires dragleave - * @fires drop - */ - fabric.Object = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.Object.prototype */ { - - /** - * Type of an object (rect, circle, path, etc.). - * Note that this property is meant to be read-only and not meant to be modified. - * If you modify, certain parts of Fabric (such as JSON loading) won't work correctly. - * @type String - * @default - */ - type: 'object', - - /** - * Horizontal origin of transformation of an object (one of "left", "right", "center") - * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups - * @type String - * @default - */ - originX: 'left', - - /** - * Vertical origin of transformation of an object (one of "top", "bottom", "center") - * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups - * @type String - * @default - */ - originY: 'top', - - /** - * Top position of an object. Note that by default it's relative to object top. You can change this by setting originY={top/center/bottom} - * @type Number - * @default - */ - top: 0, - - /** - * Left position of an object. Note that by default it's relative to object left. You can change this by setting originX={left/center/right} - * @type Number - * @default - */ - left: 0, - - /** - * Object width - * @type Number - * @default - */ - width: 0, - - /** - * Object height - * @type Number - * @default - */ - height: 0, - - /** - * Object scale factor (horizontal) - * @type Number - * @default - */ - scaleX: 1, - - /** - * Object scale factor (vertical) - * @type Number - * @default - */ - scaleY: 1, - - /** - * When true, an object is rendered as flipped horizontally - * @type Boolean - * @default - */ - flipX: false, - - /** - * When true, an object is rendered as flipped vertically - * @type Boolean - * @default - */ - flipY: false, - - /** - * Opacity of an object - * @type Number - * @default - */ - opacity: 1, - - /** - * Angle of rotation of an object (in degrees) - * @type Number - * @default - */ - angle: 0, - - /** - * Angle of skew on x axes of an object (in degrees) - * @type Number - * @default - */ - skewX: 0, - - /** - * Angle of skew on y axes of an object (in degrees) - * @type Number - * @default - */ - skewY: 0, - - /** - * Size of object's controlling corners (in pixels) - * @type Number - * @default - */ - cornerSize: 13, - - /** - * Size of object's controlling corners when touch interaction is detected - * @type Number - * @default - */ - touchCornerSize: 24, - - /** - * When true, object's controlling corners are rendered as transparent inside (i.e. stroke instead of fill) - * @type Boolean - * @default - */ - transparentCorners: true, - - /** - * Default cursor value used when hovering over this object on canvas - * @type String - * @default - */ - hoverCursor: null, - - /** - * Default cursor value used when moving this object on canvas - * @type String - * @default - */ - moveCursor: null, - - /** - * Padding between object and its controlling borders (in pixels) - * @type Number - * @default - */ - padding: 0, - - /** - * Color of controlling borders of an object (when it's active) - * @type String - * @default - */ - borderColor: 'rgb(178,204,255)', - - /** - * Array specifying dash pattern of an object's borders (hasBorder must be true) - * @since 1.6.2 - * @type Array - */ - borderDashArray: null, - - /** - * Color of controlling corners of an object (when it's active) - * @type String - * @default - */ - cornerColor: 'rgb(178,204,255)', - - /** - * Color of controlling corners of an object (when it's active and transparentCorners false) - * @since 1.6.2 - * @type String - * @default - */ - cornerStrokeColor: null, - - /** - * Specify style of control, 'rect' or 'circle' - * @since 1.6.2 - * @type String - */ - cornerStyle: 'rect', - - /** - * Array specifying dash pattern of an object's control (hasBorder must be true) - * @since 1.6.2 - * @type Array - */ - cornerDashArray: null, - - /** - * When true, this object will use center point as the origin of transformation - * when being scaled via the controls. - * Backwards incompatibility note: This property replaces "centerTransform" (Boolean). - * @since 1.3.4 - * @type Boolean - * @default - */ - centeredScaling: false, - - /** - * When true, this object will use center point as the origin of transformation - * when being rotated via the controls. - * Backwards incompatibility note: This property replaces "centerTransform" (Boolean). - * @since 1.3.4 - * @type Boolean - * @default - */ - centeredRotation: true, - - /** - * Color of object's fill - * takes css colors https://www.w3.org/TR/css-color-3/ - * @type String - * @default - */ - fill: 'rgb(0,0,0)', - - /** - * Fill rule used to fill an object - * accepted values are nonzero, evenodd - * Backwards incompatibility note: This property was used for setting globalCompositeOperation until v1.4.12 (use `fabric.Object#globalCompositeOperation` instead) - * @type String - * @default - */ - fillRule: 'nonzero', - - /** - * Composite rule used for canvas globalCompositeOperation - * @type String - * @default - */ - globalCompositeOperation: 'source-over', - - /** - * Background color of an object. - * takes css colors https://www.w3.org/TR/css-color-3/ - * @type String - * @default - */ - backgroundColor: '', - - /** - * Selection Background color of an object. colored layer behind the object when it is active. - * does not mix good with globalCompositeOperation methods. - * @type String - * @default - */ - selectionBackgroundColor: '', - - /** - * When defined, an object is rendered via stroke and this property specifies its color - * takes css colors https://www.w3.org/TR/css-color-3/ - * @type String - * @default - */ - stroke: null, - - /** - * Width of a stroke used to render this object - * @type Number - * @default - */ - strokeWidth: 1, - - /** - * Array specifying dash pattern of an object's stroke (stroke must be defined) - * @type Array - */ - strokeDashArray: null, - - /** - * Line offset of an object's stroke - * @type Number - * @default - */ - strokeDashOffset: 0, - - /** - * Line endings style of an object's stroke (one of "butt", "round", "square") - * @type String - * @default - */ - strokeLineCap: 'butt', - - /** - * Corner style of an object's stroke (one of "bevel", "round", "miter") - * @type String - * @default - */ - strokeLineJoin: 'miter', - - /** - * Maximum miter length (used for strokeLineJoin = "miter") of an object's stroke - * @type Number - * @default - */ - strokeMiterLimit: 4, - - /** - * Shadow object representing shadow of this shape - * @type fabric.Shadow - * @default - */ - shadow: null, - - /** - * Opacity of object's controlling borders when object is active and moving - * @type Number - * @default - */ - borderOpacityWhenMoving: 0.4, - - /** - * Scale factor of object's controlling borders - * bigger number will make a thicker border - * border is 1, so this is basically a border thickness - * since there is no way to change the border itself. - * @type Number - * @default - */ - borderScaleFactor: 1, - - /** - * Minimum allowed scale value of an object - * @type Number - * @default - */ - minScaleLimit: 0, - - /** - * When set to `false`, an object can not be selected for modification (using either point-click-based or group-based selection). - * But events still fire on it. - * @type Boolean - * @default - */ - selectable: true, - - /** - * When set to `false`, an object can not be a target of events. All events propagate through it. Introduced in v1.3.4 - * @type Boolean - * @default - */ - evented: true, - - /** - * When set to `false`, an object is not rendered on canvas - * @type Boolean - * @default - */ - visible: true, - - /** - * When set to `false`, object's controls are not displayed and can not be used to manipulate object - * @type Boolean - * @default - */ - hasControls: true, - - /** - * When set to `false`, object's controlling borders are not rendered - * @type Boolean - * @default - */ - hasBorders: true, - - /** - * When set to `true`, objects are "found" on canvas on per-pixel basis rather than according to bounding box - * @type Boolean - * @default - */ - perPixelTargetFind: false, - - /** - * When `false`, default object's values are not included in its serialization - * @type Boolean - * @default - */ - includeDefaultValues: true, - - /** - * When `true`, object horizontal movement is locked - * @type Boolean - * @default - */ - lockMovementX: false, - - /** - * When `true`, object vertical movement is locked - * @type Boolean - * @default - */ - lockMovementY: false, - - /** - * When `true`, object rotation is locked - * @type Boolean - * @default - */ - lockRotation: false, - - /** - * When `true`, object horizontal scaling is locked - * @type Boolean - * @default - */ - lockScalingX: false, - - /** - * When `true`, object vertical scaling is locked - * @type Boolean - * @default - */ - lockScalingY: false, - - /** - * When `true`, object horizontal skewing is locked - * @type Boolean - * @default - */ - lockSkewingX: false, - - /** - * When `true`, object vertical skewing is locked - * @type Boolean - * @default - */ - lockSkewingY: false, - - /** - * When `true`, object cannot be flipped by scaling into negative values - * @type Boolean - * @default - */ - lockScalingFlip: false, - - /** - * When `true`, object is not exported in OBJECT/JSON - * @since 1.6.3 - * @type Boolean - * @default - */ - excludeFromExport: false, - - /** - * When `true`, object is cached on an additional canvas. - * When `false`, object is not cached unless necessary ( clipPath ) - * default to true - * @since 1.7.0 - * @type Boolean - * @default true - */ - objectCaching: objectCaching, - - /** - * When `true`, object properties are checked for cache invalidation. In some particular - * situation you may want this to be disabled ( spray brush, very big, groups) - * or if your application does not allow you to modify properties for groups child you want - * to disable it for groups. - * default to false - * since 1.7.0 - * @type Boolean - * @default false - */ - statefullCache: false, - - /** - * When `true`, cache does not get updated during scaling. The picture will get blocky if scaled - * too much and will be redrawn with correct details at the end of scaling. - * this setting is performance and application dependant. - * default to true - * since 1.7.0 - * @type Boolean - * @default true - */ - noScaleCache: true, - - /** - * When `false`, the stoke width will scale with the object. - * When `true`, the stroke will always match the exact pixel size entered for stroke width. - * default to false - * @since 2.6.0 - * @type Boolean - * @default false - * @type Boolean - * @default false - */ - strokeUniform: false, - - /** - * When set to `true`, object's cache will be rerendered next render call. - * since 1.7.0 - * @type Boolean - * @default true - */ - dirty: true, - - /** - * keeps the value of the last hovered corner during mouse move. - * 0 is no corner, or 'mt', 'ml', 'mtr' etc.. - * It should be private, but there is no harm in using it as - * a read-only property. - * @type number|string|any - * @default 0 - */ - __corner: 0, - - /** - * Determines if the fill or the stroke is drawn first (one of "fill" or "stroke") - * @type String - * @default - */ - paintFirst: 'fill', - - /** - * When 'down', object is set to active on mousedown/touchstart - * When 'up', object is set to active on mouseup/touchend - * Experimental. Let's see if this breaks anything before supporting officially - * @private - * since 4.4.0 - * @type String - * @default 'down' - */ - activeOn: 'down', - - /** - * List of properties to consider when checking if state - * of an object is changed (fabric.Object#hasStateChanged) - * as well as for history (undo/redo) purposes - * @type Array - */ - stateProperties: ( - 'top left width height scaleX scaleY flipX flipY originX originY transformMatrix ' + - 'stroke strokeWidth strokeDashArray strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit ' + - 'angle opacity fill globalCompositeOperation shadow visible backgroundColor ' + - 'skewX skewY fillRule paintFirst clipPath strokeUniform' - ).split(' '), - - /** - * List of properties to consider when checking if cache needs refresh - * Those properties are checked by statefullCache ON ( or lazy mode if we want ) or from single - * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty - * and refreshed at the next render - * @type Array - */ - cacheProperties: ( - 'fill stroke strokeWidth strokeDashArray width height paintFirst strokeUniform' + - ' strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit backgroundColor clipPath' - ).split(' '), - - /** - * List of properties to consider for animating colors. - * @type Array - */ - colorProperties: ( - 'fill stroke backgroundColor' - ).split(' '), - - /** - * a fabricObject that, without stroke define a clipping area with their shape. filled in black - * the clipPath object gets used when the object has rendered, and the context is placed in the center - * of the object cacheCanvas. - * If you want 0,0 of a clipPath to align with an object center, use clipPath.originX/Y to 'center' - * @type fabric.Object - */ - clipPath: undefined, - - /** - * Meaningful ONLY when the object is used as clipPath. - * if true, the clipPath will make the object clip to the outside of the clipPath - * since 2.4.0 - * @type boolean - * @default false - */ - inverted: false, - - /** - * Meaningful ONLY when the object is used as clipPath. - * if true, the clipPath will have its top and left relative to canvas, and will - * not be influenced by the object transform. This will make the clipPath relative - * to the canvas, but clipping just a particular object. - * WARNING this is beta, this feature may change or be renamed. - * since 2.4.0 - * @type boolean - * @default false - */ - absolutePositioned: false, - - /** - * Constructor - * @param {Object} [options] Options object - */ - initialize: function(options) { - if (options) { - this.setOptions(options); - } - }, - - /** - * Create a the canvas used to keep the cached copy of the object - * @private - */ - _createCacheCanvas: function() { - this._cacheProperties = {}; - this._cacheCanvas = fabric.util.createCanvasElement(); - this._cacheContext = this._cacheCanvas.getContext('2d'); - this._updateCacheCanvas(); - // if canvas gets created, is empty, so dirty. - this.dirty = true; - }, - - /** - * Limit the cache dimensions so that X * Y do not cross fabric.perfLimitSizeTotal - * and each side do not cross fabric.cacheSideLimit - * those numbers are configurable so that you can get as much detail as you want - * making bargain with performances. - * @param {Object} dims - * @param {Object} dims.width width of canvas - * @param {Object} dims.height height of canvas - * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache - * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache - * @return {Object}.width width of canvas - * @return {Object}.height height of canvas - * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache - * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache - */ - _limitCacheSize: function(dims) { - var perfLimitSizeTotal = fabric.perfLimitSizeTotal, - width = dims.width, height = dims.height, - max = fabric.maxCacheSideLimit, min = fabric.minCacheSideLimit; - if (width <= max && height <= max && width * height <= perfLimitSizeTotal) { - if (width < min) { - dims.width = min; - } - if (height < min) { - dims.height = min; - } - return dims; - } - var ar = width / height, limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal), - capValue = fabric.util.capValue, - x = capValue(min, limitedDims.x, max), - y = capValue(min, limitedDims.y, max); - if (width > x) { - dims.zoomX /= width / x; - dims.width = x; - dims.capped = true; - } - if (height > y) { - dims.zoomY /= height / y; - dims.height = y; - dims.capped = true; - } - return dims; - }, - - /** - * Return the dimension and the zoom level needed to create a cache canvas - * big enough to host the object to be cached. - * @private - * @return {Object}.x width of object to be cached - * @return {Object}.y height of object to be cached - * @return {Object}.width width of canvas - * @return {Object}.height height of canvas - * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache - * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache - */ - _getCacheCanvasDimensions: function() { - var objectScale = this.getTotalObjectScaling(), - // caculate dimensions without skewing - dim = this._getTransformedDimensions(0, 0), - neededX = dim.x * objectScale.scaleX / this.scaleX, - neededY = dim.y * objectScale.scaleY / this.scaleY; - return { - // for sure this ALIASING_LIMIT is slightly creating problem - // in situation in which the cache canvas gets an upper limit - // also objectScale contains already scaleX and scaleY - width: neededX + ALIASING_LIMIT, - height: neededY + ALIASING_LIMIT, - zoomX: objectScale.scaleX, - zoomY: objectScale.scaleY, - x: neededX, - y: neededY - }; - }, - - /** - * Update width and height of the canvas for cache - * returns true or false if canvas needed resize. - * @private - * @return {Boolean} true if the canvas has been resized - */ - _updateCacheCanvas: function() { - var targetCanvas = this.canvas; - if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) { - var target = targetCanvas._currentTransform.target, - action = targetCanvas._currentTransform.action; - if (this === target && action.slice && action.slice(0, 5) === 'scale') { - return false; - } - } - var canvas = this._cacheCanvas, - dims = this._limitCacheSize(this._getCacheCanvasDimensions()), - minCacheSize = fabric.minCacheSideLimit, - width = dims.width, height = dims.height, drawingWidth, drawingHeight, - zoomX = dims.zoomX, zoomY = dims.zoomY, - dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight, - zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY, - shouldRedraw = dimensionsChanged || zoomChanged, - additionalWidth = 0, additionalHeight = 0, shouldResizeCanvas = false; - if (dimensionsChanged) { - var canvasWidth = this._cacheCanvas.width, - canvasHeight = this._cacheCanvas.height, - sizeGrowing = width > canvasWidth || height > canvasHeight, - sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) && - canvasWidth > minCacheSize && canvasHeight > minCacheSize; - shouldResizeCanvas = sizeGrowing || sizeShrinking; - if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) { - additionalWidth = width * 0.1; - additionalHeight = height * 0.1; - } - } - if (shouldRedraw) { - if (shouldResizeCanvas) { - canvas.width = Math.ceil(width + additionalWidth); - canvas.height = Math.ceil(height + additionalHeight); - } - else { - this._cacheContext.setTransform(1, 0, 0, 1, 0, 0); - this._cacheContext.clearRect(0, 0, canvas.width, canvas.height); - } - drawingWidth = dims.x / 2; - drawingHeight = dims.y / 2; - this.cacheTranslationX = Math.round(canvas.width / 2 - drawingWidth) + drawingWidth; - this.cacheTranslationY = Math.round(canvas.height / 2 - drawingHeight) + drawingHeight; - this.cacheWidth = width; - this.cacheHeight = height; - this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY); - this._cacheContext.scale(zoomX, zoomY); - this.zoomX = zoomX; - this.zoomY = zoomY; - return true; - } - return false; - }, - - /** - * Sets object's properties from options - * @param {Object} [options] Options object - */ - setOptions: function(options) { - this._setOptions(options); - this._initGradient(options.fill, 'fill'); - this._initGradient(options.stroke, 'stroke'); - this._initPattern(options.fill, 'fill'); - this._initPattern(options.stroke, 'stroke'); - }, - - /** - * Transforms context when rendering an object - * @param {CanvasRenderingContext2D} ctx Context - */ - transform: function(ctx) { - var needFullTransform = (this.group && !this.group._transformDone) || - (this.group && this.canvas && ctx === this.canvas.contextTop); - var m = this.calcTransformMatrix(!needFullTransform); - ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); - }, - - /** - * Returns an object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of an instance - */ - toObject: function(propertiesToInclude) { - var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, - - object = { - type: this.type, - version: fabric.version, - originX: this.originX, - originY: this.originY, - left: toFixed(this.left, NUM_FRACTION_DIGITS), - top: toFixed(this.top, NUM_FRACTION_DIGITS), - width: toFixed(this.width, NUM_FRACTION_DIGITS), - height: toFixed(this.height, NUM_FRACTION_DIGITS), - fill: (this.fill && this.fill.toObject) ? this.fill.toObject() : this.fill, - stroke: (this.stroke && this.stroke.toObject) ? this.stroke.toObject() : this.stroke, - strokeWidth: toFixed(this.strokeWidth, NUM_FRACTION_DIGITS), - strokeDashArray: this.strokeDashArray ? this.strokeDashArray.concat() : this.strokeDashArray, - strokeLineCap: this.strokeLineCap, - strokeDashOffset: this.strokeDashOffset, - strokeLineJoin: this.strokeLineJoin, - strokeUniform: this.strokeUniform, - strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS), - scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS), - scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS), - angle: toFixed(this.angle, NUM_FRACTION_DIGITS), - flipX: this.flipX, - flipY: this.flipY, - opacity: toFixed(this.opacity, NUM_FRACTION_DIGITS), - shadow: (this.shadow && this.shadow.toObject) ? this.shadow.toObject() : this.shadow, - visible: this.visible, - backgroundColor: this.backgroundColor, - fillRule: this.fillRule, - paintFirst: this.paintFirst, - globalCompositeOperation: this.globalCompositeOperation, - skewX: toFixed(this.skewX, NUM_FRACTION_DIGITS), - skewY: toFixed(this.skewY, NUM_FRACTION_DIGITS), - }; - - if (this.clipPath) { - object.clipPath = this.clipPath.toObject(propertiesToInclude); - object.clipPath.inverted = this.clipPath.inverted; - object.clipPath.absolutePositioned = this.clipPath.absolutePositioned; - } - - fabric.util.populateWithProperties(this, object, propertiesToInclude); - if (!this.includeDefaultValues) { - object = this._removeDefaultValues(object); - } - - return object; - }, - - /** - * Returns (dataless) object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of an instance - */ - toDatalessObject: function(propertiesToInclude) { - // will be overwritten by subclasses - return this.toObject(propertiesToInclude); - }, - - /** - * @private - * @param {Object} object - */ - _removeDefaultValues: function(object) { - var prototype = fabric.util.getKlass(object.type).prototype, - stateProperties = prototype.stateProperties; - stateProperties.forEach(function(prop) { - if (prop === 'left' || prop === 'top') { - return; - } - if (object[prop] === prototype[prop]) { - delete object[prop]; - } - var isArray = Object.prototype.toString.call(object[prop]) === '[object Array]' && - Object.prototype.toString.call(prototype[prop]) === '[object Array]'; - - // basically a check for [] === [] - if (isArray && object[prop].length === 0 && prototype[prop].length === 0) { - delete object[prop]; - } - }); - - return object; - }, - - /** - * Returns a string representation of an instance - * @return {String} - */ - toString: function() { - return '#'; - }, - - /** - * Return the object scale factor counting also the group scaling - * @return {Object} object with scaleX and scaleY properties - */ - getObjectScaling: function() { - var options = fabric.util.qrDecompose(this.calcTransformMatrix()); - return { scaleX: Math.abs(options.scaleX), scaleY: Math.abs(options.scaleY) }; - }, - - /** - * Return the object scale factor counting also the group scaling, zoom and retina - * @return {Object} object with scaleX and scaleY properties - */ - getTotalObjectScaling: function() { - var scale = this.getObjectScaling(), scaleX = scale.scaleX, scaleY = scale.scaleY; - if (this.canvas) { - var zoom = this.canvas.getZoom(); - var retina = this.canvas.getRetinaScaling(); - scaleX *= zoom * retina; - scaleY *= zoom * retina; - } - return { scaleX: scaleX, scaleY: scaleY }; - }, - - /** - * Return the object opacity counting also the group property - * @return {Number} - */ - getObjectOpacity: function() { - var opacity = this.opacity; - if (this.group) { - opacity *= this.group.getObjectOpacity(); - } - return opacity; - }, - - /** - * @private - * @param {String} key - * @param {*} value - * @return {fabric.Object} thisArg - */ - _set: function(key, value) { - var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY'), - isChanged = this[key] !== value, groupNeedsUpdate = false; - - if (shouldConstrainValue) { - value = this._constrainScale(value); - } - if (key === 'scaleX' && value < 0) { - this.flipX = !this.flipX; - value *= -1; - } - else if (key === 'scaleY' && value < 0) { - this.flipY = !this.flipY; - value *= -1; - } - else if (key === 'shadow' && value && !(value instanceof fabric.Shadow)) { - value = new fabric.Shadow(value); - } - else if (key === 'dirty' && this.group) { - this.group.set('dirty', value); - } - - this[key] = value; - - if (isChanged) { - groupNeedsUpdate = this.group && this.group.isOnACache(); - if (this.cacheProperties.indexOf(key) > -1) { - this.dirty = true; - groupNeedsUpdate && this.group.set('dirty', true); - } - else if (groupNeedsUpdate && this.stateProperties.indexOf(key) > -1) { - this.group.set('dirty', true); - } - } - return this; - }, - - /** - * This callback function is called by the parent group of an object every - * time a non-delegated property changes on the group. It is passed the key - * and value as parameters. Not adding in this function's signature to avoid - * Travis build error about unused variables. - */ - setOnGroup: function() { - // implemented by sub-classes, as needed. - }, - - /** - * Retrieves viewportTransform from Object's canvas if possible - * @method getViewportTransform - * @memberOf fabric.Object.prototype - * @return {Array} - */ - getViewportTransform: function() { - if (this.canvas && this.canvas.viewportTransform) { - return this.canvas.viewportTransform; - } - return fabric.iMatrix.concat(); - }, - - /* - * @private - * return if the object would be visible in rendering - * @memberOf fabric.Object.prototype - * @return {Boolean} - */ - isNotVisible: function() { - return this.opacity === 0 || - (!this.width && !this.height && this.strokeWidth === 0) || - !this.visible; - }, - - /** - * Renders an object on a specified context - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - render: function(ctx) { - // do not render if width/height are zeros or object is not visible - if (this.isNotVisible()) { - return; - } - if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) { - return; - } - ctx.save(); - this._setupCompositeOperation(ctx); - this.drawSelectionBackground(ctx); - this.transform(ctx); - this._setOpacity(ctx); - this._setShadow(ctx, this); - if (this.shouldCache()) { - this.renderCache(); - this.drawCacheOnCanvas(ctx); - } - else { - this._removeCacheCanvas(); - this.dirty = false; - this.drawObject(ctx); - if (this.objectCaching && this.statefullCache) { - this.saveState({ propertySet: 'cacheProperties' }); - } - } - ctx.restore(); - }, - - renderCache: function(options) { - options = options || {}; - if (!this._cacheCanvas) { - this._createCacheCanvas(); - } - if (this.isCacheDirty()) { - this.statefullCache && this.saveState({ propertySet: 'cacheProperties' }); - this.drawObject(this._cacheContext, options.forClipping); - this.dirty = false; - } - }, - - /** - * Remove cacheCanvas and its dimensions from the objects - */ - _removeCacheCanvas: function() { - this._cacheCanvas = null; - this.cacheWidth = 0; - this.cacheHeight = 0; - }, - - /** - * return true if the object will draw a stroke - * Does not consider text styles. This is just a shortcut used at rendering time - * We want it to be an approximation and be fast. - * wrote to avoid extra caching, it has to return true when stroke happens, - * can guess when it will not happen at 100% chance, does not matter if it misses - * some use case where the stroke is invisible. - * @since 3.0.0 - * @returns Boolean - */ - hasStroke: function() { - return this.stroke && this.stroke !== 'transparent' && this.strokeWidth !== 0; - }, - - /** - * return true if the object will draw a fill - * Does not consider text styles. This is just a shortcut used at rendering time - * We want it to be an approximation and be fast. - * wrote to avoid extra caching, it has to return true when fill happens, - * can guess when it will not happen at 100% chance, does not matter if it misses - * some use case where the fill is invisible. - * @since 3.0.0 - * @returns Boolean - */ - hasFill: function() { - return this.fill && this.fill !== 'transparent'; - }, - - /** - * When set to `true`, force the object to have its own cache, even if it is inside a group - * it may be needed when your object behave in a particular way on the cache and always needs - * its own isolated canvas to render correctly. - * Created to be overridden - * since 1.7.12 - * @returns Boolean - */ - needsItsOwnCache: function() { - if (this.paintFirst === 'stroke' && - this.hasFill() && this.hasStroke() && typeof this.shadow === 'object') { - return true; - } - if (this.clipPath) { - return true; - } - return false; - }, - - /** - * Decide if the object should cache or not. Create its own cache level - * objectCaching is a global flag, wins over everything - * needsItsOwnCache should be used when the object drawing method requires - * a cache step. None of the fabric classes requires it. - * Generally you do not cache objects in groups because the group outside is cached. - * Read as: cache if is needed, or if the feature is enabled but we are not already caching. - * @return {Boolean} - */ - shouldCache: function() { - this.ownCaching = this.needsItsOwnCache() || ( - this.objectCaching && - (!this.group || !this.group.isOnACache()) - ); - return this.ownCaching; - }, - - /** - * Check if this object or a child object will cast a shadow - * used by Group.shouldCache to know if child has a shadow recursively - * @return {Boolean} - */ - willDrawShadow: function() { - return !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0); - }, - - /** - * Execute the drawing operation for an object clipPath - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - drawClipPathOnCache: function(ctx) { - var path = this.clipPath; - ctx.save(); - // DEBUG: uncomment this line, comment the following - // ctx.globalAlpha = 0.4 - if (path.inverted) { - ctx.globalCompositeOperation = 'destination-out'; - } - else { - ctx.globalCompositeOperation = 'destination-in'; - } - //ctx.scale(1 / 2, 1 / 2); - if (path.absolutePositioned) { - var m = fabric.util.invertTransform(this.calcTransformMatrix()); - ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); - } - path.transform(ctx); - ctx.scale(1 / path.zoomX, 1 / path.zoomY); - ctx.drawImage(path._cacheCanvas, -path.cacheTranslationX, -path.cacheTranslationY); - ctx.restore(); - }, - - /** - * Execute the drawing operation for an object on a specified context - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - drawObject: function(ctx, forClipping) { - var originalFill = this.fill, originalStroke = this.stroke; - if (forClipping) { - this.fill = 'black'; - this.stroke = ''; - this._setClippingProperties(ctx); - } - else { - this._renderBackground(ctx); - } - this._render(ctx); - this._drawClipPath(ctx); - this.fill = originalFill; - this.stroke = originalStroke; - }, - - _drawClipPath: function(ctx) { - var path = this.clipPath; - if (!path) { return; } - // needed to setup a couple of variables - // path canvas gets overridden with this one. - // TODO find a better solution? - path.canvas = this.canvas; - path.shouldCache(); - path._transformDone = true; - path.renderCache({ forClipping: true }); - this.drawClipPathOnCache(ctx); - }, - - /** - * Paint the cached copy of the object on the target context. - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - drawCacheOnCanvas: function(ctx) { - ctx.scale(1 / this.zoomX, 1 / this.zoomY); - ctx.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY); - }, - - /** - * Check if cache is dirty - * @param {Boolean} skipCanvas skip canvas checks because this object is painted - * on parent canvas. - */ - isCacheDirty: function(skipCanvas) { - if (this.isNotVisible()) { - return false; - } - if (this._cacheCanvas && !skipCanvas && this._updateCacheCanvas()) { - // in this case the context is already cleared. - return true; - } - else { - if (this.dirty || - (this.clipPath && this.clipPath.absolutePositioned) || - (this.statefullCache && this.hasStateChanged('cacheProperties')) - ) { - if (this._cacheCanvas && !skipCanvas) { - var width = this.cacheWidth / this.zoomX; - var height = this.cacheHeight / this.zoomY; - this._cacheContext.clearRect(-width / 2, -height / 2, width, height); - } - return true; - } - } - return false; - }, - - /** - * Draws a background for the object big as its untransformed dimensions - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderBackground: function(ctx) { - if (!this.backgroundColor) { - return; - } - var dim = this._getNonTransformedDimensions(); - ctx.fillStyle = this.backgroundColor; - - ctx.fillRect( - -dim.x / 2, - -dim.y / 2, - dim.x, - dim.y - ); - // if there is background color no other shadows - // should be casted - this._removeShadow(ctx); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _setOpacity: function(ctx) { - if (this.group && !this.group._transformDone) { - ctx.globalAlpha = this.getObjectOpacity(); - } - else { - ctx.globalAlpha *= this.opacity; - } - }, - - _setStrokeStyles: function(ctx, decl) { - var stroke = decl.stroke; - if (stroke) { - ctx.lineWidth = decl.strokeWidth; - ctx.lineCap = decl.strokeLineCap; - ctx.lineDashOffset = decl.strokeDashOffset; - ctx.lineJoin = decl.strokeLineJoin; - ctx.miterLimit = decl.strokeMiterLimit; - if (stroke.toLive) { - if (stroke.gradientUnits === 'percentage' || stroke.gradientTransform || stroke.patternTransform) { - // need to transform gradient in a pattern. - // this is a slow process. If you are hitting this codepath, and the object - // is not using caching, you should consider switching it on. - // we need a canvas as big as the current object caching canvas. - this._applyPatternForTransformedGradient(ctx, stroke); - } - else { - // is a simple gradient or pattern - ctx.strokeStyle = stroke.toLive(ctx, this); - this._applyPatternGradientTransform(ctx, stroke); - } - } - else { - // is a color - ctx.strokeStyle = decl.stroke; - } - } - }, - - _setFillStyles: function(ctx, decl) { - var fill = decl.fill; - if (fill) { - if (fill.toLive) { - ctx.fillStyle = fill.toLive(ctx, this); - this._applyPatternGradientTransform(ctx, decl.fill); - } - else { - ctx.fillStyle = fill; - } - } - }, - - _setClippingProperties: function(ctx) { - ctx.globalAlpha = 1; - ctx.strokeStyle = 'transparent'; - ctx.fillStyle = '#000000'; - }, - - /** - * @private - * Sets line dash - * @param {CanvasRenderingContext2D} ctx Context to set the dash line on - * @param {Array} dashArray array representing dashes - * @param {Function} alternative function to call if browser does not support lineDash - */ - _setLineDash: function(ctx, dashArray, alternative) { - if (!dashArray || dashArray.length === 0) { - return; - } - // Spec requires the concatenation of two copies the dash list when the number of elements is odd - if (1 & dashArray.length) { - dashArray.push.apply(dashArray, dashArray); - } - if (supportsLineDash) { - ctx.setLineDash(dashArray); - } - else { - alternative && alternative(ctx); - } - }, - - /** - * Renders controls and borders for the object - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Object} [styleOverride] properties to override the object style - */ - _renderControls: function(ctx, styleOverride) { - var vpt = this.getViewportTransform(), - matrix = this.calcTransformMatrix(), - options, drawBorders, drawControls; - styleOverride = styleOverride || { }; - drawBorders = typeof styleOverride.hasBorders !== 'undefined' ? styleOverride.hasBorders : this.hasBorders; - drawControls = typeof styleOverride.hasControls !== 'undefined' ? styleOverride.hasControls : this.hasControls; - matrix = fabric.util.multiplyTransformMatrices(vpt, matrix); - options = fabric.util.qrDecompose(matrix); - ctx.save(); - ctx.translate(options.translateX, options.translateY); - ctx.lineWidth = 1 * this.borderScaleFactor; - if (!this.group) { - ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; - } - if (styleOverride.forActiveSelection) { - ctx.rotate(degreesToRadians(options.angle)); - drawBorders && this.drawBordersInGroup(ctx, options, styleOverride); - } - else { - ctx.rotate(degreesToRadians(this.angle)); - drawBorders && this.drawBorders(ctx, styleOverride); - } - drawControls && this.drawControls(ctx, styleOverride); - ctx.restore(); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _setShadow: function(ctx) { - if (!this.shadow) { - return; - } - - var shadow = this.shadow, canvas = this.canvas, scaling, - multX = (canvas && canvas.viewportTransform[0]) || 1, - multY = (canvas && canvas.viewportTransform[3]) || 1; - if (shadow.nonScaling) { - scaling = { scaleX: 1, scaleY: 1 }; - } - else { - scaling = this.getObjectScaling(); - } - if (canvas && canvas._isRetinaScaling()) { - multX *= fabric.devicePixelRatio; - multY *= fabric.devicePixelRatio; - } - ctx.shadowColor = shadow.color; - ctx.shadowBlur = shadow.blur * fabric.browserShadowBlurConstant * - (multX + multY) * (scaling.scaleX + scaling.scaleY) / 4; - ctx.shadowOffsetX = shadow.offsetX * multX * scaling.scaleX; - ctx.shadowOffsetY = shadow.offsetY * multY * scaling.scaleY; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _removeShadow: function(ctx) { - if (!this.shadow) { - return; - } - - ctx.shadowColor = ''; - ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Object} filler fabric.Pattern or fabric.Gradient - * @return {Object} offset.offsetX offset for text rendering - * @return {Object} offset.offsetY offset for text rendering - */ - _applyPatternGradientTransform: function(ctx, filler) { - if (!filler || !filler.toLive) { - return { offsetX: 0, offsetY: 0 }; - } - var t = filler.gradientTransform || filler.patternTransform; - var offsetX = -this.width / 2 + filler.offsetX || 0, - offsetY = -this.height / 2 + filler.offsetY || 0; - - if (filler.gradientUnits === 'percentage') { - ctx.transform(this.width, 0, 0, this.height, offsetX, offsetY); - } - else { - ctx.transform(1, 0, 0, 1, offsetX, offsetY); - } - if (t) { - ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]); - } - return { offsetX: offsetX, offsetY: offsetY }; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderPaintInOrder: function(ctx) { - if (this.paintFirst === 'stroke') { - this._renderStroke(ctx); - this._renderFill(ctx); - } - else { - this._renderFill(ctx); - this._renderStroke(ctx); - } - }, - - /** - * @private - * function that actually render something on the context. - * empty here to allow Obects to work on tests to benchmark fabric functionalites - * not related to rendering - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(/* ctx */) { - - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderFill: function(ctx) { - if (!this.fill) { - return; - } - - ctx.save(); - this._setFillStyles(ctx, this); - if (this.fillRule === 'evenodd') { - ctx.fill('evenodd'); - } - else { - ctx.fill(); - } - ctx.restore(); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderStroke: function(ctx) { - if (!this.stroke || this.strokeWidth === 0) { - return; - } - - if (this.shadow && !this.shadow.affectStroke) { - this._removeShadow(ctx); - } - - ctx.save(); - if (this.strokeUniform && this.group) { - var scaling = this.getObjectScaling(); - ctx.scale(1 / scaling.scaleX, 1 / scaling.scaleY); - } - else if (this.strokeUniform) { - ctx.scale(1 / this.scaleX, 1 / this.scaleY); - } - this._setLineDash(ctx, this.strokeDashArray, this._renderDashedStroke); - this._setStrokeStyles(ctx, this); - ctx.stroke(); - ctx.restore(); - }, - - /** - * This function try to patch the missing gradientTransform on canvas gradients. - * transforming a context to transform the gradient, is going to transform the stroke too. - * we want to transform the gradient but not the stroke operation, so we create - * a transformed gradient on a pattern and then we use the pattern instead of the gradient. - * this method has drwabacks: is slow, is in low resolution, needs a patch for when the size - * is limited. - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {fabric.Gradient} filler a fabric gradient instance - */ - _applyPatternForTransformedGradient: function(ctx, filler) { - var dims = this._limitCacheSize(this._getCacheCanvasDimensions()), - pCanvas = fabric.util.createCanvasElement(), pCtx, retinaScaling = this.canvas.getRetinaScaling(), - width = dims.x / this.scaleX / retinaScaling, height = dims.y / this.scaleY / retinaScaling; - pCanvas.width = width; - pCanvas.height = height; - pCtx = pCanvas.getContext('2d'); - pCtx.beginPath(); pCtx.moveTo(0, 0); pCtx.lineTo(width, 0); pCtx.lineTo(width, height); - pCtx.lineTo(0, height); pCtx.closePath(); - pCtx.translate(width / 2, height / 2); - pCtx.scale( - dims.zoomX / this.scaleX / retinaScaling, - dims.zoomY / this.scaleY / retinaScaling - ); - this._applyPatternGradientTransform(pCtx, filler); - pCtx.fillStyle = filler.toLive(ctx); - pCtx.fill(); - ctx.translate(-this.width / 2 - this.strokeWidth / 2, -this.height / 2 - this.strokeWidth / 2); - ctx.scale( - retinaScaling * this.scaleX / dims.zoomX, - retinaScaling * this.scaleY / dims.zoomY - ); - ctx.strokeStyle = pCtx.createPattern(pCanvas, 'no-repeat'); - }, - - /** - * This function is an helper for svg import. it returns the center of the object in the svg - * untransformed coordinates - * @private - * @return {Object} center point from element coordinates - */ - _findCenterFromElement: function() { - return { x: this.left + this.width / 2, y: this.top + this.height / 2 }; - }, - - /** - * This function is an helper for svg import. it decompose the transformMatrix - * and assign properties to object. - * untransformed coordinates - * @private - * @chainable - */ - _assignTransformMatrixProps: function() { - if (this.transformMatrix) { - var options = fabric.util.qrDecompose(this.transformMatrix); - this.flipX = false; - this.flipY = false; - this.set('scaleX', options.scaleX); - this.set('scaleY', options.scaleY); - this.angle = options.angle; - this.skewX = options.skewX; - this.skewY = 0; - } - }, - - /** - * This function is an helper for svg import. it removes the transform matrix - * and set to object properties that fabricjs can handle - * @private - * @param {Object} preserveAspectRatioOptions - * @return {thisArg} - */ - _removeTransformMatrix: function(preserveAspectRatioOptions) { - var center = this._findCenterFromElement(); - if (this.transformMatrix) { - this._assignTransformMatrixProps(); - center = fabric.util.transformPoint(center, this.transformMatrix); - } - this.transformMatrix = null; - if (preserveAspectRatioOptions) { - this.scaleX *= preserveAspectRatioOptions.scaleX; - this.scaleY *= preserveAspectRatioOptions.scaleY; - this.cropX = preserveAspectRatioOptions.cropX; - this.cropY = preserveAspectRatioOptions.cropY; - center.x += preserveAspectRatioOptions.offsetLeft; - center.y += preserveAspectRatioOptions.offsetTop; - this.width = preserveAspectRatioOptions.width; - this.height = preserveAspectRatioOptions.height; - } - this.setPositionByOrigin(center, 'center', 'center'); - }, - - /** - * Clones an instance, using a callback method will work for every object. - * @param {Function} callback Callback is invoked with a clone as a first argument - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - */ - clone: function(callback, propertiesToInclude) { - var objectForm = this.toObject(propertiesToInclude); - if (this.constructor.fromObject) { - this.constructor.fromObject(objectForm, callback); - } - else { - fabric.Object._fromObject('Object', objectForm, callback); - } - }, - - /** - * Creates an instance of fabric.Image out of an object - * makes use of toCanvasElement. - * Once this method was based on toDataUrl and loadImage, so it also had a quality - * and format option. toCanvasElement is faster and produce no loss of quality. - * If you need to get a real Jpeg or Png from an object, using toDataURL is the right way to do it. - * toCanvasElement and then toBlob from the obtained canvas is also a good option. - * This method is sync now, but still support the callback because we did not want to break. - * When fabricJS 5.0 will be planned, this will probably be changed to not have a callback. - * @param {Function} callback callback, invoked with an instance as a first argument - * @param {Object} [options] for clone as image, passed to toDataURL - * @param {Number} [options.multiplier=1] Multiplier to scale by - * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 - * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 - * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 - * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 - * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4 - * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 - * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2 - * @return {fabric.Object} thisArg - */ - cloneAsImage: function(callback, options) { - var canvasEl = this.toCanvasElement(options); - if (callback) { - callback(new fabric.Image(canvasEl)); - } - return this; - }, - - /** - * Converts an object into a HTMLCanvas element - * @param {Object} options Options object - * @param {Number} [options.multiplier=1] Multiplier to scale by - * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 - * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 - * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 - * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 - * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4 - * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 - * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2 - * @return {HTMLCanvasElement} Returns DOM element with the fabric.Object - */ - toCanvasElement: function(options) { - options || (options = { }); - - var utils = fabric.util, origParams = utils.saveObjectTransform(this), - originalGroup = this.group, - originalShadow = this.shadow, abs = Math.abs, - multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? fabric.devicePixelRatio : 1); - delete this.group; - if (options.withoutTransform) { - utils.resetObjectTransform(this); - } - if (options.withoutShadow) { - this.shadow = null; - } - - var el = fabric.util.createCanvasElement(), - // skip canvas zoom and calculate with setCoords now. - boundingRect = this.getBoundingRect(true, true), - shadow = this.shadow, scaling, - shadowOffset = { x: 0, y: 0 }, shadowBlur, - width, height; - - if (shadow) { - shadowBlur = shadow.blur; - if (shadow.nonScaling) { - scaling = { scaleX: 1, scaleY: 1 }; - } - else { - scaling = this.getObjectScaling(); - } - // consider non scaling shadow. - shadowOffset.x = 2 * Math.round(abs(shadow.offsetX) + shadowBlur) * (abs(scaling.scaleX)); - shadowOffset.y = 2 * Math.round(abs(shadow.offsetY) + shadowBlur) * (abs(scaling.scaleY)); - } - width = boundingRect.width + shadowOffset.x; - height = boundingRect.height + shadowOffset.y; - // if the current width/height is not an integer - // we need to make it so. - el.width = Math.ceil(width); - el.height = Math.ceil(height); - var canvas = new fabric.StaticCanvas(el, { - enableRetinaScaling: false, - renderOnAddRemove: false, - skipOffscreen: false, - }); - if (options.format === 'jpeg') { - canvas.backgroundColor = '#fff'; - } - this.setPositionByOrigin(new fabric.Point(canvas.width / 2, canvas.height / 2), 'center', 'center'); - - var originalCanvas = this.canvas; - canvas.add(this); - var canvasEl = canvas.toCanvasElement(multiplier || 1, options); - this.shadow = originalShadow; - this.set('canvas', originalCanvas); - if (originalGroup) { - this.group = originalGroup; - } - this.set(origParams).setCoords(); - // canvas.dispose will call image.dispose that will nullify the elements - // since this canvas is a simple element for the process, we remove references - // to objects in this way in order to avoid object trashing. - canvas._objects = []; - canvas.dispose(); - canvas = null; - - return canvasEl; - }, - - /** - * Converts an object into a data-url-like string - * @param {Object} options Options object - * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png" - * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg. - * @param {Number} [options.multiplier=1] Multiplier to scale by - * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 - * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 - * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 - * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 - * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4 - * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 - * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2 - * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format - */ - toDataURL: function(options) { - options || (options = { }); - return fabric.util.toDataURL(this.toCanvasElement(options), options.format || 'png', options.quality || 1); - }, - - /** - * Returns true if specified type is identical to the type of an instance - * @param {String} type Type to check against - * @return {Boolean} - */ - isType: function(type) { - return this.type === type; - }, - - /** - * Returns complexity of an instance - * @return {Number} complexity of this instance (is 1 unless subclassed) - */ - complexity: function() { - return 1; - }, - - /** - * Returns a JSON representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} JSON - */ - toJSON: function(propertiesToInclude) { - // delegate, not alias - return this.toObject(propertiesToInclude); - }, - - /** - * Sets "angle" of an instance with centered rotation - * @param {Number} angle Angle value (in degrees) - * @return {fabric.Object} thisArg - * @chainable - */ - rotate: function(angle) { - var shouldCenterOrigin = (this.originX !== 'center' || this.originY !== 'center') && this.centeredRotation; - - if (shouldCenterOrigin) { - this._setOriginToCenter(); - } - - this.set('angle', angle); - - if (shouldCenterOrigin) { - this._resetOrigin(); - } - - return this; - }, - - /** - * Centers object horizontally on canvas to which it was added last. - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - centerH: function () { - this.canvas && this.canvas.centerObjectH(this); - return this; - }, - - /** - * Centers object horizontally on current viewport of canvas to which it was added last. - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - viewportCenterH: function () { - this.canvas && this.canvas.viewportCenterObjectH(this); - return this; - }, - - /** - * Centers object vertically on canvas to which it was added last. - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - centerV: function () { - this.canvas && this.canvas.centerObjectV(this); - return this; - }, - - /** - * Centers object vertically on current viewport of canvas to which it was added last. - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - viewportCenterV: function () { - this.canvas && this.canvas.viewportCenterObjectV(this); - return this; - }, - - /** - * Centers object vertically and horizontally on canvas to which is was added last - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - center: function () { - this.canvas && this.canvas.centerObject(this); - return this; - }, - - /** - * Centers object on current viewport of canvas to which it was added last. - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - viewportCenter: function () { - this.canvas && this.canvas.viewportCenterObject(this); - return this; - }, - - /** - * Returns coordinates of a pointer relative to an object - * @param {Event} e Event to operate upon - * @param {Object} [pointer] Pointer to operate upon (instead of event) - * @return {Object} Coordinates of a pointer (x, y) - */ - getLocalPointer: function(e, pointer) { - pointer = pointer || this.canvas.getPointer(e); - var pClicked = new fabric.Point(pointer.x, pointer.y), - objectLeftTop = this._getLeftTopCoords(); - if (this.angle) { - pClicked = fabric.util.rotatePoint( - pClicked, objectLeftTop, degreesToRadians(-this.angle)); - } - return { - x: pClicked.x - objectLeftTop.x, - y: pClicked.y - objectLeftTop.y - }; - }, - - /** - * Sets canvas globalCompositeOperation for specific object - * custom composition operation for the particular object can be specified using globalCompositeOperation property - * @param {CanvasRenderingContext2D} ctx Rendering canvas context - */ - _setupCompositeOperation: function (ctx) { - if (this.globalCompositeOperation) { - ctx.globalCompositeOperation = this.globalCompositeOperation; - } - } - }); - - fabric.util.createAccessors && fabric.util.createAccessors(fabric.Object); - - extend(fabric.Object.prototype, fabric.Observable); - - /** - * Defines the number of fraction digits to use when serializing object values. - * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc. - * @static - * @memberOf fabric.Object - * @constant - * @type Number - */ - fabric.Object.NUM_FRACTION_DIGITS = 2; - - fabric.Object._fromObject = function(className, object, callback, extraParam) { - var klass = fabric[className]; - object = clone(object, true); - fabric.util.enlivenPatterns([object.fill, object.stroke], function(patterns) { - if (typeof patterns[0] !== 'undefined') { - object.fill = patterns[0]; - } - if (typeof patterns[1] !== 'undefined') { - object.stroke = patterns[1]; - } - fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) { - object.clipPath = enlivedProps[0]; - var instance = extraParam ? new klass(object[extraParam], object) : new klass(object); - callback && callback(instance); - }); - }); - }; - - /** - * Unique id used internally when creating SVG elements - * @static - * @memberOf fabric.Object - * @type Number - */ - fabric.Object.__uid = 0; -})(typeof exports !== 'undefined' ? exports : this); - - -(function() { - - var degreesToRadians = fabric.util.degreesToRadians, - originXOffset = { - left: -0.5, - center: 0, - right: 0.5 - }, - originYOffset = { - top: -0.5, - center: 0, - bottom: 0.5 - }; - - fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - - /** - * Translates the coordinates from a set of origin to another (based on the object's dimensions) - * @param {fabric.Point} point The point which corresponds to the originX and originY params - * @param {String} fromOriginX Horizontal origin: 'left', 'center' or 'right' - * @param {String} fromOriginY Vertical origin: 'top', 'center' or 'bottom' - * @param {String} toOriginX Horizontal origin: 'left', 'center' or 'right' - * @param {String} toOriginY Vertical origin: 'top', 'center' or 'bottom' - * @return {fabric.Point} - */ - translateToGivenOrigin: function(point, fromOriginX, fromOriginY, toOriginX, toOriginY) { - var x = point.x, - y = point.y, - offsetX, offsetY, dim; - - if (typeof fromOriginX === 'string') { - fromOriginX = originXOffset[fromOriginX]; - } - else { - fromOriginX -= 0.5; - } - - if (typeof toOriginX === 'string') { - toOriginX = originXOffset[toOriginX]; - } - else { - toOriginX -= 0.5; - } - - offsetX = toOriginX - fromOriginX; - - if (typeof fromOriginY === 'string') { - fromOriginY = originYOffset[fromOriginY]; - } - else { - fromOriginY -= 0.5; - } - - if (typeof toOriginY === 'string') { - toOriginY = originYOffset[toOriginY]; - } - else { - toOriginY -= 0.5; - } - - offsetY = toOriginY - fromOriginY; - - if (offsetX || offsetY) { - dim = this._getTransformedDimensions(); - x = point.x + offsetX * dim.x; - y = point.y + offsetY * dim.y; - } - - return new fabric.Point(x, y); - }, - - /** - * Translates the coordinates from origin to center coordinates (based on the object's dimensions) - * @param {fabric.Point} point The point which corresponds to the originX and originY params - * @param {String} originX Horizontal origin: 'left', 'center' or 'right' - * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' - * @return {fabric.Point} - */ - translateToCenterPoint: function(point, originX, originY) { - var p = this.translateToGivenOrigin(point, originX, originY, 'center', 'center'); - if (this.angle) { - return fabric.util.rotatePoint(p, point, degreesToRadians(this.angle)); - } - return p; - }, - - /** - * Translates the coordinates from center to origin coordinates (based on the object's dimensions) - * @param {fabric.Point} center The point which corresponds to center of the object - * @param {String} originX Horizontal origin: 'left', 'center' or 'right' - * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' - * @return {fabric.Point} - */ - translateToOriginPoint: function(center, originX, originY) { - var p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY); - if (this.angle) { - return fabric.util.rotatePoint(p, center, degreesToRadians(this.angle)); - } - return p; - }, - - /** - * Returns the real center coordinates of the object - * @return {fabric.Point} - */ - getCenterPoint: function() { - var leftTop = new fabric.Point(this.left, this.top); - return this.translateToCenterPoint(leftTop, this.originX, this.originY); - }, - - /** - * Returns the coordinates of the object based on center coordinates - * @param {fabric.Point} point The point which corresponds to the originX and originY params - * @return {fabric.Point} - */ - // getOriginPoint: function(center) { - // return this.translateToOriginPoint(center, this.originX, this.originY); - // }, - - /** - * Returns the coordinates of the object as if it has a different origin - * @param {String} originX Horizontal origin: 'left', 'center' or 'right' - * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' - * @return {fabric.Point} - */ - getPointByOrigin: function(originX, originY) { - var center = this.getCenterPoint(); - return this.translateToOriginPoint(center, originX, originY); - }, - - /** - * Returns the point in local coordinates - * @param {fabric.Point} point The point relative to the global coordinate system - * @param {String} originX Horizontal origin: 'left', 'center' or 'right' - * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' - * @return {fabric.Point} - */ - toLocalPoint: function(point, originX, originY) { - var center = this.getCenterPoint(), - p, p2; - - if (typeof originX !== 'undefined' && typeof originY !== 'undefined' ) { - p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY); - } - else { - p = new fabric.Point(this.left, this.top); - } - - p2 = new fabric.Point(point.x, point.y); - if (this.angle) { - p2 = fabric.util.rotatePoint(p2, center, -degreesToRadians(this.angle)); - } - return p2.subtractEquals(p); - }, - - /** - * Returns the point in global coordinates - * @param {fabric.Point} The point relative to the local coordinate system - * @return {fabric.Point} - */ - // toGlobalPoint: function(point) { - // return fabric.util.rotatePoint(point, this.getCenterPoint(), degreesToRadians(this.angle)).addEquals(new fabric.Point(this.left, this.top)); - // }, - - /** - * Sets the position of the object taking into consideration the object's origin - * @param {fabric.Point} pos The new position of the object - * @param {String} originX Horizontal origin: 'left', 'center' or 'right' - * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' - * @return {void} - */ - setPositionByOrigin: function(pos, originX, originY) { - var center = this.translateToCenterPoint(pos, originX, originY), - position = this.translateToOriginPoint(center, this.originX, this.originY); - this.set('left', position.x); - this.set('top', position.y); - }, - - /** - * @param {String} to One of 'left', 'center', 'right' - */ - adjustPosition: function(to) { - var angle = degreesToRadians(this.angle), - hypotFull = this.getScaledWidth(), - xFull = fabric.util.cos(angle) * hypotFull, - yFull = fabric.util.sin(angle) * hypotFull, - offsetFrom, offsetTo; - - //TODO: this function does not consider mixed situation like top, center. - if (typeof this.originX === 'string') { - offsetFrom = originXOffset[this.originX]; - } - else { - offsetFrom = this.originX - 0.5; - } - if (typeof to === 'string') { - offsetTo = originXOffset[to]; - } - else { - offsetTo = to - 0.5; - } - this.left += xFull * (offsetTo - offsetFrom); - this.top += yFull * (offsetTo - offsetFrom); - this.setCoords(); - this.originX = to; - }, - - /** - * Sets the origin/position of the object to it's center point - * @private - * @return {void} - */ - _setOriginToCenter: function() { - this._originalOriginX = this.originX; - this._originalOriginY = this.originY; - - var center = this.getCenterPoint(); - - this.originX = 'center'; - this.originY = 'center'; - - this.left = center.x; - this.top = center.y; - }, - - /** - * Resets the origin/position of the object to it's original origin - * @private - * @return {void} - */ - _resetOrigin: function() { - var originPoint = this.translateToOriginPoint( - this.getCenterPoint(), - this._originalOriginX, - this._originalOriginY); - - this.originX = this._originalOriginX; - this.originY = this._originalOriginY; - - this.left = originPoint.x; - this.top = originPoint.y; - - this._originalOriginX = null; - this._originalOriginY = null; - }, - - /** - * @private - */ - _getLeftTopCoords: function() { - return this.translateToOriginPoint(this.getCenterPoint(), 'left', 'top'); - }, - }); - -})(); - - -(function() { - - function arrayFromCoords(coords) { - return [ - new fabric.Point(coords.tl.x, coords.tl.y), - new fabric.Point(coords.tr.x, coords.tr.y), - new fabric.Point(coords.br.x, coords.br.y), - new fabric.Point(coords.bl.x, coords.bl.y) - ]; - } - - var util = fabric.util, - degreesToRadians = util.degreesToRadians, - multiplyMatrices = util.multiplyTransformMatrices, - transformPoint = util.transformPoint; - - util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - - /** - * Describe object's corner position in canvas element coordinates. - * properties are depending on control keys and padding the main controls. - * each property is an object with x, y and corner. - * The `corner` property contains in a similar manner the 4 points of the - * interactive area of the corner. - * The coordinates depends from the controls positionHandler and are used - * to draw and locate controls - * @memberOf fabric.Object.prototype - */ - oCoords: null, - - /** - * Describe object's corner position in canvas object absolute coordinates - * properties are tl,tr,bl,br and describe the four main corner. - * each property is an object with x, y, instance of Fabric.Point. - * The coordinates depends from this properties: width, height, scaleX, scaleY - * skewX, skewY, angle, strokeWidth, top, left. - * Those coordinates are useful to understand where an object is. They get updated - * with oCoords but they do not need to be updated when zoom or panning change. - * The coordinates get updated with @method setCoords. - * You can calculate them without updating with @method calcACoords(); - * @memberOf fabric.Object.prototype - */ - aCoords: null, - - /** - * Describe object's corner position in canvas element coordinates. - * includes padding. Used of object detection. - * set and refreshed with setCoords and calcCoords. - * @memberOf fabric.Object.prototype - */ - lineCoords: null, - - /** - * storage for object transform matrix - */ - ownMatrixCache: null, - - /** - * storage for object full transform matrix - */ - matrixCache: null, - - /** - * custom controls interface - * controls are added by default_controls.js - */ - controls: { }, - - /** - * return correct set of coordinates for intersection - * this will return either aCoords or lineCoords. - * @param {Boolean} absolute will return aCoords if true or lineCoords - * @return {Object} {tl, tr, br, bl} points - */ - _getCoords: function(absolute, calculate) { - if (calculate) { - return (absolute ? this.calcACoords() : this.calcLineCoords()); - } - if (!this.aCoords || !this.lineCoords) { - this.setCoords(true); - } - return (absolute ? this.aCoords : this.lineCoords); - }, - - /** - * return correct set of coordinates for intersection - * this will return either aCoords or lineCoords. - * The coords are returned in an array. - * @return {Array} [tl, tr, br, bl] of points - */ - getCoords: function(absolute, calculate) { - return arrayFromCoords(this._getCoords(absolute, calculate)); - }, - - /** - * Checks if object intersects with an area formed by 2 points - * @param {Object} pointTL top-left point of area - * @param {Object} pointBR bottom-right point of area - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if object intersects with an area formed by 2 points - */ - intersectsWithRect: function(pointTL, pointBR, absolute, calculate) { - var coords = this.getCoords(absolute, calculate), - intersection = fabric.Intersection.intersectPolygonRectangle( - coords, - pointTL, - pointBR - ); - return intersection.status === 'Intersection'; - }, - - /** - * Checks if object intersects with another object - * @param {Object} other Object to test - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if object intersects with another object - */ - intersectsWithObject: function(other, absolute, calculate) { - var intersection = fabric.Intersection.intersectPolygonPolygon( - this.getCoords(absolute, calculate), - other.getCoords(absolute, calculate) - ); - - return intersection.status === 'Intersection' - || other.isContainedWithinObject(this, absolute, calculate) - || this.isContainedWithinObject(other, absolute, calculate); - }, - - /** - * Checks if object is fully contained within area of another object - * @param {Object} other Object to test - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if object is fully contained within area of another object - */ - isContainedWithinObject: function(other, absolute, calculate) { - var points = this.getCoords(absolute, calculate), - otherCoords = absolute ? other.aCoords : other.lineCoords, - i = 0, lines = other._getImageLines(otherCoords); - for (; i < 4; i++) { - if (!other.containsPoint(points[i], lines)) { - return false; - } - } - return true; - }, - - /** - * Checks if object is fully contained within area formed by 2 points - * @param {Object} pointTL top-left point of area - * @param {Object} pointBR bottom-right point of area - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if object is fully contained within area formed by 2 points - */ - isContainedWithinRect: function(pointTL, pointBR, absolute, calculate) { - var boundingRect = this.getBoundingRect(absolute, calculate); - - return ( - boundingRect.left >= pointTL.x && - boundingRect.left + boundingRect.width <= pointBR.x && - boundingRect.top >= pointTL.y && - boundingRect.top + boundingRect.height <= pointBR.y - ); - }, - - /** - * Checks if point is inside the object - * @param {fabric.Point} point Point to check against - * @param {Object} [lines] object returned from @method _getImageLines - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if point is inside the object - */ - containsPoint: function(point, lines, absolute, calculate) { - var coords = this._getCoords(absolute, calculate), - lines = lines || this._getImageLines(coords), - xPoints = this._findCrossPoints(point, lines); - // if xPoints is odd then point is inside the object - return (xPoints !== 0 && xPoints % 2 === 1); - }, - - /** - * Checks if object is contained within the canvas with current viewportTransform - * the check is done stopping at first point that appears on screen - * @param {Boolean} [calculate] use coordinates of current position instead of .aCoords - * @return {Boolean} true if object is fully or partially contained within canvas - */ - isOnScreen: function(calculate) { - if (!this.canvas) { - return false; - } - var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br; - var points = this.getCoords(true, calculate); - // if some point is on screen, the object is on screen. - if (points.some(function(point) { - return point.x <= pointBR.x && point.x >= pointTL.x && - point.y <= pointBR.y && point.y >= pointTL.y; - })) { - return true; - } - // no points on screen, check intersection with absolute coordinates - if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) { - return true; - } - return this._containsCenterOfCanvas(pointTL, pointBR, calculate); - }, - - /** - * Checks if the object contains the midpoint between canvas extremities - * Does not make sense outside the context of isOnScreen and isPartiallyOnScreen - * @private - * @param {Fabric.Point} pointTL Top Left point - * @param {Fabric.Point} pointBR Top Right point - * @param {Boolean} calculate use coordinates of current position instead of .oCoords - * @return {Boolean} true if the object contains the point - */ - _containsCenterOfCanvas: function(pointTL, pointBR, calculate) { - // worst case scenario the object is so big that contains the screen - var centerPoint = { x: (pointTL.x + pointBR.x) / 2, y: (pointTL.y + pointBR.y) / 2 }; - if (this.containsPoint(centerPoint, null, true, calculate)) { - return true; - } - return false; - }, - - /** - * Checks if object is partially contained within the canvas with current viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if object is partially contained within canvas - */ - isPartiallyOnScreen: function(calculate) { - if (!this.canvas) { - return false; - } - var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br; - if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) { - return true; - } - var allPointsAreOutside = this.getCoords(true, calculate).every(function(point) { - return (point.x >= pointBR.x || point.x <= pointTL.x) && - (point.y >= pointBR.y || point.y <= pointTL.y); - }); - return allPointsAreOutside && this._containsCenterOfCanvas(pointTL, pointBR, calculate); - }, - - /** - * Method that returns an object with the object edges in it, given the coordinates of the corners - * @private - * @param {Object} oCoords Coordinates of the object corners - */ - _getImageLines: function(oCoords) { - - var lines = { - topline: { - o: oCoords.tl, - d: oCoords.tr - }, - rightline: { - o: oCoords.tr, - d: oCoords.br - }, - bottomline: { - o: oCoords.br, - d: oCoords.bl - }, - leftline: { - o: oCoords.bl, - d: oCoords.tl - } - }; - - // // debugging - // if (this.canvas.contextTop) { - // this.canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2); - // } - - return lines; - }, - - /** - * Helper method to determine how many cross points are between the 4 object edges - * and the horizontal line determined by a point on canvas - * @private - * @param {fabric.Point} point Point to check - * @param {Object} lines Coordinates of the object being evaluated - */ - // remove yi, not used but left code here just in case. - _findCrossPoints: function(point, lines) { - var b1, b2, a1, a2, xi, // yi, - xcount = 0, - iLine; - - for (var lineKey in lines) { - iLine = lines[lineKey]; - // optimisation 1: line below point. no cross - if ((iLine.o.y < point.y) && (iLine.d.y < point.y)) { - continue; - } - // optimisation 2: line above point. no cross - if ((iLine.o.y >= point.y) && (iLine.d.y >= point.y)) { - continue; - } - // optimisation 3: vertical line case - if ((iLine.o.x === iLine.d.x) && (iLine.o.x >= point.x)) { - xi = iLine.o.x; - // yi = point.y; - } - // calculate the intersection point - else { - b1 = 0; - b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x); - a1 = point.y - b1 * point.x; - a2 = iLine.o.y - b2 * iLine.o.x; - - xi = -(a1 - a2) / (b1 - b2); - // yi = a1 + b1 * xi; - } - // dont count xi < point.x cases - if (xi >= point.x) { - xcount += 1; - } - // optimisation 4: specific for square images - if (xcount === 2) { - break; - } - } - return xcount; - }, - - /** - * Returns coordinates of object's bounding rectangle (left, top, width, height) - * the box is intended as aligned to axis of canvas. - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords / .aCoords - * @return {Object} Object with left, top, width, height properties - */ - getBoundingRect: function(absolute, calculate) { - var coords = this.getCoords(absolute, calculate); - return util.makeBoundingBoxFromPoints(coords); - }, - - /** - * Returns width of an object's bounding box counting transformations - * before 2.0 it was named getWidth(); - * @return {Number} width value - */ - getScaledWidth: function() { - return this._getTransformedDimensions().x; - }, - - /** - * Returns height of an object bounding box counting transformations - * before 2.0 it was named getHeight(); - * @return {Number} height value - */ - getScaledHeight: function() { - return this._getTransformedDimensions().y; - }, - - /** - * Makes sure the scale is valid and modifies it if necessary - * @private - * @param {Number} value - * @return {Number} - */ - _constrainScale: function(value) { - if (Math.abs(value) < this.minScaleLimit) { - if (value < 0) { - return -this.minScaleLimit; - } - else { - return this.minScaleLimit; - } - } - else if (value === 0) { - return 0.0001; - } - return value; - }, - - /** - * Scales an object (equally by x and y) - * @param {Number} value Scale factor - * @return {fabric.Object} thisArg - * @chainable - */ - scale: function(value) { - this._set('scaleX', value); - this._set('scaleY', value); - return this.setCoords(); - }, - - /** - * Scales an object to a given width, with respect to bounding box (scaling by x/y equally) - * @param {Number} value New width value - * @param {Boolean} absolute ignore viewport - * @return {fabric.Object} thisArg - * @chainable - */ - scaleToWidth: function(value, absolute) { - // adjust to bounding rect factor so that rotated shapes would fit as well - var boundingRectFactor = this.getBoundingRect(absolute).width / this.getScaledWidth(); - return this.scale(value / this.width / boundingRectFactor); - }, - - /** - * Scales an object to a given height, with respect to bounding box (scaling by x/y equally) - * @param {Number} value New height value - * @param {Boolean} absolute ignore viewport - * @return {fabric.Object} thisArg - * @chainable - */ - scaleToHeight: function(value, absolute) { - // adjust to bounding rect factor so that rotated shapes would fit as well - var boundingRectFactor = this.getBoundingRect(absolute).height / this.getScaledHeight(); - return this.scale(value / this.height / boundingRectFactor); - }, - - /** - * Calculates and returns the .coords of an object. - * unused by the library, only for the end dev. - * @return {Object} Object with tl, tr, br, bl .... - * @chainable - * @deprecated - */ - calcCoords: function(absolute) { - // this is a compatibility function to avoid removing calcCoords now. - if (absolute) { - return this.calcACoords(); - } - return this.calcOCoords(); - }, - - calcLineCoords: function() { - var vpt = this.getViewportTransform(), - padding = this.padding, angle = degreesToRadians(this.angle), - cos = util.cos(angle), sin = util.sin(angle), - cosP = cos * padding, sinP = sin * padding, cosPSinP = cosP + sinP, - cosPMinusSinP = cosP - sinP, aCoords = this.calcACoords(); - - var lineCoords = { - tl: transformPoint(aCoords.tl, vpt), - tr: transformPoint(aCoords.tr, vpt), - bl: transformPoint(aCoords.bl, vpt), - br: transformPoint(aCoords.br, vpt), - }; - - if (padding) { - lineCoords.tl.x -= cosPMinusSinP; - lineCoords.tl.y -= cosPSinP; - lineCoords.tr.x += cosPSinP; - lineCoords.tr.y -= cosPMinusSinP; - lineCoords.bl.x -= cosPSinP; - lineCoords.bl.y += cosPMinusSinP; - lineCoords.br.x += cosPMinusSinP; - lineCoords.br.y += cosPSinP; - } - - return lineCoords; - }, - - calcOCoords: function() { - var rotateMatrix = this._calcRotateMatrix(), - translateMatrix = this._calcTranslateMatrix(), - vpt = this.getViewportTransform(), - startMatrix = multiplyMatrices(vpt, translateMatrix), - finalMatrix = multiplyMatrices(startMatrix, rotateMatrix), - finalMatrix = multiplyMatrices(finalMatrix, [1 / vpt[0], 0, 0, 1 / vpt[3], 0, 0]), - dim = this._calculateCurrentDimensions(), - coords = {}; - this.forEachControl(function(control, key, fabricObject) { - coords[key] = control.positionHandler(dim, finalMatrix, fabricObject); - }); - - // debug code - // var canvas = this.canvas; - // setTimeout(function() { - // canvas.contextTop.clearRect(0, 0, 700, 700); - // canvas.contextTop.fillStyle = 'green'; - // Object.keys(coords).forEach(function(key) { - // var control = coords[key]; - // canvas.contextTop.fillRect(control.x, control.y, 3, 3); - // }); - // }, 50); - return coords; - }, - - calcACoords: function() { - var rotateMatrix = this._calcRotateMatrix(), - translateMatrix = this._calcTranslateMatrix(), - finalMatrix = multiplyMatrices(translateMatrix, rotateMatrix), - dim = this._getTransformedDimensions(), - w = dim.x / 2, h = dim.y / 2; - return { - // corners - tl: transformPoint({ x: -w, y: -h }, finalMatrix), - tr: transformPoint({ x: w, y: -h }, finalMatrix), - bl: transformPoint({ x: -w, y: h }, finalMatrix), - br: transformPoint({ x: w, y: h }, finalMatrix) - }; - }, - - /** - * Sets corner and controls position coordinates based on current angle, width and height, left and top. - * oCoords are used to find the corners - * aCoords are used to quickly find an object on the canvas - * lineCoords are used to quickly find object during pointer events. - * See {@link https://github.com/kangax/fabric.js/wiki/When-to-call-setCoords|When-to-call-setCoords} - * @param {Boolean} [skipCorners] skip calculation of oCoords. - * @return {fabric.Object} thisArg - * @chainable - */ - setCoords: function(skipCorners) { - this.aCoords = this.calcACoords(); - // in case we are in a group, for how the inner group target check works, - // lineCoords are exactly aCoords. Since the vpt gets absorbed by the normalized pointer. - this.lineCoords = this.group ? this.aCoords : this.calcLineCoords(); - if (skipCorners) { - return this; - } - // set coordinates of the draggable boxes in the corners used to scale/rotate the image - this.oCoords = this.calcOCoords(); - this._setCornerCoords && this._setCornerCoords(); - return this; - }, - - /** - * calculate rotation matrix of an object - * @return {Array} rotation matrix for the object - */ - _calcRotateMatrix: function() { - return util.calcRotateMatrix(this); - }, - - /** - * calculate the translation matrix for an object transform - * @return {Array} rotation matrix for the object - */ - _calcTranslateMatrix: function() { - var center = this.getCenterPoint(); - return [1, 0, 0, 1, center.x, center.y]; - }, - - transformMatrixKey: function(skipGroup) { - var sep = '_', prefix = ''; - if (!skipGroup && this.group) { - prefix = this.group.transformMatrixKey(skipGroup) + sep; - }; - return prefix + this.top + sep + this.left + sep + this.scaleX + sep + this.scaleY + - sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.originX + sep + this.originY + - sep + this.width + sep + this.height + sep + this.strokeWidth + this.flipX + this.flipY; - }, - - /** - * calculate transform matrix that represents the current transformations from the - * object's properties. - * @param {Boolean} [skipGroup] return transform matrix for object not counting parent transformations - * There are some situation in which this is useful to avoid the fake rotation. - * @return {Array} transform matrix for the object - */ - calcTransformMatrix: function(skipGroup) { - var matrix = this.calcOwnMatrix(); - if (skipGroup || !this.group) { - return matrix; - } - var key = this.transformMatrixKey(skipGroup), cache = this.matrixCache || (this.matrixCache = {}); - if (cache.key === key) { - return cache.value; - } - if (this.group) { - matrix = multiplyMatrices(this.group.calcTransformMatrix(false), matrix); - } - cache.key = key; - cache.value = matrix; - return matrix; - }, - - /** - * calculate transform matrix that represents the current transformations from the - * object's properties, this matrix does not include the group transformation - * @return {Array} transform matrix for the object - */ - calcOwnMatrix: function() { - var key = this.transformMatrixKey(true), cache = this.ownMatrixCache || (this.ownMatrixCache = {}); - if (cache.key === key) { - return cache.value; - } - var tMatrix = this._calcTranslateMatrix(), - options = { - angle: this.angle, - translateX: tMatrix[4], - translateY: tMatrix[5], - scaleX: this.scaleX, - scaleY: this.scaleY, - skewX: this.skewX, - skewY: this.skewY, - flipX: this.flipX, - flipY: this.flipY, - }; - cache.key = key; - cache.value = util.composeMatrix(options); - return cache.value; - }, - - /* - * Calculate object dimensions from its properties - * @private - * @deprecated since 3.4.0, please use fabric.util._calcDimensionsTransformMatrix - * not including or including flipX, flipY to emulate the flipping boolean - * @return {Object} .x width dimension - * @return {Object} .y height dimension - */ - _calcDimensionsTransformMatrix: function(skewX, skewY, flipping) { - return util.calcDimensionsMatrix({ - skewX: skewX, - skewY: skewY, - scaleX: this.scaleX * (flipping && this.flipX ? -1 : 1), - scaleY: this.scaleY * (flipping && this.flipY ? -1 : 1) - }); - }, - - /* - * Calculate object dimensions from its properties - * @private - * @return {Object} .x width dimension - * @return {Object} .y height dimension - */ - _getNonTransformedDimensions: function() { - var strokeWidth = this.strokeWidth, - w = this.width + strokeWidth, - h = this.height + strokeWidth; - return { x: w, y: h }; - }, - - /* - * Calculate object bounding box dimensions from its properties scale, skew. - * @param {Number} skewX, a value to override current skewX - * @param {Number} skewY, a value to override current skewY - * @private - * @return {Object} .x width dimension - * @return {Object} .y height dimension - */ - _getTransformedDimensions: function(skewX, skewY) { - if (typeof skewX === 'undefined') { - skewX = this.skewX; - } - if (typeof skewY === 'undefined') { - skewY = this.skewY; - } - var dimensions = this._getNonTransformedDimensions(), dimX, dimY, - noSkew = skewX === 0 && skewY === 0; - - if (this.strokeUniform) { - dimX = this.width; - dimY = this.height; - } - else { - dimX = dimensions.x; - dimY = dimensions.y; - } - if (noSkew) { - return this._finalizeDimensions(dimX * this.scaleX, dimY * this.scaleY); - } - var bbox = util.sizeAfterTransform(dimX, dimY, { - scaleX: this.scaleX, - scaleY: this.scaleY, - skewX: skewX, - skewY: skewY, - }); - return this._finalizeDimensions(bbox.x, bbox.y); - }, - - /* - * Calculate object bounding box dimensions from its properties scale, skew. - * @param Number width width of the bbox - * @param Number height height of the bbox - * @private - * @return {Object} .x finalized width dimension - * @return {Object} .y finalized height dimension - */ - _finalizeDimensions: function(width, height) { - return this.strokeUniform ? - { x: width + this.strokeWidth, y: height + this.strokeWidth } - : - { x: width, y: height }; - }, - - /* - * Calculate object dimensions for controls box, including padding and canvas zoom. - * and active selection - * private - */ - _calculateCurrentDimensions: function() { - var vpt = this.getViewportTransform(), - dim = this._getTransformedDimensions(), - p = transformPoint(dim, vpt, true); - return p.scalarAdd(2 * this.padding); - }, - }); -})(); - - -fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - - /** - * Moves an object to the bottom of the stack of drawn objects - * @return {fabric.Object} thisArg - * @chainable - */ - sendToBack: function() { - if (this.group) { - fabric.StaticCanvas.prototype.sendToBack.call(this.group, this); - } - else if (this.canvas) { - this.canvas.sendToBack(this); - } - return this; - }, - - /** - * Moves an object to the top of the stack of drawn objects - * @return {fabric.Object} thisArg - * @chainable - */ - bringToFront: function() { - if (this.group) { - fabric.StaticCanvas.prototype.bringToFront.call(this.group, this); - } - else if (this.canvas) { - this.canvas.bringToFront(this); - } - return this; - }, - - /** - * Moves an object down in stack of drawn objects - * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object - * @return {fabric.Object} thisArg - * @chainable - */ - sendBackwards: function(intersecting) { - if (this.group) { - fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting); - } - else if (this.canvas) { - this.canvas.sendBackwards(this, intersecting); - } - return this; - }, - - /** - * Moves an object up in stack of drawn objects - * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object - * @return {fabric.Object} thisArg - * @chainable - */ - bringForward: function(intersecting) { - if (this.group) { - fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting); - } - else if (this.canvas) { - this.canvas.bringForward(this, intersecting); - } - return this; - }, - - /** - * Moves an object to specified level in stack of drawn objects - * @param {Number} index New position of object - * @return {fabric.Object} thisArg - * @chainable - */ - moveTo: function(index) { - if (this.group && this.group.type !== 'activeSelection') { - fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index); - } - else if (this.canvas) { - this.canvas.moveTo(this, index); - } - return this; - } -}); - - -/* _TO_SVG_START_ */ -(function() { - function getSvgColorString(prop, value) { - if (!value) { - return prop + ': none; '; - } - else if (value.toLive) { - return prop + ': url(#SVGID_' + value.id + '); '; - } - else { - var color = new fabric.Color(value), - str = prop + ': ' + color.toRgb() + '; ', - opacity = color.getAlpha(); - if (opacity !== 1) { - //change the color in rgb + opacity - str += prop + '-opacity: ' + opacity.toString() + '; '; - } - return str; - } - } - - var toFixed = fabric.util.toFixed; - - fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - /** - * Returns styles-string for svg-export - * @param {Boolean} skipShadow a boolean to skip shadow filter output - * @return {String} - */ - getSvgStyles: function(skipShadow) { - - var fillRule = this.fillRule ? this.fillRule : 'nonzero', - strokeWidth = this.strokeWidth ? this.strokeWidth : '0', - strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none', - strokeDashOffset = this.strokeDashOffset ? this.strokeDashOffset : '0', - strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt', - strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter', - strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4', - opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1', - visibility = this.visible ? '' : ' visibility: hidden;', - filter = skipShadow ? '' : this.getSvgFilter(), - fill = getSvgColorString('fill', this.fill), - stroke = getSvgColorString('stroke', this.stroke); - - return [ - stroke, - 'stroke-width: ', strokeWidth, '; ', - 'stroke-dasharray: ', strokeDashArray, '; ', - 'stroke-linecap: ', strokeLineCap, '; ', - 'stroke-dashoffset: ', strokeDashOffset, '; ', - 'stroke-linejoin: ', strokeLineJoin, '; ', - 'stroke-miterlimit: ', strokeMiterLimit, '; ', - fill, - 'fill-rule: ', fillRule, '; ', - 'opacity: ', opacity, ';', - filter, - visibility - ].join(''); - }, - - /** - * Returns styles-string for svg-export - * @param {Object} style the object from which to retrieve style properties - * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style. - * @return {String} - */ - getSvgSpanStyles: function(style, useWhiteSpace) { - var term = '; '; - var fontFamily = style.fontFamily ? - 'font-family: ' + (((style.fontFamily.indexOf('\'') === -1 && style.fontFamily.indexOf('"') === -1) ? - '\'' + style.fontFamily + '\'' : style.fontFamily)) + term : ''; - var strokeWidth = style.strokeWidth ? 'stroke-width: ' + style.strokeWidth + term : '', - fontFamily = fontFamily, - fontSize = style.fontSize ? 'font-size: ' + style.fontSize + 'px' + term : '', - fontStyle = style.fontStyle ? 'font-style: ' + style.fontStyle + term : '', - fontWeight = style.fontWeight ? 'font-weight: ' + style.fontWeight + term : '', - fill = style.fill ? getSvgColorString('fill', style.fill) : '', - stroke = style.stroke ? getSvgColorString('stroke', style.stroke) : '', - textDecoration = this.getSvgTextDecoration(style), - deltaY = style.deltaY ? 'baseline-shift: ' + (-style.deltaY) + '; ' : ''; - if (textDecoration) { - textDecoration = 'text-decoration: ' + textDecoration + term; - } - - return [ - stroke, - strokeWidth, - fontFamily, - fontSize, - fontStyle, - fontWeight, - textDecoration, - fill, - deltaY, - useWhiteSpace ? 'white-space: pre; ' : '' - ].join(''); - }, - - /** - * Returns text-decoration property for svg-export - * @param {Object} style the object from which to retrieve style properties - * @return {String} - */ - getSvgTextDecoration: function(style) { - return ['overline', 'underline', 'line-through'].filter(function(decoration) { - return style[decoration.replace('-', '')]; - }).join(' '); - }, - - /** - * Returns filter for svg shadow - * @return {String} - */ - getSvgFilter: function() { - return this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : ''; - }, - - /** - * Returns id attribute for svg output - * @return {String} - */ - getSvgCommons: function() { - return [ - this.id ? 'id="' + this.id + '" ' : '', - this.clipPath ? 'clip-path="url(#' + this.clipPath.clipPathId + ')" ' : '', - ].join(''); - }, - - /** - * Returns transform-string for svg-export - * @param {Boolean} use the full transform or the single object one. - * @return {String} - */ - getSvgTransform: function(full, additionalTransform) { - var transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(), - svgTransform = 'transform="' + fabric.util.matrixToSVG(transform); - return svgTransform + - (additionalTransform || '') + '" '; - }, - - _setSVGBg: function(textBgRects) { - if (this.backgroundColor) { - var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - textBgRects.push( - '\t\t\n'); - } - }, - - /** - * Returns svg representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toSVG: function(reviver) { - return this._createBaseSVGMarkup(this._toSVG(reviver), { reviver: reviver }); - }, - - /** - * Returns svg clipPath representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toClipPathSVG: function(reviver) { - return '\t' + this._createBaseClipPathSVGMarkup(this._toSVG(reviver), { reviver: reviver }); - }, - - /** - * @private - */ - _createBaseClipPathSVGMarkup: function(objectMarkup, options) { - options = options || {}; - var reviver = options.reviver, - additionalTransform = options.additionalTransform || '', - commonPieces = [ - this.getSvgTransform(true, additionalTransform), - this.getSvgCommons(), - ].join(''), - // insert commons in the markup, style and svgCommons - index = objectMarkup.indexOf('COMMON_PARTS'); - objectMarkup[index] = commonPieces; - return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join(''); - }, - - /** - * @private - */ - _createBaseSVGMarkup: function(objectMarkup, options) { - options = options || {}; - var noStyle = options.noStyle, - reviver = options.reviver, - styleInfo = noStyle ? '' : 'style="' + this.getSvgStyles() + '" ', - shadowInfo = options.withShadow ? 'style="' + this.getSvgFilter() + '" ' : '', - clipPath = this.clipPath, - vectorEffect = this.strokeUniform ? 'vector-effect="non-scaling-stroke" ' : '', - absoluteClipPath = clipPath && clipPath.absolutePositioned, - stroke = this.stroke, fill = this.fill, shadow = this.shadow, - commonPieces, markup = [], clipPathMarkup, - // insert commons in the markup, style and svgCommons - index = objectMarkup.indexOf('COMMON_PARTS'), - additionalTransform = options.additionalTransform; - if (clipPath) { - clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++; - clipPathMarkup = '\n' + - clipPath.toClipPathSVG(reviver) + - '\n'; - } - if (absoluteClipPath) { - markup.push( - '\n' - ); - } - markup.push( - '\n' - ); - commonPieces = [ - styleInfo, - vectorEffect, - noStyle ? '' : this.addPaintOrder(), ' ', - additionalTransform ? 'transform="' + additionalTransform + '" ' : '', - ].join(''); - objectMarkup[index] = commonPieces; - if (fill && fill.toLive) { - markup.push(fill.toSVG(this)); - } - if (stroke && stroke.toLive) { - markup.push(stroke.toSVG(this)); - } - if (shadow) { - markup.push(shadow.toSVG(this)); - } - if (clipPath) { - markup.push(clipPathMarkup); - } - markup.push(objectMarkup.join('')); - markup.push('\n'); - absoluteClipPath && markup.push('\n'); - return reviver ? reviver(markup.join('')) : markup.join(''); - }, - - addPaintOrder: function() { - return this.paintFirst !== 'fill' ? ' paint-order="' + this.paintFirst + '" ' : ''; - } - }); -})(); -/* _TO_SVG_END_ */ - - -(function() { - - var extend = fabric.util.object.extend, - originalSet = 'stateProperties'; - - /* - Depends on `stateProperties` - */ - function saveProps(origin, destination, props) { - var tmpObj = { }, deep = true; - props.forEach(function(prop) { - tmpObj[prop] = origin[prop]; - }); - - extend(origin[destination], tmpObj, deep); - } - - function _isEqual(origValue, currentValue, firstPass) { - if (origValue === currentValue) { - // if the objects are identical, return - return true; - } - else if (Array.isArray(origValue)) { - if (!Array.isArray(currentValue) || origValue.length !== currentValue.length) { - return false; - } - for (var i = 0, len = origValue.length; i < len; i++) { - if (!_isEqual(origValue[i], currentValue[i])) { - return false; - } - } - return true; - } - else if (origValue && typeof origValue === 'object') { - var keys = Object.keys(origValue), key; - if (!currentValue || - typeof currentValue !== 'object' || - (!firstPass && keys.length !== Object.keys(currentValue).length) - ) { - return false; - } - for (var i = 0, len = keys.length; i < len; i++) { - key = keys[i]; - // since clipPath is in the statefull cache list and the clipPath objects - // would be iterated as an object, this would lead to possible infinite recursion - // we do not want to compare those. - if (key === 'canvas' || key === 'group') { - continue; - } - if (!_isEqual(origValue[key], currentValue[key])) { - return false; - } - } - return true; - } - } - - - fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - - /** - * Returns true if object state (one of its state properties) was changed - * @param {String} [propertySet] optional name for the set of property we want to save - * @return {Boolean} true if instance' state has changed since `{@link fabric.Object#saveState}` was called - */ - hasStateChanged: function(propertySet) { - propertySet = propertySet || originalSet; - var dashedPropertySet = '_' + propertySet; - if (Object.keys(this[dashedPropertySet]).length < this[propertySet].length) { - return true; - } - return !_isEqual(this[dashedPropertySet], this, true); - }, - - /** - * Saves state of an object - * @param {Object} [options] Object with additional `stateProperties` array to include when saving state - * @return {fabric.Object} thisArg - */ - saveState: function(options) { - var propertySet = options && options.propertySet || originalSet, - destination = '_' + propertySet; - if (!this[destination]) { - return this.setupState(options); - } - saveProps(this, destination, this[propertySet]); - if (options && options.stateProperties) { - saveProps(this, destination, options.stateProperties); - } - return this; - }, - - /** - * Setups state of an object - * @param {Object} [options] Object with additional `stateProperties` array to include when saving state - * @return {fabric.Object} thisArg - */ - setupState: function(options) { - options = options || { }; - var propertySet = options.propertySet || originalSet; - options.propertySet = propertySet; - this['_' + propertySet] = { }; - this.saveState(options); - return this; - } - }); -})(); - - -(function() { - - var degreesToRadians = fabric.util.degreesToRadians; - - fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - /** - * Determines which corner has been clicked - * @private - * @param {Object} pointer The pointer indicating the mouse position - * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or false if nothing is found - */ - _findTargetCorner: function(pointer, forTouch) { - // objects in group, anykind, are not self modificable, - // must not return an hovered corner. - if (!this.hasControls || this.group || (!this.canvas || this.canvas._activeObject !== this)) { - return false; - } - - var ex = pointer.x, - ey = pointer.y, - xPoints, - lines, keys = Object.keys(this.oCoords), - j = keys.length - 1, i; - this.__corner = 0; - - // cycle in reverse order so we pick first the one on top - for (; j >= 0; j--) { - i = keys[j]; - if (!this.isControlVisible(i)) { - continue; - } - - lines = this._getImageLines(forTouch ? this.oCoords[i].touchCorner : this.oCoords[i].corner); - // // debugging - // - // this.canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2); - - xPoints = this._findCrossPoints({ x: ex, y: ey }, lines); - if (xPoints !== 0 && xPoints % 2 === 1) { - this.__corner = i; - return i; - } - } - return false; - }, - - /** - * Calls a function for each control. The function gets called, - * with the control, the object that is calling the iterator and the control's key - * @param {Function} fn function to iterate over the controls over - */ - forEachControl: function(fn) { - for (var i in this.controls) { - fn(this.controls[i], i, this); - }; - }, - - /** - * Sets the coordinates of the draggable boxes in the corners of - * the image used to scale/rotate it. - * note: if we would switch to ROUND corner area, all of this would disappear. - * everything would resolve to a single point and a pythagorean theorem for the distance - * @private - */ - _setCornerCoords: function() { - var coords = this.oCoords; - - for (var control in coords) { - var controlObject = this.controls[control]; - coords[control].corner = controlObject.calcCornerCoords( - this.angle, this.cornerSize, coords[control].x, coords[control].y, false); - coords[control].touchCorner = controlObject.calcCornerCoords( - this.angle, this.touchCornerSize, coords[control].x, coords[control].y, true); - } - }, - - /** - * Draws a colored layer behind the object, inside its selection borders. - * Requires public options: padding, selectionBackgroundColor - * this function is called when the context is transformed - * has checks to be skipped when the object is on a staticCanvas - * @param {CanvasRenderingContext2D} ctx Context to draw on - * @return {fabric.Object} thisArg - * @chainable - */ - drawSelectionBackground: function(ctx) { - if (!this.selectionBackgroundColor || - (this.canvas && !this.canvas.interactive) || - (this.canvas && this.canvas._activeObject !== this) - ) { - return this; - } - ctx.save(); - var center = this.getCenterPoint(), wh = this._calculateCurrentDimensions(), - vpt = this.canvas.viewportTransform; - ctx.translate(center.x, center.y); - ctx.scale(1 / vpt[0], 1 / vpt[3]); - ctx.rotate(degreesToRadians(this.angle)); - ctx.fillStyle = this.selectionBackgroundColor; - ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y); - ctx.restore(); - return this; - }, - - /** - * Draws borders of an object's bounding box. - * Requires public properties: width, height - * Requires public options: padding, borderColor - * @param {CanvasRenderingContext2D} ctx Context to draw on - * @param {Object} styleOverride object to override the object style - * @return {fabric.Object} thisArg - * @chainable - */ - drawBorders: function(ctx, styleOverride) { - styleOverride = styleOverride || {}; - var wh = this._calculateCurrentDimensions(), - strokeWidth = this.borderScaleFactor, - width = wh.x + strokeWidth, - height = wh.y + strokeWidth, - hasControls = typeof styleOverride.hasControls !== 'undefined' ? - styleOverride.hasControls : this.hasControls, - shouldStroke = false; - - ctx.save(); - ctx.strokeStyle = styleOverride.borderColor || this.borderColor; - this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null); - - ctx.strokeRect( - -width / 2, - -height / 2, - width, - height - ); - - if (hasControls) { - ctx.beginPath(); - this.forEachControl(function(control, key, fabricObject) { - // in this moment, the ctx is centered on the object. - // width and height of the above function are the size of the bbox. - if (control.withConnection && control.getVisibility(fabricObject, key)) { - // reset movement for each control - shouldStroke = true; - ctx.moveTo(control.x * width, control.y * height); - ctx.lineTo( - control.x * width + control.offsetX, - control.y * height + control.offsetY - ); - } - }); - if (shouldStroke) { - ctx.stroke(); - } - } - ctx.restore(); - return this; - }, - - /** - * Draws borders of an object's bounding box when it is inside a group. - * Requires public properties: width, height - * Requires public options: padding, borderColor - * @param {CanvasRenderingContext2D} ctx Context to draw on - * @param {object} options object representing current object parameters - * @param {Object} styleOverride object to override the object style - * @return {fabric.Object} thisArg - * @chainable - */ - drawBordersInGroup: function(ctx, options, styleOverride) { - styleOverride = styleOverride || {}; - var bbox = fabric.util.sizeAfterTransform(this.width, this.height, options), - strokeWidth = this.strokeWidth, - strokeUniform = this.strokeUniform, - borderScaleFactor = this.borderScaleFactor, - width = - bbox.x + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleX) + borderScaleFactor, - height = - bbox.y + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleY) + borderScaleFactor; - ctx.save(); - this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null); - ctx.strokeStyle = styleOverride.borderColor || this.borderColor; - ctx.strokeRect( - -width / 2, - -height / 2, - width, - height - ); - - ctx.restore(); - return this; - }, - - /** - * Draws corners of an object's bounding box. - * Requires public properties: width, height - * Requires public options: cornerSize, padding - * @param {CanvasRenderingContext2D} ctx Context to draw on - * @param {Object} styleOverride object to override the object style - * @return {fabric.Object} thisArg - * @chainable - */ - drawControls: function(ctx, styleOverride) { - styleOverride = styleOverride || {}; - ctx.save(); - ctx.setTransform(this.canvas.getRetinaScaling(), 0, 0, this.canvas.getRetinaScaling(), 0, 0); - ctx.strokeStyle = ctx.fillStyle = styleOverride.cornerColor || this.cornerColor; - if (!this.transparentCorners) { - ctx.strokeStyle = styleOverride.cornerStrokeColor || this.cornerStrokeColor; - } - this._setLineDash(ctx, styleOverride.cornerDashArray || this.cornerDashArray, null); - this.setCoords(); - this.forEachControl(function(control, key, fabricObject) { - if (control.getVisibility(fabricObject, key)) { - control.render(ctx, - fabricObject.oCoords[key].x, - fabricObject.oCoords[key].y, styleOverride, fabricObject); - } - }); - ctx.restore(); - - return this; - }, - - /** - * Returns true if the specified control is visible, false otherwise. - * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'. - * @returns {Boolean} true if the specified control is visible, false otherwise - */ - isControlVisible: function(controlKey) { - return this.controls[controlKey] && this.controls[controlKey].getVisibility(this, controlKey); - }, - - /** - * Sets the visibility of the specified control. - * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'. - * @param {Boolean} visible true to set the specified control visible, false otherwise - * @return {fabric.Object} thisArg - * @chainable - */ - setControlVisible: function(controlKey, visible) { - if (!this._controlsVisibility) { - this._controlsVisibility = {}; - } - this._controlsVisibility[controlKey] = visible; - return this; - }, - - /** - * Sets the visibility state of object controls. - * @param {Object} [options] Options object - * @param {Boolean} [options.bl] true to enable the bottom-left control, false to disable it - * @param {Boolean} [options.br] true to enable the bottom-right control, false to disable it - * @param {Boolean} [options.mb] true to enable the middle-bottom control, false to disable it - * @param {Boolean} [options.ml] true to enable the middle-left control, false to disable it - * @param {Boolean} [options.mr] true to enable the middle-right control, false to disable it - * @param {Boolean} [options.mt] true to enable the middle-top control, false to disable it - * @param {Boolean} [options.tl] true to enable the top-left control, false to disable it - * @param {Boolean} [options.tr] true to enable the top-right control, false to disable it - * @param {Boolean} [options.mtr] true to enable the middle-top-rotate control, false to disable it - * @return {fabric.Object} thisArg - * @chainable - */ - setControlsVisibility: function(options) { - options || (options = { }); - - for (var p in options) { - this.setControlVisible(p, options[p]); - } - return this; - }, - - - /** - * This callback function is called every time _discardActiveObject or _setActiveObject - * try to to deselect this object. If the function returns true, the process is cancelled - * @param {Object} [options] options sent from the upper functions - * @param {Event} [options.e] event if the process is generated by an event - */ - onDeselect: function() { - // implemented by sub-classes, as needed. - }, - - - /** - * This callback function is called every time _discardActiveObject or _setActiveObject - * try to to select this object. If the function returns true, the process is cancelled - * @param {Object} [options] options sent from the upper functions - * @param {Event} [options.e] event if the process is generated by an event - */ - onSelect: function() { - // implemented by sub-classes, as needed. - } - }); -})(); - - -fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { - - /** - * Animation duration (in ms) for fx* methods - * @type Number - * @default - */ - FX_DURATION: 500, - - /** - * Centers object horizontally with animation. - * @param {fabric.Object} object Object to center - * @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties - * @param {Function} [callbacks.onComplete] Invoked on completion - * @param {Function} [callbacks.onChange] Invoked on every step of animation - * @return {fabric.Canvas} thisArg - * @chainable - */ - fxCenterObjectH: function (object, callbacks) { - callbacks = callbacks || { }; - - var empty = function() { }, - onComplete = callbacks.onComplete || empty, - onChange = callbacks.onChange || empty, - _this = this; - - fabric.util.animate({ - startValue: object.left, - endValue: this.getCenter().left, - duration: this.FX_DURATION, - onChange: function(value) { - object.set('left', value); - _this.requestRenderAll(); - onChange(); - }, - onComplete: function() { - object.setCoords(); - onComplete(); - } - }); - - return this; - }, - - /** - * Centers object vertically with animation. - * @param {fabric.Object} object Object to center - * @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties - * @param {Function} [callbacks.onComplete] Invoked on completion - * @param {Function} [callbacks.onChange] Invoked on every step of animation - * @return {fabric.Canvas} thisArg - * @chainable - */ - fxCenterObjectV: function (object, callbacks) { - callbacks = callbacks || { }; - - var empty = function() { }, - onComplete = callbacks.onComplete || empty, - onChange = callbacks.onChange || empty, - _this = this; - - fabric.util.animate({ - startValue: object.top, - endValue: this.getCenter().top, - duration: this.FX_DURATION, - onChange: function(value) { - object.set('top', value); - _this.requestRenderAll(); - onChange(); - }, - onComplete: function() { - object.setCoords(); - onComplete(); - } - }); - - return this; - }, - - /** - * Same as `fabric.Canvas#remove` but animated - * @param {fabric.Object} object Object to remove - * @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties - * @param {Function} [callbacks.onComplete] Invoked on completion - * @param {Function} [callbacks.onChange] Invoked on every step of animation - * @return {fabric.Canvas} thisArg - * @chainable - */ - fxRemove: function (object, callbacks) { - callbacks = callbacks || { }; - - var empty = function() { }, - onComplete = callbacks.onComplete || empty, - onChange = callbacks.onChange || empty, - _this = this; - - fabric.util.animate({ - startValue: object.opacity, - endValue: 0, - duration: this.FX_DURATION, - onChange: function(value) { - object.set('opacity', value); - _this.requestRenderAll(); - onChange(); - }, - onComplete: function () { - _this.remove(object); - onComplete(); - } - }); - - return this; - } -}); - -fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - /** - * Animates object's properties - * @param {String|Object} property Property to animate (if string) or properties to animate (if object) - * @param {Number|Object} value Value to animate property to (if string was given first) or options object - * @return {fabric.Object} thisArg - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation} - * @chainable - * - * As object — multiple properties - * - * object.animate({ left: ..., top: ... }); - * object.animate({ left: ..., top: ... }, { duration: ... }); - * - * As string — one property - * - * object.animate('left', ...); - * object.animate('left', { duration: ... }); - * - */ - animate: function() { - if (arguments[0] && typeof arguments[0] === 'object') { - var propsToAnimate = [], prop, skipCallbacks; - for (prop in arguments[0]) { - propsToAnimate.push(prop); - } - for (var i = 0, len = propsToAnimate.length; i < len; i++) { - prop = propsToAnimate[i]; - skipCallbacks = i !== len - 1; - this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks); - } - } - else { - this._animate.apply(this, arguments); - } - return this; - }, - - /** - * @private - * @param {String} property Property to animate - * @param {String} to Value to animate to - * @param {Object} [options] Options object - * @param {Boolean} [skipCallbacks] When true, callbacks like onchange and oncomplete are not invoked - */ - _animate: function(property, to, options, skipCallbacks) { - var _this = this, propPair; - - to = to.toString(); - - if (!options) { - options = { }; - } - else { - options = fabric.util.object.clone(options); - } - - if (~property.indexOf('.')) { - propPair = property.split('.'); - } - - var propIsColor = - _this.colorProperties.indexOf(property) > -1 || - (propPair && _this.colorProperties.indexOf(propPair[1]) > -1); - - var currentValue = propPair - ? this.get(propPair[0])[propPair[1]] - : this.get(property); - - if (!('from' in options)) { - options.from = currentValue; - } - - if (!propIsColor) { - if (~to.indexOf('=')) { - to = currentValue + parseFloat(to.replace('=', '')); - } - else { - to = parseFloat(to); - } - } - - var _options = { - startValue: options.from, - endValue: to, - byValue: options.by, - easing: options.easing, - duration: options.duration, - abort: options.abort && function () { - return options.abort.call(_this); - }, - onChange: function (value, valueProgress, timeProgress) { - if (propPair) { - _this[propPair[0]][propPair[1]] = value; - } - else { - _this.set(property, value); - } - if (skipCallbacks) { - return; - } - options.onChange && options.onChange(value, valueProgress, timeProgress); - }, - onComplete: function (value, valueProgress, timeProgress) { - if (skipCallbacks) { - return; - } - - _this.setCoords(); - options.onComplete && options.onComplete(value, valueProgress, timeProgress); - } - }; - - if (propIsColor) { - fabric.util.animateColor(_options.startValue, _options.endValue, _options.duration, _options); - } - else { - fabric.util.animate(_options); - } - } -}); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - clone = fabric.util.object.clone, - coordProps = { x1: 1, x2: 1, y1: 1, y2: 1 }, - supportsLineDash = fabric.StaticCanvas.supports('setLineDash'); - - if (fabric.Line) { - fabric.warn('fabric.Line is already defined'); - return; - } - - /** - * Line class - * @class fabric.Line - * @extends fabric.Object - * @see {@link fabric.Line#initialize} for constructor definition - */ - fabric.Line = fabric.util.createClass(fabric.Object, /** @lends fabric.Line.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'line', - - /** - * x value or first line edge - * @type Number - * @default - */ - x1: 0, - - /** - * y value or first line edge - * @type Number - * @default - */ - y1: 0, - - /** - * x value or second line edge - * @type Number - * @default - */ - x2: 0, - - /** - * y value or second line edge - * @type Number - * @default - */ - y2: 0, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('x1', 'x2', 'y1', 'y2'), - - /** - * Constructor - * @param {Array} [points] Array of points - * @param {Object} [options] Options object - * @return {fabric.Line} thisArg - */ - initialize: function(points, options) { - if (!points) { - points = [0, 0, 0, 0]; - } - - this.callSuper('initialize', options); - - this.set('x1', points[0]); - this.set('y1', points[1]); - this.set('x2', points[2]); - this.set('y2', points[3]); - - this._setWidthHeight(options); - }, - - /** - * @private - * @param {Object} [options] Options - */ - _setWidthHeight: function(options) { - options || (options = { }); - - this.width = Math.abs(this.x2 - this.x1); - this.height = Math.abs(this.y2 - this.y1); - - this.left = 'left' in options - ? options.left - : this._getLeftToOriginX(); - - this.top = 'top' in options - ? options.top - : this._getTopToOriginY(); - }, - - /** - * @private - * @param {String} key - * @param {*} value - */ - _set: function(key, value) { - this.callSuper('_set', key, value); - if (typeof coordProps[key] !== 'undefined') { - this._setWidthHeight(); - } - return this; - }, - - /** - * @private - * @return {Number} leftToOriginX Distance from left edge of canvas to originX of Line. - */ - _getLeftToOriginX: makeEdgeToOriginGetter( - { // property names - origin: 'originX', - axis1: 'x1', - axis2: 'x2', - dimension: 'width' - }, - { // possible values of origin - nearest: 'left', - center: 'center', - farthest: 'right' - } - ), - - /** - * @private - * @return {Number} topToOriginY Distance from top edge of canvas to originY of Line. - */ - _getTopToOriginY: makeEdgeToOriginGetter( - { // property names - origin: 'originY', - axis1: 'y1', - axis2: 'y2', - dimension: 'height' - }, - { // possible values of origin - nearest: 'top', - center: 'center', - farthest: 'bottom' - } - ), - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - ctx.beginPath(); - - if (!this.strokeDashArray || this.strokeDashArray && supportsLineDash) { - // move from center (of virtual box) to its left/top corner - // we can't assume x1, y1 is top left and x2, y2 is bottom right - var p = this.calcLinePoints(); - ctx.moveTo(p.x1, p.y1); - ctx.lineTo(p.x2, p.y2); - } - - ctx.lineWidth = this.strokeWidth; - - // TODO: test this - // make sure setting "fill" changes color of a line - // (by copying fillStyle to strokeStyle, since line is stroked, not filled) - var origStrokeStyle = ctx.strokeStyle; - ctx.strokeStyle = this.stroke || ctx.fillStyle; - this.stroke && this._renderStroke(ctx); - ctx.strokeStyle = origStrokeStyle; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderDashedStroke: function(ctx) { - var p = this.calcLinePoints(); - - ctx.beginPath(); - fabric.util.drawDashedLine(ctx, p.x1, p.y1, p.x2, p.y2, this.strokeDashArray); - ctx.closePath(); - }, - - /** - * This function is an helper for svg import. it returns the center of the object in the svg - * untransformed coordinates - * @private - * @return {Object} center point from element coordinates - */ - _findCenterFromElement: function() { - return { - x: (this.x1 + this.x2) / 2, - y: (this.y1 + this.y2) / 2, - }; - }, - - /** - * Returns object representation of an instance - * @method toObject - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return extend(this.callSuper('toObject', propertiesToInclude), this.calcLinePoints()); - }, - - /* - * Calculate object dimensions from its properties - * @private - */ - _getNonTransformedDimensions: function() { - var dim = this.callSuper('_getNonTransformedDimensions'); - if (this.strokeLineCap === 'butt') { - if (this.width === 0) { - dim.y -= this.strokeWidth; - } - if (this.height === 0) { - dim.x -= this.strokeWidth; - } - } - return dim; - }, - - /** - * Recalculates line points given width and height - * @private - */ - calcLinePoints: function() { - var xMult = this.x1 <= this.x2 ? -1 : 1, - yMult = this.y1 <= this.y2 ? -1 : 1, - x1 = (xMult * this.width * 0.5), - y1 = (yMult * this.height * 0.5), - x2 = (xMult * this.width * -0.5), - y2 = (yMult * this.height * -0.5); - - return { - x1: x1, - x2: x2, - y1: y1, - y2: y2 - }; - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var p = this.calcLinePoints(); - return [ - '\n' - ]; - }, - /* _TO_SVG_END_ */ - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Line.fromElement}) - * @static - * @memberOf fabric.Line - * @see http://www.w3.org/TR/SVG/shapes.html#LineElement - */ - fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x1 y1 x2 y2'.split(' ')); - - /** - * Returns fabric.Line instance from an SVG element - * @static - * @memberOf fabric.Line - * @param {SVGElement} element Element to parse - * @param {Object} [options] Options object - * @param {Function} [callback] callback function invoked after parsing - */ - fabric.Line.fromElement = function(element, callback, options) { - options = options || { }; - var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES), - points = [ - parsedAttributes.x1 || 0, - parsedAttributes.y1 || 0, - parsedAttributes.x2 || 0, - parsedAttributes.y2 || 0 - ]; - callback(new fabric.Line(points, extend(parsedAttributes, options))); - }; - /* _FROM_SVG_END_ */ - - /** - * Returns fabric.Line instance from an object representation - * @static - * @memberOf fabric.Line - * @param {Object} object Object to create an instance from - * @param {function} [callback] invoked with new instance as first argument - */ - fabric.Line.fromObject = function(object, callback) { - function _callback(instance) { - delete instance.points; - callback && callback(instance); - }; - var options = clone(object, true); - options.points = [object.x1, object.y1, object.x2, object.y2]; - fabric.Object._fromObject('Line', options, _callback, 'points'); - }; - - /** - * Produces a function that calculates distance from canvas edge to Line origin. - */ - function makeEdgeToOriginGetter(propertyNames, originValues) { - var origin = propertyNames.origin, - axis1 = propertyNames.axis1, - axis2 = propertyNames.axis2, - dimension = propertyNames.dimension, - nearest = originValues.nearest, - center = originValues.center, - farthest = originValues.farthest; - - return function() { - switch (this.get(origin)) { - case nearest: - return Math.min(this.get(axis1), this.get(axis2)); - case center: - return Math.min(this.get(axis1), this.get(axis2)) + (0.5 * this.get(dimension)); - case farthest: - return Math.max(this.get(axis1), this.get(axis2)); - } - }; - - } - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - pi = Math.PI; - - if (fabric.Circle) { - fabric.warn('fabric.Circle is already defined.'); - return; - } - - /** - * Circle class - * @class fabric.Circle - * @extends fabric.Object - * @see {@link fabric.Circle#initialize} for constructor definition - */ - fabric.Circle = fabric.util.createClass(fabric.Object, /** @lends fabric.Circle.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'circle', - - /** - * Radius of this circle - * @type Number - * @default - */ - radius: 0, - - /** - * Start angle of the circle, moving clockwise - * deprecated type, this should be in degree, this was an oversight. - * probably will change to degrees in next major version - * @type Number - * @default 0 - */ - startAngle: 0, - - /** - * End angle of the circle - * deprecated type, this should be in degree, this was an oversight. - * probably will change to degrees in next major version - * @type Number - * @default 2Pi - */ - endAngle: pi * 2, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('radius', 'startAngle', 'endAngle'), - - /** - * @private - * @param {String} key - * @param {*} value - * @return {fabric.Circle} thisArg - */ - _set: function(key, value) { - this.callSuper('_set', key, value); - - if (key === 'radius') { - this.setRadius(value); - } - - return this; - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return this.callSuper('toObject', ['radius', 'startAngle', 'endAngle'].concat(propertiesToInclude)); - }, - - /* _TO_SVG_START_ */ - - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var svgString, x = 0, y = 0, - angle = (this.endAngle - this.startAngle) % ( 2 * pi); - - if (angle === 0) { - svgString = [ - '\n' - ]; - } - else { - var startX = fabric.util.cos(this.startAngle) * this.radius, - startY = fabric.util.sin(this.startAngle) * this.radius, - endX = fabric.util.cos(this.endAngle) * this.radius, - endY = fabric.util.sin(this.endAngle) * this.radius, - largeFlag = angle > pi ? '1' : '0'; - svgString = [ - '\n' - ]; - } - return svgString; - }, - /* _TO_SVG_END_ */ - - /** - * @private - * @param {CanvasRenderingContext2D} ctx context to render on - */ - _render: function(ctx) { - ctx.beginPath(); - ctx.arc( - 0, - 0, - this.radius, - this.startAngle, - this.endAngle, false); - this._renderPaintInOrder(ctx); - }, - - /** - * Returns horizontal radius of an object (according to how an object is scaled) - * @return {Number} - */ - getRadiusX: function() { - return this.get('radius') * this.get('scaleX'); - }, - - /** - * Returns vertical radius of an object (according to how an object is scaled) - * @return {Number} - */ - getRadiusY: function() { - return this.get('radius') * this.get('scaleY'); - }, - - /** - * Sets radius of an object (and updates width accordingly) - * @return {fabric.Circle} thisArg - */ - setRadius: function(value) { - this.radius = value; - return this.set('width', value * 2).set('height', value * 2); - }, - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement}) - * @static - * @memberOf fabric.Circle - * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement - */ - fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy r'.split(' ')); - - /** - * Returns {@link fabric.Circle} instance from an SVG element - * @static - * @memberOf fabric.Circle - * @param {SVGElement} element Element to parse - * @param {Function} [callback] Options callback invoked after parsing is finished - * @param {Object} [options] Options object - * @throws {Error} If value of `r` attribute is missing or invalid - */ - fabric.Circle.fromElement = function(element, callback) { - var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES); - - if (!isValidRadius(parsedAttributes)) { - throw new Error('value of `r` attribute is required and can not be negative'); - } - - parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.radius; - parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.radius; - callback(new fabric.Circle(parsedAttributes)); - }; - - /** - * @private - */ - function isValidRadius(attributes) { - return (('radius' in attributes) && (attributes.radius >= 0)); - } - /* _FROM_SVG_END_ */ - - /** - * Returns {@link fabric.Circle} instance from an object representation - * @static - * @memberOf fabric.Circle - * @param {Object} object Object to create an instance from - * @param {function} [callback] invoked with new instance as first argument - * @return {Object} Instance of fabric.Circle - */ - fabric.Circle.fromObject = function(object, callback) { - return fabric.Object._fromObject('Circle', object, callback); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }); - - if (fabric.Triangle) { - fabric.warn('fabric.Triangle is already defined'); - return; - } - - /** - * Triangle class - * @class fabric.Triangle - * @extends fabric.Object - * @return {fabric.Triangle} thisArg - * @see {@link fabric.Triangle#initialize} for constructor definition - */ - fabric.Triangle = fabric.util.createClass(fabric.Object, /** @lends fabric.Triangle.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'triangle', - - /** - * Width is set to 100 to compensate the old initialize code that was setting it to 100 - * @type Number - * @default - */ - width: 100, - - /** - * Height is set to 100 to compensate the old initialize code that was setting it to 100 - * @type Number - * @default - */ - height: 100, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - var widthBy2 = this.width / 2, - heightBy2 = this.height / 2; - - ctx.beginPath(); - ctx.moveTo(-widthBy2, heightBy2); - ctx.lineTo(0, -heightBy2); - ctx.lineTo(widthBy2, heightBy2); - ctx.closePath(); - - this._renderPaintInOrder(ctx); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderDashedStroke: function(ctx) { - var widthBy2 = this.width / 2, - heightBy2 = this.height / 2; - - ctx.beginPath(); - fabric.util.drawDashedLine(ctx, -widthBy2, heightBy2, 0, -heightBy2, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, 0, -heightBy2, widthBy2, heightBy2, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, widthBy2, heightBy2, -widthBy2, heightBy2, this.strokeDashArray); - ctx.closePath(); - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var widthBy2 = this.width / 2, - heightBy2 = this.height / 2, - points = [ - -widthBy2 + ' ' + heightBy2, - '0 ' + -heightBy2, - widthBy2 + ' ' + heightBy2 - ].join(','); - return [ - '' - ]; - }, - /* _TO_SVG_END_ */ - }); - - /** - * Returns {@link fabric.Triangle} instance from an object representation - * @static - * @memberOf fabric.Triangle - * @param {Object} object Object to create an instance from - * @param {function} [callback] invoked with new instance as first argument - */ - fabric.Triangle.fromObject = function(object, callback) { - return fabric.Object._fromObject('Triangle', object, callback); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - piBy2 = Math.PI * 2; - - if (fabric.Ellipse) { - fabric.warn('fabric.Ellipse is already defined.'); - return; - } - - /** - * Ellipse class - * @class fabric.Ellipse - * @extends fabric.Object - * @return {fabric.Ellipse} thisArg - * @see {@link fabric.Ellipse#initialize} for constructor definition - */ - fabric.Ellipse = fabric.util.createClass(fabric.Object, /** @lends fabric.Ellipse.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'ellipse', - - /** - * Horizontal radius - * @type Number - * @default - */ - rx: 0, - - /** - * Vertical radius - * @type Number - * @default - */ - ry: 0, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'), - - /** - * Constructor - * @param {Object} [options] Options object - * @return {fabric.Ellipse} thisArg - */ - initialize: function(options) { - this.callSuper('initialize', options); - this.set('rx', options && options.rx || 0); - this.set('ry', options && options.ry || 0); - }, - - /** - * @private - * @param {String} key - * @param {*} value - * @return {fabric.Ellipse} thisArg - */ - _set: function(key, value) { - this.callSuper('_set', key, value); - switch (key) { - - case 'rx': - this.rx = value; - this.set('width', value * 2); - break; - - case 'ry': - this.ry = value; - this.set('height', value * 2); - break; - - } - return this; - }, - - /** - * Returns horizontal radius of an object (according to how an object is scaled) - * @return {Number} - */ - getRx: function() { - return this.get('rx') * this.get('scaleX'); - }, - - /** - * Returns Vertical radius of an object (according to how an object is scaled) - * @return {Number} - */ - getRy: function() { - return this.get('ry') * this.get('scaleY'); - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude)); - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - return [ - '\n' - ]; - }, - /* _TO_SVG_END_ */ - - /** - * @private - * @param {CanvasRenderingContext2D} ctx context to render on - */ - _render: function(ctx) { - ctx.beginPath(); - ctx.save(); - ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0); - ctx.arc( - 0, - 0, - this.rx, - 0, - piBy2, - false); - ctx.restore(); - this._renderPaintInOrder(ctx); - }, - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Ellipse.fromElement}) - * @static - * @memberOf fabric.Ellipse - * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement - */ - fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy rx ry'.split(' ')); - - /** - * Returns {@link fabric.Ellipse} instance from an SVG element - * @static - * @memberOf fabric.Ellipse - * @param {SVGElement} element Element to parse - * @param {Function} [callback] Options callback invoked after parsing is finished - * @return {fabric.Ellipse} - */ - fabric.Ellipse.fromElement = function(element, callback) { - - var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES); - - parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx; - parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry; - callback(new fabric.Ellipse(parsedAttributes)); - }; - /* _FROM_SVG_END_ */ - - /** - * Returns {@link fabric.Ellipse} instance from an object representation - * @static - * @memberOf fabric.Ellipse - * @param {Object} object Object to create an instance from - * @param {function} [callback] invoked with new instance as first argument - * @return {fabric.Ellipse} - */ - fabric.Ellipse.fromObject = function(object, callback) { - return fabric.Object._fromObject('Ellipse', object, callback); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend; - - if (fabric.Rect) { - fabric.warn('fabric.Rect is already defined'); - return; - } - - /** - * Rectangle class - * @class fabric.Rect - * @extends fabric.Object - * @return {fabric.Rect} thisArg - * @see {@link fabric.Rect#initialize} for constructor definition - */ - fabric.Rect = fabric.util.createClass(fabric.Object, /** @lends fabric.Rect.prototype */ { - - /** - * List of properties to consider when checking if state of an object is changed ({@link fabric.Object#hasStateChanged}) - * as well as for history (undo/redo) purposes - * @type Array - */ - stateProperties: fabric.Object.prototype.stateProperties.concat('rx', 'ry'), - - /** - * Type of an object - * @type String - * @default - */ - type: 'rect', - - /** - * Horizontal border radius - * @type Number - * @default - */ - rx: 0, - - /** - * Vertical border radius - * @type Number - * @default - */ - ry: 0, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'), - - /** - * Constructor - * @param {Object} [options] Options object - * @return {Object} thisArg - */ - initialize: function(options) { - this.callSuper('initialize', options); - this._initRxRy(); - }, - - /** - * Initializes rx/ry attributes - * @private - */ - _initRxRy: function() { - if (this.rx && !this.ry) { - this.ry = this.rx; - } - else if (this.ry && !this.rx) { - this.rx = this.ry; - } - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - - // 1x1 case (used in spray brush) optimization was removed because - // with caching and higher zoom level this makes more damage than help - - var rx = this.rx ? Math.min(this.rx, this.width / 2) : 0, - ry = this.ry ? Math.min(this.ry, this.height / 2) : 0, - w = this.width, - h = this.height, - x = -this.width / 2, - y = -this.height / 2, - isRounded = rx !== 0 || ry !== 0, - /* "magic number" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */ - k = 1 - 0.5522847498; - ctx.beginPath(); - - ctx.moveTo(x + rx, y); - - ctx.lineTo(x + w - rx, y); - isRounded && ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry); - - ctx.lineTo(x + w, y + h - ry); - isRounded && ctx.bezierCurveTo(x + w, y + h - k * ry, x + w - k * rx, y + h, x + w - rx, y + h); - - ctx.lineTo(x + rx, y + h); - isRounded && ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry); - - ctx.lineTo(x, y + ry); - isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y); - - ctx.closePath(); - - this._renderPaintInOrder(ctx); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderDashedStroke: function(ctx) { - var x = -this.width / 2, - y = -this.height / 2, - w = this.width, - h = this.height; - - ctx.beginPath(); - fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray); - ctx.closePath(); - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude)); - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var x = -this.width / 2, y = -this.height / 2; - return [ - '\n' - ]; - }, - /* _TO_SVG_END_ */ - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by `fabric.Rect.fromElement`) - * @static - * @memberOf fabric.Rect - * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement - */ - fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y rx ry width height'.split(' ')); - - /** - * Returns {@link fabric.Rect} instance from an SVG element - * @static - * @memberOf fabric.Rect - * @param {SVGElement} element Element to parse - * @param {Function} callback callback function invoked after parsing - * @param {Object} [options] Options object - */ - fabric.Rect.fromElement = function(element, callback, options) { - if (!element) { - return callback(null); - } - options = options || { }; - - var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES); - parsedAttributes.left = parsedAttributes.left || 0; - parsedAttributes.top = parsedAttributes.top || 0; - parsedAttributes.height = parsedAttributes.height || 0; - parsedAttributes.width = parsedAttributes.width || 0; - var rect = new fabric.Rect(extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes)); - rect.visible = rect.visible && rect.width > 0 && rect.height > 0; - callback(rect); - }; - /* _FROM_SVG_END_ */ - - /** - * Returns {@link fabric.Rect} instance from an object representation - * @static - * @memberOf fabric.Rect - * @param {Object} object Object to create an instance from - * @param {Function} [callback] Callback to invoke when an fabric.Rect instance is created - */ - fabric.Rect.fromObject = function(object, callback) { - return fabric.Object._fromObject('Rect', object, callback); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - min = fabric.util.array.min, - max = fabric.util.array.max, - toFixed = fabric.util.toFixed; - - if (fabric.Polyline) { - fabric.warn('fabric.Polyline is already defined'); - return; - } - - /** - * Polyline class - * @class fabric.Polyline - * @extends fabric.Object - * @see {@link fabric.Polyline#initialize} for constructor definition - */ - fabric.Polyline = fabric.util.createClass(fabric.Object, /** @lends fabric.Polyline.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'polyline', - - /** - * Points array - * @type Array - * @default - */ - points: null, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('points'), - - /** - * Constructor - * @param {Array} points Array of points (where each point is an object with x and y) - * @param {Object} [options] Options object - * @return {fabric.Polyline} thisArg - * @example - * var poly = new fabric.Polyline([ - * { x: 10, y: 10 }, - * { x: 50, y: 30 }, - * { x: 40, y: 70 }, - * { x: 60, y: 50 }, - * { x: 100, y: 150 }, - * { x: 40, y: 100 } - * ], { - * stroke: 'red', - * left: 100, - * top: 100 - * }); - */ - initialize: function(points, options) { - options = options || {}; - this.points = points || []; - this.callSuper('initialize', options); - this._setPositionDimensions(options); - }, - - _setPositionDimensions: function(options) { - var calcDim = this._calcDimensions(options), correctLeftTop; - this.width = calcDim.width; - this.height = calcDim.height; - if (!options.fromSVG) { - correctLeftTop = this.translateToGivenOrigin( - { x: calcDim.left - this.strokeWidth / 2, y: calcDim.top - this.strokeWidth / 2 }, - 'left', - 'top', - this.originX, - this.originY - ); - } - if (typeof options.left === 'undefined') { - this.left = options.fromSVG ? calcDim.left : correctLeftTop.x; - } - if (typeof options.top === 'undefined') { - this.top = options.fromSVG ? calcDim.top : correctLeftTop.y; - } - this.pathOffset = { - x: calcDim.left + this.width / 2, - y: calcDim.top + this.height / 2 - }; - }, - - /** - * Calculate the polygon min and max point from points array, - * returning an object with left, top, width, height to measure the - * polygon size - * @return {Object} object.left X coordinate of the polygon leftmost point - * @return {Object} object.top Y coordinate of the polygon topmost point - * @return {Object} object.width distance between X coordinates of the polygon leftmost and rightmost point - * @return {Object} object.height distance between Y coordinates of the polygon topmost and bottommost point - * @private - */ - _calcDimensions: function() { - - var points = this.points, - minX = min(points, 'x') || 0, - minY = min(points, 'y') || 0, - maxX = max(points, 'x') || 0, - maxY = max(points, 'y') || 0, - width = (maxX - minX), - height = (maxY - minY); - - return { - left: minX, - top: minY, - width: width, - height: height - }; - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of an instance - */ - toObject: function(propertiesToInclude) { - return extend(this.callSuper('toObject', propertiesToInclude), { - points: this.points.concat() - }); - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var points = [], diffX = this.pathOffset.x, diffY = this.pathOffset.y, - NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - - for (var i = 0, len = this.points.length; i < len; i++) { - points.push( - toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS), ',', - toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), ' ' - ); - } - return [ - '<' + this.type + ' ', 'COMMON_PARTS', - 'points="', points.join(''), - '" />\n' - ]; - }, - /* _TO_SVG_END_ */ - - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - commonRender: function(ctx) { - var point, len = this.points.length, - x = this.pathOffset.x, - y = this.pathOffset.y; - - if (!len || isNaN(this.points[len - 1].y)) { - // do not draw if no points or odd points - // NaN comes from parseFloat of a empty string in parser - return false; - } - ctx.beginPath(); - ctx.moveTo(this.points[0].x - x, this.points[0].y - y); - for (var i = 0; i < len; i++) { - point = this.points[i]; - ctx.lineTo(point.x - x, point.y - y); - } - return true; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - if (!this.commonRender(ctx)) { - return; - } - this._renderPaintInOrder(ctx); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderDashedStroke: function(ctx) { - var p1, p2; - - ctx.beginPath(); - for (var i = 0, len = this.points.length; i < len; i++) { - p1 = this.points[i]; - p2 = this.points[i + 1] || p1; - fabric.util.drawDashedLine(ctx, p1.x, p1.y, p2.x, p2.y, this.strokeDashArray); - } - }, - - /** - * Returns complexity of an instance - * @return {Number} complexity of this instance - */ - complexity: function() { - return this.get('points').length; - } - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Polyline.fromElement}) - * @static - * @memberOf fabric.Polyline - * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement - */ - fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(); - - /** - * Returns fabric.Polyline instance from an SVG element - * @static - * @memberOf fabric.Polyline - * @param {SVGElement} element Element to parser - * @param {Function} callback callback function invoked after parsing - * @param {Object} [options] Options object - */ - fabric.Polyline.fromElementGenerator = function(_class) { - return function(element, callback, options) { - if (!element) { - return callback(null); - } - options || (options = { }); - - var points = fabric.parsePointsAttribute(element.getAttribute('points')), - parsedAttributes = fabric.parseAttributes(element, fabric[_class].ATTRIBUTE_NAMES); - parsedAttributes.fromSVG = true; - callback(new fabric[_class](points, extend(parsedAttributes, options))); - }; - }; - - fabric.Polyline.fromElement = fabric.Polyline.fromElementGenerator('Polyline'); - - /* _FROM_SVG_END_ */ - - /** - * Returns fabric.Polyline instance from an object representation - * @static - * @memberOf fabric.Polyline - * @param {Object} object Object to create an instance from - * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created - */ - fabric.Polyline.fromObject = function(object, callback) { - return fabric.Object._fromObject('Polyline', object, callback, 'points'); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }); - - if (fabric.Polygon) { - fabric.warn('fabric.Polygon is already defined'); - return; - } - - /** - * Polygon class - * @class fabric.Polygon - * @extends fabric.Polyline - * @see {@link fabric.Polygon#initialize} for constructor definition - */ - fabric.Polygon = fabric.util.createClass(fabric.Polyline, /** @lends fabric.Polygon.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'polygon', - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - if (!this.commonRender(ctx)) { - return; - } - ctx.closePath(); - this._renderPaintInOrder(ctx); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderDashedStroke: function(ctx) { - this.callSuper('_renderDashedStroke', ctx); - ctx.closePath(); - }, - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by `fabric.Polygon.fromElement`) - * @static - * @memberOf fabric.Polygon - * @see: http://www.w3.org/TR/SVG/shapes.html#PolygonElement - */ - fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(); - - /** - * Returns {@link fabric.Polygon} instance from an SVG element - * @static - * @memberOf fabric.Polygon - * @param {SVGElement} element Element to parse - * @param {Function} callback callback function invoked after parsing - * @param {Object} [options] Options object - */ - fabric.Polygon.fromElement = fabric.Polyline.fromElementGenerator('Polygon'); - /* _FROM_SVG_END_ */ - - /** - * Returns fabric.Polygon instance from an object representation - * @static - * @memberOf fabric.Polygon - * @param {Object} object Object to create an instance from - * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created - */ - fabric.Polygon.fromObject = function(object, callback) { - return fabric.Object._fromObject('Polygon', object, callback, 'points'); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - min = fabric.util.array.min, - max = fabric.util.array.max, - extend = fabric.util.object.extend, - _toString = Object.prototype.toString, - toFixed = fabric.util.toFixed; - - if (fabric.Path) { - fabric.warn('fabric.Path is already defined'); - return; - } - - /** - * Path class - * @class fabric.Path - * @extends fabric.Object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup} - * @see {@link fabric.Path#initialize} for constructor definition - */ - fabric.Path = fabric.util.createClass(fabric.Object, /** @lends fabric.Path.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'path', - - /** - * Array of path points - * @type Array - * @default - */ - path: null, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('path', 'fillRule'), - - stateProperties: fabric.Object.prototype.stateProperties.concat('path'), - - /** - * Constructor - * @param {Array|String} path Path data (sequence of coordinates and corresponding "command" tokens) - * @param {Object} [options] Options object - * @return {fabric.Path} thisArg - */ - initialize: function(path, options) { - options = options || { }; - this.callSuper('initialize', options); - if (!path) { - path = []; - } - - var fromArray = _toString.call(path) === '[object Array]'; - - this.path = fromArray - ? fabric.util.makePathSimpler(path) - - : fabric.util.makePathSimpler( - fabric.util.parsePath(path) - ); - - if (!this.path) { - return; - } - fabric.Polyline.prototype._setPositionDimensions.call(this, options); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx context to render path on - */ - _renderPathCommands: function(ctx) { - var current, // current instruction - subpathStartX = 0, - subpathStartY = 0, - x = 0, // current x - y = 0, // current y - controlX = 0, // current control point x - controlY = 0, // current control point y - l = -this.pathOffset.x, - t = -this.pathOffset.y; - - ctx.beginPath(); - - for (var i = 0, len = this.path.length; i < len; ++i) { - - current = this.path[i]; - - switch (current[0]) { // first letter - - case 'L': // lineto, absolute - x = current[1]; - y = current[2]; - ctx.lineTo(x + l, y + t); - break; - - case 'M': // moveTo, absolute - x = current[1]; - y = current[2]; - subpathStartX = x; - subpathStartY = y; - ctx.moveTo(x + l, y + t); - break; - - case 'C': // bezierCurveTo, absolute - x = current[5]; - y = current[6]; - controlX = current[3]; - controlY = current[4]; - ctx.bezierCurveTo( - current[1] + l, - current[2] + t, - controlX + l, - controlY + t, - x + l, - y + t - ); - break; - - case 'Q': // quadraticCurveTo, absolute - ctx.quadraticCurveTo( - current[1] + l, - current[2] + t, - current[3] + l, - current[4] + t - ); - x = current[3]; - y = current[4]; - controlX = current[1]; - controlY = current[2]; - break; - - case 'z': - case 'Z': - x = subpathStartX; - y = subpathStartY; - ctx.closePath(); - break; - } - } - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx context to render path on - */ - _render: function(ctx) { - this._renderPathCommands(ctx); - this._renderPaintInOrder(ctx); - }, - - /** - * Returns string representation of an instance - * @return {String} string representation of an instance - */ - toString: function() { - return '#'; - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return extend(this.callSuper('toObject', propertiesToInclude), { - path: this.path.map(function(item) { return item.slice(); }), - }); - }, - - /** - * Returns dataless object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toDatalessObject: function(propertiesToInclude) { - var o = this.toObject(['sourcePath'].concat(propertiesToInclude)); - if (o.sourcePath) { - delete o.path; - } - return o; - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var path = this.path.map(function(path) { - return path.join(' '); - }).join(' '); - return [ - '\n' - ]; - }, - - _getOffsetTransform: function() { - var digits = fabric.Object.NUM_FRACTION_DIGITS; - return ' translate(' + toFixed(-this.pathOffset.x, digits) + ', ' + - toFixed(-this.pathOffset.y, digits) + ')'; - }, - - /** - * Returns svg clipPath representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toClipPathSVG: function(reviver) { - var additionalTransform = this._getOffsetTransform(); - return '\t' + this._createBaseClipPathSVGMarkup( - this._toSVG(), { reviver: reviver, additionalTransform: additionalTransform } - ); - }, - - /** - * Returns svg representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toSVG: function(reviver) { - var additionalTransform = this._getOffsetTransform(); - return this._createBaseSVGMarkup(this._toSVG(), { reviver: reviver, additionalTransform: additionalTransform }); - }, - /* _TO_SVG_END_ */ - - /** - * Returns number representation of an instance complexity - * @return {Number} complexity of this instance - */ - complexity: function() { - return this.path.length; - }, - - /** - * @private - */ - _calcDimensions: function() { - - var aX = [], - aY = [], - current, // current instruction - subpathStartX = 0, - subpathStartY = 0, - x = 0, // current x - y = 0, // current y - bounds; - - for (var i = 0, len = this.path.length; i < len; ++i) { - - current = this.path[i]; - - switch (current[0]) { // first letter - - case 'L': // lineto, absolute - x = current[1]; - y = current[2]; - bounds = []; - break; - - case 'M': // moveTo, absolute - x = current[1]; - y = current[2]; - subpathStartX = x; - subpathStartY = y; - bounds = []; - break; - - case 'C': // bezierCurveTo, absolute - bounds = fabric.util.getBoundsOfCurve(x, y, - current[1], - current[2], - current[3], - current[4], - current[5], - current[6] - ); - x = current[5]; - y = current[6]; - break; - - case 'Q': // quadraticCurveTo, absolute - bounds = fabric.util.getBoundsOfCurve(x, y, - current[1], - current[2], - current[1], - current[2], - current[3], - current[4] - ); - x = current[3]; - y = current[4]; - break; - - case 'z': - case 'Z': - x = subpathStartX; - y = subpathStartY; - break; - } - bounds.forEach(function (point) { - aX.push(point.x); - aY.push(point.y); - }); - aX.push(x); - aY.push(y); - } - - var minX = min(aX) || 0, - minY = min(aY) || 0, - maxX = max(aX) || 0, - maxY = max(aY) || 0, - deltaX = maxX - minX, - deltaY = maxY - minY; - - return { - left: minX, - top: minY, - width: deltaX, - height: deltaY - }; - } - }); - - /** - * Creates an instance of fabric.Path from an object - * @static - * @memberOf fabric.Path - * @param {Object} object - * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created - */ - fabric.Path.fromObject = function(object, callback) { - if (typeof object.sourcePath === 'string') { - var pathUrl = object.sourcePath; - fabric.loadSVGFromURL(pathUrl, function (elements) { - var path = elements[0]; - path.setOptions(object); - callback && callback(path); - }); - } - else { - fabric.Object._fromObject('Path', object, callback, 'path'); - } - }; - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by `fabric.Path.fromElement`) - * @static - * @memberOf fabric.Path - * @see http://www.w3.org/TR/SVG/paths.html#PathElement - */ - fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(['d']); - - /** - * Creates an instance of fabric.Path from an SVG element - * @static - * @memberOf fabric.Path - * @param {SVGElement} element to parse - * @param {Function} callback Callback to invoke when an fabric.Path instance is created - * @param {Object} [options] Options object - * @param {Function} [callback] Options callback invoked after parsing is finished - */ - fabric.Path.fromElement = function(element, callback, options) { - var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES); - parsedAttributes.fromSVG = true; - callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options))); - }; - /* _FROM_SVG_END_ */ - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - min = fabric.util.array.min, - max = fabric.util.array.max; - - if (fabric.Group) { - return; - } - - /** - * Group class - * @class fabric.Group - * @extends fabric.Object - * @mixes fabric.Collection - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups} - * @see {@link fabric.Group#initialize} for constructor definition - */ - fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection, /** @lends fabric.Group.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'group', - - /** - * Width of stroke - * @type Number - * @default - */ - strokeWidth: 0, - - /** - * Indicates if click, mouseover, mouseout events & hoverCursor should also check for subtargets - * @type Boolean - * @default - */ - subTargetCheck: false, - - /** - * Groups are container, do not render anything on theyr own, ence no cache properties - * @type Array - * @default - */ - cacheProperties: [], - - /** - * setOnGroup is a method used for TextBox that is no more used since 2.0.0 The behavior is still - * available setting this boolean to true. - * @type Boolean - * @since 2.0.0 - * @default - */ - useSetOnGroup: false, - - /** - * Constructor - * @param {Object} objects Group objects - * @param {Object} [options] Options object - * @param {Boolean} [isAlreadyGrouped] if true, objects have been grouped already. - * @return {Object} thisArg - */ - initialize: function(objects, options, isAlreadyGrouped) { - options = options || {}; - this._objects = []; - // if objects enclosed in a group have been grouped already, - // we cannot change properties of objects. - // Thus we need to set options to group without objects, - isAlreadyGrouped && this.callSuper('initialize', options); - this._objects = objects || []; - for (var i = this._objects.length; i--; ) { - this._objects[i].group = this; - } - - if (!isAlreadyGrouped) { - var center = options && options.centerPoint; - // we want to set origins before calculating the bounding box. - // so that the topleft can be set with that in mind. - // if specific top and left are passed, are overwritten later - // with the callSuper('initialize', options) - if (options.originX !== undefined) { - this.originX = options.originX; - } - if (options.originY !== undefined) { - this.originY = options.originY; - } - // if coming from svg i do not want to calc bounds. - // i assume width and height are passed along options - center || this._calcBounds(); - this._updateObjectsCoords(center); - delete options.centerPoint; - this.callSuper('initialize', options); - } - else { - this._updateObjectsACoords(); - } - - this.setCoords(); - }, - - /** - * @private - */ - _updateObjectsACoords: function() { - var skipControls = true; - for (var i = this._objects.length; i--; ){ - this._objects[i].setCoords(skipControls); - } - }, - - /** - * @private - * @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change - */ - _updateObjectsCoords: function(center) { - var center = center || this.getCenterPoint(); - for (var i = this._objects.length; i--; ){ - this._updateObjectCoords(this._objects[i], center); - } - }, - - /** - * @private - * @param {Object} object - * @param {fabric.Point} center, current center of group. - */ - _updateObjectCoords: function(object, center) { - var objectLeft = object.left, - objectTop = object.top, - skipControls = true; - - object.set({ - left: objectLeft - center.x, - top: objectTop - center.y - }); - object.group = this; - object.setCoords(skipControls); - }, - - /** - * Returns string represenation of a group - * @return {String} - */ - toString: function() { - return '#'; - }, - - /** - * Adds an object to a group; Then recalculates group's dimension, position. - * @param {Object} object - * @return {fabric.Group} thisArg - * @chainable - */ - addWithUpdate: function(object) { - var nested = !!this.group; - this._restoreObjectsState(); - fabric.util.resetObjectTransform(this); - if (object) { - if (nested) { - // if this group is inside another group, we need to pre transform the object - fabric.util.removeTransformFromObject(object, this.group.calcTransformMatrix()); - } - this._objects.push(object); - object.group = this; - object._set('canvas', this.canvas); - } - this._calcBounds(); - this._updateObjectsCoords(); - this.dirty = true; - if (nested) { - this.group.addWithUpdate(); - } - else { - this.setCoords(); - } - return this; - }, - - /** - * Removes an object from a group; Then recalculates group's dimension, position. - * @param {Object} object - * @return {fabric.Group} thisArg - * @chainable - */ - removeWithUpdate: function(object) { - this._restoreObjectsState(); - fabric.util.resetObjectTransform(this); - - this.remove(object); - this._calcBounds(); - this._updateObjectsCoords(); - this.setCoords(); - this.dirty = true; - return this; - }, - - /** - * @private - */ - _onObjectAdded: function(object) { - this.dirty = true; - object.group = this; - object._set('canvas', this.canvas); - }, - - /** - * @private - */ - _onObjectRemoved: function(object) { - this.dirty = true; - delete object.group; - }, - - /** - * @private - */ - _set: function(key, value) { - var i = this._objects.length; - if (this.useSetOnGroup) { - while (i--) { - this._objects[i].setOnGroup(key, value); - } - } - if (key === 'canvas') { - while (i--) { - this._objects[i]._set(key, value); - } - } - fabric.Object.prototype._set.call(this, key, value); - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - var _includeDefaultValues = this.includeDefaultValues; - var objsToObject = this._objects.map(function(obj) { - var originalDefaults = obj.includeDefaultValues; - obj.includeDefaultValues = _includeDefaultValues; - var _obj = obj.toObject(propertiesToInclude); - obj.includeDefaultValues = originalDefaults; - return _obj; - }); - var obj = fabric.Object.prototype.toObject.call(this, propertiesToInclude); - obj.objects = objsToObject; - return obj; - }, - - /** - * Returns object representation of an instance, in dataless mode. - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toDatalessObject: function(propertiesToInclude) { - var objsToObject, sourcePath = this.sourcePath; - if (sourcePath) { - objsToObject = sourcePath; - } - else { - var _includeDefaultValues = this.includeDefaultValues; - objsToObject = this._objects.map(function(obj) { - var originalDefaults = obj.includeDefaultValues; - obj.includeDefaultValues = _includeDefaultValues; - var _obj = obj.toDatalessObject(propertiesToInclude); - obj.includeDefaultValues = originalDefaults; - return _obj; - }); - } - var obj = fabric.Object.prototype.toDatalessObject.call(this, propertiesToInclude); - obj.objects = objsToObject; - return obj; - }, - - /** - * Renders instance on a given context - * @param {CanvasRenderingContext2D} ctx context to render instance on - */ - render: function(ctx) { - this._transformDone = true; - this.callSuper('render', ctx); - this._transformDone = false; - }, - - /** - * Decide if the object should cache or not. Create its own cache level - * needsItsOwnCache should be used when the object drawing method requires - * a cache step. None of the fabric classes requires it. - * Generally you do not cache objects in groups because the group is already cached. - * @return {Boolean} - */ - shouldCache: function() { - var ownCache = fabric.Object.prototype.shouldCache.call(this); - if (ownCache) { - for (var i = 0, len = this._objects.length; i < len; i++) { - if (this._objects[i].willDrawShadow()) { - this.ownCaching = false; - return false; - } - } - } - return ownCache; - }, - - /** - * Check if this object or a child object will cast a shadow - * @return {Boolean} - */ - willDrawShadow: function() { - if (fabric.Object.prototype.willDrawShadow.call(this)) { - return true; - } - for (var i = 0, len = this._objects.length; i < len; i++) { - if (this._objects[i].willDrawShadow()) { - return true; - } - } - return false; - }, - - /** - * Check if this group or its parent group are caching, recursively up - * @return {Boolean} - */ - isOnACache: function() { - return this.ownCaching || (this.group && this.group.isOnACache()); - }, - - /** - * Execute the drawing operation for an object on a specified context - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - drawObject: function(ctx) { - for (var i = 0, len = this._objects.length; i < len; i++) { - this._objects[i].render(ctx); - } - this._drawClipPath(ctx); - }, - - /** - * Check if cache is dirty - */ - isCacheDirty: function(skipCanvas) { - if (this.callSuper('isCacheDirty', skipCanvas)) { - return true; - } - if (!this.statefullCache) { - return false; - } - for (var i = 0, len = this._objects.length; i < len; i++) { - if (this._objects[i].isCacheDirty(true)) { - if (this._cacheCanvas) { - // if this group has not a cache canvas there is nothing to clean - var x = this.cacheWidth / this.zoomX, y = this.cacheHeight / this.zoomY; - this._cacheContext.clearRect(-x / 2, -y / 2, x, y); - } - return true; - } - } - return false; - }, - - /** - * Restores original state of each of group objects (original state is that which was before group was created). - * if the nested boolean is true, the original state will be restored just for the - * first group and not for all the group chain - * @private - * @param {Boolean} nested tell the function to restore object state up to the parent group and not more - * @return {fabric.Group} thisArg - * @chainable - */ - _restoreObjectsState: function() { - var groupMatrix = this.calcOwnMatrix(); - this._objects.forEach(function(object) { - // instead of using _this = this; - fabric.util.addTransformToObject(object, groupMatrix); - delete object.group; - object.setCoords(); - }); - return this; - }, - - /** - * Realises the transform from this group onto the supplied object - * i.e. it tells you what would happen if the supplied object was in - * the group, and then the group was destroyed. It mutates the supplied - * object. - * Warning: this method is not useful anymore, it has been kept to no break the api. - * is not used in the fabricJS codebase - * this method will be reduced to using the utility. - * @private - * @deprecated - * @param {fabric.Object} object - * @param {Array} parentMatrix parent transformation - * @return {fabric.Object} transformedObject - */ - realizeTransform: function(object, parentMatrix) { - fabric.util.addTransformToObject(object, parentMatrix); - return object; - }, - - /** - * Destroys a group (restoring state of its objects) - * @return {fabric.Group} thisArg - * @chainable - */ - destroy: function() { - // when group is destroyed objects needs to get a repaint to be eventually - // displayed on canvas. - this._objects.forEach(function(object) { - object.set('dirty', true); - }); - return this._restoreObjectsState(); - }, - - /** - * make a group an active selection, remove the group from canvas - * the group has to be on canvas for this to work. - * @return {fabric.ActiveSelection} thisArg - * @chainable - */ - toActiveSelection: function() { - if (!this.canvas) { - return; - } - var objects = this._objects, canvas = this.canvas; - this._objects = []; - var options = this.toObject(); - delete options.objects; - var activeSelection = new fabric.ActiveSelection([]); - activeSelection.set(options); - activeSelection.type = 'activeSelection'; - canvas.remove(this); - objects.forEach(function(object) { - object.group = activeSelection; - object.dirty = true; - canvas.add(object); - }); - activeSelection.canvas = canvas; - activeSelection._objects = objects; - canvas._activeObject = activeSelection; - activeSelection.setCoords(); - return activeSelection; - }, - - /** - * Destroys a group (restoring state of its objects) - * @return {fabric.Group} thisArg - * @chainable - */ - ungroupOnCanvas: function() { - return this._restoreObjectsState(); - }, - - /** - * Sets coordinates of all objects inside group - * @return {fabric.Group} thisArg - * @chainable - */ - setObjectsCoords: function() { - var skipControls = true; - this.forEachObject(function(object) { - object.setCoords(skipControls); - }); - return this; - }, - - /** - * @private - */ - _calcBounds: function(onlyWidthHeight) { - var aX = [], - aY = [], - o, prop, coords, - props = ['tr', 'br', 'bl', 'tl'], - i = 0, iLen = this._objects.length, - j, jLen = props.length; - - for ( ; i < iLen; ++i) { - o = this._objects[i]; - coords = o.calcACoords(); - for (j = 0; j < jLen; j++) { - prop = props[j]; - aX.push(coords[prop].x); - aY.push(coords[prop].y); - } - o.aCoords = coords; - } - - this._getBounds(aX, aY, onlyWidthHeight); - }, - - /** - * @private - */ - _getBounds: function(aX, aY, onlyWidthHeight) { - var minXY = new fabric.Point(min(aX), min(aY)), - maxXY = new fabric.Point(max(aX), max(aY)), - top = minXY.y || 0, left = minXY.x || 0, - width = (maxXY.x - minXY.x) || 0, - height = (maxXY.y - minXY.y) || 0; - this.width = width; - this.height = height; - if (!onlyWidthHeight) { - // the bounding box always finds the topleft most corner. - // whatever is the group origin, we set up here the left/top position. - this.setPositionByOrigin({ x: left, y: top }, 'left', 'top'); - } - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - _toSVG: function(reviver) { - var svgString = ['\n']; - - for (var i = 0, len = this._objects.length; i < len; i++) { - svgString.push('\t\t', this._objects[i].toSVG(reviver)); - } - svgString.push('\n'); - return svgString; - }, - - /** - * Returns styles-string for svg-export, specific version for group - * @return {String} - */ - getSvgStyles: function() { - var opacity = typeof this.opacity !== 'undefined' && this.opacity !== 1 ? - 'opacity: ' + this.opacity + ';' : '', - visibility = this.visible ? '' : ' visibility: hidden;'; - return [ - opacity, - this.getSvgFilter(), - visibility - ].join(''); - }, - - /** - * Returns svg clipPath representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toClipPathSVG: function(reviver) { - var svgString = []; - - for (var i = 0, len = this._objects.length; i < len; i++) { - svgString.push('\t', this._objects[i].toClipPathSVG(reviver)); - } - - return this._createBaseClipPathSVGMarkup(svgString, { reviver: reviver }); - }, - /* _TO_SVG_END_ */ - }); - - /** - * Returns {@link fabric.Group} instance from an object representation - * @static - * @memberOf fabric.Group - * @param {Object} object Object to create a group from - * @param {Function} [callback] Callback to invoke when an group instance is created - */ - fabric.Group.fromObject = function(object, callback) { - var objects = object.objects, - options = fabric.util.object.clone(object, true); - delete options.objects; - if (typeof objects === 'string') { - // it has to be an url or something went wrong. - fabric.loadSVGFromURL(objects, function (elements) { - var group = fabric.util.groupSVGElements(elements, object, objects); - group.set(options); - callback && callback(group); - }); - return; - } - fabric.util.enlivenObjects(objects, function(enlivenedObjects) { - fabric.util.enlivenObjects([object.clipPath], function(enlivedClipPath) { - var options = fabric.util.object.clone(object, true); - options.clipPath = enlivedClipPath[0]; - delete options.objects; - callback && callback(new fabric.Group(enlivenedObjects, options, true)); - }); - }); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }); - - if (fabric.ActiveSelection) { - return; - } - - /** - * Group class - * @class fabric.ActiveSelection - * @extends fabric.Group - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups} - * @see {@link fabric.ActiveSelection#initialize} for constructor definition - */ - fabric.ActiveSelection = fabric.util.createClass(fabric.Group, /** @lends fabric.ActiveSelection.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'activeSelection', - - /** - * Constructor - * @param {Object} objects ActiveSelection objects - * @param {Object} [options] Options object - * @return {Object} thisArg - */ - initialize: function(objects, options) { - options = options || {}; - this._objects = objects || []; - for (var i = this._objects.length; i--; ) { - this._objects[i].group = this; - } - - if (options.originX) { - this.originX = options.originX; - } - if (options.originY) { - this.originY = options.originY; - } - this._calcBounds(); - this._updateObjectsCoords(); - fabric.Object.prototype.initialize.call(this, options); - this.setCoords(); - }, - - /** - * Change te activeSelection to a normal group, - * High level function that automatically adds it to canvas as - * active object. no events fired. - * @since 2.0.0 - * @return {fabric.Group} - */ - toGroup: function() { - var objects = this._objects.concat(); - this._objects = []; - var options = fabric.Object.prototype.toObject.call(this); - var newGroup = new fabric.Group([]); - delete options.type; - newGroup.set(options); - objects.forEach(function(object) { - object.canvas.remove(object); - object.group = newGroup; - }); - newGroup._objects = objects; - if (!this.canvas) { - return newGroup; - } - var canvas = this.canvas; - canvas.add(newGroup); - canvas._activeObject = newGroup; - newGroup.setCoords(); - return newGroup; - }, - - /** - * If returns true, deselection is cancelled. - * @since 2.0.0 - * @return {Boolean} [cancel] - */ - onDeselect: function() { - this.destroy(); - return false; - }, - - /** - * Returns string representation of a group - * @return {String} - */ - toString: function() { - return '#'; - }, - - /** - * Decide if the object should cache or not. Create its own cache level - * objectCaching is a global flag, wins over everything - * needsItsOwnCache should be used when the object drawing method requires - * a cache step. None of the fabric classes requires it. - * Generally you do not cache objects in groups because the group outside is cached. - * @return {Boolean} - */ - shouldCache: function() { - return false; - }, - - /** - * Check if this group or its parent group are caching, recursively up - * @return {Boolean} - */ - isOnACache: function() { - return false; - }, - - /** - * Renders controls and borders for the object - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Object} [styleOverride] properties to override the object style - * @param {Object} [childrenOverride] properties to override the children overrides - */ - _renderControls: function(ctx, styleOverride, childrenOverride) { - ctx.save(); - ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; - this.callSuper('_renderControls', ctx, styleOverride); - childrenOverride = childrenOverride || { }; - if (typeof childrenOverride.hasControls === 'undefined') { - childrenOverride.hasControls = false; - } - childrenOverride.forActiveSelection = true; - for (var i = 0, len = this._objects.length; i < len; i++) { - this._objects[i]._renderControls(ctx, childrenOverride); - } - ctx.restore(); - }, - }); - - /** - * Returns {@link fabric.ActiveSelection} instance from an object representation - * @static - * @memberOf fabric.ActiveSelection - * @param {Object} object Object to create a group from - * @param {Function} [callback] Callback to invoke when an ActiveSelection instance is created - */ - fabric.ActiveSelection.fromObject = function(object, callback) { - fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) { - delete object.objects; - callback && callback(new fabric.ActiveSelection(enlivenedObjects, object, true)); - }); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var extend = fabric.util.object.extend; - - if (!global.fabric) { - global.fabric = { }; - } - - if (global.fabric.Image) { - fabric.warn('fabric.Image is already defined.'); - return; - } - - /** - * Image class - * @class fabric.Image - * @extends fabric.Object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images} - * @see {@link fabric.Image#initialize} for constructor definition - */ - fabric.Image = fabric.util.createClass(fabric.Object, /** @lends fabric.Image.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'image', - - /** - * Width of a stroke. - * For image quality a stroke multiple of 2 gives better results. - * @type Number - * @default - */ - strokeWidth: 0, - - /** - * When calling {@link fabric.Image.getSrc}, return value from element src with `element.getAttribute('src')`. - * This allows for relative urls as image src. - * @since 2.7.0 - * @type Boolean - * @default - */ - srcFromAttribute: false, - - /** - * private - * contains last value of scaleX to detect - * if the Image got resized after the last Render - * @type Number - */ - _lastScaleX: 1, - - /** - * private - * contains last value of scaleY to detect - * if the Image got resized after the last Render - * @type Number - */ - _lastScaleY: 1, - - /** - * private - * contains last value of scaling applied by the apply filter chain - * @type Number - */ - _filterScalingX: 1, - - /** - * private - * contains last value of scaling applied by the apply filter chain - * @type Number - */ - _filterScalingY: 1, - - /** - * minimum scale factor under which any resizeFilter is triggered to resize the image - * 0 will disable the automatic resize. 1 will trigger automatically always. - * number bigger than 1 are not implemented yet. - * @type Number - */ - minimumScaleTrigger: 0.5, - - /** - * List of properties to consider when checking if - * state of an object is changed ({@link fabric.Object#hasStateChanged}) - * as well as for history (undo/redo) purposes - * @type Array - */ - stateProperties: fabric.Object.prototype.stateProperties.concat('cropX', 'cropY'), - - /** - * List of properties to consider when checking if cache needs refresh - * Those properties are checked by statefullCache ON ( or lazy mode if we want ) or from single - * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty - * and refreshed at the next render - * @type Array - */ - cacheProperties: fabric.Object.prototype.cacheProperties.concat('cropX', 'cropY'), - - /** - * key used to retrieve the texture representing this image - * @since 2.0.0 - * @type String - * @default - */ - cacheKey: '', - - /** - * Image crop in pixels from original image size. - * @since 2.0.0 - * @type Number - * @default - */ - cropX: 0, - - /** - * Image crop in pixels from original image size. - * @since 2.0.0 - * @type Number - * @default - */ - cropY: 0, - - /** - * Indicates whether this canvas will use image smoothing when painting this image. - * Also influence if the cacheCanvas for this image uses imageSmoothing - * @since 4.0.0-beta.11 - * @type Boolean - * @default - */ - imageSmoothing: true, - - /** - * Constructor - * Image can be initialized with any canvas drawable or a string. - * The string should be a url and will be loaded as an image. - * Canvas and Image element work out of the box, while videos require extra code to work. - * Please check video element events for seeking. - * @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | String} element Image element - * @param {Object} [options] Options object - * @param {function} [callback] callback function to call after eventual filters applied. - * @return {fabric.Image} thisArg - */ - initialize: function(element, options) { - options || (options = { }); - this.filters = []; - this.cacheKey = 'texture' + fabric.Object.__uid++; - this.callSuper('initialize', options); - this._initElement(element, options); - }, - - /** - * Returns image element which this instance if based on - * @return {HTMLImageElement} Image element - */ - getElement: function() { - return this._element || {}; - }, - - /** - * Sets image element for this instance to a specified one. - * If filters defined they are applied to new image. - * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area. - * @param {HTMLImageElement} element - * @param {Object} [options] Options object - * @return {fabric.Image} thisArg - * @chainable - */ - setElement: function(element, options) { - this.removeTexture(this.cacheKey); - this.removeTexture(this.cacheKey + '_filtered'); - this._element = element; - this._originalElement = element; - this._initConfig(options); - if (this.filters.length !== 0) { - this.applyFilters(); - } - // resizeFilters work on the already filtered copy. - // we need to apply resizeFilters AFTER normal filters. - // applyResizeFilters is run more often than normal filters - // and is triggered by user interactions rather than dev code - if (this.resizeFilter) { - this.applyResizeFilters(); - } - return this; - }, - - /** - * Delete a single texture if in webgl mode - */ - removeTexture: function(key) { - var backend = fabric.filterBackend; - if (backend && backend.evictCachesForKey) { - backend.evictCachesForKey(key); - } - }, - - /** - * Delete textures, reference to elements and eventually JSDOM cleanup - */ - dispose: function() { - this.removeTexture(this.cacheKey); - this.removeTexture(this.cacheKey + '_filtered'); - this._cacheContext = undefined; - ['_originalElement', '_element', '_filteredEl', '_cacheCanvas'].forEach((function(element) { - fabric.util.cleanUpJsdomNode(this[element]); - this[element] = undefined; - }).bind(this)); - }, - - /** - * Get the crossOrigin value (of the corresponding image element) - */ - getCrossOrigin: function() { - return this._originalElement && (this._originalElement.crossOrigin || null); - }, - - /** - * Returns original size of an image - * @return {Object} Object with "width" and "height" properties - */ - getOriginalSize: function() { - var element = this.getElement(); - return { - width: element.naturalWidth || element.width, - height: element.naturalHeight || element.height - }; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _stroke: function(ctx) { - if (!this.stroke || this.strokeWidth === 0) { - return; - } - var w = this.width / 2, h = this.height / 2; - ctx.beginPath(); - ctx.moveTo(-w, -h); - ctx.lineTo(w, -h); - ctx.lineTo(w, h); - ctx.lineTo(-w, h); - ctx.lineTo(-w, -h); - ctx.closePath(); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderDashedStroke: function(ctx) { - var x = -this.width / 2, - y = -this.height / 2, - w = this.width, - h = this.height; - - ctx.save(); - this._setStrokeStyles(ctx, this); - - ctx.beginPath(); - fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray); - ctx.closePath(); - ctx.restore(); - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of an instance - */ - toObject: function(propertiesToInclude) { - var filters = []; - - this.filters.forEach(function(filterObj) { - if (filterObj) { - filters.push(filterObj.toObject()); - } - }); - var object = extend( - this.callSuper( - 'toObject', - ['cropX', 'cropY'].concat(propertiesToInclude) - ), { - src: this.getSrc(), - crossOrigin: this.getCrossOrigin(), - filters: filters, - }); - if (this.resizeFilter) { - object.resizeFilter = this.resizeFilter.toObject(); - } - return object; - }, - - /** - * Returns true if an image has crop applied, inspecting values of cropX,cropY,width,height. - * @return {Boolean} - */ - hasCrop: function() { - return this.cropX || this.cropY || this.width < this._element.width || this.height < this._element.height; - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var svgString = [], imageMarkup = [], strokeSvg, element = this._element, - x = -this.width / 2, y = -this.height / 2, clipPath = '', imageRendering = ''; - if (!element) { - return []; - } - if (this.hasCrop()) { - var clipPathId = fabric.Object.__uid++; - svgString.push( - '\n', - '\t\n', - '\n' - ); - clipPath = ' clip-path="url(#imageCrop_' + clipPathId + ')" '; - } - if (!this.imageSmoothing) { - imageRendering = '" image-rendering="optimizeSpeed'; - } - imageMarkup.push('\t\n'); - - if (this.stroke || this.strokeDashArray) { - var origFill = this.fill; - this.fill = null; - strokeSvg = [ - '\t\n' - ]; - this.fill = origFill; - } - if (this.paintFirst !== 'fill') { - svgString = svgString.concat(strokeSvg, imageMarkup); - } - else { - svgString = svgString.concat(imageMarkup, strokeSvg); - } - return svgString; - }, - /* _TO_SVG_END_ */ - - /** - * Returns source of an image - * @param {Boolean} filtered indicates if the src is needed for svg - * @return {String} Source of an image - */ - getSrc: function(filtered) { - var element = filtered ? this._element : this._originalElement; - if (element) { - if (element.toDataURL) { - return element.toDataURL(); - } - - if (this.srcFromAttribute) { - return element.getAttribute('src'); - } - else { - return element.src; - } - } - else { - return this.src || ''; - } - }, - - /** - * Sets source of an image - * @param {String} src Source string (URL) - * @param {Function} [callback] Callback is invoked when image has been loaded (and all filters have been applied) - * @param {Object} [options] Options object - * @param {String} [options.crossOrigin] crossOrigin value (one of "", "anonymous", "use-credentials") - * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes - * @return {fabric.Image} thisArg - * @chainable - */ - setSrc: function(src, callback, options) { - fabric.util.loadImage(src, function(img, isError) { - this.setElement(img, options); - this._setWidthHeight(); - callback && callback(this, isError); - }, this, options && options.crossOrigin); - return this; - }, - - /** - * Returns string representation of an instance - * @return {String} String representation of an instance - */ - toString: function() { - return '#'; - }, - - applyResizeFilters: function() { - var filter = this.resizeFilter, - minimumScale = this.minimumScaleTrigger, - objectScale = this.getTotalObjectScaling(), - scaleX = objectScale.scaleX, - scaleY = objectScale.scaleY, - elementToFilter = this._filteredEl || this._originalElement; - if (this.group) { - this.set('dirty', true); - } - if (!filter || (scaleX > minimumScale && scaleY > minimumScale)) { - this._element = elementToFilter; - this._filterScalingX = 1; - this._filterScalingY = 1; - this._lastScaleX = scaleX; - this._lastScaleY = scaleY; - return; - } - if (!fabric.filterBackend) { - fabric.filterBackend = fabric.initFilterBackend(); - } - var canvasEl = fabric.util.createCanvasElement(), - cacheKey = this._filteredEl ? (this.cacheKey + '_filtered') : this.cacheKey, - sourceWidth = elementToFilter.width, sourceHeight = elementToFilter.height; - canvasEl.width = sourceWidth; - canvasEl.height = sourceHeight; - this._element = canvasEl; - this._lastScaleX = filter.scaleX = scaleX; - this._lastScaleY = filter.scaleY = scaleY; - fabric.filterBackend.applyFilters( - [filter], elementToFilter, sourceWidth, sourceHeight, this._element, cacheKey); - this._filterScalingX = canvasEl.width / this._originalElement.width; - this._filterScalingY = canvasEl.height / this._originalElement.height; - }, - - /** - * Applies filters assigned to this image (from "filters" array) or from filter param - * @method applyFilters - * @param {Array} filters to be applied - * @param {Boolean} forResizing specify if the filter operation is a resize operation - * @return {thisArg} return the fabric.Image object - * @chainable - */ - applyFilters: function(filters) { - - filters = filters || this.filters || []; - filters = filters.filter(function(filter) { return filter && !filter.isNeutralState(); }); - this.set('dirty', true); - - // needs to clear out or WEBGL will not resize correctly - this.removeTexture(this.cacheKey + '_filtered'); - - if (filters.length === 0) { - this._element = this._originalElement; - this._filteredEl = null; - this._filterScalingX = 1; - this._filterScalingY = 1; - return this; - } - - var imgElement = this._originalElement, - sourceWidth = imgElement.naturalWidth || imgElement.width, - sourceHeight = imgElement.naturalHeight || imgElement.height; - - if (this._element === this._originalElement) { - // if the element is the same we need to create a new element - var canvasEl = fabric.util.createCanvasElement(); - canvasEl.width = sourceWidth; - canvasEl.height = sourceHeight; - this._element = canvasEl; - this._filteredEl = canvasEl; - } - else { - // clear the existing element to get new filter data - // also dereference the eventual resized _element - this._element = this._filteredEl; - this._filteredEl.getContext('2d').clearRect(0, 0, sourceWidth, sourceHeight); - // we also need to resize again at next renderAll, so remove saved _lastScaleX/Y - this._lastScaleX = 1; - this._lastScaleY = 1; - } - if (!fabric.filterBackend) { - fabric.filterBackend = fabric.initFilterBackend(); - } - fabric.filterBackend.applyFilters( - filters, this._originalElement, sourceWidth, sourceHeight, this._element, this.cacheKey); - if (this._originalElement.width !== this._element.width || - this._originalElement.height !== this._element.height) { - this._filterScalingX = this._element.width / this._originalElement.width; - this._filterScalingY = this._element.height / this._originalElement.height; - } - return this; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - fabric.util.setImageSmoothing(ctx, this.imageSmoothing); - if (this.isMoving !== true && this.resizeFilter && this._needsResize()) { - this.applyResizeFilters(); - } - this._stroke(ctx); - this._renderPaintInOrder(ctx); - }, - - /** - * Paint the cached copy of the object on the target context. - * it will set the imageSmoothing for the draw operation - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - drawCacheOnCanvas: function(ctx) { - fabric.util.setImageSmoothing(ctx, this.imageSmoothing); - fabric.Object.prototype.drawCacheOnCanvas.call(this, ctx); - }, - - /** - * Decide if the object should cache or not. Create its own cache level - * needsItsOwnCache should be used when the object drawing method requires - * a cache step. None of the fabric classes requires it. - * Generally you do not cache objects in groups because the group outside is cached. - * This is the special image version where we would like to avoid caching where possible. - * Essentially images do not benefit from caching. They may require caching, and in that - * case we do it. Also caching an image usually ends in a loss of details. - * A full performance audit should be done. - * @return {Boolean} - */ - shouldCache: function() { - return this.needsItsOwnCache(); - }, - - _renderFill: function(ctx) { - var elementToDraw = this._element; - if (!elementToDraw) { - return; - } - var scaleX = this._filterScalingX, scaleY = this._filterScalingY, - w = this.width, h = this.height, min = Math.min, max = Math.max, - // crop values cannot be lesser than 0. - cropX = max(this.cropX, 0), cropY = max(this.cropY, 0), - elWidth = elementToDraw.naturalWidth || elementToDraw.width, - elHeight = elementToDraw.naturalHeight || elementToDraw.height, - sX = cropX * scaleX, - sY = cropY * scaleY, - // the width height cannot exceed element width/height, starting from the crop offset. - sW = min(w * scaleX, elWidth - sX), - sH = min(h * scaleY, elHeight - sY), - x = -w / 2, y = -h / 2, - maxDestW = min(w, elWidth / scaleX - cropX), - maxDestH = min(h, elHeight / scaleY - cropY); - - elementToDraw && ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, maxDestW, maxDestH); - }, - - /** - * needed to check if image needs resize - * @private - */ - _needsResize: function() { - var scale = this.getTotalObjectScaling(); - return (scale.scaleX !== this._lastScaleX || scale.scaleY !== this._lastScaleY); - }, - - /** - * @private - */ - _resetWidthHeight: function() { - this.set(this.getOriginalSize()); - }, - - /** - * The Image class's initialization method. This method is automatically - * called by the constructor. - * @private - * @param {HTMLImageElement|String} element The element representing the image - * @param {Object} [options] Options object - */ - _initElement: function(element, options) { - this.setElement(fabric.util.getById(element), options); - fabric.util.addClass(this.getElement(), fabric.Image.CSS_CANVAS); - }, - - /** - * @private - * @param {Object} [options] Options object - */ - _initConfig: function(options) { - options || (options = { }); - this.setOptions(options); - this._setWidthHeight(options); - }, - - /** - * @private - * @param {Array} filters to be initialized - * @param {Function} callback Callback to invoke when all fabric.Image.filters instances are created - */ - _initFilters: function(filters, callback) { - if (filters && filters.length) { - fabric.util.enlivenObjects(filters, function(enlivenedObjects) { - callback && callback(enlivenedObjects); - }, 'fabric.Image.filters'); - } - else { - callback && callback(); - } - }, - - /** - * @private - * Set the width and the height of the image object, using the element or the - * options. - * @param {Object} [options] Object with width/height properties - */ - _setWidthHeight: function(options) { - options || (options = { }); - var el = this.getElement(); - this.width = options.width || el.naturalWidth || el.width || 0; - this.height = options.height || el.naturalHeight || el.height || 0; - }, - - /** - * Calculate offset for center and scale factor for the image in order to respect - * the preserveAspectRatio attribute - * @private - * @return {Object} - */ - parsePreserveAspectRatioAttribute: function() { - var pAR = fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio || ''), - rWidth = this._element.width, rHeight = this._element.height, - scaleX = 1, scaleY = 1, offsetLeft = 0, offsetTop = 0, cropX = 0, cropY = 0, - offset, pWidth = this.width, pHeight = this.height, parsedAttributes = { width: pWidth, height: pHeight }; - if (pAR && (pAR.alignX !== 'none' || pAR.alignY !== 'none')) { - if (pAR.meetOrSlice === 'meet') { - scaleX = scaleY = fabric.util.findScaleToFit(this._element, parsedAttributes); - offset = (pWidth - rWidth * scaleX) / 2; - if (pAR.alignX === 'Min') { - offsetLeft = -offset; - } - if (pAR.alignX === 'Max') { - offsetLeft = offset; - } - offset = (pHeight - rHeight * scaleY) / 2; - if (pAR.alignY === 'Min') { - offsetTop = -offset; - } - if (pAR.alignY === 'Max') { - offsetTop = offset; - } - } - if (pAR.meetOrSlice === 'slice') { - scaleX = scaleY = fabric.util.findScaleToCover(this._element, parsedAttributes); - offset = rWidth - pWidth / scaleX; - if (pAR.alignX === 'Mid') { - cropX = offset / 2; - } - if (pAR.alignX === 'Max') { - cropX = offset; - } - offset = rHeight - pHeight / scaleY; - if (pAR.alignY === 'Mid') { - cropY = offset / 2; - } - if (pAR.alignY === 'Max') { - cropY = offset; - } - rWidth = pWidth / scaleX; - rHeight = pHeight / scaleY; - } - } - else { - scaleX = pWidth / rWidth; - scaleY = pHeight / rHeight; - } - return { - width: rWidth, - height: rHeight, - scaleX: scaleX, - scaleY: scaleY, - offsetLeft: offsetLeft, - offsetTop: offsetTop, - cropX: cropX, - cropY: cropY - }; - } - }); - - /** - * Default CSS class name for canvas - * @static - * @type String - * @default - */ - fabric.Image.CSS_CANVAS = 'canvas-img'; - - /** - * Alias for getSrc - * @static - */ - fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc; - - /** - * Creates an instance of fabric.Image from its object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} callback Callback to invoke when an image instance is created - */ - fabric.Image.fromObject = function(_object, callback) { - var object = fabric.util.object.clone(_object); - fabric.util.loadImage(object.src, function(img, isError) { - if (isError) { - callback && callback(null, true); - return; - } - fabric.Image.prototype._initFilters.call(object, object.filters, function(filters) { - object.filters = filters || []; - fabric.Image.prototype._initFilters.call(object, [object.resizeFilter], function(resizeFilters) { - object.resizeFilter = resizeFilters[0]; - fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) { - object.clipPath = enlivedProps[0]; - var image = new fabric.Image(img, object); - callback(image, false); - }); - }); - }); - }, null, object.crossOrigin); - }; - - /** - * Creates an instance of fabric.Image from an URL string - * @static - * @param {String} url URL to create an image from - * @param {Function} [callback] Callback to invoke when image is created (newly created image is passed as a first argument). Second argument is a boolean indicating if an error occurred or not. - * @param {Object} [imgOptions] Options object - */ - fabric.Image.fromURL = function(url, callback, imgOptions) { - fabric.util.loadImage(url, function(img, isError) { - callback && callback(new fabric.Image(img, imgOptions), isError); - }, null, imgOptions && imgOptions.crossOrigin); - }; - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Image.fromElement}) - * @static - * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement} - */ - fabric.Image.ATTRIBUTE_NAMES = - fabric.SHARED_ATTRIBUTES.concat( - 'x y width height preserveAspectRatio xlink:href crossOrigin image-rendering'.split(' ') - ); - - /** - * Returns {@link fabric.Image} instance from an SVG element - * @static - * @param {SVGElement} element Element to parse - * @param {Object} [options] Options object - * @param {Function} callback Callback to execute when fabric.Image object is created - * @return {fabric.Image} Instance of fabric.Image - */ - fabric.Image.fromElement = function(element, callback, options) { - var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES); - fabric.Image.fromURL(parsedAttributes['xlink:href'], callback, - extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes)); - }; - /* _FROM_SVG_END_ */ - -})(typeof exports !== 'undefined' ? exports : this); - - -fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - - /** - * @private - * @return {Number} angle value - */ - _getAngleValueForStraighten: function() { - var angle = this.angle % 360; - if (angle > 0) { - return Math.round((angle - 1) / 90) * 90; - } - return Math.round(angle / 90) * 90; - }, - - /** - * Straightens an object (rotating it from current angle to one of 0, 90, 180, 270, etc. depending on which is closer) - * @return {fabric.Object} thisArg - * @chainable - */ - straighten: function() { - this.rotate(this._getAngleValueForStraighten()); - return this; - }, - - /** - * Same as {@link fabric.Object.prototype.straighten} but with animation - * @param {Object} callbacks Object with callback functions - * @param {Function} [callbacks.onComplete] Invoked on completion - * @param {Function} [callbacks.onChange] Invoked on every step of animation - * @return {fabric.Object} thisArg - * @chainable - */ - fxStraighten: function(callbacks) { - callbacks = callbacks || { }; - - var empty = function() { }, - onComplete = callbacks.onComplete || empty, - onChange = callbacks.onChange || empty, - _this = this; - - fabric.util.animate({ - startValue: this.get('angle'), - endValue: this._getAngleValueForStraighten(), - duration: this.FX_DURATION, - onChange: function(value) { - _this.rotate(value); - onChange(); - }, - onComplete: function() { - _this.setCoords(); - onComplete(); - }, - }); - - return this; - } -}); - -fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { - - /** - * Straightens object, then rerenders canvas - * @param {fabric.Object} object Object to straighten - * @return {fabric.Canvas} thisArg - * @chainable - */ - straightenObject: function (object) { - object.straighten(); - this.requestRenderAll(); - return this; - }, - - /** - * Same as {@link fabric.Canvas.prototype.straightenObject}, but animated - * @param {fabric.Object} object Object to straighten - * @return {fabric.Canvas} thisArg - * @chainable - */ - fxStraightenObject: function (object) { - object.fxStraighten({ - onChange: this.requestRenderAllBound - }); - return this; - } -}); - - -(function() { - - 'use strict'; - - /** - * Tests if webgl supports certain precision - * @param {WebGL} Canvas WebGL context to test on - * @param {String} Precision to test can be any of following: 'lowp', 'mediump', 'highp' - * @returns {Boolean} Whether the user's browser WebGL supports given precision. - */ - function testPrecision(gl, precision){ - var fragmentSource = 'precision ' + precision + ' float;\nvoid main(){}'; - var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); - gl.shaderSource(fragmentShader, fragmentSource); - gl.compileShader(fragmentShader); - if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { - return false; - } - return true; - } - - /** - * Indicate whether this filtering backend is supported by the user's browser. - * @param {Number} tileSize check if the tileSize is supported - * @returns {Boolean} Whether the user's browser supports WebGL. - */ - fabric.isWebglSupported = function(tileSize) { - if (fabric.isLikelyNode) { - return false; - } - tileSize = tileSize || fabric.WebglFilterBackend.prototype.tileSize; - var canvas = document.createElement('canvas'); - var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); - var isSupported = false; - // eslint-disable-next-line - if (gl) { - fabric.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); - isSupported = fabric.maxTextureSize >= tileSize; - var precisions = ['highp', 'mediump', 'lowp']; - for (var i = 0; i < 3; i++){ - if (testPrecision(gl, precisions[i])){ - fabric.webGlPrecision = precisions[i]; - break; - }; - } - } - this.isSupported = isSupported; - return isSupported; - }; - - fabric.WebglFilterBackend = WebglFilterBackend; - - /** - * WebGL filter backend. - */ - function WebglFilterBackend(options) { - if (options && options.tileSize) { - this.tileSize = options.tileSize; - } - this.setupGLContext(this.tileSize, this.tileSize); - this.captureGPUInfo(); - }; - - WebglFilterBackend.prototype = /** @lends fabric.WebglFilterBackend.prototype */ { - - tileSize: 2048, - - /** - * Experimental. This object is a sort of repository of help layers used to avoid - * of recreating them during frequent filtering. If you are previewing a filter with - * a slider you probably do not want to create help layers every filter step. - * in this object there will be appended some canvases, created once, resized sometimes - * cleared never. Clearing is left to the developer. - **/ - resources: { - - }, - - /** - * Setup a WebGL context suitable for filtering, and bind any needed event handlers. - */ - setupGLContext: function(width, height) { - this.dispose(); - this.createWebGLCanvas(width, height); - // eslint-disable-next-line - this.aPosition = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]); - this.chooseFastestCopyGLTo2DMethod(width, height); - }, - - /** - * Pick a method to copy data from GL context to 2d canvas. In some browsers using - * putImageData is faster than drawImage for that specific operation. - */ - chooseFastestCopyGLTo2DMethod: function(width, height) { - var canMeasurePerf = typeof window.performance !== 'undefined', canUseImageData; - try { - new ImageData(1, 1); - canUseImageData = true; - } - catch (e) { - canUseImageData = false; - } - // eslint-disable-next-line no-undef - var canUseArrayBuffer = typeof ArrayBuffer !== 'undefined'; - // eslint-disable-next-line no-undef - var canUseUint8Clamped = typeof Uint8ClampedArray !== 'undefined'; - - if (!(canMeasurePerf && canUseImageData && canUseArrayBuffer && canUseUint8Clamped)) { - return; - } - - var targetCanvas = fabric.util.createCanvasElement(); - // eslint-disable-next-line no-undef - var imageBuffer = new ArrayBuffer(width * height * 4); - if (fabric.forceGLPutImageData) { - this.imageBuffer = imageBuffer; - this.copyGLTo2D = copyGLTo2DPutImageData; - return; - } - var testContext = { - imageBuffer: imageBuffer, - destinationWidth: width, - destinationHeight: height, - targetCanvas: targetCanvas - }; - var startTime, drawImageTime, putImageDataTime; - targetCanvas.width = width; - targetCanvas.height = height; - - startTime = window.performance.now(); - copyGLTo2DDrawImage.call(testContext, this.gl, testContext); - drawImageTime = window.performance.now() - startTime; - - startTime = window.performance.now(); - copyGLTo2DPutImageData.call(testContext, this.gl, testContext); - putImageDataTime = window.performance.now() - startTime; - - if (drawImageTime > putImageDataTime) { - this.imageBuffer = imageBuffer; - this.copyGLTo2D = copyGLTo2DPutImageData; - } - else { - this.copyGLTo2D = copyGLTo2DDrawImage; - } - }, - - /** - * Create a canvas element and associated WebGL context and attaches them as - * class properties to the GLFilterBackend class. - */ - createWebGLCanvas: function(width, height) { - var canvas = fabric.util.createCanvasElement(); - canvas.width = width; - canvas.height = height; - var glOptions = { - alpha: true, - premultipliedAlpha: false, - depth: false, - stencil: false, - antialias: false - }, - gl = canvas.getContext('webgl', glOptions); - if (!gl) { - gl = canvas.getContext('experimental-webgl', glOptions); - } - if (!gl) { - return; - } - gl.clearColor(0, 0, 0, 0); - // this canvas can fire webglcontextlost and webglcontextrestored - this.canvas = canvas; - this.gl = gl; - }, - - /** - * Attempts to apply the requested filters to the source provided, drawing the filtered output - * to the provided target canvas. - * - * @param {Array} filters The filters to apply. - * @param {HTMLImageElement|HTMLCanvasElement} source The source to be filtered. - * @param {Number} width The width of the source input. - * @param {Number} height The height of the source input. - * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn. - * @param {String|undefined} cacheKey A key used to cache resources related to the source. If - * omitted, caching will be skipped. - */ - applyFilters: function(filters, source, width, height, targetCanvas, cacheKey) { - var gl = this.gl; - var cachedTexture; - if (cacheKey) { - cachedTexture = this.getCachedTexture(cacheKey, source); - } - var pipelineState = { - originalWidth: source.width || source.originalWidth, - originalHeight: source.height || source.originalHeight, - sourceWidth: width, - sourceHeight: height, - destinationWidth: width, - destinationHeight: height, - context: gl, - sourceTexture: this.createTexture(gl, width, height, !cachedTexture && source), - targetTexture: this.createTexture(gl, width, height), - originalTexture: cachedTexture || - this.createTexture(gl, width, height, !cachedTexture && source), - passes: filters.length, - webgl: true, - aPosition: this.aPosition, - programCache: this.programCache, - pass: 0, - filterBackend: this, - targetCanvas: targetCanvas - }; - var tempFbo = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, tempFbo); - filters.forEach(function(filter) { filter && filter.applyTo(pipelineState); }); - resizeCanvasIfNeeded(pipelineState); - this.copyGLTo2D(gl, pipelineState); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.deleteTexture(pipelineState.sourceTexture); - gl.deleteTexture(pipelineState.targetTexture); - gl.deleteFramebuffer(tempFbo); - targetCanvas.getContext('2d').setTransform(1, 0, 0, 1, 0, 0); - return pipelineState; - }, - - /** - * Detach event listeners, remove references, and clean up caches. - */ - dispose: function() { - if (this.canvas) { - this.canvas = null; - this.gl = null; - } - this.clearWebGLCaches(); - }, - - /** - * Wipe out WebGL-related caches. - */ - clearWebGLCaches: function() { - this.programCache = {}; - this.textureCache = {}; - }, - - /** - * Create a WebGL texture object. - * - * Accepts specific dimensions to initialize the texture to or a source image. - * - * @param {WebGLRenderingContext} gl The GL context to use for creating the texture. - * @param {Number} width The width to initialize the texture at. - * @param {Number} height The height to initialize the texture. - * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source for the texture data. - * @returns {WebGLTexture} - */ - createTexture: function(gl, width, height, textureImageSource) { - var texture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - if (textureImageSource) { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureImageSource); - } - else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - return texture; - }, - - /** - * Can be optionally used to get a texture from the cache array - * - * If an existing texture is not found, a new texture is created and cached. - * - * @param {String} uniqueId A cache key to use to find an existing texture. - * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source to use to create the - * texture cache entry if one does not already exist. - */ - getCachedTexture: function(uniqueId, textureImageSource) { - if (this.textureCache[uniqueId]) { - return this.textureCache[uniqueId]; - } - else { - var texture = this.createTexture( - this.gl, textureImageSource.width, textureImageSource.height, textureImageSource); - this.textureCache[uniqueId] = texture; - return texture; - } - }, - - /** - * Clear out cached resources related to a source image that has been - * filtered previously. - * - * @param {String} cacheKey The cache key provided when the source image was filtered. - */ - evictCachesForKey: function(cacheKey) { - if (this.textureCache[cacheKey]) { - this.gl.deleteTexture(this.textureCache[cacheKey]); - delete this.textureCache[cacheKey]; - } - }, - - copyGLTo2D: copyGLTo2DDrawImage, - - /** - * Attempt to extract GPU information strings from a WebGL context. - * - * Useful information when debugging or blacklisting specific GPUs. - * - * @returns {Object} A GPU info object with renderer and vendor strings. - */ - captureGPUInfo: function() { - if (this.gpuInfo) { - return this.gpuInfo; - } - var gl = this.gl, gpuInfo = { renderer: '', vendor: '' }; - if (!gl) { - return gpuInfo; - } - var ext = gl.getExtension('WEBGL_debug_renderer_info'); - if (ext) { - var renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL); - var vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL); - if (renderer) { - gpuInfo.renderer = renderer.toLowerCase(); - } - if (vendor) { - gpuInfo.vendor = vendor.toLowerCase(); - } - } - this.gpuInfo = gpuInfo; - return gpuInfo; - }, - }; -})(); - -function resizeCanvasIfNeeded(pipelineState) { - var targetCanvas = pipelineState.targetCanvas, - width = targetCanvas.width, height = targetCanvas.height, - dWidth = pipelineState.destinationWidth, - dHeight = pipelineState.destinationHeight; - - if (width !== dWidth || height !== dHeight) { - targetCanvas.width = dWidth; - targetCanvas.height = dHeight; - } -} - -/** - * Copy an input WebGL canvas on to an output 2D canvas. - * - * The WebGL canvas is assumed to be upside down, with the top-left pixel of the - * desired output image appearing in the bottom-left corner of the WebGL canvas. - * - * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from. - * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to. - * @param {Object} pipelineState The 2D target canvas to copy on to. - */ -function copyGLTo2DDrawImage(gl, pipelineState) { - var glCanvas = gl.canvas, targetCanvas = pipelineState.targetCanvas, - ctx = targetCanvas.getContext('2d'); - ctx.translate(0, targetCanvas.height); // move it down again - ctx.scale(1, -1); // vertical flip - // where is my image on the big glcanvas? - var sourceY = glCanvas.height - targetCanvas.height; - ctx.drawImage(glCanvas, 0, sourceY, targetCanvas.width, targetCanvas.height, 0, 0, - targetCanvas.width, targetCanvas.height); -} - -/** - * Copy an input WebGL canvas on to an output 2D canvas using 2d canvas' putImageData - * API. Measurably faster than using ctx.drawImage in Firefox (version 54 on OSX Sierra). - * - * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from. - * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to. - * @param {Object} pipelineState The 2D target canvas to copy on to. - */ -function copyGLTo2DPutImageData(gl, pipelineState) { - var targetCanvas = pipelineState.targetCanvas, ctx = targetCanvas.getContext('2d'), - dWidth = pipelineState.destinationWidth, - dHeight = pipelineState.destinationHeight, - numBytes = dWidth * dHeight * 4; - - // eslint-disable-next-line no-undef - var u8 = new Uint8Array(this.imageBuffer, 0, numBytes); - // eslint-disable-next-line no-undef - var u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes); - - gl.readPixels(0, 0, dWidth, dHeight, gl.RGBA, gl.UNSIGNED_BYTE, u8); - var imgData = new ImageData(u8Clamped, dWidth, dHeight); - ctx.putImageData(imgData, 0, 0); -} - - -(function() { - - 'use strict'; - - var noop = function() {}; - - fabric.Canvas2dFilterBackend = Canvas2dFilterBackend; - - /** - * Canvas 2D filter backend. - */ - function Canvas2dFilterBackend() {}; - - Canvas2dFilterBackend.prototype = /** @lends fabric.Canvas2dFilterBackend.prototype */ { - evictCachesForKey: noop, - dispose: noop, - clearWebGLCaches: noop, - - /** - * Experimental. This object is a sort of repository of help layers used to avoid - * of recreating them during frequent filtering. If you are previewing a filter with - * a slider you probably do not want to create help layers every filter step. - * in this object there will be appended some canvases, created once, resized sometimes - * cleared never. Clearing is left to the developer. - **/ - resources: { - - }, - - /** - * Apply a set of filters against a source image and draw the filtered output - * to the provided destination canvas. - * - * @param {EnhancedFilter} filters The filter to apply. - * @param {HTMLImageElement|HTMLCanvasElement} sourceElement The source to be filtered. - * @param {Number} sourceWidth The width of the source input. - * @param {Number} sourceHeight The height of the source input. - * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn. - */ - applyFilters: function(filters, sourceElement, sourceWidth, sourceHeight, targetCanvas) { - var ctx = targetCanvas.getContext('2d'); - ctx.drawImage(sourceElement, 0, 0, sourceWidth, sourceHeight); - var imageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight); - var originalImageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight); - var pipelineState = { - sourceWidth: sourceWidth, - sourceHeight: sourceHeight, - imageData: imageData, - originalEl: sourceElement, - originalImageData: originalImageData, - canvasEl: targetCanvas, - ctx: ctx, - filterBackend: this, - }; - filters.forEach(function(filter) { filter.applyTo(pipelineState); }); - if (pipelineState.imageData.width !== sourceWidth || pipelineState.imageData.height !== sourceHeight) { - targetCanvas.width = pipelineState.imageData.width; - targetCanvas.height = pipelineState.imageData.height; - } - ctx.putImageData(pipelineState.imageData, 0, 0); - return pipelineState; - }, - - }; -})(); - - -/** - * @namespace fabric.Image.filters - * @memberOf fabric.Image - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#image_filters} - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - */ -fabric.Image = fabric.Image || { }; -fabric.Image.filters = fabric.Image.filters || { }; - -/** - * Root filter class from which all filter classes inherit from - * @class fabric.Image.filters.BaseFilter - * @memberOf fabric.Image.filters - */ -fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Image.filters.BaseFilter.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'BaseFilter', - - /** - * Array of attributes to send with buffers. do not modify - * @private - */ - - vertexSource: 'attribute vec2 aPosition;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vTexCoord = aPosition;\n' + - 'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n' + - '}', - - fragmentSource: 'precision highp float;\n' + - 'varying vec2 vTexCoord;\n' + - 'uniform sampler2D uTexture;\n' + - 'void main() {\n' + - 'gl_FragColor = texture2D(uTexture, vTexCoord);\n' + - '}', - - /** - * Constructor - * @param {Object} [options] Options object - */ - initialize: function(options) { - if (options) { - this.setOptions(options); - } - }, - - /** - * Sets filter's properties from options - * @param {Object} [options] Options object - */ - setOptions: function(options) { - for (var prop in options) { - this[prop] = options[prop]; - } - }, - - /** - * Compile this filter's shader program. - * - * @param {WebGLRenderingContext} gl The GL canvas context to use for shader compilation. - * @param {String} fragmentSource fragmentShader source for compilation - * @param {String} vertexSource vertexShader source for compilation - */ - createProgram: function(gl, fragmentSource, vertexSource) { - fragmentSource = fragmentSource || this.fragmentSource; - vertexSource = vertexSource || this.vertexSource; - if (fabric.webGlPrecision !== 'highp'){ - fragmentSource = fragmentSource.replace( - /precision highp float/g, - 'precision ' + fabric.webGlPrecision + ' float' - ); - } - var vertexShader = gl.createShader(gl.VERTEX_SHADER); - gl.shaderSource(vertexShader, vertexSource); - gl.compileShader(vertexShader); - if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) { - throw new Error( - // eslint-disable-next-line prefer-template - 'Vertex shader compile error for ' + this.type + ': ' + - gl.getShaderInfoLog(vertexShader) - ); - } - - var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); - gl.shaderSource(fragmentShader, fragmentSource); - gl.compileShader(fragmentShader); - if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { - throw new Error( - // eslint-disable-next-line prefer-template - 'Fragment shader compile error for ' + this.type + ': ' + - gl.getShaderInfoLog(fragmentShader) - ); - } - - var program = gl.createProgram(); - gl.attachShader(program, vertexShader); - gl.attachShader(program, fragmentShader); - gl.linkProgram(program); - if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { - throw new Error( - // eslint-disable-next-line prefer-template - 'Shader link error for "${this.type}" ' + - gl.getProgramInfoLog(program) - ); - } - - var attributeLocations = this.getAttributeLocations(gl, program); - var uniformLocations = this.getUniformLocations(gl, program) || { }; - uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW'); - uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH'); - return { - program: program, - attributeLocations: attributeLocations, - uniformLocations: uniformLocations - }; - }, - - /** - * Return a map of attribute names to WebGLAttributeLocation objects. - * - * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. - * @param {WebGLShaderProgram} program The shader program from which to take attribute locations. - * @returns {Object} A map of attribute names to attribute locations. - */ - getAttributeLocations: function(gl, program) { - return { - aPosition: gl.getAttribLocation(program, 'aPosition'), - }; - }, - - /** - * Return a map of uniform names to WebGLUniformLocation objects. - * - * Intended to be overridden by subclasses. - * - * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. - * @param {WebGLShaderProgram} program The shader program from which to take uniform locations. - * @returns {Object} A map of uniform names to uniform locations. - */ - getUniformLocations: function (/* gl, program */) { - // in case i do not need any special uniform i need to return an empty object - return { }; - }, - - /** - * Send attribute data from this filter to its shader program on the GPU. - * - * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. - * @param {Object} attributeLocations A map of shader attribute names to their locations. - */ - sendAttributeData: function(gl, attributeLocations, aPositionData) { - var attributeLocation = attributeLocations.aPosition; - var buffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - gl.enableVertexAttribArray(attributeLocation); - gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0); - gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW); - }, - - _setupFrameBuffer: function(options) { - var gl = options.context, width, height; - if (options.passes > 1) { - width = options.destinationWidth; - height = options.destinationHeight; - if (options.sourceWidth !== width || options.sourceHeight !== height) { - gl.deleteTexture(options.targetTexture); - options.targetTexture = options.filterBackend.createTexture(gl, width, height); - } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, - options.targetTexture, 0); - } - else { - // draw last filter on canvas and not to framebuffer. - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.finish(); - } - }, - - _swapTextures: function(options) { - options.passes--; - options.pass++; - var temp = options.targetTexture; - options.targetTexture = options.sourceTexture; - options.sourceTexture = temp; - }, - - /** - * Generic isNeutral implementation for one parameter based filters. - * Used only in image applyFilters to discard filters that will not have an effect - * on the image - * Other filters may need their own version ( ColorMatrix, HueRotation, gamma, ComposedFilter ) - * @param {Object} options - **/ - isNeutralState: function(/* options */) { - var main = this.mainParameter, - _class = fabric.Image.filters[this.type].prototype; - if (main) { - if (Array.isArray(_class[main])) { - for (var i = _class[main].length; i--;) { - if (this[main][i] !== _class[main][i]) { - return false; - } - } - return true; - } - else { - return _class[main] === this[main]; - } - } - else { - return false; - } - }, - - /** - * Apply this filter to the input image data provided. - * - * Determines whether to use WebGL or Canvas2D based on the options.webgl flag. - * - * @param {Object} options - * @param {Number} options.passes The number of filters remaining to be executed - * @param {Boolean} options.webgl Whether to use webgl to render the filter. - * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. - * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - applyTo: function(options) { - if (options.webgl) { - this._setupFrameBuffer(options); - this.applyToWebGL(options); - this._swapTextures(options); - } - else { - this.applyTo2d(options); - } - }, - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - if (!options.programCache.hasOwnProperty(this.type)) { - options.programCache[this.type] = this.createProgram(options.context); - } - return options.programCache[this.type]; - }, - - /** - * Apply this filter using webgl. - * - * @param {Object} options - * @param {Number} options.passes The number of filters remaining to be executed - * @param {Boolean} options.webgl Whether to use webgl to render the filter. - * @param {WebGLTexture} options.originalTexture The texture of the original input image. - * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. - * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - applyToWebGL: function(options) { - var gl = options.context; - var shader = this.retrieveShader(options); - if (options.pass === 0 && options.originalTexture) { - gl.bindTexture(gl.TEXTURE_2D, options.originalTexture); - } - else { - gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture); - } - gl.useProgram(shader.program); - this.sendAttributeData(gl, shader.attributeLocations, options.aPosition); - - gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth); - gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight); - - this.sendUniformData(gl, shader.uniformLocations); - gl.viewport(0, 0, options.destinationWidth, options.destinationHeight); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - }, - - bindAdditionalTexture: function(gl, texture, textureUnit) { - gl.activeTexture(textureUnit); - gl.bindTexture(gl.TEXTURE_2D, texture); - // reset active texture to 0 as usual - gl.activeTexture(gl.TEXTURE0); - }, - - unbindAdditionalTexture: function(gl, textureUnit) { - gl.activeTexture(textureUnit); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.activeTexture(gl.TEXTURE0); - }, - - getMainParameter: function() { - return this[this.mainParameter]; - }, - - setMainParameter: function(value) { - this[this.mainParameter] = value; - }, - - /** - * Send uniform data from this filter to its shader program on the GPU. - * - * Intended to be overridden by subclasses. - * - * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. - * @param {Object} uniformLocations A map of shader uniform names to their locations. - */ - sendUniformData: function(/* gl, uniformLocations */) { - // Intentionally left blank. Override me in subclasses. - }, - - /** - * If needed by a 2d filter, this functions can create an helper canvas to be used - * remember that options.targetCanvas is available for use till end of chain. - */ - createHelpLayer: function(options) { - if (!options.helpLayer) { - var helpLayer = document.createElement('canvas'); - helpLayer.width = options.sourceWidth; - helpLayer.height = options.sourceHeight; - options.helpLayer = helpLayer; - } - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - var object = { type: this.type }, mainP = this.mainParameter; - if (mainP) { - object[mainP] = this[mainP]; - } - return object; - }, - - /** - * Returns a JSON representation of an instance - * @return {Object} JSON - */ - toJSON: function() { - // delegate, not alias - return this.toObject(); - } -}); - -fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { - var filter = new fabric.Image.filters[object.type](object); - callback && callback(filter); - return filter; -}; - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Color Matrix filter class - * @class fabric.Image.filters.ColorMatrix - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.ColorMatrix#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @see {@Link http://www.webwasp.co.uk/tutorials/219/Color_Matrix_Filter.php} - * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl} - * @example Kodachrome filter - * var filter = new fabric.Image.filters.ColorMatrix({ - * matrix: [ - 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502, - -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203, - -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946, - 0, 0, 0, 1, 0 - ] - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.ColorMatrix = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.ColorMatrix.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'ColorMatrix', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'varying vec2 vTexCoord;\n' + - 'uniform mat4 uColorMatrix;\n' + - 'uniform vec4 uConstants;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'color *= uColorMatrix;\n' + - 'color += uConstants;\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * Colormatrix for pixels. - * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning - * outside the -1, 1 range. - * 0.0039215686 is the part of 1 that get translated to 1 in 2d - * @param {Array} matrix array of 20 numbers. - * @default - */ - matrix: [ - 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0 - ], - - mainParameter: 'matrix', - - /** - * Lock the colormatrix on the color part, skipping alpha, manly for non webgl scenario - * to save some calculation - */ - colorsOnly: true, - - /** - * Constructor - * @param {Object} [options] Options object - */ - initialize: function(options) { - this.callSuper('initialize', options); - // create a new array instead mutating the prototype with push - this.matrix = this.matrix.slice(0); - }, - - /** - * Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8Array to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, - iLen = data.length, - m = this.matrix, - r, g, b, a, i, colorsOnly = this.colorsOnly; - - for (i = 0; i < iLen; i += 4) { - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - if (colorsOnly) { - data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255; - data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255; - data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255; - } - else { - a = data[i + 3]; - data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4] * 255; - data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9] * 255; - data[i + 2] = r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14] * 255; - data[i + 3] = r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19] * 255; - } - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uColorMatrix: gl.getUniformLocation(program, 'uColorMatrix'), - uConstants: gl.getUniformLocation(program, 'uConstants'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - var m = this.matrix, - matrix = [ - m[0], m[1], m[2], m[3], - m[5], m[6], m[7], m[8], - m[10], m[11], m[12], m[13], - m[15], m[16], m[17], m[18] - ], - constants = [m[4], m[9], m[14], m[19]]; - gl.uniformMatrix4fv(uniformLocations.uColorMatrix, false, matrix); - gl.uniform4fv(uniformLocations.uConstants, constants); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] function to invoke after filter creation - * @return {fabric.Image.filters.ColorMatrix} Instance of fabric.Image.filters.ColorMatrix - */ - fabric.Image.filters.ColorMatrix.fromObject = fabric.Image.filters.BaseFilter.fromObject; -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Brightness filter class - * @class fabric.Image.filters.Brightness - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Brightness#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Brightness({ - * brightness: 0.05 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Brightness = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Brightness.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Brightness', - - /** - * Fragment source for the brightness program - */ - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uBrightness;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'color.rgb += uBrightness;\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * Brightness value, from -1 to 1. - * translated to -255 to 255 for 2d - * 0.0039215686 is the part of 1 that get translated to 1 in 2d - * @param {Number} brightness - * @default - */ - brightness: 0, - - /** - * Describe the property that is the filter parameter - * @param {String} m - * @default - */ - mainParameter: 'brightness', - - /** - * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - if (this.brightness === 0) { - return; - } - var imageData = options.imageData, - data = imageData.data, i, len = data.length, - brightness = Math.round(this.brightness * 255); - for (i = 0; i < len; i += 4) { - data[i] = data[i] + brightness; - data[i + 1] = data[i + 1] + brightness; - data[i + 2] = data[i + 2] + brightness; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uBrightness: gl.getUniformLocation(program, 'uBrightness'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uBrightness, this.brightness); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Brightness} Instance of fabric.Image.filters.Brightness - */ - fabric.Image.filters.Brightness.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Adapted from html5rocks article - * @class fabric.Image.filters.Convolute - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Convolute#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example Sharpen filter - * var filter = new fabric.Image.filters.Convolute({ - * matrix: [ 0, -1, 0, - * -1, 5, -1, - * 0, -1, 0 ] - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - * @example Blur filter - * var filter = new fabric.Image.filters.Convolute({ - * matrix: [ 1/9, 1/9, 1/9, - * 1/9, 1/9, 1/9, - * 1/9, 1/9, 1/9 ] - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - * @example Emboss filter - * var filter = new fabric.Image.filters.Convolute({ - * matrix: [ 1, 1, 1, - * 1, 0.7, -1, - * -1, -1, -1 ] - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - * @example Emboss filter with opaqueness - * var filter = new fabric.Image.filters.Convolute({ - * opaque: true, - * matrix: [ 1, 1, 1, - * 1, 0.7, -1, - * -1, -1, -1 ] - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - filters.Convolute = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Convolute.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Convolute', - - /* - * Opaque value (true/false) - */ - opaque: false, - - /* - * matrix for the filter, max 9x9 - */ - matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0], - - /** - * Fragment source for the brightness program - */ - fragmentSource: { - Convolute_3_1: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[9];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 0);\n' + - 'for (float h = 0.0; h < 3.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 3.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\n' + - 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\n' + - '}\n' + - '}\n' + - 'gl_FragColor = color;\n' + - '}', - Convolute_3_0: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[9];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 1);\n' + - 'for (float h = 0.0; h < 3.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 3.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\n' + - 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\n' + - '}\n' + - '}\n' + - 'float alpha = texture2D(uTexture, vTexCoord).a;\n' + - 'gl_FragColor = color;\n' + - 'gl_FragColor.a = alpha;\n' + - '}', - Convolute_5_1: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[25];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 0);\n' + - 'for (float h = 0.0; h < 5.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 5.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n' + - 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\n' + - '}\n' + - '}\n' + - 'gl_FragColor = color;\n' + - '}', - Convolute_5_0: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[25];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 1);\n' + - 'for (float h = 0.0; h < 5.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 5.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n' + - 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\n' + - '}\n' + - '}\n' + - 'float alpha = texture2D(uTexture, vTexCoord).a;\n' + - 'gl_FragColor = color;\n' + - 'gl_FragColor.a = alpha;\n' + - '}', - Convolute_7_1: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[49];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 0);\n' + - 'for (float h = 0.0; h < 7.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 7.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n' + - 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\n' + - '}\n' + - '}\n' + - 'gl_FragColor = color;\n' + - '}', - Convolute_7_0: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[49];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 1);\n' + - 'for (float h = 0.0; h < 7.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 7.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n' + - 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\n' + - '}\n' + - '}\n' + - 'float alpha = texture2D(uTexture, vTexCoord).a;\n' + - 'gl_FragColor = color;\n' + - 'gl_FragColor.a = alpha;\n' + - '}', - Convolute_9_1: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[81];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 0);\n' + - 'for (float h = 0.0; h < 9.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 9.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n' + - 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\n' + - '}\n' + - '}\n' + - 'gl_FragColor = color;\n' + - '}', - Convolute_9_0: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[81];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 1);\n' + - 'for (float h = 0.0; h < 9.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 9.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n' + - 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\n' + - '}\n' + - '}\n' + - 'float alpha = texture2D(uTexture, vTexCoord).a;\n' + - 'gl_FragColor = color;\n' + - 'gl_FragColor.a = alpha;\n' + - '}', - }, - - /** - * Constructor - * @memberOf fabric.Image.filters.Convolute.prototype - * @param {Object} [options] Options object - * @param {Boolean} [options.opaque=false] Opaque value (true/false) - * @param {Array} [options.matrix] Filter matrix - */ - - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - var size = Math.sqrt(this.matrix.length); - var cacheKey = this.type + '_' + size + '_' + (this.opaque ? 1 : 0); - var shaderSource = this.fragmentSource[cacheKey]; - if (!options.programCache.hasOwnProperty(cacheKey)) { - options.programCache[cacheKey] = this.createProgram(options.context, shaderSource); - } - return options.programCache[cacheKey]; - }, - - /** - * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, - weights = this.matrix, - side = Math.round(Math.sqrt(weights.length)), - halfSide = Math.floor(side / 2), - sw = imageData.width, - sh = imageData.height, - output = options.ctx.createImageData(sw, sh), - dst = output.data, - // go through the destination image pixels - alphaFac = this.opaque ? 1 : 0, - r, g, b, a, dstOff, - scx, scy, srcOff, wt, - x, y, cx, cy; - - for (y = 0; y < sh; y++) { - for (x = 0; x < sw; x++) { - dstOff = (y * sw + x) * 4; - // calculate the weighed sum of the source image pixels that - // fall under the convolution matrix - r = 0; g = 0; b = 0; a = 0; - - for (cy = 0; cy < side; cy++) { - for (cx = 0; cx < side; cx++) { - scy = y + cy - halfSide; - scx = x + cx - halfSide; - - // eslint-disable-next-line max-depth - if (scy < 0 || scy >= sh || scx < 0 || scx >= sw) { - continue; - } - - srcOff = (scy * sw + scx) * 4; - wt = weights[cy * side + cx]; - - r += data[srcOff] * wt; - g += data[srcOff + 1] * wt; - b += data[srcOff + 2] * wt; - // eslint-disable-next-line max-depth - if (!alphaFac) { - a += data[srcOff + 3] * wt; - } - } - } - dst[dstOff] = r; - dst[dstOff + 1] = g; - dst[dstOff + 2] = b; - if (!alphaFac) { - dst[dstOff + 3] = a; - } - else { - dst[dstOff + 3] = data[dstOff + 3]; - } - } - } - options.imageData = output; - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uMatrix: gl.getUniformLocation(program, 'uMatrix'), - uOpaque: gl.getUniformLocation(program, 'uOpaque'), - uHalfSize: gl.getUniformLocation(program, 'uHalfSize'), - uSize: gl.getUniformLocation(program, 'uSize'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1fv(uniformLocations.uMatrix, this.matrix); - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return extend(this.callSuper('toObject'), { - opaque: this.opaque, - matrix: this.matrix - }); - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Convolute} Instance of fabric.Image.filters.Convolute - */ - fabric.Image.filters.Convolute.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Grayscale image filter class - * @class fabric.Image.filters.Grayscale - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Grayscale(); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Grayscale = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Grayscale.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Grayscale', - - fragmentSource: { - average: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'float average = (color.r + color.b + color.g) / 3.0;\n' + - 'gl_FragColor = vec4(average, average, average, color.a);\n' + - '}', - lightness: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform int uMode;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 col = texture2D(uTexture, vTexCoord);\n' + - 'float average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\n' + - 'gl_FragColor = vec4(average, average, average, col.a);\n' + - '}', - luminosity: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform int uMode;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 col = texture2D(uTexture, vTexCoord);\n' + - 'float average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\n' + - 'gl_FragColor = vec4(average, average, average, col.a);\n' + - '}', - }, - - - /** - * Grayscale mode, between 'average', 'lightness', 'luminosity' - * @param {String} type - * @default - */ - mode: 'average', - - mainParameter: 'mode', - - /** - * Apply the Grayscale operation to a Uint8Array representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8Array to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, i, - len = data.length, value, - mode = this.mode; - for (i = 0; i < len; i += 4) { - if (mode === 'average') { - value = (data[i] + data[i + 1] + data[i + 2]) / 3; - } - else if (mode === 'lightness') { - value = (Math.min(data[i], data[i + 1], data[i + 2]) + - Math.max(data[i], data[i + 1], data[i + 2])) / 2; - } - else if (mode === 'luminosity') { - value = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2]; - } - data[i] = value; - data[i + 1] = value; - data[i + 2] = value; - } - }, - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - var cacheKey = this.type + '_' + this.mode; - if (!options.programCache.hasOwnProperty(cacheKey)) { - var shaderSource = this.fragmentSource[this.mode]; - options.programCache[cacheKey] = this.createProgram(options.context, shaderSource); - } - return options.programCache[cacheKey]; - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uMode: gl.getUniformLocation(program, 'uMode'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - // default average mode. - var mode = 1; - gl.uniform1i(uniformLocations.uMode, mode); - }, - - /** - * Grayscale filter isNeutralState implementation - * The filter is never neutral - * on the image - **/ - isNeutralState: function() { - return false; - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Grayscale} Instance of fabric.Image.filters.Grayscale - */ - fabric.Image.filters.Grayscale.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Invert filter class - * @class fabric.Image.filters.Invert - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Invert(); - * object.filters.push(filter); - * object.applyFilters(canvas.renderAll.bind(canvas)); - */ - filters.Invert = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Invert.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Invert', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform int uInvert;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'if (uInvert == 1) {\n' + - 'gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\n' + - '} else {\n' + - 'gl_FragColor = color;\n' + - '}\n' + - '}', - - /** - * Filter invert. if false, does nothing - * @param {Boolean} invert - * @default - */ - invert: true, - - mainParameter: 'invert', - - /** - * Apply the Invert operation to a Uint8Array representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8Array to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, i, - len = data.length; - for (i = 0; i < len; i += 4) { - data[i] = 255 - data[i]; - data[i + 1] = 255 - data[i + 1]; - data[i + 2] = 255 - data[i + 2]; - } - }, - - /** - * Invert filter isNeutralState implementation - * Used only in image applyFilters to discard filters that will not have an effect - * on the image - * @param {Object} options - **/ - isNeutralState: function() { - return !this.invert; - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uInvert: gl.getUniformLocation(program, 'uInvert'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1i(uniformLocations.uInvert, this.invert); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Invert} Instance of fabric.Image.filters.Invert - */ - fabric.Image.filters.Invert.fromObject = fabric.Image.filters.BaseFilter.fromObject; - - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Noise filter class - * @class fabric.Image.filters.Noise - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Noise#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Noise({ - * noise: 700 - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - filters.Noise = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Noise.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Noise', - - /** - * Fragment source for the noise program - */ - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uStepH;\n' + - 'uniform float uNoise;\n' + - 'uniform float uSeed;\n' + - 'varying vec2 vTexCoord;\n' + - 'float rand(vec2 co, float seed, float vScale) {\n' + - 'return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\n' + - '}\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * Describe the property that is the filter parameter - * @param {String} m - * @default - */ - mainParameter: 'noise', - - /** - * Noise value, from - * @param {Number} noise - * @default - */ - noise: 0, - - /** - * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - if (this.noise === 0) { - return; - } - var imageData = options.imageData, - data = imageData.data, i, len = data.length, - noise = this.noise, rand; - - for (i = 0, len = data.length; i < len; i += 4) { - - rand = (0.5 - Math.random()) * noise; - - data[i] += rand; - data[i + 1] += rand; - data[i + 2] += rand; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uNoise: gl.getUniformLocation(program, 'uNoise'), - uSeed: gl.getUniformLocation(program, 'uSeed'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uNoise, this.noise / 255); - gl.uniform1f(uniformLocations.uSeed, Math.random()); - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return extend(this.callSuper('toObject'), { - noise: this.noise - }); - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Noise} Instance of fabric.Image.filters.Noise - */ - fabric.Image.filters.Noise.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Pixelate filter class - * @class fabric.Image.filters.Pixelate - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Pixelate#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Pixelate({ - * blocksize: 8 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Pixelate = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Pixelate.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Pixelate', - - blocksize: 4, - - mainParameter: 'blocksize', - - /** - * Fragment source for the Pixelate program - */ - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uBlocksize;\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'float blockW = uBlocksize * uStepW;\n' + - 'float blockH = uBlocksize * uStepW;\n' + - 'int posX = int(vTexCoord.x / blockW);\n' + - 'int posY = int(vTexCoord.y / blockH);\n' + - 'float fposX = float(posX);\n' + - 'float fposY = float(posY);\n' + - 'vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\n' + - 'vec4 color = texture2D(uTexture, squareCoords);\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * Apply the Pixelate operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, - iLen = imageData.height, - jLen = imageData.width, - index, i, j, r, g, b, a, - _i, _j, _iLen, _jLen; - - for (i = 0; i < iLen; i += this.blocksize) { - for (j = 0; j < jLen; j += this.blocksize) { - - index = (i * 4) * jLen + (j * 4); - - r = data[index]; - g = data[index + 1]; - b = data[index + 2]; - a = data[index + 3]; - - _iLen = Math.min(i + this.blocksize, iLen); - _jLen = Math.min(j + this.blocksize, jLen); - for (_i = i; _i < _iLen; _i++) { - for (_j = j; _j < _jLen; _j++) { - index = (_i * 4) * jLen + (_j * 4); - data[index] = r; - data[index + 1] = g; - data[index + 2] = b; - data[index + 3] = a; - } - } - } - } - }, - - /** - * Indicate when the filter is not gonna apply changes to the image - **/ - isNeutralState: function() { - return this.blocksize === 1; - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uBlocksize: gl.getUniformLocation(program, 'uBlocksize'), - uStepW: gl.getUniformLocation(program, 'uStepW'), - uStepH: gl.getUniformLocation(program, 'uStepH'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uBlocksize, this.blocksize); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Pixelate} Instance of fabric.Image.filters.Pixelate - */ - fabric.Image.filters.Pixelate.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Remove white filter class - * @class fabric.Image.filters.RemoveColor - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.RemoveColor#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.RemoveColor({ - * threshold: 0.2, - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - filters.RemoveColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.RemoveColor.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'RemoveColor', - - /** - * Color to remove, in any format understood by fabric.Color. - * @param {String} type - * @default - */ - color: '#FFFFFF', - - /** - * Fragment source for the brightness program - */ - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform vec4 uLow;\n' + - 'uniform vec4 uHigh;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'gl_FragColor = texture2D(uTexture, vTexCoord);\n' + - 'if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\n' + - 'gl_FragColor.a = 0.0;\n' + - '}\n' + - '}', - - /** - * distance to actual color, as value up or down from each r,g,b - * between 0 and 1 - **/ - distance: 0.02, - - /** - * For color to remove inside distance, use alpha channel for a smoother deletion - * NOT IMPLEMENTED YET - **/ - useAlpha: false, - - /** - * Constructor - * @memberOf fabric.Image.filters.RemoveWhite.prototype - * @param {Object} [options] Options object - * @param {Number} [options.color=#RRGGBB] Threshold value - * @param {Number} [options.distance=10] Distance value - */ - - /** - * Applies filter to canvas element - * @param {Object} canvasEl Canvas element to apply filter to - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, i, - distance = this.distance * 255, - r, g, b, - source = new fabric.Color(this.color).getSource(), - lowC = [ - source[0] - distance, - source[1] - distance, - source[2] - distance, - ], - highC = [ - source[0] + distance, - source[1] + distance, - source[2] + distance, - ]; - - - for (i = 0; i < data.length; i += 4) { - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - - if (r > lowC[0] && - g > lowC[1] && - b > lowC[2] && - r < highC[0] && - g < highC[1] && - b < highC[2]) { - data[i + 3] = 0; - } - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uLow: gl.getUniformLocation(program, 'uLow'), - uHigh: gl.getUniformLocation(program, 'uHigh'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - var source = new fabric.Color(this.color).getSource(), - distance = parseFloat(this.distance), - lowC = [ - 0 + source[0] / 255 - distance, - 0 + source[1] / 255 - distance, - 0 + source[2] / 255 - distance, - 1 - ], - highC = [ - source[0] / 255 + distance, - source[1] / 255 + distance, - source[2] / 255 + distance, - 1 - ]; - gl.uniform4fv(uniformLocations.uLow, lowC); - gl.uniform4fv(uniformLocations.uHigh, highC); - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return extend(this.callSuper('toObject'), { - color: this.color, - distance: this.distance - }); - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.RemoveColor} Instance of fabric.Image.filters.RemoveWhite - */ - fabric.Image.filters.RemoveColor.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - var matrices = { - Brownie: [ - 0.59970,0.34553,-0.27082,0,0.186, - -0.03770,0.86095,0.15059,0,-0.1449, - 0.24113,-0.07441,0.44972,0,-0.02965, - 0,0,0,1,0 - ], - Vintage: [ - 0.62793,0.32021,-0.03965,0,0.03784, - 0.02578,0.64411,0.03259,0,0.02926, - 0.04660,-0.08512,0.52416,0,0.02023, - 0,0,0,1,0 - ], - Kodachrome: [ - 1.12855,-0.39673,-0.03992,0,0.24991, - -0.16404,1.08352,-0.05498,0,0.09698, - -0.16786,-0.56034,1.60148,0,0.13972, - 0,0,0,1,0 - ], - Technicolor: [ - 1.91252,-0.85453,-0.09155,0,0.04624, - -0.30878,1.76589,-0.10601,0,-0.27589, - -0.23110,-0.75018,1.84759,0,0.12137, - 0,0,0,1,0 - ], - Polaroid: [ - 1.438,-0.062,-0.062,0,0, - -0.122,1.378,-0.122,0,0, - -0.016,-0.016,1.483,0,0, - 0,0,0,1,0 - ], - Sepia: [ - 0.393, 0.769, 0.189, 0, 0, - 0.349, 0.686, 0.168, 0, 0, - 0.272, 0.534, 0.131, 0, 0, - 0, 0, 0, 1, 0 - ], - BlackWhite: [ - 1.5, 1.5, 1.5, 0, -1, - 1.5, 1.5, 1.5, 0, -1, - 1.5, 1.5, 1.5, 0, -1, - 0, 0, 0, 1, 0, - ] - }; - - for (var key in matrices) { - filters[key] = createClass(filters.ColorMatrix, /** @lends fabric.Image.filters.Sepia.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: key, - - /** - * Colormatrix for the effect - * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning - * outside the -1, 1 range. - * @param {Array} matrix array of 20 numbers. - * @default - */ - matrix: matrices[key], - - /** - * Lock the matrix export for this kind of static, parameter less filters. - */ - mainParameter: false, - /** - * Lock the colormatrix on the color part, skipping alpha - */ - colorsOnly: true, - - }); - fabric.Image.filters[key].fromObject = fabric.Image.filters.BaseFilter.fromObject; - } -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - 'use strict'; - - var fabric = global.fabric, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Color Blend filter class - * @class fabric.Image.filter.BlendColor - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @example - * var filter = new fabric.Image.filters.BlendColor({ - * color: '#000', - * mode: 'multiply' - * }); - * - * var filter = new fabric.Image.filters.BlendImage({ - * image: fabricImageObject, - * mode: 'multiply', - * alpha: 0.5 - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - - filters.BlendColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blend.prototype */ { - type: 'BlendColor', - - /** - * Color to make the blend operation with. default to a reddish color since black or white - * gives always strong result. - **/ - color: '#F95C63', - - /** - * Blend mode for the filter: one of multiply, add, diff, screen, subtract, - * darken, lighten, overlay, exclusion, tint. - **/ - mode: 'multiply', - - /** - * alpha value. represent the strength of the blend color operation. - **/ - alpha: 1, - - /** - * Fragment source for the Multiply program - */ - fragmentSource: { - multiply: 'gl_FragColor.rgb *= uColor.rgb;\n', - screen: 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\n', - add: 'gl_FragColor.rgb += uColor.rgb;\n', - diff: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\n', - subtract: 'gl_FragColor.rgb -= uColor.rgb;\n', - lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\n', - darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\n', - exclusion: 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\n', - overlay: 'if (uColor.r < 0.5) {\n' + - 'gl_FragColor.r *= 2.0 * uColor.r;\n' + - '} else {\n' + - 'gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n' + - '}\n' + - 'if (uColor.g < 0.5) {\n' + - 'gl_FragColor.g *= 2.0 * uColor.g;\n' + - '} else {\n' + - 'gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n' + - '}\n' + - 'if (uColor.b < 0.5) {\n' + - 'gl_FragColor.b *= 2.0 * uColor.b;\n' + - '} else {\n' + - 'gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n' + - '}\n', - tint: 'gl_FragColor.rgb *= (1.0 - uColor.a);\n' + - 'gl_FragColor.rgb += uColor.rgb;\n', - }, - - /** - * build the fragment source for the filters, joining the common part with - * the specific one. - * @param {String} mode the mode of the filter, a key of this.fragmentSource - * @return {String} the source to be compiled - * @private - */ - buildSource: function(mode) { - return 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform vec4 uColor;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'gl_FragColor = color;\n' + - 'if (color.a > 0.0) {\n' + - this.fragmentSource[mode] + - '}\n' + - '}'; - }, - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - var cacheKey = this.type + '_' + this.mode, shaderSource; - if (!options.programCache.hasOwnProperty(cacheKey)) { - shaderSource = this.buildSource(this.mode); - options.programCache[cacheKey] = this.createProgram(options.context, shaderSource); - } - return options.programCache[cacheKey]; - }, - - /** - * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, iLen = data.length, - tr, tg, tb, - r, g, b, - source, alpha1 = 1 - this.alpha; - - source = new fabric.Color(this.color).getSource(); - tr = source[0] * this.alpha; - tg = source[1] * this.alpha; - tb = source[2] * this.alpha; - - for (var i = 0; i < iLen; i += 4) { - - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - - switch (this.mode) { - case 'multiply': - data[i] = r * tr / 255; - data[i + 1] = g * tg / 255; - data[i + 2] = b * tb / 255; - break; - case 'screen': - data[i] = 255 - (255 - r) * (255 - tr) / 255; - data[i + 1] = 255 - (255 - g) * (255 - tg) / 255; - data[i + 2] = 255 - (255 - b) * (255 - tb) / 255; - break; - case 'add': - data[i] = r + tr; - data[i + 1] = g + tg; - data[i + 2] = b + tb; - break; - case 'diff': - case 'difference': - data[i] = Math.abs(r - tr); - data[i + 1] = Math.abs(g - tg); - data[i + 2] = Math.abs(b - tb); - break; - case 'subtract': - data[i] = r - tr; - data[i + 1] = g - tg; - data[i + 2] = b - tb; - break; - case 'darken': - data[i] = Math.min(r, tr); - data[i + 1] = Math.min(g, tg); - data[i + 2] = Math.min(b, tb); - break; - case 'lighten': - data[i] = Math.max(r, tr); - data[i + 1] = Math.max(g, tg); - data[i + 2] = Math.max(b, tb); - break; - case 'overlay': - data[i] = tr < 128 ? (2 * r * tr / 255) : (255 - 2 * (255 - r) * (255 - tr) / 255); - data[i + 1] = tg < 128 ? (2 * g * tg / 255) : (255 - 2 * (255 - g) * (255 - tg) / 255); - data[i + 2] = tb < 128 ? (2 * b * tb / 255) : (255 - 2 * (255 - b) * (255 - tb) / 255); - break; - case 'exclusion': - data[i] = tr + r - ((2 * tr * r) / 255); - data[i + 1] = tg + g - ((2 * tg * g) / 255); - data[i + 2] = tb + b - ((2 * tb * b) / 255); - break; - case 'tint': - data[i] = tr + r * alpha1; - data[i + 1] = tg + g * alpha1; - data[i + 2] = tb + b * alpha1; - } - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uColor: gl.getUniformLocation(program, 'uColor'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - var source = new fabric.Color(this.color).getSource(); - source[0] = this.alpha * source[0] / 255; - source[1] = this.alpha * source[1] / 255; - source[2] = this.alpha * source[2] / 255; - source[3] = this.alpha; - gl.uniform4fv(uniformLocations.uColor, source); - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return { - type: this.type, - color: this.color, - mode: this.mode, - alpha: this.alpha - }; - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.BlendColor} Instance of fabric.Image.filters.BlendColor - */ - fabric.Image.filters.BlendColor.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - 'use strict'; - - var fabric = global.fabric, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Image Blend filter class - * @class fabric.Image.filter.BlendImage - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @example - * var filter = new fabric.Image.filters.BlendColor({ - * color: '#000', - * mode: 'multiply' - * }); - * - * var filter = new fabric.Image.filters.BlendImage({ - * image: fabricImageObject, - * mode: 'multiply', - * alpha: 0.5 - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - - filters.BlendImage = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.BlendImage.prototype */ { - type: 'BlendImage', - - /** - * Color to make the blend operation with. default to a reddish color since black or white - * gives always strong result. - **/ - image: null, - - /** - * Blend mode for the filter: one of multiply, add, diff, screen, subtract, - * darken, lighten, overlay, exclusion, tint. - **/ - mode: 'multiply', - - /** - * alpha value. represent the strength of the blend image operation. - * not implemented. - **/ - alpha: 1, - - vertexSource: 'attribute vec2 aPosition;\n' + - 'varying vec2 vTexCoord;\n' + - 'varying vec2 vTexCoord2;\n' + - 'uniform mat3 uTransformMatrix;\n' + - 'void main() {\n' + - 'vTexCoord = aPosition;\n' + - 'vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\n' + - 'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n' + - '}', - - /** - * Fragment source for the Multiply program - */ - fragmentSource: { - multiply: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform sampler2D uImage;\n' + - 'uniform vec4 uColor;\n' + - 'varying vec2 vTexCoord;\n' + - 'varying vec2 vTexCoord2;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'vec4 color2 = texture2D(uImage, vTexCoord2);\n' + - 'color.rgba *= color2.rgba;\n' + - 'gl_FragColor = color;\n' + - '}', - mask: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform sampler2D uImage;\n' + - 'uniform vec4 uColor;\n' + - 'varying vec2 vTexCoord;\n' + - 'varying vec2 vTexCoord2;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'vec4 color2 = texture2D(uImage, vTexCoord2);\n' + - 'color.a = color2.a;\n' + - 'gl_FragColor = color;\n' + - '}', - }, - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - var cacheKey = this.type + '_' + this.mode; - var shaderSource = this.fragmentSource[this.mode]; - if (!options.programCache.hasOwnProperty(cacheKey)) { - options.programCache[cacheKey] = this.createProgram(options.context, shaderSource); - } - return options.programCache[cacheKey]; - }, - - applyToWebGL: function(options) { - // load texture to blend. - var gl = options.context, - texture = this.createTexture(options.filterBackend, this.image); - this.bindAdditionalTexture(gl, texture, gl.TEXTURE1); - this.callSuper('applyToWebGL', options); - this.unbindAdditionalTexture(gl, gl.TEXTURE1); - }, - - createTexture: function(backend, image) { - return backend.getCachedTexture(image.cacheKey, image._element); - }, - - /** - * Calculate a transformMatrix to adapt the image to blend over - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - calculateMatrix: function() { - var image = this.image, - width = image._element.width, - height = image._element.height; - return [ - 1 / image.scaleX, 0, 0, - 0, 1 / image.scaleY, 0, - -image.left / width, -image.top / height, 1 - ]; - }, - - /** - * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - resources = options.filterBackend.resources, - data = imageData.data, iLen = data.length, - width = imageData.width, - height = imageData.height, - tr, tg, tb, ta, - r, g, b, a, - canvas1, context, image = this.image, blendData; - - if (!resources.blendImage) { - resources.blendImage = fabric.util.createCanvasElement(); - } - canvas1 = resources.blendImage; - context = canvas1.getContext('2d'); - if (canvas1.width !== width || canvas1.height !== height) { - canvas1.width = width; - canvas1.height = height; - } - else { - context.clearRect(0, 0, width, height); - } - context.setTransform(image.scaleX, 0, 0, image.scaleY, image.left, image.top); - context.drawImage(image._element, 0, 0, width, height); - blendData = context.getImageData(0, 0, width, height).data; - for (var i = 0; i < iLen; i += 4) { - - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - a = data[i + 3]; - - tr = blendData[i]; - tg = blendData[i + 1]; - tb = blendData[i + 2]; - ta = blendData[i + 3]; - - switch (this.mode) { - case 'multiply': - data[i] = r * tr / 255; - data[i + 1] = g * tg / 255; - data[i + 2] = b * tb / 255; - data[i + 3] = a * ta / 255; - break; - case 'mask': - data[i + 3] = ta; - break; - } - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uTransformMatrix: gl.getUniformLocation(program, 'uTransformMatrix'), - uImage: gl.getUniformLocation(program, 'uImage'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - var matrix = this.calculateMatrix(); - gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1. - gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix); - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return { - type: this.type, - image: this.image && this.image.toObject(), - mode: this.mode, - alpha: this.alpha - }; - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} callback to be invoked after filter creation - * @return {fabric.Image.filters.BlendImage} Instance of fabric.Image.filters.BlendImage - */ - fabric.Image.filters.BlendImage.fromObject = function(object, callback) { - fabric.Image.fromObject(object.image, function(image) { - var options = fabric.util.object.clone(object); - options.image = image; - callback(new fabric.Image.filters.BlendImage(options)); - }); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), pow = Math.pow, floor = Math.floor, - sqrt = Math.sqrt, abs = Math.abs, round = Math.round, sin = Math.sin, - ceil = Math.ceil, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Resize image filter class - * @class fabric.Image.filters.Resize - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Resize(); - * object.filters.push(filter); - * object.applyFilters(canvas.renderAll.bind(canvas)); - */ - filters.Resize = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Resize.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Resize', - - /** - * Resize type - * for webgl resizeType is just lanczos, for canvas2d can be: - * bilinear, hermite, sliceHack, lanczos. - * @param {String} resizeType - * @default - */ - resizeType: 'hermite', - - /** - * Scale factor for resizing, x axis - * @param {Number} scaleX - * @default - */ - scaleX: 1, - - /** - * Scale factor for resizing, y axis - * @param {Number} scaleY - * @default - */ - scaleY: 1, - - /** - * LanczosLobes parameter for lanczos filter, valid for resizeType lanczos - * @param {Number} lanczosLobes - * @default - */ - lanczosLobes: 3, - - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uDelta: gl.getUniformLocation(program, 'uDelta'), - uTaps: gl.getUniformLocation(program, 'uTaps'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform2fv(uniformLocations.uDelta, this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height]); - gl.uniform1fv(uniformLocations.uTaps, this.taps); - }, - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - var filterWindow = this.getFilterWindow(), cacheKey = this.type + '_' + filterWindow; - if (!options.programCache.hasOwnProperty(cacheKey)) { - var fragmentShader = this.generateShader(filterWindow); - options.programCache[cacheKey] = this.createProgram(options.context, fragmentShader); - } - return options.programCache[cacheKey]; - }, - - getFilterWindow: function() { - var scale = this.tempScale; - return Math.ceil(this.lanczosLobes / scale); - }, - - getTaps: function() { - var lobeFunction = this.lanczosCreate(this.lanczosLobes), scale = this.tempScale, - filterWindow = this.getFilterWindow(), taps = new Array(filterWindow); - for (var i = 1; i <= filterWindow; i++) { - taps[i - 1] = lobeFunction(i * scale); - } - return taps; - }, - - /** - * Generate vertex and shader sources from the necessary steps numbers - * @param {Number} filterWindow - */ - generateShader: function(filterWindow) { - var offsets = new Array(filterWindow), - fragmentShader = this.fragmentSourceTOP, filterWindow; - - for (var i = 1; i <= filterWindow; i++) { - offsets[i - 1] = i + '.0 * uDelta'; - } - - fragmentShader += 'uniform float uTaps[' + filterWindow + '];\n'; - fragmentShader += 'void main() {\n'; - fragmentShader += ' vec4 color = texture2D(uTexture, vTexCoord);\n'; - fragmentShader += ' float sum = 1.0;\n'; - - offsets.forEach(function(offset, i) { - fragmentShader += ' color += texture2D(uTexture, vTexCoord + ' + offset + ') * uTaps[' + i + '];\n'; - fragmentShader += ' color += texture2D(uTexture, vTexCoord - ' + offset + ') * uTaps[' + i + '];\n'; - fragmentShader += ' sum += 2.0 * uTaps[' + i + '];\n'; - }); - fragmentShader += ' gl_FragColor = color / sum;\n'; - fragmentShader += '}'; - return fragmentShader; - }, - - fragmentSourceTOP: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform vec2 uDelta;\n' + - 'varying vec2 vTexCoord;\n', - - /** - * Apply the resize filter to the image - * Determines whether to use WebGL or Canvas2D based on the options.webgl flag. - * - * @param {Object} options - * @param {Number} options.passes The number of filters remaining to be executed - * @param {Boolean} options.webgl Whether to use webgl to render the filter. - * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. - * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - applyTo: function(options) { - if (options.webgl) { - options.passes++; - this.width = options.sourceWidth; - this.horizontal = true; - this.dW = Math.round(this.width * this.scaleX); - this.dH = options.sourceHeight; - this.tempScale = this.dW / this.width; - this.taps = this.getTaps(); - options.destinationWidth = this.dW; - this._setupFrameBuffer(options); - this.applyToWebGL(options); - this._swapTextures(options); - options.sourceWidth = options.destinationWidth; - - this.height = options.sourceHeight; - this.horizontal = false; - this.dH = Math.round(this.height * this.scaleY); - this.tempScale = this.dH / this.height; - this.taps = this.getTaps(); - options.destinationHeight = this.dH; - this._setupFrameBuffer(options); - this.applyToWebGL(options); - this._swapTextures(options); - options.sourceHeight = options.destinationHeight; - } - else { - this.applyTo2d(options); - } - }, - - isNeutralState: function() { - return this.scaleX === 1 && this.scaleY === 1; - }, - - lanczosCreate: function(lobes) { - return function(x) { - if (x >= lobes || x <= -lobes) { - return 0.0; - } - if (x < 1.19209290E-07 && x > -1.19209290E-07) { - return 1.0; - } - x *= Math.PI; - var xx = x / lobes; - return (sin(x) / x) * sin(xx) / xx; - }; - }, - - /** - * Applies filter to canvas element - * @memberOf fabric.Image.filters.Resize.prototype - * @param {Object} canvasEl Canvas element to apply filter to - * @param {Number} scaleX - * @param {Number} scaleY - */ - applyTo2d: function(options) { - var imageData = options.imageData, - scaleX = this.scaleX, - scaleY = this.scaleY; - - this.rcpScaleX = 1 / scaleX; - this.rcpScaleY = 1 / scaleY; - - var oW = imageData.width, oH = imageData.height, - dW = round(oW * scaleX), dH = round(oH * scaleY), - newData; - - if (this.resizeType === 'sliceHack') { - newData = this.sliceByTwo(options, oW, oH, dW, dH); - } - else if (this.resizeType === 'hermite') { - newData = this.hermiteFastResize(options, oW, oH, dW, dH); - } - else if (this.resizeType === 'bilinear') { - newData = this.bilinearFiltering(options, oW, oH, dW, dH); - } - else if (this.resizeType === 'lanczos') { - newData = this.lanczosResize(options, oW, oH, dW, dH); - } - options.imageData = newData; - }, - - /** - * Filter sliceByTwo - * @param {Object} canvasEl Canvas element to apply filter to - * @param {Number} oW Original Width - * @param {Number} oH Original Height - * @param {Number} dW Destination Width - * @param {Number} dH Destination Height - * @returns {ImageData} - */ - sliceByTwo: function(options, oW, oH, dW, dH) { - var imageData = options.imageData, - mult = 0.5, doneW = false, doneH = false, stepW = oW * mult, - stepH = oH * mult, resources = fabric.filterBackend.resources, - tmpCanvas, ctx, sX = 0, sY = 0, dX = oW, dY = 0; - if (!resources.sliceByTwo) { - resources.sliceByTwo = document.createElement('canvas'); - } - tmpCanvas = resources.sliceByTwo; - if (tmpCanvas.width < oW * 1.5 || tmpCanvas.height < oH) { - tmpCanvas.width = oW * 1.5; - tmpCanvas.height = oH; - } - ctx = tmpCanvas.getContext('2d'); - ctx.clearRect(0, 0, oW * 1.5, oH); - ctx.putImageData(imageData, 0, 0); - - dW = floor(dW); - dH = floor(dH); - - while (!doneW || !doneH) { - oW = stepW; - oH = stepH; - if (dW < floor(stepW * mult)) { - stepW = floor(stepW * mult); - } - else { - stepW = dW; - doneW = true; - } - if (dH < floor(stepH * mult)) { - stepH = floor(stepH * mult); - } - else { - stepH = dH; - doneH = true; - } - ctx.drawImage(tmpCanvas, sX, sY, oW, oH, dX, dY, stepW, stepH); - sX = dX; - sY = dY; - dY += stepH; - } - return ctx.getImageData(sX, sY, dW, dH); - }, - - /** - * Filter lanczosResize - * @param {Object} canvasEl Canvas element to apply filter to - * @param {Number} oW Original Width - * @param {Number} oH Original Height - * @param {Number} dW Destination Width - * @param {Number} dH Destination Height - * @returns {ImageData} - */ - lanczosResize: function(options, oW, oH, dW, dH) { - - function process(u) { - var v, i, weight, idx, a, red, green, - blue, alpha, fX, fY; - center.x = (u + 0.5) * ratioX; - icenter.x = floor(center.x); - for (v = 0; v < dH; v++) { - center.y = (v + 0.5) * ratioY; - icenter.y = floor(center.y); - a = 0; red = 0; green = 0; blue = 0; alpha = 0; - for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) { - if (i < 0 || i >= oW) { - continue; - } - fX = floor(1000 * abs(i - center.x)); - if (!cacheLanc[fX]) { - cacheLanc[fX] = { }; - } - for (var j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) { - if (j < 0 || j >= oH) { - continue; - } - fY = floor(1000 * abs(j - center.y)); - if (!cacheLanc[fX][fY]) { - cacheLanc[fX][fY] = lanczos(sqrt(pow(fX * rcpRatioX, 2) + pow(fY * rcpRatioY, 2)) / 1000); - } - weight = cacheLanc[fX][fY]; - if (weight > 0) { - idx = (j * oW + i) * 4; - a += weight; - red += weight * srcData[idx]; - green += weight * srcData[idx + 1]; - blue += weight * srcData[idx + 2]; - alpha += weight * srcData[idx + 3]; - } - } - } - idx = (v * dW + u) * 4; - destData[idx] = red / a; - destData[idx + 1] = green / a; - destData[idx + 2] = blue / a; - destData[idx + 3] = alpha / a; - } - - if (++u < dW) { - return process(u); - } - else { - return destImg; - } - } - - var srcData = options.imageData.data, - destImg = options.ctx.createImageData(dW, dH), - destData = destImg.data, - lanczos = this.lanczosCreate(this.lanczosLobes), - ratioX = this.rcpScaleX, ratioY = this.rcpScaleY, - rcpRatioX = 2 / this.rcpScaleX, rcpRatioY = 2 / this.rcpScaleY, - range2X = ceil(ratioX * this.lanczosLobes / 2), - range2Y = ceil(ratioY * this.lanczosLobes / 2), - cacheLanc = { }, center = { }, icenter = { }; - - return process(0); - }, - - /** - * bilinearFiltering - * @param {Object} canvasEl Canvas element to apply filter to - * @param {Number} oW Original Width - * @param {Number} oH Original Height - * @param {Number} dW Destination Width - * @param {Number} dH Destination Height - * @returns {ImageData} - */ - bilinearFiltering: function(options, oW, oH, dW, dH) { - var a, b, c, d, x, y, i, j, xDiff, yDiff, chnl, - color, offset = 0, origPix, ratioX = this.rcpScaleX, - ratioY = this.rcpScaleY, - w4 = 4 * (oW - 1), img = options.imageData, - pixels = img.data, destImage = options.ctx.createImageData(dW, dH), - destPixels = destImage.data; - for (i = 0; i < dH; i++) { - for (j = 0; j < dW; j++) { - x = floor(ratioX * j); - y = floor(ratioY * i); - xDiff = ratioX * j - x; - yDiff = ratioY * i - y; - origPix = 4 * (y * oW + x); - - for (chnl = 0; chnl < 4; chnl++) { - a = pixels[origPix + chnl]; - b = pixels[origPix + 4 + chnl]; - c = pixels[origPix + w4 + chnl]; - d = pixels[origPix + w4 + 4 + chnl]; - color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) + - c * yDiff * (1 - xDiff) + d * xDiff * yDiff; - destPixels[offset++] = color; - } - } - } - return destImage; - }, - - /** - * hermiteFastResize - * @param {Object} canvasEl Canvas element to apply filter to - * @param {Number} oW Original Width - * @param {Number} oH Original Height - * @param {Number} dW Destination Width - * @param {Number} dH Destination Height - * @returns {ImageData} - */ - hermiteFastResize: function(options, oW, oH, dW, dH) { - var ratioW = this.rcpScaleX, ratioH = this.rcpScaleY, - ratioWHalf = ceil(ratioW / 2), - ratioHHalf = ceil(ratioH / 2), - img = options.imageData, data = img.data, - img2 = options.ctx.createImageData(dW, dH), data2 = img2.data; - for (var j = 0; j < dH; j++) { - for (var i = 0; i < dW; i++) { - var x2 = (i + j * dW) * 4, weight = 0, weights = 0, weightsAlpha = 0, - gxR = 0, gxG = 0, gxB = 0, gxA = 0, centerY = (j + 0.5) * ratioH; - for (var yy = floor(j * ratioH); yy < (j + 1) * ratioH; yy++) { - var dy = abs(centerY - (yy + 0.5)) / ratioHHalf, - centerX = (i + 0.5) * ratioW, w0 = dy * dy; - for (var xx = floor(i * ratioW); xx < (i + 1) * ratioW; xx++) { - var dx = abs(centerX - (xx + 0.5)) / ratioWHalf, - w = sqrt(w0 + dx * dx); - /* eslint-disable max-depth */ - if (w > 1 && w < -1) { - continue; - } - //hermite filter - weight = 2 * w * w * w - 3 * w * w + 1; - if (weight > 0) { - dx = 4 * (xx + yy * oW); - //alpha - gxA += weight * data[dx + 3]; - weightsAlpha += weight; - //colors - if (data[dx + 3] < 255) { - weight = weight * data[dx + 3] / 250; - } - gxR += weight * data[dx]; - gxG += weight * data[dx + 1]; - gxB += weight * data[dx + 2]; - weights += weight; - } - /* eslint-enable max-depth */ - } - } - data2[x2] = gxR / weights; - data2[x2 + 1] = gxG / weights; - data2[x2 + 2] = gxB / weights; - data2[x2 + 3] = gxA / weightsAlpha; - } - } - return img2; - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return { - type: this.type, - scaleX: this.scaleX, - scaleY: this.scaleY, - resizeType: this.resizeType, - lanczosLobes: this.lanczosLobes - }; - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Resize} Instance of fabric.Image.filters.Resize - */ - fabric.Image.filters.Resize.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Contrast filter class - * @class fabric.Image.filters.Contrast - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Contrast#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Contrast({ - * contrast: 0.25 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Contrast = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Contrast.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Contrast', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uContrast;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\n' + - 'color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * contrast value, range from -1 to 1. - * @param {Number} contrast - * @default 0 - */ - contrast: 0, - - mainParameter: 'contrast', - - /** - * Constructor - * @memberOf fabric.Image.filters.Contrast.prototype - * @param {Object} [options] Options object - * @param {Number} [options.contrast=0] Value to contrast the image up (-1...1) - */ - - /** - * Apply the Contrast operation to a Uint8Array representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8Array to be filtered. - */ - applyTo2d: function(options) { - if (this.contrast === 0) { - return; - } - var imageData = options.imageData, i, len, - data = imageData.data, len = data.length, - contrast = Math.floor(this.contrast * 255), - contrastF = 259 * (contrast + 255) / (255 * (259 - contrast)); - - for (i = 0; i < len; i += 4) { - data[i] = contrastF * (data[i] - 128) + 128; - data[i + 1] = contrastF * (data[i + 1] - 128) + 128; - data[i + 2] = contrastF * (data[i + 2] - 128) + 128; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uContrast: gl.getUniformLocation(program, 'uContrast'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uContrast, this.contrast); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Contrast} Instance of fabric.Image.filters.Contrast - */ - fabric.Image.filters.Contrast.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Saturate filter class - * @class fabric.Image.filters.Saturation - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Saturation#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Saturation({ - * saturation: 100 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Saturation = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Saturation.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Saturation', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uSaturation;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'float rgMax = max(color.r, color.g);\n' + - 'float rgbMax = max(rgMax, color.b);\n' + - 'color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\n' + - 'color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\n' + - 'color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\n' + - 'gl_FragColor = color;\n' + - '}', - - saturation: 0, - - mainParameter: 'saturation', - - /** - * Constructor - * @memberOf fabric.Image.filters.Saturate.prototype - * @param {Object} [options] Options object - * @param {Number} [options.saturate=0] Value to saturate the image (-1...1) - */ - - /** - * Apply the Saturation operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - if (this.saturation === 0) { - return; - } - var imageData = options.imageData, - data = imageData.data, len = data.length, - adjust = -this.saturation, i, max; - - for (i = 0; i < len; i += 4) { - max = Math.max(data[i], data[i + 1], data[i + 2]); - data[i] += max !== data[i] ? (max - data[i]) * adjust : 0; - data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0; - data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uSaturation: gl.getUniformLocation(program, 'uSaturation'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uSaturation, -this.saturation); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Saturation} Instance of fabric.Image.filters.Saturate - */ - fabric.Image.filters.Saturation.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Blur filter class - * @class fabric.Image.filters.Blur - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Blur#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Blur({ - * blur: 0.5 - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - filters.Blur = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blur.prototype */ { - - type: 'Blur', - - /* -'gl_FragColor = vec4(0.0);', -'gl_FragColor += texture2D(texture, vTexCoord + -7 * uDelta)*0.0044299121055113265;', -'gl_FragColor += texture2D(texture, vTexCoord + -6 * uDelta)*0.00895781211794;', -'gl_FragColor += texture2D(texture, vTexCoord + -5 * uDelta)*0.0215963866053;', -'gl_FragColor += texture2D(texture, vTexCoord + -4 * uDelta)*0.0443683338718;', -'gl_FragColor += texture2D(texture, vTexCoord + -3 * uDelta)*0.0776744219933;', -'gl_FragColor += texture2D(texture, vTexCoord + -2 * uDelta)*0.115876621105;', -'gl_FragColor += texture2D(texture, vTexCoord + -1 * uDelta)*0.147308056121;', -'gl_FragColor += texture2D(texture, vTexCoord )*0.159576912161;', -'gl_FragColor += texture2D(texture, vTexCoord + 1 * uDelta)*0.147308056121;', -'gl_FragColor += texture2D(texture, vTexCoord + 2 * uDelta)*0.115876621105;', -'gl_FragColor += texture2D(texture, vTexCoord + 3 * uDelta)*0.0776744219933;', -'gl_FragColor += texture2D(texture, vTexCoord + 4 * uDelta)*0.0443683338718;', -'gl_FragColor += texture2D(texture, vTexCoord + 5 * uDelta)*0.0215963866053;', -'gl_FragColor += texture2D(texture, vTexCoord + 6 * uDelta)*0.00895781211794;', -'gl_FragColor += texture2D(texture, vTexCoord + 7 * uDelta)*0.0044299121055113265;', -*/ - - /* eslint-disable max-len */ - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform vec2 uDelta;\n' + - 'varying vec2 vTexCoord;\n' + - 'const float nSamples = 15.0;\n' + - 'vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\n' + - 'float random(vec3 scale) {\n' + - /* use the fragment position for a different seed per-pixel */ - 'return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\n' + - '}\n' + - 'void main() {\n' + - 'vec4 color = vec4(0.0);\n' + - 'float total = 0.0;\n' + - 'float offset = random(v3offset);\n' + - 'for (float t = -nSamples; t <= nSamples; t++) {\n' + - 'float percent = (t + offset - 0.5) / nSamples;\n' + - 'float weight = 1.0 - abs(percent);\n' + - 'color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\n' + - 'total += weight;\n' + - '}\n' + - 'gl_FragColor = color / total;\n' + - '}', - /* eslint-enable max-len */ - - /** - * blur value, in percentage of image dimensions. - * specific to keep the image blur constant at different resolutions - * range between 0 and 1. - */ - blur: 0, - - mainParameter: 'blur', - - applyTo: function(options) { - if (options.webgl) { - // this aspectRatio is used to give the same blur to vertical and horizontal - this.aspectRatio = options.sourceWidth / options.sourceHeight; - options.passes++; - this._setupFrameBuffer(options); - this.horizontal = true; - this.applyToWebGL(options); - this._swapTextures(options); - this._setupFrameBuffer(options); - this.horizontal = false; - this.applyToWebGL(options); - this._swapTextures(options); - } - else { - this.applyTo2d(options); - } - }, - - applyTo2d: function(options) { - // paint canvasEl with current image data. - //options.ctx.putImageData(options.imageData, 0, 0); - options.imageData = this.simpleBlur(options); - }, - - simpleBlur: function(options) { - var resources = options.filterBackend.resources, canvas1, canvas2, - width = options.imageData.width, - height = options.imageData.height; - - if (!resources.blurLayer1) { - resources.blurLayer1 = fabric.util.createCanvasElement(); - resources.blurLayer2 = fabric.util.createCanvasElement(); - } - canvas1 = resources.blurLayer1; - canvas2 = resources.blurLayer2; - if (canvas1.width !== width || canvas1.height !== height) { - canvas2.width = canvas1.width = width; - canvas2.height = canvas1.height = height; - } - var ctx1 = canvas1.getContext('2d'), - ctx2 = canvas2.getContext('2d'), - nSamples = 15, - random, percent, j, i, - blur = this.blur * 0.06 * 0.5; - - // load first canvas - ctx1.putImageData(options.imageData, 0, 0); - ctx2.clearRect(0, 0, width, height); - - for (i = -nSamples; i <= nSamples; i++) { - random = (Math.random() - 0.5) / 4; - percent = i / nSamples; - j = blur * percent * width + random; - ctx2.globalAlpha = 1 - Math.abs(percent); - ctx2.drawImage(canvas1, j, random); - ctx1.drawImage(canvas2, 0, 0); - ctx2.globalAlpha = 1; - ctx2.clearRect(0, 0, canvas2.width, canvas2.height); - } - for (i = -nSamples; i <= nSamples; i++) { - random = (Math.random() - 0.5) / 4; - percent = i / nSamples; - j = blur * percent * height + random; - ctx2.globalAlpha = 1 - Math.abs(percent); - ctx2.drawImage(canvas1, random, j); - ctx1.drawImage(canvas2, 0, 0); - ctx2.globalAlpha = 1; - ctx2.clearRect(0, 0, canvas2.width, canvas2.height); - } - options.ctx.drawImage(canvas1, 0, 0); - var newImageData = options.ctx.getImageData(0, 0, canvas1.width, canvas1.height); - ctx1.globalAlpha = 1; - ctx1.clearRect(0, 0, canvas1.width, canvas1.height); - return newImageData; - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - delta: gl.getUniformLocation(program, 'uDelta'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - var delta = this.chooseRightDelta(); - gl.uniform2fv(uniformLocations.delta, delta); - }, - - /** - * choose right value of image percentage to blur with - * @returns {Array} a numeric array with delta values - */ - chooseRightDelta: function() { - var blurScale = 1, delta = [0, 0], blur; - if (this.horizontal) { - if (this.aspectRatio > 1) { - // image is wide, i want to shrink radius horizontal - blurScale = 1 / this.aspectRatio; - } - } - else { - if (this.aspectRatio < 1) { - // image is tall, i want to shrink radius vertical - blurScale = this.aspectRatio; - } - } - blur = blurScale * this.blur * 0.12; - if (this.horizontal) { - delta[0] = blur; - } - else { - delta[1] = blur; - } - return delta; - }, - }); - - /** - * Deserialize a JSON definition of a BlurFilter into a concrete instance. - */ - filters.Blur.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Gamma filter class - * @class fabric.Image.filters.Gamma - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Gamma#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Gamma({ - * gamma: [1, 0.5, 2.1] - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Gamma = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Gamma.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Gamma', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform vec3 uGamma;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'vec3 correction = (1.0 / uGamma);\n' + - 'color.r = pow(color.r, correction.r);\n' + - 'color.g = pow(color.g, correction.g);\n' + - 'color.b = pow(color.b, correction.b);\n' + - 'gl_FragColor = color;\n' + - 'gl_FragColor.rgb *= color.a;\n' + - '}', - - /** - * Gamma array value, from 0.01 to 2.2. - * @param {Array} gamma - * @default - */ - gamma: [1, 1, 1], - - /** - * Describe the property that is the filter parameter - * @param {String} m - * @default - */ - mainParameter: 'gamma', - - /** - * Constructor - * @param {Object} [options] Options object - */ - initialize: function(options) { - this.gamma = [1, 1, 1]; - filters.BaseFilter.prototype.initialize.call(this, options); - }, - - /** - * Apply the Gamma operation to a Uint8Array representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8Array to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, data = imageData.data, - gamma = this.gamma, len = data.length, - rInv = 1 / gamma[0], gInv = 1 / gamma[1], - bInv = 1 / gamma[2], i; - - if (!this.rVals) { - // eslint-disable-next-line - this.rVals = new Uint8Array(256); - // eslint-disable-next-line - this.gVals = new Uint8Array(256); - // eslint-disable-next-line - this.bVals = new Uint8Array(256); - } - - // This is an optimization - pre-compute a look-up table for each color channel - // instead of performing these pow calls for each pixel in the image. - for (i = 0, len = 256; i < len; i++) { - this.rVals[i] = Math.pow(i / 255, rInv) * 255; - this.gVals[i] = Math.pow(i / 255, gInv) * 255; - this.bVals[i] = Math.pow(i / 255, bInv) * 255; - } - for (i = 0, len = data.length; i < len; i += 4) { - data[i] = this.rVals[data[i]]; - data[i + 1] = this.gVals[data[i + 1]]; - data[i + 2] = this.bVals[data[i + 2]]; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uGamma: gl.getUniformLocation(program, 'uGamma'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform3fv(uniformLocations.uGamma, this.gamma); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Gamma} Instance of fabric.Image.filters.Gamma - */ - fabric.Image.filters.Gamma.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * A container class that knows how to apply a sequence of filters to an input image. - */ - filters.Composed = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Composed.prototype */ { - - type: 'Composed', - - /** - * A non sparse array of filters to apply - */ - subFilters: [], - - /** - * Constructor - * @param {Object} [options] Options object - */ - initialize: function(options) { - this.callSuper('initialize', options); - // create a new array instead mutating the prototype with push - this.subFilters = this.subFilters.slice(0); - }, - - /** - * Apply this container's filters to the input image provided. - * - * @param {Object} options - * @param {Number} options.passes The number of filters remaining to be applied. - */ - applyTo: function(options) { - options.passes += this.subFilters.length - 1; - this.subFilters.forEach(function(filter) { - filter.applyTo(options); - }); - }, - - /** - * Serialize this filter into JSON. - * - * @returns {Object} A JSON representation of this filter. - */ - toObject: function() { - return fabric.util.object.extend(this.callSuper('toObject'), { - subFilters: this.subFilters.map(function(filter) { return filter.toObject(); }), - }); - }, - - isNeutralState: function() { - return !this.subFilters.some(function(filter) { return !filter.isNeutralState(); }); - } - }); - - /** - * Deserialize a JSON definition of a ComposedFilter into a concrete instance. - */ - fabric.Image.filters.Composed.fromObject = function(object, callback) { - var filters = object.subFilters || [], - subFilters = filters.map(function(filter) { - return new fabric.Image.filters[filter.type](filter); - }), - instance = new fabric.Image.filters.Composed({ subFilters: subFilters }); - callback && callback(instance); - return instance; - }; -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * HueRotation filter class - * @class fabric.Image.filters.HueRotation - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.HueRotation#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.HueRotation({ - * rotation: -0.5 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.HueRotation = createClass(filters.ColorMatrix, /** @lends fabric.Image.filters.HueRotation.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'HueRotation', - - /** - * HueRotation value, from -1 to 1. - * the unit is radians - * @param {Number} myParameter - * @default - */ - rotation: 0, - - /** - * Describe the property that is the filter parameter - * @param {String} m - * @default - */ - mainParameter: 'rotation', - - calculateMatrix: function() { - var rad = this.rotation * Math.PI, cos = fabric.util.cos(rad), sin = fabric.util.sin(rad), - aThird = 1 / 3, aThirdSqtSin = Math.sqrt(aThird) * sin, OneMinusCos = 1 - cos; - this.matrix = [ - 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0 - ]; - this.matrix[0] = cos + OneMinusCos / 3; - this.matrix[1] = aThird * OneMinusCos - aThirdSqtSin; - this.matrix[2] = aThird * OneMinusCos + aThirdSqtSin; - this.matrix[5] = aThird * OneMinusCos + aThirdSqtSin; - this.matrix[6] = cos + aThird * OneMinusCos; - this.matrix[7] = aThird * OneMinusCos - aThirdSqtSin; - this.matrix[10] = aThird * OneMinusCos - aThirdSqtSin; - this.matrix[11] = aThird * OneMinusCos + aThirdSqtSin; - this.matrix[12] = cos + aThird * OneMinusCos; - }, - - /** - * HueRotation isNeutralState implementation - * Used only in image applyFilters to discard filters that will not have an effect - * on the image - * @param {Object} options - **/ - isNeutralState: function(options) { - this.calculateMatrix(); - return filters.BaseFilter.prototype.isNeutralState.call(this, options); - }, - - /** - * Apply this filter to the input image data provided. - * - * Determines whether to use WebGL or Canvas2D based on the options.webgl flag. - * - * @param {Object} options - * @param {Number} options.passes The number of filters remaining to be executed - * @param {Boolean} options.webgl Whether to use webgl to render the filter. - * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. - * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - applyTo: function(options) { - this.calculateMatrix(); - filters.BaseFilter.prototype.applyTo.call(this, options); - }, - - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.HueRotation} Instance of fabric.Image.filters.HueRotation - */ - fabric.Image.filters.HueRotation.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - clone = fabric.util.object.clone; - - if (fabric.Text) { - fabric.warn('fabric.Text is already defined'); - return; - } - - var additionalProps = - ('fontFamily fontWeight fontSize text underline overline linethrough' + - ' textAlign fontStyle lineHeight textBackgroundColor charSpacing styles path').split(' '); - - /** - * Text class - * @class fabric.Text - * @extends fabric.Object - * @return {fabric.Text} thisArg - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text} - * @see {@link fabric.Text#initialize} for constructor definition - */ - fabric.Text = fabric.util.createClass(fabric.Object, /** @lends fabric.Text.prototype */ { - - /** - * Properties which when set cause object to change dimensions - * @type Array - * @private - */ - _dimensionAffectingProps: [ - 'fontSize', - 'fontWeight', - 'fontFamily', - 'fontStyle', - 'lineHeight', - 'text', - 'charSpacing', - 'textAlign', - 'styles', - 'path' - ], - - /** - * @private - */ - _reNewline: /\r?\n/, - - /** - * Use this regular expression to filter for whitespaces that is not a new line. - * Mostly used when text is 'justify' aligned. - * @private - */ - _reSpacesAndTabs: /[ \t\r]/g, - - /** - * Use this regular expression to filter for whitespace that is not a new line. - * Mostly used when text is 'justify' aligned. - * @private - */ - _reSpaceAndTab: /[ \t\r]/, - - /** - * Use this regular expression to filter consecutive groups of non spaces. - * Mostly used when text is 'justify' aligned. - * @private - */ - _reWords: /\S+/g, - - /** - * Type of an object - * @type String - * @default - */ - type: 'text', - - /** - * Font size (in pixels) - * @type Number - * @default - */ - fontSize: 40, - - /** - * Font weight (e.g. bold, normal, 400, 600, 800) - * @type {(Number|String)} - * @default - */ - fontWeight: 'normal', - - /** - * Font family - * @type String - * @default - */ - fontFamily: 'Times New Roman', - - /** - * Text decoration underline. - * @type Boolean - * @default - */ - underline: false, - - /** - * Text decoration overline. - * @type Boolean - * @default - */ - overline: false, - - /** - * Text decoration linethrough. - * @type Boolean - * @default - */ - linethrough: false, - - /** - * Text alignment. Possible values: "left", "center", "right", "justify", - * "justify-left", "justify-center" or "justify-right". - * @type String - * @default - */ - textAlign: 'left', - - /** - * Font style . Possible values: "", "normal", "italic" or "oblique". - * @type String - * @default - */ - fontStyle: 'normal', - - /** - * Line height - * @type Number - * @default - */ - lineHeight: 1.16, - - /** - * Superscript schema object (minimum overlap) - * @type {Object} - * @default - */ - superscript: { - size: 0.60, // fontSize factor - baseline: -0.35 // baseline-shift factor (upwards) - }, - - /** - * Subscript schema object (minimum overlap) - * @type {Object} - * @default - */ - subscript: { - size: 0.60, // fontSize factor - baseline: 0.11 // baseline-shift factor (downwards) - }, - - /** - * Background color of text lines - * @type String - * @default - */ - textBackgroundColor: '', - - /** - * List of properties to consider when checking if - * state of an object is changed ({@link fabric.Object#hasStateChanged}) - * as well as for history (undo/redo) purposes - * @type Array - */ - stateProperties: fabric.Object.prototype.stateProperties.concat(additionalProps), - - /** - * List of properties to consider when checking if cache needs refresh - * @type Array - */ - cacheProperties: fabric.Object.prototype.cacheProperties.concat(additionalProps), - - /** - * When defined, an object is rendered via stroke and this property specifies its color. - * Backwards incompatibility note: This property was named "strokeStyle" until v1.1.6 - * @type String - * @default - */ - stroke: null, - - /** - * Shadow object representing shadow of this shape. - * Backwards incompatibility note: This property was named "textShadow" (String) until v1.2.11 - * @type fabric.Shadow - * @default - */ - shadow: null, - - /** - * fabric.Path that the text can follow. - * This feature is in BETA. - * @type fabric.Path - * @default - */ - path: null, - - /** - * @private - */ - _fontSizeFraction: 0.222, - - /** - * @private - */ - offsets: { - underline: 0.10, - linethrough: -0.315, - overline: -0.88 - }, - - /** - * Text Line proportion to font Size (in pixels) - * @type Number - * @default - */ - _fontSizeMult: 1.13, - - /** - * additional space between characters - * expressed in thousands of em unit - * @type Number - * @default - */ - charSpacing: 0, - - /** - * Object containing character styles - top-level properties -> line numbers, - * 2nd-level properties - character numbers - * @type Object - * @default - */ - styles: null, - - /** - * Reference to a context to measure text char or couple of chars - * the cacheContext of the canvas will be used or a freshly created one if the object is not on canvas - * once created it will be referenced on fabric._measuringContext to avoid creating a canvas for every - * text object created. - * @type {CanvasRenderingContext2D} - * @default - */ - _measuringContext: null, - - /** - * Baseline shift, styles only, keep at 0 for the main text object - * @type {Number} - * @default - */ - deltaY: 0, - - /** - * WARNING: EXPERIMENTAL. NOT SUPPORTED YET - * determine the direction of the text. - * This has to be set manually together with textAlign and originX for proper - * experience. - * some interesting link for the future - * https://www.w3.org/International/questions/qa-bidi-unicode-controls - * @since 4.5.0 - * @type {String} 'ltr|rtl' - * @default - */ - direction: 'ltr', - - /** - * Array of properties that define a style unit (of 'styles'). - * @type {Array} - * @default - */ - _styleProperties: [ - 'stroke', - 'strokeWidth', - 'fill', - 'fontFamily', - 'fontSize', - 'fontWeight', - 'fontStyle', - 'underline', - 'overline', - 'linethrough', - 'deltaY', - 'textBackgroundColor', - ], - - /** - * contains characters bounding boxes - */ - __charBounds: [], - - /** - * use this size when measuring text. To avoid IE11 rounding errors - * @type {Number} - * @default - * @readonly - * @private - */ - CACHE_FONT_SIZE: 400, - - /** - * contains the min text width to avoid getting 0 - * @type {Number} - * @default - */ - MIN_TEXT_WIDTH: 2, - - /** - * Constructor - * @param {String} text Text string - * @param {Object} [options] Options object - * @return {fabric.Text} thisArg - */ - initialize: function(text, options) { - this.styles = options ? (options.styles || { }) : { }; - this.text = text; - this.__skipDimension = true; - this.callSuper('initialize', options); - if (this.path) { - this.setPathInfo(); - } - this.__skipDimension = false; - this.initDimensions(); - this.setCoords(); - this.setupState({ propertySet: '_dimensionAffectingProps' }); - }, - - /** - * If text has a path, it will add the extra information needed - * for path and text calculations - * @return {fabric.Text} thisArg - */ - setPathInfo: function() { - var path = this.path; - if (path) { - path.segmentsInfo = fabric.util.getPathSegmentsInfo(path.path); - } - }, - - /** - * Return a context for measurement of text string. - * if created it gets stored for reuse - * @param {String} text Text string - * @param {Object} [options] Options object - * @return {fabric.Text} thisArg - */ - getMeasuringContext: function() { - // if we did not return we have to measure something. - if (!fabric._measuringContext) { - fabric._measuringContext = this.canvas && this.canvas.contextCache || - fabric.util.createCanvasElement().getContext('2d'); - } - return fabric._measuringContext; - }, - - /** - * @private - * Divides text into lines of text and lines of graphemes. - */ - _splitText: function() { - var newLines = this._splitTextIntoLines(this.text); - this.textLines = newLines.lines; - this._textLines = newLines.graphemeLines; - this._unwrappedTextLines = newLines._unwrappedLines; - this._text = newLines.graphemeText; - return newLines; - }, - - /** - * Initialize or update text dimensions. - * Updates this.width and this.height with the proper values. - * Does not return dimensions. - */ - initDimensions: function() { - if (this.__skipDimension) { - return; - } - this._splitText(); - this._clearCache(); - if (this.path) { - this.width = this.path.width; - this.height = this.path.height; - } - else { - this.width = this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH; - this.height = this.calcTextHeight(); - } - if (this.textAlign.indexOf('justify') !== -1) { - // once text is measured we need to make space fatter to make justified text. - this.enlargeSpaces(); - } - this.saveState({ propertySet: '_dimensionAffectingProps' }); - }, - - /** - * Enlarge space boxes and shift the others - */ - enlargeSpaces: function() { - var diffSpace, currentLineWidth, numberOfSpaces, accumulatedSpace, line, charBound, spaces; - for (var i = 0, len = this._textLines.length; i < len; i++) { - if (this.textAlign !== 'justify' && (i === len - 1 || this.isEndOfWrapping(i))) { - continue; - } - accumulatedSpace = 0; - line = this._textLines[i]; - currentLineWidth = this.getLineWidth(i); - if (currentLineWidth < this.width && (spaces = this.textLines[i].match(this._reSpacesAndTabs))) { - numberOfSpaces = spaces.length; - diffSpace = (this.width - currentLineWidth) / numberOfSpaces; - for (var j = 0, jlen = line.length; j <= jlen; j++) { - charBound = this.__charBounds[i][j]; - if (this._reSpaceAndTab.test(line[j])) { - charBound.width += diffSpace; - charBound.kernedWidth += diffSpace; - charBound.left += accumulatedSpace; - accumulatedSpace += diffSpace; - } - else { - charBound.left += accumulatedSpace; - } - } - } - } - }, - - /** - * Detect if the text line is ended with an hard break - * text and itext do not have wrapping, return false - * @return {Boolean} - */ - isEndOfWrapping: function(lineIndex) { - return lineIndex === this._textLines.length - 1; - }, - - /** - * Detect if a line has a linebreak and so we need to account for it when moving - * and counting style. - * It return always for text and Itext. - * @return Number - */ - missingNewlineOffset: function() { - return 1; - }, - - /** - * Returns string representation of an instance - * @return {String} String representation of text object - */ - toString: function() { - return '#'; - }, - - /** - * Return the dimension and the zoom level needed to create a cache canvas - * big enough to host the object to be cached. - * @private - * @param {Object} dim.x width of object to be cached - * @param {Object} dim.y height of object to be cached - * @return {Object}.width width of canvas - * @return {Object}.height height of canvas - * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache - * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache - */ - _getCacheCanvasDimensions: function() { - var dims = this.callSuper('_getCacheCanvasDimensions'); - var fontSize = this.fontSize; - dims.width += fontSize * dims.zoomX; - dims.height += fontSize * dims.zoomY; - return dims; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - this._setTextStyles(ctx); - this._renderTextLinesBackground(ctx); - this._renderTextDecoration(ctx, 'underline'); - this._renderText(ctx); - this._renderTextDecoration(ctx, 'overline'); - this._renderTextDecoration(ctx, 'linethrough'); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderText: function(ctx) { - if (this.paintFirst === 'stroke') { - this._renderTextStroke(ctx); - this._renderTextFill(ctx); - } - else { - this._renderTextFill(ctx); - this._renderTextStroke(ctx); - } - }, - - /** - * Set the font parameter of the context with the object properties or with charStyle - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Object} [charStyle] object with font style properties - * @param {String} [charStyle.fontFamily] Font Family - * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix ) - * @param {String} [charStyle.fontWeight] Font weight - * @param {String} [charStyle.fontStyle] Font style (italic|normal) - */ - _setTextStyles: function(ctx, charStyle, forMeasuring) { - ctx.textBaseline = 'alphabetic'; - ctx.font = this._getFontDeclaration(charStyle, forMeasuring); - }, - - /** - * calculate and return the text Width measuring each line. - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @return {Number} Maximum width of fabric.Text object - */ - calcTextWidth: function() { - var maxWidth = this.getLineWidth(0); - - for (var i = 1, len = this._textLines.length; i < len; i++) { - var currentLineWidth = this.getLineWidth(i); - if (currentLineWidth > maxWidth) { - maxWidth = currentLineWidth; - } - } - return maxWidth; - }, - - /** - * @private - * @param {String} method Method name ("fillText" or "strokeText") - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {String} line Text to render - * @param {Number} left Left position of text - * @param {Number} top Top position of text - * @param {Number} lineIndex Index of a line in a text - */ - _renderTextLine: function(method, ctx, line, left, top, lineIndex) { - this._renderChars(method, ctx, line, left, top, lineIndex); - }, - - /** - * Renders the text background for lines, taking care of style - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderTextLinesBackground: function(ctx) { - if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) { - return; - } - var heightOfLine, - lineLeftOffset, originalFill = ctx.fillStyle, - line, lastColor, - leftOffset = this._getLeftOffset(), - lineTopOffset = this._getTopOffset(), - boxStart = 0, boxWidth = 0, charBox, currentColor, path = this.path, - drawStart; - - for (var i = 0, len = this._textLines.length; i < len; i++) { - heightOfLine = this.getHeightOfLine(i); - if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor', i)) { - lineTopOffset += heightOfLine; - continue; - } - line = this._textLines[i]; - lineLeftOffset = this._getLineLeftOffset(i); - boxWidth = 0; - boxStart = 0; - lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor'); - for (var j = 0, jlen = line.length; j < jlen; j++) { - charBox = this.__charBounds[i][j]; - currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor'); - if (path) { - ctx.save(); - ctx.translate(charBox.renderLeft, charBox.renderTop); - ctx.rotate(charBox.angle); - ctx.fillStyle = currentColor; - currentColor && ctx.fillRect( - -charBox.width / 2, - -heightOfLine / this.lineHeight * (1 - this._fontSizeFraction), - charBox.width, - heightOfLine / this.lineHeight - ); - ctx.restore(); - } - else if (currentColor !== lastColor) { - drawStart = leftOffset + lineLeftOffset + boxStart; - if (this.direction === 'rtl') { - drawStart = this.width - drawStart - boxWidth; - } - ctx.fillStyle = lastColor; - lastColor && ctx.fillRect( - drawStart, - lineTopOffset, - boxWidth, - heightOfLine / this.lineHeight - ); - boxStart = charBox.left; - boxWidth = charBox.width; - lastColor = currentColor; - } - else { - boxWidth += charBox.kernedWidth; - } - } - if (currentColor && !path) { - drawStart = leftOffset + lineLeftOffset + boxStart; - if (this.direction === 'rtl') { - drawStart = this.width - drawStart - boxWidth; - } - ctx.fillStyle = currentColor; - ctx.fillRect( - drawStart, - lineTopOffset, - boxWidth, - heightOfLine / this.lineHeight - ); - } - lineTopOffset += heightOfLine; - } - ctx.fillStyle = originalFill; - // if there is text background color no - // other shadows should be casted - this._removeShadow(ctx); - }, - - /** - * @private - * @param {Object} decl style declaration for cache - * @param {String} decl.fontFamily fontFamily - * @param {String} decl.fontStyle fontStyle - * @param {String} decl.fontWeight fontWeight - * @return {Object} reference to cache - */ - getFontCache: function(decl) { - var fontFamily = decl.fontFamily.toLowerCase(); - if (!fabric.charWidthsCache[fontFamily]) { - fabric.charWidthsCache[fontFamily] = { }; - } - var cache = fabric.charWidthsCache[fontFamily], - cacheProp = decl.fontStyle.toLowerCase() + '_' + (decl.fontWeight + '').toLowerCase(); - if (!cache[cacheProp]) { - cache[cacheProp] = { }; - } - return cache[cacheProp]; - }, - - /** - * measure and return the width of a single character. - * possibly overridden to accommodate different measure logic or - * to hook some external lib for character measurement - * @private - * @param {String} _char, char to be measured - * @param {Object} charStyle style of char to be measured - * @param {String} [previousChar] previous char - * @param {Object} [prevCharStyle] style of previous char - */ - _measureChar: function(_char, charStyle, previousChar, prevCharStyle) { - // first i try to return from cache - var fontCache = this.getFontCache(charStyle), fontDeclaration = this._getFontDeclaration(charStyle), - previousFontDeclaration = this._getFontDeclaration(prevCharStyle), couple = previousChar + _char, - stylesAreEqual = fontDeclaration === previousFontDeclaration, width, coupleWidth, previousWidth, - fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE, kernedWidth; - - if (previousChar && fontCache[previousChar] !== undefined) { - previousWidth = fontCache[previousChar]; - } - if (fontCache[_char] !== undefined) { - kernedWidth = width = fontCache[_char]; - } - if (stylesAreEqual && fontCache[couple] !== undefined) { - coupleWidth = fontCache[couple]; - kernedWidth = coupleWidth - previousWidth; - } - if (width === undefined || previousWidth === undefined || coupleWidth === undefined) { - var ctx = this.getMeasuringContext(); - // send a TRUE to specify measuring font size CACHE_FONT_SIZE - this._setTextStyles(ctx, charStyle, true); - } - if (width === undefined) { - kernedWidth = width = ctx.measureText(_char).width; - fontCache[_char] = width; - } - if (previousWidth === undefined && stylesAreEqual && previousChar) { - previousWidth = ctx.measureText(previousChar).width; - fontCache[previousChar] = previousWidth; - } - if (stylesAreEqual && coupleWidth === undefined) { - // we can measure the kerning couple and subtract the width of the previous character - coupleWidth = ctx.measureText(couple).width; - fontCache[couple] = coupleWidth; - kernedWidth = coupleWidth - previousWidth; - } - return { width: width * fontMultiplier, kernedWidth: kernedWidth * fontMultiplier }; - }, - - /** - * Computes height of character at given position - * @param {Number} line the line index number - * @param {Number} _char the character index number - * @return {Number} fontSize of the character - */ - getHeightOfChar: function(line, _char) { - return this.getValueOfPropertyAt(line, _char, 'fontSize'); - }, - - /** - * measure a text line measuring all characters. - * @param {Number} lineIndex line number - * @return {Number} Line width - */ - measureLine: function(lineIndex) { - var lineInfo = this._measureLine(lineIndex); - if (this.charSpacing !== 0) { - lineInfo.width -= this._getWidthOfCharSpacing(); - } - if (lineInfo.width < 0) { - lineInfo.width = 0; - } - return lineInfo; - }, - - /** - * measure every grapheme of a line, populating __charBounds - * @param {Number} lineIndex - * @return {Object} object.width total width of characters - * @return {Object} object.widthOfSpaces length of chars that match this._reSpacesAndTabs - */ - _measureLine: function(lineIndex) { - var width = 0, i, grapheme, line = this._textLines[lineIndex], prevGrapheme, - graphemeInfo, numOfSpaces = 0, lineBounds = new Array(line.length), - positionInPath = 0, startingPoint, totalPathLength, path = this.path; - - this.__charBounds[lineIndex] = lineBounds; - if (path) { - startingPoint = fabric.util.getPointOnPath(path.path, 0, path.segmentsInfo); - totalPathLength = path.segmentsInfo[path.segmentsInfo.length - 1].length; - startingPoint.x += path.pathOffset.x; - startingPoint.y += path.pathOffset.y; - } - for (i = 0; i < line.length; i++) { - grapheme = line[i]; - graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme); - if (path) { - if (positionInPath > totalPathLength) { - positionInPath %= totalPathLength; - } - // it would probably much fater to send all the grapheme position for a line - // and calculate path position/angle at once. - this._setGraphemeOnPath(positionInPath, graphemeInfo, startingPoint); - } - lineBounds[i] = graphemeInfo; - width += graphemeInfo.kernedWidth; - positionInPath += graphemeInfo.kernedWidth; - prevGrapheme = grapheme; - } - // this latest bound box represent the last character of the line - // to simplify cursor handling in interactive mode. - lineBounds[i] = { - left: graphemeInfo ? graphemeInfo.left + graphemeInfo.width : 0, - width: 0, - kernedWidth: 0, - height: this.fontSize - }; - return { width: width, numOfSpaces: numOfSpaces }; - }, - - /** - * Calculate the angle and the left,top position of the char that follow a path. - * It appends it to graphemeInfo to be reused later at rendering - * @private - * @param {Number} positionInPath to be measured - * @param {Object} graphemeInfo current grapheme box information - * @param {Object} startingPoint position of the point - */ - _setGraphemeOnPath: function(positionInPath, graphemeInfo, startingPoint) { - var centerPosition = positionInPath + graphemeInfo.kernedWidth / 2, - path = this.path; - - // we are at currentPositionOnPath. we want to know what point on the path is. - var info = fabric.util.getPointOnPath(path.path, centerPosition, path.segmentsInfo); - graphemeInfo.renderLeft = info.x - startingPoint.x; - graphemeInfo.renderTop = info.y - startingPoint.y; - graphemeInfo.angle = info.angle; - }, - - /** - * Measure and return the info of a single grapheme. - * needs the the info of previous graphemes already filled - * @private - * @param {String} grapheme to be measured - * @param {Number} lineIndex index of the line where the char is - * @param {Number} charIndex position in the line - * @param {String} [prevGrapheme] character preceding the one to be measured - */ - _getGraphemeBox: function(grapheme, lineIndex, charIndex, prevGrapheme, skipLeft) { - var style = this.getCompleteStyleDeclaration(lineIndex, charIndex), - prevStyle = prevGrapheme ? this.getCompleteStyleDeclaration(lineIndex, charIndex - 1) : { }, - info = this._measureChar(grapheme, style, prevGrapheme, prevStyle), - kernedWidth = info.kernedWidth, - width = info.width, charSpacing; - - if (this.charSpacing !== 0) { - charSpacing = this._getWidthOfCharSpacing(); - width += charSpacing; - kernedWidth += charSpacing; - } - - var box = { - width: width, - left: 0, - height: style.fontSize, - kernedWidth: kernedWidth, - deltaY: style.deltaY, - }; - if (charIndex > 0 && !skipLeft) { - var previousBox = this.__charBounds[lineIndex][charIndex - 1]; - box.left = previousBox.left + previousBox.width + info.kernedWidth - info.width; - } - return box; - }, - - /** - * Calculate height of line at 'lineIndex' - * @param {Number} lineIndex index of line to calculate - * @return {Number} - */ - getHeightOfLine: function(lineIndex) { - if (this.__lineHeights[lineIndex]) { - return this.__lineHeights[lineIndex]; - } - - var line = this._textLines[lineIndex], - // char 0 is measured before the line cycle because it nneds to char - // emptylines - maxHeight = this.getHeightOfChar(lineIndex, 0); - for (var i = 1, len = line.length; i < len; i++) { - maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight); - } - - return this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult; - }, - - /** - * Calculate text box height - */ - calcTextHeight: function() { - var lineHeight, height = 0; - for (var i = 0, len = this._textLines.length; i < len; i++) { - lineHeight = this.getHeightOfLine(i); - height += (i === len - 1 ? lineHeight / this.lineHeight : lineHeight); - } - return height; - }, - - /** - * @private - * @return {Number} Left offset - */ - _getLeftOffset: function() { - return this.direction === 'ltr' ? -this.width / 2 : this.width / 2; - }, - - /** - * @private - * @return {Number} Top offset - */ - _getTopOffset: function() { - return -this.height / 2; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {String} method Method name ("fillText" or "strokeText") - */ - _renderTextCommon: function(ctx, method) { - ctx.save(); - var lineHeights = 0, left = this._getLeftOffset(), top = this._getTopOffset(); - for (var i = 0, len = this._textLines.length; i < len; i++) { - var heightOfLine = this.getHeightOfLine(i), - maxHeight = heightOfLine / this.lineHeight, - leftOffset = this._getLineLeftOffset(i); - this._renderTextLine( - method, - ctx, - this._textLines[i], - left + leftOffset, - top + lineHeights + maxHeight, - i - ); - lineHeights += heightOfLine; - } - ctx.restore(); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderTextFill: function(ctx) { - if (!this.fill && !this.styleHas('fill')) { - return; - } - - this._renderTextCommon(ctx, 'fillText'); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderTextStroke: function(ctx) { - if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) { - return; - } - - if (this.shadow && !this.shadow.affectStroke) { - this._removeShadow(ctx); - } - - ctx.save(); - this._setLineDash(ctx, this.strokeDashArray); - ctx.beginPath(); - this._renderTextCommon(ctx, 'strokeText'); - ctx.closePath(); - ctx.restore(); - }, - - /** - * @private - * @param {String} method fillText or strokeText. - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Array} line Content of the line, splitted in an array by grapheme - * @param {Number} left - * @param {Number} top - * @param {Number} lineIndex - */ - _renderChars: function(method, ctx, line, left, top, lineIndex) { - // set proper line offset - var lineHeight = this.getHeightOfLine(lineIndex), - isJustify = this.textAlign.indexOf('justify') !== -1, - actualStyle, - nextStyle, - charsToRender = '', - charBox, - boxWidth = 0, - timeToRender, - path = this.path, - shortCut = !isJustify && this.charSpacing === 0 && this.isEmptyStyles(lineIndex) && !path, - isLtr = this.direction === 'ltr', sign = this.direction === 'ltr' ? 1 : -1, - drawingLeft; - - ctx.save(); - top -= lineHeight * this._fontSizeFraction / this.lineHeight; - if (shortCut) { - // render all the line in one pass without checking - // drawingLeft = isLtr ? left : left - this.getLineWidth(lineIndex); - ctx.canvas.setAttribute('dir', isLtr ? 'ltr' : 'rtl'); - ctx.direction = isLtr ? 'ltr' : 'rtl'; - ctx.textAlign = isLtr ? 'left' : 'right'; - this._renderChar(method, ctx, lineIndex, 0, line.join(''), left, top, lineHeight); - ctx.restore(); - return; - } - for (var i = 0, len = line.length - 1; i <= len; i++) { - timeToRender = i === len || this.charSpacing || path; - charsToRender += line[i]; - charBox = this.__charBounds[lineIndex][i]; - if (boxWidth === 0) { - left += sign * (charBox.kernedWidth - charBox.width); - boxWidth += charBox.width; - } - else { - boxWidth += charBox.kernedWidth; - } - if (isJustify && !timeToRender) { - if (this._reSpaceAndTab.test(line[i])) { - timeToRender = true; - } - } - if (!timeToRender) { - // if we have charSpacing, we render char by char - actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i); - nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1); - timeToRender = this._hasStyleChanged(actualStyle, nextStyle); - } - if (timeToRender) { - if (path) { - ctx.save(); - ctx.translate(charBox.renderLeft, charBox.renderTop); - ctx.rotate(charBox.angle); - this._renderChar(method, ctx, lineIndex, i, charsToRender, -boxWidth / 2, 0, lineHeight); - ctx.restore(); - } - else { - drawingLeft = left; - ctx.canvas.setAttribute('dir', isLtr ? 'ltr' : 'rtl'); - ctx.direction = isLtr ? 'ltr' : 'rtl'; - ctx.textAlign = isLtr ? 'left' : 'right'; - this._renderChar(method, ctx, lineIndex, i, charsToRender, drawingLeft, top, lineHeight); - } - charsToRender = ''; - actualStyle = nextStyle; - left += sign * boxWidth; - boxWidth = 0; - } - } - ctx.restore(); - }, - - /** - * This function try to patch the missing gradientTransform on canvas gradients. - * transforming a context to transform the gradient, is going to transform the stroke too. - * we want to transform the gradient but not the stroke operation, so we create - * a transformed gradient on a pattern and then we use the pattern instead of the gradient. - * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size - * is limited. - * @private - * @param {fabric.Gradient} filler a fabric gradient instance - * @return {CanvasPattern} a pattern to use as fill/stroke style - */ - _applyPatternGradientTransformText: function(filler) { - var pCanvas = fabric.util.createCanvasElement(), pCtx, - // TODO: verify compatibility with strokeUniform - width = this.width + this.strokeWidth, height = this.height + this.strokeWidth; - pCanvas.width = width; - pCanvas.height = height; - pCtx = pCanvas.getContext('2d'); - pCtx.beginPath(); pCtx.moveTo(0, 0); pCtx.lineTo(width, 0); pCtx.lineTo(width, height); - pCtx.lineTo(0, height); pCtx.closePath(); - pCtx.translate(width / 2, height / 2); - pCtx.fillStyle = filler.toLive(pCtx); - this._applyPatternGradientTransform(pCtx, filler); - pCtx.fill(); - return pCtx.createPattern(pCanvas, 'no-repeat'); - }, - - handleFiller: function(ctx, property, filler) { - var offsetX, offsetY; - if (filler.toLive) { - if (filler.gradientUnits === 'percentage' || filler.gradientTransform || filler.patternTransform) { - // need to transform gradient in a pattern. - // this is a slow process. If you are hitting this codepath, and the object - // is not using caching, you should consider switching it on. - // we need a canvas as big as the current object caching canvas. - offsetX = -this.width / 2; - offsetY = -this.height / 2; - ctx.translate(offsetX, offsetY); - ctx[property] = this._applyPatternGradientTransformText(filler); - return { offsetX: offsetX, offsetY: offsetY }; - } - else { - // is a simple gradient or pattern - ctx[property] = filler.toLive(ctx, this); - return this._applyPatternGradientTransform(ctx, filler); - } - } - else { - // is a color - ctx[property] = filler; - } - return { offsetX: 0, offsetY: 0 }; - }, - - _setStrokeStyles: function(ctx, decl) { - ctx.lineWidth = decl.strokeWidth; - ctx.lineCap = this.strokeLineCap; - ctx.lineDashOffset = this.strokeDashOffset; - ctx.lineJoin = this.strokeLineJoin; - ctx.miterLimit = this.strokeMiterLimit; - return this.handleFiller(ctx, 'strokeStyle', decl.stroke); - }, - - _setFillStyles: function(ctx, decl) { - return this.handleFiller(ctx, 'fillStyle', decl.fill); - }, - - /** - * @private - * @param {String} method - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Number} lineIndex - * @param {Number} charIndex - * @param {String} _char - * @param {Number} left Left coordinate - * @param {Number} top Top coordinate - * @param {Number} lineHeight Height of the line - */ - _renderChar: function(method, ctx, lineIndex, charIndex, _char, left, top) { - var decl = this._getStyleDeclaration(lineIndex, charIndex), - fullDecl = this.getCompleteStyleDeclaration(lineIndex, charIndex), - shouldFill = method === 'fillText' && fullDecl.fill, - shouldStroke = method === 'strokeText' && fullDecl.stroke && fullDecl.strokeWidth, - fillOffsets, strokeOffsets; - - if (!shouldStroke && !shouldFill) { - return; - } - ctx.save(); - - shouldFill && (fillOffsets = this._setFillStyles(ctx, fullDecl)); - shouldStroke && (strokeOffsets = this._setStrokeStyles(ctx, fullDecl)); - - ctx.font = this._getFontDeclaration(fullDecl); - - - if (decl && decl.textBackgroundColor) { - this._removeShadow(ctx); - } - if (decl && decl.deltaY) { - top += decl.deltaY; - } - shouldFill && ctx.fillText(_char, left - fillOffsets.offsetX, top - fillOffsets.offsetY); - shouldStroke && ctx.strokeText(_char, left - strokeOffsets.offsetX, top - strokeOffsets.offsetY); - ctx.restore(); - }, - - /** - * Turns the character into a 'superior figure' (i.e. 'superscript') - * @param {Number} start selection start - * @param {Number} end selection end - * @returns {fabric.Text} thisArg - * @chainable - */ - setSuperscript: function(start, end) { - return this._setScript(start, end, this.superscript); - }, - - /** - * Turns the character into an 'inferior figure' (i.e. 'subscript') - * @param {Number} start selection start - * @param {Number} end selection end - * @returns {fabric.Text} thisArg - * @chainable - */ - setSubscript: function(start, end) { - return this._setScript(start, end, this.subscript); - }, - - /** - * Applies 'schema' at given position - * @private - * @param {Number} start selection start - * @param {Number} end selection end - * @param {Number} schema - * @returns {fabric.Text} thisArg - * @chainable - */ - _setScript: function(start, end, schema) { - var loc = this.get2DCursorLocation(start, true), - fontSize = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'fontSize'), - dy = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'deltaY'), - style = { fontSize: fontSize * schema.size, deltaY: dy + fontSize * schema.baseline }; - this.setSelectionStyles(style, start, end); - return this; - }, - - /** - * @private - * @param {Object} prevStyle - * @param {Object} thisStyle - */ - _hasStyleChanged: function(prevStyle, thisStyle) { - return prevStyle.fill !== thisStyle.fill || - prevStyle.stroke !== thisStyle.stroke || - prevStyle.strokeWidth !== thisStyle.strokeWidth || - prevStyle.fontSize !== thisStyle.fontSize || - prevStyle.fontFamily !== thisStyle.fontFamily || - prevStyle.fontWeight !== thisStyle.fontWeight || - prevStyle.fontStyle !== thisStyle.fontStyle || - prevStyle.deltaY !== thisStyle.deltaY; - }, - - /** - * @private - * @param {Object} prevStyle - * @param {Object} thisStyle - */ - _hasStyleChangedForSvg: function(prevStyle, thisStyle) { - return this._hasStyleChanged(prevStyle, thisStyle) || - prevStyle.overline !== thisStyle.overline || - prevStyle.underline !== thisStyle.underline || - prevStyle.linethrough !== thisStyle.linethrough; - }, - - /** - * @private - * @param {Number} lineIndex index text line - * @return {Number} Line left offset - */ - _getLineLeftOffset: function(lineIndex) { - var lineWidth = this.getLineWidth(lineIndex), - lineDiff = this.width - lineWidth, textAlign = this.textAlign, direction = this.direction, - isEndOfWrapping, leftOffset = 0, isEndOfWrapping = this.isEndOfWrapping(lineIndex); - if (textAlign === 'justify' - || (textAlign === 'justify-center' && !isEndOfWrapping) - || (textAlign === 'justify-right' && !isEndOfWrapping) - || (textAlign === 'justify-left' && !isEndOfWrapping) - ) { - return 0; - } - if (textAlign === 'center') { - leftOffset = lineDiff / 2; - } - if (textAlign === 'right') { - leftOffset = lineDiff; - } - if (textAlign === 'justify-center') { - leftOffset = lineDiff / 2; - } - if (textAlign === 'justify-right') { - leftOffset = lineDiff; - } - if (direction === 'rtl') { - leftOffset -= lineDiff; - } - return leftOffset; - }, - - /** - * @private - */ - _clearCache: function() { - this.__lineWidths = []; - this.__lineHeights = []; - this.__charBounds = []; - }, - - /** - * @private - */ - _shouldClearDimensionCache: function() { - var shouldClear = this._forceClearCache; - shouldClear || (shouldClear = this.hasStateChanged('_dimensionAffectingProps')); - if (shouldClear) { - this.dirty = true; - this._forceClearCache = false; - } - return shouldClear; - }, - - /** - * Measure a single line given its index. Used to calculate the initial - * text bounding box. The values are calculated and stored in __lineWidths cache. - * @private - * @param {Number} lineIndex line number - * @return {Number} Line width - */ - getLineWidth: function(lineIndex) { - if (this.__lineWidths[lineIndex]) { - return this.__lineWidths[lineIndex]; - } - - var width, line = this._textLines[lineIndex], lineInfo; - - if (line === '') { - width = 0; - } - else { - lineInfo = this.measureLine(lineIndex); - width = lineInfo.width; - } - this.__lineWidths[lineIndex] = width; - return width; - }, - - _getWidthOfCharSpacing: function() { - if (this.charSpacing !== 0) { - return this.fontSize * this.charSpacing / 1000; - } - return 0; - }, - - /** - * Retrieves the value of property at given character position - * @param {Number} lineIndex the line number - * @param {Number} charIndex the character number - * @param {String} property the property name - * @returns the value of 'property' - */ - getValueOfPropertyAt: function(lineIndex, charIndex, property) { - var charStyle = this._getStyleDeclaration(lineIndex, charIndex); - if (charStyle && typeof charStyle[property] !== 'undefined') { - return charStyle[property]; - } - return this[property]; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderTextDecoration: function(ctx, type) { - if (!this[type] && !this.styleHas(type)) { - return; - } - var heightOfLine, size, _size, - lineLeftOffset, dy, _dy, - line, lastDecoration, - leftOffset = this._getLeftOffset(), - topOffset = this._getTopOffset(), top, - boxStart, boxWidth, charBox, currentDecoration, - maxHeight, currentFill, lastFill, path = this.path, - charSpacing = this._getWidthOfCharSpacing(), - offsetY = this.offsets[type]; - - for (var i = 0, len = this._textLines.length; i < len; i++) { - heightOfLine = this.getHeightOfLine(i); - if (!this[type] && !this.styleHas(type, i)) { - topOffset += heightOfLine; - continue; - } - line = this._textLines[i]; - maxHeight = heightOfLine / this.lineHeight; - lineLeftOffset = this._getLineLeftOffset(i); - boxStart = 0; - boxWidth = 0; - lastDecoration = this.getValueOfPropertyAt(i, 0, type); - lastFill = this.getValueOfPropertyAt(i, 0, 'fill'); - top = topOffset + maxHeight * (1 - this._fontSizeFraction); - size = this.getHeightOfChar(i, 0); - dy = this.getValueOfPropertyAt(i, 0, 'deltaY'); - for (var j = 0, jlen = line.length; j < jlen; j++) { - charBox = this.__charBounds[i][j]; - currentDecoration = this.getValueOfPropertyAt(i, j, type); - currentFill = this.getValueOfPropertyAt(i, j, 'fill'); - _size = this.getHeightOfChar(i, j); - _dy = this.getValueOfPropertyAt(i, j, 'deltaY'); - if (path && currentDecoration && currentFill) { - ctx.save(); - ctx.fillStyle = lastFill; - ctx.translate(charBox.renderLeft, charBox.renderTop); - ctx.rotate(charBox.angle); - ctx.fillRect( - -charBox.kernedWidth / 2, - offsetY * _size + _dy, - charBox.kernedWidth, - this.fontSize / 15 - ); - ctx.restore(); - } - else if ( - (currentDecoration !== lastDecoration || currentFill !== lastFill || _size !== size || _dy !== dy) - && boxWidth > 0 - ) { - var drawStart = leftOffset + lineLeftOffset + boxStart; - if (this.direction === 'rtl') { - drawStart = this.width - drawStart - boxWidth; - } - if (lastDecoration && lastFill) { - ctx.fillStyle = lastFill; - ctx.fillRect( - drawStart, - top + offsetY * size + dy, - boxWidth, - this.fontSize / 15 - ); - } - boxStart = charBox.left; - boxWidth = charBox.width; - lastDecoration = currentDecoration; - lastFill = currentFill; - size = _size; - dy = _dy; - } - else { - boxWidth += charBox.kernedWidth; - } - } - var drawStart = leftOffset + lineLeftOffset + boxStart; - if (this.direction === 'rtl') { - drawStart = this.width - drawStart - boxWidth; - } - ctx.fillStyle = currentFill; - currentDecoration && currentFill && ctx.fillRect( - drawStart, - top + offsetY * size + dy, - boxWidth - charSpacing, - this.fontSize / 15 - ); - topOffset += heightOfLine; - } - // if there is text background color no - // other shadows should be casted - this._removeShadow(ctx); - }, - - /** - * return font declaration string for canvas context - * @param {Object} [styleObject] object - * @returns {String} font declaration formatted for canvas context. - */ - _getFontDeclaration: function(styleObject, forMeasuring) { - var style = styleObject || this, family = this.fontFamily, - fontIsGeneric = fabric.Text.genericFonts.indexOf(family.toLowerCase()) > -1; - var fontFamily = family === undefined || - family.indexOf('\'') > -1 || family.indexOf(',') > -1 || - family.indexOf('"') > -1 || fontIsGeneric - ? style.fontFamily : '"' + style.fontFamily + '"'; - return [ - // node-canvas needs "weight style", while browsers need "style weight" - // verify if this can be fixed in JSDOM - (fabric.isLikelyNode ? style.fontWeight : style.fontStyle), - (fabric.isLikelyNode ? style.fontStyle : style.fontWeight), - forMeasuring ? this.CACHE_FONT_SIZE + 'px' : style.fontSize + 'px', - fontFamily - ].join(' '); - }, - - /** - * Renders text instance on a specified context - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - render: function(ctx) { - // do not render if object is not visible - if (!this.visible) { - return; - } - if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) { - return; - } - if (this._shouldClearDimensionCache()) { - this.initDimensions(); - } - this.callSuper('render', ctx); - }, - - /** - * Returns the text as an array of lines. - * @param {String} text text to split - * @returns {Array} Lines in the text - */ - _splitTextIntoLines: function(text) { - var lines = text.split(this._reNewline), - newLines = new Array(lines.length), - newLine = ['\n'], - newText = []; - for (var i = 0; i < lines.length; i++) { - newLines[i] = fabric.util.string.graphemeSplit(lines[i]); - newText = newText.concat(newLines[i], newLine); - } - newText.pop(); - return { _unwrappedLines: newLines, lines: lines, graphemeText: newText, graphemeLines: newLines }; - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of an instance - */ - toObject: function(propertiesToInclude) { - var additionalProperties = [ - 'text', - 'fontSize', - 'fontWeight', - 'fontFamily', - 'fontStyle', - 'lineHeight', - 'underline', - 'overline', - 'linethrough', - 'textAlign', - 'textBackgroundColor', - 'charSpacing', - 'path', - 'direction', - ].concat(propertiesToInclude); - var obj = this.callSuper('toObject', additionalProperties); - obj.styles = clone(this.styles, true); - obj.path = this.path && this.path.toObject(); - return obj; - }, - - /** - * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`. - * @param {String|Object} key Property name or object (if object, iterate over the object properties) - * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one) - * @return {fabric.Object} thisArg - * @chainable - */ - set: function(key, value) { - this.callSuper('set', key, value); - var needsDims = false; - var isAddingPath = false; - if (typeof key === 'object') { - for (var _key in key) { - if (_key === 'path') { - this.setPathInfo(); - } - needsDims = needsDims || this._dimensionAffectingProps.indexOf(_key) !== -1; - isAddingPath = isAddingPath || _key === 'path'; - } - } - else { - needsDims = this._dimensionAffectingProps.indexOf(key) !== -1; - isAddingPath = key === 'path'; - } - if (isAddingPath) { - this.setPathInfo(); - } - if (needsDims) { - this.initDimensions(); - this.setCoords(); - } - return this; - }, - - /** - * Returns complexity of an instance - * @return {Number} complexity - */ - complexity: function() { - return 1; - } - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Text.fromElement}) - * @static - * @memberOf fabric.Text - * @see: http://www.w3.org/TR/SVG/text.html#TextElement - */ - fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat( - 'x y dx dy font-family font-style font-weight font-size letter-spacing text-decoration text-anchor'.split(' ')); - - /** - * Default SVG font size - * @static - * @memberOf fabric.Text - */ - fabric.Text.DEFAULT_SVG_FONT_SIZE = 16; - - /** - * Returns fabric.Text instance from an SVG element (not yet implemented) - * @static - * @memberOf fabric.Text - * @param {SVGElement} element Element to parse - * @param {Function} callback callback function invoked after parsing - * @param {Object} [options] Options object - */ - fabric.Text.fromElement = function(element, callback, options) { - if (!element) { - return callback(null); - } - - var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES), - parsedAnchor = parsedAttributes.textAnchor || 'left'; - options = fabric.util.object.extend((options ? clone(options) : { }), parsedAttributes); - - options.top = options.top || 0; - options.left = options.left || 0; - if (parsedAttributes.textDecoration) { - var textDecoration = parsedAttributes.textDecoration; - if (textDecoration.indexOf('underline') !== -1) { - options.underline = true; - } - if (textDecoration.indexOf('overline') !== -1) { - options.overline = true; - } - if (textDecoration.indexOf('line-through') !== -1) { - options.linethrough = true; - } - delete options.textDecoration; - } - if ('dx' in parsedAttributes) { - options.left += parsedAttributes.dx; - } - if ('dy' in parsedAttributes) { - options.top += parsedAttributes.dy; - } - if (!('fontSize' in options)) { - options.fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE; - } - - var textContent = ''; - - // The XML is not properly parsed in IE9 so a workaround to get - // textContent is through firstChild.data. Another workaround would be - // to convert XML loaded from a file to be converted using DOMParser (same way loadSVGFromString() does) - if (!('textContent' in element)) { - if ('firstChild' in element && element.firstChild !== null) { - if ('data' in element.firstChild && element.firstChild.data !== null) { - textContent = element.firstChild.data; - } - } - } - else { - textContent = element.textContent; - } - - textContent = textContent.replace(/^\s+|\s+$|\n+/g, '').replace(/\s+/g, ' '); - var originalStrokeWidth = options.strokeWidth; - options.strokeWidth = 0; - - var text = new fabric.Text(textContent, options), - textHeightScaleFactor = text.getScaledHeight() / text.height, - lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height, - scaledDiff = lineHeightDiff * textHeightScaleFactor, - textHeight = text.getScaledHeight() + scaledDiff, - offX = 0; - /* - Adjust positioning: - x/y attributes in SVG correspond to the bottom-left corner of text bounding box - fabric output by default at top, left. - */ - if (parsedAnchor === 'center') { - offX = text.getScaledWidth() / 2; - } - if (parsedAnchor === 'right') { - offX = text.getScaledWidth(); - } - text.set({ - left: text.left - offX, - top: text.top - (textHeight - text.fontSize * (0.07 + text._fontSizeFraction)) / text.lineHeight, - strokeWidth: typeof originalStrokeWidth !== 'undefined' ? originalStrokeWidth : 1, - }); - callback(text); - }; - /* _FROM_SVG_END_ */ - - /** - * Returns fabric.Text instance from an object representation - * @static - * @memberOf fabric.Text - * @param {Object} object plain js Object to create an instance from - * @param {Function} [callback] Callback to invoke when an fabric.Text instance is created - */ - fabric.Text.fromObject = function(object, callback) { - var objectCopy = clone(object), path = object.path; - delete objectCopy.path; - return fabric.Object._fromObject('Text', objectCopy, function(textInstance) { - if (path) { - fabric.Object._fromObject('Path', path, function(pathInstance) { - textInstance.set('path', pathInstance); - callback(textInstance); - }, 'path'); - } - else { - callback(textInstance); - } - }, 'text'); - }; - - fabric.Text.genericFonts = ['sans-serif', 'serif', 'cursive', 'fantasy', 'monospace']; - - fabric.util.createAccessors && fabric.util.createAccessors(fabric.Text); - -})(typeof exports !== 'undefined' ? exports : this); - - -(function() { - fabric.util.object.extend(fabric.Text.prototype, /** @lends fabric.Text.prototype */ { - /** - * Returns true if object has no styling or no styling in a line - * @param {Number} lineIndex , lineIndex is on wrapped lines. - * @return {Boolean} - */ - isEmptyStyles: function(lineIndex) { - if (!this.styles) { - return true; - } - if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) { - return true; - } - var obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] }; - for (var p1 in obj) { - for (var p2 in obj[p1]) { - // eslint-disable-next-line no-unused-vars - for (var p3 in obj[p1][p2]) { - return false; - } - } - } - return true; - }, - - /** - * Returns true if object has a style property or has it ina specified line - * This function is used to detect if a text will use a particular property or not. - * @param {String} property to check for - * @param {Number} lineIndex to check the style on - * @return {Boolean} - */ - styleHas: function(property, lineIndex) { - if (!this.styles || !property || property === '') { - return false; - } - if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) { - return false; - } - var obj = typeof lineIndex === 'undefined' ? this.styles : { 0: this.styles[lineIndex] }; - // eslint-disable-next-line - for (var p1 in obj) { - // eslint-disable-next-line - for (var p2 in obj[p1]) { - if (typeof obj[p1][p2][property] !== 'undefined') { - return true; - } - } - } - return false; - }, - - /** - * Check if characters in a text have a value for a property - * whose value matches the textbox's value for that property. If so, - * the character-level property is deleted. If the character - * has no other properties, then it is also deleted. Finally, - * if the line containing that character has no other characters - * then it also is deleted. - * - * @param {string} property The property to compare between characters and text. - */ - cleanStyle: function(property) { - if (!this.styles || !property || property === '') { - return false; - } - var obj = this.styles, stylesCount = 0, letterCount, stylePropertyValue, - allStyleObjectPropertiesMatch = true, graphemeCount = 0, styleObject; - // eslint-disable-next-line - for (var p1 in obj) { - letterCount = 0; - // eslint-disable-next-line - for (var p2 in obj[p1]) { - var styleObject = obj[p1][p2], - stylePropertyHasBeenSet = styleObject.hasOwnProperty(property); - - stylesCount++; - - if (stylePropertyHasBeenSet) { - if (!stylePropertyValue) { - stylePropertyValue = styleObject[property]; - } - else if (styleObject[property] !== stylePropertyValue) { - allStyleObjectPropertiesMatch = false; - } - - if (styleObject[property] === this[property]) { - delete styleObject[property]; - } - } - else { - allStyleObjectPropertiesMatch = false; - } - - if (Object.keys(styleObject).length !== 0) { - letterCount++; - } - else { - delete obj[p1][p2]; - } - } - - if (letterCount === 0) { - delete obj[p1]; - } - } - // if every grapheme has the same style set then - // delete those styles and set it on the parent - for (var i = 0; i < this._textLines.length; i++) { - graphemeCount += this._textLines[i].length; - } - if (allStyleObjectPropertiesMatch && stylesCount === graphemeCount) { - this[property] = stylePropertyValue; - this.removeStyle(property); - } - }, - - /** - * Remove a style property or properties from all individual character styles - * in a text object. Deletes the character style object if it contains no other style - * props. Deletes a line style object if it contains no other character styles. - * - * @param {String} props The property to remove from character styles. - */ - removeStyle: function(property) { - if (!this.styles || !property || property === '') { - return; - } - var obj = this.styles, line, lineNum, charNum; - for (lineNum in obj) { - line = obj[lineNum]; - for (charNum in line) { - delete line[charNum][property]; - if (Object.keys(line[charNum]).length === 0) { - delete line[charNum]; - } - } - if (Object.keys(line).length === 0) { - delete obj[lineNum]; - } - } - }, - - /** - * @private - */ - _extendStyles: function(index, styles) { - var loc = this.get2DCursorLocation(index); - - if (!this._getLineStyle(loc.lineIndex)) { - this._setLineStyle(loc.lineIndex); - } - - if (!this._getStyleDeclaration(loc.lineIndex, loc.charIndex)) { - this._setStyleDeclaration(loc.lineIndex, loc.charIndex, {}); - } - - fabric.util.object.extend(this._getStyleDeclaration(loc.lineIndex, loc.charIndex), styles); - }, - - /** - * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start) - * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used. - * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles. - */ - get2DCursorLocation: function(selectionStart, skipWrapping) { - if (typeof selectionStart === 'undefined') { - selectionStart = this.selectionStart; - } - var lines = skipWrapping ? this._unwrappedTextLines : this._textLines, - len = lines.length; - for (var i = 0; i < len; i++) { - if (selectionStart <= lines[i].length) { - return { - lineIndex: i, - charIndex: selectionStart - }; - } - selectionStart -= lines[i].length + this.missingNewlineOffset(i); - } - return { - lineIndex: i - 1, - charIndex: lines[i - 1].length < selectionStart ? lines[i - 1].length : selectionStart - }; - }, - - /** - * Gets style of a current selection/cursor (at the start position) - * if startIndex or endIndex are not provided, selectionStart or selectionEnd will be used. - * @param {Number} [startIndex] Start index to get styles at - * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1 - * @param {Boolean} [complete] get full style or not - * @return {Array} styles an array with one, zero or more Style objects - */ - getSelectionStyles: function(startIndex, endIndex, complete) { - if (typeof startIndex === 'undefined') { - startIndex = this.selectionStart || 0; - } - if (typeof endIndex === 'undefined') { - endIndex = this.selectionEnd || startIndex; - } - var styles = []; - for (var i = startIndex; i < endIndex; i++) { - styles.push(this.getStyleAtPosition(i, complete)); - } - return styles; - }, - - /** - * Gets style of a current selection/cursor position - * @param {Number} position to get styles at - * @param {Boolean} [complete] full style if true - * @return {Object} style Style object at a specified index - * @private - */ - getStyleAtPosition: function(position, complete) { - var loc = this.get2DCursorLocation(position), - style = complete ? this.getCompleteStyleDeclaration(loc.lineIndex, loc.charIndex) : - this._getStyleDeclaration(loc.lineIndex, loc.charIndex); - return style || {}; - }, - - /** - * Sets style of a current selection, if no selection exist, do not set anything. - * @param {Object} [styles] Styles object - * @param {Number} [startIndex] Start index to get styles at - * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1 - * @return {fabric.IText} thisArg - * @chainable - */ - setSelectionStyles: function(styles, startIndex, endIndex) { - if (typeof startIndex === 'undefined') { - startIndex = this.selectionStart || 0; - } - if (typeof endIndex === 'undefined') { - endIndex = this.selectionEnd || startIndex; - } - for (var i = startIndex; i < endIndex; i++) { - this._extendStyles(i, styles); - } - /* not included in _extendStyles to avoid clearing cache more than once */ - this._forceClearCache = true; - return this; - }, - - /** - * get the reference, not a clone, of the style object for a given character - * @param {Number} lineIndex - * @param {Number} charIndex - * @return {Object} style object - */ - _getStyleDeclaration: function(lineIndex, charIndex) { - var lineStyle = this.styles && this.styles[lineIndex]; - if (!lineStyle) { - return null; - } - return lineStyle[charIndex]; - }, - - /** - * return a new object that contains all the style property for a character - * the object returned is newly created - * @param {Number} lineIndex of the line where the character is - * @param {Number} charIndex position of the character on the line - * @return {Object} style object - */ - getCompleteStyleDeclaration: function(lineIndex, charIndex) { - var style = this._getStyleDeclaration(lineIndex, charIndex) || { }, - styleObject = { }, prop; - for (var i = 0; i < this._styleProperties.length; i++) { - prop = this._styleProperties[i]; - styleObject[prop] = typeof style[prop] === 'undefined' ? this[prop] : style[prop]; - } - return styleObject; - }, - - /** - * @param {Number} lineIndex - * @param {Number} charIndex - * @param {Object} style - * @private - */ - _setStyleDeclaration: function(lineIndex, charIndex, style) { - this.styles[lineIndex][charIndex] = style; - }, - - /** - * - * @param {Number} lineIndex - * @param {Number} charIndex - * @private - */ - _deleteStyleDeclaration: function(lineIndex, charIndex) { - delete this.styles[lineIndex][charIndex]; - }, - - /** - * @param {Number} lineIndex - * @return {Boolean} if the line exists or not - * @private - */ - _getLineStyle: function(lineIndex) { - return !!this.styles[lineIndex]; - }, - - /** - * Set the line style to an empty object so that is initialized - * @param {Number} lineIndex - * @private - */ - _setLineStyle: function(lineIndex) { - this.styles[lineIndex] = {}; - }, - - /** - * @param {Number} lineIndex - * @private - */ - _deleteLineStyle: function(lineIndex) { - delete this.styles[lineIndex]; - } - }); -})(); - - -(function() { - - function parseDecoration(object) { - if (object.textDecoration) { - object.textDecoration.indexOf('underline') > -1 && (object.underline = true); - object.textDecoration.indexOf('line-through') > -1 && (object.linethrough = true); - object.textDecoration.indexOf('overline') > -1 && (object.overline = true); - delete object.textDecoration; - } - } - - /** - * IText class (introduced in v1.4) Events are also fired with "text:" - * prefix when observing canvas. - * @class fabric.IText - * @extends fabric.Text - * @mixes fabric.Observable - * - * @fires changed - * @fires selection:changed - * @fires editing:entered - * @fires editing:exited - * - * @return {fabric.IText} thisArg - * @see {@link fabric.IText#initialize} for constructor definition - * - *

    Supported key combinations:

    - *
    -   *   Move cursor:                    left, right, up, down
    -   *   Select character:               shift + left, shift + right
    -   *   Select text vertically:         shift + up, shift + down
    -   *   Move cursor by word:            alt + left, alt + right
    -   *   Select words:                   shift + alt + left, shift + alt + right
    -   *   Move cursor to line start/end:  cmd + left, cmd + right or home, end
    -   *   Select till start/end of line:  cmd + shift + left, cmd + shift + right or shift + home, shift + end
    -   *   Jump to start/end of text:      cmd + up, cmd + down
    -   *   Select till start/end of text:  cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown
    -   *   Delete character:               backspace
    -   *   Delete word:                    alt + backspace
    -   *   Delete line:                    cmd + backspace
    -   *   Forward delete:                 delete
    -   *   Copy text:                      ctrl/cmd + c
    -   *   Paste text:                     ctrl/cmd + v
    -   *   Cut text:                       ctrl/cmd + x
    -   *   Select entire text:             ctrl/cmd + a
    -   *   Quit editing                    tab or esc
    -   * 
    - * - *

    Supported mouse/touch combination

    - *
    -   *   Position cursor:                click/touch
    -   *   Create selection:               click/touch & drag
    -   *   Create selection:               click & shift + click
    -   *   Select word:                    double click
    -   *   Select line:                    triple click
    -   * 
    - */ - fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable, /** @lends fabric.IText.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'i-text', - - /** - * Index where text selection starts (or where cursor is when there is no selection) - * @type Number - * @default - */ - selectionStart: 0, - - /** - * Index where text selection ends - * @type Number - * @default - */ - selectionEnd: 0, - - /** - * Color of text selection - * @type String - * @default - */ - selectionColor: 'rgba(17,119,255,0.3)', - - /** - * Indicates whether text is in editing mode - * @type Boolean - * @default - */ - isEditing: false, - - /** - * Indicates whether a text can be edited - * @type Boolean - * @default - */ - editable: true, - - /** - * Border color of text object while it's in editing mode - * @type String - * @default - */ - editingBorderColor: 'rgba(102,153,255,0.25)', - - /** - * Width of cursor (in px) - * @type Number - * @default - */ - cursorWidth: 2, - - /** - * Color of text cursor color in editing mode. - * if not set (default) will take color from the text. - * if set to a color value that fabric can understand, it will - * be used instead of the color of the text at the current position. - * @type String - * @default - */ - cursorColor: '', - - /** - * Delay between cursor blink (in ms) - * @type Number - * @default - */ - cursorDelay: 1000, - - /** - * Duration of cursor fadein (in ms) - * @type Number - * @default - */ - cursorDuration: 600, - - /** - * Indicates whether internal text char widths can be cached - * @type Boolean - * @default - */ - caching: true, - - /** - * @private - */ - _reSpace: /\s|\n/, - - /** - * @private - */ - _currentCursorOpacity: 0, - - /** - * @private - */ - _selectionDirection: null, - - /** - * @private - */ - _abortCursorAnimation: false, - - /** - * @private - */ - __widthOfSpace: [], - - /** - * Helps determining when the text is in composition, so that the cursor - * rendering is altered. - */ - inCompositionMode: false, - - /** - * Constructor - * @param {String} text Text string - * @param {Object} [options] Options object - * @return {fabric.IText} thisArg - */ - initialize: function(text, options) { - this.callSuper('initialize', text, options); - this.initBehavior(); - }, - - /** - * Sets selection start (left boundary of a selection) - * @param {Number} index Index to set selection start to - */ - setSelectionStart: function(index) { - index = Math.max(index, 0); - this._updateAndFire('selectionStart', index); - }, - - /** - * Sets selection end (right boundary of a selection) - * @param {Number} index Index to set selection end to - */ - setSelectionEnd: function(index) { - index = Math.min(index, this.text.length); - this._updateAndFire('selectionEnd', index); - }, - - /** - * @private - * @param {String} property 'selectionStart' or 'selectionEnd' - * @param {Number} index new position of property - */ - _updateAndFire: function(property, index) { - if (this[property] !== index) { - this._fireSelectionChanged(); - this[property] = index; - } - this._updateTextarea(); - }, - - /** - * Fires the even of selection changed - * @private - */ - _fireSelectionChanged: function() { - this.fire('selection:changed'); - this.canvas && this.canvas.fire('text:selection:changed', { target: this }); - }, - - /** - * Initialize text dimensions. Render all text on given context - * or on a offscreen canvas to get the text width with measureText. - * Updates this.width and this.height with the proper values. - * Does not return dimensions. - * @private - */ - initDimensions: function() { - this.isEditing && this.initDelayedCursor(); - this.clearContextTop(); - this.callSuper('initDimensions'); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - render: function(ctx) { - this.clearContextTop(); - this.callSuper('render', ctx); - // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor - // the correct position but not at every cursor animation. - this.cursorOffsetCache = { }; - this.renderCursorOrSelection(); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - this.callSuper('_render', ctx); - }, - - /** - * Prepare and clean the contextTop - */ - clearContextTop: function(skipRestore) { - if (!this.isEditing || !this.canvas || !this.canvas.contextTop) { - return; - } - var ctx = this.canvas.contextTop, v = this.canvas.viewportTransform; - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - this.transform(ctx); - this._clearTextArea(ctx); - skipRestore || ctx.restore(); - }, - /** - * Renders cursor or selection (depending on what exists) - * it does on the contextTop. If contextTop is not available, do nothing. - */ - renderCursorOrSelection: function() { - if (!this.isEditing || !this.canvas || !this.canvas.contextTop) { - return; - } - var boundaries = this._getCursorBoundaries(), - ctx = this.canvas.contextTop; - this.clearContextTop(true); - if (this.selectionStart === this.selectionEnd) { - this.renderCursor(boundaries, ctx); - } - else { - this.renderSelection(boundaries, ctx); - } - ctx.restore(); - }, - - _clearTextArea: function(ctx) { - // we add 4 pixel, to be sure to do not leave any pixel out - var width = this.width + 4, height = this.height + 4; - ctx.clearRect(-width / 2, -height / 2, width, height); - }, - - /** - * Returns cursor boundaries (left, top, leftOffset, topOffset) - * @private - * @param {Array} chars Array of characters - * @param {String} typeOfBoundaries - */ - _getCursorBoundaries: function(position) { - - // left/top are left/top of entire text box - // leftOffset/topOffset are offset from that left/top point of a text box - - if (typeof position === 'undefined') { - position = this.selectionStart; - } - - var left = this._getLeftOffset(), - top = this._getTopOffset(), - offsets = this._getCursorBoundariesOffsets(position); - return { - left: left, - top: top, - leftOffset: offsets.left, - topOffset: offsets.top - }; - }, - - /** - * @private - */ - _getCursorBoundariesOffsets: function(position) { - if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) { - return this.cursorOffsetCache; - } - var lineLeftOffset, - lineIndex, - charIndex, - topOffset = 0, - leftOffset = 0, - boundaries, - cursorPosition = this.get2DCursorLocation(position); - charIndex = cursorPosition.charIndex; - lineIndex = cursorPosition.lineIndex; - for (var i = 0; i < lineIndex; i++) { - topOffset += this.getHeightOfLine(i); - } - lineLeftOffset = this._getLineLeftOffset(lineIndex); - var bound = this.__charBounds[lineIndex][charIndex]; - bound && (leftOffset = bound.left); - if (this.charSpacing !== 0 && charIndex === this._textLines[lineIndex].length) { - leftOffset -= this._getWidthOfCharSpacing(); - } - boundaries = { - top: topOffset, - left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0), - }; - if (this.direction === 'rtl') { - boundaries.left *= -1; - } - this.cursorOffsetCache = boundaries; - return this.cursorOffsetCache; - }, - - /** - * Renders cursor - * @param {Object} boundaries - * @param {CanvasRenderingContext2D} ctx transformed context to draw on - */ - renderCursor: function(boundaries, ctx) { - var cursorLocation = this.get2DCursorLocation(), - lineIndex = cursorLocation.lineIndex, - charIndex = cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0, - charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'), - multiplier = this.scaleX * this.canvas.getZoom(), - cursorWidth = this.cursorWidth / multiplier, - topOffset = boundaries.topOffset, - dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY'); - topOffset += (1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex) / this.lineHeight - - charHeight * (1 - this._fontSizeFraction); - - if (this.inCompositionMode) { - this.renderSelection(boundaries, ctx); - } - ctx.fillStyle = this.cursorColor || this.getValueOfPropertyAt(lineIndex, charIndex, 'fill'); - ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity; - ctx.fillRect( - boundaries.left + boundaries.leftOffset - cursorWidth / 2, - topOffset + boundaries.top + dy, - cursorWidth, - charHeight); - }, - - /** - * Renders text selection - * @param {Object} boundaries Object with left/top/leftOffset/topOffset - * @param {CanvasRenderingContext2D} ctx transformed context to draw on - */ - renderSelection: function(boundaries, ctx) { - - var selectionStart = this.inCompositionMode ? this.hiddenTextarea.selectionStart : this.selectionStart, - selectionEnd = this.inCompositionMode ? this.hiddenTextarea.selectionEnd : this.selectionEnd, - isJustify = this.textAlign.indexOf('justify') !== -1, - start = this.get2DCursorLocation(selectionStart), - end = this.get2DCursorLocation(selectionEnd), - startLine = start.lineIndex, - endLine = end.lineIndex, - startChar = start.charIndex < 0 ? 0 : start.charIndex, - endChar = end.charIndex < 0 ? 0 : end.charIndex; - - for (var i = startLine; i <= endLine; i++) { - var lineOffset = this._getLineLeftOffset(i) || 0, - lineHeight = this.getHeightOfLine(i), - realLineHeight = 0, boxStart = 0, boxEnd = 0; - - if (i === startLine) { - boxStart = this.__charBounds[startLine][startChar].left; - } - if (i >= startLine && i < endLine) { - boxEnd = isJustify && !this.isEndOfWrapping(i) ? this.width : this.getLineWidth(i) || 5; // WTF is this 5? - } - else if (i === endLine) { - if (endChar === 0) { - boxEnd = this.__charBounds[endLine][endChar].left; - } - else { - var charSpacing = this._getWidthOfCharSpacing(); - boxEnd = this.__charBounds[endLine][endChar - 1].left - + this.__charBounds[endLine][endChar - 1].width - charSpacing; - } - } - realLineHeight = lineHeight; - if (this.lineHeight < 1 || (i === endLine && this.lineHeight > 1)) { - lineHeight /= this.lineHeight; - } - var drawStart = boundaries.left + lineOffset + boxStart, - drawWidth = boxEnd - boxStart, - drawHeight = lineHeight, extraTop = 0; - if (this.inCompositionMode) { - ctx.fillStyle = this.compositionColor || 'black'; - drawHeight = 1; - extraTop = lineHeight; - } - else { - ctx.fillStyle = this.selectionColor; - } - if (this.direction === 'rtl') { - drawStart = this.width - drawStart - drawWidth; - } - ctx.fillRect( - drawStart, - boundaries.top + boundaries.topOffset + extraTop, - drawWidth, - drawHeight); - boundaries.topOffset += realLineHeight; - } - }, - - /** - * High level function to know the height of the cursor. - * the currentChar is the one that precedes the cursor - * Returns fontSize of char at the current cursor - * Unused from the library, is for the end user - * @return {Number} Character font size - */ - getCurrentCharFontSize: function() { - var cp = this._getCurrentCharIndex(); - return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize'); - }, - - /** - * High level function to know the color of the cursor. - * the currentChar is the one that precedes the cursor - * Returns color (fill) of char at the current cursor - * if the text object has a pattern or gradient for filler, it will return that. - * Unused by the library, is for the end user - * @return {String | fabric.Gradient | fabric.Pattern} Character color (fill) - */ - getCurrentCharColor: function() { - var cp = this._getCurrentCharIndex(); - return this.getValueOfPropertyAt(cp.l, cp.c, 'fill'); - }, - - /** - * Returns the cursor position for the getCurrent.. functions - * @private - */ - _getCurrentCharIndex: function() { - var cursorPosition = this.get2DCursorLocation(this.selectionStart, true), - charIndex = cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0; - return { l: cursorPosition.lineIndex, c: charIndex }; - } - }); - - /** - * Returns fabric.IText instance from an object representation - * @static - * @memberOf fabric.IText - * @param {Object} object Object to create an instance from - * @param {function} [callback] invoked with new instance as argument - */ - fabric.IText.fromObject = function(object, callback) { - parseDecoration(object); - if (object.styles) { - for (var i in object.styles) { - for (var j in object.styles[i]) { - parseDecoration(object.styles[i][j]); - } - } - } - fabric.Object._fromObject('IText', object, callback, 'text'); - }; -})(); - - -(function() { - - var clone = fabric.util.object.clone; - - fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ { - - /** - * Initializes all the interactive behavior of IText - */ - initBehavior: function() { - this.initAddedHandler(); - this.initRemovedHandler(); - this.initCursorSelectionHandlers(); - this.initDoubleClickSimulation(); - this.mouseMoveHandler = this.mouseMoveHandler.bind(this); - }, - - onDeselect: function() { - this.isEditing && this.exitEditing(); - this.selected = false; - }, - - /** - * Initializes "added" event handler - */ - initAddedHandler: function() { - var _this = this; - this.on('added', function() { - var canvas = _this.canvas; - if (canvas) { - if (!canvas._hasITextHandlers) { - canvas._hasITextHandlers = true; - _this._initCanvasHandlers(canvas); - } - canvas._iTextInstances = canvas._iTextInstances || []; - canvas._iTextInstances.push(_this); - } - }); - }, - - initRemovedHandler: function() { - var _this = this; - this.on('removed', function() { - var canvas = _this.canvas; - if (canvas) { - canvas._iTextInstances = canvas._iTextInstances || []; - fabric.util.removeFromArray(canvas._iTextInstances, _this); - if (canvas._iTextInstances.length === 0) { - canvas._hasITextHandlers = false; - _this._removeCanvasHandlers(canvas); - } - } - }); - }, - - /** - * register canvas event to manage exiting on other instances - * @private - */ - _initCanvasHandlers: function(canvas) { - canvas._mouseUpITextHandler = function() { - if (canvas._iTextInstances) { - canvas._iTextInstances.forEach(function(obj) { - obj.__isMousedown = false; - }); - } - }; - canvas.on('mouse:up', canvas._mouseUpITextHandler); - }, - - /** - * remove canvas event to manage exiting on other instances - * @private - */ - _removeCanvasHandlers: function(canvas) { - canvas.off('mouse:up', canvas._mouseUpITextHandler); - }, - - /** - * @private - */ - _tick: function() { - this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, '_onTickComplete'); - }, - - /** - * @private - */ - _animateCursor: function(obj, targetOpacity, duration, completeMethod) { - - var tickState; - - tickState = { - isAborted: false, - abort: function() { - this.isAborted = true; - }, - }; - - obj.animate('_currentCursorOpacity', targetOpacity, { - duration: duration, - onComplete: function() { - if (!tickState.isAborted) { - obj[completeMethod](); - } - }, - onChange: function() { - // we do not want to animate a selection, only cursor - if (obj.canvas && obj.selectionStart === obj.selectionEnd) { - obj.renderCursorOrSelection(); - } - }, - abort: function() { - return tickState.isAborted; - } - }); - return tickState; - }, - - /** - * @private - */ - _onTickComplete: function() { - - var _this = this; - - if (this._cursorTimeout1) { - clearTimeout(this._cursorTimeout1); - } - this._cursorTimeout1 = setTimeout(function() { - _this._currentTickCompleteState = _this._animateCursor(_this, 0, this.cursorDuration / 2, '_tick'); - }, 100); - }, - - /** - * Initializes delayed cursor - */ - initDelayedCursor: function(restart) { - var _this = this, - delay = restart ? 0 : this.cursorDelay; - - this.abortCursorAnimation(); - this._currentCursorOpacity = 1; - this._cursorTimeout2 = setTimeout(function() { - _this._tick(); - }, delay); - }, - - /** - * Aborts cursor animation and clears all timeouts - */ - abortCursorAnimation: function() { - var shouldClear = this._currentTickState || this._currentTickCompleteState, - canvas = this.canvas; - this._currentTickState && this._currentTickState.abort(); - this._currentTickCompleteState && this._currentTickCompleteState.abort(); - - clearTimeout(this._cursorTimeout1); - clearTimeout(this._cursorTimeout2); - - this._currentCursorOpacity = 0; - // to clear just itext area we need to transform the context - // it may not be worth it - if (shouldClear && canvas) { - canvas.clearContext(canvas.contextTop || canvas.contextContainer); - } - - }, - - /** - * Selects entire text - * @return {fabric.IText} thisArg - * @chainable - */ - selectAll: function() { - this.selectionStart = 0; - this.selectionEnd = this._text.length; - this._fireSelectionChanged(); - this._updateTextarea(); - return this; - }, - - /** - * Returns selected text - * @return {String} - */ - getSelectedText: function() { - return this._text.slice(this.selectionStart, this.selectionEnd).join(''); - }, - - /** - * Find new selection index representing start of current word according to current selection index - * @param {Number} startFrom Current selection index - * @return {Number} New selection index - */ - findWordBoundaryLeft: function(startFrom) { - var offset = 0, index = startFrom - 1; - - // remove space before cursor first - if (this._reSpace.test(this._text[index])) { - while (this._reSpace.test(this._text[index])) { - offset++; - index--; - } - } - while (/\S/.test(this._text[index]) && index > -1) { - offset++; - index--; - } - - return startFrom - offset; - }, - - /** - * Find new selection index representing end of current word according to current selection index - * @param {Number} startFrom Current selection index - * @return {Number} New selection index - */ - findWordBoundaryRight: function(startFrom) { - var offset = 0, index = startFrom; - - // remove space after cursor first - if (this._reSpace.test(this._text[index])) { - while (this._reSpace.test(this._text[index])) { - offset++; - index++; - } - } - while (/\S/.test(this._text[index]) && index < this._text.length) { - offset++; - index++; - } - - return startFrom + offset; - }, - - /** - * Find new selection index representing start of current line according to current selection index - * @param {Number} startFrom Current selection index - * @return {Number} New selection index - */ - findLineBoundaryLeft: function(startFrom) { - var offset = 0, index = startFrom - 1; - - while (!/\n/.test(this._text[index]) && index > -1) { - offset++; - index--; - } - - return startFrom - offset; - }, - - /** - * Find new selection index representing end of current line according to current selection index - * @param {Number} startFrom Current selection index - * @return {Number} New selection index - */ - findLineBoundaryRight: function(startFrom) { - var offset = 0, index = startFrom; - - while (!/\n/.test(this._text[index]) && index < this._text.length) { - offset++; - index++; - } - - return startFrom + offset; - }, - - /** - * Finds index corresponding to beginning or end of a word - * @param {Number} selectionStart Index of a character - * @param {Number} direction 1 or -1 - * @return {Number} Index of the beginning or end of a word - */ - searchWordBoundary: function(selectionStart, direction) { - var text = this._text, - index = this._reSpace.test(text[selectionStart]) ? selectionStart - 1 : selectionStart, - _char = text[index], - // wrong - reNonWord = fabric.reNonWord; - - while (!reNonWord.test(_char) && index > 0 && index < text.length) { - index += direction; - _char = text[index]; - } - if (reNonWord.test(_char)) { - index += direction === 1 ? 0 : 1; - } - return index; - }, - - /** - * Selects a word based on the index - * @param {Number} selectionStart Index of a character - */ - selectWord: function(selectionStart) { - selectionStart = selectionStart || this.selectionStart; - var newSelectionStart = this.searchWordBoundary(selectionStart, -1), /* search backwards */ - newSelectionEnd = this.searchWordBoundary(selectionStart, 1); /* search forward */ - - this.selectionStart = newSelectionStart; - this.selectionEnd = newSelectionEnd; - this._fireSelectionChanged(); - this._updateTextarea(); - this.renderCursorOrSelection(); - }, - - /** - * Selects a line based on the index - * @param {Number} selectionStart Index of a character - * @return {fabric.IText} thisArg - * @chainable - */ - selectLine: function(selectionStart) { - selectionStart = selectionStart || this.selectionStart; - var newSelectionStart = this.findLineBoundaryLeft(selectionStart), - newSelectionEnd = this.findLineBoundaryRight(selectionStart); - - this.selectionStart = newSelectionStart; - this.selectionEnd = newSelectionEnd; - this._fireSelectionChanged(); - this._updateTextarea(); - return this; - }, - - /** - * Enters editing state - * @return {fabric.IText} thisArg - * @chainable - */ - enterEditing: function(e) { - if (this.isEditing || !this.editable) { - return; - } - - if (this.canvas) { - this.canvas.calcOffset(); - this.exitEditingOnOthers(this.canvas); - } - - this.isEditing = true; - - this.initHiddenTextarea(e); - this.hiddenTextarea.focus(); - this.hiddenTextarea.value = this.text; - this._updateTextarea(); - this._saveEditingProps(); - this._setEditingProps(); - this._textBeforeEdit = this.text; - - this._tick(); - this.fire('editing:entered'); - this._fireSelectionChanged(); - if (!this.canvas) { - return this; - } - this.canvas.fire('text:editing:entered', { target: this }); - this.initMouseMoveHandler(); - this.canvas.requestRenderAll(); - return this; - }, - - exitEditingOnOthers: function(canvas) { - if (canvas._iTextInstances) { - canvas._iTextInstances.forEach(function(obj) { - obj.selected = false; - if (obj.isEditing) { - obj.exitEditing(); - } - }); - } - }, - - /** - * Initializes "mousemove" event handler - */ - initMouseMoveHandler: function() { - this.canvas.on('mouse:move', this.mouseMoveHandler); - }, - - /** - * @private - */ - mouseMoveHandler: function(options) { - if (!this.__isMousedown || !this.isEditing) { - return; - } - - var newSelectionStart = this.getSelectionStartFromPointer(options.e), - currentStart = this.selectionStart, - currentEnd = this.selectionEnd; - if ( - (newSelectionStart !== this.__selectionStartOnMouseDown || currentStart === currentEnd) - && - (currentStart === newSelectionStart || currentEnd === newSelectionStart) - ) { - return; - } - if (newSelectionStart > this.__selectionStartOnMouseDown) { - this.selectionStart = this.__selectionStartOnMouseDown; - this.selectionEnd = newSelectionStart; - } - else { - this.selectionStart = newSelectionStart; - this.selectionEnd = this.__selectionStartOnMouseDown; - } - if (this.selectionStart !== currentStart || this.selectionEnd !== currentEnd) { - this.restartCursorIfNeeded(); - this._fireSelectionChanged(); - this._updateTextarea(); - this.renderCursorOrSelection(); - } - }, - - /** - * @private - */ - _setEditingProps: function() { - this.hoverCursor = 'text'; - - if (this.canvas) { - this.canvas.defaultCursor = this.canvas.moveCursor = 'text'; - } - - this.borderColor = this.editingBorderColor; - this.hasControls = this.selectable = false; - this.lockMovementX = this.lockMovementY = true; - }, - - /** - * convert from textarea to grapheme indexes - */ - fromStringToGraphemeSelection: function(start, end, text) { - var smallerTextStart = text.slice(0, start), - graphemeStart = fabric.util.string.graphemeSplit(smallerTextStart).length; - if (start === end) { - return { selectionStart: graphemeStart, selectionEnd: graphemeStart }; - } - var smallerTextEnd = text.slice(start, end), - graphemeEnd = fabric.util.string.graphemeSplit(smallerTextEnd).length; - return { selectionStart: graphemeStart, selectionEnd: graphemeStart + graphemeEnd }; - }, - - /** - * convert from fabric to textarea values - */ - fromGraphemeToStringSelection: function(start, end, _text) { - var smallerTextStart = _text.slice(0, start), - graphemeStart = smallerTextStart.join('').length; - if (start === end) { - return { selectionStart: graphemeStart, selectionEnd: graphemeStart }; - } - var smallerTextEnd = _text.slice(start, end), - graphemeEnd = smallerTextEnd.join('').length; - return { selectionStart: graphemeStart, selectionEnd: graphemeStart + graphemeEnd }; - }, - - /** - * @private - */ - _updateTextarea: function() { - this.cursorOffsetCache = { }; - if (!this.hiddenTextarea) { - return; - } - if (!this.inCompositionMode) { - var newSelection = this.fromGraphemeToStringSelection(this.selectionStart, this.selectionEnd, this._text); - this.hiddenTextarea.selectionStart = newSelection.selectionStart; - this.hiddenTextarea.selectionEnd = newSelection.selectionEnd; - } - this.updateTextareaPosition(); - }, - - /** - * @private - */ - updateFromTextArea: function() { - if (!this.hiddenTextarea) { - return; - } - this.cursorOffsetCache = { }; - this.text = this.hiddenTextarea.value; - if (this._shouldClearDimensionCache()) { - this.initDimensions(); - this.setCoords(); - } - var newSelection = this.fromStringToGraphemeSelection( - this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value); - this.selectionEnd = this.selectionStart = newSelection.selectionEnd; - if (!this.inCompositionMode) { - this.selectionStart = newSelection.selectionStart; - } - this.updateTextareaPosition(); - }, - - /** - * @private - */ - updateTextareaPosition: function() { - if (this.selectionStart === this.selectionEnd) { - var style = this._calcTextareaPosition(); - this.hiddenTextarea.style.left = style.left; - this.hiddenTextarea.style.top = style.top; - } - }, - - /** - * @private - * @return {Object} style contains style for hiddenTextarea - */ - _calcTextareaPosition: function() { - if (!this.canvas) { - return { x: 1, y: 1 }; - } - var desiredPosition = this.inCompositionMode ? this.compositionStart : this.selectionStart, - boundaries = this._getCursorBoundaries(desiredPosition), - cursorLocation = this.get2DCursorLocation(desiredPosition), - lineIndex = cursorLocation.lineIndex, - charIndex = cursorLocation.charIndex, - charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') * this.lineHeight, - leftOffset = boundaries.leftOffset, - m = this.calcTransformMatrix(), - p = { - x: boundaries.left + leftOffset, - y: boundaries.top + boundaries.topOffset + charHeight - }, - retinaScaling = this.canvas.getRetinaScaling(), - upperCanvas = this.canvas.upperCanvasEl, - upperCanvasWidth = upperCanvas.width / retinaScaling, - upperCanvasHeight = upperCanvas.height / retinaScaling, - maxWidth = upperCanvasWidth - charHeight, - maxHeight = upperCanvasHeight - charHeight, - scaleX = upperCanvas.clientWidth / upperCanvasWidth, - scaleY = upperCanvas.clientHeight / upperCanvasHeight; - - p = fabric.util.transformPoint(p, m); - p = fabric.util.transformPoint(p, this.canvas.viewportTransform); - p.x *= scaleX; - p.y *= scaleY; - if (p.x < 0) { - p.x = 0; - } - if (p.x > maxWidth) { - p.x = maxWidth; - } - if (p.y < 0) { - p.y = 0; - } - if (p.y > maxHeight) { - p.y = maxHeight; - } - - // add canvas offset on document - p.x += this.canvas._offset.left; - p.y += this.canvas._offset.top; - - return { left: p.x + 'px', top: p.y + 'px', fontSize: charHeight + 'px', charHeight: charHeight }; - }, - - /** - * @private - */ - _saveEditingProps: function() { - this._savedProps = { - hasControls: this.hasControls, - borderColor: this.borderColor, - lockMovementX: this.lockMovementX, - lockMovementY: this.lockMovementY, - hoverCursor: this.hoverCursor, - selectable: this.selectable, - defaultCursor: this.canvas && this.canvas.defaultCursor, - moveCursor: this.canvas && this.canvas.moveCursor - }; - }, - - /** - * @private - */ - _restoreEditingProps: function() { - if (!this._savedProps) { - return; - } - - this.hoverCursor = this._savedProps.hoverCursor; - this.hasControls = this._savedProps.hasControls; - this.borderColor = this._savedProps.borderColor; - this.selectable = this._savedProps.selectable; - this.lockMovementX = this._savedProps.lockMovementX; - this.lockMovementY = this._savedProps.lockMovementY; - - if (this.canvas) { - this.canvas.defaultCursor = this._savedProps.defaultCursor; - this.canvas.moveCursor = this._savedProps.moveCursor; - } - }, - - /** - * Exits from editing state - * @return {fabric.IText} thisArg - * @chainable - */ - exitEditing: function() { - var isTextChanged = (this._textBeforeEdit !== this.text); - var hiddenTextarea = this.hiddenTextarea; - this.selected = false; - this.isEditing = false; - - this.selectionEnd = this.selectionStart; - - if (hiddenTextarea) { - hiddenTextarea.blur && hiddenTextarea.blur(); - hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea); - } - this.hiddenTextarea = null; - this.abortCursorAnimation(); - this._restoreEditingProps(); - this._currentCursorOpacity = 0; - if (this._shouldClearDimensionCache()) { - this.initDimensions(); - this.setCoords(); - } - this.fire('editing:exited'); - isTextChanged && this.fire('modified'); - if (this.canvas) { - this.canvas.off('mouse:move', this.mouseMoveHandler); - this.canvas.fire('text:editing:exited', { target: this }); - isTextChanged && this.canvas.fire('object:modified', { target: this }); - } - return this; - }, - - /** - * @private - */ - _removeExtraneousStyles: function() { - for (var prop in this.styles) { - if (!this._textLines[prop]) { - delete this.styles[prop]; - } - } - }, - - /** - * remove and reflow a style block from start to end. - * @param {Number} start linear start position for removal (included in removal) - * @param {Number} end linear end position for removal ( excluded from removal ) - */ - removeStyleFromTo: function(start, end) { - var cursorStart = this.get2DCursorLocation(start, true), - cursorEnd = this.get2DCursorLocation(end, true), - lineStart = cursorStart.lineIndex, - charStart = cursorStart.charIndex, - lineEnd = cursorEnd.lineIndex, - charEnd = cursorEnd.charIndex, - i, styleObj; - if (lineStart !== lineEnd) { - // step1 remove the trailing of lineStart - if (this.styles[lineStart]) { - for (i = charStart; i < this._unwrappedTextLines[lineStart].length; i++) { - delete this.styles[lineStart][i]; - } - } - // step2 move the trailing of lineEnd to lineStart if needed - if (this.styles[lineEnd]) { - for (i = charEnd; i < this._unwrappedTextLines[lineEnd].length; i++) { - styleObj = this.styles[lineEnd][i]; - if (styleObj) { - this.styles[lineStart] || (this.styles[lineStart] = { }); - this.styles[lineStart][charStart + i - charEnd] = styleObj; - } - } - } - // step3 detects lines will be completely removed. - for (i = lineStart + 1; i <= lineEnd; i++) { - delete this.styles[i]; - } - // step4 shift remaining lines. - this.shiftLineStyles(lineEnd, lineStart - lineEnd); - } - else { - // remove and shift left on the same line - if (this.styles[lineStart]) { - styleObj = this.styles[lineStart]; - var diff = charEnd - charStart, numericChar, _char; - for (i = charStart; i < charEnd; i++) { - delete styleObj[i]; - } - for (_char in this.styles[lineStart]) { - numericChar = parseInt(_char, 10); - if (numericChar >= charEnd) { - styleObj[numericChar - diff] = styleObj[_char]; - delete styleObj[_char]; - } - } - } - } - }, - - /** - * Shifts line styles up or down - * @param {Number} lineIndex Index of a line - * @param {Number} offset Can any number? - */ - shiftLineStyles: function(lineIndex, offset) { - // shift all line styles by offset upward or downward - // do not clone deep. we need new array, not new style objects - var clonedStyles = clone(this.styles); - for (var line in this.styles) { - var numericLine = parseInt(line, 10); - if (numericLine > lineIndex) { - this.styles[numericLine + offset] = clonedStyles[numericLine]; - if (!clonedStyles[numericLine - offset]) { - delete this.styles[numericLine]; - } - } - } - }, - - restartCursorIfNeeded: function() { - if (!this._currentTickState || this._currentTickState.isAborted - || !this._currentTickCompleteState || this._currentTickCompleteState.isAborted - ) { - this.initDelayedCursor(); - } - }, - - /** - * Handle insertion of more consecutive style lines for when one or more - * newlines gets added to the text. Since current style needs to be shifted - * first we shift the current style of the number lines needed, then we add - * new lines from the last to the first. - * @param {Number} lineIndex Index of a line - * @param {Number} charIndex Index of a char - * @param {Number} qty number of lines to add - * @param {Array} copiedStyle Array of objects styles - */ - insertNewlineStyleObject: function(lineIndex, charIndex, qty, copiedStyle) { - var currentCharStyle, - newLineStyles = {}, - somethingAdded = false, - isEndOfLine = this._unwrappedTextLines[lineIndex].length === charIndex; - - qty || (qty = 1); - this.shiftLineStyles(lineIndex, qty); - if (this.styles[lineIndex]) { - currentCharStyle = this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1]; - } - // we clone styles of all chars - // after cursor onto the current line - for (var index in this.styles[lineIndex]) { - var numIndex = parseInt(index, 10); - if (numIndex >= charIndex) { - somethingAdded = true; - newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index]; - // remove lines from the previous line since they're on a new line now - if (!(isEndOfLine && charIndex === 0)) { - delete this.styles[lineIndex][index]; - } - } - } - var styleCarriedOver = false; - if (somethingAdded && !isEndOfLine) { - // if is end of line, the extra style we copied - // is probably not something we want - this.styles[lineIndex + qty] = newLineStyles; - styleCarriedOver = true; - } - if (styleCarriedOver) { - // skip the last line of since we already prepared it. - qty--; - } - // for the all the lines or all the other lines - // we clone current char style onto the next (otherwise empty) line - while (qty > 0) { - if (copiedStyle && copiedStyle[qty - 1]) { - this.styles[lineIndex + qty] = { 0: clone(copiedStyle[qty - 1]) }; - } - else if (currentCharStyle) { - this.styles[lineIndex + qty] = { 0: clone(currentCharStyle) }; - } - else { - delete this.styles[lineIndex + qty]; - } - qty--; - } - this._forceClearCache = true; - }, - - /** - * Inserts style object for a given line/char index - * @param {Number} lineIndex Index of a line - * @param {Number} charIndex Index of a char - * @param {Number} quantity number Style object to insert, if given - * @param {Array} copiedStyle array of style objects - */ - insertCharStyleObject: function(lineIndex, charIndex, quantity, copiedStyle) { - if (!this.styles) { - this.styles = {}; - } - var currentLineStyles = this.styles[lineIndex], - currentLineStylesCloned = currentLineStyles ? clone(currentLineStyles) : {}; - - quantity || (quantity = 1); - // shift all char styles by quantity forward - // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4 - for (var index in currentLineStylesCloned) { - var numericIndex = parseInt(index, 10); - if (numericIndex >= charIndex) { - currentLineStyles[numericIndex + quantity] = currentLineStylesCloned[numericIndex]; - // only delete the style if there was nothing moved there - if (!currentLineStylesCloned[numericIndex - quantity]) { - delete currentLineStyles[numericIndex]; - } - } - } - this._forceClearCache = true; - if (copiedStyle) { - while (quantity--) { - if (!Object.keys(copiedStyle[quantity]).length) { - continue; - } - if (!this.styles[lineIndex]) { - this.styles[lineIndex] = {}; - } - this.styles[lineIndex][charIndex + quantity] = clone(copiedStyle[quantity]); - } - return; - } - if (!currentLineStyles) { - return; - } - var newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1]; - while (newStyle && quantity--) { - this.styles[lineIndex][charIndex + quantity] = clone(newStyle); - } - }, - - /** - * Inserts style object(s) - * @param {Array} insertedText Characters at the location where style is inserted - * @param {Number} start cursor index for inserting style - * @param {Array} [copiedStyle] array of style objects to insert. - */ - insertNewStyleBlock: function(insertedText, start, copiedStyle) { - var cursorLoc = this.get2DCursorLocation(start, true), - addedLines = [0], linesLength = 0; - // get an array of how many char per lines are being added. - for (var i = 0; i < insertedText.length; i++) { - if (insertedText[i] === '\n') { - linesLength++; - addedLines[linesLength] = 0; - } - else { - addedLines[linesLength]++; - } - } - // for the first line copy the style from the current char position. - if (addedLines[0] > 0) { - this.insertCharStyleObject(cursorLoc.lineIndex, cursorLoc.charIndex, addedLines[0], copiedStyle); - copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1); - } - linesLength && this.insertNewlineStyleObject( - cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLength); - for (var i = 1; i < linesLength; i++) { - if (addedLines[i] > 0) { - this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle); - } - else if (copiedStyle) { - this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0]; - } - copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1); - } - // we use i outside the loop to get it like linesLength - if (addedLines[i] > 0) { - this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle); - } - }, - - /** - * Set the selectionStart and selectionEnd according to the new position of cursor - * mimic the key - mouse navigation when shift is pressed. - */ - setSelectionStartEndWithShift: function(start, end, newSelection) { - if (newSelection <= start) { - if (end === start) { - this._selectionDirection = 'left'; - } - else if (this._selectionDirection === 'right') { - this._selectionDirection = 'left'; - this.selectionEnd = start; - } - this.selectionStart = newSelection; - } - else if (newSelection > start && newSelection < end) { - if (this._selectionDirection === 'right') { - this.selectionEnd = newSelection; - } - else { - this.selectionStart = newSelection; - } - } - else { - // newSelection is > selection start and end - if (end === start) { - this._selectionDirection = 'right'; - } - else if (this._selectionDirection === 'left') { - this._selectionDirection = 'right'; - this.selectionStart = end; - } - this.selectionEnd = newSelection; - } - }, - - setSelectionInBoundaries: function() { - var length = this.text.length; - if (this.selectionStart > length) { - this.selectionStart = length; - } - else if (this.selectionStart < 0) { - this.selectionStart = 0; - } - if (this.selectionEnd > length) { - this.selectionEnd = length; - } - else if (this.selectionEnd < 0) { - this.selectionEnd = 0; - } - } - }); -})(); - - -fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ { - /** - * Initializes "dbclick" event handler - */ - initDoubleClickSimulation: function() { - - // for double click - this.__lastClickTime = +new Date(); - - // for triple click - this.__lastLastClickTime = +new Date(); - - this.__lastPointer = { }; - - this.on('mousedown', this.onMouseDown); - }, - - /** - * Default event handler to simulate triple click - * @private - */ - onMouseDown: function(options) { - if (!this.canvas) { - return; - } - this.__newClickTime = +new Date(); - var newPointer = options.pointer; - if (this.isTripleClick(newPointer)) { - this.fire('tripleclick', options); - this._stopEvent(options.e); - } - this.__lastLastClickTime = this.__lastClickTime; - this.__lastClickTime = this.__newClickTime; - this.__lastPointer = newPointer; - this.__lastIsEditing = this.isEditing; - this.__lastSelected = this.selected; - }, - - isTripleClick: function(newPointer) { - return this.__newClickTime - this.__lastClickTime < 500 && - this.__lastClickTime - this.__lastLastClickTime < 500 && - this.__lastPointer.x === newPointer.x && - this.__lastPointer.y === newPointer.y; - }, - - /** - * @private - */ - _stopEvent: function(e) { - e.preventDefault && e.preventDefault(); - e.stopPropagation && e.stopPropagation(); - }, - - /** - * Initializes event handlers related to cursor or selection - */ - initCursorSelectionHandlers: function() { - this.initMousedownHandler(); - this.initMouseupHandler(); - this.initClicks(); - }, - - /** - * Default handler for double click, select a word - */ - doubleClickHandler: function(options) { - if (!this.isEditing) { - return; - } - this.selectWord(this.getSelectionStartFromPointer(options.e)); - }, - - /** - * Default handler for triple click, select a line - */ - tripleClickHandler: function(options) { - if (!this.isEditing) { - return; - } - this.selectLine(this.getSelectionStartFromPointer(options.e)); - }, - - /** - * Initializes double and triple click event handlers - */ - initClicks: function() { - this.on('mousedblclick', this.doubleClickHandler); - this.on('tripleclick', this.tripleClickHandler); - }, - - /** - * Default event handler for the basic functionalities needed on _mouseDown - * can be overridden to do something different. - * Scope of this implementation is: find the click position, set selectionStart - * find selectionEnd, initialize the drawing of either cursor or selection area - * initializing a mousedDown on a text area will cancel fabricjs knowledge of - * current compositionMode. It will be set to false. - */ - _mouseDownHandler: function(options) { - if (!this.canvas || !this.editable || (options.e.button && options.e.button !== 1)) { - return; - } - - this.__isMousedown = true; - - if (this.selected) { - this.inCompositionMode = false; - this.setCursorByClick(options.e); - } - - if (this.isEditing) { - this.__selectionStartOnMouseDown = this.selectionStart; - if (this.selectionStart === this.selectionEnd) { - this.abortCursorAnimation(); - } - this.renderCursorOrSelection(); - } - }, - - /** - * Default event handler for the basic functionalities needed on mousedown:before - * can be overridden to do something different. - * Scope of this implementation is: verify the object is already selected when mousing down - */ - _mouseDownHandlerBefore: function(options) { - if (!this.canvas || !this.editable || (options.e.button && options.e.button !== 1)) { - return; - } - // we want to avoid that an object that was selected and then becomes unselectable, - // may trigger editing mode in some way. - this.selected = this === this.canvas._activeObject; - }, - - /** - * Initializes "mousedown" event handler - */ - initMousedownHandler: function() { - this.on('mousedown', this._mouseDownHandler); - this.on('mousedown:before', this._mouseDownHandlerBefore); - }, - - /** - * Initializes "mouseup" event handler - */ - initMouseupHandler: function() { - this.on('mouseup', this.mouseUpHandler); - }, - - /** - * standard handler for mouse up, overridable - * @private - */ - mouseUpHandler: function(options) { - this.__isMousedown = false; - if (!this.editable || this.group || - (options.transform && options.transform.actionPerformed) || - (options.e.button && options.e.button !== 1)) { - return; - } - - if (this.canvas) { - var currentActive = this.canvas._activeObject; - if (currentActive && currentActive !== this) { - // avoid running this logic when there is an active object - // this because is possible with shift click and fast clicks, - // to rapidly deselect and reselect this object and trigger an enterEdit - return; - } - } - - if (this.__lastSelected && !this.__corner) { - this.selected = false; - this.__lastSelected = false; - this.enterEditing(options.e); - if (this.selectionStart === this.selectionEnd) { - this.initDelayedCursor(true); - } - else { - this.renderCursorOrSelection(); - } - } - else { - this.selected = true; - } - }, - - /** - * Changes cursor location in a text depending on passed pointer (x/y) object - * @param {Event} e Event object - */ - setCursorByClick: function(e) { - var newSelection = this.getSelectionStartFromPointer(e), - start = this.selectionStart, end = this.selectionEnd; - if (e.shiftKey) { - this.setSelectionStartEndWithShift(start, end, newSelection); - } - else { - this.selectionStart = newSelection; - this.selectionEnd = newSelection; - } - if (this.isEditing) { - this._fireSelectionChanged(); - this._updateTextarea(); - } - }, - - /** - * Returns index of a character corresponding to where an object was clicked - * @param {Event} e Event object - * @return {Number} Index of a character - */ - getSelectionStartFromPointer: function(e) { - var mouseOffset = this.getLocalPointer(e), - prevWidth = 0, - width = 0, - height = 0, - charIndex = 0, - lineIndex = 0, - lineLeftOffset, - line; - for (var i = 0, len = this._textLines.length; i < len; i++) { - if (height <= mouseOffset.y) { - height += this.getHeightOfLine(i) * this.scaleY; - lineIndex = i; - if (i > 0) { - charIndex += this._textLines[i - 1].length + this.missingNewlineOffset(i - 1); - } - } - else { - break; - } - } - lineLeftOffset = this._getLineLeftOffset(lineIndex); - width = lineLeftOffset * this.scaleX; - line = this._textLines[lineIndex]; - // handling of RTL: in order to get things work correctly, - // we assume RTL writing is mirrored compared to LTR writing. - // so in position detection we mirror the X offset, and when is time - // of rendering it, we mirror it again. - if (this.direction === 'rtl') { - mouseOffset.x = this.width * this.scaleX - mouseOffset.x + width; - } - for (var j = 0, jlen = line.length; j < jlen; j++) { - prevWidth = width; - // i removed something about flipX here, check. - width += this.__charBounds[lineIndex][j].kernedWidth * this.scaleX; - if (width <= mouseOffset.x) { - charIndex++; - } - else { - break; - } - } - return this._getNewSelectionStartFromOffset(mouseOffset, prevWidth, width, charIndex, jlen); - }, - - /** - * @private - */ - _getNewSelectionStartFromOffset: function(mouseOffset, prevWidth, width, index, jlen) { - // we need Math.abs because when width is after the last char, the offset is given as 1, while is 0 - var distanceBtwLastCharAndCursor = mouseOffset.x - prevWidth, - distanceBtwNextCharAndCursor = width - mouseOffset.x, - offset = distanceBtwNextCharAndCursor > distanceBtwLastCharAndCursor || - distanceBtwNextCharAndCursor < 0 ? 0 : 1, - newSelectionStart = index + offset; - // if object is horizontally flipped, mirror cursor location from the end - if (this.flipX) { - newSelectionStart = jlen - newSelectionStart; - } - - if (newSelectionStart > this._text.length) { - newSelectionStart = this._text.length; - } - - return newSelectionStart; - } -}); - - -fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ { - - /** - * Initializes hidden textarea (needed to bring up keyboard in iOS) - */ - initHiddenTextarea: function() { - this.hiddenTextarea = fabric.document.createElement('textarea'); - this.hiddenTextarea.setAttribute('autocapitalize', 'off'); - this.hiddenTextarea.setAttribute('autocorrect', 'off'); - this.hiddenTextarea.setAttribute('autocomplete', 'off'); - this.hiddenTextarea.setAttribute('spellcheck', 'false'); - this.hiddenTextarea.setAttribute('data-fabric-hiddentextarea', ''); - this.hiddenTextarea.setAttribute('wrap', 'off'); - var style = this._calcTextareaPosition(); - // line-height: 1px; was removed from the style to fix this: - // https://bugs.chromium.org/p/chromium/issues/detail?id=870966 - this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top + - '; left: ' + style.left + '; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px;' + - ' paddingーtop: ' + style.fontSize + ';'; - fabric.document.body.appendChild(this.hiddenTextarea); - - fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'keyup', this.onKeyUp.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'input', this.onInput.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'copy', this.copy.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'cut', this.copy.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'paste', this.paste.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'compositionstart', this.onCompositionStart.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'compositionupdate', this.onCompositionUpdate.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'compositionend', this.onCompositionEnd.bind(this)); - - if (!this._clickHandlerInitialized && this.canvas) { - fabric.util.addListener(this.canvas.upperCanvasEl, 'click', this.onClick.bind(this)); - this._clickHandlerInitialized = true; - } - }, - - /** - * For functionalities on keyDown - * Map a special key to a function of the instance/prototype - * If you need different behaviour for ESC or TAB or arrows, you have to change - * this map setting the name of a function that you build on the fabric.Itext or - * your prototype. - * the map change will affect all Instances unless you need for only some text Instances - * in that case you have to clone this object and assign your Instance. - * this.keysMap = fabric.util.object.clone(this.keysMap); - * The function must be in fabric.Itext.prototype.myFunction And will receive event as args[0] - */ - keysMap: { - 9: 'exitEditing', - 27: 'exitEditing', - 33: 'moveCursorUp', - 34: 'moveCursorDown', - 35: 'moveCursorRight', - 36: 'moveCursorLeft', - 37: 'moveCursorLeft', - 38: 'moveCursorUp', - 39: 'moveCursorRight', - 40: 'moveCursorDown', - }, - - keysMapRtl: { - 9: 'exitEditing', - 27: 'exitEditing', - 33: 'moveCursorUp', - 34: 'moveCursorDown', - 35: 'moveCursorLeft', - 36: 'moveCursorRight', - 37: 'moveCursorRight', - 38: 'moveCursorUp', - 39: 'moveCursorLeft', - 40: 'moveCursorDown', - }, - - /** - * For functionalities on keyUp + ctrl || cmd - */ - ctrlKeysMapUp: { - 67: 'copy', - 88: 'cut' - }, - - /** - * For functionalities on keyDown + ctrl || cmd - */ - ctrlKeysMapDown: { - 65: 'selectAll' - }, - - onClick: function() { - // No need to trigger click event here, focus is enough to have the keyboard appear on Android - this.hiddenTextarea && this.hiddenTextarea.focus(); - }, - - /** - * Handles keydown event - * only used for arrows and combination of modifier keys. - * @param {Event} e Event object - */ - onKeyDown: function(e) { - if (!this.isEditing) { - return; - } - var keyMap = this.direction === 'rtl' ? this.keysMapRtl : this.keysMap; - if (e.keyCode in keyMap) { - this[keyMap[e.keyCode]](e); - } - else if ((e.keyCode in this.ctrlKeysMapDown) && (e.ctrlKey || e.metaKey)) { - this[this.ctrlKeysMapDown[e.keyCode]](e); - } - else { - return; - } - e.stopImmediatePropagation(); - e.preventDefault(); - if (e.keyCode >= 33 && e.keyCode <= 40) { - // if i press an arrow key just update selection - this.inCompositionMode = false; - this.clearContextTop(); - this.renderCursorOrSelection(); - } - else { - this.canvas && this.canvas.requestRenderAll(); - } - }, - - /** - * Handles keyup event - * We handle KeyUp because ie11 and edge have difficulties copy/pasting - * if a copy/cut event fired, keyup is dismissed - * @param {Event} e Event object - */ - onKeyUp: function(e) { - if (!this.isEditing || this._copyDone || this.inCompositionMode) { - this._copyDone = false; - return; - } - if ((e.keyCode in this.ctrlKeysMapUp) && (e.ctrlKey || e.metaKey)) { - this[this.ctrlKeysMapUp[e.keyCode]](e); - } - else { - return; - } - e.stopImmediatePropagation(); - e.preventDefault(); - this.canvas && this.canvas.requestRenderAll(); - }, - - /** - * Handles onInput event - * @param {Event} e Event object - */ - onInput: function(e) { - var fromPaste = this.fromPaste; - this.fromPaste = false; - e && e.stopPropagation(); - if (!this.isEditing) { - return; - } - // decisions about style changes. - var nextText = this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText, - charCount = this._text.length, - nextCharCount = nextText.length, - removedText, insertedText, - charDiff = nextCharCount - charCount, - selectionStart = this.selectionStart, selectionEnd = this.selectionEnd, - selection = selectionStart !== selectionEnd, - copiedStyle, removeFrom, removeTo; - if (this.hiddenTextarea.value === '') { - this.styles = { }; - this.updateFromTextArea(); - this.fire('changed'); - if (this.canvas) { - this.canvas.fire('text:changed', { target: this }); - this.canvas.requestRenderAll(); - } - return; - } - - var textareaSelection = this.fromStringToGraphemeSelection( - this.hiddenTextarea.selectionStart, - this.hiddenTextarea.selectionEnd, - this.hiddenTextarea.value - ); - var backDelete = selectionStart > textareaSelection.selectionStart; - - if (selection) { - removedText = this._text.slice(selectionStart, selectionEnd); - charDiff += selectionEnd - selectionStart; - } - else if (nextCharCount < charCount) { - if (backDelete) { - removedText = this._text.slice(selectionEnd + charDiff, selectionEnd); - } - else { - removedText = this._text.slice(selectionStart, selectionStart - charDiff); - } - } - insertedText = nextText.slice(textareaSelection.selectionEnd - charDiff, textareaSelection.selectionEnd); - if (removedText && removedText.length) { - if (insertedText.length) { - // let's copy some style before deleting. - // we want to copy the style before the cursor OR the style at the cursor if selection - // is bigger than 0. - copiedStyle = this.getSelectionStyles(selectionStart, selectionStart + 1, false); - // now duplicate the style one for each inserted text. - copiedStyle = insertedText.map(function() { - // this return an array of references, but that is fine since we are - // copying the style later. - return copiedStyle[0]; - }); - } - if (selection) { - removeFrom = selectionStart; - removeTo = selectionEnd; - } - else if (backDelete) { - // detect differences between forwardDelete and backDelete - removeFrom = selectionEnd - removedText.length; - removeTo = selectionEnd; - } - else { - removeFrom = selectionEnd; - removeTo = selectionEnd + removedText.length; - } - this.removeStyleFromTo(removeFrom, removeTo); - } - if (insertedText.length) { - if (fromPaste && insertedText.join('') === fabric.copiedText && !fabric.disableStyleCopyPaste) { - copiedStyle = fabric.copiedTextStyle; - } - this.insertNewStyleBlock(insertedText, selectionStart, copiedStyle); - } - this.updateFromTextArea(); - this.fire('changed'); - if (this.canvas) { - this.canvas.fire('text:changed', { target: this }); - this.canvas.requestRenderAll(); - } - }, - /** - * Composition start - */ - onCompositionStart: function() { - this.inCompositionMode = true; - }, - - /** - * Composition end - */ - onCompositionEnd: function() { - this.inCompositionMode = false; - }, - - // /** - // * Composition update - // */ - onCompositionUpdate: function(e) { - this.compositionStart = e.target.selectionStart; - this.compositionEnd = e.target.selectionEnd; - this.updateTextareaPosition(); - }, - - /** - * Copies selected text - * @param {Event} e Event object - */ - copy: function() { - if (this.selectionStart === this.selectionEnd) { - //do not cut-copy if no selection - return; - } - - fabric.copiedText = this.getSelectedText(); - if (!fabric.disableStyleCopyPaste) { - fabric.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd, true); - } - else { - fabric.copiedTextStyle = null; - } - this._copyDone = true; - }, - - /** - * Pastes text - * @param {Event} e Event object - */ - paste: function() { - this.fromPaste = true; - }, - - /** - * @private - * @param {Event} e Event object - * @return {Object} Clipboard data object - */ - _getClipboardData: function(e) { - return (e && e.clipboardData) || fabric.window.clipboardData; - }, - - /** - * Finds the width in pixels before the cursor on the same line - * @private - * @param {Number} lineIndex - * @param {Number} charIndex - * @return {Number} widthBeforeCursor width before cursor - */ - _getWidthBeforeCursor: function(lineIndex, charIndex) { - var widthBeforeCursor = this._getLineLeftOffset(lineIndex), bound; - - if (charIndex > 0) { - bound = this.__charBounds[lineIndex][charIndex - 1]; - widthBeforeCursor += bound.left + bound.width; - } - return widthBeforeCursor; - }, - - /** - * Gets start offset of a selection - * @param {Event} e Event object - * @param {Boolean} isRight - * @return {Number} - */ - getDownCursorOffset: function(e, isRight) { - var selectionProp = this._getSelectionForOffset(e, isRight), - cursorLocation = this.get2DCursorLocation(selectionProp), - lineIndex = cursorLocation.lineIndex; - // if on last line, down cursor goes to end of line - if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) { - // move to the end of a text - return this._text.length - selectionProp; - } - var charIndex = cursorLocation.charIndex, - widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex), - indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor), - textAfterCursor = this._textLines[lineIndex].slice(charIndex); - return textAfterCursor.length + indexOnOtherLine + 1 + this.missingNewlineOffset(lineIndex); - }, - - /** - * private - * Helps finding if the offset should be counted from Start or End - * @param {Event} e Event object - * @param {Boolean} isRight - * @return {Number} - */ - _getSelectionForOffset: function(e, isRight) { - if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) { - return this.selectionEnd; - } - else { - return this.selectionStart; - } - }, - - /** - * @param {Event} e Event object - * @param {Boolean} isRight - * @return {Number} - */ - getUpCursorOffset: function(e, isRight) { - var selectionProp = this._getSelectionForOffset(e, isRight), - cursorLocation = this.get2DCursorLocation(selectionProp), - lineIndex = cursorLocation.lineIndex; - if (lineIndex === 0 || e.metaKey || e.keyCode === 33) { - // if on first line, up cursor goes to start of line - return -selectionProp; - } - var charIndex = cursorLocation.charIndex, - widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex), - indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor), - textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex), - missingNewlineOffset = this.missingNewlineOffset(lineIndex - 1); - // return a negative offset - return -this._textLines[lineIndex - 1].length - + indexOnOtherLine - textBeforeCursor.length + (1 - missingNewlineOffset); - }, - - /** - * for a given width it founds the matching character. - * @private - */ - _getIndexOnLine: function(lineIndex, width) { - - var line = this._textLines[lineIndex], - lineLeftOffset = this._getLineLeftOffset(lineIndex), - widthOfCharsOnLine = lineLeftOffset, - indexOnLine = 0, charWidth, foundMatch; - - for (var j = 0, jlen = line.length; j < jlen; j++) { - charWidth = this.__charBounds[lineIndex][j].width; - widthOfCharsOnLine += charWidth; - if (widthOfCharsOnLine > width) { - foundMatch = true; - var leftEdge = widthOfCharsOnLine - charWidth, - rightEdge = widthOfCharsOnLine, - offsetFromLeftEdge = Math.abs(leftEdge - width), - offsetFromRightEdge = Math.abs(rightEdge - width); - - indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : (j - 1); - break; - } - } - - // reached end - if (!foundMatch) { - indexOnLine = line.length - 1; - } - - return indexOnLine; - }, - - - /** - * Moves cursor down - * @param {Event} e Event object - */ - moveCursorDown: function(e) { - if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) { - return; - } - this._moveCursorUpOrDown('Down', e); - }, - - /** - * Moves cursor up - * @param {Event} e Event object - */ - moveCursorUp: function(e) { - if (this.selectionStart === 0 && this.selectionEnd === 0) { - return; - } - this._moveCursorUpOrDown('Up', e); - }, - - /** - * Moves cursor up or down, fires the events - * @param {String} direction 'Up' or 'Down' - * @param {Event} e Event object - */ - _moveCursorUpOrDown: function(direction, e) { - // getUpCursorOffset - // getDownCursorOffset - var action = 'get' + direction + 'CursorOffset', - offset = this[action](e, this._selectionDirection === 'right'); - if (e.shiftKey) { - this.moveCursorWithShift(offset); - } - else { - this.moveCursorWithoutShift(offset); - } - if (offset !== 0) { - this.setSelectionInBoundaries(); - this.abortCursorAnimation(); - this._currentCursorOpacity = 1; - this.initDelayedCursor(); - this._fireSelectionChanged(); - this._updateTextarea(); - } - }, - - /** - * Moves cursor with shift - * @param {Number} offset - */ - moveCursorWithShift: function(offset) { - var newSelection = this._selectionDirection === 'left' - ? this.selectionStart + offset - : this.selectionEnd + offset; - this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, newSelection); - return offset !== 0; - }, - - /** - * Moves cursor up without shift - * @param {Number} offset - */ - moveCursorWithoutShift: function(offset) { - if (offset < 0) { - this.selectionStart += offset; - this.selectionEnd = this.selectionStart; - } - else { - this.selectionEnd += offset; - this.selectionStart = this.selectionEnd; - } - return offset !== 0; - }, - - /** - * Moves cursor left - * @param {Event} e Event object - */ - moveCursorLeft: function(e) { - if (this.selectionStart === 0 && this.selectionEnd === 0) { - return; - } - this._moveCursorLeftOrRight('Left', e); - }, - - /** - * @private - * @return {Boolean} true if a change happened - */ - _move: function(e, prop, direction) { - var newValue; - if (e.altKey) { - newValue = this['findWordBoundary' + direction](this[prop]); - } - else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36 ) { - newValue = this['findLineBoundary' + direction](this[prop]); - } - else { - this[prop] += direction === 'Left' ? -1 : 1; - return true; - } - if (typeof newValue !== undefined && this[prop] !== newValue) { - this[prop] = newValue; - return true; - } - }, - - /** - * @private - */ - _moveLeft: function(e, prop) { - return this._move(e, prop, 'Left'); - }, - - /** - * @private - */ - _moveRight: function(e, prop) { - return this._move(e, prop, 'Right'); - }, - - /** - * Moves cursor left without keeping selection - * @param {Event} e - */ - moveCursorLeftWithoutShift: function(e) { - var change = true; - this._selectionDirection = 'left'; - - // only move cursor when there is no selection, - // otherwise we discard it, and leave cursor on same place - if (this.selectionEnd === this.selectionStart && this.selectionStart !== 0) { - change = this._moveLeft(e, 'selectionStart'); - - } - this.selectionEnd = this.selectionStart; - return change; - }, - - /** - * Moves cursor left while keeping selection - * @param {Event} e - */ - moveCursorLeftWithShift: function(e) { - if (this._selectionDirection === 'right' && this.selectionStart !== this.selectionEnd) { - return this._moveLeft(e, 'selectionEnd'); - } - else if (this.selectionStart !== 0){ - this._selectionDirection = 'left'; - return this._moveLeft(e, 'selectionStart'); - } - }, - - /** - * Moves cursor right - * @param {Event} e Event object - */ - moveCursorRight: function(e) { - if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) { - return; - } - this._moveCursorLeftOrRight('Right', e); - }, - - /** - * Moves cursor right or Left, fires event - * @param {String} direction 'Left', 'Right' - * @param {Event} e Event object - */ - _moveCursorLeftOrRight: function(direction, e) { - var actionName = 'moveCursor' + direction + 'With'; - this._currentCursorOpacity = 1; - - if (e.shiftKey) { - actionName += 'Shift'; - } - else { - actionName += 'outShift'; - } - if (this[actionName](e)) { - this.abortCursorAnimation(); - this.initDelayedCursor(); - this._fireSelectionChanged(); - this._updateTextarea(); - } - }, - - /** - * Moves cursor right while keeping selection - * @param {Event} e - */ - moveCursorRightWithShift: function(e) { - if (this._selectionDirection === 'left' && this.selectionStart !== this.selectionEnd) { - return this._moveRight(e, 'selectionStart'); - } - else if (this.selectionEnd !== this._text.length) { - this._selectionDirection = 'right'; - return this._moveRight(e, 'selectionEnd'); - } - }, - - /** - * Moves cursor right without keeping selection - * @param {Event} e Event object - */ - moveCursorRightWithoutShift: function(e) { - var changed = true; - this._selectionDirection = 'right'; - - if (this.selectionStart === this.selectionEnd) { - changed = this._moveRight(e, 'selectionStart'); - this.selectionEnd = this.selectionStart; - } - else { - this.selectionStart = this.selectionEnd; - } - return changed; - }, - - /** - * Removes characters from start/end - * start/end ar per grapheme position in _text array. - * - * @param {Number} start - * @param {Number} end default to start + 1 - */ - removeChars: function(start, end) { - if (typeof end === 'undefined') { - end = start + 1; - } - this.removeStyleFromTo(start, end); - this._text.splice(start, end - start); - this.text = this._text.join(''); - this.set('dirty', true); - if (this._shouldClearDimensionCache()) { - this.initDimensions(); - this.setCoords(); - } - this._removeExtraneousStyles(); - }, - - /** - * insert characters at start position, before start position. - * start equal 1 it means the text get inserted between actual grapheme 0 and 1 - * if style array is provided, it must be as the same length of text in graphemes - * if end is provided and is bigger than start, old text is replaced. - * start/end ar per grapheme position in _text array. - * - * @param {String} text text to insert - * @param {Array} style array of style objects - * @param {Number} start - * @param {Number} end default to start + 1 - */ - insertChars: function(text, style, start, end) { - if (typeof end === 'undefined') { - end = start; - } - if (end > start) { - this.removeStyleFromTo(start, end); - } - var graphemes = fabric.util.string.graphemeSplit(text); - this.insertNewStyleBlock(graphemes, start, style); - this._text = [].concat(this._text.slice(0, start), graphemes, this._text.slice(end)); - this.text = this._text.join(''); - this.set('dirty', true); - if (this._shouldClearDimensionCache()) { - this.initDimensions(); - this.setCoords(); - } - this._removeExtraneousStyles(); - }, - -}); - - -/* _TO_SVG_START_ */ -(function() { - var toFixed = fabric.util.toFixed, - multipleSpacesRegex = / +/g; - - fabric.util.object.extend(fabric.Text.prototype, /** @lends fabric.Text.prototype */ { - - /** - * Returns SVG representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - _toSVG: function() { - var offsets = this._getSVGLeftTopOffsets(), - textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft); - return this._wrapSVGTextAndBg(textAndBg); - }, - - /** - * Returns svg representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toSVG: function(reviver) { - return this._createBaseSVGMarkup( - this._toSVG(), - { reviver: reviver, noStyle: true, withShadow: true } - ); - }, - - /** - * @private - */ - _getSVGLeftTopOffsets: function() { - return { - textLeft: -this.width / 2, - textTop: -this.height / 2, - lineTop: this.getHeightOfLine(0) - }; - }, - - /** - * @private - */ - _wrapSVGTextAndBg: function(textAndBg) { - var noShadow = true, - textDecoration = this.getSvgTextDecoration(this); - return [ - textAndBg.textBgRects.join(''), - '\t\t', - textAndBg.textSpans.join(''), - '\n' - ]; - }, - - /** - * @private - * @param {Number} textTopOffset Text top offset - * @param {Number} textLeftOffset Text left offset - * @return {Object} - */ - _getSVGTextAndBg: function(textTopOffset, textLeftOffset) { - var textSpans = [], - textBgRects = [], - height = textTopOffset, lineOffset; - // bounding-box background - this._setSVGBg(textBgRects); - - // text and text-background - for (var i = 0, len = this._textLines.length; i < len; i++) { - lineOffset = this._getLineLeftOffset(i); - if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) { - this._setSVGTextLineBg(textBgRects, i, textLeftOffset + lineOffset, height); - } - this._setSVGTextLineText(textSpans, i, textLeftOffset + lineOffset, height); - height += this.getHeightOfLine(i); - } - - return { - textSpans: textSpans, - textBgRects: textBgRects - }; - }, - - /** - * @private - */ - _createTextCharSpan: function(_char, styleDecl, left, top) { - var shouldUseWhitespace = _char !== _char.trim() || _char.match(multipleSpacesRegex), - styleProps = this.getSvgSpanStyles(styleDecl, shouldUseWhitespace), - fillStyles = styleProps ? 'style="' + styleProps + '"' : '', - dy = styleDecl.deltaY, dySpan = '', - NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - if (dy) { - dySpan = ' dy="' + toFixed(dy, NUM_FRACTION_DIGITS) + '" '; - } - return [ - '', - fabric.util.string.escapeXml(_char), - '' - ].join(''); - }, - - _setSVGTextLineText: function(textSpans, lineIndex, textLeftOffset, textTopOffset) { - // set proper line offset - var lineHeight = this.getHeightOfLine(lineIndex), - isJustify = this.textAlign.indexOf('justify') !== -1, - actualStyle, - nextStyle, - charsToRender = '', - charBox, style, - boxWidth = 0, - line = this._textLines[lineIndex], - timeToRender; - - textTopOffset += lineHeight * (1 - this._fontSizeFraction) / this.lineHeight; - for (var i = 0, len = line.length - 1; i <= len; i++) { - timeToRender = i === len || this.charSpacing; - charsToRender += line[i]; - charBox = this.__charBounds[lineIndex][i]; - if (boxWidth === 0) { - textLeftOffset += charBox.kernedWidth - charBox.width; - boxWidth += charBox.width; - } - else { - boxWidth += charBox.kernedWidth; - } - if (isJustify && !timeToRender) { - if (this._reSpaceAndTab.test(line[i])) { - timeToRender = true; - } - } - if (!timeToRender) { - // if we have charSpacing, we render char by char - actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i); - nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1); - timeToRender = this._hasStyleChangedForSvg(actualStyle, nextStyle); - } - if (timeToRender) { - style = this._getStyleDeclaration(lineIndex, i) || { }; - textSpans.push(this._createTextCharSpan(charsToRender, style, textLeftOffset, textTopOffset)); - charsToRender = ''; - actualStyle = nextStyle; - textLeftOffset += boxWidth; - boxWidth = 0; - } - } - }, - - _pushTextBgRect: function(textBgRects, color, left, top, width, height) { - var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - textBgRects.push( - '\t\t\n'); - }, - - _setSVGTextLineBg: function(textBgRects, i, leftOffset, textTopOffset) { - var line = this._textLines[i], - heightOfLine = this.getHeightOfLine(i) / this.lineHeight, - boxWidth = 0, - boxStart = 0, - charBox, currentColor, - lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor'); - for (var j = 0, jlen = line.length; j < jlen; j++) { - charBox = this.__charBounds[i][j]; - currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor'); - if (currentColor !== lastColor) { - lastColor && this._pushTextBgRect(textBgRects, lastColor, leftOffset + boxStart, - textTopOffset, boxWidth, heightOfLine); - boxStart = charBox.left; - boxWidth = charBox.width; - lastColor = currentColor; - } - else { - boxWidth += charBox.kernedWidth; - } - } - currentColor && this._pushTextBgRect(textBgRects, currentColor, leftOffset + boxStart, - textTopOffset, boxWidth, heightOfLine); - }, - - /** - * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values - * we work around it by "moving" alpha channel into opacity attribute and setting fill's alpha to 1 - * - * @private - * @param {*} value - * @return {String} - */ - _getFillAttributes: function(value) { - var fillColor = (value && typeof value === 'string') ? new fabric.Color(value) : ''; - if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) { - return 'fill="' + value + '"'; - } - return 'opacity="' + fillColor.getAlpha() + '" fill="' + fillColor.setAlpha(1).toRgb() + '"'; - }, - - /** - * @private - */ - _getSVGLineTopOffset: function(lineIndex) { - var lineTopOffset = 0, lastHeight = 0; - for (var j = 0; j < lineIndex; j++) { - lineTopOffset += this.getHeightOfLine(j); - } - lastHeight = this.getHeightOfLine(j); - return { - lineTop: lineTopOffset, - offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult) - }; - }, - - /** - * Returns styles-string for svg-export - * @param {Boolean} skipShadow a boolean to skip shadow filter output - * @return {String} - */ - getSvgStyles: function(skipShadow) { - var svgStyle = fabric.Object.prototype.getSvgStyles.call(this, skipShadow); - return svgStyle + ' white-space: pre;'; - }, - }); -})(); -/* _TO_SVG_END_ */ - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = {}); - - /** - * Textbox class, based on IText, allows the user to resize the text rectangle - * and wraps lines automatically. Textboxes have their Y scaling locked, the - * user can only change width. Height is adjusted automatically based on the - * wrapping of lines. - * @class fabric.Textbox - * @extends fabric.IText - * @mixes fabric.Observable - * @return {fabric.Textbox} thisArg - * @see {@link fabric.Textbox#initialize} for constructor definition - */ - fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, { - - /** - * Type of an object - * @type String - * @default - */ - type: 'textbox', - - /** - * Minimum width of textbox, in pixels. - * @type Number - * @default - */ - minWidth: 20, - - /** - * Minimum calculated width of a textbox, in pixels. - * fixed to 2 so that an empty textbox cannot go to 0 - * and is still selectable without text. - * @type Number - * @default - */ - dynamicMinWidth: 2, - - /** - * Cached array of text wrapping. - * @type Array - */ - __cachedLines: null, - - /** - * Override standard Object class values - */ - lockScalingFlip: true, - - /** - * Override standard Object class values - * Textbox needs this on false - */ - noScaleCache: false, - - /** - * Properties which when set cause object to change dimensions - * @type Object - * @private - */ - _dimensionAffectingProps: fabric.Text.prototype._dimensionAffectingProps.concat('width'), - - /** - * Use this regular expression to split strings in breakable lines - * @private - */ - _wordJoiners: /[ \t\r]/, - - /** - * Use this boolean property in order to split strings that have no white space concept. - * this is a cheap way to help with chinese/japanese - * @type Boolean - * @since 2.6.0 - */ - splitByGrapheme: false, - - /** - * Unlike superclass's version of this function, Textbox does not update - * its width. - * @private - * @override - */ - initDimensions: function() { - if (this.__skipDimension) { - return; - } - this.isEditing && this.initDelayedCursor(); - this.clearContextTop(); - this._clearCache(); - // clear dynamicMinWidth as it will be different after we re-wrap line - this.dynamicMinWidth = 0; - // wrap lines - this._styleMap = this._generateStyleMap(this._splitText()); - // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap - if (this.dynamicMinWidth > this.width) { - this._set('width', this.dynamicMinWidth); - } - if (this.textAlign.indexOf('justify') !== -1) { - // once text is measured we need to make space fatter to make justified text. - this.enlargeSpaces(); - } - // clear cache and re-calculate height - this.height = this.calcTextHeight(); - this.saveState({ propertySet: '_dimensionAffectingProps' }); - }, - - /** - * Generate an object that translates the style object so that it is - * broken up by visual lines (new lines and automatic wrapping). - * The original text styles object is broken up by actual lines (new lines only), - * which is only sufficient for Text / IText - * @private - */ - _generateStyleMap: function(textInfo) { - var realLineCount = 0, - realLineCharCount = 0, - charCount = 0, - map = {}; - - for (var i = 0; i < textInfo.graphemeLines.length; i++) { - if (textInfo.graphemeText[charCount] === '\n' && i > 0) { - realLineCharCount = 0; - charCount++; - realLineCount++; - } - else if (!this.splitByGrapheme && this._reSpaceAndTab.test(textInfo.graphemeText[charCount]) && i > 0) { - // this case deals with space's that are removed from end of lines when wrapping - realLineCharCount++; - charCount++; - } - - map[i] = { line: realLineCount, offset: realLineCharCount }; - - charCount += textInfo.graphemeLines[i].length; - realLineCharCount += textInfo.graphemeLines[i].length; - } - - return map; - }, - - /** - * Returns true if object has a style property or has it on a specified line - * @param {Number} lineIndex - * @return {Boolean} - */ - styleHas: function(property, lineIndex) { - if (this._styleMap && !this.isWrapping) { - var map = this._styleMap[lineIndex]; - if (map) { - lineIndex = map.line; - } - } - return fabric.Text.prototype.styleHas.call(this, property, lineIndex); - }, - - /** - * Returns true if object has no styling or no styling in a line - * @param {Number} lineIndex , lineIndex is on wrapped lines. - * @return {Boolean} - */ - isEmptyStyles: function(lineIndex) { - if (!this.styles) { - return true; - } - var offset = 0, nextLineIndex = lineIndex + 1, nextOffset, obj, shouldLimit = false, - map = this._styleMap[lineIndex], mapNextLine = this._styleMap[lineIndex + 1]; - if (map) { - lineIndex = map.line; - offset = map.offset; - } - if (mapNextLine) { - nextLineIndex = mapNextLine.line; - shouldLimit = nextLineIndex === lineIndex; - nextOffset = mapNextLine.offset; - } - obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] }; - for (var p1 in obj) { - for (var p2 in obj[p1]) { - if (p2 >= offset && (!shouldLimit || p2 < nextOffset)) { - // eslint-disable-next-line no-unused-vars - for (var p3 in obj[p1][p2]) { - return false; - } - } - } - } - return true; - }, - - /** - * @param {Number} lineIndex - * @param {Number} charIndex - * @private - */ - _getStyleDeclaration: function(lineIndex, charIndex) { - if (this._styleMap && !this.isWrapping) { - var map = this._styleMap[lineIndex]; - if (!map) { - return null; - } - lineIndex = map.line; - charIndex = map.offset + charIndex; - } - return this.callSuper('_getStyleDeclaration', lineIndex, charIndex); - }, - - /** - * @param {Number} lineIndex - * @param {Number} charIndex - * @param {Object} style - * @private - */ - _setStyleDeclaration: function(lineIndex, charIndex, style) { - var map = this._styleMap[lineIndex]; - lineIndex = map.line; - charIndex = map.offset + charIndex; - - this.styles[lineIndex][charIndex] = style; - }, - - /** - * @param {Number} lineIndex - * @param {Number} charIndex - * @private - */ - _deleteStyleDeclaration: function(lineIndex, charIndex) { - var map = this._styleMap[lineIndex]; - lineIndex = map.line; - charIndex = map.offset + charIndex; - delete this.styles[lineIndex][charIndex]; - }, - - /** - * probably broken need a fix - * Returns the real style line that correspond to the wrapped lineIndex line - * Used just to verify if the line does exist or not. - * @param {Number} lineIndex - * @returns {Boolean} if the line exists or not - * @private - */ - _getLineStyle: function(lineIndex) { - var map = this._styleMap[lineIndex]; - return !!this.styles[map.line]; - }, - - /** - * Set the line style to an empty object so that is initialized - * @param {Number} lineIndex - * @param {Object} style - * @private - */ - _setLineStyle: function(lineIndex) { - var map = this._styleMap[lineIndex]; - this.styles[map.line] = {}; - }, - - /** - * Wraps text using the 'width' property of Textbox. First this function - * splits text on newlines, so we preserve newlines entered by the user. - * Then it wraps each line using the width of the Textbox by calling - * _wrapLine(). - * @param {Array} lines The string array of text that is split into lines - * @param {Number} desiredWidth width you want to wrap to - * @returns {Array} Array of lines - */ - _wrapText: function(lines, desiredWidth) { - var wrapped = [], i; - this.isWrapping = true; - for (i = 0; i < lines.length; i++) { - wrapped = wrapped.concat(this._wrapLine(lines[i], i, desiredWidth)); - } - this.isWrapping = false; - return wrapped; - }, - - /** - * Helper function to measure a string of text, given its lineIndex and charIndex offset - * it gets called when charBounds are not available yet. - * @param {CanvasRenderingContext2D} ctx - * @param {String} text - * @param {number} lineIndex - * @param {number} charOffset - * @returns {number} - * @private - */ - _measureWord: function(word, lineIndex, charOffset) { - var width = 0, prevGrapheme, skipLeft = true; - charOffset = charOffset || 0; - for (var i = 0, len = word.length; i < len; i++) { - var box = this._getGraphemeBox(word[i], lineIndex, i + charOffset, prevGrapheme, skipLeft); - width += box.kernedWidth; - prevGrapheme = word[i]; - } - return width; - }, - - /** - * Wraps a line of text using the width of the Textbox and a context. - * @param {Array} line The grapheme array that represent the line - * @param {Number} lineIndex - * @param {Number} desiredWidth width you want to wrap the line to - * @param {Number} reservedSpace space to remove from wrapping for custom functionalities - * @returns {Array} Array of line(s) into which the given text is wrapped - * to. - */ - _wrapLine: function(_line, lineIndex, desiredWidth, reservedSpace) { - var lineWidth = 0, - splitByGrapheme = this.splitByGrapheme, - graphemeLines = [], - line = [], - // spaces in different languages? - words = splitByGrapheme ? fabric.util.string.graphemeSplit(_line) : _line.split(this._wordJoiners), - word = '', - offset = 0, - infix = splitByGrapheme ? '' : ' ', - wordWidth = 0, - infixWidth = 0, - largestWordWidth = 0, - lineJustStarted = true, - additionalSpace = this._getWidthOfCharSpacing(), - reservedSpace = reservedSpace || 0; - // fix a difference between split and graphemeSplit - if (words.length === 0) { - words.push([]); - } - desiredWidth -= reservedSpace; - for (var i = 0; i < words.length; i++) { - // if using splitByGrapheme words are already in graphemes. - word = splitByGrapheme ? words[i] : fabric.util.string.graphemeSplit(words[i]); - wordWidth = this._measureWord(word, lineIndex, offset); - offset += word.length; - - lineWidth += infixWidth + wordWidth - additionalSpace; - if (lineWidth > desiredWidth && !lineJustStarted) { - graphemeLines.push(line); - line = []; - lineWidth = wordWidth; - lineJustStarted = true; - } - else { - lineWidth += additionalSpace; - } - - if (!lineJustStarted && !splitByGrapheme) { - line.push(infix); - } - line = line.concat(word); - - infixWidth = splitByGrapheme ? 0 : this._measureWord([infix], lineIndex, offset); - offset++; - lineJustStarted = false; - // keep track of largest word - if (wordWidth > largestWordWidth) { - largestWordWidth = wordWidth; - } - } - - i && graphemeLines.push(line); - - if (largestWordWidth + reservedSpace > this.dynamicMinWidth) { - this.dynamicMinWidth = largestWordWidth - additionalSpace + reservedSpace; - } - return graphemeLines; - }, - - /** - * Detect if the text line is ended with an hard break - * text and itext do not have wrapping, return false - * @param {Number} lineIndex text to split - * @return {Boolean} - */ - isEndOfWrapping: function(lineIndex) { - if (!this._styleMap[lineIndex + 1]) { - // is last line, return true; - return true; - } - if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) { - // this is last line before a line break, return true; - return true; - } - return false; - }, - - /** - * Detect if a line has a linebreak and so we need to account for it when moving - * and counting style. - * @return Number - */ - missingNewlineOffset: function(lineIndex) { - if (this.splitByGrapheme) { - return this.isEndOfWrapping(lineIndex) ? 1 : 0; - } - return 1; - }, - - /** - * Gets lines of text to render in the Textbox. This function calculates - * text wrapping on the fly every time it is called. - * @param {String} text text to split - * @returns {Array} Array of lines in the Textbox. - * @override - */ - _splitTextIntoLines: function(text) { - var newText = fabric.Text.prototype._splitTextIntoLines.call(this, text), - graphemeLines = this._wrapText(newText.lines, this.width), - lines = new Array(graphemeLines.length); - for (var i = 0; i < graphemeLines.length; i++) { - lines[i] = graphemeLines[i].join(''); - } - newText.lines = lines; - newText.graphemeLines = graphemeLines; - return newText; - }, - - getMinWidth: function() { - return Math.max(this.minWidth, this.dynamicMinWidth); - }, - - _removeExtraneousStyles: function() { - var linesToKeep = {}; - for (var prop in this._styleMap) { - if (this._textLines[prop]) { - linesToKeep[this._styleMap[prop].line] = 1; - } - } - for (var prop in this.styles) { - if (!linesToKeep[prop]) { - delete this.styles[prop]; - } - } - }, - - /** - * Returns object representation of an instance - * @method toObject - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return this.callSuper('toObject', ['minWidth', 'splitByGrapheme'].concat(propertiesToInclude)); - } - }); - - /** - * Returns fabric.Textbox instance from an object representation - * @static - * @memberOf fabric.Textbox - * @param {Object} object Object to create an instance from - * @param {Function} [callback] Callback to invoke when an fabric.Textbox instance is created - */ - fabric.Textbox.fromObject = function(object, callback) { - return fabric.Object._fromObject('Textbox', object, callback, 'text'); - }; -})(typeof exports !== 'undefined' ? exports : this); - - -(function() { - - var controlsUtils = fabric.controlsUtils, - scaleSkewStyleHandler = controlsUtils.scaleSkewCursorStyleHandler, - scaleStyleHandler = controlsUtils.scaleCursorStyleHandler, - scalingEqually = controlsUtils.scalingEqually, - scalingYOrSkewingX = controlsUtils.scalingYOrSkewingX, - scalingXOrSkewingY = controlsUtils.scalingXOrSkewingY, - scaleOrSkewActionName = controlsUtils.scaleOrSkewActionName, - objectControls = fabric.Object.prototype.controls; - - objectControls.ml = new fabric.Control({ - x: -0.5, - y: 0, - cursorStyleHandler: scaleSkewStyleHandler, - actionHandler: scalingXOrSkewingY, - getActionName: scaleOrSkewActionName, - }); - - objectControls.mr = new fabric.Control({ - x: 0.5, - y: 0, - cursorStyleHandler: scaleSkewStyleHandler, - actionHandler: scalingXOrSkewingY, - getActionName: scaleOrSkewActionName, - }); - - objectControls.mb = new fabric.Control({ - x: 0, - y: 0.5, - cursorStyleHandler: scaleSkewStyleHandler, - actionHandler: scalingYOrSkewingX, - getActionName: scaleOrSkewActionName, - }); - - objectControls.mt = new fabric.Control({ - x: 0, - y: -0.5, - cursorStyleHandler: scaleSkewStyleHandler, - actionHandler: scalingYOrSkewingX, - getActionName: scaleOrSkewActionName, - }); - - objectControls.tl = new fabric.Control({ - x: -0.5, - y: -0.5, - cursorStyleHandler: scaleStyleHandler, - actionHandler: scalingEqually - }); - - objectControls.tr = new fabric.Control({ - x: 0.5, - y: -0.5, - cursorStyleHandler: scaleStyleHandler, - actionHandler: scalingEqually - }); - - objectControls.bl = new fabric.Control({ - x: -0.5, - y: 0.5, - cursorStyleHandler: scaleStyleHandler, - actionHandler: scalingEqually - }); - - objectControls.br = new fabric.Control({ - x: 0.5, - y: 0.5, - cursorStyleHandler: scaleStyleHandler, - actionHandler: scalingEqually - }); - - objectControls.mtr = new fabric.Control({ - x: 0, - y: -0.5, - actionHandler: controlsUtils.rotationWithSnapping, - cursorStyleHandler: controlsUtils.rotationStyleHandler, - offsetY: -40, - withConnection: true, - actionName: 'rotate', - }); - - if (fabric.Textbox) { - // this is breaking the prototype inheritance, no time / ideas to fix it. - // is important to document that if you want to have all objects to have a - // specific custom control, you have to add it to Object prototype and to Textbox - // prototype. The controls are shared as references. So changes to control `tr` - // can still apply to all objects if needed. - var textBoxControls = fabric.Textbox.prototype.controls = { }; - - textBoxControls.mtr = objectControls.mtr; - textBoxControls.tr = objectControls.tr; - textBoxControls.br = objectControls.br; - textBoxControls.tl = objectControls.tl; - textBoxControls.bl = objectControls.bl; - textBoxControls.mt = objectControls.mt; - textBoxControls.mb = objectControls.mb; - - textBoxControls.mr = new fabric.Control({ - x: 0.5, - y: 0, - actionHandler: controlsUtils.changeWidth, - cursorStyleHandler: scaleSkewStyleHandler, - actionName: 'resizing', - }); - - textBoxControls.ml = new fabric.Control({ - x: -0.5, - y: 0, - actionHandler: controlsUtils.changeWidth, - cursorStyleHandler: scaleSkewStyleHandler, - actionName: 'resizing', - }); - } -})(); - diff --git a/web/static/js9_old/js/fabric-v4.5.1.min.js b/web/static/js9_old/js/fabric-v4.5.1.min.js deleted file mode 100644 index a60f0d6381cf70698a3158ee1ed1e293333d2413..0000000000000000000000000000000000000000 --- a/web/static/js9_old/js/fabric-v4.5.1.min.js +++ /dev/null @@ -1 +0,0 @@ -var fabric=fabric||{version:"4.5.1"};if("undefined"!=typeof exports?exports.fabric=fabric:"function"==typeof define&&define.amd&&define([],function(){return fabric}),"undefined"!=typeof document&&"undefined"!=typeof window)document instanceof("undefined"!=typeof HTMLDocument?HTMLDocument:Document)?fabric.document=document:fabric.document=document.implementation.createHTMLDocument(""),fabric.window=window;else{var jsdom=require("jsdom"),virtualWindow=new jsdom.JSDOM(decodeURIComponent("%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E"),{features:{FetchExternalResources:["img"]},resources:"usable"}).window;fabric.document=virtualWindow.document,fabric.jsdomImplForWrapper=require("jsdom/lib/jsdom/living/generated/utils").implForWrapper,fabric.nodeCanvas=require("jsdom/lib/jsdom/utils").Canvas,fabric.window=virtualWindow,DOMParser=fabric.window.DOMParser}function resizeCanvasIfNeeded(t){var e=t.targetCanvas,i=e.width,r=e.height,n=t.destinationWidth,s=t.destinationHeight;i===n&&r===s||(e.width=n,e.height=s)}function copyGLTo2DDrawImage(t,e){var i=t.canvas,r=e.targetCanvas,n=r.getContext("2d");n.translate(0,r.height),n.scale(1,-1);var s=i.height-r.height;n.drawImage(i,0,s,r.width,r.height,0,0,r.width,r.height)}function copyGLTo2DPutImageData(t,e){var i=e.targetCanvas.getContext("2d"),r=e.destinationWidth,n=e.destinationHeight,s=r*n*4,o=new Uint8Array(this.imageBuffer,0,s),a=new Uint8ClampedArray(this.imageBuffer,0,s);t.readPixels(0,0,r,n,t.RGBA,t.UNSIGNED_BYTE,o);var h=new ImageData(a,r,n);i.putImageData(h,0,0)}fabric.isTouchSupported="ontouchstart"in fabric.window||"ontouchstart"in fabric.document||fabric.window&&fabric.window.navigator&&0_)for(var C=1,S=d.length;C/g,">")},graphemeSplit:function(t){var e,i=0,r=[];for(i=0;it.x&&this.y>t.y},gte:function(t){return this.x>=t.x&&this.y>=t.y},lerp:function(t,e){return void 0===e&&(e=.5),e=Math.max(Math.min(1,e),0),new i(this.x+(t.x-this.x)*e,this.y+(t.y-this.y)*e)},distanceFrom:function(t){var e=this.x-t.x,i=this.y-t.y;return Math.sqrt(e*e+i*i)},midPointFrom:function(t){return this.lerp(t)},min:function(t){return new i(Math.min(this.x,t.x),Math.min(this.y,t.y))},max:function(t){return new i(Math.max(this.x,t.x),Math.max(this.y,t.y))},toString:function(){return this.x+","+this.y},setXY:function(t,e){return this.x=t,this.y=e,this},setX:function(t){return this.x=t,this},setY:function(t){return this.y=t,this},setFromPoint:function(t){return this.x=t.x,this.y=t.y,this},swap:function(t){var e=this.x,i=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=i},clone:function(){return new i(this.x,this.y)}}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var f=t.fabric||(t.fabric={});function d(t){this.status=t,this.points=[]}f.Intersection?f.warn("fabric.Intersection is already defined"):(f.Intersection=d,f.Intersection.prototype={constructor:d,appendPoint:function(t){return this.points.push(t),this},appendPoints:function(t){return this.points=this.points.concat(t),this}},f.Intersection.intersectLineLine=function(t,e,i,r){var n,s=(r.x-i.x)*(t.y-i.y)-(r.y-i.y)*(t.x-i.x),o=(e.x-t.x)*(t.y-i.y)-(e.y-t.y)*(t.x-i.x),a=(r.y-i.y)*(e.x-t.x)-(r.x-i.x)*(e.y-t.y);if(0!==a){var h=s/a,c=o/a;0<=h&&h<=1&&0<=c&&c<=1?(n=new d("Intersection")).appendPoint(new f.Point(t.x+h*(e.x-t.x),t.y+h*(e.y-t.y))):n=new d}else n=new d(0===s||0===o?"Coincident":"Parallel");return n},f.Intersection.intersectLinePolygon=function(t,e,i){var r,n,s,o,a=new d,h=i.length;for(o=0;o=h&&(c.x-=h),c.x<=-h&&(c.x+=h),c.y>=h&&(c.y-=h),c.y<=h&&(c.y+=h),c.x-=o.offsetX,c.y-=o.offsetY,c}function y(t){return t.flipX!==t.flipY}function _(t,e,i,r,n){if(0!==t[e]){var s=n/t._getTransformedDimensions()[r]*t[i];t.set(i,s)}}function x(t,e,i,r){var n,s=e.target,o=s._getTransformedDimensions(0,s.skewY),a=P(e,e.originX,e.originY,i,r),h=Math.abs(2*a.x)-o.x,c=s.skewX;h<2?n=0:(n=v(Math.atan2(h/s.scaleX,o.y/s.scaleY)),e.originX===f&&e.originY===p&&(n=-n),e.originX===g&&e.originY===d&&(n=-n),y(s)&&(n=-n));var l=c!==n;if(l){var u=s._getTransformedDimensions().y;s.set("skewX",n),_(s,"skewY","scaleY","y",u)}return l}function C(t,e,i,r){var n,s=e.target,o=s._getTransformedDimensions(s.skewX,0),a=P(e,e.originX,e.originY,i,r),h=Math.abs(2*a.y)-o.y,c=s.skewY;h<2?n=0:(n=v(Math.atan2(h/s.scaleY,o.x/s.scaleX)),e.originX===f&&e.originY===p&&(n=-n),e.originX===g&&e.originY===d&&(n=-n),y(s)&&(n=-n));var l=c!==n;if(l){var u=s._getTransformedDimensions().x;s.set("skewY",n),_(s,"skewX","scaleX","x",u)}return l}function D(t,e,i,r,n){n=n||{};var s,o,a,h,c,l,u=e.target,f=u.lockScalingX,d=u.lockScalingY,g=n.by,p=w(t,u),v=k(u,g,p),m=e.gestureScale;if(v)return!1;if(m)o=e.scaleX*m,a=e.scaleY*m;else{if(s=P(e,e.originX,e.originY,i,r),c="y"!==g?T(s.x):1,l="x"!==g?T(s.y):1,e.signX||(e.signX=c),e.signY||(e.signY=l),u.lockScalingFlip&&(e.signX!==c||e.signY!==l))return!1;if(h=u._getTransformedDimensions(),p&&!g){var b=Math.abs(s.x)+Math.abs(s.y),y=e.original,_=b/(Math.abs(h.x*y.scaleX/u.scaleX)+Math.abs(h.y*y.scaleY/u.scaleY));o=y.scaleX*_,a=y.scaleY*_}else o=Math.abs(s.x*u.scaleX/h.x),a=Math.abs(s.y*u.scaleY/h.y);O(e)&&(o*=2,a*=2),e.signX!==c&&"y"!==g&&(e.originX=S[e.originX],o*=-1,e.signX=c),e.signY!==l&&"x"!==g&&(e.originY=S[e.originY],a*=-1,e.signY=l)}var x=u.scaleX,C=u.scaleY;return g?("x"===g&&u.set("scaleX",o),"y"===g&&u.set("scaleY",a)):(!f&&u.set("scaleX",o),!d&&u.set("scaleY",a)),x!==u.scaleX||C!==u.scaleY}n.scaleCursorStyleHandler=function(t,e,i){var r=w(t,i),n="";if(0!==e.x&&0===e.y?n="x":0===e.x&&0!==e.y&&(n="y"),k(i,n,r))return"not-allowed";var s=a(i,e);return o[s]+"-resize"},n.skewCursorStyleHandler=function(t,e,i){var r="not-allowed";if(0!==e.x&&i.lockSkewingY)return r;if(0!==e.y&&i.lockSkewingX)return r;var n=a(i,e)%4;return s[n]+"-resize"},n.scaleSkewCursorStyleHandler=function(t,e,i){return t[i.canvas.altActionKey]?n.skewCursorStyleHandler(t,e,i):n.scaleCursorStyleHandler(t,e,i)},n.rotationWithSnapping=b("rotating",m(function(t,e,i,r){var n=e,s=n.target,o=s.translateToOriginPoint(s.getCenterPoint(),n.originX,n.originY);if(s.lockRotation)return!1;var a,h=Math.atan2(n.ey-o.y,n.ex-o.x),c=Math.atan2(r-o.y,i-o.x),l=v(c-h+n.theta);if(0o.r2,c=this.gradientTransform?this.gradientTransform.concat():fabric.iMatrix.concat(),l=-this.offsetX,u=-this.offsetY,f=!!e.additionalTransform,d="pixels"===this.gradientUnits?"userSpaceOnUse":"objectBoundingBox";if(a.sort(function(t,e){return t.offset-e.offset}),"objectBoundingBox"===d?(l/=t.width,u/=t.height):(l+=t.width/2,u+=t.height/2),"path"===t.type&&"percentage"!==this.gradientUnits&&(l-=t.pathOffset.x,u-=t.pathOffset.y),c[4]-=l,c[5]-=u,s='id="SVGID_'+this.id+'" gradientUnits="'+d+'"',s+=' gradientTransform="'+(f?e.additionalTransform+" ":"")+fabric.util.matrixToSVG(c)+'" ',"linear"===this.type?n=["\n']:"radial"===this.type&&(n=["\n']),"radial"===this.type){if(h)for((a=a.concat()).reverse(),i=0,r=a.length;i\n')}return n.push("linear"===this.type?"\n":"\n"),n.join("")},toLive:function(t){var e,i,r,n=fabric.util.object.clone(this.coords);if(this.type){for("linear"===this.type?e=t.createLinearGradient(n.x1,n.y1,n.x2,n.y2):"radial"===this.type&&(e=t.createRadialGradient(n.x1,n.y1,n.r1,n.x2,n.y2,n.r2)),i=0,r=this.colorStops.length;i\n\n\n'},setOptions:function(t){for(var e in t)this[e]=t[e]},toLive:function(t){var e=this.source;if(!e)return"";if(void 0!==e.src){if(!e.complete)return"";if(0===e.naturalWidth||0===e.naturalHeight)return""}return t.createPattern(e,this.repeat)}})}(),function(t){"use strict";var o=t.fabric||(t.fabric={}),a=o.util.toFixed;o.Shadow?o.warn("fabric.Shadow is already defined."):(o.Shadow=o.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,nonScaling:!1,initialize:function(t){for(var e in"string"==typeof t&&(t=this._parseShadow(t)),t)this[e]=t[e];this.id=o.Object.__uid++},_parseShadow:function(t){var e=t.trim(),i=o.Shadow.reOffsetsAndBlur.exec(e)||[];return{color:(e.replace(o.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)").trim(),offsetX:parseFloat(i[1],10)||0,offsetY:parseFloat(i[2],10)||0,blur:parseFloat(i[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(t){var e=40,i=40,r=o.Object.NUM_FRACTION_DIGITS,n=o.util.rotateVector({x:this.offsetX,y:this.offsetY},o.util.degreesToRadians(-t.angle)),s=new o.Color(this.color);return t.width&&t.height&&(e=100*a((Math.abs(n.x)+this.blur)/t.width,r)+20,i=100*a((Math.abs(n.y)+this.blur)/t.height,r)+20),t.flipX&&(n.x*=-1),t.flipY&&(n.y*=-1),'\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n'},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke,nonScaling:this.nonScaling};var e={},i=o.Shadow.prototype;return["color","blur","offsetX","offsetY","affectStroke","nonScaling"].forEach(function(t){this[t]!==i[t]&&(e[t]=this[t])},this),e}}),o.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?(-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?(\d+(?:\.\d*)?(?:px)?)?(?:\s?|$)(?:$|\s)/)}("undefined"!=typeof exports?exports:this),function(){"use strict";if(fabric.StaticCanvas)fabric.warn("fabric.StaticCanvas is already defined.");else{var n=fabric.util.object.extend,t=fabric.util.getElementOffset,c=fabric.util.removeFromArray,a=fabric.util.toFixed,s=fabric.util.transformPoint,o=fabric.util.invertTransform,i=fabric.util.getNodeCanvas,r=fabric.util.createCanvasElement,e=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass(fabric.CommonMethods,{initialize:function(t,e){e||(e={}),this.renderAndResetBound=this.renderAndReset.bind(this),this.requestRenderAllBound=this.requestRenderAll.bind(this),this._initStatic(t,e)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!1,renderOnAddRemove:!0,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,viewportTransform:fabric.iMatrix.concat(),backgroundVpt:!0,overlayVpt:!0,enableRetinaScaling:!0,vptCoords:{},skipOffscreen:!0,clipPath:void 0,_initStatic:function(t,e){var i=this.requestRenderAllBound;this._objects=[],this._createLowerCanvas(t),this._initOptions(e),this.interactive||this._initRetinaScaling(),e.overlayImage&&this.setOverlayImage(e.overlayImage,i),e.backgroundImage&&this.setBackgroundImage(e.backgroundImage,i),e.backgroundColor&&this.setBackgroundColor(e.backgroundColor,i),e.overlayColor&&this.setOverlayColor(e.overlayColor,i),this.calcOffset()},_isRetinaScaling:function(){return 1!==fabric.devicePixelRatio&&this.enableRetinaScaling},getRetinaScaling:function(){return this._isRetinaScaling()?fabric.devicePixelRatio:1},_initRetinaScaling:function(){if(this._isRetinaScaling()){var t=fabric.devicePixelRatio;this.__initRetinaScaling(t,this.lowerCanvasEl,this.contextContainer),this.upperCanvasEl&&this.__initRetinaScaling(t,this.upperCanvasEl,this.contextTop)}},__initRetinaScaling:function(t,e,i){e.setAttribute("width",this.width*t),e.setAttribute("height",this.height*t),i.scale(t,t)},calcOffset:function(){return this._offset=t(this.lowerCanvasEl),this},setOverlayImage:function(t,e,i){return this.__setBgOverlayImage("overlayImage",t,e,i)},setBackgroundImage:function(t,e,i){return this.__setBgOverlayImage("backgroundImage",t,e,i)},setOverlayColor:function(t,e){return this.__setBgOverlayColor("overlayColor",t,e)},setBackgroundColor:function(t,e){return this.__setBgOverlayColor("backgroundColor",t,e)},__setBgOverlayImage:function(r,t,n,s){return"string"==typeof t?fabric.util.loadImage(t,function(t,e){if(t){var i=new fabric.Image(t,s);(this[r]=i).canvas=this}n&&n(t,e)},this,s&&s.crossOrigin):(s&&t.setOptions(s),(this[r]=t)&&(t.canvas=this),n&&n(t,!1)),this},__setBgOverlayColor:function(t,e,i){return this[t]=e,this._initGradient(e,t),this._initPattern(e,t,i),this},_createCanvasElement:function(){var t=r();if(!t)throw e;if(t.style||(t.style={}),void 0===t.getContext)throw e;return t},_initOptions:function(t){var e=this.lowerCanvasEl;this._setOptions(t),this.width=this.width||parseInt(e.width,10)||0,this.height=this.height||parseInt(e.height,10)||0,this.lowerCanvasEl.style&&(e.width=this.width,e.height=this.height,e.style.width=this.width+"px",e.style.height=this.height+"px",this.viewportTransform=this.viewportTransform.slice())},_createLowerCanvas:function(t){t&&t.getContext?this.lowerCanvasEl=t:this.lowerCanvasEl=fabric.util.getById(t)||this._createCanvasElement(),fabric.util.addClass(this.lowerCanvasEl,"lower-canvas"),this.interactive&&this._applyCanvasStyle(this.lowerCanvasEl),this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(t,e){return this.setDimensions({width:t},e)},setHeight:function(t,e){return this.setDimensions({height:t},e)},setDimensions:function(t,e){var i;for(var r in e=e||{},t)i=t[r],e.cssOnly||(this._setBackstoreDimension(r,t[r]),i+="px",this.hasLostContext=!0),e.backstoreOnly||this._setCssDimension(r,i);return this._isCurrentlyDrawing&&this.freeDrawingBrush&&this.freeDrawingBrush._setBrushStyles(),this._initRetinaScaling(),this.calcOffset(),e.cssOnly||this.requestRenderAll(),this},_setBackstoreDimension:function(t,e){return this.lowerCanvasEl[t]=e,this.upperCanvasEl&&(this.upperCanvasEl[t]=e),this.cacheCanvasEl&&(this.cacheCanvasEl[t]=e),this[t]=e,this},_setCssDimension:function(t,e){return this.lowerCanvasEl.style[t]=e,this.upperCanvasEl&&(this.upperCanvasEl.style[t]=e),this.wrapperEl&&(this.wrapperEl.style[t]=e),this},getZoom:function(){return this.viewportTransform[0]},setViewportTransform:function(t){var e,i,r,n=this._activeObject,s=this.backgroundImage,o=this.overlayImage;for(this.viewportTransform=t,i=0,r=this._objects.length;i\n'),this._setSVGBgOverlayColor(i,"background"),this._setSVGBgOverlayImage(i,"backgroundImage",e),this._setSVGObjects(i,e),this.clipPath&&i.push("\n"),this._setSVGBgOverlayColor(i,"overlay"),this._setSVGBgOverlayImage(i,"overlayImage",e),i.push(""),i.join("")},_setSVGPreamble:function(t,e){e.suppressPreamble||t.push('\n','\n')},_setSVGHeader:function(t,e){var i,r=e.width||this.width,n=e.height||this.height,s='viewBox="0 0 '+this.width+" "+this.height+'" ',o=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?s='viewBox="'+e.viewBox.x+" "+e.viewBox.y+" "+e.viewBox.width+" "+e.viewBox.height+'" ':this.svgViewportTransformation&&(i=this.viewportTransform,s='viewBox="'+a(-i[4]/i[0],o)+" "+a(-i[5]/i[3],o)+" "+a(this.width/i[0],o)+" "+a(this.height/i[3],o)+'" '),t.push("\n',"Created with Fabric.js ",fabric.version,"\n","\n",this.createSVGFontFacesMarkup(),this.createSVGRefElementsMarkup(),this.createSVGClipPathMarkup(e),"\n")},createSVGClipPathMarkup:function(t){var e=this.clipPath;return e?(e.clipPathId="CLIPPATH_"+fabric.Object.__uid++,'\n'+this.clipPath.toClipPathSVG(t.reviver)+"\n"):""},createSVGRefElementsMarkup:function(){var s=this;return["background","overlay"].map(function(t){var e=s[t+"Color"];if(e&&e.toLive){var i=s[t+"Vpt"],r=s.viewportTransform,n={width:s.width/(i?r[0]:1),height:s.height/(i?r[3]:1)};return e.toSVG(n,{additionalTransform:i?fabric.util.matrixToSVG(r):""})}}).join("")},createSVGFontFacesMarkup:function(){var t,e,i,r,n,s,o,a,h="",c={},l=fabric.fontPaths,u=[];for(this._objects.forEach(function t(e){u.push(e),e._objects&&e._objects.forEach(t)}),o=0,a=u.length;o',"\n",h,"","\n"].join("")),h},_setSVGObjects:function(t,e){var i,r,n,s=this._objects;for(r=0,n=s.length;r
    \n")}else t.push('\n")},sendToBack:function(t){if(!t)return this;var e,i,r,n=this._activeObject;if(t===n&&"activeSelection"===t.type)for(e=(r=n._objects).length;e--;)i=r[e],c(this._objects,i),this._objects.unshift(i);else c(this._objects,t),this._objects.unshift(t);return this.renderOnAddRemove&&this.requestRenderAll(),this},bringToFront:function(t){if(!t)return this;var e,i,r,n=this._activeObject;if(t===n&&"activeSelection"===t.type)for(r=n._objects,e=0;e"}}),n(fabric.StaticCanvas.prototype,fabric.Observable),n(fabric.StaticCanvas.prototype,fabric.Collection),n(fabric.StaticCanvas.prototype,fabric.DataURLExporter),n(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(t){var e=r();if(!e||!e.getContext)return null;var i=e.getContext("2d");if(!i)return null;switch(t){case"setLineDash":return void 0!==i.setLineDash;default:return null}}}),fabric.StaticCanvas.prototype.toJSON=fabric.StaticCanvas.prototype.toObject,fabric.isLikelyNode&&(fabric.StaticCanvas.prototype.createPNGStream=function(){var t=i(this.lowerCanvasEl);return t&&t.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(t){var e=i(this.lowerCanvasEl);return e&&e.createJPEGStream(t)})}}(),fabric.BaseBrush=fabric.util.createClass({color:"rgb(0, 0, 0)",width:1,shadow:null,strokeLineCap:"round",strokeLineJoin:"round",strokeMiterLimit:10,strokeDashArray:null,limitedToCanvasSize:!1,_setBrushStyles:function(){var t=this.canvas.contextTop;t.strokeStyle=this.color,t.lineWidth=this.width,t.lineCap=this.strokeLineCap,t.miterLimit=this.strokeMiterLimit,t.lineJoin=this.strokeLineJoin,fabric.StaticCanvas.supports("setLineDash")&&t.setLineDash(this.strokeDashArray||[])},_saveAndTransform:function(t){var e=this.canvas.viewportTransform;t.save(),t.transform(e[0],e[1],e[2],e[3],e[4],e[5])},_setShadow:function(){if(this.shadow){var t=this.canvas,e=this.shadow,i=t.contextTop,r=t.getZoom();t&&t._isRetinaScaling()&&(r*=fabric.devicePixelRatio),i.shadowColor=e.color,i.shadowBlur=e.blur*r,i.shadowOffsetX=e.offsetX*r,i.shadowOffsetY=e.offsetY*r}},needsFullRender:function(){return new fabric.Color(this.color).getAlpha()<1||!!this.shadow},_resetShadow:function(){var t=this.canvas.contextTop;t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0},_isOutSideCanvas:function(t){return t.x<0||t.x>this.canvas.getWidth()||t.y<0||t.y>this.canvas.getHeight()}}),fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{decimate:.4,initialize:function(t){this.canvas=t,this._points=[]},_drawSegment:function(t,e,i){var r=e.midPointFrom(i);return t.quadraticCurveTo(e.x,e.y,r.x,r.y),r},onMouseDown:function(t,e){this.canvas._isMainEvent(e.e)&&(this._prepareForDrawing(t),this._captureDrawingPath(t),this._render())},onMouseMove:function(t,e){if(this.canvas._isMainEvent(e.e)&&(!0!==this.limitedToCanvasSize||!this._isOutSideCanvas(t))&&this._captureDrawingPath(t)&&1t[e-2].x?1:n.x===t[e-2].x?0:-1,h=n.y>t[e-2].y?1:n.y===t[e-2].y?0:-1),i.push("L ",n.x+a*r," ",n.y+h*r),i},createPath:function(t){var e=new fabric.Path(t,{fill:null,stroke:this.color,strokeWidth:this.width,strokeLineCap:this.strokeLineCap,strokeMiterLimit:this.strokeMiterLimit,strokeLineJoin:this.strokeLineJoin,strokeDashArray:this.strokeDashArray});return this.shadow&&(this.shadow.affectStroke=!0,e.shadow=new fabric.Shadow(this.shadow)),e},decimatePoints:function(t,e){if(t.length<=2)return t;var i,r=this.canvas.getZoom(),n=Math.pow(e/r,2),s=t.length-1,o=t[0],a=[o];for(i=1;i"},getObjectScaling:function(){var t=x.util.qrDecompose(this.calcTransformMatrix());return{scaleX:Math.abs(t.scaleX),scaleY:Math.abs(t.scaleY)}},getTotalObjectScaling:function(){var t=this.getObjectScaling(),e=t.scaleX,i=t.scaleY;if(this.canvas){var r=this.canvas.getZoom(),n=this.canvas.getRetinaScaling();e*=r*n,i*=r*n}return{scaleX:e,scaleY:i}},getObjectOpacity:function(){var t=this.opacity;return this.group&&(t*=this.group.getObjectOpacity()),t},_set:function(t,e){var i="scaleX"===t||"scaleY"===t,r=this[t]!==e,n=!1;return i&&(e=this._constrainScale(e)),"scaleX"===t&&e<0?(this.flipX=!this.flipX,e*=-1):"scaleY"===t&&e<0?(this.flipY=!this.flipY,e*=-1):"shadow"!==t||!e||e instanceof x.Shadow?"dirty"===t&&this.group&&this.group.set("dirty",e):e=new x.Shadow(e),this[t]=e,r&&(n=this.group&&this.group.isOnACache(),-1=t.x&&n.left+n.width<=e.x&&n.top>=t.y&&n.top+n.height<=e.y},containsPoint:function(t,e,i,r){var n=this._getCoords(i,r),s=(e=e||this._getImageLines(n),this._findCrossPoints(t,e));return 0!==s&&s%2==1},isOnScreen:function(t){if(!this.canvas)return!1;var e=this.canvas.vptCoords.tl,i=this.canvas.vptCoords.br;return!!this.getCoords(!0,t).some(function(t){return t.x<=i.x&&t.x>=e.x&&t.y<=i.y&&t.y>=e.y})||(!!this.intersectsWithRect(e,i,!0,t)||this._containsCenterOfCanvas(e,i,t))},_containsCenterOfCanvas:function(t,e,i){var r={x:(t.x+e.x)/2,y:(t.y+e.y)/2};return!!this.containsPoint(r,null,!0,i)},isPartiallyOnScreen:function(t){if(!this.canvas)return!1;var e=this.canvas.vptCoords.tl,i=this.canvas.vptCoords.br;return!!this.intersectsWithRect(e,i,!0,t)||this.getCoords(!0,t).every(function(t){return(t.x>=i.x||t.x<=e.x)&&(t.y>=i.y||t.y<=e.y)})&&this._containsCenterOfCanvas(e,i,t)},_getImageLines:function(t){return{topline:{o:t.tl,d:t.tr},rightline:{o:t.tr,d:t.br},bottomline:{o:t.br,d:t.bl},leftline:{o:t.bl,d:t.tl}}},_findCrossPoints:function(t,e){var i,r,n,s=0;for(var o in e)if(!((n=e[o]).o.y=t.y&&n.d.y>=t.y||(n.o.x===n.d.x&&n.o.x>=t.x?r=n.o.x:(0,i=(n.d.y-n.o.y)/(n.d.x-n.o.x),r=-(t.y-0*t.x-(n.o.y-i*n.o.x))/(0-i)),r>=t.x&&(s+=1),2!==s)))break;return s},getBoundingRect:function(t,e){var i=this.getCoords(t,e);return c.makeBoundingBoxFromPoints(i)},getScaledWidth:function(){return this._getTransformedDimensions().x},getScaledHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(t){return Math.abs(t)
    \n')}},toSVG:function(t){return this._createBaseSVGMarkup(this._toSVG(t),{reviver:t})},toClipPathSVG:function(t){return"\t"+this._createBaseClipPathSVGMarkup(this._toSVG(t),{reviver:t})},_createBaseClipPathSVGMarkup:function(t,e){var i=(e=e||{}).reviver,r=e.additionalTransform||"",n=[this.getSvgTransform(!0,r),this.getSvgCommons()].join(""),s=t.indexOf("COMMON_PARTS");return t[s]=n,i?i(t.join("")):t.join("")},_createBaseSVGMarkup:function(t,e){var i,r,n=(e=e||{}).noStyle,s=e.reviver,o=n?"":'style="'+this.getSvgStyles()+'" ',a=e.withShadow?'style="'+this.getSvgFilter()+'" ':"",h=this.clipPath,c=this.strokeUniform?'vector-effect="non-scaling-stroke" ':"",l=h&&h.absolutePositioned,u=this.stroke,f=this.fill,d=this.shadow,g=[],p=t.indexOf("COMMON_PARTS"),v=e.additionalTransform;return h&&(h.clipPathId="CLIPPATH_"+fabric.Object.__uid++,r='\n'+h.toClipPathSVG(s)+"\n"),l&&g.push("\n"),g.push("\n"),i=[o,c,n?"":this.addPaintOrder()," ",v?'transform="'+v+'" ':""].join(""),t[p]=i,f&&f.toLive&&g.push(f.toSVG(this)),u&&u.toLive&&g.push(u.toSVG(this)),d&&g.push(d.toSVG(this)),h&&g.push(r),g.push(t.join("")),g.push("\n"),l&&g.push("\n"),s?s(g.join("")):g.join("")},addPaintOrder:function(){return"fill"!==this.paintFirst?' paint-order="'+this.paintFirst+'" ':""}})}(),function(){var n=fabric.util.object.extend,r="stateProperties";function s(e,t,i){var r={};i.forEach(function(t){r[t]=e[t]}),n(e[t],r,!0)}fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(t){var e="_"+(t=t||r);return Object.keys(this[e]).length\n']}}),s.Line.ATTRIBUTE_NAMES=s.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),s.Line.fromElement=function(t,e,i){i=i||{};var r=s.parseAttributes(t,s.Line.ATTRIBUTE_NAMES),n=[r.x1||0,r.y1||0,r.x2||0,r.y2||0];e(new s.Line(n,o(r,i)))},s.Line.fromObject=function(t,e){var i=r(t,!0);i.points=[t.x1,t.y1,t.x2,t.y2],s.Object._fromObject("Line",i,function(t){delete t.points,e&&e(t)},"points")})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var a=t.fabric||(t.fabric={}),h=Math.PI;a.Circle?a.warn("fabric.Circle is already defined."):(a.Circle=a.util.createClass(a.Object,{type:"circle",radius:0,startAngle:0,endAngle:2*h,cacheProperties:a.Object.prototype.cacheProperties.concat("radius","startAngle","endAngle"),_set:function(t,e){return this.callSuper("_set",t,e),"radius"===t&&this.setRadius(e),this},toObject:function(t){return this.callSuper("toObject",["radius","startAngle","endAngle"].concat(t))},_toSVG:function(){var t,e=(this.endAngle-this.startAngle)%(2*h);if(0===e)t=["\n'];else{var i=a.util.cos(this.startAngle)*this.radius,r=a.util.sin(this.startAngle)*this.radius,n=a.util.cos(this.endAngle)*this.radius,s=a.util.sin(this.endAngle)*this.radius,o=h\n"]}return t},_render:function(t){t.beginPath(),t.arc(0,0,this.radius,this.startAngle,this.endAngle,!1),this._renderPaintInOrder(t)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(t){return this.radius=t,this.set("width",2*t).set("height",2*t)}}),a.Circle.ATTRIBUTE_NAMES=a.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),a.Circle.fromElement=function(t,e){var i,r=a.parseAttributes(t,a.Circle.ATTRIBUTE_NAMES);if(!("radius"in(i=r)&&0<=i.radius))throw new Error("value of `r` attribute is required and can not be negative");r.left=(r.left||0)-r.radius,r.top=(r.top||0)-r.radius,e(new a.Circle(r))},a.Circle.fromObject=function(t,e){return a.Object._fromObject("Circle",t,e)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var r=t.fabric||(t.fabric={});r.Triangle?r.warn("fabric.Triangle is already defined"):(r.Triangle=r.util.createClass(r.Object,{type:"triangle",width:100,height:100,_render:function(t){var e=this.width/2,i=this.height/2;t.beginPath(),t.moveTo(-e,i),t.lineTo(0,-i),t.lineTo(e,i),t.closePath(),this._renderPaintInOrder(t)},_renderDashedStroke:function(t){var e=this.width/2,i=this.height/2;t.beginPath(),r.util.drawDashedLine(t,-e,i,0,-i,this.strokeDashArray),r.util.drawDashedLine(t,0,-i,e,i,this.strokeDashArray),r.util.drawDashedLine(t,e,i,-e,i,this.strokeDashArray),t.closePath()},_toSVG:function(){var t=this.width/2,e=this.height/2;return["']}}),r.Triangle.fromObject=function(t,e){return r.Object._fromObject("Triangle",t,e)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var r=t.fabric||(t.fabric={}),e=2*Math.PI;r.Ellipse?r.warn("fabric.Ellipse is already defined."):(r.Ellipse=r.util.createClass(r.Object,{type:"ellipse",rx:0,ry:0,cacheProperties:r.Object.prototype.cacheProperties.concat("rx","ry"),initialize:function(t){this.callSuper("initialize",t),this.set("rx",t&&t.rx||0),this.set("ry",t&&t.ry||0)},_set:function(t,e){switch(this.callSuper("_set",t,e),t){case"rx":this.rx=e,this.set("width",2*e);break;case"ry":this.ry=e,this.set("height",2*e)}return this},getRx:function(){return this.get("rx")*this.get("scaleX")},getRy:function(){return this.get("ry")*this.get("scaleY")},toObject:function(t){return this.callSuper("toObject",["rx","ry"].concat(t))},_toSVG:function(){return["\n']},_render:function(t){t.beginPath(),t.save(),t.transform(1,0,0,this.ry/this.rx,0,0),t.arc(0,0,this.rx,0,e,!1),t.restore(),this._renderPaintInOrder(t)}}),r.Ellipse.ATTRIBUTE_NAMES=r.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),r.Ellipse.fromElement=function(t,e){var i=r.parseAttributes(t,r.Ellipse.ATTRIBUTE_NAMES);i.left=(i.left||0)-i.rx,i.top=(i.top||0)-i.ry,e(new r.Ellipse(i))},r.Ellipse.fromObject=function(t,e){return r.Object._fromObject("Ellipse",t,e)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var s=t.fabric||(t.fabric={}),o=s.util.object.extend;s.Rect?s.warn("fabric.Rect is already defined"):(s.Rect=s.util.createClass(s.Object,{stateProperties:s.Object.prototype.stateProperties.concat("rx","ry"),type:"rect",rx:0,ry:0,cacheProperties:s.Object.prototype.cacheProperties.concat("rx","ry"),initialize:function(t){this.callSuper("initialize",t),this._initRxRy()},_initRxRy:function(){this.rx&&!this.ry?this.ry=this.rx:this.ry&&!this.rx&&(this.rx=this.ry)},_render:function(t){var e=this.rx?Math.min(this.rx,this.width/2):0,i=this.ry?Math.min(this.ry,this.height/2):0,r=this.width,n=this.height,s=-this.width/2,o=-this.height/2,a=0!==e||0!==i,h=.4477152502;t.beginPath(),t.moveTo(s+e,o),t.lineTo(s+r-e,o),a&&t.bezierCurveTo(s+r-h*e,o,s+r,o+h*i,s+r,o+i),t.lineTo(s+r,o+n-i),a&&t.bezierCurveTo(s+r,o+n-h*i,s+r-h*e,o+n,s+r-e,o+n),t.lineTo(s+e,o+n),a&&t.bezierCurveTo(s+h*e,o+n,s,o+n-h*i,s,o+n-i),t.lineTo(s,o+i),a&&t.bezierCurveTo(s,o+h*i,s+h*e,o,s+e,o),t.closePath(),this._renderPaintInOrder(t)},_renderDashedStroke:function(t){var e=-this.width/2,i=-this.height/2,r=this.width,n=this.height;t.beginPath(),s.util.drawDashedLine(t,e,i,e+r,i,this.strokeDashArray),s.util.drawDashedLine(t,e+r,i,e+r,i+n,this.strokeDashArray),s.util.drawDashedLine(t,e+r,i+n,e,i+n,this.strokeDashArray),s.util.drawDashedLine(t,e,i+n,e,i,this.strokeDashArray),t.closePath()},toObject:function(t){return this.callSuper("toObject",["rx","ry"].concat(t))},_toSVG:function(){return["\n']}}),s.Rect.ATTRIBUTE_NAMES=s.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")),s.Rect.fromElement=function(t,e,i){if(!t)return e(null);i=i||{};var r=s.parseAttributes(t,s.Rect.ATTRIBUTE_NAMES);r.left=r.left||0,r.top=r.top||0,r.height=r.height||0,r.width=r.width||0;var n=new s.Rect(o(i?s.util.object.clone(i):{},r));n.visible=n.visible&&0\n']},commonRender:function(t){var e,i=this.points.length,r=this.pathOffset.x,n=this.pathOffset.y;if(!i||isNaN(this.points[i-1].y))return!1;t.beginPath(),t.moveTo(this.points[0].x-r,this.points[0].y-n);for(var s=0;s"},toObject:function(t){return n(this.callSuper("toObject",t),{path:this.path.map(function(t){return t.slice()})})},toDatalessObject:function(t){var e=this.toObject(["sourcePath"].concat(t));return e.sourcePath&&delete e.path,e},_toSVG:function(){return["\n"]},_getOffsetTransform:function(){var t=f.Object.NUM_FRACTION_DIGITS;return" translate("+e(-this.pathOffset.x,t)+", "+e(-this.pathOffset.y,t)+")"},toClipPathSVG:function(t){var e=this._getOffsetTransform();return"\t"+this._createBaseClipPathSVGMarkup(this._toSVG(),{reviver:t,additionalTransform:e})},toSVG:function(t){var e=this._getOffsetTransform();return this._createBaseSVGMarkup(this._toSVG(),{reviver:t,additionalTransform:e})},complexity:function(){return this.path.length},_calcDimensions:function(){for(var t,e,i=[],r=[],n=0,s=0,o=0,a=0,h=0,c=this.path.length;h"},addWithUpdate:function(t){var e=!!this.group;return this._restoreObjectsState(),c.util.resetObjectTransform(this),t&&(e&&c.util.removeTransformFromObject(t,this.group.calcTransformMatrix()),this._objects.push(t),t.group=this,t._set("canvas",this.canvas)),this._calcBounds(),this._updateObjectsCoords(),this.dirty=!0,e?this.group.addWithUpdate():this.setCoords(),this},removeWithUpdate:function(t){return this._restoreObjectsState(),c.util.resetObjectTransform(this),this.remove(t),this._calcBounds(),this._updateObjectsCoords(),this.setCoords(),this.dirty=!0,this},_onObjectAdded:function(t){this.dirty=!0,t.group=this,t._set("canvas",this.canvas)},_onObjectRemoved:function(t){this.dirty=!0,delete t.group},_set:function(t,e){var i=this._objects.length;if(this.useSetOnGroup)for(;i--;)this._objects[i].setOnGroup(t,e);if("canvas"===t)for(;i--;)this._objects[i]._set(t,e);c.Object.prototype._set.call(this,t,e)},toObject:function(r){var n=this.includeDefaultValues,t=this._objects.map(function(t){var e=t.includeDefaultValues;t.includeDefaultValues=n;var i=t.toObject(r);return t.includeDefaultValues=e,i}),e=c.Object.prototype.toObject.call(this,r);return e.objects=t,e},toDatalessObject:function(r){var t,e=this.sourcePath;if(e)t=e;else{var n=this.includeDefaultValues;t=this._objects.map(function(t){var e=t.includeDefaultValues;t.includeDefaultValues=n;var i=t.toDatalessObject(r);return t.includeDefaultValues=e,i})}var i=c.Object.prototype.toDatalessObject.call(this,r);return i.objects=t,i},render:function(t){this._transformDone=!0,this.callSuper("render",t),this._transformDone=!1},shouldCache:function(){var t=c.Object.prototype.shouldCache.call(this);if(t)for(var e=0,i=this._objects.length;e\n"],i=0,r=this._objects.length;i\n"),e},getSvgStyles:function(){var t=void 0!==this.opacity&&1!==this.opacity?"opacity: "+this.opacity+";":"",e=this.visible?"":" visibility: hidden;";return[t,this.getSvgFilter(),e].join("")},toClipPathSVG:function(t){for(var e=[],i=0,r=this._objects.length;i"},shouldCache:function(){return!1},isOnACache:function(){return!1},_renderControls:function(t,e,i){t.save(),t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,this.callSuper("_renderControls",t,e),void 0===(i=i||{}).hasControls&&(i.hasControls=!1),i.forActiveSelection=!0;for(var r=0,n=this._objects.length;r\n','\t\n',"\n"),o=' clip-path="url(#imageCrop_'+h+')" '}if(this.imageSmoothing||(a='" image-rendering="optimizeSpeed'),i.push("\t\n"),this.stroke||this.strokeDashArray){var c=this.fill;this.fill=null,t=["\t\n'],this.fill=c}return e="fill"!==this.paintFirst?e.concat(t,i):e.concat(i,t)},getSrc:function(t){var e=t?this._element:this._originalElement;return e?e.toDataURL?e.toDataURL():this.srcFromAttribute?e.getAttribute("src"):e.src:this.src||""},setSrc:function(t,i,r){return fabric.util.loadImage(t,function(t,e){this.setElement(t,r),this._setWidthHeight(),i&&i(this,e)},this,r&&r.crossOrigin),this},toString:function(){return'#'},applyResizeFilters:function(){var t=this.resizeFilter,e=this.minimumScaleTrigger,i=this.getTotalObjectScaling(),r=i.scaleX,n=i.scaleY,s=this._filteredEl||this._originalElement;if(this.group&&this.set("dirty",!0),!t||e=t;for(var a=["highp","mediump","lowp"],h=0;h<3;h++)if(void 0,i="precision "+a[h]+" float;\nvoid main(){}",r=(e=s).createShader(e.FRAGMENT_SHADER),e.shaderSource(r,i),e.compileShader(r),e.getShaderParameter(r,e.COMPILE_STATUS)){fabric.webGlPrecision=a[h];break}}return this.isSupported=o},(fabric.WebglFilterBackend=t).prototype={tileSize:2048,resources:{},setupGLContext:function(t,e){this.dispose(),this.createWebGLCanvas(t,e),this.aPosition=new Float32Array([0,0,0,1,1,0,1,1]),this.chooseFastestCopyGLTo2DMethod(t,e)},chooseFastestCopyGLTo2DMethod:function(t,e){var i,r=void 0!==window.performance;try{new ImageData(1,1),i=!0}catch(t){i=!1}var n="undefined"!=typeof ArrayBuffer,s="undefined"!=typeof Uint8ClampedArray;if(r&&i&&n&&s){var o=fabric.util.createCanvasElement(),a=new ArrayBuffer(t*e*4);if(fabric.forceGLPutImageData)return this.imageBuffer=a,void(this.copyGLTo2D=copyGLTo2DPutImageData);var h,c,l={imageBuffer:a,destinationWidth:t,destinationHeight:e,targetCanvas:o};o.width=t,o.height=e,h=window.performance.now(),copyGLTo2DDrawImage.call(l,this.gl,l),c=window.performance.now()-h,h=window.performance.now(),copyGLTo2DPutImageData.call(l,this.gl,l),window.performance.now()-h 0.0) {\n"+this.fragmentSource[t]+"}\n}"},retrieveShader:function(t){var e,i=this.type+"_"+this.mode;return t.programCache.hasOwnProperty(i)||(e=this.buildSource(this.mode),t.programCache[i]=this.createProgram(t.context,e)),t.programCache[i]},applyTo2d:function(t){var e,i,r,n,s,o,a,h=t.imageData.data,c=h.length,l=1-this.alpha;e=(a=new f.Color(this.color).getSource())[0]*this.alpha,i=a[1]*this.alpha,r=a[2]*this.alpha;for(var u=0;u'},_getCacheCanvasDimensions:function(){var t=this.callSuper("_getCacheCanvasDimensions"),e=this.fontSize;return t.width+=e*t.zoomX,t.height+=e*t.zoomY,t},_render:function(t){this._setTextStyles(t),this._renderTextLinesBackground(t),this._renderTextDecoration(t,"underline"),this._renderText(t),this._renderTextDecoration(t,"overline"),this._renderTextDecoration(t,"linethrough")},_renderText:function(t){"stroke"===this.paintFirst?(this._renderTextStroke(t),this._renderTextFill(t)):(this._renderTextFill(t),this._renderTextStroke(t))},_setTextStyles:function(t,e,i){t.textBaseline="alphabetic",t.font=this._getFontDeclaration(e,i)},calcTextWidth:function(){for(var t=this.getLineWidth(0),e=1,i=this._textLines.length;ethis.__selectionStartOnMouseDown?(this.selectionStart=this.__selectionStartOnMouseDown,this.selectionEnd=e):(this.selectionStart=e,this.selectionEnd=this.__selectionStartOnMouseDown),this.selectionStart===i&&this.selectionEnd===r||(this.restartCursorIfNeeded(),this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection()))}},_setEditingProps:function(){this.hoverCursor="text",this.canvas&&(this.canvas.defaultCursor=this.canvas.moveCursor="text"),this.borderColor=this.editingBorderColor,this.hasControls=this.selectable=!1,this.lockMovementX=this.lockMovementY=!0},fromStringToGraphemeSelection:function(t,e,i){var r=i.slice(0,t),n=fabric.util.string.graphemeSplit(r).length;if(t===e)return{selectionStart:n,selectionEnd:n};var s=i.slice(t,e);return{selectionStart:n,selectionEnd:n+fabric.util.string.graphemeSplit(s).length}},fromGraphemeToStringSelection:function(t,e,i){var r=i.slice(0,t).join("").length;return t===e?{selectionStart:r,selectionEnd:r}:{selectionStart:r,selectionEnd:r+i.slice(t,e).join("").length}},_updateTextarea:function(){if(this.cursorOffsetCache={},this.hiddenTextarea){if(!this.inCompositionMode){var t=this.fromGraphemeToStringSelection(this.selectionStart,this.selectionEnd,this._text);this.hiddenTextarea.selectionStart=t.selectionStart,this.hiddenTextarea.selectionEnd=t.selectionEnd}this.updateTextareaPosition()}},updateFromTextArea:function(){if(this.hiddenTextarea){this.cursorOffsetCache={},this.text=this.hiddenTextarea.value,this._shouldClearDimensionCache()&&(this.initDimensions(),this.setCoords());var t=this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart,this.hiddenTextarea.selectionEnd,this.hiddenTextarea.value);this.selectionEnd=this.selectionStart=t.selectionEnd,this.inCompositionMode||(this.selectionStart=t.selectionStart),this.updateTextareaPosition()}},updateTextareaPosition:function(){if(this.selectionStart===this.selectionEnd){var t=this._calcTextareaPosition();this.hiddenTextarea.style.left=t.left,this.hiddenTextarea.style.top=t.top}},_calcTextareaPosition:function(){if(!this.canvas)return{x:1,y:1};var t=this.inCompositionMode?this.compositionStart:this.selectionStart,e=this._getCursorBoundaries(t),i=this.get2DCursorLocation(t),r=i.lineIndex,n=i.charIndex,s=this.getValueOfPropertyAt(r,n,"fontSize")*this.lineHeight,o=e.leftOffset,a=this.calcTransformMatrix(),h={x:e.left+o,y:e.top+e.topOffset+s},c=this.canvas.getRetinaScaling(),l=this.canvas.upperCanvasEl,u=l.width/c,f=l.height/c,d=u-s,g=f-s,p=l.clientWidth/u,v=l.clientHeight/f;return h=fabric.util.transformPoint(h,a),(h=fabric.util.transformPoint(h,this.canvas.viewportTransform)).x*=p,h.y*=v,h.x<0&&(h.x=0),h.x>d&&(h.x=d),h.y<0&&(h.y=0),h.y>g&&(h.y=g),h.x+=this.canvas._offset.left,h.y+=this.canvas._offset.top,{left:h.x+"px",top:h.y+"px",fontSize:s+"px",charHeight:s}},_saveEditingProps:function(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,selectable:this.selectable,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}},_restoreEditingProps:function(){this._savedProps&&(this.hoverCursor=this._savedProps.hoverCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,this.selectable=this._savedProps.selectable,this.lockMovementX=this._savedProps.lockMovementX,this.lockMovementY=this._savedProps.lockMovementY,this.canvas&&(this.canvas.defaultCursor=this._savedProps.defaultCursor,this.canvas.moveCursor=this._savedProps.moveCursor))},exitEditing:function(){var t=this._textBeforeEdit!==this.text,e=this.hiddenTextarea;return this.selected=!1,this.isEditing=!1,this.selectionEnd=this.selectionStart,e&&(e.blur&&e.blur(),e.parentNode&&e.parentNode.removeChild(e)),this.hiddenTextarea=null,this.abortCursorAnimation(),this._restoreEditingProps(),this._currentCursorOpacity=0,this._shouldClearDimensionCache()&&(this.initDimensions(),this.setCoords()),this.fire("editing:exited"),t&&this.fire("modified"),this.canvas&&(this.canvas.off("mouse:move",this.mouseMoveHandler),this.canvas.fire("text:editing:exited",{target:this}),t&&this.canvas.fire("object:modified",{target:this})),this},_removeExtraneousStyles:function(){for(var t in this.styles)this._textLines[t]||delete this.styles[t]},removeStyleFromTo:function(t,e){var i,r,n=this.get2DCursorLocation(t,!0),s=this.get2DCursorLocation(e,!0),o=n.lineIndex,a=n.charIndex,h=s.lineIndex,c=s.charIndex;if(o!==h){if(this.styles[o])for(i=a;it?this.selectionStart=t:this.selectionStart<0&&(this.selectionStart=0),this.selectionEnd>t?this.selectionEnd=t:this.selectionEnd<0&&(this.selectionEnd=0)}})}(),fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+new Date,this.__lastLastClickTime=+new Date,this.__lastPointer={},this.on("mousedown",this.onMouseDown)},onMouseDown:function(t){if(this.canvas){this.__newClickTime=+new Date;var e=t.pointer;this.isTripleClick(e)&&(this.fire("tripleclick",t),this._stopEvent(t.e)),this.__lastLastClickTime=this.__lastClickTime,this.__lastClickTime=this.__newClickTime,this.__lastPointer=e,this.__lastIsEditing=this.isEditing,this.__lastSelected=this.selected}},isTripleClick:function(t){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===t.x&&this.__lastPointer.y===t.y},_stopEvent:function(t){t.preventDefault&&t.preventDefault(),t.stopPropagation&&t.stopPropagation()},initCursorSelectionHandlers:function(){this.initMousedownHandler(),this.initMouseupHandler(),this.initClicks()},doubleClickHandler:function(t){this.isEditing&&this.selectWord(this.getSelectionStartFromPointer(t.e))},tripleClickHandler:function(t){this.isEditing&&this.selectLine(this.getSelectionStartFromPointer(t.e))},initClicks:function(){this.on("mousedblclick",this.doubleClickHandler),this.on("tripleclick",this.tripleClickHandler)},_mouseDownHandler:function(t){!this.canvas||!this.editable||t.e.button&&1!==t.e.button||(this.__isMousedown=!0,this.selected&&(this.inCompositionMode=!1,this.setCursorByClick(t.e)),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.selectionStart===this.selectionEnd&&this.abortCursorAnimation(),this.renderCursorOrSelection()))},_mouseDownHandlerBefore:function(t){!this.canvas||!this.editable||t.e.button&&1!==t.e.button||(this.selected=this===this.canvas._activeObject)},initMousedownHandler:function(){this.on("mousedown",this._mouseDownHandler),this.on("mousedown:before",this._mouseDownHandlerBefore)},initMouseupHandler:function(){this.on("mouseup",this.mouseUpHandler)},mouseUpHandler:function(t){if(this.__isMousedown=!1,!(!this.editable||this.group||t.transform&&t.transform.actionPerformed||t.e.button&&1!==t.e.button)){if(this.canvas){var e=this.canvas._activeObject;if(e&&e!==this)return}this.__lastSelected&&!this.__corner?(this.selected=!1,this.__lastSelected=!1,this.enterEditing(t.e),this.selectionStart===this.selectionEnd?this.initDelayedCursor(!0):this.renderCursorOrSelection()):this.selected=!0}},setCursorByClick:function(t){var e=this.getSelectionStartFromPointer(t),i=this.selectionStart,r=this.selectionEnd;t.shiftKey?this.setSelectionStartEndWithShift(i,r,e):(this.selectionStart=e,this.selectionEnd=e),this.isEditing&&(this._fireSelectionChanged(),this._updateTextarea())},getSelectionStartFromPointer:function(t){for(var e,i=this.getLocalPointer(t),r=0,n=0,s=0,o=0,a=0,h=0,c=this._textLines.length;hthis._text.length&&(a=this._text.length),a}}),fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(){this.hiddenTextarea=fabric.document.createElement("textarea"),this.hiddenTextarea.setAttribute("autocapitalize","off"),this.hiddenTextarea.setAttribute("autocorrect","off"),this.hiddenTextarea.setAttribute("autocomplete","off"),this.hiddenTextarea.setAttribute("spellcheck","false"),this.hiddenTextarea.setAttribute("data-fabric-hiddentextarea",""),this.hiddenTextarea.setAttribute("wrap","off");var t=this._calcTextareaPosition();this.hiddenTextarea.style.cssText="position: absolute; top: "+t.top+"; left: "+t.left+"; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; paddingーtop: "+t.fontSize+";",fabric.document.body.appendChild(this.hiddenTextarea),fabric.util.addListener(this.hiddenTextarea,"keydown",this.onKeyDown.bind(this)),fabric.util.addListener(this.hiddenTextarea,"keyup",this.onKeyUp.bind(this)),fabric.util.addListener(this.hiddenTextarea,"input",this.onInput.bind(this)),fabric.util.addListener(this.hiddenTextarea,"copy",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"cut",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"paste",this.paste.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionstart",this.onCompositionStart.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionupdate",this.onCompositionUpdate.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionend",this.onCompositionEnd.bind(this)),!this._clickHandlerInitialized&&this.canvas&&(fabric.util.addListener(this.canvas.upperCanvasEl,"click",this.onClick.bind(this)),this._clickHandlerInitialized=!0)},keysMap:{9:"exitEditing",27:"exitEditing",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorRight",36:"moveCursorLeft",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown"},keysMapRtl:{9:"exitEditing",27:"exitEditing",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorLeft",36:"moveCursorRight",37:"moveCursorRight",38:"moveCursorUp",39:"moveCursorLeft",40:"moveCursorDown"},ctrlKeysMapUp:{67:"copy",88:"cut"},ctrlKeysMapDown:{65:"selectAll"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(t){if(this.isEditing){var e="rtl"===this.direction?this.keysMapRtl:this.keysMap;if(t.keyCode in e)this[e[t.keyCode]](t);else{if(!(t.keyCode in this.ctrlKeysMapDown&&(t.ctrlKey||t.metaKey)))return;this[this.ctrlKeysMapDown[t.keyCode]](t)}t.stopImmediatePropagation(),t.preventDefault(),33<=t.keyCode&&t.keyCode<=40?(this.inCompositionMode=!1,this.clearContextTop(),this.renderCursorOrSelection()):this.canvas&&this.canvas.requestRenderAll()}},onKeyUp:function(t){!this.isEditing||this._copyDone||this.inCompositionMode?this._copyDone=!1:t.keyCode in this.ctrlKeysMapUp&&(t.ctrlKey||t.metaKey)&&(this[this.ctrlKeysMapUp[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.requestRenderAll())},onInput:function(t){var e=this.fromPaste;if(this.fromPaste=!1,t&&t.stopPropagation(),this.isEditing){var i,r,n,s,o,a=this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,h=this._text.length,c=a.length,l=c-h,u=this.selectionStart,f=this.selectionEnd,d=u!==f;if(""===this.hiddenTextarea.value)return this.styles={},this.updateFromTextArea(),this.fire("changed"),void(this.canvas&&(this.canvas.fire("text:changed",{target:this}),this.canvas.requestRenderAll()));var g=this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart,this.hiddenTextarea.selectionEnd,this.hiddenTextarea.value),p=u>g.selectionStart;d?(i=this._text.slice(u,f),l+=f-u):c=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorUpOrDown("Down",t)},moveCursorUp:function(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorUpOrDown("Up",t)},_moveCursorUpOrDown:function(t,e){var i=this["get"+t+"CursorOffset"](e,"right"===this._selectionDirection);e.shiftKey?this.moveCursorWithShift(i):this.moveCursorWithoutShift(i),0!==i&&(this.setSelectionInBoundaries(),this.abortCursorAnimation(),this._currentCursorOpacity=1,this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorWithShift:function(t){var e="left"===this._selectionDirection?this.selectionStart+t:this.selectionEnd+t;return this.setSelectionStartEndWithShift(this.selectionStart,this.selectionEnd,e),0!==t},moveCursorWithoutShift:function(t){return t<0?(this.selectionStart+=t,this.selectionEnd=this.selectionStart):(this.selectionEnd+=t,this.selectionStart=this.selectionEnd),0!==t},moveCursorLeft:function(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorLeftOrRight("Left",t)},_move:function(t,e,i){var r;if(t.altKey)r=this["findWordBoundary"+i](this[e]);else{if(!t.metaKey&&35!==t.keyCode&&36!==t.keyCode)return this[e]+="Left"===i?-1:1,!0;r=this["findLineBoundary"+i](this[e])}if(void 0!==typeof r&&this[e]!==r)return this[e]=r,!0},_moveLeft:function(t,e){return this._move(t,e,"Left")},_moveRight:function(t,e){return this._move(t,e,"Right")},moveCursorLeftWithoutShift:function(t){var e=!0;return this._selectionDirection="left",this.selectionEnd===this.selectionStart&&0!==this.selectionStart&&(e=this._moveLeft(t,"selectionStart")),this.selectionEnd=this.selectionStart,e},moveCursorLeftWithShift:function(t){return"right"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveLeft(t,"selectionEnd"):0!==this.selectionStart?(this._selectionDirection="left",this._moveLeft(t,"selectionStart")):void 0},moveCursorRight:function(t){this.selectionStart>=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorLeftOrRight("Right",t)},_moveCursorLeftOrRight:function(t,e){var i="moveCursor"+t+"With";this._currentCursorOpacity=1,e.shiftKey?i+="Shift":i+="outShift",this[i](e)&&(this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorRightWithShift:function(t){return"left"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveRight(t,"selectionStart"):this.selectionEnd!==this._text.length?(this._selectionDirection="right",this._moveRight(t,"selectionEnd")):void 0},moveCursorRightWithoutShift:function(t){var e=!0;return this._selectionDirection="right",this.selectionStart===this.selectionEnd?(e=this._moveRight(t,"selectionStart"),this.selectionEnd=this.selectionStart):this.selectionStart=this.selectionEnd,e},removeChars:function(t,e){void 0===e&&(e=t+1),this.removeStyleFromTo(t,e),this._text.splice(t,e-t),this.text=this._text.join(""),this.set("dirty",!0),this._shouldClearDimensionCache()&&(this.initDimensions(),this.setCoords()),this._removeExtraneousStyles()},insertChars:function(t,e,i,r){void 0===r&&(r=i),i",t.textSpans.join(""),"\n"]},_getSVGTextAndBg:function(t,e){var i,r=[],n=[],s=t;this._setSVGBg(n);for(var o=0,a=this._textLines.length;o",fabric.util.string.escapeXml(t),""].join("")},_setSVGTextLineText:function(t,e,i,r){var n,s,o,a,h,c=this.getHeightOfLine(e),l=-1!==this.textAlign.indexOf("justify"),u="",f=0,d=this._textLines[e];r+=c*(1-this._fontSizeFraction)/this.lineHeight;for(var g=0,p=d.length-1;g<=p;g++)h=g===p||this.charSpacing,u+=d[g],o=this.__charBounds[e][g],0===f?(i+=o.kernedWidth-o.width,f+=o.width):f+=o.kernedWidth,l&&!h&&this._reSpaceAndTab.test(d[g])&&(h=!0),h||(n=n||this.getCompleteStyleDeclaration(e,g),s=this.getCompleteStyleDeclaration(e,g+1),h=this._hasStyleChangedForSvg(n,s)),h&&(a=this._getStyleDeclaration(e,g)||{},t.push(this._createTextCharSpan(u,a,i,r)),u="",n=s,i+=f,f=0)},_pushTextBgRect:function(t,e,i,r,n,s){var o=fabric.Object.NUM_FRACTION_DIGITS;t.push("\t\t\n')},_setSVGTextLineBg:function(t,e,i,r){for(var n,s,o=this._textLines[e],a=this.getHeightOfLine(e)/this.lineHeight,h=0,c=0,l=this.getValueOfPropertyAt(e,0,"textBackgroundColor"),u=0,f=o.length;uthis.width&&this._set("width",this.dynamicMinWidth),-1!==this.textAlign.indexOf("justify")&&this.enlargeSpaces(),this.height=this.calcTextHeight(),this.saveState({propertySet:"_dimensionAffectingProps"}))},_generateStyleMap:function(t){for(var e=0,i=0,r=0,n={},s=0;sthis.dynamicMinWidth&&(this.dynamicMinWidth=g-v+r),o},isEndOfWrapping:function(t){return!this._styleMap[t+1]||this._styleMap[t+1].line!==this._styleMap[t].line},missingNewlineOffset:function(t){return this.splitByGrapheme?this.isEndOfWrapping(t)?1:0:1},_splitTextIntoLines:function(t){for(var e=b.Text.prototype._splitTextIntoLines.call(this,t),i=this._wrapText(e.lines,this.width),r=new Array(i.length),n=0;n 0); - -/** - * True when in environment that's probably Node.js - * @type boolean - */ -fabric.isLikelyNode = typeof Buffer !== 'undefined' && - typeof window === 'undefined'; - -/* _FROM_SVG_START_ */ -/** - * Attributes parsed from all SVG elements - * @type array - */ -fabric.SHARED_ATTRIBUTES = [ - 'display', - 'transform', - 'fill', 'fill-opacity', 'fill-rule', - 'opacity', - 'stroke', 'stroke-dasharray', 'stroke-linecap', 'stroke-dashoffset', - 'stroke-linejoin', 'stroke-miterlimit', - 'stroke-opacity', 'stroke-width', - 'id', 'paint-order', 'vector-effect', - 'instantiated_by_use', 'clip-path', -]; -/* _FROM_SVG_END_ */ - -/** - * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion. - */ -fabric.DPI = 96; -fabric.reNum = '(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:[eE][-+]?\\d+)?)'; -fabric.commaWsp = '(?:\\s+,?\\s*|,\\s*)'; -fabric.rePathCommand = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:[eE][-+]?\d+)?)/ig; -fabric.reNonWord = /[ \n\.,;!\?\-]/; -fabric.fontPaths = { }; -fabric.iMatrix = [1, 0, 0, 1, 0, 0]; -fabric.svgNS = 'http://www.w3.org/2000/svg'; - -/** - * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine. - * @since 1.7.14 - * @type Number - * @default - */ -fabric.perfLimitSizeTotal = 2097152; - -/** - * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000 - * @since 1.7.14 - * @type Number - * @default - */ -fabric.maxCacheSideLimit = 4096; - -/** - * Lowest pixel limit for cache canvases, set at 256PX - * @since 1.7.14 - * @type Number - * @default - */ -fabric.minCacheSideLimit = 256; - -/** - * Cache Object for widths of chars in text rendering. - */ -fabric.charWidthsCache = { }; - -/** - * if webgl is enabled and available, textureSize will determine the size - * of the canvas backend - * @since 2.0.0 - * @type Number - * @default - */ -fabric.textureSize = 2048; - -/** - * When 'true', style information is not retained when copy/pasting text, making - * pasted text use destination style. - * Defaults to 'false'. - * @type Boolean - * @default - */ -fabric.disableStyleCopyPaste = false; - -/** - * Enable webgl for filtering picture is available - * A filtering backend will be initialized, this will both take memory and - * time since a default 2048x2048 canvas will be created for the gl context - * @since 2.0.0 - * @type Boolean - * @default - */ -fabric.enableGLFiltering = true; - -/** - * Device Pixel Ratio - * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html - */ -fabric.devicePixelRatio = fabric.window.devicePixelRatio || - fabric.window.webkitDevicePixelRatio || - fabric.window.mozDevicePixelRatio || - 1; -/** - * Browser-specific constant to adjust CanvasRenderingContext2D.shadowBlur value, - * which is unitless and not rendered equally across browsers. - * - * Values that work quite well (as of October 2017) are: - * - Chrome: 1.5 - * - Edge: 1.75 - * - Firefox: 0.9 - * - Safari: 0.95 - * - * @since 2.0.0 - * @type Number - * @default 1 - */ -fabric.browserShadowBlurConstant = 1; - -/** - * This object contains the result of arc to bezier conversion for faster retrieving if the same arc needs to be converted again. - * It was an internal variable, is accessible since version 2.3.4 - */ -fabric.arcToSegmentsCache = { }; - -/** - * This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it. - * It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing - * you do not get any speed benefit and you get a big object in memory. - * The object was a private variable before, while now is appended to the lib so that you have access to it and you - * can eventually clear it. - * It was an internal variable, is accessible since version 2.3.4 - */ -fabric.boundsOfCurveCache = { }; - -/** - * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better - * @default true - */ -fabric.cachesBoundsOfCurve = true; - -/** - * Skip performance testing of setupGLContext and force the use of putImageData that seems to be the one that works best on - * Chrome + old hardware. if your users are experiencing empty images after filtering you may try to force this to true - * this has to be set before instantiating the filtering backend ( before filtering the first image ) - * @type Boolean - * @default false - */ -fabric.forceGLPutImageData = false; - -fabric.initFilterBackend = function() { - if (fabric.enableGLFiltering && fabric.isWebglSupported && fabric.isWebglSupported(fabric.textureSize)) { - console.log('max texture size: ' + fabric.maxTextureSize); - return (new fabric.WebglFilterBackend({ tileSize: fabric.textureSize })); - } - else if (fabric.Canvas2dFilterBackend) { - return (new fabric.Canvas2dFilterBackend()); - } -}; - - -if (typeof document !== 'undefined' && typeof window !== 'undefined') { - // ensure globality even if entire library were function wrapped (as in Meteor.js packaging system) - window.fabric = fabric; -} - - -(function() { - - /** - * @private - * @param {String} eventName - * @param {Function} handler - */ - function _removeEventListener(eventName, handler) { - if (!this.__eventListeners[eventName]) { - return; - } - var eventListener = this.__eventListeners[eventName]; - if (handler) { - eventListener[eventListener.indexOf(handler)] = false; - } - else { - fabric.util.array.fill(eventListener, false); - } - } - - /** - * Observes specified event - * @memberOf fabric.Observable - * @alias on - * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler}) - * @param {Function} handler Function that receives a notification when an event of the specified type occurs - * @return {Self} thisArg - * @chainable - */ - function on(eventName, handler) { - if (!this.__eventListeners) { - this.__eventListeners = { }; - } - // one object with key/value pairs was passed - if (arguments.length === 1) { - for (var prop in eventName) { - this.on(prop, eventName[prop]); - } - } - else { - if (!this.__eventListeners[eventName]) { - this.__eventListeners[eventName] = []; - } - this.__eventListeners[eventName].push(handler); - } - return this; - } - - function _once(eventName, handler) { - var _handler = function () { - handler.apply(this, arguments); - this.off(eventName, _handler); - }.bind(this); - this.on(eventName, _handler); - } - - function once(eventName, handler) { - // one object with key/value pairs was passed - if (arguments.length === 1) { - for (var prop in eventName) { - _once.call(this, prop, eventName[prop]); - } - } - else { - _once.call(this, eventName, handler); - } - return this; - } - - /** - * Stops event observing for a particular event handler. Calling this method - * without arguments removes all handlers for all events - * @memberOf fabric.Observable - * @alias off - * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler}) - * @param {Function} handler Function to be deleted from EventListeners - * @return {Self} thisArg - * @chainable - */ - function off(eventName, handler) { - if (!this.__eventListeners) { - return this; - } - - // remove all key/value pairs (event name -> event handler) - if (arguments.length === 0) { - for (eventName in this.__eventListeners) { - _removeEventListener.call(this, eventName); - } - } - // one object with key/value pairs was passed - else if (arguments.length === 1 && typeof arguments[0] === 'object') { - for (var prop in eventName) { - _removeEventListener.call(this, prop, eventName[prop]); - } - } - else { - _removeEventListener.call(this, eventName, handler); - } - return this; - } - - /** - * Fires event with an optional options object - * @memberOf fabric.Observable - * @param {String} eventName Event name to fire - * @param {Object} [options] Options object - * @return {Self} thisArg - * @chainable - */ - function fire(eventName, options) { - if (!this.__eventListeners) { - return this; - } - - var listenersForEvent = this.__eventListeners[eventName]; - if (!listenersForEvent) { - return this; - } - - for (var i = 0, len = listenersForEvent.length; i < len; i++) { - listenersForEvent[i] && listenersForEvent[i].call(this, options || { }); - } - this.__eventListeners[eventName] = listenersForEvent.filter(function(value) { - return value !== false; - }); - return this; - } - - /** - * @namespace fabric.Observable - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events} - * @see {@link http://fabricjs.com/events|Events demo} - */ - fabric.Observable = { - fire: fire, - on: on, - once: once, - off: off, - }; -})(); - - -/** - * @namespace fabric.Collection - */ -fabric.Collection = { - - _objects: [], - - /** - * Adds objects to collection, Canvas or Group, then renders canvas - * (if `renderOnAddRemove` is not `false`). - * in case of Group no changes to bounding box are made. - * Objects should be instances of (or inherit from) fabric.Object - * Use of this function is highly discouraged for groups. - * you can add a bunch of objects with the add method but then you NEED - * to run a addWithUpdate call for the Group class or position/bbox will be wrong. - * @param {...fabric.Object} object Zero or more fabric instances - * @return {Self} thisArg - * @chainable - */ - add: function () { - this._objects.push.apply(this._objects, arguments); - if (this._onObjectAdded) { - for (var i = 0, length = arguments.length; i < length; i++) { - this._onObjectAdded(arguments[i]); - } - } - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * Inserts an object into collection at specified index, then renders canvas (if `renderOnAddRemove` is not `false`) - * An object should be an instance of (or inherit from) fabric.Object - * Use of this function is highly discouraged for groups. - * you can add a bunch of objects with the insertAt method but then you NEED - * to run a addWithUpdate call for the Group class or position/bbox will be wrong. - * @param {Object} object Object to insert - * @param {Number} index Index to insert object at - * @param {Boolean} nonSplicing When `true`, no splicing (shifting) of objects occurs - * @return {Self} thisArg - * @chainable - */ - insertAt: function (object, index, nonSplicing) { - var objects = this._objects; - if (nonSplicing) { - objects[index] = object; - } - else { - objects.splice(index, 0, object); - } - this._onObjectAdded && this._onObjectAdded(object); - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`) - * @param {...fabric.Object} object Zero or more fabric instances - * @return {Self} thisArg - * @chainable - */ - remove: function() { - var objects = this._objects, - index, somethingRemoved = false; - - for (var i = 0, length = arguments.length; i < length; i++) { - index = objects.indexOf(arguments[i]); - - // only call onObjectRemoved if an object was actually removed - if (index !== -1) { - somethingRemoved = true; - objects.splice(index, 1); - this._onObjectRemoved && this._onObjectRemoved(arguments[i]); - } - } - - this.renderOnAddRemove && somethingRemoved && this.requestRenderAll(); - return this; - }, - - /** - * Executes given function for each object in this group - * @param {Function} callback - * Callback invoked with current object as first argument, - * index - as second and an array of all objects - as third. - * Callback is invoked in a context of Global Object (e.g. `window`) - * when no `context` argument is given - * - * @param {Object} context Context (aka thisObject) - * @return {Self} thisArg - * @chainable - */ - forEachObject: function(callback, context) { - var objects = this.getObjects(); - for (var i = 0, len = objects.length; i < len; i++) { - callback.call(context, objects[i], i, objects); - } - return this; - }, - - /** - * Returns an array of children objects of this instance - * Type parameter introduced in 1.3.10 - * since 2.3.5 this method return always a COPY of the array; - * @param {String} [type] When specified, only objects of this type are returned - * @return {Array} - */ - getObjects: function(type) { - if (typeof type === 'undefined') { - return this._objects.concat(); - } - return this._objects.filter(function(o) { - return o.type === type; - }); - }, - - /** - * Returns object at specified index - * @param {Number} index - * @return {Self} thisArg - */ - item: function (index) { - return this._objects[index]; - }, - - /** - * Returns true if collection contains no objects - * @return {Boolean} true if collection is empty - */ - isEmpty: function () { - return this._objects.length === 0; - }, - - /** - * Returns a size of a collection (i.e: length of an array containing its objects) - * @return {Number} Collection size - */ - size: function() { - return this._objects.length; - }, - - /** - * Returns true if collection contains an object - * @param {Object} object Object to check against - * @param {Boolean} [deep=false] `true` to check all descendants, `false` to check only `_objects` - * @return {Boolean} `true` if collection contains an object - */ - contains: function (object, deep) { - if (this._objects.indexOf(object) > -1) { - return true; - } - else if (deep) { - return this._objects.some(function (obj) { - return typeof obj.contains === 'function' && obj.contains(object, true); - }); - } - return false; - }, - - /** - * Returns number representation of a collection complexity - * @return {Number} complexity - */ - complexity: function () { - return this._objects.reduce(function (memo, current) { - memo += current.complexity ? current.complexity() : 0; - return memo; - }, 0); - } -}; - - -/** - * @namespace fabric.CommonMethods - */ -fabric.CommonMethods = { - - /** - * Sets object's properties from options - * @param {Object} [options] Options object - */ - _setOptions: function(options) { - for (var prop in options) { - this.set(prop, options[prop]); - } - }, - - /** - * @private - * @param {Object} [filler] Options object - * @param {String} [property] property to set the Gradient to - */ - _initGradient: function(filler, property) { - if (filler && filler.colorStops && !(filler instanceof fabric.Gradient)) { - this.set(property, new fabric.Gradient(filler)); - } - }, - - /** - * @private - * @param {Object} [filler] Options object - * @param {String} [property] property to set the Pattern to - * @param {Function} [callback] callback to invoke after pattern load - */ - _initPattern: function(filler, property, callback) { - if (filler && filler.source && !(filler instanceof fabric.Pattern)) { - this.set(property, new fabric.Pattern(filler, callback)); - } - else { - callback && callback(); - } - }, - - /** - * @private - */ - _setObject: function(obj) { - for (var prop in obj) { - this._set(prop, obj[prop]); - } - }, - - /** - * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`. - * @param {String|Object} key Property name or object (if object, iterate over the object properties) - * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one) - * @return {fabric.Object} thisArg - * @chainable - */ - set: function(key, value) { - if (typeof key === 'object') { - this._setObject(key); - } - else { - this._set(key, value); - } - return this; - }, - - _set: function(key, value) { - this[key] = value; - }, - - /** - * Toggles specified property from `true` to `false` or from `false` to `true` - * @param {String} property Property to toggle - * @return {fabric.Object} thisArg - * @chainable - */ - toggle: function(property) { - var value = this.get(property); - if (typeof value === 'boolean') { - this.set(property, !value); - } - return this; - }, - - /** - * Basic getter - * @param {String} property Property name - * @return {*} value of a property - */ - get: function(property) { - return this[property]; - } -}; - - -(function(global) { - - var sqrt = Math.sqrt, - atan2 = Math.atan2, - pow = Math.pow, - PiBy180 = Math.PI / 180, - PiBy2 = Math.PI / 2; - - /** - * @namespace fabric.util - */ - fabric.util = { - - /** - * Calculate the cos of an angle, avoiding returning floats for known results - * @static - * @memberOf fabric.util - * @param {Number} angle the angle in radians or in degree - * @return {Number} - */ - cos: function(angle) { - if (angle === 0) { return 1; } - if (angle < 0) { - // cos(a) = cos(-a) - angle = -angle; - } - var angleSlice = angle / PiBy2; - switch (angleSlice) { - case 1: case 3: return 0; - case 2: return -1; - } - return Math.cos(angle); - }, - - /** - * Calculate the sin of an angle, avoiding returning floats for known results - * @static - * @memberOf fabric.util - * @param {Number} angle the angle in radians or in degree - * @return {Number} - */ - sin: function(angle) { - if (angle === 0) { return 0; } - var angleSlice = angle / PiBy2, sign = 1; - if (angle < 0) { - // sin(-a) = -sin(a) - sign = -1; - } - switch (angleSlice) { - case 1: return sign; - case 2: return 0; - case 3: return -sign; - } - return Math.sin(angle); - }, - - /** - * Removes value from an array. - * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf` - * @static - * @memberOf fabric.util - * @param {Array} array - * @param {*} value - * @return {Array} original array - */ - removeFromArray: function(array, value) { - var idx = array.indexOf(value); - if (idx !== -1) { - array.splice(idx, 1); - } - return array; - }, - - /** - * Returns random number between 2 specified ones. - * @static - * @memberOf fabric.util - * @param {Number} min lower limit - * @param {Number} max upper limit - * @return {Number} random value (between min and max) - */ - getRandomInt: function(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; - }, - - /** - * Transforms degrees to radians. - * @static - * @memberOf fabric.util - * @param {Number} degrees value in degrees - * @return {Number} value in radians - */ - degreesToRadians: function(degrees) { - return degrees * PiBy180; - }, - - /** - * Transforms radians to degrees. - * @static - * @memberOf fabric.util - * @param {Number} radians value in radians - * @return {Number} value in degrees - */ - radiansToDegrees: function(radians) { - return radians / PiBy180; - }, - - /** - * Rotates `point` around `origin` with `radians` - * @static - * @memberOf fabric.util - * @param {fabric.Point} point The point to rotate - * @param {fabric.Point} origin The origin of the rotation - * @param {Number} radians The radians of the angle for the rotation - * @return {fabric.Point} The new rotated point - */ - rotatePoint: function(point, origin, radians) { - var newPoint = new fabric.Point(point.x - origin.x, point.y - origin.y), - v = fabric.util.rotateVector(newPoint, radians); - return new fabric.Point(v.x, v.y).addEquals(origin); - }, - - /** - * Rotates `vector` with `radians` - * @static - * @memberOf fabric.util - * @param {Object} vector The vector to rotate (x and y) - * @param {Number} radians The radians of the angle for the rotation - * @return {Object} The new rotated point - */ - rotateVector: function(vector, radians) { - var sin = fabric.util.sin(radians), - cos = fabric.util.cos(radians), - rx = vector.x * cos - vector.y * sin, - ry = vector.x * sin + vector.y * cos; - return { - x: rx, - y: ry - }; - }, - - /** - * Apply transform t to point p - * @static - * @memberOf fabric.util - * @param {fabric.Point} p The point to transform - * @param {Array} t The transform - * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied - * @return {fabric.Point} The transformed point - */ - transformPoint: function(p, t, ignoreOffset) { - if (ignoreOffset) { - return new fabric.Point( - t[0] * p.x + t[2] * p.y, - t[1] * p.x + t[3] * p.y - ); - } - return new fabric.Point( - t[0] * p.x + t[2] * p.y + t[4], - t[1] * p.x + t[3] * p.y + t[5] - ); - }, - - /** - * Returns coordinates of points's bounding rectangle (left, top, width, height) - * @param {Array} points 4 points array - * @param {Array} [transform] an array of 6 numbers representing a 2x3 transform matrix - * @return {Object} Object with left, top, width, height properties - */ - makeBoundingBoxFromPoints: function(points, transform) { - if (transform) { - for (var i = 0; i < points.length; i++) { - points[i] = fabric.util.transformPoint(points[i], transform); - } - } - var xPoints = [points[0].x, points[1].x, points[2].x, points[3].x], - minX = fabric.util.array.min(xPoints), - maxX = fabric.util.array.max(xPoints), - width = maxX - minX, - yPoints = [points[0].y, points[1].y, points[2].y, points[3].y], - minY = fabric.util.array.min(yPoints), - maxY = fabric.util.array.max(yPoints), - height = maxY - minY; - - return { - left: minX, - top: minY, - width: width, - height: height - }; - }, - - /** - * Invert transformation t - * @static - * @memberOf fabric.util - * @param {Array} t The transform - * @return {Array} The inverted transform - */ - invertTransform: function(t) { - var a = 1 / (t[0] * t[3] - t[1] * t[2]), - r = [a * t[3], -a * t[1], -a * t[2], a * t[0]], - o = fabric.util.transformPoint({ x: t[4], y: t[5] }, r, true); - r[4] = -o.x; - r[5] = -o.y; - return r; - }, - - /** - * A wrapper around Number#toFixed, which contrary to native method returns number, not string. - * @static - * @memberOf fabric.util - * @param {Number|String} number number to operate on - * @param {Number} fractionDigits number of fraction digits to "leave" - * @return {Number} - */ - toFixed: function(number, fractionDigits) { - return parseFloat(Number(number).toFixed(fractionDigits)); - }, - - /** - * Converts from attribute value to pixel value if applicable. - * Returns converted pixels or original value not converted. - * @param {Number|String} value number to operate on - * @param {Number} fontSize - * @return {Number|String} - */ - parseUnit: function(value, fontSize) { - var unit = /\D{0,2}$/.exec(value), - number = parseFloat(value); - if (!fontSize) { - fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE; - } - switch (unit[0]) { - case 'mm': - return number * fabric.DPI / 25.4; - - case 'cm': - return number * fabric.DPI / 2.54; - - case 'in': - return number * fabric.DPI; - - case 'pt': - return number * fabric.DPI / 72; // or * 4 / 3 - - case 'pc': - return number * fabric.DPI / 72 * 12; // or * 16 - - case 'em': - return number * fontSize; - - default: - return number; - } - }, - - /** - * Function which always returns `false`. - * @static - * @memberOf fabric.util - * @return {Boolean} - */ - falseFunction: function() { - return false; - }, - - /** - * Returns klass "Class" object of given namespace - * @memberOf fabric.util - * @param {String} type Type of object (eg. 'circle') - * @param {String} namespace Namespace to get klass "Class" object from - * @return {Object} klass "Class" - */ - getKlass: function(type, namespace) { - // capitalize first letter only - type = fabric.util.string.camelize(type.charAt(0).toUpperCase() + type.slice(1)); - return fabric.util.resolveNamespace(namespace)[type]; - }, - - /** - * Returns array of attributes for given svg that fabric parses - * @memberOf fabric.util - * @param {String} type Type of svg element (eg. 'circle') - * @return {Array} string names of supported attributes - */ - getSvgAttributes: function(type) { - var attributes = [ - 'instantiated_by_use', - 'style', - 'id', - 'class' - ]; - switch (type) { - case 'linearGradient': - attributes = attributes.concat(['x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform']); - break; - case 'radialGradient': - attributes = attributes.concat(['gradientUnits', 'gradientTransform', 'cx', 'cy', 'r', 'fx', 'fy', 'fr']); - break; - case 'stop': - attributes = attributes.concat(['offset', 'stop-color', 'stop-opacity']); - break; - } - return attributes; - }, - - /** - * Returns object of given namespace - * @memberOf fabric.util - * @param {String} namespace Namespace string e.g. 'fabric.Image.filter' or 'fabric' - * @return {Object} Object for given namespace (default fabric) - */ - resolveNamespace: function(namespace) { - if (!namespace) { - return fabric; - } - - var parts = namespace.split('.'), - len = parts.length, i, - obj = global || fabric.window; - - for (i = 0; i < len; ++i) { - obj = obj[parts[i]]; - } - - return obj; - }, - - /** - * Loads image element from given url and passes it to a callback - * @memberOf fabric.util - * @param {String} url URL representing an image - * @param {Function} callback Callback; invoked with loaded image - * @param {*} [context] Context to invoke callback in - * @param {Object} [crossOrigin] crossOrigin value to set image element to - */ - loadImage: function(url, callback, context, crossOrigin) { - if (!url) { - callback && callback.call(context, url); - return; - } - - var img = fabric.util.createImage(); - - /** @ignore */ - var onLoadCallback = function () { - callback && callback.call(context, img, false); - img = img.onload = img.onerror = null; - }; - - img.onload = onLoadCallback; - /** @ignore */ - img.onerror = function() { - fabric.log('Error loading ' + img.src); - callback && callback.call(context, null, true); - img = img.onload = img.onerror = null; - }; - - // data-urls appear to be buggy with crossOrigin - // https://github.com/kangax/fabric.js/commit/d0abb90f1cd5c5ef9d2a94d3fb21a22330da3e0a#commitcomment-4513767 - // see https://code.google.com/p/chromium/issues/detail?id=315152 - // https://bugzilla.mozilla.org/show_bug.cgi?id=935069 - // crossOrigin null is the same as not set. - if (url.indexOf('data') !== 0 && - crossOrigin !== undefined && - crossOrigin !== null) { - img.crossOrigin = crossOrigin; - } - - // IE10 / IE11-Fix: SVG contents from data: URI - // will only be available if the IMG is present - // in the DOM (and visible) - if (url.substring(0,14) === 'data:image/svg') { - img.onload = null; - fabric.util.loadImageInDom(img, onLoadCallback); - } - - img.src = url; - }, - - /** - * Attaches SVG image with data: URL to the dom - * @memberOf fabric.util - * @param {Object} img Image object with data:image/svg src - * @param {Function} callback Callback; invoked with loaded image - * @return {Object} DOM element (div containing the SVG image) - */ - loadImageInDom: function(img, onLoadCallback) { - var div = fabric.document.createElement('div'); - div.style.width = div.style.height = '1px'; - div.style.left = div.style.top = '-100%'; - div.style.position = 'absolute'; - div.appendChild(img); - fabric.document.querySelector('body').appendChild(div); - /** - * Wrap in function to: - * 1. Call existing callback - * 2. Cleanup DOM - */ - img.onload = function () { - onLoadCallback(); - div.parentNode.removeChild(div); - div = null; - }; - }, - - /** - * Creates corresponding fabric instances from their object representations - * @static - * @memberOf fabric.util - * @param {Array} objects Objects to enliven - * @param {Function} callback Callback to invoke when all objects are created - * @param {String} namespace Namespace to get klass "Class" object from - * @param {Function} reviver Method for further parsing of object elements, - * called after each fabric object created. - */ - enlivenObjects: function(objects, callback, namespace, reviver) { - objects = objects || []; - - var enlivenedObjects = [], - numLoadedObjects = 0, - numTotalObjects = objects.length; - - function onLoaded() { - if (++numLoadedObjects === numTotalObjects) { - callback && callback(enlivenedObjects.filter(function(obj) { - // filter out undefined objects (objects that gave error) - return obj; - })); - } - } - - if (!numTotalObjects) { - callback && callback(enlivenedObjects); - return; - } - - objects.forEach(function (o, index) { - // if sparse array - if (!o || !o.type) { - onLoaded(); - return; - } - var klass = fabric.util.getKlass(o.type, namespace); - klass.fromObject(o, function (obj, error) { - error || (enlivenedObjects[index] = obj); - reviver && reviver(o, obj, error); - onLoaded(); - }); - }); - }, - - /** - * Create and wait for loading of patterns - * @static - * @memberOf fabric.util - * @param {Array} patterns Objects to enliven - * @param {Function} callback Callback to invoke when all objects are created - * called after each fabric object created. - */ - enlivenPatterns: function(patterns, callback) { - patterns = patterns || []; - - function onLoaded() { - if (++numLoadedPatterns === numPatterns) { - callback && callback(enlivenedPatterns); - } - } - - var enlivenedPatterns = [], - numLoadedPatterns = 0, - numPatterns = patterns.length; - - if (!numPatterns) { - callback && callback(enlivenedPatterns); - return; - } - - patterns.forEach(function (p, index) { - if (p && p.source) { - new fabric.Pattern(p, function(pattern) { - enlivenedPatterns[index] = pattern; - onLoaded(); - }); - } - else { - enlivenedPatterns[index] = p; - onLoaded(); - } - }); - }, - - /** - * Groups SVG elements (usually those retrieved from SVG document) - * @static - * @memberOf fabric.util - * @param {Array} elements SVG elements to group - * @param {Object} [options] Options object - * @param {String} path Value to set sourcePath to - * @return {fabric.Object|fabric.Group} - */ - groupSVGElements: function(elements, options, path) { - var object; - if (elements && elements.length === 1) { - return elements[0]; - } - if (options) { - if (options.width && options.height) { - options.centerPoint = { - x: options.width / 2, - y: options.height / 2 - }; - } - else { - delete options.width; - delete options.height; - } - } - object = new fabric.Group(elements, options); - if (typeof path !== 'undefined') { - object.sourcePath = path; - } - return object; - }, - - /** - * Populates an object with properties of another object - * @static - * @memberOf fabric.util - * @param {Object} source Source object - * @param {Object} destination Destination object - * @return {Array} properties Properties names to include - */ - populateWithProperties: function(source, destination, properties) { - if (properties && Object.prototype.toString.call(properties) === '[object Array]') { - for (var i = 0, len = properties.length; i < len; i++) { - if (properties[i] in source) { - destination[properties[i]] = source[properties[i]]; - } - } - } - }, - - /** - * WARNING: THIS WAS TO SUPPORT OLD BROWSERS. deprecated. - * WILL BE REMOVED IN FABRIC 5.0 - * Draws a dashed line between two points - * - * This method is used to draw dashed line around selection area. - * See dotted stroke in canvas - * - * @param {CanvasRenderingContext2D} ctx context - * @param {Number} x start x coordinate - * @param {Number} y start y coordinate - * @param {Number} x2 end x coordinate - * @param {Number} y2 end y coordinate - * @param {Array} da dash array pattern - * @deprecated - */ - drawDashedLine: function(ctx, x, y, x2, y2, da) { - var dx = x2 - x, - dy = y2 - y, - len = sqrt(dx * dx + dy * dy), - rot = atan2(dy, dx), - dc = da.length, - di = 0, - draw = true; - - ctx.save(); - ctx.translate(x, y); - ctx.moveTo(0, 0); - ctx.rotate(rot); - - x = 0; - while (len > x) { - x += da[di++ % dc]; - if (x > len) { - x = len; - } - ctx[draw ? 'lineTo' : 'moveTo'](x, 0); - draw = !draw; - } - - ctx.restore(); - }, - - /** - * Creates canvas element - * @static - * @memberOf fabric.util - * @return {CanvasElement} initialized canvas element - */ - createCanvasElement: function() { - return fabric.document.createElement('canvas'); - }, - - /** - * Creates a canvas element that is a copy of another and is also painted - * @param {CanvasElement} canvas to copy size and content of - * @static - * @memberOf fabric.util - * @return {CanvasElement} initialized canvas element - */ - copyCanvasElement: function(canvas) { - var newCanvas = fabric.util.createCanvasElement(); - newCanvas.width = canvas.width; - newCanvas.height = canvas.height; - newCanvas.getContext('2d').drawImage(canvas, 0, 0); - return newCanvas; - }, - - /** - * since 2.6.0 moved from canvas instance to utility. - * @param {CanvasElement} canvasEl to copy size and content of - * @param {String} format 'jpeg' or 'png', in some browsers 'webp' is ok too - * @param {Number} quality <= 1 and > 0 - * @static - * @memberOf fabric.util - * @return {String} data url - */ - toDataURL: function(canvasEl, format, quality) { - return canvasEl.toDataURL('image/' + format, quality); - }, - - /** - * Creates image element (works on client and node) - * @static - * @memberOf fabric.util - * @return {HTMLImageElement} HTML image element - */ - createImage: function() { - return fabric.document.createElement('img'); - }, - - /** - * Multiply matrix A by matrix B to nest transformations - * @static - * @memberOf fabric.util - * @param {Array} a First transformMatrix - * @param {Array} b Second transformMatrix - * @param {Boolean} is2x2 flag to multiply matrices as 2x2 matrices - * @return {Array} The product of the two transform matrices - */ - multiplyTransformMatrices: function(a, b, is2x2) { - // Matrix multiply a * b - return [ - a[0] * b[0] + a[2] * b[1], - a[1] * b[0] + a[3] * b[1], - a[0] * b[2] + a[2] * b[3], - a[1] * b[2] + a[3] * b[3], - is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4], - is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5] - ]; - }, - - /** - * Decomposes standard 2x3 matrix into transform components - * @static - * @memberOf fabric.util - * @param {Array} a transformMatrix - * @return {Object} Components of transform - */ - qrDecompose: function(a) { - var angle = atan2(a[1], a[0]), - denom = pow(a[0], 2) + pow(a[1], 2), - scaleX = sqrt(denom), - scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX, - skewX = atan2(a[0] * a[2] + a[1] * a [3], denom); - return { - angle: angle / PiBy180, - scaleX: scaleX, - scaleY: scaleY, - skewX: skewX / PiBy180, - skewY: 0, - translateX: a[4], - translateY: a[5] - }; - }, - - /** - * Returns a transform matrix starting from an object of the same kind of - * the one returned from qrDecompose, useful also if you want to calculate some - * transformations from an object that is not enlived yet - * @static - * @memberOf fabric.util - * @param {Object} options - * @param {Number} [options.angle] angle in degrees - * @return {Number[]} transform matrix - */ - calcRotateMatrix: function(options) { - if (!options.angle) { - return fabric.iMatrix.concat(); - } - var theta = fabric.util.degreesToRadians(options.angle), - cos = fabric.util.cos(theta), - sin = fabric.util.sin(theta); - return [cos, sin, -sin, cos, 0, 0]; - }, - - /** - * Returns a transform matrix starting from an object of the same kind of - * the one returned from qrDecompose, useful also if you want to calculate some - * transformations from an object that is not enlived yet. - * is called DimensionsTransformMatrix because those properties are the one that influence - * the size of the resulting box of the object. - * @static - * @memberOf fabric.util - * @param {Object} options - * @param {Number} [options.scaleX] - * @param {Number} [options.scaleY] - * @param {Boolean} [options.flipX] - * @param {Boolean} [options.flipY] - * @param {Number} [options.skewX] - * @param {Number} [options.skewX] - * @return {Number[]} transform matrix - */ - calcDimensionsMatrix: function(options) { - var scaleX = typeof options.scaleX === 'undefined' ? 1 : options.scaleX, - scaleY = typeof options.scaleY === 'undefined' ? 1 : options.scaleY, - scaleMatrix = [ - options.flipX ? -scaleX : scaleX, - 0, - 0, - options.flipY ? -scaleY : scaleY, - 0, - 0], - multiply = fabric.util.multiplyTransformMatrices, - degreesToRadians = fabric.util.degreesToRadians; - if (options.skewX) { - scaleMatrix = multiply( - scaleMatrix, - [1, 0, Math.tan(degreesToRadians(options.skewX)), 1], - true); - } - if (options.skewY) { - scaleMatrix = multiply( - scaleMatrix, - [1, Math.tan(degreesToRadians(options.skewY)), 0, 1], - true); - } - return scaleMatrix; - }, - - /** - * Returns a transform matrix starting from an object of the same kind of - * the one returned from qrDecompose, useful also if you want to calculate some - * transformations from an object that is not enlived yet - * @static - * @memberOf fabric.util - * @param {Object} options - * @param {Number} [options.angle] - * @param {Number} [options.scaleX] - * @param {Number} [options.scaleY] - * @param {Boolean} [options.flipX] - * @param {Boolean} [options.flipY] - * @param {Number} [options.skewX] - * @param {Number} [options.skewX] - * @param {Number} [options.translateX] - * @param {Number} [options.translateY] - * @return {Number[]} transform matrix - */ - composeMatrix: function(options) { - var matrix = [1, 0, 0, 1, options.translateX || 0, options.translateY || 0], - multiply = fabric.util.multiplyTransformMatrices; - if (options.angle) { - matrix = multiply(matrix, fabric.util.calcRotateMatrix(options)); - } - if (options.scaleX !== 1 || options.scaleY !== 1 || - options.skewX || options.skewY || options.flipX || options.flipY) { - matrix = multiply(matrix, fabric.util.calcDimensionsMatrix(options)); - } - return matrix; - }, - - /** - * reset an object transform state to neutral. Top and left are not accounted for - * @static - * @memberOf fabric.util - * @param {fabric.Object} target object to transform - */ - resetObjectTransform: function (target) { - target.scaleX = 1; - target.scaleY = 1; - target.skewX = 0; - target.skewY = 0; - target.flipX = false; - target.flipY = false; - target.rotate(0); - }, - - /** - * Extract Object transform values - * @static - * @memberOf fabric.util - * @param {fabric.Object} target object to read from - * @return {Object} Components of transform - */ - saveObjectTransform: function (target) { - return { - scaleX: target.scaleX, - scaleY: target.scaleY, - skewX: target.skewX, - skewY: target.skewY, - angle: target.angle, - left: target.left, - flipX: target.flipX, - flipY: target.flipY, - top: target.top - }; - }, - - /** - * Returns true if context has transparent pixel - * at specified location (taking tolerance into account) - * @param {CanvasRenderingContext2D} ctx context - * @param {Number} x x coordinate - * @param {Number} y y coordinate - * @param {Number} tolerance Tolerance - */ - isTransparent: function(ctx, x, y, tolerance) { - - // If tolerance is > 0 adjust start coords to take into account. - // If moves off Canvas fix to 0 - if (tolerance > 0) { - if (x > tolerance) { - x -= tolerance; - } - else { - x = 0; - } - if (y > tolerance) { - y -= tolerance; - } - else { - y = 0; - } - } - - var _isTransparent = true, i, temp, - imageData = ctx.getImageData(x, y, (tolerance * 2) || 1, (tolerance * 2) || 1), - l = imageData.data.length; - - // Split image data - for tolerance > 1, pixelDataSize = 4; - for (i = 3; i < l; i += 4) { - temp = imageData.data[i]; - _isTransparent = temp <= 0; - if (_isTransparent === false) { - break; // Stop if colour found - } - } - - imageData = null; - - return _isTransparent; - }, - - /** - * Parse preserveAspectRatio attribute from element - * @param {string} attribute to be parsed - * @return {Object} an object containing align and meetOrSlice attribute - */ - parsePreserveAspectRatioAttribute: function(attribute) { - var meetOrSlice = 'meet', alignX = 'Mid', alignY = 'Mid', - aspectRatioAttrs = attribute.split(' '), align; - - if (aspectRatioAttrs && aspectRatioAttrs.length) { - meetOrSlice = aspectRatioAttrs.pop(); - if (meetOrSlice !== 'meet' && meetOrSlice !== 'slice') { - align = meetOrSlice; - meetOrSlice = 'meet'; - } - else if (aspectRatioAttrs.length) { - align = aspectRatioAttrs.pop(); - } - } - //divide align in alignX and alignY - alignX = align !== 'none' ? align.slice(1, 4) : 'none'; - alignY = align !== 'none' ? align.slice(5, 8) : 'none'; - return { - meetOrSlice: meetOrSlice, - alignX: alignX, - alignY: alignY - }; - }, - - /** - * Clear char widths cache for the given font family or all the cache if no - * fontFamily is specified. - * Use it if you know you are loading fonts in a lazy way and you are not waiting - * for custom fonts to load properly when adding text objects to the canvas. - * If a text object is added when its own font is not loaded yet, you will get wrong - * measurement and so wrong bounding boxes. - * After the font cache is cleared, either change the textObject text content or call - * initDimensions() to trigger a recalculation - * @memberOf fabric.util - * @param {String} [fontFamily] font family to clear - */ - clearFabricFontCache: function(fontFamily) { - fontFamily = (fontFamily || '').toLowerCase(); - if (!fontFamily) { - fabric.charWidthsCache = { }; - } - else if (fabric.charWidthsCache[fontFamily]) { - delete fabric.charWidthsCache[fontFamily]; - } - }, - - /** - * Given current aspect ratio, determines the max width and height that can - * respect the total allowed area for the cache. - * @memberOf fabric.util - * @param {Number} ar aspect ratio - * @param {Number} maximumArea Maximum area you want to achieve - * @return {Object.x} Limited dimensions by X - * @return {Object.y} Limited dimensions by Y - */ - limitDimsByArea: function(ar, maximumArea) { - var roughWidth = Math.sqrt(maximumArea * ar), - perfLimitSizeY = Math.floor(maximumArea / roughWidth); - return { x: Math.floor(roughWidth), y: perfLimitSizeY }; - }, - - capValue: function(min, value, max) { - return Math.max(min, Math.min(value, max)); - }, - - /** - * Finds the scale for the object source to fit inside the object destination, - * keeping aspect ratio intact. - * respect the total allowed area for the cache. - * @memberOf fabric.util - * @param {Object | fabric.Object} source - * @param {Number} source.height natural unscaled height of the object - * @param {Number} source.width natural unscaled width of the object - * @param {Object | fabric.Object} destination - * @param {Number} destination.height natural unscaled height of the object - * @param {Number} destination.width natural unscaled width of the object - * @return {Number} scale factor to apply to source to fit into destination - */ - findScaleToFit: function(source, destination) { - return Math.min(destination.width / source.width, destination.height / source.height); - }, - - /** - * Finds the scale for the object source to cover entirely the object destination, - * keeping aspect ratio intact. - * respect the total allowed area for the cache. - * @memberOf fabric.util - * @param {Object | fabric.Object} source - * @param {Number} source.height natural unscaled height of the object - * @param {Number} source.width natural unscaled width of the object - * @param {Object | fabric.Object} destination - * @param {Number} destination.height natural unscaled height of the object - * @param {Number} destination.width natural unscaled width of the object - * @return {Number} scale factor to apply to source to cover destination - */ - findScaleToCover: function(source, destination) { - return Math.max(destination.width / source.width, destination.height / source.height); - }, - - /** - * given an array of 6 number returns something like `"matrix(...numbers)"` - * @memberOf fabric.util - * @param {Array} transform an array with 6 numbers - * @return {String} transform matrix for svg - * @return {Object.y} Limited dimensions by Y - */ - matrixToSVG: function(transform) { - return 'matrix(' + transform.map(function(value) { - return fabric.util.toFixed(value, fabric.Object.NUM_FRACTION_DIGITS); - }).join(' ') + ')'; - }, - - /** - * given an object and a transform, apply the inverse transform to the object, - * this is equivalent to remove from that object that transformation, so that - * added in a space with the removed transform, the object will be the same as before. - * Removing from an object a transform that scale by 2 is like scaling it by 1/2. - * Removing from an object a transfrom that rotate by 30deg is like rotating by 30deg - * in the opposite direction. - * This util is used to add objects inside transformed groups or nested groups. - * @memberOf fabric.util - * @param {fabric.Object} object the object you want to transform - * @param {Array} transform the destination transform - */ - removeTransformFromObject: function(object, transform) { - var inverted = fabric.util.invertTransform(transform), - finalTransform = fabric.util.multiplyTransformMatrices(inverted, object.calcOwnMatrix()); - fabric.util.applyTransformToObject(object, finalTransform); - }, - - /** - * given an object and a transform, apply the transform to the object. - * this is equivalent to change the space where the object is drawn. - * Adding to an object a transform that scale by 2 is like scaling it by 2. - * This is used when removing an object from an active selection for example. - * @memberOf fabric.util - * @param {fabric.Object} object the object you want to transform - * @param {Array} transform the destination transform - */ - addTransformToObject: function(object, transform) { - fabric.util.applyTransformToObject( - object, - fabric.util.multiplyTransformMatrices(transform, object.calcOwnMatrix()) - ); - }, - - /** - * discard an object transform state and apply the one from the matrix. - * @memberOf fabric.util - * @param {fabric.Object} object the object you want to transform - * @param {Array} transform the destination transform - */ - applyTransformToObject: function(object, transform) { - var options = fabric.util.qrDecompose(transform), - center = new fabric.Point(options.translateX, options.translateY); - object.flipX = false; - object.flipY = false; - object.set('scaleX', options.scaleX); - object.set('scaleY', options.scaleY); - object.skewX = options.skewX; - object.skewY = options.skewY; - object.angle = options.angle; - object.setPositionByOrigin(center, 'center', 'center'); - }, - - /** - * given a width and height, return the size of the bounding box - * that can contains the box with width/height with applied transform - * described in options. - * Use to calculate the boxes around objects for controls. - * @memberOf fabric.util - * @param {Number} width - * @param {Number} height - * @param {Object} options - * @param {Number} options.scaleX - * @param {Number} options.scaleY - * @param {Number} options.skewX - * @param {Number} options.skewY - * @return {Object.x} width of containing - * @return {Object.y} height of containing - */ - sizeAfterTransform: function(width, height, options) { - var dimX = width / 2, dimY = height / 2, - points = [ - { - x: -dimX, - y: -dimY - }, - { - x: dimX, - y: -dimY - }, - { - x: -dimX, - y: dimY - }, - { - x: dimX, - y: dimY - }], - transformMatrix = fabric.util.calcDimensionsMatrix(options), - bbox = fabric.util.makeBoundingBoxFromPoints(points, transformMatrix); - return { - x: bbox.width, - y: bbox.height, - }; - } - }; -})(typeof exports !== 'undefined' ? exports : this); - - -(function() { - var _join = Array.prototype.join, - commandLengths = { - m: 2, - l: 2, - h: 1, - v: 1, - c: 6, - s: 4, - q: 4, - t: 2, - a: 7 - }, - repeatedCommands = { - m: 'l', - M: 'L' - }; - function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) { - var costh2 = fabric.util.cos(th2), - sinth2 = fabric.util.sin(th2), - costh3 = fabric.util.cos(th3), - sinth3 = fabric.util.sin(th3), - toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1, - toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1, - cp1X = fromX + mT * ( -cosTh * rx * sinth2 - sinTh * ry * costh2), - cp1Y = fromY + mT * ( -sinTh * rx * sinth2 + cosTh * ry * costh2), - cp2X = toX + mT * ( cosTh * rx * sinth3 + sinTh * ry * costh3), - cp2Y = toY + mT * ( sinTh * rx * sinth3 - cosTh * ry * costh3); - - return ['C', - cp1X, cp1Y, - cp2X, cp2Y, - toX, toY - ]; - } - - /* Adapted from http://dxr.mozilla.org/mozilla-central/source/content/svg/content/src/nsSVGPathDataParser.cpp - * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here - * http://mozilla.org/MPL/2.0/ - */ - function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) { - var PI = Math.PI, th = rotateX * PI / 180, - sinTh = fabric.util.sin(th), - cosTh = fabric.util.cos(th), - fromX = 0, fromY = 0; - - rx = Math.abs(rx); - ry = Math.abs(ry); - - var px = -cosTh * toX * 0.5 - sinTh * toY * 0.5, - py = -cosTh * toY * 0.5 + sinTh * toX * 0.5, - rx2 = rx * rx, ry2 = ry * ry, py2 = py * py, px2 = px * px, - pl = rx2 * ry2 - rx2 * py2 - ry2 * px2, - root = 0; - - if (pl < 0) { - var s = Math.sqrt(1 - pl / (rx2 * ry2)); - rx *= s; - ry *= s; - } - else { - root = (large === sweep ? -1.0 : 1.0) * - Math.sqrt( pl / (rx2 * py2 + ry2 * px2)); - } - - var cx = root * rx * py / ry, - cy = -root * ry * px / rx, - cx1 = cosTh * cx - sinTh * cy + toX * 0.5, - cy1 = sinTh * cx + cosTh * cy + toY * 0.5, - mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry), - dtheta = calcVectorAngle((px - cx) / rx, (py - cy) / ry, (-px - cx) / rx, (-py - cy) / ry); - - if (sweep === 0 && dtheta > 0) { - dtheta -= 2 * PI; - } - else if (sweep === 1 && dtheta < 0) { - dtheta += 2 * PI; - } - - // Convert into cubic bezier segments <= 90deg - var segments = Math.ceil(Math.abs(dtheta / PI * 2)), - result = [], mDelta = dtheta / segments, - mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2), - th3 = mTheta + mDelta; - - for (var i = 0; i < segments; i++) { - result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY); - fromX = result[i][5]; - fromY = result[i][6]; - mTheta = th3; - th3 += mDelta; - } - return result; - } - - /* - * Private - */ - function calcVectorAngle(ux, uy, vx, vy) { - var ta = Math.atan2(uy, ux), - tb = Math.atan2(vy, vx); - if (tb >= ta) { - return tb - ta; - } - else { - return 2 * Math.PI - (ta - tb); - } - } - - /** - * Calculate bounding box of a beziercurve - * @param {Number} x0 starting point - * @param {Number} y0 - * @param {Number} x1 first control point - * @param {Number} y1 - * @param {Number} x2 secondo control point - * @param {Number} y2 - * @param {Number} x3 end of bezier - * @param {Number} y3 - */ - // taken from http://jsbin.com/ivomiq/56/edit no credits available for that. - // TODO: can we normalize this with the starting points set at 0 and then translated the bbox? - function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) { - var argsString; - if (fabric.cachesBoundsOfCurve) { - argsString = _join.call(arguments); - if (fabric.boundsOfCurveCache[argsString]) { - return fabric.boundsOfCurveCache[argsString]; - } - } - - var sqrt = Math.sqrt, - min = Math.min, max = Math.max, - abs = Math.abs, tvalues = [], - bounds = [[], []], - a, b, c, t, t1, t2, b2ac, sqrtb2ac; - - b = 6 * x0 - 12 * x1 + 6 * x2; - a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3; - c = 3 * x1 - 3 * x0; - - for (var i = 0; i < 2; ++i) { - if (i > 0) { - b = 6 * y0 - 12 * y1 + 6 * y2; - a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3; - c = 3 * y1 - 3 * y0; - } - - if (abs(a) < 1e-12) { - if (abs(b) < 1e-12) { - continue; - } - t = -c / b; - if (0 < t && t < 1) { - tvalues.push(t); - } - continue; - } - b2ac = b * b - 4 * c * a; - if (b2ac < 0) { - continue; - } - sqrtb2ac = sqrt(b2ac); - t1 = (-b + sqrtb2ac) / (2 * a); - if (0 < t1 && t1 < 1) { - tvalues.push(t1); - } - t2 = (-b - sqrtb2ac) / (2 * a); - if (0 < t2 && t2 < 1) { - tvalues.push(t2); - } - } - - var x, y, j = tvalues.length, jlen = j, mt; - while (j--) { - t = tvalues[j]; - mt = 1 - t; - x = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3); - bounds[0][j] = x; - - y = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3); - bounds[1][j] = y; - } - - bounds[0][jlen] = x0; - bounds[1][jlen] = y0; - bounds[0][jlen + 1] = x3; - bounds[1][jlen + 1] = y3; - var result = [ - { - x: min.apply(null, bounds[0]), - y: min.apply(null, bounds[1]) - }, - { - x: max.apply(null, bounds[0]), - y: max.apply(null, bounds[1]) - } - ]; - if (fabric.cachesBoundsOfCurve) { - fabric.boundsOfCurveCache[argsString] = result; - } - return result; - } - - /** - * Converts arc to a bunch of bezier curves - * @param {Number} fx starting point x - * @param {Number} fy starting point y - * @param {Array} coords Arc command - */ - function fromArcToBeziers(fx, fy, coords) { - var rx = coords[1], - ry = coords[2], - rot = coords[3], - large = coords[4], - sweep = coords[5], - tx = coords[6], - ty = coords[7], - segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot); - - for (var i = 0, len = segsNorm.length; i < len; i++) { - segsNorm[i][1] += fx; - segsNorm[i][2] += fy; - segsNorm[i][3] += fx; - segsNorm[i][4] += fy; - segsNorm[i][5] += fx; - segsNorm[i][6] += fy; - } - return segsNorm; - }; - - /** - * This function take a parsed SVG path and make it simpler for fabricJS logic. - * simplification consist of: only UPPERCASE absolute commands ( relative converted to absolute ) - * S converted in C, T converted in Q, A converted in C. - * @param {Array} path the array of commands of a parsed svg path for fabric.Path - * @return {Array} the simplified array of commands of a parsed svg path for fabric.Path - */ - function makePathSimpler(path) { - // x and y represent the last point of the path. the previous command point. - // we add them to each relative command to make it an absolute comment. - // we also swap the v V h H with L, because are easier to transform. - var x = 0, y = 0, len = path.length, - // x1 and y1 represent the last point of the subpath. the subpath is started with - // m or M command. When a z or Z command is drawn, x and y need to be resetted to - // the last x1 and y1. - x1 = 0, y1 = 0, current, i, converted, - // previous will host the letter of the previous command, to handle S and T. - // controlX and controlY will host the previous reflected control point - destinationPath = [], previous, controlX, controlY; - for (i = 0; i < len; ++i) { - converted = false; - current = path[i].slice(0); - switch (current[0]) { // first letter - case 'l': // lineto, relative - current[0] = 'L'; - current[1] += x; - current[2] += y; - // falls through - case 'L': - x = current[1]; - y = current[2]; - break; - case 'h': // horizontal lineto, relative - current[1] += x; - // falls through - case 'H': - current[0] = 'L'; - current[2] = y; - x = current[1]; - break; - case 'v': // vertical lineto, relative - current[1] += y; - // falls through - case 'V': - current[0] = 'L'; - y = current[1]; - current[1] = x; - current[2] = y; - break; - case 'm': // moveTo, relative - current[0] = 'M'; - current[1] += x; - current[2] += y; - // falls through - case 'M': - x = current[1]; - y = current[2]; - x1 = current[1]; - y1 = current[2]; - break; - case 'c': // bezierCurveTo, relative - current[0] = 'C'; - current[1] += x; - current[2] += y; - current[3] += x; - current[4] += y; - current[5] += x; - current[6] += y; - // falls through - case 'C': - controlX = current[3]; - controlY = current[4]; - x = current[5]; - y = current[6]; - break; - case 's': // shorthand cubic bezierCurveTo, relative - current[0] = 'S'; - current[1] += x; - current[2] += y; - current[3] += x; - current[4] += y; - // falls through - case 'S': - // would be sScC but since we are swapping sSc for C, we check just that. - if (previous === 'C') { - // calculate reflection of previous control points - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - else { - // If there is no previous command or if the previous command was not a C, c, S, or s, - // the control point is coincident with the current point - controlX = x; - controlY = y; - } - x = current[3]; - y = current[4]; - current[0] = 'C'; - current[5] = current[3]; - current[6] = current[4]; - current[3] = current[1]; - current[4] = current[2]; - current[1] = controlX; - current[2] = controlY; - // current[3] and current[4] are NOW the second control point. - // we keep it for the next reflection. - controlX = current[3]; - controlY = current[4]; - break; - case 'q': // quadraticCurveTo, relative - current[0] = 'Q'; - current[1] += x; - current[2] += y; - current[3] += x; - current[4] += y; - // falls through - case 'Q': - controlX = current[1]; - controlY = current[2]; - x = current[3]; - y = current[4]; - break; - case 't': // shorthand quadraticCurveTo, relative - current[0] = 'T'; - current[1] += x; - current[2] += y; - // falls through - case 'T': - if (previous === 'Q') { - // calculate reflection of previous control point - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - else { - // If there is no previous command or if the previous command was not a Q, q, T or t, - // assume the control point is coincident with the current point - controlX = x; - controlY = y; - } - current[0] = 'Q'; - x = current[1]; - y = current[2]; - current[1] = controlX; - current[2] = controlY; - current[3] = x; - current[4] = y; - break; - case 'a': - current[0] = 'A'; - current[6] += x; - current[7] += y; - // falls through - case 'A': - converted = true; - destinationPath = destinationPath.concat(fromArcToBeziers(x, y, current)); - x = current[6]; - y = current[7]; - break; - case 'z': - case 'Z': - x = x1; - y = y1; - break; - default: - } - if (!converted) { - destinationPath.push(current); - } - previous = current[0]; - } - return destinationPath; - }; - - /** - * Calc length from point x1,y1 to x2,y2 - * @param {Number} x1 starting point x - * @param {Number} y1 starting point y - * @param {Number} x2 starting point x - * @param {Number} y2 starting point y - * @return {Number} length of segment - */ - function calcLineLength(x1, y1, x2, y2) { - return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); - } - - // functions for the Cubic beizer - // taken from: https://github.com/konvajs/konva/blob/7.0.5/src/shapes/Path.ts#L350 - function CB1(t) { - return t * t * t; - } - function CB2(t) { - return 3 * t * t * (1 - t); - } - function CB3(t) { - return 3 * t * (1 - t) * (1 - t); - } - function CB4(t) { - return (1 - t) * (1 - t) * (1 - t); - } - - function getPointOnCubicBezierIterator(p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) { - return function(pct) { - var c1 = CB1(pct), c2 = CB2(pct), c3 = CB3(pct), c4 = CB4(pct); - return { - x: p4x * c1 + p3x * c2 + p2x * c3 + p1x * c4, - y: p4y * c1 + p3y * c2 + p2y * c3 + p1y * c4 - }; - }; - } - - function getTangentCubicIterator(p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) { - return function (pct) { - var invT = 1 - pct, - tangentX = (3 * invT * invT * (p2x - p1x)) + (6 * invT * pct * (p3x - p2x)) + - (3 * pct * pct * (p4x - p3x)), - tangentY = (3 * invT * invT * (p2y - p1y)) + (6 * invT * pct * (p3y - p2y)) + - (3 * pct * pct * (p4y - p3y)); - return Math.atan2(tangentY, tangentX); - }; - } - - function QB1(t) { - return t * t; - } - - function QB2(t) { - return 2 * t * (1 - t); - } - - function QB3(t) { - return (1 - t) * (1 - t); - } - - function getPointOnQuadraticBezierIterator(p1x, p1y, p2x, p2y, p3x, p3y) { - return function(pct) { - var c1 = QB1(pct), c2 = QB2(pct), c3 = QB3(pct); - return { - x: p3x * c1 + p2x * c2 + p1x * c3, - y: p3y * c1 + p2y * c2 + p1y * c3 - }; - }; - } - - function getTangentQuadraticIterator(p1x, p1y, p2x, p2y, p3x, p3y) { - return function (pct) { - var invT = 1 - pct, - tangentX = (2 * invT * (p2x - p1x)) + (2 * pct * (p3x - p2x)), - tangentY = (2 * invT * (p2y - p1y)) + (2 * pct * (p3y - p2y)); - return Math.atan2(tangentY, tangentX); - }; - } - - - // this will run over a path segment ( a cubic or quadratic segment) and approximate it - // with 100 segemnts. This will good enough to calculate the length of the curve - function pathIterator(iterator, x1, y1) { - var tempP = { x: x1, y: y1 }, p, tmpLen = 0, perc; - for (perc = 1; perc <= 100; perc += 1) { - p = iterator(perc / 100); - tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y); - tempP = p; - } - return tmpLen; - } - - /** - * Given a pathInfo, and a distance in pixels, find the percentage from 0 to 1 - * that correspond to that pixels run over the path. - * The percentage will be then used to find the correct point on the canvas for the path. - * @param {Array} segInfo fabricJS collection of information on a parsed path - * @param {Number} distance from starting point, in pixels. - * @return {Object} info object with x and y ( the point on canvas ) and angle, the tangent on that point; - */ - function findPercentageForDistance(segInfo, distance) { - var perc = 0, tmpLen = 0, iterator = segInfo.iterator, tempP = { x: segInfo.x, y: segInfo.y }, - p, nextLen, nextStep = 0.01, angleFinder = segInfo.angleFinder, lastPerc; - // nextStep > 0.0001 covers 0.00015625 that 1/64th of 1/100 - // the path - while (tmpLen < distance && perc <= 1 && nextStep > 0.0001) { - p = iterator(perc); - lastPerc = perc; - nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y); - // compare tmpLen each cycle with distance, decide next perc to test. - if ((nextLen + tmpLen) > distance) { - // we discard this step and we make smaller steps. - nextStep /= 2; - perc -= nextStep; - } - else { - tempP = p; - perc += nextStep; - tmpLen += nextLen; - } - } - p.angle = angleFinder(lastPerc); - return p; - } - - /** - * Run over a parsed and simplifed path and extrac some informations. - * informations are length of each command and starting point - * @param {Array} path fabricJS parsed path commands - * @return {Array} path commands informations - */ - function getPathSegmentsInfo(path) { - var totalLength = 0, len = path.length, current, - //x2 and y2 are the coords of segment start - //x1 and y1 are the coords of the current point - x1 = 0, y1 = 0, x2 = 0, y2 = 0, info = [], iterator, tempInfo, angleFinder; - for (var i = 0; i < len; i++) { - current = path[i]; - tempInfo = { - x: x1, - y: y1, - command: current[0], - }; - switch (current[0]) { //first letter - case 'M': - tempInfo.length = 0; - x2 = x1 = current[1]; - y2 = y1 = current[2]; - break; - case 'L': - tempInfo.length = calcLineLength(x1, y1, current[1], current[2]); - x1 = current[1]; - y1 = current[2]; - break; - case 'C': - iterator = getPointOnCubicBezierIterator( - x1, - y1, - current[1], - current[2], - current[3], - current[4], - current[5], - current[6] - ); - angleFinder = getTangentCubicIterator( - x1, - y1, - current[1], - current[2], - current[3], - current[4], - current[5], - current[6] - ); - tempInfo.iterator = iterator; - tempInfo.angleFinder = angleFinder; - tempInfo.length = pathIterator(iterator, x1, y1); - x1 = current[5]; - y1 = current[6]; - break; - case 'Q': - iterator = getPointOnQuadraticBezierIterator( - x1, - y1, - current[1], - current[2], - current[3], - current[4] - ); - angleFinder = getTangentQuadraticIterator( - x1, - y1, - current[1], - current[2], - current[3], - current[4] - ); - tempInfo.iterator = iterator; - tempInfo.angleFinder = angleFinder; - tempInfo.length = pathIterator(iterator, x1, y1); - x1 = current[3]; - y1 = current[4]; - break; - case 'Z': - case 'z': - // we add those in order to ease calculations later - tempInfo.destX = x2; - tempInfo.destY = y2; - tempInfo.length = calcLineLength(x1, y1, x2, y2); - x1 = x2; - y1 = y2; - break; - } - totalLength += tempInfo.length; - info.push(tempInfo); - } - info.push({ length: totalLength, x: x1, y: y1 }); - return info; - } - - function getPointOnPath(path, distance, infos) { - if (!infos) { - infos = getPathSegmentsInfo(path); - } - var i = 0; - while ((distance - infos[i].length > 0) && i < (infos.length - 2)) { - distance -= infos[i].length; - i++; - } - // var distance = infos[infos.length - 1] * perc; - var segInfo = infos[i], segPercent = distance / segInfo.length, - command = segInfo.command, segment = path[i], info; - - switch (command) { - case 'M': - return { x: segInfo.x, y: segInfo.y, angle: 0 }; - case 'Z': - case 'z': - info = new fabric.Point(segInfo.x, segInfo.y).lerp( - new fabric.Point(segInfo.destX, segInfo.destY), - segPercent - ); - info.angle = Math.atan2(segInfo.destY - segInfo.y, segInfo.destX - segInfo.x); - return info; - case 'L': - info = new fabric.Point(segInfo.x, segInfo.y).lerp( - new fabric.Point(segment[1], segment[2]), - segPercent - ); - info.angle = Math.atan2(segment[2] - segInfo.y, segment[1] - segInfo.x); - return info; - case 'C': - return findPercentageForDistance(segInfo, distance); - case 'Q': - return findPercentageForDistance(segInfo, distance); - } - } - - /** - * - * @param {string} pathString - * @return {(string|number)[][]} An array of SVG path commands - * @example Usage - * parsePath('M 3 4 Q 3 5 2 1 4 0 Q 9 12 2 1 4 0') === [ - * ['M', 3, 4], - * ['Q', 3, 5, 2, 1, 4, 0], - * ['Q', 9, 12, 2, 1, 4, 0], - * ]; - * - */ - function parsePath(pathString) { - var result = [], - coords = [], - currentPath, - parsed, - re = fabric.rePathCommand, - rNumber = '[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?\\s*', - rNumberCommaWsp = '(' + rNumber + ')' + fabric.commaWsp, - rFlagCommaWsp = '([01])' + fabric.commaWsp + '?', - rArcSeq = rNumberCommaWsp + '?' + rNumberCommaWsp + '?' + rNumberCommaWsp + rFlagCommaWsp + rFlagCommaWsp + - rNumberCommaWsp + '?(' + rNumber + ')', - regArcArgumentSequence = new RegExp(rArcSeq, 'g'), - match, - coordsStr, - // one of commands (m,M,l,L,q,Q,c,C,etc.) followed by non-command characters (i.e. command values) - path; - if (!pathString || !pathString.match) { - return result; - } - path = pathString.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi); - - for (var i = 0, coordsParsed, len = path.length; i < len; i++) { - currentPath = path[i]; - - coordsStr = currentPath.slice(1).trim(); - coords.length = 0; - - var command = currentPath.charAt(0); - coordsParsed = [command]; - - if (command.toLowerCase() === 'a') { - // arcs have special flags that apparently don't require spaces so handle special - for (var args; (args = regArcArgumentSequence.exec(coordsStr));) { - for (var j = 1; j < args.length; j++) { - coords.push(args[j]); - } - } - } - else { - while ((match = re.exec(coordsStr))) { - coords.push(match[0]); - } - } - - for (var j = 0, jlen = coords.length; j < jlen; j++) { - parsed = parseFloat(coords[j]); - if (!isNaN(parsed)) { - coordsParsed.push(parsed); - } - } - - var commandLength = commandLengths[command.toLowerCase()], - repeatedCommand = repeatedCommands[command] || command; - - if (coordsParsed.length - 1 > commandLength) { - for (var k = 1, klen = coordsParsed.length; k < klen; k += commandLength) { - result.push([command].concat(coordsParsed.slice(k, k + commandLength))); - command = repeatedCommand; - } - } - else { - result.push(coordsParsed); - } - } - - return result; - }; - - /** - * - * Converts points to a smooth SVG path - * @param {{ x: number,y: number }[]} points Array of points - * @param {number} [correction] Apply a correction to the path (usually we use `width / 1000`). If value is undefined 0 is used as the correction value. - * @return {(string|number)[][]} An array of SVG path commands - */ - function getSmoothPathFromPoints(points, correction) { - var path = [], i, - p1 = new fabric.Point(points[0].x, points[0].y), - p2 = new fabric.Point(points[1].x, points[1].y), - len = points.length, multSignX = 1, multSignY = 0, manyPoints = len > 2; - correction = correction || 0; - - if (manyPoints) { - multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1; - multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1; - } - path.push(['M', p1.x - multSignX * correction, p1.y - multSignY * correction]); - for (i = 1; i < len; i++) { - if (!p1.eq(p2)) { - var midPoint = p1.midPointFrom(p2); - // p1 is our bezier control point - // midpoint is our endpoint - // start point is p(i-1) value. - path.push(['Q', p1.x, p1.y, midPoint.x, midPoint.y]); - } - p1 = points[i]; - if ((i + 1) < points.length) { - p2 = points[i + 1]; - } - } - if (manyPoints) { - multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1; - multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1; - } - path.push(['L', p1.x + multSignX * correction, p1.y + multSignY * correction]); - return path; - } - /** - * Transform a path by transforming each segment. - * it has to be a simplified path or it won't work. - * WARNING: this depends from pathOffset for correct operation - * @param {Array} path fabricJS parsed and simplified path commands - * @param {Array} transform matrix that represent the transformation - * @param {Object} [pathOffset] the fabric.Path pathOffset - * @param {Number} pathOffset.x - * @param {Number} pathOffset.y - * @returns {Array} the transformed path - */ - function transformPath(path, transform, pathOffset) { - if (pathOffset) { - transform = fabric.util.multiplyTransformMatrices( - transform, - [1, 0, 0, 1, -pathOffset.x, -pathOffset.y] - ); - } - return path.map(function(pathSegment) { - var newSegment = pathSegment.slice(0), point = {}; - for (var i = 1; i < pathSegment.length - 1; i += 2) { - point.x = pathSegment[i]; - point.y = pathSegment[i + 1]; - point = fabric.util.transformPoint(point, transform); - newSegment[i] = point.x; - newSegment[i + 1] = point.y; - } - return newSegment; - }); - } - - /** - * Calculate bounding box of a elliptic-arc - * @deprecated - * @param {Number} fx start point of arc - * @param {Number} fy - * @param {Number} rx horizontal radius - * @param {Number} ry vertical radius - * @param {Number} rot angle of horizontal axis - * @param {Number} large 1 or 0, whatever the arc is the big or the small on the 2 points - * @param {Number} sweep 1 or 0, 1 clockwise or counterclockwise direction - * @param {Number} tx end point of arc - * @param {Number} ty - */ - function getBoundsOfArc(fx, fy, rx, ry, rot, large, sweep, tx, ty) { - - var fromX = 0, fromY = 0, bound, bounds = [], - segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot); - - for (var i = 0, len = segs.length; i < len; i++) { - bound = getBoundsOfCurve(fromX, fromY, segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5], segs[i][6]); - bounds.push({ x: bound[0].x + fx, y: bound[0].y + fy }); - bounds.push({ x: bound[1].x + fx, y: bound[1].y + fy }); - fromX = segs[i][5]; - fromY = segs[i][6]; - } - return bounds; - }; - - /** - * Draws arc - * @deprecated - * @param {CanvasRenderingContext2D} ctx - * @param {Number} fx - * @param {Number} fy - * @param {Array} coords coords of the arc, without the front 'A/a' - */ - function drawArc(ctx, fx, fy, coords) { - coords = coords.slice(0).unshift('X'); // command A or a does not matter - var beziers = fromArcToBeziers(fx, fy, coords); - beziers.forEach(function(bezier) { - ctx.bezierCurveTo.apply(ctx, bezier.slice(1)); - }); - }; - - /** - * Join path commands to go back to svg format - * @param {Array} pathData fabricJS parsed path commands - * @return {String} joined path 'M 0 0 L 20 30' - */ - fabric.util.joinPath = function(pathData) { - return pathData.map(function (segment) { return segment.join(' '); }).join(' '); - }; - fabric.util.parsePath = parsePath; - fabric.util.makePathSimpler = makePathSimpler; - fabric.util.getSmoothPathFromPoints = getSmoothPathFromPoints; - fabric.util.getPathSegmentsInfo = getPathSegmentsInfo; - fabric.util.getBoundsOfCurve = getBoundsOfCurve; - fabric.util.getPointOnPath = getPointOnPath; - fabric.util.transformPath = transformPath; - /** - * Typo of `fromArcToBeziers` kept for not breaking the api once corrected. - * Will be removed in fabric 5.0 - * @deprecated - */ - fabric.util.fromArcToBeizers = fromArcToBeziers; - // kept because we do not want to make breaking changes. - // but useless and deprecated. - fabric.util.getBoundsOfArc = getBoundsOfArc; - fabric.util.drawArc = drawArc; -})(); - - -(function() { - - var slice = Array.prototype.slice; - - /** - * Invokes method on all items in a given array - * @memberOf fabric.util.array - * @param {Array} array Array to iterate over - * @param {String} method Name of a method to invoke - * @return {Array} - */ - function invoke(array, method) { - var args = slice.call(arguments, 2), result = []; - for (var i = 0, len = array.length; i < len; i++) { - result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]); - } - return result; - } - - /** - * Finds maximum value in array (not necessarily "first" one) - * @memberOf fabric.util.array - * @param {Array} array Array to iterate over - * @param {String} byProperty - * @return {*} - */ - function max(array, byProperty) { - return find(array, byProperty, function(value1, value2) { - return value1 >= value2; - }); - } - - /** - * Finds minimum value in array (not necessarily "first" one) - * @memberOf fabric.util.array - * @param {Array} array Array to iterate over - * @param {String} byProperty - * @return {*} - */ - function min(array, byProperty) { - return find(array, byProperty, function(value1, value2) { - return value1 < value2; - }); - } - - /** - * @private - */ - function fill(array, value) { - var k = array.length; - while (k--) { - array[k] = value; - } - return array; - } - - /** - * @private - */ - function find(array, byProperty, condition) { - if (!array || array.length === 0) { - return; - } - - var i = array.length - 1, - result = byProperty ? array[i][byProperty] : array[i]; - if (byProperty) { - while (i--) { - if (condition(array[i][byProperty], result)) { - result = array[i][byProperty]; - } - } - } - else { - while (i--) { - if (condition(array[i], result)) { - result = array[i]; - } - } - } - return result; - } - - /** - * @namespace fabric.util.array - */ - fabric.util.array = { - fill: fill, - invoke: invoke, - min: min, - max: max - }; - -})(); - - -(function() { - /** - * Copies all enumerable properties of one js object to another - * this does not and cannot compete with generic utils. - * Does not clone or extend fabric.Object subclasses. - * This is mostly for internal use and has extra handling for fabricJS objects - * it skips the canvas and group properties in deep cloning. - * @memberOf fabric.util.object - * @param {Object} destination Where to copy to - * @param {Object} source Where to copy from - * @param {Boolean} [deep] Whether to extend nested objects - * @return {Object} - */ - - function extend(destination, source, deep) { - // JScript DontEnum bug is not taken care of - // the deep clone is for internal use, is not meant to avoid - // javascript traps or cloning html element or self referenced objects. - if (deep) { - if (!fabric.isLikelyNode && source instanceof Element) { - // avoid cloning deep images, canvases, - destination = source; - } - else if (source instanceof Array) { - destination = []; - for (var i = 0, len = source.length; i < len; i++) { - destination[i] = extend({ }, source[i], deep); - } - } - else if (source && typeof source === 'object') { - for (var property in source) { - if (property === 'canvas' || property === 'group') { - // we do not want to clone this props at all. - // we want to keep the keys in the copy - destination[property] = null; - } - else if (source.hasOwnProperty(property)) { - destination[property] = extend({ }, source[property], deep); - } - } - } - else { - // this sounds odd for an extend but is ok for recursive use - destination = source; - } - } - else { - for (var property in source) { - destination[property] = source[property]; - } - } - return destination; - } - - /** - * Creates an empty object and copies all enumerable properties of another object to it - * This method is mostly for internal use, and not intended for duplicating shapes in canvas. - * @memberOf fabric.util.object - * @param {Object} object Object to clone - * @param {Boolean} [deep] Whether to clone nested objects - * @return {Object} - */ - - //TODO: this function return an empty object if you try to clone null - function clone(object, deep) { - return extend({ }, object, deep); - } - - /** @namespace fabric.util.object */ - fabric.util.object = { - extend: extend, - clone: clone - }; - fabric.util.object.extend(fabric.util, fabric.Observable); -})(); - - -(function() { - - /** - * Camelizes a string - * @memberOf fabric.util.string - * @param {String} string String to camelize - * @return {String} Camelized version of a string - */ - function camelize(string) { - return string.replace(/-+(.)?/g, function(match, character) { - return character ? character.toUpperCase() : ''; - }); - } - - /** - * Capitalizes a string - * @memberOf fabric.util.string - * @param {String} string String to capitalize - * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized - * and other letters stay untouched, if false first letter is capitalized - * and other letters are converted to lowercase. - * @return {String} Capitalized version of a string - */ - function capitalize(string, firstLetterOnly) { - return string.charAt(0).toUpperCase() + - (firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase()); - } - - /** - * Escapes XML in a string - * @memberOf fabric.util.string - * @param {String} string String to escape - * @return {String} Escaped version of a string - */ - function escapeXml(string) { - return string.replace(/&/g, '&') - .replace(/"/g, '"') - .replace(/'/g, ''') - .replace(//g, '>'); - } - - /** - * Divide a string in the user perceived single units - * @memberOf fabric.util.string - * @param {String} textstring String to escape - * @return {Array} array containing the graphemes - */ - function graphemeSplit(textstring) { - var i = 0, chr, graphemes = []; - for (i = 0, chr; i < textstring.length; i++) { - if ((chr = getWholeChar(textstring, i)) === false) { - continue; - } - graphemes.push(chr); - } - return graphemes; - } - - // taken from mdn in the charAt doc page. - function getWholeChar(str, i) { - var code = str.charCodeAt(i); - - if (isNaN(code)) { - return ''; // Position not found - } - if (code < 0xD800 || code > 0xDFFF) { - return str.charAt(i); - } - - // High surrogate (could change last hex to 0xDB7F to treat high private - // surrogates as single characters) - if (0xD800 <= code && code <= 0xDBFF) { - if (str.length <= (i + 1)) { - throw 'High surrogate without following low surrogate'; - } - var next = str.charCodeAt(i + 1); - if (0xDC00 > next || next > 0xDFFF) { - throw 'High surrogate without following low surrogate'; - } - return str.charAt(i) + str.charAt(i + 1); - } - // Low surrogate (0xDC00 <= code && code <= 0xDFFF) - if (i === 0) { - throw 'Low surrogate without preceding high surrogate'; - } - var prev = str.charCodeAt(i - 1); - - // (could change last hex to 0xDB7F to treat high private - // surrogates as single characters) - if (0xD800 > prev || prev > 0xDBFF) { - throw 'Low surrogate without preceding high surrogate'; - } - // We can pass over low surrogates now as the second component - // in a pair which we have already processed - return false; - } - - - /** - * String utilities - * @namespace fabric.util.string - */ - fabric.util.string = { - camelize: camelize, - capitalize: capitalize, - escapeXml: escapeXml, - graphemeSplit: graphemeSplit - }; -})(); - - -(function() { - - var slice = Array.prototype.slice, emptyFunction = function() { }, - - IS_DONTENUM_BUGGY = (function() { - for (var p in { toString: 1 }) { - if (p === 'toString') { - return false; - } - } - return true; - })(), - - /** @ignore */ - addMethods = function(klass, source, parent) { - for (var property in source) { - - if (property in klass.prototype && - typeof klass.prototype[property] === 'function' && - (source[property] + '').indexOf('callSuper') > -1) { - - klass.prototype[property] = (function(property) { - return function() { - - var superclass = this.constructor.superclass; - this.constructor.superclass = parent; - var returnValue = source[property].apply(this, arguments); - this.constructor.superclass = superclass; - - if (property !== 'initialize') { - return returnValue; - } - }; - })(property); - } - else { - klass.prototype[property] = source[property]; - } - - if (IS_DONTENUM_BUGGY) { - if (source.toString !== Object.prototype.toString) { - klass.prototype.toString = source.toString; - } - if (source.valueOf !== Object.prototype.valueOf) { - klass.prototype.valueOf = source.valueOf; - } - } - } - }; - - function Subclass() { } - - function callSuper(methodName) { - var parentMethod = null, - _this = this; - - // climb prototype chain to find method not equal to callee's method - while (_this.constructor.superclass) { - var superClassMethod = _this.constructor.superclass.prototype[methodName]; - if (_this[methodName] !== superClassMethod) { - parentMethod = superClassMethod; - break; - } - // eslint-disable-next-line - _this = _this.constructor.superclass.prototype; - } - - if (!parentMethod) { - return console.log('tried to callSuper ' + methodName + ', method not found in prototype chain', this); - } - - return (arguments.length > 1) - ? parentMethod.apply(this, slice.call(arguments, 1)) - : parentMethod.call(this); - } - - /** - * Helper for creation of "classes". - * @memberOf fabric.util - * @param {Function} [parent] optional "Class" to inherit from - * @param {Object} [properties] Properties shared by all instances of this class - * (be careful modifying objects defined here as this would affect all instances) - */ - function createClass() { - var parent = null, - properties = slice.call(arguments, 0); - - if (typeof properties[0] === 'function') { - parent = properties.shift(); - } - function klass() { - this.initialize.apply(this, arguments); - } - - klass.superclass = parent; - klass.subclasses = []; - - if (parent) { - Subclass.prototype = parent.prototype; - klass.prototype = new Subclass(); - parent.subclasses.push(klass); - } - for (var i = 0, length = properties.length; i < length; i++) { - addMethods(klass, properties[i], parent); - } - if (!klass.prototype.initialize) { - klass.prototype.initialize = emptyFunction; - } - klass.prototype.constructor = klass; - klass.prototype.callSuper = callSuper; - return klass; - } - - fabric.util.createClass = createClass; -})(); - - -(function () { - // since ie11 can use addEventListener but they do not support options, i need to check - var couldUseAttachEvent = !!fabric.document.createElement('div').attachEvent, - touchEvents = ['touchstart', 'touchmove', 'touchend']; - /** - * Adds an event listener to an element - * @function - * @memberOf fabric.util - * @param {HTMLElement} element - * @param {String} eventName - * @param {Function} handler - */ - fabric.util.addListener = function(element, eventName, handler, options) { - element && element.addEventListener(eventName, handler, couldUseAttachEvent ? false : options); - }; - - /** - * Removes an event listener from an element - * @function - * @memberOf fabric.util - * @param {HTMLElement} element - * @param {String} eventName - * @param {Function} handler - */ - fabric.util.removeListener = function(element, eventName, handler, options) { - element && element.removeEventListener(eventName, handler, couldUseAttachEvent ? false : options); - }; - - function getTouchInfo(event) { - var touchProp = event.changedTouches; - if (touchProp && touchProp[0]) { - return touchProp[0]; - } - return event; - } - - fabric.util.getPointer = function(event) { - var element = event.target, - scroll = fabric.util.getScrollLeftTop(element), - _evt = getTouchInfo(event); - return { - x: _evt.clientX + scroll.left, - y: _evt.clientY + scroll.top - }; - }; - - fabric.util.isTouchEvent = function(event) { - return touchEvents.indexOf(event.type) > -1 || event.pointerType === 'touch'; - }; -})(); - - -(function () { - - /** - * Cross-browser wrapper for setting element's style - * @memberOf fabric.util - * @param {HTMLElement} element - * @param {Object} styles - * @return {HTMLElement} Element that was passed as a first argument - */ - function setStyle(element, styles) { - var elementStyle = element.style; - if (!elementStyle) { - return element; - } - if (typeof styles === 'string') { - element.style.cssText += ';' + styles; - return styles.indexOf('opacity') > -1 - ? setOpacity(element, styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) - : element; - } - for (var property in styles) { - if (property === 'opacity') { - setOpacity(element, styles[property]); - } - else { - var normalizedProperty = (property === 'float' || property === 'cssFloat') - ? (typeof elementStyle.styleFloat === 'undefined' ? 'cssFloat' : 'styleFloat') - : property; - elementStyle[normalizedProperty] = styles[property]; - } - } - return element; - } - - var parseEl = fabric.document.createElement('div'), - supportsOpacity = typeof parseEl.style.opacity === 'string', - supportsFilters = typeof parseEl.style.filter === 'string', - reOpacity = /alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/, - - /** @ignore */ - setOpacity = function (element) { return element; }; - - if (supportsOpacity) { - /** @ignore */ - setOpacity = function(element, value) { - element.style.opacity = value; - return element; - }; - } - else if (supportsFilters) { - /** @ignore */ - setOpacity = function(element, value) { - var es = element.style; - if (element.currentStyle && !element.currentStyle.hasLayout) { - es.zoom = 1; - } - if (reOpacity.test(es.filter)) { - value = value >= 0.9999 ? '' : ('alpha(opacity=' + (value * 100) + ')'); - es.filter = es.filter.replace(reOpacity, value); - } - else { - es.filter += ' alpha(opacity=' + (value * 100) + ')'; - } - return element; - }; - } - - fabric.util.setStyle = setStyle; - -})(); - - -(function() { - - var _slice = Array.prototype.slice; - - /** - * Takes id and returns an element with that id (if one exists in a document) - * @memberOf fabric.util - * @param {String|HTMLElement} id - * @return {HTMLElement|null} - */ - function getById(id) { - return typeof id === 'string' ? fabric.document.getElementById(id) : id; - } - - var sliceCanConvertNodelists, - /** - * Converts an array-like object (e.g. arguments or NodeList) to an array - * @memberOf fabric.util - * @param {Object} arrayLike - * @return {Array} - */ - toArray = function(arrayLike) { - return _slice.call(arrayLike, 0); - }; - - try { - sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array; - } - catch (err) { } - - if (!sliceCanConvertNodelists) { - toArray = function(arrayLike) { - var arr = new Array(arrayLike.length), i = arrayLike.length; - while (i--) { - arr[i] = arrayLike[i]; - } - return arr; - }; - } - - /** - * Creates specified element with specified attributes - * @memberOf fabric.util - * @param {String} tagName Type of an element to create - * @param {Object} [attributes] Attributes to set on an element - * @return {HTMLElement} Newly created element - */ - function makeElement(tagName, attributes) { - var el = fabric.document.createElement(tagName); - for (var prop in attributes) { - if (prop === 'class') { - el.className = attributes[prop]; - } - else if (prop === 'for') { - el.htmlFor = attributes[prop]; - } - else { - el.setAttribute(prop, attributes[prop]); - } - } - return el; - } - - /** - * Adds class to an element - * @memberOf fabric.util - * @param {HTMLElement} element Element to add class to - * @param {String} className Class to add to an element - */ - function addClass(element, className) { - if (element && (' ' + element.className + ' ').indexOf(' ' + className + ' ') === -1) { - element.className += (element.className ? ' ' : '') + className; - } - } - - /** - * Wraps element with another element - * @memberOf fabric.util - * @param {HTMLElement} element Element to wrap - * @param {HTMLElement|String} wrapper Element to wrap with - * @param {Object} [attributes] Attributes to set on a wrapper - * @return {HTMLElement} wrapper - */ - function wrapElement(element, wrapper, attributes) { - if (typeof wrapper === 'string') { - wrapper = makeElement(wrapper, attributes); - } - if (element.parentNode) { - element.parentNode.replaceChild(wrapper, element); - } - wrapper.appendChild(element); - return wrapper; - } - - /** - * Returns element scroll offsets - * @memberOf fabric.util - * @param {HTMLElement} element Element to operate on - * @return {Object} Object with left/top values - */ - function getScrollLeftTop(element) { - - var left = 0, - top = 0, - docElement = fabric.document.documentElement, - body = fabric.document.body || { - scrollLeft: 0, scrollTop: 0 - }; - - // While loop checks (and then sets element to) .parentNode OR .host - // to account for ShadowDOM. We still want to traverse up out of ShadowDOM, - // but the .parentNode of a root ShadowDOM node will always be null, instead - // it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938 - while (element && (element.parentNode || element.host)) { - - // Set element to element parent, or 'host' in case of ShadowDOM - element = element.parentNode || element.host; - - if (element === fabric.document) { - left = body.scrollLeft || docElement.scrollLeft || 0; - top = body.scrollTop || docElement.scrollTop || 0; - } - else { - left += element.scrollLeft || 0; - top += element.scrollTop || 0; - } - - if (element.nodeType === 1 && element.style.position === 'fixed') { - break; - } - } - - return { left: left, top: top }; - } - - /** - * Returns offset for a given element - * @function - * @memberOf fabric.util - * @param {HTMLElement} element Element to get offset for - * @return {Object} Object with "left" and "top" properties - */ - function getElementOffset(element) { - var docElem, - doc = element && element.ownerDocument, - box = { left: 0, top: 0 }, - offset = { left: 0, top: 0 }, - scrollLeftTop, - offsetAttributes = { - borderLeftWidth: 'left', - borderTopWidth: 'top', - paddingLeft: 'left', - paddingTop: 'top' - }; - - if (!doc) { - return offset; - } - - for (var attr in offsetAttributes) { - offset[offsetAttributes[attr]] += parseInt(getElementStyle(element, attr), 10) || 0; - } - - docElem = doc.documentElement; - if ( typeof element.getBoundingClientRect !== 'undefined' ) { - box = element.getBoundingClientRect(); - } - - scrollLeftTop = getScrollLeftTop(element); - - return { - left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left, - top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top - }; - } - - /** - * Returns style attribute value of a given element - * @memberOf fabric.util - * @param {HTMLElement} element Element to get style attribute for - * @param {String} attr Style attribute to get for element - * @return {String} Style attribute value of the given element. - */ - var getElementStyle; - if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) { - getElementStyle = function(element, attr) { - var style = fabric.document.defaultView.getComputedStyle(element, null); - return style ? style[attr] : undefined; - }; - } - else { - getElementStyle = function(element, attr) { - var value = element.style[attr]; - if (!value && element.currentStyle) { - value = element.currentStyle[attr]; - } - return value; - }; - } - - (function () { - var style = fabric.document.documentElement.style, - selectProp = 'userSelect' in style - ? 'userSelect' - : 'MozUserSelect' in style - ? 'MozUserSelect' - : 'WebkitUserSelect' in style - ? 'WebkitUserSelect' - : 'KhtmlUserSelect' in style - ? 'KhtmlUserSelect' - : ''; - - /** - * Makes element unselectable - * @memberOf fabric.util - * @param {HTMLElement} element Element to make unselectable - * @return {HTMLElement} Element that was passed in - */ - function makeElementUnselectable(element) { - if (typeof element.onselectstart !== 'undefined') { - element.onselectstart = fabric.util.falseFunction; - } - if (selectProp) { - element.style[selectProp] = 'none'; - } - else if (typeof element.unselectable === 'string') { - element.unselectable = 'on'; - } - return element; - } - - /** - * Makes element selectable - * @memberOf fabric.util - * @param {HTMLElement} element Element to make selectable - * @return {HTMLElement} Element that was passed in - */ - function makeElementSelectable(element) { - if (typeof element.onselectstart !== 'undefined') { - element.onselectstart = null; - } - if (selectProp) { - element.style[selectProp] = ''; - } - else if (typeof element.unselectable === 'string') { - element.unselectable = ''; - } - return element; - } - - fabric.util.makeElementUnselectable = makeElementUnselectable; - fabric.util.makeElementSelectable = makeElementSelectable; - })(); - - function getNodeCanvas(element) { - var impl = fabric.jsdomImplForWrapper(element); - return impl._canvas || impl._image; - }; - - function cleanUpJsdomNode(element) { - if (!fabric.isLikelyNode) { - return; - } - var impl = fabric.jsdomImplForWrapper(element); - if (impl) { - impl._image = null; - impl._canvas = null; - // unsure if necessary - impl._currentSrc = null; - impl._attributes = null; - impl._classList = null; - } - } - - function setImageSmoothing(ctx, value) { - ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled || ctx.webkitImageSmoothingEnabled - || ctx.mozImageSmoothingEnabled || ctx.msImageSmoothingEnabled || ctx.oImageSmoothingEnabled; - ctx.imageSmoothingEnabled = value; - } - - /** - * setImageSmoothing sets the context imageSmoothingEnabled property. - * Used by canvas and by ImageObject. - * @memberOf fabric.util - * @since 4.0.0 - * @param {HTMLRenderingContext2D} ctx to set on - * @param {Boolean} value true or false - */ - fabric.util.setImageSmoothing = setImageSmoothing; - fabric.util.getById = getById; - fabric.util.toArray = toArray; - fabric.util.addClass = addClass; - fabric.util.makeElement = makeElement; - fabric.util.wrapElement = wrapElement; - fabric.util.getScrollLeftTop = getScrollLeftTop; - fabric.util.getElementOffset = getElementOffset; - fabric.util.getNodeCanvas = getNodeCanvas; - fabric.util.cleanUpJsdomNode = cleanUpJsdomNode; - -})(); - - -(function() { - - function addParamToUrl(url, param) { - return url + (/\?/.test(url) ? '&' : '?') + param; - } - - function emptyFn() { } - - /** - * Cross-browser abstraction for sending XMLHttpRequest - * @memberOf fabric.util - * @param {String} url URL to send XMLHttpRequest to - * @param {Object} [options] Options object - * @param {String} [options.method="GET"] - * @param {String} [options.parameters] parameters to append to url in GET or in body - * @param {String} [options.body] body to send with POST or PUT request - * @param {Function} options.onComplete Callback to invoke when request is completed - * @return {XMLHttpRequest} request - */ - function request(url, options) { - options || (options = { }); - - var method = options.method ? options.method.toUpperCase() : 'GET', - onComplete = options.onComplete || function() { }, - xhr = new fabric.window.XMLHttpRequest(), - body = options.body || options.parameters; - - /** @ignore */ - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - onComplete(xhr); - xhr.onreadystatechange = emptyFn; - } - }; - - if (method === 'GET') { - body = null; - if (typeof options.parameters === 'string') { - url = addParamToUrl(url, options.parameters); - } - } - - xhr.open(method, url, true); - - if (method === 'POST' || method === 'PUT') { - xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); - } - - xhr.send(body); - return xhr; - } - - fabric.util.request = request; -})(); - - -/** - * Wrapper around `console.log` (when available) - * @param {*} [values] Values to log - */ -fabric.log = console.log; - -/** - * Wrapper around `console.warn` (when available) - * @param {*} [values] Values to log as a warning - */ -fabric.warn = console.warn; - - -(function() { - - function noop() { - return false; - } - - function defaultEasing(t, b, c, d) { - return -c * Math.cos(t / d * (Math.PI / 2)) + c + b; - } - - /** - * Changes value from one to another within certain period of time, invoking callbacks as value is being changed. - * @memberOf fabric.util - * @param {Object} [options] Animation options - * @param {Function} [options.onChange] Callback; invoked on every value change - * @param {Function} [options.onComplete] Callback; invoked when value change is completed - * @param {Number} [options.startValue=0] Starting value - * @param {Number} [options.endValue=100] Ending value - * @param {Number} [options.byValue=100] Value to modify the property by - * @param {Function} [options.easing] Easing function - * @param {Number} [options.duration=500] Duration of change (in ms) - * @param {Function} [options.abort] Additional function with logic. If returns true, onComplete is called. - * @returns {Function} abort function - */ - function animate(options) { - var cancel = false; - requestAnimFrame(function(timestamp) { - options || (options = { }); - - var start = timestamp || +new Date(), - duration = options.duration || 500, - finish = start + duration, time, - onChange = options.onChange || noop, - abort = options.abort || noop, - onComplete = options.onComplete || noop, - easing = options.easing || defaultEasing, - startValue = 'startValue' in options ? options.startValue : 0, - endValue = 'endValue' in options ? options.endValue : 100, - byValue = options.byValue || endValue - startValue; - - options.onStart && options.onStart(); - - (function tick(ticktime) { - // TODO: move abort call after calculation - // and pass (current,valuePerc, timePerc) as arguments - time = ticktime || +new Date(); - var currentTime = time > finish ? duration : (time - start), - timePerc = currentTime / duration, - current = easing(currentTime, startValue, byValue, duration), - valuePerc = Math.abs((current - startValue) / byValue); - if (cancel) { - return; - } - if (abort(current, valuePerc, timePerc)) { - // remove this in 4.0 - // does to even make sense to abort and run onComplete? - onComplete(endValue, 1, 1); - return; - } - if (time > finish) { - onChange(endValue, 1, 1); - onComplete(endValue, 1, 1); - return; - } - else { - onChange(current, valuePerc, timePerc); - requestAnimFrame(tick); - } - })(start); - }); - return function() { - cancel = true; - }; - } - - var _requestAnimFrame = fabric.window.requestAnimationFrame || - fabric.window.webkitRequestAnimationFrame || - fabric.window.mozRequestAnimationFrame || - fabric.window.oRequestAnimationFrame || - fabric.window.msRequestAnimationFrame || - function(callback) { - return fabric.window.setTimeout(callback, 1000 / 60); - }; - - var _cancelAnimFrame = fabric.window.cancelAnimationFrame || fabric.window.clearTimeout; - - /** - * requestAnimationFrame polyfill based on http://paulirish.com/2011/requestanimationframe-for-smart-animating/ - * In order to get a precise start time, `requestAnimFrame` should be called as an entry into the method - * @memberOf fabric.util - * @param {Function} callback Callback to invoke - * @param {DOMElement} element optional Element to associate with animation - */ - function requestAnimFrame() { - return _requestAnimFrame.apply(fabric.window, arguments); - } - - function cancelAnimFrame() { - return _cancelAnimFrame.apply(fabric.window, arguments); - } - - fabric.util.animate = animate; - fabric.util.requestAnimFrame = requestAnimFrame; - fabric.util.cancelAnimFrame = cancelAnimFrame; -})(); - - -(function() { - // Calculate an in-between color. Returns a "rgba()" string. - // Credit: Edwin Martin - // http://www.bitstorm.org/jquery/color-animation/jquery.animate-colors.js - function calculateColor(begin, end, pos) { - var color = 'rgba(' - + parseInt((begin[0] + pos * (end[0] - begin[0])), 10) + ',' - + parseInt((begin[1] + pos * (end[1] - begin[1])), 10) + ',' - + parseInt((begin[2] + pos * (end[2] - begin[2])), 10); - - color += ',' + (begin && end ? parseFloat(begin[3] + pos * (end[3] - begin[3])) : 1); - color += ')'; - return color; - } - - /** - * Changes the color from one to another within certain period of time, invoking callbacks as value is being changed. - * @memberOf fabric.util - * @param {String} fromColor The starting color in hex or rgb(a) format. - * @param {String} toColor The starting color in hex or rgb(a) format. - * @param {Number} [duration] Duration of change (in ms). - * @param {Object} [options] Animation options - * @param {Function} [options.onChange] Callback; invoked on every value change - * @param {Function} [options.onComplete] Callback; invoked when value change is completed - * @param {Function} [options.colorEasing] Easing function. Note that this function only take two arguments (currentTime, duration). Thus the regular animation easing functions cannot be used. - * @param {Function} [options.abort] Additional function with logic. If returns true, onComplete is called. - * @returns {Function} abort function - */ - function animateColor(fromColor, toColor, duration, options) { - var startColor = new fabric.Color(fromColor).getSource(), - endColor = new fabric.Color(toColor).getSource(), - originalOnComplete = options.onComplete, - originalOnChange = options.onChange; - options = options || {}; - - return fabric.util.animate(fabric.util.object.extend(options, { - duration: duration || 500, - startValue: startColor, - endValue: endColor, - byValue: endColor, - easing: function (currentTime, startValue, byValue, duration) { - var posValue = options.colorEasing - ? options.colorEasing(currentTime, duration) - : 1 - Math.cos(currentTime / duration * (Math.PI / 2)); - return calculateColor(startValue, byValue, posValue); - }, - // has to take in account for color restoring; - onComplete: function(current, valuePerc, timePerc) { - if (originalOnComplete) { - return originalOnComplete( - calculateColor(endColor, endColor, 0), - valuePerc, - timePerc - ); - } - }, - onChange: function(current, valuePerc, timePerc) { - if (originalOnChange) { - if (Array.isArray(current)) { - return originalOnChange( - calculateColor(current, current, 0), - valuePerc, - timePerc - ); - } - originalOnChange(current, valuePerc, timePerc); - } - } - })); - } - - fabric.util.animateColor = animateColor; - -})(); - - -(function() { - - function normalize(a, c, p, s) { - if (a < Math.abs(c)) { - a = c; - s = p / 4; - } - else { - //handle the 0/0 case: - if (c === 0 && a === 0) { - s = p / (2 * Math.PI) * Math.asin(1); - } - else { - s = p / (2 * Math.PI) * Math.asin(c / a); - } - } - return { a: a, c: c, p: p, s: s }; - } - - function elastic(opts, t, d) { - return opts.a * - Math.pow(2, 10 * (t -= 1)) * - Math.sin( (t * d - opts.s) * (2 * Math.PI) / opts.p ); - } - - /** - * Cubic easing out - * @memberOf fabric.util.ease - */ - function easeOutCubic(t, b, c, d) { - return c * ((t = t / d - 1) * t * t + 1) + b; - } - - /** - * Cubic easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutCubic(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return c / 2 * t * t * t + b; - } - return c / 2 * ((t -= 2) * t * t + 2) + b; - } - - /** - * Quartic easing in - * @memberOf fabric.util.ease - */ - function easeInQuart(t, b, c, d) { - return c * (t /= d) * t * t * t + b; - } - - /** - * Quartic easing out - * @memberOf fabric.util.ease - */ - function easeOutQuart(t, b, c, d) { - return -c * ((t = t / d - 1) * t * t * t - 1) + b; - } - - /** - * Quartic easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutQuart(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return c / 2 * t * t * t * t + b; - } - return -c / 2 * ((t -= 2) * t * t * t - 2) + b; - } - - /** - * Quintic easing in - * @memberOf fabric.util.ease - */ - function easeInQuint(t, b, c, d) { - return c * (t /= d) * t * t * t * t + b; - } - - /** - * Quintic easing out - * @memberOf fabric.util.ease - */ - function easeOutQuint(t, b, c, d) { - return c * ((t = t / d - 1) * t * t * t * t + 1) + b; - } - - /** - * Quintic easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutQuint(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return c / 2 * t * t * t * t * t + b; - } - return c / 2 * ((t -= 2) * t * t * t * t + 2) + b; - } - - /** - * Sinusoidal easing in - * @memberOf fabric.util.ease - */ - function easeInSine(t, b, c, d) { - return -c * Math.cos(t / d * (Math.PI / 2)) + c + b; - } - - /** - * Sinusoidal easing out - * @memberOf fabric.util.ease - */ - function easeOutSine(t, b, c, d) { - return c * Math.sin(t / d * (Math.PI / 2)) + b; - } - - /** - * Sinusoidal easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutSine(t, b, c, d) { - return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b; - } - - /** - * Exponential easing in - * @memberOf fabric.util.ease - */ - function easeInExpo(t, b, c, d) { - return (t === 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b; - } - - /** - * Exponential easing out - * @memberOf fabric.util.ease - */ - function easeOutExpo(t, b, c, d) { - return (t === d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b; - } - - /** - * Exponential easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutExpo(t, b, c, d) { - if (t === 0) { - return b; - } - if (t === d) { - return b + c; - } - t /= d / 2; - if (t < 1) { - return c / 2 * Math.pow(2, 10 * (t - 1)) + b; - } - return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b; - } - - /** - * Circular easing in - * @memberOf fabric.util.ease - */ - function easeInCirc(t, b, c, d) { - return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b; - } - - /** - * Circular easing out - * @memberOf fabric.util.ease - */ - function easeOutCirc(t, b, c, d) { - return c * Math.sqrt(1 - (t = t / d - 1) * t) + b; - } - - /** - * Circular easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutCirc(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b; - } - return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b; - } - - /** - * Elastic easing in - * @memberOf fabric.util.ease - */ - function easeInElastic(t, b, c, d) { - var s = 1.70158, p = 0, a = c; - if (t === 0) { - return b; - } - t /= d; - if (t === 1) { - return b + c; - } - if (!p) { - p = d * 0.3; - } - var opts = normalize(a, c, p, s); - return -elastic(opts, t, d) + b; - } - - /** - * Elastic easing out - * @memberOf fabric.util.ease - */ - function easeOutElastic(t, b, c, d) { - var s = 1.70158, p = 0, a = c; - if (t === 0) { - return b; - } - t /= d; - if (t === 1) { - return b + c; - } - if (!p) { - p = d * 0.3; - } - var opts = normalize(a, c, p, s); - return opts.a * Math.pow(2, -10 * t) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) + opts.c + b; - } - - /** - * Elastic easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutElastic(t, b, c, d) { - var s = 1.70158, p = 0, a = c; - if (t === 0) { - return b; - } - t /= d / 2; - if (t === 2) { - return b + c; - } - if (!p) { - p = d * (0.3 * 1.5); - } - var opts = normalize(a, c, p, s); - if (t < 1) { - return -0.5 * elastic(opts, t, d) + b; - } - return opts.a * Math.pow(2, -10 * (t -= 1)) * - Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) * 0.5 + opts.c + b; - } - - /** - * Backwards easing in - * @memberOf fabric.util.ease - */ - function easeInBack(t, b, c, d, s) { - if (s === undefined) { - s = 1.70158; - } - return c * (t /= d) * t * ((s + 1) * t - s) + b; - } - - /** - * Backwards easing out - * @memberOf fabric.util.ease - */ - function easeOutBack(t, b, c, d, s) { - if (s === undefined) { - s = 1.70158; - } - return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; - } - - /** - * Backwards easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutBack(t, b, c, d, s) { - if (s === undefined) { - s = 1.70158; - } - t /= d / 2; - if (t < 1) { - return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b; - } - return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b; - } - - /** - * Bouncing easing in - * @memberOf fabric.util.ease - */ - function easeInBounce(t, b, c, d) { - return c - easeOutBounce (d - t, 0, c, d) + b; - } - - /** - * Bouncing easing out - * @memberOf fabric.util.ease - */ - function easeOutBounce(t, b, c, d) { - if ((t /= d) < (1 / 2.75)) { - return c * (7.5625 * t * t) + b; - } - else if (t < (2 / 2.75)) { - return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b; - } - else if (t < (2.5 / 2.75)) { - return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b; - } - else { - return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b; - } - } - - /** - * Bouncing easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutBounce(t, b, c, d) { - if (t < d / 2) { - return easeInBounce (t * 2, 0, c, d) * 0.5 + b; - } - return easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b; - } - - /** - * Easing functions - * See Easing Equations by Robert Penner - * @namespace fabric.util.ease - */ - fabric.util.ease = { - - /** - * Quadratic easing in - * @memberOf fabric.util.ease - */ - easeInQuad: function(t, b, c, d) { - return c * (t /= d) * t + b; - }, - - /** - * Quadratic easing out - * @memberOf fabric.util.ease - */ - easeOutQuad: function(t, b, c, d) { - return -c * (t /= d) * (t - 2) + b; - }, - - /** - * Quadratic easing in and out - * @memberOf fabric.util.ease - */ - easeInOutQuad: function(t, b, c, d) { - t /= (d / 2); - if (t < 1) { - return c / 2 * t * t + b; - } - return -c / 2 * ((--t) * (t - 2) - 1) + b; - }, - - /** - * Cubic easing in - * @memberOf fabric.util.ease - */ - easeInCubic: function(t, b, c, d) { - return c * (t /= d) * t * t + b; - }, - - easeOutCubic: easeOutCubic, - easeInOutCubic: easeInOutCubic, - easeInQuart: easeInQuart, - easeOutQuart: easeOutQuart, - easeInOutQuart: easeInOutQuart, - easeInQuint: easeInQuint, - easeOutQuint: easeOutQuint, - easeInOutQuint: easeInOutQuint, - easeInSine: easeInSine, - easeOutSine: easeOutSine, - easeInOutSine: easeInOutSine, - easeInExpo: easeInExpo, - easeOutExpo: easeOutExpo, - easeInOutExpo: easeInOutExpo, - easeInCirc: easeInCirc, - easeOutCirc: easeOutCirc, - easeInOutCirc: easeInOutCirc, - easeInElastic: easeInElastic, - easeOutElastic: easeOutElastic, - easeInOutElastic: easeInOutElastic, - easeInBack: easeInBack, - easeOutBack: easeOutBack, - easeInOutBack: easeInOutBack, - easeInBounce: easeInBounce, - easeOutBounce: easeOutBounce, - easeInOutBounce: easeInOutBounce - }; - -})(); - - -(function(global) { - - 'use strict'; - - /** - * @name fabric - * @namespace - */ - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - clone = fabric.util.object.clone, - toFixed = fabric.util.toFixed, - parseUnit = fabric.util.parseUnit, - multiplyTransformMatrices = fabric.util.multiplyTransformMatrices, - - svgValidTagNames = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line', - 'image', 'text'], - svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'], - svgInvalidAncestors = ['pattern', 'defs', 'symbol', 'metadata', 'clipPath', 'mask', 'desc'], - svgValidParents = ['symbol', 'g', 'a', 'svg', 'clipPath', 'defs'], - - attributesMap = { - cx: 'left', - x: 'left', - r: 'radius', - cy: 'top', - y: 'top', - display: 'visible', - visibility: 'visible', - transform: 'transformMatrix', - 'fill-opacity': 'fillOpacity', - 'fill-rule': 'fillRule', - 'font-family': 'fontFamily', - 'font-size': 'fontSize', - 'font-style': 'fontStyle', - 'font-weight': 'fontWeight', - 'letter-spacing': 'charSpacing', - 'paint-order': 'paintFirst', - 'stroke-dasharray': 'strokeDashArray', - 'stroke-dashoffset': 'strokeDashOffset', - 'stroke-linecap': 'strokeLineCap', - 'stroke-linejoin': 'strokeLineJoin', - 'stroke-miterlimit': 'strokeMiterLimit', - 'stroke-opacity': 'strokeOpacity', - 'stroke-width': 'strokeWidth', - 'text-decoration': 'textDecoration', - 'text-anchor': 'textAnchor', - opacity: 'opacity', - 'clip-path': 'clipPath', - 'clip-rule': 'clipRule', - 'vector-effect': 'strokeUniform', - 'image-rendering': 'imageSmoothing', - }, - - colorAttributes = { - stroke: 'strokeOpacity', - fill: 'fillOpacity' - }, - - fSize = 'font-size', cPath = 'clip-path'; - - fabric.svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames); - fabric.svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements); - fabric.svgInvalidAncestorsRegEx = getSvgRegex(svgInvalidAncestors); - fabric.svgValidParentsRegEx = getSvgRegex(svgValidParents); - - fabric.cssRules = { }; - fabric.gradientDefs = { }; - fabric.clipPaths = { }; - - function normalizeAttr(attr) { - // transform attribute names - if (attr in attributesMap) { - return attributesMap[attr]; - } - return attr; - } - - function normalizeValue(attr, value, parentAttributes, fontSize) { - var isArray = Object.prototype.toString.call(value) === '[object Array]', - parsed; - - if ((attr === 'fill' || attr === 'stroke') && value === 'none') { - value = ''; - } - else if (attr === 'strokeUniform') { - return (value === 'non-scaling-stroke'); - } - else if (attr === 'strokeDashArray') { - if (value === 'none') { - value = null; - } - else { - value = value.replace(/,/g, ' ').split(/\s+/).map(parseFloat); - } - } - else if (attr === 'transformMatrix') { - if (parentAttributes && parentAttributes.transformMatrix) { - value = multiplyTransformMatrices( - parentAttributes.transformMatrix, fabric.parseTransformAttribute(value)); - } - else { - value = fabric.parseTransformAttribute(value); - } - } - else if (attr === 'visible') { - value = value !== 'none' && value !== 'hidden'; - // display=none on parent element always takes precedence over child element - if (parentAttributes && parentAttributes.visible === false) { - value = false; - } - } - else if (attr === 'opacity') { - value = parseFloat(value); - if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') { - value *= parentAttributes.opacity; - } - } - else if (attr === 'textAnchor' /* text-anchor */) { - value = value === 'start' ? 'left' : value === 'end' ? 'right' : 'center'; - } - else if (attr === 'charSpacing') { - // parseUnit returns px and we convert it to em - parsed = parseUnit(value, fontSize) / fontSize * 1000; - } - else if (attr === 'paintFirst') { - var fillIndex = value.indexOf('fill'); - var strokeIndex = value.indexOf('stroke'); - var value = 'fill'; - if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) { - value = 'stroke'; - } - else if (fillIndex === -1 && strokeIndex > -1) { - value = 'stroke'; - } - } - else if (attr === 'href' || attr === 'xlink:href' || attr === 'font') { - return value; - } - else if (attr === 'imageSmoothing') { - return (value === 'optimizeQuality'); - } - else { - parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize); - } - - return (!isArray && isNaN(parsed) ? value : parsed); - } - - /** - * @private - */ - function getSvgRegex(arr) { - return new RegExp('^(' + arr.join('|') + ')\\b', 'i'); - } - - /** - * @private - * @param {Object} attributes Array of attributes to parse - */ - function _setStrokeFillOpacity(attributes) { - for (var attr in colorAttributes) { - - if (typeof attributes[colorAttributes[attr]] === 'undefined' || attributes[attr] === '') { - continue; - } - - if (typeof attributes[attr] === 'undefined') { - if (!fabric.Object.prototype[attr]) { - continue; - } - attributes[attr] = fabric.Object.prototype[attr]; - } - - if (attributes[attr].indexOf('url(') === 0) { - continue; - } - - var color = new fabric.Color(attributes[attr]); - attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttributes[attr]], 2)).toRgba(); - } - return attributes; - } - - /** - * @private - */ - function _getMultipleNodes(doc, nodeNames) { - var nodeName, nodeArray = [], nodeList, i, len; - for (i = 0, len = nodeNames.length; i < len; i++) { - nodeName = nodeNames[i]; - nodeList = doc.getElementsByTagName(nodeName); - nodeArray = nodeArray.concat(Array.prototype.slice.call(nodeList)); - } - return nodeArray; - } - - /** - * Parses "transform" attribute, returning an array of values - * @static - * @function - * @memberOf fabric - * @param {String} attributeValue String containing attribute value - * @return {Array} Array of 6 elements representing transformation matrix - */ - fabric.parseTransformAttribute = (function() { - function rotateMatrix(matrix, args) { - var cos = fabric.util.cos(args[0]), sin = fabric.util.sin(args[0]), - x = 0, y = 0; - if (args.length === 3) { - x = args[1]; - y = args[2]; - } - - matrix[0] = cos; - matrix[1] = sin; - matrix[2] = -sin; - matrix[3] = cos; - matrix[4] = x - (cos * x - sin * y); - matrix[5] = y - (sin * x + cos * y); - } - - function scaleMatrix(matrix, args) { - var multiplierX = args[0], - multiplierY = (args.length === 2) ? args[1] : args[0]; - - matrix[0] = multiplierX; - matrix[3] = multiplierY; - } - - function skewMatrix(matrix, args, pos) { - matrix[pos] = Math.tan(fabric.util.degreesToRadians(args[0])); - } - - function translateMatrix(matrix, args) { - matrix[4] = args[0]; - if (args.length === 2) { - matrix[5] = args[1]; - } - } - - // identity matrix - var iMatrix = fabric.iMatrix, - - // == begin transform regexp - number = fabric.reNum, - - commaWsp = fabric.commaWsp, - - skewX = '(?:(skewX)\\s*\\(\\s*(' + number + ')\\s*\\))', - - skewY = '(?:(skewY)\\s*\\(\\s*(' + number + ')\\s*\\))', - - rotate = '(?:(rotate)\\s*\\(\\s*(' + number + ')(?:' + - commaWsp + '(' + number + ')' + - commaWsp + '(' + number + '))?\\s*\\))', - - scale = '(?:(scale)\\s*\\(\\s*(' + number + ')(?:' + - commaWsp + '(' + number + '))?\\s*\\))', - - translate = '(?:(translate)\\s*\\(\\s*(' + number + ')(?:' + - commaWsp + '(' + number + '))?\\s*\\))', - - matrix = '(?:(matrix)\\s*\\(\\s*' + - '(' + number + ')' + commaWsp + - '(' + number + ')' + commaWsp + - '(' + number + ')' + commaWsp + - '(' + number + ')' + commaWsp + - '(' + number + ')' + commaWsp + - '(' + number + ')' + - '\\s*\\))', - - transform = '(?:' + - matrix + '|' + - translate + '|' + - scale + '|' + - rotate + '|' + - skewX + '|' + - skewY + - ')', - - transforms = '(?:' + transform + '(?:' + commaWsp + '*' + transform + ')*' + ')', - - transformList = '^\\s*(?:' + transforms + '?)\\s*$', - - // http://www.w3.org/TR/SVG/coords.html#TransformAttribute - reTransformList = new RegExp(transformList), - // == end transform regexp - - reTransform = new RegExp(transform, 'g'); - - return function(attributeValue) { - - // start with identity matrix - var matrix = iMatrix.concat(), - matrices = []; - - // return if no argument was given or - // an argument does not match transform attribute regexp - if (!attributeValue || (attributeValue && !reTransformList.test(attributeValue))) { - return matrix; - } - - attributeValue.replace(reTransform, function(match) { - - var m = new RegExp(transform).exec(match).filter(function (match) { - // match !== '' && match != null - return (!!match); - }), - operation = m[1], - args = m.slice(2).map(parseFloat); - - switch (operation) { - case 'translate': - translateMatrix(matrix, args); - break; - case 'rotate': - args[0] = fabric.util.degreesToRadians(args[0]); - rotateMatrix(matrix, args); - break; - case 'scale': - scaleMatrix(matrix, args); - break; - case 'skewX': - skewMatrix(matrix, args, 2); - break; - case 'skewY': - skewMatrix(matrix, args, 1); - break; - case 'matrix': - matrix = args; - break; - } - - // snapshot current matrix into matrices array - matrices.push(matrix.concat()); - // reset - matrix = iMatrix.concat(); - }); - - var combinedMatrix = matrices[0]; - while (matrices.length > 1) { - matrices.shift(); - combinedMatrix = fabric.util.multiplyTransformMatrices(combinedMatrix, matrices[0]); - } - return combinedMatrix; - }; - })(); - - /** - * @private - */ - function parseStyleString(style, oStyle) { - var attr, value; - style.replace(/;\s*$/, '').split(';').forEach(function (chunk) { - var pair = chunk.split(':'); - - attr = pair[0].trim().toLowerCase(); - value = pair[1].trim(); - - oStyle[attr] = value; - }); - } - - /** - * @private - */ - function parseStyleObject(style, oStyle) { - var attr, value; - for (var prop in style) { - if (typeof style[prop] === 'undefined') { - continue; - } - - attr = prop.toLowerCase(); - value = style[prop]; - - oStyle[attr] = value; - } - } - - /** - * @private - */ - function getGlobalStylesForElement(element, svgUid) { - var styles = { }; - for (var rule in fabric.cssRules[svgUid]) { - if (elementMatchesRule(element, rule.split(' '))) { - for (var property in fabric.cssRules[svgUid][rule]) { - styles[property] = fabric.cssRules[svgUid][rule][property]; - } - } - } - return styles; - } - - /** - * @private - */ - function elementMatchesRule(element, selectors) { - var firstMatching, parentMatching = true; - //start from rightmost selector. - firstMatching = selectorMatches(element, selectors.pop()); - if (firstMatching && selectors.length) { - parentMatching = doesSomeParentMatch(element, selectors); - } - return firstMatching && parentMatching && (selectors.length === 0); - } - - function doesSomeParentMatch(element, selectors) { - var selector, parentMatching = true; - while (element.parentNode && element.parentNode.nodeType === 1 && selectors.length) { - if (parentMatching) { - selector = selectors.pop(); - } - element = element.parentNode; - parentMatching = selectorMatches(element, selector); - } - return selectors.length === 0; - } - - /** - * @private - */ - function selectorMatches(element, selector) { - var nodeName = element.nodeName, - classNames = element.getAttribute('class'), - id = element.getAttribute('id'), matcher, i; - // i check if a selector matches slicing away part from it. - // if i get empty string i should match - matcher = new RegExp('^' + nodeName, 'i'); - selector = selector.replace(matcher, ''); - if (id && selector.length) { - matcher = new RegExp('#' + id + '(?![a-zA-Z\\-]+)', 'i'); - selector = selector.replace(matcher, ''); - } - if (classNames && selector.length) { - classNames = classNames.split(' '); - for (i = classNames.length; i--;) { - matcher = new RegExp('\\.' + classNames[i] + '(?![a-zA-Z\\-]+)', 'i'); - selector = selector.replace(matcher, ''); - } - } - return selector.length === 0; - } - - /** - * @private - * to support IE8 missing getElementById on SVGdocument and on node xmlDOM - */ - function elementById(doc, id) { - var el; - doc.getElementById && (el = doc.getElementById(id)); - if (el) { - return el; - } - var node, i, len, nodelist = doc.getElementsByTagName('*'); - for (i = 0, len = nodelist.length; i < len; i++) { - node = nodelist[i]; - if (id === node.getAttribute('id')) { - return node; - } - } - } - - /** - * @private - */ - function parseUseDirectives(doc) { - var nodelist = _getMultipleNodes(doc, ['use', 'svg:use']), i = 0; - while (nodelist.length && i < nodelist.length) { - var el = nodelist[i], - xlinkAttribute = el.getAttribute('xlink:href') || el.getAttribute('href'); - - if (xlinkAttribute === null) { - return; - } - - var xlink = xlinkAttribute.substr(1), - x = el.getAttribute('x') || 0, - y = el.getAttribute('y') || 0, - el2 = elementById(doc, xlink).cloneNode(true), - currentTrans = (el2.getAttribute('transform') || '') + ' translate(' + x + ', ' + y + ')', - parentNode, - oldLength = nodelist.length, attr, - j, - attrs, - len, - namespace = fabric.svgNS; - - applyViewboxTransform(el2); - if (/^svg$/i.test(el2.nodeName)) { - var el3 = el2.ownerDocument.createElementNS(namespace, 'g'); - for (j = 0, attrs = el2.attributes, len = attrs.length; j < len; j++) { - attr = attrs.item(j); - el3.setAttributeNS(namespace, attr.nodeName, attr.nodeValue); - } - // el2.firstChild != null - while (el2.firstChild) { - el3.appendChild(el2.firstChild); - } - el2 = el3; - } - - for (j = 0, attrs = el.attributes, len = attrs.length; j < len; j++) { - attr = attrs.item(j); - if (attr.nodeName === 'x' || attr.nodeName === 'y' || - attr.nodeName === 'xlink:href' || attr.nodeName === 'href') { - continue; - } - - if (attr.nodeName === 'transform') { - currentTrans = attr.nodeValue + ' ' + currentTrans; - } - else { - el2.setAttribute(attr.nodeName, attr.nodeValue); - } - } - - el2.setAttribute('transform', currentTrans); - el2.setAttribute('instantiated_by_use', '1'); - el2.removeAttribute('id'); - parentNode = el.parentNode; - parentNode.replaceChild(el2, el); - // some browsers do not shorten nodelist after replaceChild (IE8) - if (nodelist.length === oldLength) { - i++; - } - } - } - - // http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute - // matches, e.g.: +14.56e-12, etc. - var reViewBoxAttrValue = new RegExp( - '^' + - '\\s*(' + fabric.reNum + '+)\\s*,?' + - '\\s*(' + fabric.reNum + '+)\\s*,?' + - '\\s*(' + fabric.reNum + '+)\\s*,?' + - '\\s*(' + fabric.reNum + '+)\\s*' + - '$' - ); - - /** - * Add a element that envelop all child elements and makes the viewbox transformMatrix descend on all elements - */ - function applyViewboxTransform(element) { - if (!fabric.svgViewBoxElementsRegEx.test(element.nodeName)) { - return {}; - } - var viewBoxAttr = element.getAttribute('viewBox'), - scaleX = 1, - scaleY = 1, - minX = 0, - minY = 0, - viewBoxWidth, viewBoxHeight, matrix, el, - widthAttr = element.getAttribute('width'), - heightAttr = element.getAttribute('height'), - x = element.getAttribute('x') || 0, - y = element.getAttribute('y') || 0, - preserveAspectRatio = element.getAttribute('preserveAspectRatio') || '', - missingViewBox = (!viewBoxAttr || !(viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue))), - missingDimAttr = (!widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%'), - toBeParsed = missingViewBox && missingDimAttr, - parsedDim = { }, translateMatrix = '', widthDiff = 0, heightDiff = 0; - - parsedDim.width = 0; - parsedDim.height = 0; - parsedDim.toBeParsed = toBeParsed; - - if (missingViewBox) { - if (((x || y) && element.parentNode && element.parentNode.nodeName !== '#document')) { - translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') '; - matrix = (element.getAttribute('transform') || '') + translateMatrix; - element.setAttribute('transform', matrix); - element.removeAttribute('x'); - element.removeAttribute('y'); - } - } - - if (toBeParsed) { - return parsedDim; - } - - if (missingViewBox) { - parsedDim.width = parseUnit(widthAttr); - parsedDim.height = parseUnit(heightAttr); - // set a transform for elements that have x y and are inner(only) SVGs - return parsedDim; - } - minX = -parseFloat(viewBoxAttr[1]); - minY = -parseFloat(viewBoxAttr[2]); - viewBoxWidth = parseFloat(viewBoxAttr[3]); - viewBoxHeight = parseFloat(viewBoxAttr[4]); - parsedDim.minX = minX; - parsedDim.minY = minY; - parsedDim.viewBoxWidth = viewBoxWidth; - parsedDim.viewBoxHeight = viewBoxHeight; - if (!missingDimAttr) { - parsedDim.width = parseUnit(widthAttr); - parsedDim.height = parseUnit(heightAttr); - scaleX = parsedDim.width / viewBoxWidth; - scaleY = parsedDim.height / viewBoxHeight; - } - else { - parsedDim.width = viewBoxWidth; - parsedDim.height = viewBoxHeight; - } - - // default is to preserve aspect ratio - preserveAspectRatio = fabric.util.parsePreserveAspectRatioAttribute(preserveAspectRatio); - if (preserveAspectRatio.alignX !== 'none') { - //translate all container for the effect of Mid, Min, Max - if (preserveAspectRatio.meetOrSlice === 'meet') { - scaleY = scaleX = (scaleX > scaleY ? scaleY : scaleX); - // calculate additional translation to move the viewbox - } - if (preserveAspectRatio.meetOrSlice === 'slice') { - scaleY = scaleX = (scaleX > scaleY ? scaleX : scaleY); - // calculate additional translation to move the viewbox - } - widthDiff = parsedDim.width - viewBoxWidth * scaleX; - heightDiff = parsedDim.height - viewBoxHeight * scaleX; - if (preserveAspectRatio.alignX === 'Mid') { - widthDiff /= 2; - } - if (preserveAspectRatio.alignY === 'Mid') { - heightDiff /= 2; - } - if (preserveAspectRatio.alignX === 'Min') { - widthDiff = 0; - } - if (preserveAspectRatio.alignY === 'Min') { - heightDiff = 0; - } - } - - if (scaleX === 1 && scaleY === 1 && minX === 0 && minY === 0 && x === 0 && y === 0) { - return parsedDim; - } - if ((x || y) && element.parentNode.nodeName !== '#document') { - translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') '; - } - - matrix = translateMatrix + ' matrix(' + scaleX + - ' 0' + - ' 0 ' + - scaleY + ' ' + - (minX * scaleX + widthDiff) + ' ' + - (minY * scaleY + heightDiff) + ') '; - // seems unused. - // parsedDim.viewboxTransform = fabric.parseTransformAttribute(matrix); - if (element.nodeName === 'svg') { - el = element.ownerDocument.createElementNS(fabric.svgNS, 'g'); - // element.firstChild != null - while (element.firstChild) { - el.appendChild(element.firstChild); - } - element.appendChild(el); - } - else { - el = element; - el.removeAttribute('x'); - el.removeAttribute('y'); - matrix = el.getAttribute('transform') + matrix; - } - el.setAttribute('transform', matrix); - return parsedDim; - } - - function hasAncestorWithNodeName(element, nodeName) { - while (element && (element = element.parentNode)) { - if (element.nodeName && nodeName.test(element.nodeName.replace('svg:', '')) - && !element.getAttribute('instantiated_by_use')) { - return true; - } - } - return false; - } - - /** - * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback - * @static - * @function - * @memberOf fabric - * @param {SVGDocument} doc SVG document to parse - * @param {Function} callback Callback to call when parsing is finished; - * It's being passed an array of elements (parsed from a document). - * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created. - * @param {Object} [parsingOptions] options for parsing document - * @param {String} [parsingOptions.crossOrigin] crossOrigin settings - */ - fabric.parseSVGDocument = function(doc, callback, reviver, parsingOptions) { - if (!doc) { - return; - } - - parseUseDirectives(doc); - - var svgUid = fabric.Object.__uid++, i, len, - options = applyViewboxTransform(doc), - descendants = fabric.util.toArray(doc.getElementsByTagName('*')); - options.crossOrigin = parsingOptions && parsingOptions.crossOrigin; - options.svgUid = svgUid; - - if (descendants.length === 0 && fabric.isLikelyNode) { - // we're likely in node, where "o3-xml" library fails to gEBTN("*") - // https://github.com/ajaxorg/node-o3-xml/issues/21 - descendants = doc.selectNodes('//*[name(.)!="svg"]'); - var arr = []; - for (i = 0, len = descendants.length; i < len; i++) { - arr[i] = descendants[i]; - } - descendants = arr; - } - - var elements = descendants.filter(function(el) { - applyViewboxTransform(el); - return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', '')) && - !hasAncestorWithNodeName(el, fabric.svgInvalidAncestorsRegEx); // http://www.w3.org/TR/SVG/struct.html#DefsElement - }); - if (!elements || (elements && !elements.length)) { - callback && callback([], {}); - return; - } - var clipPaths = { }; - descendants.filter(function(el) { - return el.nodeName.replace('svg:', '') === 'clipPath'; - }).forEach(function(el) { - var id = el.getAttribute('id'); - clipPaths[id] = fabric.util.toArray(el.getElementsByTagName('*')).filter(function(el) { - return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', '')); - }); - }); - fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc); - fabric.cssRules[svgUid] = fabric.getCSSRules(doc); - fabric.clipPaths[svgUid] = clipPaths; - // Precedence of rules: style > class > attribute - fabric.parseElements(elements, function(instances, elements) { - if (callback) { - callback(instances, options, elements, descendants); - delete fabric.gradientDefs[svgUid]; - delete fabric.cssRules[svgUid]; - delete fabric.clipPaths[svgUid]; - } - }, clone(options), reviver, parsingOptions); - }; - - function recursivelyParseGradientsXlink(doc, gradient) { - var gradientsAttrs = ['gradientTransform', 'x1', 'x2', 'y1', 'y2', 'gradientUnits', 'cx', 'cy', 'r', 'fx', 'fy'], - xlinkAttr = 'xlink:href', - xLink = gradient.getAttribute(xlinkAttr).substr(1), - referencedGradient = elementById(doc, xLink); - if (referencedGradient && referencedGradient.getAttribute(xlinkAttr)) { - recursivelyParseGradientsXlink(doc, referencedGradient); - } - gradientsAttrs.forEach(function(attr) { - if (referencedGradient && !gradient.hasAttribute(attr) && referencedGradient.hasAttribute(attr)) { - gradient.setAttribute(attr, referencedGradient.getAttribute(attr)); - } - }); - if (!gradient.children.length) { - var referenceClone = referencedGradient.cloneNode(true); - while (referenceClone.firstChild) { - gradient.appendChild(referenceClone.firstChild); - } - } - gradient.removeAttribute(xlinkAttr); - } - - var reFontDeclaration = new RegExp( - '(normal|italic)?\\s*(normal|small-caps)?\\s*' + - '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*(' + - fabric.reNum + - '(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|' + fabric.reNum + '))?\\s+(.*)'); - - extend(fabric, { - /** - * Parses a short font declaration, building adding its properties to a style object - * @static - * @function - * @memberOf fabric - * @param {String} value font declaration - * @param {Object} oStyle definition - */ - parseFontDeclaration: function(value, oStyle) { - var match = value.match(reFontDeclaration); - - if (!match) { - return; - } - var fontStyle = match[1], - // font variant is not used - // fontVariant = match[2], - fontWeight = match[3], - fontSize = match[4], - lineHeight = match[5], - fontFamily = match[6]; - - if (fontStyle) { - oStyle.fontStyle = fontStyle; - } - if (fontWeight) { - oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight); - } - if (fontSize) { - oStyle.fontSize = parseUnit(fontSize); - } - if (fontFamily) { - oStyle.fontFamily = fontFamily; - } - if (lineHeight) { - oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight; - } - }, - - /** - * Parses an SVG document, returning all of the gradient declarations found in it - * @static - * @function - * @memberOf fabric - * @param {SVGDocument} doc SVG document to parse - * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element - */ - getGradientDefs: function(doc) { - var tagArray = [ - 'linearGradient', - 'radialGradient', - 'svg:linearGradient', - 'svg:radialGradient'], - elList = _getMultipleNodes(doc, tagArray), - el, j = 0, gradientDefs = { }; - j = elList.length; - while (j--) { - el = elList[j]; - if (el.getAttribute('xlink:href')) { - recursivelyParseGradientsXlink(doc, el); - } - gradientDefs[el.getAttribute('id')] = el; - } - return gradientDefs; - }, - - /** - * Returns an object of attributes' name/value, given element and an array of attribute names; - * Parses parent "g" nodes recursively upwards. - * @static - * @memberOf fabric - * @param {DOMElement} element Element to parse - * @param {Array} attributes Array of attributes to parse - * @return {Object} object containing parsed attributes' names/values - */ - parseAttributes: function(element, attributes, svgUid) { - - if (!element) { - return; - } - - var value, - parentAttributes = { }, - fontSize, parentFontSize; - - if (typeof svgUid === 'undefined') { - svgUid = element.getAttribute('svgUid'); - } - // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards - if (element.parentNode && fabric.svgValidParentsRegEx.test(element.parentNode.nodeName)) { - parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid); - } - - var ownAttributes = attributes.reduce(function(memo, attr) { - value = element.getAttribute(attr); - if (value) { // eslint-disable-line - memo[attr] = value; - } - return memo; - }, { }); - // add values parsed from style, which take precedence over attributes - // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes) - var cssAttrs = extend( - getGlobalStylesForElement(element, svgUid), - fabric.parseStyleAttribute(element) - ); - ownAttributes = extend( - ownAttributes, - cssAttrs - ); - if (cssAttrs[cPath]) { - element.setAttribute(cPath, cssAttrs[cPath]); - } - fontSize = parentFontSize = parentAttributes.fontSize || fabric.Text.DEFAULT_SVG_FONT_SIZE; - if (ownAttributes[fSize]) { - // looks like the minimum should be 9px when dealing with ems. this is what looks like in browsers. - ownAttributes[fSize] = fontSize = parseUnit(ownAttributes[fSize], parentFontSize); - } - - var normalizedAttr, normalizedValue, normalizedStyle = {}; - for (var attr in ownAttributes) { - normalizedAttr = normalizeAttr(attr); - normalizedValue = normalizeValue(normalizedAttr, ownAttributes[attr], parentAttributes, fontSize); - normalizedStyle[normalizedAttr] = normalizedValue; - } - if (normalizedStyle && normalizedStyle.font) { - fabric.parseFontDeclaration(normalizedStyle.font, normalizedStyle); - } - var mergedAttrs = extend(parentAttributes, normalizedStyle); - return fabric.svgValidParentsRegEx.test(element.nodeName) ? mergedAttrs : _setStrokeFillOpacity(mergedAttrs); - }, - - /** - * Transforms an array of svg elements to corresponding fabric.* instances - * @static - * @memberOf fabric - * @param {Array} elements Array of elements to parse - * @param {Function} callback Being passed an array of fabric instances (transformed from SVG elements) - * @param {Object} [options] Options object - * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created. - */ - parseElements: function(elements, callback, options, reviver, parsingOptions) { - new fabric.ElementsParser(elements, callback, options, reviver, parsingOptions).parse(); - }, - - /** - * Parses "style" attribute, retuning an object with values - * @static - * @memberOf fabric - * @param {SVGElement} element Element to parse - * @return {Object} Objects with values parsed from style attribute of an element - */ - parseStyleAttribute: function(element) { - var oStyle = { }, - style = element.getAttribute('style'); - - if (!style) { - return oStyle; - } - - if (typeof style === 'string') { - parseStyleString(style, oStyle); - } - else { - parseStyleObject(style, oStyle); - } - - return oStyle; - }, - - /** - * Parses "points" attribute, returning an array of values - * @static - * @memberOf fabric - * @param {String} points points attribute string - * @return {Array} array of points - */ - parsePointsAttribute: function(points) { - - // points attribute is required and must not be empty - if (!points) { - return null; - } - - // replace commas with whitespace and remove bookending whitespace - points = points.replace(/,/g, ' ').trim(); - - points = points.split(/\s+/); - var parsedPoints = [], i, len; - - for (i = 0, len = points.length; i < len; i += 2) { - parsedPoints.push({ - x: parseFloat(points[i]), - y: parseFloat(points[i + 1]) - }); - } - - // odd number of points is an error - // if (parsedPoints.length % 2 !== 0) { - // return null; - // } - - return parsedPoints; - }, - - /** - * Returns CSS rules for a given SVG document - * @static - * @function - * @memberOf fabric - * @param {SVGDocument} doc SVG document to parse - * @return {Object} CSS rules of this document - */ - getCSSRules: function(doc) { - var styles = doc.getElementsByTagName('style'), i, len, - allRules = { }, rules; - - // very crude parsing of style contents - for (i = 0, len = styles.length; i < len; i++) { - var styleContents = styles[i].textContent; - - // remove comments - styleContents = styleContents.replace(/\/\*[\s\S]*?\*\//g, ''); - if (styleContents.trim() === '') { - continue; - } - rules = styleContents.match(/[^{]*\{[\s\S]*?\}/g); - rules = rules.map(function(rule) { return rule.trim(); }); - // eslint-disable-next-line no-loop-func - rules.forEach(function(rule) { - - var match = rule.match(/([\s\S]*?)\s*\{([^}]*)\}/), - ruleObj = { }, declaration = match[2].trim(), - propertyValuePairs = declaration.replace(/;$/, '').split(/\s*;\s*/); - - for (i = 0, len = propertyValuePairs.length; i < len; i++) { - var pair = propertyValuePairs[i].split(/\s*:\s*/), - property = pair[0], - value = pair[1]; - ruleObj[property] = value; - } - rule = match[1]; - rule.split(',').forEach(function(_rule) { - _rule = _rule.replace(/^svg/i, '').trim(); - if (_rule === '') { - return; - } - if (allRules[_rule]) { - fabric.util.object.extend(allRules[_rule], ruleObj); - } - else { - allRules[_rule] = fabric.util.object.clone(ruleObj); - } - }); - }); - } - return allRules; - }, - - /** - * Takes url corresponding to an SVG document, and parses it into a set of fabric objects. - * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy) - * @memberOf fabric - * @param {String} url - * @param {Function} callback - * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created. - * @param {Object} [options] Object containing options for parsing - * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources - */ - loadSVGFromURL: function(url, callback, reviver, options) { - - url = url.replace(/^\n\s*/, '').trim(); - new fabric.util.request(url, { - method: 'get', - onComplete: onComplete - }); - - function onComplete(r) { - - var xml = r.responseXML; - if (!xml || !xml.documentElement) { - callback && callback(null); - return false; - } - - fabric.parseSVGDocument(xml.documentElement, function (results, _options, elements, allElements) { - callback && callback(results, _options, elements, allElements); - }, reviver, options); - } - }, - - /** - * Takes string corresponding to an SVG document, and parses it into a set of fabric objects - * @memberOf fabric - * @param {String} string - * @param {Function} callback - * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created. - * @param {Object} [options] Object containing options for parsing - * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources - */ - loadSVGFromString: function(string, callback, reviver, options) { - var parser = new fabric.window.DOMParser(), - doc = parser.parseFromString(string.trim(), 'text/xml'); - fabric.parseSVGDocument(doc.documentElement, function (results, _options, elements, allElements) { - callback(results, _options, elements, allElements); - }, reviver, options); - } - }); - -})(typeof exports !== 'undefined' ? exports : this); - - -fabric.ElementsParser = function(elements, callback, options, reviver, parsingOptions, doc) { - this.elements = elements; - this.callback = callback; - this.options = options; - this.reviver = reviver; - this.svgUid = (options && options.svgUid) || 0; - this.parsingOptions = parsingOptions; - this.regexUrl = /^url\(['"]?#([^'"]+)['"]?\)/g; - this.doc = doc; -}; - -(function(proto) { - proto.parse = function() { - this.instances = new Array(this.elements.length); - this.numElements = this.elements.length; - this.createObjects(); - }; - - proto.createObjects = function() { - var _this = this; - this.elements.forEach(function(element, i) { - element.setAttribute('svgUid', _this.svgUid); - _this.createObject(element, i); - }); - }; - - proto.findTag = function(el) { - return fabric[fabric.util.string.capitalize(el.tagName.replace('svg:', ''))]; - }; - - proto.createObject = function(el, index) { - var klass = this.findTag(el); - if (klass && klass.fromElement) { - try { - klass.fromElement(el, this.createCallback(index, el), this.options); - } - catch (err) { - fabric.log(err); - } - } - else { - this.checkIfDone(); - } - }; - - proto.createCallback = function(index, el) { - var _this = this; - return function(obj) { - var _options; - _this.resolveGradient(obj, el, 'fill'); - _this.resolveGradient(obj, el, 'stroke'); - if (obj instanceof fabric.Image && obj._originalElement) { - _options = obj.parsePreserveAspectRatioAttribute(el); - } - obj._removeTransformMatrix(_options); - _this.resolveClipPath(obj, el); - _this.reviver && _this.reviver(el, obj); - _this.instances[index] = obj; - _this.checkIfDone(); - }; - }; - - proto.extractPropertyDefinition = function(obj, property, storage) { - var value = obj[property], regex = this.regexUrl; - if (!regex.test(value)) { - return; - } - regex.lastIndex = 0; - var id = regex.exec(value)[1]; - regex.lastIndex = 0; - return fabric[storage][this.svgUid][id]; - }; - - proto.resolveGradient = function(obj, el, property) { - var gradientDef = this.extractPropertyDefinition(obj, property, 'gradientDefs'); - if (gradientDef) { - var opacityAttr = el.getAttribute(property + '-opacity'); - var gradient = fabric.Gradient.fromElement(gradientDef, obj, opacityAttr, this.options); - obj.set(property, gradient); - } - }; - - proto.createClipPathCallback = function(obj, container) { - return function(_newObj) { - _newObj._removeTransformMatrix(); - _newObj.fillRule = _newObj.clipRule; - container.push(_newObj); - }; - }; - - proto.resolveClipPath = function(obj, usingElement) { - var clipPath = this.extractPropertyDefinition(obj, 'clipPath', 'clipPaths'), - element, klass, objTransformInv, container, gTransform, options; - if (clipPath) { - container = []; - objTransformInv = fabric.util.invertTransform(obj.calcTransformMatrix()); - // move the clipPath tag as sibling to the real element that is using it - var clipPathTag = clipPath[0].parentNode; - var clipPathOwner = usingElement; - while (clipPathOwner.parentNode && clipPathOwner.getAttribute('clip-path') !== obj.clipPath) { - clipPathOwner = clipPathOwner.parentNode; - } - clipPathOwner.parentNode.appendChild(clipPathTag); - for (var i = 0; i < clipPath.length; i++) { - element = clipPath[i]; - klass = this.findTag(element); - klass.fromElement( - element, - this.createClipPathCallback(obj, container), - this.options - ); - } - if (container.length === 1) { - clipPath = container[0]; - } - else { - clipPath = new fabric.Group(container); - } - gTransform = fabric.util.multiplyTransformMatrices( - objTransformInv, - clipPath.calcTransformMatrix() - ); - if (clipPath.clipPath) { - this.resolveClipPath(clipPath, clipPathOwner); - } - var options = fabric.util.qrDecompose(gTransform); - clipPath.flipX = false; - clipPath.flipY = false; - clipPath.set('scaleX', options.scaleX); - clipPath.set('scaleY', options.scaleY); - clipPath.angle = options.angle; - clipPath.skewX = options.skewX; - clipPath.skewY = 0; - clipPath.setPositionByOrigin({ x: options.translateX, y: options.translateY }, 'center', 'center'); - obj.clipPath = clipPath; - } - else { - // if clip-path does not resolve to any element, delete the property. - delete obj.clipPath; - } - }; - - proto.checkIfDone = function() { - if (--this.numElements === 0) { - this.instances = this.instances.filter(function(el) { - // eslint-disable-next-line no-eq-null, eqeqeq - return el != null; - }); - this.callback(this.instances, this.elements); - } - }; -})(fabric.ElementsParser.prototype); - - -(function(global) { - - 'use strict'; - - /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */ - - var fabric = global.fabric || (global.fabric = { }); - - if (fabric.Point) { - fabric.warn('fabric.Point is already defined'); - return; - } - - fabric.Point = Point; - - /** - * Point class - * @class fabric.Point - * @memberOf fabric - * @constructor - * @param {Number} x - * @param {Number} y - * @return {fabric.Point} thisArg - */ - function Point(x, y) { - this.x = x; - this.y = y; - } - - Point.prototype = /** @lends fabric.Point.prototype */ { - - type: 'point', - - constructor: Point, - - /** - * Adds another point to this one and returns another one - * @param {fabric.Point} that - * @return {fabric.Point} new Point instance with added values - */ - add: function (that) { - return new Point(this.x + that.x, this.y + that.y); - }, - - /** - * Adds another point to this one - * @param {fabric.Point} that - * @return {fabric.Point} thisArg - * @chainable - */ - addEquals: function (that) { - this.x += that.x; - this.y += that.y; - return this; - }, - - /** - * Adds value to this point and returns a new one - * @param {Number} scalar - * @return {fabric.Point} new Point with added value - */ - scalarAdd: function (scalar) { - return new Point(this.x + scalar, this.y + scalar); - }, - - /** - * Adds value to this point - * @param {Number} scalar - * @return {fabric.Point} thisArg - * @chainable - */ - scalarAddEquals: function (scalar) { - this.x += scalar; - this.y += scalar; - return this; - }, - - /** - * Subtracts another point from this point and returns a new one - * @param {fabric.Point} that - * @return {fabric.Point} new Point object with subtracted values - */ - subtract: function (that) { - return new Point(this.x - that.x, this.y - that.y); - }, - - /** - * Subtracts another point from this point - * @param {fabric.Point} that - * @return {fabric.Point} thisArg - * @chainable - */ - subtractEquals: function (that) { - this.x -= that.x; - this.y -= that.y; - return this; - }, - - /** - * Subtracts value from this point and returns a new one - * @param {Number} scalar - * @return {fabric.Point} - */ - scalarSubtract: function (scalar) { - return new Point(this.x - scalar, this.y - scalar); - }, - - /** - * Subtracts value from this point - * @param {Number} scalar - * @return {fabric.Point} thisArg - * @chainable - */ - scalarSubtractEquals: function (scalar) { - this.x -= scalar; - this.y -= scalar; - return this; - }, - - /** - * Multiplies this point by a value and returns a new one - * TODO: rename in scalarMultiply in 2.0 - * @param {Number} scalar - * @return {fabric.Point} - */ - multiply: function (scalar) { - return new Point(this.x * scalar, this.y * scalar); - }, - - /** - * Multiplies this point by a value - * TODO: rename in scalarMultiplyEquals in 2.0 - * @param {Number} scalar - * @return {fabric.Point} thisArg - * @chainable - */ - multiplyEquals: function (scalar) { - this.x *= scalar; - this.y *= scalar; - return this; - }, - - /** - * Divides this point by a value and returns a new one - * TODO: rename in scalarDivide in 2.0 - * @param {Number} scalar - * @return {fabric.Point} - */ - divide: function (scalar) { - return new Point(this.x / scalar, this.y / scalar); - }, - - /** - * Divides this point by a value - * TODO: rename in scalarDivideEquals in 2.0 - * @param {Number} scalar - * @return {fabric.Point} thisArg - * @chainable - */ - divideEquals: function (scalar) { - this.x /= scalar; - this.y /= scalar; - return this; - }, - - /** - * Returns true if this point is equal to another one - * @param {fabric.Point} that - * @return {Boolean} - */ - eq: function (that) { - return (this.x === that.x && this.y === that.y); - }, - - /** - * Returns true if this point is less than another one - * @param {fabric.Point} that - * @return {Boolean} - */ - lt: function (that) { - return (this.x < that.x && this.y < that.y); - }, - - /** - * Returns true if this point is less than or equal to another one - * @param {fabric.Point} that - * @return {Boolean} - */ - lte: function (that) { - return (this.x <= that.x && this.y <= that.y); - }, - - /** - - * Returns true if this point is greater another one - * @param {fabric.Point} that - * @return {Boolean} - */ - gt: function (that) { - return (this.x > that.x && this.y > that.y); - }, - - /** - * Returns true if this point is greater than or equal to another one - * @param {fabric.Point} that - * @return {Boolean} - */ - gte: function (that) { - return (this.x >= that.x && this.y >= that.y); - }, - - /** - * Returns new point which is the result of linear interpolation with this one and another one - * @param {fabric.Point} that - * @param {Number} t , position of interpolation, between 0 and 1 default 0.5 - * @return {fabric.Point} - */ - lerp: function (that, t) { - if (typeof t === 'undefined') { - t = 0.5; - } - t = Math.max(Math.min(1, t), 0); - return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t); - }, - - /** - * Returns distance from this point and another one - * @param {fabric.Point} that - * @return {Number} - */ - distanceFrom: function (that) { - var dx = this.x - that.x, - dy = this.y - that.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - /** - * Returns the point between this point and another one - * @param {fabric.Point} that - * @return {fabric.Point} - */ - midPointFrom: function (that) { - return this.lerp(that); - }, - - /** - * Returns a new point which is the min of this and another one - * @param {fabric.Point} that - * @return {fabric.Point} - */ - min: function (that) { - return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y)); - }, - - /** - * Returns a new point which is the max of this and another one - * @param {fabric.Point} that - * @return {fabric.Point} - */ - max: function (that) { - return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y)); - }, - - /** - * Returns string representation of this point - * @return {String} - */ - toString: function () { - return this.x + ',' + this.y; - }, - - /** - * Sets x/y of this point - * @param {Number} x - * @param {Number} y - * @chainable - */ - setXY: function (x, y) { - this.x = x; - this.y = y; - return this; - }, - - /** - * Sets x of this point - * @param {Number} x - * @chainable - */ - setX: function (x) { - this.x = x; - return this; - }, - - /** - * Sets y of this point - * @param {Number} y - * @chainable - */ - setY: function (y) { - this.y = y; - return this; - }, - - /** - * Sets x/y of this point from another point - * @param {fabric.Point} that - * @chainable - */ - setFromPoint: function (that) { - this.x = that.x; - this.y = that.y; - return this; - }, - - /** - * Swaps x/y of this point and another point - * @param {fabric.Point} that - */ - swap: function (that) { - var x = this.x, - y = this.y; - this.x = that.x; - this.y = that.y; - that.x = x; - that.y = y; - }, - - /** - * return a cloned instance of the point - * @return {fabric.Point} - */ - clone: function () { - return new Point(this.x, this.y); - } - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */ - var fabric = global.fabric || (global.fabric = { }); - - if (fabric.Intersection) { - fabric.warn('fabric.Intersection is already defined'); - return; - } - - /** - * Intersection class - * @class fabric.Intersection - * @memberOf fabric - * @constructor - */ - function Intersection(status) { - this.status = status; - this.points = []; - } - - fabric.Intersection = Intersection; - - fabric.Intersection.prototype = /** @lends fabric.Intersection.prototype */ { - - constructor: Intersection, - - /** - * Appends a point to intersection - * @param {fabric.Point} point - * @return {fabric.Intersection} thisArg - * @chainable - */ - appendPoint: function (point) { - this.points.push(point); - return this; - }, - - /** - * Appends points to intersection - * @param {Array} points - * @return {fabric.Intersection} thisArg - * @chainable - */ - appendPoints: function (points) { - this.points = this.points.concat(points); - return this; - } - }; - - /** - * Checks if one line intersects another - * TODO: rename in intersectSegmentSegment - * @static - * @param {fabric.Point} a1 - * @param {fabric.Point} a2 - * @param {fabric.Point} b1 - * @param {fabric.Point} b2 - * @return {fabric.Intersection} - */ - fabric.Intersection.intersectLineLine = function (a1, a2, b1, b2) { - var result, - uaT = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x), - ubT = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x), - uB = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y); - if (uB !== 0) { - var ua = uaT / uB, - ub = ubT / uB; - if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) { - result = new Intersection('Intersection'); - result.appendPoint(new fabric.Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y))); - } - else { - result = new Intersection(); - } - } - else { - if (uaT === 0 || ubT === 0) { - result = new Intersection('Coincident'); - } - else { - result = new Intersection('Parallel'); - } - } - return result; - }; - - /** - * Checks if line intersects polygon - * TODO: rename in intersectSegmentPolygon - * fix detection of coincident - * @static - * @param {fabric.Point} a1 - * @param {fabric.Point} a2 - * @param {Array} points - * @return {fabric.Intersection} - */ - fabric.Intersection.intersectLinePolygon = function(a1, a2, points) { - var result = new Intersection(), - length = points.length, - b1, b2, inter, i; - - for (i = 0; i < length; i++) { - b1 = points[i]; - b2 = points[(i + 1) % length]; - inter = Intersection.intersectLineLine(a1, a2, b1, b2); - - result.appendPoints(inter.points); - } - if (result.points.length > 0) { - result.status = 'Intersection'; - } - return result; - }; - - /** - * Checks if polygon intersects another polygon - * @static - * @param {Array} points1 - * @param {Array} points2 - * @return {fabric.Intersection} - */ - fabric.Intersection.intersectPolygonPolygon = function (points1, points2) { - var result = new Intersection(), - length = points1.length, i; - - for (i = 0; i < length; i++) { - var a1 = points1[i], - a2 = points1[(i + 1) % length], - inter = Intersection.intersectLinePolygon(a1, a2, points2); - - result.appendPoints(inter.points); - } - if (result.points.length > 0) { - result.status = 'Intersection'; - } - return result; - }; - - /** - * Checks if polygon intersects rectangle - * @static - * @param {Array} points - * @param {fabric.Point} r1 - * @param {fabric.Point} r2 - * @return {fabric.Intersection} - */ - fabric.Intersection.intersectPolygonRectangle = function (points, r1, r2) { - var min = r1.min(r2), - max = r1.max(r2), - topRight = new fabric.Point(max.x, min.y), - bottomLeft = new fabric.Point(min.x, max.y), - inter1 = Intersection.intersectLinePolygon(min, topRight, points), - inter2 = Intersection.intersectLinePolygon(topRight, max, points), - inter3 = Intersection.intersectLinePolygon(max, bottomLeft, points), - inter4 = Intersection.intersectLinePolygon(bottomLeft, min, points), - result = new Intersection(); - - result.appendPoints(inter1.points); - result.appendPoints(inter2.points); - result.appendPoints(inter3.points); - result.appendPoints(inter4.points); - - if (result.points.length > 0) { - result.status = 'Intersection'; - } - return result; - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }); - - if (fabric.Color) { - fabric.warn('fabric.Color is already defined.'); - return; - } - - /** - * Color class - * The purpose of {@link fabric.Color} is to abstract and encapsulate common color operations; - * {@link fabric.Color} is a constructor and creates instances of {@link fabric.Color} objects. - * - * @class fabric.Color - * @param {String} color optional in hex or rgb(a) or hsl format or from known color list - * @return {fabric.Color} thisArg - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#colors} - */ - function Color(color) { - if (!color) { - this.setSource([0, 0, 0, 1]); - } - else { - this._tryParsingColor(color); - } - } - - fabric.Color = Color; - - fabric.Color.prototype = /** @lends fabric.Color.prototype */ { - - /** - * @private - * @param {String|Array} color Color value to parse - */ - _tryParsingColor: function(color) { - var source; - - if (color in Color.colorNameMap) { - color = Color.colorNameMap[color]; - } - - if (color === 'transparent') { - source = [255, 255, 255, 0]; - } - - if (!source) { - source = Color.sourceFromHex(color); - } - if (!source) { - source = Color.sourceFromRgb(color); - } - if (!source) { - source = Color.sourceFromHsl(color); - } - if (!source) { - //if color is not recognize let's make black as canvas does - source = [0, 0, 0, 1]; - } - if (source) { - this.setSource(source); - } - }, - - /** - * Adapted from https://github.com/mjijackson - * @private - * @param {Number} r Red color value - * @param {Number} g Green color value - * @param {Number} b Blue color value - * @return {Array} Hsl color - */ - _rgbToHsl: function(r, g, b) { - r /= 255; g /= 255; b /= 255; - - var h, s, l, - max = fabric.util.array.max([r, g, b]), - min = fabric.util.array.min([r, g, b]); - - l = (max + min) / 2; - - if (max === min) { - h = s = 0; // achromatic - } - else { - var d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - case g: - h = (b - r) / d + 2; - break; - case b: - h = (r - g) / d + 4; - break; - } - h /= 6; - } - - return [ - Math.round(h * 360), - Math.round(s * 100), - Math.round(l * 100) - ]; - }, - - /** - * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1]) - * @return {Array} - */ - getSource: function() { - return this._source; - }, - - /** - * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1]) - * @param {Array} source - */ - setSource: function(source) { - this._source = source; - }, - - /** - * Returns color representation in RGB format - * @return {String} ex: rgb(0-255,0-255,0-255) - */ - toRgb: function() { - var source = this.getSource(); - return 'rgb(' + source[0] + ',' + source[1] + ',' + source[2] + ')'; - }, - - /** - * Returns color representation in RGBA format - * @return {String} ex: rgba(0-255,0-255,0-255,0-1) - */ - toRgba: function() { - var source = this.getSource(); - return 'rgba(' + source[0] + ',' + source[1] + ',' + source[2] + ',' + source[3] + ')'; - }, - - /** - * Returns color representation in HSL format - * @return {String} ex: hsl(0-360,0%-100%,0%-100%) - */ - toHsl: function() { - var source = this.getSource(), - hsl = this._rgbToHsl(source[0], source[1], source[2]); - - return 'hsl(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%)'; - }, - - /** - * Returns color representation in HSLA format - * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1) - */ - toHsla: function() { - var source = this.getSource(), - hsl = this._rgbToHsl(source[0], source[1], source[2]); - - return 'hsla(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%,' + source[3] + ')'; - }, - - /** - * Returns color representation in HEX format - * @return {String} ex: FF5555 - */ - toHex: function() { - var source = this.getSource(), r, g, b; - - r = source[0].toString(16); - r = (r.length === 1) ? ('0' + r) : r; - - g = source[1].toString(16); - g = (g.length === 1) ? ('0' + g) : g; - - b = source[2].toString(16); - b = (b.length === 1) ? ('0' + b) : b; - - return r.toUpperCase() + g.toUpperCase() + b.toUpperCase(); - }, - - /** - * Returns color representation in HEXA format - * @return {String} ex: FF5555CC - */ - toHexa: function() { - var source = this.getSource(), a; - - a = Math.round(source[3] * 255); - a = a.toString(16); - a = (a.length === 1) ? ('0' + a) : a; - - return this.toHex() + a.toUpperCase(); - }, - - /** - * Gets value of alpha channel for this color - * @return {Number} 0-1 - */ - getAlpha: function() { - return this.getSource()[3]; - }, - - /** - * Sets value of alpha channel for this color - * @param {Number} alpha Alpha value 0-1 - * @return {fabric.Color} thisArg - */ - setAlpha: function(alpha) { - var source = this.getSource(); - source[3] = alpha; - this.setSource(source); - return this; - }, - - /** - * Transforms color to its grayscale representation - * @return {fabric.Color} thisArg - */ - toGrayscale: function() { - var source = this.getSource(), - average = parseInt((source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0), 10), - currentAlpha = source[3]; - this.setSource([average, average, average, currentAlpha]); - return this; - }, - - /** - * Transforms color to its black and white representation - * @param {Number} threshold - * @return {fabric.Color} thisArg - */ - toBlackWhite: function(threshold) { - var source = this.getSource(), - average = (source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0), - currentAlpha = source[3]; - - threshold = threshold || 127; - - average = (Number(average) < Number(threshold)) ? 0 : 255; - this.setSource([average, average, average, currentAlpha]); - return this; - }, - - /** - * Overlays color with another color - * @param {String|fabric.Color} otherColor - * @return {fabric.Color} thisArg - */ - overlayWith: function(otherColor) { - if (!(otherColor instanceof Color)) { - otherColor = new Color(otherColor); - } - - var result = [], - alpha = this.getAlpha(), - otherAlpha = 0.5, - source = this.getSource(), - otherSource = otherColor.getSource(), i; - - for (i = 0; i < 3; i++) { - result.push(Math.round((source[i] * (1 - otherAlpha)) + (otherSource[i] * otherAlpha))); - } - - result[3] = alpha; - this.setSource(result); - return this; - } - }; - - /** - * Regex matching color in RGB or RGBA formats (ex: rgb(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5)) - * @static - * @field - * @memberOf fabric.Color - */ - // eslint-disable-next-line max-len - fabric.Color.reRGBa = /^rgba?\(\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*(?:\s*,\s*((?:\d*\.?\d+)?)\s*)?\)$/i; - - /** - * Regex matching color in HSL or HSLA formats (ex: hsl(200, 80%, 10%), hsla(300, 50%, 80%, 0.5), hsla( 300 , 50% , 80% , 0.5 )) - * @static - * @field - * @memberOf fabric.Color - */ - fabric.Color.reHSLa = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3}\%)\s*,\s*(\d{1,3}\%)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/i; - - /** - * Regex matching color in HEX format (ex: #FF5544CC, #FF5555, 010155, aff) - * @static - * @field - * @memberOf fabric.Color - */ - fabric.Color.reHex = /^#?([0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{4}|[0-9a-f]{3})$/i; - - /** - * Map of the 148 color names with HEX code - * @static - * @field - * @memberOf fabric.Color - * @see: https://www.w3.org/TR/css3-color/#svg-color - */ - fabric.Color.colorNameMap = { - aliceblue: '#F0F8FF', - antiquewhite: '#FAEBD7', - aqua: '#00FFFF', - aquamarine: '#7FFFD4', - azure: '#F0FFFF', - beige: '#F5F5DC', - bisque: '#FFE4C4', - black: '#000000', - blanchedalmond: '#FFEBCD', - blue: '#0000FF', - blueviolet: '#8A2BE2', - brown: '#A52A2A', - burlywood: '#DEB887', - cadetblue: '#5F9EA0', - chartreuse: '#7FFF00', - chocolate: '#D2691E', - coral: '#FF7F50', - cornflowerblue: '#6495ED', - cornsilk: '#FFF8DC', - crimson: '#DC143C', - cyan: '#00FFFF', - darkblue: '#00008B', - darkcyan: '#008B8B', - darkgoldenrod: '#B8860B', - darkgray: '#A9A9A9', - darkgrey: '#A9A9A9', - darkgreen: '#006400', - darkkhaki: '#BDB76B', - darkmagenta: '#8B008B', - darkolivegreen: '#556B2F', - darkorange: '#FF8C00', - darkorchid: '#9932CC', - darkred: '#8B0000', - darksalmon: '#E9967A', - darkseagreen: '#8FBC8F', - darkslateblue: '#483D8B', - darkslategray: '#2F4F4F', - darkslategrey: '#2F4F4F', - darkturquoise: '#00CED1', - darkviolet: '#9400D3', - deeppink: '#FF1493', - deepskyblue: '#00BFFF', - dimgray: '#696969', - dimgrey: '#696969', - dodgerblue: '#1E90FF', - firebrick: '#B22222', - floralwhite: '#FFFAF0', - forestgreen: '#228B22', - fuchsia: '#FF00FF', - gainsboro: '#DCDCDC', - ghostwhite: '#F8F8FF', - gold: '#FFD700', - goldenrod: '#DAA520', - gray: '#808080', - grey: '#808080', - green: '#008000', - greenyellow: '#ADFF2F', - honeydew: '#F0FFF0', - hotpink: '#FF69B4', - indianred: '#CD5C5C', - indigo: '#4B0082', - ivory: '#FFFFF0', - khaki: '#F0E68C', - lavender: '#E6E6FA', - lavenderblush: '#FFF0F5', - lawngreen: '#7CFC00', - lemonchiffon: '#FFFACD', - lightblue: '#ADD8E6', - lightcoral: '#F08080', - lightcyan: '#E0FFFF', - lightgoldenrodyellow: '#FAFAD2', - lightgray: '#D3D3D3', - lightgrey: '#D3D3D3', - lightgreen: '#90EE90', - lightpink: '#FFB6C1', - lightsalmon: '#FFA07A', - lightseagreen: '#20B2AA', - lightskyblue: '#87CEFA', - lightslategray: '#778899', - lightslategrey: '#778899', - lightsteelblue: '#B0C4DE', - lightyellow: '#FFFFE0', - lime: '#00FF00', - limegreen: '#32CD32', - linen: '#FAF0E6', - magenta: '#FF00FF', - maroon: '#800000', - mediumaquamarine: '#66CDAA', - mediumblue: '#0000CD', - mediumorchid: '#BA55D3', - mediumpurple: '#9370DB', - mediumseagreen: '#3CB371', - mediumslateblue: '#7B68EE', - mediumspringgreen: '#00FA9A', - mediumturquoise: '#48D1CC', - mediumvioletred: '#C71585', - midnightblue: '#191970', - mintcream: '#F5FFFA', - mistyrose: '#FFE4E1', - moccasin: '#FFE4B5', - navajowhite: '#FFDEAD', - navy: '#000080', - oldlace: '#FDF5E6', - olive: '#808000', - olivedrab: '#6B8E23', - orange: '#FFA500', - orangered: '#FF4500', - orchid: '#DA70D6', - palegoldenrod: '#EEE8AA', - palegreen: '#98FB98', - paleturquoise: '#AFEEEE', - palevioletred: '#DB7093', - papayawhip: '#FFEFD5', - peachpuff: '#FFDAB9', - peru: '#CD853F', - pink: '#FFC0CB', - plum: '#DDA0DD', - powderblue: '#B0E0E6', - purple: '#800080', - rebeccapurple: '#663399', - red: '#FF0000', - rosybrown: '#BC8F8F', - royalblue: '#4169E1', - saddlebrown: '#8B4513', - salmon: '#FA8072', - sandybrown: '#F4A460', - seagreen: '#2E8B57', - seashell: '#FFF5EE', - sienna: '#A0522D', - silver: '#C0C0C0', - skyblue: '#87CEEB', - slateblue: '#6A5ACD', - slategray: '#708090', - slategrey: '#708090', - snow: '#FFFAFA', - springgreen: '#00FF7F', - steelblue: '#4682B4', - tan: '#D2B48C', - teal: '#008080', - thistle: '#D8BFD8', - tomato: '#FF6347', - turquoise: '#40E0D0', - violet: '#EE82EE', - wheat: '#F5DEB3', - white: '#FFFFFF', - whitesmoke: '#F5F5F5', - yellow: '#FFFF00', - yellowgreen: '#9ACD32' - }; - - /** - * @private - * @param {Number} p - * @param {Number} q - * @param {Number} t - * @return {Number} - */ - function hue2rgb(p, q, t) { - if (t < 0) { - t += 1; - } - if (t > 1) { - t -= 1; - } - if (t < 1 / 6) { - return p + (q - p) * 6 * t; - } - if (t < 1 / 2) { - return q; - } - if (t < 2 / 3) { - return p + (q - p) * (2 / 3 - t) * 6; - } - return p; - } - - /** - * Returns new color object, when given a color in RGB format - * @memberOf fabric.Color - * @param {String} color Color value ex: rgb(0-255,0-255,0-255) - * @return {fabric.Color} - */ - fabric.Color.fromRgb = function(color) { - return Color.fromSource(Color.sourceFromRgb(color)); - }; - - /** - * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format - * @memberOf fabric.Color - * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%) - * @return {Array} source - */ - fabric.Color.sourceFromRgb = function(color) { - var match = color.match(Color.reRGBa); - if (match) { - var r = parseInt(match[1], 10) / (/%$/.test(match[1]) ? 100 : 1) * (/%$/.test(match[1]) ? 255 : 1), - g = parseInt(match[2], 10) / (/%$/.test(match[2]) ? 100 : 1) * (/%$/.test(match[2]) ? 255 : 1), - b = parseInt(match[3], 10) / (/%$/.test(match[3]) ? 100 : 1) * (/%$/.test(match[3]) ? 255 : 1); - - return [ - parseInt(r, 10), - parseInt(g, 10), - parseInt(b, 10), - match[4] ? parseFloat(match[4]) : 1 - ]; - } - }; - - /** - * Returns new color object, when given a color in RGBA format - * @static - * @function - * @memberOf fabric.Color - * @param {String} color - * @return {fabric.Color} - */ - fabric.Color.fromRgba = Color.fromRgb; - - /** - * Returns new color object, when given a color in HSL format - * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%) - * @memberOf fabric.Color - * @return {fabric.Color} - */ - fabric.Color.fromHsl = function(color) { - return Color.fromSource(Color.sourceFromHsl(color)); - }; - - /** - * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format. - * Adapted from https://github.com/mjijackson - * @memberOf fabric.Color - * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1) - * @return {Array} source - * @see http://http://www.w3.org/TR/css3-color/#hsl-color - */ - fabric.Color.sourceFromHsl = function(color) { - var match = color.match(Color.reHSLa); - if (!match) { - return; - } - - var h = (((parseFloat(match[1]) % 360) + 360) % 360) / 360, - s = parseFloat(match[2]) / (/%$/.test(match[2]) ? 100 : 1), - l = parseFloat(match[3]) / (/%$/.test(match[3]) ? 100 : 1), - r, g, b; - - if (s === 0) { - r = g = b = l; - } - else { - var q = l <= 0.5 ? l * (s + 1) : l + s - l * s, - p = l * 2 - q; - - r = hue2rgb(p, q, h + 1 / 3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1 / 3); - } - - return [ - Math.round(r * 255), - Math.round(g * 255), - Math.round(b * 255), - match[4] ? parseFloat(match[4]) : 1 - ]; - }; - - /** - * Returns new color object, when given a color in HSLA format - * @static - * @function - * @memberOf fabric.Color - * @param {String} color - * @return {fabric.Color} - */ - fabric.Color.fromHsla = Color.fromHsl; - - /** - * Returns new color object, when given a color in HEX format - * @static - * @memberOf fabric.Color - * @param {String} color Color value ex: FF5555 - * @return {fabric.Color} - */ - fabric.Color.fromHex = function(color) { - return Color.fromSource(Color.sourceFromHex(color)); - }; - - /** - * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HEX format - * @static - * @memberOf fabric.Color - * @param {String} color ex: FF5555 or FF5544CC (RGBa) - * @return {Array} source - */ - fabric.Color.sourceFromHex = function(color) { - if (color.match(Color.reHex)) { - var value = color.slice(color.indexOf('#') + 1), - isShortNotation = (value.length === 3 || value.length === 4), - isRGBa = (value.length === 8 || value.length === 4), - r = isShortNotation ? (value.charAt(0) + value.charAt(0)) : value.substring(0, 2), - g = isShortNotation ? (value.charAt(1) + value.charAt(1)) : value.substring(2, 4), - b = isShortNotation ? (value.charAt(2) + value.charAt(2)) : value.substring(4, 6), - a = isRGBa ? (isShortNotation ? (value.charAt(3) + value.charAt(3)) : value.substring(6, 8)) : 'FF'; - - return [ - parseInt(r, 16), - parseInt(g, 16), - parseInt(b, 16), - parseFloat((parseInt(a, 16) / 255).toFixed(2)) - ]; - } - }; - - /** - * Returns new color object, when given color in array representation (ex: [200, 100, 100, 0.5]) - * @static - * @memberOf fabric.Color - * @param {Array} source - * @return {fabric.Color} - */ - fabric.Color.fromSource = function(source) { - var oColor = new Color(); - oColor.setSource(source); - return oColor; - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - scaleMap = ['e', 'se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e'], - skewMap = ['ns', 'nesw', 'ew', 'nwse'], - controls = {}, - LEFT = 'left', TOP = 'top', RIGHT = 'right', BOTTOM = 'bottom', CENTER = 'center', - opposite = { - top: BOTTOM, - bottom: TOP, - left: RIGHT, - right: LEFT, - center: CENTER, - }, radiansToDegrees = fabric.util.radiansToDegrees, - sign = (Math.sign || function(x) { return ((x > 0) - (x < 0)) || +x; }); - - /** - * Combine control position and object angle to find the control direction compared - * to the object center. - * @param {fabric.Object} fabricObject the fabric object for which we are rendering controls - * @param {fabric.Control} control the control class - * @return {Number} 0 - 7 a quadrant number - */ - function findCornerQuadrant(fabricObject, control) { - var cornerAngle = fabricObject.angle + radiansToDegrees(Math.atan2(control.y, control.x)) + 360; - return Math.round((cornerAngle % 360) / 45); - } - - function fireEvent(eventName, options) { - var target = options.transform.target, - canvas = target.canvas, - canvasOptions = fabric.util.object.clone(options); - canvasOptions.target = target; - canvas && canvas.fire('object:' + eventName, canvasOptions); - target.fire(eventName, options); - } - - /** - * Inspect event and fabricObject properties to understand if the scaling action - * @param {Event} eventData from the user action - * @param {fabric.Object} fabricObject the fabric object about to scale - * @return {Boolean} true if scale is proportional - */ - function scaleIsProportional(eventData, fabricObject) { - var canvas = fabricObject.canvas, uniScaleKey = canvas.uniScaleKey, - uniformIsToggled = eventData[uniScaleKey]; - return (canvas.uniformScaling && !uniformIsToggled) || - (!canvas.uniformScaling && uniformIsToggled); - } - - /** - * Checks if transform is centered - * @param {Object} transform transform data - * @return {Boolean} true if transform is centered - */ - function isTransformCentered(transform) { - return transform.originX === CENTER && transform.originY === CENTER; - } - - /** - * Inspect fabricObject to understand if the current scaling action is allowed - * @param {fabric.Object} fabricObject the fabric object about to scale - * @param {String} by 'x' or 'y' or '' - * @param {Boolean} scaleProportionally true if we are trying to scale proportionally - * @return {Boolean} true if scaling is not allowed at current conditions - */ - function scalingIsForbidden(fabricObject, by, scaleProportionally) { - var lockX = fabricObject.lockScalingX, lockY = fabricObject.lockScalingY; - if (lockX && lockY) { - return true; - } - if (!by && (lockX || lockY) && scaleProportionally) { - return true; - } - if (lockX && by === 'x') { - return true; - } - if (lockY && by === 'y') { - return true; - } - return false; - } - - /** - * return the correct cursor style for the scale action - * @param {Event} eventData the javascript event that is causing the scale - * @param {fabric.Control} control the control that is interested in the action - * @param {fabric.Object} fabricObject the fabric object that is interested in the action - * @return {String} a valid css string for the cursor - */ - function scaleCursorStyleHandler(eventData, control, fabricObject) { - var notAllowed = 'not-allowed', - scaleProportionally = scaleIsProportional(eventData, fabricObject), - by = ''; - if (control.x !== 0 && control.y === 0) { - by = 'x'; - } - else if (control.x === 0 && control.y !== 0) { - by = 'y'; - } - if (scalingIsForbidden(fabricObject, by, scaleProportionally)) { - return notAllowed; - } - var n = findCornerQuadrant(fabricObject, control); - return scaleMap[n] + '-resize'; - } - - /** - * return the correct cursor style for the skew action - * @param {Event} eventData the javascript event that is causing the scale - * @param {fabric.Control} control the control that is interested in the action - * @param {fabric.Object} fabricObject the fabric object that is interested in the action - * @return {String} a valid css string for the cursor - */ - function skewCursorStyleHandler(eventData, control, fabricObject) { - var notAllowed = 'not-allowed'; - if (control.x !== 0 && fabricObject.lockSkewingY) { - return notAllowed; - } - if (control.y !== 0 && fabricObject.lockSkewingX) { - return notAllowed; - } - var n = findCornerQuadrant(fabricObject, control) % 4; - return skewMap[n] + '-resize'; - } - - /** - * Combine skew and scale style handlers to cover fabric standard use case - * @param {Event} eventData the javascript event that is causing the scale - * @param {fabric.Control} control the control that is interested in the action - * @param {fabric.Object} fabricObject the fabric object that is interested in the action - * @return {String} a valid css string for the cursor - */ - function scaleSkewCursorStyleHandler(eventData, control, fabricObject) { - if (eventData[fabricObject.canvas.altActionKey]) { - return controls.skewCursorStyleHandler(eventData, control, fabricObject); - } - return controls.scaleCursorStyleHandler(eventData, control, fabricObject); - } - - /** - * Inspect event, control and fabricObject to return the correct action name - * @param {Event} eventData the javascript event that is causing the scale - * @param {fabric.Control} control the control that is interested in the action - * @param {fabric.Object} fabricObject the fabric object that is interested in the action - * @return {String} an action name - */ - function scaleOrSkewActionName(eventData, control, fabricObject) { - var isAlternative = eventData[fabricObject.canvas.altActionKey]; - if (control.x === 0) { - // then is scaleY or skewX - return isAlternative ? 'skewX' : 'scaleY'; - } - if (control.y === 0) { - // then is scaleY or skewX - return isAlternative ? 'skewY' : 'scaleX'; - } - } - - /** - * Find the correct style for the control that is used for rotation. - * this function is very simple and it just take care of not-allowed or standard cursor - * @param {Event} eventData the javascript event that is causing the scale - * @param {fabric.Control} control the control that is interested in the action - * @param {fabric.Object} fabricObject the fabric object that is interested in the action - * @return {String} a valid css string for the cursor - */ - function rotationStyleHandler(eventData, control, fabricObject) { - if (fabricObject.lockRotation) { - return 'not-allowed'; - } - return control.cursorStyle; - } - - function commonEventInfo(eventData, transform, x, y) { - return { - e: eventData, - transform: transform, - pointer: { - x: x, - y: y, - } - }; - } - - /** - * Wrap an action handler with saving/restoring object position on the transform. - * this is the code that permits to objects to keep their position while transforming. - * @param {Function} actionHandler the function to wrap - * @return {Function} a function with an action handler signature - */ - function wrapWithFixedAnchor(actionHandler) { - return function(eventData, transform, x, y) { - var target = transform.target, centerPoint = target.getCenterPoint(), - constraint = target.translateToOriginPoint(centerPoint, transform.originX, transform.originY), - actionPerformed = actionHandler(eventData, transform, x, y); - target.setPositionByOrigin(constraint, transform.originX, transform.originY); - return actionPerformed; - }; - } - - /** - * Wrap an action handler with firing an event if the action is performed - * @param {Function} actionHandler the function to wrap - * @return {Function} a function with an action handler signature - */ - function wrapWithFireEvent(eventName, actionHandler) { - return function(eventData, transform, x, y) { - var actionPerformed = actionHandler(eventData, transform, x, y); - if (actionPerformed) { - fireEvent(eventName, commonEventInfo(eventData, transform, x, y)); - } - return actionPerformed; - }; - } - - /** - * Transforms a point described by x and y in a distance from the top left corner of the object - * bounding box. - * @param {Object} transform - * @param {String} originX - * @param {String} originY - * @param {number} x - * @param {number} y - * @return {Fabric.Point} the normalized point - */ - function getLocalPoint(transform, originX, originY, x, y) { - var target = transform.target, - control = target.controls[transform.corner], - zoom = target.canvas.getZoom(), - padding = target.padding / zoom, - localPoint = target.toLocalPoint(new fabric.Point(x, y), originX, originY); - if (localPoint.x >= padding) { - localPoint.x -= padding; - } - if (localPoint.x <= -padding) { - localPoint.x += padding; - } - if (localPoint.y >= padding) { - localPoint.y -= padding; - } - if (localPoint.y <= padding) { - localPoint.y += padding; - } - localPoint.x -= control.offsetX; - localPoint.y -= control.offsetY; - return localPoint; - } - - /** - * Detect if the fabric object is flipped on one side. - * @param {fabric.Object} target - * @return {Boolean} true if one flip, but not two. - */ - function targetHasOneFlip(target) { - return target.flipX !== target.flipY; - } - - /** - * Utility function to compensate the scale factor when skew is applied on both axes - * @private - */ - function compensateScaleForSkew(target, oppositeSkew, scaleToCompensate, axis, reference) { - if (target[oppositeSkew] !== 0) { - var newDim = target._getTransformedDimensions()[axis]; - var newValue = reference / newDim * target[scaleToCompensate]; - target.set(scaleToCompensate, newValue); - } - } - - /** - * Action handler for skewing on the X axis - * @private - */ - function skewObjectX(eventData, transform, x, y) { - var target = transform.target, - // find how big the object would be, if there was no skewX. takes in account scaling - dimNoSkew = target._getTransformedDimensions(0, target.skewY), - localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y), - // the mouse is in the center of the object, and we want it to stay there. - // so the object will grow twice as much as the mouse. - // this makes the skew growth to localPoint * 2 - dimNoSkew. - totalSkewSize = Math.abs(localPoint.x * 2) - dimNoSkew.x, - currentSkew = target.skewX, newSkew; - if (totalSkewSize < 2) { - // let's make it easy to go back to position 0. - newSkew = 0; - } - else { - newSkew = radiansToDegrees( - Math.atan2((totalSkewSize / target.scaleX), (dimNoSkew.y / target.scaleY)) - ); - // now we have to find the sign of the skew. - // it mostly depend on the origin of transformation. - if (transform.originX === LEFT && transform.originY === BOTTOM) { - newSkew = -newSkew; - } - if (transform.originX === RIGHT && transform.originY === TOP) { - newSkew = -newSkew; - } - if (targetHasOneFlip(target)) { - newSkew = -newSkew; - } - } - var hasSkewed = currentSkew !== newSkew; - if (hasSkewed) { - var dimBeforeSkewing = target._getTransformedDimensions().y; - target.set('skewX', newSkew); - compensateScaleForSkew(target, 'skewY', 'scaleY', 'y', dimBeforeSkewing); - } - return hasSkewed; - } - - /** - * Action handler for skewing on the Y axis - * @private - */ - function skewObjectY(eventData, transform, x, y) { - var target = transform.target, - // find how big the object would be, if there was no skewX. takes in account scaling - dimNoSkew = target._getTransformedDimensions(target.skewX, 0), - localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y), - // the mouse is in the center of the object, and we want it to stay there. - // so the object will grow twice as much as the mouse. - // this makes the skew growth to localPoint * 2 - dimNoSkew. - totalSkewSize = Math.abs(localPoint.y * 2) - dimNoSkew.y, - currentSkew = target.skewY, newSkew; - if (totalSkewSize < 2) { - // let's make it easy to go back to position 0. - newSkew = 0; - } - else { - newSkew = radiansToDegrees( - Math.atan2((totalSkewSize / target.scaleY), (dimNoSkew.x / target.scaleX)) - ); - // now we have to find the sign of the skew. - // it mostly depend on the origin of transformation. - if (transform.originX === LEFT && transform.originY === BOTTOM) { - newSkew = -newSkew; - } - if (transform.originX === RIGHT && transform.originY === TOP) { - newSkew = -newSkew; - } - if (targetHasOneFlip(target)) { - newSkew = -newSkew; - } - } - var hasSkewed = currentSkew !== newSkew; - if (hasSkewed) { - var dimBeforeSkewing = target._getTransformedDimensions().x; - target.set('skewY', newSkew); - compensateScaleForSkew(target, 'skewX', 'scaleX', 'x', dimBeforeSkewing); - } - return hasSkewed; - } - - /** - * Wrapped Action handler for skewing on the Y axis, takes care of the - * skew direction and determine the correct transform origin for the anchor point - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - */ - function skewHandlerX(eventData, transform, x, y) { - // step1 figure out and change transform origin. - // if skewX > 0 and originY bottom we anchor on right - // if skewX > 0 and originY top we anchor on left - // if skewX < 0 and originY bottom we anchor on left - // if skewX < 0 and originY top we anchor on right - // if skewX is 0, we look for mouse position to understand where are we going. - var target = transform.target, currentSkew = target.skewX, originX, originY = transform.originY; - if (target.lockSkewingX) { - return false; - } - if (currentSkew === 0) { - var localPointFromCenter = getLocalPoint(transform, CENTER, CENTER, x, y); - if (localPointFromCenter.x > 0) { - // we are pulling right, anchor left; - originX = LEFT; - } - else { - // we are pulling right, anchor right - originX = RIGHT; - } - } - else { - if (currentSkew > 0) { - originX = originY === TOP ? LEFT : RIGHT; - } - if (currentSkew < 0) { - originX = originY === TOP ? RIGHT : LEFT; - } - // is the object flipped on one side only? swap the origin. - if (targetHasOneFlip(target)) { - originX = originX === LEFT ? RIGHT : LEFT; - } - } - - // once we have the origin, we find the anchor point - transform.originX = originX; - var finalHandler = wrapWithFireEvent('skewing', wrapWithFixedAnchor(skewObjectX)); - return finalHandler(eventData, transform, x, y); - } - - /** - * Wrapped Action handler for skewing on the Y axis, takes care of the - * skew direction and determine the correct transform origin for the anchor point - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - */ - function skewHandlerY(eventData, transform, x, y) { - // step1 figure out and change transform origin. - // if skewY > 0 and originX left we anchor on top - // if skewY > 0 and originX right we anchor on bottom - // if skewY < 0 and originX left we anchor on bottom - // if skewY < 0 and originX right we anchor on top - // if skewY is 0, we look for mouse position to understand where are we going. - var target = transform.target, currentSkew = target.skewY, originY, originX = transform.originX; - if (target.lockSkewingY) { - return false; - } - if (currentSkew === 0) { - var localPointFromCenter = getLocalPoint(transform, CENTER, CENTER, x, y); - if (localPointFromCenter.y > 0) { - // we are pulling down, anchor up; - originY = TOP; - } - else { - // we are pulling up, anchor down - originY = BOTTOM; - } - } - else { - if (currentSkew > 0) { - originY = originX === LEFT ? TOP : BOTTOM; - } - if (currentSkew < 0) { - originY = originX === LEFT ? BOTTOM : TOP; - } - // is the object flipped on one side only? swap the origin. - if (targetHasOneFlip(target)) { - originY = originY === TOP ? BOTTOM : TOP; - } - } - - // once we have the origin, we find the anchor point - transform.originY = originY; - var finalHandler = wrapWithFireEvent('skewing', wrapWithFixedAnchor(skewObjectY)); - return finalHandler(eventData, transform, x, y); - } - - /** - * Action handler for rotation and snapping, without anchor point. - * Needs to be wrapped with `wrapWithFixedAnchor` to be effective - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - * @private - */ - function rotationWithSnapping(eventData, transform, x, y) { - var t = transform, - target = t.target, - pivotPoint = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY); - - if (target.lockRotation) { - return false; - } - - var lastAngle = Math.atan2(t.ey - pivotPoint.y, t.ex - pivotPoint.x), - curAngle = Math.atan2(y - pivotPoint.y, x - pivotPoint.x), - angle = radiansToDegrees(curAngle - lastAngle + t.theta), - hasRotated = true; - - if (target.snapAngle > 0) { - var snapAngle = target.snapAngle, - snapThreshold = target.snapThreshold || snapAngle, - rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle, - leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle; - - if (Math.abs(angle - leftAngleLocked) < snapThreshold) { - angle = leftAngleLocked; - } - else if (Math.abs(angle - rightAngleLocked) < snapThreshold) { - angle = rightAngleLocked; - } - } - - // normalize angle to positive value - if (angle < 0) { - angle = 360 + angle; - } - angle %= 360; - - hasRotated = target.angle !== angle; - target.angle = angle; - return hasRotated; - } - - /** - * Basic scaling logic, reused with different constrain for scaling X,Y, freely or equally. - * Needs to be wrapped with `wrapWithFixedAnchor` to be effective - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @param {Object} options additional information for scaling - * @param {String} options.by 'x', 'y', 'equally' or '' to indicate type of scaling - * @return {Boolean} true if some change happened - * @private - */ - function scaleObject(eventData, transform, x, y, options) { - options = options || {}; - var target = transform.target, - lockScalingX = target.lockScalingX, lockScalingY = target.lockScalingY, - by = options.by, newPoint, scaleX, scaleY, dim, - scaleProportionally = scaleIsProportional(eventData, target), - forbidScaling = scalingIsForbidden(target, by, scaleProportionally), - signX, signY, gestureScale = transform.gestureScale; - - if (forbidScaling) { - return false; - } - if (gestureScale) { - scaleX = transform.scaleX * gestureScale; - scaleY = transform.scaleY * gestureScale; - } - else { - newPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y); - // use of sign: We use sign to detect change of direction of an action. sign usually change when - // we cross the origin point with the mouse. So a scale flip for example. There is an issue when scaling - // by center and scaling using one middle control ( default: mr, mt, ml, mb), the mouse movement can easily - // cross many time the origin point and flip the object. so we need a way to filter out the noise. - // This ternary here should be ok to filter out X scaling when we want Y only and vice versa. - signX = by !== 'y' ? sign(newPoint.x) : 1; - signY = by !== 'x' ? sign(newPoint.y) : 1; - if (!transform.signX) { - transform.signX = signX; - } - if (!transform.signY) { - transform.signY = signY; - } - - if (target.lockScalingFlip && - (transform.signX !== signX || transform.signY !== signY) - ) { - return false; - } - - dim = target._getTransformedDimensions(); - // missing detection of flip and logic to switch the origin - if (scaleProportionally && !by) { - // uniform scaling - var distance = Math.abs(newPoint.x) + Math.abs(newPoint.y), - original = transform.original, - originalDistance = Math.abs(dim.x * original.scaleX / target.scaleX) + - Math.abs(dim.y * original.scaleY / target.scaleY), - scale = distance / originalDistance; - scaleX = original.scaleX * scale; - scaleY = original.scaleY * scale; - } - else { - scaleX = Math.abs(newPoint.x * target.scaleX / dim.x); - scaleY = Math.abs(newPoint.y * target.scaleY / dim.y); - } - // if we are scaling by center, we need to double the scale - if (isTransformCentered(transform)) { - scaleX *= 2; - scaleY *= 2; - } - if (transform.signX !== signX && by !== 'y') { - transform.originX = opposite[transform.originX]; - scaleX *= -1; - transform.signX = signX; - } - if (transform.signY !== signY && by !== 'x') { - transform.originY = opposite[transform.originY]; - scaleY *= -1; - transform.signY = signY; - } - } - // minScale is taken are in the setter. - var oldScaleX = target.scaleX, oldScaleY = target.scaleY; - if (!by) { - !lockScalingX && target.set('scaleX', scaleX); - !lockScalingY && target.set('scaleY', scaleY); - } - else { - // forbidden cases already handled on top here. - by === 'x' && target.set('scaleX', scaleX); - by === 'y' && target.set('scaleY', scaleY); - } - return oldScaleX !== target.scaleX || oldScaleY !== target.scaleY; - } - - /** - * Generic scaling logic, to scale from corners either equally or freely. - * Needs to be wrapped with `wrapWithFixedAnchor` to be effective - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - */ - function scaleObjectFromCorner(eventData, transform, x, y) { - return scaleObject(eventData, transform, x, y); - } - - /** - * Scaling logic for the X axis. - * Needs to be wrapped with `wrapWithFixedAnchor` to be effective - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - */ - function scaleObjectX(eventData, transform, x, y) { - return scaleObject(eventData, transform, x, y , { by: 'x' }); - } - - /** - * Scaling logic for the Y axis. - * Needs to be wrapped with `wrapWithFixedAnchor` to be effective - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - */ - function scaleObjectY(eventData, transform, x, y) { - return scaleObject(eventData, transform, x, y , { by: 'y' }); - } - - /** - * Composed action handler to either scale Y or skew X - * Needs to be wrapped with `wrapWithFixedAnchor` to be effective - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - */ - function scalingYOrSkewingX(eventData, transform, x, y) { - // ok some safety needed here. - if (eventData[transform.target.canvas.altActionKey]) { - return controls.skewHandlerX(eventData, transform, x, y); - } - return controls.scalingY(eventData, transform, x, y); - } - - /** - * Composed action handler to either scale X or skew Y - * Needs to be wrapped with `wrapWithFixedAnchor` to be effective - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - */ - function scalingXOrSkewingY(eventData, transform, x, y) { - // ok some safety needed here. - if (eventData[transform.target.canvas.altActionKey]) { - return controls.skewHandlerY(eventData, transform, x, y); - } - return controls.scalingX(eventData, transform, x, y); - } - - /** - * Action handler to change textbox width - * Needs to be wrapped with `wrapWithFixedAnchor` to be effective - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - */ - function changeWidth(eventData, transform, x, y) { - var target = transform.target, localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y), - strokePadding = target.strokeWidth / (target.strokeUniform ? target.scaleX : 1), - multiplier = isTransformCentered(transform) ? 2 : 1, - oldWidth = target.width, - newWidth = Math.abs(localPoint.x * multiplier / target.scaleX) - strokePadding; - target.set('width', Math.max(newWidth, 0)); - return oldWidth !== newWidth; - } - - /** - * Action handler - * @private - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if the translation occurred - */ - function dragHandler(eventData, transform, x, y) { - var target = transform.target, - newLeft = x - transform.offsetX, - newTop = y - transform.offsetY, - moveX = !target.get('lockMovementX') && target.left !== newLeft, - moveY = !target.get('lockMovementY') && target.top !== newTop; - moveX && target.set('left', newLeft); - moveY && target.set('top', newTop); - if (moveX || moveY) { - fireEvent('moving', commonEventInfo(eventData, transform, x, y)); - } - return moveX || moveY; - } - - controls.scaleCursorStyleHandler = scaleCursorStyleHandler; - controls.skewCursorStyleHandler = skewCursorStyleHandler; - controls.scaleSkewCursorStyleHandler = scaleSkewCursorStyleHandler; - controls.rotationWithSnapping = wrapWithFireEvent('rotating', wrapWithFixedAnchor(rotationWithSnapping)); - controls.scalingEqually = wrapWithFireEvent('scaling', wrapWithFixedAnchor( scaleObjectFromCorner)); - controls.scalingX = wrapWithFireEvent('scaling', wrapWithFixedAnchor(scaleObjectX)); - controls.scalingY = wrapWithFireEvent('scaling', wrapWithFixedAnchor(scaleObjectY)); - controls.scalingYOrSkewingX = scalingYOrSkewingX; - controls.scalingXOrSkewingY = scalingXOrSkewingY; - controls.changeWidth = wrapWithFireEvent('resizing', wrapWithFixedAnchor(changeWidth)); - controls.skewHandlerX = skewHandlerX; - controls.skewHandlerY = skewHandlerY; - controls.dragHandler = dragHandler; - controls.scaleOrSkewActionName = scaleOrSkewActionName; - controls.rotationStyleHandler = rotationStyleHandler; - controls.fireEvent = fireEvent; - controls.wrapWithFixedAnchor = wrapWithFixedAnchor; - controls.wrapWithFireEvent = wrapWithFireEvent; - controls.getLocalPoint = getLocalPoint; - fabric.controlsUtils = controls; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - degreesToRadians = fabric.util.degreesToRadians, - controls = fabric.controlsUtils; - - /** - * Render a round control, as per fabric features. - * This function is written to respect object properties like transparentCorners, cornerSize - * cornerColor, cornerStrokeColor - * plus the addition of offsetY and offsetX. - * @param {CanvasRenderingContext2D} ctx context to render on - * @param {Number} left x coordinate where the control center should be - * @param {Number} top y coordinate where the control center should be - * @param {Object} styleOverride override for fabric.Object controls style - * @param {fabric.Object} fabricObject the fabric object for which we are rendering controls - */ - function renderCircleControl (ctx, left, top, styleOverride, fabricObject) { - styleOverride = styleOverride || {}; - var xSize = this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize, - ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize, - transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ? - styleOverride.transparentCorners : fabricObject.transparentCorners, - methodName = transparentCorners ? 'stroke' : 'fill', - stroke = !transparentCorners && (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor), - myLeft = left, - myTop = top, size; - ctx.save(); - ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor; - ctx.strokeStyle = styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor; - // as soon as fabric react v5, remove ie11, use proper ellipse code. - if (xSize > ySize) { - size = xSize; - ctx.scale(1.0, ySize / xSize); - myTop = top * xSize / ySize; - } - else if (ySize > xSize) { - size = ySize; - ctx.scale(xSize / ySize, 1.0); - myLeft = left * ySize / xSize; - } - else { - size = xSize; - } - // this is still wrong - ctx.lineWidth = 1; - ctx.beginPath(); - ctx.arc(myLeft, myTop, size / 2, 0, 2 * Math.PI, false); - ctx[methodName](); - if (stroke) { - ctx.stroke(); - } - ctx.restore(); - } - - /** - * Render a square control, as per fabric features. - * This function is written to respect object properties like transparentCorners, cornerSize - * cornerColor, cornerStrokeColor - * plus the addition of offsetY and offsetX. - * @param {CanvasRenderingContext2D} ctx context to render on - * @param {Number} left x coordinate where the control center should be - * @param {Number} top y coordinate where the control center should be - * @param {Object} styleOverride override for fabric.Object controls style - * @param {fabric.Object} fabricObject the fabric object for which we are rendering controls - */ - function renderSquareControl(ctx, left, top, styleOverride, fabricObject) { - styleOverride = styleOverride || {}; - var xSize = this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize, - ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize, - transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ? - styleOverride.transparentCorners : fabricObject.transparentCorners, - methodName = transparentCorners ? 'stroke' : 'fill', - stroke = !transparentCorners && ( - styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor - ), xSizeBy2 = xSize / 2, ySizeBy2 = ySize / 2; - ctx.save(); - ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor; - ctx.strokeStyle = styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor; - // this is still wrong - ctx.lineWidth = 1; - ctx.translate(left, top); - ctx.rotate(degreesToRadians(fabricObject.angle)); - // this does not work, and fixed with ( && ) does not make sense. - // to have real transparent corners we need the controls on upperCanvas - // transparentCorners || ctx.clearRect(-xSizeBy2, -ySizeBy2, xSize, ySize); - ctx[methodName + 'Rect'](-xSizeBy2, -ySizeBy2, xSize, ySize); - if (stroke) { - ctx.strokeRect(-xSizeBy2, -ySizeBy2, xSize, ySize); - } - ctx.restore(); - } - - controls.renderCircleControl = renderCircleControl; - controls.renderSquareControl = renderSquareControl; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }); - - function Control(options) { - for (var i in options) { - this[i] = options[i]; - } - } - - fabric.Control = Control; - - fabric.Control.prototype = /** @lends fabric.Control.prototype */ { - - /** - * keep track of control visibility. - * mainly for backward compatibility. - * if you do not want to see a control, you can remove it - * from the controlset. - * @type {Boolean} - * @default true - */ - visible: true, - - /** - * Name of the action that the control will likely execute. - * This is optional. FabricJS uses to identify what the user is doing for some - * extra optimizations. If you are writing a custom control and you want to know - * somewhere else in the code what is going on, you can use this string here. - * you can also provide a custom getActionName if your control run multiple actions - * depending on some external state. - * default to scale since is the most common, used on 4 corners by default - * @type {String} - * @default 'scale' - */ - actionName: 'scale', - - /** - * Drawing angle of the control. - * NOT used for now, but name marked as needed for internal logic - * example: to reuse the same drawing function for different rotated controls - * @type {Number} - * @default 0 - */ - angle: 0, - - /** - * Relative position of the control. X - * 0,0 is the center of the Object, while -0.5 (left) or 0.5 (right) are the extremities - * of the bounding box. - * @type {Number} - * @default 0 - */ - x: 0, - - /** - * Relative position of the control. Y - * 0,0 is the center of the Object, while -0.5 (top) or 0.5 (bottom) are the extremities - * of the bounding box. - * @type {Number} - * @default 0 - */ - y: 0, - - /** - * Horizontal offset of the control from the defined position. In pixels - * Positive offset moves the control to the right, negative to the left. - * It used when you want to have position of control that does not scale with - * the bounding box. Example: rotation control is placed at x:0, y: 0.5 on - * the boundindbox, with an offset of 30 pixels vertically. Those 30 pixels will - * stay 30 pixels no matter how the object is big. Another example is having 2 - * controls in the corner, that stay in the same position when the object scale. - * of the bounding box. - * @type {Number} - * @default 0 - */ - offsetX: 0, - - /** - * Vertical offset of the control from the defined position. In pixels - * Positive offset moves the control to the bottom, negative to the top. - * @type {Number} - * @default 0 - */ - offsetY: 0, - - /** - * Sets the length of the control. If null, defaults to object's cornerSize. - * Expects both sizeX and sizeY to be set when set. - * @type {?Number} - * @default null - */ - sizeX: null, - - /** - * Sets the height of the control. If null, defaults to object's cornerSize. - * Expects both sizeX and sizeY to be set when set. - * @type {?Number} - * @default null - */ - sizeY: null, - - /** - * Sets the length of the touch area of the control. If null, defaults to object's touchCornerSize. - * Expects both touchSizeX and touchSizeY to be set when set. - * @type {?Number} - * @default null - */ - touchSizeX: null, - - /** - * Sets the height of the touch area of the control. If null, defaults to object's touchCornerSize. - * Expects both touchSizeX and touchSizeY to be set when set. - * @type {?Number} - * @default null - */ - touchSizeY: null, - - /** - * Css cursor style to display when the control is hovered. - * if the method `cursorStyleHandler` is provided, this property is ignored. - * @type {String} - * @default 'crosshair' - */ - cursorStyle: 'crosshair', - - /** - * If controls has an offsetY or offsetX, draw a line that connects - * the control to the bounding box - * @type {Boolean} - * @default false - */ - withConnection: false, - - /** - * The control actionHandler, provide one to handle action ( control being moved ) - * @param {Event} eventData the native mouse event - * @param {Object} transformData properties of the current transform - * @param {Number} x x position of the cursor - * @param {Number} y y position of the cursor - * @return {Boolean} true if the action/event modified the object - */ - actionHandler: function(/* eventData, transformData, x, y */) { }, - - /** - * The control handler for mouse down, provide one to handle mouse down on control - * @param {Event} eventData the native mouse event - * @param {Object} transformData properties of the current transform - * @param {Number} x x position of the cursor - * @param {Number} y y position of the cursor - * @return {Boolean} true if the action/event modified the object - */ - mouseDownHandler: function(/* eventData, transformData, x, y */) { }, - - /** - * The control mouseUpHandler, provide one to handle an effect on mouse up. - * @param {Event} eventData the native mouse event - * @param {Object} transformData properties of the current transform - * @param {Number} x x position of the cursor - * @param {Number} y y position of the cursor - * @return {Boolean} true if the action/event modified the object - */ - mouseUpHandler: function(/* eventData, transformData, x, y */) { }, - - /** - * Returns control actionHandler - * @param {Event} eventData the native mouse event - * @param {fabric.Object} fabricObject on which the control is displayed - * @param {fabric.Control} control control for which the action handler is being asked - * @return {Function} the action handler - */ - getActionHandler: function(/* eventData, fabricObject, control */) { - return this.actionHandler; - }, - - /** - * Returns control mouseDown handler - * @param {Event} eventData the native mouse event - * @param {fabric.Object} fabricObject on which the control is displayed - * @param {fabric.Control} control control for which the action handler is being asked - * @return {Function} the action handler - */ - getMouseDownHandler: function(/* eventData, fabricObject, control */) { - return this.mouseDownHandler; - }, - - /** - * Returns control mouseUp handler - * @param {Event} eventData the native mouse event - * @param {fabric.Object} fabricObject on which the control is displayed - * @param {fabric.Control} control control for which the action handler is being asked - * @return {Function} the action handler - */ - getMouseUpHandler: function(/* eventData, fabricObject, control */) { - return this.mouseUpHandler; - }, - - /** - * Returns control cursorStyle for css using cursorStyle. If you need a more elaborate - * function you can pass one in the constructor - * the cursorStyle property - * @param {Event} eventData the native mouse event - * @param {fabric.Control} control the current control ( likely this) - * @param {fabric.Object} object on which the control is displayed - * @return {String} - */ - cursorStyleHandler: function(eventData, control /* fabricObject */) { - return control.cursorStyle; - }, - - /** - * Returns the action name. The basic implementation just return the actionName property. - * @param {Event} eventData the native mouse event - * @param {fabric.Control} control the current control ( likely this) - * @param {fabric.Object} object on which the control is displayed - * @return {String} - */ - getActionName: function(eventData, control /* fabricObject */) { - return control.actionName; - }, - - /** - * Returns controls visibility - * @param {fabric.Object} object on which the control is displayed - * @param {String} controlKey key where the control is memorized on the - * @return {Boolean} - */ - getVisibility: function(fabricObject, controlKey) { - var objectVisibility = fabricObject._controlsVisibility; - if (objectVisibility && typeof objectVisibility[controlKey] !== 'undefined') { - return objectVisibility[controlKey]; - } - return this.visible; - }, - - /** - * Sets controls visibility - * @param {Boolean} visibility for the object - * @return {Void} - */ - setVisibility: function(visibility /* name, fabricObject */) { - this.visible = visibility; - }, - - - positionHandler: function(dim, finalMatrix /*, fabricObject, currentControl */) { - var point = fabric.util.transformPoint({ - x: this.x * dim.x + this.offsetX, - y: this.y * dim.y + this.offsetY }, finalMatrix); - return point; - }, - - /** - * Returns the coords for this control based on object values. - * @param {Number} objectAngle angle from the fabric object holding the control - * @param {Number} objectCornerSize cornerSize from the fabric object holding the control (or touchCornerSize if - * isTouch is true) - * @param {Number} centerX x coordinate where the control center should be - * @param {Number} centerY y coordinate where the control center should be - * @param {boolean} isTouch true if touch corner, false if normal corner - */ - calcCornerCoords: function(objectAngle, objectCornerSize, centerX, centerY, isTouch) { - var cosHalfOffset, - sinHalfOffset, - cosHalfOffsetComp, - sinHalfOffsetComp, - xSize = (isTouch) ? this.touchSizeX : this.sizeX, - ySize = (isTouch) ? this.touchSizeY : this.sizeY; - if (xSize && ySize && xSize !== ySize) { - // handle rectangular corners - var controlTriangleAngle = Math.atan2(ySize, xSize); - var cornerHypotenuse = Math.sqrt(xSize * xSize + ySize * ySize) / 2; - var newTheta = controlTriangleAngle - fabric.util.degreesToRadians(objectAngle); - var newThetaComp = Math.PI / 2 - controlTriangleAngle - fabric.util.degreesToRadians(objectAngle); - cosHalfOffset = cornerHypotenuse * fabric.util.cos(newTheta); - sinHalfOffset = cornerHypotenuse * fabric.util.sin(newTheta); - // use complementary angle for two corners - cosHalfOffsetComp = cornerHypotenuse * fabric.util.cos(newThetaComp); - sinHalfOffsetComp = cornerHypotenuse * fabric.util.sin(newThetaComp); - } - else { - // handle square corners - // use default object corner size unless size is defined - var cornerSize = (xSize && ySize) ? xSize : objectCornerSize; - /* 0.7071067812 stands for sqrt(2)/2 */ - cornerHypotenuse = cornerSize * 0.7071067812; - // complementary angles are equal since they're both 45 degrees - var newTheta = fabric.util.degreesToRadians(45 - objectAngle); - cosHalfOffset = cosHalfOffsetComp = cornerHypotenuse * fabric.util.cos(newTheta); - sinHalfOffset = sinHalfOffsetComp = cornerHypotenuse * fabric.util.sin(newTheta); - } - - return { - tl: { - x: centerX - sinHalfOffsetComp, - y: centerY - cosHalfOffsetComp, - }, - tr: { - x: centerX + cosHalfOffset, - y: centerY - sinHalfOffset, - }, - bl: { - x: centerX - cosHalfOffset, - y: centerY + sinHalfOffset, - }, - br: { - x: centerX + sinHalfOffsetComp, - y: centerY + cosHalfOffsetComp, - }, - }; - }, - - /** - * Render function for the control. - * When this function runs the context is unscaled. unrotate. Just retina scaled. - * all the functions will have to translate to the point left,top before starting Drawing - * if they want to draw a control where the position is detected. - * left and top are the result of the positionHandler function - * @param {RenderingContext2D} ctx the context where the control will be drawn - * @param {Number} left position of the canvas where we are about to render the control. - * @param {Number} top position of the canvas where we are about to render the control. - * @param {Object} styleOverride - * @param {fabric.Object} fabricObject the object where the control is about to be rendered - */ - render: function(ctx, left, top, styleOverride, fabricObject) { - styleOverride = styleOverride || {}; - switch (styleOverride.cornerStyle || fabricObject.cornerStyle) { - case 'circle': - fabric.controlsUtils.renderCircleControl.call(this, ctx, left, top, styleOverride, fabricObject); - break; - default: - fabric.controlsUtils.renderSquareControl.call(this, ctx, left, top, styleOverride, fabricObject); - } - }, - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function() { - - /* _FROM_SVG_START_ */ - function getColorStop(el, multiplier) { - var style = el.getAttribute('style'), - offset = el.getAttribute('offset') || 0, - color, colorAlpha, opacity, i; - - // convert percents to absolute values - offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1); - offset = offset < 0 ? 0 : offset > 1 ? 1 : offset; - if (style) { - var keyValuePairs = style.split(/\s*;\s*/); - - if (keyValuePairs[keyValuePairs.length - 1] === '') { - keyValuePairs.pop(); - } - - for (i = keyValuePairs.length; i--; ) { - - var split = keyValuePairs[i].split(/\s*:\s*/), - key = split[0].trim(), - value = split[1].trim(); - - if (key === 'stop-color') { - color = value; - } - else if (key === 'stop-opacity') { - opacity = value; - } - } - } - - if (!color) { - color = el.getAttribute('stop-color') || 'rgb(0,0,0)'; - } - if (!opacity) { - opacity = el.getAttribute('stop-opacity'); - } - - color = new fabric.Color(color); - colorAlpha = color.getAlpha(); - opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity); - opacity *= colorAlpha * multiplier; - - return { - offset: offset, - color: color.toRgb(), - opacity: opacity - }; - } - - function getLinearCoords(el) { - return { - x1: el.getAttribute('x1') || 0, - y1: el.getAttribute('y1') || 0, - x2: el.getAttribute('x2') || '100%', - y2: el.getAttribute('y2') || 0 - }; - } - - function getRadialCoords(el) { - return { - x1: el.getAttribute('fx') || el.getAttribute('cx') || '50%', - y1: el.getAttribute('fy') || el.getAttribute('cy') || '50%', - r1: 0, - x2: el.getAttribute('cx') || '50%', - y2: el.getAttribute('cy') || '50%', - r2: el.getAttribute('r') || '50%' - }; - } - /* _FROM_SVG_END_ */ - - var clone = fabric.util.object.clone; - - /** - * Gradient class - * @class fabric.Gradient - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients} - * @see {@link fabric.Gradient#initialize} for constructor definition - */ - fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ { - - /** - * Horizontal offset for aligning gradients coming from SVG when outside pathgroups - * @type Number - * @default 0 - */ - offsetX: 0, - - /** - * Vertical offset for aligning gradients coming from SVG when outside pathgroups - * @type Number - * @default 0 - */ - offsetY: 0, - - /** - * A transform matrix to apply to the gradient before painting. - * Imported from svg gradients, is not applied with the current transform in the center. - * Before this transform is applied, the origin point is at the top left corner of the object - * plus the addition of offsetY and offsetX. - * @type Number[] - * @default null - */ - gradientTransform: null, - - /** - * coordinates units for coords. - * If `pixels`, the number of coords are in the same unit of width / height. - * If set as `percentage` the coords are still a number, but 1 means 100% of width - * for the X and 100% of the height for the y. It can be bigger than 1 and negative. - * allowed values pixels or percentage. - * @type String - * @default 'pixels' - */ - gradientUnits: 'pixels', - - /** - * Gradient type linear or radial - * @type String - * @default 'pixels' - */ - type: 'linear', - - /** - * Constructor - * @param {Object} options Options object with type, coords, gradientUnits and colorStops - * @param {Object} [options.type] gradient type linear or radial - * @param {Object} [options.gradientUnits] gradient units - * @param {Object} [options.offsetX] SVG import compatibility - * @param {Object} [options.offsetY] SVG import compatibility - * @param {Object[]} options.colorStops contains the colorstops. - * @param {Object} options.coords contains the coords of the gradient - * @param {Number} [options.coords.x1] X coordiante of the first point for linear or of the focal point for radial - * @param {Number} [options.coords.y1] Y coordiante of the first point for linear or of the focal point for radial - * @param {Number} [options.coords.x2] X coordiante of the second point for linear or of the center point for radial - * @param {Number} [options.coords.y2] Y coordiante of the second point for linear or of the center point for radial - * @param {Number} [options.coords.r1] only for radial gradient, radius of the inner circle - * @param {Number} [options.coords.r2] only for radial gradient, radius of the external circle - * @return {fabric.Gradient} thisArg - */ - initialize: function(options) { - options || (options = { }); - options.coords || (options.coords = { }); - - var coords, _this = this; - - // sets everything, then coords and colorstops get sets again - Object.keys(options).forEach(function(option) { - _this[option] = options[option]; - }); - - if (this.id) { - this.id += '_' + fabric.Object.__uid++; - } - else { - this.id = fabric.Object.__uid++; - } - - coords = { - x1: options.coords.x1 || 0, - y1: options.coords.y1 || 0, - x2: options.coords.x2 || 0, - y2: options.coords.y2 || 0 - }; - - if (this.type === 'radial') { - coords.r1 = options.coords.r1 || 0; - coords.r2 = options.coords.r2 || 0; - } - - this.coords = coords; - this.colorStops = options.colorStops.slice(); - }, - - /** - * Adds another colorStop - * @param {Object} colorStop Object with offset and color - * @return {fabric.Gradient} thisArg - */ - addColorStop: function(colorStops) { - for (var position in colorStops) { - var color = new fabric.Color(colorStops[position]); - this.colorStops.push({ - offset: parseFloat(position), - color: color.toRgb(), - opacity: color.getAlpha() - }); - } - return this; - }, - - /** - * Returns object representation of a gradient - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} - */ - toObject: function(propertiesToInclude) { - var object = { - type: this.type, - coords: this.coords, - colorStops: this.colorStops, - offsetX: this.offsetX, - offsetY: this.offsetY, - gradientUnits: this.gradientUnits, - gradientTransform: this.gradientTransform ? this.gradientTransform.concat() : this.gradientTransform - }; - fabric.util.populateWithProperties(this, object, propertiesToInclude); - - return object; - }, - - /* _TO_SVG_START_ */ - /** - * Returns SVG representation of an gradient - * @param {Object} object Object to create a gradient for - * @return {String} SVG representation of an gradient (linear/radial) - */ - toSVG: function(object, options) { - var coords = clone(this.coords, true), i, len, options = options || {}, - markup, commonAttributes, colorStops = clone(this.colorStops, true), - needsSwap = coords.r1 > coords.r2, - transform = this.gradientTransform ? this.gradientTransform.concat() : fabric.iMatrix.concat(), - offsetX = -this.offsetX, offsetY = -this.offsetY, - withViewport = !!options.additionalTransform, - gradientUnits = this.gradientUnits === 'pixels' ? 'userSpaceOnUse' : 'objectBoundingBox'; - // colorStops must be sorted ascending - colorStops.sort(function(a, b) { - return a.offset - b.offset; - }); - - if (gradientUnits === 'objectBoundingBox') { - offsetX /= object.width; - offsetY /= object.height; - } - else { - offsetX += object.width / 2; - offsetY += object.height / 2; - } - if (object.type === 'path' && this.gradientUnits !== 'percentage') { - offsetX -= object.pathOffset.x; - offsetY -= object.pathOffset.y; - } - - - transform[4] -= offsetX; - transform[5] -= offsetY; - - commonAttributes = 'id="SVGID_' + this.id + - '" gradientUnits="' + gradientUnits + '"'; - commonAttributes += ' gradientTransform="' + (withViewport ? - options.additionalTransform + ' ' : '') + fabric.util.matrixToSVG(transform) + '" '; - - if (this.type === 'linear') { - markup = [ - '\n' - ]; - } - else if (this.type === 'radial') { - // svg radial gradient has just 1 radius. the biggest. - markup = [ - '\n' - ]; - } - - if (this.type === 'radial') { - if (needsSwap) { - // svg goes from internal to external radius. if radius are inverted, swap color stops. - colorStops = colorStops.concat(); - colorStops.reverse(); - for (i = 0, len = colorStops.length; i < len; i++) { - colorStops[i].offset = 1 - colorStops[i].offset; - } - } - var minRadius = Math.min(coords.r1, coords.r2); - if (minRadius > 0) { - // i have to shift all colorStops and add new one in 0. - var maxRadius = Math.max(coords.r1, coords.r2), - percentageShift = minRadius / maxRadius; - for (i = 0, len = colorStops.length; i < len; i++) { - colorStops[i].offset += percentageShift * (1 - colorStops[i].offset); - } - } - } - - for (i = 0, len = colorStops.length; i < len; i++) { - var colorStop = colorStops[i]; - markup.push( - '\n' - ); - } - - markup.push((this.type === 'linear' ? '\n' : '\n')); - - return markup.join(''); - }, - /* _TO_SVG_END_ */ - - /** - * Returns an instance of CanvasGradient - * @param {CanvasRenderingContext2D} ctx Context to render on - * @return {CanvasGradient} - */ - toLive: function(ctx) { - var gradient, coords = fabric.util.object.clone(this.coords), i, len; - - if (!this.type) { - return; - } - - if (this.type === 'linear') { - gradient = ctx.createLinearGradient( - coords.x1, coords.y1, coords.x2, coords.y2); - } - else if (this.type === 'radial') { - gradient = ctx.createRadialGradient( - coords.x1, coords.y1, coords.r1, coords.x2, coords.y2, coords.r2); - } - - for (i = 0, len = this.colorStops.length; i < len; i++) { - var color = this.colorStops[i].color, - opacity = this.colorStops[i].opacity, - offset = this.colorStops[i].offset; - - if (typeof opacity !== 'undefined') { - color = new fabric.Color(color).setAlpha(opacity).toRgba(); - } - gradient.addColorStop(offset, color); - } - - return gradient; - } - }); - - fabric.util.object.extend(fabric.Gradient, { - - /* _FROM_SVG_START_ */ - /** - * Returns {@link fabric.Gradient} instance from an SVG element - * @static - * @memberOf fabric.Gradient - * @param {SVGGradientElement} el SVG gradient element - * @param {fabric.Object} instance - * @param {String} opacityAttr A fill-opacity or stroke-opacity attribute to multiply to each stop's opacity. - * @param {Object} svgOptions an object containing the size of the SVG in order to parse correctly gradients - * that uses gradientUnits as 'userSpaceOnUse' and percentages. - * @param {Object.number} viewBoxWidth width part of the viewBox attribute on svg - * @param {Object.number} viewBoxHeight height part of the viewBox attribute on svg - * @param {Object.number} width width part of the svg tag if viewBox is not specified - * @param {Object.number} height height part of the svg tag if viewBox is not specified - * @return {fabric.Gradient} Gradient instance - * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement - * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement - */ - fromElement: function(el, instance, opacityAttr, svgOptions) { - /** - * @example: - * - * - * - * - * - * - * OR - * - * - * - * - * - * - * OR - * - * - * - * - * - * - * - * OR - * - * - * - * - * - * - * - */ - - var multiplier = parseFloat(opacityAttr) / (/%$/.test(opacityAttr) ? 100 : 1); - multiplier = multiplier < 0 ? 0 : multiplier > 1 ? 1 : multiplier; - if (isNaN(multiplier)) { - multiplier = 1; - } - - var colorStopEls = el.getElementsByTagName('stop'), - type, - gradientUnits = el.getAttribute('gradientUnits') === 'userSpaceOnUse' ? - 'pixels' : 'percentage', - gradientTransform = el.getAttribute('gradientTransform') || '', - colorStops = [], - coords, i, offsetX = 0, offsetY = 0, - transformMatrix; - if (el.nodeName === 'linearGradient' || el.nodeName === 'LINEARGRADIENT') { - type = 'linear'; - coords = getLinearCoords(el); - } - else { - type = 'radial'; - coords = getRadialCoords(el); - } - - for (i = colorStopEls.length; i--; ) { - colorStops.push(getColorStop(colorStopEls[i], multiplier)); - } - - transformMatrix = fabric.parseTransformAttribute(gradientTransform); - - __convertPercentUnitsToValues(instance, coords, svgOptions, gradientUnits); - - if (gradientUnits === 'pixels') { - offsetX = -instance.left; - offsetY = -instance.top; - } - - var gradient = new fabric.Gradient({ - id: el.getAttribute('id'), - type: type, - coords: coords, - colorStops: colorStops, - gradientUnits: gradientUnits, - gradientTransform: transformMatrix, - offsetX: offsetX, - offsetY: offsetY, - }); - - return gradient; - } - /* _FROM_SVG_END_ */ - }); - - /** - * @private - */ - function __convertPercentUnitsToValues(instance, options, svgOptions, gradientUnits) { - var propValue, finalValue; - Object.keys(options).forEach(function(prop) { - propValue = options[prop]; - if (propValue === 'Infinity') { - finalValue = 1; - } - else if (propValue === '-Infinity') { - finalValue = 0; - } - else { - finalValue = parseFloat(options[prop], 10); - if (typeof propValue === 'string' && /^(\d+\.\d+)%|(\d+)%$/.test(propValue)) { - finalValue *= 0.01; - if (gradientUnits === 'pixels') { - // then we need to fix those percentages here in svg parsing - if (prop === 'x1' || prop === 'x2' || prop === 'r2') { - finalValue *= svgOptions.viewBoxWidth || svgOptions.width; - } - if (prop === 'y1' || prop === 'y2') { - finalValue *= svgOptions.viewBoxHeight || svgOptions.height; - } - } - } - } - options[prop] = finalValue; - }); - } -})(); - - -(function() { - - 'use strict'; - - var toFixed = fabric.util.toFixed; - - /** - * Pattern class - * @class fabric.Pattern - * @see {@link http://fabricjs.com/patterns|Pattern demo} - * @see {@link http://fabricjs.com/dynamic-patterns|DynamicPattern demo} - * @see {@link fabric.Pattern#initialize} for constructor definition - */ - - - fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ { - - /** - * Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat) - * @type String - * @default - */ - repeat: 'repeat', - - /** - * Pattern horizontal offset from object's left/top corner - * @type Number - * @default - */ - offsetX: 0, - - /** - * Pattern vertical offset from object's left/top corner - * @type Number - * @default - */ - offsetY: 0, - - /** - * crossOrigin value (one of "", "anonymous", "use-credentials") - * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes - * @type String - * @default - */ - crossOrigin: '', - - /** - * transform matrix to change the pattern, imported from svgs. - * @type Array - * @default - */ - patternTransform: null, - - /** - * Constructor - * @param {Object} [options] Options object - * @param {Function} [callback] function to invoke after callback init. - * @return {fabric.Pattern} thisArg - */ - initialize: function(options, callback) { - options || (options = { }); - - this.id = fabric.Object.__uid++; - this.setOptions(options); - if (!options.source || (options.source && typeof options.source !== 'string')) { - callback && callback(this); - return; - } - else { - // img src string - var _this = this; - this.source = fabric.util.createImage(); - fabric.util.loadImage(options.source, function(img, isError) { - _this.source = img; - callback && callback(_this, isError); - }, null, this.crossOrigin); - } - }, - - /** - * Returns object representation of a pattern - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of a pattern instance - */ - toObject: function(propertiesToInclude) { - var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, - source, object; - - // element - if (typeof this.source.src === 'string') { - source = this.source.src; - } - // element - else if (typeof this.source === 'object' && this.source.toDataURL) { - source = this.source.toDataURL(); - } - - object = { - type: 'pattern', - source: source, - repeat: this.repeat, - crossOrigin: this.crossOrigin, - offsetX: toFixed(this.offsetX, NUM_FRACTION_DIGITS), - offsetY: toFixed(this.offsetY, NUM_FRACTION_DIGITS), - patternTransform: this.patternTransform ? this.patternTransform.concat() : null - }; - fabric.util.populateWithProperties(this, object, propertiesToInclude); - - return object; - }, - - /* _TO_SVG_START_ */ - /** - * Returns SVG representation of a pattern - * @param {fabric.Object} object - * @return {String} SVG representation of a pattern - */ - toSVG: function(object) { - var patternSource = typeof this.source === 'function' ? this.source() : this.source, - patternWidth = patternSource.width / object.width, - patternHeight = patternSource.height / object.height, - patternOffsetX = this.offsetX / object.width, - patternOffsetY = this.offsetY / object.height, - patternImgSrc = ''; - if (this.repeat === 'repeat-x' || this.repeat === 'no-repeat') { - patternHeight = 1; - if (patternOffsetY) { - patternHeight += Math.abs(patternOffsetY); - } - } - if (this.repeat === 'repeat-y' || this.repeat === 'no-repeat') { - patternWidth = 1; - if (patternOffsetX) { - patternWidth += Math.abs(patternOffsetX); - } - - } - if (patternSource.src) { - patternImgSrc = patternSource.src; - } - else if (patternSource.toDataURL) { - patternImgSrc = patternSource.toDataURL(); - } - - return '\n' + - '\n' + - '\n'; - }, - /* _TO_SVG_END_ */ - - setOptions: function(options) { - for (var prop in options) { - this[prop] = options[prop]; - } - }, - - /** - * Returns an instance of CanvasPattern - * @param {CanvasRenderingContext2D} ctx Context to create pattern - * @return {CanvasPattern} - */ - toLive: function(ctx) { - var source = this.source; - // if the image failed to load, return, and allow rest to continue loading - if (!source) { - return ''; - } - - // if an image - if (typeof source.src !== 'undefined') { - if (!source.complete) { - return ''; - } - if (source.naturalWidth === 0 || source.naturalHeight === 0) { - return ''; - } - } - return ctx.createPattern(source, this.repeat); - } - }); -})(); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - toFixed = fabric.util.toFixed; - - if (fabric.Shadow) { - fabric.warn('fabric.Shadow is already defined.'); - return; - } - - /** - * Shadow class - * @class fabric.Shadow - * @see {@link http://fabricjs.com/shadows|Shadow demo} - * @see {@link fabric.Shadow#initialize} for constructor definition - */ - fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { - - /** - * Shadow color - * @type String - * @default - */ - color: 'rgb(0,0,0)', - - /** - * Shadow blur - * @type Number - */ - blur: 0, - - /** - * Shadow horizontal offset - * @type Number - * @default - */ - offsetX: 0, - - /** - * Shadow vertical offset - * @type Number - * @default - */ - offsetY: 0, - - /** - * Whether the shadow should affect stroke operations - * @type Boolean - * @default - */ - affectStroke: false, - - /** - * Indicates whether toObject should include default values - * @type Boolean - * @default - */ - includeDefaultValues: true, - - /** - * When `false`, the shadow will scale with the object. - * When `true`, the shadow's offsetX, offsetY, and blur will not be affected by the object's scale. - * default to false - * @type Boolean - * @default - */ - nonScaling: false, - - /** - * Constructor - * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetY properties or string (e.g. "rgba(0,0,0,0.2) 2px 2px 10px") - * @return {fabric.Shadow} thisArg - */ - initialize: function(options) { - - if (typeof options === 'string') { - options = this._parseShadow(options); - } - - for (var prop in options) { - this[prop] = options[prop]; - } - - this.id = fabric.Object.__uid++; - }, - - /** - * @private - * @param {String} shadow Shadow value to parse - * @return {Object} Shadow object with color, offsetX, offsetY and blur - */ - _parseShadow: function(shadow) { - var shadowStr = shadow.trim(), - offsetsAndBlur = fabric.Shadow.reOffsetsAndBlur.exec(shadowStr) || [], - color = shadowStr.replace(fabric.Shadow.reOffsetsAndBlur, '') || 'rgb(0,0,0)'; - - return { - color: color.trim(), - offsetX: parseFloat(offsetsAndBlur[1], 10) || 0, - offsetY: parseFloat(offsetsAndBlur[2], 10) || 0, - blur: parseFloat(offsetsAndBlur[3], 10) || 0 - }; - }, - - /** - * Returns a string representation of an instance - * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow - * @return {String} Returns CSS3 text-shadow declaration - */ - toString: function() { - return [this.offsetX, this.offsetY, this.blur, this.color].join('px '); - }, - - /* _TO_SVG_START_ */ - /** - * Returns SVG representation of a shadow - * @param {fabric.Object} object - * @return {String} SVG representation of a shadow - */ - toSVG: function(object) { - var fBoxX = 40, fBoxY = 40, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, - offset = fabric.util.rotateVector( - { x: this.offsetX, y: this.offsetY }, - fabric.util.degreesToRadians(-object.angle)), - BLUR_BOX = 20, color = new fabric.Color(this.color); - - if (object.width && object.height) { - //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion - // we add some extra space to filter box to contain the blur ( 20 ) - fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX; - fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX; - } - if (object.flipX) { - offset.x *= -1; - } - if (object.flipY) { - offset.y *= -1; - } - - return ( - '\n' + - '\t\n' + - '\t\n' + - '\t\n' + - '\t\n' + - '\t\n' + - '\t\t\n' + - '\t\t\n' + - '\t\n' + - '\n'); - }, - /* _TO_SVG_END_ */ - - /** - * Returns object representation of a shadow - * @return {Object} Object representation of a shadow instance - */ - toObject: function() { - if (this.includeDefaultValues) { - return { - color: this.color, - blur: this.blur, - offsetX: this.offsetX, - offsetY: this.offsetY, - affectStroke: this.affectStroke, - nonScaling: this.nonScaling - }; - } - var obj = { }, proto = fabric.Shadow.prototype; - - ['color', 'blur', 'offsetX', 'offsetY', 'affectStroke', 'nonScaling'].forEach(function(prop) { - if (this[prop] !== proto[prop]) { - obj[prop] = this[prop]; - } - }, this); - - return obj; - } - }); - - /** - * Regex matching shadow offsetX, offsetY and blur (ex: "2px 2px 10px rgba(0,0,0,0.2)", "rgb(0,255,0) 2px 2px") - * @static - * @field - * @memberOf fabric.Shadow - */ - // eslint-disable-next-line max-len - fabric.Shadow.reOffsetsAndBlur = /(?:\s|^)(-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?(-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?(\d+(?:\.\d*)?(?:px)?)?(?:\s?|$)(?:$|\s)/; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function () { - - 'use strict'; - - if (fabric.StaticCanvas) { - fabric.warn('fabric.StaticCanvas is already defined.'); - return; - } - - // aliases for faster resolution - var extend = fabric.util.object.extend, - getElementOffset = fabric.util.getElementOffset, - removeFromArray = fabric.util.removeFromArray, - toFixed = fabric.util.toFixed, - transformPoint = fabric.util.transformPoint, - invertTransform = fabric.util.invertTransform, - getNodeCanvas = fabric.util.getNodeCanvas, - createCanvasElement = fabric.util.createCanvasElement, - - CANVAS_INIT_ERROR = new Error('Could not initialize `canvas` element'); - - /** - * Static canvas class - * @class fabric.StaticCanvas - * @mixes fabric.Collection - * @mixes fabric.Observable - * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo} - * @see {@link fabric.StaticCanvas#initialize} for constructor definition - * @fires before:render - * @fires after:render - * @fires canvas:cleared - * @fires object:added - * @fires object:removed - */ - fabric.StaticCanvas = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.StaticCanvas.prototype */ { - - /** - * Constructor - * @param {HTMLElement | String} el <canvas> element to initialize instance on - * @param {Object} [options] Options object - * @return {Object} thisArg - */ - initialize: function(el, options) { - options || (options = { }); - this.renderAndResetBound = this.renderAndReset.bind(this); - this.requestRenderAllBound = this.requestRenderAll.bind(this); - this._initStatic(el, options); - }, - - /** - * Background color of canvas instance. - * Should be set via {@link fabric.StaticCanvas#setBackgroundColor}. - * @type {(String|fabric.Pattern)} - * @default - */ - backgroundColor: '', - - /** - * Background image of canvas instance. - * since 2.4.0 image caching is active, please when putting an image as background, add to the - * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom - * vale. As an alternative you can disable image objectCaching - * @type fabric.Image - * @default - */ - backgroundImage: null, - - /** - * Overlay color of canvas instance. - * Should be set via {@link fabric.StaticCanvas#setOverlayColor} - * @since 1.3.9 - * @type {(String|fabric.Pattern)} - * @default - */ - overlayColor: '', - - /** - * Overlay image of canvas instance. - * since 2.4.0 image caching is active, please when putting an image as overlay, add to the - * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom - * vale. As an alternative you can disable image objectCaching - * @type fabric.Image - * @default - */ - overlayImage: null, - - /** - * Indicates whether toObject/toDatalessObject should include default values - * if set to false, takes precedence over the object value. - * @type Boolean - * @default - */ - includeDefaultValues: true, - - /** - * Indicates whether objects' state should be saved - * @type Boolean - * @default - */ - stateful: false, - - /** - * Indicates whether {@link fabric.Collection.add}, {@link fabric.Collection.insertAt} and {@link fabric.Collection.remove}, - * {@link fabric.StaticCanvas.moveTo}, {@link fabric.StaticCanvas.clear} and many more, should also re-render canvas. - * Disabling this option will not give a performance boost when adding/removing a lot of objects to/from canvas at once - * since the renders are quequed and executed one per frame. - * Disabling is suggested anyway and managing the renders of the app manually is not a big effort ( canvas.requestRenderAll() ) - * Left default to true to do not break documentation and old app, fiddles. - * @type Boolean - * @default - */ - renderOnAddRemove: true, - - /** - * Indicates whether object controls (borders/controls) are rendered above overlay image - * @type Boolean - * @default - */ - controlsAboveOverlay: false, - - /** - * Indicates whether the browser can be scrolled when using a touchscreen and dragging on the canvas - * @type Boolean - * @default - */ - allowTouchScrolling: false, - - /** - * Indicates whether this canvas will use image smoothing, this is on by default in browsers - * @type Boolean - * @default - */ - imageSmoothingEnabled: true, - - /** - * The transformation (in the format of Canvas transform) which focuses the viewport - * @type Array - * @default - */ - viewportTransform: fabric.iMatrix.concat(), - - /** - * if set to false background image is not affected by viewport transform - * @since 1.6.3 - * @type Boolean - * @default - */ - backgroundVpt: true, - - /** - * if set to false overlya image is not affected by viewport transform - * @since 1.6.3 - * @type Boolean - * @default - */ - overlayVpt: true, - - /** - * When true, canvas is scaled by devicePixelRatio for better rendering on retina screens - * @type Boolean - * @default - */ - enableRetinaScaling: true, - - /** - * Describe canvas element extension over design - * properties are tl,tr,bl,br. - * if canvas is not zoomed/panned those points are the four corner of canvas - * if canvas is viewportTransformed you those points indicate the extension - * of canvas element in plain untrasformed coordinates - * The coordinates get updated with @method calcViewportBoundaries. - * @memberOf fabric.StaticCanvas.prototype - */ - vptCoords: { }, - - /** - * Based on vptCoords and object.aCoords, skip rendering of objects that - * are not included in current viewport. - * May greatly help in applications with crowded canvas and use of zoom/pan - * If One of the corner of the bounding box of the object is on the canvas - * the objects get rendered. - * @memberOf fabric.StaticCanvas.prototype - * @type Boolean - * @default - */ - skipOffscreen: true, - - /** - * a fabricObject that, without stroke define a clipping area with their shape. filled in black - * the clipPath object gets used when the canvas has rendered, and the context is placed in the - * top left corner of the canvas. - * clipPath will clip away controls, if you do not want this to happen use controlsAboveOverlay = true - * @type fabric.Object - */ - clipPath: undefined, - - /** - * @private - * @param {HTMLElement | String} el <canvas> element to initialize instance on - * @param {Object} [options] Options object - */ - _initStatic: function(el, options) { - var cb = this.requestRenderAllBound; - this._objects = []; - this._createLowerCanvas(el); - this._initOptions(options); - // only initialize retina scaling once - if (!this.interactive) { - this._initRetinaScaling(); - } - - if (options.overlayImage) { - this.setOverlayImage(options.overlayImage, cb); - } - if (options.backgroundImage) { - this.setBackgroundImage(options.backgroundImage, cb); - } - if (options.backgroundColor) { - this.setBackgroundColor(options.backgroundColor, cb); - } - if (options.overlayColor) { - this.setOverlayColor(options.overlayColor, cb); - } - this.calcOffset(); - }, - - /** - * @private - */ - _isRetinaScaling: function() { - return (fabric.devicePixelRatio !== 1 && this.enableRetinaScaling); - }, - - /** - * @private - * @return {Number} retinaScaling if applied, otherwise 1; - */ - getRetinaScaling: function() { - return this._isRetinaScaling() ? fabric.devicePixelRatio : 1; - }, - - /** - * @private - */ - _initRetinaScaling: function() { - if (!this._isRetinaScaling()) { - return; - } - var scaleRatio = fabric.devicePixelRatio; - this.__initRetinaScaling(scaleRatio, this.lowerCanvasEl, this.contextContainer); - if (this.upperCanvasEl) { - this.__initRetinaScaling(scaleRatio, this.upperCanvasEl, this.contextTop); - } - }, - - __initRetinaScaling: function(scaleRatio, canvas, context) { - canvas.setAttribute('width', this.width * scaleRatio); - canvas.setAttribute('height', this.height * scaleRatio); - context.scale(scaleRatio, scaleRatio); - }, - - - /** - * Calculates canvas element offset relative to the document - * This method is also attached as "resize" event handler of window - * @return {fabric.Canvas} instance - * @chainable - */ - calcOffset: function () { - this._offset = getElementOffset(this.lowerCanvasEl); - return this; - }, - - /** - * Sets {@link fabric.StaticCanvas#overlayImage|overlay image} for this canvas - * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set overlay to - * @param {Function} callback callback to invoke when image is loaded and set as an overlay - * @param {Object} [options] Optional options to set for the {@link fabric.Image|overlay image}. - * @return {fabric.Canvas} thisArg - * @chainable - * @see {@link http://jsfiddle.net/fabricjs/MnzHT/|jsFiddle demo} - * @example Normal overlayImage with left/top = 0 - * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), { - * // Needed to position overlayImage at 0/0 - * originX: 'left', - * originY: 'top' - * }); - * @example overlayImage with different properties - * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), { - * opacity: 0.5, - * angle: 45, - * left: 400, - * top: 400, - * originX: 'left', - * originY: 'top' - * }); - * @example Stretched overlayImage #1 - width/height correspond to canvas width/height - * fabric.Image.fromURL('http://fabricjs.com/assets/jail_cell_bars.png', function(img, isError) { - * img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'}); - * canvas.setOverlayImage(img, canvas.renderAll.bind(canvas)); - * }); - * @example Stretched overlayImage #2 - width/height correspond to canvas width/height - * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), { - * width: canvas.width, - * height: canvas.height, - * // Needed to position overlayImage at 0/0 - * originX: 'left', - * originY: 'top' - * }); - * @example overlayImage loaded from cross-origin - * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), { - * opacity: 0.5, - * angle: 45, - * left: 400, - * top: 400, - * originX: 'left', - * originY: 'top', - * crossOrigin: 'anonymous' - * }); - */ - setOverlayImage: function (image, callback, options) { - return this.__setBgOverlayImage('overlayImage', image, callback, options); - }, - - /** - * Sets {@link fabric.StaticCanvas#backgroundImage|background image} for this canvas - * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set background to - * @param {Function} callback Callback to invoke when image is loaded and set as background - * @param {Object} [options] Optional options to set for the {@link fabric.Image|background image}. - * @return {fabric.Canvas} thisArg - * @chainable - * @see {@link http://jsfiddle.net/djnr8o7a/28/|jsFiddle demo} - * @example Normal backgroundImage with left/top = 0 - * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), { - * // Needed to position backgroundImage at 0/0 - * originX: 'left', - * originY: 'top' - * }); - * @example backgroundImage with different properties - * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), { - * opacity: 0.5, - * angle: 45, - * left: 400, - * top: 400, - * originX: 'left', - * originY: 'top' - * }); - * @example Stretched backgroundImage #1 - width/height correspond to canvas width/height - * fabric.Image.fromURL('http://fabricjs.com/assets/honey_im_subtle.png', function(img, isError) { - * img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'}); - * canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas)); - * }); - * @example Stretched backgroundImage #2 - width/height correspond to canvas width/height - * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), { - * width: canvas.width, - * height: canvas.height, - * // Needed to position backgroundImage at 0/0 - * originX: 'left', - * originY: 'top' - * }); - * @example backgroundImage loaded from cross-origin - * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), { - * opacity: 0.5, - * angle: 45, - * left: 400, - * top: 400, - * originX: 'left', - * originY: 'top', - * crossOrigin: 'anonymous' - * }); - */ - // TODO: fix stretched examples - setBackgroundImage: function (image, callback, options) { - return this.__setBgOverlayImage('backgroundImage', image, callback, options); - }, - - /** - * Sets {@link fabric.StaticCanvas#overlayColor|foreground color} for this canvas - * @param {(String|fabric.Pattern)} overlayColor Color or pattern to set foreground color to - * @param {Function} callback Callback to invoke when foreground color is set - * @return {fabric.Canvas} thisArg - * @chainable - * @see {@link http://jsfiddle.net/fabricjs/pB55h/|jsFiddle demo} - * @example Normal overlayColor - color value - * canvas.setOverlayColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas)); - * @example fabric.Pattern used as overlayColor - * canvas.setOverlayColor({ - * source: 'http://fabricjs.com/assets/escheresque_ste.png' - * }, canvas.renderAll.bind(canvas)); - * @example fabric.Pattern used as overlayColor with repeat and offset - * canvas.setOverlayColor({ - * source: 'http://fabricjs.com/assets/escheresque_ste.png', - * repeat: 'repeat', - * offsetX: 200, - * offsetY: 100 - * }, canvas.renderAll.bind(canvas)); - */ - setOverlayColor: function(overlayColor, callback) { - return this.__setBgOverlayColor('overlayColor', overlayColor, callback); - }, - - /** - * Sets {@link fabric.StaticCanvas#backgroundColor|background color} for this canvas - * @param {(String|fabric.Pattern)} backgroundColor Color or pattern to set background color to - * @param {Function} callback Callback to invoke when background color is set - * @return {fabric.Canvas} thisArg - * @chainable - * @see {@link http://jsfiddle.net/fabricjs/hXzvk/|jsFiddle demo} - * @example Normal backgroundColor - color value - * canvas.setBackgroundColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas)); - * @example fabric.Pattern used as backgroundColor - * canvas.setBackgroundColor({ - * source: 'http://fabricjs.com/assets/escheresque_ste.png' - * }, canvas.renderAll.bind(canvas)); - * @example fabric.Pattern used as backgroundColor with repeat and offset - * canvas.setBackgroundColor({ - * source: 'http://fabricjs.com/assets/escheresque_ste.png', - * repeat: 'repeat', - * offsetX: 200, - * offsetY: 100 - * }, canvas.renderAll.bind(canvas)); - */ - setBackgroundColor: function(backgroundColor, callback) { - return this.__setBgOverlayColor('backgroundColor', backgroundColor, callback); - }, - - /** - * @private - * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundImage|backgroundImage} - * or {@link fabric.StaticCanvas#overlayImage|overlayImage}) - * @param {(fabric.Image|String|null)} image fabric.Image instance, URL of an image or null to set background or overlay to - * @param {Function} callback Callback to invoke when image is loaded and set as background or overlay. The first argument is the created image, the second argument is a flag indicating whether an error occurred or not. - * @param {Object} [options] Optional options to set for the {@link fabric.Image|image}. - */ - __setBgOverlayImage: function(property, image, callback, options) { - if (typeof image === 'string') { - fabric.util.loadImage(image, function(img, isError) { - if (img) { - var instance = new fabric.Image(img, options); - this[property] = instance; - instance.canvas = this; - } - callback && callback(img, isError); - }, this, options && options.crossOrigin); - } - else { - options && image.setOptions(options); - this[property] = image; - image && (image.canvas = this); - callback && callback(image, false); - } - - return this; - }, - - /** - * @private - * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundColor|backgroundColor} - * or {@link fabric.StaticCanvas#overlayColor|overlayColor}) - * @param {(Object|String|null)} color Object with pattern information, color value or null - * @param {Function} [callback] Callback is invoked when color is set - */ - __setBgOverlayColor: function(property, color, callback) { - this[property] = color; - this._initGradient(color, property); - this._initPattern(color, property, callback); - return this; - }, - - /** - * @private - */ - _createCanvasElement: function() { - var element = createCanvasElement(); - if (!element) { - throw CANVAS_INIT_ERROR; - } - if (!element.style) { - element.style = { }; - } - if (typeof element.getContext === 'undefined') { - throw CANVAS_INIT_ERROR; - } - return element; - }, - - /** - * @private - * @param {Object} [options] Options object - */ - _initOptions: function (options) { - var lowerCanvasEl = this.lowerCanvasEl; - this._setOptions(options); - - this.width = this.width || parseInt(lowerCanvasEl.width, 10) || 0; - this.height = this.height || parseInt(lowerCanvasEl.height, 10) || 0; - - if (!this.lowerCanvasEl.style) { - return; - } - - lowerCanvasEl.width = this.width; - lowerCanvasEl.height = this.height; - - lowerCanvasEl.style.width = this.width + 'px'; - lowerCanvasEl.style.height = this.height + 'px'; - - this.viewportTransform = this.viewportTransform.slice(); - }, - - /** - * Creates a bottom canvas - * @private - * @param {HTMLElement} [canvasEl] - */ - _createLowerCanvas: function (canvasEl) { - // canvasEl === 'HTMLCanvasElement' does not work on jsdom/node - if (canvasEl && canvasEl.getContext) { - this.lowerCanvasEl = canvasEl; - } - else { - this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement(); - } - - fabric.util.addClass(this.lowerCanvasEl, 'lower-canvas'); - this._originalCanvasStyle = this.lowerCanvasEl.style; - if (this.interactive) { - this._applyCanvasStyle(this.lowerCanvasEl); - } - - this.contextContainer = this.lowerCanvasEl.getContext('2d'); - }, - - /** - * Returns canvas width (in px) - * @return {Number} - */ - getWidth: function () { - return this.width; - }, - - /** - * Returns canvas height (in px) - * @return {Number} - */ - getHeight: function () { - return this.height; - }, - - /** - * Sets width of this canvas instance - * @param {Number|String} value Value to set width to - * @param {Object} [options] Options object - * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions - * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions - * @return {fabric.Canvas} instance - * @chainable true - */ - setWidth: function (value, options) { - return this.setDimensions({ width: value }, options); - }, - - /** - * Sets height of this canvas instance - * @param {Number|String} value Value to set height to - * @param {Object} [options] Options object - * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions - * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions - * @return {fabric.Canvas} instance - * @chainable true - */ - setHeight: function (value, options) { - return this.setDimensions({ height: value }, options); - }, - - /** - * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em) - * @param {Object} dimensions Object with width/height properties - * @param {Number|String} [dimensions.width] Width of canvas element - * @param {Number|String} [dimensions.height] Height of canvas element - * @param {Object} [options] Options object - * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions - * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions - * @return {fabric.Canvas} thisArg - * @chainable - */ - setDimensions: function (dimensions, options) { - var cssValue; - - options = options || {}; - - for (var prop in dimensions) { - cssValue = dimensions[prop]; - - if (!options.cssOnly) { - this._setBackstoreDimension(prop, dimensions[prop]); - cssValue += 'px'; - this.hasLostContext = true; - } - - if (!options.backstoreOnly) { - this._setCssDimension(prop, cssValue); - } - } - if (this._isCurrentlyDrawing) { - this.freeDrawingBrush && this.freeDrawingBrush._setBrushStyles(); - } - this._initRetinaScaling(); - this.calcOffset(); - - if (!options.cssOnly) { - this.requestRenderAll(); - } - - return this; - }, - - /** - * Helper for setting width/height - * @private - * @param {String} prop property (width|height) - * @param {Number} value value to set property to - * @return {fabric.Canvas} instance - * @chainable true - */ - _setBackstoreDimension: function (prop, value) { - this.lowerCanvasEl[prop] = value; - - if (this.upperCanvasEl) { - this.upperCanvasEl[prop] = value; - } - - if (this.cacheCanvasEl) { - this.cacheCanvasEl[prop] = value; - } - - this[prop] = value; - - return this; - }, - - /** - * Helper for setting css width/height - * @private - * @param {String} prop property (width|height) - * @param {String} value value to set property to - * @return {fabric.Canvas} instance - * @chainable true - */ - _setCssDimension: function (prop, value) { - this.lowerCanvasEl.style[prop] = value; - - if (this.upperCanvasEl) { - this.upperCanvasEl.style[prop] = value; - } - - if (this.wrapperEl) { - this.wrapperEl.style[prop] = value; - } - - return this; - }, - - /** - * Returns canvas zoom level - * @return {Number} - */ - getZoom: function () { - return this.viewportTransform[0]; - }, - - /** - * Sets viewport transform of this canvas instance - * @param {Array} vpt the transform in the form of context.transform - * @return {fabric.Canvas} instance - * @chainable true - */ - setViewportTransform: function (vpt) { - var activeObject = this._activeObject, - backgroundObject = this.backgroundImage, - overlayObject = this.overlayImage, - object, i, len; - this.viewportTransform = vpt; - for (i = 0, len = this._objects.length; i < len; i++) { - object = this._objects[i]; - object.group || object.setCoords(true); - } - if (activeObject) { - activeObject.setCoords(); - } - if (backgroundObject) { - backgroundObject.setCoords(true); - } - if (overlayObject) { - overlayObject.setCoords(true); - } - this.calcViewportBoundaries(); - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * Sets zoom level of this canvas instance, the zoom centered around point - * meaning that following zoom to point with the same point will have the visual - * effect of the zoom originating from that point. The point won't move. - * It has nothing to do with canvas center or visual center of the viewport. - * @param {fabric.Point} point to zoom with respect to - * @param {Number} value to set zoom to, less than 1 zooms out - * @return {fabric.Canvas} instance - * @chainable true - */ - zoomToPoint: function (point, value) { - // TODO: just change the scale, preserve other transformations - var before = point, vpt = this.viewportTransform.slice(0); - point = transformPoint(point, invertTransform(this.viewportTransform)); - vpt[0] = value; - vpt[3] = value; - var after = transformPoint(point, vpt); - vpt[4] += before.x - after.x; - vpt[5] += before.y - after.y; - return this.setViewportTransform(vpt); - }, - - /** - * Sets zoom level of this canvas instance - * @param {Number} value to set zoom to, less than 1 zooms out - * @return {fabric.Canvas} instance - * @chainable true - */ - setZoom: function (value) { - this.zoomToPoint(new fabric.Point(0, 0), value); - return this; - }, - - /** - * Pan viewport so as to place point at top left corner of canvas - * @param {fabric.Point} point to move to - * @return {fabric.Canvas} instance - * @chainable true - */ - absolutePan: function (point) { - var vpt = this.viewportTransform.slice(0); - vpt[4] = -point.x; - vpt[5] = -point.y; - return this.setViewportTransform(vpt); - }, - - /** - * Pans viewpoint relatively - * @param {fabric.Point} point (position vector) to move by - * @return {fabric.Canvas} instance - * @chainable true - */ - relativePan: function (point) { - return this.absolutePan(new fabric.Point( - -point.x - this.viewportTransform[4], - -point.y - this.viewportTransform[5] - )); - }, - - /** - * Returns <canvas> element corresponding to this instance - * @return {HTMLCanvasElement} - */ - getElement: function () { - return this.lowerCanvasEl; - }, - - /** - * @private - * @param {fabric.Object} obj Object that was added - */ - _onObjectAdded: function(obj) { - this.stateful && obj.setupState(); - obj._set('canvas', this); - obj.setCoords(); - this.fire('object:added', { target: obj }); - obj.fire('added'); - }, - - /** - * @private - * @param {fabric.Object} obj Object that was removed - */ - _onObjectRemoved: function(obj) { - this.fire('object:removed', { target: obj }); - obj.fire('removed'); - delete obj.canvas; - }, - - /** - * Clears specified context of canvas element - * @param {CanvasRenderingContext2D} ctx Context to clear - * @return {fabric.Canvas} thisArg - * @chainable - */ - clearContext: function(ctx) { - ctx.clearRect(0, 0, this.width, this.height); - return this; - }, - - /** - * Returns context of canvas where objects are drawn - * @return {CanvasRenderingContext2D} - */ - getContext: function () { - return this.contextContainer; - }, - - /** - * Clears all contexts (background, main, top) of an instance - * @return {fabric.Canvas} thisArg - * @chainable - */ - clear: function () { - this.remove.apply(this, this.getObjects()); - this.backgroundImage = null; - this.overlayImage = null; - this.backgroundColor = ''; - this.overlayColor = ''; - if (this._hasITextHandlers) { - this.off('mouse:up', this._mouseUpITextHandler); - this._iTextInstances = null; - this._hasITextHandlers = false; - } - this.clearContext(this.contextContainer); - this.fire('canvas:cleared'); - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * Renders the canvas - * @return {fabric.Canvas} instance - * @chainable - */ - renderAll: function () { - var canvasToDrawOn = this.contextContainer; - this.renderCanvas(canvasToDrawOn, this._objects); - return this; - }, - - /** - * Function created to be instance bound at initialization - * used in requestAnimationFrame rendering - * Let the fabricJS call it. If you call it manually you could have more - * animationFrame stacking on to of each other - * for an imperative rendering, use canvas.renderAll - * @private - * @return {fabric.Canvas} instance - * @chainable - */ - renderAndReset: function() { - this.isRendering = 0; - this.renderAll(); - }, - - /** - * Append a renderAll request to next animation frame. - * unless one is already in progress, in that case nothing is done - * a boolean flag will avoid appending more. - * @return {fabric.Canvas} instance - * @chainable - */ - requestRenderAll: function () { - if (!this.isRendering) { - this.isRendering = fabric.util.requestAnimFrame(this.renderAndResetBound); - } - return this; - }, - - /** - * Calculate the position of the 4 corner of canvas with current viewportTransform. - * helps to determinate when an object is in the current rendering viewport using - * object absolute coordinates ( aCoords ) - * @return {Object} points.tl - * @chainable - */ - calcViewportBoundaries: function() { - var points = { }, width = this.width, height = this.height, - iVpt = invertTransform(this.viewportTransform); - points.tl = transformPoint({ x: 0, y: 0 }, iVpt); - points.br = transformPoint({ x: width, y: height }, iVpt); - points.tr = new fabric.Point(points.br.x, points.tl.y); - points.bl = new fabric.Point(points.tl.x, points.br.y); - this.vptCoords = points; - return points; - }, - - cancelRequestedRender: function() { - if (this.isRendering) { - fabric.util.cancelAnimFrame(this.isRendering); - this.isRendering = 0; - } - }, - - /** - * Renders background, objects, overlay and controls. - * @param {CanvasRenderingContext2D} ctx - * @param {Array} objects to render - * @return {fabric.Canvas} instance - * @chainable - */ - renderCanvas: function(ctx, objects) { - var v = this.viewportTransform, path = this.clipPath; - this.cancelRequestedRender(); - this.calcViewportBoundaries(); - this.clearContext(ctx); - fabric.util.setImageSmoothing(ctx, this.imageSmoothingEnabled); - this.fire('before:render', { ctx: ctx, }); - this._renderBackground(ctx); - - ctx.save(); - //apply viewport transform once for all rendering process - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - this._renderObjects(ctx, objects); - ctx.restore(); - if (!this.controlsAboveOverlay && this.interactive) { - this.drawControls(ctx); - } - if (path) { - path.canvas = this; - // needed to setup a couple of variables - path.shouldCache(); - path._transformDone = true; - path.renderCache({ forClipping: true }); - this.drawClipPathOnCanvas(ctx); - } - this._renderOverlay(ctx); - if (this.controlsAboveOverlay && this.interactive) { - this.drawControls(ctx); - } - this.fire('after:render', { ctx: ctx, }); - }, - - /** - * Paint the cached clipPath on the lowerCanvasEl - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - drawClipPathOnCanvas: function(ctx) { - var v = this.viewportTransform, path = this.clipPath; - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - // DEBUG: uncomment this line, comment the following - // ctx.globalAlpha = 0.4; - ctx.globalCompositeOperation = 'destination-in'; - path.transform(ctx); - ctx.scale(1 / path.zoomX, 1 / path.zoomY); - ctx.drawImage(path._cacheCanvas, -path.cacheTranslationX, -path.cacheTranslationY); - ctx.restore(); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Array} objects to render - */ - _renderObjects: function(ctx, objects) { - var i, len; - for (i = 0, len = objects.length; i < len; ++i) { - objects[i] && objects[i].render(ctx); - } - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {string} property 'background' or 'overlay' - */ - _renderBackgroundOrOverlay: function(ctx, property) { - var fill = this[property + 'Color'], object = this[property + 'Image'], - v = this.viewportTransform, needsVpt = this[property + 'Vpt']; - if (!fill && !object) { - return; - } - if (fill) { - ctx.save(); - ctx.beginPath(); - ctx.moveTo(0, 0); - ctx.lineTo(this.width, 0); - ctx.lineTo(this.width, this.height); - ctx.lineTo(0, this.height); - ctx.closePath(); - ctx.fillStyle = fill.toLive - ? fill.toLive(ctx, this) - : fill; - if (needsVpt) { - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - } - ctx.transform(1, 0, 0, 1, fill.offsetX || 0, fill.offsetY || 0); - var m = fill.gradientTransform || fill.patternTransform; - m && ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); - ctx.fill(); - ctx.restore(); - } - if (object) { - ctx.save(); - if (needsVpt) { - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - } - object.render(ctx); - ctx.restore(); - } - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderBackground: function(ctx) { - this._renderBackgroundOrOverlay(ctx, 'background'); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderOverlay: function(ctx) { - this._renderBackgroundOrOverlay(ctx, 'overlay'); - }, - - /** - * Returns coordinates of a center of canvas. - * Returned value is an object with top and left properties - * @return {Object} object with "top" and "left" number values - */ - getCenter: function () { - return { - top: this.height / 2, - left: this.width / 2 - }; - }, - - /** - * Centers object horizontally in the canvas - * @param {fabric.Object} object Object to center horizontally - * @return {fabric.Canvas} thisArg - */ - centerObjectH: function (object) { - return this._centerObject(object, new fabric.Point(this.getCenter().left, object.getCenterPoint().y)); - }, - - /** - * Centers object vertically in the canvas - * @param {fabric.Object} object Object to center vertically - * @return {fabric.Canvas} thisArg - * @chainable - */ - centerObjectV: function (object) { - return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, this.getCenter().top)); - }, - - /** - * Centers object vertically and horizontally in the canvas - * @param {fabric.Object} object Object to center vertically and horizontally - * @return {fabric.Canvas} thisArg - * @chainable - */ - centerObject: function(object) { - var center = this.getCenter(); - - return this._centerObject(object, new fabric.Point(center.left, center.top)); - }, - - /** - * Centers object vertically and horizontally in the viewport - * @param {fabric.Object} object Object to center vertically and horizontally - * @return {fabric.Canvas} thisArg - * @chainable - */ - viewportCenterObject: function(object) { - var vpCenter = this.getVpCenter(); - - return this._centerObject(object, vpCenter); - }, - - /** - * Centers object horizontally in the viewport, object.top is unchanged - * @param {fabric.Object} object Object to center vertically and horizontally - * @return {fabric.Canvas} thisArg - * @chainable - */ - viewportCenterObjectH: function(object) { - var vpCenter = this.getVpCenter(); - this._centerObject(object, new fabric.Point(vpCenter.x, object.getCenterPoint().y)); - return this; - }, - - /** - * Centers object Vertically in the viewport, object.top is unchanged - * @param {fabric.Object} object Object to center vertically and horizontally - * @return {fabric.Canvas} thisArg - * @chainable - */ - viewportCenterObjectV: function(object) { - var vpCenter = this.getVpCenter(); - - return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, vpCenter.y)); - }, - - /** - * Calculate the point in canvas that correspond to the center of actual viewport. - * @return {fabric.Point} vpCenter, viewport center - * @chainable - */ - getVpCenter: function() { - var center = this.getCenter(), - iVpt = invertTransform(this.viewportTransform); - return transformPoint({ x: center.left, y: center.top }, iVpt); - }, - - /** - * @private - * @param {fabric.Object} object Object to center - * @param {fabric.Point} center Center point - * @return {fabric.Canvas} thisArg - * @chainable - */ - _centerObject: function(object, center) { - object.setPositionByOrigin(center, 'center', 'center'); - object.setCoords(); - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * Returns dataless JSON representation of canvas - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {String} json string - */ - toDatalessJSON: function (propertiesToInclude) { - return this.toDatalessObject(propertiesToInclude); - }, - - /** - * Returns object representation of canvas - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function (propertiesToInclude) { - return this._toObjectMethod('toObject', propertiesToInclude); - }, - - /** - * Returns dataless object representation of canvas - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toDatalessObject: function (propertiesToInclude) { - return this._toObjectMethod('toDatalessObject', propertiesToInclude); - }, - - /** - * @private - */ - _toObjectMethod: function (methodName, propertiesToInclude) { - - var clipPath = this.clipPath, data = { - version: fabric.version, - objects: this._toObjects(methodName, propertiesToInclude), - }; - if (clipPath && !clipPath.excludeFromExport) { - data.clipPath = this._toObject(this.clipPath, methodName, propertiesToInclude); - } - extend(data, this.__serializeBgOverlay(methodName, propertiesToInclude)); - - fabric.util.populateWithProperties(this, data, propertiesToInclude); - - return data; - }, - - /** - * @private - */ - _toObjects: function(methodName, propertiesToInclude) { - return this._objects.filter(function(object) { - return !object.excludeFromExport; - }).map(function(instance) { - return this._toObject(instance, methodName, propertiesToInclude); - }, this); - }, - - /** - * @private - */ - _toObject: function(instance, methodName, propertiesToInclude) { - var originalValue; - - if (!this.includeDefaultValues) { - originalValue = instance.includeDefaultValues; - instance.includeDefaultValues = false; - } - - var object = instance[methodName](propertiesToInclude); - if (!this.includeDefaultValues) { - instance.includeDefaultValues = originalValue; - } - return object; - }, - - /** - * @private - */ - __serializeBgOverlay: function(methodName, propertiesToInclude) { - var data = {}, bgImage = this.backgroundImage, overlayImage = this.overlayImage, - bgColor = this.backgroundColor, overlayColor = this.overlayColor; - - if (bgColor && bgColor.toObject) { - if (!bgColor.excludeFromExport) { - data.background = bgColor.toObject(propertiesToInclude); - } - } - else if (bgColor) { - data.background = bgColor; - } - - if (overlayColor && overlayColor.toObject) { - if (!overlayColor.excludeFromExport) { - data.overlay = overlayColor.toObject(propertiesToInclude); - } - } - else if (overlayColor) { - data.overlay = overlayColor; - } - - if (bgImage && !bgImage.excludeFromExport) { - data.backgroundImage = this._toObject(bgImage, methodName, propertiesToInclude); - } - if (overlayImage && !overlayImage.excludeFromExport) { - data.overlayImage = this._toObject(overlayImage, methodName, propertiesToInclude); - } - - return data; - }, - - /* _TO_SVG_START_ */ - /** - * When true, getSvgTransform() will apply the StaticCanvas.viewportTransform to the SVG transformation. When true, - * a zoomed canvas will then produce zoomed SVG output. - * @type Boolean - * @default - */ - svgViewportTransformation: true, - - /** - * Returns SVG representation of canvas - * @function - * @param {Object} [options] Options object for SVG output - * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included - * @param {Object} [options.viewBox] SVG viewbox object - * @param {Number} [options.viewBox.x] x-coordinate of viewbox - * @param {Number} [options.viewBox.y] y-coordinate of viewbox - * @param {Number} [options.viewBox.width] Width of viewbox - * @param {Number} [options.viewBox.height] Height of viewbox - * @param {String} [options.encoding=UTF-8] Encoding of SVG output - * @param {String} [options.width] desired width of svg with or without units - * @param {String} [options.height] desired height of svg with or without units - * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation. - * @return {String} SVG string - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization} - * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo} - * @example Normal SVG output - * var svg = canvas.toSVG(); - * @example SVG output without preamble (without <?xml ../>) - * var svg = canvas.toSVG({suppressPreamble: true}); - * @example SVG output with viewBox attribute - * var svg = canvas.toSVG({ - * viewBox: { - * x: 100, - * y: 100, - * width: 200, - * height: 300 - * } - * }); - * @example SVG output with different encoding (default: UTF-8) - * var svg = canvas.toSVG({encoding: 'ISO-8859-1'}); - * @example Modify SVG output with reviver function - * var svg = canvas.toSVG(null, function(svg) { - * return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', ''); - * }); - */ - toSVG: function(options, reviver) { - options || (options = { }); - options.reviver = reviver; - var markup = []; - - this._setSVGPreamble(markup, options); - this._setSVGHeader(markup, options); - if (this.clipPath) { - markup.push('\n'); - } - this._setSVGBgOverlayColor(markup, 'background'); - this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver); - this._setSVGObjects(markup, reviver); - if (this.clipPath) { - markup.push('\n'); - } - this._setSVGBgOverlayColor(markup, 'overlay'); - this._setSVGBgOverlayImage(markup, 'overlayImage', reviver); - - markup.push(''); - - return markup.join(''); - }, - - /** - * @private - */ - _setSVGPreamble: function(markup, options) { - if (options.suppressPreamble) { - return; - } - markup.push( - '\n', - '\n' - ); - }, - - /** - * @private - */ - _setSVGHeader: function(markup, options) { - var width = options.width || this.width, - height = options.height || this.height, - vpt, viewBox = 'viewBox="0 0 ' + this.width + ' ' + this.height + '" ', - NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - - if (options.viewBox) { - viewBox = 'viewBox="' + - options.viewBox.x + ' ' + - options.viewBox.y + ' ' + - options.viewBox.width + ' ' + - options.viewBox.height + '" '; - } - else { - if (this.svgViewportTransformation) { - vpt = this.viewportTransform; - viewBox = 'viewBox="' + - toFixed(-vpt[4] / vpt[0], NUM_FRACTION_DIGITS) + ' ' + - toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS) + ' ' + - toFixed(this.width / vpt[0], NUM_FRACTION_DIGITS) + ' ' + - toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS) + '" '; - } - } - - markup.push( - '\n', - 'Created with Fabric.js ', fabric.version, '\n', - '\n', - this.createSVGFontFacesMarkup(), - this.createSVGRefElementsMarkup(), - this.createSVGClipPathMarkup(options), - '\n' - ); - }, - - createSVGClipPathMarkup: function(options) { - var clipPath = this.clipPath; - if (clipPath) { - clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++; - return '\n' + - this.clipPath.toClipPathSVG(options.reviver) + - '\n'; - } - return ''; - }, - - /** - * Creates markup containing SVG referenced elements like patterns, gradients etc. - * @return {String} - */ - createSVGRefElementsMarkup: function() { - var _this = this, - markup = ['background', 'overlay'].map(function(prop) { - var fill = _this[prop + 'Color']; - if (fill && fill.toLive) { - var shouldTransform = _this[prop + 'Vpt'], vpt = _this.viewportTransform, - object = { - width: _this.width / (shouldTransform ? vpt[0] : 1), - height: _this.height / (shouldTransform ? vpt[3] : 1) - }; - return fill.toSVG( - object, - { additionalTransform: shouldTransform ? fabric.util.matrixToSVG(vpt) : '' } - ); - } - }); - return markup.join(''); - }, - - /** - * Creates markup containing SVG font faces, - * font URLs for font faces must be collected by developers - * and are not extracted from the DOM by fabricjs - * @param {Array} objects Array of fabric objects - * @return {String} - */ - createSVGFontFacesMarkup: function() { - var markup = '', fontList = { }, obj, fontFamily, - style, row, rowIndex, _char, charIndex, i, len, - fontPaths = fabric.fontPaths, objects = []; - - this._objects.forEach(function add(object) { - objects.push(object); - if (object._objects) { - object._objects.forEach(add); - } - }); - - for (i = 0, len = objects.length; i < len; i++) { - obj = objects[i]; - fontFamily = obj.fontFamily; - if (obj.type.indexOf('text') === -1 || fontList[fontFamily] || !fontPaths[fontFamily]) { - continue; - } - fontList[fontFamily] = true; - if (!obj.styles) { - continue; - } - style = obj.styles; - for (rowIndex in style) { - row = style[rowIndex]; - for (charIndex in row) { - _char = row[charIndex]; - fontFamily = _char.fontFamily; - if (!fontList[fontFamily] && fontPaths[fontFamily]) { - fontList[fontFamily] = true; - } - } - } - } - - for (var j in fontList) { - markup += [ - '\t\t@font-face {\n', - '\t\t\tfont-family: \'', j, '\';\n', - '\t\t\tsrc: url(\'', fontPaths[j], '\');\n', - '\t\t}\n' - ].join(''); - } - - if (markup) { - markup = [ - '\t\n' - ].join(''); - } - - return markup; - }, - - /** - * @private - */ - _setSVGObjects: function(markup, reviver) { - var instance, i, len, objects = this._objects; - for (i = 0, len = objects.length; i < len; i++) { - instance = objects[i]; - if (instance.excludeFromExport) { - continue; - } - this._setSVGObject(markup, instance, reviver); - } - }, - - /** - * @private - */ - _setSVGObject: function(markup, instance, reviver) { - markup.push(instance.toSVG(reviver)); - }, - - /** - * @private - */ - _setSVGBgOverlayImage: function(markup, property, reviver) { - if (this[property] && !this[property].excludeFromExport && this[property].toSVG) { - markup.push(this[property].toSVG(reviver)); - } - }, - - /** - * @private - */ - _setSVGBgOverlayColor: function(markup, property) { - var filler = this[property + 'Color'], vpt = this.viewportTransform, finalWidth = this.width, - finalHeight = this.height; - if (!filler) { - return; - } - if (filler.toLive) { - var repeat = filler.repeat, iVpt = fabric.util.invertTransform(vpt), shouldInvert = this[property + 'Vpt'], - additionalTransform = shouldInvert ? fabric.util.matrixToSVG(iVpt) : ''; - markup.push( - '\n' - ); - } - else { - markup.push( - '\n' - ); - } - }, - /* _TO_SVG_END_ */ - - /** - * Moves an object or the objects of a multiple selection - * to the bottom of the stack of drawn objects - * @param {fabric.Object} object Object to send to back - * @return {fabric.Canvas} thisArg - * @chainable - */ - sendToBack: function (object) { - if (!object) { - return this; - } - var activeSelection = this._activeObject, - i, obj, objs; - if (object === activeSelection && object.type === 'activeSelection') { - objs = activeSelection._objects; - for (i = objs.length; i--;) { - obj = objs[i]; - removeFromArray(this._objects, obj); - this._objects.unshift(obj); - } - } - else { - removeFromArray(this._objects, object); - this._objects.unshift(object); - } - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * Moves an object or the objects of a multiple selection - * to the top of the stack of drawn objects - * @param {fabric.Object} object Object to send - * @return {fabric.Canvas} thisArg - * @chainable - */ - bringToFront: function (object) { - if (!object) { - return this; - } - var activeSelection = this._activeObject, - i, obj, objs; - if (object === activeSelection && object.type === 'activeSelection') { - objs = activeSelection._objects; - for (i = 0; i < objs.length; i++) { - obj = objs[i]; - removeFromArray(this._objects, obj); - this._objects.push(obj); - } - } - else { - removeFromArray(this._objects, object); - this._objects.push(object); - } - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * Moves an object or a selection down in stack of drawn objects - * An optional parameter, intersecting allows to move the object in behind - * the first intersecting object. Where intersection is calculated with - * bounding box. If no intersection is found, there will not be change in the - * stack. - * @param {fabric.Object} object Object to send - * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object - * @return {fabric.Canvas} thisArg - * @chainable - */ - sendBackwards: function (object, intersecting) { - if (!object) { - return this; - } - var activeSelection = this._activeObject, - i, obj, idx, newIdx, objs, objsMoved = 0; - - if (object === activeSelection && object.type === 'activeSelection') { - objs = activeSelection._objects; - for (i = 0; i < objs.length; i++) { - obj = objs[i]; - idx = this._objects.indexOf(obj); - if (idx > 0 + objsMoved) { - newIdx = idx - 1; - removeFromArray(this._objects, obj); - this._objects.splice(newIdx, 0, obj); - } - objsMoved++; - } - } - else { - idx = this._objects.indexOf(object); - if (idx !== 0) { - // if object is not on the bottom of stack - newIdx = this._findNewLowerIndex(object, idx, intersecting); - removeFromArray(this._objects, object); - this._objects.splice(newIdx, 0, object); - } - } - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * @private - */ - _findNewLowerIndex: function(object, idx, intersecting) { - var newIdx, i; - - if (intersecting) { - newIdx = idx; - - // traverse down the stack looking for the nearest intersecting object - for (i = idx - 1; i >= 0; --i) { - - var isIntersecting = object.intersectsWithObject(this._objects[i]) || - object.isContainedWithinObject(this._objects[i]) || - this._objects[i].isContainedWithinObject(object); - - if (isIntersecting) { - newIdx = i; - break; - } - } - } - else { - newIdx = idx - 1; - } - - return newIdx; - }, - - /** - * Moves an object or a selection up in stack of drawn objects - * An optional parameter, intersecting allows to move the object in front - * of the first intersecting object. Where intersection is calculated with - * bounding box. If no intersection is found, there will not be change in the - * stack. - * @param {fabric.Object} object Object to send - * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object - * @return {fabric.Canvas} thisArg - * @chainable - */ - bringForward: function (object, intersecting) { - if (!object) { - return this; - } - var activeSelection = this._activeObject, - i, obj, idx, newIdx, objs, objsMoved = 0; - - if (object === activeSelection && object.type === 'activeSelection') { - objs = activeSelection._objects; - for (i = objs.length; i--;) { - obj = objs[i]; - idx = this._objects.indexOf(obj); - if (idx < this._objects.length - 1 - objsMoved) { - newIdx = idx + 1; - removeFromArray(this._objects, obj); - this._objects.splice(newIdx, 0, obj); - } - objsMoved++; - } - } - else { - idx = this._objects.indexOf(object); - if (idx !== this._objects.length - 1) { - // if object is not on top of stack (last item in an array) - newIdx = this._findNewUpperIndex(object, idx, intersecting); - removeFromArray(this._objects, object); - this._objects.splice(newIdx, 0, object); - } - } - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * @private - */ - _findNewUpperIndex: function(object, idx, intersecting) { - var newIdx, i, len; - - if (intersecting) { - newIdx = idx; - - // traverse up the stack looking for the nearest intersecting object - for (i = idx + 1, len = this._objects.length; i < len; ++i) { - - var isIntersecting = object.intersectsWithObject(this._objects[i]) || - object.isContainedWithinObject(this._objects[i]) || - this._objects[i].isContainedWithinObject(object); - - if (isIntersecting) { - newIdx = i; - break; - } - } - } - else { - newIdx = idx + 1; - } - - return newIdx; - }, - - /** - * Moves an object to specified level in stack of drawn objects - * @param {fabric.Object} object Object to send - * @param {Number} index Position to move to - * @return {fabric.Canvas} thisArg - * @chainable - */ - moveTo: function (object, index) { - removeFromArray(this._objects, object); - this._objects.splice(index, 0, object); - return this.renderOnAddRemove && this.requestRenderAll(); - }, - - /** - * Clears a canvas element and dispose objects - * @return {fabric.Canvas} thisArg - * @chainable - */ - dispose: function () { - // cancel eventually ongoing renders - if (this.isRendering) { - fabric.util.cancelAnimFrame(this.isRendering); - this.isRendering = 0; - } - this.forEachObject(function(object) { - object.dispose && object.dispose(); - }); - this._objects = []; - if (this.backgroundImage && this.backgroundImage.dispose) { - this.backgroundImage.dispose(); - } - this.backgroundImage = null; - if (this.overlayImage && this.overlayImage.dispose) { - this.overlayImage.dispose(); - } - this.overlayImage = null; - this._iTextInstances = null; - this.contextContainer = null; - // restore canvas style - this.lowerCanvasEl.classList.remove('lower-canvas'); - this.lowerCanvasEl.style = this._originalCanvasStyle; - delete this._originalCanvasStyle; - // restore canvas size to original size in case retina scaling was applied - this.lowerCanvasEl.setAttribute('width', this.width); - this.lowerCanvasEl.setAttribute('height', this.height); - fabric.util.cleanUpJsdomNode(this.lowerCanvasEl); - this.lowerCanvasEl = undefined; - return this; - }, - - /** - * Returns a string representation of an instance - * @return {String} string representation of an instance - */ - toString: function () { - return '#'; - } - }); - - extend(fabric.StaticCanvas.prototype, fabric.Observable); - extend(fabric.StaticCanvas.prototype, fabric.Collection); - extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter); - - extend(fabric.StaticCanvas, /** @lends fabric.StaticCanvas */ { - - /** - * @static - * @type String - * @default - */ - EMPTY_JSON: '{"objects": [], "background": "white"}', - - /** - * Provides a way to check support of some of the canvas methods - * (either those of HTMLCanvasElement itself, or rendering context) - * - * @param {String} methodName Method to check support for; - * Could be one of "setLineDash" - * @return {Boolean | null} `true` if method is supported (or at least exists), - * `null` if canvas element or context can not be initialized - */ - supports: function (methodName) { - var el = createCanvasElement(); - - if (!el || !el.getContext) { - return null; - } - - var ctx = el.getContext('2d'); - if (!ctx) { - return null; - } - - switch (methodName) { - - case 'setLineDash': - return typeof ctx.setLineDash !== 'undefined'; - - default: - return null; - } - } - }); - - /** - * Returns Object representation of canvas - * this alias is provided because if you call JSON.stringify on an instance, - * the toJSON object will be invoked if it exists. - * Having a toJSON method means you can do JSON.stringify(myCanvas) - * @function - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} JSON compatible object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization} - * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo} - * @example JSON without additional properties - * var json = canvas.toJSON(); - * @example JSON with additional properties included - * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY']); - * @example JSON without default values - * canvas.includeDefaultValues = false; - * var json = canvas.toJSON(); - */ - fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject; - - if (fabric.isLikelyNode) { - fabric.StaticCanvas.prototype.createPNGStream = function() { - var impl = getNodeCanvas(this.lowerCanvasEl); - return impl && impl.createPNGStream(); - }; - fabric.StaticCanvas.prototype.createJPEGStream = function(opts) { - var impl = getNodeCanvas(this.lowerCanvasEl); - return impl && impl.createJPEGStream(opts); - }; - } -})(); - - -/** - * BaseBrush class - * @class fabric.BaseBrush - * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo} - */ -fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ { - - /** - * Color of a brush - * @type String - * @default - */ - color: 'rgb(0, 0, 0)', - - /** - * Width of a brush, has to be a Number, no string literals - * @type Number - * @default - */ - width: 1, - - /** - * Shadow object representing shadow of this shape. - * Backwards incompatibility note: This property replaces "shadowColor" (String), "shadowOffsetX" (Number), - * "shadowOffsetY" (Number) and "shadowBlur" (Number) since v1.2.12 - * @type fabric.Shadow - * @default - */ - shadow: null, - - /** - * Line endings style of a brush (one of "butt", "round", "square") - * @type String - * @default - */ - strokeLineCap: 'round', - - /** - * Corner style of a brush (one of "bevel", "round", "miter") - * @type String - * @default - */ - strokeLineJoin: 'round', - - /** - * Maximum miter length (used for strokeLineJoin = "miter") of a brush's - * @type Number - * @default - */ - strokeMiterLimit: 10, - - /** - * Stroke Dash Array. - * @type Array - * @default - */ - strokeDashArray: null, - - /** - * When `true`, the free drawing is limited to the whiteboard size. Default to false. - * @type Boolean - * @default false - */ - - limitedToCanvasSize: false, - - - /** - * Sets brush styles - * @private - */ - _setBrushStyles: function() { - var ctx = this.canvas.contextTop; - ctx.strokeStyle = this.color; - ctx.lineWidth = this.width; - ctx.lineCap = this.strokeLineCap; - ctx.miterLimit = this.strokeMiterLimit; - ctx.lineJoin = this.strokeLineJoin; - ctx.setLineDash(this.strokeDashArray || []); - }, - - /** - * Sets the transformation on given context - * @param {RenderingContext2d} ctx context to render on - * @private - */ - _saveAndTransform: function(ctx) { - var v = this.canvas.viewportTransform; - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - }, - - /** - * Sets brush shadow styles - * @private - */ - _setShadow: function() { - if (!this.shadow) { - return; - } - - var canvas = this.canvas, - shadow = this.shadow, - ctx = canvas.contextTop, - zoom = canvas.getZoom(); - if (canvas && canvas._isRetinaScaling()) { - zoom *= fabric.devicePixelRatio; - } - - ctx.shadowColor = shadow.color; - ctx.shadowBlur = shadow.blur * zoom; - ctx.shadowOffsetX = shadow.offsetX * zoom; - ctx.shadowOffsetY = shadow.offsetY * zoom; - }, - - needsFullRender: function() { - var color = new fabric.Color(this.color); - return color.getAlpha() < 1 || !!this.shadow; - }, - - /** - * Removes brush shadow styles - * @private - */ - _resetShadow: function() { - var ctx = this.canvas.contextTop; - - ctx.shadowColor = ''; - ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0; - }, - - /** - * Check is pointer is outside canvas boundaries - * @param {Object} pointer - * @private - */ - _isOutSideCanvas: function(pointer) { - return pointer.x < 0 || pointer.x > this.canvas.getWidth() || pointer.y < 0 || pointer.y > this.canvas.getHeight(); - } -}); - - -(function() { - /** - * PencilBrush class - * @class fabric.PencilBrush - * @extends fabric.BaseBrush - */ - fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.PencilBrush.prototype */ { - - /** - * Discard points that are less than `decimate` pixel distant from each other - * @type Number - * @default 0.4 - */ - decimate: 0.4, - - /** - * Constructor - * @param {fabric.Canvas} canvas - * @return {fabric.PencilBrush} Instance of a pencil brush - */ - initialize: function(canvas) { - this.canvas = canvas; - this._points = []; - }, - - /** - * Invoked inside on mouse down and mouse move - * @param {Object} pointer - */ - _drawSegment: function (ctx, p1, p2) { - var midPoint = p1.midPointFrom(p2); - ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y); - return midPoint; - }, - - /** - * Invoked on mouse down - * @param {Object} pointer - */ - onMouseDown: function(pointer, options) { - if (!this.canvas._isMainEvent(options.e)) { - return; - } - this._prepareForDrawing(pointer); - // capture coordinates immediately - // this allows to draw dots (when movement never occurs) - this._captureDrawingPath(pointer); - this._render(); - }, - - /** - * Invoked on mouse move - * @param {Object} pointer - */ - onMouseMove: function(pointer, options) { - if (!this.canvas._isMainEvent(options.e)) { - return; - } - if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) { - return; - } - if (this._captureDrawingPath(pointer) && this._points.length > 1) { - if (this.needsFullRender()) { - // redraw curve - // clear top canvas - this.canvas.clearContext(this.canvas.contextTop); - this._render(); - } - else { - var points = this._points, length = points.length, ctx = this.canvas.contextTop; - // draw the curve update - this._saveAndTransform(ctx); - if (this.oldEnd) { - ctx.beginPath(); - ctx.moveTo(this.oldEnd.x, this.oldEnd.y); - } - this.oldEnd = this._drawSegment(ctx, points[length - 2], points[length - 1], true); - ctx.stroke(); - ctx.restore(); - } - } - }, - - /** - * Invoked on mouse up - */ - onMouseUp: function(options) { - if (!this.canvas._isMainEvent(options.e)) { - return true; - } - this.oldEnd = undefined; - this._finalizeAndAddPath(); - return false; - }, - - /** - * @private - * @param {Object} pointer Actual mouse position related to the canvas. - */ - _prepareForDrawing: function(pointer) { - - var p = new fabric.Point(pointer.x, pointer.y); - - this._reset(); - this._addPoint(p); - this.canvas.contextTop.moveTo(p.x, p.y); - }, - - /** - * @private - * @param {fabric.Point} point Point to be added to points array - */ - _addPoint: function(point) { - if (this._points.length > 1 && point.eq(this._points[this._points.length - 1])) { - return false; - } - this._points.push(point); - return true; - }, - - /** - * Clear points array and set contextTop canvas style. - * @private - */ - _reset: function() { - this._points = []; - this._setBrushStyles(); - this._setShadow(); - }, - - /** - * @private - * @param {Object} pointer Actual mouse position related to the canvas. - */ - _captureDrawingPath: function(pointer) { - var pointerPoint = new fabric.Point(pointer.x, pointer.y); - return this._addPoint(pointerPoint); - }, - - /** - * Draw a smooth path on the topCanvas using quadraticCurveTo - * @private - */ - _render: function() { - var ctx = this.canvas.contextTop, i, len, - p1 = this._points[0], - p2 = this._points[1]; - - this._saveAndTransform(ctx); - ctx.beginPath(); - //if we only have 2 points in the path and they are the same - //it means that the user only clicked the canvas without moving the mouse - //then we should be drawing a dot. A path isn't drawn between two identical dots - //that's why we set them apart a bit - if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) { - var width = this.width / 1000; - p1 = new fabric.Point(p1.x, p1.y); - p2 = new fabric.Point(p2.x, p2.y); - p1.x -= width; - p2.x += width; - } - ctx.moveTo(p1.x, p1.y); - - for (i = 1, len = this._points.length; i < len; i++) { - // we pick the point between pi + 1 & pi + 2 as the - // end point and p1 as our control point. - this._drawSegment(ctx, p1, p2); - p1 = this._points[i]; - p2 = this._points[i + 1]; - } - // Draw last line as a straight line while - // we wait for the next point to be able to calculate - // the bezier control point - ctx.lineTo(p1.x, p1.y); - ctx.stroke(); - ctx.restore(); - }, - - /** - * Converts points to SVG path - * @param {Array} points Array of points - * @return {(string|number)[][]} SVG path commands - */ - convertPointsToSVGPath: function (points) { - var correction = this.width / 1000; - return fabric.util.getSmoothPathFromPoints(points, correction); - }, - - /** - * @private - * @param {(string|number)[][]} pathData SVG path commands - * @returns {boolean} - */ - _isEmptySVGPath: function (pathData) { - var pathString = fabric.util.joinPath(pathData); - return pathString === 'M 0 0 Q 0 0 0 0 L 0 0'; - }, - - /** - * Creates fabric.Path object to add on canvas - * @param {(string|number)[][]} pathData Path data - * @return {fabric.Path} Path to add on canvas - */ - createPath: function(pathData) { - var path = new fabric.Path(pathData, { - fill: null, - stroke: this.color, - strokeWidth: this.width, - strokeLineCap: this.strokeLineCap, - strokeMiterLimit: this.strokeMiterLimit, - strokeLineJoin: this.strokeLineJoin, - strokeDashArray: this.strokeDashArray, - }); - if (this.shadow) { - this.shadow.affectStroke = true; - path.shadow = new fabric.Shadow(this.shadow); - } - - return path; - }, - - /** - * Decimate points array with the decimate value - */ - decimatePoints: function(points, distance) { - if (points.length <= 2) { - return points; - } - var zoom = this.canvas.getZoom(), adjustedDistance = Math.pow(distance / zoom, 2), - i, l = points.length - 1, lastPoint = points[0], newPoints = [lastPoint], - cDistance; - for (i = 1; i < l - 1; i++) { - cDistance = Math.pow(lastPoint.x - points[i].x, 2) + Math.pow(lastPoint.y - points[i].y, 2); - if (cDistance >= adjustedDistance) { - lastPoint = points[i]; - newPoints.push(lastPoint); - } - } - /** - * Add the last point from the original line to the end of the array. - * This ensures decimate doesn't delete the last point on the line, and ensures the line is > 1 point. - */ - newPoints.push(points[l]); - return newPoints; - }, - - /** - * On mouseup after drawing the path on contextTop canvas - * we use the points captured to create an new fabric path object - * and add it to the fabric canvas. - */ - _finalizeAndAddPath: function() { - var ctx = this.canvas.contextTop; - ctx.closePath(); - if (this.decimate) { - this._points = this.decimatePoints(this._points, this.decimate); - } - var pathData = this.convertPointsToSVGPath(this._points); - if (this._isEmptySVGPath(pathData)) { - // do not create 0 width/height paths, as they are - // rendered inconsistently across browsers - // Firefox 4, for example, renders a dot, - // whereas Chrome 10 renders nothing - this.canvas.requestRenderAll(); - return; - } - - var path = this.createPath(pathData); - this.canvas.clearContext(this.canvas.contextTop); - this.canvas.fire('before:path:created', { path: path }); - this.canvas.add(path); - this.canvas.requestRenderAll(); - path.setCoords(); - this._resetShadow(); - - - // fire event 'path' created - this.canvas.fire('path:created', { path: path }); - } - }); -})(); - - -/** - * CircleBrush class - * @class fabric.CircleBrush - */ -fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.CircleBrush.prototype */ { - - /** - * Width of a brush - * @type Number - * @default - */ - width: 10, - - /** - * Constructor - * @param {fabric.Canvas} canvas - * @return {fabric.CircleBrush} Instance of a circle brush - */ - initialize: function(canvas) { - this.canvas = canvas; - this.points = []; - }, - - /** - * Invoked inside on mouse down and mouse move - * @param {Object} pointer - */ - drawDot: function(pointer) { - var point = this.addPoint(pointer), - ctx = this.canvas.contextTop; - this._saveAndTransform(ctx); - this.dot(ctx, point); - ctx.restore(); - }, - - dot: function(ctx, point) { - ctx.fillStyle = point.fill; - ctx.beginPath(); - ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false); - ctx.closePath(); - ctx.fill(); - }, - - /** - * Invoked on mouse down - */ - onMouseDown: function(pointer) { - this.points.length = 0; - this.canvas.clearContext(this.canvas.contextTop); - this._setShadow(); - this.drawDot(pointer); - }, - - /** - * Render the full state of the brush - * @private - */ - _render: function() { - var ctx = this.canvas.contextTop, i, len, - points = this.points; - this._saveAndTransform(ctx); - for (i = 0, len = points.length; i < len; i++) { - this.dot(ctx, points[i]); - } - ctx.restore(); - }, - - /** - * Invoked on mouse move - * @param {Object} pointer - */ - onMouseMove: function(pointer) { - if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) { - return; - } - if (this.needsFullRender()) { - this.canvas.clearContext(this.canvas.contextTop); - this.addPoint(pointer); - this._render(); - } - else { - this.drawDot(pointer); - } - }, - - /** - * Invoked on mouse up - */ - onMouseUp: function() { - var originalRenderOnAddRemove = this.canvas.renderOnAddRemove, i, len; - this.canvas.renderOnAddRemove = false; - - var circles = []; - - for (i = 0, len = this.points.length; i < len; i++) { - var point = this.points[i], - circle = new fabric.Circle({ - radius: point.radius, - left: point.x, - top: point.y, - originX: 'center', - originY: 'center', - fill: point.fill - }); - - this.shadow && (circle.shadow = new fabric.Shadow(this.shadow)); - - circles.push(circle); - } - var group = new fabric.Group(circles); - group.canvas = this.canvas; - - this.canvas.fire('before:path:created', { path: group }); - this.canvas.add(group); - this.canvas.fire('path:created', { path: group }); - - this.canvas.clearContext(this.canvas.contextTop); - this._resetShadow(); - this.canvas.renderOnAddRemove = originalRenderOnAddRemove; - this.canvas.requestRenderAll(); - }, - - /** - * @param {Object} pointer - * @return {fabric.Point} Just added pointer point - */ - addPoint: function(pointer) { - var pointerPoint = new fabric.Point(pointer.x, pointer.y), - - circleRadius = fabric.util.getRandomInt( - Math.max(0, this.width - 20), this.width + 20) / 2, - - circleColor = new fabric.Color(this.color) - .setAlpha(fabric.util.getRandomInt(0, 100) / 100) - .toRgba(); - - pointerPoint.radius = circleRadius; - pointerPoint.fill = circleColor; - - this.points.push(pointerPoint); - - return pointerPoint; - } -}); - - -/** - * SprayBrush class - * @class fabric.SprayBrush - */ -fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric.SprayBrush.prototype */ { - - /** - * Width of a spray - * @type Number - * @default - */ - width: 10, - - /** - * Density of a spray (number of dots per chunk) - * @type Number - * @default - */ - density: 20, - - /** - * Width of spray dots - * @type Number - * @default - */ - dotWidth: 1, - - /** - * Width variance of spray dots - * @type Number - * @default - */ - dotWidthVariance: 1, - - /** - * Whether opacity of a dot should be random - * @type Boolean - * @default - */ - randomOpacity: false, - - /** - * Whether overlapping dots (rectangles) should be removed (for performance reasons) - * @type Boolean - * @default - */ - optimizeOverlapping: true, - - /** - * Constructor - * @param {fabric.Canvas} canvas - * @return {fabric.SprayBrush} Instance of a spray brush - */ - initialize: function(canvas) { - this.canvas = canvas; - this.sprayChunks = []; - }, - - /** - * Invoked on mouse down - * @param {Object} pointer - */ - onMouseDown: function(pointer) { - this.sprayChunks.length = 0; - this.canvas.clearContext(this.canvas.contextTop); - this._setShadow(); - - this.addSprayChunk(pointer); - this.render(this.sprayChunkPoints); - }, - - /** - * Invoked on mouse move - * @param {Object} pointer - */ - onMouseMove: function(pointer) { - if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) { - return; - } - this.addSprayChunk(pointer); - this.render(this.sprayChunkPoints); - }, - - /** - * Invoked on mouse up - */ - onMouseUp: function() { - var originalRenderOnAddRemove = this.canvas.renderOnAddRemove; - this.canvas.renderOnAddRemove = false; - - var rects = []; - - for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) { - var sprayChunk = this.sprayChunks[i]; - - for (var j = 0, jlen = sprayChunk.length; j < jlen; j++) { - - var rect = new fabric.Rect({ - width: sprayChunk[j].width, - height: sprayChunk[j].width, - left: sprayChunk[j].x + 1, - top: sprayChunk[j].y + 1, - originX: 'center', - originY: 'center', - fill: this.color - }); - rects.push(rect); - } - } - - if (this.optimizeOverlapping) { - rects = this._getOptimizedRects(rects); - } - - var group = new fabric.Group(rects); - this.shadow && group.set('shadow', new fabric.Shadow(this.shadow)); - this.canvas.fire('before:path:created', { path: group }); - this.canvas.add(group); - this.canvas.fire('path:created', { path: group }); - - this.canvas.clearContext(this.canvas.contextTop); - this._resetShadow(); - this.canvas.renderOnAddRemove = originalRenderOnAddRemove; - this.canvas.requestRenderAll(); - }, - - /** - * @private - * @param {Array} rects - */ - _getOptimizedRects: function(rects) { - - // avoid creating duplicate rects at the same coordinates - var uniqueRects = { }, key, i, len; - - for (i = 0, len = rects.length; i < len; i++) { - key = rects[i].left + '' + rects[i].top; - if (!uniqueRects[key]) { - uniqueRects[key] = rects[i]; - } - } - var uniqueRectsArray = []; - for (key in uniqueRects) { - uniqueRectsArray.push(uniqueRects[key]); - } - - return uniqueRectsArray; - }, - - /** - * Render new chunk of spray brush - */ - render: function(sprayChunk) { - var ctx = this.canvas.contextTop, i, len; - ctx.fillStyle = this.color; - - this._saveAndTransform(ctx); - - for (i = 0, len = sprayChunk.length; i < len; i++) { - var point = sprayChunk[i]; - if (typeof point.opacity !== 'undefined') { - ctx.globalAlpha = point.opacity; - } - ctx.fillRect(point.x, point.y, point.width, point.width); - } - ctx.restore(); - }, - - /** - * Render all spray chunks - */ - _render: function() { - var ctx = this.canvas.contextTop, i, ilen; - ctx.fillStyle = this.color; - - this._saveAndTransform(ctx); - - for (i = 0, ilen = this.sprayChunks.length; i < ilen; i++) { - this.render(this.sprayChunks[i]); - } - ctx.restore(); - }, - - /** - * @param {Object} pointer - */ - addSprayChunk: function(pointer) { - this.sprayChunkPoints = []; - - var x, y, width, radius = this.width / 2, i; - - for (i = 0; i < this.density; i++) { - - x = fabric.util.getRandomInt(pointer.x - radius, pointer.x + radius); - y = fabric.util.getRandomInt(pointer.y - radius, pointer.y + radius); - - if (this.dotWidthVariance) { - width = fabric.util.getRandomInt( - // bottom clamp width to 1 - Math.max(1, this.dotWidth - this.dotWidthVariance), - this.dotWidth + this.dotWidthVariance); - } - else { - width = this.dotWidth; - } - - var point = new fabric.Point(x, y); - point.width = width; - - if (this.randomOpacity) { - point.opacity = fabric.util.getRandomInt(0, 100) / 100; - } - - this.sprayChunkPoints.push(point); - } - - this.sprayChunks.push(this.sprayChunkPoints); - } -}); - - -/** - * PatternBrush class - * @class fabric.PatternBrush - * @extends fabric.BaseBrush - */ -fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fabric.PatternBrush.prototype */ { - - getPatternSrc: function() { - - var dotWidth = 20, - dotDistance = 5, - patternCanvas = fabric.util.createCanvasElement(), - patternCtx = patternCanvas.getContext('2d'); - - patternCanvas.width = patternCanvas.height = dotWidth + dotDistance; - - patternCtx.fillStyle = this.color; - patternCtx.beginPath(); - patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false); - patternCtx.closePath(); - patternCtx.fill(); - - return patternCanvas; - }, - - getPatternSrcFunction: function() { - return String(this.getPatternSrc).replace('this.color', '"' + this.color + '"'); - }, - - /** - * Creates "pattern" instance property - */ - getPattern: function() { - return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), 'repeat'); - }, - - /** - * Sets brush styles - */ - _setBrushStyles: function() { - this.callSuper('_setBrushStyles'); - this.canvas.contextTop.strokeStyle = this.getPattern(); - }, - - /** - * Creates path - */ - createPath: function(pathData) { - var path = this.callSuper('createPath', pathData), - topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2); - - path.stroke = new fabric.Pattern({ - source: this.source || this.getPatternSrcFunction(), - offsetX: -topLeft.x, - offsetY: -topLeft.y - }); - return path; - } -}); - - -(function() { - - var getPointer = fabric.util.getPointer, - degreesToRadians = fabric.util.degreesToRadians, - isTouchEvent = fabric.util.isTouchEvent; - - /** - * Canvas class - * @class fabric.Canvas - * @extends fabric.StaticCanvas - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas} - * @see {@link fabric.Canvas#initialize} for constructor definition - * - * @fires object:modified at the end of a transform or any change when statefull is true - * @fires object:rotating while an object is being rotated from the control - * @fires object:scaling while an object is being scaled by controls - * @fires object:moving while an object is being dragged - * @fires object:skewing while an object is being skewed from the controls - * - * @fires before:transform before a transform is is started - * @fires before:selection:cleared - * @fires selection:cleared - * @fires selection:updated - * @fires selection:created - * - * @fires path:created after a drawing operation ends and the path is added - * @fires mouse:down - * @fires mouse:move - * @fires mouse:up - * @fires mouse:down:before on mouse down, before the inner fabric logic runs - * @fires mouse:move:before on mouse move, before the inner fabric logic runs - * @fires mouse:up:before on mouse up, before the inner fabric logic runs - * @fires mouse:over - * @fires mouse:out - * @fires mouse:dblclick whenever a native dbl click event fires on the canvas. - * - * @fires dragover - * @fires dragenter - * @fires dragleave - * @fires drop - * @fires after:render at the end of the render process, receives the context in the callback - * @fires before:render at start the render process, receives the context in the callback - * - * the following events are deprecated: - * @fires object:rotated at the end of a rotation transform - * @fires object:scaled at the end of a scale transform - * @fires object:moved at the end of translation transform - * @fires object:skewed at the end of a skew transform - */ - fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, /** @lends fabric.Canvas.prototype */ { - - /** - * Constructor - * @param {HTMLElement | String} el <canvas> element to initialize instance on - * @param {Object} [options] Options object - * @return {Object} thisArg - */ - initialize: function(el, options) { - options || (options = { }); - this.renderAndResetBound = this.renderAndReset.bind(this); - this.requestRenderAllBound = this.requestRenderAll.bind(this); - this._initStatic(el, options); - this._initInteractive(); - this._createCacheCanvas(); - }, - - /** - * When true, objects can be transformed by one side (unproportionally) - * when dragged on the corners that normally would not do that. - * @type Boolean - * @default - * @since fabric 4.0 // changed name and default value - */ - uniformScaling: true, - - /** - * Indicates which key switches uniform scaling. - * values: 'altKey', 'shiftKey', 'ctrlKey'. - * If `null` or 'none' or any other string that is not a modifier key - * feature is disabled. - * totally wrong named. this sounds like `uniform scaling` - * if Canvas.uniformScaling is true, pressing this will set it to false - * and viceversa. - * @since 1.6.2 - * @type String - * @default - */ - uniScaleKey: 'shiftKey', - - /** - * When true, objects use center point as the origin of scale transformation. - * Backwards incompatibility note: This property replaces "centerTransform" (Boolean). - * @since 1.3.4 - * @type Boolean - * @default - */ - centeredScaling: false, - - /** - * When true, objects use center point as the origin of rotate transformation. - * Backwards incompatibility note: This property replaces "centerTransform" (Boolean). - * @since 1.3.4 - * @type Boolean - * @default - */ - centeredRotation: false, - - /** - * Indicates which key enable centered Transform - * values: 'altKey', 'shiftKey', 'ctrlKey'. - * If `null` or 'none' or any other string that is not a modifier key - * feature is disabled feature disabled. - * @since 1.6.2 - * @type String - * @default - */ - centeredKey: 'altKey', - - /** - * Indicates which key enable alternate action on corner - * values: 'altKey', 'shiftKey', 'ctrlKey'. - * If `null` or 'none' or any other string that is not a modifier key - * feature is disabled feature disabled. - * @since 1.6.2 - * @type String - * @default - */ - altActionKey: 'shiftKey', - - /** - * Indicates that canvas is interactive. This property should not be changed. - * @type Boolean - * @default - */ - interactive: true, - - /** - * Indicates whether group selection should be enabled - * @type Boolean - * @default - */ - selection: true, - - /** - * Indicates which key or keys enable multiple click selection - * Pass value as a string or array of strings - * values: 'altKey', 'shiftKey', 'ctrlKey'. - * If `null` or empty or containing any other string that is not a modifier key - * feature is disabled. - * @since 1.6.2 - * @type String|Array - * @default - */ - selectionKey: 'shiftKey', - - /** - * Indicates which key enable alternative selection - * in case of target overlapping with active object - * values: 'altKey', 'shiftKey', 'ctrlKey'. - * For a series of reason that come from the general expectations on how - * things should work, this feature works only for preserveObjectStacking true. - * If `null` or 'none' or any other string that is not a modifier key - * feature is disabled. - * @since 1.6.5 - * @type null|String - * @default - */ - altSelectionKey: null, - - /** - * Color of selection - * @type String - * @default - */ - selectionColor: 'rgba(100, 100, 255, 0.3)', // blue - - /** - * Default dash array pattern - * If not empty the selection border is dashed - * @type Array - */ - selectionDashArray: [], - - /** - * Color of the border of selection (usually slightly darker than color of selection itself) - * @type String - * @default - */ - selectionBorderColor: 'rgba(255, 255, 255, 0.3)', - - /** - * Width of a line used in object/group selection - * @type Number - * @default - */ - selectionLineWidth: 1, - - /** - * Select only shapes that are fully contained in the dragged selection rectangle. - * @type Boolean - * @default - */ - selectionFullyContained: false, - - /** - * Default cursor value used when hovering over an object on canvas - * @type String - * @default - */ - hoverCursor: 'move', - - /** - * Default cursor value used when moving an object on canvas - * @type String - * @default - */ - moveCursor: 'move', - - /** - * Default cursor value used for the entire canvas - * @type String - * @default - */ - defaultCursor: 'default', - - /** - * Cursor value used during free drawing - * @type String - * @default - */ - freeDrawingCursor: 'crosshair', - - /** - * Cursor value used for rotation point - * @type String - * @default - */ - rotationCursor: 'crosshair', - - /** - * Cursor value used for disabled elements ( corners with disabled action ) - * @type String - * @since 2.0.0 - * @default - */ - notAllowedCursor: 'not-allowed', - - /** - * Default element class that's given to wrapper (div) element of canvas - * @type String - * @default - */ - containerClass: 'canvas-container', - - /** - * When true, object detection happens on per-pixel basis rather than on per-bounding-box - * @type Boolean - * @default - */ - perPixelTargetFind: false, - - /** - * Number of pixels around target pixel to tolerate (consider active) during object detection - * @type Number - * @default - */ - targetFindTolerance: 0, - - /** - * When true, target detection is skipped. Target detection will return always undefined. - * click selection won't work anymore, events will fire with no targets. - * if something is selected before setting it to true, it will be deselected at the first click. - * area selection will still work. check the `selection` property too. - * if you deactivate both, you should look into staticCanvas. - * @type Boolean - * @default - */ - skipTargetFind: false, - - /** - * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing. - * After mousedown, mousemove creates a shape, - * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas. - * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing} - * @type Boolean - * @default - */ - isDrawingMode: false, - - /** - * Indicates whether objects should remain in current stack position when selected. - * When false objects are brought to top and rendered as part of the selection group - * @type Boolean - * @default - */ - preserveObjectStacking: false, - - /** - * Indicates the angle that an object will lock to while rotating. - * @type Number - * @since 1.6.7 - * @default - */ - snapAngle: 0, - - /** - * Indicates the distance from the snapAngle the rotation will lock to the snapAngle. - * When `null`, the snapThreshold will default to the snapAngle. - * @type null|Number - * @since 1.6.7 - * @default - */ - snapThreshold: null, - - /** - * Indicates if the right click on canvas can output the context menu or not - * @type Boolean - * @since 1.6.5 - * @default - */ - stopContextMenu: false, - - /** - * Indicates if the canvas can fire right click events - * @type Boolean - * @since 1.6.5 - * @default - */ - fireRightClick: false, - - /** - * Indicates if the canvas can fire middle click events - * @type Boolean - * @since 1.7.8 - * @default - */ - fireMiddleClick: false, - - /** - * Keep track of the subTargets for Mouse Events - * @type fabric.Object[] - */ - targets: [], - - /** - * Keep track of the hovered target - * @type fabric.Object - * @private - */ - _hoveredTarget: null, - - /** - * hold the list of nested targets hovered - * @type fabric.Object[] - * @private - */ - _hoveredTargets: [], - - /** - * @private - */ - _initInteractive: function() { - this._currentTransform = null; - this._groupSelector = null; - this._initWrapperElement(); - this._createUpperCanvas(); - this._initEventListeners(); - - this._initRetinaScaling(); - - this.freeDrawingBrush = fabric.PencilBrush && new fabric.PencilBrush(this); - - this.calcOffset(); - }, - - /** - * Divides objects in two groups, one to render immediately - * and one to render as activeGroup. - * @return {Array} objects to render immediately and pushes the other in the activeGroup. - */ - _chooseObjectsToRender: function() { - var activeObjects = this.getActiveObjects(), - object, objsToRender, activeGroupObjects; - - if (activeObjects.length > 0 && !this.preserveObjectStacking) { - objsToRender = []; - activeGroupObjects = []; - for (var i = 0, length = this._objects.length; i < length; i++) { - object = this._objects[i]; - if (activeObjects.indexOf(object) === -1 ) { - objsToRender.push(object); - } - else { - activeGroupObjects.push(object); - } - } - if (activeObjects.length > 1) { - this._activeObject._objects = activeGroupObjects; - } - objsToRender.push.apply(objsToRender, activeGroupObjects); - } - else { - objsToRender = this._objects; - } - return objsToRender; - }, - - /** - * Renders both the top canvas and the secondary container canvas. - * @return {fabric.Canvas} instance - * @chainable - */ - renderAll: function () { - if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) { - this.clearContext(this.contextTop); - this.contextTopDirty = false; - } - if (this.hasLostContext) { - this.renderTopLayer(this.contextTop); - } - var canvasToDrawOn = this.contextContainer; - this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender()); - return this; - }, - - renderTopLayer: function(ctx) { - ctx.save(); - if (this.isDrawingMode && this._isCurrentlyDrawing) { - this.freeDrawingBrush && this.freeDrawingBrush._render(); - this.contextTopDirty = true; - } - // we render the top context - last object - if (this.selection && this._groupSelector) { - this._drawSelection(ctx); - this.contextTopDirty = true; - } - ctx.restore(); - }, - - /** - * Method to render only the top canvas. - * Also used to render the group selection box. - * @return {fabric.Canvas} thisArg - * @chainable - */ - renderTop: function () { - var ctx = this.contextTop; - this.clearContext(ctx); - this.renderTopLayer(ctx); - this.fire('after:render'); - return this; - }, - - /** - * @private - */ - _normalizePointer: function (object, pointer) { - var m = object.calcTransformMatrix(), - invertedM = fabric.util.invertTransform(m), - vptPointer = this.restorePointerVpt(pointer); - return fabric.util.transformPoint(vptPointer, invertedM); - }, - - /** - * Returns true if object is transparent at a certain location - * @param {fabric.Object} target Object to check - * @param {Number} x Left coordinate - * @param {Number} y Top coordinate - * @return {Boolean} - */ - isTargetTransparent: function (target, x, y) { - // in case the target is the activeObject, we cannot execute this optimization - // because we need to draw controls too. - if (target.shouldCache() && target._cacheCanvas && target !== this._activeObject) { - var normalizedPointer = this._normalizePointer(target, {x: x, y: y}), - targetRelativeX = Math.max(target.cacheTranslationX + (normalizedPointer.x * target.zoomX), 0), - targetRelativeY = Math.max(target.cacheTranslationY + (normalizedPointer.y * target.zoomY), 0); - - var isTransparent = fabric.util.isTransparent( - target._cacheContext, Math.round(targetRelativeX), Math.round(targetRelativeY), this.targetFindTolerance); - - return isTransparent; - } - - var ctx = this.contextCache, - originalColor = target.selectionBackgroundColor, v = this.viewportTransform; - - target.selectionBackgroundColor = ''; - - this.clearContext(ctx); - - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - target.render(ctx); - ctx.restore(); - - target.selectionBackgroundColor = originalColor; - - var isTransparent = fabric.util.isTransparent( - ctx, x, y, this.targetFindTolerance); - - return isTransparent; - }, - - /** - * takes an event and determines if selection key has been pressed - * @private - * @param {Event} e Event object - */ - _isSelectionKeyPressed: function(e) { - var selectionKeyPressed = false; - - if (Object.prototype.toString.call(this.selectionKey) === '[object Array]') { - selectionKeyPressed = !!this.selectionKey.find(function(key) { return e[key] === true; }); - } - else { - selectionKeyPressed = e[this.selectionKey]; - } - - return selectionKeyPressed; - }, - - /** - * @private - * @param {Event} e Event object - * @param {fabric.Object} target - */ - _shouldClearSelection: function (e, target) { - var activeObjects = this.getActiveObjects(), - activeObject = this._activeObject; - - return ( - !target - || - (target && - activeObject && - activeObjects.length > 1 && - activeObjects.indexOf(target) === -1 && - activeObject !== target && - !this._isSelectionKeyPressed(e)) - || - (target && !target.evented) - || - (target && - !target.selectable && - activeObject && - activeObject !== target) - ); - }, - - /** - * centeredScaling from object can't override centeredScaling from canvas. - * this should be fixed, since object setting should take precedence over canvas. - * also this should be something that will be migrated in the control properties. - * as ability to define the origin of the transformation that the control provide. - * @private - * @param {fabric.Object} target - * @param {String} action - * @param {Boolean} altKey - */ - _shouldCenterTransform: function (target, action, altKey) { - if (!target) { - return; - } - - var centerTransform; - - if (action === 'scale' || action === 'scaleX' || action === 'scaleY' || action === 'resizing') { - centerTransform = this.centeredScaling || target.centeredScaling; - } - else if (action === 'rotate') { - centerTransform = this.centeredRotation || target.centeredRotation; - } - - return centerTransform ? !altKey : altKey; - }, - - /** - * should disappear before release 4.0 - * @private - */ - _getOriginFromCorner: function(target, corner) { - var origin = { - x: target.originX, - y: target.originY - }; - - if (corner === 'ml' || corner === 'tl' || corner === 'bl') { - origin.x = 'right'; - } - else if (corner === 'mr' || corner === 'tr' || corner === 'br') { - origin.x = 'left'; - } - - if (corner === 'tl' || corner === 'mt' || corner === 'tr') { - origin.y = 'bottom'; - } - else if (corner === 'bl' || corner === 'mb' || corner === 'br') { - origin.y = 'top'; - } - return origin; - }, - - /** - * @private - * @param {Boolean} alreadySelected true if target is already selected - * @param {String} corner a string representing the corner ml, mr, tl ... - * @param {Event} e Event object - * @param {fabric.Object} [target] inserted back to help overriding. Unused - */ - _getActionFromCorner: function(alreadySelected, corner, e, target) { - if (!corner || !alreadySelected) { - return 'drag'; - } - var control = target.controls[corner]; - return control.getActionName(e, control, target); - }, - - /** - * @private - * @param {Event} e Event object - * @param {fabric.Object} target - */ - _setupCurrentTransform: function (e, target, alreadySelected) { - if (!target) { - return; - } - - var pointer = this.getPointer(e), corner = target.__corner, - control = target.controls[corner], - actionHandler = (alreadySelected && corner) ? - control.getActionHandler(e, target, control) : fabric.controlsUtils.dragHandler, - action = this._getActionFromCorner(alreadySelected, corner, e, target), - origin = this._getOriginFromCorner(target, corner), - altKey = e[this.centeredKey], - transform = { - target: target, - action: action, - actionHandler: actionHandler, - corner: corner, - scaleX: target.scaleX, - scaleY: target.scaleY, - skewX: target.skewX, - skewY: target.skewY, - // used by transation - offsetX: pointer.x - target.left, - offsetY: pointer.y - target.top, - originX: origin.x, - originY: origin.y, - ex: pointer.x, - ey: pointer.y, - lastX: pointer.x, - lastY: pointer.y, - // unsure they are useful anymore. - // left: target.left, - // top: target.top, - theta: degreesToRadians(target.angle), - // end of unsure - width: target.width * target.scaleX, - shiftKey: e.shiftKey, - altKey: altKey, - original: fabric.util.saveObjectTransform(target), - }; - - if (this._shouldCenterTransform(target, action, altKey)) { - transform.originX = 'center'; - transform.originY = 'center'; - } - transform.original.originX = origin.x; - transform.original.originY = origin.y; - this._currentTransform = transform; - this._beforeTransform(e); - }, - - /** - * Set the cursor type of the canvas element - * @param {String} value Cursor type of the canvas element. - * @see http://www.w3.org/TR/css3-ui/#cursor - */ - setCursor: function (value) { - this.upperCanvasEl.style.cursor = value; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx to draw the selection on - */ - _drawSelection: function (ctx) { - var selector = this._groupSelector, - viewportStart = new fabric.Point(selector.ex, selector.ey), - start = fabric.util.transformPoint(viewportStart, this.viewportTransform), - viewportExtent = new fabric.Point(selector.ex + selector.left, selector.ey + selector.top), - extent = fabric.util.transformPoint(viewportExtent, this.viewportTransform), - minX = Math.min(start.x, extent.x), - minY = Math.min(start.y, extent.y), - maxX = Math.max(start.x, extent.x), - maxY = Math.max(start.y, extent.y), - strokeOffset = this.selectionLineWidth / 2; - - if (this.selectionColor) { - ctx.fillStyle = this.selectionColor; - ctx.fillRect(minX, minY, maxX - minX, maxY - minY); - } - - if (!this.selectionLineWidth || !this.selectionBorderColor) { - return; - } - ctx.lineWidth = this.selectionLineWidth; - ctx.strokeStyle = this.selectionBorderColor; - - minX += strokeOffset; - minY += strokeOffset; - maxX -= strokeOffset; - maxY -= strokeOffset; - // selection border - fabric.Object.prototype._setLineDash.call(this, ctx, this.selectionDashArray); - ctx.strokeRect(minX, minY, maxX - minX, maxY - minY); - }, - - /** - * Method that determines what object we are clicking on - * the skipGroup parameter is for internal use, is needed for shift+click action - * 11/09/2018 TODO: would be cool if findTarget could discern between being a full target - * or the outside part of the corner. - * @param {Event} e mouse event - * @param {Boolean} skipGroup when true, activeGroup is skipped and only objects are traversed through - * @return {fabric.Object} the target found - */ - findTarget: function (e, skipGroup) { - if (this.skipTargetFind) { - return; - } - - var ignoreZoom = true, - pointer = this.getPointer(e, ignoreZoom), - activeObject = this._activeObject, - aObjects = this.getActiveObjects(), - activeTarget, activeTargetSubs, - isTouch = isTouchEvent(e), - shouldLookForActive = (aObjects.length > 1 && !skipGroup) || aObjects.length === 1; - - // first check current group (if one exists) - // active group does not check sub targets like normal groups. - // if active group just exits. - this.targets = []; - - // if we hit the corner of an activeObject, let's return that. - if (shouldLookForActive && activeObject._findTargetCorner(pointer, isTouch)) { - return activeObject; - } - if (aObjects.length > 1 && !skipGroup && activeObject === this._searchPossibleTargets([activeObject], pointer)) { - return activeObject; - } - if (aObjects.length === 1 && - activeObject === this._searchPossibleTargets([activeObject], pointer)) { - if (!this.preserveObjectStacking) { - return activeObject; - } - else { - activeTarget = activeObject; - activeTargetSubs = this.targets; - this.targets = []; - } - } - var target = this._searchPossibleTargets(this._objects, pointer); - if (e[this.altSelectionKey] && target && activeTarget && target !== activeTarget) { - target = activeTarget; - this.targets = activeTargetSubs; - } - return target; - }, - - /** - * Checks point is inside the object. - * @param {Object} [pointer] x,y object of point coordinates we want to check. - * @param {fabric.Object} obj Object to test against - * @param {Object} [globalPointer] x,y object of point coordinates relative to canvas used to search per pixel target. - * @return {Boolean} true if point is contained within an area of given object - * @private - */ - _checkTarget: function(pointer, obj, globalPointer) { - if (obj && - obj.visible && - obj.evented && - // http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html - // http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html - obj.containsPoint(pointer) - ) { - if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) { - var isTransparent = this.isTargetTransparent(obj, globalPointer.x, globalPointer.y); - if (!isTransparent) { - return true; - } - } - else { - return true; - } - } - }, - - /** - * Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted - * @param {Array} [objects] objects array to look into - * @param {Object} [pointer] x,y object of point coordinates we want to check. - * @return {fabric.Object} object that contains pointer - * @private - */ - _searchPossibleTargets: function(objects, pointer) { - // Cache all targets where their bounding box contains point. - var target, i = objects.length, subTarget; - // Do not check for currently grouped objects, since we check the parent group itself. - // until we call this function specifically to search inside the activeGroup - while (i--) { - var objToCheck = objects[i]; - var pointerToUse = objToCheck.group ? - this._normalizePointer(objToCheck.group, pointer) : pointer; - if (this._checkTarget(pointerToUse, objToCheck, pointer)) { - target = objects[i]; - if (target.subTargetCheck && target instanceof fabric.Group) { - subTarget = this._searchPossibleTargets(target._objects, pointer); - subTarget && this.targets.push(subTarget); - } - break; - } - } - return target; - }, - - /** - * Returns pointer coordinates without the effect of the viewport - * @param {Object} pointer with "x" and "y" number values - * @return {Object} object with "x" and "y" number values - */ - restorePointerVpt: function(pointer) { - return fabric.util.transformPoint( - pointer, - fabric.util.invertTransform(this.viewportTransform) - ); - }, - - /** - * Returns pointer coordinates relative to canvas. - * Can return coordinates with or without viewportTransform. - * ignoreZoom false gives back coordinates that represent - * the point clicked on canvas element. - * ignoreZoom true gives back coordinates after being processed - * by the viewportTransform ( sort of coordinates of what is displayed - * on the canvas where you are clicking. - * ignoreZoom true = HTMLElement coordinates relative to top,left - * ignoreZoom false, default = fabric space coordinates, the same used for shape position - * To interact with your shapes top and left you want to use ignoreZoom true - * most of the time, while ignoreZoom false will give you coordinates - * compatible with the object.oCoords system. - * of the time. - * @param {Event} e - * @param {Boolean} ignoreZoom - * @return {Object} object with "x" and "y" number values - */ - getPointer: function (e, ignoreZoom) { - // return cached values if we are in the event processing chain - if (this._absolutePointer && !ignoreZoom) { - return this._absolutePointer; - } - if (this._pointer && ignoreZoom) { - return this._pointer; - } - - var pointer = getPointer(e), - upperCanvasEl = this.upperCanvasEl, - bounds = upperCanvasEl.getBoundingClientRect(), - boundsWidth = bounds.width || 0, - boundsHeight = bounds.height || 0, - cssScale; - - if (!boundsWidth || !boundsHeight ) { - if ('top' in bounds && 'bottom' in bounds) { - boundsHeight = Math.abs( bounds.top - bounds.bottom ); - } - if ('right' in bounds && 'left' in bounds) { - boundsWidth = Math.abs( bounds.right - bounds.left ); - } - } - - this.calcOffset(); - pointer.x = pointer.x - this._offset.left; - pointer.y = pointer.y - this._offset.top; - if (!ignoreZoom) { - pointer = this.restorePointerVpt(pointer); - } - - var retinaScaling = this.getRetinaScaling(); - if (retinaScaling !== 1) { - pointer.x /= retinaScaling; - pointer.y /= retinaScaling; - } - - if (boundsWidth === 0 || boundsHeight === 0) { - // If bounds are not available (i.e. not visible), do not apply scale. - cssScale = { width: 1, height: 1 }; - } - else { - cssScale = { - width: upperCanvasEl.width / boundsWidth, - height: upperCanvasEl.height / boundsHeight - }; - } - - return { - x: pointer.x * cssScale.width, - y: pointer.y * cssScale.height - }; - }, - - /** - * @private - * @throws {CANVAS_INIT_ERROR} If canvas can not be initialized - */ - _createUpperCanvas: function () { - var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/, ''), - lowerCanvasEl = this.lowerCanvasEl, upperCanvasEl = this.upperCanvasEl; - - // there is no need to create a new upperCanvas element if we have already one. - if (upperCanvasEl) { - upperCanvasEl.className = ''; - } - else { - upperCanvasEl = this._createCanvasElement(); - this.upperCanvasEl = upperCanvasEl; - } - fabric.util.addClass(upperCanvasEl, 'upper-canvas ' + lowerCanvasClass); - - this.wrapperEl.appendChild(upperCanvasEl); - - this._copyCanvasStyle(lowerCanvasEl, upperCanvasEl); - this._applyCanvasStyle(upperCanvasEl); - this.contextTop = upperCanvasEl.getContext('2d'); - }, - - /** - * @private - */ - _createCacheCanvas: function () { - this.cacheCanvasEl = this._createCanvasElement(); - this.cacheCanvasEl.setAttribute('width', this.width); - this.cacheCanvasEl.setAttribute('height', this.height); - this.contextCache = this.cacheCanvasEl.getContext('2d'); - }, - - /** - * @private - */ - _initWrapperElement: function () { - this.wrapperEl = fabric.util.wrapElement(this.lowerCanvasEl, 'div', { - 'class': this.containerClass - }); - fabric.util.setStyle(this.wrapperEl, { - width: this.width + 'px', - height: this.height + 'px', - position: 'relative' - }); - fabric.util.makeElementUnselectable(this.wrapperEl); - }, - - /** - * @private - * @param {HTMLElement} element canvas element to apply styles on - */ - _applyCanvasStyle: function (element) { - var width = this.width || element.width, - height = this.height || element.height; - - fabric.util.setStyle(element, { - position: 'absolute', - width: width + 'px', - height: height + 'px', - left: 0, - top: 0, - 'touch-action': this.allowTouchScrolling ? 'manipulation' : 'none', - '-ms-touch-action': this.allowTouchScrolling ? 'manipulation' : 'none' - }); - element.width = width; - element.height = height; - fabric.util.makeElementUnselectable(element); - }, - - /** - * Copy the entire inline style from one element (fromEl) to another (toEl) - * @private - * @param {Element} fromEl Element style is copied from - * @param {Element} toEl Element copied style is applied to - */ - _copyCanvasStyle: function (fromEl, toEl) { - toEl.style.cssText = fromEl.style.cssText; - }, - - /** - * Returns context of canvas where object selection is drawn - * @return {CanvasRenderingContext2D} - */ - getSelectionContext: function() { - return this.contextTop; - }, - - /** - * Returns <canvas> element on which object selection is drawn - * @return {HTMLCanvasElement} - */ - getSelectionElement: function () { - return this.upperCanvasEl; - }, - - /** - * Returns currently active object - * @return {fabric.Object} active object - */ - getActiveObject: function () { - return this._activeObject; - }, - - /** - * Returns an array with the current selected objects - * @return {fabric.Object} active object - */ - getActiveObjects: function () { - var active = this._activeObject; - if (active) { - if (active.type === 'activeSelection' && active._objects) { - return active._objects.slice(0); - } - else { - return [active]; - } - } - return []; - }, - - /** - * @private - * @param {fabric.Object} obj Object that was removed - */ - _onObjectRemoved: function(obj) { - // removing active object should fire "selection:cleared" events - if (obj === this._activeObject) { - this.fire('before:selection:cleared', { target: obj }); - this._discardActiveObject(); - this.fire('selection:cleared', { target: obj }); - obj.fire('deselected'); - } - if (obj === this._hoveredTarget){ - this._hoveredTarget = null; - this._hoveredTargets = []; - } - this.callSuper('_onObjectRemoved', obj); - }, - - /** - * @private - * Compares the old activeObject with the current one and fires correct events - * @param {fabric.Object} obj old activeObject - */ - _fireSelectionEvents: function(oldObjects, e) { - var somethingChanged = false, objects = this.getActiveObjects(), - added = [], removed = []; - oldObjects.forEach(function(oldObject) { - if (objects.indexOf(oldObject) === -1) { - somethingChanged = true; - oldObject.fire('deselected', { - e: e, - target: oldObject - }); - removed.push(oldObject); - } - }); - objects.forEach(function(object) { - if (oldObjects.indexOf(object) === -1) { - somethingChanged = true; - object.fire('selected', { - e: e, - target: object - }); - added.push(object); - } - }); - if (oldObjects.length > 0 && objects.length > 0) { - somethingChanged && this.fire('selection:updated', { - e: e, - selected: added, - deselected: removed, - // added for backward compatibility - // deprecated - updated: added[0] || removed[0], - target: this._activeObject, - }); - } - else if (objects.length > 0) { - this.fire('selection:created', { - e: e, - selected: added, - target: this._activeObject, - }); - } - else if (oldObjects.length > 0) { - this.fire('selection:cleared', { - e: e, - deselected: removed, - }); - } - }, - - /** - * Sets given object as the only active object on canvas - * @param {fabric.Object} object Object to set as an active one - * @param {Event} [e] Event (passed along when firing "object:selected") - * @return {fabric.Canvas} thisArg - * @chainable - */ - setActiveObject: function (object, e) { - var currentActives = this.getActiveObjects(); - this._setActiveObject(object, e); - this._fireSelectionEvents(currentActives, e); - return this; - }, - - /** - * This is a private method for now. - * This is supposed to be equivalent to setActiveObject but without firing - * any event. There is commitment to have this stay this way. - * This is the functional part of setActiveObject. - * @private - * @param {Object} object to set as active - * @param {Event} [e] Event (passed along when firing "object:selected") - * @return {Boolean} true if the selection happened - */ - _setActiveObject: function(object, e) { - if (this._activeObject === object) { - return false; - } - if (!this._discardActiveObject(e, object)) { - return false; - } - if (object.onSelect({ e: e })) { - return false; - } - this._activeObject = object; - return true; - }, - - /** - * This is a private method for now. - * This is supposed to be equivalent to discardActiveObject but without firing - * any events. There is commitment to have this stay this way. - * This is the functional part of discardActiveObject. - * @param {Event} [e] Event (passed along when firing "object:deselected") - * @param {Object} object to set as active - * @return {Boolean} true if the selection happened - * @private - */ - _discardActiveObject: function(e, object) { - var obj = this._activeObject; - if (obj) { - // onDeselect return TRUE to cancel selection; - if (obj.onDeselect({ e: e, object: object })) { - return false; - } - this._activeObject = null; - } - return true; - }, - - /** - * Discards currently active object and fire events. If the function is called by fabric - * as a consequence of a mouse event, the event is passed as a parameter and - * sent to the fire function for the custom events. When used as a method the - * e param does not have any application. - * @param {event} e - * @return {fabric.Canvas} thisArg - * @chainable - */ - discardActiveObject: function (e) { - var currentActives = this.getActiveObjects(), activeObject = this.getActiveObject(); - if (currentActives.length) { - this.fire('before:selection:cleared', { target: activeObject, e: e }); - } - this._discardActiveObject(e); - this._fireSelectionEvents(currentActives, e); - return this; - }, - - /** - * Clears a canvas element and removes all event listeners - * @return {fabric.Canvas} thisArg - * @chainable - */ - dispose: function () { - var wrapper = this.wrapperEl; - this.removeListeners(); - wrapper.removeChild(this.upperCanvasEl); - wrapper.removeChild(this.lowerCanvasEl); - this.contextCache = null; - this.contextTop = null; - ['upperCanvasEl', 'cacheCanvasEl'].forEach((function(element) { - fabric.util.cleanUpJsdomNode(this[element]); - this[element] = undefined; - }).bind(this)); - if (wrapper.parentNode) { - wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl); - } - delete this.wrapperEl; - fabric.StaticCanvas.prototype.dispose.call(this); - return this; - }, - - /** - * Clears all contexts (background, main, top) of an instance - * @return {fabric.Canvas} thisArg - * @chainable - */ - clear: function () { - // this.discardActiveGroup(); - this.discardActiveObject(); - this.clearContext(this.contextTop); - return this.callSuper('clear'); - }, - - /** - * Draws objects' controls (borders/controls) - * @param {CanvasRenderingContext2D} ctx Context to render controls on - */ - drawControls: function(ctx) { - var activeObject = this._activeObject; - - if (activeObject) { - activeObject._renderControls(ctx); - } - }, - - /** - * @private - */ - _toObject: function(instance, methodName, propertiesToInclude) { - //If the object is part of the current selection group, it should - //be transformed appropriately - //i.e. it should be serialised as it would appear if the selection group - //were to be destroyed. - var originalProperties = this._realizeGroupTransformOnObject(instance), - object = this.callSuper('_toObject', instance, methodName, propertiesToInclude); - //Undo the damage we did by changing all of its properties - this._unwindGroupTransformOnObject(instance, originalProperties); - return object; - }, - - /** - * Realises an object's group transformation on it - * @private - * @param {fabric.Object} [instance] the object to transform (gets mutated) - * @returns the original values of instance which were changed - */ - _realizeGroupTransformOnObject: function(instance) { - if (instance.group && instance.group.type === 'activeSelection' && this._activeObject === instance.group) { - var layoutProps = ['angle', 'flipX', 'flipY', 'left', 'scaleX', 'scaleY', 'skewX', 'skewY', 'top']; - //Copy all the positionally relevant properties across now - var originalValues = {}; - layoutProps.forEach(function(prop) { - originalValues[prop] = instance[prop]; - }); - fabric.util.addTransformToObject(instance, this._activeObject.calcOwnMatrix()); - return originalValues; - } - else { - return null; - } - }, - - /** - * Restores the changed properties of instance - * @private - * @param {fabric.Object} [instance] the object to un-transform (gets mutated) - * @param {Object} [originalValues] the original values of instance, as returned by _realizeGroupTransformOnObject - */ - _unwindGroupTransformOnObject: function(instance, originalValues) { - if (originalValues) { - instance.set(originalValues); - } - }, - - /** - * @private - */ - _setSVGObject: function(markup, instance, reviver) { - //If the object is in a selection group, simulate what would happen to that - //object when the group is deselected - var originalProperties = this._realizeGroupTransformOnObject(instance); - this.callSuper('_setSVGObject', markup, instance, reviver); - this._unwindGroupTransformOnObject(instance, originalProperties); - }, - - setViewportTransform: function (vpt) { - if (this.renderOnAddRemove && this._activeObject && this._activeObject.isEditing) { - this._activeObject.clearContextTop(); - } - fabric.StaticCanvas.prototype.setViewportTransform.call(this, vpt); - } - }); - - // copying static properties manually to work around Opera's bug, - // where "prototype" property is enumerable and overrides existing prototype - for (var prop in fabric.StaticCanvas) { - if (prop !== 'prototype') { - fabric.Canvas[prop] = fabric.StaticCanvas[prop]; - } - } -})(); - - -(function() { - - var addListener = fabric.util.addListener, - removeListener = fabric.util.removeListener, - RIGHT_CLICK = 3, MIDDLE_CLICK = 2, LEFT_CLICK = 1, - addEventOptions = { passive: false }; - - function checkClick(e, value) { - return e.button && (e.button === value - 1); - } - - fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ { - - /** - * Contains the id of the touch event that owns the fabric transform - * @type Number - * @private - */ - mainTouchId: null, - - /** - * Adds mouse listeners to canvas - * @private - */ - _initEventListeners: function () { - // in case we initialized the class twice. This should not happen normally - // but in some kind of applications where the canvas element may be changed - // this is a workaround to having double listeners. - this.removeListeners(); - this._bindEvents(); - this.addOrRemove(addListener, 'add'); - }, - - /** - * return an event prefix pointer or mouse. - * @private - */ - _getEventPrefix: function () { - return this.enablePointerEvents ? 'pointer' : 'mouse'; - }, - - addOrRemove: function(functor, eventjsFunctor) { - var canvasElement = this.upperCanvasEl, - eventTypePrefix = this._getEventPrefix(); - functor(fabric.window, 'resize', this._onResize); - functor(canvasElement, eventTypePrefix + 'down', this._onMouseDown); - functor(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - functor(canvasElement, eventTypePrefix + 'out', this._onMouseOut); - functor(canvasElement, eventTypePrefix + 'enter', this._onMouseEnter); - functor(canvasElement, 'wheel', this._onMouseWheel); - functor(canvasElement, 'contextmenu', this._onContextMenu); - functor(canvasElement, 'dblclick', this._onDoubleClick); - functor(canvasElement, 'dragover', this._onDragOver); - functor(canvasElement, 'dragenter', this._onDragEnter); - functor(canvasElement, 'dragleave', this._onDragLeave); - functor(canvasElement, 'drop', this._onDrop); - if (!this.enablePointerEvents) { - functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions); - } - if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) { - eventjs[eventjsFunctor](canvasElement, 'gesture', this._onGesture); - eventjs[eventjsFunctor](canvasElement, 'drag', this._onDrag); - eventjs[eventjsFunctor](canvasElement, 'orientation', this._onOrientationChange); - eventjs[eventjsFunctor](canvasElement, 'shake', this._onShake); - eventjs[eventjsFunctor](canvasElement, 'longpress', this._onLongPress); - } - }, - - /** - * Removes all event listeners - */ - removeListeners: function() { - this.addOrRemove(removeListener, 'remove'); - // if you dispose on a mouseDown, before mouse up, you need to clean document to... - var eventTypePrefix = this._getEventPrefix(); - removeListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp); - removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions); - removeListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions); - }, - - /** - * @private - */ - _bindEvents: function() { - if (this.eventsBound) { - // for any reason we pass here twice we do not want to bind events twice. - return; - } - this._onMouseDown = this._onMouseDown.bind(this); - this._onTouchStart = this._onTouchStart.bind(this); - this._onMouseMove = this._onMouseMove.bind(this); - this._onMouseUp = this._onMouseUp.bind(this); - this._onTouchEnd = this._onTouchEnd.bind(this); - this._onResize = this._onResize.bind(this); - this._onGesture = this._onGesture.bind(this); - this._onDrag = this._onDrag.bind(this); - this._onShake = this._onShake.bind(this); - this._onLongPress = this._onLongPress.bind(this); - this._onOrientationChange = this._onOrientationChange.bind(this); - this._onMouseWheel = this._onMouseWheel.bind(this); - this._onMouseOut = this._onMouseOut.bind(this); - this._onMouseEnter = this._onMouseEnter.bind(this); - this._onContextMenu = this._onContextMenu.bind(this); - this._onDoubleClick = this._onDoubleClick.bind(this); - this._onDragOver = this._onDragOver.bind(this); - this._onDragEnter = this._simpleEventHandler.bind(this, 'dragenter'); - this._onDragLeave = this._simpleEventHandler.bind(this, 'dragleave'); - this._onDrop = this._simpleEventHandler.bind(this, 'drop'); - this.eventsBound = true; - }, - - /** - * @private - * @param {Event} [e] Event object fired on Event.js gesture - * @param {Event} [self] Inner Event object - */ - _onGesture: function(e, self) { - this.__onTransformGesture && this.__onTransformGesture(e, self); - }, - - /** - * @private - * @param {Event} [e] Event object fired on Event.js drag - * @param {Event} [self] Inner Event object - */ - _onDrag: function(e, self) { - this.__onDrag && this.__onDrag(e, self); - }, - - /** - * @private - * @param {Event} [e] Event object fired on wheel event - */ - _onMouseWheel: function(e) { - this.__onMouseWheel(e); - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onMouseOut: function(e) { - var target = this._hoveredTarget; - this.fire('mouse:out', { target: target, e: e }); - this._hoveredTarget = null; - target && target.fire('mouseout', { e: e }); - - var _this = this; - this._hoveredTargets.forEach(function(_target){ - _this.fire('mouse:out', { target: target, e: e }); - _target && target.fire('mouseout', { e: e }); - }); - this._hoveredTargets = []; - - if (this._iTextInstances) { - this._iTextInstances.forEach(function(obj) { - if (obj.isEditing) { - obj.hiddenTextarea.focus(); - } - }); - } - }, - - /** - * @private - * @param {Event} e Event object fired on mouseenter - */ - _onMouseEnter: function(e) { - // This find target and consequent 'mouse:over' is used to - // clear old instances on hovered target. - // calling findTarget has the side effect of killing target.__corner. - // as a short term fix we are not firing this if we are currently transforming. - // as a long term fix we need to separate the action of finding a target with the - // side effects we added to it. - if (!this._currentTransform && !this.findTarget(e)) { - this.fire('mouse:over', { target: null, e: e }); - this._hoveredTarget = null; - this._hoveredTargets = []; - } - }, - - /** - * @private - * @param {Event} [e] Event object fired on Event.js orientation change - * @param {Event} [self] Inner Event object - */ - _onOrientationChange: function(e, self) { - this.__onOrientationChange && this.__onOrientationChange(e, self); - }, - - /** - * @private - * @param {Event} [e] Event object fired on Event.js shake - * @param {Event} [self] Inner Event object - */ - _onShake: function(e, self) { - this.__onShake && this.__onShake(e, self); - }, - - /** - * @private - * @param {Event} [e] Event object fired on Event.js shake - * @param {Event} [self] Inner Event object - */ - _onLongPress: function(e, self) { - this.__onLongPress && this.__onLongPress(e, self); - }, - - /** - * prevent default to allow drop event to be fired - * @private - * @param {Event} [e] Event object fired on Event.js shake - */ - _onDragOver: function(e) { - e.preventDefault(); - var target = this._simpleEventHandler('dragover', e); - this._fireEnterLeaveEvents(target, e); - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onContextMenu: function (e) { - if (this.stopContextMenu) { - e.stopPropagation(); - e.preventDefault(); - } - return false; - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onDoubleClick: function (e) { - this._cacheTransformEventData(e); - this._handleEvent(e, 'dblclick'); - this._resetTransformEventData(e); - }, - - /** - * Return a the id of an event. - * returns either the pointerId or the identifier or 0 for the mouse event - * @private - * @param {Event} evt Event object - */ - getPointerId: function(evt) { - var changedTouches = evt.changedTouches; - - if (changedTouches) { - return changedTouches[0] && changedTouches[0].identifier; - } - - if (this.enablePointerEvents) { - return evt.pointerId; - } - - return -1; - }, - - /** - * Determines if an event has the id of the event that is considered main - * @private - * @param {evt} event Event object - */ - _isMainEvent: function(evt) { - if (evt.isPrimary === true) { - return true; - } - if (evt.isPrimary === false) { - return false; - } - if (evt.type === 'touchend' && evt.touches.length === 0) { - return true; - } - if (evt.changedTouches) { - return evt.changedTouches[0].identifier === this.mainTouchId; - } - return true; - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onTouchStart: function(e) { - e.preventDefault(); - if (this.mainTouchId === null) { - this.mainTouchId = this.getPointerId(e); - } - this.__onMouseDown(e); - this._resetTransformEventData(); - var canvasElement = this.upperCanvasEl, - eventTypePrefix = this._getEventPrefix(); - addListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions); - addListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions); - // Unbind mousedown to prevent double triggers from touch devices - removeListener(canvasElement, eventTypePrefix + 'down', this._onMouseDown); - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onMouseDown: function (e) { - this.__onMouseDown(e); - this._resetTransformEventData(); - var canvasElement = this.upperCanvasEl, - eventTypePrefix = this._getEventPrefix(); - removeListener(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - addListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp); - addListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onTouchEnd: function(e) { - if (e.touches.length > 0) { - // if there are still touches stop here - return; - } - this.__onMouseUp(e); - this._resetTransformEventData(); - this.mainTouchId = null; - var eventTypePrefix = this._getEventPrefix(); - removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions); - removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions); - var _this = this; - if (this._willAddMouseDown) { - clearTimeout(this._willAddMouseDown); - } - this._willAddMouseDown = setTimeout(function() { - // Wait 400ms before rebinding mousedown to prevent double triggers - // from touch devices - addListener(_this.upperCanvasEl, eventTypePrefix + 'down', _this._onMouseDown); - _this._willAddMouseDown = 0; - }, 400); - }, - - /** - * @private - * @param {Event} e Event object fired on mouseup - */ - _onMouseUp: function (e) { - this.__onMouseUp(e); - this._resetTransformEventData(); - var canvasElement = this.upperCanvasEl, - eventTypePrefix = this._getEventPrefix(); - if (this._isMainEvent(e)) { - removeListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp); - removeListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - addListener(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - } - }, - - /** - * @private - * @param {Event} e Event object fired on mousemove - */ - _onMouseMove: function (e) { - !this.allowTouchScrolling && e.preventDefault && e.preventDefault(); - this.__onMouseMove(e); - }, - - /** - * @private - */ - _onResize: function () { - this.calcOffset(); - }, - - /** - * Decides whether the canvas should be redrawn in mouseup and mousedown events. - * @private - * @param {Object} target - */ - _shouldRender: function(target) { - var activeObject = this._activeObject; - - if ( - !!activeObject !== !!target || - (activeObject && target && (activeObject !== target)) - ) { - // this covers: switch of target, from target to no target, selection of target - // multiSelection with key and mouse - return true; - } - else if (activeObject && activeObject.isEditing) { - // if we mouse up/down over a editing textbox a cursor change, - // there is no need to re render - return false; - } - return false; - }, - - /** - * Method that defines the actions when mouse is released on canvas. - * The method resets the currentTransform parameters, store the image corner - * position in the image object and render the canvas on top. - * @private - * @param {Event} e Event object fired on mouseup - */ - __onMouseUp: function (e) { - var target, transform = this._currentTransform, - groupSelector = this._groupSelector, shouldRender = false, - isClick = (!groupSelector || (groupSelector.left === 0 && groupSelector.top === 0)); - this._cacheTransformEventData(e); - target = this._target; - this._handleEvent(e, 'up:before'); - // if right/middle click just fire events and return - // target undefined will make the _handleEvent search the target - if (checkClick(e, RIGHT_CLICK)) { - if (this.fireRightClick) { - this._handleEvent(e, 'up', RIGHT_CLICK, isClick); - } - return; - } - - if (checkClick(e, MIDDLE_CLICK)) { - if (this.fireMiddleClick) { - this._handleEvent(e, 'up', MIDDLE_CLICK, isClick); - } - this._resetTransformEventData(); - return; - } - - if (this.isDrawingMode && this._isCurrentlyDrawing) { - this._onMouseUpInDrawingMode(e); - return; - } - - if (!this._isMainEvent(e)) { - return; - } - if (transform) { - this._finalizeCurrentTransform(e); - shouldRender = transform.actionPerformed; - } - if (!isClick) { - var targetWasActive = target === this._activeObject; - this._maybeGroupObjects(e); - if (!shouldRender) { - shouldRender = ( - this._shouldRender(target) || - (!targetWasActive && target === this._activeObject) - ); - } - } - if (target) { - if (target.selectable && target !== this._activeObject && target.activeOn === 'up') { - this.setActiveObject(target, e); - shouldRender = true; - } - else { - var corner = target._findTargetCorner( - this.getPointer(e, true), - fabric.util.isTouchEvent(e) - ); - var control = target.controls[corner], - mouseUpHandler = control && control.getMouseUpHandler(e, target, control); - if (mouseUpHandler) { - var pointer = this.getPointer(e); - mouseUpHandler(e, transform, pointer.x, pointer.y); - } - } - target.isMoving = false; - } - this._setCursorFromEvent(e, target); - this._handleEvent(e, 'up', LEFT_CLICK, isClick); - this._groupSelector = null; - this._currentTransform = null; - // reset the target information about which corner is selected - target && (target.__corner = 0); - if (shouldRender) { - this.requestRenderAll(); - } - else if (!isClick) { - this.renderTop(); - } - }, - - /** - * @private - * Handle event firing for target and subtargets - * @param {Event} e event from mouse - * @param {String} eventType event to fire (up, down or move) - * @return {Fabric.Object} target return the the target found, for internal reasons. - */ - _simpleEventHandler: function(eventType, e) { - var target = this.findTarget(e), - targets = this.targets, - options = { - e: e, - target: target, - subTargets: targets, - }; - this.fire(eventType, options); - target && target.fire(eventType, options); - if (!targets) { - return target; - } - for (var i = 0; i < targets.length; i++) { - targets[i].fire(eventType, options); - } - return target; - }, - - /** - * @private - * Handle event firing for target and subtargets - * @param {Event} e event from mouse - * @param {String} eventType event to fire (up, down or move) - * @param {fabric.Object} targetObj receiving event - * @param {Number} [button] button used in the event 1 = left, 2 = middle, 3 = right - * @param {Boolean} isClick for left button only, indicates that the mouse up happened without move. - */ - _handleEvent: function(e, eventType, button, isClick) { - var target = this._target, - targets = this.targets || [], - options = { - e: e, - target: target, - subTargets: targets, - button: button || LEFT_CLICK, - isClick: isClick || false, - pointer: this._pointer, - absolutePointer: this._absolutePointer, - transform: this._currentTransform - }; - if (eventType === 'up') { - options.currentTarget = this.findTarget(e); - options.currentSubTargets = this.targets; - } - this.fire('mouse:' + eventType, options); - target && target.fire('mouse' + eventType, options); - for (var i = 0; i < targets.length; i++) { - targets[i].fire('mouse' + eventType, options); - } - }, - - /** - * @private - * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event - */ - _finalizeCurrentTransform: function(e) { - - var transform = this._currentTransform, - target = transform.target, - eventName, - options = { - e: e, - target: target, - transform: transform, - action: transform.action, - }; - - if (target._scaling) { - target._scaling = false; - } - - target.setCoords(); - - if (transform.actionPerformed || (this.stateful && target.hasStateChanged())) { - if (transform.actionPerformed) { - // this is not friendly to the new control api. - // is deprecated. - eventName = this._addEventOptions(options, transform); - this._fire(eventName, options); - } - this._fire('modified', options); - } - }, - - /** - * Mutate option object in order to add by property and give back the event name. - * @private - * @deprecated since 4.2.0 - * @param {Object} options to mutate - * @param {Object} transform to inspect action from - */ - _addEventOptions: function(options, transform) { - // we can probably add more details at low cost - // scale change, rotation changes, translation changes - var eventName, by; - switch (transform.action) { - case 'scaleX': - eventName = 'scaled'; - by = 'x'; - break; - case 'scaleY': - eventName = 'scaled'; - by = 'y'; - break; - case 'skewX': - eventName = 'skewed'; - by = 'x'; - break; - case 'skewY': - eventName = 'skewed'; - by = 'y'; - break; - case 'scale': - eventName = 'scaled'; - by = 'equally'; - break; - case 'rotate': - eventName = 'rotated'; - break; - case 'drag': - eventName = 'moved'; - break; - } - options.by = by; - return eventName; - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onMouseDownInDrawingMode: function(e) { - this._isCurrentlyDrawing = true; - if (this.getActiveObject()) { - this.discardActiveObject(e).requestRenderAll(); - } - var pointer = this.getPointer(e); - this.freeDrawingBrush.onMouseDown(pointer, { e: e, pointer: pointer }); - this._handleEvent(e, 'down'); - }, - - /** - * @private - * @param {Event} e Event object fired on mousemove - */ - _onMouseMoveInDrawingMode: function(e) { - if (this._isCurrentlyDrawing) { - var pointer = this.getPointer(e); - this.freeDrawingBrush.onMouseMove(pointer, { e: e, pointer: pointer }); - } - this.setCursor(this.freeDrawingCursor); - this._handleEvent(e, 'move'); - }, - - /** - * @private - * @param {Event} e Event object fired on mouseup - */ - _onMouseUpInDrawingMode: function(e) { - var pointer = this.getPointer(e); - this._isCurrentlyDrawing = this.freeDrawingBrush.onMouseUp({ e: e, pointer: pointer }); - this._handleEvent(e, 'up'); - }, - - /** - * Method that defines the actions when mouse is clicked on canvas. - * The method inits the currentTransform parameters and renders all the - * canvas so the current image can be placed on the top canvas and the rest - * in on the container one. - * @private - * @param {Event} e Event object fired on mousedown - */ - __onMouseDown: function (e) { - this._cacheTransformEventData(e); - this._handleEvent(e, 'down:before'); - var target = this._target; - // if right click just fire events - if (checkClick(e, RIGHT_CLICK)) { - if (this.fireRightClick) { - this._handleEvent(e, 'down', RIGHT_CLICK); - } - return; - } - - if (checkClick(e, MIDDLE_CLICK)) { - if (this.fireMiddleClick) { - this._handleEvent(e, 'down', MIDDLE_CLICK); - } - return; - } - - if (this.isDrawingMode) { - this._onMouseDownInDrawingMode(e); - return; - } - - if (!this._isMainEvent(e)) { - return; - } - - // ignore if some object is being transformed at this moment - if (this._currentTransform) { - return; - } - - var pointer = this._pointer; - // save pointer for check in __onMouseUp event - this._previousPointer = pointer; - var shouldRender = this._shouldRender(target), - shouldGroup = this._shouldGroup(e, target); - if (this._shouldClearSelection(e, target)) { - this.discardActiveObject(e); - } - else if (shouldGroup) { - this._handleGrouping(e, target); - target = this._activeObject; - } - - if (this.selection && (!target || - (!target.selectable && !target.isEditing && target !== this._activeObject))) { - this._groupSelector = { - ex: this._absolutePointer.x, - ey: this._absolutePointer.y, - top: 0, - left: 0 - }; - } - - if (target) { - var alreadySelected = target === this._activeObject; - if (target.selectable && target.activeOn === 'down') { - this.setActiveObject(target, e); - } - var corner = target._findTargetCorner( - this.getPointer(e, true), - fabric.util.isTouchEvent(e) - ); - target.__corner = corner; - if (target === this._activeObject && (corner || !shouldGroup)) { - this._setupCurrentTransform(e, target, alreadySelected); - var control = target.controls[corner], - pointer = this.getPointer(e), - mouseDownHandler = control && control.getMouseDownHandler(e, target, control); - if (mouseDownHandler) { - mouseDownHandler(e, this._currentTransform, pointer.x, pointer.y); - } - } - } - this._handleEvent(e, 'down'); - // we must renderAll so that we update the visuals - (shouldRender || shouldGroup) && this.requestRenderAll(); - }, - - /** - * reset cache form common information needed during event processing - * @private - */ - _resetTransformEventData: function() { - this._target = null; - this._pointer = null; - this._absolutePointer = null; - }, - - /** - * Cache common information needed during event processing - * @private - * @param {Event} e Event object fired on event - */ - _cacheTransformEventData: function(e) { - // reset in order to avoid stale caching - this._resetTransformEventData(); - this._pointer = this.getPointer(e, true); - this._absolutePointer = this.restorePointerVpt(this._pointer); - this._target = this._currentTransform ? this._currentTransform.target : this.findTarget(e) || null; - }, - - /** - * @private - */ - _beforeTransform: function(e) { - var t = this._currentTransform; - this.stateful && t.target.saveState(); - this.fire('before:transform', { - e: e, - transform: t, - }); - }, - - /** - * Method that defines the actions when mouse is hovering the canvas. - * The currentTransform parameter will define whether the user is rotating/scaling/translating - * an image or neither of them (only hovering). A group selection is also possible and would cancel - * all any other type of action. - * In case of an image transformation only the top canvas will be rendered. - * @private - * @param {Event} e Event object fired on mousemove - */ - __onMouseMove: function (e) { - this._handleEvent(e, 'move:before'); - this._cacheTransformEventData(e); - var target, pointer; - - if (this.isDrawingMode) { - this._onMouseMoveInDrawingMode(e); - return; - } - - if (!this._isMainEvent(e)) { - return; - } - - var groupSelector = this._groupSelector; - - // We initially clicked in an empty area, so we draw a box for multiple selection - if (groupSelector) { - pointer = this._absolutePointer; - - groupSelector.left = pointer.x - groupSelector.ex; - groupSelector.top = pointer.y - groupSelector.ey; - - this.renderTop(); - } - else if (!this._currentTransform) { - target = this.findTarget(e) || null; - this._setCursorFromEvent(e, target); - this._fireOverOutEvents(target, e); - } - else { - this._transformObject(e); - } - this._handleEvent(e, 'move'); - this._resetTransformEventData(); - }, - - /** - * Manage the mouseout, mouseover events for the fabric object on the canvas - * @param {Fabric.Object} target the target where the target from the mousemove event - * @param {Event} e Event object fired on mousemove - * @private - */ - _fireOverOutEvents: function(target, e) { - var _hoveredTarget = this._hoveredTarget, - _hoveredTargets = this._hoveredTargets, targets = this.targets, - length = Math.max(_hoveredTargets.length, targets.length); - - this.fireSyntheticInOutEvents(target, e, { - oldTarget: _hoveredTarget, - evtOut: 'mouseout', - canvasEvtOut: 'mouse:out', - evtIn: 'mouseover', - canvasEvtIn: 'mouse:over', - }); - for (var i = 0; i < length; i++){ - this.fireSyntheticInOutEvents(targets[i], e, { - oldTarget: _hoveredTargets[i], - evtOut: 'mouseout', - evtIn: 'mouseover', - }); - } - this._hoveredTarget = target; - this._hoveredTargets = this.targets.concat(); - }, - - /** - * Manage the dragEnter, dragLeave events for the fabric objects on the canvas - * @param {Fabric.Object} target the target where the target from the onDrag event - * @param {Event} e Event object fired on ondrag - * @private - */ - _fireEnterLeaveEvents: function(target, e) { - var _draggedoverTarget = this._draggedoverTarget, - _hoveredTargets = this._hoveredTargets, targets = this.targets, - length = Math.max(_hoveredTargets.length, targets.length); - - this.fireSyntheticInOutEvents(target, e, { - oldTarget: _draggedoverTarget, - evtOut: 'dragleave', - evtIn: 'dragenter', - }); - for (var i = 0; i < length; i++) { - this.fireSyntheticInOutEvents(targets[i], e, { - oldTarget: _hoveredTargets[i], - evtOut: 'dragleave', - evtIn: 'dragenter', - }); - } - this._draggedoverTarget = target; - }, - - /** - * Manage the synthetic in/out events for the fabric objects on the canvas - * @param {Fabric.Object} target the target where the target from the supported events - * @param {Event} e Event object fired - * @param {Object} config configuration for the function to work - * @param {String} config.targetName property on the canvas where the old target is stored - * @param {String} [config.canvasEvtOut] name of the event to fire at canvas level for out - * @param {String} config.evtOut name of the event to fire for out - * @param {String} [config.canvasEvtIn] name of the event to fire at canvas level for in - * @param {String} config.evtIn name of the event to fire for in - * @private - */ - fireSyntheticInOutEvents: function(target, e, config) { - var inOpt, outOpt, oldTarget = config.oldTarget, outFires, inFires, - targetChanged = oldTarget !== target, canvasEvtIn = config.canvasEvtIn, canvasEvtOut = config.canvasEvtOut; - if (targetChanged) { - inOpt = { e: e, target: target, previousTarget: oldTarget }; - outOpt = { e: e, target: oldTarget, nextTarget: target }; - } - inFires = target && targetChanged; - outFires = oldTarget && targetChanged; - if (outFires) { - canvasEvtOut && this.fire(canvasEvtOut, outOpt); - oldTarget.fire(config.evtOut, outOpt); - } - if (inFires) { - canvasEvtIn && this.fire(canvasEvtIn, inOpt); - target.fire(config.evtIn, inOpt); - } - }, - - /** - * Method that defines actions when an Event Mouse Wheel - * @param {Event} e Event object fired on mouseup - */ - __onMouseWheel: function(e) { - this._cacheTransformEventData(e); - this._handleEvent(e, 'wheel'); - this._resetTransformEventData(); - }, - - /** - * @private - * @param {Event} e Event fired on mousemove - */ - _transformObject: function(e) { - var pointer = this.getPointer(e), - transform = this._currentTransform; - - transform.reset = false; - transform.shiftKey = e.shiftKey; - transform.altKey = e[this.centeredKey]; - - this._performTransformAction(e, transform, pointer); - transform.actionPerformed && this.requestRenderAll(); - }, - - /** - * @private - */ - _performTransformAction: function(e, transform, pointer) { - var x = pointer.x, - y = pointer.y, - action = transform.action, - actionPerformed = false, - actionHandler = transform.actionHandler; - // this object could be created from the function in the control handlers - - - if (actionHandler) { - actionPerformed = actionHandler(e, transform, x, y); - } - if (action === 'drag' && actionPerformed) { - transform.target.isMoving = true; - this.setCursor(transform.target.moveCursor || this.moveCursor); - } - transform.actionPerformed = transform.actionPerformed || actionPerformed; - }, - - /** - * @private - */ - _fire: fabric.controlsUtils.fireEvent, - - /** - * Sets the cursor depending on where the canvas is being hovered. - * Note: very buggy in Opera - * @param {Event} e Event object - * @param {Object} target Object that the mouse is hovering, if so. - */ - _setCursorFromEvent: function (e, target) { - if (!target) { - this.setCursor(this.defaultCursor); - return false; - } - var hoverCursor = target.hoverCursor || this.hoverCursor, - activeSelection = this._activeObject && this._activeObject.type === 'activeSelection' ? - this._activeObject : null, - // only show proper corner when group selection is not active - corner = (!activeSelection || !activeSelection.contains(target)) - // here we call findTargetCorner always with undefined for the touch parameter. - // we assume that if you are using a cursor you do not need to interact with - // the bigger touch area. - && target._findTargetCorner(this.getPointer(e, true)); - - if (!corner) { - if (target.subTargetCheck){ - // hoverCursor should come from top-most subTarget, - // so we walk the array backwards - this.targets.concat().reverse().map(function(_target){ - hoverCursor = _target.hoverCursor || hoverCursor; - }); - } - this.setCursor(hoverCursor); - } - else { - this.setCursor(this.getCornerCursor(corner, target, e)); - } - }, - - /** - * @private - */ - getCornerCursor: function(corner, target, e) { - var control = target.controls[corner]; - return control.cursorStyleHandler(e, control, target); - } - }); -})(); - - -(function() { - - var min = Math.min, - max = Math.max; - - fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ { - - /** - * @private - * @param {Event} e Event object - * @param {fabric.Object} target - * @return {Boolean} - */ - _shouldGroup: function(e, target) { - var activeObject = this._activeObject; - return activeObject && this._isSelectionKeyPressed(e) && target && target.selectable && this.selection && - (activeObject !== target || activeObject.type === 'activeSelection') && !target.onSelect({ e: e }); - }, - - /** - * @private - * @param {Event} e Event object - * @param {fabric.Object} target - */ - _handleGrouping: function (e, target) { - var activeObject = this._activeObject; - // avoid multi select when shift click on a corner - if (activeObject.__corner) { - return; - } - if (target === activeObject) { - // if it's a group, find target again, using activeGroup objects - target = this.findTarget(e, true); - // if even object is not found or we are on activeObjectCorner, bail out - if (!target || !target.selectable) { - return; - } - } - if (activeObject && activeObject.type === 'activeSelection') { - this._updateActiveSelection(target, e); - } - else { - this._createActiveSelection(target, e); - } - }, - - /** - * @private - */ - _updateActiveSelection: function(target, e) { - var activeSelection = this._activeObject, - currentActiveObjects = activeSelection._objects.slice(0); - if (activeSelection.contains(target)) { - activeSelection.removeWithUpdate(target); - this._hoveredTarget = target; - this._hoveredTargets = this.targets.concat(); - if (activeSelection.size() === 1) { - // activate last remaining object - this._setActiveObject(activeSelection.item(0), e); - } - } - else { - activeSelection.addWithUpdate(target); - this._hoveredTarget = activeSelection; - this._hoveredTargets = this.targets.concat(); - } - this._fireSelectionEvents(currentActiveObjects, e); - }, - - /** - * @private - */ - _createActiveSelection: function(target, e) { - var currentActives = this.getActiveObjects(), group = this._createGroup(target); - this._hoveredTarget = group; - // ISSUE 4115: should we consider subTargets here? - // this._hoveredTargets = []; - // this._hoveredTargets = this.targets.concat(); - this._setActiveObject(group, e); - this._fireSelectionEvents(currentActives, e); - }, - - /** - * @private - * @param {Object} target - */ - _createGroup: function(target) { - var objects = this._objects, - isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target), - groupObjects = isActiveLower - ? [this._activeObject, target] - : [target, this._activeObject]; - this._activeObject.isEditing && this._activeObject.exitEditing(); - return new fabric.ActiveSelection(groupObjects, { - canvas: this - }); - }, - - /** - * @private - * @param {Event} e mouse event - */ - _groupSelectedObjects: function (e) { - - var group = this._collectObjects(e), - aGroup; - - // do not create group for 1 element only - if (group.length === 1) { - this.setActiveObject(group[0], e); - } - else if (group.length > 1) { - aGroup = new fabric.ActiveSelection(group.reverse(), { - canvas: this - }); - this.setActiveObject(aGroup, e); - } - }, - - /** - * @private - */ - _collectObjects: function(e) { - var group = [], - currentObject, - x1 = this._groupSelector.ex, - y1 = this._groupSelector.ey, - x2 = x1 + this._groupSelector.left, - y2 = y1 + this._groupSelector.top, - selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)), - selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)), - allowIntersect = !this.selectionFullyContained, - isClick = x1 === x2 && y1 === y2; - // we iterate reverse order to collect top first in case of click. - for (var i = this._objects.length; i--; ) { - currentObject = this._objects[i]; - - if (!currentObject || !currentObject.selectable || !currentObject.visible) { - continue; - } - - if ((allowIntersect && currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2, true)) || - currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2, true) || - (allowIntersect && currentObject.containsPoint(selectionX1Y1, null, true)) || - (allowIntersect && currentObject.containsPoint(selectionX2Y2, null, true)) - ) { - group.push(currentObject); - // only add one object if it's a click - if (isClick) { - break; - } - } - } - - if (group.length > 1) { - group = group.filter(function(object) { - return !object.onSelect({ e: e }); - }); - } - - return group; - }, - - /** - * @private - */ - _maybeGroupObjects: function(e) { - if (this.selection && this._groupSelector) { - this._groupSelectedObjects(e); - } - this.setCursor(this.defaultCursor); - // clear selection and current transformation - this._groupSelector = null; - } - }); - -})(); - - -(function () { - fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { - - /** - * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately - * @param {Object} [options] Options object - * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png" - * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg. - * @param {Number} [options.multiplier=1] Multiplier to scale by, to have consistent - * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 - * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 - * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 - * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 - * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 2.0.0 - * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format - * @see {@link http://jsfiddle.net/fabricjs/NfZVb/|jsFiddle demo} - * @example Generate jpeg dataURL with lower quality - * var dataURL = canvas.toDataURL({ - * format: 'jpeg', - * quality: 0.8 - * }); - * @example Generate cropped png dataURL (clipping of canvas) - * var dataURL = canvas.toDataURL({ - * format: 'png', - * left: 100, - * top: 100, - * width: 200, - * height: 200 - * }); - * @example Generate double scaled png dataURL - * var dataURL = canvas.toDataURL({ - * format: 'png', - * multiplier: 2 - * }); - */ - toDataURL: function (options) { - options || (options = { }); - - var format = options.format || 'png', - quality = options.quality || 1, - multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? this.getRetinaScaling() : 1), - canvasEl = this.toCanvasElement(multiplier, options); - return fabric.util.toDataURL(canvasEl, format, quality); - }, - - /** - * Create a new HTMLCanvas element painted with the current canvas content. - * No need to resize the actual one or repaint it. - * Will transfer object ownership to a new canvas, paint it, and set everything back. - * This is an intermediary step used to get to a dataUrl but also it is useful to - * create quick image copies of a canvas without passing for the dataUrl string - * @param {Number} [multiplier] a zoom factor. - * @param {Object} [cropping] Cropping informations - * @param {Number} [cropping.left] Cropping left offset. - * @param {Number} [cropping.top] Cropping top offset. - * @param {Number} [cropping.width] Cropping width. - * @param {Number} [cropping.height] Cropping height. - */ - toCanvasElement: function(multiplier, cropping) { - multiplier = multiplier || 1; - cropping = cropping || { }; - var scaledWidth = (cropping.width || this.width) * multiplier, - scaledHeight = (cropping.height || this.height) * multiplier, - zoom = this.getZoom(), - originalWidth = this.width, - originalHeight = this.height, - newZoom = zoom * multiplier, - vp = this.viewportTransform, - translateX = (vp[4] - (cropping.left || 0)) * multiplier, - translateY = (vp[5] - (cropping.top || 0)) * multiplier, - originalInteractive = this.interactive, - newVp = [newZoom, 0, 0, newZoom, translateX, translateY], - originalRetina = this.enableRetinaScaling, - canvasEl = fabric.util.createCanvasElement(), - originalContextTop = this.contextTop; - canvasEl.width = scaledWidth; - canvasEl.height = scaledHeight; - this.contextTop = null; - this.enableRetinaScaling = false; - this.interactive = false; - this.viewportTransform = newVp; - this.width = scaledWidth; - this.height = scaledHeight; - this.calcViewportBoundaries(); - this.renderCanvas(canvasEl.getContext('2d'), this._objects); - this.viewportTransform = vp; - this.width = originalWidth; - this.height = originalHeight; - this.calcViewportBoundaries(); - this.interactive = originalInteractive; - this.enableRetinaScaling = originalRetina; - this.contextTop = originalContextTop; - return canvasEl; - }, - }); - -})(); - - -fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { - /** - * Populates canvas with data from the specified JSON. - * JSON format must conform to the one of {@link fabric.Canvas#toJSON} - * @param {String|Object} json JSON string or object - * @param {Function} callback Callback, invoked when json is parsed - * and corresponding objects (e.g: {@link fabric.Image}) - * are initialized - * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created. - * @return {fabric.Canvas} instance - * @chainable - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization} - * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo} - * @example loadFromJSON - * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas)); - * @example loadFromJSON with reviver - * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas), function(o, object) { - * // `o` = json object - * // `object` = fabric.Object instance - * // ... do some stuff ... - * }); - */ - loadFromJSON: function (json, callback, reviver) { - if (!json) { - return; - } - - // serialize if it wasn't already - var serialized = (typeof json === 'string') - ? JSON.parse(json) - : fabric.util.object.clone(json); - - var _this = this, - clipPath = serialized.clipPath, - renderOnAddRemove = this.renderOnAddRemove; - - this.renderOnAddRemove = false; - - delete serialized.clipPath; - - this._enlivenObjects(serialized.objects, function (enlivenedObjects) { - _this.clear(); - _this._setBgOverlay(serialized, function () { - if (clipPath) { - _this._enlivenObjects([clipPath], function (enlivenedCanvasClip) { - _this.clipPath = enlivenedCanvasClip[0]; - _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback); - }); - } - else { - _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback); - } - }); - }, reviver); - return this; - }, - - /** - * @private - * @param {Object} serialized Object with background and overlay information - * @param {Array} restored canvas objects - * @param {Function} cached renderOnAddRemove callback - * @param {Function} callback Invoked after all background and overlay images/patterns loaded - */ - __setupCanvas: function(serialized, enlivenedObjects, renderOnAddRemove, callback) { - var _this = this; - enlivenedObjects.forEach(function(obj, index) { - // we splice the array just in case some custom classes restored from JSON - // will add more object to canvas at canvas init. - _this.insertAt(obj, index); - }); - this.renderOnAddRemove = renderOnAddRemove; - // remove parts i cannot set as options - delete serialized.objects; - delete serialized.backgroundImage; - delete serialized.overlayImage; - delete serialized.background; - delete serialized.overlay; - // this._initOptions does too many things to just - // call it. Normally loading an Object from JSON - // create the Object instance. Here the Canvas is - // already an instance and we are just loading things over it - this._setOptions(serialized); - this.renderAll(); - callback && callback(); - }, - - /** - * @private - * @param {Object} serialized Object with background and overlay information - * @param {Function} callback Invoked after all background and overlay images/patterns loaded - */ - _setBgOverlay: function(serialized, callback) { - var loaded = { - backgroundColor: false, - overlayColor: false, - backgroundImage: false, - overlayImage: false - }; - - if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background && !serialized.overlay) { - callback && callback(); - return; - } - - var cbIfLoaded = function () { - if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) { - callback && callback(); - } - }; - - this.__setBgOverlay('backgroundImage', serialized.backgroundImage, loaded, cbIfLoaded); - this.__setBgOverlay('overlayImage', serialized.overlayImage, loaded, cbIfLoaded); - this.__setBgOverlay('backgroundColor', serialized.background, loaded, cbIfLoaded); - this.__setBgOverlay('overlayColor', serialized.overlay, loaded, cbIfLoaded); - }, - - /** - * @private - * @param {String} property Property to set (backgroundImage, overlayImage, backgroundColor, overlayColor) - * @param {(Object|String)} value Value to set - * @param {Object} loaded Set loaded property to true if property is set - * @param {Object} callback Callback function to invoke after property is set - */ - __setBgOverlay: function(property, value, loaded, callback) { - var _this = this; - - if (!value) { - loaded[property] = true; - callback && callback(); - return; - } - - if (property === 'backgroundImage' || property === 'overlayImage') { - fabric.util.enlivenObjects([value], function(enlivedObject){ - _this[property] = enlivedObject[0]; - loaded[property] = true; - callback && callback(); - }); - } - else { - this['set' + fabric.util.string.capitalize(property, true)](value, function() { - loaded[property] = true; - callback && callback(); - }); - } - }, - - /** - * @private - * @param {Array} objects - * @param {Function} callback - * @param {Function} [reviver] - */ - _enlivenObjects: function (objects, callback, reviver) { - if (!objects || objects.length === 0) { - callback && callback([]); - return; - } - - fabric.util.enlivenObjects(objects, function(enlivenedObjects) { - callback && callback(enlivenedObjects); - }, null, reviver); - }, - - /** - * @private - * @param {String} format - * @param {Function} callback - */ - _toDataURL: function (format, callback) { - this.clone(function (clone) { - callback(clone.toDataURL(format)); - }); - }, - - /** - * @private - * @param {String} format - * @param {Number} multiplier - * @param {Function} callback - */ - _toDataURLWithMultiplier: function (format, multiplier, callback) { - this.clone(function (clone) { - callback(clone.toDataURLWithMultiplier(format, multiplier)); - }); - }, - - /** - * Clones canvas instance - * @param {Object} [callback] Receives cloned instance as a first argument - * @param {Array} [properties] Array of properties to include in the cloned canvas and children - */ - clone: function (callback, properties) { - var data = JSON.stringify(this.toJSON(properties)); - this.cloneWithoutData(function(clone) { - clone.loadFromJSON(data, function() { - callback && callback(clone); - }); - }); - }, - - /** - * Clones canvas instance without cloning existing data. - * This essentially copies canvas dimensions, clipping properties, etc. - * but leaves data empty (so that you can populate it with your own) - * @param {Object} [callback] Receives cloned instance as a first argument - */ - cloneWithoutData: function(callback) { - var el = fabric.util.createCanvasElement(); - - el.width = this.width; - el.height = this.height; - - var clone = new fabric.Canvas(el); - if (this.backgroundImage) { - clone.setBackgroundImage(this.backgroundImage.src, function() { - clone.renderAll(); - callback && callback(clone); - }); - clone.backgroundImageOpacity = this.backgroundImageOpacity; - clone.backgroundImageStretch = this.backgroundImageStretch; - } - else { - callback && callback(clone); - } - } -}); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - clone = fabric.util.object.clone, - toFixed = fabric.util.toFixed, - capitalize = fabric.util.string.capitalize, - degreesToRadians = fabric.util.degreesToRadians, - objectCaching = !fabric.isLikelyNode, - ALIASING_LIMIT = 2; - - if (fabric.Object) { - return; - } - - /** - * Root object class from which all 2d shape classes inherit from - * @class fabric.Object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects} - * @see {@link fabric.Object#initialize} for constructor definition - * - * @fires added - * @fires removed - * - * @fires selected - * @fires deselected - * @fires modified - * @fires modified - * @fires moved - * @fires scaled - * @fires rotated - * @fires skewed - * - * @fires rotating - * @fires scaling - * @fires moving - * @fires skewing - * - * @fires mousedown - * @fires mouseup - * @fires mouseover - * @fires mouseout - * @fires mousewheel - * @fires mousedblclick - * - * @fires dragover - * @fires dragenter - * @fires dragleave - * @fires drop - */ - fabric.Object = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.Object.prototype */ { - - /** - * Type of an object (rect, circle, path, etc.). - * Note that this property is meant to be read-only and not meant to be modified. - * If you modify, certain parts of Fabric (such as JSON loading) won't work correctly. - * @type String - * @default - */ - type: 'object', - - /** - * Horizontal origin of transformation of an object (one of "left", "right", "center") - * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups - * @type String - * @default - */ - originX: 'left', - - /** - * Vertical origin of transformation of an object (one of "top", "bottom", "center") - * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups - * @type String - * @default - */ - originY: 'top', - - /** - * Top position of an object. Note that by default it's relative to object top. You can change this by setting originY={top/center/bottom} - * @type Number - * @default - */ - top: 0, - - /** - * Left position of an object. Note that by default it's relative to object left. You can change this by setting originX={left/center/right} - * @type Number - * @default - */ - left: 0, - - /** - * Object width - * @type Number - * @default - */ - width: 0, - - /** - * Object height - * @type Number - * @default - */ - height: 0, - - /** - * Object scale factor (horizontal) - * @type Number - * @default - */ - scaleX: 1, - - /** - * Object scale factor (vertical) - * @type Number - * @default - */ - scaleY: 1, - - /** - * When true, an object is rendered as flipped horizontally - * @type Boolean - * @default - */ - flipX: false, - - /** - * When true, an object is rendered as flipped vertically - * @type Boolean - * @default - */ - flipY: false, - - /** - * Opacity of an object - * @type Number - * @default - */ - opacity: 1, - - /** - * Angle of rotation of an object (in degrees) - * @type Number - * @default - */ - angle: 0, - - /** - * Angle of skew on x axes of an object (in degrees) - * @type Number - * @default - */ - skewX: 0, - - /** - * Angle of skew on y axes of an object (in degrees) - * @type Number - * @default - */ - skewY: 0, - - /** - * Size of object's controlling corners (in pixels) - * @type Number - * @default - */ - cornerSize: 13, - - /** - * Size of object's controlling corners when touch interaction is detected - * @type Number - * @default - */ - touchCornerSize: 24, - - /** - * When true, object's controlling corners are rendered as transparent inside (i.e. stroke instead of fill) - * @type Boolean - * @default - */ - transparentCorners: true, - - /** - * Default cursor value used when hovering over this object on canvas - * @type String - * @default - */ - hoverCursor: null, - - /** - * Default cursor value used when moving this object on canvas - * @type String - * @default - */ - moveCursor: null, - - /** - * Padding between object and its controlling borders (in pixels) - * @type Number - * @default - */ - padding: 0, - - /** - * Color of controlling borders of an object (when it's active) - * @type String - * @default - */ - borderColor: 'rgb(178,204,255)', - - /** - * Array specifying dash pattern of an object's borders (hasBorder must be true) - * @since 1.6.2 - * @type Array - */ - borderDashArray: null, - - /** - * Color of controlling corners of an object (when it's active) - * @type String - * @default - */ - cornerColor: 'rgb(178,204,255)', - - /** - * Color of controlling corners of an object (when it's active and transparentCorners false) - * @since 1.6.2 - * @type String - * @default - */ - cornerStrokeColor: null, - - /** - * Specify style of control, 'rect' or 'circle' - * @since 1.6.2 - * @type String - */ - cornerStyle: 'rect', - - /** - * Array specifying dash pattern of an object's control (hasBorder must be true) - * @since 1.6.2 - * @type Array - */ - cornerDashArray: null, - - /** - * When true, this object will use center point as the origin of transformation - * when being scaled via the controls. - * Backwards incompatibility note: This property replaces "centerTransform" (Boolean). - * @since 1.3.4 - * @type Boolean - * @default - */ - centeredScaling: false, - - /** - * When true, this object will use center point as the origin of transformation - * when being rotated via the controls. - * Backwards incompatibility note: This property replaces "centerTransform" (Boolean). - * @since 1.3.4 - * @type Boolean - * @default - */ - centeredRotation: true, - - /** - * Color of object's fill - * takes css colors https://www.w3.org/TR/css-color-3/ - * @type String - * @default - */ - fill: 'rgb(0,0,0)', - - /** - * Fill rule used to fill an object - * accepted values are nonzero, evenodd - * Backwards incompatibility note: This property was used for setting globalCompositeOperation until v1.4.12 (use `fabric.Object#globalCompositeOperation` instead) - * @type String - * @default - */ - fillRule: 'nonzero', - - /** - * Composite rule used for canvas globalCompositeOperation - * @type String - * @default - */ - globalCompositeOperation: 'source-over', - - /** - * Background color of an object. - * takes css colors https://www.w3.org/TR/css-color-3/ - * @type String - * @default - */ - backgroundColor: '', - - /** - * Selection Background color of an object. colored layer behind the object when it is active. - * does not mix good with globalCompositeOperation methods. - * @type String - * @default - */ - selectionBackgroundColor: '', - - /** - * When defined, an object is rendered via stroke and this property specifies its color - * takes css colors https://www.w3.org/TR/css-color-3/ - * @type String - * @default - */ - stroke: null, - - /** - * Width of a stroke used to render this object - * @type Number - * @default - */ - strokeWidth: 1, - - /** - * Array specifying dash pattern of an object's stroke (stroke must be defined) - * @type Array - */ - strokeDashArray: null, - - /** - * Line offset of an object's stroke - * @type Number - * @default - */ - strokeDashOffset: 0, - - /** - * Line endings style of an object's stroke (one of "butt", "round", "square") - * @type String - * @default - */ - strokeLineCap: 'butt', - - /** - * Corner style of an object's stroke (one of "bevel", "round", "miter") - * @type String - * @default - */ - strokeLineJoin: 'miter', - - /** - * Maximum miter length (used for strokeLineJoin = "miter") of an object's stroke - * @type Number - * @default - */ - strokeMiterLimit: 4, - - /** - * Shadow object representing shadow of this shape - * @type fabric.Shadow - * @default - */ - shadow: null, - - /** - * Opacity of object's controlling borders when object is active and moving - * @type Number - * @default - */ - borderOpacityWhenMoving: 0.4, - - /** - * Scale factor of object's controlling borders - * bigger number will make a thicker border - * border is 1, so this is basically a border thickness - * since there is no way to change the border itself. - * @type Number - * @default - */ - borderScaleFactor: 1, - - /** - * Minimum allowed scale value of an object - * @type Number - * @default - */ - minScaleLimit: 0, - - /** - * When set to `false`, an object can not be selected for modification (using either point-click-based or group-based selection). - * But events still fire on it. - * @type Boolean - * @default - */ - selectable: true, - - /** - * When set to `false`, an object can not be a target of events. All events propagate through it. Introduced in v1.3.4 - * @type Boolean - * @default - */ - evented: true, - - /** - * When set to `false`, an object is not rendered on canvas - * @type Boolean - * @default - */ - visible: true, - - /** - * When set to `false`, object's controls are not displayed and can not be used to manipulate object - * @type Boolean - * @default - */ - hasControls: true, - - /** - * When set to `false`, object's controlling borders are not rendered - * @type Boolean - * @default - */ - hasBorders: true, - - /** - * When set to `true`, objects are "found" on canvas on per-pixel basis rather than according to bounding box - * @type Boolean - * @default - */ - perPixelTargetFind: false, - - /** - * When `false`, default object's values are not included in its serialization - * @type Boolean - * @default - */ - includeDefaultValues: true, - - /** - * When `true`, object horizontal movement is locked - * @type Boolean - * @default - */ - lockMovementX: false, - - /** - * When `true`, object vertical movement is locked - * @type Boolean - * @default - */ - lockMovementY: false, - - /** - * When `true`, object rotation is locked - * @type Boolean - * @default - */ - lockRotation: false, - - /** - * When `true`, object horizontal scaling is locked - * @type Boolean - * @default - */ - lockScalingX: false, - - /** - * When `true`, object vertical scaling is locked - * @type Boolean - * @default - */ - lockScalingY: false, - - /** - * When `true`, object horizontal skewing is locked - * @type Boolean - * @default - */ - lockSkewingX: false, - - /** - * When `true`, object vertical skewing is locked - * @type Boolean - * @default - */ - lockSkewingY: false, - - /** - * When `true`, object cannot be flipped by scaling into negative values - * @type Boolean - * @default - */ - lockScalingFlip: false, - - /** - * When `true`, object is not exported in OBJECT/JSON - * @since 1.6.3 - * @type Boolean - * @default - */ - excludeFromExport: false, - - /** - * When `true`, object is cached on an additional canvas. - * When `false`, object is not cached unless necessary ( clipPath ) - * default to true - * @since 1.7.0 - * @type Boolean - * @default true - */ - objectCaching: objectCaching, - - /** - * When `true`, object properties are checked for cache invalidation. In some particular - * situation you may want this to be disabled ( spray brush, very big, groups) - * or if your application does not allow you to modify properties for groups child you want - * to disable it for groups. - * default to false - * since 1.7.0 - * @type Boolean - * @default false - */ - statefullCache: false, - - /** - * When `true`, cache does not get updated during scaling. The picture will get blocky if scaled - * too much and will be redrawn with correct details at the end of scaling. - * this setting is performance and application dependant. - * default to true - * since 1.7.0 - * @type Boolean - * @default true - */ - noScaleCache: true, - - /** - * When `false`, the stoke width will scale with the object. - * When `true`, the stroke will always match the exact pixel size entered for stroke width. - * default to false - * @since 2.6.0 - * @type Boolean - * @default false - * @type Boolean - * @default false - */ - strokeUniform: false, - - /** - * When set to `true`, object's cache will be rerendered next render call. - * since 1.7.0 - * @type Boolean - * @default true - */ - dirty: true, - - /** - * keeps the value of the last hovered corner during mouse move. - * 0 is no corner, or 'mt', 'ml', 'mtr' etc.. - * It should be private, but there is no harm in using it as - * a read-only property. - * @type number|string|any - * @default 0 - */ - __corner: 0, - - /** - * Determines if the fill or the stroke is drawn first (one of "fill" or "stroke") - * @type String - * @default - */ - paintFirst: 'fill', - - /** - * When 'down', object is set to active on mousedown/touchstart - * When 'up', object is set to active on mouseup/touchend - * Experimental. Let's see if this breaks anything before supporting officially - * @private - * since 4.4.0 - * @type String - * @default 'down' - */ - activeOn: 'down', - - /** - * List of properties to consider when checking if state - * of an object is changed (fabric.Object#hasStateChanged) - * as well as for history (undo/redo) purposes - * @type Array - */ - stateProperties: ( - 'top left width height scaleX scaleY flipX flipY originX originY transformMatrix ' + - 'stroke strokeWidth strokeDashArray strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit ' + - 'angle opacity fill globalCompositeOperation shadow visible backgroundColor ' + - 'skewX skewY fillRule paintFirst clipPath strokeUniform' - ).split(' '), - - /** - * List of properties to consider when checking if cache needs refresh - * Those properties are checked by statefullCache ON ( or lazy mode if we want ) or from single - * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty - * and refreshed at the next render - * @type Array - */ - cacheProperties: ( - 'fill stroke strokeWidth strokeDashArray width height paintFirst strokeUniform' + - ' strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit backgroundColor clipPath' - ).split(' '), - - /** - * List of properties to consider for animating colors. - * @type Array - */ - colorProperties: ( - 'fill stroke backgroundColor' - ).split(' '), - - /** - * a fabricObject that, without stroke define a clipping area with their shape. filled in black - * the clipPath object gets used when the object has rendered, and the context is placed in the center - * of the object cacheCanvas. - * If you want 0,0 of a clipPath to align with an object center, use clipPath.originX/Y to 'center' - * @type fabric.Object - */ - clipPath: undefined, - - /** - * Meaningful ONLY when the object is used as clipPath. - * if true, the clipPath will make the object clip to the outside of the clipPath - * since 2.4.0 - * @type boolean - * @default false - */ - inverted: false, - - /** - * Meaningful ONLY when the object is used as clipPath. - * if true, the clipPath will have its top and left relative to canvas, and will - * not be influenced by the object transform. This will make the clipPath relative - * to the canvas, but clipping just a particular object. - * WARNING this is beta, this feature may change or be renamed. - * since 2.4.0 - * @type boolean - * @default false - */ - absolutePositioned: false, - - /** - * Constructor - * @param {Object} [options] Options object - */ - initialize: function(options) { - if (options) { - this.setOptions(options); - } - }, - - /** - * Create a the canvas used to keep the cached copy of the object - * @private - */ - _createCacheCanvas: function() { - this._cacheProperties = {}; - this._cacheCanvas = fabric.util.createCanvasElement(); - this._cacheContext = this._cacheCanvas.getContext('2d'); - this._updateCacheCanvas(); - // if canvas gets created, is empty, so dirty. - this.dirty = true; - }, - - /** - * Limit the cache dimensions so that X * Y do not cross fabric.perfLimitSizeTotal - * and each side do not cross fabric.cacheSideLimit - * those numbers are configurable so that you can get as much detail as you want - * making bargain with performances. - * @param {Object} dims - * @param {Object} dims.width width of canvas - * @param {Object} dims.height height of canvas - * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache - * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache - * @return {Object}.width width of canvas - * @return {Object}.height height of canvas - * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache - * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache - */ - _limitCacheSize: function(dims) { - var perfLimitSizeTotal = fabric.perfLimitSizeTotal, - width = dims.width, height = dims.height, - max = fabric.maxCacheSideLimit, min = fabric.minCacheSideLimit; - if (width <= max && height <= max && width * height <= perfLimitSizeTotal) { - if (width < min) { - dims.width = min; - } - if (height < min) { - dims.height = min; - } - return dims; - } - var ar = width / height, limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal), - capValue = fabric.util.capValue, - x = capValue(min, limitedDims.x, max), - y = capValue(min, limitedDims.y, max); - if (width > x) { - dims.zoomX /= width / x; - dims.width = x; - dims.capped = true; - } - if (height > y) { - dims.zoomY /= height / y; - dims.height = y; - dims.capped = true; - } - return dims; - }, - - /** - * Return the dimension and the zoom level needed to create a cache canvas - * big enough to host the object to be cached. - * @private - * @return {Object}.x width of object to be cached - * @return {Object}.y height of object to be cached - * @return {Object}.width width of canvas - * @return {Object}.height height of canvas - * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache - * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache - */ - _getCacheCanvasDimensions: function() { - var objectScale = this.getTotalObjectScaling(), - // caculate dimensions without skewing - dim = this._getTransformedDimensions(0, 0), - neededX = dim.x * objectScale.scaleX / this.scaleX, - neededY = dim.y * objectScale.scaleY / this.scaleY; - return { - // for sure this ALIASING_LIMIT is slightly creating problem - // in situation in which the cache canvas gets an upper limit - // also objectScale contains already scaleX and scaleY - width: neededX + ALIASING_LIMIT, - height: neededY + ALIASING_LIMIT, - zoomX: objectScale.scaleX, - zoomY: objectScale.scaleY, - x: neededX, - y: neededY - }; - }, - - /** - * Update width and height of the canvas for cache - * returns true or false if canvas needed resize. - * @private - * @return {Boolean} true if the canvas has been resized - */ - _updateCacheCanvas: function() { - var targetCanvas = this.canvas; - if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) { - var target = targetCanvas._currentTransform.target, - action = targetCanvas._currentTransform.action; - if (this === target && action.slice && action.slice(0, 5) === 'scale') { - return false; - } - } - var canvas = this._cacheCanvas, - dims = this._limitCacheSize(this._getCacheCanvasDimensions()), - minCacheSize = fabric.minCacheSideLimit, - width = dims.width, height = dims.height, drawingWidth, drawingHeight, - zoomX = dims.zoomX, zoomY = dims.zoomY, - dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight, - zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY, - shouldRedraw = dimensionsChanged || zoomChanged, - additionalWidth = 0, additionalHeight = 0, shouldResizeCanvas = false; - if (dimensionsChanged) { - var canvasWidth = this._cacheCanvas.width, - canvasHeight = this._cacheCanvas.height, - sizeGrowing = width > canvasWidth || height > canvasHeight, - sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) && - canvasWidth > minCacheSize && canvasHeight > minCacheSize; - shouldResizeCanvas = sizeGrowing || sizeShrinking; - if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) { - additionalWidth = width * 0.1; - additionalHeight = height * 0.1; - } - } - if (this instanceof fabric.Text && this.path) { - shouldRedraw = true; - shouldResizeCanvas = true; - additionalWidth += this.getHeightOfLine(0) * this.zoomX; - additionalHeight += this.getHeightOfLine(0) * this.zoomY; - } - if (shouldRedraw) { - if (shouldResizeCanvas) { - canvas.width = Math.ceil(width + additionalWidth); - canvas.height = Math.ceil(height + additionalHeight); - } - else { - this._cacheContext.setTransform(1, 0, 0, 1, 0, 0); - this._cacheContext.clearRect(0, 0, canvas.width, canvas.height); - } - drawingWidth = dims.x / 2; - drawingHeight = dims.y / 2; - this.cacheTranslationX = Math.round(canvas.width / 2 - drawingWidth) + drawingWidth; - this.cacheTranslationY = Math.round(canvas.height / 2 - drawingHeight) + drawingHeight; - this.cacheWidth = width; - this.cacheHeight = height; - this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY); - this._cacheContext.scale(zoomX, zoomY); - this.zoomX = zoomX; - this.zoomY = zoomY; - return true; - } - return false; - }, - - /** - * Sets object's properties from options - * @param {Object} [options] Options object - */ - setOptions: function(options) { - this._setOptions(options); - this._initGradient(options.fill, 'fill'); - this._initGradient(options.stroke, 'stroke'); - this._initPattern(options.fill, 'fill'); - this._initPattern(options.stroke, 'stroke'); - }, - - /** - * Transforms context when rendering an object - * @param {CanvasRenderingContext2D} ctx Context - */ - transform: function(ctx) { - var needFullTransform = (this.group && !this.group._transformDone) || - (this.group && this.canvas && ctx === this.canvas.contextTop); - var m = this.calcTransformMatrix(!needFullTransform); - ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); - }, - - /** - * Returns an object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of an instance - */ - toObject: function(propertiesToInclude) { - var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, - - object = { - type: this.type, - version: fabric.version, - originX: this.originX, - originY: this.originY, - left: toFixed(this.left, NUM_FRACTION_DIGITS), - top: toFixed(this.top, NUM_FRACTION_DIGITS), - width: toFixed(this.width, NUM_FRACTION_DIGITS), - height: toFixed(this.height, NUM_FRACTION_DIGITS), - fill: (this.fill && this.fill.toObject) ? this.fill.toObject() : this.fill, - stroke: (this.stroke && this.stroke.toObject) ? this.stroke.toObject() : this.stroke, - strokeWidth: toFixed(this.strokeWidth, NUM_FRACTION_DIGITS), - strokeDashArray: this.strokeDashArray ? this.strokeDashArray.concat() : this.strokeDashArray, - strokeLineCap: this.strokeLineCap, - strokeDashOffset: this.strokeDashOffset, - strokeLineJoin: this.strokeLineJoin, - strokeUniform: this.strokeUniform, - strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS), - scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS), - scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS), - angle: toFixed(this.angle, NUM_FRACTION_DIGITS), - flipX: this.flipX, - flipY: this.flipY, - opacity: toFixed(this.opacity, NUM_FRACTION_DIGITS), - shadow: (this.shadow && this.shadow.toObject) ? this.shadow.toObject() : this.shadow, - visible: this.visible, - backgroundColor: this.backgroundColor, - fillRule: this.fillRule, - paintFirst: this.paintFirst, - globalCompositeOperation: this.globalCompositeOperation, - skewX: toFixed(this.skewX, NUM_FRACTION_DIGITS), - skewY: toFixed(this.skewY, NUM_FRACTION_DIGITS), - }; - - if (this.clipPath && !this.clipPath.excludeFromExport) { - object.clipPath = this.clipPath.toObject(propertiesToInclude); - object.clipPath.inverted = this.clipPath.inverted; - object.clipPath.absolutePositioned = this.clipPath.absolutePositioned; - } - - fabric.util.populateWithProperties(this, object, propertiesToInclude); - if (!this.includeDefaultValues) { - object = this._removeDefaultValues(object); - } - - return object; - }, - - /** - * Returns (dataless) object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of an instance - */ - toDatalessObject: function(propertiesToInclude) { - // will be overwritten by subclasses - return this.toObject(propertiesToInclude); - }, - - /** - * @private - * @param {Object} object - */ - _removeDefaultValues: function(object) { - var prototype = fabric.util.getKlass(object.type).prototype, - stateProperties = prototype.stateProperties; - stateProperties.forEach(function(prop) { - if (prop === 'left' || prop === 'top') { - return; - } - if (object[prop] === prototype[prop]) { - delete object[prop]; - } - var isArray = Object.prototype.toString.call(object[prop]) === '[object Array]' && - Object.prototype.toString.call(prototype[prop]) === '[object Array]'; - - // basically a check for [] === [] - if (isArray && object[prop].length === 0 && prototype[prop].length === 0) { - delete object[prop]; - } - }); - - return object; - }, - - /** - * Returns a string representation of an instance - * @return {String} - */ - toString: function() { - return '#'; - }, - - /** - * Return the object scale factor counting also the group scaling - * @return {Object} object with scaleX and scaleY properties - */ - getObjectScaling: function() { - // if the object is a top level one, on the canvas, we go for simple aritmetic - // otherwise the complex method with angles will return approximations and decimals - // and will likely kill the cache when not needed - // https://github.com/fabricjs/fabric.js/issues/7157 - if (!this.group) { - return { - scaleX: this.scaleX, - scaleY: this.scaleY, - }; - } - // if we are inside a group total zoom calculation is complex, we defer to generic matrices - var options = fabric.util.qrDecompose(this.calcTransformMatrix()); - return { scaleX: Math.abs(options.scaleX), scaleY: Math.abs(options.scaleY) }; - }, - - /** - * Return the object scale factor counting also the group scaling, zoom and retina - * @return {Object} object with scaleX and scaleY properties - */ - getTotalObjectScaling: function() { - var scale = this.getObjectScaling(), scaleX = scale.scaleX, scaleY = scale.scaleY; - if (this.canvas) { - var zoom = this.canvas.getZoom(); - var retina = this.canvas.getRetinaScaling(); - scaleX *= zoom * retina; - scaleY *= zoom * retina; - } - return { scaleX: scaleX, scaleY: scaleY }; - }, - - /** - * Return the object opacity counting also the group property - * @return {Number} - */ - getObjectOpacity: function() { - var opacity = this.opacity; - if (this.group) { - opacity *= this.group.getObjectOpacity(); - } - return opacity; - }, - - /** - * @private - * @param {String} key - * @param {*} value - * @return {fabric.Object} thisArg - */ - _set: function(key, value) { - var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY'), - isChanged = this[key] !== value, groupNeedsUpdate = false; - - if (shouldConstrainValue) { - value = this._constrainScale(value); - } - if (key === 'scaleX' && value < 0) { - this.flipX = !this.flipX; - value *= -1; - } - else if (key === 'scaleY' && value < 0) { - this.flipY = !this.flipY; - value *= -1; - } - else if (key === 'shadow' && value && !(value instanceof fabric.Shadow)) { - value = new fabric.Shadow(value); - } - else if (key === 'dirty' && this.group) { - this.group.set('dirty', value); - } - - this[key] = value; - - if (isChanged) { - groupNeedsUpdate = this.group && this.group.isOnACache(); - if (this.cacheProperties.indexOf(key) > -1) { - this.dirty = true; - groupNeedsUpdate && this.group.set('dirty', true); - } - else if (groupNeedsUpdate && this.stateProperties.indexOf(key) > -1) { - this.group.set('dirty', true); - } - } - return this; - }, - - /** - * This callback function is called by the parent group of an object every - * time a non-delegated property changes on the group. It is passed the key - * and value as parameters. Not adding in this function's signature to avoid - * Travis build error about unused variables. - */ - setOnGroup: function() { - // implemented by sub-classes, as needed. - }, - - /** - * Retrieves viewportTransform from Object's canvas if possible - * @method getViewportTransform - * @memberOf fabric.Object.prototype - * @return {Array} - */ - getViewportTransform: function() { - if (this.canvas && this.canvas.viewportTransform) { - return this.canvas.viewportTransform; - } - return fabric.iMatrix.concat(); - }, - - /* - * @private - * return if the object would be visible in rendering - * @memberOf fabric.Object.prototype - * @return {Boolean} - */ - isNotVisible: function() { - return this.opacity === 0 || - (!this.width && !this.height && this.strokeWidth === 0) || - !this.visible; - }, - - /** - * Renders an object on a specified context - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - render: function(ctx) { - // do not render if width/height are zeros or object is not visible - if (this.isNotVisible()) { - return; - } - if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) { - return; - } - ctx.save(); - this._setupCompositeOperation(ctx); - this.drawSelectionBackground(ctx); - this.transform(ctx); - this._setOpacity(ctx); - this._setShadow(ctx, this); - if (this.shouldCache()) { - this.renderCache(); - this.drawCacheOnCanvas(ctx); - } - else { - this._removeCacheCanvas(); - this.dirty = false; - this.drawObject(ctx); - if (this.objectCaching && this.statefullCache) { - this.saveState({ propertySet: 'cacheProperties' }); - } - } - ctx.restore(); - }, - - renderCache: function(options) { - options = options || {}; - if (!this._cacheCanvas) { - this._createCacheCanvas(); - } - if (this.isCacheDirty()) { - this.statefullCache && this.saveState({ propertySet: 'cacheProperties' }); - this.drawObject(this._cacheContext, options.forClipping); - this.dirty = false; - } - }, - - /** - * Remove cacheCanvas and its dimensions from the objects - */ - _removeCacheCanvas: function() { - this._cacheCanvas = null; - this.cacheWidth = 0; - this.cacheHeight = 0; - }, - - /** - * return true if the object will draw a stroke - * Does not consider text styles. This is just a shortcut used at rendering time - * We want it to be an approximation and be fast. - * wrote to avoid extra caching, it has to return true when stroke happens, - * can guess when it will not happen at 100% chance, does not matter if it misses - * some use case where the stroke is invisible. - * @since 3.0.0 - * @returns Boolean - */ - hasStroke: function() { - return this.stroke && this.stroke !== 'transparent' && this.strokeWidth !== 0; - }, - - /** - * return true if the object will draw a fill - * Does not consider text styles. This is just a shortcut used at rendering time - * We want it to be an approximation and be fast. - * wrote to avoid extra caching, it has to return true when fill happens, - * can guess when it will not happen at 100% chance, does not matter if it misses - * some use case where the fill is invisible. - * @since 3.0.0 - * @returns Boolean - */ - hasFill: function() { - return this.fill && this.fill !== 'transparent'; - }, - - /** - * When set to `true`, force the object to have its own cache, even if it is inside a group - * it may be needed when your object behave in a particular way on the cache and always needs - * its own isolated canvas to render correctly. - * Created to be overridden - * since 1.7.12 - * @returns Boolean - */ - needsItsOwnCache: function() { - if (this.paintFirst === 'stroke' && - this.hasFill() && this.hasStroke() && typeof this.shadow === 'object') { - return true; - } - if (this.clipPath) { - return true; - } - return false; - }, - - /** - * Decide if the object should cache or not. Create its own cache level - * objectCaching is a global flag, wins over everything - * needsItsOwnCache should be used when the object drawing method requires - * a cache step. None of the fabric classes requires it. - * Generally you do not cache objects in groups because the group outside is cached. - * Read as: cache if is needed, or if the feature is enabled but we are not already caching. - * @return {Boolean} - */ - shouldCache: function() { - this.ownCaching = this.needsItsOwnCache() || ( - this.objectCaching && - (!this.group || !this.group.isOnACache()) - ); - return this.ownCaching; - }, - - /** - * Check if this object or a child object will cast a shadow - * used by Group.shouldCache to know if child has a shadow recursively - * @return {Boolean} - */ - willDrawShadow: function() { - return !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0); - }, - - /** - * Execute the drawing operation for an object clipPath - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - drawClipPathOnCache: function(ctx) { - var path = this.clipPath; - ctx.save(); - // DEBUG: uncomment this line, comment the following - // ctx.globalAlpha = 0.4 - if (path.inverted) { - ctx.globalCompositeOperation = 'destination-out'; - } - else { - ctx.globalCompositeOperation = 'destination-in'; - } - //ctx.scale(1 / 2, 1 / 2); - if (path.absolutePositioned) { - var m = fabric.util.invertTransform(this.calcTransformMatrix()); - ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); - } - path.transform(ctx); - ctx.scale(1 / path.zoomX, 1 / path.zoomY); - ctx.drawImage(path._cacheCanvas, -path.cacheTranslationX, -path.cacheTranslationY); - ctx.restore(); - }, - - /** - * Execute the drawing operation for an object on a specified context - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - drawObject: function(ctx, forClipping) { - var originalFill = this.fill, originalStroke = this.stroke; - if (forClipping) { - this.fill = 'black'; - this.stroke = ''; - this._setClippingProperties(ctx); - } - else { - this._renderBackground(ctx); - } - this._render(ctx); - this._drawClipPath(ctx); - this.fill = originalFill; - this.stroke = originalStroke; - }, - - _drawClipPath: function(ctx) { - var path = this.clipPath; - if (!path) { return; } - // needed to setup a couple of variables - // path canvas gets overridden with this one. - // TODO find a better solution? - path.canvas = this.canvas; - path.shouldCache(); - path._transformDone = true; - path.renderCache({ forClipping: true }); - this.drawClipPathOnCache(ctx); - }, - - /** - * Paint the cached copy of the object on the target context. - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - drawCacheOnCanvas: function(ctx) { - ctx.scale(1 / this.zoomX, 1 / this.zoomY); - ctx.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY); - }, - - /** - * Check if cache is dirty - * @param {Boolean} skipCanvas skip canvas checks because this object is painted - * on parent canvas. - */ - isCacheDirty: function(skipCanvas) { - if (this.isNotVisible()) { - return false; - } - if (this._cacheCanvas && !skipCanvas && this._updateCacheCanvas()) { - // in this case the context is already cleared. - return true; - } - else { - if (this.dirty || - (this.clipPath && this.clipPath.absolutePositioned) || - (this.statefullCache && this.hasStateChanged('cacheProperties')) - ) { - if (this._cacheCanvas && !skipCanvas) { - var width = this.cacheWidth / this.zoomX; - var height = this.cacheHeight / this.zoomY; - this._cacheContext.clearRect(-width / 2, -height / 2, width, height); - } - return true; - } - } - return false; - }, - - /** - * Draws a background for the object big as its untransformed dimensions - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderBackground: function(ctx) { - if (!this.backgroundColor) { - return; - } - var dim = this._getNonTransformedDimensions(); - ctx.fillStyle = this.backgroundColor; - - ctx.fillRect( - -dim.x / 2, - -dim.y / 2, - dim.x, - dim.y - ); - // if there is background color no other shadows - // should be casted - this._removeShadow(ctx); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _setOpacity: function(ctx) { - if (this.group && !this.group._transformDone) { - ctx.globalAlpha = this.getObjectOpacity(); - } - else { - ctx.globalAlpha *= this.opacity; - } - }, - - _setStrokeStyles: function(ctx, decl) { - var stroke = decl.stroke; - if (stroke) { - ctx.lineWidth = decl.strokeWidth; - ctx.lineCap = decl.strokeLineCap; - ctx.lineDashOffset = decl.strokeDashOffset; - ctx.lineJoin = decl.strokeLineJoin; - ctx.miterLimit = decl.strokeMiterLimit; - if (stroke.toLive) { - if (stroke.gradientUnits === 'percentage' || stroke.gradientTransform || stroke.patternTransform) { - // need to transform gradient in a pattern. - // this is a slow process. If you are hitting this codepath, and the object - // is not using caching, you should consider switching it on. - // we need a canvas as big as the current object caching canvas. - this._applyPatternForTransformedGradient(ctx, stroke); - } - else { - // is a simple gradient or pattern - ctx.strokeStyle = stroke.toLive(ctx, this); - this._applyPatternGradientTransform(ctx, stroke); - } - } - else { - // is a color - ctx.strokeStyle = decl.stroke; - } - } - }, - - _setFillStyles: function(ctx, decl) { - var fill = decl.fill; - if (fill) { - if (fill.toLive) { - ctx.fillStyle = fill.toLive(ctx, this); - this._applyPatternGradientTransform(ctx, decl.fill); - } - else { - ctx.fillStyle = fill; - } - } - }, - - _setClippingProperties: function(ctx) { - ctx.globalAlpha = 1; - ctx.strokeStyle = 'transparent'; - ctx.fillStyle = '#000000'; - }, - - /** - * @private - * Sets line dash - * @param {CanvasRenderingContext2D} ctx Context to set the dash line on - * @param {Array} dashArray array representing dashes - */ - _setLineDash: function(ctx, dashArray) { - if (!dashArray || dashArray.length === 0) { - return; - } - // Spec requires the concatenation of two copies the dash list when the number of elements is odd - if (1 & dashArray.length) { - dashArray.push.apply(dashArray, dashArray); - } - ctx.setLineDash(dashArray); - }, - - /** - * Renders controls and borders for the object - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Object} [styleOverride] properties to override the object style - */ - _renderControls: function(ctx, styleOverride) { - var vpt = this.getViewportTransform(), - matrix = this.calcTransformMatrix(), - options, drawBorders, drawControls; - styleOverride = styleOverride || { }; - drawBorders = typeof styleOverride.hasBorders !== 'undefined' ? styleOverride.hasBorders : this.hasBorders; - drawControls = typeof styleOverride.hasControls !== 'undefined' ? styleOverride.hasControls : this.hasControls; - matrix = fabric.util.multiplyTransformMatrices(vpt, matrix); - options = fabric.util.qrDecompose(matrix); - ctx.save(); - ctx.translate(options.translateX, options.translateY); - ctx.lineWidth = 1 * this.borderScaleFactor; - if (!this.group) { - ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; - } - ctx.rotate(degreesToRadians(options.angle)); - if (styleOverride.forActiveSelection || this.group) { - drawBorders && this.drawBordersInGroup(ctx, options, styleOverride); - } - else { - drawBorders && this.drawBorders(ctx, styleOverride); - } - drawControls && this.drawControls(ctx, styleOverride); - ctx.restore(); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _setShadow: function(ctx) { - if (!this.shadow) { - return; - } - - var shadow = this.shadow, canvas = this.canvas, scaling, - multX = (canvas && canvas.viewportTransform[0]) || 1, - multY = (canvas && canvas.viewportTransform[3]) || 1; - if (shadow.nonScaling) { - scaling = { scaleX: 1, scaleY: 1 }; - } - else { - scaling = this.getObjectScaling(); - } - if (canvas && canvas._isRetinaScaling()) { - multX *= fabric.devicePixelRatio; - multY *= fabric.devicePixelRatio; - } - ctx.shadowColor = shadow.color; - ctx.shadowBlur = shadow.blur * fabric.browserShadowBlurConstant * - (multX + multY) * (scaling.scaleX + scaling.scaleY) / 4; - ctx.shadowOffsetX = shadow.offsetX * multX * scaling.scaleX; - ctx.shadowOffsetY = shadow.offsetY * multY * scaling.scaleY; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _removeShadow: function(ctx) { - if (!this.shadow) { - return; - } - - ctx.shadowColor = ''; - ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Object} filler fabric.Pattern or fabric.Gradient - * @return {Object} offset.offsetX offset for text rendering - * @return {Object} offset.offsetY offset for text rendering - */ - _applyPatternGradientTransform: function(ctx, filler) { - if (!filler || !filler.toLive) { - return { offsetX: 0, offsetY: 0 }; - } - var t = filler.gradientTransform || filler.patternTransform; - var offsetX = -this.width / 2 + filler.offsetX || 0, - offsetY = -this.height / 2 + filler.offsetY || 0; - - if (filler.gradientUnits === 'percentage') { - ctx.transform(this.width, 0, 0, this.height, offsetX, offsetY); - } - else { - ctx.transform(1, 0, 0, 1, offsetX, offsetY); - } - if (t) { - ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]); - } - return { offsetX: offsetX, offsetY: offsetY }; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderPaintInOrder: function(ctx) { - if (this.paintFirst === 'stroke') { - this._renderStroke(ctx); - this._renderFill(ctx); - } - else { - this._renderFill(ctx); - this._renderStroke(ctx); - } - }, - - /** - * @private - * function that actually render something on the context. - * empty here to allow Obects to work on tests to benchmark fabric functionalites - * not related to rendering - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(/* ctx */) { - - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderFill: function(ctx) { - if (!this.fill) { - return; - } - - ctx.save(); - this._setFillStyles(ctx, this); - if (this.fillRule === 'evenodd') { - ctx.fill('evenodd'); - } - else { - ctx.fill(); - } - ctx.restore(); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderStroke: function(ctx) { - if (!this.stroke || this.strokeWidth === 0) { - return; - } - - if (this.shadow && !this.shadow.affectStroke) { - this._removeShadow(ctx); - } - - ctx.save(); - if (this.strokeUniform && this.group) { - var scaling = this.getObjectScaling(); - ctx.scale(1 / scaling.scaleX, 1 / scaling.scaleY); - } - else if (this.strokeUniform) { - ctx.scale(1 / this.scaleX, 1 / this.scaleY); - } - this._setLineDash(ctx, this.strokeDashArray); - this._setStrokeStyles(ctx, this); - ctx.stroke(); - ctx.restore(); - }, - - /** - * This function try to patch the missing gradientTransform on canvas gradients. - * transforming a context to transform the gradient, is going to transform the stroke too. - * we want to transform the gradient but not the stroke operation, so we create - * a transformed gradient on a pattern and then we use the pattern instead of the gradient. - * this method has drwabacks: is slow, is in low resolution, needs a patch for when the size - * is limited. - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {fabric.Gradient} filler a fabric gradient instance - */ - _applyPatternForTransformedGradient: function(ctx, filler) { - var dims = this._limitCacheSize(this._getCacheCanvasDimensions()), - pCanvas = fabric.util.createCanvasElement(), pCtx, retinaScaling = this.canvas.getRetinaScaling(), - width = dims.x / this.scaleX / retinaScaling, height = dims.y / this.scaleY / retinaScaling; - pCanvas.width = width; - pCanvas.height = height; - pCtx = pCanvas.getContext('2d'); - pCtx.beginPath(); pCtx.moveTo(0, 0); pCtx.lineTo(width, 0); pCtx.lineTo(width, height); - pCtx.lineTo(0, height); pCtx.closePath(); - pCtx.translate(width / 2, height / 2); - pCtx.scale( - dims.zoomX / this.scaleX / retinaScaling, - dims.zoomY / this.scaleY / retinaScaling - ); - this._applyPatternGradientTransform(pCtx, filler); - pCtx.fillStyle = filler.toLive(ctx); - pCtx.fill(); - ctx.translate(-this.width / 2 - this.strokeWidth / 2, -this.height / 2 - this.strokeWidth / 2); - ctx.scale( - retinaScaling * this.scaleX / dims.zoomX, - retinaScaling * this.scaleY / dims.zoomY - ); - ctx.strokeStyle = pCtx.createPattern(pCanvas, 'no-repeat'); - }, - - /** - * This function is an helper for svg import. it returns the center of the object in the svg - * untransformed coordinates - * @private - * @return {Object} center point from element coordinates - */ - _findCenterFromElement: function() { - return { x: this.left + this.width / 2, y: this.top + this.height / 2 }; - }, - - /** - * This function is an helper for svg import. it decompose the transformMatrix - * and assign properties to object. - * untransformed coordinates - * @private - * @chainable - */ - _assignTransformMatrixProps: function() { - if (this.transformMatrix) { - var options = fabric.util.qrDecompose(this.transformMatrix); - this.flipX = false; - this.flipY = false; - this.set('scaleX', options.scaleX); - this.set('scaleY', options.scaleY); - this.angle = options.angle; - this.skewX = options.skewX; - this.skewY = 0; - } - }, - - /** - * This function is an helper for svg import. it removes the transform matrix - * and set to object properties that fabricjs can handle - * @private - * @param {Object} preserveAspectRatioOptions - * @return {thisArg} - */ - _removeTransformMatrix: function(preserveAspectRatioOptions) { - var center = this._findCenterFromElement(); - if (this.transformMatrix) { - this._assignTransformMatrixProps(); - center = fabric.util.transformPoint(center, this.transformMatrix); - } - this.transformMatrix = null; - if (preserveAspectRatioOptions) { - this.scaleX *= preserveAspectRatioOptions.scaleX; - this.scaleY *= preserveAspectRatioOptions.scaleY; - this.cropX = preserveAspectRatioOptions.cropX; - this.cropY = preserveAspectRatioOptions.cropY; - center.x += preserveAspectRatioOptions.offsetLeft; - center.y += preserveAspectRatioOptions.offsetTop; - this.width = preserveAspectRatioOptions.width; - this.height = preserveAspectRatioOptions.height; - } - this.setPositionByOrigin(center, 'center', 'center'); - }, - - /** - * Clones an instance, using a callback method will work for every object. - * @param {Function} callback Callback is invoked with a clone as a first argument - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - */ - clone: function(callback, propertiesToInclude) { - var objectForm = this.toObject(propertiesToInclude); - if (this.constructor.fromObject) { - this.constructor.fromObject(objectForm, callback); - } - else { - fabric.Object._fromObject('Object', objectForm, callback); - } - }, - - /** - * Creates an instance of fabric.Image out of an object - * makes use of toCanvasElement. - * Once this method was based on toDataUrl and loadImage, so it also had a quality - * and format option. toCanvasElement is faster and produce no loss of quality. - * If you need to get a real Jpeg or Png from an object, using toDataURL is the right way to do it. - * toCanvasElement and then toBlob from the obtained canvas is also a good option. - * This method is sync now, but still support the callback because we did not want to break. - * When fabricJS 5.0 will be planned, this will probably be changed to not have a callback. - * @param {Function} callback callback, invoked with an instance as a first argument - * @param {Object} [options] for clone as image, passed to toDataURL - * @param {Number} [options.multiplier=1] Multiplier to scale by - * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 - * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 - * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 - * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 - * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4 - * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 - * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2 - * @return {fabric.Object} thisArg - */ - cloneAsImage: function(callback, options) { - var canvasEl = this.toCanvasElement(options); - if (callback) { - callback(new fabric.Image(canvasEl)); - } - return this; - }, - - /** - * Converts an object into a HTMLCanvas element - * @param {Object} options Options object - * @param {Number} [options.multiplier=1] Multiplier to scale by - * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 - * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 - * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 - * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 - * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4 - * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 - * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2 - * @return {HTMLCanvasElement} Returns DOM element with the fabric.Object - */ - toCanvasElement: function(options) { - options || (options = { }); - - var utils = fabric.util, origParams = utils.saveObjectTransform(this), - originalGroup = this.group, - originalShadow = this.shadow, abs = Math.abs, - multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? fabric.devicePixelRatio : 1); - delete this.group; - if (options.withoutTransform) { - utils.resetObjectTransform(this); - } - if (options.withoutShadow) { - this.shadow = null; - } - - var el = fabric.util.createCanvasElement(), - // skip canvas zoom and calculate with setCoords now. - boundingRect = this.getBoundingRect(true, true), - shadow = this.shadow, scaling, - shadowOffset = { x: 0, y: 0 }, shadowBlur, - width, height; - - if (shadow) { - shadowBlur = shadow.blur; - if (shadow.nonScaling) { - scaling = { scaleX: 1, scaleY: 1 }; - } - else { - scaling = this.getObjectScaling(); - } - // consider non scaling shadow. - shadowOffset.x = 2 * Math.round(abs(shadow.offsetX) + shadowBlur) * (abs(scaling.scaleX)); - shadowOffset.y = 2 * Math.round(abs(shadow.offsetY) + shadowBlur) * (abs(scaling.scaleY)); - } - width = boundingRect.width + shadowOffset.x; - height = boundingRect.height + shadowOffset.y; - // if the current width/height is not an integer - // we need to make it so. - el.width = Math.ceil(width); - el.height = Math.ceil(height); - var canvas = new fabric.StaticCanvas(el, { - enableRetinaScaling: false, - renderOnAddRemove: false, - skipOffscreen: false, - }); - if (options.format === 'jpeg') { - canvas.backgroundColor = '#fff'; - } - this.setPositionByOrigin(new fabric.Point(canvas.width / 2, canvas.height / 2), 'center', 'center'); - - var originalCanvas = this.canvas; - canvas.add(this); - var canvasEl = canvas.toCanvasElement(multiplier || 1, options); - this.shadow = originalShadow; - this.set('canvas', originalCanvas); - if (originalGroup) { - this.group = originalGroup; - } - this.set(origParams).setCoords(); - // canvas.dispose will call image.dispose that will nullify the elements - // since this canvas is a simple element for the process, we remove references - // to objects in this way in order to avoid object trashing. - canvas._objects = []; - canvas.dispose(); - canvas = null; - - return canvasEl; - }, - - /** - * Converts an object into a data-url-like string - * @param {Object} options Options object - * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png" - * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg. - * @param {Number} [options.multiplier=1] Multiplier to scale by - * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 - * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 - * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 - * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 - * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4 - * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 - * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2 - * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format - */ - toDataURL: function(options) { - options || (options = { }); - return fabric.util.toDataURL(this.toCanvasElement(options), options.format || 'png', options.quality || 1); - }, - - /** - * Returns true if specified type is identical to the type of an instance - * @param {String} type Type to check against - * @return {Boolean} - */ - isType: function(type) { - return this.type === type; - }, - - /** - * Returns complexity of an instance - * @return {Number} complexity of this instance (is 1 unless subclassed) - */ - complexity: function() { - return 1; - }, - - /** - * Returns a JSON representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} JSON - */ - toJSON: function(propertiesToInclude) { - // delegate, not alias - return this.toObject(propertiesToInclude); - }, - - /** - * Sets "angle" of an instance with centered rotation - * @param {Number} angle Angle value (in degrees) - * @return {fabric.Object} thisArg - * @chainable - */ - rotate: function(angle) { - var shouldCenterOrigin = (this.originX !== 'center' || this.originY !== 'center') && this.centeredRotation; - - if (shouldCenterOrigin) { - this._setOriginToCenter(); - } - - this.set('angle', angle); - - if (shouldCenterOrigin) { - this._resetOrigin(); - } - - return this; - }, - - /** - * Centers object horizontally on canvas to which it was added last. - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - centerH: function () { - this.canvas && this.canvas.centerObjectH(this); - return this; - }, - - /** - * Centers object horizontally on current viewport of canvas to which it was added last. - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - viewportCenterH: function () { - this.canvas && this.canvas.viewportCenterObjectH(this); - return this; - }, - - /** - * Centers object vertically on canvas to which it was added last. - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - centerV: function () { - this.canvas && this.canvas.centerObjectV(this); - return this; - }, - - /** - * Centers object vertically on current viewport of canvas to which it was added last. - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - viewportCenterV: function () { - this.canvas && this.canvas.viewportCenterObjectV(this); - return this; - }, - - /** - * Centers object vertically and horizontally on canvas to which is was added last - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - center: function () { - this.canvas && this.canvas.centerObject(this); - return this; - }, - - /** - * Centers object on current viewport of canvas to which it was added last. - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - viewportCenter: function () { - this.canvas && this.canvas.viewportCenterObject(this); - return this; - }, - - /** - * Returns coordinates of a pointer relative to an object - * @param {Event} e Event to operate upon - * @param {Object} [pointer] Pointer to operate upon (instead of event) - * @return {Object} Coordinates of a pointer (x, y) - */ - getLocalPointer: function(e, pointer) { - pointer = pointer || this.canvas.getPointer(e); - var pClicked = new fabric.Point(pointer.x, pointer.y), - objectLeftTop = this._getLeftTopCoords(); - if (this.angle) { - pClicked = fabric.util.rotatePoint( - pClicked, objectLeftTop, degreesToRadians(-this.angle)); - } - return { - x: pClicked.x - objectLeftTop.x, - y: pClicked.y - objectLeftTop.y - }; - }, - - /** - * Sets canvas globalCompositeOperation for specific object - * custom composition operation for the particular object can be specified using globalCompositeOperation property - * @param {CanvasRenderingContext2D} ctx Rendering canvas context - */ - _setupCompositeOperation: function (ctx) { - if (this.globalCompositeOperation) { - ctx.globalCompositeOperation = this.globalCompositeOperation; - } - } - }); - - fabric.util.createAccessors && fabric.util.createAccessors(fabric.Object); - - extend(fabric.Object.prototype, fabric.Observable); - - /** - * Defines the number of fraction digits to use when serializing object values. - * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc. - * @static - * @memberOf fabric.Object - * @constant - * @type Number - */ - fabric.Object.NUM_FRACTION_DIGITS = 2; - - fabric.Object._fromObject = function(className, object, callback, extraParam) { - var klass = fabric[className]; - object = clone(object, true); - fabric.util.enlivenPatterns([object.fill, object.stroke], function(patterns) { - if (typeof patterns[0] !== 'undefined') { - object.fill = patterns[0]; - } - if (typeof patterns[1] !== 'undefined') { - object.stroke = patterns[1]; - } - fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) { - object.clipPath = enlivedProps[0]; - var instance = extraParam ? new klass(object[extraParam], object) : new klass(object); - callback && callback(instance); - }); - }); - }; - - /** - * Unique id used internally when creating SVG elements - * @static - * @memberOf fabric.Object - * @type Number - */ - fabric.Object.__uid = 0; -})(typeof exports !== 'undefined' ? exports : this); - - -(function() { - - var degreesToRadians = fabric.util.degreesToRadians, - originXOffset = { - left: -0.5, - center: 0, - right: 0.5 - }, - originYOffset = { - top: -0.5, - center: 0, - bottom: 0.5 - }; - - fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - - /** - * Translates the coordinates from a set of origin to another (based on the object's dimensions) - * @param {fabric.Point} point The point which corresponds to the originX and originY params - * @param {String} fromOriginX Horizontal origin: 'left', 'center' or 'right' - * @param {String} fromOriginY Vertical origin: 'top', 'center' or 'bottom' - * @param {String} toOriginX Horizontal origin: 'left', 'center' or 'right' - * @param {String} toOriginY Vertical origin: 'top', 'center' or 'bottom' - * @return {fabric.Point} - */ - translateToGivenOrigin: function(point, fromOriginX, fromOriginY, toOriginX, toOriginY) { - var x = point.x, - y = point.y, - offsetX, offsetY, dim; - - if (typeof fromOriginX === 'string') { - fromOriginX = originXOffset[fromOriginX]; - } - else { - fromOriginX -= 0.5; - } - - if (typeof toOriginX === 'string') { - toOriginX = originXOffset[toOriginX]; - } - else { - toOriginX -= 0.5; - } - - offsetX = toOriginX - fromOriginX; - - if (typeof fromOriginY === 'string') { - fromOriginY = originYOffset[fromOriginY]; - } - else { - fromOriginY -= 0.5; - } - - if (typeof toOriginY === 'string') { - toOriginY = originYOffset[toOriginY]; - } - else { - toOriginY -= 0.5; - } - - offsetY = toOriginY - fromOriginY; - - if (offsetX || offsetY) { - dim = this._getTransformedDimensions(); - x = point.x + offsetX * dim.x; - y = point.y + offsetY * dim.y; - } - - return new fabric.Point(x, y); - }, - - /** - * Translates the coordinates from origin to center coordinates (based on the object's dimensions) - * @param {fabric.Point} point The point which corresponds to the originX and originY params - * @param {String} originX Horizontal origin: 'left', 'center' or 'right' - * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' - * @return {fabric.Point} - */ - translateToCenterPoint: function(point, originX, originY) { - var p = this.translateToGivenOrigin(point, originX, originY, 'center', 'center'); - if (this.angle) { - return fabric.util.rotatePoint(p, point, degreesToRadians(this.angle)); - } - return p; - }, - - /** - * Translates the coordinates from center to origin coordinates (based on the object's dimensions) - * @param {fabric.Point} center The point which corresponds to center of the object - * @param {String} originX Horizontal origin: 'left', 'center' or 'right' - * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' - * @return {fabric.Point} - */ - translateToOriginPoint: function(center, originX, originY) { - var p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY); - if (this.angle) { - return fabric.util.rotatePoint(p, center, degreesToRadians(this.angle)); - } - return p; - }, - - /** - * Returns the real center coordinates of the object - * @return {fabric.Point} - */ - getCenterPoint: function() { - var leftTop = new fabric.Point(this.left, this.top); - return this.translateToCenterPoint(leftTop, this.originX, this.originY); - }, - - /** - * Returns the coordinates of the object based on center coordinates - * @param {fabric.Point} point The point which corresponds to the originX and originY params - * @return {fabric.Point} - */ - // getOriginPoint: function(center) { - // return this.translateToOriginPoint(center, this.originX, this.originY); - // }, - - /** - * Returns the coordinates of the object as if it has a different origin - * @param {String} originX Horizontal origin: 'left', 'center' or 'right' - * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' - * @return {fabric.Point} - */ - getPointByOrigin: function(originX, originY) { - var center = this.getCenterPoint(); - return this.translateToOriginPoint(center, originX, originY); - }, - - /** - * Returns the point in local coordinates - * @param {fabric.Point} point The point relative to the global coordinate system - * @param {String} originX Horizontal origin: 'left', 'center' or 'right' - * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' - * @return {fabric.Point} - */ - toLocalPoint: function(point, originX, originY) { - var center = this.getCenterPoint(), - p, p2; - - if (typeof originX !== 'undefined' && typeof originY !== 'undefined' ) { - p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY); - } - else { - p = new fabric.Point(this.left, this.top); - } - - p2 = new fabric.Point(point.x, point.y); - if (this.angle) { - p2 = fabric.util.rotatePoint(p2, center, -degreesToRadians(this.angle)); - } - return p2.subtractEquals(p); - }, - - /** - * Returns the point in global coordinates - * @param {fabric.Point} The point relative to the local coordinate system - * @return {fabric.Point} - */ - // toGlobalPoint: function(point) { - // return fabric.util.rotatePoint(point, this.getCenterPoint(), degreesToRadians(this.angle)).addEquals(new fabric.Point(this.left, this.top)); - // }, - - /** - * Sets the position of the object taking into consideration the object's origin - * @param {fabric.Point} pos The new position of the object - * @param {String} originX Horizontal origin: 'left', 'center' or 'right' - * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' - * @return {void} - */ - setPositionByOrigin: function(pos, originX, originY) { - var center = this.translateToCenterPoint(pos, originX, originY), - position = this.translateToOriginPoint(center, this.originX, this.originY); - this.set('left', position.x); - this.set('top', position.y); - }, - - /** - * @param {String} to One of 'left', 'center', 'right' - */ - adjustPosition: function(to) { - var angle = degreesToRadians(this.angle), - hypotFull = this.getScaledWidth(), - xFull = fabric.util.cos(angle) * hypotFull, - yFull = fabric.util.sin(angle) * hypotFull, - offsetFrom, offsetTo; - - //TODO: this function does not consider mixed situation like top, center. - if (typeof this.originX === 'string') { - offsetFrom = originXOffset[this.originX]; - } - else { - offsetFrom = this.originX - 0.5; - } - if (typeof to === 'string') { - offsetTo = originXOffset[to]; - } - else { - offsetTo = to - 0.5; - } - this.left += xFull * (offsetTo - offsetFrom); - this.top += yFull * (offsetTo - offsetFrom); - this.setCoords(); - this.originX = to; - }, - - /** - * Sets the origin/position of the object to it's center point - * @private - * @return {void} - */ - _setOriginToCenter: function() { - this._originalOriginX = this.originX; - this._originalOriginY = this.originY; - - var center = this.getCenterPoint(); - - this.originX = 'center'; - this.originY = 'center'; - - this.left = center.x; - this.top = center.y; - }, - - /** - * Resets the origin/position of the object to it's original origin - * @private - * @return {void} - */ - _resetOrigin: function() { - var originPoint = this.translateToOriginPoint( - this.getCenterPoint(), - this._originalOriginX, - this._originalOriginY); - - this.originX = this._originalOriginX; - this.originY = this._originalOriginY; - - this.left = originPoint.x; - this.top = originPoint.y; - - this._originalOriginX = null; - this._originalOriginY = null; - }, - - /** - * @private - */ - _getLeftTopCoords: function() { - return this.translateToOriginPoint(this.getCenterPoint(), 'left', 'top'); - }, - }); - -})(); - - -(function() { - - function arrayFromCoords(coords) { - return [ - new fabric.Point(coords.tl.x, coords.tl.y), - new fabric.Point(coords.tr.x, coords.tr.y), - new fabric.Point(coords.br.x, coords.br.y), - new fabric.Point(coords.bl.x, coords.bl.y) - ]; - } - - var util = fabric.util, - degreesToRadians = util.degreesToRadians, - multiplyMatrices = util.multiplyTransformMatrices, - transformPoint = util.transformPoint; - - util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - - /** - * Describe object's corner position in canvas element coordinates. - * properties are depending on control keys and padding the main controls. - * each property is an object with x, y and corner. - * The `corner` property contains in a similar manner the 4 points of the - * interactive area of the corner. - * The coordinates depends from the controls positionHandler and are used - * to draw and locate controls - * @memberOf fabric.Object.prototype - */ - oCoords: null, - - /** - * Describe object's corner position in canvas object absolute coordinates - * properties are tl,tr,bl,br and describe the four main corner. - * each property is an object with x, y, instance of Fabric.Point. - * The coordinates depends from this properties: width, height, scaleX, scaleY - * skewX, skewY, angle, strokeWidth, top, left. - * Those coordinates are useful to understand where an object is. They get updated - * with oCoords but they do not need to be updated when zoom or panning change. - * The coordinates get updated with @method setCoords. - * You can calculate them without updating with @method calcACoords(); - * @memberOf fabric.Object.prototype - */ - aCoords: null, - - /** - * Describe object's corner position in canvas element coordinates. - * includes padding. Used of object detection. - * set and refreshed with setCoords and calcCoords. - * @memberOf fabric.Object.prototype - */ - lineCoords: null, - - /** - * storage for object transform matrix - */ - ownMatrixCache: null, - - /** - * storage for object full transform matrix - */ - matrixCache: null, - - /** - * custom controls interface - * controls are added by default_controls.js - */ - controls: { }, - - /** - * return correct set of coordinates for intersection - * this will return either aCoords or lineCoords. - * @param {Boolean} absolute will return aCoords if true or lineCoords - * @return {Object} {tl, tr, br, bl} points - */ - _getCoords: function(absolute, calculate) { - if (calculate) { - return (absolute ? this.calcACoords() : this.calcLineCoords()); - } - if (!this.aCoords || !this.lineCoords) { - this.setCoords(true); - } - return (absolute ? this.aCoords : this.lineCoords); - }, - - /** - * return correct set of coordinates for intersection - * this will return either aCoords or lineCoords. - * The coords are returned in an array. - * @return {Array} [tl, tr, br, bl] of points - */ - getCoords: function(absolute, calculate) { - return arrayFromCoords(this._getCoords(absolute, calculate)); - }, - - /** - * Checks if object intersects with an area formed by 2 points - * @param {Object} pointTL top-left point of area - * @param {Object} pointBR bottom-right point of area - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if object intersects with an area formed by 2 points - */ - intersectsWithRect: function(pointTL, pointBR, absolute, calculate) { - var coords = this.getCoords(absolute, calculate), - intersection = fabric.Intersection.intersectPolygonRectangle( - coords, - pointTL, - pointBR - ); - return intersection.status === 'Intersection'; - }, - - /** - * Checks if object intersects with another object - * @param {Object} other Object to test - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if object intersects with another object - */ - intersectsWithObject: function(other, absolute, calculate) { - var intersection = fabric.Intersection.intersectPolygonPolygon( - this.getCoords(absolute, calculate), - other.getCoords(absolute, calculate) - ); - - return intersection.status === 'Intersection' - || other.isContainedWithinObject(this, absolute, calculate) - || this.isContainedWithinObject(other, absolute, calculate); - }, - - /** - * Checks if object is fully contained within area of another object - * @param {Object} other Object to test - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if object is fully contained within area of another object - */ - isContainedWithinObject: function(other, absolute, calculate) { - var points = this.getCoords(absolute, calculate), - otherCoords = absolute ? other.aCoords : other.lineCoords, - i = 0, lines = other._getImageLines(otherCoords); - for (; i < 4; i++) { - if (!other.containsPoint(points[i], lines)) { - return false; - } - } - return true; - }, - - /** - * Checks if object is fully contained within area formed by 2 points - * @param {Object} pointTL top-left point of area - * @param {Object} pointBR bottom-right point of area - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if object is fully contained within area formed by 2 points - */ - isContainedWithinRect: function(pointTL, pointBR, absolute, calculate) { - var boundingRect = this.getBoundingRect(absolute, calculate); - - return ( - boundingRect.left >= pointTL.x && - boundingRect.left + boundingRect.width <= pointBR.x && - boundingRect.top >= pointTL.y && - boundingRect.top + boundingRect.height <= pointBR.y - ); - }, - - /** - * Checks if point is inside the object - * @param {fabric.Point} point Point to check against - * @param {Object} [lines] object returned from @method _getImageLines - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if point is inside the object - */ - containsPoint: function(point, lines, absolute, calculate) { - var coords = this._getCoords(absolute, calculate), - lines = lines || this._getImageLines(coords), - xPoints = this._findCrossPoints(point, lines); - // if xPoints is odd then point is inside the object - return (xPoints !== 0 && xPoints % 2 === 1); - }, - - /** - * Checks if object is contained within the canvas with current viewportTransform - * the check is done stopping at first point that appears on screen - * @param {Boolean} [calculate] use coordinates of current position instead of .aCoords - * @return {Boolean} true if object is fully or partially contained within canvas - */ - isOnScreen: function(calculate) { - if (!this.canvas) { - return false; - } - var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br; - var points = this.getCoords(true, calculate); - // if some point is on screen, the object is on screen. - if (points.some(function(point) { - return point.x <= pointBR.x && point.x >= pointTL.x && - point.y <= pointBR.y && point.y >= pointTL.y; - })) { - return true; - } - // no points on screen, check intersection with absolute coordinates - if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) { - return true; - } - return this._containsCenterOfCanvas(pointTL, pointBR, calculate); - }, - - /** - * Checks if the object contains the midpoint between canvas extremities - * Does not make sense outside the context of isOnScreen and isPartiallyOnScreen - * @private - * @param {Fabric.Point} pointTL Top Left point - * @param {Fabric.Point} pointBR Top Right point - * @param {Boolean} calculate use coordinates of current position instead of .oCoords - * @return {Boolean} true if the object contains the point - */ - _containsCenterOfCanvas: function(pointTL, pointBR, calculate) { - // worst case scenario the object is so big that contains the screen - var centerPoint = { x: (pointTL.x + pointBR.x) / 2, y: (pointTL.y + pointBR.y) / 2 }; - if (this.containsPoint(centerPoint, null, true, calculate)) { - return true; - } - return false; - }, - - /** - * Checks if object is partially contained within the canvas with current viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if object is partially contained within canvas - */ - isPartiallyOnScreen: function(calculate) { - if (!this.canvas) { - return false; - } - var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br; - if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) { - return true; - } - var allPointsAreOutside = this.getCoords(true, calculate).every(function(point) { - return (point.x >= pointBR.x || point.x <= pointTL.x) && - (point.y >= pointBR.y || point.y <= pointTL.y); - }); - return allPointsAreOutside && this._containsCenterOfCanvas(pointTL, pointBR, calculate); - }, - - /** - * Method that returns an object with the object edges in it, given the coordinates of the corners - * @private - * @param {Object} oCoords Coordinates of the object corners - */ - _getImageLines: function(oCoords) { - - var lines = { - topline: { - o: oCoords.tl, - d: oCoords.tr - }, - rightline: { - o: oCoords.tr, - d: oCoords.br - }, - bottomline: { - o: oCoords.br, - d: oCoords.bl - }, - leftline: { - o: oCoords.bl, - d: oCoords.tl - } - }; - - // // debugging - // if (this.canvas.contextTop) { - // this.canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2); - // } - - return lines; - }, - - /** - * Helper method to determine how many cross points are between the 4 object edges - * and the horizontal line determined by a point on canvas - * @private - * @param {fabric.Point} point Point to check - * @param {Object} lines Coordinates of the object being evaluated - */ - // remove yi, not used but left code here just in case. - _findCrossPoints: function(point, lines) { - var b1, b2, a1, a2, xi, // yi, - xcount = 0, - iLine; - - for (var lineKey in lines) { - iLine = lines[lineKey]; - // optimisation 1: line below point. no cross - if ((iLine.o.y < point.y) && (iLine.d.y < point.y)) { - continue; - } - // optimisation 2: line above point. no cross - if ((iLine.o.y >= point.y) && (iLine.d.y >= point.y)) { - continue; - } - // optimisation 3: vertical line case - if ((iLine.o.x === iLine.d.x) && (iLine.o.x >= point.x)) { - xi = iLine.o.x; - // yi = point.y; - } - // calculate the intersection point - else { - b1 = 0; - b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x); - a1 = point.y - b1 * point.x; - a2 = iLine.o.y - b2 * iLine.o.x; - - xi = -(a1 - a2) / (b1 - b2); - // yi = a1 + b1 * xi; - } - // dont count xi < point.x cases - if (xi >= point.x) { - xcount += 1; - } - // optimisation 4: specific for square images - if (xcount === 2) { - break; - } - } - return xcount; - }, - - /** - * Returns coordinates of object's bounding rectangle (left, top, width, height) - * the box is intended as aligned to axis of canvas. - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords / .aCoords - * @return {Object} Object with left, top, width, height properties - */ - getBoundingRect: function(absolute, calculate) { - var coords = this.getCoords(absolute, calculate); - return util.makeBoundingBoxFromPoints(coords); - }, - - /** - * Returns width of an object's bounding box counting transformations - * before 2.0 it was named getWidth(); - * @return {Number} width value - */ - getScaledWidth: function() { - return this._getTransformedDimensions().x; - }, - - /** - * Returns height of an object bounding box counting transformations - * before 2.0 it was named getHeight(); - * @return {Number} height value - */ - getScaledHeight: function() { - return this._getTransformedDimensions().y; - }, - - /** - * Makes sure the scale is valid and modifies it if necessary - * @private - * @param {Number} value - * @return {Number} - */ - _constrainScale: function(value) { - if (Math.abs(value) < this.minScaleLimit) { - if (value < 0) { - return -this.minScaleLimit; - } - else { - return this.minScaleLimit; - } - } - else if (value === 0) { - return 0.0001; - } - return value; - }, - - /** - * Scales an object (equally by x and y) - * @param {Number} value Scale factor - * @return {fabric.Object} thisArg - * @chainable - */ - scale: function(value) { - this._set('scaleX', value); - this._set('scaleY', value); - return this.setCoords(); - }, - - /** - * Scales an object to a given width, with respect to bounding box (scaling by x/y equally) - * @param {Number} value New width value - * @param {Boolean} absolute ignore viewport - * @return {fabric.Object} thisArg - * @chainable - */ - scaleToWidth: function(value, absolute) { - // adjust to bounding rect factor so that rotated shapes would fit as well - var boundingRectFactor = this.getBoundingRect(absolute).width / this.getScaledWidth(); - return this.scale(value / this.width / boundingRectFactor); - }, - - /** - * Scales an object to a given height, with respect to bounding box (scaling by x/y equally) - * @param {Number} value New height value - * @param {Boolean} absolute ignore viewport - * @return {fabric.Object} thisArg - * @chainable - */ - scaleToHeight: function(value, absolute) { - // adjust to bounding rect factor so that rotated shapes would fit as well - var boundingRectFactor = this.getBoundingRect(absolute).height / this.getScaledHeight(); - return this.scale(value / this.height / boundingRectFactor); - }, - - /** - * Calculates and returns the .coords of an object. - * unused by the library, only for the end dev. - * @return {Object} Object with tl, tr, br, bl .... - * @chainable - * @deprecated - */ - calcCoords: function(absolute) { - // this is a compatibility function to avoid removing calcCoords now. - if (absolute) { - return this.calcACoords(); - } - return this.calcOCoords(); - }, - - calcLineCoords: function() { - var vpt = this.getViewportTransform(), - padding = this.padding, angle = degreesToRadians(this.angle), - cos = util.cos(angle), sin = util.sin(angle), - cosP = cos * padding, sinP = sin * padding, cosPSinP = cosP + sinP, - cosPMinusSinP = cosP - sinP, aCoords = this.calcACoords(); - - var lineCoords = { - tl: transformPoint(aCoords.tl, vpt), - tr: transformPoint(aCoords.tr, vpt), - bl: transformPoint(aCoords.bl, vpt), - br: transformPoint(aCoords.br, vpt), - }; - - if (padding) { - lineCoords.tl.x -= cosPMinusSinP; - lineCoords.tl.y -= cosPSinP; - lineCoords.tr.x += cosPSinP; - lineCoords.tr.y -= cosPMinusSinP; - lineCoords.bl.x -= cosPSinP; - lineCoords.bl.y += cosPMinusSinP; - lineCoords.br.x += cosPMinusSinP; - lineCoords.br.y += cosPSinP; - } - - return lineCoords; - }, - - calcOCoords: function() { - var rotateMatrix = this._calcRotateMatrix(), - translateMatrix = this._calcTranslateMatrix(), - vpt = this.getViewportTransform(), - startMatrix = multiplyMatrices(vpt, translateMatrix), - finalMatrix = multiplyMatrices(startMatrix, rotateMatrix), - finalMatrix = multiplyMatrices(finalMatrix, [1 / vpt[0], 0, 0, 1 / vpt[3], 0, 0]), - dim = this._calculateCurrentDimensions(), - coords = {}; - this.forEachControl(function(control, key, fabricObject) { - coords[key] = control.positionHandler(dim, finalMatrix, fabricObject); - }); - - // debug code - // var canvas = this.canvas; - // setTimeout(function() { - // canvas.contextTop.clearRect(0, 0, 700, 700); - // canvas.contextTop.fillStyle = 'green'; - // Object.keys(coords).forEach(function(key) { - // var control = coords[key]; - // canvas.contextTop.fillRect(control.x, control.y, 3, 3); - // }); - // }, 50); - return coords; - }, - - calcACoords: function() { - var rotateMatrix = this._calcRotateMatrix(), - translateMatrix = this._calcTranslateMatrix(), - finalMatrix = multiplyMatrices(translateMatrix, rotateMatrix), - dim = this._getTransformedDimensions(), - w = dim.x / 2, h = dim.y / 2; - return { - // corners - tl: transformPoint({ x: -w, y: -h }, finalMatrix), - tr: transformPoint({ x: w, y: -h }, finalMatrix), - bl: transformPoint({ x: -w, y: h }, finalMatrix), - br: transformPoint({ x: w, y: h }, finalMatrix) - }; - }, - - /** - * Sets corner and controls position coordinates based on current angle, width and height, left and top. - * oCoords are used to find the corners - * aCoords are used to quickly find an object on the canvas - * lineCoords are used to quickly find object during pointer events. - * See {@link https://github.com/kangax/fabric.js/wiki/When-to-call-setCoords|When-to-call-setCoords} - * @param {Boolean} [skipCorners] skip calculation of oCoords. - * @return {fabric.Object} thisArg - * @chainable - */ - setCoords: function(skipCorners) { - this.aCoords = this.calcACoords(); - // in case we are in a group, for how the inner group target check works, - // lineCoords are exactly aCoords. Since the vpt gets absorbed by the normalized pointer. - this.lineCoords = this.group ? this.aCoords : this.calcLineCoords(); - if (skipCorners) { - return this; - } - // set coordinates of the draggable boxes in the corners used to scale/rotate the image - this.oCoords = this.calcOCoords(); - this._setCornerCoords && this._setCornerCoords(); - return this; - }, - - /** - * calculate rotation matrix of an object - * @return {Array} rotation matrix for the object - */ - _calcRotateMatrix: function() { - return util.calcRotateMatrix(this); - }, - - /** - * calculate the translation matrix for an object transform - * @return {Array} rotation matrix for the object - */ - _calcTranslateMatrix: function() { - var center = this.getCenterPoint(); - return [1, 0, 0, 1, center.x, center.y]; - }, - - transformMatrixKey: function(skipGroup) { - var sep = '_', prefix = ''; - if (!skipGroup && this.group) { - prefix = this.group.transformMatrixKey(skipGroup) + sep; - }; - return prefix + this.top + sep + this.left + sep + this.scaleX + sep + this.scaleY + - sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.originX + sep + this.originY + - sep + this.width + sep + this.height + sep + this.strokeWidth + this.flipX + this.flipY; - }, - - /** - * calculate transform matrix that represents the current transformations from the - * object's properties. - * @param {Boolean} [skipGroup] return transform matrix for object not counting parent transformations - * There are some situation in which this is useful to avoid the fake rotation. - * @return {Array} transform matrix for the object - */ - calcTransformMatrix: function(skipGroup) { - var matrix = this.calcOwnMatrix(); - if (skipGroup || !this.group) { - return matrix; - } - var key = this.transformMatrixKey(skipGroup), cache = this.matrixCache || (this.matrixCache = {}); - if (cache.key === key) { - return cache.value; - } - if (this.group) { - matrix = multiplyMatrices(this.group.calcTransformMatrix(false), matrix); - } - cache.key = key; - cache.value = matrix; - return matrix; - }, - - /** - * calculate transform matrix that represents the current transformations from the - * object's properties, this matrix does not include the group transformation - * @return {Array} transform matrix for the object - */ - calcOwnMatrix: function() { - var key = this.transformMatrixKey(true), cache = this.ownMatrixCache || (this.ownMatrixCache = {}); - if (cache.key === key) { - return cache.value; - } - var tMatrix = this._calcTranslateMatrix(), - options = { - angle: this.angle, - translateX: tMatrix[4], - translateY: tMatrix[5], - scaleX: this.scaleX, - scaleY: this.scaleY, - skewX: this.skewX, - skewY: this.skewY, - flipX: this.flipX, - flipY: this.flipY, - }; - cache.key = key; - cache.value = util.composeMatrix(options); - return cache.value; - }, - - /* - * Calculate object dimensions from its properties - * @private - * @deprecated since 3.4.0, please use fabric.util._calcDimensionsTransformMatrix - * not including or including flipX, flipY to emulate the flipping boolean - * @return {Object} .x width dimension - * @return {Object} .y height dimension - */ - _calcDimensionsTransformMatrix: function(skewX, skewY, flipping) { - return util.calcDimensionsMatrix({ - skewX: skewX, - skewY: skewY, - scaleX: this.scaleX * (flipping && this.flipX ? -1 : 1), - scaleY: this.scaleY * (flipping && this.flipY ? -1 : 1) - }); - }, - - /* - * Calculate object dimensions from its properties - * @private - * @return {Object} .x width dimension - * @return {Object} .y height dimension - */ - _getNonTransformedDimensions: function() { - var strokeWidth = this.strokeWidth, - w = this.width + strokeWidth, - h = this.height + strokeWidth; - return { x: w, y: h }; - }, - - /* - * Calculate object bounding box dimensions from its properties scale, skew. - * @param {Number} skewX, a value to override current skewX - * @param {Number} skewY, a value to override current skewY - * @private - * @return {Object} .x width dimension - * @return {Object} .y height dimension - */ - _getTransformedDimensions: function(skewX, skewY) { - if (typeof skewX === 'undefined') { - skewX = this.skewX; - } - if (typeof skewY === 'undefined') { - skewY = this.skewY; - } - var dimensions, dimX, dimY, - noSkew = skewX === 0 && skewY === 0; - - if (this.strokeUniform) { - dimX = this.width; - dimY = this.height; - } - else { - dimensions = this._getNonTransformedDimensions(); - dimX = dimensions.x; - dimY = dimensions.y; - } - if (noSkew) { - return this._finalizeDimensions(dimX * this.scaleX, dimY * this.scaleY); - } - var bbox = util.sizeAfterTransform(dimX, dimY, { - scaleX: this.scaleX, - scaleY: this.scaleY, - skewX: skewX, - skewY: skewY, - }); - return this._finalizeDimensions(bbox.x, bbox.y); - }, - - /* - * Calculate object bounding box dimensions from its properties scale, skew. - * @param Number width width of the bbox - * @param Number height height of the bbox - * @private - * @return {Object} .x finalized width dimension - * @return {Object} .y finalized height dimension - */ - _finalizeDimensions: function(width, height) { - return this.strokeUniform ? - { x: width + this.strokeWidth, y: height + this.strokeWidth } - : - { x: width, y: height }; - }, - - /* - * Calculate object dimensions for controls box, including padding and canvas zoom. - * and active selection - * private - */ - _calculateCurrentDimensions: function() { - var vpt = this.getViewportTransform(), - dim = this._getTransformedDimensions(), - p = transformPoint(dim, vpt, true); - return p.scalarAdd(2 * this.padding); - }, - }); -})(); - - -fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - - /** - * Moves an object to the bottom of the stack of drawn objects - * @return {fabric.Object} thisArg - * @chainable - */ - sendToBack: function() { - if (this.group) { - fabric.StaticCanvas.prototype.sendToBack.call(this.group, this); - } - else if (this.canvas) { - this.canvas.sendToBack(this); - } - return this; - }, - - /** - * Moves an object to the top of the stack of drawn objects - * @return {fabric.Object} thisArg - * @chainable - */ - bringToFront: function() { - if (this.group) { - fabric.StaticCanvas.prototype.bringToFront.call(this.group, this); - } - else if (this.canvas) { - this.canvas.bringToFront(this); - } - return this; - }, - - /** - * Moves an object down in stack of drawn objects - * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object - * @return {fabric.Object} thisArg - * @chainable - */ - sendBackwards: function(intersecting) { - if (this.group) { - fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting); - } - else if (this.canvas) { - this.canvas.sendBackwards(this, intersecting); - } - return this; - }, - - /** - * Moves an object up in stack of drawn objects - * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object - * @return {fabric.Object} thisArg - * @chainable - */ - bringForward: function(intersecting) { - if (this.group) { - fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting); - } - else if (this.canvas) { - this.canvas.bringForward(this, intersecting); - } - return this; - }, - - /** - * Moves an object to specified level in stack of drawn objects - * @param {Number} index New position of object - * @return {fabric.Object} thisArg - * @chainable - */ - moveTo: function(index) { - if (this.group && this.group.type !== 'activeSelection') { - fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index); - } - else if (this.canvas) { - this.canvas.moveTo(this, index); - } - return this; - } -}); - - -/* _TO_SVG_START_ */ -(function() { - function getSvgColorString(prop, value) { - if (!value) { - return prop + ': none; '; - } - else if (value.toLive) { - return prop + ': url(#SVGID_' + value.id + '); '; - } - else { - var color = new fabric.Color(value), - str = prop + ': ' + color.toRgb() + '; ', - opacity = color.getAlpha(); - if (opacity !== 1) { - //change the color in rgb + opacity - str += prop + '-opacity: ' + opacity.toString() + '; '; - } - return str; - } - } - - var toFixed = fabric.util.toFixed; - - fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - /** - * Returns styles-string for svg-export - * @param {Boolean} skipShadow a boolean to skip shadow filter output - * @return {String} - */ - getSvgStyles: function(skipShadow) { - - var fillRule = this.fillRule ? this.fillRule : 'nonzero', - strokeWidth = this.strokeWidth ? this.strokeWidth : '0', - strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none', - strokeDashOffset = this.strokeDashOffset ? this.strokeDashOffset : '0', - strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt', - strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter', - strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4', - opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1', - visibility = this.visible ? '' : ' visibility: hidden;', - filter = skipShadow ? '' : this.getSvgFilter(), - fill = getSvgColorString('fill', this.fill), - stroke = getSvgColorString('stroke', this.stroke); - - return [ - stroke, - 'stroke-width: ', strokeWidth, '; ', - 'stroke-dasharray: ', strokeDashArray, '; ', - 'stroke-linecap: ', strokeLineCap, '; ', - 'stroke-dashoffset: ', strokeDashOffset, '; ', - 'stroke-linejoin: ', strokeLineJoin, '; ', - 'stroke-miterlimit: ', strokeMiterLimit, '; ', - fill, - 'fill-rule: ', fillRule, '; ', - 'opacity: ', opacity, ';', - filter, - visibility - ].join(''); - }, - - /** - * Returns styles-string for svg-export - * @param {Object} style the object from which to retrieve style properties - * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style. - * @return {String} - */ - getSvgSpanStyles: function(style, useWhiteSpace) { - var term = '; '; - var fontFamily = style.fontFamily ? - 'font-family: ' + (((style.fontFamily.indexOf('\'') === -1 && style.fontFamily.indexOf('"') === -1) ? - '\'' + style.fontFamily + '\'' : style.fontFamily)) + term : ''; - var strokeWidth = style.strokeWidth ? 'stroke-width: ' + style.strokeWidth + term : '', - fontFamily = fontFamily, - fontSize = style.fontSize ? 'font-size: ' + style.fontSize + 'px' + term : '', - fontStyle = style.fontStyle ? 'font-style: ' + style.fontStyle + term : '', - fontWeight = style.fontWeight ? 'font-weight: ' + style.fontWeight + term : '', - fill = style.fill ? getSvgColorString('fill', style.fill) : '', - stroke = style.stroke ? getSvgColorString('stroke', style.stroke) : '', - textDecoration = this.getSvgTextDecoration(style), - deltaY = style.deltaY ? 'baseline-shift: ' + (-style.deltaY) + '; ' : ''; - if (textDecoration) { - textDecoration = 'text-decoration: ' + textDecoration + term; - } - - return [ - stroke, - strokeWidth, - fontFamily, - fontSize, - fontStyle, - fontWeight, - textDecoration, - fill, - deltaY, - useWhiteSpace ? 'white-space: pre; ' : '' - ].join(''); - }, - - /** - * Returns text-decoration property for svg-export - * @param {Object} style the object from which to retrieve style properties - * @return {String} - */ - getSvgTextDecoration: function(style) { - return ['overline', 'underline', 'line-through'].filter(function(decoration) { - return style[decoration.replace('-', '')]; - }).join(' '); - }, - - /** - * Returns filter for svg shadow - * @return {String} - */ - getSvgFilter: function() { - return this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : ''; - }, - - /** - * Returns id attribute for svg output - * @return {String} - */ - getSvgCommons: function() { - return [ - this.id ? 'id="' + this.id + '" ' : '', - this.clipPath ? 'clip-path="url(#' + this.clipPath.clipPathId + ')" ' : '', - ].join(''); - }, - - /** - * Returns transform-string for svg-export - * @param {Boolean} use the full transform or the single object one. - * @return {String} - */ - getSvgTransform: function(full, additionalTransform) { - var transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(), - svgTransform = 'transform="' + fabric.util.matrixToSVG(transform); - return svgTransform + - (additionalTransform || '') + '" '; - }, - - _setSVGBg: function(textBgRects) { - if (this.backgroundColor) { - var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - textBgRects.push( - '\t\t\n'); - } - }, - - /** - * Returns svg representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toSVG: function(reviver) { - return this._createBaseSVGMarkup(this._toSVG(reviver), { reviver: reviver }); - }, - - /** - * Returns svg clipPath representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toClipPathSVG: function(reviver) { - return '\t' + this._createBaseClipPathSVGMarkup(this._toSVG(reviver), { reviver: reviver }); - }, - - /** - * @private - */ - _createBaseClipPathSVGMarkup: function(objectMarkup, options) { - options = options || {}; - var reviver = options.reviver, - additionalTransform = options.additionalTransform || '', - commonPieces = [ - this.getSvgTransform(true, additionalTransform), - this.getSvgCommons(), - ].join(''), - // insert commons in the markup, style and svgCommons - index = objectMarkup.indexOf('COMMON_PARTS'); - objectMarkup[index] = commonPieces; - return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join(''); - }, - - /** - * @private - */ - _createBaseSVGMarkup: function(objectMarkup, options) { - options = options || {}; - var noStyle = options.noStyle, - reviver = options.reviver, - styleInfo = noStyle ? '' : 'style="' + this.getSvgStyles() + '" ', - shadowInfo = options.withShadow ? 'style="' + this.getSvgFilter() + '" ' : '', - clipPath = this.clipPath, - vectorEffect = this.strokeUniform ? 'vector-effect="non-scaling-stroke" ' : '', - absoluteClipPath = clipPath && clipPath.absolutePositioned, - stroke = this.stroke, fill = this.fill, shadow = this.shadow, - commonPieces, markup = [], clipPathMarkup, - // insert commons in the markup, style and svgCommons - index = objectMarkup.indexOf('COMMON_PARTS'), - additionalTransform = options.additionalTransform; - if (clipPath) { - clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++; - clipPathMarkup = '\n' + - clipPath.toClipPathSVG(reviver) + - '\n'; - } - if (absoluteClipPath) { - markup.push( - '\n' - ); - } - markup.push( - '\n' - ); - commonPieces = [ - styleInfo, - vectorEffect, - noStyle ? '' : this.addPaintOrder(), ' ', - additionalTransform ? 'transform="' + additionalTransform + '" ' : '', - ].join(''); - objectMarkup[index] = commonPieces; - if (fill && fill.toLive) { - markup.push(fill.toSVG(this)); - } - if (stroke && stroke.toLive) { - markup.push(stroke.toSVG(this)); - } - if (shadow) { - markup.push(shadow.toSVG(this)); - } - if (clipPath) { - markup.push(clipPathMarkup); - } - markup.push(objectMarkup.join('')); - markup.push('\n'); - absoluteClipPath && markup.push('\n'); - return reviver ? reviver(markup.join('')) : markup.join(''); - }, - - addPaintOrder: function() { - return this.paintFirst !== 'fill' ? ' paint-order="' + this.paintFirst + '" ' : ''; - } - }); -})(); -/* _TO_SVG_END_ */ - - -(function() { - - var extend = fabric.util.object.extend, - originalSet = 'stateProperties'; - - /* - Depends on `stateProperties` - */ - function saveProps(origin, destination, props) { - var tmpObj = { }, deep = true; - props.forEach(function(prop) { - tmpObj[prop] = origin[prop]; - }); - - extend(origin[destination], tmpObj, deep); - } - - function _isEqual(origValue, currentValue, firstPass) { - if (origValue === currentValue) { - // if the objects are identical, return - return true; - } - else if (Array.isArray(origValue)) { - if (!Array.isArray(currentValue) || origValue.length !== currentValue.length) { - return false; - } - for (var i = 0, len = origValue.length; i < len; i++) { - if (!_isEqual(origValue[i], currentValue[i])) { - return false; - } - } - return true; - } - else if (origValue && typeof origValue === 'object') { - var keys = Object.keys(origValue), key; - if (!currentValue || - typeof currentValue !== 'object' || - (!firstPass && keys.length !== Object.keys(currentValue).length) - ) { - return false; - } - for (var i = 0, len = keys.length; i < len; i++) { - key = keys[i]; - // since clipPath is in the statefull cache list and the clipPath objects - // would be iterated as an object, this would lead to possible infinite recursion - // we do not want to compare those. - if (key === 'canvas' || key === 'group') { - continue; - } - if (!_isEqual(origValue[key], currentValue[key])) { - return false; - } - } - return true; - } - } - - - fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - - /** - * Returns true if object state (one of its state properties) was changed - * @param {String} [propertySet] optional name for the set of property we want to save - * @return {Boolean} true if instance' state has changed since `{@link fabric.Object#saveState}` was called - */ - hasStateChanged: function(propertySet) { - propertySet = propertySet || originalSet; - var dashedPropertySet = '_' + propertySet; - if (Object.keys(this[dashedPropertySet]).length < this[propertySet].length) { - return true; - } - return !_isEqual(this[dashedPropertySet], this, true); - }, - - /** - * Saves state of an object - * @param {Object} [options] Object with additional `stateProperties` array to include when saving state - * @return {fabric.Object} thisArg - */ - saveState: function(options) { - var propertySet = options && options.propertySet || originalSet, - destination = '_' + propertySet; - if (!this[destination]) { - return this.setupState(options); - } - saveProps(this, destination, this[propertySet]); - if (options && options.stateProperties) { - saveProps(this, destination, options.stateProperties); - } - return this; - }, - - /** - * Setups state of an object - * @param {Object} [options] Object with additional `stateProperties` array to include when saving state - * @return {fabric.Object} thisArg - */ - setupState: function(options) { - options = options || { }; - var propertySet = options.propertySet || originalSet; - options.propertySet = propertySet; - this['_' + propertySet] = { }; - this.saveState(options); - return this; - } - }); -})(); - - -(function() { - - var degreesToRadians = fabric.util.degreesToRadians; - - fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - /** - * Determines which corner has been clicked - * @private - * @param {Object} pointer The pointer indicating the mouse position - * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or false if nothing is found - */ - _findTargetCorner: function(pointer, forTouch) { - // objects in group, anykind, are not self modificable, - // must not return an hovered corner. - if (!this.hasControls || this.group || (!this.canvas || this.canvas._activeObject !== this)) { - return false; - } - - var ex = pointer.x, - ey = pointer.y, - xPoints, - lines, keys = Object.keys(this.oCoords), - j = keys.length - 1, i; - this.__corner = 0; - - // cycle in reverse order so we pick first the one on top - for (; j >= 0; j--) { - i = keys[j]; - if (!this.isControlVisible(i)) { - continue; - } - - lines = this._getImageLines(forTouch ? this.oCoords[i].touchCorner : this.oCoords[i].corner); - // // debugging - // - // this.canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2); - - xPoints = this._findCrossPoints({ x: ex, y: ey }, lines); - if (xPoints !== 0 && xPoints % 2 === 1) { - this.__corner = i; - return i; - } - } - return false; - }, - - /** - * Calls a function for each control. The function gets called, - * with the control, the object that is calling the iterator and the control's key - * @param {Function} fn function to iterate over the controls over - */ - forEachControl: function(fn) { - for (var i in this.controls) { - fn(this.controls[i], i, this); - }; - }, - - /** - * Sets the coordinates of the draggable boxes in the corners of - * the image used to scale/rotate it. - * note: if we would switch to ROUND corner area, all of this would disappear. - * everything would resolve to a single point and a pythagorean theorem for the distance - * @private - */ - _setCornerCoords: function() { - var coords = this.oCoords; - - for (var control in coords) { - var controlObject = this.controls[control]; - coords[control].corner = controlObject.calcCornerCoords( - this.angle, this.cornerSize, coords[control].x, coords[control].y, false); - coords[control].touchCorner = controlObject.calcCornerCoords( - this.angle, this.touchCornerSize, coords[control].x, coords[control].y, true); - } - }, - - /** - * Draws a colored layer behind the object, inside its selection borders. - * Requires public options: padding, selectionBackgroundColor - * this function is called when the context is transformed - * has checks to be skipped when the object is on a staticCanvas - * @param {CanvasRenderingContext2D} ctx Context to draw on - * @return {fabric.Object} thisArg - * @chainable - */ - drawSelectionBackground: function(ctx) { - if (!this.selectionBackgroundColor || - (this.canvas && !this.canvas.interactive) || - (this.canvas && this.canvas._activeObject !== this) - ) { - return this; - } - ctx.save(); - var center = this.getCenterPoint(), wh = this._calculateCurrentDimensions(), - vpt = this.canvas.viewportTransform; - ctx.translate(center.x, center.y); - ctx.scale(1 / vpt[0], 1 / vpt[3]); - ctx.rotate(degreesToRadians(this.angle)); - ctx.fillStyle = this.selectionBackgroundColor; - ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y); - ctx.restore(); - return this; - }, - - /** - * Draws borders of an object's bounding box. - * Requires public properties: width, height - * Requires public options: padding, borderColor - * @param {CanvasRenderingContext2D} ctx Context to draw on - * @param {Object} styleOverride object to override the object style - * @return {fabric.Object} thisArg - * @chainable - */ - drawBorders: function(ctx, styleOverride) { - styleOverride = styleOverride || {}; - var wh = this._calculateCurrentDimensions(), - strokeWidth = this.borderScaleFactor, - width = wh.x + strokeWidth, - height = wh.y + strokeWidth, - hasControls = typeof styleOverride.hasControls !== 'undefined' ? - styleOverride.hasControls : this.hasControls, - shouldStroke = false; - - ctx.save(); - ctx.strokeStyle = styleOverride.borderColor || this.borderColor; - this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray); - - ctx.strokeRect( - -width / 2, - -height / 2, - width, - height - ); - - if (hasControls) { - ctx.beginPath(); - this.forEachControl(function(control, key, fabricObject) { - // in this moment, the ctx is centered on the object. - // width and height of the above function are the size of the bbox. - if (control.withConnection && control.getVisibility(fabricObject, key)) { - // reset movement for each control - shouldStroke = true; - ctx.moveTo(control.x * width, control.y * height); - ctx.lineTo( - control.x * width + control.offsetX, - control.y * height + control.offsetY - ); - } - }); - if (shouldStroke) { - ctx.stroke(); - } - } - ctx.restore(); - return this; - }, - - /** - * Draws borders of an object's bounding box when it is inside a group. - * Requires public properties: width, height - * Requires public options: padding, borderColor - * @param {CanvasRenderingContext2D} ctx Context to draw on - * @param {object} options object representing current object parameters - * @param {Object} styleOverride object to override the object style - * @return {fabric.Object} thisArg - * @chainable - */ - drawBordersInGroup: function(ctx, options, styleOverride) { - styleOverride = styleOverride || {}; - var bbox = fabric.util.sizeAfterTransform(this.width, this.height, options), - strokeWidth = this.strokeWidth, - strokeUniform = this.strokeUniform, - borderScaleFactor = this.borderScaleFactor, - width = - bbox.x + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleX) + borderScaleFactor, - height = - bbox.y + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleY) + borderScaleFactor; - ctx.save(); - this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray); - ctx.strokeStyle = styleOverride.borderColor || this.borderColor; - ctx.strokeRect( - -width / 2, - -height / 2, - width, - height - ); - - ctx.restore(); - return this; - }, - - /** - * Draws corners of an object's bounding box. - * Requires public properties: width, height - * Requires public options: cornerSize, padding - * @param {CanvasRenderingContext2D} ctx Context to draw on - * @param {Object} styleOverride object to override the object style - * @return {fabric.Object} thisArg - * @chainable - */ - drawControls: function(ctx, styleOverride) { - styleOverride = styleOverride || {}; - ctx.save(); - var retinaScaling = this.canvas.getRetinaScaling(), matrix, p; - ctx.setTransform(retinaScaling, 0, 0, retinaScaling, 0, 0); - ctx.strokeStyle = ctx.fillStyle = styleOverride.cornerColor || this.cornerColor; - if (!this.transparentCorners) { - ctx.strokeStyle = styleOverride.cornerStrokeColor || this.cornerStrokeColor; - } - this._setLineDash(ctx, styleOverride.cornerDashArray || this.cornerDashArray); - this.setCoords(); - if (this.group) { - // fabricJS does not really support drawing controls inside groups, - // this piece of code here helps having at least the control in places. - // If an application needs to show some objects as selected because of some UI state - // can still call Object._renderControls() on any object they desire, independently of groups. - // using no padding, circular controls and hiding the rotating cursor is higly suggested, - matrix = this.group.calcTransformMatrix(); - } - this.forEachControl(function(control, key, fabricObject) { - p = fabricObject.oCoords[key]; - if (control.getVisibility(fabricObject, key)) { - if (matrix) { - p = fabric.util.transformPoint(p, matrix); - } - control.render(ctx, p.x, p.y, styleOverride, fabricObject); - } - }); - ctx.restore(); - - return this; - }, - - /** - * Returns true if the specified control is visible, false otherwise. - * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'. - * @returns {Boolean} true if the specified control is visible, false otherwise - */ - isControlVisible: function(controlKey) { - return this.controls[controlKey] && this.controls[controlKey].getVisibility(this, controlKey); - }, - - /** - * Sets the visibility of the specified control. - * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'. - * @param {Boolean} visible true to set the specified control visible, false otherwise - * @return {fabric.Object} thisArg - * @chainable - */ - setControlVisible: function(controlKey, visible) { - if (!this._controlsVisibility) { - this._controlsVisibility = {}; - } - this._controlsVisibility[controlKey] = visible; - return this; - }, - - /** - * Sets the visibility state of object controls. - * @param {Object} [options] Options object - * @param {Boolean} [options.bl] true to enable the bottom-left control, false to disable it - * @param {Boolean} [options.br] true to enable the bottom-right control, false to disable it - * @param {Boolean} [options.mb] true to enable the middle-bottom control, false to disable it - * @param {Boolean} [options.ml] true to enable the middle-left control, false to disable it - * @param {Boolean} [options.mr] true to enable the middle-right control, false to disable it - * @param {Boolean} [options.mt] true to enable the middle-top control, false to disable it - * @param {Boolean} [options.tl] true to enable the top-left control, false to disable it - * @param {Boolean} [options.tr] true to enable the top-right control, false to disable it - * @param {Boolean} [options.mtr] true to enable the middle-top-rotate control, false to disable it - * @return {fabric.Object} thisArg - * @chainable - */ - setControlsVisibility: function(options) { - options || (options = { }); - - for (var p in options) { - this.setControlVisible(p, options[p]); - } - return this; - }, - - - /** - * This callback function is called every time _discardActiveObject or _setActiveObject - * try to to deselect this object. If the function returns true, the process is cancelled - * @param {Object} [options] options sent from the upper functions - * @param {Event} [options.e] event if the process is generated by an event - */ - onDeselect: function() { - // implemented by sub-classes, as needed. - }, - - - /** - * This callback function is called every time _discardActiveObject or _setActiveObject - * try to to select this object. If the function returns true, the process is cancelled - * @param {Object} [options] options sent from the upper functions - * @param {Event} [options.e] event if the process is generated by an event - */ - onSelect: function() { - // implemented by sub-classes, as needed. - } - }); -})(); - - -fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { - - /** - * Animation duration (in ms) for fx* methods - * @type Number - * @default - */ - FX_DURATION: 500, - - /** - * Centers object horizontally with animation. - * @param {fabric.Object} object Object to center - * @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties - * @param {Function} [callbacks.onComplete] Invoked on completion - * @param {Function} [callbacks.onChange] Invoked on every step of animation - * @return {fabric.Canvas} thisArg - * @chainable - */ - fxCenterObjectH: function (object, callbacks) { - callbacks = callbacks || { }; - - var empty = function() { }, - onComplete = callbacks.onComplete || empty, - onChange = callbacks.onChange || empty, - _this = this; - - fabric.util.animate({ - startValue: object.left, - endValue: this.getCenter().left, - duration: this.FX_DURATION, - onChange: function(value) { - object.set('left', value); - _this.requestRenderAll(); - onChange(); - }, - onComplete: function() { - object.setCoords(); - onComplete(); - } - }); - - return this; - }, - - /** - * Centers object vertically with animation. - * @param {fabric.Object} object Object to center - * @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties - * @param {Function} [callbacks.onComplete] Invoked on completion - * @param {Function} [callbacks.onChange] Invoked on every step of animation - * @return {fabric.Canvas} thisArg - * @chainable - */ - fxCenterObjectV: function (object, callbacks) { - callbacks = callbacks || { }; - - var empty = function() { }, - onComplete = callbacks.onComplete || empty, - onChange = callbacks.onChange || empty, - _this = this; - - fabric.util.animate({ - startValue: object.top, - endValue: this.getCenter().top, - duration: this.FX_DURATION, - onChange: function(value) { - object.set('top', value); - _this.requestRenderAll(); - onChange(); - }, - onComplete: function() { - object.setCoords(); - onComplete(); - } - }); - - return this; - }, - - /** - * Same as `fabric.Canvas#remove` but animated - * @param {fabric.Object} object Object to remove - * @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties - * @param {Function} [callbacks.onComplete] Invoked on completion - * @param {Function} [callbacks.onChange] Invoked on every step of animation - * @return {fabric.Canvas} thisArg - * @chainable - */ - fxRemove: function (object, callbacks) { - callbacks = callbacks || { }; - - var empty = function() { }, - onComplete = callbacks.onComplete || empty, - onChange = callbacks.onChange || empty, - _this = this; - - fabric.util.animate({ - startValue: object.opacity, - endValue: 0, - duration: this.FX_DURATION, - onChange: function(value) { - object.set('opacity', value); - _this.requestRenderAll(); - onChange(); - }, - onComplete: function () { - _this.remove(object); - onComplete(); - } - }); - - return this; - } -}); - -fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - /** - * Animates object's properties - * @param {String|Object} property Property to animate (if string) or properties to animate (if object) - * @param {Number|Object} value Value to animate property to (if string was given first) or options object - * @return {fabric.Object} thisArg - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation} - * @chainable - * - * As object — multiple properties - * - * object.animate({ left: ..., top: ... }); - * object.animate({ left: ..., top: ... }, { duration: ... }); - * - * As string — one property - * - * object.animate('left', ...); - * object.animate('left', { duration: ... }); - * - */ - animate: function() { - if (arguments[0] && typeof arguments[0] === 'object') { - var propsToAnimate = [], prop, skipCallbacks; - for (prop in arguments[0]) { - propsToAnimate.push(prop); - } - for (var i = 0, len = propsToAnimate.length; i < len; i++) { - prop = propsToAnimate[i]; - skipCallbacks = i !== len - 1; - this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks); - } - } - else { - this._animate.apply(this, arguments); - } - return this; - }, - - /** - * @private - * @param {String} property Property to animate - * @param {String} to Value to animate to - * @param {Object} [options] Options object - * @param {Boolean} [skipCallbacks] When true, callbacks like onchange and oncomplete are not invoked - */ - _animate: function(property, to, options, skipCallbacks) { - var _this = this, propPair; - - to = to.toString(); - - if (!options) { - options = { }; - } - else { - options = fabric.util.object.clone(options); - } - - if (~property.indexOf('.')) { - propPair = property.split('.'); - } - - var propIsColor = - _this.colorProperties.indexOf(property) > -1 || - (propPair && _this.colorProperties.indexOf(propPair[1]) > -1); - - var currentValue = propPair - ? this.get(propPair[0])[propPair[1]] - : this.get(property); - - if (!('from' in options)) { - options.from = currentValue; - } - - if (!propIsColor) { - if (~to.indexOf('=')) { - to = currentValue + parseFloat(to.replace('=', '')); - } - else { - to = parseFloat(to); - } - } - - var _options = { - startValue: options.from, - endValue: to, - byValue: options.by, - easing: options.easing, - duration: options.duration, - abort: options.abort && function(value, valueProgress, timeProgress) { - return options.abort.call(_this, value, valueProgress, timeProgress); - }, - onChange: function (value, valueProgress, timeProgress) { - if (propPair) { - _this[propPair[0]][propPair[1]] = value; - } - else { - _this.set(property, value); - } - if (skipCallbacks) { - return; - } - options.onChange && options.onChange(value, valueProgress, timeProgress); - }, - onComplete: function (value, valueProgress, timeProgress) { - if (skipCallbacks) { - return; - } - - _this.setCoords(); - options.onComplete && options.onComplete(value, valueProgress, timeProgress); - } - }; - - if (propIsColor) { - return fabric.util.animateColor(_options.startValue, _options.endValue, _options.duration, _options); - } - else { - return fabric.util.animate(_options); - } - } -}); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - clone = fabric.util.object.clone, - coordProps = { x1: 1, x2: 1, y1: 1, y2: 1 }; - - if (fabric.Line) { - fabric.warn('fabric.Line is already defined'); - return; - } - - /** - * Line class - * @class fabric.Line - * @extends fabric.Object - * @see {@link fabric.Line#initialize} for constructor definition - */ - fabric.Line = fabric.util.createClass(fabric.Object, /** @lends fabric.Line.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'line', - - /** - * x value or first line edge - * @type Number - * @default - */ - x1: 0, - - /** - * y value or first line edge - * @type Number - * @default - */ - y1: 0, - - /** - * x value or second line edge - * @type Number - * @default - */ - x2: 0, - - /** - * y value or second line edge - * @type Number - * @default - */ - y2: 0, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('x1', 'x2', 'y1', 'y2'), - - /** - * Constructor - * @param {Array} [points] Array of points - * @param {Object} [options] Options object - * @return {fabric.Line} thisArg - */ - initialize: function(points, options) { - if (!points) { - points = [0, 0, 0, 0]; - } - - this.callSuper('initialize', options); - - this.set('x1', points[0]); - this.set('y1', points[1]); - this.set('x2', points[2]); - this.set('y2', points[3]); - - this._setWidthHeight(options); - }, - - /** - * @private - * @param {Object} [options] Options - */ - _setWidthHeight: function(options) { - options || (options = { }); - - this.width = Math.abs(this.x2 - this.x1); - this.height = Math.abs(this.y2 - this.y1); - - this.left = 'left' in options - ? options.left - : this._getLeftToOriginX(); - - this.top = 'top' in options - ? options.top - : this._getTopToOriginY(); - }, - - /** - * @private - * @param {String} key - * @param {*} value - */ - _set: function(key, value) { - this.callSuper('_set', key, value); - if (typeof coordProps[key] !== 'undefined') { - this._setWidthHeight(); - } - return this; - }, - - /** - * @private - * @return {Number} leftToOriginX Distance from left edge of canvas to originX of Line. - */ - _getLeftToOriginX: makeEdgeToOriginGetter( - { // property names - origin: 'originX', - axis1: 'x1', - axis2: 'x2', - dimension: 'width' - }, - { // possible values of origin - nearest: 'left', - center: 'center', - farthest: 'right' - } - ), - - /** - * @private - * @return {Number} topToOriginY Distance from top edge of canvas to originY of Line. - */ - _getTopToOriginY: makeEdgeToOriginGetter( - { // property names - origin: 'originY', - axis1: 'y1', - axis2: 'y2', - dimension: 'height' - }, - { // possible values of origin - nearest: 'top', - center: 'center', - farthest: 'bottom' - } - ), - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - ctx.beginPath(); - - - var p = this.calcLinePoints(); - ctx.moveTo(p.x1, p.y1); - ctx.lineTo(p.x2, p.y2); - - ctx.lineWidth = this.strokeWidth; - - // TODO: test this - // make sure setting "fill" changes color of a line - // (by copying fillStyle to strokeStyle, since line is stroked, not filled) - var origStrokeStyle = ctx.strokeStyle; - ctx.strokeStyle = this.stroke || ctx.fillStyle; - this.stroke && this._renderStroke(ctx); - ctx.strokeStyle = origStrokeStyle; - }, - - /** - * This function is an helper for svg import. it returns the center of the object in the svg - * untransformed coordinates - * @private - * @return {Object} center point from element coordinates - */ - _findCenterFromElement: function() { - return { - x: (this.x1 + this.x2) / 2, - y: (this.y1 + this.y2) / 2, - }; - }, - - /** - * Returns object representation of an instance - * @method toObject - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return extend(this.callSuper('toObject', propertiesToInclude), this.calcLinePoints()); - }, - - /* - * Calculate object dimensions from its properties - * @private - */ - _getNonTransformedDimensions: function() { - var dim = this.callSuper('_getNonTransformedDimensions'); - if (this.strokeLineCap === 'butt') { - if (this.width === 0) { - dim.y -= this.strokeWidth; - } - if (this.height === 0) { - dim.x -= this.strokeWidth; - } - } - return dim; - }, - - /** - * Recalculates line points given width and height - * @private - */ - calcLinePoints: function() { - var xMult = this.x1 <= this.x2 ? -1 : 1, - yMult = this.y1 <= this.y2 ? -1 : 1, - x1 = (xMult * this.width * 0.5), - y1 = (yMult * this.height * 0.5), - x2 = (xMult * this.width * -0.5), - y2 = (yMult * this.height * -0.5); - - return { - x1: x1, - x2: x2, - y1: y1, - y2: y2 - }; - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var p = this.calcLinePoints(); - return [ - '\n' - ]; - }, - /* _TO_SVG_END_ */ - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Line.fromElement}) - * @static - * @memberOf fabric.Line - * @see http://www.w3.org/TR/SVG/shapes.html#LineElement - */ - fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x1 y1 x2 y2'.split(' ')); - - /** - * Returns fabric.Line instance from an SVG element - * @static - * @memberOf fabric.Line - * @param {SVGElement} element Element to parse - * @param {Object} [options] Options object - * @param {Function} [callback] callback function invoked after parsing - */ - fabric.Line.fromElement = function(element, callback, options) { - options = options || { }; - var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES), - points = [ - parsedAttributes.x1 || 0, - parsedAttributes.y1 || 0, - parsedAttributes.x2 || 0, - parsedAttributes.y2 || 0 - ]; - callback(new fabric.Line(points, extend(parsedAttributes, options))); - }; - /* _FROM_SVG_END_ */ - - /** - * Returns fabric.Line instance from an object representation - * @static - * @memberOf fabric.Line - * @param {Object} object Object to create an instance from - * @param {function} [callback] invoked with new instance as first argument - */ - fabric.Line.fromObject = function(object, callback) { - function _callback(instance) { - delete instance.points; - callback && callback(instance); - }; - var options = clone(object, true); - options.points = [object.x1, object.y1, object.x2, object.y2]; - fabric.Object._fromObject('Line', options, _callback, 'points'); - }; - - /** - * Produces a function that calculates distance from canvas edge to Line origin. - */ - function makeEdgeToOriginGetter(propertyNames, originValues) { - var origin = propertyNames.origin, - axis1 = propertyNames.axis1, - axis2 = propertyNames.axis2, - dimension = propertyNames.dimension, - nearest = originValues.nearest, - center = originValues.center, - farthest = originValues.farthest; - - return function() { - switch (this.get(origin)) { - case nearest: - return Math.min(this.get(axis1), this.get(axis2)); - case center: - return Math.min(this.get(axis1), this.get(axis2)) + (0.5 * this.get(dimension)); - case farthest: - return Math.max(this.get(axis1), this.get(axis2)); - } - }; - - } - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - pi = Math.PI; - - if (fabric.Circle) { - fabric.warn('fabric.Circle is already defined.'); - return; - } - - /** - * Circle class - * @class fabric.Circle - * @extends fabric.Object - * @see {@link fabric.Circle#initialize} for constructor definition - */ - fabric.Circle = fabric.util.createClass(fabric.Object, /** @lends fabric.Circle.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'circle', - - /** - * Radius of this circle - * @type Number - * @default - */ - radius: 0, - - /** - * Start angle of the circle, moving clockwise - * deprecated type, this should be in degree, this was an oversight. - * probably will change to degrees in next major version - * @type Number - * @default 0 - */ - startAngle: 0, - - /** - * End angle of the circle - * deprecated type, this should be in degree, this was an oversight. - * probably will change to degrees in next major version - * @type Number - * @default 2Pi - */ - endAngle: pi * 2, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('radius', 'startAngle', 'endAngle'), - - /** - * @private - * @param {String} key - * @param {*} value - * @return {fabric.Circle} thisArg - */ - _set: function(key, value) { - this.callSuper('_set', key, value); - - if (key === 'radius') { - this.setRadius(value); - } - - return this; - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return this.callSuper('toObject', ['radius', 'startAngle', 'endAngle'].concat(propertiesToInclude)); - }, - - /* _TO_SVG_START_ */ - - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var svgString, x = 0, y = 0, - angle = (this.endAngle - this.startAngle) % ( 2 * pi); - - if (angle === 0) { - svgString = [ - '\n' - ]; - } - else { - var startX = fabric.util.cos(this.startAngle) * this.radius, - startY = fabric.util.sin(this.startAngle) * this.radius, - endX = fabric.util.cos(this.endAngle) * this.radius, - endY = fabric.util.sin(this.endAngle) * this.radius, - largeFlag = angle > pi ? '1' : '0'; - svgString = [ - '\n' - ]; - } - return svgString; - }, - /* _TO_SVG_END_ */ - - /** - * @private - * @param {CanvasRenderingContext2D} ctx context to render on - */ - _render: function(ctx) { - ctx.beginPath(); - ctx.arc( - 0, - 0, - this.radius, - this.startAngle, - this.endAngle, false); - this._renderPaintInOrder(ctx); - }, - - /** - * Returns horizontal radius of an object (according to how an object is scaled) - * @return {Number} - */ - getRadiusX: function() { - return this.get('radius') * this.get('scaleX'); - }, - - /** - * Returns vertical radius of an object (according to how an object is scaled) - * @return {Number} - */ - getRadiusY: function() { - return this.get('radius') * this.get('scaleY'); - }, - - /** - * Sets radius of an object (and updates width accordingly) - * @return {fabric.Circle} thisArg - */ - setRadius: function(value) { - this.radius = value; - return this.set('width', value * 2).set('height', value * 2); - }, - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement}) - * @static - * @memberOf fabric.Circle - * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement - */ - fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy r'.split(' ')); - - /** - * Returns {@link fabric.Circle} instance from an SVG element - * @static - * @memberOf fabric.Circle - * @param {SVGElement} element Element to parse - * @param {Function} [callback] Options callback invoked after parsing is finished - * @param {Object} [options] Options object - * @throws {Error} If value of `r` attribute is missing or invalid - */ - fabric.Circle.fromElement = function(element, callback) { - var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES); - - if (!isValidRadius(parsedAttributes)) { - throw new Error('value of `r` attribute is required and can not be negative'); - } - - parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.radius; - parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.radius; - callback(new fabric.Circle(parsedAttributes)); - }; - - /** - * @private - */ - function isValidRadius(attributes) { - return (('radius' in attributes) && (attributes.radius >= 0)); - } - /* _FROM_SVG_END_ */ - - /** - * Returns {@link fabric.Circle} instance from an object representation - * @static - * @memberOf fabric.Circle - * @param {Object} object Object to create an instance from - * @param {function} [callback] invoked with new instance as first argument - * @return {void} - */ - fabric.Circle.fromObject = function(object, callback) { - fabric.Object._fromObject('Circle', object, callback); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }); - - if (fabric.Triangle) { - fabric.warn('fabric.Triangle is already defined'); - return; - } - - /** - * Triangle class - * @class fabric.Triangle - * @extends fabric.Object - * @return {fabric.Triangle} thisArg - * @see {@link fabric.Triangle#initialize} for constructor definition - */ - fabric.Triangle = fabric.util.createClass(fabric.Object, /** @lends fabric.Triangle.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'triangle', - - /** - * Width is set to 100 to compensate the old initialize code that was setting it to 100 - * @type Number - * @default - */ - width: 100, - - /** - * Height is set to 100 to compensate the old initialize code that was setting it to 100 - * @type Number - * @default - */ - height: 100, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - var widthBy2 = this.width / 2, - heightBy2 = this.height / 2; - - ctx.beginPath(); - ctx.moveTo(-widthBy2, heightBy2); - ctx.lineTo(0, -heightBy2); - ctx.lineTo(widthBy2, heightBy2); - ctx.closePath(); - - this._renderPaintInOrder(ctx); - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var widthBy2 = this.width / 2, - heightBy2 = this.height / 2, - points = [ - -widthBy2 + ' ' + heightBy2, - '0 ' + -heightBy2, - widthBy2 + ' ' + heightBy2 - ].join(','); - return [ - '' - ]; - }, - /* _TO_SVG_END_ */ - }); - - /** - * Returns {@link fabric.Triangle} instance from an object representation - * @static - * @memberOf fabric.Triangle - * @param {Object} object Object to create an instance from - * @param {function} [callback] invoked with new instance as first argument - */ - fabric.Triangle.fromObject = function(object, callback) { - return fabric.Object._fromObject('Triangle', object, callback); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - piBy2 = Math.PI * 2; - - if (fabric.Ellipse) { - fabric.warn('fabric.Ellipse is already defined.'); - return; - } - - /** - * Ellipse class - * @class fabric.Ellipse - * @extends fabric.Object - * @return {fabric.Ellipse} thisArg - * @see {@link fabric.Ellipse#initialize} for constructor definition - */ - fabric.Ellipse = fabric.util.createClass(fabric.Object, /** @lends fabric.Ellipse.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'ellipse', - - /** - * Horizontal radius - * @type Number - * @default - */ - rx: 0, - - /** - * Vertical radius - * @type Number - * @default - */ - ry: 0, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'), - - /** - * Constructor - * @param {Object} [options] Options object - * @return {fabric.Ellipse} thisArg - */ - initialize: function(options) { - this.callSuper('initialize', options); - this.set('rx', options && options.rx || 0); - this.set('ry', options && options.ry || 0); - }, - - /** - * @private - * @param {String} key - * @param {*} value - * @return {fabric.Ellipse} thisArg - */ - _set: function(key, value) { - this.callSuper('_set', key, value); - switch (key) { - - case 'rx': - this.rx = value; - this.set('width', value * 2); - break; - - case 'ry': - this.ry = value; - this.set('height', value * 2); - break; - - } - return this; - }, - - /** - * Returns horizontal radius of an object (according to how an object is scaled) - * @return {Number} - */ - getRx: function() { - return this.get('rx') * this.get('scaleX'); - }, - - /** - * Returns Vertical radius of an object (according to how an object is scaled) - * @return {Number} - */ - getRy: function() { - return this.get('ry') * this.get('scaleY'); - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude)); - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - return [ - '\n' - ]; - }, - /* _TO_SVG_END_ */ - - /** - * @private - * @param {CanvasRenderingContext2D} ctx context to render on - */ - _render: function(ctx) { - ctx.beginPath(); - ctx.save(); - ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0); - ctx.arc( - 0, - 0, - this.rx, - 0, - piBy2, - false); - ctx.restore(); - this._renderPaintInOrder(ctx); - }, - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Ellipse.fromElement}) - * @static - * @memberOf fabric.Ellipse - * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement - */ - fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy rx ry'.split(' ')); - - /** - * Returns {@link fabric.Ellipse} instance from an SVG element - * @static - * @memberOf fabric.Ellipse - * @param {SVGElement} element Element to parse - * @param {Function} [callback] Options callback invoked after parsing is finished - * @return {fabric.Ellipse} - */ - fabric.Ellipse.fromElement = function(element, callback) { - - var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES); - - parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx; - parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry; - callback(new fabric.Ellipse(parsedAttributes)); - }; - /* _FROM_SVG_END_ */ - - /** - * Returns {@link fabric.Ellipse} instance from an object representation - * @static - * @memberOf fabric.Ellipse - * @param {Object} object Object to create an instance from - * @param {function} [callback] invoked with new instance as first argument - * @return {void} - */ - fabric.Ellipse.fromObject = function(object, callback) { - fabric.Object._fromObject('Ellipse', object, callback); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend; - - if (fabric.Rect) { - fabric.warn('fabric.Rect is already defined'); - return; - } - - /** - * Rectangle class - * @class fabric.Rect - * @extends fabric.Object - * @return {fabric.Rect} thisArg - * @see {@link fabric.Rect#initialize} for constructor definition - */ - fabric.Rect = fabric.util.createClass(fabric.Object, /** @lends fabric.Rect.prototype */ { - - /** - * List of properties to consider when checking if state of an object is changed ({@link fabric.Object#hasStateChanged}) - * as well as for history (undo/redo) purposes - * @type Array - */ - stateProperties: fabric.Object.prototype.stateProperties.concat('rx', 'ry'), - - /** - * Type of an object - * @type String - * @default - */ - type: 'rect', - - /** - * Horizontal border radius - * @type Number - * @default - */ - rx: 0, - - /** - * Vertical border radius - * @type Number - * @default - */ - ry: 0, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'), - - /** - * Constructor - * @param {Object} [options] Options object - * @return {Object} thisArg - */ - initialize: function(options) { - this.callSuper('initialize', options); - this._initRxRy(); - }, - - /** - * Initializes rx/ry attributes - * @private - */ - _initRxRy: function() { - if (this.rx && !this.ry) { - this.ry = this.rx; - } - else if (this.ry && !this.rx) { - this.rx = this.ry; - } - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - - // 1x1 case (used in spray brush) optimization was removed because - // with caching and higher zoom level this makes more damage than help - - var rx = this.rx ? Math.min(this.rx, this.width / 2) : 0, - ry = this.ry ? Math.min(this.ry, this.height / 2) : 0, - w = this.width, - h = this.height, - x = -this.width / 2, - y = -this.height / 2, - isRounded = rx !== 0 || ry !== 0, - /* "magic number" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */ - k = 1 - 0.5522847498; - ctx.beginPath(); - - ctx.moveTo(x + rx, y); - - ctx.lineTo(x + w - rx, y); - isRounded && ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry); - - ctx.lineTo(x + w, y + h - ry); - isRounded && ctx.bezierCurveTo(x + w, y + h - k * ry, x + w - k * rx, y + h, x + w - rx, y + h); - - ctx.lineTo(x + rx, y + h); - isRounded && ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry); - - ctx.lineTo(x, y + ry); - isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y); - - ctx.closePath(); - - this._renderPaintInOrder(ctx); - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude)); - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var x = -this.width / 2, y = -this.height / 2; - return [ - '\n' - ]; - }, - /* _TO_SVG_END_ */ - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by `fabric.Rect.fromElement`) - * @static - * @memberOf fabric.Rect - * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement - */ - fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y rx ry width height'.split(' ')); - - /** - * Returns {@link fabric.Rect} instance from an SVG element - * @static - * @memberOf fabric.Rect - * @param {SVGElement} element Element to parse - * @param {Function} callback callback function invoked after parsing - * @param {Object} [options] Options object - */ - fabric.Rect.fromElement = function(element, callback, options) { - if (!element) { - return callback(null); - } - options = options || { }; - - var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES); - parsedAttributes.left = parsedAttributes.left || 0; - parsedAttributes.top = parsedAttributes.top || 0; - parsedAttributes.height = parsedAttributes.height || 0; - parsedAttributes.width = parsedAttributes.width || 0; - var rect = new fabric.Rect(extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes)); - rect.visible = rect.visible && rect.width > 0 && rect.height > 0; - callback(rect); - }; - /* _FROM_SVG_END_ */ - - /** - * Returns {@link fabric.Rect} instance from an object representation - * @static - * @memberOf fabric.Rect - * @param {Object} object Object to create an instance from - * @param {Function} [callback] Callback to invoke when an fabric.Rect instance is created - */ - fabric.Rect.fromObject = function(object, callback) { - return fabric.Object._fromObject('Rect', object, callback); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - min = fabric.util.array.min, - max = fabric.util.array.max, - toFixed = fabric.util.toFixed; - - if (fabric.Polyline) { - fabric.warn('fabric.Polyline is already defined'); - return; - } - - /** - * Polyline class - * @class fabric.Polyline - * @extends fabric.Object - * @see {@link fabric.Polyline#initialize} for constructor definition - */ - fabric.Polyline = fabric.util.createClass(fabric.Object, /** @lends fabric.Polyline.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'polyline', - - /** - * Points array - * @type Array - * @default - */ - points: null, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('points'), - - /** - * Constructor - * @param {Array} points Array of points (where each point is an object with x and y) - * @param {Object} [options] Options object - * @return {fabric.Polyline} thisArg - * @example - * var poly = new fabric.Polyline([ - * { x: 10, y: 10 }, - * { x: 50, y: 30 }, - * { x: 40, y: 70 }, - * { x: 60, y: 50 }, - * { x: 100, y: 150 }, - * { x: 40, y: 100 } - * ], { - * stroke: 'red', - * left: 100, - * top: 100 - * }); - */ - initialize: function(points, options) { - options = options || {}; - this.points = points || []; - this.callSuper('initialize', options); - this._setPositionDimensions(options); - }, - - _setPositionDimensions: function(options) { - var calcDim = this._calcDimensions(options), correctLeftTop; - this.width = calcDim.width; - this.height = calcDim.height; - if (!options.fromSVG) { - correctLeftTop = this.translateToGivenOrigin( - { x: calcDim.left - this.strokeWidth / 2, y: calcDim.top - this.strokeWidth / 2 }, - 'left', - 'top', - this.originX, - this.originY - ); - } - if (typeof options.left === 'undefined') { - this.left = options.fromSVG ? calcDim.left : correctLeftTop.x; - } - if (typeof options.top === 'undefined') { - this.top = options.fromSVG ? calcDim.top : correctLeftTop.y; - } - this.pathOffset = { - x: calcDim.left + this.width / 2, - y: calcDim.top + this.height / 2 - }; - }, - - /** - * Calculate the polygon min and max point from points array, - * returning an object with left, top, width, height to measure the - * polygon size - * @return {Object} object.left X coordinate of the polygon leftmost point - * @return {Object} object.top Y coordinate of the polygon topmost point - * @return {Object} object.width distance between X coordinates of the polygon leftmost and rightmost point - * @return {Object} object.height distance between Y coordinates of the polygon topmost and bottommost point - * @private - */ - _calcDimensions: function() { - - var points = this.points, - minX = min(points, 'x') || 0, - minY = min(points, 'y') || 0, - maxX = max(points, 'x') || 0, - maxY = max(points, 'y') || 0, - width = (maxX - minX), - height = (maxY - minY); - - return { - left: minX, - top: minY, - width: width, - height: height - }; - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of an instance - */ - toObject: function(propertiesToInclude) { - return extend(this.callSuper('toObject', propertiesToInclude), { - points: this.points.concat() - }); - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var points = [], diffX = this.pathOffset.x, diffY = this.pathOffset.y, - NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - - for (var i = 0, len = this.points.length; i < len; i++) { - points.push( - toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS), ',', - toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), ' ' - ); - } - return [ - '<' + this.type + ' ', 'COMMON_PARTS', - 'points="', points.join(''), - '" />\n' - ]; - }, - /* _TO_SVG_END_ */ - - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - commonRender: function(ctx) { - var point, len = this.points.length, - x = this.pathOffset.x, - y = this.pathOffset.y; - - if (!len || isNaN(this.points[len - 1].y)) { - // do not draw if no points or odd points - // NaN comes from parseFloat of a empty string in parser - return false; - } - ctx.beginPath(); - ctx.moveTo(this.points[0].x - x, this.points[0].y - y); - for (var i = 0; i < len; i++) { - point = this.points[i]; - ctx.lineTo(point.x - x, point.y - y); - } - return true; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - if (!this.commonRender(ctx)) { - return; - } - this._renderPaintInOrder(ctx); - }, - - /** - * Returns complexity of an instance - * @return {Number} complexity of this instance - */ - complexity: function() { - return this.get('points').length; - } - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Polyline.fromElement}) - * @static - * @memberOf fabric.Polyline - * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement - */ - fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(); - - /** - * Returns fabric.Polyline instance from an SVG element - * @static - * @memberOf fabric.Polyline - * @param {SVGElement} element Element to parser - * @param {Function} callback callback function invoked after parsing - * @param {Object} [options] Options object - */ - fabric.Polyline.fromElementGenerator = function(_class) { - return function(element, callback, options) { - if (!element) { - return callback(null); - } - options || (options = { }); - - var points = fabric.parsePointsAttribute(element.getAttribute('points')), - parsedAttributes = fabric.parseAttributes(element, fabric[_class].ATTRIBUTE_NAMES); - parsedAttributes.fromSVG = true; - callback(new fabric[_class](points, extend(parsedAttributes, options))); - }; - }; - - fabric.Polyline.fromElement = fabric.Polyline.fromElementGenerator('Polyline'); - - /* _FROM_SVG_END_ */ - - /** - * Returns fabric.Polyline instance from an object representation - * @static - * @memberOf fabric.Polyline - * @param {Object} object Object to create an instance from - * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created - */ - fabric.Polyline.fromObject = function(object, callback) { - return fabric.Object._fromObject('Polyline', object, callback, 'points'); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }); - - if (fabric.Polygon) { - fabric.warn('fabric.Polygon is already defined'); - return; - } - - /** - * Polygon class - * @class fabric.Polygon - * @extends fabric.Polyline - * @see {@link fabric.Polygon#initialize} for constructor definition - */ - fabric.Polygon = fabric.util.createClass(fabric.Polyline, /** @lends fabric.Polygon.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'polygon', - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - if (!this.commonRender(ctx)) { - return; - } - ctx.closePath(); - this._renderPaintInOrder(ctx); - }, - - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by `fabric.Polygon.fromElement`) - * @static - * @memberOf fabric.Polygon - * @see: http://www.w3.org/TR/SVG/shapes.html#PolygonElement - */ - fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(); - - /** - * Returns {@link fabric.Polygon} instance from an SVG element - * @static - * @memberOf fabric.Polygon - * @param {SVGElement} element Element to parse - * @param {Function} callback callback function invoked after parsing - * @param {Object} [options] Options object - */ - fabric.Polygon.fromElement = fabric.Polyline.fromElementGenerator('Polygon'); - /* _FROM_SVG_END_ */ - - /** - * Returns fabric.Polygon instance from an object representation - * @static - * @memberOf fabric.Polygon - * @param {Object} object Object to create an instance from - * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created - * @return {void} - */ - fabric.Polygon.fromObject = function(object, callback) { - fabric.Object._fromObject('Polygon', object, callback, 'points'); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - min = fabric.util.array.min, - max = fabric.util.array.max, - extend = fabric.util.object.extend, - _toString = Object.prototype.toString, - toFixed = fabric.util.toFixed; - - if (fabric.Path) { - fabric.warn('fabric.Path is already defined'); - return; - } - - /** - * Path class - * @class fabric.Path - * @extends fabric.Object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup} - * @see {@link fabric.Path#initialize} for constructor definition - */ - fabric.Path = fabric.util.createClass(fabric.Object, /** @lends fabric.Path.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'path', - - /** - * Array of path points - * @type Array - * @default - */ - path: null, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('path', 'fillRule'), - - stateProperties: fabric.Object.prototype.stateProperties.concat('path'), - - /** - * Constructor - * @param {Array|String} path Path data (sequence of coordinates and corresponding "command" tokens) - * @param {Object} [options] Options object - * @return {fabric.Path} thisArg - */ - initialize: function(path, options) { - options = options || { }; - this.callSuper('initialize', options); - if (!path) { - path = []; - } - - var fromArray = _toString.call(path) === '[object Array]'; - - this.path = fabric.util.makePathSimpler( - fromArray ? path : fabric.util.parsePath(path) - ); - - if (!this.path) { - return; - } - fabric.Polyline.prototype._setPositionDimensions.call(this, options); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx context to render path on - */ - _renderPathCommands: function(ctx) { - var current, // current instruction - subpathStartX = 0, - subpathStartY = 0, - x = 0, // current x - y = 0, // current y - controlX = 0, // current control point x - controlY = 0, // current control point y - l = -this.pathOffset.x, - t = -this.pathOffset.y; - - ctx.beginPath(); - - for (var i = 0, len = this.path.length; i < len; ++i) { - - current = this.path[i]; - - switch (current[0]) { // first letter - - case 'L': // lineto, absolute - x = current[1]; - y = current[2]; - ctx.lineTo(x + l, y + t); - break; - - case 'M': // moveTo, absolute - x = current[1]; - y = current[2]; - subpathStartX = x; - subpathStartY = y; - ctx.moveTo(x + l, y + t); - break; - - case 'C': // bezierCurveTo, absolute - x = current[5]; - y = current[6]; - controlX = current[3]; - controlY = current[4]; - ctx.bezierCurveTo( - current[1] + l, - current[2] + t, - controlX + l, - controlY + t, - x + l, - y + t - ); - break; - - case 'Q': // quadraticCurveTo, absolute - ctx.quadraticCurveTo( - current[1] + l, - current[2] + t, - current[3] + l, - current[4] + t - ); - x = current[3]; - y = current[4]; - controlX = current[1]; - controlY = current[2]; - break; - - case 'z': - case 'Z': - x = subpathStartX; - y = subpathStartY; - ctx.closePath(); - break; - } - } - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx context to render path on - */ - _render: function(ctx) { - this._renderPathCommands(ctx); - this._renderPaintInOrder(ctx); - }, - - /** - * Returns string representation of an instance - * @return {String} string representation of an instance - */ - toString: function() { - return '#'; - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return extend(this.callSuper('toObject', propertiesToInclude), { - path: this.path.map(function(item) { return item.slice(); }), - }); - }, - - /** - * Returns dataless object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toDatalessObject: function(propertiesToInclude) { - var o = this.toObject(['sourcePath'].concat(propertiesToInclude)); - if (o.sourcePath) { - delete o.path; - } - return o; - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var path = fabric.util.joinPath(this.path); - return [ - '\n' - ]; - }, - - _getOffsetTransform: function() { - var digits = fabric.Object.NUM_FRACTION_DIGITS; - return ' translate(' + toFixed(-this.pathOffset.x, digits) + ', ' + - toFixed(-this.pathOffset.y, digits) + ')'; - }, - - /** - * Returns svg clipPath representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toClipPathSVG: function(reviver) { - var additionalTransform = this._getOffsetTransform(); - return '\t' + this._createBaseClipPathSVGMarkup( - this._toSVG(), { reviver: reviver, additionalTransform: additionalTransform } - ); - }, - - /** - * Returns svg representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toSVG: function(reviver) { - var additionalTransform = this._getOffsetTransform(); - return this._createBaseSVGMarkup(this._toSVG(), { reviver: reviver, additionalTransform: additionalTransform }); - }, - /* _TO_SVG_END_ */ - - /** - * Returns number representation of an instance complexity - * @return {Number} complexity of this instance - */ - complexity: function() { - return this.path.length; - }, - - /** - * @private - */ - _calcDimensions: function() { - - var aX = [], - aY = [], - current, // current instruction - subpathStartX = 0, - subpathStartY = 0, - x = 0, // current x - y = 0, // current y - bounds; - - for (var i = 0, len = this.path.length; i < len; ++i) { - - current = this.path[i]; - - switch (current[0]) { // first letter - - case 'L': // lineto, absolute - x = current[1]; - y = current[2]; - bounds = []; - break; - - case 'M': // moveTo, absolute - x = current[1]; - y = current[2]; - subpathStartX = x; - subpathStartY = y; - bounds = []; - break; - - case 'C': // bezierCurveTo, absolute - bounds = fabric.util.getBoundsOfCurve(x, y, - current[1], - current[2], - current[3], - current[4], - current[5], - current[6] - ); - x = current[5]; - y = current[6]; - break; - - case 'Q': // quadraticCurveTo, absolute - bounds = fabric.util.getBoundsOfCurve(x, y, - current[1], - current[2], - current[1], - current[2], - current[3], - current[4] - ); - x = current[3]; - y = current[4]; - break; - - case 'z': - case 'Z': - x = subpathStartX; - y = subpathStartY; - break; - } - bounds.forEach(function (point) { - aX.push(point.x); - aY.push(point.y); - }); - aX.push(x); - aY.push(y); - } - - var minX = min(aX) || 0, - minY = min(aY) || 0, - maxX = max(aX) || 0, - maxY = max(aY) || 0, - deltaX = maxX - minX, - deltaY = maxY - minY; - - return { - left: minX, - top: minY, - width: deltaX, - height: deltaY - }; - } - }); - - /** - * Creates an instance of fabric.Path from an object - * @static - * @memberOf fabric.Path - * @param {Object} object - * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created - */ - fabric.Path.fromObject = function(object, callback) { - if (typeof object.sourcePath === 'string') { - var pathUrl = object.sourcePath; - fabric.loadSVGFromURL(pathUrl, function (elements) { - var path = elements[0]; - path.setOptions(object); - callback && callback(path); - }); - } - else { - fabric.Object._fromObject('Path', object, callback, 'path'); - } - }; - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by `fabric.Path.fromElement`) - * @static - * @memberOf fabric.Path - * @see http://www.w3.org/TR/SVG/paths.html#PathElement - */ - fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(['d']); - - /** - * Creates an instance of fabric.Path from an SVG element - * @static - * @memberOf fabric.Path - * @param {SVGElement} element to parse - * @param {Function} callback Callback to invoke when an fabric.Path instance is created - * @param {Object} [options] Options object - * @param {Function} [callback] Options callback invoked after parsing is finished - */ - fabric.Path.fromElement = function(element, callback, options) { - var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES); - parsedAttributes.fromSVG = true; - callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options))); - }; - /* _FROM_SVG_END_ */ - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - min = fabric.util.array.min, - max = fabric.util.array.max; - - if (fabric.Group) { - return; - } - - /** - * Group class - * @class fabric.Group - * @extends fabric.Object - * @mixes fabric.Collection - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups} - * @see {@link fabric.Group#initialize} for constructor definition - */ - fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection, /** @lends fabric.Group.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'group', - - /** - * Width of stroke - * @type Number - * @default - */ - strokeWidth: 0, - - /** - * Indicates if click, mouseover, mouseout events & hoverCursor should also check for subtargets - * @type Boolean - * @default - */ - subTargetCheck: false, - - /** - * Groups are container, do not render anything on theyr own, ence no cache properties - * @type Array - * @default - */ - cacheProperties: [], - - /** - * setOnGroup is a method used for TextBox that is no more used since 2.0.0 The behavior is still - * available setting this boolean to true. - * @type Boolean - * @since 2.0.0 - * @default - */ - useSetOnGroup: false, - - /** - * Constructor - * @param {Object} objects Group objects - * @param {Object} [options] Options object - * @param {Boolean} [isAlreadyGrouped] if true, objects have been grouped already. - * @return {Object} thisArg - */ - initialize: function(objects, options, isAlreadyGrouped) { - options = options || {}; - this._objects = []; - // if objects enclosed in a group have been grouped already, - // we cannot change properties of objects. - // Thus we need to set options to group without objects, - isAlreadyGrouped && this.callSuper('initialize', options); - this._objects = objects || []; - for (var i = this._objects.length; i--; ) { - this._objects[i].group = this; - } - - if (!isAlreadyGrouped) { - var center = options && options.centerPoint; - // we want to set origins before calculating the bounding box. - // so that the topleft can be set with that in mind. - // if specific top and left are passed, are overwritten later - // with the callSuper('initialize', options) - if (options.originX !== undefined) { - this.originX = options.originX; - } - if (options.originY !== undefined) { - this.originY = options.originY; - } - // if coming from svg i do not want to calc bounds. - // i assume width and height are passed along options - center || this._calcBounds(); - this._updateObjectsCoords(center); - delete options.centerPoint; - this.callSuper('initialize', options); - } - else { - this._updateObjectsACoords(); - } - - this.setCoords(); - }, - - /** - * @private - */ - _updateObjectsACoords: function() { - var skipControls = true; - for (var i = this._objects.length; i--; ){ - this._objects[i].setCoords(skipControls); - } - }, - - /** - * @private - * @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change - */ - _updateObjectsCoords: function(center) { - var center = center || this.getCenterPoint(); - for (var i = this._objects.length; i--; ){ - this._updateObjectCoords(this._objects[i], center); - } - }, - - /** - * @private - * @param {Object} object - * @param {fabric.Point} center, current center of group. - */ - _updateObjectCoords: function(object, center) { - var objectLeft = object.left, - objectTop = object.top, - skipControls = true; - - object.set({ - left: objectLeft - center.x, - top: objectTop - center.y - }); - object.group = this; - object.setCoords(skipControls); - }, - - /** - * Returns string represenation of a group - * @return {String} - */ - toString: function() { - return '#'; - }, - - /** - * Adds an object to a group; Then recalculates group's dimension, position. - * @param {Object} object - * @return {fabric.Group} thisArg - * @chainable - */ - addWithUpdate: function(object) { - var nested = !!this.group; - this._restoreObjectsState(); - fabric.util.resetObjectTransform(this); - if (object) { - if (nested) { - // if this group is inside another group, we need to pre transform the object - fabric.util.removeTransformFromObject(object, this.group.calcTransformMatrix()); - } - this._objects.push(object); - object.group = this; - object._set('canvas', this.canvas); - } - this._calcBounds(); - this._updateObjectsCoords(); - this.dirty = true; - if (nested) { - this.group.addWithUpdate(); - } - else { - this.setCoords(); - } - return this; - }, - - /** - * Removes an object from a group; Then recalculates group's dimension, position. - * @param {Object} object - * @return {fabric.Group} thisArg - * @chainable - */ - removeWithUpdate: function(object) { - this._restoreObjectsState(); - fabric.util.resetObjectTransform(this); - - this.remove(object); - this._calcBounds(); - this._updateObjectsCoords(); - this.setCoords(); - this.dirty = true; - return this; - }, - - /** - * @private - */ - _onObjectAdded: function(object) { - this.dirty = true; - object.group = this; - object._set('canvas', this.canvas); - }, - - /** - * @private - */ - _onObjectRemoved: function(object) { - this.dirty = true; - delete object.group; - }, - - /** - * @private - */ - _set: function(key, value) { - var i = this._objects.length; - if (this.useSetOnGroup) { - while (i--) { - this._objects[i].setOnGroup(key, value); - } - } - if (key === 'canvas') { - while (i--) { - this._objects[i]._set(key, value); - } - } - fabric.Object.prototype._set.call(this, key, value); - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - var _includeDefaultValues = this.includeDefaultValues; - var objsToObject = this._objects - .filter(function (obj) { - return !obj.excludeFromExport; - }) - .map(function (obj) { - var originalDefaults = obj.includeDefaultValues; - obj.includeDefaultValues = _includeDefaultValues; - var _obj = obj.toObject(propertiesToInclude); - obj.includeDefaultValues = originalDefaults; - return _obj; - }); - var obj = fabric.Object.prototype.toObject.call(this, propertiesToInclude); - obj.objects = objsToObject; - return obj; - }, - - /** - * Returns object representation of an instance, in dataless mode. - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toDatalessObject: function(propertiesToInclude) { - var objsToObject, sourcePath = this.sourcePath; - if (sourcePath) { - objsToObject = sourcePath; - } - else { - var _includeDefaultValues = this.includeDefaultValues; - objsToObject = this._objects.map(function(obj) { - var originalDefaults = obj.includeDefaultValues; - obj.includeDefaultValues = _includeDefaultValues; - var _obj = obj.toDatalessObject(propertiesToInclude); - obj.includeDefaultValues = originalDefaults; - return _obj; - }); - } - var obj = fabric.Object.prototype.toDatalessObject.call(this, propertiesToInclude); - obj.objects = objsToObject; - return obj; - }, - - /** - * Renders instance on a given context - * @param {CanvasRenderingContext2D} ctx context to render instance on - */ - render: function(ctx) { - this._transformDone = true; - this.callSuper('render', ctx); - this._transformDone = false; - }, - - /** - * Decide if the object should cache or not. Create its own cache level - * needsItsOwnCache should be used when the object drawing method requires - * a cache step. None of the fabric classes requires it. - * Generally you do not cache objects in groups because the group is already cached. - * @return {Boolean} - */ - shouldCache: function() { - var ownCache = fabric.Object.prototype.shouldCache.call(this); - if (ownCache) { - for (var i = 0, len = this._objects.length; i < len; i++) { - if (this._objects[i].willDrawShadow()) { - this.ownCaching = false; - return false; - } - } - } - return ownCache; - }, - - /** - * Check if this object or a child object will cast a shadow - * @return {Boolean} - */ - willDrawShadow: function() { - if (fabric.Object.prototype.willDrawShadow.call(this)) { - return true; - } - for (var i = 0, len = this._objects.length; i < len; i++) { - if (this._objects[i].willDrawShadow()) { - return true; - } - } - return false; - }, - - /** - * Check if this group or its parent group are caching, recursively up - * @return {Boolean} - */ - isOnACache: function() { - return this.ownCaching || (this.group && this.group.isOnACache()); - }, - - /** - * Execute the drawing operation for an object on a specified context - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - drawObject: function(ctx) { - for (var i = 0, len = this._objects.length; i < len; i++) { - this._objects[i].render(ctx); - } - this._drawClipPath(ctx); - }, - - /** - * Check if cache is dirty - */ - isCacheDirty: function(skipCanvas) { - if (this.callSuper('isCacheDirty', skipCanvas)) { - return true; - } - if (!this.statefullCache) { - return false; - } - for (var i = 0, len = this._objects.length; i < len; i++) { - if (this._objects[i].isCacheDirty(true)) { - if (this._cacheCanvas) { - // if this group has not a cache canvas there is nothing to clean - var x = this.cacheWidth / this.zoomX, y = this.cacheHeight / this.zoomY; - this._cacheContext.clearRect(-x / 2, -y / 2, x, y); - } - return true; - } - } - return false; - }, - - /** - * Restores original state of each of group objects (original state is that which was before group was created). - * if the nested boolean is true, the original state will be restored just for the - * first group and not for all the group chain - * @private - * @param {Boolean} nested tell the function to restore object state up to the parent group and not more - * @return {fabric.Group} thisArg - * @chainable - */ - _restoreObjectsState: function() { - var groupMatrix = this.calcOwnMatrix(); - this._objects.forEach(function(object) { - // instead of using _this = this; - fabric.util.addTransformToObject(object, groupMatrix); - delete object.group; - object.setCoords(); - }); - return this; - }, - - /** - * Realises the transform from this group onto the supplied object - * i.e. it tells you what would happen if the supplied object was in - * the group, and then the group was destroyed. It mutates the supplied - * object. - * Warning: this method is not useful anymore, it has been kept to no break the api. - * is not used in the fabricJS codebase - * this method will be reduced to using the utility. - * @private - * @deprecated - * @param {fabric.Object} object - * @param {Array} parentMatrix parent transformation - * @return {fabric.Object} transformedObject - */ - realizeTransform: function(object, parentMatrix) { - fabric.util.addTransformToObject(object, parentMatrix); - return object; - }, - - /** - * Destroys a group (restoring state of its objects) - * @return {fabric.Group} thisArg - * @chainable - */ - destroy: function() { - // when group is destroyed objects needs to get a repaint to be eventually - // displayed on canvas. - this._objects.forEach(function(object) { - object.set('dirty', true); - }); - return this._restoreObjectsState(); - }, - - /** - * make a group an active selection, remove the group from canvas - * the group has to be on canvas for this to work. - * @return {fabric.ActiveSelection} thisArg - * @chainable - */ - toActiveSelection: function() { - if (!this.canvas) { - return; - } - var objects = this._objects, canvas = this.canvas; - this._objects = []; - var options = this.toObject(); - delete options.objects; - var activeSelection = new fabric.ActiveSelection([]); - activeSelection.set(options); - activeSelection.type = 'activeSelection'; - canvas.remove(this); - objects.forEach(function(object) { - object.group = activeSelection; - object.dirty = true; - canvas.add(object); - }); - activeSelection.canvas = canvas; - activeSelection._objects = objects; - canvas._activeObject = activeSelection; - activeSelection.setCoords(); - return activeSelection; - }, - - /** - * Destroys a group (restoring state of its objects) - * @return {fabric.Group} thisArg - * @chainable - */ - ungroupOnCanvas: function() { - return this._restoreObjectsState(); - }, - - /** - * Sets coordinates of all objects inside group - * @return {fabric.Group} thisArg - * @chainable - */ - setObjectsCoords: function() { - var skipControls = true; - this.forEachObject(function(object) { - object.setCoords(skipControls); - }); - return this; - }, - - /** - * @private - */ - _calcBounds: function(onlyWidthHeight) { - var aX = [], - aY = [], - o, prop, coords, - props = ['tr', 'br', 'bl', 'tl'], - i = 0, iLen = this._objects.length, - j, jLen = props.length; - - for ( ; i < iLen; ++i) { - o = this._objects[i]; - coords = o.calcACoords(); - for (j = 0; j < jLen; j++) { - prop = props[j]; - aX.push(coords[prop].x); - aY.push(coords[prop].y); - } - o.aCoords = coords; - } - - this._getBounds(aX, aY, onlyWidthHeight); - }, - - /** - * @private - */ - _getBounds: function(aX, aY, onlyWidthHeight) { - var minXY = new fabric.Point(min(aX), min(aY)), - maxXY = new fabric.Point(max(aX), max(aY)), - top = minXY.y || 0, left = minXY.x || 0, - width = (maxXY.x - minXY.x) || 0, - height = (maxXY.y - minXY.y) || 0; - this.width = width; - this.height = height; - if (!onlyWidthHeight) { - // the bounding box always finds the topleft most corner. - // whatever is the group origin, we set up here the left/top position. - this.setPositionByOrigin({ x: left, y: top }, 'left', 'top'); - } - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - _toSVG: function(reviver) { - var svgString = ['\n']; - - for (var i = 0, len = this._objects.length; i < len; i++) { - svgString.push('\t\t', this._objects[i].toSVG(reviver)); - } - svgString.push('\n'); - return svgString; - }, - - /** - * Returns styles-string for svg-export, specific version for group - * @return {String} - */ - getSvgStyles: function() { - var opacity = typeof this.opacity !== 'undefined' && this.opacity !== 1 ? - 'opacity: ' + this.opacity + ';' : '', - visibility = this.visible ? '' : ' visibility: hidden;'; - return [ - opacity, - this.getSvgFilter(), - visibility - ].join(''); - }, - - /** - * Returns svg clipPath representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toClipPathSVG: function(reviver) { - var svgString = []; - - for (var i = 0, len = this._objects.length; i < len; i++) { - svgString.push('\t', this._objects[i].toClipPathSVG(reviver)); - } - - return this._createBaseClipPathSVGMarkup(svgString, { reviver: reviver }); - }, - /* _TO_SVG_END_ */ - }); - - /** - * Returns {@link fabric.Group} instance from an object representation - * @static - * @memberOf fabric.Group - * @param {Object} object Object to create a group from - * @param {Function} [callback] Callback to invoke when an group instance is created - */ - fabric.Group.fromObject = function(object, callback) { - var objects = object.objects, - options = fabric.util.object.clone(object, true); - delete options.objects; - if (typeof objects === 'string') { - // it has to be an url or something went wrong. - fabric.loadSVGFromURL(objects, function (elements) { - var group = fabric.util.groupSVGElements(elements, object, objects); - group.set(options); - callback && callback(group); - }); - return; - } - fabric.util.enlivenObjects(objects, function(enlivenedObjects) { - fabric.util.enlivenObjects([object.clipPath], function(enlivedClipPath) { - var options = fabric.util.object.clone(object, true); - options.clipPath = enlivedClipPath[0]; - delete options.objects; - callback && callback(new fabric.Group(enlivenedObjects, options, true)); - }); - }); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }); - - if (fabric.ActiveSelection) { - return; - } - - /** - * Group class - * @class fabric.ActiveSelection - * @extends fabric.Group - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups} - * @see {@link fabric.ActiveSelection#initialize} for constructor definition - */ - fabric.ActiveSelection = fabric.util.createClass(fabric.Group, /** @lends fabric.ActiveSelection.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'activeSelection', - - /** - * Constructor - * @param {Object} objects ActiveSelection objects - * @param {Object} [options] Options object - * @return {Object} thisArg - */ - initialize: function(objects, options) { - options = options || {}; - this._objects = objects || []; - for (var i = this._objects.length; i--; ) { - this._objects[i].group = this; - } - - if (options.originX) { - this.originX = options.originX; - } - if (options.originY) { - this.originY = options.originY; - } - this._calcBounds(); - this._updateObjectsCoords(); - fabric.Object.prototype.initialize.call(this, options); - this.setCoords(); - }, - - /** - * Change te activeSelection to a normal group, - * High level function that automatically adds it to canvas as - * active object. no events fired. - * @since 2.0.0 - * @return {fabric.Group} - */ - toGroup: function() { - var objects = this._objects.concat(); - this._objects = []; - var options = fabric.Object.prototype.toObject.call(this); - var newGroup = new fabric.Group([]); - delete options.type; - newGroup.set(options); - objects.forEach(function(object) { - object.canvas.remove(object); - object.group = newGroup; - }); - newGroup._objects = objects; - if (!this.canvas) { - return newGroup; - } - var canvas = this.canvas; - canvas.add(newGroup); - canvas._activeObject = newGroup; - newGroup.setCoords(); - return newGroup; - }, - - /** - * If returns true, deselection is cancelled. - * @since 2.0.0 - * @return {Boolean} [cancel] - */ - onDeselect: function() { - this.destroy(); - return false; - }, - - /** - * Returns string representation of a group - * @return {String} - */ - toString: function() { - return '#'; - }, - - /** - * Decide if the object should cache or not. Create its own cache level - * objectCaching is a global flag, wins over everything - * needsItsOwnCache should be used when the object drawing method requires - * a cache step. None of the fabric classes requires it. - * Generally you do not cache objects in groups because the group outside is cached. - * @return {Boolean} - */ - shouldCache: function() { - return false; - }, - - /** - * Check if this group or its parent group are caching, recursively up - * @return {Boolean} - */ - isOnACache: function() { - return false; - }, - - /** - * Renders controls and borders for the object - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Object} [styleOverride] properties to override the object style - * @param {Object} [childrenOverride] properties to override the children overrides - */ - _renderControls: function(ctx, styleOverride, childrenOverride) { - ctx.save(); - ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; - this.callSuper('_renderControls', ctx, styleOverride); - childrenOverride = childrenOverride || { }; - if (typeof childrenOverride.hasControls === 'undefined') { - childrenOverride.hasControls = false; - } - childrenOverride.forActiveSelection = true; - for (var i = 0, len = this._objects.length; i < len; i++) { - this._objects[i]._renderControls(ctx, childrenOverride); - } - ctx.restore(); - }, - }); - - /** - * Returns {@link fabric.ActiveSelection} instance from an object representation - * @static - * @memberOf fabric.ActiveSelection - * @param {Object} object Object to create a group from - * @param {Function} [callback] Callback to invoke when an ActiveSelection instance is created - */ - fabric.ActiveSelection.fromObject = function(object, callback) { - fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) { - delete object.objects; - callback && callback(new fabric.ActiveSelection(enlivenedObjects, object, true)); - }); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var extend = fabric.util.object.extend; - - if (!global.fabric) { - global.fabric = { }; - } - - if (global.fabric.Image) { - fabric.warn('fabric.Image is already defined.'); - return; - } - - /** - * Image class - * @class fabric.Image - * @extends fabric.Object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images} - * @see {@link fabric.Image#initialize} for constructor definition - */ - fabric.Image = fabric.util.createClass(fabric.Object, /** @lends fabric.Image.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'image', - - /** - * Width of a stroke. - * For image quality a stroke multiple of 2 gives better results. - * @type Number - * @default - */ - strokeWidth: 0, - - /** - * When calling {@link fabric.Image.getSrc}, return value from element src with `element.getAttribute('src')`. - * This allows for relative urls as image src. - * @since 2.7.0 - * @type Boolean - * @default - */ - srcFromAttribute: false, - - /** - * private - * contains last value of scaleX to detect - * if the Image got resized after the last Render - * @type Number - */ - _lastScaleX: 1, - - /** - * private - * contains last value of scaleY to detect - * if the Image got resized after the last Render - * @type Number - */ - _lastScaleY: 1, - - /** - * private - * contains last value of scaling applied by the apply filter chain - * @type Number - */ - _filterScalingX: 1, - - /** - * private - * contains last value of scaling applied by the apply filter chain - * @type Number - */ - _filterScalingY: 1, - - /** - * minimum scale factor under which any resizeFilter is triggered to resize the image - * 0 will disable the automatic resize. 1 will trigger automatically always. - * number bigger than 1 are not implemented yet. - * @type Number - */ - minimumScaleTrigger: 0.5, - - /** - * List of properties to consider when checking if - * state of an object is changed ({@link fabric.Object#hasStateChanged}) - * as well as for history (undo/redo) purposes - * @type Array - */ - stateProperties: fabric.Object.prototype.stateProperties.concat('cropX', 'cropY'), - - /** - * List of properties to consider when checking if cache needs refresh - * Those properties are checked by statefullCache ON ( or lazy mode if we want ) or from single - * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty - * and refreshed at the next render - * @type Array - */ - cacheProperties: fabric.Object.prototype.cacheProperties.concat('cropX', 'cropY'), - - /** - * key used to retrieve the texture representing this image - * @since 2.0.0 - * @type String - * @default - */ - cacheKey: '', - - /** - * Image crop in pixels from original image size. - * @since 2.0.0 - * @type Number - * @default - */ - cropX: 0, - - /** - * Image crop in pixels from original image size. - * @since 2.0.0 - * @type Number - * @default - */ - cropY: 0, - - /** - * Indicates whether this canvas will use image smoothing when painting this image. - * Also influence if the cacheCanvas for this image uses imageSmoothing - * @since 4.0.0-beta.11 - * @type Boolean - * @default - */ - imageSmoothing: true, - - /** - * Constructor - * Image can be initialized with any canvas drawable or a string. - * The string should be a url and will be loaded as an image. - * Canvas and Image element work out of the box, while videos require extra code to work. - * Please check video element events for seeking. - * @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | String} element Image element - * @param {Object} [options] Options object - * @param {function} [callback] callback function to call after eventual filters applied. - * @return {fabric.Image} thisArg - */ - initialize: function(element, options) { - options || (options = { }); - this.filters = []; - this.cacheKey = 'texture' + fabric.Object.__uid++; - this.callSuper('initialize', options); - this._initElement(element, options); - }, - - /** - * Returns image element which this instance if based on - * @return {HTMLImageElement} Image element - */ - getElement: function() { - return this._element || {}; - }, - - /** - * Sets image element for this instance to a specified one. - * If filters defined they are applied to new image. - * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area. - * @param {HTMLImageElement} element - * @param {Object} [options] Options object - * @return {fabric.Image} thisArg - * @chainable - */ - setElement: function(element, options) { - this.removeTexture(this.cacheKey); - this.removeTexture(this.cacheKey + '_filtered'); - this._element = element; - this._originalElement = element; - this._initConfig(options); - if (this.filters.length !== 0) { - this.applyFilters(); - } - // resizeFilters work on the already filtered copy. - // we need to apply resizeFilters AFTER normal filters. - // applyResizeFilters is run more often than normal filters - // and is triggered by user interactions rather than dev code - if (this.resizeFilter) { - this.applyResizeFilters(); - } - return this; - }, - - /** - * Delete a single texture if in webgl mode - */ - removeTexture: function(key) { - var backend = fabric.filterBackend; - if (backend && backend.evictCachesForKey) { - backend.evictCachesForKey(key); - } - }, - - /** - * Delete textures, reference to elements and eventually JSDOM cleanup - */ - dispose: function() { - this.removeTexture(this.cacheKey); - this.removeTexture(this.cacheKey + '_filtered'); - this._cacheContext = undefined; - ['_originalElement', '_element', '_filteredEl', '_cacheCanvas'].forEach((function(element) { - fabric.util.cleanUpJsdomNode(this[element]); - this[element] = undefined; - }).bind(this)); - }, - - /** - * Get the crossOrigin value (of the corresponding image element) - */ - getCrossOrigin: function() { - return this._originalElement && (this._originalElement.crossOrigin || null); - }, - - /** - * Returns original size of an image - * @return {Object} Object with "width" and "height" properties - */ - getOriginalSize: function() { - var element = this.getElement(); - return { - width: element.naturalWidth || element.width, - height: element.naturalHeight || element.height - }; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _stroke: function(ctx) { - if (!this.stroke || this.strokeWidth === 0) { - return; - } - var w = this.width / 2, h = this.height / 2; - ctx.beginPath(); - ctx.moveTo(-w, -h); - ctx.lineTo(w, -h); - ctx.lineTo(w, h); - ctx.lineTo(-w, h); - ctx.lineTo(-w, -h); - ctx.closePath(); - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of an instance - */ - toObject: function(propertiesToInclude) { - var filters = []; - - this.filters.forEach(function(filterObj) { - if (filterObj) { - filters.push(filterObj.toObject()); - } - }); - var object = extend( - this.callSuper( - 'toObject', - ['cropX', 'cropY'].concat(propertiesToInclude) - ), { - src: this.getSrc(), - crossOrigin: this.getCrossOrigin(), - filters: filters, - }); - if (this.resizeFilter) { - object.resizeFilter = this.resizeFilter.toObject(); - } - return object; - }, - - /** - * Returns true if an image has crop applied, inspecting values of cropX,cropY,width,height. - * @return {Boolean} - */ - hasCrop: function() { - return this.cropX || this.cropY || this.width < this._element.width || this.height < this._element.height; - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var svgString = [], imageMarkup = [], strokeSvg, element = this._element, - x = -this.width / 2, y = -this.height / 2, clipPath = '', imageRendering = ''; - if (!element) { - return []; - } - if (this.hasCrop()) { - var clipPathId = fabric.Object.__uid++; - svgString.push( - '\n', - '\t\n', - '\n' - ); - clipPath = ' clip-path="url(#imageCrop_' + clipPathId + ')" '; - } - if (!this.imageSmoothing) { - imageRendering = '" image-rendering="optimizeSpeed'; - } - imageMarkup.push('\t\n'); - - if (this.stroke || this.strokeDashArray) { - var origFill = this.fill; - this.fill = null; - strokeSvg = [ - '\t\n' - ]; - this.fill = origFill; - } - if (this.paintFirst !== 'fill') { - svgString = svgString.concat(strokeSvg, imageMarkup); - } - else { - svgString = svgString.concat(imageMarkup, strokeSvg); - } - return svgString; - }, - /* _TO_SVG_END_ */ - - /** - * Returns source of an image - * @param {Boolean} filtered indicates if the src is needed for svg - * @return {String} Source of an image - */ - getSrc: function(filtered) { - var element = filtered ? this._element : this._originalElement; - if (element) { - if (element.toDataURL) { - return element.toDataURL(); - } - - if (this.srcFromAttribute) { - return element.getAttribute('src'); - } - else { - return element.src; - } - } - else { - return this.src || ''; - } - }, - - /** - * Sets source of an image - * @param {String} src Source string (URL) - * @param {Function} [callback] Callback is invoked when image has been loaded (and all filters have been applied) - * @param {Object} [options] Options object - * @param {String} [options.crossOrigin] crossOrigin value (one of "", "anonymous", "use-credentials") - * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes - * @return {fabric.Image} thisArg - * @chainable - */ - setSrc: function(src, callback, options) { - fabric.util.loadImage(src, function(img, isError) { - this.setElement(img, options); - this._setWidthHeight(); - callback && callback(this, isError); - }, this, options && options.crossOrigin); - return this; - }, - - /** - * Returns string representation of an instance - * @return {String} String representation of an instance - */ - toString: function() { - return '#'; - }, - - applyResizeFilters: function() { - var filter = this.resizeFilter, - minimumScale = this.minimumScaleTrigger, - objectScale = this.getTotalObjectScaling(), - scaleX = objectScale.scaleX, - scaleY = objectScale.scaleY, - elementToFilter = this._filteredEl || this._originalElement; - if (this.group) { - this.set('dirty', true); - } - if (!filter || (scaleX > minimumScale && scaleY > minimumScale)) { - this._element = elementToFilter; - this._filterScalingX = 1; - this._filterScalingY = 1; - this._lastScaleX = scaleX; - this._lastScaleY = scaleY; - return; - } - if (!fabric.filterBackend) { - fabric.filterBackend = fabric.initFilterBackend(); - } - var canvasEl = fabric.util.createCanvasElement(), - cacheKey = this._filteredEl ? (this.cacheKey + '_filtered') : this.cacheKey, - sourceWidth = elementToFilter.width, sourceHeight = elementToFilter.height; - canvasEl.width = sourceWidth; - canvasEl.height = sourceHeight; - this._element = canvasEl; - this._lastScaleX = filter.scaleX = scaleX; - this._lastScaleY = filter.scaleY = scaleY; - fabric.filterBackend.applyFilters( - [filter], elementToFilter, sourceWidth, sourceHeight, this._element, cacheKey); - this._filterScalingX = canvasEl.width / this._originalElement.width; - this._filterScalingY = canvasEl.height / this._originalElement.height; - }, - - /** - * Applies filters assigned to this image (from "filters" array) or from filter param - * @method applyFilters - * @param {Array} filters to be applied - * @param {Boolean} forResizing specify if the filter operation is a resize operation - * @return {thisArg} return the fabric.Image object - * @chainable - */ - applyFilters: function(filters) { - - filters = filters || this.filters || []; - filters = filters.filter(function(filter) { return filter && !filter.isNeutralState(); }); - this.set('dirty', true); - - // needs to clear out or WEBGL will not resize correctly - this.removeTexture(this.cacheKey + '_filtered'); - - if (filters.length === 0) { - this._element = this._originalElement; - this._filteredEl = null; - this._filterScalingX = 1; - this._filterScalingY = 1; - return this; - } - - var imgElement = this._originalElement, - sourceWidth = imgElement.naturalWidth || imgElement.width, - sourceHeight = imgElement.naturalHeight || imgElement.height; - - if (this._element === this._originalElement) { - // if the element is the same we need to create a new element - var canvasEl = fabric.util.createCanvasElement(); - canvasEl.width = sourceWidth; - canvasEl.height = sourceHeight; - this._element = canvasEl; - this._filteredEl = canvasEl; - } - else { - // clear the existing element to get new filter data - // also dereference the eventual resized _element - this._element = this._filteredEl; - this._filteredEl.getContext('2d').clearRect(0, 0, sourceWidth, sourceHeight); - // we also need to resize again at next renderAll, so remove saved _lastScaleX/Y - this._lastScaleX = 1; - this._lastScaleY = 1; - } - if (!fabric.filterBackend) { - fabric.filterBackend = fabric.initFilterBackend(); - } - fabric.filterBackend.applyFilters( - filters, this._originalElement, sourceWidth, sourceHeight, this._element, this.cacheKey); - if (this._originalElement.width !== this._element.width || - this._originalElement.height !== this._element.height) { - this._filterScalingX = this._element.width / this._originalElement.width; - this._filterScalingY = this._element.height / this._originalElement.height; - } - return this; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - fabric.util.setImageSmoothing(ctx, this.imageSmoothing); - if (this.isMoving !== true && this.resizeFilter && this._needsResize()) { - this.applyResizeFilters(); - } - this._stroke(ctx); - this._renderPaintInOrder(ctx); - }, - - /** - * Paint the cached copy of the object on the target context. - * it will set the imageSmoothing for the draw operation - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - drawCacheOnCanvas: function(ctx) { - fabric.util.setImageSmoothing(ctx, this.imageSmoothing); - fabric.Object.prototype.drawCacheOnCanvas.call(this, ctx); - }, - - /** - * Decide if the object should cache or not. Create its own cache level - * needsItsOwnCache should be used when the object drawing method requires - * a cache step. None of the fabric classes requires it. - * Generally you do not cache objects in groups because the group outside is cached. - * This is the special image version where we would like to avoid caching where possible. - * Essentially images do not benefit from caching. They may require caching, and in that - * case we do it. Also caching an image usually ends in a loss of details. - * A full performance audit should be done. - * @return {Boolean} - */ - shouldCache: function() { - return this.needsItsOwnCache(); - }, - - _renderFill: function(ctx) { - var elementToDraw = this._element; - if (!elementToDraw) { - return; - } - var scaleX = this._filterScalingX, scaleY = this._filterScalingY, - w = this.width, h = this.height, min = Math.min, max = Math.max, - // crop values cannot be lesser than 0. - cropX = max(this.cropX, 0), cropY = max(this.cropY, 0), - elWidth = elementToDraw.naturalWidth || elementToDraw.width, - elHeight = elementToDraw.naturalHeight || elementToDraw.height, - sX = cropX * scaleX, - sY = cropY * scaleY, - // the width height cannot exceed element width/height, starting from the crop offset. - sW = min(w * scaleX, elWidth - sX), - sH = min(h * scaleY, elHeight - sY), - x = -w / 2, y = -h / 2, - maxDestW = min(w, elWidth / scaleX - cropX), - maxDestH = min(h, elHeight / scaleY - cropY); - - elementToDraw && ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, maxDestW, maxDestH); - }, - - /** - * needed to check if image needs resize - * @private - */ - _needsResize: function() { - var scale = this.getTotalObjectScaling(); - return (scale.scaleX !== this._lastScaleX || scale.scaleY !== this._lastScaleY); - }, - - /** - * @private - */ - _resetWidthHeight: function() { - this.set(this.getOriginalSize()); - }, - - /** - * The Image class's initialization method. This method is automatically - * called by the constructor. - * @private - * @param {HTMLImageElement|String} element The element representing the image - * @param {Object} [options] Options object - */ - _initElement: function(element, options) { - this.setElement(fabric.util.getById(element), options); - fabric.util.addClass(this.getElement(), fabric.Image.CSS_CANVAS); - }, - - /** - * @private - * @param {Object} [options] Options object - */ - _initConfig: function(options) { - options || (options = { }); - this.setOptions(options); - this._setWidthHeight(options); - }, - - /** - * @private - * @param {Array} filters to be initialized - * @param {Function} callback Callback to invoke when all fabric.Image.filters instances are created - */ - _initFilters: function(filters, callback) { - if (filters && filters.length) { - fabric.util.enlivenObjects(filters, function(enlivenedObjects) { - callback && callback(enlivenedObjects); - }, 'fabric.Image.filters'); - } - else { - callback && callback(); - } - }, - - /** - * @private - * Set the width and the height of the image object, using the element or the - * options. - * @param {Object} [options] Object with width/height properties - */ - _setWidthHeight: function(options) { - options || (options = { }); - var el = this.getElement(); - this.width = options.width || el.naturalWidth || el.width || 0; - this.height = options.height || el.naturalHeight || el.height || 0; - }, - - /** - * Calculate offset for center and scale factor for the image in order to respect - * the preserveAspectRatio attribute - * @private - * @return {Object} - */ - parsePreserveAspectRatioAttribute: function() { - var pAR = fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio || ''), - rWidth = this._element.width, rHeight = this._element.height, - scaleX = 1, scaleY = 1, offsetLeft = 0, offsetTop = 0, cropX = 0, cropY = 0, - offset, pWidth = this.width, pHeight = this.height, parsedAttributes = { width: pWidth, height: pHeight }; - if (pAR && (pAR.alignX !== 'none' || pAR.alignY !== 'none')) { - if (pAR.meetOrSlice === 'meet') { - scaleX = scaleY = fabric.util.findScaleToFit(this._element, parsedAttributes); - offset = (pWidth - rWidth * scaleX) / 2; - if (pAR.alignX === 'Min') { - offsetLeft = -offset; - } - if (pAR.alignX === 'Max') { - offsetLeft = offset; - } - offset = (pHeight - rHeight * scaleY) / 2; - if (pAR.alignY === 'Min') { - offsetTop = -offset; - } - if (pAR.alignY === 'Max') { - offsetTop = offset; - } - } - if (pAR.meetOrSlice === 'slice') { - scaleX = scaleY = fabric.util.findScaleToCover(this._element, parsedAttributes); - offset = rWidth - pWidth / scaleX; - if (pAR.alignX === 'Mid') { - cropX = offset / 2; - } - if (pAR.alignX === 'Max') { - cropX = offset; - } - offset = rHeight - pHeight / scaleY; - if (pAR.alignY === 'Mid') { - cropY = offset / 2; - } - if (pAR.alignY === 'Max') { - cropY = offset; - } - rWidth = pWidth / scaleX; - rHeight = pHeight / scaleY; - } - } - else { - scaleX = pWidth / rWidth; - scaleY = pHeight / rHeight; - } - return { - width: rWidth, - height: rHeight, - scaleX: scaleX, - scaleY: scaleY, - offsetLeft: offsetLeft, - offsetTop: offsetTop, - cropX: cropX, - cropY: cropY - }; - } - }); - - /** - * Default CSS class name for canvas - * @static - * @type String - * @default - */ - fabric.Image.CSS_CANVAS = 'canvas-img'; - - /** - * Alias for getSrc - * @static - */ - fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc; - - /** - * Creates an instance of fabric.Image from its object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} callback Callback to invoke when an image instance is created - */ - fabric.Image.fromObject = function(_object, callback) { - var object = fabric.util.object.clone(_object); - fabric.util.loadImage(object.src, function(img, isError) { - if (isError) { - callback && callback(null, true); - return; - } - fabric.Image.prototype._initFilters.call(object, object.filters, function(filters) { - object.filters = filters || []; - fabric.Image.prototype._initFilters.call(object, [object.resizeFilter], function(resizeFilters) { - object.resizeFilter = resizeFilters[0]; - fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) { - object.clipPath = enlivedProps[0]; - var image = new fabric.Image(img, object); - callback(image, false); - }); - }); - }); - }, null, object.crossOrigin); - }; - - /** - * Creates an instance of fabric.Image from an URL string - * @static - * @param {String} url URL to create an image from - * @param {Function} [callback] Callback to invoke when image is created (newly created image is passed as a first argument). Second argument is a boolean indicating if an error occurred or not. - * @param {Object} [imgOptions] Options object - */ - fabric.Image.fromURL = function(url, callback, imgOptions) { - fabric.util.loadImage(url, function(img, isError) { - callback && callback(new fabric.Image(img, imgOptions), isError); - }, null, imgOptions && imgOptions.crossOrigin); - }; - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Image.fromElement}) - * @static - * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement} - */ - fabric.Image.ATTRIBUTE_NAMES = - fabric.SHARED_ATTRIBUTES.concat( - 'x y width height preserveAspectRatio xlink:href crossOrigin image-rendering'.split(' ') - ); - - /** - * Returns {@link fabric.Image} instance from an SVG element - * @static - * @param {SVGElement} element Element to parse - * @param {Object} [options] Options object - * @param {Function} callback Callback to execute when fabric.Image object is created - * @return {fabric.Image} Instance of fabric.Image - */ - fabric.Image.fromElement = function(element, callback, options) { - var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES); - fabric.Image.fromURL(parsedAttributes['xlink:href'], callback, - extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes)); - }; - /* _FROM_SVG_END_ */ - -})(typeof exports !== 'undefined' ? exports : this); - - -fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - - /** - * @private - * @return {Number} angle value - */ - _getAngleValueForStraighten: function() { - var angle = this.angle % 360; - if (angle > 0) { - return Math.round((angle - 1) / 90) * 90; - } - return Math.round(angle / 90) * 90; - }, - - /** - * Straightens an object (rotating it from current angle to one of 0, 90, 180, 270, etc. depending on which is closer) - * @return {fabric.Object} thisArg - * @chainable - */ - straighten: function() { - this.rotate(this._getAngleValueForStraighten()); - return this; - }, - - /** - * Same as {@link fabric.Object.prototype.straighten} but with animation - * @param {Object} callbacks Object with callback functions - * @param {Function} [callbacks.onComplete] Invoked on completion - * @param {Function} [callbacks.onChange] Invoked on every step of animation - * @return {fabric.Object} thisArg - * @chainable - */ - fxStraighten: function(callbacks) { - callbacks = callbacks || { }; - - var empty = function() { }, - onComplete = callbacks.onComplete || empty, - onChange = callbacks.onChange || empty, - _this = this; - - fabric.util.animate({ - startValue: this.get('angle'), - endValue: this._getAngleValueForStraighten(), - duration: this.FX_DURATION, - onChange: function(value) { - _this.rotate(value); - onChange(); - }, - onComplete: function() { - _this.setCoords(); - onComplete(); - }, - }); - - return this; - } -}); - -fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { - - /** - * Straightens object, then rerenders canvas - * @param {fabric.Object} object Object to straighten - * @return {fabric.Canvas} thisArg - * @chainable - */ - straightenObject: function (object) { - object.straighten(); - this.requestRenderAll(); - return this; - }, - - /** - * Same as {@link fabric.Canvas.prototype.straightenObject}, but animated - * @param {fabric.Object} object Object to straighten - * @return {fabric.Canvas} thisArg - * @chainable - */ - fxStraightenObject: function (object) { - object.fxStraighten({ - onChange: this.requestRenderAllBound - }); - return this; - } -}); - - -(function() { - - 'use strict'; - - /** - * Tests if webgl supports certain precision - * @param {WebGL} Canvas WebGL context to test on - * @param {String} Precision to test can be any of following: 'lowp', 'mediump', 'highp' - * @returns {Boolean} Whether the user's browser WebGL supports given precision. - */ - function testPrecision(gl, precision){ - var fragmentSource = 'precision ' + precision + ' float;\nvoid main(){}'; - var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); - gl.shaderSource(fragmentShader, fragmentSource); - gl.compileShader(fragmentShader); - if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { - return false; - } - return true; - } - - /** - * Indicate whether this filtering backend is supported by the user's browser. - * @param {Number} tileSize check if the tileSize is supported - * @returns {Boolean} Whether the user's browser supports WebGL. - */ - fabric.isWebglSupported = function(tileSize) { - if (fabric.isLikelyNode) { - return false; - } - tileSize = tileSize || fabric.WebglFilterBackend.prototype.tileSize; - var canvas = document.createElement('canvas'); - var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); - var isSupported = false; - // eslint-disable-next-line - if (gl) { - fabric.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); - isSupported = fabric.maxTextureSize >= tileSize; - var precisions = ['highp', 'mediump', 'lowp']; - for (var i = 0; i < 3; i++){ - if (testPrecision(gl, precisions[i])){ - fabric.webGlPrecision = precisions[i]; - break; - }; - } - } - this.isSupported = isSupported; - return isSupported; - }; - - fabric.WebglFilterBackend = WebglFilterBackend; - - /** - * WebGL filter backend. - */ - function WebglFilterBackend(options) { - if (options && options.tileSize) { - this.tileSize = options.tileSize; - } - this.setupGLContext(this.tileSize, this.tileSize); - this.captureGPUInfo(); - }; - - WebglFilterBackend.prototype = /** @lends fabric.WebglFilterBackend.prototype */ { - - tileSize: 2048, - - /** - * Experimental. This object is a sort of repository of help layers used to avoid - * of recreating them during frequent filtering. If you are previewing a filter with - * a slider you probably do not want to create help layers every filter step. - * in this object there will be appended some canvases, created once, resized sometimes - * cleared never. Clearing is left to the developer. - **/ - resources: { - - }, - - /** - * Setup a WebGL context suitable for filtering, and bind any needed event handlers. - */ - setupGLContext: function(width, height) { - this.dispose(); - this.createWebGLCanvas(width, height); - // eslint-disable-next-line - this.aPosition = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]); - this.chooseFastestCopyGLTo2DMethod(width, height); - }, - - /** - * Pick a method to copy data from GL context to 2d canvas. In some browsers using - * putImageData is faster than drawImage for that specific operation. - */ - chooseFastestCopyGLTo2DMethod: function(width, height) { - var canMeasurePerf = typeof window.performance !== 'undefined', canUseImageData; - try { - new ImageData(1, 1); - canUseImageData = true; - } - catch (e) { - canUseImageData = false; - } - // eslint-disable-next-line no-undef - var canUseArrayBuffer = typeof ArrayBuffer !== 'undefined'; - // eslint-disable-next-line no-undef - var canUseUint8Clamped = typeof Uint8ClampedArray !== 'undefined'; - - if (!(canMeasurePerf && canUseImageData && canUseArrayBuffer && canUseUint8Clamped)) { - return; - } - - var targetCanvas = fabric.util.createCanvasElement(); - // eslint-disable-next-line no-undef - var imageBuffer = new ArrayBuffer(width * height * 4); - if (fabric.forceGLPutImageData) { - this.imageBuffer = imageBuffer; - this.copyGLTo2D = copyGLTo2DPutImageData; - return; - } - var testContext = { - imageBuffer: imageBuffer, - destinationWidth: width, - destinationHeight: height, - targetCanvas: targetCanvas - }; - var startTime, drawImageTime, putImageDataTime; - targetCanvas.width = width; - targetCanvas.height = height; - - startTime = window.performance.now(); - copyGLTo2DDrawImage.call(testContext, this.gl, testContext); - drawImageTime = window.performance.now() - startTime; - - startTime = window.performance.now(); - copyGLTo2DPutImageData.call(testContext, this.gl, testContext); - putImageDataTime = window.performance.now() - startTime; - - if (drawImageTime > putImageDataTime) { - this.imageBuffer = imageBuffer; - this.copyGLTo2D = copyGLTo2DPutImageData; - } - else { - this.copyGLTo2D = copyGLTo2DDrawImage; - } - }, - - /** - * Create a canvas element and associated WebGL context and attaches them as - * class properties to the GLFilterBackend class. - */ - createWebGLCanvas: function(width, height) { - var canvas = fabric.util.createCanvasElement(); - canvas.width = width; - canvas.height = height; - var glOptions = { - alpha: true, - premultipliedAlpha: false, - depth: false, - stencil: false, - antialias: false - }, - gl = canvas.getContext('webgl', glOptions); - if (!gl) { - gl = canvas.getContext('experimental-webgl', glOptions); - } - if (!gl) { - return; - } - gl.clearColor(0, 0, 0, 0); - // this canvas can fire webglcontextlost and webglcontextrestored - this.canvas = canvas; - this.gl = gl; - }, - - /** - * Attempts to apply the requested filters to the source provided, drawing the filtered output - * to the provided target canvas. - * - * @param {Array} filters The filters to apply. - * @param {HTMLImageElement|HTMLCanvasElement} source The source to be filtered. - * @param {Number} width The width of the source input. - * @param {Number} height The height of the source input. - * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn. - * @param {String|undefined} cacheKey A key used to cache resources related to the source. If - * omitted, caching will be skipped. - */ - applyFilters: function(filters, source, width, height, targetCanvas, cacheKey) { - var gl = this.gl; - var cachedTexture; - if (cacheKey) { - cachedTexture = this.getCachedTexture(cacheKey, source); - } - var pipelineState = { - originalWidth: source.width || source.originalWidth, - originalHeight: source.height || source.originalHeight, - sourceWidth: width, - sourceHeight: height, - destinationWidth: width, - destinationHeight: height, - context: gl, - sourceTexture: this.createTexture(gl, width, height, !cachedTexture && source), - targetTexture: this.createTexture(gl, width, height), - originalTexture: cachedTexture || - this.createTexture(gl, width, height, !cachedTexture && source), - passes: filters.length, - webgl: true, - aPosition: this.aPosition, - programCache: this.programCache, - pass: 0, - filterBackend: this, - targetCanvas: targetCanvas - }; - var tempFbo = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, tempFbo); - filters.forEach(function(filter) { filter && filter.applyTo(pipelineState); }); - resizeCanvasIfNeeded(pipelineState); - this.copyGLTo2D(gl, pipelineState); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.deleteTexture(pipelineState.sourceTexture); - gl.deleteTexture(pipelineState.targetTexture); - gl.deleteFramebuffer(tempFbo); - targetCanvas.getContext('2d').setTransform(1, 0, 0, 1, 0, 0); - return pipelineState; - }, - - /** - * Detach event listeners, remove references, and clean up caches. - */ - dispose: function() { - if (this.canvas) { - this.canvas = null; - this.gl = null; - } - this.clearWebGLCaches(); - }, - - /** - * Wipe out WebGL-related caches. - */ - clearWebGLCaches: function() { - this.programCache = {}; - this.textureCache = {}; - }, - - /** - * Create a WebGL texture object. - * - * Accepts specific dimensions to initialize the texture to or a source image. - * - * @param {WebGLRenderingContext} gl The GL context to use for creating the texture. - * @param {Number} width The width to initialize the texture at. - * @param {Number} height The height to initialize the texture. - * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source for the texture data. - * @returns {WebGLTexture} - */ - createTexture: function(gl, width, height, textureImageSource) { - var texture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - if (textureImageSource) { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureImageSource); - } - else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - return texture; - }, - - /** - * Can be optionally used to get a texture from the cache array - * - * If an existing texture is not found, a new texture is created and cached. - * - * @param {String} uniqueId A cache key to use to find an existing texture. - * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source to use to create the - * texture cache entry if one does not already exist. - */ - getCachedTexture: function(uniqueId, textureImageSource) { - if (this.textureCache[uniqueId]) { - return this.textureCache[uniqueId]; - } - else { - var texture = this.createTexture( - this.gl, textureImageSource.width, textureImageSource.height, textureImageSource); - this.textureCache[uniqueId] = texture; - return texture; - } - }, - - /** - * Clear out cached resources related to a source image that has been - * filtered previously. - * - * @param {String} cacheKey The cache key provided when the source image was filtered. - */ - evictCachesForKey: function(cacheKey) { - if (this.textureCache[cacheKey]) { - this.gl.deleteTexture(this.textureCache[cacheKey]); - delete this.textureCache[cacheKey]; - } - }, - - copyGLTo2D: copyGLTo2DDrawImage, - - /** - * Attempt to extract GPU information strings from a WebGL context. - * - * Useful information when debugging or blacklisting specific GPUs. - * - * @returns {Object} A GPU info object with renderer and vendor strings. - */ - captureGPUInfo: function() { - if (this.gpuInfo) { - return this.gpuInfo; - } - var gl = this.gl, gpuInfo = { renderer: '', vendor: '' }; - if (!gl) { - return gpuInfo; - } - var ext = gl.getExtension('WEBGL_debug_renderer_info'); - if (ext) { - var renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL); - var vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL); - if (renderer) { - gpuInfo.renderer = renderer.toLowerCase(); - } - if (vendor) { - gpuInfo.vendor = vendor.toLowerCase(); - } - } - this.gpuInfo = gpuInfo; - return gpuInfo; - }, - }; -})(); - -function resizeCanvasIfNeeded(pipelineState) { - var targetCanvas = pipelineState.targetCanvas, - width = targetCanvas.width, height = targetCanvas.height, - dWidth = pipelineState.destinationWidth, - dHeight = pipelineState.destinationHeight; - - if (width !== dWidth || height !== dHeight) { - targetCanvas.width = dWidth; - targetCanvas.height = dHeight; - } -} - -/** - * Copy an input WebGL canvas on to an output 2D canvas. - * - * The WebGL canvas is assumed to be upside down, with the top-left pixel of the - * desired output image appearing in the bottom-left corner of the WebGL canvas. - * - * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from. - * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to. - * @param {Object} pipelineState The 2D target canvas to copy on to. - */ -function copyGLTo2DDrawImage(gl, pipelineState) { - var glCanvas = gl.canvas, targetCanvas = pipelineState.targetCanvas, - ctx = targetCanvas.getContext('2d'); - ctx.translate(0, targetCanvas.height); // move it down again - ctx.scale(1, -1); // vertical flip - // where is my image on the big glcanvas? - var sourceY = glCanvas.height - targetCanvas.height; - ctx.drawImage(glCanvas, 0, sourceY, targetCanvas.width, targetCanvas.height, 0, 0, - targetCanvas.width, targetCanvas.height); -} - -/** - * Copy an input WebGL canvas on to an output 2D canvas using 2d canvas' putImageData - * API. Measurably faster than using ctx.drawImage in Firefox (version 54 on OSX Sierra). - * - * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from. - * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to. - * @param {Object} pipelineState The 2D target canvas to copy on to. - */ -function copyGLTo2DPutImageData(gl, pipelineState) { - var targetCanvas = pipelineState.targetCanvas, ctx = targetCanvas.getContext('2d'), - dWidth = pipelineState.destinationWidth, - dHeight = pipelineState.destinationHeight, - numBytes = dWidth * dHeight * 4; - - // eslint-disable-next-line no-undef - var u8 = new Uint8Array(this.imageBuffer, 0, numBytes); - // eslint-disable-next-line no-undef - var u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes); - - gl.readPixels(0, 0, dWidth, dHeight, gl.RGBA, gl.UNSIGNED_BYTE, u8); - var imgData = new ImageData(u8Clamped, dWidth, dHeight); - ctx.putImageData(imgData, 0, 0); -} - - -(function() { - - 'use strict'; - - var noop = function() {}; - - fabric.Canvas2dFilterBackend = Canvas2dFilterBackend; - - /** - * Canvas 2D filter backend. - */ - function Canvas2dFilterBackend() {}; - - Canvas2dFilterBackend.prototype = /** @lends fabric.Canvas2dFilterBackend.prototype */ { - evictCachesForKey: noop, - dispose: noop, - clearWebGLCaches: noop, - - /** - * Experimental. This object is a sort of repository of help layers used to avoid - * of recreating them during frequent filtering. If you are previewing a filter with - * a slider you probably do not want to create help layers every filter step. - * in this object there will be appended some canvases, created once, resized sometimes - * cleared never. Clearing is left to the developer. - **/ - resources: { - - }, - - /** - * Apply a set of filters against a source image and draw the filtered output - * to the provided destination canvas. - * - * @param {EnhancedFilter} filters The filter to apply. - * @param {HTMLImageElement|HTMLCanvasElement} sourceElement The source to be filtered. - * @param {Number} sourceWidth The width of the source input. - * @param {Number} sourceHeight The height of the source input. - * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn. - */ - applyFilters: function(filters, sourceElement, sourceWidth, sourceHeight, targetCanvas) { - var ctx = targetCanvas.getContext('2d'); - ctx.drawImage(sourceElement, 0, 0, sourceWidth, sourceHeight); - var imageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight); - var originalImageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight); - var pipelineState = { - sourceWidth: sourceWidth, - sourceHeight: sourceHeight, - imageData: imageData, - originalEl: sourceElement, - originalImageData: originalImageData, - canvasEl: targetCanvas, - ctx: ctx, - filterBackend: this, - }; - filters.forEach(function(filter) { filter.applyTo(pipelineState); }); - if (pipelineState.imageData.width !== sourceWidth || pipelineState.imageData.height !== sourceHeight) { - targetCanvas.width = pipelineState.imageData.width; - targetCanvas.height = pipelineState.imageData.height; - } - ctx.putImageData(pipelineState.imageData, 0, 0); - return pipelineState; - }, - - }; -})(); - - -/** - * @namespace fabric.Image.filters - * @memberOf fabric.Image - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#image_filters} - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - */ -fabric.Image = fabric.Image || { }; -fabric.Image.filters = fabric.Image.filters || { }; - -/** - * Root filter class from which all filter classes inherit from - * @class fabric.Image.filters.BaseFilter - * @memberOf fabric.Image.filters - */ -fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Image.filters.BaseFilter.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'BaseFilter', - - /** - * Array of attributes to send with buffers. do not modify - * @private - */ - - vertexSource: 'attribute vec2 aPosition;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vTexCoord = aPosition;\n' + - 'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n' + - '}', - - fragmentSource: 'precision highp float;\n' + - 'varying vec2 vTexCoord;\n' + - 'uniform sampler2D uTexture;\n' + - 'void main() {\n' + - 'gl_FragColor = texture2D(uTexture, vTexCoord);\n' + - '}', - - /** - * Constructor - * @param {Object} [options] Options object - */ - initialize: function(options) { - if (options) { - this.setOptions(options); - } - }, - - /** - * Sets filter's properties from options - * @param {Object} [options] Options object - */ - setOptions: function(options) { - for (var prop in options) { - this[prop] = options[prop]; - } - }, - - /** - * Compile this filter's shader program. - * - * @param {WebGLRenderingContext} gl The GL canvas context to use for shader compilation. - * @param {String} fragmentSource fragmentShader source for compilation - * @param {String} vertexSource vertexShader source for compilation - */ - createProgram: function(gl, fragmentSource, vertexSource) { - fragmentSource = fragmentSource || this.fragmentSource; - vertexSource = vertexSource || this.vertexSource; - if (fabric.webGlPrecision !== 'highp'){ - fragmentSource = fragmentSource.replace( - /precision highp float/g, - 'precision ' + fabric.webGlPrecision + ' float' - ); - } - var vertexShader = gl.createShader(gl.VERTEX_SHADER); - gl.shaderSource(vertexShader, vertexSource); - gl.compileShader(vertexShader); - if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) { - throw new Error( - // eslint-disable-next-line prefer-template - 'Vertex shader compile error for ' + this.type + ': ' + - gl.getShaderInfoLog(vertexShader) - ); - } - - var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); - gl.shaderSource(fragmentShader, fragmentSource); - gl.compileShader(fragmentShader); - if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { - throw new Error( - // eslint-disable-next-line prefer-template - 'Fragment shader compile error for ' + this.type + ': ' + - gl.getShaderInfoLog(fragmentShader) - ); - } - - var program = gl.createProgram(); - gl.attachShader(program, vertexShader); - gl.attachShader(program, fragmentShader); - gl.linkProgram(program); - if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { - throw new Error( - // eslint-disable-next-line prefer-template - 'Shader link error for "${this.type}" ' + - gl.getProgramInfoLog(program) - ); - } - - var attributeLocations = this.getAttributeLocations(gl, program); - var uniformLocations = this.getUniformLocations(gl, program) || { }; - uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW'); - uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH'); - return { - program: program, - attributeLocations: attributeLocations, - uniformLocations: uniformLocations - }; - }, - - /** - * Return a map of attribute names to WebGLAttributeLocation objects. - * - * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. - * @param {WebGLShaderProgram} program The shader program from which to take attribute locations. - * @returns {Object} A map of attribute names to attribute locations. - */ - getAttributeLocations: function(gl, program) { - return { - aPosition: gl.getAttribLocation(program, 'aPosition'), - }; - }, - - /** - * Return a map of uniform names to WebGLUniformLocation objects. - * - * Intended to be overridden by subclasses. - * - * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. - * @param {WebGLShaderProgram} program The shader program from which to take uniform locations. - * @returns {Object} A map of uniform names to uniform locations. - */ - getUniformLocations: function (/* gl, program */) { - // in case i do not need any special uniform i need to return an empty object - return { }; - }, - - /** - * Send attribute data from this filter to its shader program on the GPU. - * - * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. - * @param {Object} attributeLocations A map of shader attribute names to their locations. - */ - sendAttributeData: function(gl, attributeLocations, aPositionData) { - var attributeLocation = attributeLocations.aPosition; - var buffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - gl.enableVertexAttribArray(attributeLocation); - gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0); - gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW); - }, - - _setupFrameBuffer: function(options) { - var gl = options.context, width, height; - if (options.passes > 1) { - width = options.destinationWidth; - height = options.destinationHeight; - if (options.sourceWidth !== width || options.sourceHeight !== height) { - gl.deleteTexture(options.targetTexture); - options.targetTexture = options.filterBackend.createTexture(gl, width, height); - } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, - options.targetTexture, 0); - } - else { - // draw last filter on canvas and not to framebuffer. - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.finish(); - } - }, - - _swapTextures: function(options) { - options.passes--; - options.pass++; - var temp = options.targetTexture; - options.targetTexture = options.sourceTexture; - options.sourceTexture = temp; - }, - - /** - * Generic isNeutral implementation for one parameter based filters. - * Used only in image applyFilters to discard filters that will not have an effect - * on the image - * Other filters may need their own version ( ColorMatrix, HueRotation, gamma, ComposedFilter ) - * @param {Object} options - **/ - isNeutralState: function(/* options */) { - var main = this.mainParameter, - _class = fabric.Image.filters[this.type].prototype; - if (main) { - if (Array.isArray(_class[main])) { - for (var i = _class[main].length; i--;) { - if (this[main][i] !== _class[main][i]) { - return false; - } - } - return true; - } - else { - return _class[main] === this[main]; - } - } - else { - return false; - } - }, - - /** - * Apply this filter to the input image data provided. - * - * Determines whether to use WebGL or Canvas2D based on the options.webgl flag. - * - * @param {Object} options - * @param {Number} options.passes The number of filters remaining to be executed - * @param {Boolean} options.webgl Whether to use webgl to render the filter. - * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. - * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - applyTo: function(options) { - if (options.webgl) { - this._setupFrameBuffer(options); - this.applyToWebGL(options); - this._swapTextures(options); - } - else { - this.applyTo2d(options); - } - }, - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - if (!options.programCache.hasOwnProperty(this.type)) { - options.programCache[this.type] = this.createProgram(options.context); - } - return options.programCache[this.type]; - }, - - /** - * Apply this filter using webgl. - * - * @param {Object} options - * @param {Number} options.passes The number of filters remaining to be executed - * @param {Boolean} options.webgl Whether to use webgl to render the filter. - * @param {WebGLTexture} options.originalTexture The texture of the original input image. - * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. - * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - applyToWebGL: function(options) { - var gl = options.context; - var shader = this.retrieveShader(options); - if (options.pass === 0 && options.originalTexture) { - gl.bindTexture(gl.TEXTURE_2D, options.originalTexture); - } - else { - gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture); - } - gl.useProgram(shader.program); - this.sendAttributeData(gl, shader.attributeLocations, options.aPosition); - - gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth); - gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight); - - this.sendUniformData(gl, shader.uniformLocations); - gl.viewport(0, 0, options.destinationWidth, options.destinationHeight); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - }, - - bindAdditionalTexture: function(gl, texture, textureUnit) { - gl.activeTexture(textureUnit); - gl.bindTexture(gl.TEXTURE_2D, texture); - // reset active texture to 0 as usual - gl.activeTexture(gl.TEXTURE0); - }, - - unbindAdditionalTexture: function(gl, textureUnit) { - gl.activeTexture(textureUnit); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.activeTexture(gl.TEXTURE0); - }, - - getMainParameter: function() { - return this[this.mainParameter]; - }, - - setMainParameter: function(value) { - this[this.mainParameter] = value; - }, - - /** - * Send uniform data from this filter to its shader program on the GPU. - * - * Intended to be overridden by subclasses. - * - * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. - * @param {Object} uniformLocations A map of shader uniform names to their locations. - */ - sendUniformData: function(/* gl, uniformLocations */) { - // Intentionally left blank. Override me in subclasses. - }, - - /** - * If needed by a 2d filter, this functions can create an helper canvas to be used - * remember that options.targetCanvas is available for use till end of chain. - */ - createHelpLayer: function(options) { - if (!options.helpLayer) { - var helpLayer = document.createElement('canvas'); - helpLayer.width = options.sourceWidth; - helpLayer.height = options.sourceHeight; - options.helpLayer = helpLayer; - } - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - var object = { type: this.type }, mainP = this.mainParameter; - if (mainP) { - object[mainP] = this[mainP]; - } - return object; - }, - - /** - * Returns a JSON representation of an instance - * @return {Object} JSON - */ - toJSON: function() { - // delegate, not alias - return this.toObject(); - } -}); - -fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { - var filter = new fabric.Image.filters[object.type](object); - callback && callback(filter); - return filter; -}; - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Color Matrix filter class - * @class fabric.Image.filters.ColorMatrix - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.ColorMatrix#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @see {@Link http://www.webwasp.co.uk/tutorials/219/Color_Matrix_Filter.php} - * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl} - * @example Kodachrome filter - * var filter = new fabric.Image.filters.ColorMatrix({ - * matrix: [ - 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502, - -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203, - -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946, - 0, 0, 0, 1, 0 - ] - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.ColorMatrix = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.ColorMatrix.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'ColorMatrix', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'varying vec2 vTexCoord;\n' + - 'uniform mat4 uColorMatrix;\n' + - 'uniform vec4 uConstants;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'color *= uColorMatrix;\n' + - 'color += uConstants;\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * Colormatrix for pixels. - * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning - * outside the -1, 1 range. - * 0.0039215686 is the part of 1 that get translated to 1 in 2d - * @param {Array} matrix array of 20 numbers. - * @default - */ - matrix: [ - 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0 - ], - - mainParameter: 'matrix', - - /** - * Lock the colormatrix on the color part, skipping alpha, manly for non webgl scenario - * to save some calculation - */ - colorsOnly: true, - - /** - * Constructor - * @param {Object} [options] Options object - */ - initialize: function(options) { - this.callSuper('initialize', options); - // create a new array instead mutating the prototype with push - this.matrix = this.matrix.slice(0); - }, - - /** - * Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8Array to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, - iLen = data.length, - m = this.matrix, - r, g, b, a, i, colorsOnly = this.colorsOnly; - - for (i = 0; i < iLen; i += 4) { - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - if (colorsOnly) { - data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255; - data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255; - data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255; - } - else { - a = data[i + 3]; - data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4] * 255; - data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9] * 255; - data[i + 2] = r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14] * 255; - data[i + 3] = r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19] * 255; - } - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uColorMatrix: gl.getUniformLocation(program, 'uColorMatrix'), - uConstants: gl.getUniformLocation(program, 'uConstants'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - var m = this.matrix, - matrix = [ - m[0], m[1], m[2], m[3], - m[5], m[6], m[7], m[8], - m[10], m[11], m[12], m[13], - m[15], m[16], m[17], m[18] - ], - constants = [m[4], m[9], m[14], m[19]]; - gl.uniformMatrix4fv(uniformLocations.uColorMatrix, false, matrix); - gl.uniform4fv(uniformLocations.uConstants, constants); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] function to invoke after filter creation - * @return {fabric.Image.filters.ColorMatrix} Instance of fabric.Image.filters.ColorMatrix - */ - fabric.Image.filters.ColorMatrix.fromObject = fabric.Image.filters.BaseFilter.fromObject; -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Brightness filter class - * @class fabric.Image.filters.Brightness - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Brightness#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Brightness({ - * brightness: 0.05 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Brightness = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Brightness.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Brightness', - - /** - * Fragment source for the brightness program - */ - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uBrightness;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'color.rgb += uBrightness;\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * Brightness value, from -1 to 1. - * translated to -255 to 255 for 2d - * 0.0039215686 is the part of 1 that get translated to 1 in 2d - * @param {Number} brightness - * @default - */ - brightness: 0, - - /** - * Describe the property that is the filter parameter - * @param {String} m - * @default - */ - mainParameter: 'brightness', - - /** - * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - if (this.brightness === 0) { - return; - } - var imageData = options.imageData, - data = imageData.data, i, len = data.length, - brightness = Math.round(this.brightness * 255); - for (i = 0; i < len; i += 4) { - data[i] = data[i] + brightness; - data[i + 1] = data[i + 1] + brightness; - data[i + 2] = data[i + 2] + brightness; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uBrightness: gl.getUniformLocation(program, 'uBrightness'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uBrightness, this.brightness); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Brightness} Instance of fabric.Image.filters.Brightness - */ - fabric.Image.filters.Brightness.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Adapted from html5rocks article - * @class fabric.Image.filters.Convolute - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Convolute#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example Sharpen filter - * var filter = new fabric.Image.filters.Convolute({ - * matrix: [ 0, -1, 0, - * -1, 5, -1, - * 0, -1, 0 ] - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - * @example Blur filter - * var filter = new fabric.Image.filters.Convolute({ - * matrix: [ 1/9, 1/9, 1/9, - * 1/9, 1/9, 1/9, - * 1/9, 1/9, 1/9 ] - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - * @example Emboss filter - * var filter = new fabric.Image.filters.Convolute({ - * matrix: [ 1, 1, 1, - * 1, 0.7, -1, - * -1, -1, -1 ] - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - * @example Emboss filter with opaqueness - * var filter = new fabric.Image.filters.Convolute({ - * opaque: true, - * matrix: [ 1, 1, 1, - * 1, 0.7, -1, - * -1, -1, -1 ] - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - filters.Convolute = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Convolute.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Convolute', - - /* - * Opaque value (true/false) - */ - opaque: false, - - /* - * matrix for the filter, max 9x9 - */ - matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0], - - /** - * Fragment source for the brightness program - */ - fragmentSource: { - Convolute_3_1: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[9];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 0);\n' + - 'for (float h = 0.0; h < 3.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 3.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\n' + - 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\n' + - '}\n' + - '}\n' + - 'gl_FragColor = color;\n' + - '}', - Convolute_3_0: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[9];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 1);\n' + - 'for (float h = 0.0; h < 3.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 3.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\n' + - 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\n' + - '}\n' + - '}\n' + - 'float alpha = texture2D(uTexture, vTexCoord).a;\n' + - 'gl_FragColor = color;\n' + - 'gl_FragColor.a = alpha;\n' + - '}', - Convolute_5_1: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[25];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 0);\n' + - 'for (float h = 0.0; h < 5.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 5.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n' + - 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\n' + - '}\n' + - '}\n' + - 'gl_FragColor = color;\n' + - '}', - Convolute_5_0: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[25];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 1);\n' + - 'for (float h = 0.0; h < 5.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 5.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n' + - 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\n' + - '}\n' + - '}\n' + - 'float alpha = texture2D(uTexture, vTexCoord).a;\n' + - 'gl_FragColor = color;\n' + - 'gl_FragColor.a = alpha;\n' + - '}', - Convolute_7_1: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[49];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 0);\n' + - 'for (float h = 0.0; h < 7.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 7.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n' + - 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\n' + - '}\n' + - '}\n' + - 'gl_FragColor = color;\n' + - '}', - Convolute_7_0: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[49];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 1);\n' + - 'for (float h = 0.0; h < 7.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 7.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n' + - 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\n' + - '}\n' + - '}\n' + - 'float alpha = texture2D(uTexture, vTexCoord).a;\n' + - 'gl_FragColor = color;\n' + - 'gl_FragColor.a = alpha;\n' + - '}', - Convolute_9_1: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[81];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 0);\n' + - 'for (float h = 0.0; h < 9.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 9.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n' + - 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\n' + - '}\n' + - '}\n' + - 'gl_FragColor = color;\n' + - '}', - Convolute_9_0: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[81];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 1);\n' + - 'for (float h = 0.0; h < 9.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 9.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n' + - 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\n' + - '}\n' + - '}\n' + - 'float alpha = texture2D(uTexture, vTexCoord).a;\n' + - 'gl_FragColor = color;\n' + - 'gl_FragColor.a = alpha;\n' + - '}', - }, - - /** - * Constructor - * @memberOf fabric.Image.filters.Convolute.prototype - * @param {Object} [options] Options object - * @param {Boolean} [options.opaque=false] Opaque value (true/false) - * @param {Array} [options.matrix] Filter matrix - */ - - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - var size = Math.sqrt(this.matrix.length); - var cacheKey = this.type + '_' + size + '_' + (this.opaque ? 1 : 0); - var shaderSource = this.fragmentSource[cacheKey]; - if (!options.programCache.hasOwnProperty(cacheKey)) { - options.programCache[cacheKey] = this.createProgram(options.context, shaderSource); - } - return options.programCache[cacheKey]; - }, - - /** - * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, - weights = this.matrix, - side = Math.round(Math.sqrt(weights.length)), - halfSide = Math.floor(side / 2), - sw = imageData.width, - sh = imageData.height, - output = options.ctx.createImageData(sw, sh), - dst = output.data, - // go through the destination image pixels - alphaFac = this.opaque ? 1 : 0, - r, g, b, a, dstOff, - scx, scy, srcOff, wt, - x, y, cx, cy; - - for (y = 0; y < sh; y++) { - for (x = 0; x < sw; x++) { - dstOff = (y * sw + x) * 4; - // calculate the weighed sum of the source image pixels that - // fall under the convolution matrix - r = 0; g = 0; b = 0; a = 0; - - for (cy = 0; cy < side; cy++) { - for (cx = 0; cx < side; cx++) { - scy = y + cy - halfSide; - scx = x + cx - halfSide; - - // eslint-disable-next-line max-depth - if (scy < 0 || scy >= sh || scx < 0 || scx >= sw) { - continue; - } - - srcOff = (scy * sw + scx) * 4; - wt = weights[cy * side + cx]; - - r += data[srcOff] * wt; - g += data[srcOff + 1] * wt; - b += data[srcOff + 2] * wt; - // eslint-disable-next-line max-depth - if (!alphaFac) { - a += data[srcOff + 3] * wt; - } - } - } - dst[dstOff] = r; - dst[dstOff + 1] = g; - dst[dstOff + 2] = b; - if (!alphaFac) { - dst[dstOff + 3] = a; - } - else { - dst[dstOff + 3] = data[dstOff + 3]; - } - } - } - options.imageData = output; - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uMatrix: gl.getUniformLocation(program, 'uMatrix'), - uOpaque: gl.getUniformLocation(program, 'uOpaque'), - uHalfSize: gl.getUniformLocation(program, 'uHalfSize'), - uSize: gl.getUniformLocation(program, 'uSize'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1fv(uniformLocations.uMatrix, this.matrix); - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return extend(this.callSuper('toObject'), { - opaque: this.opaque, - matrix: this.matrix - }); - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Convolute} Instance of fabric.Image.filters.Convolute - */ - fabric.Image.filters.Convolute.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Grayscale image filter class - * @class fabric.Image.filters.Grayscale - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Grayscale(); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Grayscale = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Grayscale.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Grayscale', - - fragmentSource: { - average: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'float average = (color.r + color.b + color.g) / 3.0;\n' + - 'gl_FragColor = vec4(average, average, average, color.a);\n' + - '}', - lightness: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform int uMode;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 col = texture2D(uTexture, vTexCoord);\n' + - 'float average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\n' + - 'gl_FragColor = vec4(average, average, average, col.a);\n' + - '}', - luminosity: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform int uMode;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 col = texture2D(uTexture, vTexCoord);\n' + - 'float average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\n' + - 'gl_FragColor = vec4(average, average, average, col.a);\n' + - '}', - }, - - - /** - * Grayscale mode, between 'average', 'lightness', 'luminosity' - * @param {String} type - * @default - */ - mode: 'average', - - mainParameter: 'mode', - - /** - * Apply the Grayscale operation to a Uint8Array representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8Array to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, i, - len = data.length, value, - mode = this.mode; - for (i = 0; i < len; i += 4) { - if (mode === 'average') { - value = (data[i] + data[i + 1] + data[i + 2]) / 3; - } - else if (mode === 'lightness') { - value = (Math.min(data[i], data[i + 1], data[i + 2]) + - Math.max(data[i], data[i + 1], data[i + 2])) / 2; - } - else if (mode === 'luminosity') { - value = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2]; - } - data[i] = value; - data[i + 1] = value; - data[i + 2] = value; - } - }, - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - var cacheKey = this.type + '_' + this.mode; - if (!options.programCache.hasOwnProperty(cacheKey)) { - var shaderSource = this.fragmentSource[this.mode]; - options.programCache[cacheKey] = this.createProgram(options.context, shaderSource); - } - return options.programCache[cacheKey]; - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uMode: gl.getUniformLocation(program, 'uMode'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - // default average mode. - var mode = 1; - gl.uniform1i(uniformLocations.uMode, mode); - }, - - /** - * Grayscale filter isNeutralState implementation - * The filter is never neutral - * on the image - **/ - isNeutralState: function() { - return false; - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Grayscale} Instance of fabric.Image.filters.Grayscale - */ - fabric.Image.filters.Grayscale.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Invert filter class - * @class fabric.Image.filters.Invert - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Invert(); - * object.filters.push(filter); - * object.applyFilters(canvas.renderAll.bind(canvas)); - */ - filters.Invert = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Invert.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Invert', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform int uInvert;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'if (uInvert == 1) {\n' + - 'gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\n' + - '} else {\n' + - 'gl_FragColor = color;\n' + - '}\n' + - '}', - - /** - * Filter invert. if false, does nothing - * @param {Boolean} invert - * @default - */ - invert: true, - - mainParameter: 'invert', - - /** - * Apply the Invert operation to a Uint8Array representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8Array to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, i, - len = data.length; - for (i = 0; i < len; i += 4) { - data[i] = 255 - data[i]; - data[i + 1] = 255 - data[i + 1]; - data[i + 2] = 255 - data[i + 2]; - } - }, - - /** - * Invert filter isNeutralState implementation - * Used only in image applyFilters to discard filters that will not have an effect - * on the image - * @param {Object} options - **/ - isNeutralState: function() { - return !this.invert; - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uInvert: gl.getUniformLocation(program, 'uInvert'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1i(uniformLocations.uInvert, this.invert); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Invert} Instance of fabric.Image.filters.Invert - */ - fabric.Image.filters.Invert.fromObject = fabric.Image.filters.BaseFilter.fromObject; - - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Noise filter class - * @class fabric.Image.filters.Noise - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Noise#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Noise({ - * noise: 700 - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - filters.Noise = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Noise.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Noise', - - /** - * Fragment source for the noise program - */ - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uStepH;\n' + - 'uniform float uNoise;\n' + - 'uniform float uSeed;\n' + - 'varying vec2 vTexCoord;\n' + - 'float rand(vec2 co, float seed, float vScale) {\n' + - 'return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\n' + - '}\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * Describe the property that is the filter parameter - * @param {String} m - * @default - */ - mainParameter: 'noise', - - /** - * Noise value, from - * @param {Number} noise - * @default - */ - noise: 0, - - /** - * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - if (this.noise === 0) { - return; - } - var imageData = options.imageData, - data = imageData.data, i, len = data.length, - noise = this.noise, rand; - - for (i = 0, len = data.length; i < len; i += 4) { - - rand = (0.5 - Math.random()) * noise; - - data[i] += rand; - data[i + 1] += rand; - data[i + 2] += rand; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uNoise: gl.getUniformLocation(program, 'uNoise'), - uSeed: gl.getUniformLocation(program, 'uSeed'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uNoise, this.noise / 255); - gl.uniform1f(uniformLocations.uSeed, Math.random()); - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return extend(this.callSuper('toObject'), { - noise: this.noise - }); - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Noise} Instance of fabric.Image.filters.Noise - */ - fabric.Image.filters.Noise.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Pixelate filter class - * @class fabric.Image.filters.Pixelate - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Pixelate#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Pixelate({ - * blocksize: 8 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Pixelate = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Pixelate.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Pixelate', - - blocksize: 4, - - mainParameter: 'blocksize', - - /** - * Fragment source for the Pixelate program - */ - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uBlocksize;\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'float blockW = uBlocksize * uStepW;\n' + - 'float blockH = uBlocksize * uStepW;\n' + - 'int posX = int(vTexCoord.x / blockW);\n' + - 'int posY = int(vTexCoord.y / blockH);\n' + - 'float fposX = float(posX);\n' + - 'float fposY = float(posY);\n' + - 'vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\n' + - 'vec4 color = texture2D(uTexture, squareCoords);\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * Apply the Pixelate operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, - iLen = imageData.height, - jLen = imageData.width, - index, i, j, r, g, b, a, - _i, _j, _iLen, _jLen; - - for (i = 0; i < iLen; i += this.blocksize) { - for (j = 0; j < jLen; j += this.blocksize) { - - index = (i * 4) * jLen + (j * 4); - - r = data[index]; - g = data[index + 1]; - b = data[index + 2]; - a = data[index + 3]; - - _iLen = Math.min(i + this.blocksize, iLen); - _jLen = Math.min(j + this.blocksize, jLen); - for (_i = i; _i < _iLen; _i++) { - for (_j = j; _j < _jLen; _j++) { - index = (_i * 4) * jLen + (_j * 4); - data[index] = r; - data[index + 1] = g; - data[index + 2] = b; - data[index + 3] = a; - } - } - } - } - }, - - /** - * Indicate when the filter is not gonna apply changes to the image - **/ - isNeutralState: function() { - return this.blocksize === 1; - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uBlocksize: gl.getUniformLocation(program, 'uBlocksize'), - uStepW: gl.getUniformLocation(program, 'uStepW'), - uStepH: gl.getUniformLocation(program, 'uStepH'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uBlocksize, this.blocksize); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Pixelate} Instance of fabric.Image.filters.Pixelate - */ - fabric.Image.filters.Pixelate.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Remove white filter class - * @class fabric.Image.filters.RemoveColor - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.RemoveColor#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.RemoveColor({ - * threshold: 0.2, - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - filters.RemoveColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.RemoveColor.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'RemoveColor', - - /** - * Color to remove, in any format understood by fabric.Color. - * @param {String} type - * @default - */ - color: '#FFFFFF', - - /** - * Fragment source for the brightness program - */ - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform vec4 uLow;\n' + - 'uniform vec4 uHigh;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'gl_FragColor = texture2D(uTexture, vTexCoord);\n' + - 'if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\n' + - 'gl_FragColor.a = 0.0;\n' + - '}\n' + - '}', - - /** - * distance to actual color, as value up or down from each r,g,b - * between 0 and 1 - **/ - distance: 0.02, - - /** - * For color to remove inside distance, use alpha channel for a smoother deletion - * NOT IMPLEMENTED YET - **/ - useAlpha: false, - - /** - * Constructor - * @memberOf fabric.Image.filters.RemoveWhite.prototype - * @param {Object} [options] Options object - * @param {Number} [options.color=#RRGGBB] Threshold value - * @param {Number} [options.distance=10] Distance value - */ - - /** - * Applies filter to canvas element - * @param {Object} canvasEl Canvas element to apply filter to - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, i, - distance = this.distance * 255, - r, g, b, - source = new fabric.Color(this.color).getSource(), - lowC = [ - source[0] - distance, - source[1] - distance, - source[2] - distance, - ], - highC = [ - source[0] + distance, - source[1] + distance, - source[2] + distance, - ]; - - - for (i = 0; i < data.length; i += 4) { - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - - if (r > lowC[0] && - g > lowC[1] && - b > lowC[2] && - r < highC[0] && - g < highC[1] && - b < highC[2]) { - data[i + 3] = 0; - } - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uLow: gl.getUniformLocation(program, 'uLow'), - uHigh: gl.getUniformLocation(program, 'uHigh'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - var source = new fabric.Color(this.color).getSource(), - distance = parseFloat(this.distance), - lowC = [ - 0 + source[0] / 255 - distance, - 0 + source[1] / 255 - distance, - 0 + source[2] / 255 - distance, - 1 - ], - highC = [ - source[0] / 255 + distance, - source[1] / 255 + distance, - source[2] / 255 + distance, - 1 - ]; - gl.uniform4fv(uniformLocations.uLow, lowC); - gl.uniform4fv(uniformLocations.uHigh, highC); - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return extend(this.callSuper('toObject'), { - color: this.color, - distance: this.distance - }); - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.RemoveColor} Instance of fabric.Image.filters.RemoveWhite - */ - fabric.Image.filters.RemoveColor.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - var matrices = { - Brownie: [ - 0.59970,0.34553,-0.27082,0,0.186, - -0.03770,0.86095,0.15059,0,-0.1449, - 0.24113,-0.07441,0.44972,0,-0.02965, - 0,0,0,1,0 - ], - Vintage: [ - 0.62793,0.32021,-0.03965,0,0.03784, - 0.02578,0.64411,0.03259,0,0.02926, - 0.04660,-0.08512,0.52416,0,0.02023, - 0,0,0,1,0 - ], - Kodachrome: [ - 1.12855,-0.39673,-0.03992,0,0.24991, - -0.16404,1.08352,-0.05498,0,0.09698, - -0.16786,-0.56034,1.60148,0,0.13972, - 0,0,0,1,0 - ], - Technicolor: [ - 1.91252,-0.85453,-0.09155,0,0.04624, - -0.30878,1.76589,-0.10601,0,-0.27589, - -0.23110,-0.75018,1.84759,0,0.12137, - 0,0,0,1,0 - ], - Polaroid: [ - 1.438,-0.062,-0.062,0,0, - -0.122,1.378,-0.122,0,0, - -0.016,-0.016,1.483,0,0, - 0,0,0,1,0 - ], - Sepia: [ - 0.393, 0.769, 0.189, 0, 0, - 0.349, 0.686, 0.168, 0, 0, - 0.272, 0.534, 0.131, 0, 0, - 0, 0, 0, 1, 0 - ], - BlackWhite: [ - 1.5, 1.5, 1.5, 0, -1, - 1.5, 1.5, 1.5, 0, -1, - 1.5, 1.5, 1.5, 0, -1, - 0, 0, 0, 1, 0, - ] - }; - - for (var key in matrices) { - filters[key] = createClass(filters.ColorMatrix, /** @lends fabric.Image.filters.Sepia.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: key, - - /** - * Colormatrix for the effect - * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning - * outside the -1, 1 range. - * @param {Array} matrix array of 20 numbers. - * @default - */ - matrix: matrices[key], - - /** - * Lock the matrix export for this kind of static, parameter less filters. - */ - mainParameter: false, - /** - * Lock the colormatrix on the color part, skipping alpha - */ - colorsOnly: true, - - }); - fabric.Image.filters[key].fromObject = fabric.Image.filters.BaseFilter.fromObject; - } -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - 'use strict'; - - var fabric = global.fabric, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Color Blend filter class - * @class fabric.Image.filter.BlendColor - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @example - * var filter = new fabric.Image.filters.BlendColor({ - * color: '#000', - * mode: 'multiply' - * }); - * - * var filter = new fabric.Image.filters.BlendImage({ - * image: fabricImageObject, - * mode: 'multiply', - * alpha: 0.5 - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - - filters.BlendColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blend.prototype */ { - type: 'BlendColor', - - /** - * Color to make the blend operation with. default to a reddish color since black or white - * gives always strong result. - **/ - color: '#F95C63', - - /** - * Blend mode for the filter: one of multiply, add, diff, screen, subtract, - * darken, lighten, overlay, exclusion, tint. - **/ - mode: 'multiply', - - /** - * alpha value. represent the strength of the blend color operation. - **/ - alpha: 1, - - /** - * Fragment source for the Multiply program - */ - fragmentSource: { - multiply: 'gl_FragColor.rgb *= uColor.rgb;\n', - screen: 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\n', - add: 'gl_FragColor.rgb += uColor.rgb;\n', - diff: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\n', - subtract: 'gl_FragColor.rgb -= uColor.rgb;\n', - lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\n', - darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\n', - exclusion: 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\n', - overlay: 'if (uColor.r < 0.5) {\n' + - 'gl_FragColor.r *= 2.0 * uColor.r;\n' + - '} else {\n' + - 'gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n' + - '}\n' + - 'if (uColor.g < 0.5) {\n' + - 'gl_FragColor.g *= 2.0 * uColor.g;\n' + - '} else {\n' + - 'gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n' + - '}\n' + - 'if (uColor.b < 0.5) {\n' + - 'gl_FragColor.b *= 2.0 * uColor.b;\n' + - '} else {\n' + - 'gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n' + - '}\n', - tint: 'gl_FragColor.rgb *= (1.0 - uColor.a);\n' + - 'gl_FragColor.rgb += uColor.rgb;\n', - }, - - /** - * build the fragment source for the filters, joining the common part with - * the specific one. - * @param {String} mode the mode of the filter, a key of this.fragmentSource - * @return {String} the source to be compiled - * @private - */ - buildSource: function(mode) { - return 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform vec4 uColor;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'gl_FragColor = color;\n' + - 'if (color.a > 0.0) {\n' + - this.fragmentSource[mode] + - '}\n' + - '}'; - }, - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - var cacheKey = this.type + '_' + this.mode, shaderSource; - if (!options.programCache.hasOwnProperty(cacheKey)) { - shaderSource = this.buildSource(this.mode); - options.programCache[cacheKey] = this.createProgram(options.context, shaderSource); - } - return options.programCache[cacheKey]; - }, - - /** - * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, iLen = data.length, - tr, tg, tb, - r, g, b, - source, alpha1 = 1 - this.alpha; - - source = new fabric.Color(this.color).getSource(); - tr = source[0] * this.alpha; - tg = source[1] * this.alpha; - tb = source[2] * this.alpha; - - for (var i = 0; i < iLen; i += 4) { - - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - - switch (this.mode) { - case 'multiply': - data[i] = r * tr / 255; - data[i + 1] = g * tg / 255; - data[i + 2] = b * tb / 255; - break; - case 'screen': - data[i] = 255 - (255 - r) * (255 - tr) / 255; - data[i + 1] = 255 - (255 - g) * (255 - tg) / 255; - data[i + 2] = 255 - (255 - b) * (255 - tb) / 255; - break; - case 'add': - data[i] = r + tr; - data[i + 1] = g + tg; - data[i + 2] = b + tb; - break; - case 'diff': - case 'difference': - data[i] = Math.abs(r - tr); - data[i + 1] = Math.abs(g - tg); - data[i + 2] = Math.abs(b - tb); - break; - case 'subtract': - data[i] = r - tr; - data[i + 1] = g - tg; - data[i + 2] = b - tb; - break; - case 'darken': - data[i] = Math.min(r, tr); - data[i + 1] = Math.min(g, tg); - data[i + 2] = Math.min(b, tb); - break; - case 'lighten': - data[i] = Math.max(r, tr); - data[i + 1] = Math.max(g, tg); - data[i + 2] = Math.max(b, tb); - break; - case 'overlay': - data[i] = tr < 128 ? (2 * r * tr / 255) : (255 - 2 * (255 - r) * (255 - tr) / 255); - data[i + 1] = tg < 128 ? (2 * g * tg / 255) : (255 - 2 * (255 - g) * (255 - tg) / 255); - data[i + 2] = tb < 128 ? (2 * b * tb / 255) : (255 - 2 * (255 - b) * (255 - tb) / 255); - break; - case 'exclusion': - data[i] = tr + r - ((2 * tr * r) / 255); - data[i + 1] = tg + g - ((2 * tg * g) / 255); - data[i + 2] = tb + b - ((2 * tb * b) / 255); - break; - case 'tint': - data[i] = tr + r * alpha1; - data[i + 1] = tg + g * alpha1; - data[i + 2] = tb + b * alpha1; - } - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uColor: gl.getUniformLocation(program, 'uColor'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - var source = new fabric.Color(this.color).getSource(); - source[0] = this.alpha * source[0] / 255; - source[1] = this.alpha * source[1] / 255; - source[2] = this.alpha * source[2] / 255; - source[3] = this.alpha; - gl.uniform4fv(uniformLocations.uColor, source); - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return { - type: this.type, - color: this.color, - mode: this.mode, - alpha: this.alpha - }; - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.BlendColor} Instance of fabric.Image.filters.BlendColor - */ - fabric.Image.filters.BlendColor.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - 'use strict'; - - var fabric = global.fabric, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Image Blend filter class - * @class fabric.Image.filter.BlendImage - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @example - * var filter = new fabric.Image.filters.BlendColor({ - * color: '#000', - * mode: 'multiply' - * }); - * - * var filter = new fabric.Image.filters.BlendImage({ - * image: fabricImageObject, - * mode: 'multiply', - * alpha: 0.5 - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - - filters.BlendImage = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.BlendImage.prototype */ { - type: 'BlendImage', - - /** - * Color to make the blend operation with. default to a reddish color since black or white - * gives always strong result. - **/ - image: null, - - /** - * Blend mode for the filter: one of multiply, add, diff, screen, subtract, - * darken, lighten, overlay, exclusion, tint. - **/ - mode: 'multiply', - - /** - * alpha value. represent the strength of the blend image operation. - * not implemented. - **/ - alpha: 1, - - vertexSource: 'attribute vec2 aPosition;\n' + - 'varying vec2 vTexCoord;\n' + - 'varying vec2 vTexCoord2;\n' + - 'uniform mat3 uTransformMatrix;\n' + - 'void main() {\n' + - 'vTexCoord = aPosition;\n' + - 'vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\n' + - 'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n' + - '}', - - /** - * Fragment source for the Multiply program - */ - fragmentSource: { - multiply: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform sampler2D uImage;\n' + - 'uniform vec4 uColor;\n' + - 'varying vec2 vTexCoord;\n' + - 'varying vec2 vTexCoord2;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'vec4 color2 = texture2D(uImage, vTexCoord2);\n' + - 'color.rgba *= color2.rgba;\n' + - 'gl_FragColor = color;\n' + - '}', - mask: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform sampler2D uImage;\n' + - 'uniform vec4 uColor;\n' + - 'varying vec2 vTexCoord;\n' + - 'varying vec2 vTexCoord2;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'vec4 color2 = texture2D(uImage, vTexCoord2);\n' + - 'color.a = color2.a;\n' + - 'gl_FragColor = color;\n' + - '}', - }, - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - var cacheKey = this.type + '_' + this.mode; - var shaderSource = this.fragmentSource[this.mode]; - if (!options.programCache.hasOwnProperty(cacheKey)) { - options.programCache[cacheKey] = this.createProgram(options.context, shaderSource); - } - return options.programCache[cacheKey]; - }, - - applyToWebGL: function(options) { - // load texture to blend. - var gl = options.context, - texture = this.createTexture(options.filterBackend, this.image); - this.bindAdditionalTexture(gl, texture, gl.TEXTURE1); - this.callSuper('applyToWebGL', options); - this.unbindAdditionalTexture(gl, gl.TEXTURE1); - }, - - createTexture: function(backend, image) { - return backend.getCachedTexture(image.cacheKey, image._element); - }, - - /** - * Calculate a transformMatrix to adapt the image to blend over - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - calculateMatrix: function() { - var image = this.image, - width = image._element.width, - height = image._element.height; - return [ - 1 / image.scaleX, 0, 0, - 0, 1 / image.scaleY, 0, - -image.left / width, -image.top / height, 1 - ]; - }, - - /** - * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - resources = options.filterBackend.resources, - data = imageData.data, iLen = data.length, - width = imageData.width, - height = imageData.height, - tr, tg, tb, ta, - r, g, b, a, - canvas1, context, image = this.image, blendData; - - if (!resources.blendImage) { - resources.blendImage = fabric.util.createCanvasElement(); - } - canvas1 = resources.blendImage; - context = canvas1.getContext('2d'); - if (canvas1.width !== width || canvas1.height !== height) { - canvas1.width = width; - canvas1.height = height; - } - else { - context.clearRect(0, 0, width, height); - } - context.setTransform(image.scaleX, 0, 0, image.scaleY, image.left, image.top); - context.drawImage(image._element, 0, 0, width, height); - blendData = context.getImageData(0, 0, width, height).data; - for (var i = 0; i < iLen; i += 4) { - - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - a = data[i + 3]; - - tr = blendData[i]; - tg = blendData[i + 1]; - tb = blendData[i + 2]; - ta = blendData[i + 3]; - - switch (this.mode) { - case 'multiply': - data[i] = r * tr / 255; - data[i + 1] = g * tg / 255; - data[i + 2] = b * tb / 255; - data[i + 3] = a * ta / 255; - break; - case 'mask': - data[i + 3] = ta; - break; - } - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uTransformMatrix: gl.getUniformLocation(program, 'uTransformMatrix'), - uImage: gl.getUniformLocation(program, 'uImage'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - var matrix = this.calculateMatrix(); - gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1. - gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix); - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return { - type: this.type, - image: this.image && this.image.toObject(), - mode: this.mode, - alpha: this.alpha - }; - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} callback to be invoked after filter creation - * @return {fabric.Image.filters.BlendImage} Instance of fabric.Image.filters.BlendImage - */ - fabric.Image.filters.BlendImage.fromObject = function(object, callback) { - fabric.Image.fromObject(object.image, function(image) { - var options = fabric.util.object.clone(object); - options.image = image; - callback(new fabric.Image.filters.BlendImage(options)); - }); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), pow = Math.pow, floor = Math.floor, - sqrt = Math.sqrt, abs = Math.abs, round = Math.round, sin = Math.sin, - ceil = Math.ceil, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Resize image filter class - * @class fabric.Image.filters.Resize - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Resize(); - * object.filters.push(filter); - * object.applyFilters(canvas.renderAll.bind(canvas)); - */ - filters.Resize = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Resize.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Resize', - - /** - * Resize type - * for webgl resizeType is just lanczos, for canvas2d can be: - * bilinear, hermite, sliceHack, lanczos. - * @param {String} resizeType - * @default - */ - resizeType: 'hermite', - - /** - * Scale factor for resizing, x axis - * @param {Number} scaleX - * @default - */ - scaleX: 1, - - /** - * Scale factor for resizing, y axis - * @param {Number} scaleY - * @default - */ - scaleY: 1, - - /** - * LanczosLobes parameter for lanczos filter, valid for resizeType lanczos - * @param {Number} lanczosLobes - * @default - */ - lanczosLobes: 3, - - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uDelta: gl.getUniformLocation(program, 'uDelta'), - uTaps: gl.getUniformLocation(program, 'uTaps'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform2fv(uniformLocations.uDelta, this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height]); - gl.uniform1fv(uniformLocations.uTaps, this.taps); - }, - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - var filterWindow = this.getFilterWindow(), cacheKey = this.type + '_' + filterWindow; - if (!options.programCache.hasOwnProperty(cacheKey)) { - var fragmentShader = this.generateShader(filterWindow); - options.programCache[cacheKey] = this.createProgram(options.context, fragmentShader); - } - return options.programCache[cacheKey]; - }, - - getFilterWindow: function() { - var scale = this.tempScale; - return Math.ceil(this.lanczosLobes / scale); - }, - - getTaps: function() { - var lobeFunction = this.lanczosCreate(this.lanczosLobes), scale = this.tempScale, - filterWindow = this.getFilterWindow(), taps = new Array(filterWindow); - for (var i = 1; i <= filterWindow; i++) { - taps[i - 1] = lobeFunction(i * scale); - } - return taps; - }, - - /** - * Generate vertex and shader sources from the necessary steps numbers - * @param {Number} filterWindow - */ - generateShader: function(filterWindow) { - var offsets = new Array(filterWindow), - fragmentShader = this.fragmentSourceTOP, filterWindow; - - for (var i = 1; i <= filterWindow; i++) { - offsets[i - 1] = i + '.0 * uDelta'; - } - - fragmentShader += 'uniform float uTaps[' + filterWindow + '];\n'; - fragmentShader += 'void main() {\n'; - fragmentShader += ' vec4 color = texture2D(uTexture, vTexCoord);\n'; - fragmentShader += ' float sum = 1.0;\n'; - - offsets.forEach(function(offset, i) { - fragmentShader += ' color += texture2D(uTexture, vTexCoord + ' + offset + ') * uTaps[' + i + '];\n'; - fragmentShader += ' color += texture2D(uTexture, vTexCoord - ' + offset + ') * uTaps[' + i + '];\n'; - fragmentShader += ' sum += 2.0 * uTaps[' + i + '];\n'; - }); - fragmentShader += ' gl_FragColor = color / sum;\n'; - fragmentShader += '}'; - return fragmentShader; - }, - - fragmentSourceTOP: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform vec2 uDelta;\n' + - 'varying vec2 vTexCoord;\n', - - /** - * Apply the resize filter to the image - * Determines whether to use WebGL or Canvas2D based on the options.webgl flag. - * - * @param {Object} options - * @param {Number} options.passes The number of filters remaining to be executed - * @param {Boolean} options.webgl Whether to use webgl to render the filter. - * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. - * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - applyTo: function(options) { - if (options.webgl) { - options.passes++; - this.width = options.sourceWidth; - this.horizontal = true; - this.dW = Math.round(this.width * this.scaleX); - this.dH = options.sourceHeight; - this.tempScale = this.dW / this.width; - this.taps = this.getTaps(); - options.destinationWidth = this.dW; - this._setupFrameBuffer(options); - this.applyToWebGL(options); - this._swapTextures(options); - options.sourceWidth = options.destinationWidth; - - this.height = options.sourceHeight; - this.horizontal = false; - this.dH = Math.round(this.height * this.scaleY); - this.tempScale = this.dH / this.height; - this.taps = this.getTaps(); - options.destinationHeight = this.dH; - this._setupFrameBuffer(options); - this.applyToWebGL(options); - this._swapTextures(options); - options.sourceHeight = options.destinationHeight; - } - else { - this.applyTo2d(options); - } - }, - - isNeutralState: function() { - return this.scaleX === 1 && this.scaleY === 1; - }, - - lanczosCreate: function(lobes) { - return function(x) { - if (x >= lobes || x <= -lobes) { - return 0.0; - } - if (x < 1.19209290E-07 && x > -1.19209290E-07) { - return 1.0; - } - x *= Math.PI; - var xx = x / lobes; - return (sin(x) / x) * sin(xx) / xx; - }; - }, - - /** - * Applies filter to canvas element - * @memberOf fabric.Image.filters.Resize.prototype - * @param {Object} canvasEl Canvas element to apply filter to - * @param {Number} scaleX - * @param {Number} scaleY - */ - applyTo2d: function(options) { - var imageData = options.imageData, - scaleX = this.scaleX, - scaleY = this.scaleY; - - this.rcpScaleX = 1 / scaleX; - this.rcpScaleY = 1 / scaleY; - - var oW = imageData.width, oH = imageData.height, - dW = round(oW * scaleX), dH = round(oH * scaleY), - newData; - - if (this.resizeType === 'sliceHack') { - newData = this.sliceByTwo(options, oW, oH, dW, dH); - } - else if (this.resizeType === 'hermite') { - newData = this.hermiteFastResize(options, oW, oH, dW, dH); - } - else if (this.resizeType === 'bilinear') { - newData = this.bilinearFiltering(options, oW, oH, dW, dH); - } - else if (this.resizeType === 'lanczos') { - newData = this.lanczosResize(options, oW, oH, dW, dH); - } - options.imageData = newData; - }, - - /** - * Filter sliceByTwo - * @param {Object} canvasEl Canvas element to apply filter to - * @param {Number} oW Original Width - * @param {Number} oH Original Height - * @param {Number} dW Destination Width - * @param {Number} dH Destination Height - * @returns {ImageData} - */ - sliceByTwo: function(options, oW, oH, dW, dH) { - var imageData = options.imageData, - mult = 0.5, doneW = false, doneH = false, stepW = oW * mult, - stepH = oH * mult, resources = fabric.filterBackend.resources, - tmpCanvas, ctx, sX = 0, sY = 0, dX = oW, dY = 0; - if (!resources.sliceByTwo) { - resources.sliceByTwo = document.createElement('canvas'); - } - tmpCanvas = resources.sliceByTwo; - if (tmpCanvas.width < oW * 1.5 || tmpCanvas.height < oH) { - tmpCanvas.width = oW * 1.5; - tmpCanvas.height = oH; - } - ctx = tmpCanvas.getContext('2d'); - ctx.clearRect(0, 0, oW * 1.5, oH); - ctx.putImageData(imageData, 0, 0); - - dW = floor(dW); - dH = floor(dH); - - while (!doneW || !doneH) { - oW = stepW; - oH = stepH; - if (dW < floor(stepW * mult)) { - stepW = floor(stepW * mult); - } - else { - stepW = dW; - doneW = true; - } - if (dH < floor(stepH * mult)) { - stepH = floor(stepH * mult); - } - else { - stepH = dH; - doneH = true; - } - ctx.drawImage(tmpCanvas, sX, sY, oW, oH, dX, dY, stepW, stepH); - sX = dX; - sY = dY; - dY += stepH; - } - return ctx.getImageData(sX, sY, dW, dH); - }, - - /** - * Filter lanczosResize - * @param {Object} canvasEl Canvas element to apply filter to - * @param {Number} oW Original Width - * @param {Number} oH Original Height - * @param {Number} dW Destination Width - * @param {Number} dH Destination Height - * @returns {ImageData} - */ - lanczosResize: function(options, oW, oH, dW, dH) { - - function process(u) { - var v, i, weight, idx, a, red, green, - blue, alpha, fX, fY; - center.x = (u + 0.5) * ratioX; - icenter.x = floor(center.x); - for (v = 0; v < dH; v++) { - center.y = (v + 0.5) * ratioY; - icenter.y = floor(center.y); - a = 0; red = 0; green = 0; blue = 0; alpha = 0; - for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) { - if (i < 0 || i >= oW) { - continue; - } - fX = floor(1000 * abs(i - center.x)); - if (!cacheLanc[fX]) { - cacheLanc[fX] = { }; - } - for (var j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) { - if (j < 0 || j >= oH) { - continue; - } - fY = floor(1000 * abs(j - center.y)); - if (!cacheLanc[fX][fY]) { - cacheLanc[fX][fY] = lanczos(sqrt(pow(fX * rcpRatioX, 2) + pow(fY * rcpRatioY, 2)) / 1000); - } - weight = cacheLanc[fX][fY]; - if (weight > 0) { - idx = (j * oW + i) * 4; - a += weight; - red += weight * srcData[idx]; - green += weight * srcData[idx + 1]; - blue += weight * srcData[idx + 2]; - alpha += weight * srcData[idx + 3]; - } - } - } - idx = (v * dW + u) * 4; - destData[idx] = red / a; - destData[idx + 1] = green / a; - destData[idx + 2] = blue / a; - destData[idx + 3] = alpha / a; - } - - if (++u < dW) { - return process(u); - } - else { - return destImg; - } - } - - var srcData = options.imageData.data, - destImg = options.ctx.createImageData(dW, dH), - destData = destImg.data, - lanczos = this.lanczosCreate(this.lanczosLobes), - ratioX = this.rcpScaleX, ratioY = this.rcpScaleY, - rcpRatioX = 2 / this.rcpScaleX, rcpRatioY = 2 / this.rcpScaleY, - range2X = ceil(ratioX * this.lanczosLobes / 2), - range2Y = ceil(ratioY * this.lanczosLobes / 2), - cacheLanc = { }, center = { }, icenter = { }; - - return process(0); - }, - - /** - * bilinearFiltering - * @param {Object} canvasEl Canvas element to apply filter to - * @param {Number} oW Original Width - * @param {Number} oH Original Height - * @param {Number} dW Destination Width - * @param {Number} dH Destination Height - * @returns {ImageData} - */ - bilinearFiltering: function(options, oW, oH, dW, dH) { - var a, b, c, d, x, y, i, j, xDiff, yDiff, chnl, - color, offset = 0, origPix, ratioX = this.rcpScaleX, - ratioY = this.rcpScaleY, - w4 = 4 * (oW - 1), img = options.imageData, - pixels = img.data, destImage = options.ctx.createImageData(dW, dH), - destPixels = destImage.data; - for (i = 0; i < dH; i++) { - for (j = 0; j < dW; j++) { - x = floor(ratioX * j); - y = floor(ratioY * i); - xDiff = ratioX * j - x; - yDiff = ratioY * i - y; - origPix = 4 * (y * oW + x); - - for (chnl = 0; chnl < 4; chnl++) { - a = pixels[origPix + chnl]; - b = pixels[origPix + 4 + chnl]; - c = pixels[origPix + w4 + chnl]; - d = pixels[origPix + w4 + 4 + chnl]; - color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) + - c * yDiff * (1 - xDiff) + d * xDiff * yDiff; - destPixels[offset++] = color; - } - } - } - return destImage; - }, - - /** - * hermiteFastResize - * @param {Object} canvasEl Canvas element to apply filter to - * @param {Number} oW Original Width - * @param {Number} oH Original Height - * @param {Number} dW Destination Width - * @param {Number} dH Destination Height - * @returns {ImageData} - */ - hermiteFastResize: function(options, oW, oH, dW, dH) { - var ratioW = this.rcpScaleX, ratioH = this.rcpScaleY, - ratioWHalf = ceil(ratioW / 2), - ratioHHalf = ceil(ratioH / 2), - img = options.imageData, data = img.data, - img2 = options.ctx.createImageData(dW, dH), data2 = img2.data; - for (var j = 0; j < dH; j++) { - for (var i = 0; i < dW; i++) { - var x2 = (i + j * dW) * 4, weight = 0, weights = 0, weightsAlpha = 0, - gxR = 0, gxG = 0, gxB = 0, gxA = 0, centerY = (j + 0.5) * ratioH; - for (var yy = floor(j * ratioH); yy < (j + 1) * ratioH; yy++) { - var dy = abs(centerY - (yy + 0.5)) / ratioHHalf, - centerX = (i + 0.5) * ratioW, w0 = dy * dy; - for (var xx = floor(i * ratioW); xx < (i + 1) * ratioW; xx++) { - var dx = abs(centerX - (xx + 0.5)) / ratioWHalf, - w = sqrt(w0 + dx * dx); - /* eslint-disable max-depth */ - if (w > 1 && w < -1) { - continue; - } - //hermite filter - weight = 2 * w * w * w - 3 * w * w + 1; - if (weight > 0) { - dx = 4 * (xx + yy * oW); - //alpha - gxA += weight * data[dx + 3]; - weightsAlpha += weight; - //colors - if (data[dx + 3] < 255) { - weight = weight * data[dx + 3] / 250; - } - gxR += weight * data[dx]; - gxG += weight * data[dx + 1]; - gxB += weight * data[dx + 2]; - weights += weight; - } - /* eslint-enable max-depth */ - } - } - data2[x2] = gxR / weights; - data2[x2 + 1] = gxG / weights; - data2[x2 + 2] = gxB / weights; - data2[x2 + 3] = gxA / weightsAlpha; - } - } - return img2; - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return { - type: this.type, - scaleX: this.scaleX, - scaleY: this.scaleY, - resizeType: this.resizeType, - lanczosLobes: this.lanczosLobes - }; - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Resize} Instance of fabric.Image.filters.Resize - */ - fabric.Image.filters.Resize.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Contrast filter class - * @class fabric.Image.filters.Contrast - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Contrast#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Contrast({ - * contrast: 0.25 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Contrast = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Contrast.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Contrast', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uContrast;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\n' + - 'color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * contrast value, range from -1 to 1. - * @param {Number} contrast - * @default 0 - */ - contrast: 0, - - mainParameter: 'contrast', - - /** - * Constructor - * @memberOf fabric.Image.filters.Contrast.prototype - * @param {Object} [options] Options object - * @param {Number} [options.contrast=0] Value to contrast the image up (-1...1) - */ - - /** - * Apply the Contrast operation to a Uint8Array representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8Array to be filtered. - */ - applyTo2d: function(options) { - if (this.contrast === 0) { - return; - } - var imageData = options.imageData, i, len, - data = imageData.data, len = data.length, - contrast = Math.floor(this.contrast * 255), - contrastF = 259 * (contrast + 255) / (255 * (259 - contrast)); - - for (i = 0; i < len; i += 4) { - data[i] = contrastF * (data[i] - 128) + 128; - data[i + 1] = contrastF * (data[i + 1] - 128) + 128; - data[i + 2] = contrastF * (data[i + 2] - 128) + 128; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uContrast: gl.getUniformLocation(program, 'uContrast'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uContrast, this.contrast); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Contrast} Instance of fabric.Image.filters.Contrast - */ - fabric.Image.filters.Contrast.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Saturate filter class - * @class fabric.Image.filters.Saturation - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Saturation#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Saturation({ - * saturation: 1 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Saturation = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Saturation.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Saturation', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uSaturation;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'float rgMax = max(color.r, color.g);\n' + - 'float rgbMax = max(rgMax, color.b);\n' + - 'color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\n' + - 'color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\n' + - 'color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * Saturation value, from -1 to 1. - * Increases/decreases the color saturation. - * A value of 0 has no effect. - * - * @param {Number} saturation - * @default - */ - saturation: 0, - - mainParameter: 'saturation', - - /** - * Constructor - * @memberOf fabric.Image.filters.Saturate.prototype - * @param {Object} [options] Options object - * @param {Number} [options.saturate=0] Value to saturate the image (-1...1) - */ - - /** - * Apply the Saturation operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - if (this.saturation === 0) { - return; - } - var imageData = options.imageData, - data = imageData.data, len = data.length, - adjust = -this.saturation, i, max; - - for (i = 0; i < len; i += 4) { - max = Math.max(data[i], data[i + 1], data[i + 2]); - data[i] += max !== data[i] ? (max - data[i]) * adjust : 0; - data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0; - data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uSaturation: gl.getUniformLocation(program, 'uSaturation'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uSaturation, -this.saturation); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Saturation} Instance of fabric.Image.filters.Saturate - */ - fabric.Image.filters.Saturation.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Vibrance filter class - * @class fabric.Image.filters.Vibrance - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Vibrance#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Vibrance({ - * vibrance: 1 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Vibrance = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Vibrance.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Vibrance', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uVibrance;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'float max = max(color.r, max(color.g, color.b));\n' + - 'float avg = (color.r + color.g + color.b) / 3.0;\n' + - 'float amt = (abs(max - avg) * 2.0) * uVibrance;\n' + - 'color.r += max != color.r ? (max - color.r) * amt : 0.00;\n' + - 'color.g += max != color.g ? (max - color.g) * amt : 0.00;\n' + - 'color.b += max != color.b ? (max - color.b) * amt : 0.00;\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * Vibrance value, from -1 to 1. - * Increases/decreases the saturation of more muted colors with less effect on saturated colors. - * A value of 0 has no effect. - * - * @param {Number} vibrance - * @default - */ - vibrance: 0, - - mainParameter: 'vibrance', - - /** - * Constructor - * @memberOf fabric.Image.filters.Vibrance.prototype - * @param {Object} [options] Options object - * @param {Number} [options.vibrance=0] Vibrance value for the image (between -1 and 1) - */ - - /** - * Apply the Vibrance operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - if (this.vibrance === 0) { - return; - } - var imageData = options.imageData, - data = imageData.data, len = data.length, - adjust = -this.vibrance, i, max, avg, amt; - - for (i = 0; i < len; i += 4) { - max = Math.max(data[i], data[i + 1], data[i + 2]); - avg = (data[i] + data[i + 1] + data[i + 2]) / 3; - amt = ((Math.abs(max - avg) * 2 / 255) * adjust); - data[i] += max !== data[i] ? (max - data[i]) * amt : 0; - data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * amt : 0; - data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * amt : 0; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uVibrance: gl.getUniformLocation(program, 'uVibrance'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uVibrance, -this.vibrance); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Vibrance} Instance of fabric.Image.filters.Vibrance - */ - fabric.Image.filters.Vibrance.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Blur filter class - * @class fabric.Image.filters.Blur - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Blur#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Blur({ - * blur: 0.5 - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - filters.Blur = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blur.prototype */ { - - type: 'Blur', - - /* -'gl_FragColor = vec4(0.0);', -'gl_FragColor += texture2D(texture, vTexCoord + -7 * uDelta)*0.0044299121055113265;', -'gl_FragColor += texture2D(texture, vTexCoord + -6 * uDelta)*0.00895781211794;', -'gl_FragColor += texture2D(texture, vTexCoord + -5 * uDelta)*0.0215963866053;', -'gl_FragColor += texture2D(texture, vTexCoord + -4 * uDelta)*0.0443683338718;', -'gl_FragColor += texture2D(texture, vTexCoord + -3 * uDelta)*0.0776744219933;', -'gl_FragColor += texture2D(texture, vTexCoord + -2 * uDelta)*0.115876621105;', -'gl_FragColor += texture2D(texture, vTexCoord + -1 * uDelta)*0.147308056121;', -'gl_FragColor += texture2D(texture, vTexCoord )*0.159576912161;', -'gl_FragColor += texture2D(texture, vTexCoord + 1 * uDelta)*0.147308056121;', -'gl_FragColor += texture2D(texture, vTexCoord + 2 * uDelta)*0.115876621105;', -'gl_FragColor += texture2D(texture, vTexCoord + 3 * uDelta)*0.0776744219933;', -'gl_FragColor += texture2D(texture, vTexCoord + 4 * uDelta)*0.0443683338718;', -'gl_FragColor += texture2D(texture, vTexCoord + 5 * uDelta)*0.0215963866053;', -'gl_FragColor += texture2D(texture, vTexCoord + 6 * uDelta)*0.00895781211794;', -'gl_FragColor += texture2D(texture, vTexCoord + 7 * uDelta)*0.0044299121055113265;', -*/ - - /* eslint-disable max-len */ - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform vec2 uDelta;\n' + - 'varying vec2 vTexCoord;\n' + - 'const float nSamples = 15.0;\n' + - 'vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\n' + - 'float random(vec3 scale) {\n' + - /* use the fragment position for a different seed per-pixel */ - 'return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\n' + - '}\n' + - 'void main() {\n' + - 'vec4 color = vec4(0.0);\n' + - 'float total = 0.0;\n' + - 'float offset = random(v3offset);\n' + - 'for (float t = -nSamples; t <= nSamples; t++) {\n' + - 'float percent = (t + offset - 0.5) / nSamples;\n' + - 'float weight = 1.0 - abs(percent);\n' + - 'color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\n' + - 'total += weight;\n' + - '}\n' + - 'gl_FragColor = color / total;\n' + - '}', - /* eslint-enable max-len */ - - /** - * blur value, in percentage of image dimensions. - * specific to keep the image blur constant at different resolutions - * range between 0 and 1. - */ - blur: 0, - - mainParameter: 'blur', - - applyTo: function(options) { - if (options.webgl) { - // this aspectRatio is used to give the same blur to vertical and horizontal - this.aspectRatio = options.sourceWidth / options.sourceHeight; - options.passes++; - this._setupFrameBuffer(options); - this.horizontal = true; - this.applyToWebGL(options); - this._swapTextures(options); - this._setupFrameBuffer(options); - this.horizontal = false; - this.applyToWebGL(options); - this._swapTextures(options); - } - else { - this.applyTo2d(options); - } - }, - - applyTo2d: function(options) { - // paint canvasEl with current image data. - //options.ctx.putImageData(options.imageData, 0, 0); - options.imageData = this.simpleBlur(options); - }, - - simpleBlur: function(options) { - var resources = options.filterBackend.resources, canvas1, canvas2, - width = options.imageData.width, - height = options.imageData.height; - - if (!resources.blurLayer1) { - resources.blurLayer1 = fabric.util.createCanvasElement(); - resources.blurLayer2 = fabric.util.createCanvasElement(); - } - canvas1 = resources.blurLayer1; - canvas2 = resources.blurLayer2; - if (canvas1.width !== width || canvas1.height !== height) { - canvas2.width = canvas1.width = width; - canvas2.height = canvas1.height = height; - } - var ctx1 = canvas1.getContext('2d'), - ctx2 = canvas2.getContext('2d'), - nSamples = 15, - random, percent, j, i, - blur = this.blur * 0.06 * 0.5; - - // load first canvas - ctx1.putImageData(options.imageData, 0, 0); - ctx2.clearRect(0, 0, width, height); - - for (i = -nSamples; i <= nSamples; i++) { - random = (Math.random() - 0.5) / 4; - percent = i / nSamples; - j = blur * percent * width + random; - ctx2.globalAlpha = 1 - Math.abs(percent); - ctx2.drawImage(canvas1, j, random); - ctx1.drawImage(canvas2, 0, 0); - ctx2.globalAlpha = 1; - ctx2.clearRect(0, 0, canvas2.width, canvas2.height); - } - for (i = -nSamples; i <= nSamples; i++) { - random = (Math.random() - 0.5) / 4; - percent = i / nSamples; - j = blur * percent * height + random; - ctx2.globalAlpha = 1 - Math.abs(percent); - ctx2.drawImage(canvas1, random, j); - ctx1.drawImage(canvas2, 0, 0); - ctx2.globalAlpha = 1; - ctx2.clearRect(0, 0, canvas2.width, canvas2.height); - } - options.ctx.drawImage(canvas1, 0, 0); - var newImageData = options.ctx.getImageData(0, 0, canvas1.width, canvas1.height); - ctx1.globalAlpha = 1; - ctx1.clearRect(0, 0, canvas1.width, canvas1.height); - return newImageData; - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - delta: gl.getUniformLocation(program, 'uDelta'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - var delta = this.chooseRightDelta(); - gl.uniform2fv(uniformLocations.delta, delta); - }, - - /** - * choose right value of image percentage to blur with - * @returns {Array} a numeric array with delta values - */ - chooseRightDelta: function() { - var blurScale = 1, delta = [0, 0], blur; - if (this.horizontal) { - if (this.aspectRatio > 1) { - // image is wide, i want to shrink radius horizontal - blurScale = 1 / this.aspectRatio; - } - } - else { - if (this.aspectRatio < 1) { - // image is tall, i want to shrink radius vertical - blurScale = this.aspectRatio; - } - } - blur = blurScale * this.blur * 0.12; - if (this.horizontal) { - delta[0] = blur; - } - else { - delta[1] = blur; - } - return delta; - }, - }); - - /** - * Deserialize a JSON definition of a BlurFilter into a concrete instance. - */ - filters.Blur.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Gamma filter class - * @class fabric.Image.filters.Gamma - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Gamma#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Gamma({ - * gamma: [1, 0.5, 2.1] - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Gamma = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Gamma.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Gamma', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform vec3 uGamma;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'vec3 correction = (1.0 / uGamma);\n' + - 'color.r = pow(color.r, correction.r);\n' + - 'color.g = pow(color.g, correction.g);\n' + - 'color.b = pow(color.b, correction.b);\n' + - 'gl_FragColor = color;\n' + - 'gl_FragColor.rgb *= color.a;\n' + - '}', - - /** - * Gamma array value, from 0.01 to 2.2. - * @param {Array} gamma - * @default - */ - gamma: [1, 1, 1], - - /** - * Describe the property that is the filter parameter - * @param {String} m - * @default - */ - mainParameter: 'gamma', - - /** - * Constructor - * @param {Object} [options] Options object - */ - initialize: function(options) { - this.gamma = [1, 1, 1]; - filters.BaseFilter.prototype.initialize.call(this, options); - }, - - /** - * Apply the Gamma operation to a Uint8Array representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8Array to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, data = imageData.data, - gamma = this.gamma, len = data.length, - rInv = 1 / gamma[0], gInv = 1 / gamma[1], - bInv = 1 / gamma[2], i; - - if (!this.rVals) { - // eslint-disable-next-line - this.rVals = new Uint8Array(256); - // eslint-disable-next-line - this.gVals = new Uint8Array(256); - // eslint-disable-next-line - this.bVals = new Uint8Array(256); - } - - // This is an optimization - pre-compute a look-up table for each color channel - // instead of performing these pow calls for each pixel in the image. - for (i = 0, len = 256; i < len; i++) { - this.rVals[i] = Math.pow(i / 255, rInv) * 255; - this.gVals[i] = Math.pow(i / 255, gInv) * 255; - this.bVals[i] = Math.pow(i / 255, bInv) * 255; - } - for (i = 0, len = data.length; i < len; i += 4) { - data[i] = this.rVals[data[i]]; - data[i + 1] = this.gVals[data[i + 1]]; - data[i + 2] = this.bVals[data[i + 2]]; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uGamma: gl.getUniformLocation(program, 'uGamma'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform3fv(uniformLocations.uGamma, this.gamma); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Gamma} Instance of fabric.Image.filters.Gamma - */ - fabric.Image.filters.Gamma.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * A container class that knows how to apply a sequence of filters to an input image. - */ - filters.Composed = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Composed.prototype */ { - - type: 'Composed', - - /** - * A non sparse array of filters to apply - */ - subFilters: [], - - /** - * Constructor - * @param {Object} [options] Options object - */ - initialize: function(options) { - this.callSuper('initialize', options); - // create a new array instead mutating the prototype with push - this.subFilters = this.subFilters.slice(0); - }, - - /** - * Apply this container's filters to the input image provided. - * - * @param {Object} options - * @param {Number} options.passes The number of filters remaining to be applied. - */ - applyTo: function(options) { - options.passes += this.subFilters.length - 1; - this.subFilters.forEach(function(filter) { - filter.applyTo(options); - }); - }, - - /** - * Serialize this filter into JSON. - * - * @returns {Object} A JSON representation of this filter. - */ - toObject: function() { - return fabric.util.object.extend(this.callSuper('toObject'), { - subFilters: this.subFilters.map(function(filter) { return filter.toObject(); }), - }); - }, - - isNeutralState: function() { - return !this.subFilters.some(function(filter) { return !filter.isNeutralState(); }); - } - }); - - /** - * Deserialize a JSON definition of a ComposedFilter into a concrete instance. - */ - fabric.Image.filters.Composed.fromObject = function(object, callback) { - var filters = object.subFilters || [], - subFilters = filters.map(function(filter) { - return new fabric.Image.filters[filter.type](filter); - }), - instance = new fabric.Image.filters.Composed({ subFilters: subFilters }); - callback && callback(instance); - return instance; - }; -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * HueRotation filter class - * @class fabric.Image.filters.HueRotation - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.HueRotation#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.HueRotation({ - * rotation: -0.5 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.HueRotation = createClass(filters.ColorMatrix, /** @lends fabric.Image.filters.HueRotation.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'HueRotation', - - /** - * HueRotation value, from -1 to 1. - * the unit is radians - * @param {Number} myParameter - * @default - */ - rotation: 0, - - /** - * Describe the property that is the filter parameter - * @param {String} m - * @default - */ - mainParameter: 'rotation', - - calculateMatrix: function() { - var rad = this.rotation * Math.PI, cos = fabric.util.cos(rad), sin = fabric.util.sin(rad), - aThird = 1 / 3, aThirdSqtSin = Math.sqrt(aThird) * sin, OneMinusCos = 1 - cos; - this.matrix = [ - 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0 - ]; - this.matrix[0] = cos + OneMinusCos / 3; - this.matrix[1] = aThird * OneMinusCos - aThirdSqtSin; - this.matrix[2] = aThird * OneMinusCos + aThirdSqtSin; - this.matrix[5] = aThird * OneMinusCos + aThirdSqtSin; - this.matrix[6] = cos + aThird * OneMinusCos; - this.matrix[7] = aThird * OneMinusCos - aThirdSqtSin; - this.matrix[10] = aThird * OneMinusCos - aThirdSqtSin; - this.matrix[11] = aThird * OneMinusCos + aThirdSqtSin; - this.matrix[12] = cos + aThird * OneMinusCos; - }, - - /** - * HueRotation isNeutralState implementation - * Used only in image applyFilters to discard filters that will not have an effect - * on the image - * @param {Object} options - **/ - isNeutralState: function(options) { - this.calculateMatrix(); - return filters.BaseFilter.prototype.isNeutralState.call(this, options); - }, - - /** - * Apply this filter to the input image data provided. - * - * Determines whether to use WebGL or Canvas2D based on the options.webgl flag. - * - * @param {Object} options - * @param {Number} options.passes The number of filters remaining to be executed - * @param {Boolean} options.webgl Whether to use webgl to render the filter. - * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. - * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - applyTo: function(options) { - this.calculateMatrix(); - filters.BaseFilter.prototype.applyTo.call(this, options); - }, - - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.HueRotation} Instance of fabric.Image.filters.HueRotation - */ - fabric.Image.filters.HueRotation.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - clone = fabric.util.object.clone; - - if (fabric.Text) { - fabric.warn('fabric.Text is already defined'); - return; - } - - var additionalProps = - ('fontFamily fontWeight fontSize text underline overline linethrough' + - ' textAlign fontStyle lineHeight textBackgroundColor charSpacing styles' + - ' direction path pathStartOffset pathSide').split(' '); - - /** - * Text class - * @class fabric.Text - * @extends fabric.Object - * @return {fabric.Text} thisArg - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text} - * @see {@link fabric.Text#initialize} for constructor definition - */ - fabric.Text = fabric.util.createClass(fabric.Object, /** @lends fabric.Text.prototype */ { - - /** - * Properties which when set cause object to change dimensions - * @type Array - * @private - */ - _dimensionAffectingProps: [ - 'fontSize', - 'fontWeight', - 'fontFamily', - 'fontStyle', - 'lineHeight', - 'text', - 'charSpacing', - 'textAlign', - 'styles', - 'path', - 'pathStartOffset', - 'pathSide' - ], - - /** - * @private - */ - _reNewline: /\r?\n/, - - /** - * Use this regular expression to filter for whitespaces that is not a new line. - * Mostly used when text is 'justify' aligned. - * @private - */ - _reSpacesAndTabs: /[ \t\r]/g, - - /** - * Use this regular expression to filter for whitespace that is not a new line. - * Mostly used when text is 'justify' aligned. - * @private - */ - _reSpaceAndTab: /[ \t\r]/, - - /** - * Use this regular expression to filter consecutive groups of non spaces. - * Mostly used when text is 'justify' aligned. - * @private - */ - _reWords: /\S+/g, - - /** - * Type of an object - * @type String - * @default - */ - type: 'text', - - /** - * Font size (in pixels) - * @type Number - * @default - */ - fontSize: 40, - - /** - * Font weight (e.g. bold, normal, 400, 600, 800) - * @type {(Number|String)} - * @default - */ - fontWeight: 'normal', - - /** - * Font family - * @type String - * @default - */ - fontFamily: 'Times New Roman', - - /** - * Text decoration underline. - * @type Boolean - * @default - */ - underline: false, - - /** - * Text decoration overline. - * @type Boolean - * @default - */ - overline: false, - - /** - * Text decoration linethrough. - * @type Boolean - * @default - */ - linethrough: false, - - /** - * Text alignment. Possible values: "left", "center", "right", "justify", - * "justify-left", "justify-center" or "justify-right". - * @type String - * @default - */ - textAlign: 'left', - - /** - * Font style . Possible values: "", "normal", "italic" or "oblique". - * @type String - * @default - */ - fontStyle: 'normal', - - /** - * Line height - * @type Number - * @default - */ - lineHeight: 1.16, - - /** - * Superscript schema object (minimum overlap) - * @type {Object} - * @default - */ - superscript: { - size: 0.60, // fontSize factor - baseline: -0.35 // baseline-shift factor (upwards) - }, - - /** - * Subscript schema object (minimum overlap) - * @type {Object} - * @default - */ - subscript: { - size: 0.60, // fontSize factor - baseline: 0.11 // baseline-shift factor (downwards) - }, - - /** - * Background color of text lines - * @type String - * @default - */ - textBackgroundColor: '', - - /** - * List of properties to consider when checking if - * state of an object is changed ({@link fabric.Object#hasStateChanged}) - * as well as for history (undo/redo) purposes - * @type Array - */ - stateProperties: fabric.Object.prototype.stateProperties.concat(additionalProps), - - /** - * List of properties to consider when checking if cache needs refresh - * @type Array - */ - cacheProperties: fabric.Object.prototype.cacheProperties.concat(additionalProps), - - /** - * When defined, an object is rendered via stroke and this property specifies its color. - * Backwards incompatibility note: This property was named "strokeStyle" until v1.1.6 - * @type String - * @default - */ - stroke: null, - - /** - * Shadow object representing shadow of this shape. - * Backwards incompatibility note: This property was named "textShadow" (String) until v1.2.11 - * @type fabric.Shadow - * @default - */ - shadow: null, - - /** - * fabric.Path that the text should follow. - * since 4.6.0 the path will be drawn automatically. - * if you want to make the path visible, give it a stroke and strokeWidth or fill value - * if you want it to be hidden, assign visible = false to the path. - * This feature is in BETA, and SVG import/export is not yet supported. - * @type fabric.Path - * @example - * var textPath = new fabric.Text('Text on a path', { - * top: 150, - * left: 150, - * textAlign: 'center', - * charSpacing: -50, - * path: new fabric.Path('M 0 0 C 50 -100 150 -100 200 0', { - * strokeWidth: 1, - * visible: false - * }), - * pathSide: 'left', - * pathStartOffset: 0 - * }); - * @default - */ - path: null, - - /** - * Offset amount for text path starting position - * Only used when text has a path - * @type Number - * @default - */ - pathStartOffset: 0, - - /** - * Which side of the path the text should be drawn on. - * Only used when text has a path - * @type {String} 'left|right' - * @default - */ - pathSide: 'left', - - /** - * @private - */ - _fontSizeFraction: 0.222, - - /** - * @private - */ - offsets: { - underline: 0.10, - linethrough: -0.315, - overline: -0.88 - }, - - /** - * Text Line proportion to font Size (in pixels) - * @type Number - * @default - */ - _fontSizeMult: 1.13, - - /** - * additional space between characters - * expressed in thousands of em unit - * @type Number - * @default - */ - charSpacing: 0, - - /** - * Object containing character styles - top-level properties -> line numbers, - * 2nd-level properties - character numbers - * @type Object - * @default - */ - styles: null, - - /** - * Reference to a context to measure text char or couple of chars - * the cacheContext of the canvas will be used or a freshly created one if the object is not on canvas - * once created it will be referenced on fabric._measuringContext to avoid creating a canvas for every - * text object created. - * @type {CanvasRenderingContext2D} - * @default - */ - _measuringContext: null, - - /** - * Baseline shift, styles only, keep at 0 for the main text object - * @type {Number} - * @default - */ - deltaY: 0, - - /** - * WARNING: EXPERIMENTAL. NOT SUPPORTED YET - * determine the direction of the text. - * This has to be set manually together with textAlign and originX for proper - * experience. - * some interesting link for the future - * https://www.w3.org/International/questions/qa-bidi-unicode-controls - * @since 4.5.0 - * @type {String} 'ltr|rtl' - * @default - */ - direction: 'ltr', - - /** - * Array of properties that define a style unit (of 'styles'). - * @type {Array} - * @default - */ - _styleProperties: [ - 'stroke', - 'strokeWidth', - 'fill', - 'fontFamily', - 'fontSize', - 'fontWeight', - 'fontStyle', - 'underline', - 'overline', - 'linethrough', - 'deltaY', - 'textBackgroundColor', - ], - - /** - * contains characters bounding boxes - */ - __charBounds: [], - - /** - * use this size when measuring text. To avoid IE11 rounding errors - * @type {Number} - * @default - * @readonly - * @private - */ - CACHE_FONT_SIZE: 400, - - /** - * contains the min text width to avoid getting 0 - * @type {Number} - * @default - */ - MIN_TEXT_WIDTH: 2, - - /** - * Constructor - * @param {String} text Text string - * @param {Object} [options] Options object - * @return {fabric.Text} thisArg - */ - initialize: function(text, options) { - this.styles = options ? (options.styles || { }) : { }; - this.text = text; - this.__skipDimension = true; - this.callSuper('initialize', options); - if (this.path) { - this.setPathInfo(); - } - this.__skipDimension = false; - this.initDimensions(); - this.setCoords(); - this.setupState({ propertySet: '_dimensionAffectingProps' }); - }, - - /** - * If text has a path, it will add the extra information needed - * for path and text calculations - * @return {fabric.Text} thisArg - */ - setPathInfo: function() { - var path = this.path; - if (path) { - path.segmentsInfo = fabric.util.getPathSegmentsInfo(path.path); - } - }, - - /** - * Return a context for measurement of text string. - * if created it gets stored for reuse - * @param {String} text Text string - * @param {Object} [options] Options object - * @return {fabric.Text} thisArg - */ - getMeasuringContext: function() { - // if we did not return we have to measure something. - if (!fabric._measuringContext) { - fabric._measuringContext = this.canvas && this.canvas.contextCache || - fabric.util.createCanvasElement().getContext('2d'); - } - return fabric._measuringContext; - }, - - /** - * @private - * Divides text into lines of text and lines of graphemes. - */ - _splitText: function() { - var newLines = this._splitTextIntoLines(this.text); - this.textLines = newLines.lines; - this._textLines = newLines.graphemeLines; - this._unwrappedTextLines = newLines._unwrappedLines; - this._text = newLines.graphemeText; - return newLines; - }, - - /** - * Initialize or update text dimensions. - * Updates this.width and this.height with the proper values. - * Does not return dimensions. - */ - initDimensions: function() { - if (this.__skipDimension) { - return; - } - this._splitText(); - this._clearCache(); - if (this.path) { - this.width = this.path.width; - this.height = this.path.height; - } - else { - this.width = this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH; - this.height = this.calcTextHeight(); - } - if (this.textAlign.indexOf('justify') !== -1) { - // once text is measured we need to make space fatter to make justified text. - this.enlargeSpaces(); - } - this.saveState({ propertySet: '_dimensionAffectingProps' }); - }, - - /** - * Enlarge space boxes and shift the others - */ - enlargeSpaces: function() { - var diffSpace, currentLineWidth, numberOfSpaces, accumulatedSpace, line, charBound, spaces; - for (var i = 0, len = this._textLines.length; i < len; i++) { - if (this.textAlign !== 'justify' && (i === len - 1 || this.isEndOfWrapping(i))) { - continue; - } - accumulatedSpace = 0; - line = this._textLines[i]; - currentLineWidth = this.getLineWidth(i); - if (currentLineWidth < this.width && (spaces = this.textLines[i].match(this._reSpacesAndTabs))) { - numberOfSpaces = spaces.length; - diffSpace = (this.width - currentLineWidth) / numberOfSpaces; - for (var j = 0, jlen = line.length; j <= jlen; j++) { - charBound = this.__charBounds[i][j]; - if (this._reSpaceAndTab.test(line[j])) { - charBound.width += diffSpace; - charBound.kernedWidth += diffSpace; - charBound.left += accumulatedSpace; - accumulatedSpace += diffSpace; - } - else { - charBound.left += accumulatedSpace; - } - } - } - } - }, - - /** - * Detect if the text line is ended with an hard break - * text and itext do not have wrapping, return false - * @return {Boolean} - */ - isEndOfWrapping: function(lineIndex) { - return lineIndex === this._textLines.length - 1; - }, - - /** - * Detect if a line has a linebreak and so we need to account for it when moving - * and counting style. - * It return always for text and Itext. - * @return Number - */ - missingNewlineOffset: function() { - return 1; - }, - - /** - * Returns string representation of an instance - * @return {String} String representation of text object - */ - toString: function() { - return '#'; - }, - - /** - * Return the dimension and the zoom level needed to create a cache canvas - * big enough to host the object to be cached. - * @private - * @param {Object} dim.x width of object to be cached - * @param {Object} dim.y height of object to be cached - * @return {Object}.width width of canvas - * @return {Object}.height height of canvas - * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache - * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache - */ - _getCacheCanvasDimensions: function() { - var dims = this.callSuper('_getCacheCanvasDimensions'); - var fontSize = this.fontSize; - dims.width += fontSize * dims.zoomX; - dims.height += fontSize * dims.zoomY; - return dims; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - var path = this.path; - path && !path.isNotVisible() && path._render(ctx); - this._setTextStyles(ctx); - this._renderTextLinesBackground(ctx); - this._renderTextDecoration(ctx, 'underline'); - this._renderText(ctx); - this._renderTextDecoration(ctx, 'overline'); - this._renderTextDecoration(ctx, 'linethrough'); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderText: function(ctx) { - if (this.paintFirst === 'stroke') { - this._renderTextStroke(ctx); - this._renderTextFill(ctx); - } - else { - this._renderTextFill(ctx); - this._renderTextStroke(ctx); - } - }, - - /** - * Set the font parameter of the context with the object properties or with charStyle - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Object} [charStyle] object with font style properties - * @param {String} [charStyle.fontFamily] Font Family - * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix ) - * @param {String} [charStyle.fontWeight] Font weight - * @param {String} [charStyle.fontStyle] Font style (italic|normal) - */ - _setTextStyles: function(ctx, charStyle, forMeasuring) { - ctx.textBaseline = 'alphabetic'; - ctx.font = this._getFontDeclaration(charStyle, forMeasuring); - }, - - /** - * calculate and return the text Width measuring each line. - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @return {Number} Maximum width of fabric.Text object - */ - calcTextWidth: function() { - var maxWidth = this.getLineWidth(0); - - for (var i = 1, len = this._textLines.length; i < len; i++) { - var currentLineWidth = this.getLineWidth(i); - if (currentLineWidth > maxWidth) { - maxWidth = currentLineWidth; - } - } - return maxWidth; - }, - - /** - * @private - * @param {String} method Method name ("fillText" or "strokeText") - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {String} line Text to render - * @param {Number} left Left position of text - * @param {Number} top Top position of text - * @param {Number} lineIndex Index of a line in a text - */ - _renderTextLine: function(method, ctx, line, left, top, lineIndex) { - this._renderChars(method, ctx, line, left, top, lineIndex); - }, - - /** - * Renders the text background for lines, taking care of style - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderTextLinesBackground: function(ctx) { - if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) { - return; - } - var heightOfLine, - lineLeftOffset, originalFill = ctx.fillStyle, - line, lastColor, - leftOffset = this._getLeftOffset(), - lineTopOffset = this._getTopOffset(), - boxStart = 0, boxWidth = 0, charBox, currentColor, path = this.path, - drawStart; - - for (var i = 0, len = this._textLines.length; i < len; i++) { - heightOfLine = this.getHeightOfLine(i); - if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor', i)) { - lineTopOffset += heightOfLine; - continue; - } - line = this._textLines[i]; - lineLeftOffset = this._getLineLeftOffset(i); - boxWidth = 0; - boxStart = 0; - lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor'); - for (var j = 0, jlen = line.length; j < jlen; j++) { - charBox = this.__charBounds[i][j]; - currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor'); - if (path) { - ctx.save(); - ctx.translate(charBox.renderLeft, charBox.renderTop); - ctx.rotate(charBox.angle); - ctx.fillStyle = currentColor; - currentColor && ctx.fillRect( - -charBox.width / 2, - -heightOfLine / this.lineHeight * (1 - this._fontSizeFraction), - charBox.width, - heightOfLine / this.lineHeight - ); - ctx.restore(); - } - else if (currentColor !== lastColor) { - drawStart = leftOffset + lineLeftOffset + boxStart; - if (this.direction === 'rtl') { - drawStart = this.width - drawStart - boxWidth; - } - ctx.fillStyle = lastColor; - lastColor && ctx.fillRect( - drawStart, - lineTopOffset, - boxWidth, - heightOfLine / this.lineHeight - ); - boxStart = charBox.left; - boxWidth = charBox.width; - lastColor = currentColor; - } - else { - boxWidth += charBox.kernedWidth; - } - } - if (currentColor && !path) { - drawStart = leftOffset + lineLeftOffset + boxStart; - if (this.direction === 'rtl') { - drawStart = this.width - drawStart - boxWidth; - } - ctx.fillStyle = currentColor; - ctx.fillRect( - drawStart, - lineTopOffset, - boxWidth, - heightOfLine / this.lineHeight - ); - } - lineTopOffset += heightOfLine; - } - ctx.fillStyle = originalFill; - // if there is text background color no - // other shadows should be casted - this._removeShadow(ctx); - }, - - /** - * @private - * @param {Object} decl style declaration for cache - * @param {String} decl.fontFamily fontFamily - * @param {String} decl.fontStyle fontStyle - * @param {String} decl.fontWeight fontWeight - * @return {Object} reference to cache - */ - getFontCache: function(decl) { - var fontFamily = decl.fontFamily.toLowerCase(); - if (!fabric.charWidthsCache[fontFamily]) { - fabric.charWidthsCache[fontFamily] = { }; - } - var cache = fabric.charWidthsCache[fontFamily], - cacheProp = decl.fontStyle.toLowerCase() + '_' + (decl.fontWeight + '').toLowerCase(); - if (!cache[cacheProp]) { - cache[cacheProp] = { }; - } - return cache[cacheProp]; - }, - - /** - * measure and return the width of a single character. - * possibly overridden to accommodate different measure logic or - * to hook some external lib for character measurement - * @private - * @param {String} _char, char to be measured - * @param {Object} charStyle style of char to be measured - * @param {String} [previousChar] previous char - * @param {Object} [prevCharStyle] style of previous char - */ - _measureChar: function(_char, charStyle, previousChar, prevCharStyle) { - // first i try to return from cache - var fontCache = this.getFontCache(charStyle), fontDeclaration = this._getFontDeclaration(charStyle), - previousFontDeclaration = this._getFontDeclaration(prevCharStyle), couple = previousChar + _char, - stylesAreEqual = fontDeclaration === previousFontDeclaration, width, coupleWidth, previousWidth, - fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE, kernedWidth; - - if (previousChar && fontCache[previousChar] !== undefined) { - previousWidth = fontCache[previousChar]; - } - if (fontCache[_char] !== undefined) { - kernedWidth = width = fontCache[_char]; - } - if (stylesAreEqual && fontCache[couple] !== undefined) { - coupleWidth = fontCache[couple]; - kernedWidth = coupleWidth - previousWidth; - } - if (width === undefined || previousWidth === undefined || coupleWidth === undefined) { - var ctx = this.getMeasuringContext(); - // send a TRUE to specify measuring font size CACHE_FONT_SIZE - this._setTextStyles(ctx, charStyle, true); - } - if (width === undefined) { - kernedWidth = width = ctx.measureText(_char).width; - fontCache[_char] = width; - } - if (previousWidth === undefined && stylesAreEqual && previousChar) { - previousWidth = ctx.measureText(previousChar).width; - fontCache[previousChar] = previousWidth; - } - if (stylesAreEqual && coupleWidth === undefined) { - // we can measure the kerning couple and subtract the width of the previous character - coupleWidth = ctx.measureText(couple).width; - fontCache[couple] = coupleWidth; - kernedWidth = coupleWidth - previousWidth; - } - return { width: width * fontMultiplier, kernedWidth: kernedWidth * fontMultiplier }; - }, - - /** - * Computes height of character at given position - * @param {Number} line the line index number - * @param {Number} _char the character index number - * @return {Number} fontSize of the character - */ - getHeightOfChar: function(line, _char) { - return this.getValueOfPropertyAt(line, _char, 'fontSize'); - }, - - /** - * measure a text line measuring all characters. - * @param {Number} lineIndex line number - * @return {Number} Line width - */ - measureLine: function(lineIndex) { - var lineInfo = this._measureLine(lineIndex); - if (this.charSpacing !== 0) { - lineInfo.width -= this._getWidthOfCharSpacing(); - } - if (lineInfo.width < 0) { - lineInfo.width = 0; - } - return lineInfo; - }, - - /** - * measure every grapheme of a line, populating __charBounds - * @param {Number} lineIndex - * @return {Object} object.width total width of characters - * @return {Object} object.widthOfSpaces length of chars that match this._reSpacesAndTabs - */ - _measureLine: function(lineIndex) { - var width = 0, i, grapheme, line = this._textLines[lineIndex], prevGrapheme, - graphemeInfo, numOfSpaces = 0, lineBounds = new Array(line.length), - positionInPath = 0, startingPoint, totalPathLength, path = this.path, - reverse = this.pathSide === 'right'; - - this.__charBounds[lineIndex] = lineBounds; - for (i = 0; i < line.length; i++) { - grapheme = line[i]; - graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme); - lineBounds[i] = graphemeInfo; - width += graphemeInfo.kernedWidth; - prevGrapheme = grapheme; - } - // this latest bound box represent the last character of the line - // to simplify cursor handling in interactive mode. - lineBounds[i] = { - left: graphemeInfo ? graphemeInfo.left + graphemeInfo.width : 0, - width: 0, - kernedWidth: 0, - height: this.fontSize - }; - if (path) { - totalPathLength = path.segmentsInfo[path.segmentsInfo.length - 1].length; - startingPoint = fabric.util.getPointOnPath(path.path, 0, path.segmentsInfo); - startingPoint.x += path.pathOffset.x; - startingPoint.y += path.pathOffset.y; - switch (this.textAlign) { - case 'left': - positionInPath = reverse ? (totalPathLength - width) : 0; - break; - case 'center': - positionInPath = (totalPathLength - width) / 2; - break; - case 'right': - positionInPath = reverse ? 0 : (totalPathLength - width); - break; - //todo - add support for justify - } - positionInPath += this.pathStartOffset * (reverse ? -1 : 1); - for (i = reverse ? line.length - 1 : 0; - reverse ? i >= 0 : i < line.length; - reverse ? i-- : i++) { - graphemeInfo = lineBounds[i]; - if (positionInPath > totalPathLength) { - positionInPath %= totalPathLength; - } - else if (positionInPath < 0) { - positionInPath += totalPathLength; - } - // it would probably much faster to send all the grapheme position for a line - // and calculate path position/angle at once. - this._setGraphemeOnPath(positionInPath, graphemeInfo, startingPoint); - positionInPath += graphemeInfo.kernedWidth; - } - } - return { width: width, numOfSpaces: numOfSpaces }; - }, - - /** - * Calculate the angle and the left,top position of the char that follow a path. - * It appends it to graphemeInfo to be reused later at rendering - * @private - * @param {Number} positionInPath to be measured - * @param {Object} graphemeInfo current grapheme box information - * @param {Object} startingPoint position of the point - */ - _setGraphemeOnPath: function(positionInPath, graphemeInfo, startingPoint) { - var centerPosition = positionInPath + graphemeInfo.kernedWidth / 2, - path = this.path; - - // we are at currentPositionOnPath. we want to know what point on the path is. - var info = fabric.util.getPointOnPath(path.path, centerPosition, path.segmentsInfo); - graphemeInfo.renderLeft = info.x - startingPoint.x; - graphemeInfo.renderTop = info.y - startingPoint.y; - graphemeInfo.angle = info.angle + (this.pathSide === 'right' ? Math.PI : 0); - }, - - /** - * Measure and return the info of a single grapheme. - * needs the the info of previous graphemes already filled - * @private - * @param {String} grapheme to be measured - * @param {Number} lineIndex index of the line where the char is - * @param {Number} charIndex position in the line - * @param {String} [prevGrapheme] character preceding the one to be measured - */ - _getGraphemeBox: function(grapheme, lineIndex, charIndex, prevGrapheme, skipLeft) { - var style = this.getCompleteStyleDeclaration(lineIndex, charIndex), - prevStyle = prevGrapheme ? this.getCompleteStyleDeclaration(lineIndex, charIndex - 1) : { }, - info = this._measureChar(grapheme, style, prevGrapheme, prevStyle), - kernedWidth = info.kernedWidth, - width = info.width, charSpacing; - - if (this.charSpacing !== 0) { - charSpacing = this._getWidthOfCharSpacing(); - width += charSpacing; - kernedWidth += charSpacing; - } - - var box = { - width: width, - left: 0, - height: style.fontSize, - kernedWidth: kernedWidth, - deltaY: style.deltaY, - }; - if (charIndex > 0 && !skipLeft) { - var previousBox = this.__charBounds[lineIndex][charIndex - 1]; - box.left = previousBox.left + previousBox.width + info.kernedWidth - info.width; - } - return box; - }, - - /** - * Calculate height of line at 'lineIndex' - * @param {Number} lineIndex index of line to calculate - * @return {Number} - */ - getHeightOfLine: function(lineIndex) { - if (this.__lineHeights[lineIndex]) { - return this.__lineHeights[lineIndex]; - } - - var line = this._textLines[lineIndex], - // char 0 is measured before the line cycle because it nneds to char - // emptylines - maxHeight = this.getHeightOfChar(lineIndex, 0); - for (var i = 1, len = line.length; i < len; i++) { - maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight); - } - - return this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult; - }, - - /** - * Calculate text box height - */ - calcTextHeight: function() { - var lineHeight, height = 0; - for (var i = 0, len = this._textLines.length; i < len; i++) { - lineHeight = this.getHeightOfLine(i); - height += (i === len - 1 ? lineHeight / this.lineHeight : lineHeight); - } - return height; - }, - - /** - * @private - * @return {Number} Left offset - */ - _getLeftOffset: function() { - return this.direction === 'ltr' ? -this.width / 2 : this.width / 2; - }, - - /** - * @private - * @return {Number} Top offset - */ - _getTopOffset: function() { - return -this.height / 2; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {String} method Method name ("fillText" or "strokeText") - */ - _renderTextCommon: function(ctx, method) { - ctx.save(); - var lineHeights = 0, left = this._getLeftOffset(), top = this._getTopOffset(); - for (var i = 0, len = this._textLines.length; i < len; i++) { - var heightOfLine = this.getHeightOfLine(i), - maxHeight = heightOfLine / this.lineHeight, - leftOffset = this._getLineLeftOffset(i); - this._renderTextLine( - method, - ctx, - this._textLines[i], - left + leftOffset, - top + lineHeights + maxHeight, - i - ); - lineHeights += heightOfLine; - } - ctx.restore(); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderTextFill: function(ctx) { - if (!this.fill && !this.styleHas('fill')) { - return; - } - - this._renderTextCommon(ctx, 'fillText'); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderTextStroke: function(ctx) { - if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) { - return; - } - - if (this.shadow && !this.shadow.affectStroke) { - this._removeShadow(ctx); - } - - ctx.save(); - this._setLineDash(ctx, this.strokeDashArray); - ctx.beginPath(); - this._renderTextCommon(ctx, 'strokeText'); - ctx.closePath(); - ctx.restore(); - }, - - /** - * @private - * @param {String} method fillText or strokeText. - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Array} line Content of the line, splitted in an array by grapheme - * @param {Number} left - * @param {Number} top - * @param {Number} lineIndex - */ - _renderChars: function(method, ctx, line, left, top, lineIndex) { - // set proper line offset - var lineHeight = this.getHeightOfLine(lineIndex), - isJustify = this.textAlign.indexOf('justify') !== -1, - actualStyle, - nextStyle, - charsToRender = '', - charBox, - boxWidth = 0, - timeToRender, - path = this.path, - shortCut = !isJustify && this.charSpacing === 0 && this.isEmptyStyles(lineIndex) && !path, - isLtr = this.direction === 'ltr', sign = this.direction === 'ltr' ? 1 : -1, - drawingLeft; - - ctx.save(); - top -= lineHeight * this._fontSizeFraction / this.lineHeight; - if (shortCut) { - // render all the line in one pass without checking - // drawingLeft = isLtr ? left : left - this.getLineWidth(lineIndex); - ctx.canvas.setAttribute('dir', isLtr ? 'ltr' : 'rtl'); - ctx.direction = isLtr ? 'ltr' : 'rtl'; - ctx.textAlign = isLtr ? 'left' : 'right'; - this._renderChar(method, ctx, lineIndex, 0, line.join(''), left, top, lineHeight); - ctx.restore(); - return; - } - for (var i = 0, len = line.length - 1; i <= len; i++) { - timeToRender = i === len || this.charSpacing || path; - charsToRender += line[i]; - charBox = this.__charBounds[lineIndex][i]; - if (boxWidth === 0) { - left += sign * (charBox.kernedWidth - charBox.width); - boxWidth += charBox.width; - } - else { - boxWidth += charBox.kernedWidth; - } - if (isJustify && !timeToRender) { - if (this._reSpaceAndTab.test(line[i])) { - timeToRender = true; - } - } - if (!timeToRender) { - // if we have charSpacing, we render char by char - actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i); - nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1); - timeToRender = this._hasStyleChanged(actualStyle, nextStyle); - } - if (timeToRender) { - if (path) { - ctx.save(); - ctx.translate(charBox.renderLeft, charBox.renderTop); - ctx.rotate(charBox.angle); - this._renderChar(method, ctx, lineIndex, i, charsToRender, -boxWidth / 2, 0, lineHeight); - ctx.restore(); - } - else { - drawingLeft = left; - ctx.canvas.setAttribute('dir', isLtr ? 'ltr' : 'rtl'); - ctx.direction = isLtr ? 'ltr' : 'rtl'; - ctx.textAlign = isLtr ? 'left' : 'right'; - this._renderChar(method, ctx, lineIndex, i, charsToRender, drawingLeft, top, lineHeight); - } - charsToRender = ''; - actualStyle = nextStyle; - left += sign * boxWidth; - boxWidth = 0; - } - } - ctx.restore(); - }, - - /** - * This function try to patch the missing gradientTransform on canvas gradients. - * transforming a context to transform the gradient, is going to transform the stroke too. - * we want to transform the gradient but not the stroke operation, so we create - * a transformed gradient on a pattern and then we use the pattern instead of the gradient. - * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size - * is limited. - * @private - * @param {fabric.Gradient} filler a fabric gradient instance - * @return {CanvasPattern} a pattern to use as fill/stroke style - */ - _applyPatternGradientTransformText: function(filler) { - var pCanvas = fabric.util.createCanvasElement(), pCtx, - // TODO: verify compatibility with strokeUniform - width = this.width + this.strokeWidth, height = this.height + this.strokeWidth; - pCanvas.width = width; - pCanvas.height = height; - pCtx = pCanvas.getContext('2d'); - pCtx.beginPath(); pCtx.moveTo(0, 0); pCtx.lineTo(width, 0); pCtx.lineTo(width, height); - pCtx.lineTo(0, height); pCtx.closePath(); - pCtx.translate(width / 2, height / 2); - pCtx.fillStyle = filler.toLive(pCtx); - this._applyPatternGradientTransform(pCtx, filler); - pCtx.fill(); - return pCtx.createPattern(pCanvas, 'no-repeat'); - }, - - handleFiller: function(ctx, property, filler) { - var offsetX, offsetY; - if (filler.toLive) { - if (filler.gradientUnits === 'percentage' || filler.gradientTransform || filler.patternTransform) { - // need to transform gradient in a pattern. - // this is a slow process. If you are hitting this codepath, and the object - // is not using caching, you should consider switching it on. - // we need a canvas as big as the current object caching canvas. - offsetX = -this.width / 2; - offsetY = -this.height / 2; - ctx.translate(offsetX, offsetY); - ctx[property] = this._applyPatternGradientTransformText(filler); - return { offsetX: offsetX, offsetY: offsetY }; - } - else { - // is a simple gradient or pattern - ctx[property] = filler.toLive(ctx, this); - return this._applyPatternGradientTransform(ctx, filler); - } - } - else { - // is a color - ctx[property] = filler; - } - return { offsetX: 0, offsetY: 0 }; - }, - - _setStrokeStyles: function(ctx, decl) { - ctx.lineWidth = decl.strokeWidth; - ctx.lineCap = this.strokeLineCap; - ctx.lineDashOffset = this.strokeDashOffset; - ctx.lineJoin = this.strokeLineJoin; - ctx.miterLimit = this.strokeMiterLimit; - return this.handleFiller(ctx, 'strokeStyle', decl.stroke); - }, - - _setFillStyles: function(ctx, decl) { - return this.handleFiller(ctx, 'fillStyle', decl.fill); - }, - - /** - * @private - * @param {String} method - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Number} lineIndex - * @param {Number} charIndex - * @param {String} _char - * @param {Number} left Left coordinate - * @param {Number} top Top coordinate - * @param {Number} lineHeight Height of the line - */ - _renderChar: function(method, ctx, lineIndex, charIndex, _char, left, top) { - var decl = this._getStyleDeclaration(lineIndex, charIndex), - fullDecl = this.getCompleteStyleDeclaration(lineIndex, charIndex), - shouldFill = method === 'fillText' && fullDecl.fill, - shouldStroke = method === 'strokeText' && fullDecl.stroke && fullDecl.strokeWidth, - fillOffsets, strokeOffsets; - - if (!shouldStroke && !shouldFill) { - return; - } - ctx.save(); - - shouldFill && (fillOffsets = this._setFillStyles(ctx, fullDecl)); - shouldStroke && (strokeOffsets = this._setStrokeStyles(ctx, fullDecl)); - - ctx.font = this._getFontDeclaration(fullDecl); - - - if (decl && decl.textBackgroundColor) { - this._removeShadow(ctx); - } - if (decl && decl.deltaY) { - top += decl.deltaY; - } - shouldFill && ctx.fillText(_char, left - fillOffsets.offsetX, top - fillOffsets.offsetY); - shouldStroke && ctx.strokeText(_char, left - strokeOffsets.offsetX, top - strokeOffsets.offsetY); - ctx.restore(); - }, - - /** - * Turns the character into a 'superior figure' (i.e. 'superscript') - * @param {Number} start selection start - * @param {Number} end selection end - * @returns {fabric.Text} thisArg - * @chainable - */ - setSuperscript: function(start, end) { - return this._setScript(start, end, this.superscript); - }, - - /** - * Turns the character into an 'inferior figure' (i.e. 'subscript') - * @param {Number} start selection start - * @param {Number} end selection end - * @returns {fabric.Text} thisArg - * @chainable - */ - setSubscript: function(start, end) { - return this._setScript(start, end, this.subscript); - }, - - /** - * Applies 'schema' at given position - * @private - * @param {Number} start selection start - * @param {Number} end selection end - * @param {Number} schema - * @returns {fabric.Text} thisArg - * @chainable - */ - _setScript: function(start, end, schema) { - var loc = this.get2DCursorLocation(start, true), - fontSize = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'fontSize'), - dy = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'deltaY'), - style = { fontSize: fontSize * schema.size, deltaY: dy + fontSize * schema.baseline }; - this.setSelectionStyles(style, start, end); - return this; - }, - - /** - * @private - * @param {Object} prevStyle - * @param {Object} thisStyle - */ - _hasStyleChanged: function(prevStyle, thisStyle) { - return prevStyle.fill !== thisStyle.fill || - prevStyle.stroke !== thisStyle.stroke || - prevStyle.strokeWidth !== thisStyle.strokeWidth || - prevStyle.fontSize !== thisStyle.fontSize || - prevStyle.fontFamily !== thisStyle.fontFamily || - prevStyle.fontWeight !== thisStyle.fontWeight || - prevStyle.fontStyle !== thisStyle.fontStyle || - prevStyle.deltaY !== thisStyle.deltaY; - }, - - /** - * @private - * @param {Object} prevStyle - * @param {Object} thisStyle - */ - _hasStyleChangedForSvg: function(prevStyle, thisStyle) { - return this._hasStyleChanged(prevStyle, thisStyle) || - prevStyle.overline !== thisStyle.overline || - prevStyle.underline !== thisStyle.underline || - prevStyle.linethrough !== thisStyle.linethrough; - }, - - /** - * @private - * @param {Number} lineIndex index text line - * @return {Number} Line left offset - */ - _getLineLeftOffset: function(lineIndex) { - var lineWidth = this.getLineWidth(lineIndex), - lineDiff = this.width - lineWidth, textAlign = this.textAlign, direction = this.direction, - isEndOfWrapping, leftOffset = 0, isEndOfWrapping = this.isEndOfWrapping(lineIndex); - if (textAlign === 'justify' - || (textAlign === 'justify-center' && !isEndOfWrapping) - || (textAlign === 'justify-right' && !isEndOfWrapping) - || (textAlign === 'justify-left' && !isEndOfWrapping) - ) { - return 0; - } - if (textAlign === 'center') { - leftOffset = lineDiff / 2; - } - if (textAlign === 'right') { - leftOffset = lineDiff; - } - if (textAlign === 'justify-center') { - leftOffset = lineDiff / 2; - } - if (textAlign === 'justify-right') { - leftOffset = lineDiff; - } - if (direction === 'rtl') { - leftOffset -= lineDiff; - } - return leftOffset; - }, - - /** - * @private - */ - _clearCache: function() { - this.__lineWidths = []; - this.__lineHeights = []; - this.__charBounds = []; - }, - - /** - * @private - */ - _shouldClearDimensionCache: function() { - var shouldClear = this._forceClearCache; - shouldClear || (shouldClear = this.hasStateChanged('_dimensionAffectingProps')); - if (shouldClear) { - this.dirty = true; - this._forceClearCache = false; - } - return shouldClear; - }, - - /** - * Measure a single line given its index. Used to calculate the initial - * text bounding box. The values are calculated and stored in __lineWidths cache. - * @private - * @param {Number} lineIndex line number - * @return {Number} Line width - */ - getLineWidth: function(lineIndex) { - if (this.__lineWidths[lineIndex]) { - return this.__lineWidths[lineIndex]; - } - - var width, line = this._textLines[lineIndex], lineInfo; - - if (line === '') { - width = 0; - } - else { - lineInfo = this.measureLine(lineIndex); - width = lineInfo.width; - } - this.__lineWidths[lineIndex] = width; - return width; - }, - - _getWidthOfCharSpacing: function() { - if (this.charSpacing !== 0) { - return this.fontSize * this.charSpacing / 1000; - } - return 0; - }, - - /** - * Retrieves the value of property at given character position - * @param {Number} lineIndex the line number - * @param {Number} charIndex the character number - * @param {String} property the property name - * @returns the value of 'property' - */ - getValueOfPropertyAt: function(lineIndex, charIndex, property) { - var charStyle = this._getStyleDeclaration(lineIndex, charIndex); - if (charStyle && typeof charStyle[property] !== 'undefined') { - return charStyle[property]; - } - return this[property]; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderTextDecoration: function(ctx, type) { - if (!this[type] && !this.styleHas(type)) { - return; - } - var heightOfLine, size, _size, - lineLeftOffset, dy, _dy, - line, lastDecoration, - leftOffset = this._getLeftOffset(), - topOffset = this._getTopOffset(), top, - boxStart, boxWidth, charBox, currentDecoration, - maxHeight, currentFill, lastFill, path = this.path, - charSpacing = this._getWidthOfCharSpacing(), - offsetY = this.offsets[type]; - - for (var i = 0, len = this._textLines.length; i < len; i++) { - heightOfLine = this.getHeightOfLine(i); - if (!this[type] && !this.styleHas(type, i)) { - topOffset += heightOfLine; - continue; - } - line = this._textLines[i]; - maxHeight = heightOfLine / this.lineHeight; - lineLeftOffset = this._getLineLeftOffset(i); - boxStart = 0; - boxWidth = 0; - lastDecoration = this.getValueOfPropertyAt(i, 0, type); - lastFill = this.getValueOfPropertyAt(i, 0, 'fill'); - top = topOffset + maxHeight * (1 - this._fontSizeFraction); - size = this.getHeightOfChar(i, 0); - dy = this.getValueOfPropertyAt(i, 0, 'deltaY'); - for (var j = 0, jlen = line.length; j < jlen; j++) { - charBox = this.__charBounds[i][j]; - currentDecoration = this.getValueOfPropertyAt(i, j, type); - currentFill = this.getValueOfPropertyAt(i, j, 'fill'); - _size = this.getHeightOfChar(i, j); - _dy = this.getValueOfPropertyAt(i, j, 'deltaY'); - if (path && currentDecoration && currentFill) { - ctx.save(); - ctx.fillStyle = lastFill; - ctx.translate(charBox.renderLeft, charBox.renderTop); - ctx.rotate(charBox.angle); - ctx.fillRect( - -charBox.kernedWidth / 2, - offsetY * _size + _dy, - charBox.kernedWidth, - this.fontSize / 15 - ); - ctx.restore(); - } - else if ( - (currentDecoration !== lastDecoration || currentFill !== lastFill || _size !== size || _dy !== dy) - && boxWidth > 0 - ) { - var drawStart = leftOffset + lineLeftOffset + boxStart; - if (this.direction === 'rtl') { - drawStart = this.width - drawStart - boxWidth; - } - if (lastDecoration && lastFill) { - ctx.fillStyle = lastFill; - ctx.fillRect( - drawStart, - top + offsetY * size + dy, - boxWidth, - this.fontSize / 15 - ); - } - boxStart = charBox.left; - boxWidth = charBox.width; - lastDecoration = currentDecoration; - lastFill = currentFill; - size = _size; - dy = _dy; - } - else { - boxWidth += charBox.kernedWidth; - } - } - var drawStart = leftOffset + lineLeftOffset + boxStart; - if (this.direction === 'rtl') { - drawStart = this.width - drawStart - boxWidth; - } - ctx.fillStyle = currentFill; - currentDecoration && currentFill && ctx.fillRect( - drawStart, - top + offsetY * size + dy, - boxWidth - charSpacing, - this.fontSize / 15 - ); - topOffset += heightOfLine; - } - // if there is text background color no - // other shadows should be casted - this._removeShadow(ctx); - }, - - /** - * return font declaration string for canvas context - * @param {Object} [styleObject] object - * @returns {String} font declaration formatted for canvas context. - */ - _getFontDeclaration: function(styleObject, forMeasuring) { - var style = styleObject || this, family = this.fontFamily, - fontIsGeneric = fabric.Text.genericFonts.indexOf(family.toLowerCase()) > -1; - var fontFamily = family === undefined || - family.indexOf('\'') > -1 || family.indexOf(',') > -1 || - family.indexOf('"') > -1 || fontIsGeneric - ? style.fontFamily : '"' + style.fontFamily + '"'; - return [ - // node-canvas needs "weight style", while browsers need "style weight" - // verify if this can be fixed in JSDOM - (fabric.isLikelyNode ? style.fontWeight : style.fontStyle), - (fabric.isLikelyNode ? style.fontStyle : style.fontWeight), - forMeasuring ? this.CACHE_FONT_SIZE + 'px' : style.fontSize + 'px', - fontFamily - ].join(' '); - }, - - /** - * Renders text instance on a specified context - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - render: function(ctx) { - // do not render if object is not visible - if (!this.visible) { - return; - } - if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) { - return; - } - if (this._shouldClearDimensionCache()) { - this.initDimensions(); - } - this.callSuper('render', ctx); - }, - - /** - * Returns the text as an array of lines. - * @param {String} text text to split - * @returns {Array} Lines in the text - */ - _splitTextIntoLines: function(text) { - var lines = text.split(this._reNewline), - newLines = new Array(lines.length), - newLine = ['\n'], - newText = []; - for (var i = 0; i < lines.length; i++) { - newLines[i] = fabric.util.string.graphemeSplit(lines[i]); - newText = newText.concat(newLines[i], newLine); - } - newText.pop(); - return { _unwrappedLines: newLines, lines: lines, graphemeText: newText, graphemeLines: newLines }; - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of an instance - */ - toObject: function(propertiesToInclude) { - var allProperties = additionalProps.concat(propertiesToInclude); - var obj = this.callSuper('toObject', allProperties); - // styles will be overridden with a properly cloned structure - obj.styles = clone(this.styles, true); - if (obj.path) { - obj.path = this.path.toObject(); - } - return obj; - }, - - /** - * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`. - * @param {String|Object} key Property name or object (if object, iterate over the object properties) - * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one) - * @return {fabric.Object} thisArg - * @chainable - */ - set: function(key, value) { - this.callSuper('set', key, value); - var needsDims = false; - var isAddingPath = false; - if (typeof key === 'object') { - for (var _key in key) { - if (_key === 'path') { - this.setPathInfo(); - } - needsDims = needsDims || this._dimensionAffectingProps.indexOf(_key) !== -1; - isAddingPath = isAddingPath || _key === 'path'; - } - } - else { - needsDims = this._dimensionAffectingProps.indexOf(key) !== -1; - isAddingPath = key === 'path'; - } - if (isAddingPath) { - this.setPathInfo(); - } - if (needsDims) { - this.initDimensions(); - this.setCoords(); - } - return this; - }, - - /** - * Returns complexity of an instance - * @return {Number} complexity - */ - complexity: function() { - return 1; - } - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Text.fromElement}) - * @static - * @memberOf fabric.Text - * @see: http://www.w3.org/TR/SVG/text.html#TextElement - */ - fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat( - 'x y dx dy font-family font-style font-weight font-size letter-spacing text-decoration text-anchor'.split(' ')); - - /** - * Default SVG font size - * @static - * @memberOf fabric.Text - */ - fabric.Text.DEFAULT_SVG_FONT_SIZE = 16; - - /** - * Returns fabric.Text instance from an SVG element (not yet implemented) - * @static - * @memberOf fabric.Text - * @param {SVGElement} element Element to parse - * @param {Function} callback callback function invoked after parsing - * @param {Object} [options] Options object - */ - fabric.Text.fromElement = function(element, callback, options) { - if (!element) { - return callback(null); - } - - var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES), - parsedAnchor = parsedAttributes.textAnchor || 'left'; - options = fabric.util.object.extend((options ? clone(options) : { }), parsedAttributes); - - options.top = options.top || 0; - options.left = options.left || 0; - if (parsedAttributes.textDecoration) { - var textDecoration = parsedAttributes.textDecoration; - if (textDecoration.indexOf('underline') !== -1) { - options.underline = true; - } - if (textDecoration.indexOf('overline') !== -1) { - options.overline = true; - } - if (textDecoration.indexOf('line-through') !== -1) { - options.linethrough = true; - } - delete options.textDecoration; - } - if ('dx' in parsedAttributes) { - options.left += parsedAttributes.dx; - } - if ('dy' in parsedAttributes) { - options.top += parsedAttributes.dy; - } - if (!('fontSize' in options)) { - options.fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE; - } - - var textContent = ''; - - // The XML is not properly parsed in IE9 so a workaround to get - // textContent is through firstChild.data. Another workaround would be - // to convert XML loaded from a file to be converted using DOMParser (same way loadSVGFromString() does) - if (!('textContent' in element)) { - if ('firstChild' in element && element.firstChild !== null) { - if ('data' in element.firstChild && element.firstChild.data !== null) { - textContent = element.firstChild.data; - } - } - } - else { - textContent = element.textContent; - } - - textContent = textContent.replace(/^\s+|\s+$|\n+/g, '').replace(/\s+/g, ' '); - var originalStrokeWidth = options.strokeWidth; - options.strokeWidth = 0; - - var text = new fabric.Text(textContent, options), - textHeightScaleFactor = text.getScaledHeight() / text.height, - lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height, - scaledDiff = lineHeightDiff * textHeightScaleFactor, - textHeight = text.getScaledHeight() + scaledDiff, - offX = 0; - /* - Adjust positioning: - x/y attributes in SVG correspond to the bottom-left corner of text bounding box - fabric output by default at top, left. - */ - if (parsedAnchor === 'center') { - offX = text.getScaledWidth() / 2; - } - if (parsedAnchor === 'right') { - offX = text.getScaledWidth(); - } - text.set({ - left: text.left - offX, - top: text.top - (textHeight - text.fontSize * (0.07 + text._fontSizeFraction)) / text.lineHeight, - strokeWidth: typeof originalStrokeWidth !== 'undefined' ? originalStrokeWidth : 1, - }); - callback(text); - }; - /* _FROM_SVG_END_ */ - - /** - * Returns fabric.Text instance from an object representation - * @static - * @memberOf fabric.Text - * @param {Object} object plain js Object to create an instance from - * @param {Function} [callback] Callback to invoke when an fabric.Text instance is created - */ - fabric.Text.fromObject = function(object, callback) { - var objectCopy = clone(object), path = object.path; - delete objectCopy.path; - return fabric.Object._fromObject('Text', objectCopy, function(textInstance) { - if (path) { - fabric.Object._fromObject('Path', path, function(pathInstance) { - textInstance.set('path', pathInstance); - callback(textInstance); - }, 'path'); - } - else { - callback(textInstance); - } - }, 'text'); - }; - - fabric.Text.genericFonts = ['sans-serif', 'serif', 'cursive', 'fantasy', 'monospace']; - - fabric.util.createAccessors && fabric.util.createAccessors(fabric.Text); - -})(typeof exports !== 'undefined' ? exports : this); - - -(function() { - fabric.util.object.extend(fabric.Text.prototype, /** @lends fabric.Text.prototype */ { - /** - * Returns true if object has no styling or no styling in a line - * @param {Number} lineIndex , lineIndex is on wrapped lines. - * @return {Boolean} - */ - isEmptyStyles: function(lineIndex) { - if (!this.styles) { - return true; - } - if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) { - return true; - } - var obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] }; - for (var p1 in obj) { - for (var p2 in obj[p1]) { - // eslint-disable-next-line no-unused-vars - for (var p3 in obj[p1][p2]) { - return false; - } - } - } - return true; - }, - - /** - * Returns true if object has a style property or has it ina specified line - * This function is used to detect if a text will use a particular property or not. - * @param {String} property to check for - * @param {Number} lineIndex to check the style on - * @return {Boolean} - */ - styleHas: function(property, lineIndex) { - if (!this.styles || !property || property === '') { - return false; - } - if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) { - return false; - } - var obj = typeof lineIndex === 'undefined' ? this.styles : { 0: this.styles[lineIndex] }; - // eslint-disable-next-line - for (var p1 in obj) { - // eslint-disable-next-line - for (var p2 in obj[p1]) { - if (typeof obj[p1][p2][property] !== 'undefined') { - return true; - } - } - } - return false; - }, - - /** - * Check if characters in a text have a value for a property - * whose value matches the textbox's value for that property. If so, - * the character-level property is deleted. If the character - * has no other properties, then it is also deleted. Finally, - * if the line containing that character has no other characters - * then it also is deleted. - * - * @param {string} property The property to compare between characters and text. - */ - cleanStyle: function(property) { - if (!this.styles || !property || property === '') { - return false; - } - var obj = this.styles, stylesCount = 0, letterCount, stylePropertyValue, - allStyleObjectPropertiesMatch = true, graphemeCount = 0, styleObject; - // eslint-disable-next-line - for (var p1 in obj) { - letterCount = 0; - // eslint-disable-next-line - for (var p2 in obj[p1]) { - var styleObject = obj[p1][p2], - stylePropertyHasBeenSet = styleObject.hasOwnProperty(property); - - stylesCount++; - - if (stylePropertyHasBeenSet) { - if (!stylePropertyValue) { - stylePropertyValue = styleObject[property]; - } - else if (styleObject[property] !== stylePropertyValue) { - allStyleObjectPropertiesMatch = false; - } - - if (styleObject[property] === this[property]) { - delete styleObject[property]; - } - } - else { - allStyleObjectPropertiesMatch = false; - } - - if (Object.keys(styleObject).length !== 0) { - letterCount++; - } - else { - delete obj[p1][p2]; - } - } - - if (letterCount === 0) { - delete obj[p1]; - } - } - // if every grapheme has the same style set then - // delete those styles and set it on the parent - for (var i = 0; i < this._textLines.length; i++) { - graphemeCount += this._textLines[i].length; - } - if (allStyleObjectPropertiesMatch && stylesCount === graphemeCount) { - this[property] = stylePropertyValue; - this.removeStyle(property); - } - }, - - /** - * Remove a style property or properties from all individual character styles - * in a text object. Deletes the character style object if it contains no other style - * props. Deletes a line style object if it contains no other character styles. - * - * @param {String} props The property to remove from character styles. - */ - removeStyle: function(property) { - if (!this.styles || !property || property === '') { - return; - } - var obj = this.styles, line, lineNum, charNum; - for (lineNum in obj) { - line = obj[lineNum]; - for (charNum in line) { - delete line[charNum][property]; - if (Object.keys(line[charNum]).length === 0) { - delete line[charNum]; - } - } - if (Object.keys(line).length === 0) { - delete obj[lineNum]; - } - } - }, - - /** - * @private - */ - _extendStyles: function(index, styles) { - var loc = this.get2DCursorLocation(index); - - if (!this._getLineStyle(loc.lineIndex)) { - this._setLineStyle(loc.lineIndex); - } - - if (!this._getStyleDeclaration(loc.lineIndex, loc.charIndex)) { - this._setStyleDeclaration(loc.lineIndex, loc.charIndex, {}); - } - - fabric.util.object.extend(this._getStyleDeclaration(loc.lineIndex, loc.charIndex), styles); - }, - - /** - * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start) - * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used. - * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles. - */ - get2DCursorLocation: function(selectionStart, skipWrapping) { - if (typeof selectionStart === 'undefined') { - selectionStart = this.selectionStart; - } - var lines = skipWrapping ? this._unwrappedTextLines : this._textLines, - len = lines.length; - for (var i = 0; i < len; i++) { - if (selectionStart <= lines[i].length) { - return { - lineIndex: i, - charIndex: selectionStart - }; - } - selectionStart -= lines[i].length + this.missingNewlineOffset(i); - } - return { - lineIndex: i - 1, - charIndex: lines[i - 1].length < selectionStart ? lines[i - 1].length : selectionStart - }; - }, - - /** - * Gets style of a current selection/cursor (at the start position) - * if startIndex or endIndex are not provided, selectionStart or selectionEnd will be used. - * @param {Number} [startIndex] Start index to get styles at - * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1 - * @param {Boolean} [complete] get full style or not - * @return {Array} styles an array with one, zero or more Style objects - */ - getSelectionStyles: function(startIndex, endIndex, complete) { - if (typeof startIndex === 'undefined') { - startIndex = this.selectionStart || 0; - } - if (typeof endIndex === 'undefined') { - endIndex = this.selectionEnd || startIndex; - } - var styles = []; - for (var i = startIndex; i < endIndex; i++) { - styles.push(this.getStyleAtPosition(i, complete)); - } - return styles; - }, - - /** - * Gets style of a current selection/cursor position - * @param {Number} position to get styles at - * @param {Boolean} [complete] full style if true - * @return {Object} style Style object at a specified index - * @private - */ - getStyleAtPosition: function(position, complete) { - var loc = this.get2DCursorLocation(position), - style = complete ? this.getCompleteStyleDeclaration(loc.lineIndex, loc.charIndex) : - this._getStyleDeclaration(loc.lineIndex, loc.charIndex); - return style || {}; - }, - - /** - * Sets style of a current selection, if no selection exist, do not set anything. - * @param {Object} [styles] Styles object - * @param {Number} [startIndex] Start index to get styles at - * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1 - * @return {fabric.IText} thisArg - * @chainable - */ - setSelectionStyles: function(styles, startIndex, endIndex) { - if (typeof startIndex === 'undefined') { - startIndex = this.selectionStart || 0; - } - if (typeof endIndex === 'undefined') { - endIndex = this.selectionEnd || startIndex; - } - for (var i = startIndex; i < endIndex; i++) { - this._extendStyles(i, styles); - } - /* not included in _extendStyles to avoid clearing cache more than once */ - this._forceClearCache = true; - return this; - }, - - /** - * get the reference, not a clone, of the style object for a given character - * @param {Number} lineIndex - * @param {Number} charIndex - * @return {Object} style object - */ - _getStyleDeclaration: function(lineIndex, charIndex) { - var lineStyle = this.styles && this.styles[lineIndex]; - if (!lineStyle) { - return null; - } - return lineStyle[charIndex]; - }, - - /** - * return a new object that contains all the style property for a character - * the object returned is newly created - * @param {Number} lineIndex of the line where the character is - * @param {Number} charIndex position of the character on the line - * @return {Object} style object - */ - getCompleteStyleDeclaration: function(lineIndex, charIndex) { - var style = this._getStyleDeclaration(lineIndex, charIndex) || { }, - styleObject = { }, prop; - for (var i = 0; i < this._styleProperties.length; i++) { - prop = this._styleProperties[i]; - styleObject[prop] = typeof style[prop] === 'undefined' ? this[prop] : style[prop]; - } - return styleObject; - }, - - /** - * @param {Number} lineIndex - * @param {Number} charIndex - * @param {Object} style - * @private - */ - _setStyleDeclaration: function(lineIndex, charIndex, style) { - this.styles[lineIndex][charIndex] = style; - }, - - /** - * - * @param {Number} lineIndex - * @param {Number} charIndex - * @private - */ - _deleteStyleDeclaration: function(lineIndex, charIndex) { - delete this.styles[lineIndex][charIndex]; - }, - - /** - * @param {Number} lineIndex - * @return {Boolean} if the line exists or not - * @private - */ - _getLineStyle: function(lineIndex) { - return !!this.styles[lineIndex]; - }, - - /** - * Set the line style to an empty object so that is initialized - * @param {Number} lineIndex - * @private - */ - _setLineStyle: function(lineIndex) { - this.styles[lineIndex] = {}; - }, - - /** - * @param {Number} lineIndex - * @private - */ - _deleteLineStyle: function(lineIndex) { - delete this.styles[lineIndex]; - } - }); -})(); - - -(function() { - - function parseDecoration(object) { - if (object.textDecoration) { - object.textDecoration.indexOf('underline') > -1 && (object.underline = true); - object.textDecoration.indexOf('line-through') > -1 && (object.linethrough = true); - object.textDecoration.indexOf('overline') > -1 && (object.overline = true); - delete object.textDecoration; - } - } - - /** - * IText class (introduced in v1.4) Events are also fired with "text:" - * prefix when observing canvas. - * @class fabric.IText - * @extends fabric.Text - * @mixes fabric.Observable - * - * @fires changed - * @fires selection:changed - * @fires editing:entered - * @fires editing:exited - * - * @return {fabric.IText} thisArg - * @see {@link fabric.IText#initialize} for constructor definition - * - *

    Supported key combinations:

    - *
    -   *   Move cursor:                    left, right, up, down
    -   *   Select character:               shift + left, shift + right
    -   *   Select text vertically:         shift + up, shift + down
    -   *   Move cursor by word:            alt + left, alt + right
    -   *   Select words:                   shift + alt + left, shift + alt + right
    -   *   Move cursor to line start/end:  cmd + left, cmd + right or home, end
    -   *   Select till start/end of line:  cmd + shift + left, cmd + shift + right or shift + home, shift + end
    -   *   Jump to start/end of text:      cmd + up, cmd + down
    -   *   Select till start/end of text:  cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown
    -   *   Delete character:               backspace
    -   *   Delete word:                    alt + backspace
    -   *   Delete line:                    cmd + backspace
    -   *   Forward delete:                 delete
    -   *   Copy text:                      ctrl/cmd + c
    -   *   Paste text:                     ctrl/cmd + v
    -   *   Cut text:                       ctrl/cmd + x
    -   *   Select entire text:             ctrl/cmd + a
    -   *   Quit editing                    tab or esc
    -   * 
    - * - *

    Supported mouse/touch combination

    - *
    -   *   Position cursor:                click/touch
    -   *   Create selection:               click/touch & drag
    -   *   Create selection:               click & shift + click
    -   *   Select word:                    double click
    -   *   Select line:                    triple click
    -   * 
    - */ - fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable, /** @lends fabric.IText.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'i-text', - - /** - * Index where text selection starts (or where cursor is when there is no selection) - * @type Number - * @default - */ - selectionStart: 0, - - /** - * Index where text selection ends - * @type Number - * @default - */ - selectionEnd: 0, - - /** - * Color of text selection - * @type String - * @default - */ - selectionColor: 'rgba(17,119,255,0.3)', - - /** - * Indicates whether text is in editing mode - * @type Boolean - * @default - */ - isEditing: false, - - /** - * Indicates whether a text can be edited - * @type Boolean - * @default - */ - editable: true, - - /** - * Border color of text object while it's in editing mode - * @type String - * @default - */ - editingBorderColor: 'rgba(102,153,255,0.25)', - - /** - * Width of cursor (in px) - * @type Number - * @default - */ - cursorWidth: 2, - - /** - * Color of text cursor color in editing mode. - * if not set (default) will take color from the text. - * if set to a color value that fabric can understand, it will - * be used instead of the color of the text at the current position. - * @type String - * @default - */ - cursorColor: '', - - /** - * Delay between cursor blink (in ms) - * @type Number - * @default - */ - cursorDelay: 1000, - - /** - * Duration of cursor fadein (in ms) - * @type Number - * @default - */ - cursorDuration: 600, - - /** - * Indicates whether internal text char widths can be cached - * @type Boolean - * @default - */ - caching: true, - - /** - * DOM container to append the hiddenTextarea. - * An alternative to attaching to the document.body. - * Useful to reduce laggish redraw of the full document.body tree and - * also with modals event capturing that won't let the textarea take focus. - * @type HTMLElement - * @default - */ - hiddenTextareaContainer: null, - - /** - * @private - */ - _reSpace: /\s|\n/, - - /** - * @private - */ - _currentCursorOpacity: 0, - - /** - * @private - */ - _selectionDirection: null, - - /** - * @private - */ - _abortCursorAnimation: false, - - /** - * @private - */ - __widthOfSpace: [], - - /** - * Helps determining when the text is in composition, so that the cursor - * rendering is altered. - */ - inCompositionMode: false, - - /** - * Constructor - * @param {String} text Text string - * @param {Object} [options] Options object - * @return {fabric.IText} thisArg - */ - initialize: function(text, options) { - this.callSuper('initialize', text, options); - this.initBehavior(); - }, - - /** - * Sets selection start (left boundary of a selection) - * @param {Number} index Index to set selection start to - */ - setSelectionStart: function(index) { - index = Math.max(index, 0); - this._updateAndFire('selectionStart', index); - }, - - /** - * Sets selection end (right boundary of a selection) - * @param {Number} index Index to set selection end to - */ - setSelectionEnd: function(index) { - index = Math.min(index, this.text.length); - this._updateAndFire('selectionEnd', index); - }, - - /** - * @private - * @param {String} property 'selectionStart' or 'selectionEnd' - * @param {Number} index new position of property - */ - _updateAndFire: function(property, index) { - if (this[property] !== index) { - this._fireSelectionChanged(); - this[property] = index; - } - this._updateTextarea(); - }, - - /** - * Fires the even of selection changed - * @private - */ - _fireSelectionChanged: function() { - this.fire('selection:changed'); - this.canvas && this.canvas.fire('text:selection:changed', { target: this }); - }, - - /** - * Initialize text dimensions. Render all text on given context - * or on a offscreen canvas to get the text width with measureText. - * Updates this.width and this.height with the proper values. - * Does not return dimensions. - * @private - */ - initDimensions: function() { - this.isEditing && this.initDelayedCursor(); - this.clearContextTop(); - this.callSuper('initDimensions'); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - render: function(ctx) { - this.clearContextTop(); - this.callSuper('render', ctx); - // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor - // the correct position but not at every cursor animation. - this.cursorOffsetCache = { }; - this.renderCursorOrSelection(); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - this.callSuper('_render', ctx); - }, - - /** - * Prepare and clean the contextTop - */ - clearContextTop: function(skipRestore) { - if (!this.isEditing || !this.canvas || !this.canvas.contextTop) { - return; - } - var ctx = this.canvas.contextTop, v = this.canvas.viewportTransform; - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - this.transform(ctx); - this._clearTextArea(ctx); - skipRestore || ctx.restore(); - }, - /** - * Renders cursor or selection (depending on what exists) - * it does on the contextTop. If contextTop is not available, do nothing. - */ - renderCursorOrSelection: function() { - if (!this.isEditing || !this.canvas || !this.canvas.contextTop) { - return; - } - var boundaries = this._getCursorBoundaries(), - ctx = this.canvas.contextTop; - this.clearContextTop(true); - if (this.selectionStart === this.selectionEnd) { - this.renderCursor(boundaries, ctx); - } - else { - this.renderSelection(boundaries, ctx); - } - ctx.restore(); - }, - - _clearTextArea: function(ctx) { - // we add 4 pixel, to be sure to do not leave any pixel out - var width = this.width + 4, height = this.height + 4; - ctx.clearRect(-width / 2, -height / 2, width, height); - }, - - /** - * Returns cursor boundaries (left, top, leftOffset, topOffset) - * @private - * @param {Array} chars Array of characters - * @param {String} typeOfBoundaries - */ - _getCursorBoundaries: function(position) { - - // left/top are left/top of entire text box - // leftOffset/topOffset are offset from that left/top point of a text box - - if (typeof position === 'undefined') { - position = this.selectionStart; - } - - var left = this._getLeftOffset(), - top = this._getTopOffset(), - offsets = this._getCursorBoundariesOffsets(position); - return { - left: left, - top: top, - leftOffset: offsets.left, - topOffset: offsets.top - }; - }, - - /** - * @private - */ - _getCursorBoundariesOffsets: function(position) { - if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) { - return this.cursorOffsetCache; - } - var lineLeftOffset, - lineIndex, - charIndex, - topOffset = 0, - leftOffset = 0, - boundaries, - cursorPosition = this.get2DCursorLocation(position); - charIndex = cursorPosition.charIndex; - lineIndex = cursorPosition.lineIndex; - for (var i = 0; i < lineIndex; i++) { - topOffset += this.getHeightOfLine(i); - } - lineLeftOffset = this._getLineLeftOffset(lineIndex); - var bound = this.__charBounds[lineIndex][charIndex]; - bound && (leftOffset = bound.left); - if (this.charSpacing !== 0 && charIndex === this._textLines[lineIndex].length) { - leftOffset -= this._getWidthOfCharSpacing(); - } - boundaries = { - top: topOffset, - left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0), - }; - if (this.direction === 'rtl') { - boundaries.left *= -1; - } - this.cursorOffsetCache = boundaries; - return this.cursorOffsetCache; - }, - - /** - * Renders cursor - * @param {Object} boundaries - * @param {CanvasRenderingContext2D} ctx transformed context to draw on - */ - renderCursor: function(boundaries, ctx) { - var cursorLocation = this.get2DCursorLocation(), - lineIndex = cursorLocation.lineIndex, - charIndex = cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0, - charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'), - multiplier = this.scaleX * this.canvas.getZoom(), - cursorWidth = this.cursorWidth / multiplier, - topOffset = boundaries.topOffset, - dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY'); - topOffset += (1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex) / this.lineHeight - - charHeight * (1 - this._fontSizeFraction); - - if (this.inCompositionMode) { - this.renderSelection(boundaries, ctx); - } - ctx.fillStyle = this.cursorColor || this.getValueOfPropertyAt(lineIndex, charIndex, 'fill'); - ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity; - ctx.fillRect( - boundaries.left + boundaries.leftOffset - cursorWidth / 2, - topOffset + boundaries.top + dy, - cursorWidth, - charHeight); - }, - - /** - * Renders text selection - * @param {Object} boundaries Object with left/top/leftOffset/topOffset - * @param {CanvasRenderingContext2D} ctx transformed context to draw on - */ - renderSelection: function(boundaries, ctx) { - - var selectionStart = this.inCompositionMode ? this.hiddenTextarea.selectionStart : this.selectionStart, - selectionEnd = this.inCompositionMode ? this.hiddenTextarea.selectionEnd : this.selectionEnd, - isJustify = this.textAlign.indexOf('justify') !== -1, - start = this.get2DCursorLocation(selectionStart), - end = this.get2DCursorLocation(selectionEnd), - startLine = start.lineIndex, - endLine = end.lineIndex, - startChar = start.charIndex < 0 ? 0 : start.charIndex, - endChar = end.charIndex < 0 ? 0 : end.charIndex; - - for (var i = startLine; i <= endLine; i++) { - var lineOffset = this._getLineLeftOffset(i) || 0, - lineHeight = this.getHeightOfLine(i), - realLineHeight = 0, boxStart = 0, boxEnd = 0; - - if (i === startLine) { - boxStart = this.__charBounds[startLine][startChar].left; - } - if (i >= startLine && i < endLine) { - boxEnd = isJustify && !this.isEndOfWrapping(i) ? this.width : this.getLineWidth(i) || 5; // WTF is this 5? - } - else if (i === endLine) { - if (endChar === 0) { - boxEnd = this.__charBounds[endLine][endChar].left; - } - else { - var charSpacing = this._getWidthOfCharSpacing(); - boxEnd = this.__charBounds[endLine][endChar - 1].left - + this.__charBounds[endLine][endChar - 1].width - charSpacing; - } - } - realLineHeight = lineHeight; - if (this.lineHeight < 1 || (i === endLine && this.lineHeight > 1)) { - lineHeight /= this.lineHeight; - } - var drawStart = boundaries.left + lineOffset + boxStart, - drawWidth = boxEnd - boxStart, - drawHeight = lineHeight, extraTop = 0; - if (this.inCompositionMode) { - ctx.fillStyle = this.compositionColor || 'black'; - drawHeight = 1; - extraTop = lineHeight; - } - else { - ctx.fillStyle = this.selectionColor; - } - if (this.direction === 'rtl') { - drawStart = this.width - drawStart - drawWidth; - } - ctx.fillRect( - drawStart, - boundaries.top + boundaries.topOffset + extraTop, - drawWidth, - drawHeight); - boundaries.topOffset += realLineHeight; - } - }, - - /** - * High level function to know the height of the cursor. - * the currentChar is the one that precedes the cursor - * Returns fontSize of char at the current cursor - * Unused from the library, is for the end user - * @return {Number} Character font size - */ - getCurrentCharFontSize: function() { - var cp = this._getCurrentCharIndex(); - return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize'); - }, - - /** - * High level function to know the color of the cursor. - * the currentChar is the one that precedes the cursor - * Returns color (fill) of char at the current cursor - * if the text object has a pattern or gradient for filler, it will return that. - * Unused by the library, is for the end user - * @return {String | fabric.Gradient | fabric.Pattern} Character color (fill) - */ - getCurrentCharColor: function() { - var cp = this._getCurrentCharIndex(); - return this.getValueOfPropertyAt(cp.l, cp.c, 'fill'); - }, - - /** - * Returns the cursor position for the getCurrent.. functions - * @private - */ - _getCurrentCharIndex: function() { - var cursorPosition = this.get2DCursorLocation(this.selectionStart, true), - charIndex = cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0; - return { l: cursorPosition.lineIndex, c: charIndex }; - } - }); - - /** - * Returns fabric.IText instance from an object representation - * @static - * @memberOf fabric.IText - * @param {Object} object Object to create an instance from - * @param {function} [callback] invoked with new instance as argument - */ - fabric.IText.fromObject = function(object, callback) { - parseDecoration(object); - if (object.styles) { - for (var i in object.styles) { - for (var j in object.styles[i]) { - parseDecoration(object.styles[i][j]); - } - } - } - fabric.Object._fromObject('IText', object, callback, 'text'); - }; -})(); - - -(function() { - - var clone = fabric.util.object.clone; - - fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ { - - /** - * Initializes all the interactive behavior of IText - */ - initBehavior: function() { - this.initAddedHandler(); - this.initRemovedHandler(); - this.initCursorSelectionHandlers(); - this.initDoubleClickSimulation(); - this.mouseMoveHandler = this.mouseMoveHandler.bind(this); - }, - - onDeselect: function() { - this.isEditing && this.exitEditing(); - this.selected = false; - }, - - /** - * Initializes "added" event handler - */ - initAddedHandler: function() { - var _this = this; - this.on('added', function() { - var canvas = _this.canvas; - if (canvas) { - if (!canvas._hasITextHandlers) { - canvas._hasITextHandlers = true; - _this._initCanvasHandlers(canvas); - } - canvas._iTextInstances = canvas._iTextInstances || []; - canvas._iTextInstances.push(_this); - } - }); - }, - - initRemovedHandler: function() { - var _this = this; - this.on('removed', function() { - var canvas = _this.canvas; - if (canvas) { - canvas._iTextInstances = canvas._iTextInstances || []; - fabric.util.removeFromArray(canvas._iTextInstances, _this); - if (canvas._iTextInstances.length === 0) { - canvas._hasITextHandlers = false; - _this._removeCanvasHandlers(canvas); - } - } - }); - }, - - /** - * register canvas event to manage exiting on other instances - * @private - */ - _initCanvasHandlers: function(canvas) { - canvas._mouseUpITextHandler = function() { - if (canvas._iTextInstances) { - canvas._iTextInstances.forEach(function(obj) { - obj.__isMousedown = false; - }); - } - }; - canvas.on('mouse:up', canvas._mouseUpITextHandler); - }, - - /** - * remove canvas event to manage exiting on other instances - * @private - */ - _removeCanvasHandlers: function(canvas) { - canvas.off('mouse:up', canvas._mouseUpITextHandler); - }, - - /** - * @private - */ - _tick: function() { - this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, '_onTickComplete'); - }, - - /** - * @private - */ - _animateCursor: function(obj, targetOpacity, duration, completeMethod) { - - var tickState; - - tickState = { - isAborted: false, - abort: function() { - this.isAborted = true; - }, - }; - - obj.animate('_currentCursorOpacity', targetOpacity, { - duration: duration, - onComplete: function() { - if (!tickState.isAborted) { - obj[completeMethod](); - } - }, - onChange: function() { - // we do not want to animate a selection, only cursor - if (obj.canvas && obj.selectionStart === obj.selectionEnd) { - obj.renderCursorOrSelection(); - } - }, - abort: function() { - return tickState.isAborted; - } - }); - return tickState; - }, - - /** - * @private - */ - _onTickComplete: function() { - - var _this = this; - - if (this._cursorTimeout1) { - clearTimeout(this._cursorTimeout1); - } - this._cursorTimeout1 = setTimeout(function() { - _this._currentTickCompleteState = _this._animateCursor(_this, 0, this.cursorDuration / 2, '_tick'); - }, 100); - }, - - /** - * Initializes delayed cursor - */ - initDelayedCursor: function(restart) { - var _this = this, - delay = restart ? 0 : this.cursorDelay; - - this.abortCursorAnimation(); - this._currentCursorOpacity = 1; - this._cursorTimeout2 = setTimeout(function() { - _this._tick(); - }, delay); - }, - - /** - * Aborts cursor animation and clears all timeouts - */ - abortCursorAnimation: function() { - var shouldClear = this._currentTickState || this._currentTickCompleteState, - canvas = this.canvas; - this._currentTickState && this._currentTickState.abort(); - this._currentTickCompleteState && this._currentTickCompleteState.abort(); - - clearTimeout(this._cursorTimeout1); - clearTimeout(this._cursorTimeout2); - - this._currentCursorOpacity = 0; - // to clear just itext area we need to transform the context - // it may not be worth it - if (shouldClear && canvas) { - canvas.clearContext(canvas.contextTop || canvas.contextContainer); - } - - }, - - /** - * Selects entire text - * @return {fabric.IText} thisArg - * @chainable - */ - selectAll: function() { - this.selectionStart = 0; - this.selectionEnd = this._text.length; - this._fireSelectionChanged(); - this._updateTextarea(); - return this; - }, - - /** - * Returns selected text - * @return {String} - */ - getSelectedText: function() { - return this._text.slice(this.selectionStart, this.selectionEnd).join(''); - }, - - /** - * Find new selection index representing start of current word according to current selection index - * @param {Number} startFrom Current selection index - * @return {Number} New selection index - */ - findWordBoundaryLeft: function(startFrom) { - var offset = 0, index = startFrom - 1; - - // remove space before cursor first - if (this._reSpace.test(this._text[index])) { - while (this._reSpace.test(this._text[index])) { - offset++; - index--; - } - } - while (/\S/.test(this._text[index]) && index > -1) { - offset++; - index--; - } - - return startFrom - offset; - }, - - /** - * Find new selection index representing end of current word according to current selection index - * @param {Number} startFrom Current selection index - * @return {Number} New selection index - */ - findWordBoundaryRight: function(startFrom) { - var offset = 0, index = startFrom; - - // remove space after cursor first - if (this._reSpace.test(this._text[index])) { - while (this._reSpace.test(this._text[index])) { - offset++; - index++; - } - } - while (/\S/.test(this._text[index]) && index < this._text.length) { - offset++; - index++; - } - - return startFrom + offset; - }, - - /** - * Find new selection index representing start of current line according to current selection index - * @param {Number} startFrom Current selection index - * @return {Number} New selection index - */ - findLineBoundaryLeft: function(startFrom) { - var offset = 0, index = startFrom - 1; - - while (!/\n/.test(this._text[index]) && index > -1) { - offset++; - index--; - } - - return startFrom - offset; - }, - - /** - * Find new selection index representing end of current line according to current selection index - * @param {Number} startFrom Current selection index - * @return {Number} New selection index - */ - findLineBoundaryRight: function(startFrom) { - var offset = 0, index = startFrom; - - while (!/\n/.test(this._text[index]) && index < this._text.length) { - offset++; - index++; - } - - return startFrom + offset; - }, - - /** - * Finds index corresponding to beginning or end of a word - * @param {Number} selectionStart Index of a character - * @param {Number} direction 1 or -1 - * @return {Number} Index of the beginning or end of a word - */ - searchWordBoundary: function(selectionStart, direction) { - var text = this._text, - index = this._reSpace.test(text[selectionStart]) ? selectionStart - 1 : selectionStart, - _char = text[index], - // wrong - reNonWord = fabric.reNonWord; - - while (!reNonWord.test(_char) && index > 0 && index < text.length) { - index += direction; - _char = text[index]; - } - if (reNonWord.test(_char)) { - index += direction === 1 ? 0 : 1; - } - return index; - }, - - /** - * Selects a word based on the index - * @param {Number} selectionStart Index of a character - */ - selectWord: function(selectionStart) { - selectionStart = selectionStart || this.selectionStart; - var newSelectionStart = this.searchWordBoundary(selectionStart, -1), /* search backwards */ - newSelectionEnd = this.searchWordBoundary(selectionStart, 1); /* search forward */ - - this.selectionStart = newSelectionStart; - this.selectionEnd = newSelectionEnd; - this._fireSelectionChanged(); - this._updateTextarea(); - this.renderCursorOrSelection(); - }, - - /** - * Selects a line based on the index - * @param {Number} selectionStart Index of a character - * @return {fabric.IText} thisArg - * @chainable - */ - selectLine: function(selectionStart) { - selectionStart = selectionStart || this.selectionStart; - var newSelectionStart = this.findLineBoundaryLeft(selectionStart), - newSelectionEnd = this.findLineBoundaryRight(selectionStart); - - this.selectionStart = newSelectionStart; - this.selectionEnd = newSelectionEnd; - this._fireSelectionChanged(); - this._updateTextarea(); - return this; - }, - - /** - * Enters editing state - * @return {fabric.IText} thisArg - * @chainable - */ - enterEditing: function(e) { - if (this.isEditing || !this.editable) { - return; - } - - if (this.canvas) { - this.canvas.calcOffset(); - this.exitEditingOnOthers(this.canvas); - } - - this.isEditing = true; - - this.initHiddenTextarea(e); - this.hiddenTextarea.focus(); - this.hiddenTextarea.value = this.text; - this._updateTextarea(); - this._saveEditingProps(); - this._setEditingProps(); - this._textBeforeEdit = this.text; - - this._tick(); - this.fire('editing:entered'); - this._fireSelectionChanged(); - if (!this.canvas) { - return this; - } - this.canvas.fire('text:editing:entered', { target: this }); - this.initMouseMoveHandler(); - this.canvas.requestRenderAll(); - return this; - }, - - exitEditingOnOthers: function(canvas) { - if (canvas._iTextInstances) { - canvas._iTextInstances.forEach(function(obj) { - obj.selected = false; - if (obj.isEditing) { - obj.exitEditing(); - } - }); - } - }, - - /** - * Initializes "mousemove" event handler - */ - initMouseMoveHandler: function() { - this.canvas.on('mouse:move', this.mouseMoveHandler); - }, - - /** - * @private - */ - mouseMoveHandler: function(options) { - if (!this.__isMousedown || !this.isEditing) { - return; - } - - var newSelectionStart = this.getSelectionStartFromPointer(options.e), - currentStart = this.selectionStart, - currentEnd = this.selectionEnd; - if ( - (newSelectionStart !== this.__selectionStartOnMouseDown || currentStart === currentEnd) - && - (currentStart === newSelectionStart || currentEnd === newSelectionStart) - ) { - return; - } - if (newSelectionStart > this.__selectionStartOnMouseDown) { - this.selectionStart = this.__selectionStartOnMouseDown; - this.selectionEnd = newSelectionStart; - } - else { - this.selectionStart = newSelectionStart; - this.selectionEnd = this.__selectionStartOnMouseDown; - } - if (this.selectionStart !== currentStart || this.selectionEnd !== currentEnd) { - this.restartCursorIfNeeded(); - this._fireSelectionChanged(); - this._updateTextarea(); - this.renderCursorOrSelection(); - } - }, - - /** - * @private - */ - _setEditingProps: function() { - this.hoverCursor = 'text'; - - if (this.canvas) { - this.canvas.defaultCursor = this.canvas.moveCursor = 'text'; - } - - this.borderColor = this.editingBorderColor; - this.hasControls = this.selectable = false; - this.lockMovementX = this.lockMovementY = true; - }, - - /** - * convert from textarea to grapheme indexes - */ - fromStringToGraphemeSelection: function(start, end, text) { - var smallerTextStart = text.slice(0, start), - graphemeStart = fabric.util.string.graphemeSplit(smallerTextStart).length; - if (start === end) { - return { selectionStart: graphemeStart, selectionEnd: graphemeStart }; - } - var smallerTextEnd = text.slice(start, end), - graphemeEnd = fabric.util.string.graphemeSplit(smallerTextEnd).length; - return { selectionStart: graphemeStart, selectionEnd: graphemeStart + graphemeEnd }; - }, - - /** - * convert from fabric to textarea values - */ - fromGraphemeToStringSelection: function(start, end, _text) { - var smallerTextStart = _text.slice(0, start), - graphemeStart = smallerTextStart.join('').length; - if (start === end) { - return { selectionStart: graphemeStart, selectionEnd: graphemeStart }; - } - var smallerTextEnd = _text.slice(start, end), - graphemeEnd = smallerTextEnd.join('').length; - return { selectionStart: graphemeStart, selectionEnd: graphemeStart + graphemeEnd }; - }, - - /** - * @private - */ - _updateTextarea: function() { - this.cursorOffsetCache = { }; - if (!this.hiddenTextarea) { - return; - } - if (!this.inCompositionMode) { - var newSelection = this.fromGraphemeToStringSelection(this.selectionStart, this.selectionEnd, this._text); - this.hiddenTextarea.selectionStart = newSelection.selectionStart; - this.hiddenTextarea.selectionEnd = newSelection.selectionEnd; - } - this.updateTextareaPosition(); - }, - - /** - * @private - */ - updateFromTextArea: function() { - if (!this.hiddenTextarea) { - return; - } - this.cursorOffsetCache = { }; - this.text = this.hiddenTextarea.value; - if (this._shouldClearDimensionCache()) { - this.initDimensions(); - this.setCoords(); - } - var newSelection = this.fromStringToGraphemeSelection( - this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value); - this.selectionEnd = this.selectionStart = newSelection.selectionEnd; - if (!this.inCompositionMode) { - this.selectionStart = newSelection.selectionStart; - } - this.updateTextareaPosition(); - }, - - /** - * @private - */ - updateTextareaPosition: function() { - if (this.selectionStart === this.selectionEnd) { - var style = this._calcTextareaPosition(); - this.hiddenTextarea.style.left = style.left; - this.hiddenTextarea.style.top = style.top; - } - }, - - /** - * @private - * @return {Object} style contains style for hiddenTextarea - */ - _calcTextareaPosition: function() { - if (!this.canvas) { - return { x: 1, y: 1 }; - } - var desiredPosition = this.inCompositionMode ? this.compositionStart : this.selectionStart, - boundaries = this._getCursorBoundaries(desiredPosition), - cursorLocation = this.get2DCursorLocation(desiredPosition), - lineIndex = cursorLocation.lineIndex, - charIndex = cursorLocation.charIndex, - charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') * this.lineHeight, - leftOffset = boundaries.leftOffset, - m = this.calcTransformMatrix(), - p = { - x: boundaries.left + leftOffset, - y: boundaries.top + boundaries.topOffset + charHeight - }, - retinaScaling = this.canvas.getRetinaScaling(), - upperCanvas = this.canvas.upperCanvasEl, - upperCanvasWidth = upperCanvas.width / retinaScaling, - upperCanvasHeight = upperCanvas.height / retinaScaling, - maxWidth = upperCanvasWidth - charHeight, - maxHeight = upperCanvasHeight - charHeight, - scaleX = upperCanvas.clientWidth / upperCanvasWidth, - scaleY = upperCanvas.clientHeight / upperCanvasHeight; - - p = fabric.util.transformPoint(p, m); - p = fabric.util.transformPoint(p, this.canvas.viewportTransform); - p.x *= scaleX; - p.y *= scaleY; - if (p.x < 0) { - p.x = 0; - } - if (p.x > maxWidth) { - p.x = maxWidth; - } - if (p.y < 0) { - p.y = 0; - } - if (p.y > maxHeight) { - p.y = maxHeight; - } - - // add canvas offset on document - p.x += this.canvas._offset.left; - p.y += this.canvas._offset.top; - - return { left: p.x + 'px', top: p.y + 'px', fontSize: charHeight + 'px', charHeight: charHeight }; - }, - - /** - * @private - */ - _saveEditingProps: function() { - this._savedProps = { - hasControls: this.hasControls, - borderColor: this.borderColor, - lockMovementX: this.lockMovementX, - lockMovementY: this.lockMovementY, - hoverCursor: this.hoverCursor, - selectable: this.selectable, - defaultCursor: this.canvas && this.canvas.defaultCursor, - moveCursor: this.canvas && this.canvas.moveCursor - }; - }, - - /** - * @private - */ - _restoreEditingProps: function() { - if (!this._savedProps) { - return; - } - - this.hoverCursor = this._savedProps.hoverCursor; - this.hasControls = this._savedProps.hasControls; - this.borderColor = this._savedProps.borderColor; - this.selectable = this._savedProps.selectable; - this.lockMovementX = this._savedProps.lockMovementX; - this.lockMovementY = this._savedProps.lockMovementY; - - if (this.canvas) { - this.canvas.defaultCursor = this._savedProps.defaultCursor; - this.canvas.moveCursor = this._savedProps.moveCursor; - } - }, - - /** - * Exits from editing state - * @return {fabric.IText} thisArg - * @chainable - */ - exitEditing: function() { - var isTextChanged = (this._textBeforeEdit !== this.text); - var hiddenTextarea = this.hiddenTextarea; - this.selected = false; - this.isEditing = false; - - this.selectionEnd = this.selectionStart; - - if (hiddenTextarea) { - hiddenTextarea.blur && hiddenTextarea.blur(); - hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea); - } - this.hiddenTextarea = null; - this.abortCursorAnimation(); - this._restoreEditingProps(); - this._currentCursorOpacity = 0; - if (this._shouldClearDimensionCache()) { - this.initDimensions(); - this.setCoords(); - } - this.fire('editing:exited'); - isTextChanged && this.fire('modified'); - if (this.canvas) { - this.canvas.off('mouse:move', this.mouseMoveHandler); - this.canvas.fire('text:editing:exited', { target: this }); - isTextChanged && this.canvas.fire('object:modified', { target: this }); - } - return this; - }, - - /** - * @private - */ - _removeExtraneousStyles: function() { - for (var prop in this.styles) { - if (!this._textLines[prop]) { - delete this.styles[prop]; - } - } - }, - - /** - * remove and reflow a style block from start to end. - * @param {Number} start linear start position for removal (included in removal) - * @param {Number} end linear end position for removal ( excluded from removal ) - */ - removeStyleFromTo: function(start, end) { - var cursorStart = this.get2DCursorLocation(start, true), - cursorEnd = this.get2DCursorLocation(end, true), - lineStart = cursorStart.lineIndex, - charStart = cursorStart.charIndex, - lineEnd = cursorEnd.lineIndex, - charEnd = cursorEnd.charIndex, - i, styleObj; - if (lineStart !== lineEnd) { - // step1 remove the trailing of lineStart - if (this.styles[lineStart]) { - for (i = charStart; i < this._unwrappedTextLines[lineStart].length; i++) { - delete this.styles[lineStart][i]; - } - } - // step2 move the trailing of lineEnd to lineStart if needed - if (this.styles[lineEnd]) { - for (i = charEnd; i < this._unwrappedTextLines[lineEnd].length; i++) { - styleObj = this.styles[lineEnd][i]; - if (styleObj) { - this.styles[lineStart] || (this.styles[lineStart] = { }); - this.styles[lineStart][charStart + i - charEnd] = styleObj; - } - } - } - // step3 detects lines will be completely removed. - for (i = lineStart + 1; i <= lineEnd; i++) { - delete this.styles[i]; - } - // step4 shift remaining lines. - this.shiftLineStyles(lineEnd, lineStart - lineEnd); - } - else { - // remove and shift left on the same line - if (this.styles[lineStart]) { - styleObj = this.styles[lineStart]; - var diff = charEnd - charStart, numericChar, _char; - for (i = charStart; i < charEnd; i++) { - delete styleObj[i]; - } - for (_char in this.styles[lineStart]) { - numericChar = parseInt(_char, 10); - if (numericChar >= charEnd) { - styleObj[numericChar - diff] = styleObj[_char]; - delete styleObj[_char]; - } - } - } - } - }, - - /** - * Shifts line styles up or down - * @param {Number} lineIndex Index of a line - * @param {Number} offset Can any number? - */ - shiftLineStyles: function(lineIndex, offset) { - // shift all line styles by offset upward or downward - // do not clone deep. we need new array, not new style objects - var clonedStyles = clone(this.styles); - for (var line in this.styles) { - var numericLine = parseInt(line, 10); - if (numericLine > lineIndex) { - this.styles[numericLine + offset] = clonedStyles[numericLine]; - if (!clonedStyles[numericLine - offset]) { - delete this.styles[numericLine]; - } - } - } - }, - - restartCursorIfNeeded: function() { - if (!this._currentTickState || this._currentTickState.isAborted - || !this._currentTickCompleteState || this._currentTickCompleteState.isAborted - ) { - this.initDelayedCursor(); - } - }, - - /** - * Handle insertion of more consecutive style lines for when one or more - * newlines gets added to the text. Since current style needs to be shifted - * first we shift the current style of the number lines needed, then we add - * new lines from the last to the first. - * @param {Number} lineIndex Index of a line - * @param {Number} charIndex Index of a char - * @param {Number} qty number of lines to add - * @param {Array} copiedStyle Array of objects styles - */ - insertNewlineStyleObject: function(lineIndex, charIndex, qty, copiedStyle) { - var currentCharStyle, - newLineStyles = {}, - somethingAdded = false, - isEndOfLine = this._unwrappedTextLines[lineIndex].length === charIndex; - - qty || (qty = 1); - this.shiftLineStyles(lineIndex, qty); - if (this.styles[lineIndex]) { - currentCharStyle = this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1]; - } - // we clone styles of all chars - // after cursor onto the current line - for (var index in this.styles[lineIndex]) { - var numIndex = parseInt(index, 10); - if (numIndex >= charIndex) { - somethingAdded = true; - newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index]; - // remove lines from the previous line since they're on a new line now - if (!(isEndOfLine && charIndex === 0)) { - delete this.styles[lineIndex][index]; - } - } - } - var styleCarriedOver = false; - if (somethingAdded && !isEndOfLine) { - // if is end of line, the extra style we copied - // is probably not something we want - this.styles[lineIndex + qty] = newLineStyles; - styleCarriedOver = true; - } - if (styleCarriedOver) { - // skip the last line of since we already prepared it. - qty--; - } - // for the all the lines or all the other lines - // we clone current char style onto the next (otherwise empty) line - while (qty > 0) { - if (copiedStyle && copiedStyle[qty - 1]) { - this.styles[lineIndex + qty] = { 0: clone(copiedStyle[qty - 1]) }; - } - else if (currentCharStyle) { - this.styles[lineIndex + qty] = { 0: clone(currentCharStyle) }; - } - else { - delete this.styles[lineIndex + qty]; - } - qty--; - } - this._forceClearCache = true; - }, - - /** - * Inserts style object for a given line/char index - * @param {Number} lineIndex Index of a line - * @param {Number} charIndex Index of a char - * @param {Number} quantity number Style object to insert, if given - * @param {Array} copiedStyle array of style objects - */ - insertCharStyleObject: function(lineIndex, charIndex, quantity, copiedStyle) { - if (!this.styles) { - this.styles = {}; - } - var currentLineStyles = this.styles[lineIndex], - currentLineStylesCloned = currentLineStyles ? clone(currentLineStyles) : {}; - - quantity || (quantity = 1); - // shift all char styles by quantity forward - // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4 - for (var index in currentLineStylesCloned) { - var numericIndex = parseInt(index, 10); - if (numericIndex >= charIndex) { - currentLineStyles[numericIndex + quantity] = currentLineStylesCloned[numericIndex]; - // only delete the style if there was nothing moved there - if (!currentLineStylesCloned[numericIndex - quantity]) { - delete currentLineStyles[numericIndex]; - } - } - } - this._forceClearCache = true; - if (copiedStyle) { - while (quantity--) { - if (!Object.keys(copiedStyle[quantity]).length) { - continue; - } - if (!this.styles[lineIndex]) { - this.styles[lineIndex] = {}; - } - this.styles[lineIndex][charIndex + quantity] = clone(copiedStyle[quantity]); - } - return; - } - if (!currentLineStyles) { - return; - } - var newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1]; - while (newStyle && quantity--) { - this.styles[lineIndex][charIndex + quantity] = clone(newStyle); - } - }, - - /** - * Inserts style object(s) - * @param {Array} insertedText Characters at the location where style is inserted - * @param {Number} start cursor index for inserting style - * @param {Array} [copiedStyle] array of style objects to insert. - */ - insertNewStyleBlock: function(insertedText, start, copiedStyle) { - var cursorLoc = this.get2DCursorLocation(start, true), - addedLines = [0], linesLength = 0; - // get an array of how many char per lines are being added. - for (var i = 0; i < insertedText.length; i++) { - if (insertedText[i] === '\n') { - linesLength++; - addedLines[linesLength] = 0; - } - else { - addedLines[linesLength]++; - } - } - // for the first line copy the style from the current char position. - if (addedLines[0] > 0) { - this.insertCharStyleObject(cursorLoc.lineIndex, cursorLoc.charIndex, addedLines[0], copiedStyle); - copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1); - } - linesLength && this.insertNewlineStyleObject( - cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLength); - for (var i = 1; i < linesLength; i++) { - if (addedLines[i] > 0) { - this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle); - } - else if (copiedStyle) { - this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0]; - } - copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1); - } - // we use i outside the loop to get it like linesLength - if (addedLines[i] > 0) { - this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle); - } - }, - - /** - * Set the selectionStart and selectionEnd according to the new position of cursor - * mimic the key - mouse navigation when shift is pressed. - */ - setSelectionStartEndWithShift: function(start, end, newSelection) { - if (newSelection <= start) { - if (end === start) { - this._selectionDirection = 'left'; - } - else if (this._selectionDirection === 'right') { - this._selectionDirection = 'left'; - this.selectionEnd = start; - } - this.selectionStart = newSelection; - } - else if (newSelection > start && newSelection < end) { - if (this._selectionDirection === 'right') { - this.selectionEnd = newSelection; - } - else { - this.selectionStart = newSelection; - } - } - else { - // newSelection is > selection start and end - if (end === start) { - this._selectionDirection = 'right'; - } - else if (this._selectionDirection === 'left') { - this._selectionDirection = 'right'; - this.selectionStart = end; - } - this.selectionEnd = newSelection; - } - }, - - setSelectionInBoundaries: function() { - var length = this.text.length; - if (this.selectionStart > length) { - this.selectionStart = length; - } - else if (this.selectionStart < 0) { - this.selectionStart = 0; - } - if (this.selectionEnd > length) { - this.selectionEnd = length; - } - else if (this.selectionEnd < 0) { - this.selectionEnd = 0; - } - } - }); -})(); - - -fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ { - /** - * Initializes "dbclick" event handler - */ - initDoubleClickSimulation: function() { - - // for double click - this.__lastClickTime = +new Date(); - - // for triple click - this.__lastLastClickTime = +new Date(); - - this.__lastPointer = { }; - - this.on('mousedown', this.onMouseDown); - }, - - /** - * Default event handler to simulate triple click - * @private - */ - onMouseDown: function(options) { - if (!this.canvas) { - return; - } - this.__newClickTime = +new Date(); - var newPointer = options.pointer; - if (this.isTripleClick(newPointer)) { - this.fire('tripleclick', options); - this._stopEvent(options.e); - } - this.__lastLastClickTime = this.__lastClickTime; - this.__lastClickTime = this.__newClickTime; - this.__lastPointer = newPointer; - this.__lastIsEditing = this.isEditing; - this.__lastSelected = this.selected; - }, - - isTripleClick: function(newPointer) { - return this.__newClickTime - this.__lastClickTime < 500 && - this.__lastClickTime - this.__lastLastClickTime < 500 && - this.__lastPointer.x === newPointer.x && - this.__lastPointer.y === newPointer.y; - }, - - /** - * @private - */ - _stopEvent: function(e) { - e.preventDefault && e.preventDefault(); - e.stopPropagation && e.stopPropagation(); - }, - - /** - * Initializes event handlers related to cursor or selection - */ - initCursorSelectionHandlers: function() { - this.initMousedownHandler(); - this.initMouseupHandler(); - this.initClicks(); - }, - - /** - * Default handler for double click, select a word - */ - doubleClickHandler: function(options) { - if (!this.isEditing) { - return; - } - this.selectWord(this.getSelectionStartFromPointer(options.e)); - }, - - /** - * Default handler for triple click, select a line - */ - tripleClickHandler: function(options) { - if (!this.isEditing) { - return; - } - this.selectLine(this.getSelectionStartFromPointer(options.e)); - }, - - /** - * Initializes double and triple click event handlers - */ - initClicks: function() { - this.on('mousedblclick', this.doubleClickHandler); - this.on('tripleclick', this.tripleClickHandler); - }, - - /** - * Default event handler for the basic functionalities needed on _mouseDown - * can be overridden to do something different. - * Scope of this implementation is: find the click position, set selectionStart - * find selectionEnd, initialize the drawing of either cursor or selection area - * initializing a mousedDown on a text area will cancel fabricjs knowledge of - * current compositionMode. It will be set to false. - */ - _mouseDownHandler: function(options) { - if (!this.canvas || !this.editable || (options.e.button && options.e.button !== 1)) { - return; - } - - this.__isMousedown = true; - - if (this.selected) { - this.inCompositionMode = false; - this.setCursorByClick(options.e); - } - - if (this.isEditing) { - this.__selectionStartOnMouseDown = this.selectionStart; - if (this.selectionStart === this.selectionEnd) { - this.abortCursorAnimation(); - } - this.renderCursorOrSelection(); - } - }, - - /** - * Default event handler for the basic functionalities needed on mousedown:before - * can be overridden to do something different. - * Scope of this implementation is: verify the object is already selected when mousing down - */ - _mouseDownHandlerBefore: function(options) { - if (!this.canvas || !this.editable || (options.e.button && options.e.button !== 1)) { - return; - } - // we want to avoid that an object that was selected and then becomes unselectable, - // may trigger editing mode in some way. - this.selected = this === this.canvas._activeObject; - }, - - /** - * Initializes "mousedown" event handler - */ - initMousedownHandler: function() { - this.on('mousedown', this._mouseDownHandler); - this.on('mousedown:before', this._mouseDownHandlerBefore); - }, - - /** - * Initializes "mouseup" event handler - */ - initMouseupHandler: function() { - this.on('mouseup', this.mouseUpHandler); - }, - - /** - * standard handler for mouse up, overridable - * @private - */ - mouseUpHandler: function(options) { - this.__isMousedown = false; - if (!this.editable || this.group || - (options.transform && options.transform.actionPerformed) || - (options.e.button && options.e.button !== 1)) { - return; - } - - if (this.canvas) { - var currentActive = this.canvas._activeObject; - if (currentActive && currentActive !== this) { - // avoid running this logic when there is an active object - // this because is possible with shift click and fast clicks, - // to rapidly deselect and reselect this object and trigger an enterEdit - return; - } - } - - if (this.__lastSelected && !this.__corner) { - this.selected = false; - this.__lastSelected = false; - this.enterEditing(options.e); - if (this.selectionStart === this.selectionEnd) { - this.initDelayedCursor(true); - } - else { - this.renderCursorOrSelection(); - } - } - else { - this.selected = true; - } - }, - - /** - * Changes cursor location in a text depending on passed pointer (x/y) object - * @param {Event} e Event object - */ - setCursorByClick: function(e) { - var newSelection = this.getSelectionStartFromPointer(e), - start = this.selectionStart, end = this.selectionEnd; - if (e.shiftKey) { - this.setSelectionStartEndWithShift(start, end, newSelection); - } - else { - this.selectionStart = newSelection; - this.selectionEnd = newSelection; - } - if (this.isEditing) { - this._fireSelectionChanged(); - this._updateTextarea(); - } - }, - - /** - * Returns index of a character corresponding to where an object was clicked - * @param {Event} e Event object - * @return {Number} Index of a character - */ - getSelectionStartFromPointer: function(e) { - var mouseOffset = this.getLocalPointer(e), - prevWidth = 0, - width = 0, - height = 0, - charIndex = 0, - lineIndex = 0, - lineLeftOffset, - line; - for (var i = 0, len = this._textLines.length; i < len; i++) { - if (height <= mouseOffset.y) { - height += this.getHeightOfLine(i) * this.scaleY; - lineIndex = i; - if (i > 0) { - charIndex += this._textLines[i - 1].length + this.missingNewlineOffset(i - 1); - } - } - else { - break; - } - } - lineLeftOffset = this._getLineLeftOffset(lineIndex); - width = lineLeftOffset * this.scaleX; - line = this._textLines[lineIndex]; - // handling of RTL: in order to get things work correctly, - // we assume RTL writing is mirrored compared to LTR writing. - // so in position detection we mirror the X offset, and when is time - // of rendering it, we mirror it again. - if (this.direction === 'rtl') { - mouseOffset.x = this.width * this.scaleX - mouseOffset.x + width; - } - for (var j = 0, jlen = line.length; j < jlen; j++) { - prevWidth = width; - // i removed something about flipX here, check. - width += this.__charBounds[lineIndex][j].kernedWidth * this.scaleX; - if (width <= mouseOffset.x) { - charIndex++; - } - else { - break; - } - } - return this._getNewSelectionStartFromOffset(mouseOffset, prevWidth, width, charIndex, jlen); - }, - - /** - * @private - */ - _getNewSelectionStartFromOffset: function(mouseOffset, prevWidth, width, index, jlen) { - // we need Math.abs because when width is after the last char, the offset is given as 1, while is 0 - var distanceBtwLastCharAndCursor = mouseOffset.x - prevWidth, - distanceBtwNextCharAndCursor = width - mouseOffset.x, - offset = distanceBtwNextCharAndCursor > distanceBtwLastCharAndCursor || - distanceBtwNextCharAndCursor < 0 ? 0 : 1, - newSelectionStart = index + offset; - // if object is horizontally flipped, mirror cursor location from the end - if (this.flipX) { - newSelectionStart = jlen - newSelectionStart; - } - - if (newSelectionStart > this._text.length) { - newSelectionStart = this._text.length; - } - - return newSelectionStart; - } -}); - - -fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ { - - /** - * Initializes hidden textarea (needed to bring up keyboard in iOS) - */ - initHiddenTextarea: function() { - this.hiddenTextarea = fabric.document.createElement('textarea'); - this.hiddenTextarea.setAttribute('autocapitalize', 'off'); - this.hiddenTextarea.setAttribute('autocorrect', 'off'); - this.hiddenTextarea.setAttribute('autocomplete', 'off'); - this.hiddenTextarea.setAttribute('spellcheck', 'false'); - this.hiddenTextarea.setAttribute('data-fabric-hiddentextarea', ''); - this.hiddenTextarea.setAttribute('wrap', 'off'); - var style = this._calcTextareaPosition(); - // line-height: 1px; was removed from the style to fix this: - // https://bugs.chromium.org/p/chromium/issues/detail?id=870966 - this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top + - '; left: ' + style.left + '; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px;' + - ' paddingーtop: ' + style.fontSize + ';'; - - if (this.hiddenTextareaContainer) { - this.hiddenTextareaContainer.appendChild(this.hiddenTextarea); - } - else { - fabric.document.body.appendChild(this.hiddenTextarea); - } - - fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'keyup', this.onKeyUp.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'input', this.onInput.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'copy', this.copy.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'cut', this.copy.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'paste', this.paste.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'compositionstart', this.onCompositionStart.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'compositionupdate', this.onCompositionUpdate.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'compositionend', this.onCompositionEnd.bind(this)); - - if (!this._clickHandlerInitialized && this.canvas) { - fabric.util.addListener(this.canvas.upperCanvasEl, 'click', this.onClick.bind(this)); - this._clickHandlerInitialized = true; - } - }, - - /** - * For functionalities on keyDown - * Map a special key to a function of the instance/prototype - * If you need different behaviour for ESC or TAB or arrows, you have to change - * this map setting the name of a function that you build on the fabric.Itext or - * your prototype. - * the map change will affect all Instances unless you need for only some text Instances - * in that case you have to clone this object and assign your Instance. - * this.keysMap = fabric.util.object.clone(this.keysMap); - * The function must be in fabric.Itext.prototype.myFunction And will receive event as args[0] - */ - keysMap: { - 9: 'exitEditing', - 27: 'exitEditing', - 33: 'moveCursorUp', - 34: 'moveCursorDown', - 35: 'moveCursorRight', - 36: 'moveCursorLeft', - 37: 'moveCursorLeft', - 38: 'moveCursorUp', - 39: 'moveCursorRight', - 40: 'moveCursorDown', - }, - - keysMapRtl: { - 9: 'exitEditing', - 27: 'exitEditing', - 33: 'moveCursorUp', - 34: 'moveCursorDown', - 35: 'moveCursorLeft', - 36: 'moveCursorRight', - 37: 'moveCursorRight', - 38: 'moveCursorUp', - 39: 'moveCursorLeft', - 40: 'moveCursorDown', - }, - - /** - * For functionalities on keyUp + ctrl || cmd - */ - ctrlKeysMapUp: { - 67: 'copy', - 88: 'cut' - }, - - /** - * For functionalities on keyDown + ctrl || cmd - */ - ctrlKeysMapDown: { - 65: 'selectAll' - }, - - onClick: function() { - // No need to trigger click event here, focus is enough to have the keyboard appear on Android - this.hiddenTextarea && this.hiddenTextarea.focus(); - }, - - /** - * Handles keydown event - * only used for arrows and combination of modifier keys. - * @param {Event} e Event object - */ - onKeyDown: function(e) { - if (!this.isEditing) { - return; - } - var keyMap = this.direction === 'rtl' ? this.keysMapRtl : this.keysMap; - if (e.keyCode in keyMap) { - this[keyMap[e.keyCode]](e); - } - else if ((e.keyCode in this.ctrlKeysMapDown) && (e.ctrlKey || e.metaKey)) { - this[this.ctrlKeysMapDown[e.keyCode]](e); - } - else { - return; - } - e.stopImmediatePropagation(); - e.preventDefault(); - if (e.keyCode >= 33 && e.keyCode <= 40) { - // if i press an arrow key just update selection - this.inCompositionMode = false; - this.clearContextTop(); - this.renderCursorOrSelection(); - } - else { - this.canvas && this.canvas.requestRenderAll(); - } - }, - - /** - * Handles keyup event - * We handle KeyUp because ie11 and edge have difficulties copy/pasting - * if a copy/cut event fired, keyup is dismissed - * @param {Event} e Event object - */ - onKeyUp: function(e) { - if (!this.isEditing || this._copyDone || this.inCompositionMode) { - this._copyDone = false; - return; - } - if ((e.keyCode in this.ctrlKeysMapUp) && (e.ctrlKey || e.metaKey)) { - this[this.ctrlKeysMapUp[e.keyCode]](e); - } - else { - return; - } - e.stopImmediatePropagation(); - e.preventDefault(); - this.canvas && this.canvas.requestRenderAll(); - }, - - /** - * Handles onInput event - * @param {Event} e Event object - */ - onInput: function(e) { - var fromPaste = this.fromPaste; - this.fromPaste = false; - e && e.stopPropagation(); - if (!this.isEditing) { - return; - } - // decisions about style changes. - var nextText = this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText, - charCount = this._text.length, - nextCharCount = nextText.length, - removedText, insertedText, - charDiff = nextCharCount - charCount, - selectionStart = this.selectionStart, selectionEnd = this.selectionEnd, - selection = selectionStart !== selectionEnd, - copiedStyle, removeFrom, removeTo; - if (this.hiddenTextarea.value === '') { - this.styles = { }; - this.updateFromTextArea(); - this.fire('changed'); - if (this.canvas) { - this.canvas.fire('text:changed', { target: this }); - this.canvas.requestRenderAll(); - } - return; - } - - var textareaSelection = this.fromStringToGraphemeSelection( - this.hiddenTextarea.selectionStart, - this.hiddenTextarea.selectionEnd, - this.hiddenTextarea.value - ); - var backDelete = selectionStart > textareaSelection.selectionStart; - - if (selection) { - removedText = this._text.slice(selectionStart, selectionEnd); - charDiff += selectionEnd - selectionStart; - } - else if (nextCharCount < charCount) { - if (backDelete) { - removedText = this._text.slice(selectionEnd + charDiff, selectionEnd); - } - else { - removedText = this._text.slice(selectionStart, selectionStart - charDiff); - } - } - insertedText = nextText.slice(textareaSelection.selectionEnd - charDiff, textareaSelection.selectionEnd); - if (removedText && removedText.length) { - if (insertedText.length) { - // let's copy some style before deleting. - // we want to copy the style before the cursor OR the style at the cursor if selection - // is bigger than 0. - copiedStyle = this.getSelectionStyles(selectionStart, selectionStart + 1, false); - // now duplicate the style one for each inserted text. - copiedStyle = insertedText.map(function() { - // this return an array of references, but that is fine since we are - // copying the style later. - return copiedStyle[0]; - }); - } - if (selection) { - removeFrom = selectionStart; - removeTo = selectionEnd; - } - else if (backDelete) { - // detect differences between forwardDelete and backDelete - removeFrom = selectionEnd - removedText.length; - removeTo = selectionEnd; - } - else { - removeFrom = selectionEnd; - removeTo = selectionEnd + removedText.length; - } - this.removeStyleFromTo(removeFrom, removeTo); - } - if (insertedText.length) { - if (fromPaste && insertedText.join('') === fabric.copiedText && !fabric.disableStyleCopyPaste) { - copiedStyle = fabric.copiedTextStyle; - } - this.insertNewStyleBlock(insertedText, selectionStart, copiedStyle); - } - this.updateFromTextArea(); - this.fire('changed'); - if (this.canvas) { - this.canvas.fire('text:changed', { target: this }); - this.canvas.requestRenderAll(); - } - }, - /** - * Composition start - */ - onCompositionStart: function() { - this.inCompositionMode = true; - }, - - /** - * Composition end - */ - onCompositionEnd: function() { - this.inCompositionMode = false; - }, - - // /** - // * Composition update - // */ - onCompositionUpdate: function(e) { - this.compositionStart = e.target.selectionStart; - this.compositionEnd = e.target.selectionEnd; - this.updateTextareaPosition(); - }, - - /** - * Copies selected text - * @param {Event} e Event object - */ - copy: function() { - if (this.selectionStart === this.selectionEnd) { - //do not cut-copy if no selection - return; - } - - fabric.copiedText = this.getSelectedText(); - if (!fabric.disableStyleCopyPaste) { - fabric.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd, true); - } - else { - fabric.copiedTextStyle = null; - } - this._copyDone = true; - }, - - /** - * Pastes text - * @param {Event} e Event object - */ - paste: function() { - this.fromPaste = true; - }, - - /** - * @private - * @param {Event} e Event object - * @return {Object} Clipboard data object - */ - _getClipboardData: function(e) { - return (e && e.clipboardData) || fabric.window.clipboardData; - }, - - /** - * Finds the width in pixels before the cursor on the same line - * @private - * @param {Number} lineIndex - * @param {Number} charIndex - * @return {Number} widthBeforeCursor width before cursor - */ - _getWidthBeforeCursor: function(lineIndex, charIndex) { - var widthBeforeCursor = this._getLineLeftOffset(lineIndex), bound; - - if (charIndex > 0) { - bound = this.__charBounds[lineIndex][charIndex - 1]; - widthBeforeCursor += bound.left + bound.width; - } - return widthBeforeCursor; - }, - - /** - * Gets start offset of a selection - * @param {Event} e Event object - * @param {Boolean} isRight - * @return {Number} - */ - getDownCursorOffset: function(e, isRight) { - var selectionProp = this._getSelectionForOffset(e, isRight), - cursorLocation = this.get2DCursorLocation(selectionProp), - lineIndex = cursorLocation.lineIndex; - // if on last line, down cursor goes to end of line - if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) { - // move to the end of a text - return this._text.length - selectionProp; - } - var charIndex = cursorLocation.charIndex, - widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex), - indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor), - textAfterCursor = this._textLines[lineIndex].slice(charIndex); - return textAfterCursor.length + indexOnOtherLine + 1 + this.missingNewlineOffset(lineIndex); - }, - - /** - * private - * Helps finding if the offset should be counted from Start or End - * @param {Event} e Event object - * @param {Boolean} isRight - * @return {Number} - */ - _getSelectionForOffset: function(e, isRight) { - if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) { - return this.selectionEnd; - } - else { - return this.selectionStart; - } - }, - - /** - * @param {Event} e Event object - * @param {Boolean} isRight - * @return {Number} - */ - getUpCursorOffset: function(e, isRight) { - var selectionProp = this._getSelectionForOffset(e, isRight), - cursorLocation = this.get2DCursorLocation(selectionProp), - lineIndex = cursorLocation.lineIndex; - if (lineIndex === 0 || e.metaKey || e.keyCode === 33) { - // if on first line, up cursor goes to start of line - return -selectionProp; - } - var charIndex = cursorLocation.charIndex, - widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex), - indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor), - textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex), - missingNewlineOffset = this.missingNewlineOffset(lineIndex - 1); - // return a negative offset - return -this._textLines[lineIndex - 1].length - + indexOnOtherLine - textBeforeCursor.length + (1 - missingNewlineOffset); - }, - - /** - * for a given width it founds the matching character. - * @private - */ - _getIndexOnLine: function(lineIndex, width) { - - var line = this._textLines[lineIndex], - lineLeftOffset = this._getLineLeftOffset(lineIndex), - widthOfCharsOnLine = lineLeftOffset, - indexOnLine = 0, charWidth, foundMatch; - - for (var j = 0, jlen = line.length; j < jlen; j++) { - charWidth = this.__charBounds[lineIndex][j].width; - widthOfCharsOnLine += charWidth; - if (widthOfCharsOnLine > width) { - foundMatch = true; - var leftEdge = widthOfCharsOnLine - charWidth, - rightEdge = widthOfCharsOnLine, - offsetFromLeftEdge = Math.abs(leftEdge - width), - offsetFromRightEdge = Math.abs(rightEdge - width); - - indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : (j - 1); - break; - } - } - - // reached end - if (!foundMatch) { - indexOnLine = line.length - 1; - } - - return indexOnLine; - }, - - - /** - * Moves cursor down - * @param {Event} e Event object - */ - moveCursorDown: function(e) { - if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) { - return; - } - this._moveCursorUpOrDown('Down', e); - }, - - /** - * Moves cursor up - * @param {Event} e Event object - */ - moveCursorUp: function(e) { - if (this.selectionStart === 0 && this.selectionEnd === 0) { - return; - } - this._moveCursorUpOrDown('Up', e); - }, - - /** - * Moves cursor up or down, fires the events - * @param {String} direction 'Up' or 'Down' - * @param {Event} e Event object - */ - _moveCursorUpOrDown: function(direction, e) { - // getUpCursorOffset - // getDownCursorOffset - var action = 'get' + direction + 'CursorOffset', - offset = this[action](e, this._selectionDirection === 'right'); - if (e.shiftKey) { - this.moveCursorWithShift(offset); - } - else { - this.moveCursorWithoutShift(offset); - } - if (offset !== 0) { - this.setSelectionInBoundaries(); - this.abortCursorAnimation(); - this._currentCursorOpacity = 1; - this.initDelayedCursor(); - this._fireSelectionChanged(); - this._updateTextarea(); - } - }, - - /** - * Moves cursor with shift - * @param {Number} offset - */ - moveCursorWithShift: function(offset) { - var newSelection = this._selectionDirection === 'left' - ? this.selectionStart + offset - : this.selectionEnd + offset; - this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, newSelection); - return offset !== 0; - }, - - /** - * Moves cursor up without shift - * @param {Number} offset - */ - moveCursorWithoutShift: function(offset) { - if (offset < 0) { - this.selectionStart += offset; - this.selectionEnd = this.selectionStart; - } - else { - this.selectionEnd += offset; - this.selectionStart = this.selectionEnd; - } - return offset !== 0; - }, - - /** - * Moves cursor left - * @param {Event} e Event object - */ - moveCursorLeft: function(e) { - if (this.selectionStart === 0 && this.selectionEnd === 0) { - return; - } - this._moveCursorLeftOrRight('Left', e); - }, - - /** - * @private - * @return {Boolean} true if a change happened - */ - _move: function(e, prop, direction) { - var newValue; - if (e.altKey) { - newValue = this['findWordBoundary' + direction](this[prop]); - } - else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36 ) { - newValue = this['findLineBoundary' + direction](this[prop]); - } - else { - this[prop] += direction === 'Left' ? -1 : 1; - return true; - } - if (typeof newValue !== undefined && this[prop] !== newValue) { - this[prop] = newValue; - return true; - } - }, - - /** - * @private - */ - _moveLeft: function(e, prop) { - return this._move(e, prop, 'Left'); - }, - - /** - * @private - */ - _moveRight: function(e, prop) { - return this._move(e, prop, 'Right'); - }, - - /** - * Moves cursor left without keeping selection - * @param {Event} e - */ - moveCursorLeftWithoutShift: function(e) { - var change = true; - this._selectionDirection = 'left'; - - // only move cursor when there is no selection, - // otherwise we discard it, and leave cursor on same place - if (this.selectionEnd === this.selectionStart && this.selectionStart !== 0) { - change = this._moveLeft(e, 'selectionStart'); - - } - this.selectionEnd = this.selectionStart; - return change; - }, - - /** - * Moves cursor left while keeping selection - * @param {Event} e - */ - moveCursorLeftWithShift: function(e) { - if (this._selectionDirection === 'right' && this.selectionStart !== this.selectionEnd) { - return this._moveLeft(e, 'selectionEnd'); - } - else if (this.selectionStart !== 0){ - this._selectionDirection = 'left'; - return this._moveLeft(e, 'selectionStart'); - } - }, - - /** - * Moves cursor right - * @param {Event} e Event object - */ - moveCursorRight: function(e) { - if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) { - return; - } - this._moveCursorLeftOrRight('Right', e); - }, - - /** - * Moves cursor right or Left, fires event - * @param {String} direction 'Left', 'Right' - * @param {Event} e Event object - */ - _moveCursorLeftOrRight: function(direction, e) { - var actionName = 'moveCursor' + direction + 'With'; - this._currentCursorOpacity = 1; - - if (e.shiftKey) { - actionName += 'Shift'; - } - else { - actionName += 'outShift'; - } - if (this[actionName](e)) { - this.abortCursorAnimation(); - this.initDelayedCursor(); - this._fireSelectionChanged(); - this._updateTextarea(); - } - }, - - /** - * Moves cursor right while keeping selection - * @param {Event} e - */ - moveCursorRightWithShift: function(e) { - if (this._selectionDirection === 'left' && this.selectionStart !== this.selectionEnd) { - return this._moveRight(e, 'selectionStart'); - } - else if (this.selectionEnd !== this._text.length) { - this._selectionDirection = 'right'; - return this._moveRight(e, 'selectionEnd'); - } - }, - - /** - * Moves cursor right without keeping selection - * @param {Event} e Event object - */ - moveCursorRightWithoutShift: function(e) { - var changed = true; - this._selectionDirection = 'right'; - - if (this.selectionStart === this.selectionEnd) { - changed = this._moveRight(e, 'selectionStart'); - this.selectionEnd = this.selectionStart; - } - else { - this.selectionStart = this.selectionEnd; - } - return changed; - }, - - /** - * Removes characters from start/end - * start/end ar per grapheme position in _text array. - * - * @param {Number} start - * @param {Number} end default to start + 1 - */ - removeChars: function(start, end) { - if (typeof end === 'undefined') { - end = start + 1; - } - this.removeStyleFromTo(start, end); - this._text.splice(start, end - start); - this.text = this._text.join(''); - this.set('dirty', true); - if (this._shouldClearDimensionCache()) { - this.initDimensions(); - this.setCoords(); - } - this._removeExtraneousStyles(); - }, - - /** - * insert characters at start position, before start position. - * start equal 1 it means the text get inserted between actual grapheme 0 and 1 - * if style array is provided, it must be as the same length of text in graphemes - * if end is provided and is bigger than start, old text is replaced. - * start/end ar per grapheme position in _text array. - * - * @param {String} text text to insert - * @param {Array} style array of style objects - * @param {Number} start - * @param {Number} end default to start + 1 - */ - insertChars: function(text, style, start, end) { - if (typeof end === 'undefined') { - end = start; - } - if (end > start) { - this.removeStyleFromTo(start, end); - } - var graphemes = fabric.util.string.graphemeSplit(text); - this.insertNewStyleBlock(graphemes, start, style); - this._text = [].concat(this._text.slice(0, start), graphemes, this._text.slice(end)); - this.text = this._text.join(''); - this.set('dirty', true); - if (this._shouldClearDimensionCache()) { - this.initDimensions(); - this.setCoords(); - } - this._removeExtraneousStyles(); - }, - -}); - - -/* _TO_SVG_START_ */ -(function() { - var toFixed = fabric.util.toFixed, - multipleSpacesRegex = / +/g; - - fabric.util.object.extend(fabric.Text.prototype, /** @lends fabric.Text.prototype */ { - - /** - * Returns SVG representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - _toSVG: function() { - var offsets = this._getSVGLeftTopOffsets(), - textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft); - return this._wrapSVGTextAndBg(textAndBg); - }, - - /** - * Returns svg representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toSVG: function(reviver) { - return this._createBaseSVGMarkup( - this._toSVG(), - { reviver: reviver, noStyle: true, withShadow: true } - ); - }, - - /** - * @private - */ - _getSVGLeftTopOffsets: function() { - return { - textLeft: -this.width / 2, - textTop: -this.height / 2, - lineTop: this.getHeightOfLine(0) - }; - }, - - /** - * @private - */ - _wrapSVGTextAndBg: function(textAndBg) { - var noShadow = true, - textDecoration = this.getSvgTextDecoration(this); - return [ - textAndBg.textBgRects.join(''), - '\t\t', - textAndBg.textSpans.join(''), - '\n' - ]; - }, - - /** - * @private - * @param {Number} textTopOffset Text top offset - * @param {Number} textLeftOffset Text left offset - * @return {Object} - */ - _getSVGTextAndBg: function(textTopOffset, textLeftOffset) { - var textSpans = [], - textBgRects = [], - height = textTopOffset, lineOffset; - // bounding-box background - this._setSVGBg(textBgRects); - - // text and text-background - for (var i = 0, len = this._textLines.length; i < len; i++) { - lineOffset = this._getLineLeftOffset(i); - if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) { - this._setSVGTextLineBg(textBgRects, i, textLeftOffset + lineOffset, height); - } - this._setSVGTextLineText(textSpans, i, textLeftOffset + lineOffset, height); - height += this.getHeightOfLine(i); - } - - return { - textSpans: textSpans, - textBgRects: textBgRects - }; - }, - - /** - * @private - */ - _createTextCharSpan: function(_char, styleDecl, left, top) { - var shouldUseWhitespace = _char !== _char.trim() || _char.match(multipleSpacesRegex), - styleProps = this.getSvgSpanStyles(styleDecl, shouldUseWhitespace), - fillStyles = styleProps ? 'style="' + styleProps + '"' : '', - dy = styleDecl.deltaY, dySpan = '', - NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - if (dy) { - dySpan = ' dy="' + toFixed(dy, NUM_FRACTION_DIGITS) + '" '; - } - return [ - '', - fabric.util.string.escapeXml(_char), - '' - ].join(''); - }, - - _setSVGTextLineText: function(textSpans, lineIndex, textLeftOffset, textTopOffset) { - // set proper line offset - var lineHeight = this.getHeightOfLine(lineIndex), - isJustify = this.textAlign.indexOf('justify') !== -1, - actualStyle, - nextStyle, - charsToRender = '', - charBox, style, - boxWidth = 0, - line = this._textLines[lineIndex], - timeToRender; - - textTopOffset += lineHeight * (1 - this._fontSizeFraction) / this.lineHeight; - for (var i = 0, len = line.length - 1; i <= len; i++) { - timeToRender = i === len || this.charSpacing; - charsToRender += line[i]; - charBox = this.__charBounds[lineIndex][i]; - if (boxWidth === 0) { - textLeftOffset += charBox.kernedWidth - charBox.width; - boxWidth += charBox.width; - } - else { - boxWidth += charBox.kernedWidth; - } - if (isJustify && !timeToRender) { - if (this._reSpaceAndTab.test(line[i])) { - timeToRender = true; - } - } - if (!timeToRender) { - // if we have charSpacing, we render char by char - actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i); - nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1); - timeToRender = this._hasStyleChangedForSvg(actualStyle, nextStyle); - } - if (timeToRender) { - style = this._getStyleDeclaration(lineIndex, i) || { }; - textSpans.push(this._createTextCharSpan(charsToRender, style, textLeftOffset, textTopOffset)); - charsToRender = ''; - actualStyle = nextStyle; - textLeftOffset += boxWidth; - boxWidth = 0; - } - } - }, - - _pushTextBgRect: function(textBgRects, color, left, top, width, height) { - var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - textBgRects.push( - '\t\t\n'); - }, - - _setSVGTextLineBg: function(textBgRects, i, leftOffset, textTopOffset) { - var line = this._textLines[i], - heightOfLine = this.getHeightOfLine(i) / this.lineHeight, - boxWidth = 0, - boxStart = 0, - charBox, currentColor, - lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor'); - for (var j = 0, jlen = line.length; j < jlen; j++) { - charBox = this.__charBounds[i][j]; - currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor'); - if (currentColor !== lastColor) { - lastColor && this._pushTextBgRect(textBgRects, lastColor, leftOffset + boxStart, - textTopOffset, boxWidth, heightOfLine); - boxStart = charBox.left; - boxWidth = charBox.width; - lastColor = currentColor; - } - else { - boxWidth += charBox.kernedWidth; - } - } - currentColor && this._pushTextBgRect(textBgRects, currentColor, leftOffset + boxStart, - textTopOffset, boxWidth, heightOfLine); - }, - - /** - * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values - * we work around it by "moving" alpha channel into opacity attribute and setting fill's alpha to 1 - * - * @private - * @param {*} value - * @return {String} - */ - _getFillAttributes: function(value) { - var fillColor = (value && typeof value === 'string') ? new fabric.Color(value) : ''; - if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) { - return 'fill="' + value + '"'; - } - return 'opacity="' + fillColor.getAlpha() + '" fill="' + fillColor.setAlpha(1).toRgb() + '"'; - }, - - /** - * @private - */ - _getSVGLineTopOffset: function(lineIndex) { - var lineTopOffset = 0, lastHeight = 0; - for (var j = 0; j < lineIndex; j++) { - lineTopOffset += this.getHeightOfLine(j); - } - lastHeight = this.getHeightOfLine(j); - return { - lineTop: lineTopOffset, - offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult) - }; - }, - - /** - * Returns styles-string for svg-export - * @param {Boolean} skipShadow a boolean to skip shadow filter output - * @return {String} - */ - getSvgStyles: function(skipShadow) { - var svgStyle = fabric.Object.prototype.getSvgStyles.call(this, skipShadow); - return svgStyle + ' white-space: pre;'; - }, - }); -})(); -/* _TO_SVG_END_ */ - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = {}); - - /** - * Textbox class, based on IText, allows the user to resize the text rectangle - * and wraps lines automatically. Textboxes have their Y scaling locked, the - * user can only change width. Height is adjusted automatically based on the - * wrapping of lines. - * @class fabric.Textbox - * @extends fabric.IText - * @mixes fabric.Observable - * @return {fabric.Textbox} thisArg - * @see {@link fabric.Textbox#initialize} for constructor definition - */ - fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, { - - /** - * Type of an object - * @type String - * @default - */ - type: 'textbox', - - /** - * Minimum width of textbox, in pixels. - * @type Number - * @default - */ - minWidth: 20, - - /** - * Minimum calculated width of a textbox, in pixels. - * fixed to 2 so that an empty textbox cannot go to 0 - * and is still selectable without text. - * @type Number - * @default - */ - dynamicMinWidth: 2, - - /** - * Cached array of text wrapping. - * @type Array - */ - __cachedLines: null, - - /** - * Override standard Object class values - */ - lockScalingFlip: true, - - /** - * Override standard Object class values - * Textbox needs this on false - */ - noScaleCache: false, - - /** - * Properties which when set cause object to change dimensions - * @type Object - * @private - */ - _dimensionAffectingProps: fabric.Text.prototype._dimensionAffectingProps.concat('width'), - - /** - * Use this regular expression to split strings in breakable lines - * @private - */ - _wordJoiners: /[ \t\r]/, - - /** - * Use this boolean property in order to split strings that have no white space concept. - * this is a cheap way to help with chinese/japanese - * @type Boolean - * @since 2.6.0 - */ - splitByGrapheme: false, - - /** - * Unlike superclass's version of this function, Textbox does not update - * its width. - * @private - * @override - */ - initDimensions: function() { - if (this.__skipDimension) { - return; - } - this.isEditing && this.initDelayedCursor(); - this.clearContextTop(); - this._clearCache(); - // clear dynamicMinWidth as it will be different after we re-wrap line - this.dynamicMinWidth = 0; - // wrap lines - this._styleMap = this._generateStyleMap(this._splitText()); - // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap - if (this.dynamicMinWidth > this.width) { - this._set('width', this.dynamicMinWidth); - } - if (this.textAlign.indexOf('justify') !== -1) { - // once text is measured we need to make space fatter to make justified text. - this.enlargeSpaces(); - } - // clear cache and re-calculate height - this.height = this.calcTextHeight(); - this.saveState({ propertySet: '_dimensionAffectingProps' }); - }, - - /** - * Generate an object that translates the style object so that it is - * broken up by visual lines (new lines and automatic wrapping). - * The original text styles object is broken up by actual lines (new lines only), - * which is only sufficient for Text / IText - * @private - */ - _generateStyleMap: function(textInfo) { - var realLineCount = 0, - realLineCharCount = 0, - charCount = 0, - map = {}; - - for (var i = 0; i < textInfo.graphemeLines.length; i++) { - if (textInfo.graphemeText[charCount] === '\n' && i > 0) { - realLineCharCount = 0; - charCount++; - realLineCount++; - } - else if (!this.splitByGrapheme && this._reSpaceAndTab.test(textInfo.graphemeText[charCount]) && i > 0) { - // this case deals with space's that are removed from end of lines when wrapping - realLineCharCount++; - charCount++; - } - - map[i] = { line: realLineCount, offset: realLineCharCount }; - - charCount += textInfo.graphemeLines[i].length; - realLineCharCount += textInfo.graphemeLines[i].length; - } - - return map; - }, - - /** - * Returns true if object has a style property or has it on a specified line - * @param {Number} lineIndex - * @return {Boolean} - */ - styleHas: function(property, lineIndex) { - if (this._styleMap && !this.isWrapping) { - var map = this._styleMap[lineIndex]; - if (map) { - lineIndex = map.line; - } - } - return fabric.Text.prototype.styleHas.call(this, property, lineIndex); - }, - - /** - * Returns true if object has no styling or no styling in a line - * @param {Number} lineIndex , lineIndex is on wrapped lines. - * @return {Boolean} - */ - isEmptyStyles: function(lineIndex) { - if (!this.styles) { - return true; - } - var offset = 0, nextLineIndex = lineIndex + 1, nextOffset, obj, shouldLimit = false, - map = this._styleMap[lineIndex], mapNextLine = this._styleMap[lineIndex + 1]; - if (map) { - lineIndex = map.line; - offset = map.offset; - } - if (mapNextLine) { - nextLineIndex = mapNextLine.line; - shouldLimit = nextLineIndex === lineIndex; - nextOffset = mapNextLine.offset; - } - obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] }; - for (var p1 in obj) { - for (var p2 in obj[p1]) { - if (p2 >= offset && (!shouldLimit || p2 < nextOffset)) { - // eslint-disable-next-line no-unused-vars - for (var p3 in obj[p1][p2]) { - return false; - } - } - } - } - return true; - }, - - /** - * @param {Number} lineIndex - * @param {Number} charIndex - * @private - */ - _getStyleDeclaration: function(lineIndex, charIndex) { - if (this._styleMap && !this.isWrapping) { - var map = this._styleMap[lineIndex]; - if (!map) { - return null; - } - lineIndex = map.line; - charIndex = map.offset + charIndex; - } - return this.callSuper('_getStyleDeclaration', lineIndex, charIndex); - }, - - /** - * @param {Number} lineIndex - * @param {Number} charIndex - * @param {Object} style - * @private - */ - _setStyleDeclaration: function(lineIndex, charIndex, style) { - var map = this._styleMap[lineIndex]; - lineIndex = map.line; - charIndex = map.offset + charIndex; - - this.styles[lineIndex][charIndex] = style; - }, - - /** - * @param {Number} lineIndex - * @param {Number} charIndex - * @private - */ - _deleteStyleDeclaration: function(lineIndex, charIndex) { - var map = this._styleMap[lineIndex]; - lineIndex = map.line; - charIndex = map.offset + charIndex; - delete this.styles[lineIndex][charIndex]; - }, - - /** - * probably broken need a fix - * Returns the real style line that correspond to the wrapped lineIndex line - * Used just to verify if the line does exist or not. - * @param {Number} lineIndex - * @returns {Boolean} if the line exists or not - * @private - */ - _getLineStyle: function(lineIndex) { - var map = this._styleMap[lineIndex]; - return !!this.styles[map.line]; - }, - - /** - * Set the line style to an empty object so that is initialized - * @param {Number} lineIndex - * @param {Object} style - * @private - */ - _setLineStyle: function(lineIndex) { - var map = this._styleMap[lineIndex]; - this.styles[map.line] = {}; - }, - - /** - * Wraps text using the 'width' property of Textbox. First this function - * splits text on newlines, so we preserve newlines entered by the user. - * Then it wraps each line using the width of the Textbox by calling - * _wrapLine(). - * @param {Array} lines The string array of text that is split into lines - * @param {Number} desiredWidth width you want to wrap to - * @returns {Array} Array of lines - */ - _wrapText: function(lines, desiredWidth) { - var wrapped = [], i; - this.isWrapping = true; - for (i = 0; i < lines.length; i++) { - wrapped = wrapped.concat(this._wrapLine(lines[i], i, desiredWidth)); - } - this.isWrapping = false; - return wrapped; - }, - - /** - * Helper function to measure a string of text, given its lineIndex and charIndex offset - * it gets called when charBounds are not available yet. - * @param {CanvasRenderingContext2D} ctx - * @param {String} text - * @param {number} lineIndex - * @param {number} charOffset - * @returns {number} - * @private - */ - _measureWord: function(word, lineIndex, charOffset) { - var width = 0, prevGrapheme, skipLeft = true; - charOffset = charOffset || 0; - for (var i = 0, len = word.length; i < len; i++) { - var box = this._getGraphemeBox(word[i], lineIndex, i + charOffset, prevGrapheme, skipLeft); - width += box.kernedWidth; - prevGrapheme = word[i]; - } - return width; - }, - - /** - * Wraps a line of text using the width of the Textbox and a context. - * @param {Array} line The grapheme array that represent the line - * @param {Number} lineIndex - * @param {Number} desiredWidth width you want to wrap the line to - * @param {Number} reservedSpace space to remove from wrapping for custom functionalities - * @returns {Array} Array of line(s) into which the given text is wrapped - * to. - */ - _wrapLine: function(_line, lineIndex, desiredWidth, reservedSpace) { - var lineWidth = 0, - splitByGrapheme = this.splitByGrapheme, - graphemeLines = [], - line = [], - // spaces in different languages? - words = splitByGrapheme ? fabric.util.string.graphemeSplit(_line) : _line.split(this._wordJoiners), - word = '', - offset = 0, - infix = splitByGrapheme ? '' : ' ', - wordWidth = 0, - infixWidth = 0, - largestWordWidth = 0, - lineJustStarted = true, - additionalSpace = this._getWidthOfCharSpacing(), - reservedSpace = reservedSpace || 0; - // fix a difference between split and graphemeSplit - if (words.length === 0) { - words.push([]); - } - desiredWidth -= reservedSpace; - for (var i = 0; i < words.length; i++) { - // if using splitByGrapheme words are already in graphemes. - word = splitByGrapheme ? words[i] : fabric.util.string.graphemeSplit(words[i]); - wordWidth = this._measureWord(word, lineIndex, offset); - offset += word.length; - - lineWidth += infixWidth + wordWidth - additionalSpace; - if (lineWidth > desiredWidth && !lineJustStarted) { - graphemeLines.push(line); - line = []; - lineWidth = wordWidth; - lineJustStarted = true; - } - else { - lineWidth += additionalSpace; - } - - if (!lineJustStarted && !splitByGrapheme) { - line.push(infix); - } - line = line.concat(word); - - infixWidth = splitByGrapheme ? 0 : this._measureWord([infix], lineIndex, offset); - offset++; - lineJustStarted = false; - // keep track of largest word - if (wordWidth > largestWordWidth) { - largestWordWidth = wordWidth; - } - } - - i && graphemeLines.push(line); - - if (largestWordWidth + reservedSpace > this.dynamicMinWidth) { - this.dynamicMinWidth = largestWordWidth - additionalSpace + reservedSpace; - } - return graphemeLines; - }, - - /** - * Detect if the text line is ended with an hard break - * text and itext do not have wrapping, return false - * @param {Number} lineIndex text to split - * @return {Boolean} - */ - isEndOfWrapping: function(lineIndex) { - if (!this._styleMap[lineIndex + 1]) { - // is last line, return true; - return true; - } - if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) { - // this is last line before a line break, return true; - return true; - } - return false; - }, - - /** - * Detect if a line has a linebreak and so we need to account for it when moving - * and counting style. - * @return Number - */ - missingNewlineOffset: function(lineIndex) { - if (this.splitByGrapheme) { - return this.isEndOfWrapping(lineIndex) ? 1 : 0; - } - return 1; - }, - - /** - * Gets lines of text to render in the Textbox. This function calculates - * text wrapping on the fly every time it is called. - * @param {String} text text to split - * @returns {Array} Array of lines in the Textbox. - * @override - */ - _splitTextIntoLines: function(text) { - var newText = fabric.Text.prototype._splitTextIntoLines.call(this, text), - graphemeLines = this._wrapText(newText.lines, this.width), - lines = new Array(graphemeLines.length); - for (var i = 0; i < graphemeLines.length; i++) { - lines[i] = graphemeLines[i].join(''); - } - newText.lines = lines; - newText.graphemeLines = graphemeLines; - return newText; - }, - - getMinWidth: function() { - return Math.max(this.minWidth, this.dynamicMinWidth); - }, - - _removeExtraneousStyles: function() { - var linesToKeep = {}; - for (var prop in this._styleMap) { - if (this._textLines[prop]) { - linesToKeep[this._styleMap[prop].line] = 1; - } - } - for (var prop in this.styles) { - if (!linesToKeep[prop]) { - delete this.styles[prop]; - } - } - }, - - /** - * Returns object representation of an instance - * @method toObject - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return this.callSuper('toObject', ['minWidth', 'splitByGrapheme'].concat(propertiesToInclude)); - } - }); - - /** - * Returns fabric.Textbox instance from an object representation - * @static - * @memberOf fabric.Textbox - * @param {Object} object Object to create an instance from - * @param {Function} [callback] Callback to invoke when an fabric.Textbox instance is created - */ - fabric.Textbox.fromObject = function(object, callback) { - return fabric.Object._fromObject('Textbox', object, callback, 'text'); - }; -})(typeof exports !== 'undefined' ? exports : this); - - -(function() { - - var controlsUtils = fabric.controlsUtils, - scaleSkewStyleHandler = controlsUtils.scaleSkewCursorStyleHandler, - scaleStyleHandler = controlsUtils.scaleCursorStyleHandler, - scalingEqually = controlsUtils.scalingEqually, - scalingYOrSkewingX = controlsUtils.scalingYOrSkewingX, - scalingXOrSkewingY = controlsUtils.scalingXOrSkewingY, - scaleOrSkewActionName = controlsUtils.scaleOrSkewActionName, - objectControls = fabric.Object.prototype.controls; - - objectControls.ml = new fabric.Control({ - x: -0.5, - y: 0, - cursorStyleHandler: scaleSkewStyleHandler, - actionHandler: scalingXOrSkewingY, - getActionName: scaleOrSkewActionName, - }); - - objectControls.mr = new fabric.Control({ - x: 0.5, - y: 0, - cursorStyleHandler: scaleSkewStyleHandler, - actionHandler: scalingXOrSkewingY, - getActionName: scaleOrSkewActionName, - }); - - objectControls.mb = new fabric.Control({ - x: 0, - y: 0.5, - cursorStyleHandler: scaleSkewStyleHandler, - actionHandler: scalingYOrSkewingX, - getActionName: scaleOrSkewActionName, - }); - - objectControls.mt = new fabric.Control({ - x: 0, - y: -0.5, - cursorStyleHandler: scaleSkewStyleHandler, - actionHandler: scalingYOrSkewingX, - getActionName: scaleOrSkewActionName, - }); - - objectControls.tl = new fabric.Control({ - x: -0.5, - y: -0.5, - cursorStyleHandler: scaleStyleHandler, - actionHandler: scalingEqually - }); - - objectControls.tr = new fabric.Control({ - x: 0.5, - y: -0.5, - cursorStyleHandler: scaleStyleHandler, - actionHandler: scalingEqually - }); - - objectControls.bl = new fabric.Control({ - x: -0.5, - y: 0.5, - cursorStyleHandler: scaleStyleHandler, - actionHandler: scalingEqually - }); - - objectControls.br = new fabric.Control({ - x: 0.5, - y: 0.5, - cursorStyleHandler: scaleStyleHandler, - actionHandler: scalingEqually - }); - - objectControls.mtr = new fabric.Control({ - x: 0, - y: -0.5, - actionHandler: controlsUtils.rotationWithSnapping, - cursorStyleHandler: controlsUtils.rotationStyleHandler, - offsetY: -40, - withConnection: true, - actionName: 'rotate', - }); - - if (fabric.Textbox) { - // this is breaking the prototype inheritance, no time / ideas to fix it. - // is important to document that if you want to have all objects to have a - // specific custom control, you have to add it to Object prototype and to Textbox - // prototype. The controls are shared as references. So changes to control `tr` - // can still apply to all objects if needed. - var textBoxControls = fabric.Textbox.prototype.controls = { }; - - textBoxControls.mtr = objectControls.mtr; - textBoxControls.tr = objectControls.tr; - textBoxControls.br = objectControls.br; - textBoxControls.tl = objectControls.tl; - textBoxControls.bl = objectControls.bl; - textBoxControls.mt = objectControls.mt; - textBoxControls.mb = objectControls.mb; - - textBoxControls.mr = new fabric.Control({ - x: 0.5, - y: 0, - actionHandler: controlsUtils.changeWidth, - cursorStyleHandler: scaleSkewStyleHandler, - actionName: 'resizing', - }); - - textBoxControls.ml = new fabric.Control({ - x: -0.5, - y: 0, - actionHandler: controlsUtils.changeWidth, - cursorStyleHandler: scaleSkewStyleHandler, - actionName: 'resizing', - }); - } -})(); - diff --git a/web/static/js9_old/js/fabric-v4.6.0.min.js b/web/static/js9_old/js/fabric-v4.6.0.min.js deleted file mode 100644 index 34c1ff02fd99e0d9046f04e338f9a4ea2882fefa..0000000000000000000000000000000000000000 --- a/web/static/js9_old/js/fabric-v4.6.0.min.js +++ /dev/null @@ -1 +0,0 @@ -var jsdom,virtualWindow,fabric=fabric||{version:"4.6.0"};function resizeCanvasIfNeeded(t){var e=t.targetCanvas,i=e.width,r=e.height,n=t.destinationWidth,t=t.destinationHeight;i===n&&r===t||(e.width=n,e.height=t)}function copyGLTo2DDrawImage(t,e){var i=t.canvas,r=e.targetCanvas,t=r.getContext("2d");t.translate(0,r.height),t.scale(1,-1);e=i.height-r.height;t.drawImage(i,0,e,r.width,r.height,0,0,r.width,r.height)}function copyGLTo2DPutImageData(t,e){var i=e.targetCanvas.getContext("2d"),r=e.destinationWidth,n=e.destinationHeight,s=r*n*4,e=new Uint8Array(this.imageBuffer,0,s),s=new Uint8ClampedArray(this.imageBuffer,0,s);t.readPixels(0,0,r,n,t.RGBA,t.UNSIGNED_BYTE,e);n=new ImageData(s,r,n);i.putImageData(n,0,0)}"undefined"!=typeof exports?exports.fabric=fabric:"function"==typeof define&&define.amd&&define([],function(){return fabric}),"undefined"!=typeof document&&"undefined"!=typeof window?(document instanceof("undefined"!=typeof HTMLDocument?HTMLDocument:Document)?fabric.document=document:fabric.document=document.implementation.createHTMLDocument(""),fabric.window=window):(jsdom=require("jsdom"),virtualWindow=new jsdom.JSDOM(decodeURIComponent("%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E"),{features:{FetchExternalResources:["img"]},resources:"usable"}).window,fabric.document=virtualWindow.document,fabric.jsdomImplForWrapper=require("jsdom/lib/jsdom/living/generated/utils").implForWrapper,fabric.nodeCanvas=require("jsdom/lib/jsdom/utils").Canvas,fabric.window=virtualWindow,DOMParser=fabric.window.DOMParser),fabric.isTouchSupported="ontouchstart"in fabric.window||"ontouchstart"in fabric.document||fabric.window&&fabric.window.navigator&&0_)for(var C=1,S=v.length;Ct[i-2].x?1:s.x===t[i-2].x?0:-1,h=s.y>t[i-2].y?1:s.y===t[i-2].y?0:-1),n.push(["L",s.x+c*e,s.y+h*e]),n},fabric.util.getPathSegmentsInfo=l,fabric.util.getBoundsOfCurve=v,fabric.util.getPointOnPath=function(t,e,i){i=i||l(t);for(var r=0;0/g,">")},graphemeSplit:function(t){for(var e,i=0,r=[],i=0;it.x&&this.y>t.y},gte:function(t){return this.x>=t.x&&this.y>=t.y},lerp:function(t,e){return void 0===e&&(e=.5),e=Math.max(Math.min(1,e),0),new i(this.x+(t.x-this.x)*e,this.y+(t.y-this.y)*e)},distanceFrom:function(t){var e=this.x-t.x,t=this.y-t.y;return Math.sqrt(e*e+t*t)},midPointFrom:function(t){return this.lerp(t)},min:function(t){return new i(Math.min(this.x,t.x),Math.min(this.y,t.y))},max:function(t){return new i(Math.max(this.x,t.x),Math.max(this.y,t.y))},toString:function(){return this.x+","+this.y},setXY:function(t,e){return this.x=t,this.y=e,this},setX:function(t){return this.x=t,this},setY:function(t){return this.y=t,this},setFromPoint:function(t){return this.x=t.x,this.y=t.y,this},swap:function(t){var e=this.x,i=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=i},clone:function(){return new i(this.x,this.y)}}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var a=t.fabric||(t.fabric={});function c(t){this.status=t,this.points=[]}a.Intersection?a.warn("fabric.Intersection is already defined"):(a.Intersection=c,a.Intersection.prototype={constructor:c,appendPoint:function(t){return this.points.push(t),this},appendPoints:function(t){return this.points=this.points.concat(t),this}},a.Intersection.intersectLineLine=function(t,e,i,r){var n,s=(r.x-i.x)*(t.y-i.y)-(r.y-i.y)*(t.x-i.x),o=(e.x-t.x)*(t.y-i.y)-(e.y-t.y)*(t.x-i.x),r=(r.y-i.y)*(e.x-t.x)-(r.x-i.x)*(e.y-t.y);return 0!=r?(i=o/r,0<=(r=s/r)&&r<=1&&0<=i&&i<=1?(n=new c("Intersection")).appendPoint(new a.Point(t.x+r*(e.x-t.x),t.y+r*(e.y-t.y))):n=new c):n=new c(0==s||0==o?"Coincident":"Parallel"),n},a.Intersection.intersectLinePolygon=function(t,e,i){for(var r,n,s=new c,o=i.length,a=0;a=t&&(i.x-=t),i.x<=-t&&(i.x+=t),i.y>=t&&(i.y-=t),i.y<=t&&(i.y+=t),i.x-=o.offsetX,i.y-=o.offsetY,i}function w(t){return t.flipX!==t.flipY}function O(t,e,i,r,n){0!==t[e]&&(r=n/t._getTransformedDimensions()[r]*t[i],t.set(i,r))}function k(t,e,i,r){var n,s=e.target,o=s._getTransformedDimensions(0,s.skewY),i=T(e,e.originX,e.originY,i,r),r=Math.abs(2*i.x)-o.x,i=s.skewX;r<2?n=0:(n=g(Math.atan2(r/s.scaleX,o.y/s.scaleY)),e.originX===c&&e.originY===u&&(n=-n),e.originX===l&&e.originY===h&&(n=-n),w(s)&&(n=-n));e=i!==n;return e&&(i=s._getTransformedDimensions().y,s.set("skewX",n),O(s,"skewY","scaleY","y",i)),e}function P(t,e,i,r){var n,s=e.target,o=s._getTransformedDimensions(s.skewX,0),i=T(e,e.originX,e.originY,i,r),r=Math.abs(2*i.y)-o.y,i=s.skewY;r<2?n=0:(n=g(Math.atan2(r/s.scaleY,o.x/s.scaleX)),e.originX===c&&e.originY===u&&(n=-n),e.originX===l&&e.originY===h&&(n=-n),w(s)&&(n=-n));e=i!==n;return e&&(i=s._getTransformedDimensions().x,s.set("skewY",n),O(s,"skewX","scaleX","x",i)),e}function E(t,e,i,r,n){var s=e.target,o=s.lockScalingX,a=s.lockScalingY,c=(n=n||{}).by,h=b(t,s),n=_(s,c,h),t=e.gestureScale;if(n)return!1;if(t)l=e.scaleX*t,u=e.scaleY*t;else{if(n=T(e,e.originX,e.originY,i,r),t="y"!==c?p(n.x):1,f="x"!==c?p(n.y):1,e.signX||(e.signX=t),e.signY||(e.signY=f),s.lockScalingFlip&&(e.signX!==t||e.signY!==f))return!1;var l,u,i=s._getTransformedDimensions();u=h&&!c?(r=Math.abs(n.x)+Math.abs(n.y),h=e.original,r=r/(Math.abs(i.x*h.scaleX/s.scaleX)+Math.abs(i.y*h.scaleY/s.scaleY)),l=h.scaleX*r,h.scaleY*r):(l=Math.abs(n.x*s.scaleX/i.x),Math.abs(n.y*s.scaleY/i.y)),y(e)&&(l*=2,u*=2),e.signX!==t&&"y"!==c&&(e.originX=d[e.originX],l*=-1,e.signX=t),e.signY!==f&&"x"!==c&&(e.originY=d[e.originY],u*=-1,e.signY=f)}var e=s.scaleX,f=s.scaleY;return c?("x"===c&&s.set("scaleX",l),"y"===c&&s.set("scaleY",u)):(o||s.set("scaleX",l),a||s.set("scaleY",u)),e!==s.scaleX||f!==s.scaleY}o.scaleCursorStyleHandler=function(t,e,i){var r=b(t,i),t="";return 0!==e.x&&0===e.y?t="x":0===e.x&&0!==e.y&&(t="y"),_(i,t,r)?"not-allowed":(e=m(i,e),n[e]+"-resize")},o.skewCursorStyleHandler=function(t,e,i){var r="not-allowed";return 0!==e.x&&i.lockSkewingY||0!==e.y&&i.lockSkewingX?r:(e=m(i,e)%4,s[e]+"-resize")},o.scaleSkewCursorStyleHandler=function(t,e,i){return t[i.canvas.altActionKey]?o.skewCursorStyleHandler(t,e,i):o.scaleCursorStyleHandler(t,e,i)},o.rotationWithSnapping=S("rotating",C(function(t,e,i,r){var n=e,s=n.target,o=s.translateToOriginPoint(s.getCenterPoint(),n.originX,n.originY);return!s.lockRotation&&(e=Math.atan2(n.ey-o.y,n.ex-o.x),r=Math.atan2(r-o.y,i-o.x),i=g(r-e+n.theta),0r.r2,o=(this.gradientTransform||fabric.iMatrix).concat(),a=-this.offsetX,c=-this.offsetY,h=!!e.additionalTransform,l="pixels"===this.gradientUnits?"userSpaceOnUse":"objectBoundingBox";if(n.sort(function(t,e){return t.offset-e.offset}),"objectBoundingBox"==l?(a/=t.width,c/=t.height):(a+=t.width/2,c+=t.height/2),"path"===t.type&&"percentage"!==this.gradientUnits&&(a-=t.pathOffset.x,c-=t.pathOffset.y),o[4]-=a,o[5]-=c,l='id="SVGID_'+this.id+'" gradientUnits="'+l+'"',l+=' gradientTransform="'+(h?e.additionalTransform+" ":"")+fabric.util.matrixToSVG(o)+'" ',"linear"===this.type?i=["\n']:"radial"===this.type&&(i=["\n']),"radial"===this.type){if(s)for((n=n.concat()).reverse(),f=0,d=n.length;f\n')}return i.push("linear"===this.type?"\n":"\n"),i.join("")},toLive:function(t){var e,i,r,n=fabric.util.object.clone(this.coords);if(this.type){for("linear"===this.type?e=t.createLinearGradient(n.x1,n.y1,n.x2,n.y2):"radial"===this.type&&(e=t.createRadialGradient(n.x1,n.y1,n.r1,n.x2,n.y2,n.r2)),i=0,r=this.colorStops.length;i\n\n\n'},setOptions:function(t){for(var e in t)this[e]=t[e]},toLive:function(t){var e=this.source;if(!e)return"";if(void 0!==e.src){if(!e.complete)return"";if(0===e.naturalWidth||0===e.naturalHeight)return""}return t.createPattern(e,this.repeat)}})}(),function(t){"use strict";var o=t.fabric||(t.fabric={}),a=o.util.toFixed;o.Shadow?o.warn("fabric.Shadow is already defined."):(o.Shadow=o.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,nonScaling:!1,initialize:function(t){for(var e in t="string"==typeof t?this._parseShadow(t):t)this[e]=t[e];this.id=o.Object.__uid++},_parseShadow:function(t){var e=t.trim(),t=o.Shadow.reOffsetsAndBlur.exec(e)||[];return{color:(e.replace(o.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)").trim(),offsetX:parseFloat(t[1],10)||0,offsetY:parseFloat(t[2],10)||0,blur:parseFloat(t[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(t){var e=40,i=40,r=o.Object.NUM_FRACTION_DIGITS,n=o.util.rotateVector({x:this.offsetX,y:this.offsetY},o.util.degreesToRadians(-t.angle)),s=new o.Color(this.color);return t.width&&t.height&&(e=100*a((Math.abs(n.x)+this.blur)/t.width,r)+20,i=100*a((Math.abs(n.y)+this.blur)/t.height,r)+20),t.flipX&&(n.x*=-1),t.flipY&&(n.y*=-1),'\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n'},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke,nonScaling:this.nonScaling};var e={},i=o.Shadow.prototype;return["color","blur","offsetX","offsetY","affectStroke","nonScaling"].forEach(function(t){this[t]!==i[t]&&(e[t]=this[t])},this),e}}),o.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?(-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?(\d+(?:\.\d*)?(?:px)?)?(?:\s?|$)(?:$|\s)/)}("undefined"!=typeof exports?exports:this),function(){"use strict";var n,t,h,a,s,o,i,r,e;fabric.StaticCanvas?fabric.warn("fabric.StaticCanvas is already defined."):(n=fabric.util.object.extend,t=fabric.util.getElementOffset,h=fabric.util.removeFromArray,a=fabric.util.toFixed,s=fabric.util.transformPoint,o=fabric.util.invertTransform,i=fabric.util.getNodeCanvas,r=fabric.util.createCanvasElement,e=new Error("Could not initialize `canvas` element"),fabric.StaticCanvas=fabric.util.createClass(fabric.CommonMethods,{initialize:function(t,e){e=e||{},this.renderAndResetBound=this.renderAndReset.bind(this),this.requestRenderAllBound=this.requestRenderAll.bind(this),this._initStatic(t,e)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!1,renderOnAddRemove:!0,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,viewportTransform:fabric.iMatrix.concat(),backgroundVpt:!0,overlayVpt:!0,enableRetinaScaling:!0,vptCoords:{},skipOffscreen:!0,clipPath:void 0,_initStatic:function(t,e){var i=this.requestRenderAllBound;this._objects=[],this._createLowerCanvas(t),this._initOptions(e),this.interactive||this._initRetinaScaling(),e.overlayImage&&this.setOverlayImage(e.overlayImage,i),e.backgroundImage&&this.setBackgroundImage(e.backgroundImage,i),e.backgroundColor&&this.setBackgroundColor(e.backgroundColor,i),e.overlayColor&&this.setOverlayColor(e.overlayColor,i),this.calcOffset()},_isRetinaScaling:function(){return 1!==fabric.devicePixelRatio&&this.enableRetinaScaling},getRetinaScaling:function(){return this._isRetinaScaling()?fabric.devicePixelRatio:1},_initRetinaScaling:function(){var t;this._isRetinaScaling()&&(t=fabric.devicePixelRatio,this.__initRetinaScaling(t,this.lowerCanvasEl,this.contextContainer),this.upperCanvasEl&&this.__initRetinaScaling(t,this.upperCanvasEl,this.contextTop))},__initRetinaScaling:function(t,e,i){e.setAttribute("width",this.width*t),e.setAttribute("height",this.height*t),i.scale(t,t)},calcOffset:function(){return this._offset=t(this.lowerCanvasEl),this},setOverlayImage:function(t,e,i){return this.__setBgOverlayImage("overlayImage",t,e,i)},setBackgroundImage:function(t,e,i){return this.__setBgOverlayImage("backgroundImage",t,e,i)},setOverlayColor:function(t,e){return this.__setBgOverlayColor("overlayColor",t,e)},setBackgroundColor:function(t,e){return this.__setBgOverlayColor("backgroundColor",t,e)},__setBgOverlayImage:function(r,t,n,s){return"string"==typeof t?fabric.util.loadImage(t,function(t,e){var i;t&&(i=new fabric.Image(t,s),(this[r]=i).canvas=this),n&&n(t,e)},this,s&&s.crossOrigin):(s&&t.setOptions(s),(this[r]=t)&&(t.canvas=this),n&&n(t,!1)),this},__setBgOverlayColor:function(t,e,i){return this[t]=e,this._initGradient(e,t),this._initPattern(e,t,i),this},_createCanvasElement:function(){var t=r();if(!t)throw e;if(t.style||(t.style={}),void 0===t.getContext)throw e;return t},_initOptions:function(t){var e=this.lowerCanvasEl;this._setOptions(t),this.width=this.width||parseInt(e.width,10)||0,this.height=this.height||parseInt(e.height,10)||0,this.lowerCanvasEl.style&&(e.width=this.width,e.height=this.height,e.style.width=this.width+"px",e.style.height=this.height+"px",this.viewportTransform=this.viewportTransform.slice())},_createLowerCanvas:function(t){t&&t.getContext?this.lowerCanvasEl=t:this.lowerCanvasEl=fabric.util.getById(t)||this._createCanvasElement(),fabric.util.addClass(this.lowerCanvasEl,"lower-canvas"),this._originalCanvasStyle=this.lowerCanvasEl.style,this.interactive&&this._applyCanvasStyle(this.lowerCanvasEl),this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(t,e){return this.setDimensions({width:t},e)},setHeight:function(t,e){return this.setDimensions({height:t},e)},setDimensions:function(t,e){var i,r;for(r in e=e||{},t)i=t[r],e.cssOnly||(this._setBackstoreDimension(r,t[r]),i+="px",this.hasLostContext=!0),e.backstoreOnly||this._setCssDimension(r,i);return this._isCurrentlyDrawing&&this.freeDrawingBrush&&this.freeDrawingBrush._setBrushStyles(),this._initRetinaScaling(),this.calcOffset(),e.cssOnly||this.requestRenderAll(),this},_setBackstoreDimension:function(t,e){return this.lowerCanvasEl[t]=e,this.upperCanvasEl&&(this.upperCanvasEl[t]=e),this.cacheCanvasEl&&(this.cacheCanvasEl[t]=e),this[t]=e,this},_setCssDimension:function(t,e){return this.lowerCanvasEl.style[t]=e,this.upperCanvasEl&&(this.upperCanvasEl.style[t]=e),this.wrapperEl&&(this.wrapperEl.style[t]=e),this},getZoom:function(){return this.viewportTransform[0]},setViewportTransform:function(t){var e,i,r,n=this._activeObject,s=this.backgroundImage,o=this.overlayImage;for(this.viewportTransform=t,i=0,r=this._objects.length;i\n'),this._setSVGBgOverlayColor(i,"background"),this._setSVGBgOverlayImage(i,"backgroundImage",e),this._setSVGObjects(i,e),this.clipPath&&i.push("
    \n"),this._setSVGBgOverlayColor(i,"overlay"),this._setSVGBgOverlayImage(i,"overlayImage",e),i.push(""),i.join("")},_setSVGPreamble:function(t,e){e.suppressPreamble||t.push('\n','\n')},_setSVGHeader:function(t,e){var i,r=e.width||this.width,n=e.height||this.height,s='viewBox="0 0 '+this.width+" "+this.height+'" ',o=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?s='viewBox="'+e.viewBox.x+" "+e.viewBox.y+" "+e.viewBox.width+" "+e.viewBox.height+'" ':this.svgViewportTransformation&&(i=this.viewportTransform,s='viewBox="'+a(-i[4]/i[0],o)+" "+a(-i[5]/i[3],o)+" "+a(this.width/i[0],o)+" "+a(this.height/i[3],o)+'" '),t.push("\n',"Created with Fabric.js ",fabric.version,"\n","\n",this.createSVGFontFacesMarkup(),this.createSVGRefElementsMarkup(),this.createSVGClipPathMarkup(e),"\n")},createSVGClipPathMarkup:function(t){var e=this.clipPath;return e?(e.clipPathId="CLIPPATH_"+fabric.Object.__uid++,'\n'+this.clipPath.toClipPathSVG(t.reviver)+"\n"):""},createSVGRefElementsMarkup:function(){var n=this;return["background","overlay"].map(function(t){var e=n[t+"Color"];if(e&&e.toLive){var i=n[t+"Vpt"],r=n.viewportTransform,t={width:n.width/(i?r[0]:1),height:n.height/(i?r[3]:1)};return e.toSVG(t,{additionalTransform:i?fabric.util.matrixToSVG(r):""})}}).join("")},createSVGFontFacesMarkup:function(){var t,e,i,r,n,s,o,a,c,h="",l={},u=fabric.fontPaths,f=[];for(this._objects.forEach(function t(e){f.push(e),e._objects&&e._objects.forEach(t)}),o=0,a=f.length;o',"\n",h,"","\n"].join("")},_setSVGObjects:function(t,e){for(var i,r=this._objects,n=0,s=r.length;n
    \n")):t.push('\n"))},sendToBack:function(t){if(!t)return this;var e,i,r,n=this._activeObject;if(t===n&&"activeSelection"===t.type)for(e=(r=n._objects).length;e--;)i=r[e],h(this._objects,i),this._objects.unshift(i);else h(this._objects,t),this._objects.unshift(t);return this.renderOnAddRemove&&this.requestRenderAll(),this},bringToFront:function(t){if(!t)return this;var e,i,r,n=this._activeObject;if(t===n&&"activeSelection"===t.type)for(r=n._objects,e=0;e"}}),n(fabric.StaticCanvas.prototype,fabric.Observable),n(fabric.StaticCanvas.prototype,fabric.Collection),n(fabric.StaticCanvas.prototype,fabric.DataURLExporter),n(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(t){var e=r();if(!e||!e.getContext)return null;e=e.getContext("2d");return!e||"setLineDash"!==t?null:void 0!==e.setLineDash}}),fabric.StaticCanvas.prototype.toJSON=fabric.StaticCanvas.prototype.toObject,fabric.isLikelyNode&&(fabric.StaticCanvas.prototype.createPNGStream=function(){var t=i(this.lowerCanvasEl);return t&&t.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(t){var e=i(this.lowerCanvasEl);return e&&e.createJPEGStream(t)}))}(),fabric.BaseBrush=fabric.util.createClass({color:"rgb(0, 0, 0)",width:1,shadow:null,strokeLineCap:"round",strokeLineJoin:"round",strokeMiterLimit:10,strokeDashArray:null,limitedToCanvasSize:!1,_setBrushStyles:function(){var t=this.canvas.contextTop;t.strokeStyle=this.color,t.lineWidth=this.width,t.lineCap=this.strokeLineCap,t.miterLimit=this.strokeMiterLimit,t.lineJoin=this.strokeLineJoin,t.setLineDash(this.strokeDashArray||[])},_saveAndTransform:function(t){var e=this.canvas.viewportTransform;t.save(),t.transform(e[0],e[1],e[2],e[3],e[4],e[5])},_setShadow:function(){var t,e,i,r;this.shadow&&(t=this.canvas,e=this.shadow,i=t.contextTop,r=t.getZoom(),t&&t._isRetinaScaling()&&(r*=fabric.devicePixelRatio),i.shadowColor=e.color,i.shadowBlur=e.blur*r,i.shadowOffsetX=e.offsetX*r,i.shadowOffsetY=e.offsetY*r)},needsFullRender:function(){return new fabric.Color(this.color).getAlpha()<1||!!this.shadow},_resetShadow:function(){var t=this.canvas.contextTop;t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0},_isOutSideCanvas:function(t){return t.x<0||t.x>this.canvas.getWidth()||t.y<0||t.y>this.canvas.getHeight()}}),fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{decimate:.4,initialize:function(t){this.canvas=t,this._points=[]},_drawSegment:function(t,e,i){i=e.midPointFrom(i);return t.quadraticCurveTo(e.x,e.y,i.x,i.y),i},onMouseDown:function(t,e){this.canvas._isMainEvent(e.e)&&(this._prepareForDrawing(t),this._captureDrawingPath(t),this._render())},onMouseMove:function(t,e){var i;this.canvas._isMainEvent(e.e)&&(!0===this.limitedToCanvasSize&&this._isOutSideCanvas(t)||this._captureDrawingPath(t)&&1"},getObjectScaling:function(){if(!this.group)return{scaleX:this.scaleX,scaleY:this.scaleY};var t=g.util.qrDecompose(this.calcTransformMatrix());return{scaleX:Math.abs(t.scaleX),scaleY:Math.abs(t.scaleY)}},getTotalObjectScaling:function(){var t,e=this.getObjectScaling(),i=e.scaleX,r=e.scaleY;return this.canvas&&(i*=(t=this.canvas.getZoom())*(e=this.canvas.getRetinaScaling()),r*=t*e),{scaleX:i,scaleY:r}},getObjectOpacity:function(){var t=this.opacity;return this.group&&(t*=this.group.getObjectOpacity()),t},_set:function(t,e){var i,r=this[t]!==e;return("scaleX"===t||"scaleY"===t)&&(e=this._constrainScale(e)),"scaleX"===t&&e<0?(this.flipX=!this.flipX,e*=-1):"scaleY"===t&&e<0?(this.flipY=!this.flipY,e*=-1):"shadow"!==t||!e||e instanceof g.Shadow?"dirty"===t&&this.group&&this.group.set("dirty",e):e=new g.Shadow(e),this[t]=e,r&&(i=this.group&&this.group.isOnACache(),-1=t.x&&r.left+r.width<=e.x&&r.top>=t.y&&r.top+r.height<=e.y},containsPoint:function(t,e,i,r){r=this._getCoords(i,r),e=e||this._getImageLines(r),e=this._findCrossPoints(t,e);return 0!==e&&e%2==1},isOnScreen:function(t){if(!this.canvas)return!1;var e=this.canvas.vptCoords.tl,i=this.canvas.vptCoords.br;return!!this.getCoords(!0,t).some(function(t){return t.x<=i.x&&t.x>=e.x&&t.y<=i.y&&t.y>=e.y})||(!!this.intersectsWithRect(e,i,!0,t)||this._containsCenterOfCanvas(e,i,t))},_containsCenterOfCanvas:function(t,e,i){e={x:(t.x+e.x)/2,y:(t.y+e.y)/2};return!!this.containsPoint(e,null,!0,i)},isPartiallyOnScreen:function(t){if(!this.canvas)return!1;var e=this.canvas.vptCoords.tl,i=this.canvas.vptCoords.br;return!!this.intersectsWithRect(e,i,!0,t)||this.getCoords(!0,t).every(function(t){return(t.x>=i.x||t.x<=e.x)&&(t.y>=i.y||t.y<=e.y)})&&this._containsCenterOfCanvas(e,i,t)},_getImageLines:function(t){return{topline:{o:t.tl,d:t.tr},rightline:{o:t.tr,d:t.br},bottomline:{o:t.br,d:t.bl},leftline:{o:t.bl,d:t.tl}}},_findCrossPoints:function(t,e){var i,r,n,s=0;for(n in e)if(!((r=e[n]).o.y=t.y&&r.d.y>=t.y||((r.o.x===r.d.x&&r.o.x>=t.x?r.o.x:(i=(r.d.y-r.o.y)/(r.d.x-r.o.x),-(t.y-0*t.x-(r.o.y-i*r.o.x))/(0-i)))>=t.x&&(s+=1),2!==s)))break;return s},getBoundingRect:function(t,e){e=this.getCoords(t,e);return s.makeBoundingBoxFromPoints(e)},getScaledWidth:function(){return this._getTransformedDimensions().x},getScaledHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(t){return Math.abs(t)
    \n'))},toSVG:function(t){return this._createBaseSVGMarkup(this._toSVG(t),{reviver:t})},toClipPathSVG:function(t){return"\t"+this._createBaseClipPathSVGMarkup(this._toSVG(t),{reviver:t})},_createBaseClipPathSVGMarkup:function(t,e){var i=(e=e||{}).reviver,r=e.additionalTransform||"",e=[this.getSvgTransform(!0,r),this.getSvgCommons()].join(""),r=t.indexOf("COMMON_PARTS");return t[r]=e,i?i(t.join("")):t.join("")},_createBaseSVGMarkup:function(t,e){var i,r=(e=e||{}).noStyle,n=e.reviver,s=r?"":'style="'+this.getSvgStyles()+'" ',o=e.withShadow?'style="'+this.getSvgFilter()+'" ':"",a=this.clipPath,c=this.strokeUniform?'vector-effect="non-scaling-stroke" ':"",h=a&&a.absolutePositioned,l=this.stroke,u=this.fill,f=this.shadow,d=[],g=t.indexOf("COMMON_PARTS"),e=e.additionalTransform;return a&&(a.clipPathId="CLIPPATH_"+fabric.Object.__uid++,i='\n'+a.toClipPathSVG(n)+"\n"),h&&d.push("\n"),d.push("\n"),e=[s,c,r?"":this.addPaintOrder()," ",e?'transform="'+e+'" ':""].join(""),t[g]=e,u&&u.toLive&&d.push(u.toSVG(this)),l&&l.toLive&&d.push(l.toSVG(this)),f&&d.push(f.toSVG(this)),a&&d.push(i),d.push(t.join("")),d.push("\n"),h&&d.push("\n"),n?n(d.join("")):d.join("")},addPaintOrder:function(){return"fill"!==this.paintFirst?' paint-order="'+this.paintFirst+'" ':""}})}(),function(){var n=fabric.util.object.extend,r="stateProperties";function s(e,t,i){var r={};i.forEach(function(t){r[t]=e[t]}),n(e[t],r,!0)}fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(t){var e="_"+(t=t||r);return Object.keys(this[e]).length\n']}}),n.Line.ATTRIBUTE_NAMES=n.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),n.Line.fromElement=function(t,e,i){i=i||{};var r=n.parseAttributes(t,n.Line.ATTRIBUTE_NAMES),t=[r.x1||0,r.y1||0,r.x2||0,r.y2||0];e(new n.Line(t,s(r,i)))},n.Line.fromObject=function(t,e){var i=r(t,!0);i.points=[t.x1,t.y1,t.x2,t.y2],n.Object._fromObject("Line",i,function(t){delete t.points,e&&e(t)},"points")})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var s=t.fabric||(t.fabric={}),o=Math.PI;s.Circle?s.warn("fabric.Circle is already defined."):(s.Circle=s.util.createClass(s.Object,{type:"circle",radius:0,startAngle:0,endAngle:2*o,cacheProperties:s.Object.prototype.cacheProperties.concat("radius","startAngle","endAngle"),_set:function(t,e){return this.callSuper("_set",t,e),"radius"===t&&this.setRadius(e),this},toObject:function(t){return this.callSuper("toObject",["radius","startAngle","endAngle"].concat(t))},_toSVG:function(){var t,e,i,r,n=(this.endAngle-this.startAngle)%(2*o);return 0==n?["\n']:(t=s.util.cos(this.startAngle)*this.radius,e=s.util.sin(this.startAngle)*this.radius,i=s.util.cos(this.endAngle)*this.radius,r=s.util.sin(this.endAngle)*this.radius,['\n"])},_render:function(t){t.beginPath(),t.arc(0,0,this.radius,this.startAngle,this.endAngle,!1),this._renderPaintInOrder(t)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(t){return this.radius=t,this.set("width",2*t).set("height",2*t)}}),s.Circle.ATTRIBUTE_NAMES=s.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),s.Circle.fromElement=function(t,e){var i=s.parseAttributes(t,s.Circle.ATTRIBUTE_NAMES);if(!("radius"in(t=i)&&0<=t.radius))throw new Error("value of `r` attribute is required and can not be negative");i.left=(i.left||0)-i.radius,i.top=(i.top||0)-i.radius,e(new s.Circle(i))},s.Circle.fromObject=function(t,e){s.Object._fromObject("Circle",t,e)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var i=t.fabric||(t.fabric={});i.Triangle?i.warn("fabric.Triangle is already defined"):(i.Triangle=i.util.createClass(i.Object,{type:"triangle",width:100,height:100,_render:function(t){var e=this.width/2,i=this.height/2;t.beginPath(),t.moveTo(-e,i),t.lineTo(0,-i),t.lineTo(e,i),t.closePath(),this._renderPaintInOrder(t)},_toSVG:function(){var t=this.width/2,e=this.height/2;return["']}}),i.Triangle.fromObject=function(t,e){return i.Object._fromObject("Triangle",t,e)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var i=t.fabric||(t.fabric={}),e=2*Math.PI;i.Ellipse?i.warn("fabric.Ellipse is already defined."):(i.Ellipse=i.util.createClass(i.Object,{type:"ellipse",rx:0,ry:0,cacheProperties:i.Object.prototype.cacheProperties.concat("rx","ry"),initialize:function(t){this.callSuper("initialize",t),this.set("rx",t&&t.rx||0),this.set("ry",t&&t.ry||0)},_set:function(t,e){switch(this.callSuper("_set",t,e),t){case"rx":this.rx=e,this.set("width",2*e);break;case"ry":this.ry=e,this.set("height",2*e)}return this},getRx:function(){return this.get("rx")*this.get("scaleX")},getRy:function(){return this.get("ry")*this.get("scaleY")},toObject:function(t){return this.callSuper("toObject",["rx","ry"].concat(t))},_toSVG:function(){return["\n']},_render:function(t){t.beginPath(),t.save(),t.transform(1,0,0,this.ry/this.rx,0,0),t.arc(0,0,this.rx,0,e,!1),t.restore(),this._renderPaintInOrder(t)}}),i.Ellipse.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),i.Ellipse.fromElement=function(t,e){t=i.parseAttributes(t,i.Ellipse.ATTRIBUTE_NAMES);t.left=(t.left||0)-t.rx,t.top=(t.top||0)-t.ry,e(new i.Ellipse(t))},i.Ellipse.fromObject=function(t,e){i.Object._fromObject("Ellipse",t,e)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var r=t.fabric||(t.fabric={}),n=r.util.object.extend;r.Rect?r.warn("fabric.Rect is already defined"):(r.Rect=r.util.createClass(r.Object,{stateProperties:r.Object.prototype.stateProperties.concat("rx","ry"),type:"rect",rx:0,ry:0,cacheProperties:r.Object.prototype.cacheProperties.concat("rx","ry"),initialize:function(t){this.callSuper("initialize",t),this._initRxRy()},_initRxRy:function(){this.rx&&!this.ry?this.ry=this.rx:this.ry&&!this.rx&&(this.rx=this.ry)},_render:function(t){var e=this.rx?Math.min(this.rx,this.width/2):0,i=this.ry?Math.min(this.ry,this.height/2):0,r=this.width,n=this.height,s=-this.width/2,o=-this.height/2,a=0!==e||0!==i,c=.4477152502;t.beginPath(),t.moveTo(s+e,o),t.lineTo(s+r-e,o),a&&t.bezierCurveTo(s+r-c*e,o,s+r,o+c*i,s+r,o+i),t.lineTo(s+r,o+n-i),a&&t.bezierCurveTo(s+r,o+n-c*i,s+r-c*e,o+n,s+r-e,o+n),t.lineTo(s+e,o+n),a&&t.bezierCurveTo(s+c*e,o+n,s,o+n-c*i,s,o+n-i),t.lineTo(s,o+i),a&&t.bezierCurveTo(s,o+c*i,s+c*e,o,s+e,o),t.closePath(),this._renderPaintInOrder(t)},toObject:function(t){return this.callSuper("toObject",["rx","ry"].concat(t))},_toSVG:function(){return["\n']}}),r.Rect.ATTRIBUTE_NAMES=r.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")),r.Rect.fromElement=function(t,e,i){if(!t)return e(null);i=i||{};t=r.parseAttributes(t,r.Rect.ATTRIBUTE_NAMES);t.left=t.left||0,t.top=t.top||0,t.height=t.height||0,t.width=t.width||0;t=new r.Rect(n(i?r.util.object.clone(i):{},t));t.visible=t.visible&&0\n']},commonRender:function(t){var e,i=this.points.length,r=this.pathOffset.x,n=this.pathOffset.y;if(!i||isNaN(this.points[i-1].y))return!1;t.beginPath(),t.moveTo(this.points[0].x-r,this.points[0].y-n);for(var s=0;s"},toObject:function(t){return r(this.callSuper("toObject",t),{path:this.path.map(function(t){return t.slice()})})},toDatalessObject:function(t){t=this.toObject(["sourcePath"].concat(t));return t.sourcePath&&delete t.path,t},_toSVG:function(){return["\n"]},_getOffsetTransform:function(){var t=f.Object.NUM_FRACTION_DIGITS;return" translate("+e(-this.pathOffset.x,t)+", "+e(-this.pathOffset.y,t)+")"},toClipPathSVG:function(t){var e=this._getOffsetTransform();return"\t"+this._createBaseClipPathSVGMarkup(this._toSVG(),{reviver:t,additionalTransform:e})},toSVG:function(t){var e=this._getOffsetTransform();return this._createBaseSVGMarkup(this._toSVG(),{reviver:t,additionalTransform:e})},complexity:function(){return this.path.length},_calcDimensions:function(){for(var t,e,i=[],r=[],n=0,s=0,o=0,a=0,c=0,h=this.path.length;c"},addWithUpdate:function(t){var e=!!this.group;return this._restoreObjectsState(),o.util.resetObjectTransform(this),t&&(e&&o.util.removeTransformFromObject(t,this.group.calcTransformMatrix()),this._objects.push(t),t.group=this,t._set("canvas",this.canvas)),this._calcBounds(),this._updateObjectsCoords(),this.dirty=!0,e?this.group.addWithUpdate():this.setCoords(),this},removeWithUpdate:function(t){return this._restoreObjectsState(),o.util.resetObjectTransform(this),this.remove(t),this._calcBounds(),this._updateObjectsCoords(),this.setCoords(),this.dirty=!0,this},_onObjectAdded:function(t){this.dirty=!0,t.group=this,t._set("canvas",this.canvas)},_onObjectRemoved:function(t){this.dirty=!0,delete t.group},_set:function(t,e){var i=this._objects.length;if(this.useSetOnGroup)for(;i--;)this._objects[i].setOnGroup(t,e);if("canvas"===t)for(;i--;)this._objects[i]._set(t,e);o.Object.prototype._set.call(this,t,e)},toObject:function(r){var n=this.includeDefaultValues,t=this._objects.filter(function(t){return!t.excludeFromExport}).map(function(t){var e=t.includeDefaultValues;t.includeDefaultValues=n;var i=t.toObject(r);return t.includeDefaultValues=e,i}),e=o.Object.prototype.toObject.call(this,r);return e.objects=t,e},toDatalessObject:function(r){var n,t,e=this.sourcePath;t=e||(n=this.includeDefaultValues,this._objects.map(function(t){var e=t.includeDefaultValues;t.includeDefaultValues=n;var i=t.toDatalessObject(r);return t.includeDefaultValues=e,i}));e=o.Object.prototype.toDatalessObject.call(this,r);return e.objects=t,e},render:function(t){this._transformDone=!0,this.callSuper("render",t),this._transformDone=!1},shouldCache:function(){var t=o.Object.prototype.shouldCache.call(this);if(t)for(var e=0,i=this._objects.length;e\n"],i=0,r=this._objects.length;i\n"),e},getSvgStyles:function(){var t=void 0!==this.opacity&&1!==this.opacity?"opacity: "+this.opacity+";":"",e=this.visible?"":" visibility: hidden;";return[t,this.getSvgFilter(),e].join("")},toClipPathSVG:function(t){for(var e=[],i=0,r=this._objects.length;i"},shouldCache:function(){return!1},isOnACache:function(){return!1},_renderControls:function(t,e,i){t.save(),t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,this.callSuper("_renderControls",t,e),void 0===(i=i||{}).hasControls&&(i.hasControls=!1),i.forActiveSelection=!0;for(var r=0,n=this._objects.length;r\n','\t\n',"\n"),a=' clip-path="url(#imageCrop_'+e+')" '),this.imageSmoothing||(c='" image-rendering="optimizeSpeed'),r.push("\t\n"),(this.stroke||this.strokeDashArray)&&(a=this.fill,this.fill=null,t=["\t\n'],this.fill=a),i="fill"!==this.paintFirst?i.concat(t,r):i.concat(r,t)):[]},getSrc:function(t){t=t?this._element:this._originalElement;return t?t.toDataURL?t.toDataURL():this.srcFromAttribute?t.getAttribute("src"):t.src:this.src||""},setSrc:function(t,i,r){return fabric.util.loadImage(t,function(t,e){this.setElement(t,r),this._setWidthHeight(),i&&i(this,e)},this,r&&r.crossOrigin),this},toString:function(){return'#'},applyResizeFilters:function(){var t=this.resizeFilter,e=this.minimumScaleTrigger,i=this.getTotalObjectScaling(),r=i.scaleX,n=i.scaleY,s=this._filteredEl||this._originalElement;if(this.group&&this.set("dirty",!0),!t||e=t,o=["highp","mediump","lowp"],a=0;a<3;a++)if(r=void 0,r="precision "+(i=o[a])+" float;\nvoid main(){}",i=(e=s).createShader(e.FRAGMENT_SHADER),e.shaderSource(i,r),e.compileShader(i),!!e.getShaderParameter(i,e.COMPILE_STATUS)){fabric.webGlPrecision=o[a];break}}return this.isSupported=n},(fabric.WebglFilterBackend=t).prototype={tileSize:2048,resources:{},setupGLContext:function(t,e){this.dispose(),this.createWebGLCanvas(t,e),this.aPosition=new Float32Array([0,0,0,1,1,0,1,1]),this.chooseFastestCopyGLTo2DMethod(t,e)},chooseFastestCopyGLTo2DMethod:function(t,e){var i=void 0!==window.performance;try{new ImageData(1,1),s=!0}catch(t){s=!1}var r="undefined"!=typeof ArrayBuffer,n="undefined"!=typeof Uint8ClampedArray;if(i&&s&&r&&n){var s=fabric.util.createCanvasElement(),r=new ArrayBuffer(t*e*4);if(fabric.forceGLPutImageData)return this.imageBuffer=r,void(this.copyGLTo2D=copyGLTo2DPutImageData);n={imageBuffer:r,destinationWidth:t,destinationHeight:e,targetCanvas:s};s.width=t,s.height=e,s=window.performance.now(),copyGLTo2DDrawImage.call(n,this.gl,n),e=window.performance.now()-s,s=window.performance.now(),copyGLTo2DPutImageData.call(n,this.gl,n),window.performance.now()-s 0.0) {\n"+this.fragmentSource[t]+"}\n}"},retrieveShader:function(t){var e,i=this.type+"_"+this.mode;return t.programCache.hasOwnProperty(i)||(e=this.buildSource(this.mode),t.programCache[i]=this.createProgram(t.context,e)),t.programCache[i]},applyTo2d:function(t){for(var e,i,r,n=t.imageData.data,s=n.length,o=1-this.alpha,t=new u.Color(this.color).getSource(),a=t[0]*this.alpha,c=t[1]*this.alpha,h=t[2]*this.alpha,l=0;l'},_getCacheCanvasDimensions:function(){var t=this.callSuper("_getCacheCanvasDimensions"),e=this.fontSize;return t.width+=e*t.zoomX,t.height+=e*t.zoomY,t},_render:function(t){var e=this.path;e&&!e.isNotVisible()&&e._render(t),this._setTextStyles(t),this._renderTextLinesBackground(t),this._renderTextDecoration(t,"underline"),this._renderText(t),this._renderTextDecoration(t,"overline"),this._renderTextDecoration(t,"linethrough")},_renderText:function(t){"stroke"===this.paintFirst?(this._renderTextStroke(t),this._renderTextFill(t)):(this._renderTextFill(t),this._renderTextStroke(t))},_setTextStyles:function(t,e,i){t.textBaseline="alphabetic",t.font=this._getFontDeclaration(e,i)},calcTextWidth:function(){for(var t=this.getLineWidth(0),e=1,i=this._textLines.length;ethis.__selectionStartOnMouseDown?(this.selectionStart=this.__selectionStartOnMouseDown,this.selectionEnd=e):(this.selectionStart=e,this.selectionEnd=this.__selectionStartOnMouseDown),this.selectionStart===i&&this.selectionEnd===t||(this.restartCursorIfNeeded(),this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection())))},_setEditingProps:function(){this.hoverCursor="text",this.canvas&&(this.canvas.defaultCursor=this.canvas.moveCursor="text"),this.borderColor=this.editingBorderColor,this.hasControls=this.selectable=!1,this.lockMovementX=this.lockMovementY=!0},fromStringToGraphemeSelection:function(t,e,i){var r=i.slice(0,t),r=fabric.util.string.graphemeSplit(r).length;if(t===e)return{selectionStart:r,selectionEnd:r};e=i.slice(t,e);return{selectionStart:r,selectionEnd:r+fabric.util.string.graphemeSplit(e).length}},fromGraphemeToStringSelection:function(t,e,i){var r=i.slice(0,t).join("").length;return t===e?{selectionStart:r,selectionEnd:r}:{selectionStart:r,selectionEnd:r+i.slice(t,e).join("").length}},_updateTextarea:function(){var t;this.cursorOffsetCache={},this.hiddenTextarea&&(this.inCompositionMode||(t=this.fromGraphemeToStringSelection(this.selectionStart,this.selectionEnd,this._text),this.hiddenTextarea.selectionStart=t.selectionStart,this.hiddenTextarea.selectionEnd=t.selectionEnd),this.updateTextareaPosition())},updateFromTextArea:function(){var t;this.hiddenTextarea&&(this.cursorOffsetCache={},this.text=this.hiddenTextarea.value,this._shouldClearDimensionCache()&&(this.initDimensions(),this.setCoords()),t=this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart,this.hiddenTextarea.selectionEnd,this.hiddenTextarea.value),this.selectionEnd=this.selectionStart=t.selectionEnd,this.inCompositionMode||(this.selectionStart=t.selectionStart),this.updateTextareaPosition())},updateTextareaPosition:function(){var t;this.selectionStart===this.selectionEnd&&(t=this._calcTextareaPosition(),this.hiddenTextarea.style.left=t.left,this.hiddenTextarea.style.top=t.top)},_calcTextareaPosition:function(){if(!this.canvas)return{x:1,y:1};var t=this.inCompositionMode?this.compositionStart:this.selectionStart,e=this._getCursorBoundaries(t),i=this.get2DCursorLocation(t),r=i.lineIndex,n=i.charIndex,s=this.getValueOfPropertyAt(r,n,"fontSize")*this.lineHeight,o=e.leftOffset,a=this.calcTransformMatrix(),t={x:e.left+o,y:e.top+e.topOffset+s},i=this.canvas.getRetinaScaling(),r=this.canvas.upperCanvasEl,n=r.width/i,o=r.height/i,e=n-s,i=o-s,n=r.clientWidth/n,o=r.clientHeight/o,t=fabric.util.transformPoint(t,a);return(t=fabric.util.transformPoint(t,this.canvas.viewportTransform)).x*=n,t.y*=o,t.x<0&&(t.x=0),t.x>e&&(t.x=e),t.y<0&&(t.y=0),t.y>i&&(t.y=i),t.x+=this.canvas._offset.left,t.y+=this.canvas._offset.top,{left:t.x+"px",top:t.y+"px",fontSize:s+"px",charHeight:s}},_saveEditingProps:function(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,selectable:this.selectable,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}},_restoreEditingProps:function(){this._savedProps&&(this.hoverCursor=this._savedProps.hoverCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,this.selectable=this._savedProps.selectable,this.lockMovementX=this._savedProps.lockMovementX,this.lockMovementY=this._savedProps.lockMovementY,this.canvas&&(this.canvas.defaultCursor=this._savedProps.defaultCursor,this.canvas.moveCursor=this._savedProps.moveCursor))},exitEditing:function(){var t=this._textBeforeEdit!==this.text,e=this.hiddenTextarea;return this.selected=!1,this.isEditing=!1,this.selectionEnd=this.selectionStart,e&&(e.blur&&e.blur(),e.parentNode&&e.parentNode.removeChild(e)),this.hiddenTextarea=null,this.abortCursorAnimation(),this._restoreEditingProps(),this._currentCursorOpacity=0,this._shouldClearDimensionCache()&&(this.initDimensions(),this.setCoords()),this.fire("editing:exited"),t&&this.fire("modified"),this.canvas&&(this.canvas.off("mouse:move",this.mouseMoveHandler),this.canvas.fire("text:editing:exited",{target:this}),t&&this.canvas.fire("object:modified",{target:this})),this},_removeExtraneousStyles:function(){for(var t in this.styles)this._textLines[t]||delete this.styles[t]},removeStyleFromTo:function(t,e){var t=this.get2DCursorLocation(t,!0),e=this.get2DCursorLocation(e,!0),i=t.lineIndex,r=t.charIndex,n=e.lineIndex,s=e.charIndex;if(i!==n){if(this.styles[i])for(l=r;lt?this.selectionStart=t:this.selectionStart<0&&(this.selectionStart=0),this.selectionEnd>t?this.selectionEnd=t:this.selectionEnd<0&&(this.selectionEnd=0)}})}(),fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+new Date,this.__lastLastClickTime=+new Date,this.__lastPointer={},this.on("mousedown",this.onMouseDown)},onMouseDown:function(t){var e;this.canvas&&(this.__newClickTime=+new Date,e=t.pointer,this.isTripleClick(e)&&(this.fire("tripleclick",t),this._stopEvent(t.e)),this.__lastLastClickTime=this.__lastClickTime,this.__lastClickTime=this.__newClickTime,this.__lastPointer=e,this.__lastIsEditing=this.isEditing,this.__lastSelected=this.selected)},isTripleClick:function(t){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===t.x&&this.__lastPointer.y===t.y},_stopEvent:function(t){t.preventDefault&&t.preventDefault(),t.stopPropagation&&t.stopPropagation()},initCursorSelectionHandlers:function(){this.initMousedownHandler(),this.initMouseupHandler(),this.initClicks()},doubleClickHandler:function(t){this.isEditing&&this.selectWord(this.getSelectionStartFromPointer(t.e))},tripleClickHandler:function(t){this.isEditing&&this.selectLine(this.getSelectionStartFromPointer(t.e))},initClicks:function(){this.on("mousedblclick",this.doubleClickHandler),this.on("tripleclick",this.tripleClickHandler)},_mouseDownHandler:function(t){!this.canvas||!this.editable||t.e.button&&1!==t.e.button||(this.__isMousedown=!0,this.selected&&(this.inCompositionMode=!1,this.setCursorByClick(t.e)),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.selectionStart===this.selectionEnd&&this.abortCursorAnimation(),this.renderCursorOrSelection()))},_mouseDownHandlerBefore:function(t){!this.canvas||!this.editable||t.e.button&&1!==t.e.button||(this.selected=this===this.canvas._activeObject)},initMousedownHandler:function(){this.on("mousedown",this._mouseDownHandler),this.on("mousedown:before",this._mouseDownHandlerBefore)},initMouseupHandler:function(){this.on("mouseup",this.mouseUpHandler)},mouseUpHandler:function(t){if(this.__isMousedown=!1,!(!this.editable||this.group||t.transform&&t.transform.actionPerformed||t.e.button&&1!==t.e.button)){if(this.canvas){var e=this.canvas._activeObject;if(e&&e!==this)return}this.__lastSelected&&!this.__corner?(this.selected=!1,this.__lastSelected=!1,this.enterEditing(t.e),this.selectionStart===this.selectionEnd?this.initDelayedCursor(!0):this.renderCursorOrSelection()):this.selected=!0}},setCursorByClick:function(t){var e=this.getSelectionStartFromPointer(t),i=this.selectionStart,r=this.selectionEnd;t.shiftKey?this.setSelectionStartEndWithShift(i,r,e):(this.selectionStart=e,this.selectionEnd=e),this.isEditing&&(this._fireSelectionChanged(),this._updateTextarea())},getSelectionStartFromPointer:function(t){for(var e=this.getLocalPointer(t),i=0,r=0,n=0,s=0,o=0,a=0,c=this._textLines.length;athis._text.length?this._text.length:t}}),fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(){this.hiddenTextarea=fabric.document.createElement("textarea"),this.hiddenTextarea.setAttribute("autocapitalize","off"),this.hiddenTextarea.setAttribute("autocorrect","off"),this.hiddenTextarea.setAttribute("autocomplete","off"),this.hiddenTextarea.setAttribute("spellcheck","false"),this.hiddenTextarea.setAttribute("data-fabric-hiddentextarea",""),this.hiddenTextarea.setAttribute("wrap","off");var t=this._calcTextareaPosition();this.hiddenTextarea.style.cssText="position: absolute; top: "+t.top+"; left: "+t.left+"; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; paddingーtop: "+t.fontSize+";",(this.hiddenTextareaContainer||fabric.document.body).appendChild(this.hiddenTextarea),fabric.util.addListener(this.hiddenTextarea,"keydown",this.onKeyDown.bind(this)),fabric.util.addListener(this.hiddenTextarea,"keyup",this.onKeyUp.bind(this)),fabric.util.addListener(this.hiddenTextarea,"input",this.onInput.bind(this)),fabric.util.addListener(this.hiddenTextarea,"copy",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"cut",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"paste",this.paste.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionstart",this.onCompositionStart.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionupdate",this.onCompositionUpdate.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionend",this.onCompositionEnd.bind(this)),!this._clickHandlerInitialized&&this.canvas&&(fabric.util.addListener(this.canvas.upperCanvasEl,"click",this.onClick.bind(this)),this._clickHandlerInitialized=!0)},keysMap:{9:"exitEditing",27:"exitEditing",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorRight",36:"moveCursorLeft",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown"},keysMapRtl:{9:"exitEditing",27:"exitEditing",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorLeft",36:"moveCursorRight",37:"moveCursorRight",38:"moveCursorUp",39:"moveCursorLeft",40:"moveCursorDown"},ctrlKeysMapUp:{67:"copy",88:"cut"},ctrlKeysMapDown:{65:"selectAll"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(t){if(this.isEditing){var e="rtl"===this.direction?this.keysMapRtl:this.keysMap;if(t.keyCode in e)this[e[t.keyCode]](t);else{if(!(t.keyCode in this.ctrlKeysMapDown&&(t.ctrlKey||t.metaKey)))return;this[this.ctrlKeysMapDown[t.keyCode]](t)}t.stopImmediatePropagation(),t.preventDefault(),33<=t.keyCode&&t.keyCode<=40?(this.inCompositionMode=!1,this.clearContextTop(),this.renderCursorOrSelection()):this.canvas&&this.canvas.requestRenderAll()}},onKeyUp:function(t){!this.isEditing||this._copyDone||this.inCompositionMode?this._copyDone=!1:t.keyCode in this.ctrlKeysMapUp&&(t.ctrlKey||t.metaKey)&&(this[this.ctrlKeysMapUp[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.requestRenderAll())},onInput:function(t){var e=this.fromPaste;if(this.fromPaste=!1,t&&t.stopPropagation(),this.isEditing){var i,r,n,s=this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,o=this._text.length,a=s.length,c=a-o,h=this.selectionStart,l=this.selectionEnd,u=h!==l;if(""===this.hiddenTextarea.value)return this.styles={},this.updateFromTextArea(),this.fire("changed"),void(this.canvas&&(this.canvas.fire("text:changed",{target:this}),this.canvas.requestRenderAll()));var f=this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart,this.hiddenTextarea.selectionEnd,this.hiddenTextarea.value),t=h>f.selectionStart;u?(n=this._text.slice(h,l),c+=l-h):a=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorUpOrDown("Down",t)},moveCursorUp:function(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorUpOrDown("Up",t)},_moveCursorUpOrDown:function(t,e){t=this["get"+t+"CursorOffset"](e,"right"===this._selectionDirection);e.shiftKey?this.moveCursorWithShift(t):this.moveCursorWithoutShift(t),0!==t&&(this.setSelectionInBoundaries(),this.abortCursorAnimation(),this._currentCursorOpacity=1,this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorWithShift:function(t){var e="left"===this._selectionDirection?this.selectionStart+t:this.selectionEnd+t;return this.setSelectionStartEndWithShift(this.selectionStart,this.selectionEnd,e),0!==t},moveCursorWithoutShift:function(t){return t<0?(this.selectionStart+=t,this.selectionEnd=this.selectionStart):(this.selectionEnd+=t,this.selectionStart=this.selectionEnd),0!==t},moveCursorLeft:function(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorLeftOrRight("Left",t)},_move:function(t,e,i){var r;if(t.altKey)r=this["findWordBoundary"+i](this[e]);else{if(!t.metaKey&&35!==t.keyCode&&36!==t.keyCode)return this[e]+="Left"===i?-1:1,!0;r=this["findLineBoundary"+i](this[e])}if(this[e]!==r)return this[e]=r,!0},_moveLeft:function(t,e){return this._move(t,e,"Left")},_moveRight:function(t,e){return this._move(t,e,"Right")},moveCursorLeftWithoutShift:function(t){var e=!0;return this._selectionDirection="left",this.selectionEnd===this.selectionStart&&0!==this.selectionStart&&(e=this._moveLeft(t,"selectionStart")),this.selectionEnd=this.selectionStart,e},moveCursorLeftWithShift:function(t){return"right"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveLeft(t,"selectionEnd"):0!==this.selectionStart?(this._selectionDirection="left",this._moveLeft(t,"selectionStart")):void 0},moveCursorRight:function(t){this.selectionStart>=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorLeftOrRight("Right",t)},_moveCursorLeftOrRight:function(t,e){t="moveCursor"+t+"With";this._currentCursorOpacity=1,e.shiftKey?t+="Shift":t+="outShift",this[t](e)&&(this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorRightWithShift:function(t){return"left"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveRight(t,"selectionStart"):this.selectionEnd!==this._text.length?(this._selectionDirection="right",this._moveRight(t,"selectionEnd")):void 0},moveCursorRightWithoutShift:function(t){var e=!0;return this._selectionDirection="right",this.selectionStart===this.selectionEnd?(e=this._moveRight(t,"selectionStart"),this.selectionEnd=this.selectionStart):this.selectionStart=this.selectionEnd,e},removeChars:function(t,e){this.removeStyleFromTo(t,e=void 0===e?t+1:e),this._text.splice(t,e-t),this.text=this._text.join(""),this.set("dirty",!0),this._shouldClearDimensionCache()&&(this.initDimensions(),this.setCoords()),this._removeExtraneousStyles()},insertChars:function(t,e,i,r){i<(r=void 0===r?i:r)&&this.removeStyleFromTo(i,r);t=fabric.util.string.graphemeSplit(t);this.insertNewStyleBlock(t,i,e),this._text=[].concat(this._text.slice(0,i),t,this._text.slice(r)),this.text=this._text.join(""),this.set("dirty",!0),this._shouldClearDimensionCache()&&(this.initDimensions(),this.setCoords()),this._removeExtraneousStyles()}}),function(){var a=fabric.util.toFixed,c=/ +/g;fabric.util.object.extend(fabric.Text.prototype,{_toSVG:function(){var t=this._getSVGLeftTopOffsets(),t=this._getSVGTextAndBg(t.textTop,t.textLeft);return this._wrapSVGTextAndBg(t)},toSVG:function(t){return this._createBaseSVGMarkup(this._toSVG(),{reviver:t,noStyle:!0,withShadow:!0})},_getSVGLeftTopOffsets:function(){return{textLeft:-this.width/2,textTop:-this.height/2,lineTop:this.getHeightOfLine(0)}},_wrapSVGTextAndBg:function(t){var e=this.getSvgTextDecoration(this);return[t.textBgRects.join(""),'\t\t",t.textSpans.join(""),"\n"]},_getSVGTextAndBg:function(t,e){var i,r=[],n=[],s=t;this._setSVGBg(n);for(var o=0,a=this._textLines.length;o",fabric.util.string.escapeXml(t),""].join("")},_setSVGTextLineText:function(t,e,i,r){var n,s,o,a,c=this.getHeightOfLine(e),h=-1!==this.textAlign.indexOf("justify"),l="",u=0,f=this._textLines[e];r+=c*(1-this._fontSizeFraction)/this.lineHeight;for(var d=0,g=f.length-1;d<=g;d++)a=d===g||this.charSpacing,l+=f[d],o=this.__charBounds[e][d],0===u?(i+=o.kernedWidth-o.width,u+=o.width):u+=o.kernedWidth,(a=h&&!a&&this._reSpaceAndTab.test(f[d])?!0:a)||(n=n||this.getCompleteStyleDeclaration(e,d),s=this.getCompleteStyleDeclaration(e,d+1),a=this._hasStyleChangedForSvg(n,s)),a&&(a=this._getStyleDeclaration(e,d)||{},t.push(this._createTextCharSpan(l,a,i,r)),l="",n=s,i+=u,u=0)},_pushTextBgRect:function(t,e,i,r,n,s){var o=fabric.Object.NUM_FRACTION_DIGITS;t.push("\t\t\n')},_setSVGTextLineBg:function(t,e,i,r){for(var n,s,o=this._textLines[e],a=this.getHeightOfLine(e)/this.lineHeight,c=0,h=0,l=this.getValueOfPropertyAt(e,0,"textBackgroundColor"),u=0,f=o.length;uthis.width&&this._set("width",this.dynamicMinWidth),-1!==this.textAlign.indexOf("justify")&&this.enlargeSpaces(),this.height=this.calcTextHeight(),this.saveState({propertySet:"_dimensionAffectingProps"}))},_generateStyleMap:function(t){for(var e=0,i=0,r=0,n={},s=0;sthis.dynamicMinWidth&&(this.dynamicMinWidth=g-m+r),c},isEndOfWrapping:function(t){return!this._styleMap[t+1]||this._styleMap[t+1].line!==this._styleMap[t].line},missingNewlineOffset:function(t){return!this.splitByGrapheme||this.isEndOfWrapping(t)?1:0},_splitTextIntoLines:function(t){for(var t=b.Text.prototype._splitTextIntoLines.call(this,t),e=this._wrapText(t.lines,this.width),i=new Array(e.length),r=0;r 0); - -/** - * True when in environment that's probably Node.js - * @type boolean - */ -fabric.isLikelyNode = typeof Buffer !== 'undefined' && - typeof window === 'undefined'; - -/* _FROM_SVG_START_ */ -/** - * Attributes parsed from all SVG elements - * @type array - */ -fabric.SHARED_ATTRIBUTES = [ - 'display', - 'transform', - 'fill', 'fill-opacity', 'fill-rule', - 'opacity', - 'stroke', 'stroke-dasharray', 'stroke-linecap', 'stroke-dashoffset', - 'stroke-linejoin', 'stroke-miterlimit', - 'stroke-opacity', 'stroke-width', - 'id', 'paint-order', 'vector-effect', - 'instantiated_by_use', 'clip-path', -]; -/* _FROM_SVG_END_ */ - -/** - * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion. - */ -fabric.DPI = 96; -fabric.reNum = '(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:[eE][-+]?\\d+)?)'; -fabric.commaWsp = '(?:\\s+,?\\s*|,\\s*)'; -fabric.rePathCommand = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:[eE][-+]?\d+)?)/ig; -fabric.reNonWord = /[ \n\.,;!\?\-]/; -fabric.fontPaths = { }; -fabric.iMatrix = [1, 0, 0, 1, 0, 0]; -fabric.svgNS = 'http://www.w3.org/2000/svg'; - -/** - * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine. - * @since 1.7.14 - * @type Number - * @default - */ -fabric.perfLimitSizeTotal = 2097152; - -/** - * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000 - * @since 1.7.14 - * @type Number - * @default - */ -fabric.maxCacheSideLimit = 4096; - -/** - * Lowest pixel limit for cache canvases, set at 256PX - * @since 1.7.14 - * @type Number - * @default - */ -fabric.minCacheSideLimit = 256; - -/** - * Cache Object for widths of chars in text rendering. - */ -fabric.charWidthsCache = { }; - -/** - * if webgl is enabled and available, textureSize will determine the size - * of the canvas backend - * @since 2.0.0 - * @type Number - * @default - */ -fabric.textureSize = 2048; - -/** - * When 'true', style information is not retained when copy/pasting text, making - * pasted text use destination style. - * Defaults to 'false'. - * @type Boolean - * @default - */ -fabric.disableStyleCopyPaste = false; - -/** - * Enable webgl for filtering picture is available - * A filtering backend will be initialized, this will both take memory and - * time since a default 2048x2048 canvas will be created for the gl context - * @since 2.0.0 - * @type Boolean - * @default - */ -fabric.enableGLFiltering = true; - -/** - * Device Pixel Ratio - * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html - */ -fabric.devicePixelRatio = fabric.window.devicePixelRatio || - fabric.window.webkitDevicePixelRatio || - fabric.window.mozDevicePixelRatio || - 1; -/** - * Browser-specific constant to adjust CanvasRenderingContext2D.shadowBlur value, - * which is unitless and not rendered equally across browsers. - * - * Values that work quite well (as of October 2017) are: - * - Chrome: 1.5 - * - Edge: 1.75 - * - Firefox: 0.9 - * - Safari: 0.95 - * - * @since 2.0.0 - * @type Number - * @default 1 - */ -fabric.browserShadowBlurConstant = 1; - -/** - * This object contains the result of arc to bezier conversion for faster retrieving if the same arc needs to be converted again. - * It was an internal variable, is accessible since version 2.3.4 - */ -fabric.arcToSegmentsCache = { }; - -/** - * This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it. - * It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing - * you do not get any speed benefit and you get a big object in memory. - * The object was a private variable before, while now is appended to the lib so that you have access to it and you - * can eventually clear it. - * It was an internal variable, is accessible since version 2.3.4 - */ -fabric.boundsOfCurveCache = { }; - -/** - * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better - * @default true - */ -fabric.cachesBoundsOfCurve = true; - -/** - * Skip performance testing of setupGLContext and force the use of putImageData that seems to be the one that works best on - * Chrome + old hardware. if your users are experiencing empty images after filtering you may try to force this to true - * this has to be set before instantiating the filtering backend ( before filtering the first image ) - * @type Boolean - * @default false - */ -fabric.forceGLPutImageData = false; - -fabric.initFilterBackend = function() { - if (fabric.enableGLFiltering && fabric.isWebglSupported && fabric.isWebglSupported(fabric.textureSize)) { - console.log('max texture size: ' + fabric.maxTextureSize); - return (new fabric.WebglFilterBackend({ tileSize: fabric.textureSize })); - } - else if (fabric.Canvas2dFilterBackend) { - return (new fabric.Canvas2dFilterBackend()); - } -}; - - -if (typeof document !== 'undefined' && typeof window !== 'undefined') { - // ensure globality even if entire library were function wrapped (as in Meteor.js packaging system) - window.fabric = fabric; -} - - -(function() { - - /** - * @private - * @param {String} eventName - * @param {Function} handler - */ - function _removeEventListener(eventName, handler) { - if (!this.__eventListeners[eventName]) { - return; - } - var eventListener = this.__eventListeners[eventName]; - if (handler) { - eventListener[eventListener.indexOf(handler)] = false; - } - else { - fabric.util.array.fill(eventListener, false); - } - } - - /** - * Observes specified event - * @memberOf fabric.Observable - * @alias on - * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler}) - * @param {Function} handler Function that receives a notification when an event of the specified type occurs - * @return {Self} thisArg - * @chainable - */ - function on(eventName, handler) { - if (!this.__eventListeners) { - this.__eventListeners = { }; - } - // one object with key/value pairs was passed - if (arguments.length === 1) { - for (var prop in eventName) { - this.on(prop, eventName[prop]); - } - } - else { - if (!this.__eventListeners[eventName]) { - this.__eventListeners[eventName] = []; - } - this.__eventListeners[eventName].push(handler); - } - return this; - } - - function _once(eventName, handler) { - var _handler = function () { - handler.apply(this, arguments); - this.off(eventName, _handler); - }.bind(this); - this.on(eventName, _handler); - } - - function once(eventName, handler) { - // one object with key/value pairs was passed - if (arguments.length === 1) { - for (var prop in eventName) { - _once.call(this, prop, eventName[prop]); - } - } - else { - _once.call(this, eventName, handler); - } - return this; - } - - /** - * Stops event observing for a particular event handler. Calling this method - * without arguments removes all handlers for all events - * @memberOf fabric.Observable - * @alias off - * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler}) - * @param {Function} handler Function to be deleted from EventListeners - * @return {Self} thisArg - * @chainable - */ - function off(eventName, handler) { - if (!this.__eventListeners) { - return this; - } - - // remove all key/value pairs (event name -> event handler) - if (arguments.length === 0) { - for (eventName in this.__eventListeners) { - _removeEventListener.call(this, eventName); - } - } - // one object with key/value pairs was passed - else if (arguments.length === 1 && typeof arguments[0] === 'object') { - for (var prop in eventName) { - _removeEventListener.call(this, prop, eventName[prop]); - } - } - else { - _removeEventListener.call(this, eventName, handler); - } - return this; - } - - /** - * Fires event with an optional options object - * @memberOf fabric.Observable - * @param {String} eventName Event name to fire - * @param {Object} [options] Options object - * @return {Self} thisArg - * @chainable - */ - function fire(eventName, options) { - if (!this.__eventListeners) { - return this; - } - - var listenersForEvent = this.__eventListeners[eventName]; - if (!listenersForEvent) { - return this; - } - - for (var i = 0, len = listenersForEvent.length; i < len; i++) { - listenersForEvent[i] && listenersForEvent[i].call(this, options || { }); - } - this.__eventListeners[eventName] = listenersForEvent.filter(function(value) { - return value !== false; - }); - return this; - } - - /** - * @namespace fabric.Observable - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events} - * @see {@link http://fabricjs.com/events|Events demo} - */ - fabric.Observable = { - fire: fire, - on: on, - once: once, - off: off, - }; -})(); - - -/** - * @namespace fabric.Collection - */ -fabric.Collection = { - - _objects: [], - - /** - * Adds objects to collection, Canvas or Group, then renders canvas - * (if `renderOnAddRemove` is not `false`). - * in case of Group no changes to bounding box are made. - * Objects should be instances of (or inherit from) fabric.Object - * Use of this function is highly discouraged for groups. - * you can add a bunch of objects with the add method but then you NEED - * to run a addWithUpdate call for the Group class or position/bbox will be wrong. - * @param {...fabric.Object} object Zero or more fabric instances - * @return {Self} thisArg - * @chainable - */ - add: function () { - this._objects.push.apply(this._objects, arguments); - if (this._onObjectAdded) { - for (var i = 0, length = arguments.length; i < length; i++) { - this._onObjectAdded(arguments[i]); - } - } - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * Inserts an object into collection at specified index, then renders canvas (if `renderOnAddRemove` is not `false`) - * An object should be an instance of (or inherit from) fabric.Object - * Use of this function is highly discouraged for groups. - * you can add a bunch of objects with the insertAt method but then you NEED - * to run a addWithUpdate call for the Group class or position/bbox will be wrong. - * @param {Object} object Object to insert - * @param {Number} index Index to insert object at - * @param {Boolean} nonSplicing When `true`, no splicing (shifting) of objects occurs - * @return {Self} thisArg - * @chainable - */ - insertAt: function (object, index, nonSplicing) { - var objects = this._objects; - if (nonSplicing) { - objects[index] = object; - } - else { - objects.splice(index, 0, object); - } - this._onObjectAdded && this._onObjectAdded(object); - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`) - * @param {...fabric.Object} object Zero or more fabric instances - * @return {Self} thisArg - * @chainable - */ - remove: function() { - var objects = this._objects, - index, somethingRemoved = false; - - for (var i = 0, length = arguments.length; i < length; i++) { - index = objects.indexOf(arguments[i]); - - // only call onObjectRemoved if an object was actually removed - if (index !== -1) { - somethingRemoved = true; - objects.splice(index, 1); - this._onObjectRemoved && this._onObjectRemoved(arguments[i]); - } - } - - this.renderOnAddRemove && somethingRemoved && this.requestRenderAll(); - return this; - }, - - /** - * Executes given function for each object in this group - * @param {Function} callback - * Callback invoked with current object as first argument, - * index - as second and an array of all objects - as third. - * Callback is invoked in a context of Global Object (e.g. `window`) - * when no `context` argument is given - * - * @param {Object} context Context (aka thisObject) - * @return {Self} thisArg - * @chainable - */ - forEachObject: function(callback, context) { - var objects = this.getObjects(); - for (var i = 0, len = objects.length; i < len; i++) { - callback.call(context, objects[i], i, objects); - } - return this; - }, - - /** - * Returns an array of children objects of this instance - * Type parameter introduced in 1.3.10 - * since 2.3.5 this method return always a COPY of the array; - * @param {String} [type] When specified, only objects of this type are returned - * @return {Array} - */ - getObjects: function(type) { - if (typeof type === 'undefined') { - return this._objects.concat(); - } - return this._objects.filter(function(o) { - return o.type === type; - }); - }, - - /** - * Returns object at specified index - * @param {Number} index - * @return {Self} thisArg - */ - item: function (index) { - return this._objects[index]; - }, - - /** - * Returns true if collection contains no objects - * @return {Boolean} true if collection is empty - */ - isEmpty: function () { - return this._objects.length === 0; - }, - - /** - * Returns a size of a collection (i.e: length of an array containing its objects) - * @return {Number} Collection size - */ - size: function() { - return this._objects.length; - }, - - /** - * Returns true if collection contains an object - * @param {Object} object Object to check against - * @param {Boolean} [deep=false] `true` to check all descendants, `false` to check only `_objects` - * @return {Boolean} `true` if collection contains an object - */ - contains: function (object, deep) { - if (this._objects.indexOf(object) > -1) { - return true; - } - else if (deep) { - return this._objects.some(function (obj) { - return typeof obj.contains === 'function' && obj.contains(object, true); - }); - } - return false; - }, - - /** - * Returns number representation of a collection complexity - * @return {Number} complexity - */ - complexity: function () { - return this._objects.reduce(function (memo, current) { - memo += current.complexity ? current.complexity() : 0; - return memo; - }, 0); - } -}; - - -/** - * @namespace fabric.CommonMethods - */ -fabric.CommonMethods = { - - /** - * Sets object's properties from options - * @param {Object} [options] Options object - */ - _setOptions: function(options) { - for (var prop in options) { - this.set(prop, options[prop]); - } - }, - - /** - * @private - * @param {Object} [filler] Options object - * @param {String} [property] property to set the Gradient to - */ - _initGradient: function(filler, property) { - if (filler && filler.colorStops && !(filler instanceof fabric.Gradient)) { - this.set(property, new fabric.Gradient(filler)); - } - }, - - /** - * @private - * @param {Object} [filler] Options object - * @param {String} [property] property to set the Pattern to - * @param {Function} [callback] callback to invoke after pattern load - */ - _initPattern: function(filler, property, callback) { - if (filler && filler.source && !(filler instanceof fabric.Pattern)) { - this.set(property, new fabric.Pattern(filler, callback)); - } - else { - callback && callback(); - } - }, - - /** - * @private - */ - _setObject: function(obj) { - for (var prop in obj) { - this._set(prop, obj[prop]); - } - }, - - /** - * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`. - * @param {String|Object} key Property name or object (if object, iterate over the object properties) - * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one) - * @return {fabric.Object} thisArg - * @chainable - */ - set: function(key, value) { - if (typeof key === 'object') { - this._setObject(key); - } - else { - this._set(key, value); - } - return this; - }, - - _set: function(key, value) { - this[key] = value; - }, - - /** - * Toggles specified property from `true` to `false` or from `false` to `true` - * @param {String} property Property to toggle - * @return {fabric.Object} thisArg - * @chainable - */ - toggle: function(property) { - var value = this.get(property); - if (typeof value === 'boolean') { - this.set(property, !value); - } - return this; - }, - - /** - * Basic getter - * @param {String} property Property name - * @return {*} value of a property - */ - get: function(property) { - return this[property]; - } -}; - - -(function(global) { - - var sqrt = Math.sqrt, - atan2 = Math.atan2, - pow = Math.pow, - PiBy180 = Math.PI / 180, - PiBy2 = Math.PI / 2; - - /** - * @namespace fabric.util - */ - fabric.util = { - - /** - * Calculate the cos of an angle, avoiding returning floats for known results - * @static - * @memberOf fabric.util - * @param {Number} angle the angle in radians or in degree - * @return {Number} - */ - cos: function(angle) { - if (angle === 0) { return 1; } - if (angle < 0) { - // cos(a) = cos(-a) - angle = -angle; - } - var angleSlice = angle / PiBy2; - switch (angleSlice) { - case 1: case 3: return 0; - case 2: return -1; - } - return Math.cos(angle); - }, - - /** - * Calculate the sin of an angle, avoiding returning floats for known results - * @static - * @memberOf fabric.util - * @param {Number} angle the angle in radians or in degree - * @return {Number} - */ - sin: function(angle) { - if (angle === 0) { return 0; } - var angleSlice = angle / PiBy2, sign = 1; - if (angle < 0) { - // sin(-a) = -sin(a) - sign = -1; - } - switch (angleSlice) { - case 1: return sign; - case 2: return 0; - case 3: return -sign; - } - return Math.sin(angle); - }, - - /** - * Removes value from an array. - * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf` - * @static - * @memberOf fabric.util - * @param {Array} array - * @param {*} value - * @return {Array} original array - */ - removeFromArray: function(array, value) { - var idx = array.indexOf(value); - if (idx !== -1) { - array.splice(idx, 1); - } - return array; - }, - - /** - * Returns random number between 2 specified ones. - * @static - * @memberOf fabric.util - * @param {Number} min lower limit - * @param {Number} max upper limit - * @return {Number} random value (between min and max) - */ - getRandomInt: function(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; - }, - - /** - * Transforms degrees to radians. - * @static - * @memberOf fabric.util - * @param {Number} degrees value in degrees - * @return {Number} value in radians - */ - degreesToRadians: function(degrees) { - return degrees * PiBy180; - }, - - /** - * Transforms radians to degrees. - * @static - * @memberOf fabric.util - * @param {Number} radians value in radians - * @return {Number} value in degrees - */ - radiansToDegrees: function(radians) { - return radians / PiBy180; - }, - - /** - * Rotates `point` around `origin` with `radians` - * @static - * @memberOf fabric.util - * @param {fabric.Point} point The point to rotate - * @param {fabric.Point} origin The origin of the rotation - * @param {Number} radians The radians of the angle for the rotation - * @return {fabric.Point} The new rotated point - */ - rotatePoint: function(point, origin, radians) { - var newPoint = new fabric.Point(point.x - origin.x, point.y - origin.y), - v = fabric.util.rotateVector(newPoint, radians); - return new fabric.Point(v.x, v.y).addEquals(origin); - }, - - /** - * Rotates `vector` with `radians` - * @static - * @memberOf fabric.util - * @param {Object} vector The vector to rotate (x and y) - * @param {Number} radians The radians of the angle for the rotation - * @return {Object} The new rotated point - */ - rotateVector: function(vector, radians) { - var sin = fabric.util.sin(radians), - cos = fabric.util.cos(radians), - rx = vector.x * cos - vector.y * sin, - ry = vector.x * sin + vector.y * cos; - return { - x: rx, - y: ry - }; - }, - - /** - * Creates a vetor from points represented as a point - * @static - * @memberOf fabric.util - * - * @typedef {Object} Point - * @property {number} x - * @property {number} y - * - * @param {Point} from - * @param {Point} to - * @returns {Point} vector - */ - createVector: function (from, to) { - return new fabric.Point(to.x - from.x, to.y - from.y); - }, - - /** - * Calculates angle between 2 vectors using dot product - * @static - * @memberOf fabric.util - * @param {Point} a - * @param {Point} b - * @returns the angle in radian between the vectors - */ - calcAngleBetweenVectors: function (a, b) { - return Math.acos((a.x * b.x + a.y * b.y) / (Math.hypot(a.x, a.y) * Math.hypot(b.x, b.y))); - }, - - /** - * @static - * @memberOf fabric.util - * @param {Point} v - * @returns {Point} vector representing the unit vector of pointing to the direction of `v` - */ - getHatVector: function (v) { - return new fabric.Point(v.x, v.y).multiply(1 / Math.hypot(v.x, v.y)); - }, - - /** - * @static - * @memberOf fabric.util - * @param {Point} A - * @param {Point} B - * @param {Point} C - * @returns {{ vector: Point, angle: number }} vector representing the bisector of A and A's angle - */ - getBisector: function (A, B, C) { - var AB = fabric.util.createVector(A, B), AC = fabric.util.createVector(A, C); - var alpha = fabric.util.calcAngleBetweenVectors(AB, AC); - // check if alpha is relative to AB->BC - var ro = fabric.util.calcAngleBetweenVectors(fabric.util.rotateVector(AB, alpha), AC); - var phi = alpha * (ro === 0 ? 1 : -1) / 2; - return { - vector: fabric.util.getHatVector(fabric.util.rotateVector(AB, phi)), - angle: alpha - }; - }, - - /** - * Project stroke width on points returning 2 projections for each point as follows: - * - `miter`: 2 points corresponding to the outer boundary and the inner boundary of stroke. - * - `bevel`: 2 points corresponding to the bevel boundaries, tangent to the bisector. - * - `round`: same as `bevel` - * Used to calculate object's bounding box - * @static - * @memberOf fabric.util - * @param {Point[]} points - * @param {Object} options - * @param {number} options.strokeWidth - * @param {'miter'|'bevel'|'round'} options.strokeLineJoin - * @param {number} options.strokeMiterLimit https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit - * @param {boolean} options.strokeUniform - * @param {number} options.scaleX - * @param {number} options.scaleY - * @param {boolean} [openPath] whether the shape is open or not, affects the calculations of the first and last points - * @returns {fabric.Point[]} array of size 2n/4n of all suspected points - */ - projectStrokeOnPoints: function (points, options, openPath) { - var coords = [], s = options.strokeWidth / 2, - strokeUniformScalar = options.strokeUniform ? - new fabric.Point(1 / options.scaleX, 1 / options.scaleY) : new fabric.Point(1, 1), - getStrokeHatVector = function (v) { - var scalar = s / (Math.hypot(v.x, v.y)); - return new fabric.Point(v.x * scalar * strokeUniformScalar.x, v.y * scalar * strokeUniformScalar.y); - }; - if (points.length <= 1) {return coords;} - points.forEach(function (p, index) { - var A = new fabric.Point(p.x, p.y), B, C; - if (index === 0) { - C = points[index + 1]; - B = openPath ? getStrokeHatVector(fabric.util.createVector(C, A)).addEquals(A) : points[points.length - 1]; - } - else if (index === points.length - 1) { - B = points[index - 1]; - C = openPath ? getStrokeHatVector(fabric.util.createVector(B, A)).addEquals(A) : points[0]; - } - else { - B = points[index - 1]; - C = points[index + 1]; - } - var bisector = fabric.util.getBisector(A, B, C), - bisectorVector = bisector.vector, - alpha = bisector.angle, - scalar, - miterVector; - if (options.strokeLineJoin === 'miter') { - scalar = -s / Math.sin(alpha / 2); - miterVector = new fabric.Point( - bisectorVector.x * scalar * strokeUniformScalar.x, - bisectorVector.y * scalar * strokeUniformScalar.y - ); - if (Math.hypot(miterVector.x, miterVector.y) / s <= options.strokeMiterLimit) { - coords.push(A.add(miterVector)); - coords.push(A.subtract(miterVector)); - return; - } - } - scalar = -s * Math.SQRT2; - miterVector = new fabric.Point( - bisectorVector.x * scalar * strokeUniformScalar.x, - bisectorVector.y * scalar * strokeUniformScalar.y - ); - coords.push(A.add(miterVector)); - coords.push(A.subtract(miterVector)); - }); - return coords; - }, - - /** - * Apply transform t to point p - * @static - * @memberOf fabric.util - * @param {fabric.Point} p The point to transform - * @param {Array} t The transform - * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied - * @return {fabric.Point} The transformed point - */ - transformPoint: function(p, t, ignoreOffset) { - if (ignoreOffset) { - return new fabric.Point( - t[0] * p.x + t[2] * p.y, - t[1] * p.x + t[3] * p.y - ); - } - return new fabric.Point( - t[0] * p.x + t[2] * p.y + t[4], - t[1] * p.x + t[3] * p.y + t[5] - ); - }, - - /** - * Returns coordinates of points's bounding rectangle (left, top, width, height) - * @param {Array} points 4 points array - * @param {Array} [transform] an array of 6 numbers representing a 2x3 transform matrix - * @return {Object} Object with left, top, width, height properties - */ - makeBoundingBoxFromPoints: function(points, transform) { - if (transform) { - for (var i = 0; i < points.length; i++) { - points[i] = fabric.util.transformPoint(points[i], transform); - } - } - var xPoints = [points[0].x, points[1].x, points[2].x, points[3].x], - minX = fabric.util.array.min(xPoints), - maxX = fabric.util.array.max(xPoints), - width = maxX - minX, - yPoints = [points[0].y, points[1].y, points[2].y, points[3].y], - minY = fabric.util.array.min(yPoints), - maxY = fabric.util.array.max(yPoints), - height = maxY - minY; - - return { - left: minX, - top: minY, - width: width, - height: height - }; - }, - - /** - * Invert transformation t - * @static - * @memberOf fabric.util - * @param {Array} t The transform - * @return {Array} The inverted transform - */ - invertTransform: function(t) { - var a = 1 / (t[0] * t[3] - t[1] * t[2]), - r = [a * t[3], -a * t[1], -a * t[2], a * t[0]], - o = fabric.util.transformPoint({ x: t[4], y: t[5] }, r, true); - r[4] = -o.x; - r[5] = -o.y; - return r; - }, - - /** - * A wrapper around Number#toFixed, which contrary to native method returns number, not string. - * @static - * @memberOf fabric.util - * @param {Number|String} number number to operate on - * @param {Number} fractionDigits number of fraction digits to "leave" - * @return {Number} - */ - toFixed: function(number, fractionDigits) { - return parseFloat(Number(number).toFixed(fractionDigits)); - }, - - /** - * Converts from attribute value to pixel value if applicable. - * Returns converted pixels or original value not converted. - * @param {Number|String} value number to operate on - * @param {Number} fontSize - * @return {Number|String} - */ - parseUnit: function(value, fontSize) { - var unit = /\D{0,2}$/.exec(value), - number = parseFloat(value); - if (!fontSize) { - fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE; - } - switch (unit[0]) { - case 'mm': - return number * fabric.DPI / 25.4; - - case 'cm': - return number * fabric.DPI / 2.54; - - case 'in': - return number * fabric.DPI; - - case 'pt': - return number * fabric.DPI / 72; // or * 4 / 3 - - case 'pc': - return number * fabric.DPI / 72 * 12; // or * 16 - - case 'em': - return number * fontSize; - - default: - return number; - } - }, - - /** - * Function which always returns `false`. - * @static - * @memberOf fabric.util - * @return {Boolean} - */ - falseFunction: function() { - return false; - }, - - /** - * Returns klass "Class" object of given namespace - * @memberOf fabric.util - * @param {String} type Type of object (eg. 'circle') - * @param {String} namespace Namespace to get klass "Class" object from - * @return {Object} klass "Class" - */ - getKlass: function(type, namespace) { - // capitalize first letter only - type = fabric.util.string.camelize(type.charAt(0).toUpperCase() + type.slice(1)); - return fabric.util.resolveNamespace(namespace)[type]; - }, - - /** - * Returns array of attributes for given svg that fabric parses - * @memberOf fabric.util - * @param {String} type Type of svg element (eg. 'circle') - * @return {Array} string names of supported attributes - */ - getSvgAttributes: function(type) { - var attributes = [ - 'instantiated_by_use', - 'style', - 'id', - 'class' - ]; - switch (type) { - case 'linearGradient': - attributes = attributes.concat(['x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform']); - break; - case 'radialGradient': - attributes = attributes.concat(['gradientUnits', 'gradientTransform', 'cx', 'cy', 'r', 'fx', 'fy', 'fr']); - break; - case 'stop': - attributes = attributes.concat(['offset', 'stop-color', 'stop-opacity']); - break; - } - return attributes; - }, - - /** - * Returns object of given namespace - * @memberOf fabric.util - * @param {String} namespace Namespace string e.g. 'fabric.Image.filter' or 'fabric' - * @return {Object} Object for given namespace (default fabric) - */ - resolveNamespace: function(namespace) { - if (!namespace) { - return fabric; - } - - var parts = namespace.split('.'), - len = parts.length, i, - obj = global || fabric.window; - - for (i = 0; i < len; ++i) { - obj = obj[parts[i]]; - } - - return obj; - }, - - /** - * Loads image element from given url and passes it to a callback - * @memberOf fabric.util - * @param {String} url URL representing an image - * @param {Function} callback Callback; invoked with loaded image - * @param {*} [context] Context to invoke callback in - * @param {Object} [crossOrigin] crossOrigin value to set image element to - */ - loadImage: function(url, callback, context, crossOrigin) { - if (!url) { - callback && callback.call(context, url); - return; - } - - var img = fabric.util.createImage(); - - /** @ignore */ - var onLoadCallback = function () { - callback && callback.call(context, img, false); - img = img.onload = img.onerror = null; - }; - - img.onload = onLoadCallback; - /** @ignore */ - img.onerror = function() { - fabric.log('Error loading ' + img.src); - callback && callback.call(context, null, true); - img = img.onload = img.onerror = null; - }; - - // data-urls appear to be buggy with crossOrigin - // https://github.com/kangax/fabric.js/commit/d0abb90f1cd5c5ef9d2a94d3fb21a22330da3e0a#commitcomment-4513767 - // see https://code.google.com/p/chromium/issues/detail?id=315152 - // https://bugzilla.mozilla.org/show_bug.cgi?id=935069 - // crossOrigin null is the same as not set. - if (url.indexOf('data') !== 0 && - crossOrigin !== undefined && - crossOrigin !== null) { - img.crossOrigin = crossOrigin; - } - - // IE10 / IE11-Fix: SVG contents from data: URI - // will only be available if the IMG is present - // in the DOM (and visible) - if (url.substring(0,14) === 'data:image/svg') { - img.onload = null; - fabric.util.loadImageInDom(img, onLoadCallback); - } - - img.src = url; - }, - - /** - * Attaches SVG image with data: URL to the dom - * @memberOf fabric.util - * @param {Object} img Image object with data:image/svg src - * @param {Function} callback Callback; invoked with loaded image - * @return {Object} DOM element (div containing the SVG image) - */ - loadImageInDom: function(img, onLoadCallback) { - var div = fabric.document.createElement('div'); - div.style.width = div.style.height = '1px'; - div.style.left = div.style.top = '-100%'; - div.style.position = 'absolute'; - div.appendChild(img); - fabric.document.querySelector('body').appendChild(div); - /** - * Wrap in function to: - * 1. Call existing callback - * 2. Cleanup DOM - */ - img.onload = function () { - onLoadCallback(); - div.parentNode.removeChild(div); - div = null; - }; - }, - - /** - * Creates corresponding fabric instances from their object representations - * @static - * @memberOf fabric.util - * @param {Array} objects Objects to enliven - * @param {Function} callback Callback to invoke when all objects are created - * @param {String} namespace Namespace to get klass "Class" object from - * @param {Function} reviver Method for further parsing of object elements, - * called after each fabric object created. - */ - enlivenObjects: function(objects, callback, namespace, reviver) { - objects = objects || []; - - var enlivenedObjects = [], - numLoadedObjects = 0, - numTotalObjects = objects.length; - - function onLoaded() { - if (++numLoadedObjects === numTotalObjects) { - callback && callback(enlivenedObjects.filter(function(obj) { - // filter out undefined objects (objects that gave error) - return obj; - })); - } - } - - if (!numTotalObjects) { - callback && callback(enlivenedObjects); - return; - } - - objects.forEach(function (o, index) { - // if sparse array - if (!o || !o.type) { - onLoaded(); - return; - } - var klass = fabric.util.getKlass(o.type, namespace); - klass.fromObject(o, function (obj, error) { - error || (enlivenedObjects[index] = obj); - reviver && reviver(o, obj, error); - onLoaded(); - }); - }); - }, - - /** - * Creates corresponding fabric instances residing in an object, e.g. `clipPath` - * @see {@link fabric.Object.ENLIVEN_PROPS} - * @param {Object} object - * @param {Object} [context] assign enlived props to this object (pass null to skip this) - * @param {(objects:fabric.Object[]) => void} callback - */ - enlivenObjectEnlivables: function (object, context, callback) { - var enlivenProps = fabric.Object.ENLIVEN_PROPS.filter(function (key) { return !!object[key]; }); - fabric.util.enlivenObjects(enlivenProps.map(function (key) { return object[key]; }), function (enlivedProps) { - var objects = {}; - enlivenProps.forEach(function (key, index) { - objects[key] = enlivedProps[index]; - context && (context[key] = enlivedProps[index]); - }); - callback && callback(objects); - }); - }, - - /** - * Create and wait for loading of patterns - * @static - * @memberOf fabric.util - * @param {Array} patterns Objects to enliven - * @param {Function} callback Callback to invoke when all objects are created - * called after each fabric object created. - */ - enlivenPatterns: function(patterns, callback) { - patterns = patterns || []; - - function onLoaded() { - if (++numLoadedPatterns === numPatterns) { - callback && callback(enlivenedPatterns); - } - } - - var enlivenedPatterns = [], - numLoadedPatterns = 0, - numPatterns = patterns.length; - - if (!numPatterns) { - callback && callback(enlivenedPatterns); - return; - } - - patterns.forEach(function (p, index) { - if (p && p.source) { - new fabric.Pattern(p, function(pattern) { - enlivenedPatterns[index] = pattern; - onLoaded(); - }); - } - else { - enlivenedPatterns[index] = p; - onLoaded(); - } - }); - }, - - /** - * Groups SVG elements (usually those retrieved from SVG document) - * @static - * @memberOf fabric.util - * @param {Array} elements SVG elements to group - * @param {Object} [options] Options object - * @param {String} path Value to set sourcePath to - * @return {fabric.Object|fabric.Group} - */ - groupSVGElements: function(elements, options, path) { - var object; - if (elements && elements.length === 1) { - return elements[0]; - } - if (options) { - if (options.width && options.height) { - options.centerPoint = { - x: options.width / 2, - y: options.height / 2 - }; - } - else { - delete options.width; - delete options.height; - } - } - object = new fabric.Group(elements, options); - if (typeof path !== 'undefined') { - object.sourcePath = path; - } - return object; - }, - - /** - * Populates an object with properties of another object - * @static - * @memberOf fabric.util - * @param {Object} source Source object - * @param {Object} destination Destination object - * @return {Array} properties Properties names to include - */ - populateWithProperties: function(source, destination, properties) { - if (properties && Array.isArray(properties)) { - for (var i = 0, len = properties.length; i < len; i++) { - if (properties[i] in source) { - destination[properties[i]] = source[properties[i]]; - } - } - } - }, - - /** - * Creates canvas element - * @static - * @memberOf fabric.util - * @return {CanvasElement} initialized canvas element - */ - createCanvasElement: function() { - return fabric.document.createElement('canvas'); - }, - - /** - * Creates a canvas element that is a copy of another and is also painted - * @param {CanvasElement} canvas to copy size and content of - * @static - * @memberOf fabric.util - * @return {CanvasElement} initialized canvas element - */ - copyCanvasElement: function(canvas) { - var newCanvas = fabric.util.createCanvasElement(); - newCanvas.width = canvas.width; - newCanvas.height = canvas.height; - newCanvas.getContext('2d').drawImage(canvas, 0, 0); - return newCanvas; - }, - - /** - * since 2.6.0 moved from canvas instance to utility. - * @param {CanvasElement} canvasEl to copy size and content of - * @param {String} format 'jpeg' or 'png', in some browsers 'webp' is ok too - * @param {Number} quality <= 1 and > 0 - * @static - * @memberOf fabric.util - * @return {String} data url - */ - toDataURL: function(canvasEl, format, quality) { - return canvasEl.toDataURL('image/' + format, quality); - }, - - /** - * Creates image element (works on client and node) - * @static - * @memberOf fabric.util - * @return {HTMLImageElement} HTML image element - */ - createImage: function() { - return fabric.document.createElement('img'); - }, - - /** - * Multiply matrix A by matrix B to nest transformations - * @static - * @memberOf fabric.util - * @param {Array} a First transformMatrix - * @param {Array} b Second transformMatrix - * @param {Boolean} is2x2 flag to multiply matrices as 2x2 matrices - * @return {Array} The product of the two transform matrices - */ - multiplyTransformMatrices: function(a, b, is2x2) { - // Matrix multiply a * b - return [ - a[0] * b[0] + a[2] * b[1], - a[1] * b[0] + a[3] * b[1], - a[0] * b[2] + a[2] * b[3], - a[1] * b[2] + a[3] * b[3], - is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4], - is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5] - ]; - }, - - /** - * Decomposes standard 2x3 matrix into transform components - * @static - * @memberOf fabric.util - * @param {Array} a transformMatrix - * @return {Object} Components of transform - */ - qrDecompose: function(a) { - var angle = atan2(a[1], a[0]), - denom = pow(a[0], 2) + pow(a[1], 2), - scaleX = sqrt(denom), - scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX, - skewX = atan2(a[0] * a[2] + a[1] * a [3], denom); - return { - angle: angle / PiBy180, - scaleX: scaleX, - scaleY: scaleY, - skewX: skewX / PiBy180, - skewY: 0, - translateX: a[4], - translateY: a[5] - }; - }, - - /** - * Returns a transform matrix starting from an object of the same kind of - * the one returned from qrDecompose, useful also if you want to calculate some - * transformations from an object that is not enlived yet - * @static - * @memberOf fabric.util - * @param {Object} options - * @param {Number} [options.angle] angle in degrees - * @return {Number[]} transform matrix - */ - calcRotateMatrix: function(options) { - if (!options.angle) { - return fabric.iMatrix.concat(); - } - var theta = fabric.util.degreesToRadians(options.angle), - cos = fabric.util.cos(theta), - sin = fabric.util.sin(theta); - return [cos, sin, -sin, cos, 0, 0]; - }, - - /** - * Returns a transform matrix starting from an object of the same kind of - * the one returned from qrDecompose, useful also if you want to calculate some - * transformations from an object that is not enlived yet. - * is called DimensionsTransformMatrix because those properties are the one that influence - * the size of the resulting box of the object. - * @static - * @memberOf fabric.util - * @param {Object} options - * @param {Number} [options.scaleX] - * @param {Number} [options.scaleY] - * @param {Boolean} [options.flipX] - * @param {Boolean} [options.flipY] - * @param {Number} [options.skewX] - * @param {Number} [options.skewY] - * @return {Number[]} transform matrix - */ - calcDimensionsMatrix: function(options) { - var scaleX = typeof options.scaleX === 'undefined' ? 1 : options.scaleX, - scaleY = typeof options.scaleY === 'undefined' ? 1 : options.scaleY, - scaleMatrix = [ - options.flipX ? -scaleX : scaleX, - 0, - 0, - options.flipY ? -scaleY : scaleY, - 0, - 0], - multiply = fabric.util.multiplyTransformMatrices, - degreesToRadians = fabric.util.degreesToRadians; - if (options.skewX) { - scaleMatrix = multiply( - scaleMatrix, - [1, 0, Math.tan(degreesToRadians(options.skewX)), 1], - true); - } - if (options.skewY) { - scaleMatrix = multiply( - scaleMatrix, - [1, Math.tan(degreesToRadians(options.skewY)), 0, 1], - true); - } - return scaleMatrix; - }, - - /** - * Returns a transform matrix starting from an object of the same kind of - * the one returned from qrDecompose, useful also if you want to calculate some - * transformations from an object that is not enlived yet - * @static - * @memberOf fabric.util - * @param {Object} options - * @param {Number} [options.angle] - * @param {Number} [options.scaleX] - * @param {Number} [options.scaleY] - * @param {Boolean} [options.flipX] - * @param {Boolean} [options.flipY] - * @param {Number} [options.skewX] - * @param {Number} [options.skewX] - * @param {Number} [options.translateX] - * @param {Number} [options.translateY] - * @return {Number[]} transform matrix - */ - composeMatrix: function(options) { - var matrix = [1, 0, 0, 1, options.translateX || 0, options.translateY || 0], - multiply = fabric.util.multiplyTransformMatrices; - if (options.angle) { - matrix = multiply(matrix, fabric.util.calcRotateMatrix(options)); - } - if (options.scaleX !== 1 || options.scaleY !== 1 || - options.skewX || options.skewY || options.flipX || options.flipY) { - matrix = multiply(matrix, fabric.util.calcDimensionsMatrix(options)); - } - return matrix; - }, - - /** - * reset an object transform state to neutral. Top and left are not accounted for - * @static - * @memberOf fabric.util - * @param {fabric.Object} target object to transform - */ - resetObjectTransform: function (target) { - target.scaleX = 1; - target.scaleY = 1; - target.skewX = 0; - target.skewY = 0; - target.flipX = false; - target.flipY = false; - target.rotate(0); - }, - - /** - * Extract Object transform values - * @static - * @memberOf fabric.util - * @param {fabric.Object} target object to read from - * @return {Object} Components of transform - */ - saveObjectTransform: function (target) { - return { - scaleX: target.scaleX, - scaleY: target.scaleY, - skewX: target.skewX, - skewY: target.skewY, - angle: target.angle, - left: target.left, - flipX: target.flipX, - flipY: target.flipY, - top: target.top - }; - }, - - /** - * Returns true if context has transparent pixel - * at specified location (taking tolerance into account) - * @param {CanvasRenderingContext2D} ctx context - * @param {Number} x x coordinate - * @param {Number} y y coordinate - * @param {Number} tolerance Tolerance - */ - isTransparent: function(ctx, x, y, tolerance) { - - // If tolerance is > 0 adjust start coords to take into account. - // If moves off Canvas fix to 0 - if (tolerance > 0) { - if (x > tolerance) { - x -= tolerance; - } - else { - x = 0; - } - if (y > tolerance) { - y -= tolerance; - } - else { - y = 0; - } - } - - var _isTransparent = true, i, temp, - imageData = ctx.getImageData(x, y, (tolerance * 2) || 1, (tolerance * 2) || 1), - l = imageData.data.length; - - // Split image data - for tolerance > 1, pixelDataSize = 4; - for (i = 3; i < l; i += 4) { - temp = imageData.data[i]; - _isTransparent = temp <= 0; - if (_isTransparent === false) { - break; // Stop if colour found - } - } - - imageData = null; - - return _isTransparent; - }, - - /** - * Parse preserveAspectRatio attribute from element - * @param {string} attribute to be parsed - * @return {Object} an object containing align and meetOrSlice attribute - */ - parsePreserveAspectRatioAttribute: function(attribute) { - var meetOrSlice = 'meet', alignX = 'Mid', alignY = 'Mid', - aspectRatioAttrs = attribute.split(' '), align; - - if (aspectRatioAttrs && aspectRatioAttrs.length) { - meetOrSlice = aspectRatioAttrs.pop(); - if (meetOrSlice !== 'meet' && meetOrSlice !== 'slice') { - align = meetOrSlice; - meetOrSlice = 'meet'; - } - else if (aspectRatioAttrs.length) { - align = aspectRatioAttrs.pop(); - } - } - //divide align in alignX and alignY - alignX = align !== 'none' ? align.slice(1, 4) : 'none'; - alignY = align !== 'none' ? align.slice(5, 8) : 'none'; - return { - meetOrSlice: meetOrSlice, - alignX: alignX, - alignY: alignY - }; - }, - - /** - * Clear char widths cache for the given font family or all the cache if no - * fontFamily is specified. - * Use it if you know you are loading fonts in a lazy way and you are not waiting - * for custom fonts to load properly when adding text objects to the canvas. - * If a text object is added when its own font is not loaded yet, you will get wrong - * measurement and so wrong bounding boxes. - * After the font cache is cleared, either change the textObject text content or call - * initDimensions() to trigger a recalculation - * @memberOf fabric.util - * @param {String} [fontFamily] font family to clear - */ - clearFabricFontCache: function(fontFamily) { - fontFamily = (fontFamily || '').toLowerCase(); - if (!fontFamily) { - fabric.charWidthsCache = { }; - } - else if (fabric.charWidthsCache[fontFamily]) { - delete fabric.charWidthsCache[fontFamily]; - } - }, - - /** - * Given current aspect ratio, determines the max width and height that can - * respect the total allowed area for the cache. - * @memberOf fabric.util - * @param {Number} ar aspect ratio - * @param {Number} maximumArea Maximum area you want to achieve - * @return {Object.x} Limited dimensions by X - * @return {Object.y} Limited dimensions by Y - */ - limitDimsByArea: function(ar, maximumArea) { - var roughWidth = Math.sqrt(maximumArea * ar), - perfLimitSizeY = Math.floor(maximumArea / roughWidth); - return { x: Math.floor(roughWidth), y: perfLimitSizeY }; - }, - - capValue: function(min, value, max) { - return Math.max(min, Math.min(value, max)); - }, - - /** - * Finds the scale for the object source to fit inside the object destination, - * keeping aspect ratio intact. - * respect the total allowed area for the cache. - * @memberOf fabric.util - * @param {Object | fabric.Object} source - * @param {Number} source.height natural unscaled height of the object - * @param {Number} source.width natural unscaled width of the object - * @param {Object | fabric.Object} destination - * @param {Number} destination.height natural unscaled height of the object - * @param {Number} destination.width natural unscaled width of the object - * @return {Number} scale factor to apply to source to fit into destination - */ - findScaleToFit: function(source, destination) { - return Math.min(destination.width / source.width, destination.height / source.height); - }, - - /** - * Finds the scale for the object source to cover entirely the object destination, - * keeping aspect ratio intact. - * respect the total allowed area for the cache. - * @memberOf fabric.util - * @param {Object | fabric.Object} source - * @param {Number} source.height natural unscaled height of the object - * @param {Number} source.width natural unscaled width of the object - * @param {Object | fabric.Object} destination - * @param {Number} destination.height natural unscaled height of the object - * @param {Number} destination.width natural unscaled width of the object - * @return {Number} scale factor to apply to source to cover destination - */ - findScaleToCover: function(source, destination) { - return Math.max(destination.width / source.width, destination.height / source.height); - }, - - /** - * given an array of 6 number returns something like `"matrix(...numbers)"` - * @memberOf fabric.util - * @param {Array} transform an array with 6 numbers - * @return {String} transform matrix for svg - * @return {Object.y} Limited dimensions by Y - */ - matrixToSVG: function(transform) { - return 'matrix(' + transform.map(function(value) { - return fabric.util.toFixed(value, fabric.Object.NUM_FRACTION_DIGITS); - }).join(' ') + ')'; - }, - - /** - * given an object and a transform, apply the inverse transform to the object, - * this is equivalent to remove from that object that transformation, so that - * added in a space with the removed transform, the object will be the same as before. - * Removing from an object a transform that scale by 2 is like scaling it by 1/2. - * Removing from an object a transfrom that rotate by 30deg is like rotating by 30deg - * in the opposite direction. - * This util is used to add objects inside transformed groups or nested groups. - * @memberOf fabric.util - * @param {fabric.Object} object the object you want to transform - * @param {Array} transform the destination transform - */ - removeTransformFromObject: function(object, transform) { - var inverted = fabric.util.invertTransform(transform), - finalTransform = fabric.util.multiplyTransformMatrices(inverted, object.calcOwnMatrix()); - fabric.util.applyTransformToObject(object, finalTransform); - }, - - /** - * given an object and a transform, apply the transform to the object. - * this is equivalent to change the space where the object is drawn. - * Adding to an object a transform that scale by 2 is like scaling it by 2. - * This is used when removing an object from an active selection for example. - * @memberOf fabric.util - * @param {fabric.Object} object the object you want to transform - * @param {Array} transform the destination transform - */ - addTransformToObject: function(object, transform) { - fabric.util.applyTransformToObject( - object, - fabric.util.multiplyTransformMatrices(transform, object.calcOwnMatrix()) - ); - }, - - /** - * discard an object transform state and apply the one from the matrix. - * @memberOf fabric.util - * @param {fabric.Object} object the object you want to transform - * @param {Array} transform the destination transform - */ - applyTransformToObject: function(object, transform) { - var options = fabric.util.qrDecompose(transform), - center = new fabric.Point(options.translateX, options.translateY); - object.flipX = false; - object.flipY = false; - object.set('scaleX', options.scaleX); - object.set('scaleY', options.scaleY); - object.skewX = options.skewX; - object.skewY = options.skewY; - object.angle = options.angle; - object.setPositionByOrigin(center, 'center', 'center'); - }, - - /** - * given a width and height, return the size of the bounding box - * that can contains the box with width/height with applied transform - * described in options. - * Use to calculate the boxes around objects for controls. - * @memberOf fabric.util - * @param {Number} width - * @param {Number} height - * @param {Object} options - * @param {Number} options.scaleX - * @param {Number} options.scaleY - * @param {Number} options.skewX - * @param {Number} options.skewY - * @return {Object.x} width of containing - * @return {Object.y} height of containing - */ - sizeAfterTransform: function(width, height, options) { - var dimX = width / 2, dimY = height / 2, - points = [ - { - x: -dimX, - y: -dimY - }, - { - x: dimX, - y: -dimY - }, - { - x: -dimX, - y: dimY - }, - { - x: dimX, - y: dimY - }], - transformMatrix = fabric.util.calcDimensionsMatrix(options), - bbox = fabric.util.makeBoundingBoxFromPoints(points, transformMatrix); - return { - x: bbox.width, - y: bbox.height, - }; - }, - - /** - * Merges 2 clip paths into one visually equal clip path - * - * **IMPORTANT**:\ - * Does **NOT** clone the arguments, clone them proir if necessary. - * - * Creates a wrapper (group) that contains one clip path and is clipped by the other so content is kept where both overlap. - * Use this method if both the clip paths may have nested clip paths of their own, so assigning one to the other's clip path property is not possible. - * - * In order to handle the `inverted` property we follow logic described in the following cases:\ - * **(1)** both clip paths are inverted - the clip paths pass the inverted prop to the wrapper and loose it themselves.\ - * **(2)** one is inverted and the other isn't - the wrapper shouldn't become inverted and the inverted clip path must clip the non inverted one to produce an identical visual effect.\ - * **(3)** both clip paths are not inverted - wrapper and clip paths remain unchanged. - * - * @memberOf fabric.util - * @param {fabric.Object} c1 - * @param {fabric.Object} c2 - * @returns {fabric.Object} merged clip path - */ - mergeClipPaths: function (c1, c2) { - var a = c1, b = c2; - if (a.inverted && !b.inverted) { - // case (2) - a = c2; - b = c1; - } - // `b` becomes `a`'s clip path so we transform `b` to `a` coordinate plane - fabric.util.applyTransformToObject( - b, - fabric.util.multiplyTransformMatrices( - fabric.util.invertTransform(a.calcTransformMatrix()), - b.calcTransformMatrix() - ) - ); - // assign the `inverted` prop to the wrapping group - var inverted = a.inverted && b.inverted; - if (inverted) { - // case (1) - a.inverted = b.inverted = false; - } - return new fabric.Group([a], { clipPath: b, inverted: inverted }); - }, - }; -})(typeof exports !== 'undefined' ? exports : this); - - -(function() { - var _join = Array.prototype.join, - commandLengths = { - m: 2, - l: 2, - h: 1, - v: 1, - c: 6, - s: 4, - q: 4, - t: 2, - a: 7 - }, - repeatedCommands = { - m: 'l', - M: 'L' - }; - function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) { - var costh2 = fabric.util.cos(th2), - sinth2 = fabric.util.sin(th2), - costh3 = fabric.util.cos(th3), - sinth3 = fabric.util.sin(th3), - toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1, - toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1, - cp1X = fromX + mT * ( -cosTh * rx * sinth2 - sinTh * ry * costh2), - cp1Y = fromY + mT * ( -sinTh * rx * sinth2 + cosTh * ry * costh2), - cp2X = toX + mT * ( cosTh * rx * sinth3 + sinTh * ry * costh3), - cp2Y = toY + mT * ( sinTh * rx * sinth3 - cosTh * ry * costh3); - - return ['C', - cp1X, cp1Y, - cp2X, cp2Y, - toX, toY - ]; - } - - /* Adapted from http://dxr.mozilla.org/mozilla-central/source/content/svg/content/src/nsSVGPathDataParser.cpp - * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here - * http://mozilla.org/MPL/2.0/ - */ - function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) { - var PI = Math.PI, th = rotateX * PI / 180, - sinTh = fabric.util.sin(th), - cosTh = fabric.util.cos(th), - fromX = 0, fromY = 0; - - rx = Math.abs(rx); - ry = Math.abs(ry); - - var px = -cosTh * toX * 0.5 - sinTh * toY * 0.5, - py = -cosTh * toY * 0.5 + sinTh * toX * 0.5, - rx2 = rx * rx, ry2 = ry * ry, py2 = py * py, px2 = px * px, - pl = rx2 * ry2 - rx2 * py2 - ry2 * px2, - root = 0; - - if (pl < 0) { - var s = Math.sqrt(1 - pl / (rx2 * ry2)); - rx *= s; - ry *= s; - } - else { - root = (large === sweep ? -1.0 : 1.0) * - Math.sqrt( pl / (rx2 * py2 + ry2 * px2)); - } - - var cx = root * rx * py / ry, - cy = -root * ry * px / rx, - cx1 = cosTh * cx - sinTh * cy + toX * 0.5, - cy1 = sinTh * cx + cosTh * cy + toY * 0.5, - mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry), - dtheta = calcVectorAngle((px - cx) / rx, (py - cy) / ry, (-px - cx) / rx, (-py - cy) / ry); - - if (sweep === 0 && dtheta > 0) { - dtheta -= 2 * PI; - } - else if (sweep === 1 && dtheta < 0) { - dtheta += 2 * PI; - } - - // Convert into cubic bezier segments <= 90deg - var segments = Math.ceil(Math.abs(dtheta / PI * 2)), - result = [], mDelta = dtheta / segments, - mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2), - th3 = mTheta + mDelta; - - for (var i = 0; i < segments; i++) { - result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY); - fromX = result[i][5]; - fromY = result[i][6]; - mTheta = th3; - th3 += mDelta; - } - return result; - } - - /* - * Private - */ - function calcVectorAngle(ux, uy, vx, vy) { - var ta = Math.atan2(uy, ux), - tb = Math.atan2(vy, vx); - if (tb >= ta) { - return tb - ta; - } - else { - return 2 * Math.PI - (ta - tb); - } - } - - /** - * Calculate bounding box of a beziercurve - * @param {Number} x0 starting point - * @param {Number} y0 - * @param {Number} x1 first control point - * @param {Number} y1 - * @param {Number} x2 secondo control point - * @param {Number} y2 - * @param {Number} x3 end of bezier - * @param {Number} y3 - */ - // taken from http://jsbin.com/ivomiq/56/edit no credits available for that. - // TODO: can we normalize this with the starting points set at 0 and then translated the bbox? - function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) { - var argsString; - if (fabric.cachesBoundsOfCurve) { - argsString = _join.call(arguments); - if (fabric.boundsOfCurveCache[argsString]) { - return fabric.boundsOfCurveCache[argsString]; - } - } - - var sqrt = Math.sqrt, - min = Math.min, max = Math.max, - abs = Math.abs, tvalues = [], - bounds = [[], []], - a, b, c, t, t1, t2, b2ac, sqrtb2ac; - - b = 6 * x0 - 12 * x1 + 6 * x2; - a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3; - c = 3 * x1 - 3 * x0; - - for (var i = 0; i < 2; ++i) { - if (i > 0) { - b = 6 * y0 - 12 * y1 + 6 * y2; - a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3; - c = 3 * y1 - 3 * y0; - } - - if (abs(a) < 1e-12) { - if (abs(b) < 1e-12) { - continue; - } - t = -c / b; - if (0 < t && t < 1) { - tvalues.push(t); - } - continue; - } - b2ac = b * b - 4 * c * a; - if (b2ac < 0) { - continue; - } - sqrtb2ac = sqrt(b2ac); - t1 = (-b + sqrtb2ac) / (2 * a); - if (0 < t1 && t1 < 1) { - tvalues.push(t1); - } - t2 = (-b - sqrtb2ac) / (2 * a); - if (0 < t2 && t2 < 1) { - tvalues.push(t2); - } - } - - var x, y, j = tvalues.length, jlen = j, mt; - while (j--) { - t = tvalues[j]; - mt = 1 - t; - x = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3); - bounds[0][j] = x; - - y = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3); - bounds[1][j] = y; - } - - bounds[0][jlen] = x0; - bounds[1][jlen] = y0; - bounds[0][jlen + 1] = x3; - bounds[1][jlen + 1] = y3; - var result = [ - { - x: min.apply(null, bounds[0]), - y: min.apply(null, bounds[1]) - }, - { - x: max.apply(null, bounds[0]), - y: max.apply(null, bounds[1]) - } - ]; - if (fabric.cachesBoundsOfCurve) { - fabric.boundsOfCurveCache[argsString] = result; - } - return result; - } - - /** - * Converts arc to a bunch of bezier curves - * @param {Number} fx starting point x - * @param {Number} fy starting point y - * @param {Array} coords Arc command - */ - function fromArcToBeziers(fx, fy, coords) { - var rx = coords[1], - ry = coords[2], - rot = coords[3], - large = coords[4], - sweep = coords[5], - tx = coords[6], - ty = coords[7], - segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot); - - for (var i = 0, len = segsNorm.length; i < len; i++) { - segsNorm[i][1] += fx; - segsNorm[i][2] += fy; - segsNorm[i][3] += fx; - segsNorm[i][4] += fy; - segsNorm[i][5] += fx; - segsNorm[i][6] += fy; - } - return segsNorm; - }; - - /** - * This function take a parsed SVG path and make it simpler for fabricJS logic. - * simplification consist of: only UPPERCASE absolute commands ( relative converted to absolute ) - * S converted in C, T converted in Q, A converted in C. - * @param {Array} path the array of commands of a parsed svg path for fabric.Path - * @return {Array} the simplified array of commands of a parsed svg path for fabric.Path - */ - function makePathSimpler(path) { - // x and y represent the last point of the path. the previous command point. - // we add them to each relative command to make it an absolute comment. - // we also swap the v V h H with L, because are easier to transform. - var x = 0, y = 0, len = path.length, - // x1 and y1 represent the last point of the subpath. the subpath is started with - // m or M command. When a z or Z command is drawn, x and y need to be resetted to - // the last x1 and y1. - x1 = 0, y1 = 0, current, i, converted, - // previous will host the letter of the previous command, to handle S and T. - // controlX and controlY will host the previous reflected control point - destinationPath = [], previous, controlX, controlY; - for (i = 0; i < len; ++i) { - converted = false; - current = path[i].slice(0); - switch (current[0]) { // first letter - case 'l': // lineto, relative - current[0] = 'L'; - current[1] += x; - current[2] += y; - // falls through - case 'L': - x = current[1]; - y = current[2]; - break; - case 'h': // horizontal lineto, relative - current[1] += x; - // falls through - case 'H': - current[0] = 'L'; - current[2] = y; - x = current[1]; - break; - case 'v': // vertical lineto, relative - current[1] += y; - // falls through - case 'V': - current[0] = 'L'; - y = current[1]; - current[1] = x; - current[2] = y; - break; - case 'm': // moveTo, relative - current[0] = 'M'; - current[1] += x; - current[2] += y; - // falls through - case 'M': - x = current[1]; - y = current[2]; - x1 = current[1]; - y1 = current[2]; - break; - case 'c': // bezierCurveTo, relative - current[0] = 'C'; - current[1] += x; - current[2] += y; - current[3] += x; - current[4] += y; - current[5] += x; - current[6] += y; - // falls through - case 'C': - controlX = current[3]; - controlY = current[4]; - x = current[5]; - y = current[6]; - break; - case 's': // shorthand cubic bezierCurveTo, relative - current[0] = 'S'; - current[1] += x; - current[2] += y; - current[3] += x; - current[4] += y; - // falls through - case 'S': - // would be sScC but since we are swapping sSc for C, we check just that. - if (previous === 'C') { - // calculate reflection of previous control points - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - else { - // If there is no previous command or if the previous command was not a C, c, S, or s, - // the control point is coincident with the current point - controlX = x; - controlY = y; - } - x = current[3]; - y = current[4]; - current[0] = 'C'; - current[5] = current[3]; - current[6] = current[4]; - current[3] = current[1]; - current[4] = current[2]; - current[1] = controlX; - current[2] = controlY; - // current[3] and current[4] are NOW the second control point. - // we keep it for the next reflection. - controlX = current[3]; - controlY = current[4]; - break; - case 'q': // quadraticCurveTo, relative - current[0] = 'Q'; - current[1] += x; - current[2] += y; - current[3] += x; - current[4] += y; - // falls through - case 'Q': - controlX = current[1]; - controlY = current[2]; - x = current[3]; - y = current[4]; - break; - case 't': // shorthand quadraticCurveTo, relative - current[0] = 'T'; - current[1] += x; - current[2] += y; - // falls through - case 'T': - if (previous === 'Q') { - // calculate reflection of previous control point - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - else { - // If there is no previous command or if the previous command was not a Q, q, T or t, - // assume the control point is coincident with the current point - controlX = x; - controlY = y; - } - current[0] = 'Q'; - x = current[1]; - y = current[2]; - current[1] = controlX; - current[2] = controlY; - current[3] = x; - current[4] = y; - break; - case 'a': - current[0] = 'A'; - current[6] += x; - current[7] += y; - // falls through - case 'A': - converted = true; - destinationPath = destinationPath.concat(fromArcToBeziers(x, y, current)); - x = current[6]; - y = current[7]; - break; - case 'z': - case 'Z': - x = x1; - y = y1; - break; - default: - } - if (!converted) { - destinationPath.push(current); - } - previous = current[0]; - } - return destinationPath; - }; - - /** - * Calc length from point x1,y1 to x2,y2 - * @param {Number} x1 starting point x - * @param {Number} y1 starting point y - * @param {Number} x2 starting point x - * @param {Number} y2 starting point y - * @return {Number} length of segment - */ - function calcLineLength(x1, y1, x2, y2) { - return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); - } - - // functions for the Cubic beizer - // taken from: https://github.com/konvajs/konva/blob/7.0.5/src/shapes/Path.ts#L350 - function CB1(t) { - return t * t * t; - } - function CB2(t) { - return 3 * t * t * (1 - t); - } - function CB3(t) { - return 3 * t * (1 - t) * (1 - t); - } - function CB4(t) { - return (1 - t) * (1 - t) * (1 - t); - } - - function getPointOnCubicBezierIterator(p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) { - return function(pct) { - var c1 = CB1(pct), c2 = CB2(pct), c3 = CB3(pct), c4 = CB4(pct); - return { - x: p4x * c1 + p3x * c2 + p2x * c3 + p1x * c4, - y: p4y * c1 + p3y * c2 + p2y * c3 + p1y * c4 - }; - }; - } - - function getTangentCubicIterator(p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) { - return function (pct) { - var invT = 1 - pct, - tangentX = (3 * invT * invT * (p2x - p1x)) + (6 * invT * pct * (p3x - p2x)) + - (3 * pct * pct * (p4x - p3x)), - tangentY = (3 * invT * invT * (p2y - p1y)) + (6 * invT * pct * (p3y - p2y)) + - (3 * pct * pct * (p4y - p3y)); - return Math.atan2(tangentY, tangentX); - }; - } - - function QB1(t) { - return t * t; - } - - function QB2(t) { - return 2 * t * (1 - t); - } - - function QB3(t) { - return (1 - t) * (1 - t); - } - - function getPointOnQuadraticBezierIterator(p1x, p1y, p2x, p2y, p3x, p3y) { - return function(pct) { - var c1 = QB1(pct), c2 = QB2(pct), c3 = QB3(pct); - return { - x: p3x * c1 + p2x * c2 + p1x * c3, - y: p3y * c1 + p2y * c2 + p1y * c3 - }; - }; - } - - function getTangentQuadraticIterator(p1x, p1y, p2x, p2y, p3x, p3y) { - return function (pct) { - var invT = 1 - pct, - tangentX = (2 * invT * (p2x - p1x)) + (2 * pct * (p3x - p2x)), - tangentY = (2 * invT * (p2y - p1y)) + (2 * pct * (p3y - p2y)); - return Math.atan2(tangentY, tangentX); - }; - } - - - // this will run over a path segment ( a cubic or quadratic segment) and approximate it - // with 100 segemnts. This will good enough to calculate the length of the curve - function pathIterator(iterator, x1, y1) { - var tempP = { x: x1, y: y1 }, p, tmpLen = 0, perc; - for (perc = 1; perc <= 100; perc += 1) { - p = iterator(perc / 100); - tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y); - tempP = p; - } - return tmpLen; - } - - /** - * Given a pathInfo, and a distance in pixels, find the percentage from 0 to 1 - * that correspond to that pixels run over the path. - * The percentage will be then used to find the correct point on the canvas for the path. - * @param {Array} segInfo fabricJS collection of information on a parsed path - * @param {Number} distance from starting point, in pixels. - * @return {Object} info object with x and y ( the point on canvas ) and angle, the tangent on that point; - */ - function findPercentageForDistance(segInfo, distance) { - var perc = 0, tmpLen = 0, iterator = segInfo.iterator, tempP = { x: segInfo.x, y: segInfo.y }, - p, nextLen, nextStep = 0.01, angleFinder = segInfo.angleFinder, lastPerc; - // nextStep > 0.0001 covers 0.00015625 that 1/64th of 1/100 - // the path - while (tmpLen < distance && nextStep > 0.0001) { - p = iterator(perc); - lastPerc = perc; - nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y); - // compare tmpLen each cycle with distance, decide next perc to test. - if ((nextLen + tmpLen) > distance) { - // we discard this step and we make smaller steps. - perc -= nextStep; - nextStep /= 2; - } - else { - tempP = p; - perc += nextStep; - tmpLen += nextLen; - } - } - p.angle = angleFinder(lastPerc); - return p; - } - - /** - * Run over a parsed and simplifed path and extrac some informations. - * informations are length of each command and starting point - * @param {Array} path fabricJS parsed path commands - * @return {Array} path commands informations - */ - function getPathSegmentsInfo(path) { - var totalLength = 0, len = path.length, current, - //x2 and y2 are the coords of segment start - //x1 and y1 are the coords of the current point - x1 = 0, y1 = 0, x2 = 0, y2 = 0, info = [], iterator, tempInfo, angleFinder; - for (var i = 0; i < len; i++) { - current = path[i]; - tempInfo = { - x: x1, - y: y1, - command: current[0], - }; - switch (current[0]) { //first letter - case 'M': - tempInfo.length = 0; - x2 = x1 = current[1]; - y2 = y1 = current[2]; - break; - case 'L': - tempInfo.length = calcLineLength(x1, y1, current[1], current[2]); - x1 = current[1]; - y1 = current[2]; - break; - case 'C': - iterator = getPointOnCubicBezierIterator( - x1, - y1, - current[1], - current[2], - current[3], - current[4], - current[5], - current[6] - ); - angleFinder = getTangentCubicIterator( - x1, - y1, - current[1], - current[2], - current[3], - current[4], - current[5], - current[6] - ); - tempInfo.iterator = iterator; - tempInfo.angleFinder = angleFinder; - tempInfo.length = pathIterator(iterator, x1, y1); - x1 = current[5]; - y1 = current[6]; - break; - case 'Q': - iterator = getPointOnQuadraticBezierIterator( - x1, - y1, - current[1], - current[2], - current[3], - current[4] - ); - angleFinder = getTangentQuadraticIterator( - x1, - y1, - current[1], - current[2], - current[3], - current[4] - ); - tempInfo.iterator = iterator; - tempInfo.angleFinder = angleFinder; - tempInfo.length = pathIterator(iterator, x1, y1); - x1 = current[3]; - y1 = current[4]; - break; - case 'Z': - case 'z': - // we add those in order to ease calculations later - tempInfo.destX = x2; - tempInfo.destY = y2; - tempInfo.length = calcLineLength(x1, y1, x2, y2); - x1 = x2; - y1 = y2; - break; - } - totalLength += tempInfo.length; - info.push(tempInfo); - } - info.push({ length: totalLength, x: x1, y: y1 }); - return info; - } - - function getPointOnPath(path, distance, infos) { - if (!infos) { - infos = getPathSegmentsInfo(path); - } - var i = 0; - while ((distance - infos[i].length > 0) && i < (infos.length - 2)) { - distance -= infos[i].length; - i++; - } - // var distance = infos[infos.length - 1] * perc; - var segInfo = infos[i], segPercent = distance / segInfo.length, - command = segInfo.command, segment = path[i], info; - - switch (command) { - case 'M': - return { x: segInfo.x, y: segInfo.y, angle: 0 }; - case 'Z': - case 'z': - info = new fabric.Point(segInfo.x, segInfo.y).lerp( - new fabric.Point(segInfo.destX, segInfo.destY), - segPercent - ); - info.angle = Math.atan2(segInfo.destY - segInfo.y, segInfo.destX - segInfo.x); - return info; - case 'L': - info = new fabric.Point(segInfo.x, segInfo.y).lerp( - new fabric.Point(segment[1], segment[2]), - segPercent - ); - info.angle = Math.atan2(segment[2] - segInfo.y, segment[1] - segInfo.x); - return info; - case 'C': - return findPercentageForDistance(segInfo, distance); - case 'Q': - return findPercentageForDistance(segInfo, distance); - } - } - - /** - * - * @param {string} pathString - * @return {(string|number)[][]} An array of SVG path commands - * @example Usage - * parsePath('M 3 4 Q 3 5 2 1 4 0 Q 9 12 2 1 4 0') === [ - * ['M', 3, 4], - * ['Q', 3, 5, 2, 1, 4, 0], - * ['Q', 9, 12, 2, 1, 4, 0], - * ]; - * - */ - function parsePath(pathString) { - var result = [], - coords = [], - currentPath, - parsed, - re = fabric.rePathCommand, - rNumber = '[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?\\s*', - rNumberCommaWsp = '(' + rNumber + ')' + fabric.commaWsp, - rFlagCommaWsp = '([01])' + fabric.commaWsp + '?', - rArcSeq = rNumberCommaWsp + '?' + rNumberCommaWsp + '?' + rNumberCommaWsp + rFlagCommaWsp + rFlagCommaWsp + - rNumberCommaWsp + '?(' + rNumber + ')', - regArcArgumentSequence = new RegExp(rArcSeq, 'g'), - match, - coordsStr, - // one of commands (m,M,l,L,q,Q,c,C,etc.) followed by non-command characters (i.e. command values) - path; - if (!pathString || !pathString.match) { - return result; - } - path = pathString.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi); - - for (var i = 0, coordsParsed, len = path.length; i < len; i++) { - currentPath = path[i]; - - coordsStr = currentPath.slice(1).trim(); - coords.length = 0; - - var command = currentPath.charAt(0); - coordsParsed = [command]; - - if (command.toLowerCase() === 'a') { - // arcs have special flags that apparently don't require spaces so handle special - for (var args; (args = regArcArgumentSequence.exec(coordsStr));) { - for (var j = 1; j < args.length; j++) { - coords.push(args[j]); - } - } - } - else { - while ((match = re.exec(coordsStr))) { - coords.push(match[0]); - } - } - - for (var j = 0, jlen = coords.length; j < jlen; j++) { - parsed = parseFloat(coords[j]); - if (!isNaN(parsed)) { - coordsParsed.push(parsed); - } - } - - var commandLength = commandLengths[command.toLowerCase()], - repeatedCommand = repeatedCommands[command] || command; - - if (coordsParsed.length - 1 > commandLength) { - for (var k = 1, klen = coordsParsed.length; k < klen; k += commandLength) { - result.push([command].concat(coordsParsed.slice(k, k + commandLength))); - command = repeatedCommand; - } - } - else { - result.push(coordsParsed); - } - } - - return result; - }; - - /** - * - * Converts points to a smooth SVG path - * @param {{ x: number,y: number }[]} points Array of points - * @param {number} [correction] Apply a correction to the path (usually we use `width / 1000`). If value is undefined 0 is used as the correction value. - * @return {(string|number)[][]} An array of SVG path commands - */ - function getSmoothPathFromPoints(points, correction) { - var path = [], i, - p1 = new fabric.Point(points[0].x, points[0].y), - p2 = new fabric.Point(points[1].x, points[1].y), - len = points.length, multSignX = 1, multSignY = 0, manyPoints = len > 2; - correction = correction || 0; - - if (manyPoints) { - multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1; - multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1; - } - path.push(['M', p1.x - multSignX * correction, p1.y - multSignY * correction]); - for (i = 1; i < len; i++) { - if (!p1.eq(p2)) { - var midPoint = p1.midPointFrom(p2); - // p1 is our bezier control point - // midpoint is our endpoint - // start point is p(i-1) value. - path.push(['Q', p1.x, p1.y, midPoint.x, midPoint.y]); - } - p1 = points[i]; - if ((i + 1) < points.length) { - p2 = points[i + 1]; - } - } - if (manyPoints) { - multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1; - multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1; - } - path.push(['L', p1.x + multSignX * correction, p1.y + multSignY * correction]); - return path; - } - /** - * Transform a path by transforming each segment. - * it has to be a simplified path or it won't work. - * WARNING: this depends from pathOffset for correct operation - * @param {Array} path fabricJS parsed and simplified path commands - * @param {Array} transform matrix that represent the transformation - * @param {Object} [pathOffset] the fabric.Path pathOffset - * @param {Number} pathOffset.x - * @param {Number} pathOffset.y - * @returns {Array} the transformed path - */ - function transformPath(path, transform, pathOffset) { - if (pathOffset) { - transform = fabric.util.multiplyTransformMatrices( - transform, - [1, 0, 0, 1, -pathOffset.x, -pathOffset.y] - ); - } - return path.map(function(pathSegment) { - var newSegment = pathSegment.slice(0), point = {}; - for (var i = 1; i < pathSegment.length - 1; i += 2) { - point.x = pathSegment[i]; - point.y = pathSegment[i + 1]; - point = fabric.util.transformPoint(point, transform); - newSegment[i] = point.x; - newSegment[i + 1] = point.y; - } - return newSegment; - }); - } - - /** - * Join path commands to go back to svg format - * @param {Array} pathData fabricJS parsed path commands - * @return {String} joined path 'M 0 0 L 20 30' - */ - fabric.util.joinPath = function(pathData) { - return pathData.map(function (segment) { return segment.join(' '); }).join(' '); - }; - fabric.util.parsePath = parsePath; - fabric.util.makePathSimpler = makePathSimpler; - fabric.util.getSmoothPathFromPoints = getSmoothPathFromPoints; - fabric.util.getPathSegmentsInfo = getPathSegmentsInfo; - fabric.util.getBoundsOfCurve = getBoundsOfCurve; - fabric.util.getPointOnPath = getPointOnPath; - fabric.util.transformPath = transformPath; -})(); - - -(function() { - - var slice = Array.prototype.slice; - - /** - * Invokes method on all items in a given array - * @memberOf fabric.util.array - * @param {Array} array Array to iterate over - * @param {String} method Name of a method to invoke - * @return {Array} - */ - function invoke(array, method) { - var args = slice.call(arguments, 2), result = []; - for (var i = 0, len = array.length; i < len; i++) { - result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]); - } - return result; - } - - /** - * Finds maximum value in array (not necessarily "first" one) - * @memberOf fabric.util.array - * @param {Array} array Array to iterate over - * @param {String} byProperty - * @return {*} - */ - function max(array, byProperty) { - return find(array, byProperty, function(value1, value2) { - return value1 >= value2; - }); - } - - /** - * Finds minimum value in array (not necessarily "first" one) - * @memberOf fabric.util.array - * @param {Array} array Array to iterate over - * @param {String} byProperty - * @return {*} - */ - function min(array, byProperty) { - return find(array, byProperty, function(value1, value2) { - return value1 < value2; - }); - } - - /** - * @private - */ - function fill(array, value) { - var k = array.length; - while (k--) { - array[k] = value; - } - return array; - } - - /** - * @private - */ - function find(array, byProperty, condition) { - if (!array || array.length === 0) { - return; - } - - var i = array.length - 1, - result = byProperty ? array[i][byProperty] : array[i]; - if (byProperty) { - while (i--) { - if (condition(array[i][byProperty], result)) { - result = array[i][byProperty]; - } - } - } - else { - while (i--) { - if (condition(array[i], result)) { - result = array[i]; - } - } - } - return result; - } - - /** - * @namespace fabric.util.array - */ - fabric.util.array = { - fill: fill, - invoke: invoke, - min: min, - max: max - }; - -})(); - - -(function() { - /** - * Copies all enumerable properties of one js object to another - * this does not and cannot compete with generic utils. - * Does not clone or extend fabric.Object subclasses. - * This is mostly for internal use and has extra handling for fabricJS objects - * it skips the canvas and group properties in deep cloning. - * @memberOf fabric.util.object - * @param {Object} destination Where to copy to - * @param {Object} source Where to copy from - * @param {Boolean} [deep] Whether to extend nested objects - * @return {Object} - */ - - function extend(destination, source, deep) { - // JScript DontEnum bug is not taken care of - // the deep clone is for internal use, is not meant to avoid - // javascript traps or cloning html element or self referenced objects. - if (deep) { - if (!fabric.isLikelyNode && source instanceof Element) { - // avoid cloning deep images, canvases, - destination = source; - } - else if (source instanceof Array) { - destination = []; - for (var i = 0, len = source.length; i < len; i++) { - destination[i] = extend({ }, source[i], deep); - } - } - else if (source && typeof source === 'object') { - for (var property in source) { - if (property === 'canvas' || property === 'group') { - // we do not want to clone this props at all. - // we want to keep the keys in the copy - destination[property] = null; - } - else if (source.hasOwnProperty(property)) { - destination[property] = extend({ }, source[property], deep); - } - } - } - else { - // this sounds odd for an extend but is ok for recursive use - destination = source; - } - } - else { - for (var property in source) { - destination[property] = source[property]; - } - } - return destination; - } - - /** - * Creates an empty object and copies all enumerable properties of another object to it - * This method is mostly for internal use, and not intended for duplicating shapes in canvas. - * @memberOf fabric.util.object - * @param {Object} object Object to clone - * @param {Boolean} [deep] Whether to clone nested objects - * @return {Object} - */ - - //TODO: this function return an empty object if you try to clone null - function clone(object, deep) { - return extend({ }, object, deep); - } - - /** @namespace fabric.util.object */ - fabric.util.object = { - extend: extend, - clone: clone - }; - fabric.util.object.extend(fabric.util, fabric.Observable); -})(); - - -(function() { - - /** - * Camelizes a string - * @memberOf fabric.util.string - * @param {String} string String to camelize - * @return {String} Camelized version of a string - */ - function camelize(string) { - return string.replace(/-+(.)?/g, function(match, character) { - return character ? character.toUpperCase() : ''; - }); - } - - /** - * Capitalizes a string - * @memberOf fabric.util.string - * @param {String} string String to capitalize - * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized - * and other letters stay untouched, if false first letter is capitalized - * and other letters are converted to lowercase. - * @return {String} Capitalized version of a string - */ - function capitalize(string, firstLetterOnly) { - return string.charAt(0).toUpperCase() + - (firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase()); - } - - /** - * Escapes XML in a string - * @memberOf fabric.util.string - * @param {String} string String to escape - * @return {String} Escaped version of a string - */ - function escapeXml(string) { - return string.replace(/&/g, '&') - .replace(/"/g, '"') - .replace(/'/g, ''') - .replace(//g, '>'); - } - - /** - * Divide a string in the user perceived single units - * @memberOf fabric.util.string - * @param {String} textstring String to escape - * @return {Array} array containing the graphemes - */ - function graphemeSplit(textstring) { - var i = 0, chr, graphemes = []; - for (i = 0, chr; i < textstring.length; i++) { - if ((chr = getWholeChar(textstring, i)) === false) { - continue; - } - graphemes.push(chr); - } - return graphemes; - } - - // taken from mdn in the charAt doc page. - function getWholeChar(str, i) { - var code = str.charCodeAt(i); - - if (isNaN(code)) { - return ''; // Position not found - } - if (code < 0xD800 || code > 0xDFFF) { - return str.charAt(i); - } - - // High surrogate (could change last hex to 0xDB7F to treat high private - // surrogates as single characters) - if (0xD800 <= code && code <= 0xDBFF) { - if (str.length <= (i + 1)) { - throw 'High surrogate without following low surrogate'; - } - var next = str.charCodeAt(i + 1); - if (0xDC00 > next || next > 0xDFFF) { - throw 'High surrogate without following low surrogate'; - } - return str.charAt(i) + str.charAt(i + 1); - } - // Low surrogate (0xDC00 <= code && code <= 0xDFFF) - if (i === 0) { - throw 'Low surrogate without preceding high surrogate'; - } - var prev = str.charCodeAt(i - 1); - - // (could change last hex to 0xDB7F to treat high private - // surrogates as single characters) - if (0xD800 > prev || prev > 0xDBFF) { - throw 'Low surrogate without preceding high surrogate'; - } - // We can pass over low surrogates now as the second component - // in a pair which we have already processed - return false; - } - - - /** - * String utilities - * @namespace fabric.util.string - */ - fabric.util.string = { - camelize: camelize, - capitalize: capitalize, - escapeXml: escapeXml, - graphemeSplit: graphemeSplit - }; -})(); - - -(function() { - - var slice = Array.prototype.slice, emptyFunction = function() { }, - - IS_DONTENUM_BUGGY = (function() { - for (var p in { toString: 1 }) { - if (p === 'toString') { - return false; - } - } - return true; - })(), - - /** @ignore */ - addMethods = function(klass, source, parent) { - for (var property in source) { - - if (property in klass.prototype && - typeof klass.prototype[property] === 'function' && - (source[property] + '').indexOf('callSuper') > -1) { - - klass.prototype[property] = (function(property) { - return function() { - - var superclass = this.constructor.superclass; - this.constructor.superclass = parent; - var returnValue = source[property].apply(this, arguments); - this.constructor.superclass = superclass; - - if (property !== 'initialize') { - return returnValue; - } - }; - })(property); - } - else { - klass.prototype[property] = source[property]; - } - - if (IS_DONTENUM_BUGGY) { - if (source.toString !== Object.prototype.toString) { - klass.prototype.toString = source.toString; - } - if (source.valueOf !== Object.prototype.valueOf) { - klass.prototype.valueOf = source.valueOf; - } - } - } - }; - - function Subclass() { } - - function callSuper(methodName) { - var parentMethod = null, - _this = this; - - // climb prototype chain to find method not equal to callee's method - while (_this.constructor.superclass) { - var superClassMethod = _this.constructor.superclass.prototype[methodName]; - if (_this[methodName] !== superClassMethod) { - parentMethod = superClassMethod; - break; - } - // eslint-disable-next-line - _this = _this.constructor.superclass.prototype; - } - - if (!parentMethod) { - return console.log('tried to callSuper ' + methodName + ', method not found in prototype chain', this); - } - - return (arguments.length > 1) - ? parentMethod.apply(this, slice.call(arguments, 1)) - : parentMethod.call(this); - } - - /** - * Helper for creation of "classes". - * @memberOf fabric.util - * @param {Function} [parent] optional "Class" to inherit from - * @param {Object} [properties] Properties shared by all instances of this class - * (be careful modifying objects defined here as this would affect all instances) - */ - function createClass() { - var parent = null, - properties = slice.call(arguments, 0); - - if (typeof properties[0] === 'function') { - parent = properties.shift(); - } - function klass() { - this.initialize.apply(this, arguments); - } - - klass.superclass = parent; - klass.subclasses = []; - - if (parent) { - Subclass.prototype = parent.prototype; - klass.prototype = new Subclass(); - parent.subclasses.push(klass); - } - for (var i = 0, length = properties.length; i < length; i++) { - addMethods(klass, properties[i], parent); - } - if (!klass.prototype.initialize) { - klass.prototype.initialize = emptyFunction; - } - klass.prototype.constructor = klass; - klass.prototype.callSuper = callSuper; - return klass; - } - - fabric.util.createClass = createClass; -})(); - - -(function () { - // since ie11 can use addEventListener but they do not support options, i need to check - var couldUseAttachEvent = !!fabric.document.createElement('div').attachEvent, - touchEvents = ['touchstart', 'touchmove', 'touchend']; - /** - * Adds an event listener to an element - * @function - * @memberOf fabric.util - * @param {HTMLElement} element - * @param {String} eventName - * @param {Function} handler - */ - fabric.util.addListener = function(element, eventName, handler, options) { - element && element.addEventListener(eventName, handler, couldUseAttachEvent ? false : options); - }; - - /** - * Removes an event listener from an element - * @function - * @memberOf fabric.util - * @param {HTMLElement} element - * @param {String} eventName - * @param {Function} handler - */ - fabric.util.removeListener = function(element, eventName, handler, options) { - element && element.removeEventListener(eventName, handler, couldUseAttachEvent ? false : options); - }; - - function getTouchInfo(event) { - var touchProp = event.changedTouches; - if (touchProp && touchProp[0]) { - return touchProp[0]; - } - return event; - } - - fabric.util.getPointer = function(event) { - var element = event.target, - scroll = fabric.util.getScrollLeftTop(element), - _evt = getTouchInfo(event); - return { - x: _evt.clientX + scroll.left, - y: _evt.clientY + scroll.top - }; - }; - - fabric.util.isTouchEvent = function(event) { - return touchEvents.indexOf(event.type) > -1 || event.pointerType === 'touch'; - }; -})(); - - -(function () { - - /** - * Cross-browser wrapper for setting element's style - * @memberOf fabric.util - * @param {HTMLElement} element - * @param {Object} styles - * @return {HTMLElement} Element that was passed as a first argument - */ - function setStyle(element, styles) { - var elementStyle = element.style; - if (!elementStyle) { - return element; - } - if (typeof styles === 'string') { - element.style.cssText += ';' + styles; - return styles.indexOf('opacity') > -1 - ? setOpacity(element, styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) - : element; - } - for (var property in styles) { - if (property === 'opacity') { - setOpacity(element, styles[property]); - } - else { - var normalizedProperty = (property === 'float' || property === 'cssFloat') - ? (typeof elementStyle.styleFloat === 'undefined' ? 'cssFloat' : 'styleFloat') - : property; - elementStyle[normalizedProperty] = styles[property]; - } - } - return element; - } - - var parseEl = fabric.document.createElement('div'), - supportsOpacity = typeof parseEl.style.opacity === 'string', - supportsFilters = typeof parseEl.style.filter === 'string', - reOpacity = /alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/, - - /** @ignore */ - setOpacity = function (element) { return element; }; - - if (supportsOpacity) { - /** @ignore */ - setOpacity = function(element, value) { - element.style.opacity = value; - return element; - }; - } - else if (supportsFilters) { - /** @ignore */ - setOpacity = function(element, value) { - var es = element.style; - if (element.currentStyle && !element.currentStyle.hasLayout) { - es.zoom = 1; - } - if (reOpacity.test(es.filter)) { - value = value >= 0.9999 ? '' : ('alpha(opacity=' + (value * 100) + ')'); - es.filter = es.filter.replace(reOpacity, value); - } - else { - es.filter += ' alpha(opacity=' + (value * 100) + ')'; - } - return element; - }; - } - - fabric.util.setStyle = setStyle; - -})(); - - -(function() { - - var _slice = Array.prototype.slice; - - /** - * Takes id and returns an element with that id (if one exists in a document) - * @memberOf fabric.util - * @param {String|HTMLElement} id - * @return {HTMLElement|null} - */ - function getById(id) { - return typeof id === 'string' ? fabric.document.getElementById(id) : id; - } - - var sliceCanConvertNodelists, - /** - * Converts an array-like object (e.g. arguments or NodeList) to an array - * @memberOf fabric.util - * @param {Object} arrayLike - * @return {Array} - */ - toArray = function(arrayLike) { - return _slice.call(arrayLike, 0); - }; - - try { - sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array; - } - catch (err) { } - - if (!sliceCanConvertNodelists) { - toArray = function(arrayLike) { - var arr = new Array(arrayLike.length), i = arrayLike.length; - while (i--) { - arr[i] = arrayLike[i]; - } - return arr; - }; - } - - /** - * Creates specified element with specified attributes - * @memberOf fabric.util - * @param {String} tagName Type of an element to create - * @param {Object} [attributes] Attributes to set on an element - * @return {HTMLElement} Newly created element - */ - function makeElement(tagName, attributes) { - var el = fabric.document.createElement(tagName); - for (var prop in attributes) { - if (prop === 'class') { - el.className = attributes[prop]; - } - else if (prop === 'for') { - el.htmlFor = attributes[prop]; - } - else { - el.setAttribute(prop, attributes[prop]); - } - } - return el; - } - - /** - * Adds class to an element - * @memberOf fabric.util - * @param {HTMLElement} element Element to add class to - * @param {String} className Class to add to an element - */ - function addClass(element, className) { - if (element && (' ' + element.className + ' ').indexOf(' ' + className + ' ') === -1) { - element.className += (element.className ? ' ' : '') + className; - } - } - - /** - * Wraps element with another element - * @memberOf fabric.util - * @param {HTMLElement} element Element to wrap - * @param {HTMLElement|String} wrapper Element to wrap with - * @param {Object} [attributes] Attributes to set on a wrapper - * @return {HTMLElement} wrapper - */ - function wrapElement(element, wrapper, attributes) { - if (typeof wrapper === 'string') { - wrapper = makeElement(wrapper, attributes); - } - if (element.parentNode) { - element.parentNode.replaceChild(wrapper, element); - } - wrapper.appendChild(element); - return wrapper; - } - - /** - * Returns element scroll offsets - * @memberOf fabric.util - * @param {HTMLElement} element Element to operate on - * @return {Object} Object with left/top values - */ - function getScrollLeftTop(element) { - - var left = 0, - top = 0, - docElement = fabric.document.documentElement, - body = fabric.document.body || { - scrollLeft: 0, scrollTop: 0 - }; - - // While loop checks (and then sets element to) .parentNode OR .host - // to account for ShadowDOM. We still want to traverse up out of ShadowDOM, - // but the .parentNode of a root ShadowDOM node will always be null, instead - // it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938 - while (element && (element.parentNode || element.host)) { - - // Set element to element parent, or 'host' in case of ShadowDOM - element = element.parentNode || element.host; - - if (element === fabric.document) { - left = body.scrollLeft || docElement.scrollLeft || 0; - top = body.scrollTop || docElement.scrollTop || 0; - } - else { - left += element.scrollLeft || 0; - top += element.scrollTop || 0; - } - - if (element.nodeType === 1 && element.style.position === 'fixed') { - break; - } - } - - return { left: left, top: top }; - } - - /** - * Returns offset for a given element - * @function - * @memberOf fabric.util - * @param {HTMLElement} element Element to get offset for - * @return {Object} Object with "left" and "top" properties - */ - function getElementOffset(element) { - var docElem, - doc = element && element.ownerDocument, - box = { left: 0, top: 0 }, - offset = { left: 0, top: 0 }, - scrollLeftTop, - offsetAttributes = { - borderLeftWidth: 'left', - borderTopWidth: 'top', - paddingLeft: 'left', - paddingTop: 'top' - }; - - if (!doc) { - return offset; - } - - for (var attr in offsetAttributes) { - offset[offsetAttributes[attr]] += parseInt(getElementStyle(element, attr), 10) || 0; - } - - docElem = doc.documentElement; - if ( typeof element.getBoundingClientRect !== 'undefined' ) { - box = element.getBoundingClientRect(); - } - - scrollLeftTop = getScrollLeftTop(element); - - return { - left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left, - top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top - }; - } - - /** - * Returns style attribute value of a given element - * @memberOf fabric.util - * @param {HTMLElement} element Element to get style attribute for - * @param {String} attr Style attribute to get for element - * @return {String} Style attribute value of the given element. - */ - var getElementStyle; - if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) { - getElementStyle = function(element, attr) { - var style = fabric.document.defaultView.getComputedStyle(element, null); - return style ? style[attr] : undefined; - }; - } - else { - getElementStyle = function(element, attr) { - var value = element.style[attr]; - if (!value && element.currentStyle) { - value = element.currentStyle[attr]; - } - return value; - }; - } - - (function () { - var style = fabric.document.documentElement.style, - selectProp = 'userSelect' in style - ? 'userSelect' - : 'MozUserSelect' in style - ? 'MozUserSelect' - : 'WebkitUserSelect' in style - ? 'WebkitUserSelect' - : 'KhtmlUserSelect' in style - ? 'KhtmlUserSelect' - : ''; - - /** - * Makes element unselectable - * @memberOf fabric.util - * @param {HTMLElement} element Element to make unselectable - * @return {HTMLElement} Element that was passed in - */ - function makeElementUnselectable(element) { - if (typeof element.onselectstart !== 'undefined') { - element.onselectstart = fabric.util.falseFunction; - } - if (selectProp) { - element.style[selectProp] = 'none'; - } - else if (typeof element.unselectable === 'string') { - element.unselectable = 'on'; - } - return element; - } - - /** - * Makes element selectable - * @memberOf fabric.util - * @param {HTMLElement} element Element to make selectable - * @return {HTMLElement} Element that was passed in - */ - function makeElementSelectable(element) { - if (typeof element.onselectstart !== 'undefined') { - element.onselectstart = null; - } - if (selectProp) { - element.style[selectProp] = ''; - } - else if (typeof element.unselectable === 'string') { - element.unselectable = ''; - } - return element; - } - - fabric.util.makeElementUnselectable = makeElementUnselectable; - fabric.util.makeElementSelectable = makeElementSelectable; - })(); - - function getNodeCanvas(element) { - var impl = fabric.jsdomImplForWrapper(element); - return impl._canvas || impl._image; - }; - - function cleanUpJsdomNode(element) { - if (!fabric.isLikelyNode) { - return; - } - var impl = fabric.jsdomImplForWrapper(element); - if (impl) { - impl._image = null; - impl._canvas = null; - // unsure if necessary - impl._currentSrc = null; - impl._attributes = null; - impl._classList = null; - } - } - - function setImageSmoothing(ctx, value) { - ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled || ctx.webkitImageSmoothingEnabled - || ctx.mozImageSmoothingEnabled || ctx.msImageSmoothingEnabled || ctx.oImageSmoothingEnabled; - ctx.imageSmoothingEnabled = value; - } - - /** - * setImageSmoothing sets the context imageSmoothingEnabled property. - * Used by canvas and by ImageObject. - * @memberOf fabric.util - * @since 4.0.0 - * @param {HTMLRenderingContext2D} ctx to set on - * @param {Boolean} value true or false - */ - fabric.util.setImageSmoothing = setImageSmoothing; - fabric.util.getById = getById; - fabric.util.toArray = toArray; - fabric.util.addClass = addClass; - fabric.util.makeElement = makeElement; - fabric.util.wrapElement = wrapElement; - fabric.util.getScrollLeftTop = getScrollLeftTop; - fabric.util.getElementOffset = getElementOffset; - fabric.util.getNodeCanvas = getNodeCanvas; - fabric.util.cleanUpJsdomNode = cleanUpJsdomNode; - -})(); - - -(function() { - - function addParamToUrl(url, param) { - return url + (/\?/.test(url) ? '&' : '?') + param; - } - - function emptyFn() { } - - /** - * Cross-browser abstraction for sending XMLHttpRequest - * @memberOf fabric.util - * @param {String} url URL to send XMLHttpRequest to - * @param {Object} [options] Options object - * @param {String} [options.method="GET"] - * @param {String} [options.parameters] parameters to append to url in GET or in body - * @param {String} [options.body] body to send with POST or PUT request - * @param {Function} options.onComplete Callback to invoke when request is completed - * @return {XMLHttpRequest} request - */ - function request(url, options) { - options || (options = { }); - - var method = options.method ? options.method.toUpperCase() : 'GET', - onComplete = options.onComplete || function() { }, - xhr = new fabric.window.XMLHttpRequest(), - body = options.body || options.parameters; - - /** @ignore */ - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - onComplete(xhr); - xhr.onreadystatechange = emptyFn; - } - }; - - if (method === 'GET') { - body = null; - if (typeof options.parameters === 'string') { - url = addParamToUrl(url, options.parameters); - } - } - - xhr.open(method, url, true); - - if (method === 'POST' || method === 'PUT') { - xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); - } - - xhr.send(body); - return xhr; - } - - fabric.util.request = request; -})(); - - -/** - * Wrapper around `console.log` (when available) - * @param {*} [values] Values to log - */ -fabric.log = console.log; - -/** - * Wrapper around `console.warn` (when available) - * @param {*} [values] Values to log as a warning - */ -fabric.warn = console.warn; - - -(function () { - - var extend = fabric.util.object.extend, - clone = fabric.util.object.clone; - - /** - * @typedef {Object} AnimationOptions - * Animation of a value or list of values. - * When using lists, think of something like this: - * fabric.util.animate({ - * startValue: [1, 2, 3], - * endValue: [2, 4, 6], - * onChange: function([a, b, c]) { - * canvas.zoomToPoint({x: b, y: c}, a) - * canvas.renderAll() - * } - * }); - * @example - * @property {Function} [onChange] Callback; invoked on every value change - * @property {Function} [onComplete] Callback; invoked when value change is completed - * @example - * // Note: startValue, endValue, and byValue must match the type - * var animationOptions = { startValue: 0, endValue: 1, byValue: 0.25 } - * var animationOptions = { startValue: [0, 1], endValue: [1, 2], byValue: [0.25, 0.25] } - * @property {number | number[]} [startValue=0] Starting value - * @property {number | number[]} [endValue=100] Ending value - * @property {number | number[]} [byValue=100] Value to modify the property by - * @property {Function} [easing] Easing function - * @property {Number} [duration=500] Duration of change (in ms) - * @property {Function} [abort] Additional function with logic. If returns true, animation aborts. - * - * @typedef {() => void} CancelFunction - * - * @typedef {Object} AnimationCurrentState - * @property {number | number[]} currentValue value in range [`startValue`, `endValue`] - * @property {number} completionRate value in range [0, 1] - * @property {number} durationRate value in range [0, 1] - * - * @typedef {(AnimationOptions & AnimationCurrentState & { cancel: CancelFunction }} AnimationContext - */ - - /** - * Array holding all running animations - * @memberof fabric - * @type {AnimationContext[]} - */ - var RUNNING_ANIMATIONS = []; - fabric.util.object.extend(RUNNING_ANIMATIONS, { - - /** - * cancel all running animations at the next requestAnimFrame - * @returns {AnimationContext[]} - */ - cancelAll: function () { - var animations = this.splice(0); - animations.forEach(function (animation) { - animation.cancel(); - }); - return animations; - }, - - /** - * cancel all running animations attached to canvas at the next requestAnimFrame - * @param {fabric.Canvas} canvas - * @returns {AnimationContext[]} - */ - cancelByCanvas: function (canvas) { - if (!canvas) { - return []; - } - var cancelled = this.filter(function (animation) { - return typeof animation.target === 'object' && animation.target.canvas === canvas; - }); - cancelled.forEach(function (animation) { - animation.cancel(); - }); - return cancelled; - }, - - /** - * cancel all running animations for target at the next requestAnimFrame - * @param {*} target - * @returns {AnimationContext[]} - */ - cancelByTarget: function (target) { - var cancelled = this.findAnimationsByTarget(target); - cancelled.forEach(function (animation) { - animation.cancel(); - }); - return cancelled; - }, - - /** - * - * @param {CancelFunction} cancelFunc the function returned by animate - * @returns {number} - */ - findAnimationIndex: function (cancelFunc) { - return this.indexOf(this.findAnimation(cancelFunc)); - }, - - /** - * - * @param {CancelFunction} cancelFunc the function returned by animate - * @returns {AnimationContext | undefined} animation's options object - */ - findAnimation: function (cancelFunc) { - return this.find(function (animation) { - return animation.cancel === cancelFunc; - }); - }, - - /** - * - * @param {*} target the object that is assigned to the target property of the animation context - * @returns {AnimationContext[]} array of animation options object associated with target - */ - findAnimationsByTarget: function (target) { - if (!target) { - return []; - } - return this.filter(function (animation) { - return animation.target === target; - }); - } - }); - - function noop() { - return false; - } - - function defaultEasing(t, b, c, d) { - return -c * Math.cos(t / d * (Math.PI / 2)) + c + b; - } - - /** - * Changes value from one to another within certain period of time, invoking callbacks as value is being changed. - * @memberOf fabric.util - * @param {AnimationOptions} [options] Animation options - * @example - * // Note: startValue, endValue, and byValue must match the type - * fabric.util.animate({ startValue: 0, endValue: 1, byValue: 0.25 }) - * fabric.util.animate({ startValue: [0, 1], endValue: [1, 2], byValue: [0.25, 0.25] }) - * @returns {CancelFunction} cancel function - */ - function animate(options) { - options || (options = {}); - var cancel = false, - context, - removeFromRegistry = function () { - var index = fabric.runningAnimations.indexOf(context); - return index > -1 && fabric.runningAnimations.splice(index, 1)[0]; - }; - - context = extend(clone(options), { - cancel: function () { - cancel = true; - return removeFromRegistry(); - }, - currentValue: 'startValue' in options ? options.startValue : 0, - completionRate: 0, - durationRate: 0 - }); - fabric.runningAnimations.push(context); - - requestAnimFrame(function(timestamp) { - var start = timestamp || +new Date(), - duration = options.duration || 500, - finish = start + duration, time, - onChange = options.onChange || noop, - abort = options.abort || noop, - onComplete = options.onComplete || noop, - easing = options.easing || defaultEasing, - isMany = 'startValue' in options ? options.startValue.length > 0 : false, - startValue = 'startValue' in options ? options.startValue : 0, - endValue = 'endValue' in options ? options.endValue : 100, - byValue = options.byValue || (isMany ? startValue.map(function(value, i) { - return endValue[i] - startValue[i]; - }) : endValue - startValue); - - options.onStart && options.onStart(); - - (function tick(ticktime) { - time = ticktime || +new Date(); - var currentTime = time > finish ? duration : (time - start), - timePerc = currentTime / duration, - current = isMany ? startValue.map(function(_value, i) { - return easing(currentTime, startValue[i], byValue[i], duration); - }) : easing(currentTime, startValue, byValue, duration), - valuePerc = isMany ? Math.abs((current[0] - startValue[0]) / byValue[0]) - : Math.abs((current - startValue) / byValue); - // update context - context.currentValue = isMany ? current.slice() : current; - context.completionRate = valuePerc; - context.durationRate = timePerc; - if (cancel) { - return; - } - if (abort(current, valuePerc, timePerc)) { - removeFromRegistry(); - return; - } - if (time > finish) { - // update context - context.currentValue = isMany ? endValue.slice() : endValue; - context.completionRate = 1; - context.durationRate = 1; - // execute callbacks - onChange(isMany ? endValue.slice() : endValue, 1, 1); - onComplete(endValue, 1, 1); - removeFromRegistry(); - return; - } - else { - onChange(current, valuePerc, timePerc); - requestAnimFrame(tick); - } - })(start); - }); - - return context.cancel; - } - - var _requestAnimFrame = fabric.window.requestAnimationFrame || - fabric.window.webkitRequestAnimationFrame || - fabric.window.mozRequestAnimationFrame || - fabric.window.oRequestAnimationFrame || - fabric.window.msRequestAnimationFrame || - function(callback) { - return fabric.window.setTimeout(callback, 1000 / 60); - }; - - var _cancelAnimFrame = fabric.window.cancelAnimationFrame || fabric.window.clearTimeout; - - /** - * requestAnimationFrame polyfill based on http://paulirish.com/2011/requestanimationframe-for-smart-animating/ - * In order to get a precise start time, `requestAnimFrame` should be called as an entry into the method - * @memberOf fabric.util - * @param {Function} callback Callback to invoke - * @param {DOMElement} element optional Element to associate with animation - */ - function requestAnimFrame() { - return _requestAnimFrame.apply(fabric.window, arguments); - } - - function cancelAnimFrame() { - return _cancelAnimFrame.apply(fabric.window, arguments); - } - - fabric.util.animate = animate; - fabric.util.requestAnimFrame = requestAnimFrame; - fabric.util.cancelAnimFrame = cancelAnimFrame; - fabric.runningAnimations = RUNNING_ANIMATIONS; -})(); - - -(function() { - // Calculate an in-between color. Returns a "rgba()" string. - // Credit: Edwin Martin - // http://www.bitstorm.org/jquery/color-animation/jquery.animate-colors.js - function calculateColor(begin, end, pos) { - var color = 'rgba(' - + parseInt((begin[0] + pos * (end[0] - begin[0])), 10) + ',' - + parseInt((begin[1] + pos * (end[1] - begin[1])), 10) + ',' - + parseInt((begin[2] + pos * (end[2] - begin[2])), 10); - - color += ',' + (begin && end ? parseFloat(begin[3] + pos * (end[3] - begin[3])) : 1); - color += ')'; - return color; - } - - /** - * Changes the color from one to another within certain period of time, invoking callbacks as value is being changed. - * @memberOf fabric.util - * @param {String} fromColor The starting color in hex or rgb(a) format. - * @param {String} toColor The starting color in hex or rgb(a) format. - * @param {Number} [duration] Duration of change (in ms). - * @param {Object} [options] Animation options - * @param {Function} [options.onChange] Callback; invoked on every value change - * @param {Function} [options.onComplete] Callback; invoked when value change is completed - * @param {Function} [options.colorEasing] Easing function. Note that this function only take two arguments (currentTime, duration). Thus the regular animation easing functions cannot be used. - * @param {Function} [options.abort] Additional function with logic. If returns true, onComplete is called. - * @returns {Function} abort function - */ - function animateColor(fromColor, toColor, duration, options) { - var startColor = new fabric.Color(fromColor).getSource(), - endColor = new fabric.Color(toColor).getSource(), - originalOnComplete = options.onComplete, - originalOnChange = options.onChange; - options = options || {}; - - return fabric.util.animate(fabric.util.object.extend(options, { - duration: duration || 500, - startValue: startColor, - endValue: endColor, - byValue: endColor, - easing: function (currentTime, startValue, byValue, duration) { - var posValue = options.colorEasing - ? options.colorEasing(currentTime, duration) - : 1 - Math.cos(currentTime / duration * (Math.PI / 2)); - return calculateColor(startValue, byValue, posValue); - }, - // has to take in account for color restoring; - onComplete: function(current, valuePerc, timePerc) { - if (originalOnComplete) { - return originalOnComplete( - calculateColor(endColor, endColor, 0), - valuePerc, - timePerc - ); - } - }, - onChange: function(current, valuePerc, timePerc) { - if (originalOnChange) { - if (Array.isArray(current)) { - return originalOnChange( - calculateColor(current, current, 0), - valuePerc, - timePerc - ); - } - originalOnChange(current, valuePerc, timePerc); - } - } - })); - } - - fabric.util.animateColor = animateColor; - -})(); - - -(function() { - - function normalize(a, c, p, s) { - if (a < Math.abs(c)) { - a = c; - s = p / 4; - } - else { - //handle the 0/0 case: - if (c === 0 && a === 0) { - s = p / (2 * Math.PI) * Math.asin(1); - } - else { - s = p / (2 * Math.PI) * Math.asin(c / a); - } - } - return { a: a, c: c, p: p, s: s }; - } - - function elastic(opts, t, d) { - return opts.a * - Math.pow(2, 10 * (t -= 1)) * - Math.sin( (t * d - opts.s) * (2 * Math.PI) / opts.p ); - } - - /** - * Cubic easing out - * @memberOf fabric.util.ease - */ - function easeOutCubic(t, b, c, d) { - return c * ((t = t / d - 1) * t * t + 1) + b; - } - - /** - * Cubic easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutCubic(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return c / 2 * t * t * t + b; - } - return c / 2 * ((t -= 2) * t * t + 2) + b; - } - - /** - * Quartic easing in - * @memberOf fabric.util.ease - */ - function easeInQuart(t, b, c, d) { - return c * (t /= d) * t * t * t + b; - } - - /** - * Quartic easing out - * @memberOf fabric.util.ease - */ - function easeOutQuart(t, b, c, d) { - return -c * ((t = t / d - 1) * t * t * t - 1) + b; - } - - /** - * Quartic easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutQuart(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return c / 2 * t * t * t * t + b; - } - return -c / 2 * ((t -= 2) * t * t * t - 2) + b; - } - - /** - * Quintic easing in - * @memberOf fabric.util.ease - */ - function easeInQuint(t, b, c, d) { - return c * (t /= d) * t * t * t * t + b; - } - - /** - * Quintic easing out - * @memberOf fabric.util.ease - */ - function easeOutQuint(t, b, c, d) { - return c * ((t = t / d - 1) * t * t * t * t + 1) + b; - } - - /** - * Quintic easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutQuint(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return c / 2 * t * t * t * t * t + b; - } - return c / 2 * ((t -= 2) * t * t * t * t + 2) + b; - } - - /** - * Sinusoidal easing in - * @memberOf fabric.util.ease - */ - function easeInSine(t, b, c, d) { - return -c * Math.cos(t / d * (Math.PI / 2)) + c + b; - } - - /** - * Sinusoidal easing out - * @memberOf fabric.util.ease - */ - function easeOutSine(t, b, c, d) { - return c * Math.sin(t / d * (Math.PI / 2)) + b; - } - - /** - * Sinusoidal easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutSine(t, b, c, d) { - return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b; - } - - /** - * Exponential easing in - * @memberOf fabric.util.ease - */ - function easeInExpo(t, b, c, d) { - return (t === 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b; - } - - /** - * Exponential easing out - * @memberOf fabric.util.ease - */ - function easeOutExpo(t, b, c, d) { - return (t === d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b; - } - - /** - * Exponential easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutExpo(t, b, c, d) { - if (t === 0) { - return b; - } - if (t === d) { - return b + c; - } - t /= d / 2; - if (t < 1) { - return c / 2 * Math.pow(2, 10 * (t - 1)) + b; - } - return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b; - } - - /** - * Circular easing in - * @memberOf fabric.util.ease - */ - function easeInCirc(t, b, c, d) { - return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b; - } - - /** - * Circular easing out - * @memberOf fabric.util.ease - */ - function easeOutCirc(t, b, c, d) { - return c * Math.sqrt(1 - (t = t / d - 1) * t) + b; - } - - /** - * Circular easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutCirc(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b; - } - return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b; - } - - /** - * Elastic easing in - * @memberOf fabric.util.ease - */ - function easeInElastic(t, b, c, d) { - var s = 1.70158, p = 0, a = c; - if (t === 0) { - return b; - } - t /= d; - if (t === 1) { - return b + c; - } - if (!p) { - p = d * 0.3; - } - var opts = normalize(a, c, p, s); - return -elastic(opts, t, d) + b; - } - - /** - * Elastic easing out - * @memberOf fabric.util.ease - */ - function easeOutElastic(t, b, c, d) { - var s = 1.70158, p = 0, a = c; - if (t === 0) { - return b; - } - t /= d; - if (t === 1) { - return b + c; - } - if (!p) { - p = d * 0.3; - } - var opts = normalize(a, c, p, s); - return opts.a * Math.pow(2, -10 * t) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) + opts.c + b; - } - - /** - * Elastic easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutElastic(t, b, c, d) { - var s = 1.70158, p = 0, a = c; - if (t === 0) { - return b; - } - t /= d / 2; - if (t === 2) { - return b + c; - } - if (!p) { - p = d * (0.3 * 1.5); - } - var opts = normalize(a, c, p, s); - if (t < 1) { - return -0.5 * elastic(opts, t, d) + b; - } - return opts.a * Math.pow(2, -10 * (t -= 1)) * - Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) * 0.5 + opts.c + b; - } - - /** - * Backwards easing in - * @memberOf fabric.util.ease - */ - function easeInBack(t, b, c, d, s) { - if (s === undefined) { - s = 1.70158; - } - return c * (t /= d) * t * ((s + 1) * t - s) + b; - } - - /** - * Backwards easing out - * @memberOf fabric.util.ease - */ - function easeOutBack(t, b, c, d, s) { - if (s === undefined) { - s = 1.70158; - } - return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; - } - - /** - * Backwards easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutBack(t, b, c, d, s) { - if (s === undefined) { - s = 1.70158; - } - t /= d / 2; - if (t < 1) { - return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b; - } - return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b; - } - - /** - * Bouncing easing in - * @memberOf fabric.util.ease - */ - function easeInBounce(t, b, c, d) { - return c - easeOutBounce (d - t, 0, c, d) + b; - } - - /** - * Bouncing easing out - * @memberOf fabric.util.ease - */ - function easeOutBounce(t, b, c, d) { - if ((t /= d) < (1 / 2.75)) { - return c * (7.5625 * t * t) + b; - } - else if (t < (2 / 2.75)) { - return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b; - } - else if (t < (2.5 / 2.75)) { - return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b; - } - else { - return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b; - } - } - - /** - * Bouncing easing in and out - * @memberOf fabric.util.ease - */ - function easeInOutBounce(t, b, c, d) { - if (t < d / 2) { - return easeInBounce (t * 2, 0, c, d) * 0.5 + b; - } - return easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b; - } - - /** - * Easing functions - * See Easing Equations by Robert Penner - * @namespace fabric.util.ease - */ - fabric.util.ease = { - - /** - * Quadratic easing in - * @memberOf fabric.util.ease - */ - easeInQuad: function(t, b, c, d) { - return c * (t /= d) * t + b; - }, - - /** - * Quadratic easing out - * @memberOf fabric.util.ease - */ - easeOutQuad: function(t, b, c, d) { - return -c * (t /= d) * (t - 2) + b; - }, - - /** - * Quadratic easing in and out - * @memberOf fabric.util.ease - */ - easeInOutQuad: function(t, b, c, d) { - t /= (d / 2); - if (t < 1) { - return c / 2 * t * t + b; - } - return -c / 2 * ((--t) * (t - 2) - 1) + b; - }, - - /** - * Cubic easing in - * @memberOf fabric.util.ease - */ - easeInCubic: function(t, b, c, d) { - return c * (t /= d) * t * t + b; - }, - - easeOutCubic: easeOutCubic, - easeInOutCubic: easeInOutCubic, - easeInQuart: easeInQuart, - easeOutQuart: easeOutQuart, - easeInOutQuart: easeInOutQuart, - easeInQuint: easeInQuint, - easeOutQuint: easeOutQuint, - easeInOutQuint: easeInOutQuint, - easeInSine: easeInSine, - easeOutSine: easeOutSine, - easeInOutSine: easeInOutSine, - easeInExpo: easeInExpo, - easeOutExpo: easeOutExpo, - easeInOutExpo: easeInOutExpo, - easeInCirc: easeInCirc, - easeOutCirc: easeOutCirc, - easeInOutCirc: easeInOutCirc, - easeInElastic: easeInElastic, - easeOutElastic: easeOutElastic, - easeInOutElastic: easeInOutElastic, - easeInBack: easeInBack, - easeOutBack: easeOutBack, - easeInOutBack: easeInOutBack, - easeInBounce: easeInBounce, - easeOutBounce: easeOutBounce, - easeInOutBounce: easeInOutBounce - }; - -})(); - - -(function(global) { - - 'use strict'; - - /** - * @name fabric - * @namespace - */ - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - clone = fabric.util.object.clone, - toFixed = fabric.util.toFixed, - parseUnit = fabric.util.parseUnit, - multiplyTransformMatrices = fabric.util.multiplyTransformMatrices, - - svgValidTagNames = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line', - 'image', 'text'], - svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'], - svgInvalidAncestors = ['pattern', 'defs', 'symbol', 'metadata', 'clipPath', 'mask', 'desc'], - svgValidParents = ['symbol', 'g', 'a', 'svg', 'clipPath', 'defs'], - - attributesMap = { - cx: 'left', - x: 'left', - r: 'radius', - cy: 'top', - y: 'top', - display: 'visible', - visibility: 'visible', - transform: 'transformMatrix', - 'fill-opacity': 'fillOpacity', - 'fill-rule': 'fillRule', - 'font-family': 'fontFamily', - 'font-size': 'fontSize', - 'font-style': 'fontStyle', - 'font-weight': 'fontWeight', - 'letter-spacing': 'charSpacing', - 'paint-order': 'paintFirst', - 'stroke-dasharray': 'strokeDashArray', - 'stroke-dashoffset': 'strokeDashOffset', - 'stroke-linecap': 'strokeLineCap', - 'stroke-linejoin': 'strokeLineJoin', - 'stroke-miterlimit': 'strokeMiterLimit', - 'stroke-opacity': 'strokeOpacity', - 'stroke-width': 'strokeWidth', - 'text-decoration': 'textDecoration', - 'text-anchor': 'textAnchor', - opacity: 'opacity', - 'clip-path': 'clipPath', - 'clip-rule': 'clipRule', - 'vector-effect': 'strokeUniform', - 'image-rendering': 'imageSmoothing', - }, - - colorAttributes = { - stroke: 'strokeOpacity', - fill: 'fillOpacity' - }, - - fSize = 'font-size', cPath = 'clip-path'; - - fabric.svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames); - fabric.svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements); - fabric.svgInvalidAncestorsRegEx = getSvgRegex(svgInvalidAncestors); - fabric.svgValidParentsRegEx = getSvgRegex(svgValidParents); - - fabric.cssRules = { }; - fabric.gradientDefs = { }; - fabric.clipPaths = { }; - - function normalizeAttr(attr) { - // transform attribute names - if (attr in attributesMap) { - return attributesMap[attr]; - } - return attr; - } - - function normalizeValue(attr, value, parentAttributes, fontSize) { - var isArray = Array.isArray(value), parsed; - - if ((attr === 'fill' || attr === 'stroke') && value === 'none') { - value = ''; - } - else if (attr === 'strokeUniform') { - return (value === 'non-scaling-stroke'); - } - else if (attr === 'strokeDashArray') { - if (value === 'none') { - value = null; - } - else { - value = value.replace(/,/g, ' ').split(/\s+/).map(parseFloat); - } - } - else if (attr === 'transformMatrix') { - if (parentAttributes && parentAttributes.transformMatrix) { - value = multiplyTransformMatrices( - parentAttributes.transformMatrix, fabric.parseTransformAttribute(value)); - } - else { - value = fabric.parseTransformAttribute(value); - } - } - else if (attr === 'visible') { - value = value !== 'none' && value !== 'hidden'; - // display=none on parent element always takes precedence over child element - if (parentAttributes && parentAttributes.visible === false) { - value = false; - } - } - else if (attr === 'opacity') { - value = parseFloat(value); - if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') { - value *= parentAttributes.opacity; - } - } - else if (attr === 'textAnchor' /* text-anchor */) { - value = value === 'start' ? 'left' : value === 'end' ? 'right' : 'center'; - } - else if (attr === 'charSpacing') { - // parseUnit returns px and we convert it to em - parsed = parseUnit(value, fontSize) / fontSize * 1000; - } - else if (attr === 'paintFirst') { - var fillIndex = value.indexOf('fill'); - var strokeIndex = value.indexOf('stroke'); - var value = 'fill'; - if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) { - value = 'stroke'; - } - else if (fillIndex === -1 && strokeIndex > -1) { - value = 'stroke'; - } - } - else if (attr === 'href' || attr === 'xlink:href' || attr === 'font') { - return value; - } - else if (attr === 'imageSmoothing') { - return (value === 'optimizeQuality'); - } - else { - parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize); - } - - return (!isArray && isNaN(parsed) ? value : parsed); - } - - /** - * @private - */ - function getSvgRegex(arr) { - return new RegExp('^(' + arr.join('|') + ')\\b', 'i'); - } - - /** - * @private - * @param {Object} attributes Array of attributes to parse - */ - function _setStrokeFillOpacity(attributes) { - for (var attr in colorAttributes) { - - if (typeof attributes[colorAttributes[attr]] === 'undefined' || attributes[attr] === '') { - continue; - } - - if (typeof attributes[attr] === 'undefined') { - if (!fabric.Object.prototype[attr]) { - continue; - } - attributes[attr] = fabric.Object.prototype[attr]; - } - - if (attributes[attr].indexOf('url(') === 0) { - continue; - } - - var color = new fabric.Color(attributes[attr]); - attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttributes[attr]], 2)).toRgba(); - } - return attributes; - } - - /** - * @private - */ - function _getMultipleNodes(doc, nodeNames) { - var nodeName, nodeArray = [], nodeList, i, len; - for (i = 0, len = nodeNames.length; i < len; i++) { - nodeName = nodeNames[i]; - nodeList = doc.getElementsByTagName(nodeName); - nodeArray = nodeArray.concat(Array.prototype.slice.call(nodeList)); - } - return nodeArray; - } - - /** - * Parses "transform" attribute, returning an array of values - * @static - * @function - * @memberOf fabric - * @param {String} attributeValue String containing attribute value - * @return {Array} Array of 6 elements representing transformation matrix - */ - fabric.parseTransformAttribute = (function() { - function rotateMatrix(matrix, args) { - var cos = fabric.util.cos(args[0]), sin = fabric.util.sin(args[0]), - x = 0, y = 0; - if (args.length === 3) { - x = args[1]; - y = args[2]; - } - - matrix[0] = cos; - matrix[1] = sin; - matrix[2] = -sin; - matrix[3] = cos; - matrix[4] = x - (cos * x - sin * y); - matrix[5] = y - (sin * x + cos * y); - } - - function scaleMatrix(matrix, args) { - var multiplierX = args[0], - multiplierY = (args.length === 2) ? args[1] : args[0]; - - matrix[0] = multiplierX; - matrix[3] = multiplierY; - } - - function skewMatrix(matrix, args, pos) { - matrix[pos] = Math.tan(fabric.util.degreesToRadians(args[0])); - } - - function translateMatrix(matrix, args) { - matrix[4] = args[0]; - if (args.length === 2) { - matrix[5] = args[1]; - } - } - - // identity matrix - var iMatrix = fabric.iMatrix, - - // == begin transform regexp - number = fabric.reNum, - - commaWsp = fabric.commaWsp, - - skewX = '(?:(skewX)\\s*\\(\\s*(' + number + ')\\s*\\))', - - skewY = '(?:(skewY)\\s*\\(\\s*(' + number + ')\\s*\\))', - - rotate = '(?:(rotate)\\s*\\(\\s*(' + number + ')(?:' + - commaWsp + '(' + number + ')' + - commaWsp + '(' + number + '))?\\s*\\))', - - scale = '(?:(scale)\\s*\\(\\s*(' + number + ')(?:' + - commaWsp + '(' + number + '))?\\s*\\))', - - translate = '(?:(translate)\\s*\\(\\s*(' + number + ')(?:' + - commaWsp + '(' + number + '))?\\s*\\))', - - matrix = '(?:(matrix)\\s*\\(\\s*' + - '(' + number + ')' + commaWsp + - '(' + number + ')' + commaWsp + - '(' + number + ')' + commaWsp + - '(' + number + ')' + commaWsp + - '(' + number + ')' + commaWsp + - '(' + number + ')' + - '\\s*\\))', - - transform = '(?:' + - matrix + '|' + - translate + '|' + - scale + '|' + - rotate + '|' + - skewX + '|' + - skewY + - ')', - - transforms = '(?:' + transform + '(?:' + commaWsp + '*' + transform + ')*' + ')', - - transformList = '^\\s*(?:' + transforms + '?)\\s*$', - - // http://www.w3.org/TR/SVG/coords.html#TransformAttribute - reTransformList = new RegExp(transformList), - // == end transform regexp - - reTransform = new RegExp(transform, 'g'); - - return function(attributeValue) { - - // start with identity matrix - var matrix = iMatrix.concat(), - matrices = []; - - // return if no argument was given or - // an argument does not match transform attribute regexp - if (!attributeValue || (attributeValue && !reTransformList.test(attributeValue))) { - return matrix; - } - - attributeValue.replace(reTransform, function(match) { - - var m = new RegExp(transform).exec(match).filter(function (match) { - // match !== '' && match != null - return (!!match); - }), - operation = m[1], - args = m.slice(2).map(parseFloat); - - switch (operation) { - case 'translate': - translateMatrix(matrix, args); - break; - case 'rotate': - args[0] = fabric.util.degreesToRadians(args[0]); - rotateMatrix(matrix, args); - break; - case 'scale': - scaleMatrix(matrix, args); - break; - case 'skewX': - skewMatrix(matrix, args, 2); - break; - case 'skewY': - skewMatrix(matrix, args, 1); - break; - case 'matrix': - matrix = args; - break; - } - - // snapshot current matrix into matrices array - matrices.push(matrix.concat()); - // reset - matrix = iMatrix.concat(); - }); - - var combinedMatrix = matrices[0]; - while (matrices.length > 1) { - matrices.shift(); - combinedMatrix = fabric.util.multiplyTransformMatrices(combinedMatrix, matrices[0]); - } - return combinedMatrix; - }; - })(); - - /** - * @private - */ - function parseStyleString(style, oStyle) { - var attr, value; - style.replace(/;\s*$/, '').split(';').forEach(function (chunk) { - var pair = chunk.split(':'); - - attr = pair[0].trim().toLowerCase(); - value = pair[1].trim(); - - oStyle[attr] = value; - }); - } - - /** - * @private - */ - function parseStyleObject(style, oStyle) { - var attr, value; - for (var prop in style) { - if (typeof style[prop] === 'undefined') { - continue; - } - - attr = prop.toLowerCase(); - value = style[prop]; - - oStyle[attr] = value; - } - } - - /** - * @private - */ - function getGlobalStylesForElement(element, svgUid) { - var styles = { }; - for (var rule in fabric.cssRules[svgUid]) { - if (elementMatchesRule(element, rule.split(' '))) { - for (var property in fabric.cssRules[svgUid][rule]) { - styles[property] = fabric.cssRules[svgUid][rule][property]; - } - } - } - return styles; - } - - /** - * @private - */ - function elementMatchesRule(element, selectors) { - var firstMatching, parentMatching = true; - //start from rightmost selector. - firstMatching = selectorMatches(element, selectors.pop()); - if (firstMatching && selectors.length) { - parentMatching = doesSomeParentMatch(element, selectors); - } - return firstMatching && parentMatching && (selectors.length === 0); - } - - function doesSomeParentMatch(element, selectors) { - var selector, parentMatching = true; - while (element.parentNode && element.parentNode.nodeType === 1 && selectors.length) { - if (parentMatching) { - selector = selectors.pop(); - } - element = element.parentNode; - parentMatching = selectorMatches(element, selector); - } - return selectors.length === 0; - } - - /** - * @private - */ - function selectorMatches(element, selector) { - var nodeName = element.nodeName, - classNames = element.getAttribute('class'), - id = element.getAttribute('id'), matcher, i; - // i check if a selector matches slicing away part from it. - // if i get empty string i should match - matcher = new RegExp('^' + nodeName, 'i'); - selector = selector.replace(matcher, ''); - if (id && selector.length) { - matcher = new RegExp('#' + id + '(?![a-zA-Z\\-]+)', 'i'); - selector = selector.replace(matcher, ''); - } - if (classNames && selector.length) { - classNames = classNames.split(' '); - for (i = classNames.length; i--;) { - matcher = new RegExp('\\.' + classNames[i] + '(?![a-zA-Z\\-]+)', 'i'); - selector = selector.replace(matcher, ''); - } - } - return selector.length === 0; - } - - /** - * @private - * to support IE8 missing getElementById on SVGdocument and on node xmlDOM - */ - function elementById(doc, id) { - var el; - doc.getElementById && (el = doc.getElementById(id)); - if (el) { - return el; - } - var node, i, len, nodelist = doc.getElementsByTagName('*'); - for (i = 0, len = nodelist.length; i < len; i++) { - node = nodelist[i]; - if (id === node.getAttribute('id')) { - return node; - } - } - } - - /** - * @private - */ - function parseUseDirectives(doc) { - var nodelist = _getMultipleNodes(doc, ['use', 'svg:use']), i = 0; - while (nodelist.length && i < nodelist.length) { - var el = nodelist[i], - xlinkAttribute = el.getAttribute('xlink:href') || el.getAttribute('href'); - - if (xlinkAttribute === null) { - return; - } - - var xlink = xlinkAttribute.slice(1), - x = el.getAttribute('x') || 0, - y = el.getAttribute('y') || 0, - el2 = elementById(doc, xlink).cloneNode(true), - currentTrans = (el2.getAttribute('transform') || '') + ' translate(' + x + ', ' + y + ')', - parentNode, - oldLength = nodelist.length, attr, - j, - attrs, - len, - namespace = fabric.svgNS; - - applyViewboxTransform(el2); - if (/^svg$/i.test(el2.nodeName)) { - var el3 = el2.ownerDocument.createElementNS(namespace, 'g'); - for (j = 0, attrs = el2.attributes, len = attrs.length; j < len; j++) { - attr = attrs.item(j); - el3.setAttributeNS(namespace, attr.nodeName, attr.nodeValue); - } - // el2.firstChild != null - while (el2.firstChild) { - el3.appendChild(el2.firstChild); - } - el2 = el3; - } - - for (j = 0, attrs = el.attributes, len = attrs.length; j < len; j++) { - attr = attrs.item(j); - if (attr.nodeName === 'x' || attr.nodeName === 'y' || - attr.nodeName === 'xlink:href' || attr.nodeName === 'href') { - continue; - } - - if (attr.nodeName === 'transform') { - currentTrans = attr.nodeValue + ' ' + currentTrans; - } - else { - el2.setAttribute(attr.nodeName, attr.nodeValue); - } - } - - el2.setAttribute('transform', currentTrans); - el2.setAttribute('instantiated_by_use', '1'); - el2.removeAttribute('id'); - parentNode = el.parentNode; - parentNode.replaceChild(el2, el); - // some browsers do not shorten nodelist after replaceChild (IE8) - if (nodelist.length === oldLength) { - i++; - } - } - } - - // http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute - // matches, e.g.: +14.56e-12, etc. - var reViewBoxAttrValue = new RegExp( - '^' + - '\\s*(' + fabric.reNum + '+)\\s*,?' + - '\\s*(' + fabric.reNum + '+)\\s*,?' + - '\\s*(' + fabric.reNum + '+)\\s*,?' + - '\\s*(' + fabric.reNum + '+)\\s*' + - '$' - ); - - /** - * Add a element that envelop all child elements and makes the viewbox transformMatrix descend on all elements - */ - function applyViewboxTransform(element) { - if (!fabric.svgViewBoxElementsRegEx.test(element.nodeName)) { - return {}; - } - var viewBoxAttr = element.getAttribute('viewBox'), - scaleX = 1, - scaleY = 1, - minX = 0, - minY = 0, - viewBoxWidth, viewBoxHeight, matrix, el, - widthAttr = element.getAttribute('width'), - heightAttr = element.getAttribute('height'), - x = element.getAttribute('x') || 0, - y = element.getAttribute('y') || 0, - preserveAspectRatio = element.getAttribute('preserveAspectRatio') || '', - missingViewBox = (!viewBoxAttr || !(viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue))), - missingDimAttr = (!widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%'), - toBeParsed = missingViewBox && missingDimAttr, - parsedDim = { }, translateMatrix = '', widthDiff = 0, heightDiff = 0; - - parsedDim.width = 0; - parsedDim.height = 0; - parsedDim.toBeParsed = toBeParsed; - - if (missingViewBox) { - if (((x || y) && element.parentNode && element.parentNode.nodeName !== '#document')) { - translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') '; - matrix = (element.getAttribute('transform') || '') + translateMatrix; - element.setAttribute('transform', matrix); - element.removeAttribute('x'); - element.removeAttribute('y'); - } - } - - if (toBeParsed) { - return parsedDim; - } - - if (missingViewBox) { - parsedDim.width = parseUnit(widthAttr); - parsedDim.height = parseUnit(heightAttr); - // set a transform for elements that have x y and are inner(only) SVGs - return parsedDim; - } - minX = -parseFloat(viewBoxAttr[1]); - minY = -parseFloat(viewBoxAttr[2]); - viewBoxWidth = parseFloat(viewBoxAttr[3]); - viewBoxHeight = parseFloat(viewBoxAttr[4]); - parsedDim.minX = minX; - parsedDim.minY = minY; - parsedDim.viewBoxWidth = viewBoxWidth; - parsedDim.viewBoxHeight = viewBoxHeight; - if (!missingDimAttr) { - parsedDim.width = parseUnit(widthAttr); - parsedDim.height = parseUnit(heightAttr); - scaleX = parsedDim.width / viewBoxWidth; - scaleY = parsedDim.height / viewBoxHeight; - } - else { - parsedDim.width = viewBoxWidth; - parsedDim.height = viewBoxHeight; - } - - // default is to preserve aspect ratio - preserveAspectRatio = fabric.util.parsePreserveAspectRatioAttribute(preserveAspectRatio); - if (preserveAspectRatio.alignX !== 'none') { - //translate all container for the effect of Mid, Min, Max - if (preserveAspectRatio.meetOrSlice === 'meet') { - scaleY = scaleX = (scaleX > scaleY ? scaleY : scaleX); - // calculate additional translation to move the viewbox - } - if (preserveAspectRatio.meetOrSlice === 'slice') { - scaleY = scaleX = (scaleX > scaleY ? scaleX : scaleY); - // calculate additional translation to move the viewbox - } - widthDiff = parsedDim.width - viewBoxWidth * scaleX; - heightDiff = parsedDim.height - viewBoxHeight * scaleX; - if (preserveAspectRatio.alignX === 'Mid') { - widthDiff /= 2; - } - if (preserveAspectRatio.alignY === 'Mid') { - heightDiff /= 2; - } - if (preserveAspectRatio.alignX === 'Min') { - widthDiff = 0; - } - if (preserveAspectRatio.alignY === 'Min') { - heightDiff = 0; - } - } - - if (scaleX === 1 && scaleY === 1 && minX === 0 && minY === 0 && x === 0 && y === 0) { - return parsedDim; - } - if ((x || y) && element.parentNode.nodeName !== '#document') { - translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') '; - } - - matrix = translateMatrix + ' matrix(' + scaleX + - ' 0' + - ' 0 ' + - scaleY + ' ' + - (minX * scaleX + widthDiff) + ' ' + - (minY * scaleY + heightDiff) + ') '; - // seems unused. - // parsedDim.viewboxTransform = fabric.parseTransformAttribute(matrix); - if (element.nodeName === 'svg') { - el = element.ownerDocument.createElementNS(fabric.svgNS, 'g'); - // element.firstChild != null - while (element.firstChild) { - el.appendChild(element.firstChild); - } - element.appendChild(el); - } - else { - el = element; - el.removeAttribute('x'); - el.removeAttribute('y'); - matrix = el.getAttribute('transform') + matrix; - } - el.setAttribute('transform', matrix); - return parsedDim; - } - - function hasAncestorWithNodeName(element, nodeName) { - while (element && (element = element.parentNode)) { - if (element.nodeName && nodeName.test(element.nodeName.replace('svg:', '')) - && !element.getAttribute('instantiated_by_use')) { - return true; - } - } - return false; - } - - /** - * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback - * @static - * @function - * @memberOf fabric - * @param {SVGDocument} doc SVG document to parse - * @param {Function} callback Callback to call when parsing is finished; - * It's being passed an array of elements (parsed from a document). - * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created. - * @param {Object} [parsingOptions] options for parsing document - * @param {String} [parsingOptions.crossOrigin] crossOrigin settings - */ - fabric.parseSVGDocument = function(doc, callback, reviver, parsingOptions) { - if (!doc) { - return; - } - - parseUseDirectives(doc); - - var svgUid = fabric.Object.__uid++, i, len, - options = applyViewboxTransform(doc), - descendants = fabric.util.toArray(doc.getElementsByTagName('*')); - options.crossOrigin = parsingOptions && parsingOptions.crossOrigin; - options.svgUid = svgUid; - - if (descendants.length === 0 && fabric.isLikelyNode) { - // we're likely in node, where "o3-xml" library fails to gEBTN("*") - // https://github.com/ajaxorg/node-o3-xml/issues/21 - descendants = doc.selectNodes('//*[name(.)!="svg"]'); - var arr = []; - for (i = 0, len = descendants.length; i < len; i++) { - arr[i] = descendants[i]; - } - descendants = arr; - } - - var elements = descendants.filter(function(el) { - applyViewboxTransform(el); - return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', '')) && - !hasAncestorWithNodeName(el, fabric.svgInvalidAncestorsRegEx); // http://www.w3.org/TR/SVG/struct.html#DefsElement - }); - if (!elements || (elements && !elements.length)) { - callback && callback([], {}); - return; - } - var clipPaths = { }; - descendants.filter(function(el) { - return el.nodeName.replace('svg:', '') === 'clipPath'; - }).forEach(function(el) { - var id = el.getAttribute('id'); - clipPaths[id] = fabric.util.toArray(el.getElementsByTagName('*')).filter(function(el) { - return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', '')); - }); - }); - fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc); - fabric.cssRules[svgUid] = fabric.getCSSRules(doc); - fabric.clipPaths[svgUid] = clipPaths; - // Precedence of rules: style > class > attribute - fabric.parseElements(elements, function(instances, elements) { - if (callback) { - callback(instances, options, elements, descendants); - delete fabric.gradientDefs[svgUid]; - delete fabric.cssRules[svgUid]; - delete fabric.clipPaths[svgUid]; - } - }, clone(options), reviver, parsingOptions); - }; - - function recursivelyParseGradientsXlink(doc, gradient) { - var gradientsAttrs = ['gradientTransform', 'x1', 'x2', 'y1', 'y2', 'gradientUnits', 'cx', 'cy', 'r', 'fx', 'fy'], - xlinkAttr = 'xlink:href', - xLink = gradient.getAttribute(xlinkAttr).slice(1), - referencedGradient = elementById(doc, xLink); - if (referencedGradient && referencedGradient.getAttribute(xlinkAttr)) { - recursivelyParseGradientsXlink(doc, referencedGradient); - } - gradientsAttrs.forEach(function(attr) { - if (referencedGradient && !gradient.hasAttribute(attr) && referencedGradient.hasAttribute(attr)) { - gradient.setAttribute(attr, referencedGradient.getAttribute(attr)); - } - }); - if (!gradient.children.length) { - var referenceClone = referencedGradient.cloneNode(true); - while (referenceClone.firstChild) { - gradient.appendChild(referenceClone.firstChild); - } - } - gradient.removeAttribute(xlinkAttr); - } - - var reFontDeclaration = new RegExp( - '(normal|italic)?\\s*(normal|small-caps)?\\s*' + - '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*(' + - fabric.reNum + - '(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|' + fabric.reNum + '))?\\s+(.*)'); - - extend(fabric, { - /** - * Parses a short font declaration, building adding its properties to a style object - * @static - * @function - * @memberOf fabric - * @param {String} value font declaration - * @param {Object} oStyle definition - */ - parseFontDeclaration: function(value, oStyle) { - var match = value.match(reFontDeclaration); - - if (!match) { - return; - } - var fontStyle = match[1], - // font variant is not used - // fontVariant = match[2], - fontWeight = match[3], - fontSize = match[4], - lineHeight = match[5], - fontFamily = match[6]; - - if (fontStyle) { - oStyle.fontStyle = fontStyle; - } - if (fontWeight) { - oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight); - } - if (fontSize) { - oStyle.fontSize = parseUnit(fontSize); - } - if (fontFamily) { - oStyle.fontFamily = fontFamily; - } - if (lineHeight) { - oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight; - } - }, - - /** - * Parses an SVG document, returning all of the gradient declarations found in it - * @static - * @function - * @memberOf fabric - * @param {SVGDocument} doc SVG document to parse - * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element - */ - getGradientDefs: function(doc) { - var tagArray = [ - 'linearGradient', - 'radialGradient', - 'svg:linearGradient', - 'svg:radialGradient'], - elList = _getMultipleNodes(doc, tagArray), - el, j = 0, gradientDefs = { }; - j = elList.length; - while (j--) { - el = elList[j]; - if (el.getAttribute('xlink:href')) { - recursivelyParseGradientsXlink(doc, el); - } - gradientDefs[el.getAttribute('id')] = el; - } - return gradientDefs; - }, - - /** - * Returns an object of attributes' name/value, given element and an array of attribute names; - * Parses parent "g" nodes recursively upwards. - * @static - * @memberOf fabric - * @param {DOMElement} element Element to parse - * @param {Array} attributes Array of attributes to parse - * @return {Object} object containing parsed attributes' names/values - */ - parseAttributes: function(element, attributes, svgUid) { - - if (!element) { - return; - } - - var value, - parentAttributes = { }, - fontSize, parentFontSize; - - if (typeof svgUid === 'undefined') { - svgUid = element.getAttribute('svgUid'); - } - // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards - if (element.parentNode && fabric.svgValidParentsRegEx.test(element.parentNode.nodeName)) { - parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid); - } - - var ownAttributes = attributes.reduce(function(memo, attr) { - value = element.getAttribute(attr); - if (value) { // eslint-disable-line - memo[attr] = value; - } - return memo; - }, { }); - // add values parsed from style, which take precedence over attributes - // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes) - var cssAttrs = extend( - getGlobalStylesForElement(element, svgUid), - fabric.parseStyleAttribute(element) - ); - ownAttributes = extend( - ownAttributes, - cssAttrs - ); - if (cssAttrs[cPath]) { - element.setAttribute(cPath, cssAttrs[cPath]); - } - fontSize = parentFontSize = parentAttributes.fontSize || fabric.Text.DEFAULT_SVG_FONT_SIZE; - if (ownAttributes[fSize]) { - // looks like the minimum should be 9px when dealing with ems. this is what looks like in browsers. - ownAttributes[fSize] = fontSize = parseUnit(ownAttributes[fSize], parentFontSize); - } - - var normalizedAttr, normalizedValue, normalizedStyle = {}; - for (var attr in ownAttributes) { - normalizedAttr = normalizeAttr(attr); - normalizedValue = normalizeValue(normalizedAttr, ownAttributes[attr], parentAttributes, fontSize); - normalizedStyle[normalizedAttr] = normalizedValue; - } - if (normalizedStyle && normalizedStyle.font) { - fabric.parseFontDeclaration(normalizedStyle.font, normalizedStyle); - } - var mergedAttrs = extend(parentAttributes, normalizedStyle); - return fabric.svgValidParentsRegEx.test(element.nodeName) ? mergedAttrs : _setStrokeFillOpacity(mergedAttrs); - }, - - /** - * Transforms an array of svg elements to corresponding fabric.* instances - * @static - * @memberOf fabric - * @param {Array} elements Array of elements to parse - * @param {Function} callback Being passed an array of fabric instances (transformed from SVG elements) - * @param {Object} [options] Options object - * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created. - */ - parseElements: function(elements, callback, options, reviver, parsingOptions) { - new fabric.ElementsParser(elements, callback, options, reviver, parsingOptions).parse(); - }, - - /** - * Parses "style" attribute, retuning an object with values - * @static - * @memberOf fabric - * @param {SVGElement} element Element to parse - * @return {Object} Objects with values parsed from style attribute of an element - */ - parseStyleAttribute: function(element) { - var oStyle = { }, - style = element.getAttribute('style'); - - if (!style) { - return oStyle; - } - - if (typeof style === 'string') { - parseStyleString(style, oStyle); - } - else { - parseStyleObject(style, oStyle); - } - - return oStyle; - }, - - /** - * Parses "points" attribute, returning an array of values - * @static - * @memberOf fabric - * @param {String} points points attribute string - * @return {Array} array of points - */ - parsePointsAttribute: function(points) { - - // points attribute is required and must not be empty - if (!points) { - return null; - } - - // replace commas with whitespace and remove bookending whitespace - points = points.replace(/,/g, ' ').trim(); - - points = points.split(/\s+/); - var parsedPoints = [], i, len; - - for (i = 0, len = points.length; i < len; i += 2) { - parsedPoints.push({ - x: parseFloat(points[i]), - y: parseFloat(points[i + 1]) - }); - } - - // odd number of points is an error - // if (parsedPoints.length % 2 !== 0) { - // return null; - // } - - return parsedPoints; - }, - - /** - * Returns CSS rules for a given SVG document - * @static - * @function - * @memberOf fabric - * @param {SVGDocument} doc SVG document to parse - * @return {Object} CSS rules of this document - */ - getCSSRules: function(doc) { - var styles = doc.getElementsByTagName('style'), i, len, - allRules = { }, rules; - - // very crude parsing of style contents - for (i = 0, len = styles.length; i < len; i++) { - var styleContents = styles[i].textContent; - - // remove comments - styleContents = styleContents.replace(/\/\*[\s\S]*?\*\//g, ''); - if (styleContents.trim() === '') { - continue; - } - // recovers all the rule in this form `body { style code... }` - // rules = styleContents.match(/[^{]*\{[\s\S]*?\}/g); - rules = styleContents.split('}'); - // remove empty rules. - rules = rules.filter(function(rule) { return rule.trim(); }); - // at this point we have hopefully an array of rules `body { style code... ` - // eslint-disable-next-line no-loop-func - rules.forEach(function(rule) { - - var match = rule.split('{'), - ruleObj = { }, declaration = match[1].trim(), - propertyValuePairs = declaration.split(';').filter(function(pair) { return pair.trim(); }); - - for (i = 0, len = propertyValuePairs.length; i < len; i++) { - var pair = propertyValuePairs[i].split(':'), - property = pair[0].trim(), - value = pair[1].trim(); - ruleObj[property] = value; - } - rule = match[0].trim(); - rule.split(',').forEach(function(_rule) { - _rule = _rule.replace(/^svg/i, '').trim(); - if (_rule === '') { - return; - } - if (allRules[_rule]) { - fabric.util.object.extend(allRules[_rule], ruleObj); - } - else { - allRules[_rule] = fabric.util.object.clone(ruleObj); - } - }); - }); - } - return allRules; - }, - - /** - * Takes url corresponding to an SVG document, and parses it into a set of fabric objects. - * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy) - * @memberOf fabric - * @param {String} url - * @param {Function} callback - * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created. - * @param {Object} [options] Object containing options for parsing - * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources - */ - loadSVGFromURL: function(url, callback, reviver, options) { - - url = url.replace(/^\n\s*/, '').trim(); - new fabric.util.request(url, { - method: 'get', - onComplete: onComplete - }); - - function onComplete(r) { - - var xml = r.responseXML; - if (!xml || !xml.documentElement) { - callback && callback(null); - return false; - } - - fabric.parseSVGDocument(xml.documentElement, function (results, _options, elements, allElements) { - callback && callback(results, _options, elements, allElements); - }, reviver, options); - } - }, - - /** - * Takes string corresponding to an SVG document, and parses it into a set of fabric objects - * @memberOf fabric - * @param {String} string - * @param {Function} callback - * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created. - * @param {Object} [options] Object containing options for parsing - * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources - */ - loadSVGFromString: function(string, callback, reviver, options) { - var parser = new fabric.window.DOMParser(), - doc = parser.parseFromString(string.trim(), 'text/xml'); - fabric.parseSVGDocument(doc.documentElement, function (results, _options, elements, allElements) { - callback(results, _options, elements, allElements); - }, reviver, options); - } - }); - -})(typeof exports !== 'undefined' ? exports : this); - - -fabric.ElementsParser = function(elements, callback, options, reviver, parsingOptions, doc) { - this.elements = elements; - this.callback = callback; - this.options = options; - this.reviver = reviver; - this.svgUid = (options && options.svgUid) || 0; - this.parsingOptions = parsingOptions; - this.regexUrl = /^url\(['"]?#([^'"]+)['"]?\)/g; - this.doc = doc; -}; - -(function(proto) { - proto.parse = function() { - this.instances = new Array(this.elements.length); - this.numElements = this.elements.length; - this.createObjects(); - }; - - proto.createObjects = function() { - var _this = this; - this.elements.forEach(function(element, i) { - element.setAttribute('svgUid', _this.svgUid); - _this.createObject(element, i); - }); - }; - - proto.findTag = function(el) { - return fabric[fabric.util.string.capitalize(el.tagName.replace('svg:', ''))]; - }; - - proto.createObject = function(el, index) { - var klass = this.findTag(el); - if (klass && klass.fromElement) { - try { - klass.fromElement(el, this.createCallback(index, el), this.options); - } - catch (err) { - fabric.log(err); - } - } - else { - this.checkIfDone(); - } - }; - - proto.createCallback = function(index, el) { - var _this = this; - return function(obj) { - var _options; - _this.resolveGradient(obj, el, 'fill'); - _this.resolveGradient(obj, el, 'stroke'); - if (obj instanceof fabric.Image && obj._originalElement) { - _options = obj.parsePreserveAspectRatioAttribute(el); - } - obj._removeTransformMatrix(_options); - _this.resolveClipPath(obj, el); - _this.reviver && _this.reviver(el, obj); - _this.instances[index] = obj; - _this.checkIfDone(); - }; - }; - - proto.extractPropertyDefinition = function(obj, property, storage) { - var value = obj[property], regex = this.regexUrl; - if (!regex.test(value)) { - return; - } - regex.lastIndex = 0; - var id = regex.exec(value)[1]; - regex.lastIndex = 0; - return fabric[storage][this.svgUid][id]; - }; - - proto.resolveGradient = function(obj, el, property) { - var gradientDef = this.extractPropertyDefinition(obj, property, 'gradientDefs'); - if (gradientDef) { - var opacityAttr = el.getAttribute(property + '-opacity'); - var gradient = fabric.Gradient.fromElement(gradientDef, obj, opacityAttr, this.options); - obj.set(property, gradient); - } - }; - - proto.createClipPathCallback = function(obj, container) { - return function(_newObj) { - _newObj._removeTransformMatrix(); - _newObj.fillRule = _newObj.clipRule; - container.push(_newObj); - }; - }; - - proto.resolveClipPath = function(obj, usingElement) { - var clipPath = this.extractPropertyDefinition(obj, 'clipPath', 'clipPaths'), - element, klass, objTransformInv, container, gTransform, options; - if (clipPath) { - container = []; - objTransformInv = fabric.util.invertTransform(obj.calcTransformMatrix()); - // move the clipPath tag as sibling to the real element that is using it - var clipPathTag = clipPath[0].parentNode; - var clipPathOwner = usingElement; - while (clipPathOwner.parentNode && clipPathOwner.getAttribute('clip-path') !== obj.clipPath) { - clipPathOwner = clipPathOwner.parentNode; - } - clipPathOwner.parentNode.appendChild(clipPathTag); - for (var i = 0; i < clipPath.length; i++) { - element = clipPath[i]; - klass = this.findTag(element); - klass.fromElement( - element, - this.createClipPathCallback(obj, container), - this.options - ); - } - if (container.length === 1) { - clipPath = container[0]; - } - else { - clipPath = new fabric.Group(container); - } - gTransform = fabric.util.multiplyTransformMatrices( - objTransformInv, - clipPath.calcTransformMatrix() - ); - if (clipPath.clipPath) { - this.resolveClipPath(clipPath, clipPathOwner); - } - var options = fabric.util.qrDecompose(gTransform); - clipPath.flipX = false; - clipPath.flipY = false; - clipPath.set('scaleX', options.scaleX); - clipPath.set('scaleY', options.scaleY); - clipPath.angle = options.angle; - clipPath.skewX = options.skewX; - clipPath.skewY = 0; - clipPath.setPositionByOrigin({ x: options.translateX, y: options.translateY }, 'center', 'center'); - obj.clipPath = clipPath; - } - else { - // if clip-path does not resolve to any element, delete the property. - delete obj.clipPath; - } - }; - - proto.checkIfDone = function() { - if (--this.numElements === 0) { - this.instances = this.instances.filter(function(el) { - // eslint-disable-next-line no-eq-null, eqeqeq - return el != null; - }); - this.callback(this.instances, this.elements); - } - }; -})(fabric.ElementsParser.prototype); - - -(function(global) { - - 'use strict'; - - /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */ - - var fabric = global.fabric || (global.fabric = { }); - - if (fabric.Point) { - fabric.warn('fabric.Point is already defined'); - return; - } - - fabric.Point = Point; - - /** - * Point class - * @class fabric.Point - * @memberOf fabric - * @constructor - * @param {Number} x - * @param {Number} y - * @return {fabric.Point} thisArg - */ - function Point(x, y) { - this.x = x; - this.y = y; - } - - Point.prototype = /** @lends fabric.Point.prototype */ { - - type: 'point', - - constructor: Point, - - /** - * Adds another point to this one and returns another one - * @param {fabric.Point} that - * @return {fabric.Point} new Point instance with added values - */ - add: function (that) { - return new Point(this.x + that.x, this.y + that.y); - }, - - /** - * Adds another point to this one - * @param {fabric.Point} that - * @return {fabric.Point} thisArg - * @chainable - */ - addEquals: function (that) { - this.x += that.x; - this.y += that.y; - return this; - }, - - /** - * Adds value to this point and returns a new one - * @param {Number} scalar - * @return {fabric.Point} new Point with added value - */ - scalarAdd: function (scalar) { - return new Point(this.x + scalar, this.y + scalar); - }, - - /** - * Adds value to this point - * @param {Number} scalar - * @return {fabric.Point} thisArg - * @chainable - */ - scalarAddEquals: function (scalar) { - this.x += scalar; - this.y += scalar; - return this; - }, - - /** - * Subtracts another point from this point and returns a new one - * @param {fabric.Point} that - * @return {fabric.Point} new Point object with subtracted values - */ - subtract: function (that) { - return new Point(this.x - that.x, this.y - that.y); - }, - - /** - * Subtracts another point from this point - * @param {fabric.Point} that - * @return {fabric.Point} thisArg - * @chainable - */ - subtractEquals: function (that) { - this.x -= that.x; - this.y -= that.y; - return this; - }, - - /** - * Subtracts value from this point and returns a new one - * @param {Number} scalar - * @return {fabric.Point} - */ - scalarSubtract: function (scalar) { - return new Point(this.x - scalar, this.y - scalar); - }, - - /** - * Subtracts value from this point - * @param {Number} scalar - * @return {fabric.Point} thisArg - * @chainable - */ - scalarSubtractEquals: function (scalar) { - this.x -= scalar; - this.y -= scalar; - return this; - }, - - /** - * Multiplies this point by a value and returns a new one - * TODO: rename in scalarMultiply in 2.0 - * @param {Number} scalar - * @return {fabric.Point} - */ - multiply: function (scalar) { - return new Point(this.x * scalar, this.y * scalar); - }, - - /** - * Multiplies this point by a value - * TODO: rename in scalarMultiplyEquals in 2.0 - * @param {Number} scalar - * @return {fabric.Point} thisArg - * @chainable - */ - multiplyEquals: function (scalar) { - this.x *= scalar; - this.y *= scalar; - return this; - }, - - /** - * Divides this point by a value and returns a new one - * TODO: rename in scalarDivide in 2.0 - * @param {Number} scalar - * @return {fabric.Point} - */ - divide: function (scalar) { - return new Point(this.x / scalar, this.y / scalar); - }, - - /** - * Divides this point by a value - * TODO: rename in scalarDivideEquals in 2.0 - * @param {Number} scalar - * @return {fabric.Point} thisArg - * @chainable - */ - divideEquals: function (scalar) { - this.x /= scalar; - this.y /= scalar; - return this; - }, - - /** - * Returns true if this point is equal to another one - * @param {fabric.Point} that - * @return {Boolean} - */ - eq: function (that) { - return (this.x === that.x && this.y === that.y); - }, - - /** - * Returns true if this point is less than another one - * @param {fabric.Point} that - * @return {Boolean} - */ - lt: function (that) { - return (this.x < that.x && this.y < that.y); - }, - - /** - * Returns true if this point is less than or equal to another one - * @param {fabric.Point} that - * @return {Boolean} - */ - lte: function (that) { - return (this.x <= that.x && this.y <= that.y); - }, - - /** - - * Returns true if this point is greater another one - * @param {fabric.Point} that - * @return {Boolean} - */ - gt: function (that) { - return (this.x > that.x && this.y > that.y); - }, - - /** - * Returns true if this point is greater than or equal to another one - * @param {fabric.Point} that - * @return {Boolean} - */ - gte: function (that) { - return (this.x >= that.x && this.y >= that.y); - }, - - /** - * Returns new point which is the result of linear interpolation with this one and another one - * @param {fabric.Point} that - * @param {Number} t , position of interpolation, between 0 and 1 default 0.5 - * @return {fabric.Point} - */ - lerp: function (that, t) { - if (typeof t === 'undefined') { - t = 0.5; - } - t = Math.max(Math.min(1, t), 0); - return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t); - }, - - /** - * Returns distance from this point and another one - * @param {fabric.Point} that - * @return {Number} - */ - distanceFrom: function (that) { - var dx = this.x - that.x, - dy = this.y - that.y; - return Math.sqrt(dx * dx + dy * dy); - }, - - /** - * Returns the point between this point and another one - * @param {fabric.Point} that - * @return {fabric.Point} - */ - midPointFrom: function (that) { - return this.lerp(that); - }, - - /** - * Returns a new point which is the min of this and another one - * @param {fabric.Point} that - * @return {fabric.Point} - */ - min: function (that) { - return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y)); - }, - - /** - * Returns a new point which is the max of this and another one - * @param {fabric.Point} that - * @return {fabric.Point} - */ - max: function (that) { - return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y)); - }, - - /** - * Returns string representation of this point - * @return {String} - */ - toString: function () { - return this.x + ',' + this.y; - }, - - /** - * Sets x/y of this point - * @param {Number} x - * @param {Number} y - * @chainable - */ - setXY: function (x, y) { - this.x = x; - this.y = y; - return this; - }, - - /** - * Sets x of this point - * @param {Number} x - * @chainable - */ - setX: function (x) { - this.x = x; - return this; - }, - - /** - * Sets y of this point - * @param {Number} y - * @chainable - */ - setY: function (y) { - this.y = y; - return this; - }, - - /** - * Sets x/y of this point from another point - * @param {fabric.Point} that - * @chainable - */ - setFromPoint: function (that) { - this.x = that.x; - this.y = that.y; - return this; - }, - - /** - * Swaps x/y of this point and another point - * @param {fabric.Point} that - */ - swap: function (that) { - var x = this.x, - y = this.y; - this.x = that.x; - this.y = that.y; - that.x = x; - that.y = y; - }, - - /** - * return a cloned instance of the point - * @return {fabric.Point} - */ - clone: function () { - return new Point(this.x, this.y); - } - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */ - var fabric = global.fabric || (global.fabric = { }); - - if (fabric.Intersection) { - fabric.warn('fabric.Intersection is already defined'); - return; - } - - /** - * Intersection class - * @class fabric.Intersection - * @memberOf fabric - * @constructor - */ - function Intersection(status) { - this.status = status; - this.points = []; - } - - fabric.Intersection = Intersection; - - fabric.Intersection.prototype = /** @lends fabric.Intersection.prototype */ { - - constructor: Intersection, - - /** - * Appends a point to intersection - * @param {fabric.Point} point - * @return {fabric.Intersection} thisArg - * @chainable - */ - appendPoint: function (point) { - this.points.push(point); - return this; - }, - - /** - * Appends points to intersection - * @param {Array} points - * @return {fabric.Intersection} thisArg - * @chainable - */ - appendPoints: function (points) { - this.points = this.points.concat(points); - return this; - } - }; - - /** - * Checks if one line intersects another - * TODO: rename in intersectSegmentSegment - * @static - * @param {fabric.Point} a1 - * @param {fabric.Point} a2 - * @param {fabric.Point} b1 - * @param {fabric.Point} b2 - * @return {fabric.Intersection} - */ - fabric.Intersection.intersectLineLine = function (a1, a2, b1, b2) { - var result, - uaT = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x), - ubT = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x), - uB = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y); - if (uB !== 0) { - var ua = uaT / uB, - ub = ubT / uB; - if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) { - result = new Intersection('Intersection'); - result.appendPoint(new fabric.Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y))); - } - else { - result = new Intersection(); - } - } - else { - if (uaT === 0 || ubT === 0) { - result = new Intersection('Coincident'); - } - else { - result = new Intersection('Parallel'); - } - } - return result; - }; - - /** - * Checks if line intersects polygon - * TODO: rename in intersectSegmentPolygon - * fix detection of coincident - * @static - * @param {fabric.Point} a1 - * @param {fabric.Point} a2 - * @param {Array} points - * @return {fabric.Intersection} - */ - fabric.Intersection.intersectLinePolygon = function(a1, a2, points) { - var result = new Intersection(), - length = points.length, - b1, b2, inter, i; - - for (i = 0; i < length; i++) { - b1 = points[i]; - b2 = points[(i + 1) % length]; - inter = Intersection.intersectLineLine(a1, a2, b1, b2); - - result.appendPoints(inter.points); - } - if (result.points.length > 0) { - result.status = 'Intersection'; - } - return result; - }; - - /** - * Checks if polygon intersects another polygon - * @static - * @param {Array} points1 - * @param {Array} points2 - * @return {fabric.Intersection} - */ - fabric.Intersection.intersectPolygonPolygon = function (points1, points2) { - var result = new Intersection(), - length = points1.length, i; - - for (i = 0; i < length; i++) { - var a1 = points1[i], - a2 = points1[(i + 1) % length], - inter = Intersection.intersectLinePolygon(a1, a2, points2); - - result.appendPoints(inter.points); - } - if (result.points.length > 0) { - result.status = 'Intersection'; - } - return result; - }; - - /** - * Checks if polygon intersects rectangle - * @static - * @param {Array} points - * @param {fabric.Point} r1 - * @param {fabric.Point} r2 - * @return {fabric.Intersection} - */ - fabric.Intersection.intersectPolygonRectangle = function (points, r1, r2) { - var min = r1.min(r2), - max = r1.max(r2), - topRight = new fabric.Point(max.x, min.y), - bottomLeft = new fabric.Point(min.x, max.y), - inter1 = Intersection.intersectLinePolygon(min, topRight, points), - inter2 = Intersection.intersectLinePolygon(topRight, max, points), - inter3 = Intersection.intersectLinePolygon(max, bottomLeft, points), - inter4 = Intersection.intersectLinePolygon(bottomLeft, min, points), - result = new Intersection(); - - result.appendPoints(inter1.points); - result.appendPoints(inter2.points); - result.appendPoints(inter3.points); - result.appendPoints(inter4.points); - - if (result.points.length > 0) { - result.status = 'Intersection'; - } - return result; - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }); - - if (fabric.Color) { - fabric.warn('fabric.Color is already defined.'); - return; - } - - /** - * Color class - * The purpose of {@link fabric.Color} is to abstract and encapsulate common color operations; - * {@link fabric.Color} is a constructor and creates instances of {@link fabric.Color} objects. - * - * @class fabric.Color - * @param {String} color optional in hex or rgb(a) or hsl format or from known color list - * @return {fabric.Color} thisArg - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#colors} - */ - function Color(color) { - if (!color) { - this.setSource([0, 0, 0, 1]); - } - else { - this._tryParsingColor(color); - } - } - - fabric.Color = Color; - - fabric.Color.prototype = /** @lends fabric.Color.prototype */ { - - /** - * @private - * @param {String|Array} color Color value to parse - */ - _tryParsingColor: function(color) { - var source; - - if (color in Color.colorNameMap) { - color = Color.colorNameMap[color]; - } - - if (color === 'transparent') { - source = [255, 255, 255, 0]; - } - - if (!source) { - source = Color.sourceFromHex(color); - } - if (!source) { - source = Color.sourceFromRgb(color); - } - if (!source) { - source = Color.sourceFromHsl(color); - } - if (!source) { - //if color is not recognize let's make black as canvas does - source = [0, 0, 0, 1]; - } - if (source) { - this.setSource(source); - } - }, - - /** - * Adapted from https://github.com/mjijackson - * @private - * @param {Number} r Red color value - * @param {Number} g Green color value - * @param {Number} b Blue color value - * @return {Array} Hsl color - */ - _rgbToHsl: function(r, g, b) { - r /= 255; g /= 255; b /= 255; - - var h, s, l, - max = fabric.util.array.max([r, g, b]), - min = fabric.util.array.min([r, g, b]); - - l = (max + min) / 2; - - if (max === min) { - h = s = 0; // achromatic - } - else { - var d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - case g: - h = (b - r) / d + 2; - break; - case b: - h = (r - g) / d + 4; - break; - } - h /= 6; - } - - return [ - Math.round(h * 360), - Math.round(s * 100), - Math.round(l * 100) - ]; - }, - - /** - * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1]) - * @return {Array} - */ - getSource: function() { - return this._source; - }, - - /** - * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1]) - * @param {Array} source - */ - setSource: function(source) { - this._source = source; - }, - - /** - * Returns color representation in RGB format - * @return {String} ex: rgb(0-255,0-255,0-255) - */ - toRgb: function() { - var source = this.getSource(); - return 'rgb(' + source[0] + ',' + source[1] + ',' + source[2] + ')'; - }, - - /** - * Returns color representation in RGBA format - * @return {String} ex: rgba(0-255,0-255,0-255,0-1) - */ - toRgba: function() { - var source = this.getSource(); - return 'rgba(' + source[0] + ',' + source[1] + ',' + source[2] + ',' + source[3] + ')'; - }, - - /** - * Returns color representation in HSL format - * @return {String} ex: hsl(0-360,0%-100%,0%-100%) - */ - toHsl: function() { - var source = this.getSource(), - hsl = this._rgbToHsl(source[0], source[1], source[2]); - - return 'hsl(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%)'; - }, - - /** - * Returns color representation in HSLA format - * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1) - */ - toHsla: function() { - var source = this.getSource(), - hsl = this._rgbToHsl(source[0], source[1], source[2]); - - return 'hsla(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%,' + source[3] + ')'; - }, - - /** - * Returns color representation in HEX format - * @return {String} ex: FF5555 - */ - toHex: function() { - var source = this.getSource(), r, g, b; - - r = source[0].toString(16); - r = (r.length === 1) ? ('0' + r) : r; - - g = source[1].toString(16); - g = (g.length === 1) ? ('0' + g) : g; - - b = source[2].toString(16); - b = (b.length === 1) ? ('0' + b) : b; - - return r.toUpperCase() + g.toUpperCase() + b.toUpperCase(); - }, - - /** - * Returns color representation in HEXA format - * @return {String} ex: FF5555CC - */ - toHexa: function() { - var source = this.getSource(), a; - - a = Math.round(source[3] * 255); - a = a.toString(16); - a = (a.length === 1) ? ('0' + a) : a; - - return this.toHex() + a.toUpperCase(); - }, - - /** - * Gets value of alpha channel for this color - * @return {Number} 0-1 - */ - getAlpha: function() { - return this.getSource()[3]; - }, - - /** - * Sets value of alpha channel for this color - * @param {Number} alpha Alpha value 0-1 - * @return {fabric.Color} thisArg - */ - setAlpha: function(alpha) { - var source = this.getSource(); - source[3] = alpha; - this.setSource(source); - return this; - }, - - /** - * Transforms color to its grayscale representation - * @return {fabric.Color} thisArg - */ - toGrayscale: function() { - var source = this.getSource(), - average = parseInt((source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0), 10), - currentAlpha = source[3]; - this.setSource([average, average, average, currentAlpha]); - return this; - }, - - /** - * Transforms color to its black and white representation - * @param {Number} threshold - * @return {fabric.Color} thisArg - */ - toBlackWhite: function(threshold) { - var source = this.getSource(), - average = (source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0), - currentAlpha = source[3]; - - threshold = threshold || 127; - - average = (Number(average) < Number(threshold)) ? 0 : 255; - this.setSource([average, average, average, currentAlpha]); - return this; - }, - - /** - * Overlays color with another color - * @param {String|fabric.Color} otherColor - * @return {fabric.Color} thisArg - */ - overlayWith: function(otherColor) { - if (!(otherColor instanceof Color)) { - otherColor = new Color(otherColor); - } - - var result = [], - alpha = this.getAlpha(), - otherAlpha = 0.5, - source = this.getSource(), - otherSource = otherColor.getSource(), i; - - for (i = 0; i < 3; i++) { - result.push(Math.round((source[i] * (1 - otherAlpha)) + (otherSource[i] * otherAlpha))); - } - - result[3] = alpha; - this.setSource(result); - return this; - } - }; - - /** - * Regex matching color in RGB or RGBA formats (ex: rgb(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5)) - * @static - * @field - * @memberOf fabric.Color - */ - // eslint-disable-next-line max-len - fabric.Color.reRGBa = /^rgba?\(\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*(?:\s*,\s*((?:\d*\.?\d+)?)\s*)?\)$/i; - - /** - * Regex matching color in HSL or HSLA formats (ex: hsl(200, 80%, 10%), hsla(300, 50%, 80%, 0.5), hsla( 300 , 50% , 80% , 0.5 )) - * @static - * @field - * @memberOf fabric.Color - */ - fabric.Color.reHSLa = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3}\%)\s*,\s*(\d{1,3}\%)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/i; - - /** - * Regex matching color in HEX format (ex: #FF5544CC, #FF5555, 010155, aff) - * @static - * @field - * @memberOf fabric.Color - */ - fabric.Color.reHex = /^#?([0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{4}|[0-9a-f]{3})$/i; - - /** - * Map of the 148 color names with HEX code - * @static - * @field - * @memberOf fabric.Color - * @see: https://www.w3.org/TR/css3-color/#svg-color - */ - fabric.Color.colorNameMap = { - aliceblue: '#F0F8FF', - antiquewhite: '#FAEBD7', - aqua: '#00FFFF', - aquamarine: '#7FFFD4', - azure: '#F0FFFF', - beige: '#F5F5DC', - bisque: '#FFE4C4', - black: '#000000', - blanchedalmond: '#FFEBCD', - blue: '#0000FF', - blueviolet: '#8A2BE2', - brown: '#A52A2A', - burlywood: '#DEB887', - cadetblue: '#5F9EA0', - chartreuse: '#7FFF00', - chocolate: '#D2691E', - coral: '#FF7F50', - cornflowerblue: '#6495ED', - cornsilk: '#FFF8DC', - crimson: '#DC143C', - cyan: '#00FFFF', - darkblue: '#00008B', - darkcyan: '#008B8B', - darkgoldenrod: '#B8860B', - darkgray: '#A9A9A9', - darkgrey: '#A9A9A9', - darkgreen: '#006400', - darkkhaki: '#BDB76B', - darkmagenta: '#8B008B', - darkolivegreen: '#556B2F', - darkorange: '#FF8C00', - darkorchid: '#9932CC', - darkred: '#8B0000', - darksalmon: '#E9967A', - darkseagreen: '#8FBC8F', - darkslateblue: '#483D8B', - darkslategray: '#2F4F4F', - darkslategrey: '#2F4F4F', - darkturquoise: '#00CED1', - darkviolet: '#9400D3', - deeppink: '#FF1493', - deepskyblue: '#00BFFF', - dimgray: '#696969', - dimgrey: '#696969', - dodgerblue: '#1E90FF', - firebrick: '#B22222', - floralwhite: '#FFFAF0', - forestgreen: '#228B22', - fuchsia: '#FF00FF', - gainsboro: '#DCDCDC', - ghostwhite: '#F8F8FF', - gold: '#FFD700', - goldenrod: '#DAA520', - gray: '#808080', - grey: '#808080', - green: '#008000', - greenyellow: '#ADFF2F', - honeydew: '#F0FFF0', - hotpink: '#FF69B4', - indianred: '#CD5C5C', - indigo: '#4B0082', - ivory: '#FFFFF0', - khaki: '#F0E68C', - lavender: '#E6E6FA', - lavenderblush: '#FFF0F5', - lawngreen: '#7CFC00', - lemonchiffon: '#FFFACD', - lightblue: '#ADD8E6', - lightcoral: '#F08080', - lightcyan: '#E0FFFF', - lightgoldenrodyellow: '#FAFAD2', - lightgray: '#D3D3D3', - lightgrey: '#D3D3D3', - lightgreen: '#90EE90', - lightpink: '#FFB6C1', - lightsalmon: '#FFA07A', - lightseagreen: '#20B2AA', - lightskyblue: '#87CEFA', - lightslategray: '#778899', - lightslategrey: '#778899', - lightsteelblue: '#B0C4DE', - lightyellow: '#FFFFE0', - lime: '#00FF00', - limegreen: '#32CD32', - linen: '#FAF0E6', - magenta: '#FF00FF', - maroon: '#800000', - mediumaquamarine: '#66CDAA', - mediumblue: '#0000CD', - mediumorchid: '#BA55D3', - mediumpurple: '#9370DB', - mediumseagreen: '#3CB371', - mediumslateblue: '#7B68EE', - mediumspringgreen: '#00FA9A', - mediumturquoise: '#48D1CC', - mediumvioletred: '#C71585', - midnightblue: '#191970', - mintcream: '#F5FFFA', - mistyrose: '#FFE4E1', - moccasin: '#FFE4B5', - navajowhite: '#FFDEAD', - navy: '#000080', - oldlace: '#FDF5E6', - olive: '#808000', - olivedrab: '#6B8E23', - orange: '#FFA500', - orangered: '#FF4500', - orchid: '#DA70D6', - palegoldenrod: '#EEE8AA', - palegreen: '#98FB98', - paleturquoise: '#AFEEEE', - palevioletred: '#DB7093', - papayawhip: '#FFEFD5', - peachpuff: '#FFDAB9', - peru: '#CD853F', - pink: '#FFC0CB', - plum: '#DDA0DD', - powderblue: '#B0E0E6', - purple: '#800080', - rebeccapurple: '#663399', - red: '#FF0000', - rosybrown: '#BC8F8F', - royalblue: '#4169E1', - saddlebrown: '#8B4513', - salmon: '#FA8072', - sandybrown: '#F4A460', - seagreen: '#2E8B57', - seashell: '#FFF5EE', - sienna: '#A0522D', - silver: '#C0C0C0', - skyblue: '#87CEEB', - slateblue: '#6A5ACD', - slategray: '#708090', - slategrey: '#708090', - snow: '#FFFAFA', - springgreen: '#00FF7F', - steelblue: '#4682B4', - tan: '#D2B48C', - teal: '#008080', - thistle: '#D8BFD8', - tomato: '#FF6347', - turquoise: '#40E0D0', - violet: '#EE82EE', - wheat: '#F5DEB3', - white: '#FFFFFF', - whitesmoke: '#F5F5F5', - yellow: '#FFFF00', - yellowgreen: '#9ACD32' - }; - - /** - * @private - * @param {Number} p - * @param {Number} q - * @param {Number} t - * @return {Number} - */ - function hue2rgb(p, q, t) { - if (t < 0) { - t += 1; - } - if (t > 1) { - t -= 1; - } - if (t < 1 / 6) { - return p + (q - p) * 6 * t; - } - if (t < 1 / 2) { - return q; - } - if (t < 2 / 3) { - return p + (q - p) * (2 / 3 - t) * 6; - } - return p; - } - - /** - * Returns new color object, when given a color in RGB format - * @memberOf fabric.Color - * @param {String} color Color value ex: rgb(0-255,0-255,0-255) - * @return {fabric.Color} - */ - fabric.Color.fromRgb = function(color) { - return Color.fromSource(Color.sourceFromRgb(color)); - }; - - /** - * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format - * @memberOf fabric.Color - * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%) - * @return {Array} source - */ - fabric.Color.sourceFromRgb = function(color) { - var match = color.match(Color.reRGBa); - if (match) { - var r = parseInt(match[1], 10) / (/%$/.test(match[1]) ? 100 : 1) * (/%$/.test(match[1]) ? 255 : 1), - g = parseInt(match[2], 10) / (/%$/.test(match[2]) ? 100 : 1) * (/%$/.test(match[2]) ? 255 : 1), - b = parseInt(match[3], 10) / (/%$/.test(match[3]) ? 100 : 1) * (/%$/.test(match[3]) ? 255 : 1); - - return [ - parseInt(r, 10), - parseInt(g, 10), - parseInt(b, 10), - match[4] ? parseFloat(match[4]) : 1 - ]; - } - }; - - /** - * Returns new color object, when given a color in RGBA format - * @static - * @function - * @memberOf fabric.Color - * @param {String} color - * @return {fabric.Color} - */ - fabric.Color.fromRgba = Color.fromRgb; - - /** - * Returns new color object, when given a color in HSL format - * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%) - * @memberOf fabric.Color - * @return {fabric.Color} - */ - fabric.Color.fromHsl = function(color) { - return Color.fromSource(Color.sourceFromHsl(color)); - }; - - /** - * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format. - * Adapted from https://github.com/mjijackson - * @memberOf fabric.Color - * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1) - * @return {Array} source - * @see http://http://www.w3.org/TR/css3-color/#hsl-color - */ - fabric.Color.sourceFromHsl = function(color) { - var match = color.match(Color.reHSLa); - if (!match) { - return; - } - - var h = (((parseFloat(match[1]) % 360) + 360) % 360) / 360, - s = parseFloat(match[2]) / (/%$/.test(match[2]) ? 100 : 1), - l = parseFloat(match[3]) / (/%$/.test(match[3]) ? 100 : 1), - r, g, b; - - if (s === 0) { - r = g = b = l; - } - else { - var q = l <= 0.5 ? l * (s + 1) : l + s - l * s, - p = l * 2 - q; - - r = hue2rgb(p, q, h + 1 / 3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1 / 3); - } - - return [ - Math.round(r * 255), - Math.round(g * 255), - Math.round(b * 255), - match[4] ? parseFloat(match[4]) : 1 - ]; - }; - - /** - * Returns new color object, when given a color in HSLA format - * @static - * @function - * @memberOf fabric.Color - * @param {String} color - * @return {fabric.Color} - */ - fabric.Color.fromHsla = Color.fromHsl; - - /** - * Returns new color object, when given a color in HEX format - * @static - * @memberOf fabric.Color - * @param {String} color Color value ex: FF5555 - * @return {fabric.Color} - */ - fabric.Color.fromHex = function(color) { - return Color.fromSource(Color.sourceFromHex(color)); - }; - - /** - * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HEX format - * @static - * @memberOf fabric.Color - * @param {String} color ex: FF5555 or FF5544CC (RGBa) - * @return {Array} source - */ - fabric.Color.sourceFromHex = function(color) { - if (color.match(Color.reHex)) { - var value = color.slice(color.indexOf('#') + 1), - isShortNotation = (value.length === 3 || value.length === 4), - isRGBa = (value.length === 8 || value.length === 4), - r = isShortNotation ? (value.charAt(0) + value.charAt(0)) : value.substring(0, 2), - g = isShortNotation ? (value.charAt(1) + value.charAt(1)) : value.substring(2, 4), - b = isShortNotation ? (value.charAt(2) + value.charAt(2)) : value.substring(4, 6), - a = isRGBa ? (isShortNotation ? (value.charAt(3) + value.charAt(3)) : value.substring(6, 8)) : 'FF'; - - return [ - parseInt(r, 16), - parseInt(g, 16), - parseInt(b, 16), - parseFloat((parseInt(a, 16) / 255).toFixed(2)) - ]; - } - }; - - /** - * Returns new color object, when given color in array representation (ex: [200, 100, 100, 0.5]) - * @static - * @memberOf fabric.Color - * @param {Array} source - * @return {fabric.Color} - */ - fabric.Color.fromSource = function(source) { - var oColor = new Color(); - oColor.setSource(source); - return oColor; - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - scaleMap = ['e', 'se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e'], - skewMap = ['ns', 'nesw', 'ew', 'nwse'], - controls = {}, - LEFT = 'left', TOP = 'top', RIGHT = 'right', BOTTOM = 'bottom', CENTER = 'center', - opposite = { - top: BOTTOM, - bottom: TOP, - left: RIGHT, - right: LEFT, - center: CENTER, - }, radiansToDegrees = fabric.util.radiansToDegrees, - sign = (Math.sign || function(x) { return ((x > 0) - (x < 0)) || +x; }); - - /** - * Combine control position and object angle to find the control direction compared - * to the object center. - * @param {fabric.Object} fabricObject the fabric object for which we are rendering controls - * @param {fabric.Control} control the control class - * @return {Number} 0 - 7 a quadrant number - */ - function findCornerQuadrant(fabricObject, control) { - var cornerAngle = fabricObject.angle + radiansToDegrees(Math.atan2(control.y, control.x)) + 360; - return Math.round((cornerAngle % 360) / 45); - } - - function fireEvent(eventName, options) { - var target = options.transform.target, - canvas = target.canvas, - canvasOptions = fabric.util.object.clone(options); - canvasOptions.target = target; - canvas && canvas.fire('object:' + eventName, canvasOptions); - target.fire(eventName, options); - } - - /** - * Inspect event and fabricObject properties to understand if the scaling action - * @param {Event} eventData from the user action - * @param {fabric.Object} fabricObject the fabric object about to scale - * @return {Boolean} true if scale is proportional - */ - function scaleIsProportional(eventData, fabricObject) { - var canvas = fabricObject.canvas, uniScaleKey = canvas.uniScaleKey, - uniformIsToggled = eventData[uniScaleKey]; - return (canvas.uniformScaling && !uniformIsToggled) || - (!canvas.uniformScaling && uniformIsToggled); - } - - /** - * Checks if transform is centered - * @param {Object} transform transform data - * @return {Boolean} true if transform is centered - */ - function isTransformCentered(transform) { - return transform.originX === CENTER && transform.originY === CENTER; - } - - /** - * Inspect fabricObject to understand if the current scaling action is allowed - * @param {fabric.Object} fabricObject the fabric object about to scale - * @param {String} by 'x' or 'y' or '' - * @param {Boolean} scaleProportionally true if we are trying to scale proportionally - * @return {Boolean} true if scaling is not allowed at current conditions - */ - function scalingIsForbidden(fabricObject, by, scaleProportionally) { - var lockX = fabricObject.lockScalingX, lockY = fabricObject.lockScalingY; - if (lockX && lockY) { - return true; - } - if (!by && (lockX || lockY) && scaleProportionally) { - return true; - } - if (lockX && by === 'x') { - return true; - } - if (lockY && by === 'y') { - return true; - } - return false; - } - - /** - * return the correct cursor style for the scale action - * @param {Event} eventData the javascript event that is causing the scale - * @param {fabric.Control} control the control that is interested in the action - * @param {fabric.Object} fabricObject the fabric object that is interested in the action - * @return {String} a valid css string for the cursor - */ - function scaleCursorStyleHandler(eventData, control, fabricObject) { - var notAllowed = 'not-allowed', - scaleProportionally = scaleIsProportional(eventData, fabricObject), - by = ''; - if (control.x !== 0 && control.y === 0) { - by = 'x'; - } - else if (control.x === 0 && control.y !== 0) { - by = 'y'; - } - if (scalingIsForbidden(fabricObject, by, scaleProportionally)) { - return notAllowed; - } - var n = findCornerQuadrant(fabricObject, control); - return scaleMap[n] + '-resize'; - } - - /** - * return the correct cursor style for the skew action - * @param {Event} eventData the javascript event that is causing the scale - * @param {fabric.Control} control the control that is interested in the action - * @param {fabric.Object} fabricObject the fabric object that is interested in the action - * @return {String} a valid css string for the cursor - */ - function skewCursorStyleHandler(eventData, control, fabricObject) { - var notAllowed = 'not-allowed'; - if (control.x !== 0 && fabricObject.lockSkewingY) { - return notAllowed; - } - if (control.y !== 0 && fabricObject.lockSkewingX) { - return notAllowed; - } - var n = findCornerQuadrant(fabricObject, control) % 4; - return skewMap[n] + '-resize'; - } - - /** - * Combine skew and scale style handlers to cover fabric standard use case - * @param {Event} eventData the javascript event that is causing the scale - * @param {fabric.Control} control the control that is interested in the action - * @param {fabric.Object} fabricObject the fabric object that is interested in the action - * @return {String} a valid css string for the cursor - */ - function scaleSkewCursorStyleHandler(eventData, control, fabricObject) { - if (eventData[fabricObject.canvas.altActionKey]) { - return controls.skewCursorStyleHandler(eventData, control, fabricObject); - } - return controls.scaleCursorStyleHandler(eventData, control, fabricObject); - } - - /** - * Inspect event, control and fabricObject to return the correct action name - * @param {Event} eventData the javascript event that is causing the scale - * @param {fabric.Control} control the control that is interested in the action - * @param {fabric.Object} fabricObject the fabric object that is interested in the action - * @return {String} an action name - */ - function scaleOrSkewActionName(eventData, control, fabricObject) { - var isAlternative = eventData[fabricObject.canvas.altActionKey]; - if (control.x === 0) { - // then is scaleY or skewX - return isAlternative ? 'skewX' : 'scaleY'; - } - if (control.y === 0) { - // then is scaleY or skewX - return isAlternative ? 'skewY' : 'scaleX'; - } - } - - /** - * Find the correct style for the control that is used for rotation. - * this function is very simple and it just take care of not-allowed or standard cursor - * @param {Event} eventData the javascript event that is causing the scale - * @param {fabric.Control} control the control that is interested in the action - * @param {fabric.Object} fabricObject the fabric object that is interested in the action - * @return {String} a valid css string for the cursor - */ - function rotationStyleHandler(eventData, control, fabricObject) { - if (fabricObject.lockRotation) { - return 'not-allowed'; - } - return control.cursorStyle; - } - - function commonEventInfo(eventData, transform, x, y) { - return { - e: eventData, - transform: transform, - pointer: { - x: x, - y: y, - } - }; - } - - /** - * Wrap an action handler with saving/restoring object position on the transform. - * this is the code that permits to objects to keep their position while transforming. - * @param {Function} actionHandler the function to wrap - * @return {Function} a function with an action handler signature - */ - function wrapWithFixedAnchor(actionHandler) { - return function(eventData, transform, x, y) { - var target = transform.target, centerPoint = target.getCenterPoint(), - constraint = target.translateToOriginPoint(centerPoint, transform.originX, transform.originY), - actionPerformed = actionHandler(eventData, transform, x, y); - target.setPositionByOrigin(constraint, transform.originX, transform.originY); - return actionPerformed; - }; - } - - /** - * Wrap an action handler with firing an event if the action is performed - * @param {Function} actionHandler the function to wrap - * @return {Function} a function with an action handler signature - */ - function wrapWithFireEvent(eventName, actionHandler) { - return function(eventData, transform, x, y) { - var actionPerformed = actionHandler(eventData, transform, x, y); - if (actionPerformed) { - fireEvent(eventName, commonEventInfo(eventData, transform, x, y)); - } - return actionPerformed; - }; - } - - /** - * Transforms a point described by x and y in a distance from the top left corner of the object - * bounding box. - * @param {Object} transform - * @param {String} originX - * @param {String} originY - * @param {number} x - * @param {number} y - * @return {Fabric.Point} the normalized point - */ - function getLocalPoint(transform, originX, originY, x, y) { - var target = transform.target, - control = target.controls[transform.corner], - zoom = target.canvas.getZoom(), - padding = target.padding / zoom, - localPoint = target.toLocalPoint(new fabric.Point(x, y), originX, originY); - if (localPoint.x >= padding) { - localPoint.x -= padding; - } - if (localPoint.x <= -padding) { - localPoint.x += padding; - } - if (localPoint.y >= padding) { - localPoint.y -= padding; - } - if (localPoint.y <= padding) { - localPoint.y += padding; - } - localPoint.x -= control.offsetX; - localPoint.y -= control.offsetY; - return localPoint; - } - - /** - * Detect if the fabric object is flipped on one side. - * @param {fabric.Object} target - * @return {Boolean} true if one flip, but not two. - */ - function targetHasOneFlip(target) { - return target.flipX !== target.flipY; - } - - /** - * Utility function to compensate the scale factor when skew is applied on both axes - * @private - */ - function compensateScaleForSkew(target, oppositeSkew, scaleToCompensate, axis, reference) { - if (target[oppositeSkew] !== 0) { - var newDim = target._getTransformedDimensions()[axis]; - var newValue = reference / newDim * target[scaleToCompensate]; - target.set(scaleToCompensate, newValue); - } - } - - /** - * Action handler for skewing on the X axis - * @private - */ - function skewObjectX(eventData, transform, x, y) { - var target = transform.target, - // find how big the object would be, if there was no skewX. takes in account scaling - dimNoSkew = target._getTransformedDimensions(0, target.skewY), - localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y), - // the mouse is in the center of the object, and we want it to stay there. - // so the object will grow twice as much as the mouse. - // this makes the skew growth to localPoint * 2 - dimNoSkew. - totalSkewSize = Math.abs(localPoint.x * 2) - dimNoSkew.x, - currentSkew = target.skewX, newSkew; - if (totalSkewSize < 2) { - // let's make it easy to go back to position 0. - newSkew = 0; - } - else { - newSkew = radiansToDegrees( - Math.atan2((totalSkewSize / target.scaleX), (dimNoSkew.y / target.scaleY)) - ); - // now we have to find the sign of the skew. - // it mostly depend on the origin of transformation. - if (transform.originX === LEFT && transform.originY === BOTTOM) { - newSkew = -newSkew; - } - if (transform.originX === RIGHT && transform.originY === TOP) { - newSkew = -newSkew; - } - if (targetHasOneFlip(target)) { - newSkew = -newSkew; - } - } - var hasSkewed = currentSkew !== newSkew; - if (hasSkewed) { - var dimBeforeSkewing = target._getTransformedDimensions().y; - target.set('skewX', newSkew); - compensateScaleForSkew(target, 'skewY', 'scaleY', 'y', dimBeforeSkewing); - } - return hasSkewed; - } - - /** - * Action handler for skewing on the Y axis - * @private - */ - function skewObjectY(eventData, transform, x, y) { - var target = transform.target, - // find how big the object would be, if there was no skewX. takes in account scaling - dimNoSkew = target._getTransformedDimensions(target.skewX, 0), - localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y), - // the mouse is in the center of the object, and we want it to stay there. - // so the object will grow twice as much as the mouse. - // this makes the skew growth to localPoint * 2 - dimNoSkew. - totalSkewSize = Math.abs(localPoint.y * 2) - dimNoSkew.y, - currentSkew = target.skewY, newSkew; - if (totalSkewSize < 2) { - // let's make it easy to go back to position 0. - newSkew = 0; - } - else { - newSkew = radiansToDegrees( - Math.atan2((totalSkewSize / target.scaleY), (dimNoSkew.x / target.scaleX)) - ); - // now we have to find the sign of the skew. - // it mostly depend on the origin of transformation. - if (transform.originX === LEFT && transform.originY === BOTTOM) { - newSkew = -newSkew; - } - if (transform.originX === RIGHT && transform.originY === TOP) { - newSkew = -newSkew; - } - if (targetHasOneFlip(target)) { - newSkew = -newSkew; - } - } - var hasSkewed = currentSkew !== newSkew; - if (hasSkewed) { - var dimBeforeSkewing = target._getTransformedDimensions().x; - target.set('skewY', newSkew); - compensateScaleForSkew(target, 'skewX', 'scaleX', 'x', dimBeforeSkewing); - } - return hasSkewed; - } - - /** - * Wrapped Action handler for skewing on the Y axis, takes care of the - * skew direction and determine the correct transform origin for the anchor point - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - */ - function skewHandlerX(eventData, transform, x, y) { - // step1 figure out and change transform origin. - // if skewX > 0 and originY bottom we anchor on right - // if skewX > 0 and originY top we anchor on left - // if skewX < 0 and originY bottom we anchor on left - // if skewX < 0 and originY top we anchor on right - // if skewX is 0, we look for mouse position to understand where are we going. - var target = transform.target, currentSkew = target.skewX, originX, originY = transform.originY; - if (target.lockSkewingX) { - return false; - } - if (currentSkew === 0) { - var localPointFromCenter = getLocalPoint(transform, CENTER, CENTER, x, y); - if (localPointFromCenter.x > 0) { - // we are pulling right, anchor left; - originX = LEFT; - } - else { - // we are pulling right, anchor right - originX = RIGHT; - } - } - else { - if (currentSkew > 0) { - originX = originY === TOP ? LEFT : RIGHT; - } - if (currentSkew < 0) { - originX = originY === TOP ? RIGHT : LEFT; - } - // is the object flipped on one side only? swap the origin. - if (targetHasOneFlip(target)) { - originX = originX === LEFT ? RIGHT : LEFT; - } - } - - // once we have the origin, we find the anchor point - transform.originX = originX; - var finalHandler = wrapWithFireEvent('skewing', wrapWithFixedAnchor(skewObjectX)); - return finalHandler(eventData, transform, x, y); - } - - /** - * Wrapped Action handler for skewing on the Y axis, takes care of the - * skew direction and determine the correct transform origin for the anchor point - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - */ - function skewHandlerY(eventData, transform, x, y) { - // step1 figure out and change transform origin. - // if skewY > 0 and originX left we anchor on top - // if skewY > 0 and originX right we anchor on bottom - // if skewY < 0 and originX left we anchor on bottom - // if skewY < 0 and originX right we anchor on top - // if skewY is 0, we look for mouse position to understand where are we going. - var target = transform.target, currentSkew = target.skewY, originY, originX = transform.originX; - if (target.lockSkewingY) { - return false; - } - if (currentSkew === 0) { - var localPointFromCenter = getLocalPoint(transform, CENTER, CENTER, x, y); - if (localPointFromCenter.y > 0) { - // we are pulling down, anchor up; - originY = TOP; - } - else { - // we are pulling up, anchor down - originY = BOTTOM; - } - } - else { - if (currentSkew > 0) { - originY = originX === LEFT ? TOP : BOTTOM; - } - if (currentSkew < 0) { - originY = originX === LEFT ? BOTTOM : TOP; - } - // is the object flipped on one side only? swap the origin. - if (targetHasOneFlip(target)) { - originY = originY === TOP ? BOTTOM : TOP; - } - } - - // once we have the origin, we find the anchor point - transform.originY = originY; - var finalHandler = wrapWithFireEvent('skewing', wrapWithFixedAnchor(skewObjectY)); - return finalHandler(eventData, transform, x, y); - } - - /** - * Action handler for rotation and snapping, without anchor point. - * Needs to be wrapped with `wrapWithFixedAnchor` to be effective - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - * @private - */ - function rotationWithSnapping(eventData, transform, x, y) { - var t = transform, - target = t.target, - pivotPoint = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY); - - if (target.lockRotation) { - return false; - } - - var lastAngle = Math.atan2(t.ey - pivotPoint.y, t.ex - pivotPoint.x), - curAngle = Math.atan2(y - pivotPoint.y, x - pivotPoint.x), - angle = radiansToDegrees(curAngle - lastAngle + t.theta), - hasRotated = true; - - if (target.snapAngle > 0) { - var snapAngle = target.snapAngle, - snapThreshold = target.snapThreshold || snapAngle, - rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle, - leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle; - - if (Math.abs(angle - leftAngleLocked) < snapThreshold) { - angle = leftAngleLocked; - } - else if (Math.abs(angle - rightAngleLocked) < snapThreshold) { - angle = rightAngleLocked; - } - } - - // normalize angle to positive value - if (angle < 0) { - angle = 360 + angle; - } - angle %= 360; - - hasRotated = target.angle !== angle; - target.angle = angle; - return hasRotated; - } - - /** - * Basic scaling logic, reused with different constrain for scaling X,Y, freely or equally. - * Needs to be wrapped with `wrapWithFixedAnchor` to be effective - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @param {Object} options additional information for scaling - * @param {String} options.by 'x', 'y', 'equally' or '' to indicate type of scaling - * @return {Boolean} true if some change happened - * @private - */ - function scaleObject(eventData, transform, x, y, options) { - options = options || {}; - var target = transform.target, - lockScalingX = target.lockScalingX, lockScalingY = target.lockScalingY, - by = options.by, newPoint, scaleX, scaleY, dim, - scaleProportionally = scaleIsProportional(eventData, target), - forbidScaling = scalingIsForbidden(target, by, scaleProportionally), - signX, signY, gestureScale = transform.gestureScale; - - if (forbidScaling) { - return false; - } - if (gestureScale) { - scaleX = transform.scaleX * gestureScale; - scaleY = transform.scaleY * gestureScale; - } - else { - newPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y); - // use of sign: We use sign to detect change of direction of an action. sign usually change when - // we cross the origin point with the mouse. So a scale flip for example. There is an issue when scaling - // by center and scaling using one middle control ( default: mr, mt, ml, mb), the mouse movement can easily - // cross many time the origin point and flip the object. so we need a way to filter out the noise. - // This ternary here should be ok to filter out X scaling when we want Y only and vice versa. - signX = by !== 'y' ? sign(newPoint.x) : 1; - signY = by !== 'x' ? sign(newPoint.y) : 1; - if (!transform.signX) { - transform.signX = signX; - } - if (!transform.signY) { - transform.signY = signY; - } - - if (target.lockScalingFlip && - (transform.signX !== signX || transform.signY !== signY) - ) { - return false; - } - - dim = target._getTransformedDimensions(); - // missing detection of flip and logic to switch the origin - if (scaleProportionally && !by) { - // uniform scaling - var distance = Math.abs(newPoint.x) + Math.abs(newPoint.y), - original = transform.original, - originalDistance = Math.abs(dim.x * original.scaleX / target.scaleX) + - Math.abs(dim.y * original.scaleY / target.scaleY), - scale = distance / originalDistance; - scaleX = original.scaleX * scale; - scaleY = original.scaleY * scale; - } - else { - scaleX = Math.abs(newPoint.x * target.scaleX / dim.x); - scaleY = Math.abs(newPoint.y * target.scaleY / dim.y); - } - // if we are scaling by center, we need to double the scale - if (isTransformCentered(transform)) { - scaleX *= 2; - scaleY *= 2; - } - if (transform.signX !== signX && by !== 'y') { - transform.originX = opposite[transform.originX]; - scaleX *= -1; - transform.signX = signX; - } - if (transform.signY !== signY && by !== 'x') { - transform.originY = opposite[transform.originY]; - scaleY *= -1; - transform.signY = signY; - } - } - // minScale is taken are in the setter. - var oldScaleX = target.scaleX, oldScaleY = target.scaleY; - if (!by) { - !lockScalingX && target.set('scaleX', scaleX); - !lockScalingY && target.set('scaleY', scaleY); - } - else { - // forbidden cases already handled on top here. - by === 'x' && target.set('scaleX', scaleX); - by === 'y' && target.set('scaleY', scaleY); - } - return oldScaleX !== target.scaleX || oldScaleY !== target.scaleY; - } - - /** - * Generic scaling logic, to scale from corners either equally or freely. - * Needs to be wrapped with `wrapWithFixedAnchor` to be effective - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - */ - function scaleObjectFromCorner(eventData, transform, x, y) { - return scaleObject(eventData, transform, x, y); - } - - /** - * Scaling logic for the X axis. - * Needs to be wrapped with `wrapWithFixedAnchor` to be effective - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - */ - function scaleObjectX(eventData, transform, x, y) { - return scaleObject(eventData, transform, x, y , { by: 'x' }); - } - - /** - * Scaling logic for the Y axis. - * Needs to be wrapped with `wrapWithFixedAnchor` to be effective - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - */ - function scaleObjectY(eventData, transform, x, y) { - return scaleObject(eventData, transform, x, y , { by: 'y' }); - } - - /** - * Composed action handler to either scale Y or skew X - * Needs to be wrapped with `wrapWithFixedAnchor` to be effective - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - */ - function scalingYOrSkewingX(eventData, transform, x, y) { - // ok some safety needed here. - if (eventData[transform.target.canvas.altActionKey]) { - return controls.skewHandlerX(eventData, transform, x, y); - } - return controls.scalingY(eventData, transform, x, y); - } - - /** - * Composed action handler to either scale X or skew Y - * Needs to be wrapped with `wrapWithFixedAnchor` to be effective - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - */ - function scalingXOrSkewingY(eventData, transform, x, y) { - // ok some safety needed here. - if (eventData[transform.target.canvas.altActionKey]) { - return controls.skewHandlerY(eventData, transform, x, y); - } - return controls.scalingX(eventData, transform, x, y); - } - - /** - * Action handler to change textbox width - * Needs to be wrapped with `wrapWithFixedAnchor` to be effective - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if some change happened - */ - function changeWidth(eventData, transform, x, y) { - var target = transform.target, localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y), - strokePadding = target.strokeWidth / (target.strokeUniform ? target.scaleX : 1), - multiplier = isTransformCentered(transform) ? 2 : 1, - oldWidth = target.width, - newWidth = Math.abs(localPoint.x * multiplier / target.scaleX) - strokePadding; - target.set('width', Math.max(newWidth, 0)); - return oldWidth !== newWidth; - } - - /** - * Action handler - * @private - * @param {Event} eventData javascript event that is doing the transform - * @param {Object} transform javascript object containing a series of information around the current transform - * @param {number} x current mouse x position, canvas normalized - * @param {number} y current mouse y position, canvas normalized - * @return {Boolean} true if the translation occurred - */ - function dragHandler(eventData, transform, x, y) { - var target = transform.target, - newLeft = x - transform.offsetX, - newTop = y - transform.offsetY, - moveX = !target.get('lockMovementX') && target.left !== newLeft, - moveY = !target.get('lockMovementY') && target.top !== newTop; - moveX && target.set('left', newLeft); - moveY && target.set('top', newTop); - if (moveX || moveY) { - fireEvent('moving', commonEventInfo(eventData, transform, x, y)); - } - return moveX || moveY; - } - - controls.scaleCursorStyleHandler = scaleCursorStyleHandler; - controls.skewCursorStyleHandler = skewCursorStyleHandler; - controls.scaleSkewCursorStyleHandler = scaleSkewCursorStyleHandler; - controls.rotationWithSnapping = wrapWithFireEvent('rotating', wrapWithFixedAnchor(rotationWithSnapping)); - controls.scalingEqually = wrapWithFireEvent('scaling', wrapWithFixedAnchor( scaleObjectFromCorner)); - controls.scalingX = wrapWithFireEvent('scaling', wrapWithFixedAnchor(scaleObjectX)); - controls.scalingY = wrapWithFireEvent('scaling', wrapWithFixedAnchor(scaleObjectY)); - controls.scalingYOrSkewingX = scalingYOrSkewingX; - controls.scalingXOrSkewingY = scalingXOrSkewingY; - controls.changeWidth = wrapWithFireEvent('resizing', wrapWithFixedAnchor(changeWidth)); - controls.skewHandlerX = skewHandlerX; - controls.skewHandlerY = skewHandlerY; - controls.dragHandler = dragHandler; - controls.scaleOrSkewActionName = scaleOrSkewActionName; - controls.rotationStyleHandler = rotationStyleHandler; - controls.fireEvent = fireEvent; - controls.wrapWithFixedAnchor = wrapWithFixedAnchor; - controls.wrapWithFireEvent = wrapWithFireEvent; - controls.getLocalPoint = getLocalPoint; - fabric.controlsUtils = controls; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - degreesToRadians = fabric.util.degreesToRadians, - controls = fabric.controlsUtils; - - /** - * Render a round control, as per fabric features. - * This function is written to respect object properties like transparentCorners, cornerSize - * cornerColor, cornerStrokeColor - * plus the addition of offsetY and offsetX. - * @param {CanvasRenderingContext2D} ctx context to render on - * @param {Number} left x coordinate where the control center should be - * @param {Number} top y coordinate where the control center should be - * @param {Object} styleOverride override for fabric.Object controls style - * @param {fabric.Object} fabricObject the fabric object for which we are rendering controls - */ - function renderCircleControl (ctx, left, top, styleOverride, fabricObject) { - styleOverride = styleOverride || {}; - var xSize = this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize, - ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize, - transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ? - styleOverride.transparentCorners : fabricObject.transparentCorners, - methodName = transparentCorners ? 'stroke' : 'fill', - stroke = !transparentCorners && (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor), - myLeft = left, - myTop = top, size; - ctx.save(); - ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor; - ctx.strokeStyle = styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor; - // as soon as fabric react v5, remove ie11, use proper ellipse code. - if (xSize > ySize) { - size = xSize; - ctx.scale(1.0, ySize / xSize); - myTop = top * xSize / ySize; - } - else if (ySize > xSize) { - size = ySize; - ctx.scale(xSize / ySize, 1.0); - myLeft = left * ySize / xSize; - } - else { - size = xSize; - } - // this is still wrong - ctx.lineWidth = 1; - ctx.beginPath(); - ctx.arc(myLeft, myTop, size / 2, 0, 2 * Math.PI, false); - ctx[methodName](); - if (stroke) { - ctx.stroke(); - } - ctx.restore(); - } - - /** - * Render a square control, as per fabric features. - * This function is written to respect object properties like transparentCorners, cornerSize - * cornerColor, cornerStrokeColor - * plus the addition of offsetY and offsetX. - * @param {CanvasRenderingContext2D} ctx context to render on - * @param {Number} left x coordinate where the control center should be - * @param {Number} top y coordinate where the control center should be - * @param {Object} styleOverride override for fabric.Object controls style - * @param {fabric.Object} fabricObject the fabric object for which we are rendering controls - */ - function renderSquareControl(ctx, left, top, styleOverride, fabricObject) { - styleOverride = styleOverride || {}; - var xSize = this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize, - ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize, - transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ? - styleOverride.transparentCorners : fabricObject.transparentCorners, - methodName = transparentCorners ? 'stroke' : 'fill', - stroke = !transparentCorners && ( - styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor - ), xSizeBy2 = xSize / 2, ySizeBy2 = ySize / 2; - ctx.save(); - ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor; - ctx.strokeStyle = styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor; - // this is still wrong - ctx.lineWidth = 1; - ctx.translate(left, top); - ctx.rotate(degreesToRadians(fabricObject.angle)); - // this does not work, and fixed with ( && ) does not make sense. - // to have real transparent corners we need the controls on upperCanvas - // transparentCorners || ctx.clearRect(-xSizeBy2, -ySizeBy2, xSize, ySize); - ctx[methodName + 'Rect'](-xSizeBy2, -ySizeBy2, xSize, ySize); - if (stroke) { - ctx.strokeRect(-xSizeBy2, -ySizeBy2, xSize, ySize); - } - ctx.restore(); - } - - controls.renderCircleControl = renderCircleControl; - controls.renderSquareControl = renderSquareControl; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }); - - function Control(options) { - for (var i in options) { - this[i] = options[i]; - } - } - - fabric.Control = Control; - - fabric.Control.prototype = /** @lends fabric.Control.prototype */ { - - /** - * keep track of control visibility. - * mainly for backward compatibility. - * if you do not want to see a control, you can remove it - * from the controlset. - * @type {Boolean} - * @default true - */ - visible: true, - - /** - * Name of the action that the control will likely execute. - * This is optional. FabricJS uses to identify what the user is doing for some - * extra optimizations. If you are writing a custom control and you want to know - * somewhere else in the code what is going on, you can use this string here. - * you can also provide a custom getActionName if your control run multiple actions - * depending on some external state. - * default to scale since is the most common, used on 4 corners by default - * @type {String} - * @default 'scale' - */ - actionName: 'scale', - - /** - * Drawing angle of the control. - * NOT used for now, but name marked as needed for internal logic - * example: to reuse the same drawing function for different rotated controls - * @type {Number} - * @default 0 - */ - angle: 0, - - /** - * Relative position of the control. X - * 0,0 is the center of the Object, while -0.5 (left) or 0.5 (right) are the extremities - * of the bounding box. - * @type {Number} - * @default 0 - */ - x: 0, - - /** - * Relative position of the control. Y - * 0,0 is the center of the Object, while -0.5 (top) or 0.5 (bottom) are the extremities - * of the bounding box. - * @type {Number} - * @default 0 - */ - y: 0, - - /** - * Horizontal offset of the control from the defined position. In pixels - * Positive offset moves the control to the right, negative to the left. - * It used when you want to have position of control that does not scale with - * the bounding box. Example: rotation control is placed at x:0, y: 0.5 on - * the boundindbox, with an offset of 30 pixels vertically. Those 30 pixels will - * stay 30 pixels no matter how the object is big. Another example is having 2 - * controls in the corner, that stay in the same position when the object scale. - * of the bounding box. - * @type {Number} - * @default 0 - */ - offsetX: 0, - - /** - * Vertical offset of the control from the defined position. In pixels - * Positive offset moves the control to the bottom, negative to the top. - * @type {Number} - * @default 0 - */ - offsetY: 0, - - /** - * Sets the length of the control. If null, defaults to object's cornerSize. - * Expects both sizeX and sizeY to be set when set. - * @type {?Number} - * @default null - */ - sizeX: null, - - /** - * Sets the height of the control. If null, defaults to object's cornerSize. - * Expects both sizeX and sizeY to be set when set. - * @type {?Number} - * @default null - */ - sizeY: null, - - /** - * Sets the length of the touch area of the control. If null, defaults to object's touchCornerSize. - * Expects both touchSizeX and touchSizeY to be set when set. - * @type {?Number} - * @default null - */ - touchSizeX: null, - - /** - * Sets the height of the touch area of the control. If null, defaults to object's touchCornerSize. - * Expects both touchSizeX and touchSizeY to be set when set. - * @type {?Number} - * @default null - */ - touchSizeY: null, - - /** - * Css cursor style to display when the control is hovered. - * if the method `cursorStyleHandler` is provided, this property is ignored. - * @type {String} - * @default 'crosshair' - */ - cursorStyle: 'crosshair', - - /** - * If controls has an offsetY or offsetX, draw a line that connects - * the control to the bounding box - * @type {Boolean} - * @default false - */ - withConnection: false, - - /** - * The control actionHandler, provide one to handle action ( control being moved ) - * @param {Event} eventData the native mouse event - * @param {Object} transformData properties of the current transform - * @param {Number} x x position of the cursor - * @param {Number} y y position of the cursor - * @return {Boolean} true if the action/event modified the object - */ - actionHandler: function(/* eventData, transformData, x, y */) { }, - - /** - * The control handler for mouse down, provide one to handle mouse down on control - * @param {Event} eventData the native mouse event - * @param {Object} transformData properties of the current transform - * @param {Number} x x position of the cursor - * @param {Number} y y position of the cursor - * @return {Boolean} true if the action/event modified the object - */ - mouseDownHandler: function(/* eventData, transformData, x, y */) { }, - - /** - * The control mouseUpHandler, provide one to handle an effect on mouse up. - * @param {Event} eventData the native mouse event - * @param {Object} transformData properties of the current transform - * @param {Number} x x position of the cursor - * @param {Number} y y position of the cursor - * @return {Boolean} true if the action/event modified the object - */ - mouseUpHandler: function(/* eventData, transformData, x, y */) { }, - - /** - * Returns control actionHandler - * @param {Event} eventData the native mouse event - * @param {fabric.Object} fabricObject on which the control is displayed - * @param {fabric.Control} control control for which the action handler is being asked - * @return {Function} the action handler - */ - getActionHandler: function(/* eventData, fabricObject, control */) { - return this.actionHandler; - }, - - /** - * Returns control mouseDown handler - * @param {Event} eventData the native mouse event - * @param {fabric.Object} fabricObject on which the control is displayed - * @param {fabric.Control} control control for which the action handler is being asked - * @return {Function} the action handler - */ - getMouseDownHandler: function(/* eventData, fabricObject, control */) { - return this.mouseDownHandler; - }, - - /** - * Returns control mouseUp handler - * @param {Event} eventData the native mouse event - * @param {fabric.Object} fabricObject on which the control is displayed - * @param {fabric.Control} control control for which the action handler is being asked - * @return {Function} the action handler - */ - getMouseUpHandler: function(/* eventData, fabricObject, control */) { - return this.mouseUpHandler; - }, - - /** - * Returns control cursorStyle for css using cursorStyle. If you need a more elaborate - * function you can pass one in the constructor - * the cursorStyle property - * @param {Event} eventData the native mouse event - * @param {fabric.Control} control the current control ( likely this) - * @param {fabric.Object} object on which the control is displayed - * @return {String} - */ - cursorStyleHandler: function(eventData, control /* fabricObject */) { - return control.cursorStyle; - }, - - /** - * Returns the action name. The basic implementation just return the actionName property. - * @param {Event} eventData the native mouse event - * @param {fabric.Control} control the current control ( likely this) - * @param {fabric.Object} object on which the control is displayed - * @return {String} - */ - getActionName: function(eventData, control /* fabricObject */) { - return control.actionName; - }, - - /** - * Returns controls visibility - * @param {fabric.Object} object on which the control is displayed - * @param {String} controlKey key where the control is memorized on the - * @return {Boolean} - */ - getVisibility: function(fabricObject, controlKey) { - var objectVisibility = fabricObject._controlsVisibility; - if (objectVisibility && typeof objectVisibility[controlKey] !== 'undefined') { - return objectVisibility[controlKey]; - } - return this.visible; - }, - - /** - * Sets controls visibility - * @param {Boolean} visibility for the object - * @return {Void} - */ - setVisibility: function(visibility /* name, fabricObject */) { - this.visible = visibility; - }, - - - positionHandler: function(dim, finalMatrix /*, fabricObject, currentControl */) { - var point = fabric.util.transformPoint({ - x: this.x * dim.x + this.offsetX, - y: this.y * dim.y + this.offsetY }, finalMatrix); - return point; - }, - - /** - * Returns the coords for this control based on object values. - * @param {Number} objectAngle angle from the fabric object holding the control - * @param {Number} objectCornerSize cornerSize from the fabric object holding the control (or touchCornerSize if - * isTouch is true) - * @param {Number} centerX x coordinate where the control center should be - * @param {Number} centerY y coordinate where the control center should be - * @param {boolean} isTouch true if touch corner, false if normal corner - */ - calcCornerCoords: function(objectAngle, objectCornerSize, centerX, centerY, isTouch) { - var cosHalfOffset, - sinHalfOffset, - cosHalfOffsetComp, - sinHalfOffsetComp, - xSize = (isTouch) ? this.touchSizeX : this.sizeX, - ySize = (isTouch) ? this.touchSizeY : this.sizeY; - if (xSize && ySize && xSize !== ySize) { - // handle rectangular corners - var controlTriangleAngle = Math.atan2(ySize, xSize); - var cornerHypotenuse = Math.sqrt(xSize * xSize + ySize * ySize) / 2; - var newTheta = controlTriangleAngle - fabric.util.degreesToRadians(objectAngle); - var newThetaComp = Math.PI / 2 - controlTriangleAngle - fabric.util.degreesToRadians(objectAngle); - cosHalfOffset = cornerHypotenuse * fabric.util.cos(newTheta); - sinHalfOffset = cornerHypotenuse * fabric.util.sin(newTheta); - // use complementary angle for two corners - cosHalfOffsetComp = cornerHypotenuse * fabric.util.cos(newThetaComp); - sinHalfOffsetComp = cornerHypotenuse * fabric.util.sin(newThetaComp); - } - else { - // handle square corners - // use default object corner size unless size is defined - var cornerSize = (xSize && ySize) ? xSize : objectCornerSize; - /* 0.7071067812 stands for sqrt(2)/2 */ - cornerHypotenuse = cornerSize * 0.7071067812; - // complementary angles are equal since they're both 45 degrees - var newTheta = fabric.util.degreesToRadians(45 - objectAngle); - cosHalfOffset = cosHalfOffsetComp = cornerHypotenuse * fabric.util.cos(newTheta); - sinHalfOffset = sinHalfOffsetComp = cornerHypotenuse * fabric.util.sin(newTheta); - } - - return { - tl: { - x: centerX - sinHalfOffsetComp, - y: centerY - cosHalfOffsetComp, - }, - tr: { - x: centerX + cosHalfOffset, - y: centerY - sinHalfOffset, - }, - bl: { - x: centerX - cosHalfOffset, - y: centerY + sinHalfOffset, - }, - br: { - x: centerX + sinHalfOffsetComp, - y: centerY + cosHalfOffsetComp, - }, - }; - }, - - /** - * Render function for the control. - * When this function runs the context is unscaled. unrotate. Just retina scaled. - * all the functions will have to translate to the point left,top before starting Drawing - * if they want to draw a control where the position is detected. - * left and top are the result of the positionHandler function - * @param {RenderingContext2D} ctx the context where the control will be drawn - * @param {Number} left position of the canvas where we are about to render the control. - * @param {Number} top position of the canvas where we are about to render the control. - * @param {Object} styleOverride - * @param {fabric.Object} fabricObject the object where the control is about to be rendered - */ - render: function(ctx, left, top, styleOverride, fabricObject) { - styleOverride = styleOverride || {}; - switch (styleOverride.cornerStyle || fabricObject.cornerStyle) { - case 'circle': - fabric.controlsUtils.renderCircleControl.call(this, ctx, left, top, styleOverride, fabricObject); - break; - default: - fabric.controlsUtils.renderSquareControl.call(this, ctx, left, top, styleOverride, fabricObject); - } - }, - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function() { - - /* _FROM_SVG_START_ */ - function getColorStop(el, multiplier) { - var style = el.getAttribute('style'), - offset = el.getAttribute('offset') || 0, - color, colorAlpha, opacity, i; - - // convert percents to absolute values - offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1); - offset = offset < 0 ? 0 : offset > 1 ? 1 : offset; - if (style) { - var keyValuePairs = style.split(/\s*;\s*/); - - if (keyValuePairs[keyValuePairs.length - 1] === '') { - keyValuePairs.pop(); - } - - for (i = keyValuePairs.length; i--; ) { - - var split = keyValuePairs[i].split(/\s*:\s*/), - key = split[0].trim(), - value = split[1].trim(); - - if (key === 'stop-color') { - color = value; - } - else if (key === 'stop-opacity') { - opacity = value; - } - } - } - - if (!color) { - color = el.getAttribute('stop-color') || 'rgb(0,0,0)'; - } - if (!opacity) { - opacity = el.getAttribute('stop-opacity'); - } - - color = new fabric.Color(color); - colorAlpha = color.getAlpha(); - opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity); - opacity *= colorAlpha * multiplier; - - return { - offset: offset, - color: color.toRgb(), - opacity: opacity - }; - } - - function getLinearCoords(el) { - return { - x1: el.getAttribute('x1') || 0, - y1: el.getAttribute('y1') || 0, - x2: el.getAttribute('x2') || '100%', - y2: el.getAttribute('y2') || 0 - }; - } - - function getRadialCoords(el) { - return { - x1: el.getAttribute('fx') || el.getAttribute('cx') || '50%', - y1: el.getAttribute('fy') || el.getAttribute('cy') || '50%', - r1: 0, - x2: el.getAttribute('cx') || '50%', - y2: el.getAttribute('cy') || '50%', - r2: el.getAttribute('r') || '50%' - }; - } - /* _FROM_SVG_END_ */ - - var clone = fabric.util.object.clone; - - /** - * Gradient class - * @class fabric.Gradient - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients} - * @see {@link fabric.Gradient#initialize} for constructor definition - */ - fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ { - - /** - * Horizontal offset for aligning gradients coming from SVG when outside pathgroups - * @type Number - * @default 0 - */ - offsetX: 0, - - /** - * Vertical offset for aligning gradients coming from SVG when outside pathgroups - * @type Number - * @default 0 - */ - offsetY: 0, - - /** - * A transform matrix to apply to the gradient before painting. - * Imported from svg gradients, is not applied with the current transform in the center. - * Before this transform is applied, the origin point is at the top left corner of the object - * plus the addition of offsetY and offsetX. - * @type Number[] - * @default null - */ - gradientTransform: null, - - /** - * coordinates units for coords. - * If `pixels`, the number of coords are in the same unit of width / height. - * If set as `percentage` the coords are still a number, but 1 means 100% of width - * for the X and 100% of the height for the y. It can be bigger than 1 and negative. - * allowed values pixels or percentage. - * @type String - * @default 'pixels' - */ - gradientUnits: 'pixels', - - /** - * Gradient type linear or radial - * @type String - * @default 'pixels' - */ - type: 'linear', - - /** - * Constructor - * @param {Object} options Options object with type, coords, gradientUnits and colorStops - * @param {Object} [options.type] gradient type linear or radial - * @param {Object} [options.gradientUnits] gradient units - * @param {Object} [options.offsetX] SVG import compatibility - * @param {Object} [options.offsetY] SVG import compatibility - * @param {Object[]} options.colorStops contains the colorstops. - * @param {Object} options.coords contains the coords of the gradient - * @param {Number} [options.coords.x1] X coordiante of the first point for linear or of the focal point for radial - * @param {Number} [options.coords.y1] Y coordiante of the first point for linear or of the focal point for radial - * @param {Number} [options.coords.x2] X coordiante of the second point for linear or of the center point for radial - * @param {Number} [options.coords.y2] Y coordiante of the second point for linear or of the center point for radial - * @param {Number} [options.coords.r1] only for radial gradient, radius of the inner circle - * @param {Number} [options.coords.r2] only for radial gradient, radius of the external circle - * @return {fabric.Gradient} thisArg - */ - initialize: function(options) { - options || (options = { }); - options.coords || (options.coords = { }); - - var coords, _this = this; - - // sets everything, then coords and colorstops get sets again - Object.keys(options).forEach(function(option) { - _this[option] = options[option]; - }); - - if (this.id) { - this.id += '_' + fabric.Object.__uid++; - } - else { - this.id = fabric.Object.__uid++; - } - - coords = { - x1: options.coords.x1 || 0, - y1: options.coords.y1 || 0, - x2: options.coords.x2 || 0, - y2: options.coords.y2 || 0 - }; - - if (this.type === 'radial') { - coords.r1 = options.coords.r1 || 0; - coords.r2 = options.coords.r2 || 0; - } - - this.coords = coords; - this.colorStops = options.colorStops.slice(); - }, - - /** - * Adds another colorStop - * @param {Object} colorStop Object with offset and color - * @return {fabric.Gradient} thisArg - */ - addColorStop: function(colorStops) { - for (var position in colorStops) { - var color = new fabric.Color(colorStops[position]); - this.colorStops.push({ - offset: parseFloat(position), - color: color.toRgb(), - opacity: color.getAlpha() - }); - } - return this; - }, - - /** - * Returns object representation of a gradient - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} - */ - toObject: function(propertiesToInclude) { - var object = { - type: this.type, - coords: this.coords, - colorStops: this.colorStops, - offsetX: this.offsetX, - offsetY: this.offsetY, - gradientUnits: this.gradientUnits, - gradientTransform: this.gradientTransform ? this.gradientTransform.concat() : this.gradientTransform - }; - fabric.util.populateWithProperties(this, object, propertiesToInclude); - - return object; - }, - - /* _TO_SVG_START_ */ - /** - * Returns SVG representation of an gradient - * @param {Object} object Object to create a gradient for - * @return {String} SVG representation of an gradient (linear/radial) - */ - toSVG: function(object, options) { - var coords = clone(this.coords, true), i, len, options = options || {}, - markup, commonAttributes, colorStops = clone(this.colorStops, true), - needsSwap = coords.r1 > coords.r2, - transform = this.gradientTransform ? this.gradientTransform.concat() : fabric.iMatrix.concat(), - offsetX = -this.offsetX, offsetY = -this.offsetY, - withViewport = !!options.additionalTransform, - gradientUnits = this.gradientUnits === 'pixels' ? 'userSpaceOnUse' : 'objectBoundingBox'; - // colorStops must be sorted ascending - colorStops.sort(function(a, b) { - return a.offset - b.offset; - }); - - if (gradientUnits === 'objectBoundingBox') { - offsetX /= object.width; - offsetY /= object.height; - } - else { - offsetX += object.width / 2; - offsetY += object.height / 2; - } - if (object.type === 'path' && this.gradientUnits !== 'percentage') { - offsetX -= object.pathOffset.x; - offsetY -= object.pathOffset.y; - } - - - transform[4] -= offsetX; - transform[5] -= offsetY; - - commonAttributes = 'id="SVGID_' + this.id + - '" gradientUnits="' + gradientUnits + '"'; - commonAttributes += ' gradientTransform="' + (withViewport ? - options.additionalTransform + ' ' : '') + fabric.util.matrixToSVG(transform) + '" '; - - if (this.type === 'linear') { - markup = [ - '\n' - ]; - } - else if (this.type === 'radial') { - // svg radial gradient has just 1 radius. the biggest. - markup = [ - '\n' - ]; - } - - if (this.type === 'radial') { - if (needsSwap) { - // svg goes from internal to external radius. if radius are inverted, swap color stops. - colorStops = colorStops.concat(); - colorStops.reverse(); - for (i = 0, len = colorStops.length; i < len; i++) { - colorStops[i].offset = 1 - colorStops[i].offset; - } - } - var minRadius = Math.min(coords.r1, coords.r2); - if (minRadius > 0) { - // i have to shift all colorStops and add new one in 0. - var maxRadius = Math.max(coords.r1, coords.r2), - percentageShift = minRadius / maxRadius; - for (i = 0, len = colorStops.length; i < len; i++) { - colorStops[i].offset += percentageShift * (1 - colorStops[i].offset); - } - } - } - - for (i = 0, len = colorStops.length; i < len; i++) { - var colorStop = colorStops[i]; - markup.push( - '\n' - ); - } - - markup.push((this.type === 'linear' ? '\n' : '\n')); - - return markup.join(''); - }, - /* _TO_SVG_END_ */ - - /** - * Returns an instance of CanvasGradient - * @param {CanvasRenderingContext2D} ctx Context to render on - * @return {CanvasGradient} - */ - toLive: function(ctx) { - var gradient, coords = fabric.util.object.clone(this.coords), i, len; - - if (!this.type) { - return; - } - - if (this.type === 'linear') { - gradient = ctx.createLinearGradient( - coords.x1, coords.y1, coords.x2, coords.y2); - } - else if (this.type === 'radial') { - gradient = ctx.createRadialGradient( - coords.x1, coords.y1, coords.r1, coords.x2, coords.y2, coords.r2); - } - - for (i = 0, len = this.colorStops.length; i < len; i++) { - var color = this.colorStops[i].color, - opacity = this.colorStops[i].opacity, - offset = this.colorStops[i].offset; - - if (typeof opacity !== 'undefined') { - color = new fabric.Color(color).setAlpha(opacity).toRgba(); - } - gradient.addColorStop(offset, color); - } - - return gradient; - } - }); - - fabric.util.object.extend(fabric.Gradient, { - - /* _FROM_SVG_START_ */ - /** - * Returns {@link fabric.Gradient} instance from an SVG element - * @static - * @memberOf fabric.Gradient - * @param {SVGGradientElement} el SVG gradient element - * @param {fabric.Object} instance - * @param {String} opacityAttr A fill-opacity or stroke-opacity attribute to multiply to each stop's opacity. - * @param {Object} svgOptions an object containing the size of the SVG in order to parse correctly gradients - * that uses gradientUnits as 'userSpaceOnUse' and percentages. - * @param {Object.number} viewBoxWidth width part of the viewBox attribute on svg - * @param {Object.number} viewBoxHeight height part of the viewBox attribute on svg - * @param {Object.number} width width part of the svg tag if viewBox is not specified - * @param {Object.number} height height part of the svg tag if viewBox is not specified - * @return {fabric.Gradient} Gradient instance - * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement - * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement - */ - fromElement: function(el, instance, opacityAttr, svgOptions) { - /** - * @example: - * - * - * - * - * - * - * OR - * - * - * - * - * - * - * OR - * - * - * - * - * - * - * - * OR - * - * - * - * - * - * - * - */ - - var multiplier = parseFloat(opacityAttr) / (/%$/.test(opacityAttr) ? 100 : 1); - multiplier = multiplier < 0 ? 0 : multiplier > 1 ? 1 : multiplier; - if (isNaN(multiplier)) { - multiplier = 1; - } - - var colorStopEls = el.getElementsByTagName('stop'), - type, - gradientUnits = el.getAttribute('gradientUnits') === 'userSpaceOnUse' ? - 'pixels' : 'percentage', - gradientTransform = el.getAttribute('gradientTransform') || '', - colorStops = [], - coords, i, offsetX = 0, offsetY = 0, - transformMatrix; - if (el.nodeName === 'linearGradient' || el.nodeName === 'LINEARGRADIENT') { - type = 'linear'; - coords = getLinearCoords(el); - } - else { - type = 'radial'; - coords = getRadialCoords(el); - } - - for (i = colorStopEls.length; i--; ) { - colorStops.push(getColorStop(colorStopEls[i], multiplier)); - } - - transformMatrix = fabric.parseTransformAttribute(gradientTransform); - - __convertPercentUnitsToValues(instance, coords, svgOptions, gradientUnits); - - if (gradientUnits === 'pixels') { - offsetX = -instance.left; - offsetY = -instance.top; - } - - var gradient = new fabric.Gradient({ - id: el.getAttribute('id'), - type: type, - coords: coords, - colorStops: colorStops, - gradientUnits: gradientUnits, - gradientTransform: transformMatrix, - offsetX: offsetX, - offsetY: offsetY, - }); - - return gradient; - } - /* _FROM_SVG_END_ */ - }); - - /** - * @private - */ - function __convertPercentUnitsToValues(instance, options, svgOptions, gradientUnits) { - var propValue, finalValue; - Object.keys(options).forEach(function(prop) { - propValue = options[prop]; - if (propValue === 'Infinity') { - finalValue = 1; - } - else if (propValue === '-Infinity') { - finalValue = 0; - } - else { - finalValue = parseFloat(options[prop], 10); - if (typeof propValue === 'string' && /^(\d+\.\d+)%|(\d+)%$/.test(propValue)) { - finalValue *= 0.01; - if (gradientUnits === 'pixels') { - // then we need to fix those percentages here in svg parsing - if (prop === 'x1' || prop === 'x2' || prop === 'r2') { - finalValue *= svgOptions.viewBoxWidth || svgOptions.width; - } - if (prop === 'y1' || prop === 'y2') { - finalValue *= svgOptions.viewBoxHeight || svgOptions.height; - } - } - } - } - options[prop] = finalValue; - }); - } -})(); - - -(function() { - - 'use strict'; - - var toFixed = fabric.util.toFixed; - - /** - * Pattern class - * @class fabric.Pattern - * @see {@link http://fabricjs.com/patterns|Pattern demo} - * @see {@link http://fabricjs.com/dynamic-patterns|DynamicPattern demo} - * @see {@link fabric.Pattern#initialize} for constructor definition - */ - - - fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ { - - /** - * Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat) - * @type String - * @default - */ - repeat: 'repeat', - - /** - * Pattern horizontal offset from object's left/top corner - * @type Number - * @default - */ - offsetX: 0, - - /** - * Pattern vertical offset from object's left/top corner - * @type Number - * @default - */ - offsetY: 0, - - /** - * crossOrigin value (one of "", "anonymous", "use-credentials") - * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes - * @type String - * @default - */ - crossOrigin: '', - - /** - * transform matrix to change the pattern, imported from svgs. - * @type Array - * @default - */ - patternTransform: null, - - /** - * Constructor - * @param {Object} [options] Options object - * @param {Function} [callback] function to invoke after callback init. - * @return {fabric.Pattern} thisArg - */ - initialize: function(options, callback) { - options || (options = { }); - - this.id = fabric.Object.__uid++; - this.setOptions(options); - if (!options.source || (options.source && typeof options.source !== 'string')) { - callback && callback(this); - return; - } - else { - // img src string - var _this = this; - this.source = fabric.util.createImage(); - fabric.util.loadImage(options.source, function(img, isError) { - _this.source = img; - callback && callback(_this, isError); - }, null, this.crossOrigin); - } - }, - - /** - * Returns object representation of a pattern - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of a pattern instance - */ - toObject: function(propertiesToInclude) { - var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, - source, object; - - // element - if (typeof this.source.src === 'string') { - source = this.source.src; - } - // element - else if (typeof this.source === 'object' && this.source.toDataURL) { - source = this.source.toDataURL(); - } - - object = { - type: 'pattern', - source: source, - repeat: this.repeat, - crossOrigin: this.crossOrigin, - offsetX: toFixed(this.offsetX, NUM_FRACTION_DIGITS), - offsetY: toFixed(this.offsetY, NUM_FRACTION_DIGITS), - patternTransform: this.patternTransform ? this.patternTransform.concat() : null - }; - fabric.util.populateWithProperties(this, object, propertiesToInclude); - - return object; - }, - - /* _TO_SVG_START_ */ - /** - * Returns SVG representation of a pattern - * @param {fabric.Object} object - * @return {String} SVG representation of a pattern - */ - toSVG: function(object) { - var patternSource = typeof this.source === 'function' ? this.source() : this.source, - patternWidth = patternSource.width / object.width, - patternHeight = patternSource.height / object.height, - patternOffsetX = this.offsetX / object.width, - patternOffsetY = this.offsetY / object.height, - patternImgSrc = ''; - if (this.repeat === 'repeat-x' || this.repeat === 'no-repeat') { - patternHeight = 1; - if (patternOffsetY) { - patternHeight += Math.abs(patternOffsetY); - } - } - if (this.repeat === 'repeat-y' || this.repeat === 'no-repeat') { - patternWidth = 1; - if (patternOffsetX) { - patternWidth += Math.abs(patternOffsetX); - } - - } - if (patternSource.src) { - patternImgSrc = patternSource.src; - } - else if (patternSource.toDataURL) { - patternImgSrc = patternSource.toDataURL(); - } - - return '\n' + - '\n' + - '\n'; - }, - /* _TO_SVG_END_ */ - - setOptions: function(options) { - for (var prop in options) { - this[prop] = options[prop]; - } - }, - - /** - * Returns an instance of CanvasPattern - * @param {CanvasRenderingContext2D} ctx Context to create pattern - * @return {CanvasPattern} - */ - toLive: function(ctx) { - var source = this.source; - // if the image failed to load, return, and allow rest to continue loading - if (!source) { - return ''; - } - - // if an image - if (typeof source.src !== 'undefined') { - if (!source.complete) { - return ''; - } - if (source.naturalWidth === 0 || source.naturalHeight === 0) { - return ''; - } - } - return ctx.createPattern(source, this.repeat); - } - }); -})(); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - toFixed = fabric.util.toFixed; - - if (fabric.Shadow) { - fabric.warn('fabric.Shadow is already defined.'); - return; - } - - /** - * Shadow class - * @class fabric.Shadow - * @see {@link http://fabricjs.com/shadows|Shadow demo} - * @see {@link fabric.Shadow#initialize} for constructor definition - */ - fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { - - /** - * Shadow color - * @type String - * @default - */ - color: 'rgb(0,0,0)', - - /** - * Shadow blur - * @type Number - */ - blur: 0, - - /** - * Shadow horizontal offset - * @type Number - * @default - */ - offsetX: 0, - - /** - * Shadow vertical offset - * @type Number - * @default - */ - offsetY: 0, - - /** - * Whether the shadow should affect stroke operations - * @type Boolean - * @default - */ - affectStroke: false, - - /** - * Indicates whether toObject should include default values - * @type Boolean - * @default - */ - includeDefaultValues: true, - - /** - * When `false`, the shadow will scale with the object. - * When `true`, the shadow's offsetX, offsetY, and blur will not be affected by the object's scale. - * default to false - * @type Boolean - * @default - */ - nonScaling: false, - - /** - * Constructor - * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetY properties or string (e.g. "rgba(0,0,0,0.2) 2px 2px 10px") - * @return {fabric.Shadow} thisArg - */ - initialize: function(options) { - - if (typeof options === 'string') { - options = this._parseShadow(options); - } - - for (var prop in options) { - this[prop] = options[prop]; - } - - this.id = fabric.Object.__uid++; - }, - - /** - * @private - * @param {String} shadow Shadow value to parse - * @return {Object} Shadow object with color, offsetX, offsetY and blur - */ - _parseShadow: function(shadow) { - var shadowStr = shadow.trim(), - offsetsAndBlur = fabric.Shadow.reOffsetsAndBlur.exec(shadowStr) || [], - color = shadowStr.replace(fabric.Shadow.reOffsetsAndBlur, '') || 'rgb(0,0,0)'; - - return { - color: color.trim(), - offsetX: parseFloat(offsetsAndBlur[1], 10) || 0, - offsetY: parseFloat(offsetsAndBlur[2], 10) || 0, - blur: parseFloat(offsetsAndBlur[3], 10) || 0 - }; - }, - - /** - * Returns a string representation of an instance - * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow - * @return {String} Returns CSS3 text-shadow declaration - */ - toString: function() { - return [this.offsetX, this.offsetY, this.blur, this.color].join('px '); - }, - - /* _TO_SVG_START_ */ - /** - * Returns SVG representation of a shadow - * @param {fabric.Object} object - * @return {String} SVG representation of a shadow - */ - toSVG: function(object) { - var fBoxX = 40, fBoxY = 40, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, - offset = fabric.util.rotateVector( - { x: this.offsetX, y: this.offsetY }, - fabric.util.degreesToRadians(-object.angle)), - BLUR_BOX = 20, color = new fabric.Color(this.color); - - if (object.width && object.height) { - //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion - // we add some extra space to filter box to contain the blur ( 20 ) - fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX; - fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX; - } - if (object.flipX) { - offset.x *= -1; - } - if (object.flipY) { - offset.y *= -1; - } - - return ( - '\n' + - '\t\n' + - '\t\n' + - '\t\n' + - '\t\n' + - '\t\n' + - '\t\t\n' + - '\t\t\n' + - '\t\n' + - '\n'); - }, - /* _TO_SVG_END_ */ - - /** - * Returns object representation of a shadow - * @return {Object} Object representation of a shadow instance - */ - toObject: function() { - if (this.includeDefaultValues) { - return { - color: this.color, - blur: this.blur, - offsetX: this.offsetX, - offsetY: this.offsetY, - affectStroke: this.affectStroke, - nonScaling: this.nonScaling - }; - } - var obj = { }, proto = fabric.Shadow.prototype; - - ['color', 'blur', 'offsetX', 'offsetY', 'affectStroke', 'nonScaling'].forEach(function(prop) { - if (this[prop] !== proto[prop]) { - obj[prop] = this[prop]; - } - }, this); - - return obj; - } - }); - - /** - * Regex matching shadow offsetX, offsetY and blur (ex: "2px 2px 10px rgba(0,0,0,0.2)", "rgb(0,255,0) 2px 2px") - * @static - * @field - * @memberOf fabric.Shadow - */ - // eslint-disable-next-line max-len - fabric.Shadow.reOffsetsAndBlur = /(?:\s|^)(-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?(-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?(\d+(?:\.\d*)?(?:px)?)?(?:\s?|$)(?:$|\s)/; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function () { - - 'use strict'; - - if (fabric.StaticCanvas) { - fabric.warn('fabric.StaticCanvas is already defined.'); - return; - } - - // aliases for faster resolution - var extend = fabric.util.object.extend, - getElementOffset = fabric.util.getElementOffset, - removeFromArray = fabric.util.removeFromArray, - toFixed = fabric.util.toFixed, - transformPoint = fabric.util.transformPoint, - invertTransform = fabric.util.invertTransform, - getNodeCanvas = fabric.util.getNodeCanvas, - createCanvasElement = fabric.util.createCanvasElement, - - CANVAS_INIT_ERROR = new Error('Could not initialize `canvas` element'); - - /** - * Static canvas class - * @class fabric.StaticCanvas - * @mixes fabric.Collection - * @mixes fabric.Observable - * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo} - * @see {@link fabric.StaticCanvas#initialize} for constructor definition - * @fires before:render - * @fires after:render - * @fires canvas:cleared - * @fires object:added - * @fires object:removed - */ - fabric.StaticCanvas = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.StaticCanvas.prototype */ { - - /** - * Constructor - * @param {HTMLElement | String} el <canvas> element to initialize instance on - * @param {Object} [options] Options object - * @return {Object} thisArg - */ - initialize: function(el, options) { - options || (options = { }); - this.renderAndResetBound = this.renderAndReset.bind(this); - this.requestRenderAllBound = this.requestRenderAll.bind(this); - this._initStatic(el, options); - }, - - /** - * Background color of canvas instance. - * Should be set via {@link fabric.StaticCanvas#setBackgroundColor}. - * @type {(String|fabric.Pattern)} - * @default - */ - backgroundColor: '', - - /** - * Background image of canvas instance. - * since 2.4.0 image caching is active, please when putting an image as background, add to the - * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom - * vale. As an alternative you can disable image objectCaching - * @type fabric.Image - * @default - */ - backgroundImage: null, - - /** - * Overlay color of canvas instance. - * Should be set via {@link fabric.StaticCanvas#setOverlayColor} - * @since 1.3.9 - * @type {(String|fabric.Pattern)} - * @default - */ - overlayColor: '', - - /** - * Overlay image of canvas instance. - * since 2.4.0 image caching is active, please when putting an image as overlay, add to the - * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom - * vale. As an alternative you can disable image objectCaching - * @type fabric.Image - * @default - */ - overlayImage: null, - - /** - * Indicates whether toObject/toDatalessObject should include default values - * if set to false, takes precedence over the object value. - * @type Boolean - * @default - */ - includeDefaultValues: true, - - /** - * Indicates whether objects' state should be saved - * @type Boolean - * @default - */ - stateful: false, - - /** - * Indicates whether {@link fabric.Collection.add}, {@link fabric.Collection.insertAt} and {@link fabric.Collection.remove}, - * {@link fabric.StaticCanvas.moveTo}, {@link fabric.StaticCanvas.clear} and many more, should also re-render canvas. - * Disabling this option will not give a performance boost when adding/removing a lot of objects to/from canvas at once - * since the renders are quequed and executed one per frame. - * Disabling is suggested anyway and managing the renders of the app manually is not a big effort ( canvas.requestRenderAll() ) - * Left default to true to do not break documentation and old app, fiddles. - * @type Boolean - * @default - */ - renderOnAddRemove: true, - - /** - * Indicates whether object controls (borders/controls) are rendered above overlay image - * @type Boolean - * @default - */ - controlsAboveOverlay: false, - - /** - * Indicates whether the browser can be scrolled when using a touchscreen and dragging on the canvas - * @type Boolean - * @default - */ - allowTouchScrolling: false, - - /** - * Indicates whether this canvas will use image smoothing, this is on by default in browsers - * @type Boolean - * @default - */ - imageSmoothingEnabled: true, - - /** - * The transformation (a Canvas 2D API transform matrix) which focuses the viewport - * @type Array - * @example Default transform - * canvas.viewportTransform = [1, 0, 0, 1, 0, 0]; - * @example Scale by 70% and translate toward bottom-right by 50, without skewing - * canvas.viewportTransform = [0.7, 0, 0, 0.7, 50, 50]; - * @default - */ - viewportTransform: fabric.iMatrix.concat(), - - /** - * if set to false background image is not affected by viewport transform - * @since 1.6.3 - * @type Boolean - * @default - */ - backgroundVpt: true, - - /** - * if set to false overlya image is not affected by viewport transform - * @since 1.6.3 - * @type Boolean - * @default - */ - overlayVpt: true, - - /** - * When true, canvas is scaled by devicePixelRatio for better rendering on retina screens - * @type Boolean - * @default - */ - enableRetinaScaling: true, - - /** - * Describe canvas element extension over design - * properties are tl,tr,bl,br. - * if canvas is not zoomed/panned those points are the four corner of canvas - * if canvas is viewportTransformed you those points indicate the extension - * of canvas element in plain untrasformed coordinates - * The coordinates get updated with @method calcViewportBoundaries. - * @memberOf fabric.StaticCanvas.prototype - */ - vptCoords: { }, - - /** - * Based on vptCoords and object.aCoords, skip rendering of objects that - * are not included in current viewport. - * May greatly help in applications with crowded canvas and use of zoom/pan - * If One of the corner of the bounding box of the object is on the canvas - * the objects get rendered. - * @memberOf fabric.StaticCanvas.prototype - * @type Boolean - * @default - */ - skipOffscreen: true, - - /** - * a fabricObject that, without stroke define a clipping area with their shape. filled in black - * the clipPath object gets used when the canvas has rendered, and the context is placed in the - * top left corner of the canvas. - * clipPath will clip away controls, if you do not want this to happen use controlsAboveOverlay = true - * @type fabric.Object - */ - clipPath: undefined, - - /** - * @private - * @param {HTMLElement | String} el <canvas> element to initialize instance on - * @param {Object} [options] Options object - */ - _initStatic: function(el, options) { - var cb = this.requestRenderAllBound; - this._objects = []; - this._createLowerCanvas(el); - this._initOptions(options); - // only initialize retina scaling once - if (!this.interactive) { - this._initRetinaScaling(); - } - - if (options.overlayImage) { - this.setOverlayImage(options.overlayImage, cb); - } - if (options.backgroundImage) { - this.setBackgroundImage(options.backgroundImage, cb); - } - if (options.backgroundColor) { - this.setBackgroundColor(options.backgroundColor, cb); - } - if (options.overlayColor) { - this.setOverlayColor(options.overlayColor, cb); - } - this.calcOffset(); - }, - - /** - * @private - */ - _isRetinaScaling: function() { - return (fabric.devicePixelRatio > 1 && this.enableRetinaScaling); - }, - - /** - * @private - * @return {Number} retinaScaling if applied, otherwise 1; - */ - getRetinaScaling: function() { - return this._isRetinaScaling() ? Math.max(1, fabric.devicePixelRatio) : 1; - }, - - /** - * @private - */ - _initRetinaScaling: function() { - if (!this._isRetinaScaling()) { - return; - } - var scaleRatio = fabric.devicePixelRatio; - this.__initRetinaScaling(scaleRatio, this.lowerCanvasEl, this.contextContainer); - if (this.upperCanvasEl) { - this.__initRetinaScaling(scaleRatio, this.upperCanvasEl, this.contextTop); - } - }, - - __initRetinaScaling: function(scaleRatio, canvas, context) { - canvas.setAttribute('width', this.width * scaleRatio); - canvas.setAttribute('height', this.height * scaleRatio); - context.scale(scaleRatio, scaleRatio); - }, - - - /** - * Calculates canvas element offset relative to the document - * This method is also attached as "resize" event handler of window - * @return {fabric.Canvas} instance - * @chainable - */ - calcOffset: function () { - this._offset = getElementOffset(this.lowerCanvasEl); - return this; - }, - - /** - * Sets {@link fabric.StaticCanvas#overlayImage|overlay image} for this canvas - * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set overlay to - * @param {Function} callback callback to invoke when image is loaded and set as an overlay - * @param {Object} [options] Optional options to set for the {@link fabric.Image|overlay image}. - * @return {fabric.Canvas} thisArg - * @chainable - * @see {@link http://jsfiddle.net/fabricjs/MnzHT/|jsFiddle demo} - * @example Normal overlayImage with left/top = 0 - * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), { - * // Needed to position overlayImage at 0/0 - * originX: 'left', - * originY: 'top' - * }); - * @example overlayImage with different properties - * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), { - * opacity: 0.5, - * angle: 45, - * left: 400, - * top: 400, - * originX: 'left', - * originY: 'top' - * }); - * @example Stretched overlayImage #1 - width/height correspond to canvas width/height - * fabric.Image.fromURL('http://fabricjs.com/assets/jail_cell_bars.png', function(img, isError) { - * img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'}); - * canvas.setOverlayImage(img, canvas.renderAll.bind(canvas)); - * }); - * @example Stretched overlayImage #2 - width/height correspond to canvas width/height - * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), { - * width: canvas.width, - * height: canvas.height, - * // Needed to position overlayImage at 0/0 - * originX: 'left', - * originY: 'top' - * }); - * @example overlayImage loaded from cross-origin - * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), { - * opacity: 0.5, - * angle: 45, - * left: 400, - * top: 400, - * originX: 'left', - * originY: 'top', - * crossOrigin: 'anonymous' - * }); - */ - setOverlayImage: function (image, callback, options) { - return this.__setBgOverlayImage('overlayImage', image, callback, options); - }, - - /** - * Sets {@link fabric.StaticCanvas#backgroundImage|background image} for this canvas - * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set background to - * @param {Function} callback Callback to invoke when image is loaded and set as background - * @param {Object} [options] Optional options to set for the {@link fabric.Image|background image}. - * @return {fabric.Canvas} thisArg - * @chainable - * @see {@link http://jsfiddle.net/djnr8o7a/28/|jsFiddle demo} - * @example Normal backgroundImage with left/top = 0 - * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), { - * // Needed to position backgroundImage at 0/0 - * originX: 'left', - * originY: 'top' - * }); - * @example backgroundImage with different properties - * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), { - * opacity: 0.5, - * angle: 45, - * left: 400, - * top: 400, - * originX: 'left', - * originY: 'top' - * }); - * @example Stretched backgroundImage #1 - width/height correspond to canvas width/height - * fabric.Image.fromURL('http://fabricjs.com/assets/honey_im_subtle.png', function(img, isError) { - * img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'}); - * canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas)); - * }); - * @example Stretched backgroundImage #2 - width/height correspond to canvas width/height - * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), { - * width: canvas.width, - * height: canvas.height, - * // Needed to position backgroundImage at 0/0 - * originX: 'left', - * originY: 'top' - * }); - * @example backgroundImage loaded from cross-origin - * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), { - * opacity: 0.5, - * angle: 45, - * left: 400, - * top: 400, - * originX: 'left', - * originY: 'top', - * crossOrigin: 'anonymous' - * }); - */ - // TODO: fix stretched examples - setBackgroundImage: function (image, callback, options) { - return this.__setBgOverlayImage('backgroundImage', image, callback, options); - }, - - /** - * Sets {@link fabric.StaticCanvas#overlayColor|foreground color} for this canvas - * @param {(String|fabric.Pattern)} overlayColor Color or pattern to set foreground color to - * @param {Function} callback Callback to invoke when foreground color is set - * @return {fabric.Canvas} thisArg - * @chainable - * @see {@link http://jsfiddle.net/fabricjs/pB55h/|jsFiddle demo} - * @example Normal overlayColor - color value - * canvas.setOverlayColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas)); - * @example fabric.Pattern used as overlayColor - * canvas.setOverlayColor({ - * source: 'http://fabricjs.com/assets/escheresque_ste.png' - * }, canvas.renderAll.bind(canvas)); - * @example fabric.Pattern used as overlayColor with repeat and offset - * canvas.setOverlayColor({ - * source: 'http://fabricjs.com/assets/escheresque_ste.png', - * repeat: 'repeat', - * offsetX: 200, - * offsetY: 100 - * }, canvas.renderAll.bind(canvas)); - */ - setOverlayColor: function(overlayColor, callback) { - return this.__setBgOverlayColor('overlayColor', overlayColor, callback); - }, - - /** - * Sets {@link fabric.StaticCanvas#backgroundColor|background color} for this canvas - * @param {(String|fabric.Pattern)} backgroundColor Color or pattern to set background color to - * @param {Function} callback Callback to invoke when background color is set - * @return {fabric.Canvas} thisArg - * @chainable - * @see {@link http://jsfiddle.net/fabricjs/hXzvk/|jsFiddle demo} - * @example Normal backgroundColor - color value - * canvas.setBackgroundColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas)); - * @example fabric.Pattern used as backgroundColor - * canvas.setBackgroundColor({ - * source: 'http://fabricjs.com/assets/escheresque_ste.png' - * }, canvas.renderAll.bind(canvas)); - * @example fabric.Pattern used as backgroundColor with repeat and offset - * canvas.setBackgroundColor({ - * source: 'http://fabricjs.com/assets/escheresque_ste.png', - * repeat: 'repeat', - * offsetX: 200, - * offsetY: 100 - * }, canvas.renderAll.bind(canvas)); - */ - setBackgroundColor: function(backgroundColor, callback) { - return this.__setBgOverlayColor('backgroundColor', backgroundColor, callback); - }, - - /** - * @private - * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundImage|backgroundImage} - * or {@link fabric.StaticCanvas#overlayImage|overlayImage}) - * @param {(fabric.Image|String|null)} image fabric.Image instance, URL of an image or null to set background or overlay to - * @param {Function} callback Callback to invoke when image is loaded and set as background or overlay. The first argument is the created image, the second argument is a flag indicating whether an error occurred or not. - * @param {Object} [options] Optional options to set for the {@link fabric.Image|image}. - */ - __setBgOverlayImage: function(property, image, callback, options) { - if (typeof image === 'string') { - fabric.util.loadImage(image, function(img, isError) { - if (img) { - var instance = new fabric.Image(img, options); - this[property] = instance; - instance.canvas = this; - } - callback && callback(img, isError); - }, this, options && options.crossOrigin); - } - else { - options && image.setOptions(options); - this[property] = image; - image && (image.canvas = this); - callback && callback(image, false); - } - - return this; - }, - - /** - * @private - * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundColor|backgroundColor} - * or {@link fabric.StaticCanvas#overlayColor|overlayColor}) - * @param {(Object|String|null)} color Object with pattern information, color value or null - * @param {Function} [callback] Callback is invoked when color is set - */ - __setBgOverlayColor: function(property, color, callback) { - this[property] = color; - this._initGradient(color, property); - this._initPattern(color, property, callback); - return this; - }, - - /** - * @private - */ - _createCanvasElement: function() { - var element = createCanvasElement(); - if (!element) { - throw CANVAS_INIT_ERROR; - } - if (!element.style) { - element.style = { }; - } - if (typeof element.getContext === 'undefined') { - throw CANVAS_INIT_ERROR; - } - return element; - }, - - /** - * @private - * @param {Object} [options] Options object - */ - _initOptions: function (options) { - var lowerCanvasEl = this.lowerCanvasEl; - this._setOptions(options); - - this.width = this.width || parseInt(lowerCanvasEl.width, 10) || 0; - this.height = this.height || parseInt(lowerCanvasEl.height, 10) || 0; - - if (!this.lowerCanvasEl.style) { - return; - } - - lowerCanvasEl.width = this.width; - lowerCanvasEl.height = this.height; - - lowerCanvasEl.style.width = this.width + 'px'; - lowerCanvasEl.style.height = this.height + 'px'; - - this.viewportTransform = this.viewportTransform.slice(); - }, - - /** - * Creates a bottom canvas - * @private - * @param {HTMLElement} [canvasEl] - */ - _createLowerCanvas: function (canvasEl) { - // canvasEl === 'HTMLCanvasElement' does not work on jsdom/node - if (canvasEl && canvasEl.getContext) { - this.lowerCanvasEl = canvasEl; - } - else { - this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement(); - } - - fabric.util.addClass(this.lowerCanvasEl, 'lower-canvas'); - this._originalCanvasStyle = this.lowerCanvasEl.style; - if (this.interactive) { - this._applyCanvasStyle(this.lowerCanvasEl); - } - - this.contextContainer = this.lowerCanvasEl.getContext('2d'); - }, - - /** - * Returns canvas width (in px) - * @return {Number} - */ - getWidth: function () { - return this.width; - }, - - /** - * Returns canvas height (in px) - * @return {Number} - */ - getHeight: function () { - return this.height; - }, - - /** - * Sets width of this canvas instance - * @param {Number|String} value Value to set width to - * @param {Object} [options] Options object - * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions - * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions - * @return {fabric.Canvas} instance - * @chainable true - */ - setWidth: function (value, options) { - return this.setDimensions({ width: value }, options); - }, - - /** - * Sets height of this canvas instance - * @param {Number|String} value Value to set height to - * @param {Object} [options] Options object - * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions - * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions - * @return {fabric.Canvas} instance - * @chainable true - */ - setHeight: function (value, options) { - return this.setDimensions({ height: value }, options); - }, - - /** - * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em) - * @param {Object} dimensions Object with width/height properties - * @param {Number|String} [dimensions.width] Width of canvas element - * @param {Number|String} [dimensions.height] Height of canvas element - * @param {Object} [options] Options object - * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions - * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions - * @return {fabric.Canvas} thisArg - * @chainable - */ - setDimensions: function (dimensions, options) { - var cssValue; - - options = options || {}; - - for (var prop in dimensions) { - cssValue = dimensions[prop]; - - if (!options.cssOnly) { - this._setBackstoreDimension(prop, dimensions[prop]); - cssValue += 'px'; - this.hasLostContext = true; - } - - if (!options.backstoreOnly) { - this._setCssDimension(prop, cssValue); - } - } - if (this._isCurrentlyDrawing) { - this.freeDrawingBrush && this.freeDrawingBrush._setBrushStyles(this.contextTop); - } - this._initRetinaScaling(); - this.calcOffset(); - - if (!options.cssOnly) { - this.requestRenderAll(); - } - - return this; - }, - - /** - * Helper for setting width/height - * @private - * @param {String} prop property (width|height) - * @param {Number} value value to set property to - * @return {fabric.Canvas} instance - * @chainable true - */ - _setBackstoreDimension: function (prop, value) { - this.lowerCanvasEl[prop] = value; - - if (this.upperCanvasEl) { - this.upperCanvasEl[prop] = value; - } - - if (this.cacheCanvasEl) { - this.cacheCanvasEl[prop] = value; - } - - this[prop] = value; - - return this; - }, - - /** - * Helper for setting css width/height - * @private - * @param {String} prop property (width|height) - * @param {String} value value to set property to - * @return {fabric.Canvas} instance - * @chainable true - */ - _setCssDimension: function (prop, value) { - this.lowerCanvasEl.style[prop] = value; - - if (this.upperCanvasEl) { - this.upperCanvasEl.style[prop] = value; - } - - if (this.wrapperEl) { - this.wrapperEl.style[prop] = value; - } - - return this; - }, - - /** - * Returns canvas zoom level - * @return {Number} - */ - getZoom: function () { - return this.viewportTransform[0]; - }, - - /** - * Sets viewport transformation of this canvas instance - * @param {Array} vpt a Canvas 2D API transform matrix - * @return {fabric.Canvas} instance - * @chainable true - */ - setViewportTransform: function (vpt) { - var activeObject = this._activeObject, - backgroundObject = this.backgroundImage, - overlayObject = this.overlayImage, - object, i, len; - this.viewportTransform = vpt; - for (i = 0, len = this._objects.length; i < len; i++) { - object = this._objects[i]; - object.group || object.setCoords(true); - } - if (activeObject) { - activeObject.setCoords(); - } - if (backgroundObject) { - backgroundObject.setCoords(true); - } - if (overlayObject) { - overlayObject.setCoords(true); - } - this.calcViewportBoundaries(); - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * Sets zoom level of this canvas instance, the zoom centered around point - * meaning that following zoom to point with the same point will have the visual - * effect of the zoom originating from that point. The point won't move. - * It has nothing to do with canvas center or visual center of the viewport. - * @param {fabric.Point} point to zoom with respect to - * @param {Number} value to set zoom to, less than 1 zooms out - * @return {fabric.Canvas} instance - * @chainable true - */ - zoomToPoint: function (point, value) { - // TODO: just change the scale, preserve other transformations - var before = point, vpt = this.viewportTransform.slice(0); - point = transformPoint(point, invertTransform(this.viewportTransform)); - vpt[0] = value; - vpt[3] = value; - var after = transformPoint(point, vpt); - vpt[4] += before.x - after.x; - vpt[5] += before.y - after.y; - return this.setViewportTransform(vpt); - }, - - /** - * Sets zoom level of this canvas instance - * @param {Number} value to set zoom to, less than 1 zooms out - * @return {fabric.Canvas} instance - * @chainable true - */ - setZoom: function (value) { - this.zoomToPoint(new fabric.Point(0, 0), value); - return this; - }, - - /** - * Pan viewport so as to place point at top left corner of canvas - * @param {fabric.Point} point to move to - * @return {fabric.Canvas} instance - * @chainable true - */ - absolutePan: function (point) { - var vpt = this.viewportTransform.slice(0); - vpt[4] = -point.x; - vpt[5] = -point.y; - return this.setViewportTransform(vpt); - }, - - /** - * Pans viewpoint relatively - * @param {fabric.Point} point (position vector) to move by - * @return {fabric.Canvas} instance - * @chainable true - */ - relativePan: function (point) { - return this.absolutePan(new fabric.Point( - -point.x - this.viewportTransform[4], - -point.y - this.viewportTransform[5] - )); - }, - - /** - * Returns <canvas> element corresponding to this instance - * @return {HTMLCanvasElement} - */ - getElement: function () { - return this.lowerCanvasEl; - }, - - /** - * @private - * @param {fabric.Object} obj Object that was added - */ - _onObjectAdded: function(obj) { - this.stateful && obj.setupState(); - obj._set('canvas', this); - obj.setCoords(); - this.fire('object:added', { target: obj }); - obj.fire('added'); - }, - - /** - * @private - * @param {fabric.Object} obj Object that was removed - */ - _onObjectRemoved: function(obj) { - this.fire('object:removed', { target: obj }); - obj.fire('removed'); - delete obj.canvas; - }, - - /** - * Clears specified context of canvas element - * @param {CanvasRenderingContext2D} ctx Context to clear - * @return {fabric.Canvas} thisArg - * @chainable - */ - clearContext: function(ctx) { - ctx.clearRect(0, 0, this.width, this.height); - return this; - }, - - /** - * Returns context of canvas where objects are drawn - * @return {CanvasRenderingContext2D} - */ - getContext: function () { - return this.contextContainer; - }, - - /** - * Clears all contexts (background, main, top) of an instance - * @return {fabric.Canvas} thisArg - * @chainable - */ - clear: function () { - this.remove.apply(this, this.getObjects()); - this.backgroundImage = null; - this.overlayImage = null; - this.backgroundColor = ''; - this.overlayColor = ''; - if (this._hasITextHandlers) { - this.off('mouse:up', this._mouseUpITextHandler); - this._iTextInstances = null; - this._hasITextHandlers = false; - } - this.clearContext(this.contextContainer); - this.fire('canvas:cleared'); - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * Renders the canvas - * @return {fabric.Canvas} instance - * @chainable - */ - renderAll: function () { - var canvasToDrawOn = this.contextContainer; - this.renderCanvas(canvasToDrawOn, this._objects); - return this; - }, - - /** - * Function created to be instance bound at initialization - * used in requestAnimationFrame rendering - * Let the fabricJS call it. If you call it manually you could have more - * animationFrame stacking on to of each other - * for an imperative rendering, use canvas.renderAll - * @private - * @return {fabric.Canvas} instance - * @chainable - */ - renderAndReset: function() { - this.isRendering = 0; - this.renderAll(); - }, - - /** - * Append a renderAll request to next animation frame. - * unless one is already in progress, in that case nothing is done - * a boolean flag will avoid appending more. - * @return {fabric.Canvas} instance - * @chainable - */ - requestRenderAll: function () { - if (!this.isRendering) { - this.isRendering = fabric.util.requestAnimFrame(this.renderAndResetBound); - } - return this; - }, - - /** - * Calculate the position of the 4 corner of canvas with current viewportTransform. - * helps to determinate when an object is in the current rendering viewport using - * object absolute coordinates ( aCoords ) - * @return {Object} points.tl - * @chainable - */ - calcViewportBoundaries: function() { - var points = { }, width = this.width, height = this.height, - iVpt = invertTransform(this.viewportTransform); - points.tl = transformPoint({ x: 0, y: 0 }, iVpt); - points.br = transformPoint({ x: width, y: height }, iVpt); - points.tr = new fabric.Point(points.br.x, points.tl.y); - points.bl = new fabric.Point(points.tl.x, points.br.y); - this.vptCoords = points; - return points; - }, - - cancelRequestedRender: function() { - if (this.isRendering) { - fabric.util.cancelAnimFrame(this.isRendering); - this.isRendering = 0; - } - }, - - /** - * Renders background, objects, overlay and controls. - * @param {CanvasRenderingContext2D} ctx - * @param {Array} objects to render - * @return {fabric.Canvas} instance - * @chainable - */ - renderCanvas: function(ctx, objects) { - var v = this.viewportTransform, path = this.clipPath; - this.cancelRequestedRender(); - this.calcViewportBoundaries(); - this.clearContext(ctx); - fabric.util.setImageSmoothing(ctx, this.imageSmoothingEnabled); - this.fire('before:render', { ctx: ctx, }); - this._renderBackground(ctx); - - ctx.save(); - //apply viewport transform once for all rendering process - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - this._renderObjects(ctx, objects); - ctx.restore(); - if (!this.controlsAboveOverlay && this.interactive) { - this.drawControls(ctx); - } - if (path) { - path.canvas = this; - // needed to setup a couple of variables - path.shouldCache(); - path._transformDone = true; - path.renderCache({ forClipping: true }); - this.drawClipPathOnCanvas(ctx); - } - this._renderOverlay(ctx); - if (this.controlsAboveOverlay && this.interactive) { - this.drawControls(ctx); - } - this.fire('after:render', { ctx: ctx, }); - }, - - /** - * Paint the cached clipPath on the lowerCanvasEl - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - drawClipPathOnCanvas: function(ctx) { - var v = this.viewportTransform, path = this.clipPath; - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - // DEBUG: uncomment this line, comment the following - // ctx.globalAlpha = 0.4; - ctx.globalCompositeOperation = 'destination-in'; - path.transform(ctx); - ctx.scale(1 / path.zoomX, 1 / path.zoomY); - ctx.drawImage(path._cacheCanvas, -path.cacheTranslationX, -path.cacheTranslationY); - ctx.restore(); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Array} objects to render - */ - _renderObjects: function(ctx, objects) { - var i, len; - for (i = 0, len = objects.length; i < len; ++i) { - objects[i] && objects[i].render(ctx); - } - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {string} property 'background' or 'overlay' - */ - _renderBackgroundOrOverlay: function(ctx, property) { - var fill = this[property + 'Color'], object = this[property + 'Image'], - v = this.viewportTransform, needsVpt = this[property + 'Vpt']; - if (!fill && !object) { - return; - } - if (fill) { - ctx.save(); - ctx.beginPath(); - ctx.moveTo(0, 0); - ctx.lineTo(this.width, 0); - ctx.lineTo(this.width, this.height); - ctx.lineTo(0, this.height); - ctx.closePath(); - ctx.fillStyle = fill.toLive - ? fill.toLive(ctx, this) - : fill; - if (needsVpt) { - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - } - ctx.transform(1, 0, 0, 1, fill.offsetX || 0, fill.offsetY || 0); - var m = fill.gradientTransform || fill.patternTransform; - m && ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); - ctx.fill(); - ctx.restore(); - } - if (object) { - ctx.save(); - if (needsVpt) { - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - } - object.render(ctx); - ctx.restore(); - } - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderBackground: function(ctx) { - this._renderBackgroundOrOverlay(ctx, 'background'); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderOverlay: function(ctx) { - this._renderBackgroundOrOverlay(ctx, 'overlay'); - }, - - /** - * Returns coordinates of a center of canvas. - * Returned value is an object with top and left properties - * @return {Object} object with "top" and "left" number values - * @deprecated migrate to `getCenterPoint` - */ - getCenter: function () { - return { - top: this.height / 2, - left: this.width / 2 - }; - }, - - /** - * Returns coordinates of a center of canvas. - * @return {fabric.Point} - */ - getCenterPoint: function () { - return new fabric.Point(this.width / 2, this.height / 2); - }, - - /** - * Centers object horizontally in the canvas - * @param {fabric.Object} object Object to center horizontally - * @return {fabric.Canvas} thisArg - */ - centerObjectH: function (object) { - return this._centerObject(object, new fabric.Point(this.getCenterPoint().x, object.getCenterPoint().y)); - }, - - /** - * Centers object vertically in the canvas - * @param {fabric.Object} object Object to center vertically - * @return {fabric.Canvas} thisArg - * @chainable - */ - centerObjectV: function (object) { - return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, this.getCenterPoint().y)); - }, - - /** - * Centers object vertically and horizontally in the canvas - * @param {fabric.Object} object Object to center vertically and horizontally - * @return {fabric.Canvas} thisArg - * @chainable - */ - centerObject: function(object) { - var center = this.getCenterPoint(); - return this._centerObject(object, center); - }, - - /** - * Centers object vertically and horizontally in the viewport - * @param {fabric.Object} object Object to center vertically and horizontally - * @return {fabric.Canvas} thisArg - * @chainable - */ - viewportCenterObject: function(object) { - var vpCenter = this.getVpCenter(); - return this._centerObject(object, vpCenter); - }, - - /** - * Centers object horizontally in the viewport, object.top is unchanged - * @param {fabric.Object} object Object to center vertically and horizontally - * @return {fabric.Canvas} thisArg - * @chainable - */ - viewportCenterObjectH: function(object) { - var vpCenter = this.getVpCenter(); - this._centerObject(object, new fabric.Point(vpCenter.x, object.getCenterPoint().y)); - return this; - }, - - /** - * Centers object Vertically in the viewport, object.top is unchanged - * @param {fabric.Object} object Object to center vertically and horizontally - * @return {fabric.Canvas} thisArg - * @chainable - */ - viewportCenterObjectV: function(object) { - var vpCenter = this.getVpCenter(); - - return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, vpCenter.y)); - }, - - /** - * Calculate the point in canvas that correspond to the center of actual viewport. - * @return {fabric.Point} vpCenter, viewport center - * @chainable - */ - getVpCenter: function() { - var center = this.getCenterPoint(), - iVpt = invertTransform(this.viewportTransform); - return transformPoint(center, iVpt); - }, - - /** - * @private - * @param {fabric.Object} object Object to center - * @param {fabric.Point} center Center point - * @return {fabric.Canvas} thisArg - * @chainable - */ - _centerObject: function(object, center) { - object.setPositionByOrigin(center, 'center', 'center'); - object.setCoords(); - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * Returns dataless JSON representation of canvas - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {String} json string - */ - toDatalessJSON: function (propertiesToInclude) { - return this.toDatalessObject(propertiesToInclude); - }, - - /** - * Returns object representation of canvas - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function (propertiesToInclude) { - return this._toObjectMethod('toObject', propertiesToInclude); - }, - - /** - * Returns dataless object representation of canvas - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toDatalessObject: function (propertiesToInclude) { - return this._toObjectMethod('toDatalessObject', propertiesToInclude); - }, - - /** - * @private - */ - _toObjectMethod: function (methodName, propertiesToInclude) { - - var clipPath = this.clipPath, data = { - version: fabric.version, - objects: this._toObjects(methodName, propertiesToInclude), - }; - if (clipPath && !clipPath.excludeFromExport) { - data.clipPath = this._toObject(this.clipPath, methodName, propertiesToInclude); - } - extend(data, this.__serializeBgOverlay(methodName, propertiesToInclude)); - - fabric.util.populateWithProperties(this, data, propertiesToInclude); - - return data; - }, - - /** - * @private - */ - _toObjects: function(methodName, propertiesToInclude) { - return this._objects.filter(function(object) { - return !object.excludeFromExport; - }).map(function(instance) { - return this._toObject(instance, methodName, propertiesToInclude); - }, this); - }, - - /** - * @private - */ - _toObject: function(instance, methodName, propertiesToInclude) { - var originalValue; - - if (!this.includeDefaultValues) { - originalValue = instance.includeDefaultValues; - instance.includeDefaultValues = false; - } - - var object = instance[methodName](propertiesToInclude); - if (!this.includeDefaultValues) { - instance.includeDefaultValues = originalValue; - } - return object; - }, - - /** - * @private - */ - __serializeBgOverlay: function(methodName, propertiesToInclude) { - var data = {}, bgImage = this.backgroundImage, overlayImage = this.overlayImage, - bgColor = this.backgroundColor, overlayColor = this.overlayColor; - - if (bgColor && bgColor.toObject) { - if (!bgColor.excludeFromExport) { - data.background = bgColor.toObject(propertiesToInclude); - } - } - else if (bgColor) { - data.background = bgColor; - } - - if (overlayColor && overlayColor.toObject) { - if (!overlayColor.excludeFromExport) { - data.overlay = overlayColor.toObject(propertiesToInclude); - } - } - else if (overlayColor) { - data.overlay = overlayColor; - } - - if (bgImage && !bgImage.excludeFromExport) { - data.backgroundImage = this._toObject(bgImage, methodName, propertiesToInclude); - } - if (overlayImage && !overlayImage.excludeFromExport) { - data.overlayImage = this._toObject(overlayImage, methodName, propertiesToInclude); - } - - return data; - }, - - /* _TO_SVG_START_ */ - /** - * When true, getSvgTransform() will apply the StaticCanvas.viewportTransform to the SVG transformation. When true, - * a zoomed canvas will then produce zoomed SVG output. - * @type Boolean - * @default - */ - svgViewportTransformation: true, - - /** - * Returns SVG representation of canvas - * @function - * @param {Object} [options] Options object for SVG output - * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included - * @param {Object} [options.viewBox] SVG viewbox object - * @param {Number} [options.viewBox.x] x-coordinate of viewbox - * @param {Number} [options.viewBox.y] y-coordinate of viewbox - * @param {Number} [options.viewBox.width] Width of viewbox - * @param {Number} [options.viewBox.height] Height of viewbox - * @param {String} [options.encoding=UTF-8] Encoding of SVG output - * @param {String} [options.width] desired width of svg with or without units - * @param {String} [options.height] desired height of svg with or without units - * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation. - * @return {String} SVG string - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization} - * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo} - * @example Normal SVG output - * var svg = canvas.toSVG(); - * @example SVG output without preamble (without <?xml ../>) - * var svg = canvas.toSVG({suppressPreamble: true}); - * @example SVG output with viewBox attribute - * var svg = canvas.toSVG({ - * viewBox: { - * x: 100, - * y: 100, - * width: 200, - * height: 300 - * } - * }); - * @example SVG output with different encoding (default: UTF-8) - * var svg = canvas.toSVG({encoding: 'ISO-8859-1'}); - * @example Modify SVG output with reviver function - * var svg = canvas.toSVG(null, function(svg) { - * return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', ''); - * }); - */ - toSVG: function(options, reviver) { - options || (options = { }); - options.reviver = reviver; - var markup = []; - - this._setSVGPreamble(markup, options); - this._setSVGHeader(markup, options); - if (this.clipPath) { - markup.push('\n'); - } - this._setSVGBgOverlayColor(markup, 'background'); - this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver); - this._setSVGObjects(markup, reviver); - if (this.clipPath) { - markup.push('\n'); - } - this._setSVGBgOverlayColor(markup, 'overlay'); - this._setSVGBgOverlayImage(markup, 'overlayImage', reviver); - - markup.push(''); - - return markup.join(''); - }, - - /** - * @private - */ - _setSVGPreamble: function(markup, options) { - if (options.suppressPreamble) { - return; - } - markup.push( - '\n', - '\n' - ); - }, - - /** - * @private - */ - _setSVGHeader: function(markup, options) { - var width = options.width || this.width, - height = options.height || this.height, - vpt, viewBox = 'viewBox="0 0 ' + this.width + ' ' + this.height + '" ', - NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - - if (options.viewBox) { - viewBox = 'viewBox="' + - options.viewBox.x + ' ' + - options.viewBox.y + ' ' + - options.viewBox.width + ' ' + - options.viewBox.height + '" '; - } - else { - if (this.svgViewportTransformation) { - vpt = this.viewportTransform; - viewBox = 'viewBox="' + - toFixed(-vpt[4] / vpt[0], NUM_FRACTION_DIGITS) + ' ' + - toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS) + ' ' + - toFixed(this.width / vpt[0], NUM_FRACTION_DIGITS) + ' ' + - toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS) + '" '; - } - } - - markup.push( - '\n', - 'Created with Fabric.js ', fabric.version, '\n', - '\n', - this.createSVGFontFacesMarkup(), - this.createSVGRefElementsMarkup(), - this.createSVGClipPathMarkup(options), - '\n' - ); - }, - - createSVGClipPathMarkup: function(options) { - var clipPath = this.clipPath; - if (clipPath) { - clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++; - return '\n' + - this.clipPath.toClipPathSVG(options.reviver) + - '\n'; - } - return ''; - }, - - /** - * Creates markup containing SVG referenced elements like patterns, gradients etc. - * @return {String} - */ - createSVGRefElementsMarkup: function() { - var _this = this, - markup = ['background', 'overlay'].map(function(prop) { - var fill = _this[prop + 'Color']; - if (fill && fill.toLive) { - var shouldTransform = _this[prop + 'Vpt'], vpt = _this.viewportTransform, - object = { - width: _this.width / (shouldTransform ? vpt[0] : 1), - height: _this.height / (shouldTransform ? vpt[3] : 1) - }; - return fill.toSVG( - object, - { additionalTransform: shouldTransform ? fabric.util.matrixToSVG(vpt) : '' } - ); - } - }); - return markup.join(''); - }, - - /** - * Creates markup containing SVG font faces, - * font URLs for font faces must be collected by developers - * and are not extracted from the DOM by fabricjs - * @param {Array} objects Array of fabric objects - * @return {String} - */ - createSVGFontFacesMarkup: function() { - var markup = '', fontList = { }, obj, fontFamily, - style, row, rowIndex, _char, charIndex, i, len, - fontPaths = fabric.fontPaths, objects = []; - - this._objects.forEach(function add(object) { - objects.push(object); - if (object._objects) { - object._objects.forEach(add); - } - }); - - for (i = 0, len = objects.length; i < len; i++) { - obj = objects[i]; - fontFamily = obj.fontFamily; - if (obj.type.indexOf('text') === -1 || fontList[fontFamily] || !fontPaths[fontFamily]) { - continue; - } - fontList[fontFamily] = true; - if (!obj.styles) { - continue; - } - style = obj.styles; - for (rowIndex in style) { - row = style[rowIndex]; - for (charIndex in row) { - _char = row[charIndex]; - fontFamily = _char.fontFamily; - if (!fontList[fontFamily] && fontPaths[fontFamily]) { - fontList[fontFamily] = true; - } - } - } - } - - for (var j in fontList) { - markup += [ - '\t\t@font-face {\n', - '\t\t\tfont-family: \'', j, '\';\n', - '\t\t\tsrc: url(\'', fontPaths[j], '\');\n', - '\t\t}\n' - ].join(''); - } - - if (markup) { - markup = [ - '\t\n' - ].join(''); - } - - return markup; - }, - - /** - * @private - */ - _setSVGObjects: function(markup, reviver) { - var instance, i, len, objects = this._objects; - for (i = 0, len = objects.length; i < len; i++) { - instance = objects[i]; - if (instance.excludeFromExport) { - continue; - } - this._setSVGObject(markup, instance, reviver); - } - }, - - /** - * @private - */ - _setSVGObject: function(markup, instance, reviver) { - markup.push(instance.toSVG(reviver)); - }, - - /** - * @private - */ - _setSVGBgOverlayImage: function(markup, property, reviver) { - if (this[property] && !this[property].excludeFromExport && this[property].toSVG) { - markup.push(this[property].toSVG(reviver)); - } - }, - - /** - * @private - */ - _setSVGBgOverlayColor: function(markup, property) { - var filler = this[property + 'Color'], vpt = this.viewportTransform, finalWidth = this.width, - finalHeight = this.height; - if (!filler) { - return; - } - if (filler.toLive) { - var repeat = filler.repeat, iVpt = fabric.util.invertTransform(vpt), shouldInvert = this[property + 'Vpt'], - additionalTransform = shouldInvert ? fabric.util.matrixToSVG(iVpt) : ''; - markup.push( - '\n' - ); - } - else { - markup.push( - '\n' - ); - } - }, - /* _TO_SVG_END_ */ - - /** - * Moves an object or the objects of a multiple selection - * to the bottom of the stack of drawn objects - * @param {fabric.Object} object Object to send to back - * @return {fabric.Canvas} thisArg - * @chainable - */ - sendToBack: function (object) { - if (!object) { - return this; - } - var activeSelection = this._activeObject, - i, obj, objs; - if (object === activeSelection && object.type === 'activeSelection') { - objs = activeSelection._objects; - for (i = objs.length; i--;) { - obj = objs[i]; - removeFromArray(this._objects, obj); - this._objects.unshift(obj); - } - } - else { - removeFromArray(this._objects, object); - this._objects.unshift(object); - } - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * Moves an object or the objects of a multiple selection - * to the top of the stack of drawn objects - * @param {fabric.Object} object Object to send - * @return {fabric.Canvas} thisArg - * @chainable - */ - bringToFront: function (object) { - if (!object) { - return this; - } - var activeSelection = this._activeObject, - i, obj, objs; - if (object === activeSelection && object.type === 'activeSelection') { - objs = activeSelection._objects; - for (i = 0; i < objs.length; i++) { - obj = objs[i]; - removeFromArray(this._objects, obj); - this._objects.push(obj); - } - } - else { - removeFromArray(this._objects, object); - this._objects.push(object); - } - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * Moves an object or a selection down in stack of drawn objects - * An optional parameter, intersecting allows to move the object in behind - * the first intersecting object. Where intersection is calculated with - * bounding box. If no intersection is found, there will not be change in the - * stack. - * @param {fabric.Object} object Object to send - * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object - * @return {fabric.Canvas} thisArg - * @chainable - */ - sendBackwards: function (object, intersecting) { - if (!object) { - return this; - } - var activeSelection = this._activeObject, - i, obj, idx, newIdx, objs, objsMoved = 0; - - if (object === activeSelection && object.type === 'activeSelection') { - objs = activeSelection._objects; - for (i = 0; i < objs.length; i++) { - obj = objs[i]; - idx = this._objects.indexOf(obj); - if (idx > 0 + objsMoved) { - newIdx = idx - 1; - removeFromArray(this._objects, obj); - this._objects.splice(newIdx, 0, obj); - } - objsMoved++; - } - } - else { - idx = this._objects.indexOf(object); - if (idx !== 0) { - // if object is not on the bottom of stack - newIdx = this._findNewLowerIndex(object, idx, intersecting); - removeFromArray(this._objects, object); - this._objects.splice(newIdx, 0, object); - } - } - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * @private - */ - _findNewLowerIndex: function(object, idx, intersecting) { - var newIdx, i; - - if (intersecting) { - newIdx = idx; - - // traverse down the stack looking for the nearest intersecting object - for (i = idx - 1; i >= 0; --i) { - - var isIntersecting = object.intersectsWithObject(this._objects[i]) || - object.isContainedWithinObject(this._objects[i]) || - this._objects[i].isContainedWithinObject(object); - - if (isIntersecting) { - newIdx = i; - break; - } - } - } - else { - newIdx = idx - 1; - } - - return newIdx; - }, - - /** - * Moves an object or a selection up in stack of drawn objects - * An optional parameter, intersecting allows to move the object in front - * of the first intersecting object. Where intersection is calculated with - * bounding box. If no intersection is found, there will not be change in the - * stack. - * @param {fabric.Object} object Object to send - * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object - * @return {fabric.Canvas} thisArg - * @chainable - */ - bringForward: function (object, intersecting) { - if (!object) { - return this; - } - var activeSelection = this._activeObject, - i, obj, idx, newIdx, objs, objsMoved = 0; - - if (object === activeSelection && object.type === 'activeSelection') { - objs = activeSelection._objects; - for (i = objs.length; i--;) { - obj = objs[i]; - idx = this._objects.indexOf(obj); - if (idx < this._objects.length - 1 - objsMoved) { - newIdx = idx + 1; - removeFromArray(this._objects, obj); - this._objects.splice(newIdx, 0, obj); - } - objsMoved++; - } - } - else { - idx = this._objects.indexOf(object); - if (idx !== this._objects.length - 1) { - // if object is not on top of stack (last item in an array) - newIdx = this._findNewUpperIndex(object, idx, intersecting); - removeFromArray(this._objects, object); - this._objects.splice(newIdx, 0, object); - } - } - this.renderOnAddRemove && this.requestRenderAll(); - return this; - }, - - /** - * @private - */ - _findNewUpperIndex: function(object, idx, intersecting) { - var newIdx, i, len; - - if (intersecting) { - newIdx = idx; - - // traverse up the stack looking for the nearest intersecting object - for (i = idx + 1, len = this._objects.length; i < len; ++i) { - - var isIntersecting = object.intersectsWithObject(this._objects[i]) || - object.isContainedWithinObject(this._objects[i]) || - this._objects[i].isContainedWithinObject(object); - - if (isIntersecting) { - newIdx = i; - break; - } - } - } - else { - newIdx = idx + 1; - } - - return newIdx; - }, - - /** - * Moves an object to specified level in stack of drawn objects - * @param {fabric.Object} object Object to send - * @param {Number} index Position to move to - * @return {fabric.Canvas} thisArg - * @chainable - */ - moveTo: function (object, index) { - removeFromArray(this._objects, object); - this._objects.splice(index, 0, object); - return this.renderOnAddRemove && this.requestRenderAll(); - }, - - /** - * Clears a canvas element and dispose objects - * @return {fabric.Canvas} thisArg - * @chainable - */ - dispose: function () { - // cancel eventually ongoing renders - if (this.isRendering) { - fabric.util.cancelAnimFrame(this.isRendering); - this.isRendering = 0; - } - this.forEachObject(function(object) { - object.dispose && object.dispose(); - }); - this._objects = []; - if (this.backgroundImage && this.backgroundImage.dispose) { - this.backgroundImage.dispose(); - } - this.backgroundImage = null; - if (this.overlayImage && this.overlayImage.dispose) { - this.overlayImage.dispose(); - } - this.overlayImage = null; - this._iTextInstances = null; - this.contextContainer = null; - // restore canvas style - this.lowerCanvasEl.classList.remove('lower-canvas'); - fabric.util.setStyle(this.lowerCanvasEl, this._originalCanvasStyle); - delete this._originalCanvasStyle; - // restore canvas size to original size in case retina scaling was applied - this.lowerCanvasEl.setAttribute('width', this.width); - this.lowerCanvasEl.setAttribute('height', this.height); - fabric.util.cleanUpJsdomNode(this.lowerCanvasEl); - this.lowerCanvasEl = undefined; - return this; - }, - - /** - * Returns a string representation of an instance - * @return {String} string representation of an instance - */ - toString: function () { - return '#'; - } - }); - - extend(fabric.StaticCanvas.prototype, fabric.Observable); - extend(fabric.StaticCanvas.prototype, fabric.Collection); - extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter); - - extend(fabric.StaticCanvas, /** @lends fabric.StaticCanvas */ { - - /** - * @static - * @type String - * @default - */ - EMPTY_JSON: '{"objects": [], "background": "white"}', - - /** - * Provides a way to check support of some of the canvas methods - * (either those of HTMLCanvasElement itself, or rendering context) - * - * @param {String} methodName Method to check support for; - * Could be one of "setLineDash" - * @return {Boolean | null} `true` if method is supported (or at least exists), - * `null` if canvas element or context can not be initialized - */ - supports: function (methodName) { - var el = createCanvasElement(); - - if (!el || !el.getContext) { - return null; - } - - var ctx = el.getContext('2d'); - if (!ctx) { - return null; - } - - switch (methodName) { - - case 'setLineDash': - return typeof ctx.setLineDash !== 'undefined'; - - default: - return null; - } - } - }); - - /** - * Returns Object representation of canvas - * this alias is provided because if you call JSON.stringify on an instance, - * the toJSON object will be invoked if it exists. - * Having a toJSON method means you can do JSON.stringify(myCanvas) - * @function - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} JSON compatible object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization} - * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo} - * @example JSON without additional properties - * var json = canvas.toJSON(); - * @example JSON with additional properties included - * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY']); - * @example JSON without default values - * canvas.includeDefaultValues = false; - * var json = canvas.toJSON(); - */ - fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject; - - if (fabric.isLikelyNode) { - fabric.StaticCanvas.prototype.createPNGStream = function() { - var impl = getNodeCanvas(this.lowerCanvasEl); - return impl && impl.createPNGStream(); - }; - fabric.StaticCanvas.prototype.createJPEGStream = function(opts) { - var impl = getNodeCanvas(this.lowerCanvasEl); - return impl && impl.createJPEGStream(opts); - }; - } -})(); - - -/** - * BaseBrush class - * @class fabric.BaseBrush - * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo} - */ -fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ { - - /** - * Color of a brush - * @type String - * @default - */ - color: 'rgb(0, 0, 0)', - - /** - * Width of a brush, has to be a Number, no string literals - * @type Number - * @default - */ - width: 1, - - /** - * Shadow object representing shadow of this shape. - * Backwards incompatibility note: This property replaces "shadowColor" (String), "shadowOffsetX" (Number), - * "shadowOffsetY" (Number) and "shadowBlur" (Number) since v1.2.12 - * @type fabric.Shadow - * @default - */ - shadow: null, - - /** - * Line endings style of a brush (one of "butt", "round", "square") - * @type String - * @default - */ - strokeLineCap: 'round', - - /** - * Corner style of a brush (one of "bevel", "round", "miter") - * @type String - * @default - */ - strokeLineJoin: 'round', - - /** - * Maximum miter length (used for strokeLineJoin = "miter") of a brush's - * @type Number - * @default - */ - strokeMiterLimit: 10, - - /** - * Stroke Dash Array. - * @type Array - * @default - */ - strokeDashArray: null, - - /** - * When `true`, the free drawing is limited to the whiteboard size. Default to false. - * @type Boolean - * @default false - */ - - limitedToCanvasSize: false, - - - /** - * Sets brush styles - * @private - * @param {CanvasRenderingContext2D} ctx - */ - _setBrushStyles: function (ctx) { - ctx.strokeStyle = this.color; - ctx.lineWidth = this.width; - ctx.lineCap = this.strokeLineCap; - ctx.miterLimit = this.strokeMiterLimit; - ctx.lineJoin = this.strokeLineJoin; - ctx.setLineDash(this.strokeDashArray || []); - }, - - /** - * Sets the transformation on given context - * @param {RenderingContext2d} ctx context to render on - * @private - */ - _saveAndTransform: function(ctx) { - var v = this.canvas.viewportTransform; - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - }, - - /** - * Sets brush shadow styles - * @private - */ - _setShadow: function() { - if (!this.shadow) { - return; - } - - var canvas = this.canvas, - shadow = this.shadow, - ctx = canvas.contextTop, - zoom = canvas.getZoom(); - if (canvas && canvas._isRetinaScaling()) { - zoom *= fabric.devicePixelRatio; - } - - ctx.shadowColor = shadow.color; - ctx.shadowBlur = shadow.blur * zoom; - ctx.shadowOffsetX = shadow.offsetX * zoom; - ctx.shadowOffsetY = shadow.offsetY * zoom; - }, - - needsFullRender: function() { - var color = new fabric.Color(this.color); - return color.getAlpha() < 1 || !!this.shadow; - }, - - /** - * Removes brush shadow styles - * @private - */ - _resetShadow: function() { - var ctx = this.canvas.contextTop; - - ctx.shadowColor = ''; - ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0; - }, - - /** - * Check is pointer is outside canvas boundaries - * @param {Object} pointer - * @private - */ - _isOutSideCanvas: function(pointer) { - return pointer.x < 0 || pointer.x > this.canvas.getWidth() || pointer.y < 0 || pointer.y > this.canvas.getHeight(); - } -}); - - -(function() { - /** - * PencilBrush class - * @class fabric.PencilBrush - * @extends fabric.BaseBrush - */ - fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.PencilBrush.prototype */ { - - /** - * Discard points that are less than `decimate` pixel distant from each other - * @type Number - * @default 0.4 - */ - decimate: 0.4, - - /** - * Draws a straight line between last recorded point to current pointer - * Used for `shift` functionality - * - * @type boolean - * @default false - */ - drawStraightLine: false, - - /** - * The event modifier key that makes the brush draw a straight line. - * If `null` or 'none' or any other string that is not a modifier key the feature is disabled. - * @type {'altKey' | 'shiftKey' | 'ctrlKey' | 'none' | undefined | null} - */ - straightLineKey: 'shiftKey', - - /** - * Constructor - * @param {fabric.Canvas} canvas - * @return {fabric.PencilBrush} Instance of a pencil brush - */ - initialize: function(canvas) { - this.canvas = canvas; - this._points = []; - }, - - needsFullRender: function () { - return this.callSuper('needsFullRender') || this._hasStraightLine; - }, - - /** - * Invoked inside on mouse down and mouse move - * @param {Object} pointer - */ - _drawSegment: function (ctx, p1, p2) { - var midPoint = p1.midPointFrom(p2); - ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y); - return midPoint; - }, - - /** - * Invoked on mouse down - * @param {Object} pointer - */ - onMouseDown: function(pointer, options) { - if (!this.canvas._isMainEvent(options.e)) { - return; - } - this.drawStraightLine = options.e[this.straightLineKey]; - this._prepareForDrawing(pointer); - // capture coordinates immediately - // this allows to draw dots (when movement never occurs) - this._captureDrawingPath(pointer); - this._render(); - }, - - /** - * Invoked on mouse move - * @param {Object} pointer - */ - onMouseMove: function(pointer, options) { - if (!this.canvas._isMainEvent(options.e)) { - return; - } - this.drawStraightLine = options.e[this.straightLineKey]; - if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) { - return; - } - if (this._captureDrawingPath(pointer) && this._points.length > 1) { - if (this.needsFullRender()) { - // redraw curve - // clear top canvas - this.canvas.clearContext(this.canvas.contextTop); - this._render(); - } - else { - var points = this._points, length = points.length, ctx = this.canvas.contextTop; - // draw the curve update - this._saveAndTransform(ctx); - if (this.oldEnd) { - ctx.beginPath(); - ctx.moveTo(this.oldEnd.x, this.oldEnd.y); - } - this.oldEnd = this._drawSegment(ctx, points[length - 2], points[length - 1], true); - ctx.stroke(); - ctx.restore(); - } - } - }, - - /** - * Invoked on mouse up - */ - onMouseUp: function(options) { - if (!this.canvas._isMainEvent(options.e)) { - return true; - } - this.drawStraightLine = false; - this.oldEnd = undefined; - this._finalizeAndAddPath(); - return false; - }, - - /** - * @private - * @param {Object} pointer Actual mouse position related to the canvas. - */ - _prepareForDrawing: function(pointer) { - - var p = new fabric.Point(pointer.x, pointer.y); - - this._reset(); - this._addPoint(p); - this.canvas.contextTop.moveTo(p.x, p.y); - }, - - /** - * @private - * @param {fabric.Point} point Point to be added to points array - */ - _addPoint: function(point) { - if (this._points.length > 1 && point.eq(this._points[this._points.length - 1])) { - return false; - } - if (this.drawStraightLine && this._points.length > 1) { - this._hasStraightLine = true; - this._points.pop(); - } - this._points.push(point); - return true; - }, - - /** - * Clear points array and set contextTop canvas style. - * @private - */ - _reset: function() { - this._points = []; - this._setBrushStyles(this.canvas.contextTop); - this._setShadow(); - this._hasStraightLine = false; - }, - - /** - * @private - * @param {Object} pointer Actual mouse position related to the canvas. - */ - _captureDrawingPath: function(pointer) { - var pointerPoint = new fabric.Point(pointer.x, pointer.y); - return this._addPoint(pointerPoint); - }, - - /** - * Draw a smooth path on the topCanvas using quadraticCurveTo - * @private - * @param {CanvasRenderingContext2D} [ctx] - */ - _render: function(ctx) { - var i, len, - p1 = this._points[0], - p2 = this._points[1]; - ctx = ctx || this.canvas.contextTop; - this._saveAndTransform(ctx); - ctx.beginPath(); - //if we only have 2 points in the path and they are the same - //it means that the user only clicked the canvas without moving the mouse - //then we should be drawing a dot. A path isn't drawn between two identical dots - //that's why we set them apart a bit - if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) { - var width = this.width / 1000; - p1 = new fabric.Point(p1.x, p1.y); - p2 = new fabric.Point(p2.x, p2.y); - p1.x -= width; - p2.x += width; - } - ctx.moveTo(p1.x, p1.y); - - for (i = 1, len = this._points.length; i < len; i++) { - // we pick the point between pi + 1 & pi + 2 as the - // end point and p1 as our control point. - this._drawSegment(ctx, p1, p2); - p1 = this._points[i]; - p2 = this._points[i + 1]; - } - // Draw last line as a straight line while - // we wait for the next point to be able to calculate - // the bezier control point - ctx.lineTo(p1.x, p1.y); - ctx.stroke(); - ctx.restore(); - }, - - /** - * Converts points to SVG path - * @param {Array} points Array of points - * @return {(string|number)[][]} SVG path commands - */ - convertPointsToSVGPath: function (points) { - var correction = this.width / 1000; - return fabric.util.getSmoothPathFromPoints(points, correction); - }, - - /** - * @private - * @param {(string|number)[][]} pathData SVG path commands - * @returns {boolean} - */ - _isEmptySVGPath: function (pathData) { - var pathString = fabric.util.joinPath(pathData); - return pathString === 'M 0 0 Q 0 0 0 0 L 0 0'; - }, - - /** - * Creates fabric.Path object to add on canvas - * @param {(string|number)[][]} pathData Path data - * @return {fabric.Path} Path to add on canvas - */ - createPath: function(pathData) { - var path = new fabric.Path(pathData, { - fill: null, - stroke: this.color, - strokeWidth: this.width, - strokeLineCap: this.strokeLineCap, - strokeMiterLimit: this.strokeMiterLimit, - strokeLineJoin: this.strokeLineJoin, - strokeDashArray: this.strokeDashArray, - }); - if (this.shadow) { - this.shadow.affectStroke = true; - path.shadow = new fabric.Shadow(this.shadow); - } - - return path; - }, - - /** - * Decimate points array with the decimate value - */ - decimatePoints: function(points, distance) { - if (points.length <= 2) { - return points; - } - var zoom = this.canvas.getZoom(), adjustedDistance = Math.pow(distance / zoom, 2), - i, l = points.length - 1, lastPoint = points[0], newPoints = [lastPoint], - cDistance; - for (i = 1; i < l - 1; i++) { - cDistance = Math.pow(lastPoint.x - points[i].x, 2) + Math.pow(lastPoint.y - points[i].y, 2); - if (cDistance >= adjustedDistance) { - lastPoint = points[i]; - newPoints.push(lastPoint); - } - } - /** - * Add the last point from the original line to the end of the array. - * This ensures decimate doesn't delete the last point on the line, and ensures the line is > 1 point. - */ - newPoints.push(points[l]); - return newPoints; - }, - - /** - * On mouseup after drawing the path on contextTop canvas - * we use the points captured to create an new fabric path object - * and add it to the fabric canvas. - */ - _finalizeAndAddPath: function() { - var ctx = this.canvas.contextTop; - ctx.closePath(); - if (this.decimate) { - this._points = this.decimatePoints(this._points, this.decimate); - } - var pathData = this.convertPointsToSVGPath(this._points); - if (this._isEmptySVGPath(pathData)) { - // do not create 0 width/height paths, as they are - // rendered inconsistently across browsers - // Firefox 4, for example, renders a dot, - // whereas Chrome 10 renders nothing - this.canvas.requestRenderAll(); - return; - } - - var path = this.createPath(pathData); - this.canvas.clearContext(this.canvas.contextTop); - this.canvas.fire('before:path:created', { path: path }); - this.canvas.add(path); - this.canvas.requestRenderAll(); - path.setCoords(); - this._resetShadow(); - - - // fire event 'path' created - this.canvas.fire('path:created', { path: path }); - } - }); -})(); - - -/** - * CircleBrush class - * @class fabric.CircleBrush - */ -fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.CircleBrush.prototype */ { - - /** - * Width of a brush - * @type Number - * @default - */ - width: 10, - - /** - * Constructor - * @param {fabric.Canvas} canvas - * @return {fabric.CircleBrush} Instance of a circle brush - */ - initialize: function(canvas) { - this.canvas = canvas; - this.points = []; - }, - - /** - * Invoked inside on mouse down and mouse move - * @param {Object} pointer - */ - drawDot: function(pointer) { - var point = this.addPoint(pointer), - ctx = this.canvas.contextTop; - this._saveAndTransform(ctx); - this.dot(ctx, point); - ctx.restore(); - }, - - dot: function(ctx, point) { - ctx.fillStyle = point.fill; - ctx.beginPath(); - ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false); - ctx.closePath(); - ctx.fill(); - }, - - /** - * Invoked on mouse down - */ - onMouseDown: function(pointer) { - this.points.length = 0; - this.canvas.clearContext(this.canvas.contextTop); - this._setShadow(); - this.drawDot(pointer); - }, - - /** - * Render the full state of the brush - * @private - */ - _render: function() { - var ctx = this.canvas.contextTop, i, len, - points = this.points; - this._saveAndTransform(ctx); - for (i = 0, len = points.length; i < len; i++) { - this.dot(ctx, points[i]); - } - ctx.restore(); - }, - - /** - * Invoked on mouse move - * @param {Object} pointer - */ - onMouseMove: function(pointer) { - if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) { - return; - } - if (this.needsFullRender()) { - this.canvas.clearContext(this.canvas.contextTop); - this.addPoint(pointer); - this._render(); - } - else { - this.drawDot(pointer); - } - }, - - /** - * Invoked on mouse up - */ - onMouseUp: function() { - var originalRenderOnAddRemove = this.canvas.renderOnAddRemove, i, len; - this.canvas.renderOnAddRemove = false; - - var circles = []; - - for (i = 0, len = this.points.length; i < len; i++) { - var point = this.points[i], - circle = new fabric.Circle({ - radius: point.radius, - left: point.x, - top: point.y, - originX: 'center', - originY: 'center', - fill: point.fill - }); - - this.shadow && (circle.shadow = new fabric.Shadow(this.shadow)); - - circles.push(circle); - } - var group = new fabric.Group(circles); - group.canvas = this.canvas; - - this.canvas.fire('before:path:created', { path: group }); - this.canvas.add(group); - this.canvas.fire('path:created', { path: group }); - - this.canvas.clearContext(this.canvas.contextTop); - this._resetShadow(); - this.canvas.renderOnAddRemove = originalRenderOnAddRemove; - this.canvas.requestRenderAll(); - }, - - /** - * @param {Object} pointer - * @return {fabric.Point} Just added pointer point - */ - addPoint: function(pointer) { - var pointerPoint = new fabric.Point(pointer.x, pointer.y), - - circleRadius = fabric.util.getRandomInt( - Math.max(0, this.width - 20), this.width + 20) / 2, - - circleColor = new fabric.Color(this.color) - .setAlpha(fabric.util.getRandomInt(0, 100) / 100) - .toRgba(); - - pointerPoint.radius = circleRadius; - pointerPoint.fill = circleColor; - - this.points.push(pointerPoint); - - return pointerPoint; - } -}); - - -/** - * SprayBrush class - * @class fabric.SprayBrush - */ -fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric.SprayBrush.prototype */ { - - /** - * Width of a spray - * @type Number - * @default - */ - width: 10, - - /** - * Density of a spray (number of dots per chunk) - * @type Number - * @default - */ - density: 20, - - /** - * Width of spray dots - * @type Number - * @default - */ - dotWidth: 1, - - /** - * Width variance of spray dots - * @type Number - * @default - */ - dotWidthVariance: 1, - - /** - * Whether opacity of a dot should be random - * @type Boolean - * @default - */ - randomOpacity: false, - - /** - * Whether overlapping dots (rectangles) should be removed (for performance reasons) - * @type Boolean - * @default - */ - optimizeOverlapping: true, - - /** - * Constructor - * @param {fabric.Canvas} canvas - * @return {fabric.SprayBrush} Instance of a spray brush - */ - initialize: function(canvas) { - this.canvas = canvas; - this.sprayChunks = []; - }, - - /** - * Invoked on mouse down - * @param {Object} pointer - */ - onMouseDown: function(pointer) { - this.sprayChunks.length = 0; - this.canvas.clearContext(this.canvas.contextTop); - this._setShadow(); - - this.addSprayChunk(pointer); - this.render(this.sprayChunkPoints); - }, - - /** - * Invoked on mouse move - * @param {Object} pointer - */ - onMouseMove: function(pointer) { - if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) { - return; - } - this.addSprayChunk(pointer); - this.render(this.sprayChunkPoints); - }, - - /** - * Invoked on mouse up - */ - onMouseUp: function() { - var originalRenderOnAddRemove = this.canvas.renderOnAddRemove; - this.canvas.renderOnAddRemove = false; - - var rects = []; - - for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) { - var sprayChunk = this.sprayChunks[i]; - - for (var j = 0, jlen = sprayChunk.length; j < jlen; j++) { - - var rect = new fabric.Rect({ - width: sprayChunk[j].width, - height: sprayChunk[j].width, - left: sprayChunk[j].x + 1, - top: sprayChunk[j].y + 1, - originX: 'center', - originY: 'center', - fill: this.color - }); - rects.push(rect); - } - } - - if (this.optimizeOverlapping) { - rects = this._getOptimizedRects(rects); - } - - var group = new fabric.Group(rects); - this.shadow && group.set('shadow', new fabric.Shadow(this.shadow)); - this.canvas.fire('before:path:created', { path: group }); - this.canvas.add(group); - this.canvas.fire('path:created', { path: group }); - - this.canvas.clearContext(this.canvas.contextTop); - this._resetShadow(); - this.canvas.renderOnAddRemove = originalRenderOnAddRemove; - this.canvas.requestRenderAll(); - }, - - /** - * @private - * @param {Array} rects - */ - _getOptimizedRects: function(rects) { - - // avoid creating duplicate rects at the same coordinates - var uniqueRects = { }, key, i, len; - - for (i = 0, len = rects.length; i < len; i++) { - key = rects[i].left + '' + rects[i].top; - if (!uniqueRects[key]) { - uniqueRects[key] = rects[i]; - } - } - var uniqueRectsArray = []; - for (key in uniqueRects) { - uniqueRectsArray.push(uniqueRects[key]); - } - - return uniqueRectsArray; - }, - - /** - * Render new chunk of spray brush - */ - render: function(sprayChunk) { - var ctx = this.canvas.contextTop, i, len; - ctx.fillStyle = this.color; - - this._saveAndTransform(ctx); - - for (i = 0, len = sprayChunk.length; i < len; i++) { - var point = sprayChunk[i]; - if (typeof point.opacity !== 'undefined') { - ctx.globalAlpha = point.opacity; - } - ctx.fillRect(point.x, point.y, point.width, point.width); - } - ctx.restore(); - }, - - /** - * Render all spray chunks - */ - _render: function() { - var ctx = this.canvas.contextTop, i, ilen; - ctx.fillStyle = this.color; - - this._saveAndTransform(ctx); - - for (i = 0, ilen = this.sprayChunks.length; i < ilen; i++) { - this.render(this.sprayChunks[i]); - } - ctx.restore(); - }, - - /** - * @param {Object} pointer - */ - addSprayChunk: function(pointer) { - this.sprayChunkPoints = []; - - var x, y, width, radius = this.width / 2, i; - - for (i = 0; i < this.density; i++) { - - x = fabric.util.getRandomInt(pointer.x - radius, pointer.x + radius); - y = fabric.util.getRandomInt(pointer.y - radius, pointer.y + radius); - - if (this.dotWidthVariance) { - width = fabric.util.getRandomInt( - // bottom clamp width to 1 - Math.max(1, this.dotWidth - this.dotWidthVariance), - this.dotWidth + this.dotWidthVariance); - } - else { - width = this.dotWidth; - } - - var point = new fabric.Point(x, y); - point.width = width; - - if (this.randomOpacity) { - point.opacity = fabric.util.getRandomInt(0, 100) / 100; - } - - this.sprayChunkPoints.push(point); - } - - this.sprayChunks.push(this.sprayChunkPoints); - } -}); - - -/** - * PatternBrush class - * @class fabric.PatternBrush - * @extends fabric.BaseBrush - */ -fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fabric.PatternBrush.prototype */ { - - getPatternSrc: function() { - - var dotWidth = 20, - dotDistance = 5, - patternCanvas = fabric.util.createCanvasElement(), - patternCtx = patternCanvas.getContext('2d'); - - patternCanvas.width = patternCanvas.height = dotWidth + dotDistance; - - patternCtx.fillStyle = this.color; - patternCtx.beginPath(); - patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false); - patternCtx.closePath(); - patternCtx.fill(); - - return patternCanvas; - }, - - getPatternSrcFunction: function() { - return String(this.getPatternSrc).replace('this.color', '"' + this.color + '"'); - }, - - /** - * Creates "pattern" instance property - * @param {CanvasRenderingContext2D} ctx - */ - getPattern: function(ctx) { - return ctx.createPattern(this.source || this.getPatternSrc(), 'repeat'); - }, - - /** - * Sets brush styles - * @param {CanvasRenderingContext2D} ctx - */ - _setBrushStyles: function(ctx) { - this.callSuper('_setBrushStyles', ctx); - ctx.strokeStyle = this.getPattern(ctx); - }, - - /** - * Creates path - */ - createPath: function(pathData) { - var path = this.callSuper('createPath', pathData), - topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2); - - path.stroke = new fabric.Pattern({ - source: this.source || this.getPatternSrcFunction(), - offsetX: -topLeft.x, - offsetY: -topLeft.y - }); - return path; - } -}); - - -(function() { - - var getPointer = fabric.util.getPointer, - degreesToRadians = fabric.util.degreesToRadians, - isTouchEvent = fabric.util.isTouchEvent; - - /** - * Canvas class - * @class fabric.Canvas - * @extends fabric.StaticCanvas - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas} - * @see {@link fabric.Canvas#initialize} for constructor definition - * - * @fires object:modified at the end of a transform or any change when statefull is true - * @fires object:rotating while an object is being rotated from the control - * @fires object:scaling while an object is being scaled by controls - * @fires object:moving while an object is being dragged - * @fires object:skewing while an object is being skewed from the controls - * - * @fires before:transform before a transform is is started - * @fires before:selection:cleared - * @fires selection:cleared - * @fires selection:updated - * @fires selection:created - * - * @fires path:created after a drawing operation ends and the path is added - * @fires mouse:down - * @fires mouse:move - * @fires mouse:up - * @fires mouse:down:before on mouse down, before the inner fabric logic runs - * @fires mouse:move:before on mouse move, before the inner fabric logic runs - * @fires mouse:up:before on mouse up, before the inner fabric logic runs - * @fires mouse:over - * @fires mouse:out - * @fires mouse:dblclick whenever a native dbl click event fires on the canvas. - * - * @fires dragover - * @fires dragenter - * @fires dragleave - * @fires drop:before before drop event. same native event. This is added to handle edge cases - * @fires drop - * @fires after:render at the end of the render process, receives the context in the callback - * @fires before:render at start the render process, receives the context in the callback - * - */ - fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, /** @lends fabric.Canvas.prototype */ { - - /** - * Constructor - * @param {HTMLElement | String} el <canvas> element to initialize instance on - * @param {Object} [options] Options object - * @return {Object} thisArg - */ - initialize: function(el, options) { - options || (options = { }); - this.renderAndResetBound = this.renderAndReset.bind(this); - this.requestRenderAllBound = this.requestRenderAll.bind(this); - this._initStatic(el, options); - this._initInteractive(); - this._createCacheCanvas(); - }, - - /** - * When true, objects can be transformed by one side (unproportionally) - * when dragged on the corners that normally would not do that. - * @type Boolean - * @default - * @since fabric 4.0 // changed name and default value - */ - uniformScaling: true, - - /** - * Indicates which key switches uniform scaling. - * values: 'altKey', 'shiftKey', 'ctrlKey'. - * If `null` or 'none' or any other string that is not a modifier key - * feature is disabled. - * totally wrong named. this sounds like `uniform scaling` - * if Canvas.uniformScaling is true, pressing this will set it to false - * and viceversa. - * @since 1.6.2 - * @type String - * @default - */ - uniScaleKey: 'shiftKey', - - /** - * When true, objects use center point as the origin of scale transformation. - * Backwards incompatibility note: This property replaces "centerTransform" (Boolean). - * @since 1.3.4 - * @type Boolean - * @default - */ - centeredScaling: false, - - /** - * When true, objects use center point as the origin of rotate transformation. - * Backwards incompatibility note: This property replaces "centerTransform" (Boolean). - * @since 1.3.4 - * @type Boolean - * @default - */ - centeredRotation: false, - - /** - * Indicates which key enable centered Transform - * values: 'altKey', 'shiftKey', 'ctrlKey'. - * If `null` or 'none' or any other string that is not a modifier key - * feature is disabled feature disabled. - * @since 1.6.2 - * @type String - * @default - */ - centeredKey: 'altKey', - - /** - * Indicates which key enable alternate action on corner - * values: 'altKey', 'shiftKey', 'ctrlKey'. - * If `null` or 'none' or any other string that is not a modifier key - * feature is disabled feature disabled. - * @since 1.6.2 - * @type String - * @default - */ - altActionKey: 'shiftKey', - - /** - * Indicates that canvas is interactive. This property should not be changed. - * @type Boolean - * @default - */ - interactive: true, - - /** - * Indicates whether group selection should be enabled - * @type Boolean - * @default - */ - selection: true, - - /** - * Indicates which key or keys enable multiple click selection - * Pass value as a string or array of strings - * values: 'altKey', 'shiftKey', 'ctrlKey'. - * If `null` or empty or containing any other string that is not a modifier key - * feature is disabled. - * @since 1.6.2 - * @type String|Array - * @default - */ - selectionKey: 'shiftKey', - - /** - * Indicates which key enable alternative selection - * in case of target overlapping with active object - * values: 'altKey', 'shiftKey', 'ctrlKey'. - * For a series of reason that come from the general expectations on how - * things should work, this feature works only for preserveObjectStacking true. - * If `null` or 'none' or any other string that is not a modifier key - * feature is disabled. - * @since 1.6.5 - * @type null|String - * @default - */ - altSelectionKey: null, - - /** - * Color of selection - * @type String - * @default - */ - selectionColor: 'rgba(100, 100, 255, 0.3)', // blue - - /** - * Default dash array pattern - * If not empty the selection border is dashed - * @type Array - */ - selectionDashArray: [], - - /** - * Color of the border of selection (usually slightly darker than color of selection itself) - * @type String - * @default - */ - selectionBorderColor: 'rgba(255, 255, 255, 0.3)', - - /** - * Width of a line used in object/group selection - * @type Number - * @default - */ - selectionLineWidth: 1, - - /** - * Select only shapes that are fully contained in the dragged selection rectangle. - * @type Boolean - * @default - */ - selectionFullyContained: false, - - /** - * Default cursor value used when hovering over an object on canvas - * @type String - * @default - */ - hoverCursor: 'move', - - /** - * Default cursor value used when moving an object on canvas - * @type String - * @default - */ - moveCursor: 'move', - - /** - * Default cursor value used for the entire canvas - * @type String - * @default - */ - defaultCursor: 'default', - - /** - * Cursor value used during free drawing - * @type String - * @default - */ - freeDrawingCursor: 'crosshair', - - /** - * Cursor value used for disabled elements ( corners with disabled action ) - * @type String - * @since 2.0.0 - * @default - */ - notAllowedCursor: 'not-allowed', - - /** - * Default element class that's given to wrapper (div) element of canvas - * @type String - * @default - */ - containerClass: 'canvas-container', - - /** - * When true, object detection happens on per-pixel basis rather than on per-bounding-box - * @type Boolean - * @default - */ - perPixelTargetFind: false, - - /** - * Number of pixels around target pixel to tolerate (consider active) during object detection - * @type Number - * @default - */ - targetFindTolerance: 0, - - /** - * When true, target detection is skipped. Target detection will return always undefined. - * click selection won't work anymore, events will fire with no targets. - * if something is selected before setting it to true, it will be deselected at the first click. - * area selection will still work. check the `selection` property too. - * if you deactivate both, you should look into staticCanvas. - * @type Boolean - * @default - */ - skipTargetFind: false, - - /** - * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing. - * After mousedown, mousemove creates a shape, - * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas. - * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing} - * @type Boolean - * @default - */ - isDrawingMode: false, - - /** - * Indicates whether objects should remain in current stack position when selected. - * When false objects are brought to top and rendered as part of the selection group - * @type Boolean - * @default - */ - preserveObjectStacking: false, - - /** - * Indicates the angle that an object will lock to while rotating. - * @type Number - * @since 1.6.7 - * @default - */ - snapAngle: 0, - - /** - * Indicates the distance from the snapAngle the rotation will lock to the snapAngle. - * When `null`, the snapThreshold will default to the snapAngle. - * @type null|Number - * @since 1.6.7 - * @default - */ - snapThreshold: null, - - /** - * Indicates if the right click on canvas can output the context menu or not - * @type Boolean - * @since 1.6.5 - * @default - */ - stopContextMenu: false, - - /** - * Indicates if the canvas can fire right click events - * @type Boolean - * @since 1.6.5 - * @default - */ - fireRightClick: false, - - /** - * Indicates if the canvas can fire middle click events - * @type Boolean - * @since 1.7.8 - * @default - */ - fireMiddleClick: false, - - /** - * Keep track of the subTargets for Mouse Events - * @type fabric.Object[] - */ - targets: [], - - /** - * When the option is enabled, PointerEvent is used instead of MouseEvent. - * @type Boolean - * @default - */ - enablePointerEvents: false, - - /** - * Keep track of the hovered target - * @type fabric.Object - * @private - */ - _hoveredTarget: null, - - /** - * hold the list of nested targets hovered - * @type fabric.Object[] - * @private - */ - _hoveredTargets: [], - - /** - * @private - */ - _initInteractive: function() { - this._currentTransform = null; - this._groupSelector = null; - this._initWrapperElement(); - this._createUpperCanvas(); - this._initEventListeners(); - - this._initRetinaScaling(); - - this.freeDrawingBrush = fabric.PencilBrush && new fabric.PencilBrush(this); - - this.calcOffset(); - }, - - /** - * Divides objects in two groups, one to render immediately - * and one to render as activeGroup. - * @return {Array} objects to render immediately and pushes the other in the activeGroup. - */ - _chooseObjectsToRender: function() { - var activeObjects = this.getActiveObjects(), - object, objsToRender, activeGroupObjects; - - if (activeObjects.length > 0 && !this.preserveObjectStacking) { - objsToRender = []; - activeGroupObjects = []; - for (var i = 0, length = this._objects.length; i < length; i++) { - object = this._objects[i]; - if (activeObjects.indexOf(object) === -1 ) { - objsToRender.push(object); - } - else { - activeGroupObjects.push(object); - } - } - if (activeObjects.length > 1) { - this._activeObject._objects = activeGroupObjects; - } - objsToRender.push.apply(objsToRender, activeGroupObjects); - } - else { - objsToRender = this._objects; - } - return objsToRender; - }, - - /** - * Renders both the top canvas and the secondary container canvas. - * @return {fabric.Canvas} instance - * @chainable - */ - renderAll: function () { - if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) { - this.clearContext(this.contextTop); - this.contextTopDirty = false; - } - if (this.hasLostContext) { - this.renderTopLayer(this.contextTop); - this.hasLostContext = false; - } - var canvasToDrawOn = this.contextContainer; - this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender()); - return this; - }, - - renderTopLayer: function(ctx) { - ctx.save(); - if (this.isDrawingMode && this._isCurrentlyDrawing) { - this.freeDrawingBrush && this.freeDrawingBrush._render(); - this.contextTopDirty = true; - } - // we render the top context - last object - if (this.selection && this._groupSelector) { - this._drawSelection(ctx); - this.contextTopDirty = true; - } - ctx.restore(); - }, - - /** - * Method to render only the top canvas. - * Also used to render the group selection box. - * @return {fabric.Canvas} thisArg - * @chainable - */ - renderTop: function () { - var ctx = this.contextTop; - this.clearContext(ctx); - this.renderTopLayer(ctx); - this.fire('after:render'); - return this; - }, - - /** - * @private - */ - _normalizePointer: function (object, pointer) { - var m = object.calcTransformMatrix(), - invertedM = fabric.util.invertTransform(m), - vptPointer = this.restorePointerVpt(pointer); - return fabric.util.transformPoint(vptPointer, invertedM); - }, - - /** - * Returns true if object is transparent at a certain location - * @param {fabric.Object} target Object to check - * @param {Number} x Left coordinate - * @param {Number} y Top coordinate - * @return {Boolean} - */ - isTargetTransparent: function (target, x, y) { - // in case the target is the activeObject, we cannot execute this optimization - // because we need to draw controls too. - if (target.shouldCache() && target._cacheCanvas && target !== this._activeObject) { - var normalizedPointer = this._normalizePointer(target, {x: x, y: y}), - targetRelativeX = Math.max(target.cacheTranslationX + (normalizedPointer.x * target.zoomX), 0), - targetRelativeY = Math.max(target.cacheTranslationY + (normalizedPointer.y * target.zoomY), 0); - - var isTransparent = fabric.util.isTransparent( - target._cacheContext, Math.round(targetRelativeX), Math.round(targetRelativeY), this.targetFindTolerance); - - return isTransparent; - } - - var ctx = this.contextCache, - originalColor = target.selectionBackgroundColor, v = this.viewportTransform; - - target.selectionBackgroundColor = ''; - - this.clearContext(ctx); - - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - target.render(ctx); - ctx.restore(); - - target.selectionBackgroundColor = originalColor; - - var isTransparent = fabric.util.isTransparent( - ctx, x, y, this.targetFindTolerance); - - return isTransparent; - }, - - /** - * takes an event and determines if selection key has been pressed - * @private - * @param {Event} e Event object - */ - _isSelectionKeyPressed: function(e) { - var selectionKeyPressed = false; - - if (Array.isArray(this.selectionKey)) { - selectionKeyPressed = !!this.selectionKey.find(function(key) { return e[key] === true; }); - } - else { - selectionKeyPressed = e[this.selectionKey]; - } - - return selectionKeyPressed; - }, - - /** - * @private - * @param {Event} e Event object - * @param {fabric.Object} target - */ - _shouldClearSelection: function (e, target) { - var activeObjects = this.getActiveObjects(), - activeObject = this._activeObject; - - return ( - !target - || - (target && - activeObject && - activeObjects.length > 1 && - activeObjects.indexOf(target) === -1 && - activeObject !== target && - !this._isSelectionKeyPressed(e)) - || - (target && !target.evented) - || - (target && - !target.selectable && - activeObject && - activeObject !== target) - ); - }, - - /** - * centeredScaling from object can't override centeredScaling from canvas. - * this should be fixed, since object setting should take precedence over canvas. - * also this should be something that will be migrated in the control properties. - * as ability to define the origin of the transformation that the control provide. - * @private - * @param {fabric.Object} target - * @param {String} action - * @param {Boolean} altKey - */ - _shouldCenterTransform: function (target, action, altKey) { - if (!target) { - return; - } - - var centerTransform; - - if (action === 'scale' || action === 'scaleX' || action === 'scaleY' || action === 'resizing') { - centerTransform = this.centeredScaling || target.centeredScaling; - } - else if (action === 'rotate') { - centerTransform = this.centeredRotation || target.centeredRotation; - } - - return centerTransform ? !altKey : altKey; - }, - - /** - * should disappear before release 4.0 - * @private - */ - _getOriginFromCorner: function(target, corner) { - var origin = { - x: target.originX, - y: target.originY - }; - - if (corner === 'ml' || corner === 'tl' || corner === 'bl') { - origin.x = 'right'; - } - else if (corner === 'mr' || corner === 'tr' || corner === 'br') { - origin.x = 'left'; - } - - if (corner === 'tl' || corner === 'mt' || corner === 'tr') { - origin.y = 'bottom'; - } - else if (corner === 'bl' || corner === 'mb' || corner === 'br') { - origin.y = 'top'; - } - return origin; - }, - - /** - * @private - * @param {Boolean} alreadySelected true if target is already selected - * @param {String} corner a string representing the corner ml, mr, tl ... - * @param {Event} e Event object - * @param {fabric.Object} [target] inserted back to help overriding. Unused - */ - _getActionFromCorner: function(alreadySelected, corner, e, target) { - if (!corner || !alreadySelected) { - return 'drag'; - } - var control = target.controls[corner]; - return control.getActionName(e, control, target); - }, - - /** - * @private - * @param {Event} e Event object - * @param {fabric.Object} target - */ - _setupCurrentTransform: function (e, target, alreadySelected) { - if (!target) { - return; - } - - var pointer = this.getPointer(e), corner = target.__corner, - control = target.controls[corner], - actionHandler = (alreadySelected && corner) ? - control.getActionHandler(e, target, control) : fabric.controlsUtils.dragHandler, - action = this._getActionFromCorner(alreadySelected, corner, e, target), - origin = this._getOriginFromCorner(target, corner), - altKey = e[this.centeredKey], - transform = { - target: target, - action: action, - actionHandler: actionHandler, - corner: corner, - scaleX: target.scaleX, - scaleY: target.scaleY, - skewX: target.skewX, - skewY: target.skewY, - // used by transation - offsetX: pointer.x - target.left, - offsetY: pointer.y - target.top, - originX: origin.x, - originY: origin.y, - ex: pointer.x, - ey: pointer.y, - lastX: pointer.x, - lastY: pointer.y, - // unsure they are useful anymore. - // left: target.left, - // top: target.top, - theta: degreesToRadians(target.angle), - // end of unsure - width: target.width * target.scaleX, - shiftKey: e.shiftKey, - altKey: altKey, - original: fabric.util.saveObjectTransform(target), - }; - - if (this._shouldCenterTransform(target, action, altKey)) { - transform.originX = 'center'; - transform.originY = 'center'; - } - transform.original.originX = origin.x; - transform.original.originY = origin.y; - this._currentTransform = transform; - this._beforeTransform(e); - }, - - /** - * Set the cursor type of the canvas element - * @param {String} value Cursor type of the canvas element. - * @see http://www.w3.org/TR/css3-ui/#cursor - */ - setCursor: function (value) { - this.upperCanvasEl.style.cursor = value; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx to draw the selection on - */ - _drawSelection: function (ctx) { - var selector = this._groupSelector, - viewportStart = new fabric.Point(selector.ex, selector.ey), - start = fabric.util.transformPoint(viewportStart, this.viewportTransform), - viewportExtent = new fabric.Point(selector.ex + selector.left, selector.ey + selector.top), - extent = fabric.util.transformPoint(viewportExtent, this.viewportTransform), - minX = Math.min(start.x, extent.x), - minY = Math.min(start.y, extent.y), - maxX = Math.max(start.x, extent.x), - maxY = Math.max(start.y, extent.y), - strokeOffset = this.selectionLineWidth / 2; - - if (this.selectionColor) { - ctx.fillStyle = this.selectionColor; - ctx.fillRect(minX, minY, maxX - minX, maxY - minY); - } - - if (!this.selectionLineWidth || !this.selectionBorderColor) { - return; - } - ctx.lineWidth = this.selectionLineWidth; - ctx.strokeStyle = this.selectionBorderColor; - - minX += strokeOffset; - minY += strokeOffset; - maxX -= strokeOffset; - maxY -= strokeOffset; - // selection border - fabric.Object.prototype._setLineDash.call(this, ctx, this.selectionDashArray); - ctx.strokeRect(minX, minY, maxX - minX, maxY - minY); - }, - - /** - * Method that determines what object we are clicking on - * the skipGroup parameter is for internal use, is needed for shift+click action - * 11/09/2018 TODO: would be cool if findTarget could discern between being a full target - * or the outside part of the corner. - * @param {Event} e mouse event - * @param {Boolean} skipGroup when true, activeGroup is skipped and only objects are traversed through - * @return {fabric.Object} the target found - */ - findTarget: function (e, skipGroup) { - if (this.skipTargetFind) { - return; - } - - var ignoreZoom = true, - pointer = this.getPointer(e, ignoreZoom), - activeObject = this._activeObject, - aObjects = this.getActiveObjects(), - activeTarget, activeTargetSubs, - isTouch = isTouchEvent(e), - shouldLookForActive = (aObjects.length > 1 && !skipGroup) || aObjects.length === 1; - - // first check current group (if one exists) - // active group does not check sub targets like normal groups. - // if active group just exits. - this.targets = []; - - // if we hit the corner of an activeObject, let's return that. - if (shouldLookForActive && activeObject._findTargetCorner(pointer, isTouch)) { - return activeObject; - } - if (aObjects.length > 1 && !skipGroup && activeObject === this._searchPossibleTargets([activeObject], pointer)) { - return activeObject; - } - if (aObjects.length === 1 && - activeObject === this._searchPossibleTargets([activeObject], pointer)) { - if (!this.preserveObjectStacking) { - return activeObject; - } - else { - activeTarget = activeObject; - activeTargetSubs = this.targets; - this.targets = []; - } - } - var target = this._searchPossibleTargets(this._objects, pointer); - if (e[this.altSelectionKey] && target && activeTarget && target !== activeTarget) { - target = activeTarget; - this.targets = activeTargetSubs; - } - return target; - }, - - /** - * Checks point is inside the object. - * @param {Object} [pointer] x,y object of point coordinates we want to check. - * @param {fabric.Object} obj Object to test against - * @param {Object} [globalPointer] x,y object of point coordinates relative to canvas used to search per pixel target. - * @return {Boolean} true if point is contained within an area of given object - * @private - */ - _checkTarget: function(pointer, obj, globalPointer) { - if (obj && - obj.visible && - obj.evented && - // http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html - // http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html - obj.containsPoint(pointer) - ) { - if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) { - var isTransparent = this.isTargetTransparent(obj, globalPointer.x, globalPointer.y); - if (!isTransparent) { - return true; - } - } - else { - return true; - } - } - }, - - /** - * Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted - * @param {Array} [objects] objects array to look into - * @param {Object} [pointer] x,y object of point coordinates we want to check. - * @return {fabric.Object} object that contains pointer - * @private - */ - _searchPossibleTargets: function(objects, pointer) { - // Cache all targets where their bounding box contains point. - var target, i = objects.length, subTarget; - // Do not check for currently grouped objects, since we check the parent group itself. - // until we call this function specifically to search inside the activeGroup - while (i--) { - var objToCheck = objects[i]; - var pointerToUse = objToCheck.group ? - this._normalizePointer(objToCheck.group, pointer) : pointer; - if (this._checkTarget(pointerToUse, objToCheck, pointer)) { - target = objects[i]; - if (target.subTargetCheck && target instanceof fabric.Group) { - subTarget = this._searchPossibleTargets(target._objects, pointer); - subTarget && this.targets.push(subTarget); - } - break; - } - } - return target; - }, - - /** - * Returns pointer coordinates without the effect of the viewport - * @param {Object} pointer with "x" and "y" number values - * @return {Object} object with "x" and "y" number values - */ - restorePointerVpt: function(pointer) { - return fabric.util.transformPoint( - pointer, - fabric.util.invertTransform(this.viewportTransform) - ); - }, - - /** - * Returns pointer coordinates relative to canvas. - * Can return coordinates with or without viewportTransform. - * ignoreZoom false gives back coordinates that represent - * the point clicked on canvas element. - * ignoreZoom true gives back coordinates after being processed - * by the viewportTransform ( sort of coordinates of what is displayed - * on the canvas where you are clicking. - * ignoreZoom true = HTMLElement coordinates relative to top,left - * ignoreZoom false, default = fabric space coordinates, the same used for shape position - * To interact with your shapes top and left you want to use ignoreZoom true - * most of the time, while ignoreZoom false will give you coordinates - * compatible with the object.oCoords system. - * of the time. - * @param {Event} e - * @param {Boolean} ignoreZoom - * @return {Object} object with "x" and "y" number values - */ - getPointer: function (e, ignoreZoom) { - // return cached values if we are in the event processing chain - if (this._absolutePointer && !ignoreZoom) { - return this._absolutePointer; - } - if (this._pointer && ignoreZoom) { - return this._pointer; - } - - var pointer = getPointer(e), - upperCanvasEl = this.upperCanvasEl, - bounds = upperCanvasEl.getBoundingClientRect(), - boundsWidth = bounds.width || 0, - boundsHeight = bounds.height || 0, - cssScale; - - if (!boundsWidth || !boundsHeight ) { - if ('top' in bounds && 'bottom' in bounds) { - boundsHeight = Math.abs( bounds.top - bounds.bottom ); - } - if ('right' in bounds && 'left' in bounds) { - boundsWidth = Math.abs( bounds.right - bounds.left ); - } - } - - this.calcOffset(); - pointer.x = pointer.x - this._offset.left; - pointer.y = pointer.y - this._offset.top; - if (!ignoreZoom) { - pointer = this.restorePointerVpt(pointer); - } - - var retinaScaling = this.getRetinaScaling(); - if (retinaScaling !== 1) { - pointer.x /= retinaScaling; - pointer.y /= retinaScaling; - } - - if (boundsWidth === 0 || boundsHeight === 0) { - // If bounds are not available (i.e. not visible), do not apply scale. - cssScale = { width: 1, height: 1 }; - } - else { - cssScale = { - width: upperCanvasEl.width / boundsWidth, - height: upperCanvasEl.height / boundsHeight - }; - } - - return { - x: pointer.x * cssScale.width, - y: pointer.y * cssScale.height - }; - }, - - /** - * @private - * @throws {CANVAS_INIT_ERROR} If canvas can not be initialized - */ - _createUpperCanvas: function () { - var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/, ''), - lowerCanvasEl = this.lowerCanvasEl, upperCanvasEl = this.upperCanvasEl; - - // there is no need to create a new upperCanvas element if we have already one. - if (upperCanvasEl) { - upperCanvasEl.className = ''; - } - else { - upperCanvasEl = this._createCanvasElement(); - this.upperCanvasEl = upperCanvasEl; - } - fabric.util.addClass(upperCanvasEl, 'upper-canvas ' + lowerCanvasClass); - - this.wrapperEl.appendChild(upperCanvasEl); - - this._copyCanvasStyle(lowerCanvasEl, upperCanvasEl); - this._applyCanvasStyle(upperCanvasEl); - this.contextTop = upperCanvasEl.getContext('2d'); - }, - - /** - * Returns context of top canvas where interactions are drawn - * @returns {CanvasRenderingContext2D} - */ - getTopContext: function () { - return this.contextTop; - }, - - /** - * @private - */ - _createCacheCanvas: function () { - this.cacheCanvasEl = this._createCanvasElement(); - this.cacheCanvasEl.setAttribute('width', this.width); - this.cacheCanvasEl.setAttribute('height', this.height); - this.contextCache = this.cacheCanvasEl.getContext('2d'); - }, - - /** - * @private - */ - _initWrapperElement: function () { - this.wrapperEl = fabric.util.wrapElement(this.lowerCanvasEl, 'div', { - 'class': this.containerClass - }); - fabric.util.setStyle(this.wrapperEl, { - width: this.width + 'px', - height: this.height + 'px', - position: 'relative' - }); - fabric.util.makeElementUnselectable(this.wrapperEl); - }, - - /** - * @private - * @param {HTMLElement} element canvas element to apply styles on - */ - _applyCanvasStyle: function (element) { - var width = this.width || element.width, - height = this.height || element.height; - - fabric.util.setStyle(element, { - position: 'absolute', - width: width + 'px', - height: height + 'px', - left: 0, - top: 0, - 'touch-action': this.allowTouchScrolling ? 'manipulation' : 'none', - '-ms-touch-action': this.allowTouchScrolling ? 'manipulation' : 'none' - }); - element.width = width; - element.height = height; - fabric.util.makeElementUnselectable(element); - }, - - /** - * Copy the entire inline style from one element (fromEl) to another (toEl) - * @private - * @param {Element} fromEl Element style is copied from - * @param {Element} toEl Element copied style is applied to - */ - _copyCanvasStyle: function (fromEl, toEl) { - toEl.style.cssText = fromEl.style.cssText; - }, - - /** - * Returns context of canvas where object selection is drawn - * @return {CanvasRenderingContext2D} - */ - getSelectionContext: function() { - return this.contextTop; - }, - - /** - * Returns <canvas> element on which object selection is drawn - * @return {HTMLCanvasElement} - */ - getSelectionElement: function () { - return this.upperCanvasEl; - }, - - /** - * Returns currently active object - * @return {fabric.Object} active object - */ - getActiveObject: function () { - return this._activeObject; - }, - - /** - * Returns an array with the current selected objects - * @return {fabric.Object} active object - */ - getActiveObjects: function () { - var active = this._activeObject; - if (active) { - if (active.type === 'activeSelection' && active._objects) { - return active._objects.slice(0); - } - else { - return [active]; - } - } - return []; - }, - - /** - * @private - * @param {fabric.Object} obj Object that was removed - */ - _onObjectRemoved: function(obj) { - // removing active object should fire "selection:cleared" events - if (obj === this._activeObject) { - this.fire('before:selection:cleared', { target: obj }); - this._discardActiveObject(); - this.fire('selection:cleared', { target: obj }); - obj.fire('deselected'); - } - if (obj === this._hoveredTarget){ - this._hoveredTarget = null; - this._hoveredTargets = []; - } - this.callSuper('_onObjectRemoved', obj); - }, - - /** - * @private - * Compares the old activeObject with the current one and fires correct events - * @param {fabric.Object} obj old activeObject - */ - _fireSelectionEvents: function(oldObjects, e) { - var somethingChanged = false, objects = this.getActiveObjects(), - added = [], removed = []; - oldObjects.forEach(function(oldObject) { - if (objects.indexOf(oldObject) === -1) { - somethingChanged = true; - oldObject.fire('deselected', { - e: e, - target: oldObject - }); - removed.push(oldObject); - } - }); - objects.forEach(function(object) { - if (oldObjects.indexOf(object) === -1) { - somethingChanged = true; - object.fire('selected', { - e: e, - target: object - }); - added.push(object); - } - }); - if (oldObjects.length > 0 && objects.length > 0) { - somethingChanged && this.fire('selection:updated', { - e: e, - selected: added, - deselected: removed, - }); - } - else if (objects.length > 0) { - this.fire('selection:created', { - e: e, - selected: added, - }); - } - else if (oldObjects.length > 0) { - this.fire('selection:cleared', { - e: e, - deselected: removed, - }); - } - }, - - /** - * Sets given object as the only active object on canvas - * @param {fabric.Object} object Object to set as an active one - * @param {Event} [e] Event (passed along when firing "object:selected") - * @return {fabric.Canvas} thisArg - * @chainable - */ - setActiveObject: function (object, e) { - var currentActives = this.getActiveObjects(); - this._setActiveObject(object, e); - this._fireSelectionEvents(currentActives, e); - return this; - }, - - /** - * This is a private method for now. - * This is supposed to be equivalent to setActiveObject but without firing - * any event. There is commitment to have this stay this way. - * This is the functional part of setActiveObject. - * @private - * @param {Object} object to set as active - * @param {Event} [e] Event (passed along when firing "object:selected") - * @return {Boolean} true if the selection happened - */ - _setActiveObject: function(object, e) { - if (this._activeObject === object) { - return false; - } - if (!this._discardActiveObject(e, object)) { - return false; - } - if (object.onSelect({ e: e })) { - return false; - } - this._activeObject = object; - return true; - }, - - /** - * This is a private method for now. - * This is supposed to be equivalent to discardActiveObject but without firing - * any events. There is commitment to have this stay this way. - * This is the functional part of discardActiveObject. - * @param {Event} [e] Event (passed along when firing "object:deselected") - * @param {Object} object to set as active - * @return {Boolean} true if the selection happened - * @private - */ - _discardActiveObject: function(e, object) { - var obj = this._activeObject; - if (obj) { - // onDeselect return TRUE to cancel selection; - if (obj.onDeselect({ e: e, object: object })) { - return false; - } - this._activeObject = null; - } - return true; - }, - - /** - * Discards currently active object and fire events. If the function is called by fabric - * as a consequence of a mouse event, the event is passed as a parameter and - * sent to the fire function for the custom events. When used as a method the - * e param does not have any application. - * @param {event} e - * @return {fabric.Canvas} thisArg - * @chainable - */ - discardActiveObject: function (e) { - var currentActives = this.getActiveObjects(), activeObject = this.getActiveObject(); - if (currentActives.length) { - this.fire('before:selection:cleared', { target: activeObject, e: e }); - } - this._discardActiveObject(e); - this._fireSelectionEvents(currentActives, e); - return this; - }, - - /** - * Clears a canvas element and removes all event listeners - * @return {fabric.Canvas} thisArg - * @chainable - */ - dispose: function () { - var wrapper = this.wrapperEl; - this.removeListeners(); - wrapper.removeChild(this.upperCanvasEl); - wrapper.removeChild(this.lowerCanvasEl); - this.contextCache = null; - this.contextTop = null; - ['upperCanvasEl', 'cacheCanvasEl'].forEach((function(element) { - fabric.util.cleanUpJsdomNode(this[element]); - this[element] = undefined; - }).bind(this)); - if (wrapper.parentNode) { - wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl); - } - delete this.wrapperEl; - fabric.StaticCanvas.prototype.dispose.call(this); - return this; - }, - - /** - * Clears all contexts (background, main, top) of an instance - * @return {fabric.Canvas} thisArg - * @chainable - */ - clear: function () { - // this.discardActiveGroup(); - this.discardActiveObject(); - this.clearContext(this.contextTop); - return this.callSuper('clear'); - }, - - /** - * Draws objects' controls (borders/controls) - * @param {CanvasRenderingContext2D} ctx Context to render controls on - */ - drawControls: function(ctx) { - var activeObject = this._activeObject; - - if (activeObject) { - activeObject._renderControls(ctx); - } - }, - - /** - * @private - */ - _toObject: function(instance, methodName, propertiesToInclude) { - //If the object is part of the current selection group, it should - //be transformed appropriately - //i.e. it should be serialised as it would appear if the selection group - //were to be destroyed. - var originalProperties = this._realizeGroupTransformOnObject(instance), - object = this.callSuper('_toObject', instance, methodName, propertiesToInclude); - //Undo the damage we did by changing all of its properties - this._unwindGroupTransformOnObject(instance, originalProperties); - return object; - }, - - /** - * Realises an object's group transformation on it - * @private - * @param {fabric.Object} [instance] the object to transform (gets mutated) - * @returns the original values of instance which were changed - */ - _realizeGroupTransformOnObject: function(instance) { - if (instance.group && instance.group.type === 'activeSelection' && this._activeObject === instance.group) { - var layoutProps = ['angle', 'flipX', 'flipY', 'left', 'scaleX', 'scaleY', 'skewX', 'skewY', 'top']; - //Copy all the positionally relevant properties across now - var originalValues = {}; - layoutProps.forEach(function(prop) { - originalValues[prop] = instance[prop]; - }); - fabric.util.addTransformToObject(instance, this._activeObject.calcOwnMatrix()); - return originalValues; - } - else { - return null; - } - }, - - /** - * Restores the changed properties of instance - * @private - * @param {fabric.Object} [instance] the object to un-transform (gets mutated) - * @param {Object} [originalValues] the original values of instance, as returned by _realizeGroupTransformOnObject - */ - _unwindGroupTransformOnObject: function(instance, originalValues) { - if (originalValues) { - instance.set(originalValues); - } - }, - - /** - * @private - */ - _setSVGObject: function(markup, instance, reviver) { - //If the object is in a selection group, simulate what would happen to that - //object when the group is deselected - var originalProperties = this._realizeGroupTransformOnObject(instance); - this.callSuper('_setSVGObject', markup, instance, reviver); - this._unwindGroupTransformOnObject(instance, originalProperties); - }, - - setViewportTransform: function (vpt) { - if (this.renderOnAddRemove && this._activeObject && this._activeObject.isEditing) { - this._activeObject.clearContextTop(); - } - fabric.StaticCanvas.prototype.setViewportTransform.call(this, vpt); - } - }); - - // copying static properties manually to work around Opera's bug, - // where "prototype" property is enumerable and overrides existing prototype - for (var prop in fabric.StaticCanvas) { - if (prop !== 'prototype') { - fabric.Canvas[prop] = fabric.StaticCanvas[prop]; - } - } -})(); - - -(function() { - - var addListener = fabric.util.addListener, - removeListener = fabric.util.removeListener, - RIGHT_CLICK = 3, MIDDLE_CLICK = 2, LEFT_CLICK = 1, - addEventOptions = { passive: false }; - - function checkClick(e, value) { - return e.button && (e.button === value - 1); - } - - fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ { - - /** - * Contains the id of the touch event that owns the fabric transform - * @type Number - * @private - */ - mainTouchId: null, - - /** - * Adds mouse listeners to canvas - * @private - */ - _initEventListeners: function () { - // in case we initialized the class twice. This should not happen normally - // but in some kind of applications where the canvas element may be changed - // this is a workaround to having double listeners. - this.removeListeners(); - this._bindEvents(); - this.addOrRemove(addListener, 'add'); - }, - - /** - * return an event prefix pointer or mouse. - * @private - */ - _getEventPrefix: function () { - return this.enablePointerEvents ? 'pointer' : 'mouse'; - }, - - addOrRemove: function(functor, eventjsFunctor) { - var canvasElement = this.upperCanvasEl, - eventTypePrefix = this._getEventPrefix(); - functor(fabric.window, 'resize', this._onResize); - functor(canvasElement, eventTypePrefix + 'down', this._onMouseDown); - functor(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - functor(canvasElement, eventTypePrefix + 'out', this._onMouseOut); - functor(canvasElement, eventTypePrefix + 'enter', this._onMouseEnter); - functor(canvasElement, 'wheel', this._onMouseWheel); - functor(canvasElement, 'contextmenu', this._onContextMenu); - functor(canvasElement, 'dblclick', this._onDoubleClick); - functor(canvasElement, 'dragover', this._onDragOver); - functor(canvasElement, 'dragenter', this._onDragEnter); - functor(canvasElement, 'dragleave', this._onDragLeave); - functor(canvasElement, 'drop', this._onDrop); - if (!this.enablePointerEvents) { - functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions); - } - if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) { - eventjs[eventjsFunctor](canvasElement, 'gesture', this._onGesture); - eventjs[eventjsFunctor](canvasElement, 'drag', this._onDrag); - eventjs[eventjsFunctor](canvasElement, 'orientation', this._onOrientationChange); - eventjs[eventjsFunctor](canvasElement, 'shake', this._onShake); - eventjs[eventjsFunctor](canvasElement, 'longpress', this._onLongPress); - } - }, - - /** - * Removes all event listeners - */ - removeListeners: function() { - this.addOrRemove(removeListener, 'remove'); - // if you dispose on a mouseDown, before mouse up, you need to clean document to... - var eventTypePrefix = this._getEventPrefix(); - removeListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp); - removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions); - removeListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions); - }, - - /** - * @private - */ - _bindEvents: function() { - if (this.eventsBound) { - // for any reason we pass here twice we do not want to bind events twice. - return; - } - this._onMouseDown = this._onMouseDown.bind(this); - this._onTouchStart = this._onTouchStart.bind(this); - this._onMouseMove = this._onMouseMove.bind(this); - this._onMouseUp = this._onMouseUp.bind(this); - this._onTouchEnd = this._onTouchEnd.bind(this); - this._onResize = this._onResize.bind(this); - this._onGesture = this._onGesture.bind(this); - this._onDrag = this._onDrag.bind(this); - this._onShake = this._onShake.bind(this); - this._onLongPress = this._onLongPress.bind(this); - this._onOrientationChange = this._onOrientationChange.bind(this); - this._onMouseWheel = this._onMouseWheel.bind(this); - this._onMouseOut = this._onMouseOut.bind(this); - this._onMouseEnter = this._onMouseEnter.bind(this); - this._onContextMenu = this._onContextMenu.bind(this); - this._onDoubleClick = this._onDoubleClick.bind(this); - this._onDragOver = this._onDragOver.bind(this); - this._onDragEnter = this._simpleEventHandler.bind(this, 'dragenter'); - this._onDragLeave = this._simpleEventHandler.bind(this, 'dragleave'); - this._onDrop = this._onDrop.bind(this); - this.eventsBound = true; - }, - - /** - * @private - * @param {Event} [e] Event object fired on Event.js gesture - * @param {Event} [self] Inner Event object - */ - _onGesture: function(e, self) { - this.__onTransformGesture && this.__onTransformGesture(e, self); - }, - - /** - * @private - * @param {Event} [e] Event object fired on Event.js drag - * @param {Event} [self] Inner Event object - */ - _onDrag: function(e, self) { - this.__onDrag && this.__onDrag(e, self); - }, - - /** - * @private - * @param {Event} [e] Event object fired on wheel event - */ - _onMouseWheel: function(e) { - this.__onMouseWheel(e); - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onMouseOut: function(e) { - var target = this._hoveredTarget; - this.fire('mouse:out', { target: target, e: e }); - this._hoveredTarget = null; - target && target.fire('mouseout', { e: e }); - - var _this = this; - this._hoveredTargets.forEach(function(_target){ - _this.fire('mouse:out', { target: target, e: e }); - _target && target.fire('mouseout', { e: e }); - }); - this._hoveredTargets = []; - - if (this._iTextInstances) { - this._iTextInstances.forEach(function(obj) { - if (obj.isEditing) { - obj.hiddenTextarea.focus(); - } - }); - } - }, - - /** - * @private - * @param {Event} e Event object fired on mouseenter - */ - _onMouseEnter: function(e) { - // This find target and consequent 'mouse:over' is used to - // clear old instances on hovered target. - // calling findTarget has the side effect of killing target.__corner. - // as a short term fix we are not firing this if we are currently transforming. - // as a long term fix we need to separate the action of finding a target with the - // side effects we added to it. - if (!this._currentTransform && !this.findTarget(e)) { - this.fire('mouse:over', { target: null, e: e }); - this._hoveredTarget = null; - this._hoveredTargets = []; - } - }, - - /** - * @private - * @param {Event} [e] Event object fired on Event.js orientation change - * @param {Event} [self] Inner Event object - */ - _onOrientationChange: function(e, self) { - this.__onOrientationChange && this.__onOrientationChange(e, self); - }, - - /** - * @private - * @param {Event} [e] Event object fired on Event.js shake - * @param {Event} [self] Inner Event object - */ - _onShake: function(e, self) { - this.__onShake && this.__onShake(e, self); - }, - - /** - * @private - * @param {Event} [e] Event object fired on Event.js shake - * @param {Event} [self] Inner Event object - */ - _onLongPress: function(e, self) { - this.__onLongPress && this.__onLongPress(e, self); - }, - - /** - * prevent default to allow drop event to be fired - * @private - * @param {Event} [e] Event object fired on Event.js shake - */ - _onDragOver: function(e) { - e.preventDefault(); - var target = this._simpleEventHandler('dragover', e); - this._fireEnterLeaveEvents(target, e); - }, - - /** - * `drop:before` is a an event that allow you to schedule logic - * before the `drop` event. Prefer `drop` event always, but if you need - * to run some drop-disabling logic on an event, since there is no way - * to handle event handlers ordering, use `drop:before` - * @param {Event} e - */ - _onDrop: function (e) { - this._simpleEventHandler('drop:before', e); - return this._simpleEventHandler('drop', e); - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onContextMenu: function (e) { - if (this.stopContextMenu) { - e.stopPropagation(); - e.preventDefault(); - } - return false; - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onDoubleClick: function (e) { - this._cacheTransformEventData(e); - this._handleEvent(e, 'dblclick'); - this._resetTransformEventData(e); - }, - - /** - * Return a the id of an event. - * returns either the pointerId or the identifier or 0 for the mouse event - * @private - * @param {Event} evt Event object - */ - getPointerId: function(evt) { - var changedTouches = evt.changedTouches; - - if (changedTouches) { - return changedTouches[0] && changedTouches[0].identifier; - } - - if (this.enablePointerEvents) { - return evt.pointerId; - } - - return -1; - }, - - /** - * Determines if an event has the id of the event that is considered main - * @private - * @param {evt} event Event object - */ - _isMainEvent: function(evt) { - if (evt.isPrimary === true) { - return true; - } - if (evt.isPrimary === false) { - return false; - } - if (evt.type === 'touchend' && evt.touches.length === 0) { - return true; - } - if (evt.changedTouches) { - return evt.changedTouches[0].identifier === this.mainTouchId; - } - return true; - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onTouchStart: function(e) { - e.preventDefault(); - if (this.mainTouchId === null) { - this.mainTouchId = this.getPointerId(e); - } - this.__onMouseDown(e); - this._resetTransformEventData(); - var canvasElement = this.upperCanvasEl, - eventTypePrefix = this._getEventPrefix(); - addListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions); - addListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions); - // Unbind mousedown to prevent double triggers from touch devices - removeListener(canvasElement, eventTypePrefix + 'down', this._onMouseDown); - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onMouseDown: function (e) { - this.__onMouseDown(e); - this._resetTransformEventData(); - var canvasElement = this.upperCanvasEl, - eventTypePrefix = this._getEventPrefix(); - removeListener(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - addListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp); - addListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onTouchEnd: function(e) { - if (e.touches.length > 0) { - // if there are still touches stop here - return; - } - this.__onMouseUp(e); - this._resetTransformEventData(); - this.mainTouchId = null; - var eventTypePrefix = this._getEventPrefix(); - removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions); - removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions); - var _this = this; - if (this._willAddMouseDown) { - clearTimeout(this._willAddMouseDown); - } - this._willAddMouseDown = setTimeout(function() { - // Wait 400ms before rebinding mousedown to prevent double triggers - // from touch devices - addListener(_this.upperCanvasEl, eventTypePrefix + 'down', _this._onMouseDown); - _this._willAddMouseDown = 0; - }, 400); - }, - - /** - * @private - * @param {Event} e Event object fired on mouseup - */ - _onMouseUp: function (e) { - this.__onMouseUp(e); - this._resetTransformEventData(); - var canvasElement = this.upperCanvasEl, - eventTypePrefix = this._getEventPrefix(); - if (this._isMainEvent(e)) { - removeListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp); - removeListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - addListener(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions); - } - }, - - /** - * @private - * @param {Event} e Event object fired on mousemove - */ - _onMouseMove: function (e) { - !this.allowTouchScrolling && e.preventDefault && e.preventDefault(); - this.__onMouseMove(e); - }, - - /** - * @private - */ - _onResize: function () { - this.calcOffset(); - }, - - /** - * Decides whether the canvas should be redrawn in mouseup and mousedown events. - * @private - * @param {Object} target - */ - _shouldRender: function(target) { - var activeObject = this._activeObject; - - if ( - !!activeObject !== !!target || - (activeObject && target && (activeObject !== target)) - ) { - // this covers: switch of target, from target to no target, selection of target - // multiSelection with key and mouse - return true; - } - else if (activeObject && activeObject.isEditing) { - // if we mouse up/down over a editing textbox a cursor change, - // there is no need to re render - return false; - } - return false; - }, - - /** - * Method that defines the actions when mouse is released on canvas. - * The method resets the currentTransform parameters, store the image corner - * position in the image object and render the canvas on top. - * @private - * @param {Event} e Event object fired on mouseup - */ - __onMouseUp: function (e) { - var target, transform = this._currentTransform, - groupSelector = this._groupSelector, shouldRender = false, - isClick = (!groupSelector || (groupSelector.left === 0 && groupSelector.top === 0)); - this._cacheTransformEventData(e); - target = this._target; - this._handleEvent(e, 'up:before'); - // if right/middle click just fire events and return - // target undefined will make the _handleEvent search the target - if (checkClick(e, RIGHT_CLICK)) { - if (this.fireRightClick) { - this._handleEvent(e, 'up', RIGHT_CLICK, isClick); - } - return; - } - - if (checkClick(e, MIDDLE_CLICK)) { - if (this.fireMiddleClick) { - this._handleEvent(e, 'up', MIDDLE_CLICK, isClick); - } - this._resetTransformEventData(); - return; - } - - if (this.isDrawingMode && this._isCurrentlyDrawing) { - this._onMouseUpInDrawingMode(e); - return; - } - - if (!this._isMainEvent(e)) { - return; - } - if (transform) { - this._finalizeCurrentTransform(e); - shouldRender = transform.actionPerformed; - } - if (!isClick) { - var targetWasActive = target === this._activeObject; - this._maybeGroupObjects(e); - if (!shouldRender) { - shouldRender = ( - this._shouldRender(target) || - (!targetWasActive && target === this._activeObject) - ); - } - } - var corner, pointer; - if (target) { - corner = target._findTargetCorner( - this.getPointer(e, true), - fabric.util.isTouchEvent(e) - ); - if (target.selectable && target !== this._activeObject && target.activeOn === 'up') { - this.setActiveObject(target, e); - shouldRender = true; - } - else { - var control = target.controls[corner], - mouseUpHandler = control && control.getMouseUpHandler(e, target, control); - if (mouseUpHandler) { - pointer = this.getPointer(e); - mouseUpHandler(e, transform, pointer.x, pointer.y); - } - } - target.isMoving = false; - } - // if we are ending up a transform on a different control or a new object - // fire the original mouse up from the corner that started the transform - if (transform && (transform.target !== target || transform.corner !== corner)) { - var originalControl = transform.target && transform.target.controls[transform.corner], - originalMouseUpHandler = originalControl && originalControl.getMouseUpHandler(e, target, control); - pointer = pointer || this.getPointer(e); - originalMouseUpHandler && originalMouseUpHandler(e, transform, pointer.x, pointer.y); - } - this._setCursorFromEvent(e, target); - this._handleEvent(e, 'up', LEFT_CLICK, isClick); - this._groupSelector = null; - this._currentTransform = null; - // reset the target information about which corner is selected - target && (target.__corner = 0); - if (shouldRender) { - this.requestRenderAll(); - } - else if (!isClick) { - this.renderTop(); - } - }, - - /** - * @private - * Handle event firing for target and subtargets - * @param {Event} e event from mouse - * @param {String} eventType event to fire (up, down or move) - * @return {Fabric.Object} target return the the target found, for internal reasons. - */ - _simpleEventHandler: function(eventType, e) { - var target = this.findTarget(e), - targets = this.targets, - options = { - e: e, - target: target, - subTargets: targets, - }; - this.fire(eventType, options); - target && target.fire(eventType, options); - if (!targets) { - return target; - } - for (var i = 0; i < targets.length; i++) { - targets[i].fire(eventType, options); - } - return target; - }, - - /** - * @private - * Handle event firing for target and subtargets - * @param {Event} e event from mouse - * @param {String} eventType event to fire (up, down or move) - * @param {fabric.Object} targetObj receiving event - * @param {Number} [button] button used in the event 1 = left, 2 = middle, 3 = right - * @param {Boolean} isClick for left button only, indicates that the mouse up happened without move. - */ - _handleEvent: function(e, eventType, button, isClick) { - var target = this._target, - targets = this.targets || [], - options = { - e: e, - target: target, - subTargets: targets, - button: button || LEFT_CLICK, - isClick: isClick || false, - pointer: this._pointer, - absolutePointer: this._absolutePointer, - transform: this._currentTransform - }; - if (eventType === 'up') { - options.currentTarget = this.findTarget(e); - options.currentSubTargets = this.targets; - } - this.fire('mouse:' + eventType, options); - target && target.fire('mouse' + eventType, options); - for (var i = 0; i < targets.length; i++) { - targets[i].fire('mouse' + eventType, options); - } - }, - - /** - * @private - * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event - */ - _finalizeCurrentTransform: function(e) { - - var transform = this._currentTransform, - target = transform.target, - options = { - e: e, - target: target, - transform: transform, - action: transform.action, - }; - - if (target._scaling) { - target._scaling = false; - } - - target.setCoords(); - - if (transform.actionPerformed || (this.stateful && target.hasStateChanged())) { - this._fire('modified', options); - } - }, - - /** - * @private - * @param {Event} e Event object fired on mousedown - */ - _onMouseDownInDrawingMode: function(e) { - this._isCurrentlyDrawing = true; - if (this.getActiveObject()) { - this.discardActiveObject(e).requestRenderAll(); - } - var pointer = this.getPointer(e); - this.freeDrawingBrush.onMouseDown(pointer, { e: e, pointer: pointer }); - this._handleEvent(e, 'down'); - }, - - /** - * @private - * @param {Event} e Event object fired on mousemove - */ - _onMouseMoveInDrawingMode: function(e) { - if (this._isCurrentlyDrawing) { - var pointer = this.getPointer(e); - this.freeDrawingBrush.onMouseMove(pointer, { e: e, pointer: pointer }); - } - this.setCursor(this.freeDrawingCursor); - this._handleEvent(e, 'move'); - }, - - /** - * @private - * @param {Event} e Event object fired on mouseup - */ - _onMouseUpInDrawingMode: function(e) { - var pointer = this.getPointer(e); - this._isCurrentlyDrawing = this.freeDrawingBrush.onMouseUp({ e: e, pointer: pointer }); - this._handleEvent(e, 'up'); - }, - - /** - * Method that defines the actions when mouse is clicked on canvas. - * The method inits the currentTransform parameters and renders all the - * canvas so the current image can be placed on the top canvas and the rest - * in on the container one. - * @private - * @param {Event} e Event object fired on mousedown - */ - __onMouseDown: function (e) { - this._cacheTransformEventData(e); - this._handleEvent(e, 'down:before'); - var target = this._target; - // if right click just fire events - if (checkClick(e, RIGHT_CLICK)) { - if (this.fireRightClick) { - this._handleEvent(e, 'down', RIGHT_CLICK); - } - return; - } - - if (checkClick(e, MIDDLE_CLICK)) { - if (this.fireMiddleClick) { - this._handleEvent(e, 'down', MIDDLE_CLICK); - } - return; - } - - if (this.isDrawingMode) { - this._onMouseDownInDrawingMode(e); - return; - } - - if (!this._isMainEvent(e)) { - return; - } - - // ignore if some object is being transformed at this moment - if (this._currentTransform) { - return; - } - - var pointer = this._pointer; - // save pointer for check in __onMouseUp event - this._previousPointer = pointer; - var shouldRender = this._shouldRender(target), - shouldGroup = this._shouldGroup(e, target); - if (this._shouldClearSelection(e, target)) { - this.discardActiveObject(e); - } - else if (shouldGroup) { - this._handleGrouping(e, target); - target = this._activeObject; - } - - if (this.selection && (!target || - (!target.selectable && !target.isEditing && target !== this._activeObject))) { - this._groupSelector = { - ex: this._absolutePointer.x, - ey: this._absolutePointer.y, - top: 0, - left: 0 - }; - } - - if (target) { - var alreadySelected = target === this._activeObject; - if (target.selectable && target.activeOn === 'down') { - this.setActiveObject(target, e); - } - var corner = target._findTargetCorner( - this.getPointer(e, true), - fabric.util.isTouchEvent(e) - ); - target.__corner = corner; - if (target === this._activeObject && (corner || !shouldGroup)) { - this._setupCurrentTransform(e, target, alreadySelected); - var control = target.controls[corner], - pointer = this.getPointer(e), - mouseDownHandler = control && control.getMouseDownHandler(e, target, control); - if (mouseDownHandler) { - mouseDownHandler(e, this._currentTransform, pointer.x, pointer.y); - } - } - } - this._handleEvent(e, 'down'); - // we must renderAll so that we update the visuals - (shouldRender || shouldGroup) && this.requestRenderAll(); - }, - - /** - * reset cache form common information needed during event processing - * @private - */ - _resetTransformEventData: function() { - this._target = null; - this._pointer = null; - this._absolutePointer = null; - }, - - /** - * Cache common information needed during event processing - * @private - * @param {Event} e Event object fired on event - */ - _cacheTransformEventData: function(e) { - // reset in order to avoid stale caching - this._resetTransformEventData(); - this._pointer = this.getPointer(e, true); - this._absolutePointer = this.restorePointerVpt(this._pointer); - this._target = this._currentTransform ? this._currentTransform.target : this.findTarget(e) || null; - }, - - /** - * @private - */ - _beforeTransform: function(e) { - var t = this._currentTransform; - this.stateful && t.target.saveState(); - this.fire('before:transform', { - e: e, - transform: t, - }); - }, - - /** - * Method that defines the actions when mouse is hovering the canvas. - * The currentTransform parameter will define whether the user is rotating/scaling/translating - * an image or neither of them (only hovering). A group selection is also possible and would cancel - * all any other type of action. - * In case of an image transformation only the top canvas will be rendered. - * @private - * @param {Event} e Event object fired on mousemove - */ - __onMouseMove: function (e) { - this._handleEvent(e, 'move:before'); - this._cacheTransformEventData(e); - var target, pointer; - - if (this.isDrawingMode) { - this._onMouseMoveInDrawingMode(e); - return; - } - - if (!this._isMainEvent(e)) { - return; - } - - var groupSelector = this._groupSelector; - - // We initially clicked in an empty area, so we draw a box for multiple selection - if (groupSelector) { - pointer = this._absolutePointer; - - groupSelector.left = pointer.x - groupSelector.ex; - groupSelector.top = pointer.y - groupSelector.ey; - - this.renderTop(); - } - else if (!this._currentTransform) { - target = this.findTarget(e) || null; - this._setCursorFromEvent(e, target); - this._fireOverOutEvents(target, e); - } - else { - this._transformObject(e); - } - this._handleEvent(e, 'move'); - this._resetTransformEventData(); - }, - - /** - * Manage the mouseout, mouseover events for the fabric object on the canvas - * @param {Fabric.Object} target the target where the target from the mousemove event - * @param {Event} e Event object fired on mousemove - * @private - */ - _fireOverOutEvents: function(target, e) { - var _hoveredTarget = this._hoveredTarget, - _hoveredTargets = this._hoveredTargets, targets = this.targets, - length = Math.max(_hoveredTargets.length, targets.length); - - this.fireSyntheticInOutEvents(target, e, { - oldTarget: _hoveredTarget, - evtOut: 'mouseout', - canvasEvtOut: 'mouse:out', - evtIn: 'mouseover', - canvasEvtIn: 'mouse:over', - }); - for (var i = 0; i < length; i++){ - this.fireSyntheticInOutEvents(targets[i], e, { - oldTarget: _hoveredTargets[i], - evtOut: 'mouseout', - evtIn: 'mouseover', - }); - } - this._hoveredTarget = target; - this._hoveredTargets = this.targets.concat(); - }, - - /** - * Manage the dragEnter, dragLeave events for the fabric objects on the canvas - * @param {Fabric.Object} target the target where the target from the onDrag event - * @param {Event} e Event object fired on ondrag - * @private - */ - _fireEnterLeaveEvents: function(target, e) { - var _draggedoverTarget = this._draggedoverTarget, - _hoveredTargets = this._hoveredTargets, targets = this.targets, - length = Math.max(_hoveredTargets.length, targets.length); - - this.fireSyntheticInOutEvents(target, e, { - oldTarget: _draggedoverTarget, - evtOut: 'dragleave', - evtIn: 'dragenter', - }); - for (var i = 0; i < length; i++) { - this.fireSyntheticInOutEvents(targets[i], e, { - oldTarget: _hoveredTargets[i], - evtOut: 'dragleave', - evtIn: 'dragenter', - }); - } - this._draggedoverTarget = target; - }, - - /** - * Manage the synthetic in/out events for the fabric objects on the canvas - * @param {Fabric.Object} target the target where the target from the supported events - * @param {Event} e Event object fired - * @param {Object} config configuration for the function to work - * @param {String} config.targetName property on the canvas where the old target is stored - * @param {String} [config.canvasEvtOut] name of the event to fire at canvas level for out - * @param {String} config.evtOut name of the event to fire for out - * @param {String} [config.canvasEvtIn] name of the event to fire at canvas level for in - * @param {String} config.evtIn name of the event to fire for in - * @private - */ - fireSyntheticInOutEvents: function(target, e, config) { - var inOpt, outOpt, oldTarget = config.oldTarget, outFires, inFires, - targetChanged = oldTarget !== target, canvasEvtIn = config.canvasEvtIn, canvasEvtOut = config.canvasEvtOut; - if (targetChanged) { - inOpt = { e: e, target: target, previousTarget: oldTarget }; - outOpt = { e: e, target: oldTarget, nextTarget: target }; - } - inFires = target && targetChanged; - outFires = oldTarget && targetChanged; - if (outFires) { - canvasEvtOut && this.fire(canvasEvtOut, outOpt); - oldTarget.fire(config.evtOut, outOpt); - } - if (inFires) { - canvasEvtIn && this.fire(canvasEvtIn, inOpt); - target.fire(config.evtIn, inOpt); - } - }, - - /** - * Method that defines actions when an Event Mouse Wheel - * @param {Event} e Event object fired on mouseup - */ - __onMouseWheel: function(e) { - this._cacheTransformEventData(e); - this._handleEvent(e, 'wheel'); - this._resetTransformEventData(); - }, - - /** - * @private - * @param {Event} e Event fired on mousemove - */ - _transformObject: function(e) { - var pointer = this.getPointer(e), - transform = this._currentTransform; - - transform.reset = false; - transform.shiftKey = e.shiftKey; - transform.altKey = e[this.centeredKey]; - - this._performTransformAction(e, transform, pointer); - transform.actionPerformed && this.requestRenderAll(); - }, - - /** - * @private - */ - _performTransformAction: function(e, transform, pointer) { - var x = pointer.x, - y = pointer.y, - action = transform.action, - actionPerformed = false, - actionHandler = transform.actionHandler; - // this object could be created from the function in the control handlers - - - if (actionHandler) { - actionPerformed = actionHandler(e, transform, x, y); - } - if (action === 'drag' && actionPerformed) { - transform.target.isMoving = true; - this.setCursor(transform.target.moveCursor || this.moveCursor); - } - transform.actionPerformed = transform.actionPerformed || actionPerformed; - }, - - /** - * @private - */ - _fire: fabric.controlsUtils.fireEvent, - - /** - * Sets the cursor depending on where the canvas is being hovered. - * Note: very buggy in Opera - * @param {Event} e Event object - * @param {Object} target Object that the mouse is hovering, if so. - */ - _setCursorFromEvent: function (e, target) { - if (!target) { - this.setCursor(this.defaultCursor); - return false; - } - var hoverCursor = target.hoverCursor || this.hoverCursor, - activeSelection = this._activeObject && this._activeObject.type === 'activeSelection' ? - this._activeObject : null, - // only show proper corner when group selection is not active - corner = (!activeSelection || !activeSelection.contains(target)) - // here we call findTargetCorner always with undefined for the touch parameter. - // we assume that if you are using a cursor you do not need to interact with - // the bigger touch area. - && target._findTargetCorner(this.getPointer(e, true)); - - if (!corner) { - if (target.subTargetCheck){ - // hoverCursor should come from top-most subTarget, - // so we walk the array backwards - this.targets.concat().reverse().map(function(_target){ - hoverCursor = _target.hoverCursor || hoverCursor; - }); - } - this.setCursor(hoverCursor); - } - else { - this.setCursor(this.getCornerCursor(corner, target, e)); - } - }, - - /** - * @private - */ - getCornerCursor: function(corner, target, e) { - var control = target.controls[corner]; - return control.cursorStyleHandler(e, control, target); - } - }); -})(); - - -(function() { - - var min = Math.min, - max = Math.max; - - fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ { - - /** - * @private - * @param {Event} e Event object - * @param {fabric.Object} target - * @return {Boolean} - */ - _shouldGroup: function(e, target) { - var activeObject = this._activeObject; - return activeObject && this._isSelectionKeyPressed(e) && target && target.selectable && this.selection && - (activeObject !== target || activeObject.type === 'activeSelection') && !target.onSelect({ e: e }); - }, - - /** - * @private - * @param {Event} e Event object - * @param {fabric.Object} target - */ - _handleGrouping: function (e, target) { - var activeObject = this._activeObject; - // avoid multi select when shift click on a corner - if (activeObject.__corner) { - return; - } - if (target === activeObject) { - // if it's a group, find target again, using activeGroup objects - target = this.findTarget(e, true); - // if even object is not found or we are on activeObjectCorner, bail out - if (!target || !target.selectable) { - return; - } - } - if (activeObject && activeObject.type === 'activeSelection') { - this._updateActiveSelection(target, e); - } - else { - this._createActiveSelection(target, e); - } - }, - - /** - * @private - */ - _updateActiveSelection: function(target, e) { - var activeSelection = this._activeObject, - currentActiveObjects = activeSelection._objects.slice(0); - if (activeSelection.contains(target)) { - activeSelection.removeWithUpdate(target); - this._hoveredTarget = target; - this._hoveredTargets = this.targets.concat(); - if (activeSelection.size() === 1) { - // activate last remaining object - this._setActiveObject(activeSelection.item(0), e); - } - } - else { - activeSelection.addWithUpdate(target); - this._hoveredTarget = activeSelection; - this._hoveredTargets = this.targets.concat(); - } - this._fireSelectionEvents(currentActiveObjects, e); - }, - - /** - * @private - */ - _createActiveSelection: function(target, e) { - var currentActives = this.getActiveObjects(), group = this._createGroup(target); - this._hoveredTarget = group; - // ISSUE 4115: should we consider subTargets here? - // this._hoveredTargets = []; - // this._hoveredTargets = this.targets.concat(); - this._setActiveObject(group, e); - this._fireSelectionEvents(currentActives, e); - }, - - /** - * @private - * @param {Object} target - */ - _createGroup: function(target) { - var objects = this._objects, - isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target), - groupObjects = isActiveLower - ? [this._activeObject, target] - : [target, this._activeObject]; - this._activeObject.isEditing && this._activeObject.exitEditing(); - return new fabric.ActiveSelection(groupObjects, { - canvas: this - }); - }, - - /** - * @private - * @param {Event} e mouse event - */ - _groupSelectedObjects: function (e) { - - var group = this._collectObjects(e), - aGroup; - - // do not create group for 1 element only - if (group.length === 1) { - this.setActiveObject(group[0], e); - } - else if (group.length > 1) { - aGroup = new fabric.ActiveSelection(group.reverse(), { - canvas: this - }); - this.setActiveObject(aGroup, e); - } - }, - - /** - * @private - */ - _collectObjects: function(e) { - var group = [], - currentObject, - x1 = this._groupSelector.ex, - y1 = this._groupSelector.ey, - x2 = x1 + this._groupSelector.left, - y2 = y1 + this._groupSelector.top, - selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)), - selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)), - allowIntersect = !this.selectionFullyContained, - isClick = x1 === x2 && y1 === y2; - // we iterate reverse order to collect top first in case of click. - for (var i = this._objects.length; i--; ) { - currentObject = this._objects[i]; - - if (!currentObject || !currentObject.selectable || !currentObject.visible) { - continue; - } - - if ((allowIntersect && currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2, true)) || - currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2, true) || - (allowIntersect && currentObject.containsPoint(selectionX1Y1, null, true)) || - (allowIntersect && currentObject.containsPoint(selectionX2Y2, null, true)) - ) { - group.push(currentObject); - // only add one object if it's a click - if (isClick) { - break; - } - } - } - - if (group.length > 1) { - group = group.filter(function(object) { - return !object.onSelect({ e: e }); - }); - } - - return group; - }, - - /** - * @private - */ - _maybeGroupObjects: function(e) { - if (this.selection && this._groupSelector) { - this._groupSelectedObjects(e); - } - this.setCursor(this.defaultCursor); - // clear selection and current transformation - this._groupSelector = null; - } - }); - -})(); - - -(function () { - fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { - - /** - * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately - * @param {Object} [options] Options object - * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png" - * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg. - * @param {Number} [options.multiplier=1] Multiplier to scale by, to have consistent - * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 - * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 - * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 - * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 - * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 2.0.0 - * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format - * @see {@link http://jsfiddle.net/fabricjs/NfZVb/|jsFiddle demo} - * @example Generate jpeg dataURL with lower quality - * var dataURL = canvas.toDataURL({ - * format: 'jpeg', - * quality: 0.8 - * }); - * @example Generate cropped png dataURL (clipping of canvas) - * var dataURL = canvas.toDataURL({ - * format: 'png', - * left: 100, - * top: 100, - * width: 200, - * height: 200 - * }); - * @example Generate double scaled png dataURL - * var dataURL = canvas.toDataURL({ - * format: 'png', - * multiplier: 2 - * }); - */ - toDataURL: function (options) { - options || (options = { }); - - var format = options.format || 'png', - quality = options.quality || 1, - multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? this.getRetinaScaling() : 1), - canvasEl = this.toCanvasElement(multiplier, options); - return fabric.util.toDataURL(canvasEl, format, quality); - }, - - /** - * Create a new HTMLCanvas element painted with the current canvas content. - * No need to resize the actual one or repaint it. - * Will transfer object ownership to a new canvas, paint it, and set everything back. - * This is an intermediary step used to get to a dataUrl but also it is useful to - * create quick image copies of a canvas without passing for the dataUrl string - * @param {Number} [multiplier] a zoom factor. - * @param {Object} [cropping] Cropping informations - * @param {Number} [cropping.left] Cropping left offset. - * @param {Number} [cropping.top] Cropping top offset. - * @param {Number} [cropping.width] Cropping width. - * @param {Number} [cropping.height] Cropping height. - */ - toCanvasElement: function(multiplier, cropping) { - multiplier = multiplier || 1; - cropping = cropping || { }; - var scaledWidth = (cropping.width || this.width) * multiplier, - scaledHeight = (cropping.height || this.height) * multiplier, - zoom = this.getZoom(), - originalWidth = this.width, - originalHeight = this.height, - newZoom = zoom * multiplier, - vp = this.viewportTransform, - translateX = (vp[4] - (cropping.left || 0)) * multiplier, - translateY = (vp[5] - (cropping.top || 0)) * multiplier, - originalInteractive = this.interactive, - newVp = [newZoom, 0, 0, newZoom, translateX, translateY], - originalRetina = this.enableRetinaScaling, - canvasEl = fabric.util.createCanvasElement(), - originalContextTop = this.contextTop; - canvasEl.width = scaledWidth; - canvasEl.height = scaledHeight; - this.contextTop = null; - this.enableRetinaScaling = false; - this.interactive = false; - this.viewportTransform = newVp; - this.width = scaledWidth; - this.height = scaledHeight; - this.calcViewportBoundaries(); - this.renderCanvas(canvasEl.getContext('2d'), this._objects); - this.viewportTransform = vp; - this.width = originalWidth; - this.height = originalHeight; - this.calcViewportBoundaries(); - this.interactive = originalInteractive; - this.enableRetinaScaling = originalRetina; - this.contextTop = originalContextTop; - return canvasEl; - }, - }); - -})(); - - -fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { - /** - * Populates canvas with data from the specified JSON. - * JSON format must conform to the one of {@link fabric.Canvas#toJSON} - * @param {String|Object} json JSON string or object - * @param {Function} callback Callback, invoked when json is parsed - * and corresponding objects (e.g: {@link fabric.Image}) - * are initialized - * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created. - * @return {fabric.Canvas} instance - * @chainable - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization} - * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo} - * @example loadFromJSON - * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas)); - * @example loadFromJSON with reviver - * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas), function(o, object) { - * // `o` = json object - * // `object` = fabric.Object instance - * // ... do some stuff ... - * }); - */ - loadFromJSON: function (json, callback, reviver) { - if (!json) { - return; - } - - // serialize if it wasn't already - var serialized = (typeof json === 'string') - ? JSON.parse(json) - : fabric.util.object.clone(json); - - var _this = this, - clipPath = serialized.clipPath, - renderOnAddRemove = this.renderOnAddRemove; - - this.renderOnAddRemove = false; - - delete serialized.clipPath; - - this._enlivenObjects(serialized.objects, function (enlivenedObjects) { - _this.clear(); - _this._setBgOverlay(serialized, function () { - if (clipPath) { - _this._enlivenObjects([clipPath], function (enlivenedCanvasClip) { - _this.clipPath = enlivenedCanvasClip[0]; - _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback); - }); - } - else { - _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback); - } - }); - }, reviver); - return this; - }, - - /** - * @private - * @param {Object} serialized Object with background and overlay information - * @param {Array} restored canvas objects - * @param {Function} cached renderOnAddRemove callback - * @param {Function} callback Invoked after all background and overlay images/patterns loaded - */ - __setupCanvas: function(serialized, enlivenedObjects, renderOnAddRemove, callback) { - var _this = this; - enlivenedObjects.forEach(function(obj, index) { - // we splice the array just in case some custom classes restored from JSON - // will add more object to canvas at canvas init. - _this.insertAt(obj, index); - }); - this.renderOnAddRemove = renderOnAddRemove; - // remove parts i cannot set as options - delete serialized.objects; - delete serialized.backgroundImage; - delete serialized.overlayImage; - delete serialized.background; - delete serialized.overlay; - // this._initOptions does too many things to just - // call it. Normally loading an Object from JSON - // create the Object instance. Here the Canvas is - // already an instance and we are just loading things over it - this._setOptions(serialized); - this.renderAll(); - callback && callback(); - }, - - /** - * @private - * @param {Object} serialized Object with background and overlay information - * @param {Function} callback Invoked after all background and overlay images/patterns loaded - */ - _setBgOverlay: function(serialized, callback) { - var loaded = { - backgroundColor: false, - overlayColor: false, - backgroundImage: false, - overlayImage: false - }; - - if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background && !serialized.overlay) { - callback && callback(); - return; - } - - var cbIfLoaded = function () { - if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) { - callback && callback(); - } - }; - - this.__setBgOverlay('backgroundImage', serialized.backgroundImage, loaded, cbIfLoaded); - this.__setBgOverlay('overlayImage', serialized.overlayImage, loaded, cbIfLoaded); - this.__setBgOverlay('backgroundColor', serialized.background, loaded, cbIfLoaded); - this.__setBgOverlay('overlayColor', serialized.overlay, loaded, cbIfLoaded); - }, - - /** - * @private - * @param {String} property Property to set (backgroundImage, overlayImage, backgroundColor, overlayColor) - * @param {(Object|String)} value Value to set - * @param {Object} loaded Set loaded property to true if property is set - * @param {Object} callback Callback function to invoke after property is set - */ - __setBgOverlay: function(property, value, loaded, callback) { - var _this = this; - - if (!value) { - loaded[property] = true; - callback && callback(); - return; - } - - if (property === 'backgroundImage' || property === 'overlayImage') { - fabric.util.enlivenObjects([value], function(enlivedObject){ - _this[property] = enlivedObject[0]; - loaded[property] = true; - callback && callback(); - }); - } - else { - this['set' + fabric.util.string.capitalize(property, true)](value, function() { - loaded[property] = true; - callback && callback(); - }); - } - }, - - /** - * @private - * @param {Array} objects - * @param {Function} callback - * @param {Function} [reviver] - */ - _enlivenObjects: function (objects, callback, reviver) { - if (!objects || objects.length === 0) { - callback && callback([]); - return; - } - - fabric.util.enlivenObjects(objects, function(enlivenedObjects) { - callback && callback(enlivenedObjects); - }, null, reviver); - }, - - /** - * @private - * @param {String} format - * @param {Function} callback - */ - _toDataURL: function (format, callback) { - this.clone(function (clone) { - callback(clone.toDataURL(format)); - }); - }, - - /** - * @private - * @param {String} format - * @param {Number} multiplier - * @param {Function} callback - */ - _toDataURLWithMultiplier: function (format, multiplier, callback) { - this.clone(function (clone) { - callback(clone.toDataURLWithMultiplier(format, multiplier)); - }); - }, - - /** - * Clones canvas instance - * @param {Object} [callback] Receives cloned instance as a first argument - * @param {Array} [properties] Array of properties to include in the cloned canvas and children - */ - clone: function (callback, properties) { - var data = JSON.stringify(this.toJSON(properties)); - this.cloneWithoutData(function(clone) { - clone.loadFromJSON(data, function() { - callback && callback(clone); - }); - }); - }, - - /** - * Clones canvas instance without cloning existing data. - * This essentially copies canvas dimensions, clipping properties, etc. - * but leaves data empty (so that you can populate it with your own) - * @param {Object} [callback] Receives cloned instance as a first argument - */ - cloneWithoutData: function(callback) { - var el = fabric.util.createCanvasElement(); - - el.width = this.width; - el.height = this.height; - - var clone = new fabric.Canvas(el); - if (this.backgroundImage) { - clone.setBackgroundImage(this.backgroundImage.src, function() { - clone.renderAll(); - callback && callback(clone); - }); - clone.backgroundImageOpacity = this.backgroundImageOpacity; - clone.backgroundImageStretch = this.backgroundImageStretch; - } - else { - callback && callback(clone); - } - } -}); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - clone = fabric.util.object.clone, - toFixed = fabric.util.toFixed, - capitalize = fabric.util.string.capitalize, - degreesToRadians = fabric.util.degreesToRadians, - objectCaching = !fabric.isLikelyNode, - ALIASING_LIMIT = 2; - - if (fabric.Object) { - return; - } - - /** - * Root object class from which all 2d shape classes inherit from - * @class fabric.Object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects} - * @see {@link fabric.Object#initialize} for constructor definition - * - * @fires added - * @fires removed - * - * @fires selected - * @fires deselected - * @fires modified - * @fires modified - * @fires moved - * @fires scaled - * @fires rotated - * @fires skewed - * - * @fires rotating - * @fires scaling - * @fires moving - * @fires skewing - * - * @fires mousedown - * @fires mouseup - * @fires mouseover - * @fires mouseout - * @fires mousewheel - * @fires mousedblclick - * - * @fires dragover - * @fires dragenter - * @fires dragleave - * @fires drop - */ - fabric.Object = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.Object.prototype */ { - - /** - * Type of an object (rect, circle, path, etc.). - * Note that this property is meant to be read-only and not meant to be modified. - * If you modify, certain parts of Fabric (such as JSON loading) won't work correctly. - * @type String - * @default - */ - type: 'object', - - /** - * Horizontal origin of transformation of an object (one of "left", "right", "center") - * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups - * @type String - * @default - */ - originX: 'left', - - /** - * Vertical origin of transformation of an object (one of "top", "bottom", "center") - * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups - * @type String - * @default - */ - originY: 'top', - - /** - * Top position of an object. Note that by default it's relative to object top. You can change this by setting originY={top/center/bottom} - * @type Number - * @default - */ - top: 0, - - /** - * Left position of an object. Note that by default it's relative to object left. You can change this by setting originX={left/center/right} - * @type Number - * @default - */ - left: 0, - - /** - * Object width - * @type Number - * @default - */ - width: 0, - - /** - * Object height - * @type Number - * @default - */ - height: 0, - - /** - * Object scale factor (horizontal) - * @type Number - * @default - */ - scaleX: 1, - - /** - * Object scale factor (vertical) - * @type Number - * @default - */ - scaleY: 1, - - /** - * When true, an object is rendered as flipped horizontally - * @type Boolean - * @default - */ - flipX: false, - - /** - * When true, an object is rendered as flipped vertically - * @type Boolean - * @default - */ - flipY: false, - - /** - * Opacity of an object - * @type Number - * @default - */ - opacity: 1, - - /** - * Angle of rotation of an object (in degrees) - * @type Number - * @default - */ - angle: 0, - - /** - * Angle of skew on x axes of an object (in degrees) - * @type Number - * @default - */ - skewX: 0, - - /** - * Angle of skew on y axes of an object (in degrees) - * @type Number - * @default - */ - skewY: 0, - - /** - * Size of object's controlling corners (in pixels) - * @type Number - * @default - */ - cornerSize: 13, - - /** - * Size of object's controlling corners when touch interaction is detected - * @type Number - * @default - */ - touchCornerSize: 24, - - /** - * When true, object's controlling corners are rendered as transparent inside (i.e. stroke instead of fill) - * @type Boolean - * @default - */ - transparentCorners: true, - - /** - * Default cursor value used when hovering over this object on canvas - * @type String - * @default - */ - hoverCursor: null, - - /** - * Default cursor value used when moving this object on canvas - * @type String - * @default - */ - moveCursor: null, - - /** - * Padding between object and its controlling borders (in pixels) - * @type Number - * @default - */ - padding: 0, - - /** - * Color of controlling borders of an object (when it's active) - * @type String - * @default - */ - borderColor: 'rgb(178,204,255)', - - /** - * Array specifying dash pattern of an object's borders (hasBorder must be true) - * @since 1.6.2 - * @type Array - */ - borderDashArray: null, - - /** - * Color of controlling corners of an object (when it's active) - * @type String - * @default - */ - cornerColor: 'rgb(178,204,255)', - - /** - * Color of controlling corners of an object (when it's active and transparentCorners false) - * @since 1.6.2 - * @type String - * @default - */ - cornerStrokeColor: null, - - /** - * Specify style of control, 'rect' or 'circle' - * @since 1.6.2 - * @type String - */ - cornerStyle: 'rect', - - /** - * Array specifying dash pattern of an object's control (hasBorder must be true) - * @since 1.6.2 - * @type Array - */ - cornerDashArray: null, - - /** - * When true, this object will use center point as the origin of transformation - * when being scaled via the controls. - * Backwards incompatibility note: This property replaces "centerTransform" (Boolean). - * @since 1.3.4 - * @type Boolean - * @default - */ - centeredScaling: false, - - /** - * When true, this object will use center point as the origin of transformation - * when being rotated via the controls. - * Backwards incompatibility note: This property replaces "centerTransform" (Boolean). - * @since 1.3.4 - * @type Boolean - * @default - */ - centeredRotation: true, - - /** - * Color of object's fill - * takes css colors https://www.w3.org/TR/css-color-3/ - * @type String - * @default - */ - fill: 'rgb(0,0,0)', - - /** - * Fill rule used to fill an object - * accepted values are nonzero, evenodd - * Backwards incompatibility note: This property was used for setting globalCompositeOperation until v1.4.12 (use `fabric.Object#globalCompositeOperation` instead) - * @type String - * @default - */ - fillRule: 'nonzero', - - /** - * Composite rule used for canvas globalCompositeOperation - * @type String - * @default - */ - globalCompositeOperation: 'source-over', - - /** - * Background color of an object. - * takes css colors https://www.w3.org/TR/css-color-3/ - * @type String - * @default - */ - backgroundColor: '', - - /** - * Selection Background color of an object. colored layer behind the object when it is active. - * does not mix good with globalCompositeOperation methods. - * @type String - * @default - */ - selectionBackgroundColor: '', - - /** - * When defined, an object is rendered via stroke and this property specifies its color - * takes css colors https://www.w3.org/TR/css-color-3/ - * @type String - * @default - */ - stroke: null, - - /** - * Width of a stroke used to render this object - * @type Number - * @default - */ - strokeWidth: 1, - - /** - * Array specifying dash pattern of an object's stroke (stroke must be defined) - * @type Array - */ - strokeDashArray: null, - - /** - * Line offset of an object's stroke - * @type Number - * @default - */ - strokeDashOffset: 0, - - /** - * Line endings style of an object's stroke (one of "butt", "round", "square") - * @type String - * @default - */ - strokeLineCap: 'butt', - - /** - * Corner style of an object's stroke (one of "bevel", "round", "miter") - * @type String - * @default - */ - strokeLineJoin: 'miter', - - /** - * Maximum miter length (used for strokeLineJoin = "miter") of an object's stroke - * @type Number - * @default - */ - strokeMiterLimit: 4, - - /** - * Shadow object representing shadow of this shape - * @type fabric.Shadow - * @default - */ - shadow: null, - - /** - * Opacity of object's controlling borders when object is active and moving - * @type Number - * @default - */ - borderOpacityWhenMoving: 0.4, - - /** - * Scale factor of object's controlling borders - * bigger number will make a thicker border - * border is 1, so this is basically a border thickness - * since there is no way to change the border itself. - * @type Number - * @default - */ - borderScaleFactor: 1, - - /** - * Minimum allowed scale value of an object - * @type Number - * @default - */ - minScaleLimit: 0, - - /** - * When set to `false`, an object can not be selected for modification (using either point-click-based or group-based selection). - * But events still fire on it. - * @type Boolean - * @default - */ - selectable: true, - - /** - * When set to `false`, an object can not be a target of events. All events propagate through it. Introduced in v1.3.4 - * @type Boolean - * @default - */ - evented: true, - - /** - * When set to `false`, an object is not rendered on canvas - * @type Boolean - * @default - */ - visible: true, - - /** - * When set to `false`, object's controls are not displayed and can not be used to manipulate object - * @type Boolean - * @default - */ - hasControls: true, - - /** - * When set to `false`, object's controlling borders are not rendered - * @type Boolean - * @default - */ - hasBorders: true, - - /** - * When set to `true`, objects are "found" on canvas on per-pixel basis rather than according to bounding box - * @type Boolean - * @default - */ - perPixelTargetFind: false, - - /** - * When `false`, default object's values are not included in its serialization - * @type Boolean - * @default - */ - includeDefaultValues: true, - - /** - * When `true`, object horizontal movement is locked - * @type Boolean - * @default - */ - lockMovementX: false, - - /** - * When `true`, object vertical movement is locked - * @type Boolean - * @default - */ - lockMovementY: false, - - /** - * When `true`, object rotation is locked - * @type Boolean - * @default - */ - lockRotation: false, - - /** - * When `true`, object horizontal scaling is locked - * @type Boolean - * @default - */ - lockScalingX: false, - - /** - * When `true`, object vertical scaling is locked - * @type Boolean - * @default - */ - lockScalingY: false, - - /** - * When `true`, object horizontal skewing is locked - * @type Boolean - * @default - */ - lockSkewingX: false, - - /** - * When `true`, object vertical skewing is locked - * @type Boolean - * @default - */ - lockSkewingY: false, - - /** - * When `true`, object cannot be flipped by scaling into negative values - * @type Boolean - * @default - */ - lockScalingFlip: false, - - /** - * When `true`, object is not exported in OBJECT/JSON - * @since 1.6.3 - * @type Boolean - * @default - */ - excludeFromExport: false, - - /** - * When `true`, object is cached on an additional canvas. - * When `false`, object is not cached unless necessary ( clipPath ) - * default to true - * @since 1.7.0 - * @type Boolean - * @default true - */ - objectCaching: objectCaching, - - /** - * When `true`, object properties are checked for cache invalidation. In some particular - * situation you may want this to be disabled ( spray brush, very big, groups) - * or if your application does not allow you to modify properties for groups child you want - * to disable it for groups. - * default to false - * since 1.7.0 - * @type Boolean - * @default false - */ - statefullCache: false, - - /** - * When `true`, cache does not get updated during scaling. The picture will get blocky if scaled - * too much and will be redrawn with correct details at the end of scaling. - * this setting is performance and application dependant. - * default to true - * since 1.7.0 - * @type Boolean - * @default true - */ - noScaleCache: true, - - /** - * When `false`, the stoke width will scale with the object. - * When `true`, the stroke will always match the exact pixel size entered for stroke width. - * this Property does not work on Text classes or drawing call that uses strokeText,fillText methods - * default to false - * @since 2.6.0 - * @type Boolean - * @default false - * @type Boolean - * @default false - */ - strokeUniform: false, - - /** - * When set to `true`, object's cache will be rerendered next render call. - * since 1.7.0 - * @type Boolean - * @default true - */ - dirty: true, - - /** - * keeps the value of the last hovered corner during mouse move. - * 0 is no corner, or 'mt', 'ml', 'mtr' etc.. - * It should be private, but there is no harm in using it as - * a read-only property. - * @type number|string|any - * @default 0 - */ - __corner: 0, - - /** - * Determines if the fill or the stroke is drawn first (one of "fill" or "stroke") - * @type String - * @default - */ - paintFirst: 'fill', - - /** - * When 'down', object is set to active on mousedown/touchstart - * When 'up', object is set to active on mouseup/touchend - * Experimental. Let's see if this breaks anything before supporting officially - * @private - * since 4.4.0 - * @type String - * @default 'down' - */ - activeOn: 'down', - - /** - * List of properties to consider when checking if state - * of an object is changed (fabric.Object#hasStateChanged) - * as well as for history (undo/redo) purposes - * @type Array - */ - stateProperties: ( - 'top left width height scaleX scaleY flipX flipY originX originY transformMatrix ' + - 'stroke strokeWidth strokeDashArray strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit ' + - 'angle opacity fill globalCompositeOperation shadow visible backgroundColor ' + - 'skewX skewY fillRule paintFirst clipPath strokeUniform' - ).split(' '), - - /** - * List of properties to consider when checking if cache needs refresh - * Those properties are checked by statefullCache ON ( or lazy mode if we want ) or from single - * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty - * and refreshed at the next render - * @type Array - */ - cacheProperties: ( - 'fill stroke strokeWidth strokeDashArray width height paintFirst strokeUniform' + - ' strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit backgroundColor clipPath' - ).split(' '), - - /** - * List of properties to consider for animating colors. - * @type Array - */ - colorProperties: ( - 'fill stroke backgroundColor' - ).split(' '), - - /** - * a fabricObject that, without stroke define a clipping area with their shape. filled in black - * the clipPath object gets used when the object has rendered, and the context is placed in the center - * of the object cacheCanvas. - * If you want 0,0 of a clipPath to align with an object center, use clipPath.originX/Y to 'center' - * @type fabric.Object - */ - clipPath: undefined, - - /** - * Meaningful ONLY when the object is used as clipPath. - * if true, the clipPath will make the object clip to the outside of the clipPath - * since 2.4.0 - * @type boolean - * @default false - */ - inverted: false, - - /** - * Meaningful ONLY when the object is used as clipPath. - * if true, the clipPath will have its top and left relative to canvas, and will - * not be influenced by the object transform. This will make the clipPath relative - * to the canvas, but clipping just a particular object. - * WARNING this is beta, this feature may change or be renamed. - * since 2.4.0 - * @type boolean - * @default false - */ - absolutePositioned: false, - - /** - * Constructor - * @param {Object} [options] Options object - */ - initialize: function(options) { - if (options) { - this.setOptions(options); - } - }, - - /** - * Create a the canvas used to keep the cached copy of the object - * @private - */ - _createCacheCanvas: function() { - this._cacheProperties = {}; - this._cacheCanvas = fabric.util.createCanvasElement(); - this._cacheContext = this._cacheCanvas.getContext('2d'); - this._updateCacheCanvas(); - // if canvas gets created, is empty, so dirty. - this.dirty = true; - }, - - /** - * Limit the cache dimensions so that X * Y do not cross fabric.perfLimitSizeTotal - * and each side do not cross fabric.cacheSideLimit - * those numbers are configurable so that you can get as much detail as you want - * making bargain with performances. - * @param {Object} dims - * @param {Object} dims.width width of canvas - * @param {Object} dims.height height of canvas - * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache - * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache - * @return {Object}.width width of canvas - * @return {Object}.height height of canvas - * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache - * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache - */ - _limitCacheSize: function(dims) { - var perfLimitSizeTotal = fabric.perfLimitSizeTotal, - width = dims.width, height = dims.height, - max = fabric.maxCacheSideLimit, min = fabric.minCacheSideLimit; - if (width <= max && height <= max && width * height <= perfLimitSizeTotal) { - if (width < min) { - dims.width = min; - } - if (height < min) { - dims.height = min; - } - return dims; - } - var ar = width / height, limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal), - capValue = fabric.util.capValue, - x = capValue(min, limitedDims.x, max), - y = capValue(min, limitedDims.y, max); - if (width > x) { - dims.zoomX /= width / x; - dims.width = x; - dims.capped = true; - } - if (height > y) { - dims.zoomY /= height / y; - dims.height = y; - dims.capped = true; - } - return dims; - }, - - /** - * Return the dimension and the zoom level needed to create a cache canvas - * big enough to host the object to be cached. - * @private - * @return {Object}.x width of object to be cached - * @return {Object}.y height of object to be cached - * @return {Object}.width width of canvas - * @return {Object}.height height of canvas - * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache - * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache - */ - _getCacheCanvasDimensions: function() { - var objectScale = this.getTotalObjectScaling(), - // caculate dimensions without skewing - dim = this._getTransformedDimensions(0, 0), - neededX = dim.x * objectScale.scaleX / this.scaleX, - neededY = dim.y * objectScale.scaleY / this.scaleY; - return { - // for sure this ALIASING_LIMIT is slightly creating problem - // in situation in which the cache canvas gets an upper limit - // also objectScale contains already scaleX and scaleY - width: neededX + ALIASING_LIMIT, - height: neededY + ALIASING_LIMIT, - zoomX: objectScale.scaleX, - zoomY: objectScale.scaleY, - x: neededX, - y: neededY - }; - }, - - /** - * Update width and height of the canvas for cache - * returns true or false if canvas needed resize. - * @private - * @return {Boolean} true if the canvas has been resized - */ - _updateCacheCanvas: function() { - var targetCanvas = this.canvas; - if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) { - var target = targetCanvas._currentTransform.target, - action = targetCanvas._currentTransform.action; - if (this === target && action.slice && action.slice(0, 5) === 'scale') { - return false; - } - } - var canvas = this._cacheCanvas, - dims = this._limitCacheSize(this._getCacheCanvasDimensions()), - minCacheSize = fabric.minCacheSideLimit, - width = dims.width, height = dims.height, drawingWidth, drawingHeight, - zoomX = dims.zoomX, zoomY = dims.zoomY, - dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight, - zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY, - shouldRedraw = dimensionsChanged || zoomChanged, - additionalWidth = 0, additionalHeight = 0, shouldResizeCanvas = false; - if (dimensionsChanged) { - var canvasWidth = this._cacheCanvas.width, - canvasHeight = this._cacheCanvas.height, - sizeGrowing = width > canvasWidth || height > canvasHeight, - sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) && - canvasWidth > minCacheSize && canvasHeight > minCacheSize; - shouldResizeCanvas = sizeGrowing || sizeShrinking; - if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) { - additionalWidth = width * 0.1; - additionalHeight = height * 0.1; - } - } - if (this instanceof fabric.Text && this.path) { - shouldRedraw = true; - shouldResizeCanvas = true; - additionalWidth += this.getHeightOfLine(0) * this.zoomX; - additionalHeight += this.getHeightOfLine(0) * this.zoomY; - } - if (shouldRedraw) { - if (shouldResizeCanvas) { - canvas.width = Math.ceil(width + additionalWidth); - canvas.height = Math.ceil(height + additionalHeight); - } - else { - this._cacheContext.setTransform(1, 0, 0, 1, 0, 0); - this._cacheContext.clearRect(0, 0, canvas.width, canvas.height); - } - drawingWidth = dims.x / 2; - drawingHeight = dims.y / 2; - this.cacheTranslationX = Math.round(canvas.width / 2 - drawingWidth) + drawingWidth; - this.cacheTranslationY = Math.round(canvas.height / 2 - drawingHeight) + drawingHeight; - this.cacheWidth = width; - this.cacheHeight = height; - this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY); - this._cacheContext.scale(zoomX, zoomY); - this.zoomX = zoomX; - this.zoomY = zoomY; - return true; - } - return false; - }, - - /** - * Sets object's properties from options - * @param {Object} [options] Options object - */ - setOptions: function(options) { - this._setOptions(options); - this._initGradient(options.fill, 'fill'); - this._initGradient(options.stroke, 'stroke'); - this._initPattern(options.fill, 'fill'); - this._initPattern(options.stroke, 'stroke'); - }, - - /** - * Transforms context when rendering an object - * @param {CanvasRenderingContext2D} ctx Context - */ - transform: function(ctx) { - var needFullTransform = (this.group && !this.group._transformDone) || - (this.group && this.canvas && ctx === this.canvas.contextTop); - var m = this.calcTransformMatrix(!needFullTransform); - ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); - }, - - /** - * Returns an object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of an instance - */ - toObject: function(propertiesToInclude) { - var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, - - object = { - type: this.type, - version: fabric.version, - originX: this.originX, - originY: this.originY, - left: toFixed(this.left, NUM_FRACTION_DIGITS), - top: toFixed(this.top, NUM_FRACTION_DIGITS), - width: toFixed(this.width, NUM_FRACTION_DIGITS), - height: toFixed(this.height, NUM_FRACTION_DIGITS), - fill: (this.fill && this.fill.toObject) ? this.fill.toObject() : this.fill, - stroke: (this.stroke && this.stroke.toObject) ? this.stroke.toObject() : this.stroke, - strokeWidth: toFixed(this.strokeWidth, NUM_FRACTION_DIGITS), - strokeDashArray: this.strokeDashArray ? this.strokeDashArray.concat() : this.strokeDashArray, - strokeLineCap: this.strokeLineCap, - strokeDashOffset: this.strokeDashOffset, - strokeLineJoin: this.strokeLineJoin, - strokeUniform: this.strokeUniform, - strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS), - scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS), - scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS), - angle: toFixed(this.angle, NUM_FRACTION_DIGITS), - flipX: this.flipX, - flipY: this.flipY, - opacity: toFixed(this.opacity, NUM_FRACTION_DIGITS), - shadow: (this.shadow && this.shadow.toObject) ? this.shadow.toObject() : this.shadow, - visible: this.visible, - backgroundColor: this.backgroundColor, - fillRule: this.fillRule, - paintFirst: this.paintFirst, - globalCompositeOperation: this.globalCompositeOperation, - skewX: toFixed(this.skewX, NUM_FRACTION_DIGITS), - skewY: toFixed(this.skewY, NUM_FRACTION_DIGITS), - }; - - if (this.clipPath && !this.clipPath.excludeFromExport) { - object.clipPath = this.clipPath.toObject(propertiesToInclude); - object.clipPath.inverted = this.clipPath.inverted; - object.clipPath.absolutePositioned = this.clipPath.absolutePositioned; - } - - fabric.util.populateWithProperties(this, object, propertiesToInclude); - if (!this.includeDefaultValues) { - object = this._removeDefaultValues(object); - } - - return object; - }, - - /** - * Returns (dataless) object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of an instance - */ - toDatalessObject: function(propertiesToInclude) { - // will be overwritten by subclasses - return this.toObject(propertiesToInclude); - }, - - /** - * @private - * @param {Object} object - */ - _removeDefaultValues: function(object) { - var prototype = fabric.util.getKlass(object.type).prototype, - stateProperties = prototype.stateProperties; - stateProperties.forEach(function(prop) { - if (prop === 'left' || prop === 'top') { - return; - } - if (object[prop] === prototype[prop]) { - delete object[prop]; - } - // basically a check for [] === [] - if (Array.isArray(object[prop]) && Array.isArray(prototype[prop]) - && object[prop].length === 0 && prototype[prop].length === 0) { - delete object[prop]; - } - }); - - return object; - }, - - /** - * Returns a string representation of an instance - * @return {String} - */ - toString: function() { - return '#'; - }, - - /** - * Return the object scale factor counting also the group scaling - * @return {Object} object with scaleX and scaleY properties - */ - getObjectScaling: function() { - // if the object is a top level one, on the canvas, we go for simple aritmetic - // otherwise the complex method with angles will return approximations and decimals - // and will likely kill the cache when not needed - // https://github.com/fabricjs/fabric.js/issues/7157 - if (!this.group) { - return { - scaleX: this.scaleX, - scaleY: this.scaleY, - }; - } - // if we are inside a group total zoom calculation is complex, we defer to generic matrices - var options = fabric.util.qrDecompose(this.calcTransformMatrix()); - return { scaleX: Math.abs(options.scaleX), scaleY: Math.abs(options.scaleY) }; - }, - - /** - * Return the object scale factor counting also the group scaling, zoom and retina - * @return {Object} object with scaleX and scaleY properties - */ - getTotalObjectScaling: function() { - var scale = this.getObjectScaling(), scaleX = scale.scaleX, scaleY = scale.scaleY; - if (this.canvas) { - var zoom = this.canvas.getZoom(); - var retina = this.canvas.getRetinaScaling(); - scaleX *= zoom * retina; - scaleY *= zoom * retina; - } - return { scaleX: scaleX, scaleY: scaleY }; - }, - - /** - * Return the object opacity counting also the group property - * @return {Number} - */ - getObjectOpacity: function() { - var opacity = this.opacity; - if (this.group) { - opacity *= this.group.getObjectOpacity(); - } - return opacity; - }, - - /** - * @private - * @param {String} key - * @param {*} value - * @return {fabric.Object} thisArg - */ - _set: function(key, value) { - var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY'), - isChanged = this[key] !== value, groupNeedsUpdate = false; - - if (shouldConstrainValue) { - value = this._constrainScale(value); - } - if (key === 'scaleX' && value < 0) { - this.flipX = !this.flipX; - value *= -1; - } - else if (key === 'scaleY' && value < 0) { - this.flipY = !this.flipY; - value *= -1; - } - else if (key === 'shadow' && value && !(value instanceof fabric.Shadow)) { - value = new fabric.Shadow(value); - } - else if (key === 'dirty' && this.group) { - this.group.set('dirty', value); - } - - this[key] = value; - - if (isChanged) { - groupNeedsUpdate = this.group && this.group.isOnACache(); - if (this.cacheProperties.indexOf(key) > -1) { - this.dirty = true; - groupNeedsUpdate && this.group.set('dirty', true); - } - else if (groupNeedsUpdate && this.stateProperties.indexOf(key) > -1) { - this.group.set('dirty', true); - } - } - return this; - }, - - /** - * This callback function is called by the parent group of an object every - * time a non-delegated property changes on the group. It is passed the key - * and value as parameters. Not adding in this function's signature to avoid - * Travis build error about unused variables. - */ - setOnGroup: function() { - // implemented by sub-classes, as needed. - }, - - /** - * Retrieves viewportTransform from Object's canvas if possible - * @method getViewportTransform - * @memberOf fabric.Object.prototype - * @return {Array} - */ - getViewportTransform: function() { - if (this.canvas && this.canvas.viewportTransform) { - return this.canvas.viewportTransform; - } - return fabric.iMatrix.concat(); - }, - - /* - * @private - * return if the object would be visible in rendering - * @memberOf fabric.Object.prototype - * @return {Boolean} - */ - isNotVisible: function() { - return this.opacity === 0 || - (!this.width && !this.height && this.strokeWidth === 0) || - !this.visible; - }, - - /** - * Renders an object on a specified context - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - render: function(ctx) { - // do not render if width/height are zeros or object is not visible - if (this.isNotVisible()) { - return; - } - if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) { - return; - } - ctx.save(); - this._setupCompositeOperation(ctx); - this.drawSelectionBackground(ctx); - this.transform(ctx); - this._setOpacity(ctx); - this._setShadow(ctx, this); - if (this.shouldCache()) { - this.renderCache(); - this.drawCacheOnCanvas(ctx); - } - else { - this._removeCacheCanvas(); - this.dirty = false; - this.drawObject(ctx); - if (this.objectCaching && this.statefullCache) { - this.saveState({ propertySet: 'cacheProperties' }); - } - } - ctx.restore(); - }, - - renderCache: function(options) { - options = options || {}; - if (!this._cacheCanvas || !this._cacheContext) { - this._createCacheCanvas(); - } - if (this.isCacheDirty()) { - this.statefullCache && this.saveState({ propertySet: 'cacheProperties' }); - this.drawObject(this._cacheContext, options.forClipping); - this.dirty = false; - } - }, - - /** - * Remove cacheCanvas and its dimensions from the objects - */ - _removeCacheCanvas: function() { - this._cacheCanvas = null; - this._cacheContext = null; - this.cacheWidth = 0; - this.cacheHeight = 0; - }, - - /** - * return true if the object will draw a stroke - * Does not consider text styles. This is just a shortcut used at rendering time - * We want it to be an approximation and be fast. - * wrote to avoid extra caching, it has to return true when stroke happens, - * can guess when it will not happen at 100% chance, does not matter if it misses - * some use case where the stroke is invisible. - * @since 3.0.0 - * @returns Boolean - */ - hasStroke: function() { - return this.stroke && this.stroke !== 'transparent' && this.strokeWidth !== 0; - }, - - /** - * return true if the object will draw a fill - * Does not consider text styles. This is just a shortcut used at rendering time - * We want it to be an approximation and be fast. - * wrote to avoid extra caching, it has to return true when fill happens, - * can guess when it will not happen at 100% chance, does not matter if it misses - * some use case where the fill is invisible. - * @since 3.0.0 - * @returns Boolean - */ - hasFill: function() { - return this.fill && this.fill !== 'transparent'; - }, - - /** - * When set to `true`, force the object to have its own cache, even if it is inside a group - * it may be needed when your object behave in a particular way on the cache and always needs - * its own isolated canvas to render correctly. - * Created to be overridden - * since 1.7.12 - * @returns Boolean - */ - needsItsOwnCache: function() { - if (this.paintFirst === 'stroke' && - this.hasFill() && this.hasStroke() && typeof this.shadow === 'object') { - return true; - } - if (this.clipPath) { - return true; - } - return false; - }, - - /** - * Decide if the object should cache or not. Create its own cache level - * objectCaching is a global flag, wins over everything - * needsItsOwnCache should be used when the object drawing method requires - * a cache step. None of the fabric classes requires it. - * Generally you do not cache objects in groups because the group outside is cached. - * Read as: cache if is needed, or if the feature is enabled but we are not already caching. - * @return {Boolean} - */ - shouldCache: function() { - this.ownCaching = this.needsItsOwnCache() || ( - this.objectCaching && - (!this.group || !this.group.isOnACache()) - ); - return this.ownCaching; - }, - - /** - * Check if this object or a child object will cast a shadow - * used by Group.shouldCache to know if child has a shadow recursively - * @return {Boolean} - */ - willDrawShadow: function() { - return !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0); - }, - - /** - * Execute the drawing operation for an object clipPath - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {fabric.Object} clipPath - */ - drawClipPathOnCache: function(ctx, clipPath) { - ctx.save(); - // DEBUG: uncomment this line, comment the following - // ctx.globalAlpha = 0.4 - if (clipPath.inverted) { - ctx.globalCompositeOperation = 'destination-out'; - } - else { - ctx.globalCompositeOperation = 'destination-in'; - } - //ctx.scale(1 / 2, 1 / 2); - if (clipPath.absolutePositioned) { - var m = fabric.util.invertTransform(this.calcTransformMatrix()); - ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); - } - clipPath.transform(ctx); - ctx.scale(1 / clipPath.zoomX, 1 / clipPath.zoomY); - ctx.drawImage(clipPath._cacheCanvas, -clipPath.cacheTranslationX, -clipPath.cacheTranslationY); - ctx.restore(); - }, - - /** - * Execute the drawing operation for an object on a specified context - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - drawObject: function(ctx, forClipping) { - var originalFill = this.fill, originalStroke = this.stroke; - if (forClipping) { - this.fill = 'black'; - this.stroke = ''; - this._setClippingProperties(ctx); - } - else { - this._renderBackground(ctx); - } - this._render(ctx); - this._drawClipPath(ctx, this.clipPath); - this.fill = originalFill; - this.stroke = originalStroke; - }, - - /** - * Prepare clipPath state and cache and draw it on instance's cache - * @param {CanvasRenderingContext2D} ctx - * @param {fabric.Object} clipPath - */ - _drawClipPath: function (ctx, clipPath) { - if (!clipPath) { return; } - // needed to setup a couple of variables - // path canvas gets overridden with this one. - // TODO find a better solution? - clipPath.canvas = this.canvas; - clipPath.shouldCache(); - clipPath._transformDone = true; - clipPath.renderCache({ forClipping: true }); - this.drawClipPathOnCache(ctx, clipPath); - }, - - /** - * Paint the cached copy of the object on the target context. - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - drawCacheOnCanvas: function(ctx) { - ctx.scale(1 / this.zoomX, 1 / this.zoomY); - ctx.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY); - }, - - /** - * Check if cache is dirty - * @param {Boolean} skipCanvas skip canvas checks because this object is painted - * on parent canvas. - */ - isCacheDirty: function(skipCanvas) { - if (this.isNotVisible()) { - return false; - } - if (this._cacheCanvas && this._cacheContext && !skipCanvas && this._updateCacheCanvas()) { - // in this case the context is already cleared. - return true; - } - else { - if (this.dirty || - (this.clipPath && this.clipPath.absolutePositioned) || - (this.statefullCache && this.hasStateChanged('cacheProperties')) - ) { - if (this._cacheCanvas && this._cacheContext && !skipCanvas) { - var width = this.cacheWidth / this.zoomX; - var height = this.cacheHeight / this.zoomY; - this._cacheContext.clearRect(-width / 2, -height / 2, width, height); - } - return true; - } - } - return false; - }, - - /** - * Draws a background for the object big as its untransformed dimensions - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderBackground: function(ctx) { - if (!this.backgroundColor) { - return; - } - var dim = this._getNonTransformedDimensions(); - ctx.fillStyle = this.backgroundColor; - - ctx.fillRect( - -dim.x / 2, - -dim.y / 2, - dim.x, - dim.y - ); - // if there is background color no other shadows - // should be casted - this._removeShadow(ctx); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _setOpacity: function(ctx) { - if (this.group && !this.group._transformDone) { - ctx.globalAlpha = this.getObjectOpacity(); - } - else { - ctx.globalAlpha *= this.opacity; - } - }, - - _setStrokeStyles: function(ctx, decl) { - var stroke = decl.stroke; - if (stroke) { - ctx.lineWidth = decl.strokeWidth; - ctx.lineCap = decl.strokeLineCap; - ctx.lineDashOffset = decl.strokeDashOffset; - ctx.lineJoin = decl.strokeLineJoin; - ctx.miterLimit = decl.strokeMiterLimit; - if (stroke.toLive) { - if (stroke.gradientUnits === 'percentage' || stroke.gradientTransform || stroke.patternTransform) { - // need to transform gradient in a pattern. - // this is a slow process. If you are hitting this codepath, and the object - // is not using caching, you should consider switching it on. - // we need a canvas as big as the current object caching canvas. - this._applyPatternForTransformedGradient(ctx, stroke); - } - else { - // is a simple gradient or pattern - ctx.strokeStyle = stroke.toLive(ctx, this); - this._applyPatternGradientTransform(ctx, stroke); - } - } - else { - // is a color - ctx.strokeStyle = decl.stroke; - } - } - }, - - _setFillStyles: function(ctx, decl) { - var fill = decl.fill; - if (fill) { - if (fill.toLive) { - ctx.fillStyle = fill.toLive(ctx, this); - this._applyPatternGradientTransform(ctx, decl.fill); - } - else { - ctx.fillStyle = fill; - } - } - }, - - _setClippingProperties: function(ctx) { - ctx.globalAlpha = 1; - ctx.strokeStyle = 'transparent'; - ctx.fillStyle = '#000000'; - }, - - /** - * @private - * Sets line dash - * @param {CanvasRenderingContext2D} ctx Context to set the dash line on - * @param {Array} dashArray array representing dashes - */ - _setLineDash: function(ctx, dashArray) { - if (!dashArray || dashArray.length === 0) { - return; - } - // Spec requires the concatenation of two copies the dash list when the number of elements is odd - if (1 & dashArray.length) { - dashArray.push.apply(dashArray, dashArray); - } - ctx.setLineDash(dashArray); - }, - - /** - * Renders controls and borders for the object - * the context here is not transformed - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Object} [styleOverride] properties to override the object style - */ - _renderControls: function(ctx, styleOverride) { - var vpt = this.getViewportTransform(), - matrix = this.calcTransformMatrix(), - options, drawBorders, drawControls; - styleOverride = styleOverride || { }; - drawBorders = typeof styleOverride.hasBorders !== 'undefined' ? styleOverride.hasBorders : this.hasBorders; - drawControls = typeof styleOverride.hasControls !== 'undefined' ? styleOverride.hasControls : this.hasControls; - matrix = fabric.util.multiplyTransformMatrices(vpt, matrix); - options = fabric.util.qrDecompose(matrix); - ctx.save(); - ctx.translate(options.translateX, options.translateY); - ctx.lineWidth = 1 * this.borderScaleFactor; - if (!this.group) { - ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; - } - if (this.flipX) { - options.angle -= 180; - } - ctx.rotate(degreesToRadians(this.group ? options.angle : this.angle)); - if (styleOverride.forActiveSelection || this.group) { - drawBorders && this.drawBordersInGroup(ctx, options, styleOverride); - } - else { - drawBorders && this.drawBorders(ctx, styleOverride); - } - drawControls && this.drawControls(ctx, styleOverride); - ctx.restore(); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _setShadow: function(ctx) { - if (!this.shadow) { - return; - } - - var shadow = this.shadow, canvas = this.canvas, scaling, - multX = (canvas && canvas.viewportTransform[0]) || 1, - multY = (canvas && canvas.viewportTransform[3]) || 1; - if (shadow.nonScaling) { - scaling = { scaleX: 1, scaleY: 1 }; - } - else { - scaling = this.getObjectScaling(); - } - if (canvas && canvas._isRetinaScaling()) { - multX *= fabric.devicePixelRatio; - multY *= fabric.devicePixelRatio; - } - ctx.shadowColor = shadow.color; - ctx.shadowBlur = shadow.blur * fabric.browserShadowBlurConstant * - (multX + multY) * (scaling.scaleX + scaling.scaleY) / 4; - ctx.shadowOffsetX = shadow.offsetX * multX * scaling.scaleX; - ctx.shadowOffsetY = shadow.offsetY * multY * scaling.scaleY; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _removeShadow: function(ctx) { - if (!this.shadow) { - return; - } - - ctx.shadowColor = ''; - ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Object} filler fabric.Pattern or fabric.Gradient - * @return {Object} offset.offsetX offset for text rendering - * @return {Object} offset.offsetY offset for text rendering - */ - _applyPatternGradientTransform: function(ctx, filler) { - if (!filler || !filler.toLive) { - return { offsetX: 0, offsetY: 0 }; - } - var t = filler.gradientTransform || filler.patternTransform; - var offsetX = -this.width / 2 + filler.offsetX || 0, - offsetY = -this.height / 2 + filler.offsetY || 0; - - if (filler.gradientUnits === 'percentage') { - ctx.transform(this.width, 0, 0, this.height, offsetX, offsetY); - } - else { - ctx.transform(1, 0, 0, 1, offsetX, offsetY); - } - if (t) { - ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]); - } - return { offsetX: offsetX, offsetY: offsetY }; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderPaintInOrder: function(ctx) { - if (this.paintFirst === 'stroke') { - this._renderStroke(ctx); - this._renderFill(ctx); - } - else { - this._renderFill(ctx); - this._renderStroke(ctx); - } - }, - - /** - * @private - * function that actually render something on the context. - * empty here to allow Obects to work on tests to benchmark fabric functionalites - * not related to rendering - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(/* ctx */) { - - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderFill: function(ctx) { - if (!this.fill) { - return; - } - - ctx.save(); - this._setFillStyles(ctx, this); - if (this.fillRule === 'evenodd') { - ctx.fill('evenodd'); - } - else { - ctx.fill(); - } - ctx.restore(); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderStroke: function(ctx) { - if (!this.stroke || this.strokeWidth === 0) { - return; - } - - if (this.shadow && !this.shadow.affectStroke) { - this._removeShadow(ctx); - } - - ctx.save(); - if (this.strokeUniform && this.group) { - var scaling = this.getObjectScaling(); - ctx.scale(1 / scaling.scaleX, 1 / scaling.scaleY); - } - else if (this.strokeUniform) { - ctx.scale(1 / this.scaleX, 1 / this.scaleY); - } - this._setLineDash(ctx, this.strokeDashArray); - this._setStrokeStyles(ctx, this); - ctx.stroke(); - ctx.restore(); - }, - - /** - * This function try to patch the missing gradientTransform on canvas gradients. - * transforming a context to transform the gradient, is going to transform the stroke too. - * we want to transform the gradient but not the stroke operation, so we create - * a transformed gradient on a pattern and then we use the pattern instead of the gradient. - * this method has drwabacks: is slow, is in low resolution, needs a patch for when the size - * is limited. - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {fabric.Gradient} filler a fabric gradient instance - */ - _applyPatternForTransformedGradient: function(ctx, filler) { - var dims = this._limitCacheSize(this._getCacheCanvasDimensions()), - pCanvas = fabric.util.createCanvasElement(), pCtx, retinaScaling = this.canvas.getRetinaScaling(), - width = dims.x / this.scaleX / retinaScaling, height = dims.y / this.scaleY / retinaScaling; - pCanvas.width = width; - pCanvas.height = height; - pCtx = pCanvas.getContext('2d'); - pCtx.beginPath(); pCtx.moveTo(0, 0); pCtx.lineTo(width, 0); pCtx.lineTo(width, height); - pCtx.lineTo(0, height); pCtx.closePath(); - pCtx.translate(width / 2, height / 2); - pCtx.scale( - dims.zoomX / this.scaleX / retinaScaling, - dims.zoomY / this.scaleY / retinaScaling - ); - this._applyPatternGradientTransform(pCtx, filler); - pCtx.fillStyle = filler.toLive(ctx); - pCtx.fill(); - ctx.translate(-this.width / 2 - this.strokeWidth / 2, -this.height / 2 - this.strokeWidth / 2); - ctx.scale( - retinaScaling * this.scaleX / dims.zoomX, - retinaScaling * this.scaleY / dims.zoomY - ); - ctx.strokeStyle = pCtx.createPattern(pCanvas, 'no-repeat'); - }, - - /** - * This function is an helper for svg import. it returns the center of the object in the svg - * untransformed coordinates - * @private - * @return {Object} center point from element coordinates - */ - _findCenterFromElement: function() { - return { x: this.left + this.width / 2, y: this.top + this.height / 2 }; - }, - - /** - * This function is an helper for svg import. it decompose the transformMatrix - * and assign properties to object. - * untransformed coordinates - * @private - * @chainable - */ - _assignTransformMatrixProps: function() { - if (this.transformMatrix) { - var options = fabric.util.qrDecompose(this.transformMatrix); - this.flipX = false; - this.flipY = false; - this.set('scaleX', options.scaleX); - this.set('scaleY', options.scaleY); - this.angle = options.angle; - this.skewX = options.skewX; - this.skewY = 0; - } - }, - - /** - * This function is an helper for svg import. it removes the transform matrix - * and set to object properties that fabricjs can handle - * @private - * @param {Object} preserveAspectRatioOptions - * @return {thisArg} - */ - _removeTransformMatrix: function(preserveAspectRatioOptions) { - var center = this._findCenterFromElement(); - if (this.transformMatrix) { - this._assignTransformMatrixProps(); - center = fabric.util.transformPoint(center, this.transformMatrix); - } - this.transformMatrix = null; - if (preserveAspectRatioOptions) { - this.scaleX *= preserveAspectRatioOptions.scaleX; - this.scaleY *= preserveAspectRatioOptions.scaleY; - this.cropX = preserveAspectRatioOptions.cropX; - this.cropY = preserveAspectRatioOptions.cropY; - center.x += preserveAspectRatioOptions.offsetLeft; - center.y += preserveAspectRatioOptions.offsetTop; - this.width = preserveAspectRatioOptions.width; - this.height = preserveAspectRatioOptions.height; - } - this.setPositionByOrigin(center, 'center', 'center'); - }, - - /** - * Clones an instance, using a callback method will work for every object. - * @param {Function} callback Callback is invoked with a clone as a first argument - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - */ - clone: function(callback, propertiesToInclude) { - var objectForm = this.toObject(propertiesToInclude); - if (this.constructor.fromObject) { - this.constructor.fromObject(objectForm, callback); - } - else { - fabric.Object._fromObject('Object', objectForm, callback); - } - }, - - /** - * Creates an instance of fabric.Image out of an object - * makes use of toCanvasElement. - * Once this method was based on toDataUrl and loadImage, so it also had a quality - * and format option. toCanvasElement is faster and produce no loss of quality. - * If you need to get a real Jpeg or Png from an object, using toDataURL is the right way to do it. - * toCanvasElement and then toBlob from the obtained canvas is also a good option. - * This method is sync now, but still support the callback because we did not want to break. - * When fabricJS 5.0 will be planned, this will probably be changed to not have a callback. - * @param {Function} callback callback, invoked with an instance as a first argument - * @param {Object} [options] for clone as image, passed to toDataURL - * @param {Number} [options.multiplier=1] Multiplier to scale by - * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 - * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 - * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 - * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 - * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4 - * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 - * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2 - * @return {fabric.Object} thisArg - */ - cloneAsImage: function(callback, options) { - var canvasEl = this.toCanvasElement(options); - if (callback) { - callback(new fabric.Image(canvasEl)); - } - return this; - }, - - /** - * Converts an object into a HTMLCanvas element - * @param {Object} options Options object - * @param {Number} [options.multiplier=1] Multiplier to scale by - * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 - * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 - * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 - * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 - * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4 - * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 - * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2 - * @return {HTMLCanvasElement} Returns DOM element with the fabric.Object - */ - toCanvasElement: function(options) { - options || (options = { }); - - var utils = fabric.util, origParams = utils.saveObjectTransform(this), - originalGroup = this.group, - originalShadow = this.shadow, abs = Math.abs, - multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? fabric.devicePixelRatio : 1); - delete this.group; - if (options.withoutTransform) { - utils.resetObjectTransform(this); - } - if (options.withoutShadow) { - this.shadow = null; - } - - var el = fabric.util.createCanvasElement(), - // skip canvas zoom and calculate with setCoords now. - boundingRect = this.getBoundingRect(true, true), - shadow = this.shadow, scaling, - shadowOffset = { x: 0, y: 0 }, shadowBlur, - width, height; - - if (shadow) { - shadowBlur = shadow.blur; - if (shadow.nonScaling) { - scaling = { scaleX: 1, scaleY: 1 }; - } - else { - scaling = this.getObjectScaling(); - } - // consider non scaling shadow. - shadowOffset.x = 2 * Math.round(abs(shadow.offsetX) + shadowBlur) * (abs(scaling.scaleX)); - shadowOffset.y = 2 * Math.round(abs(shadow.offsetY) + shadowBlur) * (abs(scaling.scaleY)); - } - width = boundingRect.width + shadowOffset.x; - height = boundingRect.height + shadowOffset.y; - // if the current width/height is not an integer - // we need to make it so. - el.width = Math.ceil(width); - el.height = Math.ceil(height); - var canvas = new fabric.StaticCanvas(el, { - enableRetinaScaling: false, - renderOnAddRemove: false, - skipOffscreen: false, - }); - if (options.format === 'jpeg') { - canvas.backgroundColor = '#fff'; - } - this.setPositionByOrigin(new fabric.Point(canvas.width / 2, canvas.height / 2), 'center', 'center'); - - var originalCanvas = this.canvas; - canvas.add(this); - var canvasEl = canvas.toCanvasElement(multiplier || 1, options); - this.shadow = originalShadow; - this.set('canvas', originalCanvas); - if (originalGroup) { - this.group = originalGroup; - } - this.set(origParams).setCoords(); - // canvas.dispose will call image.dispose that will nullify the elements - // since this canvas is a simple element for the process, we remove references - // to objects in this way in order to avoid object trashing. - canvas._objects = []; - canvas.dispose(); - canvas = null; - - return canvasEl; - }, - - /** - * Converts an object into a data-url-like string - * @param {Object} options Options object - * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png" - * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg. - * @param {Number} [options.multiplier=1] Multiplier to scale by - * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 - * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 - * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 - * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 - * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4 - * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 - * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2 - * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format - */ - toDataURL: function(options) { - options || (options = { }); - return fabric.util.toDataURL(this.toCanvasElement(options), options.format || 'png', options.quality || 1); - }, - - /** - * Returns true if specified type is identical to the type of an instance - * @param {String} type Type to check against - * @return {Boolean} - */ - isType: function(type) { - return arguments.length > 1 ? Array.from(arguments).includes(this.type) : this.type === type; - }, - - /** - * Returns complexity of an instance - * @return {Number} complexity of this instance (is 1 unless subclassed) - */ - complexity: function() { - return 1; - }, - - /** - * Returns a JSON representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} JSON - */ - toJSON: function(propertiesToInclude) { - // delegate, not alias - return this.toObject(propertiesToInclude); - }, - - /** - * Sets "angle" of an instance with centered rotation - * @param {Number} angle Angle value (in degrees) - * @return {fabric.Object} thisArg - * @chainable - */ - rotate: function(angle) { - var shouldCenterOrigin = (this.originX !== 'center' || this.originY !== 'center') && this.centeredRotation; - - if (shouldCenterOrigin) { - this._setOriginToCenter(); - } - - this.set('angle', angle); - - if (shouldCenterOrigin) { - this._resetOrigin(); - } - - return this; - }, - - /** - * Centers object horizontally on canvas to which it was added last. - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - centerH: function () { - this.canvas && this.canvas.centerObjectH(this); - return this; - }, - - /** - * Centers object horizontally on current viewport of canvas to which it was added last. - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - viewportCenterH: function () { - this.canvas && this.canvas.viewportCenterObjectH(this); - return this; - }, - - /** - * Centers object vertically on canvas to which it was added last. - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - centerV: function () { - this.canvas && this.canvas.centerObjectV(this); - return this; - }, - - /** - * Centers object vertically on current viewport of canvas to which it was added last. - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - viewportCenterV: function () { - this.canvas && this.canvas.viewportCenterObjectV(this); - return this; - }, - - /** - * Centers object vertically and horizontally on canvas to which is was added last - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - center: function () { - this.canvas && this.canvas.centerObject(this); - return this; - }, - - /** - * Centers object on current viewport of canvas to which it was added last. - * You might need to call `setCoords` on an object after centering, to update controls area. - * @return {fabric.Object} thisArg - * @chainable - */ - viewportCenter: function () { - this.canvas && this.canvas.viewportCenterObject(this); - return this; - }, - - /** - * Returns coordinates of a pointer relative to an object - * @param {Event} e Event to operate upon - * @param {Object} [pointer] Pointer to operate upon (instead of event) - * @return {Object} Coordinates of a pointer (x, y) - */ - getLocalPointer: function(e, pointer) { - pointer = pointer || this.canvas.getPointer(e); - var pClicked = new fabric.Point(pointer.x, pointer.y), - objectLeftTop = this._getLeftTopCoords(); - if (this.angle) { - pClicked = fabric.util.rotatePoint( - pClicked, objectLeftTop, degreesToRadians(-this.angle)); - } - return { - x: pClicked.x - objectLeftTop.x, - y: pClicked.y - objectLeftTop.y - }; - }, - - /** - * Sets canvas globalCompositeOperation for specific object - * custom composition operation for the particular object can be specified using globalCompositeOperation property - * @param {CanvasRenderingContext2D} ctx Rendering canvas context - */ - _setupCompositeOperation: function (ctx) { - if (this.globalCompositeOperation) { - ctx.globalCompositeOperation = this.globalCompositeOperation; - } - }, - - /** - * cancel instance's running animations - * override if necessary to dispose artifacts such as `clipPath` - */ - dispose: function () { - if (fabric.runningAnimations) { - fabric.runningAnimations.cancelByTarget(this); - } - } - }); - - fabric.util.createAccessors && fabric.util.createAccessors(fabric.Object); - - extend(fabric.Object.prototype, fabric.Observable); - - /** - * Defines the number of fraction digits to use when serializing object values. - * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc. - * @static - * @memberOf fabric.Object - * @constant - * @type Number - */ - fabric.Object.NUM_FRACTION_DIGITS = 2; - - /** - * Defines which properties should be enlivened from the object passed to {@link fabric.Object._fromObject} - * @static - * @memberOf fabric.Object - * @constant - * @type string[] - */ - fabric.Object.ENLIVEN_PROPS = ['clipPath']; - - fabric.Object._fromObject = function(className, object, callback, extraParam) { - var klass = fabric[className]; - object = clone(object, true); - fabric.util.enlivenPatterns([object.fill, object.stroke], function(patterns) { - if (typeof patterns[0] !== 'undefined') { - object.fill = patterns[0]; - } - if (typeof patterns[1] !== 'undefined') { - object.stroke = patterns[1]; - } - fabric.util.enlivenObjectEnlivables(object, object, function () { - var instance = extraParam ? new klass(object[extraParam], object) : new klass(object); - callback && callback(instance); - }); - }); - }; - - /** - * Unique id used internally when creating SVG elements - * @static - * @memberOf fabric.Object - * @type Number - */ - fabric.Object.__uid = 0; -})(typeof exports !== 'undefined' ? exports : this); - - -(function() { - - var degreesToRadians = fabric.util.degreesToRadians, - originXOffset = { - left: -0.5, - center: 0, - right: 0.5 - }, - originYOffset = { - top: -0.5, - center: 0, - bottom: 0.5 - }; - - fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - - /** - * Translates the coordinates from a set of origin to another (based on the object's dimensions) - * @param {fabric.Point} point The point which corresponds to the originX and originY params - * @param {String} fromOriginX Horizontal origin: 'left', 'center' or 'right' - * @param {String} fromOriginY Vertical origin: 'top', 'center' or 'bottom' - * @param {String} toOriginX Horizontal origin: 'left', 'center' or 'right' - * @param {String} toOriginY Vertical origin: 'top', 'center' or 'bottom' - * @return {fabric.Point} - */ - translateToGivenOrigin: function(point, fromOriginX, fromOriginY, toOriginX, toOriginY) { - var x = point.x, - y = point.y, - offsetX, offsetY, dim; - - if (typeof fromOriginX === 'string') { - fromOriginX = originXOffset[fromOriginX]; - } - else { - fromOriginX -= 0.5; - } - - if (typeof toOriginX === 'string') { - toOriginX = originXOffset[toOriginX]; - } - else { - toOriginX -= 0.5; - } - - offsetX = toOriginX - fromOriginX; - - if (typeof fromOriginY === 'string') { - fromOriginY = originYOffset[fromOriginY]; - } - else { - fromOriginY -= 0.5; - } - - if (typeof toOriginY === 'string') { - toOriginY = originYOffset[toOriginY]; - } - else { - toOriginY -= 0.5; - } - - offsetY = toOriginY - fromOriginY; - - if (offsetX || offsetY) { - dim = this._getTransformedDimensions(); - x = point.x + offsetX * dim.x; - y = point.y + offsetY * dim.y; - } - - return new fabric.Point(x, y); - }, - - /** - * Translates the coordinates from origin to center coordinates (based on the object's dimensions) - * @param {fabric.Point} point The point which corresponds to the originX and originY params - * @param {String} originX Horizontal origin: 'left', 'center' or 'right' - * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' - * @return {fabric.Point} - */ - translateToCenterPoint: function(point, originX, originY) { - var p = this.translateToGivenOrigin(point, originX, originY, 'center', 'center'); - if (this.angle) { - return fabric.util.rotatePoint(p, point, degreesToRadians(this.angle)); - } - return p; - }, - - /** - * Translates the coordinates from center to origin coordinates (based on the object's dimensions) - * @param {fabric.Point} center The point which corresponds to center of the object - * @param {String} originX Horizontal origin: 'left', 'center' or 'right' - * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' - * @return {fabric.Point} - */ - translateToOriginPoint: function(center, originX, originY) { - var p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY); - if (this.angle) { - return fabric.util.rotatePoint(p, center, degreesToRadians(this.angle)); - } - return p; - }, - - /** - * Returns the real center coordinates of the object - * @return {fabric.Point} - */ - getCenterPoint: function() { - var leftTop = new fabric.Point(this.left, this.top); - return this.translateToCenterPoint(leftTop, this.originX, this.originY); - }, - - /** - * Returns the coordinates of the object based on center coordinates - * @param {fabric.Point} point The point which corresponds to the originX and originY params - * @return {fabric.Point} - */ - // getOriginPoint: function(center) { - // return this.translateToOriginPoint(center, this.originX, this.originY); - // }, - - /** - * Returns the coordinates of the object as if it has a different origin - * @param {String} originX Horizontal origin: 'left', 'center' or 'right' - * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' - * @return {fabric.Point} - */ - getPointByOrigin: function(originX, originY) { - var center = this.getCenterPoint(); - return this.translateToOriginPoint(center, originX, originY); - }, - - /** - * Returns the point in local coordinates - * @param {fabric.Point} point The point relative to the global coordinate system - * @param {String} originX Horizontal origin: 'left', 'center' or 'right' - * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' - * @return {fabric.Point} - */ - toLocalPoint: function(point, originX, originY) { - var center = this.getCenterPoint(), - p, p2; - - if (typeof originX !== 'undefined' && typeof originY !== 'undefined' ) { - p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY); - } - else { - p = new fabric.Point(this.left, this.top); - } - - p2 = new fabric.Point(point.x, point.y); - if (this.angle) { - p2 = fabric.util.rotatePoint(p2, center, -degreesToRadians(this.angle)); - } - return p2.subtractEquals(p); - }, - - /** - * Returns the point in global coordinates - * @param {fabric.Point} The point relative to the local coordinate system - * @return {fabric.Point} - */ - // toGlobalPoint: function(point) { - // return fabric.util.rotatePoint(point, this.getCenterPoint(), degreesToRadians(this.angle)).addEquals(new fabric.Point(this.left, this.top)); - // }, - - /** - * Sets the position of the object taking into consideration the object's origin - * @param {fabric.Point} pos The new position of the object - * @param {String} originX Horizontal origin: 'left', 'center' or 'right' - * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' - * @return {void} - */ - setPositionByOrigin: function(pos, originX, originY) { - var center = this.translateToCenterPoint(pos, originX, originY), - position = this.translateToOriginPoint(center, this.originX, this.originY); - this.set('left', position.x); - this.set('top', position.y); - }, - - /** - * @param {String} to One of 'left', 'center', 'right' - */ - adjustPosition: function(to) { - var angle = degreesToRadians(this.angle), - hypotFull = this.getScaledWidth(), - xFull = fabric.util.cos(angle) * hypotFull, - yFull = fabric.util.sin(angle) * hypotFull, - offsetFrom, offsetTo; - - //TODO: this function does not consider mixed situation like top, center. - if (typeof this.originX === 'string') { - offsetFrom = originXOffset[this.originX]; - } - else { - offsetFrom = this.originX - 0.5; - } - if (typeof to === 'string') { - offsetTo = originXOffset[to]; - } - else { - offsetTo = to - 0.5; - } - this.left += xFull * (offsetTo - offsetFrom); - this.top += yFull * (offsetTo - offsetFrom); - this.setCoords(); - this.originX = to; - }, - - /** - * Sets the origin/position of the object to it's center point - * @private - * @return {void} - */ - _setOriginToCenter: function() { - this._originalOriginX = this.originX; - this._originalOriginY = this.originY; - - var center = this.getCenterPoint(); - - this.originX = 'center'; - this.originY = 'center'; - - this.left = center.x; - this.top = center.y; - }, - - /** - * Resets the origin/position of the object to it's original origin - * @private - * @return {void} - */ - _resetOrigin: function() { - var originPoint = this.translateToOriginPoint( - this.getCenterPoint(), - this._originalOriginX, - this._originalOriginY); - - this.originX = this._originalOriginX; - this.originY = this._originalOriginY; - - this.left = originPoint.x; - this.top = originPoint.y; - - this._originalOriginX = null; - this._originalOriginY = null; - }, - - /** - * @private - */ - _getLeftTopCoords: function() { - return this.translateToOriginPoint(this.getCenterPoint(), 'left', 'top'); - }, - }); - -})(); - - -(function() { - - function arrayFromCoords(coords) { - return [ - new fabric.Point(coords.tl.x, coords.tl.y), - new fabric.Point(coords.tr.x, coords.tr.y), - new fabric.Point(coords.br.x, coords.br.y), - new fabric.Point(coords.bl.x, coords.bl.y) - ]; - } - - var util = fabric.util, - degreesToRadians = util.degreesToRadians, - multiplyMatrices = util.multiplyTransformMatrices, - transformPoint = util.transformPoint; - - util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - - /** - * Describe object's corner position in canvas element coordinates. - * properties are depending on control keys and padding the main controls. - * each property is an object with x, y and corner. - * The `corner` property contains in a similar manner the 4 points of the - * interactive area of the corner. - * The coordinates depends from the controls positionHandler and are used - * to draw and locate controls - * @memberOf fabric.Object.prototype - */ - oCoords: null, - - /** - * Describe object's corner position in canvas object absolute coordinates - * properties are tl,tr,bl,br and describe the four main corner. - * each property is an object with x, y, instance of Fabric.Point. - * The coordinates depends from this properties: width, height, scaleX, scaleY - * skewX, skewY, angle, strokeWidth, top, left. - * Those coordinates are useful to understand where an object is. They get updated - * with oCoords but they do not need to be updated when zoom or panning change. - * The coordinates get updated with @method setCoords. - * You can calculate them without updating with @method calcACoords(); - * @memberOf fabric.Object.prototype - */ - aCoords: null, - - /** - * Describe object's corner position in canvas element coordinates. - * includes padding. Used of object detection. - * set and refreshed with setCoords. - * @memberOf fabric.Object.prototype - */ - lineCoords: null, - - /** - * storage for object transform matrix - */ - ownMatrixCache: null, - - /** - * storage for object full transform matrix - */ - matrixCache: null, - - /** - * custom controls interface - * controls are added by default_controls.js - */ - controls: { }, - - /** - * return correct set of coordinates for intersection - * this will return either aCoords or lineCoords. - * @param {Boolean} absolute will return aCoords if true or lineCoords - * @return {Object} {tl, tr, br, bl} points - */ - _getCoords: function(absolute, calculate) { - if (calculate) { - return (absolute ? this.calcACoords() : this.calcLineCoords()); - } - if (!this.aCoords || !this.lineCoords) { - this.setCoords(true); - } - return (absolute ? this.aCoords : this.lineCoords); - }, - - /** - * return correct set of coordinates for intersection - * this will return either aCoords or lineCoords. - * The coords are returned in an array. - * @return {Array} [tl, tr, br, bl] of points - */ - getCoords: function(absolute, calculate) { - return arrayFromCoords(this._getCoords(absolute, calculate)); - }, - - /** - * Checks if object intersects with an area formed by 2 points - * @param {Object} pointTL top-left point of area - * @param {Object} pointBR bottom-right point of area - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if object intersects with an area formed by 2 points - */ - intersectsWithRect: function(pointTL, pointBR, absolute, calculate) { - var coords = this.getCoords(absolute, calculate), - intersection = fabric.Intersection.intersectPolygonRectangle( - coords, - pointTL, - pointBR - ); - return intersection.status === 'Intersection'; - }, - - /** - * Checks if object intersects with another object - * @param {Object} other Object to test - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if object intersects with another object - */ - intersectsWithObject: function(other, absolute, calculate) { - var intersection = fabric.Intersection.intersectPolygonPolygon( - this.getCoords(absolute, calculate), - other.getCoords(absolute, calculate) - ); - - return intersection.status === 'Intersection' - || other.isContainedWithinObject(this, absolute, calculate) - || this.isContainedWithinObject(other, absolute, calculate); - }, - - /** - * Checks if object is fully contained within area of another object - * @param {Object} other Object to test - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if object is fully contained within area of another object - */ - isContainedWithinObject: function(other, absolute, calculate) { - var points = this.getCoords(absolute, calculate), - otherCoords = absolute ? other.aCoords : other.lineCoords, - i = 0, lines = other._getImageLines(otherCoords); - for (; i < 4; i++) { - if (!other.containsPoint(points[i], lines)) { - return false; - } - } - return true; - }, - - /** - * Checks if object is fully contained within area formed by 2 points - * @param {Object} pointTL top-left point of area - * @param {Object} pointBR bottom-right point of area - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if object is fully contained within area formed by 2 points - */ - isContainedWithinRect: function(pointTL, pointBR, absolute, calculate) { - var boundingRect = this.getBoundingRect(absolute, calculate); - - return ( - boundingRect.left >= pointTL.x && - boundingRect.left + boundingRect.width <= pointBR.x && - boundingRect.top >= pointTL.y && - boundingRect.top + boundingRect.height <= pointBR.y - ); - }, - - /** - * Checks if point is inside the object - * @param {fabric.Point} point Point to check against - * @param {Object} [lines] object returned from @method _getImageLines - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if point is inside the object - */ - containsPoint: function(point, lines, absolute, calculate) { - var coords = this._getCoords(absolute, calculate), - lines = lines || this._getImageLines(coords), - xPoints = this._findCrossPoints(point, lines); - // if xPoints is odd then point is inside the object - return (xPoints !== 0 && xPoints % 2 === 1); - }, - - /** - * Checks if object is contained within the canvas with current viewportTransform - * the check is done stopping at first point that appears on screen - * @param {Boolean} [calculate] use coordinates of current position instead of .aCoords - * @return {Boolean} true if object is fully or partially contained within canvas - */ - isOnScreen: function(calculate) { - if (!this.canvas) { - return false; - } - var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br; - var points = this.getCoords(true, calculate); - // if some point is on screen, the object is on screen. - if (points.some(function(point) { - return point.x <= pointBR.x && point.x >= pointTL.x && - point.y <= pointBR.y && point.y >= pointTL.y; - })) { - return true; - } - // no points on screen, check intersection with absolute coordinates - if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) { - return true; - } - return this._containsCenterOfCanvas(pointTL, pointBR, calculate); - }, - - /** - * Checks if the object contains the midpoint between canvas extremities - * Does not make sense outside the context of isOnScreen and isPartiallyOnScreen - * @private - * @param {Fabric.Point} pointTL Top Left point - * @param {Fabric.Point} pointBR Top Right point - * @param {Boolean} calculate use coordinates of current position instead of .oCoords - * @return {Boolean} true if the object contains the point - */ - _containsCenterOfCanvas: function(pointTL, pointBR, calculate) { - // worst case scenario the object is so big that contains the screen - var centerPoint = { x: (pointTL.x + pointBR.x) / 2, y: (pointTL.y + pointBR.y) / 2 }; - if (this.containsPoint(centerPoint, null, true, calculate)) { - return true; - } - return false; - }, - - /** - * Checks if object is partially contained within the canvas with current viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords - * @return {Boolean} true if object is partially contained within canvas - */ - isPartiallyOnScreen: function(calculate) { - if (!this.canvas) { - return false; - } - var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br; - if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) { - return true; - } - var allPointsAreOutside = this.getCoords(true, calculate).every(function(point) { - return (point.x >= pointBR.x || point.x <= pointTL.x) && - (point.y >= pointBR.y || point.y <= pointTL.y); - }); - return allPointsAreOutside && this._containsCenterOfCanvas(pointTL, pointBR, calculate); - }, - - /** - * Method that returns an object with the object edges in it, given the coordinates of the corners - * @private - * @param {Object} oCoords Coordinates of the object corners - */ - _getImageLines: function(oCoords) { - - var lines = { - topline: { - o: oCoords.tl, - d: oCoords.tr - }, - rightline: { - o: oCoords.tr, - d: oCoords.br - }, - bottomline: { - o: oCoords.br, - d: oCoords.bl - }, - leftline: { - o: oCoords.bl, - d: oCoords.tl - } - }; - - // // debugging - // if (this.canvas.contextTop) { - // this.canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2); - // } - - return lines; - }, - - /** - * Helper method to determine how many cross points are between the 4 object edges - * and the horizontal line determined by a point on canvas - * @private - * @param {fabric.Point} point Point to check - * @param {Object} lines Coordinates of the object being evaluated - */ - // remove yi, not used but left code here just in case. - _findCrossPoints: function(point, lines) { - var b1, b2, a1, a2, xi, // yi, - xcount = 0, - iLine; - - for (var lineKey in lines) { - iLine = lines[lineKey]; - // optimisation 1: line below point. no cross - if ((iLine.o.y < point.y) && (iLine.d.y < point.y)) { - continue; - } - // optimisation 2: line above point. no cross - if ((iLine.o.y >= point.y) && (iLine.d.y >= point.y)) { - continue; - } - // optimisation 3: vertical line case - if ((iLine.o.x === iLine.d.x) && (iLine.o.x >= point.x)) { - xi = iLine.o.x; - // yi = point.y; - } - // calculate the intersection point - else { - b1 = 0; - b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x); - a1 = point.y - b1 * point.x; - a2 = iLine.o.y - b2 * iLine.o.x; - - xi = -(a1 - a2) / (b1 - b2); - // yi = a1 + b1 * xi; - } - // dont count xi < point.x cases - if (xi >= point.x) { - xcount += 1; - } - // optimisation 4: specific for square images - if (xcount === 2) { - break; - } - } - return xcount; - }, - - /** - * Returns coordinates of object's bounding rectangle (left, top, width, height) - * the box is intended as aligned to axis of canvas. - * @param {Boolean} [absolute] use coordinates without viewportTransform - * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords / .aCoords - * @return {Object} Object with left, top, width, height properties - */ - getBoundingRect: function(absolute, calculate) { - var coords = this.getCoords(absolute, calculate); - return util.makeBoundingBoxFromPoints(coords); - }, - - /** - * Returns width of an object's bounding box counting transformations - * before 2.0 it was named getWidth(); - * @return {Number} width value - */ - getScaledWidth: function() { - return this._getTransformedDimensions().x; - }, - - /** - * Returns height of an object bounding box counting transformations - * before 2.0 it was named getHeight(); - * @return {Number} height value - */ - getScaledHeight: function() { - return this._getTransformedDimensions().y; - }, - - /** - * Makes sure the scale is valid and modifies it if necessary - * @private - * @param {Number} value - * @return {Number} - */ - _constrainScale: function(value) { - if (Math.abs(value) < this.minScaleLimit) { - if (value < 0) { - return -this.minScaleLimit; - } - else { - return this.minScaleLimit; - } - } - else if (value === 0) { - return 0.0001; - } - return value; - }, - - /** - * Scales an object (equally by x and y) - * @param {Number} value Scale factor - * @return {fabric.Object} thisArg - * @chainable - */ - scale: function(value) { - this._set('scaleX', value); - this._set('scaleY', value); - return this.setCoords(); - }, - - /** - * Scales an object to a given width, with respect to bounding box (scaling by x/y equally) - * @param {Number} value New width value - * @param {Boolean} absolute ignore viewport - * @return {fabric.Object} thisArg - * @chainable - */ - scaleToWidth: function(value, absolute) { - // adjust to bounding rect factor so that rotated shapes would fit as well - var boundingRectFactor = this.getBoundingRect(absolute).width / this.getScaledWidth(); - return this.scale(value / this.width / boundingRectFactor); - }, - - /** - * Scales an object to a given height, with respect to bounding box (scaling by x/y equally) - * @param {Number} value New height value - * @param {Boolean} absolute ignore viewport - * @return {fabric.Object} thisArg - * @chainable - */ - scaleToHeight: function(value, absolute) { - // adjust to bounding rect factor so that rotated shapes would fit as well - var boundingRectFactor = this.getBoundingRect(absolute).height / this.getScaledHeight(); - return this.scale(value / this.height / boundingRectFactor); - }, - - calcLineCoords: function() { - var vpt = this.getViewportTransform(), - padding = this.padding, angle = degreesToRadians(this.angle), - cos = util.cos(angle), sin = util.sin(angle), - cosP = cos * padding, sinP = sin * padding, cosPSinP = cosP + sinP, - cosPMinusSinP = cosP - sinP, aCoords = this.calcACoords(); - - var lineCoords = { - tl: transformPoint(aCoords.tl, vpt), - tr: transformPoint(aCoords.tr, vpt), - bl: transformPoint(aCoords.bl, vpt), - br: transformPoint(aCoords.br, vpt), - }; - - if (padding) { - lineCoords.tl.x -= cosPMinusSinP; - lineCoords.tl.y -= cosPSinP; - lineCoords.tr.x += cosPSinP; - lineCoords.tr.y -= cosPMinusSinP; - lineCoords.bl.x -= cosPSinP; - lineCoords.bl.y += cosPMinusSinP; - lineCoords.br.x += cosPMinusSinP; - lineCoords.br.y += cosPSinP; - } - - return lineCoords; - }, - - calcOCoords: function() { - var rotateMatrix = this._calcRotateMatrix(), - translateMatrix = this._calcTranslateMatrix(), - vpt = this.getViewportTransform(), - startMatrix = multiplyMatrices(vpt, translateMatrix), - finalMatrix = multiplyMatrices(startMatrix, rotateMatrix), - finalMatrix = multiplyMatrices(finalMatrix, [1 / vpt[0], 0, 0, 1 / vpt[3], 0, 0]), - dim = this._calculateCurrentDimensions(), - coords = {}; - this.forEachControl(function(control, key, fabricObject) { - coords[key] = control.positionHandler(dim, finalMatrix, fabricObject); - }); - - // debug code - // var canvas = this.canvas; - // setTimeout(function() { - // canvas.contextTop.clearRect(0, 0, 700, 700); - // canvas.contextTop.fillStyle = 'green'; - // Object.keys(coords).forEach(function(key) { - // var control = coords[key]; - // canvas.contextTop.fillRect(control.x, control.y, 3, 3); - // }); - // }, 50); - return coords; - }, - - calcACoords: function() { - var rotateMatrix = this._calcRotateMatrix(), - translateMatrix = this._calcTranslateMatrix(), - finalMatrix = multiplyMatrices(translateMatrix, rotateMatrix), - dim = this._getTransformedDimensions(), - w = dim.x / 2, h = dim.y / 2; - return { - // corners - tl: transformPoint({ x: -w, y: -h }, finalMatrix), - tr: transformPoint({ x: w, y: -h }, finalMatrix), - bl: transformPoint({ x: -w, y: h }, finalMatrix), - br: transformPoint({ x: w, y: h }, finalMatrix) - }; - }, - - /** - * Sets corner and controls position coordinates based on current angle, width and height, left and top. - * oCoords are used to find the corners - * aCoords are used to quickly find an object on the canvas - * lineCoords are used to quickly find object during pointer events. - * See {@link https://github.com/fabricjs/fabric.js/wiki/When-to-call-setCoords} and {@link http://fabricjs.com/fabric-gotchas} - * - * @param {Boolean} [skipCorners] skip calculation of oCoords. - * @return {fabric.Object} thisArg - * @chainable - */ - setCoords: function(skipCorners) { - this.aCoords = this.calcACoords(); - // in case we are in a group, for how the inner group target check works, - // lineCoords are exactly aCoords. Since the vpt gets absorbed by the normalized pointer. - this.lineCoords = this.group ? this.aCoords : this.calcLineCoords(); - if (skipCorners) { - return this; - } - // set coordinates of the draggable boxes in the corners used to scale/rotate the image - this.oCoords = this.calcOCoords(); - this._setCornerCoords && this._setCornerCoords(); - return this; - }, - - /** - * calculate rotation matrix of an object - * @return {Array} rotation matrix for the object - */ - _calcRotateMatrix: function() { - return util.calcRotateMatrix(this); - }, - - /** - * calculate the translation matrix for an object transform - * @return {Array} rotation matrix for the object - */ - _calcTranslateMatrix: function() { - var center = this.getCenterPoint(); - return [1, 0, 0, 1, center.x, center.y]; - }, - - transformMatrixKey: function(skipGroup) { - var sep = '_', prefix = ''; - if (!skipGroup && this.group) { - prefix = this.group.transformMatrixKey(skipGroup) + sep; - }; - return prefix + this.top + sep + this.left + sep + this.scaleX + sep + this.scaleY + - sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.originX + sep + this.originY + - sep + this.width + sep + this.height + sep + this.strokeWidth + this.flipX + this.flipY; - }, - - /** - * calculate transform matrix that represents the current transformations from the - * object's properties. - * @param {Boolean} [skipGroup] return transform matrix for object not counting parent transformations - * There are some situation in which this is useful to avoid the fake rotation. - * @return {Array} transform matrix for the object - */ - calcTransformMatrix: function(skipGroup) { - var matrix = this.calcOwnMatrix(); - if (skipGroup || !this.group) { - return matrix; - } - var key = this.transformMatrixKey(skipGroup), cache = this.matrixCache || (this.matrixCache = {}); - if (cache.key === key) { - return cache.value; - } - if (this.group) { - matrix = multiplyMatrices(this.group.calcTransformMatrix(false), matrix); - } - cache.key = key; - cache.value = matrix; - return matrix; - }, - - /** - * calculate transform matrix that represents the current transformations from the - * object's properties, this matrix does not include the group transformation - * @return {Array} transform matrix for the object - */ - calcOwnMatrix: function() { - var key = this.transformMatrixKey(true), cache = this.ownMatrixCache || (this.ownMatrixCache = {}); - if (cache.key === key) { - return cache.value; - } - var tMatrix = this._calcTranslateMatrix(), - options = { - angle: this.angle, - translateX: tMatrix[4], - translateY: tMatrix[5], - scaleX: this.scaleX, - scaleY: this.scaleY, - skewX: this.skewX, - skewY: this.skewY, - flipX: this.flipX, - flipY: this.flipY, - }; - cache.key = key; - cache.value = util.composeMatrix(options); - return cache.value; - }, - - /* - * Calculate object dimensions from its properties - * @private - * @return {Object} .x width dimension - * @return {Object} .y height dimension - */ - _getNonTransformedDimensions: function() { - var strokeWidth = this.strokeWidth, - w = this.width + strokeWidth, - h = this.height + strokeWidth; - return { x: w, y: h }; - }, - - /* - * Calculate object bounding box dimensions from its properties scale, skew. - * @param {Number} skewX, a value to override current skewX - * @param {Number} skewY, a value to override current skewY - * @private - * @return {Object} .x width dimension - * @return {Object} .y height dimension - */ - _getTransformedDimensions: function(skewX, skewY) { - if (typeof skewX === 'undefined') { - skewX = this.skewX; - } - if (typeof skewY === 'undefined') { - skewY = this.skewY; - } - var dimensions, dimX, dimY, - noSkew = skewX === 0 && skewY === 0; - - if (this.strokeUniform) { - dimX = this.width; - dimY = this.height; - } - else { - dimensions = this._getNonTransformedDimensions(); - dimX = dimensions.x; - dimY = dimensions.y; - } - if (noSkew) { - return this._finalizeDimensions(dimX * this.scaleX, dimY * this.scaleY); - } - var bbox = util.sizeAfterTransform(dimX, dimY, { - scaleX: this.scaleX, - scaleY: this.scaleY, - skewX: skewX, - skewY: skewY, - }); - return this._finalizeDimensions(bbox.x, bbox.y); - }, - - /* - * Calculate object bounding box dimensions from its properties scale, skew. - * @param Number width width of the bbox - * @param Number height height of the bbox - * @private - * @return {Object} .x finalized width dimension - * @return {Object} .y finalized height dimension - */ - _finalizeDimensions: function(width, height) { - return this.strokeUniform ? - { x: width + this.strokeWidth, y: height + this.strokeWidth } - : - { x: width, y: height }; - }, - - /* - * Calculate object dimensions for controls box, including padding and canvas zoom. - * and active selection - * private - */ - _calculateCurrentDimensions: function() { - var vpt = this.getViewportTransform(), - dim = this._getTransformedDimensions(), - p = transformPoint(dim, vpt, true); - return p.scalarAdd(2 * this.padding); - }, - }); -})(); - - -fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - - /** - * Moves an object to the bottom of the stack of drawn objects - * @return {fabric.Object} thisArg - * @chainable - */ - sendToBack: function() { - if (this.group) { - fabric.StaticCanvas.prototype.sendToBack.call(this.group, this); - } - else if (this.canvas) { - this.canvas.sendToBack(this); - } - return this; - }, - - /** - * Moves an object to the top of the stack of drawn objects - * @return {fabric.Object} thisArg - * @chainable - */ - bringToFront: function() { - if (this.group) { - fabric.StaticCanvas.prototype.bringToFront.call(this.group, this); - } - else if (this.canvas) { - this.canvas.bringToFront(this); - } - return this; - }, - - /** - * Moves an object down in stack of drawn objects - * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object - * @return {fabric.Object} thisArg - * @chainable - */ - sendBackwards: function(intersecting) { - if (this.group) { - fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting); - } - else if (this.canvas) { - this.canvas.sendBackwards(this, intersecting); - } - return this; - }, - - /** - * Moves an object up in stack of drawn objects - * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object - * @return {fabric.Object} thisArg - * @chainable - */ - bringForward: function(intersecting) { - if (this.group) { - fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting); - } - else if (this.canvas) { - this.canvas.bringForward(this, intersecting); - } - return this; - }, - - /** - * Moves an object to specified level in stack of drawn objects - * @param {Number} index New position of object - * @return {fabric.Object} thisArg - * @chainable - */ - moveTo: function(index) { - if (this.group && this.group.type !== 'activeSelection') { - fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index); - } - else if (this.canvas) { - this.canvas.moveTo(this, index); - } - return this; - } -}); - - -/* _TO_SVG_START_ */ -(function() { - function getSvgColorString(prop, value) { - if (!value) { - return prop + ': none; '; - } - else if (value.toLive) { - return prop + ': url(#SVGID_' + value.id + '); '; - } - else { - var color = new fabric.Color(value), - str = prop + ': ' + color.toRgb() + '; ', - opacity = color.getAlpha(); - if (opacity !== 1) { - //change the color in rgb + opacity - str += prop + '-opacity: ' + opacity.toString() + '; '; - } - return str; - } - } - - var toFixed = fabric.util.toFixed; - - fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - /** - * Returns styles-string for svg-export - * @param {Boolean} skipShadow a boolean to skip shadow filter output - * @return {String} - */ - getSvgStyles: function(skipShadow) { - - var fillRule = this.fillRule ? this.fillRule : 'nonzero', - strokeWidth = this.strokeWidth ? this.strokeWidth : '0', - strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none', - strokeDashOffset = this.strokeDashOffset ? this.strokeDashOffset : '0', - strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt', - strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter', - strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4', - opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1', - visibility = this.visible ? '' : ' visibility: hidden;', - filter = skipShadow ? '' : this.getSvgFilter(), - fill = getSvgColorString('fill', this.fill), - stroke = getSvgColorString('stroke', this.stroke); - - return [ - stroke, - 'stroke-width: ', strokeWidth, '; ', - 'stroke-dasharray: ', strokeDashArray, '; ', - 'stroke-linecap: ', strokeLineCap, '; ', - 'stroke-dashoffset: ', strokeDashOffset, '; ', - 'stroke-linejoin: ', strokeLineJoin, '; ', - 'stroke-miterlimit: ', strokeMiterLimit, '; ', - fill, - 'fill-rule: ', fillRule, '; ', - 'opacity: ', opacity, ';', - filter, - visibility - ].join(''); - }, - - /** - * Returns styles-string for svg-export - * @param {Object} style the object from which to retrieve style properties - * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style. - * @return {String} - */ - getSvgSpanStyles: function(style, useWhiteSpace) { - var term = '; '; - var fontFamily = style.fontFamily ? - 'font-family: ' + (((style.fontFamily.indexOf('\'') === -1 && style.fontFamily.indexOf('"') === -1) ? - '\'' + style.fontFamily + '\'' : style.fontFamily)) + term : ''; - var strokeWidth = style.strokeWidth ? 'stroke-width: ' + style.strokeWidth + term : '', - fontFamily = fontFamily, - fontSize = style.fontSize ? 'font-size: ' + style.fontSize + 'px' + term : '', - fontStyle = style.fontStyle ? 'font-style: ' + style.fontStyle + term : '', - fontWeight = style.fontWeight ? 'font-weight: ' + style.fontWeight + term : '', - fill = style.fill ? getSvgColorString('fill', style.fill) : '', - stroke = style.stroke ? getSvgColorString('stroke', style.stroke) : '', - textDecoration = this.getSvgTextDecoration(style), - deltaY = style.deltaY ? 'baseline-shift: ' + (-style.deltaY) + '; ' : ''; - if (textDecoration) { - textDecoration = 'text-decoration: ' + textDecoration + term; - } - - return [ - stroke, - strokeWidth, - fontFamily, - fontSize, - fontStyle, - fontWeight, - textDecoration, - fill, - deltaY, - useWhiteSpace ? 'white-space: pre; ' : '' - ].join(''); - }, - - /** - * Returns text-decoration property for svg-export - * @param {Object} style the object from which to retrieve style properties - * @return {String} - */ - getSvgTextDecoration: function(style) { - return ['overline', 'underline', 'line-through'].filter(function(decoration) { - return style[decoration.replace('-', '')]; - }).join(' '); - }, - - /** - * Returns filter for svg shadow - * @return {String} - */ - getSvgFilter: function() { - return this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : ''; - }, - - /** - * Returns id attribute for svg output - * @return {String} - */ - getSvgCommons: function() { - return [ - this.id ? 'id="' + this.id + '" ' : '', - this.clipPath ? 'clip-path="url(#' + this.clipPath.clipPathId + ')" ' : '', - ].join(''); - }, - - /** - * Returns transform-string for svg-export - * @param {Boolean} use the full transform or the single object one. - * @return {String} - */ - getSvgTransform: function(full, additionalTransform) { - var transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(), - svgTransform = 'transform="' + fabric.util.matrixToSVG(transform); - return svgTransform + - (additionalTransform || '') + '" '; - }, - - _setSVGBg: function(textBgRects) { - if (this.backgroundColor) { - var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - textBgRects.push( - '\t\t\n'); - } - }, - - /** - * Returns svg representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toSVG: function(reviver) { - return this._createBaseSVGMarkup(this._toSVG(reviver), { reviver: reviver }); - }, - - /** - * Returns svg clipPath representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toClipPathSVG: function(reviver) { - return '\t' + this._createBaseClipPathSVGMarkup(this._toSVG(reviver), { reviver: reviver }); - }, - - /** - * @private - */ - _createBaseClipPathSVGMarkup: function(objectMarkup, options) { - options = options || {}; - var reviver = options.reviver, - additionalTransform = options.additionalTransform || '', - commonPieces = [ - this.getSvgTransform(true, additionalTransform), - this.getSvgCommons(), - ].join(''), - // insert commons in the markup, style and svgCommons - index = objectMarkup.indexOf('COMMON_PARTS'); - objectMarkup[index] = commonPieces; - return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join(''); - }, - - /** - * @private - */ - _createBaseSVGMarkup: function(objectMarkup, options) { - options = options || {}; - var noStyle = options.noStyle, - reviver = options.reviver, - styleInfo = noStyle ? '' : 'style="' + this.getSvgStyles() + '" ', - shadowInfo = options.withShadow ? 'style="' + this.getSvgFilter() + '" ' : '', - clipPath = this.clipPath, - vectorEffect = this.strokeUniform ? 'vector-effect="non-scaling-stroke" ' : '', - absoluteClipPath = clipPath && clipPath.absolutePositioned, - stroke = this.stroke, fill = this.fill, shadow = this.shadow, - commonPieces, markup = [], clipPathMarkup, - // insert commons in the markup, style and svgCommons - index = objectMarkup.indexOf('COMMON_PARTS'), - additionalTransform = options.additionalTransform; - if (clipPath) { - clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++; - clipPathMarkup = '\n' + - clipPath.toClipPathSVG(reviver) + - '\n'; - } - if (absoluteClipPath) { - markup.push( - '\n' - ); - } - markup.push( - '\n' - ); - commonPieces = [ - styleInfo, - vectorEffect, - noStyle ? '' : this.addPaintOrder(), ' ', - additionalTransform ? 'transform="' + additionalTransform + '" ' : '', - ].join(''); - objectMarkup[index] = commonPieces; - if (fill && fill.toLive) { - markup.push(fill.toSVG(this)); - } - if (stroke && stroke.toLive) { - markup.push(stroke.toSVG(this)); - } - if (shadow) { - markup.push(shadow.toSVG(this)); - } - if (clipPath) { - markup.push(clipPathMarkup); - } - markup.push(objectMarkup.join('')); - markup.push('\n'); - absoluteClipPath && markup.push('\n'); - return reviver ? reviver(markup.join('')) : markup.join(''); - }, - - addPaintOrder: function() { - return this.paintFirst !== 'fill' ? ' paint-order="' + this.paintFirst + '" ' : ''; - } - }); -})(); -/* _TO_SVG_END_ */ - - -(function() { - - var extend = fabric.util.object.extend, - originalSet = 'stateProperties'; - - /* - Depends on `stateProperties` - */ - function saveProps(origin, destination, props) { - var tmpObj = { }, deep = true; - props.forEach(function(prop) { - tmpObj[prop] = origin[prop]; - }); - - extend(origin[destination], tmpObj, deep); - } - - function _isEqual(origValue, currentValue, firstPass) { - if (origValue === currentValue) { - // if the objects are identical, return - return true; - } - else if (Array.isArray(origValue)) { - if (!Array.isArray(currentValue) || origValue.length !== currentValue.length) { - return false; - } - for (var i = 0, len = origValue.length; i < len; i++) { - if (!_isEqual(origValue[i], currentValue[i])) { - return false; - } - } - return true; - } - else if (origValue && typeof origValue === 'object') { - var keys = Object.keys(origValue), key; - if (!currentValue || - typeof currentValue !== 'object' || - (!firstPass && keys.length !== Object.keys(currentValue).length) - ) { - return false; - } - for (var i = 0, len = keys.length; i < len; i++) { - key = keys[i]; - // since clipPath is in the statefull cache list and the clipPath objects - // would be iterated as an object, this would lead to possible infinite recursion - // we do not want to compare those. - if (key === 'canvas' || key === 'group') { - continue; - } - if (!_isEqual(origValue[key], currentValue[key])) { - return false; - } - } - return true; - } - } - - - fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - - /** - * Returns true if object state (one of its state properties) was changed - * @param {String} [propertySet] optional name for the set of property we want to save - * @return {Boolean} true if instance' state has changed since `{@link fabric.Object#saveState}` was called - */ - hasStateChanged: function(propertySet) { - propertySet = propertySet || originalSet; - var dashedPropertySet = '_' + propertySet; - if (Object.keys(this[dashedPropertySet]).length < this[propertySet].length) { - return true; - } - return !_isEqual(this[dashedPropertySet], this, true); - }, - - /** - * Saves state of an object - * @param {Object} [options] Object with additional `stateProperties` array to include when saving state - * @return {fabric.Object} thisArg - */ - saveState: function(options) { - var propertySet = options && options.propertySet || originalSet, - destination = '_' + propertySet; - if (!this[destination]) { - return this.setupState(options); - } - saveProps(this, destination, this[propertySet]); - if (options && options.stateProperties) { - saveProps(this, destination, options.stateProperties); - } - return this; - }, - - /** - * Setups state of an object - * @param {Object} [options] Object with additional `stateProperties` array to include when saving state - * @return {fabric.Object} thisArg - */ - setupState: function(options) { - options = options || { }; - var propertySet = options.propertySet || originalSet; - options.propertySet = propertySet; - this['_' + propertySet] = { }; - this.saveState(options); - return this; - } - }); -})(); - - -(function() { - - var degreesToRadians = fabric.util.degreesToRadians; - - fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - /** - * Determines which corner has been clicked - * @private - * @param {Object} pointer The pointer indicating the mouse position - * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or false if nothing is found - */ - _findTargetCorner: function(pointer, forTouch) { - // objects in group, anykind, are not self modificable, - // must not return an hovered corner. - if (!this.hasControls || this.group || (!this.canvas || this.canvas._activeObject !== this)) { - return false; - } - - var ex = pointer.x, - ey = pointer.y, - xPoints, - lines, keys = Object.keys(this.oCoords), - j = keys.length - 1, i; - this.__corner = 0; - - // cycle in reverse order so we pick first the one on top - for (; j >= 0; j--) { - i = keys[j]; - if (!this.isControlVisible(i)) { - continue; - } - - lines = this._getImageLines(forTouch ? this.oCoords[i].touchCorner : this.oCoords[i].corner); - // // debugging - // - // this.canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2); - // - // this.canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2); - // this.canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2); - - xPoints = this._findCrossPoints({ x: ex, y: ey }, lines); - if (xPoints !== 0 && xPoints % 2 === 1) { - this.__corner = i; - return i; - } - } - return false; - }, - - /** - * Calls a function for each control. The function gets called, - * with the control, the object that is calling the iterator and the control's key - * @param {Function} fn function to iterate over the controls over - */ - forEachControl: function(fn) { - for (var i in this.controls) { - fn(this.controls[i], i, this); - }; - }, - - /** - * Sets the coordinates of the draggable boxes in the corners of - * the image used to scale/rotate it. - * note: if we would switch to ROUND corner area, all of this would disappear. - * everything would resolve to a single point and a pythagorean theorem for the distance - * @private - */ - _setCornerCoords: function() { - var coords = this.oCoords; - - for (var control in coords) { - var controlObject = this.controls[control]; - coords[control].corner = controlObject.calcCornerCoords( - this.angle, this.cornerSize, coords[control].x, coords[control].y, false); - coords[control].touchCorner = controlObject.calcCornerCoords( - this.angle, this.touchCornerSize, coords[control].x, coords[control].y, true); - } - }, - - /** - * Draws a colored layer behind the object, inside its selection borders. - * Requires public options: padding, selectionBackgroundColor - * this function is called when the context is transformed - * has checks to be skipped when the object is on a staticCanvas - * @param {CanvasRenderingContext2D} ctx Context to draw on - * @return {fabric.Object} thisArg - * @chainable - */ - drawSelectionBackground: function(ctx) { - if (!this.selectionBackgroundColor || - (this.canvas && !this.canvas.interactive) || - (this.canvas && this.canvas._activeObject !== this) - ) { - return this; - } - ctx.save(); - var center = this.getCenterPoint(), wh = this._calculateCurrentDimensions(), - vpt = this.canvas.viewportTransform; - ctx.translate(center.x, center.y); - ctx.scale(1 / vpt[0], 1 / vpt[3]); - ctx.rotate(degreesToRadians(this.angle)); - ctx.fillStyle = this.selectionBackgroundColor; - ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y); - ctx.restore(); - return this; - }, - - /** - * Draws borders of an object's bounding box. - * Requires public properties: width, height - * Requires public options: padding, borderColor - * @param {CanvasRenderingContext2D} ctx Context to draw on - * @param {Object} styleOverride object to override the object style - * @return {fabric.Object} thisArg - * @chainable - */ - drawBorders: function(ctx, styleOverride) { - styleOverride = styleOverride || {}; - var wh = this._calculateCurrentDimensions(), - strokeWidth = this.borderScaleFactor, - width = wh.x + strokeWidth, - height = wh.y + strokeWidth, - hasControls = typeof styleOverride.hasControls !== 'undefined' ? - styleOverride.hasControls : this.hasControls, - shouldStroke = false; - - ctx.save(); - ctx.strokeStyle = styleOverride.borderColor || this.borderColor; - this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray); - - ctx.strokeRect( - -width / 2, - -height / 2, - width, - height - ); - - if (hasControls) { - ctx.beginPath(); - this.forEachControl(function(control, key, fabricObject) { - // in this moment, the ctx is centered on the object. - // width and height of the above function are the size of the bbox. - if (control.withConnection && control.getVisibility(fabricObject, key)) { - // reset movement for each control - shouldStroke = true; - ctx.moveTo(control.x * width, control.y * height); - ctx.lineTo( - control.x * width + control.offsetX, - control.y * height + control.offsetY - ); - } - }); - if (shouldStroke) { - ctx.stroke(); - } - } - ctx.restore(); - return this; - }, - - /** - * Draws borders of an object's bounding box when it is inside a group. - * Requires public properties: width, height - * Requires public options: padding, borderColor - * @param {CanvasRenderingContext2D} ctx Context to draw on - * @param {object} options object representing current object parameters - * @param {Object} styleOverride object to override the object style - * @return {fabric.Object} thisArg - * @chainable - */ - drawBordersInGroup: function(ctx, options, styleOverride) { - styleOverride = styleOverride || {}; - var bbox = fabric.util.sizeAfterTransform(this.width, this.height, options), - strokeWidth = this.strokeWidth, - strokeUniform = this.strokeUniform, - borderScaleFactor = this.borderScaleFactor, - width = - bbox.x + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleX) + borderScaleFactor, - height = - bbox.y + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleY) + borderScaleFactor; - ctx.save(); - this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray); - ctx.strokeStyle = styleOverride.borderColor || this.borderColor; - ctx.strokeRect( - -width / 2, - -height / 2, - width, - height - ); - - ctx.restore(); - return this; - }, - - /** - * Draws corners of an object's bounding box. - * Requires public properties: width, height - * Requires public options: cornerSize, padding - * @param {CanvasRenderingContext2D} ctx Context to draw on - * @param {Object} styleOverride object to override the object style - * @return {fabric.Object} thisArg - * @chainable - */ - drawControls: function(ctx, styleOverride) { - styleOverride = styleOverride || {}; - ctx.save(); - var retinaScaling = this.canvas.getRetinaScaling(), matrix, p; - ctx.setTransform(retinaScaling, 0, 0, retinaScaling, 0, 0); - ctx.strokeStyle = ctx.fillStyle = styleOverride.cornerColor || this.cornerColor; - if (!this.transparentCorners) { - ctx.strokeStyle = styleOverride.cornerStrokeColor || this.cornerStrokeColor; - } - this._setLineDash(ctx, styleOverride.cornerDashArray || this.cornerDashArray); - this.setCoords(); - if (this.group) { - // fabricJS does not really support drawing controls inside groups, - // this piece of code here helps having at least the control in places. - // If an application needs to show some objects as selected because of some UI state - // can still call Object._renderControls() on any object they desire, independently of groups. - // using no padding, circular controls and hiding the rotating cursor is higly suggested, - matrix = this.group.calcTransformMatrix(); - } - this.forEachControl(function(control, key, fabricObject) { - p = fabricObject.oCoords[key]; - if (control.getVisibility(fabricObject, key)) { - if (matrix) { - p = fabric.util.transformPoint(p, matrix); - } - control.render(ctx, p.x, p.y, styleOverride, fabricObject); - } - }); - ctx.restore(); - - return this; - }, - - /** - * Returns true if the specified control is visible, false otherwise. - * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'. - * @returns {Boolean} true if the specified control is visible, false otherwise - */ - isControlVisible: function(controlKey) { - return this.controls[controlKey] && this.controls[controlKey].getVisibility(this, controlKey); - }, - - /** - * Sets the visibility of the specified control. - * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'. - * @param {Boolean} visible true to set the specified control visible, false otherwise - * @return {fabric.Object} thisArg - * @chainable - */ - setControlVisible: function(controlKey, visible) { - if (!this._controlsVisibility) { - this._controlsVisibility = {}; - } - this._controlsVisibility[controlKey] = visible; - return this; - }, - - /** - * Sets the visibility state of object controls. - * @param {Object} [options] Options object - * @param {Boolean} [options.bl] true to enable the bottom-left control, false to disable it - * @param {Boolean} [options.br] true to enable the bottom-right control, false to disable it - * @param {Boolean} [options.mb] true to enable the middle-bottom control, false to disable it - * @param {Boolean} [options.ml] true to enable the middle-left control, false to disable it - * @param {Boolean} [options.mr] true to enable the middle-right control, false to disable it - * @param {Boolean} [options.mt] true to enable the middle-top control, false to disable it - * @param {Boolean} [options.tl] true to enable the top-left control, false to disable it - * @param {Boolean} [options.tr] true to enable the top-right control, false to disable it - * @param {Boolean} [options.mtr] true to enable the middle-top-rotate control, false to disable it - * @return {fabric.Object} thisArg - * @chainable - */ - setControlsVisibility: function(options) { - options || (options = { }); - - for (var p in options) { - this.setControlVisible(p, options[p]); - } - return this; - }, - - - /** - * This callback function is called every time _discardActiveObject or _setActiveObject - * try to to deselect this object. If the function returns true, the process is cancelled - * @param {Object} [options] options sent from the upper functions - * @param {Event} [options.e] event if the process is generated by an event - */ - onDeselect: function() { - // implemented by sub-classes, as needed. - }, - - - /** - * This callback function is called every time _discardActiveObject or _setActiveObject - * try to to select this object. If the function returns true, the process is cancelled - * @param {Object} [options] options sent from the upper functions - * @param {Event} [options.e] event if the process is generated by an event - */ - onSelect: function() { - // implemented by sub-classes, as needed. - } - }); -})(); - - -fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { - - /** - * Animation duration (in ms) for fx* methods - * @type Number - * @default - */ - FX_DURATION: 500, - - /** - * Centers object horizontally with animation. - * @param {fabric.Object} object Object to center - * @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties - * @param {Function} [callbacks.onComplete] Invoked on completion - * @param {Function} [callbacks.onChange] Invoked on every step of animation - * @return {fabric.AnimationContext} context - */ - fxCenterObjectH: function (object, callbacks) { - callbacks = callbacks || { }; - - var empty = function() { }, - onComplete = callbacks.onComplete || empty, - onChange = callbacks.onChange || empty, - _this = this; - - return fabric.util.animate({ - target: this, - startValue: object.left, - endValue: this.getCenterPoint().x, - duration: this.FX_DURATION, - onChange: function(value) { - object.set('left', value); - _this.requestRenderAll(); - onChange(); - }, - onComplete: function() { - object.setCoords(); - onComplete(); - } - }); - }, - - /** - * Centers object vertically with animation. - * @param {fabric.Object} object Object to center - * @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties - * @param {Function} [callbacks.onComplete] Invoked on completion - * @param {Function} [callbacks.onChange] Invoked on every step of animation - * @return {fabric.AnimationContext} context - */ - fxCenterObjectV: function (object, callbacks) { - callbacks = callbacks || { }; - - var empty = function() { }, - onComplete = callbacks.onComplete || empty, - onChange = callbacks.onChange || empty, - _this = this; - - return fabric.util.animate({ - target: this, - startValue: object.top, - endValue: this.getCenterPoint().y, - duration: this.FX_DURATION, - onChange: function(value) { - object.set('top', value); - _this.requestRenderAll(); - onChange(); - }, - onComplete: function() { - object.setCoords(); - onComplete(); - } - }); - }, - - /** - * Same as `fabric.Canvas#remove` but animated - * @param {fabric.Object} object Object to remove - * @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties - * @param {Function} [callbacks.onComplete] Invoked on completion - * @param {Function} [callbacks.onChange] Invoked on every step of animation - * @return {fabric.AnimationContext} context - */ - fxRemove: function (object, callbacks) { - callbacks = callbacks || { }; - - var empty = function() { }, - onComplete = callbacks.onComplete || empty, - onChange = callbacks.onChange || empty, - _this = this; - - return fabric.util.animate({ - target: this, - startValue: object.opacity, - endValue: 0, - duration: this.FX_DURATION, - onChange: function(value) { - object.set('opacity', value); - _this.requestRenderAll(); - onChange(); - }, - onComplete: function () { - _this.remove(object); - onComplete(); - } - }); - } -}); - -fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - /** - * Animates object's properties - * @param {String|Object} property Property to animate (if string) or properties to animate (if object) - * @param {Number|Object} value Value to animate property to (if string was given first) or options object - * @return {fabric.Object} thisArg - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation} - * @return {fabric.AnimationContext | fabric.AnimationContext[]} animation context (or an array if passed multiple properties) - * - * As object — multiple properties - * - * object.animate({ left: ..., top: ... }); - * object.animate({ left: ..., top: ... }, { duration: ... }); - * - * As string — one property - * - * object.animate('left', ...); - * object.animate('left', { duration: ... }); - * - */ - animate: function () { - if (arguments[0] && typeof arguments[0] === 'object') { - var propsToAnimate = [], prop, skipCallbacks, out = []; - for (prop in arguments[0]) { - propsToAnimate.push(prop); - } - for (var i = 0, len = propsToAnimate.length; i < len; i++) { - prop = propsToAnimate[i]; - skipCallbacks = i !== len - 1; - out.push(this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks)); - } - return out; - } - else { - return this._animate.apply(this, arguments); - } - }, - - /** - * @private - * @param {String} property Property to animate - * @param {String} to Value to animate to - * @param {Object} [options] Options object - * @param {Boolean} [skipCallbacks] When true, callbacks like onchange and oncomplete are not invoked - */ - _animate: function(property, to, options, skipCallbacks) { - var _this = this, propPair; - - to = to.toString(); - - if (!options) { - options = { }; - } - else { - options = fabric.util.object.clone(options); - } - - if (~property.indexOf('.')) { - propPair = property.split('.'); - } - - var propIsColor = - _this.colorProperties.indexOf(property) > -1 || - (propPair && _this.colorProperties.indexOf(propPair[1]) > -1); - - var currentValue = propPair - ? this.get(propPair[0])[propPair[1]] - : this.get(property); - - if (!('from' in options)) { - options.from = currentValue; - } - - if (!propIsColor) { - if (~to.indexOf('=')) { - to = currentValue + parseFloat(to.replace('=', '')); - } - else { - to = parseFloat(to); - } - } - - var _options = { - target: this, - startValue: options.from, - endValue: to, - byValue: options.by, - easing: options.easing, - duration: options.duration, - abort: options.abort && function(value, valueProgress, timeProgress) { - return options.abort.call(_this, value, valueProgress, timeProgress); - }, - onChange: function (value, valueProgress, timeProgress) { - if (propPair) { - _this[propPair[0]][propPair[1]] = value; - } - else { - _this.set(property, value); - } - if (skipCallbacks) { - return; - } - options.onChange && options.onChange(value, valueProgress, timeProgress); - }, - onComplete: function (value, valueProgress, timeProgress) { - if (skipCallbacks) { - return; - } - - _this.setCoords(); - options.onComplete && options.onComplete(value, valueProgress, timeProgress); - } - }; - - if (propIsColor) { - return fabric.util.animateColor(_options.startValue, _options.endValue, _options.duration, _options); - } - else { - return fabric.util.animate(_options); - } - } -}); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - clone = fabric.util.object.clone, - coordProps = { x1: 1, x2: 1, y1: 1, y2: 1 }; - - if (fabric.Line) { - fabric.warn('fabric.Line is already defined'); - return; - } - - /** - * Line class - * @class fabric.Line - * @extends fabric.Object - * @see {@link fabric.Line#initialize} for constructor definition - */ - fabric.Line = fabric.util.createClass(fabric.Object, /** @lends fabric.Line.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'line', - - /** - * x value or first line edge - * @type Number - * @default - */ - x1: 0, - - /** - * y value or first line edge - * @type Number - * @default - */ - y1: 0, - - /** - * x value or second line edge - * @type Number - * @default - */ - x2: 0, - - /** - * y value or second line edge - * @type Number - * @default - */ - y2: 0, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('x1', 'x2', 'y1', 'y2'), - - /** - * Constructor - * @param {Array} [points] Array of points - * @param {Object} [options] Options object - * @return {fabric.Line} thisArg - */ - initialize: function(points, options) { - if (!points) { - points = [0, 0, 0, 0]; - } - - this.callSuper('initialize', options); - - this.set('x1', points[0]); - this.set('y1', points[1]); - this.set('x2', points[2]); - this.set('y2', points[3]); - - this._setWidthHeight(options); - }, - - /** - * @private - * @param {Object} [options] Options - */ - _setWidthHeight: function(options) { - options || (options = { }); - - this.width = Math.abs(this.x2 - this.x1); - this.height = Math.abs(this.y2 - this.y1); - - this.left = 'left' in options - ? options.left - : this._getLeftToOriginX(); - - this.top = 'top' in options - ? options.top - : this._getTopToOriginY(); - }, - - /** - * @private - * @param {String} key - * @param {*} value - */ - _set: function(key, value) { - this.callSuper('_set', key, value); - if (typeof coordProps[key] !== 'undefined') { - this._setWidthHeight(); - } - return this; - }, - - /** - * @private - * @return {Number} leftToOriginX Distance from left edge of canvas to originX of Line. - */ - _getLeftToOriginX: makeEdgeToOriginGetter( - { // property names - origin: 'originX', - axis1: 'x1', - axis2: 'x2', - dimension: 'width' - }, - { // possible values of origin - nearest: 'left', - center: 'center', - farthest: 'right' - } - ), - - /** - * @private - * @return {Number} topToOriginY Distance from top edge of canvas to originY of Line. - */ - _getTopToOriginY: makeEdgeToOriginGetter( - { // property names - origin: 'originY', - axis1: 'y1', - axis2: 'y2', - dimension: 'height' - }, - { // possible values of origin - nearest: 'top', - center: 'center', - farthest: 'bottom' - } - ), - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - ctx.beginPath(); - - - var p = this.calcLinePoints(); - ctx.moveTo(p.x1, p.y1); - ctx.lineTo(p.x2, p.y2); - - ctx.lineWidth = this.strokeWidth; - - // TODO: test this - // make sure setting "fill" changes color of a line - // (by copying fillStyle to strokeStyle, since line is stroked, not filled) - var origStrokeStyle = ctx.strokeStyle; - ctx.strokeStyle = this.stroke || ctx.fillStyle; - this.stroke && this._renderStroke(ctx); - ctx.strokeStyle = origStrokeStyle; - }, - - /** - * This function is an helper for svg import. it returns the center of the object in the svg - * untransformed coordinates - * @private - * @return {Object} center point from element coordinates - */ - _findCenterFromElement: function() { - return { - x: (this.x1 + this.x2) / 2, - y: (this.y1 + this.y2) / 2, - }; - }, - - /** - * Returns object representation of an instance - * @method toObject - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return extend(this.callSuper('toObject', propertiesToInclude), this.calcLinePoints()); - }, - - /* - * Calculate object dimensions from its properties - * @private - */ - _getNonTransformedDimensions: function() { - var dim = this.callSuper('_getNonTransformedDimensions'); - if (this.strokeLineCap === 'butt') { - if (this.width === 0) { - dim.y -= this.strokeWidth; - } - if (this.height === 0) { - dim.x -= this.strokeWidth; - } - } - return dim; - }, - - /** - * Recalculates line points given width and height - * @private - */ - calcLinePoints: function() { - var xMult = this.x1 <= this.x2 ? -1 : 1, - yMult = this.y1 <= this.y2 ? -1 : 1, - x1 = (xMult * this.width * 0.5), - y1 = (yMult * this.height * 0.5), - x2 = (xMult * this.width * -0.5), - y2 = (yMult * this.height * -0.5); - - return { - x1: x1, - x2: x2, - y1: y1, - y2: y2 - }; - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var p = this.calcLinePoints(); - return [ - '\n' - ]; - }, - /* _TO_SVG_END_ */ - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Line.fromElement}) - * @static - * @memberOf fabric.Line - * @see http://www.w3.org/TR/SVG/shapes.html#LineElement - */ - fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x1 y1 x2 y2'.split(' ')); - - /** - * Returns fabric.Line instance from an SVG element - * @static - * @memberOf fabric.Line - * @param {SVGElement} element Element to parse - * @param {Object} [options] Options object - * @param {Function} [callback] callback function invoked after parsing - */ - fabric.Line.fromElement = function(element, callback, options) { - options = options || { }; - var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES), - points = [ - parsedAttributes.x1 || 0, - parsedAttributes.y1 || 0, - parsedAttributes.x2 || 0, - parsedAttributes.y2 || 0 - ]; - callback(new fabric.Line(points, extend(parsedAttributes, options))); - }; - /* _FROM_SVG_END_ */ - - /** - * Returns fabric.Line instance from an object representation - * @static - * @memberOf fabric.Line - * @param {Object} object Object to create an instance from - * @param {function} [callback] invoked with new instance as first argument - */ - fabric.Line.fromObject = function(object, callback) { - function _callback(instance) { - delete instance.points; - callback && callback(instance); - }; - var options = clone(object, true); - options.points = [object.x1, object.y1, object.x2, object.y2]; - fabric.Object._fromObject('Line', options, _callback, 'points'); - }; - - /** - * Produces a function that calculates distance from canvas edge to Line origin. - */ - function makeEdgeToOriginGetter(propertyNames, originValues) { - var origin = propertyNames.origin, - axis1 = propertyNames.axis1, - axis2 = propertyNames.axis2, - dimension = propertyNames.dimension, - nearest = originValues.nearest, - center = originValues.center, - farthest = originValues.farthest; - - return function() { - switch (this.get(origin)) { - case nearest: - return Math.min(this.get(axis1), this.get(axis2)); - case center: - return Math.min(this.get(axis1), this.get(axis2)) + (0.5 * this.get(dimension)); - case farthest: - return Math.max(this.get(axis1), this.get(axis2)); - } - }; - - } - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - degreesToRadians = fabric.util.degreesToRadians; - - if (fabric.Circle) { - fabric.warn('fabric.Circle is already defined.'); - return; - } - - /** - * Circle class - * @class fabric.Circle - * @extends fabric.Object - * @see {@link fabric.Circle#initialize} for constructor definition - */ - fabric.Circle = fabric.util.createClass(fabric.Object, /** @lends fabric.Circle.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'circle', - - /** - * Radius of this circle - * @type Number - * @default - */ - radius: 0, - - /** - * degrees of start of the circle. - * probably will change to degrees in next major version - * @type Number 0 - 359 - * @default 0 - */ - startAngle: 0, - - /** - * End angle of the circle - * probably will change to degrees in next major version - * @type Number 1 - 360 - * @default 360 - */ - endAngle: 360, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('radius', 'startAngle', 'endAngle'), - - /** - * @private - * @param {String} key - * @param {*} value - * @return {fabric.Circle} thisArg - */ - _set: function(key, value) { - this.callSuper('_set', key, value); - - if (key === 'radius') { - this.setRadius(value); - } - - return this; - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return this.callSuper('toObject', ['radius', 'startAngle', 'endAngle'].concat(propertiesToInclude)); - }, - - /* _TO_SVG_START_ */ - - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var svgString, x = 0, y = 0, - angle = (this.endAngle - this.startAngle) % 360; - - if (angle === 0) { - svgString = [ - '\n' - ]; - } - else { - var start = degreesToRadians(this.startAngle), - end = degreesToRadians(this.endAngle), - radius = this.radius, - startX = fabric.util.cos(start) * radius, - startY = fabric.util.sin(start) * radius, - endX = fabric.util.cos(end) * radius, - endY = fabric.util.sin(end) * radius, - largeFlag = angle > 180 ? '1' : '0'; - svgString = [ - '\n' - ]; - } - return svgString; - }, - /* _TO_SVG_END_ */ - - /** - * @private - * @param {CanvasRenderingContext2D} ctx context to render on - */ - _render: function(ctx) { - ctx.beginPath(); - ctx.arc( - 0, - 0, - this.radius, - degreesToRadians(this.startAngle), - degreesToRadians(this.endAngle), - false - ); - this._renderPaintInOrder(ctx); - }, - - /** - * Returns horizontal radius of an object (according to how an object is scaled) - * @return {Number} - */ - getRadiusX: function() { - return this.get('radius') * this.get('scaleX'); - }, - - /** - * Returns vertical radius of an object (according to how an object is scaled) - * @return {Number} - */ - getRadiusY: function() { - return this.get('radius') * this.get('scaleY'); - }, - - /** - * Sets radius of an object (and updates width accordingly) - * @return {fabric.Circle} thisArg - */ - setRadius: function(value) { - this.radius = value; - return this.set('width', value * 2).set('height', value * 2); - }, - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement}) - * @static - * @memberOf fabric.Circle - * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement - */ - fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy r'.split(' ')); - - /** - * Returns {@link fabric.Circle} instance from an SVG element - * @static - * @memberOf fabric.Circle - * @param {SVGElement} element Element to parse - * @param {Function} [callback] Options callback invoked after parsing is finished - * @param {Object} [options] Options object - * @throws {Error} If value of `r` attribute is missing or invalid - */ - fabric.Circle.fromElement = function(element, callback) { - var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES); - - if (!isValidRadius(parsedAttributes)) { - throw new Error('value of `r` attribute is required and can not be negative'); - } - - parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.radius; - parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.radius; - callback(new fabric.Circle(parsedAttributes)); - }; - - /** - * @private - */ - function isValidRadius(attributes) { - return (('radius' in attributes) && (attributes.radius >= 0)); - } - /* _FROM_SVG_END_ */ - - /** - * Returns {@link fabric.Circle} instance from an object representation - * @static - * @memberOf fabric.Circle - * @param {Object} object Object to create an instance from - * @param {function} [callback] invoked with new instance as first argument - * @return {void} - */ - fabric.Circle.fromObject = function(object, callback) { - fabric.Object._fromObject('Circle', object, callback); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }); - - if (fabric.Triangle) { - fabric.warn('fabric.Triangle is already defined'); - return; - } - - /** - * Triangle class - * @class fabric.Triangle - * @extends fabric.Object - * @return {fabric.Triangle} thisArg - * @see {@link fabric.Triangle#initialize} for constructor definition - */ - fabric.Triangle = fabric.util.createClass(fabric.Object, /** @lends fabric.Triangle.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'triangle', - - /** - * Width is set to 100 to compensate the old initialize code that was setting it to 100 - * @type Number - * @default - */ - width: 100, - - /** - * Height is set to 100 to compensate the old initialize code that was setting it to 100 - * @type Number - * @default - */ - height: 100, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - var widthBy2 = this.width / 2, - heightBy2 = this.height / 2; - - ctx.beginPath(); - ctx.moveTo(-widthBy2, heightBy2); - ctx.lineTo(0, -heightBy2); - ctx.lineTo(widthBy2, heightBy2); - ctx.closePath(); - - this._renderPaintInOrder(ctx); - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var widthBy2 = this.width / 2, - heightBy2 = this.height / 2, - points = [ - -widthBy2 + ' ' + heightBy2, - '0 ' + -heightBy2, - widthBy2 + ' ' + heightBy2 - ].join(','); - return [ - '' - ]; - }, - /* _TO_SVG_END_ */ - }); - - /** - * Returns {@link fabric.Triangle} instance from an object representation - * @static - * @memberOf fabric.Triangle - * @param {Object} object Object to create an instance from - * @param {function} [callback] invoked with new instance as first argument - */ - fabric.Triangle.fromObject = function(object, callback) { - return fabric.Object._fromObject('Triangle', object, callback); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - piBy2 = Math.PI * 2; - - if (fabric.Ellipse) { - fabric.warn('fabric.Ellipse is already defined.'); - return; - } - - /** - * Ellipse class - * @class fabric.Ellipse - * @extends fabric.Object - * @return {fabric.Ellipse} thisArg - * @see {@link fabric.Ellipse#initialize} for constructor definition - */ - fabric.Ellipse = fabric.util.createClass(fabric.Object, /** @lends fabric.Ellipse.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'ellipse', - - /** - * Horizontal radius - * @type Number - * @default - */ - rx: 0, - - /** - * Vertical radius - * @type Number - * @default - */ - ry: 0, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'), - - /** - * Constructor - * @param {Object} [options] Options object - * @return {fabric.Ellipse} thisArg - */ - initialize: function(options) { - this.callSuper('initialize', options); - this.set('rx', options && options.rx || 0); - this.set('ry', options && options.ry || 0); - }, - - /** - * @private - * @param {String} key - * @param {*} value - * @return {fabric.Ellipse} thisArg - */ - _set: function(key, value) { - this.callSuper('_set', key, value); - switch (key) { - - case 'rx': - this.rx = value; - this.set('width', value * 2); - break; - - case 'ry': - this.ry = value; - this.set('height', value * 2); - break; - - } - return this; - }, - - /** - * Returns horizontal radius of an object (according to how an object is scaled) - * @return {Number} - */ - getRx: function() { - return this.get('rx') * this.get('scaleX'); - }, - - /** - * Returns Vertical radius of an object (according to how an object is scaled) - * @return {Number} - */ - getRy: function() { - return this.get('ry') * this.get('scaleY'); - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude)); - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - return [ - '\n' - ]; - }, - /* _TO_SVG_END_ */ - - /** - * @private - * @param {CanvasRenderingContext2D} ctx context to render on - */ - _render: function(ctx) { - ctx.beginPath(); - ctx.save(); - ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0); - ctx.arc( - 0, - 0, - this.rx, - 0, - piBy2, - false); - ctx.restore(); - this._renderPaintInOrder(ctx); - }, - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Ellipse.fromElement}) - * @static - * @memberOf fabric.Ellipse - * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement - */ - fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy rx ry'.split(' ')); - - /** - * Returns {@link fabric.Ellipse} instance from an SVG element - * @static - * @memberOf fabric.Ellipse - * @param {SVGElement} element Element to parse - * @param {Function} [callback] Options callback invoked after parsing is finished - * @return {fabric.Ellipse} - */ - fabric.Ellipse.fromElement = function(element, callback) { - - var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES); - - parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx; - parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry; - callback(new fabric.Ellipse(parsedAttributes)); - }; - /* _FROM_SVG_END_ */ - - /** - * Returns {@link fabric.Ellipse} instance from an object representation - * @static - * @memberOf fabric.Ellipse - * @param {Object} object Object to create an instance from - * @param {function} [callback] invoked with new instance as first argument - * @return {void} - */ - fabric.Ellipse.fromObject = function(object, callback) { - fabric.Object._fromObject('Ellipse', object, callback); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend; - - if (fabric.Rect) { - fabric.warn('fabric.Rect is already defined'); - return; - } - - /** - * Rectangle class - * @class fabric.Rect - * @extends fabric.Object - * @return {fabric.Rect} thisArg - * @see {@link fabric.Rect#initialize} for constructor definition - */ - fabric.Rect = fabric.util.createClass(fabric.Object, /** @lends fabric.Rect.prototype */ { - - /** - * List of properties to consider when checking if state of an object is changed ({@link fabric.Object#hasStateChanged}) - * as well as for history (undo/redo) purposes - * @type Array - */ - stateProperties: fabric.Object.prototype.stateProperties.concat('rx', 'ry'), - - /** - * Type of an object - * @type String - * @default - */ - type: 'rect', - - /** - * Horizontal border radius - * @type Number - * @default - */ - rx: 0, - - /** - * Vertical border radius - * @type Number - * @default - */ - ry: 0, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'), - - /** - * Constructor - * @param {Object} [options] Options object - * @return {Object} thisArg - */ - initialize: function(options) { - this.callSuper('initialize', options); - this._initRxRy(); - }, - - /** - * Initializes rx/ry attributes - * @private - */ - _initRxRy: function() { - if (this.rx && !this.ry) { - this.ry = this.rx; - } - else if (this.ry && !this.rx) { - this.rx = this.ry; - } - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - - // 1x1 case (used in spray brush) optimization was removed because - // with caching and higher zoom level this makes more damage than help - - var rx = this.rx ? Math.min(this.rx, this.width / 2) : 0, - ry = this.ry ? Math.min(this.ry, this.height / 2) : 0, - w = this.width, - h = this.height, - x = -this.width / 2, - y = -this.height / 2, - isRounded = rx !== 0 || ry !== 0, - /* "magic number" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */ - k = 1 - 0.5522847498; - ctx.beginPath(); - - ctx.moveTo(x + rx, y); - - ctx.lineTo(x + w - rx, y); - isRounded && ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry); - - ctx.lineTo(x + w, y + h - ry); - isRounded && ctx.bezierCurveTo(x + w, y + h - k * ry, x + w - k * rx, y + h, x + w - rx, y + h); - - ctx.lineTo(x + rx, y + h); - isRounded && ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry); - - ctx.lineTo(x, y + ry); - isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y); - - ctx.closePath(); - - this._renderPaintInOrder(ctx); - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude)); - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var x = -this.width / 2, y = -this.height / 2; - return [ - '\n' - ]; - }, - /* _TO_SVG_END_ */ - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by `fabric.Rect.fromElement`) - * @static - * @memberOf fabric.Rect - * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement - */ - fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y rx ry width height'.split(' ')); - - /** - * Returns {@link fabric.Rect} instance from an SVG element - * @static - * @memberOf fabric.Rect - * @param {SVGElement} element Element to parse - * @param {Function} callback callback function invoked after parsing - * @param {Object} [options] Options object - */ - fabric.Rect.fromElement = function(element, callback, options) { - if (!element) { - return callback(null); - } - options = options || { }; - - var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES); - parsedAttributes.left = parsedAttributes.left || 0; - parsedAttributes.top = parsedAttributes.top || 0; - parsedAttributes.height = parsedAttributes.height || 0; - parsedAttributes.width = parsedAttributes.width || 0; - var rect = new fabric.Rect(extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes)); - rect.visible = rect.visible && rect.width > 0 && rect.height > 0; - callback(rect); - }; - /* _FROM_SVG_END_ */ - - /** - * Returns {@link fabric.Rect} instance from an object representation - * @static - * @memberOf fabric.Rect - * @param {Object} object Object to create an instance from - * @param {Function} [callback] Callback to invoke when an fabric.Rect instance is created - */ - fabric.Rect.fromObject = function(object, callback) { - return fabric.Object._fromObject('Rect', object, callback); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - min = fabric.util.array.min, - max = fabric.util.array.max, - toFixed = fabric.util.toFixed, - projectStrokeOnPoints = fabric.util.projectStrokeOnPoints; - - if (fabric.Polyline) { - fabric.warn('fabric.Polyline is already defined'); - return; - } - - /** - * Polyline class - * @class fabric.Polyline - * @extends fabric.Object - * @see {@link fabric.Polyline#initialize} for constructor definition - */ - fabric.Polyline = fabric.util.createClass(fabric.Object, /** @lends fabric.Polyline.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'polyline', - - /** - * Points array - * @type Array - * @default - */ - points: null, - - /** - * WARNING: Feature in progress - * Calculate the exact bounding box taking in account strokeWidth on acute angles - * this will be turned to true by default on fabric 6.0 - * maybe will be left in as an optimization since calculations may be slow - * @deprecated - * @type Boolean - * @default false - */ - exactBoundingBox: false, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('points'), - - /** - * Constructor - * @param {Array} points Array of points (where each point is an object with x and y) - * @param {Object} [options] Options object - * @return {fabric.Polyline} thisArg - * @example - * var poly = new fabric.Polyline([ - * { x: 10, y: 10 }, - * { x: 50, y: 30 }, - * { x: 40, y: 70 }, - * { x: 60, y: 50 }, - * { x: 100, y: 150 }, - * { x: 40, y: 100 } - * ], { - * stroke: 'red', - * left: 100, - * top: 100 - * }); - */ - initialize: function(points, options) { - options = options || {}; - this.points = points || []; - this.callSuper('initialize', options); - this._setPositionDimensions(options); - }, - - /** - * @private - */ - _projectStrokeOnPoints: function () { - return projectStrokeOnPoints(this.points, this, true); - }, - - _setPositionDimensions: function(options) { - var calcDim = this._calcDimensions(options), correctLeftTop, - correctSize = this.exactBoundingBox ? this.strokeWidth : 0; - this.width = calcDim.width - correctSize; - this.height = calcDim.height - correctSize; - if (!options.fromSVG) { - correctLeftTop = this.translateToGivenOrigin( - { - // this looks bad, but is one way to keep it optional for now. - x: calcDim.left - this.strokeWidth / 2 + correctSize / 2, - y: calcDim.top - this.strokeWidth / 2 + correctSize / 2 - }, - 'left', - 'top', - this.originX, - this.originY - ); - } - if (typeof options.left === 'undefined') { - this.left = options.fromSVG ? calcDim.left : correctLeftTop.x; - } - if (typeof options.top === 'undefined') { - this.top = options.fromSVG ? calcDim.top : correctLeftTop.y; - } - this.pathOffset = { - x: calcDim.left + this.width / 2 + correctSize / 2, - y: calcDim.top + this.height / 2 + correctSize / 2 - }; - }, - - /** - * Calculate the polygon min and max point from points array, - * returning an object with left, top, width, height to measure the - * polygon size - * @return {Object} object.left X coordinate of the polygon leftmost point - * @return {Object} object.top Y coordinate of the polygon topmost point - * @return {Object} object.width distance between X coordinates of the polygon leftmost and rightmost point - * @return {Object} object.height distance between Y coordinates of the polygon topmost and bottommost point - * @private - */ - _calcDimensions: function() { - - var points = this.exactBoundingBox ? this._projectStrokeOnPoints() : this.points, - minX = min(points, 'x') || 0, - minY = min(points, 'y') || 0, - maxX = max(points, 'x') || 0, - maxY = max(points, 'y') || 0, - width = (maxX - minX), - height = (maxY - minY); - - return { - left: minX, - top: minY, - width: width, - height: height, - }; - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of an instance - */ - toObject: function(propertiesToInclude) { - return extend(this.callSuper('toObject', propertiesToInclude), { - points: this.points.concat() - }); - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var points = [], diffX = this.pathOffset.x, diffY = this.pathOffset.y, - NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - - for (var i = 0, len = this.points.length; i < len; i++) { - points.push( - toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS), ',', - toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), ' ' - ); - } - return [ - '<' + this.type + ' ', 'COMMON_PARTS', - 'points="', points.join(''), - '" />\n' - ]; - }, - /* _TO_SVG_END_ */ - - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - commonRender: function(ctx) { - var point, len = this.points.length, - x = this.pathOffset.x, - y = this.pathOffset.y; - - if (!len || isNaN(this.points[len - 1].y)) { - // do not draw if no points or odd points - // NaN comes from parseFloat of a empty string in parser - return false; - } - ctx.beginPath(); - ctx.moveTo(this.points[0].x - x, this.points[0].y - y); - for (var i = 0; i < len; i++) { - point = this.points[i]; - ctx.lineTo(point.x - x, point.y - y); - } - return true; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - if (!this.commonRender(ctx)) { - return; - } - this._renderPaintInOrder(ctx); - }, - - /** - * Returns complexity of an instance - * @return {Number} complexity of this instance - */ - complexity: function() { - return this.get('points').length; - } - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Polyline.fromElement}) - * @static - * @memberOf fabric.Polyline - * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement - */ - fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(); - - /** - * Returns fabric.Polyline instance from an SVG element - * @static - * @memberOf fabric.Polyline - * @param {SVGElement} element Element to parser - * @param {Function} callback callback function invoked after parsing - * @param {Object} [options] Options object - */ - fabric.Polyline.fromElementGenerator = function(_class) { - return function(element, callback, options) { - if (!element) { - return callback(null); - } - options || (options = { }); - - var points = fabric.parsePointsAttribute(element.getAttribute('points')), - parsedAttributes = fabric.parseAttributes(element, fabric[_class].ATTRIBUTE_NAMES); - parsedAttributes.fromSVG = true; - callback(new fabric[_class](points, extend(parsedAttributes, options))); - }; - }; - - fabric.Polyline.fromElement = fabric.Polyline.fromElementGenerator('Polyline'); - - /* _FROM_SVG_END_ */ - - /** - * Returns fabric.Polyline instance from an object representation - * @static - * @memberOf fabric.Polyline - * @param {Object} object Object to create an instance from - * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created - */ - fabric.Polyline.fromObject = function(object, callback) { - return fabric.Object._fromObject('Polyline', object, callback, 'points'); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = {}), - projectStrokeOnPoints = fabric.util.projectStrokeOnPoints; - - if (fabric.Polygon) { - fabric.warn('fabric.Polygon is already defined'); - return; - } - - /** - * Polygon class - * @class fabric.Polygon - * @extends fabric.Polyline - * @see {@link fabric.Polygon#initialize} for constructor definition - */ - fabric.Polygon = fabric.util.createClass(fabric.Polyline, /** @lends fabric.Polygon.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'polygon', - - /** - * @private - */ - _projectStrokeOnPoints: function () { - return projectStrokeOnPoints(this.points, this); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - if (!this.commonRender(ctx)) { - return; - } - ctx.closePath(); - this._renderPaintInOrder(ctx); - }, - - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by `fabric.Polygon.fromElement`) - * @static - * @memberOf fabric.Polygon - * @see: http://www.w3.org/TR/SVG/shapes.html#PolygonElement - */ - fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(); - - /** - * Returns {@link fabric.Polygon} instance from an SVG element - * @static - * @memberOf fabric.Polygon - * @param {SVGElement} element Element to parse - * @param {Function} callback callback function invoked after parsing - * @param {Object} [options] Options object - */ - fabric.Polygon.fromElement = fabric.Polyline.fromElementGenerator('Polygon'); - /* _FROM_SVG_END_ */ - - /** - * Returns fabric.Polygon instance from an object representation - * @static - * @memberOf fabric.Polygon - * @param {Object} object Object to create an instance from - * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created - * @return {void} - */ - fabric.Polygon.fromObject = function(object, callback) { - fabric.Object._fromObject('Polygon', object, callback, 'points'); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - min = fabric.util.array.min, - max = fabric.util.array.max, - extend = fabric.util.object.extend, - clone = fabric.util.object.clone, - toFixed = fabric.util.toFixed; - - if (fabric.Path) { - fabric.warn('fabric.Path is already defined'); - return; - } - - /** - * Path class - * @class fabric.Path - * @extends fabric.Object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup} - * @see {@link fabric.Path#initialize} for constructor definition - */ - fabric.Path = fabric.util.createClass(fabric.Object, /** @lends fabric.Path.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'path', - - /** - * Array of path points - * @type Array - * @default - */ - path: null, - - cacheProperties: fabric.Object.prototype.cacheProperties.concat('path', 'fillRule'), - - stateProperties: fabric.Object.prototype.stateProperties.concat('path'), - - /** - * Constructor - * @param {Array|String} path Path data (sequence of coordinates and corresponding "command" tokens) - * @param {Object} [options] Options object - * @return {fabric.Path} thisArg - */ - initialize: function (path, options) { - options = clone(options || {}); - delete options.path; - this.callSuper('initialize', options); - this._setPath(path || [], options); - }, - - /** - * @private - * @param {Array|String} path Path data (sequence of coordinates and corresponding "command" tokens) - * @param {Object} [options] Options object - */ - _setPath: function (path, options) { - this.path = fabric.util.makePathSimpler( - Array.isArray(path) ? path : fabric.util.parsePath(path) - ); - - fabric.Polyline.prototype._setPositionDimensions.call(this, options || {}); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx context to render path on - */ - _renderPathCommands: function(ctx) { - var current, // current instruction - subpathStartX = 0, - subpathStartY = 0, - x = 0, // current x - y = 0, // current y - controlX = 0, // current control point x - controlY = 0, // current control point y - l = -this.pathOffset.x, - t = -this.pathOffset.y; - - ctx.beginPath(); - - for (var i = 0, len = this.path.length; i < len; ++i) { - - current = this.path[i]; - - switch (current[0]) { // first letter - - case 'L': // lineto, absolute - x = current[1]; - y = current[2]; - ctx.lineTo(x + l, y + t); - break; - - case 'M': // moveTo, absolute - x = current[1]; - y = current[2]; - subpathStartX = x; - subpathStartY = y; - ctx.moveTo(x + l, y + t); - break; - - case 'C': // bezierCurveTo, absolute - x = current[5]; - y = current[6]; - controlX = current[3]; - controlY = current[4]; - ctx.bezierCurveTo( - current[1] + l, - current[2] + t, - controlX + l, - controlY + t, - x + l, - y + t - ); - break; - - case 'Q': // quadraticCurveTo, absolute - ctx.quadraticCurveTo( - current[1] + l, - current[2] + t, - current[3] + l, - current[4] + t - ); - x = current[3]; - y = current[4]; - controlX = current[1]; - controlY = current[2]; - break; - - case 'z': - case 'Z': - x = subpathStartX; - y = subpathStartY; - ctx.closePath(); - break; - } - } - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx context to render path on - */ - _render: function(ctx) { - this._renderPathCommands(ctx); - this._renderPaintInOrder(ctx); - }, - - /** - * Returns string representation of an instance - * @return {String} string representation of an instance - */ - toString: function() { - return '#'; - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return extend(this.callSuper('toObject', propertiesToInclude), { - path: this.path.map(function(item) { return item.slice(); }), - }); - }, - - /** - * Returns dataless object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toDatalessObject: function(propertiesToInclude) { - var o = this.toObject(['sourcePath'].concat(propertiesToInclude)); - if (o.sourcePath) { - delete o.path; - } - return o; - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var path = fabric.util.joinPath(this.path); - return [ - '\n' - ]; - }, - - _getOffsetTransform: function() { - var digits = fabric.Object.NUM_FRACTION_DIGITS; - return ' translate(' + toFixed(-this.pathOffset.x, digits) + ', ' + - toFixed(-this.pathOffset.y, digits) + ')'; - }, - - /** - * Returns svg clipPath representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toClipPathSVG: function(reviver) { - var additionalTransform = this._getOffsetTransform(); - return '\t' + this._createBaseClipPathSVGMarkup( - this._toSVG(), { reviver: reviver, additionalTransform: additionalTransform } - ); - }, - - /** - * Returns svg representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toSVG: function(reviver) { - var additionalTransform = this._getOffsetTransform(); - return this._createBaseSVGMarkup(this._toSVG(), { reviver: reviver, additionalTransform: additionalTransform }); - }, - /* _TO_SVG_END_ */ - - /** - * Returns number representation of an instance complexity - * @return {Number} complexity of this instance - */ - complexity: function() { - return this.path.length; - }, - - /** - * @private - */ - _calcDimensions: function() { - - var aX = [], - aY = [], - current, // current instruction - subpathStartX = 0, - subpathStartY = 0, - x = 0, // current x - y = 0, // current y - bounds; - - for (var i = 0, len = this.path.length; i < len; ++i) { - - current = this.path[i]; - - switch (current[0]) { // first letter - - case 'L': // lineto, absolute - x = current[1]; - y = current[2]; - bounds = []; - break; - - case 'M': // moveTo, absolute - x = current[1]; - y = current[2]; - subpathStartX = x; - subpathStartY = y; - bounds = []; - break; - - case 'C': // bezierCurveTo, absolute - bounds = fabric.util.getBoundsOfCurve(x, y, - current[1], - current[2], - current[3], - current[4], - current[5], - current[6] - ); - x = current[5]; - y = current[6]; - break; - - case 'Q': // quadraticCurveTo, absolute - bounds = fabric.util.getBoundsOfCurve(x, y, - current[1], - current[2], - current[1], - current[2], - current[3], - current[4] - ); - x = current[3]; - y = current[4]; - break; - - case 'z': - case 'Z': - x = subpathStartX; - y = subpathStartY; - break; - } - bounds.forEach(function (point) { - aX.push(point.x); - aY.push(point.y); - }); - aX.push(x); - aY.push(y); - } - - var minX = min(aX) || 0, - minY = min(aY) || 0, - maxX = max(aX) || 0, - maxY = max(aY) || 0, - deltaX = maxX - minX, - deltaY = maxY - minY; - - return { - left: minX, - top: minY, - width: deltaX, - height: deltaY - }; - } - }); - - /** - * Creates an instance of fabric.Path from an object - * @static - * @memberOf fabric.Path - * @param {Object} object - * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created - */ - fabric.Path.fromObject = function(object, callback) { - if (typeof object.sourcePath === 'string') { - var pathUrl = object.sourcePath; - fabric.loadSVGFromURL(pathUrl, function (elements) { - var path = elements[0]; - path.setOptions(object); - callback && callback(path); - }); - } - else { - fabric.Object._fromObject('Path', object, callback, 'path'); - } - }; - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by `fabric.Path.fromElement`) - * @static - * @memberOf fabric.Path - * @see http://www.w3.org/TR/SVG/paths.html#PathElement - */ - fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(['d']); - - /** - * Creates an instance of fabric.Path from an SVG element - * @static - * @memberOf fabric.Path - * @param {SVGElement} element to parse - * @param {Function} callback Callback to invoke when an fabric.Path instance is created - * @param {Object} [options] Options object - * @param {Function} [callback] Options callback invoked after parsing is finished - */ - fabric.Path.fromElement = function(element, callback, options) { - var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES); - parsedAttributes.fromSVG = true; - callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options))); - }; - /* _FROM_SVG_END_ */ - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - min = fabric.util.array.min, - max = fabric.util.array.max; - - if (fabric.Group) { - return; - } - - /** - * Group class - * @class fabric.Group - * @extends fabric.Object - * @mixes fabric.Collection - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups} - * @see {@link fabric.Group#initialize} for constructor definition - */ - fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection, /** @lends fabric.Group.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'group', - - /** - * Width of stroke - * @type Number - * @default - */ - strokeWidth: 0, - - /** - * Indicates if click, mouseover, mouseout events & hoverCursor should also check for subtargets - * @type Boolean - * @default - */ - subTargetCheck: false, - - /** - * Groups are container, do not render anything on theyr own, ence no cache properties - * @type Array - * @default - */ - cacheProperties: [], - - /** - * setOnGroup is a method used for TextBox that is no more used since 2.0.0 The behavior is still - * available setting this boolean to true. - * @type Boolean - * @since 2.0.0 - * @default - */ - useSetOnGroup: false, - - /** - * Constructor - * @param {Object} objects Group objects - * @param {Object} [options] Options object - * @param {Boolean} [isAlreadyGrouped] if true, objects have been grouped already. - * @return {Object} thisArg - */ - initialize: function(objects, options, isAlreadyGrouped) { - options = options || {}; - this._objects = []; - // if objects enclosed in a group have been grouped already, - // we cannot change properties of objects. - // Thus we need to set options to group without objects, - isAlreadyGrouped && this.callSuper('initialize', options); - this._objects = objects || []; - for (var i = this._objects.length; i--; ) { - this._objects[i].group = this; - } - - if (!isAlreadyGrouped) { - var center = options && options.centerPoint; - // we want to set origins before calculating the bounding box. - // so that the topleft can be set with that in mind. - // if specific top and left are passed, are overwritten later - // with the callSuper('initialize', options) - if (options.originX !== undefined) { - this.originX = options.originX; - } - if (options.originY !== undefined) { - this.originY = options.originY; - } - // if coming from svg i do not want to calc bounds. - // i assume width and height are passed along options - center || this._calcBounds(); - this._updateObjectsCoords(center); - delete options.centerPoint; - this.callSuper('initialize', options); - } - else { - this._updateObjectsACoords(); - } - - this.setCoords(); - }, - - /** - * @private - */ - _updateObjectsACoords: function() { - var skipControls = true; - for (var i = this._objects.length; i--; ){ - this._objects[i].setCoords(skipControls); - } - }, - - /** - * @private - * @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change - */ - _updateObjectsCoords: function(center) { - var center = center || this.getCenterPoint(); - for (var i = this._objects.length; i--; ){ - this._updateObjectCoords(this._objects[i], center); - } - }, - - /** - * @private - * @param {Object} object - * @param {fabric.Point} center, current center of group. - */ - _updateObjectCoords: function(object, center) { - var objectLeft = object.left, - objectTop = object.top, - skipControls = true; - - object.set({ - left: objectLeft - center.x, - top: objectTop - center.y - }); - object.group = this; - object.setCoords(skipControls); - }, - - /** - * Returns string represenation of a group - * @return {String} - */ - toString: function() { - return '#'; - }, - - /** - * Adds an object to a group; Then recalculates group's dimension, position. - * @param {Object} object - * @return {fabric.Group} thisArg - * @chainable - */ - addWithUpdate: function(object) { - var nested = !!this.group; - this._restoreObjectsState(); - fabric.util.resetObjectTransform(this); - if (object) { - if (nested) { - // if this group is inside another group, we need to pre transform the object - fabric.util.removeTransformFromObject(object, this.group.calcTransformMatrix()); - } - this._objects.push(object); - object.group = this; - object._set('canvas', this.canvas); - } - this._calcBounds(); - this._updateObjectsCoords(); - this.dirty = true; - if (nested) { - this.group.addWithUpdate(); - } - else { - this.setCoords(); - } - return this; - }, - - /** - * Removes an object from a group; Then recalculates group's dimension, position. - * @param {Object} object - * @return {fabric.Group} thisArg - * @chainable - */ - removeWithUpdate: function(object) { - this._restoreObjectsState(); - fabric.util.resetObjectTransform(this); - - this.remove(object); - this._calcBounds(); - this._updateObjectsCoords(); - this.setCoords(); - this.dirty = true; - return this; - }, - - /** - * @private - */ - _onObjectAdded: function(object) { - this.dirty = true; - object.group = this; - object._set('canvas', this.canvas); - }, - - /** - * @private - */ - _onObjectRemoved: function(object) { - this.dirty = true; - delete object.group; - }, - - /** - * @private - */ - _set: function(key, value) { - var i = this._objects.length; - if (this.useSetOnGroup) { - while (i--) { - this._objects[i].setOnGroup(key, value); - } - } - if (key === 'canvas') { - while (i--) { - this._objects[i]._set(key, value); - } - } - fabric.Object.prototype._set.call(this, key, value); - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - var _includeDefaultValues = this.includeDefaultValues; - var objsToObject = this._objects - .filter(function (obj) { - return !obj.excludeFromExport; - }) - .map(function (obj) { - var originalDefaults = obj.includeDefaultValues; - obj.includeDefaultValues = _includeDefaultValues; - var _obj = obj.toObject(propertiesToInclude); - obj.includeDefaultValues = originalDefaults; - return _obj; - }); - var obj = fabric.Object.prototype.toObject.call(this, propertiesToInclude); - obj.objects = objsToObject; - return obj; - }, - - /** - * Returns object representation of an instance, in dataless mode. - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toDatalessObject: function(propertiesToInclude) { - var objsToObject, sourcePath = this.sourcePath; - if (sourcePath) { - objsToObject = sourcePath; - } - else { - var _includeDefaultValues = this.includeDefaultValues; - objsToObject = this._objects.map(function(obj) { - var originalDefaults = obj.includeDefaultValues; - obj.includeDefaultValues = _includeDefaultValues; - var _obj = obj.toDatalessObject(propertiesToInclude); - obj.includeDefaultValues = originalDefaults; - return _obj; - }); - } - var obj = fabric.Object.prototype.toDatalessObject.call(this, propertiesToInclude); - obj.objects = objsToObject; - return obj; - }, - - /** - * Renders instance on a given context - * @param {CanvasRenderingContext2D} ctx context to render instance on - */ - render: function(ctx) { - this._transformDone = true; - this.callSuper('render', ctx); - this._transformDone = false; - }, - - /** - * Decide if the object should cache or not. Create its own cache level - * needsItsOwnCache should be used when the object drawing method requires - * a cache step. None of the fabric classes requires it. - * Generally you do not cache objects in groups because the group is already cached. - * @return {Boolean} - */ - shouldCache: function() { - var ownCache = fabric.Object.prototype.shouldCache.call(this); - if (ownCache) { - for (var i = 0, len = this._objects.length; i < len; i++) { - if (this._objects[i].willDrawShadow()) { - this.ownCaching = false; - return false; - } - } - } - return ownCache; - }, - - /** - * Check if this object or a child object will cast a shadow - * @return {Boolean} - */ - willDrawShadow: function() { - if (fabric.Object.prototype.willDrawShadow.call(this)) { - return true; - } - for (var i = 0, len = this._objects.length; i < len; i++) { - if (this._objects[i].willDrawShadow()) { - return true; - } - } - return false; - }, - - /** - * Check if this group or its parent group are caching, recursively up - * @return {Boolean} - */ - isOnACache: function() { - return this.ownCaching || (this.group && this.group.isOnACache()); - }, - - /** - * Execute the drawing operation for an object on a specified context - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - drawObject: function(ctx) { - for (var i = 0, len = this._objects.length; i < len; i++) { - this._objects[i].render(ctx); - } - this._drawClipPath(ctx, this.clipPath); - }, - - /** - * Check if cache is dirty - */ - isCacheDirty: function(skipCanvas) { - if (this.callSuper('isCacheDirty', skipCanvas)) { - return true; - } - if (!this.statefullCache) { - return false; - } - for (var i = 0, len = this._objects.length; i < len; i++) { - if (this._objects[i].isCacheDirty(true)) { - if (this._cacheCanvas) { - // if this group has not a cache canvas there is nothing to clean - var x = this.cacheWidth / this.zoomX, y = this.cacheHeight / this.zoomY; - this._cacheContext.clearRect(-x / 2, -y / 2, x, y); - } - return true; - } - } - return false; - }, - - /** - * Restores original state of each of group objects (original state is that which was before group was created). - * if the nested boolean is true, the original state will be restored just for the - * first group and not for all the group chain - * @private - * @param {Boolean} nested tell the function to restore object state up to the parent group and not more - * @return {fabric.Group} thisArg - * @chainable - */ - _restoreObjectsState: function() { - var groupMatrix = this.calcOwnMatrix(); - this._objects.forEach(function(object) { - // instead of using _this = this; - fabric.util.addTransformToObject(object, groupMatrix); - delete object.group; - object.setCoords(); - }); - return this; - }, - - /** - * Destroys a group (restoring state of its objects) - * @return {fabric.Group} thisArg - * @chainable - */ - destroy: function() { - // when group is destroyed objects needs to get a repaint to be eventually - // displayed on canvas. - this._objects.forEach(function(object) { - object.set('dirty', true); - }); - return this._restoreObjectsState(); - }, - - dispose: function () { - this.callSuper('dispose'); - this.forEachObject(function (object) { - object.dispose && object.dispose(); - }); - this._objects = []; - }, - - /** - * make a group an active selection, remove the group from canvas - * the group has to be on canvas for this to work. - * @return {fabric.ActiveSelection} thisArg - * @chainable - */ - toActiveSelection: function() { - if (!this.canvas) { - return; - } - var objects = this._objects, canvas = this.canvas; - this._objects = []; - var options = this.toObject(); - delete options.objects; - var activeSelection = new fabric.ActiveSelection([]); - activeSelection.set(options); - activeSelection.type = 'activeSelection'; - canvas.remove(this); - objects.forEach(function(object) { - object.group = activeSelection; - object.dirty = true; - canvas.add(object); - }); - activeSelection.canvas = canvas; - activeSelection._objects = objects; - canvas._activeObject = activeSelection; - activeSelection.setCoords(); - return activeSelection; - }, - - /** - * Destroys a group (restoring state of its objects) - * @return {fabric.Group} thisArg - * @chainable - */ - ungroupOnCanvas: function() { - return this._restoreObjectsState(); - }, - - /** - * Sets coordinates of all objects inside group - * @return {fabric.Group} thisArg - * @chainable - */ - setObjectsCoords: function() { - var skipControls = true; - this.forEachObject(function(object) { - object.setCoords(skipControls); - }); - return this; - }, - - /** - * @private - */ - _calcBounds: function(onlyWidthHeight) { - var aX = [], - aY = [], - o, prop, coords, - props = ['tr', 'br', 'bl', 'tl'], - i = 0, iLen = this._objects.length, - j, jLen = props.length; - - for ( ; i < iLen; ++i) { - o = this._objects[i]; - coords = o.calcACoords(); - for (j = 0; j < jLen; j++) { - prop = props[j]; - aX.push(coords[prop].x); - aY.push(coords[prop].y); - } - o.aCoords = coords; - } - - this._getBounds(aX, aY, onlyWidthHeight); - }, - - /** - * @private - */ - _getBounds: function(aX, aY, onlyWidthHeight) { - var minXY = new fabric.Point(min(aX), min(aY)), - maxXY = new fabric.Point(max(aX), max(aY)), - top = minXY.y || 0, left = minXY.x || 0, - width = (maxXY.x - minXY.x) || 0, - height = (maxXY.y - minXY.y) || 0; - this.width = width; - this.height = height; - if (!onlyWidthHeight) { - // the bounding box always finds the topleft most corner. - // whatever is the group origin, we set up here the left/top position. - this.setPositionByOrigin({ x: left, y: top }, 'left', 'top'); - } - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - _toSVG: function(reviver) { - var svgString = ['\n']; - - for (var i = 0, len = this._objects.length; i < len; i++) { - svgString.push('\t\t', this._objects[i].toSVG(reviver)); - } - svgString.push('\n'); - return svgString; - }, - - /** - * Returns styles-string for svg-export, specific version for group - * @return {String} - */ - getSvgStyles: function() { - var opacity = typeof this.opacity !== 'undefined' && this.opacity !== 1 ? - 'opacity: ' + this.opacity + ';' : '', - visibility = this.visible ? '' : ' visibility: hidden;'; - return [ - opacity, - this.getSvgFilter(), - visibility - ].join(''); - }, - - /** - * Returns svg clipPath representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toClipPathSVG: function(reviver) { - var svgString = []; - - for (var i = 0, len = this._objects.length; i < len; i++) { - svgString.push('\t', this._objects[i].toClipPathSVG(reviver)); - } - - return this._createBaseClipPathSVGMarkup(svgString, { reviver: reviver }); - }, - /* _TO_SVG_END_ */ - }); - - /** - * Returns {@link fabric.Group} instance from an object representation - * @static - * @memberOf fabric.Group - * @param {Object} object Object to create a group from - * @param {Function} [callback] Callback to invoke when an group instance is created - */ - fabric.Group.fromObject = function(object, callback) { - var objects = object.objects, - options = fabric.util.object.clone(object, true); - delete options.objects; - if (typeof objects === 'string') { - // it has to be an url or something went wrong. - fabric.loadSVGFromURL(objects, function (elements) { - var group = fabric.util.groupSVGElements(elements, object, objects); - group.set(options); - callback && callback(group); - }); - return; - } - fabric.util.enlivenObjects(objects, function (enlivenedObjects) { - var options = fabric.util.object.clone(object, true); - delete options.objects; - fabric.util.enlivenObjectEnlivables(object, options, function () { - callback && callback(new fabric.Group(enlivenedObjects, options, true)); - }); - }); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }); - - if (fabric.ActiveSelection) { - return; - } - - /** - * Group class - * @class fabric.ActiveSelection - * @extends fabric.Group - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups} - * @see {@link fabric.ActiveSelection#initialize} for constructor definition - */ - fabric.ActiveSelection = fabric.util.createClass(fabric.Group, /** @lends fabric.ActiveSelection.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'activeSelection', - - /** - * Constructor - * @param {Object} objects ActiveSelection objects - * @param {Object} [options] Options object - * @return {Object} thisArg - */ - initialize: function(objects, options) { - options = options || {}; - this._objects = objects || []; - for (var i = this._objects.length; i--; ) { - this._objects[i].group = this; - } - - if (options.originX) { - this.originX = options.originX; - } - if (options.originY) { - this.originY = options.originY; - } - this._calcBounds(); - this._updateObjectsCoords(); - fabric.Object.prototype.initialize.call(this, options); - this.setCoords(); - }, - - /** - * Change te activeSelection to a normal group, - * High level function that automatically adds it to canvas as - * active object. no events fired. - * @since 2.0.0 - * @return {fabric.Group} - */ - toGroup: function() { - var objects = this._objects.concat(); - this._objects = []; - var options = fabric.Object.prototype.toObject.call(this); - var newGroup = new fabric.Group([]); - delete options.type; - newGroup.set(options); - objects.forEach(function(object) { - object.canvas.remove(object); - object.group = newGroup; - }); - newGroup._objects = objects; - if (!this.canvas) { - return newGroup; - } - var canvas = this.canvas; - canvas.add(newGroup); - canvas._activeObject = newGroup; - newGroup.setCoords(); - return newGroup; - }, - - /** - * If returns true, deselection is cancelled. - * @since 2.0.0 - * @return {Boolean} [cancel] - */ - onDeselect: function() { - this.destroy(); - return false; - }, - - /** - * Returns string representation of a group - * @return {String} - */ - toString: function() { - return '#'; - }, - - /** - * Decide if the object should cache or not. Create its own cache level - * objectCaching is a global flag, wins over everything - * needsItsOwnCache should be used when the object drawing method requires - * a cache step. None of the fabric classes requires it. - * Generally you do not cache objects in groups because the group outside is cached. - * @return {Boolean} - */ - shouldCache: function() { - return false; - }, - - /** - * Check if this group or its parent group are caching, recursively up - * @return {Boolean} - */ - isOnACache: function() { - return false; - }, - - /** - * Renders controls and borders for the object - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Object} [styleOverride] properties to override the object style - * @param {Object} [childrenOverride] properties to override the children overrides - */ - _renderControls: function(ctx, styleOverride, childrenOverride) { - ctx.save(); - ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; - this.callSuper('_renderControls', ctx, styleOverride); - childrenOverride = childrenOverride || { }; - if (typeof childrenOverride.hasControls === 'undefined') { - childrenOverride.hasControls = false; - } - childrenOverride.forActiveSelection = true; - for (var i = 0, len = this._objects.length; i < len; i++) { - this._objects[i]._renderControls(ctx, childrenOverride); - } - ctx.restore(); - }, - }); - - /** - * Returns {@link fabric.ActiveSelection} instance from an object representation - * @static - * @memberOf fabric.ActiveSelection - * @param {Object} object Object to create a group from - * @param {Function} [callback] Callback to invoke when an ActiveSelection instance is created - */ - fabric.ActiveSelection.fromObject = function(object, callback) { - fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) { - delete object.objects; - callback && callback(new fabric.ActiveSelection(enlivenedObjects, object, true)); - }); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var extend = fabric.util.object.extend; - - if (!global.fabric) { - global.fabric = { }; - } - - if (global.fabric.Image) { - fabric.warn('fabric.Image is already defined.'); - return; - } - - /** - * Image class - * @class fabric.Image - * @extends fabric.Object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images} - * @see {@link fabric.Image#initialize} for constructor definition - */ - fabric.Image = fabric.util.createClass(fabric.Object, /** @lends fabric.Image.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'image', - - /** - * Width of a stroke. - * For image quality a stroke multiple of 2 gives better results. - * @type Number - * @default - */ - strokeWidth: 0, - - /** - * When calling {@link fabric.Image.getSrc}, return value from element src with `element.getAttribute('src')`. - * This allows for relative urls as image src. - * @since 2.7.0 - * @type Boolean - * @default - */ - srcFromAttribute: false, - - /** - * private - * contains last value of scaleX to detect - * if the Image got resized after the last Render - * @type Number - */ - _lastScaleX: 1, - - /** - * private - * contains last value of scaleY to detect - * if the Image got resized after the last Render - * @type Number - */ - _lastScaleY: 1, - - /** - * private - * contains last value of scaling applied by the apply filter chain - * @type Number - */ - _filterScalingX: 1, - - /** - * private - * contains last value of scaling applied by the apply filter chain - * @type Number - */ - _filterScalingY: 1, - - /** - * minimum scale factor under which any resizeFilter is triggered to resize the image - * 0 will disable the automatic resize. 1 will trigger automatically always. - * number bigger than 1 are not implemented yet. - * @type Number - */ - minimumScaleTrigger: 0.5, - - /** - * List of properties to consider when checking if - * state of an object is changed ({@link fabric.Object#hasStateChanged}) - * as well as for history (undo/redo) purposes - * @type Array - */ - stateProperties: fabric.Object.prototype.stateProperties.concat('cropX', 'cropY'), - - /** - * List of properties to consider when checking if cache needs refresh - * Those properties are checked by statefullCache ON ( or lazy mode if we want ) or from single - * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty - * and refreshed at the next render - * @type Array - */ - cacheProperties: fabric.Object.prototype.cacheProperties.concat('cropX', 'cropY'), - - /** - * key used to retrieve the texture representing this image - * @since 2.0.0 - * @type String - * @default - */ - cacheKey: '', - - /** - * Image crop in pixels from original image size. - * @since 2.0.0 - * @type Number - * @default - */ - cropX: 0, - - /** - * Image crop in pixels from original image size. - * @since 2.0.0 - * @type Number - * @default - */ - cropY: 0, - - /** - * Indicates whether this canvas will use image smoothing when painting this image. - * Also influence if the cacheCanvas for this image uses imageSmoothing - * @since 4.0.0-beta.11 - * @type Boolean - * @default - */ - imageSmoothing: true, - - /** - * Constructor - * Image can be initialized with any canvas drawable or a string. - * The string should be a url and will be loaded as an image. - * Canvas and Image element work out of the box, while videos require extra code to work. - * Please check video element events for seeking. - * @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | String} element Image element - * @param {Object} [options] Options object - * @param {function} [callback] callback function to call after eventual filters applied. - * @return {fabric.Image} thisArg - */ - initialize: function(element, options) { - options || (options = { }); - this.filters = []; - this.cacheKey = 'texture' + fabric.Object.__uid++; - this.callSuper('initialize', options); - this._initElement(element, options); - }, - - /** - * Returns image element which this instance if based on - * @return {HTMLImageElement} Image element - */ - getElement: function() { - return this._element || {}; - }, - - /** - * Sets image element for this instance to a specified one. - * If filters defined they are applied to new image. - * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area. - * @param {HTMLImageElement} element - * @param {Object} [options] Options object - * @return {fabric.Image} thisArg - * @chainable - */ - setElement: function(element, options) { - this.removeTexture(this.cacheKey); - this.removeTexture(this.cacheKey + '_filtered'); - this._element = element; - this._originalElement = element; - this._initConfig(options); - if (this.filters.length !== 0) { - this.applyFilters(); - } - // resizeFilters work on the already filtered copy. - // we need to apply resizeFilters AFTER normal filters. - // applyResizeFilters is run more often than normal filters - // and is triggered by user interactions rather than dev code - if (this.resizeFilter) { - this.applyResizeFilters(); - } - return this; - }, - - /** - * Delete a single texture if in webgl mode - */ - removeTexture: function(key) { - var backend = fabric.filterBackend; - if (backend && backend.evictCachesForKey) { - backend.evictCachesForKey(key); - } - }, - - /** - * Delete textures, reference to elements and eventually JSDOM cleanup - */ - dispose: function () { - this.callSuper('dispose'); - this.removeTexture(this.cacheKey); - this.removeTexture(this.cacheKey + '_filtered'); - this._cacheContext = undefined; - ['_originalElement', '_element', '_filteredEl', '_cacheCanvas'].forEach((function(element) { - fabric.util.cleanUpJsdomNode(this[element]); - this[element] = undefined; - }).bind(this)); - }, - - /** - * Get the crossOrigin value (of the corresponding image element) - */ - getCrossOrigin: function() { - return this._originalElement && (this._originalElement.crossOrigin || null); - }, - - /** - * Returns original size of an image - * @return {Object} Object with "width" and "height" properties - */ - getOriginalSize: function() { - var element = this.getElement(); - return { - width: element.naturalWidth || element.width, - height: element.naturalHeight || element.height - }; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _stroke: function(ctx) { - if (!this.stroke || this.strokeWidth === 0) { - return; - } - var w = this.width / 2, h = this.height / 2; - ctx.beginPath(); - ctx.moveTo(-w, -h); - ctx.lineTo(w, -h); - ctx.lineTo(w, h); - ctx.lineTo(-w, h); - ctx.lineTo(-w, -h); - ctx.closePath(); - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of an instance - */ - toObject: function(propertiesToInclude) { - var filters = []; - - this.filters.forEach(function(filterObj) { - if (filterObj) { - filters.push(filterObj.toObject()); - } - }); - var object = extend( - this.callSuper( - 'toObject', - ['cropX', 'cropY'].concat(propertiesToInclude) - ), { - src: this.getSrc(), - crossOrigin: this.getCrossOrigin(), - filters: filters, - }); - if (this.resizeFilter) { - object.resizeFilter = this.resizeFilter.toObject(); - } - return object; - }, - - /** - * Returns true if an image has crop applied, inspecting values of cropX,cropY,width,height. - * @return {Boolean} - */ - hasCrop: function() { - return this.cropX || this.cropY || this.width < this._element.width || this.height < this._element.height; - }, - - /* _TO_SVG_START_ */ - /** - * Returns svg representation of an instance - * @return {Array} an array of strings with the specific svg representation - * of the instance - */ - _toSVG: function() { - var svgString = [], imageMarkup = [], strokeSvg, element = this._element, - x = -this.width / 2, y = -this.height / 2, clipPath = '', imageRendering = ''; - if (!element) { - return []; - } - if (this.hasCrop()) { - var clipPathId = fabric.Object.__uid++; - svgString.push( - '\n', - '\t\n', - '\n' - ); - clipPath = ' clip-path="url(#imageCrop_' + clipPathId + ')" '; - } - if (!this.imageSmoothing) { - imageRendering = '" image-rendering="optimizeSpeed'; - } - imageMarkup.push('\t\n'); - - if (this.stroke || this.strokeDashArray) { - var origFill = this.fill; - this.fill = null; - strokeSvg = [ - '\t\n' - ]; - this.fill = origFill; - } - if (this.paintFirst !== 'fill') { - svgString = svgString.concat(strokeSvg, imageMarkup); - } - else { - svgString = svgString.concat(imageMarkup, strokeSvg); - } - return svgString; - }, - /* _TO_SVG_END_ */ - - /** - * Returns source of an image - * @param {Boolean} filtered indicates if the src is needed for svg - * @return {String} Source of an image - */ - getSrc: function(filtered) { - var element = filtered ? this._element : this._originalElement; - if (element) { - if (element.toDataURL) { - return element.toDataURL(); - } - - if (this.srcFromAttribute) { - return element.getAttribute('src'); - } - else { - return element.src; - } - } - else { - return this.src || ''; - } - }, - - /** - * Sets source of an image - * @param {String} src Source string (URL) - * @param {Function} [callback] Callback is invoked when image has been loaded (and all filters have been applied) - * @param {Object} [options] Options object - * @param {String} [options.crossOrigin] crossOrigin value (one of "", "anonymous", "use-credentials") - * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes - * @return {fabric.Image} thisArg - * @chainable - */ - setSrc: function(src, callback, options) { - fabric.util.loadImage(src, function(img, isError) { - this.setElement(img, options); - this._setWidthHeight(); - callback && callback(this, isError); - }, this, options && options.crossOrigin); - return this; - }, - - /** - * Returns string representation of an instance - * @return {String} String representation of an instance - */ - toString: function() { - return '#'; - }, - - applyResizeFilters: function() { - var filter = this.resizeFilter, - minimumScale = this.minimumScaleTrigger, - objectScale = this.getTotalObjectScaling(), - scaleX = objectScale.scaleX, - scaleY = objectScale.scaleY, - elementToFilter = this._filteredEl || this._originalElement; - if (this.group) { - this.set('dirty', true); - } - if (!filter || (scaleX > minimumScale && scaleY > minimumScale)) { - this._element = elementToFilter; - this._filterScalingX = 1; - this._filterScalingY = 1; - this._lastScaleX = scaleX; - this._lastScaleY = scaleY; - return; - } - if (!fabric.filterBackend) { - fabric.filterBackend = fabric.initFilterBackend(); - } - var canvasEl = fabric.util.createCanvasElement(), - cacheKey = this._filteredEl ? (this.cacheKey + '_filtered') : this.cacheKey, - sourceWidth = elementToFilter.width, sourceHeight = elementToFilter.height; - canvasEl.width = sourceWidth; - canvasEl.height = sourceHeight; - this._element = canvasEl; - this._lastScaleX = filter.scaleX = scaleX; - this._lastScaleY = filter.scaleY = scaleY; - fabric.filterBackend.applyFilters( - [filter], elementToFilter, sourceWidth, sourceHeight, this._element, cacheKey); - this._filterScalingX = canvasEl.width / this._originalElement.width; - this._filterScalingY = canvasEl.height / this._originalElement.height; - }, - - /** - * Applies filters assigned to this image (from "filters" array) or from filter param - * @method applyFilters - * @param {Array} filters to be applied - * @param {Boolean} forResizing specify if the filter operation is a resize operation - * @return {thisArg} return the fabric.Image object - * @chainable - */ - applyFilters: function(filters) { - - filters = filters || this.filters || []; - filters = filters.filter(function(filter) { return filter && !filter.isNeutralState(); }); - this.set('dirty', true); - - // needs to clear out or WEBGL will not resize correctly - this.removeTexture(this.cacheKey + '_filtered'); - - if (filters.length === 0) { - this._element = this._originalElement; - this._filteredEl = null; - this._filterScalingX = 1; - this._filterScalingY = 1; - return this; - } - - var imgElement = this._originalElement, - sourceWidth = imgElement.naturalWidth || imgElement.width, - sourceHeight = imgElement.naturalHeight || imgElement.height; - - if (this._element === this._originalElement) { - // if the element is the same we need to create a new element - var canvasEl = fabric.util.createCanvasElement(); - canvasEl.width = sourceWidth; - canvasEl.height = sourceHeight; - this._element = canvasEl; - this._filteredEl = canvasEl; - } - else { - // clear the existing element to get new filter data - // also dereference the eventual resized _element - this._element = this._filteredEl; - this._filteredEl.getContext('2d').clearRect(0, 0, sourceWidth, sourceHeight); - // we also need to resize again at next renderAll, so remove saved _lastScaleX/Y - this._lastScaleX = 1; - this._lastScaleY = 1; - } - if (!fabric.filterBackend) { - fabric.filterBackend = fabric.initFilterBackend(); - } - fabric.filterBackend.applyFilters( - filters, this._originalElement, sourceWidth, sourceHeight, this._element, this.cacheKey); - if (this._originalElement.width !== this._element.width || - this._originalElement.height !== this._element.height) { - this._filterScalingX = this._element.width / this._originalElement.width; - this._filterScalingY = this._element.height / this._originalElement.height; - } - return this; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - fabric.util.setImageSmoothing(ctx, this.imageSmoothing); - if (this.isMoving !== true && this.resizeFilter && this._needsResize()) { - this.applyResizeFilters(); - } - this._stroke(ctx); - this._renderPaintInOrder(ctx); - }, - - /** - * Paint the cached copy of the object on the target context. - * it will set the imageSmoothing for the draw operation - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - drawCacheOnCanvas: function(ctx) { - fabric.util.setImageSmoothing(ctx, this.imageSmoothing); - fabric.Object.prototype.drawCacheOnCanvas.call(this, ctx); - }, - - /** - * Decide if the object should cache or not. Create its own cache level - * needsItsOwnCache should be used when the object drawing method requires - * a cache step. None of the fabric classes requires it. - * Generally you do not cache objects in groups because the group outside is cached. - * This is the special image version where we would like to avoid caching where possible. - * Essentially images do not benefit from caching. They may require caching, and in that - * case we do it. Also caching an image usually ends in a loss of details. - * A full performance audit should be done. - * @return {Boolean} - */ - shouldCache: function() { - return this.needsItsOwnCache(); - }, - - _renderFill: function(ctx) { - var elementToDraw = this._element; - if (!elementToDraw) { - return; - } - var scaleX = this._filterScalingX, scaleY = this._filterScalingY, - w = this.width, h = this.height, min = Math.min, max = Math.max, - // crop values cannot be lesser than 0. - cropX = max(this.cropX, 0), cropY = max(this.cropY, 0), - elWidth = elementToDraw.naturalWidth || elementToDraw.width, - elHeight = elementToDraw.naturalHeight || elementToDraw.height, - sX = cropX * scaleX, - sY = cropY * scaleY, - // the width height cannot exceed element width/height, starting from the crop offset. - sW = min(w * scaleX, elWidth - sX), - sH = min(h * scaleY, elHeight - sY), - x = -w / 2, y = -h / 2, - maxDestW = min(w, elWidth / scaleX - cropX), - maxDestH = min(h, elHeight / scaleY - cropY); - - elementToDraw && ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, maxDestW, maxDestH); - }, - - /** - * needed to check if image needs resize - * @private - */ - _needsResize: function() { - var scale = this.getTotalObjectScaling(); - return (scale.scaleX !== this._lastScaleX || scale.scaleY !== this._lastScaleY); - }, - - /** - * @private - */ - _resetWidthHeight: function() { - this.set(this.getOriginalSize()); - }, - - /** - * The Image class's initialization method. This method is automatically - * called by the constructor. - * @private - * @param {HTMLImageElement|String} element The element representing the image - * @param {Object} [options] Options object - */ - _initElement: function(element, options) { - this.setElement(fabric.util.getById(element), options); - fabric.util.addClass(this.getElement(), fabric.Image.CSS_CANVAS); - }, - - /** - * @private - * @param {Object} [options] Options object - */ - _initConfig: function(options) { - options || (options = { }); - this.setOptions(options); - this._setWidthHeight(options); - }, - - /** - * @private - * @param {Array} filters to be initialized - * @param {Function} callback Callback to invoke when all fabric.Image.filters instances are created - */ - _initFilters: function(filters, callback) { - if (filters && filters.length) { - fabric.util.enlivenObjects(filters, function(enlivenedObjects) { - callback && callback(enlivenedObjects); - }, 'fabric.Image.filters'); - } - else { - callback && callback(); - } - }, - - /** - * @private - * Set the width and the height of the image object, using the element or the - * options. - * @param {Object} [options] Object with width/height properties - */ - _setWidthHeight: function(options) { - options || (options = { }); - var el = this.getElement(); - this.width = options.width || el.naturalWidth || el.width || 0; - this.height = options.height || el.naturalHeight || el.height || 0; - }, - - /** - * Calculate offset for center and scale factor for the image in order to respect - * the preserveAspectRatio attribute - * @private - * @return {Object} - */ - parsePreserveAspectRatioAttribute: function() { - var pAR = fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio || ''), - rWidth = this._element.width, rHeight = this._element.height, - scaleX = 1, scaleY = 1, offsetLeft = 0, offsetTop = 0, cropX = 0, cropY = 0, - offset, pWidth = this.width, pHeight = this.height, parsedAttributes = { width: pWidth, height: pHeight }; - if (pAR && (pAR.alignX !== 'none' || pAR.alignY !== 'none')) { - if (pAR.meetOrSlice === 'meet') { - scaleX = scaleY = fabric.util.findScaleToFit(this._element, parsedAttributes); - offset = (pWidth - rWidth * scaleX) / 2; - if (pAR.alignX === 'Min') { - offsetLeft = -offset; - } - if (pAR.alignX === 'Max') { - offsetLeft = offset; - } - offset = (pHeight - rHeight * scaleY) / 2; - if (pAR.alignY === 'Min') { - offsetTop = -offset; - } - if (pAR.alignY === 'Max') { - offsetTop = offset; - } - } - if (pAR.meetOrSlice === 'slice') { - scaleX = scaleY = fabric.util.findScaleToCover(this._element, parsedAttributes); - offset = rWidth - pWidth / scaleX; - if (pAR.alignX === 'Mid') { - cropX = offset / 2; - } - if (pAR.alignX === 'Max') { - cropX = offset; - } - offset = rHeight - pHeight / scaleY; - if (pAR.alignY === 'Mid') { - cropY = offset / 2; - } - if (pAR.alignY === 'Max') { - cropY = offset; - } - rWidth = pWidth / scaleX; - rHeight = pHeight / scaleY; - } - } - else { - scaleX = pWidth / rWidth; - scaleY = pHeight / rHeight; - } - return { - width: rWidth, - height: rHeight, - scaleX: scaleX, - scaleY: scaleY, - offsetLeft: offsetLeft, - offsetTop: offsetTop, - cropX: cropX, - cropY: cropY - }; - } - }); - - /** - * Default CSS class name for canvas - * @static - * @type String - * @default - */ - fabric.Image.CSS_CANVAS = 'canvas-img'; - - /** - * Alias for getSrc - * @static - */ - fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc; - - /** - * Creates an instance of fabric.Image from its object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} callback Callback to invoke when an image instance is created - */ - fabric.Image.fromObject = function(_object, callback) { - var object = fabric.util.object.clone(_object); - fabric.util.loadImage(object.src, function(img, isError) { - if (isError) { - callback && callback(null, true); - return; - } - fabric.Image.prototype._initFilters.call(object, object.filters, function(filters) { - object.filters = filters || []; - fabric.Image.prototype._initFilters.call(object, [object.resizeFilter], function(resizeFilters) { - object.resizeFilter = resizeFilters[0]; - fabric.util.enlivenObjectEnlivables(object, object, function () { - var image = new fabric.Image(img, object); - callback(image, false); - }); - }); - }); - }, null, object.crossOrigin); - }; - - /** - * Creates an instance of fabric.Image from an URL string - * @static - * @param {String} url URL to create an image from - * @param {Function} [callback] Callback to invoke when image is created (newly created image is passed as a first argument). Second argument is a boolean indicating if an error occurred or not. - * @param {Object} [imgOptions] Options object - */ - fabric.Image.fromURL = function(url, callback, imgOptions) { - fabric.util.loadImage(url, function(img, isError) { - callback && callback(new fabric.Image(img, imgOptions), isError); - }, null, imgOptions && imgOptions.crossOrigin); - }; - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Image.fromElement}) - * @static - * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement} - */ - fabric.Image.ATTRIBUTE_NAMES = - fabric.SHARED_ATTRIBUTES.concat( - 'x y width height preserveAspectRatio xlink:href crossOrigin image-rendering'.split(' ') - ); - - /** - * Returns {@link fabric.Image} instance from an SVG element - * @static - * @param {SVGElement} element Element to parse - * @param {Object} [options] Options object - * @param {Function} callback Callback to execute when fabric.Image object is created - * @return {fabric.Image} Instance of fabric.Image - */ - fabric.Image.fromElement = function(element, callback, options) { - var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES); - fabric.Image.fromURL(parsedAttributes['xlink:href'], callback, - extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes)); - }; - /* _FROM_SVG_END_ */ - -})(typeof exports !== 'undefined' ? exports : this); - - -fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { - - /** - * @private - * @return {Number} angle value - */ - _getAngleValueForStraighten: function() { - var angle = this.angle % 360; - if (angle > 0) { - return Math.round((angle - 1) / 90) * 90; - } - return Math.round(angle / 90) * 90; - }, - - /** - * Straightens an object (rotating it from current angle to one of 0, 90, 180, 270, etc. depending on which is closer) - * @return {fabric.Object} thisArg - * @chainable - */ - straighten: function() { - return this.rotate(this._getAngleValueForStraighten()); - }, - - /** - * Same as {@link fabric.Object.prototype.straighten} but with animation - * @param {Object} callbacks Object with callback functions - * @param {Function} [callbacks.onComplete] Invoked on completion - * @param {Function} [callbacks.onChange] Invoked on every step of animation - * @return {fabric.Object} thisArg - */ - fxStraighten: function(callbacks) { - callbacks = callbacks || { }; - - var empty = function() { }, - onComplete = callbacks.onComplete || empty, - onChange = callbacks.onChange || empty, - _this = this; - - return fabric.util.animate({ - target: this, - startValue: this.get('angle'), - endValue: this._getAngleValueForStraighten(), - duration: this.FX_DURATION, - onChange: function(value) { - _this.rotate(value); - onChange(); - }, - onComplete: function() { - _this.setCoords(); - onComplete(); - }, - }); - } -}); - -fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { - - /** - * Straightens object, then rerenders canvas - * @param {fabric.Object} object Object to straighten - * @return {fabric.Canvas} thisArg - * @chainable - */ - straightenObject: function (object) { - object.straighten(); - this.requestRenderAll(); - return this; - }, - - /** - * Same as {@link fabric.Canvas.prototype.straightenObject}, but animated - * @param {fabric.Object} object Object to straighten - * @return {fabric.Canvas} thisArg - */ - fxStraightenObject: function (object) { - return object.fxStraighten({ - onChange: this.requestRenderAllBound - }); - } -}); - - -(function() { - - 'use strict'; - - /** - * Tests if webgl supports certain precision - * @param {WebGL} Canvas WebGL context to test on - * @param {String} Precision to test can be any of following: 'lowp', 'mediump', 'highp' - * @returns {Boolean} Whether the user's browser WebGL supports given precision. - */ - function testPrecision(gl, precision){ - var fragmentSource = 'precision ' + precision + ' float;\nvoid main(){}'; - var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); - gl.shaderSource(fragmentShader, fragmentSource); - gl.compileShader(fragmentShader); - if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { - return false; - } - return true; - } - - /** - * Indicate whether this filtering backend is supported by the user's browser. - * @param {Number} tileSize check if the tileSize is supported - * @returns {Boolean} Whether the user's browser supports WebGL. - */ - fabric.isWebglSupported = function(tileSize) { - if (fabric.isLikelyNode) { - return false; - } - tileSize = tileSize || fabric.WebglFilterBackend.prototype.tileSize; - var canvas = document.createElement('canvas'); - var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); - var isSupported = false; - // eslint-disable-next-line - if (gl) { - fabric.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); - isSupported = fabric.maxTextureSize >= tileSize; - var precisions = ['highp', 'mediump', 'lowp']; - for (var i = 0; i < 3; i++){ - if (testPrecision(gl, precisions[i])){ - fabric.webGlPrecision = precisions[i]; - break; - }; - } - } - this.isSupported = isSupported; - return isSupported; - }; - - fabric.WebglFilterBackend = WebglFilterBackend; - - /** - * WebGL filter backend. - */ - function WebglFilterBackend(options) { - if (options && options.tileSize) { - this.tileSize = options.tileSize; - } - this.setupGLContext(this.tileSize, this.tileSize); - this.captureGPUInfo(); - }; - - WebglFilterBackend.prototype = /** @lends fabric.WebglFilterBackend.prototype */ { - - tileSize: 2048, - - /** - * Experimental. This object is a sort of repository of help layers used to avoid - * of recreating them during frequent filtering. If you are previewing a filter with - * a slider you probably do not want to create help layers every filter step. - * in this object there will be appended some canvases, created once, resized sometimes - * cleared never. Clearing is left to the developer. - **/ - resources: { - - }, - - /** - * Setup a WebGL context suitable for filtering, and bind any needed event handlers. - */ - setupGLContext: function(width, height) { - this.dispose(); - this.createWebGLCanvas(width, height); - // eslint-disable-next-line - this.aPosition = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]); - this.chooseFastestCopyGLTo2DMethod(width, height); - }, - - /** - * Pick a method to copy data from GL context to 2d canvas. In some browsers using - * putImageData is faster than drawImage for that specific operation. - */ - chooseFastestCopyGLTo2DMethod: function(width, height) { - var canMeasurePerf = typeof window.performance !== 'undefined', canUseImageData; - try { - new ImageData(1, 1); - canUseImageData = true; - } - catch (e) { - canUseImageData = false; - } - // eslint-disable-next-line no-undef - var canUseArrayBuffer = typeof ArrayBuffer !== 'undefined'; - // eslint-disable-next-line no-undef - var canUseUint8Clamped = typeof Uint8ClampedArray !== 'undefined'; - - if (!(canMeasurePerf && canUseImageData && canUseArrayBuffer && canUseUint8Clamped)) { - return; - } - - var targetCanvas = fabric.util.createCanvasElement(); - // eslint-disable-next-line no-undef - var imageBuffer = new ArrayBuffer(width * height * 4); - if (fabric.forceGLPutImageData) { - this.imageBuffer = imageBuffer; - this.copyGLTo2D = copyGLTo2DPutImageData; - return; - } - var testContext = { - imageBuffer: imageBuffer, - destinationWidth: width, - destinationHeight: height, - targetCanvas: targetCanvas - }; - var startTime, drawImageTime, putImageDataTime; - targetCanvas.width = width; - targetCanvas.height = height; - - startTime = window.performance.now(); - copyGLTo2DDrawImage.call(testContext, this.gl, testContext); - drawImageTime = window.performance.now() - startTime; - - startTime = window.performance.now(); - copyGLTo2DPutImageData.call(testContext, this.gl, testContext); - putImageDataTime = window.performance.now() - startTime; - - if (drawImageTime > putImageDataTime) { - this.imageBuffer = imageBuffer; - this.copyGLTo2D = copyGLTo2DPutImageData; - } - else { - this.copyGLTo2D = copyGLTo2DDrawImage; - } - }, - - /** - * Create a canvas element and associated WebGL context and attaches them as - * class properties to the GLFilterBackend class. - */ - createWebGLCanvas: function(width, height) { - var canvas = fabric.util.createCanvasElement(); - canvas.width = width; - canvas.height = height; - var glOptions = { - alpha: true, - premultipliedAlpha: false, - depth: false, - stencil: false, - antialias: false - }, - gl = canvas.getContext('webgl', glOptions); - if (!gl) { - gl = canvas.getContext('experimental-webgl', glOptions); - } - if (!gl) { - return; - } - gl.clearColor(0, 0, 0, 0); - // this canvas can fire webglcontextlost and webglcontextrestored - this.canvas = canvas; - this.gl = gl; - }, - - /** - * Attempts to apply the requested filters to the source provided, drawing the filtered output - * to the provided target canvas. - * - * @param {Array} filters The filters to apply. - * @param {HTMLImageElement|HTMLCanvasElement} source The source to be filtered. - * @param {Number} width The width of the source input. - * @param {Number} height The height of the source input. - * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn. - * @param {String|undefined} cacheKey A key used to cache resources related to the source. If - * omitted, caching will be skipped. - */ - applyFilters: function(filters, source, width, height, targetCanvas, cacheKey) { - var gl = this.gl; - var cachedTexture; - if (cacheKey) { - cachedTexture = this.getCachedTexture(cacheKey, source); - } - var pipelineState = { - originalWidth: source.width || source.originalWidth, - originalHeight: source.height || source.originalHeight, - sourceWidth: width, - sourceHeight: height, - destinationWidth: width, - destinationHeight: height, - context: gl, - sourceTexture: this.createTexture(gl, width, height, !cachedTexture && source), - targetTexture: this.createTexture(gl, width, height), - originalTexture: cachedTexture || - this.createTexture(gl, width, height, !cachedTexture && source), - passes: filters.length, - webgl: true, - aPosition: this.aPosition, - programCache: this.programCache, - pass: 0, - filterBackend: this, - targetCanvas: targetCanvas - }; - var tempFbo = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, tempFbo); - filters.forEach(function(filter) { filter && filter.applyTo(pipelineState); }); - resizeCanvasIfNeeded(pipelineState); - this.copyGLTo2D(gl, pipelineState); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.deleteTexture(pipelineState.sourceTexture); - gl.deleteTexture(pipelineState.targetTexture); - gl.deleteFramebuffer(tempFbo); - targetCanvas.getContext('2d').setTransform(1, 0, 0, 1, 0, 0); - return pipelineState; - }, - - /** - * Detach event listeners, remove references, and clean up caches. - */ - dispose: function() { - if (this.canvas) { - this.canvas = null; - this.gl = null; - } - this.clearWebGLCaches(); - }, - - /** - * Wipe out WebGL-related caches. - */ - clearWebGLCaches: function() { - this.programCache = {}; - this.textureCache = {}; - }, - - /** - * Create a WebGL texture object. - * - * Accepts specific dimensions to initialize the texture to or a source image. - * - * @param {WebGLRenderingContext} gl The GL context to use for creating the texture. - * @param {Number} width The width to initialize the texture at. - * @param {Number} height The height to initialize the texture. - * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source for the texture data. - * @returns {WebGLTexture} - */ - createTexture: function(gl, width, height, textureImageSource) { - var texture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - if (textureImageSource) { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureImageSource); - } - else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - return texture; - }, - - /** - * Can be optionally used to get a texture from the cache array - * - * If an existing texture is not found, a new texture is created and cached. - * - * @param {String} uniqueId A cache key to use to find an existing texture. - * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source to use to create the - * texture cache entry if one does not already exist. - */ - getCachedTexture: function(uniqueId, textureImageSource) { - if (this.textureCache[uniqueId]) { - return this.textureCache[uniqueId]; - } - else { - var texture = this.createTexture( - this.gl, textureImageSource.width, textureImageSource.height, textureImageSource); - this.textureCache[uniqueId] = texture; - return texture; - } - }, - - /** - * Clear out cached resources related to a source image that has been - * filtered previously. - * - * @param {String} cacheKey The cache key provided when the source image was filtered. - */ - evictCachesForKey: function(cacheKey) { - if (this.textureCache[cacheKey]) { - this.gl.deleteTexture(this.textureCache[cacheKey]); - delete this.textureCache[cacheKey]; - } - }, - - copyGLTo2D: copyGLTo2DDrawImage, - - /** - * Attempt to extract GPU information strings from a WebGL context. - * - * Useful information when debugging or blacklisting specific GPUs. - * - * @returns {Object} A GPU info object with renderer and vendor strings. - */ - captureGPUInfo: function() { - if (this.gpuInfo) { - return this.gpuInfo; - } - var gl = this.gl, gpuInfo = { renderer: '', vendor: '' }; - if (!gl) { - return gpuInfo; - } - var ext = gl.getExtension('WEBGL_debug_renderer_info'); - if (ext) { - var renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL); - var vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL); - if (renderer) { - gpuInfo.renderer = renderer.toLowerCase(); - } - if (vendor) { - gpuInfo.vendor = vendor.toLowerCase(); - } - } - this.gpuInfo = gpuInfo; - return gpuInfo; - }, - }; -})(); - -function resizeCanvasIfNeeded(pipelineState) { - var targetCanvas = pipelineState.targetCanvas, - width = targetCanvas.width, height = targetCanvas.height, - dWidth = pipelineState.destinationWidth, - dHeight = pipelineState.destinationHeight; - - if (width !== dWidth || height !== dHeight) { - targetCanvas.width = dWidth; - targetCanvas.height = dHeight; - } -} - -/** - * Copy an input WebGL canvas on to an output 2D canvas. - * - * The WebGL canvas is assumed to be upside down, with the top-left pixel of the - * desired output image appearing in the bottom-left corner of the WebGL canvas. - * - * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from. - * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to. - * @param {Object} pipelineState The 2D target canvas to copy on to. - */ -function copyGLTo2DDrawImage(gl, pipelineState) { - var glCanvas = gl.canvas, targetCanvas = pipelineState.targetCanvas, - ctx = targetCanvas.getContext('2d'); - ctx.translate(0, targetCanvas.height); // move it down again - ctx.scale(1, -1); // vertical flip - // where is my image on the big glcanvas? - var sourceY = glCanvas.height - targetCanvas.height; - ctx.drawImage(glCanvas, 0, sourceY, targetCanvas.width, targetCanvas.height, 0, 0, - targetCanvas.width, targetCanvas.height); -} - -/** - * Copy an input WebGL canvas on to an output 2D canvas using 2d canvas' putImageData - * API. Measurably faster than using ctx.drawImage in Firefox (version 54 on OSX Sierra). - * - * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from. - * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to. - * @param {Object} pipelineState The 2D target canvas to copy on to. - */ -function copyGLTo2DPutImageData(gl, pipelineState) { - var targetCanvas = pipelineState.targetCanvas, ctx = targetCanvas.getContext('2d'), - dWidth = pipelineState.destinationWidth, - dHeight = pipelineState.destinationHeight, - numBytes = dWidth * dHeight * 4; - - // eslint-disable-next-line no-undef - var u8 = new Uint8Array(this.imageBuffer, 0, numBytes); - // eslint-disable-next-line no-undef - var u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes); - - gl.readPixels(0, 0, dWidth, dHeight, gl.RGBA, gl.UNSIGNED_BYTE, u8); - var imgData = new ImageData(u8Clamped, dWidth, dHeight); - ctx.putImageData(imgData, 0, 0); -} - - -(function() { - - 'use strict'; - - var noop = function() {}; - - fabric.Canvas2dFilterBackend = Canvas2dFilterBackend; - - /** - * Canvas 2D filter backend. - */ - function Canvas2dFilterBackend() {}; - - Canvas2dFilterBackend.prototype = /** @lends fabric.Canvas2dFilterBackend.prototype */ { - evictCachesForKey: noop, - dispose: noop, - clearWebGLCaches: noop, - - /** - * Experimental. This object is a sort of repository of help layers used to avoid - * of recreating them during frequent filtering. If you are previewing a filter with - * a slider you probably do not want to create help layers every filter step. - * in this object there will be appended some canvases, created once, resized sometimes - * cleared never. Clearing is left to the developer. - **/ - resources: { - - }, - - /** - * Apply a set of filters against a source image and draw the filtered output - * to the provided destination canvas. - * - * @param {EnhancedFilter} filters The filter to apply. - * @param {HTMLImageElement|HTMLCanvasElement} sourceElement The source to be filtered. - * @param {Number} sourceWidth The width of the source input. - * @param {Number} sourceHeight The height of the source input. - * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn. - */ - applyFilters: function(filters, sourceElement, sourceWidth, sourceHeight, targetCanvas) { - var ctx = targetCanvas.getContext('2d'); - ctx.drawImage(sourceElement, 0, 0, sourceWidth, sourceHeight); - var imageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight); - var originalImageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight); - var pipelineState = { - sourceWidth: sourceWidth, - sourceHeight: sourceHeight, - imageData: imageData, - originalEl: sourceElement, - originalImageData: originalImageData, - canvasEl: targetCanvas, - ctx: ctx, - filterBackend: this, - }; - filters.forEach(function(filter) { filter.applyTo(pipelineState); }); - if (pipelineState.imageData.width !== sourceWidth || pipelineState.imageData.height !== sourceHeight) { - targetCanvas.width = pipelineState.imageData.width; - targetCanvas.height = pipelineState.imageData.height; - } - ctx.putImageData(pipelineState.imageData, 0, 0); - return pipelineState; - }, - - }; -})(); - - -/** - * @namespace fabric.Image.filters - * @memberOf fabric.Image - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#image_filters} - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - */ -fabric.Image = fabric.Image || { }; -fabric.Image.filters = fabric.Image.filters || { }; - -/** - * Root filter class from which all filter classes inherit from - * @class fabric.Image.filters.BaseFilter - * @memberOf fabric.Image.filters - */ -fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Image.filters.BaseFilter.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'BaseFilter', - - /** - * Array of attributes to send with buffers. do not modify - * @private - */ - - vertexSource: 'attribute vec2 aPosition;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vTexCoord = aPosition;\n' + - 'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n' + - '}', - - fragmentSource: 'precision highp float;\n' + - 'varying vec2 vTexCoord;\n' + - 'uniform sampler2D uTexture;\n' + - 'void main() {\n' + - 'gl_FragColor = texture2D(uTexture, vTexCoord);\n' + - '}', - - /** - * Constructor - * @param {Object} [options] Options object - */ - initialize: function(options) { - if (options) { - this.setOptions(options); - } - }, - - /** - * Sets filter's properties from options - * @param {Object} [options] Options object - */ - setOptions: function(options) { - for (var prop in options) { - this[prop] = options[prop]; - } - }, - - /** - * Compile this filter's shader program. - * - * @param {WebGLRenderingContext} gl The GL canvas context to use for shader compilation. - * @param {String} fragmentSource fragmentShader source for compilation - * @param {String} vertexSource vertexShader source for compilation - */ - createProgram: function(gl, fragmentSource, vertexSource) { - fragmentSource = fragmentSource || this.fragmentSource; - vertexSource = vertexSource || this.vertexSource; - if (fabric.webGlPrecision !== 'highp'){ - fragmentSource = fragmentSource.replace( - /precision highp float/g, - 'precision ' + fabric.webGlPrecision + ' float' - ); - } - var vertexShader = gl.createShader(gl.VERTEX_SHADER); - gl.shaderSource(vertexShader, vertexSource); - gl.compileShader(vertexShader); - if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) { - throw new Error( - // eslint-disable-next-line prefer-template - 'Vertex shader compile error for ' + this.type + ': ' + - gl.getShaderInfoLog(vertexShader) - ); - } - - var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); - gl.shaderSource(fragmentShader, fragmentSource); - gl.compileShader(fragmentShader); - if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { - throw new Error( - // eslint-disable-next-line prefer-template - 'Fragment shader compile error for ' + this.type + ': ' + - gl.getShaderInfoLog(fragmentShader) - ); - } - - var program = gl.createProgram(); - gl.attachShader(program, vertexShader); - gl.attachShader(program, fragmentShader); - gl.linkProgram(program); - if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { - throw new Error( - // eslint-disable-next-line prefer-template - 'Shader link error for "${this.type}" ' + - gl.getProgramInfoLog(program) - ); - } - - var attributeLocations = this.getAttributeLocations(gl, program); - var uniformLocations = this.getUniformLocations(gl, program) || { }; - uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW'); - uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH'); - return { - program: program, - attributeLocations: attributeLocations, - uniformLocations: uniformLocations - }; - }, - - /** - * Return a map of attribute names to WebGLAttributeLocation objects. - * - * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. - * @param {WebGLShaderProgram} program The shader program from which to take attribute locations. - * @returns {Object} A map of attribute names to attribute locations. - */ - getAttributeLocations: function(gl, program) { - return { - aPosition: gl.getAttribLocation(program, 'aPosition'), - }; - }, - - /** - * Return a map of uniform names to WebGLUniformLocation objects. - * - * Intended to be overridden by subclasses. - * - * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. - * @param {WebGLShaderProgram} program The shader program from which to take uniform locations. - * @returns {Object} A map of uniform names to uniform locations. - */ - getUniformLocations: function (/* gl, program */) { - // in case i do not need any special uniform i need to return an empty object - return { }; - }, - - /** - * Send attribute data from this filter to its shader program on the GPU. - * - * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. - * @param {Object} attributeLocations A map of shader attribute names to their locations. - */ - sendAttributeData: function(gl, attributeLocations, aPositionData) { - var attributeLocation = attributeLocations.aPosition; - var buffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - gl.enableVertexAttribArray(attributeLocation); - gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0); - gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW); - }, - - _setupFrameBuffer: function(options) { - var gl = options.context, width, height; - if (options.passes > 1) { - width = options.destinationWidth; - height = options.destinationHeight; - if (options.sourceWidth !== width || options.sourceHeight !== height) { - gl.deleteTexture(options.targetTexture); - options.targetTexture = options.filterBackend.createTexture(gl, width, height); - } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, - options.targetTexture, 0); - } - else { - // draw last filter on canvas and not to framebuffer. - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.finish(); - } - }, - - _swapTextures: function(options) { - options.passes--; - options.pass++; - var temp = options.targetTexture; - options.targetTexture = options.sourceTexture; - options.sourceTexture = temp; - }, - - /** - * Generic isNeutral implementation for one parameter based filters. - * Used only in image applyFilters to discard filters that will not have an effect - * on the image - * Other filters may need their own version ( ColorMatrix, HueRotation, gamma, ComposedFilter ) - * @param {Object} options - **/ - isNeutralState: function(/* options */) { - var main = this.mainParameter, - _class = fabric.Image.filters[this.type].prototype; - if (main) { - if (Array.isArray(_class[main])) { - for (var i = _class[main].length; i--;) { - if (this[main][i] !== _class[main][i]) { - return false; - } - } - return true; - } - else { - return _class[main] === this[main]; - } - } - else { - return false; - } - }, - - /** - * Apply this filter to the input image data provided. - * - * Determines whether to use WebGL or Canvas2D based on the options.webgl flag. - * - * @param {Object} options - * @param {Number} options.passes The number of filters remaining to be executed - * @param {Boolean} options.webgl Whether to use webgl to render the filter. - * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. - * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - applyTo: function(options) { - if (options.webgl) { - this._setupFrameBuffer(options); - this.applyToWebGL(options); - this._swapTextures(options); - } - else { - this.applyTo2d(options); - } - }, - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - if (!options.programCache.hasOwnProperty(this.type)) { - options.programCache[this.type] = this.createProgram(options.context); - } - return options.programCache[this.type]; - }, - - /** - * Apply this filter using webgl. - * - * @param {Object} options - * @param {Number} options.passes The number of filters remaining to be executed - * @param {Boolean} options.webgl Whether to use webgl to render the filter. - * @param {WebGLTexture} options.originalTexture The texture of the original input image. - * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. - * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - applyToWebGL: function(options) { - var gl = options.context; - var shader = this.retrieveShader(options); - if (options.pass === 0 && options.originalTexture) { - gl.bindTexture(gl.TEXTURE_2D, options.originalTexture); - } - else { - gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture); - } - gl.useProgram(shader.program); - this.sendAttributeData(gl, shader.attributeLocations, options.aPosition); - - gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth); - gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight); - - this.sendUniformData(gl, shader.uniformLocations); - gl.viewport(0, 0, options.destinationWidth, options.destinationHeight); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - }, - - bindAdditionalTexture: function(gl, texture, textureUnit) { - gl.activeTexture(textureUnit); - gl.bindTexture(gl.TEXTURE_2D, texture); - // reset active texture to 0 as usual - gl.activeTexture(gl.TEXTURE0); - }, - - unbindAdditionalTexture: function(gl, textureUnit) { - gl.activeTexture(textureUnit); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.activeTexture(gl.TEXTURE0); - }, - - getMainParameter: function() { - return this[this.mainParameter]; - }, - - setMainParameter: function(value) { - this[this.mainParameter] = value; - }, - - /** - * Send uniform data from this filter to its shader program on the GPU. - * - * Intended to be overridden by subclasses. - * - * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. - * @param {Object} uniformLocations A map of shader uniform names to their locations. - */ - sendUniformData: function(/* gl, uniformLocations */) { - // Intentionally left blank. Override me in subclasses. - }, - - /** - * If needed by a 2d filter, this functions can create an helper canvas to be used - * remember that options.targetCanvas is available for use till end of chain. - */ - createHelpLayer: function(options) { - if (!options.helpLayer) { - var helpLayer = document.createElement('canvas'); - helpLayer.width = options.sourceWidth; - helpLayer.height = options.sourceHeight; - options.helpLayer = helpLayer; - } - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - var object = { type: this.type }, mainP = this.mainParameter; - if (mainP) { - object[mainP] = this[mainP]; - } - return object; - }, - - /** - * Returns a JSON representation of an instance - * @return {Object} JSON - */ - toJSON: function() { - // delegate, not alias - return this.toObject(); - } -}); - -fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { - var filter = new fabric.Image.filters[object.type](object); - callback && callback(filter); - return filter; -}; - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Color Matrix filter class - * @class fabric.Image.filters.ColorMatrix - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.ColorMatrix#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @see {@Link http://www.webwasp.co.uk/tutorials/219/Color_Matrix_Filter.php} - * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl} - * @example Kodachrome filter - * var filter = new fabric.Image.filters.ColorMatrix({ - * matrix: [ - 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502, - -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203, - -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946, - 0, 0, 0, 1, 0 - ] - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.ColorMatrix = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.ColorMatrix.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'ColorMatrix', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'varying vec2 vTexCoord;\n' + - 'uniform mat4 uColorMatrix;\n' + - 'uniform vec4 uConstants;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'color *= uColorMatrix;\n' + - 'color += uConstants;\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * Colormatrix for pixels. - * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning - * outside the -1, 1 range. - * 0.0039215686 is the part of 1 that get translated to 1 in 2d - * @param {Array} matrix array of 20 numbers. - * @default - */ - matrix: [ - 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0 - ], - - mainParameter: 'matrix', - - /** - * Lock the colormatrix on the color part, skipping alpha, mainly for non webgl scenario - * to save some calculation - * @type Boolean - * @default true - */ - colorsOnly: true, - - /** - * Constructor - * @param {Object} [options] Options object - */ - initialize: function(options) { - this.callSuper('initialize', options); - // create a new array instead mutating the prototype with push - this.matrix = this.matrix.slice(0); - }, - - /** - * Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8Array to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, - iLen = data.length, - m = this.matrix, - r, g, b, a, i, colorsOnly = this.colorsOnly; - - for (i = 0; i < iLen; i += 4) { - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - if (colorsOnly) { - data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255; - data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255; - data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255; - } - else { - a = data[i + 3]; - data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4] * 255; - data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9] * 255; - data[i + 2] = r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14] * 255; - data[i + 3] = r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19] * 255; - } - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uColorMatrix: gl.getUniformLocation(program, 'uColorMatrix'), - uConstants: gl.getUniformLocation(program, 'uConstants'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - var m = this.matrix, - matrix = [ - m[0], m[1], m[2], m[3], - m[5], m[6], m[7], m[8], - m[10], m[11], m[12], m[13], - m[15], m[16], m[17], m[18] - ], - constants = [m[4], m[9], m[14], m[19]]; - gl.uniformMatrix4fv(uniformLocations.uColorMatrix, false, matrix); - gl.uniform4fv(uniformLocations.uConstants, constants); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] function to invoke after filter creation - * @return {fabric.Image.filters.ColorMatrix} Instance of fabric.Image.filters.ColorMatrix - */ - fabric.Image.filters.ColorMatrix.fromObject = fabric.Image.filters.BaseFilter.fromObject; -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Brightness filter class - * @class fabric.Image.filters.Brightness - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Brightness#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Brightness({ - * brightness: 0.05 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Brightness = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Brightness.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Brightness', - - /** - * Fragment source for the brightness program - */ - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uBrightness;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'color.rgb += uBrightness;\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * Brightness value, from -1 to 1. - * translated to -255 to 255 for 2d - * 0.0039215686 is the part of 1 that get translated to 1 in 2d - * @param {Number} brightness - * @default - */ - brightness: 0, - - /** - * Describe the property that is the filter parameter - * @param {String} m - * @default - */ - mainParameter: 'brightness', - - /** - * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - if (this.brightness === 0) { - return; - } - var imageData = options.imageData, - data = imageData.data, i, len = data.length, - brightness = Math.round(this.brightness * 255); - for (i = 0; i < len; i += 4) { - data[i] = data[i] + brightness; - data[i + 1] = data[i + 1] + brightness; - data[i + 2] = data[i + 2] + brightness; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uBrightness: gl.getUniformLocation(program, 'uBrightness'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uBrightness, this.brightness); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Brightness} Instance of fabric.Image.filters.Brightness - */ - fabric.Image.filters.Brightness.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Adapted from html5rocks article - * @class fabric.Image.filters.Convolute - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Convolute#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example Sharpen filter - * var filter = new fabric.Image.filters.Convolute({ - * matrix: [ 0, -1, 0, - * -1, 5, -1, - * 0, -1, 0 ] - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - * @example Blur filter - * var filter = new fabric.Image.filters.Convolute({ - * matrix: [ 1/9, 1/9, 1/9, - * 1/9, 1/9, 1/9, - * 1/9, 1/9, 1/9 ] - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - * @example Emboss filter - * var filter = new fabric.Image.filters.Convolute({ - * matrix: [ 1, 1, 1, - * 1, 0.7, -1, - * -1, -1, -1 ] - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - * @example Emboss filter with opaqueness - * var filter = new fabric.Image.filters.Convolute({ - * opaque: true, - * matrix: [ 1, 1, 1, - * 1, 0.7, -1, - * -1, -1, -1 ] - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - filters.Convolute = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Convolute.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Convolute', - - /* - * Opaque value (true/false) - */ - opaque: false, - - /* - * matrix for the filter, max 9x9 - */ - matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0], - - /** - * Fragment source for the brightness program - */ - fragmentSource: { - Convolute_3_1: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[9];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 0);\n' + - 'for (float h = 0.0; h < 3.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 3.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\n' + - 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\n' + - '}\n' + - '}\n' + - 'gl_FragColor = color;\n' + - '}', - Convolute_3_0: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[9];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 1);\n' + - 'for (float h = 0.0; h < 3.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 3.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\n' + - 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\n' + - '}\n' + - '}\n' + - 'float alpha = texture2D(uTexture, vTexCoord).a;\n' + - 'gl_FragColor = color;\n' + - 'gl_FragColor.a = alpha;\n' + - '}', - Convolute_5_1: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[25];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 0);\n' + - 'for (float h = 0.0; h < 5.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 5.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n' + - 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\n' + - '}\n' + - '}\n' + - 'gl_FragColor = color;\n' + - '}', - Convolute_5_0: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[25];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 1);\n' + - 'for (float h = 0.0; h < 5.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 5.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n' + - 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\n' + - '}\n' + - '}\n' + - 'float alpha = texture2D(uTexture, vTexCoord).a;\n' + - 'gl_FragColor = color;\n' + - 'gl_FragColor.a = alpha;\n' + - '}', - Convolute_7_1: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[49];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 0);\n' + - 'for (float h = 0.0; h < 7.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 7.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n' + - 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\n' + - '}\n' + - '}\n' + - 'gl_FragColor = color;\n' + - '}', - Convolute_7_0: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[49];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 1);\n' + - 'for (float h = 0.0; h < 7.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 7.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n' + - 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\n' + - '}\n' + - '}\n' + - 'float alpha = texture2D(uTexture, vTexCoord).a;\n' + - 'gl_FragColor = color;\n' + - 'gl_FragColor.a = alpha;\n' + - '}', - Convolute_9_1: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[81];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 0);\n' + - 'for (float h = 0.0; h < 9.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 9.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n' + - 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\n' + - '}\n' + - '}\n' + - 'gl_FragColor = color;\n' + - '}', - Convolute_9_0: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uMatrix[81];\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = vec4(0, 0, 0, 1);\n' + - 'for (float h = 0.0; h < 9.0; h+=1.0) {\n' + - 'for (float w = 0.0; w < 9.0; w+=1.0) {\n' + - 'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n' + - 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\n' + - '}\n' + - '}\n' + - 'float alpha = texture2D(uTexture, vTexCoord).a;\n' + - 'gl_FragColor = color;\n' + - 'gl_FragColor.a = alpha;\n' + - '}', - }, - - /** - * Constructor - * @memberOf fabric.Image.filters.Convolute.prototype - * @param {Object} [options] Options object - * @param {Boolean} [options.opaque=false] Opaque value (true/false) - * @param {Array} [options.matrix] Filter matrix - */ - - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - var size = Math.sqrt(this.matrix.length); - var cacheKey = this.type + '_' + size + '_' + (this.opaque ? 1 : 0); - var shaderSource = this.fragmentSource[cacheKey]; - if (!options.programCache.hasOwnProperty(cacheKey)) { - options.programCache[cacheKey] = this.createProgram(options.context, shaderSource); - } - return options.programCache[cacheKey]; - }, - - /** - * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, - weights = this.matrix, - side = Math.round(Math.sqrt(weights.length)), - halfSide = Math.floor(side / 2), - sw = imageData.width, - sh = imageData.height, - output = options.ctx.createImageData(sw, sh), - dst = output.data, - // go through the destination image pixels - alphaFac = this.opaque ? 1 : 0, - r, g, b, a, dstOff, - scx, scy, srcOff, wt, - x, y, cx, cy; - - for (y = 0; y < sh; y++) { - for (x = 0; x < sw; x++) { - dstOff = (y * sw + x) * 4; - // calculate the weighed sum of the source image pixels that - // fall under the convolution matrix - r = 0; g = 0; b = 0; a = 0; - - for (cy = 0; cy < side; cy++) { - for (cx = 0; cx < side; cx++) { - scy = y + cy - halfSide; - scx = x + cx - halfSide; - - // eslint-disable-next-line max-depth - if (scy < 0 || scy >= sh || scx < 0 || scx >= sw) { - continue; - } - - srcOff = (scy * sw + scx) * 4; - wt = weights[cy * side + cx]; - - r += data[srcOff] * wt; - g += data[srcOff + 1] * wt; - b += data[srcOff + 2] * wt; - // eslint-disable-next-line max-depth - if (!alphaFac) { - a += data[srcOff + 3] * wt; - } - } - } - dst[dstOff] = r; - dst[dstOff + 1] = g; - dst[dstOff + 2] = b; - if (!alphaFac) { - dst[dstOff + 3] = a; - } - else { - dst[dstOff + 3] = data[dstOff + 3]; - } - } - } - options.imageData = output; - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uMatrix: gl.getUniformLocation(program, 'uMatrix'), - uOpaque: gl.getUniformLocation(program, 'uOpaque'), - uHalfSize: gl.getUniformLocation(program, 'uHalfSize'), - uSize: gl.getUniformLocation(program, 'uSize'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1fv(uniformLocations.uMatrix, this.matrix); - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return extend(this.callSuper('toObject'), { - opaque: this.opaque, - matrix: this.matrix - }); - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Convolute} Instance of fabric.Image.filters.Convolute - */ - fabric.Image.filters.Convolute.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Grayscale image filter class - * @class fabric.Image.filters.Grayscale - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Grayscale(); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Grayscale = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Grayscale.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Grayscale', - - fragmentSource: { - average: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'float average = (color.r + color.b + color.g) / 3.0;\n' + - 'gl_FragColor = vec4(average, average, average, color.a);\n' + - '}', - lightness: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform int uMode;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 col = texture2D(uTexture, vTexCoord);\n' + - 'float average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\n' + - 'gl_FragColor = vec4(average, average, average, col.a);\n' + - '}', - luminosity: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform int uMode;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 col = texture2D(uTexture, vTexCoord);\n' + - 'float average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\n' + - 'gl_FragColor = vec4(average, average, average, col.a);\n' + - '}', - }, - - - /** - * Grayscale mode, between 'average', 'lightness', 'luminosity' - * @param {String} type - * @default - */ - mode: 'average', - - mainParameter: 'mode', - - /** - * Apply the Grayscale operation to a Uint8Array representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8Array to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, i, - len = data.length, value, - mode = this.mode; - for (i = 0; i < len; i += 4) { - if (mode === 'average') { - value = (data[i] + data[i + 1] + data[i + 2]) / 3; - } - else if (mode === 'lightness') { - value = (Math.min(data[i], data[i + 1], data[i + 2]) + - Math.max(data[i], data[i + 1], data[i + 2])) / 2; - } - else if (mode === 'luminosity') { - value = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2]; - } - data[i] = value; - data[i + 1] = value; - data[i + 2] = value; - } - }, - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - var cacheKey = this.type + '_' + this.mode; - if (!options.programCache.hasOwnProperty(cacheKey)) { - var shaderSource = this.fragmentSource[this.mode]; - options.programCache[cacheKey] = this.createProgram(options.context, shaderSource); - } - return options.programCache[cacheKey]; - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uMode: gl.getUniformLocation(program, 'uMode'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - // default average mode. - var mode = 1; - gl.uniform1i(uniformLocations.uMode, mode); - }, - - /** - * Grayscale filter isNeutralState implementation - * The filter is never neutral - * on the image - **/ - isNeutralState: function() { - return false; - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Grayscale} Instance of fabric.Image.filters.Grayscale - */ - fabric.Image.filters.Grayscale.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Invert filter class - * @class fabric.Image.filters.Invert - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Invert(); - * object.filters.push(filter); - * object.applyFilters(canvas.renderAll.bind(canvas)); - */ - filters.Invert = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Invert.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Invert', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform int uInvert;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'if (uInvert == 1) {\n' + - 'gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\n' + - '} else {\n' + - 'gl_FragColor = color;\n' + - '}\n' + - '}', - - /** - * Filter invert. if false, does nothing - * @param {Boolean} invert - * @default - */ - invert: true, - - mainParameter: 'invert', - - /** - * Apply the Invert operation to a Uint8Array representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8Array to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, i, - len = data.length; - for (i = 0; i < len; i += 4) { - data[i] = 255 - data[i]; - data[i + 1] = 255 - data[i + 1]; - data[i + 2] = 255 - data[i + 2]; - } - }, - - /** - * Invert filter isNeutralState implementation - * Used only in image applyFilters to discard filters that will not have an effect - * on the image - * @param {Object} options - **/ - isNeutralState: function() { - return !this.invert; - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uInvert: gl.getUniformLocation(program, 'uInvert'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1i(uniformLocations.uInvert, this.invert); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Invert} Instance of fabric.Image.filters.Invert - */ - fabric.Image.filters.Invert.fromObject = fabric.Image.filters.BaseFilter.fromObject; - - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Noise filter class - * @class fabric.Image.filters.Noise - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Noise#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Noise({ - * noise: 700 - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - filters.Noise = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Noise.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Noise', - - /** - * Fragment source for the noise program - */ - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uStepH;\n' + - 'uniform float uNoise;\n' + - 'uniform float uSeed;\n' + - 'varying vec2 vTexCoord;\n' + - 'float rand(vec2 co, float seed, float vScale) {\n' + - 'return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\n' + - '}\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * Describe the property that is the filter parameter - * @param {String} m - * @default - */ - mainParameter: 'noise', - - /** - * Noise value, from - * @param {Number} noise - * @default - */ - noise: 0, - - /** - * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - if (this.noise === 0) { - return; - } - var imageData = options.imageData, - data = imageData.data, i, len = data.length, - noise = this.noise, rand; - - for (i = 0, len = data.length; i < len; i += 4) { - - rand = (0.5 - Math.random()) * noise; - - data[i] += rand; - data[i + 1] += rand; - data[i + 2] += rand; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uNoise: gl.getUniformLocation(program, 'uNoise'), - uSeed: gl.getUniformLocation(program, 'uSeed'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uNoise, this.noise / 255); - gl.uniform1f(uniformLocations.uSeed, Math.random()); - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return extend(this.callSuper('toObject'), { - noise: this.noise - }); - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Noise} Instance of fabric.Image.filters.Noise - */ - fabric.Image.filters.Noise.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Pixelate filter class - * @class fabric.Image.filters.Pixelate - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Pixelate#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Pixelate({ - * blocksize: 8 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Pixelate = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Pixelate.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Pixelate', - - blocksize: 4, - - mainParameter: 'blocksize', - - /** - * Fragment source for the Pixelate program - */ - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uBlocksize;\n' + - 'uniform float uStepW;\n' + - 'uniform float uStepH;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'float blockW = uBlocksize * uStepW;\n' + - 'float blockH = uBlocksize * uStepW;\n' + - 'int posX = int(vTexCoord.x / blockW);\n' + - 'int posY = int(vTexCoord.y / blockH);\n' + - 'float fposX = float(posX);\n' + - 'float fposY = float(posY);\n' + - 'vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\n' + - 'vec4 color = texture2D(uTexture, squareCoords);\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * Apply the Pixelate operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, - iLen = imageData.height, - jLen = imageData.width, - index, i, j, r, g, b, a, - _i, _j, _iLen, _jLen; - - for (i = 0; i < iLen; i += this.blocksize) { - for (j = 0; j < jLen; j += this.blocksize) { - - index = (i * 4) * jLen + (j * 4); - - r = data[index]; - g = data[index + 1]; - b = data[index + 2]; - a = data[index + 3]; - - _iLen = Math.min(i + this.blocksize, iLen); - _jLen = Math.min(j + this.blocksize, jLen); - for (_i = i; _i < _iLen; _i++) { - for (_j = j; _j < _jLen; _j++) { - index = (_i * 4) * jLen + (_j * 4); - data[index] = r; - data[index + 1] = g; - data[index + 2] = b; - data[index + 3] = a; - } - } - } - } - }, - - /** - * Indicate when the filter is not gonna apply changes to the image - **/ - isNeutralState: function() { - return this.blocksize === 1; - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uBlocksize: gl.getUniformLocation(program, 'uBlocksize'), - uStepW: gl.getUniformLocation(program, 'uStepW'), - uStepH: gl.getUniformLocation(program, 'uStepH'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uBlocksize, this.blocksize); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Pixelate} Instance of fabric.Image.filters.Pixelate - */ - fabric.Image.filters.Pixelate.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - extend = fabric.util.object.extend, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Remove white filter class - * @class fabric.Image.filters.RemoveColor - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.RemoveColor#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.RemoveColor({ - * threshold: 0.2, - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - filters.RemoveColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.RemoveColor.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'RemoveColor', - - /** - * Color to remove, in any format understood by fabric.Color. - * @param {String} type - * @default - */ - color: '#FFFFFF', - - /** - * Fragment source for the brightness program - */ - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform vec4 uLow;\n' + - 'uniform vec4 uHigh;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'gl_FragColor = texture2D(uTexture, vTexCoord);\n' + - 'if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\n' + - 'gl_FragColor.a = 0.0;\n' + - '}\n' + - '}', - - /** - * distance to actual color, as value up or down from each r,g,b - * between 0 and 1 - **/ - distance: 0.02, - - /** - * For color to remove inside distance, use alpha channel for a smoother deletion - * NOT IMPLEMENTED YET - **/ - useAlpha: false, - - /** - * Constructor - * @memberOf fabric.Image.filters.RemoveWhite.prototype - * @param {Object} [options] Options object - * @param {Number} [options.color=#RRGGBB] Threshold value - * @param {Number} [options.distance=10] Distance value - */ - - /** - * Applies filter to canvas element - * @param {Object} canvasEl Canvas element to apply filter to - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, i, - distance = this.distance * 255, - r, g, b, - source = new fabric.Color(this.color).getSource(), - lowC = [ - source[0] - distance, - source[1] - distance, - source[2] - distance, - ], - highC = [ - source[0] + distance, - source[1] + distance, - source[2] + distance, - ]; - - - for (i = 0; i < data.length; i += 4) { - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - - if (r > lowC[0] && - g > lowC[1] && - b > lowC[2] && - r < highC[0] && - g < highC[1] && - b < highC[2]) { - data[i + 3] = 0; - } - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uLow: gl.getUniformLocation(program, 'uLow'), - uHigh: gl.getUniformLocation(program, 'uHigh'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - var source = new fabric.Color(this.color).getSource(), - distance = parseFloat(this.distance), - lowC = [ - 0 + source[0] / 255 - distance, - 0 + source[1] / 255 - distance, - 0 + source[2] / 255 - distance, - 1 - ], - highC = [ - source[0] / 255 + distance, - source[1] / 255 + distance, - source[2] / 255 + distance, - 1 - ]; - gl.uniform4fv(uniformLocations.uLow, lowC); - gl.uniform4fv(uniformLocations.uHigh, highC); - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return extend(this.callSuper('toObject'), { - color: this.color, - distance: this.distance - }); - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.RemoveColor} Instance of fabric.Image.filters.RemoveWhite - */ - fabric.Image.filters.RemoveColor.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - var matrices = { - Brownie: [ - 0.59970,0.34553,-0.27082,0,0.186, - -0.03770,0.86095,0.15059,0,-0.1449, - 0.24113,-0.07441,0.44972,0,-0.02965, - 0,0,0,1,0 - ], - Vintage: [ - 0.62793,0.32021,-0.03965,0,0.03784, - 0.02578,0.64411,0.03259,0,0.02926, - 0.04660,-0.08512,0.52416,0,0.02023, - 0,0,0,1,0 - ], - Kodachrome: [ - 1.12855,-0.39673,-0.03992,0,0.24991, - -0.16404,1.08352,-0.05498,0,0.09698, - -0.16786,-0.56034,1.60148,0,0.13972, - 0,0,0,1,0 - ], - Technicolor: [ - 1.91252,-0.85453,-0.09155,0,0.04624, - -0.30878,1.76589,-0.10601,0,-0.27589, - -0.23110,-0.75018,1.84759,0,0.12137, - 0,0,0,1,0 - ], - Polaroid: [ - 1.438,-0.062,-0.062,0,0, - -0.122,1.378,-0.122,0,0, - -0.016,-0.016,1.483,0,0, - 0,0,0,1,0 - ], - Sepia: [ - 0.393, 0.769, 0.189, 0, 0, - 0.349, 0.686, 0.168, 0, 0, - 0.272, 0.534, 0.131, 0, 0, - 0, 0, 0, 1, 0 - ], - BlackWhite: [ - 1.5, 1.5, 1.5, 0, -1, - 1.5, 1.5, 1.5, 0, -1, - 1.5, 1.5, 1.5, 0, -1, - 0, 0, 0, 1, 0, - ] - }; - - for (var key in matrices) { - filters[key] = createClass(filters.ColorMatrix, /** @lends fabric.Image.filters.Sepia.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: key, - - /** - * Colormatrix for the effect - * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning - * outside the -1, 1 range. - * @param {Array} matrix array of 20 numbers. - * @default - */ - matrix: matrices[key], - - /** - * Lock the matrix export for this kind of static, parameter less filters. - */ - mainParameter: false, - /** - * Lock the colormatrix on the color part, skipping alpha - */ - colorsOnly: true, - - }); - fabric.Image.filters[key].fromObject = fabric.Image.filters.BaseFilter.fromObject; - } -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - 'use strict'; - - var fabric = global.fabric, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Color Blend filter class - * @class fabric.Image.filter.BlendColor - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @example - * var filter = new fabric.Image.filters.BlendColor({ - * color: '#000', - * mode: 'multiply' - * }); - * - * var filter = new fabric.Image.filters.BlendImage({ - * image: fabricImageObject, - * mode: 'multiply', - * alpha: 0.5 - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - - filters.BlendColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blend.prototype */ { - type: 'BlendColor', - - /** - * Color to make the blend operation with. default to a reddish color since black or white - * gives always strong result. - * @type String - * @default - **/ - color: '#F95C63', - - /** - * Blend mode for the filter: one of multiply, add, diff, screen, subtract, - * darken, lighten, overlay, exclusion, tint. - * @type String - * @default - **/ - mode: 'multiply', - - /** - * alpha value. represent the strength of the blend color operation. - * @type Number - * @default - **/ - alpha: 1, - - /** - * Fragment source for the Multiply program - */ - fragmentSource: { - multiply: 'gl_FragColor.rgb *= uColor.rgb;\n', - screen: 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\n', - add: 'gl_FragColor.rgb += uColor.rgb;\n', - diff: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\n', - subtract: 'gl_FragColor.rgb -= uColor.rgb;\n', - lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\n', - darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\n', - exclusion: 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\n', - overlay: 'if (uColor.r < 0.5) {\n' + - 'gl_FragColor.r *= 2.0 * uColor.r;\n' + - '} else {\n' + - 'gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n' + - '}\n' + - 'if (uColor.g < 0.5) {\n' + - 'gl_FragColor.g *= 2.0 * uColor.g;\n' + - '} else {\n' + - 'gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n' + - '}\n' + - 'if (uColor.b < 0.5) {\n' + - 'gl_FragColor.b *= 2.0 * uColor.b;\n' + - '} else {\n' + - 'gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n' + - '}\n', - tint: 'gl_FragColor.rgb *= (1.0 - uColor.a);\n' + - 'gl_FragColor.rgb += uColor.rgb;\n', - }, - - /** - * build the fragment source for the filters, joining the common part with - * the specific one. - * @param {String} mode the mode of the filter, a key of this.fragmentSource - * @return {String} the source to be compiled - * @private - */ - buildSource: function(mode) { - return 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform vec4 uColor;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'gl_FragColor = color;\n' + - 'if (color.a > 0.0) {\n' + - this.fragmentSource[mode] + - '}\n' + - '}'; - }, - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - var cacheKey = this.type + '_' + this.mode, shaderSource; - if (!options.programCache.hasOwnProperty(cacheKey)) { - shaderSource = this.buildSource(this.mode); - options.programCache[cacheKey] = this.createProgram(options.context, shaderSource); - } - return options.programCache[cacheKey]; - }, - - /** - * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - data = imageData.data, iLen = data.length, - tr, tg, tb, - r, g, b, - source, alpha1 = 1 - this.alpha; - - source = new fabric.Color(this.color).getSource(); - tr = source[0] * this.alpha; - tg = source[1] * this.alpha; - tb = source[2] * this.alpha; - - for (var i = 0; i < iLen; i += 4) { - - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - - switch (this.mode) { - case 'multiply': - data[i] = r * tr / 255; - data[i + 1] = g * tg / 255; - data[i + 2] = b * tb / 255; - break; - case 'screen': - data[i] = 255 - (255 - r) * (255 - tr) / 255; - data[i + 1] = 255 - (255 - g) * (255 - tg) / 255; - data[i + 2] = 255 - (255 - b) * (255 - tb) / 255; - break; - case 'add': - data[i] = r + tr; - data[i + 1] = g + tg; - data[i + 2] = b + tb; - break; - case 'diff': - case 'difference': - data[i] = Math.abs(r - tr); - data[i + 1] = Math.abs(g - tg); - data[i + 2] = Math.abs(b - tb); - break; - case 'subtract': - data[i] = r - tr; - data[i + 1] = g - tg; - data[i + 2] = b - tb; - break; - case 'darken': - data[i] = Math.min(r, tr); - data[i + 1] = Math.min(g, tg); - data[i + 2] = Math.min(b, tb); - break; - case 'lighten': - data[i] = Math.max(r, tr); - data[i + 1] = Math.max(g, tg); - data[i + 2] = Math.max(b, tb); - break; - case 'overlay': - data[i] = tr < 128 ? (2 * r * tr / 255) : (255 - 2 * (255 - r) * (255 - tr) / 255); - data[i + 1] = tg < 128 ? (2 * g * tg / 255) : (255 - 2 * (255 - g) * (255 - tg) / 255); - data[i + 2] = tb < 128 ? (2 * b * tb / 255) : (255 - 2 * (255 - b) * (255 - tb) / 255); - break; - case 'exclusion': - data[i] = tr + r - ((2 * tr * r) / 255); - data[i + 1] = tg + g - ((2 * tg * g) / 255); - data[i + 2] = tb + b - ((2 * tb * b) / 255); - break; - case 'tint': - data[i] = tr + r * alpha1; - data[i + 1] = tg + g * alpha1; - data[i + 2] = tb + b * alpha1; - } - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uColor: gl.getUniformLocation(program, 'uColor'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - var source = new fabric.Color(this.color).getSource(); - source[0] = this.alpha * source[0] / 255; - source[1] = this.alpha * source[1] / 255; - source[2] = this.alpha * source[2] / 255; - source[3] = this.alpha; - gl.uniform4fv(uniformLocations.uColor, source); - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return { - type: this.type, - color: this.color, - mode: this.mode, - alpha: this.alpha - }; - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.BlendColor} Instance of fabric.Image.filters.BlendColor - */ - fabric.Image.filters.BlendColor.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - 'use strict'; - - var fabric = global.fabric, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Image Blend filter class - * @class fabric.Image.filter.BlendImage - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @example - * var filter = new fabric.Image.filters.BlendColor({ - * color: '#000', - * mode: 'multiply' - * }); - * - * var filter = new fabric.Image.filters.BlendImage({ - * image: fabricImageObject, - * mode: 'multiply', - * alpha: 0.5 - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - - filters.BlendImage = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.BlendImage.prototype */ { - type: 'BlendImage', - - /** - * Color to make the blend operation with. default to a reddish color since black or white - * gives always strong result. - **/ - image: null, - - /** - * Blend mode for the filter (one of "multiply", "mask") - * @type String - * @default - **/ - mode: 'multiply', - - /** - * alpha value. represent the strength of the blend image operation. - * not implemented. - **/ - alpha: 1, - - vertexSource: 'attribute vec2 aPosition;\n' + - 'varying vec2 vTexCoord;\n' + - 'varying vec2 vTexCoord2;\n' + - 'uniform mat3 uTransformMatrix;\n' + - 'void main() {\n' + - 'vTexCoord = aPosition;\n' + - 'vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\n' + - 'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n' + - '}', - - /** - * Fragment source for the Multiply program - */ - fragmentSource: { - multiply: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform sampler2D uImage;\n' + - 'uniform vec4 uColor;\n' + - 'varying vec2 vTexCoord;\n' + - 'varying vec2 vTexCoord2;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'vec4 color2 = texture2D(uImage, vTexCoord2);\n' + - 'color.rgba *= color2.rgba;\n' + - 'gl_FragColor = color;\n' + - '}', - mask: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform sampler2D uImage;\n' + - 'uniform vec4 uColor;\n' + - 'varying vec2 vTexCoord;\n' + - 'varying vec2 vTexCoord2;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'vec4 color2 = texture2D(uImage, vTexCoord2);\n' + - 'color.a = color2.a;\n' + - 'gl_FragColor = color;\n' + - '}', - }, - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - var cacheKey = this.type + '_' + this.mode; - var shaderSource = this.fragmentSource[this.mode]; - if (!options.programCache.hasOwnProperty(cacheKey)) { - options.programCache[cacheKey] = this.createProgram(options.context, shaderSource); - } - return options.programCache[cacheKey]; - }, - - applyToWebGL: function(options) { - // load texture to blend. - var gl = options.context, - texture = this.createTexture(options.filterBackend, this.image); - this.bindAdditionalTexture(gl, texture, gl.TEXTURE1); - this.callSuper('applyToWebGL', options); - this.unbindAdditionalTexture(gl, gl.TEXTURE1); - }, - - createTexture: function(backend, image) { - return backend.getCachedTexture(image.cacheKey, image._element); - }, - - /** - * Calculate a transformMatrix to adapt the image to blend over - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - calculateMatrix: function() { - var image = this.image, - width = image._element.width, - height = image._element.height; - return [ - 1 / image.scaleX, 0, 0, - 0, 1 / image.scaleY, 0, - -image.left / width, -image.top / height, 1 - ]; - }, - - /** - * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, - resources = options.filterBackend.resources, - data = imageData.data, iLen = data.length, - width = imageData.width, - height = imageData.height, - tr, tg, tb, ta, - r, g, b, a, - canvas1, context, image = this.image, blendData; - - if (!resources.blendImage) { - resources.blendImage = fabric.util.createCanvasElement(); - } - canvas1 = resources.blendImage; - context = canvas1.getContext('2d'); - if (canvas1.width !== width || canvas1.height !== height) { - canvas1.width = width; - canvas1.height = height; - } - else { - context.clearRect(0, 0, width, height); - } - context.setTransform(image.scaleX, 0, 0, image.scaleY, image.left, image.top); - context.drawImage(image._element, 0, 0, width, height); - blendData = context.getImageData(0, 0, width, height).data; - for (var i = 0; i < iLen; i += 4) { - - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - a = data[i + 3]; - - tr = blendData[i]; - tg = blendData[i + 1]; - tb = blendData[i + 2]; - ta = blendData[i + 3]; - - switch (this.mode) { - case 'multiply': - data[i] = r * tr / 255; - data[i + 1] = g * tg / 255; - data[i + 2] = b * tb / 255; - data[i + 3] = a * ta / 255; - break; - case 'mask': - data[i + 3] = ta; - break; - } - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uTransformMatrix: gl.getUniformLocation(program, 'uTransformMatrix'), - uImage: gl.getUniformLocation(program, 'uImage'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - var matrix = this.calculateMatrix(); - gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1. - gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix); - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return { - type: this.type, - image: this.image && this.image.toObject(), - mode: this.mode, - alpha: this.alpha - }; - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} callback to be invoked after filter creation - * @return {fabric.Image.filters.BlendImage} Instance of fabric.Image.filters.BlendImage - */ - fabric.Image.filters.BlendImage.fromObject = function(object, callback) { - fabric.Image.fromObject(object.image, function(image) { - var options = fabric.util.object.clone(object); - options.image = image; - callback(new fabric.Image.filters.BlendImage(options)); - }); - }; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), pow = Math.pow, floor = Math.floor, - sqrt = Math.sqrt, abs = Math.abs, round = Math.round, sin = Math.sin, - ceil = Math.ceil, - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Resize image filter class - * @class fabric.Image.filters.Resize - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Resize(); - * object.filters.push(filter); - * object.applyFilters(canvas.renderAll.bind(canvas)); - */ - filters.Resize = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Resize.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Resize', - - /** - * Resize type - * for webgl resizeType is just lanczos, for canvas2d can be: - * bilinear, hermite, sliceHack, lanczos. - * @param {String} resizeType - * @default - */ - resizeType: 'hermite', - - /** - * Scale factor for resizing, x axis - * @param {Number} scaleX - * @default - */ - scaleX: 1, - - /** - * Scale factor for resizing, y axis - * @param {Number} scaleY - * @default - */ - scaleY: 1, - - /** - * LanczosLobes parameter for lanczos filter, valid for resizeType lanczos - * @param {Number} lanczosLobes - * @default - */ - lanczosLobes: 3, - - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uDelta: gl.getUniformLocation(program, 'uDelta'), - uTaps: gl.getUniformLocation(program, 'uTaps'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform2fv(uniformLocations.uDelta, this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height]); - gl.uniform1fv(uniformLocations.uTaps, this.taps); - }, - - /** - * Retrieves the cached shader. - * @param {Object} options - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - retrieveShader: function(options) { - var filterWindow = this.getFilterWindow(), cacheKey = this.type + '_' + filterWindow; - if (!options.programCache.hasOwnProperty(cacheKey)) { - var fragmentShader = this.generateShader(filterWindow); - options.programCache[cacheKey] = this.createProgram(options.context, fragmentShader); - } - return options.programCache[cacheKey]; - }, - - getFilterWindow: function() { - var scale = this.tempScale; - return Math.ceil(this.lanczosLobes / scale); - }, - - getTaps: function() { - var lobeFunction = this.lanczosCreate(this.lanczosLobes), scale = this.tempScale, - filterWindow = this.getFilterWindow(), taps = new Array(filterWindow); - for (var i = 1; i <= filterWindow; i++) { - taps[i - 1] = lobeFunction(i * scale); - } - return taps; - }, - - /** - * Generate vertex and shader sources from the necessary steps numbers - * @param {Number} filterWindow - */ - generateShader: function(filterWindow) { - var offsets = new Array(filterWindow), - fragmentShader = this.fragmentSourceTOP, filterWindow; - - for (var i = 1; i <= filterWindow; i++) { - offsets[i - 1] = i + '.0 * uDelta'; - } - - fragmentShader += 'uniform float uTaps[' + filterWindow + '];\n'; - fragmentShader += 'void main() {\n'; - fragmentShader += ' vec4 color = texture2D(uTexture, vTexCoord);\n'; - fragmentShader += ' float sum = 1.0;\n'; - - offsets.forEach(function(offset, i) { - fragmentShader += ' color += texture2D(uTexture, vTexCoord + ' + offset + ') * uTaps[' + i + '];\n'; - fragmentShader += ' color += texture2D(uTexture, vTexCoord - ' + offset + ') * uTaps[' + i + '];\n'; - fragmentShader += ' sum += 2.0 * uTaps[' + i + '];\n'; - }); - fragmentShader += ' gl_FragColor = color / sum;\n'; - fragmentShader += '}'; - return fragmentShader; - }, - - fragmentSourceTOP: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform vec2 uDelta;\n' + - 'varying vec2 vTexCoord;\n', - - /** - * Apply the resize filter to the image - * Determines whether to use WebGL or Canvas2D based on the options.webgl flag. - * - * @param {Object} options - * @param {Number} options.passes The number of filters remaining to be executed - * @param {Boolean} options.webgl Whether to use webgl to render the filter. - * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. - * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - applyTo: function(options) { - if (options.webgl) { - options.passes++; - this.width = options.sourceWidth; - this.horizontal = true; - this.dW = Math.round(this.width * this.scaleX); - this.dH = options.sourceHeight; - this.tempScale = this.dW / this.width; - this.taps = this.getTaps(); - options.destinationWidth = this.dW; - this._setupFrameBuffer(options); - this.applyToWebGL(options); - this._swapTextures(options); - options.sourceWidth = options.destinationWidth; - - this.height = options.sourceHeight; - this.horizontal = false; - this.dH = Math.round(this.height * this.scaleY); - this.tempScale = this.dH / this.height; - this.taps = this.getTaps(); - options.destinationHeight = this.dH; - this._setupFrameBuffer(options); - this.applyToWebGL(options); - this._swapTextures(options); - options.sourceHeight = options.destinationHeight; - } - else { - this.applyTo2d(options); - } - }, - - isNeutralState: function() { - return this.scaleX === 1 && this.scaleY === 1; - }, - - lanczosCreate: function(lobes) { - return function(x) { - if (x >= lobes || x <= -lobes) { - return 0.0; - } - if (x < 1.19209290E-07 && x > -1.19209290E-07) { - return 1.0; - } - x *= Math.PI; - var xx = x / lobes; - return (sin(x) / x) * sin(xx) / xx; - }; - }, - - /** - * Applies filter to canvas element - * @memberOf fabric.Image.filters.Resize.prototype - * @param {Object} canvasEl Canvas element to apply filter to - * @param {Number} scaleX - * @param {Number} scaleY - */ - applyTo2d: function(options) { - var imageData = options.imageData, - scaleX = this.scaleX, - scaleY = this.scaleY; - - this.rcpScaleX = 1 / scaleX; - this.rcpScaleY = 1 / scaleY; - - var oW = imageData.width, oH = imageData.height, - dW = round(oW * scaleX), dH = round(oH * scaleY), - newData; - - if (this.resizeType === 'sliceHack') { - newData = this.sliceByTwo(options, oW, oH, dW, dH); - } - else if (this.resizeType === 'hermite') { - newData = this.hermiteFastResize(options, oW, oH, dW, dH); - } - else if (this.resizeType === 'bilinear') { - newData = this.bilinearFiltering(options, oW, oH, dW, dH); - } - else if (this.resizeType === 'lanczos') { - newData = this.lanczosResize(options, oW, oH, dW, dH); - } - options.imageData = newData; - }, - - /** - * Filter sliceByTwo - * @param {Object} canvasEl Canvas element to apply filter to - * @param {Number} oW Original Width - * @param {Number} oH Original Height - * @param {Number} dW Destination Width - * @param {Number} dH Destination Height - * @returns {ImageData} - */ - sliceByTwo: function(options, oW, oH, dW, dH) { - var imageData = options.imageData, - mult = 0.5, doneW = false, doneH = false, stepW = oW * mult, - stepH = oH * mult, resources = fabric.filterBackend.resources, - tmpCanvas, ctx, sX = 0, sY = 0, dX = oW, dY = 0; - if (!resources.sliceByTwo) { - resources.sliceByTwo = document.createElement('canvas'); - } - tmpCanvas = resources.sliceByTwo; - if (tmpCanvas.width < oW * 1.5 || tmpCanvas.height < oH) { - tmpCanvas.width = oW * 1.5; - tmpCanvas.height = oH; - } - ctx = tmpCanvas.getContext('2d'); - ctx.clearRect(0, 0, oW * 1.5, oH); - ctx.putImageData(imageData, 0, 0); - - dW = floor(dW); - dH = floor(dH); - - while (!doneW || !doneH) { - oW = stepW; - oH = stepH; - if (dW < floor(stepW * mult)) { - stepW = floor(stepW * mult); - } - else { - stepW = dW; - doneW = true; - } - if (dH < floor(stepH * mult)) { - stepH = floor(stepH * mult); - } - else { - stepH = dH; - doneH = true; - } - ctx.drawImage(tmpCanvas, sX, sY, oW, oH, dX, dY, stepW, stepH); - sX = dX; - sY = dY; - dY += stepH; - } - return ctx.getImageData(sX, sY, dW, dH); - }, - - /** - * Filter lanczosResize - * @param {Object} canvasEl Canvas element to apply filter to - * @param {Number} oW Original Width - * @param {Number} oH Original Height - * @param {Number} dW Destination Width - * @param {Number} dH Destination Height - * @returns {ImageData} - */ - lanczosResize: function(options, oW, oH, dW, dH) { - - function process(u) { - var v, i, weight, idx, a, red, green, - blue, alpha, fX, fY; - center.x = (u + 0.5) * ratioX; - icenter.x = floor(center.x); - for (v = 0; v < dH; v++) { - center.y = (v + 0.5) * ratioY; - icenter.y = floor(center.y); - a = 0; red = 0; green = 0; blue = 0; alpha = 0; - for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) { - if (i < 0 || i >= oW) { - continue; - } - fX = floor(1000 * abs(i - center.x)); - if (!cacheLanc[fX]) { - cacheLanc[fX] = { }; - } - for (var j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) { - if (j < 0 || j >= oH) { - continue; - } - fY = floor(1000 * abs(j - center.y)); - if (!cacheLanc[fX][fY]) { - cacheLanc[fX][fY] = lanczos(sqrt(pow(fX * rcpRatioX, 2) + pow(fY * rcpRatioY, 2)) / 1000); - } - weight = cacheLanc[fX][fY]; - if (weight > 0) { - idx = (j * oW + i) * 4; - a += weight; - red += weight * srcData[idx]; - green += weight * srcData[idx + 1]; - blue += weight * srcData[idx + 2]; - alpha += weight * srcData[idx + 3]; - } - } - } - idx = (v * dW + u) * 4; - destData[idx] = red / a; - destData[idx + 1] = green / a; - destData[idx + 2] = blue / a; - destData[idx + 3] = alpha / a; - } - - if (++u < dW) { - return process(u); - } - else { - return destImg; - } - } - - var srcData = options.imageData.data, - destImg = options.ctx.createImageData(dW, dH), - destData = destImg.data, - lanczos = this.lanczosCreate(this.lanczosLobes), - ratioX = this.rcpScaleX, ratioY = this.rcpScaleY, - rcpRatioX = 2 / this.rcpScaleX, rcpRatioY = 2 / this.rcpScaleY, - range2X = ceil(ratioX * this.lanczosLobes / 2), - range2Y = ceil(ratioY * this.lanczosLobes / 2), - cacheLanc = { }, center = { }, icenter = { }; - - return process(0); - }, - - /** - * bilinearFiltering - * @param {Object} canvasEl Canvas element to apply filter to - * @param {Number} oW Original Width - * @param {Number} oH Original Height - * @param {Number} dW Destination Width - * @param {Number} dH Destination Height - * @returns {ImageData} - */ - bilinearFiltering: function(options, oW, oH, dW, dH) { - var a, b, c, d, x, y, i, j, xDiff, yDiff, chnl, - color, offset = 0, origPix, ratioX = this.rcpScaleX, - ratioY = this.rcpScaleY, - w4 = 4 * (oW - 1), img = options.imageData, - pixels = img.data, destImage = options.ctx.createImageData(dW, dH), - destPixels = destImage.data; - for (i = 0; i < dH; i++) { - for (j = 0; j < dW; j++) { - x = floor(ratioX * j); - y = floor(ratioY * i); - xDiff = ratioX * j - x; - yDiff = ratioY * i - y; - origPix = 4 * (y * oW + x); - - for (chnl = 0; chnl < 4; chnl++) { - a = pixels[origPix + chnl]; - b = pixels[origPix + 4 + chnl]; - c = pixels[origPix + w4 + chnl]; - d = pixels[origPix + w4 + 4 + chnl]; - color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) + - c * yDiff * (1 - xDiff) + d * xDiff * yDiff; - destPixels[offset++] = color; - } - } - } - return destImage; - }, - - /** - * hermiteFastResize - * @param {Object} canvasEl Canvas element to apply filter to - * @param {Number} oW Original Width - * @param {Number} oH Original Height - * @param {Number} dW Destination Width - * @param {Number} dH Destination Height - * @returns {ImageData} - */ - hermiteFastResize: function(options, oW, oH, dW, dH) { - var ratioW = this.rcpScaleX, ratioH = this.rcpScaleY, - ratioWHalf = ceil(ratioW / 2), - ratioHHalf = ceil(ratioH / 2), - img = options.imageData, data = img.data, - img2 = options.ctx.createImageData(dW, dH), data2 = img2.data; - for (var j = 0; j < dH; j++) { - for (var i = 0; i < dW; i++) { - var x2 = (i + j * dW) * 4, weight = 0, weights = 0, weightsAlpha = 0, - gxR = 0, gxG = 0, gxB = 0, gxA = 0, centerY = (j + 0.5) * ratioH; - for (var yy = floor(j * ratioH); yy < (j + 1) * ratioH; yy++) { - var dy = abs(centerY - (yy + 0.5)) / ratioHHalf, - centerX = (i + 0.5) * ratioW, w0 = dy * dy; - for (var xx = floor(i * ratioW); xx < (i + 1) * ratioW; xx++) { - var dx = abs(centerX - (xx + 0.5)) / ratioWHalf, - w = sqrt(w0 + dx * dx); - /* eslint-disable max-depth */ - if (w > 1 && w < -1) { - continue; - } - //hermite filter - weight = 2 * w * w * w - 3 * w * w + 1; - if (weight > 0) { - dx = 4 * (xx + yy * oW); - //alpha - gxA += weight * data[dx + 3]; - weightsAlpha += weight; - //colors - if (data[dx + 3] < 255) { - weight = weight * data[dx + 3] / 250; - } - gxR += weight * data[dx]; - gxG += weight * data[dx + 1]; - gxB += weight * data[dx + 2]; - weights += weight; - } - /* eslint-enable max-depth */ - } - } - data2[x2] = gxR / weights; - data2[x2 + 1] = gxG / weights; - data2[x2 + 2] = gxB / weights; - data2[x2 + 3] = gxA / weightsAlpha; - } - } - return img2; - }, - - /** - * Returns object representation of an instance - * @return {Object} Object representation of an instance - */ - toObject: function() { - return { - type: this.type, - scaleX: this.scaleX, - scaleY: this.scaleY, - resizeType: this.resizeType, - lanczosLobes: this.lanczosLobes - }; - } - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Resize} Instance of fabric.Image.filters.Resize - */ - fabric.Image.filters.Resize.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Contrast filter class - * @class fabric.Image.filters.Contrast - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Contrast#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Contrast({ - * contrast: 0.25 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Contrast = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Contrast.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Contrast', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uContrast;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\n' + - 'color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * contrast value, range from -1 to 1. - * @param {Number} contrast - * @default 0 - */ - contrast: 0, - - mainParameter: 'contrast', - - /** - * Constructor - * @memberOf fabric.Image.filters.Contrast.prototype - * @param {Object} [options] Options object - * @param {Number} [options.contrast=0] Value to contrast the image up (-1...1) - */ - - /** - * Apply the Contrast operation to a Uint8Array representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8Array to be filtered. - */ - applyTo2d: function(options) { - if (this.contrast === 0) { - return; - } - var imageData = options.imageData, i, len, - data = imageData.data, len = data.length, - contrast = Math.floor(this.contrast * 255), - contrastF = 259 * (contrast + 255) / (255 * (259 - contrast)); - - for (i = 0; i < len; i += 4) { - data[i] = contrastF * (data[i] - 128) + 128; - data[i + 1] = contrastF * (data[i + 1] - 128) + 128; - data[i + 2] = contrastF * (data[i + 2] - 128) + 128; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uContrast: gl.getUniformLocation(program, 'uContrast'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uContrast, this.contrast); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Contrast} Instance of fabric.Image.filters.Contrast - */ - fabric.Image.filters.Contrast.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Saturate filter class - * @class fabric.Image.filters.Saturation - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Saturation#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Saturation({ - * saturation: 1 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Saturation = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Saturation.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Saturation', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uSaturation;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'float rgMax = max(color.r, color.g);\n' + - 'float rgbMax = max(rgMax, color.b);\n' + - 'color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\n' + - 'color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\n' + - 'color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * Saturation value, from -1 to 1. - * Increases/decreases the color saturation. - * A value of 0 has no effect. - * - * @param {Number} saturation - * @default - */ - saturation: 0, - - mainParameter: 'saturation', - - /** - * Constructor - * @memberOf fabric.Image.filters.Saturate.prototype - * @param {Object} [options] Options object - * @param {Number} [options.saturate=0] Value to saturate the image (-1...1) - */ - - /** - * Apply the Saturation operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - if (this.saturation === 0) { - return; - } - var imageData = options.imageData, - data = imageData.data, len = data.length, - adjust = -this.saturation, i, max; - - for (i = 0; i < len; i += 4) { - max = Math.max(data[i], data[i + 1], data[i + 2]); - data[i] += max !== data[i] ? (max - data[i]) * adjust : 0; - data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0; - data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uSaturation: gl.getUniformLocation(program, 'uSaturation'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uSaturation, -this.saturation); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Saturation} Instance of fabric.Image.filters.Saturate - */ - fabric.Image.filters.Saturation.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Vibrance filter class - * @class fabric.Image.filters.Vibrance - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Vibrance#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Vibrance({ - * vibrance: 1 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Vibrance = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Vibrance.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Vibrance', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform float uVibrance;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'float max = max(color.r, max(color.g, color.b));\n' + - 'float avg = (color.r + color.g + color.b) / 3.0;\n' + - 'float amt = (abs(max - avg) * 2.0) * uVibrance;\n' + - 'color.r += max != color.r ? (max - color.r) * amt : 0.00;\n' + - 'color.g += max != color.g ? (max - color.g) * amt : 0.00;\n' + - 'color.b += max != color.b ? (max - color.b) * amt : 0.00;\n' + - 'gl_FragColor = color;\n' + - '}', - - /** - * Vibrance value, from -1 to 1. - * Increases/decreases the saturation of more muted colors with less effect on saturated colors. - * A value of 0 has no effect. - * - * @param {Number} vibrance - * @default - */ - vibrance: 0, - - mainParameter: 'vibrance', - - /** - * Constructor - * @memberOf fabric.Image.filters.Vibrance.prototype - * @param {Object} [options] Options object - * @param {Number} [options.vibrance=0] Vibrance value for the image (between -1 and 1) - */ - - /** - * Apply the Vibrance operation to a Uint8ClampedArray representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. - */ - applyTo2d: function(options) { - if (this.vibrance === 0) { - return; - } - var imageData = options.imageData, - data = imageData.data, len = data.length, - adjust = -this.vibrance, i, max, avg, amt; - - for (i = 0; i < len; i += 4) { - max = Math.max(data[i], data[i + 1], data[i + 2]); - avg = (data[i] + data[i + 1] + data[i + 2]) / 3; - amt = ((Math.abs(max - avg) * 2 / 255) * adjust); - data[i] += max !== data[i] ? (max - data[i]) * amt : 0; - data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * amt : 0; - data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * amt : 0; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uVibrance: gl.getUniformLocation(program, 'uVibrance'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform1f(uniformLocations.uVibrance, -this.vibrance); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {Function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Vibrance} Instance of fabric.Image.filters.Vibrance - */ - fabric.Image.filters.Vibrance.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Blur filter class - * @class fabric.Image.filters.Blur - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Blur#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Blur({ - * blur: 0.5 - * }); - * object.filters.push(filter); - * object.applyFilters(); - * canvas.renderAll(); - */ - filters.Blur = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blur.prototype */ { - - type: 'Blur', - - /* -'gl_FragColor = vec4(0.0);', -'gl_FragColor += texture2D(texture, vTexCoord + -7 * uDelta)*0.0044299121055113265;', -'gl_FragColor += texture2D(texture, vTexCoord + -6 * uDelta)*0.00895781211794;', -'gl_FragColor += texture2D(texture, vTexCoord + -5 * uDelta)*0.0215963866053;', -'gl_FragColor += texture2D(texture, vTexCoord + -4 * uDelta)*0.0443683338718;', -'gl_FragColor += texture2D(texture, vTexCoord + -3 * uDelta)*0.0776744219933;', -'gl_FragColor += texture2D(texture, vTexCoord + -2 * uDelta)*0.115876621105;', -'gl_FragColor += texture2D(texture, vTexCoord + -1 * uDelta)*0.147308056121;', -'gl_FragColor += texture2D(texture, vTexCoord )*0.159576912161;', -'gl_FragColor += texture2D(texture, vTexCoord + 1 * uDelta)*0.147308056121;', -'gl_FragColor += texture2D(texture, vTexCoord + 2 * uDelta)*0.115876621105;', -'gl_FragColor += texture2D(texture, vTexCoord + 3 * uDelta)*0.0776744219933;', -'gl_FragColor += texture2D(texture, vTexCoord + 4 * uDelta)*0.0443683338718;', -'gl_FragColor += texture2D(texture, vTexCoord + 5 * uDelta)*0.0215963866053;', -'gl_FragColor += texture2D(texture, vTexCoord + 6 * uDelta)*0.00895781211794;', -'gl_FragColor += texture2D(texture, vTexCoord + 7 * uDelta)*0.0044299121055113265;', -*/ - - /* eslint-disable max-len */ - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform vec2 uDelta;\n' + - 'varying vec2 vTexCoord;\n' + - 'const float nSamples = 15.0;\n' + - 'vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\n' + - 'float random(vec3 scale) {\n' + - /* use the fragment position for a different seed per-pixel */ - 'return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\n' + - '}\n' + - 'void main() {\n' + - 'vec4 color = vec4(0.0);\n' + - 'float total = 0.0;\n' + - 'float offset = random(v3offset);\n' + - 'for (float t = -nSamples; t <= nSamples; t++) {\n' + - 'float percent = (t + offset - 0.5) / nSamples;\n' + - 'float weight = 1.0 - abs(percent);\n' + - 'color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\n' + - 'total += weight;\n' + - '}\n' + - 'gl_FragColor = color / total;\n' + - '}', - /* eslint-enable max-len */ - - /** - * blur value, in percentage of image dimensions. - * specific to keep the image blur constant at different resolutions - * range between 0 and 1. - * @type Number - * @default - */ - blur: 0, - - mainParameter: 'blur', - - applyTo: function(options) { - if (options.webgl) { - // this aspectRatio is used to give the same blur to vertical and horizontal - this.aspectRatio = options.sourceWidth / options.sourceHeight; - options.passes++; - this._setupFrameBuffer(options); - this.horizontal = true; - this.applyToWebGL(options); - this._swapTextures(options); - this._setupFrameBuffer(options); - this.horizontal = false; - this.applyToWebGL(options); - this._swapTextures(options); - } - else { - this.applyTo2d(options); - } - }, - - applyTo2d: function(options) { - // paint canvasEl with current image data. - //options.ctx.putImageData(options.imageData, 0, 0); - options.imageData = this.simpleBlur(options); - }, - - simpleBlur: function(options) { - var resources = options.filterBackend.resources, canvas1, canvas2, - width = options.imageData.width, - height = options.imageData.height; - - if (!resources.blurLayer1) { - resources.blurLayer1 = fabric.util.createCanvasElement(); - resources.blurLayer2 = fabric.util.createCanvasElement(); - } - canvas1 = resources.blurLayer1; - canvas2 = resources.blurLayer2; - if (canvas1.width !== width || canvas1.height !== height) { - canvas2.width = canvas1.width = width; - canvas2.height = canvas1.height = height; - } - var ctx1 = canvas1.getContext('2d'), - ctx2 = canvas2.getContext('2d'), - nSamples = 15, - random, percent, j, i, - blur = this.blur * 0.06 * 0.5; - - // load first canvas - ctx1.putImageData(options.imageData, 0, 0); - ctx2.clearRect(0, 0, width, height); - - for (i = -nSamples; i <= nSamples; i++) { - random = (Math.random() - 0.5) / 4; - percent = i / nSamples; - j = blur * percent * width + random; - ctx2.globalAlpha = 1 - Math.abs(percent); - ctx2.drawImage(canvas1, j, random); - ctx1.drawImage(canvas2, 0, 0); - ctx2.globalAlpha = 1; - ctx2.clearRect(0, 0, canvas2.width, canvas2.height); - } - for (i = -nSamples; i <= nSamples; i++) { - random = (Math.random() - 0.5) / 4; - percent = i / nSamples; - j = blur * percent * height + random; - ctx2.globalAlpha = 1 - Math.abs(percent); - ctx2.drawImage(canvas1, random, j); - ctx1.drawImage(canvas2, 0, 0); - ctx2.globalAlpha = 1; - ctx2.clearRect(0, 0, canvas2.width, canvas2.height); - } - options.ctx.drawImage(canvas1, 0, 0); - var newImageData = options.ctx.getImageData(0, 0, canvas1.width, canvas1.height); - ctx1.globalAlpha = 1; - ctx1.clearRect(0, 0, canvas1.width, canvas1.height); - return newImageData; - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - delta: gl.getUniformLocation(program, 'uDelta'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - var delta = this.chooseRightDelta(); - gl.uniform2fv(uniformLocations.delta, delta); - }, - - /** - * choose right value of image percentage to blur with - * @returns {Array} a numeric array with delta values - */ - chooseRightDelta: function() { - var blurScale = 1, delta = [0, 0], blur; - if (this.horizontal) { - if (this.aspectRatio > 1) { - // image is wide, i want to shrink radius horizontal - blurScale = 1 / this.aspectRatio; - } - } - else { - if (this.aspectRatio < 1) { - // image is tall, i want to shrink radius vertical - blurScale = this.aspectRatio; - } - } - blur = blurScale * this.blur * 0.12; - if (this.horizontal) { - delta[0] = blur; - } - else { - delta[1] = blur; - } - return delta; - }, - }); - - /** - * Deserialize a JSON definition of a BlurFilter into a concrete instance. - */ - filters.Blur.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * Gamma filter class - * @class fabric.Image.filters.Gamma - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.Gamma#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.Gamma({ - * gamma: [1, 0.5, 2.1] - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.Gamma = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Gamma.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'Gamma', - - fragmentSource: 'precision highp float;\n' + - 'uniform sampler2D uTexture;\n' + - 'uniform vec3 uGamma;\n' + - 'varying vec2 vTexCoord;\n' + - 'void main() {\n' + - 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'vec3 correction = (1.0 / uGamma);\n' + - 'color.r = pow(color.r, correction.r);\n' + - 'color.g = pow(color.g, correction.g);\n' + - 'color.b = pow(color.b, correction.b);\n' + - 'gl_FragColor = color;\n' + - 'gl_FragColor.rgb *= color.a;\n' + - '}', - - /** - * Gamma array value, from 0.01 to 2.2. - * @param {Array} gamma - * @default - */ - gamma: [1, 1, 1], - - /** - * Describe the property that is the filter parameter - * @param {String} m - * @default - */ - mainParameter: 'gamma', - - /** - * Constructor - * @param {Object} [options] Options object - */ - initialize: function(options) { - this.gamma = [1, 1, 1]; - filters.BaseFilter.prototype.initialize.call(this, options); - }, - - /** - * Apply the Gamma operation to a Uint8Array representing the pixels of an image. - * - * @param {Object} options - * @param {ImageData} options.imageData The Uint8Array to be filtered. - */ - applyTo2d: function(options) { - var imageData = options.imageData, data = imageData.data, - gamma = this.gamma, len = data.length, - rInv = 1 / gamma[0], gInv = 1 / gamma[1], - bInv = 1 / gamma[2], i; - - if (!this.rVals) { - // eslint-disable-next-line - this.rVals = new Uint8Array(256); - // eslint-disable-next-line - this.gVals = new Uint8Array(256); - // eslint-disable-next-line - this.bVals = new Uint8Array(256); - } - - // This is an optimization - pre-compute a look-up table for each color channel - // instead of performing these pow calls for each pixel in the image. - for (i = 0, len = 256; i < len; i++) { - this.rVals[i] = Math.pow(i / 255, rInv) * 255; - this.gVals[i] = Math.pow(i / 255, gInv) * 255; - this.bVals[i] = Math.pow(i / 255, bInv) * 255; - } - for (i = 0, len = data.length; i < len; i += 4) { - data[i] = this.rVals[data[i]]; - data[i + 1] = this.gVals[data[i + 1]]; - data[i + 2] = this.bVals[data[i + 2]]; - } - }, - - /** - * Return WebGL uniform locations for this filter's shader. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {WebGLShaderProgram} program This filter's compiled shader program. - */ - getUniformLocations: function(gl, program) { - return { - uGamma: gl.getUniformLocation(program, 'uGamma'), - }; - }, - - /** - * Send data from this filter to its shader program's uniforms. - * - * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. - * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects - */ - sendUniformData: function(gl, uniformLocations) { - gl.uniform3fv(uniformLocations.uGamma, this.gamma); - }, - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.Gamma} Instance of fabric.Image.filters.Gamma - */ - fabric.Image.filters.Gamma.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * A container class that knows how to apply a sequence of filters to an input image. - */ - filters.Composed = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Composed.prototype */ { - - type: 'Composed', - - /** - * A non sparse array of filters to apply - */ - subFilters: [], - - /** - * Constructor - * @param {Object} [options] Options object - */ - initialize: function(options) { - this.callSuper('initialize', options); - // create a new array instead mutating the prototype with push - this.subFilters = this.subFilters.slice(0); - }, - - /** - * Apply this container's filters to the input image provided. - * - * @param {Object} options - * @param {Number} options.passes The number of filters remaining to be applied. - */ - applyTo: function(options) { - options.passes += this.subFilters.length - 1; - this.subFilters.forEach(function(filter) { - filter.applyTo(options); - }); - }, - - /** - * Serialize this filter into JSON. - * - * @returns {Object} A JSON representation of this filter. - */ - toObject: function() { - return fabric.util.object.extend(this.callSuper('toObject'), { - subFilters: this.subFilters.map(function(filter) { return filter.toObject(); }), - }); - }, - - isNeutralState: function() { - return !this.subFilters.some(function(filter) { return !filter.isNeutralState(); }); - } - }); - - /** - * Deserialize a JSON definition of a ComposedFilter into a concrete instance. - */ - fabric.Image.filters.Composed.fromObject = function(object, callback) { - var filters = object.subFilters || [], - subFilters = filters.map(function(filter) { - return new fabric.Image.filters[filter.type](filter); - }), - instance = new fabric.Image.filters.Composed({ subFilters: subFilters }); - callback && callback(instance); - return instance; - }; -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - filters = fabric.Image.filters, - createClass = fabric.util.createClass; - - /** - * HueRotation filter class - * @class fabric.Image.filters.HueRotation - * @memberOf fabric.Image.filters - * @extends fabric.Image.filters.BaseFilter - * @see {@link fabric.Image.filters.HueRotation#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} - * @example - * var filter = new fabric.Image.filters.HueRotation({ - * rotation: -0.5 - * }); - * object.filters.push(filter); - * object.applyFilters(); - */ - filters.HueRotation = createClass(filters.ColorMatrix, /** @lends fabric.Image.filters.HueRotation.prototype */ { - - /** - * Filter type - * @param {String} type - * @default - */ - type: 'HueRotation', - - /** - * HueRotation value, from -1 to 1. - * the unit is radians - * @param {Number} myParameter - * @default - */ - rotation: 0, - - /** - * Describe the property that is the filter parameter - * @param {String} m - * @default - */ - mainParameter: 'rotation', - - calculateMatrix: function() { - var rad = this.rotation * Math.PI, cos = fabric.util.cos(rad), sin = fabric.util.sin(rad), - aThird = 1 / 3, aThirdSqtSin = Math.sqrt(aThird) * sin, OneMinusCos = 1 - cos; - this.matrix = [ - 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0 - ]; - this.matrix[0] = cos + OneMinusCos / 3; - this.matrix[1] = aThird * OneMinusCos - aThirdSqtSin; - this.matrix[2] = aThird * OneMinusCos + aThirdSqtSin; - this.matrix[5] = aThird * OneMinusCos + aThirdSqtSin; - this.matrix[6] = cos + aThird * OneMinusCos; - this.matrix[7] = aThird * OneMinusCos - aThirdSqtSin; - this.matrix[10] = aThird * OneMinusCos - aThirdSqtSin; - this.matrix[11] = aThird * OneMinusCos + aThirdSqtSin; - this.matrix[12] = cos + aThird * OneMinusCos; - }, - - /** - * HueRotation isNeutralState implementation - * Used only in image applyFilters to discard filters that will not have an effect - * on the image - * @param {Object} options - **/ - isNeutralState: function(options) { - this.calculateMatrix(); - return filters.BaseFilter.prototype.isNeutralState.call(this, options); - }, - - /** - * Apply this filter to the input image data provided. - * - * Determines whether to use WebGL or Canvas2D based on the options.webgl flag. - * - * @param {Object} options - * @param {Number} options.passes The number of filters remaining to be executed - * @param {Boolean} options.webgl Whether to use webgl to render the filter. - * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. - * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. - * @param {WebGLRenderingContext} options.context The GL context used for rendering. - * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. - */ - applyTo: function(options) { - this.calculateMatrix(); - filters.BaseFilter.prototype.applyTo.call(this, options); - }, - - }); - - /** - * Returns filter instance from an object representation - * @static - * @param {Object} object Object to create an instance from - * @param {function} [callback] to be invoked after filter creation - * @return {fabric.Image.filters.HueRotation} Instance of fabric.Image.filters.HueRotation - */ - fabric.Image.filters.HueRotation.fromObject = fabric.Image.filters.BaseFilter.fromObject; - -})(typeof exports !== 'undefined' ? exports : this); - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = { }), - clone = fabric.util.object.clone; - - if (fabric.Text) { - fabric.warn('fabric.Text is already defined'); - return; - } - - var additionalProps = - ('fontFamily fontWeight fontSize text underline overline linethrough' + - ' textAlign fontStyle lineHeight textBackgroundColor charSpacing styles' + - ' direction path pathStartOffset pathSide pathAlign').split(' '); - - /** - * Text class - * @class fabric.Text - * @extends fabric.Object - * @return {fabric.Text} thisArg - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text} - * @see {@link fabric.Text#initialize} for constructor definition - */ - fabric.Text = fabric.util.createClass(fabric.Object, /** @lends fabric.Text.prototype */ { - - /** - * Properties which when set cause object to change dimensions - * @type Array - * @private - */ - _dimensionAffectingProps: [ - 'fontSize', - 'fontWeight', - 'fontFamily', - 'fontStyle', - 'lineHeight', - 'text', - 'charSpacing', - 'textAlign', - 'styles', - 'path', - 'pathStartOffset', - 'pathSide', - 'pathAlign' - ], - - /** - * @private - */ - _reNewline: /\r?\n/, - - /** - * Use this regular expression to filter for whitespaces that is not a new line. - * Mostly used when text is 'justify' aligned. - * @private - */ - _reSpacesAndTabs: /[ \t\r]/g, - - /** - * Use this regular expression to filter for whitespace that is not a new line. - * Mostly used when text is 'justify' aligned. - * @private - */ - _reSpaceAndTab: /[ \t\r]/, - - /** - * Use this regular expression to filter consecutive groups of non spaces. - * Mostly used when text is 'justify' aligned. - * @private - */ - _reWords: /\S+/g, - - /** - * Type of an object - * @type String - * @default - */ - type: 'text', - - /** - * Font size (in pixels) - * @type Number - * @default - */ - fontSize: 40, - - /** - * Font weight (e.g. bold, normal, 400, 600, 800) - * @type {(Number|String)} - * @default - */ - fontWeight: 'normal', - - /** - * Font family - * @type String - * @default - */ - fontFamily: 'Times New Roman', - - /** - * Text decoration underline. - * @type Boolean - * @default - */ - underline: false, - - /** - * Text decoration overline. - * @type Boolean - * @default - */ - overline: false, - - /** - * Text decoration linethrough. - * @type Boolean - * @default - */ - linethrough: false, - - /** - * Text alignment. Possible values: "left", "center", "right", "justify", - * "justify-left", "justify-center" or "justify-right". - * @type String - * @default - */ - textAlign: 'left', - - /** - * Font style . Possible values: "", "normal", "italic" or "oblique". - * @type String - * @default - */ - fontStyle: 'normal', - - /** - * Line height - * @type Number - * @default - */ - lineHeight: 1.16, - - /** - * Superscript schema object (minimum overlap) - * @type {Object} - * @default - */ - superscript: { - size: 0.60, // fontSize factor - baseline: -0.35 // baseline-shift factor (upwards) - }, - - /** - * Subscript schema object (minimum overlap) - * @type {Object} - * @default - */ - subscript: { - size: 0.60, // fontSize factor - baseline: 0.11 // baseline-shift factor (downwards) - }, - - /** - * Background color of text lines - * @type String - * @default - */ - textBackgroundColor: '', - - /** - * List of properties to consider when checking if - * state of an object is changed ({@link fabric.Object#hasStateChanged}) - * as well as for history (undo/redo) purposes - * @type Array - */ - stateProperties: fabric.Object.prototype.stateProperties.concat(additionalProps), - - /** - * List of properties to consider when checking if cache needs refresh - * @type Array - */ - cacheProperties: fabric.Object.prototype.cacheProperties.concat(additionalProps), - - /** - * When defined, an object is rendered via stroke and this property specifies its color. - * Backwards incompatibility note: This property was named "strokeStyle" until v1.1.6 - * @type String - * @default - */ - stroke: null, - - /** - * Shadow object representing shadow of this shape. - * Backwards incompatibility note: This property was named "textShadow" (String) until v1.2.11 - * @type fabric.Shadow - * @default - */ - shadow: null, - - /** - * fabric.Path that the text should follow. - * since 4.6.0 the path will be drawn automatically. - * if you want to make the path visible, give it a stroke and strokeWidth or fill value - * if you want it to be hidden, assign visible = false to the path. - * This feature is in BETA, and SVG import/export is not yet supported. - * @type fabric.Path - * @example - * var textPath = new fabric.Text('Text on a path', { - * top: 150, - * left: 150, - * textAlign: 'center', - * charSpacing: -50, - * path: new fabric.Path('M 0 0 C 50 -100 150 -100 200 0', { - * strokeWidth: 1, - * visible: false - * }), - * pathSide: 'left', - * pathStartOffset: 0 - * }); - * @default - */ - path: null, - - /** - * Offset amount for text path starting position - * Only used when text has a path - * @type Number - * @default - */ - pathStartOffset: 0, - - /** - * Which side of the path the text should be drawn on. - * Only used when text has a path - * @type {String} 'left|right' - * @default - */ - pathSide: 'left', - - /** - * How text is aligned to the path. This property determines - * the perpendicular position of each character relative to the path. - * (one of "baseline", "center", "ascender", "descender") - * This feature is in BETA, and its behavior may change - * @type String - * @default - */ - pathAlign: 'baseline', - - /** - * @private - */ - _fontSizeFraction: 0.222, - - /** - * @private - */ - offsets: { - underline: 0.10, - linethrough: -0.315, - overline: -0.88 - }, - - /** - * Text Line proportion to font Size (in pixels) - * @type Number - * @default - */ - _fontSizeMult: 1.13, - - /** - * additional space between characters - * expressed in thousands of em unit - * @type Number - * @default - */ - charSpacing: 0, - - /** - * Object containing character styles - top-level properties -> line numbers, - * 2nd-level properties - character numbers - * @type Object - * @default - */ - styles: null, - - /** - * Reference to a context to measure text char or couple of chars - * the cacheContext of the canvas will be used or a freshly created one if the object is not on canvas - * once created it will be referenced on fabric._measuringContext to avoid creating a canvas for every - * text object created. - * @type {CanvasRenderingContext2D} - * @default - */ - _measuringContext: null, - - /** - * Baseline shift, styles only, keep at 0 for the main text object - * @type {Number} - * @default - */ - deltaY: 0, - - /** - * WARNING: EXPERIMENTAL. NOT SUPPORTED YET - * determine the direction of the text. - * This has to be set manually together with textAlign and originX for proper - * experience. - * some interesting link for the future - * https://www.w3.org/International/questions/qa-bidi-unicode-controls - * @since 4.5.0 - * @type {String} 'ltr|rtl' - * @default - */ - direction: 'ltr', - - /** - * Array of properties that define a style unit (of 'styles'). - * @type {Array} - * @default - */ - _styleProperties: [ - 'stroke', - 'strokeWidth', - 'fill', - 'fontFamily', - 'fontSize', - 'fontWeight', - 'fontStyle', - 'underline', - 'overline', - 'linethrough', - 'deltaY', - 'textBackgroundColor', - ], - - /** - * contains characters bounding boxes - */ - __charBounds: [], - - /** - * use this size when measuring text. To avoid IE11 rounding errors - * @type {Number} - * @default - * @readonly - * @private - */ - CACHE_FONT_SIZE: 400, - - /** - * contains the min text width to avoid getting 0 - * @type {Number} - * @default - */ - MIN_TEXT_WIDTH: 2, - - /** - * Constructor - * @param {String} text Text string - * @param {Object} [options] Options object - * @return {fabric.Text} thisArg - */ - initialize: function(text, options) { - this.styles = options ? (options.styles || { }) : { }; - this.text = text; - this.__skipDimension = true; - this.callSuper('initialize', options); - if (this.path) { - this.setPathInfo(); - } - this.__skipDimension = false; - this.initDimensions(); - this.setCoords(); - this.setupState({ propertySet: '_dimensionAffectingProps' }); - }, - - /** - * If text has a path, it will add the extra information needed - * for path and text calculations - * @return {fabric.Text} thisArg - */ - setPathInfo: function() { - var path = this.path; - if (path) { - path.segmentsInfo = fabric.util.getPathSegmentsInfo(path.path); - } - }, - - /** - * Return a context for measurement of text string. - * if created it gets stored for reuse - * this is for internal use, please do not use it - * @private - * @param {String} text Text string - * @param {Object} [options] Options object - * @return {fabric.Text} thisArg - */ - getMeasuringContext: function() { - // if we did not return we have to measure something. - if (!fabric._measuringContext) { - fabric._measuringContext = this.canvas && this.canvas.contextCache || - fabric.util.createCanvasElement().getContext('2d'); - } - return fabric._measuringContext; - }, - - /** - * @private - * Divides text into lines of text and lines of graphemes. - */ - _splitText: function() { - var newLines = this._splitTextIntoLines(this.text); - this.textLines = newLines.lines; - this._textLines = newLines.graphemeLines; - this._unwrappedTextLines = newLines._unwrappedLines; - this._text = newLines.graphemeText; - return newLines; - }, - - /** - * Initialize or update text dimensions. - * Updates this.width and this.height with the proper values. - * Does not return dimensions. - */ - initDimensions: function() { - if (this.__skipDimension) { - return; - } - this._splitText(); - this._clearCache(); - if (this.path) { - this.width = this.path.width; - this.height = this.path.height; - } - else { - this.width = this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH; - this.height = this.calcTextHeight(); - } - if (this.textAlign.indexOf('justify') !== -1) { - // once text is measured we need to make space fatter to make justified text. - this.enlargeSpaces(); - } - this.saveState({ propertySet: '_dimensionAffectingProps' }); - }, - - /** - * Enlarge space boxes and shift the others - */ - enlargeSpaces: function() { - var diffSpace, currentLineWidth, numberOfSpaces, accumulatedSpace, line, charBound, spaces; - for (var i = 0, len = this._textLines.length; i < len; i++) { - if (this.textAlign !== 'justify' && (i === len - 1 || this.isEndOfWrapping(i))) { - continue; - } - accumulatedSpace = 0; - line = this._textLines[i]; - currentLineWidth = this.getLineWidth(i); - if (currentLineWidth < this.width && (spaces = this.textLines[i].match(this._reSpacesAndTabs))) { - numberOfSpaces = spaces.length; - diffSpace = (this.width - currentLineWidth) / numberOfSpaces; - for (var j = 0, jlen = line.length; j <= jlen; j++) { - charBound = this.__charBounds[i][j]; - if (this._reSpaceAndTab.test(line[j])) { - charBound.width += diffSpace; - charBound.kernedWidth += diffSpace; - charBound.left += accumulatedSpace; - accumulatedSpace += diffSpace; - } - else { - charBound.left += accumulatedSpace; - } - } - } - } - }, - - /** - * Detect if the text line is ended with an hard break - * text and itext do not have wrapping, return false - * @return {Boolean} - */ - isEndOfWrapping: function(lineIndex) { - return lineIndex === this._textLines.length - 1; - }, - - /** - * Detect if a line has a linebreak and so we need to account for it when moving - * and counting style. - * It return always for text and Itext. - * @return Number - */ - missingNewlineOffset: function() { - return 1; - }, - - /** - * Returns string representation of an instance - * @return {String} String representation of text object - */ - toString: function() { - return '#'; - }, - - /** - * Return the dimension and the zoom level needed to create a cache canvas - * big enough to host the object to be cached. - * @private - * @param {Object} dim.x width of object to be cached - * @param {Object} dim.y height of object to be cached - * @return {Object}.width width of canvas - * @return {Object}.height height of canvas - * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache - * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache - */ - _getCacheCanvasDimensions: function() { - var dims = this.callSuper('_getCacheCanvasDimensions'); - var fontSize = this.fontSize; - dims.width += fontSize * dims.zoomX; - dims.height += fontSize * dims.zoomY; - return dims; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - var path = this.path; - path && !path.isNotVisible() && path._render(ctx); - this._setTextStyles(ctx); - this._renderTextLinesBackground(ctx); - this._renderTextDecoration(ctx, 'underline'); - this._renderText(ctx); - this._renderTextDecoration(ctx, 'overline'); - this._renderTextDecoration(ctx, 'linethrough'); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderText: function(ctx) { - if (this.paintFirst === 'stroke') { - this._renderTextStroke(ctx); - this._renderTextFill(ctx); - } - else { - this._renderTextFill(ctx); - this._renderTextStroke(ctx); - } - }, - - /** - * Set the font parameter of the context with the object properties or with charStyle - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Object} [charStyle] object with font style properties - * @param {String} [charStyle.fontFamily] Font Family - * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix ) - * @param {String} [charStyle.fontWeight] Font weight - * @param {String} [charStyle.fontStyle] Font style (italic|normal) - */ - _setTextStyles: function(ctx, charStyle, forMeasuring) { - ctx.textBaseline = 'alphabetical'; - if (this.path) { - switch (this.pathAlign) { - case 'center': - ctx.textBaseline = 'middle'; - break; - case 'ascender': - ctx.textBaseline = 'top'; - break; - case 'descender': - ctx.textBaseline = 'bottom'; - break; - } - } - ctx.font = this._getFontDeclaration(charStyle, forMeasuring); - }, - - /** - * calculate and return the text Width measuring each line. - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @return {Number} Maximum width of fabric.Text object - */ - calcTextWidth: function() { - var maxWidth = this.getLineWidth(0); - - for (var i = 1, len = this._textLines.length; i < len; i++) { - var currentLineWidth = this.getLineWidth(i); - if (currentLineWidth > maxWidth) { - maxWidth = currentLineWidth; - } - } - return maxWidth; - }, - - /** - * @private - * @param {String} method Method name ("fillText" or "strokeText") - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {String} line Text to render - * @param {Number} left Left position of text - * @param {Number} top Top position of text - * @param {Number} lineIndex Index of a line in a text - */ - _renderTextLine: function(method, ctx, line, left, top, lineIndex) { - this._renderChars(method, ctx, line, left, top, lineIndex); - }, - - /** - * Renders the text background for lines, taking care of style - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderTextLinesBackground: function(ctx) { - if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) { - return; - } - var heightOfLine, - lineLeftOffset, originalFill = ctx.fillStyle, - line, lastColor, - leftOffset = this._getLeftOffset(), - lineTopOffset = this._getTopOffset(), - boxStart = 0, boxWidth = 0, charBox, currentColor, path = this.path, - drawStart; - - for (var i = 0, len = this._textLines.length; i < len; i++) { - heightOfLine = this.getHeightOfLine(i); - if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor', i)) { - lineTopOffset += heightOfLine; - continue; - } - line = this._textLines[i]; - lineLeftOffset = this._getLineLeftOffset(i); - boxWidth = 0; - boxStart = 0; - lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor'); - for (var j = 0, jlen = line.length; j < jlen; j++) { - charBox = this.__charBounds[i][j]; - currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor'); - if (path) { - ctx.save(); - ctx.translate(charBox.renderLeft, charBox.renderTop); - ctx.rotate(charBox.angle); - ctx.fillStyle = currentColor; - currentColor && ctx.fillRect( - -charBox.width / 2, - -heightOfLine / this.lineHeight * (1 - this._fontSizeFraction), - charBox.width, - heightOfLine / this.lineHeight - ); - ctx.restore(); - } - else if (currentColor !== lastColor) { - drawStart = leftOffset + lineLeftOffset + boxStart; - if (this.direction === 'rtl') { - drawStart = this.width - drawStart - boxWidth; - } - ctx.fillStyle = lastColor; - lastColor && ctx.fillRect( - drawStart, - lineTopOffset, - boxWidth, - heightOfLine / this.lineHeight - ); - boxStart = charBox.left; - boxWidth = charBox.width; - lastColor = currentColor; - } - else { - boxWidth += charBox.kernedWidth; - } - } - if (currentColor && !path) { - drawStart = leftOffset + lineLeftOffset + boxStart; - if (this.direction === 'rtl') { - drawStart = this.width - drawStart - boxWidth; - } - ctx.fillStyle = currentColor; - ctx.fillRect( - drawStart, - lineTopOffset, - boxWidth, - heightOfLine / this.lineHeight - ); - } - lineTopOffset += heightOfLine; - } - ctx.fillStyle = originalFill; - // if there is text background color no - // other shadows should be casted - this._removeShadow(ctx); - }, - - /** - * @private - * @param {Object} decl style declaration for cache - * @param {String} decl.fontFamily fontFamily - * @param {String} decl.fontStyle fontStyle - * @param {String} decl.fontWeight fontWeight - * @return {Object} reference to cache - */ - getFontCache: function(decl) { - var fontFamily = decl.fontFamily.toLowerCase(); - if (!fabric.charWidthsCache[fontFamily]) { - fabric.charWidthsCache[fontFamily] = { }; - } - var cache = fabric.charWidthsCache[fontFamily], - cacheProp = decl.fontStyle.toLowerCase() + '_' + (decl.fontWeight + '').toLowerCase(); - if (!cache[cacheProp]) { - cache[cacheProp] = { }; - } - return cache[cacheProp]; - }, - - /** - * measure and return the width of a single character. - * possibly overridden to accommodate different measure logic or - * to hook some external lib for character measurement - * @private - * @param {String} _char, char to be measured - * @param {Object} charStyle style of char to be measured - * @param {String} [previousChar] previous char - * @param {Object} [prevCharStyle] style of previous char - */ - _measureChar: function(_char, charStyle, previousChar, prevCharStyle) { - // first i try to return from cache - var fontCache = this.getFontCache(charStyle), fontDeclaration = this._getFontDeclaration(charStyle), - previousFontDeclaration = this._getFontDeclaration(prevCharStyle), couple = previousChar + _char, - stylesAreEqual = fontDeclaration === previousFontDeclaration, width, coupleWidth, previousWidth, - fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE, kernedWidth; - - if (previousChar && fontCache[previousChar] !== undefined) { - previousWidth = fontCache[previousChar]; - } - if (fontCache[_char] !== undefined) { - kernedWidth = width = fontCache[_char]; - } - if (stylesAreEqual && fontCache[couple] !== undefined) { - coupleWidth = fontCache[couple]; - kernedWidth = coupleWidth - previousWidth; - } - if (width === undefined || previousWidth === undefined || coupleWidth === undefined) { - var ctx = this.getMeasuringContext(); - // send a TRUE to specify measuring font size CACHE_FONT_SIZE - this._setTextStyles(ctx, charStyle, true); - } - if (width === undefined) { - kernedWidth = width = ctx.measureText(_char).width; - fontCache[_char] = width; - } - if (previousWidth === undefined && stylesAreEqual && previousChar) { - previousWidth = ctx.measureText(previousChar).width; - fontCache[previousChar] = previousWidth; - } - if (stylesAreEqual && coupleWidth === undefined) { - // we can measure the kerning couple and subtract the width of the previous character - coupleWidth = ctx.measureText(couple).width; - fontCache[couple] = coupleWidth; - kernedWidth = coupleWidth - previousWidth; - } - return { width: width * fontMultiplier, kernedWidth: kernedWidth * fontMultiplier }; - }, - - /** - * Computes height of character at given position - * @param {Number} line the line index number - * @param {Number} _char the character index number - * @return {Number} fontSize of the character - */ - getHeightOfChar: function(line, _char) { - return this.getValueOfPropertyAt(line, _char, 'fontSize'); - }, - - /** - * measure a text line measuring all characters. - * @param {Number} lineIndex line number - * @return {Number} Line width - */ - measureLine: function(lineIndex) { - var lineInfo = this._measureLine(lineIndex); - if (this.charSpacing !== 0) { - lineInfo.width -= this._getWidthOfCharSpacing(); - } - if (lineInfo.width < 0) { - lineInfo.width = 0; - } - return lineInfo; - }, - - /** - * measure every grapheme of a line, populating __charBounds - * @param {Number} lineIndex - * @return {Object} object.width total width of characters - * @return {Object} object.widthOfSpaces length of chars that match this._reSpacesAndTabs - */ - _measureLine: function(lineIndex) { - var width = 0, i, grapheme, line = this._textLines[lineIndex], prevGrapheme, - graphemeInfo, numOfSpaces = 0, lineBounds = new Array(line.length), - positionInPath = 0, startingPoint, totalPathLength, path = this.path, - reverse = this.pathSide === 'right'; - - this.__charBounds[lineIndex] = lineBounds; - for (i = 0; i < line.length; i++) { - grapheme = line[i]; - graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme); - lineBounds[i] = graphemeInfo; - width += graphemeInfo.kernedWidth; - prevGrapheme = grapheme; - } - // this latest bound box represent the last character of the line - // to simplify cursor handling in interactive mode. - lineBounds[i] = { - left: graphemeInfo ? graphemeInfo.left + graphemeInfo.width : 0, - width: 0, - kernedWidth: 0, - height: this.fontSize - }; - if (path) { - totalPathLength = path.segmentsInfo[path.segmentsInfo.length - 1].length; - startingPoint = fabric.util.getPointOnPath(path.path, 0, path.segmentsInfo); - startingPoint.x += path.pathOffset.x; - startingPoint.y += path.pathOffset.y; - switch (this.textAlign) { - case 'left': - positionInPath = reverse ? (totalPathLength - width) : 0; - break; - case 'center': - positionInPath = (totalPathLength - width) / 2; - break; - case 'right': - positionInPath = reverse ? 0 : (totalPathLength - width); - break; - //todo - add support for justify - } - positionInPath += this.pathStartOffset * (reverse ? -1 : 1); - for (i = reverse ? line.length - 1 : 0; - reverse ? i >= 0 : i < line.length; - reverse ? i-- : i++) { - graphemeInfo = lineBounds[i]; - if (positionInPath > totalPathLength) { - positionInPath %= totalPathLength; - } - else if (positionInPath < 0) { - positionInPath += totalPathLength; - } - // it would probably much faster to send all the grapheme position for a line - // and calculate path position/angle at once. - this._setGraphemeOnPath(positionInPath, graphemeInfo, startingPoint); - positionInPath += graphemeInfo.kernedWidth; - } - } - return { width: width, numOfSpaces: numOfSpaces }; - }, - - /** - * Calculate the angle and the left,top position of the char that follow a path. - * It appends it to graphemeInfo to be reused later at rendering - * @private - * @param {Number} positionInPath to be measured - * @param {Object} graphemeInfo current grapheme box information - * @param {Object} startingPoint position of the point - */ - _setGraphemeOnPath: function(positionInPath, graphemeInfo, startingPoint) { - var centerPosition = positionInPath + graphemeInfo.kernedWidth / 2, - path = this.path; - - // we are at currentPositionOnPath. we want to know what point on the path is. - var info = fabric.util.getPointOnPath(path.path, centerPosition, path.segmentsInfo); - graphemeInfo.renderLeft = info.x - startingPoint.x; - graphemeInfo.renderTop = info.y - startingPoint.y; - graphemeInfo.angle = info.angle + (this.pathSide === 'right' ? Math.PI : 0); - }, - - /** - * Measure and return the info of a single grapheme. - * needs the the info of previous graphemes already filled - * @private - * @param {String} grapheme to be measured - * @param {Number} lineIndex index of the line where the char is - * @param {Number} charIndex position in the line - * @param {String} [prevGrapheme] character preceding the one to be measured - */ - _getGraphemeBox: function(grapheme, lineIndex, charIndex, prevGrapheme, skipLeft) { - var style = this.getCompleteStyleDeclaration(lineIndex, charIndex), - prevStyle = prevGrapheme ? this.getCompleteStyleDeclaration(lineIndex, charIndex - 1) : { }, - info = this._measureChar(grapheme, style, prevGrapheme, prevStyle), - kernedWidth = info.kernedWidth, - width = info.width, charSpacing; - - if (this.charSpacing !== 0) { - charSpacing = this._getWidthOfCharSpacing(); - width += charSpacing; - kernedWidth += charSpacing; - } - - var box = { - width: width, - left: 0, - height: style.fontSize, - kernedWidth: kernedWidth, - deltaY: style.deltaY, - }; - if (charIndex > 0 && !skipLeft) { - var previousBox = this.__charBounds[lineIndex][charIndex - 1]; - box.left = previousBox.left + previousBox.width + info.kernedWidth - info.width; - } - return box; - }, - - /** - * Calculate height of line at 'lineIndex' - * @param {Number} lineIndex index of line to calculate - * @return {Number} - */ - getHeightOfLine: function(lineIndex) { - if (this.__lineHeights[lineIndex]) { - return this.__lineHeights[lineIndex]; - } - - var line = this._textLines[lineIndex], - // char 0 is measured before the line cycle because it nneds to char - // emptylines - maxHeight = this.getHeightOfChar(lineIndex, 0); - for (var i = 1, len = line.length; i < len; i++) { - maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight); - } - - return this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult; - }, - - /** - * Calculate text box height - */ - calcTextHeight: function() { - var lineHeight, height = 0; - for (var i = 0, len = this._textLines.length; i < len; i++) { - lineHeight = this.getHeightOfLine(i); - height += (i === len - 1 ? lineHeight / this.lineHeight : lineHeight); - } - return height; - }, - - /** - * @private - * @return {Number} Left offset - */ - _getLeftOffset: function() { - return this.direction === 'ltr' ? -this.width / 2 : this.width / 2; - }, - - /** - * @private - * @return {Number} Top offset - */ - _getTopOffset: function() { - return -this.height / 2; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {String} method Method name ("fillText" or "strokeText") - */ - _renderTextCommon: function(ctx, method) { - ctx.save(); - var lineHeights = 0, left = this._getLeftOffset(), top = this._getTopOffset(); - for (var i = 0, len = this._textLines.length; i < len; i++) { - var heightOfLine = this.getHeightOfLine(i), - maxHeight = heightOfLine / this.lineHeight, - leftOffset = this._getLineLeftOffset(i); - this._renderTextLine( - method, - ctx, - this._textLines[i], - left + leftOffset, - top + lineHeights + maxHeight, - i - ); - lineHeights += heightOfLine; - } - ctx.restore(); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderTextFill: function(ctx) { - if (!this.fill && !this.styleHas('fill')) { - return; - } - - this._renderTextCommon(ctx, 'fillText'); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderTextStroke: function(ctx) { - if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) { - return; - } - - if (this.shadow && !this.shadow.affectStroke) { - this._removeShadow(ctx); - } - - ctx.save(); - this._setLineDash(ctx, this.strokeDashArray); - ctx.beginPath(); - this._renderTextCommon(ctx, 'strokeText'); - ctx.closePath(); - ctx.restore(); - }, - - /** - * @private - * @param {String} method fillText or strokeText. - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Array} line Content of the line, splitted in an array by grapheme - * @param {Number} left - * @param {Number} top - * @param {Number} lineIndex - */ - _renderChars: function(method, ctx, line, left, top, lineIndex) { - // set proper line offset - var lineHeight = this.getHeightOfLine(lineIndex), - isJustify = this.textAlign.indexOf('justify') !== -1, - actualStyle, - nextStyle, - charsToRender = '', - charBox, - boxWidth = 0, - timeToRender, - path = this.path, - shortCut = !isJustify && this.charSpacing === 0 && this.isEmptyStyles(lineIndex) && !path, - isLtr = this.direction === 'ltr', sign = this.direction === 'ltr' ? 1 : -1, - drawingLeft, currentDirection = ctx.canvas.getAttribute('dir'); - ctx.save(); - if (currentDirection !== this.direction) { - ctx.canvas.setAttribute('dir', isLtr ? 'ltr' : 'rtl'); - ctx.direction = isLtr ? 'ltr' : 'rtl'; - ctx.textAlign = isLtr ? 'left' : 'right'; - } - top -= lineHeight * this._fontSizeFraction / this.lineHeight; - if (shortCut) { - // render all the line in one pass without checking - // drawingLeft = isLtr ? left : left - this.getLineWidth(lineIndex); - this._renderChar(method, ctx, lineIndex, 0, line.join(''), left, top, lineHeight); - ctx.restore(); - return; - } - for (var i = 0, len = line.length - 1; i <= len; i++) { - timeToRender = i === len || this.charSpacing || path; - charsToRender += line[i]; - charBox = this.__charBounds[lineIndex][i]; - if (boxWidth === 0) { - left += sign * (charBox.kernedWidth - charBox.width); - boxWidth += charBox.width; - } - else { - boxWidth += charBox.kernedWidth; - } - if (isJustify && !timeToRender) { - if (this._reSpaceAndTab.test(line[i])) { - timeToRender = true; - } - } - if (!timeToRender) { - // if we have charSpacing, we render char by char - actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i); - nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1); - timeToRender = this._hasStyleChanged(actualStyle, nextStyle); - } - if (timeToRender) { - if (path) { - ctx.save(); - ctx.translate(charBox.renderLeft, charBox.renderTop); - ctx.rotate(charBox.angle); - this._renderChar(method, ctx, lineIndex, i, charsToRender, -boxWidth / 2, 0, lineHeight); - ctx.restore(); - } - else { - drawingLeft = left; - this._renderChar(method, ctx, lineIndex, i, charsToRender, drawingLeft, top, lineHeight); - } - charsToRender = ''; - actualStyle = nextStyle; - left += sign * boxWidth; - boxWidth = 0; - } - } - ctx.restore(); - }, - - /** - * This function try to patch the missing gradientTransform on canvas gradients. - * transforming a context to transform the gradient, is going to transform the stroke too. - * we want to transform the gradient but not the stroke operation, so we create - * a transformed gradient on a pattern and then we use the pattern instead of the gradient. - * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size - * is limited. - * @private - * @param {fabric.Gradient} filler a fabric gradient instance - * @return {CanvasPattern} a pattern to use as fill/stroke style - */ - _applyPatternGradientTransformText: function(filler) { - var pCanvas = fabric.util.createCanvasElement(), pCtx, - // TODO: verify compatibility with strokeUniform - width = this.width + this.strokeWidth, height = this.height + this.strokeWidth; - pCanvas.width = width; - pCanvas.height = height; - pCtx = pCanvas.getContext('2d'); - pCtx.beginPath(); pCtx.moveTo(0, 0); pCtx.lineTo(width, 0); pCtx.lineTo(width, height); - pCtx.lineTo(0, height); pCtx.closePath(); - pCtx.translate(width / 2, height / 2); - pCtx.fillStyle = filler.toLive(pCtx); - this._applyPatternGradientTransform(pCtx, filler); - pCtx.fill(); - return pCtx.createPattern(pCanvas, 'no-repeat'); - }, - - handleFiller: function(ctx, property, filler) { - var offsetX, offsetY; - if (filler.toLive) { - if (filler.gradientUnits === 'percentage' || filler.gradientTransform || filler.patternTransform) { - // need to transform gradient in a pattern. - // this is a slow process. If you are hitting this codepath, and the object - // is not using caching, you should consider switching it on. - // we need a canvas as big as the current object caching canvas. - offsetX = -this.width / 2; - offsetY = -this.height / 2; - ctx.translate(offsetX, offsetY); - ctx[property] = this._applyPatternGradientTransformText(filler); - return { offsetX: offsetX, offsetY: offsetY }; - } - else { - // is a simple gradient or pattern - ctx[property] = filler.toLive(ctx, this); - return this._applyPatternGradientTransform(ctx, filler); - } - } - else { - // is a color - ctx[property] = filler; - } - return { offsetX: 0, offsetY: 0 }; - }, - - _setStrokeStyles: function(ctx, decl) { - ctx.lineWidth = decl.strokeWidth; - ctx.lineCap = this.strokeLineCap; - ctx.lineDashOffset = this.strokeDashOffset; - ctx.lineJoin = this.strokeLineJoin; - ctx.miterLimit = this.strokeMiterLimit; - return this.handleFiller(ctx, 'strokeStyle', decl.stroke); - }, - - _setFillStyles: function(ctx, decl) { - return this.handleFiller(ctx, 'fillStyle', decl.fill); - }, - - /** - * @private - * @param {String} method - * @param {CanvasRenderingContext2D} ctx Context to render on - * @param {Number} lineIndex - * @param {Number} charIndex - * @param {String} _char - * @param {Number} left Left coordinate - * @param {Number} top Top coordinate - * @param {Number} lineHeight Height of the line - */ - _renderChar: function(method, ctx, lineIndex, charIndex, _char, left, top) { - var decl = this._getStyleDeclaration(lineIndex, charIndex), - fullDecl = this.getCompleteStyleDeclaration(lineIndex, charIndex), - shouldFill = method === 'fillText' && fullDecl.fill, - shouldStroke = method === 'strokeText' && fullDecl.stroke && fullDecl.strokeWidth, - fillOffsets, strokeOffsets; - - if (!shouldStroke && !shouldFill) { - return; - } - ctx.save(); - - shouldFill && (fillOffsets = this._setFillStyles(ctx, fullDecl)); - shouldStroke && (strokeOffsets = this._setStrokeStyles(ctx, fullDecl)); - - ctx.font = this._getFontDeclaration(fullDecl); - - - if (decl && decl.textBackgroundColor) { - this._removeShadow(ctx); - } - if (decl && decl.deltaY) { - top += decl.deltaY; - } - shouldFill && ctx.fillText(_char, left - fillOffsets.offsetX, top - fillOffsets.offsetY); - shouldStroke && ctx.strokeText(_char, left - strokeOffsets.offsetX, top - strokeOffsets.offsetY); - ctx.restore(); - }, - - /** - * Turns the character into a 'superior figure' (i.e. 'superscript') - * @param {Number} start selection start - * @param {Number} end selection end - * @returns {fabric.Text} thisArg - * @chainable - */ - setSuperscript: function(start, end) { - return this._setScript(start, end, this.superscript); - }, - - /** - * Turns the character into an 'inferior figure' (i.e. 'subscript') - * @param {Number} start selection start - * @param {Number} end selection end - * @returns {fabric.Text} thisArg - * @chainable - */ - setSubscript: function(start, end) { - return this._setScript(start, end, this.subscript); - }, - - /** - * Applies 'schema' at given position - * @private - * @param {Number} start selection start - * @param {Number} end selection end - * @param {Number} schema - * @returns {fabric.Text} thisArg - * @chainable - */ - _setScript: function(start, end, schema) { - var loc = this.get2DCursorLocation(start, true), - fontSize = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'fontSize'), - dy = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'deltaY'), - style = { fontSize: fontSize * schema.size, deltaY: dy + fontSize * schema.baseline }; - this.setSelectionStyles(style, start, end); - return this; - }, - - /** - * @private - * @param {Object} prevStyle - * @param {Object} thisStyle - */ - _hasStyleChanged: function(prevStyle, thisStyle) { - return prevStyle.fill !== thisStyle.fill || - prevStyle.stroke !== thisStyle.stroke || - prevStyle.strokeWidth !== thisStyle.strokeWidth || - prevStyle.fontSize !== thisStyle.fontSize || - prevStyle.fontFamily !== thisStyle.fontFamily || - prevStyle.fontWeight !== thisStyle.fontWeight || - prevStyle.fontStyle !== thisStyle.fontStyle || - prevStyle.deltaY !== thisStyle.deltaY; - }, - - /** - * @private - * @param {Object} prevStyle - * @param {Object} thisStyle - */ - _hasStyleChangedForSvg: function(prevStyle, thisStyle) { - return this._hasStyleChanged(prevStyle, thisStyle) || - prevStyle.overline !== thisStyle.overline || - prevStyle.underline !== thisStyle.underline || - prevStyle.linethrough !== thisStyle.linethrough; - }, - - /** - * @private - * @param {Number} lineIndex index text line - * @return {Number} Line left offset - */ - _getLineLeftOffset: function(lineIndex) { - var lineWidth = this.getLineWidth(lineIndex), - lineDiff = this.width - lineWidth, textAlign = this.textAlign, direction = this.direction, - isEndOfWrapping, leftOffset = 0, isEndOfWrapping = this.isEndOfWrapping(lineIndex); - if (textAlign === 'justify' - || (textAlign === 'justify-center' && !isEndOfWrapping) - || (textAlign === 'justify-right' && !isEndOfWrapping) - || (textAlign === 'justify-left' && !isEndOfWrapping) - ) { - return 0; - } - if (textAlign === 'center') { - leftOffset = lineDiff / 2; - } - if (textAlign === 'right') { - leftOffset = lineDiff; - } - if (textAlign === 'justify-center') { - leftOffset = lineDiff / 2; - } - if (textAlign === 'justify-right') { - leftOffset = lineDiff; - } - if (direction === 'rtl') { - leftOffset -= lineDiff; - } - return leftOffset; - }, - - /** - * @private - */ - _clearCache: function() { - this.__lineWidths = []; - this.__lineHeights = []; - this.__charBounds = []; - }, - - /** - * @private - */ - _shouldClearDimensionCache: function() { - var shouldClear = this._forceClearCache; - shouldClear || (shouldClear = this.hasStateChanged('_dimensionAffectingProps')); - if (shouldClear) { - this.dirty = true; - this._forceClearCache = false; - } - return shouldClear; - }, - - /** - * Measure a single line given its index. Used to calculate the initial - * text bounding box. The values are calculated and stored in __lineWidths cache. - * @private - * @param {Number} lineIndex line number - * @return {Number} Line width - */ - getLineWidth: function(lineIndex) { - if (this.__lineWidths[lineIndex] !== undefined) { - return this.__lineWidths[lineIndex]; - } - - var lineInfo = this.measureLine(lineIndex); - var width = lineInfo.width; - this.__lineWidths[lineIndex] = width; - return width; - }, - - _getWidthOfCharSpacing: function() { - if (this.charSpacing !== 0) { - return this.fontSize * this.charSpacing / 1000; - } - return 0; - }, - - /** - * Retrieves the value of property at given character position - * @param {Number} lineIndex the line number - * @param {Number} charIndex the character number - * @param {String} property the property name - * @returns the value of 'property' - */ - getValueOfPropertyAt: function(lineIndex, charIndex, property) { - var charStyle = this._getStyleDeclaration(lineIndex, charIndex); - if (charStyle && typeof charStyle[property] !== 'undefined') { - return charStyle[property]; - } - return this[property]; - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _renderTextDecoration: function(ctx, type) { - if (!this[type] && !this.styleHas(type)) { - return; - } - var heightOfLine, size, _size, - lineLeftOffset, dy, _dy, - line, lastDecoration, - leftOffset = this._getLeftOffset(), - topOffset = this._getTopOffset(), top, - boxStart, boxWidth, charBox, currentDecoration, - maxHeight, currentFill, lastFill, path = this.path, - charSpacing = this._getWidthOfCharSpacing(), - offsetY = this.offsets[type]; - - for (var i = 0, len = this._textLines.length; i < len; i++) { - heightOfLine = this.getHeightOfLine(i); - if (!this[type] && !this.styleHas(type, i)) { - topOffset += heightOfLine; - continue; - } - line = this._textLines[i]; - maxHeight = heightOfLine / this.lineHeight; - lineLeftOffset = this._getLineLeftOffset(i); - boxStart = 0; - boxWidth = 0; - lastDecoration = this.getValueOfPropertyAt(i, 0, type); - lastFill = this.getValueOfPropertyAt(i, 0, 'fill'); - top = topOffset + maxHeight * (1 - this._fontSizeFraction); - size = this.getHeightOfChar(i, 0); - dy = this.getValueOfPropertyAt(i, 0, 'deltaY'); - for (var j = 0, jlen = line.length; j < jlen; j++) { - charBox = this.__charBounds[i][j]; - currentDecoration = this.getValueOfPropertyAt(i, j, type); - currentFill = this.getValueOfPropertyAt(i, j, 'fill'); - _size = this.getHeightOfChar(i, j); - _dy = this.getValueOfPropertyAt(i, j, 'deltaY'); - if (path && currentDecoration && currentFill) { - ctx.save(); - ctx.fillStyle = lastFill; - ctx.translate(charBox.renderLeft, charBox.renderTop); - ctx.rotate(charBox.angle); - ctx.fillRect( - -charBox.kernedWidth / 2, - offsetY * _size + _dy, - charBox.kernedWidth, - this.fontSize / 15 - ); - ctx.restore(); - } - else if ( - (currentDecoration !== lastDecoration || currentFill !== lastFill || _size !== size || _dy !== dy) - && boxWidth > 0 - ) { - var drawStart = leftOffset + lineLeftOffset + boxStart; - if (this.direction === 'rtl') { - drawStart = this.width - drawStart - boxWidth; - } - if (lastDecoration && lastFill) { - ctx.fillStyle = lastFill; - ctx.fillRect( - drawStart, - top + offsetY * size + dy, - boxWidth, - this.fontSize / 15 - ); - } - boxStart = charBox.left; - boxWidth = charBox.width; - lastDecoration = currentDecoration; - lastFill = currentFill; - size = _size; - dy = _dy; - } - else { - boxWidth += charBox.kernedWidth; - } - } - var drawStart = leftOffset + lineLeftOffset + boxStart; - if (this.direction === 'rtl') { - drawStart = this.width - drawStart - boxWidth; - } - ctx.fillStyle = currentFill; - currentDecoration && currentFill && ctx.fillRect( - drawStart, - top + offsetY * size + dy, - boxWidth - charSpacing, - this.fontSize / 15 - ); - topOffset += heightOfLine; - } - // if there is text background color no - // other shadows should be casted - this._removeShadow(ctx); - }, - - /** - * return font declaration string for canvas context - * @param {Object} [styleObject] object - * @returns {String} font declaration formatted for canvas context. - */ - _getFontDeclaration: function(styleObject, forMeasuring) { - var style = styleObject || this, family = this.fontFamily, - fontIsGeneric = fabric.Text.genericFonts.indexOf(family.toLowerCase()) > -1; - var fontFamily = family === undefined || - family.indexOf('\'') > -1 || family.indexOf(',') > -1 || - family.indexOf('"') > -1 || fontIsGeneric - ? style.fontFamily : '"' + style.fontFamily + '"'; - return [ - // node-canvas needs "weight style", while browsers need "style weight" - // verify if this can be fixed in JSDOM - (fabric.isLikelyNode ? style.fontWeight : style.fontStyle), - (fabric.isLikelyNode ? style.fontStyle : style.fontWeight), - forMeasuring ? this.CACHE_FONT_SIZE + 'px' : style.fontSize + 'px', - fontFamily - ].join(' '); - }, - - /** - * Renders text instance on a specified context - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - render: function(ctx) { - // do not render if object is not visible - if (!this.visible) { - return; - } - if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) { - return; - } - if (this._shouldClearDimensionCache()) { - this.initDimensions(); - } - this.callSuper('render', ctx); - }, - - /** - * Returns the text as an array of lines. - * @param {String} text text to split - * @returns {Array} Lines in the text - */ - _splitTextIntoLines: function(text) { - var lines = text.split(this._reNewline), - newLines = new Array(lines.length), - newLine = ['\n'], - newText = []; - for (var i = 0; i < lines.length; i++) { - newLines[i] = fabric.util.string.graphemeSplit(lines[i]); - newText = newText.concat(newLines[i], newLine); - } - newText.pop(); - return { _unwrappedLines: newLines, lines: lines, graphemeText: newText, graphemeLines: newLines }; - }, - - /** - * Returns object representation of an instance - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} Object representation of an instance - */ - toObject: function(propertiesToInclude) { - var allProperties = additionalProps.concat(propertiesToInclude); - var obj = this.callSuper('toObject', allProperties); - // styles will be overridden with a properly cloned structure - obj.styles = clone(this.styles, true); - if (obj.path) { - obj.path = this.path.toObject(); - } - return obj; - }, - - /** - * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`. - * @param {String|Object} key Property name or object (if object, iterate over the object properties) - * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one) - * @return {fabric.Object} thisArg - * @chainable - */ - set: function(key, value) { - this.callSuper('set', key, value); - var needsDims = false; - var isAddingPath = false; - if (typeof key === 'object') { - for (var _key in key) { - if (_key === 'path') { - this.setPathInfo(); - } - needsDims = needsDims || this._dimensionAffectingProps.indexOf(_key) !== -1; - isAddingPath = isAddingPath || _key === 'path'; - } - } - else { - needsDims = this._dimensionAffectingProps.indexOf(key) !== -1; - isAddingPath = key === 'path'; - } - if (isAddingPath) { - this.setPathInfo(); - } - if (needsDims) { - this.initDimensions(); - this.setCoords(); - } - return this; - }, - - /** - * Returns complexity of an instance - * @return {Number} complexity - */ - complexity: function() { - return 1; - } - }); - - /* _FROM_SVG_START_ */ - /** - * List of attribute names to account for when parsing SVG element (used by {@link fabric.Text.fromElement}) - * @static - * @memberOf fabric.Text - * @see: http://www.w3.org/TR/SVG/text.html#TextElement - */ - fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat( - 'x y dx dy font-family font-style font-weight font-size letter-spacing text-decoration text-anchor'.split(' ')); - - /** - * Default SVG font size - * @static - * @memberOf fabric.Text - */ - fabric.Text.DEFAULT_SVG_FONT_SIZE = 16; - - /** - * Returns fabric.Text instance from an SVG element (not yet implemented) - * @static - * @memberOf fabric.Text - * @param {SVGElement} element Element to parse - * @param {Function} callback callback function invoked after parsing - * @param {Object} [options] Options object - */ - fabric.Text.fromElement = function(element, callback, options) { - if (!element) { - return callback(null); - } - - var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES), - parsedAnchor = parsedAttributes.textAnchor || 'left'; - options = fabric.util.object.extend((options ? clone(options) : { }), parsedAttributes); - - options.top = options.top || 0; - options.left = options.left || 0; - if (parsedAttributes.textDecoration) { - var textDecoration = parsedAttributes.textDecoration; - if (textDecoration.indexOf('underline') !== -1) { - options.underline = true; - } - if (textDecoration.indexOf('overline') !== -1) { - options.overline = true; - } - if (textDecoration.indexOf('line-through') !== -1) { - options.linethrough = true; - } - delete options.textDecoration; - } - if ('dx' in parsedAttributes) { - options.left += parsedAttributes.dx; - } - if ('dy' in parsedAttributes) { - options.top += parsedAttributes.dy; - } - if (!('fontSize' in options)) { - options.fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE; - } - - var textContent = ''; - - // The XML is not properly parsed in IE9 so a workaround to get - // textContent is through firstChild.data. Another workaround would be - // to convert XML loaded from a file to be converted using DOMParser (same way loadSVGFromString() does) - if (!('textContent' in element)) { - if ('firstChild' in element && element.firstChild !== null) { - if ('data' in element.firstChild && element.firstChild.data !== null) { - textContent = element.firstChild.data; - } - } - } - else { - textContent = element.textContent; - } - - textContent = textContent.replace(/^\s+|\s+$|\n+/g, '').replace(/\s+/g, ' '); - var originalStrokeWidth = options.strokeWidth; - options.strokeWidth = 0; - - var text = new fabric.Text(textContent, options), - textHeightScaleFactor = text.getScaledHeight() / text.height, - lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height, - scaledDiff = lineHeightDiff * textHeightScaleFactor, - textHeight = text.getScaledHeight() + scaledDiff, - offX = 0; - /* - Adjust positioning: - x/y attributes in SVG correspond to the bottom-left corner of text bounding box - fabric output by default at top, left. - */ - if (parsedAnchor === 'center') { - offX = text.getScaledWidth() / 2; - } - if (parsedAnchor === 'right') { - offX = text.getScaledWidth(); - } - text.set({ - left: text.left - offX, - top: text.top - (textHeight - text.fontSize * (0.07 + text._fontSizeFraction)) / text.lineHeight, - strokeWidth: typeof originalStrokeWidth !== 'undefined' ? originalStrokeWidth : 1, - }); - callback(text); - }; - /* _FROM_SVG_END_ */ - - /** - * Returns fabric.Text instance from an object representation - * @static - * @memberOf fabric.Text - * @param {Object} object plain js Object to create an instance from - * @param {Function} [callback] Callback to invoke when an fabric.Text instance is created - */ - fabric.Text.fromObject = function(object, callback) { - var objectCopy = clone(object), path = object.path; - delete objectCopy.path; - return fabric.Object._fromObject('Text', objectCopy, function(textInstance) { - if (path) { - fabric.Object._fromObject('Path', path, function(pathInstance) { - textInstance.set('path', pathInstance); - callback(textInstance); - }, 'path'); - } - else { - callback(textInstance); - } - }, 'text'); - }; - - fabric.Text.genericFonts = ['sans-serif', 'serif', 'cursive', 'fantasy', 'monospace']; - - fabric.util.createAccessors && fabric.util.createAccessors(fabric.Text); - -})(typeof exports !== 'undefined' ? exports : this); - - -(function() { - fabric.util.object.extend(fabric.Text.prototype, /** @lends fabric.Text.prototype */ { - /** - * Returns true if object has no styling or no styling in a line - * @param {Number} lineIndex , lineIndex is on wrapped lines. - * @return {Boolean} - */ - isEmptyStyles: function(lineIndex) { - if (!this.styles) { - return true; - } - if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) { - return true; - } - var obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] }; - for (var p1 in obj) { - for (var p2 in obj[p1]) { - // eslint-disable-next-line no-unused-vars - for (var p3 in obj[p1][p2]) { - return false; - } - } - } - return true; - }, - - /** - * Returns true if object has a style property or has it ina specified line - * This function is used to detect if a text will use a particular property or not. - * @param {String} property to check for - * @param {Number} lineIndex to check the style on - * @return {Boolean} - */ - styleHas: function(property, lineIndex) { - if (!this.styles || !property || property === '') { - return false; - } - if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) { - return false; - } - var obj = typeof lineIndex === 'undefined' ? this.styles : { 0: this.styles[lineIndex] }; - // eslint-disable-next-line - for (var p1 in obj) { - // eslint-disable-next-line - for (var p2 in obj[p1]) { - if (typeof obj[p1][p2][property] !== 'undefined') { - return true; - } - } - } - return false; - }, - - /** - * Check if characters in a text have a value for a property - * whose value matches the textbox's value for that property. If so, - * the character-level property is deleted. If the character - * has no other properties, then it is also deleted. Finally, - * if the line containing that character has no other characters - * then it also is deleted. - * - * @param {string} property The property to compare between characters and text. - */ - cleanStyle: function(property) { - if (!this.styles || !property || property === '') { - return false; - } - var obj = this.styles, stylesCount = 0, letterCount, stylePropertyValue, - allStyleObjectPropertiesMatch = true, graphemeCount = 0, styleObject; - // eslint-disable-next-line - for (var p1 in obj) { - letterCount = 0; - // eslint-disable-next-line - for (var p2 in obj[p1]) { - var styleObject = obj[p1][p2], - stylePropertyHasBeenSet = styleObject.hasOwnProperty(property); - - stylesCount++; - - if (stylePropertyHasBeenSet) { - if (!stylePropertyValue) { - stylePropertyValue = styleObject[property]; - } - else if (styleObject[property] !== stylePropertyValue) { - allStyleObjectPropertiesMatch = false; - } - - if (styleObject[property] === this[property]) { - delete styleObject[property]; - } - } - else { - allStyleObjectPropertiesMatch = false; - } - - if (Object.keys(styleObject).length !== 0) { - letterCount++; - } - else { - delete obj[p1][p2]; - } - } - - if (letterCount === 0) { - delete obj[p1]; - } - } - // if every grapheme has the same style set then - // delete those styles and set it on the parent - for (var i = 0; i < this._textLines.length; i++) { - graphemeCount += this._textLines[i].length; - } - if (allStyleObjectPropertiesMatch && stylesCount === graphemeCount) { - this[property] = stylePropertyValue; - this.removeStyle(property); - } - }, - - /** - * Remove a style property or properties from all individual character styles - * in a text object. Deletes the character style object if it contains no other style - * props. Deletes a line style object if it contains no other character styles. - * - * @param {String} props The property to remove from character styles. - */ - removeStyle: function(property) { - if (!this.styles || !property || property === '') { - return; - } - var obj = this.styles, line, lineNum, charNum; - for (lineNum in obj) { - line = obj[lineNum]; - for (charNum in line) { - delete line[charNum][property]; - if (Object.keys(line[charNum]).length === 0) { - delete line[charNum]; - } - } - if (Object.keys(line).length === 0) { - delete obj[lineNum]; - } - } - }, - - /** - * @private - */ - _extendStyles: function(index, styles) { - var loc = this.get2DCursorLocation(index); - - if (!this._getLineStyle(loc.lineIndex)) { - this._setLineStyle(loc.lineIndex); - } - - if (!this._getStyleDeclaration(loc.lineIndex, loc.charIndex)) { - this._setStyleDeclaration(loc.lineIndex, loc.charIndex, {}); - } - - fabric.util.object.extend(this._getStyleDeclaration(loc.lineIndex, loc.charIndex), styles); - }, - - /** - * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start) - * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used. - * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles. - */ - get2DCursorLocation: function(selectionStart, skipWrapping) { - if (typeof selectionStart === 'undefined') { - selectionStart = this.selectionStart; - } - var lines = skipWrapping ? this._unwrappedTextLines : this._textLines, - len = lines.length; - for (var i = 0; i < len; i++) { - if (selectionStart <= lines[i].length) { - return { - lineIndex: i, - charIndex: selectionStart - }; - } - selectionStart -= lines[i].length + this.missingNewlineOffset(i); - } - return { - lineIndex: i - 1, - charIndex: lines[i - 1].length < selectionStart ? lines[i - 1].length : selectionStart - }; - }, - - /** - * Gets style of a current selection/cursor (at the start position) - * if startIndex or endIndex are not provided, selectionStart or selectionEnd will be used. - * @param {Number} [startIndex] Start index to get styles at - * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1 - * @param {Boolean} [complete] get full style or not - * @return {Array} styles an array with one, zero or more Style objects - */ - getSelectionStyles: function(startIndex, endIndex, complete) { - if (typeof startIndex === 'undefined') { - startIndex = this.selectionStart || 0; - } - if (typeof endIndex === 'undefined') { - endIndex = this.selectionEnd || startIndex; - } - var styles = []; - for (var i = startIndex; i < endIndex; i++) { - styles.push(this.getStyleAtPosition(i, complete)); - } - return styles; - }, - - /** - * Gets style of a current selection/cursor position - * @param {Number} position to get styles at - * @param {Boolean} [complete] full style if true - * @return {Object} style Style object at a specified index - * @private - */ - getStyleAtPosition: function(position, complete) { - var loc = this.get2DCursorLocation(position), - style = complete ? this.getCompleteStyleDeclaration(loc.lineIndex, loc.charIndex) : - this._getStyleDeclaration(loc.lineIndex, loc.charIndex); - return style || {}; - }, - - /** - * Sets style of a current selection, if no selection exist, do not set anything. - * @param {Object} [styles] Styles object - * @param {Number} [startIndex] Start index to get styles at - * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1 - * @return {fabric.IText} thisArg - * @chainable - */ - setSelectionStyles: function(styles, startIndex, endIndex) { - if (typeof startIndex === 'undefined') { - startIndex = this.selectionStart || 0; - } - if (typeof endIndex === 'undefined') { - endIndex = this.selectionEnd || startIndex; - } - for (var i = startIndex; i < endIndex; i++) { - this._extendStyles(i, styles); - } - /* not included in _extendStyles to avoid clearing cache more than once */ - this._forceClearCache = true; - return this; - }, - - /** - * get the reference, not a clone, of the style object for a given character - * @param {Number} lineIndex - * @param {Number} charIndex - * @return {Object} style object - */ - _getStyleDeclaration: function(lineIndex, charIndex) { - var lineStyle = this.styles && this.styles[lineIndex]; - if (!lineStyle) { - return null; - } - return lineStyle[charIndex]; - }, - - /** - * return a new object that contains all the style property for a character - * the object returned is newly created - * @param {Number} lineIndex of the line where the character is - * @param {Number} charIndex position of the character on the line - * @return {Object} style object - */ - getCompleteStyleDeclaration: function(lineIndex, charIndex) { - var style = this._getStyleDeclaration(lineIndex, charIndex) || { }, - styleObject = { }, prop; - for (var i = 0; i < this._styleProperties.length; i++) { - prop = this._styleProperties[i]; - styleObject[prop] = typeof style[prop] === 'undefined' ? this[prop] : style[prop]; - } - return styleObject; - }, - - /** - * @param {Number} lineIndex - * @param {Number} charIndex - * @param {Object} style - * @private - */ - _setStyleDeclaration: function(lineIndex, charIndex, style) { - this.styles[lineIndex][charIndex] = style; - }, - - /** - * - * @param {Number} lineIndex - * @param {Number} charIndex - * @private - */ - _deleteStyleDeclaration: function(lineIndex, charIndex) { - delete this.styles[lineIndex][charIndex]; - }, - - /** - * @param {Number} lineIndex - * @return {Boolean} if the line exists or not - * @private - */ - _getLineStyle: function(lineIndex) { - return !!this.styles[lineIndex]; - }, - - /** - * Set the line style to an empty object so that is initialized - * @param {Number} lineIndex - * @private - */ - _setLineStyle: function(lineIndex) { - this.styles[lineIndex] = {}; - }, - - /** - * @param {Number} lineIndex - * @private - */ - _deleteLineStyle: function(lineIndex) { - delete this.styles[lineIndex]; - } - }); -})(); - - -(function() { - - function parseDecoration(object) { - if (object.textDecoration) { - object.textDecoration.indexOf('underline') > -1 && (object.underline = true); - object.textDecoration.indexOf('line-through') > -1 && (object.linethrough = true); - object.textDecoration.indexOf('overline') > -1 && (object.overline = true); - delete object.textDecoration; - } - } - - /** - * IText class (introduced in v1.4) Events are also fired with "text:" - * prefix when observing canvas. - * @class fabric.IText - * @extends fabric.Text - * @mixes fabric.Observable - * - * @fires changed - * @fires selection:changed - * @fires editing:entered - * @fires editing:exited - * - * @return {fabric.IText} thisArg - * @see {@link fabric.IText#initialize} for constructor definition - * - *

    Supported key combinations:

    - *
    -   *   Move cursor:                    left, right, up, down
    -   *   Select character:               shift + left, shift + right
    -   *   Select text vertically:         shift + up, shift + down
    -   *   Move cursor by word:            alt + left, alt + right
    -   *   Select words:                   shift + alt + left, shift + alt + right
    -   *   Move cursor to line start/end:  cmd + left, cmd + right or home, end
    -   *   Select till start/end of line:  cmd + shift + left, cmd + shift + right or shift + home, shift + end
    -   *   Jump to start/end of text:      cmd + up, cmd + down
    -   *   Select till start/end of text:  cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown
    -   *   Delete character:               backspace
    -   *   Delete word:                    alt + backspace
    -   *   Delete line:                    cmd + backspace
    -   *   Forward delete:                 delete
    -   *   Copy text:                      ctrl/cmd + c
    -   *   Paste text:                     ctrl/cmd + v
    -   *   Cut text:                       ctrl/cmd + x
    -   *   Select entire text:             ctrl/cmd + a
    -   *   Quit editing                    tab or esc
    -   * 
    - * - *

    Supported mouse/touch combination

    - *
    -   *   Position cursor:                click/touch
    -   *   Create selection:               click/touch & drag
    -   *   Create selection:               click & shift + click
    -   *   Select word:                    double click
    -   *   Select line:                    triple click
    -   * 
    - */ - fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable, /** @lends fabric.IText.prototype */ { - - /** - * Type of an object - * @type String - * @default - */ - type: 'i-text', - - /** - * Index where text selection starts (or where cursor is when there is no selection) - * @type Number - * @default - */ - selectionStart: 0, - - /** - * Index where text selection ends - * @type Number - * @default - */ - selectionEnd: 0, - - /** - * Color of text selection - * @type String - * @default - */ - selectionColor: 'rgba(17,119,255,0.3)', - - /** - * Indicates whether text is in editing mode - * @type Boolean - * @default - */ - isEditing: false, - - /** - * Indicates whether a text can be edited - * @type Boolean - * @default - */ - editable: true, - - /** - * Border color of text object while it's in editing mode - * @type String - * @default - */ - editingBorderColor: 'rgba(102,153,255,0.25)', - - /** - * Width of cursor (in px) - * @type Number - * @default - */ - cursorWidth: 2, - - /** - * Color of text cursor color in editing mode. - * if not set (default) will take color from the text. - * if set to a color value that fabric can understand, it will - * be used instead of the color of the text at the current position. - * @type String - * @default - */ - cursorColor: '', - - /** - * Delay between cursor blink (in ms) - * @type Number - * @default - */ - cursorDelay: 1000, - - /** - * Duration of cursor fadein (in ms) - * @type Number - * @default - */ - cursorDuration: 600, - - /** - * Indicates whether internal text char widths can be cached - * @type Boolean - * @default - */ - caching: true, - - /** - * DOM container to append the hiddenTextarea. - * An alternative to attaching to the document.body. - * Useful to reduce laggish redraw of the full document.body tree and - * also with modals event capturing that won't let the textarea take focus. - * @type HTMLElement - * @default - */ - hiddenTextareaContainer: null, - - /** - * @private - */ - _reSpace: /\s|\n/, - - /** - * @private - */ - _currentCursorOpacity: 0, - - /** - * @private - */ - _selectionDirection: null, - - /** - * @private - */ - _abortCursorAnimation: false, - - /** - * @private - */ - __widthOfSpace: [], - - /** - * Helps determining when the text is in composition, so that the cursor - * rendering is altered. - */ - inCompositionMode: false, - - /** - * Constructor - * @param {String} text Text string - * @param {Object} [options] Options object - * @return {fabric.IText} thisArg - */ - initialize: function(text, options) { - this.callSuper('initialize', text, options); - this.initBehavior(); - }, - - /** - * Sets selection start (left boundary of a selection) - * @param {Number} index Index to set selection start to - */ - setSelectionStart: function(index) { - index = Math.max(index, 0); - this._updateAndFire('selectionStart', index); - }, - - /** - * Sets selection end (right boundary of a selection) - * @param {Number} index Index to set selection end to - */ - setSelectionEnd: function(index) { - index = Math.min(index, this.text.length); - this._updateAndFire('selectionEnd', index); - }, - - /** - * @private - * @param {String} property 'selectionStart' or 'selectionEnd' - * @param {Number} index new position of property - */ - _updateAndFire: function(property, index) { - if (this[property] !== index) { - this._fireSelectionChanged(); - this[property] = index; - } - this._updateTextarea(); - }, - - /** - * Fires the even of selection changed - * @private - */ - _fireSelectionChanged: function() { - this.fire('selection:changed'); - this.canvas && this.canvas.fire('text:selection:changed', { target: this }); - }, - - /** - * Initialize text dimensions. Render all text on given context - * or on a offscreen canvas to get the text width with measureText. - * Updates this.width and this.height with the proper values. - * Does not return dimensions. - * @private - */ - initDimensions: function() { - this.isEditing && this.initDelayedCursor(); - this.clearContextTop(); - this.callSuper('initDimensions'); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - render: function(ctx) { - this.clearContextTop(); - this.callSuper('render', ctx); - // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor - // the correct position but not at every cursor animation. - this.cursorOffsetCache = { }; - this.renderCursorOrSelection(); - }, - - /** - * @private - * @param {CanvasRenderingContext2D} ctx Context to render on - */ - _render: function(ctx) { - this.callSuper('_render', ctx); - }, - - /** - * Prepare and clean the contextTop - */ - clearContextTop: function(skipRestore) { - if (!this.isEditing || !this.canvas || !this.canvas.contextTop) { - return; - } - var ctx = this.canvas.contextTop, v = this.canvas.viewportTransform; - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - this.transform(ctx); - this._clearTextArea(ctx); - skipRestore || ctx.restore(); - }, - /** - * Renders cursor or selection (depending on what exists) - * it does on the contextTop. If contextTop is not available, do nothing. - */ - renderCursorOrSelection: function() { - if (!this.isEditing || !this.canvas || !this.canvas.contextTop) { - return; - } - var boundaries = this._getCursorBoundaries(), - ctx = this.canvas.contextTop; - this.clearContextTop(true); - if (this.selectionStart === this.selectionEnd) { - this.renderCursor(boundaries, ctx); - } - else { - this.renderSelection(boundaries, ctx); - } - ctx.restore(); - }, - - _clearTextArea: function(ctx) { - // we add 4 pixel, to be sure to do not leave any pixel out - var width = this.width + 4, height = this.height + 4; - ctx.clearRect(-width / 2, -height / 2, width, height); - }, - - /** - * Returns cursor boundaries (left, top, leftOffset, topOffset) - * @private - * @param {Array} chars Array of characters - * @param {String} typeOfBoundaries - */ - _getCursorBoundaries: function(position) { - - // left/top are left/top of entire text box - // leftOffset/topOffset are offset from that left/top point of a text box - - if (typeof position === 'undefined') { - position = this.selectionStart; - } - - var left = this._getLeftOffset(), - top = this._getTopOffset(), - offsets = this._getCursorBoundariesOffsets(position); - return { - left: left, - top: top, - leftOffset: offsets.left, - topOffset: offsets.top - }; - }, - - /** - * @private - */ - _getCursorBoundariesOffsets: function(position) { - if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) { - return this.cursorOffsetCache; - } - var lineLeftOffset, - lineIndex, - charIndex, - topOffset = 0, - leftOffset = 0, - boundaries, - cursorPosition = this.get2DCursorLocation(position); - charIndex = cursorPosition.charIndex; - lineIndex = cursorPosition.lineIndex; - for (var i = 0; i < lineIndex; i++) { - topOffset += this.getHeightOfLine(i); - } - lineLeftOffset = this._getLineLeftOffset(lineIndex); - var bound = this.__charBounds[lineIndex][charIndex]; - bound && (leftOffset = bound.left); - if (this.charSpacing !== 0 && charIndex === this._textLines[lineIndex].length) { - leftOffset -= this._getWidthOfCharSpacing(); - } - boundaries = { - top: topOffset, - left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0), - }; - if (this.direction === 'rtl') { - boundaries.left *= -1; - } - this.cursorOffsetCache = boundaries; - return this.cursorOffsetCache; - }, - - /** - * Renders cursor - * @param {Object} boundaries - * @param {CanvasRenderingContext2D} ctx transformed context to draw on - */ - renderCursor: function(boundaries, ctx) { - var cursorLocation = this.get2DCursorLocation(), - lineIndex = cursorLocation.lineIndex, - charIndex = cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0, - charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'), - multiplier = this.scaleX * this.canvas.getZoom(), - cursorWidth = this.cursorWidth / multiplier, - topOffset = boundaries.topOffset, - dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY'); - topOffset += (1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex) / this.lineHeight - - charHeight * (1 - this._fontSizeFraction); - - if (this.inCompositionMode) { - this.renderSelection(boundaries, ctx); - } - ctx.fillStyle = this.cursorColor || this.getValueOfPropertyAt(lineIndex, charIndex, 'fill'); - ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity; - ctx.fillRect( - boundaries.left + boundaries.leftOffset - cursorWidth / 2, - topOffset + boundaries.top + dy, - cursorWidth, - charHeight); - }, - - /** - * Renders text selection - * @param {Object} boundaries Object with left/top/leftOffset/topOffset - * @param {CanvasRenderingContext2D} ctx transformed context to draw on - */ - renderSelection: function(boundaries, ctx) { - - var selectionStart = this.inCompositionMode ? this.hiddenTextarea.selectionStart : this.selectionStart, - selectionEnd = this.inCompositionMode ? this.hiddenTextarea.selectionEnd : this.selectionEnd, - isJustify = this.textAlign.indexOf('justify') !== -1, - start = this.get2DCursorLocation(selectionStart), - end = this.get2DCursorLocation(selectionEnd), - startLine = start.lineIndex, - endLine = end.lineIndex, - startChar = start.charIndex < 0 ? 0 : start.charIndex, - endChar = end.charIndex < 0 ? 0 : end.charIndex; - - for (var i = startLine; i <= endLine; i++) { - var lineOffset = this._getLineLeftOffset(i) || 0, - lineHeight = this.getHeightOfLine(i), - realLineHeight = 0, boxStart = 0, boxEnd = 0; - - if (i === startLine) { - boxStart = this.__charBounds[startLine][startChar].left; - } - if (i >= startLine && i < endLine) { - boxEnd = isJustify && !this.isEndOfWrapping(i) ? this.width : this.getLineWidth(i) || 5; // WTF is this 5? - } - else if (i === endLine) { - if (endChar === 0) { - boxEnd = this.__charBounds[endLine][endChar].left; - } - else { - var charSpacing = this._getWidthOfCharSpacing(); - boxEnd = this.__charBounds[endLine][endChar - 1].left - + this.__charBounds[endLine][endChar - 1].width - charSpacing; - } - } - realLineHeight = lineHeight; - if (this.lineHeight < 1 || (i === endLine && this.lineHeight > 1)) { - lineHeight /= this.lineHeight; - } - var drawStart = boundaries.left + lineOffset + boxStart, - drawWidth = boxEnd - boxStart, - drawHeight = lineHeight, extraTop = 0; - if (this.inCompositionMode) { - ctx.fillStyle = this.compositionColor || 'black'; - drawHeight = 1; - extraTop = lineHeight; - } - else { - ctx.fillStyle = this.selectionColor; - } - if (this.direction === 'rtl') { - drawStart = this.width - drawStart - drawWidth; - } - ctx.fillRect( - drawStart, - boundaries.top + boundaries.topOffset + extraTop, - drawWidth, - drawHeight); - boundaries.topOffset += realLineHeight; - } - }, - - /** - * High level function to know the height of the cursor. - * the currentChar is the one that precedes the cursor - * Returns fontSize of char at the current cursor - * Unused from the library, is for the end user - * @return {Number} Character font size - */ - getCurrentCharFontSize: function() { - var cp = this._getCurrentCharIndex(); - return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize'); - }, - - /** - * High level function to know the color of the cursor. - * the currentChar is the one that precedes the cursor - * Returns color (fill) of char at the current cursor - * if the text object has a pattern or gradient for filler, it will return that. - * Unused by the library, is for the end user - * @return {String | fabric.Gradient | fabric.Pattern} Character color (fill) - */ - getCurrentCharColor: function() { - var cp = this._getCurrentCharIndex(); - return this.getValueOfPropertyAt(cp.l, cp.c, 'fill'); - }, - - /** - * Returns the cursor position for the getCurrent.. functions - * @private - */ - _getCurrentCharIndex: function() { - var cursorPosition = this.get2DCursorLocation(this.selectionStart, true), - charIndex = cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0; - return { l: cursorPosition.lineIndex, c: charIndex }; - } - }); - - /** - * Returns fabric.IText instance from an object representation - * @static - * @memberOf fabric.IText - * @param {Object} object Object to create an instance from - * @param {function} [callback] invoked with new instance as argument - */ - fabric.IText.fromObject = function(object, callback) { - parseDecoration(object); - if (object.styles) { - for (var i in object.styles) { - for (var j in object.styles[i]) { - parseDecoration(object.styles[i][j]); - } - } - } - fabric.Object._fromObject('IText', object, callback, 'text'); - }; -})(); - - -(function() { - - var clone = fabric.util.object.clone; - - fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ { - - /** - * Initializes all the interactive behavior of IText - */ - initBehavior: function() { - this.initAddedHandler(); - this.initRemovedHandler(); - this.initCursorSelectionHandlers(); - this.initDoubleClickSimulation(); - this.mouseMoveHandler = this.mouseMoveHandler.bind(this); - }, - - onDeselect: function() { - this.isEditing && this.exitEditing(); - this.selected = false; - }, - - /** - * Initializes "added" event handler - */ - initAddedHandler: function() { - var _this = this; - this.on('added', function() { - var canvas = _this.canvas; - if (canvas) { - if (!canvas._hasITextHandlers) { - canvas._hasITextHandlers = true; - _this._initCanvasHandlers(canvas); - } - canvas._iTextInstances = canvas._iTextInstances || []; - canvas._iTextInstances.push(_this); - } - }); - }, - - initRemovedHandler: function() { - var _this = this; - this.on('removed', function() { - var canvas = _this.canvas; - if (canvas) { - canvas._iTextInstances = canvas._iTextInstances || []; - fabric.util.removeFromArray(canvas._iTextInstances, _this); - if (canvas._iTextInstances.length === 0) { - canvas._hasITextHandlers = false; - _this._removeCanvasHandlers(canvas); - } - } - }); - }, - - /** - * register canvas event to manage exiting on other instances - * @private - */ - _initCanvasHandlers: function(canvas) { - canvas._mouseUpITextHandler = function() { - if (canvas._iTextInstances) { - canvas._iTextInstances.forEach(function(obj) { - obj.__isMousedown = false; - }); - } - }; - canvas.on('mouse:up', canvas._mouseUpITextHandler); - }, - - /** - * remove canvas event to manage exiting on other instances - * @private - */ - _removeCanvasHandlers: function(canvas) { - canvas.off('mouse:up', canvas._mouseUpITextHandler); - }, - - /** - * @private - */ - _tick: function() { - this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, '_onTickComplete'); - }, - - /** - * @private - */ - _animateCursor: function(obj, targetOpacity, duration, completeMethod) { - - var tickState; - - tickState = { - isAborted: false, - abort: function() { - this.isAborted = true; - }, - }; - - obj.animate('_currentCursorOpacity', targetOpacity, { - duration: duration, - onComplete: function() { - if (!tickState.isAborted) { - obj[completeMethod](); - } - }, - onChange: function() { - // we do not want to animate a selection, only cursor - if (obj.canvas && obj.selectionStart === obj.selectionEnd) { - obj.renderCursorOrSelection(); - } - }, - abort: function() { - return tickState.isAborted; - } - }); - return tickState; - }, - - /** - * @private - */ - _onTickComplete: function() { - - var _this = this; - - if (this._cursorTimeout1) { - clearTimeout(this._cursorTimeout1); - } - this._cursorTimeout1 = setTimeout(function() { - _this._currentTickCompleteState = _this._animateCursor(_this, 0, this.cursorDuration / 2, '_tick'); - }, 100); - }, - - /** - * Initializes delayed cursor - */ - initDelayedCursor: function(restart) { - var _this = this, - delay = restart ? 0 : this.cursorDelay; - - this.abortCursorAnimation(); - this._currentCursorOpacity = 1; - this._cursorTimeout2 = setTimeout(function() { - _this._tick(); - }, delay); - }, - - /** - * Aborts cursor animation and clears all timeouts - */ - abortCursorAnimation: function() { - var shouldClear = this._currentTickState || this._currentTickCompleteState, - canvas = this.canvas; - this._currentTickState && this._currentTickState.abort(); - this._currentTickCompleteState && this._currentTickCompleteState.abort(); - - clearTimeout(this._cursorTimeout1); - clearTimeout(this._cursorTimeout2); - - this._currentCursorOpacity = 0; - // to clear just itext area we need to transform the context - // it may not be worth it - if (shouldClear && canvas) { - canvas.clearContext(canvas.contextTop || canvas.contextContainer); - } - - }, - - /** - * Selects entire text - * @return {fabric.IText} thisArg - * @chainable - */ - selectAll: function() { - this.selectionStart = 0; - this.selectionEnd = this._text.length; - this._fireSelectionChanged(); - this._updateTextarea(); - return this; - }, - - /** - * Returns selected text - * @return {String} - */ - getSelectedText: function() { - return this._text.slice(this.selectionStart, this.selectionEnd).join(''); - }, - - /** - * Find new selection index representing start of current word according to current selection index - * @param {Number} startFrom Current selection index - * @return {Number} New selection index - */ - findWordBoundaryLeft: function(startFrom) { - var offset = 0, index = startFrom - 1; - - // remove space before cursor first - if (this._reSpace.test(this._text[index])) { - while (this._reSpace.test(this._text[index])) { - offset++; - index--; - } - } - while (/\S/.test(this._text[index]) && index > -1) { - offset++; - index--; - } - - return startFrom - offset; - }, - - /** - * Find new selection index representing end of current word according to current selection index - * @param {Number} startFrom Current selection index - * @return {Number} New selection index - */ - findWordBoundaryRight: function(startFrom) { - var offset = 0, index = startFrom; - - // remove space after cursor first - if (this._reSpace.test(this._text[index])) { - while (this._reSpace.test(this._text[index])) { - offset++; - index++; - } - } - while (/\S/.test(this._text[index]) && index < this._text.length) { - offset++; - index++; - } - - return startFrom + offset; - }, - - /** - * Find new selection index representing start of current line according to current selection index - * @param {Number} startFrom Current selection index - * @return {Number} New selection index - */ - findLineBoundaryLeft: function(startFrom) { - var offset = 0, index = startFrom - 1; - - while (!/\n/.test(this._text[index]) && index > -1) { - offset++; - index--; - } - - return startFrom - offset; - }, - - /** - * Find new selection index representing end of current line according to current selection index - * @param {Number} startFrom Current selection index - * @return {Number} New selection index - */ - findLineBoundaryRight: function(startFrom) { - var offset = 0, index = startFrom; - - while (!/\n/.test(this._text[index]) && index < this._text.length) { - offset++; - index++; - } - - return startFrom + offset; - }, - - /** - * Finds index corresponding to beginning or end of a word - * @param {Number} selectionStart Index of a character - * @param {Number} direction 1 or -1 - * @return {Number} Index of the beginning or end of a word - */ - searchWordBoundary: function(selectionStart, direction) { - var text = this._text, - index = this._reSpace.test(text[selectionStart]) ? selectionStart - 1 : selectionStart, - _char = text[index], - // wrong - reNonWord = fabric.reNonWord; - - while (!reNonWord.test(_char) && index > 0 && index < text.length) { - index += direction; - _char = text[index]; - } - if (reNonWord.test(_char)) { - index += direction === 1 ? 0 : 1; - } - return index; - }, - - /** - * Selects a word based on the index - * @param {Number} selectionStart Index of a character - */ - selectWord: function(selectionStart) { - selectionStart = selectionStart || this.selectionStart; - var newSelectionStart = this.searchWordBoundary(selectionStart, -1), /* search backwards */ - newSelectionEnd = this.searchWordBoundary(selectionStart, 1); /* search forward */ - - this.selectionStart = newSelectionStart; - this.selectionEnd = newSelectionEnd; - this._fireSelectionChanged(); - this._updateTextarea(); - this.renderCursorOrSelection(); - }, - - /** - * Selects a line based on the index - * @param {Number} selectionStart Index of a character - * @return {fabric.IText} thisArg - * @chainable - */ - selectLine: function(selectionStart) { - selectionStart = selectionStart || this.selectionStart; - var newSelectionStart = this.findLineBoundaryLeft(selectionStart), - newSelectionEnd = this.findLineBoundaryRight(selectionStart); - - this.selectionStart = newSelectionStart; - this.selectionEnd = newSelectionEnd; - this._fireSelectionChanged(); - this._updateTextarea(); - return this; - }, - - /** - * Enters editing state - * @return {fabric.IText} thisArg - * @chainable - */ - enterEditing: function(e) { - if (this.isEditing || !this.editable) { - return; - } - - if (this.canvas) { - this.canvas.calcOffset(); - this.exitEditingOnOthers(this.canvas); - } - - this.isEditing = true; - - this.initHiddenTextarea(e); - this.hiddenTextarea.focus(); - this.hiddenTextarea.value = this.text; - this._updateTextarea(); - this._saveEditingProps(); - this._setEditingProps(); - this._textBeforeEdit = this.text; - - this._tick(); - this.fire('editing:entered'); - this._fireSelectionChanged(); - if (!this.canvas) { - return this; - } - this.canvas.fire('text:editing:entered', { target: this }); - this.initMouseMoveHandler(); - this.canvas.requestRenderAll(); - return this; - }, - - exitEditingOnOthers: function(canvas) { - if (canvas._iTextInstances) { - canvas._iTextInstances.forEach(function(obj) { - obj.selected = false; - if (obj.isEditing) { - obj.exitEditing(); - } - }); - } - }, - - /** - * Initializes "mousemove" event handler - */ - initMouseMoveHandler: function() { - this.canvas.on('mouse:move', this.mouseMoveHandler); - }, - - /** - * @private - */ - mouseMoveHandler: function(options) { - if (!this.__isMousedown || !this.isEditing) { - return; - } - - var newSelectionStart = this.getSelectionStartFromPointer(options.e), - currentStart = this.selectionStart, - currentEnd = this.selectionEnd; - if ( - (newSelectionStart !== this.__selectionStartOnMouseDown || currentStart === currentEnd) - && - (currentStart === newSelectionStart || currentEnd === newSelectionStart) - ) { - return; - } - if (newSelectionStart > this.__selectionStartOnMouseDown) { - this.selectionStart = this.__selectionStartOnMouseDown; - this.selectionEnd = newSelectionStart; - } - else { - this.selectionStart = newSelectionStart; - this.selectionEnd = this.__selectionStartOnMouseDown; - } - if (this.selectionStart !== currentStart || this.selectionEnd !== currentEnd) { - this.restartCursorIfNeeded(); - this._fireSelectionChanged(); - this._updateTextarea(); - this.renderCursorOrSelection(); - } - }, - - /** - * @private - */ - _setEditingProps: function() { - this.hoverCursor = 'text'; - - if (this.canvas) { - this.canvas.defaultCursor = this.canvas.moveCursor = 'text'; - } - - this.borderColor = this.editingBorderColor; - this.hasControls = this.selectable = false; - this.lockMovementX = this.lockMovementY = true; - }, - - /** - * convert from textarea to grapheme indexes - */ - fromStringToGraphemeSelection: function(start, end, text) { - var smallerTextStart = text.slice(0, start), - graphemeStart = fabric.util.string.graphemeSplit(smallerTextStart).length; - if (start === end) { - return { selectionStart: graphemeStart, selectionEnd: graphemeStart }; - } - var smallerTextEnd = text.slice(start, end), - graphemeEnd = fabric.util.string.graphemeSplit(smallerTextEnd).length; - return { selectionStart: graphemeStart, selectionEnd: graphemeStart + graphemeEnd }; - }, - - /** - * convert from fabric to textarea values - */ - fromGraphemeToStringSelection: function(start, end, _text) { - var smallerTextStart = _text.slice(0, start), - graphemeStart = smallerTextStart.join('').length; - if (start === end) { - return { selectionStart: graphemeStart, selectionEnd: graphemeStart }; - } - var smallerTextEnd = _text.slice(start, end), - graphemeEnd = smallerTextEnd.join('').length; - return { selectionStart: graphemeStart, selectionEnd: graphemeStart + graphemeEnd }; - }, - - /** - * @private - */ - _updateTextarea: function() { - this.cursorOffsetCache = { }; - if (!this.hiddenTextarea) { - return; - } - if (!this.inCompositionMode) { - var newSelection = this.fromGraphemeToStringSelection(this.selectionStart, this.selectionEnd, this._text); - this.hiddenTextarea.selectionStart = newSelection.selectionStart; - this.hiddenTextarea.selectionEnd = newSelection.selectionEnd; - } - this.updateTextareaPosition(); - }, - - /** - * @private - */ - updateFromTextArea: function() { - if (!this.hiddenTextarea) { - return; - } - this.cursorOffsetCache = { }; - this.text = this.hiddenTextarea.value; - if (this._shouldClearDimensionCache()) { - this.initDimensions(); - this.setCoords(); - } - var newSelection = this.fromStringToGraphemeSelection( - this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value); - this.selectionEnd = this.selectionStart = newSelection.selectionEnd; - if (!this.inCompositionMode) { - this.selectionStart = newSelection.selectionStart; - } - this.updateTextareaPosition(); - }, - - /** - * @private - */ - updateTextareaPosition: function() { - if (this.selectionStart === this.selectionEnd) { - var style = this._calcTextareaPosition(); - this.hiddenTextarea.style.left = style.left; - this.hiddenTextarea.style.top = style.top; - } - }, - - /** - * @private - * @return {Object} style contains style for hiddenTextarea - */ - _calcTextareaPosition: function() { - if (!this.canvas) { - return { x: 1, y: 1 }; - } - var desiredPosition = this.inCompositionMode ? this.compositionStart : this.selectionStart, - boundaries = this._getCursorBoundaries(desiredPosition), - cursorLocation = this.get2DCursorLocation(desiredPosition), - lineIndex = cursorLocation.lineIndex, - charIndex = cursorLocation.charIndex, - charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') * this.lineHeight, - leftOffset = boundaries.leftOffset, - m = this.calcTransformMatrix(), - p = { - x: boundaries.left + leftOffset, - y: boundaries.top + boundaries.topOffset + charHeight - }, - retinaScaling = this.canvas.getRetinaScaling(), - upperCanvas = this.canvas.upperCanvasEl, - upperCanvasWidth = upperCanvas.width / retinaScaling, - upperCanvasHeight = upperCanvas.height / retinaScaling, - maxWidth = upperCanvasWidth - charHeight, - maxHeight = upperCanvasHeight - charHeight, - scaleX = upperCanvas.clientWidth / upperCanvasWidth, - scaleY = upperCanvas.clientHeight / upperCanvasHeight; - - p = fabric.util.transformPoint(p, m); - p = fabric.util.transformPoint(p, this.canvas.viewportTransform); - p.x *= scaleX; - p.y *= scaleY; - if (p.x < 0) { - p.x = 0; - } - if (p.x > maxWidth) { - p.x = maxWidth; - } - if (p.y < 0) { - p.y = 0; - } - if (p.y > maxHeight) { - p.y = maxHeight; - } - - // add canvas offset on document - p.x += this.canvas._offset.left; - p.y += this.canvas._offset.top; - - return { left: p.x + 'px', top: p.y + 'px', fontSize: charHeight + 'px', charHeight: charHeight }; - }, - - /** - * @private - */ - _saveEditingProps: function() { - this._savedProps = { - hasControls: this.hasControls, - borderColor: this.borderColor, - lockMovementX: this.lockMovementX, - lockMovementY: this.lockMovementY, - hoverCursor: this.hoverCursor, - selectable: this.selectable, - defaultCursor: this.canvas && this.canvas.defaultCursor, - moveCursor: this.canvas && this.canvas.moveCursor - }; - }, - - /** - * @private - */ - _restoreEditingProps: function() { - if (!this._savedProps) { - return; - } - - this.hoverCursor = this._savedProps.hoverCursor; - this.hasControls = this._savedProps.hasControls; - this.borderColor = this._savedProps.borderColor; - this.selectable = this._savedProps.selectable; - this.lockMovementX = this._savedProps.lockMovementX; - this.lockMovementY = this._savedProps.lockMovementY; - - if (this.canvas) { - this.canvas.defaultCursor = this._savedProps.defaultCursor; - this.canvas.moveCursor = this._savedProps.moveCursor; - } - }, - - /** - * Exits from editing state - * @return {fabric.IText} thisArg - * @chainable - */ - exitEditing: function() { - var isTextChanged = (this._textBeforeEdit !== this.text); - var hiddenTextarea = this.hiddenTextarea; - this.selected = false; - this.isEditing = false; - - this.selectionEnd = this.selectionStart; - - if (hiddenTextarea) { - hiddenTextarea.blur && hiddenTextarea.blur(); - hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea); - } - this.hiddenTextarea = null; - this.abortCursorAnimation(); - this._restoreEditingProps(); - this._currentCursorOpacity = 0; - if (this._shouldClearDimensionCache()) { - this.initDimensions(); - this.setCoords(); - } - this.fire('editing:exited'); - isTextChanged && this.fire('modified'); - if (this.canvas) { - this.canvas.off('mouse:move', this.mouseMoveHandler); - this.canvas.fire('text:editing:exited', { target: this }); - isTextChanged && this.canvas.fire('object:modified', { target: this }); - } - return this; - }, - - /** - * @private - */ - _removeExtraneousStyles: function() { - for (var prop in this.styles) { - if (!this._textLines[prop]) { - delete this.styles[prop]; - } - } - }, - - /** - * remove and reflow a style block from start to end. - * @param {Number} start linear start position for removal (included in removal) - * @param {Number} end linear end position for removal ( excluded from removal ) - */ - removeStyleFromTo: function(start, end) { - var cursorStart = this.get2DCursorLocation(start, true), - cursorEnd = this.get2DCursorLocation(end, true), - lineStart = cursorStart.lineIndex, - charStart = cursorStart.charIndex, - lineEnd = cursorEnd.lineIndex, - charEnd = cursorEnd.charIndex, - i, styleObj; - if (lineStart !== lineEnd) { - // step1 remove the trailing of lineStart - if (this.styles[lineStart]) { - for (i = charStart; i < this._unwrappedTextLines[lineStart].length; i++) { - delete this.styles[lineStart][i]; - } - } - // step2 move the trailing of lineEnd to lineStart if needed - if (this.styles[lineEnd]) { - for (i = charEnd; i < this._unwrappedTextLines[lineEnd].length; i++) { - styleObj = this.styles[lineEnd][i]; - if (styleObj) { - this.styles[lineStart] || (this.styles[lineStart] = { }); - this.styles[lineStart][charStart + i - charEnd] = styleObj; - } - } - } - // step3 detects lines will be completely removed. - for (i = lineStart + 1; i <= lineEnd; i++) { - delete this.styles[i]; - } - // step4 shift remaining lines. - this.shiftLineStyles(lineEnd, lineStart - lineEnd); - } - else { - // remove and shift left on the same line - if (this.styles[lineStart]) { - styleObj = this.styles[lineStart]; - var diff = charEnd - charStart, numericChar, _char; - for (i = charStart; i < charEnd; i++) { - delete styleObj[i]; - } - for (_char in this.styles[lineStart]) { - numericChar = parseInt(_char, 10); - if (numericChar >= charEnd) { - styleObj[numericChar - diff] = styleObj[_char]; - delete styleObj[_char]; - } - } - } - } - }, - - /** - * Shifts line styles up or down - * @param {Number} lineIndex Index of a line - * @param {Number} offset Can any number? - */ - shiftLineStyles: function(lineIndex, offset) { - // shift all line styles by offset upward or downward - // do not clone deep. we need new array, not new style objects - var clonedStyles = clone(this.styles); - for (var line in this.styles) { - var numericLine = parseInt(line, 10); - if (numericLine > lineIndex) { - this.styles[numericLine + offset] = clonedStyles[numericLine]; - if (!clonedStyles[numericLine - offset]) { - delete this.styles[numericLine]; - } - } - } - }, - - restartCursorIfNeeded: function() { - if (!this._currentTickState || this._currentTickState.isAborted - || !this._currentTickCompleteState || this._currentTickCompleteState.isAborted - ) { - this.initDelayedCursor(); - } - }, - - /** - * Handle insertion of more consecutive style lines for when one or more - * newlines gets added to the text. Since current style needs to be shifted - * first we shift the current style of the number lines needed, then we add - * new lines from the last to the first. - * @param {Number} lineIndex Index of a line - * @param {Number} charIndex Index of a char - * @param {Number} qty number of lines to add - * @param {Array} copiedStyle Array of objects styles - */ - insertNewlineStyleObject: function(lineIndex, charIndex, qty, copiedStyle) { - var currentCharStyle, - newLineStyles = {}, - somethingAdded = false, - isEndOfLine = this._unwrappedTextLines[lineIndex].length === charIndex; - - qty || (qty = 1); - this.shiftLineStyles(lineIndex, qty); - if (this.styles[lineIndex]) { - currentCharStyle = this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1]; - } - // we clone styles of all chars - // after cursor onto the current line - for (var index in this.styles[lineIndex]) { - var numIndex = parseInt(index, 10); - if (numIndex >= charIndex) { - somethingAdded = true; - newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index]; - // remove lines from the previous line since they're on a new line now - if (!(isEndOfLine && charIndex === 0)) { - delete this.styles[lineIndex][index]; - } - } - } - var styleCarriedOver = false; - if (somethingAdded && !isEndOfLine) { - // if is end of line, the extra style we copied - // is probably not something we want - this.styles[lineIndex + qty] = newLineStyles; - styleCarriedOver = true; - } - if (styleCarriedOver) { - // skip the last line of since we already prepared it. - qty--; - } - // for the all the lines or all the other lines - // we clone current char style onto the next (otherwise empty) line - while (qty > 0) { - if (copiedStyle && copiedStyle[qty - 1]) { - this.styles[lineIndex + qty] = { 0: clone(copiedStyle[qty - 1]) }; - } - else if (currentCharStyle) { - this.styles[lineIndex + qty] = { 0: clone(currentCharStyle) }; - } - else { - delete this.styles[lineIndex + qty]; - } - qty--; - } - this._forceClearCache = true; - }, - - /** - * Inserts style object for a given line/char index - * @param {Number} lineIndex Index of a line - * @param {Number} charIndex Index of a char - * @param {Number} quantity number Style object to insert, if given - * @param {Array} copiedStyle array of style objects - */ - insertCharStyleObject: function(lineIndex, charIndex, quantity, copiedStyle) { - if (!this.styles) { - this.styles = {}; - } - var currentLineStyles = this.styles[lineIndex], - currentLineStylesCloned = currentLineStyles ? clone(currentLineStyles) : {}; - - quantity || (quantity = 1); - // shift all char styles by quantity forward - // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4 - for (var index in currentLineStylesCloned) { - var numericIndex = parseInt(index, 10); - if (numericIndex >= charIndex) { - currentLineStyles[numericIndex + quantity] = currentLineStylesCloned[numericIndex]; - // only delete the style if there was nothing moved there - if (!currentLineStylesCloned[numericIndex - quantity]) { - delete currentLineStyles[numericIndex]; - } - } - } - this._forceClearCache = true; - if (copiedStyle) { - while (quantity--) { - if (!Object.keys(copiedStyle[quantity]).length) { - continue; - } - if (!this.styles[lineIndex]) { - this.styles[lineIndex] = {}; - } - this.styles[lineIndex][charIndex + quantity] = clone(copiedStyle[quantity]); - } - return; - } - if (!currentLineStyles) { - return; - } - var newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1]; - while (newStyle && quantity--) { - this.styles[lineIndex][charIndex + quantity] = clone(newStyle); - } - }, - - /** - * Inserts style object(s) - * @param {Array} insertedText Characters at the location where style is inserted - * @param {Number} start cursor index for inserting style - * @param {Array} [copiedStyle] array of style objects to insert. - */ - insertNewStyleBlock: function(insertedText, start, copiedStyle) { - var cursorLoc = this.get2DCursorLocation(start, true), - addedLines = [0], linesLength = 0; - // get an array of how many char per lines are being added. - for (var i = 0; i < insertedText.length; i++) { - if (insertedText[i] === '\n') { - linesLength++; - addedLines[linesLength] = 0; - } - else { - addedLines[linesLength]++; - } - } - // for the first line copy the style from the current char position. - if (addedLines[0] > 0) { - this.insertCharStyleObject(cursorLoc.lineIndex, cursorLoc.charIndex, addedLines[0], copiedStyle); - copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1); - } - linesLength && this.insertNewlineStyleObject( - cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLength); - for (var i = 1; i < linesLength; i++) { - if (addedLines[i] > 0) { - this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle); - } - else if (copiedStyle) { - // this test is required in order to close #6841 - // when a pasted buffer begins with a newline then - // this.styles[cursorLoc.lineIndex + i] and copiedStyle[0] - // may be undefined for some reason - if (this.styles[cursorLoc.lineIndex + i] && copiedStyle[0]) { - this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0]; - } - } - copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1); - } - // we use i outside the loop to get it like linesLength - if (addedLines[i] > 0) { - this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle); - } - }, - - /** - * Set the selectionStart and selectionEnd according to the new position of cursor - * mimic the key - mouse navigation when shift is pressed. - */ - setSelectionStartEndWithShift: function(start, end, newSelection) { - if (newSelection <= start) { - if (end === start) { - this._selectionDirection = 'left'; - } - else if (this._selectionDirection === 'right') { - this._selectionDirection = 'left'; - this.selectionEnd = start; - } - this.selectionStart = newSelection; - } - else if (newSelection > start && newSelection < end) { - if (this._selectionDirection === 'right') { - this.selectionEnd = newSelection; - } - else { - this.selectionStart = newSelection; - } - } - else { - // newSelection is > selection start and end - if (end === start) { - this._selectionDirection = 'right'; - } - else if (this._selectionDirection === 'left') { - this._selectionDirection = 'right'; - this.selectionStart = end; - } - this.selectionEnd = newSelection; - } - }, - - setSelectionInBoundaries: function() { - var length = this.text.length; - if (this.selectionStart > length) { - this.selectionStart = length; - } - else if (this.selectionStart < 0) { - this.selectionStart = 0; - } - if (this.selectionEnd > length) { - this.selectionEnd = length; - } - else if (this.selectionEnd < 0) { - this.selectionEnd = 0; - } - } - }); -})(); - - -fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ { - /** - * Initializes "dbclick" event handler - */ - initDoubleClickSimulation: function() { - - // for double click - this.__lastClickTime = +new Date(); - - // for triple click - this.__lastLastClickTime = +new Date(); - - this.__lastPointer = { }; - - this.on('mousedown', this.onMouseDown); - }, - - /** - * Default event handler to simulate triple click - * @private - */ - onMouseDown: function(options) { - if (!this.canvas) { - return; - } - this.__newClickTime = +new Date(); - var newPointer = options.pointer; - if (this.isTripleClick(newPointer)) { - this.fire('tripleclick', options); - this._stopEvent(options.e); - } - this.__lastLastClickTime = this.__lastClickTime; - this.__lastClickTime = this.__newClickTime; - this.__lastPointer = newPointer; - this.__lastIsEditing = this.isEditing; - this.__lastSelected = this.selected; - }, - - isTripleClick: function(newPointer) { - return this.__newClickTime - this.__lastClickTime < 500 && - this.__lastClickTime - this.__lastLastClickTime < 500 && - this.__lastPointer.x === newPointer.x && - this.__lastPointer.y === newPointer.y; - }, - - /** - * @private - */ - _stopEvent: function(e) { - e.preventDefault && e.preventDefault(); - e.stopPropagation && e.stopPropagation(); - }, - - /** - * Initializes event handlers related to cursor or selection - */ - initCursorSelectionHandlers: function() { - this.initMousedownHandler(); - this.initMouseupHandler(); - this.initClicks(); - }, - - /** - * Default handler for double click, select a word - */ - doubleClickHandler: function(options) { - if (!this.isEditing) { - return; - } - this.selectWord(this.getSelectionStartFromPointer(options.e)); - }, - - /** - * Default handler for triple click, select a line - */ - tripleClickHandler: function(options) { - if (!this.isEditing) { - return; - } - this.selectLine(this.getSelectionStartFromPointer(options.e)); - }, - - /** - * Initializes double and triple click event handlers - */ - initClicks: function() { - this.on('mousedblclick', this.doubleClickHandler); - this.on('tripleclick', this.tripleClickHandler); - }, - - /** - * Default event handler for the basic functionalities needed on _mouseDown - * can be overridden to do something different. - * Scope of this implementation is: find the click position, set selectionStart - * find selectionEnd, initialize the drawing of either cursor or selection area - * initializing a mousedDown on a text area will cancel fabricjs knowledge of - * current compositionMode. It will be set to false. - */ - _mouseDownHandler: function(options) { - if (!this.canvas || !this.editable || (options.e.button && options.e.button !== 1)) { - return; - } - - this.__isMousedown = true; - - if (this.selected) { - this.inCompositionMode = false; - this.setCursorByClick(options.e); - } - - if (this.isEditing) { - this.__selectionStartOnMouseDown = this.selectionStart; - if (this.selectionStart === this.selectionEnd) { - this.abortCursorAnimation(); - } - this.renderCursorOrSelection(); - } - }, - - /** - * Default event handler for the basic functionalities needed on mousedown:before - * can be overridden to do something different. - * Scope of this implementation is: verify the object is already selected when mousing down - */ - _mouseDownHandlerBefore: function(options) { - if (!this.canvas || !this.editable || (options.e.button && options.e.button !== 1)) { - return; - } - // we want to avoid that an object that was selected and then becomes unselectable, - // may trigger editing mode in some way. - this.selected = this === this.canvas._activeObject; - }, - - /** - * Initializes "mousedown" event handler - */ - initMousedownHandler: function() { - this.on('mousedown', this._mouseDownHandler); - this.on('mousedown:before', this._mouseDownHandlerBefore); - }, - - /** - * Initializes "mouseup" event handler - */ - initMouseupHandler: function() { - this.on('mouseup', this.mouseUpHandler); - }, - - /** - * standard handler for mouse up, overridable - * @private - */ - mouseUpHandler: function(options) { - this.__isMousedown = false; - if (!this.editable || this.group || - (options.transform && options.transform.actionPerformed) || - (options.e.button && options.e.button !== 1)) { - return; - } - - if (this.canvas) { - var currentActive = this.canvas._activeObject; - if (currentActive && currentActive !== this) { - // avoid running this logic when there is an active object - // this because is possible with shift click and fast clicks, - // to rapidly deselect and reselect this object and trigger an enterEdit - return; - } - } - - if (this.__lastSelected && !this.__corner) { - this.selected = false; - this.__lastSelected = false; - this.enterEditing(options.e); - if (this.selectionStart === this.selectionEnd) { - this.initDelayedCursor(true); - } - else { - this.renderCursorOrSelection(); - } - } - else { - this.selected = true; - } - }, - - /** - * Changes cursor location in a text depending on passed pointer (x/y) object - * @param {Event} e Event object - */ - setCursorByClick: function(e) { - var newSelection = this.getSelectionStartFromPointer(e), - start = this.selectionStart, end = this.selectionEnd; - if (e.shiftKey) { - this.setSelectionStartEndWithShift(start, end, newSelection); - } - else { - this.selectionStart = newSelection; - this.selectionEnd = newSelection; - } - if (this.isEditing) { - this._fireSelectionChanged(); - this._updateTextarea(); - } - }, - - /** - * Returns index of a character corresponding to where an object was clicked - * @param {Event} e Event object - * @return {Number} Index of a character - */ - getSelectionStartFromPointer: function(e) { - var mouseOffset = this.getLocalPointer(e), - prevWidth = 0, - width = 0, - height = 0, - charIndex = 0, - lineIndex = 0, - lineLeftOffset, - line; - for (var i = 0, len = this._textLines.length; i < len; i++) { - if (height <= mouseOffset.y) { - height += this.getHeightOfLine(i) * this.scaleY; - lineIndex = i; - if (i > 0) { - charIndex += this._textLines[i - 1].length + this.missingNewlineOffset(i - 1); - } - } - else { - break; - } - } - lineLeftOffset = this._getLineLeftOffset(lineIndex); - width = lineLeftOffset * this.scaleX; - line = this._textLines[lineIndex]; - // handling of RTL: in order to get things work correctly, - // we assume RTL writing is mirrored compared to LTR writing. - // so in position detection we mirror the X offset, and when is time - // of rendering it, we mirror it again. - if (this.direction === 'rtl') { - mouseOffset.x = this.width * this.scaleX - mouseOffset.x + width; - } - for (var j = 0, jlen = line.length; j < jlen; j++) { - prevWidth = width; - // i removed something about flipX here, check. - width += this.__charBounds[lineIndex][j].kernedWidth * this.scaleX; - if (width <= mouseOffset.x) { - charIndex++; - } - else { - break; - } - } - return this._getNewSelectionStartFromOffset(mouseOffset, prevWidth, width, charIndex, jlen); - }, - - /** - * @private - */ - _getNewSelectionStartFromOffset: function(mouseOffset, prevWidth, width, index, jlen) { - // we need Math.abs because when width is after the last char, the offset is given as 1, while is 0 - var distanceBtwLastCharAndCursor = mouseOffset.x - prevWidth, - distanceBtwNextCharAndCursor = width - mouseOffset.x, - offset = distanceBtwNextCharAndCursor > distanceBtwLastCharAndCursor || - distanceBtwNextCharAndCursor < 0 ? 0 : 1, - newSelectionStart = index + offset; - // if object is horizontally flipped, mirror cursor location from the end - if (this.flipX) { - newSelectionStart = jlen - newSelectionStart; - } - - if (newSelectionStart > this._text.length) { - newSelectionStart = this._text.length; - } - - return newSelectionStart; - } -}); - - -fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ { - - /** - * Initializes hidden textarea (needed to bring up keyboard in iOS) - */ - initHiddenTextarea: function() { - this.hiddenTextarea = fabric.document.createElement('textarea'); - this.hiddenTextarea.setAttribute('autocapitalize', 'off'); - this.hiddenTextarea.setAttribute('autocorrect', 'off'); - this.hiddenTextarea.setAttribute('autocomplete', 'off'); - this.hiddenTextarea.setAttribute('spellcheck', 'false'); - this.hiddenTextarea.setAttribute('data-fabric-hiddentextarea', ''); - this.hiddenTextarea.setAttribute('wrap', 'off'); - var style = this._calcTextareaPosition(); - // line-height: 1px; was removed from the style to fix this: - // https://bugs.chromium.org/p/chromium/issues/detail?id=870966 - this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top + - '; left: ' + style.left + '; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px;' + - ' paddingーtop: ' + style.fontSize + ';'; - - if (this.hiddenTextareaContainer) { - this.hiddenTextareaContainer.appendChild(this.hiddenTextarea); - } - else { - fabric.document.body.appendChild(this.hiddenTextarea); - } - - fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'keyup', this.onKeyUp.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'input', this.onInput.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'copy', this.copy.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'cut', this.copy.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'paste', this.paste.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'compositionstart', this.onCompositionStart.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'compositionupdate', this.onCompositionUpdate.bind(this)); - fabric.util.addListener(this.hiddenTextarea, 'compositionend', this.onCompositionEnd.bind(this)); - - if (!this._clickHandlerInitialized && this.canvas) { - fabric.util.addListener(this.canvas.upperCanvasEl, 'click', this.onClick.bind(this)); - this._clickHandlerInitialized = true; - } - }, - - /** - * For functionalities on keyDown - * Map a special key to a function of the instance/prototype - * If you need different behaviour for ESC or TAB or arrows, you have to change - * this map setting the name of a function that you build on the fabric.Itext or - * your prototype. - * the map change will affect all Instances unless you need for only some text Instances - * in that case you have to clone this object and assign your Instance. - * this.keysMap = fabric.util.object.clone(this.keysMap); - * The function must be in fabric.Itext.prototype.myFunction And will receive event as args[0] - */ - keysMap: { - 9: 'exitEditing', - 27: 'exitEditing', - 33: 'moveCursorUp', - 34: 'moveCursorDown', - 35: 'moveCursorRight', - 36: 'moveCursorLeft', - 37: 'moveCursorLeft', - 38: 'moveCursorUp', - 39: 'moveCursorRight', - 40: 'moveCursorDown', - }, - - keysMapRtl: { - 9: 'exitEditing', - 27: 'exitEditing', - 33: 'moveCursorUp', - 34: 'moveCursorDown', - 35: 'moveCursorLeft', - 36: 'moveCursorRight', - 37: 'moveCursorRight', - 38: 'moveCursorUp', - 39: 'moveCursorLeft', - 40: 'moveCursorDown', - }, - - /** - * For functionalities on keyUp + ctrl || cmd - */ - ctrlKeysMapUp: { - 67: 'copy', - 88: 'cut' - }, - - /** - * For functionalities on keyDown + ctrl || cmd - */ - ctrlKeysMapDown: { - 65: 'selectAll' - }, - - onClick: function() { - // No need to trigger click event here, focus is enough to have the keyboard appear on Android - this.hiddenTextarea && this.hiddenTextarea.focus(); - }, - - /** - * Handles keydown event - * only used for arrows and combination of modifier keys. - * @param {Event} e Event object - */ - onKeyDown: function(e) { - if (!this.isEditing) { - return; - } - var keyMap = this.direction === 'rtl' ? this.keysMapRtl : this.keysMap; - if (e.keyCode in keyMap) { - this[keyMap[e.keyCode]](e); - } - else if ((e.keyCode in this.ctrlKeysMapDown) && (e.ctrlKey || e.metaKey)) { - this[this.ctrlKeysMapDown[e.keyCode]](e); - } - else { - return; - } - e.stopImmediatePropagation(); - e.preventDefault(); - if (e.keyCode >= 33 && e.keyCode <= 40) { - // if i press an arrow key just update selection - this.inCompositionMode = false; - this.clearContextTop(); - this.renderCursorOrSelection(); - } - else { - this.canvas && this.canvas.requestRenderAll(); - } - }, - - /** - * Handles keyup event - * We handle KeyUp because ie11 and edge have difficulties copy/pasting - * if a copy/cut event fired, keyup is dismissed - * @param {Event} e Event object - */ - onKeyUp: function(e) { - if (!this.isEditing || this._copyDone || this.inCompositionMode) { - this._copyDone = false; - return; - } - if ((e.keyCode in this.ctrlKeysMapUp) && (e.ctrlKey || e.metaKey)) { - this[this.ctrlKeysMapUp[e.keyCode]](e); - } - else { - return; - } - e.stopImmediatePropagation(); - e.preventDefault(); - this.canvas && this.canvas.requestRenderAll(); - }, - - /** - * Handles onInput event - * @param {Event} e Event object - */ - onInput: function(e) { - var fromPaste = this.fromPaste; - this.fromPaste = false; - e && e.stopPropagation(); - if (!this.isEditing) { - return; - } - // decisions about style changes. - var nextText = this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText, - charCount = this._text.length, - nextCharCount = nextText.length, - removedText, insertedText, - charDiff = nextCharCount - charCount, - selectionStart = this.selectionStart, selectionEnd = this.selectionEnd, - selection = selectionStart !== selectionEnd, - copiedStyle, removeFrom, removeTo; - if (this.hiddenTextarea.value === '') { - this.styles = { }; - this.updateFromTextArea(); - this.fire('changed'); - if (this.canvas) { - this.canvas.fire('text:changed', { target: this }); - this.canvas.requestRenderAll(); - } - return; - } - - var textareaSelection = this.fromStringToGraphemeSelection( - this.hiddenTextarea.selectionStart, - this.hiddenTextarea.selectionEnd, - this.hiddenTextarea.value - ); - var backDelete = selectionStart > textareaSelection.selectionStart; - - if (selection) { - removedText = this._text.slice(selectionStart, selectionEnd); - charDiff += selectionEnd - selectionStart; - } - else if (nextCharCount < charCount) { - if (backDelete) { - removedText = this._text.slice(selectionEnd + charDiff, selectionEnd); - } - else { - removedText = this._text.slice(selectionStart, selectionStart - charDiff); - } - } - insertedText = nextText.slice(textareaSelection.selectionEnd - charDiff, textareaSelection.selectionEnd); - if (removedText && removedText.length) { - if (insertedText.length) { - // let's copy some style before deleting. - // we want to copy the style before the cursor OR the style at the cursor if selection - // is bigger than 0. - copiedStyle = this.getSelectionStyles(selectionStart, selectionStart + 1, false); - // now duplicate the style one for each inserted text. - copiedStyle = insertedText.map(function() { - // this return an array of references, but that is fine since we are - // copying the style later. - return copiedStyle[0]; - }); - } - if (selection) { - removeFrom = selectionStart; - removeTo = selectionEnd; - } - else if (backDelete) { - // detect differences between forwardDelete and backDelete - removeFrom = selectionEnd - removedText.length; - removeTo = selectionEnd; - } - else { - removeFrom = selectionEnd; - removeTo = selectionEnd + removedText.length; - } - this.removeStyleFromTo(removeFrom, removeTo); - } - if (insertedText.length) { - if (fromPaste && insertedText.join('') === fabric.copiedText && !fabric.disableStyleCopyPaste) { - copiedStyle = fabric.copiedTextStyle; - } - this.insertNewStyleBlock(insertedText, selectionStart, copiedStyle); - } - this.updateFromTextArea(); - this.fire('changed'); - if (this.canvas) { - this.canvas.fire('text:changed', { target: this }); - this.canvas.requestRenderAll(); - } - }, - /** - * Composition start - */ - onCompositionStart: function() { - this.inCompositionMode = true; - }, - - /** - * Composition end - */ - onCompositionEnd: function() { - this.inCompositionMode = false; - }, - - // /** - // * Composition update - // */ - onCompositionUpdate: function(e) { - this.compositionStart = e.target.selectionStart; - this.compositionEnd = e.target.selectionEnd; - this.updateTextareaPosition(); - }, - - /** - * Copies selected text - * @param {Event} e Event object - */ - copy: function() { - if (this.selectionStart === this.selectionEnd) { - //do not cut-copy if no selection - return; - } - - fabric.copiedText = this.getSelectedText(); - if (!fabric.disableStyleCopyPaste) { - fabric.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd, true); - } - else { - fabric.copiedTextStyle = null; - } - this._copyDone = true; - }, - - /** - * Pastes text - * @param {Event} e Event object - */ - paste: function() { - this.fromPaste = true; - }, - - /** - * @private - * @param {Event} e Event object - * @return {Object} Clipboard data object - */ - _getClipboardData: function(e) { - return (e && e.clipboardData) || fabric.window.clipboardData; - }, - - /** - * Finds the width in pixels before the cursor on the same line - * @private - * @param {Number} lineIndex - * @param {Number} charIndex - * @return {Number} widthBeforeCursor width before cursor - */ - _getWidthBeforeCursor: function(lineIndex, charIndex) { - var widthBeforeCursor = this._getLineLeftOffset(lineIndex), bound; - - if (charIndex > 0) { - bound = this.__charBounds[lineIndex][charIndex - 1]; - widthBeforeCursor += bound.left + bound.width; - } - return widthBeforeCursor; - }, - - /** - * Gets start offset of a selection - * @param {Event} e Event object - * @param {Boolean} isRight - * @return {Number} - */ - getDownCursorOffset: function(e, isRight) { - var selectionProp = this._getSelectionForOffset(e, isRight), - cursorLocation = this.get2DCursorLocation(selectionProp), - lineIndex = cursorLocation.lineIndex; - // if on last line, down cursor goes to end of line - if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) { - // move to the end of a text - return this._text.length - selectionProp; - } - var charIndex = cursorLocation.charIndex, - widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex), - indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor), - textAfterCursor = this._textLines[lineIndex].slice(charIndex); - return textAfterCursor.length + indexOnOtherLine + 1 + this.missingNewlineOffset(lineIndex); - }, - - /** - * private - * Helps finding if the offset should be counted from Start or End - * @param {Event} e Event object - * @param {Boolean} isRight - * @return {Number} - */ - _getSelectionForOffset: function(e, isRight) { - if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) { - return this.selectionEnd; - } - else { - return this.selectionStart; - } - }, - - /** - * @param {Event} e Event object - * @param {Boolean} isRight - * @return {Number} - */ - getUpCursorOffset: function(e, isRight) { - var selectionProp = this._getSelectionForOffset(e, isRight), - cursorLocation = this.get2DCursorLocation(selectionProp), - lineIndex = cursorLocation.lineIndex; - if (lineIndex === 0 || e.metaKey || e.keyCode === 33) { - // if on first line, up cursor goes to start of line - return -selectionProp; - } - var charIndex = cursorLocation.charIndex, - widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex), - indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor), - textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex), - missingNewlineOffset = this.missingNewlineOffset(lineIndex - 1); - // return a negative offset - return -this._textLines[lineIndex - 1].length - + indexOnOtherLine - textBeforeCursor.length + (1 - missingNewlineOffset); - }, - - /** - * for a given width it founds the matching character. - * @private - */ - _getIndexOnLine: function(lineIndex, width) { - - var line = this._textLines[lineIndex], - lineLeftOffset = this._getLineLeftOffset(lineIndex), - widthOfCharsOnLine = lineLeftOffset, - indexOnLine = 0, charWidth, foundMatch; - - for (var j = 0, jlen = line.length; j < jlen; j++) { - charWidth = this.__charBounds[lineIndex][j].width; - widthOfCharsOnLine += charWidth; - if (widthOfCharsOnLine > width) { - foundMatch = true; - var leftEdge = widthOfCharsOnLine - charWidth, - rightEdge = widthOfCharsOnLine, - offsetFromLeftEdge = Math.abs(leftEdge - width), - offsetFromRightEdge = Math.abs(rightEdge - width); - - indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : (j - 1); - break; - } - } - - // reached end - if (!foundMatch) { - indexOnLine = line.length - 1; - } - - return indexOnLine; - }, - - - /** - * Moves cursor down - * @param {Event} e Event object - */ - moveCursorDown: function(e) { - if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) { - return; - } - this._moveCursorUpOrDown('Down', e); - }, - - /** - * Moves cursor up - * @param {Event} e Event object - */ - moveCursorUp: function(e) { - if (this.selectionStart === 0 && this.selectionEnd === 0) { - return; - } - this._moveCursorUpOrDown('Up', e); - }, - - /** - * Moves cursor up or down, fires the events - * @param {String} direction 'Up' or 'Down' - * @param {Event} e Event object - */ - _moveCursorUpOrDown: function(direction, e) { - // getUpCursorOffset - // getDownCursorOffset - var action = 'get' + direction + 'CursorOffset', - offset = this[action](e, this._selectionDirection === 'right'); - if (e.shiftKey) { - this.moveCursorWithShift(offset); - } - else { - this.moveCursorWithoutShift(offset); - } - if (offset !== 0) { - this.setSelectionInBoundaries(); - this.abortCursorAnimation(); - this._currentCursorOpacity = 1; - this.initDelayedCursor(); - this._fireSelectionChanged(); - this._updateTextarea(); - } - }, - - /** - * Moves cursor with shift - * @param {Number} offset - */ - moveCursorWithShift: function(offset) { - var newSelection = this._selectionDirection === 'left' - ? this.selectionStart + offset - : this.selectionEnd + offset; - this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, newSelection); - return offset !== 0; - }, - - /** - * Moves cursor up without shift - * @param {Number} offset - */ - moveCursorWithoutShift: function(offset) { - if (offset < 0) { - this.selectionStart += offset; - this.selectionEnd = this.selectionStart; - } - else { - this.selectionEnd += offset; - this.selectionStart = this.selectionEnd; - } - return offset !== 0; - }, - - /** - * Moves cursor left - * @param {Event} e Event object - */ - moveCursorLeft: function(e) { - if (this.selectionStart === 0 && this.selectionEnd === 0) { - return; - } - this._moveCursorLeftOrRight('Left', e); - }, - - /** - * @private - * @return {Boolean} true if a change happened - */ - _move: function(e, prop, direction) { - var newValue; - if (e.altKey) { - newValue = this['findWordBoundary' + direction](this[prop]); - } - else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36 ) { - newValue = this['findLineBoundary' + direction](this[prop]); - } - else { - this[prop] += direction === 'Left' ? -1 : 1; - return true; - } - if (typeof newValue !== undefined && this[prop] !== newValue) { - this[prop] = newValue; - return true; - } - }, - - /** - * @private - */ - _moveLeft: function(e, prop) { - return this._move(e, prop, 'Left'); - }, - - /** - * @private - */ - _moveRight: function(e, prop) { - return this._move(e, prop, 'Right'); - }, - - /** - * Moves cursor left without keeping selection - * @param {Event} e - */ - moveCursorLeftWithoutShift: function(e) { - var change = true; - this._selectionDirection = 'left'; - - // only move cursor when there is no selection, - // otherwise we discard it, and leave cursor on same place - if (this.selectionEnd === this.selectionStart && this.selectionStart !== 0) { - change = this._moveLeft(e, 'selectionStart'); - - } - this.selectionEnd = this.selectionStart; - return change; - }, - - /** - * Moves cursor left while keeping selection - * @param {Event} e - */ - moveCursorLeftWithShift: function(e) { - if (this._selectionDirection === 'right' && this.selectionStart !== this.selectionEnd) { - return this._moveLeft(e, 'selectionEnd'); - } - else if (this.selectionStart !== 0){ - this._selectionDirection = 'left'; - return this._moveLeft(e, 'selectionStart'); - } - }, - - /** - * Moves cursor right - * @param {Event} e Event object - */ - moveCursorRight: function(e) { - if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) { - return; - } - this._moveCursorLeftOrRight('Right', e); - }, - - /** - * Moves cursor right or Left, fires event - * @param {String} direction 'Left', 'Right' - * @param {Event} e Event object - */ - _moveCursorLeftOrRight: function(direction, e) { - var actionName = 'moveCursor' + direction + 'With'; - this._currentCursorOpacity = 1; - - if (e.shiftKey) { - actionName += 'Shift'; - } - else { - actionName += 'outShift'; - } - if (this[actionName](e)) { - this.abortCursorAnimation(); - this.initDelayedCursor(); - this._fireSelectionChanged(); - this._updateTextarea(); - } - }, - - /** - * Moves cursor right while keeping selection - * @param {Event} e - */ - moveCursorRightWithShift: function(e) { - if (this._selectionDirection === 'left' && this.selectionStart !== this.selectionEnd) { - return this._moveRight(e, 'selectionStart'); - } - else if (this.selectionEnd !== this._text.length) { - this._selectionDirection = 'right'; - return this._moveRight(e, 'selectionEnd'); - } - }, - - /** - * Moves cursor right without keeping selection - * @param {Event} e Event object - */ - moveCursorRightWithoutShift: function(e) { - var changed = true; - this._selectionDirection = 'right'; - - if (this.selectionStart === this.selectionEnd) { - changed = this._moveRight(e, 'selectionStart'); - this.selectionEnd = this.selectionStart; - } - else { - this.selectionStart = this.selectionEnd; - } - return changed; - }, - - /** - * Removes characters from start/end - * start/end ar per grapheme position in _text array. - * - * @param {Number} start - * @param {Number} end default to start + 1 - */ - removeChars: function(start, end) { - if (typeof end === 'undefined') { - end = start + 1; - } - this.removeStyleFromTo(start, end); - this._text.splice(start, end - start); - this.text = this._text.join(''); - this.set('dirty', true); - if (this._shouldClearDimensionCache()) { - this.initDimensions(); - this.setCoords(); - } - this._removeExtraneousStyles(); - }, - - /** - * insert characters at start position, before start position. - * start equal 1 it means the text get inserted between actual grapheme 0 and 1 - * if style array is provided, it must be as the same length of text in graphemes - * if end is provided and is bigger than start, old text is replaced. - * start/end ar per grapheme position in _text array. - * - * @param {String} text text to insert - * @param {Array} style array of style objects - * @param {Number} start - * @param {Number} end default to start + 1 - */ - insertChars: function(text, style, start, end) { - if (typeof end === 'undefined') { - end = start; - } - if (end > start) { - this.removeStyleFromTo(start, end); - } - var graphemes = fabric.util.string.graphemeSplit(text); - this.insertNewStyleBlock(graphemes, start, style); - this._text = [].concat(this._text.slice(0, start), graphemes, this._text.slice(end)); - this.text = this._text.join(''); - this.set('dirty', true); - if (this._shouldClearDimensionCache()) { - this.initDimensions(); - this.setCoords(); - } - this._removeExtraneousStyles(); - }, - -}); - - -/* _TO_SVG_START_ */ -(function() { - var toFixed = fabric.util.toFixed, - multipleSpacesRegex = / +/g; - - fabric.util.object.extend(fabric.Text.prototype, /** @lends fabric.Text.prototype */ { - - /** - * Returns SVG representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - _toSVG: function() { - var offsets = this._getSVGLeftTopOffsets(), - textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft); - return this._wrapSVGTextAndBg(textAndBg); - }, - - /** - * Returns svg representation of an instance - * @param {Function} [reviver] Method for further parsing of svg representation. - * @return {String} svg representation of an instance - */ - toSVG: function(reviver) { - return this._createBaseSVGMarkup( - this._toSVG(), - { reviver: reviver, noStyle: true, withShadow: true } - ); - }, - - /** - * @private - */ - _getSVGLeftTopOffsets: function() { - return { - textLeft: -this.width / 2, - textTop: -this.height / 2, - lineTop: this.getHeightOfLine(0) - }; - }, - - /** - * @private - */ - _wrapSVGTextAndBg: function(textAndBg) { - var noShadow = true, - textDecoration = this.getSvgTextDecoration(this); - return [ - textAndBg.textBgRects.join(''), - '\t\t', - textAndBg.textSpans.join(''), - '\n' - ]; - }, - - /** - * @private - * @param {Number} textTopOffset Text top offset - * @param {Number} textLeftOffset Text left offset - * @return {Object} - */ - _getSVGTextAndBg: function(textTopOffset, textLeftOffset) { - var textSpans = [], - textBgRects = [], - height = textTopOffset, lineOffset; - // bounding-box background - this._setSVGBg(textBgRects); - - // text and text-background - for (var i = 0, len = this._textLines.length; i < len; i++) { - lineOffset = this._getLineLeftOffset(i); - if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) { - this._setSVGTextLineBg(textBgRects, i, textLeftOffset + lineOffset, height); - } - this._setSVGTextLineText(textSpans, i, textLeftOffset + lineOffset, height); - height += this.getHeightOfLine(i); - } - - return { - textSpans: textSpans, - textBgRects: textBgRects - }; - }, - - /** - * @private - */ - _createTextCharSpan: function(_char, styleDecl, left, top) { - var shouldUseWhitespace = _char !== _char.trim() || _char.match(multipleSpacesRegex), - styleProps = this.getSvgSpanStyles(styleDecl, shouldUseWhitespace), - fillStyles = styleProps ? 'style="' + styleProps + '"' : '', - dy = styleDecl.deltaY, dySpan = '', - NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - if (dy) { - dySpan = ' dy="' + toFixed(dy, NUM_FRACTION_DIGITS) + '" '; - } - return [ - '', - fabric.util.string.escapeXml(_char), - '' - ].join(''); - }, - - _setSVGTextLineText: function(textSpans, lineIndex, textLeftOffset, textTopOffset) { - // set proper line offset - var lineHeight = this.getHeightOfLine(lineIndex), - isJustify = this.textAlign.indexOf('justify') !== -1, - actualStyle, - nextStyle, - charsToRender = '', - charBox, style, - boxWidth = 0, - line = this._textLines[lineIndex], - timeToRender; - - textTopOffset += lineHeight * (1 - this._fontSizeFraction) / this.lineHeight; - for (var i = 0, len = line.length - 1; i <= len; i++) { - timeToRender = i === len || this.charSpacing; - charsToRender += line[i]; - charBox = this.__charBounds[lineIndex][i]; - if (boxWidth === 0) { - textLeftOffset += charBox.kernedWidth - charBox.width; - boxWidth += charBox.width; - } - else { - boxWidth += charBox.kernedWidth; - } - if (isJustify && !timeToRender) { - if (this._reSpaceAndTab.test(line[i])) { - timeToRender = true; - } - } - if (!timeToRender) { - // if we have charSpacing, we render char by char - actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i); - nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1); - timeToRender = this._hasStyleChangedForSvg(actualStyle, nextStyle); - } - if (timeToRender) { - style = this._getStyleDeclaration(lineIndex, i) || { }; - textSpans.push(this._createTextCharSpan(charsToRender, style, textLeftOffset, textTopOffset)); - charsToRender = ''; - actualStyle = nextStyle; - textLeftOffset += boxWidth; - boxWidth = 0; - } - } - }, - - _pushTextBgRect: function(textBgRects, color, left, top, width, height) { - var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - textBgRects.push( - '\t\t\n'); - }, - - _setSVGTextLineBg: function(textBgRects, i, leftOffset, textTopOffset) { - var line = this._textLines[i], - heightOfLine = this.getHeightOfLine(i) / this.lineHeight, - boxWidth = 0, - boxStart = 0, - charBox, currentColor, - lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor'); - for (var j = 0, jlen = line.length; j < jlen; j++) { - charBox = this.__charBounds[i][j]; - currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor'); - if (currentColor !== lastColor) { - lastColor && this._pushTextBgRect(textBgRects, lastColor, leftOffset + boxStart, - textTopOffset, boxWidth, heightOfLine); - boxStart = charBox.left; - boxWidth = charBox.width; - lastColor = currentColor; - } - else { - boxWidth += charBox.kernedWidth; - } - } - currentColor && this._pushTextBgRect(textBgRects, currentColor, leftOffset + boxStart, - textTopOffset, boxWidth, heightOfLine); - }, - - /** - * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values - * we work around it by "moving" alpha channel into opacity attribute and setting fill's alpha to 1 - * - * @private - * @param {*} value - * @return {String} - */ - _getFillAttributes: function(value) { - var fillColor = (value && typeof value === 'string') ? new fabric.Color(value) : ''; - if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) { - return 'fill="' + value + '"'; - } - return 'opacity="' + fillColor.getAlpha() + '" fill="' + fillColor.setAlpha(1).toRgb() + '"'; - }, - - /** - * @private - */ - _getSVGLineTopOffset: function(lineIndex) { - var lineTopOffset = 0, lastHeight = 0; - for (var j = 0; j < lineIndex; j++) { - lineTopOffset += this.getHeightOfLine(j); - } - lastHeight = this.getHeightOfLine(j); - return { - lineTop: lineTopOffset, - offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult) - }; - }, - - /** - * Returns styles-string for svg-export - * @param {Boolean} skipShadow a boolean to skip shadow filter output - * @return {String} - */ - getSvgStyles: function(skipShadow) { - var svgStyle = fabric.Object.prototype.getSvgStyles.call(this, skipShadow); - return svgStyle + ' white-space: pre;'; - }, - }); -})(); -/* _TO_SVG_END_ */ - - -(function(global) { - - 'use strict'; - - var fabric = global.fabric || (global.fabric = {}); - - /** - * Textbox class, based on IText, allows the user to resize the text rectangle - * and wraps lines automatically. Textboxes have their Y scaling locked, the - * user can only change width. Height is adjusted automatically based on the - * wrapping of lines. - * @class fabric.Textbox - * @extends fabric.IText - * @mixes fabric.Observable - * @return {fabric.Textbox} thisArg - * @see {@link fabric.Textbox#initialize} for constructor definition - */ - fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, { - - /** - * Type of an object - * @type String - * @default - */ - type: 'textbox', - - /** - * Minimum width of textbox, in pixels. - * @type Number - * @default - */ - minWidth: 20, - - /** - * Minimum calculated width of a textbox, in pixels. - * fixed to 2 so that an empty textbox cannot go to 0 - * and is still selectable without text. - * @type Number - * @default - */ - dynamicMinWidth: 2, - - /** - * Cached array of text wrapping. - * @type Array - */ - __cachedLines: null, - - /** - * Override standard Object class values - */ - lockScalingFlip: true, - - /** - * Override standard Object class values - * Textbox needs this on false - */ - noScaleCache: false, - - /** - * Properties which when set cause object to change dimensions - * @type Object - * @private - */ - _dimensionAffectingProps: fabric.Text.prototype._dimensionAffectingProps.concat('width'), - - /** - * Use this regular expression to split strings in breakable lines - * @private - */ - _wordJoiners: /[ \t\r]/, - - /** - * Use this boolean property in order to split strings that have no white space concept. - * this is a cheap way to help with chinese/japanese - * @type Boolean - * @since 2.6.0 - */ - splitByGrapheme: false, - - /** - * Unlike superclass's version of this function, Textbox does not update - * its width. - * @private - * @override - */ - initDimensions: function() { - if (this.__skipDimension) { - return; - } - this.isEditing && this.initDelayedCursor(); - this.clearContextTop(); - this._clearCache(); - // clear dynamicMinWidth as it will be different after we re-wrap line - this.dynamicMinWidth = 0; - // wrap lines - this._styleMap = this._generateStyleMap(this._splitText()); - // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap - if (this.dynamicMinWidth > this.width) { - this._set('width', this.dynamicMinWidth); - } - if (this.textAlign.indexOf('justify') !== -1) { - // once text is measured we need to make space fatter to make justified text. - this.enlargeSpaces(); - } - // clear cache and re-calculate height - this.height = this.calcTextHeight(); - this.saveState({ propertySet: '_dimensionAffectingProps' }); - }, - - /** - * Generate an object that translates the style object so that it is - * broken up by visual lines (new lines and automatic wrapping). - * The original text styles object is broken up by actual lines (new lines only), - * which is only sufficient for Text / IText - * @private - */ - _generateStyleMap: function(textInfo) { - var realLineCount = 0, - realLineCharCount = 0, - charCount = 0, - map = {}; - - for (var i = 0; i < textInfo.graphemeLines.length; i++) { - if (textInfo.graphemeText[charCount] === '\n' && i > 0) { - realLineCharCount = 0; - charCount++; - realLineCount++; - } - else if (!this.splitByGrapheme && this._reSpaceAndTab.test(textInfo.graphemeText[charCount]) && i > 0) { - // this case deals with space's that are removed from end of lines when wrapping - realLineCharCount++; - charCount++; - } - - map[i] = { line: realLineCount, offset: realLineCharCount }; - - charCount += textInfo.graphemeLines[i].length; - realLineCharCount += textInfo.graphemeLines[i].length; - } - - return map; - }, - - /** - * Returns true if object has a style property or has it on a specified line - * @param {Number} lineIndex - * @return {Boolean} - */ - styleHas: function(property, lineIndex) { - if (this._styleMap && !this.isWrapping) { - var map = this._styleMap[lineIndex]; - if (map) { - lineIndex = map.line; - } - } - return fabric.Text.prototype.styleHas.call(this, property, lineIndex); - }, - - /** - * Returns true if object has no styling or no styling in a line - * @param {Number} lineIndex , lineIndex is on wrapped lines. - * @return {Boolean} - */ - isEmptyStyles: function(lineIndex) { - if (!this.styles) { - return true; - } - var offset = 0, nextLineIndex = lineIndex + 1, nextOffset, obj, shouldLimit = false, - map = this._styleMap[lineIndex], mapNextLine = this._styleMap[lineIndex + 1]; - if (map) { - lineIndex = map.line; - offset = map.offset; - } - if (mapNextLine) { - nextLineIndex = mapNextLine.line; - shouldLimit = nextLineIndex === lineIndex; - nextOffset = mapNextLine.offset; - } - obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] }; - for (var p1 in obj) { - for (var p2 in obj[p1]) { - if (p2 >= offset && (!shouldLimit || p2 < nextOffset)) { - // eslint-disable-next-line no-unused-vars - for (var p3 in obj[p1][p2]) { - return false; - } - } - } - } - return true; - }, - - /** - * @param {Number} lineIndex - * @param {Number} charIndex - * @private - */ - _getStyleDeclaration: function(lineIndex, charIndex) { - if (this._styleMap && !this.isWrapping) { - var map = this._styleMap[lineIndex]; - if (!map) { - return null; - } - lineIndex = map.line; - charIndex = map.offset + charIndex; - } - return this.callSuper('_getStyleDeclaration', lineIndex, charIndex); - }, - - /** - * @param {Number} lineIndex - * @param {Number} charIndex - * @param {Object} style - * @private - */ - _setStyleDeclaration: function(lineIndex, charIndex, style) { - var map = this._styleMap[lineIndex]; - lineIndex = map.line; - charIndex = map.offset + charIndex; - - this.styles[lineIndex][charIndex] = style; - }, - - /** - * @param {Number} lineIndex - * @param {Number} charIndex - * @private - */ - _deleteStyleDeclaration: function(lineIndex, charIndex) { - var map = this._styleMap[lineIndex]; - lineIndex = map.line; - charIndex = map.offset + charIndex; - delete this.styles[lineIndex][charIndex]; - }, - - /** - * probably broken need a fix - * Returns the real style line that correspond to the wrapped lineIndex line - * Used just to verify if the line does exist or not. - * @param {Number} lineIndex - * @returns {Boolean} if the line exists or not - * @private - */ - _getLineStyle: function(lineIndex) { - var map = this._styleMap[lineIndex]; - return !!this.styles[map.line]; - }, - - /** - * Set the line style to an empty object so that is initialized - * @param {Number} lineIndex - * @param {Object} style - * @private - */ - _setLineStyle: function(lineIndex) { - var map = this._styleMap[lineIndex]; - this.styles[map.line] = {}; - }, - - /** - * Wraps text using the 'width' property of Textbox. First this function - * splits text on newlines, so we preserve newlines entered by the user. - * Then it wraps each line using the width of the Textbox by calling - * _wrapLine(). - * @param {Array} lines The string array of text that is split into lines - * @param {Number} desiredWidth width you want to wrap to - * @returns {Array} Array of lines - */ - _wrapText: function(lines, desiredWidth) { - var wrapped = [], i; - this.isWrapping = true; - for (i = 0; i < lines.length; i++) { - wrapped = wrapped.concat(this._wrapLine(lines[i], i, desiredWidth)); - } - this.isWrapping = false; - return wrapped; - }, - - /** - * Helper function to measure a string of text, given its lineIndex and charIndex offset - * it gets called when charBounds are not available yet. - * @param {CanvasRenderingContext2D} ctx - * @param {String} text - * @param {number} lineIndex - * @param {number} charOffset - * @returns {number} - * @private - */ - _measureWord: function(word, lineIndex, charOffset) { - var width = 0, prevGrapheme, skipLeft = true; - charOffset = charOffset || 0; - for (var i = 0, len = word.length; i < len; i++) { - var box = this._getGraphemeBox(word[i], lineIndex, i + charOffset, prevGrapheme, skipLeft); - width += box.kernedWidth; - prevGrapheme = word[i]; - } - return width; - }, - - /** - * Wraps a line of text using the width of the Textbox and a context. - * @param {Array} line The grapheme array that represent the line - * @param {Number} lineIndex - * @param {Number} desiredWidth width you want to wrap the line to - * @param {Number} reservedSpace space to remove from wrapping for custom functionalities - * @returns {Array} Array of line(s) into which the given text is wrapped - * to. - */ - _wrapLine: function(_line, lineIndex, desiredWidth, reservedSpace) { - var lineWidth = 0, - splitByGrapheme = this.splitByGrapheme, - graphemeLines = [], - line = [], - // spaces in different languages? - words = splitByGrapheme ? fabric.util.string.graphemeSplit(_line) : _line.split(this._wordJoiners), - word = '', - offset = 0, - infix = splitByGrapheme ? '' : ' ', - wordWidth = 0, - infixWidth = 0, - largestWordWidth = 0, - lineJustStarted = true, - additionalSpace = this._getWidthOfCharSpacing(), - reservedSpace = reservedSpace || 0; - // fix a difference between split and graphemeSplit - if (words.length === 0) { - words.push([]); - } - desiredWidth -= reservedSpace; - for (var i = 0; i < words.length; i++) { - // if using splitByGrapheme words are already in graphemes. - word = splitByGrapheme ? words[i] : fabric.util.string.graphemeSplit(words[i]); - wordWidth = this._measureWord(word, lineIndex, offset); - offset += word.length; - - lineWidth += infixWidth + wordWidth - additionalSpace; - if (lineWidth > desiredWidth && !lineJustStarted) { - graphemeLines.push(line); - line = []; - lineWidth = wordWidth; - lineJustStarted = true; - } - else { - lineWidth += additionalSpace; - } - - if (!lineJustStarted && !splitByGrapheme) { - line.push(infix); - } - line = line.concat(word); - - infixWidth = splitByGrapheme ? 0 : this._measureWord([infix], lineIndex, offset); - offset++; - lineJustStarted = false; - // keep track of largest word - if (wordWidth > largestWordWidth) { - largestWordWidth = wordWidth; - } - } - - i && graphemeLines.push(line); - - if (largestWordWidth + reservedSpace > this.dynamicMinWidth) { - this.dynamicMinWidth = largestWordWidth - additionalSpace + reservedSpace; - } - return graphemeLines; - }, - - /** - * Detect if the text line is ended with an hard break - * text and itext do not have wrapping, return false - * @param {Number} lineIndex text to split - * @return {Boolean} - */ - isEndOfWrapping: function(lineIndex) { - if (!this._styleMap[lineIndex + 1]) { - // is last line, return true; - return true; - } - if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) { - // this is last line before a line break, return true; - return true; - } - return false; - }, - - /** - * Detect if a line has a linebreak and so we need to account for it when moving - * and counting style. - * @return Number - */ - missingNewlineOffset: function(lineIndex) { - if (this.splitByGrapheme) { - return this.isEndOfWrapping(lineIndex) ? 1 : 0; - } - return 1; - }, - - /** - * Gets lines of text to render in the Textbox. This function calculates - * text wrapping on the fly every time it is called. - * @param {String} text text to split - * @returns {Array} Array of lines in the Textbox. - * @override - */ - _splitTextIntoLines: function(text) { - var newText = fabric.Text.prototype._splitTextIntoLines.call(this, text), - graphemeLines = this._wrapText(newText.lines, this.width), - lines = new Array(graphemeLines.length); - for (var i = 0; i < graphemeLines.length; i++) { - lines[i] = graphemeLines[i].join(''); - } - newText.lines = lines; - newText.graphemeLines = graphemeLines; - return newText; - }, - - getMinWidth: function() { - return Math.max(this.minWidth, this.dynamicMinWidth); - }, - - _removeExtraneousStyles: function() { - var linesToKeep = {}; - for (var prop in this._styleMap) { - if (this._textLines[prop]) { - linesToKeep[this._styleMap[prop].line] = 1; - } - } - for (var prop in this.styles) { - if (!linesToKeep[prop]) { - delete this.styles[prop]; - } - } - }, - - /** - * Returns object representation of an instance - * @method toObject - * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {Object} object representation of an instance - */ - toObject: function(propertiesToInclude) { - return this.callSuper('toObject', ['minWidth', 'splitByGrapheme'].concat(propertiesToInclude)); - } - }); - - /** - * Returns fabric.Textbox instance from an object representation - * @static - * @memberOf fabric.Textbox - * @param {Object} object Object to create an instance from - * @param {Function} [callback] Callback to invoke when an fabric.Textbox instance is created - */ - fabric.Textbox.fromObject = function(object, callback) { - return fabric.Object._fromObject('Textbox', object, callback, 'text'); - }; -})(typeof exports !== 'undefined' ? exports : this); - - -(function() { - - var controlsUtils = fabric.controlsUtils, - scaleSkewStyleHandler = controlsUtils.scaleSkewCursorStyleHandler, - scaleStyleHandler = controlsUtils.scaleCursorStyleHandler, - scalingEqually = controlsUtils.scalingEqually, - scalingYOrSkewingX = controlsUtils.scalingYOrSkewingX, - scalingXOrSkewingY = controlsUtils.scalingXOrSkewingY, - scaleOrSkewActionName = controlsUtils.scaleOrSkewActionName, - objectControls = fabric.Object.prototype.controls; - - objectControls.ml = new fabric.Control({ - x: -0.5, - y: 0, - cursorStyleHandler: scaleSkewStyleHandler, - actionHandler: scalingXOrSkewingY, - getActionName: scaleOrSkewActionName, - }); - - objectControls.mr = new fabric.Control({ - x: 0.5, - y: 0, - cursorStyleHandler: scaleSkewStyleHandler, - actionHandler: scalingXOrSkewingY, - getActionName: scaleOrSkewActionName, - }); - - objectControls.mb = new fabric.Control({ - x: 0, - y: 0.5, - cursorStyleHandler: scaleSkewStyleHandler, - actionHandler: scalingYOrSkewingX, - getActionName: scaleOrSkewActionName, - }); - - objectControls.mt = new fabric.Control({ - x: 0, - y: -0.5, - cursorStyleHandler: scaleSkewStyleHandler, - actionHandler: scalingYOrSkewingX, - getActionName: scaleOrSkewActionName, - }); - - objectControls.tl = new fabric.Control({ - x: -0.5, - y: -0.5, - cursorStyleHandler: scaleStyleHandler, - actionHandler: scalingEqually - }); - - objectControls.tr = new fabric.Control({ - x: 0.5, - y: -0.5, - cursorStyleHandler: scaleStyleHandler, - actionHandler: scalingEqually - }); - - objectControls.bl = new fabric.Control({ - x: -0.5, - y: 0.5, - cursorStyleHandler: scaleStyleHandler, - actionHandler: scalingEqually - }); - - objectControls.br = new fabric.Control({ - x: 0.5, - y: 0.5, - cursorStyleHandler: scaleStyleHandler, - actionHandler: scalingEqually - }); - - objectControls.mtr = new fabric.Control({ - x: 0, - y: -0.5, - actionHandler: controlsUtils.rotationWithSnapping, - cursorStyleHandler: controlsUtils.rotationStyleHandler, - offsetY: -40, - withConnection: true, - actionName: 'rotate', - }); - - if (fabric.Textbox) { - // this is breaking the prototype inheritance, no time / ideas to fix it. - // is important to document that if you want to have all objects to have a - // specific custom control, you have to add it to Object prototype and to Textbox - // prototype. The controls are shared as references. So changes to control `tr` - // can still apply to all objects if needed. - var textBoxControls = fabric.Textbox.prototype.controls = { }; - - textBoxControls.mtr = objectControls.mtr; - textBoxControls.tr = objectControls.tr; - textBoxControls.br = objectControls.br; - textBoxControls.tl = objectControls.tl; - textBoxControls.bl = objectControls.bl; - textBoxControls.mt = objectControls.mt; - textBoxControls.mb = objectControls.mb; - - textBoxControls.mr = new fabric.Control({ - x: 0.5, - y: 0, - actionHandler: controlsUtils.changeWidth, - cursorStyleHandler: scaleSkewStyleHandler, - actionName: 'resizing', - }); - - textBoxControls.ml = new fabric.Control({ - x: -0.5, - y: 0, - actionHandler: controlsUtils.changeWidth, - cursorStyleHandler: scaleSkewStyleHandler, - actionName: 'resizing', - }); - } -})(); - diff --git a/web/static/js9_old/js/fabric-v5.2.1.min.js b/web/static/js9_old/js/fabric-v5.2.1.min.js deleted file mode 100644 index 38f1c3d23d37126c27b9770f6671cce17d1f26e6..0000000000000000000000000000000000000000 --- a/web/static/js9_old/js/fabric-v5.2.1.min.js +++ /dev/null @@ -1 +0,0 @@ -var fabric=fabric||{version:"5.2.1"};if("undefined"!=typeof exports?exports.fabric=fabric:"function"==typeof define&&define.amd&&define([],function(){return fabric}),"undefined"!=typeof document&&"undefined"!=typeof window)document instanceof("undefined"!=typeof HTMLDocument?HTMLDocument:Document)?fabric.document=document:fabric.document=document.implementation.createHTMLDocument(""),fabric.window=window;else{var jsdom=require("jsdom"),virtualWindow=new jsdom.JSDOM(decodeURIComponent("%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E"),{features:{FetchExternalResources:["img"]},resources:"usable"}).window;fabric.document=virtualWindow.document,fabric.jsdomImplForWrapper=require("jsdom/lib/jsdom/living/generated/utils").implForWrapper,fabric.nodeCanvas=require("jsdom/lib/jsdom/utils").Canvas,fabric.window=virtualWindow,DOMParser=fabric.window.DOMParser}function resizeCanvasIfNeeded(t){var e=t.targetCanvas,i=e.width,r=e.height,n=t.destinationWidth,s=t.destinationHeight;i===n&&r===s||(e.width=n,e.height=s)}function copyGLTo2DDrawImage(t,e){var i=t.canvas,r=e.targetCanvas,n=r.getContext("2d");n.translate(0,r.height),n.scale(1,-1);var s=i.height-r.height;n.drawImage(i,0,s,r.width,r.height,0,0,r.width,r.height)}function copyGLTo2DPutImageData(t,e){var i=e.targetCanvas.getContext("2d"),r=e.destinationWidth,n=e.destinationHeight,s=r*n*4,o=new Uint8Array(this.imageBuffer,0,s),a=new Uint8ClampedArray(this.imageBuffer,0,s);t.readPixels(0,0,r,n,t.RGBA,t.UNSIGNED_BYTE,o);var c=new ImageData(a,r,n);i.putImageData(c,0,0)}fabric.isTouchSupported="ontouchstart"in fabric.window||"ontouchstart"in fabric.document||fabric.window&&fabric.window.navigator&&0_)for(var C=1,S=d.length;Ct[i-2].x?1:n.x===t[i-2].x?0:-1,c=n.y>t[i-2].y?1:n.y===t[i-2].y?0:-1),r.push(["L",n.x+a*e,n.y+c*e]),r},fabric.util.getPathSegmentsInfo=l,fabric.util.getBoundsOfCurve=function(t,e,i,r,n,s,o,a){var c;if(fabric.cachesBoundsOfCurve&&(c=D.call(arguments),fabric.boundsOfCurveCache[c]))return fabric.boundsOfCurveCache[c];var h,l,u,f,d,g,p,v,m=Math.sqrt,b=Math.min,y=Math.max,_=Math.abs,x=[],C=[[],[]];l=6*t-12*i+6*n,h=-3*t+9*i-9*n+3*o,u=3*i-3*t;for(var S=0;S<2;++S)if(0/g,">")},graphemeSplit:function(t){var e,i=0,r=[];for(i=0;it.x&&this.y>t.y},gte:function(t){return this.x>=t.x&&this.y>=t.y},lerp:function(t,e){return void 0===e&&(e=.5),e=Math.max(Math.min(1,e),0),new i(this.x+(t.x-this.x)*e,this.y+(t.y-this.y)*e)},distanceFrom:function(t){var e=this.x-t.x,i=this.y-t.y;return Math.sqrt(e*e+i*i)},midPointFrom:function(t){return this.lerp(t)},min:function(t){return new i(Math.min(this.x,t.x),Math.min(this.y,t.y))},max:function(t){return new i(Math.max(this.x,t.x),Math.max(this.y,t.y))},toString:function(){return this.x+","+this.y},setXY:function(t,e){return this.x=t,this.y=e,this},setX:function(t){return this.x=t,this},setY:function(t){return this.y=t,this},setFromPoint:function(t){return this.x=t.x,this.y=t.y,this},swap:function(t){var e=this.x,i=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=i},clone:function(){return new i(this.x,this.y)}}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var f=t.fabric||(t.fabric={});function d(t){this.status=t,this.points=[]}f.Intersection?f.warn("fabric.Intersection is already defined"):(f.Intersection=d,f.Intersection.prototype={constructor:d,appendPoint:function(t){return this.points.push(t),this},appendPoints:function(t){return this.points=this.points.concat(t),this}},f.Intersection.intersectLineLine=function(t,e,i,r){var n,s=(r.x-i.x)*(t.y-i.y)-(r.y-i.y)*(t.x-i.x),o=(e.x-t.x)*(t.y-i.y)-(e.y-t.y)*(t.x-i.x),a=(r.y-i.y)*(e.x-t.x)-(r.x-i.x)*(e.y-t.y);if(0!==a){var c=s/a,h=o/a;0<=c&&c<=1&&0<=h&&h<=1?(n=new d("Intersection")).appendPoint(new f.Point(t.x+c*(e.x-t.x),t.y+c*(e.y-t.y))):n=new d}else n=new d(0===s||0===o?"Coincident":"Parallel");return n},f.Intersection.intersectLinePolygon=function(t,e,i){var r,n,s,o,a=new d,c=i.length;for(o=0;o=c&&(h.x-=c),h.x<=-c&&(h.x+=c),h.y>=c&&(h.y-=c),h.y<=c&&(h.y+=c),h.x-=o.offsetX,h.y-=o.offsetY,h}function y(t){return t.flipX!==t.flipY}function _(t,e,i,r,n){if(0!==t[e]){var s=n/t._getTransformedDimensions()[r]*t[i];t.set(i,s)}}function x(t,e,i,r){var n,s=e.target,o=s._getTransformedDimensions(0,s.skewY),a=P(e,e.originX,e.originY,i,r),c=Math.abs(2*a.x)-o.x,h=s.skewX;c<2?n=0:(n=v(Math.atan2(c/s.scaleX,o.y/s.scaleY)),e.originX===f&&e.originY===p&&(n=-n),e.originX===g&&e.originY===d&&(n=-n),y(s)&&(n=-n));var l=h!==n;if(l){var u=s._getTransformedDimensions().y;s.set("skewX",n),_(s,"skewY","scaleY","y",u)}return l}function C(t,e,i,r){var n,s=e.target,o=s._getTransformedDimensions(s.skewX,0),a=P(e,e.originX,e.originY,i,r),c=Math.abs(2*a.y)-o.y,h=s.skewY;c<2?n=0:(n=v(Math.atan2(c/s.scaleY,o.x/s.scaleX)),e.originX===f&&e.originY===p&&(n=-n),e.originX===g&&e.originY===d&&(n=-n),y(s)&&(n=-n));var l=h!==n;if(l){var u=s._getTransformedDimensions().x;s.set("skewY",n),_(s,"skewX","scaleX","x",u)}return l}function E(t,e,i,r,n){n=n||{};var s,o,a,c,h,l,u=e.target,f=u.lockScalingX,d=u.lockScalingY,g=n.by,p=w(t,u),v=k(u,g,p),m=e.gestureScale;if(v)return!1;if(m)o=e.scaleX*m,a=e.scaleY*m;else{if(s=P(e,e.originX,e.originY,i,r),h="y"!==g?T(s.x):1,l="x"!==g?T(s.y):1,e.signX||(e.signX=h),e.signY||(e.signY=l),u.lockScalingFlip&&(e.signX!==h||e.signY!==l))return!1;if(c=u._getTransformedDimensions(),p&&!g){var b=Math.abs(s.x)+Math.abs(s.y),y=e.original,_=b/(Math.abs(c.x*y.scaleX/u.scaleX)+Math.abs(c.y*y.scaleY/u.scaleY));o=y.scaleX*_,a=y.scaleY*_}else o=Math.abs(s.x*u.scaleX/c.x),a=Math.abs(s.y*u.scaleY/c.y);O(e)&&(o*=2,a*=2),e.signX!==h&&"y"!==g&&(e.originX=S[e.originX],o*=-1,e.signX=h),e.signY!==l&&"x"!==g&&(e.originY=S[e.originY],a*=-1,e.signY=l)}var x=u.scaleX,C=u.scaleY;return g?("x"===g&&u.set("scaleX",o),"y"===g&&u.set("scaleY",a)):(!f&&u.set("scaleX",o),!d&&u.set("scaleY",a)),x!==u.scaleX||C!==u.scaleY}n.scaleCursorStyleHandler=function(t,e,i){var r=w(t,i),n="";if(0!==e.x&&0===e.y?n="x":0===e.x&&0!==e.y&&(n="y"),k(i,n,r))return"not-allowed";var s=a(i,e);return o[s]+"-resize"},n.skewCursorStyleHandler=function(t,e,i){var r="not-allowed";if(0!==e.x&&i.lockSkewingY)return r;if(0!==e.y&&i.lockSkewingX)return r;var n=a(i,e)%4;return s[n]+"-resize"},n.scaleSkewCursorStyleHandler=function(t,e,i){return t[i.canvas.altActionKey]?n.skewCursorStyleHandler(t,e,i):n.scaleCursorStyleHandler(t,e,i)},n.rotationWithSnapping=b("rotating",m(function(t,e,i,r){var n=e,s=n.target,o=s.translateToOriginPoint(s.getCenterPoint(),n.originX,n.originY);if(s.lockRotation)return!1;var a,c=Math.atan2(n.ey-o.y,n.ex-o.x),h=Math.atan2(r-o.y,i-o.x),l=v(h-c+n.theta);if(0o.r2,h=this.gradientTransform?this.gradientTransform.concat():fabric.iMatrix.concat(),l=-this.offsetX,u=-this.offsetY,f=!!e.additionalTransform,d="pixels"===this.gradientUnits?"userSpaceOnUse":"objectBoundingBox";if(a.sort(function(t,e){return t.offset-e.offset}),"objectBoundingBox"===d?(l/=t.width,u/=t.height):(l+=t.width/2,u+=t.height/2),"path"===t.type&&"percentage"!==this.gradientUnits&&(l-=t.pathOffset.x,u-=t.pathOffset.y),h[4]-=l,h[5]-=u,s='id="SVGID_'+this.id+'" gradientUnits="'+d+'"',s+=' gradientTransform="'+(f?e.additionalTransform+" ":"")+fabric.util.matrixToSVG(h)+'" ',"linear"===this.type?n=["\n']:"radial"===this.type&&(n=["\n']),"radial"===this.type){if(c)for((a=a.concat()).reverse(),i=0,r=a.length;i\n')}return n.push("linear"===this.type?"\n":"\n"),n.join("")},toLive:function(t){var e,i,r,n=fabric.util.object.clone(this.coords);if(this.type){for("linear"===this.type?e=t.createLinearGradient(n.x1,n.y1,n.x2,n.y2):"radial"===this.type&&(e=t.createRadialGradient(n.x1,n.y1,n.r1,n.x2,n.y2,n.r2)),i=0,r=this.colorStops.length;i\n\n\n'},setOptions:function(t){for(var e in t)this[e]=t[e]},toLive:function(t){var e=this.source;if(!e)return"";if(void 0!==e.src){if(!e.complete)return"";if(0===e.naturalWidth||0===e.naturalHeight)return""}return t.createPattern(e,this.repeat)}})}(),function(t){"use strict";var o=t.fabric||(t.fabric={}),a=o.util.toFixed;o.Shadow?o.warn("fabric.Shadow is already defined."):(o.Shadow=o.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,nonScaling:!1,initialize:function(t){for(var e in"string"==typeof t&&(t=this._parseShadow(t)),t)this[e]=t[e];this.id=o.Object.__uid++},_parseShadow:function(t){var e=t.trim(),i=o.Shadow.reOffsetsAndBlur.exec(e)||[];return{color:(e.replace(o.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)").trim(),offsetX:parseFloat(i[1],10)||0,offsetY:parseFloat(i[2],10)||0,blur:parseFloat(i[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(t){var e=40,i=40,r=o.Object.NUM_FRACTION_DIGITS,n=o.util.rotateVector({x:this.offsetX,y:this.offsetY},o.util.degreesToRadians(-t.angle)),s=new o.Color(this.color);return t.width&&t.height&&(e=100*a((Math.abs(n.x)+this.blur)/t.width,r)+20,i=100*a((Math.abs(n.y)+this.blur)/t.height,r)+20),t.flipX&&(n.x*=-1),t.flipY&&(n.y*=-1),'\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n'},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke,nonScaling:this.nonScaling};var e={},i=o.Shadow.prototype;return["color","blur","offsetX","offsetY","affectStroke","nonScaling"].forEach(function(t){this[t]!==i[t]&&(e[t]=this[t])},this),e}}),o.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?(-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?(\d+(?:\.\d*)?(?:px)?)?(?:\s?|$)(?:$|\s)/)}("undefined"!=typeof exports?exports:this),function(){"use strict";if(fabric.StaticCanvas)fabric.warn("fabric.StaticCanvas is already defined.");else{var n=fabric.util.object.extend,t=fabric.util.getElementOffset,h=fabric.util.removeFromArray,a=fabric.util.toFixed,s=fabric.util.transformPoint,o=fabric.util.invertTransform,i=fabric.util.getNodeCanvas,r=fabric.util.createCanvasElement,e=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass(fabric.CommonMethods,{initialize:function(t,e){e||(e={}),this.renderAndResetBound=this.renderAndReset.bind(this),this.requestRenderAllBound=this.requestRenderAll.bind(this),this._initStatic(t,e)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!1,renderOnAddRemove:!0,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,viewportTransform:fabric.iMatrix.concat(),backgroundVpt:!0,overlayVpt:!0,enableRetinaScaling:!0,vptCoords:{},skipOffscreen:!0,clipPath:void 0,_initStatic:function(t,e){var i=this.requestRenderAllBound;this._objects=[],this._createLowerCanvas(t),this._initOptions(e),this.interactive||this._initRetinaScaling(),e.overlayImage&&this.setOverlayImage(e.overlayImage,i),e.backgroundImage&&this.setBackgroundImage(e.backgroundImage,i),e.backgroundColor&&this.setBackgroundColor(e.backgroundColor,i),e.overlayColor&&this.setOverlayColor(e.overlayColor,i),this.calcOffset()},_isRetinaScaling:function(){return 1\n'),this._setSVGBgOverlayColor(i,"background"),this._setSVGBgOverlayImage(i,"backgroundImage",e),this._setSVGObjects(i,e),this.clipPath&&i.push("
    \n"),this._setSVGBgOverlayColor(i,"overlay"),this._setSVGBgOverlayImage(i,"overlayImage",e),i.push(""),i.join("")},_setSVGPreamble:function(t,e){e.suppressPreamble||t.push('\n','\n')},_setSVGHeader:function(t,e){var i,r=e.width||this.width,n=e.height||this.height,s='viewBox="0 0 '+this.width+" "+this.height+'" ',o=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?s='viewBox="'+e.viewBox.x+" "+e.viewBox.y+" "+e.viewBox.width+" "+e.viewBox.height+'" ':this.svgViewportTransformation&&(i=this.viewportTransform,s='viewBox="'+a(-i[4]/i[0],o)+" "+a(-i[5]/i[3],o)+" "+a(this.width/i[0],o)+" "+a(this.height/i[3],o)+'" '),t.push("\n',"Created with Fabric.js ",fabric.version,"\n","\n",this.createSVGFontFacesMarkup(),this.createSVGRefElementsMarkup(),this.createSVGClipPathMarkup(e),"\n")},createSVGClipPathMarkup:function(t){var e=this.clipPath;return e?(e.clipPathId="CLIPPATH_"+fabric.Object.__uid++,'\n'+this.clipPath.toClipPathSVG(t.reviver)+"\n"):""},createSVGRefElementsMarkup:function(){var s=this;return["background","overlay"].map(function(t){var e=s[t+"Color"];if(e&&e.toLive){var i=s[t+"Vpt"],r=s.viewportTransform,n={width:s.width/(i?r[0]:1),height:s.height/(i?r[3]:1)};return e.toSVG(n,{additionalTransform:i?fabric.util.matrixToSVG(r):""})}}).join("")},createSVGFontFacesMarkup:function(){var t,e,i,r,n,s,o,a,c="",h={},l=fabric.fontPaths,u=[];for(this._objects.forEach(function t(e){u.push(e),e._objects&&e._objects.forEach(t)}),o=0,a=u.length;o',"\n",c,"","\n"].join("")),c},_setSVGObjects:function(t,e){var i,r,n,s=this._objects;for(r=0,n=s.length;r
    \n")}else t.push('\n")},sendToBack:function(t){if(!t)return this;var e,i,r,n=this._activeObject;if(t===n&&"activeSelection"===t.type)for(e=(r=n._objects).length;e--;)i=r[e],h(this._objects,i),this._objects.unshift(i);else h(this._objects,t),this._objects.unshift(t);return this.renderOnAddRemove&&this.requestRenderAll(),this},bringToFront:function(t){if(!t)return this;var e,i,r,n=this._activeObject;if(t===n&&"activeSelection"===t.type)for(r=n._objects,e=0;e"}}),n(fabric.StaticCanvas.prototype,fabric.Observable),n(fabric.StaticCanvas.prototype,fabric.Collection),n(fabric.StaticCanvas.prototype,fabric.DataURLExporter),n(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(t){var e=r();if(!e||!e.getContext)return null;var i=e.getContext("2d");if(!i)return null;switch(t){case"setLineDash":return void 0!==i.setLineDash;default:return null}}}),fabric.StaticCanvas.prototype.toJSON=fabric.StaticCanvas.prototype.toObject,fabric.isLikelyNode&&(fabric.StaticCanvas.prototype.createPNGStream=function(){var t=i(this.lowerCanvasEl);return t&&t.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(t){var e=i(this.lowerCanvasEl);return e&&e.createJPEGStream(t)})}}(),fabric.BaseBrush=fabric.util.createClass({color:"rgb(0, 0, 0)",width:1,shadow:null,strokeLineCap:"round",strokeLineJoin:"round",strokeMiterLimit:10,strokeDashArray:null,limitedToCanvasSize:!1,_setBrushStyles:function(t){t.strokeStyle=this.color,t.lineWidth=this.width,t.lineCap=this.strokeLineCap,t.miterLimit=this.strokeMiterLimit,t.lineJoin=this.strokeLineJoin,t.setLineDash(this.strokeDashArray||[])},_saveAndTransform:function(t){var e=this.canvas.viewportTransform;t.save(),t.transform(e[0],e[1],e[2],e[3],e[4],e[5])},_setShadow:function(){if(this.shadow){var t=this.canvas,e=this.shadow,i=t.contextTop,r=t.getZoom();t&&t._isRetinaScaling()&&(r*=fabric.devicePixelRatio),i.shadowColor=e.color,i.shadowBlur=e.blur*r,i.shadowOffsetX=e.offsetX*r,i.shadowOffsetY=e.offsetY*r}},needsFullRender:function(){return new fabric.Color(this.color).getAlpha()<1||!!this.shadow},_resetShadow:function(){var t=this.canvas.contextTop;t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0},_isOutSideCanvas:function(t){return t.x<0||t.x>this.canvas.getWidth()||t.y<0||t.y>this.canvas.getHeight()}}),fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{decimate:.4,drawStraightLine:!1,straightLineKey:"shiftKey",initialize:function(t){this.canvas=t,this._points=[]},needsFullRender:function(){return this.callSuper("needsFullRender")||this._hasStraightLine},_drawSegment:function(t,e,i){var r=e.midPointFrom(i);return t.quadraticCurveTo(e.x,e.y,r.x,r.y),r},onMouseDown:function(t,e){this.canvas._isMainEvent(e.e)&&(this.drawStraightLine=e.e[this.straightLineKey],this._prepareForDrawing(t),this._captureDrawingPath(t),this._render())},onMouseMove:function(t,e){if(this.canvas._isMainEvent(e.e)&&(this.drawStraightLine=e.e[this.straightLineKey],(!0!==this.limitedToCanvasSize||!this._isOutSideCanvas(t))&&this._captureDrawingPath(t)&&1"},getObjectScaling:function(){if(!this.group)return{scaleX:this.scaleX,scaleY:this.scaleY};var t=x.util.qrDecompose(this.calcTransformMatrix());return{scaleX:Math.abs(t.scaleX),scaleY:Math.abs(t.scaleY)}},getTotalObjectScaling:function(){var t=this.getObjectScaling(),e=t.scaleX,i=t.scaleY;if(this.canvas){var r=this.canvas.getZoom(),n=this.canvas.getRetinaScaling();e*=r*n,i*=r*n}return{scaleX:e,scaleY:i}},getObjectOpacity:function(){var t=this.opacity;return this.group&&(t*=this.group.getObjectOpacity()),t},_set:function(t,e){var i="scaleX"===t||"scaleY"===t,r=this[t]!==e,n=!1;return i&&(e=this._constrainScale(e)),"scaleX"===t&&e<0?(this.flipX=!this.flipX,e*=-1):"scaleY"===t&&e<0?(this.flipY=!this.flipY,e*=-1):"shadow"!==t||!e||e instanceof x.Shadow?"dirty"===t&&this.group&&this.group.set("dirty",e):e=new x.Shadow(e),this[t]=e,r&&(n=this.group&&this.group.isOnACache(),-1=t.x&&n.left+n.width<=e.x&&n.top>=t.y&&n.top+n.height<=e.y},containsPoint:function(t,e,i,r){var n=this._getCoords(i,r),s=(e=e||this._getImageLines(n),this._findCrossPoints(t,e));return 0!==s&&s%2==1},isOnScreen:function(t){if(!this.canvas)return!1;var e=this.canvas.vptCoords.tl,i=this.canvas.vptCoords.br;return!!this.getCoords(!0,t).some(function(t){return t.x<=i.x&&t.x>=e.x&&t.y<=i.y&&t.y>=e.y})||(!!this.intersectsWithRect(e,i,!0,t)||this._containsCenterOfCanvas(e,i,t))},_containsCenterOfCanvas:function(t,e,i){var r={x:(t.x+e.x)/2,y:(t.y+e.y)/2};return!!this.containsPoint(r,null,!0,i)},isPartiallyOnScreen:function(t){if(!this.canvas)return!1;var e=this.canvas.vptCoords.tl,i=this.canvas.vptCoords.br;return!!this.intersectsWithRect(e,i,!0,t)||this.getCoords(!0,t).every(function(t){return(t.x>=i.x||t.x<=e.x)&&(t.y>=i.y||t.y<=e.y)})&&this._containsCenterOfCanvas(e,i,t)},_getImageLines:function(t){return{topline:{o:t.tl,d:t.tr},rightline:{o:t.tr,d:t.br},bottomline:{o:t.br,d:t.bl},leftline:{o:t.bl,d:t.tl}}},_findCrossPoints:function(t,e){var i,r,n,s=0;for(var o in e)if(!((n=e[o]).o.y=t.y&&n.d.y>=t.y||(n.o.x===n.d.x&&n.o.x>=t.x?r=n.o.x:(0,i=(n.d.y-n.o.y)/(n.d.x-n.o.x),r=-(t.y-0*t.x-(n.o.y-i*n.o.x))/(0-i)),r>=t.x&&(s+=1),2!==s)))break;return s},getBoundingRect:function(t,e){var i=this.getCoords(t,e);return h.makeBoundingBoxFromPoints(i)},getScaledWidth:function(){return this._getTransformedDimensions().x},getScaledHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(t){return Math.abs(t)
    \n')}},toSVG:function(t){return this._createBaseSVGMarkup(this._toSVG(t),{reviver:t})},toClipPathSVG:function(t){return"\t"+this._createBaseClipPathSVGMarkup(this._toSVG(t),{reviver:t})},_createBaseClipPathSVGMarkup:function(t,e){var i=(e=e||{}).reviver,r=e.additionalTransform||"",n=[this.getSvgTransform(!0,r),this.getSvgCommons()].join(""),s=t.indexOf("COMMON_PARTS");return t[s]=n,i?i(t.join("")):t.join("")},_createBaseSVGMarkup:function(t,e){var i,r,n=(e=e||{}).noStyle,s=e.reviver,o=n?"":'style="'+this.getSvgStyles()+'" ',a=e.withShadow?'style="'+this.getSvgFilter()+'" ':"",c=this.clipPath,h=this.strokeUniform?'vector-effect="non-scaling-stroke" ':"",l=c&&c.absolutePositioned,u=this.stroke,f=this.fill,d=this.shadow,g=[],p=t.indexOf("COMMON_PARTS"),v=e.additionalTransform;return c&&(c.clipPathId="CLIPPATH_"+fabric.Object.__uid++,r='\n'+c.toClipPathSVG(s)+"\n"),l&&g.push("\n"),g.push("\n"),i=[o,h,n?"":this.addPaintOrder()," ",v?'transform="'+v+'" ':""].join(""),t[p]=i,f&&f.toLive&&g.push(f.toSVG(this)),u&&u.toLive&&g.push(u.toSVG(this)),d&&g.push(d.toSVG(this)),c&&g.push(r),g.push(t.join("")),g.push("\n"),l&&g.push("\n"),s?s(g.join("")):g.join("")},addPaintOrder:function(){return"fill"!==this.paintFirst?' paint-order="'+this.paintFirst+'" ':""}})}(),function(){var n=fabric.util.object.extend,r="stateProperties";function s(e,t,i){var r={};i.forEach(function(t){r[t]=e[t]}),n(e[t],r,!0)}fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(t){var e="_"+(t=t||r);return Object.keys(this[e]).length\n']}}),s.Line.ATTRIBUTE_NAMES=s.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),s.Line.fromElement=function(t,e,i){i=i||{};var r=s.parseAttributes(t,s.Line.ATTRIBUTE_NAMES),n=[r.x1||0,r.y1||0,r.x2||0,r.y2||0];e(new s.Line(n,o(r,i)))},s.Line.fromObject=function(t,e){var i=r(t,!0);i.points=[t.x1,t.y1,t.x2,t.y2],s.Object._fromObject("Line",i,function(t){delete t.points,e&&e(t)},"points")})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var s=t.fabric||(t.fabric={}),o=s.util.degreesToRadians;s.Circle?s.warn("fabric.Circle is already defined."):(s.Circle=s.util.createClass(s.Object,{type:"circle",radius:0,startAngle:0,endAngle:360,cacheProperties:s.Object.prototype.cacheProperties.concat("radius","startAngle","endAngle"),_set:function(t,e){return this.callSuper("_set",t,e),"radius"===t&&this.setRadius(e),this},toObject:function(t){return this.callSuper("toObject",["radius","startAngle","endAngle"].concat(t))},_toSVG:function(){var t,e=(this.endAngle-this.startAngle)%360;if(0===e)t=["\n'];else{var i=o(this.startAngle),r=o(this.endAngle),n=this.radius;t=['\n"]}return t},_render:function(t){t.beginPath(),t.arc(0,0,this.radius,o(this.startAngle),o(this.endAngle),!1),this._renderPaintInOrder(t)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(t){return this.radius=t,this.set("width",2*t).set("height",2*t)}}),s.Circle.ATTRIBUTE_NAMES=s.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),s.Circle.fromElement=function(t,e){var i,r=s.parseAttributes(t,s.Circle.ATTRIBUTE_NAMES);if(!("radius"in(i=r)&&0<=i.radius))throw new Error("value of `r` attribute is required and can not be negative");r.left=(r.left||0)-r.radius,r.top=(r.top||0)-r.radius,e(new s.Circle(r))},s.Circle.fromObject=function(t,e){s.Object._fromObject("Circle",t,e)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var i=t.fabric||(t.fabric={});i.Triangle?i.warn("fabric.Triangle is already defined"):(i.Triangle=i.util.createClass(i.Object,{type:"triangle",width:100,height:100,_render:function(t){var e=this.width/2,i=this.height/2;t.beginPath(),t.moveTo(-e,i),t.lineTo(0,-i),t.lineTo(e,i),t.closePath(),this._renderPaintInOrder(t)},_toSVG:function(){var t=this.width/2,e=this.height/2;return["']}}),i.Triangle.fromObject=function(t,e){return i.Object._fromObject("Triangle",t,e)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var r=t.fabric||(t.fabric={}),e=2*Math.PI;r.Ellipse?r.warn("fabric.Ellipse is already defined."):(r.Ellipse=r.util.createClass(r.Object,{type:"ellipse",rx:0,ry:0,cacheProperties:r.Object.prototype.cacheProperties.concat("rx","ry"),initialize:function(t){this.callSuper("initialize",t),this.set("rx",t&&t.rx||0),this.set("ry",t&&t.ry||0)},_set:function(t,e){switch(this.callSuper("_set",t,e),t){case"rx":this.rx=e,this.set("width",2*e);break;case"ry":this.ry=e,this.set("height",2*e)}return this},getRx:function(){return this.get("rx")*this.get("scaleX")},getRy:function(){return this.get("ry")*this.get("scaleY")},toObject:function(t){return this.callSuper("toObject",["rx","ry"].concat(t))},_toSVG:function(){return["\n']},_render:function(t){t.beginPath(),t.save(),t.transform(1,0,0,this.ry/this.rx,0,0),t.arc(0,0,this.rx,0,e,!1),t.restore(),this._renderPaintInOrder(t)}}),r.Ellipse.ATTRIBUTE_NAMES=r.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),r.Ellipse.fromElement=function(t,e){var i=r.parseAttributes(t,r.Ellipse.ATTRIBUTE_NAMES);i.left=(i.left||0)-i.rx,i.top=(i.top||0)-i.ry,e(new r.Ellipse(i))},r.Ellipse.fromObject=function(t,e){r.Object._fromObject("Ellipse",t,e)})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var s=t.fabric||(t.fabric={}),o=s.util.object.extend;s.Rect?s.warn("fabric.Rect is already defined"):(s.Rect=s.util.createClass(s.Object,{stateProperties:s.Object.prototype.stateProperties.concat("rx","ry"),type:"rect",rx:0,ry:0,cacheProperties:s.Object.prototype.cacheProperties.concat("rx","ry"),initialize:function(t){this.callSuper("initialize",t),this._initRxRy()},_initRxRy:function(){this.rx&&!this.ry?this.ry=this.rx:this.ry&&!this.rx&&(this.rx=this.ry)},_render:function(t){var e=this.rx?Math.min(this.rx,this.width/2):0,i=this.ry?Math.min(this.ry,this.height/2):0,r=this.width,n=this.height,s=-this.width/2,o=-this.height/2,a=0!==e||0!==i,c=.4477152502;t.beginPath(),t.moveTo(s+e,o),t.lineTo(s+r-e,o),a&&t.bezierCurveTo(s+r-c*e,o,s+r,o+c*i,s+r,o+i),t.lineTo(s+r,o+n-i),a&&t.bezierCurveTo(s+r,o+n-c*i,s+r-c*e,o+n,s+r-e,o+n),t.lineTo(s+e,o+n),a&&t.bezierCurveTo(s+c*e,o+n,s,o+n-c*i,s,o+n-i),t.lineTo(s,o+i),a&&t.bezierCurveTo(s,o+c*i,s+c*e,o,s+e,o),t.closePath(),this._renderPaintInOrder(t)},toObject:function(t){return this.callSuper("toObject",["rx","ry"].concat(t))},_toSVG:function(){return["\n']}}),s.Rect.ATTRIBUTE_NAMES=s.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")),s.Rect.fromElement=function(t,e,i){if(!t)return e(null);i=i||{};var r=s.parseAttributes(t,s.Rect.ATTRIBUTE_NAMES);r.left=r.left||0,r.top=r.top||0,r.height=r.height||0,r.width=r.width||0;var n=new s.Rect(o(i?s.util.object.clone(i):{},r));n.visible=n.visible&&0\n']},commonRender:function(t){var e,i=this.points.length,r=this.pathOffset.x,n=this.pathOffset.y;if(!i||isNaN(this.points[i-1].y))return!1;t.beginPath(),t.moveTo(this.points[0].x-r,this.points[0].y-n);for(var s=0;s"},toObject:function(t){return n(this.callSuper("toObject",t),{path:this.path.map(function(t){return t.slice()})})},toDatalessObject:function(t){var e=this.toObject(["sourcePath"].concat(t));return e.sourcePath&&delete e.path,e},_toSVG:function(){return["\n"]},_getOffsetTransform:function(){var t=f.Object.NUM_FRACTION_DIGITS;return" translate("+e(-this.pathOffset.x,t)+", "+e(-this.pathOffset.y,t)+")"},toClipPathSVG:function(t){var e=this._getOffsetTransform();return"\t"+this._createBaseClipPathSVGMarkup(this._toSVG(),{reviver:t,additionalTransform:e})},toSVG:function(t){var e=this._getOffsetTransform();return this._createBaseSVGMarkup(this._toSVG(),{reviver:t,additionalTransform:e})},complexity:function(){return this.path.length},_calcDimensions:function(){for(var t,e,i=[],r=[],n=0,s=0,o=0,a=0,c=0,h=this.path.length;c"},addWithUpdate:function(t){var e=!!this.group;return this._restoreObjectsState(),h.util.resetObjectTransform(this),t&&(e&&h.util.removeTransformFromObject(t,this.group.calcTransformMatrix()),this._objects.push(t),t.group=this,t._set("canvas",this.canvas)),this._calcBounds(),this._updateObjectsCoords(),this.dirty=!0,e?this.group.addWithUpdate():this.setCoords(),this},removeWithUpdate:function(t){return this._restoreObjectsState(),h.util.resetObjectTransform(this),this.remove(t),this._calcBounds(),this._updateObjectsCoords(),this.setCoords(),this.dirty=!0,this},_onObjectAdded:function(t){this.dirty=!0,t.group=this,t._set("canvas",this.canvas)},_onObjectRemoved:function(t){this.dirty=!0,delete t.group},_set:function(t,e){var i=this._objects.length;if(this.useSetOnGroup)for(;i--;)this._objects[i].setOnGroup(t,e);if("canvas"===t)for(;i--;)this._objects[i]._set(t,e);h.Object.prototype._set.call(this,t,e)},toObject:function(r){var n=this.includeDefaultValues,t=this._objects.filter(function(t){return!t.excludeFromExport}).map(function(t){var e=t.includeDefaultValues;t.includeDefaultValues=n;var i=t.toObject(r);return t.includeDefaultValues=e,i}),e=h.Object.prototype.toObject.call(this,r);return e.objects=t,e},toDatalessObject:function(r){var t,e=this.sourcePath;if(e)t=e;else{var n=this.includeDefaultValues;t=this._objects.map(function(t){var e=t.includeDefaultValues;t.includeDefaultValues=n;var i=t.toDatalessObject(r);return t.includeDefaultValues=e,i})}var i=h.Object.prototype.toDatalessObject.call(this,r);return i.objects=t,i},render:function(t){this._transformDone=!0,this.callSuper("render",t),this._transformDone=!1},shouldCache:function(){var t=h.Object.prototype.shouldCache.call(this);if(t)for(var e=0,i=this._objects.length;e\n"],i=0,r=this._objects.length;i\n"),e},getSvgStyles:function(){var t=void 0!==this.opacity&&1!==this.opacity?"opacity: "+this.opacity+";":"",e=this.visible?"":" visibility: hidden;";return[t,this.getSvgFilter(),e].join("")},toClipPathSVG:function(t){for(var e=[],i=0,r=this._objects.length;i"},shouldCache:function(){return!1},isOnACache:function(){return!1},_renderControls:function(t,e,i){t.save(),t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,this.callSuper("_renderControls",t,e),void 0===(i=i||{}).hasControls&&(i.hasControls=!1),i.forActiveSelection=!0;for(var r=0,n=this._objects.length;r\n','\t\n',"\n"),o=' clip-path="url(#imageCrop_'+c+')" '}if(this.imageSmoothing||(a='" image-rendering="optimizeSpeed'),i.push("\t\n"),this.stroke||this.strokeDashArray){var h=this.fill;this.fill=null,t=["\t\n'],this.fill=h}return e="fill"!==this.paintFirst?e.concat(t,i):e.concat(i,t)},getSrc:function(t){var e=t?this._element:this._originalElement;return e?e.toDataURL?e.toDataURL():this.srcFromAttribute?e.getAttribute("src"):e.src:this.src||""},setSrc:function(t,i,r){return fabric.util.loadImage(t,function(t,e){this.setElement(t,r),this._setWidthHeight(),i&&i(this,e)},this,r&&r.crossOrigin),this},toString:function(){return'#'},applyResizeFilters:function(){var t=this.resizeFilter,e=this.minimumScaleTrigger,i=this.getTotalObjectScaling(),r=i.scaleX,n=i.scaleY,s=this._filteredEl||this._originalElement;if(this.group&&this.set("dirty",!0),!t||e=t;for(var a=["highp","mediump","lowp"],c=0;c<3;c++)if(void 0,i="precision "+a[c]+" float;\nvoid main(){}",r=(e=s).createShader(e.FRAGMENT_SHADER),e.shaderSource(r,i),e.compileShader(r),e.getShaderParameter(r,e.COMPILE_STATUS)){fabric.webGlPrecision=a[c];break}}return this.isSupported=o},(fabric.WebglFilterBackend=t).prototype={tileSize:2048,resources:{},setupGLContext:function(t,e){this.dispose(),this.createWebGLCanvas(t,e),this.aPosition=new Float32Array([0,0,0,1,1,0,1,1]),this.chooseFastestCopyGLTo2DMethod(t,e)},chooseFastestCopyGLTo2DMethod:function(t,e){var i,r=void 0!==window.performance;try{new ImageData(1,1),i=!0}catch(t){i=!1}var n="undefined"!=typeof ArrayBuffer,s="undefined"!=typeof Uint8ClampedArray;if(r&&i&&n&&s){var o=fabric.util.createCanvasElement(),a=new ArrayBuffer(t*e*4);if(fabric.forceGLPutImageData)return this.imageBuffer=a,void(this.copyGLTo2D=copyGLTo2DPutImageData);var c,h,l={imageBuffer:a,destinationWidth:t,destinationHeight:e,targetCanvas:o};o.width=t,o.height=e,c=window.performance.now(),copyGLTo2DDrawImage.call(l,this.gl,l),h=window.performance.now()-c,c=window.performance.now(),copyGLTo2DPutImageData.call(l,this.gl,l),window.performance.now()-c 0.0) {\n"+this.fragmentSource[t]+"}\n}"},retrieveShader:function(t){var e,i=this.type+"_"+this.mode;return t.programCache.hasOwnProperty(i)||(e=this.buildSource(this.mode),t.programCache[i]=this.createProgram(t.context,e)),t.programCache[i]},applyTo2d:function(t){var e,i,r,n,s,o,a,c=t.imageData.data,h=c.length,l=1-this.alpha;e=(a=new f.Color(this.color).getSource())[0]*this.alpha,i=a[1]*this.alpha,r=a[2]*this.alpha;for(var u=0;u'},_getCacheCanvasDimensions:function(){var t=this.callSuper("_getCacheCanvasDimensions"),e=this.fontSize;return t.width+=e*t.zoomX,t.height+=e*t.zoomY,t},_render:function(t){var e=this.path;e&&!e.isNotVisible()&&e._render(t),this._setTextStyles(t),this._renderTextLinesBackground(t),this._renderTextDecoration(t,"underline"),this._renderText(t),this._renderTextDecoration(t,"overline"),this._renderTextDecoration(t,"linethrough")},_renderText:function(t){"stroke"===this.paintFirst?(this._renderTextStroke(t),this._renderTextFill(t)):(this._renderTextFill(t),this._renderTextStroke(t))},_setTextStyles:function(t,e,i){if(t.textBaseline="alphabetical",this.path)switch(this.pathAlign){case"center":t.textBaseline="middle";break;case"ascender":t.textBaseline="top";break;case"descender":t.textBaseline="bottom"}t.font=this._getFontDeclaration(e,i)},calcTextWidth:function(){for(var t=this.getLineWidth(0),e=1,i=this._textLines.length;ethis.__selectionStartOnMouseDown?(this.selectionStart=this.__selectionStartOnMouseDown,this.selectionEnd=e):(this.selectionStart=e,this.selectionEnd=this.__selectionStartOnMouseDown),this.selectionStart===i&&this.selectionEnd===r||(this.restartCursorIfNeeded(),this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection()))}},_setEditingProps:function(){this.hoverCursor="text",this.canvas&&(this.canvas.defaultCursor=this.canvas.moveCursor="text"),this.borderColor=this.editingBorderColor,this.hasControls=this.selectable=!1,this.lockMovementX=this.lockMovementY=!0},fromStringToGraphemeSelection:function(t,e,i){var r=i.slice(0,t),n=fabric.util.string.graphemeSplit(r).length;if(t===e)return{selectionStart:n,selectionEnd:n};var s=i.slice(t,e);return{selectionStart:n,selectionEnd:n+fabric.util.string.graphemeSplit(s).length}},fromGraphemeToStringSelection:function(t,e,i){var r=i.slice(0,t).join("").length;return t===e?{selectionStart:r,selectionEnd:r}:{selectionStart:r,selectionEnd:r+i.slice(t,e).join("").length}},_updateTextarea:function(){if(this.cursorOffsetCache={},this.hiddenTextarea){if(!this.inCompositionMode){var t=this.fromGraphemeToStringSelection(this.selectionStart,this.selectionEnd,this._text);this.hiddenTextarea.selectionStart=t.selectionStart,this.hiddenTextarea.selectionEnd=t.selectionEnd}this.updateTextareaPosition()}},updateFromTextArea:function(){if(this.hiddenTextarea){this.cursorOffsetCache={},this.text=this.hiddenTextarea.value,this._shouldClearDimensionCache()&&(this.initDimensions(),this.setCoords());var t=this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart,this.hiddenTextarea.selectionEnd,this.hiddenTextarea.value);this.selectionEnd=this.selectionStart=t.selectionEnd,this.inCompositionMode||(this.selectionStart=t.selectionStart),this.updateTextareaPosition()}},updateTextareaPosition:function(){if(this.selectionStart===this.selectionEnd){var t=this._calcTextareaPosition();this.hiddenTextarea.style.left=t.left,this.hiddenTextarea.style.top=t.top}},_calcTextareaPosition:function(){if(!this.canvas)return{x:1,y:1};var t=this.inCompositionMode?this.compositionStart:this.selectionStart,e=this._getCursorBoundaries(t),i=this.get2DCursorLocation(t),r=i.lineIndex,n=i.charIndex,s=this.getValueOfPropertyAt(r,n,"fontSize")*this.lineHeight,o=e.leftOffset,a=this.calcTransformMatrix(),c={x:e.left+o,y:e.top+e.topOffset+s},h=this.canvas.getRetinaScaling(),l=this.canvas.upperCanvasEl,u=l.width/h,f=l.height/h,d=u-s,g=f-s,p=l.clientWidth/u,v=l.clientHeight/f;return c=fabric.util.transformPoint(c,a),(c=fabric.util.transformPoint(c,this.canvas.viewportTransform)).x*=p,c.y*=v,c.x<0&&(c.x=0),c.x>d&&(c.x=d),c.y<0&&(c.y=0),c.y>g&&(c.y=g),c.x+=this.canvas._offset.left,c.y+=this.canvas._offset.top,{left:c.x+"px",top:c.y+"px",fontSize:s+"px",charHeight:s}},_saveEditingProps:function(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,selectable:this.selectable,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}},_restoreEditingProps:function(){this._savedProps&&(this.hoverCursor=this._savedProps.hoverCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,this.selectable=this._savedProps.selectable,this.lockMovementX=this._savedProps.lockMovementX,this.lockMovementY=this._savedProps.lockMovementY,this.canvas&&(this.canvas.defaultCursor=this._savedProps.defaultCursor,this.canvas.moveCursor=this._savedProps.moveCursor))},exitEditing:function(){var t=this._textBeforeEdit!==this.text,e=this.hiddenTextarea;return this.selected=!1,this.isEditing=!1,this.selectionEnd=this.selectionStart,e&&(e.blur&&e.blur(),e.parentNode&&e.parentNode.removeChild(e)),this.hiddenTextarea=null,this.abortCursorAnimation(),this._restoreEditingProps(),this._currentCursorOpacity=0,this._shouldClearDimensionCache()&&(this.initDimensions(),this.setCoords()),this.fire("editing:exited"),t&&this.fire("modified"),this.canvas&&(this.canvas.off("mouse:move",this.mouseMoveHandler),this.canvas.fire("text:editing:exited",{target:this}),t&&this.canvas.fire("object:modified",{target:this})),this},_removeExtraneousStyles:function(){for(var t in this.styles)this._textLines[t]||delete this.styles[t]},removeStyleFromTo:function(t,e){var i,r,n=this.get2DCursorLocation(t,!0),s=this.get2DCursorLocation(e,!0),o=n.lineIndex,a=n.charIndex,c=s.lineIndex,h=s.charIndex;if(o!==c){if(this.styles[o])for(i=a;it?this.selectionStart=t:this.selectionStart<0&&(this.selectionStart=0),this.selectionEnd>t?this.selectionEnd=t:this.selectionEnd<0&&(this.selectionEnd=0)}})}(),fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+new Date,this.__lastLastClickTime=+new Date,this.__lastPointer={},this.on("mousedown",this.onMouseDown)},onMouseDown:function(t){if(this.canvas){this.__newClickTime=+new Date;var e=t.pointer;this.isTripleClick(e)&&(this.fire("tripleclick",t),this._stopEvent(t.e)),this.__lastLastClickTime=this.__lastClickTime,this.__lastClickTime=this.__newClickTime,this.__lastPointer=e,this.__lastIsEditing=this.isEditing,this.__lastSelected=this.selected}},isTripleClick:function(t){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===t.x&&this.__lastPointer.y===t.y},_stopEvent:function(t){t.preventDefault&&t.preventDefault(),t.stopPropagation&&t.stopPropagation()},initCursorSelectionHandlers:function(){this.initMousedownHandler(),this.initMouseupHandler(),this.initClicks()},doubleClickHandler:function(t){this.isEditing&&this.selectWord(this.getSelectionStartFromPointer(t.e))},tripleClickHandler:function(t){this.isEditing&&this.selectLine(this.getSelectionStartFromPointer(t.e))},initClicks:function(){this.on("mousedblclick",this.doubleClickHandler),this.on("tripleclick",this.tripleClickHandler)},_mouseDownHandler:function(t){!this.canvas||!this.editable||t.e.button&&1!==t.e.button||(this.__isMousedown=!0,this.selected&&(this.inCompositionMode=!1,this.setCursorByClick(t.e)),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.selectionStart===this.selectionEnd&&this.abortCursorAnimation(),this.renderCursorOrSelection()))},_mouseDownHandlerBefore:function(t){!this.canvas||!this.editable||t.e.button&&1!==t.e.button||(this.selected=this===this.canvas._activeObject)},initMousedownHandler:function(){this.on("mousedown",this._mouseDownHandler),this.on("mousedown:before",this._mouseDownHandlerBefore)},initMouseupHandler:function(){this.on("mouseup",this.mouseUpHandler)},mouseUpHandler:function(t){if(this.__isMousedown=!1,!(!this.editable||this.group||t.transform&&t.transform.actionPerformed||t.e.button&&1!==t.e.button)){if(this.canvas){var e=this.canvas._activeObject;if(e&&e!==this)return}this.__lastSelected&&!this.__corner?(this.selected=!1,this.__lastSelected=!1,this.enterEditing(t.e),this.selectionStart===this.selectionEnd?this.initDelayedCursor(!0):this.renderCursorOrSelection()):this.selected=!0}},setCursorByClick:function(t){var e=this.getSelectionStartFromPointer(t),i=this.selectionStart,r=this.selectionEnd;t.shiftKey?this.setSelectionStartEndWithShift(i,r,e):(this.selectionStart=e,this.selectionEnd=e),this.isEditing&&(this._fireSelectionChanged(),this._updateTextarea())},getSelectionStartFromPointer:function(t){for(var e,i=this.getLocalPointer(t),r=0,n=0,s=0,o=0,a=0,c=0,h=this._textLines.length;cthis._text.length&&(a=this._text.length),a}}),fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(){this.hiddenTextarea=fabric.document.createElement("textarea"),this.hiddenTextarea.setAttribute("autocapitalize","off"),this.hiddenTextarea.setAttribute("autocorrect","off"),this.hiddenTextarea.setAttribute("autocomplete","off"),this.hiddenTextarea.setAttribute("spellcheck","false"),this.hiddenTextarea.setAttribute("data-fabric-hiddentextarea",""),this.hiddenTextarea.setAttribute("wrap","off");var t=this._calcTextareaPosition();this.hiddenTextarea.style.cssText="position: absolute; top: "+t.top+"; left: "+t.left+"; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; paddingーtop: "+t.fontSize+";",this.hiddenTextareaContainer?this.hiddenTextareaContainer.appendChild(this.hiddenTextarea):fabric.document.body.appendChild(this.hiddenTextarea),fabric.util.addListener(this.hiddenTextarea,"keydown",this.onKeyDown.bind(this)),fabric.util.addListener(this.hiddenTextarea,"keyup",this.onKeyUp.bind(this)),fabric.util.addListener(this.hiddenTextarea,"input",this.onInput.bind(this)),fabric.util.addListener(this.hiddenTextarea,"copy",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"cut",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"paste",this.paste.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionstart",this.onCompositionStart.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionupdate",this.onCompositionUpdate.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionend",this.onCompositionEnd.bind(this)),!this._clickHandlerInitialized&&this.canvas&&(fabric.util.addListener(this.canvas.upperCanvasEl,"click",this.onClick.bind(this)),this._clickHandlerInitialized=!0)},keysMap:{9:"exitEditing",27:"exitEditing",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorRight",36:"moveCursorLeft",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown"},keysMapRtl:{9:"exitEditing",27:"exitEditing",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorLeft",36:"moveCursorRight",37:"moveCursorRight",38:"moveCursorUp",39:"moveCursorLeft",40:"moveCursorDown"},ctrlKeysMapUp:{67:"copy",88:"cut"},ctrlKeysMapDown:{65:"selectAll"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(t){if(this.isEditing){var e="rtl"===this.direction?this.keysMapRtl:this.keysMap;if(t.keyCode in e)this[e[t.keyCode]](t);else{if(!(t.keyCode in this.ctrlKeysMapDown&&(t.ctrlKey||t.metaKey)))return;this[this.ctrlKeysMapDown[t.keyCode]](t)}t.stopImmediatePropagation(),t.preventDefault(),33<=t.keyCode&&t.keyCode<=40?(this.inCompositionMode=!1,this.clearContextTop(),this.renderCursorOrSelection()):this.canvas&&this.canvas.requestRenderAll()}},onKeyUp:function(t){!this.isEditing||this._copyDone||this.inCompositionMode?this._copyDone=!1:t.keyCode in this.ctrlKeysMapUp&&(t.ctrlKey||t.metaKey)&&(this[this.ctrlKeysMapUp[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.requestRenderAll())},onInput:function(t){var e=this.fromPaste;if(this.fromPaste=!1,t&&t.stopPropagation(),this.isEditing){var i,r,n,s,o,a=this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,c=this._text.length,h=a.length,l=h-c,u=this.selectionStart,f=this.selectionEnd,d=u!==f;if(""===this.hiddenTextarea.value)return this.styles={},this.updateFromTextArea(),this.fire("changed"),void(this.canvas&&(this.canvas.fire("text:changed",{target:this}),this.canvas.requestRenderAll()));var g=this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart,this.hiddenTextarea.selectionEnd,this.hiddenTextarea.value),p=u>g.selectionStart;d?(i=this._text.slice(u,f),l+=f-u):h=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorUpOrDown("Down",t)},moveCursorUp:function(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorUpOrDown("Up",t)},_moveCursorUpOrDown:function(t,e){var i=this["get"+t+"CursorOffset"](e,"right"===this._selectionDirection);e.shiftKey?this.moveCursorWithShift(i):this.moveCursorWithoutShift(i),0!==i&&(this.setSelectionInBoundaries(),this.abortCursorAnimation(),this._currentCursorOpacity=1,this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorWithShift:function(t){var e="left"===this._selectionDirection?this.selectionStart+t:this.selectionEnd+t;return this.setSelectionStartEndWithShift(this.selectionStart,this.selectionEnd,e),0!==t},moveCursorWithoutShift:function(t){return t<0?(this.selectionStart+=t,this.selectionEnd=this.selectionStart):(this.selectionEnd+=t,this.selectionStart=this.selectionEnd),0!==t},moveCursorLeft:function(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorLeftOrRight("Left",t)},_move:function(t,e,i){var r;if(t.altKey)r=this["findWordBoundary"+i](this[e]);else{if(!t.metaKey&&35!==t.keyCode&&36!==t.keyCode)return this[e]+="Left"===i?-1:1,!0;r=this["findLineBoundary"+i](this[e])}if(void 0!==typeof r&&this[e]!==r)return this[e]=r,!0},_moveLeft:function(t,e){return this._move(t,e,"Left")},_moveRight:function(t,e){return this._move(t,e,"Right")},moveCursorLeftWithoutShift:function(t){var e=!0;return this._selectionDirection="left",this.selectionEnd===this.selectionStart&&0!==this.selectionStart&&(e=this._moveLeft(t,"selectionStart")),this.selectionEnd=this.selectionStart,e},moveCursorLeftWithShift:function(t){return"right"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveLeft(t,"selectionEnd"):0!==this.selectionStart?(this._selectionDirection="left",this._moveLeft(t,"selectionStart")):void 0},moveCursorRight:function(t){this.selectionStart>=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorLeftOrRight("Right",t)},_moveCursorLeftOrRight:function(t,e){var i="moveCursor"+t+"With";this._currentCursorOpacity=1,e.shiftKey?i+="Shift":i+="outShift",this[i](e)&&(this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())},moveCursorRightWithShift:function(t){return"left"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveRight(t,"selectionStart"):this.selectionEnd!==this._text.length?(this._selectionDirection="right",this._moveRight(t,"selectionEnd")):void 0},moveCursorRightWithoutShift:function(t){var e=!0;return this._selectionDirection="right",this.selectionStart===this.selectionEnd?(e=this._moveRight(t,"selectionStart"),this.selectionEnd=this.selectionStart):this.selectionStart=this.selectionEnd,e},removeChars:function(t,e){void 0===e&&(e=t+1),this.removeStyleFromTo(t,e),this._text.splice(t,e-t),this.text=this._text.join(""),this.set("dirty",!0),this._shouldClearDimensionCache()&&(this.initDimensions(),this.setCoords()),this._removeExtraneousStyles()},insertChars:function(t,e,i,r){void 0===r&&(r=i),i",t.textSpans.join(""),"\n"]},_getSVGTextAndBg:function(t,e){var i,r=[],n=[],s=t;this._setSVGBg(n);for(var o=0,a=this._textLines.length;o",fabric.util.string.escapeXml(t),""].join("")},_setSVGTextLineText:function(t,e,i,r){var n,s,o,a,c,h=this.getHeightOfLine(e),l=-1!==this.textAlign.indexOf("justify"),u="",f=0,d=this._textLines[e];r+=h*(1-this._fontSizeFraction)/this.lineHeight;for(var g=0,p=d.length-1;g<=p;g++)c=g===p||this.charSpacing,u+=d[g],o=this.__charBounds[e][g],0===f?(i+=o.kernedWidth-o.width,f+=o.width):f+=o.kernedWidth,l&&!c&&this._reSpaceAndTab.test(d[g])&&(c=!0),c||(n=n||this.getCompleteStyleDeclaration(e,g),s=this.getCompleteStyleDeclaration(e,g+1),c=this._hasStyleChangedForSvg(n,s)),c&&(a=this._getStyleDeclaration(e,g)||{},t.push(this._createTextCharSpan(u,a,i,r)),u="",n=s,i+=f,f=0)},_pushTextBgRect:function(t,e,i,r,n,s){var o=fabric.Object.NUM_FRACTION_DIGITS;t.push("\t\t\n')},_setSVGTextLineBg:function(t,e,i,r){for(var n,s,o=this._textLines[e],a=this.getHeightOfLine(e)/this.lineHeight,c=0,h=0,l=this.getValueOfPropertyAt(e,0,"textBackgroundColor"),u=0,f=o.length;uthis.width&&this._set("width",this.dynamicMinWidth),-1!==this.textAlign.indexOf("justify")&&this.enlargeSpaces(),this.height=this.calcTextHeight(),this.saveState({propertySet:"_dimensionAffectingProps"}))},_generateStyleMap:function(t){for(var e=0,i=0,r=0,n={},s=0;sthis.dynamicMinWidth&&(this.dynamicMinWidth=g-v+r),o},isEndOfWrapping:function(t){return!this._styleMap[t+1]||this._styleMap[t+1].line!==this._styleMap[t].line},missingNewlineOffset:function(t){return this.splitByGrapheme?this.isEndOfWrapping(t)?1:0:1},_splitTextIntoLines:function(t){for(var e=b.Text.prototype._splitTextIntoLines.call(this,t),i=this._wrapText(e.lines,this.width),r=new Array(i.length),n=0;n
    \ -
    "); - - $(div).bind("plotselected", function (event, ranges) { zoomStackIn (plot, event, ranges, options.zoomFunc); }); - $(div).find(".zoomout").click(function () { zoomStackOut(plot, options.zoomFunc); }); - - $(div).find(".zoomout").css("visibility", "hidden"); - - enabled = 0; - } - } - - function zoomOptions(plot, opts) { - // zoomStack can be true or it can be an object containing options - if ( opts && opts.zoomStack ) { - if( typeof opts.zoomStack === "object" ){ - options.zoomStack = opts.zoomStack.enabled; - options.zoomFunc = opts.zoomStack.func; - } else { - options.zoomStack = opts.zoomStack; - } - } - if( options.zoomStack ){ - enabled = 1; - plot.hooks.drawOverlay.push(zoomStack); - } - } - - function init(plot) { - plot.hooks.processOptions.push(zoomOptions); - } - - $.plot.plugins.push({ init: init, options: options, name: "zoomStack", version: 0.1 }); -}($)); - diff --git a/web/static/js9_old/js/flot-zoom.min.js b/web/static/js9_old/js/flot-zoom.min.js deleted file mode 100644 index 922995c17ead130494bcb55c7872a022de3859f0..0000000000000000000000000000000000000000 --- a/web/static/js9_old/js/flot-zoom.min.js +++ /dev/null @@ -1,7 +0,0 @@ -var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(a,c,b){a instanceof String&&(a=String(a));for(var e=a.length,f=0;f
    \t\t
    "),a(b).bind("plotselected", -function(b,e){b=f.zoomFunc;var c=d.getAxes(),h=d.getPlaceholder(),g={};g.xmin=c.xaxis.min;g.xmax=c.xaxis.max;g.ymin=c.yaxis.min;g.ymax=c.yaxis.max;d.stack.push(g);c.xaxis.options.min=e.xaxis.from;c.xaxis.options.max=e.xaxis.to;c.yaxis.options.min=e.yaxis.from;c.yaxis.options.max=e.yaxis.to;d.clearSelection(!0);d.setupGrid();d.draw();a(h).find(".zoomout").css("visibility","visible");void 0!==b&&b(d,g)}),a(b).find(".zoomout").click(function(){var b=f.zoomFunc,c=d.stack.pop(),e=d.getPlaceholder();0=== -d.stack.length&&a(e).find(".zoomout").css("visibility","hidden");d.getAxes().xaxis.options.min=c.xmin;d.getAxes().xaxis.options.max=c.xmax;d.getAxes().yaxis.options.min=c.ymin;d.getAxes().yaxis.options.max=c.ymax;d.clearSelection(!0);d.setupGrid();d.draw();void 0!==b&&b(d,c)}),a(b).find(".zoomout").css("visibility","hidden"),e=0)}function b(a,b){b&&b.zoomStack&&("object"===typeof b.zoomStack?(f.zoomStack=b.zoomStack.enabled,f.zoomFunc=b.zoomStack.func):f.zoomStack=b.zoomStack);f.zoomStack&&(e=1,a.hooks.drawOverlay.push(c))} -var e=0,f={zoomStack:0,zoomFunc:void 0};a.plot.plugins.push({init:function(a){a.hooks.processOptions.push(b)},options:f,name:"zoomStack",version:.1})})($); diff --git a/web/static/js9_old/js/gaussblur-orig.js b/web/static/js9_old/js/gaussblur-orig.js deleted file mode 100644 index d5c0606ef88af5a7ebb8ee125c293896cdc1b658..0000000000000000000000000000000000000000 --- a/web/static/js9_old/js/gaussblur-orig.js +++ /dev/null @@ -1,60 +0,0 @@ -// blog.ivank.net/fastest-gaussian-blur.html -// and http://elynxsdk.free.fr/ext-docs/Blur/Fast_box_blur.pdf -var gaussBlur = (function(){ - -function gaussBlur (scl, tcl, w, h, r) { - var bxs = boxesForGauss(r, 3); - boxBlur (scl, tcl, w, h, (bxs[0]-1)/2); - boxBlur (tcl, scl, w, h, (bxs[1]-1)/2); - boxBlur (scl, tcl, w, h, (bxs[2]-1)/2); -} - -function boxesForGauss(sigma, n) // standard deviation, number of boxes -{ - var wIdeal = Math.sqrt((12*sigma*sigma/n)+1); // Ideal averaging filter width - var wl = Math.floor(wIdeal); if(wl%2==0) wl--; - var wu = wl+2; - - var mIdeal = (12*sigma*sigma - n*wl*wl - 4*n*wl - 3*n)/(-4*wl - 4); - var m = Math.round(mIdeal); - // var sigmaActual = Math.sqrt( (m*wl*wl + (n-m)*wu*wu - n)/12 ); - - var sizes = []; for(var i=0; ik;k++)c.push(k= 0 && scy < sh && scx >= 0 && scx < sw){ - scy = Math.min(sh-1, Math.max(0, sy + cy - halfSide)); - scx = Math.min(sw-1, Math.max(0, sx + cx - halfSide)); - srcOff = (scy * sw + scx)*4; - wt = weights[cy * side + cx]; - r += src[srcOff] * wt; - g += src[srcOff+1] * wt; - b += src[srcOff+2] * wt; - a += src[srcOff+3] * wt; - // } - } - } - dst[dstOff] = r; - dst[dstOff+1] = g; - dst[dstOff+2] = b; - dst[dstOff+3] = a + alphaFac*(255-a); - } - } - return pixels; - } - - function convolveFloat32(ctx, pixels, weights, opaque){ - var x, y, sx, sy, scx, scy, dstOff, cx, cy, srcOff, wt, r, g, b, a; - var side = Math.round(Math.sqrt(weights.length)); - var halfSide = Math.floor(side/2); - - var src = pixels.data; - var sw = pixels.width; - var sh = pixels.height; - - var w = sw; - var h = sh; - var output = { - width: w, height: h, data: new Float32Array(w*h*4) - }; - var dst = output.data; - var alphaFac = opaque ? 1 : 0; - for (y = 0; y < h; y++){ - for (x = 0; x < w; x++){ - sy = y; - sx = x; - dstOff = (y * w + x) * 4; - r = 0; g = 0; b = 0; a = 0; - for (cy = 0; cy < side; cy++){ - for (cx = 0; cx < side; cx++){ - scy = Math.min(sh-1, Math.max(0, sy + cy - halfSide)); - scx = Math.min(sw-1, Math.max(0, sx + cx - halfSide)); - srcOff = (scy*sw + scx)*4; - wt = weights[cy*side + cx]; - r += src[srcOff] * wt; - g += src[srcOff+1] * wt; - b += src[srcOff+2] * wt; - a += src[srcOff+3] * wt; - } - } - dst[dstOff] = r; - dst[dstOff+1] = g; - dst[dstOff+2] = b; - dst[dstOff+3] = a + alphaFac*(255-a); - } - } - return output.data; - } - - function luminance(ctx, imageData){ - var i, v; - var data = imageData.data; - for(i = 0; i < data.length; i += 4){ - // CIE luminance for the RGB - // Human eye is bad at seeing red and blue, so de-emphasize them. - v = 0.2126*data[i] + 0.7152*data[i+1] + 0.0722*data[i+2]; - data[i] = data[i+1] = data[i+2] = v; - } - return imageData; - } - - function greyscale(ctx, imageData){ - var i, v; - var data = imageData.data; - for(i = 0; i < data.length; i += 4){ - v = 0.299*data[i] + 0.587*data[i+1] + 0.114*data[i+2]; - data[i] = data[i+1] = data[i+2] = v; - } - return imageData; - } - - function greyscaleAvg(ctx, imageData){ - var i, v; - var data = imageData.data; - for(i = 0; i < data.length; i += 4){ - v = (data[i] + data[i+1] + data[i+2])/3; - data[i] = data[i+1] = data[i+2] = v; - } - return imageData; - } - - function duotone(ctx, imageData, which) { - var i, r; - var data = imageData.data; - switch(which){ - case "r": - which = 0; - break; - case "g": - which = 1; - break; - case "b": - which = 2; - break; - default: - which = 0; - break; - } - for(i = 0; i < data.length; i += 4) { - // average the other two colors for this pixel - r = (data[i] + data[i+1] + data[i+2] - data[i+which])/2; - data[i+which] = r; - } - return imageData; - } - - function noise(ctx, imageData, lower, upper){ - var i, radius, mod; - var data = imageData.data; - if(arguments.length < 3){ - lower = -30; - upper = 30; - } else if( arguments.length === 3 ){ - upper = lower; - lower = -lower; - } - radius = upper - lower; - for(i = 0; i < data.length; i += 4){ - mod = Math.floor((Math.random() * radius) - upper); - data[i] += mod; - data[i+1] += mod; - data[i+2] += mod; - } - return imageData; - } - - function invert(ctx, imageData){ - var i; - var data = imageData.data; - for(i = 0; i < data.length; i += 4){ - data[i] = 255 - data[i]; - data[i+1] = 255 - data[i+1]; - data[i+2] = 255 - data[i+2]; - } - return imageData; - } - - function pixelate(ctx, imageData, radius){ - var r, g, b, idx, odx, ody; - var x, y, nx, ny, delta, ioff; - var width = imageData.width; - var height = imageData.height; - var data = imageData.data; - if(arguments.length < 3){ - radius = 2; - } - if( radius <= 0 ){ - return imageData; - } - delta = (2 * radius); - for(y = radius; y < height - radius; y += delta){ - for(x = radius; x < width - radius; x += delta){ - idx = ((width * y) + x) * 4; - r = data[idx]; - g = data[idx + 1]; - b = data[idx + 2]; - for(ny = -radius; ny < radius; ++ny){ - ody = (width*(y + ny)); - for(nx = -radius; nx < radius; ++nx){ - odx = (ody + (x + nx)) * 4; - data[odx] = r; - data[odx+1] = g; - data[odx+2] = b; - } - } - } - } - ioff = height % delta ? height % delta : delta; - for(y = height - ioff; y < height; y++){ - ody = width * y; - for(x = 0; x < width; x++){ - odx = (x + ody) * 4; - data[odx] = 0; - data[odx+1] = 0; - data[odx+2] = 0; - } - } - ioff = width % delta ? width % delta : delta; - for(y = 0; y < height; y++){ - ody = width * y; - for(x = width - ioff; x < width; x++){ - odx = (x + ody) * 4; - data[odx] = 0; - data[odx+1] = 0; - data[odx+2] = 0; - } - } - return imageData; - } - - function gamma(ctx, imageData, amount){ - var i; - var data = imageData.data; - if(arguments.length < 3){ - amount = 0.2; - } - for(i = 0; i < data.length; i += 4){ - data[i] = 255 * Math.pow(data[i] / 255, amount); - data[i+1] = 255 * Math.pow(data[i+1] / 255, amount); - data[i+2] = 255 * Math.pow(data[i+2] / 255, amount); - } - return imageData; - } - - function brighten(ctx, imageData, a){ - var i; - var data = imageData.data; - if(arguments.length < 3){ - a = 10; - } - for(i = 0; i < data.length; i += 4){ - data[i] += a; - data[i+1] += a; - data[i+2] += a; - } - return imageData; - } - - function sepia(ctx, imageData, adjust){ - var i, r, g, b; - var data = imageData.data; - if( adjust === undefined ){ - adjust = 100; - } - adjust /= 100; - for(i = 0; i < data.length; i += 4){ - r = data[i]; - g = data[i+1]; - b = data[i+2]; -// data[i] = (r * 0.393) + (g * 0.769) + (b * 0.189); -// data[i+1] = (r * 0.349) + (g * 0.686) + (b * 0.168); -// data[i+2] = (r * 0.272) + (g * 0.534) + (b * 0.131); - // Caman.js - // All three color channels have special conversion factors that - // define what sepia is. Here we adjust each channel individually, - // with the twist that you can partially apply the sepia filter. - data[i] = Math.min(255, (r * (1 - (0.607 * adjust))) + (g * (0.769 * adjust)) + (b * (0.189 * adjust))); - data[i+1] = Math.min(255, (r * (0.349 * adjust)) + (g * (1 - (0.314 * adjust))) + (b * (0.168 * adjust))); - data[i+2] = Math.min(255, (r * (0.272 * adjust)) + (g * (0.534 * adjust)) + (b * (1- (0.869 * adjust)))); - } - return imageData; - } - - function contrast(ctx, imageData, amount){ - var i; - var data = imageData.data; - if(arguments.length < 3){ - amount = 2; - } - if(amount < -100){ - amount = -100; - } else if(amount > 100){ - amount = 100; - } - for(i = 0; i < data.length; i += 4){ - data[i] = ((((data[i] / 255) - 0.5) * amount) + 0.5) * 255; - data[i+1] = ((((data[i+1] / 255) - 0.5) * amount) + 0.5) * 255; - data[i+2] = ((((data[i+2] / 255) - 0.5) * amount) + 0.5) * 255; - } - return imageData; - } - - function threshold(ctx, imageData, thresh, low, high){ - var i, r, g, b, val; - var data = imageData.data; - if(arguments.length < 3){ - thresh = 10; - low = 0; - high = 255; - } else if(arguments.length < 5){ - low = 0; - high = 255; - } - for(i = 0; i < data.length-1; i += 4){ - r = data[i]; - g = data[i+1]; - b = data[i+2]; - val = (0.2126*r + 0.7152*g + 0.0722*b >= thresh) ? high : low; - data[i] = data[i+1] = data[i+2] = val; - } - return imageData; - } - - function medianFilter(ctx, imageData){ - return convolve(ctx, imageData, - [1,0,0,0,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1,0,1,0,0,0,1], - true, true); - } - - function sobel(ctx, imageData, colorize){ - var i, v, h; - var vertical, horizontal; - var data = imageData.data; - imageData = greyscaleAvg(ctx, imageData); - horizontal = convolveFloat32(ctx, imageData, - [ -1, 0, 1, -2, 0, 2, -1, 0, 1 ]); - vertical = convolveFloat32(ctx, imageData, - [ -1, -2, -1, 0, 0, 0, 1, 2, 1 ]); - if(colorize){ - for (i=0; i total){ - swap = true; - } - } - } - } - return imageData; - } - - function solarize(ctx, imageData, threshold){ - var i, r, g, b, intensity; - var data = imageData.data; - if(arguments.length < 3){ - threshold = 50; - } - for(i = 0; i < data.length; ++i){ - r = data[i]; - g = data[i+1]; - b = data[i+2]; - intensity = (r + g + b)/3.0; - if(intensity < threshold){ - data[i] = 255 - r; - data[i+1] = 255 - g; - data[i+2] = 255 - b; - } - } - return imageData; - } - -// function blur(ctx, imageData){ -// return convolve(ctx, imageData, -// [ 1, 2, 1, 2, 1, 2, 1, 2, 1 ], -// true, true); -// } - // JSManipulate.js - function blur(ctx, imageData, amount){ - var width = imageData.width; - var width4 = width << 2; - var height = imageData.height; - var data = imageData.data; - var q, qq, qqq, b0, b1, b2, b3, bigB, index, indexLast; - var pixel, ppixel, pppixel, ppppixel; - var c = 0; - if( amount === undefined ){ - amount = 30; - } - amount /= 10; - if (amount < 0.0) { - amount = 0.0; - } - if (amount >= 2.5) { - q = 0.98711 * amount - 0.96330; - } else if (amount >= 0.5) { - q = 3.97156 - 4.14554 * Math.sqrt(1.0 - 0.26891 * amount); - } else { - q = 2 * amount * (3.97156 - 4.14554 * Math.sqrt(1.0 - 0.26891 * 0.5)); - } - qq = q * q; - qqq = qq * q; - b0 = 1.57825 + (2.44413 * q) + (1.4281 * qq ) + (0.422205 * qqq); - b1 = ((2.44413 * q) + (2.85619 * qq) + (1.26661 * qqq)) / b0; - b2 = (-((1.4281 * qq) + (1.26661 * qqq))) / b0; - b3 = (0.422205 * qqq) / b0; - bigB = 1.0 - (b1 + b2 + b3); - for (c = 0; c < 3; c++) { - for (var y = 0; y < height; y++) { - index = y * width4 + c; - indexLast = y * width4 + ((width - 1) << 2) + c; - pixel = data[index]; - ppixel = pixel; - pppixel = ppixel; - ppppixel = pppixel; - for (; index <= indexLast; index += 4) { - pixel = bigB * data[index] + b1 * ppixel + b2 * pppixel + b3 * ppppixel; - data[index] = pixel; - ppppixel = pppixel; - pppixel = ppixel; - ppixel = pixel; - } - index = y * width4 + ((width - 1) << 2) + c; - indexLast = y * width4 + c; - pixel = data[index]; - ppixel = pixel; - pppixel = ppixel; - ppppixel = pppixel; - for (; index >= indexLast; index -= 4) { - pixel = bigB * data[index] + b1 * ppixel + b2 * pppixel + b3 * ppppixel; - data[index] = pixel; - ppppixel = pppixel; - pppixel = ppixel; - ppixel = pixel; - } - } - } - for (c = 0; c < 3; c++) { - for (var x = 0; x < width; x++) { - index = (x << 2) + c; - indexLast = (height - 1) * width4 + (x << 2) + c; - pixel = data[index]; - ppixel = pixel; - pppixel = ppixel; - ppppixel = pppixel; - for (; index <= indexLast; index += width4) { - pixel = bigB * data[index] + b1 * ppixel + b2 * pppixel + b3 * ppppixel; - data[index] = pixel; - ppppixel = pppixel; - pppixel = ppixel; - ppixel = pixel; - } - index = (height - 1) * width4 + (x << 2) + c; - indexLast = (x << 2) + c; - pixel = data[index]; - ppixel = pixel; - pppixel = ppixel; - ppppixel = pppixel; - for (; index >= indexLast; index -= width4) { - pixel = bigB * data[index] + b1 * ppixel + b2 * pppixel + b3 * ppppixel; - data[index] = pixel; - ppppixel = pppixel; - pppixel = ppixel; - ppixel = pixel; - } - } - } - } - - - function edgeDetect(ctx, imageData){ - return convolve(ctx, imageData, - [ -1, -1, -1, -1, 8, -1, -1, -1, -1 ]); - } - - function sharpen(ctx, imageData, amount){ - if(arguments.length < 3){ - amount = 20; - } - return convolve(ctx, imageData, - [ 0, -1, 0, -1, amount, -1, 0, -1, 0 ], - true, true); - } - - function emboss(ctx, imageData, amount){ - if(arguments.length < 3){ - amount = 95; - } - return convolve(ctx, imageData, - [ -18, -9, 9, -9, 100 - amount, 9, 0, 9, 18 ], - true, true); - } - - function lighten(ctx, imageData, amount){ - if(arguments.length < 3 || amount < 0){ - amount = 12/9; - } - return convolve(ctx, imageData, [ 0, 0, 0, 0, amount, 0, 0, 0, 0 ]); - } - - function darken(ctx, imageData, amount){ - if(arguments.length < 3 || amount > 1){ - amount = 6/9; - } - return convolve(ctx, imageData, [ 0, 0, 0, 0, amount, 0, 0, 0, 0 ]); - } - - return { - convolve : convolve, - luminance : luminance, - greyscale : greyscale, - greyscaleAvg : greyscaleAvg, - brighten : brighten, - noise : noise, - duotone : duotone, - invert : invert, - pixelate : pixelate, - sobel : sobel, - medianFilter : medianFilter, - sepia : sepia, - contrast : contrast, - threshold : threshold, - gamma : gamma, - gaussBlur5 : gaussBlur5, - posterize : posterize, - scatter : scatter, - solarize : solarize, - sharpen : sharpen, - edgeDetect : edgeDetect, - blur : blur, - emboss : emboss, - lighten : lighten, - darken : darken - }; -}()); diff --git a/web/static/js9_old/js/imagefilters.min.js b/web/static/js9_old/js/imagefilters.min.js deleted file mode 100644 index cdb9742fc19f15ae328d2baff7b802128f2da4fb..0000000000000000000000000000000000000000 --- a/web/static/js9_old/js/imagefilters.min.js +++ /dev/null @@ -1,15 +0,0 @@ -var ImageFilters; -ImageFilters=function(){function D(c){var d;var a=c.reduce(function(a,c){return a+c});for(d=0;darguments.length&&(a=10);for(b=0;barguments.length?(a=-30,b=30):3===arguments.length&&(b=a,a=-a);var g=b-a;for(e=0;earguments.length&&(a=2);if(0>=a)return d;var q=2*a;for(e=a;earguments.length&&(a=2);-100> -a?a=-100:100arguments.length?(a=10,b=0,e=255):5>arguments.length&&(b=0,e=255);for(f=0;f=a?e:b;g[f]=g[f+1]=g[f+2]=h}return d},gamma:function(c,d,a){var b,e=d.data;3>arguments.length&&(a=.2);for(b=0;barguments.length&&(a=40);for(b=0;256>b;++b)barguments.length&&(a=5);if(0>=a)return d;var m=2*a;var q=(a-1)*a;for(e=a;eq&&(n=!0)}}return d},solarize:function(c,d,a){var b,e=d.data;3>arguments.length&&(a=50);for(b=0;barguments.length&&(a=20);return v(c,d,[0,-1,0,-1,a,-1,0,-1,0],!0,!0)},edgeDetect:function(c,d){return v(c,d,[-1,-1,-1,-1,8,-1,-1,-1,-1])},blur:function(c,d,a){c=d.width;var b=c<<2,e=d.height;d=d.data;var f,g,h,k,m;void 0===a&& -(a=30);a/=10;0>a&&(a=0);a=2.5<=a?.98711*a-.9633:.5<=a?3.97156-4.14554*Math.sqrt(1-.26891*a):2*a*(3.97156-4.14554*Math.sqrt(.865545));var q=a*a;var n=q*a;var p=1.57825+2.44413*a+1.4281*q+.422205*n;a=(2.44413*a+2.85619*q+1.26661*n)/p;q=-(1.4281*q+1.26661*n)/p;n=.422205*n/p;p=1-(a+q+n);for(m=0;3>m;m++)for(var r=0;r=t;l-=4)f=p*d[l]+a*g+q*h+n*k,d[l]=f, -k=h,h=g,g=f}for(m=0;3>m;m++)for(r=0;r=t;l-=b)f=p*d[l]+a*g+q*h+n*k,d[l]=f,k=h,h=g,g=f}},emboss:function(c,d,a){3>arguments.length&&(a=95);return v(c,d,[-18,-9,9,-9,100-a,9,0,9,18],!0,!0)},lighten:function(c,d,a){if(3>arguments.length||0>a)a=12/9;return v(c,d,[0,0,0,0,a,0,0,0,0])},darken:function(c,d,a){if(3>arguments.length||1 elements - // (i.e., `typeof document.createElement( "object" ) === "function"`). - // We don't want to classify *any* DOM node as a function. - return typeof obj === "function" && typeof obj.nodeType !== "number"; - }; - - -var isWindow = function isWindow( obj ) { - return obj != null && obj === obj.window; - }; - - -var document = window.document; - - - - var preservedScriptAttributes = { - type: true, - src: true, - nonce: true, - noModule: true - }; - - function DOMEval( code, node, doc ) { - doc = doc || document; - - var i, val, - script = doc.createElement( "script" ); - - script.text = code; - if ( node ) { - for ( i in preservedScriptAttributes ) { - - // Support: Firefox 64+, Edge 18+ - // Some browsers don't support the "nonce" property on scripts. - // On the other hand, just using `getAttribute` is not enough as - // the `nonce` attribute is reset to an empty string whenever it - // becomes browsing-context connected. - // See https://github.com/whatwg/html/issues/2369 - // See https://html.spec.whatwg.org/#nonce-attributes - // The `node.getAttribute` check was added for the sake of - // `jQuery.globalEval` so that it can fake a nonce-containing node - // via an object. - val = node[ i ] || node.getAttribute && node.getAttribute( i ); - if ( val ) { - script.setAttribute( i, val ); - } - } - } - doc.head.appendChild( script ).parentNode.removeChild( script ); - } - - -function toType( obj ) { - if ( obj == null ) { - return obj + ""; - } - - // Support: Android <=2.3 only (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call( obj ) ] || "object" : - typeof obj; -} -/* global Symbol */ -// Defining this global in .eslintrc.json would create a danger of using the global -// unguarded in another place, it seems safer to define global only for this module - - - -var - version = "3.5.0", - - // Define a local copy of jQuery - jQuery = function( selector, context ) { - - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init( selector, context ); - }; - -jQuery.fn = jQuery.prototype = { - - // The current version of jQuery being used - jquery: version, - - constructor: jQuery, - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function() { - return slice.call( this ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - - // Return all the elements in a clean array - if ( num == null ) { - return slice.call( this ); - } - - // Return just the one element from the set - return num < 0 ? this[ num + this.length ] : this[ num ]; - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - each: function( callback ) { - return jQuery.each( this, callback ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map( this, function( elem, i ) { - return callback.call( elem, i, elem ); - } ) ); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - even: function() { - return this.pushStack( jQuery.grep( this, function( _elem, i ) { - return ( i + 1 ) % 2; - } ) ); - }, - - odd: function() { - return this.pushStack( jQuery.grep( this, function( _elem, i ) { - return i % 2; - } ) ); - }, - - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); - }, - - end: function() { - return this.prevObject || this.constructor(); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: arr.sort, - splice: arr.splice -}; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[ 0 ] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - - // Skip the boolean and the target - target = arguments[ i ] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !isFunction( target ) ) { - target = {}; - } - - // Extend jQuery itself if only one argument is passed - if ( i === length ) { - target = this; - i--; - } - - for ( ; i < length; i++ ) { - - // Only deal with non-null/undefined values - if ( ( options = arguments[ i ] ) != null ) { - - // Extend the base object - for ( name in options ) { - copy = options[ name ]; - - // Prevent Object.prototype pollution - // Prevent never-ending loop - if ( name === "__proto__" || target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject( copy ) || - ( copyIsArray = Array.isArray( copy ) ) ) ) { - src = target[ name ]; - - // Ensure proper type for the source value - if ( copyIsArray && !Array.isArray( src ) ) { - clone = []; - } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { - clone = {}; - } else { - clone = src; - } - copyIsArray = false; - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend( { - - // Unique for each copy of jQuery on the page - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function( msg ) { - throw new Error( msg ); - }, - - noop: function() {}, - - isPlainObject: function( obj ) { - var proto, Ctor; - - // Detect obvious negatives - // Use toString instead of jQuery.type to catch host objects - if ( !obj || toString.call( obj ) !== "[object Object]" ) { - return false; - } - - proto = getProto( obj ); - - // Objects with no prototype (e.g., `Object.create( null )`) are plain - if ( !proto ) { - return true; - } - - // Objects with prototype are plain iff they were constructed by a global Object function - Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; - return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; - }, - - isEmptyObject: function( obj ) { - var name; - - for ( name in obj ) { - return false; - } - return true; - }, - - // Evaluates a script in a provided context; falls back to the global one - // if not specified. - globalEval: function( code, options, doc ) { - DOMEval( code, { nonce: options && options.nonce }, doc ); - }, - - each: function( obj, callback ) { - var length, i = 0; - - if ( isArrayLike( obj ) ) { - length = obj.length; - for ( ; i < length; i++ ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } else { - for ( i in obj ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } - - return obj; - }, - - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; - - if ( arr != null ) { - if ( isArrayLike( Object( arr ) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - push.call( ret, arr ); - } - } - - return ret; - }, - - inArray: function( elem, arr, i ) { - return arr == null ? -1 : indexOf.call( arr, elem, i ); - }, - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - merge: function( first, second ) { - var len = +second.length, - j = 0, - i = first.length; - - for ( ; j < len; j++ ) { - first[ i++ ] = second[ j ]; - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, invert ) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - callbackInverse = !callback( elems[ i ], i ); - if ( callbackInverse !== callbackExpect ) { - matches.push( elems[ i ] ); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var length, value, - i = 0, - ret = []; - - // Go through the array, translating each of the items to their new values - if ( isArrayLike( elems ) ) { - length = elems.length; - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - - // Go through every key on the object, - } else { - for ( i in elems ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - } - - // Flatten any nested arrays - return flat( ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support -} ); - -if ( typeof Symbol === "function" ) { - jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; -} - -// Populate the class2type map -jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), -function( _i, name ) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -} ); - -function isArrayLike( obj ) { - - // Support: real iOS 8.2 only (not reproducible in simulator) - // `in` check used to prevent JIT error (gh-2145) - // hasOwn isn't used here due to false negatives - // regarding Nodelist length in IE - var length = !!obj && "length" in obj && obj.length, - type = toType( obj ); - - if ( isFunction( obj ) || isWindow( obj ) ) { - return false; - } - - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj; -} -var Sizzle = -/*! - * Sizzle CSS Selector Engine v2.3.5 - * https://sizzlejs.com/ - * - * Copyright JS Foundation and other contributors - * Released under the MIT license - * https://js.foundation/ - * - * Date: 2020-03-14 - */ -( function( window ) { -var i, - support, - Expr, - getText, - isXML, - tokenize, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, - - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - // Instance-specific data - expando = "sizzle" + 1 * new Date(), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - nonnativeSelectorCache = createCache(), - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, - - // Instance methods - hasOwn = ( {} ).hasOwnProperty, - arr = [], - pop = arr.pop, - pushNative = arr.push, - push = arr.push, - slice = arr.slice, - - // Use a stripped-down indexOf as it's faster than native - // https://jsperf.com/thor-indexof-vs-for/5 - indexOf = function( list, elem ) { - var i = 0, - len = list.length; - for ( ; i < len; i++ ) { - if ( list[ i ] === elem ) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + - "ismap|loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // http://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", - - // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram - identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + - "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", - - // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + - - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + - - // "Attribute values must be CSS identifiers [capture 5] - // or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + - whitespace + "*\\]", - - pseudos = ":(" + identifier + ")(?:\\((" + - - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + - - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + - - // 3. anything else (capture 2) - ".*" + - ")\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rwhitespace = new RegExp( whitespace + "+", "g" ), - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + - whitespace + "+$", "g" ), - - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + - "*" ), - rdescend = new RegExp( whitespace + "|>" ), - - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), - - matchExpr = { - "ID": new RegExp( "^#(" + identifier + ")" ), - "CLASS": new RegExp( "^\\.(" + identifier + ")" ), - "TAG": new RegExp( "^(" + identifier + "|[*])" ), - "ATTR": new RegExp( "^" + attributes ), - "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + - whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + - whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), - - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + - "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + - "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, - - rhtml = /HTML$/i, - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rnative = /^[^{]+\{\s*\[native \w/, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - - // CSS escapes - // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), - funescape = function( escape, nonHex ) { - var high = "0x" + escape.slice( 1 ) - 0x10000; - - return nonHex ? - - // Strip the backslash prefix from a non-hex escape sequence - nonHex : - - // Replace a hexadecimal escape sequence with the encoded Unicode code point - // Support: IE <=11+ - // For values outside the Basic Multilingual Plane (BMP), manually construct a - // surrogate pair - high < 0 ? - String.fromCharCode( high + 0x10000 ) : - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }, - - // CSS string/identifier serialization - // https://drafts.csswg.org/cssom/#common-serializing-idioms - rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, - fcssescape = function( ch, asCodePoint ) { - if ( asCodePoint ) { - - // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER - if ( ch === "\0" ) { - return "\uFFFD"; - } - - // Control characters and (dependent upon position) numbers get escaped as code points - return ch.slice( 0, -1 ) + "\\" + - ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; - } - - // Other potentially-special ASCII characters get backslash-escaped - return "\\" + ch; - }, - - // Used for iframes - // See setDocument() - // Removing the function wrapper causes a "Permission Denied" - // error in IE - unloadHandler = function() { - setDocument(); - }, - - inDisabledFieldset = addCombinator( - function( elem ) { - return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; - }, - { dir: "parentNode", next: "legend" } - ); - -// Optimize for push.apply( _, NodeList ) -try { - push.apply( - ( arr = slice.call( preferredDoc.childNodes ) ), - preferredDoc.childNodes - ); - - // Support: Android<4.0 - // Detect silently failing push.apply - // eslint-disable-next-line no-unused-expressions - arr[ preferredDoc.childNodes.length ].nodeType; -} catch ( e ) { - push = { apply: arr.length ? - - // Leverage slice if possible - function( target, els ) { - pushNative.apply( target, slice.call( els ) ); - } : - - // Support: IE<9 - // Otherwise append directly - function( target, els ) { - var j = target.length, - i = 0; - - // Can't trust NodeList.length - while ( ( target[ j++ ] = els[ i++ ] ) ) {} - target.length = j - 1; - } - }; -} - -function Sizzle( selector, context, results, seed ) { - var m, i, elem, nid, match, groups, newSelector, - newContext = context && context.ownerDocument, - - // nodeType defaults to 9, since context defaults to document - nodeType = context ? context.nodeType : 9; - - results = results || []; - - // Return early from calls with invalid selector or context - if ( typeof selector !== "string" || !selector || - nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { - - return results; - } - - // Try to shortcut find operations (as opposed to filters) in HTML documents - if ( !seed ) { - setDocument( context ); - context = context || document; - - if ( documentIsHTML ) { - - // If the selector is sufficiently simple, try using a "get*By*" DOM method - // (excepting DocumentFragment context, where the methods don't exist) - if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { - - // ID selector - if ( ( m = match[ 1 ] ) ) { - - // Document context - if ( nodeType === 9 ) { - if ( ( elem = context.getElementById( m ) ) ) { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } - - // Element context - } else { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( newContext && ( elem = newContext.getElementById( m ) ) && - contains( context, elem ) && - elem.id === m ) { - - results.push( elem ); - return results; - } - } - - // Type selector - } else if ( match[ 2 ] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // Class selector - } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && - context.getElementsByClassName ) { - - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // Take advantage of querySelectorAll - if ( support.qsa && - !nonnativeSelectorCache[ selector + " " ] && - ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && - - // Support: IE 8 only - // Exclude object elements - ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { - - newSelector = selector; - newContext = context; - - // qSA considers elements outside a scoping root when evaluating child or - // descendant combinators, which is not what we want. - // In such cases, we work around the behavior by prefixing every selector in the - // list with an ID selector referencing the scope context. - // The technique has to be used as well when a leading combinator is used - // as such selectors are not recognized by querySelectorAll. - // Thanks to Andrew Dupont for this technique. - if ( nodeType === 1 && - ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { - - // Expand context for sibling selectors - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || - context; - - // We can use :scope instead of the ID hack if the browser - // supports it & if we're not changing the context. - if ( newContext !== context || !support.scope ) { - - // Capture the context ID, setting it first if necessary - if ( ( nid = context.getAttribute( "id" ) ) ) { - nid = nid.replace( rcssescape, fcssescape ); - } else { - context.setAttribute( "id", ( nid = expando ) ); - } - } - - // Prefix every selector in the list - groups = tokenize( selector ); - i = groups.length; - while ( i-- ) { - groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + - toSelector( groups[ i ] ); - } - newSelector = groups.join( "," ); - } - - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch ( qsaError ) { - nonnativeSelectorCache( selector, true ); - } finally { - if ( nid === expando ) { - context.removeAttribute( "id" ); - } - } - } - } - } - - // All others - return select( selector.replace( rtrim, "$1" ), context, results, seed ); -} - -/** - * Create key-value caches of limited size - * @returns {function(string, object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ -function createCache() { - var keys = []; - - function cache( key, value ) { - - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if ( keys.push( key + " " ) > Expr.cacheLength ) { - - // Only keep the most recent entries - delete cache[ keys.shift() ]; - } - return ( cache[ key + " " ] = value ); - } - return cache; -} - -/** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ -function markFunction( fn ) { - fn[ expando ] = true; - return fn; -} - -/** - * Support testing using an element - * @param {Function} fn Passed the created element and returns a boolean result - */ -function assert( fn ) { - var el = document.createElement( "fieldset" ); - - try { - return !!fn( el ); - } catch ( e ) { - return false; - } finally { - - // Remove from its parent by default - if ( el.parentNode ) { - el.parentNode.removeChild( el ); - } - - // release memory in IE - el = null; - } -} - -/** - * Adds the same handler for all of the specified attrs - * @param {String} attrs Pipe-separated list of attributes - * @param {Function} handler The method that will be applied - */ -function addHandle( attrs, handler ) { - var arr = attrs.split( "|" ), - i = arr.length; - - while ( i-- ) { - Expr.attrHandle[ arr[ i ] ] = handler; - } -} - -/** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ -function siblingCheck( a, b ) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - a.sourceIndex - b.sourceIndex; - - // Use IE sourceIndex if available on both nodes - if ( diff ) { - return diff; - } - - // Check if b follows a - if ( cur ) { - while ( ( cur = cur.nextSibling ) ) { - if ( cur === b ) { - return -1; - } - } - } - - return a ? 1 : -1; -} - -/** - * Returns a function to use in pseudos for input types - * @param {String} type - */ -function createInputPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ -function createButtonPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return ( name === "input" || name === "button" ) && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for :enabled/:disabled - * @param {Boolean} disabled true for :disabled; false for :enabled - */ -function createDisabledPseudo( disabled ) { - - // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable - return function( elem ) { - - // Only certain elements can match :enabled or :disabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled - if ( "form" in elem ) { - - // Check for inherited disabledness on relevant non-disabled elements: - // * listed form-associated elements in a disabled fieldset - // https://html.spec.whatwg.org/multipage/forms.html#category-listed - // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled - // * option elements in a disabled optgroup - // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled - // All such elements have a "form" property. - if ( elem.parentNode && elem.disabled === false ) { - - // Option elements defer to a parent optgroup if present - if ( "label" in elem ) { - if ( "label" in elem.parentNode ) { - return elem.parentNode.disabled === disabled; - } else { - return elem.disabled === disabled; - } - } - - // Support: IE 6 - 11 - // Use the isDisabled shortcut property to check for disabled fieldset ancestors - return elem.isDisabled === disabled || - - // Where there is no isDisabled, check manually - /* jshint -W018 */ - elem.isDisabled !== !disabled && - inDisabledFieldset( elem ) === disabled; - } - - return elem.disabled === disabled; - - // Try to winnow out elements that can't be disabled before trusting the disabled property. - // Some victims get caught in our net (label, legend, menu, track), but it shouldn't - // even exist on them, let alone have a boolean value. - } else if ( "label" in elem ) { - return elem.disabled === disabled; - } - - // Remaining elements are neither :enabled nor :disabled - return false; - }; -} - -/** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ -function createPositionalPseudo( fn ) { - return markFunction( function( argument ) { - argument = +argument; - return markFunction( function( seed, matches ) { - var j, - matchIndexes = fn( [], seed.length, argument ), - i = matchIndexes.length; - - // Match elements found at the specified indexes - while ( i-- ) { - if ( seed[ ( j = matchIndexes[ i ] ) ] ) { - seed[ j ] = !( matches[ j ] = seed[ j ] ); - } - } - } ); - } ); -} - -/** - * Checks a node for validity as a Sizzle context - * @param {Element|Object=} context - * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value - */ -function testContext( context ) { - return context && typeof context.getElementsByTagName !== "undefined" && context; -} - -// Expose support vars for convenience -support = Sizzle.support = {}; - -/** - * Detects XML nodes - * @param {Element|Object} elem An element or a document - * @returns {Boolean} True iff elem is a non-HTML XML node - */ -isXML = Sizzle.isXML = function( elem ) { - var namespace = elem.namespaceURI, - docElem = ( elem.ownerDocument || elem ).documentElement; - - // Support: IE <=8 - // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes - // https://bugs.jquery.com/ticket/4833 - return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); -}; - -/** - * Sets document-related variables once based on the current document - * @param {Element|Object} [doc] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ -setDocument = Sizzle.setDocument = function( node ) { - var hasCompare, subWindow, - doc = node ? node.ownerDocument || node : preferredDoc; - - // Return early if doc is invalid or already selected - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { - return document; - } - - // Update global variables - document = doc; - docElem = document.documentElement; - documentIsHTML = !isXML( document ); - - // Support: IE 9 - 11+, Edge 12 - 18+ - // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( preferredDoc != document && - ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { - - // Support: IE 11, Edge - if ( subWindow.addEventListener ) { - subWindow.addEventListener( "unload", unloadHandler, false ); - - // Support: IE 9 - 10 only - } else if ( subWindow.attachEvent ) { - subWindow.attachEvent( "onunload", unloadHandler ); - } - } - - // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, - // Safari 4 - 5 only, Opera <=11.6 - 12.x only - // IE/Edge & older browsers don't support the :scope pseudo-class. - // Support: Safari 6.0 only - // Safari 6.0 supports :scope but it's an alias of :root there. - support.scope = assert( function( el ) { - docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); - return typeof el.querySelectorAll !== "undefined" && - !el.querySelectorAll( ":scope fieldset div" ).length; - } ); - - /* Attributes - ---------------------------------------------------------------------- */ - - // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties - // (excepting IE8 booleans) - support.attributes = assert( function( el ) { - el.className = "i"; - return !el.getAttribute( "className" ); - } ); - - /* getElement(s)By* - ---------------------------------------------------------------------- */ - - // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert( function( el ) { - el.appendChild( document.createComment( "" ) ); - return !el.getElementsByTagName( "*" ).length; - } ); - - // Support: IE<9 - support.getElementsByClassName = rnative.test( document.getElementsByClassName ); - - // Support: IE<10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programmatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert( function( el ) { - docElem.appendChild( el ).id = expando; - return !document.getElementsByName || !document.getElementsByName( expando ).length; - } ); - - // ID filter and find - if ( support.getById ) { - Expr.filter[ "ID" ] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - return elem.getAttribute( "id" ) === attrId; - }; - }; - Expr.find[ "ID" ] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var elem = context.getElementById( id ); - return elem ? [ elem ] : []; - } - }; - } else { - Expr.filter[ "ID" ] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - var node = typeof elem.getAttributeNode !== "undefined" && - elem.getAttributeNode( "id" ); - return node && node.value === attrId; - }; - }; - - // Support: IE 6 - 7 only - // getElementById is not reliable as a find shortcut - Expr.find[ "ID" ] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var node, i, elems, - elem = context.getElementById( id ); - - if ( elem ) { - - // Verify the id attribute - node = elem.getAttributeNode( "id" ); - if ( node && node.value === id ) { - return [ elem ]; - } - - // Fall back on getElementsByName - elems = context.getElementsByName( id ); - i = 0; - while ( ( elem = elems[ i++ ] ) ) { - node = elem.getAttributeNode( "id" ); - if ( node && node.value === id ) { - return [ elem ]; - } - } - } - - return []; - } - }; - } - - // Tag - Expr.find[ "TAG" ] = support.getElementsByTagName ? - function( tag, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( tag ); - - // DocumentFragment nodes don't have gEBTN - } else if ( support.qsa ) { - return context.querySelectorAll( tag ); - } - } : - - function( tag, context ) { - var elem, - tmp = [], - i = 0, - - // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too - results = context.getElementsByTagName( tag ); - - // Filter out possible comments - if ( tag === "*" ) { - while ( ( elem = results[ i++ ] ) ) { - if ( elem.nodeType === 1 ) { - tmp.push( elem ); - } - } - - return tmp; - } - return results; - }; - - // Class - Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { - if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { - return context.getElementsByClassName( className ); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - // QSA and matchesSelector support - - // matchesSelector(:active) reports false when true (IE9/Opera 11.5) - rbuggyMatches = []; - - // qSa(:focus) reports false when true (Chrome 21) - // We allow this because of a bug in IE8/9 that throws an error - // whenever `document.activeElement` is accessed on an iframe - // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See https://bugs.jquery.com/ticket/13378 - rbuggyQSA = []; - - if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { - - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert( function( el ) { - - var input; - - // Select is set to empty string on purpose - // This is to test IE's treatment of not explicitly - // setting a boolean content attribute, - // since its presence should be enough - // https://bugs.jquery.com/ticket/12359 - docElem.appendChild( el ).innerHTML = "" + - ""; - - // Support: IE8, Opera 11-12.16 - // Nothing should be selected when empty strings follow ^= or $= or *= - // The test attribute must be unknown in Opera but "safe" for WinRT - // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { - rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); - } - - // Support: IE8 - // Boolean attributes and "value" are not treated correctly - if ( !el.querySelectorAll( "[selected]" ).length ) { - rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); - } - - // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ - if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { - rbuggyQSA.push( "~=" ); - } - - // Support: IE 11+, Edge 15 - 18+ - // IE 11/Edge don't find elements on a `[name='']` query in some cases. - // Adding a temporary attribute to the document before the selection works - // around the issue. - // Interestingly, IE 10 & older don't seem to have the issue. - input = document.createElement( "input" ); - input.setAttribute( "name", "" ); - el.appendChild( input ); - if ( !el.querySelectorAll( "[name='']" ).length ) { - rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + - whitespace + "*(?:''|\"\")" ); - } - - // Webkit/Opera - :checked should return selected option elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - // IE8 throws error here and will not see later tests - if ( !el.querySelectorAll( ":checked" ).length ) { - rbuggyQSA.push( ":checked" ); - } - - // Support: Safari 8+, iOS 8+ - // https://bugs.webkit.org/show_bug.cgi?id=136851 - // In-page `selector#id sibling-combinator selector` fails - if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { - rbuggyQSA.push( ".#.+[+~]" ); - } - - // Support: Firefox <=3.6 - 5 only - // Old Firefox doesn't throw on a badly-escaped identifier. - el.querySelectorAll( "\\\f" ); - rbuggyQSA.push( "[\\r\\n\\f]" ); - } ); - - assert( function( el ) { - el.innerHTML = "" + - ""; - - // Support: Windows 8 Native Apps - // The type and name attributes are restricted during .innerHTML assignment - var input = document.createElement( "input" ); - input.setAttribute( "type", "hidden" ); - el.appendChild( input ).setAttribute( "name", "D" ); - - // Support: IE8 - // Enforce case-sensitivity of name attribute - if ( el.querySelectorAll( "[name=d]" ).length ) { - rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); - } - - // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) - // IE8 throws error here and will not see later tests - if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Support: IE9-11+ - // IE's :disabled selector does not pick up the children of disabled fieldsets - docElem.appendChild( el ).disabled = true; - if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Support: Opera 10 - 11 only - // Opera 10-11 does not throw on post-comma invalid pseudos - el.querySelectorAll( "*,:x" ); - rbuggyQSA.push( ",.*:" ); - } ); - } - - if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || - docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector ) ) ) ) { - - assert( function( el ) { - - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9) - support.disconnectedMatch = matches.call( el, "*" ); - - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( el, "[s!='']:x" ); - rbuggyMatches.push( "!=", pseudos ); - } ); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); - - /* Contains - ---------------------------------------------------------------------- */ - hasCompare = rnative.test( docElem.compareDocumentPosition ); - - // Element contains another - // Purposefully self-exclusive - // As in, an element does not contain itself - contains = hasCompare || rnative.test( docElem.contains ) ? - function( a, b ) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b && b.parentNode; - return a === bup || !!( bup && bup.nodeType === 1 && ( - adown.contains ? - adown.contains( bup ) : - a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - ) ); - } : - function( a, b ) { - if ( b ) { - while ( ( b = b.parentNode ) ) { - if ( b === a ) { - return true; - } - } - } - return false; - }; - - /* Sorting - ---------------------------------------------------------------------- */ - - // Document order sorting - sortOrder = hasCompare ? - function( a, b ) { - - // Flag for duplicate removal - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - // Sort on method existence if only one input has compareDocumentPosition - var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; - if ( compare ) { - return compare; - } - - // Calculate position if both inputs belong to the same document - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? - a.compareDocumentPosition( b ) : - - // Otherwise we know they are disconnected - 1; - - // Disconnected nodes - if ( compare & 1 || - ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { - - // Choose the first element that is related to our preferred document - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( a == document || a.ownerDocument == preferredDoc && - contains( preferredDoc, a ) ) { - return -1; - } - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( b == document || b.ownerDocument == preferredDoc && - contains( preferredDoc, b ) ) { - return 1; - } - - // Maintain original order - return sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - } - - return compare & 4 ? -1 : 1; - } : - function( a, b ) { - - // Exit early if the nodes are identical - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - var cur, - i = 0, - aup = a.parentNode, - bup = b.parentNode, - ap = [ a ], - bp = [ b ]; - - // Parentless nodes are either documents or disconnected - if ( !aup || !bup ) { - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - /* eslint-disable eqeqeq */ - return a == document ? -1 : - b == document ? 1 : - /* eslint-enable eqeqeq */ - aup ? -1 : - bup ? 1 : - sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - - // If the nodes are siblings, we can do a quick check - } else if ( aup === bup ) { - return siblingCheck( a, b ); - } - - // Otherwise we need full lists of their ancestors for comparison - cur = a; - while ( ( cur = cur.parentNode ) ) { - ap.unshift( cur ); - } - cur = b; - while ( ( cur = cur.parentNode ) ) { - bp.unshift( cur ); - } - - // Walk down the tree looking for a discrepancy - while ( ap[ i ] === bp[ i ] ) { - i++; - } - - return i ? - - // Do a sibling check if the nodes have a common ancestor - siblingCheck( ap[ i ], bp[ i ] ) : - - // Otherwise nodes in our document sort first - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - /* eslint-disable eqeqeq */ - ap[ i ] == preferredDoc ? -1 : - bp[ i ] == preferredDoc ? 1 : - /* eslint-enable eqeqeq */ - 0; - }; - - return document; -}; - -Sizzle.matches = function( expr, elements ) { - return Sizzle( expr, null, null, elements ); -}; - -Sizzle.matchesSelector = function( elem, expr ) { - setDocument( elem ); - - if ( support.matchesSelector && documentIsHTML && - !nonnativeSelectorCache[ expr + " " ] && - ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && - ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { - - try { - var ret = matches.call( elem, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || support.disconnectedMatch || - - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11 ) { - return ret; - } - } catch ( e ) { - nonnativeSelectorCache( expr, true ); - } - } - - return Sizzle( expr, document, null, [ elem ] ).length > 0; -}; - -Sizzle.contains = function( context, elem ) { - - // Set document vars if needed - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( ( context.ownerDocument || context ) != document ) { - setDocument( context ); - } - return contains( context, elem ); -}; - -Sizzle.attr = function( elem, name ) { - - // Set document vars if needed - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( ( elem.ownerDocument || elem ) != document ) { - setDocument( elem ); - } - - var fn = Expr.attrHandle[ name.toLowerCase() ], - - // Don't get fooled by Object.prototype properties (jQuery #13807) - val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? - fn( elem, name, !documentIsHTML ) : - undefined; - - return val !== undefined ? - val : - support.attributes || !documentIsHTML ? - elem.getAttribute( name ) : - ( val = elem.getAttributeNode( name ) ) && val.specified ? - val.value : - null; -}; - -Sizzle.escape = function( sel ) { - return ( sel + "" ).replace( rcssescape, fcssescape ); -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Document sorting and removing duplicates - * @param {ArrayLike} results - */ -Sizzle.uniqueSort = function( results ) { - var elem, - duplicates = [], - j = 0, - i = 0; - - // Unless we *know* we can detect duplicates, assume their presence - hasDuplicate = !support.detectDuplicates; - sortInput = !support.sortStable && results.slice( 0 ); - results.sort( sortOrder ); - - if ( hasDuplicate ) { - while ( ( elem = results[ i++ ] ) ) { - if ( elem === results[ i ] ) { - j = duplicates.push( i ); - } - } - while ( j-- ) { - results.splice( duplicates[ j ], 1 ); - } - } - - // Clear input after sorting to release objects - // See https://github.com/jquery/sizzle/pull/225 - sortInput = null; - - return results; -}; - -/** - * Utility function for retrieving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -getText = Sizzle.getText = function( elem ) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; - - if ( !nodeType ) { - - // If no nodeType, this is expected to be an array - while ( ( node = elem[ i++ ] ) ) { - - // Do not traverse comment nodes - ret += getText( node ); - } - } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { - - // Use textContent for elements - // innerText usage removed for consistency of new lines (jQuery #11153) - if ( typeof elem.textContent === "string" ) { - return elem.textContent; - } else { - - // Traverse its children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - - // Do not include comment or processing instruction nodes - - return ret; -}; - -Expr = Sizzle.selectors = { - - // Can be adjusted by the user - cacheLength: 50, - - createPseudo: markFunction, - - match: matchExpr, - - attrHandle: {}, - - find: {}, - - relative: { - ">": { dir: "parentNode", first: true }, - " ": { dir: "parentNode" }, - "+": { dir: "previousSibling", first: true }, - "~": { dir: "previousSibling" } - }, - - preFilter: { - "ATTR": function( match ) { - match[ 1 ] = match[ 1 ].replace( runescape, funescape ); - - // Move the given value to match[3] whether quoted or unquoted - match[ 3 ] = ( match[ 3 ] || match[ 4 ] || - match[ 5 ] || "" ).replace( runescape, funescape ); - - if ( match[ 2 ] === "~=" ) { - match[ 3 ] = " " + match[ 3 ] + " "; - } - - return match.slice( 0, 4 ); - }, - - "CHILD": function( match ) { - - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[ 1 ] = match[ 1 ].toLowerCase(); - - if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { - - // nth-* requires argument - if ( !match[ 3 ] ) { - Sizzle.error( match[ 0 ] ); - } - - // numeric x and y parameters for Expr.filter.CHILD - // remember that false/true cast respectively to 0/1 - match[ 4 ] = +( match[ 4 ] ? - match[ 5 ] + ( match[ 6 ] || 1 ) : - 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); - match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); - - // other types prohibit arguments - } else if ( match[ 3 ] ) { - Sizzle.error( match[ 0 ] ); - } - - return match; - }, - - "PSEUDO": function( match ) { - var excess, - unquoted = !match[ 6 ] && match[ 2 ]; - - if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { - return null; - } - - // Accept quoted arguments as-is - if ( match[ 3 ] ) { - match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; - - // Strip excess characters from unquoted arguments - } else if ( unquoted && rpseudo.test( unquoted ) && - - // Get excess from tokenize (recursively) - ( excess = tokenize( unquoted, true ) ) && - - // advance to the next closing parenthesis - ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { - - // excess is a negative index - match[ 0 ] = match[ 0 ].slice( 0, excess ); - match[ 2 ] = unquoted.slice( 0, excess ); - } - - // Return only captures needed by the pseudo filter method (type and argument) - return match.slice( 0, 3 ); - } - }, - - filter: { - - "TAG": function( nodeNameSelector ) { - var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); - return nodeNameSelector === "*" ? - function() { - return true; - } : - function( elem ) { - return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; - }; - }, - - "CLASS": function( className ) { - var pattern = classCache[ className + " " ]; - - return pattern || - ( pattern = new RegExp( "(^|" + whitespace + - ")" + className + "(" + whitespace + "|$)" ) ) && classCache( - className, function( elem ) { - return pattern.test( - typeof elem.className === "string" && elem.className || - typeof elem.getAttribute !== "undefined" && - elem.getAttribute( "class" ) || - "" - ); - } ); - }, - - "ATTR": function( name, operator, check ) { - return function( elem ) { - var result = Sizzle.attr( elem, name ); - - if ( result == null ) { - return operator === "!="; - } - if ( !operator ) { - return true; - } - - result += ""; - - /* eslint-disable max-len */ - - return operator === "=" ? result === check : - operator === "!=" ? result !== check : - operator === "^=" ? check && result.indexOf( check ) === 0 : - operator === "*=" ? check && result.indexOf( check ) > -1 : - operator === "$=" ? check && result.slice( -check.length ) === check : - operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : - operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : - false; - /* eslint-enable max-len */ - - }; - }, - - "CHILD": function( type, what, _argument, first, last ) { - var simple = type.slice( 0, 3 ) !== "nth", - forward = type.slice( -4 ) !== "last", - ofType = what === "of-type"; - - return first === 1 && last === 0 ? - - // Shortcut for :nth-*(n) - function( elem ) { - return !!elem.parentNode; - } : - - function( elem, _context, xml ) { - var cache, uniqueCache, outerCache, node, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType, - diff = false; - - if ( parent ) { - - // :(first|last|only)-(child|of-type) - if ( simple ) { - while ( dir ) { - node = elem; - while ( ( node = node[ dir ] ) ) { - if ( ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1 ) { - - return false; - } - } - - // Reverse direction for :only-* (if we haven't yet done so) - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } - - start = [ forward ? parent.firstChild : parent.lastChild ]; - - // non-xml :nth-child(...) stores cache data on `parent` - if ( forward && useCache ) { - - // Seek `elem` from a previously-cached index - - // ...in a gzip-friendly way - node = parent; - outerCache = node[ expando ] || ( node[ expando ] = {} ); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - ( outerCache[ node.uniqueID ] = {} ); - - cache = uniqueCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex && cache[ 2 ]; - node = nodeIndex && parent.childNodes[ nodeIndex ]; - - while ( ( node = ++nodeIndex && node && node[ dir ] || - - // Fallback to seeking `elem` from the start - ( diff = nodeIndex = 0 ) || start.pop() ) ) { - - // When found, cache indexes on `parent` and break - if ( node.nodeType === 1 && ++diff && node === elem ) { - uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; - break; - } - } - - } else { - - // Use previously-cached element index if available - if ( useCache ) { - - // ...in a gzip-friendly way - node = elem; - outerCache = node[ expando ] || ( node[ expando ] = {} ); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - ( outerCache[ node.uniqueID ] = {} ); - - cache = uniqueCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex; - } - - // xml :nth-child(...) - // or :nth-last-child(...) or :nth(-last)?-of-type(...) - if ( diff === false ) { - - // Use the same loop as above to seek `elem` from the start - while ( ( node = ++nodeIndex && node && node[ dir ] || - ( diff = nodeIndex = 0 ) || start.pop() ) ) { - - if ( ( ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1 ) && - ++diff ) { - - // Cache the index of each encountered element - if ( useCache ) { - outerCache = node[ expando ] || - ( node[ expando ] = {} ); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - ( outerCache[ node.uniqueID ] = {} ); - - uniqueCache[ type ] = [ dirruns, diff ]; - } - - if ( node === elem ) { - break; - } - } - } - } - } - - // Incorporate the offset, then check against cycle size - diff -= last; - return diff === first || ( diff % first === 0 && diff / first >= 0 ); - } - }; - }, - - "PSEUDO": function( pseudo, argument ) { - - // pseudo-class names are case-insensitive - // http://www.w3.org/TR/selectors/#pseudo-classes - // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || - Sizzle.error( "unsupported pseudo: " + pseudo ); - - // The user may use createPseudo to indicate that - // arguments are needed to create the filter function - // just as Sizzle does - if ( fn[ expando ] ) { - return fn( argument ); - } - - // But maintain support for old signatures - if ( fn.length > 1 ) { - args = [ pseudo, pseudo, "", argument ]; - return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction( function( seed, matches ) { - var idx, - matched = fn( seed, argument ), - i = matched.length; - while ( i-- ) { - idx = indexOf( seed, matched[ i ] ); - seed[ idx ] = !( matches[ idx ] = matched[ i ] ); - } - } ) : - function( elem ) { - return fn( elem, 0, args ); - }; - } - - return fn; - } - }, - - pseudos: { - - // Potentially complex pseudos - "not": markFunction( function( selector ) { - - // Trim the selector passed to compile - // to avoid treating leading and trailing - // spaces as combinators - var input = [], - results = [], - matcher = compile( selector.replace( rtrim, "$1" ) ); - - return matcher[ expando ] ? - markFunction( function( seed, matches, _context, xml ) { - var elem, - unmatched = matcher( seed, null, xml, [] ), - i = seed.length; - - // Match elements unmatched by `matcher` - while ( i-- ) { - if ( ( elem = unmatched[ i ] ) ) { - seed[ i ] = !( matches[ i ] = elem ); - } - } - } ) : - function( elem, _context, xml ) { - input[ 0 ] = elem; - matcher( input, null, xml, results ); - - // Don't keep the element (issue #299) - input[ 0 ] = null; - return !results.pop(); - }; - } ), - - "has": markFunction( function( selector ) { - return function( elem ) { - return Sizzle( selector, elem ).length > 0; - }; - } ), - - "contains": markFunction( function( text ) { - text = text.replace( runescape, funescape ); - return function( elem ) { - return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; - }; - } ), - - // "Whether an element is represented by a :lang() selector - // is based solely on the element's language value - // being equal to the identifier C, - // or beginning with the identifier C immediately followed by "-". - // The matching of C against the element's language value is performed case-insensitively. - // The identifier C does not have to be a valid language name." - // http://www.w3.org/TR/selectors/#lang-pseudo - "lang": markFunction( function( lang ) { - - // lang value must be a valid identifier - if ( !ridentifier.test( lang || "" ) ) { - Sizzle.error( "unsupported lang: " + lang ); - } - lang = lang.replace( runescape, funescape ).toLowerCase(); - return function( elem ) { - var elemLang; - do { - if ( ( elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { - - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; - } - } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); - return false; - }; - } ), - - // Miscellaneous - "target": function( elem ) { - var hash = window.location && window.location.hash; - return hash && hash.slice( 1 ) === elem.id; - }, - - "root": function( elem ) { - return elem === docElem; - }, - - "focus": function( elem ) { - return elem === document.activeElement && - ( !document.hasFocus || document.hasFocus() ) && - !!( elem.type || elem.href || ~elem.tabIndex ); - }, - - // Boolean properties - "enabled": createDisabledPseudo( false ), - "disabled": createDisabledPseudo( true ), - - "checked": function( elem ) { - - // In CSS3, :checked should return both checked and selected elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - var nodeName = elem.nodeName.toLowerCase(); - return ( nodeName === "input" && !!elem.checked ) || - ( nodeName === "option" && !!elem.selected ); - }, - - "selected": function( elem ) { - - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - // eslint-disable-next-line no-unused-expressions - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - // Contents - "empty": function( elem ) { - - // http://www.w3.org/TR/selectors/#empty-pseudo - // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), - // but not by others (comment: 8; processing instruction: 7; etc.) - // nodeType < 6 works because attributes (2) do not appear as children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - if ( elem.nodeType < 6 ) { - return false; - } - } - return true; - }, - - "parent": function( elem ) { - return !Expr.pseudos[ "empty" ]( elem ); - }, - - // Element/input types - "header": function( elem ) { - return rheader.test( elem.nodeName ); - }, - - "input": function( elem ) { - return rinputs.test( elem.nodeName ); - }, - - "button": function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === "button" || name === "button"; - }, - - "text": function( elem ) { - var attr; - return elem.nodeName.toLowerCase() === "input" && - elem.type === "text" && - - // Support: IE<8 - // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" - ( ( attr = elem.getAttribute( "type" ) ) == null || - attr.toLowerCase() === "text" ); - }, - - // Position-in-collection - "first": createPositionalPseudo( function() { - return [ 0 ]; - } ), - - "last": createPositionalPseudo( function( _matchIndexes, length ) { - return [ length - 1 ]; - } ), - - "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { - return [ argument < 0 ? argument + length : argument ]; - } ), - - "even": createPositionalPseudo( function( matchIndexes, length ) { - var i = 0; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ), - - "odd": createPositionalPseudo( function( matchIndexes, length ) { - var i = 1; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ), - - "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { - var i = argument < 0 ? - argument + length : - argument > length ? - length : - argument; - for ( ; --i >= 0; ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ), - - "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; ++i < length; ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ) - } -}; - -Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; - -// Add button/input type pseudos -for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { - Expr.pseudos[ i ] = createInputPseudo( i ); -} -for ( i in { submit: true, reset: true } ) { - Expr.pseudos[ i ] = createButtonPseudo( i ); -} - -// Easy API for creating new setFilters -function setFilters() {} -setFilters.prototype = Expr.filters = Expr.pseudos; -Expr.setFilters = new setFilters(); - -tokenize = Sizzle.tokenize = function( selector, parseOnly ) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[ selector + " " ]; - - if ( cached ) { - return parseOnly ? 0 : cached.slice( 0 ); - } - - soFar = selector; - groups = []; - preFilters = Expr.preFilter; - - while ( soFar ) { - - // Comma and first run - if ( !matched || ( match = rcomma.exec( soFar ) ) ) { - if ( match ) { - - // Don't consume trailing commas as valid - soFar = soFar.slice( match[ 0 ].length ) || soFar; - } - groups.push( ( tokens = [] ) ); - } - - matched = false; - - // Combinators - if ( ( match = rcombinators.exec( soFar ) ) ) { - matched = match.shift(); - tokens.push( { - value: matched, - - // Cast descendant combinators to space - type: match[ 0 ].replace( rtrim, " " ) - } ); - soFar = soFar.slice( matched.length ); - } - - // Filters - for ( type in Expr.filter ) { - if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || - ( match = preFilters[ type ]( match ) ) ) ) { - matched = match.shift(); - tokens.push( { - value: matched, - type: type, - matches: match - } ); - soFar = soFar.slice( matched.length ); - } - } - - if ( !matched ) { - break; - } - } - - // Return the length of the invalid excess - // if we're just parsing - // Otherwise, throw an error or return tokens - return parseOnly ? - soFar.length : - soFar ? - Sizzle.error( selector ) : - - // Cache the tokens - tokenCache( selector, groups ).slice( 0 ); -}; - -function toSelector( tokens ) { - var i = 0, - len = tokens.length, - selector = ""; - for ( ; i < len; i++ ) { - selector += tokens[ i ].value; - } - return selector; -} - -function addCombinator( matcher, combinator, base ) { - var dir = combinator.dir, - skip = combinator.next, - key = skip || dir, - checkNonElements = base && key === "parentNode", - doneName = done++; - - return combinator.first ? - - // Check against closest ancestor/preceding element - function( elem, context, xml ) { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - return matcher( elem, context, xml ); - } - } - return false; - } : - - // Check against all ancestor/preceding elements - function( elem, context, xml ) { - var oldCache, uniqueCache, outerCache, - newCache = [ dirruns, doneName ]; - - // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching - if ( xml ) { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - if ( matcher( elem, context, xml ) ) { - return true; - } - } - } - } else { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || ( elem[ expando ] = {} ); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ elem.uniqueID ] || - ( outerCache[ elem.uniqueID ] = {} ); - - if ( skip && skip === elem.nodeName.toLowerCase() ) { - elem = elem[ dir ] || elem; - } else if ( ( oldCache = uniqueCache[ key ] ) && - oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { - - // Assign to newCache so results back-propagate to previous elements - return ( newCache[ 2 ] = oldCache[ 2 ] ); - } else { - - // Reuse newcache so results back-propagate to previous elements - uniqueCache[ key ] = newCache; - - // A match means we're done; a fail means we have to keep checking - if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { - return true; - } - } - } - } - } - return false; - }; -} - -function elementMatcher( matchers ) { - return matchers.length > 1 ? - function( elem, context, xml ) { - var i = matchers.length; - while ( i-- ) { - if ( !matchers[ i ]( elem, context, xml ) ) { - return false; - } - } - return true; - } : - matchers[ 0 ]; -} - -function multipleContexts( selector, contexts, results ) { - var i = 0, - len = contexts.length; - for ( ; i < len; i++ ) { - Sizzle( selector, contexts[ i ], results ); - } - return results; -} - -function condense( unmatched, map, filter, context, xml ) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; - - for ( ; i < len; i++ ) { - if ( ( elem = unmatched[ i ] ) ) { - if ( !filter || filter( elem, context, xml ) ) { - newUnmatched.push( elem ); - if ( mapped ) { - map.push( i ); - } - } - } - } - - return newUnmatched; -} - -function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { - if ( postFilter && !postFilter[ expando ] ) { - postFilter = setMatcher( postFilter ); - } - if ( postFinder && !postFinder[ expando ] ) { - postFinder = setMatcher( postFinder, postSelector ); - } - return markFunction( function( seed, results, context, xml ) { - var temp, i, elem, - preMap = [], - postMap = [], - preexisting = results.length, - - // Get initial elements from seed or context - elems = seed || multipleContexts( - selector || "*", - context.nodeType ? [ context ] : context, - [] - ), - - // Prefilter to get matcher input, preserving a map for seed-results synchronization - matcherIn = preFilter && ( seed || !selector ) ? - condense( elems, preMap, preFilter, context, xml ) : - elems, - - matcherOut = matcher ? - - // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, - postFinder || ( seed ? preFilter : preexisting || postFilter ) ? - - // ...intermediate processing is necessary - [] : - - // ...otherwise use results directly - results : - matcherIn; - - // Find primary matches - if ( matcher ) { - matcher( matcherIn, matcherOut, context, xml ); - } - - // Apply postFilter - if ( postFilter ) { - temp = condense( matcherOut, postMap ); - postFilter( temp, [], context, xml ); - - // Un-match failing elements by moving them back to matcherIn - i = temp.length; - while ( i-- ) { - if ( ( elem = temp[ i ] ) ) { - matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); - } - } - } - - if ( seed ) { - if ( postFinder || preFilter ) { - if ( postFinder ) { - - // Get the final matcherOut by condensing this intermediate into postFinder contexts - temp = []; - i = matcherOut.length; - while ( i-- ) { - if ( ( elem = matcherOut[ i ] ) ) { - - // Restore matcherIn since elem is not yet a final match - temp.push( ( matcherIn[ i ] = elem ) ); - } - } - postFinder( null, ( matcherOut = [] ), temp, xml ); - } - - // Move matched elements from seed to results to keep them synchronized - i = matcherOut.length; - while ( i-- ) { - if ( ( elem = matcherOut[ i ] ) && - ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { - - seed[ temp ] = !( results[ temp ] = elem ); - } - } - } - - // Add elements to results, through postFinder if defined - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice( preexisting, matcherOut.length ) : - matcherOut - ); - if ( postFinder ) { - postFinder( null, results, matcherOut, xml ); - } else { - push.apply( results, matcherOut ); - } - } - } ); -} - -function matcherFromTokens( tokens ) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[ tokens[ 0 ].type ], - implicitRelative = leadingRelative || Expr.relative[ " " ], - i = leadingRelative ? 1 : 0, - - // The foundational matcher ensures that elements are reachable from top-level context(s) - matchContext = addCombinator( function( elem ) { - return elem === checkContext; - }, implicitRelative, true ), - matchAnyContext = addCombinator( function( elem ) { - return indexOf( checkContext, elem ) > -1; - }, implicitRelative, true ), - matchers = [ function( elem, context, xml ) { - var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( - ( checkContext = context ).nodeType ? - matchContext( elem, context, xml ) : - matchAnyContext( elem, context, xml ) ); - - // Avoid hanging onto element (issue #299) - checkContext = null; - return ret; - } ]; - - for ( ; i < len; i++ ) { - if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { - matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; - } else { - matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); - - // Return special upon seeing a positional matcher - if ( matcher[ expando ] ) { - - // Find the next relative operator (if any) for proper handling - j = ++i; - for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[ j ].type ] ) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher( matchers ), - i > 1 && toSelector( - - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens - .slice( 0, i - 1 ) - .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) - ).replace( rtrim, "$1" ), - matcher, - i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), - j < len && toSelector( tokens ) - ); - } - matchers.push( matcher ); - } - } - - return elementMatcher( matchers ); -} - -function matcherFromGroupMatchers( elementMatchers, setMatchers ) { - var bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function( seed, context, xml, results, outermost ) { - var elem, j, matcher, - matchedCount = 0, - i = "0", - unmatched = seed && [], - setMatched = [], - contextBackup = outermostContext, - - // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), - - // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), - len = elems.length; - - if ( outermost ) { - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - outermostContext = context == document || context || outermost; - } - - // Add elements passing elementMatchers directly to results - // Support: IE<9, Safari - // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id - for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { - if ( byElement && elem ) { - j = 0; - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( !context && elem.ownerDocument != document ) { - setDocument( elem ); - xml = !documentIsHTML; - } - while ( ( matcher = elementMatchers[ j++ ] ) ) { - if ( matcher( elem, context || document, xml ) ) { - results.push( elem ); - break; - } - } - if ( outermost ) { - dirruns = dirrunsUnique; - } - } - - // Track unmatched elements for set filters - if ( bySet ) { - - // They will have gone through all possible matchers - if ( ( elem = !matcher && elem ) ) { - matchedCount--; - } - - // Lengthen the array for every element, matched or not - if ( seed ) { - unmatched.push( elem ); - } - } - } - - // `i` is now the count of elements visited above, and adding it to `matchedCount` - // makes the latter nonnegative. - matchedCount += i; - - // Apply set filters to unmatched elements - // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` - // equals `i`), unless we didn't visit _any_ elements in the above loop because we have - // no element matchers and no seed. - // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that - // case, which will result in a "00" `matchedCount` that differs from `i` but is also - // numerically zero. - if ( bySet && i !== matchedCount ) { - j = 0; - while ( ( matcher = setMatchers[ j++ ] ) ) { - matcher( unmatched, setMatched, context, xml ); - } - - if ( seed ) { - - // Reintegrate element matches to eliminate the need for sorting - if ( matchedCount > 0 ) { - while ( i-- ) { - if ( !( unmatched[ i ] || setMatched[ i ] ) ) { - setMatched[ i ] = pop.call( results ); - } - } - } - - // Discard index placeholder values to get only actual matches - setMatched = condense( setMatched ); - } - - // Add matches to results - push.apply( results, setMatched ); - - // Seedless set matches succeeding multiple successful matchers stipulate sorting - if ( outermost && !seed && setMatched.length > 0 && - ( matchedCount + setMatchers.length ) > 1 ) { - - Sizzle.uniqueSort( results ); - } - } - - // Override manipulation of globals by nested matchers - if ( outermost ) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; - } - - return unmatched; - }; - - return bySet ? - markFunction( superMatcher ) : - superMatcher; -} - -compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[ selector + " " ]; - - if ( !cached ) { - - // Generate a function of recursive functions that can be used to check each element - if ( !match ) { - match = tokenize( selector ); - } - i = match.length; - while ( i-- ) { - cached = matcherFromTokens( match[ i ] ); - if ( cached[ expando ] ) { - setMatchers.push( cached ); - } else { - elementMatchers.push( cached ); - } - } - - // Cache the compiled function - cached = compilerCache( - selector, - matcherFromGroupMatchers( elementMatchers, setMatchers ) - ); - - // Save selector and tokenization - cached.selector = selector; - } - return cached; -}; - -/** - * A low-level selection function that works with Sizzle's compiled - * selector functions - * @param {String|Function} selector A selector or a pre-compiled - * selector function built with Sizzle.compile - * @param {Element} context - * @param {Array} [results] - * @param {Array} [seed] A set of elements to match against - */ -select = Sizzle.select = function( selector, context, results, seed ) { - var i, tokens, token, type, find, - compiled = typeof selector === "function" && selector, - match = !seed && tokenize( ( selector = compiled.selector || selector ) ); - - results = results || []; - - // Try to minimize operations if there is only one selector in the list and no seed - // (the latter of which guarantees us context) - if ( match.length === 1 ) { - - // Reduce context if the leading compound selector is an ID - tokens = match[ 0 ] = match[ 0 ].slice( 0 ); - if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && - context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { - - context = ( Expr.find[ "ID" ]( token.matches[ 0 ] - .replace( runescape, funescape ), context ) || [] )[ 0 ]; - if ( !context ) { - return results; - - // Precompiled matchers will still verify ancestry, so step up a level - } else if ( compiled ) { - context = context.parentNode; - } - - selector = selector.slice( tokens.shift().value.length ); - } - - // Fetch a seed set for right-to-left matching - i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; - while ( i-- ) { - token = tokens[ i ]; - - // Abort if we hit a combinator - if ( Expr.relative[ ( type = token.type ) ] ) { - break; - } - if ( ( find = Expr.find[ type ] ) ) { - - // Search, expanding context for leading sibling combinators - if ( ( seed = find( - token.matches[ 0 ].replace( runescape, funescape ), - rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || - context - ) ) ) { - - // If seed is empty or no tokens remain, we can return early - tokens.splice( i, 1 ); - selector = seed.length && toSelector( tokens ); - if ( !selector ) { - push.apply( results, seed ); - return results; - } - - break; - } - } - } - } - - // Compile and execute a filtering function if one is not provided - // Provide `match` to avoid retokenization if we modified the selector above - ( compiled || compile( selector, match ) )( - seed, - context, - !documentIsHTML, - results, - !context || rsibling.test( selector ) && testContext( context.parentNode ) || context - ); - return results; -}; - -// One-time assignments - -// Sort stability -support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; - -// Support: Chrome 14-35+ -// Always assume duplicates if they aren't passed to the comparison function -support.detectDuplicates = !!hasDuplicate; - -// Initialize against the default document -setDocument(); - -// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) -// Detached nodes confoundingly follow *each other* -support.sortDetached = assert( function( el ) { - - // Should return 1, but returns 4 (following) - return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; -} ); - -// Support: IE<8 -// Prevent attribute/property "interpolation" -// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !assert( function( el ) { - el.innerHTML = ""; - return el.firstChild.getAttribute( "href" ) === "#"; -} ) ) { - addHandle( "type|href|height|width", function( elem, name, isXML ) { - if ( !isXML ) { - return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); - } - } ); -} - -// Support: IE<9 -// Use defaultValue in place of getAttribute("value") -if ( !support.attributes || !assert( function( el ) { - el.innerHTML = ""; - el.firstChild.setAttribute( "value", "" ); - return el.firstChild.getAttribute( "value" ) === ""; -} ) ) { - addHandle( "value", function( elem, _name, isXML ) { - if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { - return elem.defaultValue; - } - } ); -} - -// Support: IE<9 -// Use getAttributeNode to fetch booleans when getAttribute lies -if ( !assert( function( el ) { - return el.getAttribute( "disabled" ) == null; -} ) ) { - addHandle( booleans, function( elem, name, isXML ) { - var val; - if ( !isXML ) { - return elem[ name ] === true ? name.toLowerCase() : - ( val = elem.getAttributeNode( name ) ) && val.specified ? - val.value : - null; - } - } ); -} - -return Sizzle; - -} )( window ); - - - -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; - -// Deprecated -jQuery.expr[ ":" ] = jQuery.expr.pseudos; -jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; -jQuery.escapeSelector = Sizzle.escape; - - - - -var dir = function( elem, dir, until ) { - var matched = [], - truncate = until !== undefined; - - while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { - if ( elem.nodeType === 1 ) { - if ( truncate && jQuery( elem ).is( until ) ) { - break; - } - matched.push( elem ); - } - } - return matched; -}; - - -var siblings = function( n, elem ) { - var matched = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - matched.push( n ); - } - } - - return matched; -}; - - -var rneedsContext = jQuery.expr.match.needsContext; - - - -function nodeName( elem, name ) { - - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - -}; -var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); - - - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, not ) { - if ( isFunction( qualifier ) ) { - return jQuery.grep( elements, function( elem, i ) { - return !!qualifier.call( elem, i, elem ) !== not; - } ); - } - - // Single element - if ( qualifier.nodeType ) { - return jQuery.grep( elements, function( elem ) { - return ( elem === qualifier ) !== not; - } ); - } - - // Arraylike of elements (jQuery, arguments, Array) - if ( typeof qualifier !== "string" ) { - return jQuery.grep( elements, function( elem ) { - return ( indexOf.call( qualifier, elem ) > -1 ) !== not; - } ); - } - - // Filtered directly for both simple and complex selectors - return jQuery.filter( qualifier, elements, not ); -} - -jQuery.filter = function( expr, elems, not ) { - var elem = elems[ 0 ]; - - if ( not ) { - expr = ":not(" + expr + ")"; - } - - if ( elems.length === 1 && elem.nodeType === 1 ) { - return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; - } - - return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { - return elem.nodeType === 1; - } ) ); -}; - -jQuery.fn.extend( { - find: function( selector ) { - var i, ret, - len = this.length, - self = this; - - if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter( function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - } ) ); - } - - ret = this.pushStack( [] ); - - for ( i = 0; i < len; i++ ) { - jQuery.find( selector, self[ i ], ret ); - } - - return len > 1 ? jQuery.uniqueSort( ret ) : ret; - }, - filter: function( selector ) { - return this.pushStack( winnow( this, selector || [], false ) ); - }, - not: function( selector ) { - return this.pushStack( winnow( this, selector || [], true ) ); - }, - is: function( selector ) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test( selector ) ? - jQuery( selector ) : - selector || [], - false - ).length; - } -} ); - - -// Initialize a jQuery object - - -// A central reference to the root jQuery(document) -var rootjQuery, - - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - // Shortcut simple #id case for speed - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, - - init = jQuery.fn.init = function( selector, context, root ) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } - - // Method init() accepts an alternate rootjQuery - // so migrate can support jQuery.sub (gh-2101) - root = root || rootjQuery; - - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector[ 0 ] === "<" && - selector[ selector.length - 1 ] === ">" && - selector.length >= 3 ) { - - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = rquickExpr.exec( selector ); - } - - // Match html or make sure no context is specified for #id - if ( match && ( match[ 1 ] || !context ) ) { - - // HANDLE: $(html) -> $(array) - if ( match[ 1 ] ) { - context = context instanceof jQuery ? context[ 0 ] : context; - - // Option to run scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge( this, jQuery.parseHTML( - match[ 1 ], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); - - // HANDLE: $(html, props) - if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { - - // Properties of context are called as methods if possible - if ( isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); - - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document.getElementById( match[ 2 ] ); - - if ( elem ) { - - // Inject the element directly into the jQuery object - this[ 0 ] = elem; - this.length = 1; - } - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || root ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this[ 0 ] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( isFunction( selector ) ) { - return root.ready !== undefined ? - root.ready( selector ) : - - // Execute immediately if ready is not present - selector( jQuery ); - } - - return jQuery.makeArray( selector, this ); - }; - -// Give the init function the jQuery prototype for later instantiation -init.prototype = jQuery.fn; - -// Initialize central reference -rootjQuery = jQuery( document ); - - -var rparentsprev = /^(?:parents|prev(?:Until|All))/, - - // Methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.fn.extend( { - has: function( target ) { - var targets = jQuery( target, this ), - l = targets.length; - - return this.filter( function() { - var i = 0; - for ( ; i < l; i++ ) { - if ( jQuery.contains( this, targets[ i ] ) ) { - return true; - } - } - } ); - }, - - closest: function( selectors, context ) { - var cur, - i = 0, - l = this.length, - matched = [], - targets = typeof selectors !== "string" && jQuery( selectors ); - - // Positional selectors never match, since there's no _selection_ context - if ( !rneedsContext.test( selectors ) ) { - for ( ; i < l; i++ ) { - for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { - - // Always skip document fragments - if ( cur.nodeType < 11 && ( targets ? - targets.index( cur ) > -1 : - - // Don't pass non-elements to Sizzle - cur.nodeType === 1 && - jQuery.find.matchesSelector( cur, selectors ) ) ) { - - matched.push( cur ); - break; - } - } - } - } - - return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); - }, - - // Determine the position of an element within the set - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; - } - - // Index in selector - if ( typeof elem === "string" ) { - return indexOf.call( jQuery( elem ), this[ 0 ] ); - } - - // Locate the position of the desired element - return indexOf.call( this, - - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[ 0 ] : elem - ); - }, - - add: function( selector, context ) { - return this.pushStack( - jQuery.uniqueSort( - jQuery.merge( this.get(), jQuery( selector, context ) ) - ) - ); - }, - - addBack: function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - } -} ); - -function sibling( cur, dir ) { - while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} - return cur; -} - -jQuery.each( { - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, _i, until ) { - return dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return sibling( elem, "nextSibling" ); - }, - prev: function( elem ) { - return sibling( elem, "previousSibling" ); - }, - nextAll: function( elem ) { - return dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, _i, until ) { - return dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, _i, until ) { - return dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return siblings( ( elem.parentNode || {} ).firstChild, elem ); - }, - children: function( elem ) { - return siblings( elem.firstChild ); - }, - contents: function( elem ) { - if ( elem.contentDocument != null && - - // Support: IE 11+ - // elements with no `data` attribute has an object - // `contentDocument` with a `null` prototype. - getProto( elem.contentDocument ) ) { - - return elem.contentDocument; - } - - // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only - // Treat the template element as a regular one in browsers that - // don't support it. - if ( nodeName( elem, "template" ) ) { - elem = elem.content || elem; - } - - return jQuery.merge( [], elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var matched = jQuery.map( this, fn, until ); - - if ( name.slice( -5 ) !== "Until" ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - matched = jQuery.filter( selector, matched ); - } - - if ( this.length > 1 ) { - - // Remove duplicates - if ( !guaranteedUnique[ name ] ) { - jQuery.uniqueSort( matched ); - } - - // Reverse order for parents* and prev-derivatives - if ( rparentsprev.test( name ) ) { - matched.reverse(); - } - } - - return this.pushStack( matched ); - }; -} ); -var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); - - - -// Convert String-formatted options into Object-formatted ones -function createOptions( options ) { - var object = {}; - jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { - object[ flag ] = true; - } ); - return object; -} - -/* - * Create a callback list using the following parameters: - * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible options: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( options ) { - - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - createOptions( options ) : - jQuery.extend( {}, options ); - - var // Flag to know if list is currently firing - firing, - - // Last fire value for non-forgettable lists - memory, - - // Flag to know if list was already fired - fired, - - // Flag to prevent firing - locked, - - // Actual callback list - list = [], - - // Queue of execution data for repeatable lists - queue = [], - - // Index of currently firing callback (modified by add/remove as needed) - firingIndex = -1, - - // Fire callbacks - fire = function() { - - // Enforce single-firing - locked = locked || options.once; - - // Execute callbacks for all pending executions, - // respecting firingIndex overrides and runtime changes - fired = firing = true; - for ( ; queue.length; firingIndex = -1 ) { - memory = queue.shift(); - while ( ++firingIndex < list.length ) { - - // Run callback and check for early termination - if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && - options.stopOnFalse ) { - - // Jump to end and forget the data so .add doesn't re-fire - firingIndex = list.length; - memory = false; - } - } - } - - // Forget the data if we're done with it - if ( !options.memory ) { - memory = false; - } - - firing = false; - - // Clean up if we're done firing for good - if ( locked ) { - - // Keep an empty list if we have data for future add calls - if ( memory ) { - list = []; - - // Otherwise, this object is spent - } else { - list = ""; - } - } - }, - - // Actual Callbacks object - self = { - - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - - // If we have memory from a past run, we should fire after adding - if ( memory && !firing ) { - firingIndex = list.length - 1; - queue.push( memory ); - } - - ( function add( args ) { - jQuery.each( args, function( _, arg ) { - if ( isFunction( arg ) ) { - if ( !options.unique || !self.has( arg ) ) { - list.push( arg ); - } - } else if ( arg && arg.length && toType( arg ) !== "string" ) { - - // Inspect recursively - add( arg ); - } - } ); - } )( arguments ); - - if ( memory && !firing ) { - fire(); - } - } - return this; - }, - - // Remove a callback from the list - remove: function() { - jQuery.each( arguments, function( _, arg ) { - var index; - while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); - - // Handle firing indexes - if ( index <= firingIndex ) { - firingIndex--; - } - } - } ); - return this; - }, - - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function( fn ) { - return fn ? - jQuery.inArray( fn, list ) > -1 : - list.length > 0; - }, - - // Remove all callbacks from the list - empty: function() { - if ( list ) { - list = []; - } - return this; - }, - - // Disable .fire and .add - // Abort any current/pending executions - // Clear all callbacks and values - disable: function() { - locked = queue = []; - list = memory = ""; - return this; - }, - disabled: function() { - return !list; - }, - - // Disable .fire - // Also disable .add unless we have memory (since it would have no effect) - // Abort any pending executions - lock: function() { - locked = queue = []; - if ( !memory && !firing ) { - list = memory = ""; - } - return this; - }, - locked: function() { - return !!locked; - }, - - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( !locked ) { - args = args || []; - args = [ context, args.slice ? args.slice() : args ]; - queue.push( args ); - if ( !firing ) { - fire(); - } - } - return this; - }, - - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; - - return self; -}; - - -function Identity( v ) { - return v; -} -function Thrower( ex ) { - throw ex; -} - -function adoptValue( value, resolve, reject, noValue ) { - var method; - - try { - - // Check for promise aspect first to privilege synchronous behavior - if ( value && isFunction( ( method = value.promise ) ) ) { - method.call( value ).done( resolve ).fail( reject ); - - // Other thenables - } else if ( value && isFunction( ( method = value.then ) ) ) { - method.call( value, resolve, reject ); - - // Other non-thenables - } else { - - // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: - // * false: [ value ].slice( 0 ) => resolve( value ) - // * true: [ value ].slice( 1 ) => resolve() - resolve.apply( undefined, [ value ].slice( noValue ) ); - } - - // For Promises/A+, convert exceptions into rejections - // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in - // Deferred#then to conditionally suppress rejection. - } catch ( value ) { - - // Support: Android 4.0 only - // Strict mode functions invoked without .call/.apply get global-object context - reject.apply( undefined, [ value ] ); - } -} - -jQuery.extend( { - - Deferred: function( func ) { - var tuples = [ - - // action, add listener, callbacks, - // ... .then handlers, argument index, [final state] - [ "notify", "progress", jQuery.Callbacks( "memory" ), - jQuery.Callbacks( "memory" ), 2 ], - [ "resolve", "done", jQuery.Callbacks( "once memory" ), - jQuery.Callbacks( "once memory" ), 0, "resolved" ], - [ "reject", "fail", jQuery.Callbacks( "once memory" ), - jQuery.Callbacks( "once memory" ), 1, "rejected" ] - ], - state = "pending", - promise = { - state: function() { - return state; - }, - always: function() { - deferred.done( arguments ).fail( arguments ); - return this; - }, - "catch": function( fn ) { - return promise.then( null, fn ); - }, - - // Keep pipe for back-compat - pipe: function( /* fnDone, fnFail, fnProgress */ ) { - var fns = arguments; - - return jQuery.Deferred( function( newDefer ) { - jQuery.each( tuples, function( _i, tuple ) { - - // Map tuples (progress, done, fail) to arguments (done, fail, progress) - var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; - - // deferred.progress(function() { bind to newDefer or newDefer.notify }) - // deferred.done(function() { bind to newDefer or newDefer.resolve }) - // deferred.fail(function() { bind to newDefer or newDefer.reject }) - deferred[ tuple[ 1 ] ]( function() { - var returned = fn && fn.apply( this, arguments ); - if ( returned && isFunction( returned.promise ) ) { - returned.promise() - .progress( newDefer.notify ) - .done( newDefer.resolve ) - .fail( newDefer.reject ); - } else { - newDefer[ tuple[ 0 ] + "With" ]( - this, - fn ? [ returned ] : arguments - ); - } - } ); - } ); - fns = null; - } ).promise(); - }, - then: function( onFulfilled, onRejected, onProgress ) { - var maxDepth = 0; - function resolve( depth, deferred, handler, special ) { - return function() { - var that = this, - args = arguments, - mightThrow = function() { - var returned, then; - - // Support: Promises/A+ section 2.3.3.3.3 - // https://promisesaplus.com/#point-59 - // Ignore double-resolution attempts - if ( depth < maxDepth ) { - return; - } - - returned = handler.apply( that, args ); - - // Support: Promises/A+ section 2.3.1 - // https://promisesaplus.com/#point-48 - if ( returned === deferred.promise() ) { - throw new TypeError( "Thenable self-resolution" ); - } - - // Support: Promises/A+ sections 2.3.3.1, 3.5 - // https://promisesaplus.com/#point-54 - // https://promisesaplus.com/#point-75 - // Retrieve `then` only once - then = returned && - - // Support: Promises/A+ section 2.3.4 - // https://promisesaplus.com/#point-64 - // Only check objects and functions for thenability - ( typeof returned === "object" || - typeof returned === "function" ) && - returned.then; - - // Handle a returned thenable - if ( isFunction( then ) ) { - - // Special processors (notify) just wait for resolution - if ( special ) { - then.call( - returned, - resolve( maxDepth, deferred, Identity, special ), - resolve( maxDepth, deferred, Thrower, special ) - ); - - // Normal processors (resolve) also hook into progress - } else { - - // ...and disregard older resolution values - maxDepth++; - - then.call( - returned, - resolve( maxDepth, deferred, Identity, special ), - resolve( maxDepth, deferred, Thrower, special ), - resolve( maxDepth, deferred, Identity, - deferred.notifyWith ) - ); - } - - // Handle all other returned values - } else { - - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if ( handler !== Identity ) { - that = undefined; - args = [ returned ]; - } - - // Process the value(s) - // Default process is resolve - ( special || deferred.resolveWith )( that, args ); - } - }, - - // Only normal processors (resolve) catch and reject exceptions - process = special ? - mightThrow : - function() { - try { - mightThrow(); - } catch ( e ) { - - if ( jQuery.Deferred.exceptionHook ) { - jQuery.Deferred.exceptionHook( e, - process.stackTrace ); - } - - // Support: Promises/A+ section 2.3.3.3.4.1 - // https://promisesaplus.com/#point-61 - // Ignore post-resolution exceptions - if ( depth + 1 >= maxDepth ) { - - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if ( handler !== Thrower ) { - that = undefined; - args = [ e ]; - } - - deferred.rejectWith( that, args ); - } - } - }; - - // Support: Promises/A+ section 2.3.3.3.1 - // https://promisesaplus.com/#point-57 - // Re-resolve promises immediately to dodge false rejection from - // subsequent errors - if ( depth ) { - process(); - } else { - - // Call an optional hook to record the stack, in case of exception - // since it's otherwise lost when execution goes async - if ( jQuery.Deferred.getStackHook ) { - process.stackTrace = jQuery.Deferred.getStackHook(); - } - window.setTimeout( process ); - } - }; - } - - return jQuery.Deferred( function( newDefer ) { - - // progress_handlers.add( ... ) - tuples[ 0 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onProgress ) ? - onProgress : - Identity, - newDefer.notifyWith - ) - ); - - // fulfilled_handlers.add( ... ) - tuples[ 1 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onFulfilled ) ? - onFulfilled : - Identity - ) - ); - - // rejected_handlers.add( ... ) - tuples[ 2 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onRejected ) ? - onRejected : - Thrower - ) - ); - } ).promise(); - }, - - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - return obj != null ? jQuery.extend( obj, promise ) : promise; - } - }, - deferred = {}; - - // Add list-specific methods - jQuery.each( tuples, function( i, tuple ) { - var list = tuple[ 2 ], - stateString = tuple[ 5 ]; - - // promise.progress = list.add - // promise.done = list.add - // promise.fail = list.add - promise[ tuple[ 1 ] ] = list.add; - - // Handle state - if ( stateString ) { - list.add( - function() { - - // state = "resolved" (i.e., fulfilled) - // state = "rejected" - state = stateString; - }, - - // rejected_callbacks.disable - // fulfilled_callbacks.disable - tuples[ 3 - i ][ 2 ].disable, - - // rejected_handlers.disable - // fulfilled_handlers.disable - tuples[ 3 - i ][ 3 ].disable, - - // progress_callbacks.lock - tuples[ 0 ][ 2 ].lock, - - // progress_handlers.lock - tuples[ 0 ][ 3 ].lock - ); - } - - // progress_handlers.fire - // fulfilled_handlers.fire - // rejected_handlers.fire - list.add( tuple[ 3 ].fire ); - - // deferred.notify = function() { deferred.notifyWith(...) } - // deferred.resolve = function() { deferred.resolveWith(...) } - // deferred.reject = function() { deferred.rejectWith(...) } - deferred[ tuple[ 0 ] ] = function() { - deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); - return this; - }; - - // deferred.notifyWith = list.fireWith - // deferred.resolveWith = list.fireWith - // deferred.rejectWith = list.fireWith - deferred[ tuple[ 0 ] + "With" ] = list.fireWith; - } ); - - // Make the deferred a promise - promise.promise( deferred ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( singleValue ) { - var - - // count of uncompleted subordinates - remaining = arguments.length, - - // count of unprocessed arguments - i = remaining, - - // subordinate fulfillment data - resolveContexts = Array( i ), - resolveValues = slice.call( arguments ), - - // the master Deferred - master = jQuery.Deferred(), - - // subordinate callback factory - updateFunc = function( i ) { - return function( value ) { - resolveContexts[ i ] = this; - resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; - if ( !( --remaining ) ) { - master.resolveWith( resolveContexts, resolveValues ); - } - }; - }; - - // Single- and empty arguments are adopted like Promise.resolve - if ( remaining <= 1 ) { - adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, - !remaining ); - - // Use .then() to unwrap secondary thenables (cf. gh-3000) - if ( master.state() === "pending" || - isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { - - return master.then(); - } - } - - // Multiple arguments are aggregated like Promise.all array elements - while ( i-- ) { - adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); - } - - return master.promise(); - } -} ); - - -// These usually indicate a programmer mistake during development, -// warn about them ASAP rather than swallowing them by default. -var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; - -jQuery.Deferred.exceptionHook = function( error, stack ) { - - // Support: IE 8 - 9 only - // Console exists when dev tools are open, which can happen at any time - if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { - window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); - } -}; - - - - -jQuery.readyException = function( error ) { - window.setTimeout( function() { - throw error; - } ); -}; - - - - -// The deferred used on DOM ready -var readyList = jQuery.Deferred(); - -jQuery.fn.ready = function( fn ) { - - readyList - .then( fn ) - - // Wrap jQuery.readyException in a function so that the lookup - // happens at the time of error handling instead of callback - // registration. - .catch( function( error ) { - jQuery.readyException( error ); - } ); - - return this; -}; - -jQuery.extend( { - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Handle when the DOM is ready - ready: function( wait ) { - - // Abort if there are pending holds or we're already ready - if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { - return; - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - } -} ); - -jQuery.ready.then = readyList.then; - -// The ready event handler and self cleanup method -function completed() { - document.removeEventListener( "DOMContentLoaded", completed ); - window.removeEventListener( "load", completed ); - jQuery.ready(); -} - -// Catch cases where $(document).ready() is called -// after the browser event has already occurred. -// Support: IE <=9 - 10 only -// Older IE sometimes signals "interactive" too soon -if ( document.readyState === "complete" || - ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { - - // Handle it asynchronously to allow scripts the opportunity to delay ready - window.setTimeout( jQuery.ready ); - -} else { - - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", completed ); -} - - - - -// Multifunctional method to get and set values of a collection -// The value/s can optionally be executed if it's a function -var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { - var i = 0, - len = elems.length, - bulk = key == null; - - // Sets many values - if ( toType( key ) === "object" ) { - chainable = true; - for ( i in key ) { - access( elems, fn, i, key[ i ], true, emptyGet, raw ); - } - - // Sets one value - } else if ( value !== undefined ) { - chainable = true; - - if ( !isFunction( value ) ) { - raw = true; - } - - if ( bulk ) { - - // Bulk operations run against the entire set - if ( raw ) { - fn.call( elems, value ); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function( elem, _key, value ) { - return bulk.call( jQuery( elem ), value ); - }; - } - } - - if ( fn ) { - for ( ; i < len; i++ ) { - fn( - elems[ i ], key, raw ? - value : - value.call( elems[ i ], i, fn( elems[ i ], key ) ) - ); - } - } - } - - if ( chainable ) { - return elems; - } - - // Gets - if ( bulk ) { - return fn.call( elems ); - } - - return len ? fn( elems[ 0 ], key ) : emptyGet; -}; - - -// Matches dashed string for camelizing -var rmsPrefix = /^-ms-/, - rdashAlpha = /-([a-z])/g; - -// Used by camelCase as callback to replace() -function fcamelCase( _all, letter ) { - return letter.toUpperCase(); -} - -// Convert dashed to camelCase; used by the css and data modules -// Support: IE <=9 - 11, Edge 12 - 15 -// Microsoft forgot to hump their vendor prefix (#9572) -function camelCase( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); -} -var acceptData = function( owner ) { - - // Accepts only: - // - Node - // - Node.ELEMENT_NODE - // - Node.DOCUMENT_NODE - // - Object - // - Any - return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); -}; - - - - -function Data() { - this.expando = jQuery.expando + Data.uid++; -} - -Data.uid = 1; - -Data.prototype = { - - cache: function( owner ) { - - // Check if the owner object already has a cache - var value = owner[ this.expando ]; - - // If not, create one - if ( !value ) { - value = Object.create( null ); - - // We can accept data for non-element nodes in modern browsers, - // but we should not, see #8335. - // Always return an empty object. - if ( acceptData( owner ) ) { - - // If it is a node unlikely to be stringify-ed or looped over - // use plain assignment - if ( owner.nodeType ) { - owner[ this.expando ] = value; - - // Otherwise secure it in a non-enumerable property - // configurable must be true to allow the property to be - // deleted when data is removed - } else { - Object.defineProperty( owner, this.expando, { - value: value, - configurable: true - } ); - } - } - } - - return value; - }, - set: function( owner, data, value ) { - var prop, - cache = this.cache( owner ); - - // Handle: [ owner, key, value ] args - // Always use camelCase key (gh-2257) - if ( typeof data === "string" ) { - cache[ camelCase( data ) ] = value; - - // Handle: [ owner, { properties } ] args - } else { - - // Copy the properties one-by-one to the cache object - for ( prop in data ) { - cache[ camelCase( prop ) ] = data[ prop ]; - } - } - return cache; - }, - get: function( owner, key ) { - return key === undefined ? - this.cache( owner ) : - - // Always use camelCase key (gh-2257) - owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; - }, - access: function( owner, key, value ) { - - // In cases where either: - // - // 1. No key was specified - // 2. A string key was specified, but no value provided - // - // Take the "read" path and allow the get method to determine - // which value to return, respectively either: - // - // 1. The entire cache object - // 2. The data stored at the key - // - if ( key === undefined || - ( ( key && typeof key === "string" ) && value === undefined ) ) { - - return this.get( owner, key ); - } - - // When the key is not a string, or both a key and value - // are specified, set or extend (existing objects) with either: - // - // 1. An object of properties - // 2. A key and value - // - this.set( owner, key, value ); - - // Since the "set" path can have two possible entry points - // return the expected data based on which path was taken[*] - return value !== undefined ? value : key; - }, - remove: function( owner, key ) { - var i, - cache = owner[ this.expando ]; - - if ( cache === undefined ) { - return; - } - - if ( key !== undefined ) { - - // Support array or space separated string of keys - if ( Array.isArray( key ) ) { - - // If key is an array of keys... - // We always set camelCase keys, so remove that. - key = key.map( camelCase ); - } else { - key = camelCase( key ); - - // If a key with the spaces exists, use it. - // Otherwise, create an array by matching non-whitespace - key = key in cache ? - [ key ] : - ( key.match( rnothtmlwhite ) || [] ); - } - - i = key.length; - - while ( i-- ) { - delete cache[ key[ i ] ]; - } - } - - // Remove the expando if there's no more data - if ( key === undefined || jQuery.isEmptyObject( cache ) ) { - - // Support: Chrome <=35 - 45 - // Webkit & Blink performance suffers when deleting properties - // from DOM nodes, so set to undefined instead - // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) - if ( owner.nodeType ) { - owner[ this.expando ] = undefined; - } else { - delete owner[ this.expando ]; - } - } - }, - hasData: function( owner ) { - var cache = owner[ this.expando ]; - return cache !== undefined && !jQuery.isEmptyObject( cache ); - } -}; -var dataPriv = new Data(); - -var dataUser = new Data(); - - - -// Implementation Summary -// -// 1. Enforce API surface and semantic compatibility with 1.9.x branch -// 2. Improve the module's maintainability by reducing the storage -// paths to a single mechanism. -// 3. Use the same single mechanism to support "private" and "user" data. -// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) -// 5. Avoid exposing implementation details on user objects (eg. expando properties) -// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 - -var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /[A-Z]/g; - -function getData( data ) { - if ( data === "true" ) { - return true; - } - - if ( data === "false" ) { - return false; - } - - if ( data === "null" ) { - return null; - } - - // Only convert to a number if it doesn't change the string - if ( data === +data + "" ) { - return +data; - } - - if ( rbrace.test( data ) ) { - return JSON.parse( data ); - } - - return data; -} - -function dataAttr( elem, key, data ) { - var name; - - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = getData( data ); - } catch ( e ) {} - - // Make sure we set the data so it isn't changed later - dataUser.set( elem, key, data ); - } else { - data = undefined; - } - } - return data; -} - -jQuery.extend( { - hasData: function( elem ) { - return dataUser.hasData( elem ) || dataPriv.hasData( elem ); - }, - - data: function( elem, name, data ) { - return dataUser.access( elem, name, data ); - }, - - removeData: function( elem, name ) { - dataUser.remove( elem, name ); - }, - - // TODO: Now that all calls to _data and _removeData have been replaced - // with direct calls to dataPriv methods, these can be deprecated. - _data: function( elem, name, data ) { - return dataPriv.access( elem, name, data ); - }, - - _removeData: function( elem, name ) { - dataPriv.remove( elem, name ); - } -} ); - -jQuery.fn.extend( { - data: function( key, value ) { - var i, name, data, - elem = this[ 0 ], - attrs = elem && elem.attributes; - - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = dataUser.get( elem ); - - if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { - i = attrs.length; - while ( i-- ) { - - // Support: IE 11 only - // The attrs elements can be null (#14894) - if ( attrs[ i ] ) { - name = attrs[ i ].name; - if ( name.indexOf( "data-" ) === 0 ) { - name = camelCase( name.slice( 5 ) ); - dataAttr( elem, name, data[ name ] ); - } - } - } - dataPriv.set( elem, "hasDataAttrs", true ); - } - } - - return data; - } - - // Sets multiple values - if ( typeof key === "object" ) { - return this.each( function() { - dataUser.set( this, key ); - } ); - } - - return access( this, function( value ) { - var data; - - // The calling jQuery object (element matches) is not empty - // (and therefore has an element appears at this[ 0 ]) and the - // `value` parameter was not undefined. An empty jQuery object - // will result in `undefined` for elem = this[ 0 ] which will - // throw an exception if an attempt to read a data cache is made. - if ( elem && value === undefined ) { - - // Attempt to get data from the cache - // The key will always be camelCased in Data - data = dataUser.get( elem, key ); - if ( data !== undefined ) { - return data; - } - - // Attempt to "discover" the data in - // HTML5 custom data-* attrs - data = dataAttr( elem, key ); - if ( data !== undefined ) { - return data; - } - - // We tried really hard, but the data doesn't exist. - return; - } - - // Set the data... - this.each( function() { - - // We always store the camelCased key - dataUser.set( this, key, value ); - } ); - }, null, value, arguments.length > 1, null, true ); - }, - - removeData: function( key ) { - return this.each( function() { - dataUser.remove( this, key ); - } ); - } -} ); - - -jQuery.extend( { - queue: function( elem, type, data ) { - var queue; - - if ( elem ) { - type = ( type || "fx" ) + "queue"; - queue = dataPriv.get( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !queue || Array.isArray( data ) ) { - queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); - } else { - queue.push( data ); - } - } - return queue || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - startLength = queue.length, - fn = queue.shift(), - hooks = jQuery._queueHooks( elem, type ), - next = function() { - jQuery.dequeue( elem, type ); - }; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - startLength--; - } - - if ( fn ) { - - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - // Clear up the last queue stop function - delete hooks.stop; - fn.call( elem, next, hooks ); - } - - if ( !startLength && hooks ) { - hooks.empty.fire(); - } - }, - - // Not public - generate a queueHooks object, or return the current one - _queueHooks: function( elem, type ) { - var key = type + "queueHooks"; - return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { - empty: jQuery.Callbacks( "once memory" ).add( function() { - dataPriv.remove( elem, [ type + "queue", key ] ); - } ) - } ); - } -} ); - -jQuery.fn.extend( { - queue: function( type, data ) { - var setter = 2; - - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - setter--; - } - - if ( arguments.length < setter ) { - return jQuery.queue( this[ 0 ], type ); - } - - return data === undefined ? - this : - this.each( function() { - var queue = jQuery.queue( this, type, data ); - - // Ensure a hooks for this queue - jQuery._queueHooks( this, type ); - - if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - } ); - }, - dequeue: function( type ) { - return this.each( function() { - jQuery.dequeue( this, type ); - } ); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, obj ) { - var tmp, - count = 1, - defer = jQuery.Deferred(), - elements = this, - i = this.length, - resolve = function() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - }; - - if ( typeof type !== "string" ) { - obj = type; - type = undefined; - } - type = type || "fx"; - - while ( i-- ) { - tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); - if ( tmp && tmp.empty ) { - count++; - tmp.empty.add( resolve ); - } - } - resolve(); - return defer.promise( obj ); - } -} ); -var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; - -var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); - - -var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; - -var documentElement = document.documentElement; - - - - var isAttached = function( elem ) { - return jQuery.contains( elem.ownerDocument, elem ); - }, - composed = { composed: true }; - - // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only - // Check attachment across shadow DOM boundaries when possible (gh-3504) - // Support: iOS 10.0-10.2 only - // Early iOS 10 versions support `attachShadow` but not `getRootNode`, - // leading to errors. We need to check for `getRootNode`. - if ( documentElement.getRootNode ) { - isAttached = function( elem ) { - return jQuery.contains( elem.ownerDocument, elem ) || - elem.getRootNode( composed ) === elem.ownerDocument; - }; - } -var isHiddenWithinTree = function( elem, el ) { - - // isHiddenWithinTree might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; - - // Inline style trumps all - return elem.style.display === "none" || - elem.style.display === "" && - - // Otherwise, check computed style - // Support: Firefox <=43 - 45 - // Disconnected elements can have computed display: none, so first confirm that elem is - // in the document. - isAttached( elem ) && - - jQuery.css( elem, "display" ) === "none"; - }; - - - -function adjustCSS( elem, prop, valueParts, tween ) { - var adjusted, scale, - maxIterations = 20, - currentValue = tween ? - function() { - return tween.cur(); - } : - function() { - return jQuery.css( elem, prop, "" ); - }, - initial = currentValue(), - unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), - - // Starting value computation is required for potential unit mismatches - initialInUnit = elem.nodeType && - ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && - rcssNum.exec( jQuery.css( elem, prop ) ); - - if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { - - // Support: Firefox <=54 - // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) - initial = initial / 2; - - // Trust units reported by jQuery.css - unit = unit || initialInUnit[ 3 ]; - - // Iteratively approximate from a nonzero starting point - initialInUnit = +initial || 1; - - while ( maxIterations-- ) { - - // Evaluate and update our best guess (doubling guesses that zero out). - // Finish if the scale equals or crosses 1 (making the old*new product non-positive). - jQuery.style( elem, prop, initialInUnit + unit ); - if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { - maxIterations = 0; - } - initialInUnit = initialInUnit / scale; - - } - - initialInUnit = initialInUnit * 2; - jQuery.style( elem, prop, initialInUnit + unit ); - - // Make sure we update the tween properties later on - valueParts = valueParts || []; - } - - if ( valueParts ) { - initialInUnit = +initialInUnit || +initial || 0; - - // Apply relative offset (+=/-=) if specified - adjusted = valueParts[ 1 ] ? - initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : - +valueParts[ 2 ]; - if ( tween ) { - tween.unit = unit; - tween.start = initialInUnit; - tween.end = adjusted; - } - } - return adjusted; -} - - -var defaultDisplayMap = {}; - -function getDefaultDisplay( elem ) { - var temp, - doc = elem.ownerDocument, - nodeName = elem.nodeName, - display = defaultDisplayMap[ nodeName ]; - - if ( display ) { - return display; - } - - temp = doc.body.appendChild( doc.createElement( nodeName ) ); - display = jQuery.css( temp, "display" ); - - temp.parentNode.removeChild( temp ); - - if ( display === "none" ) { - display = "block"; - } - defaultDisplayMap[ nodeName ] = display; - - return display; -} - -function showHide( elements, show ) { - var display, elem, - values = [], - index = 0, - length = elements.length; - - // Determine new display value for elements that need to change - for ( ; index < length; index++ ) { - elem = elements[ index ]; - if ( !elem.style ) { - continue; - } - - display = elem.style.display; - if ( show ) { - - // Since we force visibility upon cascade-hidden elements, an immediate (and slow) - // check is required in this first loop unless we have a nonempty display value (either - // inline or about-to-be-restored) - if ( display === "none" ) { - values[ index ] = dataPriv.get( elem, "display" ) || null; - if ( !values[ index ] ) { - elem.style.display = ""; - } - } - if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { - values[ index ] = getDefaultDisplay( elem ); - } - } else { - if ( display !== "none" ) { - values[ index ] = "none"; - - // Remember what we're overwriting - dataPriv.set( elem, "display", display ); - } - } - } - - // Set the display of the elements in a second loop to avoid constant reflow - for ( index = 0; index < length; index++ ) { - if ( values[ index ] != null ) { - elements[ index ].style.display = values[ index ]; - } - } - - return elements; -} - -jQuery.fn.extend( { - show: function() { - return showHide( this, true ); - }, - hide: function() { - return showHide( this ); - }, - toggle: function( state ) { - if ( typeof state === "boolean" ) { - return state ? this.show() : this.hide(); - } - - return this.each( function() { - if ( isHiddenWithinTree( this ) ) { - jQuery( this ).show(); - } else { - jQuery( this ).hide(); - } - } ); - } -} ); -var rcheckableType = ( /^(?:checkbox|radio)$/i ); - -var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); - -var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); - - - -( function() { - var fragment = document.createDocumentFragment(), - div = fragment.appendChild( document.createElement( "div" ) ), - input = document.createElement( "input" ); - - // Support: Android 4.0 - 4.3 only - // Check state lost if the name is set (#11217) - // Support: Windows Web Apps (WWA) - // `name` and `type` must use .setAttribute for WWA (#14901) - input.setAttribute( "type", "radio" ); - input.setAttribute( "checked", "checked" ); - input.setAttribute( "name", "t" ); - - div.appendChild( input ); - - // Support: Android <=4.1 only - // Older WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Support: IE <=11 only - // Make sure textarea (and checkbox) defaultValue is properly cloned - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; - - // Support: IE <=9 only - // IE <=9 replaces "; - support.option = !!div.lastChild; -} )(); - - -// We have to close these tags to support XHTML (#13200) -var wrapMap = { - - // XHTML parsers do not magically insert elements in the - // same way that tag soup parsers do. So we cannot shorten - // this by omitting or other required elements. - thead: [ 1, "", "
    " ], - col: [ 2, "", "
    " ], - tr: [ 2, "", "
    " ], - td: [ 3, "", "
    " ], - - _default: [ 0, "", "" ] -}; - -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// Support: IE <=9 only -if ( !support.option ) { - wrapMap.optgroup = wrapMap.option = [ 1, "" ]; -} - - -function getAll( context, tag ) { - - // Support: IE <=9 - 11 only - // Use typeof to avoid zero-argument method invocation on host objects (#15151) - var ret; - - if ( typeof context.getElementsByTagName !== "undefined" ) { - ret = context.getElementsByTagName( tag || "*" ); - - } else if ( typeof context.querySelectorAll !== "undefined" ) { - ret = context.querySelectorAll( tag || "*" ); - - } else { - ret = []; - } - - if ( tag === undefined || tag && nodeName( context, tag ) ) { - return jQuery.merge( [ context ], ret ); - } - - return ret; -} - - -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - dataPriv.set( - elems[ i ], - "globalEval", - !refElements || dataPriv.get( refElements[ i ], "globalEval" ) - ); - } -} - - -var rhtml = /<|&#?\w+;/; - -function buildFragment( elems, context, scripts, selection, ignored ) { - var elem, tmp, tag, wrap, attached, j, - fragment = context.createDocumentFragment(), - nodes = [], - i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - elem = elems[ i ]; - - if ( elem || elem === 0 ) { - - // Add nodes directly - if ( toType( elem ) === "object" ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); - - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - - // Convert html into DOM nodes - } else { - tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); - - // Deserialize a standard representation - tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; - - // Descend through wrappers to the right content - j = wrap[ 0 ]; - while ( j-- ) { - tmp = tmp.lastChild; - } - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, tmp.childNodes ); - - // Remember the top-level container - tmp = fragment.firstChild; - - // Ensure the created nodes are orphaned (#12392) - tmp.textContent = ""; - } - } - } - - // Remove wrapper from fragment - fragment.textContent = ""; - - i = 0; - while ( ( elem = nodes[ i++ ] ) ) { - - // Skip elements already in the context collection (trac-4087) - if ( selection && jQuery.inArray( elem, selection ) > -1 ) { - if ( ignored ) { - ignored.push( elem ); - } - continue; - } - - attached = isAttached( elem ); - - // Append to fragment - tmp = getAll( fragment.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( attached ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( ( elem = tmp[ j++ ] ) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - return fragment; -} - - -var - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)/; - -function returnTrue() { - return true; -} - -function returnFalse() { - return false; -} - -// Support: IE <=9 - 11+ -// focus() and blur() are asynchronous, except when they are no-op. -// So expect focus to be synchronous when the element is already active, -// and blur to be synchronous when the element is not already active. -// (focus and blur are always synchronous in other supported browsers, -// this just defines when we can count on it). -function expectSync( elem, type ) { - return ( elem === safeActiveElement() ) === ( type === "focus" ); -} - -// Support: IE <=9 only -// Accessing document.activeElement can throw unexpectedly -// https://bugs.jquery.com/ticket/13393 -function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } -} - -function on( elem, types, selector, data, fn, one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - on( elem, type, selector, data, types[ type ], one ); - } - return elem; - } - - if ( data == null && fn == null ) { - - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return elem; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return elem.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - } ); -} - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - global: {}, - - add: function( elem, types, handler, data, selector ) { - - var handleObjIn, eventHandle, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.get( elem ); - - // Only attach events to objects that accept data - if ( !acceptData( elem ) ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Ensure that invalid selectors throw exceptions at attach time - // Evaluate against documentElement in case elem is a non-element node (e.g., document) - if ( selector ) { - jQuery.find.matchesSelector( documentElement, selector ); - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if ( !( events = elemData.events ) ) { - events = elemData.events = Object.create( null ); - } - if ( !( eventHandle = elemData.handle ) ) { - eventHandle = elemData.handle = function( e ) { - - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? - jQuery.event.dispatch.apply( elem, arguments ) : undefined; - }; - } - - // Handle multiple events separated by a space - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend( { - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join( "." ) - }, handleObjIn ); - - // Init the event handler queue if we're the first - if ( !( handlers = events[ type ] ) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener if the special events handler returns false - if ( !special.setup || - special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - }, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - - var j, origCount, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); - - if ( !elemData || !( events = elemData.events ) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[ 2 ] && - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || - selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || - special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove data and the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - dataPriv.remove( elem, "handle events" ); - } - }, - - dispatch: function( nativeEvent ) { - - var i, j, ret, matched, handleObj, handlerQueue, - args = new Array( arguments.length ), - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( nativeEvent ), - - handlers = ( - dataPriv.get( this, "events" ) || Object.create( null ) - )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[ 0 ] = event; - - for ( i = 1; i < arguments.length; i++ ) { - args[ i ] = arguments[ i ]; - } - - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; - - j = 0; - while ( ( handleObj = matched.handlers[ j++ ] ) && - !event.isImmediatePropagationStopped() ) { - - // If the event is namespaced, then each handler is only invoked if it is - // specially universal or its namespaces are a superset of the event's. - if ( !event.rnamespace || handleObj.namespace === false || - event.rnamespace.test( handleObj.namespace ) ) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || - handleObj.handler ).apply( matched.elem, args ); - - if ( ret !== undefined ) { - if ( ( event.result = ret ) === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - handlers: function( event, handlers ) { - var i, handleObj, sel, matchedHandlers, matchedSelectors, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Find delegate handlers - if ( delegateCount && - - // Support: IE <=9 - // Black-hole SVG instance trees (trac-13180) - cur.nodeType && - - // Support: Firefox <=42 - // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) - // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click - // Support: IE 11 only - // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) - !( event.type === "click" && event.button >= 1 ) ) { - - for ( ; cur !== this; cur = cur.parentNode || this ) { - - // Don't check non-elements (#13208) - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { - matchedHandlers = []; - matchedSelectors = {}; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; - - if ( matchedSelectors[ sel ] === undefined ) { - matchedSelectors[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) > -1 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matchedSelectors[ sel ] ) { - matchedHandlers.push( handleObj ); - } - } - if ( matchedHandlers.length ) { - handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); - } - } - } - } - - // Add the remaining (directly-bound) handlers - cur = this; - if ( delegateCount < handlers.length ) { - handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); - } - - return handlerQueue; - }, - - addProp: function( name, hook ) { - Object.defineProperty( jQuery.Event.prototype, name, { - enumerable: true, - configurable: true, - - get: isFunction( hook ) ? - function() { - if ( this.originalEvent ) { - return hook( this.originalEvent ); - } - } : - function() { - if ( this.originalEvent ) { - return this.originalEvent[ name ]; - } - }, - - set: function( value ) { - Object.defineProperty( this, name, { - enumerable: true, - configurable: true, - writable: true, - value: value - } ); - } - } ); - }, - - fix: function( originalEvent ) { - return originalEvent[ jQuery.expando ] ? - originalEvent : - new jQuery.Event( originalEvent ); - }, - - special: { - load: { - - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - click: { - - // Utilize native event to ensure correct state for checkable inputs - setup: function( data ) { - - // For mutual compressibility with _default, replace `this` access with a local var. - // `|| data` is dead code meant only to preserve the variable through minification. - var el = this || data; - - // Claim the first handler - if ( rcheckableType.test( el.type ) && - el.click && nodeName( el, "input" ) ) { - - // dataPriv.set( el, "click", ... ) - leverageNative( el, "click", returnTrue ); - } - - // Return false to allow normal processing in the caller - return false; - }, - trigger: function( data ) { - - // For mutual compressibility with _default, replace `this` access with a local var. - // `|| data` is dead code meant only to preserve the variable through minification. - var el = this || data; - - // Force setup before triggering a click - if ( rcheckableType.test( el.type ) && - el.click && nodeName( el, "input" ) ) { - - leverageNative( el, "click" ); - } - - // Return non-false to allow normal event-path propagation - return true; - }, - - // For cross-browser consistency, suppress native .click() on links - // Also prevent it if we're currently inside a leveraged native-event stack - _default: function( event ) { - var target = event.target; - return rcheckableType.test( target.type ) && - target.click && nodeName( target, "input" ) && - dataPriv.get( target, "click" ) || - nodeName( target, "a" ); - } - }, - - beforeunload: { - postDispatch: function( event ) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if ( event.result !== undefined && event.originalEvent ) { - event.originalEvent.returnValue = event.result; - } - } - } - } -}; - -// Ensure the presence of an event listener that handles manually-triggered -// synthetic events by interrupting progress until reinvoked in response to -// *native* events that it fires directly, ensuring that state changes have -// already occurred before other listeners are invoked. -function leverageNative( el, type, expectSync ) { - - // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add - if ( !expectSync ) { - if ( dataPriv.get( el, type ) === undefined ) { - jQuery.event.add( el, type, returnTrue ); - } - return; - } - - // Register the controller as a special universal handler for all event namespaces - dataPriv.set( el, type, false ); - jQuery.event.add( el, type, { - namespace: false, - handler: function( event ) { - var notAsync, result, - saved = dataPriv.get( this, type ); - - if ( ( event.isTrigger & 1 ) && this[ type ] ) { - - // Interrupt processing of the outer synthetic .trigger()ed event - // Saved data should be false in such cases, but might be a leftover capture object - // from an async native handler (gh-4350) - if ( !saved.length ) { - - // Store arguments for use when handling the inner native event - // There will always be at least one argument (an event object), so this array - // will not be confused with a leftover capture object. - saved = slice.call( arguments ); - dataPriv.set( this, type, saved ); - - // Trigger the native event and capture its result - // Support: IE <=9 - 11+ - // focus() and blur() are asynchronous - notAsync = expectSync( this, type ); - this[ type ](); - result = dataPriv.get( this, type ); - if ( saved !== result || notAsync ) { - dataPriv.set( this, type, false ); - } else { - result = {}; - } - if ( saved !== result ) { - - // Cancel the outer synthetic event - event.stopImmediatePropagation(); - event.preventDefault(); - return result.value; - } - - // If this is an inner synthetic event for an event with a bubbling surrogate - // (focus or blur), assume that the surrogate already propagated from triggering the - // native event and prevent that from happening again here. - // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the - // bubbling surrogate propagates *after* the non-bubbling base), but that seems - // less bad than duplication. - } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { - event.stopPropagation(); - } - - // If this is a native event triggered above, everything is now in order - // Fire an inner synthetic event with the original arguments - } else if ( saved.length ) { - - // ...and capture the result - dataPriv.set( this, type, { - value: jQuery.event.trigger( - - // Support: IE <=9 - 11+ - // Extend with the prototype to reset the above stopImmediatePropagation() - jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), - saved.slice( 1 ), - this - ) - } ); - - // Abort handling of the native event - event.stopImmediatePropagation(); - } - } - } ); -} - -jQuery.removeEvent = function( elem, type, handle ) { - - // This "if" is needed for plain objects - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle ); - } -}; - -jQuery.Event = function( src, props ) { - - // Allow instantiation without the 'new' keyword - if ( !( this instanceof jQuery.Event ) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - - // Support: Android <=2.3 only - src.returnValue === false ? - returnTrue : - returnFalse; - - // Create target properties - // Support: Safari <=6 - 7 only - // Target should not be a text node (#504, #13143) - this.target = ( src.target && src.target.nodeType === 3 ) ? - src.target.parentNode : - src.target; - - this.currentTarget = src.currentTarget; - this.relatedTarget = src.relatedTarget; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || Date.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - constructor: jQuery.Event, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - isSimulated: false, - - preventDefault: function() { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - - if ( e && !this.isSimulated ) { - e.preventDefault(); - } - }, - stopPropagation: function() { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - - if ( e && !this.isSimulated ) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function() { - var e = this.originalEvent; - - this.isImmediatePropagationStopped = returnTrue; - - if ( e && !this.isSimulated ) { - e.stopImmediatePropagation(); - } - - this.stopPropagation(); - } -}; - -// Includes all common event props including KeyEvent and MouseEvent specific props -jQuery.each( { - altKey: true, - bubbles: true, - cancelable: true, - changedTouches: true, - ctrlKey: true, - detail: true, - eventPhase: true, - metaKey: true, - pageX: true, - pageY: true, - shiftKey: true, - view: true, - "char": true, - code: true, - charCode: true, - key: true, - keyCode: true, - button: true, - buttons: true, - clientX: true, - clientY: true, - offsetX: true, - offsetY: true, - pointerId: true, - pointerType: true, - screenX: true, - screenY: true, - targetTouches: true, - toElement: true, - touches: true, - - which: function( event ) { - var button = event.button; - - // Add which for key events - if ( event.which == null && rkeyEvent.test( event.type ) ) { - return event.charCode != null ? event.charCode : event.keyCode; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { - if ( button & 1 ) { - return 1; - } - - if ( button & 2 ) { - return 3; - } - - if ( button & 4 ) { - return 2; - } - - return 0; - } - - return event.which; - } -}, jQuery.event.addProp ); - -jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { - jQuery.event.special[ type ] = { - - // Utilize native event if possible so blur/focus sequence is correct - setup: function() { - - // Claim the first handler - // dataPriv.set( this, "focus", ... ) - // dataPriv.set( this, "blur", ... ) - leverageNative( this, type, expectSync ); - - // Return false to allow normal processing in the caller - return false; - }, - trigger: function() { - - // Force setup before trigger - leverageNative( this, type ); - - // Return non-false to allow normal event-path propagation - return true; - }, - - delegateType: delegateType - }; -} ); - -// Create mouseenter/leave events using mouseover/out and event-time checks -// so that event delegation works in jQuery. -// Do the same for pointerenter/pointerleave and pointerover/pointerout -// -// Support: Safari 7 only -// Safari sends mouseenter too often; see: -// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 -// for the description of the bug (it existed in older Chrome versions as well). -jQuery.each( { - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mouseenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -} ); - -jQuery.fn.extend( { - - on: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn ); - }, - one: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? - handleObj.origType + "." + handleObj.namespace : - handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each( function() { - jQuery.event.remove( this, types, fn, selector ); - } ); - } -} ); - - -var - - // Support: IE <=10 - 11, Edge 12 - 13 only - // In IE/Edge using regex groups here causes severe slowdowns. - // See https://connect.microsoft.com/IE/feedback/details/1736512/ - rnoInnerhtml = /\s*$/g; - -// Prefer a tbody over its parent table for containing new rows -function manipulationTarget( elem, content ) { - if ( nodeName( elem, "table" ) && - nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { - - return jQuery( elem ).children( "tbody" )[ 0 ] || elem; - } - - return elem; -} - -// Replace/restore the type attribute of script elements for safe DOM manipulation -function disableScript( elem ) { - elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; - return elem; -} -function restoreScript( elem ) { - if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { - elem.type = elem.type.slice( 5 ); - } else { - elem.removeAttribute( "type" ); - } - - return elem; -} - -function cloneCopyEvent( src, dest ) { - var i, l, type, pdataOld, udataOld, udataCur, events; - - if ( dest.nodeType !== 1 ) { - return; - } - - // 1. Copy private data: events, handlers, etc. - if ( dataPriv.hasData( src ) ) { - pdataOld = dataPriv.get( src ); - events = pdataOld.events; - - if ( events ) { - dataPriv.remove( dest, "handle events" ); - - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } - } - } - } - - // 2. Copy user data - if ( dataUser.hasData( src ) ) { - udataOld = dataUser.access( src ); - udataCur = jQuery.extend( {}, udataOld ); - - dataUser.set( dest, udataCur ); - } -} - -// Fix IE bugs, see support tests -function fixInput( src, dest ) { - var nodeName = dest.nodeName.toLowerCase(); - - // Fails to persist the checked state of a cloned checkbox or radio button. - if ( nodeName === "input" && rcheckableType.test( src.type ) ) { - dest.checked = src.checked; - - // Fails to return the selected option to the default selected state when cloning options - } else if ( nodeName === "input" || nodeName === "textarea" ) { - dest.defaultValue = src.defaultValue; - } -} - -function domManip( collection, args, callback, ignored ) { - - // Flatten any nested arrays - args = flat( args ); - - var fragment, first, scripts, hasScripts, node, doc, - i = 0, - l = collection.length, - iNoClone = l - 1, - value = args[ 0 ], - valueIsFunction = isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( valueIsFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return collection.each( function( index ) { - var self = collection.eq( index ); - if ( valueIsFunction ) { - args[ 0 ] = value.call( this, index, self.html() ); - } - domManip( self, args, callback, ignored ); - } ); - } - - if ( l ) { - fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - // Require either new content or an interest in ignored elements to invoke the callback - if ( first || ignored ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item - // instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( collection[ i ], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Reenable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !dataPriv.access( node, "globalEval" ) && - jQuery.contains( doc, node ) ) { - - if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { - - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl && !node.noModule ) { - jQuery._evalUrl( node.src, { - nonce: node.nonce || node.getAttribute( "nonce" ) - }, doc ); - } - } else { - DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); - } - } - } - } - } - } - - return collection; -} - -function remove( elem, selector, keepData ) { - var node, - nodes = selector ? jQuery.filter( selector, elem ) : elem, - i = 0; - - for ( ; ( node = nodes[ i ] ) != null; i++ ) { - if ( !keepData && node.nodeType === 1 ) { - jQuery.cleanData( getAll( node ) ); - } - - if ( node.parentNode ) { - if ( keepData && isAttached( node ) ) { - setGlobalEval( getAll( node, "script" ) ); - } - node.parentNode.removeChild( node ); - } - } - - return elem; -} - -jQuery.extend( { - htmlPrefilter: function( html ) { - return html; - }, - - clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var i, l, srcElements, destElements, - clone = elem.cloneNode( true ), - inPage = isAttached( elem ); - - // Fix IE cloning issues - if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && - !jQuery.isXMLDoc( elem ) ) { - - // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 - destElements = getAll( clone ); - srcElements = getAll( elem ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - fixInput( srcElements[ i ], destElements[ i ] ); - } - } - - // Copy the events from the original to the clone - if ( dataAndEvents ) { - if ( deepDataAndEvents ) { - srcElements = srcElements || getAll( elem ); - destElements = destElements || getAll( clone ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - cloneCopyEvent( srcElements[ i ], destElements[ i ] ); - } - } else { - cloneCopyEvent( elem, clone ); - } - } - - // Preserve script evaluation history - destElements = getAll( clone, "script" ); - if ( destElements.length > 0 ) { - setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); - } - - // Return the cloned set - return clone; - }, - - cleanData: function( elems ) { - var data, elem, type, - special = jQuery.event.special, - i = 0; - - for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { - if ( acceptData( elem ) ) { - if ( ( data = elem[ dataPriv.expando ] ) ) { - if ( data.events ) { - for ( type in data.events ) { - if ( special[ type ] ) { - jQuery.event.remove( elem, type ); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent( elem, type, data.handle ); - } - } - } - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataPriv.expando ] = undefined; - } - if ( elem[ dataUser.expando ] ) { - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataUser.expando ] = undefined; - } - } - } - } -} ); - -jQuery.fn.extend( { - detach: function( selector ) { - return remove( this, selector, true ); - }, - - remove: function( selector ) { - return remove( this, selector ); - }, - - text: function( value ) { - return access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().each( function() { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - this.textContent = value; - } - } ); - }, null, value, arguments.length ); - }, - - append: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - } ); - }, - - prepend: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); - } - } ); - }, - - before: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); - } - } ); - }, - - after: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - } ); - }, - - empty: function() { - var elem, - i = 0; - - for ( ; ( elem = this[ i ] ) != null; i++ ) { - if ( elem.nodeType === 1 ) { - - // Prevent memory leaks - jQuery.cleanData( getAll( elem, false ) ); - - // Remove any remaining nodes - elem.textContent = ""; - } - } - - return this; - }, - - clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map( function() { - return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - } ); - }, - - html: function( value ) { - return access( this, function( value ) { - var elem = this[ 0 ] || {}, - i = 0, - l = this.length; - - if ( value === undefined && elem.nodeType === 1 ) { - return elem.innerHTML; - } - - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { - - value = jQuery.htmlPrefilter( value ); - - try { - for ( ; i < l; i++ ) { - elem = this[ i ] || {}; - - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch ( e ) {} - } - - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, - - replaceWith: function() { - var ignored = []; - - // Make the changes, replacing each non-ignored context element with the new content - return domManip( this, arguments, function( elem ) { - var parent = this.parentNode; - - if ( jQuery.inArray( this, ignored ) < 0 ) { - jQuery.cleanData( getAll( this ) ); - if ( parent ) { - parent.replaceChild( elem, this ); - } - } - - // Force callback invocation - }, ignored ); - } -} ); - -jQuery.each( { - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1, - i = 0; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone( true ); - jQuery( insert[ i ] )[ original ]( elems ); - - // Support: Android <=4.0 only, PhantomJS 1 only - // .get() because push.apply(_, arraylike) throws on ancient WebKit - push.apply( ret, elems.get() ); - } - - return this.pushStack( ret ); - }; -} ); -var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); - -var getStyles = function( elem ) { - - // Support: IE <=11 only, Firefox <=30 (#15098, #14150) - // IE throws on elements created in popups - // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" - var view = elem.ownerDocument.defaultView; - - if ( !view || !view.opener ) { - view = window; - } - - return view.getComputedStyle( elem ); - }; - -var swap = function( elem, options, callback ) { - var ret, name, - old = {}; - - // Remember the old values, and insert the new ones - for ( name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - ret = callback.call( elem ); - - // Revert the old values - for ( name in options ) { - elem.style[ name ] = old[ name ]; - } - - return ret; -}; - - -var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); - - - -( function() { - - // Executing both pixelPosition & boxSizingReliable tests require only one layout - // so they're executed at the same time to save the second computation. - function computeStyleTests() { - - // This is a singleton, we need to execute it only once - if ( !div ) { - return; - } - - container.style.cssText = "position:absolute;left:-11111px;width:60px;" + - "margin-top:1px;padding:0;border:0"; - div.style.cssText = - "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + - "margin:auto;border:1px;padding:1px;" + - "width:60%;top:1%"; - documentElement.appendChild( container ).appendChild( div ); - - var divStyle = window.getComputedStyle( div ); - pixelPositionVal = divStyle.top !== "1%"; - - // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 - reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; - - // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 - // Some styles come back with percentage values, even though they shouldn't - div.style.right = "60%"; - pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; - - // Support: IE 9 - 11 only - // Detect misreporting of content dimensions for box-sizing:border-box elements - boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; - - // Support: IE 9 only - // Detect overflow:scroll screwiness (gh-3699) - // Support: Chrome <=64 - // Don't get tricked when zoom affects offsetWidth (gh-4029) - div.style.position = "absolute"; - scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; - - documentElement.removeChild( container ); - - // Nullify the div so it wouldn't be stored in the memory and - // it will also be a sign that checks already performed - div = null; - } - - function roundPixelMeasures( measure ) { - return Math.round( parseFloat( measure ) ); - } - - var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, - reliableTrDimensionsVal, reliableMarginLeftVal, - container = document.createElement( "div" ), - div = document.createElement( "div" ); - - // Finish early in limited (non-browser) environments - if ( !div.style ) { - return; - } - - // Support: IE <=9 - 11 only - // Style of cloned element affects source element cloned (#8908) - div.style.backgroundClip = "content-box"; - div.cloneNode( true ).style.backgroundClip = ""; - support.clearCloneStyle = div.style.backgroundClip === "content-box"; - - jQuery.extend( support, { - boxSizingReliable: function() { - computeStyleTests(); - return boxSizingReliableVal; - }, - pixelBoxStyles: function() { - computeStyleTests(); - return pixelBoxStylesVal; - }, - pixelPosition: function() { - computeStyleTests(); - return pixelPositionVal; - }, - reliableMarginLeft: function() { - computeStyleTests(); - return reliableMarginLeftVal; - }, - scrollboxSize: function() { - computeStyleTests(); - return scrollboxSizeVal; - }, - - // Support: IE 9 - 11+, Edge 15 - 18+ - // IE/Edge misreport `getComputedStyle` of table rows with width/height - // set in CSS while `offset*` properties report correct values. - // Behavior in IE 9 is more subtle than in newer versions & it passes - // some versions of this test; make sure not to make it pass there! - reliableTrDimensions: function() { - var table, tr, trChild, trStyle; - if ( reliableTrDimensionsVal == null ) { - table = document.createElement( "table" ); - tr = document.createElement( "tr" ); - trChild = document.createElement( "div" ); - - table.style.cssText = "position:absolute;left:-11111px"; - tr.style.height = "1px"; - trChild.style.height = "9px"; - - documentElement - .appendChild( table ) - .appendChild( tr ) - .appendChild( trChild ); - - trStyle = window.getComputedStyle( tr ); - reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; - - documentElement.removeChild( table ); - } - return reliableTrDimensionsVal; - } - } ); -} )(); - - -function curCSS( elem, name, computed ) { - var width, minWidth, maxWidth, ret, - - // Support: Firefox 51+ - // Retrieving style before computed somehow - // fixes an issue with getting wrong values - // on detached elements - style = elem.style; - - computed = computed || getStyles( elem ); - - // getPropertyValue is needed for: - // .css('filter') (IE 9 only, #12537) - // .css('--customProperty) (#3144) - if ( computed ) { - ret = computed.getPropertyValue( name ) || computed[ name ]; - - if ( ret === "" && !isAttached( elem ) ) { - ret = jQuery.style( elem, name ); - } - - // A tribute to the "awesome hack by Dean Edwards" - // Android Browser returns percentage for some values, - // but width seems to be reliably pixels. - // This is against the CSSOM draft spec: - // https://drafts.csswg.org/cssom/#resolved-values - if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { - - // Remember the original values - width = style.width; - minWidth = style.minWidth; - maxWidth = style.maxWidth; - - // Put in the new values to get a computed value out - style.minWidth = style.maxWidth = style.width = ret; - ret = computed.width; - - // Revert the changed values - style.width = width; - style.minWidth = minWidth; - style.maxWidth = maxWidth; - } - } - - return ret !== undefined ? - - // Support: IE <=9 - 11 only - // IE returns zIndex value as an integer. - ret + "" : - ret; -} - - -function addGetHookIf( conditionFn, hookFn ) { - - // Define the hook, we'll check on the first run if it's really needed. - return { - get: function() { - if ( conditionFn() ) { - - // Hook not needed (or it's not possible to use it due - // to missing dependency), remove it. - delete this.get; - return; - } - - // Hook needed; redefine it so that the support test is not executed again. - return ( this.get = hookFn ).apply( this, arguments ); - } - }; -} - - -var cssPrefixes = [ "Webkit", "Moz", "ms" ], - emptyStyle = document.createElement( "div" ).style, - vendorProps = {}; - -// Return a vendor-prefixed property or undefined -function vendorPropName( name ) { - - // Check for vendor prefixed names - var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), - i = cssPrefixes.length; - - while ( i-- ) { - name = cssPrefixes[ i ] + capName; - if ( name in emptyStyle ) { - return name; - } - } -} - -// Return a potentially-mapped jQuery.cssProps or vendor prefixed property -function finalPropName( name ) { - var final = jQuery.cssProps[ name ] || vendorProps[ name ]; - - if ( final ) { - return final; - } - if ( name in emptyStyle ) { - return name; - } - return vendorProps[ name ] = vendorPropName( name ) || name; -} - - -var - - // Swappable if display is none or starts with table - // except "table", "table-cell", or "table-caption" - // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display - rdisplayswap = /^(none|table(?!-c[ea]).+)/, - rcustomProp = /^--/, - cssShow = { position: "absolute", visibility: "hidden", display: "block" }, - cssNormalTransform = { - letterSpacing: "0", - fontWeight: "400" - }; - -function setPositiveNumber( _elem, value, subtract ) { - - // Any relative (+/-) values have already been - // normalized at this point - var matches = rcssNum.exec( value ); - return matches ? - - // Guard against undefined "subtract", e.g., when used as in cssHooks - Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : - value; -} - -function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { - var i = dimension === "width" ? 1 : 0, - extra = 0, - delta = 0; - - // Adjustment may not be necessary - if ( box === ( isBorderBox ? "border" : "content" ) ) { - return 0; - } - - for ( ; i < 4; i += 2 ) { - - // Both box models exclude margin - if ( box === "margin" ) { - delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); - } - - // If we get here with a content-box, we're seeking "padding" or "border" or "margin" - if ( !isBorderBox ) { - - // Add padding - delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - - // For "border" or "margin", add border - if ( box !== "padding" ) { - delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - - // But still keep track of it otherwise - } else { - extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - - // If we get here with a border-box (content + padding + border), we're seeking "content" or - // "padding" or "margin" - } else { - - // For "content", subtract padding - if ( box === "content" ) { - delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - } - - // For "content" or "padding", subtract border - if ( box !== "margin" ) { - delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - } - } - - // Account for positive content-box scroll gutter when requested by providing computedVal - if ( !isBorderBox && computedVal >= 0 ) { - - // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border - // Assuming integer scroll gutter, subtract the rest and round down - delta += Math.max( 0, Math.ceil( - elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - - computedVal - - delta - - extra - - 0.5 - - // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter - // Use an explicit zero to avoid NaN (gh-3964) - ) ) || 0; - } - - return delta; -} - -function getWidthOrHeight( elem, dimension, extra ) { - - // Start with computed style - var styles = getStyles( elem ), - - // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). - // Fake content-box until we know it's needed to know the true value. - boxSizingNeeded = !support.boxSizingReliable() || extra, - isBorderBox = boxSizingNeeded && - jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - valueIsBorderBox = isBorderBox, - - val = curCSS( elem, dimension, styles ), - offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); - - // Support: Firefox <=54 - // Return a confounding non-pixel value or feign ignorance, as appropriate. - if ( rnumnonpx.test( val ) ) { - if ( !extra ) { - return val; - } - val = "auto"; - } - - - // Support: IE 9 - 11 only - // Use offsetWidth/offsetHeight for when box sizing is unreliable. - // In those cases, the computed value can be trusted to be border-box. - if ( ( !support.boxSizingReliable() && isBorderBox || - - // Support: IE 10 - 11+, Edge 15 - 18+ - // IE/Edge misreport `getComputedStyle` of table rows with width/height - // set in CSS while `offset*` properties report correct values. - // Interestingly, in some cases IE 9 doesn't suffer from this issue. - !support.reliableTrDimensions() && nodeName( elem, "tr" ) || - - // Fall back to offsetWidth/offsetHeight when value is "auto" - // This happens for inline elements with no explicit setting (gh-3571) - val === "auto" || - - // Support: Android <=4.1 - 4.3 only - // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) - !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && - - // Make sure the element is visible & connected - elem.getClientRects().length ) { - - isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; - - // Where available, offsetWidth/offsetHeight approximate border box dimensions. - // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the - // retrieved value as a content box dimension. - valueIsBorderBox = offsetProp in elem; - if ( valueIsBorderBox ) { - val = elem[ offsetProp ]; - } - } - - // Normalize "" and auto - val = parseFloat( val ) || 0; - - // Adjust for the element's box model - return ( val + - boxModelAdjustment( - elem, - dimension, - extra || ( isBorderBox ? "border" : "content" ), - valueIsBorderBox, - styles, - - // Provide the current computed size to request scroll gutter calculation (gh-3589) - val - ) - ) + "px"; -} - -jQuery.extend( { - - // Add in style property hooks for overriding the default - // behavior of getting and setting a style property - cssHooks: { - opacity: { - get: function( elem, computed ) { - if ( computed ) { - - // We should always get a number back from opacity - var ret = curCSS( elem, "opacity" ); - return ret === "" ? "1" : ret; - } - } - } - }, - - // Don't automatically add "px" to these possibly-unitless properties - cssNumber: { - "animationIterationCount": true, - "columnCount": true, - "fillOpacity": true, - "flexGrow": true, - "flexShrink": true, - "fontWeight": true, - "gridArea": true, - "gridColumn": true, - "gridColumnEnd": true, - "gridColumnStart": true, - "gridRow": true, - "gridRowEnd": true, - "gridRowStart": true, - "lineHeight": true, - "opacity": true, - "order": true, - "orphans": true, - "widows": true, - "zIndex": true, - "zoom": true - }, - - // Add in properties whose names you wish to fix before - // setting or getting the value - cssProps: {}, - - // Get and set the style property on a DOM Node - style: function( elem, name, value, extra ) { - - // Don't set styles on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { - return; - } - - // Make sure that we're working with the right name - var ret, type, hooks, - origName = camelCase( name ), - isCustomProp = rcustomProp.test( name ), - style = elem.style; - - // Make sure that we're working with the right name. We don't - // want to query the value if it is a CSS custom property - // since they are user-defined. - if ( !isCustomProp ) { - name = finalPropName( origName ); - } - - // Gets hook for the prefixed version, then unprefixed version - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // Check if we're setting a value - if ( value !== undefined ) { - type = typeof value; - - // Convert "+=" or "-=" to relative numbers (#7345) - if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { - value = adjustCSS( elem, name, ret ); - - // Fixes bug #9237 - type = "number"; - } - - // Make sure that null and NaN values aren't set (#7116) - if ( value == null || value !== value ) { - return; - } - - // If a number was passed in, add the unit (except for certain CSS properties) - // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append - // "px" to a few hardcoded values. - if ( type === "number" && !isCustomProp ) { - value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); - } - - // background-* props affect original clone's values - if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { - style[ name ] = "inherit"; - } - - // If a hook was provided, use that value, otherwise just set the specified value - if ( !hooks || !( "set" in hooks ) || - ( value = hooks.set( elem, value, extra ) ) !== undefined ) { - - if ( isCustomProp ) { - style.setProperty( name, value ); - } else { - style[ name ] = value; - } - } - - } else { - - // If a hook was provided get the non-computed value from there - if ( hooks && "get" in hooks && - ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { - - return ret; - } - - // Otherwise just get the value from the style object - return style[ name ]; - } - }, - - css: function( elem, name, extra, styles ) { - var val, num, hooks, - origName = camelCase( name ), - isCustomProp = rcustomProp.test( name ); - - // Make sure that we're working with the right name. We don't - // want to modify the value if it is a CSS custom property - // since they are user-defined. - if ( !isCustomProp ) { - name = finalPropName( origName ); - } - - // Try prefixed name followed by the unprefixed name - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // If a hook was provided get the computed value from there - if ( hooks && "get" in hooks ) { - val = hooks.get( elem, true, extra ); - } - - // Otherwise, if a way to get the computed value exists, use that - if ( val === undefined ) { - val = curCSS( elem, name, styles ); - } - - // Convert "normal" to computed value - if ( val === "normal" && name in cssNormalTransform ) { - val = cssNormalTransform[ name ]; - } - - // Make numeric if forced or a qualifier was provided and val looks numeric - if ( extra === "" || extra ) { - num = parseFloat( val ); - return extra === true || isFinite( num ) ? num || 0 : val; - } - - return val; - } -} ); - -jQuery.each( [ "height", "width" ], function( _i, dimension ) { - jQuery.cssHooks[ dimension ] = { - get: function( elem, computed, extra ) { - if ( computed ) { - - // Certain elements can have dimension info if we invisibly show them - // but it must have a current display style that would benefit - return rdisplayswap.test( jQuery.css( elem, "display" ) ) && - - // Support: Safari 8+ - // Table columns in Safari have non-zero offsetWidth & zero - // getBoundingClientRect().width unless display is changed. - // Support: IE <=11 only - // Running getBoundingClientRect on a disconnected node - // in IE throws an error. - ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? - swap( elem, cssShow, function() { - return getWidthOrHeight( elem, dimension, extra ); - } ) : - getWidthOrHeight( elem, dimension, extra ); - } - }, - - set: function( elem, value, extra ) { - var matches, - styles = getStyles( elem ), - - // Only read styles.position if the test has a chance to fail - // to avoid forcing a reflow. - scrollboxSizeBuggy = !support.scrollboxSize() && - styles.position === "absolute", - - // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) - boxSizingNeeded = scrollboxSizeBuggy || extra, - isBorderBox = boxSizingNeeded && - jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - subtract = extra ? - boxModelAdjustment( - elem, - dimension, - extra, - isBorderBox, - styles - ) : - 0; - - // Account for unreliable border-box dimensions by comparing offset* to computed and - // faking a content-box to get border and padding (gh-3699) - if ( isBorderBox && scrollboxSizeBuggy ) { - subtract -= Math.ceil( - elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - - parseFloat( styles[ dimension ] ) - - boxModelAdjustment( elem, dimension, "border", false, styles ) - - 0.5 - ); - } - - // Convert to pixels if value adjustment is needed - if ( subtract && ( matches = rcssNum.exec( value ) ) && - ( matches[ 3 ] || "px" ) !== "px" ) { - - elem.style[ dimension ] = value; - value = jQuery.css( elem, dimension ); - } - - return setPositiveNumber( elem, value, subtract ); - } - }; -} ); - -jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, - function( elem, computed ) { - if ( computed ) { - return ( parseFloat( curCSS( elem, "marginLeft" ) ) || - elem.getBoundingClientRect().left - - swap( elem, { marginLeft: 0 }, function() { - return elem.getBoundingClientRect().left; - } ) - ) + "px"; - } - } -); - -// These hooks are used by animate to expand properties -jQuery.each( { - margin: "", - padding: "", - border: "Width" -}, function( prefix, suffix ) { - jQuery.cssHooks[ prefix + suffix ] = { - expand: function( value ) { - var i = 0, - expanded = {}, - - // Assumes a single number if not a string - parts = typeof value === "string" ? value.split( " " ) : [ value ]; - - for ( ; i < 4; i++ ) { - expanded[ prefix + cssExpand[ i ] + suffix ] = - parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; - } - - return expanded; - } - }; - - if ( prefix !== "margin" ) { - jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; - } -} ); - -jQuery.fn.extend( { - css: function( name, value ) { - return access( this, function( elem, name, value ) { - var styles, len, - map = {}, - i = 0; - - if ( Array.isArray( name ) ) { - styles = getStyles( elem ); - len = name.length; - - for ( ; i < len; i++ ) { - map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); - } - - return map; - } - - return value !== undefined ? - jQuery.style( elem, name, value ) : - jQuery.css( elem, name ); - }, name, value, arguments.length > 1 ); - } -} ); - - -function Tween( elem, options, prop, end, easing ) { - return new Tween.prototype.init( elem, options, prop, end, easing ); -} -jQuery.Tween = Tween; - -Tween.prototype = { - constructor: Tween, - init: function( elem, options, prop, end, easing, unit ) { - this.elem = elem; - this.prop = prop; - this.easing = easing || jQuery.easing._default; - this.options = options; - this.start = this.now = this.cur(); - this.end = end; - this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); - }, - cur: function() { - var hooks = Tween.propHooks[ this.prop ]; - - return hooks && hooks.get ? - hooks.get( this ) : - Tween.propHooks._default.get( this ); - }, - run: function( percent ) { - var eased, - hooks = Tween.propHooks[ this.prop ]; - - if ( this.options.duration ) { - this.pos = eased = jQuery.easing[ this.easing ]( - percent, this.options.duration * percent, 0, 1, this.options.duration - ); - } else { - this.pos = eased = percent; - } - this.now = ( this.end - this.start ) * eased + this.start; - - if ( this.options.step ) { - this.options.step.call( this.elem, this.now, this ); - } - - if ( hooks && hooks.set ) { - hooks.set( this ); - } else { - Tween.propHooks._default.set( this ); - } - return this; - } -}; - -Tween.prototype.init.prototype = Tween.prototype; - -Tween.propHooks = { - _default: { - get: function( tween ) { - var result; - - // Use a property on the element directly when it is not a DOM element, - // or when there is no matching style property that exists. - if ( tween.elem.nodeType !== 1 || - tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { - return tween.elem[ tween.prop ]; - } - - // Passing an empty string as a 3rd parameter to .css will automatically - // attempt a parseFloat and fallback to a string if the parse fails. - // Simple values such as "10px" are parsed to Float; - // complex values such as "rotate(1rad)" are returned as-is. - result = jQuery.css( tween.elem, tween.prop, "" ); - - // Empty strings, null, undefined and "auto" are converted to 0. - return !result || result === "auto" ? 0 : result; - }, - set: function( tween ) { - - // Use step hook for back compat. - // Use cssHook if its there. - // Use .style if available and use plain properties where available. - if ( jQuery.fx.step[ tween.prop ] ) { - jQuery.fx.step[ tween.prop ]( tween ); - } else if ( tween.elem.nodeType === 1 && ( - jQuery.cssHooks[ tween.prop ] || - tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { - jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); - } else { - tween.elem[ tween.prop ] = tween.now; - } - } - } -}; - -// Support: IE <=9 only -// Panic based approach to setting things on disconnected nodes -Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { - set: function( tween ) { - if ( tween.elem.nodeType && tween.elem.parentNode ) { - tween.elem[ tween.prop ] = tween.now; - } - } -}; - -jQuery.easing = { - linear: function( p ) { - return p; - }, - swing: function( p ) { - return 0.5 - Math.cos( p * Math.PI ) / 2; - }, - _default: "swing" -}; - -jQuery.fx = Tween.prototype.init; - -// Back compat <1.8 extension point -jQuery.fx.step = {}; - - - - -var - fxNow, inProgress, - rfxtypes = /^(?:toggle|show|hide)$/, - rrun = /queueHooks$/; - -function schedule() { - if ( inProgress ) { - if ( document.hidden === false && window.requestAnimationFrame ) { - window.requestAnimationFrame( schedule ); - } else { - window.setTimeout( schedule, jQuery.fx.interval ); - } - - jQuery.fx.tick(); - } -} - -// Animations created synchronously will run synchronously -function createFxNow() { - window.setTimeout( function() { - fxNow = undefined; - } ); - return ( fxNow = Date.now() ); -} - -// Generate parameters to create a standard animation -function genFx( type, includeWidth ) { - var which, - i = 0, - attrs = { height: type }; - - // If we include width, step value is 1 to do all cssExpand values, - // otherwise step value is 2 to skip over Left and Right - includeWidth = includeWidth ? 1 : 0; - for ( ; i < 4; i += 2 - includeWidth ) { - which = cssExpand[ i ]; - attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; - } - - if ( includeWidth ) { - attrs.opacity = attrs.width = type; - } - - return attrs; -} - -function createTween( value, prop, animation ) { - var tween, - collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), - index = 0, - length = collection.length; - for ( ; index < length; index++ ) { - if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { - - // We're done with this property - return tween; - } - } -} - -function defaultPrefilter( elem, props, opts ) { - var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, - isBox = "width" in props || "height" in props, - anim = this, - orig = {}, - style = elem.style, - hidden = elem.nodeType && isHiddenWithinTree( elem ), - dataShow = dataPriv.get( elem, "fxshow" ); - - // Queue-skipping animations hijack the fx hooks - if ( !opts.queue ) { - hooks = jQuery._queueHooks( elem, "fx" ); - if ( hooks.unqueued == null ) { - hooks.unqueued = 0; - oldfire = hooks.empty.fire; - hooks.empty.fire = function() { - if ( !hooks.unqueued ) { - oldfire(); - } - }; - } - hooks.unqueued++; - - anim.always( function() { - - // Ensure the complete handler is called before this completes - anim.always( function() { - hooks.unqueued--; - if ( !jQuery.queue( elem, "fx" ).length ) { - hooks.empty.fire(); - } - } ); - } ); - } - - // Detect show/hide animations - for ( prop in props ) { - value = props[ prop ]; - if ( rfxtypes.test( value ) ) { - delete props[ prop ]; - toggle = toggle || value === "toggle"; - if ( value === ( hidden ? "hide" : "show" ) ) { - - // Pretend to be hidden if this is a "show" and - // there is still data from a stopped show/hide - if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { - hidden = true; - - // Ignore all other no-op show/hide data - } else { - continue; - } - } - orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); - } - } - - // Bail out if this is a no-op like .hide().hide() - propTween = !jQuery.isEmptyObject( props ); - if ( !propTween && jQuery.isEmptyObject( orig ) ) { - return; - } - - // Restrict "overflow" and "display" styles during box animations - if ( isBox && elem.nodeType === 1 ) { - - // Support: IE <=9 - 11, Edge 12 - 15 - // Record all 3 overflow attributes because IE does not infer the shorthand - // from identically-valued overflowX and overflowY and Edge just mirrors - // the overflowX value there. - opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; - - // Identify a display type, preferring old show/hide data over the CSS cascade - restoreDisplay = dataShow && dataShow.display; - if ( restoreDisplay == null ) { - restoreDisplay = dataPriv.get( elem, "display" ); - } - display = jQuery.css( elem, "display" ); - if ( display === "none" ) { - if ( restoreDisplay ) { - display = restoreDisplay; - } else { - - // Get nonempty value(s) by temporarily forcing visibility - showHide( [ elem ], true ); - restoreDisplay = elem.style.display || restoreDisplay; - display = jQuery.css( elem, "display" ); - showHide( [ elem ] ); - } - } - - // Animate inline elements as inline-block - if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { - if ( jQuery.css( elem, "float" ) === "none" ) { - - // Restore the original display value at the end of pure show/hide animations - if ( !propTween ) { - anim.done( function() { - style.display = restoreDisplay; - } ); - if ( restoreDisplay == null ) { - display = style.display; - restoreDisplay = display === "none" ? "" : display; - } - } - style.display = "inline-block"; - } - } - } - - if ( opts.overflow ) { - style.overflow = "hidden"; - anim.always( function() { - style.overflow = opts.overflow[ 0 ]; - style.overflowX = opts.overflow[ 1 ]; - style.overflowY = opts.overflow[ 2 ]; - } ); - } - - // Implement show/hide animations - propTween = false; - for ( prop in orig ) { - - // General show/hide setup for this element animation - if ( !propTween ) { - if ( dataShow ) { - if ( "hidden" in dataShow ) { - hidden = dataShow.hidden; - } - } else { - dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); - } - - // Store hidden/visible for toggle so `.stop().toggle()` "reverses" - if ( toggle ) { - dataShow.hidden = !hidden; - } - - // Show elements before animating them - if ( hidden ) { - showHide( [ elem ], true ); - } - - /* eslint-disable no-loop-func */ - - anim.done( function() { - - /* eslint-enable no-loop-func */ - - // The final step of a "hide" animation is actually hiding the element - if ( !hidden ) { - showHide( [ elem ] ); - } - dataPriv.remove( elem, "fxshow" ); - for ( prop in orig ) { - jQuery.style( elem, prop, orig[ prop ] ); - } - } ); - } - - // Per-property setup - propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); - if ( !( prop in dataShow ) ) { - dataShow[ prop ] = propTween.start; - if ( hidden ) { - propTween.end = propTween.start; - propTween.start = 0; - } - } - } -} - -function propFilter( props, specialEasing ) { - var index, name, easing, value, hooks; - - // camelCase, specialEasing and expand cssHook pass - for ( index in props ) { - name = camelCase( index ); - easing = specialEasing[ name ]; - value = props[ index ]; - if ( Array.isArray( value ) ) { - easing = value[ 1 ]; - value = props[ index ] = value[ 0 ]; - } - - if ( index !== name ) { - props[ name ] = value; - delete props[ index ]; - } - - hooks = jQuery.cssHooks[ name ]; - if ( hooks && "expand" in hooks ) { - value = hooks.expand( value ); - delete props[ name ]; - - // Not quite $.extend, this won't overwrite existing keys. - // Reusing 'index' because we have the correct "name" - for ( index in value ) { - if ( !( index in props ) ) { - props[ index ] = value[ index ]; - specialEasing[ index ] = easing; - } - } - } else { - specialEasing[ name ] = easing; - } - } -} - -function Animation( elem, properties, options ) { - var result, - stopped, - index = 0, - length = Animation.prefilters.length, - deferred = jQuery.Deferred().always( function() { - - // Don't match elem in the :animated selector - delete tick.elem; - } ), - tick = function() { - if ( stopped ) { - return false; - } - var currentTime = fxNow || createFxNow(), - remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), - - // Support: Android 2.3 only - // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) - temp = remaining / animation.duration || 0, - percent = 1 - temp, - index = 0, - length = animation.tweens.length; - - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( percent ); - } - - deferred.notifyWith( elem, [ animation, percent, remaining ] ); - - // If there's more to do, yield - if ( percent < 1 && length ) { - return remaining; - } - - // If this was an empty animation, synthesize a final progress notification - if ( !length ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); - } - - // Resolve the animation and report its conclusion - deferred.resolveWith( elem, [ animation ] ); - return false; - }, - animation = deferred.promise( { - elem: elem, - props: jQuery.extend( {}, properties ), - opts: jQuery.extend( true, { - specialEasing: {}, - easing: jQuery.easing._default - }, options ), - originalProperties: properties, - originalOptions: options, - startTime: fxNow || createFxNow(), - duration: options.duration, - tweens: [], - createTween: function( prop, end ) { - var tween = jQuery.Tween( elem, animation.opts, prop, end, - animation.opts.specialEasing[ prop ] || animation.opts.easing ); - animation.tweens.push( tween ); - return tween; - }, - stop: function( gotoEnd ) { - var index = 0, - - // If we are going to the end, we want to run all the tweens - // otherwise we skip this part - length = gotoEnd ? animation.tweens.length : 0; - if ( stopped ) { - return this; - } - stopped = true; - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( 1 ); - } - - // Resolve when we played the last frame; otherwise, reject - if ( gotoEnd ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); - deferred.resolveWith( elem, [ animation, gotoEnd ] ); - } else { - deferred.rejectWith( elem, [ animation, gotoEnd ] ); - } - return this; - } - } ), - props = animation.props; - - propFilter( props, animation.opts.specialEasing ); - - for ( ; index < length; index++ ) { - result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); - if ( result ) { - if ( isFunction( result.stop ) ) { - jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = - result.stop.bind( result ); - } - return result; - } - } - - jQuery.map( props, createTween, animation ); - - if ( isFunction( animation.opts.start ) ) { - animation.opts.start.call( elem, animation ); - } - - // Attach callbacks from options - animation - .progress( animation.opts.progress ) - .done( animation.opts.done, animation.opts.complete ) - .fail( animation.opts.fail ) - .always( animation.opts.always ); - - jQuery.fx.timer( - jQuery.extend( tick, { - elem: elem, - anim: animation, - queue: animation.opts.queue - } ) - ); - - return animation; -} - -jQuery.Animation = jQuery.extend( Animation, { - - tweeners: { - "*": [ function( prop, value ) { - var tween = this.createTween( prop, value ); - adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); - return tween; - } ] - }, - - tweener: function( props, callback ) { - if ( isFunction( props ) ) { - callback = props; - props = [ "*" ]; - } else { - props = props.match( rnothtmlwhite ); - } - - var prop, - index = 0, - length = props.length; - - for ( ; index < length; index++ ) { - prop = props[ index ]; - Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; - Animation.tweeners[ prop ].unshift( callback ); - } - }, - - prefilters: [ defaultPrefilter ], - - prefilter: function( callback, prepend ) { - if ( prepend ) { - Animation.prefilters.unshift( callback ); - } else { - Animation.prefilters.push( callback ); - } - } -} ); - -jQuery.speed = function( speed, easing, fn ) { - var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { - complete: fn || !fn && easing || - isFunction( speed ) && speed, - duration: speed, - easing: fn && easing || easing && !isFunction( easing ) && easing - }; - - // Go to the end state if fx are off - if ( jQuery.fx.off ) { - opt.duration = 0; - - } else { - if ( typeof opt.duration !== "number" ) { - if ( opt.duration in jQuery.fx.speeds ) { - opt.duration = jQuery.fx.speeds[ opt.duration ]; - - } else { - opt.duration = jQuery.fx.speeds._default; - } - } - } - - // Normalize opt.queue - true/undefined/null -> "fx" - if ( opt.queue == null || opt.queue === true ) { - opt.queue = "fx"; - } - - // Queueing - opt.old = opt.complete; - - opt.complete = function() { - if ( isFunction( opt.old ) ) { - opt.old.call( this ); - } - - if ( opt.queue ) { - jQuery.dequeue( this, opt.queue ); - } - }; - - return opt; -}; - -jQuery.fn.extend( { - fadeTo: function( speed, to, easing, callback ) { - - // Show any hidden elements after setting opacity to 0 - return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() - - // Animate to the value specified - .end().animate( { opacity: to }, speed, easing, callback ); - }, - animate: function( prop, speed, easing, callback ) { - var empty = jQuery.isEmptyObject( prop ), - optall = jQuery.speed( speed, easing, callback ), - doAnimation = function() { - - // Operate on a copy of prop so per-property easing won't be lost - var anim = Animation( this, jQuery.extend( {}, prop ), optall ); - - // Empty animations, or finishing resolves immediately - if ( empty || dataPriv.get( this, "finish" ) ) { - anim.stop( true ); - } - }; - doAnimation.finish = doAnimation; - - return empty || optall.queue === false ? - this.each( doAnimation ) : - this.queue( optall.queue, doAnimation ); - }, - stop: function( type, clearQueue, gotoEnd ) { - var stopQueue = function( hooks ) { - var stop = hooks.stop; - delete hooks.stop; - stop( gotoEnd ); - }; - - if ( typeof type !== "string" ) { - gotoEnd = clearQueue; - clearQueue = type; - type = undefined; - } - if ( clearQueue ) { - this.queue( type || "fx", [] ); - } - - return this.each( function() { - var dequeue = true, - index = type != null && type + "queueHooks", - timers = jQuery.timers, - data = dataPriv.get( this ); - - if ( index ) { - if ( data[ index ] && data[ index ].stop ) { - stopQueue( data[ index ] ); - } - } else { - for ( index in data ) { - if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { - stopQueue( data[ index ] ); - } - } - } - - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && - ( type == null || timers[ index ].queue === type ) ) { - - timers[ index ].anim.stop( gotoEnd ); - dequeue = false; - timers.splice( index, 1 ); - } - } - - // Start the next in the queue if the last step wasn't forced. - // Timers currently will call their complete callbacks, which - // will dequeue but only if they were gotoEnd. - if ( dequeue || !gotoEnd ) { - jQuery.dequeue( this, type ); - } - } ); - }, - finish: function( type ) { - if ( type !== false ) { - type = type || "fx"; - } - return this.each( function() { - var index, - data = dataPriv.get( this ), - queue = data[ type + "queue" ], - hooks = data[ type + "queueHooks" ], - timers = jQuery.timers, - length = queue ? queue.length : 0; - - // Enable finishing flag on private data - data.finish = true; - - // Empty the queue first - jQuery.queue( this, type, [] ); - - if ( hooks && hooks.stop ) { - hooks.stop.call( this, true ); - } - - // Look for any active animations, and finish them - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && timers[ index ].queue === type ) { - timers[ index ].anim.stop( true ); - timers.splice( index, 1 ); - } - } - - // Look for any animations in the old queue and finish them - for ( index = 0; index < length; index++ ) { - if ( queue[ index ] && queue[ index ].finish ) { - queue[ index ].finish.call( this ); - } - } - - // Turn off finishing flag - delete data.finish; - } ); - } -} ); - -jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { - var cssFn = jQuery.fn[ name ]; - jQuery.fn[ name ] = function( speed, easing, callback ) { - return speed == null || typeof speed === "boolean" ? - cssFn.apply( this, arguments ) : - this.animate( genFx( name, true ), speed, easing, callback ); - }; -} ); - -// Generate shortcuts for custom animations -jQuery.each( { - slideDown: genFx( "show" ), - slideUp: genFx( "hide" ), - slideToggle: genFx( "toggle" ), - fadeIn: { opacity: "show" }, - fadeOut: { opacity: "hide" }, - fadeToggle: { opacity: "toggle" } -}, function( name, props ) { - jQuery.fn[ name ] = function( speed, easing, callback ) { - return this.animate( props, speed, easing, callback ); - }; -} ); - -jQuery.timers = []; -jQuery.fx.tick = function() { - var timer, - i = 0, - timers = jQuery.timers; - - fxNow = Date.now(); - - for ( ; i < timers.length; i++ ) { - timer = timers[ i ]; - - // Run the timer and safely remove it when done (allowing for external removal) - if ( !timer() && timers[ i ] === timer ) { - timers.splice( i--, 1 ); - } - } - - if ( !timers.length ) { - jQuery.fx.stop(); - } - fxNow = undefined; -}; - -jQuery.fx.timer = function( timer ) { - jQuery.timers.push( timer ); - jQuery.fx.start(); -}; - -jQuery.fx.interval = 13; -jQuery.fx.start = function() { - if ( inProgress ) { - return; - } - - inProgress = true; - schedule(); -}; - -jQuery.fx.stop = function() { - inProgress = null; -}; - -jQuery.fx.speeds = { - slow: 600, - fast: 200, - - // Default speed - _default: 400 -}; - - -// Based off of the plugin by Clint Helfers, with permission. -// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ -jQuery.fn.delay = function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; - type = type || "fx"; - - return this.queue( type, function( next, hooks ) { - var timeout = window.setTimeout( next, time ); - hooks.stop = function() { - window.clearTimeout( timeout ); - }; - } ); -}; - - -( function() { - var input = document.createElement( "input" ), - select = document.createElement( "select" ), - opt = select.appendChild( document.createElement( "option" ) ); - - input.type = "checkbox"; - - // Support: Android <=4.3 only - // Default value for a checkbox should be "on" - support.checkOn = input.value !== ""; - - // Support: IE <=11 only - // Must access selectedIndex to make default options select - support.optSelected = opt.selected; - - // Support: IE <=11 only - // An input loses its value after becoming a radio - input = document.createElement( "input" ); - input.value = "t"; - input.type = "radio"; - support.radioValue = input.value === "t"; -} )(); - - -var boolHook, - attrHandle = jQuery.expr.attrHandle; - -jQuery.fn.extend( { - attr: function( name, value ) { - return access( this, jQuery.attr, name, value, arguments.length > 1 ); - }, - - removeAttr: function( name ) { - return this.each( function() { - jQuery.removeAttr( this, name ); - } ); - } -} ); - -jQuery.extend( { - attr: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set attributes on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === "undefined" ) { - return jQuery.prop( elem, name, value ); - } - - // Attribute hooks are determined by the lowercase version - // Grab necessary hook if one is defined - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - hooks = jQuery.attrHooks[ name.toLowerCase() ] || - ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); - } - - if ( value !== undefined ) { - if ( value === null ) { - jQuery.removeAttr( elem, name ); - return; - } - - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } - - elem.setAttribute( name, value + "" ); - return value; - } - - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } - - ret = jQuery.find.attr( elem, name ); - - // Non-existent attributes return null, we normalize to undefined - return ret == null ? undefined : ret; - }, - - attrHooks: { - type: { - set: function( elem, value ) { - if ( !support.radioValue && value === "radio" && - nodeName( elem, "input" ) ) { - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - } - }, - - removeAttr: function( elem, value ) { - var name, - i = 0, - - // Attribute names can contain non-HTML whitespace characters - // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 - attrNames = value && value.match( rnothtmlwhite ); - - if ( attrNames && elem.nodeType === 1 ) { - while ( ( name = attrNames[ i++ ] ) ) { - elem.removeAttribute( name ); - } - } - } -} ); - -// Hooks for boolean attributes -boolHook = { - set: function( elem, value, name ) { - if ( value === false ) { - - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else { - elem.setAttribute( name, name ); - } - return name; - } -}; - -jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { - var getter = attrHandle[ name ] || jQuery.find.attr; - - attrHandle[ name ] = function( elem, name, isXML ) { - var ret, handle, - lowercaseName = name.toLowerCase(); - - if ( !isXML ) { - - // Avoid an infinite loop by temporarily removing this function from the getter - handle = attrHandle[ lowercaseName ]; - attrHandle[ lowercaseName ] = ret; - ret = getter( elem, name, isXML ) != null ? - lowercaseName : - null; - attrHandle[ lowercaseName ] = handle; - } - return ret; - }; -} ); - - - - -var rfocusable = /^(?:input|select|textarea|button)$/i, - rclickable = /^(?:a|area)$/i; - -jQuery.fn.extend( { - prop: function( name, value ) { - return access( this, jQuery.prop, name, value, arguments.length > 1 ); - }, - - removeProp: function( name ) { - return this.each( function() { - delete this[ jQuery.propFix[ name ] || name ]; - } ); - } -} ); - -jQuery.extend( { - prop: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set properties on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } - - return ( elem[ name ] = value ); - } - - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } - - return elem[ name ]; - }, - - propHooks: { - tabIndex: { - get: function( elem ) { - - // Support: IE <=9 - 11 only - // elem.tabIndex doesn't always return the - // correct value when it hasn't been explicitly set - // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - // Use proper attribute retrieval(#12072) - var tabindex = jQuery.find.attr( elem, "tabindex" ); - - if ( tabindex ) { - return parseInt( tabindex, 10 ); - } - - if ( - rfocusable.test( elem.nodeName ) || - rclickable.test( elem.nodeName ) && - elem.href - ) { - return 0; - } - - return -1; - } - } - }, - - propFix: { - "for": "htmlFor", - "class": "className" - } -} ); - -// Support: IE <=11 only -// Accessing the selectedIndex property -// forces the browser to respect setting selected -// on the option -// The getter ensures a default option is selected -// when in an optgroup -// eslint rule "no-unused-expressions" is disabled for this code -// since it considers such accessions noop -if ( !support.optSelected ) { - jQuery.propHooks.selected = { - get: function( elem ) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if ( parent && parent.parentNode ) { - parent.parentNode.selectedIndex; - } - return null; - }, - set: function( elem ) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if ( parent ) { - parent.selectedIndex; - - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - } - }; -} - -jQuery.each( [ - "tabIndex", - "readOnly", - "maxLength", - "cellSpacing", - "cellPadding", - "rowSpan", - "colSpan", - "useMap", - "frameBorder", - "contentEditable" -], function() { - jQuery.propFix[ this.toLowerCase() ] = this; -} ); - - - - - // Strip and collapse whitespace according to HTML spec - // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace - function stripAndCollapse( value ) { - var tokens = value.match( rnothtmlwhite ) || []; - return tokens.join( " " ); - } - - -function getClass( elem ) { - return elem.getAttribute && elem.getAttribute( "class" ) || ""; -} - -function classesToArray( value ) { - if ( Array.isArray( value ) ) { - return value; - } - if ( typeof value === "string" ) { - return value.match( rnothtmlwhite ) || []; - } - return []; -} - -jQuery.fn.extend( { - addClass: function( value ) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; - - if ( isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); - } ); - } - - classes = classesToArray( value ); - - if ( classes.length ) { - while ( ( elem = this[ i++ ] ) ) { - curValue = getClass( elem ); - cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); - - if ( cur ) { - j = 0; - while ( ( clazz = classes[ j++ ] ) ) { - if ( cur.indexOf( " " + clazz + " " ) < 0 ) { - cur += clazz + " "; - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - elem.setAttribute( "class", finalValue ); - } - } - } - } - - return this; - }, - - removeClass: function( value ) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; - - if ( isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); - } ); - } - - if ( !arguments.length ) { - return this.attr( "class", "" ); - } - - classes = classesToArray( value ); - - if ( classes.length ) { - while ( ( elem = this[ i++ ] ) ) { - curValue = getClass( elem ); - - // This expression is here for better compressibility (see addClass) - cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); - - if ( cur ) { - j = 0; - while ( ( clazz = classes[ j++ ] ) ) { - - // Remove *all* instances - while ( cur.indexOf( " " + clazz + " " ) > -1 ) { - cur = cur.replace( " " + clazz + " ", " " ); - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - elem.setAttribute( "class", finalValue ); - } - } - } - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var type = typeof value, - isValidValue = type === "string" || Array.isArray( value ); - - if ( typeof stateVal === "boolean" && isValidValue ) { - return stateVal ? this.addClass( value ) : this.removeClass( value ); - } - - if ( isFunction( value ) ) { - return this.each( function( i ) { - jQuery( this ).toggleClass( - value.call( this, i, getClass( this ), stateVal ), - stateVal - ); - } ); - } - - return this.each( function() { - var className, i, self, classNames; - - if ( isValidValue ) { - - // Toggle individual class names - i = 0; - self = jQuery( this ); - classNames = classesToArray( value ); - - while ( ( className = classNames[ i++ ] ) ) { - - // Check each className given, space separated list - if ( self.hasClass( className ) ) { - self.removeClass( className ); - } else { - self.addClass( className ); - } - } - - // Toggle whole class name - } else if ( value === undefined || type === "boolean" ) { - className = getClass( this ); - if ( className ) { - - // Store className if set - dataPriv.set( this, "__className__", className ); - } - - // If the element has a class name or if we're passed `false`, - // then remove the whole classname (if there was one, the above saved it). - // Otherwise bring back whatever was previously saved (if anything), - // falling back to the empty string if nothing was stored. - if ( this.setAttribute ) { - this.setAttribute( "class", - className || value === false ? - "" : - dataPriv.get( this, "__className__" ) || "" - ); - } - } - } ); - }, - - hasClass: function( selector ) { - var className, elem, - i = 0; - - className = " " + selector + " "; - while ( ( elem = this[ i++ ] ) ) { - if ( elem.nodeType === 1 && - ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { - return true; - } - } - - return false; - } -} ); - - - - -var rreturn = /\r/g; - -jQuery.fn.extend( { - val: function( value ) { - var hooks, ret, valueIsFunction, - elem = this[ 0 ]; - - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.type ] || - jQuery.valHooks[ elem.nodeName.toLowerCase() ]; - - if ( hooks && - "get" in hooks && - ( ret = hooks.get( elem, "value" ) ) !== undefined - ) { - return ret; - } - - ret = elem.value; - - // Handle most common string cases - if ( typeof ret === "string" ) { - return ret.replace( rreturn, "" ); - } - - // Handle cases where value is null/undef or number - return ret == null ? "" : ret; - } - - return; - } - - valueIsFunction = isFunction( value ); - - return this.each( function( i ) { - var val; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( valueIsFunction ) { - val = value.call( this, i, jQuery( this ).val() ); - } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; - - } else if ( typeof val === "number" ) { - val += ""; - - } else if ( Array.isArray( val ) ) { - val = jQuery.map( val, function( value ) { - return value == null ? "" : value + ""; - } ); - } - - hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; - - // If set returns undefined, fall back to normal setting - if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { - this.value = val; - } - } ); - } -} ); - -jQuery.extend( { - valHooks: { - option: { - get: function( elem ) { - - var val = jQuery.find.attr( elem, "value" ); - return val != null ? - val : - - // Support: IE <=10 - 11 only - // option.text throws exceptions (#14686, #14858) - // Strip and collapse whitespace - // https://html.spec.whatwg.org/#strip-and-collapse-whitespace - stripAndCollapse( jQuery.text( elem ) ); - } - }, - select: { - get: function( elem ) { - var value, option, i, - options = elem.options, - index = elem.selectedIndex, - one = elem.type === "select-one", - values = one ? null : [], - max = one ? index + 1 : options.length; - - if ( index < 0 ) { - i = max; - - } else { - i = one ? index : 0; - } - - // Loop through all the selected options - for ( ; i < max; i++ ) { - option = options[ i ]; - - // Support: IE <=9 only - // IE8-9 doesn't update selected after form reset (#2551) - if ( ( option.selected || i === index ) && - - // Don't return options that are disabled or in a disabled optgroup - !option.disabled && - ( !option.parentNode.disabled || - !nodeName( option.parentNode, "optgroup" ) ) ) { - - // Get the specific value for the option - value = jQuery( option ).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - }, - - set: function( elem, value ) { - var optionSet, option, - options = elem.options, - values = jQuery.makeArray( value ), - i = options.length; - - while ( i-- ) { - option = options[ i ]; - - /* eslint-disable no-cond-assign */ - - if ( option.selected = - jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 - ) { - optionSet = true; - } - - /* eslint-enable no-cond-assign */ - } - - // Force browsers to behave consistently when non-matching value is set - if ( !optionSet ) { - elem.selectedIndex = -1; - } - return values; - } - } - } -} ); - -// Radios and checkboxes getter/setter -jQuery.each( [ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - set: function( elem, value ) { - if ( Array.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); - } - } - }; - if ( !support.checkOn ) { - jQuery.valHooks[ this ].get = function( elem ) { - return elem.getAttribute( "value" ) === null ? "on" : elem.value; - }; - } -} ); - - - - -// Return jQuery for attributes-only inclusion - - -support.focusin = "onfocusin" in window; - - -var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - stopPropagationCallback = function( e ) { - e.stopPropagation(); - }; - -jQuery.extend( jQuery.event, { - - trigger: function( event, data, elem, onlyHandlers ) { - - var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; - - cur = lastElement = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf( "." ) > -1 ) { - - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split( "." ); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf( ":" ) < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join( "." ); - event.rnamespace = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === ( elem.ownerDocument || document ) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { - lastElement = cur; - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( - dataPriv.get( cur, "events" ) || Object.create( null ) - )[ event.type ] && - dataPriv.get( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( ( !special._default || - special._default.apply( eventPath.pop(), data ) === false ) && - acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name as the event. - // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - - if ( event.isPropagationStopped() ) { - lastElement.addEventListener( type, stopPropagationCallback ); - } - - elem[ type ](); - - if ( event.isPropagationStopped() ) { - lastElement.removeEventListener( type, stopPropagationCallback ); - } - - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } - - return event.result; - }, - - // Piggyback on a donor event to simulate a different one - // Used only for `focus(in | out)` events - simulate: function( type, elem, event ) { - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true - } - ); - - jQuery.event.trigger( e, null, elem ); - } - -} ); - -jQuery.fn.extend( { - - trigger: function( type, data ) { - return this.each( function() { - jQuery.event.trigger( type, data, this ); - } ); - }, - triggerHandler: function( type, data ) { - var elem = this[ 0 ]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } - } -} ); - - -// Support: Firefox <=44 -// Firefox doesn't have focus(in | out) events -// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 -// -// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 -// focus(in | out) events fire after focus & blur events, -// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order -// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 -if ( !support.focusin ) { - jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - - // Handle: regular nodes (via `this.ownerDocument`), window - // (via `this.document`) & document (via `this`). - var doc = this.ownerDocument || this.document || this, - attaches = dataPriv.access( doc, fix ); - - if ( !attaches ) { - doc.addEventListener( orig, handler, true ); - } - dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this.document || this, - attaches = dataPriv.access( doc, fix ) - 1; - - if ( !attaches ) { - doc.removeEventListener( orig, handler, true ); - dataPriv.remove( doc, fix ); - - } else { - dataPriv.access( doc, fix, attaches ); - } - } - }; - } ); -} -var location = window.location; - -var nonce = { guid: Date.now() }; - -var rquery = ( /\?/ ); - - - -// Cross-browser xml parsing -jQuery.parseXML = function( data ) { - var xml; - if ( !data || typeof data !== "string" ) { - return null; - } - - // Support: IE 9 - 11 only - // IE throws on parseFromString with invalid input. - try { - xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); - } catch ( e ) { - xml = undefined; - } - - if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { - jQuery.error( "Invalid XML: " + data ); - } - return xml; -}; - - -var - rbracket = /\[\]$/, - rCRLF = /\r?\n/g, - rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, - rsubmittable = /^(?:input|select|textarea|keygen)/i; - -function buildParams( prefix, obj, traditional, add ) { - var name; - - if ( Array.isArray( obj ) ) { - - // Serialize array item. - jQuery.each( obj, function( i, v ) { - if ( traditional || rbracket.test( prefix ) ) { - - // Treat each array item as a scalar. - add( prefix, v ); - - } else { - - // Item is non-scalar (array or object), encode its numeric index. - buildParams( - prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", - v, - traditional, - add - ); - } - } ); - - } else if ( !traditional && toType( obj ) === "object" ) { - - // Serialize object item. - for ( name in obj ) { - buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); - } - - } else { - - // Serialize scalar item. - add( prefix, obj ); - } -} - -// Serialize an array of form elements or a set of -// key/values into a query string -jQuery.param = function( a, traditional ) { - var prefix, - s = [], - add = function( key, valueOrFunction ) { - - // If value is a function, invoke it and use its return value - var value = isFunction( valueOrFunction ) ? - valueOrFunction() : - valueOrFunction; - - s[ s.length ] = encodeURIComponent( key ) + "=" + - encodeURIComponent( value == null ? "" : value ); - }; - - if ( a == null ) { - return ""; - } - - // If an array was passed in, assume that it is an array of form elements. - if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { - - // Serialize the form elements - jQuery.each( a, function() { - add( this.name, this.value ); - } ); - - } else { - - // If traditional, encode the "old" way (the way 1.3.2 or older - // did it), otherwise encode params recursively. - for ( prefix in a ) { - buildParams( prefix, a[ prefix ], traditional, add ); - } - } - - // Return the resulting serialization - return s.join( "&" ); -}; - -jQuery.fn.extend( { - serialize: function() { - return jQuery.param( this.serializeArray() ); - }, - serializeArray: function() { - return this.map( function() { - - // Can add propHook for "elements" to filter or add form elements - var elements = jQuery.prop( this, "elements" ); - return elements ? jQuery.makeArray( elements ) : this; - } ) - .filter( function() { - var type = this.type; - - // Use .is( ":disabled" ) so that fieldset[disabled] works - return this.name && !jQuery( this ).is( ":disabled" ) && - rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && - ( this.checked || !rcheckableType.test( type ) ); - } ) - .map( function( _i, elem ) { - var val = jQuery( this ).val(); - - if ( val == null ) { - return null; - } - - if ( Array.isArray( val ) ) { - return jQuery.map( val, function( val ) { - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ); - } - - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ).get(); - } -} ); - - -var - r20 = /%20/g, - rhash = /#.*$/, - rantiCache = /([?&])_=[^&]*/, - rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, - - // #7653, #8125, #8152: local protocol detection - rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, - rnoContent = /^(?:GET|HEAD)$/, - rprotocol = /^\/\//, - - /* Prefilters - * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) - * 2) These are called: - * - BEFORE asking for a transport - * - AFTER param serialization (s.data is a string if s.processData is true) - * 3) key is the dataType - * 4) the catchall symbol "*" can be used - * 5) execution will start with transport dataType and THEN continue down to "*" if needed - */ - prefilters = {}, - - /* Transports bindings - * 1) key is the dataType - * 2) the catchall symbol "*" can be used - * 3) selection will start with transport dataType and THEN go to "*" if needed - */ - transports = {}, - - // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression - allTypes = "*/".concat( "*" ), - - // Anchor tag for parsing the document origin - originAnchor = document.createElement( "a" ); - originAnchor.href = location.href; - -// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport -function addToPrefiltersOrTransports( structure ) { - - // dataTypeExpression is optional and defaults to "*" - return function( dataTypeExpression, func ) { - - if ( typeof dataTypeExpression !== "string" ) { - func = dataTypeExpression; - dataTypeExpression = "*"; - } - - var dataType, - i = 0, - dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; - - if ( isFunction( func ) ) { - - // For each dataType in the dataTypeExpression - while ( ( dataType = dataTypes[ i++ ] ) ) { - - // Prepend if requested - if ( dataType[ 0 ] === "+" ) { - dataType = dataType.slice( 1 ) || "*"; - ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); - - // Otherwise append - } else { - ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); - } - } - } - }; -} - -// Base inspection function for prefilters and transports -function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { - - var inspected = {}, - seekingTransport = ( structure === transports ); - - function inspect( dataType ) { - var selected; - inspected[ dataType ] = true; - jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { - var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); - if ( typeof dataTypeOrTransport === "string" && - !seekingTransport && !inspected[ dataTypeOrTransport ] ) { - - options.dataTypes.unshift( dataTypeOrTransport ); - inspect( dataTypeOrTransport ); - return false; - } else if ( seekingTransport ) { - return !( selected = dataTypeOrTransport ); - } - } ); - return selected; - } - - return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); -} - -// A special extend for ajax options -// that takes "flat" options (not to be deep extended) -// Fixes #9887 -function ajaxExtend( target, src ) { - var key, deep, - flatOptions = jQuery.ajaxSettings.flatOptions || {}; - - for ( key in src ) { - if ( src[ key ] !== undefined ) { - ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; - } - } - if ( deep ) { - jQuery.extend( true, target, deep ); - } - - return target; -} - -/* Handles responses to an ajax request: - * - finds the right dataType (mediates between content-type and expected dataType) - * - returns the corresponding response - */ -function ajaxHandleResponses( s, jqXHR, responses ) { - - var ct, type, finalDataType, firstDataType, - contents = s.contents, - dataTypes = s.dataTypes; - - // Remove auto dataType and get content-type in the process - while ( dataTypes[ 0 ] === "*" ) { - dataTypes.shift(); - if ( ct === undefined ) { - ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); - } - } - - // Check if we're dealing with a known content-type - if ( ct ) { - for ( type in contents ) { - if ( contents[ type ] && contents[ type ].test( ct ) ) { - dataTypes.unshift( type ); - break; - } - } - } - - // Check to see if we have a response for the expected dataType - if ( dataTypes[ 0 ] in responses ) { - finalDataType = dataTypes[ 0 ]; - } else { - - // Try convertible dataTypes - for ( type in responses ) { - if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { - finalDataType = type; - break; - } - if ( !firstDataType ) { - firstDataType = type; - } - } - - // Or just use first one - finalDataType = finalDataType || firstDataType; - } - - // If we found a dataType - // We add the dataType to the list if needed - // and return the corresponding response - if ( finalDataType ) { - if ( finalDataType !== dataTypes[ 0 ] ) { - dataTypes.unshift( finalDataType ); - } - return responses[ finalDataType ]; - } -} - -/* Chain conversions given the request and the original response - * Also sets the responseXXX fields on the jqXHR instance - */ -function ajaxConvert( s, response, jqXHR, isSuccess ) { - var conv2, current, conv, tmp, prev, - converters = {}, - - // Work with a copy of dataTypes in case we need to modify it for conversion - dataTypes = s.dataTypes.slice(); - - // Create converters map with lowercased keys - if ( dataTypes[ 1 ] ) { - for ( conv in s.converters ) { - converters[ conv.toLowerCase() ] = s.converters[ conv ]; - } - } - - current = dataTypes.shift(); - - // Convert to each sequential dataType - while ( current ) { - - if ( s.responseFields[ current ] ) { - jqXHR[ s.responseFields[ current ] ] = response; - } - - // Apply the dataFilter if provided - if ( !prev && isSuccess && s.dataFilter ) { - response = s.dataFilter( response, s.dataType ); - } - - prev = current; - current = dataTypes.shift(); - - if ( current ) { - - // There's only work to do if current dataType is non-auto - if ( current === "*" ) { - - current = prev; - - // Convert response if prev dataType is non-auto and differs from current - } else if ( prev !== "*" && prev !== current ) { - - // Seek a direct converter - conv = converters[ prev + " " + current ] || converters[ "* " + current ]; - - // If none found, seek a pair - if ( !conv ) { - for ( conv2 in converters ) { - - // If conv2 outputs current - tmp = conv2.split( " " ); - if ( tmp[ 1 ] === current ) { - - // If prev can be converted to accepted input - conv = converters[ prev + " " + tmp[ 0 ] ] || - converters[ "* " + tmp[ 0 ] ]; - if ( conv ) { - - // Condense equivalence converters - if ( conv === true ) { - conv = converters[ conv2 ]; - - // Otherwise, insert the intermediate dataType - } else if ( converters[ conv2 ] !== true ) { - current = tmp[ 0 ]; - dataTypes.unshift( tmp[ 1 ] ); - } - break; - } - } - } - } - - // Apply converter (if not an equivalence) - if ( conv !== true ) { - - // Unless errors are allowed to bubble, catch and return them - if ( conv && s.throws ) { - response = conv( response ); - } else { - try { - response = conv( response ); - } catch ( e ) { - return { - state: "parsererror", - error: conv ? e : "No conversion from " + prev + " to " + current - }; - } - } - } - } - } - } - - return { state: "success", data: response }; -} - -jQuery.extend( { - - // Counter for holding the number of active queries - active: 0, - - // Last-Modified header cache for next request - lastModified: {}, - etag: {}, - - ajaxSettings: { - url: location.href, - type: "GET", - isLocal: rlocalProtocol.test( location.protocol ), - global: true, - processData: true, - async: true, - contentType: "application/x-www-form-urlencoded; charset=UTF-8", - - /* - timeout: 0, - data: null, - dataType: null, - username: null, - password: null, - cache: null, - throws: false, - traditional: false, - headers: {}, - */ - - accepts: { - "*": allTypes, - text: "text/plain", - html: "text/html", - xml: "application/xml, text/xml", - json: "application/json, text/javascript" - }, - - contents: { - xml: /\bxml\b/, - html: /\bhtml/, - json: /\bjson\b/ - }, - - responseFields: { - xml: "responseXML", - text: "responseText", - json: "responseJSON" - }, - - // Data converters - // Keys separate source (or catchall "*") and destination types with a single space - converters: { - - // Convert anything to text - "* text": String, - - // Text to html (true = no transformation) - "text html": true, - - // Evaluate text as a json expression - "text json": JSON.parse, - - // Parse text as xml - "text xml": jQuery.parseXML - }, - - // For options that shouldn't be deep extended: - // you can add your own custom options here if - // and when you create one that shouldn't be - // deep extended (see ajaxExtend) - flatOptions: { - url: true, - context: true - } - }, - - // Creates a full fledged settings object into target - // with both ajaxSettings and settings fields. - // If target is omitted, writes into ajaxSettings. - ajaxSetup: function( target, settings ) { - return settings ? - - // Building a settings object - ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : - - // Extending ajaxSettings - ajaxExtend( jQuery.ajaxSettings, target ); - }, - - ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), - ajaxTransport: addToPrefiltersOrTransports( transports ), - - // Main method - ajax: function( url, options ) { - - // If url is an object, simulate pre-1.5 signature - if ( typeof url === "object" ) { - options = url; - url = undefined; - } - - // Force options to be an object - options = options || {}; - - var transport, - - // URL without anti-cache param - cacheURL, - - // Response headers - responseHeadersString, - responseHeaders, - - // timeout handle - timeoutTimer, - - // Url cleanup var - urlAnchor, - - // Request state (becomes false upon send and true upon completion) - completed, - - // To know if global events are to be dispatched - fireGlobals, - - // Loop variable - i, - - // uncached part of the url - uncached, - - // Create the final options object - s = jQuery.ajaxSetup( {}, options ), - - // Callbacks context - callbackContext = s.context || s, - - // Context for global events is callbackContext if it is a DOM node or jQuery collection - globalEventContext = s.context && - ( callbackContext.nodeType || callbackContext.jquery ) ? - jQuery( callbackContext ) : - jQuery.event, - - // Deferreds - deferred = jQuery.Deferred(), - completeDeferred = jQuery.Callbacks( "once memory" ), - - // Status-dependent callbacks - statusCode = s.statusCode || {}, - - // Headers (they are sent all at once) - requestHeaders = {}, - requestHeadersNames = {}, - - // Default abort message - strAbort = "canceled", - - // Fake xhr - jqXHR = { - readyState: 0, - - // Builds headers hashtable if needed - getResponseHeader: function( key ) { - var match; - if ( completed ) { - if ( !responseHeaders ) { - responseHeaders = {}; - while ( ( match = rheaders.exec( responseHeadersString ) ) ) { - responseHeaders[ match[ 1 ].toLowerCase() + " " ] = - ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) - .concat( match[ 2 ] ); - } - } - match = responseHeaders[ key.toLowerCase() + " " ]; - } - return match == null ? null : match.join( ", " ); - }, - - // Raw string - getAllResponseHeaders: function() { - return completed ? responseHeadersString : null; - }, - - // Caches the header - setRequestHeader: function( name, value ) { - if ( completed == null ) { - name = requestHeadersNames[ name.toLowerCase() ] = - requestHeadersNames[ name.toLowerCase() ] || name; - requestHeaders[ name ] = value; - } - return this; - }, - - // Overrides response content-type header - overrideMimeType: function( type ) { - if ( completed == null ) { - s.mimeType = type; - } - return this; - }, - - // Status-dependent callbacks - statusCode: function( map ) { - var code; - if ( map ) { - if ( completed ) { - - // Execute the appropriate callbacks - jqXHR.always( map[ jqXHR.status ] ); - } else { - - // Lazy-add the new callbacks in a way that preserves old ones - for ( code in map ) { - statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; - } - } - } - return this; - }, - - // Cancel the request - abort: function( statusText ) { - var finalText = statusText || strAbort; - if ( transport ) { - transport.abort( finalText ); - } - done( 0, finalText ); - return this; - } - }; - - // Attach deferreds - deferred.promise( jqXHR ); - - // Add protocol if not provided (prefilters might expect it) - // Handle falsy url in the settings object (#10093: consistency with old signature) - // We also use the url parameter if available - s.url = ( ( url || s.url || location.href ) + "" ) - .replace( rprotocol, location.protocol + "//" ); - - // Alias method option to type as per ticket #12004 - s.type = options.method || options.type || s.method || s.type; - - // Extract dataTypes list - s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; - - // A cross-domain request is in order when the origin doesn't match the current origin. - if ( s.crossDomain == null ) { - urlAnchor = document.createElement( "a" ); - - // Support: IE <=8 - 11, Edge 12 - 15 - // IE throws exception on accessing the href property if url is malformed, - // e.g. http://example.com:80x/ - try { - urlAnchor.href = s.url; - - // Support: IE <=8 - 11 only - // Anchor's host property isn't correctly set when s.url is relative - urlAnchor.href = urlAnchor.href; - s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== - urlAnchor.protocol + "//" + urlAnchor.host; - } catch ( e ) { - - // If there is an error parsing the URL, assume it is crossDomain, - // it can be rejected by the transport if it is invalid - s.crossDomain = true; - } - } - - // Convert data if not already a string - if ( s.data && s.processData && typeof s.data !== "string" ) { - s.data = jQuery.param( s.data, s.traditional ); - } - - // Apply prefilters - inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); - - // If request was aborted inside a prefilter, stop there - if ( completed ) { - return jqXHR; - } - - // We can fire global events as of now if asked to - // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) - fireGlobals = jQuery.event && s.global; - - // Watch for a new set of requests - if ( fireGlobals && jQuery.active++ === 0 ) { - jQuery.event.trigger( "ajaxStart" ); - } - - // Uppercase the type - s.type = s.type.toUpperCase(); - - // Determine if request has content - s.hasContent = !rnoContent.test( s.type ); - - // Save the URL in case we're toying with the If-Modified-Since - // and/or If-None-Match header later on - // Remove hash to simplify url manipulation - cacheURL = s.url.replace( rhash, "" ); - - // More options handling for requests with no content - if ( !s.hasContent ) { - - // Remember the hash so we can put it back - uncached = s.url.slice( cacheURL.length ); - - // If data is available and should be processed, append data to url - if ( s.data && ( s.processData || typeof s.data === "string" ) ) { - cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; - - // #9682: remove data so that it's not used in an eventual retry - delete s.data; - } - - // Add or update anti-cache param if needed - if ( s.cache === false ) { - cacheURL = cacheURL.replace( rantiCache, "$1" ); - uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + - uncached; - } - - // Put hash and anti-cache on the URL that will be requested (gh-1732) - s.url = cacheURL + uncached; - - // Change '%20' to '+' if this is encoded form body content (gh-2658) - } else if ( s.data && s.processData && - ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { - s.data = s.data.replace( r20, "+" ); - } - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - if ( jQuery.lastModified[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); - } - if ( jQuery.etag[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); - } - } - - // Set the correct header, if data is being sent - if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { - jqXHR.setRequestHeader( "Content-Type", s.contentType ); - } - - // Set the Accepts header for the server, depending on the dataType - jqXHR.setRequestHeader( - "Accept", - s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? - s.accepts[ s.dataTypes[ 0 ] ] + - ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : - s.accepts[ "*" ] - ); - - // Check for headers option - for ( i in s.headers ) { - jqXHR.setRequestHeader( i, s.headers[ i ] ); - } - - // Allow custom headers/mimetypes and early abort - if ( s.beforeSend && - ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { - - // Abort if not done already and return - return jqXHR.abort(); - } - - // Aborting is no longer a cancellation - strAbort = "abort"; - - // Install callbacks on deferreds - completeDeferred.add( s.complete ); - jqXHR.done( s.success ); - jqXHR.fail( s.error ); - - // Get transport - transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); - - // If no transport, we auto-abort - if ( !transport ) { - done( -1, "No Transport" ); - } else { - jqXHR.readyState = 1; - - // Send global event - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); - } - - // If request was aborted inside ajaxSend, stop there - if ( completed ) { - return jqXHR; - } - - // Timeout - if ( s.async && s.timeout > 0 ) { - timeoutTimer = window.setTimeout( function() { - jqXHR.abort( "timeout" ); - }, s.timeout ); - } - - try { - completed = false; - transport.send( requestHeaders, done ); - } catch ( e ) { - - // Rethrow post-completion exceptions - if ( completed ) { - throw e; - } - - // Propagate others as results - done( -1, e ); - } - } - - // Callback for when everything is done - function done( status, nativeStatusText, responses, headers ) { - var isSuccess, success, error, response, modified, - statusText = nativeStatusText; - - // Ignore repeat invocations - if ( completed ) { - return; - } - - completed = true; - - // Clear timeout if it exists - if ( timeoutTimer ) { - window.clearTimeout( timeoutTimer ); - } - - // Dereference transport for early garbage collection - // (no matter how long the jqXHR object will be used) - transport = undefined; - - // Cache response headers - responseHeadersString = headers || ""; - - // Set readyState - jqXHR.readyState = status > 0 ? 4 : 0; - - // Determine if successful - isSuccess = status >= 200 && status < 300 || status === 304; - - // Get response data - if ( responses ) { - response = ajaxHandleResponses( s, jqXHR, responses ); - } - - // Use a noop converter for missing script - if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { - s.converters[ "text script" ] = function() {}; - } - - // Convert no matter what (that way responseXXX fields are always set) - response = ajaxConvert( s, response, jqXHR, isSuccess ); - - // If successful, handle type chaining - if ( isSuccess ) { - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - modified = jqXHR.getResponseHeader( "Last-Modified" ); - if ( modified ) { - jQuery.lastModified[ cacheURL ] = modified; - } - modified = jqXHR.getResponseHeader( "etag" ); - if ( modified ) { - jQuery.etag[ cacheURL ] = modified; - } - } - - // if no content - if ( status === 204 || s.type === "HEAD" ) { - statusText = "nocontent"; - - // if not modified - } else if ( status === 304 ) { - statusText = "notmodified"; - - // If we have data, let's convert it - } else { - statusText = response.state; - success = response.data; - error = response.error; - isSuccess = !error; - } - } else { - - // Extract error from statusText and normalize for non-aborts - error = statusText; - if ( status || !statusText ) { - statusText = "error"; - if ( status < 0 ) { - status = 0; - } - } - } - - // Set data for the fake xhr object - jqXHR.status = status; - jqXHR.statusText = ( nativeStatusText || statusText ) + ""; - - // Success/Error - if ( isSuccess ) { - deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); - } else { - deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); - } - - // Status-dependent callbacks - jqXHR.statusCode( statusCode ); - statusCode = undefined; - - if ( fireGlobals ) { - globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", - [ jqXHR, s, isSuccess ? success : error ] ); - } - - // Complete - completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); - - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); - - // Handle the global AJAX counter - if ( !( --jQuery.active ) ) { - jQuery.event.trigger( "ajaxStop" ); - } - } - } - - return jqXHR; - }, - - getJSON: function( url, data, callback ) { - return jQuery.get( url, data, callback, "json" ); - }, - - getScript: function( url, callback ) { - return jQuery.get( url, undefined, callback, "script" ); - } -} ); - -jQuery.each( [ "get", "post" ], function( _i, method ) { - jQuery[ method ] = function( url, data, callback, type ) { - - // Shift arguments if data argument was omitted - if ( isFunction( data ) ) { - type = type || callback; - callback = data; - data = undefined; - } - - // The url can be an options object (which then must have .url) - return jQuery.ajax( jQuery.extend( { - url: url, - type: method, - dataType: type, - data: data, - success: callback - }, jQuery.isPlainObject( url ) && url ) ); - }; -} ); - -jQuery.ajaxPrefilter( function( s ) { - var i; - for ( i in s.headers ) { - if ( i.toLowerCase() === "content-type" ) { - s.contentType = s.headers[ i ] || ""; - } - } -} ); - - -jQuery._evalUrl = function( url, options, doc ) { - return jQuery.ajax( { - url: url, - - // Make this explicit, since user can override this through ajaxSetup (#11264) - type: "GET", - dataType: "script", - cache: true, - async: false, - global: false, - - // Only evaluate the response if it is successful (gh-4126) - // dataFilter is not invoked for failure responses, so using it instead - // of the default converter is kludgy but it works. - converters: { - "text script": function() {} - }, - dataFilter: function( response ) { - jQuery.globalEval( response, options, doc ); - } - } ); -}; - - -jQuery.fn.extend( { - wrapAll: function( html ) { - var wrap; - - if ( this[ 0 ] ) { - if ( isFunction( html ) ) { - html = html.call( this[ 0 ] ); - } - - // The elements to wrap the target around - wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); - - if ( this[ 0 ].parentNode ) { - wrap.insertBefore( this[ 0 ] ); - } - - wrap.map( function() { - var elem = this; - - while ( elem.firstElementChild ) { - elem = elem.firstElementChild; - } - - return elem; - } ).append( this ); - } - - return this; - }, - - wrapInner: function( html ) { - if ( isFunction( html ) ) { - return this.each( function( i ) { - jQuery( this ).wrapInner( html.call( this, i ) ); - } ); - } - - return this.each( function() { - var self = jQuery( this ), - contents = self.contents(); - - if ( contents.length ) { - contents.wrapAll( html ); - - } else { - self.append( html ); - } - } ); - }, - - wrap: function( html ) { - var htmlIsFunction = isFunction( html ); - - return this.each( function( i ) { - jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); - } ); - }, - - unwrap: function( selector ) { - this.parent( selector ).not( "body" ).each( function() { - jQuery( this ).replaceWith( this.childNodes ); - } ); - return this; - } -} ); - - -jQuery.expr.pseudos.hidden = function( elem ) { - return !jQuery.expr.pseudos.visible( elem ); -}; -jQuery.expr.pseudos.visible = function( elem ) { - return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); -}; - - - - -jQuery.ajaxSettings.xhr = function() { - try { - return new window.XMLHttpRequest(); - } catch ( e ) {} -}; - -var xhrSuccessStatus = { - - // File protocol always yields status code 0, assume 200 - 0: 200, - - // Support: IE <=9 only - // #1450: sometimes IE returns 1223 when it should be 204 - 1223: 204 - }, - xhrSupported = jQuery.ajaxSettings.xhr(); - -support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); -support.ajax = xhrSupported = !!xhrSupported; - -jQuery.ajaxTransport( function( options ) { - var callback, errorCallback; - - // Cross domain only allowed if supported through XMLHttpRequest - if ( support.cors || xhrSupported && !options.crossDomain ) { - return { - send: function( headers, complete ) { - var i, - xhr = options.xhr(); - - xhr.open( - options.type, - options.url, - options.async, - options.username, - options.password - ); - - // Apply custom fields if provided - if ( options.xhrFields ) { - for ( i in options.xhrFields ) { - xhr[ i ] = options.xhrFields[ i ]; - } - } - - // Override mime type if needed - if ( options.mimeType && xhr.overrideMimeType ) { - xhr.overrideMimeType( options.mimeType ); - } - - // X-Requested-With header - // For cross-domain requests, seeing as conditions for a preflight are - // akin to a jigsaw puzzle, we simply never set it to be sure. - // (it can always be set on a per-request basis or even using ajaxSetup) - // For same-domain requests, won't change header if already provided. - if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { - headers[ "X-Requested-With" ] = "XMLHttpRequest"; - } - - // Set headers - for ( i in headers ) { - xhr.setRequestHeader( i, headers[ i ] ); - } - - // Callback - callback = function( type ) { - return function() { - if ( callback ) { - callback = errorCallback = xhr.onload = - xhr.onerror = xhr.onabort = xhr.ontimeout = - xhr.onreadystatechange = null; - - if ( type === "abort" ) { - xhr.abort(); - } else if ( type === "error" ) { - - // Support: IE <=9 only - // On a manual native abort, IE9 throws - // errors on any property access that is not readyState - if ( typeof xhr.status !== "number" ) { - complete( 0, "error" ); - } else { - complete( - - // File: protocol always yields status 0; see #8605, #14207 - xhr.status, - xhr.statusText - ); - } - } else { - complete( - xhrSuccessStatus[ xhr.status ] || xhr.status, - xhr.statusText, - - // Support: IE <=9 only - // IE9 has no XHR2 but throws on binary (trac-11426) - // For XHR2 non-text, let the caller handle it (gh-2498) - ( xhr.responseType || "text" ) !== "text" || - typeof xhr.responseText !== "string" ? - { binary: xhr.response } : - { text: xhr.responseText }, - xhr.getAllResponseHeaders() - ); - } - } - }; - }; - - // Listen to events - xhr.onload = callback(); - errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); - - // Support: IE 9 only - // Use onreadystatechange to replace onabort - // to handle uncaught aborts - if ( xhr.onabort !== undefined ) { - xhr.onabort = errorCallback; - } else { - xhr.onreadystatechange = function() { - - // Check readyState before timeout as it changes - if ( xhr.readyState === 4 ) { - - // Allow onerror to be called first, - // but that will not handle a native abort - // Also, save errorCallback to a variable - // as xhr.onerror cannot be accessed - window.setTimeout( function() { - if ( callback ) { - errorCallback(); - } - } ); - } - }; - } - - // Create the abort callback - callback = callback( "abort" ); - - try { - - // Do send the request (this may raise an exception) - xhr.send( options.hasContent && options.data || null ); - } catch ( e ) { - - // #14683: Only rethrow if this hasn't been notified as an error yet - if ( callback ) { - throw e; - } - } - }, - - abort: function() { - if ( callback ) { - callback(); - } - } - }; - } -} ); - - - - -// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) -jQuery.ajaxPrefilter( function( s ) { - if ( s.crossDomain ) { - s.contents.script = false; - } -} ); - -// Install script dataType -jQuery.ajaxSetup( { - accepts: { - script: "text/javascript, application/javascript, " + - "application/ecmascript, application/x-ecmascript" - }, - contents: { - script: /\b(?:java|ecma)script\b/ - }, - converters: { - "text script": function( text ) { - jQuery.globalEval( text ); - return text; - } - } -} ); - -// Handle cache's special case and crossDomain -jQuery.ajaxPrefilter( "script", function( s ) { - if ( s.cache === undefined ) { - s.cache = false; - } - if ( s.crossDomain ) { - s.type = "GET"; - } -} ); - -// Bind script tag hack transport -jQuery.ajaxTransport( "script", function( s ) { - - // This transport only deals with cross domain or forced-by-attrs requests - if ( s.crossDomain || s.scriptAttrs ) { - var script, callback; - return { - send: function( _, complete ) { - script = jQuery( " - - - - - JS9 - - -
    -
    -
    -
    -
    -
    - -

    - - diff --git a/web/static/js9_old/js9.js b/web/static/js9_old/js9.js deleted file mode 100644 index 9a84380a4e82c3a96dbc9146eee563565f7c35dd..0000000000000000000000000000000000000000 --- a/web/static/js9_old/js9.js +++ /dev/null @@ -1,28462 +0,0 @@ -/* - * - * JS9: astronomical image display everywhere (December 10, 2012) - * - * Principals: Eric Mandel, Alexey Vikhlinin - * Organization: Center for Astrophysics | Harvard & Smithsonian, Cambridge MA - * Contact: emandel@cfa.harvard.edu - * - * Copyright (c) 2012 - 2022 Smithsonian Astrophysical Observatory - * - */ - -/*global JS9Prefs, JS9Inline, $, jQuery, fabric, io, sprintf, Astroem, dhtmlwindow, saveAs, Spinner, ResizeSensor, Jupyter, gaussBlur, ImageFilters, Plotly, tinycolor, regSelect */ - -"use strict"; - -// ensure Emscripten's Module object is available so we can pass properties -// (e.g. wasmBinary) in js9prefs.js and during JS9.init() -// (use var to add to global scope because it's how Emscripten does it) -var Module; -if( typeof Module !== "object" ){ Module = {}; } - -// generate and expose JS9 module -// (use var to add to global scope for backward compatibility with previous ES5) -var JS9 = (function(){ - -// module header -const JS9 = {}; -JS9.NAME = "JS9"; // The name of this namespace -JS9.VERSION = "3.8"; // The version of this namespace -JS9.COPYRIGHT = "Copyright (c) 2012-2022 Smithsonian Institution"; -JS9.ABOUT = `JS9 ${JS9.VERSION}: astronomical image display everywhere\nEric Mandel, Alexey Vikhlinin\n${JS9.COPYRIGHT}`; - -// internal defaults (not usually changed by users) -JS9.DEFID = "JS9"; // default JS9 display id -JS9.WIDTH = 512; // width of js9 canvas -JS9.HEIGHT = 512; // height of js9 canvas -JS9.ANON = "Anonymous"; // name to use for images with no name -JS9.PREFSFILE = "js9Prefs.json";// prefs file to load -JS9.WORKERFILE = "js9worker.js";// js9 web worker file to load -JS9.ZINDEX = 0; // z-index of image canvas: on bottom of js9 -JS9.SHAPEZINDEX = 4; // base z-index of shape layers layers -JS9.MESSZINDEX = 80; // z-index of messages: above graphics -JS9.BTNZINDEX = 90; // z-index of buttons on top of plugin canvases -JS9.MENUZINDEX = 1000; // z-index of menus: always on top! -JS9.COLORSIZE = 1024; // size of contrast/biased color array -JS9.SCALESIZE = 16384; // size of scaled color array -JS9.INVSIZE = 1024; // size of inverse array -JS9.HISTSIZE = 16384; // size of histogram equalization array -JS9.INSTALLDIR=""; // prefix to get to js9 install directory -JS9.TOROOT=""; // prefix to get to data file from install -JS9.PLUGINS=""; // regexp list of plugins -JS9.LIGHTWIN = "dhtml"; // light window type: choice of dhtml -JS9.ANTIALIAS = false; // use anti-aliasing? -JS9.SCALEIREG = true; // scale interactive regions by zoom factor? -JS9.NOMOVE = 3; // number of pixels before we recognize movement -JS9.DBLCLICK0 = 5; // < millisec => same event -JS9.DBLCLICK = 300; // < millisec => double-click -JS9.TIMEOUT = 250; // millisec before assuming light window is up -JS9.SPINOUT = 250; // millisec before assuming spinner is up -JS9.WORKEROUT = 2000; // millisec before restarting worker socket -JS9.SUPERMENU = /^SUPERMENU_/; // base of supermenu id -JS9.RESIZEDIST = 20; // size of rectangle defining resize handle -JS9.RESIZEFUDGE = 5; // fudge for webkit resize problems -JS9.RAWID0 = "raw0"; // default raw id -JS9.RAWIDX = "alt"; // default "alternate" raw id -JS9.IDFMT = " (%s)"; // format for light window id -JS9.MINZOOM = 0.125; // min zoom using scroll wheel -JS9.MAXZOOM = 32.0; // max zoom using scroll wheel -JS9.ADDZOOM = 0.1; // add/subtract amount per mouse wheel click -JS9.MODZOOM = 2; // skip factor with wheel to avoid pileup -JS9.DIRZOOM = 1; // sign (+/-) determines zoom direction -JS9.CHROMEFILEWARNING = true; // whether to alert chrome users about file URI -JS9.CLIPBOARDERROR = "the local clipboard (which only holds data copied from within JS9) does not contain any content. Were you trying to paste something copied outside JS9?"; -JS9.CLIPBOARDERROR2 = "the local clipboard (which only holds data copied from within JS9) does not contain any regions"; -JS9.URLEXP = /^(https?|ftp):\/\//; // url to determine a web page -JS9.WCSEXP = /^(fk4|fk5|icrs|galactic|ecliptic|image|physical|linear)$/; -JS9.REGSIZE = 0; // 0 -> cdelt, 1 -> ang sep (regions use #0) - -// https://hacks.mozilla.org/2013/04/detecting-touch-its-the-why-not-the-how/ -JS9.TOUCHSUPPORTED = ({}.hasOwnProperty.call(window, "ontouchstart") || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)); -// modified from: -// http://stackoverflow.com/questions/2400935/browser-detection-in-javascript -// https://stackoverflow.com/questions/58019463/how-to-detect-device-name-in-safari-on-ios-13-while-it-doesnt-show-the-correct -JS9.BROWSER = (function(){ - const P = navigator.platform; - const N = navigator.appName; - const ua = navigator.userAgent; - const tem = ua.match(/version\/([.\d]+)/i); - let M = ua.match(/(opera|chrome|safari|firefox)\/?\s*(\.?\d+(\.\d+)*)/i); - if( M && tem !== null ){ M[2] = tem[1]; } - M = M? [M[1], M[2], P]: [N, navigator.appVersion,"-?", P]; - M.push(/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(ua) || - (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)); - return M; -}()); -// convenience to allow plugins to deal with HiDPI ratio blurring -// http://stackoverflow.com/questions/15661339/how-do-i-fix-blurry-text-in-my-html5-canvas -JS9.PIXEL_RATIO = (function(){ - const ctx = document.createElement("canvas").getContext("2d"), - dpr = window.devicePixelRatio || 1, - bsr = ctx.webkitBackingStorePixelRatio || - ctx.mozBackingStorePixelRatio || - ctx.msBackingStorePixelRatio || - ctx.oBackingStorePixelRatio || - ctx.backingStorePixelRatio || 1; - - return dpr / bsr; -}()); - -// global options -JS9.globalOpts = { - helperType: "none", // one of: sock.io, get, post, none - helperPort: 2718, // default port for node.js helper - requireHelper: false, // throw error if helper is not available? - allinoneHelper: false, // allow allinone to use helper? - processQueryParams: true, // process query parameters from url? - quietReturn: false, // should API return empty string or "OK"? - useWasm: true, // use WebAssembly if available? - transforms: ["flip", "rot90", "rotate"], // order for processing transforms - rotateRelative: false, // is setRotate() relative or absolute? - clickToFocus: false, // how to change focus on the display - winType: "light", // plugin window: "light" or "new" - sortPreloads: true, // sort preloads into original order after load? - defcolor: "#00FF00", // graphics color when all else fails - fits2fits: "never", // convert to repfile? always|never|size>x Mb - requireFits2Fits: false, // throw error if fits2fits can't be run? - localAccess: true, // access files locally, when available? - prependJS9Dir: true, // prepend $JS9_DIR to relative fitsFile paths? - dataDir: null, // path to FITS data (def: use incoming path) - alerts: true, // set to false to turn off alerts - valposTarget: null, // target element for valpos updates - valposWidth: "medium", // small, medium, large - valposDCoords: false, // show display coords in valpos? - internalValPos: true, // a fancy info plugin can turns this off - internalContrastBias: true, // a fancy colorbar plugin can turns this off - containContrastBias: false, // contrast/bias only when mouse is in display? - arrowIncrement: 1, // how much to move a region using arrow keys - wcsCrosshair: false, // enable wcs crosshair matching? - localLoadFormat: "image", // current format when loading local files - remoteLoadMethod: "proxy", // proxy or cors when loading remote file - csvIncludeWCS: true, // does Get/SaveRegions(csv) include wcs info? - regWhichDefault: "auto", // "auto" => selected or all, "all" is all - regIncludeJSON: true, // does SaveRegions(reg) include the json info? - regIncludeComments: true, // does SaveRegions(reg) include the comments? - regListDCoords: false, // ListRegions(reg) list preserved disp coords? - regSaveDCoords: false, // SaveRegions(reg) save preserved disp coords? - regExpandDCoords: false, // ExpandMacro(reg) use preserved disp coords? - regCopyDCoords: true, // CopyRegions(reg) copy preserved disp coords? - regArrowCrosshair: true, // does move with arrow keys display crosshair? - regSaveWCS: "", // def wcs for saving regions - regSaveFormat: "reg", // def format for saving regions (reg,cvs,svg) - regSaveWhich1: "all", // def 'which' for saving regions (all,selected) - regSaveWhich2: "selected", // def 'which' for saving in configure dialog - regMenuCreate: true, // menu select a region creates it immediately - regMenuSelection: "circle", // region selected during last menu select - regToClipboard: false, // copy all region changes to pseudo-clipboard? - regGroupConflict: "skip", // group conflicts: error or skip - regConfigAddParens: true, // does the reg configure gui try to add parens? - regSyncTextColor: true, // sync region text color with main color? - regDisplay: "lightwin", // "lightwin" or "display" - reConfigSize: "medium", // "small", "medium" - htimeout: 10000, // connection timeout for the helper connect - lhtimeout: 10000, // connection timeout for local helper connect - ehtimeout: 500, // connection timeout for Electron connect - ehretries: 20, // connection retries Electron connect - xtimeout: 600000, // connection timeout for fetch data requests - extlist: "EVENTS STDEVT", // list of binary table extensions - imopts: "IMOPTS", // basename of FITS param containing json opts - imcmap: "IMCMAP", // basename of FITS param containing cmaps - table: {xdim: 4096, ydim: 4096, bin: 1, bitpix: 32},// image section size to extract from table - image: {xdim: 4096, ydim: 4096, bin: 1},// image section size (unlimited=0) - binMode: "s", // "s" (sum) or "a" (avg) pixels when binning - reprojSwitches: "", // Montage reproject switches - reprojectLimits: false, // internal: check for reprojection limits? - rotationCenter: "file", // "current" display center or "file" (CRPIX1,2) - runOnCR: true, // Run forms such as binning when pressed? - clearImageMemory: "heap", // rm vfile: always|never|auto|noExt|noCube|size>x Mb heap=>free heap - helperProtocol: location.protocol, // http: or https: - reloadRefresh: false, // reload an image will refresh (or redisplay)? - reloadRefreshReg: true, // reloading regions file removes previous? - nextImageMask: false, // does nextImage() show active image masks? - panMouseThreshold: 1, // pixels mouse must move before we pan - panzoomRefreshLimit: 500, // # of shapes before avoiding refresh - panWithinDisplay: false, // keep panned image within the display? - pannerDirections: true, // display direction vectors in panner? - magnifierRegions: true, // display regions in magnifier? - editRegions: true, // double-click to edit regions? - svgBorder: true, // border around the display when saving to svg? - unremoveReg: 100, // how many removed regions to save - resetEmptyShapeId: false, // reset nshape counter if all shapes removed? - maxMemory: 2000000000, // max heap memory to allocate for a fits image - loadURL: "params/load.html",// location of param html file - corsURL: "params/loadcors.html", // location of param html file - proxyURL: "params/loadproxy.html", // location of param html file - loadProxy: false, // do we allow proxy load requests to server? - imsectionURL: "params/imsection.html", // location of param html file - postMessage: false, // allow communication through iframes? - localStorage: true, // use localStorage for session params? - waitType: "spinner", // "spinner" or "mouse" - spinColor: "#FF0000", // color of spinner - spinOpacity: 0.35, // opacity of spinner - resize: true, // allow resize of display? - resizeHandle: true, // add resize handle to display? - resizeRedisplay: true, // redisplay image while resizing? - logoDisplay: false, // show JS9 logo on each display? - logo: "images/js9logo.png", // show JS9 logo on each display? - lightWinPos: "center=1", // "left=n,top=m" offset from left,top of window - lightWinClose: "ask", // ask, close, move images when closing lightwin - fallbackDisplay: true, // displayMessage fallback to display window? - refreshDragDrop: true, // refresh on drag/drag and open file? - reduceMosaic: "js9", // "js9" or "shrink" ("js9" seems to be faster) - internalRegcnts: true, // make internal regcnts analysis available? - reduceRegcnts: true, // reduce image when doing counts in regions? - plot3d: {cube:"*:*:all", mode:"avg", areaunits:"pixels", color: "green"}, // plot3d options: avg/sum, pixels/arcsecs - imexamLineHeight: 1, // "height" of line region section - copyWcsPosFormat: "$ra $dec $sys", // format for copy wcs pos to clipboard - floatPrecision: 6, // precision for floatToString() - mouseActions: ["display value/position", "change contrast/bias", "pan the image"],// 0,1,2 mousepress - touchActions: ["display value/position", "change contrast/bias", "pan the image"],// 1,2,3 fingers - keyboardActions: { - a: "add last region selected in regions menu", - b: "toggle selected region: source/background", - c: "toggle crosshair", - d: "send selected region to back", - e: "toggle selected region: include/exclude", - "M-e": "edit selected region(s)", - i: "refresh image", - I: "display full image", - "M-i": "display selected cutouts", - "M-k": "toggle keyboard actions plugin", - l: "toggle active shape layers", - "M-l": "new JS9 light window", - m: "pan to mouse position", - "M-m": "toggle mouse/touch plugin", - "M-o": "open local file", - P: "paste regions from local clipboard", - p: "paste regions to current position", - "M-,": "toggle preferences plugin", - "M-p": "toggle preferences plugin", - r: "copy region(s) to clipboard", - s: "select region", - S: "select all regions", - "M-s": "toggle shape layers plugin", - u: "undo remove of region(s)", - U: "unselect all regions", - x: "flip image around x axis", - y: "flip image around y axis", - "9": "rotate image by 90 degrees", - "/": "copy wcs position to clipboard", - "?": "copy value and position to clipboard", - "0": "reset zoom", - "=": "zoom in", - "+": "zoom in", - "-": "zoom out", - "^": "raise region layer to top", - ">": "display next image", - "<": "display previous image", - "delete": "remove selected region", - "leftArrow": "move region/position left", - "upArrow": "move region/position up", - "rightArrow": "move region/position right", - "downArrow": "move region/position down" - }, // keyboard actions - mousetouchZoom: false, // use mouse wheel, pinch to zoom? - mousetouchLimit: true, // limit zoom-out to size of image? - metaClickPan: true, // metaKey + click pans to mouse position? - // statusBar: "$mag; $scale($scaleclipping); $img(images/voyager/color_$colormap.png) $colormap; $wcssys; $image", // status display - statusBar: "$colorbar; $colormap; $mag; $scale ($scalemin,$scalemax); $wcssys; $image0", // status display - toolbarTooltips: false, // display tooltips on toolbar? - updateTitlebar: true, // update titlebar when image changes? - centerDivs: ["JS9Menubar"], // divs which take part in JS9.Display.center() - resizeDivs: ["JS9Menubar", "JS9Colorbar", "JS9Toolbar", "JS9Statusbar"], // divs which take part in JS9.Display.resize() - pinchWait: 8, // number of events to wait before testing pinch - pinchThresh: 6, // threshold for pinch test - xeqPlugins: true, // execute plugin callbacks? - extendedPlugins: true, // enable extended plugin support? - intensivePlugins: false, // enable intensive plugin support? - dynamicSelect: "click", // dynamic plugins: "click", "move", or false - dynamicHighlight: true, // highlight dynamic selection - corsProxy: "https://js9.si.edu/cgi-bin/CORS-proxy.cgi", // CORS proxy - simbadProxy:"https://js9.si.edu/cgi-bin/simbad-proxy.cgi", // simbad proxy - cgiProxy: "https://js9.si.edu/cgi-bin/FITS-proxy.cgi", // CGI proxy - catalogs: {ras: ["RA", "_RAJ2000", "RAJ2000"], // cols to search for .. - decs: ["Dec", "_DEJ2000", "DEJ2000"],// when loading catalogs - shape: "circle", // object shape - color: "yellow", // object color - width: 7, // box object width - height: 7, // box object height - radius: 3.5, // circle object radius - r1: 5.0, // ellipse object r1 - r2: 3.5, // ellipse object r2 - wcssys: "ICRS", // wcs system - skip: "#\n", // skip # and blank lines - save: true, // save cat cols in shapes - tooltip: "$data.ra $data.dec"}, // tooltip format - topColormaps: ["grey", "heat", "cool", "turbo", "viridis", "magma", "sls", "red", "green", "blue"], // toplevel colormaps - infoBox: ["file", "object", "wcsfov", "wcscen", "wcspos", "impos", "physpos", "value", "regions", "progress"], - infoBoxResize: true, // is size based on wcs? - menuBar: ["file", "edit", "view", "zoom", "scale", "color", "region", "wcs", "analysis", "help"], - menubarStyle: "classic", // mac or classic - menuPosition: "right-5 bottom-5", // where menus pop up - menuClickEvent: "mouseup", // "click" or "mouseup" - menuSelected: "check", // selected option icon - menuImages: true, // show pngs in menu? - userMenus: false, // add user menus? - userMenuDivider: "   ", // divide before user menu - imagesFileSubmenu: 5, // how many images trigger a submenu? - toolBar: ["annulus", "box", "circle", "ellipse", "line", "polygon", "text", "zoom+", "zoom-", "zoom1", "zoomtofit"], - syncOps: ["alignment","colormap","contrastbias","flip","pan","regions","rotate", "rot90","scale","wcs","zoom"], // which ops are sync'ed? - syncReciprocate: true, // default value for reciprocal sync'ing - syncWCS: true, // default value for using WCS to sync - hiddenPluginDivs: [], // which static plugin divs start hidden - separate: {layout: "auto", leftMargin: 10, topMargin: 10}, // separate a display - imageTemplates: ".fits,.fts,.png,.jpg,.jpeg,.fz,.ftz,.gz", // templates for local images - wcsUnits: {FK4:"sexagesimal", FK5:"sexagesimal", ICRS:"sexagesimal", - galactic:"degrees", ecliptic:"degrees", linear:"degrees", - physical:"pixels", image:"pixels"}, // def units for wcs sys - wcsSetUpdatesDef: true, // does setWCSUnits() update the default? - wcsHlength: 256000, // hlength passed to astroem wcsninit() - regTemplates: ".reg", // templates for local region file input - sessionTemplates: ".ses,.js9ses",// templates for local session file input - colormapTemplates: ".cmap", // templates for local colormap file input - catalogTemplates: ".cat,.tab", // templates for local catalog file input - localTemplates: ".fits,.fts", // templates for local file access - controlsMatchRegion: false, // true, false, "corner" or "border" - internalColorPicker: true, // use HTML5 color picker, if available? - newWindowWidth: 530, // width of LoadWindow("new") - newWindowHeight: 625, // height of LoadWindow("new") - debug: 0 // debug level -}; - -// favorites are used in dialog boxes and control boxes -JS9.favorites = { - scales: ["linear", "log", "histeq"], - colormaps: ["cool", "heat", "viridis", "magma"], - regions: ["annulus", "box", "circle", "ellipse"], - wcs: ["FK5", "ICRS", "galactic:Galactic", "physical", "image"] -// you can specify a display string using a colon-separated string or array: -// wcs: ["FK5:fk5", ["ICRS","icrs"], "galactic", "physical", "image"] -}; - -// desktop (i.e. Electron.js) defaults -// always wrap access in if( window.electron ){} -JS9.desktopOpts = { - currentPath: true, // files relative to current dir? - sessionPath: true // session files relative to session file? -}; - -// image param defaults -JS9.imageOpts = { - inherit: false, // inherit props from previous image? - contrast: 1.0, // default color contrast - bias: 0.5, // default color bias - invert: false, // default colormap invert - exp: 1000, // default exp value for scaling - colormap: "grey", // default color map - overlay: true, // display png/jpeg overlay? - scale: "linear", // default scale algorithm - scaleclipping: "dataminmax", // "dataminmax", "zscale", or "user" (when scalemin, scalemax is supplied) - scalemin: Number.NaN, // default scale min is undefined - scalemax: Number.NaN, // default scale max is undefined - flip: "none", // default flip state - rot90: 0, // default 90 deg rotation state - rotate: 0, // default rotation state - zscalecontrast: 0.25, // default from ds9 - zscalesamples: 600, // default from ds9 - zscaleline: 120, // default from ds9 - wcssys: "native", // default WCS sys - lcs: "physical", // default logical coordinate system - valpos: true, // whether to display value/position - sigma: "none", // gauss blur sigma or none - opacity: 1.0, // opacity between 0 and 1 - alpha: 255, // alpha for image (but use opacity!) - nancolor: "#000000", // 6-digit #hex color for NaN values - nocolor: {red:0,green:0,blue:0,alpha:0} , // static color map no color - // xcen: 0, // default x center pos to pan to - // ycen: 0, // default y center pos to pan to - zoom: 1, // default zoom factor - zooms: 6, // how many zooms in each direction? - topZooms: 2, // how many zooms are at top level? - wcsalign: true, // align image using wcs after reproj? - rotationMode: "relative", // default: relative or absolute? - crosshair: false, // enable crosshair? - disable: [], // list of disabled core services - ltvbug: false, // add 0.5/ltm to image LTV values? - listonchange: false, // whether to list after a reg change - whichonchange: "selected" // which to list ("all" or "selected") -}; - -// allows regions opts (in Regions.opts) to be overridden via js9prefs.js -JS9.regionOpts = {}; -// allows catalog opts (in Catalogs.opts) to be overridden via js9prefs.js -JS9.catalogOpts = {}; -// allows crosshair opts (in Crosshair.opts) to be overridden via js9prefs.js -JS9.crosshairOpts = {}; -// allows grid opts (in Grid.opts) to be overridden via js9prefs.js -JS9.gridOpts = {}; -// allows emscripten opts (in Module) to be overridden via js9prefs.js -JS9.emscriptenOpts = {}; -// allows fabric opts (in Fabric.opts) to be overridden via js9prefs.js -JS9.fabricOpts = {}; -// socket.io options -JS9.socketioOpts = { - reconnection: true, - reconnectionDelay: 1000, - reconnectionDelayMax : 10000, - reconnectionAttempts: 100, - timeout: JS9.globalOpts.htimeout -}; -// defaults for blending -JS9.blendOpts = { - active: true, - mode: "screen", - opacity: 1.0 -}; - -// defaults for masking -JS9.maskOpts = { - active: false, - mode: "overlay", // "overlay", "mask", "opacity" - opacity: 1, // overlay opacity - vopacity: 0, // mask opacity - value: 0, // mask value - syncops: ["flip", "pan", "rot90", "zoom"], - invert: false -}; - -// defaults for analysis (macro expansion) -JS9.analOpts = { - // if this pattern is matched in stderr, throw a real error - epattern: /^(ERROR:[^\n]*)\n/, - // location of datapath's param html file - dpathURL: "params/datapath.html", - // location of filepath's param html file - fpathURL: "params/filepath.html" -}; - -// light window opts -JS9.lightOpts = { - nclick: 0, - dhtml: { - topid: "#dhtmlwindowholder", - top: ".dhtmlwindow", - drag: ".drag-contentarea", - dragBar: ".drag-handle", - format: "width=%spx,height=%spx,resize=%s,scrolling=0", - textWin: "width=830px,height=400px,resize=1,scrolling=1", - // NB: dimensions are tied to .JS9Plot CSS params - plotWin: "width=830px,height=420px,resize=1,scrolling=1", - dpathWin: "width=830px,height=175px,resize=1,scrolling=1", - lcloseWin:"width=512px,height=190px,resize=1,scrolling=1", - paramWin: "width=830px,height=235px,resize=1,scrolling=1", - regWin0: "width=640px,height=130px,resize=1,scrolling=1", - regWin1: "width=640px,height=200px,resize=1,scrolling=1", - regWin: "width=640px,height=470px,resize=1,scrolling=1", - imageWin: "width=512px,height=598px,resize=1,scrolling=1", - lineWin: "width=400px,height=60px,resize=1,scrolling=1" - }, - lcloseURL: "params/lightclose.html" -}; - -// colors for text messages -JS9.textColorOpts = { - regions: "#00FF00", - info: "#00FF00", - inimage: "#000000" -}; - -// help pages -JS9.helpOpts = { - user: { - heading: "JS9Help", - type: "help", url:"user.html", - title: "User Manual" - }, - install: { - heading: "JS9Help", - type: "help", url:"install.html", - title: "Installing JS9" - }, - webpage: { - heading: "JS9Help", - type: "help", url:"webpage.html", - title: "Adding JS9 to a Web Page" - }, - yourdata: { - heading: "JS9Help", - type: "help", url:"yourdata.html", - title: "Adding Data to a Web Page" - }, - localtasks: { - heading: "JS9Help", - type: "help", url:"localtasks.html", - title: "Adding Local Analysis Tasks and Plugins" - }, - helper: { - heading: "JS9Help", - type: "help", url:"helper.html", - title: "Adding Server-side Analysis Tasks" - }, - serverside: { - heading: "JS9Help", - type: "help", url:"serverside.html", - title: "Server-side Analysis with JS9" - }, - publicapi: { - heading: "JS9Help", - type: "help", url:"publicapi.html", - title: "The JS9 Public API" - }, - extmsg: { - heading: "JS9Help", - type: "help", url:"extmsg.html", - title: "External Messaging" - }, - desktop: { - heading: "JS9Help", - type: "help", url:"desktop.html", - title: "JS9 on the Desktop" - }, - python: { - heading: "JS9Help", - type: "help", url:"python.html", - title: "JS9 with Python and Jupyter" - }, - archives: { - heading: "JS9Help", - type: "help", url:"archives.html", - title: "Accessing Data Archives" - }, - preferences: { - heading: "JS9Help", - type: "help", url:"preferences.html", - title: "Setting Site Preferences" - }, - regions: { - heading: "JS9Help", - type: "help", url:"regions.html", - title: "Regions Format" - }, - changelog: { - heading: "JS9Help", - type: "help", url:"changelog.html", - title: "ChangeLog" - }, - repfile: { - heading: "JS9Help", - type: "help", url:"repfile.html", - title: "Dealing with Large Files" - }, - memory: { - heading: "JS9Help", - type: "help", url:"memory.html", - title: "Dealing with Memory Limitations" - }, - issues: { - heading: "JS9Help", - type: "help", url:"knownissues.html", - title: "Known Issues" - }, - security: { - heading: "JS9Help", - type: "help", url:"securityissues.html", - title: "Security Issues" - } -}; - -// containers for groups of JS9 objects -JS9.images = []; // array of current images -JS9.displays = []; // array of current display canvases -JS9.colormaps = []; // array of current colormaps -JS9.commands = []; // array of commands -JS9.plugins = []; // array of defined plugins -JS9.preloads = []; // array of images to preload -JS9.auxFiles = []; // array of auxiliary files -JS9.supermenus = []; // array containing supermenu instances -JS9.preloadwaiting = []; // array of images currently being preloaded -JS9.publics = {}; // object containing defined public API calls -JS9.helper = {}; // only one helper per page, please -JS9.fits = {}; // object holding FITS access routines -JS9.userOpts = {}; // object to hold localStorage opts -JS9.tmp = {}; // global temp area -// misc params -// list of scales in mkScaledCells -JS9.scales = ["linear", "log", "histeq", "power", "sqrt", "squared", "asinh", "sinh"]; - -// list of known wcs systems -JS9.wcssyss = ["FK4", "FK5", "ICRS", "galactic", "ecliptic", - "physical", "image", "native"]; - -// list of known wcs units -JS9.wcsunitss = ["degrees", "sexagesimal", "pixels"]; - -// list of known regions -JS9.regions = ["annulus", "box", "circle", "cross", "ellipse", "line", "point", - "polygon", "text"]; - -// known bugs and work-arounds -JS9.bugs = {}; -// sometimes hiding the menu does not refresh the image properly -// JS9.bugs.hide_menu = true; -// turned off: 6/30/16 -JS9.bugs.hide_menu = false; -// firefox does not repaint as needed (last checked FF 24.0 on 10/20/13) -if( (JS9.BROWSER[0] === "Firefox") && JS9.BROWSER[2].search(/Linux/) >=0 ){ - JS9.bugs.firefox_linux = true; -} -// webkit resize is not quite up to par -// if( (JS9.BROWSER[0] === "Chrome") || (JS9.BROWSER[0] === "Safari") ){ -// only safari seems to need the extra border (4/18/20) -if( (JS9.BROWSER[0] === "Safari") ){ - JS9.bugs.webkit_resize = true; -} - -// wasm broken in ios 11.2.2, 11.2.5 and on, fixed in 11.3beta1 (1/22/2018) -// see: https://github.com/kripken/emscripten/issues/6042 -if( /iPad|iPhone|iPod/.test(navigator.platform) && - /11_2_(?:[2-9])/.test(navigator.userAgent) ){ - JS9.globalOpts.useWasm = false; -} -// iOS and presumably android has severe memory limits (05/2017) -// also force user to turn on crosshair, since it works with one finger -// also, iOS requires wider region dialog boxes to fit the buttons -if( JS9.BROWSER[3] ){ - JS9.globalOpts.maxMemory = Math.min(JS9.globalOpts.maxMemory, 350000000); - JS9.globalOpts.table.xdim = 2048; - JS9.globalOpts.table.ydim = 2048; - JS9.globalOpts.image.xdim = 2048; - JS9.globalOpts.image.ydim = 2048; - JS9.imageOpts.crosshair = false; - JS9.globalOpts.reproj = {xdim: 2048, ydim: 2048}; - JS9.lightOpts.dhtml.regWin0="width=660px,height=130px,resize=1,scrolling=1"; - JS9.lightOpts.dhtml.regWin1="width=660px,height=200px,resize=1,scrolling=1"; - JS9.lightOpts.dhtml.regWin="width=660px,height=470px,resize=1,scrolling=1"; -} -// Jupyter doesn't seem to be able to load wasm (7/4/2018) -if( {}.hasOwnProperty.call(window, "Jupyter") ){ - JS9.globalOpts.useWasm = false; -} -// JS9 desktop app using Electron.js -if( window.electron ){ - // Emscripten mount point for local file system, based on hostname - if( window.electron.hostFS ){ - JS9.hostFS = window.electron.hostFS; - } - // if multiple instances are running, turn off localStorage - if( window.electron.multiElectron ){ - JS9.globalOpts.localStorage = false; - } - // once recommended by Electron, they removed this by 8.0.0 - // still seems worthwhile, but let's put it here instead of passing it in - if( typeof window.eval === "function" ){ - window.eval = function(){ - throw new Error('For security reasons, Desktop JS9 does not support window.eval()'); - } - } - // cmdlineOpts are opts used by the app to specify the command line - if( window.electron.cmdlineOpts ){ - try{ JS9.cmdlineOpts = JSON.parse(window.electron.cmdlineOpts); } - catch(e){ delete JS9.cmdlineOpts; } - } -} - -// --------------------------------------------------------------------- -// JS9 Image object to manage images -// --------------------------------------------------------------------- - -JS9.Image = function(file, params, func){ - let i, card, pars, nzoom, display, txeq, tval; - let localOpts = null; - let nhist = 0; - let ncomm = 0; - // called with current image context - const mkscale = (opts) => { - // do zscale, if necessary - opts = opts || {}; - if( JS9.isNull(opts.scaleclipping) ){ - if( this.params.scaleclipping === "zscale" ){ - this.zscale(true); - } else if( this.params.scaleclipping === "zmax" ){ - this.zscale("zmax"); - } - } else { - if( opts.scaleclipping === "zscale" ){ - this.zscale(true); - } else if( opts.scaleclipping === "zmax" ){ - this.zscale("zmax"); - } - } - if( JS9.notNull(opts.scalemin) ){ - this.params.scalemin = opts.scalemin; - } - if( JS9.notNull(opts.scalemax) ){ - this.params.scalemax = opts.scalemax; - } - }; - // called with current image context - const finishUp = (func) => { - let i, s, topts, tkey, id, pre, waiting, plen, im; - const imopts = JS9.globalOpts.imopts; - const imcmap = JS9.globalOpts.imcmap; - const oalerts = JS9.globalOpts.alerts; - const rregexp = /(annulus|box|circle|ellipse|line|polygon|point|text) *\(/; - // add to list of images - JS9.images.push(this); - // clear previous messages - this.display.clearMessage(); - // if flip, rotate, rot90 opts were supplied, set transform - if( localOpts ){ - if( JS9.notNull(localOpts.flip) || - JS9.notNull(localOpts.rotate) || - JS9.notNull(localOpts.rot90) ){ - this.setTransform(); - } - } - // display image, 2D graphics, etc. - this.displayImage("all", localOpts); - // notify the helper - this.notifyHelper(); - // show regions layer - this.showShapeLayer("regions", true, {local: true}); - if( localOpts ){ - // pan, if necessary - if( (JS9.notNull(localOpts.x) && JS9.notNull(localOpts.y)) || - (JS9.notNull(localOpts.px) && JS9.notNull(localOpts.py)) || - (JS9.notNull(localOpts.ra) && JS9.notNull(localOpts.dec)) || - (JS9.notNull(localOpts.wcs)) ){ - this.setPan(localOpts); - } - // add regions, if necessary - if( localOpts.regions ){ - if( localOpts.regions.match(rregexp) ){ - this.addShapes("regions", localOpts.regions); - } else { - JS9.LoadRegions(localOpts.regions, {display:this.display}); - } - } - } - // no alerts while processing imopts or cmaps - JS9.globalOpts.alerts = false; - // looks for imcmap (json-formatted colormap object) in FITS header - if( this.raw && this.raw.header && this.raw.header[imcmap] ){ - // try to convert to object and set as image params - try{ topts = JSON.parse(this.raw.header[imcmap]); } - catch(e){ topts = null; } - if( topts ){ - try{ JS9.AddColormap(topts); } - catch(e){ /* empty */ } - } - } - // look for multi-line colormap (imcmap1, imcmap2, ...) in FITS header - tkey = `${imcmap}1`; - if( this.raw && this.raw.header && this.raw.header[tkey] ){ - // gather up the json string - for(i=1, s=""; i<100; i++){ - tkey = imcmap + String(i); - if( this.raw.header[tkey] ){ - s += this.raw.header[tkey]; - } else { - break; - } - } - // try to convert to object and set as image params - if( s ){ - try{ topts = JSON.parse(s); } - catch(e){ topts = null; } - if( topts ){ - try{ JS9.AddColormap(topts); } - catch(e){ /* empty */ } - } - } - } - // looks for imopts (json-formatted image param object) in FITS header - if( this.raw && this.raw.header && this.raw.header[imopts] ){ - // try to convert to object and set as image params - try{ topts = JSON.parse(this.raw.header[imopts]); } - catch(e){ topts = null; } - if( topts ){ - try{ this.setParam("all", topts); } - catch(e){ /* empty */ } - } - } - // look for multi-line imopts (imopts1, imopts2, ...) in FITS header - tkey = `${imopts}1`; - if( this.raw && this.raw.header && this.raw.header[tkey] ){ - // gather up the json string - for(i=1, s=""; i<100; i++){ - tkey = imopts + String(i); - if( this.raw.header[tkey] ){ - s += this.raw.header[tkey]; - } else { - break; - } - } - // try to convert to object and set as image params - if( s ){ - try{ topts = JSON.parse(s); } - catch(e){ topts = null; } - if( topts ){ - try{ this.setParam("all", topts); } - catch(e){ /* empty */ } - } - } - } - // restore alerts - JS9.globalOpts.alerts = oalerts; - // plugin callbacks - this.xeqPlugins("image", "onimageload"); - // load is complete - this.setStatus("load","complete"); - // done loading, reset wait cursor - JS9.waiting(false); - // everything else is done so call onload func, if necessary - if( func ){ - try{ JS9.xeqByName(func, window, this); } - catch(e){ JS9.error("in image onload callback", e, false); } - } - // might need to finish processing of preloads - if( JS9.preloadwaiting && JS9.preloadwaiting.length ){ - plen = JS9.preloadwaiting.length; - id = this.proxyURL || this.file; - // flag that this preload is loaded - for(i=0, waiting=0; i { - let ai = 0, bi = 0; - for(i=0; i 0 ){ - this.displayExtension("all"); - } - }; - // params can be an object containing local params, or the display string - if( params ){ - if( typeof params === "object" ){ - localOpts = params; - if( localOpts.display ){ - display = localOpts.display; - } - } else { - display = params; - } - } - // make sure we have a valid display - if( !display ){ - if( JS9.displays.length > 0 ){ - display = JS9.displays[0].id; - } else { - display = JS9.DEFID; - } - } - // save url, if available - // it's an image - this.type = "image"; - // set the display - this.display = JS9.lookupDisplay(display); - // initialize image params - this.params = {}; - // region stack for saving removed regions - this.regstack = []; - // image-specific scratch space - this.tmp = {}; - // current groups for each layer - this.groups = {}; - // xeq callback for region changes? - this.params.xeqonchange = true; - // copy image parameters - this.params = $.extend(true, this.params, JS9.imageOpts, localOpts); - // inherit properties, if necessary - if( this.display.image ){ - this.params.inherit = this.display.image.params.inherit; - if( this.params.inherit ){ - this.params = $.extend(true, - this.params, this.display.image.params); - } - } - // (turn off plugin call, since we are not fully loaded) - txeq = JS9.globalOpts.xeqPlugins; - // save overlay (setting colormap turns it off) - tval = this.params.overlay; - JS9.globalOpts.xeqPlugins = false; - this.setColormap(this.params.colormap); - this.params.overlay = tval; - JS9.globalOpts.xeqPlugins = txeq; - // do we display? - this.displayMode = true; - // initialize click state - this.clickState = 0; - // initialize click in region - this.clickInRegion = false; - this.clickInLayer = null; - // no helper queried yet - this.queried = false; - // is this a proxy image? - if( localOpts && localOpts.proxyFile ){ - this.proxyFile = localOpts.proxyFile; - } - // is there a proxy parent? - if( localOpts && localOpts.proxyParent ){ - this.proxyParent = localOpts.proxyParent; - } - if( localOpts && localOpts.proxyURL ){ - this.proxyURL = localOpts.proxyURL; - } - // was a "parent" FITS file specified? - if( localOpts && localOpts.parentFile ){ - this.parentFile = localOpts.parentFile; - } - // was "parent" info specified? - if( localOpts && localOpts.parent ){ - this.parent = localOpts.parent; - // convert card string to header - if( this.parent.cardstr && this.parent.ncard ){ - this.parent.raw = {header: {}, history:[], comments: []}; - for(i=0; i { - let ss; - if( (this.png.image.width !== this.raw.width) || - (this.png.image.height !== this.raw.height) ){ - ss = sprintf("rgb dims [%s,%s] don't match image [%s,%s]", - this.png.image.width, - this.png.image.height, - this.raw.width, - this.raw.height); - JS9.error(ss); - } - // store png data in an offscreen canvas - this.mkOffScreenCanvas(); - // finish up - finishUp(func); - }).on("error", () => { - // done loading, reset wait cursor - JS9.waiting(false); - JS9.error(`could not load image: ${this.id}`); - }); - // set src to download the display file - this.png.image.src = this.rgbFile; - } else { - // finish up - finishUp(func); - } - break; - default: - JS9.error(`unknown specification type for Load: ${typeof file}`); - break; - } -}; - -// return the image data in a relatively standard format -JS9.Image.prototype.getImageData = function(dflag){ - let data = null; - const {xdim, ydim} = this.fileDimensions(); - const atob64 = (a) => { - let i; - let s = ''; - const bytes = new Uint8Array(a.buffer); - const len = bytes.byteLength; - for(i=0; i=0; i--){ - tim = JS9.images[i]; - if( this.display === tim.display ){ - // display image, 2D graphics, etc. - tim.displayImage("all"); - tim.refreshLayers(); - // signal we're done - iscurrent = JS9.images.length; - break; - } - } - for(i=JS9.images.length-1; i>iscurrent; i--){ - tim = JS9.images[i]; - if( this.display === tim.display ){ - // display image, 2D graphics, etc. - tim.displayImage("all"); - tim.refreshLayers(); - break; - } - } - } -}; - -// make offscreen canvas to hold RGB data from the png file -JS9.Image.prototype.mkOffScreenCanvas = function(){ - // sanity check - if( !this.png || !this.png.image ){ return this; } - // offscreen object holds canvas into which we draw to get RGB values - // no need for jquery here, we only manipulate this via the canvas API - this.offscreen = {}; - this.offscreen.canvas = document.createElement("canvas"); - this.offscreen.canvas.setAttribute("width", this.png.image.width); - this.offscreen.canvas.setAttribute("height", this.png.image.height); - this.offscreen.context = this.offscreen.canvas.getContext("2d"); - // turn off anti-aliasing - if( !JS9.ANTIALIAS ){ - this.offscreen.context.imageSmoothingEnabled = false; - } - // draw the png to the offscreen canvas - this.offscreen.context.drawImage(this.png.image, 0, 0); - // read the RGBA data from offscreen - try{ - this.offscreen.img = this.offscreen.context.getImageData(0, 0, - this.png.image.width, this.png.image.height); - } catch(e){ - if( JS9.CHROMEFILEWARNING && - (JS9.BROWSER[0] === "Chrome") && (document.domain === "") ){ - alert("When using the file:// URI, Chrome must be run with the --allow-file-access-from-files switch to permit JS9 to access data."); - } else { - alert("could not read off-screen image data [same-origin policy violation?]"); - } - } - // allow chaining - return this; -}; - -JS9.Image.prototype.useOffScreenCanvas = function(){ - return this.offscreen && (this.rgbFile || this.params.overlay); -}; - -// initialize keywords for various logical coordinate systems -JS9.Image.prototype.initLCS = function(iheader){ - let i, tval, rrot, frot, a, sina, cosa; - const arr = [[0,0,0], [0,0,0], [0,0,0]]; - // header usually is raw header - const header = iheader || this.raw.header; - const cx = header.CRPIX1 || 1; - const cy = header.CRPIX2 || 1; - // seed rotation matrix and its inverse, if necessary - if( header.LCSROTA2 && header.CROTA2 ){ - // screen rotation angle is reversed from FITS convention - a = -header.CROTA2 * Math.PI / 180.0; - sina = Math.sin(a); - cosa = Math.cos(a); - frot = [[0,0,0], [0,0,0], [0,0,0]]; - frot[0][0] = cosa; - frot[0][1] = -sina; - frot[0][2] = 0; - frot[1][0] = sina; - frot[1][1] = cosa; - frot[1][2] = 0; - rrot = JS9.invertMatrix3(frot); - if( !rrot ){ - frot = null; - } - } - // physical coords - arr[0][0] = JS9.defNull(header.LTM1_1, 1.0); - arr[1][0] = header.LTM2_1 || 0.0; - arr[0][1] = header.LTM1_2 || 0.0; - arr[1][1] = JS9.defNull(header.LTM2_2, 1.0); - arr[2][0] = header.LTV1 || 0.0; - arr[2][1] = header.LTV2 || 0.0; - if( this.imtab === "image" && this.params.ltvbug ){ - // There seems to be a tiny misalignment between wcs->image and - // physical->image when ltv is involved. No idea why, but the fix is: - // (set default to false after implementing rot90/flip 10/6/2019 ... - // on the fear this is doing more harm than good) - if( JS9.notNull(header.LTV1) ){ - for(i=0; i<2; i++){ - tval = Math.abs(arr[0][i]); - if( tval > 0 && tval < 1 ){ arr[2][0] += tval * 0.5; } - } - } - if( JS9.notNull(header.LTV2) ){ - for(i=0; i<2; i++){ - tval = Math.abs(arr[1][i]); - if( tval > 0 && tval < 1 ){ arr[2][1] += tval * 0.5; } - } - } - } - this.lcs.physical = {forward: $.extend(true, [], arr), - reverse: JS9.invertMatrix3(arr)}; - if( this.lcs.physical.reverse ){ - if( frot ){ - this.lcs.physical.frot = $.extend(true, [], frot); - this.lcs.physical.rrot = $.extend(true, [], rrot); - // zero-index center - this.lcs.physical.cx = cx - arr[2][0] - 1; - this.lcs.physical.cy = cy - arr[2][1] - 1; - } - } else { - delete this.lcs.physical; - } - // detector coordinates - arr[0][0] = JS9.defNull(header.DTM1_1, 1.0); - arr[1][0] = header.DTM2_1 || 0.0; - arr[0][1] = header.DTM1_2 || 0.0; - arr[1][1] = JS9.defNull(header.DTM2_2, 1.0); - arr[2][0] = header.DTV1 || 0.0; - arr[2][1] = header.DTV2 || 0.0; - this.lcs.detector = {forward: $.extend(true, [], arr), - reverse: JS9.invertMatrix3(arr)}; - if( this.lcs.detector.reverse ){ - if( frot ){ - this.lcs.detector.frot = $.extend(true, [], frot); - this.lcs.detector.rrot = $.extend(true, [], rrot); - // zero-index center - this.lcs.detector.cx = cx - arr[2][0] - 1; - this.lcs.detector.cy = cy - arr[2][1] - 1; - } - } else { - delete this.lcs.detector; - } - // amplifier coordinates - arr[0][0] = JS9.defNull(header.ATM1_1, 1.0); - arr[1][0] = header.ATM2_1 || 0.0; - arr[0][1] = header.ATM1_2 || 0.0; - arr[1][1] = JS9.defNull(header.ATM2_2, 1.0); - arr[2][0] = header.ATV1 || 0.0; - arr[2][1] = header.ATV2 || 0.0; - this.lcs.amplifier = {forward: $.extend(true, [], arr), - reverse: JS9.invertMatrix3(arr)}; - if( this.lcs.amplifier.reverse ){ - if( frot ){ - this.lcs.amplifier.frot = $.extend(true, [], frot); - this.lcs.amplifier.rrot = $.extend(true, [], rrot); - // zero-index center - this.lcs.amplifier.cx = cx - arr[2][0] - 1; - this.lcs.amplifier.cy = cy - arr[2][1] - 1; - } - } else { - delete this.lcs.amplifier; - } - // reset lcs to image, if necessary - if( this.params && !this.lcs[this.params.lcs] ){ - this.params.lcs = "image"; - } - // set current, if not already done - if( this.params && !this.params.wcssys0 ){ - this.setWCSSys("physical"); - this.params.wcssys0 = this.params.lcs; - } - // save original physical - if( this.lcs.physical && !this.lcs.ophysical ){ - this.lcs.ophysical = $.extend(true, {}, this.lcs.physical); - } - // allow chaining - return this; -}; - -// read input object and convert to image data -JS9.Image.prototype.mkRawDataFromHDU = function(obj, opts){ - let i, s, ui, clen, hdu, pars, card, got, rlen, rmvfile, done, frheap; - let oraw, owidth, oheight, obitpix, owcssys, owcsunits; - let header, x1, y1, bin; - let nhist = 0; - let ncomm = 0; - opts = opts || {}; - if( $.isArray(obj) || JS9.isTypedArray(obj) || obj instanceof ArrayBuffer ){ - // flatten if necessary - if( $.isArray(obj[0]) ){ - obj = obj.reduce( (a, b) => { return a.concat(b); }); - } - // javascript array or typed array - hdu = {image: obj}; - } else if( typeof obj === "object" ){ - // fits object - hdu = obj; - } else { - JS9.error("unknown or missing input for HDU creation"); - } - // allow image to be passed in data property - if( hdu.data && !hdu.image ){ - hdu.image = hdu.data; - } - // better have the image ... - if( !hdu.image ){ - JS9.error(`data missing from JS9 FITS object: ${JSON.stringify(hdu)}`); - } - // quick check for 1D images (in case naxis is defined) - if( hdu.naxis < 2 ){ - JS9.error("can't image a FITS file with less than 2 dimensions"); - } - // save old essential values, if possible (for use as defaults) - // free previous WCS, if possible - if( this.raw ){ - oraw = this.raw; - owidth = this.raw.width; - oheight = this.raw.height; - obitpix = this.raw.bitpix; - owcssys = this.params.wcssys; - owcsunits = this.params.wcsunits; - this.freeWCS(); - } - // initialize raws array? - this.raws = this.raws || []; - rlen = this.raws.length; - if( !rlen ){ - // create object to hold raw data and add to raws array - this.raws.push({from: "hdu"}); - // assign this object to the high-level raw data object - this.raw = this.raws[rlen]; - // ignore rawid, this is the default raw data - this.raw.id = JS9.RAWID0; - } else { - opts.rawid = opts.rawid || JS9.RAWIDX; - // reuse raw object with the same id, after re-initializing it - got = 0; - for(i=0; i { return a.concat(b); }); - } - // make the raw data: note in the case of a typed array coming from - // the Emscripten heap, this is a copy, so we can free the heap immediately - // (done below iff clearImageMemory contains the "heap" directive). - // I didn't realize new XXXArray(typedArray) makes a copy, but see: - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray - switch(this.raw.bitpix){ - case 8: - this.raw.data = new Uint8Array(hdu.image); - break; - case 16: - this.raw.data = new Int16Array(hdu.image); - break; - case -16: - this.raw.data = new Uint16Array(hdu.image); - break; - case 32: - this.raw.data = new Int32Array(hdu.image); - break; - case -32: - this.raw.data = new Float32Array(hdu.image); - break; - case -64: - this.raw.data = new Float64Array(hdu.image); - break; - default: - JS9.error(`unsupported bitpix: ${this.raw.bitpix}`); - break; - } - // array of cards - this.raw.card = hdu.card; - // cfitsio returns these: - this.raw.cardstr = hdu.cardstr; - this.raw.ncard = hdu.ncard; - // look for header - if( hdu.head ){ - this.raw.header = hdu.head; - } else if( this.raw.card ){ - this.raw.header = {}; - // make up header from array of raw cards - clen = this.raw.card.length; - for(i=0; i 0) ){ - this.file = this.file.replace(/\[.*\]/, ""); - this.file += `[${opts.extnum}]`; - } - if( hdu.fits ){ - if( opts.extname ){ - hdu.fits.extname = opts.extname; - } - if( opts.extnum && (opts.extnum > 0) ){ - hdu.fits.extnum = opts.extnum; - } - } - } else if( hdu.fits ){ - if( hdu.fits.extname ){ - this.file = this.file.replace(/\[.*\]/, ""); - this.file += `[${hdu.fits.extname}]`; - } else if( hdu.fits.extnum && (hdu.fits.extnum > 0) ){ - this.file = this.file.replace(/\[.*\]/, ""); - this.file += `[${hdu.fits.extnum}]`; - } - } else if( this.raw.header ){ - if( this.raw.header.EXTNAME ){ - this.file = this.file.replace(/\[.*\]/, ""); - this.file += `[${this.raw.header.EXTNAME}]`; - } - } - } - // last chance: get it from the file - if( !this.id ){ - // save id in case we have to change it for uniqueness - this.id0 = (this.parentFile||this.file).split("/").reverse()[0]; - // get a unique id for this image - this.id = JS9.getImageID(this.id0, this.display.id, this); - } - // is this a proxy image? - if( opts.proxyFile ){ - this.proxyFile = opts.proxyFile; - } - // save filter, if necessary - this.raw.filter = opts.filter || ""; - this.raw.columns = opts.columns || ""; - // image or table? - if( hdu.imtab ){ - this.imtab = hdu.imtab; - } else { - this.imtab = hdu.table ? "table" : "image"; - } - // also associate imtab with this raw layer - this.raw.imtab = this.imtab; - // min and max data values - if( hdu.dmin !== undefined && hdu.dmax !== undefined ){ - // data min and max in object - this.dataminmax(hdu.dmin, hdu.dmax); - } else { - // calculate data min and max - this.dataminmax(); - } - // object, telescope, instrument names - this.object = this.raw.header.OBJECT; - this.telescope = this.raw.header.TELESCOP; - this.instrument = this.raw.header.INSTRUME; - // see if binning was passed to us in opts, e.g. from external imsection - // (internally, it's ordinarily in hdu or hdu.table) - if( opts.binstr ){ - try{ s = opts.binstr.split(/\s+/); - if( s && s.length === 2 ){ - if( (this.imtab === "table") && hdu.table ){ - hdu.table.bin = parseFloat(s[0]); - hdu.table.binMode = s[1]; - } else { - hdu.bin = parseFloat(s[0]); - hdu.binMode = s[1]; - } - } - } - catch(ignore){ /* empty */ } - } - // reset binning properties, as necessary - if( (this.imtab === "table") && hdu.table ){ - this.binning.bin = hdu.table.bin || 1; - } else if( hdu.bin ){ - this.binning.bin = hdu.bin > 0 ? hdu.bin : 1 / Math.abs(hdu.bin); - } else { - this.binning.bin = 1; - } - // make sure obin matches bin for previous load of data - if( !oraw ){ - this.binning.obin = this.binning.bin; - } - // reset the wcssys and wcsunits to previous, if necessary - if( owcssys ){ - this.setWCSSys(owcssys); - } - if( owcsunits ){ - this.setWCSUnits(owcsunits); - } - // init WCS, if necessary - if( oraw && oraw.header.CTYPE1 && oraw.header.CTYPE2 && - this.raw.header.CTYPE1 && this.raw.header.CTYPE2 && - (oraw.header.CTYPE1 !== this.raw.header.CTYPE1 || - oraw.header.CTYPE2 !== this.raw.header.CTYPE2) ){ - this.initWCS(); - } - // save offscreen data if necessary - if( JS9.notNull(hdu.offscreen) ){ - this.png = {image: hdu.offscreen}; - this.mkOffScreenCanvas(); - } - // re-init wcs - this.initWCS(); - // init the logical coordinate system, if possible - this.initLCS(); - // get hdu info, if possible - try{ - if( opts.hdus ){ - this.hdus = opts.hdus; - } else if( this.parentFile && - JS9.helper.connected && JS9.helper.js9helper ){ - obj = { - id: this.expandMacro("$id"), - cmd: this.expandMacro("js9Xeq listhdus $filename"), - image: this.file, - fits: this.parentFile, - rtype: "text" - }; - JS9.helper.send("listhdus", obj, (obj) => { - if( obj.stderr ){ - return; - } - if( obj.errcode ){ - return; - } - if( obj.stdout ){ - try{ this.hdus = JSON.parse(obj.stdout); } - catch(e) { this.hdus = null; } - } - }); - } else if( this.raw.hdu && this.raw.hdu.fits ){ - s = JS9.listhdu(this.raw.hdu.fits.vfile); - if( s ){ - try{ this.hdus = JSON.parse(s); } - catch(e) { this.hdus = null; } - } - } - } - catch(ignore){ /* empty */ } - // can we remove the virtual file? - if( this.raw.hdu && this.raw.hdu.fits && this.raw.hdu.fits.vfile ){ - s = JS9.globalOpts.clearImageMemory; - if( s === false ){ - s = ["never"]; - } else if( s === true ){ - s = ["always"]; - } else { - s = s.toLowerCase().split(/[,>]/); - } - rmvfile = false; - frheap = false; - // all conditions must be met ... - for(i=0, done=false; i s[i+1]*1000000 ){ - rmvfile = true; - } else { - rmvfile = false; - done = true; - } - } else { - rmvfile = false; - done = true; - } - break; - default: - break; - } - } - // remove virtual file and/or heap space - if( rmvfile ){ - if( JS9.DEBUG > 2 ){ - JS9.log("removing underlying FITS vfile for %s: %s", - this.id, this.raw.hdu.fits.vfile); - } - JS9.cleanupFITSFile(this.raw, true); - } else if( frheap ){ - if( JS9.DEBUG > 2 ){ - JS9.log("freeing heap space for %s: %s", - this.id, this.raw.hdu.fits.vfile); - } - JS9.cleanupFITSFile(this.raw, false); - } - } - // plugin callbacks - this.xeqPlugins("image", "onrawdata"); - // allow chaining - return this; -}; - -// store section information -JS9.Image.prototype.mkSection = function(...args){ - let s, xtra; - const sect = this.rgb.sect; - const getWidth = (zoom) => { - let len; - let canvas = this.display.canvas; - if( this.params.transformAngle ){ - len = Math.max(canvas.width, canvas.height); - return Math.min(this.raw.width * zoom, len); - } else { - return Math.min(this.raw.width * zoom, canvas.width); - } - }; - const getHeight = (zoom) => { - let len; - let canvas = this.display.canvas; - if( this.params.transformAngle ){ - len = Math.max(canvas.width, canvas.height); - return Math.min(this.raw.height * zoom, len); - } else { - return Math.min(this.raw.height * zoom, canvas.height); - } - }; - // save zoom in case we are about to change it (regions have to be scaled) - sect.ozoom = sect.zoom; - // process args - switch(args.length){ - case 0: - // no args: init to display central part of image - sect.xcen = Math.floor(this.raw.width/2); - sect.ycen = Math.floor(this.raw.height/2); - sect.width = getWidth(1); - sect.height = getHeight(1); - break; - case 1: - if( !JS9.isNumber(args[0]) ){ - JS9.error(`invalid input for generating section: ${args[0]}`); - } - sect.zoom = parseFloat(args[0]); - sect.width = getWidth(sect.zoom); - sect.height = getHeight(sect.zoom); - break; - case 2: - // two args: x, y - if( !JS9.isNumber(args[0]) || !JS9.isNumber(args[1]) ){ - JS9.error(`invalid input for generating section: ${args[0]} ${args[1]}`); - } - sect.xcen = parseFloat(args[0]); - sect.ycen = parseFloat(args[1]); - // reset width and height if there was a section offset - if( JS9.notNull(sect.ix) ){ - sect.width = getWidth(sect.zoom); - } - if( JS9.notNull(sect.iy) ){ - sect.height = getHeight(sect.zoom); - } - break; - case 3: - // three args: x, y, zoom - if( !JS9.isNumber(args[0]) || - !JS9.isNumber(args[1]) || - !JS9.isNumber(args[2]) ){ - JS9.error(`invalid input for generating section: ${args[0]} ${args[1]} ${args[2]}`); - } - sect.xcen = parseFloat(args[0]); - sect.ycen = parseFloat(args[1]); - sect.zoom = parseFloat(args[2]); - sect.width = getWidth(sect.zoom); - sect.height = getHeight(sect.zoom); - break; - default: - break; - } - // assume no offset when displaying section - delete sect.ix; - delete sect.iy; - // calculate section limits from center and dimensions - sect.x0 = sect.xcen - (sect.width/(2*sect.zoom)); - sect.y0 = sect.ycen - (sect.height/(2*sect.zoom)); - sect.x1 = sect.xcen + (sect.width/(2*sect.zoom)); - sect.y1 = sect.ycen + (sect.height/(2*sect.zoom)); - // make sure we're within bounds while maintaining section dimensions - if( sect.x0 < 0 ){ - if( JS9.globalOpts.panWithinDisplay ){ - sect.x1 -= sect.x0; - } else { - sect.ix = sect.x0 * sect.zoom; - } - sect.x0 = 0; - } - if( sect.y0 < 0 ){ - if( JS9.globalOpts.panWithinDisplay ){ - sect.y1 -= sect.y0; - } else { - sect.iy = sect.y0 * sect.zoom; - } - sect.y0 = 0; - } - if( sect.x1 > this.raw.width ){ - if( JS9.globalOpts.panWithinDisplay ){ - sect.x0 -= (sect.x1 - this.raw.width); - } else { - sect.ix = (sect.x1 - this.raw.width) * sect.zoom; - } - sect.x1 = this.raw.width; - } - if( sect.y1 > this.raw.height ){ - if( JS9.globalOpts.panWithinDisplay ){ - sect.y0 -= (sect.y1 - this.raw.height); - } else { - sect.iy = (sect.y1 - this.raw.height) * sect.zoom; - } - sect.y1 = this.raw.height; - } - // for offset images, maybe display more of the image - if( sect.ix > 0 && sect.x0 > 0 ){ - xtra = Math.min(sect.ix, sect.x0); - sect.x0 -= xtra; - sect.ix += xtra * sect.zoom; - } - if( sect.ix < 0 && sect.x1 < this.raw.width ){ - xtra = Math.min(this.raw.width - sect.x1, Math.abs(sect.ix)); - sect.x1 += xtra; - sect.ix -= xtra * sect.zoom; - } - if( sect.iy > 0 && sect.y0 > 0 ){ - xtra = Math.min(sect.iy, sect.y0); - sect.y0 -= xtra; - sect.iy += xtra * sect.zoom; - } - if( sect.iy < 0 && sect.y1 < this.raw.height ){ - xtra = Math.min(this.raw.height - sect.y1, Math.abs(sect.iy)); - sect.y1 += xtra; - sect.iy -= xtra * sect.zoom; - } - // final check: make sure we're within bounds - sect.x0 = Math.max(0, sect.x0); - sect.x1 = Math.min(this.raw.width, sect.x1); - sect.y0 = Math.max(0, sect.y0); - sect.y1 = Math.min(this.raw.height, sect.y1); - // final integer dimensions - sect.x0 = Math.floor(sect.x0); - sect.y0 = Math.floor(sect.y0); - sect.x1 = Math.floor(sect.x1); - sect.y1 = Math.floor(sect.y1); - // final section limits: derive new width and height - sect.width = Math.ceil((sect.x1 - sect.x0) * sect.zoom); - sect.height = Math.ceil((sect.y1 - sect.y0) * sect.zoom); - // sanity check - if( sect.width <= 0 || sect.height <= 0 ){ - s = sprintf("invalid image section: %s,%s [%s,%s, %s,%s, %s]", - sect.width, sect.height, - sect.x0, sect.y0, sect.x1, sect.y1, - sect.zoom); - JS9.error(s); - } - // put zoom back into params - this.params.zoom = sect.zoom; - // allow chaining - return this; -}; - -// create colormap index array from data values and specified data min/max -// from: tksao1.0/frame/frametruecolor.C -JS9.Image.prototype.mkColorData = function(){ - let i, dd, idata, odata; - const ss = JS9.SCALESIZE; - const length = ss - 1; - const dmin = this.params.scalemin; - const dmax = this.params.scalemax; - const dlen = this.raw.width * this.raw.height; - const diff = dmax - dmin; - const dval = length / diff; - // skip if colormap is static - if( this.cmapObj.type === "static" ){ - return this; - } - // allocate array - if( !this.colorData || this.colorData.length < dlen ){ - this.colorData = new Int32Array(dlen); - } - // Important note 7/13/2020: - // Chrome 83.0.4103.116 was taking either 4ms ... or 2+ seconds to do - // this loop on a 2048x2048 int image (casa.fits in js9debug.html). - // Replacing this.raw.data and this.colorData with local variables seems - // to fix this slowdown. omg ... - idata = this.raw.data; - odata = this.colorData; - // for each raw value, calculate lookup offset into scaled array - for(i=0; i= dmax ){ - odata[i] = ss - 1; - } else { - odata[i] = Math.floor(((dd - dmin) * dval) + 0.5); - } - } - // allow chaining - return this; -}; - -// generate colorcells array from current colormap -// from: tksao1.0/colorbar/colorbar.C -JS9.Image.prototype.calcContrastBias = function(i){ - let r, result; - let bias = this.params.bias; - const cs = JS9.COLORSIZE; - const contrast = this.params.contrast; - // check for (close to) default - if( ((bias - 0.5) < 0.0001) && ((contrast - 1.0) < 0.0001) ){ - return i; - } - // map i to range of 0 to 1.0 - // shift by bias (if invert, bias = 1 - bias) - // multiply by contrast - // shift to center of region - // expand back to number of dynamic colors - if( this.params.invert ){ - bias = 1 - bias; - } - r = Math.floor((((i / cs) - bias) * contrast + 0.5) * cs); - if( r < 0 ){ - result = 0; - } else if( r >= cs ){ - result = cs - 1; - } else { - result = r; - } - return result; -}; - -// generate colorcells array from current colormap -// from: tksao1.0/colorbar/colorbartruecolor.C -JS9.Image.prototype.mkColorCells = function(){ - let i, j, idx; - const cs = JS9.COLORSIZE; - // skip if colormap is static - if( this.cmapObj.type === "static" ){ - return this; - } - // allocate array for color cells - if( !this.colorCells ){ - this.colorCells = []; - } - // fill in colorcells - for(i=0; i { - let i, k, int1, int2; - const hex_alphabets = "0123456789ABCDEF"; - const value = []; - //Remove the "#" char - if there is one. - if(hex.charAt(0) === "#"){ - hex = hex.slice(1); - } - hex = hex.toUpperCase(); - for(i=0, k=0; i<6; i+=2, k++){ - int1 = hex_alphabets.indexOf(hex.charAt(i)); - int2 = hex_alphabets.indexOf(hex.charAt(i+1)); - value[k] = (int1 * 16) + int2; - } - return value; - }; - // sanity check - if( !this.colorCells ){ return this; } - // skip if colormap is static - if( this.cmapObj.type === "static" ){ return this; } - // allocate array for scaled cells - if( !this.psColors ){ - this.psColors = []; - // value for NaN - this.psColors[NaN] = hex2num(this.params.nancolor); - } - // and the inverse array for colorbar ticks - if( !this.psInverse ){ - this.psInverse = []; - // value for NaN - this.psInverse[NaN] = 0; - } - // delta for scaling - dd = this.params.scalemax - this.params.scalemin; - low = this.params.scalemin; - // apply the appropriate scale algorithm - switch(this.params.scale){ - case "linear": - // scaled cells - for(ii=0; ii= cs ){ - ll = cs - 1; - } - this.psColors[ii] = this.colorCells[ll]; - } - // inverse - for(ii=0; ii= cs ){ - ll = cs - 1; - } - this.psColors[ii] = this.colorCells[ll]; - } - // inverse - for(ii=0; ii= cs ){ - ll = cs - 1; - } - this.psColors[ii] = this.colorCells[ll]; - } - // inverse - for(ii=0; ii= cs ){ - ll = cs - 1; - } - this.psColors[ii] = this.colorCells[ll]; - } - // inverse - for(ii=0; ii= cs ){ - ll = cs - 1; - } - this.psColors[ii] = this.colorCells[ll]; - } - // inverse - for(ii=0; ii= cs ){ - ll = cs - 1; - } - this.psColors[ii] = this.colorCells[ll]; - } - // inverse - for(ii=0; ii= dmin) && (data[ii] <= dmax) ){ - jj = Math.floor((data[ii] - dmin) / diff * hh + 0.5); - if( jj < hh ){ - pdf[jj] += 1; - } - } - } - // get average - for(ii=0; ii= avg) && (color < hh) ){ - bin -= avg; - color++; - } - } - dval = (hh - 1) /hh; - while( ii < hh ){ - this.hist[ii++] = dval; - } - } - // scaled cells - for(ii=0; ii vv ){ - break; - } - } - aa = jj / hh; - this.psInverse[ii] = aa * diff + dmin; - } - break; - default: - JS9.error(`unknown scale '${this.params.scale}'`); - } - // allow chaining - return this; -}; - -// create RGB image from scaled colorCells -// sort of from: tksao1.0/frame/truecolor.c, but not really -JS9.Image.prototype.mkRGBImage = function(){ - let rgb, sect, img, xrgb, yrgb, wrgb, hrgb, rgbimg, ctx; - let inc, zinc, xIn, yIn, xOut, yOut, xOutIdx, yOutIdx, yZoom, xZoom, cobj; - let idx, odx, odxmax, ridx, gidx, bidx, mim, mimg; - let yLen, zx, zy, zyLen, mopacity, cmopacity, val; - let alpha, alpha1, alpha2, alphafloor, alphafloorvalue, curalpha; - let domask = false; - let doalphafloor = false; - let rthis = null; - let gthis = null; - let bthis = null; - let dorgb = false; - let mimmask = false; - let mimopacity = false; - let mimoverlay = false; - let cached = []; - // sanity check - if( !this.rgb ){ return this; } - // image handles for RGB mode - if( this.display.rgb.active && - ((this === this.display.rgb.rim) || - (this === this.display.rgb.gim) || - (this === this.display.rgb.bim)) ){ - dorgb = true; - if( this.display.rgb.rim ){ - rthis = this.display.rgb.rim; - } - if( this.display.rgb.gim ){ - gthis = this.display.rgb.gim; - } - if( this.display.rgb.bim ){ - bthis = this.display.rgb.bim; - } - } - ctx = this.display.context; - rgb = this.rgb; - sect = rgb.sect; - // supply your own mkRGBImage call (black-magic, used by smart-x) - if( this.MakeRGBImage && typeof this.MakeRGBImage === "function" ){ - if( this.MakeRGBImage() ){ - return this; - } - } - // backward-compatibility with v1.7 - if( this.MakePrimaryImage && typeof this.MakePrimaryImage === "function" ){ - if( this.MakePrimaryImage() ){ - return this; - } - } - // if we have an RGB file or image overlay, use offsreen RGB colors - if( this.useOffScreenCanvas() ){ - wrgb = sect.width / sect.zoom; - hrgb = sect.height / sect.zoom; - xrgb = sect.x0; - yrgb = (this.offscreen.canvas.height - 1) - (sect.y0 + hrgb); - rgbimg = this.offscreen.context.getImageData(xrgb, yrgb, wrgb, hrgb); - if( sect.zoom === 1 ){ - // for unzoomed data, we can grab the RGB pixels directly - rgb.img = rgbimg; - } else { - // for zoomed data, we have to replicate each RGB pixel - rgb.img = ctx.createImageData(sect.width, sect.height); - img = rgb.img; - odx = 0; - for(yIn=0, yOut=0; yIn mask value - if( JS9.notNull(this.params.opacity) ){ - alpha2 = this.params.opacity * 255; - } else { - alpha2 = 255; - } - // reverse mask alphas, if necessary - if( this.mask.invert ){ - alpha = alpha1; - alpha1 = alpha2; - alpha2 = alpha; - } - } else if( this.mask.mode === "opacity" ){ - // opacity mode: alpha = mask value 0 to 1 * 255 - mimopacity = true; - } else if( this.mask.mode === "overlay" ){ - // overlay mode: non-zero mask value is blended with image value - mimoverlay = true; - mimg = mim.rgb.img; - if( JS9.isNull(this.mask.opacity) ){ - this.mask.opacity = 1; - } - } - } else if( JS9.notNull(this.params.flooropacity) && !dorgb && !domask ){ - // flooropacity: image pixels <= floor value use floor opacity - // can't do this with rgb mode because we have 3 different data values - alphafloor = this.params.flooropacity * 255; - alphafloorvalue = this.params.floorvalue; - doalphafloor = true; - } - // index into scaled data using previously calc'ed data value to get RGB - // reverse y lines - odx = 0; - inc = Math.max(1, Math.floor(1/sect.zoom)); - zinc = sect.zoom * inc; - for(yIn=Math.floor(sect.y1-1), yOut=0; yIn>=sect.y0; yIn -= inc, yOut++){ - yLen = yIn * this.raw.width; - yOutIdx = yOut * zinc; - for(xIn=Math.floor(sect.x0), xOut=0; xIn this.mask.value ){ - alpha = alpha2; - } else { - alpha = alpha1; - } - } else if( mimopacity ){ - // opacity mode: masked value is the opacity - alpha = mim.raw.data[yLen +xIn] * 255; - } - if( dorgb ){ - // rgb mode: up to three indexes - ridx = rthis ? rthis.colorData[yLen + xIn] : 0; - gidx = gthis ? gthis.colorData[yLen + xIn] : 0; - bidx = bthis ? bthis.colorData[yLen + xIn] : 0; - if( JS9.isNull(ridx) || JS9.isNull(gidx) || JS9.isNull(bidx) ){ - this.display.rgb.active = false; - JS9.error("RGB images are incompatible. Turning off RGB mode.", "", false); - this.mkRGBImage(); - return this; - } - } else if( !this.staticObj ){ - // ordinary case: one index - idx = this.colorData[yLen + xIn]; - } - // current alpha to use in most cases - curalpha = alpha; - // use alpha min when data val is below threshold? - if( doalphafloor && this.raw.data[yLen + xIn] <= alphafloorvalue ){ - curalpha = alphafloor; - } - xOutIdx = xOut * zinc; - for(yZoom=0; yZoom { - let context, canvas; - if( !this.offscreenRGB ){ - canvas = document.createElement("canvas"); - context = canvas.getContext("2d"); - // turn off anti-aliasing - if( !JS9.ANTIALIAS ){ - context.imageSmoothingEnabled = false; - } - this.offscreenRGB = {canvas, context}; - } - this.offscreenRGB.canvas.width= img.width; - this.offscreenRGB.canvas.height = img.height; - this.offscreenRGB.context.putImageData(img, 0, 0); - return this.offscreenRGB.canvas; - }; - // opts is optional - opts = opts || {}; - // reproject: if reproj wcs header exists, save it for alignment - if( this.rawDataLayer() === "reproject" && opts.wcsim ){ - this.wcsim = opts.wcsim; - this.wcsim.isawcsim = true; - } - // get display offsets - this.calcDisplayOffsets(true); - // save context - ctx.save(); - // do we need to apply blend mode parameters - if( opts.opacity !== undefined ){ ctx.globalAlpha = opts.opacity; } - if( opts.blend !== undefined ){ ctx.globalCompositeOperation = opts.blend; } - // do we need to apply the canvas transform? - if( this.params.transform ){ - // this is the transform matrix - m = this.params.transform; - // translate origin to center of display - w2 = this.display.width / 2; - h2 = this.display.height / 2; - ctx.translate(w2, h2); - // set new transform - ctx.transform(m[0][0], m[0][1], m[1][0], m[1][1], m[2][0], m[2][1]); - // translate back to 0, 0 - ctx.translate(-w2, -h2); - } - // display image - ctx.drawImage(img2canvas(rgb.img), this.ix, this.iy); - // restore original context - ctx.restore(); - // allow chaining - return this; -}; - -// display image, with pre and post processing based on comma-separated string -// of options: -// colors: generate colorData -// scaled: generate colorCells and scaledCells -// rgb: generate RGB image (happens automatically for any of the above) -// display: displlay image (always done) -// plugins: execute plugin callbacks -// all: colors,scaled,rgb,display,plugins -JS9.Image.prototype.displayImage = function(imode, opts){ - let i, im, bopts, obj; - let nblend = 0; - const allmode = "colors,scaled,rgb,display,plugins"; - const blends = []; - const mode = {}; - // eslint-disable-next-line no-unused-vars - const modeFunc = (element, index, array) => { - const el = element.trim(); - mode[el] = true; - // each step implies the next ones - switch(el){ - case "colors": - mode.scaled = true; - mode.rgb = true; - break; - case "scaled": - mode.rgb = true; - break; - } - }; - // special checks for displayMode setting - if( imode === false ){ - this.displayMode = false; - return this; - } - if( imode === true ){ - this.displayMode = true; - imode = "all"; - } - // if displayMode is false, just return - if( !this.displayMode ){ - return this; - } - // did we just pass the opts params? - if( typeof imode === "object" ){ - opts = imode; - imode = null; - } - if( !imode ){ - imode = "rgb"; - } else if( imode === "all" ){ - imode = allmode; - mode.notify = true; - } else if( imode === "rgbonly" ){ - imode = "rgb,nodisplay"; - mode.notify = true; - } else if( imode === "display" ){ - mode.notify = true; - } - // get mode as elements in an object - imode.split(",").forEach(modeFunc); - // by default display the image again (unless nodisplay is set) - mode.display = true; - // and always call plugins - mode.plugins = true; - // if we have an RGB file or image overlay, skip some steps - if( this.useOffScreenCanvas() ){ - mode.colors = false; - mode.scaled = false; - } - // opts are optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse displayImage opts: ${opts}`, e); } - } - // do we need to blend? - if( this.display.blendMode && (opts.blendMode !== false) ){ - for(i=0; i=0; i--){ - im = blends[i]; - im.mkRGBImage(); - } - } - } - // if we explicitly don't display, return here; - if( mode.nodisplay ){ - return this; - } - // display image on screen - if( mode.display ){ - // clear image - this.display.context.clear(); - if( nblend ){ - // pre-calculate image offsets in case of zoom changed for an image - // which acts as wcsim for another blended image ... in case the - // blended image gets loaded before the wcs image ... messy! - for(i=blends.length-1; i>=0; i--){ - blends[i].calcDisplayOffsets(false); - } - for(i=blends.length-1; i>=0; i--){ - im = blends[i]; - // display the image using blend characteristics - bopts = {wcsim: opts.wcsim, - blend: im.blend.mode, opacity: im.blend.opacity}; - im.putImage(bopts); - if( im === this ){ - // display layers for this image - im.displayShapeLayers(); - } - } - } else { - // display the image - this.putImage(opts); - // display layers for this image - this.displayShapeLayers(); - } - // mark this image as being in this display - this.display.image = this; - // now this is the displayed image, we can add delayed shapes - while( this.delayedShapes && this.delayedShapes.length ){ - this.tmp.syncRunning = true; - obj = this.delayedShapes.shift(); - switch(obj.mode){ - case "add": - this.addShapes(obj.layer, obj.shape, obj.opts); - break; - case "change": - this.changeShapes(obj.layer, obj.shape, obj.opts); - break; - } - delete this.tmp.syncRunning; - } - delete this.delayedShapes; - } - // post-processing - // plugin callbacks - this.xeqPlugins("image", "onimagedisplay"); - // allow chaining - return this; -}; - -// refresh data for an existing image -// input obj is a fits object, array, typed array, etc. -JS9.Image.prototype.refreshImage = function(obj, opts){ - let s, arr, ozoom, ora, odec, olpos, ipos, func; - // opts is optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse refreshImage opts: ${opts}`, e); } - } - // no obj or obj is a string, this is a load with refresh turned on - if( !obj || typeof obj === "string" ){ - if( opts.onrefresh ){ - opts.onload = opts.onrefresh; - delete opts.onrefresh; - } - opts.refresh = this; - // for file:// uri, we can use the FITS pathname, where possible - if( !document.domain ){ - s = obj || this.fitsFile || this.file; - } else { - // else use the url path relative to the web page - s = obj || this.file; - } - JS9.Load(s, opts, {display: this.display}); - return; - } - // check for refresh func - opts.rawid = opts.rawid || JS9.RAWID0; - // allow explicit specification of a func, for backward-compatibility - if( typeof opts === "function" ){ - func = opts; - opts = {onrefresh: func}; - } - if( !opts.onrefresh && JS9.imageOpts.onrefresh ){ - // use global onrefresh, if possible - opts.onrefresh = JS9.imageOpts.onrefresh; - } - // save section center if it's not to be reset - if( !opts.resetSection ){ - // always save logical coords - olpos = this.imageToLogicalPos({x: this.rgb.sect.xcen, - y: this.rgb.sect.ycen}); - // save wcs pos, if available - if( this.validWCS() ){ - s = JS9.pix2wcs(this.raw.wcs, - this.rgb.sect.xcen, this.rgb.sect.ycen); - arr = s.trim().split(/\s+/); - ora = JS9.saostrtod(arr[0]); - if( JS9.isHMS(this.params.wcssys) ){ - ora *= 15.0; - } - odec = JS9.saostrtod(arr[1]); - } - } - ozoom = this.rgb.sect.zoom; - // save old binning - this.binning.obin = this.binning.bin; - // generate new data - this.mkRawDataFromHDU(obj, opts); - // reset or restore section? - if( opts.resetSection ){ - // reset section - this.mkSection(); - this.mkSection(ozoom); - } else { - // try to restore section using saved coords - if( this.validWCS() && JS9.notNull(ora) && JS9.notNull(odec) ){ - arr = JS9.wcs2pix(this.raw.wcs, ora, odec).trim().split(/ +/); - ipos = {x: parseFloat(arr[0]), y: parseFloat(arr[1])}; - } else { - ipos = this.logicalToImagePos({x: olpos.x, y: olpos.y}); - } - // but if the image position off the new image ... - if( ipos.x > 0 && ipos.x < this.raw.width && - ipos.y > 0 && ipos.y < this.raw.height ){ - this.mkSection(ipos.x, ipos.y, ozoom); - } else { - // ... just reset the section - this.mkSection(); - this.mkSection(ozoom); - } - } - // display new image data with old section - this.displayImage("colors", opts); - // redo flip and rot - this.reFlipRot(); - // notify the helper - this.notifyHelper(); - // update shape layers if necessary - if( opts.refreshRegions || - opts.resetSection || - (this.binning.obin !== this.binning.bin) ){ - this.refreshLayers(); - // update region values - this.updateShapes("regions", "all", "binning"); - } - // plugin callbacks - this.xeqPlugins("image", "onimagerefresh"); - // all done - JS9.waiting(false); - // everything else is done so call refresh func, if necessary - if( opts.onrefresh ){ - try{ JS9.xeqByName(opts.onrefresh, window, this); } - catch(e){ JS9.error("in image refresh callback", e); } - } - // allow chaining - return this; -}; - -// fileDimensions: get dimensions of "original" file -// this is the hackiest routine in the JS9 module -// why is it so hard??? -JS9.Image.prototype.fileDimensions = function(){ - let xdim, ydim; - if( this.parent && this.parent.raw.header.XTENSION !== "BINTABLE" ){ - if( this.parent.raw.header.TABDIM1 ){ - xdim = this.parent.raw.header.TABDIM1; - } else { - xdim = this.parent.raw.header.NAXIS1; - } - if( this.parent.raw.header.TABDIM2 ){ - ydim = this.parent.raw.header.TABDIM2; - } else { - ydim = this.parent.raw.header.NAXIS2; - } - } else { - if( this.raw.header.TABDIM1 ){ - xdim = this.raw.header.TABDIM1; - } else { - xdim = this.raw.header.NAXIS1; - } - if( this.raw.header.TABDIM2 ){ - ydim = this.raw.header.TABDIM2; - } else { - ydim = this.raw.header.NAXIS2; - } - } - return {xdim, ydim}; -}; - -/* - maybePhysicalToImage: the second hackiest routine in the JS9 module! - The physical position defined by LTM/LTV is not always the file position, - For example, if the file foo.fits was created from another file: - funimage somefile.fits'[*,*,2]' foo.fits - its LTM/LTV keywords will referring to the parent, instead of itself. - In such a case, we want to convert physical position to the image position - of the physical file. - This situation is signalled by the presence of a parent lcs object. - This routine is used to display sections and the binning.js plugin. -*/ -JS9.Image.prototype.maybePhysicalToImage = function(pos){ - let lpos, ipos, npos; - if( this.imtab === "image" && - this.parent && this.parent.lcs && pos.x && pos.y ){ - lpos = {x: pos.x, y: pos.y}; - // call is used because this.parent is not an image object - ipos = JS9.Image.prototype.logicalToImagePos.call(this.parent, lpos, - "ophysical"); - npos = {x: Math.floor(ipos.x+0.5), y: Math.floor(ipos.y+0.5)}; - } - return npos; -}; - -// extract and display a section of an image, with table filtering -JS9.Image.prototype.displaySection = function(opts, func){ - let s, oproxy, hdu, from, obj, oreg, nim, topts; - let ipos, lpos, npos, tbin, arr, sect; - const getval3 = (val1, val2, val3) => { - let res; - if( !JS9.isNull(val1) ){ - res = val1; - } else if( !JS9.isNull(val2) ){ - res = val2; - } - return res || val3; - }; - // convert region to section (cen and dim) - const reg2sect = (xreg) => { - let i, xdim, ydim, xcen, ycen, npos; - let xx = 0; - let yy = 0; - let minx = 1000000; - let maxx = 0; - let miny = 1000000; - let maxy = 0; - const shape = xreg.shape; - // use physical coords object, if possible - if( !this.parentFile && xreg.lcs ){ - xreg = xreg.lcs - xcen = xreg.x; - ycen = xreg.y; - // beware of problems with physical coords not tied to the file - npos = this.maybePhysicalToImage({x: xcen, y: ycen}); - if( npos ){ - xcen = npos.x; - ycen = npos.y; - } - } else { - xcen = xreg.x; - ycen = xreg.y; - } - switch( shape ){ - case "annulus": - xdim = xreg.radii[xreg.radii.length-1]*2; - ydim = xreg.radii[xreg.radii.length-1]*2; - break; - case "box": - xdim = xreg.width; - ydim = xreg.height; - break; - case "circle": - xdim = xreg.radius*2; - ydim = xreg.radius*2; - break; - case "cross": - xdim = xreg.width; - ydim = xreg.height; - break; - case "ellipse": - xdim = xreg.r1*2; - ydim = xreg.r2*2; - break; - case "polygon": - case "line": - for ( i=0; i < xreg.pts.length; i++ ) { - xx += xreg.pts[i].x; - yy += xreg.pts[i].y; - if ( xreg.pts[i].x > maxx ) { maxx = xreg.pts[i].x; } - if ( xreg.pts[i].x < minx ) { minx = xreg.pts[i].x; } - if ( xreg.pts[i].y > maxy ) { maxy = xreg.pts[i].y; } - if ( xreg.pts[i].y < miny ) { miny = xreg.pts[i].y; } - } - xreg.x = xx/xreg.pts.length; - xreg.y = yy/xreg.pts.length; - if( xreg.shape === "line" && xreg.pts.length === 2 ){ - xdim = Math.sqrt(((xreg.pts[0].x - xreg.pts[1].x) * - (xreg.pts[0].x - xreg.pts[1].x)) + - ((xreg.pts[0].y - xreg.pts[1].y) * - (xreg.pts[0].y - xreg.pts[1].y))); - ydim = 1; - } else { - xdim = maxx - minx; - ydim = maxy - miny; - } - break; - case "text": - xdim = 10; - ydim = 10; - break; - default: - break; - } - return({xcen: xcen, ycen: ycen, xdim: xdim, ydim: ydim}); - }; - // main display routine - const disp = (hdu, opts) => { - let tim, did, arr; - let ss = ""; - // make a copy of opts so we can change it - topts = $.extend(true, {}, opts || {}); - if( JS9.isNull(topts.refreshRegions) ){ - topts.refreshRegions = true; - } - if( JS9.isNull(topts.resetSection) ){ - topts.resetSection = true; - } - // start the waiting! - if( topts.waiting !== false ){ - JS9.waiting(true, this.display); - } - // the id might have changed if we changed extensions - if( hdu.fits.extname ){ - ss = `[${hdu.fits.extname}]`; - } else if( hdu.fits.extnum && hdu.fits.extnum > 0 ){ - ss = `[${hdu.fits.extnum}]`; - } else if( this.parent ){ - if( this.parent.extname ){ - ss = `[${this.parent.extname}]`; - } else if( this.parent.extnum && this.parent.extnum > 0 ){ - ss = `[${this.parent.extnum}]`; - } - } - // change id and file if extension changed - if( ss ){ - if( !topts.id ){ - topts.id = this.id.replace(/\[.*\]/,"") + ss; - } - // NB: this was removed in v2.3 ... why? ... added back in v2.5 - if( !topts.file ){ - topts.file = this.file.replace(/\[.*\]/,"") + ss; - } - } - if( topts.separate ){ - // display section as a separate image in the specified display - delete topts.xcen; - delete topts.ycen; - if( typeof topts.separate === "string" ){ - arr = topts.separate.split(":"); - switch(arr.length){ - case 1: - did = arr[0]; - break; - default: - did = arr[0]; - topts.id = arr[1]; - break; - } - // make sure we can find the display - topts.display = JS9.lookupDisplay(did); - } else { - topts.display = this.display; - } - // lame attempt to get to original parentFile - if( from === "parentFile" && this.fitsFile ){ - tim = JS9.lookupImage(this.fitsFile); - if( tim && tim.parentFile ){ - topts.parentFile = tim.parentFile; - } else { - topts.parentFile = this.fitsFile; - } - } - // save current regions (before displaying new image) - oreg = this.listRegions("all", {mode: 1, - includedcoords: true, - ignoreignore: true, - saveediting: true, - savewcsconfig: true, - sortids: false, - saveid: true}); - // func to perform when image is loaded - func = topts.ondisplaysection || topts.onrefresh || func; - // set up new and display new image - nim = new JS9.Image(hdu, topts, func); - // reset obin to be bin, since new images have no previous bin - nim.binning.obin = nim.binning.bin; - // add regions to new image - if( oreg && topts.refreshRegions !== false ){ - nim.addShapes("regions", oreg, {restoreid: true}); - } - // redo flip and rot - this.reFlipRot(); - // set status of new image - nim.setStatus("displaySection", "complete"); - } else if( typeof topts.refresh === "string" ){ - // refresh the image in the specified display - delete topts.xcen; - delete topts.ycen; - arr = topts.refresh.split(":"); - switch(arr.length){ - case 1: - did = arr[0]; - break; - default: - did = arr[0]; - topts.id = arr[1]; - break; - } - // make sure we can find the display - topts.display = JS9.lookupDisplay(did); - if( topts.display.image ){ - topts.rawid = this.raw.id; - // func to perform when image is refreshed - topts.onrefresh = topts.ondisplaysection || - topts.onrefresh || func; - // refresh the image with the new hdu - topts.display.image.refreshImage(hdu, topts); - } else { - // no image in the specified display, so make a new one - // lame attempt to get to original parentFile - if( from === "parentFile" && this.fitsFile ){ - tim = JS9.lookupImage(this.fitsFile); - if( tim && tim.parentFile ){ - topts.parentFile = tim.parentFile; - } else { - topts.parentFile = this.fitsFile; - } - } - // save current regions (before displaying new image) - oreg = this.listRegions("all", {mode: 1, - includedcoords: true, - ignoreignore: true, - saveediting: true, - savewcsconfig: true, - sortids: false, - saveid: true}); - // func to perform when image is loaded - func = topts.ondisplaysection || topts.onrefresh || func; - // set up new and display new image - nim = new JS9.Image(hdu, topts, func); - // reset obin to be bin, since new images have no previous bin - nim.binning.obin = nim.binning.bin; - // add regions to new image - if( oreg ){ - nim.addShapes("regions", oreg, {restoreid: true}); - } - // redo flip and rot - this.reFlipRot(); - } - } else { - // this is the default behavior for displaySection: - // refresh the image in the current display - topts.rawid = this.raw.id; - // func to perform when image is refreshed - topts.onrefresh = topts.ondisplaysection || topts.onrefresh || func; - // refresh the current image with the new hdu - this.refreshImage(hdu, topts); - } - // set status of old image - this.setStatus("displaySection", "complete"); - // done waiting - JS9.waiting(false); - }; - // sanity check - if( !this.raw || !this.raw.hdu || !this.raw.hdu.fits ){ - JS9.error("invalid image for displaySection"); - } - // opts is optional - opts = opts || {}; - // special case: if opts is "full", display full image - if( opts === "full" ){ - const {xdim, ydim} = this.fileDimensions(); - opts = {xdim: xdim, ydim: ydim, xcen: 0, ycen: 0}; - } else if( opts === "selected" ){ - this._selectShapes("regions", "selected", null, (obj) => { - topts = reg2sect(obj.pub); - topts.from = "virtualFile"; - topts.separate = true; - topts.refreshRegions = false; - topts.resetSection = true; - this.displaySection(topts, func); - }); - return; - } else if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse displaySection opts: ${opts}`, e); } - } - // cube column - opts.cubecol = opts.cubecol || ""; - if( opts.cubecol ){ - // string containing filename and indication that this is a cube - s = this.file - .split("/") - .reverse()[0] - .replace(/\[.*\]/,"") - .replace(".fits", `_cube_${opts.cubecol}.fits`) - .replace(/\.ftz$/, `_cube_${opts.cubecol}.fits`) - .replace(/\.gz$/, "") - .replace(/\.bz2$/, "") - .replace(/:/g, "_"); - // name of virtual file we will create - if( !opts.file ){ - opts.file = s; - } - // and its id - if( !opts.id ){ - opts.id = s; - } - // unless explicitly set to false, separate is set to true - if( opts.separate !== false ){ - opts.separate = true; - } - } - if( opts.separate ){ - // if we are generating a separate image, copy the hdu - hdu = $.extend(true, {}, this.raw.hdu); - } else { - // if we are replacing the current image, use the hdu directly - hdu = this.raw.hdu; - } - // from where do we extract the section? - from = opts.from; - if( !from ){ - if( this.parentFile && JS9.helper.connected && JS9.helper.js9helper ){ - // we will be processing a parent file to get the section - from = "parentFile"; - } else { - // we will be processing a virtual file to get the section - from = "virtualFile"; - } - } - // get previous values to use as defaults - if( this.imtab === "table" && hdu.table ){ - // tables are easy: all the previous values should be present - sect = hdu.table; - } else { - sect = {}; - // start with bin from hdu - sect.bin = hdu.bin || 1; - // images are a bit more difficult - // hack: if a parent file was used to make this image, - // calculate binning from its LTM/TLV parameters - if( from === "parentFile" && - this.raw.header && JS9.notNull(this.raw.header.LTM1_1) ){ - sect.bin = 1 / Math.abs(this.raw.header.LTM1_1); - } - // get image center from raw data - ipos = {x: this.raw.width / 2, y: this.raw.height / 2}; - // convert to physical (file) coords - lpos = this.imageToLogicalPos(ipos); - // sect.xcen = Math.floor(lpos.x + 0.5); - // sect.ycen = Math.floor(lpos.y + 0.5); - sect.xcen = Math.floor(lpos.x + 0.5*(sect.bin-1)); - sect.ycen = Math.floor(lpos.y + 0.5*(sect.bin-1)); - npos = this.maybePhysicalToImage({x: sect.xcen, y: sect.ycen}); - if( npos ){ - sect.xcen = npos.x; - sect.ycen = npos.y; - } - sect.xdim = Math.floor(hdu.naxis1 * sect.bin); - sect.ydim = Math.floor(hdu.naxis2 * sect.bin); - sect.filter = this.raw.filter || ""; - sect.columns = this.raw.columns || ""; - } - // allow binning relative to current, e.g., *2, /4, +1, -3 - if( typeof opts.bin === "string" ){ - // save and remove mode flag - if( opts.bin.match(/[as]$/) ){ - opts.binMode = opts.bin.slice(-1); - opts.bin = opts.bin.slice(0, -1); - } - // temp binning value - tbin = sect.bin || this.binning.bin; - switch( opts.bin.charAt(0) ){ - case "*": - case "x": - case "X": - opts.bin = tbin * parseFloat(opts.bin.slice(1)); - break; - case "/": - opts.bin = tbin / parseFloat(opts.bin.slice(1)); - break; - case "i": - case "I": - opts.bin = tbin * 2; - break; - case "o": - case "O": - opts.bin = tbin / 2; - break; - default: - if( JS9.isNumber(opts.bin) ){ - opts.bin = parseFloat(opts.bin); - } else { - JS9.error(`invalid bin for displaySection: ${opts.bin}`); - } - break; - } - } - // now we can make sure opts has sensible defaults - opts.xcen = getval3(opts.xcen, sect.xcen, 0); - opts.ycen = getval3(opts.ycen, sect.ycen, 0); - switch(this.imtab){ - case "table": - opts.xdim = getval3(opts.xdim, sect.xdim, JS9.fits.options.table.xdim); - opts.ydim = getval3(opts.ydim, sect.ydim, JS9.fits.options.table.ydim); - opts.bin = getval3(opts.bin, sect.bin, JS9.fits.options.table.bin); - break; - default: - opts.xdim = getval3(opts.xdim, sect.xdim, JS9.fits.options.image.xdim); - opts.ydim = getval3(opts.ydim, sect.ydim, JS9.fits.options.image.ydim); - opts.bin = getval3(opts.bin, sect.bin, JS9.fits.options.image.bin); - break; - } - opts.binMode = getval3(opts.binMode, sect.binMode, JS9.globalOpts.binMode); - // final checks on binning - // handle string bin, possibly containing explicit binMode - if( typeof opts.bin === "string" ){ - if( opts.bin.match(/[as]$/) ){ - opts.binMode = opts.bin.slice(-1); - } - opts.bin = parseFloat(opts.bin); - } - // sanity check: we need a bin - if( !opts.bin ){ - opts.bin = 1; - } - // sanity check: fractional bin must be 1/n for images - if( this.imtab === "image" && opts.bin > 0 && opts.bin < 1 ){ - opts.bin = 1.0 / Math.floor((1.0 / opts.bin) + 0.5); - } - // filter - opts.filter = getval3(opts.filter, sect.filter, ""); - // save the filter, if necessary - this.raw.filter = opts.filter || ""; - // columns - opts.columns = getval3(opts.columns, sect.columns, ""); - // save the columns, if necessary - this.raw.columns = opts.columns || ""; - // start the waiting! - if( opts.waiting !== false ){ - JS9.waiting(true, this.display); - } - // set status - this.setStatus("displaySection", "processing"); - // ... start a timeout to allow the wait spinner to get started - window.setTimeout(() => { - // get image section - switch(from){ - case "parentFile": - oproxy = this.proxyFile; - // parentFile: image sect. from external parent file of cur file - // arr is for runAnalysis, remove opts for later processing - arr = []; - arr.push({name: "xcen", value: opts.xcen}); - delete opts.xcen; - arr.push({name: "ycen", value: opts.ycen}); - delete opts.ycen; - arr.push({name: "xdim", value: opts.xdim}); - arr.push({name: "ydim", value: opts.ydim}); - // load entire image section - if( opts.xdim !== undefined ){ opts.xdim = 0; } - if( opts.ydim !== undefined ){ opts.ydim = 0; } - // recombine bin and binMode, if necessary - if( opts.binMode ){ - opts.bin = `${opts.bin}${opts.binMode}`; - delete opts.binMode; - } - arr.push({name: "bin", value: opts.bin}); - delete opts.bin; - s = `${opts.filter||""}@@${opts.cols||""}`; - arr.push({name: "filter", value: s}); - // hack: pass filter and columns along to reach binning plugin - // delete opts.filter; - // get image section from external file - arr.push({name: "slice", value: opts.slice||""}); - delete opts.slice; - obj = {id: this.expandMacro("$id"), - image: this.file, - fits: this.parentFile, - rtype: "text"}; - obj.cmd = `js9Xeq imsection ${this.parentFile}`; - // if we are changing the extension, replace the old extension - // with the new one - if( opts.extension ){ - obj.cmd = obj.cmd.replace(/\[.*\]/,""); - obj.cmd += `[${opts.extension}]`; - delete opts.extension; - } - obj.cmd += this.expandMacro(" $xdim@$xcen,$ydim@$ycen,$bin $filter $slice", arr); - JS9.helper.send("imsection", obj, (r) => { - let obj, jobj, rarr, f, pf; - if( typeof r === "object" ){ - // with socketio, we get an object - obj = r; - } else { - // with cgi, we just get a text string - if( r.search(JS9.analOpts.epattern) >=0 ){ - obj = {stderr: r}; - } else { - obj = {stdout: r}; - } - } - if( obj.stderr ){ - JS9.error(obj.stderr); - return; - } - if( obj.errcode ){ - JS9.error(`in displaySection: ${obj.errcode}`); - return; - } - // output is file and possibly parentFile - rarr = obj.stdout.split(/\n/); - // file - f = JS9.cleanPath(rarr[0]); - // relative path: add install dir prefix - if( f.charAt(0) !== "/" ){ - f = JS9.InstallDir(f); - } - // this is the proxy file (meaning: delete it on close) - opts.proxyFile = f; - // remove oproxy file if not the same as the current file - if( oproxy && (oproxy !== opts.proxyFile) ){ - this.removeProxyFile(oproxy); - } - // json fits info - if( rarr[1] ){ - try{ - jobj = JSON.parse(rarr[1]); - } - catch(ignore){ - JS9.log("couldn't parse imsection as JSON: %s", f); - jobj = null; - } - if( jobj ){ - opts.extname = jobj.extname; - opts.extnum = jobj.extnum; - opts.hdus = jobj.hdus; - opts.binstr = jobj.binstr; - opts.parent = jobj; - } - } - // look for parentFile (path relative to helper, not install) - if( rarr[2] ){ - pf = JS9.cleanPath(rarr[2]); - opts.parentFile = pf; - } - // retrieve and display newly created image section file - JS9.fetchURL(f, f, opts, (result) => { - // cleanup previous FITS file support, if necessary - // do this before we handle the new FITS file, or else - // we end up with a memory leak in the emscripten heap! - JS9.cleanupFITSFile(this.raw, true); - // start the waiting! - if( opts.waiting !== false ){ - JS9.waiting(true, this.display); - } - // process the newly retrieved data as FITS - JS9.fits.handleFITSFile(result, opts, disp); - }); - }); - break; - case "virtualFile": - // cleanup previous FITS file support, if necessary - // do this before we handle the new FITS file, or else - // we end up with a memory leak in the emscripten heap! - JS9.cleanupFITSFile(this.raw, false); - // extract image section from current virtual file - JS9.getFITSImage(hdu.fits, hdu, opts, (hdu) => { - disp(hdu, opts); - }); - break; - default: - JS9.error("image section cannot be extracted from this data file"); - break; - } - }, JS9.SPINOUT); -}; - -// display the specified extension of a multi-extension FITS file -JS9.Image.prototype.displayExtension = function(extid, opts, func){ - let i, s, got, extname, im, id; - const dispnext = (i) => { - let hdu; - const topts = $.extend(true, {}, opts); - // hdus are loaded as separate images - topts.separate = true; - // all done, call the supplied func, if any - if( i === this.hdus.length ){ - if( func ){ - try{ JS9.xeqByName(func, window, this); } - catch(e){ JS9.error("in displayExtension callback", e, false); } - } - return; - } - // next hdu - hdu = this.hdus[i]; - if( hdu.type === "image" && hdu.naxis >= 2 ){ - // load next hdu and recurse when done - this.displayExtension(hdu.hdu, topts, () => { dispnext(i+1); }); - } else { - dispnext(i+1); - } - }; - // opts is optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse displayExtension opts: ${opts}`, e); } - } - opts.waiting = false; - // only makes sense if we have hdus - if( !this.hdus ){ - JS9.error("no FITS HDUs found for displayExtension()"); - } - // sanity check - if( JS9.isNull(extid) ){ - JS9.error("missing extname/extnum for displayExtension()"); - } - // display all extensions? - if( extid === "all" ){ - // load all image extensions, in order, as separate images - // we start with the first and let the call recurse - dispnext(0); - return; - } - // extname specified? - if( typeof extid === "string" ){ - opts.extension = extid; - extname = extid.toLowerCase(); - for(i=0, got=0; i 0 ){ - if( this.display.id === im.display.id ){ - got++; - break; - } - } - } - } - if( got ){ - im.displayImage("display", opts); - im.display.clearMessage(); - if( func ){ - try{ JS9.xeqByName(func, window, this); } - catch(e){ JS9.error("in displayExtension callback", e, false); } - } - return; - } - } - // cleanup previous FITS file support, if necessary - // do this before we handle the new FITS file, or else - // we end up with a memory leak in the emscripten heap! - if( !opts.separate ){ - JS9.cleanupFITSFile(this.raw, false); - } - // process the FITS file by going to the extname/extnum - this.displaySection(opts, func); - // allow chaining - return this; -}; - -// display the specified slice of a 3D or 4d FITS cube -JS9.Image.prototype.displaySlice = function(slice, opts, func){ - let i, topts, tim; - // opts is optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse displaySlice opts: ${opts}`, e); } - } - opts.waiting = false; - // sanity check - if( JS9.isNull(slice) ){ - JS9.error("missing slice for displaySlice()"); - } - if( this.raw.header.NAXIS !== 3 ){ - JS9.error("3D image required for displaySlice()"); - } - if( slice === "all" ){ - // load and display the slices separately - // ignore the fact that we already are displaying a slice of the image, - // since we don't actually know which slice is being displayed ... - for(i=1; i<=this.raw.header.NAXIS3; i++){ - topts = $.extend(true, {}, opts, {separate: true}); - this.displaySlice(i, topts, func); - } - } else { - // slicename or slicenum specified? - if( JS9.isNumber(slice) ){ - opts.slice = `*:*:${slice}`; - } else { - opts.slice = slice; - } - // processing for separate images - if( opts.separate ){ - // make new id based on slice - opts.id = sprintf("%s_%s", - this.id - .replace(/_?([0-9])+:x:x/, "") - .replace(/_?x:([0-9])+:x/, "") - .replace(/_?x:x:([0-9])+/, ""), - opts.slice.replace(/\*/g, "x")); - // look for existing id and just redisplay, if possible - for(i=0; i 0 ){ - tim.displayImage("display", {display: tim}); - return this; - } - } - } - } - // cleanup previous FITS file heap before handling the new FITS file, - // or we end up with a memory leak in the emscripten heap - JS9.cleanupFITSFile(this.raw, false); - // process the FITS file by going to the slice - this.displaySection(opts, func); - } - // allow chaining - return this; -}; - -// convert current image to array -JS9.Image.prototype.toArray = function(opts){ - let i, j, k, bpe, idx, le, header, npad, arr, buf, _dbuf; - let dbuf, sect, xlen, blen, datalen, darr; - // opts is optional - opts = opts || {}; - // always perform the header keyword fix - opts.simple = true; - // make a copy of the header, in case we have to change it - header = $.extend(true, {}, this.raw.header); - // are we processing a section of the image? - if( JS9.notNull(opts.sect) ){ - // image section - sect = opts.sect; - // header parameters that need to change - header.NAXIS1 = sect.x1 - sect.x0; - header.NAXIS2 = sect.y1 - sect.y0; - if( JS9.notNull(header.CRPIX1) ){ - header.CRPIX1 = header.CRPIX1 - sect.x0; - } - if( JS9.notNull(header.CRPIX2) ){ - header.CRPIX2 = header.CRPIX2 - sect.y0; - } - if( JS9.notNull(header.LTV1) ){ - header.LTV1 = header.LTV1 - sect.x0; - } - if( JS9.notNull(header.LTV2) ){ - header.LTV2 = header.LTV2 - sect.y0; - } - // extract image section - // length of a date element - blen = Math.abs(this.raw.bitpix/8); - // length of a row of data - xlen = (sect.x1 - sect.x0) * blen; - // total data length of the section - datalen = xlen * (sect.y1 - sect.y0); - // make an array of the required length - darr = new ArrayBuffer(datalen); - // make a vew that we can work with - dbuf = new Uint8Array(darr); - // copy the section into the new array, one row at a time - for(i=sect.y0, j=0; i 0; - if( le ){ - idx = header.length; - bpe = Math.abs(this.raw.bitpix)/8; - _dbuf = new Uint8Array(dbuf); - // swap bytes to big-endian - for(i=0; i<_dbuf.byteLength; i+= bpe){ - for(j=i+bpe-1, k=0; k= 0 ){ - return; - } - // default is to pan to center - if( args.length === 0 ){ - panx = this.raw.width / 2; - pany = this.raw.height / 2; - } - // one string arg is a json specification - // (two string args is panx, pany in string format) - if( args.length === 1 && typeof panx === "string" ){ - if( panx === "mouse" && this.ipos ){ - panx = this.ipos.x; - pany = this.ipos.y; - } else { - try{ panx = JSON.parse(panx); } - catch(e){ JS9.error(`can't parse setPan JSON: ${panx}`, e); } - } - } - if( typeof panx === "object" ){ - obj = panx; - // passing an object supports image, physical, wcs coordinates - if( JS9.notNull(obj.x) && JS9.notNull(obj.y) ){ - // image coords - panx = obj.x; - pany = obj.y; - } - if( JS9.notNull(obj.px) && JS9.notNull(obj.py) ){ - // physical coords - pos = this.logicalToImagePos({x: obj.px, y: obj.py}); - panx = pos.x; - pany = pos.y; - } - if( typeof obj.wcs === "string" ){ - // wcs string: ra dec [wcssys] - arr = obj.wcs.trim().split(/ +/); - obj.ra = arr[0]; - obj.dec = arr[1]; - if( arr.length >= 3 ){ - obj.wcssys = arr[2]; - } - } - if( this.validWCS() && JS9.notNull(obj.ra) && JS9.notNull(obj.dec) ){ - // wcs coords - // use supplied wcs, if necessary - if( obj.wcssys ){ - owcssys = this.getWCSSys(); - txeq = JS9.globalOpts.xeqPlugins; - JS9.globalOpts.xeqPlugins = false; - this.setWCSSys(obj.wcssys, false); - } - // convert wcs supplied as strings - if( typeof obj.ra === "string" ){ - obj.ra = JS9.saostrtod(obj.ra); - if( JS9.isHMS(this.params.wcssys) ){ - obj.ra *= 15.0; - } - } - if( typeof obj.dec === "string" ){ - obj.dec = JS9.saostrtod(obj.dec); - } - // convert to image coords - arr = JS9.wcs2pix(this.raw.wcs, obj.ra, obj.dec) - .trim().split(/ +/); - panx = parseFloat(arr[0]); - pany = parseFloat(arr[1]); - // restore original wcssys - if( owcssys ){ - this.setWCSSys(owcssys, false); - JS9.globalOpts.xeqPlugins = txeq; - } - } - } - // generate section from new image coords - if( !JS9.isNumber(panx) || !JS9.isNumber(pany) ){ - JS9.error(`invalid input for setPan: ${panx} ${pany}`); - } - if( this.wcsAlign() || this.isawcsim ){ - oval = JS9.globalOpts.panWithinDisplay; - JS9.globalOpts.panWithinDisplay = true; - } - this.mkSection(panx, pany); - // set pan for aligned images, if necessary - if( this.wcsAlign() || this.isawcsim ){ - for(i=0; i x1 ){ x1 = pts[i].x; } - if( JS9.isNull(y0) || pts[i].y < y0 ){ y0 = pts[i].y; } - if( JS9.isNull(y1) || pts[i].y > y1 ){ y1 = pts[i].y; } - } - w = x1 - x0; - h = y1 - y0; - } else { - w = this.raw.width; - h = this.raw.height; - } - nzoom = Math.min(this.display.width/w, this.display.height/h); - // a little rounding makes the zoom nicer - nzoom = Math.round((nzoom + 0.0000001) * 1000000) / 1000000; - break; - default: - nzoom = parseFloat(zval); - break; - } - break; - case "number": - nzoom = zval; - break; - default: - return; - } - return nzoom; -}; - -// set zoom of RGB image -JS9.Image.prototype.setZoom = function(zval){ - let i, nzoom, im, ipos, oval; - // is this core service disabled? - if( $.inArray("zoom", this.params.disable) >= 0 ){ - return; - } - nzoom = this.parseZoom(zval); - if( !nzoom ){ - JS9.error(`invalid input for setZoom: ${zval}`); - } - if( this.wcsAlign() || this.isawcsim ){ - oval = JS9.globalOpts.panWithinDisplay; - JS9.globalOpts.panWithinDisplay = true; - } - // remake section - this.mkSection(nzoom); - // set zoom for aligned images, if necessary - if( this.wcsAlign() || this.isawcsim ){ - for(i=0; i 0 ){ nobj.flip = "x"; } - if( wcsinfo.cdelt2 < 0 ){ nobj.flip = (nobj.flip|| "") + "y"; } - // only galactic and ecliptic use the algorithm below, others are trivial - switch(wcssys){ - case "galactic": - case "ecliptic": - break; - default: - if( wcsinfo.crot ){ - nobj.angle = -wcsinfo.crot; - } - return nobj; - } - // algorithm for galactic and ecliptic ... from AV (via trello) - // turn off plugin callbacks - txeq = JS9.globalOpts.xeqPlugins; - JS9.globalOpts.xeqPlugins = false; - // set wcssys to be the same wcssys the north pole coords are in - this.setWCSSys(pole[wcssys].wcssys, false); - // get center of image in that coord system - cx = this.raw.width/2; - cy = this.raw.height/2; - arr = JS9.pix2wcs(this.raw.wcs, cx, cy).trim().split(/\s+/); - // convert strings to float (degrees) - ra = JS9.saostrtod(arr[0]); - // ra hours to degrees, if necessary - if( JS9.isHMS() ){ ra *= 15.0; } - dec = JS9.saostrtod(arr[1]); - // angular distance between north pole and image center - nobj.angle = JS9.angdist(ra, dec, pole[wcssys].ra, pole[wcssys].dec); - // remove any header-based rotation - if( JS9.notNull(this.raw.wcsinfo.crot) ){ - nobj.angle -= this.raw.wcsinfo.crot; - } - // reset to the current coord system - this.setWCSSys(wcssys, false); - // restore plugin callbacks - JS9.globalOpts.xeqPlugins = txeq; - // return info - return nobj; -}; - -// get transform -JS9.Image.prototype.getTransform = function(){ - return this.params.transform; -}; - -// set transform (basis for setFlip, setRot90, setRotate) -JS9.Image.prototype.setTransform = function(...args){ - let a, i, sina, cosa, m3, transform; - let angle = 0; - let scale = 1; - let [arg1] = args; - if( !this || !this.raw || !this.raw.header ){ - JS9.error("invalid image for setTransform"); - } - // reset -> we're done - if( arg1 === "reset" ){ - delete this.params.transform; - delete this.params.transformInverse; - delete this.params.transformAngle; - delete this.params.transformScale; - return; - } - // start with the identity matrix - transform = [[1,0,0], [0,1,0], [0,0,1]]; - // for each transform ... - for(i=0; i { - let i, arr; - let nx = 0; - let ny = 0; - let nflip = ""; - arr = (flip + (this.params.flip||"")).split(""); - for(i=0; i { - if( JS9.globalOpts.rotateRelative ){ - rot += this.params.rotate||0; - } - while( rot < 0 ){ rot += 360; } - while( rot >= 360 ){ rot -= 360; } - return rot; - } - // sanity checks - if( JS9.isNull(rot) ){ return this; } - // reset - if( rot === "reset" ){ - this.params.rotate = 0; - return this.setRotate(0); - } - // north is up in current wcs system: calculate rotation angle - if( typeof rot === "string" && rot.match(/north/i) ){ - nobj = this.getNorthIsUp(); - rot = nobj.angle; - if( JS9.notNull(nobj.flip) ){ this.setParam("flip", nobj.flip); } - } - if( typeof rot === "string" ){ - rot = parseFloat(rot); - } - if( !JS9.isNumber(rot) ){ - JS9.error(`invalid rotation for setRotate: ${rot}`); - } - if( !this || !this.raw || !this.raw.header ){ - JS9.error("invalid image for setRotate"); - } - // opts is optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse setRotate opts: ${opts}`, e); } - } - // save this routine so it can be reconstituted in a restored session - this.xeqStashSave("setRotate", [rot]); - // save normalized value - this.params.rotate = normRot(rot); - // update the transform - this.setTransform(); - // non-rectangular canvas: redo section to ensure coverage of display - if( this.params.transformAngle && - this.display.canvas.width !== this.display.canvas.height ){ - this.mkSection(this.getZoom()); - } - // redisplay using these data - this.displayImage("all", opts); - // refresh shape layers - this.refreshLayers(); - // extended plugins - if( JS9.globalOpts.extendedPlugins ){ - this.xeqPlugins("image", "onsetrotate"); - } - // allow chaining - return this; -}; - -// get 90-degree rotatation state -JS9.Image.prototype.getRot90 = function(){ - return this.params.rot90; -}; - -// rotate image by multiples of 90 degrees using canvas transform -JS9.Image.prototype.setRot90 = function(...args){ - let [rot, opts] = args; - const normRot = (rot) => { - rot += this.params.rot90||0; - while( rot < 0 ){ rot += 360; } - while( rot >= 360 ){ rot -= 360; } - if( rot === 270 ){ - rot = -90; - } - return rot; - } - // sanity checks - if( JS9.isNull(rot) ){ return this; } - // reset - if( rot === "reset" ){ - this.params.rot90 = 0; - return this.setRot90(0); - } - if( typeof rot === "string" ){ - rot = parseFloat(rot); - } - if( !this || !this.raw || !this.raw.header ){ - JS9.error("invalid image for setRot90"); - } - // opts is optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse setRot90 opts: ${opts}`, e); } - } - // only 90 degree rotations - switch(rot){ - case 0: - rot = 0; - break; - case 1: - rot = 90; - break; - case -1: - rot = -90; - break; - case 90: - break; - case -90: - break; - default: - JS9.error(`invalid setRot90 rotation value: ${rot} (use: +/1, +/90)`); - break; - } - // save this routine so it can be reconstituted in a restored session - this.xeqStashSave("setRot90", [rot]); - // save normalized value - this.params.rot90 = normRot(rot); - // update the transform - this.setTransform(); - // non-rectangular canvas: redo section to ensure coverage of display - if( this.params.transformAngle && - this.display.canvas.width !== this.display.canvas.height ){ - this.mkSection(this.getZoom()); - } - // redisplay using these data - this.displayImage("all", opts); - // refresh shape layers - this.refreshLayers(); - // extended plugins - if( JS9.globalOpts.extendedPlugins ){ - this.xeqPlugins("image", "onsetrot90"); - } - // allow chaining - return this; -}; - -// redo the current flip and rot90 in cases where the underyling data changed -// (e.g. displaySection, refreshImage) -JS9.Image.prototype.reFlipRot = function(){ - let i, flips, nrot; - let flip = this.params.flip; - let rot90 = this.params.rot90; - let rot = this.params.rotate; - if( flip !== "none" ){ - this.params.flip = "none"; - flips = flip.split(""); - for(i=0; i= 0 ){ - return; - } - // do we update the default? - if( JS9.isNull(updatedef) ){ - updatedef = JS9.globalOpts.wcsSetUpdatesDef; - } - if( wcssys === "image" ){ - this.params.wcssys = "image"; - this.params.wcsunits = "pixels"; - JS9.wcsunits.image = "pixels"; - } else if( wcssys === "physical" ){ - this.params.wcssys = "physical"; - this.params.wcsunits = "pixels"; - if( updatedef ){ - JS9.globalOpts.wcsUnits.physical = "pixels"; - } - } else if( this.validWCS() ){ - // native: original wcs from file - if( wcssys === "native" ){ - wcssys = this.params.wcssys0; - } - // set wcs system - s = JS9.wcssys(this.raw.wcs, wcssys); - if( s ){ - // store new wcs system param - this.params.wcssys = s.trim(); - // get units associated with this wcs system - u = JS9.globalOpts.wcsUnits[this.params.wcssys] || "sexagesimal"; - // set the units - this.setWCSUnits(u, updatedef); - } - } - // extended plugins - if( JS9.globalOpts.extendedPlugins ){ - this.xeqPlugins("image", "onsetwcssys"); - } - // allow chaining - return this; -}; - -// init wcs -JS9.Image.prototype.initWCS = function(header){ - let alt, key, varr, s, bufsize, buf; - const hlen = JS9.globalOpts.wcsHlength; - const awcs = /(WCSNAME|WCSAXES|CRVAL[0-9]|CRPIX[0-9]|PC[0-9]_[0-9]|CDELT[0-9]|CD[0-9]_[0-9]|CTYPE[0-9]|CUNIT[0-9]|CRVAL[0-9]|PV[0-9]_[0-9]|PS[0-9]_[0-9]|RADESYS|LONPOLE|LATPOLE)([A-Z])/; - if( !this.raw.header ){ - return this; - } - // usually it's the raw header - header = header || this.raw.header; - // clean up old wcs - this.freeWCS(); - // init object to hold alt wcs objects - this.raw.altwcs = {}; - // set up the default wcs, using the original header params - alt = "default"; - this.raw.altwcs[alt] = {}; - this.raw.altwcs[alt].header = header; - // look for wcs alternates - // see: http://www.atnf.csiro.au/people/mcalabre/WCS/wcs.pdf - for( key of Object.keys(header) ){ - // is it an alt wcs keyword? - varr = key.match(awcs); - if( varr && varr.length ){ - // this is the A-Z version - alt = varr[2]; - // init the alt wcs object, if necessary - if( !this.raw.altwcs[alt] ){ - this.raw.altwcs[alt] = {}; - // start with original header - this.raw.altwcs[alt].header = $.extend({}, header); - } - // wcslib seems to want "RADECSYS", not "RADESYS" - if( varr[1] === "RADESYS" ){ - varr[1] = "RADECSYS"; - } - // overwrite standard keyword in header with the alt value - this.raw.altwcs[alt].header[varr[1]] = header[varr[0]]; - } - } - // init all of the wcs's we found - for( key of Object.keys(this.raw.altwcs) ){ - // loop through alt wcs objects - s = JS9.raw2FITS(this.raw.altwcs[key].header); - // too large headers blow Emscripten's stack space - // this.raw.altwcs[key].wcs = JS9.initwcs(s, hlen); - // so we have to copy the header to the heap: - // allocate space for the string in the emscripten heap - bufsize = s.length + 1; - try{ buf = JS9.vmalloc(bufsize); } - catch(e){ JS9.error(`can't malloc for wcsinit: ${bufsize}`, e); } - // copy the string to the heap - try{ JS9.vstrcpy(s, buf); } - catch(e){ JS9.error(`can't copy for wcsinit: ${bufsize}`, e); } - // call the wcsinit routine, passing the heap pointer - this.raw.altwcs[key].wcs = JS9.initwcs(buf, hlen); - // free heap space - JS9.vfree(buf); - // get info about the wcs - if( this.raw.altwcs[key].wcs > 0 ){ - try{ this.raw.altwcs[key].wcsinfo = - JSON.parse(JS9.wcsinfo(this.raw.altwcs[key].wcs)); } - catch(ignore){ /* empty */ } - } - } - // set current wcs to the default - this.setWCS("default"); - // allow chaining - return this; -}; - -// close and free wcs resources -JS9.Image.prototype.freeWCS = function(raw){ - let key; - // raw defaults to ... default raw - raw = raw || this.raw; - if( raw.altwcs ){ - // free all wcs structures - for( key of Object.keys(raw.altwcs) ){ - // loop through alt wcs objects - if( raw.altwcs[key].wcs > 0 ){ - JS9.freewcs(raw.altwcs[key].wcs); - raw.altwcs[key].wcs = null; - } - } - } -}; - -// get name of current wcs (from among the alternates) -JS9.Image.prototype.getWCS = function(){ - let key, obj; - // loop through wcs objects, looking for a match - for( key of Object.keys(this.raw.altwcs) ){ - if( this.raw.wcs === this.raw.altwcs[key].wcs ){ - obj = $.extend(true, {}, this.raw.altwcs[key].wcsinfo); - obj.version = key; - obj.wcsname = this.raw.altwcs[key].header.WCSNAME; - return obj; - } - } - return null; -}; - -// set wcs to default or one of the alternative versions -JS9.Image.prototype.setWCS = function(version){ - let key, wcsname, wcssys; - version = version || "default"; - // sanity check - if( !this.raw || !this.raw.altwcs ){ return this; } - // loop through wcs objects, looking for a match - for( key of Object.keys(this.raw.altwcs) ){ - wcsname = this.raw.altwcs[key].header.WCSNAME; - if( (version === key) || (version === wcsname) ){ - // make sure its a valid wcs - if( this.raw.altwcs[key].wcs <= 0 ){ - JS9.error("invalid WCS for version: %s", version); - } - // set this wcs up as the current one - this.raw.wcs = this.raw.altwcs[key].wcs; - // get info about the wcs - this.raw.wcsinfo = this.raw.altwcs[key].wcsinfo; - // look for a good wcssys - if( this.raw.wcsinfo && this.raw.wcsinfo.radecsys ){ - wcssys = this.raw.wcsinfo.radecsys; - } else { - if( this.params.wcssys !== "native" ){ - wcssys = this.params.wcssys.trim(); - } else { - wcssys = this.params.lcs; - } - } - // set the wcs system - this.setWCSSys(wcssys); - // this is also the default - if( !this.params.wcssys0 ){ - this.params.wcssys0 = wcssys; - } - // set the wcs units - this.setWCSUnits(this.params.wcsunits); - // all done - return this; - } - } - // didn't find it - JS9.error(`could not find WCS version: ${version}`); -}; - -// is a valid WCS open and active -JS9.Image.prototype.validWCS = function(){ - return this.raw && this.raw.wcs && this.raw.wcs > 0; -}; - -// get the WCS units for this image -JS9.Image.prototype.getWCSUnits = function(){ - if( this.params.wcsunits ){ - return this.params.wcsunits; - } - return "pixels"; -}; - -// set the WCS units for this image -JS9.Image.prototype.setWCSUnits = function(wcsunits, updatedef){ - let s, ws; - // is this core service disabled? - if( $.inArray("wcs", this.params.disable) >= 0 ){ - return; - } - // do we update the default? - if( JS9.isNull(updatedef) ){ - updatedef = JS9.globalOpts.wcsSetUpdatesDef; - } - if( wcsunits === "pixels" ){ - if( JS9.isWCSSys(this.params.wcssys) ){ - this.params.wcssys = "physical"; - } - this.params.wcsunits = "pixels"; - if( updatedef ){ - JS9.globalOpts.wcsUnits[this.params.wcssys] = "pixels"; - } - } else if( this.validWCS() ){ - if( JS9.notWCS(this.params.wcssys) ){ - ws = JS9.imageOpts.wcssys; - this.setWCSSys(ws); - } - s = JS9.wcsunits(this.raw.wcs, wcsunits); - if( s ){ - this.params.wcsunits = s.trim(); - if( updatedef ){ - JS9.globalOpts.wcsUnits[this.params.wcssys] = - this.params.wcsunits; - } - } - } - // extended plugins - if( JS9.globalOpts.extendedPlugins ){ - this.xeqPlugins("image", "onsetwcsunits"); - } - // allow chaining - return this; -}; - -// notify the helper a new image was displayed -JS9.Image.prototype.notifyHelper = function(){ - let basedir, image1, image2; - const imexp = new RegExp(`^${JS9.ANON}[0-9]*`); - const installexp = JS9.INSTALLDIR ? new RegExp(`^${JS9.INSTALLDIR}`) : null; - // notify the helper - if( JS9.helper.connected && !this.file.match(imexp) ){ - switch(JS9.helper.type){ - case "get": - case "post": - // get pageid from CGI helper (socket.io does this when connecting) - if( !JS9.helper.pageid ){ - JS9.helper.send("pageid", null, (s) => { - if( s && s.trim().match(/^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/) ){ - JS9.helper.pageid = s; - JS9.helper.js9helper = "js9helper"; - } - }); - break; - } - } - // get helper info about this image - // but also try removing part of path which gets to install dir - image1 = this.file; - if( image1.charAt(0) !== "/" && installexp ){ - image2 = this.file.replace(installexp, ""); - } - JS9.helper.send("image", {"image": image1, "image2": image2}, (res) => { - let rstr, r, s, cc, regexp; - if( typeof res === "object" ){ - // from node.js, we get an object with stdout and stderr - rstr = res.stdout; - // log stderr but keep going - if( res.stderr && JS9.DEBUG > 1 ){ - JS9.log(res.stderr); - } - } else { - // with cgi, we just get stdout - rstr = res; - } - // unless we have no stdout - if( !rstr ){ - return; - } - // returns: [file, path, wcs] - // split args, dealing with spaces inside brackets - r = rstr.trim().match(/(?:[^\s[]+|\[[^\]]*\])+/g); - s = r[1]; - if( s !== "?" ){ - if( !JS9.globalOpts.dataDir ){ - this.fitsFile = s; - // prepend base of png path if fits file has no path - // is this a bad "feature" in tpos?? probably ... - if( !this.fitsFile.includes("/") ){ - basedir = this.file.match( /.*\// ); - // but don't add installdir as part of prefix - // (fitsFile path is relative to the js9 directory) - if( basedir && basedir.length ){ - regexp = new RegExp(`^${JS9.INSTALLDIR}`); - basedir = basedir[0].replace(regexp, ""); - this.fitsFile = basedir + this.fitsFile; - } - } - // prepend JS9_DIR on files if fits is not absolute - if( JS9.globalOpts.prependJS9Dir ){ - if( this.fitsFile && - !this.fitsFile.match(/^\${JS9_DIR}/) && - this.fitsFile.charAt(0) !== "/" ){ - this.fitsFile = `\${JS9_DIR}/${this.fitsFile}`; - } - if( this.parentFile && - !this.parentFile.match(/^\${JS9_DIR}/) && - this.parentFile.charAt(0) !== "/" ){ - this.parentFile = `\${JS9_DIR}/${this.parentFile}`; - } - } - } else { - cc = s.lastIndexOf("/") + 1; - this.fitsFile = `${JS9.globalOpts.dataDir}/${s.slice(cc)}`; - } - if( JS9.DEBUG > 1 ){ - JS9.log("JS9 fitsFile: %s %s", this.file, this.fitsFile); - } - } - if( this.fitsFile ){ - this.fitsFile = JS9.cleanPath(this.fitsFile); - } - if( this.parentFile ){ - this.parentFile = JS9.cleanPath(this.parentFile); - } - // first time through, query the helper for info - if( !this.queried ){ - this.queryHelper("all"); - this.queried = true; - } - }); - } - // allow chaining - return this; -}; - -// ask helper for various types of information -JS9.Image.prototype.queryHelper = function(which){ - const what = which || "all"; - // query the helper - if( JS9.helper.connected ){ - if( (what === "all") || (what === "getAnalysis") ){ - // only retrieve analysis tasks once per image - if( !this.analysisPackages ){ - JS9.helper.send("getAnalysis", {"fits": this.fitsFile}, (s) => { - if( s ){ - try{ this.analysisPackages = JSON.parse(s); } - catch(e){ JS9.log("can't get analysis", e); } - } - }); - } - } - } - // allow chaining - return this; -}; - -// expand macros for this image -JS9.Image.prototype.expandMacro = function(s, opts){ - let cmd, olen; - // sanity check - if( !s ){ return; } - // process each $ token - // eslint-disable-next-line no-unused-vars - cmd = s.replace(/\${?([a-zA-Z][a-zA-Z0-9_()]+)}?/g, (m, t, o) => { - let i, r, owcssys, pos; - // called in image context - const savewcs = (wcssys) => { - const owcs = this.params.wcssys; - if( wcssys ){ - switch(wcssys){ - case "wcs": - if( JS9.notWCS(owcs) ){ - this.params.wcssys = this.params.wcssys0; - } - break; - case "physical": - case "image": - this.params.wcssys = wcssys; - break; - default: - break; - } - } - return owcs; - }; - const restorewcs = (wcssys) => { - if( wcssys ){ - this.params.wcssys = wcssys; - } - }; - const withext = (r) => { - let e; - // for tables, we might need to add the binning filter - if( this.imtab === "table" ){ - if( this.raw.hdu && this.raw.hdu.table.filter && - !r.match(this.raw.hdu.table.filter) ){ - if( r.match(/\]\[/) ){ - r = `${r.slice(0,-1)}&&${this.raw.hdu.table.filter}]`; - } else { - r += `[${this.raw.hdu.table.filter}]`; - } - } - } else if( this.imtab === "image" ){ - // for images, we might need to add/replace extension info - e = this.file.match(/\[.*\]/); - if( e ){ - if( r.match(/\[.*\]/) ){ - r = r.replace(/\[.*\]/, e); - } else { - r += e; - } - } else if( this.raw && this.raw.hdu && - this.raw.hdu.slice ){ - // current slice of 3D cube - e = this.raw.hdu.slice - .replace(/:/g, ",").replace(/([0-9][0-9]*)/, "$1:$1"); - r += `[${e}]`; - } else if( this.raw && this.raw.header && - this.raw.header.NAXIS > 2 ){ - // first slice of 3D cube - r += `[*,*,1:1]`; - } - } - return r; - }; - const u = t.split("("); - if( u[1] ){ - u[1] = u[1].replace(/\)$/, ""); - } - switch(u[0]){ - case "id": - r = this.display.divjq.attr("id"); - break; - case "image0": - r = this.id.replace(/\[EVENTS\]/i, ""); - break; - case "image": - r = this.id; - break; - case "filename": - // for cubes, process all slices if (all) is specified - if( u[1] == "all" && this.fitsFile && - this.raw && this.raw.header && this.raw.header.NAXIS === 3 ){ - r = this.fitsFile; - } else if( this.parentFile && (u[1] !== "this") ){ - // if a filter is defined, add it - if( this.raw && this.raw.filter ){ - r = this.parentFile; - // assume parent is a table with EVENTS - if( !r.match(/\[.*\]/) ){ r += '[EVENTS]'; } - r += `[${this.raw.filter}]`; - } else { - r = withext(this.parentFile); - } - } else if( this.fitsFile ){ - r = withext(this.fitsFile); - } else { - JS9.error(`no FITS file for ${this.id}`); - } - break; - case "fits": - if( !this.fitsFile ){ - JS9.error(`no FITS file for ${this.id}`); - } - r = withext(this.fitsFile); - break; - case "parent": - if( !this.parentFile ){ - JS9.error(`no parent FITS file for ${this.id}`); - } - r = this.parentFile; - break; - case "ext": - if( this.fitsFile ){ - r = this.fitsFile.match(/\[.*\]/); - if( r === null ){ - r = ""; - } - } else { - JS9.error(`no FITS file for ${this.id}`); - } - break; - case "imcenter": - pos = this.displayToLogicalPos({x: this.display.width/2, - y: this.display.height/2}); - r = `${pos.x},${pos.y}`; - break; - case "wcscenter": - pos = this.displayToImagePos({x: this.display.width/2, - y: this.display.height/2}); - r = JS9.pix2wcs(this.raw.wcs, pos.x, pos.y).replace(/\s+/g, ","); - break; - case "sregions": - owcssys = savewcs(u[1]); - r = this.listRegions("source", - {mode:0, includedcoords:JS9.globalOpts.regExpandDCoords}) - .replace(/\s+/g,""); - restorewcs(owcssys); - break; - case "bregions": - owcssys = savewcs(u[1]); - r = this.listRegions("background", - {mode:0, includedcoords:JS9.globalOpts.regExpandDCoords}) - .replace(/\s+/g,""); - restorewcs(owcssys); - break; - case "regions": - owcssys = savewcs(u[1]); - r = this.listRegions("all", - {mode:0, includedcoords:JS9.globalOpts.regExpandDCoords}) - .replace(/\s+/g,""); - restorewcs(owcssys); - break; - case "mag": - // hack for statusbar - if( this.params.zoom ){ - r = sprintf("%s%", 100 * this.params.zoom); - } else { - r = "?"; - } - break; - default: - // look for keyword in the serialized opts array - if( opts ){ - olen = opts.length; - for(i=0; i { - if( !s1 || !s2 ){ - return false; - } - return String(s1).toUpperCase() === String(s2).toUpperCase(); - }; - // sanity check - if( !atask.title || !atask.name ){ return false; } - // is this task hidden? - if( atask.hidden ){ - return false; - } - // file validators - if( atask.files ){ - if( atask.files.match(/^fits$/) && - !this.fitsFile ){ - return false; - } - if( atask.files.match(/^table$/) ){ - if( this.imtab !== "table" ){ - return false; - } - } - if( atask.files.match(/^image$/) ){ - if( this.imtab !== "image" ){ - return false; - } - } - // header params: fitsHeader(pname,pvalue) - parr = atask.files.match(parexp); - if( parr ){ - s = this.raw.header[parr[1].toUpperCase()]; - if( !seq(s, parr[2]) ){ - return false; - } - } - // win vars: winVar(name,value) - parr = atask.files.match(winexp); - if( parr ){ - s = JS9.varByName(parr[1], window); - if( !seq(s, parr[2]) ){ - return false; - } - } - // js9 vars: js9Var(name,value) - parr = atask.files.match(js9exp); - if( parr ){ - s = JS9.varByName(parr[1], JS9); - if( !seq(s, parr[2]) ){ - return false; - } - } - // im vars: imVar(name,value) - parr = atask.files.match(imexp); - if( parr ){ - s = JS9.varByName(parr[1], this); - if( !seq(s, parr[2]) ){ - return false; - } - } - } // end of file validators - return true; -}; - -// return object containing analysis task definitions -JS9.Image.prototype.getAnalysis = function(){ - let i, j, t, tasks; - const obj = []; - // sanity check - if( !this.analysisPackages ){ return obj; } - // return validated tasks - for(j=0; j { - // shouldn't happen - if( !JS9.helper ){ - JS9.error(s, t); - } - switch(JS9.helper.type){ - case 'nodejs': - case 'socket.io': - // when socket.io is long-polling, throwing an error prevent the - // polling from completing, leading to a timeout error and disaster. - // to allow the polling to complete, throw the error after a delay - if( JS9.helper.socket && - JS9.helper.socket.io.engine.transport.name === "polling"){ - window.setTimeout(() => { - JS9.error(s, t); - }, 0); - } else { - JS9.error(s, t); - } - break; - default: - JS9.error(s, t); - break; - } - }; - // opts is optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse runAnalysis opts: ${opts}`, e); } - } - // func can be passed, or it can be global - func = func || JS9.globalOpts.analysisFunc; - // sanity check - if( !JS9.helper.connected || !this.analysisPackages ){ return; } - // get analysis task - a = this.lookupAnalysis(name); - if( !a ){ - JS9.error(`could not find analysis task: ${name}`); - return; - } - // get command line using macro expansion - if( a.action ){ - obj.cmd = this.expandMacro(a.action, opts); - } - // macro expand the strings in the keys array - if( a.keys ){ - obj.keys = {}; - for(i=0; i { - let s, robj, f, pf, xobj, files; - // return type can be string or object - if( typeof r === "object" ){ - // object from node.js - robj = r; - } else { - // string from cgi - if( r.search(JS9.analOpts.epattern) >=0 ){ - robj = {stderr: r}; - } else { - robj = {stdout: r}; - } - } - robj.errcode = robj.errcode || 0; - // if a processing func was supplied, call it and don't display - if( func ){ - func.call(this, robj.stdout, robj.stderr, robj.errcode, a); - } else { - // handle errors before we start - if( robj.stderr ){ - s = robj.stderr; - // if its only a warning, log it - if( (s.search(/WARNING:/i) >= 0) && (s.search(/ERROR:/i) < 0) ){ - JS9.log(s); - } else { - // otherwise, throw an error - analError(s, JS9.analOpts.epattern); - return; - } - } else if( robj.errcode ){ - s = `ERROR: running ${a.name} [${robj.errcode}]`; - // not sure what this means, so just log it if stdout exists - if( robj.stdout ){ - JS9.log(s); - } else { - // otherwise, throw an error - analError(s, JS9.analOpts.epattern); - return; - } - } - // display according to type - switch(a.rtype){ - case "text": - case undefined: - this.displayAnalysis("text", robj.stdout, - {divid: JS9.globalOpts.analysisDiv}); - break; - case "plot": - this.displayAnalysis("plot", robj.stdout, - {divid: JS9.globalOpts.analysisDiv}); - break; - case "alert": - if( robj.stdout ){ - alert(robj.stdout); - } - break; - case "fits": - // output is file and possibly parentFile - files = robj.stdout.split(/\s+/); - if( files && files[0] ){ - // file - f = JS9.cleanPath(files[0]); - // relative path: add install dir prefix - if( f.charAt(0) !== "/" ){ - f = JS9.InstallDir(f); - } - // which is a proxy file (meaning: delete it on close) - xobj = {proxyFile: f}; - // look for parentFile (relative to helper, not install) - if( files[1] ){ - pf = JS9.cleanPath(files[1]); - xobj.parentFile = pf; - xobj.proxyParent = pf; - } - // don't convert this FITS file into another FITS file! - xobj.fits2fits = false; - // don't fix the path for desktop - xobj.fixpath = false; - // load new file - JS9.Load(f, xobj, {display: this.display}); - } - break; - case "regions": - // output is region file (or region string), optional opts - files = robj.stdout.split(/\s+/); - if( files && files[0] ){ - // see if a json opts was returned - if( files.length > 1 ){ - try{ ropts = JSON.parse(files[1]); } - catch(e){ ropts = null; } - } - ropts = ropts || {}; - if( typeof ropts.remove === "boolean" ){ - ropts.remove = "all"; - } - if( ropts.type === "string" ){ - // region string was passed directly - if( ropts.remove ){ - this.removeShapes("regions", ropts.remove); - } - this.addShapes("regions", files[0], opts); - } else { - // region file was passed, we have to fetch it - f = JS9.cleanPath(files[0]); - // relative path: add install dir prefix - if( f.charAt(0) !== "/" ){ - f = JS9.InstallDir(f); - } - // load new region file - obj = {responseType: "text"}; - JS9.fetchURL(null, f, obj, (regions, opts) => { - if( ropts.remove ){ - this.removeShapes("regions", ropts.remove); - } - this.addShapes("regions", regions, opts); - }); - } - } - break; - case "catalog": - // output is catalog file - files = robj.stdout.split(/\s+/); - if( files && files[0] ){ - f = JS9.cleanPath(files[0]); - // load new catalog file - obj = {responseType: "text"}; - JS9.fetchURL(null, f, obj, (catalog, opts) => { - this.loadCatalog(null, catalog, opts); - }); - } - break; - case "none": - break; - default: - JS9.error(`unknown analysis result type: ${a.rtype}`); - break; - } - } - // set status - this.setStatus("runAnalysis", "complete"); - // done waiting - JS9.waiting(false); - }); - // allow chaining - return this; -}; - -// display analysis results (text or plot) -JS9.Image.prototype.displayAnalysis = function(type, s, opts){ - let i, r, id, did, hstr, pobj, divjq, title, titlefile, winFormat; - let divid, plot, pdata, popts, gim, gdiv, nscale; - const a = JS9.lightOpts[JS9.LIGHTWIN]; - const flotConfig = () => { - let s; - let winformat = "width=368px,height=110px,resize=1,scrolling=1"; - const title = JS9.Plot.opts.title; - // sanity check - if( !divjq || !plot ){ return; } - // call this once window is loaded - $(JS9.lightOpts[JS9.LIGHTWIN].topid) - .arrive("#plotConfigForm", {onceOnly: true}, () => { - JS9.Plot.initConfigForm.call(this, plot, pobj); - }); - if( JS9.allinone ){ - s = JS9.allinone.plotConfigHTML; - plot.winid = this.displayAnalysis("params", s, {title, winformat}); - } else { - s = JS9.InstallDir(JS9.Plot.opts.configURL); - plot.winid = this.displayAnalysis("params", s, {title, winformat}); - } - }; - // opts is optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse displayAnalysis opts: ${opts}`, e); } - } - // window format ... - winFormat = opts.winformat; - // ... or target div - if( opts.divid && $(`#${opts.divid}`).length > 0 ){ - divid = $(`#${opts.divid}`); - } - // make up title, if necessary - title = opts.title || ""; - if( this && !title ){ - titlefile = (this.fitsFile || this.id || ""); - titlefile = titlefile.split("/").reverse()[0]; - title = `AnalysisResults: ${titlefile}`; - // add display to title - title += sprintf(JS9.IDFMT, this.display.id); - } - // unique id for light window - id = `Analysis_${JS9.uniqueID()}`; - // process the type of analysis results - switch(type){ - case "text": - s = s || ""; - hstr = "

    "; - hstr += `
    ${s}
    `; - hstr += ""; - // populate div or create the light window to hold the text - if( divid ){ - // existing div - divid.html(hstr); - // Electron does not support search so we implement our own ... - if( window.electron ){ - JS9.searchbar(divid[0]); - } - } else { - // display light window - winFormat = winFormat || a.textWin; - did = JS9.lightWin(id, "inline", hstr, title, winFormat); - // Electron does not support search so we implement our own ... - if( window.electron ){ - JS9.searchbar(did); - } - } - break; - case "plot": - // convert results to js object - if( s && typeof s === "string" ){ - try{ pobj = JSON.parse(s); } - catch(e){ JS9.error(`can't plot return data: ${s}`, e); } - } else if( typeof s === "object" ){ - pobj = s; - } - // sanity check - if( !pobj ){ return; } - // initialize scale - pobj.curscale = {x: "linear", y: "linear"}; - // create an outer div and an inner plot for the light window open call - hstr = `
    `; - // populate div or create the light window to hold the plot - if( divid ){ - divid.html(hstr); - } else { - winFormat = winFormat || a.plotWin; - did = JS9.lightWin(id, "inline", hstr, title, winFormat); - } - // find the inner plot div which now is inside the light window - divjq = $(`#${id} #${id}Plot`); - // when using a div (instead of a lightwin), set the div size - if( divid ){ - divjq.css("width", divid.css("width")); - divjq.css("height", divid.css("height")); - divjq.css("margin", 0); - } - // flot data - if( pobj.data ){ - switch( JS9.globalOpts.plotLibrary ){ - case "plotly": - popts = $.extend(true, {}, JS9.Plot.opts, pobj.opts); - if( pobj.label ){ - popts.title = pobj.label; - } - pdata = {x: [], y: [], type: "scatter"}; - // flot data format: [[x1,y1], [x2,y2], ..] - // or: [[x1,y1,yerr1], [x2,y2,yerr2], ..] - if( pobj.data[0].length >= 3 ){ - // look for flot yerr properties - pdata.error_y = {type: 'data', array: [], visible: true}; - if( pobj.points && pobj.points.yerr ){ - if( pobj.points.yerr.color ){ - pdata.error_y.color = pobj.points.yerr.color; - } - } - } - for(i=0; i { - JS9.Plot.annotate(divjq, plt, pobj); - }; - } - pobj.color = pobj.color || popts.color; - // log scale? - if( pobj.xscale === "log" ){ - popts.xaxis = popts.xaxis || {}; - popts.xaxis.transform = JS9.Plot.logfunc; - popts.xaxis.inverseTransform = JS9.Plot.expfunc; - pobj.curscale.x = "log"; - } - if( pobj.yscale === "log" ){ - popts.yaxis = popts.yaxis || {}; - popts.yaxis.transform = JS9.Plot.logfunc; - popts.yaxis.inverseTransform = JS9.Plot.expfunc; - pobj.curscale.y = "log"; - } - try{ plot = $.plot(divjq, [pobj], popts); } - catch(e){ JS9.error("can't plot data (flot)", e); } - // annotate, if necessary - if( JS9.Plot.opts.annotate && pobj.annotations ){ - JS9.Plot.annotate(divjq, plot, pobj); - } - break; - } - // add key handlers - divjq.css("outline", "none"); - divjq.attr("tabindex", 0); - divjq.on("keydown", (evt) => { - const c = JS9.eventToCharStr(evt); - switch(c){ - case "c": - flotConfig(); - break; - case "x": - case "y": - nscale = pobj.curscale[c] !== "linear" ? "linear" : "log"; - JS9.Plot.rescale(divjq, plot, pobj, c, nscale); - break; - default: - break; - } - }); - // add the plot config gear - gim = $(``); - gim.on("click", flotConfig); - gdiv = $("
    "); - gdiv.append(gim); - divjq.append(gdiv); - } - break; - case "params": - case "regions": - case "textline": - if( divid ){ - if( JS9.allinone ){ - divid.html(s); - } else { - $.ajax({ - url: s, - cache: false, // required for v3 socket.io - dataType: "text", - success: (data) => { divid.html(data); } - }); - } - } else { - if( type === "params" ){ - winFormat = winFormat || a.paramWin; - } else if( type === "regions" ){ - if( JS9.globalOpts.regConfigSize === "small" ){ - winFormat = winFormat || a.regWin0; - } else { - winFormat = winFormat || a.regWin; - } - } else { - winFormat = winFormat || a.dpathWin; - } - r = JS9.allinone?"inline":"ajax"; - did = JS9.lightWin(id, r, s, title, winFormat); - } - break; - default: - break; - } - return did; -}; - -// save image as a FITS file -JS9.Image.prototype.saveFITS = function(fname, opts){ - let arr, blob, s, sect; - if( {}.hasOwnProperty.call(window, "saveAs") ){ - if( fname ){ - fname = fname - .replace(/\s+/g, "_") - .replace(/(png|jpg|jpeg|fz)$/i, "fits"); - if( !fname.match(/.fits$/) ){ - fname += ".fits"; - } - } else { - fname = "js9.fits"; - } - opts = opts || {}; - if( typeof opts === "string" ){ - try{ s = JSON.parse(opts); } - catch(e){ s = null; } - if( s ){ opts = s; } - } - // what do we save? - if( opts === "display" || opts.source === "display" ){ - // save currently displayed section - sect = this.rgb.sect; - arr = this.toArray({notab: true, twoaxes: true, sect: sect}); - } else if( opts === "virtual" || opts.source === "virtual" ){ - if( this.raw.hdu && this.raw.hdu.fits && this.raw.hdu.fits.vfile ){ - arr = JS9.vread(this.raw.hdu.fits.vfile, "binary"); - } else { - JS9.error("no virtual file available to save"); - } - } else { - // save entire image: first convert to array (with two axes) - arr = this.toArray({notab: true, twoaxes: true}); - } - // convert array to blob - blob = new Blob([arr], {type: "application/octet-binary"}); - // save to disk - JS9.saveAs(blob, fname); - } else { - JS9.error("no saveAs() available to save FITS file"); - } - return fname; -}; - -// save image as an img file of specified type (e.g., image/png, image/jpeg) -JS9.Image.prototype.saveIMG = function(fname, type, opts){ - let key, img, ctx, canvas, width, height, quality; - if( {}.hasOwnProperty.call(window, "saveAs") ){ - // opts can be opts object or json string or quality value - if( typeof opts === "number" ){ - quality = opts; - opts = null; - } else if( typeof opts === "string" ){ - if( JS9.isNumber(opts) ){ - quality = parseFloat(opts); - opts = null; - } else { - try{ opts = JSON.parse(opts); } - catch(e){ opts = null; } - } - if( opts ){ - quality = opts.quality; - } - } - // opts is optional - opts = opts || {}; - // filename is optional - fname = fname || "js9.png"; - // save as specified type - type = type || "image/png"; - // convenience params - width = this.display.width; - height = this.display.height; - // create off-screen canvas, into which we write all canvases - img = document.createElement("canvas"); - img.setAttribute("width", width); - img.setAttribute("height", height); - ctx = img.getContext("2d"); - // source can be image or display - if( opts.source === "image" ){ - // image: save RGB image for this image, which will be different - // from the display, e.g., when blend mode is turned on - ctx.putImageData(this.rgb.img, 0, 0); - } else { - // display: save RGB image as seen on the display, - // e.g. a composite blended image - ctx.drawImage(this.display.canvas, 0, 0); - } - // add graphics layers, unless explicitly specified not to - if( opts.layers !== false ){ - for( key of Object.keys(this.layers) ){ - // each layer canvas - if( this.layers[key].dlayer.dtype === "main" && - this.layers[key].show ){ - canvas = this.layers[key].dlayer.canvasjq[0]; - ctx.drawImage(canvas, 0, 0, width, height); - } - } - } - // sanity check on quality - if( JS9.notNull(quality) ){ - if( quality < 0 || quality > 1 ){ - quality = 0.95; - } - } - img.toBlob( (blob) => { - JS9.saveAs(blob, fname); - }, type, quality); - } else { - JS9.error("no saveAs() available for saving image"); - } - return fname; -}; - -// save image as a PNG file -JS9.Image.prototype.savePNG = function(fname, opts){ - fname = fname || "js9.png"; - if( !fname.match(/\.png$/) ){ - fname += ".png"; - } - return this.saveIMG(fname, "image/png", opts); -}; - -// save image as a JPEG file -JS9.Image.prototype.saveJPEG = function(fname, opts){ - fname = fname || "js9.jpg"; - if( !fname.match(/\.jpg$/) && !fname.match(/\.jpeg$/) ){ - fname += ".jpg"; - } - return this.saveIMG(fname, "image/jpeg", opts); -}; - -// update (and display) pixel and wcs values (connected to info plugin) -JS9.Image.prototype.updateValpos = function(ipos, disp){ - let val, vstr, vstr1, vstr2, vstr3, val3, i, c, d, p, s; - let cd1, cd2, v1, v2, units, sect; - let obj = null; - const sep1 = "\t "; - const sep2 = "\t\t "; - const sp = "    "; - const tf = (fval) => { - return JS9.floatFormattedString(fval, this.params.precision, 3); - }; - const tr = (fval, length) => { - length = length || 3; - return fval.toFixed(length); - }; - const ti = (ival, length) => { - let r = ""; - let prefix = ""; - length = length || 3; - if( ival < 0 ){ - ival = Math.abs(ival); - prefix = "-"; - } - r = r + ival; - while (r.length < length) { - r = `0${r}`; - } - return prefix + r; - }; - // only do processing if valpos is turned on - if( this.params.valpos ){ - // default is to display - if( disp === undefined ){ - disp = true; - } - // if a cached valpos object exists, use it - // this is unset and reset in the mousemove callback - if( this.valpos ){ - if( disp ){ - this.display.displayMessage("info", this.valpos, - JS9.globalOpts.valposTarget); - } - return this.valpos; - } - // get image coordinates - i = {x: ipos.x, y: ipos.y, sys: "image"}; - // get logical coordinates - p = this.imageToLogicalPos(ipos); - // get display coordinates - d = this.imageToDisplayPos(ipos); - d.sys = "display"; - // get pixel coordinates in current logical coordinate system; - if( this.params.wcssys === "image" ){ - c = i; - } else { - c = p; - } - // get image value: here we need 0-indexed display positions, - // so subtract the 0.5 of the image pixel - val = this.raw.data[Math.floor(ipos.y - 0.5) * this.raw.width + - Math.floor(ipos.x - 0.5)]; - // fix the significant digits in the value - switch(this.raw.bitpix){ - case 8: - case 16: - case -16: - case 32: - val3 = ti(val); - break; - case -32: - case -64: - val3 = tf(val); - break; - default: - val3 = ti(val); - break; - } - // create the valpos string - vstr1 = val3; - vstr2 = `${tr(c.x, 3)} ${tr(c.y, 3)} (${c.sys})`; - if( JS9.globalOpts.valposDCoords && c.sys === "image" ){ - vstr2 += `${sp}${tr(d.x, 3)} ${tr(d.y, 3)} (${d.sys})`; - } - vstr = vstr1 + sp + vstr2; - // object containing all information - obj = {ix: i.x, iy: i.y, ipos: tr(i.x, 2) + sep2 + tr(i.y, 2), - isys: "image", - px: p.x, py: p.y, ppos: tr(p.x, 2) + sep2 + tr(p.y, 2), - psys: "physical", - dx: d.x, dy: d.y, dpos: tr(d.x, 2) + sep2 + tr(d.y, 2), - dsys: "display", - cx: c.x, cy: c.y, cpos: tr(c.x, 2) + sep2 + tr(c.y, 2), - csys: c.sys, - ra: "", dec: "", wcspos: "", wcssys: "", - racen: "", deccen: "", - wcsfov: "", wcspix: "", - val: val, val3: val3, - id: this.id, file: this.file, object: this.object||""}; - if( this.telescope || this.instrument ){ - if( obj.object ){ obj.object += " "; } - obj.object += "("; - if( this.telescope ){ - obj.object += this.telescope; - if( this.instrument ){ - obj.object += ", "; - } - } - if( this.instrument ){ - obj.object += this.instrument; - } - obj.object += ")"; - } - // add wcs, if necessary - if( this.validWCS() && JS9.isWCSSys(this.params.wcssys) ){ - s = JS9.pix2wcs(this.raw.wcs, ipos.x, ipos.y).trim().split(/\s+/); - vstr3 = `${s[0]} ${s[1]} (${s[2]||"wcs"})`; - vstr = vstr1 + sp + vstr3 + sp + vstr2; - // update object with wcs - obj.ra = s[0]; - obj.dec = s[1]; - obj.wcspos = s[0] + sep1 + s[1]; - obj.wcssys = s[2]; - if( this.raw.wcsinfo ){ - cd1 = Math.abs(this.raw.wcsinfo.cdelt1); - cd2 = Math.abs(this.raw.wcsinfo.cdelt2); - v1 = 1/60; - if( this.raw.header.CUNIT1 ){ - units = this.raw.header.CUNIT1; - } - if( !units || units.match(/^deg/i) ){ - if( (cd1 >= 1) || (cd2 >= 1) ){ - units = "deg"; - } else if( (cd1 >= v1) || (cd2 >= v1) ){ - units = "'"; - cd1 *= 60; - cd2 *= 60; - } else { - units = '"'; - cd1 *= 3600; - cd2 *= 3600; - } - } - sect = this.rgb.sect; - v1 = ((sect.x1 - sect.x0) * cd1).toFixed(0); - v2 = ((sect.y1 - sect.y0) * cd2).toFixed(0); - obj.wcsfov = `${v1}${units} × ${v2}${units}`; - v1 = tr(cd1 / sect.zoom, 3); - obj.wcspix = `${v1}${units}/pix`; - obj.wcsfovpix = `${obj.wcsfov} (${obj.wcspix})`; - s = JS9.pix2wcs(this.raw.wcs, - (sect.x1 + sect.x0)/2, (sect.y1 + sect.y0)/2) - .trim().split(/\s+/); - obj.racen = s[0]; - obj.deccen = s[1]; - obj.wcscen = s[0] + sep1 + s[1]; - } - } - obj.vstrsmall = vstr1 + sp + vstr2; - obj.vstr = vstr; - obj.vstrmedium = vstr; - obj.vstrlarge = vstr + sp + this.file; - if( disp ){ - this.display.displayMessage("info", obj, - JS9.globalOpts.valposTarget); - } - } - return obj; -}; - -// toggle display of value/position -JS9.Image.prototype.toggleValpos = function(){ - this.params.valpos = !this.params.valpos; - if( !this.params.valpos ){ - this.display.clearMessage(); - } -}; - -// get color map name -JS9.Image.prototype.getColormap = function(){ - if( this.cmapObj ){ - return {colormap: this.cmapObj.name, - contrast: this.params.contrast, - bias: this.params.bias}; - } -}; - -// set color map -// calling sequences: -// setColormap(name); -// setColormap(name, contrast, bias); -// setColormap(name, staticOpts); -// setColormap(contrast, bias); -// setColormap(staticOpts); -// setColormap("rgb"); -// setColormap("invert"); -// setColormap("reset"); -JS9.Image.prototype.setColormap = function(...args){ - let [arg, arg2, arg3] = args; - let arr; - const setCmap = (arg) => { - if( this.cmapObj ){ - // unset rgb mode, if necessary - switch(this.cmapObj.name){ - case "red": - if( this.display.rgb.rim === this ){ - this.display.rgb.rim = null; - } - break; - case "green": - if( this.display.rgb.gim === this ){ - this.display.rgb.gim = null; - } - break; - case "blue": - if( this.display.rgb.bim === this ){ - this.display.rgb.bim = null; - } - break; - } - } - // remove previous static colormap - delete this.staticObj; - // add the new colormap - this.cmapObj = JS9.lookupColormap(arg); - this.params.colormap = this.cmapObj.name; - // for static colormaps, copy the static object (we might edit it) - if( this.cmapObj.type === "static" ){ - this.staticObj = $.extend(true, {}, this.cmapObj); - } - // set rgb mode, if necessary - switch(arg){ - case "red": - this.display.rgb.rim = this; - break; - case "green": - this.display.rgb.gim = this; - break; - case "blue": - this.display.rgb.bim = this; - break; - default: - break; - } - // new colormap, turn off image overlay - this.params.overlay = false; - }; - const setContrastBias = (arg1, arg2) => { - arg1 = parseFloat(arg1); - if( !Number.isNaN(arg1) ){ - this.params.contrast = arg1; - } - arg2 = parseFloat(arg2); - if( !Number.isNaN(arg2) ){ - this.params.bias = arg2; - } - }; - const setStatic = (a) => { - let i, j, color, dval; - for(i=0; i 0 && dval <= 1 ){ - dval = dval * 255; - } - color.alpha = dval; - } - break; - case 3: - // min and max - color.min = parseFloat(a[i][1]); - if( Number.isNaN(color.min) ){ - color.min = -Infinity; - } - color.max = parseFloat(a[i][2]); - if( Number.isNaN(color.max) ){ - color.max = Infinity; - } - break; - default: - break; - } - break; - } - } - } - // new colormap, turn off image overlay - this.params.overlay = false; - } - // is this core service disabled? - // (only if the colormap has been set at least once!) - if( $.inArray("colormap", this.params.disable) >= 0 && this.cmapObj ){ - return; - } - switch(args.length){ - case 1: - switch(arg){ - case "rgb": - this.display.rgb.active = !this.display.rgb.active; - break; - case "overlay": - if( this.offscreen ){ - this.params.overlay = !this.params.overlay; - } - break; - case "invert": - this.params.invert = !this.params.invert; - break; - case "reset": - this.params.invert = JS9.imageOpts.invert; - this.params.contrast = JS9.imageOpts.contrast; - this.params.bias = JS9.imageOpts.bias; - break; - default: - if( this.cmapObj && this.cmapObj.type === "static" ){ - if( $.isArray(arg) ){ - setStatic(arg); - } else if( typeof arg === "string" && arg.charAt(0) === '[' ){ - try{ - arr = JSON.parse(arg); - setStatic(arr); - } - catch(e){ - JS9.error(`can't parse JSON in setColormap: ${arg}`, e); - } - } else { - setCmap(arg); - } - } else if( typeof arg === "string" ){ - setCmap(arg); - } - break; - } - break; - case 2: - if( JS9.isNumber(arg) && JS9.isNumber(arg2) ){ - setContrastBias(arg, arg2); - } else if( this.cmapObj && this.cmapObj.type === "static" ){ - setCmap(arg); - setStatic(arg2); - } - break; - case 3: - setCmap(arg); - setContrastBias(arg2, arg3); - break; - default: - break; - } - this.displayImage("colors"); - // hack: delete filterRGBImage from stash to avoid restore during reproject - this.xeqStashDiscard("filterRGBImage"); - // extended plugins - if( JS9.globalOpts.extendedPlugins ){ - this.xeqPlugins("image", "onsetcolormap"); - } - return this; -}; - -// get scale factor -JS9.Image.prototype.getScale = function(){ - if( this.params.scale ){ - return {scale: this.params.scale, - scalemin: this.params.scalemin, - scalemax: this.params.scalemax, - scaleclipping: this.params.scaleclipping}; - } -}; - -// set scale factor -JS9.Image.prototype.setScale = function(...args){ - let [s0, s1, s2] = args; - const newscale = (s) => { - if( JS9.scales.includes(s) ){ - this.params.scale = s; - } else if( s === "dataminmax" ){ - this.params.scaleclipping = "dataminmax"; - this.params.scalemin = this.raw.dmin; - this.params.scalemax = this.raw.dmax; - } else if( s === "zscale" ){ - if( (this.params.z1 === undefined) || - (this.params.z2 === undefined) ){ - this.zscale(false); - } - this.params.scaleclipping = "zscale"; - this.params.scalemin = this.params.z1; - this.params.scalemax = this.params.z2; - } else if( s === "zmax" ){ - if( (this.params.z1 === undefined) ){ - this.zscale(false); - } - this.params.scaleclipping = "zmax"; - this.params.scalemin = this.params.z1; - this.params.scalemax = this.raw.dmax; - } else if( s === "user" ){ - this.params.scaleclipping = "user"; - } else { - JS9.error(`unknown scale: ${s}`); - } - }; - // is this core service disabled? - if( $.inArray("scale", this.params.disable) >= 0 ){ - return; - } - if( args.length ){ - switch(args.length){ - case 1: - newscale(s0); - break; - case 2: - this.params.scalemin = parseFloat(s0); - this.params.scalemax = parseFloat(s1); - this.params.scaleclipping = "user"; - break; - default: - newscale(s0); - if( (s0 !== "zscale") && (s0 !== "zmax") ){ - this.params.scalemin = parseFloat(s1); - this.params.scalemax = parseFloat(s2); - this.params.scaleclipping = "user"; - } - break; - } - this.params.precision = - JS9.floatPrecision(this.params.scalemin, this.params.scalemax); - this.displayImage("colors"); - } - // extended plugins - if( JS9.globalOpts.extendedPlugins ){ - this.xeqPlugins("image", "onsetscale"); - } - return this; -}; - -// get opacity factor -JS9.Image.prototype.getOpacity = function(){ - let obj = {}; - if( JS9.notNull(this.params.opacity) ){ - obj.opacity = this.params.opacity; - } else { - obj.opacity = 1; - } - if( JS9.notNull(this.params.flooropacity) ){ - obj.flooropacity = this.params.flooropacity; - obj.floorvalue = this.params.floorvalue; - } - return obj; -}; - -// set opacity factor: -// set default opacity for all pixels -// setOpacity(0.9) -// set opacity floor: for pixel values <= 1st arg assign 2nd arg as opacity -// setOpacity(5, 0.2) -// set default opacity, for pixel values <= 2nd arg, assign 3rd arg as opacity -// setOpacity(0.9, 5, 0.2) -// reset default opacity to 1 -// setOpacity("reset") -// remove opacity floor -// setOpacity("resetfloor") -// reset default opacity to 1, remove opacity floor -// setOpacity("resetall") -JS9.Image.prototype.setOpacity = function(...args){ - let [a1, a2, a3] = args; - // is this core service disabled? - if( $.inArray("opacity", this.params.disable) >= 0 ){ - return; - } - if( args.length ){ - switch(args.length){ - case 1: - if( typeof a1 === "string" ){ - if( a1.toLowerCase() === "reset" ){ - this.params.opacity = 1; - } else if( a1.toLowerCase() === "resetfloor" ){ - delete this.params.floorvalue; - delete this.params.flooropacity; - } else if( a1.toLowerCase() === "resetall" ){ - this.params.opacity = 1; - delete this.params.floorvalue; - delete this.params.flooropacity; - } - } else if( JS9.isNumber(a1) ){ - this.params.opacity = parseFloat(a1); - } - break; - case 2: - if( JS9.isNumber(a1) && JS9.isNumber(a2) ){ - this.params.floorvalue = parseFloat(a1); - this.params.flooropacity = parseFloat(a2); - } - break; - case 3: - if( JS9.isNumber(a1) ){ - this.params.opacity = parseFloat(a1); - } - if( JS9.isNumber(a2) && JS9.isNumber(a3) ){ - this.params.floorvalue = parseFloat(a2); - this.params.flooropacity = parseFloat(a3); - } - break; - default: - break; - } - // if we just set opacity (not reset), it must mean we want to use it, - // so turn off opacity masking, if necessary - if( typeof a1 === "number" || - (typeof a1 === "string" && !a1.match(/reset/)) ){ - if( this.mask.active && this.mask.im ){ - this.mask.active = false; - } - } - this.displayImage("colors"); - } - // extended plugins - if( JS9.globalOpts.extendedPlugins ){ - this.xeqPlugins("image", "onsetopacity"); - } - return this; -}; - -// get an image param value -JS9.Image.prototype.getParam = function(param){ - // sanity check - if( !param ){ return null; } - // return param object - if( param === "all" ){ - return this.params; - } - // return value - return this.params[param]; -}; - -// set an image param value -JS9.Image.prototype.setParam = function(param, value){ - let i, idx, ovalue, obj; - const getval = (s) => { - if( s === "true" ){ - return true; - } - if( s === "false" ){ - return false; - } - if( !JS9.isNumber(s) ){ - return s; - } - return parseFloat(s); - }; - // sanity check - if( !param ){ return null; } - // convert strings to values - value = getval(value); - // merge in new params - if( param === "all" && typeof value === "object" ){ - $.extend(true, this.params, value); - // call core methods as needed - if( value.colormap || value.contrast || value.bias ){ - obj = this.getColormap(); - value.colormap = value.colormap || obj.colormap; - value.contrast = value.contrast || obj.contrast; - value.bias = value.bias || obj.bias; - this.setColormap(value.colormap, value.contrast, value.bias); - } - if( value.scale || value.scalemin || value.scalemax ){ - obj = this.getScale(); - value.scale = value.scale || obj.scale; - value.scalemin = value.scalemin || obj.scalemin; - value.scalemax = value.scalemax || obj.scalemax; - this.setScale(value.scale, value.scalemin, value.scalemax); - } - if( value.flip ){ - this.setFlip("reset"); - this.setFlip(value.flip); - } - if( value.rot90 ){ - this.setRot90("reset"); - this.setRot90(value.rot90); - } - if( value.rotate ){ - this.setRotate("reset"); - this.setRotate(value.rotate); - } - if( value.invert ){ - this.params.invert = value.invert; - this.displayImage("colors"); - } - if( value.zoom ){ - this.setZoom(value.zoom); - } - if( value.wcssys ){ - this.setWCSSys(value.wcssys); - } - if( value.wcsunits ){ - this.setWCSUnits(value.wcsunits); - } - return this.params; - } else if( param === "disable" ){ - if( !$.isArray(value) ){ - value = [value]; - } - for(i=0; i= 0 ){ - this.params.disable.splice(idx, 1); - } - } - return this.params.disable; - } - // save old value - ovalue = this.params[param]; - // set new value - this.params[param] = value; - // call core methods as needed - switch(param){ - case "colormap": - this.setColormap(value); - break; - case "invert": - this.displayImage("colors"); - break; - case "contrast": - obj = this.getColormap(); - this.setColormap(obj.colormap, value, obj.bias); - break; - case "bias": - obj = this.getColormap(); - this.setColormap(obj.colormap, obj.contrast, value); - break; - case "overlay": - this.displayImage("colors"); - break; - case "flip": - this.setFlip("reset"); - this.setFlip(value); - break; - case "rot90": - this.setRot90("reset"); - this.setRot90(value); - break; - case "rotate": - this.setRotate("reset"); - this.setRotate(value); - break; - case "scale": - this.setScale(value); - break; - case "scalemin": - obj = this.getScale(); - this.setScale("user", value, obj.scalemax); - break; - case "scalemax": - obj = this.getScale(); - this.setScale("user", obj.scalemin, value); - break; - case "scaleclipping": - obj = this.getScale(); - this.setScale(value, obj.scalemin, obj.scalemax); - break; - case "wcssys": - this.setWCSSys(value); - break; - case "wcsunits": - this.setWCSUnits(value); - break; - case "zoom": - this.setZoom(value); - break; - } - // return old value - return ovalue; -}; - -// copy params from one image to another -JS9.Image.prototype.copyParams = function(params, images, opts){ - let i, j, im, param, val; - let xims = []; - // sanity check - if( !params ){ return; } - // opts is optional - opts = opts || {}; - if( typeof params === "string" && params.charAt(0) === '[' ){ - try{ params = JSON.parse(params); } - catch(e){ JS9.error(`can't parse JSON in copyParams: ${params}`, e); } - } - if( !$.isArray(params) ){ params = [params]; } - // do regions first to avoid problems with changes to the current image - i = $.inArray("regions", params); - if( i >= 0 ){ - params.splice(i, 1); - params.unshift("regions"); - } - // default is all images - images = images || JS9.images; - if( typeof images === "string" && images.charAt(0) === '[' ){ - try{ images = JSON.parse(images); } - catch(e){ JS9.error(`can't parse JSON in copyParams: ${images}`, e); } - } - if( !$.isArray(images) ){ images = [images]; } - // for each image - for(i=0; i 0 ){ - // integer data: BLANK header value specifies data value to ignore - if( raw.header.BLANK !== undefined ){ - blankval = raw.header.BLANK; - for(i=0; i raw.dmax ){ raw.dmax = val; } - } - } - } else { - for(i=0; i raw.dmax ){ raw.dmax = val; } - } - } - } else { - // float data: ignore NaN, infinity - for(i=0; i raw.dmax ){ raw.dmax = val; } - } - } - } - } - // re-set scaling values, if necessary - if( reminscale ){ params.scalemin = raw.dmin; } - if( remaxscale ){ params.scalemax = raw.dmax; } - // set new precision - params.precision = JS9.floatPrecision(params.scalemin, params.scalemax); - // allow chaining - return this; -}; - -// the zscale calculation -JS9.Image.prototype.zscale = function(setvals){ - let s, rawdata, bufsize, buf, vals; - // sanity check - if( !JS9.zscale || !this.raw || !this.raw.data ){ return this; } - rawdata = this.raw.data; - // allocate space for the image in the emscripten heap - bufsize = rawdata.length * rawdata.BYTES_PER_ELEMENT; - try{ buf = JS9.vmalloc(bufsize); } - catch(e){ JS9.error(`image too large for zscale malloc: ${bufsize}`, e); } - // copy the raw image data to the heap - // try{ JS9.vheap.set(new Uint8Array(rawdata.buffer), buf); } - try{ JS9.vmemcpy(new Uint8Array(rawdata.buffer), buf); } - catch(e){ JS9.error(`can't copy image to zscale heap: ${bufsize}`, e); } - // call the zscale routine - s = JS9.zscale(buf, - this.raw.width, - this.raw.height, - this.raw.bitpix, - this.params.zscalecontrast, - this.params.zscalesamples, - this.params.zscaleline); - // free emscripten heap space - JS9.vfree(buf); - // clean up return values - vals = s.trim().split(/\s+/); - // save z1 and z2 - this.params.z1 = parseFloat(vals[0]); - this.params.z2 = parseFloat(vals[1]); - // make z1 and z2 the scale clip values, if necessary - if( setvals === "zmax" ){ - this.params.scalemin = this.params.z1; - this.params.scalemax = this.raw.dmax; - } else if( setvals ){ - this.params.scalemin = this.params.z1; - this.params.scalemax = this.params.z2; - } - this.params.precision = - JS9.floatPrecision(this.params.scalemin, this.params.scalemax); - // allow chaining - return this; -}; - -// background-subtracted counts in regions -// eslint-disable-next-line no-unused-vars -JS9.Image.prototype.countsInRegions = function(...args){ - let i, s, vfile, bvfile, sect, ext, filter, bin, opts, cmdswitches; - let sregions = "field"; - let bregions = ""; - const getreg = (arg, def) => { - let ii, rarr, reg, narg; - const regrexp= /(annulus|box|circle|ellipse|line|polygon|point|text) *\(/; - // if we have no region, we're done - if( !arg ){ - return def; - } - if( typeof arg === "string" ){ - narg = this.expandMacro(arg); - // if we have no region, we're done - if( !narg ){ - return def; - } - // if its a known region, we're done - if( narg.match(regrexp) ){ - return narg; - } - } - // look for a region specifier - rarr = this.getShapes("regions", arg); - // no region are returned: this is an error - if( !rarr || !rarr.length ){ - JS9.error(`no regions found: ${arg}`); - } - // compose a region string from the returned regions - narg = ""; - for(ii=0; ii 1 ){ - if( this.imtab === "table" ){ - // for tables, regcnts has a -b switch - cmdswitches += ` -b ${bin}`; - } else { - // for images, make a temporary binned file - bvfile = `bin${bin}_${vfile.split("/").reverse()[0]}`; - sect = `0@0,0@0,${bin}`; - JS9.imsection(vfile, bvfile, sect, ""); - vfile = bvfile; - } - } - } - // could take a while ... - JS9.waiting(true, this.display); - // call low-level regcnts - s = JS9.regcnts(vfile, sregions, bregions, cmdswitches); - // all done waiting - JS9.waiting(false); - // remove binned file, if necessary - if( bvfile ){ - JS9.vunlink(bvfile); - } - // check for regions or cfitio errors - if( s.match(/^ERROR/) || s.match(/FITSIO status/) ){ - JS9.error(s); - } - // display in a lightwin, if necessary - if( opts.lightwin ){ - // display counts in a light window - this.displayAnalysis("text", s, {divid: JS9.globalOpts.analysisDiv}); - } - // return results, including errors - return s; -}; - -// radial profile plot -// eslint-disable-next-line no-unused-vars -JS9.Image.prototype.radialProfile = function(...args){ - let i, s, xlabel, ylabel, obj, cobj, pobj, res, el, opts; - let color, errorbars, errorcolor; - const carr = []; - const swobj = {cmdswitches: "-G -j -r"}; - // make up arg list, add required radial profile switches to opts - for(i=0; i res.radius2 ){ - JS9.error("radial profile source region must be an annulus"); - } - el = [(res.radius1 + res.radius2)/2, res.surfBrightness, res.surfError]; - pobj.data.push(el); - } - // display results - return this.displayAnalysis("plot", pobj, - {divid: JS9.globalOpts.analysisDiv}); -}; - -// plot of a 3D cube a region -// eslint-disable-next-line no-unused-vars -JS9.Image.prototype.plot3d = function(src, bkg, opts){ - let i, j, s, arr, jobj, el, pobj, color, mode, divid, xlabel, ylabel; - let index3, xoff, xdelt; - const counts=[]; - if( !this.raw.header || this.raw.header.NAXIS !== 3 ){ - JS9.error("plot3d requires a data cube with 3 dimensions"); - } - // opts is optional - opts = $.extend(true, {}, opts, JS9.globalOpts.plot3d); - // slice - opts.cube = opts.cube || "*:*:all"; - // make sure 'all' is specified - arr = opts.cube.split(":"); - for(i=0; i return name of current raw - if( !args.length ){ - return this.raw.id; - } - // opts is optional - opts = opts || {}; - // opts is a string with second arg a func: generate opts object - // opts is a string, no func: switch to a different raw data layer - // opts is a string + "remove": remove specified layer - if( typeof opts === "string" ){ - if( typeof func === "function" ){ - // change: rawDataLayer(id, func) to rawDataLater(obj, func) - opts = {rawid: opts}; - } else { - id = opts; - mode = func; - // look for raw layer with the specified id - for(i=0; i= 0 ){ - this.raws[cur] = nraw; - } else { - this.raws.push(nraw); - } - // assign this nraw to the high-level raw data object - this.raw = nraw; - // renew bitpix, if necessary - if( this.raw.header.bitpix ){ - this.raw.bitpix = this.raw.header.bitpix; - } - // re-calculate min and max, if necesary - if( opts.dataminmax !== false ){ - this.dataminmax(); - } - // re-init coordinate systems, if necessary - if( opts.updatewcs ){ - // init WCS, if possible - this.initWCS(); - // init the logical coordinate system, if possible - this.initLCS(); - } - // reset pan, if necessary - if( opts.resetpan ){ - this.setPan(); - } - // refresh shape layers - this.refreshLayers(); - // redisplay using these data - this.displayImage("all", opts); - // redo flip and rot - this.reFlipRot(); - } - return true; -}; - -// perform a gaussian blur on the raw data -// creates a new raw data layer ("gaussBlur") -JS9.Image.prototype.gaussBlurData = function(sigma, opts){ - if( sigma === undefined ){ - JS9.error("missing sigma value for gaussBlurData"); - } - // save value - this.params.sigma = sigma; - // opts is optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse gaussBlur opts: ${opts}`, e); } - } - // the blurred image will be floating point - if( this.raw.bitpix === -64 ){ - opts.bitpix = -64; - } else { - opts.bitpix = -32; - } - // use origin of current - opts.oraw = "current0"; - // nraw should be a floating point copy of oraw - opts.alwaysCopy = true; - // new layer - opts.rawid = opts.rawid || "gaussBlur"; - // pass the options - opts.sigma = sigma; - // save this routine so it can be reconstituted in a restored session - this.xeqStashSave("gaussBlurData", [sigma], opts.rawid); - // call routine to generate (or modify) the new layer - this.rawDataLayer(opts, (oraw, nraw) => { - let tdata; - // nraw contains a floating point copy of oraw - // make a temporary copy of nraw data for calculations - switch(nraw.bitpix){ - case -32: - tdata = new Float32Array(nraw.data); - break; - case -64: - tdata = new Float64Array(nraw.data); - break; - default: - JS9.error(`invalid temp bitpix for gaussBlur: ${nraw.bitpix}`); - break; - } - // the heart of the matter! - gaussBlur(tdata, nraw.data, nraw.width, nraw.height, sigma); - return true; - }); - // allow chaining - return this; -}; - -// perform arithmetic operations on the raw data -// creates a new raw data layer ("imarith") -JS9.Image.prototype.imarithData = function(...args){ - let im; - let [op, arg1, opts] = args; - // no args means return the available ops - if( !args.length ){ - return ["add", "sub", "mul", "div", "min", "max", "reset"]; - } - // opts is optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse imarith opts: ${opts}`, e); } - } - opts.rawid = opts.rawid || "imarith"; - // special case: reset by deleting the layer - if( (op === "reset") || (op === "remove") ){ - this.rawDataLayer(opts.rawid, "remove"); - return; - } - // sanity check - if( op === undefined || arg1 === undefined ){ - JS9.error("missing arg(s) for image arithmetic"); - } - // save this routine so it can be reconstituted in a restored session - this.xeqStashSave("imarithData", args.slice(), opts.rawid); - // operation: add, sub, mul, div ... - switch(op){ - case "add": - case "sub": - case "mul": - case "div": - case "min": - case "max": - opts.op = op; - break; - default: - JS9.error(`invalid operator for image arithmetic: ${op}`); - break; - } - // arg1: can be an image object or a numeric value - if( typeof arg1 === "object" ){ - if( (this.raw.width !== arg1.raw.width) || - (this.raw.height !== arg1.raw.height) ){ - JS9.error("images must be the same size for image arithmetic"); - } - opts.argtype = "image"; - opts.argval = arg1; - } else if( JS9.isNumber(arg1) ){ - opts.argtype = "value"; - opts.argval = arg1; - } else { - // lookup the image by name - im = JS9.lookupImage(arg1); - if( !im ){ - JS9.error(`imarith arg1 must be an image or a constant: ${arg1}`); - } - opts.argval = im; - opts.argtype = "image"; - } - // check for invalid args - if( (opts.op === "div") && - (opts.argtype === "value") && (opts.argval === 0) ){ - JS9.error("imarith can't divide by zero (nor can anyone else)"); - } - // choose a decent bitpix - if( !opts.bitpix ){ - switch(opts.argtype){ - case "image": - if( (this.raw.bitpix > 0) && (opts.argval.raw.bitpix > 0) ){ - opts.bitpix = Math.max(this.raw.bitpix, opts.argval.raw.bitpix); - } else if( (this.raw.bitpix < 0) && (opts.argval.raw.bitpix < 0) ){ - opts.bitpix = Math.min(this.raw.bitpix, opts.argval.raw.bitpix); - } else if( (this.raw.bitpix < 0) && (opts.argval.raw.bitpix > 0) ){ - opts.bitpix = this.raw.bitpix; - } else { - opts.bitpix = opts.argval.raw.bitpix; - } - break; - case "value": - if( this.raw.bitpix === -64 ){ - opts.bitpix = -64; - } else { - opts.bitpix = -32; - } - break; - } - } - // nraw should be a opts.bitpix copy of oraw - opts.alwaysCopy = true; - // use current - opts.oraw = "current"; - // call routine to generate (or modify) the new layer - this.rawDataLayer(opts, (oraw, nraw, opts) => { - let i, val; - switch(opts.argtype){ - case "image": - val = opts.argval.raw.data; - switch(opts.op){ - case "add": - for(i=0; i { - let i, oi, oj, ni, nj, nlen, oU8, nU8, ooff, noff, blankval; - const bpp = oraw.data.BYTES_PER_ELEMENT; - if( nraw.xoff === undefined ){ - nraw.xoff = 0; - } - if( nraw.yoff === undefined ){ - nraw.yoff = 0; - } - nraw.xoff += opts.x; - nraw.yoff += opts.y; - if( !opts.fill || opts.fill === "clear" ){ - if( nraw.bitpix > 0 ){ - blankval = opts.blank || nraw.header.BLANK || 0; - nraw.header.BLANK = blankval; - } else { - blankval = NaN; - } - if( typeof nraw.data.fill === "function" ){ - nraw.data.fill(blankval); - } else { - for(i=0; i= oraw.height) ){ - continue; - } - oi = 0; - ni = oi + nraw.xoff; - nlen = oraw.width; - if( ni < 0 ){ - oi -= ni; - nlen += ni; - ni = 0; - } - if( (ni + nlen) > oraw.width ){ - nlen -= (ni + nlen) - oraw.width; - } - if( nlen <= 0 ){ - return false; - } - ooff = (oj * oraw.width + oi) * bpp; - oU8 = new Uint8Array(oraw.data.buffer, ooff, nlen * bpp); - noff = (nj * oraw.width + ni) * bpp; - nU8 = new Uint8Array(nraw.data.buffer, noff, nlen * bpp); - nU8.set(oU8); - } - return true; - }); - // allow chaining - return this; -}; - -// rotate image by changing WCS info and calling reprojectData -// creates a new raw data layer ("rotate") -// angle is in degrees (since CROTA2 is in degrees) -JS9.Image.prototype.rotateData = function(...args){ - let raw, oheader, nheader, arad, sinrot, cosrot, pos, arr; - let ocdelt1 = 0.0; - let ocdelt2 = 0.0; - let [angle, opts] = args; - // sanity checks - if( !this.raws || !this.raws[0] ){ - JS9.error("no raw data for reprojection"); - } - // go back to original data for reprojection - raw = this.raws[0]; - if( !raw.header || !raw.wcsinfo ){ - JS9.error("no WCS info available for reprojection"); - } - // opts is optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse rotate opts: ${opts}`, e); } - } - // save stash name - opts.stash = "rotateData"; - // but make sure we can set the id - opts.rawid = "rotate"; - // rotate raw data - opts.oraw = JS9.RAWID0; - // maintain current section, unless specified otherwise - if( opts.resetSection !== true ){ - opts.resetSection = false; - } - // old and new header - oheader = raw.header; - nheader = $.extend(true, {}, oheader); - // rotate around current center or file center (i.e., CRPIX1,2) - opts.center = opts.center || JS9.globalOpts.rotationCenter; - if( opts.center !== "file" && this.validWCS() ){ - pos = this.getPan(); - arr = JS9.pix2wcs(this.raw.wcs, pos.x, pos.y).trim().split(/\s+/); - if( arr && arr.length > 1 ){ - nheader.CRPIX1 = pos.x; - nheader.CRPIX2 = pos.y; - nheader.CRVAL1 = JS9.saostrtod(arr[0]); - if( JS9.isHMS(this.params.wcssys) ){ - nheader.CRVAL1 *= 15.0; - } - nheader.CRVAL2 = JS9.saostrtod(arr[1]); - } - } - // normalized values from wcslib - if( raw.wcsinfo ){ - ocdelt1 = raw.wcsinfo.cdelt1 || 0; - ocdelt2 = raw.wcsinfo.cdelt2 || 0; - } - // string directives instead of a numeric angle - if( typeof angle === "string" ){ - switch(angle.toLowerCase()){ - case "northisup": - case "northup": - angle = 0; - if( ocdelt1 > 0 ){ ocdelt1 = -ocdelt1; } - if( ocdelt2 < 0 ){ ocdelt2 = -ocdelt2; } - break; - default: - angle = parseInt(angle, 10); - break; - } - } - // new header same as old, but with a changed angle - // make up new WCS keywords - // use CD matrix if possible, else set CROTA2 - if( JS9.notNull(oheader.CD1_1) ){ - arad = -(angle * Math.PI / 180.0); - sinrot = Math.sin(arad); - cosrot = Math.cos(arad); - nheader.CD1_1 = oheader.CD1_1 * cosrot + oheader.CD1_2 * sinrot; - nheader.CD1_2 = oheader.CD1_1 * -sinrot + oheader.CD1_2 * cosrot; - nheader.CD2_1 = oheader.CD2_1 * cosrot + oheader.CD2_2 * sinrot; - nheader.CD2_2 = oheader.CD2_1 * -sinrot + oheader.CD2_2 * cosrot; - } else { - nheader.CROTA2 = angle; - nheader.CDELT1 = ocdelt1; - nheader.CDELT2 = ocdelt2; - } - // flag that we will use CROTA2 to modify LTM matrix - // needed because Montage does not know about LTM - opts.lcsUseRota2 = true; - // save ptype if possible - if( raw.wcsinfo ){ - nheader.ptype = raw.wcsinfo.ptype; - } - // save this routine so it can be reconstituted in a restored session - this.xeqStashSave("rotateData", args.slice(), opts.rawid); - // rotate by reprojecting the data - return this.reprojectData(nheader, opts); -}; - -// low-level reprojection: creates reprojected file, but does not display it -// instead, it returns the name of the reprojected FITS file (emscripten vfile) -// this is the basis for reprojectData, but can be used in other routines which -// require a reprojection -JS9.Image.prototype.reproject = function(wcsim, opts){ - let awvfile, awvfile2, wvfile, owvfile; - let wcsheader, wcsstr, oheader, nheader, theader; - let arr, ivfile, ovfile, rstr, key; - let tab, tx1, tx2, ty1, ty2, s; - let n, raw, avfile, earr, cmdswitches; - let i, tid, traw, maxx, maxy, maxpix; - let rcomplete = false; - const twcs = {}; - const wcsexp = /SIMPLE|BITPIX|NAXIS|NAXIS[1-4]|AMDX|AMDY|CD[1-2]_[1-2]|CDELT[1-4]|CNPIX[1-4]|CO1_[1-9][0-9]|CO2_[1-9][0-9]|CROTA[1-4]|CRPIX[1-4]|CRVAL[1-4]|CTYPE[1-4]|CUNIT[1-4]|DATE|DATE_OBS|DC-FLAG|DEC|DETSEC|DETSIZE|EPOCH|EQUINOX|EQUINOX[a-z]|IMAGEH|IMAGEW|LATPOLE|LONGPOLE|MJD-OBS|PC00[1-4]00[1-4]|PC[1-4]_[1-4]|PIXSCALE|PIXSCAL[1-2]|PLTDECH|PLTDECM|PLTDECS|PLTDECSN|PLTRAH|PLTRAM|PLTRAS|PPO|PROJP[1-9]|PROJR0|PV[1-3]_[1-3]|PV[1-4]_[1-4]|RA|RADECSYS|SECPIX|SECPIX|SECPIX[1-2]|UT|UTMID|VELOCITY|VSOURCE|WCSAXES|WCSDEP|WCSDIM|WCSNAME|XPIXSIZE|YPIXSIZE|ZSOURCE|LTM|LTV/; - const ptypeexp = /TAN|SIN|ZEA|STG|ARC/; - const addwcsinfo = (header, wcsinfo) => { - let theader; - if( !wcsinfo ){ return header; } - theader = $.extend(true, {}, header); - if( JS9.isNull(theader.CRVAL1) && !JS9.isNull(wcsinfo.crval1) ){ - theader.CRVAL1 = wcsinfo.crval1; - } - if( JS9.isNull(theader.CRVAL2) && !JS9.isNull(wcsinfo.crval2) ){ - theader.CRVAL2 = wcsinfo.crval2; - } - if( JS9.isNull(theader.CRPIX1) && !JS9.isNull(wcsinfo.crpix1) ){ - theader.CRPIX1 = wcsinfo.crpix1; - } - if( JS9.isNull(theader.CRPIX2) && !JS9.isNull(wcsinfo.crpix2) ){ - theader.CRPIX2 = wcsinfo.crpix2; - } - if( JS9.isNull(theader.CDELT1) && !JS9.isNull(wcsinfo.cdelt1) ){ - theader.CDELT1 = wcsinfo.cdelt1; - } - if( JS9.isNull(theader.CDELT2) && !JS9.isNull(wcsinfo.cdelt2) ){ - theader.CDELT2 = wcsinfo.cdelt2; - } - if( JS9.isNull(theader.CROTA2) && !JS9.isNull(wcsinfo.crot) ){ - theader.CROTA2 = wcsinfo.crot; - } - return theader; - }; - // sanity checks - if( !JS9.reproject || !wcsim || this === wcsim ){ return; } - if( !this.raws || !this.raws[0] ){ - JS9.error("no raw data for reprojection"); - } - // go back to original data for reprojection - raw = this.raws[0]; - if( !raw.header || !raw.wcsinfo ){ - JS9.error("no WCS info available for reprojection"); - } - // opts is optional - opts = opts || {}; - // make copy of input header, removing wcs keywords - oheader = $.extend(true, {}, raw.header); - for( key of Object.keys(oheader) ){ - if( wcsexp.test(key) ){ - delete oheader[key]; - } - } - if( typeof wcsim === "object" ){ - // get wcs keywords from new header - if( wcsim.raw && wcsim.raw.header ){ - nheader = wcsim.raw.header; - } else if( wcsim.BITPIX && wcsim.NAXIS1 && wcsim.NAXIS2 ){ - // assume its a WCS header - nheader = wcsim; - } else { - JS9.error("invalid wcs object input to reproject()"); - } - for( key of Object.keys(nheader) ){ - if( wcsexp.test(key) ){ - twcs[key] = nheader[key]; - } - } - // combine new wcs keywords + old header keywords - wcsheader = $.extend(true, {}, twcs, oheader); - // sanity check on result - if( !wcsheader.NAXIS || !wcsheader.NAXIS1 || !wcsheader.NAXIS2 ){ - // JS9.error("invalid FITS image header"); - return; - } - // restrict size of reprojection - wcsheader.NAXIS1 = Math.min(wcsheader.NAXIS1, - JS9.globalOpts.image.xdim); - wcsheader.NAXIS2 = Math.min(wcsheader.NAXIS2, - JS9.globalOpts.image.ydim); - // convert reprojection header to a string - wcsstr = JS9.raw2FITS(wcsheader, {addcr: true}); - // create vfile text file containing reprojection WCS - wvfile = `wcs_${JS9.uniqueID()}.txt`; - JS9.vfile(wvfile, wcsstr); - // check limits on reprojection, if necessary - if( JS9.globalOpts.reprojectLimits ){ - // reprojection limits - maxx = JS9.globalOpts.image.xdim; - maxy = JS9.globalOpts.image.ydim; - // check max image dimension - maxpix = JS9.globalOpts.image.xdim * JS9.globalOpts.image.ydim; - // keep within the limits of current memory constraints, or die - if( (raw.header.NAXIS1 * raw.header.NAXIS2) > maxpix ){ - JS9.error(`the max reproject size is ${maxx} * ${maxy}. You can use the Bin/Filter/Section plugin to extract a section, then save it as FITS and reproject the smaller image.`); - } - } - } else { - wvfile = wcsim; - } - // check input and reproj WCS to make sure we can run fast mProjectPP - // if not, try to make an alternate WCS header amenable to mProjectPP - try{ - // try to change input WCS to a sys usable by mProjectPP - if( !ptypeexp.test(raw.wcsinfo.ptype) ){ - theader = addwcsinfo(raw.header, raw.wcsinfo); - owvfile = `owcs_${JS9.uniqueID()}.txt`; - JS9.vfile(owvfile, JS9.raw2FITS(theader, {addcr: true})); - awvfile = `awcs_${JS9.uniqueID()}.txt`; - rstr = JS9.tanhdr(owvfile, awvfile, ""); - if( JS9.DEBUG > 1 ){ - JS9.log("tanhdr (input): %s %s -> %s", - owvfile, awvfile, rstr); - } - JS9.vunlink(owvfile); - if( rstr.search(/\[struct stat="OK"/) >= 0 ){ - // add command switch to use this alternate wcs - opts.cmdswitches = opts.cmdswitches || ""; - opts.cmdswitches += ` -i ${awvfile}`; - } - } - // try to change reproject WCS to a sys usable by mProjectPP - if( (wcsim.raw && !ptypeexp.test(wcsim.raw.wcsinfo.ptype)) || - (wcsim.ptype && !ptypeexp.test(wcsim.ptype)) ){ - theader = addwcsinfo(nheader, wcsim.raw.wcsinfo); - owvfile = `owcs_${JS9.uniqueID()}.txt`; - JS9.vfile(owvfile, JS9.raw2FITS(theader, {addcr: true})); - awvfile2 = `awcs_${JS9.uniqueID()}.txt`; - rstr = JS9.tanhdr(owvfile, awvfile2, ""); - if( JS9.DEBUG > 1 ){ - JS9.log("tanhdr (reproj): %s %s -> %s", - owvfile, awvfile2, rstr); - } - JS9.vunlink(owvfile); - if( rstr.search(/\[struct stat="OK"/) >= 0 ){ - // delete old wcs file and use this alternate wcsfile - JS9.vunlink(wvfile); - wvfile = awvfile2; - } - } - } - catch(ignore){ /* empty */ } - // get reference to existing raw data file (or create one) - if( raw.hdu && raw.hdu.fits.vfile ){ - // input file name - ivfile = raw.hdu.fits.vfile; - // add extension name or number - if( raw.hdu.fits.extname ){ - ivfile += `[${raw.hdu.fits.extname}]`; - } else if( raw.hdu.fits.extnum && - (raw.hdu.fits.extnum > 0) ){ - ivfile += `[${raw.hdu.fits.extnum}]`; - } - } else { - // input file name - arr = this.toArray(); - ivfile = this.id.replace(/\.png$/, "_png" + ".fits"); - JS9.vfile(ivfile, arr); - } - // output file name - s = this.id - .replace(/\[.*\]/, "") - .replace(/\.png$/i, ".fits") - .replace(/\.fz$/i, "") - .replace(/\.gz$/i, ""); - ovfile = `reproj_${JS9.uniqueID()}_${s}`; - // remove previous vfile for this reprojection layer, if possible - tid = opts.rawid || "reproject"; - for(i=0; i= 0 ){ - avfile = `${ovfile.substring(0, n)}_area${ovfile.substring(n)}`; - } - // optional command line args - cmdswitches = opts.cmdswitches || ""; - // no area file, but add global switches for reproject processing - cmdswitches += ` -a 0 ${JS9.globalOpts.reprojSwitches}`; - // call reproject - rstr = JS9.reproject(ivfile, ovfile, wvfile, cmdswitches); - if( JS9.DEBUG > 1 ){ - JS9.log("reproject: %s %s %s [%s] -> %s", - ivfile, ovfile, wvfile, cmdswitches, rstr); - } - // delete unneeded files ... - JS9.vunlink(avfile); - JS9.vunlink(wvfile); - if( awvfile ){ - JS9.vunlink(awvfile); - } - if( arr ){ - JS9.vunlink(ivfile); - } - // ... then error check - if( rstr.search(/\[struct stat="OK"/) < 0 ){ - // signal this we completed the reproject attempt - rcomplete = true; - earr = rstr.match(/msg="(.*)"/); - if( earr && earr[1] ){ - JS9.error(`${earr[1]} (from mProjectPP)`); - } else { - JS9.error(rstr); - } - } - } - catch(e){ - // avoid double error reporting - if( !rcomplete ){ - // delete unneeded files ... - JS9.vunlink(avfile); - JS9.vunlink(wvfile); - // call error handler - if( rstr ){ - JS9.error(rstr); - } else { - JS9.error("WCS reproject failed", e); - } - } else { - return; - } - } - // return output file name - return ovfile; -}; - -// high-level routine to reproject image using WCS info -// creates a new raw data layer ("reproject") -JS9.Image.prototype.reprojectData = function(...args){ - let i, im, ovfile; - let [wcsim, opts] = args; - // sanity check - if( !wcsim || !JS9.reproject ){ return; } - // is this a string containing an image name or WCS values? - if( typeof wcsim === "string" ){ - if( wcsim === "all" ){ - for(i=0; i { - let topts, reprojHandler; - const defaultReprojHandler = (hdu) => { - // plugin callbacks - this.xeqPlugins("image", "onreprojectdata"); - topts = topts || {}; - topts.refreshRegions = true; - // reset section, unless specified otherwise - if( opts.resetSection !== false ){ - topts.resetSection = true; - } - // pass on the lcs flag - if( opts.lcsUseRota2 ){ - topts.lcsUseRota2 = true; - } - // refresh the image - this.refreshImage(hdu, topts); - // set status - this.setStatus("reprojectData", "complete"); - // might have to re-execute calls in the stash - this.xeqStashCall(this.xeqstash, [opts.stash, "reprojectData"]); - // execute onreproject function - if( typeof opts.onreproject === "function" ){ - try{ JS9.xeqByName(opts.onreproject, window, this); } - catch(e){ JS9.error("in onreproject callback", e, false); } - } - }; - // opts is optional - opts = opts || {}; - // handler - reprojHandler = opts.reprojHandler || defaultReprojHandler; - // call the low-level reproject routine, returning reprojected file - ovfile = this.reproject(wcsim, opts); - if( ovfile ){ - // refresh image using the reprojected file ... - topts = $.extend(true, {}, JS9.fits.options, opts); - // ... in a new raw data layer - topts.rawid = topts.rawid || "reproject"; - // save pointer to original wcs image - if( wcsim.raw && wcsim.raw.header ){ - topts.wcsim = wcsim; - } - // process the FITS file - try{ JS9.handleFITSFile(ovfile, topts, reprojHandler); } - catch(e){ JS9.error("can't process reprojected FITS file", e); } - } - }, JS9.SPINOUT); - // allow chaining - return this; -}; - -// apply image processing filters to the current RGB image -JS9.Image.prototype.filterRGBImage = function(...args){ - let [filter] = args; - // no arg: return list of filters - if( !filter ){ - return Object.keys(JS9.ImageFilters); - } - // pre-processing and special processing - switch(filter){ - case "reset": - // special case: reset to original RGB data, contrast/bias - this.setColormap("reset"); - return this; - case "median": - // alias used in filters plugin - filter = "medianFilter"; - break; - case "edge": - // alias used in filters plugin - filter = "edgeDetect"; - break; - default: - break; - } - // sanity check - if( !JS9.ImageFilters[filter] ){ - JS9.error(`JS9 image filter '${filter}' not available`); - } - // save this routine so it can be reconstituted in a restored session - this.xeqStashSave("filterRGBImage", args.slice()); - // remove filter name arg - args.shift(); - // add display context and RGB img arg - args.unshift(this.display.context, this.rgb.img); - // try to run the filter to generate a new RGB image - try{ JS9.ImageFilters[filter](...args); } - catch(e){ JS9.error(`JS9 image filter '${filter}' failed`, e); } - // display new RGB image - this.displayImage("display"); - // extended plugins - if( JS9.globalOpts.extendedPlugins ){ - this.xeqPlugins("image", "onfilterrgbimage"); - } - // allow chaining - return this; -}; - -// move image to a different display -// maybe this should be refactored using more useful routines ... -// ... and should (some of) this code be in the Fabric section?? -JS9.Image.prototype.moveToDisplay = function(dname){ - let i, im, key, layer, dlayer; - let got = 0; - const odisplay = this.display; - const ndisplay = JS9.lookupDisplay(dname); - // sanity check - if( !dname || !ndisplay ){ - JS9.error(`could not find display: ${dname}`); - } - // clear old display first - this.display.clearMessage(); - this.display.context.clear(); - // plugin callbacks - this.xeqPlugins("image", "onimageclear"); - // make sure the main layers in the old display are in the new display - for( key of Object.keys(odisplay.layers) ){ - if( (odisplay.layers[key].dtype === "main") && - !ndisplay.layers[key] ){ - ndisplay.newShapeLayer(key, odisplay.layers[key].opts); - } - } - // turn off display of layers in new display - // don't want them showing on the new image ... - if( ndisplay.image ){ - for( key of Object.keys(ndisplay.layers) ){ - if( ndisplay.layers[key].dtype === "main" ){ - ndisplay.image.showShapeLayer(key, false, {local: true}); - } - } - } - // re-assign each "main" layer from old display to new by: - // saving the graphics, reassigning the canvas, restoring the graphics - for( key of Object.keys(this.layers) ){ - layer = this.layers[key]; - dlayer = ndisplay.layers[key]; - if( dlayer ){ - this.showShapeLayer(key, false, {local: true}); - layer.dlayer = dlayer; - layer.divjq = dlayer.divjq; - layer.canvasjq = dlayer.canvasjq; - layer.canvas = dlayer.canvas; - } else { - delete this.layers[key]; - } - } - // move "main" display from old to new - this.display = ndisplay; - // avoid erroneous save of previous layers - this.display.image = this; - // reset section to ensure proper display size - this.mkSection(); - // and redisplay - this.displayImage("all"); - // show shape layers in new display - for( key of Object.keys(this.layers) ){ - this.showShapeLayer(key, true, {local: true}); - } - // move rgb contribution, if necessary - if( odisplay.rgb.rim === this ){ - odisplay.rgb.rim = null; - ndisplay.rgb.rim = this; - } - if( odisplay.rgb.gim === this ){ - odisplay.rgb.gim = null; - ndisplay.rgb.gim = this; - } - if( odisplay.rgb.bim === this ){ - odisplay.rgb.bim = null; - ndisplay.rgb.bim = this; - } - // old display has no image - odisplay.image = null; - // ensure proper positions for graphics - this.refreshLayers(); - // display a different image in old display, if possible - for(i=0; i= 0 ){ - JS9.displays.splice(i, 1); - } - odisplay.winid.close(); - } - // allow chaining - return this; -}; - -// save session to a json file -// NB: save is an image method, load is a display method -JS9.Image.prototype.saveSession = function(file, opts){ - let i, obj, str, blob, layer, dlayer, tobj, key, im, lpos, ipos; - const saveim = (im) => { - let regexp; - // object holding session keys - const obj = {}; - // filename - if( window.electron ){ - // remove current directory to make it relative - // this allows the session file (and data files) to be moved - // to a machine with a different directory structure, and - // also allows web and desktop sessions to be shared - regexp = new RegExp(`^${window.electron.currentDir}/`); - obj.file = im.file.replace(regexp, ""); - } else { - obj.file = im.file; - } - // display size info - obj.dwidth = im.display.width; - obj.dheight = im.display.height; - // image params - obj.params = $.extend(true, {}, im.params); - // temp values: explicitly save some of them - obj.tmp = {}; - if( im.tmp.gridStatus === "active" ){ - obj.tmp.gridStatus = "active"; - } - // get center of displayed image in physical coords - lpos = im.imageToLogicalPos({x:im.rgb.sect.xcen, - y:im.rgb.sect.ycen}); - ipos = im.maybePhysicalToImage(lpos); - if( ipos ){ - lpos = ipos; - } - // save section info - obj.sect = {}; - obj.sect.xcen = lpos.x; - obj.sect.ycen = lpos.y; - obj.sect.xdim = im.raw.width; - obj.sect.ydim = im.raw.height; - obj.sect.zoom = im.rgb.sect.zoom; - // layers - obj.layers = []; - for( key of Object.keys(im.layers) ){ - // save each main layer so it can be reconstituted - layer = im.layers[key]; - dlayer = layer.dlayer; - // only save layers on main display - // don't save crosshair or grid - if( dlayer.dtype === "main" && - key !== "crosshair" && - key !== "grid" ){ - tobj = {}; - tobj.name = key; - tobj.json = dlayer.canvas.toJSON(dlayer.el); - tobj.dopts = $.extend(true, {}, dlayer.opts); - if( layer.catalog ){ - tobj.catalog = layer.catalog; - } - if( layer.starbase ){ - tobj.starbase = JSON.stringify(layer.starbase); - } - obj.layers.push(tobj); - } - dlayer.canvas.forEachObject((obj) => { - // look for winid's: they cause circular json errors - if( obj.params && obj.params.winid ){ - if( $(obj.params.winid).is(":visible") ){ - JS9.error("please close your region dialog box(es) to avoid a JSON circular reference error when saving this session"); - } else { - obj.params.winid = null; - } - } - }); - } - // save blend state - obj.blend = im.blend; - // save routines which must be executed when restoring session - obj.xeqstash = im.xeqstash; - // save wcsim reference, if necessary - if( im.wcsim && im.wcsim.id ){ - obj.wcsim = im.wcsim.id; - } - // remove old display info - delete obj.params.display; - // remove rot90 and flip, as we will recreate them - obj.params.rot90 = 0; - obj.params.flip = "none"; - // we didn't save the crosshair - obj.params.crosshair = false; - return obj; - }; - if( !{}.hasOwnProperty.call(window, "saveAs") ){ - JS9.error("no saveAs() available to save session"); - } - // filename for saving - file = file || "js9.ses"; - // make sure we have the right extension - if( !file.match(/\.ses$/) ){ - file += ".ses"; - } - // opts is optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse session opts: ${opts}`, e); } - } - // change the cursor to show the waiting status - JS9.waiting(true, this.display); - // object we will save - obj = {}; - // list of images to save - obj.images = []; - // which images to save? - if( opts.mode === "display" ){ - // save all images in this display - for(i=0; i= 1 && - this.xeqstash[len-1] && - this.xeqstash[len-1].args[0] === -args[0] ){ - this.xeqstash.pop(); - return this; - } - break; - case "setFlip": - // two flips in the same direction cancel one another - len = this.xeqstash.length; - if( len >= 1 && - this.xeqstash[len-1] && - this.xeqstash[len-1].args[0] === args[0] ){ - this.xeqstash.pop(); - return this; - } - break; - default: - for(i=0; i { - let context = xeq.context || "image"; - try{ - switch(context){ - case "image": - this[func](...xeq.args); - break; - case "display": - this.display[func](...xeq.args); - break; - default: - this[func](...xeq.args); - break; - } - } - catch(e){ - JS9.error(`error executing stash: ${func}`, e, false); - } - }; - xeqstash = xeqstash || this.xeqstash; - if( $.isArray(xeqstash) ){ - for(i=0; i= 0 ){ - continue; - } - doxeq(key, xeq); - } - } else { - // backward compatibility: pre 3.1 used an object, not an array - for( key of Object.keys(xeqstash) ){ - if( $.inArray(key, exclArr) >= 0 ){ - continue; - } - xeq = xeqstash[key]; - doxeq(key, xeq); - } - } -}; - -// remove a stash routine -JS9.Image.prototype.xeqStashDiscard = function(xid){ - let i, key; - // sanity check - if( !this.xeqstash ){ return; } - if( $.isArray(this.xeqstash) ){ - for(i=this.xeqstash.length-1; i>=0; i--){ - if( xid === this.xeqstash[i].func || xid === this.xeqstash[i].id ){ - this.xeqstash.splice(i,1); - } - } - } else { - // pre 3.1 used an object - for( key of Object.keys(this.xeqstash) ){ - if( xid === key || xid === this.xeqstash[key].id ){ - delete this.xeqstash[key]; - } - } - } -}; - -// execute plugins of various types (using type-specific values) -JS9.Image.prototype.xeqPlugins = function(xtype, xname, xval){ - let pname, pinst, popts, parr, evt; - const xtrig = (name, obj) => { - const s = `JS9:${name}`; - $(document).trigger(s, obj); - }; - // sanity check - if( !xtype || !xname || !JS9.globalOpts.xeqPlugins ){ return; } - // array of plugin instances - parr = this.display.pluginInstances || {}; - // look for plugin callbacks to execute - for( pname of Object.keys(parr) ){ - pinst = parr[pname]; - popts = pinst.plugin.opts; - if( pinst.isActive(xname) && typeof popts[xname] === "function" ){ - this.callingPlugin = xname; - switch(xtype){ - case "image": - // used for: onimage[load,close,refresh,display] - try{ - popts[xname].call(pinst, this); - xtrig(xname, {im: this}); - } - catch(e){ pinst.errLog(xname, e); } - break; - case "region": - case "shape": - // used for: on[layer]change - // xval: pub - try{ - popts[xname].call(pinst, this, xval); - xtrig(xname, {im: this, xreg: xval}); - } - catch(e){ pinst.errLog(xname, e); } - break; - case "keydown": - case "keypress": - // used for: onkeydown, onkeypress (deprecated) - // xval: evt - evt = xval.originalEvent || xval; - try{ - popts[xname].call(pinst, this, this.ipos, evt); - xtrig(xname, {im: this, ipos: this.ipos, evt: evt}); - } - catch(e){ pinst.errLog(xname, e); } - break; - case "mouse": - // used for: onmouse[down,move,over,out] - // xval: evt - if( !this.clickInRegion || popts[`${xname}_inRegion`] ){ - evt = xval.originalEvent || xval; - try{ - popts[xname].call(pinst, this, this.ipos, evt); - xtrig(xname, {im: this, ipos: this.ipos, evt: evt}); - } - catch(e){ pinst.errLog(xname, e); } - } - break; - } - delete this.callingPlugin; - } - } - // allow chaining - return this; -}; - -// upload virtual file to proxy server -JS9.Image.prototype.uploadFITSFile = function(){ - let vfile, vdata; - const upcb = (r) => { - delete JS9.worker.uploadActive; - window.setTimeout(() => { JS9.progress(false); }, 1000); - if( r.stderr ){ - JS9.error(r.stderr); - } else if( r.stdout ){ - // set FITS filename and proxy filename - this.fitsFile = r.stdout.trim(); - this.proxyFile = this.fitsFile; - if( JS9.globalOpts.prependJS9Dir && - !this.fitsFile.match(/^\${JS9_DIR}/) && - this.fitsFile.charAt(0) !== "/" ){ - this.fitsFile = `\${JS9_DIR}/${this.fitsFile}`; - } - // re-query for analysis - this.queryHelper("all"); - } - }; - // sanity check - if( !JS9.worker ){ return; } - // only supported when using socket.io ... - if( JS9.helper.type !== "nodejs" && JS9.helper.type !== "socket.io" ){ - return; - } - // ... and only when we have a virtual file to upload - if( !this.raw.hdu || !this.raw.hdu.fits || !this.raw.hdu.fits.vfile ){ - return; - } - // only one upload at a time - if( JS9.worker.uploadActive ){ - JS9.error("only one upload allowed at a time"); - } - // this is the file to upload - vfile = this.raw.hdu.fits.vfile; - // ask the remote server if we can upload - JS9.helper.send("quotacheck", null, (robj) => { - // check quota, only errors matter - if( robj.stderr || robj.errcode ){ - JS9.error(robj.stderr || `from quotacheck: ${robj.errcode}`); - } - vdata = JS9.vread(vfile, "binary"); - JS9.worker.socketio(() => { - JS9.worker.uploadActive = true; - JS9.progress(true, this.display); - JS9.worker.send("uploadFITS", [vfile, vdata], upcb, [vdata.buffer]); - }); - }); - return this; -}; - -// remove proxy file from a remote server -JS9.Image.prototype.removeProxyFile = function(s){ - let t, reset, file, regexp; - const func = (r) => { - if( reset ){ - if( r && r.stdout.trim() === "OK" ){ - this.proxyFile = null; - this.proxyParent = null; - this.fitsFile = null; - this.analysisPackages = null; - this.queryHelper("all"); - } - } - }; - // arg can be a boolean, which means remove proxyFile and reset - if( typeof s === "boolean" ){ - reset = s; - } else if( typeof s === "string" ){ - // specify file to remove in the working directory - // check for attempt to break out of the working dir using abs path - if( s.match(/^\//) ){ - return; - } - // remove possible install dir prefix and then ... - // check attempt to break out of the working dir using ".." - regexp = new RegExp(`^${JS9.INSTALLDIR}`); - t = s.replace(regexp, ""); - if( t.match(/\.\./) ){ - return; - } - file = s; - } else { - // default is to remove the proxy file - if( !this.proxyFile ){ - return; - } - file = this.proxyFile; - // also remove the proxyParent file, if necessary - if( this.proxyParent ){ - file = `${file} ${this.proxyParent}`; - } - } - // sanity check - if( !file ){ return; } - // ask to remove proxy file, and process result - JS9.Send('removeproxy', {'cmd': `js9Xeq removeproxy ${file}`}, func); -}; - -// convert table to a shape array for the given image -JS9.Image.prototype.starbaseToShapes = function(starbase, opts){ - let i, j, k, shape, pos, siz, reg, data, header, delims, sizefunc; - let xcol, ycol, ra, dec, owcssys, wcssys, tcol, tregexp; - const global = JS9.globalOpts.catalogs; - const xcols = JS9.globalOpts.catalogs.ras; - const ycols = JS9.globalOpts.catalogs.decs; - const regs = []; - const getpos = (ra, dec) => { - let arr; - arr = JS9.wcs2pix(this.raw.wcs, ra, dec).trim().split(/ +/); - if( arr && arr.length ){ - return {x: parseFloat(arr[0]), y: parseFloat(arr[1])}; - } - return null; - }; - const getcol = (starbase, header, cols, defcol) => { - let i, j, col; - if( defcol !== undefined ){ - col = defcol; - } else { - // look for an exact match - col = -1; - for(j=0; j= 0 ){ - break; - } - } - // no exact match, look for an approx match - if( col < 0 ){ - tcol = cols[0]; - tregexp = new RegExp(`^${tcol}`, "i"); - for(i=0; i { - return { width: opts.width || global.width || 7, - height: opts.height || global.height || 7 }; - }; - break; - case "circle": - // eslint-disable-next-line no-unused-vars - sizefunc = () => { - return { radius: opts.radius || global.radius || 3.5}; - }; - break; - case "ellipse": - // eslint-disable-next-line no-unused-vars - sizefunc = () => { - return { r1: opts.r1 || global.r1 || 3.5, - r2: opts.r2 || global.r2 || 3.5 }; - }; - break; - default: - // eslint-disable-next-line no-unused-vars - sizefunc = () => { - return { width: opts.width || 7, height: opts.height || 7 }; - }; - break; - } - // save original wcs system - owcssys = this.getWCSSys(); - // set wcs system for catalogs - if( opts.wcssys ){ - wcssys = opts.wcssys; - } else if( global.wcssys ){ - wcssys = global.wcssys; - } else { - // umm ... - wcssys = "ICRS"; - } - // set wcssys for this catalog - this.setWCSSys(wcssys, false); - // convert each catalog object in the table into a JS9 shape - for(i=0, j=0; i { - const delims = " \t-.:hdmsr'\""; - const obj = {}; - obj.val = JS9.saostrtod(s); - obj.delim = String.fromCharCode(JS9.saodtype()); - if( (obj.delim !== "\0") && (delims.includes(obj.delim)) ){ - // valid delim means we converted to a float - return obj; - } else if( JS9.isNumber(s) ){ - // no delim, but its a number, so must be an int - return obj; - } - // everything else is a string - obj.val = s; - return obj; - }; - // special case: 1 non-string arg is the catalog, not the layer - if( args.length === 1 && typeof layer !== "string" ){ - catalog = layer; - layer = null; - } - // special case: 2 non-string args: file and obj, not the layer - if( args.length === 2 && typeof layer !== "string" ){ - opts = catalog; - catalog = layer; - layer = null; - } - // sanity check - if( !catalog ){ return; } - if( global.tooltip ){ - lopts.tooltip = global.tooltip; - } - // opts is optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse catalog opts: ${opts}`, e); } - } - // default color, if none specified - opts.color = opts.color || global.color || "#00FF00"; - // wcs system - opts.wcssys = opts.wcssys || global.wcssys; - // update the WCS strings when adding a catalog shape - opts.updateWCS = true; - // starbase opts - topts = {convFuncs: {def: defconv}, - units: opts.units || global.units, - skip: opts.skip || global.skip}; - // generate starbase table - try{ starbase = new JS9.Starbase(catalog, topts); } - catch(e){ JS9.error("could not parse catalog. Is it in tab-separated column format?"); } - // sanity check - if( !starbase || !starbase.data || !starbase.data.length ){ - JS9.error("no objects found in catalog"); - } - // generate new catalog shapes - shapes = this.starbaseToShapes(starbase, opts); - if( shapes.length ){ - // layer name - layer = layer || `catalog_${JS9.uniqueID()}` ; - // create a new layer, if necessary - this.display.newShapeLayer(layer, lopts); - // delete any old shapes - this.removeShapes(layer); - // save the original catalog before adding shapes - this.layers[layer].catalog = catalog; - this.layers[layer].starbase = starbase; - // add them to the catalog layer - this.addShapes(layer, shapes, opts); - } else { - JS9.error("no catalog objects found"); - } - // allow chaining - return this; -}; - -// save catalog as a file -JS9.Image.prototype.saveCatalog = function(fname, which){ - let layer, cat, blob; - layer = which || this.activeShapeLayer(); - if( !this.layers[layer] || !this.layers[layer].catalog ){ - if( layer && layer !== "undefined" ){ - JS9.error(`no catalog available: ${layer}`); - } else { - JS9.error("no active catalog available"); - } - } - cat = this.layers[layer].catalog; - blob = new Blob([cat], {type: "text/plain;charset=utf-8"}); - fname = fname || `${layer}.cat`; - if( !fname.match(/\.cat$/) ){ - fname += ".cat"; - } - if( {}.hasOwnProperty.call(window, "saveAs") ){ - JS9.saveAs(blob, fname); - } else { - JS9.error("no saveAs() available to save catalog"); - } - return fname; -}; - -// convert ra, dec from one wcs to another -JS9.Image.prototype.wcs2wcs = function(from, to, ra, dec){ - let owcssys, ounits, nwcs, arr, x, y, s, v0; - // save current wcs and units - owcssys = this.getWCSSys(); - ounits = this.getWCSUnits(); - // to, from default to current wcs - from = from || owcssys; - to = to || owcssys; - // convert ra, dec from string input to float degrees, if necessary - if( typeof ra === "string" ){ - v0 = JS9.strtoscaled(ra); - if( JS9.isHMS(from, v0.dtype) ){ - v0.dval *= 15.0; - } - ra = v0.dval; - } - if( typeof dec === "string" ){ - v0 = JS9.strtoscaled(dec); - dec = v0.dval; - } - // temporarily set the wcs to what we are converting from - nwcs = this.setWCSSys(from, false).getWCSSys(); - // make sure change was successful - if( from !== "native" ){ - if( nwcs !== from ){ - JS9.error(`unknown or invalid wcs: ${from}`); - } - } - // convert input ra, dec into image pixels in this wcs - arr = JS9.wcs2pix(this.raw.wcs, ra, dec).trim().split(/ +/); - x = parseFloat(arr[0]); - y = parseFloat(arr[1]); - // set wcs back to the target wcs - this.setWCSSys(to, false); - // convert image pixels from input ra, dec into target wcs - this.setWCSUnits("degrees", false); - s = JS9.pix2wcs(this.raw.wcs, x, y).trim(); - // reset wcs to original - this.setWCSUnits(ounits, false); - if( owcssys !== to ){ - this.setWCSSys(owcssys, false); - } - // return result - return s; -}; - -// convert wcs, physical or image image length to image length, -// using current wcs and string delimiters to determine what input type -JS9.Image.prototype.wcs2imlen = function(s){ - let v, wcsinfo, iscale; - let dpp = 1; - // sanity check - if( !s ){ return; } - v = JS9.strtoscaled(s); - wcsinfo = this.raw.wcsinfo || {cdelt1: 1, cdelt2: 1}; - // oh dear, this is cheating ... - if( wcsinfo.cdelt1 !== undefined ){ - dpp = wcsinfo.cdelt1; - } else if( wcsinfo.cdelt2 !== undefined ){ - dpp = wcsinfo.cdelt2; - } - switch(this.params.wcssys){ - case "image": - break; - case "physical": - // use LTM1_1 or LTM1_2 value stored for logical to image transforms - if( this.lcs && this.lcs.physical ){ - iscale = Math.sqrt(Math.pow(this.lcs.physical.forward[0][0],2) + - Math.pow(this.lcs.physical.forward[0][1],2)); - v.dval = Math.abs(v.dval * iscale); - } - break; - default: - // cheap conversion of wcs len to image len - if( v.dtype && (v.dtype !== ".") && (v.dtype !== "\0") ){ - v.dval = Math.abs(v.dval / dpp); - } - break; - } - return v.dval; -}; - -// --------------------------------------------------------------------- -// JS9 Colormap support -// --------------------------------------------------------------------- - -JS9.Colormap = function(...args){ - let [name, a1, a2, a3] = args; - let i, got; - // sanity check - if( !name ){ return; } - // type of colormap is based on number and type of args - this.name = name; - switch(args.length){ - case 2: - if( $.isArray(a1[0]) && typeof a1[0][0] === "number" ){ - // array of rgb values - // JS9.Colormap("sls", [[0, 0, 0], [0.043442, 0, 0.052883], ...]); - this.type = "lut"; - this.colors = a1; - } else { - // array of static colors and min, max values - // JS9.Colormap("s1", [["red",1,1], ["cyan",2,3], ["blue",4,99]]); - this.type = "static"; - this.colors = JS9.parseStaticColors(a1); - } - break; - case 4: - // three arrays of vertices - // JS9.Colormap("grey", [[0,0],[1,1]], [[0,0],[1,1]], [[0,0],[1,1]])); - this.type = "sao"; - this.vertices = [a1, a2, a3]; - break; - default: - JS9.error("colormap requires a colormap name and 1 or 3 array args"); - break; - } - // flag whether this was a core or user-defined colormap - if( !JS9.inited ){ - this.source = "core"; - } else { - this.source = "user"; - } - // replace or append - for(i=0; i 1 ){ - JS9.log("JS9 colormap: %s", this.name); - } -}; - -JS9.Colormap.prototype.mkColorCell = function(ii){ - let m, x, i, j, val, vertex, len, size, index; - const count = JS9.COLORSIZE; - const umax = 255; - const rgb = [0, 0, 0]; - switch(this.type){ - // from: tksao1.0/colormap/sao.C - case "sao": - x = ii / count; - // for each of red, green, blue ... - for(j=0; j<3; j++){ - // look for the first vertex with x value larger than our x value - vertex = this.vertices[j]; - len = vertex.length; - for(i=0; i x ){ - break; - } - } - // if first vertex x value is greater than ours, use it - if( i === 0 ){ - val = vertex[0][1]; - // if last vertex xvalue is less than ours, use it - } else if( i === len ){ - val = vertex[len-1][1]; - // interpolate between two vertices - } else { - m = (vertex[i][1] - vertex[i-1][1]) / - (vertex[i][0] - vertex[i-1][0]); - if( m ){ - // point slope form - val = m * (x - vertex[i-1][0]) + vertex[i-1][1]; - } else { - val = vertex[i][1]; - } - } - // assign value to the correct color in the result array - rgb[j] = val * umax; - } - break; - // from: tksao1.0/colormap/lut.C - case "lut": - size = this.colors.length; - // index into the evenly spaced RGB values - index = Math.floor(ii*size/count); - if( index < 0 ){ - rgb[0] = this.colors[0][0] * umax; - rgb[1] = this.colors[0][1] * umax; - rgb[2] = this.colors[0][2] * umax; - } else if( index < size ){ - rgb[0] = this.colors[index][0] * umax; - rgb[1] = this.colors[index][1] * umax; - rgb[2] = this.colors[index][2] * umax; - } else { - rgb[0] = this.colors[size-1][0] * umax; - rgb[1] = this.colors[size-1][1] * umax; - rgb[2] = this.colors[size-1][2] * umax; - } - break; - case "static": - break; - default: - JS9.error("unknown colormap type"); - break; - } - // return the news - return rgb; -}; - -// --------------------------------------------------------------------- -// JS9 display object for the screen display -// --------------------------------------------------------------------- - -JS9.Display = function(el){ - // pass jQuery element, DOM element, or id - if( el instanceof jQuery ){ - this.divjq = el; - } else if( typeof el === "object" ){ - this.divjq = $(el); - } else { - this.divjq = $(`#${el}`); - } - // make sure div has some id - if( !this.divjq.attr("id") ){ - this.divjq.attr("id", JS9.DEFID); - } - // save id - this.id = this.divjq.attr("id"); - // display-specific scratch space - this.tmp = {}; - // display RGB mode - this.rgb = { - active: false, - rim: null, - gim: null, - bim: null - }; - // add class - this.divjq.addClass("JS9"); - // set width and height on div - this.width = this.divjq.attr("data-width"); - if( !this.width ){ - this.width = JS9.WIDTH; - } - this.divjq.css("width", this.width); - this.width = parseInt(this.divjq.css("width"), 10); - this.height = this.divjq.attr("data-height"); - if( !this.height ){ - this.height = JS9.HEIGHT; - } - this.divjq.css("height", this.height); - this.height = parseInt(this.divjq.css("height"), 10); - // save original width and height - this.width0 = this.width; - this.height0 = this.height; - // set tabindex so we can sense keyboard events - // (this invocation senses keydown when no is image loaded) - this.divjq.attr("tabindex", 0); - // create DOM canvas element - this.canvas = document.createElement("canvas"); - // jquery version for event handling and DOM manipulation - this.canvasjq = $(this.canvas) - .addClass("JS9Image") - .attr("id", `${this.id}Image`) - .attr("width", this.width) - .attr("height", this.height) - .css("z-index", JS9.ZINDEX); - // add container to the high-level div - this.displayConjq = $("
    ") - .addClass("JS9Container") - .attr("id", `${this.id}DisplayConjq`) - .css("z-index", JS9.ZINDEX) - // set tabindex so we can sense keyboard events - // (this invocation senses keydown after image is loaded) - .attr("tabindex", "0") - .append(this.canvasjq) - .appendTo(this.divjq); - if( !JS9.allinone ){ - this.iconjq = $("
    ") - .addClass("JS9Logo") - .css("display", "none") - .css("z-index", JS9.ZINDEX+1) - .appendTo(this.divjq); - this.iconimgjs = $("") - .addClass("JS9Logo") - .attr("src", JS9.InstallDir(JS9.globalOpts.logo)) - .attr("alt", "js9") - .attr("title", "js9") - .appendTo(this.iconjq); - if( JS9.globalOpts.logoDisplay ){ - this.iconjq.css("display", "block"); - } - } - // add resize capability, if necessary - if( JS9.globalOpts.resizeHandle && - {}.hasOwnProperty.call(window, "ResizeSensor") ){ - this.divjq - .css("resize", "both") - .css("overflow", "hidden"); - if( JS9.bugs.webkit_resize ){ - this.owidth = parseInt(this.divjq.css("width"), 10); - this.oheight = parseInt(this.divjq.css("height"), 10); - this.divjq - .css("width", this.width + JS9.RESIZEFUDGE) - .css("height", this.height + JS9.RESIZEFUDGE); - } - this.resizeSensor = new ResizeSensor(this.divjq, () => { - let nwidth = this.divjq.width(); - let nheight = this.divjq.height(); - if( JS9.bugs.webkit_resize ){ - nwidth -= JS9.RESIZEFUDGE; - nheight -= JS9.RESIZEFUDGE; - } - this.resize(nwidth, nheight); - }); - } - // drawing context - this.context = this.canvas.getContext("2d"); - // turn off anti-aliasing - if( !JS9.ANTIALIAS ){ - this.context.imageSmoothingEnabled = false; - } - // add the display tooltip - this.tooltip = $("
    ") - .attr("id", `tooltip_${this.id}`) - .addClass("JS9Tooltip") - .appendTo(this.divjq); - // no image loaded into this canvas - this.image = null; - // no plugin instances yet - this.pluginInstances = {}; - // no layers yet - this.layers = {}; - // init message layer - this.initMessages(); - // blend mode is false to start - this.blendMode = false; - // display-based mouse/touch actions initially from global - this.mouseActions = JS9.globalOpts.mouseActions.slice(0); - this.touchActions = JS9.globalOpts.touchActions.slice(0); - // add event handlers - this.divjq.on("mouseenter", this, (evt) => { - return JS9.mouseEnterCB(evt); - }); - this.divjq.on("mouseover", this, (evt) => { - return JS9.mouseOverCB(evt); - }); - this.divjq.on("mousedown touchstart", this, (evt) => { - return JS9.mouseDownCB(evt); - }); - this.divjq.on("mousemove touchmove", this, (evt) => { - return JS9.mouseMoveCB(evt); - }); - this.divjq.on("mouseup touchend", this, (evt) => { - return JS9.mouseUpCB(evt); - }); - this.divjq.on("mouseout", this, (evt) => { - return JS9.mouseOutCB(evt); - }); - this.divjq.on("keypress", this, (evt) => { - return JS9.keyPressCB(evt); - }); - this.divjq.on("keydown", this, (evt) => { - return JS9.keyDownCB(evt); - }); - this.divjq.on("keyup", this, (evt) => { - return JS9.keyUpCB(evt); - }); - this.divjq.on("wheel", this, (evt) => { - return JS9.wheelCB(evt); - }); - // set up drag and drop, if available - this.divjq.on("dragenter", this, (evt) => { - return JS9.dragenterCB(this.id, evt); - }); - this.divjq.on("dragover", this, (evt) => { - return JS9.dragoverCB(this.id, evt); - }); - this.divjq.on("dragexit", this, (evt) => { - return JS9.dragexitCB(this.id, evt); - }); - this.divjq.on("drop", this, (evt) => { - return JS9.dragdropCB(this.id, evt); - }); - // no context menus on the display - this.divjq.on("contextmenu", this, () => { - return false; - }); - // add local file open support - this.addFileDialog("Load", JS9.globalOpts.imageTemplates); - this.addFileDialog("RefreshImage", JS9.globalOpts.imageTemplates); - this.addFileDialog("LoadRegions", JS9.globalOpts.regTemplates); - this.addFileDialog("LoadSession", JS9.globalOpts.sessionTemplates); - this.addFileDialog("LoadColormap", JS9.globalOpts.colormapTemplates); - this.addFileDialog("LoadCatalog", JS9.globalOpts.catalogTemplates); - // add to list of displays - JS9.displays.push(this); - // set focus - this.displayConjq.focus(); - // debugging - if( JS9.DEBUG ){ - JS9.log("JS9 display: %s", this.id); - } -}; - -// add support for file dialog box which executes JS9 routine on file blobs -JS9.Display.prototype.addFileDialog = function(funcName, template){ - let jdiv, jinput, id; - // sanity check - if( !funcName || !JS9.publics[funcName] ){ return; } - id = `openLocal${funcName}-${this.id}`; - // outer div - // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file - // recommends opacity over visibility, but it breaks the menubar in ios - jdiv = $("
    ") - .addClass("JS9Hidden") - .appendTo(this.divjq); - // inner file input element - jinput = $("") - .attr("type", "file") - .attr("id", id) - .attr("multiple", true) - .appendTo(jdiv); - // add accept template, if possible - if( template ){ - jinput.attr("accept", template); - } - // add callback for when input changes - jinput.on("change", (e) => { - let i, opts; - const el = e.currentTarget; - if( el.files.length ){ - switch(funcName){ - case "Load": - case "RefreshImage": - opts = {localAccess: true}; - JS9.waiting(true, this); - break; - default: - break; - } - } - for(i=0; i") - .addClass("JS9Container") - .css("z-index", JS9.MESSZINDEX) - .appendTo(this.divjq); - this.infoArea = $("
    ") - .addClass("JS9Message") - .appendTo(this.messageContainer); - this.regionsArea = $("
    ") - .addClass("JS9Message") - .appendTo(this.messageContainer); - this.progressArea = $("
    ") - .addClass("JS9Progress") - .addClass("JS9Message") - .appendTo(this.messageContainer); - this.progressBar = $("") - .addClass("JS9ProgressBar") - .attr("value", 0) - .attr("max", 100) - .attr("name", "progress") - .appendTo(this.progressArea); - // make it draggable, if possible - try{ - this.messageContainer.draggable({ - // eslint-disable-next-line no-unused-vars - start(event, ui) { - this.oicb = JS9.globalOpts.internalContrastBias; - JS9.globalOpts.internalContrastBias = false; - }, - // eslint-disable-next-line no-unused-vars - stop(event, ui) { - JS9.globalOpts.internalContrastBias = this.oicb; - } - }); - } - catch(ignore){ /* empty */ } - // allow chaining - return this; -}; - -// display a plugin in a light window or a new window -JS9.Display.prototype.displayPlugin = function(plugin){ - let i, a, w, h, p, r, s, title, name, did, oid, iid, odiv, pdiv, pinst, win; - if( typeof plugin === "string" ){ - for(i=0; i") - .attr("id", oid) - .css("display", "none") - .appendTo($(this.divjq)); - $("
    ") - .addClass(plugin.name) - .attr("id", iid) - .attr("data-js9id", this.divjq.attr("id")) - .css("height", "100%") - .css("width", "100%") - .appendTo(odiv); - } - // window not created: create and show it - // create the window - w = plugin.opts.winDims[0] || JS9.WIDTH; - h = plugin.opts.winDims[1] || JS9.HEIGHT; - if( plugin.opts.winResize ){ - r = "1"; - } else { - r = "0"; - } - // light window param string - s = sprintf(a.format, w, h, r); - // add the title, if explicitly called for and if not already added - if( plugin.opts.toolbarHTML && - plugin.opts.toolbarHTML.search(/\$title/) >= 0 ){ - title = ""; - } else { - title = plugin.opts.winTitle || ""; - } - // add display to title - title += sprintf(JS9.IDFMT, this.id); - // create the light window - win = JS9.lightWin(did, "div", oid, title, s); - // find inner div in the light window - pdiv = $(`#${did} #${iid}`); - // create the plugin inside the inner div - pinst = JS9.instantiatePlugin(pdiv, plugin, win); - pinst.winHandle.onclose = () => { - // just hide the window - pinst.winHandle.hide(); - pinst.status = "inactive"; - if( plugin.opts.onpluginclose ){ - try{ - plugin.opts.onpluginclose.call(pinst, this.image); - } - catch(e){ - JS9.log("onplugincloseCB: %s [%s]\n%s", - plugin.name, e.message, JS9.strace(e)); - } - } - return false; - }; - pinst.status = "active"; - if( plugin.opts.onplugindisplay ){ - try{ - plugin.opts.onplugindisplay.call(pinst, this.image); - } - catch(e){ - JS9.log("onplugindisplayCB: %s [%s]\n%s", - plugin.name, e.message, JS9.strace(e)); - } - } - } else if( pinst.status === "inactive" ){ - // window created but hidden: show it - if( pinst.winHandle ){ - pinst.winHandle.show(); - pinst.status = "active"; - if( plugin.opts.onplugindisplay ){ - try{ - plugin.opts.onplugindisplay.call(pinst, this.image); - } - catch(e){ - JS9.log("onplugindisplayCB: %s [%s]\n%s", - plugin.name, e.message, JS9.strace(e)); - } - } - } - } else if( pinst.status === "active" ){ - // window created and showing: hide it - if( pinst.winHandle ){ - pinst.winHandle.hide(); - pinst.status = "inactive"; - if( plugin.opts.onpluginclose ){ - try{ - plugin.opts.onpluginclose.call(pinst, this.image); - } - catch(e){ - JS9.log("onplugincloseCB: %s [%s]\n%s", - plugin.name, e.message, JS9.strace(e)); - } - } - } - } - break; - case "new": - JS9.error("external window support for plugins not yet implemented"); - break; - } -}; - -// display the general file-loading form for this display -JS9.Display.prototype.displayLoadForm = function(opts){ - let html, did, method; - const format = JS9.globalOpts.localLoadFormat; - if( JS9.globalOpts.remoteLoadMethod === "proxy" && !JS9.proxyAvailable() ){ - JS9.globalOpts.remoteLoadMethod = "cgiproxy"; - } - method = JS9.globalOpts.remoteLoadMethod; - // opts is optional, defaults to displaying local and remote - opts = opts || {local:true, remote:true}; - // options for creating window - if( JS9.isNull(opts.title) ){ - opts.title = ""; - if( opts.local ){ - opts.title = "Open "; - } - if( opts.remote ){ - if( opts.title ){ - opts.title += "or "; - } - opts.title += "Retrieve "; - } - opts.title += "an Image "; - if( opts.local ){ - opts.title += "or Auxiliary File"; - } - } - opts.winformat = opts.winformat || - "width=640px,height=300px,resize=1,scrolling=1"; - // from where do we get the html? - if( JS9.allinone ){ - html = JS9.allinone.loadHTML; - } else { - html = JS9.InstallDir(JS9.globalOpts.loadURL); - } - // call this once window is loaded to init form values - $(JS9.lightOpts[JS9.LIGHTWIN].topid) - .arrive(".loadForm", {onceOnly: true}, (el) => { - const localfile = $(el).data("localfile") || this.tmp.localfile; - const remotefile = $(el).data("remotefile") || this.tmp.remotefile; - if( opts.local ){ - $(did).find(".localfile").removeClass("nodisplay"); - $(did).find(".localdoc").removeClass("nodisplay"); - if( localfile ){ - $(did).find(`input[name="localfile"]`).val(localfile); - } - $(did).find(`input[value=${format}]`).click(); - } - if( opts.remote ){ - $(did).find(".remotefile").removeClass("nodisplay"); - $(did).find(".remotedoc").removeClass("nodisplay"); - if( remotefile ){ - $(did).find(`input[name="remotefile"]`).val(remotefile); - } - if( !JS9.proxyAvailable() ){ - $(did).find(`input[value="proxy"]`).prop("disabled", true); - } - $(did).find(`input[value=${method}]`).click(); - } - }); - // create the window - did = JS9.Image.prototype.displayAnalysis.call(null, "params", html, opts); - // save display id - $(did).data("dispid", this.id); -}; - -// resize a display -JS9.Display.prototype.resize = function(width, height, opts){ - let i, div, im, key, layer, nwidth, nheight, nleft, ntop, pinst, owidth; - const repos = (o) => { - o.left += nleft; - o.top += ntop; - o.setCoords(); - }; - // sanity check - if( !JS9.globalOpts.resize ){ - JS9.error("display resize not enabled"); - } - // no args => return current size - if( !width && !height ){ - return {width: this.width, height: this.height}; - } - // 'full' or 'reset' or 'image' - if( width === "full" ){ - opts = height; - if( window.innerWidth ){ - width = window.innerWidth; - } - if( window.innerHeight ){ - // including menubar, if available - height = window.innerHeight; - // divs we take into account when centering - for(i=0; i= 0 && - (JS9.isNull(opts.resizeMenubar) || opts.resizeMenubar) ){ - pinst = this.pluginInstances.JS9Menubar; - if( pinst ){ - $(`#${this.id}Menubar`).css("width", nwidth); - } - } - // change the toolbar width, unless explicitly told not to - if( $.inArray("JS9Toolbar", JS9.globalOpts.resizeDivs) >= 0 && - (JS9.isNull(opts.resizeToolbar) || opts.resizeToolbar) ){ - pinst = this.pluginInstances.JS9Toolbar; - if( pinst ){ - // set new value for width - pinst.divjq.attr("data-width", `${String(nwidth)}px`); - // re-init toolbar for this size - JS9.Toolbar.init.call(pinst); - } - } - // change the colorbar width, unless explicitly told not to - if( $.inArray("JS9Colorbar", JS9.globalOpts.resizeDivs) >= 0 && - (JS9.isNull(opts.resizeColorbar) || opts.resizeColorbar) ){ - pinst = this.pluginInstances.JS9Colorbar; - if( pinst ){ - // set new value for width - pinst.divjq.attr("data-width", `${String(nwidth)}px`); - // re-init colorbar for this size - JS9.Colorbar.init.call(pinst); - } - } - // change the statusbar width, unless explicitly told not to - if( $.inArray("JS9Statusbar", JS9.globalOpts.resizeDivs) >= 0 && - (JS9.isNull(opts.resizeStatusbar) || opts.resizeStatusbar) ){ - pinst = this.pluginInstances.JS9Statusbar; - if( pinst ){ - $(`#${this.id}Statusbar`).css("width", nwidth); - // resize colorbar, if necessary - if( pinst.statusBar && - pinst.statusBar.match(/\$colorbar/) && - opts.resizeStatusbarColorbar !== false ){ - pinst.colorwidth = Math.max(pinst.colorwidth + width - owidth, - JS9.Statusbar.COLORWIDTH); - JS9.Statusbar.display.call(pinst, this.image, {reinit: true}); - } - } - } - // change size of shape canvases - for( key of Object.keys(this.layers) ){ - layer = this.layers[key]; - if( layer.dtype === "main" ){ - layer.divjq.css("width", nwidth); - layer.divjq.css("height", nheight); - layer.canvasjq.attr("width", nwidth); - layer.canvasjq.attr("height", nheight); - layer.canvas.setWidth(nwidth); - layer.canvas.setHeight(nheight); - layer.canvas.calcOffset(); - } - } - // change position of shapes on currently displayed layers - // save resize parameters for undisplayed layers - for(i=0; i= this.divjq.width()) && - (pos.y + JS9.RESIZEDIST >= this.divjq.height()) ){ - return true; - } - } - return false; -}; - -// scroll the display to the center of the viewport -// http://stackoverflow.com/questions/18150090/jquery-scroll-element-to-the-middle-of-the-screen-instead-of-to-the-top-with-a -JS9.Display.prototype.center = function(){ - const el = this.divjq; - let i, div, tel, voffset, hoffset; - let elVOffset = el.offset().top; - let elHeight = el.height(); - const windowHeight = $(window).height(); - const elHOffset = el.offset().left; - const elWidth = el.width(); - const windowWidth = $(window).width(); - const speed = 250; - // divs we take into account when getting total height - for(i=0; i 0 ){ - j = $.inArray(odisp, JS9.displays); - if( j >= 0 ){ - JS9.displays.splice(j, 1); - } - el.remove(); - } - } - } - // extended plugins - if( JS9.globalOpts.extendedPlugins ){ - if( this.image ){ - this.image.xeqPlugins("image", "ongatherdisplay"); - } - } -}; - -// separate images in this display into new displays -JS9.Display.prototype.separate = function(opts){ - let arr, d0, d1, el; - let nsep = 0; - let row = 0; - let col = 0; - let myid = 1; - const sep = {}; - const saveims = {}; - const rexp = /_sep[0-9][0-9]*/; - const sepopts = JS9.globalOpts.separate; - const menuStr = "
    "; - const toolStr = "
    "; - const js9Str = "
    "; - const colorStr = "
    "; - const statusStr = "
    "; - const winoptsStr = "width=%s,height=%s,top=%s,left=%s,resize=1,scolling=1"; - const LIT_FUDGE = 5; - const COLORBAR_FUDGE = 7; - const DHTML_HEIGHT = 30 + 13; // height of dhtml lightwin extras; - const initopts = (display, fromID, opts) => { - // sanity check - if( !fromID ){ - JS9.error("can't init separation ops: no 'from' id"); - } - sep.layout = opts.layout || JS9.globalOpts.separate.layout || "auto"; - sep.leftMargin = opts.leftMargin || sepopts.leftMargin || 0; - sep.topMargin = opts.topMargin || sepopts.topMargin || 0; - // check if we want to do a grid ... and if we can - if( sep.layout === "auto" && - display.divjq.closest(".JS9GridContainer").length > 0 ){ - sep.layout = "grid"; - } - if( sep.layout === "grid" ){ - if( CSS.supports("display", "grid") ){ - el = display.divjq.closest(".JS9GridContainer"); - if( el.length > 0 ){ - sep.container = el; - } - } else { - sep.layout = "auto"; - } - } - switch(sep.layout){ - case "auto": - col = 1; - row = 0; - break; - case "horizontal": - col = 1; - row = 0; - break; - case "vertical": - col = 0; - row = 1; - break; - default: - col = 1; - row = 0; - break; - } - sep.topExtra = DHTML_HEIGHT; - sep.leftExtra = 0; - sep.js9 = $(`#${fromID}`); - sep.menubar = $(`#${fromID}Menubar`); - if( sep.menubar.length > 0 ){ - sep.menubar.isactive = sep.menubar.closest(".JS9PluginContainer").css("visibility") === "visible"; - } - sep.toolbar = $(`#${fromID}Toolbar`); - if( sep.toolbar.length > 0 ){ - sep.toolbar.isactive = sep.toolbar.closest(".JS9PluginContainer").css("visibility") === "visible"; - } - sep.statusbar = $(`#${fromID}Statusbar`); - if( sep.statusbar.length > 0 ){ - sep.statusbar.isactive = sep.statusbar.closest(".JS9PluginContainer").css("visibility") === "visible"; - } - sep.colorbar = $(`#${fromID}Colorbar`); - if( sep.colorbar.length > 0 && !sep.statusbar.length ){ - sep.colorbar.isactive = sep.colorbar.closest(".JS9PluginContainer").css("visibility") === "visible"; - } - if( sep.js9.length > 0 ){ - // hack: height of the dhtml drag handle and status area - sep.width = sep.js9.width(); - sep.height = sep.js9.height(); - sep.top = sep.js9.offset().top - $(window).scrollTop() - LIT_FUDGE; - sep.left = sep.js9.offset().left - $(document).scrollLeft(); - if( sep.menubar.isactive ){ - sep.height += sep.menubar.height(); - sep.top -= sep.menubar.height(); - } - if( sep.toolbar.isactive ){ - sep.height += sep.toolbar.height(); - sep.top -= sep.toolbar.height(); - } - if( sep.statusbar.isactive ){ - sep.height += sep.statusbar.height(); - sep.top -= sep.statusbar.height(); - } else if( sep.colorbar.isactive ){ - sep.height += sep.colorbar.height(); - sep.top -= sep.colorbar.height(); - sep.top += COLORBAR_FUDGE; - } - } - }; - const getopts = (fromID, toID) => { - let html, winopts; - if( fromID ){ - if( sep.js9.length > 0 ){ - html = ""; - if( sep.menubar.isactive ){ - html += sprintf(menuStr, toID, sep.js9.width()); - } - if( sep.toolbar.isactive ){ - html += sprintf(toolStr, toID, sep.js9.width()); - } - html += sprintf(js9Str, toID, sep.js9.width(),sep.js9.height()); - if( sep.statusbar.isactive ){ - html += sprintf(statusStr, toID, sep.js9.width()); - } else if( sep.colorbar.isactive ){ - html += sprintf(colorStr, toID, sep.js9.width()); - } - } - if( sep.layout === "auto" ){ - if( (sep.left + (sep.width * (col+0.5))) > window.innerWidth ){ - row++; - col = 0; - } - } - winopts = sprintf(winoptsStr, - sep.width, - sep.height, - sep.top + ((sep.height + sep.topMargin + sep.topExtra) * row), - sep.left + ((sep.width + sep.leftMargin + sep.leftExtra) * col)); - // move to next column - if( sep.layout === "auto" || sep.layout === "horizontal" ){ - col++; - } else if( sep.layout === "vertical" ){ - row++; - } - } - // return info for this column; - return {id: toID, html: html, winopts: winopts}; - }; - const separateim = (arr) => { - let im, xopts, id; - const n = nsep++; - if( arr.length > n ){ - if( typeof arr[n] === "number" ){ - im = JS9.images[arr[n]]; - } else { - im = arr[n]; - } - // look for images in this display - if( im && im.display === this ){ - // display this image so it's the current one we move - im.displayImage("all"); - // init params - if( d0 === undefined ){ - d0 = im.display.id; - initopts(im.display, d0, opts); - // if leave first image in place is false, decrement - // nsep so it gets separated on the next iteration - if( opts.firstinplace === false ){ - nsep--; - } - separateim(arr); - } else { - // create a new window for this image - if( typeof opts.idbase === "string" ){ - id = opts.idbase + myid++; - d1 = id; - } else { - d1 = `${d0.replace(rexp, "")}_sep${JS9.uniqueID()}`; - } - saveims[d1] = im; - xopts = getopts(d0, d1); - // replace id, if idbase was supplied in opts - if( id ){ - xopts.id = id; - } - if( sep.layout === "grid" ){ - // a div hold the html for this separated display, - // and is appended to grid container - $("
    ") - .prop("id", xopts.id + "GridItem") - .addClass("JS9GridItem") - .append($(xopts.html)) - .appendTo(sep.container); - // create the new JS9 display, with associated plugins - JS9.AddDivs(xopts.id); - // move this image - saveims[xopts.id].moveToDisplay(xopts.id); - // process next image - separateim(arr); - } else { - // create a light wndow - // code to run when new window exists - $(JS9.lightOpts[JS9.LIGHTWIN].topid) - .arrive(`#${d1}`, {onceOnly: true}, (el) => { - id = $(el).attr("id"); - // FF (at least) needs this 0ms delay - window.setTimeout(() => { - // move this image - saveims[id].moveToDisplay(id); - // process next image - separateim(arr); - }, 0); - }); - // load new window, code above gets run when window exists - JS9.LoadWindow(null, {id: xopts.id}, "light", - xopts.html, xopts.winopts); - } - } - } else { - // this image is in a different display, so process next image - separateim(arr); - } - } else { - // extended plugins - if( JS9.globalOpts.extendedPlugins ){ - if( this.image ){ - this.image.xeqPlugins("image", "onseparatedisplay"); - } - } - } - }; - // opts are optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse separate opts: ${opts}`, e); } - } - // array of images to use - arr = opts.images || JS9.images; - // start separating the images - separateim(arr); -}; - -// display the next image from the JS9 images list which is in this display -JS9.Display.prototype.nextImage = function(inc){ - let i, idx, nidx, im, dpos, npos; - let ims = []; - let masks = []; - inc = inc || 1; - if( !this.image ){ - return this; - } - dpos = this.image.pos; - // make list of image masks for this display - if( !JS9.globalOpts.nextImageMask ){ - for(i=0; i= 0 ){ - continue; - } - // candidate image - ims.push(im); - } - // if there is only one image, we're done - if( ims.length <= 1 ){ - return this; - } - // get index into images array for the currently displayed image - for(idx=0; idx= ims.length ){ - nidx -= ims.length; - } - // wrap if necessary - while( nidx < 0 ){ - nidx += ims.length; - } - // display if we are not back to where we started - if( idx !== nidx ){ - // display image, 2D graphics, etc. - im = ims[nidx]; - im.displayImage("all"); -// already done in displayImage() -// im.refreshLayers(); - im.display.clearMessage(); - if( dpos ){ - npos = im.displayToImagePos(dpos); - im.valpos = null; - im.valpos = im.updateValpos(npos, true); - } - } - // allow chaining - return this; -}; - -// load session from a json file -// NB: save is an image method, load is a display method -JS9.Display.prototype.loadSession = function(file, opts){ - let obj, left; - const objs = {}; - const finish = (im) => { - let i, dlayer, layer, lname, obj; - const dorender = () => { - // update layer's shape counter - const objs = dlayer.canvas.getObjects(); - if( objs && typeof objs.length !== "undefined" ){ - im.layers[dlayer.layerName].nshape = objs.length + 1; - } - // update objects for parents and children - JS9.Fabric.updateChildren(dlayer, null, "objects"); - // change shape positions if the displays sizes differ - im.refreshLayers(); - }; - // see: http://fabricjs.com/v5-breaking-changes - const reviver = (data, instance) => { - // detect that version is less than 5 - // change radians to degrees (for circles) - if (parseInt(data.version.slice(0, 1), 10) < 5) { - if( instance.startAngle ) instance.startAngle *= 180 / Math.PI; - if( instance.endAngle ) instance.endAngle *= 180 / Math.PI; - } - }; - obj = objs[im.file] || {}; - // reconstitute blend state - if( obj.blend ){ - im.blend = $.extend(true, {}, obj.blend); - } - // reconstitute tmp values - if( obj.tmp ){ - im.tmp = $.extend(true, {}, obj.tmp); - } - // reconstitute wcsim state - if( obj.wcsim ){ - im.wcsim = JS9.lookupImage(obj.wcsim); - } - // reconstitute layers - if( obj.layers && obj.layers.length ){ - for(i=0; i= 0 && - lname === "regions" ){ - continue; - } - // skip crosshair and grid - if( lname === "crosshair" || lname === "grid" ){ - continue; - } - // make sure layer exists in the display - dlayer = this.newShapeLayer(lname, layer.dopts); - // add a layer instance to this image (no objects yet) - im.addShapes(lname, []); - // load the session objects into the layer and render - dlayer.canvas.loadFromJSON(layer.json, dorender, reviver); - // restore catalog and starbase, if necessary - if( layer.catalog ){ - im.layers[lname].catalog = layer.catalog; - } - if( layer.starbase ){ - try{im.layers[lname].starbase = JSON.parse(layer.starbase);} - catch(ignore){ /* empty */ } - } - } - } - // if coordinate grid was active, display it - if( im.tmp && im.tmp.gridStatus === "active" ){ - im.displayCoordGrid(true); - } - // if all images are loaded, sort them to the original load order - if( JS9.notNull(left) ){ - left = left - 1; - if( left === 0 ){ - JS9.images.sort((a, b) => { - let ai = 0, bi = 0; - if( objs[a.file] ){ ai = objs[a.file].i; } - if( objs[b.file] ){ bi = objs[b.file].i; } - return ai - bi; - }); - } - } - // re-execute from the xeq stash - if( obj.xeqstash ){ - im.xeqStashCall(obj.xeqstash); - } - // plugin callbacks - if( JS9.globalOpts.extendedPlugins ){ - im.xeqPlugins("image", "onsessionload"); - } - // execute onsessionload callback, if necessary - if( typeof opts.onsessionload === "function" ){ - try{ JS9.xeqByName(opts.onsessionload, window, im); } - catch(e){ JS9.error("in onsessionload callback", e, false); } - } - }; - const loadit = (imobj) => { - let pname; - // sanity check - if( !imobj.file ){ - JS9.error("session does not contain a filename"); - } - // save copy of object so we can edit it - obj = $.extend(true, {}, imobj); - // some param info needs to be deleted - delete obj.params.display; - // unset crosshair (we don't save it or load it) - obj.params.crosshair = false; - // include an onload callback to load the layers - obj.params.onload = finish; - // get pathname of image file - pname = obj.file; - // add section info - if( obj.sect ){ - obj.params.xcen = obj.sect.xcen; - obj.params.ycen = obj.sect.ycen; - obj.params.xdim = obj.sect.xdim; - obj.params.ydim = obj.sect.ydim; - obj.params.zoom = obj.sect.zoom; - delete obj.sect; - } - // desktop only: are session file paths relative to the session path? - if( window.electron && - JS9.desktopOpts.sessionPath && - opts.sessionPath && - obj.file.charAt(0) !== "/" && - !obj.file.match(JS9.URLEXP) ){ - pname = JS9.fixPath(opts.sessionPath + obj.file, opts); - } - // save for finish - objs[pname] = obj; - // load the image - JS9.Load(pname, obj.params, {display: this.id}); - }; - const loadem = (jobj) => { - let i, key, cmap, xobj; - // restore (and remove) globals - if( jobj.globalOpts ){ - $.extend(true, JS9.globalOpts, jobj.globalOpts); - delete jobj.globalOpts; - } - // load colormaps - if( jobj.cmaps ){ - for(i=0; i= 0 ){ - xobj = {toplevel: true}; - } else { - xobj = {toplevel: false}; - } - JS9.AddColormap(cmap, xobj); - } - } - // load images - if( jobj.images ){ - left = jobj.images.length; - for(i=0; i { - loadem(jobj); - }, - error: (jqXHR, textStatus, errorThrown) => { - JS9.error(`could not load session: ${file}`, errorThrown); - } - }); - } - // allow chaining - return this; -}; - -// dummy routines to display/clear message, overwritten in info plugin -// eslint-disable-next-line no-unused-vars -JS9.Display.prototype.displayMessage = function(type, message, target){ - return; -}; -// eslint-disable-next-line no-unused-vars -JS9.Display.prototype.clearMessage = function(which){ - return; -}; - -// create a mosaic from a multi-extension FITS file or a number of images -JS9.Display.prototype.createMosaic = function(ims, opts){ - let i, im, bin, carr; - const im0 = this.image; - const line1 = "| fname|"; - const line2 = "| char|"; - // remove temp files - const cleanup = () => { - let i; - for(i=0; i { - let earr; - // check for Montage error - if( rstr.search(/\[struct stat="OK"/) < 0 ){ - // no longer waiting - JS9.waiting(false); - // first remove temp files - cleanup(); - // signal this we completed the reproject attempt - earr = rstr.match(/msg="(.*)"/); - if( earr && earr[1] ){ - JS9.error(`${earr[1]} (from ${prog})`); - } else { - JS9.error(rstr || `unknown ${prog} failure`); - } - } - }; - // display mosaic as a new image - const disp = (hdu, opts) => { - let topts, nim; - opts = opts || {}; - topts = $.extend(true, {}, opts); - // start the waiting! - if( opts.waiting !== false ){ - JS9.waiting(true, this); - } - // make sure we use the current display - topts.display = this.id; - // set up new and display new image - nim = new JS9.Image(hdu, topts); - // set status of both old and new image - im0.setStatus("createMosaic", "complete"); - nim.setStatus("createMosaic", "complete"); - // done waiting - JS9.waiting(false); - // everything else is done so call onmosaic func, if necessary - if( opts.onmosaic ){ - try{ JS9.xeqByName(opts.onmosaic, window, nim); } - catch(e){ JS9.error("in create mosaic callback", e, false); } - } - }; - // write comforting messages to the console while we wait and wait - const log = (...args) => { - let s; - if( opts.verbose || JS9.DEBUG > 1 ){ - s = sprintf(...args); - // eslint-disable-next-line no-console - JS9.log(s); - } - }; - // opts is optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse createMosaic opts: ${opts}`, e); } - } - // reduce can be taken from the global value - opts.reduce = opts.reduce || JS9.globalOpts.reduceMosaic; - // same for reduction dims - opts.dim = opts.dim || - Math.max(JS9.globalOpts.image.xdim, JS9.globalOpts.image.ydim); - // ims can be: array of ims or a single im or null (use displayed image) - // each im can itself be an im object or the image string id - if( !ims ){ - // use currently display image, if possible - if( this.image ){ - ims = [this.image]; - } else { - ims = []; - } - } else if( typeof ims === "string" ){ - if( ims === "current" ){ - // use the currently loaded image - if( this.image ){ - ims = [this.image]; - } else { - ims = []; - } - } else if( ims === "all" ){ - // use all images in this display - ims = []; - for(i=0; i { - let s, t, v, sw, naxis, rstr, inbuf, ext; - let vfile, ivfile, ovfile, bvfile, sect, topts; - let inlst, intbl, inhdr, inarr, binlst, bintbl; - let outlst, outtbl, outhdr, areafile, outfile; - const id = JS9.uniqueID(); - const imsw = "-C"; // skip naxis[3,4]: they write garbage into the table - const mktmp = (suffix) => { - return `mosaic_${id}_${suffix}`; - }; - // temps files get unique names - inlst = mktmp("in.lst"); - intbl = mktmp("in.tbl"); - inhdr = mktmp("in.hdr"); - binlst = mktmp("bin.lst"); - bintbl = mktmp("bin.tbl"); - outlst = mktmp("out.lst"); - outtbl = mktmp("out.tbl"); - outhdr = mktmp("out.hdr"); - // output file name comes from the first image name - outfile = ims[0].id - .replace(/\[.*\]/, "") - .replace(/\.fz$/i, "") - .replace(/\.gz$/i, "") - .replace(/\.fits$/i, "_mosaic.fits"); - // Montage temp areafile comes from the output file name - areafile = outfile.replace(/\.fits$/, "_area.fits"); - // init cleanup array to make sure temp files get deleted - carr = [inlst, intbl, inhdr, binlst, bintbl, - outlst, outtbl, outhdr, areafile]; - // generate input list from array of ims - s = `${line1}\n${line2}\n`; - for(i=0; i %s", vfile, ext, ovfile); - rstr = JS9.reproject(vfile, ovfile, outhdr, sw); - // check for errors - chkerr("mProjectPP", rstr); - } - } - // save output list in file - JS9.vfile(outlst, s); - // call the Mosaic/mImgtbl routine - rstr = JS9.imgtbl(outlst, ".", outtbl, ""); - // check for errors - chkerr("mImgtbl", rstr); - // make sure input table has FITS files - if( !JS9.vsize(outtbl) ){ - JS9.error("no FITS files were added to output table for mosaic"); - } - // make the mosaic - log("create mosaic: %s", outfile); - rstr = JS9.madd(outtbl, outhdr, outfile, ""); - // check for errors - chkerr("mAdd", rstr); - // cleanup temp files - cleanup(); - // construct options - topts = $.extend(true, {}, JS9.fits.options, opts); - // we want the full image - topts.image = {xdim: 0, ydim: 0}; - topts.file = outfile; - // process the newly retrieved data as FITS - JS9.fits.handleFITSFile(outfile, topts, disp); - }, JS9.SPINOUT); - // allow chaining - return this; -}; - -// swap images in the images stack for this display -// used by the sortable routine to switch images in a stack -// for moving an element of an array: -// https://stackoverflow.com/questions/5306680/move-an-array-element-from-one-array-position-to-another -JS9.Display.prototype.moveImageInStack = function(from, to){ - let i, j, nfrom, nto; - for(i=0, j=0; i 1 ){ - JS9.log("JS9 command: %s", this.name); - } -}; - -// get the display tied to this command (as well as the current image). -JS9.Command.prototype.getDisplayInfo = function(display){ - if( display && display.id ){ - this.display = display; - this.image = display.image; - } - // allow chaining - return this; -}; - -// return "get" or "set" to specify which command to run -JS9.Command.prototype.getWhich = function(args){ - let which; - if( this.get && !this.set ){ - which = "get"; - } else if( this.set && !this.get ){ - which = "set"; - } else if( this.which ){ - which = this.which(args); - } else if( args.length === 0 ){ - which = "get"; - } else { - which = "set"; - } - return which; -}; - -// --------------------------------------------------------------------- -// JS9 helper to manage connection to back-end services -// --------------------------------------------------------------------- - -JS9.Helper = function(){ - // reset protocol for file: - if( JS9.globalOpts.helperProtocol === "file:" ){ - JS9.globalOpts.helperProtocol = "http:"; - } - // reset helper timeout for local access - if( !document.domain || document.domain === "localhost" ){ - JS9.globalOpts.htimeout = JS9.globalOpts.lhtimeout; - } - // add suffix, if necessary - if( !JS9.globalOpts.helperProtocol.match(/\/\/$/) ){ - JS9.globalOpts.helperProtocol += "//"; - } - // assume the worst - this.connected = false; - this.helper = false; - // set up initial type of helper connection - if( JS9.allinone && !JS9.globalOpts.allinoneHelper ){ - this.type = "none"; - } else { - this.type = JS9.globalOpts.helperType || "sock.io"; - } - // no page id yet - this.pageid = null; - // make the connection - this.connect(); -}; - -// get back-end helper connection info -JS9.Helper.prototype.connectinfo = function(){ - let s; - // no connection configured - if( JS9.helper.connected === null ){ - return "notConfigured"; - } - // connection configured and established - if( JS9.helper.connected ){ - s = `connected ${JS9.helper.type} ${JS9.helper.url}`; - if( JS9.helper.pageid ){ - s += `

    ${JS9.helper.pageid}`; - } - return s; - } - // connection configured but not established - return `notConnected ${JS9.helper.type}`; -}; - -// connect to back-end helper -JS9.Helper.prototype.connect = function(type){ - let sockbase, sockfile; - const tries = JS9.globalOpts.ehretries; - const delay = JS9.globalOpts.ehtimeout; - const failedHelper = (textStatus, errorThrown) => { - this.connected = false; - this.helper = false; - this.ready = true; - $(document).trigger("JS9:helperReady", - {type: "socket.io", status: "error"}); - textStatus = textStatus || "timeout"; - if( !errorThrown || errorThrown === "timeout" ){ - errorThrown = "or connection refused"; - } - if( errorThrown === textStatus ){ - textStatus = ""; - } - if( errorThrown === "error" ){ - errorThrown = "is the helper running?"; - } - // throw error if needed - if( JS9.globalOpts.requireHelper ){ - JS9.error(`helper connect error: ${textStatus} (${errorThrown})`); - } else if( JS9.DEBUG ){ - JS9.log(`JS9 helper connect error: ${textStatus} (${errorThrown})`); - } - }; - const connectHelper = (url) => { - // connect to helper - $.ajax({ - url: url, - dataType: "script", - timeout: JS9.globalOpts.htimeout, - cache: true, - success: () => { - // if there is no io object, we didn't really succeed - // can happen, for example, in the Jupyter environment - if( typeof io === "undefined" ){ - failedHelper("socket io object is undefined", null); - return; - } - // connect to the helper - this.socket = io.connect(this.url, JS9.socketioOpts); - // on-event processing - this.socket.on("connect", () => { - let ii, d, p; - this.connected = true; - this.helper = true; - d = []; - for(ii=0; ii { - this.pageid = obj.pageid; - this.js9helper = obj.js9helper; - JS9.globalOpts.dataPathModify = obj.dataPathModify; - this.ready = true; - $(document).trigger("JS9:helperReady", - {type: "socket.io", status: "OK"}); - if( JS9.DEBUG ){ - JS9.log(`JS9 helper: connect: ${this.type}`); - } - }); - $(document).trigger("JS9:connected", - {type: "socket.io", status: "OK"}); - }); - this.socket.on("connect_error", () => { - this.connected = false; - this.helper = false; - if( JS9.DEBUG > 1 ){ - JS9.log("JS9 helper: connect error"); - } - }); - this.socket.on("connect_timeout", () => { - this.connected = false; - this.helper = false; - if( JS9.DEBUG > 1 ){ - JS9.log("JS9 helper: connect timeout"); - } - }); - this.socket.on("disconnect", (reason) => { - this.connected = false; - this.helper = false; - if( JS9.DEBUG > 1 ){ - JS9.log(`JS9 helper: disconnect: ${reason}`); - } - // https://github.com/socketio/socket.io-client/blob/master/docs/API.md#event-disconnect - if( reason === "io server disconnect" ){ - // the disconnection was initiated by the server, - // you need to reconnect manually - if( JS9.DEBUG > 1 ){ - JS9.log("JS9 helper: manual reconnect"); - } - this.socket.connect(); - } - // else the socket will automatically try to reconnect - }); - this.socket.on("reconnect", () => { - this.connected = true; - this.helper = true; - if( JS9.DEBUG > 1 ){ - JS9.log("JS9 helper: reconnect"); - } - }); - this.socket.on("msg", JS9.msgHandler); - }, - error: (jqXHR, textStatus, errorThrown) => { - failedHelper(textStatus, errorThrown); - } - }); - }; - // make an "alive" request of the helper (jsonp to avoid CORS rejection) - const waitForHelper = (eurl, hurl, tries) => { - $.ajax({ - url: eurl, - dataType: "jsonp", - success: () => { - connectHelper(hurl); - }, - error: () => { - if( --tries > 0 ){ - window.setTimeout(() => { - waitForHelper(eurl, hurl, tries); - }, delay); - } else { - failedHelper(); - } - } - }); - }; - // might be establishing a new type - if( type ){ - this.type = type; - } - // close off previous socket connection, if necessary - if( this.socket ){ - try{this.socket.disconnect();} - catch(e){JS9.log("warning: can't disconnect from socket");} - this.socket = null; - } - // base of helper url is either specified, same as current domain, or local - if( JS9.globalOpts.helperURL ){ - if( JS9.globalOpts.helperURL.search(/:\/\//) >=0 ){ - this.url = JS9.globalOpts.helperURL; - } else { - this.url = JS9.globalOpts.helperProtocol + JS9.globalOpts.helperURL; - } - } else if( document.domain ){ - if( location.origin ){ - this.url = location.origin; - } else { - this.url = JS9.globalOpts.helperProtocol + document.domain; - } - } else { - this.url = `${JS9.globalOpts.helperProtocol}localhost`; - } - // save base of url - this.baseurl = this.url; - // try to establish connection, based on connection type - switch(this.type){ - case "none": - this.connected = null; - this.ready = true; - // signal JS9 helper is ready - $(document).trigger("JS9:helperReady", {type: "none", status: "OK"}); - break; - case "get": - case "post": - // sanity check - if( !JS9.globalOpts.helperCGI ){ - JS9.error("cgi script name missing for helper"); - } - this.url += `/${JS9.globalOpts.helperCGI}`; - this.connected = true; - this.helper = true; - if( JS9.DEBUG ){ - JS9.log(`JS9 helper: connect: ${this.type}`); - } - this.ready = true; - $(document).trigger("JS9:helperReady", {type: "get", status: "OK"}); - break; - case "sock.io": - case "nodejs": - if( !JS9.globalOpts.helperPort ){ - JS9.error("port missing for helper"); - } - // ignore port on url, add our own - this.url = `${this.url.replace(/:[0-9][0-9]*$/, "")}:${JS9.globalOpts.helperPort}`; - // which version of socket.io? - sockbase = "socket.io"; - // use min version for production, as per migration docs - if( JS9.DEBUG <= 2 ){ - sockfile = "socket.io.min.js"; - } else { - sockfile = "socket.io.js"; - } - // full url of the socket.io.js file - this.sockurl = `${this.url}/${sockbase}/${sockfile}`; - // make sure helper is running and then connect - if( window.electron ){ - this.aliveurl = `${this.url}/alive`; - waitForHelper(this.aliveurl, this.sockurl, tries); - } else { - connectHelper(this.sockurl); - } - break; - default: - JS9.error(`unknown helper type: ${this.type}`); - break; - } -}; - -// send request to back-end helper -JS9.Helper.prototype.send = function(key, obj, cb){ - // sanity check - if( !this.connected ){ return null; } - // add cookie value - // add dataPath, if available (but always look in the helper directory) - if( obj && (typeof obj === "object") ){ - // wrap this in a try to catch CORS errors - try{ obj.cookie = document.cookie; } - catch(e){ delete obj.cookie; } - if( JS9.globalOpts.dataPath && !obj.dataPath ){ - obj.dataPath = `${JS9.globalOpts.dataPath}:.`; - } - } else { - obj = {dataPath: "."}; - } - // add path which gets us to the js9 root - if( JS9.TOROOT ){ - obj.dataPath += `:${JS9.TOROOT}`; - } - // tell server how to get to root (for datapath) - // send message, based on connection type - switch(this.type){ - case "get": - case "post": - obj.key = key; - if( JS9.helper.pageid ){ - obj.pageid = JS9.helper.pageid; - } - if( JS9.DEBUG ){ - JS9.log("JS9 cgi helper [%s, %s]: %s", - this.type, JSON.stringify(obj), this.url); - } - $.ajax({ - url: this.url, - type: this.type.toUpperCase(), - data: obj, - dataType: "text", - success: (data) => { - if( typeof data === "string" && - data.search(JS9.analOpts.epattern) >=0 ){ - JS9.log(data); - } - if( cb ){ - cb(data); - } - }, - error: (jqXHR, textStatus, errorThrown) => { - if( JS9.DEBUG ){ - JS9.log(`JS9 helper: ${this.type} failure: ${textStatus} ${errorThrown}`); - } - } - }); - break; - case "sock.io": - case "nodejs": - JS9.helper.socket.emit(key, obj, cb); - break; - } - // allow chaining - return this; -}; - -// --------------------------------------------------------------------- -// JS9 web worker support to off-load CPU intensive tasks -// --------------------------------------------------------------------- - -// create new web worker -JS9.WebWorker = function(url){ - const finishup = () => { - this.worker.onmessage = JS9.WebWorker.prototype.msgHandler.bind(this); - this.handlers = []; - }; - if( url.match(JS9.URLEXP) ){ - // avoid cross-origin problems if the webworker is being retrieved - // from somewhere other than the local host - // this leaks a small bit of memory (no revokeObjectURL call) - JS9.fetchURL(null, url, null, (blob) => { - this.worker = new Worker(URL.createObjectURL(blob)); - finishup(); - }); - } else { - // ordinary retrieval of a local file - this.worker = new Worker(url); - finishup(); - } -}; - -// handle (known) messages from web worker -JS9.WebWorker.prototype.msgHandler = function(msg){ - let i, handler; - const h = JS9.helper; - const obj = msg.data; - switch(obj.cmd){ - case "progress": - JS9.progress(obj.result.value, obj.result.max); - break; - case "initsocketio": - if( obj.result === "OK" ){ - this.sockinit = true; - for(i=0; i 1 ){ - JS9.log(`JS9 worker socketio: ${obj.cmd}`); - } - break; - case "disconnect": - delete JS9.worker.uploadActive; - JS9.progress(false); - obj.result = obj.result || "JS9 worker socket was disconnected"; - // need a slight delay here, not sure why - window.setTimeout(() => { - JS9.worker.send("initsocketio", [h.url, h.pageid], - () => { - if( obj.alert ){ - alert(obj.result); - } else if( JS9.DEBUG > 1 ){ - JS9.log(obj.result); - } - }); - }, JS9.WORKEROUT); - break; - case "error": - delete JS9.worker.uploadActive; - JS9.progress(false); - JS9.error(obj.result||"in web worker"); - break; - default: - break; - } -}; - -// send a message to a web worker -JS9.WebWorker.prototype.send = function(cmd, args, func, xfer){ - const id = cmd + JS9.uniqueID(); - const obj = {id, cmd, args}; - // push context - if( func ){ - args = args || []; - this.handlers.push({id, cmd, args, func}); - } - // send message, possibly with transferred data - if( xfer ){ - this.worker.postMessage(obj, xfer); - } else { - this.worker.postMessage(obj); - } -}; - -// initialize worker socketio connection, then call handler -JS9.WebWorker.prototype.socketio = function(handler){ - const h = JS9.helper; - JS9.worker.send("initsocketio", [h.url, h.pageid], (s) => { - if( s === "OK" ){ - if( handler ){ handler(); } - } else { - JS9.error(`can't init socket.io for JS9 worker: ${s}`); - } - }); -}; - -// terminate a web worker -JS9.WebWorker.prototype.terminate = function(){ - this.worker.terminate(); -}; - -// --------------------------------------------------------------------- -// Graphics support using fabric.js -// -// Fabric object defines graphical primitives -// --------------------------------------------------------------------- - -// quick way to separate fabric versions -fabric.major_version = parseFloat(fabric.version.split(".")[0]); -fabric.minor_version = parseFloat(fabric.version.split(".")[1]); -fabric.patch_version = parseFloat(fabric.version.split(".")[2]); - -// fabric sub-object to hold fabric routines -JS9.Fabric = {}; - -// extra fabric elements to save when switching between images - -JS9.Fabric.elements = ["cornerSize", "cornerColor", "cornerStyle", - "borderColor", - "transparentCorners", "selectionLineWidth", - "centeredScaling", "hasControls", "hasRotatingPoint", - "lockMovementX", "lockMovementY", "lockRotation", - "lockScalingX", "lockScalingY", "lockUniScaling", - "selectable", "hasBorders", "params", "pub"]; - -// global options for all shapes -JS9.Fabric.opts = { - // default fabric.js options - originX: "center", - originY: "center", - strokeWidth: 2, - selectionLineWidth: 2, - borderColor: "#00EEFF", - cornerColor: "#00EEFF", - cornerSize: fabric.isTouchSupported ? 10 : 6, - cornerStyle: "circle", - hasControls: true, - hasRotatingPoint: true, - hasBorders: true, - transparentCorners: false, - centeredScaling: true, - strokeUniform: true, - selectable: true, - // minimizes the jump when first changing the region size - padding: 0, - canvas: { - selection: true - }, - fill: "transparent", - objectCaching: false -}; - -// rescale the width of shapes in the shape layers -JS9.Fabric.rescaleStrokeWidth = function(scale, sw1){ - const tscale = ((this.scaleX + this.scaleY) / 2); - // fabric 3.6.3+ supports strokeUniform, including for groups - if( fabric.major_version >= 4 || - (fabric.major_version === 3 && - fabric.minor_version === 6 && - fabric.patch_version >= 3) ){ - return; - } - // fabric 2+ supports strokeUniform, but not for groups - // still, it fixes the different strokeWidth problem for rectangular boxes - if( fabric.major_version >= 2 && this.params && - this.params.shape !== "annulus" && this.params.shape !== "cross" ){ - return; - } - scale = scale || 1; - scale *= tscale; - if( !sw1 && this.params ){ - sw1 = this.params.sw1; - } - if( !sw1 ){ - return; - } - if( this.type === "group" ){ - this.forEachObject( (obj) => { - obj.rescaleBorder(scale, sw1); - }); - } else { - this.set("strokeWidth", sw1 / scale); - } -}; - -// ensure the circle scales the same in X and Y -JS9.Fabric.rescaleEvenly = function(){ - let lastscale; - if( !this.params || (this.scaleX === this.scaleY) ){ - return; - } - switch(this.params.shape){ - case "annulus": - case "circle": - lastscale = this.params.lastscale || 1; - if( this.scaleX !== lastscale ){ - this.scaleY = this.scaleX; - } else if( this.scaleY !== lastscale ){ - this.scaleX = this.scaleY; - } - this.params.lastscale = this.scaleX; - break; - } -}; - -// add to fabric object prototype -fabric.Object.prototype.rescaleBorder = JS9.Fabric.rescaleStrokeWidth; -fabric.Object.prototype.rescaleEvenly = JS9.Fabric.rescaleEvenly; - -// --------------------------------------------------------------------- -// Shape prototype additions to JS9 Display class -// --------------------------------------------------------------------- - -// create a new shape layer in the display -// call using display context -JS9.Fabric.newShapeLayer = function(layerName, layerOpts, divjq){ - let id, dlayer; - const display = this; - const shupdate = (obj, s) => { - let i, o, objs; - let im = dlayer.display.image; - let ao = dlayer.canvas.getActiveObject(); - let opts = {}; - // sanity check - if( !im ){ return; } - if( obj.params ){ - if( ao.type === "activeSelection" ){ - opts.group = ao; - } - im._updateShape(layerName, obj, opts, s); - } else if( (obj.type === "activeSelection") || - (obj.type === "group" && !obj.params) ){ - objs = obj.getObjects(); - for(i=0; i { - // sanity check - if( !display.image ){ return; } - // update multiselect dialog box for this image, if necessary - dlayer.display.image._updateMultiDialogs(setmode); - } - const seloff = (dlayer, obj) => { - // reset currently selected - dlayer.params.sel = null; - // reset currently selected layer - if( dlayer.display.image ){ - dlayer.display.image.layer = null; - } - // selection cleared processing - // remove anchors from previously selected polygon - if( obj ){ - switch(obj.type){ - case "polyline": - case "polygon": - JS9.Fabric.removePolygonAnchors(dlayer, obj); - // renderAll() throws an error, might be related to: - // http://fabricjs.com/v2-breaking-changes-2 - // dlayer.canvas.renderAll(); - break; - } - // region updates - shupdate(obj, "unselect"); - // update multi-select dialog - seldialog(-1); - } - }; - // eslint-disable-next-line no-unused-vars - const selmultioff = (dlayer, opts) => { - let i, obj, aobjects; - aobjects = dlayer.canvas.getActiveObjects(); - for(i=0; i { - // turn off previous selection, if necessary - if( dlayer.params.sel && obj.params && (dlayer.params.sel !== obj) ){ - seloff(dlayer, dlayer.params.sel); - } - // set currently selected layer - if( dlayer.display.image ){ - dlayer.display.image.layer = layerName; - } - // new selection processing - if( obj ){ - // add anchors to selected polygon - switch(obj.type){ - case "polyline": - case "polygon": - JS9.Fabric.addPolygonAnchors(dlayer, obj); - dlayer.canvas.renderAll(); - break; - } - // set currently selected shape - if( obj.polyparams ){ - dlayer.params.sel = obj.polyparams.polygon; - } else if( obj.params ){ - dlayer.params.sel = obj; - } - // region updates - shupdate(obj, "select"); - // update multi-select dialog - seldialog(1); - } - }; - // eslint-disable-next-line no-unused-vars - const selmultion = (dlayer, opts, activeObject) => { - let i, j, obj, parent, child, objs; - // turn off previous selection, if necessary - if( dlayer.params.sel && (dlayer.params.sel !== activeObject) ){ - seloff(dlayer, dlayer.params.sel); - } - // get current active object if necessary - activeObject = activeObject || dlayer.canvas.getActiveObject(); - // and the associated objects - objs = dlayer.canvas.getActiveObjects(); - for(i=0; i") - .addClass("JS9Container") - .css("z-index", 0) - .appendTo(divjq); - // create canvas element and append to container - dlayer.canvasjq = $("") - .addClass("JS9Layer") - .attr("id", id) - .attr("width", divjq.css("width")) - .attr("height", divjq.css("height")) - .appendTo(dlayer.divjq); - if( JS9.bugs.webkit_resize && dlayer.dtype === "main" ){ - dlayer.canvasjq - .attr("width", display.width) - .attr("height", display.height); - } - // new fabric canvas associated with this HTML canvas - dlayer.canvas = new fabric.Canvas(dlayer.canvasjq[0]); - // don't render on add or remove of objects (do it manually) - dlayer.canvas.renderOnAddRemove = false; - // preserve stacking (required in v1.6.6 to interact with polygon points) - dlayer.canvas.preserveObjectStacking = true; - // movable: short-hand for allowing objects to move (not resize) - if( dlayer.opts.movable ){ - dlayer.opts.lockMovementX = false; - dlayer.opts.lockMovementY = false; - dlayer.opts.selectable = true; - dlayer.opts.evented = true; - } else if( dlayer.opts.movable === false ){ - dlayer.opts.lockMovementX = true; - dlayer.opts.lockMovementY = true; - dlayer.opts.selectable = false; - dlayer.opts.evented = false; - } - // deprecated - if( (dlayer.opts.changeable === undefined) && - (dlayer.opts.fixinplace !== undefined) ){ - dlayer.opts.changeable = !dlayer.opts.fixinplace; - } - // locked: opposite alias of changeable - if( (dlayer.opts.changeable === undefined) && - (dlayer.opts.locked !== undefined) ){ - dlayer.opts.changeable = !dlayer.opts.locked; - } - // changeable: short-hand for allowing objects to move and resize - if( dlayer.opts.changeable ){ - dlayer.opts.hasControls = true; - dlayer.opts.hasRotatingPoint = true; - dlayer.opts.hasBorders = true; - dlayer.opts.lockMovementX = false; - dlayer.opts.lockMovementY = false; - dlayer.opts.lockRotation = false; - dlayer.opts.lockScalingX = false; - dlayer.opts.lockScalingY = false; - dlayer.opts.lockUniScaling = false; - dlayer.opts.selectable = true; - dlayer.opts.evented = true; - dlayer.opts.usekeyboard = true; - } else if( dlayer.opts.changeable === false ){ - dlayer.opts.hasControls = false; - dlayer.opts.hasRotatingPoint = false; - dlayer.opts.hasBorders = false; - dlayer.opts.lockMovementX = true; - dlayer.opts.lockMovementY = true; - dlayer.opts.lockRotation = true; - dlayer.opts.lockScalingX = true; - dlayer.opts.lockScalingY = true; - dlayer.opts.lockUniScaling = true; - dlayer.opts.selectable = false; - dlayer.opts.evented = false; - dlayer.opts.usekeyboard = false; - } - // short-hand for allowing group and individual selections - if( dlayer.opts.selectable ){ - dlayer.opts.canvas.selection = true; - } - // are mouse callbacks defined in the opts object? - if( dlayer.opts.onmousedown || dlayer.opts.onmouseup || - dlayer.opts.onmousemove || dlayer.opts.tooltip || - dlayer.opts.onmouseover || dlayer.opts.onmouseout ){ - dlayer.opts.evented = true; - if( dlayer.opts.onmousedown ){ - dlayer.canvas.on("mouse:down", (opts) => { - if( dlayer.display.image && opts.target ){ - let target = opts.target; - // nb: target might be a polygon anchor => no params - let params = target.params; - // set click state but ignore unchangeable regions - if( !params || (params && params.changeable !== false) ){ - // on main window, set region click - if( dlayer.dtype === "main" ){ - dlayer.display.image.clickInRegion = true; - dlayer.display.image.clickInLayer = layerName; - } - dlayer.opts.onmousedown.call(dlayer.canvas, - dlayer.display.image, - target.pub, - opts.e, target); - } - } else { - // only allow fabric selection if we have special key down - dlayer.canvas._selection = dlayer.canvas.selection; - if( dlayer.canvas.selection ){ - dlayer.canvas.selection = JS9.specialKey(opts.e); - } - } - }); - } else { - dlayer.canvas.on("mouse:down", (opts) => { - // only allow fabric selection if we have special key down - dlayer.canvas._selection = dlayer.canvas.selection; - if( dlayer.canvas.selection ){ - dlayer.canvas.selection = JS9.specialKey(opts.e); - } - }); - } - if( dlayer.opts.onmouseup ){ - dlayer.canvas.on("mouse:up", (opts) => { - if( dlayer.display.image && opts.target ){ - dlayer.opts.onmouseup.call(dlayer.canvas, - dlayer.display.image, - opts.target.pub, - opts.e, opts.target); - } - // restore original selection state - dlayer.canvas.selection = dlayer.canvas._selection || - dlayer.canvas.selection; - }); - } else { - dlayer.canvas.on("mouse:up", () => { - // restore original selection state - dlayer.canvas.selection = dlayer.canvas._selection || - dlayer.canvas.selection; - }); - } - if( dlayer.opts.onmousemove ){ - dlayer.canvas.on("mouse:move", (opts) => { - if( dlayer.display.image && opts.target ){ - dlayer.opts.onmousemove.call(dlayer.canvas, - dlayer.display.image, - opts.target.pub, - opts.e, opts.target); - } - }); - } - if( dlayer.opts.onmouseover ){ - dlayer.canvas.on("mouse:over", (opts) => { - if( dlayer.display.image && opts.target ){ - dlayer.opts.onmouseover.call(dlayer.canvas, - dlayer.display.image, - opts.target.pub, - opts.e, opts.target); - } - }); - } - if( dlayer.opts.onmouseout ){ - dlayer.canvas.on("mouse:out", (opts) => { - if( dlayer.display.image && opts.target ){ - dlayer.opts.onmouseout.call(dlayer.canvas, - dlayer.display.image, - opts.target.pub, - opts.e, opts.target); - } - }); - } - if( dlayer.opts.onmousedblclick ){ - dlayer.canvas.on("mouse:dblclick", (opts) => { - if( dlayer.display.image && opts.target ){ - dlayer.opts.onmousedblclick.call(dlayer.canvas, - dlayer.display.image, - opts.target.pub, - opts.e, opts.target); - } - }); - } - if( dlayer.opts.tooltip ){ - dlayer.canvas.on("mouse:over", (opts) => { - if( dlayer.display.image && opts.target ){ - JS9.tooltip(opts.target.left+opts.target.width+2, - opts.target.top+opts.target.height+2, - dlayer.opts.tooltip, - dlayer.display.image, - opts.target.pub, - opts.e, opts.target); - } - }); - dlayer.canvas.on("mouse:out", (opts) => { - if( dlayer.display.image && opts.target ){ - JS9.tooltip(opts.target.left, opts.target.top, - null, - dlayer.display.image, - opts.target.pub, - opts.e, opts.target); - } - }); - } - } else { - dlayer.canvas.on("mouse:down", (opts) => { - // only allow fabric selection if we have special key down - dlayer.canvas._selection = dlayer.canvas.selection; - if( dlayer.canvas.selection ){ - dlayer.canvas.selection = JS9.specialKey(opts.e); - } - }); - dlayer.canvas.on("mouse:up", () => { - // restore original selection state - dlayer.canvas.selection = dlayer.canvas._selection || - dlayer.canvas.selection; - }); - } - // object modified - dlayer.canvas.on("object:modified", (opts) => { - let o, i, olen, myWidth, myHeight; - const objs = []; - // sanity check - if( !opts.target ){ return; } - o = opts.target; - // update deltas to connected parents - JS9.Fabric.updateChildren(dlayer, o, "deltas"); - // might have to sort overlapping shapes by size - if( dlayer.opts.sortOverlapping ){ - o.setCoords(); - // find objects which intersect with this one - dlayer.canvas.forEachObject( (obj) => { - if( obj === o ){ - return; - } - if( o.intersectsWithObject(obj) ){ - myWidth = obj.getScaledWidth(); - myHeight = obj.getScaledHeight(); - objs.push({obj: obj, siz: myWidth * myHeight}); - } - }); - // any intersecting shapes? - if( !objs.length ){ - return; - } - myWidth = o.getScaledWidth(); - myHeight = o.getScaledHeight(); - // add current shape to array - objs.push({obj: o, siz: myWidth * myHeight}); - // sort in order of increasing size - objs.sort((a, b) => { - // using <= instead of < preserves order for = - if( a.siz <= b.siz ){ - return -1; - } else { - return 1; - } - }); - // re-order so smaller objects are in front - olen = objs.length; - for(i=0; i { - let o; - // sanity check - if( !opts.target ){ return; } - o = opts.target; - o.rescaleEvenly(); - o.rescaleBorder(); - JS9.Fabric.updateChildren(dlayer, o, "scaling"); - if( (o.type === "activeSelection") || (o.type === "group") ){ - shupdate(o, "scaling"); - } - }); - dlayer.canvas.on("object:moving", (opts) => { - let o; - // sanity check - if( !opts.target ){ return; } - o = opts.target; - JS9.Fabric.updateChildren(dlayer, o, "moving"); - if( (o.type === "activeSelection") || (o.type === "group") ){ - shupdate(o, "moving"); - } - }); - dlayer.canvas.on("object:rotating", (opts) => { - let o; - // sanity check - if( !opts.target ){ return; } - o = opts.target; - JS9.Fabric.updateChildren(dlayer, o, "rotating"); - if( (o.type === "activeSelection") || (o.type === "group") ){ - shupdate(o, "rotating"); - } - }); - // selection created: add anchors to polygon - dlayer.canvas.on("selection:created", (opts) => { - let obj; - if( JS9.globalOpts.skipSelectionProcessing ){ return; } - if( opts.target ){ - // fabric v4 - obj = opts.target; - if( obj.type === "activeSelection" || - (obj.type === "group" && !obj.params) ){ - selmultion(dlayer, opts, obj); - } else { - selon(dlayer, obj); - } - } else if( opts.selected && opts.selected.length ){ - // fabric v5 - if( opts.selected.length === 1 ){ - obj = opts.selected[0]; - selon(dlayer, obj); - } else { - selmultion(dlayer, opts); - } - } - }); - // selection updated (adding a region to the current selection): - // add anchors to polygon - dlayer.canvas.on("selection:updated", (opts) => { - let obj; - if( JS9.globalOpts.skipSelectionProcessing ){ return; } - if( opts.target ){ - // fabric v4 - obj = opts.target; - if( obj.type === "activeSelection" || - (obj.type === "group" && !obj.params) ){ - selmultion(dlayer, opts, obj); - } else { - selon(dlayer, obj); - } - } else if( opts.selected && opts.selected.length ){ - // fabric v5 - if( opts.selected.length === 1 ){ - obj = opts.selected[0]; - selon(dlayer, obj); - } else { - selmultion(dlayer, opts); - } - } - }); - // selection cleared - // v5: why does this work differently from the selection: events above??? - // (i.e. still utilizes obj.target instead of obj.selected) - dlayer.canvas.on("before:selection:cleared", (opts) => { - let obj; - if( JS9.globalOpts.skipSelectionProcessing ){ return; } - // sanity check - if( !opts.target ){ return; } - obj = opts.target; - if( obj.type === "activeSelection" || - (obj.type === "group" && !obj.params) ){ - selmultioff(dlayer, opts); - } else { - seloff(dlayer, obj); - } - }); - // if canvas moves (e.g. light window), calcOffset must be called ... - // there is no good cross-browser way to track an element changing, - // (advice is to set a timer!) so we just check when the mouse enters the - // div, because this is when the user will interact with some shape - // only do this if we are in a light window - if( dlayer.divjq.closest(JS9.lightOpts[JS9.LIGHTWIN].drag).length ){ - if( fabric.isTouchSupported ){ - dlayer.divjq.on("touchstart", () => {dlayer.canvas.calcOffset();}); - } else { - dlayer.divjq.on("mouseenter", () => {dlayer.canvas.calcOffset();}); - } - } - return dlayer; -}; - -// --------------------------------------------------------------------------- -// Shape prototype additions to JS9 Image class -// --------------------------------------------------------------------------- - -// showShapeLayer: if mode is true, layer is displayed, otherwise hidden -// also an internal call which uses {local: true} to maybe hide/show layers -// call using image context -JS9.Fabric.showShapeLayer = function(layerName, mode, opts){ - let jobj, xkey, layer, dlayer, canvas, objects, olen, obj; - let left = 0; - layer = this.getShapeLayer(layerName); - // sanity check - if( !layer ){ return; } - // opts is optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse showShapeLayer opts: ${opts}`, e); } - } - canvas = layer.canvas; - dlayer = this.display.layers[layerName]; - // no args: return show mode - if( JS9.isNull(mode) ){ - return layer.show; - } - if( mode === true || mode === "true" ){ - // restore and show layer - if( !opts.local ){ - layer.show = true; - // for non-internal show/hide, exit if we are not displaying image - if( this !== this.display.image ){ - return; - } - } - // restore selection property - if( layer.show ){ - canvas.selection = layer.opts.canvas.selection; - } - if( layer.json && layer.show ){ - canvas.loadFromJSON(layer.json, () => { - let key, tdlayer, obj; - // update objects for parents and children - JS9.Fabric.updateChildren(layer.dlayer, null, "objects"); - // translate these shapes if we resized while hidden - if( this.resize ){ - canvas.getObjects().forEach( (o) => { - o.left += this.resize.left; - o.top += this.resize.top; - o.setCoords(); - }); - canvas.calcOffset(); - } - layer.zindex = Math.abs(layer.zindex); - dlayer.divjq.css("z-index", layer.zindex); - // unselect selected objects in lower-zindex groups - for( key of Object.keys(this.layers) ){ - if( (layerName !== key) && this.layers[key].show ){ - tdlayer = this.display.layers[key]; - if( tdlayer.divjq.css("z-index") < layer.zindex ){ - obj = tdlayer.canvas.getActiveObject(); - if( obj ){ - JS9.Fabric.removePolygonAnchors(tdlayer, - obj); - if( tdlayer.canvas.getActiveObject() ){ - tdlayer.canvas.discardActiveObject(); - } - } - } - } - } - this.restoreSelection(layerName); - }); - } - // remove resize object if we have no more hidden layers - for( xkey of Object.keys(this.layers) ){ - if( this.layers[xkey].json ){ - left++; - } - } - if( !left ){ - this.resize = null; - } - // plugin callbacks - this.xeqPlugins("shape", "onshapelayershow", layerName); - } else { - // for non-internal show/hide, exit if we are not displaying image - if( !opts.local ){ - if( this !== this.display.image ){ - layer.show = false; - return; - } - } - // save and hide layer - if( layer.show ){ - // can't use forEachObject, which loops in ascending order, - // because removing anchors changes the array destructively - objects = canvas.getObjects(); - olen = objects.length; - while( olen-- ){ - obj = objects[olen]; - if( obj.params ){ - if( obj.params.winid ){ - obj.params.winid.close(); - obj.params.winid = null; - } - if( obj.params.anchors ){ - JS9.Fabric.removePolygonAnchors(layer.dlayer, obj); - } - } - } - jobj = canvas.toJSON(layer.dlayer.el); - layer.json = JSON.stringify(jobj); - this.saveSelection(layerName); - canvas.selection = false; - // push towards the bottom of the pile - if( dlayer ){ - layer.zindex = -Math.abs(layer.zindex); - dlayer.divjq.css("z-index", layer.zindex); - } - canvas.clear(); - } - if( !opts.local ){ - layer.show = false; - } - // plugin callbacks - this.xeqPlugins("shape", "onshapelayerhide", layerName); - } - return this; -}; - -// display all layers for the current image (save previous) -// call using image context -JS9.Fabric.displayShapeLayers = function(){ - let key; - // if prev and cur are the same, just exit - if( this === this.display.image ){ - return; - } - // this.display.image still points to the previously loaded image - // save old layers - if( this.display.image && this.display.image.layers ){ - for( key of Object.keys(this.display.image.layers) ){ - this.display.image.showShapeLayer(key, false, {local: true}); - } - } - // "this" points to the current image: display new layers - if( this.layers ){ - for( key of Object.keys(this.layers) ){ - this.showShapeLayer(key, true, {local: true}); - } - } -}; - -// toggle display of active layers for the current image (save previous) -// call using image context -JS9.Fabric.toggleShapeLayers = function(){ - let key, layer; - if( this.toggleLayers ){ - // toggleLayers => we are currently hidden, so display them - for( key of Object.keys(this.layers) ){ - layer = this.layers[key]; - if( layer && this.toggleLayers[key] ){ - this.showShapeLayer(key, true); - } - } - delete this.toggleLayers; - } else { - // no toggleLayers => we are currently displayed, so hide them - this.toggleLayers = {}; - for( key of Object.keys(this.layers) ){ - if( key === "crosshair" ){ - continue; - } - layer = this.layers[key]; - if( layer && layer.show && layer.dlayer.dtype === "main" ){ - this.toggleLayers[key] = true; - this.showShapeLayer(key, false); - } - } - } -}; - -// retrieve (and initialize, if necessary) a shape layer -// call using image context -// eslint-disable-next-line no-unused-vars -JS9.Fabric.getShapeLayer = function(layerName, opts){ - let dlayer, layer; - // sanity check - if( !layerName ){ return null; } - layer = this.layers[layerName]; - // create new layer, if necessary - if( !layer ){ - // check for display layer, which is required - dlayer = this.display.layers[layerName]; - if( !dlayer ){ - return null; - } - // make a new image display layer - this.layers[layerName] = {}; - // create new layer for this image - layer = this.layers[layerName]; - // assume we show this layer - layer.show = true; - // no shapes yet - layer.nshape = 0; - // backlink to display layer - layer.dlayer = dlayer; - // convenient link back to opts - layer.opts = layer.dlayer.opts; - // convenient link back to canvas - layer.canvas = layer.dlayer.canvas; - // recalculate offset -- why is this necessary?? - layer.canvas.calcOffset(); - } - // return layer - return layer; -}; - -// use zindex to make specified shape layer the active layer -// call using image context -JS9.Fabric.activeShapeLayer = function(s){ - let i, j, a, key, layer, tlayer, ozindex, tzindex, rtn; - if( !s ){ - // no args: return layer with highest zindex - for( key of Object.keys(this.layers) ){ - tlayer = this.layers[key]; - if( tlayer.dlayer.dtype === "main" ){ - if( (tzindex === undefined) || (tlayer.zindex > tzindex) ){ - tzindex = tlayer.zindex; - a = key; - } - } - } - // return highest zindex layer - rtn = a; - } else if( $.isArray(s) ){ - // non-public internal call: array of layers was specified - // set zindex for layers in decreasing order - for(i=0, j=this.zlayer-1; i { - let tkey, ctags, color; - tagcolors = tagcolors || {}; - // look through the color keys for exact match - for( tkey of Object.keys(tagcolors) ){ - ctags = tkey.split("_"); - // see if all elements match - if( $(tags).not(ctags).length === 0 && - $(ctags).not(tags).length === 0 ){ - color = tagcolors[tkey]; - break; - } - } - // look through color keys for subset match - if( !color ){ - for( tkey of Object.keys(tagcolors) ){ - ctags = tkey.split("_"); - if( $(tags).not(ctags).length === 0 ){ - color = tagcolors[tkey]; - break; - } - } - } - // look through color keys for superset match - if( !color ){ - for( tkey of Object.keys(tagcolors) ){ - ctags = tkey.split("_"); - if( $(ctags).not(tags).length === 0 ){ - color = tagcolors[tkey]; - break; - } - } - } - // final attempt: use existing object's color or a default color - color = color || (obj && obj.get("stroke")) || - tagcolors.defcolor || JS9.globalOpts.defcolor || "#000000"; - return color; - }; - // opts is optional - opts = opts || {}; - // remove means nothing else matters - if( opts.remove ){ - return {remove: opts.remove}; - } - // remove dangerous options (e.g., passed in JS9.GetRegions() object) - parent = opts.parent || (obj && obj.params && obj.params.parent); - delete opts.parent; - if( !opts.restoreid ){ - delete opts.id; - } - delete opts.restoreid; - // initialize tags - nparams.tags = []; - // pre-processing special keys - if( opts.tags ){ - if( typeof opts.tags === "string" ){ - tags = opts.tags.toLowerCase().split(","); - // modes: source, background, include, exclude, etc - for(i=0; i= 3 ){ - opts.wcssys = arr[2]; - } - } - // ra and dec are in degrees, using the current wcs - if( this.validWCS() && JS9.notNull(opts.ra) && JS9.notNull(opts.dec) ){ - // make sure we have the right wcssys - if( opts.wcssys ){ - // from passed-in opts - owcssys = this.getWCSSys(); - txeq = JS9.globalOpts.xeqPlugins; - JS9.globalOpts.xeqPlugins = false; - this.setWCSSys(opts.wcssys, false); - } else if( opts._wcssys ){ - // local override from parseRegions - owcssys = this.getWCSSys(); - txeq = JS9.globalOpts.xeqPlugins; - JS9.globalOpts.xeqPlugins = false; - this.setWCSSys(opts._wcssys, false); - // no longer needed or wanted - delete opts._wcssys; - } - // convert wcs supplied as strings - if( typeof opts.ra === "string" ){ - opts.ra = JS9.saostrtod(opts.ra); - if( JS9.isHMS(this.params.wcssys) ){ - opts.ra *= 15.0; - } - } - if( typeof opts.dec === "string" ){ - opts.dec = JS9.saostrtod(opts.dec); - } - // convert to image coords - arr = JS9.wcs2pix(this.raw.wcs, opts.ra, opts.dec).trim().split(/ +/); - // restore original wcssys - if( owcssys ){ - this.setWCSSys(owcssys, false); - JS9.globalOpts.xeqPlugins = txeq; - } - // convert to display coords - pos = this.imageToDisplayPos({x: parseFloat(arr[0]), - y: parseFloat(arr[1])}); - nopts.left = pos.x; - nopts.top = pos.y; - } - // look for primitives - if( (opts.left !== undefined) ){ - nopts.left = opts.left; - } - if( (opts.top !== undefined) ){ - nopts.top = opts.top; - } - // last gasp to get left and top (unless explicitly told not to) - if( nopts.left === undefined && opts.noLeftTop !== true ){ - if( obj && (obj.left !== undefined) ){ - nopts.left = obj.left; - } else { - nopts.left = this.display.canvasjq.attr("width") / 2 - 1; - } - } - if( nopts.top === undefined && opts.noLeftTop !== true ){ - if( obj && (obj.top !== undefined) ){ - nopts.top = obj.top; - } else { - // why is this fudge needed? - nopts.top = this.display.canvasjq.attr("height") / 2 - 1 + YFUDGE; - } - } - // relative movement requires opts left/top or an existing object - if( opts.deltax ){ - nopts.left += opts.deltax; - } - if( opts.deltay ){ - nopts.top -= opts.deltay; - } - // set scaling based on zoom factor - if( this.display.layers[layerName].dtype === "main" && - !opts.preservedcoords ){ - zoom = this.rgb.sect.zoom; - } else { - zoom = 1; - } - // look for reset directives (empty strings) - if( opts.strokeDashes === "" || opts.strokeDashArray === "" ){ - opts.strokeDashArray = []; - } - if( opts.strokeWidth === "" ){ - opts.strokeWidth = JS9.Fabric.opts.strokeWidth; - } - // shape-specific processing - switch(opts.shape){ - case "annulus": - nparams.radii = []; - if( opts.radii !== undefined ){ - if( typeof opts.radii === "string" ){ - nparams.radii = opts.radii.replace(/ /g, "").split(","); - for(i=0, j=0; i { - switch(item){ - case "top": - case "left": - case "width": - case "height": - case "radii": - case "radius": - case "rx": - case "ry": - case "angle": - case "panzoom": - case "iradius": - case "oradius": - case "nannuli": - case "aradius1": - case "aradius2": - case "configURL": - case "sortOverlapping": - case "tagcolors": - case "pts": - case "ptshape": - case "ptsize": - case "linepoints": - case "polypoints": - case "responseType": - case "display": - case "tags": - case "r1": - case "r2": - case "x": - case "y": - case "dx": - case "dy": - case "px": - case "py": - case "ra": - case "dec": - case "shape": - case "parent": - case "rtn": - case "_wcssys": - case "file": - case "savefile": - case "savewhich": - case "saveformat": - case "saveselection": - case "savewcs": - case "sortids": - case "send": - case "listonchange": - case "multitext": - return false; - case "text": - if( opts.shape === "text" ){ - return false; - } - return true; - case "editing": - return opts.editing; - default: - return true; - } - }); -}; - -// if shape is not text but text is specified in the opts, -// make a text shape as a child of this shape -// call using image context -JS9.Fabric._handleChildText = function(layerName, s, opts){ - let i, t, dpos, npos, topts, yoff, child; - const textht = 12; - // region layer only, for now - if( layerName !== "regions" ){ - return; - } - // opts are optional - opts = opts || {}; - if( (s.params.shape !== "text") && opts.text && - (!s.params.children || !s.params.children.length) ){ - yoff = (s.height * s.scaleX / 2) - textht; - // default position for text (might be overridden by textOpts) - if( Math.abs(s.angle) < 0.000001 ){ - dpos = {x: s.left, y: s.top - yoff}; - } else { - dpos = JS9.rotatePoint({x: s.left, y: s.top - yoff}, - s.angle, {x: s.left, y: s.top}); - } - npos = this.displayToImagePos(dpos); - topts = {x: npos.x, y: npos.y, angle: -s.angle, - color: s.stroke, text: opts.text, tags: s.params.tags, - parent: "TBD", rtn: "object"}; - if( opts.textOpts ){ - topts = $.extend(true, {}, topts, opts.textOpts); - } - // create the child shape - t = this.addShapes(layerName, "text", topts); - // parent object keeps track of relationship between parent and child - t.params.parent = {id: s.params.id, - obj: s, - dleft: s.left - t.left, - dtop: s.top - t.top, - lastscalex: s.scaleX, - lastscaley: s.scaleY, - lastangle: s.angle, - textheight: textht}; - // updateShape was skipped in addShapes because parent was TBD - // we can now updateShape with parent info ... - this._updateShape(layerName, t, null, "child", t.params); - // since strokeWidth changes with zoom, we need to save the opts - // and restore it on export - if( opts.strokeWidth !== undefined ){ - t.params.parent.strokeWidth = opts.strokeWidth; - } - // text might be moved off default position already - if( (npos.x !== topts.x) || (npos.y !== topts.y) ){ - t.params.parent.moved = true; - } - // flag if text RA and Dec were passed in textOpts - if( opts.textOpts && - opts.textOpts.ra !== undefined && - opts.textOpts.dec !== undefined ){ - t.params.hasTextOpts = true; - } - // parent has another child - s.params.children.push({id: t.params.id, obj: t}); - // update the parent - this._updateShape(layerName, s, null, "addchild", s.params); - } else if( s.params.children && s.params.children.length > 0 && - (JS9.notNull(opts.text) || - JS9.notNull(opts.textOpts) || - JS9.notNull(opts.color)) ){ - // process parameters passed to existing text children - for(i=0; i 0 ){ - this.changeShapes(layerName, child.params.id, topts); - } - } - } -}; - -// add shapes to a layer -// call using image context -JS9.Fabric.addShapes = function(layerName, shape, myopts){ - let i, sobj, sarr, carr, ns, s, bopts, opts, layer, canvas, dlayer; - let zoom, ttop, tleft, tangle, w2, h2, key; - let params = {}; - let rarr = [], parr = []; - const objs = []; - const grp = {}; - // is this core service disabled? - if( $.inArray("regions", this.params.disable) >= 0 && - layerName === "regions" ){ - return; - } - // optional myopts can be an object or a string - myopts = myopts || {}; - // opts can be an object or json - if( typeof myopts === "string" ){ - try{ myopts = JSON.parse(myopts); } - catch(e){ JS9.error(`can't parse shape opts: ${myopts}`, e); } - } - // delay adding the region, if this image is not the one being displayed - if( this.display.image !== this ){ - this.delayedShapes = this.delayedShapes || []; - this.delayedShapes.push({layer: layerName, shape: shape, - mode: "add", opts: myopts}); - return; - } - // remove old regions, if necessary (ie we are reloading the file) - if( myopts.file && JS9.globalOpts.reloadRefreshReg ){ - try{ this.removeShapes("regions", myopts.file); } - catch(e){ /* empty */ } - } - layer = this.getShapeLayer(layerName); - // sanity check - if( !layer || !layer.show ){ return; } - canvas = layer.canvas; - // figure out the first arg - if( typeof shape === "string" ){ - // look for a region string - s = this.parseRegions(shape, myopts); - if( typeof s === "string" ){ - // nope, normal shape string - sarr = [{shape: s}]; - } else { - // parsed array of shape objects from regions string - sarr = s; - } - } else if( $.isArray(shape) ){ - sarr = shape; - } else if( typeof shape === "object" ){ - sarr = [shape]; - } else { - return; - } - // once a shape has been added, we can set the zindex to process events - if( JS9.isNull(layer.zindex) || Number.isNaN(layer.zindex) ){ - if( this.display.layers[layerName].dtype === "main" ){ - switch(layerName){ - case JS9.Crosshair.LAYERNAME: - case JS9.Grid.LAYERNAME: - // these should never cover any other interactive layer - layer.zindex = 1; - break; - default: - // otherwise this layer goes to the top - layer.zindex = this.zlayer++; - break; - } - } else { - // layer is not in main display - layer.zindex = JS9.SHAPEZINDEX; - } - dlayer = this.display.layers[layerName]; - dlayer.divjq.css("z-index", layer.zindex); - // we can now call the shape layer create plugin callbacks - this.xeqPlugins("shape", "onshapelayercreate", layerName); - } - // baseline opts - bopts = $.extend(true, {}, JS9.Fabric.opts, layer.opts, myopts); - // process each shape object - for(ns=0; ns= 0 ){ - opts.centeredScaling = false; - } - // create the shape - switch(sobj.shape){ - case "annulus": - // save shape - params.shape = "annulus"; - // save group position - ttop = opts.top; - tleft = opts.left; - // individual radii in the group are at 0,0 - opts.top = 0; - opts.left = 0; - rarr = []; - if( params.radii ){ - for(i=0; i { - let groupid; - // ordinary shapes - if( o.params ){ - // but not child shapes - if( !o.params.parent ){ - JS9.tmp.regSelect.all.push(o.params.id); - } - } else if( o.type === "group" ){ - // groups - groupid = this.lookupGroup(o); - if( groupid ){ - JS9.tmp.regSelect.all.push(groupid); - } - } - }); - try{ - regSelect.parse(selection); - } - catch(e){ - JS9.error(`parsing selection filter: ${selection}`, e); - } - if( opts.saveselection && selection ){ - switch(selection.trim()){ - case "all": - case "saved": - case "selected": - break; - default: - this.layers[layerName].selection = selection; - break; - } - } - selection = JS9.tmp.regSelect.ids; - delete JS9.tmp.regSelect; - return selection; -}; - -// select one of more shapes by id or tag and execute a callback -// call using image context -JS9.Fabric._selectShapes = function(layerName, selection, opts, cb){ - let i, j, objects, olen, aobjects, alen, groups; - let id, ginfo, canvas, ocolor, tag, obj; - const used = []; - const xcb = (obj, ginfo) => { - if( $.inArray(obj, used) < 0 ){ - cb.call(this, obj, ginfo); - used.push(obj); - } - } - const getshapes = (objects) => { - let got, obj, olen; - // sanity check - if( !objects ){ return []; } - // get objects, including objects inside groups, which themselves - // can be within groups ... (hence the do/while loop) - olen = objects.length; - do{ - got = 0; - while( olen-- ){ - obj = objects[olen]; - // replace group with objects inside the group - if( obj.type === "group" && !obj.params ){ - objects.splice(olen, 1, ...obj.getObjects()); - got++; - } - } - olen = objects.length; - } while( got ); - return objects; - }; - const getgroups = (canvas, objects) => { - let i, j, obj, grp, olen, mlen, ao; - let mygroups = []; - let groups = []; - olen = objects.length; - // look for all possible groups - for(i=0; i { - let i, tobj; - for(i=0; i { - // but no text children - if( o.params && !o.params.parent ){ - xcb(o, ginfo); - } - }); - } else { - // dangerous case: pass the group object - // you'd better know what you are doing! - xcb(obj, ginfo); - } - } else { - // for some types of selections, we do need to - // look inside the group - obj.forEachObject((o) => { - if( o.params && id === o.params.file ){ - xcb(o, ginfo); - } - }); - } - // that's the entirety of processing we do on a group - continue; - } - // make sure its a valid region - if( !obj.params ){ continue; } - // convenience variables - ocolor = obj.stroke.toLowerCase(); - // no text children unless explicity specified - if( obj.params.parent && id !== "child" && id !== "All" ){ - continue; - } - // children should always have a parent - if( id === "child" && !obj.params.parent ){ - continue; - } - // set group info - ginfo.group = groups[olen]; - // try to match this id in various ways - if( id.toLowerCase() === "all" ){ - // all - xcb(obj, ginfo); - } else if( (id.toLowerCase() === ocolor) || - (JS9.colorToHex(id).toLowerCase() === ocolor) ){ - // color - xcb(obj, ginfo); - } else if( id === obj.params.shape ){ - // shape - xcb(obj, ginfo); - } else if( id === obj.params.file ){ - // origin filename - xcb(obj, ginfo); - } else if( typeof obj.params.data === "object" && - id === obj.params.data.syncid ){ - // sync id (see sync plugin) - xcb(obj, ginfo); - } else if( id === "child" && obj.params.parent ){ - // all - xcb(obj, ginfo); - } else if( id === "dcoords" && obj.params.preservedcoords ){ - // all - xcb(obj, ginfo); - } else if( id === "nodcoords" && !obj.params.preservedcoords ){ - // all - xcb(obj, ginfo); - } else if( id === "parent" && - obj.params.children && - obj.params.children.length ){ - // all - xcb(obj, ginfo); - } else if( $.inArray(id, JS9.wcssyss) >= 0 && - obj.params.wcsconfig && - obj.params.wcsconfig.wcssys === id ){ - // original wcs - xcb(obj, ginfo); - } else if( obj.params.tags ){ - // tags - for(i=0; i remove selection for this layer - if( shape === "reset" ){ - // remove last selection - delete layer.selection; - // change selection to none? - if( opts.activateselection !== false ){ - // deselect current active object, if necessary - if( canvas.getActiveObject() ){ - canvas.discardActiveObject(); - } - // re-display so we don't see the old group - canvas.renderAll(); - } - return this; - } - // collect the specified shapes - this._selectShapes(layerName, shape, opts, (obj) => { - // only select once, don't select shapes in groups - if( $.inArray(obj, arr) < 0 && (!obj.params || !obj.params.groupid) ){ - arr.push(obj); - } - }); - if( arr.length ){ - // deselect current active object, if necessary - if( canvas.getActiveObject() ){ - canvas.discardActiveObject(); - } - if( arr.length === 1 ){ - // select 1 shape - selection = arr[0]; - } else { - // create a group selection of 2+ shapes - selection = new fabric.ActiveSelection(arr, { - canvas: canvas - }); - } - // make this the active selection - canvas.setActiveObject(selection); - // display the new group - canvas.renderAll(); - } - return this; -}; - -// remove shapes from a group selection -// call using image context -// eslint-disable-next-line no-unused-vars -JS9.Fabric.unselectShapes = function(layerName, shape, opts){ - let layer, unshape, selection; - layer = this.getShapeLayer(layerName); - // sanity check - if( !layer || !this.layers[layerName] ){ return; } - // default is to unselect everything - if( !shape || shape === "all" || shape === "selected" ){ - return this.selectShapes(layerName, "reset"); - } - selection = this.layers[layerName].selection || "selected"; - unshape = `${selection} && !(${shape})`; - return this.selectShapes(layerName, unshape, opts); -}; - -// update public object in shapes -// call using image context -JS9.Fabric.updateShapes = function(layerName, shape, mode, opts){ - // process the specified shapes - this._selectShapes(layerName, shape, null, (obj, ginfo) => { - this._updateShape(layerName, obj, ginfo, mode, opts); - }); - return this; -}; - -// update multi-selection dialog boxes -// call using image context -JS9.Fabric._updateMultiDialogs = function(setmode){ - // update multiselect dialog box for this image, if necessary - $("form[class*='regionsConfigForm']").each((index, element) => { - const multi = $(element).data("multi"); - const winid = $(element).data("winid"); - const im = $(element).data("im"); - if( multi && winid && im === this ){ - if( im.tmp.updateMulti !== false ){ - im.initRegionsForm(null, {winid, multi, setmode}); - } - } - }); -}; - -// primitive to update one shape -// call using image context -JS9.Fabric._updateShape = function(layerName, obj, ginfo, mode, opts){ - let i, s, scalex, scaley, px, py, tval1, tval2, angstr; - let bin, zoom, tstr, dpos, gpos, ipos, npos, objs, olen, radius, oangle; - let opos, dist, txeq, owcssys, imforce, agroup, apos; - const pub = {}; - const layer = this.layers[layerName]; - const moderexp = /^(child||export|unexport|move|mouseout)$/; - const tr = (x) => { return x.toFixed(2); }; - const tr4 = (x) => { return x.toFixed(4); }; - const updatewcs = (wcs, layer, pub, regstr, angstr, opts, obj) => { - let i, s, v0, v1; - // get ra and dec of central position - s = JS9.pix2wcs(wcs, pub.x, pub.y).trim().split(/\s+/); - obj.rastr = s[0]; - obj.decstr = s[1]; - obj.wcssys = s[2]; - v0 = JS9.strtoscaled(s[0]); - if( JS9.isHMS(s[2], v0.dtype) ){ - v0.dval *= 15.0; - } - v1 = JS9.strtoscaled(s[1]); - obj.ra = v0.dval; - obj.dec = v1.dval; - // generate WCS strings iff updateWCS is true - if( (opts.updateWCS !== false) && - (opts.updateWCS || layer.opts.updateWCS) ){ - obj.wcsstr = JS9.reg2wcs(wcs, regstr, JS9.REGSIZE) - .replace(/;$/, ""); - // add angle to line, if possible - if( pub.shape === "line" && angstr ){ - obj.wcsstr = obj.wcsstr.replace(/} *$/, angstr + "}"); - } - // wcs size args - s = obj.wcsstr.replace(/.*\(/,"").replace(/\).*/,"").split(","); - for(i=0; i { - let xname; - const xeq = (onchange) => { - try{ - this.params.xeqonchange = false; - JS9.xeqByName(onchange, window, this, pub); - } - catch(e){ - JS9.log("error in onchange: %s [%s]\n%s", - this.id, e.message, JS9.strace(e)); - } - finally{ - this.params.xeqonchange = true; - } - }; - if( !obj.params.parent && !mode.match(moderexp) ){ - // when xeqonchange is set on a layer - if( this.params.xeqonchange && layer.show ){ - if( layer.opts.onchange ){ - xeq(layer.opts.onchange); - } else if( layerName === "regions" && - JS9.Regions.opts.onchange ){ - // if onchange was set after region layer was set up - xeq(JS9.Regions.opts.onchange); - } - } - // plugin callbacks: these have the form on[layer]change, - // e.g. onregionschange - xname = `on${layerName}change`; - this.xeqPlugins("shape", xname, pub); - } - }; - // sanity check - if( !obj || !obj.params ){ return; } - // convenience variables - ginfo = ginfo || {}; - opts = opts || {}; - mode = mode || "update"; - // set scaling based on zoom factor - if( this.display.layers[layerName].dtype === "main" && - !obj.params.preservedcoords ){ - zoom = this.rgb.sect.zoom; - } else { - zoom = 1; - } - // fill in the blanks - pub.mode = mode; - pub.id = obj.params.id; - pub.groupid = obj.params.groupid; - pub.shape = obj.params.shape; - pub.layer = layerName; - pub.color = obj.color || obj.stroke; - pub.tags = obj.params.tags; - pub.sticky = obj.params.sticky; - pub.preservedcoords = obj.params.preservedcoords; - if( obj.params.ignore ){ - pub.ignore = true; - } - if( obj.params.parent ){ - pub.parent = obj.params.parent.obj.params.id; - } else { - pub.parent = null; - } - if( obj.params.children && obj.params.children.length ){ - // for now, just output the first one (cf. listRegions) - pub.child = obj.params.children[0].id; - } else { - pub.child = null; - } - dpos = obj.getCenterPoint(); - gpos = {x: 0, y: 0}; - if( ginfo.group ){ - // in a group, the display pos is relative to group pos, - // so we need to add them together - gpos = ginfo.group.getCenterPoint(); - dpos = {x: gpos.x + (dpos.x * ginfo.group.scaleX), - y: gpos.y + (dpos.y * ginfo.group.scaleY)}; - // also need to rotate the position by the group angle - if( ginfo.group.angle ){ - dpos = JS9.rotatePoint(dpos, ginfo.group.angle, gpos); - } - // is the group contained in an active selection?? - if( ginfo.group.type !== "activeSelection" ){ - agroup = layer.canvas.getActiveObject(); - if( agroup && agroup.type === "activeSelection" ){ - objs = agroup.getObjects(); - olen = objs.length; - for(i=0; i= 360 ){ - pub.angle -= 360; - } - // the parts of the obj.scale[XY] values related to size (not zoom, binning) - scalex = obj.scaleX / zoom; - scaley = obj.scaleY / zoom; - if( ginfo.group ){ - scalex *= ginfo.group.scaleX; - scaley *= ginfo.group.scaleY; - } - switch(pub.shape){ - case "annulus": - pub.shape = "annulus"; - pub.radii = []; - if( pub.imsys !== "image" ){ - pub.lcs.radii = []; - } - pub.imstr = `annulus(${tr(px)},${tr(py)},`; - tstr = `annulus ${pub.x} ${pub.y} `; - objs = obj.getObjects(); - olen = objs.length; - for(i=0; i 0 ){ - pub.imstr += ","; - tstr += " "; - } - // get current point - npos = this.displayToImagePos( - {x: gpos.x + obj.left + obj.points[i].x * obj.scaleX, - y: gpos.y + obj.top + obj.points[i].y * obj.scaleY} - ); - // add rotation - npos = JS9.rotatePoint(npos, oangle, {x: pub.x, y: pub.y}); - if( pub.imsys === "image" ){ - pub.imstr += `${tr(npos.x)},${tr(npos.y)}`; - } else { - const {x, y} = this.imageToLogicalPos(npos); - pub.imstr += `${tr(x)},${tr(y)}`; - pub.lcs.pts.push({x, y}); - } - tstr += `${npos.x} ${npos.y}`; - pub.pts.push(npos); - if( pub.shape === "line" ){ - if( i === 0 ){ - dist = 0; - } else { - opos = pub.pts[i-1]; - dist += Math.sqrt(((npos.x - opos.x) * (npos.x - opos.x)) + - ((npos.y - opos.y) * (npos.y - opos.y))); - } - } - } - if( pub.shape === "line" && JS9.notNull(dist) ){ - pub.imstr += `) {"size":${tr(dist)},"units":"pixels"`; - // if only two points, add angle between them - if( pub.pts.length === 2 ){ - tval1 = Math.atan2(pub.pts[1].y - pub.pts[0].y, - pub.pts[1].x - pub.pts[0].x) * 180 / Math.PI; - while( tval1 < 0 ){ tval1 += 360; } - angstr = `,"posang":${tr4(tval1)},"posunits":"degrees"`; - pub.imstr += angstr; - } - pub.imstr += "}"; - } else { - pub.imstr += ")"; - } - // points already have the angle incorporated into them - pub.angle = 0; - break; - case "text": - pub.imstr = `text(${tr(px)},${tr(py)},"${obj.text}",${tr4(pub.angle)})`; - tstr = `text ${pub.x} ${pub.y} "${obj.text}"` + ` ${pub.angle * Math.PI / 180.0}`; - pub.text = obj.text; - break; - default: - break; - } - // wcs processing - if( this.validWCS() ){ - updatewcs(this.raw.wcs, layer, pub, tstr, angstr, opts, pub); - if( mode !== "export" && - obj.params.wcsconfig && obj.params.wcsconfig.wcssys ){ - txeq = JS9.globalOpts.xeqPlugins; - JS9.globalOpts.xeqPlugins = false; - owcssys = this.getWCSSys(); - if( JS9.notWCS(obj.params.wcsconfig.wcssys) ){ - pub.wcsconfig = $.extend(true, {}, obj.params.wcsconfig); - } else { - this.setWCSSys(obj.params.wcsconfig.wcssys, false); - updatewcs(this.raw.wcs, layer, pub, tstr, angstr, opts, - obj.params.wcsconfig); - pub.wcsconfig = $.extend(true, {}, obj.params.wcsconfig); - } - this.setWCSSys(owcssys, false); - JS9.globalOpts.xeqPlugins = txeq; - } - } - // generic "data" property, optionally supplied when the shape is created - pub.data = obj.params.data; - // save the pub object - obj.set("pub", pub); - // update dialog box, if necessary - if( obj.params.winid ){ - if( $(obj.params.winid).is(":visible") ){ - this.initRegionsForm(obj); - } else { - obj.params.winid = null; - } - } - // stop here if no callbacks were requested - if( opts.nocb ){ - return pub; - } - // callbacks for regions - xplugins(); - // post processing: - // copy to clipboard, if necessary - if( layerName === "regions" && JS9.globalOpts.regToClipboard ){ - switch(mode){ - case "update": - i = pub.parent || pub.id; - break; - default: - i = null; - break; - } - if( JS9.notNull(i) ){ - // ignore any problems - try{ s = this.listRegions(i, {mode: 1, includedcoords: true}); } - catch(e){ s = null; } - if( s ){ JS9.clipboard = s; } - } - } - // update multi dialog boxes, if necessary - if( layerName === "regions" && mode === "wcs" ){ - this._updateMultiDialogs(true); - } - // and return it - return pub; -}; - -// lookup a group, either by name or by object -// groupObj = this.lookupGroup(groupID) -// groupID = this.lookupGroup(groupObj) -JS9.Fabric.lookupGroup = function(group, layerName){ - let i, j, objs, obj, sobjs, sobj, layer, canvas; - layerName = layerName||"regions"; - layer = this.getShapeLayer(layerName); - // sanity check - if( !layer ){ return null; } - canvas = this.layers[layerName].canvas; - if( typeof group === "string" ){ - objs = canvas.getObjects(); - for(i=0; i 0 ){ - this.display.displayMessage("regions", grpstr); - } - return grpstr.replace(/;\s*/g, "\n").replace(/\n\n$/, "\n"); -}; - -// create a quasi-permanent group from selected shapes -// call using image context -// eslint-disable-next-line no-unused-vars -JS9.Fabric.groupShapes = function(layerName, shape, opts){ - let i, s, layer, dlayer, canvas, obj, id, skip, dupid; - const objs = []; - const pubs = []; - const getid = (opts) => { - let i = 1; - let id = opts.groupid || `group_${i}`; - while( this.lookupGroup(id) ){ - i = i+1; - id = id.replace(/_[0-9][0-9]*$/, "") + `_${i}`; - } - return id; - }; - // get layer - layer = this.getShapeLayer(layerName); - // sanity check - if( !layer ){ return 0; } - // dlayer - dlayer = layer.dlayer; - // opts is optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse groupShapes opts: ${opts}`, e); } - } - // convenience variable - canvas = layer.canvas; - // id for this group - id = getid(opts); - // collect the specified shapes - this._selectShapes(layerName, shape, opts, (obj) => { - if( $.inArray(obj, objs) < 0 ){ - // so far, so goodx - skip = false; - // look for conflicts - if( obj.params.groupid ){ - switch(JS9.globalOpts.regGroupConflict){ - case "skip": - // save id of the conflicting group - dupid = obj.params.groupid; - // flag to skip adding to new group - skip = true; - break; - case "error": - default: - s = sprintf("%s can only be a member of one group [%s,%s]", - layerName === "regions" ? "regions" : "shapes", - obj.params.id, obj.params.groupid); - JS9.error(s); - break; - } - } - // save for group, if necessary - if( !skip ){ - obj.params.groupid = id; - if( $.inArray("groupid", obj.params.exports) < 0 ){ - obj.params.exports.push("groupid"); - } - // save object - objs.push(obj); - pubs.push(obj.pub); - // save children (i.e., text) - // (but not pub, since don't call ongroupcreate on text) - if( obj.params && obj.params.children.length ){ - for(i=0; i= 0 ){ - shape.params.exports.splice(idx, 1); - } - } - } - } - } - // remove id from groups - if( this.groups[layerName] ){ - idx = $.inArray(groupid, this.groups[layerName]); - if( idx >= 0 ){ - this.groups[layerName].splice(idx, 1); - } - } - - return this; -}; - -// remove the active shape -// eslint-disable-next-line no-unused-vars -JS9.Fabric.removeShapes = function(layerName, shape, opts){ - let i, layer, canvas, ao; - let undoao = false; - const lopts = {mode: 1, includedcoords: true, sortids: false}; - const arr = []; - const grp = []; - layer = this.getShapeLayer(layerName); - // sanity check - if( !layer ){ return; } - canvas = layer.canvas; - // opts is optional - opts = opts || {}; - // list active objects - if( canvas.getActiveObject() ){ - ao = canvas.getActiveObjects(); - } - // save regions for unremove? - if( layerName === "regions" && JS9.globalOpts.unremoveReg ){ - this.regstack.push(this.listRegions(shape, lopts, layerName)); - if( this.regstack.length > JS9.globalOpts.unremoveReg ){ - this.regstack = this.regstack.slice(0,JS9.globalOpts.unremoveReg); - } - } - // process the specified shapes - this._selectShapes(layerName, shape, opts, (obj, ginfo) => { - let i, child, parent; - if( (obj.params.removable !== false || opts.overrideRemovable) && - (!obj.params.sticky || opts.sticky !== false) ){ - if( layer.dlayer.dtype === "main" ){ - this._updateShape(layerName, obj, ginfo, "remove"); - } - // clear any dialog box - if( obj.params.winid ){ - obj.params.winid.close(); - obj.params.winid = null; - } - // unlink parent - if( obj.params.parent ){ - parent = obj.params.parent.obj; - for(i=parent.params.children.length-1; i>=0; i--){ - if( obj === parent.params.children[i].obj ){ - parent.params.children.splice(i,1); - break; - } - } - } - // mark children for removal - for(i=0; i= 0 ){ - undoao = true; - } - // mark for removal - arr.push(obj); - } - }); - // discard active object if we are deleting one of its shapes - // do before delete, as per: http://fabricjs.com/v2-breaking-changes-2 - if( undoao ){ - canvas.discardActiveObject(); - } - // remove groups - for(i=0; i { - // public part of the shape - myshape = obj.pub || {}; - // might need shape object itself - if( opts.includeObj ){ - myshape.obj = obj; - } - shapes.push(myshape); - }); - // sort shapes by id to maintain original order of creation - if( opts.sortids !== false ){ - shapes.sort((a, b) => { return (a.id||0) - (b.id||0); }); - } - return shapes; -}; - -// change the specified shape(s) -// call using image context -JS9.Fabric.changeShapes = function(layerName, shape, opts){ - let i, s, sobj, bopts, layer, canvas, ao, aos, rlen, maxr, zoom, exports; - let topts, xopts; - const orad = [], cpts = []; - layer = this.getShapeLayer(layerName); - // sanity check - if( !layer || !opts ){ return; } - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse shape opts: ${opts}`, e); } - } - // delay changing the region, if this image is not the one being displayed - if( this.display.image !== this ){ - this.delayedShapes = this.delayedShapes || []; - this.delayedShapes.push({layer: layerName, shape: shape, - mode: "change", opts: opts}); - return; - } - canvas = layer.canvas; - // active object - ao = canvas.getActiveObject(); - if( ao && ao.type === "activeSelection" ){ - // save and temporarily remove a selected group - // fabric.js doesn't deal with this very well - aos = canvas.getActiveObjects() - canvas.discardActiveObject(); - canvas.renderAll(); - ao = null; - } - // this selection is usually saved - if( JS9.isNull(opts.saveselection) ){ opts.saveselection = true; } - // process the specified shapes - this._selectShapes(layerName, shape, opts, (obj, ginfo) => { - // set scaling based on zoom factor - if( this.display.layers[layerName].dtype === "main" && - !obj.params.preservedcoords ){ - zoom = this.rgb.sect.zoom; - } else { - zoom = 1; - } - // combine the objects parameters with the new options - // clearing some of the old ones first to avoid conflicts - if( opts.radii ){ - obj.params.radii = []; - } - if( opts.tags ){ - obj.params.tags = []; - } - if( opts.locked !== undefined ){ - delete obj.params.changeable; - } - // combine new opts with old opts - bopts = $.extend(true, {}, obj.params, opts); - // parse options and generate new obj and params - sobj = this._parseShapeOptions(layerName, bopts, obj); - // remove means remove specified shapes or all shapes - if( sobj.remove ){ - if( sobj.remove === true || sobj.remove === "true" ){ - sobj.remove = "all"; - } - if( sobj.remove !== false && sobj.remove !== "false" ){ - this.removeShapes(layerName, sobj.remove || "all"); - return; - } - } - // get new option names to export when saving regions - exports = this._exportShapeOptions(opts).filter( (item) => { - return !{}.hasOwnProperty.call(obj.params.exports, item); - }); - sobj.params.exports = obj.params.exports.concat(exports); - // if stroke (color) is defined, we probably need to convert it to hex - if( sobj.opts.stroke ){ - sobj.opts.color = sobj.opts.stroke; - sobj.opts.stroke = JS9.colorToHex(sobj.opts.stroke); - } - // shape-specific pre-processing - switch(obj.params.shape){ - case "text": - // can't use stroke, use fill instead - if( sobj.opts.stroke ){ - sobj.opts.fill = sobj.opts.stroke; - } - sobj.opts.strokeWidth = 0; - break; - case "line": - case "polygon": - // if we are changing the points, reset the fabric angle - // otherwise, it's applied to points which know nothing about it - if( sobj.opts.points && sobj.opts.points.length ){ - obj.angle = 0; - } - break; - } - // change the shape - obj.set(sobj.opts); - // reestablish params object - obj.params = $.extend(false, {}, obj.params, sobj.params); - // if strokeWidth is specified, we change params.sw1, - // which will be used by the rescaleBorder routine below - if( sobj.opts.strokeWidth ){ - obj.params.sw1 = sobj.opts.strokeWidth; - } - // shape-specific post-processing - // mainly: change of size => remove size-based scaling factor - switch(obj.params.shape){ - case "annulus": - if( opts.radii && opts.radii.length ){ - // remove existing annuli - // can't remove inside the forEachObject loop - obj.forEachObject( (tobj) => { orad.push(tobj); }); - // so do it outside the loop - rlen = orad.length; - for(i=0; i { - xopts = $.extend(true, {}, topts); - if( cpts[idx] ){ xopts.points = cpts[idx]; } - tobj.set(xopts); - }); - break; - case "ellipse": - if( opts.r1 ){ - obj.rx = obj.params.r1; - obj.scaleX = zoom; - // this sets the width of the control box - // why is it not done automatically??? - obj.width = obj.rx * 2; - } - if( opts.r2 ){ - obj.ry = obj.params.r2; - obj.scaleY = zoom; - // this sets the height of the control box - // why is it not done automatically??? - obj.height = obj.ry * 2; - } - break; - case "line": - case "polygon": - if( (opts.points && opts.points.length) || - (opts.pts && opts.pts.length) ){ - obj.scaleX = zoom; - obj.scaleY = zoom; - } - if( ao === obj ){ - JS9.Fabric.removePolygonAnchors(layer.dlayer, obj); - JS9.Fabric.addPolygonAnchors(layer.dlayer, obj); - } - // reset the center point - JS9.resetPolygonCenter(obj); - break; - case "text": - if( opts.text ){ - obj.params.text = opts.text; - } - break; - } - // make sure border width is correct - obj.rescaleBorder(); - // non-changeable shapes go to back - if( obj.params.changeable === false ){ - canvas.sendToBack(obj); - } - // send region to front or back of set of overlapping regions - switch(sobj.opts.send){ - case "front": - canvas.bringToFront(obj); - if( ao === obj ){ - canvas.discardActiveObject(); - } - break; - case "back": - canvas.sendToBack(obj); - if( ao === obj ){ - canvas.discardActiveObject(); - } - break; - default: - break; - } - // update children - JS9.Fabric.updateChildren(layer.dlayer, obj, "moving"); - JS9.Fabric.updateChildren(layer.dlayer, obj, "scaling"); - JS9.Fabric.updateChildren(layer.dlayer, obj, "rotating"); - // update child's parent deltas - JS9.Fabric.updateChildren(layer.dlayer, obj, "deltas"); - // and reset coords - obj.setCoords(); - // might need to make a text shape as a child of this shape - this._handleChildText(layerName, obj, opts); - // update the shape info and make callbacks - this._updateShape(layerName, obj, ginfo, "update"); - // callback if necessary - if( opts.onchangeshapes && obj.pub ){ - try{ JS9.xeqByName(opts.onchangeshapes, this, this, obj.pub); } - catch(e){ JS9.error("in onchangeshapes callback", e, false); } - } - }); - // reconstitute the selected group, if necessary - if( aos ){ - this.selectShapes(layerName, aos); - } - // redraw (unless explicitly specified otherwise) - if( (opts.redraw === undefined) || opts.redraw ){ - canvas.renderAll(); - } - return this; -}; - -// update shape layer after a change in panning, zooming, binning -// uses ListRegions to recreate regions, very stable but slow for many shapes -// call using image context -JS9.Fabric.refreshShapes = function(layerName){ - let regstr, owcssys, txeq, opts; - // sanity check - if( !layerName ){ return; } - // convenience variables - opts = { - mode:1, - sticky:false, - ignoreignore:true, - saveediting:true, - savewcsconfig:true, - sortids: false, - saveid:true - }; - // temporarily turn off plugin execution to avoid firing regions callbacks - txeq = JS9.globalOpts.xeqPlugins; - JS9.globalOpts.xeqPlugins = false; - // temporarily change wcs system to be independent of image coords - // (in case we copied regions from one image to another) - owcssys = this.getWCSSys(); - if( owcssys === "image" ){ - // get a wcs sys independent of image coords - if( this.validWCS() ){ - this.setWCSSys("native", false); - } else { - this.setWCSSys("physical", false); - } - } - // special optimization when panning an image with the mouse, - // to deal with slow panning a large number of regions - if( this.tmp.panzoomRefresh && this.tmp.panzoomRefresh[layerName] ){ - if( !this.tmp.panzoomRefresh[layerName].regstr ){ - // save current regions - regstr = this.listRegions("all", opts, layerName); - this.tmp.panzoomRefresh[layerName] = {regstr:regstr, refresh:false}; - // remove current regions (including unremovable ones) - this.removeShapes(layerName, "all", {overrideRemovable: true, - sticky: false}); - } else { - if( this.tmp.panzoomRefresh[layerName].refresh ){ - regstr = this.tmp.panzoomRefresh[layerName].regstr; - // add back regions in current configuration - this.addShapes(layerName, regstr, {restoreid: true}); - } - } - } else { - // get current regions (i.e., before update to current configuration) - regstr = this.listRegions("all", opts, layerName); - if( regstr ){ - // save selection (remove shapes destroys it) - this.saveSelection(layerName); - // remove current regions (including unremovable ones) - this.removeShapes(layerName, "all", {overrideRemovable: true, - sticky: false}); - // add back regions in current configuration - this.addShapes(layerName, regstr, {restoreid: true, - sortids: false}); - // restore selection - this.restoreSelection(layerName); - } - } - // restore wcs system, if necessary - if( owcssys === "image" ){ - this.setWCSSys(owcssys, false); - // update shapes to use the original coord system - this.updateShapes(layerName, "all", "refresh"); - } - // restore plugin execution - JS9.globalOpts.xeqPlugins = txeq; - return this; -}; - -// copy one or more shapes to another image -// call using image context -JS9.Fabric.copyShapes = function(layerName, to, which){ - let i, im, s, opts, layer; - const ims = []; - layer = this.getShapeLayer(layerName); - // sanity check - if( !layer ){ return; } - if( typeof to === "object" ){ - ims.push(to); - } else if( to === "all" ){ - for(i=0; i (Math.PI * 2) ){ - angle -= Math.PI * 2; - } - pos.x = Math.cos(angle) * local.x - Math.sin(angle) * local.y; - pos.y = Math.sin(angle) * local.x + Math.cos(angle) * local.y; - //Get the list of points from the polygon - points = obj.points; - //The algorithm is simple, iterate through the list of points - //and select a pair which forms a side of the polygon. - //For this side, pick a main point. Find the direction vector - //with respect to this main point, and find the position vector - //from this main point to the drag position. - //Dot product of position vector and direction vector give us - //the projection of the point on the current side. - //A simple bounds checking to ensure the projection is on - //the side, then a distance calculation. - //If the distance found is less than the current minimum difference - //update diff, newX and newY. - for(i=0; i p2.x ? p1.x : p2.x); - maxY = (p1.y > p2.y ? p1.y : p2.y); - //Select p2 as the main point. - //Find the direction vector and normalize it. - dir = {x: p1.x - p2.x, y: p1.y - p2.y}; - m = Math.sqrt(dir.x*dir.x + dir.y*dir.y); - if( m !== 0 ){ - dir.x = dir.x/m; - dir.y = dir.y/m; - } - //Find the position vector - pVec = {x: pos.x - p2.x, y: pos.y - p2.y}; - //Dot product - dot = pVec.x * dir.x + pVec.y * dir.y; - //Find the projection along the current side - p = {x: p2.x + dir.x * dot, y: p2.y + dir.y * dot}; - //Bounds checking to ensure projection remains - //between the point pair. - if( p.x < minX ){ - p.x = minX; - } else if( p.x > maxX ){ - p.x = maxX; - } - if( p.y < minY ){ - p.y = minY; - } else if( p.y > maxY ){ - p.y = maxY; - } - //Distance calculation. - d = (p.x-pos.x) * (p.x-pos.x) + (p.y-pos.y) * (p.y-pos.y); - //Minimum comparison. - if( d < diff ){ - diff = d; - newpt.x = p.x; - newpt.y = p.y; - if( i === points.length ){ - newpt.i = 0; - } else { - newpt.i = i; - } - } - } - // get canvas - layer = this.getShapeLayer(layerName); - // remove anchors - JS9.Fabric.removePolygonAnchors(layer.dlayer, obj); - // add the new point into the points array - points.splice(newpt.i+1, 0, {x: newpt.x, y: newpt.y}); - - // making this the active object will recreate the anchors - switch(obj.type){ - case "polyline": - case "polygon": - JS9.Fabric.addPolygonAnchors(layer.dlayer, obj); - layer.dlayer.canvas.renderAll(); - break; - } - // set currently selected shape - if( obj.polyparams ){ - layer.dlayer.params.sel = obj.polyparams.polygon; - } else if( obj.params ){ - layer.dlayer.params.sel = obj; - } -}; - -// remove the specified point -// call using image context -JS9.Fabric._removePolygonPoint = function(layerName, obj){ - let layer, polygon, points, pt; - // sanity check - if( !obj || !obj.polyparams ){ return; } - // get info on this point - polygon = obj.polyparams.polygon; - points = polygon.points; - // maintain minimum number of points - if( (polygon.type === "polygon") && (points.length <= 3) ){ - return; - } else if( (polygon.type === "polyline") && (points.length <= 2) ){ - return; - } - pt = obj.polyparams.point; - // delete to stop an executing movePoint callback - delete obj.polyparams.point; - // get layer - layer = this.getShapeLayer(layerName); - // remove anchors - JS9.Fabric.removePolygonAnchors(layer.dlayer, polygon); - // add the new point into the points array - points.splice(pt, 1); - // reset the center point - JS9.resetPolygonCenter(polygon); - // making this the active object will recreate the anchors - layer.canvas.setActiveObject(polygon); -}; - -// add anchors to a polygon -// don't need to call using image context -JS9.Fabric.addPolygonAnchors = function(dlayer, obj){ - let i, a; - let pos = {}; - const canvas = dlayer.canvas; - const movePoint = (obj) => { - let anchor, poly, pt, points, im; - // anchor changed location to obj.transform.target in v4.5.1 - if( obj.target && obj.target.polyparams ){ - anchor = obj.target; - } else if( obj.transform && - obj.transform.target && obj.transform.target.polyparams ){ - anchor = obj.transform.target; - } - // sanity check - if( !anchor ){ return; } - // this is the polygon associated with this anchor - poly = anchor.polyparams.polygon; - // if the polygon is not changeable, just return - if( poly.params.changeable === false ){ - return; - } - // these are the points in the polygon - points = poly.get("points"); - // this is the point id associated with this anchor - pt = anchor.polyparams.point; - // if pt is not valid, just return - if( pt === undefined || points[pt] === undefined ){ - return; - } - // new point for this anchor relative to center - // NB: anchor was rotated onto the vertex - if( poly.angle ){ - pos = JS9.rotatePoint({x: anchor.left, y: anchor.top}, -poly.angle, - {x: poly.left, y: poly.top}); - } else { - pos.x = anchor.left; - pos.y = anchor.top; - } - // move the polygon point to the anchor (in unscaled coords) - points[pt].x = (pos.x - poly.left) / poly.scaleX; - points[pt].y = (pos.y - poly.top) / poly.scaleY; - // reset the center point - JS9.resetPolygonCenter(poly); - // update the shape info - if( dlayer.display.image ){ - im = dlayer.display.image; - im._updateShape(poly.params.layerName, poly, null, "update"); - if( im.params.listonchange || poly.params.listonchange ){ - im.listRegions(poly, {mode: 2}); - } - } - // redraw - canvas.renderAll(); - }; - const moveAnchors = (obj) => { - let ii; - let tpos = {}; - // change anchor positions - for(ii=0; ii { - moveAnchors(obj); - }); - obj.on("rotating", () => { - moveAnchors(obj); - }); - obj.on("scaling", () => { - moveAnchors(obj); - }); - obj.setCoords(); -}; - -// remove anchors from a polygon -// don't need to call using image context -JS9.Fabric.removePolygonAnchors = function(dlayer, shape){ - let i; - const canvas = dlayer.canvas; - if( shape && shape.params && shape.params.anchors ){ - // need to be able to remove anchors when locking a polygon - // if( shape.params.changeable === false ){ - // return; - // } - // remove all anchors - for(i=0; i { return b.radius - a.radius; }); - // add circle for edit - for(i=0; i { - if( o.params && o.params.shape === "circle" ){ - circles.push(o); - } - }); - // will hold new radii - opts.radii = []; - // ids of circles - ids = [...this.editAnnulus.ids]; - // for each id, find the circle object and get its radius - // (what we're looking for is likely at the end of the stack) - for(j=circles.length-1; j>=0; j--){ - cid = circles[j].params.id; - for(i=ids.length-1; i>=0; i--){ - id = ids[i]; - if( cid === id ){ - // if pub.radius is epsilon, change back to 0 - if( circles[j].pub.radius === epsilon ){ - circles[j].pub.radius = 0; - } - opts.radii.push(circles[j].pub.radius); - ids.splice(i, 1); - break; - } - } - if( !ids.length ){ - break; - } - } - opts.radii.sort((a, b) => { return a - b; }); - } - // change the annulus - this.changeShapes(layerName, this.editAnnulus.annulus, opts); - // remove the edit circles - this.removeShapes(layerName, this.editAnnulus.ids); - // remove current edit parameters - delete this.editAnnulus; -}; - -// update child regions -// don't need to call using image context -JS9.Fabric.updateChildren = function(dlayer, shape, type){ - let i, o, p, child, nangle, npos, pangle, objects, olen, got; - let tdleft, tdtop; - let x = {}; - // region layer only, for now - if( dlayer.layerName !== "regions" ){ - return; - } - // re-init objects within for parents and children - if( type === "objects" ){ - // get list of top-level objects, replacing groups with their objects - objects = dlayer.canvas.getObjects().reverse(); - olen = objects.length; - do{ - got = 0; - while( olen-- ){ - o = objects[olen]; - // replace group with objects inside the group - if( o.type === "group" && !o.params ){ - objects.splice(olen, 1, ...o.getObjects()); - got++; - } - } - olen = objects.length; - } while( got ); - // first get a list of parents and children - objects.forEach( (o) => { - if( o.params ){ - if( o.params.parent || o.params.children.length ){ - x[o.params.id] = o; - } - } - }); - // then re-assign obj pointers to parents and children - objects.forEach( (o) => { - if( o.params ){ - if( o.params.parent ){ - o.params.parent.obj = x[o.params.parent.id]; - } - for(i=0; i= 360 ){ - pangle -= 360; - } - nangle = pangle - p.lastangle; - npos = JS9.rotatePoint({x: child.left,y: child.top}, - nangle, - {x: shape.left, y: shape.top}); - child.left = npos.x; - child.top = npos.y; - p.dleft = shape.left - child.left; - p.dtop = shape.top - child.top; - child.angle = child.angle + nangle; - while( child.angle < 0 ){ - child.angle += 360; - } - while( child.angle >= 360 ){ - child.angle -= 360; - } - p.lastangle = pangle; - break; - case "scaling": - p.dleft = p.dleft * (shape.scaleX / p.lastscalex); - p.dtop = (p.dtop - p.textheight) * - (shape.scaleY / p.lastscaley) + p.textheight; - p.lastscalex = shape.scaleX; - p.lastscaley = shape.scaleY; - p.moved = true; - child.left = shape.left - p.dleft; - child.top = shape.top - p.dtop; - break; - } - child.setCoords(); - if( dlayer.display.image ){ - dlayer.display.image.updateShapes(dlayer.layerName, child, - "updatechild"); - } - } -}; - -// reset center of a polygon -// don't need to call using image context -JS9.resetPolygonCenter = function(poly){ - let i, ndx, ndy, dobj, calcDim, dx, dy; - let tpos = {}; - // deltas to center - dobj = poly._calcDimensions(); - dx = (dobj.left + (dobj.width / 2)) * poly.scaleX; - dy = (dobj.top + (dobj.height / 2)) * poly.scaleY; - // new center - if( poly.angle ){ - tpos = JS9.rotatePoint( - {x: poly.left + dx, y: poly.top + dy}, - poly.angle, - {x: poly.left, y: poly.top} - ); - } else { - tpos.x = poly.left + dx; - tpos.y = poly.top + dy; - } - - // move points relative to new center - // required by polygon changes starting in fabric 1.5.x - ndx = dx / poly.scaleX; - ndy = dy / poly.scaleY; - for(i=0; i

    `; - // add layers - for( key of Object.keys(this.layers) ){ - layer = this.layers[key]; - // output (showing) layers attached to the main display - if( layer.dlayer.dtype === "main" && layer.show ){ - html += `${divstr}${layer.dlayer.canvas.toSVG()}
    `; - } - } - // add colorbar, if necessary - if( (opts.colorbar === undefined) || opts.colorbar ){ - pinst = this.display.pluginInstances.JS9Colorbar; - if( pinst && pinst.isActive() ){ - // separate from main display - yoff += 2; - // colorbar canvas - dataURL = pinst.colorbarjq[0].toDataURL("image/png"); - yoff += this.display.height; - divstr = sprintf(divtmpl, xoff, yoff); - html += `${divstr}
    `; - if( pinst.textjq && pinst.textjq[0] ){ - // colorbar text/tickmarks canvas - dataURL = pinst.textjq[0].toDataURL("image/png"); - yoff += pinst.colorbarjq.height() + 1; - divstr = sprintf(divtmpl, xoff, yoff); - // need to rescale the text ... argh!!! - html += `${divstr}
    `; - } - } - } - // finish up - html += ""; - // this is needed since v9 ... why??? - if( window.electron ){ - winurl = "data:text/html," + html; - } - // make a new window containing a blank URL - win = window.open(winurl, this.id, winopts); - if( !win ){ - JS9.error("could not create print window (check your pop-up blockers)"); - return; - } - // open DOM for writing - if( win.document ){ - // open it (not strictly necessary but ...) - win.document.open(); - // overwrite the doc with our html - win.document.write(html); - // must close! - win.document.close(); - } else { - JS9.error("no method available for drawing image into print window"); - } -}; - -// incorporate these graphics routines into JS9 -JS9.Fabric.initGraphics = function(){ - // display methods - JS9.Display.prototype.newShapeLayer = JS9.Fabric.newShapeLayer; - // image shape methods - JS9.Image.prototype._selectShapes = JS9.Fabric._selectShapes; - JS9.Image.prototype._updateShape = JS9.Fabric._updateShape; - JS9.Image.prototype._parseShapes = JS9.Fabric._parseShapes; - JS9.Image.prototype._parseShapeOptions = JS9.Fabric._parseShapeOptions; - JS9.Image.prototype._exportShapeOptions = JS9.Fabric._exportShapeOptions; - JS9.Image.prototype._handleChildText = JS9.Fabric._handleChildText; - JS9.Image.prototype._addPolygonPoint = JS9.Fabric._addPolygonPoint; - JS9.Image.prototype._removePolygonPoint = JS9.Fabric._removePolygonPoint; - JS9.Image.prototype._ungroupAnnulus = JS9.Fabric._ungroupAnnulus; - JS9.Image.prototype._regroupAnnulus = JS9.Fabric._regroupAnnulus; - JS9.Image.prototype._updateMultiDialogs = JS9.Fabric._updateMultiDialogs; - JS9.Image.prototype.addShapes = JS9.Fabric.addShapes; - JS9.Image.prototype.updateShapes = JS9.Fabric.updateShapes; - JS9.Image.prototype.getShapes = JS9.Fabric.getShapes; - JS9.Image.prototype.changeShapes = JS9.Fabric.changeShapes; - JS9.Image.prototype.removeShapes = JS9.Fabric.removeShapes; - JS9.Image.prototype.refreshShapes = JS9.Fabric.refreshShapes; - JS9.Image.prototype.copyShapes = JS9.Fabric.copyShapes; - JS9.Image.prototype.selectShapes = JS9.Fabric.selectShapes; - JS9.Image.prototype.unselectShapes = JS9.Fabric.unselectShapes; - JS9.Image.prototype.groupShapes = JS9.Fabric.groupShapes; - JS9.Image.prototype.ungroupShapes = JS9.Fabric.ungroupShapes; - JS9.Image.prototype.listGroups = JS9.Fabric.listGroups; - JS9.Image.prototype.lookupGroup = JS9.Fabric.lookupGroup; - JS9.Image.prototype.saveSelection = JS9.Fabric.saveSelection; - JS9.Image.prototype.restoreSelection = JS9.Fabric.restoreSelection; - // shape layer methods - JS9.Image.prototype.getShapeLayer = JS9.Fabric.getShapeLayer; - JS9.Image.prototype.showShapeLayer = JS9.Fabric.showShapeLayer; - JS9.Image.prototype.activeShapeLayer = JS9.Fabric.activeShapeLayer; - JS9.Image.prototype.displayShapeLayers = JS9.Fabric.displayShapeLayers; - JS9.Image.prototype.toggleShapeLayers = JS9.Fabric.toggleShapeLayers; - // print method which know about shapes - JS9.Image.prototype.print = JS9.Fabric.print; -}; - -// initialize graphics to use Fabric -JS9.Fabric.initGraphics(); - -/* - * mouse/touch module (May 19, 2016) - */ - -// create our namespace, and specify some meta-information and params -JS9.MouseTouch = {}; -JS9.MouseTouch.CLASS = "JS9"; // class of plugin -JS9.MouseTouch.NAME = "MouseTouch"; // name of this plugin -JS9.MouseTouch.WIDTH = 512; // width of light window -JS9.MouseTouch.HEIGHT = 220; // height of light window -JS9.MouseTouch.BASE = JS9.MouseTouch.CLASS + JS9.MouseTouch.NAME; - -JS9.MouseTouch.mouseText = []; -JS9.MouseTouch.mouseText[0] = "Move mouse, no buttons pressed:"; -JS9.MouseTouch.mouseText[1] = "Move mouse, primary button pressed:"; -JS9.MouseTouch.mouseText[2] = "Move mouse, secondary button pressed:"; - -JS9.MouseTouch.touchText = []; -JS9.MouseTouch.touchText[0] = "Touch move, with one finger:"; -JS9.MouseTouch.touchText[1] = "Touch move, with two fingers:"; -JS9.MouseTouch.touchText[2] = "Touch move, with three fingers:"; - -JS9.MouseTouch.textHTML="
    %s
    "; - -JS9.MouseTouch.actionHTML="
    %s
    "; - -// get an id based on the action -JS9.MouseTouch.actionid = function(cname, aname){ - return (`${cname}_${aname}`).replace(/[^A-Za-z0-9_]/g, "_"); -}; - -// add to the text descriptions -JS9.MouseTouch.addText = function(container, text){ - let s, divjq; - // create the html for this action - s = sprintf(JS9.MouseTouch.textHTML, text); - // add text html to the text container - divjq = $("
    ") - .addClass(`${JS9.MouseTouch.BASE}Text`) - .html(s) - .appendTo(container); - return divjq; -}; - -// add to the sortable action list -JS9.MouseTouch.addAction = function(container, cname, aname){ - let s, id, divjq; - id = JS9.MouseTouch.actionid(cname, aname); - // create the html for this action - s = sprintf(JS9.MouseTouch.actionHTML, aname); - // add action html to the action container - divjq = $("
    ") - .addClass(`${JS9.MouseTouch.BASE}Action`) - .attr("id", id) - .html(s) - .appendTo(container); - return divjq; -}; - -// display value/position -// eslint-disable-next-line no-unused-vars -JS9.MouseTouch.isPinch = function(im, evt){ - let i, display, dist, pinc, pdec; - const npinch = JS9.globalOpts.pinchWait; - const pthresh = JS9.globalOpts.pinchThresh; - // sanity check - if( !im ){ return -1; } - display = im.display; - if( !JS9.globalOpts.mousetouchZoom || (im.pos.touches.length !== 2) ){ - return -1; - } - switch(display.ispinch ){ - case -1: - case 1: - return display.ispinch; - } - dist = Math.sqrt(((im.pos.touches[0].x - im.pos.touches[1].x) * - (im.pos.touches[0].x - im.pos.touches[1].x)) + - ((im.pos.touches[0].y - im.pos.touches[1].y) * - (im.pos.touches[0].y - im.pos.touches[1].y))); - if( !display.dist0 ){ - display.dist0 = dist; - } - display.deltas.push(Math.floor(dist - display.dist0)); - if( display.deltas.length >= npinch ){ - for(i=1, pinc=0, pdec=0; i display.deltas[i-1] ){ - pinc++; - } else if( display.deltas[i] < display.deltas[i-1] ){ - pdec++; - } - } - if( (pinc >= pthresh) || (pdec >= pthresh) ){ - display.ispinch = 1; - } else { - display.ispinch = -1; - } - display.lastzoom = 0; - return display.ispinch; - } - // not sure yet - return 0; -}; - -// --------------------------------------------------------------------- -// -// MouseTouch.Actions: callbacks when on mouse or touch movement -// -// for mouse: no click, primary click, secondary click -// for touch: 1, 2, or 3 fingers down -// -// the mouseActions and touchActions arrays in JS9.globalOpts determine -// the initial mapping of mouse/touch configuration to callback, e.g.: -// -// JS9.globalOpts.mouseActions = ["display value/position", "change contrast/bias", "pan the image"]; -// -// You can add your own to the Actions object, with titles in mouseText ... -// They are transferred to the display object. -// -// --------------------------------------------------------------------- -JS9.MouseTouch.Actions = {}; - -// display value/position -// eslint-disable-next-line no-unused-vars -JS9.MouseTouch.Actions["display value/position"] = function(im, ipos, evt){ - // special key: do nothing - if( JS9.specialKey(evt) ){ - return; - } - // display pixel and wcs values - if( JS9.globalOpts.internalValPos && im && ipos ){ - if( (ipos.x > 0) && (ipos.y > 0) && - (ipos.x <= im.raw.width) && (ipos.y <= im.raw.height) ){ - im.valpos = im.updateValpos(ipos, true); - } - } -}; - -// change contrast/bias -JS9.MouseTouch.Actions["change contrast/bias"] = function(im, ipos, evt){ - let x, y, pos, display; - // skip contrast/bias change? - if( !JS9.globalOpts.internalContrastBias || !im || !ipos ){ - return; - } - // skip if colormap is static - if( im.cmapObj.type === "static" ){ - return; - } - // convenience variables - display = im.display; - // make sure we moved the mouse a bit - if( im.pos0 && im.pos ){ - if( ((Math.abs(im.pos0.x-im.pos.x) < JS9.NOMOVE) && - (Math.abs(im.pos0.y-im.pos.y) < JS9.NOMOVE)) ){ - return; - } - } - // inside a region or with special key: no contrast/bias - if( im.clickInRegion || JS9.specialKey(evt) ){ - return; - } - // if we have an RGB file or image overlay, no contrast/bias - if( im.useOffScreenCanvas() ){ - return; - } - // get canvas position - pos = JS9.eventToDisplayPos(evt, im.posOffset); - // contrast/bias change - x = Math.floor(pos.x + 0.5); - y = Math.floor(pos.y + 0.5); - // values only from within display window? - if( JS9.globalOpts.containContrastBias ){ - if( (x < 0) || (y < 0) || - (x >= display.canvas.width) || (y >= display.canvas.height) ){ - return; - } - } - im.params.bias = x / display.canvas.width; - im.params.contrast = y / display.canvas.height * 10.0; - // work-around for FF bug, not fixed as of 8/8/2012 - // https://bugzilla.mozilla.org/show_bug.cgi?id=732621 - if( JS9.bugs.firefox_linux ){ - window.setTimeout(() => { - im.displayImage("scaled", {blendMode: false}); - }, 0); - } else { - im.displayImage("scaled", {blendMode: false}); - } - // hack: delete filterRGBImage from stash to avoid restore during reproject - im.xeqStashDiscard("filterRGBImage"); - // extended plugins - if( JS9.globalOpts.extendedPlugins ){ - im.xeqPlugins("image", "onchangecontrastbias"); - } -}; - -// stop action for contrast/bias: redisplay image -// eslint-disable-next-line no-unused-vars -JS9.MouseTouch.Actions["change contrast/bias"].stop = function(im, ipos, evt){ - // if blendMode is on, we have to redisplay - if( im.display.blendMode ){ - im.displayImage("rgb"); - } -}; - -// zoom the image -JS9.MouseTouch.Actions["wheel zoom"] = function(im, evt){ - let ozoom, nzoom, maxzoom, key; - let floor = JS9.globalOpts.panzoomRefreshLimit; - let got = 0; - const delta = evt.originalEvent.deltaY * Math.sign(JS9.DIRZOOM); - // sanity check - if( !im ){ return; } - // is scroll to zoom turned on? - if( !JS9.globalOpts.mousetouchZoom ){ - return; - } - // prevent pileup - im.tmp.wheelzooms = im.tmp.wheelzooms || 0; - if( im.tmp.wheelzooms++ % JS9.MODZOOM !== 0 ){ - return; - } - // current zoom - ozoom = im.getZoom(); - // scroll by the delta - if( delta < 0 ){ - nzoom = Math.min(JS9.MAXZOOM, ozoom + JS9.ADDZOOM); - } else { - nzoom = Math.max(JS9.MINZOOM, ozoom - JS9.ADDZOOM); - } - // stop zooming once full image is in the screen? - if( JS9.globalOpts.mousetouchLimit ){ - maxzoom = Math.min(im.display.width/im.raw.width, - im.display.height/im.raw.height); - if( maxzoom > nzoom && ozoom > nzoom ){ - return; - } - } - // a little rounding makes the zoom nicer - nzoom = Math.round((nzoom + 0.00001) * 100) / 100; - // see if any layers have many regions, thus requiring optimization - for( key of Object.keys(im.layers) ){ - if( im.layers[key].show && im.layers[key].opts.panzoom ){ - if( im.layers[key].canvas.size() > floor ){ - im.tmp.panzoomRefresh = im.tmp.panzoomRefresh || {}; - im.tmp.panzoomRefresh[key] = {}; - got++; - } - } - } - // timeout to refresh layers - if( im.tmp.panzoomTimeout ){ - clearTimeout(im.tmp.panzoomTimeout); - delete im.tmp.panzoomTimeout; - } - if( got || im.tmp.panzoomRefresh ){ - im.tmp.panzoomTimeout = setTimeout(() => { - im.refreshLayers(im.tmp.panzoomRefresh); - delete im.tmp.panzoomRefresh; - }, JS9.TIMEOUT); - } - // zoom the image - im.setZoom(nzoom); -}; - -// pan the image -// eslint-disable-next-line no-unused-vars -JS9.MouseTouch.Actions["pan the image"] = function(im, ipos, evt){ - let dx, dy, temp, sect, pos, key; - let thresh = JS9.globalOpts.panMouseThreshold; - let floor = JS9.globalOpts.panzoomRefreshLimit; - // sanity check - if( !im ){ return; } - sect = im.rgb.sect; - // how much would we pan by? - dx = ((im.pos0.x - im.pos.x) / sect.zoom); - dy = ((im.pos0.y - im.pos.y) / sect.zoom); - // pan the image (but avoid a redisplay, if we haven't moved much) - if( Math.abs(dx) >= thresh || Math.abs(dy) >= thresh ){ - // flips will change the pan direction - if( im.params.flip === "x" ){ - dx = -dx; - } else if( im.params.flip === "y" ){ - dy = -dy; - } else if( im.params.flip === "xy" ){ - dx = -dx; - dy = -dy; - } - // rotations will change the pan direction - if( im.params.rot90 === 90 ){ - temp = dx; - dx = -dy; - dy = temp; - } else if( im.params.rot90 === 180 ){ - dx = -dx; - dy = -dy; - } else if( im.params.rot90 === -90 ){ - temp = dx; - dx = dy; - dy = -temp; - } - pos = {x: sect.xcen + dx, y: sect.ycen - dy}; - // rotations will change the pan position - if( im.params.rotate ){ - pos = JS9.rotatePoint(pos, - -im.params.rotate, - {x: sect.xcen, y: sect.ycen}); - } - // see if any layers have many regions, thus requiring optimization - for( key of Object.keys(im.layers) ){ - if( im.layers[key].show && im.layers[key].opts.panzoom ){ - if( im.layers[key].canvas.size() > floor ){ - im.tmp.panzoomRefresh = im.tmp.panzoomRefresh || {}; - im.tmp.panzoomRefresh[key] = {}; - } - } - } - im.setPan(pos); - // reset initial position - im.pos0 = im.pos; - } -}; - -// pinch zoom -// eslint-disable-next-line no-unused-vars -JS9.MouseTouch.Actions.pinch = function(im, ipos, evt){ - let display, dist, nzoom; - // sanity check - if( !im ){ return; } - // is scroll to zoom turned on? - display = im.display; - // get current distance - dist = Math.sqrt(((im.pos.touches[0].x - im.pos.touches[1].x) * - (im.pos.touches[0].x - im.pos.touches[1].x)) + - ((im.pos.touches[0].y - im.pos.touches[1].y) * - (im.pos.touches[0].y - im.pos.touches[1].y))); - nzoom = display.zoom0 * dist / display.dist0; - // a little rounding makes the zoom nicer - nzoom = Math.max(JS9.MINZOOM, Math.min(JS9.MAXZOOM, Math.round((nzoom + 0.00001) * 100) / 100)); - // zoom the image - if( nzoom !== display.lastzoom ){ - im.setZoom(nzoom); - } - display.lastzoom = nzoom; -}; - -// start of mouse/touch action processing -JS9.MouseTouch.Actions.start = function(im, ipos, evt){ - let display, action; - if( im ){ - display = im.display; - display.ispinch = 0; - display.dist0 = 0; - display.zoom0 = im.rgb.sect.zoom; - display.deltas = []; - } - action = JS9.MouseTouch.getAction(im, evt); - // call the start mouse/touch action, if necessary - if( JS9.MouseTouch.Actions[action] && - JS9.MouseTouch.Actions[action].start ){ - JS9.MouseTouch.Actions[action].start(im, im.ipos, evt); - } -}; - -// end of mouse/touch action processing -JS9.MouseTouch.Actions.stop = function(im, ipos, evt){ - const action = JS9.MouseTouch.getAction(im, evt); - // call the stop mouse/touch action, if necessary - if( JS9.MouseTouch.Actions[action] && - JS9.MouseTouch.Actions[action].stop ){ - JS9.MouseTouch.Actions[action].stop(im, im.ipos, evt); - } - return; -}; - -// get action associated with the current clickState -JS9.MouseTouch.getAction = function(im, evt){ - let action, display; - // sanity check - if( !im ){ return action; } - display = im.display; - switch(im.clickState){ - // mouse move actions - case 0: - action = display.mouseActions[0]; - break; - case 1: - action = display.mouseActions[1]; - break; - case 2: - action = display.mouseActions[2]; - break; - // touch event actions - case -1: - action = display.touchActions[0]; - break; - case -2: - switch( JS9.MouseTouch.isPinch(im, evt) ){ - case -1: - action = display.touchActions[1]; - break; - case 0: - // do nothing, no idea if its a pinch yet - break; - case 1: - action = "pinch"; - break; - } - break; - case -3: - action = display.touchActions[2]; - break; - default: - break; - } - return action; -}; - -// execute the mouse/touch action routine -JS9.MouseTouch.action = function(im, evt, action){ - action = action || JS9.MouseTouch.getAction(im, evt); - // call the mouse/touch action - if( action && JS9.MouseTouch.Actions[action] ){ - JS9.MouseTouch.Actions[action](im, im.ipos, evt); - } -}; - -// change zoom mode for this display -JS9.MouseTouch.mousetouchzoom = function(id, target){ - const display = JS9.lookupDisplay(id); - const mode = target.checked; - // change global blink mode - if( display ){ - JS9.globalOpts.mousetouchZoom = mode; - } -}; - -// constructor: add HTML elements to the plugin -JS9.MouseTouch.init = function(){ - let i, s; - // on entry, these elements have already been defined: - // this.div: the DOM element representing the div for this plugin - // this.divjq: the jquery object representing the div for this plugin - // this.id: the id of the div (or the plugin name as a default) - // this.display: the display object associated with this plugin - // this.dispMode: display mode (for internal use) - // - // create container to hold action container and header - // clean main container - this.divjq.html(""); - // allow scrolling on the plugin - this.divjq.addClass("JS9PluginScrolling"); - // main container - this.mousetouchContainer = $("
    ") - .addClass(`${JS9.MouseTouch.BASE}Container`) - .attr("id", `${this.id}MouseTouchContainer`) - .appendTo(this.divjq); - s = sprintf("
    Drag an action to reconfigure JS9 mouse/touch events:

    ", `${JS9.MouseTouch.BASE}Header`); - this.mousetouchHeadContainer = $("") - .addClass(`${JS9.MouseTouch.BASE}Container`) - .attr("id", `${this.id}MouseTouchHeadContainer`) - .html(s) - .appendTo(this.mousetouchContainer); - this.mousetouchTextContainer = $("") - .addClass(`${JS9.MouseTouch.BASE}Container`) - .attr("id", `${this.id}MouseTouchTextContainer`) - .appendTo(this.mousetouchContainer); - this.mousetouchActionContainer = $("") - .addClass(`${JS9.MouseTouch.BASE}Container`) - .attr("id", `${this.id}MouseTouchActionContainer`) - .appendTo(this.mousetouchContainer); - if( JS9.TOUCHSUPPORTED ){ - // container to hold text descriptions - this.mousetouchTouchTextContainer = $("

    ") - .addClass(`${JS9.MouseTouch.BASE}TextContainer`) - .attr("id", `${this.id}TouchTextContainer`) - .html("") - .appendTo(this.mousetouchTextContainer); - for(i=0; i") - .addClass(`${JS9.MouseTouch.BASE}ActionContainer`) - .attr("id", `${this.id}TouchContainer`) - .html("") - .appendTo(this.mousetouchActionContainer); - // add touch actions, if necessary - for(i=0; i { - this.oidx = ui.item.index(); - }, - stop: (event, ui) => { - const nidx = ui.item.index(); - const oarr = this.display.touchActions.splice(this.oidx, 1)[0]; - // JS9 action list reflects the sort - this.display.touchActions.splice(nidx, 0, oarr); - delete this.oidx; - } - }); - } - if( !/iPad|iPhone|iPod/.test(navigator.platform) ){ - // container to hold text descriptions - this.mousetouchMouseTextContainer = $("
    ") - .addClass(`${JS9.MouseTouch.BASE}TextContainer`) - .attr("id", `${this.id}MouseTextContainer`) - .appendTo(this.mousetouchTextContainer); - for(i=0; i< 3; i++){ - JS9.MouseTouch.addText.call(this, - this.mousetouchMouseTextContainer, - JS9.MouseTouch.mouseText[i]); - } - for(i=3; i") - .addClass(`${JS9.MouseTouch.BASE}ActionContainer`) - .attr("id", `${this.id}MouseContainer`) - .html("") - .appendTo(this.mousetouchActionContainer); - // add mouse actions, if necessary - for(i=0; i { - this.oidx = ui.item.index(); - }, - stop: (event, ui) => { - const nidx = ui.item.index(); - const oarr = this.display.mouseActions.splice(this.oidx, 1)[0]; - // JS9 action list reflects the sort - this.display.mouseActions.splice(nidx, 0, oarr); - delete this.oidx; - } - }); - } - // add the footer, containing buttons - s = sprintf("

    Use mouse wheel or pinch to zoom:          
    ", `${JS9.MouseTouch.BASE}Footer`, this.display.id); - this.mousetouchFootContainer = $("") - .addClass(`${JS9.MouseTouch.BASE}Container`) - .attr("id", `${this.id}MouseTouchFootContainer`) - .html(s) - .appendTo(this.mousetouchContainer); - // set initial value of scroll - if( JS9.globalOpts.mousetouchZoom ){ - this.mousetouchContainer.find("input").attr("checked", true); - } -}; - - -// --------------------------------------------------------------------- -// Regions object defines high level calls for Regions plugin -// --------------------------------------------------------------------- - -JS9.Regions = {}; -JS9.Regions.CLASS = "JS9"; -JS9.Regions.NAME = "Regions"; - -// defaults for new regions -JS9.Regions.opts = { - // update WCS strings - updateWCS: true, - // pan and zoom enabled - panzoom: true, - tags: "source,include", - strokeWidth: 2, - // annuli: inner and outer radius, number of annuli - iradius: 15, - oradius: 30, - nannuli: 1, - // box - width: 60, - height: 60, - // circle - radius: 30, - // ellipse: - // use r1, r2 to avoid confusion with rad1, rad2 for rounding in boxes! - r1: 30, - r2: 20, - // point - ptshape: "box", - ptsize: 2, - // line - linepoints: [{x: -30, y: 30}, {x:30, y:-30}], - // polygon in display coords - // points: [{x: -30, y: 30}, {x:30, y:30}, {x:30, y:-30}, {x:-30, y: -30}], - polypoints: [{x: -30, y: 30}, {x:30, y:30}, {x:0, y:-30}], - // text - // fontFamily: "Helvetica, sans-serif", - fontFamily: "Helvetica", - fontSize: 14, - fontStyle: "normal", - fontWeight: 300, - textAlign: "left", - // angles (box, ellipse) - angle: 0, - // anchor radii - aradius1: 4, - aradius2: 8, - // region configuration url - configURL: "./params/regionsconfig.html", - // region save url - saveURL: "./params/regionssave.html", - // should overlapping shapes be sorted (smallest on top)? - sortOverlapping: true, - // title for region config dialog box - title: "Edit region", - // no centered scaling for these regions - noCenteredScaling: ["box", "line"], - // colors for tags - // these should be ordered from more specific to less specific - tagcolors: { - include_source: "#00FF00", - exclude_source: "#FF0000", - include_background: "#FFD700", - exclude_background: "#FF8C00", - source: "#00FF00", - background: "#FFD700", - defcolor: "#00FF00" - }, - // mouse double-click processing - onmousedblclick(im, xreg, evt, target){ - let params = target.params; - if( (params && !params.winid && !params.ignore ) || - (!params && target.type === "activeSelection") || - (!params && target.type === "group") ){ - if( JS9.globalOpts.editRegions ){ - im.displayRegionsForm(target); - } - } - return; - }, - // mouse down processing - onmousedown(im, xreg, evt, target){ - let poly; - // nb: target might be a polygon anchor => no params - let params = target.params; - if( JS9.specialKey(evt) ){ - if( params ){ - im._regroupAnnulus(params.layerName, evt); - } - if( target.type === "polygon" || target.type === "polyline" ){ - // add polygon point - im._addPolygonPoint(params.layerName, target, evt); - im._updateShape(params.layerName, target, null, "update"); - } else if( target.polyparams && target.polyparams.polygon ){ - // remove polygon point - poly = target.polyparams.polygon; - im._removePolygonPoint(poly.params.layerName, target); - im._updateShape(poly.params.layerName, poly, null, "update"); - } else if( params && params.shape === "annulus" ){ - im._ungroupAnnulus(params.layerName, target); - } - } - }, - // mouse up processing - onmouseup(){ - let i; - let objs = []; - // one active object - if( this.getActiveObject() ){ - objs.push(this.getActiveObject()); - } - objs.push(this.getActiveObjects()); - // re-select polygon which was just processed - for(i=0; i { - let i, tim; - let objs = []; - if( dlayer.display.image ){ - tim = dlayer.display.image; - // one active object - // group of active objects - objs.push(dlayer.canvas.getActiveObjects()); - // process all active objects - for(i=0; i { - const multi = $(element).data("multi"); - const winid = $(element).data("winid"); - const im = $(element).data("im"); - if( multi && winid && im === this ){ - opts.winid = winid; - im.initRegionsForm(null, opts); - got++; - } - }); - // change title to reflect multi-select, if necessary - title = title.replace(/regions?/, "selected regions"); - // all done if we reinit'ed an existing window - if( got ){ return; } - } - // call this once window is loaded - $(JS9.lightOpts[JS9.LIGHTWIN].topid) - .arrive(".regionsConfigForm", {onceOnly: true}, () => { - opts.firsttime = true; - if( shape && shape.params ){ - this.updateShapes("regions", shape, "wcsconfig"); - } - this.initRegionsForm(shape, opts); - }); - // bring up display window - opts.winid = this.displayAnalysis("regions", s, {title, winformat}); - // save winid, if possible - if( shape && shape.params ){ - shape.params.winid = opts.winid; - } -}; - -// initialize the region config form -// call using image context -JS9.Regions.initConfigForm = function(obj, opts){ - let i, key, val, el, el2, wcssys, twcssys, mover, mout, p1, p2, cmode; - let s, s2, s3, s4, winid, wid, form, otitle, fav, arr, ao, grp, o, objs; - let multi = false; - const wcsinfo = this.raw.wcsinfo || {cdelt1: 1, cdelt2: 1}; - const defobj = { - type: "multi", - pub: {shape: "multi", wcsconfig: {}}, - params: {} - }; - const fmt= (val) => { - if( val === undefined ){ - return undefined; - } - if( (typeof val === "number") && (val % 1 !== 0) ){ - val = Math.round((val + 0.00001) * 10000) / 10000; - } - return(String(val)); - }; - const replaceNewline = (s) => { - const nl = String.fromCharCode(13, 10); - if( typeof s === "string" ){ - return s.replace(/\\n/g, nl); - } - return s; - }; - // which wcssys do we use? edit version, if available - if( obj && obj.pub ){ - if( obj.pub.wcsconfig && obj.pub.wcsconfig.wcssys ){ - wcssys = obj.pub.wcsconfig.wcssys; - } else { - wcssys = this.params.wcssys; - } - } else { - wcssys = this.params.wcssys; - // fake obj: makes the checks easier, avoid if( obj ... ) everywhere - obj = defobj; - } - cmode = obj.params.changeable === false; - // opts is optional - opts = opts || {}; - // where to we get winid? - if( obj.params.winid ){ - winid = obj.params.winid; - } else if( opts.winid ){ - winid = opts.winid; - } - // window id is required - if( !winid ){ - return; - } - // find the form, based on winid - wid = $(winid).attr("id"); - // leave trailing space! - form = `#${wid} .regionsConfigForm `; - // valid form is required - if( !$(form).length ){ - return; - } - // if the form is already a multi-select form, keep it that way - if( $(form).data("multi") ){ - multi = true; - } else { - multi = opts.multi; - } - // remove the nodisplay class from shape's div - $(`${form}.${obj.pub.shape}`).each((index, element) => { - $(element).removeClass("nodisplay"); - }); - // fill in form values based on current values in the shape object - $(`${form}.val`).each((index, element) => { - val = ""; - key = $(element).attr("name"); - // key-specific pre-processing - switch(key){ - case "x": - case "y": - if( obj.pub.lcs && obj.pub.lcs[key] !== undefined ){ - val = fmt(obj.pub.lcs[key]); - } else if( obj.pub[key] !== undefined ){ - val = fmt(obj.pub[key]); - } - break; - case "radii": - if( obj.pub.radii ){ - if( JS9.notWCS(wcssys) || - !obj.pub.wcsconfig || - !obj.pub.wcsconfig.wcsstr ){ - val = obj.pub.imstr - .replace(/^annulus\(/,"").replace(/\)$/,"") - .split(",").slice(2).join(","); - } else { - val = obj.pub.wcsconfig.wcsstr - .replace(/^annulus\(/,"").replace(/\)$/,"") - .split(",").slice(2).join(","); - } - } - break; - case "pts": - if( obj.pub.pts ){ - obj.pub.pts.forEach( (p) => { - if( val ){ - val += ", "; - } - val += `${p.x.toFixed(2)}, ${p.y.toFixed(2)}`; - }); - } else if( obj.pub.imstr ){ - // use the flat points list instead of the pts object array - val = obj.pub.imstr.replace(/^.*\(/, "").replace(/\)$/, ""); - } - break; - case "linelength": - if( obj.pub.pts && obj.pub.pts.length === 2 ){ - p1 = obj.pub.pts[0]; - p2 = obj.pub.pts[1]; - val = fmt(Math.sqrt((p2.x - p1.x) * (p2.x - p1.x) + - (p2.y - p1.y) * (p2.y - p1.y))); - switch(wcssys){ - case "image": - case "physical": - break; - default: - val *= Math.abs(wcsinfo.cdelt1); - val *= Math.abs(wcsinfo.cdelt2); - break; - } - val = fmt(val); - this.tmp.linelength = val; - } - break; - case "lineangle": - if( obj.pub.pts && obj.pub.pts.length === 2 ){ - p1 = obj.pub.pts[0]; - p2 = obj.pub.pts[1]; - val = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI; - while( val < 0 ){ val += 360; } - val = fmt(val); - this.tmp.lineangle = val; - } - break; - case "fontFamily": - if( obj.getFontFamily ){ - val = obj.getFontFamily(); - } - break; - case "fontSize": - if( obj.getFontSize ){ - val = obj.getFontSize(); - } - break; - case "fontStyle": - if( obj.getFontStyle ){ - val = obj.getFontStyle(); - } - break; - case "fontWeight": - if( obj.getFontWeight ){ - val = obj.getFontWeight(); - } - break; - case "colorPicker": - if( obj.pub.color !== undefined ){ - val = JS9.colorToHex(obj.pub.color); - } else { - val = $(form).data("colorpicker") || JS9.globalOpts.defcolor; - } - break; - case "color": - // multi: don't set color to avoid applying it to new selections - if( !multi ){ - if( obj.pub.color !== undefined ){ - val = fmt(obj.pub.color); - } else if( $(form).data("colorpicker") ){ - val = $(form).data("colorpicker"); - } - } - break; - case "strokeWidth": - if( obj.params.sw1 ){ - val = obj.params.sw1; - } else { - val = $(form).data("strokewidth") || ""; - } - break; - case "strokeDashes": - if( obj.strokeDashArray ){ - val = obj.strokeDashArray.join(" "); - if( val.match(/NaN/) ){ - val = ""; - } - } else { - val = $(form).data("strokedashes") || ""; - } - break; - case "regstr": - if( JS9.notWCS(wcssys) || - !obj.pub.wcsconfig || - !obj.pub.wcsconfig.wcsstr ){ - val = `${obj.pub.imsys};${obj.pub.imstr}`; - } else { - val = `${obj.pub.wcsconfig.wcssys};${obj.pub.wcsconfig.wcsstr}`; - } - break; - case "xpos": - switch(wcssys){ - case "image": - if( obj.pub.preservedcoords && obj.pub.dx !== undefined ){ - val = sprintf("d%.1f", obj.pub.dx); - } else if( obj.pub.x !== undefined ){ - val = sprintf("%.1f", obj.pub.x); - } - break; - case "physical": - if( obj.pub.lcs ){ - val = sprintf("%.1f", obj.pub.lcs.x); - } else if( obj.pub.x !== undefined ){ - val = sprintf("%.1f", obj.pub.x); - } - break; - default: - if( obj.pub.wcsconfig && JS9.notNull(obj.pub.wcsconfig.ra) ){ - val = sprintf("%.6f", obj.pub.wcsconfig.ra); - } else if( obj.pub.x !== undefined ){ - val = sprintf("%.1f", obj.pub.x); - } - break; - } - $(`${form}[name='${key}']`).prop("readonly", cmode); - break; - case "ypos": - switch(wcssys){ - case "image": - if( obj.pub.preservedcoords && obj.pub.dy !== undefined ){ - val = sprintf("d%.1f", obj.pub.dy); - } else if( obj.pub.y !== undefined ){ - val = sprintf("%.1f", obj.pub.y); - } - break; - case "physical": - if( obj.pub.lcs ){ - val = sprintf("%.1f", obj.pub.lcs.y); - } else if( obj.pub.y !== undefined ){ - val = sprintf("%.1f", obj.pub.y); - } - break; - default: - if( obj.pub.wcsconfig && JS9.notNull(obj.pub.wcsconfig.dec) ){ - val = sprintf("%.6f", obj.pub.wcsconfig.dec); - } else if( obj.pub.y !== undefined ){ - val = sprintf("%.1f", obj.pub.y); - } - break; - } - $(`${form}[name='${key}']`).prop("readonly", cmode); - break; - case "radius": - case "oradius": - case "length": - case "width": - case "r1": - switch(wcssys){ - case "image": - if( obj.pub[key] !== undefined ){ - val = fmt(obj.pub[key]); - } - break; - case "physical": - if( obj.pub.lcs && obj.pub.lcs[key] !== undefined ){ - val = fmt(obj.pub.lcs[key]); - } - break; - default: - if( obj.pub.wcsconfig && - JS9.notNull(obj.pub.wcsconfig.wcssizestr) ){ - val = fmt(obj.pub.wcsconfig.wcssizestr[0]); - } else if( obj.pub[key] !== undefined ){ - val = fmt(obj.pub[key]); - } - break; - } - $(`${form}[name='${key}']`).prop("readonly", cmode); - break; - case "height": - case "r2": - switch(wcssys){ - case "image": - if( obj.pub[key] !== undefined ){ - val = fmt(obj.pub[key]); - } - break; - case "physical": - if( obj.pub.lcs && obj.pub.lcs[key] !== undefined ){ - val = fmt(obj.pub.lcs[key]); - } - break; - default: - if( obj.pub.wcsconfig && - JS9.notNull(obj.pub.wcsconfig.wcssizestr) ){ - val = fmt(obj.pub.wcsconfig.wcssizestr[1]); - } else if( obj.pub[key] !== undefined ){ - val = fmt(obj.pub[key]); - } - break; - } - $(`${form}[name='${key}']`).prop("readonly", cmode); - break; - case "wcssys": - case "savewcs": - // add all wcs sys options - el = $(form).find(`[name='${key}']`); - if( !el.find("option").length ){ - for(i=0; i${JS9.wcssyss[i]}`); - } - } - if( key === "savewcs" ){ - twcssys = JS9.globalOpts.regSaveWCS || wcssys; - } else { - twcssys = wcssys; - } - el.find("option").each((index, element) => { - if( twcssys === element.value ){ - val = element.value; - } - }); - break; - case "wcsunits": - if( obj.pub.wcsunits ){ - val = obj.pub.wcsunits; - } - break; - case "childtext": - if( obj.params.children && obj.params.children.length > 0 ){ - val = replaceNewline(obj.params.children[0].obj.text); - } - break; - case "text": - if( obj.pub[key] !== undefined ){ - val = replaceNewline(fmt(obj.pub[key])); - } - break; - case "id": - if( multi ){ - val = "selected"; - } else if( obj.pub.id !== undefined ){ - val = String(obj.pub.id); - // set width of text input to be width of string - $(element).css("width", `${val.length}ch`); - } - break; - case "tags": - if( obj.pub[key] !== undefined ){ - val = fmt(obj.pub[key]); - } - break; - case "savefile": - val = $(form).data("savefile") || - this.tmp.saveregionsFile || - "js9.reg"; - if( window.electron && !val.match(/.*\//) ){ - val = `${window.electron.currentDir}/${val}`; - } - break; - case "selectfilter": - val = $(form).data("selectfilter"); - break; - case "selectshape": - case "selectcolor": - case "selecttag": - case "selectwcs": - case "selectgroup": - JS9.Regions.regionsConfigSetSelectMenu(this, $(form), key); - break; - default: - if( obj.pub[key] !== undefined ){ - val = fmt(obj.pub[key]); - } - break; - } - $(element).val(val); - }); - // display or hide options - if( multi || !this.raw.wcs || this.raw.wcs < 0 ){ - $(form).find("[name='wcssys']").hide(); - } - // edit-able parameters - // child text display for shapes, editable if no existing children yet - if( obj.type !== "text" && obj.params.children ){ - $(`${form}.childtext`).removeClass("nodisplay"); - } - // init options, if necessary - if( opts.firsttime ){ - // desktop: display file browser - if( window.electron ){ - $(form).find(".rsavebrowse, .rconfigbrowse") - .removeClass("nodisplay"); - } - // multi "cur" works off selected, not current, regions - if( multi ){ - $(form).find("label[for='savecur']") - .text("sel"); - $(form).find("input[id='savecur']") - .data("tooltip", "save selected regions"); - $(form).find("[id='selectreg']") - .prop("checked", true); - } else { - $(form).find(".checkboxes").removeClass("nodisplay"); - } - // add wcs button options - if( JS9.favorites.wcs && JS9.favorites.wcs.length ){ - // display wcs buttons - el = $(form).find(".rwcsbuttons").removeClass("nodisplay"); - // add buttons to button container, if necessary - el2 = el.find(".rwcsbuttoncontainer"); - if( el2.length && !el2.find(".rwcsbutton").length ){ - // add radio buttons for each favorite wcs - for(i=0; i - - - `); - } - // init the radio buttons - $(form).find('.rwcsbuttons').find(`[value='${wcssys}']`) - .prop('checked', true); - } - } - // alternate colorpicker - if( !JS9.globalOpts.internalColorPicker || - !$.fn.spectrum.inputTypeColorSupport() ){ - el = $(form).find(`input[name='colorPicker']`) - el.spectrum({showButtons: false, - showInput: false, - preferredFormat: "hex6"}); - // when the color is changed via the colorpicker - el.on('move.spectrum', (evt, tinycolor) => { - let color = tinycolor.toHexString(); - $(form).find("input[name='color']").val(color); - $(form).data("colorpicker", color); - }); - } - } - // checkboxes - if( obj.params.listonchange === undefined ){ - obj.params.listonchange = false; - } - if( obj.params.listonchange ){ - $(`${form}[name='listonchange']`).prop("checked", true); - } else { - $(`${form}[name='listonchange']`).prop("checked", false); - } - if( obj.params.changeable !== false ){ - $(`${form}[name='locked']`).prop("checked", false); - } else { - $(`${form}[name='locked']`).prop("checked", true); - } - if( obj.params.sticky ){ - $(`${form}[name='sticky']`).prop("checked", true); - } else { - $(`${form}[name='sticky']`).prop("checked", false); - } - // save regions processing - $(`${form}[id='includejson']`) - .prop("checked", JS9.globalOpts.regIncludeJSON); - $(`${form}[id='includecomments']`) - .prop("checked", JS9.globalOpts.regIncludeComments); - $(`${form}[id='savedcoords']`) - .prop("checked", JS9.globalOpts.regSaveDCoords); - $(`${form}[id='includewcs']`) - .prop("checked", JS9.globalOpts.csvIncludeWCS); - // unset all save format radio buttons - $(form).find(`input[name='saveformat']`) - .prop("checked", false); - // set save format based on global value - $(form).find(`input[value='${JS9.globalOpts.regSaveFormat}']`) - .prop("checked", true); - // unset all save wcs radio buttons - $(form).find(`input[name='rwcsbutton']`) - .prop("checked", false); - // set save wcs based on global value - $(form).find(`input[value='${JS9.globalOpts.regSaveWCS||wcssys}']`) - .prop("checked", true); - // set which regions get saved - if( opts.type === "save" ){ - s = `save${JS9.globalOpts.regSaveWhich1}`; - } else { - s = `save${JS9.globalOpts.regSaveWhich2}`; - } - $(`${form}[id='${s}']`).prop("checked", true); - // triggering the savefile will cause format to be updated - // and focus to be set - if( opts.type === "save" ){ - $(form).find(`input[name='savefile']`).trigger("change"); - } - // style menus - $(form).find(`input[name='strokeMenu']`).prop("selectedIndex", 0); - $(form).find(`input[name='dashesMenu']`).prop("selectedIndex", 0); - // shape specific processing - if( multi ){ - $(form).find(".regid").hide(); - $(form).find(".edit").hide(); - $(form).find(".childtext").hide(); - $(form).find(".multi").removeClass("nodisplay"); - if( opts.setmode <= 0 ){ - $(form).find(`[name='multitext']`).val(""); - $(form).find(`input[name="color"]`).val(""); - $(form).find(`input[name="strokeWidth"]`).val(""); - $(form).find(`input[name="strokeDashes"]`).val(""); - $(form).data("strokewidth", ""); - $(form).data("strokedashes", ""); - if( opts.setmode < 0 ){ - $(form).find(`[name='selectfilter']`).val(""); - $(form).data("selectfilter", ""); - } - } else { - ao = this.layers.regions.canvas.getActiveObject(); - if( ao && ao.type === "group" && !ao.params ){ - objs = ao.getObjects(); - if( objs && objs.length && objs[0] && objs[0].params ){ - grp = objs[0].params.groupid; - } - if( grp ){ - $(form).find(`[name='selectfilter']`).val(grp); - $(form).data('selectfilter', grp); - s = this.listGroups(grp); - s2 = s.substring(s.indexOf("\n")+1); - $(form).find(`[name='multitext']`).val(s2); - } else { - $(form).find(`[name='multitext']`).val(""); - } - } else if( ao ){ - ao = this.layers.regions.canvas.getActiveObjects(); - for(i=0, s=[], s2=""; i { - $(form).find(`input[name='savefile']`).focus(); - }); - } - // add tooltip callbacks (not mobile: ios buttons stop working!) - if( !$(form).data("tooltipInit") ){ - $(form).data("tooltipInit", true); - $(".rconfigcol_R, .rsavecol_R").on(mover, (e) => { - const target = e.currentTarget; - const tooltip = $(target) - .find("input, textarea, span") - .data("tooltip"); - const el = $(target) - .closest(JS9.lightOpts[JS9.LIGHTWIN].top) - .find(JS9.lightOpts[JS9.LIGHTWIN].dragBar); - if( tooltip && el.length ){ - // change title: see dhtmlwindow.js load() @line 130 - otitle = $(el)[0].childNodes[0].nodeValue.replace(/:.*/,""); - $(el)[0].childNodes[0].nodeValue = `${otitle}: ${tooltip}`; - } - }); - $(".rconfigcol_R, .rsavecol_R").on(mout, (e) => { - const target = e.currentTarget; - const el = $(target) - .closest(JS9.lightOpts[JS9.LIGHTWIN].top) - .find(JS9.lightOpts[JS9.LIGHTWIN].dragBar); - if( el.length ){ - otitle = $(el)[0].childNodes[0].nodeValue.replace(/:.*/,""); - $(el)[0].childNodes[0].nodeValue = otitle; - } - }); - } -}; - -// process the config form to change the specified shape -// call using image context -JS9.Regions.processConfigForm = function(form, obj, arr){ - let i, key, nkey, val, nval, nopts, multi, layer, wcssys; - let cpos, p1, p2, d, x, y, ang, sel; - let bin = 1; - const defobj = { - type: "multi", - pub: {shape: "multi"}, - params: {} - }; - const alen = arr.length; - const opts = {}; - const wcsinfo = this.raw.wcsinfo || {cdelt1: 1, cdelt2: 1}; - const fmt= (val) => { - if( val === undefined ){ - return undefined; - } - if( (typeof val === "number") && (val % 1 !== 0) ){ - val = Math.round((val + 0.00001) * 10000) / 10000; - } - return(String(val)); - }; - const fmtcheck = (val1, val2) => { - if( multi ){ - return true; - } - if( val1 === undefined ){ - return false; - } - return fmt(val1) !== fmt(val2); - }; - const newval = (obj, key, val) => { - // let v1, v2; - // special keys having no public or param equivalents - if( key === "remove" ){ - return val === "selected"; - } - if( key === "childtext" ){ - if( obj.params.children && obj.params.children.length > 0 ){ - if( obj.params.children[0].obj && - obj.params.children[0].obj.params ){ - return val !== obj.params.children[0].obj.params.text; - } - return false; - } - return val !== obj.params.text; - } - if( key === "strokeWidth" ){ - if( obj.params && obj.params.sw1 ){ - return val !== obj.params.sw1; - } else { - return true; - } - } - if( key === "strokeDashes" ){ - if( obj.strokeDashArray){ - return JSON.stringify(obj.strokeDashArray) !== - JSON.stringify(val); - } - if( $.isArray(val) ){ - switch(val.length){ - case 0: - return false; - case 1: - return val[0] !== ""; - case 2: - default: - return val[0] !== "" && val[1] !== ""; - } - } else { - return val !== ""; - } - } - if( key !== "tags" && val === "" ){ - return false; - } - if( key === "misc" && val !== "" ){ - return true; - } - if( key === "radii" && obj.params.radii ){ - // https://stackoverflow.com/questions/1773069/using-jquery-to-compare-two-arrays-of-javascript-objects - // v1 = val.split(",").map((item) => {return parseFloat(item)}); - // v2 = obj.params.radii; - // return $(v1).not(v2).length !== 0 || $(v2).not(v1).length !== 0; - // always return true or else annuli won't change other properties - return true; - } - if( key === "angle" ){ - return obj.angle !== -parseFloat(val); - } - if( key === "ix" ){ - if( obj.pub.preservedcoords && - val.charAt(0).toLowerCase() === "d" ){ - return fmtcheck(obj.pub.dx, JS9.saostrtod(val.substring(1))); - } else { - return fmtcheck(obj.pub.x, JS9.saostrtod(val)); - } - } - if( key === "iy" ){ - if( obj.pub.preservedcoords && - val.charAt(0).toLowerCase() === "d" ){ - return fmtcheck(obj.pub.dy, JS9.saostrtod(val.substring(1))); - } else { - return fmtcheck(obj.pub.y, JS9.saostrtod(val)); - } - } - if( key === "px" && obj.pub.lcs ){ - return fmtcheck(obj.pub.lcs.x.toFixed(1), val); - } - if( key === "py" && obj.pub.lcs ){ - return fmtcheck(obj.pub.lcs.y.toFixed(1), val); - } - if( key === "ra" ){ - if( obj.pub.wcsconfig && obj.pub.wcsconfig.wcsposstr ){ - return fmtcheck(JS9.saostrtod(obj.pub.wcsconfig.wcsposstr[0]), - JS9.saostrtod(val)); - } else if( obj.pub.wcsposstr ){ - return fmtcheck(JS9.saostrtod(obj.pub.wcsposstr[0]), - JS9.saostrtod(val)); - } - return false; - } - if( key === "dec" ){ - if( obj.pub.wcsconfig && obj.pub.wcsconfig.wcsposstr ){ - return fmtcheck(JS9.saostrtod(obj.pub.wcsconfig.wcsposstr[1]), - JS9.saostrtod(val)); - } else if( obj.pub.wcsposstr ){ - return fmtcheck(JS9.saostrtod(obj.pub.wcsposstr[1]), - JS9.saostrtod(val)); - } - } - if( key === "sticky" ){ - if( multi ){ - return false; - } else { - return fmtcheck(obj.pub.sticky||false, val); - } - } - if( key === "locked" ){ - if( multi ){ - return false; - } else { - if( obj.params.changeable !== false ){ - return val === false; - } else { - return val === true; - } - } - } - if( key === "listonchange" ){ - if( multi ){ - return false; - } - } - if( obj.pub.lcs && obj.pub.lcs[key] !== undefined ){ - if( fmtcheck(obj.pub.lcs[key], val) ){ - return true; - } - // don't look further or we end up checking image x, y - return false; - } - if( fmtcheck(obj.pub[key], val) ){ - return true; - } - if( fmtcheck(obj.params[key], val) ){ - return true; - } - if( fmtcheck(obj[key], val) ){ - return true; - } - return false; - }; - const getval = (s) => { - if( s === "true" ){ - return true; - } - if( s === "false" ){ - return false; - } - if( !JS9.isNumber(s) ){ - return s; - } - return parseFloat(s); - }; - const replaceNewline = (s) => { - const nl = String.fromCharCode(13, 10); - if( typeof s === "string" ){ - return s.replace(/\\n/g, nl); - } - return s; - }; - // set physical to image conversion, if possible - if( this.lcs && this.lcs.physical ){ - bin = Math.sqrt(Math.pow(this.lcs.physical.forward[0][0],2) + - Math.pow(this.lcs.physical.forward[0][1],2)); - } - // which wcssys do we use? edit version, if available - if( obj && obj.pub ){ - if( obj.pub.wcsconfig && obj.pub.wcsconfig.wcssys ){ - wcssys = obj.pub.wcsconfig.wcssys; - } else { - wcssys = this.params.wcssys; - } - } else { - wcssys = this.params.wcssys; - // fake obj: makes the checks easier, avoid if( obj ... ) everywhere - obj = defobj; - } - // multi selection or single region - multi = $(form).data("multi"); - // layer or regions - layer = obj.pub.layer || "regions"; - // process array of keyword/values - for(i=0; i parseInt(s, 10) ); - } - } - } - break; - case "strokeWidth": - if( val === "" ){ - opts[key] = ""; - } else { - if( JS9.isNumber(val) ){ - nval = parseInt(val, 10); - if( nval <= 0 ){ - opts[key] = ""; - } else if( (multi && val) || - (!multi && newval(obj, key, nval)) ){ - opts[key] = getval(nval); - } - } - } - break; - case "color": - if( val === "" ){ - opts[key] = ""; - } else if( newval(obj, key, val) ){ - opts[key] = getval(val); - } - break; - case "tags": - if( multi ){ - if( val ){ - if( val === '""' || val === "''" ){ - opts[key] = ""; - } else { - opts[key] = getval(val); - } - } - } else if( newval(obj, key, val) ){ - opts[key] = getval(val); - } - - break; - case "childtext": - if( obj.type !== "text" ){ - if( newval(obj, key, val) ){ - opts.text = replaceNewline(val); - } - } - break; - case "ix": - if( newval(obj, key, val) ){ - if( obj.pub.preservedcoords && - val.charAt(0).toLowerCase() === "d" ){ - opts.dx = getval(val.substring(1)); - if( opts.dy === undefined && obj.pub.dy !== undefined ){ - opts.dy = obj.pub.dy; - } - } else { - opts.x = getval(val); - if( opts.y === undefined && obj.pub.y !== undefined ){ - opts.y = obj.pub.y; - } - } - } - break; - case "iy": - if( newval(obj, key, val) ){ - if( obj.pub.preservedcoords && - val.charAt(0).toLowerCase() === "d" ){ - opts.dy = getval(val.substring(1)); - if( opts.dx === undefined && obj.pub.dx !== undefined ){ - opts.dx = obj.pub.dx; - } - } else { - opts.y = getval(val); - if( opts.x === undefined && obj.pub.x !== undefined ){ - opts.x = obj.pub.x; - } - } - } - break; - case "px": - if( newval(obj, key, val) ){ - opts.px = getval(val); - if( opts.py === undefined && obj.pub.lcs ){ - opts.py = obj.pub.lcs.y; - } - } - break; - case "py": - if( newval(obj, key, val) ){ - opts.py = getval(val); - if( opts.px === undefined && obj.pub.lcs ){ - opts.px = obj.pub.lcs.x; - } - } - break; - case "ra": - if( newval(obj, key, val) ){ - opts.ra = val; - if( opts.dec === undefined ){ - if( obj.pub.wcsconfig && obj.pub.wcsconfig.wcsposstr ){ - opts.dec = obj.pub.wcsconfig.wcsposstr[1]; - } else if( obj.pub.wcsposstr ){ - opts.dec = obj.pub.wcsposstr[1]; - } - } - } - break; - case "dec": - if( newval(obj, key, val) ){ - opts.dec = val; - if( opts.ra === undefined ){ - if( obj.pub.wcsconfig && obj.pub.wcsconfig.wcsposstr ){ - opts.ra = obj.pub.wcsconfig.wcsposstr[0]; - } else if( obj.pub.wcsposstr ){ - opts.ra = obj.pub.wcsposstr[0]; - } - } - if( opts.wcssys === undefined ){ - opts.wcssys = wcssys; - } - } - break; - case "wcssys": - break; - case "radius": - case "length": - case "width": - case "r1": - switch(wcssys){ - case "image": - if( newval(obj, key, val) ){ - opts[key] = getval(val); - } - break; - case "physical": - if( newval(obj, key, val) ){ - opts[key] = getval(val) * bin; - } - break; - default: - nval = JS9.strtoscaled(val); - val = Math.abs(nval.dval / wcsinfo.cdelt1); - nkey = key.replace("wcs", ""); - if( newval(obj, nkey, val) ){ - opts[nkey] = getval(val); - } - break; - } - break; - case "height": - case "r2": - switch(wcssys){ - case "image": - if( newval(obj, key, val) ){ - opts[key] = getval(val); - } - break; - case "physical": - if( newval(obj, key, val) ){ - opts[key] = getval(val) * bin; - } - break; - default: - nval = JS9.strtoscaled(val); - val = Math.abs(nval.dval / wcsinfo.cdelt2); - nkey = key.replace("wcs", ""); - if( newval(obj, nkey, val) ){ - opts[nkey] = getval(val); - } - break; - } - break; - case "radii": - if( newval(obj, key, val) ){ - opts[key] = val; - } - break; - case "linelength": - if( obj.pub.pts && obj.pub.pts.length === 2 ){ - if( JS9.isNumber(val) && val !== this.tmp.linelength ){ - val = parseFloat(val); - switch(wcssys){ - case "image": - case "physical": - break; - default: - if( wcsinfo.cdelt1 !== undefined ){ - val /= Math.abs(wcsinfo.cdelt1); - } else if( wcsinfo.cdelt2 !== undefined ){ - val /= Math.abs(wcsinfo.cdelt2); - } - break; - } - if( opts.pts ){ - p1 = opts.pts[0]; - p2 = opts.pts[1]; - } else { - p1 = obj.pub.pts[0]; - p2 = obj.pub.pts[1]; - } - if( $.inArray("line", - JS9.Regions.opts.noCenteredScaling) >= 0 ){ - // leave p1 fixed - // https://math.stackexchange.com/questions/175896/finding-a-point-along-a-line-a-certain-distance-away-from-another-point - d = Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + - (p1.y - p2.y) * (p1.y - p2.y) ); - x = p1.x - (val * (p1.x - p2.x))/d; - y = p1.y - (val * (p1.y - p2.y))/d; - opts.pts = [p1, {x, y}]; - } else { - // leave center fixed - cpos = {x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2 }; - ang = parseFloat(this.tmp.lineangle)||0; - p1.x = cpos.x - val/2; - p1.y = cpos.y; - p2.x = cpos.x + val/2; - p2.y = cpos.y; - opts.pts = [JS9.rotatePoint(p1, ang, cpos), - JS9.rotatePoint(p2, ang, cpos)]; - } - } - } - break; - case "lineangle": - if( obj.pub.pts && obj.pub.pts.length === 2 ){ - if( JS9.isNumber(val) && val !== this.tmp.lineangle ){ - ang = parseFloat(val) - parseFloat(this.tmp.lineangle)||0; - if( opts.pts ){ - p1 = opts.pts[0]; - p2 = opts.pts[1]; - } else { - p1 = obj.pub.pts[0]; - p2 = obj.pub.pts[1]; - } - if( $.inArray("line", - JS9.Regions.opts.noCenteredScaling) >= 0 ){ - // leave p1 fixed - opts.pts = [p1, JS9.rotatePoint(p2, ang, p1)]; - } else { - // leave center fixed - cpos = {x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2 }; - opts.pts = [JS9.rotatePoint(p1, ang, cpos), - JS9.rotatePoint(p2, ang, cpos)]; - } - } - } - break; - case "remove": - if( newval(obj, key, val) ){ - if( multi ){ - opts[key] = "selected"; - } else if( obj.pub.id !== undefined ){ - opts[key] = obj.pub.id; - } - } - break; - case "locked": - if( newval(obj, key, !getval(val)) ){ - opts.changeable = !getval(val); - } - break; - case "misc": - if( val.trim() ){ - try{ nopts = JSON.parse(val); $.extend(opts, nopts); } - catch(e){ JS9.error(`invalid json: ${val}`);} - } - break; - default: - if( newval(obj, key, val) ){ - opts[key] = getval(val); - } - break; - } - } - // change the shape(s), if necessary - if( Object.keys(opts).length > 0 ){ - if( multi ){ - sel = $(form).find(`[name='selectfilter']`).val() || "selected"; - this.changeShapes(layer, sel, opts); - } else { - sel = $(form).find(`[name='id']`).val() || obj; - this.changeShapes(layer, sel, opts); - } - this.initRegionsForm(obj, {multi}); - } -}; - -// convenience routine used in regionsConfig.html -JS9.Regions.regionsConfigSetSelectFilter = function(el, def) { - let i, s, curval, lastval, nval, nfilter; - let arr = []; - let defarr = []; - let grparr = []; - const form = el.closest('form'); - const filter = form.find(`[name='selectfilter']`); - const im = form.data('im'); - const withparens = (s) => { - let t; - if( !s ){ return ""; } - t = s.trim(); - if( t.charAt(0) === "(" && t.charAt(t.length-1) === ")" ){ - return t; - } else { - return `(${t})`; - } - }; - // sanity check - if( !im ){ return; } - // groups - grparr = im.listGroups("all", {includeregions:false}).split("\n"); - // new value from menu - nval = el.val().trim(); - // cur value from filter select - curval = filter.val().trim(); - // handle "saved" specially - if( def === "other" && nval === "saved" ){ - // compose and set the new filter selection - s = im.layers.regions.selection || ""; - if( s ){ - if( curval ){ - s = `${withparens(s)} && ${withparens(curval)}`; - } - } - filter.val(`${s}`); - // reset the menu - el.prop('selectedIndex', 0); - return; - } - if( curval ){ - arr = curval.split(/\s+/); - } - if( arr.length ){ - lastval = arr[arr.length-1]; - if( !nval.match(/[&|]/) && !lastval.match(/[&|!]/) ){ - // get array of possible values - switch(def){ - case "regions": - defarr = JS9.regions; - break; - case "colors": - break; - case "tags": - break; - case "wcssys": - defarr = JS9.wcssyss; - break; - case "groups": - defarr = grparr; - break; - case "ops": - defarr = ["!", "&&", "||"]; - break; - } - if( $.inArray(lastval, defarr) >= 0 ){ - // if new and last val is of the same type, use || for union - // (intersection of same types, but non-identical, is null) - nval = `|| ${nval}`; - } else if( $.inArray(lastval, grparr) >= 0 || - $.inArray(nval, grparr) >= 0 ){ - // if either is a group, use || for union - // (intersection of non-identical groups is null) - nval = `|| ${nval}`; - } else { - // use && for intersection, e.g., color && shape - nval = `&& ${nval}`; - } - } - } - // this is the new filter - nfilter = `${curval} ${nval}`; - // futz w/parens: split by ||, add parens around segments containing && - // if you used the menus to choose these: - // circle blue || box red - // then instead of this: - // circle && blue || box && red - // we should end up with this: - // (circle && blue) || (box && red) - if( JS9.globalOpts.regConfigAddParens ){ - arr = nfilter.split("||"); - if( arr.length >= 2 ){ - for(i=0; i 0 ){ - arr[i] = withparens(s); - } else { - arr[i] = s; - } - } - } - nfilter = arr.join(' || ').replace(/ */g, " "); - } - // compose and set the new filter selection - filter.val(nfilter); - // reset the menu - el.prop('selectedIndex', 0); -}; - -// convenience routine used in regionsConfig.html -JS9.Regions.regionsConfigSetSelectMenu = function(im, form, key) { - let i, j, s, el, objs, gots, arr; - const initmenu = (el) => { - let i; - // remove all but the header (0th option) - for(i=el.options.length-1; i>=1; i--) { - el.remove(i); - } - }; - if( !key.match(/^select/) ){ - key = `select${key}`; - } - el = form.find(`[name='${key}']`); - // reinit: clear menu - initmenu(el[0]); - // current objects - objs = im.getShapes("regions", "all"); - // add items - switch(key){ - case "selectshape": - for(i=0, gots=[]; i${s}`); - gots.push(s); - } - } - break; - case "selectcolor": - for(i=0, gots=[]; i${s}`); - gots.push(s); - } - } - break; - case "selecttag": - for(i=0, gots=[]; i${s[j]}`); - gots.push(s[j]); - } - } - } - break; - case "selectwcs": - for(i=0, gots=[]; i${s}`); - gots.push(s); - } - } - } - break; - case "selectgroup": - s = im.listGroups("all", {includeregions:false}); - if( s ){ - arr = s.split("\n"); - for(i=0; i${arr[i]}`); - } - } - break; - } -}; - -// convenience routine used in regionsConfig.html -JS9.Regions.regionsConfigSetSelectOrGroup = function(im, form, key, update){ - let obj, group, canvas; - let el1 = form.find(`[name="selectfilter"]`); - let el2 = form.find(`[name="multitext"]`); - let selection = el1.val().trim(); - // sanity check - if( !im ){ return; } - // convenience variables - canvas = im.layers.regions.canvas; - // default is to allow update of multi-selection dialog - // sometimes we definitely don't want that to happen, so ... - if( update === false ){ im.tmp.updateMulti = false; } - // default is to select - if( !selection ){ - el1.val(""); - el2.val(""); - form.data("selectfilter", ""); - if( canvas.getActiveObject() ){ - canvas.discardActiveObject(); - } - canvas.renderAll() - key = "clear"; - } - if( !key ){ - key = im.lookupGroup(selection) ? "group" : "select"; - } - switch(key){ - case "select": - form.data("selectfilter", selection); - im.selectShapes("regions", selection, {transparentgroup: false}); - break; - case "group": - form.data("selectfilter", selection); - group = im.groupShapes("regions", selection); - el1.val(group); - el2.val(im.listGroups(group)) - obj = im.lookupGroup(group); - if( obj ){ - canvas.setActiveObject(obj); - canvas.renderAll(); - JS9.Regions.regionsConfigSetSelectMenu(im, form, "selectgroup"); - } - break; - case "ungroup": - im.ungroupShapes("regions", selection); - el1.val(""); - el2.val(""); - form.data("selectfilter", ""); - if( canvas.getActiveObject() ){ - canvas.discardActiveObject(); - } - JS9.Regions.regionsConfigSetSelectMenu(im, form, "selectgroup"); - break; - case "clear": - form.find(`input[name="color"]`).val(""); - form.find(`input[name="strokeWidth"]`).val(""); - form.find(`input[name="strokeDashes"]`).val(""); - form.data("strokewidth", ""); - form.data("strokedashes", ""); - break; - default: - break; - } - delete im.tmp.updateMulti; -}; - -// paste a region from clipboard -// call using image context -JS9.Regions.pasteFromClipboard = function(curpos){ - let i, s, nobj, xpos, ypos, oval; - let objs = []; - let xcen = 0, ycen = 0; - const rregexp = /(annulus|box|circle|cross|ellipse|line|polygon|point|text) *\(/; - // sanity check - if( !this ){ return; } - // get string from clipboard - s = JS9.CopyFromClipboard().trim(); - // see if we have anything at all - if( !s ){ - JS9.error(JS9.CLIPBOARDERROR); - } - // see if we have region(s) - if( s.match(rregexp) ){ - // we don't update the clipboard for these operations - oval = JS9.globalOpts.regToClipboard; - JS9.globalOpts.regToClipboard = false; - // add regions (don't update clipboard) - objs = this.addShapes("regions", s, {rtn: "objs"}); - // place regions in the position specified by the mouse, if necessary - if( curpos ){ - // number of regions - nobj = objs.length; - // get centroid - for(i=0; i { - let i, s, key, child, ra, dec; - const nexports = {}; - const params = obj.params; - const children = params.children; - const exports = params.exports; - for(i=0; i 0) && (children[0].obj.text) ){ - child = children[0].obj; - // create a text child - nexports.text = child.text; - // get options for text child but ... - nexports.textOpts = getExports(child); - // try to minimize exported properties - if( obj.angle !== child.angle ){ - // child has an explicit angle different from parent - nexports.textOpts.angle = -child.angle; - if( (obj.params.shape === "circle") || - (obj.params.shape === "annulus") ){ - child.params.hasTextOpts = true; - } - } else if( child.angle !== 0 ){ - // parent is circle/annulus and child has an angle - if( (obj.params.shape === "circle") || - (obj.params.shape === "annulus") ){ - nexports.textOpts.angle = -child.angle; - child.params.hasTextOpts = true; - } - } - if( child.params.parent.moved || child.params.hasTextOpts ){ - // wcs, then physical coords are preferred ... - if( child.pub.ra && child.pub.dec ){ - // convert child ra, dec to target wcs, if necessary - if( owcssys && wcssys && owcssys !== wcssys ){ - s = this.wcs2wcs(owcssys, wcssys, - child.pub.ra, child.pub.dec); - s = s.trim().split(/\s+/); - ra = JS9.saostrtod(s[0]); - if( JS9.isHMS(wcssys) ){ - ra *= 15.0; - } - dec = JS9.saostrtod(s[1]); - } else { - ra = child.pub.ra; - dec = child.pub.dec; - } - nexports.textOpts.ra = ra; - nexports.textOpts.dec = dec; - } else if( child.pub.lcs ){ - nexports.textOpts.px = child.pub.lcs.x; - nexports.textOpts.py = child.pub.lcs.y; - } else { - // ... image coords will are only good for this image - nexports.textOpts.x = child.pub.x; - nexports.textOpts.y = child.pub.y; - } - } - if( nexports.textOpts.color === obj.stroke ){ - delete nexports.textOpts.color; - } - if( nexports.textOpts.text ){ - delete nexports.textOpts.text; - } - if( !Object.keys(nexports.textOpts).length ){ - delete nexports.textOpts; - } - } - return nexports; - }; - // opts is optional - opts = opts || {}; - // opts can be an object or json - if( typeof opts === "string" ){ - try{ opts = JSON.parse(opts); } - catch(e){ JS9.error(`can't parse listRegions opts: ${opts}`, e); } - } - // pass sortids from opts to topts (used by getShapes) - if( JS9.notNull(opts.sortids) ) topts.sortids = opts.sortids; - // default is to display, including non-source tags - mode = opts.mode; - if( JS9.isNull(mode) ){ - mode = 3; - } - // default is to list the regions layer - layerName = layerName || "regions"; - layer = this.getShapeLayer(layerName); - // sanity check - if( !layer ){ return; } - // set user-specified wcs, if necessary - if( opts.wcssys || opts.wcsunits ){ - txeq = JS9.globalOpts.xeqPlugins; - JS9.globalOpts.xeqPlugins = false; - if( opts.wcssys ){ - owcssys = this.getWCSSys(); - this.setWCSSys(opts.wcssys, false); - wcssys = this.getWCSSys(); - } - if( opts.wcsunits ){ - owcsunits = this.getWCSUnits(); - this.setWCSUnits(opts.wcsunits, false); - } - // update wcs values - this.updateShapes(layerName, which, "export"); - } - // include dcoord shapes? - if( JS9.isNull(opts.includedcoords) ){ - opts.includedcoords = JS9.globalOpts.regListDCoords; - } - // get specified regions into an array - pubs = this.getShapes(layerName, which, topts); - // loop through shapes - rlen = pubs.length; - // display tags if at least one is not standard "source,include" - if( mode ){ - for(i=0; i 0 ){ regstr += ","; } - regstr += `"${key}":`; - switch(typeof val){ - case "string": - regstr += `"${val}"`; - break; - case "object": - try{ regstr += JSON.stringify(val); } - catch(e){ JS9.error(`can't parse: ${val}`, e); } - break; - default: - regstr += `${val}`; - break; - } - } - } - regstr += `})`; - lasttype = "image"; - continue; - } - // init tags - tagjoin = region.tags.join(","); - if( tagjoin.includes("exclude") ){ - iestr = "-"; - } else { - iestr = ""; - } - // add exported properties - exports = getExports(obj, region); - // add id, if necessary - if( opts.saveid ){ - exports.id = region.id; - } else { - delete exports.id; - } - // save wcsconfig, if necessary - if( opts.savewcsconfig && region.wcsconfig && - Object.keys(region.wcsconfig).length > 0 ){ - exports.wcsconfig = $.extend(true, {}, region.wcsconfig); - } else { - delete exports.wcsconfig; - } - // add color, if necessary - if( region.color && !tagcolors.includes(region.color) ){ - exports.color = region.color; - } - // display tags? - if( dotags ){ - tagstr = ` # ${tagjoin}`; - } - // save editing? - if( !opts.saveediting ){ - delete exports.editing; - } - // use wcs string, if available - if( region.wcsstr && JS9.isWCSSys(this.params.wcssys) ){ - if( lasttype !== "wcs" ){ - if( lasttype !== "none" ){ - regstr += sepstr; - } - // use region wcs sys, if possible - // (current wcssys might be different!) - if( region.wcssys ){ - regstr += region.wcssys; - } else { - regstr += this.params.wcssys; - } - lasttype = "wcs"; - } - regstr += (sepstr + iestr + region.wcsstr); - } else if( region.imstr ){ - // else use image string, if available - if( lasttype !== region.imsys ){ - if( lasttype !== "none" ){ - regstr += sepstr; - } - regstr += region.imsys; - lasttype = region.imsys; - } - regstr += (sepstr + iestr + region.imstr); - } - // odd modes output the exports - if( opts.includejson !== false && - ((mode % 2) === 1) && - (Object.keys(exports).length > 0) ){ - // line region: remove size/distance info - if( region.shape === "line" ){ - regstr = regstr.replace(/ *{[^{}]*}$/,""); - } - regstr += ` ${JSON.stringify(exports)}`; - } - if( tagstr ){ - regstr += tagstr; - } - } - // remove comments, if necessary - if( opts.includecomments === false ){ - regstr = regstr.replace(/ *#[^;]*/g, ""); - } - // restore original wcs, if necessary - if( owcssys || owcsunits ){ - if( owcssys ){ - this.setWCSSys(owcssys, false); - } - if( owcsunits ){ - this.setWCSUnits(owcsunits, false); - } - // restore wcs values - this.updateShapes(layerName, which, "export"); - JS9.globalOpts.xeqPlugins = txeq; - } - // display the region string, if necessary - if( mode > 1 ){ - this.display.displayMessage("regions", regstr); - } - // always return the region string - return regstr; -}; - -// copy one or more regions to another image -// call using image context -JS9.Regions.copyRegions = function(to, which){ - return this.copyShapes("regions", to, which); -}; - -// parse a string containing a subset of DS9/Funtools regions -// call using image context -JS9.Regions.parseRegions = function(s, opts){ - let i, j, k, lines, obj, robj, txeq; - let owcssys, owcsunits, wcssys, iswcs, liswcs, pos, alen; - const regions = []; - const regrexp = /^-?(annulus|box|circle|cross|ellipse|line|polygon|point|text)$/; - const wcsrexp = /^(fk4|fk5|icrs|galactic|ecliptic|image|physical|linear)$/; - const imrexp = /^(image|physical)$/; - const unrexp = /[dr:]/; - const parrexp = /\(\s*([^)]+?)\s*\)/; - const seprexp = /\n|;/; - const optsrexp = /(\{.*\})/; - const argsrexp = /\s*,\s*/; - const charrexp = /(\(|\{|#|;|\n)/; - const comrexp = /#(?![a-zA-Z0-9]{6}['"])/; - // convert "0" to false and "1" to true - const tf = (s) => { - if( s === "0" || s.toLowerCase() === "false" ){return false;} - return true; - }; - // ds9 compatibility: get properties from comment string - const ds9properties = (s) => { - let xarr, key, key2, val, nobj; - const xobj = {}; - const rexp = /([a-zA-Z][a-zA-Z0-9_]*)\s*=\s*(\d+(\s*\d+)*|[^ '"{]+|['"{][^'"}]*['"}])/g; - const ds9opts = { - color(v) {return {color: v};}, - dash(v) {if(v){return {strokeDashArray: [3,1]};}}, - dashlist(v) { - let i, arr; - if( v ){ - arr = v.split(" "); - for(i=0; i= 1 ){ obj.fontFamily = arr[0]; } - if( len >= 2 ){ obj.fontSize = parseFloat(arr[1]); } - if( len >= 3 ){ obj.fontStyle = arr[2]; } - if( len >= 4 ){ obj.fontWeight = arr[3]; } - return obj; - }, - highlite(v) {return {hasControls: tf(v), hasBorders: tf(v), hasRotatingPoint: tf(v)};}, - move(v) {return {movable: tf(v)};}, - rotate(v) {return {rotatable: tf(v)};}, - resize(v) {return {resizable: tf(v)};}, - changeable(v) {return {changeable: tf(v)};}, - select(v) {return {selectable: tf(v)};}, - text(v) {return {text: v};}, - tag(v) {return {tags: v};}, - width(v) {return {strokeWidth: parseFloat(v)};} - }; - // opts is optional - opts = opts || {}; - // loop through DS9 region properties, converting to js9 props - while( (xarr = rexp.exec(s)) !== null ){ - key = xarr[1].toLowerCase(); - val = xarr[2].replace(/^['"{]|['"}]$/g, ""); - if( {}.hasOwnProperty.call(ds9opts, key) && - typeof ds9opts[key] === "function" ){ - nobj = ds9opts[key](val) || {}; - for( key2 of Object.keys(nobj) ){ - if( key2 === "tags" && {}.hasOwnProperty.call(xobj, key2) ){ - xobj[key2] += `,${nobj[key2]}`; - } else { - xobj[key2] = nobj[key2]; - } - } - } else { - xobj[key] = val; - } - } - // save the remaining comment - s = s.replace(rexp, ""); - if( s ){ - xobj._comment = s.trim(); - } - return xobj; - }; - // parse region line into cmd (shape or wcs), args, opts, comment - const regparse1 = (s) => { - let t, tarr, ds9props; - const tobj = {}; - // initialize the return object - tobj.opts = {}; - tobj.args = []; - tobj.isregion = 0; - // look for a command - if( s.includes("(") ){ - tobj.cmd = s.split("(")[0].trim().toLowerCase(); - } else if( s.includes("{") ){ - tobj.cmd = s.split("{")[0].trim().toLowerCase(); - } else if( s.includes("#") ){ - tobj.cmd = s.split("#")[0].trim().toLowerCase(); - } else { - tobj.cmd = s.trim().toLowerCase(); - } - // got regions? - if( tobj.cmd ){ - tobj.isregion = (tobj.cmd.search(regrexp) >=0); - } - // split on comment (ignore color specifications starting with "#") - t = s.trim().split(comrexp); - // look for json opts after the arg list - tarr = optsrexp.exec(t[0]); - if( tarr && tarr[0] ){ - // convert to object - try{ tobj.opts = JSON.parse(tarr[0].trim()); } - catch(e){ JS9.error(`can't parse opts: ${tarr[0]}`, e); } - } - // look for comments - tobj.comment = t[1]; - if( tobj.comment ){ - ds9props = ds9properties(tobj.comment.trim()); - if( ds9props._comment !== undefined ){ - tobj.comment = ds9props._comment; - delete ds9props._comment; - } - } - // merge with ds9 opts - if( ds9props ){ - tobj.opts = $.extend({}, ds9props, tobj.opts); - } - // separate the region args into an array - tarr = parrexp.exec(s); - if( tarr && tarr[0].match(optsrexp) ){ - // no region args, all properties passed in json - tobj.args = []; - } else if( tarr && tarr[1] ){ - // region args, without json opts - tobj.args = tarr[1].split(argsrexp); - } - // look for - sign signifying an exclude region - if( tobj.isregion && tobj.cmd.startsWith("-") ){ - tobj.cmd = tobj.cmd.slice(1); - if( tobj.comment ){ - if( !tobj.comment.match(/exclude/) ){ - tobj.comment += ",exclude"; - } - } else { - tobj.comment = "exclude"; - } - } - return tobj; - }; - const getipos = (ix, iy) => { - let vt, sarr, v1, v2; - let obj = {}; - // special handling for display coords - if( ix.charAt(0).toLowerCase() === "d" && - iy.charAt(0).toLowerCase() === "d" ){ - obj.dx = parseFloat(ix.substring(1)); - obj.dy = parseFloat(iy.substring(1)); - return obj; - } - // convert strings to numbers, along with unit delimiters - v1 = JS9.strtoscaled(ix); - v2 = JS9.strtoscaled(iy); - // local override of wcs if: - // a. we used sexagesimal units or appended d,r - // b. we are not currently using wcs - if( ((v1.dtype.match(unrexp)) || (v2.dtype.match(unrexp))) && - !iswcs && !owcssys.match(imrexp) ){ - liswcs = true; - wcssys = owcssys; - } - if( iswcs || liswcs ){ - // arg1 coords are hms, but ecliptic, galactic are deg - if( JS9.isHMS(wcssys, v1.dtype) ){ - v1.dval *= 15.0; - } - // convert to degrees, if necessary - if( v1.dtype === "r" ){ v1.dval = v1.dval * 180 / Math.PI; } - if( v2.dtype === "r" ){ v2.dval = v2.dval * 180 / Math.PI; } - // get image coordinates - sarr = JS9.wcs2pix(this.raw.wcs, v1.dval, v2.dval).split(/ +/); - obj.x = parseFloat(sarr[0]); - obj.y = parseFloat(sarr[1]); - return obj; - } else if( wcssys === "physical" ){ - vt = this.logicalToImagePos({x: v1.dval, y: v2.dval}); - obj.x = vt.x; - obj.y = vt.y; - return obj; - } - // image coords - obj.x = v1.dval; - obj.y = v2.dval; - return obj; - }; - // get image length - const getilen = (len, which) => { - let cstr, iscale; - const v = JS9.strtoscaled(len); - const wcsinfo = this.raw.wcsinfo || {cdelt1: 1, cdelt2: 1}; - // local override of wcs if: - // a. we are not currently using wcs - // b. we used sexagesimal units or appended d,r - if( v.dtype.match(unrexp) && !iswcs && !owcssys.match(imrexp) ){ - liswcs = true; - wcssys = owcssys; - } - if( iswcs || liswcs ){ - // convert to degrees, if necessary - if( v.dtype === "r" ){ v.dval = v.dval * 180 / Math.PI; } - // angular separation is not implemented - // region wcs size is always based on cdelt - if( JS9.REGSIZE !== 0 ){ - JS9.error("region size based on ang sep is not implemented"); - } - // wcs-based size - cstr = `cdelt${which}`; - v.dval = Math.abs(v.dval / wcsinfo[cstr]); - } else if( wcssys === "physical" ){ - // use the LTM1_1 value stored for logical to image transforms - if( this.lcs && this.lcs.physical ){ - iscale = Math.sqrt(Math.pow(this.lcs.physical.forward[0][0],2)+ - Math.pow(this.lcs.physical.forward[0][1],2)); - v.dval = Math.abs(v.dval * iscale); - } - } - return v.dval; - }; - // get image angle - const getang = (a) => { - const v = JS9.strtoscaled(a); - return v.dval; - }; - // get cleaned-up string - const getstr = (s) => { - const t = s.replace(/^['"]/, "").replace(/["']$/, ""); - return t; - }; - // sanity check - s = s.trim(); - if( !s.match(charrexp) ){ - return s; - } - // save original wcs - owcssys = this.getWCSSys(); - owcsunits = this.getWCSUnits(); - // this is the default wcs for regions - wcssys = "physical"; - // do we have a real wcs? - iswcs = JS9.isWCSSys(wcssys); - // get individual "lines" (new-line or semi-colon separated) - lines = s.split(seprexp); - // for each region or cmd - for(i=0; i= 2 && - obj.shape !== "line" && - obj.shape !== "polygon" ){ - // get image position - $.extend(obj, getipos(robj.args[0], robj.args[1])); - } - // if textOpts has ra, dec, save the wcssys, it may be - // different by the time textOpts gets processed - if( obj.textOpts && - obj.textOpts.ra !== undefined && - obj.textOpts.dec !== undefined ){ - obj.textOpts._wcssys = wcssys; - } - // region args are optional - switch(robj.cmd){ - case "annulus": - if( alen > 0 ){ - obj.radii = []; - for(j=2; j= 3 ){ - obj.width = getilen(robj.args[2], 1); - } - if( alen >= 4 ){ - obj.height = getilen(robj.args[3], 2); - } - if( alen >= 5 ){ - obj.angle = getang(robj.args[4]); - } - break; - case "circle": - if( alen >= 3 ){ - obj.radius = getilen(robj.args[2], 1); - } - break; - case "ellipse": - if( alen >= 3 ){ - obj.r1 = getilen(robj.args[2], 1); - } - if( alen >= 4 ){ - obj.r2 = getilen(robj.args[3], 2); - } - if( alen >= 5 ){ - obj.angle = getang(robj.args[4]); - } - break; - case "line": - case "polygon": - if( alen > 0 ){ - obj.pts = []; - for(j=0, k=0; j= 3 ){ - obj.text = getstr(robj.args[2]); - } - if( alen >= 4 ){ - obj.angle = getang(robj.args[3]); - } - break; - default: - break; - } - // comment contains the tags - if( robj.comment ){ - obj.tags = robj.comment; - } - // save this region - regions.push(obj); - } else { - // if its a wcs command - if( robj.cmd.match(wcsrexp) ){ - // reset the wcs system - txeq = JS9.globalOpts.xeqPlugins; - JS9.globalOpts.xeqPlugins = false; - this.setWCSSys(robj.cmd, false); - JS9.globalOpts.xeqPlugins = txeq; - // get new wcssys - wcssys = this.getWCSSys(); - // is this a real wcs? - iswcs = JS9.isWCSSys(wcssys); - } else if( robj.cmd === "remove" || robj.cmd === "delete" ){ - regions.push({remove: true}); - } - } - } - } - // restore original wcs - txeq = JS9.globalOpts.xeqPlugins; - JS9.globalOpts.xeqPlugins = false; - this.setWCSSys(owcssys, false); - this.setWCSUnits(owcsunits); - JS9.globalOpts.xeqPlugins = txeq; - // return the generated object - return regions; -}; - -// save regions to a file -JS9.Regions.saveRegions = function(fname, which, layer){ - let i, s, t, header, regstr, format, blob, opts, arr, rid; - // see if default type is implicit in the output file - if( fname ){ - arr = fname.match(/\.([^.]*)$/); - if( arr && arr[1] && arr[1].match(/^(reg|svg|csv)$/) ){ - format = arr[1]; - } - } - // layer can be a layer name or an object describing layer, output type - if( typeof layer === "object" ){ - opts = layer; - layer = null; - } else if( layer && typeof layer === "string" ){ - try{ opts = JSON.parse(layer); } - catch(e){ opts = null; } - if( opts ){ layer = null; } - } - // see if parameters are in the opts object - if( opts ){ - // layer name - if( JS9.notNull(opts.layer) ){ - layer = opts.layer; - } - // old style 'type' property is now ... - if( JS9.notNull(opts.type) ){ - format = opts.type ; - } - // ... format - if( JS9.notNull(opts.format) ){ - format = opts.format ; - } - } - // make sure we have an opts - opts = opts || {}; - // last chance ... use defaults - layer = layer || "regions"; - format = format || "reg"; - // and make a sanity check - if( !this.layers[layer] ){ - JS9.error(`can't find layer for saveRegions: ${layer}`); - } - // construct final output file name, if necessary - if( !fname ){ - if( layer !== "regions" ){ - fname = `js9_${layer}.${format}`; - } else { - fname = `js9.${format}`; - } - } - // generate the specified output - switch(format){ - case "svg": - // convert layer to svg - try{ - // add border box, if necessary - if( JS9.globalOpts.svgBorder ){ - rid = this.addShapes(layer, "box", - {left: this.rgb.img.width/2, - top: this.rgb.img.height/2, - width: this.rgb.img.width, - height: this.rgb.img.height, - color: "black", - strokeWidth: 1, - tags: "SVGBorder" - }); - } - // convert canvas to SVG - s = this.layers[layer].dlayer.canvas.toSVG(); - // remove border box, if necessary - if( JS9.globalOpts.svgBorder ){ - this.removeShapes(layer, rid); - } - } - catch(e){ JS9.error(`can't convert layer to SVG: ${layer}`);} - break; - case "csv": - // convert layer to region string - try{ - opts.mode = 1; - opts.file = fname; - // when saving csv, we might want to include the wcs info - if( JS9.isNull(opts.includewcs) ){ - opts.includewcs = JS9.globalOpts.csvIncludeWCS; - } - // when saving reg, we might want to exclude the dcoord shapes - if( JS9.isNull(opts.savedcoords) ){ - opts.includedcoords = JS9.globalOpts.regSaveDCoords; - } - // list of regions - regstr = this.listRegions(which, opts, layer); - // convert to csv - arr = regstr.split(";"); - for(i=0, s=""; ii.trim()); - } - if( !$.isArray(remtags) ){ - remtags = remtags.split(",").map(i=>i.trim()); - } - s = this.getShapes("regions", which); - // for each shape ... - for(i=0; i background, include <-> exclude -// e.g. im.toggleRegionTags("selected", "source", "background"); -// call using image context -JS9.Regions.toggleRegionTags = function(which, x1, x2){ - let i, j, s, tags, xnew; - which = which || "all"; - s = this.getShapes("regions", which); - for(i=0; i { - let i, x, y; - if( !ann.text ){ - return null; - } - x = ann.x || 0; - if( ann.y.toUpperCase() === "%Y" ){ - for(i=1; i x ){ - y = Math.max(data[i-1][1], data[i][1], data[i+1][1]); - break; - } - } - } else { - y = ann.y; - } - return {x, y}; - }; - switch( JS9.globalOpts.plotLibrary ){ - case "flot": - yTextOffset = -25; - divjq.find(".plotAnnotation").remove(); - for(i=0; i divjq.width()) ){ - continue; - } - ahtml = sprintf("
    %s
    ", - ao.left, ao.top+yTextOffset, - ac, `↓${ann.text}`); - divjq.append(ahtml); - } - break; - case "plotly": - yTextOffset = -30; - for(i=0; i { - if( val === undefined ){ - return undefined; - } - if( (typeof val === "number") && (val % 1 !== 0) ){ - val = Math.round((val + 0.001) * 100) / 100; - } - return(String(val)); - }; - // sanity check - if( !plot || !pobj ){ return; } - // convenience variables - winid = plot.winid; - wid = $(winid).attr("id"); - form = `#${wid} #plotConfigForm `; - // flot support only for now ... - if( JS9.globalOpts.plotLibrary !== "flot" ){ return; } - // fill in the values from the plot - $(`${form}.val`).each((index, element) => { - val = ""; - key = $(element).attr("name"); - // key-specific pre-processing - switch(key){ - case "xscale": - if( JS9.notNull(pobj.curscale.x) ){ - val = fmt(pobj.curscale.x); - } - break; - case "xmin": - if( JS9.notNull(plot.getAxes().xaxis.options.min) ){ - val = fmt(plot.getAxes().xaxis.options.min); - } - break; - case "xmax": - if( JS9.notNull(plot.getAxes().xaxis.options.max) ){ - val = fmt(plot.getAxes().xaxis.options.max); - } - break; - case "yscale": - if( JS9.notNull(pobj.curscale.y) ){ - val = fmt(pobj.curscale.y); - } - break; - case "ymin": - if( JS9.notNull(plot.getAxes().yaxis.options.min) ){ - val = fmt(plot.getAxes().yaxis.options.min); - } - break; - case "ymax": - if( JS9.notNull(plot.getAxes().yaxis.options.max) ){ - val = fmt(plot.getAxes().yaxis.options.max); - } - break; - default: - break; - } - $(element).val(val); - }); - // save the image for later processing - $(form).data("im", this); - // save the plot object for later processing - $(form).data("plot", plot); - // save the plot opts object for later processing - $(form).data("pobj", pobj); - // save the window id for later processing - $(form).data("winid", winid); - // add tooltip callbacks (not mobile: ios buttons stop working!) - if( !$(form).data("tooltipInit") ){ - $(form).data("tooltipInit", true); - if( JS9.BROWSER[3] ){ - mover = "touchstart"; - mout = "touchend"; - } else { - mover = "mouseover"; - mout = "mouseout"; - } - $(".plotcol_P").on(mover, (e) => { - let title; - const target = e.currentTarget; - const tooltip = $(target).find("input").data("tooltip"); - const el = $(target) - .closest(JS9.lightOpts[JS9.LIGHTWIN].top) - .find(JS9.lightOpts[JS9.LIGHTWIN].dragBar); - if( tooltip && el.length ){ - // change title: see dhtmlwindow.js load() @line 130 - title = `${JS9.Plot.opts.title}: ${tooltip}`; - $(el)[0].childNodes[0].nodeValue = title; - } - }); - $(".plotcol_P").on(mout, (e) => { - const target = e.currentTarget; - const el = $(target) - .closest(JS9.lightOpts[JS9.LIGHTWIN].top) - .find(JS9.lightOpts[JS9.LIGHTWIN].dragBar); - if( el.length ){ - $(el)[0].childNodes[0].nodeValue = JS9.Plot.opts.title; - } - }); - } -}; - -// process the plot config form: called with the image context -// eslint-disable-next-line no-unused-vars -JS9.Plot.processConfigForm = function(form, plot, pobj, arr){ - let i, key, val; - const alen = arr.length; - // sanity check - switch( JS9.globalOpts.plotLibrary ){ - case "flot": - break; - case "plotly": - return; - } - // process array of keyword/values - for(i=0; i we were way off scale - try{ s = JS9.wcs2pix(cim.raw.wcs, ra, dec); } - catch(e){ s = null; } - if( s ){ - arr = s.trim().split(/\s+/); - x = parseFloat(arr[0]); - y = parseFloat(arr[1]); - // if image pos is within the image boundaries ... - if( x > 0 && x < w && y > 0 && y < h ){ - // draw the crosshair, centered on the image pos - hopts = {pts: [{x: 0, y: y}, {x: w, y: y}], - redraw:false}; - cim.changeShapes(layername, cim.crosshair.h, hopts); - vopts = {pts: [{x: x, y: 0}, {x: x, y: h}], - redraw: true}; - cim.changeShapes(layername, cim.crosshair.v, vopts); - cim.crosshair.visible = true; - } - } - } - } - } -}; - -// hide: move the crosshair out of the display -// eslint-disable-next-line no-unused-vars -JS9.Crosshair.hide = function(im, ipos, evt){ - const layername = JS9.Crosshair.LAYERNAME; - const opts = JS9.Crosshair.opts.hiddenPts; - // sanity check - if( !im ){ return; } - // if the crosshair is visible ... - if( (im.crosshair && im.crosshair.visible) || - im.tmp.arrowCrosshairVisible ){ - // move it off the display - im.changeShapes(layername, im.crosshair.h, opts); - im.changeShapes(layername, im.crosshair.v, opts); - im.crosshair.visible = false; - delete im.tmp.arrowCrosshairVisible; - } -}; - -// image load: create the cross hair for this image -JS9.Crosshair.create = function(im){ - const opts = JS9.Crosshair.opts.hiddenPts; - const layername = JS9.Crosshair.LAYERNAME; - // sanity check - if( !im ){ return; } - if( !im.crosshair ){ - // create the crosshair object for this image - im.crosshair = {}; - // create the crosshair, but don't display it yet - im.crosshair.h = im.addShapes(layername, "line", opts); - im.crosshair.v = im.addShapes(layername, "line", opts); - im.crosshair.visible = false; - } -}; - -// mark key actions which use the shift key -JS9.Crosshair.keyaction = function(im, ipos, evt){ - if( im && evt && evt.shiftKey ){ - im.tmp.shiftKey = true; - } -}; - -// unmark key action-based shift key use -JS9.Crosshair.keyup = function(im, ipos, evt){ - // remove shiftKey marker, if necessary - if( im && im.tmp.shiftKey && evt && !evt.shiftKey ){ - delete im.tmp.shiftKey; - } -}; - -// init: create the shape layer for this display -JS9.Crosshair.init = function(){ - let i; - const layername = JS9.Crosshair.LAYERNAME; - // init the crosshair shape layer, but only once per display - for(i=0; i 1 ){ - tscale = 10; - } else if( trange > 0.1 ){ - tscale = 100; - } else if( trange > 0.01 ){ - tscale = 1000; - } else if( trange > 0.001 ){ - tscale = 10000; - } else if( trange > 0.0001 ){ - tscale = 100000; - } else { - tscale = 1000000; - } - out0 = Math.floor(in0 * tscale) / tscale; - out1 = Math.ceil(in1 * tscale) / tscale; - outinc = Math.ceil(((out1 - out0) / n) * tscale) / tscale; - return {lo: out0, hi: out1, inc: outinc}; -}; - -// generate label value -JS9.Grid.getLabel = function(opts, v, which){ - let i, t, idx, arr; - let doall = false; - switch(opts.wcsunits){ - case "sexagesimal": - if( (which === "ra") && - ((opts.wcssys !== "galactic") && (opts.wcssys !== "ecliptic")) ){ - v /= 15.0; - } - t = JS9.saodtostr(v, ":", opts.sexaPrec); - arr = t.split(":"); - if( opts.last[which] ){ - t = ""; - for(i=0; i= -opts.margin && x <= raw.width + opts.margin && - y >= -opts.margin && y <= raw.height + opts.margin ){ - t += String(`${x + 1},${y}${1}, `); - n++; - if( lineloc === 0 ){ - lineloc = 1; - if( dec < xdeclim ){ - inc = xdecinc; - } - } else if( lineloc === 1 ){ - if( dec > xdeclim ){ - lineloc = 2; - inc = xdecinc0; - } - } - } else { - if( lineloc === 1 ){ - lineloc = 2; - dec = dec - inc; - inc = xdecinc0; - } - } - } - } - if( n > 1 ){ - s += t.replace(/,\s+$/, ") "); - s += ` {"color": "${opts.lineColor}"};`; - } - } - // lines of constant Dec - for(dec=dec0; dec<=dec1; dec=dec+decinc){ - t = "line("; - inc = xrainc0; - lineloc = 0; - n = 0; - for(ra=ra0; ra<=ra1; ra=ra+inc){ - arr = JS9.wcs2pix(raw.wcs, ra, dec).trim().split(/ +/); - if( arr && arr.length ){ - x = parseFloat(arr[0]); - y = parseFloat(arr[1]); - if( x >= -opts.margin && x <= raw.width + opts.margin && - y >= -opts.margin && y <= raw.height + opts.margin ){ - t += String(`${x + 1},${y}${1}, `); - n++; - if( lineloc === 0 ){ - lineloc = 1; - if( ra < xralim ){ - inc = xrainc; - } - } else if( lineloc === 1 ){ - if( ra > xralim ){ - lineloc = 2; - inc = xrainc0; - } - } - } else { - if( lineloc === 1 ){ - lineloc = 2; - ra = ra - inc; - inc = xrainc0; - } - } - } - } - if( n > 1 ){ - s += t.replace(/,\s+$/, ") "); - s += ` {"color": "${opts.lineColor}"};`; - } - } - // dec labels along constant ra line - decoffx = opts.labelDecOffx / this.rgb.sect.zoom; - decoffy = opts.labelDecOffy / this.rgb.sect.zoom; - decskip = 0; - lastra = ra0; - for(ra=ra0, got=0; ra<=ra1; ra=ra+rainc){ - for(dec=dec0; dec<=dec1; dec=dec+decinc){ - arr = JS9.wcs2pix(raw.wcs, ra, dec).trim().split(/ +/); - if( arr && arr.length ){ - x = parseFloat(arr[0]); - y = parseFloat(arr[1]); - dpos = this.imageToDisplayPos({x, y}); - if( dpos.x > (this.ix+opts.labelMargin) && dpos.x < (this.rgb.img.width+this.ix-opts.labelMargin) && - dpos.y > (this.iy+opts.labelMargin) && dpos.y < (this.rgb.img.height+this.iy-opts.labelMargin)){ - if( decskip >= opts.decSkip ){ - s += sprintf('text(%s,%s,%s,%s) {"color":"%s", "fontFamily":"%s", "fontSize":%s, "fontStyle":"%s", "fontWeight":"%s", "originX":"left", "originY":"top"};', - x + decoffx, y + decoffy, - JS9.Grid.getLabel.call(this, opts, dec, "dec"), - opts.decAngle, - opts.labelColor, - opts.labelFontFamily, - opts.labelFontSize, - opts.labelFontStyle, - opts.labelFontWeight); - got++; - } else { - if( ra !== lastra ){ - decskip++; - } - lastra = ra; - } - } - } - } - if( got ){ - break; - } - } - // ra labels along constant dec line - raoffx = opts.labelRAOffx / this.rgb.sect.zoom; - raoffy = opts.labelRAOffy / this.rgb.sect.zoom; - raskip = 0; - lastdec = dec0; - for(dec=dec0, got=0; dec<=dec1; dec=dec+decinc){ - for(ra=ra0; ra<=ra1; ra=ra+rainc){ - arr = JS9.wcs2pix(raw.wcs, ra, dec).trim().split(/ +/); - if( arr && arr.length ){ - x = parseFloat(arr[0]); - y = parseFloat(arr[1]); - dpos = this.imageToDisplayPos({x, y}); - if( dpos.x > (this.ix+opts.labelMargin) && dpos.x < (this.rgb.img.width+this.ix-opts.labelMargin) && - dpos.y > (this.iy+opts.labelMargin) && dpos.y < (this.rgb.img.height+this.iy-opts.labelMargin)){ - if( raskip >= opts.raSkip ){ - s += sprintf('text(%s,%s,%s,%s) {"color":"%s", "fontFamily":"%s", "fontSize":%s, "fontStyle":"%s", "fontWeight":"%s", "originX":"left", "originY":"top"};', - x + raoffx, y + raoffy, - JS9.Grid.getLabel.call(this, opts, ra, "ra"), - opts.raAngle, - opts.labelColor, - opts.labelFontFamily, - opts.labelFontSize, - opts.labelFontStyle, - opts.labelFontWeight); - got++; - } else { - if( dec !== lastdec ){ - raskip++; - } - lastdec = dec; - } - } - } - } - if( got ){ - break; - } - } - // add the grid shapes - this.addShapes(JS9.Grid.LAYERNAME, s, opts); - // grid is complete and active - this.tmp.gridStatus = "active"; -}; - -// toggle grid on/off -JS9.Grid.toggle = function(im){ - // sanity check - if( !im ){ return; } - // toggle display - switch(im.tmp.gridStatus){ - case undefined: - case null: - case "inactive": - // start afresh - im.displayCoordGrid(true); - break; - case "active": - // clear the grid - im.displayCoordGrid(false); - break; - case "processing": - default: - break; - } -}; - -// display grid, as needed -JS9.Grid.regrid = function(im){ - if( im ){ - // ignore if grid is not active or the image is not loaded - if( im.tmp.gridStatus !== "active" || im.status.load !== "complete" ){ - return; - } - // redraw the grid - im.displayCoordGrid(true); - } -}; - -// plugin init: load our grid methods -// eslint-disable-next-line no-unused-vars -JS9.Grid.init = function(opts){ - let dlayer; - opts = $.extend(true, {}, JS9.Catalogs.opts, JS9.Grid.opts, opts); - // init the display shape layer - dlayer = this.display.newShapeLayer(JS9.Grid.LAYERNAME, opts); - // mouse up: no-op - dlayer.canvas.on("mouse:up", () => { - return false; - }); -}; - -// add to image prototypes -JS9.Image.prototype.displayCoordGrid = JS9.Grid.display; - -// check if an object is an image handle -JS9.isImage = function(s){ - if( typeof s === "object" && - JS9.notNull(s.id) && - JS9.notNull(s.raw) && - JS9.notNull(s.rgb) && - JS9.notNull(s.params) && - JS9.notNull(s.display) ){ - return true; - } if( typeof s === "string" && JS9.lookupImage(s) ){ - return true; - } - return false; -}; - -// --------------------------------------------------------------------- -// Dysel: callbacks when a display is selected dynamically -// --------------------------------------------------------------------- - -JS9.Dysel = {}; -JS9.Dysel.CLASS = "JS9"; -JS9.Dysel.NAME = "Dysel"; - -JS9.Dysel.display = null; -JS9.Dysel.plugins = []; - -// plugin init: no op -// eslint-disable-next-line no-unused-vars -JS9.Dysel.init = function(opts){ - return; -}; - -// unhighlight current selection -JS9.Dysel.unhighlightSelection = function(){ - if( JS9.bugs.webkit_resize ){ - $(".JS9").find(".JS9Image").removeClass("JS9Highlight"); - } else { - $(".JS9").removeClass("JS9Highlight"); - } -}; - -// highlight display when dynamic selection is made -JS9.Dysel.highlightSelection = function(im){ - let disp; - // sanity check - if( !im || !JS9.Dysel.retrievePlugins().length ){ return; } - // optimization: no processing if we only have one display - if( JS9.displays.length === 1 ){ return; } - // unhighlight all - JS9.Dysel.unhighlightSelection(); - // the display to highlight - disp = im.display; - // highlight selected - if( JS9.bugs.webkit_resize ){ - $(disp.divjq).find(".JS9Image").addClass("JS9Highlight"); - } else { - $(disp.divjq).addClass("JS9Highlight"); - } -}; - -// add to dynamic selection array -JS9.Dysel.addPlugins = function(plugin){ - JS9.Dysel.plugins.push(plugin); -}; - -// get dynamic selection array -JS9.Dysel.retrievePlugins = function(){ - return JS9.Dysel.plugins; -}; - -// return current dynamically selected display -JS9.Dysel.getDisplay = function(which){ - if( !JS9.Dysel.retrievePlugins().length ){ - return null; - } - if( which === "previous" ){ - return JS9.Dysel.odisplay; - } - return JS9.Dysel.display; -}; - -// return the display object associated with the current dynamic selection -// or else a default value -JS9.Dysel.getDisplayOr = function(def){ - if( def === "previous" ){ - return JS9.Dysel.getDisplay(def); - } - return JS9.Dysel.getDisplay() || def; -}; - -// set current dynamically selected display -JS9.Dysel.select = function(display){ - // sanity check - if( !display || !JS9.Dysel.retrievePlugins().length ){ return; } - // save old display - JS9.Dysel.odisplay = JS9.Dysel.display; - // set new display - JS9.Dysel.display = display; - if( display.image ){ - JS9.Dysel.highlightSelection(display.image); - // plugin callbacks for selected display - display.image.xeqPlugins("image", "ondynamicselect", null); - } -}; - -// imageload: select the display -JS9.Dysel.imageload = function(im){ - if( im ){ - JS9.Dysel.select(im.display); - } -}; - -// imageclose: select another display, if necessary -JS9.Dysel.imageclose = function(im){ - let i, got, disp; - if( im ){ - disp = JS9.Dysel.getDisplay(); - if( !disp || disp.image !== im ){ - return; - } - // if this the last image in this display? - for(i=0, got=0; i>> 0; - - // 3. If len is 0, return false. - if (len === 0) { - return false; - } - - // 4. Let n be ? ToInteger(fromIndex). - // (If fromIndex is undefined, this step produces the value 0.) - var n = fromIndex | 0; - - // 5. If n ≥ 0, then - // a. Let k be n. - // 6. Else n < 0, - // a. Let k be len + n. - // b. If k < 0, let k be 0. - var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); - - function sameValueZero(x, y) { - return x === y || (typeof x === "number" && typeof y === "number" && isNaN(x) && isNaN(y)); - } - - // 7. Repeat, while k < len - while (k < len) { - // a. Let elementK be the result of ? Get(O, ! ToString(k)). - // b. If SameValueZero(searchElement, elementK) is true, return true. - // c. Increase k by 1. - if (sameValueZero(o[k], searchElement)) { - return true; - } - k++; - } - - // 8. Return false - return false; - } - }); -} - -// make a copy of the raw data -// used by setFlip and setRot90 -JS9.getRawCopy = function(oraw, bitpix){ - // make copy - let nraw = $.extend(true, {}, oraw); - nraw.bitpix = bitpix || oraw.bitpix; - switch(nraw.bitpix){ - case 8: - nraw.data = new Uint8Array(oraw.data); - break; - case 16: - nraw.data = new Int16Array(oraw.data); - break; - case -16: - nraw.data = new Uint16Array(oraw.data); - break; - case 32: - nraw.data = new Int32Array(oraw.data); - break; - case -32: - nraw.data = new Float32Array(oraw.data); - break; - case -64: - nraw.data = new Float64Array(oraw.data); - break; - default: - JS9.error(`unsupported bitpix: ${nraw.bitpix}`); - break; - } - return nraw; -}; - -// extract line from raw data -// used by setFlip and setRot90 -JS9.getRawLine = function(oraw, ooff, nraw, noff){ - let obuf, nbuf; - switch(oraw.bitpix){ - case 8: - obuf = new Uint8Array(oraw.data.buffer, ooff, oraw.width); - nbuf = new Uint8Array(nraw.data.buffer, noff, oraw.width); - break; - case 16: - case -16: - obuf = new Uint16Array(oraw.data.buffer, ooff, oraw.width); - nbuf = new Uint16Array(nraw.data.buffer, noff, oraw.width); - break; - case 32: - obuf = new Uint32Array(oraw.data.buffer, ooff, oraw.width); - nbuf = new Uint32Array(nraw.data.buffer, noff, oraw.width); - break; - case -32: - obuf = new Float32Array(oraw.data.buffer, ooff, oraw.width); - nbuf = new Float32Array(nraw.data.buffer, noff, oraw.width); - break; - case -64: - obuf = new Float64Array(oraw.data.buffer, ooff, oraw.width); - nbuf = new Float64Array(nraw.data.buffer, noff, oraw.width); - break; - default: - JS9.error(`unsupported bitpix: ${oraw.bitpix}`); - break; - } - return [obuf, nbuf]; -}; - -// https://www.html5rocks.com/en/tutorials/webgl/typed_arrays/ -JS9.memcpy = function(dst, dstOffset, src, srcOffset, length){ - var dstU8 = new Uint8Array(dst, dstOffset, length); - var srcU8 = new Uint8Array(src, srcOffset, length); - dstU8.set(srcU8); -}; - -// set explicit focus for IPython/Jupyter support -JS9.jupyterFocus = function(el, el2){ - let eljq; - if( {}.hasOwnProperty.call(window, "Jupyter") ){ - if( el instanceof jQuery ){ - eljq = el; - } else { - eljq = $(el); - } - el2 = el2 || "input, textarea"; - eljq.find(el2).each((index, element) => { - Jupyter.keyboard_manager.register_events($(element)); - }); - } -}; - -// return a unique value for a given image id by appending to the id -JS9.getImageID = function(imid, dispid, myim){ - let i, im, s; - let ids = 0; - let idmax = 1; - const imlen = JS9.images.length; - const rexp = /.*<([0-9][0-9]*)>$/; - const rexp2 = /<[0-9][0-9]*>/; - imid = JS9.cleanPath(imid.replace(rexp2, ""), "id"); - for(i=0; i= 0 ){ - s = im.id.replace(rexp, "$1"); - idmax = Math.max(idmax, parseInt(s, 10)); - } - ids++; - } - } - } - if( ids ){ - return `${imid}<${String(idmax+1)}>`; - } - return imid; -}; - -// return a unique value for ids -JS9.uniqueID = (function(){ - let id = 1; // initial value - return function(){ - return id++; - }; -}()); - -// change cursor to waiting/not waiting -JS9.waiting = function(mode, display){ - let el, opts, tdisp; - switch(mode){ - case true: - if( {}.hasOwnProperty.call(window, "Spinner") && - (JS9.globalOpts.waitType === "spinner") ){ - if( display ){ - if( typeof display === "object" ){ - el = display.divjq[0]; - } else if( typeof display === "string" ){ - tdisp = JS9.lookupDisplay(display); - if( tdisp ){ - el = tdisp.divjq[0]; - } - } - } - if( !el ){ - el = $("body").get(0); - } - if( !JS9.spinner ){ - JS9.spinner = {}; - opts = {color: JS9.globalOpts.spinColor, - opacity: JS9.globalOpts.spinOpacity}; - JS9.spinner.spinner = new Spinner(opts); - } - JS9.spinner.spinner.spin(el); - } else { - $("body").addClass("waiting"); - } - break; - case false: - if( {}.hasOwnProperty.call(window, "Spinner") && - (JS9.globalOpts.waitType === "spinner") ){ - if( JS9.spinner ){ - JS9.spinner.spinner.stop(); - } - } else { - $("body").removeClass("waiting"); - } - break; - } -}; - -// display a progress bar -JS9.progress = function(arg1, arg2){ - if( (typeof arg1 === "boolean") || (typeof arg1 === "string") ){ - switch(arg1){ - case true: - case "indeterminate": - if( arg2 ){ - JS9.progress.display = arg2; - JS9.progress.display.displayMessage("progress", arg1); - } - break; - case false: - case "": - if( JS9.progress.display ){ - JS9.progress.display.clearMessage("progress"); - delete JS9.progress.display; - } - break; - } - } else if( typeof arg1 === "number" ){ - if( JS9.progress.display ){ - JS9.progress.display.displayMessage("progress", [arg1, arg2]); - } - } -}; - -// msg coming from socket.io or postMessage -JS9.msgHandler = function(msg, cb){ - let i, s, obj, tdisp, res, dobj; - let args = []; - const cmd = msg.cmd; - const id = msg.id; - const oalerts = JS9.globalOpts.alerts; - const rstr = JS9.globalOpts.quietReturn ? "" : "OK"; - const getDisplayObject = (id, args) => { - if( id ){ - // bash sends a string, not an object - if( args.length > 0 ){ - s = args[args.length-1]; - if( typeof s === "string" ){ - try{ obj = JSON.parse(s); } - catch(e){ obj = null; } - } else if( typeof s === "object" ){ - obj = s; - } - // is this the display object? see JS9.parsePublicArgs - if( obj && - (typeof obj === "object") && - {}.hasOwnProperty.call(obj, "display") && - (Object.keys(obj).length === 1) ){ - // remove the current display object - args.pop(); - // return the new one - return obj; - } else { - return {display: id}; - } - } else { - return {display: id}; - } - } - return null; - }; - // turn off alerts - if( cb ){ - JS9.globalOpts.alerts = false; - } - // look for a public API call - if( JS9.publics[cmd] ){ - // check for non-array first arg - if( !$.isArray(msg.args) ){ - msg.args = [msg.args]; - } - // change empty quoted strings to empty strings - for(i=0; i { - rval.close(); - }) - .on("touchend", (e) => { - const curtime = (new Date()).getTime(); - const lasttime = $(e.currentTarget).data("lasttime"); - if( lasttime && - (curtime - lasttime) > JS9.DBLCLICK0 && - (curtime - lasttime) < JS9.DBLCLICK ){ - rval.close(); - } - $(e.currentTarget).data("lasttime", curtime); - }); - // if ios user failed to close the window via the close button, - // give a hint (once per session only!) - $(`#${id} ${JS9.lightOpts[JS9.LIGHTWIN].dragBar}`) - .on("touchend", () => { - // skip check if we are dragging - if( !dhtmlwindow.distancex && !dhtmlwindow.distancey ){ - if( JS9.lightOpts.nclick >= 2 ){ - alert("trouble closing this window? double-tap the window handle"); - JS9.lightOpts.nclick = -1; - } else { - if( JS9.lightOpts.nclick >= 0 ){ - JS9.lightOpts.nclick++; - } - } - } else { - if( JS9.lightOpts.nclick > 0 ){ - JS9.lightOpts.nclick = 0; - } - } - }); - break; - default: - break; - } - return rval; -}; - -// wrapper for new func to avoid jslint errors -JS9.checkNew = function(obj){ - if( !obj ){ - JS9.error("internal failure in a JS9 constructor"); - } -}; - -// desperate attempt to regularize the control/meta key -JS9.specialKey = function(e){ - return (e.metaKey || e.ctrlKey); -}; - -// desperate attempt to regularize the stracktrace message -JS9.strace = function(e){ - let s = ""; - if( JS9.DEBUG > 1 ){ - s = e.stack || e.stacktrace || ""; - } - return s; -}; - -// try to make a nice string from a float -// ints remain ints, floats get truncated at 6 significant digits -JS9.floatToString = function(fval){ - if( typeof fval === "number" ){ - return sprintf("%g", - parseFloat(fval.toFixed(JS9.globalOpts.floatPrecision))); - } else if( typeof fval === "string" ){ - return fval; - } else { - return String(fval); - } -}; - -// figure out precision from range of values (used by colorbar) -// from: /tksao1.0/colorbar/colorbarbase.C -JS9.floatPrecision = function(fval1, fval2){ - let prec; - let aa = Math.floor(Math.log10(Math.abs(fval1))); - let bb = Math.floor(Math.log10(Math.abs(fval2))); -// not sure why prec is set to 1 in the else clause so ... -// if( aa !== bb ){ -// prec = aa > bb ? aa : bb; -// } else { -// prec = 1; -// } - prec = Math.max(aa, bb); - return prec; -}; - -// convert float value to a string with decent precision -// from: /tksao1.0/colorbar/colorbarbase.C -JS9.floatFormattedString = function(fval, prec, jj){ - let fmt; - let s = ""; - if( fval === undefined ){ - return s; - } - if( prec < -2 ){ - fmt = `%.${String(2+jj)}e`; - s = sprintf(fmt, fval); - } else if( prec < 0 ){ - s = fval.toFixed(Math.abs(prec)+3+jj); - } else if( prec < 2 ){ - fmt = `%.${String(prec+jj)}f`; - s = sprintf(fmt, fval); - } else if( prec < 5 ){ - s = fval.toFixed(0+jj); - } else { - fmt = `%.${String(2+jj)}e`; - s = sprintf(fmt, fval); - } - return s; -}; - -// get center of bounding box surrounding a polygon -JS9.centerPolygon = function(points){ - let i, plen, minx, maxx, miny, maxy; - // sanity check - if( !points || !points.length ){ return; } - plen = points.length; - for(i=0; i maxx) ){ - maxx = points[i].x; - } - if( (miny === undefined) || (points[i].y < miny) ){ - miny = points[i].y; - } - if( (maxy === undefined) || (points[i].y > maxy) ){ - maxy = points[i].y; - } - } - return {x: (minx + maxx) / 2.0, y: (miny + maxy) / 2.0}; -}; - -// calculate centroid for a polygon -// wont work for self-intersecting polygons but it's all I do right now! -// adapted from: http://en.wikipedia.org/wiki/Centroid -JS9.centroidPolygon = function(points, doaverage){ - let i, plen, factor, area, cx, cy; - let parta = 0; - let partx = 0; - let party = 0; - let totx = 0; - let toty = 0; - const pts = []; - // sanity check - if( !points || !points.length ){ return; } - // get points - plen = points.length; - // just average the points? - if( doaverage ){ - for(i=0; i 0 ){ - did = im.display.id; - if( !display || - (typeof display === "string" && display === did) || - (typeof display === "object" && display.id === did) ){ - return im; - } - } - } - } - return null; -}; - -// return the display for the specified id -// id can be a display object or an id from a display object -JS9.lookupDisplay = function(id, mustExist){ - let i; - const regexp = new RegExp(`[-_]?(${JS9.PLUGINS})$`); - // default is the id must exist - if( mustExist === undefined ){ - mustExist = true; - } - // lookup id - if( id && (id.toString().search(JS9.SUPERMENU) < 0) ){ - // look for whole id - for(i=0; i { - let blob; - if( xhr.readyState === 4 ){ - if( xhr.status === 200 || xhr.status === 0 ){ - // delete fetch status so JS9.error() does not process it - delete JS9.fetchURL.status; - if( xhr.responseType === "blob" ){ - blob = new Blob([xhr.response]); - // discard path (or scheme) up to slashes - // remove trailing ? params - if( name.match("://") ){ - blob.name = name.split("/").reverse()[0] - .replace(/\?.*$/, ""); - } else { - blob.name = name; - } - // hack for Google Drive's lack of a filename - if( blob.name === "uc" ){ - blob.name = `google_${JS9.uniqueID()}.fits`; - } - if( handler ){ - handler(blob, opts); - } else { - JS9.Load(blob, opts); - } - } else { - if( opts.display ){ - handler(xhr.response, opts, {display: opts.display}); - } else { - handler(xhr.response, opts); - } - } - } else if( xhr.status === 404 ){ - JS9.error(`could not find ${url}`); - } else { - JS9.error(`can't load: ${url} ${xhr.statusText} ${xhr.status}`); - } - } - }; - xhr.onerror = () => { - JS9.error(`cannot load: ${url} ... please check the url/pathname`); - }; - xhr.ontimeout = () => { - JS9.error(`timeout awaiting response from server: ${url}`); - }; - // hack: set fetch status for JS9.error() to sense and pass on - // this will be picked up by getStatus("load") - JS9.fetchURL.status = "processing"; - // fetch the data! - try{ xhr.send(); } - catch(e){ JS9.error(`request to load ${url} failed`, e); } -}; - -// JS9 wrapper around saveAs: -// deal with pathnames in Electron desktop app -JS9.saveAs = function(blob, pathname){ - let dirmatch, dirname, basename; - if( window.electron ){ - dirmatch = pathname.match(/.*\//); - // if a directory was specified ... - if( dirmatch && dirmatch[0] ){ - // ... change save directory in Electron before save - dirname = dirmatch[0]; - JS9.SaveDir(dirname, {onceOnly: true}); - } - // get basename - basename = pathname.split('/').reverse()[0]; - // wait a bit for ipc to finish, then save - window.setTimeout(() => { - // save basename in current save directory - try{ saveAs(blob, basename); } - catch(e){ JS9.error("could not saveAs", e); } - }, JS9.TIMEOUT); - } else { - // non-Electron (or no path): just save filename - try{ saveAs(blob, pathname); } - catch(e){ JS9.error("could not saveAs", e); } - } -} - -// configure or return the fits library -JS9.fitsLibrary = function(s){ - let t; - if( !s ){ - return JS9.fits.name; - } - t = s.toLowerCase(); - switch(t){ - case "astroem": - case "cfitsio": - JS9.fits = Astroem; - // set up default options - JS9.fits.options = JS9.fits.options || {}; - JS9.fits.options.handler = JS9.NewFitsImage; - JS9.fits.options.error = JS9.error; - if( JS9.userOpts.fits ){ - JS9.fits.options.extlist = JS9.userOpts.fits.extlist; - JS9.fits.options.table = { - xdim: JS9.userOpts.fits.xdim, - ydim: JS9.userOpts.fits.ydim, - bin: JS9.userOpts.fits.bin || 1 - }; - JS9.fits.options.image = { - xdim: JS9.userOpts.fits.ixdim || JS9.userOpts.fits.xmax, - ydim: JS9.userOpts.fits.iydim || JS9.userOpts.fits.ymax, - bin: JS9.userOpts.fits.ibin || 1 - }; - } else { - JS9.fits.options.extlist = JS9.globalOpts.extlist; - JS9.fits.options.table = {bin: (JS9.globalOpts.table.bin || 1)}; - // NB: dims are deprecated 11/27/16 - if( JS9.notNull(JS9.globalOpts.table.xdim) ){ - JS9.fits.options.table.xdim = JS9.globalOpts.table.xdim; - } else if( JS9.notNull(JS9.globalOpts.dims) ){ - JS9.fits.options.table.xdim = JS9.globalOpts.dims[0]; - } - if( JS9.notNull(JS9.globalOpts.table.ydim) ){ - JS9.fits.options.table.ydim = JS9.globalOpts.table.ydim; - } else if( JS9.notNull(JS9.globalOpts.dims) ){ - JS9.fits.options.table.ydim = JS9.globalOpts.dims[1]; - } - JS9.fits.options.image = {bin: (JS9.globalOpts.image.bin || 1)}; - if( JS9.notNull(JS9.globalOpts.image.xdim) ){ - JS9.fits.options.image.xdim = JS9.globalOpts.image.xdim; - } else if( JS9.notNull(JS9.globalOpts.xmax) ){ - JS9.fits.options.image.xdim = JS9.globalOpts.xmax; - } - if( JS9.notNull(JS9.globalOpts.image.ydim) ){ - JS9.fits.options.image.ydim = JS9.globalOpts.image.ydim; - } else if( JS9.notNull(JS9.globalOpts.ymax) ){ - JS9.fits.options.image.ydim = JS9.globalOpts.ymax; - } - } - if( JS9.fits.maxFITSMemory && JS9.globalOpts.maxMemory ){ - JS9.fits.maxFITSMemory(JS9.globalOpts.maxMemory); - } - break; - default: - JS9.error(`unknown fits library: ${s}`); - break; - } - // common code - JS9.fits.ready = true; - JS9.fits.name = t; - JS9.fits.options.error = JS9.error; - JS9.fits.options.waiting = JS9.waiting; - return t; -}; - -// check for 'real' FITS handling routine and call it. This routine can: -// read a blob as a FITS file -// open an existing virtual FITS file (e.g. created by Montage reprojection) -JS9.handleFITSFile = function(file, opts, handler){ - if( JS9.fits.handleFITSFile ){ - JS9.fits.handleFITSFile(file, opts, handler); - } else { - JS9.error("no FITS module available to process FITS file"); - } -}; - -// cleanup FITS file by deleting vfile, etc -JS9.cleanupFITSFile = function(raw, mode){ - let rexp; - if( JS9.hostFS ){ - rexp = new RegExp(`^${JS9.hostFS}`); - } - if( JS9.fits.cleanupFITSFile && raw && raw.hdu && raw.hdu.fits ){ - // don't delete real local file - if( rexp && raw.hdu.fits.vfile && raw.hdu.fits.vfile.match(rexp) ){ - mode = false; - } - JS9.fits.cleanupFITSFile(raw.hdu.fits, mode); - return true; - } - // just return if no available cleanup routine or no raw data file - return false; -}; - -// load an image (jpeg, png, etc) -JS9.handleImageFile = function(file, options, handler){ - const reader = new FileReader(); - options = $.extend(true, {}, JS9.fits.options, options); - handler = handler || JS9.Load; - reader.onload = (ev) => { - let data, grey, hdu; - const img = new Image(); - img.onload = () => { - let x, y, v, header; - let i = 0; - const canvas = document.createElement("canvas"); - const ctx = canvas.getContext("2d"); - const h = img.height; - const w = img.width; - canvas.width = w; - canvas.height = h; - ctx.drawImage(img, 0, 0); - data = ctx.getImageData(0, 0, w, h).data; - grey = new Float32Array(h*w); - for ( y = 0; y < h; y++ ) { - for ( x = 0; x < w; x++ ) { - // NTSC - v = 0.299 * data[i] + 0.587 * data[i+1] + 0.114 * data[i+2]; - grey[(h - y) * w + x] = v; - i += 4; - } - } - header = {SIMPLE: true, - BITPIX: -32, - NAXIS: 2, - NAXIS1: w, - NAXIS2: h}; - hdu = {filename: file.name, - naxis: 2, axis: [0, w, h], bitpix: -32, bin: 1, - head: header, data: grey, offscreen: img}; - hdu.dmin = Number.MAX_VALUE; - hdu.dmax = Number.MIN_VALUE; - for(i=0; i< h*w; i++){ - if( !Number.isNaN(hdu.data[i]) && - Number.isFinite(hdu.data[i]) ){ - hdu.dmin = Math.min(hdu.dmin, hdu.data[i]); - hdu.dmax = Math.max(hdu.dmax, hdu.data[i]); - } - } - options.source = "img"; - handler(hdu, options); - }; - img.src = ev.target.result; - }; - reader.readAsDataURL(file); -}; - -// check for 'real' FITS handling routine and call it -JS9.getFITSImage = function(fits, hdu, options, handler){ - if( JS9.fits.getFITSImage ){ - JS9.fits.getFITSImage(fits, hdu, options, handler); - } else { - JS9.error("no FITS module available to process FITS image"); - } -}; - -// run fits2fits converter, if necessary -JS9.fits2fits = function(display, file, opts, func){ - let i, s, xdim, ydim, bin, bmode, obj, xcond; - const xopts = {}; - opts = opts || {}; - if( JS9.notNull(opts.fits2fits) ){ - xcond = opts.fits2fits; - } else { - xcond = JS9.globalOpts.fits2fits; - } - if( xcond === true ){ - xcond = "always"; - } else if( xcond === false ){ - xcond = "never"; - } - // if never, we are done - if( xcond.match(/never/i) ){ - return false; - } - // make sure we are set up to run the converter - // requires a connected helper via a socket.io connection - if( !JS9.helper.connected || - (JS9.helper.type !== "nodejs" && JS9.helper.type !== "socket.io") ){ - if( xcond === "always" && JS9.globalOpts.requireFits2Fits ){ - JS9.error("can't run fits2fits without connected JS9 helper"); - } - return false; - } - // if the helper program does not exist, we might want to throw an error - if( !JS9.helper.js9helper ){ - if( JS9.globalOpts.requireFits2Fits ){ - JS9.error("js9helper not found for fits2fits processing"); - } else { - return false; - } - } - // requires a tmp workdir - if( !JS9.globalOpts.workDir ){ - if( JS9.globalOpts.requireFits2Fits ){ - JS9.error("can't run fits2fits without a workdir"); - } - return false; - } - xdim = - opts.xdim || - JS9.fits.options.image.xdim || - JS9.fits.options.table.xdim; - ydim = - opts.ydim || - JS9.fits.options.image.ydim || - JS9.fits.options.table.ydim; - bin = - opts.bin || - JS9.fits.options.image.bin || - JS9.fits.options.table.bin; - bmode = opts.binMode || JS9.globalOpts.binMode; - bmode = bmode === "a" ? "a" : ""; - // handle string bin, possibly containing explicit binMode - if( typeof bin === "string" ){ - if( bin.match(/[as]$/) ){ - bmode = bin.slice(-1); - } - bin = parseInt(bin, 10); - } - bin = Math.max(1, bin || 1); - if( JS9.notNull(opts.xcen) && JS9.notNull(opts.ycen) ){ - xopts.sect = `${xdim}@${opts.xcen},${ydim}@${opts.ycen},${bin}${bmode}`; - } else { - xopts.sect = `${xdim},${ydim},${bin}${bmode}`; - } - s = xcond.toLowerCase().split(/[>,]/); - for(i=0; i { - let robj, rarr, f, pf, nopts; - // return type can be string or object - if( typeof r === "object" ){ - // object from node.js - robj = r; - } else { - // string from cgi - if( r.search(JS9.analOpts.epattern) >=0 ){ - robj = {stderr: r}; - } else { - robj = {stdout: r}; - } - } - if( robj.stderr ){ - JS9.error(robj.stderr, JS9.analOpts.epattern); - } - if( robj.stdout ){ - // look for error condition, which we might throw or swallow - if( robj.stdout.match(/^ERROR:/) ){ - if( JS9.globalOpts.requireFits2Fits ){ - JS9.error(robj.stdout); - } else { - robj.stdout = xopts.fits; - } - } - // output is file and possibly parentFile - rarr = robj.stdout.split(/\n/); - // file - f = JS9.cleanPath(rarr[0]); - if( f === xopts.fits ){ - // same file (imsection not run) - nopts = $.extend(true, {}, opts); - } else { - // new file using imsection - // relative path: add install dir prefix - if( f.charAt(0) !== "/" ){ - f = JS9.InstallDir(f); - } - nopts = $.extend(true, {}, opts); - // but remove already-used section properties from opts - delete nopts.xcen; - delete nopts.ycen; - delete nopts.bin; - // but load entire image section - if( nopts.xdim !== undefined ){ nopts.xdim = 0; } - if( nopts.ydim !== undefined ){ nopts.ydim = 0; } - // save source - nopts.source = "fits2fits"; - // it's a proxy file (i.e., delete it on close) - nopts.proxyFile = f; - // json fits info - if( rarr[1] ){ - try{ obj = JSON.parse(rarr[1]); } - catch(ignore){ /* empty */ } - if( obj ){ - nopts.extname = obj.extname; - nopts.extnum = obj.extnum; - nopts.hdus = obj.hdus; - nopts.parent = obj; - } - } - // look for parentFile (relative to helper, not install) - if( rarr[2] ){ - pf = JS9.cleanPath(rarr[2]); - nopts.parentFile = pf; - // now add extension info, if possible - if( nopts.extname ){ - nopts.parentFile = nopts.parentFile - .replace(/\[.*\]/, ""); - nopts.parentFile += `[${nopts.extname}]`; - } else if( nopts.extnum && (nopts.extnum > 0) ){ - nopts.parentFile = nopts.parentFile - .replace(/\[.*\]/, ""); - nopts.parentFile.file += `[${nopts.extnum}]`; - } - } - // add onload, if necessary - if( func ){ - nopts.onload = func; - } - } - // no recursion! - nopts.fits2fits = false; - // load new file - JS9.Load(f, nopts, {display}); - } - }); - return true; -}; - -// return the specified colormap object (or default) -JS9.lookupColormap = function(name, mustExist){ - let i; - // default is the id must exist - if( mustExist === undefined ){ - mustExist = true; - } - if( !name ){ - name = JS9.imageOpts.colormap; - } - if( name ){ - for(i=0; i", - "47": "?" - }; - // allow direct specification of keycode as a number - if( typeof evt === "number" ){ - c = evt; - } else { - // otherwise its the event - c = evt.which || evt.keyCode; - } - s = String(c); - // normalize keyCode - if( {}.hasOwnProperty.call(_to_ascii, s) ){ - c = _to_ascii[s]; - } - if( !evt.shiftKey && (c >= 65 && c <= 90) ){ - c = String.fromCharCode(c + 32); - } else if( !evt.shiftKey && {}.hasOwnProperty.call(_specialKeys, c) ){ - c = _specialKeys[c]; - } else if( evt.shiftKey && {}.hasOwnProperty.call(_shiftUps, c) ){ - //get shifted keyCode value - c = _shiftUps[c]; - } else { - c = String.fromCharCode(c); - } - // check for special key - if( JS9.specialKey(evt) ){ - c = `M-${c}`; - } - return c; -}; - -// get position of mouse in a canvas -// http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas -JS9.eventToDisplayPos = function(evt, offset){ - // from http://www.quirksmode.org/js/events_properties.html - let i, targ, pageX, pageY, leftOff, upOff, touches, pos; - const XFUDGE = 1; - const YFUDGE = 1; - if( !evt ){ - evt = window.event; - } - if( evt.target ){ - targ = evt.target; - } else if( evt.srcElement ){ - targ = evt.srcElement; - } - if( targ.nodeType === 3 ){ // defeat Safari bug - targ = targ.parentNode; - } - // offset() returns the position of the element relative to the document - offset = offset || $(targ).offset(); - // pageX, pageY: mouse positions relative to the document - // changed touch events: take position from first finger - if( evt.originalEvent ){ - if( evt.originalEvent.touches && - evt.originalEvent.touches.length ){ - touches = evt.originalEvent.touches; - pageX = touches[0].pageX; - pageY = touches[0].pageY; - } else if( evt.originalEvent.changedTouches && - evt.originalEvent.changedTouches.length ){ - touches = evt.originalEvent.changedTouches; - pageX = touches[0].pageX; - pageY = touches[0].pageY; - } else { - pageX = evt.pageX; - pageY = evt.pageY; - } - } else { - // mouse events - pageX = evt.pageX; - pageY = evt.pageY; - } - // position is (evt pos relative to page - pos of element relative to page) - // FUDGE added after visual inspection of line512 at zoom 32 - // I tried to place the mouse, and have the magnifier be in the right place - // Linux, FF & Chrome: x=1, y=1 (5/28/14) - leftOff = offset.left + XFUDGE; - upOff = offset.top + YFUDGE; - // display position - pos = {x: Math.floor(pageX - leftOff), y: Math.floor(pageY - upOff)}; - // touch positions, if necessary - if( touches && touches.length ){ - pos.touches = [{x: pos.x, y: pos.y}]; - for(i=1; i { - let v = []; - let cosb = Math.cos ( b ); - v[0] = Math.cos ( a ) * cosb; - v[1] = Math.sin ( a ) * cosb; - v[2] = Math.sin ( b ); - return v; - }; - // modified from P.T. Wallace (acquired via email 6/29/2020) - const slaDpav = (v1, v2) => { - let x0, y0, z0, w, x1, y1, z1, s, c; - /* Unit vector to point 1. */ - x0 = v1 [ 0 ]; - y0 = v1 [ 1 ]; - z0 = v1 [ 2 ]; - w = Math.sqrt ( x0 * x0 + y0 * y0 + z0 * z0 ); - if( w != 0.0 ) { x0 /= w; y0 /= w; z0 /= w; } - /* Vector to point 2. */ - x1 = v2 [ 0 ]; - y1 = v2 [ 1 ]; - z1 = v2 [ 2 ]; - /* Position angle. */ - s = y1 * x0 - x1 * y0; - c = z1 * ( x0 * x0 + y0 * y0 ) - z0 * ( x1 * x0 + y1 * y0 ); - return ( s != 0.0 || c != 0.0 ) ? Math.atan2 ( s, c ) : 0.0; - }; - const d2r = (x) => { return x * Math.PI / 180; }; - const r2d = (x) => { return x * 180 / Math.PI; }; - a = slaDcs2c(d2r(ra1), d2r(dec1)); - b = slaDcs2c(d2r(ra2), d2r(dec2)); - dist = slaDpav(a, b); - // negation required to be in line with our conventions - dist = -dist; - return r2d(dist); -}; - -// http://stackoverflow.com/questions/13695317/rotate-a-point-around-another-point -// angle is input in degrees -JS9.rotatePoint = function(point, angle, cen) -{ - let cosA, sinA; - cen = cen || {x: 0.0, y: 0.0}; - angle = Math.PI * angle / 180.0; - cosA = Math.cos(angle); - sinA = Math.sin(angle); - return { - x: (cosA * (point.x - cen.x) - sinA * (point.y - cen.y) + cen.x), - y: (sinA * (point.x - cen.x) + cosA * (point.y - cen.y) + cen.y) - }; -}; - -// multiply two matrices -// https://stackoverflow.com/questions/27205018/multiply-2-matrices-in-javascript -JS9.matrixMultiply = function(a, b){ - let r, c, i, m; - const aNumRows = a.length, aNumCols = a[0].length; - // eslint-disable-next-line no-unused-vars - const bNumRows = b.length, bNumCols = b[0].length; - m = new Array(aNumRows); // initialize array of rows - for(r = 0; r < aNumRows; ++r){ - m[r] = new Array(bNumCols); // initialize the current row - for(c = 0; c < bNumCols; ++c){ - m[r][c] = 0; // initialize the current cell - for(i = 0; i < aNumCols; ++i){ - m[r][c] += a[r][i] * b[i][c]; - } - } - } - return m; -}; - -// invert a 3x3 matrix -JS9.invertMatrix3 = function(xin){ - let i, j, det_1; - let pos = 0.0; - let neg = 0.0; - let temp = xin[0][0] * xin[1][1]; - const prec = 1.0e-15; - const xout = [[0,0,0], [0,0,0], [0,0,0]]; - const accum = () => { - if( temp >= 0.0 ){ - pos += temp; - } else { - neg += temp; - } - }; - // sanity check for NaN - for(i=0; i<3; i++){ - for(j=0; j<2; j++){ - if( (xin[i][j] === undefined) || Number.isNaN(xin[i][j]) ){ - return null; - } - } - } - accum(); - temp = -xin[0][1] * xin[1][0]; - accum(); - det_1 = pos + neg; - // Is the submatrix A singular? - if( (det_1 === 0.0) || (Math.abs(det_1 / (pos - neg)) < prec) ){ - // Matrix M has no inverse - return null; - } - // Calculate inverse(A) = adj(A) / det(A) - det_1 = 1.0 / det_1; - xout[0][0] = xin[1][1] * det_1; - xout[1][0] = - xin[1][0] * det_1; - xout[0][1] = - xin[0][1] * det_1; - xout[1][1] = xin[0][0] * det_1; - // Calculate -C * inverse(A) - xout[2][0] = - (xin[2][0] * xout[0][0] + xin[2][1] * xout[1][0]); - xout[2][1] = - (xin[2][0] * xout[0][1] + xin[2][1] * xout[1][1]); - return xout; -}; - -// is this a string representation of a number? -// https://stackoverflow.com/questions/175739/built-in-way-in-javascript-to-check-if-a-string-is-a-valid-number -// NB: don't use Number.XXX routines, they don't work .. "2016-5" returns true -JS9.isNumber = function(s){ - return !isNaN(parseFloat(s)) && isFinite(s); -}; - -// check if a variable is neither undefined nor null -JS9.notNull = function(s){ - return s !== undefined && s !== null; -}; - -// check if a variable is either undefined or null -JS9.isNull = function(s){ - return s === undefined || s === null; -}; - -// use a default if a variable is either undefined or null -JS9.defNull = function(s, def){ - return JS9.notNull(s) ? s : def; -}; - -// check if a wcs system is a world coordinate system (fk5, etc) -JS9.isWCSSys = function(s){ - return s !== "image" && s !== "physical"; -}; - -// check if a wcs system is not a world coordinate system (fk5, etc) -JS9.notWCS = function(s){ - return s === "image" || s === "physical"; -}; - -// was last parsed string in units of hours/min/sec (using specified wcssys)? -JS9.isHMS = function(wcssys, dtype){ - dtype = dtype || String.fromCharCode(JS9.saodtype()); - return (dtype === ":" || dtype === "h") && - wcssys !== "galactic" && - wcssys !== "ecliptic"; -}; - -// is this a HEALPix image? -JS9.ishealpix = function(im){ - return im && - im.imtab === "table" && - im.raw && im.raw.header && - im.raw.header.CTYPE1 && im.raw.header.CTYPE1.match(/--HPX/i); -}; - -// is the proxy server available for LoadProxy() call? -JS9.proxyAvailable = function(){ - return JS9.globalOpts.loadProxy && - !JS9.allinone && - JS9.globalOpts.helperType !== "none" && - JS9.globalOpts.workDir; -} - -// parse a FITS card and return name and value -JS9.cardpars = function(card){ - let value; - let name = card.slice(0, 8).trim(); - if( name === "HISTORY" ){ return [name, card.slice(9).trim()]; } - if( name === "COMMENT" ){ return [name, card.slice(9).trim()]; } - if( card[8] !== "=" ){ return undefined; } - value = card.slice(10).replace(/'/g, " ").replace(/ \/.*/, "").trim(); - if( value === "T" ){ - value = true; - } else if( value === "F" ){ - value = false; - } else if( JS9.isNumber(value) ){ - value = parseFloat(value); - } - return [name, value]; -}; - -// convert obj to FITS-style string -JS9.raw2FITS = function(raw, opts){ - let i, s, obj, key, val, card, ncard, header, left; - let hasend = false; - let t = ""; - const gots = {}; - const rexp = /^(NAXIS|CRPIX|CRVAL|CTYPE|CUNIT|CDELT)[34567]/; - const fixparam = (card, name, val, comm) => { - let s, oval, regexp; - let ncard = card; - if( name === "XTENSION" && !val ){ - ncard = sprintf("%s = %20s / %-47s", - "SIMPLE", - "T", - "file does conform to FITS standard"); - - } else { - // eslint-disable-next-line no-useless-escape - regexp = new RegExp(`${name} *= *(-?[-+]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?) *`); - if( card ){ - s = card.replace(regexp, "$1"); - oval = parseFloat(s); - } else { - oval = undefined; - } - if( oval !== val ){ - ncard = sprintf("%-8s= %20s / %-47s", name, val, comm||""); - } - } - gots[name] = true; - return ncard; - }; - // sanity check - if( !raw ){ return t; } - // opts is optional - opts = opts || {}; - // backward compatibility: orig. version used boolean to specify addcr - if( typeof opts === "boolean" ){ - opts = {addcr: opts}; - } - // raw.card and raw.cardstr contain comments: use them if possible - if( raw.card || raw.cardstr ){ - header = raw.header || {}; - if( raw.card ){ - ncard = raw.card.length; - } else { - ncard = raw.ncard; - } - for(i=0; i 0 ){ - for(i=0; i#%d: name: %s type: %s", - obj.hdu, s, obj.type); - switch(obj.type){ - case "image": - t += sprintf(" bitpix: %d naxis: %d", obj.bitpix, obj.naxis); - if( obj.naxes.length ){ - t += " axes: ["; - for(j=0; jrows: %d%scols: [", obj.rows, s); - for(j=0; j { - let searchVal = value; - text.unmark({ - done: () => { - text.mark(searchVal, { - caseSensitive: bar.opts.matchcase, - diacritics: bar.opts.diacritics, - accuracy: bar.opts.matchwords ? "exactly" : "partially", - wildcards: bar.opts.matchwildcards ? "enabled" : "disabled", - done: () => { - bar.results = text.find("mark"); - bar.currentIndex = 0; - jumpTo(); - } - }); - } - }); - }; - const btnColor = (which) => { - const s = which.prop("data-btn"); - if( bar.opts[s] ){ - which.removeClass("JS9SearchButton-false"); - which.addClass("JS9SearchButton-true"); - } else { - which.removeClass("JS9SearchButton-true"); - which.addClass("JS9SearchButton-false"); - } - }; - const jumpTo = () => { - let cur, pos; - if( bar.results.length ){ - cur = bar.results.eq(bar.currentIndex); - bar.results.removeClass(currentClass); - if( cur.length ){ - cur.addClass(currentClass); - pos = cur.position().top; - if( pos < 0 || pos > div.height() ){ - pos = pos + div.scrollTop() - offsetTop; - div.scrollTop(pos); - } - } - } - }; - textid = textid || ".JS9AnalysisText"; - // make sure we have text - if( jel.is(textid) ){ - text = jel; - } else { - text = jel.find(textid); - if( !text.length ){ - return; - } - } - // light window or div? - div = jel.find(JS9.lightOpts[JS9.LIGHTWIN].drag); - if( !div.length ){ - // just a div - div = jel; - } - // does the searchbar already exist? - bar = div.find(".JS9Searchbar"); - if( bar.length ){ - // make it visiable and return - bar.css("display", "block"); - return; - } - // make a new searchbar - bar = $("
    ") - .addClass("JS9Searchbar") - .appendTo(div); - // add options - bar.opts = { - matchcase: false, - matchdiacritics: false, - matchwords: false, - matchwildcards: false, - }; - // search text box - srch = $("") - .addClass("JS9SearchInput") - .appendTo(bar); - // event fires with each keystroke - srch.on("input", () => { - search(srch.val()); - }); - // placeholder hints - if( bar.opts.matchwildcards ){ - srch.prop("placeholder", "sea*rch template?"); - } else { - srch.prop("placeholder", "search term(s)"); - } - // find next occurence - next = $("
    %s
    "; - -// get an id based on the action -JS9.Keyboard.actionid = function(cname, aname){ - return (`${cname}_${aname}`).replace(/[^A-Za-z0-9_]/g, "_"); -}; - -// add to the action list -JS9.Keyboard.addAction = function(container, cname, aname){ - let s, id, divjq; - id = JS9.Keyboard.actionid(cname, aname); - // create the html for this action - s = sprintf(JS9.Keyboard.actionHTML, aname, cname, aname); - // add action html to the action container - divjq = $("
    ") - .attr("id", id) - .html(s) - .appendTo(container); - divjq.find('.JS9KeyboardButton').on("click", (evt) => { - const action = evt.currentTarget.value; - const im = this.display.image; - if( im && action && JS9.Keyboard.Actions[action] ){ - JS9.Keyboard.Actions[action](im, im.ipos, evt); - } - }); - return divjq; -}; - -// common code for arrow key processing -JS9.Keyboard.arrowKey = function(im, evt, inc, active){ - let cpos; - // change display and image position, redisplay magnifier - im.pos.x += inc.x; - im.pos.y += inc.y; - im.ipos = im.displayToImagePos(im.pos); - if( {}.hasOwnProperty.call(JS9, "MouseTouch") ){ - im.valpos = null; - JS9.MouseTouch.Actions["display value/position"](im, im.ipos, evt); - } - if( {}.hasOwnProperty.call(JS9, "Magnifier") && !active ){ - JS9.Magnifier.display(im, im.ipos); - } - if( JS9.globalOpts.regArrowCrosshair && - {}.hasOwnProperty.call(JS9, "Crosshair") ){ - im.tmp.arrowCrosshair = true; - im.tmp.arrowCrosshairVisible = true; - if( active ){ - if( active.pub ){ - if( active.pub.shape === "polygon" && - active.pub.pts && active.pub.pts.length > 1 ){ - cpos = JS9.centroidPolygon(active.pub.pts); - } else { - cpos = {x: active.pub.x, y: active.pub.y}; - } - JS9.Crosshair.display(im, cpos, evt); - } - } else { - JS9.Crosshair.display(im, im.ipos, evt); - } - delete im.tmp.arrowCrosshair; - } -}; - -// --------------------------------------------------------------------- -// -// Keyboard.Actions: callbacks when on key press -// -// the keyboardActions array is in JS9.globalOpts determine -// the initial mapping of keyboard configuration to callback, e.g.: -// -// JS9.globalOpts.keyboardActions = {'?': 'copy valpos to clipboard', -// '/': 'copy wcs coords to clipboard', -// ... -// }; -// -// You can add your own to the Keyboard.Actions object and use them in the -// globalOpts.keyboardActions object -// -// --------------------------------------------------------------------- -JS9.Keyboard.Actions = {}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["open local file"] = function(im, ipos, evt){ - let display; - if( im ){ - display = im.display; - } else if( evt && typeof evt.data === "object" ){ - display = evt.data; - } - if( display ){ - if( window.isElectron && typeof evt.data === "object" ){ - display.displayLoadForm(); - } else { - JS9.OpenFileMenu({display}); - } - } -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["close image"] = function(im, ipos, evt){ - if( im ){ - im.closeImage(); - } -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["new JS9 light window"] = function(im, ipos, evt){ - let opts; - let display; - if( im ){ - display = im.display; - } else if( evt && typeof evt.data === "object" ){ - display = evt.data; - } - if( display ){ - opts = {clone: display.id}; - } - JS9.LoadWindow(null, opts, "light"); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["copy wcs position to clipboard"] = function(im, ipos, evt){ - let s, arr, opts; - // sanity check - if( !im || !im.raw.wcs || !ipos ){ - return; - } - // get wcs coords of current position - s = JS9.pix2wcs(im.raw.wcs, ipos.x, ipos.y).trim(); - if( JS9.globalOpts.copyWcsPosFormat ){ - arr = s.split(/\s+/); - opts = [{name: "ra", value: arr[0]}, - {name: "dec", value: arr[1]}, - {name: "sys", value: arr[2]}]; - s = im.expandMacro(JS9.globalOpts.copyWcsPosFormat, opts); - } - // copy to clipboard - JS9.CopyToClipboard(s, im); - return s; -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["copy physical position to clipboard"] = function(im, ipos, evt){ - let phys, s; - // sanity check - if( !im || !ipos ){ - return; - } - // get physical coords from image coords - phys = im.imageToLogicalPos(ipos); - s = sprintf("%f %f", phys.x, phys.y); - // copy to clipboard - JS9.CopyToClipboard(s, im); - return s; -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["copy pixel value to clipboard"] = function(im, ipos, evt){ - let s, val, prec; - // sanity check - if( !im || !ipos ){ - return; - } - // value at current position - val = im.raw.data[Math.floor(ipos.y-0.5) * im.raw.width + - Math.floor(ipos.x-0.5)]; - prec = JS9.floatPrecision(im.params.scalemin, im.params.scalemax); - s = JS9.floatFormattedString(val, prec, 3); - // copy to clipboard - JS9.CopyToClipboard(s, im); - return s; -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["copy value and position to clipboard"] = function(im, ipos, evt){ - let s, key, ovalpos; - // sanity check - if( !im || !ipos ){ - return; - } - // set valpos in case its turned off - ovalpos = im.setParam("valpos", true); - // get current valpos - s = im.updateValpos(ipos, false); - // restore original valpos - im.setParam("valpos", ovalpos); - // process valpos string - key = `vstr${ JS9.globalOpts.valposWidth}`; - if( s && s[key]){ - // reformat from html to text - s = s[key].replace(/ /g, " "); - } else { - // use blank space (otherwise, nothing is copied) - s = " "; - } - // copy to clipboard - JS9.CopyToClipboard(s, im); - return s; -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["edit selected region(s)"] = function(im, ipos, evt){ - let layer, ao; - // sanity check - if( !im ){ - return; - } - layer = im.layers.regions; - if( layer ){ - ao = layer.canvas.getActiveObject(); - if( ao && ao.type !== "activeSelection" ){ - // no active selection, edit this region - im.displayRegionsForm(ao); - } else { - // active selection or no regions: multi - im.displayRegionsForm(null, {multi: true}); - } - } -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["add last region selected in regions menu"] = function(im, ipos, evt){ - let opts = {ireg: true}; - let key = JS9.globalOpts.regMenuSelected || "circle"; - // sanity check - if( !im ){ - return; - } - opts.x = ipos.x; - opts.y = ipos.y; - return im.addShapes("regions", key, opts); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["toggle selected region: source/background"] = function(im, ipos, evt){ - // sanity check - if( !im ){ - return; - } - return im.toggleRegionTags("selected", "source", "background"); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["toggle selected region: include/exclude"] = function(im, ipos, evt){ - // sanity check - if( !im ){ - return; - } - return im.toggleRegionTags("selected", "include", "exclude"); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["tag selected region as 'source'"] = function(im, ipos, evt){ - // sanity check - if( !im ){ - return; - } - return JS9.Keyboard.editregion(im, "source", "background"); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["tag selected region as 'background'"] = function(im, ipos, evt){ - // sanity check - if( !im ){ - return; - } - return JS9.Keyboard.editregion(im, "background", "source"); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["tag selected region as 'include'"] = function(im, ipos, evt){ - // sanity check - if( !im ){ - return; - } - return JS9.Keyboard.editregion(im, "include", "exclude"); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["tag selected region as 'exclude'"] = function(im, ipos, evt){ - // sanity check - if( !im ){ - return; - } - return JS9.Keyboard.editregion(im, "exclude", "include"); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["toggle full screen mode"] = function(im, ipos, evt){ - let display; - if( im ){ - display = im.display; - } else if( evt && typeof evt.data === "object" ){ - display = evt.data; - } - if( display ){ - if( (display.width === display.width0) && - (display.height === display.height0) ){ - display.resize("full", {center: true}); - } else { - display.resize("reset"); - } - } -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["reset zoom"] = function(im, ipos, evt){ - // sanity check - if( !im ){ - return; - } - im.setZoom("1"); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["zoom in"] = function(im, ipos, evt){ - // sanity check - if( !im ){ - return; - } - im.setZoom("*2"); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["zoom out"] = function(im, ipos, evt){ - // sanity check - if( !im ){ - return; - } - im.setZoom("/2"); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["display next image"] = function(im, ipos, evt){ - // sanity check - if( !im ){ - return; - } - im.display.nextImage(1); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["display previous image"] = function(im, ipos, evt){ - // sanity check - if( !im ){ - return; - } - im.display.nextImage(-1); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["open a local FITS file"] = function(im, ipos, evt){ - let display; - if( im ){ - display = im.display; - } else if( evt && typeof evt.data === "object" ){ - display = evt.data; - } - if( display ){ - JS9.OpenFileMenu({display}); - } -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["save image as a FITS file"] = function(im, ipos, evt){ - // sanity check - if( !im ){ - return; - } - im.saveFITS(); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["save image as a PNG file"] = function(im, ipos, evt){ - // sanity check - if( !im ){ - return; - } - im.savePNG(); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["save regions as a text file"] = function(im, ipos, evt){ - // sanity check - if( !im ){ - return; - } - im.saveRegions(); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["move region/position up"] = function(im, ipos, evt){ - let canvas, layerName, active; - let inc = JS9.globalOpts.arrowIncrement; - if( evt ){ - evt.preventDefault(); - } - // sanity check - if( !im ){ return; } - layerName = im.layer || "regions"; - canvas = im.display.layers[layerName].canvas; - active = canvas.getActiveObject(); - if( active && !active.lockMovementY ) { - im.changeShapes(layerName, "selected", {deltay: inc}); - } - JS9.Keyboard.arrowKey(im, evt, {x: 0, y: inc * -1}, active); - canvas.fire("mouse:up"); - if( JS9.globalOpts.extendedPlugins ){ - im.xeqPlugins("keydown", "onarrowkey", evt); - } -}; - -JS9.Keyboard.Actions["move region/position down"] = function(im, ipos, evt){ - let canvas, layerName, active; - let inc = -JS9.globalOpts.arrowIncrement; - if( evt ){ - evt.preventDefault(); - } - // sanity check - if( !im ){ return; } - layerName = im.layer || "regions"; - canvas = im.display.layers[layerName].canvas; - active = canvas.getActiveObject(); - if( active && !active.lockMovementY ) { - im.changeShapes(layerName, "selected", {deltay: inc}); - } - JS9.Keyboard.arrowKey(im, evt, {x: 0, y: inc * -1}, active); - canvas.fire("mouse:up"); - if( JS9.globalOpts.extendedPlugins ){ - im.xeqPlugins("keydown", "onarrowkey", evt); - } -}; - -JS9.Keyboard.Actions["move region/position left"] = function(im, ipos, evt){ - let canvas, layerName, active; - let inc = -JS9.globalOpts.arrowIncrement; - if( evt ){ - evt.preventDefault(); - } - // sanity check - if( !im ){ return; } - layerName = im.layer || "regions"; - canvas = im.display.layers[layerName].canvas; - active = canvas.getActiveObject(); - if( active && !active.lockMovementX ) { - im.changeShapes(layerName, "selected", {deltax: inc}); - } - JS9.Keyboard.arrowKey(im, evt, {x: inc, y: 0}, active); - canvas.fire("mouse:up"); - if( JS9.globalOpts.extendedPlugins ){ - im.xeqPlugins("keydown", "onarrowkey", evt); - } -}; - -JS9.Keyboard.Actions["move region/position right"] = function(im, ipos, evt){ - let canvas, layerName, active; - let inc = JS9.globalOpts.arrowIncrement; - if( evt ){ - evt.preventDefault(); - } - // sanity check - if( !im ){ return; } - layerName = im.layer || "regions"; - canvas = im.display.layers[layerName].canvas; - active = canvas.getActiveObject(); - if( active && !active.lockMovementX ) { - im.changeShapes(layerName, "selected", {deltax: inc}); - } - JS9.Keyboard.arrowKey(im, evt, {x: inc, y: 0}, active); - canvas.fire("mouse:up"); - if( JS9.globalOpts.extendedPlugins ){ - im.xeqPlugins("keydown", "onarrowkey", evt); - } -}; -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["remove selected region"] = function(im, ipos, evt){ - let canvas, layerName; - if( evt ){ - evt.preventDefault(); - } - // sanity check - if( !im ){ return; } - layerName = im.layer || "regions"; - canvas = im.display.layers[layerName].canvas; - im.removeShapes(layerName, "selected"); - im.display.clearMessage(layerName); - canvas.fire("mouse:up"); -}; - -JS9.Keyboard.Actions["raise region layer to top"] = function(im, ipos, evt){ - if( evt ){ - evt.preventDefault(); - } - // sanity check - if( !im ){ return; } - im.activeShapeLayer("regions"); -}; - -JS9.Keyboard.Actions["toggle active shape layers"] = function(im, ipos, evt){ - if( evt ){ - evt.preventDefault(); - } - // sanity check - if( !im ){ return; } - im.toggleShapeLayers(); -}; - -JS9.Keyboard.Actions["send selected region to back"] = function(im, ipos, evt){ - if( evt ){ - evt.preventDefault(); - } - // sanity check - if( !im ){ return; } - im.changeShapes("regions", "selected", {send: "back"}); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["copy region(s) to clipboard"] = function(im, ipos, evt){ - let s; - // sanity check - if( !im ){ return; } - // get selected or all region(s) - s = im.listRegions(null, {mode: 1}); - // copy to clipboard - JS9.CopyToClipboard(s, im); - return s; -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["copy selected region(s) to clipboard"] = function(im, ipos, evt){ - let s; - // sanity check - if( !im ){ return; } - // get selected region(s) - s = im.listRegions("selected", {mode: 1}); - // copy to clipboard - JS9.CopyToClipboard(s, im); - return s; -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["copy all regions to clipboard"] = function(im, ipos, evt){ - let s; - // sanity check - if( !im ){ return; } - // get all regions - s = im.listRegions("all", {mode: 1}); - // copy to clipboard - JS9.CopyToClipboard(s, im); - return s; -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["paste regions from local clipboard"] = function(im, ipos, evt){ - return JS9.Regions.pasteFromClipboard.call(im, false); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["paste regions to current position"] = function(im, ipos, evt){ - return JS9.Regions.pasteFromClipboard.call(im, true); -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["undo remove of region(s)"] = function(im, ipos, evt){ - if( im ){ - im.unremoveRegions(); - } -}; - -// eslint-disable-next-line no-unused-vars -JS9.Keyboard.Actions["select region"] = function(im, ipos, evt){ - let i, layer, canvas, obj, objs; - // sanity check - if( !im ){ return; } - layer = im.layer || "regions"; - canvas = im.layers[layer].canvas; - objs = canvas.getObjects(); - for(i=0; i") - .addClass(`${JS9.Keyboard.BASE}Container`) - .attr("id", `${this.id}KeyboardContainer`) - .appendTo(this.divjq); - s = `
    Keys and their actions (or click the buttons):

    `; - this.keyboardHeadContainer = $("

    ") - .addClass(`${JS9.Keyboard.BASE}Container`) - .attr("id", `${this.id}KeyboardHeadContainer`) - .html(s) - .appendTo(this.keyboardContainer); - // container to hold keyboard actions - this.keyboardActionContainer = $("
    ") - .addClass(`${JS9.Keyboard.BASE}ActionContainer`) - .attr("id", `${this.id}ActionContainer`) - .html("") - .appendTo(this.keyboardContainer); - // add actions - for( key of Object.keys(JS9.globalOpts.keyboardActions) ){ - s = JS9.globalOpts.keyboardActions[key]; - JS9.Keyboard.addAction.call(this, this.keyboardActionContainer, key, s); - } - }; - -JS9.RegisterPlugin(JS9.Keyboard.CLASS, JS9.Keyboard.NAME, - JS9.Keyboard.init, - {menuItem: "Keyboard Actions", - onplugindisplay: JS9.Keyboard.init, - help: "help/keyboard.html", - winTitle: "Keyboard Actions", - winResize: true, - winDims: [JS9.Keyboard.WIDTH,JS9.Keyboard.HEIGHT]}); diff --git a/web/static/js9_old/plugins/core/layers.css b/web/static/js9_old/plugins/core/layers.css deleted file mode 100644 index be0f4da373e4ea708172f03ba704de78e2e25f8b..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/core/layers.css +++ /dev/null @@ -1,39 +0,0 @@ -div.JS9LayersContainer { - padding: 2px; -} - -div.JS9LayersHeader { - border: 0px solid black; - background: #E9E9E9; - padding: 0px; - margin-left: 15px; - margin-top: 5px; - margin-right: 5px; - margin-bottom: 0px; -} - -div.JS9LayersLayer { - margin: 5px; - background: #E9E9E9; - overflow: auto; -} - -div.JS9LayersLayerInactive { - padding: 10px; - border: 1px solid black; -} - -div.JS9LayersLayerActive { - padding: 9px; - border: 2px solid #00F000; -} - -span.JS9LayersSpan { - float: right; - margin-right: 10px; -} - -span.JS9NoLayers { - margin-left: 15px; -} - diff --git a/web/static/js9_old/plugins/core/layers.js b/web/static/js9_old/plugins/core/layers.js deleted file mode 100644 index b994b1eef71aba324a5131b55c8ba9fdf92688e1..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/core/layers.js +++ /dev/null @@ -1,290 +0,0 @@ -/* - * shape layer plugin (October 7, 2016) - */ - -/*global $, JS9, sprintf */ - -"use strict"; - -// create our namespace, and specify some meta-information and params -JS9.Layers = {}; -JS9.Layers.CLASS = "JS9"; // class of plugins (1st part of div class) -JS9.Layers.NAME = "Layers"; // name of this plugin (2nd part of div class) -JS9.Layers.WIDTH = 460; // width of light window -JS9.Layers.HEIGHT = 250; // height of light window -JS9.Layers.BASE = JS9.Layers.CLASS + JS9.Layers.NAME; // CSS base class name - -JS9.Layers.headerHTML='Shape layers can be hidden or made visible below. The topmost visible layer in the stack is active: it responds to mouse and touch events. Move a layer to the top of the stack to make it active.'; - -JS9.Layers.layerHTML="$visible  $save  $color   $layer  "; - -JS9.Layers.nolayersHTML='

    [Layers will appear here as they are created]'; - -JS9.Layers.visibleHTML='visible'; - -JS9.Layers.saveBothHTML=''; - -JS9.Layers.saveRegionsHTML=''; - -JS9.Layers.colorHTML=''; - -JS9.Layers.layerNameHTML='%s'; - -// get an id based on the file image id and layer -JS9.Layers.imid = function(im, layer){ - const id = `${im.display.id}_${im.id}_${layer}_`; - return `${id.replace(/[^A-Za-z0-9_]/g, "_")}Layer`; -}; - -// get a class unique between displays -JS9.Layers.dispclass = function(im){ - const id = `${JS9.Layers.BASE}_${im.display.id}`; - return id.replace(/[^A-Za-z0-9_]/g, "_"); -}; - -// change the active image -JS9.Layers.activeLayer = function(im, pinst){ - let i, s, id, dcls, order; - if( im ){ - order = pinst.layersLayerContainer.sortable("toArray"); - if( (order.length === 1) && !order[0] ){ - return; - } - for(i=0; i 1 ){ - l = `${layer} layer [zindex: ${zindex}]`; - } else { - l = `${layer} layer`; - } - opts.push({name: "layer", value: sprintf(JS9.Layers.layerNameHTML, l)}); - // create the html for this layer - s = JS9.Image.prototype.expandMacro.call(im, JS9.Layers.layerHTML, opts); - // add layer html to the layer container - divjq = $("

    ") - .addClass(cls) - .addClass(dcls) - .attr("id", id) - .attr("layer", layer) - .prop("imid", imid) - .html(s); - if( !this.nlayer ){ - divjq.appendTo(this.layersLayerContainer); - } else { - this.layersLayerContainer.find(`.${cls}`).each((idx, item) => { - let tlayer, tzindex; - const jqitem = $(item); - if( !added ){ - tlayer = jqitem.attr("layer"); - if( tlayer ){ - tzindex = parseInt(im.display.layers[tlayer].divjq - .css("z-index"), 10); - if( Math.abs(zindex) > Math.abs(tzindex) ){ - divjq.insertBefore(jqitem); - added = true; - } - } - } - }); - if( !added ){ - divjq.appendTo(this.layersLayerContainer); - } - } - // set of unset visibility buton - divjq.find(".JS9LayersVisibleCheck").prop("checked", !!im.layers[layer].show); - // another layer was added - this.nlayer++; -}; - -// init when a different image is displayed -JS9.Layers.display = function(){ - if( this.lastimage !== this.display.image ){ - JS9.Layers.init.call(this); - } -}; - -// clear when an image closes -JS9.Layers.close = function(){ - // ensure plugin display is reset - JS9.Layers.init.call(this, {mode: "clear"}); -}; - -// constructor: add HTML elements to the plugin -JS9.Layers.init = function(opts){ - let key, im; - // on entry, these elements have already been defined: - // this.div: the DOM element representing the div for this plugin - // this.divjq: the jquery object representing the div for this plugin - // this.id: the id ofthe div (or the plugin name as a default) - // this.display: the display object associated with this plugin - // this.dispMode: display mode (for internal use) - // - // opts is optional - opts = opts || {}; - // create container to hold layer container and header - // clean main container - this.divjq.html(""); - // no layers yet - this.nlayer = 0; - // allow scrolling on the plugin - this.divjq.addClass("JS9PluginScrolling"); - // main container - this.layersContainer = $("
    ") - .addClass(`${JS9.Layers.BASE}Container`) - .attr("id", `${this.id}LayersContainer`) - .css("overflow", "auto") - .appendTo(this.divjq); - // header - this.layersHeader = $("
    ") - .addClass(`${JS9.Layers.BASE}Header`) - .attr("id", `${this.display.id}Header`) - .html(JS9.Layers.headerHTML) - .appendTo(this.layersContainer); - // container to hold layers - this.layersLayerContainer = $("
    ") - .addClass(`${JS9.Layers.BASE}LayerContainer`) - .attr("id", `${this.id}LayersLayerContainer`) - .html(JS9.Layers.nolayersHTML) - .appendTo(this.layersContainer); - // done if we are only clearing - if( opts.mode === "clear" ){ - return; - } - // add current shape layers - if( this.display.image ){ - im = this.display.image; - for( key of Object.keys(im.layers) ){ - if( key === "crosshair" || key === "grid" ){ - continue; - } - JS9.Layers.addLayer.call(this, im, key); - } - this.lastimage = im; - } - // the layers within the layer container will be sortable - // the top one responds to events - this.layersLayerContainer.sortable({ - // eslint-disable-next-line no-unused-vars - start: (event, ui) => { - return; - }, - // eslint-disable-next-line no-unused-vars - stop: (event, ui) => { - JS9.Layers.activeLayer(im, this); - return; - } - }); - // set initial active layer - JS9.Layers.activeLayer(im, this); -}; - -// add this plugin into JS9 -JS9.RegisterPlugin(JS9.Layers.CLASS, JS9.Layers.NAME, JS9.Layers.init, - {menuItem: "Shape Layers", - onplugindisplay: JS9.Layers.init, - onshapelayercreate: JS9.Layers.init, - onshapelayershow: JS9.Layers.init, - onshapelayeractive: JS9.Layers.init, - onshapelayerhide: JS9.Layers.init, - onimageload: JS9.Layers.init, - onimagedisplay: JS9.Layers.display, - onimageclose: JS9.Layers.close, - help: "help/layers.html", - winTitle: "Shape Layers", - winResize: true, - winDims: [JS9.Layers.WIDTH, JS9.Layers.HEIGHT]}); diff --git a/web/static/js9_old/plugins/core/magnifier.js b/web/static/js9_old/plugins/core/magnifier.js deleted file mode 100644 index 190cc7e9e9d7ffa68a9a00716bbf13dd291156a7..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/core/magnifier.js +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Magnifier plugin - */ - -/*global $, JS9, fabric */ - -"use strict"; - -// create our namespace, and specify some meta-information and params -JS9.Magnifier = {}; -JS9.Magnifier.CLASS = "JS9"; -JS9.Magnifier.NAME = "Magnifier"; -JS9.Magnifier.WIDTH = JS9.WIDTH/2; // width of light window -JS9.Magnifier.HEIGHT = JS9.HEIGHT/2; // height of light window -JS9.Magnifier.SWIDTH = 250; // width of div -JS9.Magnifier.SHEIGHT = 250; // height of div - -// defaults for magnifier -JS9.Magnifier.opts = { - // override fabric defaults - originX: "left", - originY: "top", - hasControls: false, - hasRotatingPoint: false, - hasBorders: false, - selectable: false, - // initial magnifier zoom - zoom: 4, - // canvas options - canvas: { - selection: false - }, - // magnifier box colors - tagcolors: { - defcolor: "#00FF00" - } -}; - -// call a JS9 routine from a button in the magnifier plugin toolbar -// the plugin instantiation saves the display id in the toolbar div -JS9.Magnifier.bcall = function(...args){ - let dispid, im; - let [which, cmd, arg1] = args; - // the button plugintoolbar div has data containing the id of the display - dispid = $(which).closest("div[class^=JS9PluginToolbar]").data("displayid"); - if( dispid ){ - im = JS9.getImage(dispid); - } else { - JS9.error(`can't find display for cmd: ${cmd}`); - } - if( !im ){ - JS9.error(`can't find image for cmd: ${cmd}`); - } - switch(cmd){ - case "zoomMagnifier": - if( args.length < 3 ){ - JS9.error(`missing arg(s) for cmd: ${cmd}`); - } - try{ - JS9.Magnifier.zoom(im, arg1); - } catch(e){ - JS9.error("error calling zoomMagnifier()", e); - } - break; - default: - break; - } -}; - -// html used by the magnifier plugin -JS9.Magnifier.HTML = -`${"" + -"" + -"" + -"` + -``; - -// JS9 Magnifier constructor -JS9.Magnifier.init = function(width, height){ - // set width and height on div - this.width = this.divjq.attr("data-width"); - if( !this.width ){ - this.width = width || JS9.Magnifier.WIDTH; - } - this.divjq.css("width", this.width); - this.width = parseInt(this.divjq.css("width"), 10); - this.height = this.divjq.attr("data-height"); - if( !this.height ){ - this.height = height || JS9.Magnifier.HEIGHT; - } - this.divjq.css("height", this.height); - this.height = parseInt(this.divjq.css("height"), 10); - // create DOM canvas element - this.canvas = document.createElement("canvas"); - // jquery version for event handling and DOM manipulation - this.canvasjq = $(this.canvas); - // set class - this.canvasjq.addClass("JS9Magnifier"); - // required so graphical layers will be on top: - this.canvasjq.css("z-index", JS9.ZINDEX); - // how do we allow users to set the size of the canvas?? - // it doesn't go into the CSS and we have no canvas on the Web page ... - this.canvasjq.attr("width", this.width); - this.canvasjq.attr("height", this.height); - // drawing context - this.context = this.canvas.getContext("2d"); - // turn off anti-aliasing - if( !JS9.ANTIALIAS ){ - this.context.imageSmoothingEnabled = false; - } - // add container with canvas to the high-level div - this.containerjq = $("
    ") - .addClass("JS9Container") - .append(this.canvasjq) - .appendTo(this.divjq); - // add magnifier graphics layer to the display - // the magnifier will be appended to the div of the plugin - this.display.newShapeLayer("magnifier", JS9.Magnifier.opts, this.divjq); -}; - -// display the magnified image on the magnifier canvas -JS9.Magnifier.display = function(im, ipos){ - let pos, tval, magDisp, zoom; - let canvas, sx, sy, sw, sh, dx, dy, dw, dh; - // sanity check - // only display if we have a magnifier present - if(!im || !im.display.pluginInstances.JS9Magnifier || - (im.display.pluginInstances.JS9Magnifier.status !== "active")){ - return; - } - // don't display if a mouse button is pressed while moving, or - // if two or more touch buttons are pressed while moving - if( (im.clickState > 0) || (im.clickState < -1) ){ - return; - } - // image init: add magnifier object to image, if necessary - if( !im.magnifier ){ - im.magnifier = {zoom: JS9.Magnifier.opts.zoom, posx: 0, posy: 0}; - } - magDisp = im.display.pluginInstances.JS9Magnifier; - canvas = im.display.canvas; - zoom = im.magnifier.zoom; - sw = Math.floor(magDisp.width / zoom); - sh = Math.floor(magDisp.height / zoom); - if( ipos ){ - pos = im.imageToDisplayPos(ipos); - sx = pos.x - (sw/2); - sy = pos.y - (sh/2); - im.magnifier.posx = sx; - im.magnifier.posy = sy; - } else { - sx = im.magnifier.posx; - sy = im.magnifier.posy; - } - // default destination parameters - dx = 0; - dy = 0; - dw = magDisp.canvas.width; - dh = magDisp.canvas.height; - // adjust for boundaries - if( sx < 0 ){ - sw += sx; - dx -= (sx * zoom); - dw += (sx * zoom); - sx = 0; - } - tval = (sx + sw) - canvas.width; - if( tval > 0 ){ - sw -= tval; - dw = sw * zoom; - } - if( sy < 0 ){ - sh += sy; - dy -= (sy * zoom); - dh += (sy * zoom); - sy = 0; - } - tval = sy + sh- canvas.height; - if( tval > 0 ){ - sh -= tval; - dh = sh * zoom; - } - // display magnifier image - magDisp.context.clear(); - magDisp.context.drawImage(canvas, sx, sy, sw, sh, dx, dy, dw, dh); - // overlay regions by drawing the fabric.js canvas into the magnifier - if( JS9.globalOpts.magnifierRegions && - im.display.layers && im.display.layers.regions ){ - // get underlying html canvas - canvas = im.display.layers.regions.canvas.getElement(); - sx *= fabric.devicePixelRatio; - sy *= fabric.devicePixelRatio; - sw *= fabric.devicePixelRatio; - sh *= fabric.devicePixelRatio; - // write it into the magnifier display - magDisp.context.drawImage(canvas, sx, sy, sw, sh, dx, dy, dw, dh); - } - // stuff we only do once - if( !im.magnifier.boxid ){ - // add the center point to the magnifier, if necessary - im.magnifier.boxid = im.addShapes("magnifier", "box"); - // make background black, which looks better at the edge - $(magDisp.canvas).css("background-color", "black"); - } - // center point size and position, based on zoom - // (subtract 1 to center the box on the pixel 2/4/2020) - if( im.magnifier.ozoom !== zoom ){ - im.changeShapes("magnifier", im.magnifier.boxid, - {left: magDisp.width/2-1, top: magDisp.height/2-1, - width: zoom, height: zoom}); - im.magnifier.ozoom = im.magnifier.zoom; - } -}; - -// display the magnified image on the magnifier canvas -// this routine is called when regions change ... it delays the mag display -// until the main display can be redrawn with the changed regions. Initially, -// this routine explicitly called the fabric.js renderAll() routine so that -// the changed regions would be drawn on the canvas. This did not work when -// removing groups (artifacts were left on the screen). For related problems -// and warnings associated with working with groups, see: -// http://fabricjs.com/v2-breaking-changes-2 -JS9.Magnifier.display2 = function(im, ipos){ - window.setTimeout(() => { - JS9.Magnifier.display(im, ipos); - }, 0); -}; - -// zoom the rectangle inside the magnifier (RGB) image -// part of magnifier plugin -JS9.Magnifier.zoom = function(im, zval){ - let magnifier, ozoom, nzoom; - // sanity check - if( !im || !im.magnifier ){ - return; - } - magnifier = im.magnifier; - // get old zoom - ozoom = magnifier.zoom; - // determine new zoom - switch(zval.charAt(0)){ - case "x": - case "*": - nzoom = ozoom * parseFloat(zval.slice(1)); - break; - case "/": - nzoom = ozoom / parseFloat(zval.slice(1)); - break; - default: - nzoom = parseFloat(zval); - break; - } - // sanity check - if( !nzoom || (nzoom < 1) ){ - nzoom = 1; - } - // save old value, set new value - magnifier.ozoom = magnifier.zoom; - magnifier.zoom = nzoom; - // redisplay - JS9.Magnifier.display(im); -}; - -// clear the magnifier -JS9.Magnifier.clear = function(im){ - const magnifier = im.display.pluginInstances.JS9Magnifier; - if( magnifier && (im === im.display.image) ){ - magnifier.context.clear(); - im.removeShapes("magnifier", "all"); - im.magnifier.boxid = null; - im.magnifier.ozoom = 0; - // restore original background color - $(magnifier.canvas).css("background-color", "#E9E9E9"); - } - return im; -}; - -// add plugin to JS9 -JS9.RegisterPlugin(JS9.Magnifier.CLASS, JS9.Magnifier.NAME, JS9.Magnifier.init, - {menuItem: "Magnifier", - help: "help/magnifier.html", - dynamicSelect: true, - toolbarSeparate: false, - toolbarHTML: JS9.Magnifier.HTML, - onplugindisplay: JS9.Magnifier.display, - onregionsmove: JS9.Magnifier.display, - onregionschange: JS9.Magnifier.display2, - onmousemove: JS9.Magnifier.display, - onimagedisplay: JS9.Magnifier.display, - onimageclose: JS9.Magnifier.clear, - onimageclear: JS9.Magnifier.clear, - winTitle: "Magnifier", - winDims: [JS9.Magnifier.WIDTH, JS9.Magnifier.HEIGHT], - divArgs: [JS9.Magnifier.SWIDTH, JS9.Magnifier.SHEIGHT]}); diff --git a/web/static/js9_old/plugins/core/mef.css b/web/static/js9_old/plugins/core/mef.css deleted file mode 100644 index 585a16b719881c8ec0841968665464a9b484a2e6..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/core/mef.css +++ /dev/null @@ -1,42 +0,0 @@ -.JS9MefContainer { - padding: 10px; - overflow: auto; -} - -.JS9MefExtension { - margin: 5px; - background: #E9E9E9; - overflow: auto; - font-size: 10pt; -} - -.JS9MefHeader { - margin: 5px; - background: #E9E9E9; -} - -.JS9MefInput { - margin: 5px; - background: #E9E9E9; -} - -.JS9MefExtensionInactive { - padding: 0px; - border: 1px solid black; -} - -.JS9MefExtensionActive { - padding: 0px; - border: 2px solid #00F000; -} - -span.JS9MefStrike{ - font-weight:bold; /*set line weight here*/ - color:red; - text-decoration:line-through; -} - -span.JS9MefStrike>span { - font-weight:normal; - color: black; -} \ No newline at end of file diff --git a/web/static/js9_old/plugins/core/mef.js b/web/static/js9_old/plugins/core/mef.js deleted file mode 100644 index 7339036036b412d057633838149d4150817c58ef..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/core/mef.js +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Multi-Extension FITS module (March 31, 2016) - */ - -/*global $, JS9 */ - -"use strict"; - -// create our namespace, and specify some meta-information and params -JS9.Mef = {}; -JS9.Mef.CLASS = "JS9"; // class of plugins (1st part of div class) -JS9.Mef.NAME = "Mef"; // name of this plugin (2nd part of div class) -JS9.Mef.WIDTH = 800; // width of light window -JS9.Mef.HEIGHT = 240; // height of light window -JS9.Mef.BASE = JS9.Mef.CLASS + JS9.Mef.NAME; // CSS base class name - -// change global separate mode for this display -JS9.Mef.xseparate = function(id, target){ - const display = JS9.lookupDisplay(id); - const separate = target.checked; - // change separate mode for this instance - if( display ){ - display.pluginInstances[JS9.Mef.BASE].separate = separate; - } -}; - -// load all images -// eslint-disable-next-line no-unused-vars -JS9.Mef.xall = function(id, target){ - const display = JS9.lookupDisplay(id); - // display all image extensions - if( display && display.image ){ - display.pluginInstances[JS9.Mef.BASE].separate = true; - display.image.displayExtension("all"); - } -}; - -// get an MefExtension id based on the file image id -JS9.Mef.imid = function(im, i, noext){ - let id = `${im.display.id}_${im.id}`; - if( noext ){ - id = id.replace(/\[[a-zA-Z0-9][a-zA-Z0-9_]*\]/g,""); - } - return `${id.replace(/[^A-Za-z0-9_]/g, "_")}_MefExtension_${i}`; -}; - -// change the active extension -JS9.Mef.activeExtension = function(im, i){ - let clas, classbase; - if( im ){ - classbase = `${im.display.id}_${JS9.Mef.BASE}`; - $(`.${classbase }Extension`) - .removeClass(`${JS9.Mef.BASE}ExtensionActive`) - .addClass(`${JS9.Mef.BASE}ExtensionInactive`); - clas = JS9.Mef.imid(im, i, true); - $(`.${clas}` ) - .removeClass(`${JS9.Mef.BASE}ExtensionInactive`) - .addClass(`${JS9.Mef.BASE}ExtensionActive`); - } -}; - -// re-init when a different image is displayed -JS9.Mef.display = function(){ - if( this.lastimage !== this.display.image ){ - JS9.Mef.init.call(this); - } -}; - -// clear when an image closes -JS9.Mef.close = function(){ - // ensure plugin display is reset - JS9.Mef.init.call(this, {mode: "clear"}); -}; - -// constructor: add HTML elements to the plugin -JS9.Mef.init = function(opts){ - let i, im, id, clas, obj, s, sid, div, htmlString, classbase; - const addExt = (o, s, k) => { - let c, j; - let got = ""; - let doit = true; - switch(o.type){ - case "image": - // look for 2D image - if( o.naxes.length < 2 ){ - doit = false; - } - break; - case "table": - case "ascii": - // look for x and y columns - for(j=0; j  ${s}`; - } else { - htmlString = `
      ${s}
    `; - } - id = JS9.Mef.imid(im, k); - clas = JS9.Mef.imid(im, k, true); - classbase = `${im.display.id}_${JS9.Mef.BASE}`; - div = $("
    ") - .addClass(clas) - .addClass(`${classbase }Extension`) - .addClass(`${JS9.Mef.BASE }Extension`) - .addClass(`${JS9.Mef.BASE}ExtensionInactive`) - .attr("id", id) - .html(htmlString) - .appendTo(this.mefContainer); - if( doit ){ - div.on("mousedown touchstart", () => { - im.displayExtension(o.hdu, {separate: this.separate}); - JS9.Mef.activeExtension(im, o.hdu); - }); - } - }; - // on entry, these elements have already been defined: - // this.div: the DOM element representing the div for this plugin - // this.divjq: the jquery object representing the div for this plugin - // this.id: the id ofthe div (or the plugin name as a default) - // this.display: the display object associated with this plugin - // this.dispMode: display mode (for internal use) - // - // opts is optional - opts = opts || {}; - // allow scrolling on the plugin - this.divjq.addClass("JS9PluginScrolling"); - // clean main container - this.divjq.html(""); - // add mef container to main - this.mefContainer = $("
    ") - .addClass(`${JS9.Mef.BASE}Container`) - .attr("id", `${this.id}MefContainer`) - .appendTo(this.divjq); - // separate mode - if( this.separate === undefined ){ - this.separate = false; - } - im = this.display.image; - if( !im || (opts.mode === "clear") ){ - this.mefContainer.html("

    FITS HDU extensions will be displayed here.
    "); - return; - } - if( !im.hdus ){ - this.mefContainer.html("

    No FITS HDU extensions are present in this image.
    "); - return; - } - this.lastimage = im; - // reset main container - s = `
    Click on a FITS HDU extension to display it:`; - // add the checkbox for displaying each extension separately - sid = JS9.Mef.imid(im, "Separate"); - s += `   as a separate image
    `; - this.mefContainer.html(s); - // add a formatted string for each extension - for(i=0; i= 0 && !key.match(/^super_/) ){ - if( mode !== "all" && this.selectedDisplay ){ - // make sure display still exists - if( $.inArray(this.selectedDisplay, JS9.displays) >= 0 ){ - return [this.selectedDisplay]; - } - this.selectedDislay = null; - } - d = this.divjq.data("displays") || "*"; - s = d.split(","); - if( s[0] === "*" ){ - for(i=0; i= 0) || (disp === "all") ){ - if( JS9.bugs.webkit_resize ){ - $(".JS9").find(".JS9Image").removeClass("JS9Highlight"); - } else { - $(".JS9").removeClass("JS9Highlight"); - } - if( (disp === supermenu.selectedDisplay) || (disp === "all") ){ - // unselect - supermenu.selectedDisplay = null; - } else { - // select - supermenu.selectedDisplay = disp; - if( JS9.bugs.webkit_resize ){ - $(disp.divjq).find(".JS9Image").addClass("JS9Highlight"); - } else { - $(disp.divjq).addClass("JS9Highlight"); - } - } - } - } -}; - -// reset: invalidate the reverse key map when preferences change -// eslint-disable-next-line no-unused-vars -JS9.Menubar.reset = function(im){ - JS9.Menubar.rkeyMap = null; -}; - -// create the standard menus and user-defined menus -// each consists of a contextMenu() call and a "mousedown" callback -// to display the menu -JS9.Menubar.createMenus = function(){ - // eslint-disable-next-line no-unused-vars - const mypos = (opt, x, y) => { - let pos; - if( !{}.hasOwnProperty.call(window, "Jupyter") ){ - opt.$menu.position({ - my: 'left top', - at: JS9.globalOpts.menuPosition || "left bottom", - of: opt.$trigger, - collision: "fit" - }); - } else { - // Jupyter gets the wrong position when using $trigger ... - pos = opt.$trigger.offset(); - opt.$menu.css({"left": pos.left+20, "top": pos.top+10}); - } - }; - const onhide = () => { - const tdisp = this.display; - if( JS9.bugs.hide_menu && tdisp.image ){ - tdisp.image.displayImage("rgb"); - } - }; - const xname = (name, xact) => { - let key, hstr, tact; - let obj = {name: name}; - const gkeyActions = JS9.globalOpts.keyboardActions || {}; - const act = JS9.Menubar.keyMap[name]; - if( !JS9.Menubar.rkeyMap ){ - JS9.Menubar.rkeyMap = {}; - for( key of Object.keys(gkeyActions) ){ - JS9.Menubar.rkeyMap[gkeyActions[key]] = key; - } - JS9.Menubar.keyActions = $.extend(true, {}, gkeyActions); - } - if( JS9.notNull(act) && JS9.Menubar.rkeyMap ){ - key = JS9.Menubar.rkeyMap[act]; - if( key ){ - hstr = `${name}    ${key}`; - obj = {name: hstr, isHtmlName: true}; - } - } else if( xact && JS9.Menubar.rkeyMap ){ - for( tact of Object.keys(JS9.Menubar.rkeyMap) ){ - if( tact === xact ){ - key = JS9.Menubar.rkeyMap[tact]; - if( key ){ - hstr = `${name}    ${key}`; - obj = {name: hstr, isHtmlName: true}; - } - } - } - } - return obj; - }; - const xeqUserMenu = (evt) => { - const menu = evt.data; - evt.preventDefault(); - $(`#${menu.name}UserMenu${this.id}`).contextMenu(); - }; - const addUserMenu = (menu) => { - if( !menu || !menu.name || !menu.title || !menu.options ){ - return; - } - // define contextMenu actions - $.contextMenu({ - selector: `#${menu.name }UserMenu${this.id}`, - zIndex: JS9.MENUZINDEX, - events: { hide: onhide }, - position: mypos, - build: () => { - let i, opt, hstr, obj; - const items = {}; - for(i=0; i${opt.name}` + `  ${obj.name}
    `; - items[opt.name] = {name: hstr, isHtmlName: true}; - } else { - items[opt.name] = obj; - } - } - return { - callback: (key, kopt) => { - JS9.Menubar.getDisplays.call(this).forEach((val) => { - let i, s, args, hstr; - const udisp = val; - for(i=0; i${opt.name}` + `  ${opt.name}
    `; - } else if( menu.updateTitle === "image" ){ - hstr = `
    ${opt.name}
    `; - } - $(kopt.selector).html(hstr); - } else if( typeof menu.updateTitle === "function" ){ - try{ - s = menu.updateTitle(udisp.image, - menu.name, - opt.name); - } - catch(e){ s = (opt.name || menu.name); } - $(kopt.selector).text(s); - } else if( menu.updateTitle && opt.name ){ - $(kopt.selector).text(opt.name); - } - } - } else { - JS9.error(`unknown func for user menubar: ${opt.cmd}`); - } - } - }); - }, - items: items - }; - } - }); - }; - const addUserMenus = () => { - let i, menu; - if( JS9.globalOpts.userMenuBar ){ - for(i=0; i { - evt.preventDefault(); - $(`#fileMenu${this.id}`).contextMenu(); - }); - $.contextMenu({ - selector: `#fileMenu${this.id}`, - zIndex: JS9.MENUZINDEX, - events: { hide: onhide }, - position: mypos, - // 'click' prevents long menus from executing a random menu option - // it has to be put into the first context menu that is registered - itemClickEvent: JS9.globalOpts.menuClickEvent || "click", - build: () => { - let i, m, im, name, s1, arr, cdisp, got, iobj, cel; - let plugin, pname, pinst; - let lastxclass=""; - let n = 0; - const items = {}; - const tdisp = JS9.Menubar.getDisplays.call(this)[0]; - const tim = tdisp.image; - const imlen = JS9.images.length; - // the number of images in this display ... - for(i=0, got=0; i= JS9.globalOpts.imagesFileSubmenu ){ - items.filetitle = { - name: "Files and Displays:", - disabled: true - }; - } - // .. because images can be in top-level menu or a submenu - if( got && got < JS9.globalOpts.imagesFileSubmenu ){ - items.imagestitle = { - name: "Images:", - disabled: true - }; - iobj = items; - } else if( got ){ - items.images = { - name: "images ...", - items: { - imagestitle: { - name: "display this image:", - disabled: true - } - } - }; - iobj = items.images.items; - } - // add images from this display - for(i=0; i 0 && - tdisp !== JS9.displays[i] ){ - s1 = `moveto_${JS9.displays[i].id}`; - items.moveto.items[s1] = xname(JS9.displays[i].id); - } - } - items.moveto.items.moveto_newdisp = xname("a new display"); - } else { - items.moveto.disabled = true; - } - items.separates = { - name: "separate ...", - items: { - } - }; - if( !JS9.images.length ){ - items.separates.disabled = true; - } - items.separates.items.separate = xname("separate these images"); - if( !tim ){ - items.separates.items.separate.disabled = true; - } - items.separates.items.gather = xname("gather all images here"); - if( tim && JS9.images.length === 1 ){ - items.separates.items.gather.disabled = true; - } - items.saveas = { - name: "save ...", - items: { - saveastitle: { - name: "save all data as:", - disabled: true - }, - savefitsentire: xname("FITS"), - saveastitle2: { - name: "save displayed data as:", - disabled: true - }, - savefits: xname("FITS"), - savejpeg: xname("JPEG"), - savepng: xname("PNG"), - saveastitle3: { - name: "save memory file as:", - disabled: true - }, - savefitsvirtual: xname("FITS") - } - }; - if( !tim ){ - items.saveas.disabled = true; - } else if( !tim.raw.hdu || !tim.raw.hdu.fits || !tim.raw.hdu.fits.vfile ){ - items.saveas.items.savefitsvirtual.disabled = true; - } - items.closes = { - name: "close ...", - items: { - closestitle: { - name: "close:", - disabled: true - } - } - }; - if( !tim ){ - items.closes.disabled = true; - } - items.closes.items.close = xname("this image"); - items.closes.items.closeall = xname("all images"); - items.closes.items.free = xname("this image's memory"); - items.closes.items.removeproxy = xname("proxy file"); - if( !tim || !tim.raw || !tim.raw.hdu || !tim.raw.hdu.fits ){ - items.closes.items.free.disabled = true; - } - if( !tim || !tim.proxyFile ){ - items.closes.items.removeproxy.disabled = true; - } - items.catalogs = { - name: "catalog ...", - items: { - } - }; - if( !tim ){ - items.catalogs.disabled = true; - } - items.catalogs.items.loadcatalog = xname("load ..."); - items.catalogs.items.savecatalog = xname("save active"); - items.createmosaic = { - name: "mosaic ...", - items: { - createmosaictitle: { - name: "create a mosaic using:", - disabled: true - }, - mosaiccurrent: xname("images in the current file"), - mosaicdisplay: xname("images in this display") - } - }; - if( !tim ){ - items.createmosaic.disabled = true; - } - items.sessions = { - name: "session ...", - items: { - } - }; - items.sessions.items.loadsession = xname("load ..."); - items.sessions.items.savesession = { - name: "save ...", - items: { - savesessiontitle: { - name: "include these images:", - disabled: true - }, - savecurrent: xname("the current image"), - savedisplay: xname("all images in this display") - } - }; - items.windows = { - name: "window ...", - items: { - windowstitle: { - name: "create a new:", - disabled: true - } - } - }; - items.windows.items.lite = xname("light window"); - items.windows.items.xnew = xname("separate window"); - if( window.electron ){ - items.windows.items.xnew.disabled = true; - } - if( window.electron ){ - items.electronHelper = xname("connect to JS9 helper"); - if( JS9.helper.connected ){ - items.electronHelper.disabled = true; - } - } - // super menu - if( this.issuper ){ - arr = JS9.Menubar.getDisplays.call(this, "all"); - items.supermenu = { - name: "supermenu ...", - items: { - supertitle: { - name: "target this display:", - disabled: true - } - } - }; - for(i=0, m=0; i 0 && cel.find(".JS9GridItem").length > 1) ){ - items.removedisplay = xname("remove this display"); - } - items[`sep${n++}`] = "------"; - items.print = xname("print ..."); - if( !tim ){ - items.print.disabled = true; - } - if( window.electron ){ - items.windowPrint = xname("print window ..."); - items.windowPDF = xname("save window to pdf"); - if( window.electron.app ){ - items.saveScript = xname("export messaging script"); - } - } - // plugins - for(i=0; i { - let uplugin; - JS9.Menubar.getDisplays.call(this, "any", key) - .forEach((val) => { - let j, s, t, kid, unew, uim; - const udisp = val; - // make sure display is still valid - if( $.inArray(udisp, JS9.displays) < 0 ){ - return; - } - if( udisp ){ - uim = udisp.image; - } - switch(key){ - case "refresh": - if( uim && uim.raw.hdu && uim.raw.hdu.fits ){ - uim.refreshImage(); - } - break; - case "full": - if( uim && uim.raw.hdu && uim.raw.hdu.fits ){ - uim.displaySection("full"); - } - break; - case "cutout": - if( uim && uim.raw.hdu && uim.raw.hdu.fits ){ - uim.displaySection("selected"); - } - break; - case "free": - if( uim && uim.raw.hdu && uim.raw.hdu.fits ){ - JS9.cleanupFITSFile(uim.raw.hdu.fits, true); - } - break; - case "close": - if( uim ){ - uim.closeImage(); - } - break; - case "closeall": - if( udisp ){ - // close all images in this display - JS9.CloseDisplay(udisp.id); - } - break; - case "removeproxy": - if( uim ){ - uim.removeProxyFile(); - } - break; - case "removedisplay": - if( udisp ){ - // remove this display - JS9.RemoveDisplay(udisp.id); - } - break; - case "savecurrent": - if( udisp && uim ){ - JS9.SaveSession({mode: "image"}, - {display: udisp}); - } - break; - case "savedisplay": - if( udisp ){ - JS9.SaveSession({mode: "display"}, - {display: udisp}); - } - break; - case "loadsession": - if( udisp ){ - JS9.OpenSessionMenu({display: udisp}); - } - break; - case "loadcatalog": - if( udisp ){ - JS9.OpenCatalogsMenu({display: udisp}); - } - break; - case "savecatalog": - if( uim ){ - uim.saveCatalog(); - } - break; - case "mosaiccurrent": - if( udisp && uim ){ - JS9.CreateMosaic("current", {display: udisp}); - } - break; - case "mosaicdisplay": - if( udisp ){ - JS9.CreateMosaic("all", {display: udisp}); - } - break; - case "header": - if( uim ){ - if( uim.raw.header ){ - uim.displayAnalysis("text", - JS9.raw2FITS(uim.raw, {addcr: true}), - {title: `FITS Header: ${uim.id}`}); - } else { - JS9.error(`no FITS header for ${uim.id}`); - } - } - break; - case "hdus": - if( uim ){ - if( uim.hdus ){ - uim.displayAnalysis("text", - JS9.hdus2Str(uim.hdus), - {title: `FITS HDUs: ${uim.id}`, - winformat: "width=800px,height=200px,resize=1,scrolling=1"}); - } else { - JS9.error(`no FITS header for ${uim.id}`); - } - } - break; - case "lite": - JS9.LoadWindow(null, {clone: udisp.id}, "light"); - break; - case "xnew": - JS9.LoadWindow(null, null, "new"); - break; - case "electronHelper": - // Electron.js: send message to main - if( window.electron ){ - try{ - window.electron.sendMsg("startHelper"); - } - catch(e){ /* empty */ } - } - break; - case "pageid": - s = `

    pageid: ${JS9.helper.pageid||"none"}

    `; - t = "JS9 page id"; - // add display to title - t += sprintf(JS9.IDFMT, udisp.id); - JS9.lightWin(`fileid${JS9.uniqueID()}`, - "inline", s, t, - JS9.lightOpts[JS9.LIGHTWIN].lineWin); - break; - case "openboth": - if( udisp ){ - udisp.displayLoadForm(); - } - break; - case "openlocal": - if( udisp ){ - JS9.OpenFileMenu({display: udisp}); - } - break; - case "openremote": - if( udisp ){ - udisp.displayLoadForm({remote: true}); - } - break; - case "savefits": - case "savefitsvirtual": - case "savefitsentire": - if( uim ){ - s = uim.id.replace(/\.png/i, ".fits") - .replace(/\[.*\]/,"") - .replace(/\.gz$/i, "") - .replace(/\.bz2$/i, "") - .replace(/\s+/g, "_"); - if( key === "savefits" ){ - uim.saveFITS(s, "display"); - } else if( key === "savefitsvirtual" ){ - if( uim.raw.hdu && - uim.raw.hdu.fits && - uim.raw.hdu.fits.vfile ){ - s = uim.raw.hdu.fits.vfile - .replace(/^bz::/, "") - .replace(/^gz::/, ""); - uim.saveFITS(s, "virtual"); - } else { - JS9.error("no memory file available"); - } - } else { - uim.saveFITS(s); - } - } - break; - case "savepng": - if( uim ){ - s = uim.id.replace(/\.fit[s]?/i, ".png") - .replace(/\[.*\]/,"") - .replace(/\.gz$/i, "") - .replace(/\.bz2$/i, "") - .replace(/\s+/g, "_"); - uim.savePNG(s); - } - break; - case "savejpeg": - if( uim ){ - s = uim.id.replace(/\.fit[s]?/i, ".jpeg") - .replace(/\.png$/i, ".jpeg") - .replace(/\.gz$/i, "") - .replace(/\[.*\]/,""); - uim.saveJPEG(s); - } - break; - case "print": - if( uim ){ - uim.print(); - } - break; - case "windowPrint": - if( window.electron ){ - JS9.WindowPrint(); - } - break; - case "windowPDF": - if( window.electron ){ - JS9.WindowToPDF(); - } - break; - case "saveScript": - if( window.electron && window.electron.app ){ - JS9.SaveScript(); - } - break; - case "separate": - if( udisp ){ - udisp.separate(); - } - break; - case "gather": - if( udisp ){ - if( (this.id.search(JS9.SUPERMENU) >= 0) && - !this.selectedDisplay ){ - JS9.error("gather requires a selected display"); - } - udisp.gather(); - } - break; - default: - // maybe its a supermenu request - if( key.match(/^super_/) ){ - unew = key.replace(/^super_/,""); - JS9.Menubar.onclick.call(this, unew); - return; - } - // maybe it's a moveto request - if( key.match(/^moveto_/) ){ - unew = key.replace(/^moveto_/,""); - if( unew === "newdisp" ){ - // separate the current image - udisp.separate({images:[uim], - firstinplace:false}); - } else { - // move current image to specified display - uim.moveToDisplay(unew); - } - return; - } - // maybe it's a plugin - for(j=0; j { - evt.preventDefault(); - $(`#editMenu${this.id}`).contextMenu(); - }); - // define contextMenu actions - $.contextMenu({ - selector: `#editMenu${this.id}`, - zIndex: JS9.MENUZINDEX, - events: { hide: onhide }, - position: mypos, - build: () => { - let n=0; - const items = {}; - // plugins - items.edittitle1 = { - name: "Regions:", - disabled: true - }; - items.configReg = xname("edit"); - items.copyReg = xname("copy"); - items.pastePos = xname("paste to current pos"); - items.pasteReg = xname("paste to original pos"); - items.undoRemove = xname("undo remove"); - // deepscan-disable-next-line UNUSED_VAR_ASSIGN - items[`sep${n++}`] = "------"; - items.edittitle2 = { - name: "Position/Value:", - disabled: true - }; - items.copyWCSPos = xname("copy wcs pos"); - items.copyValPos = xname("copy value/pos"); - return { - callback: (key) => { - JS9.Menubar.getDisplays.call(this).forEach((val) => { - let s, ulayer, uao; - const udisp = val; - const uim = udisp.image; - // make sure display is still valid - if( $.inArray(udisp, JS9.displays) < 0 ){ - return; - } - switch(key){ - case "configReg": - if( uim ){ - ulayer = uim.layers.regions; - if( ulayer ){ - uao = ulayer.canvas.getActiveObject(); - if( uao && uao.type !== "activeSelection" ){ - // no active selection, edit this region - uim.displayRegionsForm(uao); - } else { - // active selection or no regions: multi - uim.displayRegionsForm(null, - {multi: true}); - } - } - } - break; - case "copyReg": - if( uim ){ - s = uim.listRegions(null, {mode: 1}); - JS9.CopyToClipboard(s); - } - break; - case "pasteReg": - if( uim ){ - JS9.Regions.pasteFromClipboard.call(uim); - } - break; - case "pastePos": - if( uim ){ - JS9.Regions.pasteFromClipboard.call(uim, - true); - } - break; - case "undoRemove": - if( uim ){ - uim.unremoveRegions(); - } - break; - case "copyWCSPos": - if( {}.hasOwnProperty.call(JS9, "Keyboard") ){ - JS9.Keyboard.Actions["copy wcs position to clipboard"](uim, uim.ipos); - } - break; - case "copyValPos": - if( {}.hasOwnProperty.call(JS9, "Keyboard") ){ - JS9.Keyboard.Actions["copy value and position to clipboard"](uim, uim.ipos); - } - break; - default: - break; - } - }); - }, - items: items - }; - } - }); - // ViewMac menu: make button open the contextMenu - $(`#viewMacMenu${this.id}`).on("mousedown", (evt) => { - evt.preventDefault(); - $(`#viewMacMenu${this.id}`).contextMenu(); - }); - // define contextMenu actions - $.contextMenu({ - selector: `#viewMacMenu${this.id}`, - zIndex: JS9.MENUZINDEX, - events: { hide: onhide }, - position: mypos, - build: () => { - let i, menu; - const items = {}; - items.edittitle1 = { - name: "View:", - disabled: true - }; - for(i=0; i { - switch(key){ - default: - $(`#${key}Menu${this.id}`).contextMenu(); - break; - } - }, - items: items - }; - } - }); - // View menu: make button open the contextMenu - $(`#viewMenu${this.id}`).on("mousedown", (evt) => { - evt.preventDefault(); - $(`#viewMenu${this.id}`).contextMenu(); - }); - // define contextMenu actions - $.contextMenu({ - selector: `#viewMenu${this.id}`, - zIndex: JS9.MENUZINDEX, - events: { hide: onhide }, - position: mypos, - build: () => { - let i, key; - let plugin, pname, pinst; - let lastxclass=""; - let n = 0; - const items = {}; - const tdisp = JS9.Menubar.getDisplays.call(this)[0]; - const tim = tdisp.image; - const editValposColor = (disp, obj) => { - delete tdisp.tmp.editingMenu; - if( obj.valposcolor ){ - JS9.textColorOpts.info = obj.valposcolor; - if( disp && disp.image ){ - disp.image.updateValpos(disp.image.ipos, true); - } - } - } - const keyValposColor = (e) => { - JS9.Menubar.getDisplays.call(this).forEach((val) => { - const obj = $.contextMenu.getInputValues(e.data); - const keycode = e.which || e.keyCode; - const vdisp = val; - // make sure display is still valid - if( $.inArray(vdisp, JS9.displays) < 0 ){ - return; - } - switch( keycode ){ - case 9: - case 13: - editValposColor(vdisp, obj); - break; - default: - vdisp.tmp.editingMenu = true; - break; - } - }); - }; - const editResize = (disp, obj) => { - let v1, v2, arr; - delete tdisp.tmp.editingMenu; - if( obj.resize ){ - arr = obj.resize.split(/[\s,/]+/); - switch(arr.length){ - case 0: - break; - case 1: - if( tim ){ - v1 = tim.wcs2imlen(arr[0]); - disp.resize(v1, v1); - } else if( JS9.isNumber(arr[0]) ){ - v1 = parseInt(arr[0], 10); - disp.resize(v1, v1); - } - break; - default: - if( tim && tim.wcs ){ - v1 = tim.wcs2imlen(arr[0]); - v2 = tim.wcs2imlen(arr[1]); - disp.resize(v1, v2); - } else if( JS9.isNumber(arr[0]) && - JS9.isNumber(arr[1]) ){ - v1 = parseInt(arr[0], 10); - v2 = parseInt(arr[1], 10); - disp.resize(v1, v2); - } - break; - } - } - }; - const keyResize = (e) => { - JS9.Menubar.getDisplays.call(this).forEach((val) => { - const obj = $.contextMenu.getInputValues(e.data); - const keycode = e.which || e.keyCode; - const vdisp = val; - // make sure display is still valid - if( $.inArray(vdisp, JS9.displays) < 0 ){ - return; - } - switch( keycode ){ - case 9: - case 13: - editResize(vdisp, obj); - break; - default: - vdisp.tmp.editingMenu = true; - break; - } - }); - }; - // plugins - items[`sep${n++}`] = {name: "Plugins:"}; - items[`sep${n-1}`].disabled = true; - for(i=0; i 1 ){ - items.vdisps.items.rawlayer.items.whichrawtitle = { - name: "current raw data:" - }; - for(i=0; i { - JS9.Menubar.getDisplays.call(this).forEach((val) => { - let ii, uplugin, s; - const udisp = val; - const uim = udisp.image; - // make sure display is still valid - if( $.inArray(udisp, JS9.displays) < 0 ){ - return; - } - switch(key){ - case "valpos": - if( uim ){ - uim.toggleValpos(); - } - break; - case "valposdisp": - JS9.globalOpts.valposDCoords = - !JS9.globalOpts.valposDCoords; - break; - case "xhair": - if( uim ){ - uim.toggleCrosshair(); - } - break; - case "xhairwcs": - if( uim ){ - uim.toggleWCSCrosshair(); - } - break; - case "toolbar": - s = !JS9.GetToolbar("showTooltips"); - JS9.SetToolbar("showTooltips", s); - break; - case "logo": - JS9.globalOpts.logoDisplay = - !JS9.globalOpts.logoDisplay; - s = JS9.globalOpts.logoDisplay ? "block" : "none"; - for(ii=0; ii { - const udisp = this.display; - const obj = {}; - if( udisp ){ - obj.resize = sprintf("%d %d", - udisp.width, udisp.height); - obj.valposcolor = JS9.textColorOpts.info; - $.contextMenu.setInputValues(opt, obj); - JS9.jupyterFocus(".context-menu-item"); - } - }, - hide: (opt) => { - let obj; - const udisp = this.display; - if( udisp ){ - // if a key was pressed, do the edit - if( udisp.tmp.editingMenu ){ - obj = $.contextMenu.getInputValues(opt); - editResize(udisp, obj); - } - } - } - }, - items: items - }; - } - }); - // Zoom menu: make button open the contextMenu - $(`#zoomMenu${this.id}`).on("mousedown", (evt) => { - evt.preventDefault(); - $(`#zoomMenu${this.id}`).contextMenu(); - }); - // define contextMenu actions - $.contextMenu({ - selector: `#zoomMenu${this.id}`, - zIndex: JS9.MENUZINDEX, - events: { hide: onhide }, - position: mypos, - build: () => { - let i, zoom, zoomp, name, name2, nim, s1; - let plugin, pname, pinst; - let lastxclass=""; - let n = 0; - const tdisp = JS9.Menubar.getDisplays.call(this)[0]; - const tim = tdisp.image; - const editZoom = (im, obj) => { - delete tdisp.tmp.editingMenu; - // allow numbers or strings - if( !Number.isNaN(obj.zoom) ){ - im.setZoom(obj.zoom); - } - }; - const editRotate = (im, obj) => { - delete tdisp.tmp.editingMenu2; - // allow numbers or strings - if( !Number.isNaN(obj.rotate) ){ - im.setRotate(obj.rotate); - } - }; - const keyZoom = (e) => { - JS9.Menubar.getDisplays.call(this).forEach((val) => { - const obj = $.contextMenu.getInputValues(e.data); - const keycode = e.which || e.keyCode; - const vdisp = val; - const vim = vdisp.image; - // make sure display is still valid - if( $.inArray(vdisp, JS9.displays) < 0 ){ - return; - } - switch( keycode ){ - case 9: - case 13: - if( vim ){ - editZoom(vim, obj); - } - break; - default: - vdisp.tmp.editingMenu = true; - break; - } - }); - }; - const keyRotate = (e) => { - JS9.Menubar.getDisplays.call(this).forEach((val) => { - const obj = $.contextMenu.getInputValues(e.data); - const keycode = e.which || e.keyCode; - const vdisp = val; - const vim = vdisp.image; - // make sure display is still valid - if( $.inArray(vdisp, JS9.displays) < 0 ){ - return; - } - switch( keycode ){ - case 9: - case 13: - if( vim ){ - editRotate(vim, obj); - } - break; - default: - vdisp.tmp.editingMenu2 = true; - break; - } - }); - }; - const items = {}; - items.zoomtitle = { - name: "Zoom Factors:", - disabled: true - }; - for(i=JS9.imageOpts.topZooms; i>=1; i--){ - zoom = Math.pow(2,-i); - zoomp = Math.pow(2,i); - name = `zoom${zoom}`; - name2 = `zoom 1/${zoomp}`; - items[name] = xname(name2); - if( tim && (tim.rgb.sect.zoom === zoom) ){ - items[name].icon = JS9.globalOpts.menuSelected; - } - } - for(i=0; i<=JS9.imageOpts.topZooms; i++){ - zoom = Math.pow(2,i); - name = `zoom${zoom}`; - name2 = `zoom ${zoom}`; - items[name] = xname(name2); - if( tim && (tim.rgb.sect.zoom === zoom) ){ - items[name].icon = JS9.globalOpts.menuSelected; - } - } - items.morezooms = { - name: "more zooms ...", - items: { - morezoomstitle: { - name: "Zoom Factors:", - disabled: true - } - } - }; - for(i=JS9.imageOpts.zooms; i>JS9.imageOpts.topZooms; i--){ - zoom = Math.pow(2,-i); - zoomp = Math.pow(2,i); - name = `zoom${zoom}`; - name2 = `zoom 1/${zoomp}`; - items.morezooms.items[name] = xname(name2); - if( tim && (tim.rgb.sect.zoom === zoom) ){ - items.morezooms.items[name].icon = JS9.globalOpts.menuSelected; - } - } - for(i=JS9.imageOpts.topZooms+1; i<=JS9.imageOpts.zooms; i++){ - zoom = Math.pow(2,i); - name = `zoom${zoom}`; - name2 = `zoom ${zoom}`; - items.morezooms.items[name] = xname(name2); - if( tim && (tim.rgb.sect.zoom === zoom) ){ - items.morezooms.items[name].icon = JS9.globalOpts.menuSelected; - } - } - items.zoom = { - events: {keyup: keyZoom}, - name: "numeric zoom:", - type: "text" - }; - items[`sep${n++}`] = "------"; - items.zoomiotitle = { - name: "Zoom In/Out:", - disabled: true - }; - items.zoomIn = xname("zoom in"); - items.zoomOut = xname("zoom out"); - items.zoomToFit = xname("zoom to fit"); - items[`sep${n++}`] = "------"; - items.panzoomtitle = { - name: "Pand and Zoom:", - disabled: true - }; - items.center = xname("pan to center"); - items.alignpanzoom = { - name: "align pan/zoom ...", - items: { - alignpanzoomtitle: { - name: "to this image:", - disabled: true - } - } - }; - for(i=0, nim=0; i { - let ii, uplugin; - JS9.Menubar.getDisplays.call(this).forEach((val) => { - const udisp = val; - const uim = udisp.image; - // make sure display is still valid - if( $.inArray(udisp, JS9.displays) < 0 ){ - return; - } - if( uim ){ - switch(key){ - case "zoomIn": - uim.setZoom("x2"); - break; - case "zoomOut": - uim.setZoom("/2"); - break; - case "zoomToFit": - uim.setZoom("tofit"); - break; - case "center": - uim.setPan(); - break; - case "reset": - uim.setZoom("1"); - uim.setPan(); - break; - case "flipX": - uim.setFlip("x"); - break; - case "flipY": - uim.setFlip("y"); - break; - case "rot90_90": - uim.setRot90(90); - break; - case "rot90_270": - uim.setRot90(-90); - break; - case "northisup": - uim.setRot90("reset"); - uim.setRotate("northisup"); - break; - case "resetall": - uim.setFlip("reset"); - uim.setRot90("reset"); - uim.setRotate("reset"); - break; - default: - // maybe it's a plugin - for(ii=0; ii { - const udisp = this.display; - const uim = udisp.image; - const obj = {}; - if( uim ){ - obj.zoom = - JS9.floatToString(uim.rgb.sect.zoom); - obj.rotate = - JS9.floatToString(uim.params.rotate||0); - } - $.contextMenu.setInputValues(opt, obj); - JS9.jupyterFocus(".context-menu-item"); - }, - hide: (opt) => { - let obj; - const udisp = this.display; - const uim = udisp.image; - if( uim ){ - // if a key was pressed, do the edit - if( udisp.tmp.editingMenu ){ - obj = $.contextMenu.getInputValues(opt); - editZoom(uim, obj); - } - if( udisp.tmp.editingMenu2 ){ - obj = $.contextMenu.getInputValues(opt); - editRotate(uim, obj); - } - } - } - }, - items: items - }; - } - }); - // Scale menu: make button open the contextMenu - $(`#scaleMenu${this.id}`).on("mousedown", (evt) => { - evt.preventDefault(); - $(`#scaleMenu${this.id}`).contextMenu(); - }); - // define contextMenu actions - $.contextMenu({ - selector: `#scaleMenu${this.id}`, - zIndex: JS9.MENUZINDEX, - events: { hide: onhide }, - position: mypos, - build: () => { - let i, s1, s2; - let plugin, pname, pinst; - let lastxclass=""; - let n = 0; - const items = {}; - const tdisp = JS9.Menubar.getDisplays.call(this)[0]; - const editScale = (im, obj) => { - let dval1 = im.params.scalemin; - let dval2 = im.params.scalemax; - delete tdisp.tmp.editingMenu; - if( JS9.isNumber(obj.scalemin) ){ - dval1 = parseFloat(obj.scalemin); - } - if( JS9.isNumber(obj.scalemax) ){ - dval2 = parseFloat(obj.scalemax); - } - im.setScale(dval1, dval2); - im.displayImage("colors"); - }; - const keyScale = (e) => { - JS9.Menubar.getDisplays.call(this).forEach((val) => { - const obj = $.contextMenu.getInputValues(e.data); - const keycode = e.which || e.keyCode; - const vdisp = val; - const vim = vdisp.image; - // make sure display is still valid - if( $.inArray(vdisp, JS9.displays) < 0 ){ - return; - } - switch( keycode ){ - case 9: - case 13: - if( vim ){ - editScale(vim, obj); - } - break; - default: - vdisp.tmp.editingMenu = true; - break; - } - }); - }; - items.scaletitle = {name: "Scaling Algorithms:", - disabled: true}; - for(i=0; i { - let ii, uplugin; - JS9.Menubar.getDisplays.call(this).forEach((val) => { - const udisp = val; - const uim = udisp.image; - // make sure display is still valid - if( $.inArray(udisp, JS9.displays) < 0 ){ - return; - } - if( uim ){ - switch(key){ - default: - // maybe it's a plugin - for(ii=0; ii { - const udisp = this.display; - const uim = udisp.image; - const obj = {}; - if( uim ){ - obj.scalemin = - JS9.floatToString(uim.params.scalemin); - obj.scalemax = - JS9.floatToString(uim.params.scalemax); - } - $.contextMenu.setInputValues(opt, obj); - JS9.jupyterFocus(".context-menu-item"); - }, - hide: (opt) => { - let obj; - const udisp = this.display; - const uim = udisp.image; - if( uim ){ - // if a key was pressed, do the edit - if( udisp.tmp.editingMenu ){ - obj = $.contextMenu.getInputValues(opt); - editScale(uim, obj); - } - } - } - }, - items: items - }; - } - }); - // Color menu: make button open the contextMenu - $(`#colorMenu${this.id}`).on("mousedown", (evt) => { - evt.preventDefault(); - $(`#colorMenu${this.id}`).contextMenu(); - }); - // define contextMenu actions - $.contextMenu({ - selector: `#colorMenu${this.id}`, - zIndex: JS9.MENUZINDEX, - events: { hide: onhide }, - position: mypos, - build: () => { - let i, s1, s2, hstr, img; - let plugin, pname, pinst; - let lastxclass=""; - let n = 0; - const items = {}; - const tdisp = JS9.Menubar.getDisplays.call(this)[0]; - const editColor = (im, obj) => { - delete tdisp.tmp.editingMenu; - if( obj.contrast && !Number.isNaN(obj.contrast) ){ - im.params.contrast = parseFloat(obj.contrast); - } - if( obj.bias && !Number.isNaN(obj.bias) ){ - im.params.bias = parseFloat(obj.bias); - } - if( obj.opacity.match(/reset/) || obj.opacity.trim() === "" ){ - im.setOpacity("reset"); - } else if( !Number.isNaN(obj.opacity) ){ - im.setOpacity(parseFloat(obj.opacity)); - } - im.displayImage("colors"); - }; - const keyColor = (e) => { - JS9.Menubar.getDisplays.call(this).forEach((val) => { - const obj = $.contextMenu.getInputValues(e.data); - const keycode = e.which || e.keyCode; - const vdisp = val; - const vim = vdisp.image; - // make sure display is still valid - if( $.inArray(vdisp, JS9.displays) < 0 ){ - return; - } - switch( keycode ){ - case 9: - case 13: - editColor(vim, obj); - break; - default: - vdisp.tmp.editingMenu = true; - break; - } - }); - }; - items.cmaptitle = { - name: "Colormaps:", - disabled: true - }; - for(i=0; i` + `  ${s2}
    `; - items[s1] = {name: hstr, isHtmlName: true}; - } else { - items[s1] = xname(s2); - } - if( tdisp.image && (tdisp.image.cmapObj.name === s1) ){ - items[s1].icon = JS9.globalOpts.menuSelected; - } - } - items.morecmaps = { - name: "more colormaps ...", - items: { - morecmapstitle: { - name: "Colormaps:", - disabled: true - } - } - }; - for(i=0; i` + `  ${s2}
    `; - items.morecmaps.items[s1] = {name: hstr, isHtmlName: true}; - } else { - items.morecmaps.items[s1] = xname(s2); - } - if( tdisp.image && (tdisp.image.cmapObj.name === s1) ){ - items.morecmaps.items[s1].icon = JS9.globalOpts.menuSelected; - } - } - } - items[`sep${n++}`] = "------"; - items.imfilter = xname("image filters ..."); - items[`sep${n++}`] = "------"; - items.contrast = { - events: {keyup: keyColor}, - name: "contrast:", - type: "text" - }; - items.bias = { - events: {keyup: keyColor}, - name: "bias:", - type: "text" - }; - items.reset = xname("reset contrast & bias"); - items[`sep${n++}`] = "------"; - items.opacity = { - events: {keyup: keyColor}, - name: "opacity:", - type: "text" - }; - items[`sep${n++}`] = "------"; - items.loadcmap = xname("load ..."); - items.savecmap = xname("save"); - items[`sep${n++}`] = "------"; - items.invert = xname("invert"); - if( tdisp.image && tdisp.image.params.invert ){ - items.invert.icon = JS9.globalOpts.menuSelected; - } - items.rgb = xname("rgb mode"); - if( tdisp.rgb.active ){ - items.rgb.icon = JS9.globalOpts.menuSelected; - } - if( tdisp.image && tdisp.image.offscreen && !tdisp.image.rgbFile ){ - items.overlay = xname("image overlay"); - if( tdisp.image.params.overlay ){ - items.overlay.icon = JS9.globalOpts.menuSelected; - } - } - items[`sep${n++}`] = "------"; - // plugins - for(i=0; i { - let ii, uplugin; - JS9.Menubar.getDisplays.call(this).forEach((val) => { - const udisp = val; - const uim = udisp.image; - // make sure display is still valid - if( $.inArray(udisp, JS9.displays) < 0 ){ - return; - } - switch(key){ - case "loadcmap": - JS9.OpenColormapMenu({display: udisp}); - break; - case "savecmap": - JS9.SaveColormap({display: udisp}); - break; - case "imfilter": - JS9.DisplayPlugin("JS9Filters", {display: udisp}); - break; - default: - // maybe it's a plugin - for(ii=0; ii { - const udisp = this.display; - const uim = udisp.image; - const obj = {}; - if( uim ){ - obj.contrast = - JS9.floatToString(uim.params.contrast); - obj.bias = - JS9.floatToString(uim.params.bias); - obj.opacity = - JS9.floatToString(uim.params.opacity); - obj.sigma = - JS9.floatToString(uim.params.sigma); - } - $.contextMenu.setInputValues(opt, obj); - JS9.jupyterFocus(".context-menu-item"); - }, - hide: (opt) => { - let obj; - const udisp = this.display; - const uim = udisp.image; - if( uim ){ - // if a key was pressed, do the edit - if( udisp.tmp.editingMenu ){ - obj = $.contextMenu.getInputValues(opt); - editColor(uim, obj); - } - } - } - }, - items: items - }; - } - }); - // Region menu: make button open the contextMenu - $(`#regionMenu${this.id}`).on("mousedown", (evt) => { - evt.preventDefault(); - $(`#regionMenu${this.id}`).contextMenu(); - }); - // define contextMenu actions - $.contextMenu({ - selector: `#regionMenu${this.id}`, - zIndex: JS9.MENUZINDEX, - events: { hide: onhide }, - position: mypos, - build: () => { - let i, s1, reg, img, key; - const tdisp = JS9.Menubar.getDisplays.call(this)[0]; - const tim = tdisp.image; - const items = {}; - const getregval = (key, val) => { - switch(key){ - case "color": - // lookup color - if( val.charAt(0) !== "#" && JS9.colorToHex(val) === val ){ - return null; - } - break; - case "strokeWidth": - // number - if( !JS9.isNumber(val) ){ - return null; - } - val = parseFloat(val); - break; - case "strokeDashArray": - // space or comma-separated list of numbers - val = val.split(/[\s,]+/); - if( !val || !val.length ){ - return null; - } - if( val.length < 2 ){ - val[1] = "0"; - } - if( !JS9.isNumber(val[0]) || !JS9.isNumber(val[1]) ){ - return null; - } - val[0] = parseFloat(val[0]); - val[1] = parseFloat(val[1]); - break; - default: - // text - break; - } - return val; - }; - const editRegions = (im, obj, which) => { - let key, val; - const opts = {}; - obj = obj || {}; - if( which ){ - key = which.substring(3); - val = obj[which]; - if( key && val && im.tmp[`editingReg${which}`] ){ - delete im.tmp[`editingReg${which}`]; - val = getregval(key, val); - if( val ){ - opts[key] = val; - im.changeShapes("regions", "selected", opts); - } - } - } else { - for( which of Object.keys(obj) ){ - key = which.substring(3); - val = obj[which]; - if( key && val && im.tmp[`editingReg${which}`] ){ - delete im.tmp[`editingReg${which}`]; - val = getregval(key, val); - if( val ){ - opts[key] = val; - } - } - } - if( Object.keys(opts).length ){ - im.changeShapes("regions", "selected", opts); - } - } - }; - items.regiontitle = { - name: "Regions:", - disabled: true - }; - if( JS9.globalOpts.menuImages ){ - for(i=0; i` + `  ${reg}
    `, - isHtmlName: true}; - } - } else { - for(i=0; i 1) ){ - for(i=0; i { - JS9.Menubar.getDisplays.call(this).forEach((val) => { - let uid, ulayer, uao, uopts; - const udisp = val; - const uim = udisp.image; - // make sure display is still valid - if( $.inArray(udisp, JS9.displays) < 0 ){ - return; - } - if( uim ){ - switch(key){ - case "loadRegions": - JS9.OpenRegionsMenu({display: udisp}); - break; - case "listRegions": - uim.listRegions(null, {mode: 2}); - break; - case "createRegions": - JS9.globalOpts.regMenuCreate = - !JS9.globalOpts.regMenuCreate; - break; - case "removeRegions": - uim.removeShapes("regions", null); - udisp.clearMessage("regions"); - break; - case "saveRegions": - ulayer = uim.layers.regions; - if( ulayer ){ - uao = ulayer.canvas.getActiveObject(); - uopts = {type: "save"}; - if( uao && uao.type !== "activeSelection" ){ - uim.displayRegionsForm(uao, uopts); - } else { - uim.displayRegionsForm(null, uopts); - } - } - break; - case "selectRegions": - if( {}.hasOwnProperty.call(JS9, "Keyboard") ){ - JS9.Keyboard.Actions["select all regions"](uim, uim.ipos); - } - break; - case "unselectRegions": - if( {}.hasOwnProperty.call(JS9, "Keyboard") ){ - JS9.Keyboard.Actions["unselect all regions"](uim, uim.ipos); - } - break; - case "selectedRegions": - ulayer = uim.layers.regions; - if( ulayer ){ - uao = ulayer.canvas.getActiveObject(); - if( uao && uao.type !== "activeSelection" ){ - // no active selection, edit this region - uim.displayRegionsForm(uao); - } else { - // active selection or no regions: multi - uim.displayRegionsForm(null, - {multi: true}); - } - } - break; - case "xeqonchange": - uim.params.xeqonchange = !uim.params.xeqonchange; - break; - case "listonchange": - uim.params.listonchange = !uim.params.listonchange; - break; - default: - // maybe it's a copyto request - if( key.match(/^copyto_/) ){ - uid = key.replace(/^copyto_/,""); - uim.copyRegions(uid); - return; - } - // otherwise it's new region - JS9.globalOpts.regMenuSelected = key; - if( JS9.globalOpts.regMenuCreate ){ - uim.addShapes("regions", key, {ireg: true}); - } - break; - } - } - }); - }, - events: { - show: (opt) => { - const obj = {color: ""}; - $.contextMenu.setInputValues(opt, obj); - JS9.jupyterFocus(".context-menu-item"); - }, - hide: (opt) => { - let obj; - const udisp = this.display; - const uim = udisp.image; - if( uim ){ - // if a key was pressed, do the edit - obj = $.contextMenu.getInputValues(opt); - editRegions(uim, obj); - } - } - }, - items: items - }; - } - }); - // WCS menu: make button open the contextMenu - $(`#wcsMenu${this.id}`).on("mousedown", (evt) => { - evt.preventDefault(); - $(`#wcsMenu${this.id}`).contextMenu(); - }); - // define contextMenu actions - $.contextMenu({ - selector: `#wcsMenu${this.id}`, - zIndex: JS9.MENUZINDEX, - events: { hide: onhide }, - position: mypos, - build: () => { - let i, s1, s2, key, altwcs, sys, units; - let n=0, nwcs=0, got=0; - const items = {}; - const tdisp = JS9.Menubar.getDisplays.call(this)[0]; - const tim = tdisp.image; - const editRotate = (im, obj) => { - delete tdisp.tmp.editingMenu; - if( JS9.isNumber(obj.rot) ){ - im.rotateData(parseFloat(obj.rot)); - } - }; - const keyRotate = (e) => { - JS9.Menubar.getDisplays.call(this).forEach((val) => { - const obj = $.contextMenu.getInputValues(e.data); - const keycode = e.which || e.keyCode; - const vdisp = val; - const vim = vdisp.image; - // make sure display is still valid - if( $.inArray(vdisp, JS9.displays) < 0 ){ - return; - } - switch( keycode ){ - case 9: - case 13: - if( vim ){ - editRotate(vim, obj); - } - break; - default: - vdisp.tmp.editingMenu = true; - break; - } - }); - }; - items.wcssystitle = { - name: "WCS Systems:", - disabled: true - }; - if( !tim || (tim && tim.validWCS()) ){ - sys = JS9.wcssyss; - } else { - sys = ["image", "physical"]; - } - for(i=0; i { - JS9.Menubar.getDisplays.call(this).forEach((val) => { - let file, s; - const rexp = new RegExp(key); - const udisp = val; - const uim = udisp.image; - // make sure display is still valid - if( $.inArray(udisp, JS9.displays) < 0 ){ - return; - } - if( uim ){ - // maybe it's an alt wcs request - if( key.match(/^altwcs_/) ){ - s = key.replace(/^altwcs_/,""); - uim.setWCS(s); - return; - } - // maybe it's a wcs reprojection request - if( key.match(/^reproject_/) ){ - if( key === "reproject_wcsalign" ){ - uim.params.wcsalign = !uim.params.wcsalign; - uim.displayImage("display"); - } else if( key === "reproject_northup" ){ - uim.rotateData("northisup"); - } else if( key === "reproject_revert" ){ - if( uim.raw.id !== JS9.RAWID0 ){ - for(i=0; i=0 ){ - uim.setWCSSys(key); - uim.updateShapes("regions", "all", "wcs"); - } else if( JS9.wcsunitss.join("@").search(rexp)>=0){ - uim.setWCSUnits(key); - uim.updateShapes("regions", "all", "wcs"); - } else { - JS9.error(`unknown wcs sys/units: ${key}`); - } - } - }); - }, - events: { - show: (opt) => { - const udisp = this.display; - const uim = udisp.image; - const obj = {}; - if( uim ){ - obj.rot = ""; - $.contextMenu.setInputValues(opt, obj); - JS9.jupyterFocus(".context-menu-item"); - } - }, - hide: (opt) => { - let obj; - const udisp = this.display; - const uim = udisp.image; - if( uim ){ - obj = $.contextMenu.getInputValues(opt); - // if a key was pressed, do the edit - if( udisp.tmp.editingMenu ){ - editRotate(uim, obj); - } - } - } - }, - items: items - }; - } - }); - // Analysis menu: make button open the contextMenu - $(`#analysisMenu${this.id}`).on("mousedown", (evt) => { - evt.preventDefault(); - $(`#analysisMenu${this.id}`).contextMenu(); - }); - // define contextMenu actions - $.contextMenu({ - selector: `#analysisMenu${this.id}`, - zIndex: JS9.MENUZINDEX, - events: { hide: onhide }, - position: mypos, - build: () => { - let i, j, s, apackages, atasks; - let plugin, pinst, pname; - let lastxclass=""; - let n = 0; - let ntask = 0; - const items = {}; - const tdisp = JS9.Menubar.getDisplays.call(this)[0]; - const im = tdisp.image; - const editAnalysis = (im, obj) => { - delete tdisp.tmp.editingMenu; - obj.sigma = obj.sigma || "0"; - if( obj.sigma === "none" ){ - obj.sigma = "0"; - } - try{ im.params.sigma = parseFloat(obj.sigma); } - catch(e){ im.params.sigma = 0; } - im.gaussBlurData(im.params.sigma); - }; - const keyAnalysis = (e) => { - JS9.Menubar.getDisplays.call(this).forEach((val) => { - const obj = $.contextMenu.getInputValues(e.data); - const keycode = e.which || e.keyCode; - const vdisp = val; - const vim = vdisp.image; - // make sure display is still valid - if( $.inArray(vdisp, JS9.displays) < 0 ){ - return; - } - switch( keycode ){ - case 9: - case 13: - editAnalysis(vim, obj); - break; - default: - vdisp.tmp.editingMenu = true; - break; - } - }); - }; - for(i=0; i 0 ){ - items[`sep${n++}`] = "------"; - } - items[`sep${n++}`] = - {name: `${plugin.xclass} Plugins:`}; - items[`sep${n-1}`].disabled = true; - } - lastxclass = plugin.xclass; - items[pname] = { - name: plugin.opts.menuItem - }; - if( pinst && (pinst.status === "active") ){ - items[pname].icon = JS9.globalOpts.menuSelected; - } - n++; - } - } - } - // no server side analysis for all-in-one configuration - if( !JS9.allinone ){ - if( n > 0 ){ - items[`sep${n++}`] = "------"; - } - items.localtitle = { - name: "Client-side Analysis:", - disabled: true - }; - items.grid = xname("Coordinate Grid"); - if( !im || !im.raw.wcs || im.raw.wcs <=0 ){ - items.grid.disabled = true; - } else { - if( im.displayCoordGrid() ){ items.grid.icon = JS9.globalOpts.menuSelected; } - } - items.regcnts = xname("Counts in Regions"); - items.radprof = xname("Radial Profile"); - if( !JS9.globalOpts.internalRegcnts || - !im || !im.raw || !im.raw.hdu || !im.raw.hdu.vfile ){ - items.regcnts.disabled = true; - items.radprof.disabled = true; - } - if( im && im.raw && im.raw.header.NAXIS === 3 ){ - items.cnts3d = xname("3D Counts in Regions"); - items.plot3d = xname("3D Plot using Regions"); - if( !JS9.globalOpts.internalRegcnts || - !im.raw.hdu || !im.raw.hdu.vfile ){ - items.cnts3d.disabled = true; - items.plot3d.disabled = true; - } - } - items.sigma = { - events: {keyup: keyAnalysis}, - name: "Blur, equivalent sigma:", - type: "text" - }; - items[`sep${n++}`] = "------"; - items.remotetitle = { - name: "Server-side Analysis:", - disabled: true - }; - if( im && im.analysisPackages ){ - apackages = im.analysisPackages; - // m = 0; - for(j=0; j { - JS9.Menubar.getDisplays.call(this).forEach((val) => { - let a, s, did, ii, tplugin; - const udisp = val; - const uim = udisp.image; - // make sure display is still valid - if( $.inArray(udisp, JS9.displays) < 0 ){ - return; - } - // first look for a plugin -- no image rquired - for(ii=0; ii { - $('#dataPath').val(JS9.globalOpts.dataPath); - }); - did = uim.displayAnalysis("textline", - JS9.InstallDir(JS9.analOpts.dpathURL), - {title: "Data path for analysis"}); - // save display id - $(did).data("dispid", udisp.id); - $(did).data("imid", uim.id); - break; - case "fpath": - // call this once window is loaded - $(JS9.lightOpts[JS9.LIGHTWIN].topid) - .arrive("#filePathForm", - {onceOnly: true}, () => { - $('#filePath').val(uim.file); - }); - did = uim.displayAnalysis("textline", - JS9.InstallDir(JS9.analOpts.fpathURL), - {title: "File path for this image"}); - // save display id - $(did).data("dispid", udisp.id); - $(did).data("imid", uim.id); - break; - case "grid": - uim.displayCoordGrid(!uim.displayCoordGrid()); - break; - case "upload": - uim.uploadFITSFile(); - break; - default: - // look for analysis routine - a = uim.lookupAnalysis(key); - if( a ){ - // load param url to run analysis task - // param url is relative to js9 install dir - if( a.purl ){ - did = uim.displayAnalysis("params", - JS9.InstallDir(a.purl), - {title: `${a.title}: ${uim.fitsFile}`, - winformat: a.pwin}); - // save info for running the task - $(did).data("dispid", udisp.id) - .data("aname", a.name); - } else { - // else run task directly - uim.runAnalysis(a.name); - } - } - return; - } - } - }); - }, - events: { - show:(opt) => { - const udisp = this.display; - const uim = udisp.image; - const obj = {}; - if( uim ){ - obj.sigma = JS9.floatToString(uim.params.sigma); - } - $.contextMenu.setInputValues(opt, obj); - JS9.jupyterFocus(".context-menu-item"); - }, - hide: (opt) => { - let obj; - const udisp = this.display; - const uim = udisp.image; - if( uim ){ - // if a key was pressed, do the edit - if( udisp.tmp.editingMenu ){ - obj = $.contextMenu.getInputValues(opt); - editAnalysis(uim, obj); - } - } - } - }, - items: items - }; - } - }); - // Help menu: make button open the contextMenu - $(`#helpMenu${this.id}`).on("mousedown", (evt) => { - evt.preventDefault(); - $(`#helpMenu${this.id}`).contextMenu(); - }); - // define contextMenu actions - $.contextMenu({ - selector: `#helpMenu${this.id}`, - zIndex: JS9.MENUZINDEX, - events: { hide: onhide }, - position: mypos, - build: () => { - let t, key, val; - let n = 1; - let last = ""; - const items = {}; - items.js9help = { - name: "General help ...", - items: { - helptitle: { - name: "General help:", - disabled: true - } - } - }; - // first, internal js9 pages - for( key of Object.keys(JS9.helpOpts) ){ - val = JS9.helpOpts[key]; - if( val.heading === "JS9Help" ){ - last = val.type; - items.js9help.items[key] = { - name: val.title - }; - } - } - items[`sep${n++}`] = "------"; - items.pluginhelp = { - name: "JS9 plugins ...", - items: { - helptitle: { - name: "JS9 plugins:", - disabled: true - } - } - }; - // second, the JS9 core plugins - for( key of Object.keys(JS9.helpOpts) ){ - val = JS9.helpOpts[key]; - if( val.heading === "JS9" ){ - last = val.type; - items.pluginhelp.items[key] = { - name: val.title.replace(/ \.\.\./, "") - }; - } - } - // last, the others - for( key of Object.keys(JS9.helpOpts) ){ - val = JS9.helpOpts[key]; - if( val.heading === "JS9Help" || val.heading === "JS9" ){ - continue; - } - if( (last !== "") && (val.type !== last) ){ - items[`sep${n++}`] = "------"; - if( val.heading ){ - t = `${val.heading } plugins`; - items[`sep${n++}`] = { - name: `${t} ...`, - items: { - title: { - name: `${t}:`, - disabled: true - } - } - }; - } - } - last = val.type; - items[`sep${n-1}`].items[key] = {name: val.title}; - } - items[`sep${n++}`] = "------"; - items.about = xname("About"); - return { - callback: (key) => { - switch(key){ - case "about": - alert(JS9.ABOUT); - break; - default: - JS9.DisplayHelp(key); - break; - } - }, - items: items - }; - } - }); - // user-defined menus - addUserMenus(); -}; - -// initialize the menu -JS9.Menubar.init = function(width, height){ - let i, j, m, ss, tt, menu, html; - this.issuper = this.id.search(JS9.SUPERMENU) >= 0; - // save object in super array, if necessary - if( this.issuper ){ - JS9.supermenus.push(this); - } - this.style = this.divjq.attr("data-style") || - JS9.globalOpts.menubarStyle || - "classic"; - this.style = this.style.toLowerCase(); - // set width and height on div - this.width = this.divjq.attr("data-width"); - if( !this.width ){ - this.width = width || JS9.Menubar.WIDTH; - } - this.divjq.css("width", this.width); - this.width = parseInt(this.divjq.css("width"), 10); - this.height = this.divjq.attr("data-height"); - this.buttonClass = this.divjq.attr("data-buttonClass") || "JS9Button" ; - this.containerClass = "JS9MenubarContainer"; - // special handling of some known button classes - if( this.buttonClass.match(/-flat/) ){ - this.containerClass += "-flat"; - } else if( this.buttonClass.match(/-border/) ){ - this.containerClass += "-border"; - } - this.backgroundColor = this.divjq.attr("data-backgroundColor"); - if( !this.height ){ - this.height = height || JS9.MENUHEIGHT; - } - this.divjq.css("height", this.height); - this.height = parseInt(this.divjq.css("height"), 10); - // look for usermenu directive, either for this element or globally - this.usermenus = this.divjq.attr("data-usermenus") === "true" || - JS9.globalOpts.userMenus; - // generate html for this menubar - html = ""; - for(j=0; j${tt} `; - } - } - } else { - if( this.style === "classic" ){ - html += ``; - } else { - switch(ss){ - case "file": - case "edit": - html += ``; - break; - case "help": - html += ``; - break; - default: - if( !this.macmenus ){ - html += `${"`; - this.macmenus = []; - } - if( tt === "View" ){ - tt = "Plugins"; - } - html += ``; - this.macmenus.push({name: ss, title: tt}); - break; - } - } - } - break; - } - } - } - // close mac-style span on View menu - if( this.macmenus ){ - html += ""; - } - // user-defined menus - if( this.usermenus && JS9.globalOpts.userMenuBar ){ - html += JS9.globalOpts.userMenuDivider || ""; - for(j=0; j${menu.title}` + `
    `; - } else { - m = menu.title; - } - html += ``; - } - } - // hidden menus - html += ""; - html += ""; - html += ""; - // link back the menubar in the display - this.display.menubar = this; - // define menubar - this.html = html.replace(/@@ID@@/g,this.id); - // add container to the high-level div - this.menuConjq = $("
    ") - .addClass(this.containerClass) - .attr("width", this.width) - .attr("height", this.height) - .html(this.html) - .appendTo(this.divjq); - // menubar background color - if( this.backgroundColor ){ - this.menuConjq.css("background", this.backgroundColor); - } - // create the standard menus - JS9.Menubar.createMenus.call(this); -}; - -JS9.RegisterPlugin("JS9", "Menubar", JS9.Menubar.init, - {onupdateprefs: JS9.Menubar.reset, - dynamicSelect: true, - winDims: [JS9.Menubar.WIDTH, JS9.Menubar.HEIGHT]}); - diff --git a/web/static/js9_old/plugins/core/mousetouch.css b/web/static/js9_old/plugins/core/mousetouch.css deleted file mode 100644 index 1bfba257a180a1c76c9998d799c266cb74a37d15..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/core/mousetouch.css +++ /dev/null @@ -1,30 +0,0 @@ -div.JS9MouseTouchContainer { - padding: 2px; -} - -div.JS9MouseTouchText { - margin: 5px; - padding: 6px 6px 6px 10px; - background: #E9E9E9; - overflow: auto; - border: 1px solid transparent; -} - -div.JS9MouseTouchAction { - margin: 5px; - padding: 6px; - background: #E9E9E9; - overflow: auto; - border: 1px solid black; -} - -div.JS9MouseTouchHeader, div.JS9MouseTouchFooter { - background: #E9E9E9; - text-align: center; - padding: 0px; - margin-left: 15px; - margin-top: 5px; - margin-right: 5px; - margin-bottom: 0px; - border: 1px solid transparent; -} diff --git a/web/static/js9_old/plugins/core/panner.js b/web/static/js9_old/plugins/core/panner.js deleted file mode 100644 index e1c820285c201abaaf61c1dc8279006cadbf436e..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/core/panner.js +++ /dev/null @@ -1,614 +0,0 @@ -/* - * Panner plugin - */ - -/*global $, JS9 */ - -"use strict"; - -// create our namespace, and specify some meta-information and params -JS9.Panner = {}; -JS9.Panner.CLASS = "JS9"; -JS9.Panner.NAME = "Panner"; -JS9.Panner.WIDTH = 320; // width of light window -JS9.Panner.HEIGHT = 320; // height of light window -JS9.Panner.SWIDTH = 250; // width of div -JS9.Panner.SHEIGHT = 250; // height of div -JS9.Panner.VSIZE = 30; -JS9.Panner.NORTH = { - color: "#00FF00", text: "N", fontSize: 12, fontFamily: "Helvetica", - strokeWidth: 1, strokeDashArray: [2,1] -}; -JS9.Panner.EAST = { - color: "#FFFF00", text: "E", fontSize: 12, fontFamily: "Helvetica", - strokeWidth: 1, strokeDashArray: [2,1] -}; - -// defaults for panner -JS9.Panner.opts = { - // override fabric defaults - hasControls: false, - hasRotatingPoint: false, - hasBorders: false, - // initial panner zoom - zoom: 4, - // canvas options - canvas: { - selection: true - }, - // panner box colors - tagcolors: { - defcolor: "#00FF00" - } -}; - -// call a JS9 routine from a button in the panner plugin toolbar -// the plugin instantiation saves the display id in the toolbar div -JS9.Panner.bcall = function(...args){ - let dispid, pinst, im; - let [which, cmd, arg1] = args; - // the button plugintoolbar div has data containing the id of the display - dispid = $(which).closest("div[class^=JS9PluginToolbar]").data("displayid"); - if( dispid ){ - im = JS9.getImage(JS9.getDynamicDisplayOr(dispid)); - pinst = im.display.pluginInstances.JS9Panner; - } else { - JS9.error(`can't find display for cmd: ${cmd}`); - } - if( !im ){ - JS9.error(`can't find image for cmd: ${cmd}`); - } - switch(cmd){ - case "zoomPanner": - if( args.length < 3 ){ - JS9.error(`missing arg(s) for cmd: ${cmd}`); - } - try{ - JS9.Panner.zoom.call(pinst, im, arg1); - } catch(e){ - JS9.error("error calling zoomPanner()", e); - } - break; - case "panImage": - try{ - im.setPan(); - } catch(e){ - JS9.error("error calling setPan()", e); - } - break; - default: - break; - } -}; - -// html used by the panner plugin -JS9.Panner.HTML = -"" + -"" + -"" + -"" + -"" + -""; - -// JS9 Panner constructor -JS9.Panner.init = function(width, height){ - // set width and height on div - this.width = this.divjq.attr("data-width"); - if( !this.width ){ - this.width = width || JS9.Panner.WIDTH; - } - this.divjq.css("width", this.width); - this.width = parseInt(this.divjq.css("width"), 10); - this.height = this.divjq.attr("data-height"); - if( !this.height ){ - this.height = height || JS9.Panner.HEIGHT; - } - this.divjq.css("height", this.height); - this.height = parseInt(this.divjq.css("height"), 10); - // create DOM canvas element - this.canvas = document.createElement("canvas"); - // jquery version for event handling and DOM manipulation - this.canvasjq = $(this.canvas); - // set class - this.canvasjq.addClass("JS9Panner"); - // required so graphical layers will be on top: - this.canvasjq.css("z-index", JS9.ZINDEX); - // how do we allow users to set the size of the canvas?? - // it doesn't go into the CSS and we have no canvas on the Web page ... - this.canvasjq.attr("width", this.width); - this.canvasjq.attr("height", this.height); - // drawing context - this.context = this.canvas.getContext("2d"); - // turn off anti-aliasing - if( !JS9.ANTIALIAS ){ - this.context.imageSmoothingEnabled = false; - this.context.webkitImageSmoothingEnabled = false; - this.context.msImageSmoothingEnabled = false; - } - // add container with canvas to the high-level div - this.containerjq = $("
    ") - .addClass("JS9Container") - .append(this.canvasjq) - .appendTo(this.divjq); - // display current image in panner - if( this.display.image ){ - JS9.Panner.disp.call(this, this.display.image); - } -}; - -// create panner (RGB) image from scaled colorCells -// sort of from: tksao1.0/frame/truecolor.c, but not really -// part of panner plugin -JS9.Panner.create = function(im){ - let panDisp, panner, sect, img; - let x0, y0, xblock, yblock; - let i, j, ii, jj, kk; - let ioff, ooff; - let width, height; - let pos, ix, iy; - let dlayer; - // sanity checks - if( !im || !im.raw || - (!im.useOffScreenCanvas() && !im.colorData) || - !im.display.pluginInstances.JS9Panner ){ - return null; - } - // add panner object to image, if necessary - if( !im.panner ){ - im.panner = {}; - } - // init zoom factor, if necessary - if( !im.panner.zoom ){ - im.panner.zoom = 1; - } - // convenience variables - panDisp = im.display.pluginInstances.JS9Panner; - panner = im.panner; - sect = im.rgb.sect; - // size image - width = Math.min(im.raw.width, panDisp.width); - height = Math.min(im.raw.height, panDisp.height); - // block RGB image to fit into panner window - panner.xblock = im.raw.width / width; - panner.yblock = im.raw.height / height; - if( panner.xblock > panner.yblock ){ - height = Math.floor(height / panner.xblock * panner.yblock + 0.5); - panner.yblock = panner.xblock; - } else if( panner.yblock > panner.xblock ){ - width = Math.floor(width / panner.yblock * panner.xblock + 0.5); - panner.xblock = panner.yblock; - } - // create an RGB image the same size as the raw data - img = im.display.context.createImageData(width,height); - // calculate block factors and starting points based on zoom and block - if( panner.zoom === 1 ){ - xblock = panner.xblock; - yblock = panner.yblock; - x0 = 0; - y0 = 0; - } else { - xblock = panner.xblock / panner.zoom; - yblock = panner.yblock / panner.zoom; - // x0, y0 is the corner of the section of the image we can display in - // the panner (we can't display the whole image if we are zoomed). - x0 = Math.max(0, ((sect.x0 + sect.x1) - (width * xblock)) / 2); - y0 = Math.max(0, ((sect.y0 + sect.y1) - (height * yblock)) / 2); - } - // save lower limits for display - panner.x0 = x0; - panner.y0 = y0; - // save as panner image - panner.img = img; - panner.ix = 0; - panner.iy = 0; - if( im.useOffScreenCanvas() ){ - // for a static RGB file, access the RGB data directly - for(j=0; j { - let im, disp, panDisp; - disp = JS9.getDynamicDisplayOr(this.display); - if( disp && disp.image ){ - im = disp.image; - } else { - im = this.display.image; - } - if( im ){ - panDisp = im.display.pluginInstances.JS9Panner; - pos = opts.target.getCenterPoint(); - // flips will change the pan position - if( im.params.flip === "x" ){ - pos.x = panDisp.width - pos.x; - } else if( im.params.flip === "y" ){ - pos.y = panDisp.height - pos.y; - } else if( im.params.flip === "xy" ){ - pos.x = panDisp.width - pos.x; - pos.y = panDisp.height - pos.y; - } - // rotations will change the pan position - if( im.params.rot90 ){ - pos = JS9.rotatePoint(pos, - im.params.rot90, - {x:panDisp.width/2, y:panDisp.height/2}); - } - // rotations will change the pan position - if( im.params.rotate ){ - pos = JS9.rotatePoint(pos, - im.params.rotate, - {x:panDisp.width/2, y:panDisp.height/2}); - } - ix = ((pos.x - im.panner.ix) * - im.panner.xblock / im.panner.zoom) + im.panner.x0; - iy = ((dlayer.canvas.height - (pos.y + im.panner.iy)) * - im.panner.yblock / im.panner.zoom) + im.panner.y0; - // pan the image - try{ - // avoid triggering a re-pan - panDisp.status = "inactive"; - // pan image - im.setPan(ix, iy); - } - catch(e){JS9.log("couldn't pan image", e);} - finally{panDisp.status = "active";} - } - }); - return im; -}; - -// display the image on the panner canvas -JS9.Panner.disp = function(im){ - let panDisp, panner, sect, tblkx, tblky; - let obj, nx, ny, nwidth, nheight, cenx, ceny, pos; - let npos1, npos2, nobj, nobjt; - let epos1, epos2, eobj, eobjt; - let angle, xflip, yflip, wcsinfo, w2, h2, m, ctx; - const img2canvas = (im, img) => { - let context, canvas; - let panner = im.display.pluginInstances.JS9Panner; - if( !panner.offscreenRGB ){ - canvas = document.createElement("canvas"); - context = canvas.getContext("2d"); - // turn off anti-aliasing - if( !JS9.ANTIALIAS ){ - context.imageSmoothingEnabled = false; - } - panner.offscreenRGB = {canvas, context}; - } - panner.offscreenRGB.canvas.width = img.width; - panner.offscreenRGB.canvas.height = img.height; - panner.offscreenRGB.context.putImageData(img, 0, 0); - return panner.offscreenRGB.canvas; - }; - // sanity check - // only display if we have an image and panner present - if( !im || - !im.display.pluginInstances.JS9Panner || - im.display.pluginInstances.JS9Panner.status !== "active" ){ - return; - } - // always remake make panner image (might be zooming, for example) - if( !JS9.Panner.create.call(this, im) ){ - return; - } - // convenience variables - wcsinfo = im.raw.wcsinfo || {cdelt1: 1, cdelt2: 1, crot: 0}; - panner = im.panner; - panDisp = im.display.pluginInstances.JS9Panner; - sect = im.rgb.sect; - cenx = panDisp.width/2; - ceny = panDisp.height/2; - ctx = panDisp.context; - // we're done if there is no panner image - if( !panner.img ){ - return; - } - // offsets into display - if( panner.img.width < panDisp.width ){ - panner.ix = Math.floor((panDisp.width - panner.img.width)/2); - } - if( panner.img.height < panDisp.height ){ - panner.iy = Math.floor((panDisp.height - panner.img.height)/2); - } - // clear first - JS9.Panner.clear.call(this, im); - // save context - ctx.save(); - // do we need to apply the canvas transform? - if( im.params.transform ){ - // this is the transform matrix - m = im.params.transform; - // translate origin to center of display - w2 = panDisp.width / 2; - h2 = panDisp.height / 2; - ctx.translate(w2, h2); - // set new transform - ctx.transform(m[0][0], m[0][1], m[1][0], m[1][1], m[2][0], m[2][1]); - // translate back to 0, 0 - ctx.translate(-w2, -h2); - } - // draw the image into the context - // ctx.putImageData(panner.img, panner.ix, panner.iy); - ctx.drawImage(img2canvas(im, panner.img), panner.ix, panner.iy); - // restore original context - ctx.restore(); - // display panner rectangle - // convenience variables - tblkx = panner.zoom / panner.xblock; - tblky = panner.zoom / panner.yblock; - // size of rectangle - nwidth = im.display.width * tblkx / sect.zoom; - nheight = im.display.height * tblky / sect.zoom; - // position of the rectangle - nx = (sect.x0 - panner.x0) * tblkx + panner.ix; - ny = panDisp.height - ((sect.y1 - panner.y0) * tblky + panner.iy); - // adjust for section offset - if( im.display.width !== sect.width ){ - nx -= (im.display.width - sect.width) * tblkx / sect.zoom / 2; - } - if( im.display.height !== sect.height ){ - ny -= (im.display.height - sect.height) * tblky / sect.zoom / 2; - } - // convert to center pos - nx += nwidth / 2; - ny += nheight / 2; - // flips will change the pan position - if( im.params.flip === "x" ){ - nx = panDisp.width - nx; - } else if( im.params.flip === "y" ){ - ny = panDisp.height - ny; - } else if( im.params.flip === "xy" ){ - nx = panDisp.width - nx; - ny = panDisp.height - ny; - } - // rotations will change the pan position - if( im.params.rot90 ){ - pos = JS9.rotatePoint({x: nx, y: ny}, - - im.params.rot90, - {x:panDisp.width/2, y:panDisp.height/2}); - nx = pos.x; - ny = pos.y; - } - // rotations will change the pan position - if( im.params.rotate ){ - pos = JS9.rotatePoint({x: nx, y: ny}, - - im.params.rotate, - {x:panDisp.width/2, y:panDisp.height/2}); - nx = pos.x; - ny = pos.y; - } - // hide rectangle if it covers the full panner - if( nwidth >= panDisp.width ){ - nx = panDisp.width / 2; - nwidth = panDisp.width + 10; - } - if( nheight >= panDisp.height ){ - ny = panDisp.height / 2; - nheight = panDisp.height + 10; - } - // object containing position and size parameters: - obj = {left: nx, top: ny, width: nwidth, height: nheight}; - // create the box - if( !im.panner.boxid ){ - im.panner.boxid = im.addShapes("panner", "box", obj); - } else { - im.changeShapes("panner", im.panner.boxid, obj); - } - // clear direction vectors - if( im.panner.northid ){ - im.removeShapes("panner", im.panner.northid); - im.removeShapes("panner", im.panner.northidt); - } - if( im.panner.eastid ){ - im.removeShapes("panner", im.panner.eastid); - im.removeShapes("panner", im.panner.eastidt); - } - // done if we are not displaying the directions vectors or no wcs - if( !JS9.globalOpts.pannerDirections || !im.raw.wcs || im.raw.wcs <= 0 ){ - return im; - } - // get north is up info - nobj = im.getNorthIsUp(); - // angle - angle = nobj.angle; - // take existing rotation into account - if( JS9.notNull(im.params.rot90) ){ - angle -= im.params.rot90; - } - // take existing rotation into account - if( JS9.notNull(im.params.rotate) ){ - angle -= im.params.rotate; - } - // flip - xflip = nobj.xflip ? -1 : 1; - yflip = nobj.yflip ? -1 : 1; - switch(im.params.flip){ - case "x": - xflip *= -1; - break; - case "y": - yflip *= -1; - break; - case "xy": - xflip *= -1; - yflip *= -1; - break; - default: - break; - } - // this is the line pointing north - npos1 = {x: cenx, y: ceny}; - if( wcsinfo.cdelt2 >= 0 ){ - npos2 = {x: cenx, y: ceny - JS9.Panner.VSIZE * yflip}; - } else { - npos2 = {x: cenx, y: ceny + JS9.Panner.VSIZE * yflip}; - } - npos2 = JS9.rotatePoint(npos2, angle, npos1); - nobj = {color: JS9.Panner.NORTH.color, - strokeWidth: JS9.Panner.NORTH.strokeWidth, - strokeDashArray: JS9.Panner.NORTH.strokeDashArray, - points: [npos1, npos2], - changeable: false, - // hack around fabric.js problems - originX: "left", originY: "top", noLeftTop: true}; - im.panner.northid = im.addShapes("panner", "line", nobj); - // this is the text 'N' - nobjt = {color: JS9.Panner.NORTH.color, - text: JS9.Panner.NORTH.text, - fontSize: JS9.Panner.NORTH.fontSize, - fontFamily: JS9.Panner.NORTH.fontFamily, - changeable: false, - left: npos2.x, top: npos2.y}; - im.panner.northidt = im.addShapes("panner", "text", nobjt); - // this is the line pointing east - epos1 = {x: cenx, y: ceny}; - if( wcsinfo.cdelt1 < 0 ){ - epos2 = {x: cenx - JS9.Panner.VSIZE * xflip, y: ceny}; - } else { - epos2 = {x: cenx + JS9.Panner.VSIZE * xflip, y: ceny}; - } - epos2 = JS9.rotatePoint(epos2, angle, epos1); - eobj = {color: JS9.Panner.EAST.color, - strokeWidth: JS9.Panner.EAST.strokeWidth, - strokeDashArray: JS9.Panner.EAST.strokeDashArray, - changeable: false, - points: [epos1, epos2], - // hack around fabric.js problems - originX: "left", originY: "top", noLeftTop: true}; - im.panner.eastid = im.addShapes("panner", "line", eobj); - // this is the text 'E' - eobjt = {color: JS9.Panner.EAST.color, - text: JS9.Panner.EAST.text, - fontSize: JS9.Panner.EAST.fontSize, - fontFamily: JS9.Panner.EAST.fontFamily, - changeable: false, - left: epos2.x, top: epos2.y}; - im.panner.eastidt = im.addShapes("panner", "text", eobjt); - return im; -}; - -// zoom the rectangle inside the panner (RGB) image -JS9.Panner.zoom = function(im, zval){ - let panner, ozoom, nzoom; - // sanity check - if( !im || !im.panner || !im.display.pluginInstances.JS9Panner ){ - return; - } - panner = im.panner; - // get old zoom - ozoom = panner.zoom; - // determine new zoom - switch(zval.charAt(0)){ - case "*": - case "x": - case "X": - nzoom = Math.min(Math.min(this.width, this.height), - ozoom * parseFloat(zval.slice(1))); - break; - case "/": - nzoom = Math.max(1, ozoom / parseFloat(zval.slice(1))); - break; - default: - nzoom = parseFloat(zval); - break; - } - // sanity check - if( !nzoom || (nzoom < 1) ){ - nzoom = 1; - } - panner.zoom = nzoom; - // redisplay the panner - JS9.Panner.disp.call(this, im); - return im; -}; - -// dynamic selection change -JS9.Panner.dysel = function(im){ - let panner; - if( im ){ - panner = im.display.pluginInstances.JS9Panner; - if( panner && panner.isDynamic ){ - JS9.Panner.disp.call(this, im); - } - } -}; - -// clear the panner -JS9.Panner.clear = function(im){ - let panner, display; - if( im ){ - display = JS9.getDynamicDisplayOr(this.display); - panner = im.display.pluginInstances.JS9Panner; - if( panner && (im.display === display) ){ - panner.context.clear(); - im.removeShapes("panner", "all"); - im.panner.boxid = null; - } - return im; - } -}; - -// add this plugin into JS9 -JS9.RegisterPlugin(JS9.Panner.CLASS, JS9.Panner.NAME, JS9.Panner.init, - {menuItem: "Panner", - help: "help/panner.html", - dynamicSelect: true, - toolbarSeparate: false, - toolbarHTML: JS9.Panner.HTML, - ondynamicselect: JS9.Panner.dysel, - onplugindisplay: JS9.Panner.disp, - onimagedisplay: JS9.Panner.disp, - onimageclose: JS9.Panner.clear, - onimageclear: JS9.Panner.clear, - onupdateprefs: JS9.Panner.disp, - onsetwcssys: JS9.Panner.disp, - winTitle: "Panner", - winDims: [JS9.Panner.WIDTH, JS9.Panner.HEIGHT], - divArgs: [JS9.Panner.SWIDTH, JS9.Panner.SHEIGHT]}); diff --git a/web/static/js9_old/plugins/core/prefs.js b/web/static/js9_old/plugins/core/prefs.js deleted file mode 100644 index 1d83af14f02a88ef40cdbf20195a376e2c9576e4..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/core/prefs.js +++ /dev/null @@ -1,1094 +0,0 @@ -/* - * preferences plugin (14 April 2015) - */ - -/*global $, JS9, ddtabcontent */ - -"use strict"; - -// To specify the JS9 display instance to link to a given PREFS div, -// use the HTML5 dataset syntax: -//
    - -// create our namespace, and specify some meta-information and params -JS9.Prefs = {}; -JS9.Prefs.CLASS = "JS9"; // class of plugins (1st part of div class) -JS9.Prefs.NAME = "Preferences"; // name of this plugin (2nd part of div class) -JS9.Prefs.WIDTH = 800; // default width of window -JS9.Prefs.HEIGHT = 400; // default height of window - -JS9.Prefs.imagesSchema = { - "title": "Image Preferences", - "description": "Preferences for each displayed image", - "properties": { - "colormap": { - "type": "string", - "helper": "default color map" - }, - "contrast": { - "type": "number", - "helper": "default color contrast" - }, - "bias": { - "type": "number", - "helper": "default color bias" - }, - "scale": { - "type": "string", - "helper": "default scale algorithm" - }, - "scaleclipping": { - "type": "string", - "helper": "'dataminmax' or 'zscale'" - }, - "zscalecontrast": { - "type": "number", - "helper": "default from ds9" - }, - "zscalesamples": { - "type": "number", - "helper": "default from ds9" - }, - "zscaleline": { - "type": "number", - "helper": "default from ds9" - }, - "exp": { - "type": "number", - "helper": "default exp value for scaling" - }, - "wcssys": { - "type": "string", - "helper": "current WCS system" - }, - "wcsunits": { - "type": "string", - "helper": "current WCS units" - }, - "lcs": { - "type": "string", - "helper": "default logical coordinate system" - }, - "opacity": { - "type": "number", - "helper": "opacity for images (0.0 to 1.0)" - }, - "zoom": { - "type": "number", - "helper": "default zoom factor" - }, - "zooms": { - "type": "number", - "helper": "how many zooms in each direction?" - }, - "nancolor": { - "type": "string", - "helper": "6-digit #hex color for NaN values" - }, - "overlay": { - "type": "boolean", - "helper": "display png/jpeg overlay?" - }, - "listonchange": { - "type": "boolean", - "helper": "list after a region change?" - }, - "whichonchange": { - "type": "string", - "helper": "list 'all' or 'selected'?" - }, - "valpos": { - "type": "boolean", - "helper": "display value/position?" - }, - "inherit": { - "type": "boolean", - "helper": "new images inherit current params?" - }, - "invert": { - "type": "boolean", - "helper": "by default, invert colormap?" - }, - "disable": { - "type": "mobject", - "helper": "array of core funcs to disable" - } - } -}; - -JS9.Prefs.regionsSchema = { - "title": "Region Preferences", - "description": "Preferences for each displayed region", - "type": "object", - "properties": { - "iradius": { - "type": "number", - "helper": "annulus: initial inner radius" - }, - "oradius": { - "type": "number", - "helper": "annulus: initial outer radius" - }, - "nannuli": { - "type": "number", - "helper": "annulus: initial number of annuli" - }, - "width": { - "type": "number", - "helper": "box: initial width" - }, - "height": { - "type": "number", - "helper": "box: initial height" - }, - "radius": { - "type": "number", - "helper": "circle: initial radius" - }, - "r1": { - "type": "number", - "helper": "ellipse: initial radius1" - }, - "r2": { - "type": "number", - "helper": "ellipse: initial radius2" - }, - "angle": { - "type": "number", - "helper": "box, ellipse: initial angle in degrees" - }, - "polypoints": { - "type": "mobject", - "helper": "polygon: x,y relative positions" - }, - "linepoints": { - "type": "mobject", - "helper": "line: x,y relative positions" - }, - "ptshape": { - "type": "string", - "helper": "point shape: box, circle, ellipse" - }, - "ptsize": { - "type": "number", - "helper": "point: size" - }, - "tags": { - "type": "string", - "helper": "initial tags for a region" - }, - "strokeWidth": { - "type": "number", - "helper": "region stroke width" - }, - "fontFamily": { - "type": "string", - "helper": "region font" - }, - "fontSize": { - "type": "string", - "helper": "region font size" - }, - "fontStyle": { - "type": "string", - "helper": "region font style" - }, - "fontWeight": { - "type": "string", - "helper": "region font weight" - }, - "textAlign": { - "type": "string", - "helper": "text alignment" - } - } -}; - -JS9.Prefs.gridSchema = { - "title": "Grid Preferences", - "description": "Preferences for wcs coordinate grids", - "type": "object", - "properties": { - "strokeWidth": { - "type": "number", - "helper": "grid stroke width" - }, - "lineColor": { - "type": "string", - "helper": "color of grid lines" - }, - "raLines": { - "type": "number", - "helper": "approx. number of RA grid lines" - }, - "raAngle": { - "type": "number", - "helper": "rotation for RA label" - }, - "raSkip": { - "type": "number", - "helper": "number of RA lines to skip" - }, - "decLines": { - "type": "number", - "helper": "approx. number of Dec grid lines" - }, - "decAngle": { - "type": "number", - "helper": "rotation for Dec label" - }, - "decSkip": { - "type": "number", - "helper": "number of Dec lines to skip" - }, - "labelColor": { - "type": "string", - "helper": "color of text labels" - }, - "labelFontFamily": { - "type": "string", - "helper": "label font" - }, - "labelFontSize": { - "type": "string", - "helper": "label font size" - }, - "labelFontStyle": { - "type": "string", - "helper": "label font style" - }, - "labelFontWeight": { - "type": "string", - "helper": "label font weight" - }, - "labelRAOffx": { - "type": "number", - "helper": "x offset of RA labels" - }, - "labelRAOffy": { - "type": "number", - "helper": "y offset of RA labels" - }, - "labelDecOffx": { - "type": "number", - "helper": "x offset of Dec labels" - }, - "labelDecOffy": { - "type": "number", - "helper": "y offset of Dec labels" - }, - "degPrec": { - "type": "number", - "helper": "precision for degree labels" - }, - "sexaPrec": { - "type": "number", - "helper": "precision for sexagesimal labels" - }, - "reduceDims": { - "type": "boolean", - "helper": "reduce lines of smaller image dim?" - }, - "stride": { - "type": "number", - "helper": "fineness of grid lines" - }, - "margin": { - "type": "number", - "helper": "edge margin for displaying a grid line" - }, - "labelMargin": { - "type": "number", - "helper": "edge margin for displaying a label" - }, - "cover": { - "type": "string", - "helper": "grid lines cover: display or image" - } - } -}; - -// schema for each source -JS9.Prefs.fitsSchema = { - "title": "FITS Preferences", - "description": "Preferences for processing FITS files", - "properties": { - "extlist": { - "type": "string", - "helper": "default binary table extensions" - }, - "xdim": { - "type": "string", - "helper": "x dim of image section from table" - }, - "ydim": { - "type": "string", - "helper": "y dim of image section from table" - }, - "bin": { - "type": "string", - "helper": "bin factor for tables" - }, - "ixdim": { - "type": "string", - "helper": "x dim of image section from image" - }, - "iydim": { - "type": "string", - "helper": "y dim of image section from table" - }, - "ibin": { - "type": "string", - "helper": "bin factor for images" - }, - "binMode": { - "type": "string", - "helper": "'s' for summing, 'a' for averaging" - }, - "clear": { - "type": "string", - "helper": "clear image's virtual file memory" - } - } -}; - -// catalogs schema -JS9.Prefs.catalogsSchema = { - "title": "Catalogs Preferences", - "description": "Preferences for loading tab-delimited catalogs", - "properties": { - "ras": { - "type": "mobject", - "helper": "RA patterns to look for in table" - }, - "decs": { - "type": "mobject", - "helper": "Dec patterns to look for in table" - }, - "wcssys": { - "type": "string", - "helper": "wcs system of catalog" - }, - "shape": { - "type": "string", - "helper": "shape of objects" - }, - "color": { - "type": "string", - "helper": "color of objects" - }, - "width": { - "type": "number", - "helper": "width of box objects" - }, - "height": { - "type": "number", - "helper": "height of box objects" - }, - "radius": { - "type": "number", - "helper": "radius of circle objects" - }, - "r1": { - "type": "number", - "helper": "r1 of ellipse objects" - }, - "r2": { - "type": "number", - "helper": "r2 of ellipse objects" - }, - "tooltip": { - "type": "string", - "helper": "tooltip format for objects" - }, - "skip": { - "type": "string", - "helper": "comment character in table" - } - } -}; - -// global schema for the page -JS9.Prefs.globalsSchema = { - "title": "Global Preferences", - "description": "Global preferences for all JS9 displays", - "properties": { - "topColormaps": { - "type": "mobject", - "helper": "array of top-level colormaps" - }, - "infoBox": { - "type": "mobject", - "helper": "array of infoBox items to display" - }, - "statusBar": { - "type": "string", - "helper": "format of statusbar display" - }, - "toolBar": { - "type": "mobject", - "helper": "array of toolbar tools to display" - }, - "separate": { - "type": "mobject", - "helper": "options when separating images" - }, - "mouseActions": { - "type": "mobject", - "helper": "array of mouse actions" - }, - "touchActions": { - "type": "mobject", - "helper": "array of touch actions" - }, - "keyboardActions": { - "type": "mobject", - "helper": "object containing keyboard actions" - }, - "centerDivs": { - "type": "mobject", - "helper": "divs used when centering" - }, - "resizeDivs": { - "type": "mobject", - "helper": "divs used when resizing" - }, - "plot3d": { - "type": "mobject", - "helper": "options for 3D data cube plot" - }, - "syncOps": { - "type": "mobject", - "helper": "ops to sync between images" - }, - "wcsUnits": { - "type": "mobject", - "helper": "default units for WCS systems" - }, - "copyWcsPosFormat": { - "type": "string", - "helper": "format string using: $ra $dec $sys" - }, - "fallbackDisplay": { - "type": "string", - "helper": "can messages fallback to display win?" - }, - "lightWinClose": { - "type": "string", - "helper": "ask,close,move when closing lightwin" - }, - "fits2fits": { - "type": "string", - "helper": "make rep file?: true,false,size>N" - }, - "dynamicSelect": { - "type": "string", - "helper": "select display: click, move, false" - }, - "panRefreshLimit": { - "type": "number", - "helper": "# of shapes to minimze refresh during pan" - }, - "regDisplay": { - "type": "string", - "helper": "show regions in 'lightwin' or 'display'" - }, - "regMenuCreate": { - "type": "boolean", - "helper": "region menu selections create regions?" - }, - "regSyncTextColor": { - "type": "boolean", - "helper": "sync region text color with main color?" - }, - "regToClipboard": { - "type": "boolean", - "helper": "region mods to pseudo-clipboard?" - }, - "regListDCoords": { - "type": "boolean", - "helper": "list regions preserving dcoords? " - }, - "metaClickPan": { - "type": "boolean", - "helper": "meta-click pans to mouse position?" - }, - "mousetouchZoom": { - "type": "boolean", - "helper": "scroll/pinch to zoom?" - }, - "mousetouchLimit": { - "type": "boolean", - "helper": "limit zoom-out to the size of the image?" - }, - "clickToFocus": { - "type": "boolean", - "helper": "click display to focus?" - }, - "valposDCoords": { - "type": "boolean", - "helper": "valpos shows display coords?" - }, - "toolbarTooltips": { - "type": "boolean", - "helper": "show tooltips in Toolbar plugin?" - }, - "updateTitlebar": { - "type": "boolean", - "helper": "update titlebar with image id?" - }, - "logoDisplay": { - "type": "boolean", - "helper": "show JS9 logo?" - }, - "reloadRefresh": { - "type": "boolean", - "helper": "does a reload refresh the data?" - }, - "reloadRefreshReg": { - "type": "boolean", - "helper": "reloading regions file removes prev?" - }, - "syncReciprocate": { - "type": "boolean", - "helper": "reciprocal image sync'ing?" - }, - "syncWCS": { - "type": "boolean", - "helper": "sync using wcs (e.g. pan)?" - }, - "nextImageMask": { - "type": "boolean", - "helper": "nextImage() show image masks?" - }, - "panWithinDisplay": { - "type": "boolean", - "helper": "keep panned image within the display?" - }, - "pannerDirections": { - "type": "boolean", - "helper": "show direction vectors in panner?" - }, - "magnifierRegions": { - "type": "boolean", - "helper": "show regions in magnifier?" - }, - "xeqPlugins": { - "type": "boolean", - "helper": "execute plugin callbacks?" - }, - "extendedPlugins": { - "type": "boolean", - "helper": "execute extended plugins?" - }, - "intensivePlugins": { - "type": "boolean", - "helper": "execute intensive plugins?" - }, - "svgBorder": { - "type": "boolean", - "helper": "add border when exporting SVG?" - } - } -}; - -// favorites schema for the page -JS9.Prefs.favoritesSchema = { - "title": "Favorites Preferences", - "description": "Favorites for all JS9 displays", - "properties": { - "scales": { - "type": "mobject", - "helper": "array of favorite scales" - }, - "colormaps": { - "type": "mobject", - "helper": "array of favorite colormaps" - }, - "regions": { - "type": "mobject", - "helper": "array of favorite regions" - }, - "wcs": { - "type": "mobject", - "helper": "array of favorite wcs systems" - } - } -}; - -// scheme for desktop apps only -JS9.Prefs.desktopSchema = { - "title": "Desktop App Preferences", - "description": "Desktop app preferences will take effect on restart", - "properties": { - "webpage": { - type: "string", - "helper": "web page to display" - }, - "width": { - type: "number", - "helper": "width of desktop window" - }, - "height": { - type: "number", - "helper": "height of desktop window" - }, - "hostfs": { - type: "boolean", - "helper": "utilize host file system?" - }, - "debug": { - type: "boolean", - "helper": "display Chrome debugger at startup?" - } - } -}; - -// source object for preferences -JS9.Prefs.sources = [ - {name: "globals", schema: JS9.Prefs.globalsSchema}, - {name: "images", schema: JS9.Prefs.imagesSchema}, - {name: "fits", schema: JS9.Prefs.fitsSchema}, - {name: "regions", schema: JS9.Prefs.regionsSchema}, - {name: "grid", schema: JS9.Prefs.gridSchema}, - {name: "catalogs", schema: JS9.Prefs.catalogsSchema}, - {name: "favorites", schema: JS9.Prefs.favoritesSchema}, - {name: "desktop", schema: JS9.Prefs.desktopSchema} -]; - -// init preference plugin -JS9.Prefs.init = function(){ - let i, s, obj, key, props, sources, source, id, pid, html, prompt; - // create the div containing one tab for each of the sources - sources = JS9.Prefs.sources; - pid = `${this.id}prefsTabs`; - html = "
    "; - html += `
    \n`; - html += "
      "; - // create a tab for each source - for(i=0; i${source.name}\n`; - } - html += "
    "; - html += "

    \n"; - // create each param form (displayed by clicking each tab) - for(i=0; i`; - html += `

    `; - html += `
    ${source.schema.description}

    `; - props = source.schema.properties || {}; - for( key of Object.keys(props) ){ - obj = props[key]; - prompt = obj.prompt || `${key}:`; - switch(obj.type){ - case "boolean": - if( source.data[key] ){ - s = "checked"; - } else { - s = ""; - } - html += `

    ${prompt}${obj.helper}
    `; - break; - default: - if( typeof source.data[key] === "object" ){ - if( obj.type === "mobject" ){ - s = JSON.stringify(source.data[key], null, 2); - } else { - s = JSON.stringify(source.data[key]); - } - } else if( JS9.isNull(source.data[key]) ){ - s = ""; - } else { - s = source.data[key]; - } - if( obj.type === "mobject" ){ - html += `
    ${prompt}${obj.helper}
    `; - } else { - html += `
    ${prompt}${obj.helper}
    `; - } - break; - } - } - if( !JS9.cmdlineOpts ){ - html += ``; - } - // manage stored preferences - if( {}.hasOwnProperty.call(window, "localStorage") && - JS9.globalOpts.localStorage ){ - html += ``; - html += ``; - html += ""; - } - // light windows get a close button - if( this.winType === "light" ){ - html += ``; - } - html += "
    "; - html += "
    "; - } - // allow scrolling on the plugin - this.divjq.addClass("JS9PluginScrolling"); - // set the html for this div - this.divjq.html(html); - // for each source, set data values which we will need in button callbacks - for(i=0; i {return {"name": e.name, "value": "false"};}).get()); - JS9.Prefs.processForm(source, arr2, display, winid); - return false; -}; - -// action for Save in Form -JS9.Prefs.saveForm = function(){ - let props, key; - const form = $(this).closest("form"); - const source = form.data("source"); - const opts = {cmd: "desktop", mode: "save"}; - const saveobj = {}; - JS9.Prefs.applyForm.call(this); - // desktop handled specially - if( source.name === "desktop" ){ - if( window.electron ){ - window.setTimeout(() => { - try{ - opts.cmdlineOpts = JS9.cmdlineOpts; - window.electron.sendMsg(opts); - } - catch(e){ JS9.error("could not save desktop form", e); } - }, JS9.TIMEOUT); - } else { - JS9.error("desktop save is only available for the JS9 desktop app"); - } - return false; - } - try{ - // only save props in the schema: e.g., don't save all of globalOpts - props = source.schema.properties || {}; - for( key of Object.keys(props) ){ - saveobj[key] = source.data[key]; - } - localStorage.setItem(source.name, JSON.stringify(saveobj, null, 2)); - JS9.userOpts[source.name] = localStorage.getItem(source.name); - } - catch(e){ JS9.error(`could not save prefs: ${source.name}`); } - return false; -}; - -// action for Show in Form -JS9.Prefs.showForm = function(){ - let s, t; - const form = $(this).closest("form"); - const source = form.data("source"); - // desktop handled specially - if( source.name === "desktop" ){ - if( JS9.cmdlineOpts ){ - s = JSON.stringify(JS9.cmdlineOpts, null, 4); - t = `
    ${s}
    `; - } else { - t = `

    No saved prefs: ${source.name}
    `; - } - } else { - try{ s = localStorage.getItem(source.name); } - catch(e){ /* empty */ } - if( s && (s !== "null") ){ - t = `
    ${s}
    `; - } else { - t = `

    No saved prefs: ${source.name}
    `; - } - } - JS9.lightWin(`savedPrefs${JS9.uniqueID()}`, "inline", t, - `Saved prefs: ${source.name}`, - JS9.lightOpts[JS9.LIGHTWIN].textWin); - return false; -}; - -// action for Delete in Form -JS9.Prefs.deleteForm = function(){ - const form = $(this).closest("form"); - const source = form.data("source"); - const opts = {cmd: "desktop", mode: "remove"}; - // desktop handled specially - if( source.name === "desktop" ){ - if( window.electron ){ - window.setTimeout(() => { - try{ window.electron.sendMsg(opts); } - catch(e){ JS9.error("could not save desktop form", e); } - }, JS9.TIMEOUT); - } else { - JS9.error("desktop save is only available for the JS9 desktop app"); - } - return false; - } - try{ localStorage.removeItem(source.name); - delete JS9.userOpts[source.name]; } - catch(e){ /* empty */ } - return false; -}; - -// process new preferences in the preference form -// eslint-disable-next-line no-unused-vars -JS9.Prefs.processForm = function(source, arr, display, winid){ - let i, j, s, key, val, obj, rlayer; - const len = arr.length; - // source-specific pre-processing - switch( source.name ){ - case "images": - obj = JS9.imageOpts; - break; - case "regions": - obj = JS9.Regions.opts; - break; - case "grid": - obj = JS9.Grid.opts; - break; - case "fits": - obj = JS9.fits.options; - break; - case "catalogs": - obj = JS9.globalOpts.catalogs; - break; - case "globals": - obj = JS9.globalOpts; - break; - case "favorites": - obj = JS9.favorites; - break; - case "desktop": - obj = JS9.cmdlineOpts; - break; - default: - JS9.error(`unknown source for preferences: ${source.name}`); - break; - } - for(i=0; i%s'; - -JS9.ScaleLimits.limitsHTML=''; - -JS9.ScaleLimits.axesHTML=''; - -JS9.ScaleLimits.plotHTML='
    Pixel Distribution: %s
    '; - -JS9.ScaleLimits.loHTML='Low:  '; - -JS9.ScaleLimits.hiHTML='High:  '; - -// change scale -JS9.ScaleLimits.xsetscale = function(did, id, target){ - const im = JS9.lookupImage(id, did); - if( im ){ - im.setScale(target.value); - } -}; - -// change low clipping limit -JS9.ScaleLimits.xsetlo = function(did, id, target){ - let val; - const im = JS9.lookupImage(id, did); - if( im ){ - val = parseFloat(target.value); - im.setScale(val, im.params.scalemax); - } -}; - -// change high clipping limit -JS9.ScaleLimits.xsethi = function(did, id, target){ - let val; - const im = JS9.lookupImage(id, did); - if( im ){ - val = parseFloat(target.value); - im.setScale(im.params.scalemin, val); - } -}; - -// other ways to determine limits -JS9.ScaleLimits.xsetlims = function(did, id, target){ - const im = JS9.lookupImage(id, did); - if( im ){ - switch(target.value){ - case "dataminmax": - im.setScale("dataminmax", im.raw.dmin, im.raw.dmax); - break; - case "zscale_z1_z2": - im.setScale("zscale", im.params.z1, im.params.z2); - break; - case "zscale_z1_datamax": - im.setScale("zmax", im.params.z1, im.raw.dmax); - break; - default: - break; - } - } -}; - -// log10 scaling -JS9.ScaleLimits.log10 = function(v){ - return v <= 0 ? null : Math.log(v) / Math.LN10; -}; - -// other ways to determine limits -JS9.ScaleLimits.xaxes = function(did, id, target){ - let plugin; - const im = JS9.lookupImage(id, did); - if( im ){ - // get current plugin instance - plugin = im.display.pluginInstances[JS9.ScaleLimits.BASE]; - // sanity check - if( !plugin || !plugin.plot ){ - return; - } - // change the scale for the specified axis - switch(target.value){ - case "xlinear": - plugin.xscale = "linear"; - JS9.ScaleLimits.doplot.call(plugin, im); - break; - case "xlog": - plugin.xscale = "log"; - JS9.ScaleLimits.doplot.call(plugin, im); - break; - case "ylinear": - plugin.yscale = "linear"; - JS9.ScaleLimits.doplot.call(plugin, im); - break; - case "ylog": - plugin.yscale = "log"; - JS9.ScaleLimits.doplot.call(plugin, im); - break; - default: - break; - } - } - // reset top-level - $(target).val("Plot Axes").prop("selected", true); -}; - -JS9.ScaleLimits.getPixelDist = function(im, ndist){ - let i, idx; - const dist = []; - const dmin = im.raw.dmin; - const drange = im.raw.dmax - im.raw.dmin; - const imlen = im.raw.width * im.raw.height; - for(i=0; i= 0 && idx < ndist ){ - dist[idx] += 1; - } - } - return dist; -}; - -JS9.ScaleLimits.to10E = function(i){ - const superscripts = ["⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"]; - if( JS9.ScaleLimits.AXISFANCY && i >= 0 && i <= 9 ){ - return `10${superscripts[i]}`; - } - return `10E${String(i)}`; -}; - -JS9.ScaleLimits.doplot = function(im){ - let i, j, s, el, xmin, xmax; - let dist, distmin, distmax, ntick, tickinc; - const dmin = im.raw.dmin; - const drange = im.raw.dmax - im.raw.dmin; - const pobj = $.extend(true, {}, JS9.ScaleLimits.dataOpts); - const popts = $.extend(true, {}, JS9.ScaleLimits.plotOpts); - const gettickinc = (datarange) => { - let tickinc; - if( datarange < 10 ){ - tickinc = 1; - } else if( datarange < 50 ){ - tickinc = 5; - } else if( datarange < 250 ){ - tickinc = 10; - } else if( datarange < 500 ){ - tickinc = 50; - } else if( datarange < 2500 ){ - tickinc = 100; - } else if( datarange < 5000 ){ - tickinc = 500; - } else if( datarange < 25000 ){ - tickinc = 1000; - } else if( datarange < 50000 ){ - tickinc = 5000; - } else if( datarange < 250000 ){ - tickinc = 10000; - } else if( datarange < 500000 ){ - tickinc = 50000; - } else if( datarange < 2500000 ){ - tickinc = 100000; - } else if( datarange < 5000000 ){ - tickinc = 500000; - } else if( datarange < 25000000 ){ - tickinc = 1000000; - } else { - tickinc = 10000000; - } - return tickinc; - }; - const annotate = (plot, x, color) => { - const ctx = plot.getCanvas().getContext("2d"); - const size = JS9.ScaleLimits.CARET; - const o = plot.pointOffset({x: x, y: 0}); - ctx.beginPath(); - ctx.moveTo(o.left, o.top); - ctx.lineTo(o.left - size, o.top - (size*2)); - ctx.lineTo(o.left + size, o.top - (size*2)); - ctx.lineTo(o.left, o.top); - ctx.fillStyle = color; - ctx.fill(); - }; - // flag we have just started - this.plotComplete = false; - // plot options - if( this.plotColor ){ - pobj.color = this.plotColor; - } - // pixel distribution - dist = JS9.ScaleLimits.getPixelDist(im, this.ndist); - // convert to flot data - for(i=0; i distmax ){ - distmax = dist[i]; - } - } - ntick = JS9.ScaleLimits.log10(distmax - distmin + 1); - for(i=0; i { - let start = ranges.xaxis.from; - let end = ranges.xaxis.to; - if( this.xscale === "log" ){ - start = Math.pow(10, start); - end = Math.pow(10, end); - } - start = start * drange / this.ndist + dmin; - end = end * drange / this.ndist + dmin; - im.setScale("user", start, end); - }); - el.off("plothover"); - el.on("plothover", (event, pos) => { - let ctx, text, s, x, y, w, h, xval; - let px = pos.x; - // sanity checks - if( !this.plot || !this.plotComplete ){ - return; - } - if( this.xscale === "log" ){ - px = Math.pow(10, px); - } - xval = px * drange / this.ndist + dmin; - if( !Number.isFinite(xval) ){ - return; - } - s = JS9.floatToString(xval); - // display x value in upper right corner of plot - ctx = this.plot.getCanvas().getContext("2d"); - ctx.save(); - ctx.textBaseline = 'top'; - ctx.font = `${JS9.ScaleLimits.XTEXTHEIGHT }px ${JS9.ScaleLimits.XTEXTFONT}`; - ctx.fillStyle = JS9.ScaleLimits.XTEXTCOLOR || "black"; - text = ctx.measureText(s); - w = Math.max(this.lastTextWidth, text.width + 2); - h = JS9.ScaleLimits.XTEXTHEIGHT + 2; - x = this.plotWidth * JS9.ScaleLimits.XTEXTFRAC; - y = this.plotHeight * JS9.ScaleLimits.YTEXTFRAC; - ctx.clearRect(x, y, w, h); - ctx.fillText(s, x, y); - ctx.restore(); - this.lastTextWidth = w; - }); - this.timeout = window.setTimeout( () => { - this.plot = $.plot(el, [pobj], popts); - this.timeout = null; - annotate(this.plot, xmin, this.xlocolor); - annotate(this.plot, xmax, this.xhicolor); - this.plotComplete = true; - }, JS9.ScaleLimits.TIMEOUT); -}; - -// re-init when a different image is displayed -JS9.ScaleLimits.display = function(){ - if( this.lastimage !== this.display.image ){ - JS9.ScaleLimits.init.call(this); - } -}; - -// clear when an image closes -JS9.ScaleLimits.close = function(){ - // ensure plugin display is reset - JS9.ScaleLimits.init.call(this, {mode: "clear"}); -}; - -// constructor: add HTML elements to the plugin -JS9.ScaleLimits.init = function(opts){ - let s, im, mopts, imid, dispid; - const getScales = () => { - let i; - let res = ""; - for(i=0; i${JS9.scales[i]}`; - } - return res; - }; - // on entry, these elements have already been defined: - // this.div: the DOM element representing the div for this plugin - // this.divjq: the jquery object representing the div for this plugin - // this.id: the id ofthe div (or the plugin name as a default) - // this.display: the display object associated with this plugin - // this.dispMode: display mode (for internal use) - // - // opts is optional - opts = opts || {}; - // set width and height of plugin itself - this.width = this.divjq.attr("data-width"); - if( !this.width ){ - this.width = JS9.ScaleLimits.WIDTH; - } - this.divjq.css("width", this.width); - this.width = parseInt(this.divjq.css("width"), 10); - this.height = this.divjq.attr("data-height"); - if( !this.height ){ - this.height = JS9.ScaleLimits.HEIGHT; - } - this.divjq.css("height", this.height); - this.height = parseInt(this.divjq.css("height"), 10); - // set width and height of plot - this.plotWidth = this.plotWidth || this.divjq.attr("data-plotWidth"); - if( !this.plotWidth ){ - this.plotWidth = this.width - JS9.ScaleLimits.WIDTHOFFSET; - } - this.plotHeight = this.plotHeight || this.divjq.attr("data-plotHeight"); - if( !this.plotHeight ){ - this.plotHeight = this.height - JS9.ScaleLimits.HEIGHTOFFSET; - } - // initial scaling - this.xscale = this.xscale || this.divjq.attr("data-xscale"); - if( !this.xscale ){ - this.xscale = JS9.ScaleLimits.XSCALE; - } - this.yscale = this.yscale || this.divjq.attr("data-yscale"); - if( !this.yscale ){ - this.yscale = JS9.ScaleLimits.YSCALE; - } - // plot colors - this.plotColor = this.plotColor || this.divjq.attr("data-plotColor"); - if( !this.plotColor ){ - this.plotColor = JS9.ScaleLimits.PLOTCOLOR; - } - // plot color - this.xlocolor = this.xlocolor || this.divjq.attr("data-xlocolor"); - if( !this.xlocolor ){ - this.xlocolor = JS9.ScaleLimits.XLOCOLOR; - } - // plot color - this.xhicolor = this.xhicolor || this.divjq.attr("data-xhicolor"); - if( !this.xhicolor ){ - this.xhicolor = JS9.ScaleLimits.XHICOLOR; - } - // set number of distribution points - this.ndist = this.divjq.attr("data-ndist"); - if( !this.ndist ){ - this.ndist = JS9.ScaleLimits.NDIST; - } - // clear out html - this.divjq.html(""); - this.lastTextWidth = 0; - // set up new html - this.scalelimsContainer = $("
    ") - .addClass(`${JS9.ScaleLimits.BASE}Container`) - .attr("id", `${this.id}Container`) - .attr("width", this.width) - .attr("height", this.height) - .appendTo(this.divjq); - // do we have an image? - im = this.display.image; - if( im && (opts.mode !== "clear") ){ - // convenience variables - imid = im.id; - dispid = im.display.id; - mopts = []; - mopts.push({name: "header", - value: JS9.ScaleLimits.headerHTML}); - mopts.push({name: "scales", - value: sprintf(JS9.ScaleLimits.scalesHTML, - dispid, imid, getScales())}); - mopts.push({name: "limits", - value: sprintf(JS9.ScaleLimits.limitsHTML, - dispid, imid)}); - mopts.push({name: "axes", - value: sprintf(JS9.ScaleLimits.axesHTML, - dispid, imid)}); - mopts.push({name: "plot", - value: sprintf(JS9.ScaleLimits.plotHTML, - imid, this.plotWidth, this.plotHeight)}); - mopts.push({name: "lo", - value: sprintf(JS9.ScaleLimits.loHTML, - JS9.floatToString(im.params.scalemin), - dispid, imid)}); - mopts.push({name: "hi", - value: sprintf(JS9.ScaleLimits.hiHTML, - JS9.floatToString(im.params.scalemax), - dispid, imid)}); - s = im.expandMacro(JS9.ScaleLimits.scalelimsHTML, mopts); - this.lastimage = im; - } else { - s = "

    Scale parameters will appear here.
    "; - } - this.scalelimsContainer.html(s); - // set up initial plot, if possible - if( im ){ - JS9.ScaleLimits.doplot.call(this, im); - } -}; - -// add this plugin into JS9 -JS9.RegisterPlugin(JS9.ScaleLimits.CLASS, JS9.ScaleLimits.NAME, - JS9.ScaleLimits.init, - {menu: "scale", - menuItem: "Scale Controls ...", - onplugindisplay: JS9.ScaleLimits.init, - onsetscale: JS9.ScaleLimits.init, - onimagedisplay: JS9.ScaleLimits.display, - onimageclose: JS9.ScaleLimits.close, - help: "help/scalecontrols.html", - winTitle: "Scale Controls", - winDims: [JS9.ScaleLimits.WIDTH, JS9.ScaleLimits.HEIGHT]}); diff --git a/web/static/js9_old/plugins/core/separate.css b/web/static/js9_old/plugins/core/separate.css deleted file mode 100644 index 4311d03f9004a24b6c5103841d26d948895df098..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/core/separate.css +++ /dev/null @@ -1,54 +0,0 @@ -div.JS9SeparateContainer { - padding: 2px; -} - -div.JS9SeparateImage { - margin: 5px; - background: #E9E9E9; - overflow: auto; -} - -div.JS9SeparateImageInactive { - padding: 10px; - border: 1px solid black; -} - -div.JS9SeparateImageActive { - padding: 9px; - border: 2px solid #00F000; -} - -div.JS9SeparateHeader { - border: 0px solid black; - background: #E9E9E9; - padding: 0px; - margin-left: 15px; - margin-top: 5px; - margin-right: 5px; - margin-bottom: 0px; -} - -input.separateButton1 { - position: relative; - width: 120px; - left: 10px; -} - -input.separateButton2 { - position: relative; - width: 90px; - left: 30px; -} - -select.separateLayoutSelect { - margin-right: 5px; -} - -#separateFile { - float: right; -} - -#separateNoFile { - margin-left: 15px; -} - diff --git a/web/static/js9_old/plugins/core/separate.js b/web/static/js9_old/plugins/core/separate.js deleted file mode 100644 index 26424dad938207f5c91a00d704d5fd44fe691c88..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/core/separate.js +++ /dev/null @@ -1,302 +0,0 @@ -/* - * image separate/gather plugin (July 26, 2018) - */ - -/*global $, JS9, sprintf */ - -"use strict"; - -// create our namespace, and specify some meta-information and params -JS9.Separate = {}; -JS9.Separate.CLASS = "JS9"; // class of plugins (1st part of div class) -JS9.Separate.NAME = "Separate"; // name of this plugin (2nd part of div class) -JS9.Separate.WIDTH = 512; // width of light window -JS9.Separate.HEIGHT = 336; // height of light window -JS9.Separate.BASE = JS9.Separate.CLASS + JS9.Separate.NAME; // CSS base class name - -JS9.Separate.topHTML='$separate

    $gather'; - -JS9.Separate.separateHTML='separate selected images or separate all images into different displays. The topmost (selected) image remains in place, and the presence or absence of its menubar, toolbar, and colorbar will be replicated in the new displays:

    ;

    '; - -JS9.Separate.gatherHTML='gather selected images or gather all images into this display:

    '; - -JS9.Separate.imageHTML="$active  $imfile"; - -JS9.Separate.activeHTML='select'; - -JS9.Separate.imfileHTML='%s'; - -JS9.Separate.nofileHTML='

    [Images will appear here as they are loaded]'; - -// change active state -JS9.Separate.xactive = function(id){ - const im = JS9.lookupImage(id); - const active = this.checked; - if( im ){ - im.tmp.separateMode = active; - } -}; - -// change active state -JS9.Separate.xlayout = function(id){ - let plugin; - const display = JS9.getDynamicDisplayOr(JS9.lookupDisplay(id)); - if( !display ){ return; } - plugin = display.pluginInstances.JS9Separate; - if( plugin && this.selectedIndex >= 0 ){ - plugin.separateLayout = this.options[this.selectedIndex].value; - } -}; - -// separate images -JS9.Separate.separate = function(id, which){ - let i, im, plugin, arr; - const opts = {}; - const display = JS9.getDynamicDisplayOr(JS9.lookupDisplay(id)); - if( !display ){ return; } - plugin = display.pluginInstances.JS9Separate; - if( plugin && plugin.separateLayout ){ - opts.layout = plugin.separateLayout; - } - switch(which){ - case "selected": - arr = []; - for(i=0; i") - .addClass(cls) - .addClass(dcls) - .attr("id", id) - .prop("imid", imid) - .html(s) - .appendTo(this.separateImageContainer); - divjq.on("mousedown touchstart", () => { - im.displayImage(); - JS9.Separate.activeImage(im); - }); - // one more div in the stack - this.separateDivs++; - // check the selected box, if necessary - divjq.find('.separateActiveCheck') - .prop('checked', im.tmp.separateMode === true); - //make it the current one - JS9.Separate.activeImage(im); -}; - -// remove an image from the list of available images -JS9.Separate.removeImage = function(im){ - let id; - if( im ){ - id = JS9.Separate.imid(im); - $(`#${id}`).remove(); - this.separateDivs--; - if( this.separateDivs === 0 ){ - this.separateImageContainer.html(JS9.Separate.nofileHTML); - } - delete im.tmp.separateMode; - return true; - } - return false; -}; - -// constructor: add HTML elements to the plugin -JS9.Separate.init = function(){ - let i, s, im, display, dispid; - const opts = []; - // on entry, these elements have already been defined: - // this.div: the DOM element representing the div for this plugin - // this.divjq: the jquery object representing the div for this plugin - // this.id: the id ofthe div (or the plugin name as a default) - // this.display: the display object associated with this plugin - // this.dispMode: display mode (for internal use) - // - // create container to hold image container and header - // clean main container - this.divjq.html(""); - // no images/divs loaded yet - this.separateDivs = 0; - // allow scrolling on the plugin - this.divjq.addClass("JS9PluginScrolling"); - // main container - this.separateContainer = $("

    ") - .addClass(`${JS9.Separate.BASE}Container`) - .attr("id", `${this.id}SeparateContainer`) - .css("overflow", "auto") - .appendTo(this.divjq); - dispid = this.display.id; - opts.push({name: "separate", value: sprintf(JS9.Separate.separateHTML, - dispid, dispid, dispid)}); - opts.push({name: "gather", value: sprintf(JS9.Separate.gatherHTML, - dispid, dispid)}); - s = JS9.Image.prototype.expandMacro.call(null, JS9.Separate.topHTML, - opts); - // header - this.separateHeader = $("
    ") - .addClass(`${JS9.Separate.BASE}Header`) - .attr("id", `${dispid}Header`) - .html(s) - .appendTo(this.separateContainer); - // container to hold images - this.separateImageContainer = $("
    ") - .addClass(`${JS9.Separate.BASE}ImageContainer`) - .attr("id", `${this.id}SeparateImageContainer`) - .html(JS9.Separate.nofileHTML) - .appendTo(this.separateContainer); - display = JS9.getDynamicDisplayOr(this.display); - // add currently loaded images - for(i=0; i { - this.oidx = ui.item.index(); - }, - stop: (event, ui) => { - const nidx = ui.item.index(); - // change JS9 image array to reflect the change - this.display.moveImageInStack(this.oidx, nidx); - // redisplay in case something changed - if( this.display.image ){ - this.display.image.displayImage(); - } - delete this.oidx; - } - }); -}; - -// callback when an image is loaded -JS9.Separate.imageload = function(im){ - const display = JS9.getDynamicDisplayOr(this.display); - if( im && im.display === display ){ - JS9.Separate.addImage.call(this, im); - } -}; - -// callback when image is displayed -JS9.Separate.imagedisplay = function(im){ - JS9.Separate.activeImage.call(this, im); -}; - -// callback when image is displayed -JS9.Separate.imageclose = function(im){ - JS9.Separate.removeImage.call(this, im); -}; - -// callback when image is displayed -JS9.Separate.reinit = function(im){ - if( im ){ - JS9.Separate.init.call(this); - } -}; - -// add this plugin into JS9 -JS9.RegisterPlugin(JS9.Separate.CLASS, JS9.Separate.NAME, JS9.Separate.init, - {menuItem: "Separate/Gather", - dynamicSelect: true, - onplugindisplay: JS9.Separate.init, - ondynamicselect: JS9.Separate.reinit, - ongatherdisplay: JS9.Separate.reinit, - onimageload: JS9.Separate.imageload, - onimagedisplay: JS9.Separate.imagedisplay, - onimageclose: JS9.Separate.imageclose, - help: "help/separate.html", - winTitle: "Separate/Gather Images", - winResize: true, - winDims: [JS9.Separate.WIDTH, JS9.Separate.HEIGHT]}); - diff --git a/web/static/js9_old/plugins/core/statusbar.css b/web/static/js9_old/plugins/core/statusbar.css deleted file mode 100644 index 3c811492a8bc4682e701d5a3d9a860b285a0a05e..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/core/statusbar.css +++ /dev/null @@ -1,67 +0,0 @@ -/* overflow scrolling technique: https://stackoverflow.com/questions/9672176/prevent-floated-divs-from-wrapping-to-new-line */ -/* this doesn't work on Linux Electron: it puts up arrows that get in the way */ -.JS9Statusbar { - /* overflow-y: scroll; */ -} - -.JS9StatusbarContainer { - background-color: #E9E9E9; - padding-left: 4px; - height: 100%; - font: normal 12px Arial; - overflow: auto; -} - -.JS9StatusbarItem { - border-radius: 4px; - display:inline-block; - vertical-align:middle; - text-align:center; - white-space:nowrap; - background-color: #E9E9E9; - color: black; - margin-top: 4px; - margin-bottom: 4px; - padding: 4px; - float: left; -} - -.JS9StatusbarItem[name*="JS9Colorbar"] { - margin-top: 0px; - padding-right: 0px; - padding-left: 0px; -} - -img.JS9StatusbarImage { - white-space:nowrap; -} - -img.JS9StatusbarImageItem[name*="zoom_"]{ - height: 12px; - width: 12px; -} - -img.JS9StatusbarImageOption[name*="color_"]{ - height: 12px; - width: 100px; -} - -.JS9StatusbarItemNoHighlight { - border: 1px solid #E9E9E9; -} - -.JS9StatusbarItemHighlight { - border: 1px solid #B0B0B0; -} - -.JS9StatusbarItemHighlight2 { - border: 1px solid #777777 -} - -.JS9StatusbarPluginItem .JS9ColorbarCanvas { - border: 0px solid black; -} - -.JS9StatusbarPluginItem { - vertical-align: middle; -} diff --git a/web/static/js9_old/plugins/core/statusbar.js b/web/static/js9_old/plugins/core/statusbar.js deleted file mode 100644 index 05b61e52ba0a0ab1b9c721b3ce54f2562a32d624..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/core/statusbar.js +++ /dev/null @@ -1,252 +0,0 @@ -/* - * status plugin (February 20, 2020) - */ - -/*global $, JS9 */ - -"use strict"; - -// create our namespace, and specify some meta-information and params -JS9.Statusbar = {}; -JS9.Statusbar.CLASS = "JS9"; // class of plugins (1st part of div class) -JS9.Statusbar.NAME = "Statusbar"; // name of this plugin (2nd part of div class) -JS9.Statusbar.WIDTH = 512; // width of light window -JS9.Statusbar.HEIGHT = 32; // height of light window -JS9.Statusbar.COLORWIDTH = 120; // width of colorbar, if present -JS9.Statusbar.COLORHEIGHT = 14; // height of colorbar, if present -JS9.Statusbar.BASE = JS9.Statusbar.CLASS + JS9.Statusbar.NAME; - -// mouse over: highlight a bit -JS9.Statusbar.mover = function(target){ - $(target).removeClass("JS9StatusbarItemNoHighlight JS9StatusbarItemHighlight2"); - $(target).addClass("JS9StatusbarItemHighlight"); -}; - -// mouse out: no highlight -JS9.Statusbar.mout = function(target){ - $(target).removeClass("JS9StatusbarItemHighlight JS9StatusbarItemHighlight2"); - $(target).addClass("JS9StatusbarItemNoHighlight"); -}; - -// mouse down: hightlight fully -JS9.Statusbar.mdown = function(target){ - // unhighlight - $(target).removeClass("JS9StatusbarItemNoHighlight JS9StatusbarItemHighlight"); - $(target).addClass("JS9StatusbarItemHighlight2"); -}; - -// mouse up: xeq action, hightlight a bit -JS9.Statusbar.mup = function(target, id){ - let s, arr; - $(target).removeClass("JS9StatusbarItemNoHighlight JS9StatusbarItemHighlight2"); - $(target).addClass("JS9StatusbarItemHighlight"); - // look at the html for this element - s = $(target).attr("name"); - if( s ){ - // is there a hint about what sort of menu status it contains? - arr = s.match(/file|image|edit|view|zoom|rot|flip|scale|color|regions|wcs|analysis|mag/i); - } - // bring up a control plugin, if possible - if( arr && arr[0] ){ - switch(arr[0]){ - case "file": - case "image": - JS9.DisplayPlugin("FITSBinning", {display: id}); - break; - case "edit": - break; - case "view": - break; - case "flip": - case "rot": - case "mag": - case "zoom": - JS9.DisplayPlugin("JS9PanZoom", {display: id}); - break; - case "scale": - JS9.DisplayPlugin("JS9Scale", {display: id}); - break; - case "color": - JS9.DisplayPlugin("JS9Color", {display: id}); - break; - case "regions": - break; - case "wcs": - break; - case "analysis": - break; - } - } -} - -// redraw status on display -JS9.Statusbar.display = function(im, opts){ - let i, s, t, oarr, arr, elements, index, pinst, statusbar; - let html = ""; - let delim = /;/; - // opts is optional - opts = opts || {}; - if( im && JS9.globalOpts.statusBar ){ - statusbar = JS9.globalOpts.statusBar; - // remove colorbar if colorbar plugin is instantiated - pinst = im.display.pluginInstances.JS9Colorbar; - if( pinst && pinst.isActive() && !this.mycolorbar ){ - statusbar = statusbar.replace(/\$colorbar;? */, ""); - } - // escape brackets and parens before macro expansion, then unescape - s = statusbar - .replace(/\(/g, " __OP__ ") - .replace(/\)/g, " __CP__ ") - .replace(/\[/g, " __OB__ ") - .replace(/\]/g, " __CB__ "); - s = im.expandMacro(s) - .replace(/ __OP__ /g, "(") - .replace(/ __CP__ /g, ")") - .replace(/ __OB__ /g, "[") - .replace(/ __CB__ /g, "]"); - if( this.statusBar !== statusbar || opts.reinit ){ - // original statusbar items - oarr = statusbar.split(delim); - // current values of items in the status bar - arr = s.split(delim); - for(i=0; i${arr[i]}
    ` - .replace(/\$img\(([^()]+)\)/g, "") - .replace(/\$colorbar/g, `
    `) - .replace(/__dummy__/, oarr[i].replace(/\s+/, "_")); - html += t; - } - // set statusbar - this.statusContainer.html(html); - // colorbar plugin: run AddDivs, remove colorbar from resize list - if( statusbar.match(/\$colorbar/) ){ - JS9.AddDivs({display: im}); - this.mycolorbar = this.display.pluginInstances.JS9Colorbar; - index = JS9.globalOpts.resizeDivs.indexOf("JS9Colorbar"); - if( index >= 0 ){ - JS9.globalOpts.resizeDivs.splice(index, 1); - } - } - // save the format to detect future changes - this.statusBar = statusbar; - } else { - // elements associated with items in statusbar - elements = this.divjq.find(`.JS9StatusbarItem`); - arr = s.split(delim); - // for each element ... - for(i=0; i") - .addClass(`${JS9.Statusbar.BASE}Container`) - .attr("id", `${this.id}Container`) - .attr("width", this.width) - .attr("height", this.height) - .appendTo(this.divjq); - // display current status, if necessary - if( this.display.image ){ - JS9.Statusbar.display.call(this, this.display.image); - } -}; - -// callback when image is (re-)displayed -JS9.Statusbar.imagedisplay = function(im){ - if( im ){ - JS9.Statusbar.display.call(this, im); - } -}; - -// callback when image is cleared or closed -// eslint-disable-next-line no-unused-vars -JS9.Statusbar.imageclear = function(im){ - JS9.Statusbar.display.call(this, null); -}; - -// dynamic change -JS9.Statusbar.dynamic = function(im){ - let status; - if( im ){ - status = im.display.pluginInstances.JS9Statusbar; - if( status && status.isDynamic ){ - JS9.Statusbar.imagedisplay.call(this, im); - } - } -}; - -// add this plugin into JS9 -JS9.RegisterPlugin(JS9.Statusbar.CLASS, JS9.Statusbar.NAME, JS9.Statusbar.init, - {menuItem: "Statusbar", - dynamicSelect: true, - ondynamicselect: JS9.Statusbar.dynamic, - onimagedisplay: JS9.Statusbar.imagedisplay, - onimageclear: JS9.Statusbar.imageclear, - onimageclose: JS9.Statusbar.imageclear, - onsetwcssys: JS9.Statusbar.imagedisplay, - onsetwcsunits: JS9.Statusbar.imagedisplay, - help: "help/statusbar.html", - winTitle: "Statusbar", - winDims: [JS9.Statusbar.WIDTH, JS9.Statusbar.HEIGHT]}); diff --git a/web/static/js9_old/plugins/core/sync.js b/web/static/js9_old/plugins/core/sync.js deleted file mode 100644 index 339116e2bb3899f3cbd21cce5873022eb2451fee..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/core/sync.js +++ /dev/null @@ -1,625 +0,0 @@ -/* - * image sync plugin (September 2, 2018) - * whenever an operation is performed on this image, sync the target images - */ - -/*global JS9, $ */ - -"use strict"; - -JS9.Sync = {}; -JS9.Sync.CLASS = "JS9"; // class of plugins (1st part of div class) -JS9.Sync.NAME = "Sync"; // name of this plugin (2nd part of div class) - -// process ops input to [un]sync -// called in image context -JS9.Sync.getOps = function(ops){ - let i, j, op; - const xops = []; - // default from above ... - ops = ops || JS9.globalOpts.syncOps; - if( !$.isArray(ops) ){ - try{ ops = JSON.parse(ops); } - catch(e){ ops = [ops]; } - } - for(i=0, j=0; i=0; i--){ - // remove if it was specified for removal - if( $.inArray(tims[i], xims) >= 0 ){ - tims.splice(i, 1); - } - } - // remove empty target image array - if( !tims.length ){ - delete this.syncs[op]; - - } - } - } - // remove empty sink object from image - if( !Object.keys(this.syncs).length ){ - delete this.syncs; - } - // reciprocal sync'ing between all images? - if( opts.reciprocate ){ - JS9.Sync.reciprocating = true; - opts.reciprocate = false; - for(i=0, xim=this; i { - // check for a target region with the same syncid as the current region - if( !r1.data || !r1.data.syncid ){ return false; } - if( !r2.data || !r2.data.syncid ){ return false; } - return r1.data.syncid === r2.data.syncid; - }; - const calcFlip = (flip) => { - let i, arr; - let nx = 0; - let ny = 0; - let nflip = ""; - arr = flip.split(""); - for(i=0; i  %s'; - -JS9.SyncUI.syncwcsHTML='  %s'; - -JS9.SyncUI.footerHTML='
    $cancel  $sync    $once    $unsync
    '; - -JS9.SyncUI.cancelHTML=''; - -JS9.SyncUI.syncHTML=''; - -JS9.SyncUI.onceHTML=''; - -JS9.SyncUI.unsyncHTML=''; - - -JS9.SyncUI.getImsOpsOpts = function(el){ - const container = el.closest(".JS9SyncUIContainer"); - const ops = []; - const ims = []; - const opts = {}; - if( container.length ){ - // gather all selected images - container.find(".JS9SyncUIImCheck").each((index, element) => { - let name = $(element).prop("name"); - let checked = $(element).prop("checked"); - if( checked ){ - ims.push(name); - } - }); - // gather all selected ops - container.find(".JS9SyncUIOpCheck").each((index, element) => { - let name = $(element).prop("name"); - let checked = $(element).prop("checked"); - if( checked ){ - ops.push(name); - } - }); - // get opts - container.find(".JS9SyncUIOptsCheck").each((index, element) => { - let name = $(element).prop("name"); - let checked = $(element).prop("checked"); - opts[name] = checked; - }); - } - return {ims, ops, opts}; -}; - -// cancel -// eslint-disable-next-line no-unused-vars -JS9.SyncUI.xcancel = function(did, target){ - let plugin; - const display = JS9.getDynamicDisplayOr(JS9.lookupDisplay(did)); - if( display ){ - plugin = display.pluginInstances.JS9SyncUI; - if( plugin && plugin.winHandle ){ - plugin.winHandle.close(); - } - } -}; - -// sync -JS9.SyncUI.xsync = function(did, target){ - let im; - const display = JS9.getDynamicDisplayOr(JS9.lookupDisplay(did)); - if( display.image ){ - im = display.image; - // get ims and opts - const {ims, ops, opts} = JS9.SyncUI.getImsOpsOpts($(target)); - // sync images, if necessary - if( ims.length && ops.length ){ - im.syncImages(ops, ims, opts); - } - JS9.SyncUI.setCheckboxes(im); - } -}; - -// sync once -JS9.SyncUI.xonce = function(did, target){ - let im; - const display = JS9.getDynamicDisplayOr(JS9.lookupDisplay(did)); - if( display.image ){ - im = display.image; - // get ims and opts - const {ims, ops} = JS9.SyncUI.getImsOpsOpts($(target)); - // copy params, if necessary - if( ims.length && ops.length ){ - im.copyParams(ops, ims); - JS9.SyncUI.setCheckboxes(im); - } - } -}; - -// unsync -JS9.SyncUI.xunsync = function(did, target){ - let im; - const display = JS9.getDynamicDisplayOr(JS9.lookupDisplay(did)); - if( display.image ){ - im = display.image; - // get ims and opts - const {ims, ops, opts} = JS9.SyncUI.getImsOpsOpts($(target)); - // unsync images, if necessary - if( ims.length && ops.length ){ - im.unsyncImages(ops, ims, opts); - } - JS9.SyncUI.setCheckboxes(im); - } -}; - -JS9.SyncUI.xrecip = function(did, target){ - let pinst; - const display = JS9.getDynamicDisplayOr(JS9.lookupDisplay(did)); - if( display ){ - pinst = display.pluginInstances.JS9SyncUI; - pinst.syncReciprocate = $(target).is(':checked'); - } -}; - -JS9.SyncUI.xsyncwcs = function(did, target){ - let pinst; - const display = JS9.getDynamicDisplayOr(JS9.lookupDisplay(did)); - if( display ){ - pinst = display.pluginInstances.JS9SyncUI; - pinst.syncWCS = $(target).is(':checked'); - } -}; - -// get a SyncImage id based on the file image id -JS9.SyncUI.imid = function(im){ - const id = `${im.display.id}_${im.id}`; - return `${id.replace(/[^A-Za-z0-9_]/g, "_")}SyncImage`; -}; - -// set checkbox for sync'ed options -JS9.SyncUI.setCheckboxes = function(im){ - let i, j, id, op, syncops, pinst; - // sanity check - if( !im ){ - return - } - // get current instance of this plugin - pinst = im.display.pluginInstances.JS9SyncUI; - // first turn all checkboxes off - pinst.syncContainer.find(".JS9SyncUIOpCheck").prop("checked", false); - pinst.syncContainer.find(".JS9SyncUIImCheck").prop("checked", false); - pinst.syncContainer.find(".JS9SyncUIOptsCheck").prop("checked", false); - // then turn on currently syn'ed options - syncops = JS9.globalOpts.syncOps; - // for each sync'ed op in this image ... - if( im.syncs ){ - for(i=0; i${s}`; -}; - -// add an image to the list of available images -JS9.SyncUI.addImage = function(im){ - let s, id, imid; - const opts = []; - const cls = `${JS9.SyncUI.BASE}ImageRow`; - if( !im ){ - return; - } - // convenience variables - imid = im.id; - // unique id - id = JS9.SyncUI.imid(im); - // value to pass to the macro expander - opts.push({name: "imid", value: im.id}); - opts.push({name: "imactive", value: sprintf(JS9.SyncUI.imactiveHTML, imid)}); - opts.push({name: "imfile", value: sprintf(JS9.SyncUI.imfileHTML, imid)}); - // create the html for this image - s = im.expandMacro(JS9.SyncUI.imageHTML, opts); - // one more div in the stack - this.syncImageDivs++; - // return image html to add to the image container - return `
    ${s}
    `; -}; - -// remove an image from the list of available images -JS9.SyncUI.removeImage = function(im){ - let id; - if( im ){ - id = JS9.SyncUI.imid(im); - $(`#${id}`).remove(); - this.syncImageDivs--; - if( !this.syncImageDivs ){ - this.syncImageContainer.html(""); - } - return true; - } - return false; -}; - -// constructor: add HTML elements to the plugin -JS9.SyncUI.init = function(){ - let i, j, s, im, op, dispid, imhead, ophead, opts, nrow, idx, syncops, html; - // on entry, these elements have already been defined: - // this.div: the DOM element representing the div for this plugin - // this.divjq: the jquery object representing the div for this plugin - // this.id: the id ofthe div (or the plugin name as a default) - // this.display: the display object associated with this plugin - // this.dispMode: display mode (for internal use) - // - // sanity check since we are always active - if( !this.divjq || !this.divjq.is(":visible") ){ - return; - } - // clean main container - this.divjq.html(""); - // no images/divs loaded yet - this.syncOpDivs = 0; - this.syncImageDivs = 0; - // allow scrolling on the plugin - this.divjq.addClass("JS9PluginScrolling"); - // init reciprocate - if( JS9.isNull(this.syncReciprocate) ){ - this.syncReciprocate = JS9.globalOpts.syncReciprocate; - } - // init syncwcs - if( JS9.isNull(this.syncWCS) ){ - this.syncWCS = JS9.globalOpts.syncWCS; - } - // convenience variables - dispid = this.display.id; - if( this.display.image ){ - this.lastim = this.display.image; - imhead = sprintf(JS9.SyncUI.HEADER, - `Images that can be synced with ${this.lastim.id}`); - } else { - this.lastim = null; - imhead = sprintf(JS9.SyncUI.HEADER, - `Images that can be synced`); - } - // main container - this.syncContainer = $("
    ") - .addClass(`${JS9.SyncUI.BASE}Container`) - .attr("id", `${this.id}SyncContainer`) - .css("overflow", "auto") - .appendTo(this.divjq); - s = JS9.Image.prototype.expandMacro.call(null, JS9.SyncUI.headerHTML); - // header - this.syncHeader = $("
    ") - .addClass(`${JS9.SyncUI.BASE}Header`) - .attr("id", `${dispid}Header`) - .html(s) - .appendTo(this.syncContainer); - // container to hold images - this.syncImageContainer = $("
    ") - .addClass(`${JS9.SyncUI.BASE}ImageContainer`) - .attr("id", `${this.id}SyncImageContainer`) - .html(imhead) - .appendTo(this.syncContainer); - // add images - html = ""; - for(i=0; i") - .addClass(`${JS9.SyncUI.BASE}OpContainer`) - .attr("id", `${this.id}SyncOpContainer`) - .html(sprintf(JS9.SyncUI.HEADER, "Operations that can be synced")) - .appendTo(this.syncContainer); - syncops = JS9.globalOpts.syncOps; - nrow = Math.floor((syncops.length + JS9.SyncUI.NCOL - 1) / JS9.SyncUI.NCOL); - for(j=0; j`; - for(i=0; i") - .addClass(`${JS9.SyncUI.BASE}OptsContainer`) - .attr("id", `${this.id}SyncOptsContainer`) - .html(ophead) - .appendTo(this.syncContainer); - opts = []; - opts.push({name: "reciprocate", value: sprintf(JS9.SyncUI.reciprocalHTML, JS9.SyncUI.COLWIDTH * 0, "reciprocate", dispid, "reciprocal sync")}); - opts.push({name: "syncwcs", value: sprintf(JS9.SyncUI.syncwcsHTML, JS9.SyncUI.COLWIDTH * 1, "syncwcs", dispid, "sync using wcs")}); - s = JS9.Image.prototype.expandMacro.call(null, JS9.SyncUI.optsHTML, opts); - // footer - this.syncOpts = $("
    ") - .attr("id", `${dispid}Opts`) - .html(s) - .appendTo(this.syncOptsContainer); - // footer containing run buttons - opts = []; - opts.push({name: "cancel", value: sprintf(JS9.SyncUI.cancelHTML, dispid, - this.winHandle ? "" : 'style="display:none;"')}); - opts.push({name: "sync", value: sprintf(JS9.SyncUI.syncHTML, dispid)}); - opts.push({name: "once", value: sprintf(JS9.SyncUI.onceHTML, dispid)}); - opts.push({name: "unsync", value: sprintf(JS9.SyncUI.unsyncHTML, dispid)}); - s = JS9.Image.prototype.expandMacro.call(null, JS9.SyncUI.footerHTML, opts); - // footer - this.syncFooter = $("
    ") - .addClass(`${JS9.SyncUI.BASE}Footer`) - .attr("id", `${dispid}Footer`) - .html(s) - .appendTo(this.syncContainer); - // initialize sync values for this image - if( this.display.image ){ - JS9.SyncUI.setCheckboxes(this.display.image); - } -}; - -// callback when plugin is redisplayed -// eslint-disable-next-line no-unused-vars -JS9.SyncUI.reinit = function(im){ - JS9.SyncUI.init.call(this); -}; - -// callback when an image is loaded -JS9.SyncUI.imageload = function(im){ - if( !im ){ return; } - JS9.SyncUI.init.call(this); -}; - -// callback when an image is displayed -JS9.SyncUI.imagedisplay = function(im){ - if( im && im !== this.lastim ){ - JS9.SyncUI.init.call(this); - } -}; - -// clean up an image when its closed -JS9.SyncUI.imageclose = function(im){ - let i; - if( !im ){ return; } - // remove this image from all other image sync lists - for(i=0; i this.width ){ - x = offset.left - w - 20; - } - this.tooltip.css({left: x, top: y, display: "inline-block"}); - } else { - this.tooltip.html("").css({left: -9999, display: "none"}); - } - return; -}; - -// add a tool to the toolbar -JS9.Toolbar.addTool = function(tool){ - let div, btn, img; - // special processing: no args means return current list of tools - if( !tool ){ - return JS9.Toolbar.tools; - } - // special processing: add "break" between section - if( tool === "$break" ){ - $("
    ").appendTo(this.activeToolbar); - return; - } - // sanity check on a real tool - if( !tool.name || !tool.cmd ){ - JS9.error(`invalid input to JS9.toolbar: ${JSON.stringify(tool)}`); - } - // enclosing div - div = $("
    ") - .addClass(`${JS9.Toolbar.BASE}ButtonDiv`) - .appendTo(this.activeToolbar); - // create the button - if( tool.image ){ - // relative path: add install dir prefix - img = tool.image; - if( JS9.inline && JS9.inline[img] ){ - // inline version is available - img = JS9.inline[img]; - } else if( img.charAt(0) !== "/" ){ - // external version - img = JS9.InstallDir(img); - } - btn = $("") - .addClass(`${JS9.Toolbar.BASE}ImageButton`) - .attr("type", "image") - .attr("src", img) - .attr("width", JS9.Toolbar.IMAGEWIDTH) - .attr("height", JS9.Toolbar.IMAGEHEIGHT) - .attr("alt", tool.name) - .appendTo(div); - } else { - btn = $("") - .addClass(`${JS9.Toolbar.BASE}ButtonButton`) - .attr("type", "button") - .attr("value", tool.name) - .appendTo(div); - } - // set up the callback to the JS9 public access routine - btn.on("click", () => { - let args; - const display = this.display; - // special processing for commands - switch(tool.cmd){ - default: - if( typeof JS9.publics[tool.cmd] === "function" ){ - // clone the array and any objects it contains - args = JSON.parse(JSON.stringify(tool.args||[])); - args.push({display: display}); - JS9.publics[tool.cmd](...args); - } else { - JS9.error(`unknown JS9 func for toolbar: ${tool.cmd}`); - } - break; - } - }); - // tool tip is optional - if( JS9.globalOpts.toolbarTooltips ){ - btn.on("mouseover", (e) => { - JS9.Toolbar.tooltip.call(this, tool, tool.tip||tool.name, e); - }); - btn.on("mouseout", (e) => { - JS9.Toolbar.tooltip.call(this, tool, null, e); - }); - } - // return something possible useful - tool.btn = btn; - return tool; -}; - -// constructor: add HTML elements to the plugin -JS9.Toolbar.init = function(width, height){ - let i, j, tool, name; - // on entry, these elements have already been defined: - // this.div: the DOM element representing the div for this plugin - // this.divjq: the jquery object representing the div for this plugin - // this.id: the id of the div (or the plugin name as a default) - // this.display: the display object associated with this plugin - // this.dispMode: display mode (for internal use) - // - this.width = this.divjq.attr("data-width"); - if( !this.width ){ - this.width = width || JS9.Toolbar.WIDTH; - } - this.divjq.css("width", this.width); - this.width = parseInt(this.divjq.css("width"), 10); - this.height = this.divjq.attr("data-height"); - if( !this.height ){ - this.height = height || JS9.Toolbar.HEIGHT; - } - this.divjq.css("height", this.height); - this.height = parseInt(this.divjq.css("height"), 10); - // clean plugin container - this.divjq.html(""); - // toolbar container - this.toolbarContainer = $("
    ") - .addClass(`${JS9.Toolbar.BASE}Container`) - .attr("id", `${this.id}Container`) - .appendTo(this.divjq); - // toolbar - this.activeToolbar = $("
    ") - .addClass(`${JS9.Toolbar.BASE}Div`) - .attr("id", `${this.id}Toolbar`) - .css("width", this.width) - .css("height", this.height) - .css("min-height", JS9.Toolbar.TOOLBARHEIGHT) - .appendTo(this.toolbarContainer); - // add a tooltip - this.tooltip = $("
    ") - .attr("id", `tooltip_${this.id}`) - .addClass("JS9ToolbarTooltip") - .appendTo(this.divjq); - // add tools from globalOpts to the list - for(j=0; j { - let i, display, pinst; - for(i=0; i%s'; - -JS9.PanZoom.zoomHTML = ''; - -JS9.PanZoom.flipHTML = ''; - -JS9.PanZoom.rot90HTML = ''; - -JS9.PanZoom.rotateHTML = ''; - -JS9.PanZoom.pantoHTML = ''; - -JS9.PanZoom.pos1HTML = ''; - -JS9.PanZoom.pos2HTML = ''; - -JS9.PanZoom.sysHTML = ''; - -JS9.PanZoom.unitsHTML = ''; - -// change pan via menu -JS9.PanZoom.xsetpan = function(did, id, target){ - const im = JS9.lookupImage(id, did); - if( im ){ - switch(target.value){ - case "center": - im.setPan(); - break; - default: - break; - } - } -}; - -// change zoom via menu -JS9.PanZoom.xsetzoom = function(did, id, target){ - let arr, arr2, zval, zoom; - const im = JS9.lookupImage(id, did); - if( im ){ - switch(target.value){ - case "in": - case "out": - case "to fit": - zoom = im.parseZoom(target.value); - if( JS9.isNumber(zoom) ){ - im.setZoom(zoom); - } - break; - default: - // format: "zoom" zoom - arr = target.value.split(/\s+/); - if( arr.length === 2 ){ - // format zoom or 1/zoom - arr2 = arr[1].split("/"); - if( arr2.length === 1 ){ - zval = parseFloat(arr2[0]); - } else { - zval = 1 / parseFloat(arr2[1]); - } - im.setZoom(zval); - } - break; - } - } -}; - -// change flip via menu -JS9.PanZoom.xsetflip = function(did, id, target){ - const im = JS9.lookupImage(id, did); - if( im ){ - switch(target.value){ - case "x axis": - im.setFlip("x"); - break; - case "y axis": - im.setFlip("y"); - break; - case "reset": - im.setFlip("reset"); - break; - default: - break; - } - } -}; - -// change rotation by 90 degrees via menu -JS9.PanZoom.xsetrot90 = function(did, id, target){ - const im = JS9.lookupImage(id, did); - if( im ){ - switch(target.value){ - case "90 left": - im.setRot90(90); - break; - case "90 right": - im.setRot90(-90); - break; - case "reset rotate": - im.setRot90("reset"); - im.setRotate("reset"); - break; - case "align: north is up": - im.setRot90("reset"); - im.setRotate("northisup"); - break; - case "reset flip/rot90/rotate": - im.setFlip("reset"); - im.setRot90("reset"); - im.setRotate("reset"); - break; - default: - break; - } - } - return false; -}; - -// change rotation by degrees via text box -JS9.PanZoom.xsetrot = function(did, id, target, evt){ - let rot, pinst; - const im = JS9.lookupImage(id, did); - if( im ){ - if( evt.keyCode !== 13 ){ return; } - rot = $(target).val().trim(); - if( rot ){ - if( rot === "reset" ){ - im.setRotate("reset"); - im.setRot90("reset"); - return; - } - pinst = im.display.pluginInstances.JS9PanZoom; - // do this before setting rotation - if( pinst ){ - pinst.rot = rot; - } - im.setRotate(rot); - // do this after setting rotation - if( pinst ){ - pinst.divjq.find(`input[name="rotate"]`).focus().caretToEnd(); - } - } - } -}; - -// pan to the position specified in the pos1,pos2 input elements -JS9.PanZoom.xpanto = function(did, id, target){ - let owcssys, arr, p1, p2, s1, s2, wcssys, pel, phys; - const im = JS9.lookupImage(id, did); - if( im ){ - pel = $(target).parent(); - wcssys = pel.find("[name='wcssys']").val(); - s1 = pel.find("[name='pos1']").val(); - s2 = pel.find("[name='pos2']").val(); - if( s1 && s2 && wcssys ){ - owcssys = im.getWCSSys(); - im.setWCSSys(wcssys); - p1 = JS9.saostrtod(s1); - if( JS9.isHMS(wcssys) ){ - p1 *= 15.0; - } - p2 = JS9.saostrtod(s2); - switch(wcssys){ - case "image": - break; - case "physical": - phys = im.logicalToImagePos({x: p1, y: p2}); - p1 = phys.x; - p2 = phys.y; - break; - default: - if( im.validWCS() ){ - arr = JS9.wcs2pix(im.raw.wcs, p1, p2).trim().split(/\s+/); - p1 = parseFloat(arr[0]); - p2 = parseFloat(arr[1]); - } - } - im.setPan(p1, p2); - im.setWCSSys(owcssys); - } - } -}; - -// change the wcs system -JS9.PanZoom.xsetwcssys = function(did, id, target){ - let owcssys, owcsunits, pel, pos1, pos2; - const nwcssys = target.value; - const im = JS9.lookupImage(id, did); - if( im ){ - owcssys = im.getWCSSys(); - owcsunits = im.getWCSUnits(); - im.setWCSSys(nwcssys); - im.tmp.wcssysPanZoom = nwcssys; - pos1 = JS9.PanZoom.getPos(im, "x"); - pos2 = JS9.PanZoom.getPos(im, "y"); - pel = $(target).parent(); - pel.find("[name='pos1']").val(pos1); - pel.find("[name='pos2']").val(pos2); - if( im.getWCSUnits() !== (im.tmp.wcsunitsPanZoom||owcsunits) ){ - JS9.PanZoom.xsetwcsunits(did, id, {value: im.getWCSUnits()}); - } - im.setWCSSys(owcssys); - im.setWCSUnits(owcsunits); - } -} - -// change the wcs units -JS9.PanZoom.xsetwcsunits = function(did, id, target){ - let owcssys, owcsunits, pel, pos1, pos2; - const nwcsunits = target.value; - const im = JS9.lookupImage(id, did); - if( im ){ - owcsunits = im.getWCSUnits(); - owcssys = im.getWCSSys(); - im.setWCSUnits(nwcsunits); - im.tmp.wcsunitsPanZoom = nwcsunits; - pos1 = JS9.PanZoom.getPos(im, "x"); - pos2 = JS9.PanZoom.getPos(im, "y"); - pel = $(target).parent(); - pel.find("[name='pos1']").val(pos1); - pel.find("[name='pos2']").val(pos2); - if( im.getWCSSys() !== (im.tmp.wcssysPanZoom||owcssys) ){ - JS9.PanZoom.xsetwcssys(did, id, {value: im.getWCSSys()}); - } - im.setWCSSys(owcssys); - im.setWCSUnits(owcsunits); - } -} - -// get position string based on wcssys -JS9.PanZoom.getPos = function(im, which){ - let s, res, phys, ipos, owcssys, owcsunits, wcssys, wcsunits; - if( im ){ - ipos = im.getPan(); - owcssys = im.getWCSSys(); - owcsunits = im.getWCSUnits(); - wcssys = im.tmp.wcssysPanZoom || owcssys; - wcsunits = im.tmp.wcsunitsPanZoom || owcsunits; - if( owcssys !== wcssys ){ - im.setWCSSys(wcssys); - } - if( owcsunits !== wcsunits ){ - im.setWCSUnits(wcsunits); - } - switch(wcssys){ - case "image": - res = String(ipos[which]); - break; - case "physical": - phys = im.imageToLogicalPos(ipos); - res = String(phys[which]); - break; - default: - if( im.validWCS() ){ - s = JS9.pix2wcs(im.raw.wcs, ipos.x, ipos.y) - .trim().split(/\s+/); - res = which === "x" ? s[0] : s[1]; - } else { - res = String(ipos[which]); - } - break; - } - if( owcssys !== wcssys ){ - im.setWCSSys(owcssys); - } - if( owcsunits !== wcsunits ){ - im.setWCSUnits(owcsunits); - } - } - return res; -}; - -// re-init (avoiding recursion) -JS9.PanZoom.reinit = function(){ - if( !this.inProcess ){ - this.inProcess = true; - JS9.PanZoom.init.call(this); - this.inProcess = false; - } -}; - -// re-init when a different image is displayed -JS9.PanZoom.display = function(){ - if( this.lastimage !== this.display.image ){ - this.inProcess = true; - JS9.PanZoom.init.call(this); - this.inProcess = false; - } -}; - -// clear when an image closes -JS9.PanZoom.close = function(){ - // ensure plugin display is reset - JS9.PanZoom.init.call(this, {mode: "clear"}); -}; - -// constructor: add HTML elements to the plugin -JS9.PanZoom.init = function(opts){ - let s, t, im, mopts, imid, dispid; - const getPanOptions = () => { - let res = ""; - res += ``; - return res; - }; - const getZoomOptions = () => { - let i, zoom, name; - let res = ""; - res += ``; - res += ``; - res += ``; - res += ``; - for(i=JS9.imageOpts.zooms; i>0; i--){ - zoom = Math.pow(2,i); - name = `zoom 1/${zoom}`; - res += ``; - } - for(i=0; i<=JS9.imageOpts.zooms; i++){ - zoom = Math.pow(2,i); - name = `zoom ${zoom}`; - res += ``; - } - return res; - }; - const getFlipOptions = () => { - let res = ""; - res += ``; - res += ``; - res += ``; - return res; - }; - const getRot90Options = () => { - let res = ""; - res += ``; - res += ``; - res += ``; - res += ``; - res += ``; - res += ``; - return res; - }; - const getRotOptions = (im) => { - let res = 0; - if( im ){ - if( JS9.globalOpts.rotateRelative && - this.rot && this.rot !== "reset" ){ - res = this.rot; - } else { - res = im.getRotate() || "0"; - } - } - return res; - }; - const getSysOptions = (im) => { - let i, sys, wcssys; - let res = ""; - if( im ){ - wcssys = im.tmp.wcssysPanZoom || im.getWCSSys(); - if( im.validWCS() ){ - sys = JS9.wcssyss; - } else { - sys = ["image", "physical"]; - } - for(i=0; i${sys[i]}`; - } else { - res += ``; - } - } - } - return res; - }; - const getUnitsOptions = (im) => { - let i, units, wcsunits; - let res = ""; - if( im ){ - wcsunits = im.tmp.wcsunitsPanZoom || im.getWCSUnits(); - if( im.validWCS() ){ - units = ["degrees", "sexagesimal", "pixels"]; - } else { - units = ["pixels"]; - } - for(i=0; i${units[i]}`; - } else { - res += ``; - } - } - } - return res; - }; - const getPos = (im, which) => { - return JS9.PanZoom.getPos(im, which); - }; - // on entry, these elements have already been defined: - // this.div: the DOM element representing the div for this plugin - // this.divjq: the jquery object representing the div for this plugin - // this.id: the id ofthe div (or the plugin name as a default) - // this.display: the display object associated with this plugin - // this.dispMode: display mode (for internal use) - // - // opts is optional - opts = opts || {}; - // set width and height of plugin itself - this.width = this.divjq.attr("data-width"); - if( !this.width ){ - this.width = JS9.PanZoom.WIDTH; - } - this.divjq.css("width", this.width); - this.width = parseInt(this.divjq.css("width"), 10); - this.height = this.divjq.attr("data-height"); - if( !this.height ){ - this.height = JS9.PanZoom.HEIGHT; - } - this.divjq.css("height", this.height); - this.height = parseInt(this.divjq.css("height"), 10); - // clear out html - this.divjq.html(""); - this.lastTextWidth = 0; - // set up new html - this.panzoomContainer = $("
    ") - .addClass(`${JS9.PanZoom.BASE}Container`) - .attr("id", `${this.id}Container`) - .attr("width", this.width) - .attr("height", this.height) - .appendTo(this.divjq); - // do we have an image? - im = this.display.image; - if( im && (opts.mode !== "clear") ){ - // convenience variables - imid = im.id; - dispid = im.display.id; - mopts = []; - t = sprintf(JS9.PanZoom.panHTML, dispid, imid, getPanOptions()); - mopts.push({name: "pan", value: t}); - t = sprintf(JS9.PanZoom.zoomHTML, dispid, imid, getZoomOptions()); - mopts.push({name: "zoom", value: t}); - t = sprintf(JS9.PanZoom.flipHTML, dispid, imid, getFlipOptions()); - mopts.push({name: "flip", value: t}); - t = sprintf(JS9.PanZoom.rot90HTML, dispid, imid, getRot90Options()); - mopts.push({name: "rot90", value: t}); - t = sprintf(JS9.PanZoom.rotateHTML, dispid, imid, getRotOptions(im)); - mopts.push({name: "rotate", value: t}); - t = sprintf(JS9.PanZoom.pantoHTML, dispid, imid); - mopts.push({name: "panto", value: t}); - t = sprintf(JS9.PanZoom.pos1HTML, getPos(im, "x")); - mopts.push({name: "pos1", value: t}); - t = sprintf(JS9.PanZoom.pos2HTML, getPos(im, "y")); - mopts.push({name: "pos2", value: t}); - t = sprintf(JS9.PanZoom.sysHTML, dispid, imid, getSysOptions(im)); - mopts.push({name: "wcssys", value: t}); - t = sprintf(JS9.PanZoom.unitsHTML, dispid, imid, getUnitsOptions(im)); - mopts.push({name: "wcsunits", value: t}); - s = im.expandMacro(JS9.PanZoom.panzoomHTML, mopts); - this.lastimage = im; - } else { - s = "

    Pan/Zoom parameters will appear here.
    "; - } - this.panzoomContainer.html(s); - if( im ){ - // init run on cr, if necessary - if( JS9.globalOpts.runOnCR ){ - this.panzoomContainer.find("[name='pos1']") - .data("enterfunc", "panto"); - this.panzoomContainer.find("[name='pos2']") - .data("enterfunc", "panto"); - } - } -}; - -// add this plugin into JS9 -JS9.RegisterPlugin(JS9.PanZoom.CLASS, JS9.PanZoom.NAME, - JS9.PanZoom.init, - {menu: "zoom", - menuItem: "Pan/Zoom Controls ...", - onplugindisplay: JS9.PanZoom.init, - onsetpan: JS9.PanZoom.reinit, - onsetzoom: JS9.PanZoom.reinit, - onsetwcssys: JS9.PanZoom.reinit, - onsetwcsunits: JS9.PanZoom.reinit, - onimagedisplay: JS9.PanZoom.display, - onimageclose: JS9.PanZoom.close, - help: "help/zoomcontrols.html", - winTitle: "Pan/Zoom Controls", - winDims: [JS9.PanZoom.WIDTH, JS9.PanZoom.HEIGHT]}); diff --git a/web/static/js9_old/plugins/fitsy/README b/web/static/js9_old/plugins/fitsy/README deleted file mode 100644 index 9f871f26dc785eeb7de535eb518f8cc9a9496007..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/fitsy/README +++ /dev/null @@ -1 +0,0 @@ -original source: https://github.com/jbroll/fitsy.js diff --git a/web/static/js9_old/plugins/fitsy/binning.html b/web/static/js9_old/plugins/fitsy/binning.html deleted file mode 100644 index 43700973331d7f459ff937eaa91cdfea4fdb8060..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/fitsy/binning.html +++ /dev/null @@ -1,134 +0,0 @@ - - - - - -Plugin: FITSBinning - - - -
    -

    -

    FITS Image Sections, with Binning and Filtering

    - -The rows in a FITS binary table must be binned before being displayed -as an image. By default, JS9 uses a bin factor of 1 to extract the -central 2048 x 2048 section of the data for display. This default is -controlled by the JS9.globalOpts.table object properties, which can be -set in your js9Prefs.js file. - -

    -Also by default, the central 2048 x 2048 section of a FITS image is displayed -at bin 1. This default is controlled by the JS9.globalOpts.image object -properties, which can be set in your js9Prefs.js file. - -

    -The Bin/Filter/Section plugin allows you to extract sections -from FITS binary tables and images, with options to choose the image -center, image dimensions, and bin factor. For tables, the plugin also -allows you to filter rows of the table by means of arithmetic and -boolean operations on the table columns. - -

    -The Bin/Filter/Section plugin works with both FITS representation -files and with ordinary in-memory FITS files. If the displayed FITS -file is a representation file (i.e., it has a parent file, a JS9 -helper is connected, etc.), the plugin will ask the JS9 helper to -extract the image section from the parent. Otherwise, it extracts the -section from the in-memory FITS file. This behavior is meant to be -transparent to the user. - -

    -When extracting an image section, you can set one or more of the -following options: -

      -
    • center: the file (physical) coordinates around which to -perform the section extraction (0,0 can be used to specify the file center). -
    • size: the size of the image to extract (before binning (or blocking) is -performed). -
    • bin (tables) or block (images): determines how table events are binned or how physical pixels are combined into -a single image pixel, after the section is extracted. -
    • mode:summing or averging of the binned (blocked) pixels -
    • filter:for tables only: row/event filter to apply when extracting the section. -
    • separate: if true, display as a separate image (default is to update the current image). -
    -

    -For example, if a table has FITS (tlmin, tlmax) dimensions 4096 x 4096, then: -

      -
    • center: 2048, 2048; dimensions: 4096, 4096; bin: 4 will bin the entire file by 4 to produce a 1024 x 1024 image. -
    • center: 1024, 1024; dimensions: 1024, 1024, bin: 2 will bin the upper left 1024 x 1024 section of the image by 2 to produce a 512 x 512 image. -
    -Specifying 0,0 for the center will cause the section to be extracted from the -center of the image. - -

    -Although the binning parameter is usually input as an real value, there are -other options available: -

      -
    • x[n]|X[n]|*[n]: multiply the current bin by n (e.g., "x2") -
    • /[n]: divide the current bin by n (e.g., "/2") -
    • +[n]: add n to the current bin (e.g., "+2") -
    • -[n]: subtract n from the current bin (e.g., "-2") -
    • in|In: multiply the current bin by 2 -
    • out|Out: divide the current bin by 2 -
    • [n]a: bin by n, averaging the binned pixels -
    • [n]s: bin by n, summing the binned pixels -
    -Note that the JS9.globalOpts.binMode property specifies the -default action for whether the binned pixels are summed together (if -binMode is "s") or averaged (if binMode is "a"). This action is overridden -by the last two bin directives listed above or by the mode input option. - -

    -Table filtering allows you to select rows from an FITS binary table -(e.g., an X-ray event list) by checking each row against an expression -involving the columns in the table. When a table is filtered, only -valid rows satisfying these expressions are used to make the image. - -

    -A filter expression consists of an arithmetic or logical operation -involving one or more column values from a table. Columns can be -compared to other columns or to numeric constants. Standard JavaScript -math functions can be applied to columns. JavaScript (or C) semantics -are used when constructing expressions, with the usual precedence and -associativity rules holding sway: -

    -  Operator                                Associativity
    -  --------                                -------------
    -  ()                                      left to right
    -  !  (bitwise not) - (unary minus)        right to left
    -  *  /                                    left to right
    -  +  -                                    left to right
    -  < <= > >=                               left to right
    -  == !=                                   left to right
    -  &  (bitwise and)                        left to right
    -  ^  (bitwise exclusive or)               left to right
    -  |  (bitwise inclusive or)               left to right
    -  && (logical and)                        left to right
    -  || (logical or)                         left to right
    -  =                                       right to left
    -
    -For example, if energy and pha are columns in a table, -then the following are valid expressions: -
    -  pha > 1
    -  energy == pha
    -  pha > 1 && energy ≤ 2
    -  max(pha,energy)≥2.5
    -
    - -

    -NB: when using cfitsio (the default, instead of the deprecated -fitsy.js), table filtering follows cfitsio conventions, which is -documented -here. - -

    -Once the desired parameters have been set, pressing the Run -button will filter, bin and display the data. - -

    - - - diff --git a/web/static/js9_old/plugins/fitsy/binning.js b/web/static/js9_old/plugins/fitsy/binning.js deleted file mode 100644 index 91a912fd7bc8ea1e524c63662c8aaa2d75652896..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/fitsy/binning.js +++ /dev/null @@ -1,352 +0,0 @@ -/*globals $, JS9 */ - -"use strict"; - -(function() { - - function reBinImage(div, display) { - let opts, npos; - let im = JS9.GetImage({display: display}); - let form = $(div).find(".js9BinningForm")[0]; - // sanity check - if( !im || !im.raw ) { return; } - // initialize opts - opts = {xcen:0, ycen:0, xdim:0, ydim:0, bin:1, filter:"", - columns:"", cubecol:""}; - // get opts from form - if( JS9.isNumber(form.xcen.value) ){ - opts.xcen = parseFloat(form.xcen.value); - } - if( JS9.isNumber(form.ycen.value) ){ - opts.ycen = parseFloat(form.ycen.value); - } - npos = im.maybePhysicalToImage({x: opts.xcen, y: opts.ycen}); - if( npos ){ - opts.xcen = npos.x; - opts.ycen = npos.y; - } - if( JS9.isNumber(form.xdim.value) ){ - opts.xdim = Math.floor(parseFloat(form.xdim.value)); - } - if( JS9.isNumber(form.ydim.value) ){ - opts.ydim = Math.floor(parseFloat(form.ydim.value)); - } - if( JS9.isNumber(form.bin.value) ){ - opts.bin = parseFloat(form.bin.value); - } else { - opts.bin = form.bin.value; - } - if( JS9.isNumber(form.bitpix.value) ){ - opts.bitpix = parseInt(form.bitpix.value, 10); - } - opts.filter = form.filter.value; - opts.columns = form.columns.value; - opts.cubecol = form.cubecol.value; - // if columns changed, we have to reset the center to 0 - if( im.raw.hdu.table && im.raw.hdu.table.columns !== opts.columns ){ - opts. xcen = 0; - opts. ycen = 0; - } - opts.separate = $(form.separate).prop("checked"); - if( opts.cubecol ) opts.separate = true; - opts.binMode = $('input[name="binmode"]:checked').val(); - im.displaySection(opts); - } - - function centerBinImage(xdim, ydim, div, display) { - let im = JS9.GetImage({display: display}); - let form = $(div).find(".js9BinningForm")[0]; - let fdims = im.fileDimensions(); - form.xcen.value = 0; - form.ycen.value = 0; - if( xdim > 0 ){ - form.xdim.value = xdim; - } else { - form.xdim.value = fdims.xdim; - } - if( ydim > 0 ){ - form.ydim.value = ydim; - } else { - form.ydim.value = fdims.ydim; - } - reBinImage(div, display); - } - - function getBinParams(div, display) { - let im, ipos, lpos, form, hdu, bin; - if ( !display ) { - if( this ){ - display = this.display; - } else { - display = JS9.displays[0]; - } - } - im = JS9.GetImage({display: display}); - if ( im ) { - form = $(div).find(".js9BinningForm")[0]; - - if ( im.raw.hdu !== undefined ) { - hdu = im.raw.hdu; - hdu.bin = hdu.bin || 1; - hdu.binMode = hdu.binMode || JS9.globalOpts.binMode || "s"; - form.rebin.disabled = false; - if( hdu.table !== undefined && !JS9.ishealpix(im) ) { - // get current center - ipos = im.getPan(); - // convert to physial (file) coords - lpos = im.imageToLogicalPos({x: ipos.ox, y: ipos.oy}); - form.xcen.value = String(Math.floor(lpos.x + 0.5)); - form.ycen.value = String(Math.floor(lpos.y + 0.5)); - form.bin.value = String(hdu.table.bin); - form.xdim.value = String(Math.floor(hdu.table.xdim)); - form.ydim.value = String(Math.floor(hdu.table.ydim)); - form.filter.value = hdu.table.filter || ""; - form.bitpix.value = hdu.table.bitpix || JS9.globalOpts.table.bitpix; - form.columns.value = hdu.table.columns || ""; - form.cubecol.value = ""; - form.bin.disabled = false; - form.xcen.disabled = false; - form.ycen.disabled = false; - form.xdim.disabled = false; - form.ydim.disabled = false; - // form.binmode.disabled = false; - form.filter.disabled = false; - form.bitpix.disabled = false; - form.columns.disabled = false; - form.cubecol.disabled = false; - } else { - hdu.bin = hdu.bin || 1; - bin = hdu.bin > 0 ? hdu.bin : 1 / Math.abs(hdu.bin); - // hack: if a parent file was used to make this image, - // calculate binning from its LTM/TLV parameters - if( im.parentFile && im.raw.header && - im.raw.header.LTM1_1 !== undefined ){ - bin = 1.0 / Math.abs(im.raw.header.LTM1_1); - } - // get image center from raw data - // ipos = {x: im.raw.width / 2, y: im.raw.height / 2}; - // get current center - ipos = im.getPan(); - // convert to physial (file) coords - lpos = im.imageToLogicalPos({x: ipos.ox, y: ipos.oy}); - // form.xcen.value = String(Math.floor(lpos.x + 0.5)); - // form.ycen.value = String(Math.floor(lpos.y + 0.5)); - form.xcen.value = String(Math.floor(lpos.x + 0.5*(bin-1))); - form.ycen.value = String(Math.floor(lpos.y + 0.5*(bin-1))); - form.bin.value = String(hdu.bin); - form.xdim.value = String(Math.floor(hdu.naxis1 * bin)); - form.ydim.value = String(Math.floor(hdu.naxis2 * bin)); - form.filter.value = ""; - form.bitpix.value = im.raw.header.BITPIX; - form.columns.value = ""; - form.cubecol.value = ""; - form.bin.disabled = false; - form.xcen.disabled = false; - form.ycen.disabled = false; - form.xdim.disabled = false; - form.ydim.disabled = false; - form.binmode.disabled = false; - form.filter.disabled = true; - form.filter.style.backgroundColor="#E0E0E0"; - form.bitpix.disabled = true; - form.bitpix.style.backgroundColor="#E0E0E0"; - form.columns.disabled = true; - form.columns.style.backgroundColor="#E0E0E0"; - form.cubecol.disabled = true; - form.cubecol.style.backgroundColor="#E0E0E0"; - } - // cube support makes no sense using a parentFile - if( im.parentFile && - JS9.helper.connected && JS9.helper.js9helper ){ - form.cubecol.value = ""; - form.cubecol.disabled = true; - form.cubecol.style.backgroundColor="#E0E0E0"; - } - // average or sum - if( hdu.binMode === "a" ){ - $('input:radio[class="avg-pixels"]').prop('checked',true); - } else { - $('input:radio[class="sum-pixels"]').prop('checked',true); - } - } else { - form.rebin.disabled = true; - } - } - } - - function binningInit() { - let i, s, cols, el, smode; - let that = this; - let elhdu = " "; - let binblock = "Block"; - let binblocked = "blocked"; - let html = ""; - let div = this.div; - let display = this.display; - let win = this.winHandle; - let disclose = win ? "" : 'style="display:none;"'; - let im = JS9.GetImage({display: this.display}); - - if( !im || (im && !im.raw.hdu) ){ - div.innerHTML = '

    FITS image sections, with binning and filtering
    '; - return; - } - if( im.imtab === "table" ){ - binblock = "Bin"; - binblocked = "binned"; - if( !JS9.ishealpix(im) ){ - elhdu = '  -   -   - ${elhdu} - - Center: - - -  center position of section - - Size: - - -  width, height of section - - ${binblock}: - - -  apply ${binblock.toLowerCase()} factor to ${im.imtab} - `; - - if( im.imtab === "image" || JS9.ishealpix(im) ){ - html += ` - Mode: - sum - average -  sum or avg ${binblocked} pixels? - `; - html += ` - Bitpix: - -  image bitpix - `; - } else { - html += ` - Mode: - sum - -  binned tables are summed - `; - html += ` - Bitpix: - -  bitpix when binning table - `; - } - html += ` Filter: - -  event/row filter when binning table - - - BinCols: - -  alternate binning cols for table - - - CubeCol: - -  table→cube: col[:min:max][:binsiz] - - - Separate: - - -  display as separate image? - - -   -   -   - - -   - - - - - `; - $(div).html(html); - - // button and checkbox actions - $(div).find(".js9-binning-full").on("click", function () { centerBinImage(0, 0, div, display); }); - $(div).find(".js9-binning-rebin").on("click", function () { reBinImage(div, display); }); - $(div).find(".js9-binning-close").on("click", function () { if( win ){ win.close(); } }); - $(div).find(".js9-binning-sep").change(function() { that.sep = $(this).prop("checked"); }); - $(div).find(".js9-binning-sep").prop("checked", !!that.sep); - $(div).find(".js9-binning-cubecol").on("input", function () { - // cubes are generated as separate displays - // but resetting the cubecol should reset the separate mode - smode = $(this).val() ? true : !!that.sep; - $(div).find(".js9-binning-sep").prop("checked", smode); - }); - - if( im.imtab === "table" && im.hdus && im.hdus.length ){ - for(i=0; iList columns`); - for(i=0; i${s}`); - } - el.prop('selectedIndex', 0); - el.on("change", function () { - s = $(this).val().replace(/:.*/, ""); - JS9.CopyToClipboard(s, im); - el.prop('selectedIndex', 0); - }); - } - } - - // set up to rebin when is pressed, if necessary - if( JS9.globalOpts.runOnCR ){ - $(div).find(".js9BinningForm").data("enterfunc", "rebin"); - } - - // get current params - getBinParams.call(null, div, display); - } - - JS9.RegisterPlugin("FITS", "Binning", binningInit, { - menu: "view", - - winTitle: "Image Sections, with Binning and Filtering", - winResize: true, - - menuItem: "Bin/Filter/Section", - - onplugindisplay: binningInit, - onimageload: binningInit, - onimagedisplay: binningInit, - onsetpan: binningInit, - onsetzoom: binningInit, - - help: "fitsy/binning.html", - - winDims: [570, 375] - }); -}()); diff --git a/web/static/js9_old/plugins/fitsy/bzip2.js b/web/static/js9_old/plugins/fitsy/bzip2.js deleted file mode 100644 index f23d9234cdbaf585dc2a20fc661936ca6e7720ea..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/fitsy/bzip2.js +++ /dev/null @@ -1,283 +0,0 @@ -/* - bzip2.js - a small bzip2 decompression implementation - - Copyright 2011 by antimatter15 (antimatter15@gmail.com) - - Based on micro-bunzip by Rob Landley (rob@landley.net). - - Copyright (c) 2011 by antimatter15 (antimatter15@gmail.com). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH - THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -var bzip2 = {}; - -bzip2.array = function(bytes){ - var bit = 0, byte = 0; - var BITMASK = [0, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF ]; - return function(n){ - var result = 0; - while(n > 0){ - var left = 8 - bit; - if(n >= left){ - result <<= left; - result |= (BITMASK[left] & bytes[byte++]); - bit = 0; - n -= left; - }else{ - result <<= n; - result |= ((bytes[byte] & (BITMASK[n] << (8 - n - bit))) >> (8 - n - bit)); - bit += n; - n = 0; - } - } - return result - } -} - -bzip2.simple = function(bits){ - var size = bzip2.header(bits); - var all = [], chunk = [] - do{ - all = all.concat(all, chunk); - chunk = bzip2.decompress(bits, size); - }while(chunk != -1); - return all; -} - -bzip2.header = function(bits){ - if(bits(8*3) != 4348520) throw "No magic number found"; - var i = bits(8) - 48; - if(i < 1 || i > 9) throw "Not a BZIP archive"; - return i; -}; - - -//takes a function for reading the block data (starting with 0x314159265359) -//a block size (0-9) (optional, defaults to 9) -//a length at which to stop decompressing and return the output -bzip2.decompress = function(bits, size, len){ - var MAX_HUFCODE_BITS = 20; - var MAX_SYMBOLS = 258; - var SYMBOL_RUNA = 0; - var SYMBOL_RUNB = 1; - var GROUP_SIZE = 50; - - var bufsize = 100000 * size; - for(var h = '', i = 0; i < 6; i++) h += bits(8).toString(16); - if(h == "177245385090") return -1; //last block - if(h != "314159265359") throw "eek not valid bzip data"; - bits(32); //ignore CRC codes - if(bits(1)) throw "unsupported obsolete version"; - var origPtr = bits(24); - if(origPtr > bufsize) throw "Initial position larger than buffer size"; - var t = bits(16); - var symToByte = new Uint8Array(256), - symTotal = 0; - for (i = 0; i < 16; i++) { - if(t & (1 << (15 - i))) { - var k = bits(16); - for(j = 0; j < 16; j++){ - if(k & (1 << (15 - j))){ - symToByte[symTotal++] = (16 * i) + j; - } - } - } - } - - var groupCount = bits(3); - if(groupCount < 2 || groupCount > 6) throw "another error"; - var nSelectors = bits(15); - if(nSelectors == 0) throw "meh"; - var mtfSymbol = []; //TODO: possibly replace JS array with typed arrays - for(var i = 0; i < groupCount; i++) mtfSymbol[i] = i; - var selectors = new Uint8Array(32768); - - for(var i = 0; i < nSelectors; i++){ - for(var j = 0; bits(1); j++) if(j >= groupCount) throw "whoops another error"; - var uc = mtfSymbol[j]; - mtfSymbol.splice(j, 1); //this is a probably inefficient MTF transform - mtfSymbol.splice(0, 0, uc); - selectors[i] = uc; - } - - var symCount = symTotal + 2; - var groups = []; - for(var j = 0; j < groupCount; j++){ - var length = new Uint8Array(MAX_SYMBOLS), - temp = new Uint8Array(MAX_HUFCODE_BITS+1); - t = bits(5); //lengths - for(var i = 0; i < symCount; i++){ - while(true){ - if (t < 1 || t > MAX_HUFCODE_BITS) throw "I gave up a while ago on writing error messages"; - if(!bits(1)) break; - if(!bits(1)) t++; - else t--; - } - length[i] = t; - } - var minLen, maxLen; - minLen = maxLen = length[0]; - for(var i = 1; i < symCount; i++){ - if(length[i] > maxLen) maxLen = length[i]; - else if(length[i] < minLen) minLen = length[i]; - } - var hufGroup; - hufGroup = groups[j] = {}; - hufGroup.permute = new Uint32Array(MAX_SYMBOLS); - hufGroup.limit = new Uint32Array(MAX_HUFCODE_BITS + 1); - hufGroup.base = new Uint32Array(MAX_HUFCODE_BITS + 1); - hufGroup.minLen = minLen; - hufGroup.maxLen = maxLen; - var base = hufGroup.base.subarray(1); - var limit = hufGroup.limit.subarray(1); - var pp = 0; - for(var i = minLen; i <= maxLen; i++) - for(var t = 0; t < symCount; t++) - if(length[t] == i) hufGroup.permute[pp++] = t; - for(i = minLen; i <= maxLen; i++) temp[i] = limit[i] = 0; - for(i = 0; i < symCount; i++) temp[length[i]]++; - pp = t = 0; - for(i = minLen; i < maxLen; i++) { - pp += temp[i]; - limit[i] = pp - 1; - pp <<= 1; - base[i+1] = pp - (t += temp[i]); - } - limit[maxLen]=pp+temp[maxLen]-1; - base[minLen]=0; - } - var byteCount = new Uint32Array(256); - for(var i = 0; i < 256; i++) mtfSymbol[i] = i; - var runPos, count, symCount, selector; - runPos = count = symCount = selector = 0; - var buf = new Uint32Array(bufsize); - while(true){ - if(!(symCount--)){ - symCount = GROUP_SIZE - 1; - if(selector >= nSelectors) throw "meow i'm a kitty, that's an error"; - hufGroup = groups[selectors[selector++]]; - base = hufGroup.base.subarray(1); - limit = hufGroup.limit.subarray(1); - } - i = hufGroup.minLen; - j = bits(i); - while(true){ - if(i > hufGroup.maxLen) throw "rawr i'm a dinosaur"; - if(j <= limit[i]) break; - i++; - j = (j << 1) | bits(1); - } - j -= base[i]; - if(j < 0 || j >= MAX_SYMBOLS) throw "moo i'm a cow"; - var nextSym = hufGroup.permute[j]; - if (nextSym == SYMBOL_RUNA || nextSym == SYMBOL_RUNB) { - if(!runPos){ - runPos = 1; - t = 0; - } - if(nextSym == SYMBOL_RUNA) t += runPos; - else t += 2 * runPos; - runPos <<= 1; - continue; - } - if(runPos){ - runPos = 0; - if(count + t >= bufsize) throw "Boom."; - uc = symToByte[mtfSymbol[0]]; - byteCount[uc] += t; - while(t--) buf[count++] = uc; - } - if(nextSym > symTotal) break; - if(count >= bufsize) throw "I can't think of anything. Error"; - i = nextSym -1; - uc = mtfSymbol[i]; - mtfSymbol.splice(i, 1); - mtfSymbol.splice(0, 0, uc); - uc = symToByte[uc]; - byteCount[uc]++; - buf[count++] = uc; - } - if(origPtr < 0 || origPtr >= count) throw "I'm a monkey and I'm throwing something at someone, namely you"; - var j = 0; - for(var i = 0; i < 256; i++){ - k = j + byteCount[i]; - byteCount[i] = j; - j = k; - } - for(var i = 0; i < count; i++){ - uc = buf[i] & 0xff; - buf[byteCount[uc]] |= (i << 8); - byteCount[uc]++; - } - var pos = 0, current = 0, run = 0; - if(count) { - pos = buf[origPtr]; - current = (pos & 0xff); - pos >>= 8; - run = -1; - } - count = count; - - var maxindex = 10000000; - var output = []; - var bindex = maxindex + 1; - var outbuf; - - var copies, previous, outbyte; - if(!len) len = Infinity; - while(count){ - count--; - previous = current; - pos = buf[pos]; - current = pos & 0xff; - pos >>= 8; - if(run++ == 3){ - copies = current; - outbyte = previous; - current = -1; - }else{ - copies = 1; - outbyte = current; - } - while(copies--){ - if ( bindex >= maxindex ) { - if ( outbuf !== undefined ) { - output.push(outbuf); - } - outbuf = new Uint8Array(maxindex); - bindex = 0; - } - - outbuf[bindex++] = outbyte; - - if(!--len) { - outbuf = outbuf.subarray(0, bindex); - output.push(outbuf); - return output; - } - } - if(current != previous) run = 0; - - } - - outbuf = outbuf.subarray(0, bindex); - output.push(outbuf); - return output; -} diff --git a/web/static/js9_old/plugins/fitsy/fitsy.js b/web/static/js9_old/plugins/fitsy/fitsy.js deleted file mode 100644 index 59191e901b035be40de3024cc2e4732f7e7fad87..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/fitsy/fitsy.js +++ /dev/null @@ -1,1247 +0,0 @@ -/*jslint evil: true, white: true, vars: true, plusplus: true, nomen: true, unparam: true, regexp: true, bitwise: true */ -/*jshint node: true, -W099: true, laxbreak:true, laxcomma:true, multistr:true, smarttabs:true */ -/*global $, alert, XMLHttpRequest - , Uint8Array, Int8Array, Uint16Array, Int16Array, Int32Array, Uint32Array, Float32Array, Float64Array, DataView, ArrayBuffer - , FileReader, Blob, Image, window, document - , Zee, Astroem, Module, pako, LZMA, bzip2 - */ - -"use strict"; - -var Fitsy; -if( Fitsy && (typeof Fitsy !== "object" || Fitsy.NAME) ){ - throw new Error("Namespace 'Fitsy' already exists"); -} - -// Create our namespace, and specify some meta-information -Fitsy = {}; -Fitsy.NAME = "Fitsy"; // The name of this namespace -Fitsy.VERSION = "1.0"; // The version of this namespace - -Fitsy.clone = function (obj) { - var copy, i, len, attr; - - // Handle the 3 simple types, and null or undefined - if (null === obj || "object" !== typeof obj) { return obj; } - - // Handle Date - if (obj instanceof Date) { - copy = new Date(); - copy.setTime(obj.getTime()); - return copy; - } - - // Handle Array - if (obj instanceof Array) { - copy = []; - for ( i = 0, len = obj.length; i < len; i++ ) { - copy[i] = Fitsy.clone(obj[i]); - } - return copy; - } - - // Handle Object - if (obj instanceof Object) { - copy = {}; - for ( attr in obj ) { - if ( obj.hasOwnProperty(attr) ) { copy[attr] = Fitsy.clone(obj[attr]); } - } - return copy; - } - - throw new Error("Unable to copy obj! Its type isn't supported."); -}; - -Fitsy.strrepeat = function (pattern, count) { - if ( count < 1 ) { return ''; } - var result = ''; - while ( count > 1 ) { - if (count & 1) { result += pattern; } - - count >>= 1; - pattern += pattern; - } - return result + pattern; -}; - -// ArrayBuffer slice not yet available everywhere ... but it should be -if (!ArrayBuffer.prototype.slice) { - ArrayBuffer.prototype.slice = function(start, end) { - var i, result, resultArray; - var that = new Uint8Array(this); - if(end === undefined){ - end = that.length; - } - result = new ArrayBuffer(end - start); - resultArray = new Uint8Array(result); - for(i = 0; i < resultArray.length; i++){ - resultArray[i] = that[i + start]; - } - return result; - }; -} - -// hostEndian: 'true' means little-endian (for use in typed array calls) -Fitsy.hostEndian = (function(){ - return new Int8Array(new Int32Array([1]).buffer)[0] === 1; -}()); - -// copy memory from one arraybuffer to another -Fitsy.memcpy = function(dst, dstOffset, src, srcOffset, length) { - var dstU8 = new Uint8Array(dst, dstOffset, length); - var srcU8 = new Uint8Array(src, srcOffset, length); - dstU8.set(srcU8); -}; - -// getDataSlice -- get a slice of data from a File reader or an Arraybuffer -// memory optimization leads to not slicing arrays, but marking the limits -Fitsy.getDataSlice = function(fits, dtype, lo, hi, func, err){ - var chunk, totalget, totalgot, maxget, get, got, left, ptr, heapptr; - var args = Array.prototype.slice.call(arguments, 6); - switch(fits.ftype){ - case "file": - if( func ){ - fits.read.onloadend = function(){ - // convert to binary string, if necessary - if( dtype === "asString" ){ - fits.result = Fitsy.getBinaryString(fits.read.result); - } else { - fits.result = fits.read.result; - } - func.apply(null, args); - }; - } - if( err ){ - fits.read.onerror = function(){ err.apply(null, args); }; - } - if( lo || hi ){ - chunk = Fitsy.getFileSlice(fits.file, lo, hi); - } else { - chunk = fits.file; - } - // always readAsArraybuffer because readAsBinaryString is not in IE11 - // binary string will be made, if necessary, after load is done - fits.read.readAsArrayBuffer(chunk); - break; - case "array": - if( dtype === "asString" ){ - // for a binary string, a slice is OK (assumed to be small) - if( lo || hi ){ - chunk = fits.file.slice(lo, hi); - } else { - // shouldn't happen! - chunk = fits.file; - } - // mimick readAsBinaryString conversion - fits.result = Fitsy.getBinaryString(chunk); - } else { - // we pass along the whole array - fits.result = fits.file; - if( lo && hi ){ - // avoid a new array.slice, it uses extra memory needlessly - // instead just mark the limits and let func use these limits - fits.rlo = lo; - fits.rhi = hi; - } else { - delete fits.rlo; - delete fits.rhi; - } - } - if( func ){ - func.apply(null, args); - } - break; - case "gzarray": - // seek to desired location - if( lo !== fits.gz.here ){ - Astroem.gzseek(fits.gz.fd, lo, 0); - fits.gz.here = lo; - } - // total number of bytes to retrieve - totalget = hi - lo; - // allocate space for retrieved data - try{ chunk = new Uint8Array(totalget); } - catch(e){ Fitsy.error("can't allocate enough memory to slice this FITS file", e); } - // max we will retrieve at any one time (minimize precious heap space) - maxget = Math.min(totalget, Fitsy.options.gzheapsize); - // allocate space on emscripten heap - ptr = Module._malloc(maxget); - // pointer into heap space to pass into routine - heapptr= new Uint8Array(Module.HEAPU8.buffer, ptr, maxget); - // this is how much we have left to retrieve - left = totalget; - // nothing retrieved yet - totalgot = 0; - // processing loop ... - while( left ){ - // how much to retrieve on this iteration - get = Math.min(left, maxget); - // try to uncompress that amount - got = Astroem.gzread(fits.gz.fd, heapptr.byteOffset, get); - // if we got anything ... - if( got > 0 ){ - // copy new data in output buffer - Fitsy.memcpy(chunk.buffer, totalgot, - Module.HEAPU8.buffer, ptr, got); - totalgot += got; - left -= got; - } else { - // we're done - left = 0; - } - } - // free up heap space - Module._free(heapptr.byteOffset); - // mark where we are in the gzip file - fits.gz.here = lo + totalgot; - // see if we got anything - if( totalgot > 0 ){ - // convert to string - if( dtype === "asString" ){ - fits.result = Fitsy.getBinaryString(chunk); - } else { - // return raw data buffer - fits.result = chunk.buffer; - } - } else { - // handle eof - fits.eof = true; - } - // call handler - if( func ){ - func.apply(null, args); - } - break; - } -}; - -// convert arraybuffer into binary string -// akin to file.readAsBinaryString for ArrayBuffers -// but also used as a replacement for readAsBinaryString (it's not in IE11) -Fitsy.getBinaryString = function(buf){ - var s = String.fromCharCode.apply(null, new Uint8Array(buf)); - return s; -}; - -// generate a table column filter from a funtools-style expression -Fitsy.tableFilter = function(hdu, filter){ - var ft1=filter; - // convert ranges: - // pi = 100:200 -> (pi >= 100 && pi <= 200) - ft1 = ft1.replace(/([a-zA-Z][a-zA-Z0-9_]*) *= *([\-]?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+\-]?[0-9]+)?) *: *([\-]?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+\-]?[0-9]+)?)/g, "($1 >= $2 && $1 <= $3)"); - // pi = 100: -> pi >= 100 - ft1 = ft1.replace(/([a-zA-Z][a-zA-Z0-9_]*) *= *([\-]?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+\-]?[0-9]+)?) *:/g, "$1 >= $2"); - // pi = :100 -> pi <= 100 - ft1 = ft1.replace(/([a-zA-Z][a-zA-Z0-9_]*) *= *:([\-]?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+\-]?[0-9]+)?)/g, "$1 <= $2"); - // lookup columns and return generated filter string - return ft1.replace(/([ (&|+\-\/*%<>=]|^)?([a-zA-Z][a-zA-Z0-9_]*)([ )&|+\-\/*%<>=]|$)/g, function (m, delim1, key, delim2) { - var s = key; - var t = key.toUpperCase(); - delim1 = delim1 || ""; - delim2 = delim2 || ""; - if ( hdu.table[s] !== undefined ) { - s = delim1 + "view.get" + hdu.table[s].type + "(vstart + i * {{table.width}} + " + hdu.table[s].offs + ")" + delim2; - } else if ( hdu.table[t] !== undefined ) { - s = delim1 + "view.get" + hdu.table[t].type + "(vstart + i * {{table.width}} + " + hdu.table[t].offs + ")" + delim2; - } else { - // couldn't find column -- that's bad - Fitsy.error("the requested column '" + key + "' is missing from this FITS table"); - } - return s; - }); -}; - -// there are different versions of file slicing ... with different syntax -Fitsy.getFileSlice = function(file, start, end){ - var blob; - if( file.slice ){ - blob = file.slice(start, end); - } else if( file.mozSlice ){ - blob = file.mozSlice(start, end); - } else if( file.webkitSlice ){ - blob = file.webkitSlice(start, end); - } - return blob; -}; - -// return true if its a number (int or float) -Fitsy.isNumber = function(s) { - return !isNaN(parseFloat(s)) && isFinite(s); -}; - -Fitsy.xtypeof = function(obj) { - return Object.prototype.toString.call(obj).slice(8, -1); -}; - -// http://stackoverflow.com/questions/3885817/how-to-check-if-a-number-is-float-or-integer -Fitsy.isFloat = function(n) { - return n === +n && n !== (n|0); -}; - -Fitsy.cardpars = function(card){ - var name, value; - if ( card[8] !== "=" ){ - return undefined; - } - name = card.slice(0, 8).trim(); - value = card.slice(10).replace(/\'/g, " ").replace(/\/.*/, "").trim(); - if( value === "T" ){ - value = true; - } else if( value === "F" ){ - value = false; - } else if( Fitsy.isNumber(value) ){ - value = parseFloat(value); - } - - return [name, value]; -}; - -Fitsy.readImageHDUDataConverter = function(fits, hdu, options, handler){ - var dv, getfunc, setfunc, tval, i, off, scale, zero, memerr; - var rstart = 0; - var littleEndian; - hdu.dmin = Number.MAX_VALUE; - hdu.dmax = Number.MIN_VALUE; - hdu.filename = fits.name; - - switch(fits.ftype){ - case "array": - if( fits.rlo ){ - // mark offsets into ArrayBuffer where this slice starts - rstart = fits.rlo; - } - break; - } - - switch( hdu.bitpix ) { - case 8: - getfunc = DataView.prototype.getUint8; - setfunc = DataView.prototype.setUint8; - try{ hdu.filedata = new Uint8Array(fits.result, rstart); } - catch(e){memerr = true;} - break; - case -16: - getfunc = DataView.prototype.getUint16; - setfunc = DataView.prototype.setUint16; - try{hdu.filedata = new Uint16Array(fits.result, rstart);} - catch(e){memerr = true;} - break; - case 16: - if ( hdu.bzero && hdu.bzero === 32768 ) { - getfunc = DataView.prototype.getInt16; - setfunc = DataView.prototype.setUint16; - try{hdu.filedata = new Uint16Array(fits.result, rstart);} - catch(e){memerr = true;} - hdu.bitpix = -16; - } else { - getfunc = DataView.prototype.getInt16; - setfunc = DataView.prototype.setInt16; - try{hdu.filedata = new Int16Array(fits.result, rstart);} - catch(e){memerr = true;} - } - break; - case 32: - getfunc = DataView.prototype.getInt32; - setfunc = DataView.prototype.setInt32; - try{hdu.filedata = new Int32Array(fits.result, rstart);} - catch(e){memerr = true;} - break; - case -32: - getfunc = DataView.prototype.getFloat32; - setfunc = DataView.prototype.setFloat32; - try{hdu.filedata = new Float32Array(fits.result, rstart);} - catch(e){memerr = true;} - break; - case -64: - getfunc = DataView.prototype.getFloat64; - setfunc = DataView.prototype.setFloat64; - try{hdu.filedata = new Float64Array(fits.result, rstart);} - catch(e){memerr = true;} - break; - default: - Fitsy.error("unsupported FITS BITPIX value: " + hdu.bitpix); - break; - } - // process memory allocation errors - if( memerr ){ - Fitsy.error("can't allocate enough memory for this FITS image"); - } - // this is where the caller (e.g. JS9) sees the data - hdu.image = hdu.filedata; - - zero = hdu.bzero || 0; - scale = hdu.bscale || 1; - - // Convert raw bytes to image data using the appropriate data view - // - dv = new DataView(fits.result); - littleEndian = hdu.converted ? Fitsy.hostEndian : false; - for(i=0, off=rstart; i < hdu.datapixls; i++, off += hdu.pixlbytes) { - tval = getfunc.call(dv, off, littleEndian) * scale + zero; - if ( !isNaN(tval) ) { - hdu.dmin = Math.min(hdu.dmin, tval); - hdu.dmax = Math.max(hdu.dmax, tval); - } - if( !hdu.converted ){ - setfunc.call(dv, off, tval, Fitsy.hostEndian); - } - } - hdu.converted = true; - - handler(hdu, options); -}; - -Fitsy.readImageHDUData = function(fits, hdu, options, handler) { - // fits.read.onloadend = function() { Fitsy.readImageHDUDataConverter(fits, hdu, options, handler); }; - // fits.read.readAsArrayBuffer(Fitsy.getFileSlice(fits.file, hdu.dataseek, hdu.dataseek + hdu.databloks*2880)); - Fitsy.getDataSlice(fits, "asArray", - hdu.dataseek, hdu.dataseek + hdu.databloks*2880, - Fitsy.readImageHDUDataConverter, Fitsy.readError, - fits, hdu, options, handler); - -}; - -var TableTFORM = { - L: { type: "UChar", size: 1 } - , X: { type: "BITS", size: 1 } - , B: { type: "UChar", size: 1 } - , I: { type: "Int16", size: 2 } - , J: { type: "Int32", size: 4 } - , K: { type: "Int64", size: 8 } - , A: { type: "Char", size: 1 } - , E: { type: "Float32", size: 4 } - , D: { type: "Float64", size: 8 } - , C: { type: "Complex64", size: 8 } - , M: { type: "Complex128", size:16 } - , P: { type: "Pointer32", size: 8 } - , Q: { type: "Pointer64", size:16 } -}; - -Fitsy.readError = function(e) { - Fitsy.error("an error occurred while reading the FITS file. (Often this is due to the browser running out of memory.)", e); -}; - -// signal waiting or done waiting -Fitsy.waiting = function(mode){ - if( Fitsy.options.waiting ){ - Fitsy.options.waiting(mode); - } -}; - -// error handler -Fitsy.error = function(s, e) { - Fitsy.waiting(false); - if( Fitsy.options.error ){ - Fitsy.options.error(s, e); - } else { - throw new Error(s); - } -}; - -Fitsy.readForDeCompress = function(fits) { - - var data = new Uint8Array(fits.result); - - if ( data[0] === 0xfd && data[1] === 0x37 && data[2] === 0x7a && data[3] === 0x58 ) { // lzip - if ( window.LZMA !== undefined ) { - - LZMA.decompress(data, function(result) { - fits.file = new Blob([result]); - - // fits.read.onloadend = function(){ Fitsy.readHeaderBlock(fits); }; - // fits.read.onerror = function(){ Fitsy.readError(fits); }; - // fits.read.readAsBinaryString(Fitsy.getFileSlice(fits.file, 0, 2880)); - Fitsy.getDataSlice(fits, "asString", 0, 2880, - Fitsy.readHeaderBlock, Fitsy.readError, - fits); - - - }); - - return; - } - - Fitsy.error("lzip support not available"); - } else if ( data[0] === 0x42 && data[1] === 0x5a ) { // bzip2 - if ( window.bzip2 !== undefined ) { - data = bzip2.simple(bzip2.array(data)); - fits.file = new Blob(data); - } else { - Fitsy.error("bzip2 support not available"); - } - } else if ( data[0] === 0x1f && data[1] === 0x8B ) { // gzip - // we are done with these ... so tell garbage collector - delete fits.file; - delete fits.hdu; - fits.hdu = []; - if ( window.hasOwnProperty("Astroem") ) { - if( data.buffer.byteLength > Fitsy.options.gzfilesize ) { - // new gzip array object - fits.ftype = "gzarray"; - fits.gz = {}; - // temp file in the emscripten file system mapped to the data - fits.gz.arrfile = Astroem.arrfile(fits.name, data); - // open the gzip'ed file - fits.gz.fd = Astroem.gzopen(fits.gz.arrfile.path, "rb"); - // reset file position - fits.gz.here = 0; - // don't know file size, we'll rely on eof - fits.size = -1; - fits.eof = false; - } else { - data = Astroem.decompress(data); - // fits.file = new Blob([data]); - fits.ftype = "array"; - fits.file = data.buffer; - fits.size = fits.file.byteLength; - } - } else if ( window.hasOwnProperty("Zee") ) { - data = Zee.decompress(data); - // fits.file = new Blob([data]); - fits.ftype = "array"; - fits.file = data.buffer; - fits.size = fits.file.byteLength; - } else if ( window.hasOwnProperty("pako") ) { - data = pako.inflate(data); - // fits.file = new Blob([data]); - fits.ftype = "array"; - fits.file = data.buffer; - fits.size = fits.file.byteLength; - } else { - Fitsy.error("gzip support not available"); - } - } else { - - Fitsy.error("not a recognized FITS file (compressed or otherwise): " + fits.name); - - } - - // fits.read.onloadend = function(){ Fitsy.readHeaderBlock(fits); }; - // fits.read.onerror = function(){ Fitsy.readError(fits); }; - // fits.read.readAsBinaryString(Fitsy.getFileSlice(fits.file, 0, 2880)); - Fitsy.getDataSlice(fits, "asString", 0, 2880, - Fitsy.readHeaderBlock, Fitsy.readError, - fits); -}; - -Fitsy.readHeaderBlock = function(fits) { - var i, off, card, pars; - var end = 0; - - // if we hit EOF on last read (usually a gzip'ed file), call the handler - if( fits.eof ){ - // call handler - Fitsy.waiting(false); - fits.handler(fits); - } - - if( !fits.hdu[fits.nhdu] ){ - fits.hdu[fits.nhdu] = {}; - } - var hdu = fits.hdu[fits.nhdu]; - if ( ! hdu.card ) { - // Mark offset in file where header starts. - hdu.headseek = fits.here; - hdu.card = []; - hdu.head = {}; - hdu.ncard = 0; - - hdu.fits = fits; - hdu.nth = fits.nhdu; - - if ( fits.here === 0 && fits.result.slice(0, 6) !== "SIMPLE" ) { - // fits.read.onloadend=function(){ Fitsy.readForDeCompress(fits); }; - // fits.read.readAsArrayBuffer(fits.file); - - // read entire compressed file and ready it for decompression - Fitsy.waiting(true); - // OMG: a delay is required to ensure cursor gets set to waiting - setTimeout(function() { - Fitsy.getDataSlice(fits, "asArray", null, null, - Fitsy.readForDeCompress, Fitsy.readError, - fits); - }, Fitsy.options.wtimeout); - - return; - } - } - if ( fits.here === 0 ) { - if ( fits.result.slice(0, 6) !== "SIMPLE" ) { - return; - } - } else { - if ( hdu.ncard === 0 && fits.result.slice(0, 8) !== "XTENSION" ) { - return; - } - } - - // Read the block advance the file pointer. - fits.here += 2880; - for ( off=0; off < 2880; hdu.ncard++, off += 80 ) { - card = fits.result.slice(off, off+80); - hdu.card[hdu.ncard] = card; - if ( card.slice(0, 8) === "END " ) { - end = 1; - break; - } - pars = Fitsy.cardpars(card); - if ( pars !== undefined ) { - hdu.head[pars[0]] = pars[1]; - } - } - if ( end ) { - hdu.axis = []; - hdu.dataseek = fits.here; // Mark offset in file where data starts. - hdu.naxis = hdu.head.NAXIS; - hdu.bitpix = hdu.head.BITPIX; - hdu.bscale = hdu.head.BSCALE; - hdu.bzero = hdu.head.BZERO; - hdu.pixlbytes = Math.abs(hdu.bitpix)/8; - - if ( hdu.naxis !== 0 ) { - hdu.datapixls = 1; - } else { - hdu.datapixls = 0; - } - - for(i=1; i <= hdu.naxis; i++){ - hdu.axis[i] = hdu.head["NAXIS" + i]; - hdu.datapixls *= hdu.axis[i]; - } - hdu.databytes = hdu.datapixls * hdu.pixlbytes; - hdu.databloks = ((hdu.databytes+(2880-1))/2880) | 0; // |0 is truncate. - fits.here += hdu.databloks * 2880; - fits.nhdu++; - - hdu.type = "image"; - - hdu.filehead = hdu.head; - hdu.filecard = hdu.card; - - if ( hdu.head.XTENSION === "BINTABLE" - || hdu.head.XTENSION === "A3DTABLE" - || hdu.head.XTENSION === "3DTABLE" ) { - - hdu.type = "table"; - - hdu.table = {}; - - hdu.width = hdu.axis[1]; - hdu.length = hdu.axis[2]; - - var form, rept, type, size, width, offs = 0; - - for ( i = 1; i <= hdu.head.TFIELDS; i++ ) { - form = hdu.head["TFORM"+i].match(/([0-9]*)([LXBIJKAEDCMPQ])/); - - rept = form[1] === "" ? 1 : +form[1]; - type = TableTFORM[form[2]].type; - size = TableTFORM[form[2]].size; - width = rept * size; - - hdu.table[hdu.head["TTYPE"+i]] = { - type: type - , size: size, width: width , rept: rept, offs: offs - , unit: hdu.head["TUNIT"+i], disp: hdu.head["TDISP"+i] - , zero: hdu.head["TZERO"+i], scale: hdu.head["TSCAL"+i] - - , min: hdu.head["TDMIN"+i] || hdu.head["TLMIN"+i] - , max: hdu.head["TDMAX"+i] || hdu.head["TLMAX"+i] - , ith: i - }; - offs += width; - } - } - } - if ( (fits.here >= fits.size) && (fits.size !== -1) ) { // EOF? hand the fits file to the handler function - Fitsy.waiting(false); - fits.handler(fits); - } else { // Or, read the next header block - // fits.read.readAsBinaryString(Fitsy.getFileSlice(fits.file, - // fits.here, - // fits.here+2880)); - Fitsy.getDataSlice(fits, "asString", fits.here, fits.here + 2880, - Fitsy.readHeaderBlock, Fitsy.readError, - fits); - } -}; - -Fitsy.fitsopen = function(file, handler) { - var fits = {}; - fits.hdu = []; - fits.read = new FileReader(); - fits.handler = handler; // User callback to complete delivery of FITS data. - if( !file ){ - Fitsy.readError(null); - } - fits.name = file.name; - fits.size = file.size; - fits.file = file; - fits.ftype = "file"; - fits.nhdu = 0; - fits.here = 0; - - // fits.read.onloadend = function(){ Fitsy.readHeaderBlock(fits); }; - // fits.read.readAsBinaryString(Fitsy.getFileSlice(fits.file, 0, 2880)); - Fitsy.getDataSlice(fits, "asString", 0, 2880, - Fitsy.readHeaderBlock, Fitsy.readError, - fits); -}; - - -Fitsy.template = function (str, data) { - - return str.replace(/\{\{([a-zA-Z0-9_.]+)(%([sfd])(\.([0-9]+))?)?\}\}/g, - function (m,key, x, type, y, prec) { - var i, val = data; - - key = key.split("."); - - for ( i = 0; i < key.length; i++ ) { - if ( val.hasOwnProperty(key[i]) ) { val = val[key[i]]; - } else { return ""; } - } - - switch ( type ) { - case "s": break; - case "f": val = val.toFixed(prec); break; - case "d": val = val.toFixed(0); break; - } - - return val; - } - ); -}; - -Fitsy.BinTableTemplate = " \n\ - return function (view, vstart, image, length) { \n\ - var i, x, y; \n\ - \n\ - var xoff = ((-( {{table.x.range}}/2 + ({{table.cx}}-{{table.x.range}}/2 )) {{BinText}}) | 0)\n\ - + (( {{image.nx}}/2 ) | 0); \n\ - var yoff = ((-( {{table.y.range}}/2 + ({{table.cy}}-{{table.x.range}}/2 )) {{BinText}}) | 0)\n\ - + (( {{image.ny}}/2 ) | 0); \n\ - \n\ - for (i = 0; i < length; i++) { \n\ - if( {{FilterText}} ){ \n\ - x = view.get{{table.x.type}}(vstart + i * {{table.width}} + {{table.x.offs}}); \n\ - y = view.get{{table.y.type}}(vstart + i * {{table.width}} + {{table.y.offs}}); \n\ - \n\ - x = (((x - {{table.x.min}}) {{BinText}}) | 0) + xoff; \n\ - y = (((y - {{table.y.min}}) {{BinText}}) | 0) + yoff; \n\ - \n\ - if (x >= 0 && x < {{image.nx}} && y >= 0 && y < {{image.ny}}) { \n\ - image.data[y * {{image.width}} + x] += 1; \n\ - } \n\ - } \n\ - } \n\ -}"; - -Fitsy.readTableHDUDataBinner = function (fits, hdu, nev, options, handler) { - var i, binner, BinText, FilterTemplate; - var FilterText = "true"; - var vstart = 0; - var opttable = options.table || Fitsy.options.table; - - if( !hdu.nev ){ - - hdu.filename = fits.name; - - if( hdu.image && (hdu.image.length >= (opttable.nx * opttable.ny)) ){ - for(i=0; i 0 ) { - if ( hdu.head.SIMPLE || hdu.head.XTENSION === "IMAGE" ) { - Fitsy.readImageHDUData(fits, hdu, options, handler); - break; - } - if ( hdu.table && hdu.head.EXTNAME === events ) { - Fitsy.readTableHDUData(fits, hdu, options, handler); - break; - } - } - } -}; - -Fitsy.handleFITSFile = function(file, options, handler) { // Read the headers. - - if ( options === undefined ) { options = Fitsy.options; } - if ( handler === undefined ) { handler = Fitsy.handler; } - - Fitsy.fitsopen(file, function (fits) { Fitsy.defaultDispatchFITS(fits, options, handler); }); -}; - - -// set default handler for data handler -// -Fitsy.datahandler = function(handler) { Fitsy.handler = handler; }; -Fitsy.dataoptions = function(options) { Fitsy.options = options; }; - -Fitsy.dragenter = function(id, e) { e.stopPropagation(); e.preventDefault(); }; -Fitsy.dragover = function(id, e) { e.stopPropagation(); e.preventDefault(); }; -Fitsy.dragexit = function(id, e) { e.stopPropagation(); e.preventDefault(); }; -Fitsy.dragdrop = function(id, e) { e.stopPropagation(); e.preventDefault(); - - Fitsy.onFile(e.target.files || e.dataTransfer.files, { display: id }); -}; - - -Fitsy.onFile = function(files, options, handler) { - var i; - - for ( i = 0; i < files.length; i++ ) { - if ( files[i].type !== "image/fits" && files[i].type.indexOf("image/") !== -1 ) { - Fitsy.handleImageFile(files[i], options, handler); - } else { - try{ Fitsy.handleFITSFile(files[i], options, handler); } - catch(e){ Fitsy.error("could not load FITS file: " + - files[i].name); } - } - } -}; - - -Fitsy.options = { - maxev: 20480, - gzfilesize: 100 * 1024 * 1024, - gzheapsize: 4 * 1024 * 1024, - xtimeout: 10000, - wtimeout: 100, - table: { nx: 1024, ny: 1024, bin: 1 - , xcol: [ "X", "x" ] - , ycol: [ "Y", "y" ] } -}; - -Fitsy.fetchURL = function(name, url, options, handler) { - var xhr = new XMLHttpRequest(); - - if ( url === undefined ) { - url = name; - name = /([^\\\/]+)$/.exec(url)[1]; - } - options = options || Fitsy.options; - - xhr.open('GET', url, true); - xhr.responseType = 'blob'; - - xhr.onload = function(e) { - var blob; - if ( this.readyState === 4 ) { - if ( this.status === 200 || this.status === 0 ) { - blob = new Blob([this.response]); - blob.name = name; - - if ( options.messages ) { options.messages(""); } - - Fitsy.onFile([blob], options, handler); - } else if( this.status === 404 ) { - Fitsy.error("could not find " + url); - } else { - Fitsy.error("can't load " + url + " (" + this.status + ")"); - } - } - }; - - xhr.onerror = function(e) { - Fitsy.error("can't load " + url); - }; - - xhr.onreadystatechange=function() { - // any response from the server will do - if( xhr.xtimeout ){ - clearTimeout(xhr.xtimeout); - delete xhr.xtimeout; - } - }; - - if ( options.messages ){ - xhr.addEventListener("progress", function(e) { options.messages("progress " + e.loaded.toString()); }); - xhr.addEventListener("error" , function(e) { options.messages("error loading FITS file"); }); - xhr.addEventListener("abort" , function(e) { options.messages("abort while loading FITS file"); }); - } - - try{ xhr.send(); } - catch(e){ Fitsy.error("request to load " + url + " failed", e); } - - // set a timeout to catch when Mac ignores the connect request entirely - xhr.xtimeout=setTimeout(function(){ - Fitsy.error("timeout while waiting for response from server; " + - url + " might not exist"); - }, Fitsy.options.xtimeout); -}; - -Fitsy.handleImageFile = function (file, options, handler) { - if ( options === undefined ) { options = Fitsy.options; } - if ( handler === undefined ) { handler = Fitsy.handler; } - - var reader = new FileReader(); - reader.onload = function ( ev ) { - var img = new Image(); - img.src = ev.target.result; - img.onload = function() { - var x, y, i = 0, brightness; - - var canvas = document.createElement('canvas'); - var ctx = canvas.getContext('2d'); - var h = img.height; - var w = img.width; - - canvas.width = w; - canvas.height = h; - - ctx.drawImage(img, 0, 0); - - var data = ctx.getImageData(0, 0, w, h).data; - var gray = new Float32Array(h*w); - - for ( y = 0; y < h; y++ ) { - for ( x = 0; x < w; x++ ) { - brightness = 0.299 * data[i] + 0.587 * data[i + 1] + 0.114 * data[i + 2]; // NTSC - - gray[(h-y)*w+x] = brightness; - i += 4; - } - } - - var hdu = { head: {}, name: file.name - , filedata: gray, image: gray, naxis: 2, axis: [0, w, h], bitpix: -32 }; - - hdu.dmin = Number.MAX_VALUE; - hdu.dmax = Number.MIN_VALUE; - - for ( i = 0; i < h*w; i++ ) { - hdu.dmin = Math.min(hdu.dmin, hdu.image[i]); - hdu.dmax = Math.max(hdu.dmax, hdu.image[i]); - } - - handler(hdu, options); - }; - }; - reader.readAsDataURL(file); -}; - diff --git a/web/static/js9_old/plugins/fitsy/lzma_worker.js b/web/static/js9_old/plugins/fitsy/lzma_worker.js deleted file mode 100644 index 0720dd3f8418fc247ed490c569f669dda2eca838..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/fitsy/lzma_worker.js +++ /dev/null @@ -1,3934 +0,0 @@ -var LZMA = (function () { - var action_compress = 1, - action_decompress = 2, - action_progress = 3; - - function update_progress(percent, callback_num) { - ///TODO: Calculate ETA. - postMessage({ - action: action_progress, - callback_num: callback_num, - result: percent - }); - } - - var $moduleName, $moduleBase; - - var _, - N8000000000000000_longLit = [0, -9223372036854775808], - N1_longLit = [4294967295, -4294967296], - P0_longLit = [0, 0], - P1_longLit = [1, 0], - P4_longLit = [4, 0], - P1000_longLit = [4096, 0], - Pffffff_longLit = [16777215, 0], - P1000000_longLit = [16777216, 0], - Pff000000_longLit = [4278190080, 0], - Pffffffff_longLit = [4294967295, 0], - P7fffffffffffffff_longLit = [4294967295, 9223372032559808512]; - - function getClass_18() { - return Ljava_lang_Object_2_classLit; - } - - function Object_0() { - } - - _ = Object_0.prototype = {}; - _.getClass$ = getClass_18; - _.typeMarker$ = nullMethod; - _.typeId$ = 1; - function getClass_22() { - return Ljava_lang_Throwable_2_classLit; - } - - function Throwable() { - } - - _ = Throwable.prototype = new Object_0(); - _.getClass$ = getClass_22; - _.typeId$ = 3; - _.detailMessage = null; - function getClass_13() { - return Ljava_lang_Exception_2_classLit; - } - - function Exception() { - } - - _ = Exception.prototype = new Throwable(); - _.getClass$ = getClass_13; - _.typeId$ = 4; - function $RuntimeException(this$static, message) { - this$static.detailMessage = message; - return this$static; - } - - function getClass_19() { - return Ljava_lang_RuntimeException_2_classLit; - } - - function RuntimeException() { - } - - _ = RuntimeException.prototype = new Exception(); - _.getClass$ = getClass_19; - _.typeId$ = 5; - function $JavaScriptException(this$static, e) { - return this$static; - } - - function getClass_0() { - return Lcom_google_gwt_core_client_JavaScriptException_2_classLit; - } - - function JavaScriptException() { - } - - _ = JavaScriptException.prototype = new RuntimeException(); - _.getClass$ = getClass_0; - _.typeId$ = 6; - function $append(a, x) { - a[a.explicitLength++] = x; - } - - function $appendNonNull(a, x) { - a[a.explicitLength++] = x; - } - - function $toString(a) { - var s_0, s; - s_0 = (s = a.join('') , a.length = a.explicitLength = 0 , s); - a[a.explicitLength++] = s_0; - return s_0; - } - - function createFromSeed(seedType, length_0) { - var array = new Array(length_0); - if (seedType > 0) { - var value = [null, 0, false, [0, 0]][seedType]; - for (var i = 0; i < length_0; ++i) { - array[i] = value; - } - } - return array; - } - - function getClass_2() { - return this.arrayClass$; - } - - function initDim(arrayClass, typeId, queryId, length_0, seedType) { - var result; - result = createFromSeed(seedType, length_0); - $clinit_4(); - wrapArray(result, expandoNames_0, expandoValues_0); - result.arrayClass$ = arrayClass; - result.typeId$ = typeId; - result.queryId$ = queryId; - return result; - } - - function initValues(arrayClass, typeId, queryId, array) { - $clinit_4(); - wrapArray(array, expandoNames_0, expandoValues_0); - array.arrayClass$ = arrayClass; - array.typeId$ = typeId; - array.queryId$ = queryId; - return array; - } - - function setCheck(array, index, value) { - if (value != null) { - if (array.queryId$ > 0 && !canCastUnsafe(value.typeId$, array.queryId$)) { - throw new ArrayStoreException(); - } - if (array.queryId$ < 0 && (value.typeMarker$ == nullMethod || value.typeId$ == 2)) { - throw new ArrayStoreException(); - } - } - return array[index] = value; - } - - function Array_0() { - } - - _ = Array_0.prototype = new Object_0(); - _.getClass$ = getClass_2; - _.typeId$ = 0; - _.arrayClass$ = null; - _.length = 0; - _.queryId$ = 0; - function $clinit_4() { - $clinit_4 = nullMethod; - expandoNames_0 = []; - expandoValues_0 = []; - initExpandos(new Array_0(), expandoNames_0, expandoValues_0); - } - - function initExpandos(protoType, expandoNames, expandoValues) { - var i = 0, value; - for (var name_0 in protoType) { - if (value = protoType[name_0]) { - expandoNames[i] = name_0; - expandoValues[i] = value; - ++i; - } - } - } - - function wrapArray(array, expandoNames, expandoValues) { - $clinit_4(); - for (var i = 0, c = expandoNames.length; i < c; ++i) { - array[expandoNames[i]] = expandoValues[i]; - } - } - - var expandoNames_0, expandoValues_0; - function canCast(srcId, dstId) { - return srcId && !!typeIdArray[srcId][dstId]; - } - - function canCastUnsafe(srcId, dstId) { - return srcId && typeIdArray[srcId][dstId]; - } - - function dynamicCast(src, dstId) { - if (src != null && !canCastUnsafe(src.typeId$, dstId)) { - throw new ClassCastException(); - } - return src; - } - - function instanceOf(src, dstId) { - return src != null && canCast(src.typeId$, dstId); - } - - function round_int(x) { - return ~~Math.max(Math.min(x, 2147483647), -2147483648); - } - - var typeIdArray = [ - {}, - {}, - {1:1}, - {2:1}, - {2:1}, - {2:1}, - {2:1}, - {2:1, 10:1}, - {2:1}, - {2:1}, - {2:1}, - {2:1}, - {2:1}, - {2:1, 11:1}, - {2:1}, - {2:1}, - {2:1}, - {4:1}, - {5:1}, - {6:1}, - {7:1}, - {8:1}, - {9:1} - ]; - - function caught(e) { - if (e != null && canCast(e.typeId$, 2)) { - return e; - } - return $JavaScriptException(new JavaScriptException(), e); - } - - function add(a, b) { - var newHigh, newLow; - newHigh = a[1] + b[1]; - newLow = a[0] + b[0]; - return create(newLow, newHigh); - } - - function addTimes(accum, a, b) { - if (a == 0) { - return accum; - } - if (b == 0) { - return accum; - } - return add(accum, create(a * b, 0)); - } - - function and(a, b) { - return makeFromBits(~~Math.max(Math.min(a[1] / 4294967296, 2147483647), -2147483648) & ~~Math.max(Math.min(b[1] / 4294967296, 2147483647), -2147483648), lowBits_0(a) & lowBits_0(b)); - } - - function compare(a, b) { - var nega, negb; - if (a[0] == b[0] && a[1] == b[1]) { - return 0; - } - nega = a[1] < 0; - negb = b[1] < 0; - if (nega && !negb) { - return -1; - } - if (!nega && negb) { - return 1; - } - if (sub(a, b)[1] < 0) { - return -1; - } - else { - return 1; - } - } - - function create(valueLow, valueHigh) { - var diffHigh, diffLow; - valueHigh %= 1.8446744073709552E19; - valueLow %= 1.8446744073709552E19; - diffHigh = valueHigh % 4294967296; - diffLow = Math.floor(valueLow / 4294967296) * 4294967296; - valueHigh = valueHigh - diffHigh + diffLow; - valueLow = valueLow - diffLow + diffHigh; - while (valueLow < 0) { - valueLow += 4294967296; - valueHigh -= 4294967296; - } - while (valueLow > 4294967295) { - valueLow -= 4294967296; - valueHigh += 4294967296; - } - valueHigh = valueHigh % 1.8446744073709552E19; - while (valueHigh > 9223372032559808512) { - valueHigh -= 1.8446744073709552E19; - } - while (valueHigh < -9223372036854775808) { - valueHigh += 1.8446744073709552E19; - } - return [valueLow, valueHigh]; - } - - function div(a, b) { - var approx, deltaRem, deltaResult, halfa, rem, result; - if (b[0] == 0 && b[1] == 0) { - throw $ArithmeticException(new ArithmeticException(), '/ by zero'); - } - if (a[0] == 0 && a[1] == 0) { - return $clinit_10() , ZERO; - } - if (eq(a, ($clinit_10() , MIN_VALUE))) { - if (eq(b, ONE) || eq(b, NEG_ONE)) { - return MIN_VALUE; - } - halfa = shr(a, 1); - approx = shl(div(halfa, b), 1); - rem = sub(a, mul(b, approx)); - return add(approx, div(rem, b)); - } - if (eq(b, MIN_VALUE)) { - return ZERO; - } - if (a[1] < 0) { - if (b[1] < 0) { - return div(neg(a), neg(b)); - } else { - return neg(div(neg(a), b)); - } - } - if (b[1] < 0) { - return neg(div(a, neg(b))); - } - result = ZERO; - rem = a; - while (compare(rem, b) >= 0) { - deltaResult = fromDouble(Math.floor(toDoubleRoundDown(rem) / toDoubleRoundUp(b))); - if (deltaResult[0] == 0 && deltaResult[1] == 0) { - deltaResult = ONE; - } - deltaRem = mul(deltaResult, b); - result = add(result, deltaResult); - rem = sub(rem, deltaRem); - } - return result; - } - - function eq(a, b) { - return a[0] == b[0] && a[1] == b[1]; - } - - function fromDouble(value) { - if (isNaN(value)) { - return $clinit_10() , ZERO; - } - if (value < -9223372036854775808) { - return $clinit_10() , MIN_VALUE; - } - if (value >= 9223372036854775807) { - return $clinit_10() , MAX_VALUE; - } - if (value > 0) { - return create(Math.floor(value), 0); - } else { - return create(Math.ceil(value), 0); - } - } - - function fromInt(value) { - var rebase, result; - if (value > -129 && value < 128) { - rebase = value + 128; - result = ($clinit_9() , boxedValues)[rebase]; - if (result == null) { - result = boxedValues[rebase] = internalFromInt(value); - } - return result; - } - return internalFromInt(value); - } - - function internalFromInt(value) { - if (value >= 0) { - return [value, 0]; - } else { - return [value + 4294967296, -4294967296]; - } - } - - function lowBits_0(a) { - if (a[0] >= 2147483648) { - return ~~Math.max(Math.min(a[0] - 4294967296, 2147483647), -2147483648); - } else { - return ~~Math.max(Math.min(a[0], 2147483647), -2147483648); - } - } - - function makeFromBits(highBits, lowBits) { - var high, low; - high = highBits * 4294967296; - low = lowBits; - if (lowBits < 0) { - low += 4294967296; - } - return [low, high]; - } - - function mul(a, b) { - var a1, a2, a3, a4, b1, b2, b3, b4, res; - if (a[0] == 0 && a[1] == 0) { - return $clinit_10() , ZERO; - } - if (b[0] == 0 && b[1] == 0) { - return $clinit_10() , ZERO; - } - if (eq(a, ($clinit_10() , MIN_VALUE))) { - return multByMinValue(b); - } - if (eq(b, MIN_VALUE)) { - return multByMinValue(a); - } - if (a[1] < 0) { - if (b[1] < 0) { - return mul(neg(a), neg(b)); - } else { - return neg(mul(neg(a), b)); - } - } - if (b[1] < 0) { - return neg(mul(a, neg(b))); - } - if (compare(a, TWO_PWR_24) < 0 && compare(b, TWO_PWR_24) < 0) { - return create((a[1] + a[0]) * (b[1] + b[0]), 0); - } - a3 = a[1] % 281474976710656; - a4 = a[1] - a3; - a1 = a[0] % 65536; - a2 = a[0] - a1; - b3 = b[1] % 281474976710656; - b4 = b[1] - b3; - b1 = b[0] % 65536; - b2 = b[0] - b1; - res = ZERO; - res = addTimes(res, a4, b1); - res = addTimes(res, a3, b2); - res = addTimes(res, a3, b1); - res = addTimes(res, a2, b3); - res = addTimes(res, a2, b2); - res = addTimes(res, a2, b1); - res = addTimes(res, a1, b4); - res = addTimes(res, a1, b3); - res = addTimes(res, a1, b2); - res = addTimes(res, a1, b1); - return res; - } - - function multByMinValue(a) { - if ((lowBits_0(a) & 1) == 1) { - return $clinit_10() , MIN_VALUE; - } else { - return $clinit_10() , ZERO; - } - } - - function neg(a) { - var newHigh, newLow; - if (eq(a, ($clinit_10() , MIN_VALUE))) { - return MIN_VALUE; - } - newHigh = -a[1]; - newLow = -a[0]; - if (newLow > 4294967295) { - newLow -= 4294967296; - newHigh += 4294967296; - } - if (newLow < 0) { - newLow += 4294967296; - newHigh -= 4294967296; - } - return [newLow, newHigh]; - } - - function pwrAsDouble(n) { - if (n <= 30) { - return 1 << n; - } else { - return pwrAsDouble(30) * pwrAsDouble(n - 30); - } - } - - function shl(a, n) { - var diff, newHigh, newLow, twoToN; - n &= 63; - if (eq(a, ($clinit_10() , MIN_VALUE))) { - if (n == 0) { - return a; - } else { - return ZERO; - } - } - if (a[1] < 0) { - return neg(shl(neg(a), n)); - } - twoToN = pwrAsDouble(n); - newHigh = a[1] * twoToN % 1.8446744073709552E19; - newLow = a[0] * twoToN; - diff = newLow - newLow % 4294967296; - newHigh += diff; - newLow -= diff; - if (newHigh >= 9223372036854775807) { - newHigh -= 1.8446744073709552E19; - } - return [newLow, newHigh]; - } - - function shr(a, n) { - var newHigh, newLow, shiftFact; - n &= 63; - shiftFact = pwrAsDouble(n); - newHigh = a[1] / shiftFact; - newLow = Math.floor(a[0] / shiftFact); - return create(newLow, newHigh); - } - - function shru(a, n) { - var sr; - n &= 63; - sr = shr(a, n); - if (a[1] < 0) { - sr = add(sr, shl(($clinit_10() , TWO), 63 - n)); - } - return sr; - } - - function sub(a, b) { - var newHigh, newLow; - newHigh = a[1] - b[1]; - newLow = a[0] - b[0]; - return create(newLow, newHigh); - } - - function toDoubleRoundDown(a) { - var diff, magnitute, toSubtract; - magnitute = round_int(Math.log(a[1]) / ($clinit_10() , LN_2)); - if (magnitute <= 48) { - return a[1] + a[0]; - } else { - diff = magnitute - 48; - toSubtract = (1 << diff) - 1; - return a[1] + (a[0] - toSubtract); - } - } - - function toDoubleRoundUp(a) { - var diff, magnitute, toAdd; - magnitute = round_int(Math.log(a[1]) / ($clinit_10() , LN_2)); - if (magnitute <= 48) { - return a[1] + a[0]; - } else { - diff = magnitute - 48; - toAdd = (1 << diff) - 1; - return a[1] + (a[0] + toAdd); - } - } - - function toString_0(a) { - var digits, rem, remDivTenPower, res, tenPowerLong, zeroesNeeded; - if (a[0] == 0 && a[1] == 0) { - return '0'; - } - if (eq(a, ($clinit_10() , MIN_VALUE))) { - return '-9223372036854775808'; - } - if (a[1] < 0) { - return '-' + toString_0(neg(a)); - } - rem = a; - res = ''; - while (!(rem[0] == 0 && rem[1] == 0)) { - tenPowerLong = fromInt(1000000000); - remDivTenPower = div(rem, tenPowerLong); - digits = '' + lowBits_0(sub(rem, mul(remDivTenPower, tenPowerLong))); - rem = remDivTenPower; - if (!(rem[0] == 0 && rem[1] == 0)) { - zeroesNeeded = 9 - digits.length; - for (; zeroesNeeded > 0; --zeroesNeeded) { - digits = '0' + digits; - } - } - res = digits + res; - } - return res; - } - - function $clinit_9() { - $clinit_9 = nullMethod; - boxedValues = initDim(_3_3D_classLit, 0, 9, 256, 0); - } - - var boxedValues; - function $clinit_10() { - $clinit_10 = nullMethod; - LN_2 = Math.log(2); - MAX_VALUE = P7fffffffffffffff_longLit; - MIN_VALUE = N8000000000000000_longLit; - NEG_ONE = fromInt(-1); - ONE = fromInt(1); - TWO = fromInt(2); - TWO_PWR_24 = P1000000_longLit; - ZERO = fromInt(0); - } - - var LN_2, MAX_VALUE, MIN_VALUE, NEG_ONE, ONE, TWO, TWO_PWR_24, ZERO; - function getClass_6() { - return Ljava_io_InputStream_2_classLit; - } - - function InputStream() { - } - - _ = InputStream.prototype = new Object_0(); - _.getClass$ = getClass_6; - _.typeId$ = 0; - function $ByteArrayInputStream(this$static, buf) { - $ByteArrayInputStream_0(this$static, buf, 0, buf.length); - return this$static; - } - - function $ByteArrayInputStream_0(this$static, buf, off, len) { - this$static.buf = buf; - this$static.pos = off; - this$static.count = off + len; - if (this$static.count > buf.length) - this$static.count = buf.length; - return this$static; - } - - function $read(this$static) { - if (this$static.pos >= this$static.count) - return -1; - return this$static.buf[this$static.pos++] & 255; - } - - function $read_0(this$static, buf, off, len) { - if (this$static.pos >= this$static.count) - return -1; - len = min(len, this$static.count - this$static.pos); - arraycopy(this$static.buf, this$static.pos, buf, off, len); - this$static.pos += len; - return len; - } - - function getClass_3() { - return Ljava_io_ByteArrayInputStream_2_classLit; - } - - function ByteArrayInputStream() { - } - - _ = ByteArrayInputStream.prototype = new InputStream(); - _.getClass$ = getClass_3; - _.typeId$ = 0; - _.buf = null; - _.count = 0; - _.pos = 0; - function getClass_7() { - return Ljava_io_OutputStream_2_classLit; - } - - function OutputStream() { - } - - _ = OutputStream.prototype = new Object_0(); - _.getClass$ = getClass_7; - _.typeId$ = 0; - function $ByteArrayOutputStream(this$static) { - this$static.buf = initDim(_3B_classLit, 0, -1, 32, 1); - return this$static; - } - - function $ensureCapacity(this$static, len) { - var newbuf; - if (len <= this$static.buf.length) - return; - len = max(len, this$static.buf.length * 2); - newbuf = initDim(_3B_classLit, 0, -1, len, 1); - arraycopy(this$static.buf, 0, newbuf, 0, this$static.buf.length); - this$static.buf = newbuf; - } - - function $toByteArray(this$static) { - var data; - data = initDim(_3B_classLit, 0, -1, this$static.count, 1); - arraycopy(this$static.buf, 0, data, 0, this$static.count); - return data; - } - - function $write(this$static, b) { - $ensureCapacity(this$static, this$static.count + 1); - this$static.buf[this$static.count++] = b << 24 >> 24; - } - - function $write_0(this$static, buf, off, len) { - $ensureCapacity(this$static, this$static.count + len); - arraycopy(buf, off, this$static.buf, this$static.count, len); - this$static.count += len; - } - - function getClass_4() { - return Ljava_io_ByteArrayOutputStream_2_classLit; - } - - function ByteArrayOutputStream() { - } - - _ = ByteArrayOutputStream.prototype = new OutputStream(); - _.getClass$ = getClass_4; - _.typeId$ = 0; - _.buf = null; - _.count = 0; - function $IOException(this$static, message) { - this$static.detailMessage = message; - return this$static; - } - - function getClass_5() { - return Ljava_io_IOException_2_classLit; - } - - function IOException() { - } - - _ = IOException.prototype = new Exception(); - _.getClass$ = getClass_5; - _.typeId$ = 7; - function $ArithmeticException(this$static, explanation) { - this$static.detailMessage = explanation; - return this$static; - } - - function getClass_8() { - return Ljava_lang_ArithmeticException_2_classLit; - } - - function ArithmeticException() { - } - - _ = ArithmeticException.prototype = new RuntimeException(); - _.getClass$ = getClass_8; - _.typeId$ = 8; - function $ArrayStoreException(this$static, message) { - this$static.detailMessage = message; - return this$static; - } - - function getClass_9() { - return Ljava_lang_ArrayStoreException_2_classLit; - } - - function ArrayStoreException() { - } - - _ = ArrayStoreException.prototype = new RuntimeException(); - _.getClass$ = getClass_9; - _.typeId$ = 9; - function createForArray(packageName, className) { - var clazz; - clazz = new Class(); - clazz.typeName = packageName + className; - return clazz; - } - - function createForClass(packageName, className) { - var clazz; - clazz = new Class(); - clazz.typeName = packageName + className; - return clazz; - } - - function createForEnum(packageName, className) { - var clazz; - clazz = new Class(); - clazz.typeName = packageName + className; - return clazz; - } - - function getClass_11() { - return Ljava_lang_Class_2_classLit; - } - - function Class() { - } - - _ = Class.prototype = new Object_0(); - _.getClass$ = getClass_11; - _.typeId$ = 0; - _.typeName = null; - function getClass_10() { - return Ljava_lang_ClassCastException_2_classLit; - } - - function ClassCastException() { - } - - _ = ClassCastException.prototype = new RuntimeException(); - _.getClass$ = getClass_10; - _.typeId$ = 12; - function getClass_12() { - return Ljava_lang_Enum_2_classLit; - } - - function Enum() { - } - - _ = Enum.prototype = new Object_0(); - _.getClass$ = getClass_12; - _.typeId$ = 0; - function $IllegalArgumentException(this$static, message) { - this$static.detailMessage = message; - return this$static; - } - - function getClass_14() { - return Ljava_lang_IllegalArgumentException_2_classLit; - } - - function IllegalArgumentException() { - } - - _ = IllegalArgumentException.prototype = new RuntimeException(); - _.getClass$ = getClass_14; - _.typeId$ = 13; - function getClass_15() { - return Ljava_lang_IllegalStateException_2_classLit; - } - - function IllegalStateException() { - } - - _ = IllegalStateException.prototype = new RuntimeException(); - _.getClass$ = getClass_15; - _.typeId$ = 14; - function getClass_16() { - return Ljava_lang_IndexOutOfBoundsException_2_classLit; - } - - function IndexOutOfBoundsException() { - } - - _ = IndexOutOfBoundsException.prototype = new RuntimeException(); - _.getClass$ = getClass_16; - _.typeId$ = 15; - function max(x, y) { - return x > y?x:y; - } - - function min(x, y) { - return x < y?x:y; - } - - function getClass_17() { - return Ljava_lang_NullPointerException_2_classLit; - } - - function NullPointerException() { - } - - _ = NullPointerException.prototype = new RuntimeException(); - _.getClass$ = getClass_17; - _.typeId$ = 16; - function $equals(this$static, other) { - if (other == null) { - return false; - } - return String(this$static) == other; - } - - function $getChars(this$static, srcBegin, srcEnd, dst, dstBegin) { - var srcIdx; - for (srcIdx = srcBegin; srcIdx < srcEnd; ++srcIdx) { - dst[dstBegin++] = this$static.charCodeAt(srcIdx); - } - } - - function getClass_21() { - return Ljava_lang_String_2_classLit; - } - - _ = String.prototype; - _.getClass$ = getClass_21; - _.typeId$ = 2; - function $StringBuilder(this$static) { - var array; - this$static.data = (array = [] , array.explicitLength = 0 , array); - return this$static; - } - - function getClass_20() { - return Ljava_lang_StringBuilder_2_classLit; - } - - function StringBuilder() { - } - - _ = StringBuilder.prototype = new Object_0(); - _.getClass$ = getClass_20; - _.typeId$ = 0; - function arraycopy(src, srcOfs, dest, destOfs, len) { - var destArray, destEnd, destTypeName, destlen, i, srcArray, srcTypeName, srclen; - - if (src == null || dest == null) { - throw new NullPointerException(); - } - - srcTypeName = (src.typeMarker$ == nullMethod || src.typeId$ == 2 ? src.getClass$() : Lcom_google_gwt_core_client_JavaScriptObject_2_classLit).typeName; - destTypeName = (dest.typeMarker$ == nullMethod || dest.typeId$ == 2 ? dest.getClass$() : Lcom_google_gwt_core_client_JavaScriptObject_2_classLit).typeName; - - if (srcTypeName.charCodeAt(0) != 91 || destTypeName.charCodeAt(0) != 91) { - throw $ArrayStoreException(new ArrayStoreException(), 'Must be array types'); - } - if (srcTypeName.charCodeAt(1) != destTypeName.charCodeAt(1)) { - throw $ArrayStoreException(new ArrayStoreException(), 'Array types must match'); - } - - srclen = src.length; - destlen = dest.length; - if (srcOfs < 0 || destOfs < 0 || len < 0 || srcOfs + len > srclen || destOfs + len > destlen) { - throw new IndexOutOfBoundsException(); - } - if ((srcTypeName.charCodeAt(1) == 76 || srcTypeName.charCodeAt(1) == 91) && !$equals(srcTypeName, destTypeName)) { - srcArray = dynamicCast(src, 3); - destArray = dynamicCast(dest, 3); - if ((src == null ? null : src) === (dest == null ? null : dest) && srcOfs < destOfs) { - srcOfs += len; - for (destEnd = destOfs + len; destEnd-- > destOfs;) { - setCheck(destArray, destEnd, srcArray[--srcOfs]); - } - } else { - for (destEnd = destOfs + len; destOfs < destEnd;) { - setCheck(destArray, destOfs++, srcArray[srcOfs++]); - } - } - } else { - for (i = 0; i < len; ++i) { - dest[destOfs + i] = src[srcOfs + i] - } - } - } - - - function $configure(this$static, encoder) { - if (!$SetDictionarySize_0(encoder, 1 << this$static.dictionarySize)) - throw $RuntimeException(new RuntimeException(), 'unexpected failure'); - if (!$SetNumFastBytes(encoder, this$static.fb)) - throw $RuntimeException(new RuntimeException(), 'unexpected failure'); - if (!$SetMatchFinder(encoder, this$static.matchFinder)) - throw $RuntimeException(new RuntimeException(), 'unexpected failure'); - if (!$SetLcLpPb_0(encoder, this$static.lc, this$static.lp, this$static.pb)) - throw $RuntimeException(new RuntimeException(), 'unexpected failure'); - } - - function getClass_23() { - return Lorg_dellroad_lzma_client_CompressionMode_2_classLit; - } - - function CompressionMode() { - } - - _ = CompressionMode.prototype = new Enum(); - _.getClass$ = getClass_23; - _.typeId$ = 0; - _.dictionarySize = 0; - _.fb = 0; - _.lc = 0; - _.lp = 0; - _.matchFinder = 0; - _.pb = 0; - - function $execute(this$static) { - var $e0; - try { - return $processChunk(this$static.chunker); - } - catch ($e0) { - $e0 = caught($e0); - if (instanceOf($e0, 10)) { - return false; - } else { - throw $e0; - } - } - } - - function $init(this$static, input, output, length_0, mode) { - var encoder, i; - if (!mode) - throw $IllegalArgumentException(new IllegalArgumentException(), 'null mode'); - if (compare(length_0, N1_longLit) < 0) - throw $IllegalArgumentException(new IllegalArgumentException(), 'invalid length ' + toString_0(length_0)); - this$static.length_0 = length_0; - encoder = $Encoder(new Encoder()); - $configure(mode, encoder); - encoder._writeEndMark = true; - $WriteCoderProperties(encoder, output); - for (i = 0; i < 64; i += 8) - $write(output, lowBits_0(shr(length_0, i)) & 255); - this$static.chunker = (encoder._needReleaseMFStream = false , (encoder._inStream = input , encoder._finished = false , $Create_2(encoder) , encoder._rangeEncoder.Stream = output , $Init_4(encoder) , $FillDistancesPrices(encoder) , $FillAlignPrices(encoder) , encoder._lenEncoder._tableSize = encoder._numFastBytes + 1 - 2 , $UpdateTables(encoder._lenEncoder, 1 << encoder._posStateBits) , encoder._repMatchLenEncoder._tableSize = encoder._numFastBytes + 1 - 2 , $UpdateTables(encoder._repMatchLenEncoder, 1 << encoder._posStateBits) , encoder.nowPos64 = P0_longLit , undefined) , $Chunker_0(new Chunker(), encoder)); - } - - function getClass_26() { - return Lorg_dellroad_lzma_client_LZMACompressor_2_classLit; - } - - function LZMACompressor() { - } - - _ = LZMACompressor.prototype = new Object_0(); - _.getClass$ = getClass_26; - _.typeId$ = 0; - _.chunker = null; - - function $LZMAByteArrayCompressor(this$static, data, mode) { - var $e0; - this$static.output = $ByteArrayOutputStream(new ByteArrayOutputStream()); - try { - $init(this$static, $ByteArrayInputStream(new ByteArrayInputStream(), data), this$static.output, fromInt(data.length), mode); - } catch ($e0) { - $e0 = caught($e0); - if (instanceOf($e0, 10)) { - throw $RuntimeException(new RuntimeException(), 'impossible exception'); - } else { - throw $e0; - } - } - return this$static; - } - - function getClass_24() { - return Lorg_dellroad_lzma_client_LZMAByteArrayCompressor_2_classLit; - } - - function LZMAByteArrayCompressor() { - } - - _ = LZMAByteArrayCompressor.prototype = new LZMACompressor(); - _.getClass$ = getClass_24; - _.typeId$ = 0; - _.output = null; - function $execute_0(this$static) { - var $e0, e; - try { - return $processChunk(this$static.chunker); - } - catch ($e0) { - $e0 = caught($e0); - if (instanceOf($e0, 10)) { - e = $e0; - this$static.exception = e; - return false; - } else { - throw $e0; - } - } - } - - function $init_0(this$static, input, output) { - var decoder, - hex_length = "", - i, - properties, - r, - tmp_length; - - properties = initDim(_3B_classLit, 0, -1, 5, 1); - for (i = 0; i < properties.length; ++i) { - r = $read(input); - if (r == -1) - throw $IOException(new IOException(), 'truncated input'); - properties[i] = r << 24 >> 24; - } - decoder = $Decoder(new Decoder()); - if (!$SetDecoderProperties(decoder, properties)) - throw $IOException(new IOException(), 'corrupted input'); - - for (i = 0; i < 64; i += 8) { - r = $read(input); - if (r == -1) - throw $IOException(new IOException(), 'truncated input'); - r = r.toString(16); - if (r.length == 1) r = "0" + r; - hex_length = r + "" + hex_length; - } - - /// Was the length set in the header (if it was compressed from a stream, the length is all f's). - if (/^0+$|^f+$/i.test(hex_length)) { - /// The length is unknown, so set to -1. - this$static.length_0 = N1_longLit; - } else { - ///NOTE: If there is a problem with the decoder because of the length, you can always set the length to -1 (N1_longLit) which means unknown. - tmp_length = parseInt(hex_length, 16); - /// If the length is too long to handle, just set it to unknown. - if (tmp_length > 4294967295) { - this$static.length_0 = N1_longLit; - } else { - this$static.length_0 = fromDouble(tmp_length); - } - } - - this$static.chunker = $CodeInChunks(decoder, input, output, this$static.length_0); - } - - function getClass_27() { - return Lorg_dellroad_lzma_client_LZMADecompressor_2_classLit; - } - - function LZMADecompressor() { - } - - _ = LZMADecompressor.prototype = new Object_0(); - _.getClass$ = getClass_27; - _.typeId$ = 0; - _.chunker = null; - _.exception = null; - _.length_0 = P0_longLit; - function $LZMAByteArrayDecompressor(this$static, data) { - this$static.output = $ByteArrayOutputStream(new ByteArrayOutputStream()); - $init_0(this$static, $ByteArrayInputStream(new ByteArrayInputStream(), data), this$static.output); - return this$static; - } - - function getClass_25() { - return Lorg_dellroad_lzma_client_LZMAByteArrayDecompressor_2_classLit; - } - - function LZMAByteArrayDecompressor() { - } - - _ = LZMAByteArrayDecompressor.prototype = new LZMADecompressor(); - _.getClass$ = getClass_25; - _.typeId$ = 0; - _.output = null; - function $Create_4(this$static, keepSizeBefore, keepSizeAfter, keepSizeReserv) { - var blockSize; - this$static._keepSizeBefore = keepSizeBefore; - this$static._keepSizeAfter = keepSizeAfter; - blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv; - if (this$static._bufferBase == null || this$static._blockSize != blockSize) { - this$static._bufferBase = null; - this$static._blockSize = blockSize; - this$static._bufferBase = initDim(_3B_classLit, 0, -1, this$static._blockSize, 1); - } - this$static._pointerToLastSafePosition = this$static._blockSize - keepSizeAfter; - } - - function $GetIndexByte(this$static, index) { - return this$static._bufferBase[this$static._bufferOffset + this$static._pos + index]; - } - - function $GetMatchLen(this$static, index, distance, limit) { - var i, pby; - if (this$static._streamEndWasReached) { - if (this$static._pos + index + limit > this$static._streamPos) { - limit = this$static._streamPos - (this$static._pos + index); - } - } - ++distance; - pby = this$static._bufferOffset + this$static._pos + index; - for (i = 0; i < limit && this$static._bufferBase[pby + i] == this$static._bufferBase[pby + i - distance]; ++i) { - } - return i; - } - - function $GetNumAvailableBytes(this$static) { - return this$static._streamPos - this$static._pos; - } - - function $MoveBlock(this$static) { - var i, numBytes, offset; - offset = this$static._bufferOffset + this$static._pos - this$static._keepSizeBefore; - if (offset > 0) { - --offset; - } - numBytes = this$static._bufferOffset + this$static._streamPos - offset; - for (i = 0; i < numBytes; ++i) { - this$static._bufferBase[i] = this$static._bufferBase[offset + i]; - } - this$static._bufferOffset -= offset; - } - - function $MovePos_1(this$static) { - var pointerToPostion; - ++this$static._pos; - if (this$static._pos > this$static._posLimit) { - pointerToPostion = this$static._bufferOffset + this$static._pos; - if (pointerToPostion > this$static._pointerToLastSafePosition) { - $MoveBlock(this$static); - } - $ReadBlock(this$static); - } - } - - function $ReadBlock(this$static) { - var numReadBytes, pointerToPostion, size; - if (this$static._streamEndWasReached) - return; - while (true) { - size = -this$static._bufferOffset + this$static._blockSize - this$static._streamPos; - if (size == 0) - return; - numReadBytes = $read_0(this$static._stream, this$static._bufferBase, this$static._bufferOffset + this$static._streamPos, size); - if (numReadBytes == -1) { - this$static._posLimit = this$static._streamPos; - pointerToPostion = this$static._bufferOffset + this$static._posLimit; - if (pointerToPostion > this$static._pointerToLastSafePosition) { - this$static._posLimit = this$static._pointerToLastSafePosition - this$static._bufferOffset; - } - this$static._streamEndWasReached = true; - return; - } - this$static._streamPos += numReadBytes; - if (this$static._streamPos >= this$static._pos + this$static._keepSizeAfter) { - this$static._posLimit = this$static._streamPos - this$static._keepSizeAfter; - } - } - } - - function $ReduceOffsets(this$static, subValue) { - this$static._bufferOffset += subValue; - this$static._posLimit -= subValue; - this$static._pos -= subValue; - this$static._streamPos -= subValue; - } - - function getClass_40() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_LZ_InWindow_2_classLit; - } - - function InWindow() { - } - - _ = InWindow.prototype = new Object_0(); - _.getClass$ = getClass_40; - _.typeId$ = 0; - _._blockSize = 0; - _._bufferBase = null; - _._bufferOffset = 0; - _._keepSizeAfter = 0; - _._keepSizeBefore = 0; - _._pointerToLastSafePosition = 0; - _._pos = 0; - _._posLimit = 0; - _._stream = null; - _._streamEndWasReached = false; - _._streamPos = 0; - function $clinit_60() { - $clinit_60 = nullMethod; - var i, j, r; - CrcTable = initDim(_3I_classLit, 0, -1, 256, 1); - for (i = 0; i < 256; ++i) { - r = i; - for (j = 0; j < 8; ++j) - if ((r & 1) != 0) { - r = r >>> 1 ^ -306674912; - } else { - r >>>= 1; - } - CrcTable[i] = r; - } - } - - function $Create_3(this$static, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter) { - var cyclicBufferSize, hs, windowReservSize; - if (historySize > 1073741567) { - return false; - } - - this$static._cutValue = 16 + (matchMaxLen >> 1); - windowReservSize = ~~((historySize + keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2) + 256; - $Create_4(this$static, historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize); - this$static._matchMaxLen = matchMaxLen; - cyclicBufferSize = historySize + 1; - if (this$static._cyclicBufferSize != cyclicBufferSize) { - this$static._son = initDim(_3I_classLit, 0, -1, (this$static._cyclicBufferSize = cyclicBufferSize) * 2, 1); - } - - hs = 65536; - if (this$static.HASH_ARRAY) { - hs = historySize - 1; - hs |= hs >> 1; - hs |= hs >> 2; - hs |= hs >> 4; - hs |= hs >> 8; - hs >>= 1; - hs |= 65535; - if (hs > 16777216) - hs >>= 1; - this$static._hashMask = hs; - ++hs; - hs += this$static.kFixHashSize; - } - - if (hs != this$static._hashSizeSum) { - this$static._hash = initDim(_3I_classLit, 0, -1, this$static._hashSizeSum = hs, 1); - } - return true; - } - - function $GetMatches(this$static, distances) { - var count, cur, curMatch, curMatch2, curMatch3, cyclicPos, delta, hash2Value, hash3Value, hashValue, len, len0, len1, lenLimit, matchMinPos, maxLen, offset, pby1, ptr0, ptr1, temp; - if (this$static._pos + this$static._matchMaxLen <= this$static._streamPos) { - lenLimit = this$static._matchMaxLen; - } else { - lenLimit = this$static._streamPos - this$static._pos; - if (lenLimit < this$static.kMinMatchCheck) { - $MovePos_0(this$static); - return 0; - } - } - offset = 0; - matchMinPos = this$static._pos > this$static._cyclicBufferSize?this$static._pos - this$static._cyclicBufferSize:0; - cur = this$static._bufferOffset + this$static._pos; - maxLen = 1; - hash2Value = 0; - hash3Value = 0; - if (this$static.HASH_ARRAY) { - temp = CrcTable[this$static._bufferBase[cur] & 255] ^ this$static._bufferBase[cur + 1] & 255; - hash2Value = temp & 1023; - temp ^= (this$static._bufferBase[cur + 2] & 255) << 8; - hash3Value = temp & 65535; - hashValue = (temp ^ CrcTable[this$static._bufferBase[cur + 3] & 255] << 5) & this$static._hashMask; - } else { - hashValue = this$static._bufferBase[cur] & 255 ^ (this$static._bufferBase[cur + 1] & 255) << 8; - } - - curMatch = this$static._hash[this$static.kFixHashSize + hashValue]; - if (this$static.HASH_ARRAY) { - curMatch2 = this$static._hash[hash2Value]; - curMatch3 = this$static._hash[1024 + hash3Value]; - this$static._hash[hash2Value] = this$static._pos; - this$static._hash[1024 + hash3Value] = this$static._pos; - if (curMatch2 > matchMinPos) { - if (this$static._bufferBase[this$static._bufferOffset + curMatch2] == this$static._bufferBase[cur]) { - distances[offset++] = maxLen = 2; - distances[offset++] = this$static._pos - curMatch2 - 1; - } - } - if (curMatch3 > matchMinPos) { - if (this$static._bufferBase[this$static._bufferOffset + curMatch3] == this$static._bufferBase[cur]) { - if (curMatch3 == curMatch2) { - offset -= 2; - } - distances[offset++] = maxLen = 3; - distances[offset++] = this$static._pos - curMatch3 - 1; - curMatch2 = curMatch3; - } - } - if (offset != 0 && curMatch2 == curMatch) { - offset -= 2; - maxLen = 1; - } - } - this$static._hash[this$static.kFixHashSize + hashValue] = this$static._pos; - ptr0 = (this$static._cyclicBufferPos << 1) + 1; - ptr1 = this$static._cyclicBufferPos << 1; - len0 = len1 = this$static.kNumHashDirectBytes; - if (this$static.kNumHashDirectBytes != 0) { - if (curMatch > matchMinPos) { - if (this$static._bufferBase[this$static._bufferOffset + curMatch + this$static.kNumHashDirectBytes] != this$static._bufferBase[cur + this$static.kNumHashDirectBytes]) { - distances[offset++] = maxLen = this$static.kNumHashDirectBytes; - distances[offset++] = this$static._pos - curMatch - 1; - } - } - } - count = this$static._cutValue; - while (true) { - if (curMatch <= matchMinPos || count-- == 0) { - this$static._son[ptr0] = this$static._son[ptr1] = 0; - break; - } - delta = this$static._pos - curMatch; - cyclicPos = (delta <= this$static._cyclicBufferPos?this$static._cyclicBufferPos - delta:this$static._cyclicBufferPos - delta + this$static._cyclicBufferSize) << 1; - pby1 = this$static._bufferOffset + curMatch; - len = len0 < len1?len0:len1; - if (this$static._bufferBase[pby1 + len] == this$static._bufferBase[cur + len]) { - while (++len != lenLimit) { - if (this$static._bufferBase[pby1 + len] != this$static._bufferBase[cur + len]) { - break; - } - } - if (maxLen < len) { - distances[offset++] = maxLen = len; - distances[offset++] = delta - 1; - if (len == lenLimit) { - this$static._son[ptr1] = this$static._son[cyclicPos]; - this$static._son[ptr0] = this$static._son[cyclicPos + 1]; - break; - } - } - } - if ((this$static._bufferBase[pby1 + len] & 255) < (this$static._bufferBase[cur + len] & 255)) { - this$static._son[ptr1] = curMatch; - ptr1 = cyclicPos + 1; - curMatch = this$static._son[ptr1]; - len1 = len; - } else { - this$static._son[ptr0] = curMatch; - ptr0 = cyclicPos; - curMatch = this$static._son[ptr0]; - len0 = len; - } - } - $MovePos_0(this$static); - return offset; - } - - function $Init_5(this$static) { - var i; - this$static._bufferOffset = 0; - this$static._pos = 0; - this$static._streamPos = 0; - this$static._streamEndWasReached = false; - $ReadBlock(this$static); - for (i = 0; i < this$static._hashSizeSum; ++i) { - this$static._hash[i] = 0; - } - this$static._cyclicBufferPos = 0; - $ReduceOffsets(this$static, -1); - } - - function $MovePos_0(this$static) { - var subValue; - if (++this$static._cyclicBufferPos >= this$static._cyclicBufferSize) { - this$static._cyclicBufferPos = 0; - } - $MovePos_1(this$static); - if (this$static._pos == 1073741823) { - subValue = this$static._pos - this$static._cyclicBufferSize; - $NormalizeLinks(this$static._son, this$static._cyclicBufferSize * 2, subValue); - $NormalizeLinks(this$static._hash, this$static._hashSizeSum, subValue); - $ReduceOffsets(this$static, subValue); - } - } - - function $NormalizeLinks(items, numItems, subValue) { - var i, value; - for (i = 0; i < numItems; ++i) { - value = items[i]; - if (value <= subValue) { - value = 0; - } else { - value -= subValue; - } - items[i] = value; - } - } - - function $SetType(this$static, numHashBytes) { - this$static.HASH_ARRAY = numHashBytes > 2; - if (this$static.HASH_ARRAY) { - this$static.kNumHashDirectBytes = 0; - this$static.kMinMatchCheck = 4; - this$static.kFixHashSize = 66560; - } else { - this$static.kNumHashDirectBytes = 2; - this$static.kMinMatchCheck = 3; - this$static.kFixHashSize = 0; - } - } - - function $Skip(this$static, num) { - var count, cur, curMatch, cyclicPos, delta, hash2Value, hash3Value, hashValue, len, len0, len1, lenLimit, matchMinPos, pby1, ptr0, ptr1, temp; - do { - if (this$static._pos + this$static._matchMaxLen <= this$static._streamPos) { - lenLimit = this$static._matchMaxLen; - } else { - lenLimit = this$static._streamPos - this$static._pos; - if (lenLimit < this$static.kMinMatchCheck) { - $MovePos_0(this$static); - continue; - } - } - matchMinPos = this$static._pos > this$static._cyclicBufferSize?this$static._pos - this$static._cyclicBufferSize:0; - cur = this$static._bufferOffset + this$static._pos; - if (this$static.HASH_ARRAY) { - temp = CrcTable[this$static._bufferBase[cur] & 255] ^ this$static._bufferBase[cur + 1] & 255; - hash2Value = temp & 1023; - this$static._hash[hash2Value] = this$static._pos; - temp ^= (this$static._bufferBase[cur + 2] & 255) << 8; - hash3Value = temp & 65535; - this$static._hash[1024 + hash3Value] = this$static._pos; - hashValue = (temp ^ CrcTable[this$static._bufferBase[cur + 3] & 255] << 5) & this$static._hashMask; - } else { - hashValue = this$static._bufferBase[cur] & 255 ^ (this$static._bufferBase[cur + 1] & 255) << 8; - } - curMatch = this$static._hash[this$static.kFixHashSize + hashValue]; - this$static._hash[this$static.kFixHashSize + hashValue] = this$static._pos; - ptr0 = (this$static._cyclicBufferPos << 1) + 1; - ptr1 = this$static._cyclicBufferPos << 1; - len0 = len1 = this$static.kNumHashDirectBytes; - count = this$static._cutValue; - while (true) { - if (curMatch <= matchMinPos || count-- == 0) { - this$static._son[ptr0] = this$static._son[ptr1] = 0; - break; - } - delta = this$static._pos - curMatch; - cyclicPos = (delta <= this$static._cyclicBufferPos?this$static._cyclicBufferPos - delta:this$static._cyclicBufferPos - delta + this$static._cyclicBufferSize) << 1; - pby1 = this$static._bufferOffset + curMatch; - len = len0 < len1?len0:len1; - if (this$static._bufferBase[pby1 + len] == this$static._bufferBase[cur + len]) { - while (++len != lenLimit) { - if (this$static._bufferBase[pby1 + len] != this$static._bufferBase[cur + len]) { - break; - } - } - if (len == lenLimit) { - this$static._son[ptr1] = this$static._son[cyclicPos]; - this$static._son[ptr0] = this$static._son[cyclicPos + 1]; - break; - } - } - if ((this$static._bufferBase[pby1 + len] & 255) < (this$static._bufferBase[cur + len] & 255)) { - this$static._son[ptr1] = curMatch; - ptr1 = cyclicPos + 1; - curMatch = this$static._son[ptr1]; - len1 = len; - } else { - this$static._son[ptr0] = curMatch; - ptr0 = cyclicPos; - curMatch = this$static._son[ptr0]; - len0 = len; - } - } - $MovePos_0(this$static); - } - while (--num != 0); - } - - function getClass_39() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_LZ_BinTree_2_classLit; - } - - function BinTree() { - } - - _ = BinTree.prototype = new InWindow(); - _.getClass$ = getClass_39; - _.typeId$ = 0; - _.HASH_ARRAY = true; - _._cutValue = 255; - _._cyclicBufferPos = 0; - _._cyclicBufferSize = 0; - _._hash = null; - _._hashMask = 0; - _._hashSizeSum = 0; - _._matchMaxLen = 0; - _._son = null; - _.kFixHashSize = 66560; - _.kMinMatchCheck = 4; - _.kNumHashDirectBytes = 0; - var CrcTable; - function $CopyBlock(this$static, distance, len) { - var pos; - pos = this$static._pos - distance - 1; - if (pos < 0) { - pos += this$static._windowSize; - } - for (; len != 0; --len) { - if (pos >= this$static._windowSize) { - pos = 0; - } - this$static._buffer[this$static._pos++] = this$static._buffer[pos++]; - if (this$static._pos >= this$static._windowSize) { - $Flush_0(this$static); - } - } - } - - function $Create_5(this$static, windowSize) { - if (this$static._buffer == null || this$static._windowSize != windowSize) { - this$static._buffer = initDim(_3B_classLit, 0, -1, windowSize, 1); - } - this$static._windowSize = windowSize; - this$static._pos = 0; - this$static._streamPos = 0; - } - - function $Flush_0(this$static) { - var size; - size = this$static._pos - this$static._streamPos; - if (size == 0) { - return; - } - $write_0(this$static._stream, this$static._buffer, this$static._streamPos, size); - if (this$static._pos >= this$static._windowSize) { - this$static._pos = 0; - } - this$static._streamPos = this$static._pos; - } - - function $GetByte(this$static, distance) { - var pos; - pos = this$static._pos - distance - 1; - if (pos < 0) { - pos += this$static._windowSize; - } - return this$static._buffer[pos]; - } - - function $Init_7(this$static, solid) { - if (!solid) { - this$static._streamPos = 0; - this$static._pos = 0; - } - } - - function $PutByte(this$static, b) { - this$static._buffer[this$static._pos++] = b; - if (this$static._pos >= this$static._windowSize) { - $Flush_0(this$static); - } - } - - function $ReleaseStream(this$static) { - $Flush_0(this$static); - this$static._stream = null; - } - - function $SetStream_0(this$static, stream) { - $Flush_0(this$static); - this$static._stream = null; - this$static._stream = stream; - } - - function getClass_41() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_LZ_OutWindow_2_classLit; - } - - function OutWindow() { - } - - _ = OutWindow.prototype = new Object_0(); - _.getClass$ = getClass_41; - _.typeId$ = 0; - _._buffer = null; - _._pos = 0; - _._stream = null; - _._streamPos = 0; - _._windowSize = 0; - function GetLenToPosState(len) { - len -= 2; - if (len < 4) { - return len; - } - return 3; - } - - function StateUpdateChar(index) { - if (index < 4) { - return 0; - } - if (index < 10) { - return index - 3; - } - return index - 6; - } - - function $Chunker_0(this$static, encoder) { - this$static.encoder = encoder; - this$static.decoder = null; - this$static.alive = true; - return this$static; - } - - function $Chunker(this$static, decoder) { - this$static.decoder = decoder; - this$static.encoder = null; - this$static.alive = true; - return this$static; - } - - function $processChunk(this$static) { - var exception; - if (!this$static.alive) { - throw new IllegalStateException(); - } - exception = true; - try { - if (this$static.encoder) { - $processEncoderChunk(this$static); - } else { - $processDecoderChunk(this$static); - } - exception = false; - return this$static.alive; - } finally { - if (exception) { - this$static.alive = false; - } - } - } - - function $processDecoderChunk(this$static) { - var result; - result = $CodeOneChunk(this$static.decoder); - if (result == -1) { - throw $IOException(new IOException(), 'corrupted input'); - } - this$static.inBytesProcessed = N1_longLit; - this$static.outBytesProcessed = this$static.decoder.nowPos64; - if (result == 1 || compare(this$static.decoder.outSize, P0_longLit) >= 0 && compare(this$static.decoder.nowPos64, this$static.decoder.outSize) >= 0) { - $CodeFinish(this$static.decoder); - this$static.alive = false; - } - } - - function $processEncoderChunk(this$static) { - $CodeOneBlock(this$static.encoder, this$static.encoder.processedInSize, this$static.encoder.processedOutSize, this$static.encoder.finished); - this$static.inBytesProcessed = this$static.encoder.processedInSize[0]; - if (this$static.encoder.finished[0]) { - $ReleaseStreams(this$static.encoder); - this$static.alive = false; - } - } - - function getClass_28() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Chunker_2_classLit; - } - - function Chunker() { - } - - _ = Chunker.prototype = new Object_0(); - _.getClass$ = getClass_28; - _.typeId$ = 0; - _.alive = false; - _.decoder = null; - _.encoder = null; - function $CodeFinish(this$static) { - $Flush_0(this$static.m_OutWindow); - $ReleaseStream(this$static.m_OutWindow); - this$static.m_RangeDecoder.Stream = null; - } - - function $CodeInChunks(this$static, inStream, outStream, outSize) { - this$static.m_RangeDecoder.Stream = inStream; - $SetStream_0(this$static.m_OutWindow, outStream); - $Init_1(this$static); - this$static.state = 0; - this$static.rep0 = 0; - this$static.rep1 = 0; - this$static.rep2 = 0; - this$static.rep3 = 0; - this$static.outSize = outSize; - this$static.nowPos64 = P0_longLit; - this$static.prevByte = 0; - return $Chunker(new Chunker(), this$static); - } - - function $CodeOneChunk(this$static) { - var decoder2, distance, len, numDirectBits, posSlot, posState; - posState = lowBits_0(this$static.nowPos64) & this$static.m_PosStateMask; - if ($DecodeBit(this$static.m_RangeDecoder, this$static.m_IsMatchDecoders, (this$static.state << 4) + posState) == 0) { - decoder2 = $GetDecoder(this$static.m_LiteralDecoder, lowBits_0(this$static.nowPos64), this$static.prevByte); - if (this$static.state < 7) { - this$static.prevByte = $DecodeNormal(decoder2, this$static.m_RangeDecoder); - } - else { - this$static.prevByte = $DecodeWithMatchByte(decoder2, this$static.m_RangeDecoder, $GetByte(this$static.m_OutWindow, this$static.rep0)); - } - $PutByte(this$static.m_OutWindow, this$static.prevByte); - this$static.state = StateUpdateChar(this$static.state); - this$static.nowPos64 = add(this$static.nowPos64, P1_longLit); - } else { - if ($DecodeBit(this$static.m_RangeDecoder, this$static.m_IsRepDecoders, this$static.state) == 1) { - len = 0; - if ($DecodeBit(this$static.m_RangeDecoder, this$static.m_IsRepG0Decoders, this$static.state) == 0) { - if ($DecodeBit(this$static.m_RangeDecoder, this$static.m_IsRep0LongDecoders, (this$static.state << 4) + posState) == 0) { - this$static.state = this$static.state < 7?9:11; - len = 1; - } - } else { - if ($DecodeBit(this$static.m_RangeDecoder, this$static.m_IsRepG1Decoders, this$static.state) == 0) { - distance = this$static.rep1; - } else { - if ($DecodeBit(this$static.m_RangeDecoder, this$static.m_IsRepG2Decoders, this$static.state) == 0) { - distance = this$static.rep2; - } else { - distance = this$static.rep3; - this$static.rep3 = this$static.rep2; - } - this$static.rep2 = this$static.rep1; - } - this$static.rep1 = this$static.rep0; - this$static.rep0 = distance; - } - if (len == 0) { - len = $Decode(this$static.m_RepLenDecoder, this$static.m_RangeDecoder, posState) + 2; - this$static.state = this$static.state < 7?8:11; - } - } else { - this$static.rep3 = this$static.rep2; - this$static.rep2 = this$static.rep1; - this$static.rep1 = this$static.rep0; - len = 2 + $Decode(this$static.m_LenDecoder, this$static.m_RangeDecoder, posState); - this$static.state = this$static.state < 7?7:10; - posSlot = $Decode_0(this$static.m_PosSlotDecoder[GetLenToPosState(len)], this$static.m_RangeDecoder); - if (posSlot >= 4) { - numDirectBits = (posSlot >> 1) - 1; - this$static.rep0 = (2 | posSlot & 1) << numDirectBits; - if (posSlot < 14) { - this$static.rep0 += ReverseDecode(this$static.m_PosDecoders, this$static.rep0 - posSlot - 1, this$static.m_RangeDecoder, numDirectBits); - } else { - this$static.rep0 += $DecodeDirectBits(this$static.m_RangeDecoder, numDirectBits - 4) << 4; - this$static.rep0 += $ReverseDecode(this$static.m_PosAlignDecoder, this$static.m_RangeDecoder); - if (this$static.rep0 < 0) { - if (this$static.rep0 == -1) { - return 1; - } - return -1; - } - } - } else - this$static.rep0 = posSlot; - } - if (compare(fromInt(this$static.rep0), this$static.nowPos64) >= 0 || this$static.rep0 >= this$static.m_DictionarySizeCheck) { - return -1; - } - $CopyBlock(this$static.m_OutWindow, this$static.rep0, len); - this$static.nowPos64 = add(this$static.nowPos64, fromInt(len)); - this$static.prevByte = $GetByte(this$static.m_OutWindow, 0); - } - return 0; - } - - function $Decoder(this$static) { - var i; - this$static.m_OutWindow = new OutWindow(); - this$static.m_RangeDecoder = new Decoder_0(); - this$static.m_IsMatchDecoders = initDim(_3S_classLit, 0, -1, 192, 1); - this$static.m_IsRepDecoders = initDim(_3S_classLit, 0, -1, 12, 1); - this$static.m_IsRepG0Decoders = initDim(_3S_classLit, 0, -1, 12, 1); - this$static.m_IsRepG1Decoders = initDim(_3S_classLit, 0, -1, 12, 1); - this$static.m_IsRepG2Decoders = initDim(_3S_classLit, 0, -1, 12, 1); - this$static.m_IsRep0LongDecoders = initDim(_3S_classLit, 0, -1, 192, 1); - this$static.m_PosSlotDecoder = initDim(_3Lorg_dellroad_lzma_client_SevenZip_Compression_RangeCoder_BitTreeDecoder_2_classLit, 0, 7, 4, 0); - this$static.m_PosDecoders = initDim(_3S_classLit, 0, -1, 114, 1); - this$static.m_PosAlignDecoder = $BitTreeDecoder(new BitTreeDecoder(), 4); - this$static.m_LenDecoder = $Decoder$LenDecoder(new Decoder$LenDecoder()); - this$static.m_RepLenDecoder = $Decoder$LenDecoder(new Decoder$LenDecoder()); - this$static.m_LiteralDecoder = new Decoder$LiteralDecoder(); - for (i = 0; i < 4; ++i) { - this$static.m_PosSlotDecoder[i] = $BitTreeDecoder(new BitTreeDecoder(), 6); - } - return this$static; - } - - function $Init_1(this$static) { - var i; - $Init_7(this$static.m_OutWindow, false); - InitBitModels(this$static.m_IsMatchDecoders); - InitBitModels(this$static.m_IsRep0LongDecoders); - InitBitModels(this$static.m_IsRepDecoders); - InitBitModels(this$static.m_IsRepG0Decoders); - InitBitModels(this$static.m_IsRepG1Decoders); - InitBitModels(this$static.m_IsRepG2Decoders); - InitBitModels(this$static.m_PosDecoders); - $Init_0(this$static.m_LiteralDecoder); - for (i = 0; i < 4; ++i) { - InitBitModels(this$static.m_PosSlotDecoder[i].Models); - } - $Init(this$static.m_LenDecoder); - $Init(this$static.m_RepLenDecoder); - InitBitModels(this$static.m_PosAlignDecoder.Models); - $Init_8(this$static.m_RangeDecoder); - } - - function $SetDecoderProperties(this$static, properties) { - var dictionarySize, i, lc, lp, pb, remainder, val; - if (properties.length < 5) - return false; - val = properties[0] & 255; - lc = val % 9; - remainder = ~~(val / 9); - lp = remainder % 5; - pb = ~~(remainder / 5); - dictionarySize = 0; - for (i = 0; i < 4; ++i) { - dictionarySize += (properties[1 + i] & 255) << i * 8; - } - if (!$SetLcLpPb(this$static, lc, lp, pb)) { - return false; - } - return $SetDictionarySize(this$static, dictionarySize); - } - - function $SetDictionarySize(this$static, dictionarySize) { - if (dictionarySize < 0) { - return false; - } - if (this$static.m_DictionarySize != dictionarySize) { - this$static.m_DictionarySize = dictionarySize; - this$static.m_DictionarySizeCheck = max(this$static.m_DictionarySize, 1); - $Create_5(this$static.m_OutWindow, max(this$static.m_DictionarySizeCheck, 4096)); - } - return true; - } - - function $SetLcLpPb(this$static, lc, lp, pb) { - var numPosStates; - if (lc > 8 || lp > 4 || pb > 4) { - return false; - } - $Create_0(this$static.m_LiteralDecoder, lp, lc); - numPosStates = 1 << pb; - $Create(this$static.m_LenDecoder, numPosStates); - $Create(this$static.m_RepLenDecoder, numPosStates); - this$static.m_PosStateMask = numPosStates - 1; - return true; - } - - function getClass_32() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Decoder_2_classLit; - } - - function Decoder() { - } - - _ = Decoder.prototype = new Object_0(); - _.getClass$ = getClass_32; - _.typeId$ = 0; - _.m_DictionarySize = -1; - _.m_DictionarySizeCheck = -1; - _.m_PosStateMask = 0; - _.nowPos64 = P0_longLit; - _.outSize = P0_longLit; - _.prevByte = 0; - _.rep0 = 0; - _.rep1 = 0; - _.rep2 = 0; - _.rep3 = 0; - _.state = 0; - function $Create(this$static, numPosStates) { - for (; this$static.m_NumPosStates < numPosStates; ++this$static.m_NumPosStates) { - this$static.m_LowCoder[this$static.m_NumPosStates] = $BitTreeDecoder(new BitTreeDecoder(), 3); - this$static.m_MidCoder[this$static.m_NumPosStates] = $BitTreeDecoder(new BitTreeDecoder(), 3); - } - } - - function $Decode(this$static, rangeDecoder, posState) { - var symbol; - if ($DecodeBit(rangeDecoder, this$static.m_Choice, 0) == 0) { - return $Decode_0(this$static.m_LowCoder[posState], rangeDecoder); - } - symbol = 8; - if ($DecodeBit(rangeDecoder, this$static.m_Choice, 1) == 0) { - symbol += $Decode_0(this$static.m_MidCoder[posState], rangeDecoder); - } else { - symbol += 8 + $Decode_0(this$static.m_HighCoder, rangeDecoder); - } - return symbol; - } - - function $Decoder$LenDecoder(this$static) { - this$static.m_Choice = initDim(_3S_classLit, 0, -1, 2, 1); - this$static.m_LowCoder = initDim(_3Lorg_dellroad_lzma_client_SevenZip_Compression_RangeCoder_BitTreeDecoder_2_classLit, 0, 7, 16, 0); - this$static.m_MidCoder = initDim(_3Lorg_dellroad_lzma_client_SevenZip_Compression_RangeCoder_BitTreeDecoder_2_classLit, 0, 7, 16, 0); - this$static.m_HighCoder = $BitTreeDecoder(new BitTreeDecoder(), 8); - return this$static; - } - - function $Init(this$static) { - var posState; - InitBitModels(this$static.m_Choice); - for (posState = 0; posState < this$static.m_NumPosStates; ++posState) { - InitBitModels(this$static.m_LowCoder[posState].Models); - InitBitModels(this$static.m_MidCoder[posState].Models); - } - InitBitModels(this$static.m_HighCoder.Models); - } - - function getClass_29() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Decoder$LenDecoder_2_classLit; - } - - function Decoder$LenDecoder() { - } - - _ = Decoder$LenDecoder.prototype = new Object_0(); - _.getClass$ = getClass_29; - _.typeId$ = 0; - _.m_NumPosStates = 0; - function $Create_0(this$static, numPosBits, numPrevBits) { - var i, numStates; - if (this$static.m_Coders != null && this$static.m_NumPrevBits == numPrevBits && this$static.m_NumPosBits == numPosBits) - return; - this$static.m_NumPosBits = numPosBits; - this$static.m_PosMask = (1 << numPosBits) - 1; - this$static.m_NumPrevBits = numPrevBits; - numStates = 1 << this$static.m_NumPrevBits + this$static.m_NumPosBits; - this$static.m_Coders = initDim(_3Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Decoder$LiteralDecoder$Decoder2_2_classLit, 0, 4, numStates, 0); - for (i = 0; i < numStates; ++i) - this$static.m_Coders[i] = $Decoder$LiteralDecoder$Decoder2(new Decoder$LiteralDecoder$Decoder2()); - } - - function $GetDecoder(this$static, pos, prevByte) { - return this$static.m_Coders[((pos & this$static.m_PosMask) << this$static.m_NumPrevBits) + ((prevByte & 255) >>> 8 - this$static.m_NumPrevBits)]; - } - - function $Init_0(this$static) { - var i, numStates; - numStates = 1 << this$static.m_NumPrevBits + this$static.m_NumPosBits; - for (i = 0; i < numStates; ++i) { - InitBitModels(this$static.m_Coders[i].m_Decoders); - } - } - - function getClass_31() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Decoder$LiteralDecoder_2_classLit; - } - - function Decoder$LiteralDecoder() { - } - - _ = Decoder$LiteralDecoder.prototype = new Object_0(); - _.getClass$ = getClass_31; - _.typeId$ = 0; - _.m_Coders = null; - _.m_NumPosBits = 0; - _.m_NumPrevBits = 0; - _.m_PosMask = 0; - function $DecodeNormal(this$static, rangeDecoder) { - var symbol; - symbol = 1; - do { - symbol = symbol << 1 | $DecodeBit(rangeDecoder, this$static.m_Decoders, symbol); - } while (symbol < 256); - return symbol << 24 >> 24; - } - - function $DecodeWithMatchByte(this$static, rangeDecoder, matchByte) { - var bit, matchBit, symbol; - symbol = 1; - do { - matchBit = matchByte >> 7 & 1; - matchByte <<= 1; - bit = $DecodeBit(rangeDecoder, this$static.m_Decoders, (1 + matchBit << 8) + symbol); - symbol = symbol << 1 | bit; - if (matchBit != bit) { - while (symbol < 256) { - symbol = symbol << 1 | $DecodeBit(rangeDecoder, this$static.m_Decoders, symbol); - } - break; - } - } while (symbol < 256); - return symbol << 24 >> 24; - } - - function $Decoder$LiteralDecoder$Decoder2(this$static) { - this$static.m_Decoders = initDim(_3S_classLit, 0, -1, 768, 1); - return this$static; - } - - function getClass_30() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Decoder$LiteralDecoder$Decoder2_2_classLit; - } - - function Decoder$LiteralDecoder$Decoder2() { - } - - _ = Decoder$LiteralDecoder$Decoder2.prototype = new Object_0(); - _.getClass$ = getClass_30; - _.typeId$ = 17; - function $clinit_59() { - $clinit_59 = nullMethod; - var c, j, k, slotFast; - g_FastPos = initDim(_3B_classLit, 0, -1, 2048, 1); - c = 2; - g_FastPos[0] = 0; - g_FastPos[1] = 1; - for (slotFast = 2; slotFast < 22; ++slotFast) { - k = 1 << (slotFast >> 1) - 1; - for (j = 0; j < k; ++j , ++c) - g_FastPos[c] = slotFast << 24 >> 24; - } - } - - function $Backward(this$static, cur) { - var backCur, backMem, posMem, posPrev; - this$static._optimumEndIndex = cur; - posMem = this$static._optimum[cur].PosPrev; - backMem = this$static._optimum[cur].BackPrev; - do { - if (this$static._optimum[cur].Prev1IsChar) { - $MakeAsChar(this$static._optimum[posMem]); - this$static._optimum[posMem].PosPrev = posMem - 1; - if (this$static._optimum[cur].Prev2) { - this$static._optimum[posMem - 1].Prev1IsChar = false; - this$static._optimum[posMem - 1].PosPrev = this$static._optimum[cur].PosPrev2; - this$static._optimum[posMem - 1].BackPrev = this$static._optimum[cur].BackPrev2; - } - } - posPrev = posMem; - backCur = backMem; - backMem = this$static._optimum[posPrev].BackPrev; - posMem = this$static._optimum[posPrev].PosPrev; - this$static._optimum[posPrev].BackPrev = backCur; - this$static._optimum[posPrev].PosPrev = cur; - cur = posPrev; - } while (cur > 0); - this$static.backRes = this$static._optimum[0].BackPrev; - this$static._optimumCurrentIndex = this$static._optimum[0].PosPrev; - return this$static._optimumCurrentIndex; - } - - function $BaseInit(this$static) { - var i; - this$static._state = 0; - this$static._previousByte = 0; - for (i = 0; i < 4; ++i) { - this$static._repDistances[i] = 0; - } - } - - function $CodeOneBlock(this$static, inSize, outSize, finished) { - var baseVal, complexState, curByte, distance, footerBits, i, len, lenToPosState, matchByte, pos, posReduced, posSlot, posState, progressPosValuePrev, subCoder; - inSize[0] = P0_longLit; - outSize[0] = P0_longLit; - finished[0] = true; - if (this$static._inStream) { - this$static._matchFinder._stream = this$static._inStream; - $Init_5(this$static._matchFinder); - this$static._needReleaseMFStream = true; - this$static._inStream = null; - } - if (this$static._finished) { - return; - } - this$static._finished = true; - progressPosValuePrev = this$static.nowPos64; - if (eq(this$static.nowPos64, P0_longLit)) { - if ($GetNumAvailableBytes(this$static._matchFinder) == 0) { - $Flush(this$static, lowBits_0(this$static.nowPos64)); - return; - } - $ReadMatchDistances(this$static); - posState = lowBits_0(this$static.nowPos64) & this$static._posStateMask; - $Encode_3(this$static._rangeEncoder, this$static._isMatch, (this$static._state << 4) + posState, 0); - this$static._state = StateUpdateChar(this$static._state); - curByte = $GetIndexByte(this$static._matchFinder, -this$static._additionalOffset); - $Encode_1($GetSubCoder(this$static._literalEncoder, lowBits_0(this$static.nowPos64), this$static._previousByte), this$static._rangeEncoder, curByte); - this$static._previousByte = curByte; - --this$static._additionalOffset; - this$static.nowPos64 = add(this$static.nowPos64, P1_longLit); - } - if ($GetNumAvailableBytes(this$static._matchFinder) == 0) { - $Flush(this$static, lowBits_0(this$static.nowPos64)); - return; - } - while (true) { - len = $GetOptimum(this$static, lowBits_0(this$static.nowPos64)); - pos = this$static.backRes; - posState = lowBits_0(this$static.nowPos64) & this$static._posStateMask; - complexState = (this$static._state << 4) + posState; - if (len == 1 && pos == -1) { - $Encode_3(this$static._rangeEncoder, this$static._isMatch, complexState, 0); - curByte = $GetIndexByte(this$static._matchFinder, -this$static._additionalOffset); - subCoder = $GetSubCoder(this$static._literalEncoder, lowBits_0(this$static.nowPos64), this$static._previousByte); - if (this$static._state < 7) { - $Encode_1(subCoder, this$static._rangeEncoder, curByte); - } else { - matchByte = $GetIndexByte(this$static._matchFinder, -this$static._repDistances[0] - 1 - this$static._additionalOffset); - $EncodeMatched(subCoder, this$static._rangeEncoder, matchByte, curByte); - } - this$static._previousByte = curByte; - this$static._state = StateUpdateChar(this$static._state); - } else { - $Encode_3(this$static._rangeEncoder, this$static._isMatch, complexState, 1); - if (pos < 4) { - $Encode_3(this$static._rangeEncoder, this$static._isRep, this$static._state, 1); - if (pos == 0) { - $Encode_3(this$static._rangeEncoder, this$static._isRepG0, this$static._state, 0); - if (len == 1) { - $Encode_3(this$static._rangeEncoder, this$static._isRep0Long, complexState, 0); - } else { - $Encode_3(this$static._rangeEncoder, this$static._isRep0Long, complexState, 1); - } - } else { - $Encode_3(this$static._rangeEncoder, this$static._isRepG0, this$static._state, 1); - if (pos == 1) { - $Encode_3(this$static._rangeEncoder, this$static._isRepG1, this$static._state, 0); - } else { - $Encode_3(this$static._rangeEncoder, this$static._isRepG1, this$static._state, 1); - $Encode_3(this$static._rangeEncoder, this$static._isRepG2, this$static._state, pos - 2); - } - } - if (len == 1) { - this$static._state = this$static._state < 7?9:11; - } else { - $Encode_0(this$static._repMatchLenEncoder, this$static._rangeEncoder, len - 2, posState); - this$static._state = this$static._state < 7?8:11; - } - distance = this$static._repDistances[pos]; - if (pos != 0) { - for (i = pos; i >= 1; --i) { - this$static._repDistances[i] = this$static._repDistances[i - 1]; - } - this$static._repDistances[0] = distance; - } - } else { - $Encode_3(this$static._rangeEncoder, this$static._isRep, this$static._state, 0); - this$static._state = this$static._state < 7?7:10; - $Encode_0(this$static._lenEncoder, this$static._rangeEncoder, len - 2, posState); - pos -= 4; - posSlot = GetPosSlot(pos); - lenToPosState = GetLenToPosState(len); - $Encode_2(this$static._posSlotEncoder[lenToPosState], this$static._rangeEncoder, posSlot); - if (posSlot >= 4) { - footerBits = (posSlot >> 1) - 1; - baseVal = (2 | posSlot & 1) << footerBits; - posReduced = pos - baseVal; - if (posSlot < 14) { - ReverseEncode(this$static._posEncoders, baseVal - posSlot - 1, this$static._rangeEncoder, footerBits, posReduced); - } else { - $EncodeDirectBits(this$static._rangeEncoder, posReduced >> 4, footerBits - 4); - $ReverseEncode(this$static._posAlignEncoder, this$static._rangeEncoder, posReduced & 15); - ++this$static._alignPriceCount; - } - } - distance = pos; - for (i = 3; i >= 1; --i) { - this$static._repDistances[i] = this$static._repDistances[i - 1]; - } - this$static._repDistances[0] = distance; - ++this$static._matchPriceCount; - } - this$static._previousByte = $GetIndexByte(this$static._matchFinder, len - 1 - this$static._additionalOffset); - } - this$static._additionalOffset -= len; - this$static.nowPos64 = add(this$static.nowPos64, fromInt(len)); - if (this$static._additionalOffset == 0) { - if (this$static._matchPriceCount >= 128) { - $FillDistancesPrices(this$static); - } - if (this$static._alignPriceCount >= 16) { - $FillAlignPrices(this$static); - } - inSize[0] = this$static.nowPos64; - outSize[0] = $GetProcessedSizeAdd(this$static._rangeEncoder); - if ($GetNumAvailableBytes(this$static._matchFinder) == 0) { - $Flush(this$static, lowBits_0(this$static.nowPos64)); - return; - } - if (compare(sub(this$static.nowPos64, progressPosValuePrev), P1000_longLit) >= 0) { - this$static._finished = false; - finished[0] = false; - return; - } - } - } - } - - function $Create_2(this$static) { - var bt, numHashBytes; - if (!this$static._matchFinder) { - bt = ($clinit_60() , new BinTree()); - numHashBytes = 4; - if (this$static._matchFinderType == 0) { - numHashBytes = 2; - } - $SetType(bt, numHashBytes); - this$static._matchFinder = bt; - } - $Create_1(this$static._literalEncoder, this$static._numLiteralPosStateBits, this$static._numLiteralContextBits); - if (this$static._dictionarySize == this$static._dictionarySizePrev && this$static._numFastBytesPrev == this$static._numFastBytes) { - return; - } - $Create_3(this$static._matchFinder, this$static._dictionarySize, 4096, this$static._numFastBytes, 274); - this$static._dictionarySizePrev = this$static._dictionarySize; - this$static._numFastBytesPrev = this$static._numFastBytes; - } - - function $Encoder(this$static) { - var i; - $clinit_59(); - this$static._repDistances = initDim(_3I_classLit, 0, -1, 4, 1); - this$static._optimum = initDim(_3Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Encoder$Optimal_2_classLit, 0, 6, 4096, 0); - this$static._rangeEncoder = ($clinit_66() , new Encoder_0()); - this$static._isMatch = initDim(_3S_classLit, 0, -1, 192, 1); - this$static._isRep = initDim(_3S_classLit, 0, -1, 12, 1); - this$static._isRepG0 = initDim(_3S_classLit, 0, -1, 12, 1); - this$static._isRepG1 = initDim(_3S_classLit, 0, -1, 12, 1); - this$static._isRepG2 = initDim(_3S_classLit, 0, -1, 12, 1); - this$static._isRep0Long = initDim(_3S_classLit, 0, -1, 192, 1); - this$static._posSlotEncoder = initDim(_3Lorg_dellroad_lzma_client_SevenZip_Compression_RangeCoder_BitTreeEncoder_2_classLit, 0, 8, 4, 0); - this$static._posEncoders = initDim(_3S_classLit, 0, -1, 114, 1); - this$static._posAlignEncoder = $BitTreeEncoder(new BitTreeEncoder(), 4); - this$static._lenEncoder = $Encoder$LenPriceTableEncoder(new Encoder$LenPriceTableEncoder()); - this$static._repMatchLenEncoder = $Encoder$LenPriceTableEncoder(new Encoder$LenPriceTableEncoder()); - this$static._literalEncoder = new Encoder$LiteralEncoder(); - this$static._matchDistances = initDim(_3I_classLit, 0, -1, 548, 1); - this$static._posSlotPrices = initDim(_3I_classLit, 0, -1, 256, 1); - this$static._distancesPrices = initDim(_3I_classLit, 0, -1, 512, 1); - this$static._alignPrices = initDim(_3I_classLit, 0, -1, 16, 1); - this$static.reps = initDim(_3I_classLit, 0, -1, 4, 1); - this$static.repLens = initDim(_3I_classLit, 0, -1, 4, 1); - this$static.processedInSize = initDim(_3J_classLit, 0, -1, 1, 3); - this$static.processedOutSize = initDim(_3J_classLit, 0, -1, 1, 3); - this$static.finished = initDim(_3Z_classLit, 0, -1, 1, 2); - this$static.properties = initDim(_3B_classLit, 0, -1, 5, 1); - this$static.tempPrices = initDim(_3I_classLit, 0, -1, 128, 1); - for (i = 0; i < 4096; ++i) { - this$static._optimum[i] = new Encoder$Optimal(); - } - for (i = 0; i < 4; ++i) { - this$static._posSlotEncoder[i] = $BitTreeEncoder(new BitTreeEncoder(), 6); - } - return this$static; - } - - function $FillAlignPrices(this$static) { - var i; - for (i = 0; i < 16; ++i) { - this$static._alignPrices[i] = $ReverseGetPrice(this$static._posAlignEncoder, i); - } - this$static._alignPriceCount = 0; - } - - function $FillDistancesPrices(this$static) { - var baseVal, encoder, footerBits, i, lenToPosState, posSlot, st, st2; - for (i = 4; i < 128; ++i) { - posSlot = GetPosSlot(i); - footerBits = (posSlot >> 1) - 1; - baseVal = (2 | posSlot & 1) << footerBits; - this$static.tempPrices[i] = ReverseGetPrice(this$static._posEncoders, baseVal - posSlot - 1, footerBits, i - baseVal); - } - for (lenToPosState = 0; lenToPosState < 4; ++lenToPosState) { - encoder = this$static._posSlotEncoder[lenToPosState]; - st = lenToPosState << 6; - for (posSlot = 0; posSlot < this$static._distTableSize; ++posSlot) { - this$static._posSlotPrices[st + posSlot] = $GetPrice_1(encoder, posSlot); - } - for (posSlot = 14; posSlot < this$static._distTableSize; ++posSlot) { - this$static._posSlotPrices[st + posSlot] += (posSlot >> 1) - 1 - 4 << 6; - } - st2 = lenToPosState * 128; - for (i = 0; i < 4; ++i) { - this$static._distancesPrices[st2 + i] = this$static._posSlotPrices[st + i]; - } - for (; i < 128; ++i) { - this$static._distancesPrices[st2 + i] = this$static._posSlotPrices[st + GetPosSlot(i)] + this$static.tempPrices[i]; - } - } - this$static._matchPriceCount = 0; - } - - function $Flush(this$static, nowPos) { - $ReleaseMFStream(this$static); - $WriteEndMarker(this$static, nowPos & this$static._posStateMask); - $FlushData(this$static._rangeEncoder); - } - - function $GetOptimum(this$static, position) { - var cur, curAnd1Price, curAndLenCharPrice, curAndLenPrice, curBack, curPrice, currentByte, distance, i, len, lenEnd, lenMain, lenRes, lenTest, lenTest2, lenTestTemp, matchByte, matchPrice, newLen, nextIsChar, nextMatchPrice, nextOptimum, nextRepMatchPrice, normalMatchPrice, numAvailableBytes, numAvailableBytesFull, numDistancePairs, offs, offset, opt, optimum, pos, posPrev, posState, posStateNext, price_4, repIndex, repLen, repMatchPrice, repMaxIndex, shortRepPrice, startLen, state, state2, t, price, price_0, price_1, price_2, price_3; - if (this$static._optimumEndIndex != this$static._optimumCurrentIndex) { - lenRes = this$static._optimum[this$static._optimumCurrentIndex].PosPrev - this$static._optimumCurrentIndex; - this$static.backRes = this$static._optimum[this$static._optimumCurrentIndex].BackPrev; - this$static._optimumCurrentIndex = this$static._optimum[this$static._optimumCurrentIndex].PosPrev; - return lenRes; - } - this$static._optimumCurrentIndex = this$static._optimumEndIndex = 0; - if (this$static._longestMatchWasFound) { - lenMain = this$static._longestMatchLength; - this$static._longestMatchWasFound = false; - } else { - lenMain = $ReadMatchDistances(this$static); - } - numDistancePairs = this$static._numDistancePairs; - numAvailableBytes = $GetNumAvailableBytes(this$static._matchFinder) + 1; - if (numAvailableBytes < 2) { - this$static.backRes = -1; - return 1; - } - if (numAvailableBytes > 273) { - numAvailableBytes = 273; - } - repMaxIndex = 0; - for (i = 0; i < 4; ++i) { - this$static.reps[i] = this$static._repDistances[i]; - this$static.repLens[i] = $GetMatchLen(this$static._matchFinder, -1, this$static.reps[i], 273); - if (this$static.repLens[i] > this$static.repLens[repMaxIndex]) { - repMaxIndex = i; - } - } - if (this$static.repLens[repMaxIndex] >= this$static._numFastBytes) { - this$static.backRes = repMaxIndex; - lenRes = this$static.repLens[repMaxIndex]; - $MovePos(this$static, lenRes - 1); - return lenRes; - } - if (lenMain >= this$static._numFastBytes) { - this$static.backRes = this$static._matchDistances[numDistancePairs - 1] + 4; - $MovePos(this$static, lenMain - 1); - return lenMain; - } - currentByte = $GetIndexByte(this$static._matchFinder, -1); - matchByte = $GetIndexByte(this$static._matchFinder, -this$static._repDistances[0] - 1 - 1); - if (lenMain < 2 && currentByte != matchByte && this$static.repLens[repMaxIndex] < 2) { - this$static.backRes = -1; - return 1; - } - this$static._optimum[0].State = this$static._state; - posState = position & this$static._posStateMask; - this$static._optimum[1].Price = ($clinit_66() , ProbPrices[this$static._isMatch[(this$static._state << 4) + posState] >>> 2]) + $GetPrice_0($GetSubCoder(this$static._literalEncoder, position, this$static._previousByte), this$static._state >= 7, matchByte, currentByte); - $MakeAsChar(this$static._optimum[1]); - matchPrice = ProbPrices[2048 - this$static._isMatch[(this$static._state << 4) + posState] >>> 2]; - repMatchPrice = matchPrice + ProbPrices[2048 - this$static._isRep[this$static._state] >>> 2]; - if (matchByte == currentByte) { - shortRepPrice = repMatchPrice + $GetRepLen1Price(this$static, this$static._state, posState); - if (shortRepPrice < this$static._optimum[1].Price) { - this$static._optimum[1].Price = shortRepPrice; - $MakeAsShortRep(this$static._optimum[1]); - } - } - lenEnd = lenMain >= this$static.repLens[repMaxIndex]?lenMain:this$static.repLens[repMaxIndex]; - if (lenEnd < 2) { - this$static.backRes = this$static._optimum[1].BackPrev; - return 1; - } - this$static._optimum[1].PosPrev = 0; - this$static._optimum[0].Backs0 = this$static.reps[0]; - this$static._optimum[0].Backs1 = this$static.reps[1]; - this$static._optimum[0].Backs2 = this$static.reps[2]; - this$static._optimum[0].Backs3 = this$static.reps[3]; - len = lenEnd; - do { - this$static._optimum[len--].Price = 268435455; - } while (len >= 2); - for (i = 0; i < 4; ++i) { - repLen = this$static.repLens[i]; - if (repLen < 2) { - continue; - } - price_4 = repMatchPrice + $GetPureRepPrice(this$static, i, this$static._state, posState); - do { - curAndLenPrice = price_4 + $GetPrice(this$static._repMatchLenEncoder, repLen - 2, posState); - optimum = this$static._optimum[repLen]; - if (curAndLenPrice < optimum.Price) { - optimum.Price = curAndLenPrice; - optimum.PosPrev = 0; - optimum.BackPrev = i; - optimum.Prev1IsChar = false; - } - } while (--repLen >= 2); - } - normalMatchPrice = matchPrice + ProbPrices[this$static._isRep[this$static._state] >>> 2]; - len = this$static.repLens[0] >= 2?this$static.repLens[0] + 1:2; - if (len <= lenMain) { - offs = 0; - while (len > this$static._matchDistances[offs]) { - offs += 2; - } - for (;; ++len) { - distance = this$static._matchDistances[offs + 1]; - curAndLenPrice = normalMatchPrice + $GetPosLenPrice(this$static, distance, len, posState); - optimum = this$static._optimum[len]; - if (curAndLenPrice < optimum.Price) { - optimum.Price = curAndLenPrice; - optimum.PosPrev = 0; - optimum.BackPrev = distance + 4; - optimum.Prev1IsChar = false; - } - if (len == this$static._matchDistances[offs]) { - offs += 2; - if (offs == numDistancePairs) { - break; - } - } - } - } - cur = 0; - while (true) { - ++cur; - if (cur == lenEnd) { - return $Backward(this$static, cur); - } - newLen = $ReadMatchDistances(this$static); - numDistancePairs = this$static._numDistancePairs; - if (newLen >= this$static._numFastBytes) { - this$static._longestMatchLength = newLen; - this$static._longestMatchWasFound = true; - return $Backward(this$static, cur); - } - ++position; - posPrev = this$static._optimum[cur].PosPrev; - if (this$static._optimum[cur].Prev1IsChar) { - --posPrev; - if (this$static._optimum[cur].Prev2) { - state = this$static._optimum[this$static._optimum[cur].PosPrev2].State; - if (this$static._optimum[cur].BackPrev2 < 4) { - state = (state < 7) ? 8 : 11; - } else { - state = (state < 7) ? 7 : 10; - } - } else { - state = this$static._optimum[posPrev].State; - } - state = StateUpdateChar(state); - } else { - state = this$static._optimum[posPrev].State; - } - if (posPrev == cur - 1) { - if (this$static._optimum[cur].BackPrev == 0) { - state = state < 7?9:11; - } else { - state = StateUpdateChar(state); - } - } else { - if (this$static._optimum[cur].Prev1IsChar && this$static._optimum[cur].Prev2) { - posPrev = this$static._optimum[cur].PosPrev2; - pos = this$static._optimum[cur].BackPrev2; - state = state < 7?8:11; - } else { - pos = this$static._optimum[cur].BackPrev; - if (pos < 4) { - state = state < 7?8:11; - } else { - state = state < 7?7:10; - } - } - opt = this$static._optimum[posPrev]; - if (pos < 4) { - if (pos == 0) { - this$static.reps[0] = opt.Backs0; - this$static.reps[1] = opt.Backs1; - this$static.reps[2] = opt.Backs2; - this$static.reps[3] = opt.Backs3; - } else if (pos == 1) { - this$static.reps[0] = opt.Backs1; - this$static.reps[1] = opt.Backs0; - this$static.reps[2] = opt.Backs2; - this$static.reps[3] = opt.Backs3; - } else if (pos == 2) { - this$static.reps[0] = opt.Backs2; - this$static.reps[1] = opt.Backs0; - this$static.reps[2] = opt.Backs1; - this$static.reps[3] = opt.Backs3; - } else { - this$static.reps[0] = opt.Backs3; - this$static.reps[1] = opt.Backs0; - this$static.reps[2] = opt.Backs1; - this$static.reps[3] = opt.Backs2; - } - } else { - this$static.reps[0] = pos - 4; - this$static.reps[1] = opt.Backs0; - this$static.reps[2] = opt.Backs1; - this$static.reps[3] = opt.Backs2; - } - } - this$static._optimum[cur].State = state; - this$static._optimum[cur].Backs0 = this$static.reps[0]; - this$static._optimum[cur].Backs1 = this$static.reps[1]; - this$static._optimum[cur].Backs2 = this$static.reps[2]; - this$static._optimum[cur].Backs3 = this$static.reps[3]; - curPrice = this$static._optimum[cur].Price; - currentByte = $GetIndexByte(this$static._matchFinder, -1); - matchByte = $GetIndexByte(this$static._matchFinder, -this$static.reps[0] - 1 - 1); - posState = position & this$static._posStateMask; - curAnd1Price = curPrice + ProbPrices[this$static._isMatch[(state << 4) + posState] >>> 2] + $GetPrice_0($GetSubCoder(this$static._literalEncoder, position, $GetIndexByte(this$static._matchFinder, -2)), state >= 7, matchByte, currentByte); - nextOptimum = this$static._optimum[cur + 1]; - nextIsChar = false; - if (curAnd1Price < nextOptimum.Price) { - nextOptimum.Price = curAnd1Price; - nextOptimum.PosPrev = cur; - nextOptimum.BackPrev = -1; - nextOptimum.Prev1IsChar = false; - nextIsChar = true; - } - matchPrice = curPrice + ProbPrices[2048 - this$static._isMatch[(state << 4) + posState] >>> 2]; - repMatchPrice = matchPrice + ProbPrices[2048 - this$static._isRep[state] >>> 2]; - if (matchByte == currentByte && !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0)) { - shortRepPrice = repMatchPrice + (ProbPrices[this$static._isRepG0[state] >>> 2] + ProbPrices[this$static._isRep0Long[(state << 4) + posState] >>> 2]); - if (shortRepPrice <= nextOptimum.Price) { - nextOptimum.Price = shortRepPrice; - nextOptimum.PosPrev = cur; - nextOptimum.BackPrev = 0; - nextOptimum.Prev1IsChar = false; - nextIsChar = true; - } - } - numAvailableBytesFull = $GetNumAvailableBytes(this$static._matchFinder) + 1; - numAvailableBytesFull = 4095 - cur < numAvailableBytesFull?4095 - cur:numAvailableBytesFull; - numAvailableBytes = numAvailableBytesFull; - if (numAvailableBytes < 2) { - continue; - } - if (numAvailableBytes > this$static._numFastBytes) { - numAvailableBytes = this$static._numFastBytes; - } - if (!nextIsChar && matchByte != currentByte) { - t = min(numAvailableBytesFull - 1, this$static._numFastBytes); - lenTest2 = $GetMatchLen(this$static._matchFinder, 0, this$static.reps[0], t); - if (lenTest2 >= 2) { - state2 = StateUpdateChar(state); - posStateNext = position + 1 & this$static._posStateMask; - nextRepMatchPrice = curAnd1Price + ProbPrices[2048 - this$static._isMatch[(state2 << 4) + posStateNext] >>> 2] + ProbPrices[2048 - this$static._isRep[state2] >>> 2]; - offset = cur + 1 + lenTest2; - while (lenEnd < offset) { - this$static._optimum[++lenEnd].Price = 268435455; - } - curAndLenPrice = nextRepMatchPrice + (price = $GetPrice(this$static._repMatchLenEncoder, lenTest2 - 2, posStateNext) , price + $GetPureRepPrice(this$static, 0, state2, posStateNext)); - optimum = this$static._optimum[offset]; - if (curAndLenPrice < optimum.Price) { - optimum.Price = curAndLenPrice; - optimum.PosPrev = cur + 1; - optimum.BackPrev = 0; - optimum.Prev1IsChar = true; - optimum.Prev2 = false; - } - } - } - startLen = 2; - for (repIndex = 0; repIndex < 4; ++repIndex) { - lenTest = $GetMatchLen(this$static._matchFinder, -1, this$static.reps[repIndex], numAvailableBytes); - if (lenTest < 2) { - continue; - } - lenTestTemp = lenTest; - do { - while (lenEnd < cur + lenTest) { - this$static._optimum[++lenEnd].Price = 268435455; - } - curAndLenPrice = repMatchPrice + (price_0 = $GetPrice(this$static._repMatchLenEncoder, lenTest - 2, posState) , price_0 + $GetPureRepPrice(this$static, repIndex, state, posState)); - optimum = this$static._optimum[cur + lenTest]; - if (curAndLenPrice < optimum.Price) { - optimum.Price = curAndLenPrice; - optimum.PosPrev = cur; - optimum.BackPrev = repIndex; - optimum.Prev1IsChar = false; - } - } while (--lenTest >= 2); - lenTest = lenTestTemp; - if (repIndex == 0) { - startLen = lenTest + 1; - } - if (lenTest < numAvailableBytesFull) { - t = min(numAvailableBytesFull - 1 - lenTest, this$static._numFastBytes); - lenTest2 = $GetMatchLen(this$static._matchFinder, lenTest, this$static.reps[repIndex], t); - if (lenTest2 >= 2) { - state2 = state < 7?8:11; - posStateNext = position + lenTest & this$static._posStateMask; - curAndLenCharPrice = repMatchPrice + (price_1 = $GetPrice(this$static._repMatchLenEncoder, lenTest - 2, posState) , price_1 + $GetPureRepPrice(this$static, repIndex, state, posState)) + ProbPrices[this$static._isMatch[(state2 << 4) + posStateNext] >>> 2] + $GetPrice_0($GetSubCoder(this$static._literalEncoder, position + lenTest, $GetIndexByte(this$static._matchFinder, lenTest - 1 - 1)), true, $GetIndexByte(this$static._matchFinder, lenTest - 1 - (this$static.reps[repIndex] + 1)), $GetIndexByte(this$static._matchFinder, lenTest - 1)); - state2 = StateUpdateChar(state2); - posStateNext = position + lenTest + 1 & this$static._posStateMask; - nextMatchPrice = curAndLenCharPrice + ProbPrices[2048 - this$static._isMatch[(state2 << 4) + posStateNext] >>> 2]; - nextRepMatchPrice = nextMatchPrice + ProbPrices[2048 - this$static._isRep[state2] >>> 2]; - offset = lenTest + 1 + lenTest2; - while (lenEnd < cur + offset) { - this$static._optimum[++lenEnd].Price = 268435455; - } - curAndLenPrice = nextRepMatchPrice + (price_2 = $GetPrice(this$static._repMatchLenEncoder, lenTest2 - 2, posStateNext) , price_2 + $GetPureRepPrice(this$static, 0, state2, posStateNext)); - optimum = this$static._optimum[cur + offset]; - if (curAndLenPrice < optimum.Price) { - optimum.Price = curAndLenPrice; - optimum.PosPrev = cur + lenTest + 1; - optimum.BackPrev = 0; - optimum.Prev1IsChar = true; - optimum.Prev2 = true; - optimum.PosPrev2 = cur; - optimum.BackPrev2 = repIndex; - } - } - } - } - if (newLen > numAvailableBytes) { - newLen = numAvailableBytes; - for (numDistancePairs = 0; newLen > this$static._matchDistances[numDistancePairs]; numDistancePairs += 2) { - } - this$static._matchDistances[numDistancePairs] = newLen; - numDistancePairs += 2; - } - if (newLen >= startLen) { - normalMatchPrice = matchPrice + ProbPrices[this$static._isRep[state] >>> 2]; - while (lenEnd < cur + newLen) { - this$static._optimum[++lenEnd].Price = 268435455; - } - offs = 0; - while (startLen > this$static._matchDistances[offs]) { - offs += 2; - } - for (lenTest = startLen;; ++lenTest) { - curBack = this$static._matchDistances[offs + 1]; - curAndLenPrice = normalMatchPrice + $GetPosLenPrice(this$static, curBack, lenTest, posState); - optimum = this$static._optimum[cur + lenTest]; - if (curAndLenPrice < optimum.Price) { - optimum.Price = curAndLenPrice; - optimum.PosPrev = cur; - optimum.BackPrev = curBack + 4; - optimum.Prev1IsChar = false; - } - if (lenTest == this$static._matchDistances[offs]) { - if (lenTest < numAvailableBytesFull) { - t = min(numAvailableBytesFull - 1 - lenTest, this$static._numFastBytes); - lenTest2 = $GetMatchLen(this$static._matchFinder, lenTest, curBack, t); - if (lenTest2 >= 2) { - state2 = state < 7?7:10; - posStateNext = position + lenTest & this$static._posStateMask; - curAndLenCharPrice = curAndLenPrice + ProbPrices[this$static._isMatch[(state2 << 4) + posStateNext] >>> 2] + $GetPrice_0($GetSubCoder(this$static._literalEncoder, position + lenTest, $GetIndexByte(this$static._matchFinder, lenTest - 1 - 1)), true, $GetIndexByte(this$static._matchFinder, lenTest - (curBack + 1) - 1), $GetIndexByte(this$static._matchFinder, lenTest - 1)); - state2 = StateUpdateChar(state2); - posStateNext = position + lenTest + 1 & this$static._posStateMask; - nextMatchPrice = curAndLenCharPrice + ProbPrices[2048 - this$static._isMatch[(state2 << 4) + posStateNext] >>> 2]; - nextRepMatchPrice = nextMatchPrice + ProbPrices[2048 - this$static._isRep[state2] >>> 2]; - offset = lenTest + 1 + lenTest2; - while (lenEnd < cur + offset) { - this$static._optimum[++lenEnd].Price = 268435455; - } - curAndLenPrice = nextRepMatchPrice + (price_3 = $GetPrice(this$static._repMatchLenEncoder, lenTest2 - 2, posStateNext) , price_3 + $GetPureRepPrice(this$static, 0, state2, posStateNext)); - optimum = this$static._optimum[cur + offset]; - if (curAndLenPrice < optimum.Price) { - optimum.Price = curAndLenPrice; - optimum.PosPrev = cur + lenTest + 1; - optimum.BackPrev = 0; - optimum.Prev1IsChar = true; - optimum.Prev2 = true; - optimum.PosPrev2 = cur; - optimum.BackPrev2 = curBack + 4; - } - } - } - offs += 2; - if (offs == numDistancePairs) - break; - } - } - } - } - } - - function $GetPosLenPrice(this$static, pos, len, posState) { - var lenToPosState, price; - lenToPosState = GetLenToPosState(len); - if (pos < 128) { - price = this$static._distancesPrices[lenToPosState * 128 + pos]; - } else { - price = this$static._posSlotPrices[(lenToPosState << 6) + GetPosSlot2(pos)] + this$static._alignPrices[pos & 15]; - } - return price + $GetPrice(this$static._lenEncoder, len - 2, posState); - } - - function $GetPureRepPrice(this$static, repIndex, state, posState) { - var price; - if (repIndex == 0) { - price = ($clinit_66() , ProbPrices[this$static._isRepG0[state] >>> 2]); - price += ProbPrices[2048 - this$static._isRep0Long[(state << 4) + posState] >>> 2]; - } else { - price = ($clinit_66() , ProbPrices[2048 - this$static._isRepG0[state] >>> 2]); - if (repIndex == 1) { - price += ProbPrices[this$static._isRepG1[state] >>> 2]; - } else { - price += ProbPrices[2048 - this$static._isRepG1[state] >>> 2]; - price += GetPrice(this$static._isRepG2[state], repIndex - 2); - } - } - return price; - } - - function $GetRepLen1Price(this$static, state, posState) { - return ($clinit_66() , ProbPrices[this$static._isRepG0[state] >>> 2]) + ProbPrices[this$static._isRep0Long[(state << 4) + posState] >>> 2]; - } - - function $Init_4(this$static) { - var i; - $BaseInit(this$static); - $Init_9(this$static._rangeEncoder); - InitBitModels_0(this$static._isMatch); - InitBitModels_0(this$static._isRep0Long); - InitBitModels_0(this$static._isRep); - InitBitModels_0(this$static._isRepG0); - InitBitModels_0(this$static._isRepG1); - InitBitModels_0(this$static._isRepG2); - InitBitModels_0(this$static._posEncoders); - $Init_3(this$static._literalEncoder); - for (i = 0; i < 4; ++i) { - InitBitModels(this$static._posSlotEncoder[i].Models); - } - $Init_2(this$static._lenEncoder, 1 << this$static._posStateBits); - $Init_2(this$static._repMatchLenEncoder, 1 << this$static._posStateBits); - InitBitModels(this$static._posAlignEncoder.Models); - this$static._longestMatchWasFound = false; - this$static._optimumEndIndex = 0; - this$static._optimumCurrentIndex = 0; - this$static._additionalOffset = 0; - } - - function $MovePos(this$static, num) { - if (num > 0) { - $Skip(this$static._matchFinder, num); - this$static._additionalOffset += num; - } - } - - function $ReadMatchDistances(this$static) { - var lenRes; - lenRes = 0; - this$static._numDistancePairs = $GetMatches(this$static._matchFinder, this$static._matchDistances); - if (this$static._numDistancePairs > 0) { - lenRes = this$static._matchDistances[this$static._numDistancePairs - 2]; - if (lenRes == this$static._numFastBytes) - lenRes += $GetMatchLen(this$static._matchFinder, lenRes - 1, this$static._matchDistances[this$static._numDistancePairs - 1], 273 - lenRes); - } - ++this$static._additionalOffset; - return lenRes; - } - - function $ReleaseMFStream(this$static) { - if (!!this$static._matchFinder && this$static._needReleaseMFStream) { - this$static._matchFinder._stream = null; - this$static._needReleaseMFStream = false; - } - } - - function $ReleaseStreams(this$static) { - $ReleaseMFStream(this$static); - this$static._rangeEncoder.Stream = null; - } - - function $SetDictionarySize_0(this$static, dictionarySize) { - var dicLogSize; - if (dictionarySize < 1 || dictionarySize > 536870912) { - return false; - } - this$static._dictionarySize = dictionarySize; - for (dicLogSize = 0; dictionarySize > 1 << dicLogSize; ++dicLogSize) { - } - this$static._distTableSize = dicLogSize * 2; - return true; - } - - function $SetLcLpPb_0(this$static, lc, lp, pb) { - if (lp < 0 || lp > 4 || lc < 0 || lc > 8 || pb < 0 || pb > 4) { - return false; - } - this$static._numLiteralPosStateBits = lp; - this$static._numLiteralContextBits = lc; - this$static._posStateBits = pb; - this$static._posStateMask = (1 << this$static._posStateBits) - 1; - return true; - } - - function $SetMatchFinder(this$static, matchFinderIndex) { - var matchFinderIndexPrev; - if (matchFinderIndex < 0 || matchFinderIndex > 2) { - return false; - } - matchFinderIndexPrev = this$static._matchFinderType; - this$static._matchFinderType = matchFinderIndex; - if (!!this$static._matchFinder && matchFinderIndexPrev != this$static._matchFinderType) { - this$static._dictionarySizePrev = -1; - this$static._matchFinder = null; - } - return true; - } - - function $SetNumFastBytes(this$static, numFastBytes) { - if (numFastBytes < 5 || numFastBytes > 273) { - return false; - } - this$static._numFastBytes = numFastBytes; - return true; - } - - function $WriteCoderProperties(this$static, outStream) { - var i; - this$static.properties[0] = (this$static._posStateBits * 5 + this$static._numLiteralPosStateBits) * 9 + this$static._numLiteralContextBits << 24 >> 24; - for (i = 0; i < 4; ++i) { - this$static.properties[1 + i] = this$static._dictionarySize >> 8 * i << 24 >> 24; - } - $write_0(outStream, this$static.properties, 0, 5); - } - - function $WriteEndMarker(this$static, posState) { - var lenToPosState; - if (!this$static._writeEndMark) { - return; - } - $Encode_3(this$static._rangeEncoder, this$static._isMatch, (this$static._state << 4) + posState, 1); - $Encode_3(this$static._rangeEncoder, this$static._isRep, this$static._state, 0); - this$static._state = this$static._state < 7?7:10; - $Encode_0(this$static._lenEncoder, this$static._rangeEncoder, 0, posState); - lenToPosState = GetLenToPosState(2); - $Encode_2(this$static._posSlotEncoder[lenToPosState], this$static._rangeEncoder, 63); - $EncodeDirectBits(this$static._rangeEncoder, 67108863, 26); - $ReverseEncode(this$static._posAlignEncoder, this$static._rangeEncoder, 15); - } - - function GetPosSlot(pos) { - if (pos < 2048) { - return g_FastPos[pos]; - } - if (pos < 2097152) { - return g_FastPos[pos >> 10] + 20; - } - return g_FastPos[pos >> 20] + 40; - } - - function GetPosSlot2(pos) { - if (pos < 131072) { - return g_FastPos[pos >> 6] + 12; - } - if (pos < 134217728) { - return g_FastPos[pos >> 16] + 32; - } - return g_FastPos[pos >> 26] + 52; - } - - function getClass_38() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Encoder_2_classLit; - } - - function Encoder() { - } - - _ = Encoder.prototype = new Object_0(); - _.getClass$ = getClass_38; - _.typeId$ = 0; - _._additionalOffset = 0; - _._alignPriceCount = 0; - _._dictionarySize = 4194304; - _._dictionarySizePrev = -1; - _._distTableSize = 44; - _._finished = false; - _._inStream = null; - _._longestMatchLength = 0; - _._longestMatchWasFound = false; - _._matchFinder = null; - _._matchFinderType = 1; - _._matchPriceCount = 0; - _._needReleaseMFStream = false; - _._numDistancePairs = 0; - _._numFastBytes = 32; - _._numFastBytesPrev = -1; - _._numLiteralContextBits = 3; - _._numLiteralPosStateBits = 0; - _._optimumCurrentIndex = 0; - _._optimumEndIndex = 0; - _._posStateBits = 2; - _._posStateMask = 3; - _._previousByte = 0; - _._state = 0; - _._writeEndMark = false; - _.backRes = 0; - _.nowPos64 = P0_longLit; - var g_FastPos; - function $Encode(this$static, rangeEncoder, symbol, posState) { - if (symbol < 8) { - $Encode_3(rangeEncoder, this$static._choice, 0, 0); - $Encode_2(this$static._lowCoder[posState], rangeEncoder, symbol); - } else { - symbol -= 8; - $Encode_3(rangeEncoder, this$static._choice, 0, 1); - if (symbol < 8) { - $Encode_3(rangeEncoder, this$static._choice, 1, 0); - $Encode_2(this$static._midCoder[posState], rangeEncoder, symbol); - } else { - $Encode_3(rangeEncoder, this$static._choice, 1, 1); - $Encode_2(this$static._highCoder, rangeEncoder, symbol - 8); - } - } - } - - function $Encoder$LenEncoder(this$static) { - var posState; - this$static._choice = initDim(_3S_classLit, 0, -1, 2, 1); - this$static._lowCoder = initDim(_3Lorg_dellroad_lzma_client_SevenZip_Compression_RangeCoder_BitTreeEncoder_2_classLit, 0, 8, 16, 0); - this$static._midCoder = initDim(_3Lorg_dellroad_lzma_client_SevenZip_Compression_RangeCoder_BitTreeEncoder_2_classLit, 0, 8, 16, 0); - this$static._highCoder = $BitTreeEncoder(new BitTreeEncoder(), 8); - for (posState = 0; posState < 16; ++posState) { - this$static._lowCoder[posState] = $BitTreeEncoder(new BitTreeEncoder(), 3); - this$static._midCoder[posState] = $BitTreeEncoder(new BitTreeEncoder(), 3); - } - return this$static; - } - - function $Init_2(this$static, numPosStates) { - var posState; - InitBitModels_0(this$static._choice); - for (posState = 0; posState < numPosStates; ++posState) { - InitBitModels(this$static._lowCoder[posState].Models); - InitBitModels(this$static._midCoder[posState].Models); - } - InitBitModels(this$static._highCoder.Models); - } - - function $SetPrices(this$static, posState, numSymbols, prices, st) { - var a0, a1, b0, b1, i; - a0 = ($clinit_66() , ProbPrices[this$static._choice[0] >>> 2]); - a1 = ProbPrices[2048 - this$static._choice[0] >>> 2]; - b0 = a1 + ProbPrices[this$static._choice[1] >>> 2]; - b1 = a1 + ProbPrices[2048 - this$static._choice[1] >>> 2]; - i = 0; - for (i = 0; i < 8; ++i) { - if (i >= numSymbols) - return; - prices[st + i] = a0 + $GetPrice_1(this$static._lowCoder[posState], i); - } - for (; i < 16; ++i) { - if (i >= numSymbols) - return; - prices[st + i] = b0 + $GetPrice_1(this$static._midCoder[posState], i - 8); - } - for (; i < numSymbols; ++i) { - prices[st + i] = b1 + $GetPrice_1(this$static._highCoder, i - 8 - 8); - } - } - - function getClass_33() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Encoder$LenEncoder_2_classLit; - } - - function Encoder$LenEncoder() { - } - - _ = Encoder$LenEncoder.prototype = new Object_0(); - _.getClass$ = getClass_33; - _.typeId$ = 0; - function $Encode_0(this$static, rangeEncoder, symbol, posState) { - $Encode(this$static, rangeEncoder, symbol, posState); - if (--this$static._counters[posState] == 0) { - $SetPrices(this$static, posState, this$static._tableSize, this$static._prices, posState * 272); - this$static._counters[posState] = this$static._tableSize; - } - } - - function $Encoder$LenPriceTableEncoder(this$static) { - $Encoder$LenEncoder(this$static); - this$static._prices = initDim(_3I_classLit, 0, -1, 4352, 1); - this$static._counters = initDim(_3I_classLit, 0, -1, 16, 1); - return this$static; - } - - function $GetPrice(this$static, symbol, posState) { - return this$static._prices[posState * 272 + symbol]; - } - - function $UpdateTables(this$static, numPosStates) { - var posState; - for (posState = 0; posState < numPosStates; ++posState) { - $SetPrices(this$static, posState, this$static._tableSize, this$static._prices, posState * 272); - this$static._counters[posState] = this$static._tableSize; - } - } - - function getClass_34() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Encoder$LenPriceTableEncoder_2_classLit; - } - - function Encoder$LenPriceTableEncoder() { - } - - _ = Encoder$LenPriceTableEncoder.prototype = new Encoder$LenEncoder(); - _.getClass$ = getClass_34; - _.typeId$ = 0; - _._tableSize = 0; - function $Create_1(this$static, numPosBits, numPrevBits) { - var i, numStates; - if (this$static.m_Coders != null && this$static.m_NumPrevBits == numPrevBits && this$static.m_NumPosBits == numPosBits) { - return; - } - this$static.m_NumPosBits = numPosBits; - this$static.m_PosMask = (1 << numPosBits) - 1; - this$static.m_NumPrevBits = numPrevBits; - numStates = 1 << this$static.m_NumPrevBits + this$static.m_NumPosBits; - this$static.m_Coders = initDim(_3Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Encoder$LiteralEncoder$Encoder2_2_classLit, 0, 5, numStates, 0); - for (i = 0; i < numStates; ++i) { - this$static.m_Coders[i] = $Encoder$LiteralEncoder$Encoder2(new Encoder$LiteralEncoder$Encoder2()); - } - } - - function $GetSubCoder(this$static, pos, prevByte) { - return this$static.m_Coders[((pos & this$static.m_PosMask) << this$static.m_NumPrevBits) + ((prevByte & 255) >>> 8 - this$static.m_NumPrevBits)]; - } - - function $Init_3(this$static) { - var i, numStates; - numStates = 1 << this$static.m_NumPrevBits + this$static.m_NumPosBits; - for (i = 0; i < numStates; ++i) { - InitBitModels_0(this$static.m_Coders[i].m_Encoders); - } - } - - function getClass_36() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Encoder$LiteralEncoder_2_classLit; - } - - function Encoder$LiteralEncoder() { - } - - _ = Encoder$LiteralEncoder.prototype = new Object_0(); - _.getClass$ = getClass_36; - _.typeId$ = 0; - _.m_Coders = null; - _.m_NumPosBits = 0; - _.m_NumPrevBits = 0; - _.m_PosMask = 0; - function $Encode_1(this$static, rangeEncoder, symbol) { - var bit, context, i; - context = 1; - for (i = 7; i >= 0; --i) { - bit = symbol >> i & 1; - $Encode_3(rangeEncoder, this$static.m_Encoders, context, bit); - context = context << 1 | bit; - } - } - - function $EncodeMatched(this$static, rangeEncoder, matchByte, symbol) { - var bit, context, i, matchBit, same, state; - context = 1; - same = true; - for (i = 7; i >= 0; --i) { - bit = symbol >> i & 1; - state = context; - if (same) { - matchBit = matchByte >> i & 1; - state += 1 + matchBit << 8; - same = matchBit == bit; - } - $Encode_3(rangeEncoder, this$static.m_Encoders, state, bit); - context = context << 1 | bit; - } - } - - function $Encoder$LiteralEncoder$Encoder2(this$static) { - this$static.m_Encoders = initDim(_3S_classLit, 0, -1, 768, 1); - return this$static; - } - - function $GetPrice_0(this$static, matchMode, matchByte, symbol) { - var bit, context, i, matchBit, price; - price = 0; - context = 1; - i = 7; - if (matchMode) { - for (; i >= 0; --i) { - matchBit = matchByte >> i & 1; - bit = symbol >> i & 1; - price += GetPrice(this$static.m_Encoders[(1 + matchBit << 8) + context], bit); - context = context << 1 | bit; - if (matchBit != bit) { - --i; - break; - } - } - } - for (; i >= 0; --i) { - bit = symbol >> i & 1; - price += GetPrice(this$static.m_Encoders[context], bit); - context = context << 1 | bit; - } - return price; - } - - function getClass_35() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Encoder$LiteralEncoder$Encoder2_2_classLit; - } - - function Encoder$LiteralEncoder$Encoder2() { - } - - _ = Encoder$LiteralEncoder$Encoder2.prototype = new Object_0(); - _.getClass$ = getClass_35; - _.typeId$ = 18; - function $MakeAsChar(this$static) { - this$static.BackPrev = -1; - this$static.Prev1IsChar = false; - } - - function $MakeAsShortRep(this$static) { - this$static.BackPrev = 0; - this$static.Prev1IsChar = false; - } - - function getClass_37() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Encoder$Optimal_2_classLit; - } - - function Encoder$Optimal() { - } - - _ = Encoder$Optimal.prototype = new Object_0(); - _.getClass$ = getClass_37; - _.typeId$ = 19; - _.BackPrev = 0; - _.BackPrev2 = 0; - _.Backs0 = 0; - _.Backs1 = 0; - _.Backs2 = 0; - _.Backs3 = 0; - _.PosPrev = 0; - _.PosPrev2 = 0; - _.Prev1IsChar = false; - _.Prev2 = false; - _.Price = 0; - _.State = 0; - function $BitTreeDecoder(this$static, numBitLevels) { - this$static.NumBitLevels = numBitLevels; - this$static.Models = initDim(_3S_classLit, 0, -1, 1 << numBitLevels, 1); - return this$static; - } - - function $Decode_0(this$static, rangeDecoder) { - var bitIndex, m; - m = 1; - for (bitIndex = this$static.NumBitLevels; bitIndex != 0; --bitIndex) { - m = (m << 1) + $DecodeBit(rangeDecoder, this$static.Models, m); - } - return m - (1 << this$static.NumBitLevels); - } - - function $ReverseDecode(this$static, rangeDecoder) { - var bit, bitIndex, m, symbol; - m = 1; - symbol = 0; - for (bitIndex = 0; bitIndex < this$static.NumBitLevels; ++bitIndex) { - bit = $DecodeBit(rangeDecoder, this$static.Models, m); - m <<= 1; - m += bit; - symbol |= bit << bitIndex; - } - return symbol; - } - - function ReverseDecode(Models, startIndex, rangeDecoder, NumBitLevels) { - var bit, bitIndex, m, symbol; - m = 1; - symbol = 0; - for (bitIndex = 0; bitIndex < NumBitLevels; ++bitIndex) { - bit = $DecodeBit(rangeDecoder, Models, startIndex + m); - m <<= 1; - m += bit; - symbol |= bit << bitIndex; - } - return symbol; - } - - function getClass_42() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_RangeCoder_BitTreeDecoder_2_classLit; - } - - function BitTreeDecoder() { - } - - _ = BitTreeDecoder.prototype = new Object_0(); - _.getClass$ = getClass_42; - _.typeId$ = 20; - _.Models = null; - _.NumBitLevels = 0; - function $BitTreeEncoder(this$static, numBitLevels) { - this$static.NumBitLevels = numBitLevels; - this$static.Models = initDim(_3S_classLit, 0, -1, 1 << numBitLevels, 1); - return this$static; - } - - function $Encode_2(this$static, rangeEncoder, symbol) { - var bit, bitIndex, m; - m = 1; - for (bitIndex = this$static.NumBitLevels; bitIndex != 0;) { - --bitIndex; - bit = symbol >>> bitIndex & 1; - $Encode_3(rangeEncoder, this$static.Models, m, bit); - m = m << 1 | bit; - } - } - - function $GetPrice_1(this$static, symbol) { - var bit, bitIndex, m, price; - price = 0; - m = 1; - for (bitIndex = this$static.NumBitLevels; bitIndex != 0;) { - --bitIndex; - bit = symbol >>> bitIndex & 1; - price += GetPrice(this$static.Models[m], bit); - m = (m << 1) + bit; - } - return price; - } - - function $ReverseEncode(this$static, rangeEncoder, symbol) { - var bit, i, m; - m = 1; - for (i = 0; i < this$static.NumBitLevels; ++i) { - bit = symbol & 1; - $Encode_3(rangeEncoder, this$static.Models, m, bit); - m = m << 1 | bit; - symbol >>= 1; - } - } - - function $ReverseGetPrice(this$static, symbol) { - var bit, i, m, price; - price = 0; - m = 1; - for (i = this$static.NumBitLevels; i != 0; --i) { - bit = symbol & 1; - symbol >>>= 1; - price += GetPrice(this$static.Models[m], bit); - m = m << 1 | bit; - } - return price; - } - - function ReverseEncode(Models, startIndex, rangeEncoder, NumBitLevels, symbol) { - var bit, i, m; - m = 1; - for (i = 0; i < NumBitLevels; ++i) { - bit = symbol & 1; - $Encode_3(rangeEncoder, Models, startIndex + m, bit); - m = m << 1 | bit; - symbol >>= 1; - } - } - - function ReverseGetPrice(Models, startIndex, NumBitLevels, symbol) { - var bit, i, m, price; - price = 0; - m = 1; - for (i = NumBitLevels; i != 0; --i) { - bit = symbol & 1; - symbol >>>= 1; - price += ($clinit_66() , ProbPrices[((Models[startIndex + m] - bit ^ -bit) & 2047) >>> 2]); - m = m << 1 | bit; - } - return price; - } - - function getClass_43() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_RangeCoder_BitTreeEncoder_2_classLit; - } - - function BitTreeEncoder() { - } - - _ = BitTreeEncoder.prototype = new Object_0(); - _.getClass$ = getClass_43; - _.typeId$ = 21; - _.Models = null; - _.NumBitLevels = 0; - function $DecodeBit(this$static, probs, index) { - var newBound, prob; - prob = probs[index]; - newBound = (this$static.Range >>> 11) * prob; - if ((this$static.Code ^ -2147483648) < (newBound ^ -2147483648)) { - this$static.Range = newBound; - probs[index] = prob + (2048 - prob >>> 5) << 16 >> 16; - if ((this$static.Range & -16777216) == 0) { - this$static.Code = this$static.Code << 8 | $read(this$static.Stream); - this$static.Range <<= 8; - } - return 0; - } else { - this$static.Range -= newBound; - this$static.Code -= newBound; - probs[index] = prob - (prob >>> 5) << 16 >> 16; - if ((this$static.Range & -16777216) == 0) { - this$static.Code = this$static.Code << 8 | $read(this$static.Stream); - this$static.Range <<= 8; - } - return 1; - } - } - - function $DecodeDirectBits(this$static, numTotalBits) { - var i, result, t; - result = 0; - for (i = numTotalBits; i != 0; --i) { - this$static.Range >>>= 1; - t = this$static.Code - this$static.Range >>> 31; - this$static.Code -= this$static.Range & t - 1; - result = result << 1 | 1 - t; - if ((this$static.Range & -16777216) == 0) { - this$static.Code = this$static.Code << 8 | $read(this$static.Stream); - this$static.Range <<= 8; - } - } - return result; - } - - function $Init_8(this$static) { - var i; - this$static.Code = 0; - this$static.Range = -1; - for (i = 0; i < 5; ++i) { - this$static.Code = this$static.Code << 8 | $read(this$static.Stream); - } - } - - function InitBitModels(probs) { - var i; - for (i = 0; i < probs.length; ++i) { - probs[i] = 1024; - } - } - - function getClass_44() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_RangeCoder_Decoder_2_classLit; - } - - function Decoder_0() { - } - - _ = Decoder_0.prototype = new Object_0(); - _.getClass$ = getClass_44; - _.typeId$ = 0; - _.Code = 0; - _.Range = 0; - _.Stream = null; - function $clinit_66() { - $clinit_66 = nullMethod; - var end, i, j, start; - ProbPrices = initDim(_3I_classLit, 0, -1, 512, 1); - for (i = 8; i >= 0; --i) { - start = 1 << 9 - i - 1; - end = 1 << 9 - i; - for (j = start; j < end; ++j) { - ProbPrices[j] = (i << 6) + (end - j << 6 >>> 9 - i - 1); - } - } - } - - function $Encode_3(this$static, probs, index, symbol) { - var newBound, prob; - prob = probs[index]; - newBound = (this$static.Range >>> 11) * prob; - if (symbol == 0) { - this$static.Range = newBound; - probs[index] = prob + (2048 - prob >>> 5) << 16 >> 16; - } else { - this$static.Low = add(this$static.Low, and(fromInt(newBound), Pffffffff_longLit)); - this$static.Range -= newBound; - probs[index] = prob - (prob >>> 5) << 16 >> 16; - } - if ((this$static.Range & -16777216) == 0) { - this$static.Range <<= 8; - $ShiftLow(this$static); - } - } - - function $EncodeDirectBits(this$static, v, numTotalBits) { - var i; - for (i = numTotalBits - 1; i >= 0; --i) { - this$static.Range >>>= 1; - if ((v >>> i & 1) == 1) { - this$static.Low = add(this$static.Low, fromInt(this$static.Range)); - } - if ((this$static.Range & -16777216) == 0) { - this$static.Range <<= 8; - $ShiftLow(this$static); - } - } - } - - function $FlushData(this$static) { - var i; - for (i = 0; i < 5; ++i) { - $ShiftLow(this$static); - } - } - - function $GetProcessedSizeAdd(this$static) { - return add(add(fromInt(this$static._cacheSize), this$static._position), P4_longLit); - } - - function $Init_9(this$static) { - this$static._position = P0_longLit; - this$static.Low = P0_longLit; - this$static.Range = -1; - this$static._cacheSize = 1; - this$static._cache = 0; - } - - function $ShiftLow(this$static) { - var LowHi, temp; - LowHi = lowBits_0(shru(this$static.Low, 32)); - if (LowHi != 0 || compare(this$static.Low, Pff000000_longLit) < 0) { - this$static._position = add(this$static._position, fromInt(this$static._cacheSize)); - temp = this$static._cache; - do { - $write(this$static.Stream, temp + LowHi); - temp = 255; - } while (--this$static._cacheSize != 0); - this$static._cache = lowBits_0(this$static.Low) >>> 24; - } - ++this$static._cacheSize; - this$static.Low = shl(and(this$static.Low, Pffffff_longLit), 8); - } - - function GetPrice(Prob, symbol) { - $clinit_66(); - return ProbPrices[((Prob - symbol ^ -symbol) & 2047) >>> 2]; - } - - function InitBitModels_0(probs) { - $clinit_66(); - var i; - for (i = 0; i < probs.length; ++i) { - probs[i] = 1024; - } - } - - function getClass_45() { - return Lorg_dellroad_lzma_client_SevenZip_Compression_RangeCoder_Encoder_2_classLit; - } - - function convert_binary_arr(arr) - { - var i; - - for (i = arr.length - 1; i >= 0; i -= 1) { - if (arr[i] < 0) { - arr[i] = 256 + arr[i]; - } - } - - return arr; - } - - function Encoder_0() { - } - - _ = Encoder_0.prototype = new Object_0(); - _.getClass$ = getClass_45; - _.typeId$ = 0; - _.Low = P0_longLit; - _.Range = 0; - _.Stream = null; - _._cache = 0; - _._cacheSize = 0; - _._position = P0_longLit; - var ProbPrices; - function decode(utf) { - var buf, i, x, y, z; - buf = $StringBuilder(new StringBuilder()); - for (i = 0; i < utf.length; ++i) { - x = utf[i] & 255; - if ((x & 128) == 0) { - if (x == 0) { - /// It appears that this is binary data, so it can't be converted to a string, so just send it back. - return convert_binary_arr(utf); - } - $appendNonNull(buf.data, String.fromCharCode(x & 65535)); - } else if ((x & 224) == 192) { - if (i + 1 >= utf.length) { - /// It appears that this is binary data, so it can't be converted to a string, so just send it back. - return convert_binary_arr(utf); - } - y = utf[++i] & 255; - if ((y & 192) != 128) { - /// It appears that this is binary data, so it can't be converted to a string, so just send it back. - return convert_binary_arr(utf); - } - $append(buf.data, String.fromCharCode((x & 31) << 6 & 65535 | y & 63)); - } else if ((x & 240) == 224) { - if (i + 2 >= utf.length) { - /// It appears that this is binary data, so it can't be converted to a string, so just send it back. - return convert_binary_arr(utf); - } - y = utf[++i] & 255; - if ((y & 192) != 128) { - /// It appears that this is binary data, so it can't be converted to a string, so just send it back. - return convert_binary_arr(utf); - } - z = utf[++i] & 255; - if ((z & 192) != 128) { - /// It appears that this is binary data, so it can't be converted to a string, so just send it back. - return convert_binary_arr(utf); - } - $appendNonNull(buf.data, String.fromCharCode(((x & 15) << 12 | (y & 63) << 6 | z & 63) & 65535)); - } else { - /// It appears that this is binary data, so it can't be converted to a string, so just send it back. - return convert_binary_arr(utf); - } - } - return $toString(buf.data); - } - - function encode(s) { - var ch, chars, data, elen, i, charArr, n; - chars = (n = s.length , charArr = initDim(_3C_classLit, 0, -1, n, 1) , $getChars(s, 0, n, charArr, 0) , charArr); - elen = 0; - for (i = 0; i < s.length; ++i) { - ch = chars[i]; - if (ch >= 1 && ch <= 127) { - ++elen; - } else if (ch == 0 || ch >= 128 && ch <= 2047) { - elen += 2; - } else { - elen += 3; - } - } - data = initDim(_3B_classLit, 0, -1, elen, 1); - elen = 0; - for (i = 0; i < s.length; ++i) { - ch = chars[i]; - if (ch >= 1 && ch <= 127) { - data[elen++] = ch << 24 >> 24; - } else if (ch == 0 || ch >= 128 && ch <= 2047) { - data[elen++] = (192 | ch >> 6 & 31) << 24 >> 24; - data[elen++] = (128 | ch & 63) << 24 >> 24; - } else { - data[elen++] = (224 | ch >> 12 & 15) << 24 >> 24; - data[elen++] = (128 | ch >> 6 & 63) << 24 >> 24; - data[elen++] = (128 | ch & 63) << 24 >> 24; - } - } - return data; - } - - function $LZMADemo(this$static) { - return this$static; - } - function toDouble(a) { - return a[1] + a[0]; - } - - function compress() { - var this$static = $LZMADemo(new LZMADemo()), - percent, - start, - /// Arguments - str = arguments[0], - mode = arguments[1], - callback_num, - on_finish, - on_progress; - - if (typeof arguments[2] === "function") { - on_finish = arguments[2]; - if (typeof arguments[3] === "function") { - on_progress = arguments[3]; - } - } else { - callback_num = arguments[2]; - } - - this$static.mode = get_mode_obj(mode); - - this$static.c = $LZMAByteArrayCompressor(new LZMAByteArrayCompressor(), encode(str), this$static.mode); - - if (on_progress) { - on_progress(0); - } else if (typeof callback_num !== "undefined") { - update_progress(0, callback_num); - } - - function do_action() { - var res; - start = (new Date).getTime(); - while ($execute(this$static.c)) { - percent = toDouble(this$static.c.chunker.inBytesProcessed) / toDouble(this$static.c.length_0); - /// If about 200 miliseconds have passed, update the progress. - if ((new Date).getTime() - start > 200) { - if (on_progress) { - on_progress(percent); - } else if (typeof callback_num !== "undefined") { - update_progress(percent, callback_num); - } - setTimeout(do_action, 0); - return false; - } - } - - if (on_progress) { - on_progress(1); - } else if (typeof callback_num !== "undefined") { - update_progress(1, callback_num); - } - - /// .slice(0) is required for Firefox 4.0 (because I think arrays are now passed by reference, which is not allowed when sending messages to or from web workers). - /// .slice(0) simply returns the entire array by value. - res = $toByteArray(this$static.c.output).slice(0); - - if (on_finish) { - on_finish(res); - } else if (typeof callback_num !== "undefined") { - postMessage({ - action: action_compress, - callback_num: callback_num, - result: res - }); - } - } - - setTimeout(do_action, 1); - } - - function decompress() { - var this$static = $LZMADemo(new LZMADemo()), - percent, - data, - start, - text, - /// Arguments - byte_arr = arguments[0], - callback_num, - on_finish, - on_progress, - sent_unknown, - has_progress; - - if (typeof arguments[1] === "function") { - on_finish = arguments[1]; - if (typeof arguments[2] === "function") { - on_progress = arguments[2]; - } - } else { - callback_num = arguments[1]; - } - - data = initValues(_3B_classLit, 0, -1, byte_arr); - - this$static.d = $LZMAByteArrayDecompressor(new LZMAByteArrayDecompressor(), data); - - if (on_progress) { - on_progress(0); - } else if (typeof callback_num !== "undefined") { - update_progress(0, callback_num); - } - - function do_action() { - var res; - - start = (new Date).getTime(); - - while ($execute_0(this$static.d)) { - if ((new Date).getTime() - start > 200) { - if (has_progress) { - percent = toDouble(this$static.d.chunker.decoder.nowPos64) / toDouble(this$static.d.length_0); - /// If about 200 miliseconds have passed, update the progress. - if (on_progress) { - on_progress(percent); - } else if (typeof callback_num !== "undefined") { - update_progress(percent, callback_num); - } - } else if (!sent_unknown) { - update_progress(-1, callback_num); - sent_unknown = true; - } - setTimeout(do_action, 0); - return false; - } - } - - if (on_progress) { - on_progress(1); - } else if (typeof callback_num !== "undefined") { - update_progress(1, callback_num); - } - - res = decode($toByteArray(this$static.d.output)); - - if (on_finish) { - on_finish(res); - } else if (typeof callback_num !== "undefined") { - postMessage({ - action: action_decompress, - callback_num: callback_num, - /// If the result is an array of integers (because it is binary), we need to use slice to make a copy of the data before it is returned from the Web Worker. - result: (typeof res !== "string" ? res.slice(0) : res) - }); - } - } - - has_progress = toDouble(this$static.d.length_0) > -1; - - setTimeout(do_action, 0); - } - - function $onModuleLoad(this$static) { - compress(this$static); - decompress(this$static); - } - - function getClass_46() { - return Lorg_dellroad_lzma_demo_client_LZMADemo_2_classLit; - } - - function LZMADemo () {} - - _ = LZMADemo.prototype = new Object_0(); - _.getClass$ = getClass_46; - _.typeId$ = 0; - _.c = null; - _.d = null; - var DEFAULT_COMPRESSION_MODE; - function init() { - !!$stats && $stats({moduleName:$moduleName, subSystem:'startup', evtGroup:'moduleStartup', millis:(new Date()).getTime(), type:'onModuleLoadStart', className:'org.dellroad.lzma.demo.client.LZMADemo'}); - } - - function gwtOnLoad(errFn, modName, modBase) { - $moduleName = modName; - $moduleBase = modBase; - if (errFn) { - try { - init(); - } - catch (e) { - errFn(modName); - } - } else { - init(); - } - } - - function nullMethod() { - } - - var Ljava_lang_Object_2_classLit = createForClass('java.lang.', 'Object'), - Ljava_lang_Throwable_2_classLit = createForClass('java.lang.', 'Throwable'), - Ljava_lang_Exception_2_classLit = createForClass('java.lang.', 'Exception'), - Ljava_lang_RuntimeException_2_classLit = createForClass('java.lang.', 'RuntimeException'), - Lcom_google_gwt_core_client_JavaScriptException_2_classLit = createForClass('com.google.gwt.core.client.', 'JavaScriptException'), - Lcom_google_gwt_core_client_JavaScriptObject_2_classLit = createForClass('com.google.gwt.core.client.', 'JavaScriptObject$'), _3_3D_classLit = createForArray('', '[[D'), - Ljava_io_InputStream_2_classLit = createForClass('java.io.', 'InputStream'), - Ljava_io_ByteArrayInputStream_2_classLit = createForClass('java.io.', 'ByteArrayInputStream'), _3B_classLit = createForArray('', '[B'), - Ljava_io_OutputStream_2_classLit = createForClass('java.io.', 'OutputStream'), - Ljava_io_ByteArrayOutputStream_2_classLit = createForClass('java.io.', 'ByteArrayOutputStream'), - Ljava_io_IOException_2_classLit = createForClass('java.io.', 'IOException'), - Ljava_lang_Enum_2_classLit = createForClass('java.lang.', 'Enum'), - Ljava_lang_ArithmeticException_2_classLit = createForClass('java.lang.', 'ArithmeticException'), - Ljava_lang_ArrayStoreException_2_classLit = createForClass('java.lang.', 'ArrayStoreException'), _3C_classLit = createForArray('', '[C'), - Ljava_lang_Class_2_classLit = createForClass('java.lang.', 'Class'), - Ljava_lang_ClassCastException_2_classLit = createForClass('java.lang.', 'ClassCastException'), - Ljava_lang_IllegalArgumentException_2_classLit = createForClass('java.lang.', 'IllegalArgumentException'), - Ljava_lang_IllegalStateException_2_classLit = createForClass('java.lang.', 'IllegalStateException'), - Ljava_lang_IndexOutOfBoundsException_2_classLit = createForClass('java.lang.', 'IndexOutOfBoundsException'), _3I_classLit = createForArray('', '[I'), - Ljava_lang_NullPointerException_2_classLit = createForClass('java.lang.', 'NullPointerException'), - Ljava_lang_String_2_classLit = createForClass('java.lang.', 'String'), - Ljava_lang_StringBuilder_2_classLit = createForClass('java.lang.', 'StringBuilder'), - Lorg_dellroad_lzma_client_SevenZip_Compression_LZ_InWindow_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.LZ.', 'InWindow'), - Lorg_dellroad_lzma_client_SevenZip_Compression_LZ_BinTree_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.LZ.', 'BinTree'), - Lorg_dellroad_lzma_client_SevenZip_Compression_LZ_OutWindow_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.LZ.', 'OutWindow'), - Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Chunker_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.LZMA.', 'Chunker'), _3S_classLit = createForArray('', '[S'), _3Lorg_dellroad_lzma_client_SevenZip_Compression_RangeCoder_BitTreeDecoder_2_classLit = createForArray('[Lorg.dellroad.lzma.client.SevenZip.Compression.RangeCoder.', 'BitTreeDecoder;'), - Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Decoder_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.LZMA.', 'Decoder'), - Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Decoder$LenDecoder_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.LZMA.', 'Decoder$LenDecoder'), _3Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Decoder$LiteralDecoder$Decoder2_2_classLit = createForArray('[Lorg.dellroad.lzma.client.SevenZip.Compression.LZMA.', 'Decoder$LiteralDecoder$Decoder2;'), - Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Decoder$LiteralDecoder_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.LZMA.', 'Decoder$LiteralDecoder'), - Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Decoder$LiteralDecoder$Decoder2_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.LZMA.', 'Decoder$LiteralDecoder$Decoder2'), _3Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Encoder$Optimal_2_classLit = createForArray('[Lorg.dellroad.lzma.client.SevenZip.Compression.LZMA.', 'Encoder$Optimal;'), _3Lorg_dellroad_lzma_client_SevenZip_Compression_RangeCoder_BitTreeEncoder_2_classLit = createForArray('[Lorg.dellroad.lzma.client.SevenZip.Compression.RangeCoder.', 'BitTreeEncoder;'), _3J_classLit = createForArray('', '[J'), _3Z_classLit = createForArray('', '[Z'), - Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Encoder_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.LZMA.', 'Encoder'), _3Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Encoder$LiteralEncoder$Encoder2_2_classLit = createForArray('[Lorg.dellroad.lzma.client.SevenZip.Compression.LZMA.', 'Encoder$LiteralEncoder$Encoder2;'), - Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Encoder$LiteralEncoder_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.LZMA.', 'Encoder$LiteralEncoder'), - Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Encoder$LiteralEncoder$Encoder2_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.LZMA.', 'Encoder$LiteralEncoder$Encoder2'), - Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Encoder$LenEncoder_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.LZMA.', 'Encoder$LenEncoder'), - Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Encoder$LenPriceTableEncoder_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.LZMA.', 'Encoder$LenPriceTableEncoder'), - Lorg_dellroad_lzma_client_SevenZip_Compression_LZMA_Encoder$Optimal_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.LZMA.', 'Encoder$Optimal'), - Lorg_dellroad_lzma_client_SevenZip_Compression_RangeCoder_BitTreeDecoder_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.RangeCoder.', 'BitTreeDecoder'), - Lorg_dellroad_lzma_client_SevenZip_Compression_RangeCoder_BitTreeEncoder_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.RangeCoder.', 'BitTreeEncoder'), - Lorg_dellroad_lzma_client_SevenZip_Compression_RangeCoder_Decoder_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.RangeCoder.', 'Decoder'), - Lorg_dellroad_lzma_client_SevenZip_Compression_RangeCoder_Encoder_2_classLit = createForClass('org.dellroad.lzma.client.SevenZip.Compression.RangeCoder.', 'Encoder'), - Lorg_dellroad_lzma_client_CompressionMode_2_classLit = createForEnum('org.dellroad.lzma.client.', 'CompressionMode'), - Lorg_dellroad_lzma_client_LZMACompressor_2_classLit = createForClass('org.dellroad.lzma.client.', 'LZMACompressor'), - Lorg_dellroad_lzma_client_LZMAByteArrayCompressor_2_classLit = createForClass('org.dellroad.lzma.client.', 'LZMAByteArrayCompressor'), - Lorg_dellroad_lzma_client_LZMADecompressor_2_classLit = createForClass('org.dellroad.lzma.client.', 'LZMADecompressor'), - Lorg_dellroad_lzma_client_LZMAByteArrayDecompressor_2_classLit = createForClass('org.dellroad.lzma.client.', 'LZMAByteArrayDecompressor'), - Lorg_dellroad_lzma_demo_client_LZMADemo_2_classLit = createForClass('org.dellroad.lzma.demo.client.', 'LZMADemo'); - - gwtOnLoad(function() {},'lzma_demo',''); - - - var get_mode_obj = (function () { - var modes = [ - {dictionarySize: 16, fb: 64, matchFinder: 0, lc: 3, lp: 0, pb: 2}, - {dictionarySize: 20, fb: 64, matchFinder: 0, lc: 3, lp: 0, pb: 2}, - {dictionarySize: 19, fb: 64, matchFinder: 1, lc: 3, lp: 0, pb: 2}, - {dictionarySize: 20, fb: 64, matchFinder: 1, lc: 3, lp: 0, pb: 2}, - {dictionarySize: 21, fb: 128, matchFinder: 1, lc: 3, lp: 0, pb: 2}, - {dictionarySize: 22, fb: 128, matchFinder: 1, lc: 3, lp: 0, pb: 2}, - {dictionarySize: 23, fb: 128, matchFinder: 1, lc: 3, lp: 0, pb: 2}, - {dictionarySize: 24, fb: 255, matchFinder: 1, lc: 3, lp: 0, pb: 2}, - {dictionarySize: 25, fb: 255, matchFinder: 1, lc: 3, lp: 0, pb: 2} - ]; - - function isNumber(n) { - return !isNaN(parseFloat(n)) && isFinite(n); - } - - return function (mode) { - if (!isNumber(mode)) { - mode = 1; - } else { - if (mode < 1) { - mode = 1; - } else if (mode > 9) { - mode = 9; - } - } - - return modes[mode - 1]; - } - }()); - - /// Are we in a Web Worker? - /// This seems to be the most reliable way to detect this. - if (typeof onmessage !== "undefined" && (typeof window === "undefined" || typeof window.document === "undefined")) { - (function create_onmessage() { - /// Create the global onmessage function. - onmessage = function (e) { - if (e && e.data) { - if (e.data.action === action_compress) { - LZMA.compress(e.data.data, e.data.mode, e.data.callback_num); - } else if (e.data.action === action_decompress) { - LZMA.decompress(e.data.data, e.data.callback_num); - } - } - } - }()); - } - - return { - compress: compress, - decompress: decompress - }; -}()); - -/// Allow Node.js to be able to access this directly if it is included directly. -this.LZMA = LZMA; - -/// This is used by browsers that do not support web workers. -this.LZMA_WORKER = LZMA; diff --git a/web/static/js9_old/plugins/fitsy/pako_inflate.min.js b/web/static/js9_old/plugins/fitsy/pako_inflate.min.js deleted file mode 100644 index 0abc5cf55cbb6ae642a4f49f38993cb6f87cf472..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/fitsy/pako_inflate.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/* pako 0.1.1 nodeca/pako */ -!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var t;"undefined"!=typeof window?t=window:"undefined"!=typeof global?t=global:"undefined"!=typeof self&&(t=self),t.pako=e()}}(function(){return function e(t,i,n){function a(r,o){if(!i[r]){if(!t[r]){var d="function"==typeof require&&require;if(!o&&d)return d(r,!0);if(s)return s(r,!0);throw new Error("Cannot find module '"+r+"'")}var f=i[r]={exports:{}};t[r][0].call(f.exports,function(e){var i=t[r][1][e];return a(i?i:e)},f,f.exports,e,t,i,n)}return i[r].exports}for(var s="function"==typeof require&&require,r=0;r=0&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(t.windowBits>=0&&t.windowBits<16)||e&&e.windowBits||(t.windowBits+=32),t.windowBits>15&&t.windowBits<48&&0===(15&t.windowBits)&&(t.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new f;var i=s.inflateInit2(this.strm,t.windowBits);if(i!==o.Z_OK)throw new Error(d[i])};l.prototype.push=function(e,t){var i,n,a=this.strm,d=this.options.chunkSize;if(this.ended)return!1;n=o.Z_NO_FLUSH,a.next_in=e,a.next_in_index=0,a.avail_in=a.next_in.length,a.next_out=new r.Buf8(d);do{if(a.avail_out=this.options.chunkSize,a.next_out_index=0,i=s.inflate(a,n),i!==o.Z_STREAM_END&&i!==o.Z_OK)return this.onEnd(i),this.ended=!0,!1;a.next_out_index&&(this.onData(r.shrinkBuf(a.next_out,a.next_out_index)),(a.avail_in>0||0===a.avail_out)&&(a.next_out=new r.Buf8(this.options.chunkSize)))}while(a.avail_in>0||0===a.avail_out);return n=t===~~t?t:t===!0?o.Z_FINISH:o.Z_NO_FLUSH,n===o.Z_FINISH?(i=s.inflateEnd(this.strm),this.onEnd(i),this.ended=!0,i===o.Z_OK):!0},l.prototype.onData=function(e){this.chunks.push(e)},l.prototype.onEnd=function(e){e===o.Z_OK&&(this.result=r.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg},i.Inflate=l,i.inflate=n,i.inflateRaw=a},{"./zlib/constants":3,"./zlib/inflate.js":6,"./zlib/messages":8,"./zlib/utils":9,"./zlib/zstream":10}],2:[function(e,t){"use strict";function i(e,t,i,n){for(var a=65535&e|0,s=e>>>16&65535|0,r=0;0!==i;){r=i>2e3?2e3:i,i-=r;do a=a+t[n++]|0,s=s+a|0;while(--r);a%=65521,s%=65521}return a|s<<16|0}t.exports=i},{}],3:[function(e,t){t.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],4:[function(e,t){"use strict";function i(){for(var e,t=[],i=0;256>i;i++){e=i;for(var n=0;8>n;n++)e=1&e?3988292384^e>>>1:e>>>1;t[i]=e}return t}function n(e,t,i,n){var s=a,r=n+i;e=-1^e;for(var o=n;r>o;o++)e=e>>>8^s[255&(e^t[o])];return-1^e}var a=i();t.exports=n},{}],5:[function(e,t){"use strict";var i=30,n=12;t.exports=function(e,t){var a,s,r,o,d,f,l,c,h,u,w,b,_,k,m,x,v,g,p,y,B,E,S,Z,z;a=e.state,s=e.next_in_index,Z=e.next_in,r=s+(e.avail_in-5),o=e.next_out_index,z=e.next_out,d=o-(t-e.avail_out),f=o+(e.avail_out-257),l=a.dmax,c=a.wsize,h=a.whave,u=a.wnext,w=a.window,b=a.hold,_=a.bits,k=a.lencode,m=a.distcode,x=(1<_&&(b+=Z[s++]<<_,_+=8,b+=Z[s++]<<_,_+=8),g=k[b&x];t:for(;;){if(p=g>>>24,b>>>=p,_-=p,p=g>>>16&255,0===p)z[o++]=65535&g;else{if(!(16&p)){if(0===(64&p)){g=k[(65535&g)+(b&(1<_&&(b+=Z[s++]<<_,_+=8),y+=b&(1<>>=p,_-=p),15>_&&(b+=Z[s++]<<_,_+=8,b+=Z[s++]<<_,_+=8),g=m[b&v];i:for(;;){if(p=g>>>24,b>>>=p,_-=p,p=g>>>16&255,!(16&p)){if(0===(64&p)){g=m[(65535&g)+(b&(1<_&&(b+=Z[s++]<<_,_+=8,p>_&&(b+=Z[s++]<<_,_+=8)),B+=b&(1<l){e.msg="invalid distance too far back",a.mode=i;break e}if(b>>>=p,_-=p,p=o-d,B>p){if(p=B-p,p>h&&a.sane){e.msg="invalid distance too far back",a.mode=i;break e}if(E=0,S=w,0===u){if(E+=c-p,y>p){y-=p;do z[o++]=w[E++];while(--p);E=o-B,S=z}}else if(p>u){if(E+=c+u-p,p-=u,y>p){y-=p;do z[o++]=w[E++];while(--p);if(E=0,y>u){p=u,y-=p;do z[o++]=w[E++];while(--p);E=o-B,S=z}}}else if(E+=u-p,y>p){y-=p;do z[o++]=w[E++];while(--p);E=o-B,S=z}for(;y>2;)z[o++]=S[E++],z[o++]=S[E++],z[o++]=S[E++],y-=3;y&&(z[o++]=S[E++],y>1&&(z[o++]=S[E++]))}else{E=o-B;do z[o++]=z[E++],z[o++]=z[E++],z[o++]=z[E++],y-=3;while(y>2);y&&(z[o++]=z[E++],y>1&&(z[o++]=z[E++]))}break}}break}}while(r>s&&f>o);y=_>>3,s-=y,_-=y<<3,b&=(1<<_)-1,e.next_in_index=s,e.next_out_index=o,e.avail_in=r>s?5+(r-s):5-(s-r),e.avail_out=f>o?257+(f-o):257-(o-f),a.hold=b,a.bits=_}},{}],6:[function(e,t,i){"use strict";function n(e){return(e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function a(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.next_index=0,this.lens=new m.Buf16(320),this.work=new m.Buf16(288),this.codes=new m.Buf32(kt),this.sane=0,this.back=0,this.was=0}function s(e,t,i,n,a,s,r,o){this.type=e,this.lens=t,this.lens_index=i,this.codes=n,this.table=a,this.table_index=s,this.bits=r,this.work=o}function r(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,t.wrap&&(e.adler=1&t.wrap),t.mode=L,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=new m.Buf32(kt),t.distcode=new m.Buf32(kt),t.sane=1,t.back=-1,R):N}function o(e){var t;return e&&e.state?(t=e.state,t.wsize=0,t.whave=0,t.wnext=0,r(e)):N}function d(e,t){var i,n;return e&&e.state?(n=e.state,0>t?(i=0,t=-t):(i=(t>>4)+1,48>t&&(t&=15)),t&&(8>t||t>15)?N:(null!==n.window&&n.wbits!==t&&(n.window=null),n.wrap=i,n.wbits=t,o(e))):N}function f(e,t){var i,n;return e?(n=new a,e.state=n,n.window=null,i=d(e,t),i!==R&&(e.state=null),i):N}function l(e){return f(e,xt)}function c(e,t,i){var n;return e&&e.state?(n=e.state,0>t?(n.hold=0,n.bits=0,R):t>16||n.bits+t>32?N:(i&=(1<t;)e.lens[t++]=8;for(;256>t;)e.lens[t++]=9;for(;280>t;)e.lens[t++]=7;for(;288>t;)e.lens[t++]=8;for(i=9,p(new s(B,e.lens,0,288,_,0,i,e.work)),t=0;32>t;)e.lens[t++]=5;i=5,p(new s(E,e.lens,0,32,k,0,i,e.work)),vt=!1}e.lencode=_,e.lenbits=9,e.distcode=k,e.distbits=5}function u(e,t,i,n){var a,s=e.state;return null===s.window&&(s.wsize=1<=s.wsize?(m.arraySet(s.window,t,i-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):(a=s.wsize-s.wnext,a>n&&(a=n),m.arraySet(s.window,t,i-n,a,s.wnext),n-=a,n?(m.arraySet(s.window,t,i-n,n,0),s.wnext=n,s.whave=s.wsize):(s.wnext+=a,s.wnext===s.wsize&&(s.wnext=0),s.whavew;){if(0===f)break e;f--,c+=a[o++]<>>8&255,i.check=v(i.check,zt,2,0),c=0,w=0,i.mode=D;break}if(i.flags=0,i.head&&(i.head.done=-1),!(1&i.wrap)||(((255&c)<<8)+(c>>8))%31){e.msg="incorrect header check",i.mode=ht;break}if((15&c)!==U){e.msg="unknown compression method",i.mode=ht;break}if(c>>>=4,w-=4,yt=(15&c)+8,0===i.wbits)i.wbits=yt;else if(yt>i.wbits){e.msg="invalid window size",i.mode=ht;break}i.dmax=1<w;){if(0===f)break e;f--,c+=a[o++]<>8&1),512&i.flags&&(zt[0]=255&c,zt[1]=c>>>8&255,i.check=v(i.check,zt,2,0)),c=0,w=0,i.mode=C;case C:for(;32>w;){if(0===f)break e;f--,c+=a[o++]<>>8&255,zt[2]=c>>>16&255,zt[3]=c>>>24&255,i.check=v(i.check,zt,4,0)),c=0,w=0,i.mode=H;case H:for(;16>w;){if(0===f)break e;f--,c+=a[o++]<>8),512&i.flags&&(zt[0]=255&c,zt[1]=c>>>8&255,i.check=v(i.check,zt,2,0)),c=0,w=0,i.mode=K;case K:if(1024&i.flags){for(;16>w;){if(0===f)break e;f--,c+=a[o++]<>>8&255,i.check=v(i.check,zt,2,0)),c=0,w=0}else i.head&&(i.head.extra=null);i.mode=M;case M:if(1024&i.flags){if(k=i.length,k>f&&(k=f),k){if(i.head&&i.head.extra)throw yt=i.head.extra_len-i.length,"Review & implement right";512&i.flags&&(i.check=v(i.check,a,k,o)),f-=k,o+=k,i.length-=k}if(i.length)break e}i.length=0,i.mode=P;case P:if(2048&i.flags){if(0===f)break e;k=0;do yt=a[o+k++],i.head&&i.head.name&&i.lengthk);if(512&i.flags&&(i.check=v(i.check,a,k,o)),f-=k,o+=k,yt)break e}else i.head&&(i.head.name=null);i.length=0,i.mode=j;case j:if(4096&i.flags){if(0===f)break e;k=0;do yt=a[o+k++],i.head&&i.head.comment&&i.lengthk);if(512&i.flags&&(i.check=v(i.check,a,k,o)),f-=k,o+=k,yt)break e}else i.head&&(i.head.comment=null);i.mode=q;case q:if(512&i.flags){for(;16>w;){if(0===f)break e;f--,c+=a[o++]<>9&1,i.head.done=1),e.adler=i.check=0,i.mode=G;break;case Y:for(;32>w;){if(0===f)break e;f--,c+=a[o++]<>>=7&w,w-=7&w,i.mode=ft;break}for(;3>w;){if(0===f)break e;f--,c+=a[o++]<>>=1,w-=1,3&c){case 0:i.mode=J;break;case 1:if(h(i),i.mode=it,t===z){c>>>=2,w-=2;break e}break;case 2:i.mode=$;break;case 3:e.msg="invalid block type",i.mode=ht}c>>>=2,w-=2;break;case J:for(c>>>=7&w,w-=7&w;32>w;){if(0===f)break e;f--,c+=a[o++]<>>16^65535)){e.msg="invalid stored block lengths",i.mode=ht;break}if(i.length=65535&c,c=0,w=0,i.mode=Q,t===z)break e;case Q:i.mode=V;case V:if(k=i.length){if(k>f&&(k=f),k>l&&(k=l),0===k)break e;m.arraySet(r,a,o,k,d),f-=k,o+=k,l-=k,d+=k,i.length-=k;break}i.mode=G;break;case $:for(;14>w;){if(0===f)break e;f--,c+=a[o++]<>>=5,w-=5,i.ndist=(31&c)+1,c>>>=5,w-=5,i.ncode=(15&c)+4,c>>>=4,w-=4,i.nlen>286||i.ndist>30){e.msg="too many length or distance symbols",i.mode=ht;break}i.have=0,i.mode=et;case et:for(;i.havew;){if(0===f)break e;f--,c+=a[o++]<>>=3,w-=3}for(;i.have<19;)i.lens[Rt[i.have++]]=0;if(m.arraySet(i.lencode,i.codes,0,i.codes.length,0),i.lenbits=7,Et=new s(y,i.lens,0,19,i.lencode,0,i.lenbits,i.work),Bt=p(Et),i.lenbits=Et.bits,Bt){e.msg="invalid code lengths set",i.mode=ht;break}i.have=0,i.mode=tt;case tt:for(;i.have>>24,mt=Zt>>>16&255,xt=65535&Zt,!(w>=kt);){if(0===f)break e;f--,c+=a[o++]<xt)c>>>=kt,w-=kt,i.lens[i.have++]=xt;else{if(16===xt){for(St=kt+2;St>w;){if(0===f)break e;f--,c+=a[o++]<>>=kt,w-=kt,0===i.have){e.msg="invalid bit length repeat",i.mode=ht;break}yt=i.lens[i.have-1],k=3+(3&c),c>>>=2,w-=2}else if(17===xt){for(St=kt+3;St>w;){if(0===f)break e;f--,c+=a[o++]<>>=kt,w-=kt,yt=0,k=3+(7&c),c>>>=3,w-=3}else{for(St=kt+7;St>w;){if(0===f)break e;f--,c+=a[o++]<>>=kt,w-=kt,yt=0,k=11+(127&c),c>>>=7,w-=7}if(i.have+k>i.nlen+i.ndist){e.msg="invalid bit length repeat",i.mode=ht;break}for(;k--;)i.lens[i.have++]=yt}}if(i.mode===ht)break;if(0===i.lens[256]){e.msg="invalid code -- missing end-of-block",i.mode=ht;break}if(m.arraySet(i.lencode,i.codes,0,i.codes.length,0),i.lenbits=9,Et=new s(B,i.lens,0,i.nlen,i.lencode,0,i.lenbits,i.work),Bt=p(Et),i.lenbits=Et.bits,Bt){e.msg="invalid literal/lengths set",i.mode=ht;break}if(i.distbits=6,m.arraySet(i.distcode,i.codes,0,i.codes.length,0),Et=new s(E,i.lens,i.nlen,i.ndist,i.distcode,0,i.distbits,i.work),Bt=p(Et),i.distbits=Et.bits,Bt){e.msg="invalid distances set",i.mode=ht;break}if(i.mode=it,t===z)break e;case it:i.mode=nt;case nt:if(f>=6&&l>=258){e.next_out_index=d,e.avail_out=l,e.next_in_index=o,e.avail_in=f,i.hold=c,i.bits=w,g(e,_),d=e.next_out_index,r=e.next_out,l=e.avail_out,o=e.next_in_index,a=e.next_in,f=e.avail_in,c=i.hold,w=i.bits,i.mode===G&&(i.back=-1);break}for(i.back=0;Zt=i.lencode[c&(1<>>24,mt=Zt>>>16&255,xt=65535&Zt,!(w>=kt);){if(0===f)break e;f--,c+=a[o++]<>vt)],kt=Zt>>>24,mt=Zt>>>16&255,xt=65535&Zt,!(w>=vt+kt);){if(0===f)break e;f--,c+=a[o++]<>>=vt,w-=vt,i.back+=vt}if(c>>>=kt,w-=kt,i.back+=kt,i.length=xt,0===mt){i.mode=dt;break}if(32&mt){i.back=-1,i.mode=G;break}if(64&mt){e.msg="invalid literal/length code",i.mode=ht;break}i.extra=15&mt,i.mode=at;case at:if(i.extra){for(St=i.extra;St>w;){if(0===f)break e;f--,c+=a[o++]<>>=i.extra,w-=i.extra,i.back+=i.extra}i.was=i.length,i.mode=st;case st:for(;Zt=i.distcode[c&(1<>>24,mt=Zt>>>16&255,xt=65535&Zt,!(w>=kt);){if(0===f)break e;f--,c+=a[o++]<>vt)],kt=Zt>>>24,mt=Zt>>>16&255,xt=65535&Zt,!(w>=vt+kt);){if(0===f)break e;f--,c+=a[o++]<>>=vt,w-=vt,i.back+=vt}if(c>>>=kt,w-=kt,i.back+=kt,64&mt){e.msg="invalid distance code",i.mode=ht;break}i.offset=xt,i.extra=15&mt,i.mode=rt;case rt:if(i.extra){for(St=i.extra;St>w;){if(0===f)break e;f--,c+=a[o++]<>>=i.extra,w-=i.extra,i.back+=i.extra}if(i.offset>i.dmax){e.msg="invalid distance too far back",i.mode=ht;break}i.mode=ot;case ot:if(0===l)break e;if(k=_-l,i.offset>k){if(k=i.offset-k,k>i.whave&&i.sane){e.msg="invalid distance too far back",i.mode=ht;break}k>i.wnext?(k-=i.wnext,bt=i.wsize-k):bt=i.wnext-k,k>i.length&&(k=i.length),_t=i.window}else _t=r,bt=d-i.offset,k=i.length;k>l&&(k=l),l-=k,i.length-=k;do r[d++]=_t[bt++];while(--k);0===i.length&&(i.mode=nt);break;case dt:if(0===l)break e;r[d++]=i.length,l--,i.mode=nt;break;case ft:if(i.wrap){for(;32>w;){if(0===f)break e;f--,c|=a[o++]<w;){if(0===f)break e;f--,c+=a[o++]<=Z;Z++)C[Z]=0;for(z=0;y>z;z++)C[p[e.lens_index+z]]++;for(O=E,A=n;A>=1&&0===C[A];A--);if(O>A&&(O=A),0===A)return B[e.table_index++]=20971520,B[e.table_index++]=20971520,e.bits=1,0;for(R=1;A>R&&0===C[R];R++);for(R>O&&(O=R),T=1,Z=1;n>=Z;Z++)if(T<<=1,T-=C[Z],0>T)return-1;if(T>0&&(g===r||1!==A))return-1;for(H[1]=0,Z=1;n>Z;Z++)H[Z+1]=H[Z]+C[Z];for(z=0;y>z;z++)0!==p[e.lens_index+z]&&(S[H[p[e.lens_index+z]]++]=z);switch(g){case r:L=K=S,k=19;break;case o:L=f,D-=257,K=l,M-=257,k=256;break;default:L=c,K=h,k=-1}if(U=0,z=0,Z=R,_=e.table_index,N=O,I=0,w=-1,F=1<a||g===d&&F>s)return 1;for(var P=0;;){P++,m=Z-I,S[z]k?(x=K[M+S[z]],v=L[D+S[z]]):(x=96,v=0),t=1<>I)+u]=m<<24|x<<16|v|0;while(0!==u);for(t=1<>=1;if(0!==t?(U&=t-1,U+=t):U=0,z++,0===--C[Z]){if(Z===A)break;Z=p[e.lens_index+S[z]]}if(Z>O&&(U&b)!==w){for(0===I&&(I=O),_+=R,N=Z-I,T=1<N+I&&(T-=C[N+I],!(0>=T));)N++,T<<=1;if(F+=1<a||g===d&&F>s)return 1;w=U&b,B[w]=O<<24|N<<16|_-e.table_index}}return 0!==U&&(B[_+U]=Z-I<<24|64<<16|0),e.table_index+=F,e.bits=O,0}},{"./utils":9}],8:[function(e,t){"use strict";t.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],9:[function(e,t,i){"use strict";var n="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;i.assign=function(e){for(var t=Array.prototype.slice.call(arguments,1);t.length;){var i=t.shift();if(i){if("object"!=typeof i)throw new TypeError(i+"must be non-object");for(var n in i)i.hasOwnProperty(n)&&(e[n]=i[n])}}return e},i.shrinkBuf=function(e,t){return e.length===t?e:e.subarray?e.subarray(0,t):(e.length=t,e)};var a={arraySet:function(e,t,i,n,a){if(t.subarray)return void e.set(t.subarray(i,i+n),a);for(var s=0;n>s;s++)e[a+s]=t[i+s]},flattenChunks:function(e){var t,i,n,a,s,r;for(n=0,t=0,i=e.length;i>t;t++)n+=e[t].length;for(r=new Uint8Array(n),a=0,t=0,i=e.length;i>t;t++)s=e[t],r.set(s,a),a+=s.length;return r}},s={arraySet:function(e,t,i,n,a){for(var s=0;n>s;s++)e[a+s]=t[i+s]},flattenChunks:function(e){return[].concat.apply([],e)}};i.setTyped=function(e){e?(i.Buf8=Uint8Array,i.Buf16=Uint16Array,i.Buf32=Int32Array,i.assign(i,a)):(i.Buf8=Array,i.Buf16=Array,i.Buf32=Array,i.assign(i,s))},i.setTyped(n)},{}],10:[function(e,t){"use strict";function i(){this.next_in=null,this.next_in_index=0,this.avail_in=0,this.total_in=0,this.next_out=null,this.next_out_index=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}t.exports=i},{}]},{},[1])(1)}); \ No newline at end of file diff --git a/web/static/js9_old/plugins/help/blend.html b/web/static/js9_old/plugins/help/blend.html deleted file mode 100644 index 1db6a838a4d07211f2eb304bf8c58e644a556de0..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/blend.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - - -Plugin: JS9Blend - - - -
    -

    JS9 Image Blending

    - -

    -The Image Blending plugin allows you to combine selected images -using a specified blend mode and optional opacity. Blend modes are -different ways in which the colors of individual pixels are -combined between a source and background image. For example, -the multiply mode multiplies the color value of the source -pixel by the color value of the background pixel and uses the -resulting (scaled) value for the color: -

    -    x = a * b
    -
    -Multiplying white (value 1) by any other color results in the latter -color being used. Multiplying black (value 0) by any other color -results in black being used. Thus, multiply makes whites -transparent but otherwise darkens the image. - -

    -One of the most useful blend modes for astronomy is screen, which is -the opposite of multiply: white pixels are made opaque, black pixels -become transparent, and other pixels are lightened. The blend algorithm -multiplies inverses and takes the inverse of the result: -

    -    x = 1 − ((1 − a) × (1 − b))
    -
    - -

    -Standard blend modes supported by modern Web browsers are documented in - -W3C Compositing and Blending, which includes algorithms and examples -for each mode. - -

    -The Image Blending plugin allows you to toggle global image blending -on and off, so that you can switch between blending and the ordinary display -of a single image. By default, when the plugin is displayed, blending is -turned on. - -

    -Each image loaded into the display will be shown in a stack. -The currently active image will be displayed with a green border. -This is the image that responds to contrast/bias changes, region -creation, etc. It also is the image on which browser-based analysis -and server-based analysis is performed. You can click on any image -in the stack to make it the current image. - -

    -If you have two or more observations of the same object displayed, you -probably will want to align them by WCS coordinates. This can be done by -utilizing the WCS->reproject menu option, which uses the WCS of one -image to reproject the other into a new raw data layer. - -

    -Once two or more images are aligned, you can change the colormap, -contrast/bias and scaling of each of them separately and then combine -them into a single display. This is done by clicking the blend -using button to add this image to the blend list, and the choosing -its blend mode and optional opacity. You can continue to change the -colormap, scale, contrast/bias, etc. of the current image even after -blending has been turned on. - -

    -Note that some, but not all, blend modes are commutative. In particular, -the non-separable blend modes (hue, saturation, -color, and luminosity) are all order-dependent. In such -cases, you can change the stacking order simply by dragging an image -into the appropriate place on the stack. -

    - - diff --git a/web/static/js9_old/plugins/help/blink.html b/web/static/js9_old/plugins/help/blink.html deleted file mode 100644 index 3012aa2b4fefcaa96a560b92f50dbf4e8c0bd85b..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/blink.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - -Plugin: JS9Blink - - - -
    -

    JS9 Image Blinking

    - -

    -The Image Blinking plugin allows you repeatedly to display a -sequence of selected images at the specified blink rate. You also can -blink selected images manually. - -

    -The Blink Images option turns on image blinking for all images -that have their own blink option set. (Thus, it is not -necessary to blink all of the loaded images.) The blink rate -menu option allows you to choose the rate of re-display, with values -ranging from 0.1 seconds to 30 seconds. The default is 1 second. You -also can click the blink manually button to display the next -image in the stack. - -

    -The blink sequence follows the order of the images listed in the image -stack. This order can be changed by moving images up and down the stack. -Note that the currently active image will be displayed with a green -border. This is the image that responds to contrast/bias changes, -region creation, etc. -

    - - diff --git a/web/static/js9_old/plugins/help/cmaps.html b/web/static/js9_old/plugins/help/cmaps.html deleted file mode 100644 index 717ea1d6e635d7a25e5ae0a9f37aaced17ef3aaf..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/cmaps.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - - -Plugin: JS9Cmaps - - - -
    -

    Create Colormaps

    - -

    -The Colormaps plugin allows you to create compatible colormaps -using a base color or an existing colormap. You can choose -the number of colormaps to create, the algorithm used to create the -new colormaps, and whether to apply them to existing images. - -

    -In order to give more control over colormap creation, the plugin -allows you to specify a number of slices into which the 360 -degree colorwheel will be divided, starting with the base color. -The n created colormaps are then assigned to the first n slices of -the colorwheel. For example, if you choose to create three slices and -three colormaps, each colormap will be separated from the others by -120 degrees (1/3 of the colorwheel). If you create six slices and three -colormaps, each colormap will be separated by 60 degrees (1/6 of the -colorwheel), starting from the base color. - -

    -The algorithms for generating new colormaps are: -

      -
    • equidistant: colormaps are created so that they are equidistant around the colorwheel. For example, when creating three colormaps from three slices, starting with a red base, the three colors used for the colormaps will be at 0, 120, and 240 degrees around the colorwheel (i.e. red, green, and blue). -
    • analogous: create groups of colors around the colorwheel (i.e., generally closer than equidistant). For example, red, orange, and red-orange are analogous colors. Choose three or more colormaps. -
    -There are many, many articles on the net describing colors and their -compatibility. Just search for "colorwheel", "color theory", or -"compatible colors", etc. - -

    -When the color picker is used to select a base color, new colors are -chosen from this base color to generate monochromatic colormaps. When an -existing colormap is used, each inflection point of the colormap generates -new colors, which then are combined into new colormaps. - -

    -By default, the color picker is the HTML5 color picker implemented -within the browser. These internal color pickers generally have -several nice ways to choose a color. If the browser does not support -an internal color picker (e.g. Safari 11, even though the Mac OSX -supports a great color picker!), a simplified color picker is used -instead. Note that the HTML5 color picker is a bit quirky: it remains -displayed when the page is unloaded or reloaded, even though it -becomes detached from the new page. You must always exit the HTML5 -color picker by clicking its exit button. - -

    -The generated colormaps are added to the Color menu in the more colormaps ... submenu. If you use the color picker to choose a base color, the colormaps are named "[id]_1", [id]_2", etc., where [id] is the id of the JS9 display (e.g. "JS9"). If you use an existing colormap, the new colormaps are called "[cname]_1", [cname]_2", etc., where [cname] is the name of the original colormap. - -

    -Colormaps can be assigned to images by clicking the button to the left -of the image name. The colormap assignments are made in stacking -order, which you can change by dragging an image into the appropriate -place on the stack. - -

    -Note that the parameters of each colormap plugin instance can be -controlled independently, and that each instance allows you to assign -colormaps to any image, regardless of its parent display. This means, -for example, that you can load three images into separate displays and -change their colormaps simultaneously. -

    - - diff --git a/web/static/js9_old/plugins/help/colorbar.html b/web/static/js9_old/plugins/help/colorbar.html deleted file mode 100644 index feb37be8707d47917f1ea34e2e841d1fdd1441fd..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/colorbar.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - -Plugin: JS9Colorbar - - - -
    -

    JS9 Colorbar

    - -The JS9 Colorbar displays the mapping of colors to pixel values -for the currently displayed image. The choice of colormap and scale -(including scale min and max values) determines the initial -distribution of colors. Moving the mouse to changing the contrast/bias -affects the mapping by expanding/compressing (contrast) and shifting -(bias) the colormap so that it covers different ranges of image values. - -

    -If you change scales (e.g., from linear to log), the colormap at first -might not appear to change. However, note that the numeric labels have -changed. This shows you how colors are now associated with a different -range of pixel values. The linear scale displays an evenly distributed -range of image values, but the log scale does not: the distribution is -a log(base10) distribution. - -

    -When printing an image using the File->print menu option, if a -colorbar is active on the page, it will be placed beneath the image. -

    - - diff --git a/web/static/js9_old/plugins/help/colorcontrols.html b/web/static/js9_old/plugins/help/colorcontrols.html deleted file mode 100644 index de846563aa3ceeae485b9b80cd6403b90a52daa0..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/colorcontrols.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - - -Plugin: JS9Color - - - -
    -

    Color Controls

    - -

    -The Color Controls plugin provides a number of ways to set colors -on an image: -

      -
    • use the Top cmaps and Other cmaps menus to change -the colormap -
    • use the Create cmaps button to toggle the -Create Colormaps plugin, allowing you to -create new colormaps -
    • use the Image filters button to toggle the Image Filters -plugin and apply image processing techniques to the displayed image -
    • use the Contrast/bias text boxes to change the contrast and bias -
    • use the Opacity options to set the opacity in various ways -
    - -

    -Opacity can be set in various ways, depending on the option chosen in the -mode menu: - -

    -When default is selected, the opacity of each pixel is set to the -default value in the first text box (which should be between 0 and 1). The -default value is also used in the pixels option. - -

    -When floor ≤ is selected, the opacity in the first text box -is applied to image pixels whose value is less than or equal to the -specified floor value in the last text box. For image values greater than -this floor value, the default opacity is applied. - -

    -When opacity is selected, a menu of opacity image files is -displayed. These opacity images must have the same dimensions as the -displayed image. A pixel value in the opacity image specifies the -opacity of the corresponding image pixel (and therefore should take on -values between 0 and 1). - -

    -For mask mode, if the value of a pixel in the image is less than -or equal to zero, the opacity of the displayed pixel is set to the -opacity value in the text box. Otherwise, the opacity is set to -the global opacity. Thus, for example, if the opacity in -the first text box is set to 0, this mode will display only the image -pixels with corresponding non-zero mask values, i.e., image pixels -"covered" by a mask. - -

    -When overlay is selected, a menu of overlay files is -displayed. These "overlay mask" images must have the same dimensions -as the displayed image. If a mask pixel has a non-zero alpha value (in -its own display frame), its color is blended with the image pixel -using source-atop composition. Otherwise, the image pixel -color alone is used in the display. This is one way you can display a -mask overlay on top of an image. A static colormap is usually used in -conjunction with an overlay mask, since pixel values not explicitly -assigned a color are transparent. Note that, when blending a mask and -image pixel, the global opacity and the individual pixel opacity of -the mask are multiplied to get each final pixel opacity. -

    - - diff --git a/web/static/js9_old/plugins/help/console.html b/web/static/js9_old/plugins/help/console.html deleted file mode 100644 index 2951dc5b0b4ffffee297e31543283367b5cafe3c..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/console.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - - -Plugin: JS9Console - - - -
    -

    JS9 Console

    - -

    -The Console plugin provides a mechanism for executing JS9 functions by -typing commands instead of using the graphical interface or -external messaging. A number of shortcut commands have been defined, including: -

    -    analysis    list/run analysis for current image (run)
    -    colormap    set/get colormap for current image (cmap)
    -    colormaps   get list of available colormaps (cmaps)
    -    global      set/get a JS9.globalOpts parameter
    -    grid        set/get coordinate grid for current image
    -    help        get list of available commands
    -    helper      set/get helper connection
    -    image       get name of current image or display specified image
    -    images      get list of currently loaded images
    -    load        load image(s)
    -    pan         set/get pan location for current image
    -    pix2wcs     get image pixel value for specified wcs position
    -    print       print image window
    -    refresh     refresh image using specified file (def: use last file)
    -    regcnts     counts in regions for current image
    -    regions     add or list region(s) (reg, region)
    -    resize      set/get display size for current image
    -    scale       set/get scaling for current image
    -    scales      get list of available scales
    -    section     display section of current image
    -    status      get status for specified (or current) image
    -    url         display a url
    -    wcssys      set/get wcs system for current image
    -    wcsu        set/get wcs units used for current image
    -    wcssystems  get list of available wcs systems
    -    wcsunits    get list of available wcs units
    -    wcs2pix     get wcs position for specified image pixel
    -    zoom        set/get zoom for current image
    -
    -where aliases are in parentheses.For example: -
    -    js9> cmap heat
    -
    -    js9> cmap
    -    heat 1 0.5
    -
    -The real value of the Console plugin lies in the fact that you can execute -any public access routine. For example: -
    -    js9> SetColormap heat
    -
    -    js9> GetColormap
    -    {"colormap":"heat","contrast":3.75,"bias":0.736328125}
    -
    -    js9> AddRegions circle(23:23:27.9,+58:48:42.8,3") {"color":"cyan"}
    -
    -The major constraint is that all arguments must be spaceless, e.g. you -cannot put spaces into a region specification. - -

    -The Console plugin thus provides a simple way of executing routines for -which there is no graphical interface. For example, you can execute -JS9.ShiftData() directly in the Console: -

    -    js9> ShiftData -10 10
    -
    - -

    -Note that the up and down arrow keys provide a simple history mechanism -for the Console plugin. - -

    - - diff --git a/web/static/js9_old/plugins/help/cube.html b/web/static/js9_old/plugins/help/cube.html deleted file mode 100644 index 62a99cbad0b56d9d81b411ad2c5e4feca9cee951..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/cube.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - -Plugin: JS9Cube - - - -
    -

    JS9 FITS Data Cubes

    - -

    -The Data Cube plugin allows you to display slices from a FITS -3D data cube. You can choose the particular slice to display using the -slider, text box, or navigation buttons. You also can blink the slices -in order using the blink and stop buttons. The default blink interval -is one second, but this can be changed with the rate menu. - -

    -By default, the slice axis is the third axis of the cube. Use the menu -at the right to specify a different slice axis. - -

    -You also can load each slice separately into JS9 with the Load All -button. Each slice will be identified by the original filename with a -<n> suffix, where n is the slice number. Loading all slices -separately allows you to blend the cube images or set up RGB mode -(on any three of them). - -

    -The underlying public access routine, JS9.DisplaySlice(), also -works on FITS 4D data cubes. This plugin will be extended to support -4D cubes if there is a need within the astronomical community. -

    - - diff --git a/web/static/js9_old/plugins/help/divs.html b/web/static/js9_old/plugins/help/divs.html deleted file mode 100644 index 4e0b0d54374d12c09ac9e451c3b3b815b2861dac..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/divs.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - -Plugin: JS9Divs - - - -
    -

    Visibility of JS9 Plugin Divs

    - -

    -JS9 plugins can be added statically to a web page by specifying a div -element with the plugin class as an attribute, e.g: -

    -  <div class="JS9Menubar"></div>
    -  <div class="JS9"></div>
    -  <div style="margin-top: 2px;">
    -  <div class="JS9Colorbar"></div>
    -
    -This plugin allows you to hide or show these in-page plugins. It works by -setting the CSS visibility property on the divs. Note that -invisible elements will still take up space on the web page. - -
    - - diff --git a/web/static/js9_old/plugins/help/filters.html b/web/static/js9_old/plugins/help/filters.html deleted file mode 100644 index 63168eacd6694ed076f9188b909b8d012ff4c1ac..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/filters.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - - -Plugin: JS9Filters - - - -
    -

    JS9 Image Filters

    - -The Image Filter plugin allows you to apply image processing -techniques directly to the displayed image without changing the -underlying raw data. The web has an overwhelming -amount of information about image processing. A good technical -article concerning the use of image filters with Javascript and the -HTML5 canvas is available at: - -http://www.html5rocks.com/en/tutorials/canvas/imagefilters/ - - -

    -Note that the standard JS9 colormaps, scale, contrast and bias -selections are applied to the raw data to regenerate the RGB -image. Thus, if you use an image processing technique and then change -colormap, contrast, bias, or scale, you will undo the applied image -processing. This is a good way to reset the displayed image. - -

    -Several image processing filters and convolutions are available, many of -which allow you to adjust a parameter using either a slider or by -typing a value into the text box: -

      -
    • blur(val): blur the image using a pseudo-Gaussian convolution -
    • brighten(val): add constant value to each pixel to change the brightness -
    • darken(val): darken by applying the kernel -[ 0, 0, 0, 0, val, 0, 0, 0, 0], -
    • duotone(0|1|2): remove a color by setting it to -the average of the other two, e.g. red=(green+blue)/2, where the input -values are: 0 = red, 1 = green, 2 = blue -
    • edge(): detect edges using the kernel -[ -1, -1, -1, -1, 8, -1, -1, -1, -1 ] -
    • emboss(val): produce embossing effect using the kernel -[-18, -9, 9, -9, 100 - val, 9, 0, 9, 18 ] -
    • gamma(val): apply the nonlinear gamma operation, used to code and -decode luminance values in video or still image systems: -out = pow(in, val) -
    • invert(): the RGB channels of the image are inverted -
    • lighten(val): lighten the image by applying the kernel -[ 0, 0, 0, 0, val, 0, 0, 0, 0 ], -
    • luminance():convert to greyscale using the CIE luminance: -0.2126*r + 0.7152*g + 0.0722*b -[255-r, 255-g, 255-b, a] -
    • median(): noise reduction technique that replaces each pixel with -the median of neighboring pixels -
    • noise(val): add random noise: -pixel = pixel + Math.floor((Math.random()*(val) -
    • pixelate(val):make image look coarser by creating a square tiling -effect of the specified size -
    • scatter(val): scatters the colors of a pixel in its -neighborhood, akin to viewing through brittle cracked glass -
    • sepia(val): image takes on shades of brown, like an antique -photograph -
    • sharpen(val): sharpen the image using the kernel -[ 0, -3, 0, -3, val, -3, 0, -3, 0 ] -
    • sobel(): use the Sobel operator to create an image that -emphasizes the edges -
    • solarize(val): which image is wholly or partially reversed in -tone. Dark areas appear light or light areas appear dark. -
    - -

    -Filters are cumulative: if you apply a filter and then apply a second filter, -the latter changes the current RGB color values that were modified by the -first filter. - -

    -You can undo the effects of the current filter by clicking the -undo [filter] button. This reverts the image to the colors used -in the previous filter. The undo operation is applied to the -current filter, allowing you to unwind the filters back to the -original image colors. The reset operation unsets all filters. -(You can, of course, unset all filters at once by changing the -colormap, contrast, bias, or scale.) -

    - - diff --git a/web/static/js9_old/plugins/help/imarith.html b/web/static/js9_old/plugins/help/imarith.html deleted file mode 100644 index f086a948b71d5d01236ed4edc97e5063caea060e..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/imarith.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - -Plugin: JS9Imarith - - - -
    -

    JS9 Image Arithmetic

    - -

    -The Image Arithmetic plugin performs basic arithmetic -operations (addition, subtraction, multiplication, division, minimum, -maximum) between the currently displayed image and either another -image or a constant real value. - -

    -To start, choose an arithmetic operation from the first menu. -Next use the second menu to choose either a real value or another -image as the second operand. In the former case, the constant value -you enter into the text box will be applied to each pixel in the -image. In the latter case, the operation is performed between the -corresponding pixels in the two images. - -

    -Click the Run button to perform the arithmetic operation. A -new raw data layer called "imarith" will be created containing the -results of the operation. Successive runs are cumulative, so that you -can build up a more complex operation from simple ones. - -

    -Click the Reset button to delete the "imarith" raw data layer, -which will allow you to start afresh. - -

    -Note that the two images must have the same dimensions. We might be -able to remove this restriction in the future, although it is -unclear how one lines up images of different dimensions. -

    - - diff --git a/web/static/js9_old/plugins/help/info.html b/web/static/js9_old/plugins/help/info.html deleted file mode 100644 index 7024579bd44040e0c4af10363c3da0e829c0af57..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/info.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - -Plugin: JS9Info - - - -
    -

    JS9 Info Box

    - -

    -Each JS9 window usually has a value/position display in the upper -left, which shows the pixel value at the current mouse position, along -with position information (WCS and/or image, depending on the -current coordinate system.) The Info Box plugin will display this information -and more in a separate window. - -

    -The information displayed in the Info Box depends on the values -contained in the JS9.globalOpts.infoBox property, an array -which looks something like this: - -

    -    infoBox: ["file", "object", "wcsfov", "wcscen", "wcspos",
    -              "impos", "physpos", "value", "regions", "progress"]
    -
    -The entries listed above tell the Info Box plugin to display the following -information: -
      -
    • file: file name -
    • object: object name, taken from FITS header -
    • wcsfov: wcs field of view -
    • wcscen: wcs center of image -
    • wcspos: current position in wcs coordinates -
    • impos: current position in image coordinates -
    • physpos: current position in physical (file) coordinates -
    • value: pixel value -
    • regions: regions, if these are not displayed in a separate window -
    • progress: progress bar, when used -
    -Currently, the other option(s) for display are: -
      -
    • dispos: current position in display coordinates -
    -You can change the list of displayed values at run-time using the -Preferences plugin or, for site-wide configuration, by -changing the value in the js9prefs.js file. -
    - - diff --git a/web/static/js9_old/plugins/help/keyboard.html b/web/static/js9_old/plugins/help/keyboard.html deleted file mode 100644 index 862d5fc1106b0c97676aff19ac81e96ae3e82c44..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/keyboard.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - -Plugin: JS9Keyboard - - - -
    -

    Keyboard Actions

    - -

    -JS9 supports the actions that get executed in response to -(case-sensitive) keypress events. The following actions are -defined in the JS9.globalOpts.keyboardActions array: -

      -
    • 0: reset zoom -
    • b: toggle selected region: source/background -
    • e: toggle selected region: include/exclude -
    • o: open a local FITS file -
    • /: copy wcs position to clipboard -
    • ?: copy value and position to clipboard -
    • =: zoom in -
    • +: zoom in -
    • -: zoom out -
    • >: display next image -
    • <: display previous image -
    • delete: remove selected region -
    • leftArrow: move selected region left -
    • upArrow: move selected region up -
    • rightArrow: move selected region right -
    • downArrow: move selected region down -
    -You can view the current mapping between keys and actions using -this Keyboard plugin. Also, you can execute individual -actions by clicking the 'key' buttons. This is especially useful for -devices without keyboards, such as iPads and iPhones. - -

    -It is possible to add new actions. To do this, first add an entry to -the JS9.Keyboard.Actions object. The property name for the new -entry should be descriptive text, like that which is found -in JS9.globalOpts.keyboardActions. The property value -will be a function having the calling sequence: -

    -  function(im, ipos, evt)
    -
    -where: -
      -
    • im: the image handle of the current image (or null) -
    • ipos: the current image position of the mouse -
    • evt: the event that triggered this action -
    -For example: -
    -  JS9.Keyboard.Actions["export image as a PNG file"] = function(im, ipos, evt){
    -    .... action implementation goes here ...
    -  };
    -
    -Once this new action property has been defined, you can map it to a -keypress event in JS9.globalOpts.keyboardActions: -
    -  JS9.globalOpts.keyboardActions["x"] = "export image as a PNG file";
    -
    -The new action will be shown in the Keyboard plugin display, and will be -executed any time the "x" key is pressed. -
    - - diff --git a/web/static/js9_old/plugins/help/layers.html b/web/static/js9_old/plugins/help/layers.html deleted file mode 100644 index 3bfe58056c396c3c738fede12f4b064e962f7b97..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/layers.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - -Plugin: JS9Layers - - - -
    -

    JS9 Shape Layers

    - -

    -JS9 supports individual layers for drawing 2D graphics. The regions -layer is a special case of a shape layer, created automatically by -JS9. The Catalog Plugin creates a separate layer for each catalog. -You can define your own shape layer using the NewShapeLayer() -public routine, and then add geometric shapes to it. - -

    -For a given image, one shape layer at a time is active, -responding to mouse and touch events. Ordinarily, a shape layer -becomes the active layer when it is first created and shapes are -added to it. Thus, the first time you create a region, the regions -layer becomes active. If you then load a catalog into a catalog layer, -that layer becomes active. - -

    -The Shape Layers plugin displays the layers defined for the current -image and allows you to turn on and off the display of any layer. It -highlights the currently active layer (the topmost visible layer in -the layer stack) allows you to make a layer active by moving it to the -top of the stack. - -

    -You also can save layers to a local file. If the layer is a catalog -(i.e., a tab-delimited table loaded using LoadCatalog() or the load -catalog menu option), you will have the choice of saving the layer -either as a catalog or a region. Otherwise, you will be able to -save the layer as a region. -

    - - diff --git a/web/static/js9_old/plugins/help/magnifier.html b/web/static/js9_old/plugins/help/magnifier.html deleted file mode 100644 index dc15a6b1caf6ba0479667a8086a03f2dc2ef9f94..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/magnifier.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - -Plugin: JS9Magnifier - - - -
    -

    JS9 Magnifier

    - -

    -The Magnifier plugin displays a blocked image of the data in an area -surrounding the mouse as it moves. The default magnification of four -can be changed using command buttons on the magnifier window. - -

    -By default, regions are displayed in the magnifier at the current -zoom. You can turn off region display by changing the value of the -JS9.globalOpts.magnifierRegions property, either by using the -Preferences plugin or, for site-wide configuration, by changing -the value in the js9prefs.js file. - -

    - - diff --git a/web/static/js9_old/plugins/help/mef.html b/web/static/js9_old/plugins/help/mef.html deleted file mode 100644 index c12a011a1b33a81838a981332e0c566ac8c87868..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/mef.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - -Plugin: JS9Mef - - - -
    -

    JS9 Multi-Extension FITS Files

    - -

    -The Extensions plugin allows you to display the HDU extensions -in a multi-extension FITS file. Simply click on the desired extension -to display it. - -

    -By default, the display (including the underlying raw data) of the new -extension replaces the previous data in the same image. If, however, -the Display each extension as a separate image checkbox is -selected, each succeeding extension will be displayed as a separate -image, so that you can view two or more extensions simultaneously. In -this case, you can use the Blink extension to blink the -extensions or the File->move image to menu option to move an -extension to a existing display or new light window. In all cases, the -raw data for that extension is available for browser-based analysis. - -

    -Note that some extensions are not available for display, including images -of less than two dimensions, and binary tables not containing x and y columns. -These extensions are marked as invalid by a strike through their description. - -

    -See the FITS Primer -for information about HDUs and multi-extension FITS. -

    - - diff --git a/web/static/js9_old/plugins/help/mousetouch.html b/web/static/js9_old/plugins/help/mousetouch.html deleted file mode 100644 index 89341e04165c06f4d9436167119b97ab273ae589..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/mousetouch.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - -Plugin: JS9MouseTouch - - - -
    -

    Mouse and Touch Actions

    - -JS9 supports the following configurable mouse and touch actions: -
      -
    • mouse movement with no buttons pressed -
    • mouse movement with one button pressed -
    • mouse movement with two buttons pressed -
    • touch with one finger -
    • touch with two fingers -
    • touch with three fingers -
    -The initial actions are defined by the JS9.globalOpts.mouseActions -and JS9.globalOpts.touchActions arrays. In addition, the -JS9.globalOpts.mousetouchZoom property specifies whether a mouse wheel -or touch/pinch will zoom the image. The default actions are: -
      -
    • mouseActions: ["display value/position", "change contrast/bias", "pan the image"] -
    • touchActions: ["display value/position", "change contrast/bias", "pan the image"] -
    • mousetouchZoom: false -
    -where the array elements map to an increasing numbers of -buttons/fingers. You can change the default actions of the elements -in either array in your js9Prefs.json file. For example, to make pan -and zoom the default one-touch and pinch actions respectively: -
      -
    • touchActions: ["pan the image", "display value/position", "change contrast/bias"] -
    • mousetouchZoom: true -
    -As usual, the defaults in js9Prefs.json are used by all JS9 displays in -a web page. - -

    -Users can change the action assignments using the MouseTouch -plugin, which displays the current mapping between mouse/touch gesture -and its action. Simply drag and drop an action to a different gesture -in order to change the mapping. You also can toggle the scroll/pinch -to zoom capability by clicking its button. -

    - - diff --git a/web/static/js9_old/plugins/help/panner.html b/web/static/js9_old/plugins/help/panner.html deleted file mode 100644 index dd33a6afed737007a630045877b06490ac4e198a..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/panner.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - -Plugin: JS9Panner - - - -
    -

    JS9 Panner

    - -

    -The Panner plugin will displays the full image along with a viewport -rectangle showing the currently displayed image section in the primary -image window. The viewport can be moved around in order to pan to -different locations in the primary image. The panner also has command -button options to zoom the viewport itself. (This makes the viewport -rectangle larger at the expense of displaying only a section of the -full image. It is useful for panning in a very large image.) - -

    -The WCS orientation (North and East) are shown on the display. -You can turn off direction display by changing the value of the -JS9.globalOpts.pannerDirections property, either by using the -Preferences plugin or, for site-wide configuration, by changing -the value in the js9prefs.js file. -

    - - diff --git a/web/static/js9_old/plugins/help/plugintest.html b/web/static/js9_old/plugins/help/plugintest.html deleted file mode 100644 index b6ce75faf11d42274a0744299bed28319c8e708f..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/plugintest.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - -JS9 Test Plugin - - - -
    -

    The plugin help page

    - -

    -Not much to say ... it's a plugin test, after all! See the page source for -implementation details. -

    -See also: -Adding Local Analysis Tasks (Plugins) to JS9 -

    - - diff --git a/web/static/js9_old/plugins/help/prefs.html b/web/static/js9_old/plugins/help/prefs.html deleted file mode 100644 index c5f91c3923561b401289bd55d4534611db9905bb..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/prefs.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - -Plugin: JS9Preferences - - - -
    -

    JS9 User Preferences

    - -

    -The JS9 preferences plugin allows you to set JS9 user preferences for -JS9-enabled Web pages in the current domain. By and large, these are -the same preferences that can be found in the JS9 site preferences -file (js9Prefs.json), and of course you can set defaults in that file. -However, the preferences plugin allows you to set these preferences in -cases where you do not have access to this file, e.g. public sites -such as js9.si.edu. - -

    Due to cross-browser security limitations, preferences are -browser-specific: your Firefox preferences will be maintained -separately from your Chrome and Safari preferences. - -

    -The following types of user preferences can be set: -

      -
    • images: colormap, contrast, scale, etc. for all newly displayed images -
    • regions: region parameters (radius, width, height, etc) for all newly created regions -
    • fits: a list of binary table extensions to look for in a drag/drop operation, size of image to extract -
    • displays: settings applied to each JS9 display, these currently consist of mouse/touch actions (see the Mouse Touch plugin for more info) -
    - -

    -You can apply your preference choices to the current session using the -Apply button. To apply and save these preferences for future -sessions, use the Save button. The Show Saved and -Delete Saved buttons allow you to view and clear the currently -saved values, respectively. -

    - - diff --git a/web/static/js9_old/plugins/help/scalecontrols.html b/web/static/js9_old/plugins/help/scalecontrols.html deleted file mode 100644 index af21084e4870a6e166d8f030e4426e83af243ee1..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/scalecontrols.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - - -Plugin: JS9Scale - - - -
    -

    Scale Controls

    - -

    -The JS9/DS9 scaling algorithms convert image pixel values to RGB -values, as described in the DS9 -documentation -"How It Works". Scaling utilizes low and high -clipping values when mapping the data to RGB. These limits are -initially taken to be the high and low data values, which obviously -can be wasteful of the color distribution if a few low or high values -are far away from the bulk of the data values. - -

    -The Scale Controls plugin therefore provides a number of ways to -set the low and high clipping limits: -

      -
    • use the Limits menu to choose data min/max, IRAF zscale z1/z2 or IRAF zscale z1/max -
    • select a portion of the Pixel Distribution plot -
    • change the Low and/or High limits directly using the text boxes -
    -The Pixel Distribution plots a histogram of the distribution of -pixel values (binned into 512 bins). The current low and high clipping -values are shown as red and green carets, respectively, at the bottom -of the plot. Moving the mouse over the plot will show the pixel -value, i.e. the x coordinate. - -

    -You can select a region of the distribution by pressing the mouse and -moving it left or right. When the mouse is released, the selected low -and high pixel values will be used as the new clipping values. -(Selection does not work for mouse-less iPads, but you still -can view the distribution values and input your chosen limits into -the Low and/or High text boxes.) - -

    -The IRAF zscale algorithm is described on the -IRAF DISPLAY task help page, -which is reproduced below. Note that zscale parameters can be changed using the -the JS9 Preferences plugin. -

    -The zscale algorithm is designed to display the image values near -the median image value without the time consuming process of -computing a full image histogram. This is particularly useful for -astronomical images which generally have a very peaked histogram -corresponding to the background sky in direct imaging or the -continuum in a two dimensional spectrum. -

    -The sample of pixels, specified by values greater than zero in the -sample mask zmask or by an image section, is selected up to a -maximum of nsample pixels. If a bad pixel mask is specified by the -bpmask parameter then any pixels with mask values which are greater -than zero are not counted in the sample. Only the first pixels up -to the limit are selected where the order is by line beginning from -the first line. If no mask is specified then a grid of pixels with -even spacing along lines and columns that make up a number less -than or equal to the maximum sample size is used. -

    -If a contrast of zero is specified (or the zrange flag is used and -the image does not have a valid minimum/maximum value) then the -minimum and maximum of the sample is used for the intensity mapping -range. -

    -If the contrast is not zero the sample pixels are ranked in -brightness to form the function I(i) where i is the rank of the -pixel and I is its value. Generally the midpoint of this function -(the median) is very near the peak of the image histogram and there -is a well defined slope about the midpoint which is related to the -width of the histogram. At the ends of the I(i) function there are -a few very bright and dark pixels due to objects and defects in the -field. To determine the slope a linear function is fit with -iterative rejection; -

    -    I(i) = intercept + slope * (i - midpoint)
    -
    -If more than half of the points are rejected then there is no well -defined slope and the full range of the sample defines z1 and z2. -Otherwise the endpoints of the linear function are used (provided -they are within the original range of the sample): -
    -    z1 = I(midpoint) + (slope / contrast) * (1 - midpoint)
    -    z2 = I(midpoint) + (slope / contrast) * (npoints - midpoint)
    -
    -As can be seen, the parameter contrast may be used to adjust the -contrast produced by this algorithm. -
    - - diff --git a/web/static/js9_old/plugins/help/separate.html b/web/static/js9_old/plugins/help/separate.html deleted file mode 100644 index d9e934d414c97dc354233931dabbfbcf7d09ec4a..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/separate.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - -Plugin: JS9Separate - - - -
    -

    Separate and Gather Images

    - -

    -The Separate and Gather Images plugin allows you to separate -selected images or all images into independent JS9 displays. The -topmost (selected) image remains in place, and new displays are -created for the others. The presence or absence of a menubar, -toolbar, and colorbar in the topmost image will be replicated in the -new displays. - -

    -You also can gather selected images or all images into the current -display. - -

    -When separating images, the plugin allows you to choose between three layouts: -

      -
    • horizontal: one row starting to the right of the first display -
    • vertical: one column underneath the first display -
    • auto: layout horizontally so long as half of each subsequent -display is visible, then start a new row -
    - -

    -The options to separate all and gather all images can -also be found in the File menu (using the auto layout). -

    - - diff --git a/web/static/js9_old/plugins/help/statusbar.html b/web/static/js9_old/plugins/help/statusbar.html deleted file mode 100644 index 245683d50b51d1d39d1b223c7406490503b2313b..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/statusbar.html +++ /dev/null @@ -1,104 +0,0 @@ - - - - - -Plugin: JS9Statusbar - - - -
    -

    JS9 Statusbar

    -

    -The JS9 Statusbar plugin displays user-configurable status values for -the currently displayed image such as zoom factor, scale, and/or -colormap. Configuration is done via -the JS9.globalOpts.statusbar format string, in which one or -more clickable status areas are separated by semi-colons. Each status -area consists of optional text (which can utilize html elements) and -dollar-sign-delimited "macros" that will be expanded to the -appropriate value for each image. - -

    -The macros can represent parameters values stored with each image, of -which the most important ones are: -

      -
    • colormap -
    • contrast -
    • bias -
    • flip -
    • rot90 -
    • scale -
    • scalemin -
    • scalemax -
    • scaleclipping -
    • wcssys -
    • wcsunits -
    • zoom -
    -See the JS9 Public -API SetParam call for -more information about image parameters. - -

    -In addition to image parameters, the following special parameters are available: -

      -
    • colorbar: colorbar plugin without tick marks -
    • fliprot: flip and rot90 params in "(flip,rot)" format -
    • image: image name -
    • image0: image name (without [EVENTS] bracket extension, where present) -
    • mag: percent magnification (e.g. zoom 2 is "200%") -
    • img(pngfile | jpgfile): display the specified image -
    -The png/jpg pathnames supplied to the $img macro should be relative to -the web page, as usual. The $fliprot macro returns an empty string if -neither flip or rot90 have been applied, otherwise it returns a parenthesized -string containing the non-zero value(s) (e.g. "(x)", or "(y,90)"). - -

    -For example, the current default value for the format string is: -

    -  $colorbar; $colormap; $mag $fliprot; $scale ($scalemin,$scalemax); $wcssys; $image0
    -
    -meaning to display a colorbar, followed by the colormap name, the -current magnification, flip and rot90 if applicable, then the scale (including -scale min and max), the wcs system, and the image name (without the -[EVENTS] extension, if present). Note that the colorbar is the real -JS9Colorbar plugin (with tick-marks turned off) and will change -dynamically as the colormap or contrast/bias is changed. - -Alternatively, this configuration: -
    -  $img(images/voyager/color_$colormap.png) $colormap; $mag; $scale($scalemin,$scalemax); $wcssys; $image
    -
    -will display a static image of the current colormap, along with the -other values. In this case, the image filename will include all -bracket extensions. - -

    -The following status macros have clickable actions: -

      -
    • image | image0: toggle the Binning plugin -
    • mag | zoom: toggle the Pan/Zoom plugin -
    • scale | scalemin | scalemax: toggle the Scale Controls plugin -
    -Thus, for example, clicking in an area that contains one of the $scale -macros will toggle the Scale plugin. - -

    -The status display will wrap onto the next line if necessary, and a scrollbar -will become available on the right-hand side. Thus, if a long image -filename is not displayed in the default setup, try the scrollbar ... - -

    -See -Configuring JS9 Site Preferences and -the JS9 User Preferences plugin for discussions -of how to set preferences such as JS9.globalOpts.statusbar on a site-wide -and an individual basis, respectively. - - -

    - - diff --git a/web/static/js9_old/plugins/help/syncui.html b/web/static/js9_old/plugins/help/syncui.html deleted file mode 100644 index c5e2bca0f905aba8dfb30840bf497483a71a8bd4..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/syncui.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - -Plugin: JS9Sync - - - -
    -

    JS9 Sync Images

    - -

    -Synchronize two or more images, so that when an operation is performed -on one image, it also is performed on the other(s). For example, when -the colormap or scale is changed on an image, it also is changed on -the sync'ed images. Or, when a region is created, moved, resized, or -removed on an image, the same happens on the sync'ed images. You also -can synchronize once only. - -

    -The plugin displays a list of images that can be sync'ed with the -current image, as well as a list of operations that can be sync'ed, -including "colormap", "contrast/bias", "flip", "pan", "regions", -"rot90", "scale", "wcs sys/units", and "zoom". Choose one or more -images to sync and one or more operations for sync'ing and then -click Sync Repeatedly" or Sync Once. The first routine -calls JS9.SyncImages() while the second calls JS9.CopyParams() -to perform repeated or single synchronizing, respectively. You also can -Unsync operations that previously had been set up for repeated -synchronization. - -

    -Upon initialization, the displayed images and ops checkboxes will show -both images and operations sync'ed with the currently displayed -image. When you execute a new repeated synchronization, the displayed -checkboxes will be updated appropriately. Note that if you -synchronize once only, the display will not reflect this one-time -action (but will continue to reflect repeated synchronizations, if -any). This makes it clear which images and ops are repeatedly sync'ed -and thus makes it easier to unsync operations. - -

    -The following options are available: -

      -
    • reciprocal sync : images sync one another (i.e., changes go both ways) -
    • sync using wcs: use wcs header params to sync (e.g. for pan), where available -
    - -
    - - diff --git a/web/static/js9_old/plugins/help/toolbar.html b/web/static/js9_old/plugins/help/toolbar.html deleted file mode 100644 index bcb903814053a468b594a8380a87c34f4ea1292e..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/toolbar.html +++ /dev/null @@ -1,99 +0,0 @@ - - - - - -Plugin: JS9Toolbar - - - -
    -

    JS9 Toolbar

    -

    -The JS9 Toolbar plugin displays tool icons that can be clicked to -execute shortcut functions such as creating a region, zooming in and -out of the image, or changing the scaling algorithm. Hover the mouse -over an icon to identify the action that will be performed (non-mobile -devices only). - -

    -The display of tools supplied by JS9 is separated into two lists: -the top-level list consists of the tools that are specified in the -JS9.globalOpts.toolBar array. Other tools are displayed in a -lower list, accessible by scrolling down. In this way, your favorite -tools can be placed at the top-level, but all tools remain available. -See -Configuring JS9 Site Preferences and -the JS9 User Preferences plugin for discussions -of how to set preferences such as JS9.globalOpts.toolBar on a site-wide -and an individual basis, respectively. - -

    -New tools can be added to the toolbar at any time using the -JS9.SetToolbar() public access routine. The text properties -associated with a tool object are: -

      -
    • name: name of the tool -
    • tip: a tooltip to display when the mouse hovers over the tool -
    • image: url (relative to the install directory) containing a PNG -image file to display as the tool icon -
    • cmd: name of the JS9 public routine to execute when the tool is -clicked -
    • args: array of arguments to pass to the JS9 public routine -
    -Only the name and cmd properties are required. If no image is -specified, a button labeled by the name value will be used. - -

    -Examples of tool objects: -

    -  {
    -    "name": "linear",
    -    "tip": "linear scale",
    -    "image": "images/toolbar/dax_images/lin.png",
    -    "cmd": "SetScale",
    -    "args": ["linear"]
    -  },
    -  {
    -    "name": "histeq",
    -    "tip": "histogram equalization",
    -    "cmd": "SetScale",
    -    "args": ["histeq"]
    -  },
    -  {
    -    "name": "annulus",
    -    "tip": "annulus region",
    -    "image": "images/toolbar/dax_images/annulus.png",
    -    "cmd": "AddRegions",
    -    "args": ["annulus"]
    -  },
    -  {
    -    "name": "remove",
    -    "tip": "remove selected region",
    -    "image": "images/toolbar/dax_images/erase.png",
    -    "cmd": "RemoveRegions",
    -    "args": ["selected"]
    -  },
    -  {
    -    "name": "zoom1",
    -    "tip": "zoom 1",
    -    "image": "images/toolbar/dax_images/mag_one.png",
    -    "cmd": "SetZoom",
    -    "args": [1]
    -  },
    -  {
    -    "name": "magnifier",
    -    "tip": "toggle magnifier display",
    -    "image": "images/toolbar/dax_images/mag.png",
    -    "cmd": "DisplayPlugin",
    -    "args": ["JS9Magnifier"]
    -  }
    -
    -See the -The JS9 Public API for more -information about this routine. - -
    - - diff --git a/web/static/js9_old/plugins/help/zoomcontrols.html b/web/static/js9_old/plugins/help/zoomcontrols.html deleted file mode 100644 index c2fa22d87a89cc127ac0edcd5dda5d4a7565f55c..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/help/zoomcontrols.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -Plugin: JS9PanZoom - - - -
    -

    JS9 Pan/Zoom Controls

    - -

    -The Pan/Zoom Controls plugin allows you to pan to an image location -that can be specified using image, physical, or WCS coordinates. - -

    -The plugin initially displays the current pan location using the -current globally configured WCS system and units. Choose a different -system and/or units via the WCS system and WCS units menus and the -current pan position will be updated appropriately. Then enter a new -position in the position text boxes and click the Pan to → -button to pan the image. - -

    -The plugin also offers menus to pan, zoom, flip, and rotate the image -by 90 degree increments, along with a text box to rotate by an -arbitrary angle in degrees. Note that arbitrary rotation is performed -in terms of an absolute angle: if you rotate by 20 degrees and then do -it again, there is no change. Also, setting the rotation to 0 sets the -angle to 0. Flipping and rot90, however, are relative to the current -state of the display. - -

    -The Flip menu's reset option unsets x and/or y -flips. The Rotate menu's reset option resets both the rot90 and -rotation angle, as does specifying reset in the rotation text box. -The Rotate menu's reset flip/rot90/rotate option resets flip, rot90, and rotate. -

    - - diff --git a/web/static/js9_old/plugins/imexam/3dplot.js b/web/static/js9_old/plugins/imexam/3dplot.js deleted file mode 100644 index 5c2a6318f313ffb07ad41e58634a4b8e417601e8..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/imexam/3dplot.js +++ /dev/null @@ -1,1490 +0,0 @@ -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;ocreate, click, move, or resize a region to see 3d plot
    "); - } - - JS9.RegisterPlugin("ImExam", "3dPlot", pluginInit, { - menu: "analysis", - - menuItem: "3dPlot", - winTitle: "3dPlot", - help: "imexam/imexam.html#3dplot", - - dynamicSelect: true, - - toolbarSeparate: true, - - onregionschange: pluginUpdate, - winDims: [250, 250], - }); -}()); - -},{"./JSSurfacePlot-V1.7/javascript/ColourGradient":2,"./JSSurfacePlot-V1.7/javascript/SurfacePlot":3,"./imexam":undefined}],2:[function(require,module,exports){ -/* - * ColourGradient.js - * - * - * Copyright (c) 2011 Greg Ross - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of the project's author nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * Class that is used to define a path through RGB space. - * @author Greg Ross - * @constructor - * @param minValue the value that will return the first colour on the path in RGB space - * @param maxValue the value that will return the last colour on the path in RGB space - * @param rgbColourArray the set of colours that defines the dirctional path through RGB space. - * The length of the array must be greater than two. - */ -greg.ross.visualisation.ColourGradient = function(minValue, maxValue, rgbColourArray) -{ - function RGB2HTML(red, green, blue) - { - var decColor = red + 256 * green + 65536 * blue; - return decColor.toString(16); - } - - /** - * Return a colour from a position on the path in RGB space that is proportioal to - * the number specified in relation to the minimum and maximum values from which the - * bounds of the path are derived. - * @member greg.ross.visualisation.ColourGradient - * @param value - */ - this.getColour = function(value) - { - if ( isNaN(value) || value < minValue || value > maxValue || rgbColourArray.length == 1) - { - var colr = { - red: rgbColourArray[0].red, - green:rgbColourArray[0].green, - blue:rgbColourArray[0].blue - }; - - return colr; - } - - var scaledValue = mapValueToZeroOneInterval(value, minValue, maxValue); - - return getPointOnColourRamp(scaledValue); - } - - function getPointOnColourRamp(value) - { - var numberOfColours = rgbColourArray.length; - var scaleWidth = 1 / (numberOfColours - 1); - var index = (value / scaleWidth); - var index = parseInt(index + ""); - - index = index >= (numberOfColours - 1) ? (numberOfColours - 2): index; - - var rgb1 = rgbColourArray[index]; - var rgb2 = rgbColourArray[index + 1]; - - var closestToOrigin, furthestFromOrigin; - - if (distanceFromRgbOrigin(rgb1) > distanceFromRgbOrigin(rgb2)) - { - closestToOrigin = rgb2; - furthestFromOrigin = rgb1; - } - else - { - closestToOrigin = rgb1; - furthestFromOrigin = rgb2; - } - - var t; - - if (closestToOrigin == rgb2) - t = 1 - mapValueToZeroOneInterval(value, index * scaleWidth, (index + 1) * scaleWidth); - else - t = mapValueToZeroOneInterval(value, index * scaleWidth, (index + 1) * scaleWidth); - - var diff = [ - t * (furthestFromOrigin.red - closestToOrigin.red), - t * (furthestFromOrigin.green - closestToOrigin.green), - t * (furthestFromOrigin.blue - closestToOrigin.blue)]; - - var r = closestToOrigin.red + diff[0]; - var g = closestToOrigin.green + diff[1]; - var b = closestToOrigin.blue + diff[2]; - - r = parseInt(r); - g = parseInt(g); - b = parseInt(b); - - var colr = { - red:r, - green:g, - blue:b - }; - - return colr; - } - - function distanceFromRgbOrigin(rgb) - { - return (rgb.red * rgb.red) + (rgb.green * rgb.green) + (rgb.blue * rgb.blue); - } - - function mapValueToZeroOneInterval(value, minValue, maxValue) - { - if (minValue == maxValue) return 0; - - var factor = (value - minValue) / (maxValue - minValue); - return factor; - } -} - - -},{}],3:[function(require,module,exports){ -/* - * SurfacePlot.js - * - * - * Copyright (c) 2011 Greg Ross - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of the project's author nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ -/* - * Register the name space - * *********************** - */ -function registerNameSpace(ns){ - var nsParts = ns.split("."); - var root = window; - var n = nsParts.length; - - for (var i = 0; i < n; i++) { - if (typeof root[nsParts[i]] == "undefined") - root[nsParts[i]] = new Object(); - - root = root[nsParts[i]]; - } -} - -registerNameSpace("greg.ross.visualisation"); - -/* - * This is the main class and entry point of the tool - * and represents the Google viz API. - * *************************************************** - */ -greg.ross.visualisation.SurfacePlot = function(container){ - this.containerElement = container; -} - -greg.ross.visualisation.SurfacePlot.prototype.draw = function(data, options) { - var xPos = options.xPos; - var yPos = options.yPos; - var w = options.width; - var h = options.height; - var colourGradient = options.colourGradient; - var fillPolygons = options.fillPolygons; - var tooltips = options.tooltips; - var xTitle = options.xTitle; - var yTitle = options.yTitle; - var zTitle = options.zTitle; - var restrictXRotation = options.restrictXRotation; - - if (this.surfacePlot == undefined) - this.surfacePlot = new greg.ross.visualisation.JSSurfacePlot(xPos, yPos, w, h, colourGradient, this.containerElement, tooltips, fillPolygons, xTitle, yTitle, zTitle, restrictXRotation); - - this.surfacePlot.redraw(data); -} - -/* - * This class does most of the work. - * ********************************* - */ -greg.ross.visualisation.JSSurfacePlot = function(x, y, width, height, colourGradient, targetElement, tooltips, fillRegions, xTitle, yTitle, zTitle, restrictXRotation){ - this.targetDiv; - var id = allocateId(); - var canvas; - var canvasContext = null; - - var scale = greg.ross.visualisation.JSSurfacePlot.DEFAULT_SCALE; - - var currentZAngle = greg.ross.visualisation.JSSurfacePlot.DEFAULT_Z_ANGLE; - var currentXAngle = greg.ross.visualisation.JSSurfacePlot.DEFAULT_X_ANGLE; - - this.data = null; - var canvas_support_checked = false; - var canvas_supported = true; - var data3ds = null; - var displayValues = null; - var numXPoints; - var numYPoints; - var transformation; - var cameraPosition; - var colourGradient; - var colourGradientObject; - var renderPoints = false; - - var mouseDown1 = false; - var mouseDown3 = false; - var mousePosX = null; - var mousePosY = null; - var lastMousePos = new greg.ross.visualisation.Point(0, 0); - var mouseButton1Up = null; - var mouseButton3Up = null; - var mouseButton1Down = new greg.ross.visualisation.Point(0, 0); - var mouseButton3Down = new greg.ross.visualisation.Point(0, 0); - var closestPointToMouse = null; - var xAxisHeader = ""; - var yAxisHeader = ""; - var zAxisHeader = ""; - var xAxisTitleLabel = new greg.ross.visualisation.Tooltip(true); - var yAxisTitleLabel = new greg.ross.visualisation.Tooltip(true); - var zAxisTitleLabel = new greg.ross.visualisation.Tooltip(true); - var tTip = new greg.ross.visualisation.Tooltip(false); - - function init(){ - transformation = new greg.ross.visualisation.Th3dtran(); - - createTargetDiv(); - - if (!targetDiv) - return; - - createCanvas(); - } - - function hideTooltip(){ - tTip.hide(); - } - - function displayTooltip(e){ - var position = new greg.ross.visualisation.Point(e.x, e.y); - tTip.show(tooltips[closestPointToMouse], 200); - } - - function render(data){ - canvasContext.clearRect(0, 0, canvas.width, canvas.height); - canvasContext.fillStyle = '#000'; - canvasContext.fillRect(0, 0, canvas.width, canvas.height); - this.data = data; - - var canvasWidth = width; - var canvasHeight = height; - - var minMargin = 20; - var drawingDim = canvasWidth - minMargin * 2; - var marginX = minMargin; - var marginY = minMargin; - - transformation.init(); - transformation.rotate(currentXAngle, 0.0, currentZAngle); - transformation.scale(scale); - transformation.translate(drawingDim / 2.0 + marginX, (drawingDim / 3.0*2) + marginY, 0.0); - - cameraPosition = new greg.ross.visualisation.Point3D(drawingDim / 2.0 + marginX, drawingDim / 2.0 + marginY, -1000.0); - - if (renderPoints) { - for (i = 0; i < data3ds.length; i++) { - var point3d = data3ds[i]; - canvasContext.fillStyle = '#ff2222'; - var transformedPoint = transformation.ChangeObjectPoint(point3d); - transformedPoint.dist = distance(transformedPoint, cameraPosition); - - var x = transformedPoint.ax; - var y = transformedPoint.ay; - - canvasContext.beginPath(); - var dotSize = greg.ross.visualisation.JSSurfacePlot.DATA_DOT_SIZE; - - canvasContext.arc((x - (dotSize / 2)), (y - (dotSize / 2)), 1, 0, self.Math.PI * 2, true); - canvasContext.fill(); - } - } - - var axes = createAxes(); - var polygons = createPolygons(data3ds); - - for (i = 0; i < axes.length; i++) { - polygons[polygons.length] = axes[i]; - } - - // Sort the polygons so that the closest ones are rendered last - // and therefore are not occluded by those behind them. - // This is really Painter's algorithm. - polygons.sort(greg.ross.visualisation.PolygonComaparator); - //polygons = sort(polygons); - - canvasContext.lineWidth = 1; - canvasContext.strokeStyle = '#888'; - canvasContext.lineJoin = "round"; - - for (i = 0; i < polygons.length; i++) { - var polygon = polygons[i]; - - if (polygon.isAnAxis()) { - var p1 = polygon.getPoint(0); - var p2 = polygon.getPoint(1); - - canvasContext.beginPath(); - canvasContext.moveTo(p1.ax, p1.ay); - canvasContext.lineTo(p2.ax, p2.ay); - canvasContext.stroke(); - } - else { - var p1 = polygon.getPoint(0); - var p2 = polygon.getPoint(1); - var p3 = polygon.getPoint(2); - var p4 = polygon.getPoint(3); - - var colourValue = (p1.lz * 1.0 + p2.lz * 1.0 + p3.lz * 1.0 + p4.lz * 1.0) / 4.0; - - // if (colourValue < 0) - // colourValue *= -1; - - var rgbColour = colourGradientObject.getColour(colourValue); - var colr = "rgb(" + rgbColour.red + "," + rgbColour.green + "," + rgbColour.blue + ")"; - canvasContext.fillStyle = colr; - - canvasContext.beginPath(); - canvasContext.moveTo(p1.ax, p1.ay); - canvasContext.lineTo(p2.ax, p2.ay); - canvasContext.lineTo(p3.ax, p3.ay); - canvasContext.lineTo(p4.ax, p4.ay); - canvasContext.lineTo(p1.ax, p1.ay); - - if (fillRegions) - canvasContext.fill(); - else - canvasContext.stroke(); - } - } - - canvasContext.stroke(); - - if (supports_canvas()) - renderAxisText(axes); - } - - function renderAxisText(axes){ - var xLabelPoint = new greg.ross.visualisation.Point3D(0.0, 0.5, 0.0); - var yLabelPoint = new greg.ross.visualisation.Point3D(-0.5, 0.0, 0.0); - var zLabelPoint = new greg.ross.visualisation.Point3D(-0.5, 0.5, 0.5); - - var transformedxLabelPoint = transformation.ChangeObjectPoint(xLabelPoint); - var transformedyLabelPoint = transformation.ChangeObjectPoint(yLabelPoint); - var transformedzLabelPoint = transformation.ChangeObjectPoint(zLabelPoint); - - var xAxis = axes[0]; - var yAxis = axes[1]; - var zAxis = axes[2]; - - canvasContext.fillStyle = '#fff'; - - if (xAxis.distanceFromCamera > yAxis.distanceFromCamera) { - var xAxisLabelPosX = transformedxLabelPoint.ax; - var xAxisLabelPosY = transformedxLabelPoint.ay; - canvasContext.fillText(xTitle, xAxisLabelPosX, xAxisLabelPosY); - } - - if (xAxis.distanceFromCamera < yAxis.distanceFromCamera) { - var yAxisLabelPosX = transformedyLabelPoint.ax; - var yAxisLabelPosY = transformedyLabelPoint.ay; - canvasContext.fillText(yTitle, yAxisLabelPosX, yAxisLabelPosY); - } - - if (xAxis.distanceFromCamera < zAxis.distanceFromCamera) { - var zAxisLabelPosX = transformedzLabelPoint.ax; - var zAxisLabelPosY = transformedzLabelPoint.ay; - canvasContext.fillText(zTitle, zAxisLabelPosX, zAxisLabelPosY); - } - } - - var sort = function(array){ - var len = array.length; - - if (len < 2) { - return array; - } - - var pivot = Math.ceil(len / 2); - return merge(sort(array.slice(0, pivot)), sort(array.slice(pivot))); - } - - var merge = function(left, right){ - var result = []; - while ((left.length > 0) && (right.length > 0)) { - if (left[0].distanceFromCamera < right[0].distanceFromCamera) { - result.push(left.shift()); - } - else { - result.push(right.shift()); - } - } - - result = result.concat(left, right); - return result; - } - - - function createAxes(){ - var axisOrigin = new greg.ross.visualisation.Point3D(-0.5, 0.5, 0); - var xAxisEndPoint = new greg.ross.visualisation.Point3D(0.5, 0.5, 0); - var yAxisEndPoint = new greg.ross.visualisation.Point3D(-0.5, -0.5, 0); - var zAxisEndPoint = new greg.ross.visualisation.Point3D(-0.5, 0.5, 1); - - var transformedAxisOrigin = transformation.ChangeObjectPoint(axisOrigin); - var transformedXAxisEndPoint = transformation.ChangeObjectPoint(xAxisEndPoint); - var transformedYAxisEndPoint = transformation.ChangeObjectPoint(yAxisEndPoint); - var transformedZAxisEndPoint = transformation.ChangeObjectPoint(zAxisEndPoint); - - var axes = new Array(); - - var xAxis = new greg.ross.visualisation.Polygon(cameraPosition, true); - xAxis.addPoint(transformedAxisOrigin); - xAxis.addPoint(transformedXAxisEndPoint); - xAxis.calculateCentroid(); - xAxis.calculateDistance(); - axes[axes.length] = xAxis; - - var yAxis = new greg.ross.visualisation.Polygon(cameraPosition, true); - yAxis.addPoint(transformedAxisOrigin); - yAxis.addPoint(transformedYAxisEndPoint); - yAxis.calculateCentroid(); - yAxis.calculateDistance(); - axes[axes.length] = yAxis; - - var zAxis = new greg.ross.visualisation.Polygon(cameraPosition, true); - zAxis.addPoint(transformedAxisOrigin); - zAxis.addPoint(transformedZAxisEndPoint); - zAxis.calculateCentroid(); - zAxis.calculateDistance(); - axes[axes.length] = zAxis; - - return axes; - } - - function createPolygons(data3D){ - var i; - var j; - var polygons = new Array(); - var index = 0; - - for (i = 0; i < numXPoints - 1; i++) { - for (j = 0; j < numYPoints - 1; j++) { - var polygon = new greg.ross.visualisation.Polygon(cameraPosition, false); - - var p1 = transformation.ChangeObjectPoint(data3D[j + (i * numYPoints)]); - var p2 = transformation.ChangeObjectPoint(data3D[j + (i * numYPoints) + numYPoints]); - var p3 = transformation.ChangeObjectPoint(data3D[j + (i * numYPoints) + numYPoints + 1]); - var p4 = transformation.ChangeObjectPoint(data3D[j + (i * numYPoints) + 1]); - - polygon.addPoint(p1); - polygon.addPoint(p2); - polygon.addPoint(p3); - polygon.addPoint(p4); - polygon.calculateCentroid(); - polygon.calculateDistance(); - - polygons[index] = polygon; - index++; - } - } - - return polygons; - } - - function getDefaultColourRamp(){ - var colour1 = { - red: 0, - green: 0, - blue: 255 - }; - var colour2 = { - red: 0, - green: 255, - blue: 255 - }; - var colour3 = { - red: 0, - green: 255, - blue: 0 - }; - var colour4 = { - red: 255, - green: 255, - blue: 0 - }; - var colour5 = { - red: 255, - green: 0, - blue: 0 - }; - return [colour1, colour2, colour3, colour4, colour5]; - } - - this.redraw = function(data){ - numXPoints = data.getNumberOfRows() * 1.0; - numYPoints = data.getNumberOfColumns() * 1.0; - - var minZValue = Number.MAX_VALUE; - var maxZValue = Number.MIN_VALUE; - - for (var i = 0; i < numXPoints; i++) { - for (var j = 0; j < numYPoints; j++) { - var value = data.getFormattedValue(i, j) * 1.0; - - if (value < minZValue) - minZValue = value; - - if (value > maxZValue) - maxZValue = value; - } - } - - var cGradient; - - if (colourGradient) - cGradient = colourGradient; - else - cGradient = getDefaultColourRamp(); - - // if (minZValue < 0 && (minZValue*-1) > maxZValue) - // maxZValue = minZValue*-1; - - colourGradientObject = new greg.ross.visualisation.ColourGradient(minZValue, maxZValue, cGradient); - - var canvasWidth = width; - var canvasHeight = height; - - var minMargin = 20; - var drawingDim = canvasWidth - minMargin * 2; - var marginX = minMargin; - var marginY = minMargin; - - if (canvasWidth > canvasHeight) { - drawingDim = canvasHeight - minMargin * 2; - marginX = (canvasWidth - drawingDim) / 2; - } - else - if (canvasWidth < canvasHeight) { - drawingDim = canvasWidth - minMargin * 2; - marginY = (canvasHeight - drawingDim) / 2; - } - - var xDivision = 1 / (numXPoints - 1); - var yDivision = 1 / (numYPoints - 1); - var xPos, yPos; - var i, j; - var numPoints = numXPoints * numYPoints; - data3ds = new Array(); - var index = 0; - - // Calculate 3D points. - for (i = 0, xPos = -0.5; i < numXPoints; i++, xPos += xDivision) { - for (j = 0, yPos = 0.5; j < numYPoints; j++, yPos -= yDivision) { - var x = xPos; - var y = yPos; - - data3ds[index] = new greg.ross.visualisation.Point3D(x, y, data.getFormattedValue(i, j)); - index++; - } - } - - render(data); - } - - function allocateId(){ - var count = 0; - var name = "surfacePlot"; - - do { - count++; - } - while (document.getElementById(name + count)) - - return name + count; - } - - function createTargetDiv(){ - this.targetDiv = document.createElement("div"); - this.targetDiv.id = id; - this.targetDiv.className = "surfaceplot"; - this.targetDiv.style.background = '#ffffff' - this.targetDiv.style.position = 'absolute'; - - if (!targetElement) - document.body.appendChild(this.targetDiv); - else { - this.targetDiv.style.position = 'relative'; - targetElement.appendChild(this.targetDiv); - } - - this.targetDiv.style.left = x + "px"; - this.targetDiv.style.top = y + "px"; - } - - function getInternetExplorerVersion() // Returns the version of Internet Explorer or a -1 - // (indicating the use of another browser). - { - var rv = -1; // Return value assumes failure. - if (navigator.appName == 'Microsoft Internet Explorer') { - var ua = navigator.userAgent; - var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); - if (re.exec(ua) != null) - rv = parseFloat(RegExp.$1); - } - return rv; - } - - function supports_canvas(){ - if (canvas_support_checked) return canvas_supported; - - canvas_support_checked = true; - canvas_supported = !!document.createElement('canvas').getContext; - return canvas_supported; - } - - function createCanvas(){ - canvas = document.createElement("canvas"); - - if (!supports_canvas()) { - G_vmlCanvasManager.initElement(canvas); - canvas.style.width = width; - canvas.style.height = height; - } - - canvas.className = "surfacePlotCanvas"; - canvas.setAttribute("width", width); - canvas.setAttribute("height", height); - canvas.style.left = '0px'; - canvas.style.top = '0px'; - - targetDiv.appendChild(canvas); - - canvasContext = canvas.getContext("2d"); - canvasContext.font = "bold 18px sans-serif"; - canvasContext.clearRect(0, 0, canvas.width, canvas.height); - - canvasContext.fillStyle = '#000'; - - canvasContext.fillRect(0, 0, canvas.width, canvas.height); - - canvasContext.beginPath(); - canvasContext.rect(0, 0, canvas.width, canvas.height); - canvasContext.strokeStyle = '#888'; - canvasContext.stroke(); - - canvas.onmousemove = mouseIsMoving; - canvas.onmouseout = hideTooltip; - canvas.onmousedown = mouseDownd; - canvas.onmouseup = mouseUpd; - - //added by edupont - canvas.addEventListener("touchstart", mouseDownd, false); - canvas.addEventListener("touchmove", mouseIsMoving, false); - canvas.addEventListener("touchend", mouseUpd, false); - canvas.addEventListener("touchcancel", hideTooltip, false); - } - - function mouseDownd(e){ - if (isShiftPressed(e)) { - mouseDown3 = true; - mouseButton3Down = getMousePositionFromEvent(e); - } - else { - mouseDown1 = true; - mouseButton1Down = getMousePositionFromEvent(e); - } - } - - function mouseUpd(e){ - if (mouseDown1) { - mouseButton1Up = lastMousePos; - } - else - if (mouseDown3) { - mouseButton3Up = lastMousePos; - } - - mouseDown1 = false; - mouseDown3 = false; - } - - function mouseIsMoving(e){ - var currentPos = getMousePositionFromEvent(e); - - if (mouseDown1) { - hideTooltip(); - calculateRotation(currentPos); - } - else - if (mouseDown3) { - hideTooltip(); - calculateScale(currentPos); - } - else { - closestPointToMouse = null; - var closestDist = Number.MAX_VALUE; - - for (var i = 0; i < data3ds.length; i++) { - var point = data3ds[i]; - var dist = distance({ - x: point.ax, - y: point.ay - }, currentPos); - - if (dist < closestDist) { - closestDist = dist; - closestPointToMouse = i; - } - } - - if (closestDist > 16) { - hideTooltip(); - return; - } - - displayTooltip(currentPos); - } - - return false; - } - - function isShiftPressed(e){ - var shiftPressed = 0; - - if (parseInt(navigator.appVersion) > 3) { - var evt = navigator.appName == "Netscape" ? e : event; - - if (navigator.appName == "Netscape" && parseInt(navigator.appVersion) == 4) { - // NETSCAPE 4 CODE - var mString = (e.modifiers + 32).toString(2).substring(3, 6); - shiftPressed = (mString.charAt(0) == "1"); - } - else { - // NEWER BROWSERS [CROSS-PLATFORM] - shiftPressed = evt.shiftKey; - } - - if (shiftPressed) - return true; - } - - return false; - } - - function getMousePositionFromEvent(e){ - if (getInternetExplorerVersion() > -1) { - var e = window.event; - - if (e.srcElement.getAttribute('Stroked') == true) { - if (mousePosX == null || mousePosY == null) - return; - } - else { - mousePosX = e.offsetX; - mousePosY = e.offsetY; - } - } - else - if (e.layerX || e.layerX == 0) // Firefox - { - mousePosX = e.layerX; - mousePosY = e.layerY; - } - else if (e.offsetX || e.offsetX == 0) // Opera - { - mousePosX = e.offsetX; - mousePosY = e.offsetY; - } - else if (e.touches[0].pageX || e.touches[0].pageX == 0) //touch events - { - mousePosX = e.touches[0].pageX; - mousePosY = e.touches[0].pageY; - } - - var currentPos = new greg.ross.visualisation.Point(mousePosX, mousePosY); - - return currentPos; - } - - function calculateRotation(e){ - lastMousePos = new greg.ross.visualisation.Point(greg.ross.visualisation.JSSurfacePlot.DEFAULT_Z_ANGLE, greg.ross.visualisation.JSSurfacePlot.DEFAULT_X_ANGLE); - - if (mouseButton1Up == null) { - mouseButton1Up = new greg.ross.visualisation.Point(greg.ross.visualisation.JSSurfacePlot.DEFAULT_Z_ANGLE, greg.ross.visualisation.JSSurfacePlot.DEFAULT_X_ANGLE); - } - - if (mouseButton1Down != null) { - lastMousePos = new greg.ross.visualisation.Point(mouseButton1Up.x + (mouseButton1Down.x - e.x),// - mouseButton1Up.y + (mouseButton1Down.y - e.y)); - } - - currentZAngle = lastMousePos.x % 360; - currentXAngle = lastMousePos.y % 360; - - if (restrictXRotation) { - - if (currentXAngle < 0) - currentXAngle = 0; - else - if (currentXAngle > 90) - currentXAngle = 90; - - } - - closestPointToMouse = null; - render(data); - } - - function calculateScale(e){ - lastMousePos = new greg.ross.visualisation.Point(0, greg.ross.visualisation.JSSurfacePlot.DEFAULT_SCALE / greg.ross.visualisation.JSSurfacePlot.SCALE_FACTOR); - - if (mouseButton3Up == null) { - mouseButton3Up = new greg.ross.visualisation.Point(0, greg.ross.visualisation.JSSurfacePlot.DEFAULT_SCALE / greg.ross.visualisation.JSSurfacePlot.SCALE_FACTOR); - } - - if (mouseButton3Down != null) { - lastMousePos = new greg.ross.visualisation.Point(mouseButton3Up.x + (mouseButton3Down.x - e.x),// - mouseButton3Up.y + (mouseButton3Down.y - e.y)); - } - - scale = lastMousePos.y * greg.ross.visualisation.JSSurfacePlot.SCALE_FACTOR; - - if (scale < greg.ross.visualisation.JSSurfacePlot.MIN_SCALE) - scale = greg.ross.visualisation.JSSurfacePlot.MIN_SCALE + 1; - else - if (scale > greg.ross.visualisation.JSSurfacePlot.MAX_SCALE) - scale = greg.ross.visualisation.JSSurfacePlot.MAX_SCALE - 1; - - lastMousePos.y = scale / greg.ross.visualisation.JSSurfacePlot.SCALE_FACTOR; - - closestPointToMouse = null; - render(data); - } - - init(); -} - -/** - * Given two coordinates, return the Euclidean distance - * between them - */ -function distance(p1, p2){ - return Math.sqrt(((p1.x - p2.x) * - (p1.x - - p2.x)) + - ((p1.y - p2.y) * (p1.y - p2.y))); -} - -/* - * Matrix3d: This class represents a 3D matrix. - * ******************************************** - */ -greg.ross.visualisation.Matrix3d = function(){ - this.matrix = new Array(); - this.numRows = 4; - this.numCols = 4; - - this.init = function(){ - this.matrix = new Array(); - - for (var i = 0; i < this.numRows; i++) { - this.matrix[i] = new Array(); - } - } - - this.getMatrix = function(){ - return this.matrix; - } - - this.matrixReset = function(){ - for (var i = 0; i < this.numRows; i++) { - for (var j = 0; j < this.numCols; j++) { - this.matrix[i][j] = 0; - } - } - } - - this.matrixIdentity = function(){ - this.matrixReset(); - this.matrix[0][0] = this.matrix[1][1] = this.matrix[2][2] = this.matrix[3][3] = 1; - } - - this.matrixCopy = function(newM){ - var temp = new greg.ross.visualisation.Matrix3d(); - var i, j; - - for (i = 0; i < this.numRows; i++) { - for (j = 0; j < this.numCols; j++) { - temp.getMatrix()[i][j] = (this.matrix[i][0] * newM.getMatrix()[0][j]) + (this.matrix[i][1] * newM.getMatrix()[1][j]) + (this.matrix[i][2] * newM.getMatrix()[2][j]) + (this.matrix[i][3] * newM.getMatrix()[3][j]); - } - } - - for (i = 0; i < this.numRows; i++) { - this.matrix[i][0] = temp.getMatrix()[i][0]; - this.matrix[i][1] = temp.getMatrix()[i][1]; - this.matrix[i][2] = temp.getMatrix()[i][2]; - this.matrix[i][3] = temp.getMatrix()[i][3]; - } - } - - this.matrixMult = function(m1, m2){ - var temp = new greg.ross.visualisation.Matrix3d(); - var i, j; - - for (i = 0; i < this.numRows; i++) { - for (j = 0; j < this.numCols; j++) { - temp.getMatrix()[i][j] = (m2.getMatrix()[i][0] * m1.getMatrix()[0][j]) + (m2.getMatrix()[i][1] * m1.getMatrix()[1][j]) + (m2.getMatrix()[i][2] * m1.getMatrix()[2][j]) + (m2.getMatrix()[i][3] * m1.getMatrix()[3][j]); - } - } - - for (i = 0; i < this.numRows; i++) { - m1.getMatrix()[i][0] = temp.getMatrix()[i][0]; - m1.getMatrix()[i][1] = temp.getMatrix()[i][1]; - m1.getMatrix()[i][2] = temp.getMatrix()[i][2]; - m1.getMatrix()[i][3] = temp.getMatrix()[i][3]; - } - } - - this.init(); -} - -/* - * Point3D: This class represents a 3D point. - * ****************************************** - */ -greg.ross.visualisation.Point3D = function(x, y, z){ - this.displayValue = ""; - - this.lx; - this.ly; - this.lz; - this.lt; - - this.wx; - this.wy; - this.wz; - this.wt; - - this.ax; - this.ay; - this.az; - this.at; - - this.dist; - - this.initPoint = function(){ - this.lx = this.ly = this.lz = this.ax = this.ay = this.az = this.at = this.wx = this.wy = this.wz = 0; - this.lt = this.wt = 1; - } - - this.init = function(x, y, z){ - this.initPoint(); - this.lx = x; - this.ly = y; - this.lz = z; - - this.ax = this.lx; - this.ay = this.ly; - this.az = this.lz; - } - - function multiply(p){ - var Temp = new Point3D(); - Temp.lx = this.lx * p.lx; - Temp.ly = this.ly * p.ly; - Temp.lz = this.lz * p.lz; - return Temp; - } - - function getDisplayValue(){ - return displayValue; - } - - function setDisplayValue(displayValue){ - this.displayValue = displayValue; - } - - this.init(x, y, z); -} - -/* - * Polygon: This class represents a polygon on the surface plot. - * ************************************************************ - */ -greg.ross.visualisation.Polygon = function(cameraPosition, isAxis){ - this.points = new Array(); - this.cameraPosition = cameraPosition; - this.isAxis = isAxis; - this.centroid = null; - this.distanceFromCamera = null; - - this.isAnAxis = function(){ - return this.isAxis; - } - - this.addPoint = function(point){ - this.points[this.points.length] = point; - } - - this.distance = function(){ - return this.distance2(this.cameraPosition, this.centroid); - } - - this.calculateDistance = function(){ - this.distanceFromCamera = this.distance(); - } - - this.calculateCentroid = function(){ - var xCentre = 0; - var yCentre = 0; - var zCentre = 0; - - var numPoints = this.points.length * 1.0; - - for (var i = 0; i < numPoints; i++) { - xCentre += this.points[i].ax; - yCentre += this.points[i].ay; - zCentre += this.points[i].az; - } - - xCentre /= numPoints; - yCentre /= numPoints; - zCentre /= numPoints; - - this.centroid = new greg.ross.visualisation.Point3D(xCentre, yCentre, zCentre); - } - - this.distance2 = function(p1, p2){ - return ((p1.ax - p2.ax) * (p1.ax - p2.ax)) + ((p1.ay - p2.ay) * (p1.ay - p2.ay)) + ((p1.az - p2.az) * (p1.az - p2.az)); - } - - this.getPoint = function(i){ - return this.points[i]; - } -} - -/* - * PolygonComaparator: Class used to sort arrays of polygons. - * ************************************************************ - */ -greg.ross.visualisation.PolygonComaparator = function(p1, p2){ - var diff = p1.distanceFromCamera - p2.distanceFromCamera; - - if (diff == 0) - return 0; - else - if (diff < 0) - return -1; - else - if (diff > 0) - return 1; - - return 0; -} - -/* - * Th3dtran: Class for matrix manipuation. - * ************************************************************ - */ -greg.ross.visualisation.Th3dtran = function(){ - this.matrix; - this.rMat; - this.rMatrix; - this.objectMatrix; - this.local = true; - - this.init = function(){ - this.matrix = new greg.ross.visualisation.Matrix3d(); - this.rMat = new greg.ross.visualisation.Matrix3d(); - this.rMatrix = new greg.ross.visualisation.Matrix3d(); - this.objectMatrix = new greg.ross.visualisation.Matrix3d(); - - this.initMatrix(); - } - - this.initMatrix = function(){ - this.matrix.matrixIdentity(); - this.objectMatrix.matrixIdentity(); - } - - this.translate = function(x, y, z){ - this.rMat.matrixIdentity(); - this.rMat.getMatrix()[3][0] = x; - this.rMat.getMatrix()[3][1] = y; - this.rMat.getMatrix()[3][2] = z; - - if (this.local) { - this.objectMatrix.matrixCopy(this.rMat); - } - else { - this.matrix.matrixCopy(this.rMat); - } - } - - this.rotate = function(x, y, z){ - var rx = x * (Math.PI / 180.0); - var ry = y * (Math.PI / 180.0); - var rz = z * (Math.PI / 180.0); - - this.rMatrix.matrixIdentity(); - this.rMat.matrixIdentity(); - this.rMat.getMatrix()[1][1] = Math.cos(rx); - this.rMat.getMatrix()[1][2] = Math.sin(rx); - this.rMat.getMatrix()[2][1] = -(Math.sin(rx)); - this.rMat.getMatrix()[2][2] = Math.cos(rx); - this.rMatrix.matrixMult(this.rMatrix, this.rMat); - - this.rMat.matrixIdentity(); - this.rMat.getMatrix()[0][0] = Math.cos(ry); - this.rMat.getMatrix()[0][2] = -(Math.sin(ry)); - this.rMat.getMatrix()[2][0] = Math.sin(ry); - this.rMat.getMatrix()[2][2] = Math.cos(ry); - this.rMat.matrixMult(this.rMatrix, this.rMat); - - this.rMat.matrixIdentity(); - this.rMat.getMatrix()[0][0] = Math.cos(rz); - this.rMat.getMatrix()[0][1] = Math.sin(rz); - this.rMat.getMatrix()[1][0] = -(Math.sin(rz)); - this.rMat.getMatrix()[1][1] = Math.cos(rz); - this.rMat.matrixMult(this.rMatrix, this.rMat); - - if (this.local) { - this.objectMatrix.matrixCopy(this.rMatrix); - } - else { - this.matrix.matrixCopy(this.rMatrix); - } - } - - this.scale = function(scale){ - this.rMat.matrixIdentity(); - this.rMat.getMatrix()[0][0] = scale; - this.rMat.getMatrix()[1][1] = scale; - this.rMat.getMatrix()[2][2] = scale; - - if (this.local) { - this.objectMatrix.matrixCopy(this.rMat); - } - else { - this.matrix.matrixCopy(this.rMat); - } - } - - this.changeLocalObject = function(p){ - p.wx = (p.ax * this.matrix.getMatrix()[0][0] + p.ay * this.matrix.getMatrix()[1][0] + p.az * this.matrix.getMatrix()[2][0] + this.matrix.getMatrix()[3][0]); - p.wy = (p.ax * this.matrix.getMatrix()[0][1] + p.ay * this.matrix.getMatrix()[1][1] + p.az * this.matrix.getMatrix()[2][1] + this.matrix.getMatrix()[3][1]); - p.wz = (p.ax * this.matrix.getMatrix()[0][2] + p.ay * this.matrix.getMatrix()[1][2] + p.az * this.matrix.getMatrix()[2][2] + this.matrix.getMatrix()[3][2]); - - return p; - } - - this.ChangeObjectPoint = function(p){ - p.ax = (p.lx * this.objectMatrix.getMatrix()[0][0] + p.ly * this.objectMatrix.getMatrix()[1][0] + p.lz * this.objectMatrix.getMatrix()[2][0] + this.objectMatrix.getMatrix()[3][0]); - p.ay = (p.lx * this.objectMatrix.getMatrix()[0][1] + p.ly * this.objectMatrix.getMatrix()[1][1] + p.lz * this.objectMatrix.getMatrix()[2][1] + this.objectMatrix.getMatrix()[3][1]); - p.az = (p.lx * this.objectMatrix.getMatrix()[0][2] + p.ly * this.objectMatrix.getMatrix()[1][2] + p.lz * this.objectMatrix.getMatrix()[2][2] + this.objectMatrix.getMatrix()[3][2]); - - return p; - } - - this.init(); -} - -/* - * Point: A simple 2D point. - * ************************************************************ - */ -greg.ross.visualisation.Point = function(x, y){ - this.x = x; - this.y = y; -} - -/* - * This function displays tooltips and was adapted from original code by Michael Leigeber. - * See http://www.leigeber.com/ - */ -greg.ross.visualisation.Tooltip = function(useExplicitPositions){ - var top = 3; - var left = 3; - var maxw = 300; - var speed = 10; - var timer = 20; - var endalpha = 95; - var alpha = 0; - var tt, t, c, b, h; - var ie = document.all ? true : false; - - this.show = function(v, w){ - if (tt == null) { - tt = document.createElement('div'); - tt.style.color = "#fff"; - - tt.style.position = 'absolute'; - tt.style.display = 'block'; - - t = document.createElement('div'); - - t.style.display = 'block'; - t.style.height = '5px'; - t.style.marginleft = '5px'; - t.style.overflow = 'hidden'; - - c = document.createElement('div'); - - b = document.createElement('div'); - - tt.appendChild(t); - tt.appendChild(c); - tt.appendChild(b); - document.body.appendChild(tt); - - if (!ie) { - tt.style.opacity = 0; - tt.style.filter = 'alpha(opacity=0)'; - } - else - tt.style.opacity = 1; - - - } - - if (!useExplicitPositions) - document.onmousemove = this.pos; - - tt.style.display = 'block'; - c.innerHTML = '' + v + ''; - tt.style.width = w ? w + 'px' : 'auto'; - - if (!w && ie) { - t.style.display = 'none'; - b.style.display = 'none'; - tt.style.width = tt.offsetWidth; - t.style.display = 'block'; - b.style.display = 'block'; - } - - if (tt.offsetWidth > maxw) { - tt.style.width = maxw + 'px'; - } - - h = parseInt(tt.offsetHeight) + top; - - if (!ie) { - clearInterval(tt.timer); - tt.timer = setInterval(function(){ - fade(1) - }, timer); - } - } - - this.setPos = function(e){ - tt.style.top = e.y + 'px'; - tt.style.left = e.x + 'px'; - } - - this.pos = function(e){ - var u = ie ? event.clientY + document.documentElement.scrollTop : e.pageY; - var l = ie ? event.clientX + document.documentElement.scrollLeft : e.pageX; - tt.style.top = (u - h) + 'px'; - tt.style.left = (l + left) + 'px'; - } - - function fade(d){ - var a = alpha; - - if ((a != endalpha && d == 1) || (a != 0 && d == -1)) { - var i = speed; - - if (endalpha - a < speed && d == 1) { - i = endalpha - a; - } - else - if (alpha < speed && d == -1) { - i = a; - } - - alpha = a + (i * d); - tt.style.opacity = alpha * .01; - tt.style.filter = 'alpha(opacity=' + alpha + ')'; - } - else { - clearInterval(tt.timer); - - if (d == -1) { - tt.style.display = 'none'; - } - } - } - - this.hide = function(){ - if (tt == null) - return; - - if (!ie) { - clearInterval(tt.timer); - tt.timer = setInterval(function(){ - fade(-1) - }, timer); - } - else { - tt.style.display = 'none'; - } - } -} - -greg.ross.visualisation.JSSurfacePlot.DEFAULT_X_ANGLE = 47; -greg.ross.visualisation.JSSurfacePlot.DEFAULT_Z_ANGLE = 47; -greg.ross.visualisation.JSSurfacePlot.DATA_DOT_SIZE = 3; -greg.ross.visualisation.JSSurfacePlot.DEFAULT_SCALE = 350; -greg.ross.visualisation.JSSurfacePlot.MIN_SCALE = 50; -greg.ross.visualisation.JSSurfacePlot.MAX_SCALE = 1100; -greg.ross.visualisation.JSSurfacePlot.SCALE_FACTOR = 1.4; - - -},{}]},{},[1]); - - diff --git a/web/static/js9_old/plugins/imexam/4arrow.png b/web/static/js9_old/plugins/imexam/4arrow.png deleted file mode 100644 index 36b875ad531cf0a6b9f9792b856ccd9d83f6797b..0000000000000000000000000000000000000000 Binary files a/web/static/js9_old/plugins/imexam/4arrow.png and /dev/null differ diff --git a/web/static/js9_old/plugins/imexam/README b/web/static/js9_old/plugins/imexam/README deleted file mode 100644 index f54c5cf9f3ce28c67805816cdd809ff03278f7ab..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/imexam/README +++ /dev/null @@ -1 +0,0 @@ -original source: https://github.com/jbroll/js9imexam diff --git a/web/static/js9_old/plugins/imexam/contour.js b/web/static/js9_old/plugins/imexam/contour.js deleted file mode 100644 index b5c558299ff9ed77c51268507dc05a5a9be2e00b..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/imexam/contour.js +++ /dev/null @@ -1,1039 +0,0 @@ -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 0 && i+k < ny ) { - xdat.data[j*nx + i] += kern[k+nk/2|0] * data.data[j*nx+i+k]; - } - } - } - } - for ( j = 0; j < ny; j++ ) { - for ( i = 0; i < nx; i++ ) { - for ( k = -nk/2|0; k < nk/2|0; k++ ) { - if ( j+k >= 0 && j+k < ny ) { - ydat.data[j*nx + i] += kern[k+nk/2|0] * xdat.data[(j+k)*nx+i]; - } - } - } - } - - return ydat; - }; - -}()); - -},{"./imexam":undefined}],2:[function(require,module,exports){ -/** - * Copyright (c) 2010, Jason Davies. - * - * All rights reserved. This code is based on Bradley White's Java version, - * which is in turn based on Nicholas Yue's C++ version, which in turn is based - * on Paul D. Bourke's original Fortran version. See below for the respective - * copyright notices. - * - * See http://paulbourke.net/papers/conrec for the original - * paper by Paul D. Bourke. - * - * The vector conversion code is based on http://apptree.net/conrec.htm by - * Graham Cox. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Copyright (c) 1996-1997 Nicholas Yue - * - * This software is copyrighted by Nicholas Yue. This code is based on Paul D. - * Bourke's CONREC.F routine. - * - * The authors hereby grant permission to use, copy, and distribute this - * software and its documentation for any purpose, provided that existing - * copyright notices are retained in all copies and that this notice is - * included verbatim in any distributions. Additionally, the authors grant - * permission to modify this software and its documentation for any purpose, - * provided that such modifications are not distributed without the explicit - * consent of the authors and that existing copyright notices are retained in - * all copies. Some of the algorithms implemented by this software are - * patented, observe all applicable patent law. - * - * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT - * OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, - * EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS - * PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR - * MODIFICATIONS. - */ - -var Conrec = (function() { - var EPSILON = 1e-20; - - var pointsEqual = function(a, b) { - var x = a.x - b.x, y = a.y - b.y; - return x * x + y * y < EPSILON; - } - - var reverseList = function(list) { - var pp = list.head; - var temp; - - while (pp) { - // swap prev/next pointers - temp = pp.next; - pp.next = pp.prev; - pp.prev = temp; - - // continue through the list - pp = temp; - } - - // swap head/tail pointers - temp = list.head; - list.head = list.tail; - list.tail = temp; - } - - var ContourBuilder = function(level) { - this.count = 0; - this.level = level; - this.s = null; - this.count = 0; - } - ContourBuilder.prototype.remove_seq = function(list) { - // if list is the first item, static ptr s is updated - if (list.prev) { - list.prev.next = list.next; - } else { - this.s = list.next; - } - - if (list.next) { - list.next.prev = list.prev; - } - --this.count; - } - ContourBuilder.prototype.addSegment = function(a, b) { - var pp; - var ss = this.s; - var ma = null; - var mb = null; - var prependA = false; - var prependB = false; - - if ( this.count++ > 100000 ) { - throw new Error("Too many calls to coutour AddSegment"); - } - - while (ss) { - if (ma == null) { - // no match for a yet - if (pointsEqual(a, ss.head.p)) { - ma = ss; - prependA = true; - } else if (pointsEqual(a, ss.tail.p)) { - ma = ss; - } - } - if (mb == null) { - // no match for b yet - if (pointsEqual(b, ss.head.p)) { - mb = ss; - prependB = true; - } else if (pointsEqual(b, ss.tail.p)) { - mb = ss; - } - } - // if we matched both no need to continue searching - if (mb != null && ma != null) { - break; - } else { - ss = ss.next; - } - } - - // c is the case selector based on which of ma and/or mb are set - var c = ((ma != null) ? 1 : 0) | ((mb != null) ? 2 : 0); - - switch(c) { - case 0: // both unmatched, add as new sequence - var aa = {p: a, prev: null}; - var bb = {p: b, next: null}; - aa.next = bb; - bb.prev = aa; - - // create sequence element and push onto head of main list. The order - // of items in this list is unimportant - ma = {head: aa, tail: bb, next: this.s, prev: null, closed: false}; - if (this.s) { - this.s.prev = ma; - } - this.s = ma; - - ++this.count; // not essential - tracks number of unmerged sequences - break; - - case 1: // a matched, b did not - thus b extends sequence ma - pp = {p: b}; - - if (prependA) { - pp.next = ma.head; - pp.prev = null; - ma.head.prev = pp; - ma.head = pp; - } else { - pp.next = null; - pp.prev = ma.tail; - ma.tail.next = pp; - ma.tail = pp; - } - break; - - case 2: // b matched, a did not - thus a extends sequence mb - pp = {p: a}; - - if (prependB) { - pp.next = mb.head; - pp.prev = null; - mb.head.prev = pp; - mb.head = pp; - } else { - pp.next = null; - pp.prev = mb.tail; - mb.tail.next = pp; - mb.tail = pp; - } - break; - - case 3: // both matched, can merge sequences - // if the sequences are the same, do nothing, as we are simply closing this path (could set a flag) - - if (ma === mb) { - pp = {p: ma.tail.p, next: ma.head, prev: null}; - ma.head.prev = pp; - ma.head = pp; - ma.closed = true; - break; - } - - // there are 4 ways the sequence pair can be joined. The current setting of prependA and - // prependB will tell us which type of join is needed. For head/head and tail/tail joins - // one sequence needs to be reversed - switch((prependA ? 1 : 0) | (prependB ? 2 : 0)) { - case 0: // tail-tail - // reverse ma and append to mb - reverseList(ma); - // fall through to head/tail case - case 1: // head-tail - // ma is appended to mb and ma discarded - mb.tail.next = ma.head; - ma.head.prev = mb.tail; - mb.tail = ma.tail; - - //discard ma sequence record - this.remove_seq(ma); - break; - - case 3: // head-head - // reverse ma and append mb to it - reverseList(ma); - // fall through to tail/head case - case 2: // tail-head - // mb is appended to ma and mb is discarded - ma.tail.next = mb.head; - mb.head.prev = ma.tail; - ma.tail = mb.tail; - - //discard mb sequence record - this.remove_seq(mb); - break; - } - } - } - - /** - * Implements CONREC. - * - * @param {function} drawContour function for drawing contour. Defaults to a - * custom "contour builder", which populates the - * contours property. - */ - var Conrec = function(drawContour) { - if (!drawContour) { - var c = this; - c.contours = {}; - /** - * drawContour - interface for implementing the user supplied method to - * render the countours. - * - * Draws a line between the start and end coordinates. - * - * @param startX - start coordinate for X - * @param startY - start coordinate for Y - * @param endX - end coordinate for X - * @param endY - end coordinate for Y - * @param contourLevel - Contour level for line. - */ - this.drawContour = function(startY, startX, endY, endX, contourLevel, k) { - var cb = c.contours[k]; - if (!cb) { - cb = c.contours[k] = new ContourBuilder(contourLevel); - } - cb.addSegment({x: startX, y: startY}, {x: endX, y: endY}); - } - this.contourList = function() { - var l = []; - var a = c.contours; - for (var k in a) { - var s = a[k].s; - var level = a[k].level; - while (s) { - var h = s.head; - var l2 = []; - l2.level = level; - l2.k = k; - while (h && h.p) { - l2.push(h.p); - h = h.next; - } - l.push(l2); - s = s.next; - } - } - l.sort(function(a, b) { return b.k - a.k }); - return l; - } - } else { - this.drawContour = drawContour; - } - this.h = new Array(5); - this.sh = new Array(5); - this.xh = new Array(5); - this.yh = new Array(5); - } - - /** - * contour is a contouring subroutine for rectangularily spaced data - * - * It emits calls to a line drawing subroutine supplied by the user which - * draws a contour map corresponding to real*4data on a randomly spaced - * rectangular grid. The coordinates emitted are in the same units given in - * the x() and y() arrays. - * - * Any number of contour levels may be specified but they must be in order of - * increasing value. - * - * - * @param {number[][]} d - matrix of data to contour - * @param {number} ilb,iub,jlb,jub - index bounds of data matrix - * - * The following two, one dimensional arrays (x and y) contain - * the horizontal and vertical coordinates of each sample points. - * @param {number[]} x - data matrix column coordinates - * @param {number[]} y - data matrix row coordinates - * @param {number} nc - number of contour levels - * @param {number[]} z - contour levels in increasing order. - */ - Conrec.prototype.contour = function(d, ilb, iub, jlb, jub, x, y, nc, z) { - var h = this.h, sh = this.sh, xh = this.xh, yh = this.yh; - var drawContour = this.drawContour; - this.contours = {}; - - /** private */ - var xsect = function(p1, p2){ - return (h[p2]*xh[p1]-h[p1]*xh[p2])/(h[p2]-h[p1]); - } - - var ysect = function(p1, p2){ - return (h[p2]*yh[p1]-h[p1]*yh[p2])/(h[p2]-h[p1]); - } - var m1; - var m2; - var m3; - var case_value; - var dmin; - var dmax; - var x1 = 0.0; - var x2 = 0.0; - var y1 = 0.0; - var y2 = 0.0; - - // The indexing of im and jm should be noted as it has to start from zero - // unlike the fortran counter part - var im = [0, 1, 1, 0]; - var jm = [0, 0, 1, 1]; - - // Note that castab is arranged differently from the FORTRAN code because - // Fortran and C/C++ arrays are transposed of each other, in this case - // it is more tricky as castab is in 3 dimensions - var castab = [ - [ - [0, 0, 8], [0, 2, 5], [7, 6, 9] - ], - [ - [0, 3, 4], [1, 3, 1], [4, 3, 0] - ], - [ - [9, 6, 7], [5, 2, 0], [8, 0, 0] - ] - ]; - - - for (var j=(jub-1);j>=jlb;j--) { - for (var i=ilb;i<=iub-1;i++) { - var temp1, temp2; - temp1 = Math.min(d.get(i, j), d.get(i, j+1)); - temp2 = Math.min(d.get(i+1, j), d.get(i+1, j+1)); - - dmin = Math.min(temp1,temp2); - temp1 = Math.max(d.get(i, j), d.get(i, j+1)); - - temp2 = Math.max(d.get(i+1, j),d.get(i+1, j+1)); - dmax = Math.max(temp1,temp2); - - if (dmax>=z[0]&&dmin<=z[nc-1]) { - for (var k=0;k=dmin&&z[k]<=dmax) { - for (var m=4;m>=0;m--) { - if (m>0) { - // The indexing of im and jm should be noted as it has to - // start from zero - h[m] = d.get(i+im[m-1], j+jm[m-1])-z[k]; - xh[m] = x[i+im[m-1]]; - yh[m] = y[j+jm[m-1]]; - } else { - h[0] = 0.25*(h[1]+h[2]+h[3]+h[4]); - xh[0]=0.5*(x[i]+x[i+1]); - yh[0]=0.5*(y[j]+y[j+1]); - } - if (h[m]>0.0) { - sh[m] = 1; - } else if (h[m]<0.0) { - sh[m] = -1; - } else - sh[m] = 0; - } - // - // Note: at this stage the relative heights of the corners and the - // centre are in the h array, and the corresponding coordinates are - // in the xh and yh arrays. The centre of the box is indexed by 0 - // and the 4 corners by 1 to 4 as shown below. - // Each triangle is then indexed by the parameter m, and the 3 - // vertices of each triangle are indexed by parameters m1,m2,and - // m3. - // It is assumed that the centre of the box is always vertex 2 - // though this isimportant only when all 3 vertices lie exactly on - // the same contour level, in which case only the side of the box - // is drawn. - // - // - // vertex 4 +-------------------+ vertex 3 - // | \ / | - // | \ m-3 / | - // | \ / | - // | \ / | - // | m=2 X m=2 | the centre is vertex 0 - // | / \ | - // | / \ | - // | / m=1 \ | - // | / \ | - // vertex 1 +-------------------+ vertex 2 - // - // - // - // Scan each triangle in the box - // - for (m=1;m<=4;m++) { - m1 = m; - m2 = 0; - if (m!=4) { - m3 = m+1; - } else { - m3 = 1; - } - case_value = castab[sh[m1]+1][sh[m2]+1][sh[m3]+1]; - if (case_value!=0) { - switch (case_value) { - case 1: // Line between vertices 1 and 2 - x1=xh[m1]; - y1=yh[m1]; - x2=xh[m2]; - y2=yh[m2]; - break; - case 2: // Line between vertices 2 and 3 - x1=xh[m2]; - y1=yh[m2]; - x2=xh[m3]; - y2=yh[m3]; - break; - case 3: // Line between vertices 3 and 1 - x1=xh[m3]; - y1=yh[m3]; - x2=xh[m1]; - y2=yh[m1]; - break; - case 4: // Line between vertex 1 and side 2-3 - x1=xh[m1]; - y1=yh[m1]; - x2=xsect(m2,m3); - y2=ysect(m2,m3); - break; - case 5: // Line between vertex 2 and side 3-1 - x1=xh[m2]; - y1=yh[m2]; - x2=xsect(m3,m1); - y2=ysect(m3,m1); - break; - case 6: // Line between vertex 3 and side 1-2 - x1=xh[m3]; - y1=yh[m3]; - x2=xsect(m1,m2); - y2=ysect(m1,m2); - break; - case 7: // Line between sides 1-2 and 2-3 - x1=xsect(m1,m2); - y1=ysect(m1,m2); - x2=xsect(m2,m3); - y2=ysect(m2,m3); - break; - case 8: // Line between sides 2-3 and 3-1 - x1=xsect(m2,m3); - y1=ysect(m2,m3); - x2=xsect(m3,m1); - y2=ysect(m3,m1); - break; - case 9: // Line between sides 3-1 and 1-2 - x1=xsect(m3,m1); - y1=ysect(m3,m1); - x2=xsect(m1,m2); - y2=ysect(m1,m2); - break; - default: - break; - } - // Put your processing code here and comment out the printf - //printf("%f %f %f %f %f\n",x1,y1,x2,y2,z[k]); - - //console.log(x1,y1,x2,y2,z[k],k); - drawContour(x1,y1,x2,y2,z[k],k); - } - } - } - } - } - } - } - } - return Conrec; -})(); -if (typeof exports !== "undefined") { - exports.Conrec = Conrec; -} - -},{}],3:[function(require,module,exports){ -/*jslint white: true, vars: true, plusplus: true, nomen: true, unparam: true, evil: true, regexp: true, bitwise: true */ -/*globals typed, Int8Array */ - -"use strict"; - -(function() { - - var top = 0; - var right = 1; - var bottom = 2; - var left = 3; - var none = 4; - - function contour (levels, xdim, ydim, image, draw) - { - var c; - var level; - - var used = new Uint8Array(xdim*ydim); - var ii,jj; - - - for ( c=0; c < levels.length; c++ ) { - level = levels[c]; - - for ( ii=0; ii < xdim*ydim; ii++) { - used[ii] = 0; - } - - // Search outer edges - // - // Search top - for ( jj=0, ii=0; ii < xdim-1; ii++ ) { - if ( image[jj*xdim + ii] < level && level <= image[jj*xdim + ii+1]) { - trace(xdim, ydim, level, ii , jj , top, image, used, draw); - } - } - - // Search right - for (jj=0; jj < ydim-1; jj++) { - if ( image[jj*xdim + ii] < level && level <= image[(jj+1)*xdim + ii]) { - trace(xdim, ydim, level, ii-1, jj , right, image, used, draw); - } - } - - // Search Bottom - for (ii--; ii >= 0; ii--) { - if ( image[jj*xdim + ii+1]= 0; jj--) { - if ( image[(jj+1)*xdim + ii] < level && level <= image[jj*xdim + ii] ) { - trace(xdim, ydim, level, ii , jj , left, image, used, draw); - } - } - - // Search each row of the image - for (jj=1; jj < ydim-1; jj++) { - for (ii=0; ii < xdim-1; ii++) { - if ( !used[jj*xdim + ii] && image[jj*xdim + ii] < level && level <= image[jj*xdim + ii+1]) { - trace(xdim, ydim, level, ii, jj , top, image, used, draw); - } - } - } - } - } - - function trace (xdim, ydim, level, xCell, yCell, side, image, used, draw) - { - var ii = xCell; - var jj = yCell; - var origSide = side; - - var init = 1; - var done = (ii<0 || ii>=xdim-1 || jj<0 && jj>=ydim-1); - - var flag; - var a, b, c, d; - var X, Y; - - while ( !done ) { - flag = 0; - - a = image[ jj *xdim + ii]; - b = image[ jj *xdim + ii+1]; - c = image[(jj+1)*xdim + ii+1]; - d = image[(jj+1)*xdim + ii]; - - if (init) { - init = 0; - switch (side) { - case top: - X = (level-a) / (b-a) + ii; - Y = jj; - break; - case right: - X = ii+1; - Y = (level-b) / (c-b) + jj; - break; - case bottom: - X = (level-c) / (d-c) + ii; - Y = jj+1; - break; - case left: - X = ii; - Y = (level-a) / (d-a) + jj; - break; - } - - } - else { - if ( side==top ) { used[jj*xdim + ii] = 1; } - - do { - if ( ++side == none ) { side = top; } - - switch (side) { - case top: - if (a>=level && level>b) { - flag = 1; - X = (level-a) / (b-a) + ii; - Y = jj; - jj--; - } - break; - case right: - if( b>=level && level>c ) { - flag = 1; - X = ii+1; - Y = (level-b) / (c-b) + jj; - ii++; - } - break; - case bottom: - if( c>=level && level>d ) { - flag = 1; - X = (level-d) / (c-d) + ii; - Y = jj+1; - jj++; - } - break; - case left: - if( d>=level && level>a ) { - flag = 1; - X = ii; - Y = (level-a) / (d-a) + jj; - ii--; - } - break; - } - } while ( !flag ); - - if ( ++side === none ) { side = top; } - if ( ++side === none ) { side = top; } - - if (ii==xCell && jj==yCell && side==origSide) { done = 1; } - if (ii<0 || ii>=xdim-1 || jj<0 || jj>=ydim-1) { done = 1; } - } - - draw(X+.5 ,Y+.5, level); - - if (done) { draw(0, 0, undefined); } - } - } - - module.exports = contour; -}()); - - -},{}],4:[function(require,module,exports){ -/*jslint white: true, vars: true, plusplus: true, nomen: true, unparam: true */ -/*globals $, JS9, imexam, alert */ - - -(function() { - "use strict"; - - var imexam = require("./imexam"); - var conrec = require("./conrec"); - var contfv = require("./contfv"); - - var binner = require("./bin"); - - - function drawContours(div, display) { - var im = JS9.GetImage({display: display}); - var form = $(div).find(".contour-form")[0]; - - var data = imexam.ndops.ndarray(im.raw.data, [im.raw.height, im.raw.width]); - - var levelString = form.level.value; - var binning = $(form).find("#binning").val(); - var smooth = $(form).find("#smooth").val(); - var quality = $(form).find("input[type=radio]:checked").val(); - - - if ( binning === "none" ) { - binning = 1; - } else { - data = binner.bin2d(data, parseInt(binning)); - } - - var level = JSON.parse("[" + levelString.trim().split(/\s+/).join(",") + "]").map(function(x) { return x*binning*binning; }); - - if ( smooth !== "none" ) { - data = binner.smooth_gaussian2d(data, parseFloat(smooth)); - } - - var contours; - - JS9.waiting(true); - setTimeout(function() { - try { - // var fudge = 0 - - // if ( binning > 1 ) { - // fudge = 1; - // } - - if ( quality === "better" ) { - var c = new conrec.Conrec(); - - try { - var xcoord = imexam.ndops.iota(0, data.shape[0]-1).map(function(x) { return x*binning+(binning-1)/2 +1.0 }) - var ycoord = imexam.ndops.iota(0, data.shape[1]-1).map(function(x) { return x*binning+(binning-1)/2 +1.0 }) - - //var xcoord = imexam.ndops.iota(1, data.shape[0]).map(function(x) { return (x-(binning-1)/2) * binning + fudge }) - //var ycoord = imexam.ndops.iota(1, data.shape[1]).map(function(x) { return (x-(binning-1)/2) * binning + fudge }) - - c.contour(data - , 0, data.shape[0]-1, 0, data.shape[1]-1 , xcoord, ycoord - , level.length, level); - } catch (e) { - alert("Too many coutour segments: Check your coutour levels.\n\nAre you trying to coutour the background levels of an image?"); - return; - } - - contours = c.contourList().map(function(contour) { - return { shape: "polygon", pts: contour }; - }); - } else { - var points = []; - contours = []; - - contours.push({ shape: "polygon", pts: points }); - - contfv(level, data.shape[0], data.shape[1], data.data - , function(x, y, level) { - if ( level === undefined ) { - points = []; - contours.push({ shape: "polygon", pts: points }); - } else { - //points.push({ x: (x+0.5-(binning-1)/2) * binning + fudge, y: (y+0.5-(binning-1)/2) * binning + fudge }); - points.push({ x: x*binning + 0.5, y: y*binning + 0.5 }); - } - }); - contours.length = contours.length-1; - } - - - JS9.NewShapeLayer("contour", JS9.Catalogs.opts, {display: im}); - JS9.RemoveShapes("contour", {display: im}); - JS9.AddShapes("contour", contours, {color: "yellow"}, {display: im}); - } - finally { - JS9.waiting(false); - } - }, 200); - } - - function getMinMax(div, display) { - var im = JS9.GetImage({display: display}); - - if ( im ) { - var form = $(div).find(".contour-form")[0]; - var data = imexam.ndops.ndarray(im.raw.data, [im.raw.width, im.raw.height]); - - form.min.value = imexam.ndops.minvalue(data).toFixed(2); - form.max.value = imexam.ndops.maxvalue(data).toFixed(2); - } - } - - function makeLevel(div, display) { - var i; - var im = JS9.GetImage({display: display}); - - if ( im ) { - var form = $(div).find(".contour-form")[0]; - - var n = Number(form.nlevel.value); - var level = imexam.ndops.ndarray(imexam.ndops.iota(1, n)); - - var min = Number(form.min.value); - var max = Number(form.max.value); - - imexam.ndops.divs(level, level, n+1); // Try n levels from min to max. - imexam.ndops.muls(level, level, max-min); - imexam.ndops.adds(level, level, min); - - var levText = []; - for ( i = 0; i < level.shape[0]; i++ ) { - levText.push(level.data[i].toFixed(2)); - } - - form.level.value = levText.join("\n"); - } - } - - function contInit() { - var im = JS9.GetImage({display: this.display}); - var div = this.div; - - div.innerHTML = '
    \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ -
    Num:
    Min:
    Max:
    Levels: \ -
    \ - Binning:       \ - \ - pix \ -
    \ - Smoothing:  \ - \ - pix \ -
    \ - Quality:  \ - faster \ - better \ -
    \ -

    \ -

    '; - - var display = this.display; - - $(div).find(".drw-contour").on("mouseup", function () { drawContours(div, display); }); - $(div).find(".get-min-max").on("mouseup", function () { getMinMax(div, display); }); - $(div).find(".make-levels").on("mouseup", function () { makeLevel(div, display); }); - - - if ( im !== undefined ) { - getMinMax(div, display); - makeLevel(div, display); - } - - imexam.fixupDiv(this); - } - - JS9.RegisterPlugin("ImExam", "Contours", contInit, { - menu: "view", - - winTitle: "Contours", - menuItem: "Contours", - help: "imexam/contours.html", - - toolbarSeparate: true, - - winDims: [400, 300], - }); -}()); - - - - -},{"./bin":1,"./conrec":2,"./contfv":3,"./imexam":undefined}]},{},[4]); - - diff --git a/web/static/js9_old/plugins/imexam/contours.html b/web/static/js9_old/plugins/imexam/contours.html deleted file mode 100644 index aeed66446f9c957c8162306a5b02d38104119658..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/imexam/contours.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - -JS9 Contours Plugin - - - -
    - -

    - -

    Contours

    - -Contours levels can be overlaid on the displayed image. - -

    -The N entry box controls the number of contours levels to draw. - -

    -Pressing the Draw Contours button will draw contours at the image levels -currently listed in the Levels: list. - -

    -Pressing the Set Min/Max button will fill in the min and max entry boxes -from the minimum and maximum values of the image. - -

    -Pressing the Make Levels will fill in the levels list with an evenly -spaced list of level values from min to max excluding the min and max values -themselves. - -

    -The Binning option allows the image data to be binned before -the contours are computed. Contours will be computed more quickly for -binned images. However, binning will cause the positions of the contours -to be less accurate. - -

    -The Smooth option causes the image data to be smoothed by a Gaussian kernel -with the specified sigma number of pixels before the contours are computed. -This technique often is necessary to achieve good results for sparse data -(e.g. event files). However, it can affect the accuracy of the contours. - -

    -The Quality radio button chooses between one of two contouring methods. -The faster option selects contours with up to 4 points per pixel. The quality -option selects contours with up to 8 points to pixel. - -

    - - diff --git a/web/static/js9_old/plugins/imexam/encircled.js b/web/static/js9_old/plugins/imexam/encircled.js deleted file mode 100644 index b4c3ed416975e27a98ed5a0f23c5fce0d83076a3..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/imexam/encircled.js +++ /dev/null @@ -1,71 +0,0 @@ -/*jslint white: true, vars: true, plusplus: true, nomen: true, unparam: true */ -/*globals $, JS9 */ - -"use strict"; - - -(function() { - var imexam = require("./imexam"); - - var encen_template = " \ -
    \ - \ - \ - \ -
    ee50{ee50%.2f}
    ee80{ee80%.2f}
    \ -
    "; - - function energUpdate(im, xreg) { - var div = this.div; - - var imag = imexam.getRegionData(im, xreg); - - var backgr = imexam.imops.backgr(imag, 4).value; - var data = imexam.ndops.assign(imexam.ndops.zeros(imag.shape), imag); - - imexam.ndops.subs(data, imag, backgr); - - var qcenter = imexam.ndops.qcenter(data); - var centroid = imexam.ndops.centroid(data, qcenter); - - var encen = imexam.imops.encen(data, [centroid.ceny, centroid.cenx]); - - var stat = {}; - stat.ee80 = imexam.ndops.indexof(encen, 0.80); - stat.ee50 = imexam.ndops.indexof(encen, 0.50); - - var edata = []; - var i; - - for ( i = 0; i < encen.shape[0]; i++ ) { - edata[i] = [i, encen.get(i)]; - } - - $(div).empty(); - var plot = $.plot(div, [edata] - , { selection: { mode: "xy" } }); - - $(div).append(imexam.template(encen_template, stat)); - } - - function energInit() { - imexam.fixupDiv(this); - $(this.div).append("

    create, click, move, or resize a region to see encircled energy
    "); - } - - JS9.RegisterPlugin("ImExam", "EncEnergy", energInit, { - menu: "analysis", - - menuItem: "Encircled Energy", - winTitle: "Encircled Energy", - help: "imexam/imexam.html#enener", - - dynamicSelect: true, - - toolbarSeparate: true, - - onregionschange: energUpdate, - winDims: [250, 250], - }); - -}()); diff --git a/web/static/js9_old/plugins/imexam/imcnts.js b/web/static/js9_old/plugins/imexam/imcnts.js deleted file mode 100644 index 4069d7ae4f035450c3a27f0a5888634c973f8c6c..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/imexam/imcnts.js +++ /dev/null @@ -1,133 +0,0 @@ -/*jslint white: true, vars: true, plusplus: true, nomen: true, unparam: true */ -/*globals $, JS9, imexam, Int32Array */ - -"use strict"; - - -(function() { - var imexam = require("./imexam"); - var template = imexam.template; - var mask = imexam.ndops.mask; - - function runImCnts(im, xreg) { - var i; - var div = this.div; - var text = $(div).find(".imcnts-result")[0]; - - var data = imexam.ndops.ndarray(im.raw.data, [im.raw.height, im.raw.width]); - - var regs = JS9.GetRegions({display: im}); - var mimg = imexam.ndops.zeros(data.shape, Int32Array); - - var list = mask.listRegions(regs); - mask.drawRegions(list, mimg.data, mimg.shape[0]); - - var cnts = imexam.ndops.imcnts(data, mimg, list.length+1); - - var backgr_cnts = 0, backgr_area = 0; - - var back = []; - var srce = []; - var net, regno; - - for ( i = 0; i < list.length; i++ ) { - if ( mask.hasTag(list[i], "background") ) { - regno = list[i].regno; - - backgr_cnts += cnts.cnts.get(regno); - backgr_area += cnts.area.get(regno); - - back.push({ regno: regno, cnts: cnts.cnts.get(regno), area: cnts.area.get(regno) }); - } - } - - for ( i = 0; i < list.length; i++ ) { - if ( mask.hasTag(list[i], "source") && !mask.hasTag(list[i], "exclude") ) { - regno = list[i].regno; - - if ( backgr_area > 0 ) { - net = cnts.cnts.get(regno) - (backgr_cnts * (cnts.area.get(regno)/backgr_area)); - } else { - net = cnts.cnts.get(regno); - } - - srce.push({ regno: regno, net: net, cnts: cnts.cnts.get(regno), area: cnts.area.get(regno) }); - } - } - - $(text).html("Source\n" - + "regno counts area net\n" - + "----- ------ ---- ---\n" - + srce.map(function(x, i) { return template("{regno%5d} {cnts%14.3f} {area%10.3f} {net%14.3f}", x); }).join("\n") - + "\n\nBackground\n" - + "regno counts area\n" - + "----- ------ ----\n" - + back.map(function(x, i) { return template("{regno%5d} {cnts%14.3f} {area%10.3f}", x); }).join("\n")); - } - -/* - function getRegions(div, display) { - var im = JS9.GetImage({display: display}); - - if ( im ) { - var data = imexam.ndops.ndarray(im.raw.data); - var form = $(div).find(".imcnts-form")[0]; - - form.min.value = imexam.ndops.minvalue(data).toFixed(2); - form.max.value = imexam.ndops.maxvalue(data).toFixed(2); - } - } - */ - - function imcntsInit() { - var div = this.div; - -/* - div.innerHTML = '

    \ - \ - \ - \ - \ - \ - \ -
    SourceBackground
    \ - \ -
    Results
    \ -
    \ -

    \ -

    '; - */ - - div.innerHTML = '
    \ - \ - \ - \ -
    Counts in Regions
    \ -
    \ -

    \ -

    '; - - //var display = this.display; - //$(div).find(".run-imcnts").on("mouseup", function () { runImCnts (div, display); }); - //$(div).find(".get-regions").on("mouseup", function () { getRegions(div, display); }); - - imexam.fixupDiv(this); - } - - JS9.RegisterPlugin("ImExam", "ImCnts", imcntsInit, { - menu: "analysis", - - winTitle: "ImCounts", - menuItem: "ImCounts", - help: "imexam/imcnts.html", - - toolbarSeparate: true, - - onregionschange: runImCnts, - winDims: [600, 250], - }); -}()); diff --git a/web/static/js9_old/plugins/imexam/imexam.html b/web/static/js9_old/plugins/imexam/imexam.html deleted file mode 100644 index 65744fdafdda3f771da59ba51c2a1540ee44ac56..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/imexam/imexam.html +++ /dev/null @@ -1,126 +0,0 @@ - - - - - -JS9 Imexam Plugins - - - -
    - -

    JS9 Imexam Plugins

    - -These tasks perform various types of image analysis using a rectangular box -surrounding the selected region. That is, the actual region shape is ignored -and the analysis reflects a rectangular section of image pixels. The selected -section can be rotated for box, ellipse, and line regions. For a line region, -the width is the length of the line, while the height is set to the value of -the JS9.globalOpts.imexamLineHeight parameter (default is 1). - -

    - -

    Region Statistics

    - -A rectangular box of image pixels is selected and some statistical -values are computed from the data. - -
    -

    Notes

    - -
      -
    • Totcounts and bscounts -

      - Totcounts are the total counts in the box region, while bscounts - has the calculated background (see below) subtracted from the total. - -

    • Background and Noise -

      - The background and noise are obtained from the outer 4 pixel-wide - perimeter of the selected region. The background value is the median - value of this area and the noise value is the RMS. -

    • -
    • Centroid -

      - The centroid is obtained by locating the brightest 9 pixel box and - computing the centroid of the background subtracted data about this point. -

    • -
    • FWHM -

      - The FWHM is estimated from the image moments about the centroid, assuming - a Gaussian distribution. -

    • -
    -
    - -

    - -

    X and Y Projection Plot

    - -A rectangular box of image pixels is selected and the projection along -the region's X (width) or Y (height) axis is plotted. The sum, -average, or median of the projected pixels may be selected. - -

    - -

    Radial Profile

    - -A rectangular box of image pixels is selected and the pixels values -are plotted against their respective radii. A Gaussian is fit to the -radial profile data and the result is also plotted. The fitted -results of the 4 parameter fit are displayed with the plot. - -

    -The center pixel from which the radii are computed is determined from the -background subtracted centroid taken about the brightest 9 pixels in the data -(same centroid as is displayed in the region stats plugin). - - -

    - -

    Pixel Value Histogram

    - -A rectangular box of image pixels is selected and a histogram of the -values is plotted. The selected pixels are binned into 250 bins -between the minimum and maximum value found in the selected region. - -

    - -

    Encircled Energy

    - -A rectangular box of image pixels is selected and background subtracted. The -analysis radius is determined from the region as follows: - -
      -
    • circle: region radius
    • -
    • annulus: max annulus radius
    • -
    • box: half the average height an width
    • -
    • ellipse: average axis radius
    • -
    • polygon: half the average of the height and width of polygon bounding box
    • -
    - -The values within the analysis radius are binned in 1 pixel radial bins. The -bins are normalized by the sum of all pixels and the result is plotted. - -

    -The background is obtained as the median from the outer 4 pixel wide perimeter of the -selected region. - -

    -The center pixel from which the encircled energy is computed is determined from -the background subtracted centroid taken about the brightest 9 pixels in the -data (same centroid as is displayed in the region stats plugin). - -

    -The 50 and 80 percent encircled energy points are displayed over the plot. - -

    - -

    3d Surface Plot

    - -A rectangular box of image pixels is selected and plotted as a surface. - -
    - - diff --git a/web/static/js9_old/plugins/imexam/imexam.js b/web/static/js9_old/plugins/imexam/imexam.js deleted file mode 100644 index 6a100631160bcb32de85e3e0c4f7bbe44abbef0a..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/imexam/imexam.js +++ /dev/null @@ -1,2543 +0,0 @@ -require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 17 ) { break;} - } - console.log(line); - } else { - for ( y = a.shape[0]-1; y >= 0; --y ) { - line = ""; - for ( x = 0; x < a.shape[1]; ++x ) { - line += a.get(y, x).toFixed(prec) + " "; - } - - console.log(line); - } - console.log("\n"); - } -}; - -ndops._hist = typed(function (a, width , min, max) { - var size = Math.floor((max-min) / width); - var h = new Int32Array(size+1); - - // ----- - if( !isNaN(a) ){ - var bin = Math.max(0, Math.min(size, Math.round((a-min)/width))) | 0; // | is truncate - h[bin]++; - } - // ----- - - return h; -}); - - - -ndops.hist = function(a, width, min, max) { - var hist = {}; - var reply; - - if ( min === undefined ) { - min = ndops.minvalue(a); - } - if ( max === undefined ) { - max = ndops.maxvalue(a); - } - if ( width === undefined ) { - width = Math.max(1, (max-min) / 250); - } - - hist.raw = a; - - hist.min = min; - hist.max = max; - hist.width = width; - - reply = ndops._hist(a, width, min, max); - hist.data = ndops.ndarray(reply, [reply.length]); - - return hist; -}; - -ndops.proj = function(a, axis) { - var sect; - var i; - - //var proj = ndops.ndarray(ndops._proj(a, axis, new Float32Array(a.shape[axis === 0 ? 1 : 0]), [a.shape[axis === 0 ? 1 : 0]])); - - var proj = {}; - proj.n = a.shape[axis === 1 ? 0 : 1]; - proj.x = a.shape[axis]; - - proj.sum = []; - proj.avg = []; - proj.med = []; - - var copy = ndops.assign(ndops.zeros(a.shape), a); - - for ( i = 0; i < proj.n; i++ ) { - if ( axis === 0 ) { - sect = ndops.section(copy, [[i, i+1], [0, proj.x]]); - } else { - sect = ndops.section(copy, [[0, proj.x], [i, i+1]]); - } - - proj.sum[i] = ndops.sum(sect); - proj.avg[i] = ndops.sum(sect)/proj.n; - proj.med[i] = ndops.median(sect); - } - - return proj; -}; - -ndops.qcenter = typed(function (a) { - var start = [], end = []; - var max = Number.MIN_VALUE; - var idx; - var iX = 0, iY = 0; - - start[0]++; - start[1]++; - end[0]--; - end[1]--; - - // ---- - var sum = - + a[iY-1][iX-1] - + a[iY-1][iX ] - + a[iY-1][iX+1] - + a[iY ][iX-1] - + a[iY ][iX ] - + a[iY ][iX+1] - + a[iY+1][iX-1] - + a[iY+1][iX ] - + a[iY+1][iX+1]; - - if ( max < sum ) { - max = sum; - idx = [iX, iY]; - } - // ---- - - return idx; -}); - -ndops._imcnts = typed({ consider: { c: false } }, function (c, a, b) { c[b] += a; }); - -ndops.imcnts = function (a, b, n) { - var reply = {}; - reply.cnts = ndops.ndarray(ndops._imcnts(new Float32Array(n), a, b)); - reply.area = ndops.hist(b, 1, 0, n-1).data; - - return reply; -}; - - -ndops._centroid = typed(function (a, nx, ny) { - var sum = 0; - var sumx = 0; - var sumy = 0; - var sumxx = 0; - var sumyy = 0; - - var r = nx*nx+ny*ny; - - var iX = 0, iY = 0; - - // ---- - if ( a > 0 && iX*iX + iY*iY < r ) { - sum += a; - sumx += a * iX; - sumxx += a * iX * iX; - sumy += a * iY; - sumyy += a * iY * iY; - } - - // ---- - - var reply = {}; - - reply.sum = sum; - reply.cenx = sumx/sum; - reply.ceny = sumy/sum; - - reply.rmom = ( sumxx - sumx * sumx / sum + sumyy - sumy * sumy / sum ) / sum; - - if ( reply.rmom <= 0 ) { - reply.fwhm = -1.0; - } else { - reply.fwhm = Math.sqrt(reply.rmom) * 2.354 / Math.sqrt(2.0); - } - - return reply; -}); - -ndops.centroid = function(a) { - var reply = ndops._centroid(a, a.shape[0], a.shape[1]); - - return reply; -}; - -ndops.flatten = function() { - var size = 0; - var i, n, a; - - for ( i = 0; i < arguments.length; i++ ) { - size += arguments[i].size; - } - - var reply = ndops.zeros([size]); - var off = 0; - - for ( n = 0; n < arguments.length; n++ ) { - a = arguments[n]; - - ndops.assign(ndops.ndarray(reply.data, a.shape, undefined, off), a); - - off += a.size; - } - - return reply; -}; - -ndops.median = function(a) { - var data = ndops.assign(ndops.zeros(a.shape), a); - - Array.prototype.sort.call(data.data, function(a, b) { return a-b; }); - - var reply = data.data[Math.round((data.size-1)/2.0)]; - - return reply; -}; - - -ndops.rms = typed(function (a) { - var sum = 0; - var squ = 0; - // ---- - if( !isNaN(a) ){ - sum += a; - squ += a*a; - } - // ---- - - var mean = sum/a.size; - - return Math.sqrt((squ - 2*mean*sum + a.size*mean*mean)/(a.size-1)); -}); - -ndops.rmsClipped = typed(function (a, min, max) { - var n = 0; - var sum = 0; - var squ = 0; - // ---- - if ( !isNaN(a) && (min === null || a > min) && (max === null || a < max) ) { - n++; - sum += a; - squ += a*a; - } - // ---- - - var mean = sum/n; - - return Math.sqrt((squ - 2*mean*sum + n*mean*mean)/(n-1)); -}); - -ndops.meanClipped = typed(function (a, min, max) { - var n = 0; - var sum = 0; - // ---- - if ( !isNaN(a) && (min === null || a > min) && (max === null || a < max) ) { - n++; - sum += a; - } - // ---- - - return sum/n; -}); - -imops.backgr = function(data, width) { - var back = {}; - - var pixels = ndops.flatten( - ndops.section(data, [[0, width], [0, data.shape[1]]]) - , ndops.section(data, [[data.shape[0]-width, data.shape[0]], [0, data.shape[1]]]) - , ndops.section(data, [[width, data.shape[0]-width], [0, width]]) - , ndops.section(data, [[width, data.shape[0]-width], [data.shape[1]-width, data.shape[1]]])); - - - back.noise = ndops.rms(pixels); - back.value = ndops.median(pixels); - - return back; -}; - -imops.mksection = function(x, y, w, h) { - return [[Math.floor(x-(w/2)), Math.floor(x+(w/2))], - [Math.floor(y-(h/2)), Math.floor(y+(h/2))]]; -}; - -imops._rproj = typed(function (a, cx, cy, radius, length) { - var rad = new Float32Array(length); - var val = new Float32Array(length); - var r = Math.sqrt(radius*radius); - var i = 0; - - var iX = 0, iY = 0; - - // ---- - var d = Math.sqrt((iY-cy)*(iY-cy) + (iX-cx)*(iX-cx)); - - if ( (d <= r) && !isNaN(a) ) { - rad[i] = d; - val[i] = a; - - i++; - } - // ---- - - return { rad: rad.subarray(0, i), val: val.subarray(0, i), n: i }; -}); - -function sortArrays(a, b) { - var indexed; - - indexed = Array.prototype.map.call(a, function(itm, i){ return [itm, i, b[i]]; }); - - indexed.sort(function(a, b){ return a[0]-b[0]; }); - - indexed.map(function(itm, i) { - a[i] = itm[0]; - b[i] = itm[2]; - }); -} - -imops.rproj = function(im, center) { - var radius = (im.shape[0]/2 + im.shape[1]/2) / 2; - var data = imops._rproj(im, center[1], center[0], radius, im.size); - - sortArrays(data.rad, data.val); - - return { radi: ndops.ndarray(data.rad, [data.rad.length]) - , data: ndops.ndarray(data.val, [data.rad.length]), radius: radius }; -}; - - -imops._encen = typed(function (a, cx, cy, radius) { - var reply = new Float32Array(radius); - var sum = 0; - var RSq = radius*radius; - - var tot = 0; - var i; - - var iX = 0, iY = 0; - - // ---- - var x = iX - cx; - var y = iY - cy; - - var rsq = x*x+y*y; - - if ( a > 0 && rsq < RSq ) { - reply[Math.round(Math.sqrt(rsq))] += a; - sum += a; - } - // ---- - - - for ( i = 0; i < radius; i++ ) { - tot += reply[i]; - - reply[i] = tot / sum; - } - - return reply; -}); - - - -imops.encen = function(im, center) { - var radius = Math.floor((im.shape[0]/2 + im.shape[1]/2) / 2); - - var reply = imops._encen(im, center[1], center[0], radius); - - return ndops.ndarray(reply, [reply.length]); -}; - -ndops.indexof = function(a, x) { - var i; - - for ( i = 0; i < a.shape[0]; i++ ) { - - if ( x < a.get(i) ) { break; } - } - - if ( i === 0 ) { return 0; } - if ( i === a.shape[0] ) { return a.shape[0]; } - - return i + (x - a.get(i))/(a.get(i) - a.get(i-1)); -}; - -ndops.gauss1d = function(radi, x0) { - var reply = ndops.zeros(radi.shape); - - var a = x0[0]; - var b = 0; // x0[1]; - var c = x0[1]; - var d = x0[2]; - - ndops.fill(reply, function(i) { - var x = radi.data[i]-b; - - return a * Math.pow(2.71828, - x*x / (2*c*c)) + d; - }); - - return reply; -}; - -ndops.gsfit1d = function(radi, data, x0) { - - var reply = typed.uncmin(function(x) { - var modl = ndops.gauss1d(radi, x); - - ndops.sub(modl, modl, data); - ndops.mul(modl, modl, modl); - ndops.fill(modl, function(i) { - return modl.get(i)/(radi.get(i)*radi.get(i)); - }); - - var sum = ndops.sum(modl); - - return Math.sqrt(sum/radi.shape[0]); - - }, x0, 0.000001); - - // console.log(reply.message); - - return reply.solution; -}; - -function reg2section(xreg) { - - switch ( xreg.shape ) { - - case "annulus": - xreg.width = xreg.radii[xreg.radii.length-1]*2; - xreg.height = xreg.radii[xreg.radii.length-1]*2; - - break; - - case "circle": - xreg.width = xreg.radius*2; - xreg.height = xreg.radius*2; - - break; - - case "ellipse": - xreg.width = xreg.r1*2; - xreg.height = xreg.r2*2; - - break; - - case "polygon": - case "line": - var i, xx = 0, yy = 0, minx = 1000000, maxx = 0, miny = 1000000, maxy = 0; - - for ( i = 0; i < xreg.pts.length; i++ ) { - xx += xreg.pts[i].x; - yy += xreg.pts[i].y; - - if ( xreg.pts[i].x > maxx ) { maxx = xreg.pts[i].x; } - if ( xreg.pts[i].x < minx ) { minx = xreg.pts[i].x; } - if ( xreg.pts[i].y > maxy ) { maxy = xreg.pts[i].y; } - if ( xreg.pts[i].y < miny ) { miny = xreg.pts[i].y; } - } - - xreg.x = xx/xreg.pts.length; - xreg.y = yy/xreg.pts.length; - - if( xreg.shape === "line" && xreg.pts.length === 2 ){ - xreg.width = Math.sqrt(((xreg.pts[0].x - xreg.pts[1].x) * - (xreg.pts[0].x - xreg.pts[1].x)) + - ((xreg.pts[0].y - xreg.pts[1].y) * - (xreg.pts[0].y - xreg.pts[1].y))); - xreg.height = JS9.globalOpts.imexamLineHeight || 1; - xreg.angle = Math.atan2(xreg.pts[1].y - xreg.pts[0].y, - xreg.pts[1].x - xreg.pts[0].x); - xreg.angle = xreg.angle * 180 / Math.PI; - } else { - xreg.width = maxx - minx; - xreg.height = maxy - miny; - } - break; - - case "text": - xreg.width = 10; - xreg.height = 10; - break; - - default: - break; - } - - return imops.mksection(xreg.x, xreg.y, xreg.width, xreg.height); -} - -exports.getRegionData = function (im, xreg) { - var section = reg2section(xreg); - var im_2d = ndops.ndarray(im.raw.data, [im.raw.height, im.raw.width]); - var imag; - - if ( xreg.angle && xreg.angle !== 0 ) { - imag = ndops.zeros([xreg.height, xreg.width]); - - ndops.rotate(imag, im_2d, xreg.angle/57.29577951, xreg.y, xreg.x); - } else { - imag = ndops.section(im_2d, section); - } - - return imag; -}; - -exports.convolve1d = typed(function(kernel, data, output) { - var i, j, x; - var half = Math.round(kernel.shape[0]/2.0); - - for ( i = 0; i < data.shape[0]; i++ ) { - for ( j = 0; j < kernel.shape[0]; j++ ) { - x = i+j-half; - - if ( x >= 0 && x < data.shape[0] ) { - output[i] += kernel[j] * data[x]; - } - } - } -}); - -exports.convolve2dSep = function(kernel, data, output) { - var x, y, i, xx, yy; - - var nx = data.shape[1]; - var ny = data.shape[0]; - var nk = kernel.shape[0]; - - var half = Math.floor(nk/2.0); - - // Run the kernel 1d over each row - // - for ( y = 0; y < ny; y++ ) { - for ( x = 0; x < nx; x++ ) { - output[y][x] = 0; - - for ( i = 0; i < nk; i++ ) { - xx = x+i-half; - - if ( xx > 0 && xx < nx ) { - output[y][x] += data[y][xx]*kernel[i]; - } - } - } - } - - // Run the kernel 1d over each column - // - for ( x = 0; x < nx; x++ ) { - for ( y = 0; y < ny; y++ ) { - - for ( i = 0; i < nk; i++ ) { - yy = y+i-half; - - if ( yy > 0 && yy < ny ) { - output[y][x] += data[y+i][x]*kernel[i]; - } - } - } - } -}; - - -exports.reg2section = reg2section; -exports.template = template; - -exports.ndops = ndops; -exports.typed = ndops; -exports.imops = imops; - - -},{"./mask.js":1,"./template":12,"typed-array-function":4,"typed-array-ops":5,"typed-array-rotate":8,"typed-numeric-uncmin":10}],1:[function(require,module,exports){ -/*jslint white: true, vars: true, plusplus: true, nomen: true, unparam: true */ -/*globals $ */ - -"use strict"; - -// source -// background -// exclude - -(function() { - var raster = require("./raster"); - - function hasTag(reg, tag) { - var i; - - for ( i = 0; i < reg.tags.length; i++ ) { - if ( reg.tags[i] === tag ) { return true; } - } - - return false; - } - exports.hasTag = hasTag; - - exports.listRegions = function (regs) { - var i, j; - var reg, regno = 1; - - var reply = []; - - for ( i = 0; i < regs.length; i++ ) { - reg = regs[i]; - - switch ( reg.shape ) { - case "annulus": - for ( j = 0; j < reg.radii.length; j++ ) { - if ( reg.radii[j] !== 0.0 ) { - reply[regno-1] = $.extend($.extend({}, reg), { regno: regno++, shape: "circle", radius: reg.radii[j] }); - } - } - break; - default: - reply[regno-1] = $.extend({ regno: regno++ }, reg); - break; - } - } - - return reply; - }; - - exports.drawRegions = function (regs, buffer, width) { - var reg, t, i; - - var type = [ "include", "exclude" ]; - - for ( t = 0; t < 2; t++ ) { - for ( i = regs.length - 1; i >= 0; i-- ) { - reg = regs[i]; - - if ( hasTag(reg, type[t]) ) { - switch ( reg.shape ) { - case "polygon": raster.drawPolygon(buffer, width, reg.pts, reg.regno); break; - case "circle": raster.drawCircle( buffer, width, reg.x, reg.y, reg.radius, reg.regno); break; - case "box": raster.drawBox( buffer, width, reg.x, reg.y, reg.width, reg.height, reg.angle, reg.regno); break; - case "ellipse": raster.drawEllipse(buffer, width, reg.x, reg.y, reg.r1, reg.r2, reg.angle, reg.regno); break; - } - } - } - } - }; -}()); - - -},{"./raster":11}],2:[function(require,module,exports){ -"use strict" - -var iota = require("iota-array") - -var arrayMethods = [ - "concat", - "join", - "slice", - "toString", - "indexOf", - "lastIndexOf", - "forEach", - "every", - "some", - "filter", - "map", - "reduce", - "reduceRight" -] - -function compare1st(a, b) { - return a[0] - b[0] -} - -function order() { - var stride = this.stride - var terms = new Array(stride.length) - var i - for(i=0; iMath.abs(this._stride1))?[1,0]:[0,1]}})") - } else if(dimension === 3) { - code.push( -"var s0=Math.abs(this._stride0),s1=Math.abs(this._stride1),s2=Math.abs(this._stride2);\ -if(s0>s1){\ -if(s1>s2){\ -return [2,1,0];\ -}else if(s0>s2){\ -return [1,2,0];\ -}else{\ -return [1,0,2];\ -}\ -}else if(s0>s2){\ -return [2,0,1];\ -}else if(s2>s1){\ -return [0,1,2];\ -}else{\ -return [0,2,1];\ -}}})") - } - } else { - code.push("ORDER})") - } - } - - //view.set(i0, ..., v): - code.push([ -"proto.set=function ",className,"_set(", args.join(","), ",v){"].join("")) - if(useGetters) { - code.push(["return this.data.set(", index_str, ",v)}"].join("")) - } else { - code.push(["return this.data[", index_str, "]=v}"].join("")) - } - - //view.get(i0, ...): - code.push(["proto.get=function ",className,"_get(", args.join(","), "){"].join("")) - if(useGetters) { - code.push(["return this.data.get(", index_str, ")}"].join("")) - } else { - code.push(["return this.data[", index_str, "]}"].join("")) - } - - //view.index: - code.push([ - "proto.index=function ", - className, - "_index(", args.join(), "){return ", - index_str, "}"].join("")) - - //view.hi(): - code.push(["proto.hi=function ",className,"_hi(",args.join(","),"){return new ", className, "(this.data,", - indices.map(function(i) { - return ["(typeof i",i,"!=='number'||i",i,"<0)?this._shape", i, ":i", i,"|0"].join("") - }).join(","), ",", - indices.map(function(i) { - return "this._stride"+i - }).join(","), ",this.offset)}"].join("")) - - //view.lo(): - var a_vars = indices.map(function(i) { return "a"+i+"=this._shape"+i }) - var c_vars = indices.map(function(i) { return "c"+i+"=this._stride"+i }) - code.push(["proto.lo=function ",className,"_lo(",args.join(","),"){var b=this.offset,d=0,", a_vars.join(","), ",", c_vars.join(",")].join("")) - for(var i=0; i=0){\ -d=i",i,"|0;\ -b+=c",i,"*d;\ -a",i,"-=d}"].join("")) - } - code.push(["return new ", className, "(this.data,", - indices.map(function(i) { - return "a"+i - }).join(","),",", - indices.map(function(i) { - return "c"+i - }).join(","), ",b)}"].join("")) - - //view.step(): - code.push(["proto.step=function ",className,"_step(",args.join(","),"){var ", - indices.map(function(i) { - return "a"+i+"=this._shape"+i - }).join(","), ",", - indices.map(function(i) { - return "b"+i+"=this._stride"+i - }).join(","),",c=this.offset,d=0,ceil=Math.ceil"].join("")) - for(var i=0; i=0){c=(c+this._stride",i,"*i",i,")|0}else{a.push(this._shape",i,");b.push(this._stride",i,")}"].join("")) - } - code.push("var ctor=CTOR_LIST[a.length+1];return ctor(this.data,a,b,c)}") - - //Add return statement - code.push(["return function construct_",className,"(data,shape,stride,offset){return new ", className,"(data,", - indices.map(function(i) { - return "shape["+i+"]" - }).join(","), ",", - indices.map(function(i) { - return "stride["+i+"]" - }).join(","), ",offset)}"].join("")) - - //Compile procedure - var procedure = new Function("CTOR_LIST", "ORDER", code.join("\n")) - return procedure(CACHED_CONSTRUCTORS[dtype], order) -} - -function arrayDType(data) { - if(data instanceof Float64Array) { - return "float64"; - } else if(data instanceof Float32Array) { - return "float32" - } else if(data instanceof Int32Array) { - return "int32" - } else if(data instanceof Uint32Array) { - return "uint32" - } else if(data instanceof Uint8Array) { - return "uint8" - } else if(data instanceof Uint16Array) { - return "uint16" - } else if(data instanceof Int16Array) { - return "int16" - } else if(data instanceof Int8Array) { - return "int8" - } else if(data instanceof Uint8ClampedArray) { - return "uint8_clamped" - } else if(data instanceof Array) { - return "array" - } - return "generic" -} - -var CACHED_CONSTRUCTORS = { - "float32":[], - "float64":[], - "int8":[], - "int16":[], - "int32":[], - "uint8":[], - "uint16":[], - "uint32":[], - "array":[], - "uint8_clamped":[], - "generic":[] -} - -;(function() { - for(var id in CACHED_CONSTRUCTORS) { - CACHED_CONSTRUCTORS[id].push(compileConstructor(id, -1)) - } -}); - -function wrappedNDArrayCtor(data, shape, stride, offset) { - if(data === undefined) { - var ctor = CACHED_CONSTRUCTORS.array[0] - return ctor([]) - } else if(typeof data === "number") { - data = [data] - } - if(shape === undefined) { - shape = [ data.length ] - } - var d = shape.length - if(stride === undefined) { - stride = new Array(d) - for(var i=d-1, sz=1; i>=0; --i) { - stride[i] = sz - sz *= shape[i] - } - } - if(offset === undefined) { - offset = 0 - for(var i=0; i=0;i-=2) { ret[i+1] = v; ret[i] = v; } - if(i===-1) { ret[0] = v; } - return ret; - } - for(i=n-1;i>=0;i--) { ret[i] = rep(s,v,k+1); } - return ret; - } - - function repeat(pattern, count) { - if (count < 1) { return ''; } - - var result = ''; - while (count > 0) { - if ( count & 1 ) { result += pattern; } - - count >>= 1; pattern += pattern; - } - return result; - } - - - - - function replaceIdentifierRefs(str, func) { - var reply = ""; - - var state = -1, match, index, first, i = 0, x; - - while ( i < str.length ) { - match = str.match(/[a-zA-Z_][a-zA-Z0-9_]*/); // Find an identifier in the string. - - if ( !match ) { break; } - - reply += str.substr(i, match.index); - - index = []; - i = match.index + match[0].length; - - x = true; - while ( x && i < str.length ) { - while ( str[i] === ' ' ) { i++; } - - switch ( str[i] ) { - case "[": - state = 1; - first = i+1; - i++; - - while ( state ) { - if ( str[i] === ']' ) { - if ( state === 1 ) { index.push(str.substring(first, i)); } - state--; - } - if ( str[i] === '[' ) { state++; } - i++; - } - break; - case "." : - first = i; - i++; - while ( str[i] === ' ' ) { i++; } - while ( str[i].match(/[ a-zA-Z0-9_]/) !== null ) { i++; } - - index.push(str.substring(first, i)); - - break; - default: - x = false; - break; - } - } - - reply += func(match[0], index); - str = str.substr(i); - i = 0; - } - - return reply + str.substr(i); - } - - - function typedArrayFunctionConstructor() { - var actuals = arguments; - var i, j; - var args; - var text; - var hash = {}; - - var body; - - if ( this.cache === undefined ) { - if ( typeof this.func === "string" ) { - text = this.func; - } else { - text = this.func.toString(); - } - this.text = text; - - var x = text.match(/function [A-Za-z0-9_]*\(([^()]*)\)[^{]*\{([\S\s]*)\}[\S\s]*/); // } - - args = x[1].split(",").map(function(s) { return s.trim(); }); - this.args = args; - - this.prep = ""; - this.post = ""; - - body = x[2].split(/\/\/ ----+/); - - if ( body.length > 1 ) { - this.prep = body[0]; - this.post = body[2]; - this.body = body[1]; - } else { - this.body = body[0]; - } - if ( this.post === "" || this.post === undefined ) { - this.post = "\nreturn " + args[0] + ";"; - } - } - args = this.args; - text = this.text; - - var opts = this.opts; - - if ( opts === undefined ) { opts = {}; } - - var type = ""; - var dime = 0; - var func; - - for ( i = 0; i < args.length; i++ ) { - if ( actuals[i] !== null && actuals[i] !== undefined && typeof actuals[i] === "object" - && (opts.consider === undefined || ( typeof opts.consider === "object" && opts.consider[args[i]] !== false )) ) { - - hash[args[i]] = actuals[i]; - - if ( !actuals[i].shape ) { - actuals[i].shape = dim(actuals[i]); - } - - dime = Math.max(actuals[i].shape.length, dime); - - if ( actuals[i].data ) { - type += " " + actuals[i].dtype + " " + actuals[i].offset + " " + " " + actuals[i].stride; - } else { - type += " O"; - } - - } else { - type += " X"; - } - } - type = dime + type; - - if ( this.cache ) { - func = this.cache[type]; - - if ( func ) { return func; } - } - - var prep = this.prep; - body = this.body; - var post = this.post; - var dims = []; - - var indicies = [ "iW", "iV", "iU", "iZ", "iY", "iX" ]; - var hasIndex = false; - - // Match each source code identifier and any associated array indexing. Extract - // the indicies and recursivly replace them also. - // - function replaceArrayRefs(text) { - - return replaceIdentifierRefs(text, function (id, indx) { - var k, offset, reply; - - if ( id === "index" ) { hasIndex = true; } - - for ( k = 0; k < indx.length; k++ ) { - indx[k] = replaceArrayRefs(indx[k]); - } - - var arg = hash[id]; - var dimen; - var joinStr, bracket, fixindx; - - - if ( arg !== undefined && typeof arg === "object" ) { - - if ( indx.length >= 1 && indx[indx.length-1].trim() === ".length" ) { - indx[0] = ".shape"; - indx[1] = indx.length-1; - indx.length = 2; - } - - if ( indx.length >= 1 && indx[0][0] === "." ) { - if ( indx.length >= 2 && indx[0].trim() === ".shape" ) { - if ( arg.data ) { - reply = id + ".shape[" + indx[1] + "]"; - } else { - reply = id + repeat("[0]", indx[1]) + ".length"; - } - } else { - reply = id + indx[0].trim(); - } - } else { - if ( arg.data ) { - dimen = arg.dimension; - - - if ( indx.length !== 0 && indx.length < arg.dimension ) { - id = id + ".data.subarray"; - bracket = "()"; - fixindx = indx.length; - } else { - id = id + ".data"; - bracket = "[]"; - fixindx = arg.dimension; - } - - joinStr = " + "; - } else { - dimen = arg.shape.length; - joinStr = "]["; - offset = ""; - bracket = "[]"; - } - - var indi = indicies.slice(6-dimen); - - if ( ( opts.loops === undefined || opts.loops === true ) && ( indx.length === 0 || dimen === indx.length ) ) { - for ( i = 0; i < dimen; i++ ) { - if ( indx[i] === undefined ) { indx[i] = indi[i]; } - if ( dims[i] === undefined ) { dims[i] = 0; } - - dims[i] = Math.max(dims[i], arg.shape[i]); - } - } - - if ( arg.data ) { - for ( i = 0; i < fixindx; i++ ) { - if ( arg.stride[i] !== 1 ) { indx[i] = "(" + indx[i] + ")*" + arg.stride[i]; } - } - - if ( arg.offset !== 0 ) { offset = arg.offset + " + "; - } else { offset = ""; } - } - - if ( indx.length ) { - reply = id + bracket[0] + offset + indx.join(joinStr) + bracket[1] + " "; - } else { - reply = id; - } - } - } else { - reply = id; - - for ( i = 0; i < indx.length; i++ ) { - if ( indx[i][0] === "." ) { - reply += indx[i].trim(); - } else { - reply += "[" + indx[i].trim() + "]"; - } - } - reply += " "; - } - - return reply; - }); - } - - body = replaceArrayRefs(body); - - var indx = indicies.slice(6-dims.length); - var indi = indicies.slice(6-dims.length).reverse(); - dims.reverse(); - - var init = "\n"; - var setp = "\n"; - - var indxZero = ""; - var indxIncr = ""; - - if ( opts.loops === undefined || opts.loops === true ) { - init += " var index = [" + rep([dims.length], 0).join(",") + "];\n"; - init += " var start = [" + rep([dims.length], 0).join(",") + "];\n"; - init += " var end = [" + rep([dims.length], 0).join(",") + "];\n\n"; - - for ( i = 0; i < dims.length; i++ ) { - - for ( j = 0; j < args.length; j++ ) { - if ( hash[args[j]] && actuals[j] !== undefined && typeof actuals[j] === "object" ) { - init += " end[" + i + "] = " + args[j] + ".shape[" + i + "];\n"; - break; - } - } - } - init += "\n"; - - for ( i = 0; i < dims.length; i++ ) { - setp += " var " + indx[i] + "start = start[" + i + "];\n"; - setp += " var " + indx[i] + "end = end[" + i + "];\n"; - - } - setp += "\n"; - for ( i = 0; i < dims.length; i++ ) { - if ( hasIndex ) { - indxZero = "index[" + (dims.length - i - 1) + "] = 0;\n"; - indxIncr = " index[" + (dims.length - i - 1) + "]++\n"; - } - - body = indxZero + "for ( var " + indi[i] + " = " + indi[i] + "start; " + indi[i] + " < " + indi[i] + "end; " + indi[i] + "++ ) {\n " + body + "\n" + indxIncr + "\n }"; - } - } - - func = "// Array optimized funciton\n"; - func += "// " + type + "\n"; - func += "return function (" + args.join(",") + ") {\n'use strict';\n\n" + init + prep + setp + body + post + "\n}"; - - if ( typed.debug ) { console.log(func); } - - if ( this.cache === undefined ) { this.cache = {}; } - - func = new Function(func)(); - this.cache[type] = func; - - return func; - } - - - function typedArrayFunctionExecute() { - var func = typedArrayFunctionConstructor.apply(this, arguments); - - var reply = func.apply(typed, arguments); - - return reply; - } - - function typed(opts, func) { - if ( func === undefined ) { - func = opts; - opts = undefined; - } - - var objst = { func: func, opts: opts }; - var reply = typedArrayFunctionExecute.bind(objst); - - reply.baked = typedArrayFunctionConstructor.bind(objst); - - return reply; - } - - var size = typed(function (a) { - var prd = 1; - // ---- - prd *= a; - // ---- - return prd; - }); - - function array(shape, DType, value) { - var reply; - var i, n; - - if ( typeof value !== "number" ) { - value = 0; - } - - if ( DType && DType.dtype ) { DType = DType.dtype; } - if ( typeof DType === "string" ) { DType = types[DType]; } - - if ( typeof DType === "function" ) { - n = size(shape); - reply = ndarray(new DType(n), shape); - - for ( i = 0; i < n; i++ ) { reply.data[i] = value; } - } else { - reply = rep(shape, value); - } - - reply.shape = shape; - - return reply; - } - - function clone (x) { - return typed.assign(typed.array(typed.dim(x), x), x); - } - - function iota(i, n) { - if ( n === undefined ) { - n = i; - i = 0; - } - var j, result = []; - for ( j = 0; j 17 ) { break;} - } - console.log(line); - } else { - for ( y = a.shape[0]-1; y >= 0; --y ) { - line = ""; - for ( x = 0; x < a.shape[1]; ++x ) { - line += a.get(y, x).toFixed(prec) + " "; - } - - console.log(line); - } - console.log("\n"); - } - } - - function section(a, sect) { - var x1 = sect[0][0]; - var x2 = sect[0][1]; - var y1 = sect[1][0]; - var y2 = sect[1][1]; - - return a.lo(y1, x1).hi(y2-y1, x2-x1); - } - - module.exports = typed; - module.exports.ndarray = ndarray; - module.exports.section = section; - module.exports.extend = extend; - module.exports.array = array; - module.exports.clone = clone; - module.exports.print = print; - module.exports.iota = iota; - module.exports.rep = rep; - module.exports.dim = dim; - - module.exports.epsilon = 2.220446049250313e-16; -}()); - - -},{"ndarray-nobuffer":2}],5:[function(require,module,exports){ -/*jslint white: true, vars: true, plusplus: true, nomen: true, unparam: true, evil: true, regexp: true */ -/*globals */ - -"use strict"; - -(function () { - var i; - var typed = require("typed-array-function"); - - var ops = {}, opname, op; - module.exports = ops; - - function twofourthr(ops) { // Allocate an output array as needed - var dima, dimb, shape; - - return function (a, b, c) { - if ( c === undefined ) { - dima = typed.dim(a); - dimb = typed.dim(b); - - if ( dima.length > dimb.length ) { - shape = dima; - } else { - shape = dimb; - } - c = b; b = a; a = typed.array(shape, b); - } - - return ops(a, b, c); - }; - } - function onefourtwo(ops) { // Allocate an output array as needed - return function (a, b) { - if ( b === undefined ) { b = a; a = typed.array(typed.dim(b), b); } - - return ops(a, b); - }; - } - - function twofourthr_bake(op) { - return function(a, b, c) { - if ( c === undefined ) { return twofourthr(op.baked(a, b, c)); } - - return op.baked(a, b, c); - }; - } - function onefourtwo_bake(op) { - return function(a, b) { - if ( b === undefined ) { return onefourtwo(op.baked(a, b)); } - - return op.baked(a, b); - }; - } - - - var assign_ops = { add: "+", sub: "-", mul: "*", div: "/", - mod: "%", band: "&", bor: "|", bxor: "^", - lshift: "<<", rshift: ">>", rrshift: ">>>" - }; - - for(opname in assign_ops) { - if ( assign_ops.hasOwnProperty(opname) ) { - op = assign_ops[opname]; - - ops[opname + "3"] = typed("function (a, b, c) { a = b " + op + " c; }"); - ops[opname + "_mask"] = typed("function (a, b, c, m) { if ( m ) { a = b " + op + " c; } }"); - ops[opname + "eq"] = typed("function (a, b ) { a " + op + "= b; } "); - ops[opname + "eq_mask"] = typed("function (a, b , m) { if ( m ) { a " + op + "= b; } }"); - - ops[opname] = twofourthr (ops[opname + "3"]); - ops[opname].baked = twofourthr_bake(ops[opname + "3"]); - - ops[opname + "s"] = ops[opname]; - ops[opname + "seq"] = ops[opname + "eq"]; - } - } - - var binary_ops = { and: "&&", or: "||", - eq: "===", neq: "!==", lt: "<", - gt: ">", leq: "<=", geq: ">=" }; - - for(opname in binary_ops) { - if ( binary_ops.hasOwnProperty(opname) ) { - op = binary_ops[opname]; - - ops[opname + "3"] = typed("function (a, b, c) { a = b " + op + " c; }"); - ops[opname + "_mask"] = typed("function (a, b, c, m) { if ( m ) { a = b " + op + " c; } }"); - ops[opname + "eq"] = typed("function (a, b ) { a = a " + op + " b; } "); - ops[opname + "eq_mask"] = typed("function (a, b , m) { if ( m ) { a = a " + op + " b; } }"); - - ops[opname] = twofourthr (ops[opname + "3"]); - ops[opname].baked = twofourthr_bake(ops[opname + "3"]); - - ops[opname + "s"] = ops[opname]; - ops[opname + "seq"] = ops[opname + "eq"]; - } - } - - - var unary_ops = { not: "!", bnot: "~", neg: "-", recip: "1.0/" }; - - for(opname in unary_ops) { - if ( unary_ops.hasOwnProperty(opname) ) { - op = unary_ops[opname]; - - ops[opname + "2"] = typed("function (a, b ) { a = " + op + " b; }"); - ops[opname + "_mask"] = typed("function (a, b , m) { if ( m ) { a = " + op + " b; } }"); - ops[opname + "eq"] = typed("function (a ) { a = " + op + " a; }"); - ops[opname + "eq" + "_mask"] = typed("function (a , m) { if ( m ) { a = " + op + " a; } }"); - - ops[opname] = onefourtwo (ops[opname + "2"]); - ops[opname].baked = onefourtwo_bake(ops[opname + "2"]); - } - } - - var math_unary = [ "Math.abs", "Math.exp", "Math.floor", "Math.log", "Math.round", "Math.sqrt" - , "Math.acos", "Math.asin", "Math.atan", "Math.ceil", "Math.cos", "Math.sin", "Math.tan" - , "isFinite", "isNaN" ]; - - for( i = 0; i < math_unary.length; i++ ) { - op = math_unary[i]; - - opname = op.split(".") - - if ( opname.length == 2 ) { - opname = opname[1] - } else { - opname = opname[0] - } - - ops[opname + "2"] = typed("function (a, b ) { a = " + op + "(b); }"); - ops[opname + "_mask"] = typed("function (a, b , m) { if ( m ) { a = " + op + "(b); } }"); - ops[opname + "eq"] = typed("function (a ) { a = " + op + "(a); }"); - ops[opname + "eq" + "_mask"] = typed("function (a , m) { if ( m ) { a = " + op + "(a); } }"); - - ops[opname] = onefourtwo (ops[opname + "2"]); - ops[opname].baked = onefourtwo_bake(ops[opname + "2"]); - } - - var math_comm = [ "max", "min" ]; - - for( i = 0; i < math_comm.length; i++ ) { - opname = op = math_comm[i]; - - ops[opname + "3"] = typed("function (a, b, c) { a = Math." + op + "(b, c); }"); - ops[opname + "_mask"] = typed("function (a, b, c, m) { if ( m ) { a = Math." + op + "(b, c); } }"); - - ops[opname] = twofourthr (ops[opname + "3"]); - ops[opname].baked = twofourthr_bake(ops[opname + "3"]); - - ops[opname + "s"] = ops[opname]; - ops[opname + "s" + "eq"] = ops[opname]; - } - - var math_noncomm = [ "atan2", "pow" ]; - - for( i = 0; i < math_noncomm.length; i++ ) { - opname = op = math_noncomm[i]; - - ops[opname + "3"] = typed("function (a, b, c) { a = Math." + op + "(b, c); }"); - ops[opname + "_mask"] = typed("function (a, b, c, m) { if ( m ) { a = Math." + op + "(b, c); } }"); - - ops[opname] = twofourthr (ops[opname + "3"]); - ops[opname].baked = twofourthr_bake(ops[opname + "3"]); - - ops[opname + "s"] = ops[opname]; - ops[opname + "s" + "eq"] = ops[opname]; - } - - ops.assign = typed(function (a, b) { a = b; }); - ops.equals = typed(function (a, b) { if ( a !== b ) { return false; } }); - ops.any = typed(function (a) { if ( a ) { return true; } }); - ops.all = typed(function (a) { if (!a ) { return false; } }); - ops.random = typed(function (a) { a = Math.random(); }); - ops.sum = typed(function (a) { - var sum = 0; - // ---- - sum += a; - // ---- - return sum; - }); - ops.prod = typed(function (a) { - var prd = 1; - // ---- - prd *= a; - // ---- - return prd; - }); - - ops.inf = typed(function (a) { - var inf = Infinity; - // ---- - if ( a < inf ) { inf = a; } - // ---- - return inf; - }); - ops.sup = typed(function (a) { - var sup = -Infinity; - // ---- - if ( a > sup ) { sup = a; } - // ---- - return sup; - }); - - - ops.norm2Squared = typed(function (a) { - var norm2 = 0; - // ---- - norm2 += a*a; - // ---- - return norm2; - }); - ops.norm2 = function (a) { return Math.sqrt(ops.norm2Squared(a)); }; - - //norm1 - //norminf - - //argmin - //argmax - -}()); - - -},{"typed-array-function":4}],6:[function(require,module,exports){ -"use strict" - -function interp1d(arr, x) { - var ix = Math.floor(x) - , fx = x - ix - , s0 = 0 <= ix && ix < arr.shape[0] - , s1 = 0 <= ix+1 && ix+1 < arr.shape[0] - , w0 = s0 ? +arr.get(ix) : 0.0 - , w1 = s1 ? +arr.get(ix+1) : 0.0 - return (1.0-fx)*w0 + fx*w1 -} - -function interp2d(arr, x, y) { - var ix = Math.floor(x) - , fx = x - ix - , s0 = 0 <= ix && ix < arr.shape[0] - , s1 = 0 <= ix+1 && ix+1 < arr.shape[0] - , iy = Math.floor(y) - , fy = y - iy - , t0 = 0 <= iy && iy < arr.shape[1] - , t1 = 0 <= iy+1 && iy+1 < arr.shape[1] - , w00 = s0&&t0 ? arr.get(ix ,iy ) : 0.0 - , w01 = s0&&t1 ? arr.get(ix ,iy+1) : 0.0 - , w10 = s1&&t0 ? arr.get(ix+1,iy ) : 0.0 - , w11 = s1&&t1 ? arr.get(ix+1,iy+1) : 0.0 - return (1.0-fy) * ((1.0-fx)*w00 + fx*w10) + fy * ((1.0-fx)*w01 + fx*w11) -} - -function interp3d(arr, x, y, z) { - var ix = Math.floor(x) - , fx = x - ix - , s0 = 0 <= ix && ix < arr.shape[0] - , s1 = 0 <= ix+1 && ix+1 < arr.shape[0] - , iy = Math.floor(y) - , fy = y - iy - , t0 = 0 <= iy && iy < arr.shape[1] - , t1 = 0 <= iy+1 && iy+1 < arr.shape[1] - , iz = Math.floor(z) - , fz = z - iz - , u0 = 0 <= iz && iz < arr.shape[2] - , u1 = 0 <= iz+1 && iz+1 < arr.shape[2] - , w000 = s0&&t0&&u0 ? arr.get(ix,iy,iz) : 0.0 - , w010 = s0&&t1&&u0 ? arr.get(ix,iy+1,iz) : 0.0 - , w100 = s1&&t0&&u0 ? arr.get(ix+1,iy,iz) : 0.0 - , w110 = s1&&t1&&u0 ? arr.get(ix+1,iy+1,iz) : 0.0 - , w001 = s0&&t0&&u1 ? arr.get(ix,iy,iz+1) : 0.0 - , w011 = s0&&t1&&u1 ? arr.get(ix,iy+1,iz+1) : 0.0 - , w101 = s1&&t0&&u1 ? arr.get(ix+1,iy,iz+1) : 0.0 - , w111 = s1&&t1&&u1 ? arr.get(ix+1,iy+1,iz+1) : 0.0 - return (1.0-fz) * ((1.0-fy) * ((1.0-fx)*w000 + fx*w100) + fy * ((1.0-fx)*w010 + fx*w110)) + fz * ((1.0-fy) * ((1.0-fx)*w001 + fx*w101) + fy * ((1.0-fx)*w011 + fx*w111)) -} - -function interpNd(arr) { - var d = arr.shape.length|0 - , ix = new Array(d) - , fx = new Array(d) - , s0 = new Array(d) - , s1 = new Array(d) - , i, t - for(i=0; i=1;i-=2) { - i1 = i-1; - ret += x[i]*y[i] + x[i1]*y[i1]; - } - if(i===0) { ret += x[0]*y[0]; } - - return ret; -}; - -numeric.dotMV = function dotMV(x,y) { - var i, p = x.length; - var ret = this.array([p], x.dtype), dotVV = this.dotVV; - for(i=p-1;i>=0;i--) { ret[i] = dotVV(x[i],y); } - return ret; -}; - -numeric.dotVM = function dotVM(x,y) { - var j,k,p,q,ret,woo,i0; - p = x.length; q = y[0].length; - ret = numeric.array([q], x.dtype); - for(k=q-1;k>=0;k--) { - woo = x[p-1]*y[p-1][k]; - for(j=p-2;j>=1;j-=2) { - i0 = j-1; - woo += x[j]*y[j][k] + x[i0]*y[i0][k]; - } - if(j===0) { woo += x[0]*y[0][k]; } - ret[k] = woo; - } - return ret; -}; - -numeric.dotMM = function dotMM(reply,x,y) { - var i,j,k,r=reply.shape[1],foo,bar,woo,i0; - - var p = x.length; - var q = y.length; - - for(i=p-1;i>=0;i--) { - foo = reply[i]; - bar = x[i]; - - for(k=r-1;k>=0;k--) { - woo = bar[q-1]*y[q-1][k]; - for(j=q-2;j>=1;j-=2) { - i0 = j-1; - woo += bar[j]*y[j][k] + bar[i0]*y[i0][k]; - } - if(j===0) { woo += bar[0]*y[0][k]; } - foo[k] = woo; - } - //ret[i] = foo; - } -}; - -numeric.diag = function diag(d) { - var i,i1,j,n = d.length, A = this.array([n, n], d.dtype), Ai; - for(i=n-1;i>=0;i--) { - Ai = A[i]; - i1 = i+2; - for(j=n-1;j>=i1;j-=2) { - Ai[j] = 0; - Ai[j-1] = 0; - } - if(j>i) { Ai[j] = 0; } - Ai[i] = d[i]; - for(j=i-1;j>=1;j-=2) { - Ai[j] = 0; - Ai[j-1] = 0; - } - if(j===0) { Ai[0] = 0; } - //A[i] = Ai; - } - return A; -}; -numeric.identity = function identity(n, type) { return this.diag(this.array([n],type,1)); }; - -numeric.tensorXX = function tensor(A,x,y) { - var m = x.length, n = y.length, Ai, i,j,xi; - - - for(i=m-1;i>=0;i--) { - Ai = A[i]; - xi = x[i]; - for(j=n-1;j>=3;--j) { - Ai[j] = xi * y[j]; - --j; - Ai[j] = xi * y[j]; - --j; - Ai[j] = xi * y[j]; - --j; - Ai[j] = xi * y[j]; - } - while(j>=0) { Ai[j] = xi * y[j]; --j; } - } - - //console.log(x, y, A[0], A[1]); -}; -numeric.tensorXX = typed({ loops: false }, numeric.tensorXX); -numeric.tensor = function tensor(x,y) { - - if(typeof x === "number" || typeof y === "number") { return numeric.mul(x,y); } - var s1 = numeric.dim(x); - var s2 = numeric.dim(y); - if(s1.length !== 1 || s2.length !== 1) { - throw new Error('numeric: tensor product is only defined for vectors'); - } - - return numeric.tensorXX(numeric.array([s1[0], s2[0]], x.dtype), x, y); -}; - - -numeric.dotVV = typed({ loops: false }, numeric.dotVV); -numeric.dotVM = typed({ loops: false }, numeric.dotVM); -numeric.dotMV = typed({ loops: false }, numeric.dotMV); -numeric.dotMM = typed({ loops: false }, numeric.dotMM); -numeric.diag = typed({ loops: false }, numeric.diag); - - -},{"typed-array-function":4}],10:[function(require,module,exports){ - - -var numeric = require("typed-array-function"); - numeric = numeric.extend(numeric, require("typed-array-ops")); - numeric = numeric.extend(numeric, require("typed-matrix-ops")); - -//9. Unconstrained optimization -exports.gradient = function gradient(f,x) { - var n = x.length; - var f0 = f(x); - if(isNaN(f0)) throw new Error('gradient: f(x) is a NaN!'); - var i,x0 = numeric.clone(x),f1,f2, J = Array(n); - var errest,roundoff,max = Math.max,eps = 1e-3,abs = Math.abs, min = Math.min; - var t0,t1,t2,it=0,d1,d2,N; - for(i=0;i20) { throw new Error("Numerical gradient fails"); } - x0[i] = x[i]+h; - f1 = f(x0); - x0[i] = x[i]-h; - f2 = f(x0); - x0[i] = x[i]; - if(isNaN(f1) || isNaN(f2)) { h/=16; continue; } - J[i] = (f1-f2)/(2*h); - t0 = x[i]-h; - t1 = x[i]; - t2 = x[i]+h; - d1 = (f1-f0)/h; - d2 = (f0-f2)/h; - N = max(abs(J[i]),abs(f0),abs(f1),abs(f2),abs(t0),abs(t1),abs(t2),1e-8); - errest = min(max(abs(d1-J[i]),abs(d2-J[i]),abs(d1-d2))/N,h/N); - if(errest>eps) { h/=16; } - else break; - } - } - return J; -} -exports.uncmin = function uncmin(f,x0,tol,gradient,maxit,callback,options) { - var grad = exports.gradient; - if(typeof options === "undefined") { options = {}; } - if(typeof tol === "undefined") { tol = 1e-8; } - if(typeof gradient === "undefined") { gradient = function(x) { return grad(f,x); }; } - if(typeof maxit === "undefined") maxit = 1000; - x0 = numeric.clone(x0); - var n = x0.length; - var f0 = f(x0),f1,df0; - if(isNaN(f0)) throw new Error('uncmin: f(x0) is a NaN!'); - var max = Math.max, norm2 = numeric.norm2; - tol = max(tol,numeric.epsilon); - var step,g0,g1,H1 = options.Hinv || numeric.identity(n); - var dot = numeric.dot, sub = numeric.sub, add = numeric.add, ten = numeric.tensor, div = numeric.div, mul = numeric.mul; - - var all = numeric.all, isfinite = numeric.isFinite, neg = numeric.neg; - var it=0,i,s,x1,y,Hy,Hs,ys,i0,t,nstep,t1,t2; - var msg = ""; - g0 = gradient(x0); - while(it= 0.1*t*df0 || isNaN(f1)) { - t *= 0.5; - ++it; - continue; - } - break; - } - if(t*nstep < tol) { msg = "Line search step size smaller than tol"; break; } - if(it === maxit) { msg = "maxit reached during line search"; break; } - g1 = gradient(x1); - - y = sub(g1,g0); - ys = dot(y,s); - Hy = dot(H1,y); - - H1 = sub(add(H1, - mul( - (ys+dot(y,Hy))/(ys*ys), - ten(s,s) )), - div(add(ten(Hy,s),ten(s,Hy)),ys)); - x0 = x1; - f0 = f1; - g0 = g1; - ++it; - - } - return {solution: x0, f: f0, gradient: g0, invHessian: H1, iterations:it, message: msg}; -} - -},{"typed-array-function":4,"typed-array-ops":5,"typed-matrix-ops":9}],11:[function(require,module,exports){ -/*jslint white: true, vars: true, plusplus: true, nomen: true, unparam: true */ -/*globals */ - -"use strict"; - -(function() { - - // http://cogsandlevers.blogspot.com/2013/11/scanline-based-filled-polygons.html - // - function drawHLine(buffer, width, x1, x2, y, k, rop) { - - if ( x1 < 0 ) { x1 = 0; } - if ( x2 > width ) { x2 = width; } - - var ofs = x1 + y * width; // calculate the offset into the buffer - var x; - - switch ( rop ) { // draw all of the pixels - case undefined: - case "set": for (x = x1; x < x2; x++) { buffer[ofs++] = k; } break; - case "add": for (x = x1; x < x2; x++) { buffer[ofs++] += k; } break; - } - } - - function scanline(x1, y1, x2, y2, miny, edges) { - var x, y, xi; - - if (y1 > y2) { // flip the points if need be - y = y1; y1 = y2; y2 = y; - x = x1; x1 = x2; x2 = x; - } - - y1 = Math.floor(y1)+1; - y2 = Math.floor(y2); - - //if ( y2 < y1 ) { y2++ } - - x = x1; // start at the start - var dx = (x2 - x1) / (y2 - y1); // change in x over change in y will give us the gradient - var ofs = Math.round(y1 - miny); // the offset the start writing at (into the array) - - for ( y = y1; y <= y2; y++ ) { // cover all y co-ordinates in the line - - xi = Math.floor(x) + 1; - - // check if we've gone over/under the max/min - // - if ( edges[ofs].minx > xi ) { edges[ofs].minx = xi; } - if ( edges[ofs].maxx < xi ) { edges[ofs].maxx = xi; } - - x += dx; // move along the gradient - ofs ++; // move along the buffer - - } - } - - function _drawPolygon(buffer, width, points, color, rop) { - var i; - var miny = points[0].y-1; // work out the minimum and maximum y values - var maxy = points[0].y-1; - - for ( i = 1; i < points.length; i++ ) { - if ( points[i].y-1 < miny) { miny = points[i].y-1; } - if ( points[i].y-1 > maxy) { maxy = points[i].y-1; } - } - - var h = maxy - miny; // the height is the size of our edges array - var edges = []; - - for ( i = 0; i <= h+1; i++ ) { // build the array with unreasonable limits - edges.push({ minx: 1000000, maxx: -1000000 }); - } - - for ( i = 0; i < points.length-1; i++ ) { // process each line in the polygon - scanline(points[i ].x-1, points[i ].y-1 - , points[i+1].x-1, points[i+1].y-1, miny, edges); - } - scanline(points[i].x-1, points[i].y-1, points[0].x-1, points[0].y-1, miny, edges); - - // draw each horizontal line - for ( i = 0; i < edges.length; i++ ) { - drawHLine( buffer, width - , Math.floor(edges[i].minx) - , Math.floor(edges[i].maxx) - , Math.floor(i + miny), color, rop); - } - } - - function d2r(d) { return d * (Math.PI / 180); } - - function rotPoints(points, angle, about) { - var x, y, i; - var reply = []; - - angle = d2r(angle); - - var sin = Math.sin(angle); - var cos = Math.cos(angle); - - for ( i = 0; i < points.length; i++ ) { - x = about.x + (((points[i].x-about.x) * cos) - ((points[i].y-about.y) * sin)); - y = about.y + (((points[i].x-about.x) * sin) + ((points[i].y-about.y) * cos)); - - reply.push({ x: x, y: y }); - } - - return reply; - } - - function polyEllipse(x, y, w, h) { - var ex, ey, i; - var reply = []; - - for ( i = 0; i < 2 * Math.PI; i += 0.01 ) { - ex = x + w*Math.cos(i); - ey = y + h*Math.sin(i); - - reply.push({ x: ex, y: ey }); - } - - return reply; - } - - function polyBox(x, y, w, h) { - return [ { x: x-w/2, y: y-h/2 } - , { x: x-w/2, y: y+h/2 } - , { x: x+w/2, y: y+h/2 } - , { x: x+w/2, y: y-h/2 } ]; - } - - exports.drawPolygon = function (buffer, width, points, color, rop) { _drawPolygon(buffer, width, points, color, rop); }; - exports.drawCircle = function (buffer, width, x, y, rad, color, rop) { _drawPolygon(buffer, width, polyEllipse(x, y, rad, rad), color, rop); }; - exports.drawEllipse = function (buffer, width, x, y, h, w, rot, color, rop) { _drawPolygon(buffer, width, rotPoints(polyEllipse(x, y, h, w), rot, { x: x, y: y }), color, rop); }; - exports.drawBox = function (buffer, width, x, y, h, w, rot, color, rop) { _drawPolygon(buffer, width, rotPoints(polyBox (x, y, h, w), rot, { x: x, y: y }), color, rop); }; -}()); - -},{}],12:[function(require,module,exports){ -/*jslint white: true, vars: true, plusplus: true, nomen: true, unparam: true */ - -"use strict"; - - - function strrep(str, n) { - var i, s = ''; - - for ( i = 0; i < n; i++ ) { s += str; } - - return s; - } - -function template(text,data) { - return text.replace(/\{([a-zA-Z0-9_.%]*)\}/g, - function(m,key){ - var type, prec, widt = 0, fmt, i; - var val = data; - - key = key.split("%"); - - if ( key.length <= 1 ) { - fmt = "%s"; - } else { - fmt = key[1]; - } - - key = key[0]; - key = key.split("."); - - for ( i = 0; i < key.length; i++ ) { - if ( val.hasOwnProperty(key[i]) ) { - val = val[key[i]]; - } else { - return ""; - } - } - - type = fmt.substring(fmt.length-1); - prec = fmt.substring(0, fmt.length-1); - - prec = prec.split("."); - - widt = prec[0] | 0; - prec = prec[1] | 0; - - switch ( type ) { - case "s": - val = val.toString(); - break; - case "f": - val = val.toFixed(prec); - break; - case "d": - val = val.toFixed(0); - break; - } - - if ( widt !== 0 && widt > val.length ) { - if ( widt > 0 ) { - val = strrep(" ", widt-val.length) + val; - } else { - val = val + strrep(" ", widt-val.length); - } - } - - return val; - } - ); -} - -module.exports = template; - -},{}]},{},[]); - diff --git a/web/static/js9_old/plugins/imexam/pixtable.js b/web/static/js9_old/plugins/imexam/pixtable.js deleted file mode 100644 index e99cd72f0f33f3a25f311c8e5e778aa701748c16..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/imexam/pixtable.js +++ /dev/null @@ -1,116 +0,0 @@ -/*jslint white: true, vars: true, plusplus: true, nomen: true, unparam: true, continue: true */ -/*globals $, JS9, greg */ - -"use strict"; - - -(function () { - var imexam = require("./imexam"); - -/* - $("table").delegate('td','mouseover mouseleave', function(e) { - if (e.type == 'mouseover') { - $(this).parent().addClass("hover"); - $("colgroup").eq($(this).index()).addClass("hover"); - } else { - $(this).parent().removeClass("hover"); - $("colgroup").eq($(this).index()).removeClass("hover"); - } - }); - */ - - function strrep(str, n, x) { - var i; - var rx = new RegExp(x, "g"); - - var s = ''; - for ( i = 0; i < n; i++ ) { - s += str.replace(rx, i); - } - return s; - } - - function htmlTable(x, y) { - var t = ""; - - t += strrep( "" - + strrep("", x, "%x") - + "\n", y, "%y"); - t += "
    "; - - return t; - } - - - // $(this).css({"font-size" : newFontSize, "line-height" : newFontSize/1.2 + "px"}); - - function pxtablUpdate(im, point) { - var im_2d = imexam.ndops.ndarray(im.raw.data, [im.raw.height, im.raw.width]); - var i = 0, j = 0; - var x, y; - - - var pxtabl = $(this.div).find(".pxtabl")[0]; - - pxtabl["cell" + j + "." + i].value = "col\\row"; - - j = 0; - for ( i = 1; i < 10; i++ ) { - x = point.x + i - 5; - - if ( x > 0 && x <= im.raw.width ) { - pxtabl["cell" + j + "." + i].value = x.toFixed(0); - } else { - pxtabl["cell" + j + "." + i].value = ""; - } - } - - i = 0; - for ( j = 1; j < 10; j++ ) { - y = point.y + j - 5; - - if ( y > 0 && y <= im.raw.height ) { - pxtabl["cell" + (10-j) + "." + i].value = y.toFixed(0); - } else { - pxtabl["cell" + (10-j) + "." + i].value = ""; - } - } - - for ( j = 1; j < 10; j++ ) { - for ( i = 1; i < 10; i++ ) { - x = (point.x + i - 5 - 0.5)|0; - y = (point.y + j - 5 - 0.5)|0; - - if ( x >= 0 && x < im.raw.width && y >= 0 && y < im.raw.height ) { - pxtabl["cell" + (10-j) + "." + i].value = im_2d.get(y, x).toPrecision(4); - } else { - pxtabl["cell" + (10-j) + "." + i].value = ""; - } - } - } - } - - function pxtablInit() { - imexam.fixupDiv(this); - - $(this.div).html("
    " + htmlTable(10, 10) + "
    "); - $(this.div).find(".row5").css("background", "lightblue"); - $(this.div).find(".col5").css("background", "lightblue"); - $(this.div).find(":input").css("font-size", "11"); - } - - JS9.RegisterPlugin("ImExam", "PxTabl", pxtablInit, { - menu: "view", - - menuItem: "Pixel Table", - winTitle: "Pixel Table", - winResize: true, - - toolbarSeparate: true, - - onmousemove: pxtablUpdate, - onarrowkey: pxtablUpdate, - winDims: [625, 240], - }); -}()); - diff --git a/web/static/js9_old/plugins/imexam/radproj.js b/web/static/js9_old/plugins/imexam/radproj.js deleted file mode 100644 index 5349f4182d96b0bcd8fa3f192e8966eab60cf585..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/imexam/radproj.js +++ /dev/null @@ -1,84 +0,0 @@ -/*jslint white: true, vars: true, plusplus: true, nomen: true, unparam: true */ -/*globals $, JS9 */ - -"use strict"; - - -(function() { - var imexam = require("./imexam"); - - var rproj_template = "
    \ - \ - \ - \ - \ -
    peak {a%.2f}
    sigma {c%.2f}
    bias {d%.2f}
    \ -
    "; - - function rprojUpdate(im, xreg) { - var div = this.div; - - var imag = imexam.getRegionData(im, xreg); - - var max = imexam.ndops.maxvalue(imag); - var backgr = imexam.imops.backgr(imag, 4).value; - var data = imexam.ndops.assign(imexam.ndops.zeros(imag.shape), imag); - - imexam.ndops.subs(data, imag, backgr); - - var qcenter = imexam.ndops.qcenter(data); - var centroid = imexam.ndops.centroid(data, qcenter); - - var rproj = imexam.imops.rproj(imag, [centroid.ceny, centroid.cenx]); - - var fit = imexam.ndops.gsfit1d(rproj.radi, rproj.data, [max, centroid.fwhm/2.355, backgr]); - - var fitv = { a: fit[0], b: 0, c: fit[1], d: fit[2] }; - - var rdata = []; - var rfdat = []; - var r; - - for ( r = 0; r < rproj.radi.shape[0]; r++ ) { - rdata[r] = [rproj.radi.get(r), rproj.data.get(r)]; - } - - rproj.samp = imexam.ndops.zeros([div.offsetWidth/2]); - - imexam.ndops.fill(rproj.samp, function(r) { return rproj.radius*r/(div.offsetWidth/2); }); - - - rproj.modl = imexam.ndops.gauss1d(rproj.samp, fit); - - for ( r = 0; r < rproj.modl.shape[0]; r++ ) { - rfdat[r] = [rproj.samp.get(r), rproj.modl.get(r)]; - } - - $(div).empty(); - var plot = $.plot(div, [{ data: rdata, points: { radius: 1, show: true } }, { data: rfdat }] - , { zoomStack: true, selection: { mode: "xy" } }); - - $(div).append(imexam.template(rproj_template, fitv)); - } - - function rprojInit() { - imexam.fixupDiv(this); - $(this.div).append("

    create, click, move, or resize a region to see radial projection
    "); - } - - JS9.RegisterPlugin("ImExam", "RadialProj", rprojInit, { - menu: "analysis", - - menuItem: "Radial Proj", - winTitle: "Radial Proj", - help: "imexam/imexam.html#r_proj", - - dynamicSelect: true, - - toolbarSeparate: true, - - onregionschange: rprojUpdate, - winDims: [250, 250], - }); - -}()); diff --git a/web/static/js9_old/plugins/imexam/reghist.js b/web/static/js9_old/plugins/imexam/reghist.js deleted file mode 100644 index 425e4df034b0534abba6707ec0e2ad3061e731a1..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/imexam/reghist.js +++ /dev/null @@ -1,93 +0,0 @@ -/*jslint white: true, vars: true, plusplus: true, nomen: true, unparam: true */ -/*globals $, JS9 */ - -"use strict"; - - -(function() { - var imexam = require("./imexam"); - - var reghistemplate = "

    \ - \ - \ - \ -
    rms {rms%.2f}
    mean {mean%.2f}
    \ -
    "; - - function histStats(div, plot, range) { - var i, j = 0; - var axes = plot.getAxes(); - - var xmin = axes.xaxis.options.min; - var xmax = axes.xaxis.options.max; - var hist = $(div).data("hist"); - var data = hist.raw; - - var rms = imexam.ndops.rmsClipped( data, xmin, xmax); - var mean = imexam.ndops.meanClipped(data, xmin, xmax); - - $(div).find(".annotation").empty(); - - $(div).append(imexam.template(reghistemplate, { rms: rms, mean: mean })); - } - - function histUpdate(im, xreg) { - var div = this.div; - - var imag = imexam.getRegionData(im, xreg); - - var hist = imexam.ndops.hist(imag); - hist.sum = imexam.ndops.sum(hist.data); - - $(div).data("hist", hist); - - var n = 0; - var skip = hist.sum * 0.001; - var h = 0, i, value; - - $(div).empty(); - - var hdata = []; - - for ( i = 0; i < hist.data.shape[0]; i++ ) { - n += hist.data.get(i); - - if ( n > skip && n < hist.sum - skip ) { - value = hist.data.get(i); - - hdata[h] = [i*hist.width+hist.min, value]; - h++; - } - } - - var plot = $.plot(div, [hdata], { zoomStack: true, zoomFunc: histStats, selection: { mode: "x" } }); - - histStats(div, plot, undefined); - -// $.plot.zoomStackIn(plot, undefined, { xaxis: { from: xmin , to: xmax } -// , yaxis: { from: axes.yaxis.min , to: axes.yaxis.max } } -// , histStats); - } - - function histInit() { - imexam.fixupDiv(this); - $(this.div).append("

    create, click, move, or resize a region to see histogram
    "); - } - - JS9.RegisterPlugin("ImExam", "Histogram", histInit, { - menu: "analysis", - - menuItem: "Histogram", - winTitle: "Histogram", - help: "imexam/imexam.html#rghist", - - dynamicSelect: true, - - toolbarSeparate: true, - toolbarHTML: " ", - - onregionschange: histUpdate, - winDims: [250, 250], - }); - -}()); diff --git a/web/static/js9_old/plugins/imexam/regstat.js b/web/static/js9_old/plugins/imexam/regstat.js deleted file mode 100644 index e3995d0b1dcf9f60838d564f8ddeba5fc2b813b3..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/imexam/regstat.js +++ /dev/null @@ -1,92 +0,0 @@ -/*jslint white: true, vars: true, plusplus: true, nomen: true, unparam: true */ -/*globals $, JS9, require */ - -"use strict"; - - -(function() { - var imexam = require("./imexam"); - - // eslint-disable-next-line no-multi-str - var statTemplate = " \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ -
    position x {reg.x%.2f} y {reg.y%.2f}
    box width {reg.width%.2f} height {reg.height%.2f}
    min {min%.2f} max {max%.2f}
    totcounts {totcnts.sum%.2f}
    bscounts {bscnts.sum%.2f}
    bkgd {bkgd.value%.2f} noise {bkgd.noise%.2f}
    centroid x {bscnts.cenx%.2f} y {bscnts.ceny%.2f}
    FWHM {bscnts.fwhm%.2f} {bscnts.rms%.2f}
    "; - - function regionStats(im, xreg){ - var section = imexam.reg2section(xreg); - var imag = imexam.getRegionData(im, xreg); - - var data = imexam.ndops.assign(imexam.ndops.zeros(imag.shape), imag); - var data2 = imexam.ndops.assign(imexam.ndops.zeros(imag.shape), imag); - - var stats = {}; - - if( !im || !xreg ){ - return null; - } - - stats.reg = xreg; - stats.min = imexam.ndops.minvalue(imag); - stats.max = imexam.ndops.maxvalue(imag); - stats.bkgd = imexam.imops.backgr(imag, 4); - - // background-subtracted data - imexam.ndops.subs(data, imag, stats.bkgd.value); - stats.bscnts = imexam.ndops.centroid(data, imexam.ndops.qcenter(data)); - stats.bscnts.cenx += section[0][0]; - stats.bscnts.ceny += section[1][0]; - - // total counts - stats.totcnts = imexam.ndops.centroid(data2, imexam.ndops.qcenter(data2)); - stats.totcnts.cenx += section[0][0]; - stats.totcnts.ceny += section[1][0]; - - return stats; - } - - function statUpdate(im, xreg) { - var div = this.div; - - $(div).html(imexam.template(statTemplate, regionStats(im, xreg))); - } - - function statInit() { - imexam.fixupDiv(this); - $(this.div).append("

    create, click, move, or resize a region to see stats
    "); - } - - // add method to JS9 Image object and to public API - JS9.Image.prototype.getRegionStats = function(xreg){ - return regionStats(this, xreg); - }; - JS9.mkPublic("GetRegionStats", "getRegionStats"); - - JS9.RegisterPlugin("ImExam", "RegionStats", statInit, { - menu: "analysis", - - winTitle: "Region Stats", - menuItem: "Region Stats", - help: "imexam/imexam.html#rgstat", - - dynamicSelect: true, - - toolbarSeparate: true, - - onregionschange: statUpdate, - winDims: [250, 250] - }); -}()); diff --git a/web/static/js9_old/plugins/imexam/rghxrg.js b/web/static/js9_old/plugins/imexam/rghxrg.js deleted file mode 100644 index f50c1090602c8f6480b4eb65ba02ee578b4dc3cc..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/imexam/rghxrg.js +++ /dev/null @@ -1,71 +0,0 @@ -/*jslint white: true, vars: true, plusplus: true, nomen: true, unparam: true */ -/*globals $, JS9, Fitsy, imexam */ - - -(function() { - "use strict"; - - - function hxrgReadPixelStack(fits, n, index, deliver, data) { - var last, i; - - if ( n === 0 ) { - data = []; - } else { - data[n-1] = fits.pixel; - } - - n += 1; - - if ( n >= fits.nhdu ) { - last = data[0]; - - for ( i = 1; i < n; i++ ) { - data[i-1] = data[i]; - } - - data[n-1] = last; - - deliver(data); - - return; - } - - Fitsy.readPixel(fits, fits.hdu[n], index, function() { hxrgReadPixelStack(fits, n, index, deliver, data); }); - } - - function pixtUpdate(im, xreg) { - var hxrg = [], i; - var div = this.div; - - hxrgReadPixelStack(im.raw.hdu.fits, 0, [xreg.pos.y, xreg.pos.x], function(data) { - - for ( i = 0; i < data.length; i++ ) { - hxrg[i] = [i, data[i]]; - } - - $(div).empty(); - $.plot(div, [hxrg]); - }); - } - - function pixtInit() { - imexam.fixupDiv(this); - $(this.div).append("

    create, click, move, or resize a region to see the pixel stack
    "); - } - - JS9.RegisterPlugin("HxRG", "PixelStack", pixtInit, { - menu: "analysis", - - menuItem: "Pixel Stack", - winTitle: "Pixel Stack", - help: "imexam/imexam.html#rghxrg", - - toolbarSeparate: true, - toolbarHTML: " ", - - onregionschange: pixtUpdate, - winDims: [250, 250], - }); - -}()); diff --git a/web/static/js9_old/plugins/imexam/xyproj.js b/web/static/js9_old/plugins/imexam/xyproj.js deleted file mode 100644 index a62b37769dba695c59413a39709099b702bba582..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/imexam/xyproj.js +++ /dev/null @@ -1,119 +0,0 @@ -/*jslint white: true, vars: true, plusplus: true, nomen: true, unparam: true */ -/*globals $, JS9 */ - - - -(function() { - "use strict"; - - var imexam = require("./imexam"); - - - var projToolbar = " \ -

    \ - \ -
    "; - - - // fit \ - - function projUpdate(im, xreg) { - var div, proj, menx, chek; - - if ( im === undefined ) { - div = xreg.div; - proj = xreg.proj; - menx = xreg.menu; - chek = xreg.chek; - } else { - div = this.div; - menx = this.outerdivjq.find(".proj_menu")[0]; - chek = this.outerdivjq.find(".proj_chek")[0]; - - proj = imexam.ndops.proj(imexam.getRegionData(im, xreg), this.plugin.opts.xyproj); - - // eslint-disable-next-line no-unused-vars - $(menx).change(function (event) { - projUpdate(undefined, { div: div, proj: proj, menu: menx, chek: chek }); - }); - // eslint-disable-next-line no-unused-vars - $(chek).change(function (event) { - projUpdate(undefined, { div: div, proj: proj, menu: menx, chek: chek }); - }); - } - - - var xdata = []; - var data; - var x; - - var proj_type = menx.options[menx.selectedIndex].value; - - - $(div).empty(); - - if ( proj_type === "sum" ) { - data = proj.sum; - } - if ( proj_type === "avg" ) { - data = proj.avg; - } - if ( proj_type === "med" ) { - data = proj.med; - } - - - for ( x = 0; x < data.length; x++ ) { - xdata[x] = [x, data[x]]; - } - - $.plot(div, [xdata], { zoomStack: true, selection: { mode: "xy" } }); - } - - function projInit() { - imexam.fixupDiv(this); - $(this.div).append("

    create, click, move, or resize a region to see projection
    "); - } - - JS9.RegisterPlugin("ImExam", "XProj", projInit, { - menu: "analysis", - - menuItem: "X Projection", - winTitle: "X Projection", - help: "imexam/imexam.html#xyproj", - - dynamicSelect: true, - - toolbarSeparate: true, - toolbarHTML: projToolbar, - - onregionschange: projUpdate, - - winDims: [250, 250], - - xyproj: 0 - }); - - JS9.RegisterPlugin("ImExam", "YProj", projInit, { - menu: "analysis", - - menuItem: "Y Projection", - winTitle: "Y Projection", - help: "imexam/imexam.html#xyproj", - - dynamicSelect: true, - - toolbarSeparate: true, - toolbarHTML: projToolbar, - - onregionschange: projUpdate, - - winDims: [250, 250], - - xyproj: 1 - }); -}()); diff --git a/web/static/js9_old/plugins/plugintest.css b/web/static/js9_old/plugins/plugintest.css deleted file mode 100644 index 48fe0d9a2de49d4deb5138dce141752c3806c4d5..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/plugintest.css +++ /dev/null @@ -1,14 +0,0 @@ -div.PLUGINtest{ - /* relative pos top/left for container, Flanagan's JavaScript, p 357 */ - position: relative; - top: 0px; - left: 0px; - display: block; - border-width: 0px; - background: lightblue; -} - -div.PLUGINmessage{ - height: 30px; - padding: 10px; -} diff --git a/web/static/js9_old/plugins/plugintest.js b/web/static/js9_old/plugins/plugintest.js deleted file mode 100644 index a21a9549b6bd614be5d79e5a6938fe5394f18168..0000000000000000000000000000000000000000 --- a/web/static/js9_old/plugins/plugintest.js +++ /dev/null @@ -1,291 +0,0 @@ -/* - * PLUGIN test module (January 26 2014) - */ - -/*jslint bitwise: true, plusplus: true, sloppy: true, vars: true, white: true, browser: true, devel: true, continue: true, unparam: true, regexp: true */ -/*global $, JS9, sprintf */ - -// To specify the JS9 display instance to link to a given PLUGIN div, -// use the HTML5 dataset syntax: -//

    - -// make a module so as not to pollute the global namespace -var PLUGIN; -if( PLUGIN && (typeof PLUGIN !== "object" || PLUGIN.CLASS) ){ - throw new Error("Namespace 'PLUGIN' already exists"); -} - -// create our namespace, and specify some meta-information and params -PLUGIN = {}; -PLUGIN.CLASS = "PLUGIN";// class of plugins (1st part of div class) -PLUGIN.NAME = "test"; // name of this plugin (2nd part of div class) -PLUGIN.NDIV = 4; // number of div message areas -PLUGIN.WIDTH = 400; // width of light window -PLUGIN.HEIGHT = 200; // height of light window (4 * (30 + 20 from css)) - -// constructor: it's here that you add HTML elements to the container div -// But you don't have to do so: you can put the HTML elements right into -// the Web page, in which case this routine can be empty. -// Obviously, you must use the contructor to add your HTML elements if you -// want to support your plugin from the View menu. -// -// The examaple below splits the difference: it allows the container div to -// be empty or filled with the inner canvas, and thus support the view menu. -PLUGIN.init = function(){ - var i; - // on entry, these elements have already been defined: - // this.div: the DOM element representing the div for this plugin - // this.divjq: the jquery object representing the div for this plugin - // this.id: the id ofthe div (or the plugin name as a default) - // this.display: the display object associated with this plugin - // this.dispMode: display mode (for internal use) - // set width and height on div - // - // create message divs - for(i=0; i") - .addClass(PLUGIN.CLASS + "message") - .attr("id", "message" + i) - .html(" ") - .appendTo(this.divjq); - } -}; - -// write a row of text in message area associated with a given plugin -PLUGIN.init.prototype.message = function(message, row) { - this.divjq.children("#message" + row).html(message); - if( JS9.DEBUG === 4 && (!message.match(/mouse/) || JS9.DEBUG >= 5) ){ - // eslint-disable-next-line no-console - console.log(message); - } -}; - -// callback when mouse is clicked (down,up) -// eslint-disable-next-line no-unused-vars -PLUGIN.click = function(im, ipos, evt){ - var t = sprintf("click: ipos=%s,%s", - ipos.x.toFixed(2), ipos.y.toFixed(2)); - this.message(t, 2); -}; - -// callback when mouse is pressed -// im: image handle -// ipos: image position; origin at 1,1 (FITS convention) -// evt: the event passed to the callback -// eslint-disable-next-line no-unused-vars -PLUGIN.mousedown = function(im, ipos, evt){ - var t = sprintf("mouseDown: ipos=%s,%s", - ipos.x.toFixed(2), ipos.y.toFixed(2)); - this.message(t, 0); -}; - -// callback when mouse is released -// eslint-disable-next-line no-unused-vars -PLUGIN.mouseup = function(im, ipos, evt){ - var t = sprintf("mouseUp: ipos=%s,%s", - ipos.x.toFixed(2), ipos.y.toFixed(2)); - this.message(t, 0); -}; - -// callback when mouse (or one-finger touch) moves (without a mouse press) -// image value: we need 0-indexed positions, so subtract 1 -// but add 0.5 before rounding since x.0 is in the middle of the pixel -// eslint-disable-next-line no-unused-vars -PLUGIN.mousemove = function(im, ipos, evt){ - var v, t; - v = im.raw.data[Math.floor(ipos.y-0.5) * im.raw.width + - Math.floor(ipos.x-0.5)]; - t = sprintf("mouseMove: ipos=%s,%s val=%s", - ipos.x.toFixed(2), ipos.y.toFixed(2), v); - this.message(t, 0); -}; - -// callback when mouse moves over the image -// eslint-disable-next-line no-unused-vars -PLUGIN.mouseover = function(im, ipos, evt){ - var t = sprintf("mouseOver: ipos=%s,%s", - ipos.x.toFixed(2), ipos.y.toFixed(2)); - this.message(t, 0); -}; - -// callback when mouse moves out of the image -// eslint-disable-next-line no-unused-vars -PLUGIN.mouseout = function(im, ipos, evt){ - var t = sprintf("mouseOut: ipos=%s,%s", - ipos.x.toFixed(2), ipos.y.toFixed(2)); - this.message(t, 0); -}; - -// callback when key is pressed -// eslint-disable-next-line no-unused-vars -PLUGIN.keydown = function(im, ipos, evt){ - var charCode = evt.which || evt.keyCode; - var charStr = JS9.eventToCharStr(evt); - var t = sprintf("keydown: %s -> %s", charCode, charStr); - this.message(t, 2); -}; - -// callback when regions move -PLUGIN.regionsmove = function(im, xreg){ - var t = sprintf("%sMove: ipos=%.2f,%.2f", xreg.shape, xreg.x, xreg.y); - // context is the calling instance - this.message(t, 1); -}; - -// callback when regions change -PLUGIN.regionschange = function(im, xreg){ - var i; - var mode = xreg.mode.substring(0,1).toUpperCase()+xreg.mode.substring(1); - var t = sprintf("%s%s: ", xreg.shape, mode); - switch(xreg.shape){ - case "annulus": - t += sprintf("ipos=%.2f,%.2f radii=", xreg.x, xreg.y); - for(i=0; i