/*
Language: Stan
Description: The Stan probabilistic programming language
Author: Sean Pinkney <sean.pinkney@gmail.com>
Website: http://mc-stan.org/
Category: scientific
*/
function stan(hljs) {
    const regex = hljs.regex;
    // variable names cannot conflict with block identifiers
    const BLOCKS = [
        'functions',
        'model',
        'data',
        'parameters',
        'quantities',
        'transformed',
        'generated'
    ];
    const STATEMENTS = [
        'for',
        'in',
        'if',
        'else',
        'while',
        'break',
        'continue',
        'return'
    ];
    const TYPES = [
        'array',
        'tuple',
        'complex',
        'int',
        'real',
        'vector',
        'complex_vector',
        'ordered',
        'positive_ordered',
        'simplex',
        'unit_vector',
        'row_vector',
        'complex_row_vector',
        'matrix',
        'complex_matrix',
        'cholesky_factor_corr|10',
        'cholesky_factor_cov|10',
        'corr_matrix|10',
        'cov_matrix|10',
        'void'
    ];
    // to get the functions list
    // clone the [stan-docs repo](https://github.com/stan-dev/docs)
    // then cd into it and run this bash script https://gist.github.com/joshgoebel/dcd33f82d4059a907c986049893843cf
    //
    // the output files are
    // distributions_quoted.txt
    // functions_quoted.txt
    const FUNCTIONS = [
        'abs',
        'acos',
        'acosh',
        'add_diag',
        'algebra_solver',
        'algebra_solver_newton',
        'append_array',
        'append_col',
        'append_row',
        'asin',
        'asinh',
        'atan',
        'atan2',
        'atanh',
        'bessel_first_kind',
        'bessel_second_kind',
        'binary_log_loss',
        'block',
        'cbrt',
        'ceil',
        'chol2inv',
        'cholesky_decompose',
        'choose',
        'col',
        'cols',
        'columns_dot_product',
        'columns_dot_self',
        'complex_schur_decompose',
        'complex_schur_decompose_t',
        'complex_schur_decompose_u',
        'conj',
        'cos',
        'cosh',
        'cov_exp_quad',
        'crossprod',
        'csr_extract',
        'csr_extract_u',
        'csr_extract_v',
        'csr_extract_w',
        'csr_matrix_times_vector',
        'csr_to_dense_matrix',
        'cumulative_sum',
        'dae',
        'dae_tol',
        'determinant',
        'diag_matrix',
        'diagonal',
        'diag_post_multiply',
        'diag_pre_multiply',
        'digamma',
        'dims',
        'distance',
        'dot_product',
        'dot_self',
        'eigendecompose',
        'eigendecompose_sym',
        'eigenvalues',
        'eigenvalues_sym',
        'eigenvectors',
        'eigenvectors_sym',
        'erf',
        'erfc',
        'exp',
        'exp2',
        'expm1',
        'falling_factorial',
        'fdim',
        'fft',
        'fft2',
        'floor',
        'fma',
        'fmax',
        'fmin',
        'fmod',
        'gamma_p',
        'gamma_q',
        'generalized_inverse',
        'get_imag',
        'get_real',
        'head',
        'hmm_hidden_state_prob',
        'hmm_marginal',
        'hypot',
        'identity_matrix',
        'inc_beta',
        'integrate_1d',
        'integrate_ode',
        'integrate_ode_adams',
        'integrate_ode_bdf',
        'integrate_ode_rk45',
        'int_step',
        'inv',
        'inv_cloglog',
        'inv_erfc',
        'inverse',
        'inverse_spd',
        'inv_fft',
        'inv_fft2',
        'inv_inc_beta',
        'inv_logit',
        'inv_Phi',
        'inv_sqrt',
        'inv_square',
        'is_inf',
        'is_nan',
        'lambert_w0',
        'lambert_wm1',
        'lbeta',
        'lchoose',
        'ldexp',
        'lgamma',
        'linspaced_array',
        'linspaced_int_array',
        'linspaced_row_vector',
        'linspaced_vector',
        'lmgamma',
        'lmultiply',
        'log',
        'log1m',
        'log1m_exp',
        'log1m_inv_logit',
        'log1p',
        'log1p_exp',
        'log_determinant',
        'log_diff_exp',
        'log_falling_factorial',
        'log_inv_logit',
        'log_inv_logit_diff',
        'logit',
        'log_mix',
        'log_modified_bessel_first_kind',
        'log_rising_factorial',
        'log_softmax',
        'log_sum_exp',
        'machine_precision',
        'map_rect',
        'matrix_exp',
        'matrix_exp_multiply',
        'matrix_power',
        'max',
        'mdivide_left_spd',
        'mdivide_left_tri_low',
        'mdivide_right_spd',
        'mdivide_right_tri_low',
        'mean',
        'min',
        'modified_bessel_first_kind',
        'modified_bessel_second_kind',
        'multiply_lower_tri_self_transpose',
        'negative_infinity',
        'norm',
        'norm1',
        'norm2',
        'not_a_number',
        'num_elements',
        'ode_adams',
        'ode_adams_tol',
        'ode_adjoint_tol_ctl',
        'ode_bdf',
        'ode_bdf_tol',
        'ode_ckrk',
        'ode_ckrk_tol',
        'ode_rk45',
        'ode_rk45_tol',
        'one_hot_array',
        'one_hot_int_array',
        'one_hot_row_vector',
        'one_hot_vector',
        'ones_array',
        'ones_int_array',
        'ones_row_vector',
        'ones_vector',
        'owens_t',
        'Phi',
        'Phi_approx',
        'polar',
        'positive_infinity',
        'pow',
        'print',
        'prod',
        'proj',
        'qr',
        'qr_Q',
        'qr_R',
        'qr_thin',
        'qr_thin_Q',
        'qr_thin_R',
        'quad_form',
        'quad_form_diag',
        'quad_form_sym',
        'quantile',
        'rank',
        'reduce_sum',
        'reject',
        'rep_array',
        'rep_matrix',
        'rep_row_vector',
        'rep_vector',
        'reverse',
        'rising_factorial',
        'round',
        'row',
        'rows',
        'rows_dot_product',
        'rows_dot_self',
        'scale_matrix_exp_multiply',
        'sd',
        'segment',
        'sin',
        'singular_values',
        'sinh',
        'size',
        'softmax',
        'sort_asc',
        'sort_desc',
        'sort_indices_asc',
        'sort_indices_desc',
        'sqrt',
        'square',
        'squared_distance',
        'step',
        'sub_col',
        'sub_row',
        'sum',
        'svd',
        'svd_U',
        'svd_V',
        'symmetrize_from_lower_tri',
        'tail',
        'tan',
        'tanh',
        'target',
        'tcrossprod',
        'tgamma',
        'to_array_1d',
        'to_array_2d',
        'to_complex',
        'to_int',
        'to_matrix',
        'to_row_vector',
        'to_vector',
        'trace',
        'trace_gen_quad_form',
        'trace_quad_form',
        'trigamma',
        'trunc',
        'uniform_simplex',
        'variance',
        'zeros_array',
        'zeros_int_array',
        'zeros_row_vector'
    ];
    const DISTRIBUTIONS = [
        'bernoulli',
        'bernoulli_logit',
        'bernoulli_logit_glm',
        'beta',
        'beta_binomial',
        'beta_proportion',
        'binomial',
        'binomial_logit',
        'categorical',
        'categorical_logit',
        'categorical_logit_glm',
        'cauchy',
        'chi_square',
        'dirichlet',
        'discrete_range',
        'double_exponential',
        'exp_mod_normal',
        'exponential',
        'frechet',
        'gamma',
        'gaussian_dlm_obs',
        'gumbel',
        'hmm_latent',
        'hypergeometric',
        'inv_chi_square',
        'inv_gamma',
        'inv_wishart',
        'inv_wishart_cholesky',
        'lkj_corr',
        'lkj_corr_cholesky',
        'logistic',
        'loglogistic',
        'lognormal',
        'multi_gp',
        'multi_gp_cholesky',
        'multinomial',
        'multinomial_logit',
        'multi_normal',
        'multi_normal_cholesky',
        'multi_normal_prec',
        'multi_student_cholesky_t',
        'multi_student_t',
        'multi_student_t_cholesky',
        'neg_binomial',
        'neg_binomial_2',
        'neg_binomial_2_log',
        'neg_binomial_2_log_glm',
        'normal',
        'normal_id_glm',
        'ordered_logistic',
        'ordered_logistic_glm',
        'ordered_probit',
        'pareto',
        'pareto_type_2',
        'poisson',
        'poisson_log',
        'poisson_log_glm',
        'rayleigh',
        'scaled_inv_chi_square',
        'skew_double_exponential',
        'skew_normal',
        'std_normal',
        'std_normal_log',
        'student_t',
        'uniform',
        'von_mises',
        'weibull',
        'wiener',
        'wishart',
        'wishart_cholesky'
    ];
    const BLOCK_COMMENT = hljs.COMMENT(/\/\*/, /\*\//, {
        relevance: 0,
        contains: [
            {
                scope: 'doctag',
                match: /@(return|param)/
            }
        ]
    });
    const INCLUDE = {
        scope: 'meta',
        begin: /#include\b/,
        end: /$/,
        contains: [
            {
                match: /[a-z][a-z-._]+/,
                scope: 'string'
            },
            hljs.C_LINE_COMMENT_MODE
        ]
    };
    const RANGE_CONSTRAINTS = [
        "lower",
        "upper",
        "offset",
        "multiplier"
    ];
    return {
        name: 'Stan',
        aliases: ['stanfuncs'],
        keywords: {
            $pattern: hljs.IDENT_RE,
            title: BLOCKS,
            type: TYPES,
            keyword: STATEMENTS,
            built_in: FUNCTIONS
        },
        contains: [
            hljs.C_LINE_COMMENT_MODE,
            INCLUDE,
            hljs.HASH_COMMENT_MODE,
            BLOCK_COMMENT,
            {
                scope: 'built_in',
                match: /\s(pi|e|sqrt2|log2|log10)(?=\()/,
                relevance: 0
            },
            {
                match: regex.concat(/[<,]\s*/, regex.either(...RANGE_CONSTRAINTS), /\s*=/),
                keywords: RANGE_CONSTRAINTS
            },
            {
                scope: 'keyword',
                match: /\btarget(?=\s*\+=)/,
            },
            {
                // highlights the 'T' in T[,] for only Stan language distributrions
                match: [
                    /~\s*/,
                    regex.either(...DISTRIBUTIONS),
                    /(?:\(\))/,
                    /\s*T(?=\s*\[)/
                ],
                scope: {
                    2: "built_in",
                    4: "keyword"
                }
            },
            {
                // highlights distributions that end with special endings
                scope: 'built_in',
                keywords: DISTRIBUTIONS,
                begin: regex.concat(/\w*/, regex.either(...DISTRIBUTIONS), /(_lpdf|_lupdf|_lpmf|_cdf|_lcdf|_lccdf|_qf)(?=\s*[\(.*\)])/)
            },
            {
                // highlights distributions after ~
                begin: [
                    /~/,
                    /\s*/,
                    regex.concat(regex.either(...DISTRIBUTIONS), /(?=\s*[\(.*\)])/)
                ],
                scope: { 3: "built_in" }
            },
            {
                // highlights user defined distributions after ~
                begin: [
                    /~/,
                    /\s*\w+(?=\s*[\(.*\)])/,
                    '(?!.*/\b(' + regex.either(...DISTRIBUTIONS) + ')\b)'
                ],
                scope: { 2: "title.function" }
            },
            {
                // highlights user defined distributions with special endings
                scope: 'title.function',
                begin: /\w*(_lpdf|_lupdf|_lpmf|_cdf|_lcdf|_lccdf|_qf)(?=\s*[\(.*\)])/
            },
            {
                scope: 'number',
                match: regex.concat(
                // Comes from @RunDevelopment accessed 11/29/2021 at
                // https://github.com/PrismJS/prism/blob/c53ad2e65b7193ab4f03a1797506a54bbb33d5a2/components/prism-stan.js#L56
                // start of big noncapture group which
                // 1. gets numbers that are by themselves
                // 2. numbers that are separated by _
                // 3. numbers that are separted by .
                /(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)/, 
                // grabs scientific notation
                // grabs complex numbers with i
                /(?:[eE][+-]?\d+(?:_\d+)*)?i?(?!\w)/),
                relevance: 0
            },
            {
                scope: 'string',
                begin: /"/,
                end: /"/
            }
        ]
    };
}
export { stan as default };
//# sourceMappingURL=stan.js.map