<?php
/**
 *
 * ADD INFO ABOUT THIS FILE LATER
 */
use PhpZmanim\Zmanim;
use Carbon\Carbon;
use PhpZmanim\HebrewCalendar\JewishCalendar;
use PhpZmanim\HebrewCalendar\JewishDate;
use PhpZmanim\HebrewCalendar\TefilaRules;
use PhpZmanim\HebrewCalendar\Parsha;

// if ( !defined( 'ABSPATH' ) ) {
//     exit;
// }

//Main zmanim_wp functions here!
//FUNCTION: Sanitize and validate inputs
function zmanim_wp_sanitize(  $variable, $type  ) {
    if ( $type == 'float' ) {
        $newvar = filter_var(
            $variable,
            FILTER_SANITIZE_NUMBER_FLOAT,
            FILTER_FLAG_ALLOW_FRACTION,
            FILTER_FLAG_ALLOW_THOUSAND
        );
        return $newvar;
    }
    if ( $type == 'int' ) {
        $newvar = filter_var( $variable, FILTER_SANITIZE_NUMBER_INT );
        return $newvar;
    }
    if ( $type == 'string' ) {
        $newvar = filter_var( $variable, FILTER_SANITIZE_SPECIAL_CHARS );
        return $newvar;
    }
    if ( $type == 'engdate' ) {
        $newvar = filter_var( $variable, FILTER_SANITIZE_SPECIAL_CHARS );
        return $newvar;
    }
} // end zmanim_wp_sanitize

function zmanim_wp_validateDate($date, $format = 'Y-m-d'){
    $d = DateTime::createFromFormat($format, $date);
    return $d && $d->format($format) === $date;
}

//FUNCTION: set up some global variables for the shortcodes
function zmanim_wp_getzmanim(
    $dateinput,
    $offset,
    $dateformat,
    $lang,
    $option,
    $globalsonly
) {
    if ( isset( $dateinput ) ) {
        $dateinput = zmanim_wp_sanitize( $dateinput, 'engdate' );
    }
    if ( isset( $offset ) ) {
        $offset = zmanim_wp_sanitize( $offset, "int" );
        if ( substr( $offset, 0, 1 ) == "+" || substr( $offset, 0, 1 ) == "-" ) {
            $offsetsign = substr( $offset, 0, 1 );
            $offsetnum = substr( $offset, 1 );
        } else {
            $offsetsign = "+";
            $offsetnum = $offset;
        }
        $offset = $offsetsign . $offsetnum;
    }
    if ( isset( $dateformat ) ) {
        $dateformat = zmanim_wp_sanitize( $dateformat, 'string' );
    }
    if ( isset( $lang ) ) {
        $lang = zmanim_wp_sanitize( $lang, 'string' );
    }
    if ( isset( $option ) ) {
        $option = zmanim_wp_sanitize( $option, 'string' );
    }
    if ( isset( $globalsonly ) ) {
        $globalsonly = zmanim_wp_sanitize( $globalsonly, 'int' );
    }
    $tzone = get_option( 'wpkz_tzone' );
    if ( !$tzone ) {
        $tzone = "America/New_York";
    }
    $lat = get_option( 'wpkz_lat' );
    $long = get_option( 'wpkz_long' );
    if ( !$lat || $lat > 90 || $lat < -90 || !$long || $long > 180 || $long < -180 ) {
        $lat = "41.4939407";
        $long = "-81.516709";
    }
    $location = get_option( 'wpkz_location' );
    if ( !$location ) {
        $location = "BKCS Cleveland";
    }
    $announcement1 = get_option( 'wpkz_announcement1' );
    if ( !$announcement1 ) {
        $announcement1 = "";
    }
    $announcement2 = get_option( 'wpkz_announcement2' );
    if ( !$announcement2 ) {
        $announcement2 = "";
    }
    $announcement3 = get_option( 'wpkz_announcement3' );
    if ( !$announcement3 ) {
        $announcement3 = "";
    }
    $announcement4 = get_option( 'wpkz_announcement4' );
    if ( !$announcement4 ) {
        $announcement4 = "";
    }
    if ( !$dateinput ) {
        $dateinput = "today";
    }

    if ( is_string( $dateinput ) ) {
        $dateinput = strtolower( $dateinput );
    }
    
     if ( preg_match( '/^next (sunday|monday|tuesday|wednesday|thursday|friday|saturday)$/',  $dateinput ) ) {
        #$thedate = gmdate( 'Y-m-d', strtotime( $dateinput ) );
        $thedate = gmdate( 'Y-m-d', strtotime( $dateinput . "+7 days" ) );
    } elseif ( in_array( $dateinput, ['sunday','monday','tuesday','wednesday','thursday','friday','saturday'] ) ) {
        if ( strtolower( gmdate( 'l' ) ) === $dateinput ) {
            $thedate = gmdate( 'Y-m-d' );
        } else {
            $thedate = gmdate( 'Y-m-d', strtotime( 'next ' . $dateinput ) );
        }
    } elseif ( $dateinput == "today" ) {
        $thedate = gmdate( 'Y-m-d' );
    } elseif ( $dateinput == "tomorrow" ) {
        $thedate = gmdate( 'Y-m-d', strtotime( '+1 day' ) );
    } elseif ( strtotime( $dateinput ) !== false ) {
        $thedate = gmdate( 'Y-m-d', strtotime( $dateinput ) );
    }

    $theyear = gmdate( 'Y', strtotime( $thedate ?? '' ) );
    $themonth = gmdate( 'm', strtotime( $thedate ?? '' ) );
    $theday = gmdate( 'd', strtotime( $thedate ?? '' ) );
    if ( $globalsonly ) {
        $output = [
            $theyear,
            $themonth,
            $theday,
            $lat,
            $long,
            $tzone,
            $offset
        ];
        return $output;
    }
    $zmanim = Zmanim::create(
        $theyear,
        $themonth,
        $theday,
        "",
        $lat,
        $long,
        0,
        $tzone
    );
    $output = $zmanim->{$option};
    if ( $offset != 0 ) {
        $output = gmdate( $dateformat, strtotime( $output . " {$offset} minutes" ) );
    } else {
        $output = gmdate( $dateformat, strtotime( $output ) );
    }
    return $output;
} // end zmanim_wp_getzmanim

function zmanim_round( $thetime, $theaction, $thelimit ) {
    // Step 1: Validate $thetime and detect its format
    $formats = [ 'g:i:s', 'G:i:s', 'g:i:s a', 'g:i a', 'G:i:s' ];
    $detected_format = null;
    $dt = null;
    foreach ( $formats as $fmt ) {
        $parsed = DateTime::createFromFormat( $fmt, $thetime );
        if ( $parsed !== false && $parsed->format( $fmt ) === $thetime ) {
            $detected_format = $fmt;
            $dt = $parsed;
            break;
        }
    }
    if ( $dt === null ) {
        return 'invalid time';
    }
    // Step 2: Validate $thelimit is an integer between 1 and 60
    if ( ! ctype_digit( (string) $thelimit ) && ! is_int( $thelimit ) ) {
        return 'invalid rounding limit';
    }
    $thelimit = intval( $thelimit );
    if ( $thelimit < 1 || $thelimit > 60 ) {
        return 'Limit must be between 1 and 60';
    }

    // Step 3: Apply rounding action
    if ( $theaction !== 'up' && $theaction !== 'down' && $theaction !== 'both' ) {
        return $thetime;
    }

    $total_minutes = (int) $dt->format( 'G' ) * 60 + (int) $dt->format( 'i' );

    if ( $theaction === 'up' ) {
        $rounded_minutes = (int) ceil( $total_minutes / $thelimit ) * $thelimit;
    } elseif ( $theaction === 'down' ) {
        $rounded_minutes = (int) floor( $total_minutes / $thelimit ) * $thelimit;
    } else { // both: ties go up (PHP round() default)
        $rounded_minutes = (int) round( $total_minutes / $thelimit ) * $thelimit;
    }

    // Wrap around midnight if rounding pushes past 23:59
    $rounded_minutes = $rounded_minutes % ( 24 * 60 );

    $dt->setTime( intdiv( $rounded_minutes, 60 ), $rounded_minutes % 60, 0 );
    return $dt->format( $detected_format );
}

// function zmanim_wp_init() {

    function tzone_handler() {
        $tzone = get_option( 'wpkz_tzone' );
        if ( !$tzone ) {
            $tzone = "America/New_York";
        }
        return $tzone;
    } //end tzone_handler

    // set up shortcode handlers
    function lat_handler() {
        $lat = get_option( 'wpkz_lat' );
        if ( !$lat ) {
            $lat = "41.4939407";
        }
        return $lat;
    } // end lat_handler

    function long_handler() {
        $long = get_option( 'wpkz_long' );
        if ( !$long ) {
            $long = "-81.516709";
        }
        return $long;
    } // end long_handler

    function location_handler() {
        $location = get_option( 'wpkz_location' );
        if ( !$location ) {
            $location = "BKCS Cleveland";
        }
        return $location;
    } // end location_handler

    function announcement1_handler() {
        $announcement1 = get_option( 'wpkz_announcement1' );
        if ( !$announcement1 ) {
            $announcement1 = "";
        }
        return $announcement1;
    } // end announcement1_handler

    function announcement2_handler() {
        $announcement2 = get_option( 'wpkz_announcement2' );
        if ( !$announcement2 ) {
            $announcement2 = "";
        }
        return $announcement2;
    } // end announcement2_handler

    function announcement3_handler() {
        $announcement3 = get_option( 'wpkz_announcement3' );
        if ( !$announcement3 ) {
            $announcement3 = "";
        }
        return $announcement3;
    } // end announcement3_handler

    function announcement4_handler() {
        $announcement4 = get_option( 'wpkz_announcement4' );
        if ( !$announcement4 ) {
            $announcement4 = "";
        }
        return $announcement4;
    } // end announcement4_handler

    function zmanim_wp_transliteration_defaults() {
        $parshaDefaults = [
            'NONE'                => '',
            'BERESHIS'            => 'Bereshees',
            'NOACH'               => 'Noach',
            'LECH_LECHA'          => 'Lech Lecha',
            'VAYERA'              => 'Vayera',
            'CHAYEI_SARA'         => 'Chayei Sara',
            'TOLDOS'              => 'Toldos',
            'VAYETZEI'            => 'Vayetzei',
            'VAYISHLACH'          => 'Vayishlach',
            'VAYESHEV'            => 'Vayeshev',
            'MIKETZ'              => 'Miketz',
            'VAYIGASH'            => 'Vayigash',
            'VAYECHI'             => 'Vayechi',
            'SHEMOS'              => 'Shemos',
            'VAERA'               => 'Vaera',
            'BO'                  => 'Bo',
            'BESHALACH'           => 'Beshalach',
            'YISRO'               => 'Yisro',
            'MISHPATIM'           => 'Mishpatim',
            'TERUMAH'             => 'Terumah',
            'TETZAVEH'            => 'Tetzaveh',
            'KI_SISA'             => 'Ki Sisa',
            'VAYAKHEL'            => 'Vayakhel',
            'PEKUDEI'             => 'Pekudei',
            'VAYIKRA'             => 'Vayikra',
            'TZAV'                => 'Tzav',
            'SHMINI'              => 'Shmini',
            'TAZRIA'              => 'Tazria',
            'METZORA'             => 'Metzora',
            'ACHREI_MOS'          => 'Acharei Mos',
            'KEDOSHIM'            => 'Kedoshim',
            'EMOR'                => 'Emor',
            'BEHAR'               => 'Behar',
            'BECHUKOSAI'          => 'Bechukosai',
            'BAMIDBAR'            => 'Bamidbar',
            'NASSO'               => 'Nasso',
            'BEHAALOSCHA'         => 'Behaalosecha',
            'SHLACH'              => "Sh'lach",
            'KORACH'              => 'Korach',
            'CHUKAS'              => 'Chukas',
            'BALAK'               => 'Balak',
            'PINCHAS'             => 'Pinchas',
            'MATOS'               => 'Matos',
            'MASEI'               => 'Masei',
            'DEVARIM'             => 'Devarim',
            'VAESCHANAN'          => 'Vaeschanan',
            'EIKEV'               => 'Eikev',
            'REEH'                => "Re'eh",
            'SHOFTIM'             => 'Shoftim',
            'KI_SEITZEI'          => 'Ki Seitzei',
            'KI_SAVO'             => 'Ki Savo',
            'NITZAVIM'            => 'Nitzavim',
            'VAYEILECH'           => 'Vayeilech',
            'HAAZINU'             => "Ha'Azinu",
            'VZOS_HABERACHA'      => 'Vezos HaBeracha',
            'VAYAKHEL_PEKUDEI'    => 'Vayakhel - Pekudei',
            'TAZRIA_METZORA'      => 'Tazria - Metzora',
            'ACHREI_MOS_KEDOSHIM' => 'Achrei Mos - Kedoshim',
            'BEHAR_BECHUKOSAI'    => 'Behar - Bechukosai',
            'CHUKAS_BALAK'        => 'Chukas - Balak',
            'MATOS_MASEI'         => 'Matos - Masei',
            'NITZAVIM_VAYEILECH'  => 'Nitzavim - Vayeilech',
            'SHKALIM'             => 'Shekalim',
            'ZACHOR'              => 'Zachor',
            'PARA'                => 'Parah',
            'HACHODESH'           => 'Hachodesh',
            'SHUVA'               => 'Shuva',
            'SHIRA'               => 'Shira',
            'HAGADOL'             => 'Hagadol',
            'CHAZON'              => 'Chazon',
            'NACHAMU'             => 'Nachamu',
        ];

        $monthDefaults = [
            'Nissan', 'Iyar', 'Sivan', 'Tammuz', 'Av', 'Elul',
            'Tishrei', 'Cheshvan', 'Kislev', 'Teves', 'Shevat',
            'Adar', 'Adar II', 'Adar I',
        ];

        $holidayDefaults = [
            "Erev Pesach", 
            "Pesach", 
            "Chol Hamoed Pesach", 
            "Pesach Sheni",
			"Erev Shavuos", 
            "Shavuos", 
            "Seventeenth of Tammuz", 
            "Tishah B'Av", 
            "Tu B'Av", 
            "Erev Rosh Hashana",
			"Rosh Hashana", 
            "Fast of Gedalyah", 
            "Erev Yom Kippur", 
            "Yom Kippur", 
            "Erev Succos", 
            "Succos",
			"Chol Hamoed Succos", 
            "Hoshana Rabbah", 
            "Shemini Atzeres", 
            "Simchas Torah", 
            "Erev Chanukah", 
            "Chanukah",
			"Tenth of Teves", 
            "Tu B'Shvat", 
            "Fast of Esther", 
            "Purim", 
            "Shushan Purim", 
            "Purim Katan", 
            "Rosh Chodesh",
			"Yom HaShoah", 
            "Yom Hazikaron", 
            "Yom Ha'atzmaut", 
            "Yom Yerushalayim", 
            "Lag B'Omer",
            "Shushan Purim Katan",
			"Isru Chag"
        ];

        return [ $parshaDefaults, $monthDefaults, $holidayDefaults ];
    } // end zmanim_wp_transliteration_defaults

    function nusach_handler() {
        // Maps string option keys to Parsha:: integer constants
        $parshaConstantMap = [
            'NONE'                => Parsha::NONE,
            'BERESHIS'            => Parsha::BERESHIS,
            'NOACH'               => Parsha::NOACH,
            'LECH_LECHA'          => Parsha::LECH_LECHA,
            'VAYERA'              => Parsha::VAYERA,
            'CHAYEI_SARA'         => Parsha::CHAYEI_SARA,
            'TOLDOS'              => Parsha::TOLDOS,
            'VAYETZEI'            => Parsha::VAYETZEI,
            'VAYISHLACH'          => Parsha::VAYISHLACH,
            'VAYESHEV'            => Parsha::VAYESHEV,
            'MIKETZ'              => Parsha::MIKETZ,
            'VAYIGASH'            => Parsha::VAYIGASH,
            'VAYECHI'             => Parsha::VAYECHI,
            'SHEMOS'              => Parsha::SHEMOS,
            'VAERA'               => Parsha::VAERA,
            'BO'                  => Parsha::BO,
            'BESHALACH'           => Parsha::BESHALACH,
            'YISRO'               => Parsha::YISRO,
            'MISHPATIM'           => Parsha::MISHPATIM,
            'TERUMAH'             => Parsha::TERUMAH,
            'TETZAVEH'            => Parsha::TETZAVEH,
            'KI_SISA'             => Parsha::KI_SISA,
            'VAYAKHEL'            => Parsha::VAYAKHEL,
            'PEKUDEI'             => Parsha::PEKUDEI,
            'VAYIKRA'             => Parsha::VAYIKRA,
            'TZAV'                => Parsha::TZAV,
            'SHMINI'              => Parsha::SHMINI,
            'TAZRIA'              => Parsha::TAZRIA,
            'METZORA'             => Parsha::METZORA,
            'ACHREI_MOS'          => Parsha::ACHREI_MOS,
            'KEDOSHIM'            => Parsha::KEDOSHIM,
            'EMOR'                => Parsha::EMOR,
            'BEHAR'               => Parsha::BEHAR,
            'BECHUKOSAI'          => Parsha::BECHUKOSAI,
            'BAMIDBAR'            => Parsha::BAMIDBAR,
            'NASSO'               => Parsha::NASSO,
            'BEHAALOSCHA'         => Parsha::BEHAALOSCHA,
            'SHLACH'              => Parsha::SHLACH,
            'KORACH'              => Parsha::KORACH,
            'CHUKAS'              => Parsha::CHUKAS,
            'BALAK'               => Parsha::BALAK,
            'PINCHAS'             => Parsha::PINCHAS,
            'MATOS'               => Parsha::MATOS,
            'MASEI'               => Parsha::MASEI,
            'DEVARIM'             => Parsha::DEVARIM,
            'VAESCHANAN'          => Parsha::VAESCHANAN,
            'EIKEV'               => Parsha::EIKEV,
            'REEH'                => Parsha::REEH,
            'SHOFTIM'             => Parsha::SHOFTIM,
            'KI_SEITZEI'          => Parsha::KI_SEITZEI,
            'KI_SAVO'             => Parsha::KI_SAVO,
            'NITZAVIM'            => Parsha::NITZAVIM,
            'VAYEILECH'           => Parsha::VAYEILECH,
            'HAAZINU'             => Parsha::HAAZINU,
            'VZOS_HABERACHA'      => Parsha::VZOS_HABERACHA,
            'VAYAKHEL_PEKUDEI'    => Parsha::VAYAKHEL_PEKUDEI,
            'TAZRIA_METZORA'      => Parsha::TAZRIA_METZORA,
            'ACHREI_MOS_KEDOSHIM' => Parsha::ACHREI_MOS_KEDOSHIM,
            'BEHAR_BECHUKOSAI'    => Parsha::BEHAR_BECHUKOSAI,
            'CHUKAS_BALAK'        => Parsha::CHUKAS_BALAK,
            'MATOS_MASEI'         => Parsha::MATOS_MASEI,
            'NITZAVIM_VAYEILECH'  => Parsha::NITZAVIM_VAYEILECH,
            'SHKALIM'             => Parsha::SHKALIM,
            'ZACHOR'              => Parsha::ZACHOR,
            'PARA'                => Parsha::PARA,
            'HACHODESH'           => Parsha::HACHODESH,
            'SHUVA'               => Parsha::SHUVA,
            'SHIRA'               => Parsha::SHIRA,
            'HAGADOL'             => Parsha::HAGADOL,
            'CHAZON'              => Parsha::CHAZON,
            'NACHAMU'             => Parsha::NACHAMU,
        ];

        [ $parshaDefaults, $monthDefaults, $holidayDefaults ] = zmanim_wp_transliteration_defaults();

        $customParsha   = get_option( 'wpkz_parsha_names', [] );
        $customMonths   = get_option( 'wpkz_month_names', [] );
        $customHolidays = get_option( 'wpkz_holiday_names', [] );
        if ( !is_array( $customParsha ) )   $customParsha   = [];
        if ( !is_array( $customMonths ) )   $customMonths   = [];
        if ( !is_array( $customHolidays ) ) $customHolidays = [];

        // Build parsha map keyed by Parsha:: integer constants
        $transliteratedParshaMap = [];
        foreach ( $parshaConstantMap as $key => $constant ) {
            $transliteratedParshaMap[$constant] =
                ( isset( $customParsha[$key] ) && $customParsha[$key] !== '' )
                    ? $customParsha[$key]
                    : $parshaDefaults[$key];
        }

        // Build months array (0-indexed)
        $transliteratedMonths = [];
        foreach ( $monthDefaults as $i => $default ) {
            $transliteratedMonths[$i] =
                ( isset( $customMonths[$i] ) && $customMonths[$i] !== '' )
                    ? $customMonths[$i]
                    : $default;
        }

        // Build holidays array (0-indexed)
        $transliteratedHolidays = [];
        foreach ( $holidayDefaults as $i => $default ) {
            $transliteratedHolidays[$i] =
                ( isset( $customHolidays[$i] ) && $customHolidays[$i] !== '' )
                    ? $customHolidays[$i]
                    : $default;
        }

        return array( $transliteratedParshaMap, $transliteratedMonths, $transliteratedHolidays );
    } // end nusach_handler

    function parsha_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
        ) );
        $option = '';
        $zmanargs = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            1
        );

        $nusach = get_option( 'wpkz_nusach' );
        $offset = $zmanargs[6];
        $theyear = $zmanargs[0];
        $themonth = $zmanargs[1];
        $theday = $zmanargs[2];
        $dayofweek = gmdate( 'w', strtotime( "{$theyear}-{$themonth}-{$theday}" ) );
        if ( $dayofweek != 6 ) {
            $daychange = 6 - $dayofweek;
            $newdate = gmdate( 'Y-m-d', strtotime( "{$theyear}-{$themonth}-{$theday}" . "+{$daychange} days" ) );
        }
        $theyear = gmdate( 'Y', strtotime( $newdate ) );
        $themonth = gmdate( 'm', strtotime( $newdate ) );
        $theday = gmdate( 'd', strtotime( $newdate ) );
        $jewishCalendar = Zmanim::jewishCalendar( Carbon::createFromDate( $theyear, $themonth, $theday ) );
        $format = Zmanim::format();

        if ( $nusach == 1 ) {
            list($transliteratedParshaMap,$transliteratedMonths,$transliteratedHolidays) = nusach_handler();
            $format->setTransliteratedParshiosList( $transliteratedParshaMap );
        } 
        if ( strtolower( $atts['lang'] ) == 'hebrew' ) {
            $format->setHebrewFormat( true );
        }

        $output = json_decode( '"' . $format->formatParsha( $jewishCalendar ) . '"' );

        if (!$output) {
            $specialParsha =  $jewishCalendar->getSpecialShabbos();
            $yomtovindex = $jewishCalendar->getYomTovIndex();
            if ( $nusach == 1 ) {
                list($transliteratedParshaMap,$transliteratedMonths,$transliteratedHolidays) = nusach_handler();
                $format->setTransliteratedHolidayList($transliteratedHolidays);
            } 
            if ( strtolower( $atts['lang'] ) == 'hebrew' ) {
                $format->setHebrewFormat( true );
            }
            if ($specialParsha>0) {
                $output = json_decode( '"' . $format->formatSpecialParsha( $jewishCalendar ) . '"' ) ;
            } elseif ($yomtovindex>-1) {
                $output =  json_decode( '"' . $format->formatYomTov($jewishCalendar) . '"' ) ;
            }
        }

        return $output;
    } // end parsha_handler

    function zmandate_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
        ) );
        $option = '';
        $zmanargs = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            1
        );
        $nusach = get_option( 'wpkz_nusach' );
        $offset = $zmanargs[6];
        $theyear = intval( $zmanargs[0] );
        $themonth = intval( $zmanargs[1] );
        $theday = intval( $zmanargs[2] );
        $jewishCalendar = Zmanim::jewishCalendar( Carbon::createFromDate( $theyear, $themonth, $theday ) );
        $format = Zmanim::format();
        if ( $nusach == 1 ) {
            list($transliteratedParshaMap,$transliteratedMonths,$transliteratedHolidays) = nusach_handler();
            $format->setTransliteratedMonthList($transliteratedMonths);
        }
        if ( strtolower( $atts['lang'] ) == 'hebrew' ) {
            $format->setHebrewFormat( true );
            $zmandate = json_decode( '"' . $format->format( $jewishCalendar ) . '"' );
        } elseif (strtolower( $atts['lang'] ) == 'transliterated' || strtolower( $atts['lang'] ) == 'translit'  || strtolower( $atts['lang'] ) == 'trans' )  {
            $zmandate = json_decode( '"' . $format->format( $jewishCalendar ) . '"' );
        } else {
            $zmandate = gmdate( 'd M Y', strtotime( "{$theyear}-{$themonth}-{$theday}" ) );    
        }

        $output = $zmandate;
        return $output;
    } // end zmandate_handler

function omer_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
        ) );
        $option = '';
        $zmanargs = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            1
        );
        $nusach = get_option( 'wpkz_nusach' );
        $offset = $zmanargs[6];
        $theyear = intval( $zmanargs[0] );
        $themonth = intval( $zmanargs[1] );
        $theday = intval( $zmanargs[2] );
        $jewishCalendar = Zmanim::jewishCalendar( Carbon::createFromDate( $theyear, $themonth, $theday ) );
        $format = Zmanim::format();

        $output =  $jewishCalendar->getDayOfOmer();
        if ($output > 0) { return $output; } else { return ""; }
    } // end zmanomer_handler

    function mevorchim_handler(  $atts = []  ) {
        global $zmanimwp_fakedate;
        $atts = wp_parse_args( $atts, array(
            "date"       => '',
            "year"       => '',
            "month"      => '',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "get"        => "both"
        ) );
        $option = '';
        $zmanargs = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            1
        );
        $thedate = $atts['date'];
        //today, next (week), or a date
        # figure out when they want this (today, next week, or a date)
        # and get either THIS sunday, the FOLLOWING sunday, or leave it alone
        if ( !$thedate ) {
            $thedate = "today";
        }
        if ( $thedate ) {
            if ( is_a( $thedate, 'DateTime' ) ) {
                #let it ride
            } elseif ( $thedate == "today" ) {
                $thedate = gmdate( 'D Y-m-d' );
                #zmanimwp_fakedate is for testing only
                if ( $zmanimwp_fakedate != "" ) {
                    $thedate = gmdate( 'D Y-m-d', strtotime( $zmanimwp_fakedate ) );
                }
                $thedate = gmdate( 'D Y-m-d', strtotime( 'next saturday', strtotime( $thedate ) ) );
            } elseif ( $thedate == "next" ) {
                $thedate = gmdate( 'D Y-m-d' );
                $thedate = gmdate( 'D Y-m-d', strtotime( 'next saturday', strtotime( $thedate ) ) );
                $thedate = gmdate( 'D Y-m-d', strtotime( $thedate . " +7 days" ) );
            }
        }
        #end if thedate
        $thedateY = gmdate( 'Y', strtotime( $thedate ) );
        $thedateM = gmdate( 'm', strtotime( $thedate ) );
        $thedateD = gmdate( 'd', strtotime( $thedate ) );
        # take the date and convert it to the hebrew date
        $todayheb = new JewishDate(Carbon::createFromDate( $thedateY, $thedateM, $thedateD ));
        $todayhebyear = $todayheb->getJewishYear();
        $todayhebmonth = $todayheb->getJewishMonth();
        $todayhebday = $todayheb->getJewishDayOfMonth();
        $mevorchimdate = Zmanim::jewishCalendar( $todayhebyear, $todayhebmonth, $todayhebday );
        #Check if todayHebDay (either this saturday, next saturday, or the date given) is Mevarchim
        $ismevorchim = $mevorchimdate->isShabbosMevorchim();

        if ($ismevorchim == true)
        {
            $thedate = gmdate( 'Y-m-d', strtotime($thedate));
            $atts['date'] = $thedate; 
            $attsget = $atts['get'];
            if ($attsget == "molad") {
                $molad = molad_handler($atts);
                return $molad;
            } elseif ($attsget == "chodesh") {
                $chodesh = chodesh_handler($atts);
                return $chodesh;
            } elseif ($attsget == "both" || $atts['get'] == "")  {
                $molad = molad_handler($atts);
                $chodesh = chodesh_handler($atts);
                return $molad."<br><br>".$chodesh;
            } else { return ""; }
        } else {return "";}


    }  // end mevorchim_handler

    function molad_handler(  $atts = []  ) {
        global $zmanimwp_fakedate;
        $atts = wp_parse_args( $atts, array(
            "date"       => '',
            "year"       => '',
            "month"      => '',
            "dateformat" => "g a",
            "lang"       => "english",
        ) );
        $option = get_option( 'wpkz_molad' );
        $zmanargs = zmanim_wp_getzmanim(
            $atts['date'],
            "",
            $atts['dateformat'],
            $atts['lang'],
            $option,
            1
        );
        $offset = $zmanargs[6];
        $attsdate = strtolower( $atts['date'] );
        $thedate = $atts['date'];
        //today, next (week), or a date (or blank)
        $dateformat = $atts['dateformat'];
        $lang = $atts['lang'];
        $moladtitle = get_option( 'wpkz_molad' ) . "<br>";

        # figure out when they want this (today, next week, or a date)
        # and get either THIS sunday, the FOLLOWING sunday, or leave it alone
        if ( !$thedate ) {
            $thedate = "today";
        }
        if ( $thedate ) {
            if ( is_a( $thedate, 'DateTime' ) ) {
                #let it ride
            } elseif ( $thedate == "today" ) {
                $thedate = gmdate( 'D Y-m-d' );
                #zmanimwp_fakedate is for testing only
                if ( $zmanimwp_fakedate != "" ) {
                    $thedate = gmdate( 'D Y-m-d', strtotime( $zmanimwp_fakedate ) );
                }
                $thedate = gmdate( 'D Y-m-d', strtotime( 'next sunday', strtotime( $thedate ) ) );
            } elseif ( $thedate == "next" ) {
                $thedate = gmdate( 'D Y-m-d' );
                $thedate = gmdate( 'D Y-m-d', strtotime( 'next sunday', strtotime( $thedate ) ) );
                $thedate = gmdate( 'D Y-m-d', strtotime( $thedate . " +7 days" ) );
            }
        }

        #end if thedate. It's now set to the upcoming sunday
        $thedateY = gmdate( 'Y', strtotime( $thedate ) );
        $thedateM = gmdate( 'm', strtotime( $thedate ) );
        $thedateD = gmdate( 'd', strtotime( $thedate ) );
        # take the date and convert it to the hebrew date
        $todayheb = new JewishDate(Carbon::createFromDate( $thedateY, $thedateM, $thedateD ));
        $chodeshyear = $todayheb->getJewishYear();
        $todayhebmonth = $todayheb->getJewishMonth();
        $todayhebday = $todayheb->getJewishDayOfMonth();

        // IF todayhebday (the upcoming Sunday) is the 30th or the 1st it means Sunday is RH and the previous Shabbat is Mevarchim.
        if ($todayhebday == 1 ) {
            $chodeshmonth = $todayhebmonth;
        } else {
            $nextheb = $todayheb->addMonthsJewish( 1 );
            $nexthebmonth = $nextheb->getJewishMonth();
            $chodeshmonth = $nexthebmonth;
        }
        // exit if the new month is Tishrei
        if ($chodeshmonth == 7) {return "";}

        $chodeshdate = Zmanim::jewishCalendar( $chodeshyear, $chodeshmonth, 1 );
        $chodeshdateeng = $chodeshdate->getGregorianCalendar();
        $molad = $chodeshdate->getMolad();
        $moladdate = $molad->getGregorianCalendar();

    // uncomment for testing
    #echo "zmanimwp_fakedate: $zmanimwp_fakedate, thedate: $thedate, today year-month-day: $chodeshyear-$todayhebmonth-$todayhebday, chodesh: $chodeshdateeng, molad: $moladdate\n";

        $moladhours = $molad->getMoladHours();
        $moladminutes = $molad->getMoladMinutes();
        $moladhoursformatted = gmdate('g a', strtotime( "{$moladhours}:{$moladminutes}" ) );
        $moladchalakim = $molad->getMoladChalakim();
        if ($moladchalakim == 0) {
            $moladchalakimstring = "";
        } elseif ($moladchalakim == 1) {
            $moladchalakimstring = "and 1 chelek";
        } else {
            $moladchalakimstring = "and $moladchalakim chalakim";
        }
        $moladdateformatted = $moladdate->format( "D m/d" );

        # if they specified "today" (or blank), we only show the molad info if it's going to be this coming shabbat
        # BUT NOT if RH starts Sunday
        # the same for "next" but if it's going to be the following week
        $moladstring = "";
        if ( empty( $attsdate ) || $attsdate == "today" || $attsdate == "next" ) {
            $moladdate = gmdate( 'Y-m-d', strtotime( $moladdate ) );
            $thedate = gmdate( 'Y-m-d', strtotime( $thedate ) );
            $daystomolad = floor( (strtotime( $moladdate ) - strtotime( $thedate )) / 86400 );
            $daystoroshchodesh = floor( (strtotime( $chodeshdateeng ) - strtotime( $thedate )) / 86400 );
            if ( $daystomolad <= 6 && $daystoroshchodesh <= 6) {
                $moladstring = "{$moladtitle} {$moladdateformatted}, {$moladminutes} minutes {$moladchalakimstring} after {$moladhoursformatted}";
            } else {
                $moladstring = "";
            }
        } else {
            $moladstring = "{$moladtitle} {$moladdateformatted}, {$moladminutes} minutes {$moladchalakimstring} after {$moladhoursformatted}";
        }
        return $moladstring;
    } // end molad_handler

    function chodesh_handler(  $atts = []  ) {
        global $zmanimwp_fakedate;
        $atts = wp_parse_args( $atts, array(
            "date"       => '',
            "year"       => '',
            "month"      => '',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
        ) );
        $option = get_option( 'wpkz_chodesh' );
        $zmanargs = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            1
        );
        $offset = $zmanargs[6];
        $attsdate = $atts['date'];
        $thedate = $atts['date'];
        //today, next (week), or a date
        $dateformat = $atts['dateformat'];
        $lang = $atts['lang'];
        $rhtitle = get_option( 'wpkz_chodesh' )  . "<br>";
#echo "title: $rhtitle";
        #$rhtitle = get_option( 'wpkz_chodesh' ) . "<br>";
        # figure out when they want this (today, next week, or a date)
        # and get either THIS sunday, the FOLLOWING sunday, or leave it alone
        if ( !$thedate ) {
            $thedate = "today";
        }
        if ( $thedate ) {
            if ( is_a( $thedate, 'DateTime' ) ) {
                #let it ride
            } elseif ( $thedate == "today" ) {
                $thedate = gmdate( 'D Y-m-d' );
                #zmanimwp_fakedate is for testing only
                if ( $zmanimwp_fakedate != "" ) {
                    $thedate = gmdate( 'D Y-m-d', strtotime( $zmanimwp_fakedate ) );
                }
                $thedate = gmdate( 'D Y-m-d', strtotime( 'next sunday', strtotime( $thedate ) ) );
            } elseif ( $thedate == "next" ) {
                $thedate = gmdate( 'D Y-m-d' );
                $thedate = gmdate( 'D Y-m-d', strtotime( 'next sunday', strtotime( $thedate ) ) );
                $thedate = gmdate( 'D Y-m-d', strtotime( $thedate . " +7 days" ) );
            }
        }
        #end if thedate
        $thedateY = gmdate( 'Y', strtotime( $thedate ) );
        $thedateM = gmdate( 'm', strtotime( $thedate ) );
        $thedateD = gmdate( 'd', strtotime( $thedate ) );
        # take the date and convert it to the hebrew date
        $todayheb = new JewishDate(Carbon::createFromDate( $thedateY, $thedateM, $thedateD ));
        $chodeshyear = $todayheb->getJewishYear();
        $todayhebmonth = $todayheb->getJewishMonth();
        $todayhebday = $todayheb->getJewishDayOfMonth();
        // IF todayhebday (the upcoming Sunday) is x/1 it means Sunday is RH and the previous Shabbat was Mevarchim.
        if ($todayhebday == 1) {
            $chodeshmonth = $todayhebmonth;
        } else {
            $nextheb = $todayheb->addMonthsJewish( 1 );
            $nexthebmonth = $nextheb->getJewishMonth();
            $chodeshmonth = $nexthebmonth;
        }
        // exit if the new month is Tishrei
        if ($chodeshmonth == 7) {return "";}
        $chodeshdate = Zmanim::jewishCalendar( $chodeshyear, $chodeshmonth, 1 );
        $chodeshdateeng = $chodeshdate->getGregorianCalendar();

    // uncomment for testing
    //echo "zmanimwp_fakedate: $zmanimwp_fakedate, thedate: $thedate, today year-month-day: $chodeshyear-$todayhebmonth-$todayhebday\n";


        $format = Zmanim::format();
        $lang = strtolower( $lang );
        if ( $lang == 'heb' || $lang == 'hebrew' ) {
            $format->setHebrewFormat( true );
            $chodeshmonthnameheb = json_decode( '"' . $format->formatMonth( $chodeshdate ) . '"' );
            $chodeshstartstring = "Rosh Chodesh {$chodeshmonthnameheb} will be ";
        } elseif ( $lang == 'both' || $lang == 'both' ) {
            $format->setHebrewFormat( false );
            $chodeshmonthnameeng = json_decode( '"' . $format->formatMonth( $chodeshdate ) . '"' );
            $format->setHebrewFormat( true );
            $chodeshmonthnameheb = json_decode( '"' . $format->formatMonth( $chodeshdate ) . '"' );
            $chodeshstartstring = "Rosh Chodesh {$chodeshmonthnameeng} / {$chodeshmonthnameheb} will be ";
        } elseif ( !isset( $lang ) || $lang == 'eng' || $lang == 'english' ) {
            $format = Zmanim::format();
            $format->setHebrewFormat( false );
            $chodeshmonthnameeng = json_decode( '"' . $format->formatMonth( $chodeshdate ) . '"' );
            $chodeshstartstring = "Rosh Chodesh {$chodeshmonthnameeng} will be ";
        }
        #get the RH date(s) for the specified hebrew month/year
        $rhstart = new JewishDate($chodeshyear, $chodeshmonth, 1);
        $rhstartdate = gmdate( 'D m/d/y', strtotime( $rhstart->getGregorianCalendar() ) );
        $rhdatestring = gmdate( 'D m/d/y', strtotime( $rhstart->getGregorianCalendar() ) );
        $nextrhstart = $rhstart->subDays( 1 );
        if ( $nextrhstart->getJewishDayOfMonth() == 30 ) {
            #2-day RH, on 30 and 1
            #get gregdate of day before 1st of month
            $rhstart = gmdate( 'D m/d/y', strtotime( $nextrhstart->getGregorianCalendar() ) );
            $rhdatestring = "{$rhstart} and " . $rhdatestring;
        }
        # if they specified "today", we only show the chodesh info if it's going to be RH.
        $rhstring = "";
        if ( empty( $attsdate ) || $attsdate == "today" || $attsdate == "next" ) {
            $rhdate = gmdate( 'Y-m-d', strtotime( $rhstartdate ) );
            $thedate = gmdate( 'Y-m-d', strtotime( $thedate ) );
            $daystochodesh = floor( (strtotime( $rhdate ) - strtotime( $thedate )) / 86400 );
            if ( $daystochodesh >= 0 && $daystochodesh <= 6 ) {
                $rhstring = "{$rhtitle} {$chodeshstartstring} {$rhdatestring}";
            } else {
                $rhstring = "";
            }
        } else {
            $rhstring = "{$rhtitle} {$chodeshstartstring} {$rhdatestring}";
        }
        return $rhstring;
    }  // end chodesh_handler

    function sunrise_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $zmanargs = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],

            "",
            1
        );
        $offset = $zmanargs[6];
        $zmanim = Zmanim::create(
            $zmanargs[0],
            $zmanargs[1],
            $zmanargs[2],
            "",
            $zmanargs[3],
            $zmanargs[4],
            0,
            $zmanargs[5]
        );
        $output = $zmanim->sunrise;
        if ( $atts['offset'] != 0 ) {
            $output = gmdate( $atts['dateformat'], strtotime( $output . " {$offset} minutes" ) );
        } else {
            $output = gmdate( $atts['dateformat'], strtotime( $output ) );
        }
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    } // end sunrise_handler

    function sunset_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $zmanargs = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            "",
            1
        );
        $offset = $zmanargs[6];
        $zmanim = Zmanim::create(
            $zmanargs[0],
            $zmanargs[1],
            $zmanargs[2],
            "",
            $zmanargs[3],
            $zmanargs[4],
            0,
            $zmanargs[5]
        );
        $output = $zmanim->sunset;
        if ( $atts['offset'] != 0 ) {
            $output = gmdate( $atts['dateformat'], strtotime( $output . " {$offset} minutes" ) );
        } else {
            $output = gmdate( $atts['dateformat'], strtotime( $output ) );
        }
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    } // end sunset_handler

    function candles_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
        ) );
        $option = get_option( 'wpkz_candles' );
        $zmanargs = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            1
        );
        $offset = $zmanargs[6];
        $zmanim = Zmanim::create(
            $zmanargs[0],
            $zmanargs[1],
            $zmanargs[2],
            "",
            $zmanargs[3],
            $zmanargs[4],
            0,
            $zmanargs[5]
        );
        $sunset = $zmanim->sunset;
        if ( $offset != 0 ) {
            $option = $option + $offset;
        }
        $output = gmdate( $atts['dateformat'], strtotime( $sunset . " -" . $option . " minutes" ) );
        return $output;
    } // end candles_handler

    function alot_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",

        ) );
        $option = get_option( 'wpkz_alot' );
        $output = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            0
        );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    } // end alot_handler

    function tzait_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $option = get_option( 'wpkz_tzait' );
        $output = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            0
        );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    } // end tzait_handler

    function tzait2_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $option = get_option( 'wpkz_tzait2' );
        $output = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            0
        );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    } // end tzait2_handler

    function chatzot_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $option = get_option( 'wpkz_chatzot' );
        $output = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            0
        );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    } // end chatzot_handler

    function shaah_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
        ) );
        $option = get_option( 'wpkz_shaah' );
        $zmanargs = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            1
        );
        $offset = $zmanargs[6];
        $zmanim = Zmanim::create(
            $zmanargs[0],
            $zmanargs[1],
            $zmanargs[2],
            "",
            $zmanargs[3],
            $zmanargs[4],
            0,
            $zmanargs[5]
        );
        $output = number_format(
            (float) $zmanim->{$option} / 60000,
            2,
            '.',
            ''
        );
        return $output;
    }// end shaah_handler

    function misheyakir_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
        ) );
        $option = get_option( 'wpkz_misheyakir' );
        $output = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            0
        );
        return $output;
    } // end misheyakir_handler

    function shema_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $option = get_option( 'wpkz_shema' );
        $output = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            0
        );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }// end shema_handler

    function shema2_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $option = get_option( 'wpkz_shema2' );
        $output = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            0
        );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }// end shema2_handler

    function tefilla_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $option = get_option( 'wpkz_tefilla' );
        $output = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            0
        );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }// end tefilla_handler

    function tefilla2_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $option = get_option( 'wpkz_tefilla2' );
        $output = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            0
        );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }// end tefilla2_handler

    function gedola_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $option = get_option( 'wpkz_gedola' );
        $output = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            0
        );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }// end gedola_handler

    function ketana_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $option = get_option( 'wpkz_ketana' );
        $output = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            0
        );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    } // end ketana_handler

    function plag_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $option = get_option( 'wpkz_plag' );
        $output = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            0
        );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    } //end plag_handler

    function plag2_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $option = get_option( 'wpkz_plag2' );
        $output = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            0
        );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    } //end plag2_handler

    function bain_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $option = get_option( 'wpkz_bain' );
        $output = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            0
        );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    } // end bain_handler

    function yomtov_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
        ) );
        $option = '';
        $zmanargs = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            1
        );
        $nusach = get_option( 'wpkz_nusach' );
        $offset = $zmanargs[6];
        $theyear = intval( $zmanargs[0] );
        $themonth = intval( $zmanargs[1] );
        $theday = intval( $zmanargs[2] );
        $jewishCalendar = Zmanim::jewishCalendar( Carbon::createFromDate( $theyear, $themonth, $theday ) );
        $specialParsha =  $jewishCalendar->getSpecialShabbos();
        $yomtovindex = $jewishCalendar->getYomTovIndex();
        $format = Zmanim::format();
        $output ="";

        if ( $nusach == 1 ) {
            list($transliteratedParshaMap,$transliteratedMonths,$transliteratedHolidays) = nusach_handler();
            $format->setTransliteratedHolidayList($transliteratedHolidays);
        } 
        if ( strtolower( $atts['lang'] ) == 'hebrew' ) {
            $format->setHebrewFormat( true );
        }
    
        if ($specialParsha>0) {
            if ($nusach ==1 ) {
                $output = "Shabbat";
            } else {
                $output = "Shabbos";
            }
            if ( strtolower( $atts['lang'] ) == 'hebrew' ) {
                $output = "שַׁבָּת ";
            }
            $output = $output . " " . json_decode( '"' . $format->formatSpecialParsha( $jewishCalendar ) . '"' ) . "<BR>";
        } elseif ($yomtovindex>-1) {
            if ($nusach ==1 ) {
                $output = "Shabbat";
            } else {
                $output = "Shabbos";
            }
            if ( strtolower( $atts['lang'] ) == 'hebrew' ) {
                $output = "שַׁבָּת ";
            }
            $output = $output . " " . $format->formatYomTov($jewishCalendar) . "<BR>";
        }
        
        return $output;
    } #end yomtov_handler


    function earlyshkia_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $option = '';
        $zmanargs = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            1
        );
        $offset = $zmanargs[6];
        $dateformat = $atts['dateformat'];
        $attsdate = $atts['date'];
        #sanitize inputs
        if ( isset( $offset ) ) {
            $offset = zmanim_wp_sanitize( $offset, "int" );
            if ( substr( $offset, 0, 1 ) == "+" || substr( $offset, 0, 1 ) == "-" ) {
                $offsetsign = substr( $offset, 0, 1 );
                $offsetnum = substr( $offset, 1 );
            } else {
                $offsetsign = "+";
                $offsetnum = $offset;
            }
            $offset = $offsetsign . $offsetnum;
        }
        if ( isset( $dateformat ) ) {
            $dateformat = zmanim_wp_sanitize( $dateformat, 'string' );
        }
        #if they said "next", get a week from Sunday
        if ( $attsdate == 'next' ) {
            $thedate = gmdate( 'Y-m-d h:i:s a' );
            $dayofweek = gmdate( 'w', strtotime( $thedate ) );
            $daystosunday = 7 - $dayofweek;
            $thedate = gmdate( 'Y-m-d', strtotime( $thedate . " +{$daystosunday} days" ) );
        } elseif ( !isset( $attsdate ) || $attsdate == 'today' ) {
            $thedate = gmdate( 'Y-m-d' );
            $dayofweek = gmdate( 'w', strtotime( $thedate ) );
            $thedate = gmdate( 'Y-m-d', strtotime( $thedate . " -{$dayofweek} days" ) );
        }
        $theyear = gmdate( 'Y', strtotime( $thedate ) );
        $themonth = gmdate( 'm', strtotime( $thedate ) );
        $theday = gmdate( 'd', strtotime( $thedate ) );
        $dayofweek = gmdate( 'w', strtotime( "{$theyear}-{$themonth}-{$theday}" ) );
        $getdate = gmdate( 'Y-m-d', strtotime( "{$theyear}-{$themonth}-{$theday}" . " -{$dayofweek} days" ) );
        for ($i = 1; $i <= 5; $i++) {
            $getyear = gmdate( 'Y', strtotime( $getdate ) );
            $getmonth = gmdate( 'm', strtotime( $getdate ) );
            $getday = gmdate( 'd', strtotime( $getdate ) );
            $zmanim = Zmanim::create(
                $getyear,
                $getmonth,
                $getday,
                "",
                $zmanargs[3],
                $zmanargs[4],
                0,
                $zmanargs[5]
            );
            $getsunset = $zmanim->sunset;
            $getsunset = $getsunset->format( 'h:i:s a' );
            $sunsetarray[] = $getsunset;
            $getdate = gmdate( 'Y-m-d', strtotime( "{$getdate}" . "+1 day" ) );
        }
        $earlyshkia = min( $sunsetarray );
        if ( $offset != 0 ) {
            $output = gmdate( $dateformat, strtotime( $earlyshkia . " {$offset} minutes" ) );
        } else {
            $output = gmdate( $dateformat, strtotime( $earlyshkia ) );
        }
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    } //end earlyshkia handler

    function lateshkia_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $option = '';
        $zmanargs = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            1
        );
        $offset = $atts['offset'];
        $dateformat = $atts['dateformat'];
        $attsdate = $atts['date'];
        #sanitize inputs
        if ( isset( $offset ) ) {
            $offset = zmanim_wp_sanitize( $offset, "int" );
            if ( substr( $offset, 0, 1 ) == "+" || substr( $offset, 0, 1 ) == "-" ) {
                $offsetsign = substr( $offset, 0, 1 );
                $offsetnum = substr( $offset, 1 );
            } else {
                $offsetsign = "+";
                $offsetnum = $offset;
            }
            $offset = $offsetsign . $offsetnum;
        }
        if ( isset( $dateformat ) ) {
            $dateformat = zmanim_wp_sanitize( $dateformat, 'string' );
        }
        #if they said "next", get a week from Sunday
        if ( $attsdate == 'next' ) {
            $thedate = gmdate( 'Y-m-d h:i:s a' );
            $dayofweek = gmdate( 'w', strtotime( $thedate ) );
            $daystosunday = 7 - $dayofweek;
            $thedate = gmdate( 'Y-m-d', strtotime( $thedate . " +{$daystosunday} days" ) );
        } elseif ( !isset( $attsdate ) || $attsdate == 'today' ) {
            $thedate = gmdate( 'Y-m-d' );
            $dayofweek = gmdate( 'w', strtotime( $thedate ) );
            $thedate = gmdate( 'Y-m-d', strtotime( $thedate . " -{$dayofweek} days" ) );
        }
        $theyear = gmdate( 'Y', strtotime( $thedate ) );
        $themonth = gmdate( 'm', strtotime( $thedate ) );
        $theday = gmdate( 'd', strtotime( $thedate ) );
        $dayofweek = gmdate( 'w', strtotime( "{$theyear}-{$themonth}-{$theday}" ) );
        $getdate = gmdate( 'Y-m-d', strtotime( "{$theyear}-{$themonth}-{$theday}" . " -{$dayofweek} days" ) );
        for ($i = 1; $i <= 5; $i++) {
            $getyear = gmdate( 'Y', strtotime( $getdate ) );
            $getmonth = gmdate( 'm', strtotime( $getdate ) );
            $getday = gmdate( 'd', strtotime( $getdate ) );
            $zmanim = Zmanim::create(
                $getyear,
                $getmonth,
                $getday,
                "",
                $zmanargs[3],
                $zmanargs[4],
                0,
                $zmanargs[5]
            );
            $getsunset = $zmanim->sunset;
            $getsunset = $getsunset->format( 'h:i:s a' );
            $sunsetarray[] = $getsunset;
            $getdate = gmdate( 'Y-m-d', strtotime( "{$getdate}" . "+1 day" ) );
        }
        $lateshkia = max( $sunsetarray );
        if ( $offset != 0 ) {
            $output = gmdate( $dateformat, strtotime( $lateshkia . " {$offset} minutes" ) );
        } else {
            $output = gmdate( $dateformat, strtotime( $lateshkia ) );
        }
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    } // end lateshkia handler

    function misheyakirweekly_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'this',
            "offset"     => 0,
            "dateformat" => "D",
            "timeformat" => "g:i a",
            "lang"       => "english",
            "daynum"     => 0,
        ) );
        $option = get_option( 'wpkz_misheyakir' );
        $zmanargs = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            1
        );
        $offset = $atts['offset'];
        $dateformat = $atts['dateformat'];
        $timeformat = $atts['timeformat'];
        $attsdate = $atts['date'];
        $daynum = $atts['daynum'];
        #sanitize inputs
        if ( isset( $offset ) ) {
            $offset = zmanim_wp_sanitize( $offset, "int" );
            if ( substr( $offset, 0, 1 ) == "+" || substr( $offset, 0, 1 ) == "-" ) {
                $offsetsign = substr( $offset, 0, 1 );
                $offsetnum = substr( $offset, 1 );
            } else {
                $offsetsign = "+";
                $offsetnum = $offset;
            }
            $offset = $offsetsign . $offsetnum;
        }
        if ( isset( $dateformat ) ) {
            $dateformat = zmanim_wp_sanitize( $dateformat, 'string' );
        }
        if ( isset( $timeformat ) ) {
            $timeformat = zmanim_wp_sanitize( $timeformat, 'string' );
        }
        #Did they want this week or next week?
        #if they said "next", get a week from Sunday
        if ( $attsdate == 'next' ) {
            $thedate = gmdate( 'Y-m-d h:i:s a' );
            $dayofweek = gmdate( 'w', strtotime( $thedate ) );
            $daystosunday = 7 - $dayofweek;
            $thedate = gmdate( 'Y-m-d', strtotime( $thedate . " +{$daystosunday} days" ) );
        } elseif ( !isset( $attsdate ) || $attsdate == 'this' ) {
            $thedate = gmdate( 'Y-m-d' );
            $dayofweek = gmdate( 'w', strtotime( $thedate ) );
            $thedate = gmdate( 'Y-m-d', strtotime( $thedate . " -{$dayofweek} days" ) );
        } else {
            $thedate = $attsdate;
        }
        for ($i = 0; $i <= 6; $i++) {
            $getyear = gmdate( 'Y', strtotime( $thedate ) );
            $getmonth = gmdate( 'm', strtotime( $thedate ) );
            $getday = gmdate( 'd', strtotime( $thedate ) );
            $zmanim = Zmanim::create(
                $getyear,
                $getmonth,
                $getday,
                "",
                $zmanargs[3],
                $zmanargs[4],
                0,
                $zmanargs[5]
            );
            $getmisheyakir = $zmanim->{$option};
            $getmisheyakir = $getmisheyakir->format( $timeformat );
            $thedate = gmdate( $dateformat, strtotime( $thedate ) );
            $misheyakirarray["{$thedate}"] = "{$getmisheyakir}";
            $thedate = gmdate( 'Y-m-d', strtotime( $thedate . " +1 day" ) );
        }
        $output = array_keys( $misheyakirarray )[$daynum] . ": " . $misheyakirarray[array_keys( $misheyakirarray )[$daynum]];
        return $output;
    } //end mishayakirweekly_handler

    function fullyear_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "iteration" => 0,
        ) );
        $iteration = '';
        if ( $atts['iteration'] > 0 ) {
            $iteration = $atts['iteration'];
        }
        $starton = get_option( 'wpkz_fullyear_start' );
        $cadence = get_option( 'wpkz_fullyear_cadence' );
        $weekday = get_option( 'wpkz_fullyear_weekday' );
        $engyear = get_option( 'wpkz_fullyear_engyear' );
        $hebyear = get_option( 'wpkz_fullyear_hebyear' );
        $fullyear_columns = [
            get_option( 'wpkz_yearly_col1' ),
            get_option( 'wpkz_yearly_col2' ),
            get_option( 'wpkz_yearly_col3' ),
            get_option( 'wpkz_yearly_col4' ),
            get_option( 'wpkz_yearly_col5' ),
            get_option( 'wpkz_yearly_col6' ),
            get_option( 'wpkz_yearly_col7' ),
            get_option( 'wpkz_yearly_col8' ),
            get_option( 'wpkz_yearly_col9' ),
            get_option( 'wpkz_yearly_col10' )
        ];
        $fullyear_column_titles = [
            get_option( 'wpkz_yearly_col1_title' ),
            get_option( 'wpkz_yearly_col2_title' ),
            get_option( 'wpkz_yearly_col3_title' ),
            get_option( 'wpkz_yearly_col4_title' ),
            get_option( 'wpkz_yearly_col5_title' ),
            get_option( 'wpkz_yearly_col6_title' ),
            get_option( 'wpkz_yearly_col7_title' ),
            get_option( 'wpkz_yearly_col8_title' ),
            get_option( 'wpkz_yearly_col9_title' ),
            get_option( 'wpkz_yearly_col10_title' )
        ];
        if ( $starton == "jan1" ) {
            $thisyear = gmdate( 'Y' );
            if ( empty( $engyear ) ) {
                $thisyear = $engyear;
            }
            $startdate = gmdate( 'Y-m-d', strtotime( $thisyear . "-01-01" ) );
        }
        if ( $starton == "tish1" ) {
            $thedateY = gmdate( 'Y' );
            $todayheb = new JewishDate(Carbon::createFromDate( $thedateY, 1, 1 ));
            $thisyear = $todayheb->getJewishYear();
            if ( !empty( $hebyear ) ) {
                $thisyear = $hebyear;
            }
            $startdateheb = new JewishDate($thisyear, 7, 1);
            $startdate = $startdateheb->getGregorianCalendar();
        }
        //prime the output variable
        $output = '<table border="1"><tr>';
        foreach ( $fullyear_column_titles as $key => $value ) {
            if ( isset( $value ) && !empty( $value ) ) {
                $output = $output . '<td>' . $value . '</td>';
            }
            //end if value
        }
        // end foreach title
        $output = $output . "</tr>";
        if ( $cadence == 'weekly' ) {
            $startdow = gmdate( 'l', strtotime( $startdate ) );
            if ( !isset( $iteration ) || $iteration == 0 || empty( $iteration ) ) {
                $iteration = 52;
            }
            if ( $startdow != $weekday ) {
                $startdate = gmdate( 'Y-m-d', strtotime( 'last ' . $weekday, strtotime( $startdate ) ) );
            }
            for ($i; $i <= $iteration; $i++) {
                $output = $output . "<tr>";
                foreach ( $fullyear_columns as $key => $value ) {
                    if ( isset( $value ) && !empty( $value ) ) {
                        $value = rtrim( $value, "]" );
                        $value = $value . " date={$startdate}]";
                        $output = $output . "<td>" . do_shortcode( $value ) . "</td>";
                    }
                    // end if $value isn't empty
                }
                // end foreach item in columns
                $output = $output . "</tr>";
                $startdate = gmdate( 'Y-m-d', strtotime( $startdate . " +7 days" ) );
            }
            // end for each iteration loop
        } elseif ( $cadence == 'daily' ) {
            if ( !isset( $iteration ) || $iteration == 0 || empty( $iteration ) ) {
                $iteration = 365;
            }
            for ($i; $i <= $iteration; $i++) {
                $output = $output . "<tr>";
                foreach ( $fullyear_columns as $key => $value ) {
                    if ( isset( $value ) && !empty( $value ) ) {
                        $value = rtrim( $value, "]" );
                        $value = $value . " date={$startdate}]";
                        $output = $output . "<td>" . do_shortcode( $value ) . "</td>";
                    }
                    // end if $value isn't empty
                }
                // end foreach item in columns
                $output = $output . "</tr>";
                $startdate = gmdate( 'Y-m-d', strtotime( $startdate . " +1 day" ) );
            }
            // end for each iteration loop
        }
        // end if cadence is daily
        $output = $output . "</table>";
        return $output;
    } // end fullyear_handler

    function early_shabbat_1_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $output = early_shabbat( "[zman_early_shabbat_1]", $atts );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }

    function early_shabbat_2_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $output = early_shabbat( "[zman_early_shabbat_2]", $atts );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }

    function early_shabbat_3_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $output = early_shabbat( "[zman_early_shabbat_3]", $atts );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }

    function early_shabbat_4_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $output = early_shabbat( "[zman_early_shabbat_4]", $atts );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }

    function early_shabbat_5_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $output = early_shabbat( "[zman_early_shabbat_5]", $atts );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }

    function early_shabbat_6_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5"
        ) );
        $output = early_shabbat( "[zman_early_shabbat_6]", $atts );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }

    function early_shabbat_7_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $output = early_shabbat( "[zman_early_shabbat_7]", $atts );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }

    function early_shabbat_8_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $output = early_shabbat( "[zman_early_shabbat_8]", $atts );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }

    function early_shabbat_9_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $output = early_shabbat( "[zman_early_shabbat_9]", $atts );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }

    function early_shabbat_10_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $output = early_shabbat( "[zman_early_shabbat_10]", $atts );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }

    function early_shabbat(  $shortcode, $atts  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $option = $early = $reg = '';
        $checkdate = $atts['date'];
        $zmanargs = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            1
        );
        
        $theyear = $zmanargs['0'];
        $themonth = $zmanargs['1'];
        $theday = $zmanargs['2'];
        $getdate = gmdate( 'Y-m-d', strtotime( "{$theyear}-{$themonth}-{$theday}" ) );
        $getdateheb = Zmanim::jewishCalendar( Carbon::createFromDate( $theyear, $themonth, $theday ) );
        $hebyear = $getdateheb->getJewishYear();
        $hebmonth = $getdateheb->getJewishMonth();
        $hebday = $getdateheb->getJewishDayOfMonth();
        $engstartmo = get_option( 'wpkz_early_eng_start_month' );
        $engstartday = get_option( 'wpkz_early_eng_start_day' );
        $engendmo = get_option( 'wpkz_early_eng_end_month' );
        $engendday = get_option( 'wpkz_early_eng_end_day' );
        $hebstartmo = get_option( 'wpkz_early_heb_start_month' );
        $hebstartday = get_option( 'wpkz_early_heb_start_day' );
        $hebendmo = get_option( 'wpkz_early_heb_end_month' );
        $hebendday = get_option( 'wpkz_early_heb_end_day' );
        $plagtime = get_option( 'wpkz_early_plagtime' );
        $shkiatime = get_option( 'wpkz_early_shkiatime' );
        $earlydst = get_option( 'wpkz_early_dst' );
        $isearly = "invalid";
        if ( !empty( $engstartmo ) && !empty( $engstartday ) && !empty( $engendmo ) && !empty( $engendday ) ) {
            $engstartmo = substr( $engstartmo, 0, 2 );
            $engendmo = substr( $engendmo, 0, 2 );
            $startdate = gmdate( 'Y-m-d', strtotime( "{$theyear}-{$engstartmo}-{$engstartday}" ) );
            $enddate = gmdate( 'Y-m-d', strtotime( "{$theyear}-{$engendmo}-{$engendday}" ) );
            if ( $getdate >= $startdate && $getdate <= $enddate && $isearly != "reg" ) {
                $isearly = "early";
            } else {
                $isearly = "reg";
            }
        }
        if ( !empty( $hebstartmo ) && !empty( $hebstartday ) && !empty( $hebendmo ) && !empty( $hebendday ) ) {
            $format = Zmanim::format();
            $hebstartmo = substr( $hebstartmo, 0, 2 );
            $hebendmo = substr( $hebendmo, 0, 2 );
            $hebstartdate = Zmanim::jewishCalendar( $hebyear, $hebstartmo, $hebstartday );
            if ( $hebendmo >= 7 ) {
                $hebyear++;
            }
            $hebenddate = Zmanim::jewishCalendar( $hebyear, $hebendmo, $hebendday );
            //convert hebdate to engdate
            $gregstart = $hebstartdate->getGregorianCalendar();
            $gregstart = gmdate( 'Y-m-d', strtotime( $gregstart ) );
            $gregend = $hebenddate->getGregorianCalendar();
            $gregend = gmdate( 'Y-m-d', strtotime( $gregend ) );
            if ( $getdate >= $gregstart && $getdate <= $gregend && $isearly != "reg" ) {
                $isearly = "early";
            } else {
                $isearly = "reg";
            }
        }
        if ( !empty( $plagtime ) ) {
            $plagtime = gmdate( 'Y-m-d H:i', strtotime( "{$getdate} {$plagtime}" ) );
            $plagshortcode = "[zman_plag date=\"{$getdate}\" dateformat=\"Y-m-d H:i\"]";
            $getplag = do_shortcode( $plagshortcode );
            $getdateplagtime = gmdate( 'Y-m-d H:i', strtotime( $getplag ) );
            if ( $plagtime <= $getdateplagtime && $isearly != "reg" ) {
                $isearly = "early";
            } else {
                $isearly = "reg";
            }
        }
        if ( !empty( $shkiatime ) ) {
            $shkiatime = gmdate( 'Y-m-d H:i', strtotime( "{$getdate} {$shkiatime}" ) );
            $shkiashortcode = "[zman_sunset date=\"{$getdate}\" dateformat=\"Y-m-d H:i\"]";
            $getshkia = do_shortcode( $shkiashortcode );
            $getdateshkiatime = gmdate( 'Y-m-d H:i', strtotime( $getshkia ) );
            if ( $shkiatime <= $getdateshkiatime && $isearly != "reg" ) {
                $isearly = "early";
            } else {
                $isearly = "reg";
            }
        }
        if ( !empty( $earlydst ) ) {
            $dststart = gmdate( 'Y-m-d', strtotime( "second Sunday of Mar " . $theyear . "" ) );
            $dstend = gmdate( 'Y-m-d', strtotime( "first Sunday of Nov " . $theyear . "" ) );
            if ( $getdate >= $dststart && $getdate <= $dstend && $isearly != "reg" ) {
                $isearly = "early";
            } else {
                $isearly = "reg";
            }
        }
        //isearly date range is valid. Process each of the shortcodes
        if ( $isearly != "invalid" ) {
            if ( $shortcode == "[zman_early_shabbat_1]" ) {
                $early = get_option( 'wpkz_early_1' );
                $reg = get_option( 'wpkz_reg_1' );
            }
            if ( $shortcode == "[zman_early_shabbat_2]" ) {
                $early = get_option( 'wpkz_early_2' );
                $reg = get_option( 'wpkz_reg_2' );
            }
            if ( $shortcode == "[zman_early_shabbat_3]" ) {
                $early = get_option( 'wpkz_early_3' );
                $reg = get_option( 'wpkz_reg_3' );
            }
            if ( $shortcode == "[zman_early_shabbat_4]" ) {
                $early = get_option( 'wpkz_early_4' );
                $reg = get_option( 'wpkz_reg_4' );
            }
            if ( $shortcode == "[zman_early_shabbat_5]" ) {
                $early = get_option( 'wpkz_early_5' );
                $reg = get_option( 'wpkz_reg_5' );
            }
            if ( $shortcode == "[zman_early_shabbat_6]" ) {
                $early = get_option( 'wpkz_early_6' );
                $reg = get_option( 'wpkz_reg_6' );
            }
            if ( $shortcode == "[zman_early_shabbat_7]" ) {
                $early = get_option( 'wpkz_early_7' );
                $reg = get_option( 'wpkz_reg_7' );
            }
            if ( $shortcode == "[zman_early_shabbat_8]" ) {
                $early = get_option( 'wpkz_early_8' );      
                $reg = get_option( 'wpkz_reg_8' );
            }
            if ( $shortcode == "[zman_early_shabbat_9]" ) {
                $early = get_option( 'wpkz_early_9' );
                $reg = get_option( 'wpkz_reg_9' );
            }
            if ( $shortcode == "[zman_early_shabbat_10]" ) {
                $early = get_option( 'wpkz_early_10' );
                $reg = get_option( 'wpkz_reg_10' );
            }
            if ( empty( $early ) && empty( $reg ) ) {
                return '';
            }
            if ( !empty( $early ) && $isearly == "early" ) {
                $output = explode_early( $early );
            } elseif ( !empty( $reg ) && $isearly == "reg" ) {
                $output = explode_early( $reg );
            } //end pick early or reg output and resolve shortcodes
        } //end if early is not "invalid"
        
        return $output;
    } //end early_shabbat_handler

    function secondary_zmanim_1_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $output = secondary_zmanim( "[zman_secondary_zmanim_1]", $atts );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }

    function secondary_zmanim_2_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $output = secondary_zmanim( "[zman_secondary_zmanim_2]", $atts );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }

    function secondary_zmanim_3_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $output = secondary_zmanim( "[zman_secondary_zmanim_3]", $atts );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }

    function secondary_zmanim_4_handler(  $atts = []  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $output = secondary_zmanim( "[zman_secondary_zmanim_4]", $atts );
        if ($atts['round'] == 'up' || $atts['round'] == 'down' || $atts['round'] == 'both') {
            $output = zmanim_round( $output, $atts['round'], $atts['roundvalue'] );
        }
        return $output;
    }

    function secondary_zmanim(  $shortcode, $atts  ) {
        $atts = wp_parse_args( $atts, array(
            "date"       => 'today',
            "offset"     => 0,
            "dateformat" => "g:i a",
            "lang"       => "english",
            "round"      => "none",
            "roundvalue"      => "5",
        ) );
        $option = $secondary = $reg = '';
        $checkdate = $atts['date'];
        $zmanargs = zmanim_wp_getzmanim(
            $atts['date'],
            $atts['offset'],
            $atts['dateformat'],
            $atts['lang'],
            $option,
            1
        );

        $theyear = $zmanargs['0'];
        $themonth = $zmanargs['1'];
        $theday = $zmanargs['2'];
        $getdate = gmdate( 'Y-m-d', strtotime( "{$theyear}-{$themonth}-{$theday}" ) );
        $getdateheb = Zmanim::jewishCalendar( Carbon::createFromDate( $theyear, $themonth, $theday ) );
        $hebyear = $getdateheb->getJewishYear();
        $hebmonth = $getdateheb->getJewishMonth();
        $hebday = $getdateheb->getJewishDayOfMonth();
        $engstartmo = get_option( 'wpkz_second_eng_start_month' );
        $engstartday = get_option( 'wpkz_second_eng_start_day' );
        $engendmo = get_option( 'wpkz_second_eng_end_month' );
        $engendday = get_option( 'wpkz_second_eng_end_day' );
        $hebstartmo = get_option( 'wpkz_second_heb_start_month' );
        $hebstartday = get_option( 'wpkz_second_heb_start_day' );
        $hebendmo = get_option( 'wpkz_second_heb_end_month' );
        $hebendday = get_option( 'wpkz_second_heb_end_day' );
        $plagtime = get_option( 'wpkz_second_plagtime' );
        $shkiatime = get_option( 'wpkz_second_shkiatime' );
        $seconddst = get_option( 'wpkz_second_dst' );
        $issecondary = "invalid";
        if ( !empty( $engstartmo ) && !empty( $engstartday ) && !empty( $engendmo ) && !empty( $engendday ) ) {
            $engstartmo = substr( $engstartmo, 0, 2 );
            $engendmo = substr( $engendmo, 0, 2 );
            $startdate = gmdate( 'Y-m-d', strtotime( "{$theyear}-{$engstartmo}-{$engstartday}" ) );
            $enddate = gmdate( 'Y-m-d', strtotime( "{$theyear}-{$engendmo}-{$engendday}" ) );
            if ( $getdate >= $startdate && $getdate <= $enddate && $issecondary != "reg" ) {
                $issecondary = "secondary";
            } else {
                $issecondary = "reg";
            }
        }
        if ( !empty( $hebstartmo ) && !empty( $hebstartday ) && !empty( $hebendmo ) && !empty( $hebendday ) ) {
            $format = Zmanim::format();
            $hebstartmo = substr( $hebstartmo, 0, 2 );
            $hebendmo = substr( $hebendmo, 0, 2 );
            $hebstartdate = Zmanim::jewishCalendar( $hebyear, $hebstartmo, $hebstartday );
            if ( $hebendmo >= 7 ) {
                $hebyear++;
            }
            $hebenddate = Zmanim::jewishCalendar( $hebyear, $hebendmo, $hebendday );
            $gregstart = $hebstartdate->getGregorianCalendar();
            $gregstart = gmdate( 'Y-m-d', strtotime( $gregstart ) );
            $gregend = $hebenddate->getGregorianCalendar();
            $gregend = gmdate( 'Y-m-d', strtotime( $gregend ) );
            if ( $getdate >= $gregstart && $getdate <= $gregend && $issecondary != "reg" ) {
                $issecondary = "secondary";
            } else {
                $issecondary = "reg";
            }
        }
        if ( !empty( $plagtime ) ) {
            $plagtime = gmdate( 'Y-m-d H:i', strtotime( "{$getdate} {$plagtime}" ) );
            $plagshortcode = "[zman_plag date=\"{$getdate}\" dateformat=\"Y-m-d H:i\"]";
            $getplag = do_shortcode( $plagshortcode );
            $getdateplagtime = gmdate( 'Y-m-d H:i', strtotime( $getplag ) );
            if ( $plagtime <= $getdateplagtime && $issecondary != "reg" ) {
                $issecondary = "secondary";
            } else {
                $issecondary = "reg";
            }
        }
        if ( !empty( $shkiatime ) ) {
            $shkiatime = gmdate( 'Y-m-d H:i', strtotime( "{$getdate} {$shkiatime}" ) );
            $shkiashortcode = "[zman_sunset date=\"{$getdate}\" dateformat=\"Y-m-d H:i\"]";
            $getshkia = do_shortcode( $shkiashortcode );
            $getdateshkiatime = gmdate( 'Y-m-d H:i', strtotime( $getshkia ) );
            if ( $shkiatime <= $getdateshkiatime && $issecondary != "reg" ) {
                $issecondary = "secondary";
            } else {
                $issecondary = "reg";
            }
        }
        if ( !empty( $seconddst ) ) {
            $dststart = gmdate( 'Y-m-d', strtotime( "second Sunday of Mar " . $theyear . "" ) );
            $dstend = gmdate( 'Y-m-d', strtotime( "first Sunday of Nov " . $theyear . "" ) );
            if ( $getdate >= $dststart && $getdate <= $dstend && $issecondary != "reg" ) {
                $issecondary = "secondary";
            } else {
                $issecondary = "reg";
            }
        }
        if ( $issecondary != "invalid" ) {
            if ( $shortcode == "[zman_secondary_zmanim_1]" ) {
                $secondary = get_option( 'wpkz_second_1' );
                $reg = get_option( 'wpkz_second_reg_1' );
            }
            if ( $shortcode == "[zman_secondary_zmanim_2]" ) {
                $secondary = get_option( 'wpkz_second_2' );
                $reg = get_option( 'wpkz_second_reg_2' );
            }
            if ( $shortcode == "[zman_secondary_zmanim_3]" ) {
                $secondary = get_option( 'wpkz_second_3' );
                $reg = get_option( 'wpkz_second_reg_3' );
            }
            if ( $shortcode == "[zman_secondary_zmanim_4]" ) {
                $secondary = get_option( 'wpkz_second_4' );
                $reg = get_option( 'wpkz_second_reg_4' );
            }
            if ( empty( $secondary ) && empty( $reg ) ) {
                return '';
            }
            if ( !empty( $secondary ) && $issecondary == "secondary" ) {
                $output = explode_secondary( $secondary );
            } elseif ( !empty( $reg ) && $issecondary == "reg" ) {
                $output = explode_secondary( $reg );
            }
        }

        return $output;
    } //end secondary_zmanim

    function explode_secondary(  $secondvar  ) {
        $order = array();
        $shortcode_pattern = '(\\[[^\\]]+\\])';
        preg_match_all( $shortcode_pattern, $secondvar, $matches );
        $betweens = preg_split( $shortcode_pattern, $secondvar );
        foreach ( $matches['0'] as $match ) {
            if ( !empty( $match ) ) {
                $matchpos = strpos( $secondvar, $match );
                $shortmatch = do_shortcode( $match );
                $order[$matchpos] = $shortmatch;
            }
        }
        foreach ( $betweens as $between ) {
            if ( !empty( $between ) ) {
                $betweenpos = strpos( $secondvar, $between );
                $order[$betweenpos] = $between;
            }
        }
        $output = '';
        ksort( $order );
        foreach ( $order as $x => $x_value ) {
            $output = $output . $x_value;
        }
        return $output;
    } //end function explode_secondary

    function explode_early(  $earlyvar  ) {
        $order = array();
        $shortcode_pattern = '(\\[[^\\]]+\\])';
        preg_match_all( $shortcode_pattern, $earlyvar, $matches );
        $betweens = preg_split( $shortcode_pattern, $earlyvar );
        foreach ( $matches['0'] as $match ) {
            if ( !empty( $match ) ) {
                $matchpos = strpos( $earlyvar, $match );
                $shortmatch = do_shortcode( $match );
                $order[$matchpos] = $shortmatch;
            }
        }
        foreach ( $betweens as $between ) {
            if ( !empty( $between ) ) {
                $betweenpos = strpos( $earlyvar, $between );
                $order[$betweenpos] = $between;
            }
        }
        $output = '';
        ksort( $order );
        foreach ( $order as $x => $x_value ) {
            $output = $output . $x_value;
        }
        return $output;
    } //end function explode_early
// } # end function zmanim_wp_init