text:
# This file is auto-generated by AWSMetadata.jl
using AWS
using AWS.AWSServices: databrew
using AWS.Compat
using AWS.UUIDs

"""
    BatchDeleteRecipeVersion()

Deletes one or more versions of a recipe at a time.

# Required Parameters
- `RecipeVersions`: An array of version identifiers to be deleted.
- `name`: The name of the recipe to be modified.

"""
batch_delete_recipe_version(RecipeVersions, name; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/recipes/$(name)/batchDeleteRecipeVersion", Dict{String, Any}("RecipeVersions"=>RecipeVersions); aws_config=aws_config)
batch_delete_recipe_version(RecipeVersions, name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/recipes/$(name)/batchDeleteRecipeVersion", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("RecipeVersions"=>RecipeVersions), args)); aws_config=aws_config)

"""
    CreateDataset()

Creates a new AWS Glue DataBrew dataset for this AWS account.

# Required Parameters
- `Input`:
- `Name`: The name of the dataset to be created.

# Optional Parameters
- `FormatOptions`:
- `Tags`: Metadata tags to apply to this dataset.
"""
create_dataset(Input, Name; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/datasets", Dict{String, Any}("Input"=>Input, "Name"=>Name); aws_config=aws_config)
create_dataset(Input, Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/datasets", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Input"=>Input, "Name"=>Name), args)); aws_config=aws_config)

"""
    CreateProfileJob()

Creates a new job to profile an AWS Glue DataBrew dataset that exists in the current AWS account.

# Required Parameters
- `DatasetName`: The name of the dataset that this job is to act upon.
- `Name`: The name of the job to be created.
- `OutputLocation`:
- `RoleArn`: The Amazon Resource Name (ARN) of the AWS Identity and Access Management (IAM) role to be assumed for this request.

# Optional Parameters
- `EncryptionKeyArn`: The Amazon Resource Name (ARN) of an encryption key that is used to protect the job.
- `EncryptionMode`: The encryption mode for the job, which can be one of the following:    SSE-KMS - para>SSE-KMS - server-side encryption with AWS KMS-managed keys.    SSE-S3 - Server-side encryption with keys managed by Amazon S3.
- `LogSubscription`: A value that enables or disables Amazon CloudWatch logging for the current AWS account. If logging is enabled, CloudWatch writes one log stream for each job run.
- `MaxCapacity`: The maximum number of nodes that DataBrew can use when the job processes data.
- `MaxRetries`: The maximum number of times to retry the job after a job run fails.
- `Tags`: Metadata tags to apply to this job.
- `Timeout`: The job's timeout in minutes. A job that attempts to run longer than this timeout period ends with a status of TIMEOUT.
"""
create_profile_job(DatasetName, Name, OutputLocation, RoleArn; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/profileJobs", Dict{String, Any}("DatasetName"=>DatasetName, "Name"=>Name, "OutputLocation"=>OutputLocation, "RoleArn"=>RoleArn); aws_config=aws_config)
create_profile_job(DatasetName, Name, OutputLocation, RoleArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/profileJobs", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("DatasetName"=>DatasetName, "Name"=>Name, "OutputLocation"=>OutputLocation, "RoleArn"=>RoleArn), args)); aws_config=aws_config)

"""
    CreateProject()

Creates a new AWS Glue DataBrew project in the current AWS account.

# Required Parameters
- `DatasetName`: The name of the dataset to associate this project with.
- `Name`: A unique name for the new project.
- `RecipeName`: The name of an existing recipe to associate with the project.
- `RoleArn`: The Amazon Resource Name (ARN) of the AWS Identity and Access Management (IAM) role to be assumed for this request.

# Optional Parameters
- `Sample`:
- `Tags`: Metadata tags to apply to this project.
"""
create_project(DatasetName, Name, RecipeName, RoleArn; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/projects", Dict{String, Any}("DatasetName"=>DatasetName, "Name"=>Name, "RecipeName"=>RecipeName, "RoleArn"=>RoleArn); aws_config=aws_config)
create_project(DatasetName, Name, RecipeName, RoleArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/projects", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("DatasetName"=>DatasetName, "Name"=>Name, "RecipeName"=>RecipeName, "RoleArn"=>RoleArn), args)); aws_config=aws_config)

"""
    CreateRecipe()

Creates a new AWS Glue DataBrew recipe for the current AWS account.

# Required Parameters
- `Name`: A unique name for the recipe.
- `Steps`: An array containing the steps to be performed by the recipe. Each recipe step consists of one recipe action and (optionally) an array of condition expressions.

# Optional Parameters
- `Description`: A description for the recipe.
- `Tags`: Metadata tags to apply to this recipe.
"""
create_recipe(Name, Steps; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/recipes", Dict{String, Any}("Name"=>Name, "Steps"=>Steps); aws_config=aws_config)
create_recipe(Name, Steps, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/recipes", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Name"=>Name, "Steps"=>Steps), args)); aws_config=aws_config)

"""
    CreateRecipeJob()

Creates a new job for an existing AWS Glue DataBrew recipe in the current AWS account. You can create a standalone job using either a project, or a combination of a recipe and a dataset.

# Required Parameters
- `Name`: A unique name for the job.
- `Outputs`: One or more artifacts that represent the output from running the job.
- `RoleArn`: The Amazon Resource Name (ARN) of the AWS Identity and Access Management (IAM) role to be assumed for this request.

# Optional Parameters
- `DatasetName`: The name of the dataset that this job processes.
- `EncryptionKeyArn`: The Amazon Resource Name (ARN) of an encryption key that is used to protect the job.
- `EncryptionMode`: The encryption mode for the job, which can be one of the following:    SSE-KMS - Server-side encryption with AWS KMS-managed keys.    SSE-S3 - Server-side encryption with keys managed by Amazon S3.
- `LogSubscription`: A value that enables or disables Amazon CloudWatch logging for the current AWS account. If logging is enabled, CloudWatch writes one log stream for each job run.
- `MaxCapacity`: The maximum number of nodes that DataBrew can consume when the job processes data.
- `MaxRetries`: The maximum number of times to retry the job after a job run fails.
- `ProjectName`: Either the name of an existing project, or a combination of a recipe and a dataset to associate with the recipe.
- `RecipeReference`:
- `Tags`: Metadata tags to apply to this job dataset.
- `Timeout`: The job's timeout in minutes. A job that attempts to run longer than this timeout period ends with a status of TIMEOUT.
"""
create_recipe_job(Name, Outputs, RoleArn; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/recipeJobs", Dict{String, Any}("Name"=>Name, "Outputs"=>Outputs, "RoleArn"=>RoleArn); aws_config=aws_config)
create_recipe_job(Name, Outputs, RoleArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/recipeJobs", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Name"=>Name, "Outputs"=>Outputs, "RoleArn"=>RoleArn), args)); aws_config=aws_config)

"""
    CreateSchedule()

Creates a new schedule for one or more AWS Glue DataBrew jobs. Jobs can be run at a specific date and time, or at regular intervals.

# Required Parameters
- `CronExpression`: The date or dates and time or times, in cron format, when the jobs are to be run.
- `Name`: A unique name for the schedule.

# Optional Parameters
- `JobNames`: The name or names of one or more jobs to be run.
- `Tags`: Metadata tags to apply to this schedule.
"""
create_schedule(CronExpression, Name; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/schedules", Dict{String, Any}("CronExpression"=>CronExpression, "Name"=>Name); aws_config=aws_config)
create_schedule(CronExpression, Name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/schedules", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("CronExpression"=>CronExpression, "Name"=>Name), args)); aws_config=aws_config)

"""
    DeleteDataset()

Deletes a dataset from AWS Glue DataBrew.

# Required Parameters
- `name`: The name of the dataset to be deleted.

"""
delete_dataset(name; aws_config::AWSConfig=global_aws_config()) = databrew("DELETE", "/datasets/$(name)"; aws_config=aws_config)
delete_dataset(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("DELETE", "/datasets/$(name)", args; aws_config=aws_config)

"""
    DeleteJob()

Deletes the specified AWS Glue DataBrew job from the current AWS account. The job can be for a recipe or for a profile.

# Required Parameters
- `name`: The name of the job to be deleted.

"""
delete_job(name; aws_config::AWSConfig=global_aws_config()) = databrew("DELETE", "/jobs/$(name)"; aws_config=aws_config)
delete_job(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("DELETE", "/jobs/$(name)", args; aws_config=aws_config)

"""
    DeleteProject()

Deletes an existing AWS Glue DataBrew project from the current AWS account.

# Required Parameters
- `name`: The name of the project to be deleted.

"""
delete_project(name; aws_config::AWSConfig=global_aws_config()) = databrew("DELETE", "/projects/$(name)"; aws_config=aws_config)
delete_project(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("DELETE", "/projects/$(name)", args; aws_config=aws_config)

"""
    DeleteRecipeVersion()

Deletes a single version of an AWS Glue DataBrew recipe.

# Required Parameters
- `name`: The name of the recipe to be deleted.
- `recipeVersion`: The version of the recipe to be deleted.

"""
delete_recipe_version(name, recipeVersion; aws_config::AWSConfig=global_aws_config()) = databrew("DELETE", "/recipes/$(name)/recipeVersion/$(recipeVersion)"; aws_config=aws_config)
delete_recipe_version(name, recipeVersion, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("DELETE", "/recipes/$(name)/recipeVersion/$(recipeVersion)", args; aws_config=aws_config)

"""
    DeleteSchedule()

Deletes the specified AWS Glue DataBrew schedule from the current AWS account.

# Required Parameters
- `name`: The name of the schedule to be deleted.

"""
delete_schedule(name; aws_config::AWSConfig=global_aws_config()) = databrew("DELETE", "/schedules/$(name)"; aws_config=aws_config)
delete_schedule(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("DELETE", "/schedules/$(name)", args; aws_config=aws_config)

"""
    DescribeDataset()

Returns the definition of a specific AWS Glue DataBrew dataset that is in the current AWS account.

# Required Parameters
- `name`: The name of the dataset to be described.

"""
describe_dataset(name; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/datasets/$(name)"; aws_config=aws_config)
describe_dataset(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/datasets/$(name)", args; aws_config=aws_config)

"""
    DescribeJob()

Returns the definition of a specific AWS Glue DataBrew job that is in the current AWS account.

# Required Parameters
- `name`: The name of the job to be described.

"""
describe_job(name; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/jobs/$(name)"; aws_config=aws_config)
describe_job(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/jobs/$(name)", args; aws_config=aws_config)

"""
    DescribeProject()

Returns the definition of a specific AWS Glue DataBrew project that is in the current AWS account.

# Required Parameters
- `name`: The name of the project to be described.

"""
describe_project(name; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/projects/$(name)"; aws_config=aws_config)
describe_project(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/projects/$(name)", args; aws_config=aws_config)

"""
    DescribeRecipe()

Returns the definition of a specific AWS Glue DataBrew recipe that is in the current AWS account.

# Required Parameters
- `name`: The name of the recipe to be described.

# Optional Parameters
- `recipeVersion`: The recipe version identifier. If this parameter isn't specified, then the latest published version is returned.
"""
describe_recipe(name; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/recipes/$(name)"; aws_config=aws_config)
describe_recipe(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/recipes/$(name)", args; aws_config=aws_config)

"""
    DescribeSchedule()

Returns the definition of a specific AWS Glue DataBrew schedule that is in the current AWS account.

# Required Parameters
- `name`: The name of the schedule to be described.

"""
describe_schedule(name; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/schedules/$(name)"; aws_config=aws_config)
describe_schedule(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/schedules/$(name)", args; aws_config=aws_config)

"""
    ListDatasets()

Lists all of the AWS Glue DataBrew datasets for the current AWS account.

# Optional Parameters
- `maxResults`: The maximum number of results to return in this request.
- `nextToken`: A token generated by DataBrew that specifies where to continue pagination if a previous request was truncated. To get the next set of pages, pass in the NextToken value from the response object of the previous page call.
"""
list_datasets(; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/datasets"; aws_config=aws_config)
list_datasets(args::AbstractDict{String, Any}; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/datasets", args; aws_config=aws_config)

"""
    ListJobRuns()

Lists all of the previous runs of a particular AWS Glue DataBrew job in the current AWS account.

# Required Parameters
- `name`: The name of the job.

# Optional Parameters
- `maxResults`: The maximum number of results to return in this request.
- `nextToken`: A token generated by AWS Glue DataBrew that specifies where to continue pagination if a previous request was truncated. To get the next set of pages, pass in the NextToken value from the response object of the previous page call.
"""
list_job_runs(name; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/jobs/$(name)/jobRuns"; aws_config=aws_config)
list_job_runs(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/jobs/$(name)/jobRuns", args; aws_config=aws_config)

"""
    ListJobs()

Lists the AWS Glue DataBrew jobs in the current AWS account.

# Optional Parameters
- `datasetName`: The name of a dataset. Using this parameter indicates to return only those jobs that act on the specified dataset.
- `maxResults`: The maximum number of results to return in this request.
- `nextToken`: A token generated by DataBrew that specifies where to continue pagination if a previous request was truncated. To get the next set of pages, pass in the NextToken value from the response object of the previous page call.
- `projectName`: The name of a project. Using this parameter indicates to return only those jobs that are associated with the specified project.
"""
list_jobs(; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/jobs"; aws_config=aws_config)
list_jobs(args::AbstractDict{String, Any}; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/jobs", args; aws_config=aws_config)

"""
    ListProjects()

Lists all of the DataBrew projects in the current AWS account.

# Optional Parameters
- `maxResults`: The maximum number of results to return in this request.
- `nextToken`: A pagination token that can be used in a subsequent request.
"""
list_projects(; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/projects"; aws_config=aws_config)
list_projects(args::AbstractDict{String, Any}; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/projects", args; aws_config=aws_config)

"""
    ListRecipeVersions()

Lists all of the versions of a particular AWS Glue DataBrew recipe in the current AWS account.

# Required Parameters
- `name`: The name of the recipe for which to return version information.

# Optional Parameters
- `maxResults`: The maximum number of results to return in this request.
- `nextToken`: A pagination token that can be used in a subsequent request.
"""
list_recipe_versions(name; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/recipeVersions", Dict{String, Any}("name"=>name); aws_config=aws_config)
list_recipe_versions(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/recipeVersions", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("name"=>name), args)); aws_config=aws_config)

"""
    ListRecipes()

Lists all of the AWS Glue DataBrew recipes in the current AWS account.

# Optional Parameters
- `maxResults`: The maximum number of results to return in this request.
- `nextToken`: A pagination token that can be used in a subsequent request.
- `recipeVersion`: A version identifier. Using this parameter indicates to return only those recipes that have this version identifier.
"""
list_recipes(; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/recipes"; aws_config=aws_config)
list_recipes(args::AbstractDict{String, Any}; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/recipes", args; aws_config=aws_config)

"""
    ListSchedules()

Lists the AWS Glue DataBrew schedules in the current AWS account.

# Optional Parameters
- `jobName`: The name of the job that these schedules apply to.
- `maxResults`: The maximum number of results to return in this request.
- `nextToken`: A pagination token that can be used in a subsequent request.
"""
list_schedules(; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/schedules"; aws_config=aws_config)
list_schedules(args::AbstractDict{String, Any}; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/schedules", args; aws_config=aws_config)

"""
    ListTagsForResource()

Lists all the tags for an AWS Glue DataBrew resource.

# Required Parameters
- `ResourceArn`: The Amazon Resource Name (ARN) string that uniquely identifies the DataBrew resource.

"""
list_tags_for_resource(ResourceArn; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/tags/$(ResourceArn)"; aws_config=aws_config)
list_tags_for_resource(ResourceArn, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("GET", "/tags/$(ResourceArn)", args; aws_config=aws_config)

"""
    PublishRecipe()

Publishes a new major version of an AWS Glue DataBrew recipe that exists in the current AWS account.

# Required Parameters
- `name`: The name of the recipe to be published.

# Optional Parameters
- `Description`: A description of the recipe to be published, for this version of the recipe.
"""
publish_recipe(name; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/recipes/$(name)/publishRecipe"; aws_config=aws_config)
publish_recipe(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/recipes/$(name)/publishRecipe", args; aws_config=aws_config)

"""
    SendProjectSessionAction()

Performs a recipe step within an interactive AWS Glue DataBrew session that's currently open.

# Required Parameters
- `name`: The name of the project to apply the action to.

# Optional Parameters
- `ClientSessionId`: A unique identifier for an interactive session that's currently open and ready for work. The action will be performed on this session.
- `Preview`: Returns the result of the recipe step, without applying it. The result isn't added to the view frame stack.
- `RecipeStep`:
- `StepIndex`: The index from which to preview a step. This index is used to preview the result of steps that have already been applied, so that the resulting view frame is from earlier in the view frame stack.
- `ViewFrame`:
"""
send_project_session_action(name; aws_config::AWSConfig=global_aws_config()) = databrew("PUT", "/projects/$(name)/sendProjectSessionAction"; aws_config=aws_config)
send_project_session_action(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("PUT", "/projects/$(name)/sendProjectSessionAction", args; aws_config=aws_config)

"""
    StartJobRun()

Runs an AWS Glue DataBrew job that exists in the current AWS account.

# Required Parameters
- `name`: The name of the job to be run.

"""
start_job_run(name; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/jobs/$(name)/startJobRun"; aws_config=aws_config)
start_job_run(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/jobs/$(name)/startJobRun", args; aws_config=aws_config)

"""
    StartProjectSession()

Creates an interactive session, enabling you to manipulate an AWS Glue DataBrew project.

# Required Parameters
- `name`: The name of the project to act upon.

# Optional Parameters
- `AssumeControl`: A value that, if true, enables you to take control of a session, even if a different client is currently accessing the project.
"""
start_project_session(name; aws_config::AWSConfig=global_aws_config()) = databrew("PUT", "/projects/$(name)/startProjectSession"; aws_config=aws_config)
start_project_session(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("PUT", "/projects/$(name)/startProjectSession", args; aws_config=aws_config)

"""
    StopJobRun()

Stops the specified job from running in the current AWS account.

# Required Parameters
- `name`: The name of the job to be stopped.
- `runId`: The ID of the job run to be stopped.

"""
stop_job_run(name, runId; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/jobs/$(name)/jobRun/$(runId)/stopJobRun"; aws_config=aws_config)
stop_job_run(name, runId, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/jobs/$(name)/jobRun/$(runId)/stopJobRun", args; aws_config=aws_config)

"""
    TagResource()

Adds metadata tags to an AWS Glue DataBrew resource, such as a dataset, job, project, or recipe.

# Required Parameters
- `ResourceArn`: The DataBrew resource to which tags should be added. The value for this parameter is an Amazon Resource Name (ARN). For DataBrew, you can tag a dataset, a job, a project, or a recipe.
- `Tags`: One or more tags to be assigned to the resource.

"""
tag_resource(ResourceArn, Tags; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/tags/$(ResourceArn)", Dict{String, Any}("Tags"=>Tags); aws_config=aws_config)
tag_resource(ResourceArn, Tags, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("POST", "/tags/$(ResourceArn)", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Tags"=>Tags), args)); aws_config=aws_config)

"""
    UntagResource()

Removes metadata tags from an AWS Glue DataBrew resource.

# Required Parameters
- `ResourceArn`: An DataBrew resource from which you want to remove a tag or tags. The value for this parameter is an Amazon Resource Name (ARN).
- `tagKeys`: The tag keys (names) of one or more tags to be removed.

"""
untag_resource(ResourceArn, tagKeys; aws_config::AWSConfig=global_aws_config()) = databrew("DELETE", "/tags/$(ResourceArn)", Dict{String, Any}("tagKeys"=>tagKeys); aws_config=aws_config)
untag_resource(ResourceArn, tagKeys, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("DELETE", "/tags/$(ResourceArn)", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("tagKeys"=>tagKeys), args)); aws_config=aws_config)

"""
    UpdateDataset()

Modifies the definition of an existing AWS Glue DataBrew dataset in the current AWS account.

# Required Parameters
- `Input`:
- `name`: The name of the dataset to be updated.

# Optional Parameters
- `FormatOptions`:
"""
update_dataset(Input, name; aws_config::AWSConfig=global_aws_config()) = databrew("PUT", "/datasets/$(name)", Dict{String, Any}("Input"=>Input); aws_config=aws_config)
update_dataset(Input, name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("PUT", "/datasets/$(name)", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Input"=>Input), args)); aws_config=aws_config)

"""
    UpdateProfileJob()

Modifies the definition of an existing AWS Glue DataBrew job in the current AWS account.

# Required Parameters
- `OutputLocation`:
- `RoleArn`: The Amazon Resource Name (ARN) of the AWS Identity and Access Management (IAM) role to be assumed for this request.
- `name`: The name of the job to be updated.

# Optional Parameters
- `EncryptionKeyArn`: The Amazon Resource Name (ARN) of an encryption key that is used to protect the job.
- `EncryptionMode`: The encryption mode for the job, which can be one of the following:    SSE-KMS - Server-side encryption with AWS KMS-managed keys.    SSE-S3 - Server-side encryption with keys managed by Amazon S3.
- `LogSubscription`: A value that enables or disables Amazon CloudWatch logging for the current AWS account. If logging is enabled, CloudWatch writes one log stream for each job run.
- `MaxCapacity`: The maximum number of nodes that DataBrew can use when the job processes data.
- `MaxRetries`: The maximum number of times to retry the job after a job run fails.
- `Timeout`: The job's timeout in minutes. A job that attempts to run longer than this timeout period ends with a status of TIMEOUT.
"""
update_profile_job(OutputLocation, RoleArn, name; aws_config::AWSConfig=global_aws_config()) = databrew("PUT", "/profileJobs/$(name)", Dict{String, Any}("OutputLocation"=>OutputLocation, "RoleArn"=>RoleArn); aws_config=aws_config)
update_profile_job(OutputLocation, RoleArn, name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("PUT", "/profileJobs/$(name)", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("OutputLocation"=>OutputLocation, "RoleArn"=>RoleArn), args)); aws_config=aws_config)

"""
    UpdateProject()

Modifies the definition of an existing AWS Glue DataBrew project in the current AWS account.

# Required Parameters
- `RoleArn`: The Amazon Resource Name (ARN) of the IAM role to be assumed for this request.
- `name`: The name of the project to be updated.

# Optional Parameters
- `Sample`:
"""
update_project(RoleArn, name; aws_config::AWSConfig=global_aws_config()) = databrew("PUT", "/projects/$(name)", Dict{String, Any}("RoleArn"=>RoleArn); aws_config=aws_config)
update_project(RoleArn, name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("PUT", "/projects/$(name)", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("RoleArn"=>RoleArn), args)); aws_config=aws_config)

"""
    UpdateRecipe()

Modifies the definition of the latest working version of an AWS Glue DataBrew recipe in the current AWS account.

# Required Parameters
- `name`: The name of the recipe to be updated.

# Optional Parameters
- `Description`: A description of the recipe.
- `Steps`: One or more steps to be performed by the recipe. Each step consists of an action, and the conditions under which the action should succeed.
"""
update_recipe(name; aws_config::AWSConfig=global_aws_config()) = databrew("PUT", "/recipes/$(name)"; aws_config=aws_config)
update_recipe(name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("PUT", "/recipes/$(name)", args; aws_config=aws_config)

"""
    UpdateRecipeJob()

Modifies the definition of an existing AWS Glue DataBrew recipe job in the current AWS account.

# Required Parameters
- `Outputs`: One or more artifacts that represent the output from running the job.
- `RoleArn`: The Amazon Resource Name (ARN) of the AWS Identity and Access Management (IAM) role to be assumed for this request.
- `name`: The name of the job to update.

# Optional Parameters
- `EncryptionKeyArn`: The Amazon Resource Name (ARN) of an encryption key that is used to protect the job.
- `EncryptionMode`: The encryption mode for the job, which can be one of the following:    SSE-KMS - Server-side encryption with AWS KMS-managed keys.    SSE-S3 - Server-side encryption with keys managed by Amazon S3.
- `LogSubscription`: A value that enables or disables Amazon CloudWatch logging for the current AWS account. If logging is enabled, CloudWatch writes one log stream for each job run.
- `MaxCapacity`: The maximum number of nodes that DataBrew can consume when the job processes data.
- `MaxRetries`: The maximum number of times to retry the job after a job run fails.
- `Timeout`: The job's timeout in minutes. A job that attempts to run longer than this timeout period ends with a status of TIMEOUT.
"""
update_recipe_job(Outputs, RoleArn, name; aws_config::AWSConfig=global_aws_config()) = databrew("PUT", "/recipeJobs/$(name)", Dict{String, Any}("Outputs"=>Outputs, "RoleArn"=>RoleArn); aws_config=aws_config)
update_recipe_job(Outputs, RoleArn, name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("PUT", "/recipeJobs/$(name)", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Outputs"=>Outputs, "RoleArn"=>RoleArn), args)); aws_config=aws_config)

"""
    UpdateSchedule()

Modifies the definition of an existing AWS Glue DataBrew schedule in the current AWS account.

# Required Parameters
- `CronExpression`: The date or dates and time or times, in cron format, when the jobs are to be run.
- `name`: The name of the schedule to update.

# Optional Parameters
- `JobNames`: The name or names of one or more jobs to be run for this schedule.
"""
update_schedule(CronExpression, name; aws_config::AWSConfig=global_aws_config()) = databrew("PUT", "/schedules/$(name)", Dict{String, Any}("CronExpression"=>CronExpression); aws_config=aws_config)
update_schedule(CronExpression, name, args::AbstractDict{String, <:Any}; aws_config::AWSConfig=global_aws_config()) = databrew("PUT", "/schedules/$(name)", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("CronExpression"=>CronExpression), args)); aws_config=aws_config)


text:
module SnoopCompile

using Serialization, OrderedCollections

export timesum  # @snoopi and @snoopc are exported from their files of definition

const anonrex = r"#{1,2}\d+#{1,2}\d+"         # detect anonymous functions
const kwrex = r"^#kw##(.*)$|^#([^#]*)##kw$"   # detect keyword-supplying functions
const kwbodyrex = r"^##(\w[^#]*)#\d+"         # detect keyword body methods
const genrex = r"^##s\d+#\d+$"                # detect generators for @generated functions
const innerrex = r"^#[^#]+#\d+"               # detect inner functions

if VERSION >= v"1.2.0-DEV.573"
    include("snoopi.jl")
    include("parcel_snoopi.jl")
end
include("snoopc.jl")
include("parcel_snoopc.jl")

include("write.jl")
include("bot.jl")

end # module

ext: jl


text:
# this writes to disk the items that Octave needs to do II or BII estimation
include("dataprep.jl")
mZs, sZs, beta, sErrors = CreatePreprocessItems()
writedlm("beta", beta)
writedlm("mZs", mZs)
writedlm("sZs", sZs)
writedlm("sErrors", sErrors)
using MXNet
items = mx.load_checkpoint("dsge30040", 20)
alpha1 = copy(items[2][:fullyconnected0_bias])
alpha2 = copy(items[2][:fullyconnected1_bias])
alpha3 = copy(items[2][:fullyconnected2_bias])
beta1 = copy(items[2][:fullyconnected0_weight])
beta2 = copy(items[2][:fullyconnected1_weight])
beta3 = copy(items[2][:fullyconnected2_weight])
writedlm("alpha1", alpha1)
writedlm("alpha2", alpha2)
writedlm("alpha3", alpha3)
writedlm("beta1", beta1)
writedlm("beta2", beta2)
writedlm("beta3", beta3)


text:
using Random
using StableRNGs
using ReinforcementLearning
using AbstractAlgebra

include("groebner.jl")

export GroebnerEnvParams,
    GroebnerEnv,
    rand_env,
    buchberger_test,
    eval_model

# /(x::GFElem{Int64}, y::GFElem{Int64}) = x * inv(y)

mutable struct GroebnerEnvParams
    nvars::Int
    maxdeg::Int
    npols::Int
    G
end

struct MatrixSpace{T}
    size::Tuple{Int, Int}
end

Base.in(x, s::MatrixSpace{T}) where T = (x isa Array{T,2}) && size(x) == s.size
Base.rand(s::MatrixSpace{T}) where T = rand(T, size)

Base.show(io::IO, params::GroebnerEnvParams) = print(
    io,
    join(["$p=$(getfield(params, p))" for p in fieldnames(GroebnerEnvParams)], ",")
)

mutable struct GroebnerEnv{N, R<:AbstractRNG} <: AbstractEnv
    params::GroebnerEnvParams
    G::Array{Array{term{N}, 1}, 1}
    P::Vector{NTuple{2, Array{term{N}, 1}}}
    reward::Int
    done::Bool
    t::Int
    rng::R
end

function copy(e::GroebnerEnv)
    return GroebnerEnv(e.params, deepcopy(e.G), deepcopy(e.P), e.reward, e.done, e.t, e.rng)
end

function rand_env(p::GroebnerEnvParams)
    # G = [[term(1., ntuple(x -> rand(1:p.maxdeg), p.nvars)),
    #           term(1., ntuple(x -> rand(1:p.maxdeg), p.nvars))]
    #          for _ in 1:p.npols]
    # P = [(G[i], G[j])
    #          for i in 1:length(G)
    #          for j in i:length(G)]
    # return GroebnerEnv(p, G, P, 0, false, 0, Random.GLOBAL_RNG)
    degree = rand(2:p.maxdeg)
    deg1 = rand(1:(degree - 1))
    deg2 = degree - deg1
    degrees1 = filter(x -> sum(x) != 0, tuples_lt(p.nvars, degree))
    degrees2 = filter(x -> sum(x) != 0, tuples_lt(p.nvars, degree))

    G = [[term(Field(rand(1:1)), tuple(rand(degrees1)...)),
              term(Field(rand(1:1)), tuple(rand(degrees2)...))]
             for _ in 1:p.npols]
    sort!.(G; lt = lt)
    P = [(G[i], G[j])
             for i in     1:length(G)
             for j in (i+1):length(G)]
    p.G = Base.copy(G)
    env = GroebnerEnv(p, G, P, 0, false, 0, Random.GLOBAL_RNG)
    RLBase.reset!(env)
    return env
end

p(env::GroebnerEnv) = length(env.P)

RLBase.action_space(env::GroebnerEnv) = env.done ? ([1]) : (1:p(env))
RLBase.state_space(env::GroebnerEnv) = MatrixSpace{Int}((p(env),
                                                    4*env.params.nvars))
RLBase.reward(env::GroebnerEnv) = env.reward
RLBase.is_terminated(env::GroebnerEnv) = env.done
# RLBase.state(env::GroebnerEnv) = !env.done ?
#     reduce(hcat, [vcat(reduce(vcat, collect.(getproperty.(f,:a))),
#                        reduce(vcat, collect.(getproperty.(g,:a)))
#                       )
#                   for (f, g) in env.P]) : Array{Int}(undef, 0, 0)

RLBase.state(env::GroebnerEnv) = !env.done ?
    reduce(hcat, [S(f, g) == [] ? repeat([0], 2*env.params.nvars) :
                                  reduce(vcat, collect.(getproperty.(binom(S(f, g)), :a)))
                  for (f, g) in env.P]
           ) : Array{Int}(undef, 0, 0)

function RLBase.reset!(env::GroebnerEnv{N, R}) where {N, R}
    env.done = false
    env.reward = 0
    # env.t = 0
    # env.G = [[term(1., ntuple(x -> rand(1:env.params.maxdeg), env.params.nvars)),
    #           term(1., ntuple(x -> rand(1:env.params.maxdeg), env.params.nvars))]
    #          for _ in 1:env.params.npols]
    # env.P = [(env.G[i], env.G[j])
    #          for i in 1:length(env.G)
    #          for j in i:length(env.G)]
    # env.t = 0

    degree = rand(2:env.params.maxdeg)
    deg1 = rand(1:(degree - 1))
    deg2 = degree - deg1
    degrees1 = filter(x -> sum(x) != 0, tuples_lt(env.params.nvars, degree))
    degrees2 = filter(x -> sum(x) != 0, tuples_lt(env.params.nvars, degree))

    env.G = [[term(Field(rand(1:1)), tuple(rand(degrees1)...)),
              term(Field(rand(1:1)), tuple(rand(degrees2)...))]
             for _ in 1:env.params.npols]
    sort!.(env.G; lt = lt)
    env.P = [(env.G[i], env.G[j])
             for i in     1:length(env.G)
             for j in (i+1):length(env.G)]
    env.t = 0

    # env.t = 0
    # env.reward = 0
    # env.done = false

    # env.G = Base.copy(env.params.G)
    # sort!.(env.G, lt=lt)
    # env.P = [(env.G[i], env.G[j])
    #          for i in     1:length(env.G)
    #          for j in (i+1):length(env.G)]
    # nothing
end

function buchberger_test(env::GroebnerEnv, model, gamma = 1.0)
    i = 0
    reward = 0
    actions = Int64[]
    rewards = Int64[]
    while length(env.P) > 0
        a = model(env)
        push!(actions, a)
        env(a)
        i = i+1
        reward = reward + env.reward
        push!(rewards, env.reward)
    end
    return i, reward, actions, rewards
end

function eval_model(env::GroebnerEnv, model; iters = 100, gamma=1.0)
    reductions = 0
    reward = 0
    rewards::Vector{Float32} = []
    sizes::Vector{Int64} = []
    times::Vector{Float32} = []

    RLBase.reset!(env)
    buchberger_test(env, model, gamma)
    for _ in 1:iters
        RLBase.reset!(env)
        stats = @timed buchberger_test(env, model, gamma)
        (i, r) = stats.value
        time = stats.time
        @assert is_groebner_basis(env.G)
        reductions = reductions + i
        reward = reward + r
        push!(rewards, r)
        push!(sizes, length(env.G))
        push!(times, time)
    end
    return Base.:/(reductions, iters), Base.:/(reward, iters), 1000*Base.:/(sum(times), iters), rewards
end

function (env::GroebnerEnv{N, R})(a) where {N, R}
    @assert a in 1:p(env)
    (f, g) = env.P[a]
    deleteat!(env.P, a)
    f = filter(t -> t.l != 0, f)
    g = filter(t -> t.l != 0, g)
    r, reward = mdiv_count(S(f, g), env.G)
    if length(r) == 1
        append!(r, [term{N}(Field(0), ntuple(x->0, N))])
    end

    sort!(r; lt = lt)

    reward = -1*(1 + reward) # +1 from S-poly construction
    if r != []
        update!(env.P, env.G, r)
        push!(env.G, r)
    end
    if length(env.P) == 0
        env.done = true
    end
    env.reward = reward
    env.t = env.t + 1
    if env.t > 10_000
        env.done = true
        env.reward = -1_000_000
        println("Stopped after 10_000 selections")
    end
end

mutable struct EasyEnv <: AbstractEnv
    state :: Array{Array{Float32, 1}, 1}
    reward::Float32
    done::Bool
    t::Int
end

RLBase.action_space(env::EasyEnv) = env.done ? ([1]) : (1:length(env.state))
RLBase.state_space(env::EasyEnv) = [1, 2, 3]

RLBase.reward(env::EasyEnv) = env.reward
RLBase.is_terminated(env::EasyEnv) = env.done
RLBase.state(env::EasyEnv) = hcat(env.state...)
function RLBase.reset!(env::EasyEnv)
    env.done = false
    env.t = 0
    n = rand(1:100)
    env.state = Vector{Float32}[10*rand(20) for _ in 1:n]
    env.reward = 0
end

function (env::EasyEnv)(a)
    @assert a in 1:length(env.state)

    env.reward = sum(env.state[a])

    env.state = Vector{Float32}[10*rand(20) for _ in 1:(length(env.state) - 1)]

    if length(env.state) == 0
        env.done = true
    end
    env.t += 1
end

# struct CartPoleEnvParams{T}
#     gravity::T
#     masscart::T
#     masspole::T
#     totalmass::T
#     halflength::T
#     polemasslength::T
#     forcemag::T
#     dt::T
#     thetathreshold::T
#     xthreshold::T
#     max_steps::Int
# end

# Base.show(io::IO, params::CartPoleEnvParams) = print(
#     io,
#     join(["$p=$(getfield(params, p))" for p in fieldnames(CartPoleEnvParams)], ","),
# )

# mutable struct CartPoleEnv{T,R<:AbstractRNG} <: AbstractEnv
#     params::CartPoleEnvParams{T}
#     state::Array{T,1}
#     action::Int
#     done::Bool
#     t::Int
#     rng::R
# end

# """
#     CartPoleEnv(;kwargs...)
# # Keyword arguments
# - `T = Float64`
# - `gravity = T(9.8)`
# - `masscart = T(1.0)`
# - `masspole = T(0.1)`
# - `halflength = T(0.5)`
# - `forcemag = T(10.0)`
# - `max_steps = 200`
# - 'dt = 0.02'
# - `rng = Random.GLOBAL_RNG`
# """
# function CartPoleEnv(;
#     T = Float64,
#     gravity = 9.8,
#     masscart = 1.0,
#     masspole = 0.1,
#     halflength = 0.5,
#     forcemag = 10.0,
#     max_steps = 200,
#     dt = 0.02,
#     rng = Random.GLOBAL_RNG,
# )
#     params = CartPoleEnvParams{T}(
#         gravity,
#         masscart,
#         masspole,
#         masscart + masspole,
#         halflength,
#         masspole * halflength,
#         forcemag,
#         dt,
#         Base.:/(2 * 12 * π , 360),
#         2.4,
#         max_steps,
#     )
#     high = cp = CartPoleEnv(params, zeros(T, 4), 2, false, 0, rng)
#     reset!(cp)
#     cp
# end

# CartPoleEnv{T}(; kwargs...) where {T} = CartPoleEnv(; T = T, kwargs...)

# function RLBase.reset!(env::CartPoleEnv{T}) where {T<:Number}
#     env.state[:] = T(0.1) * rand(env.rng, T, 4) .- T(0.05)
#     env.t = 0
#     env.action = 2
#     env.done = false
#     nothing
# end

# RLBase.action_space(env::CartPoleEnv) = Base.OneTo(2)

# RLBase.state_space(env::CartPoleEnv{T}) where {T} = Space(
#     ClosedInterval{T}[
#         (-2*env.params.xthreshold)..(2*env.params.xthreshold),
#         -1e38..1e38,
#         (-2*env.params.thetathreshold)..(2*env.params.thetathreshold),
#         -1e38..1e38,
#     ],
# )

# RLBase.reward(env::CartPoleEnv{T}) where {T} = env.done ? zero(T) : one(T)
# RLBase.is_terminated(env::CartPoleEnv) = env.done
# RLBase.state(env::CartPoleEnv) = env.state

# function (env::CartPoleEnv)(a)
#     @assert a in (1, 2)
#     env.action = a
#     env.t += 1
#     force = a == 2 ? env.params.forcemag : -env.params.forcemag
#     x, xdot, theta, thetadot = env.state
#     costheta = cos(theta)
#     sintheta = sin(theta)
#     tmp = (force + env.params.polemasslength * thetadot^2 * sintheta) / env.params.totalmass
#     thetaacc =
#         (env.params.gravity * sintheta - costheta * tmp) / (
#             env.params.halflength *
#             (4 / 3 - env.params.masspole * costheta^2 / env.params.totalmass)
#         )
#     xacc = tmp - env.params.polemasslength * thetaacc * costheta / env.params.totalmass
#     env.state[1] += env.params.dt * xdot
#     env.state[2] += env.params.dt * xacc
#     env.state[3] += env.params.dt * thetadot
#     env.state[4] += env.params.dt * thetaacc
#     env.done =
#         abs(env.state[1]) > env.params.xthreshold ||
#         abs(env.state[3]) > env.params.thetathreshold ||
#         env.t > env.params.max_steps
#     nothing
# end

# Random.seed!(env::CartPoleEnv, seed) = Random.seed!(env.rng, seed)


text:
function molar_to_weight(value,x,MW)
    return value/LinearAlgebra.dot(MW,x)*1000.0
end

function weight_to_molar(value,x,MW)
    return (value*LinearAlgebra.dot(MW,x))/1000.0
end

#transformation of arbitrary molar units to the SI units
@inline function _transform_v(v,mw,x)
    return 1.0*v
end

@inline function _transform_v(v::Unitful.Quantity{<:Real, Unitful.𝐋^3*Unitful.𝐍^-1},mw,x)
    return Unitful.ustrip(u"m^3/mol"(v))
end

@inline function _transform_v(v::Unitful.Quantity{<:Real, Unitful.𝐋^-3*Unitful.𝐍^1},mw,x)
    return 1/Unitful.ustrip(u"mol/m^3"(v))
end

@inline function _transform_v(v::Unitful.Quantity{<:Real, Unitful.𝐋^-3*Unitful.𝐌^1},mw,x)
    return weight_to_molar(1/Unitful.ustrip(u"kg/m^3"(v)),mw,x)
end

@inline function _transform_v(v::Unitful.Quantity{<:Real, Unitful.𝐋^3*Unitful.𝐌^-1},mw,x)
    return weight_to_molar(Unitful.ustrip(u"m^3/kg"(v)),mw,x)
end

@inline function _transform_T(T)
    return 1.0*T
end

@inline function _transform_T(T::TT) where TT <: Unitful.Temperature
        return Unitful.ustrip(u"K"(T))
end

function _transformVT(V,T,mw,x)
    return (_transform_v(V,mw,x),_transform_T(T))
end

@inline function _transform_P(P)
    return 1.0*P
end

@inline function _transform_P(P::TT) where TT <: Unitful.Pressure
        return Unitful.ustrip(u"Pa"(P))
end

###
### fraction utilities
###
function normalizefrac!(x)
    summ = sum(x)
    for i = 1:length(x)
        x[i] /=summ
    end
    x
end

function normalizefrac(x)
    summ = sum(x)
    y = copy(x)
    for i = 1:length(x)
        y[i] /=summ
    end
    return y
end
function randfrac(N::Integer)
    x = rand(N)
    return x ./sum(x)
end
function randfrac(x0::Array)
    length(x0)>0 && begin
    x = similar(x0)
    zerox = 0.0
    for i = 1:length(x0)
     x[i]=ifelse(x0[i]==zerox,zerox,rand())
    end
    x /= sum(x)
    return x
end
end

function randpurefrac(x0::Array)
    x = zeros(length(x0))
    i = rand(LinearIndices(findall(x->x!=0.0,x0)))
    x[i] = 1.0
    return x
end

function solve_cubic_eq(coeff1::T,coeff2::T,coeff3::T,coeff4::T) where T<:Real
    # Cubic equation solver for complex polynomial (degree=3)
    # http://en.wikipedia.org/wiki/Cubic_function   Lagrange's method

    a1  =  1 / coeff4
    E1  = -coeff3*a1
    E2  =  coeff2*a1
    E3  = -coeff1*a1
    s0  =  E1
    E12 =  E1*E1
    A   =  2*E1*E12 - 9*E1*E2 + 27*E3 # = s1^3 + s2^3
    B   =  E12 - 3*E2                 # = s1 s2
    # quadratic equation: z^2 - Az + B^3=0  where roots are equal to s1^3 and s2^3
    Δ = sqrt(A*A - 4*B*B*B)
    if real(conj(A)*Δ)>=0 # scalar product to decide the sign yielding bigger magnitude
        s1 = exp(log(0.5 * (A + Δ)) * third)
    else
        s1 = exp(log(0.5 * (A - Δ)) * third)
    end
    if s1 == 0
        s2 = s1
    else
        s2 = B / s1
    end
    zeta1 = complex(-0.5, sqrt(T(3.0))*0.5)
    zeta2 = conj(zeta1)
    return third*(s0 + s1 + s2), third*(s0 + s1*zeta2 + s2*zeta1), third*(s0 + s1*zeta1 + s2*zeta2)
end


text:
# MIT License
# Copyright (c) 2017: Xavier Gandibleux, Anthony Przybylski, Gauthier Soleilhac, and contributors.
mutable struct problem
    psize::Int #Number of variables
    p1::Vector{Int} #Objective vector 1
    p2::Vector{Int} #Objective vector 1
    w::Vector{Int} #Weights vector
    c::Int #Knapsack Capacity
    C0::Vector{Int} #Indices of variables always set to 0
    C1::Vector{Int} #Indices of variables always set to 1
    ω::Int #Weight of items always picked
    min_profit_1::Int #Guaranteed profit on first objective by picking the items in C1
    min_profit_2::Int #Guaranteed profit on second objective by picking the items in C1
    eff1::Vector{Float64} #Variables efficiency wrt objective 1
    eff2::Vector{Float64} #Variables efficiency wrt objective 2
    variables::Vector{Int} #Remaining variables of the problem after reduction
    ub_z1_i0::Vector{Int} #Upper bound on z1 for each variable i fixed to 0
    ub_z1_i1::Vector{Int} #Upper bound on z1 for each variable i fixed to 1
    ub_z2_i0::Vector{Int} #Upper bound on z2 for each variable i fixed to 0
    ub_z2_i1::Vector{Int} #Upper bound on z2 for each variable i fixed to 1
end

Base.copy(pb::problem) = problem(pb.psize, pb.p1, pb.p2, pb.w, pb.c, copy(pb.C0), copy(pb.C1),
    pb.ω, pb.min_profit_1, pb.min_profit_2, pb.eff1, pb.eff2, copy(pb.variables), pb.ub_z1_i0,
    pb.ub_z1_i1, pb.ub_z2_i0, pb.ub_z2_i1)

#Printer
Base.show(io::IO, pb::problem) =
    print(io, "Bi-objective Knapsack Problem with $(size(pb))($(pb.psize)) variables :\n
p1=$(pb.p1)\np2=$(pb.p2)\nw=$(pb.w)\nc=$(pb.c)\nC0=$(pb.C0)\nC1=$(pb.C1)\n")

#Constructor
problem(p1, p2, w, c) = problem(length(w), p1, p2, w, c, Int[], Int[], 0, 0, 0, p1 ./ w, p2 ./ w, collect(1:length(w)), zeros(Int, length(w)), zeros(Int, length(w)), zeros(Int, length(w)), zeros(Int, length(w)))

size(pb::problem)::Int = length(pb.variables)
variables(pb::problem)::Vector{Int} = pb.variables

function reduce_problem!(pb::problem, output::Bool)

    n = size(pb)

    #Compute Pref(vi) and Dom(vi) ∀i = 1..n
    Pref = [Int[] for i = 1:size(pb)]
    Dom = [Int[] for i = 1:size(pb)]
    for i = 1:n-1, j = i+1:n
        i1, i2, j1, j2 = pb.p1[i], pb.p2[i], pb.p1[j], pb.p2[j]
        wi, wj = pb.w[i], pb.w[j]

        if ((i1 > j1 && i2 >= j2) || (i1 >= j1 && i2 > j2)) && wi <= wj
            push!(Pref[j], i)
            push!(Dom[i], j)
        end
        if ((j1 > i1 && j2 >= i2) || (j1 >= i1 && j2 > i2)) && wj <= wi
            push!(Pref[i], j)
            push!(Dom[j], i)
        end
    end

    #Compute LB and UB : bounds on the cardinality of an efficient solution
    c = pb.c

    w = sort(pb.w, rev=true)
    sum_weight = 0
    LB = 0
    while LB < n && w[LB+1] + sum_weight <= c
        LB += 1
        sum_weight += w[LB]
    end

    reverse!(w)
    sum_weight = 0
    UB = 0
    while UB < n && w[UB+1] + sum_weight <= c
        UB += 1
        sum_weight += w[UB]
    end

    #Compute C0 and C1 : sets of variables always set to 0 / 1 in an efficient solution
    C0 = pb.C0
    C1 = pb.C1

    for i = 1:n
        if length(Pref[i]) >= UB
            push!(C0, i)
        elseif n - length(Dom[i]) <= LB
            push!(C1, i)
        elseif !isempty(Pref[i]) && sum(j -> pb.w[j], Pref[i]) + pb.w[i] > c
            push!(C0, i)
        elseif sum(j -> j ∉ Dom[i] ? pb.w[j] : 0 , 1:n) <= c
            push!(C1, i)
        end
    end

    if !isempty(C1)
        pb.ω = sum(i -> pb.w[i], C1)
        pb.min_profit_1 = sum(i -> pb.p1[i], C1)
        pb.min_profit_2 = sum(i -> pb.p2[i], C1)
    end
    deleteat!(pb.variables, sort(union(C0,C1)))

    if output && pb.psize != size(pb)
        println("Global reduction from $(pb.psize) to $(size(pb)) variables")
    end

    calculate_upper_bounds!(pb)

    nothing
end

function calculate_upper_bounds!(pb::problem)
    vars = sort(variables(pb), by = v -> pb.eff1[v], rev=true)
    for i=1:size(pb)
        #Calculate relaxation with variable i set to 0
        w = pb.ω
        ub = pb.min_profit_1
        j = 1
        while j <= size(pb) && (i==j || w + pb.w[vars[j]] <= pb.c)
            v = vars[j]
            if j != i
                w += pb.w[v]
                ub += pb.p1[v]
            end
            j += 1
        end
        if j <= size(pb)
            v = vars[j]
            cleft = pb.c - w
            if j+1 == i || j == size(pb)
                if j+2 <= size(pb)
                    U0 = ub + floor(Int, cleft * pb.p1[vars[j+2]]/pb.w[vars[j+2]])
                else
                    U0 = ub
                end
            else
                U0 = ub + floor(Int, cleft * pb.p1[vars[j+1]]/pb.w[vars[j+1]])
            end
            if j-1==i || j == 1
                if j-2 >= 1
                    U1 = ub + floor(Int, pb.p1[v] - (pb.w[v] - cleft)*(pb.p1[vars[j-2]]/pb.w[vars[j-2]]))
                else
                    U1 = 0
                end
            else
                U1 = ub + floor(Int, pb.p1[v] - (pb.w[v] - cleft)*(pb.p1[vars[j-1]]/pb.w[vars[j-1]]))
            end
        ub = max(U0,U1)
        end

        pb.ub_z1_i0[vars[i]] = ub
    end
    for i=1:size(pb)
        #Calculate relaxation with variable i set to 1
        w = pb.ω + pb.w[vars[i]]
        ub = pb.min_profit_1 + pb.p1[vars[i]]
        j = 1
        while j <= size(pb) && (i==j || w + pb.w[vars[j]] <= pb.c)
            v = vars[j]
            if j != i
                w += pb.w[v]
                ub += pb.p1[v]
            end
            j += 1
        end
        if j <= size(pb)
            v = vars[j]
            cleft = pb.c - w
            if j+1 == i || j == size(pb)
                if j+2 <= size(pb)
                    U0 = ub + floor(Int, cleft * pb.p1[vars[j+2]]/pb.w[vars[j+2]])
                else
                    U0 = ub
                end
            else
                U0 = ub + floor(Int, cleft * pb.p1[vars[j+1]]/pb.w[vars[j+1]])
            end
            if j-1==i || j == 1
                if j-2 >= 1
                    U1 = ub + floor(Int, pb.p1[v] - (pb.w[v] - cleft)*(pb.p1[vars[j-2]]/pb.w[vars[j-2]]))
                else
                    U1 = 0
                end
            else
                U1 = ub + floor(Int, pb.p1[v] - (pb.w[v] - cleft)*(pb.p1[vars[j-1]]/pb.w[vars[j-1]]))
            end
            ub = max(U0,U1)
        end
        pb.ub_z1_i1[vars[i]] = ub
    end

    vars = sort(variables(pb), by = v -> pb.eff2[v], rev=true)

    for i=1:size(pb)
        #Calculate relaxation with variable i set to 0
        w = pb.ω
        ub = pb.min_profit_2
        j = 1 ; v = vars[j]
        j = 1
        while j <= size(pb) && (i==j || w + pb.w[vars[j]] <= pb.c)
            v = vars[j]
            if j != i
                w += pb.w[v]
                ub += pb.p2[v]
            end
            j += 1
        end
        if j <= size(pb)
            v = vars[j]
            cleft = pb.c - w
            if j+1 == i || j == size(pb)
                if j+2 <= size(pb)
                    U0 = ub + floor(Int, cleft * pb.p2[vars[j+2]]/pb.w[vars[j+2]])
                else
                    U0 = ub
                end
            else
                U0 = ub + floor(Int, cleft * pb.p2[vars[j+1]]/pb.w[vars[j+1]])
            end
            if j-1==i || j == 1
                if j-2 >= 1
                    U1 = ub + floor(Int, pb.p2[v] - (pb.w[v] - cleft)*(pb.p2[vars[j-2]]/pb.w[vars[j-2]]))
                else
                    U1 = 0
                end
            else
                U1 = ub + floor(Int, pb.p2[v] - (pb.w[v] - cleft)*(pb.p2[vars[j-1]]/pb.w[vars[j-1]]))
            end
            ub = max(U0,U1)
        end
        pb.ub_z2_i0[vars[i]] = ub
    end
    for i=1:size(pb)
        #Calculate relaxation with variable i set to 1
        w = pb.ω + pb.w[vars[i]]
        ub = pb.min_profit_2 + pb.p2[vars[i]]
        j = 1
        while j <= size(pb) && (i==j || w + pb.w[vars[j]] <= pb.c)
            v = vars[j]
            if j != i
                w += pb.w[v]
                ub += pb.p2[v]
            end
            j += 1
        end
        if j <= size(pb)
            v = vars[j]
            cleft = pb.c - w
            if j+1 == i || j == size(pb)
                if j+2 <= size(pb)
                    U0 = ub + floor(Int, cleft * pb.p2[vars[j+2]]/pb.w[vars[j+2]])
                else
                    U0 = ub
                end
            else
                U0 = ub + floor(Int, cleft * pb.p2[vars[j+1]]/pb.w[vars[j+1]])
            end
            if j-1==i || j == 1
                if j-2 >= 1
                    U1 = ub + floor(Int, pb.p2[v] - (pb.w[v] - cleft)*(pb.p2[vars[j-2]]/pb.w[vars[j-2]]))
                else
                    U1 = 0
                end
            else
                U1 = ub + floor(Int, pb.p2[v] - (pb.w[v] - cleft)*(pb.p2[vars[j-1]]/pb.w[vars[j-1]]))
            end
            ub = max(U0,U1)
        end
        pb.ub_z2_i1[vars[i]] = ub
    end
end

max_stars_repo_name: vOptSolver/vOptSpecific

max_issues_repo_name: vOptSolver/vOptSpecific

max_forks_repo_name: vOptSolver/vOptSpecific


text:
int_rules_4_1_9 = @theory begin

    #= ::Subsection::Closed:: =#
    #= 4.1.9*trig^m*(a+b*sin^n+c*sin^(2*n))^p =#
    @apply_utils Antiderivative((~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~(p'), ~x) => (1 / (4 ^ ~p * (~c) ^ ~p)) * Antiderivative((~b + 2 * ~c * sin(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~n], ~x) && (EqQ(~n2, 2 * ~n) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegerQ(~p)))
    @apply_utils Antiderivative((~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~(p'), ~x) => (1 / (4 ^ ~p * (~c) ^ ~p)) * Antiderivative((~b + 2 * ~c * cos(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~n], ~x) && (EqQ(~n2, 2 * ~n) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegerQ(~p)))
    @apply_utils Antiderivative((~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~p, ~x) => ((~a + ~b * sin(~d + ~e * ~x) ^ ~n + ~c * sin(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p / (~b + 2 * ~c * sin(~d + ~e * ~x) ^ ~n) ^ (2 * ~p)) * Antiderivative(u * (~b + 2 * ~c * sin(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~n, ~p], ~x) && (EqQ(~n2, 2 * ~n) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && Not(IntegerQ(~p))))
    @apply_utils Antiderivative((~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~p, ~x) => ((~a + ~b * cos(~d + ~e * ~x) ^ ~n + ~c * cos(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p / (~b + 2 * ~c * cos(~d + ~e * ~x) ^ ~n) ^ (2 * ~p)) * Antiderivative(u * (~b + 2 * ~c * cos(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~n, ~p], ~x) && (EqQ(~n2, 2 * ~n) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && Not(IntegerQ(~p))))
    @apply_utils Antiderivative(1 / (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~(n2')), ~x) => Module([q = Rt((~b) ^ 2 - 4 * ~a * ~c, 2)], ((2 * ~c) / q) * Antiderivative(1 / ((~b - q) + 2 * ~c * sin(~d + ~e * ~x) ^ ~n), ~x) - ((2 * ~c) / q) * Antiderivative(1 / (~b + q + 2 * ~c * sin(~d + ~e * ~x) ^ ~n), ~x)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~n], ~x) && (EqQ(~n2, 2 * ~n) && NeQ((~b) ^ 2 - 4 * ~a * ~c, 0))
    @apply_utils Antiderivative(1 / (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~(n2')), ~x) => Module([q = Rt((~b) ^ 2 - 4 * ~a * ~c, 2)], ((2 * ~c) / q) * Antiderivative(1 / ((~b - q) + 2 * ~c * cos(~d + ~e * ~x) ^ ~n), ~x) - ((2 * ~c) / q) * Antiderivative(1 / (~b + q + 2 * ~c * cos(~d + ~e * ~x) ^ ~n), ~x)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~n], ~x) && (EqQ(~n2, 2 * ~n) && NeQ((~b) ^ 2 - 4 * ~a * ~c, 0))
    @apply_utils Antiderivative(sin(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~p, ~x) => (1 / (4 ^ ~p * (~c) ^ ~p)) * Antiderivative(sin(~d + ~e * ~x) ^ ~m * (~b + 2 * ~c * sin(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n], ~x) && (EqQ(~n2, 2 * ~n) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegerQ(~p)))
    @apply_utils Antiderivative(cos(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~p, ~x) => (1 / (4 ^ ~p * (~c) ^ ~p)) * Antiderivative(cos(~d + ~e * ~x) ^ ~m * (~b + 2 * ~c * cos(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n], ~x) && (EqQ(~n2, 2 * ~n) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegerQ(~p)))
    @apply_utils Antiderivative(sin(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~p, ~x) => ((~a + ~b * sin(~d + ~e * ~x) ^ ~n + ~c * sin(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p / (~b + 2 * ~c * sin(~d + ~e * ~x) ^ ~n) ^ (2 * ~p)) * Antiderivative(sin(~d + ~e * ~x) ^ ~m * (~b + 2 * ~c * sin(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p], ~x) && (EqQ(~n2, 2 * ~n) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && Not(IntegerQ(~p))))
    @apply_utils Antiderivative(cos(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~p, ~x) => ((~a + ~b * cos(~d + ~e * ~x) ^ ~n + ~c * cos(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p / (~b + 2 * ~c * cos(~d + ~e * ~x) ^ ~n) ^ (2 * ~p)) * Antiderivative(cos(~d + ~e * ~x) ^ ~m * (~b + 2 * ~c * cos(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p], ~x) && (EqQ(~n2, 2 * ~n) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && Not(IntegerQ(~p))))
    @apply_utils Antiderivative(sin(~(d') + ~(e') * ~x) ^ ~m * (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~n + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~n2) ^ ~p, ~x) => Module([f = FreeFactors(cot(~d + ~e * ~x), ~x)], (-f / ~e) * Subst(Antiderivative(ExpandToSum(~c + ~b * (1 + (~x) ^ 2) ^ (~n / 2) + ~a * (1 + (~x) ^ 2) ^ ~n, ~x) ^ ~p / (1 + f ^ 2 * (~x) ^ 2) ^ (~m / 2 + ~n * ~p + 1), ~x), ~x, cot(~d + ~e * ~x) / f)) <-- FreeQ([~a, ~b, ~c, ~d, ~e], ~x) && (EqQ(~n2, 2 * ~n) && (IntegerQ(~m / 2) && (NeQ((~b) ^ 2 - 4 * ~a * ~c, 0) && (IntegerQ(~n / 2) && IntegerQ(~p)))))
    @apply_utils Antiderivative(cos(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~n + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~n2) ^ ~p, ~x) => Module([f = FreeFactors(tan(~d + ~e * ~x), ~x)], (f / ~e) * Subst(Antiderivative(ExpandToSum(~c + ~b * (1 + (~x) ^ 2) ^ (~n / 2) + ~a * (1 + (~x) ^ 2) ^ ~n, ~x) ^ ~p / (1 + f ^ 2 * (~x) ^ 2) ^ (~m / 2 + ~n * ~p + 1), ~x), ~x, tan(~d + ~e * ~x) / f)) <-- FreeQ([~a, ~b, ~c, ~d, ~e], ~x) && (EqQ(~n2, 2 * ~n) && (IntegerQ(~m / 2) && (NeQ((~b) ^ 2 - 4 * ~a * ~c, 0) && (IntegerQ(~n / 2) && IntegerQ(~p)))))
    @apply_utils Antiderivative(sin(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~p, ~x) => Antiderivative(ExpandTrig(sin(~d + ~e * ~x) ^ ~m * (~a + ~b * sin(~d + ~e * ~x) ^ ~n + ~c * sin(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e], ~x) && (EqQ(~n2, 2 * ~n) && (NeQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegersQ(~m, ~n, ~p)))
    @apply_utils Antiderivative(cos(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~p, ~x) => Antiderivative(ExpandTrig(cos(~d + ~e * ~x) ^ ~m * (~a + ~b * cos(~d + ~e * ~x) ^ ~n + ~c * cos(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e], ~x) && (EqQ(~n2, 2 * ~n) && (NeQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegersQ(~m, ~n, ~p)))
    @apply_utils Antiderivative(cos(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * (~(f') * sin(~(d') + ~(e') * ~x)) ^ ~(n') + ~(c') * (~(f') * sin(~(d') + ~(e') * ~x)) ^ ~(n2')) ^ ~(p'), ~x) => Module([g = FreeFactors(sin(~d + ~e * ~x), ~x)], (g / ~e) * Subst(Antiderivative((1 - g ^ 2 * (~x) ^ 2) ^ ((~m - 1) / 2) * (~a + ~b * (~f * g * ~x) ^ ~n + ~c * (~f * g * ~x) ^ (2 * ~n)) ^ ~p, ~x), ~x, sin(~d + ~e * ~x) / g)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~n, ~p], ~x) && (EqQ(~n2, 2 * ~n) && IntegerQ((~m - 1) / 2))
    @apply_utils Antiderivative(sin(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * (~(f') * cos(~(d') + ~(e') * ~x)) ^ ~(n') + ~(c') * (~(f') * cos(~(d') + ~(e') * ~x)) ^ ~(n2')) ^ ~(p'), ~x) => Module([g = FreeFactors(cos(~d + ~e * ~x), ~x)], (-g / ~e) * Subst(Antiderivative((1 - g ^ 2 * (~x) ^ 2) ^ ((~m - 1) / 2) * (~a + ~b * (~f * g * ~x) ^ ~n + ~c * (~f * g * ~x) ^ (2 * ~n)) ^ ~p, ~x), ~x, cos(~d + ~e * ~x) / g)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~n, ~p], ~x) && (EqQ(~n2, 2 * ~n) && IntegerQ((~m - 1) / 2))
    @apply_utils Antiderivative(cos(~(d') + ~(e') * ~x) ^ ~m * (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~(p'), ~x) => (1 / (4 ^ ~p * (~c) ^ ~p)) * Antiderivative(cos(~d + ~e * ~x) ^ ~m * (~b + 2 * ~c * sin(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n], ~x) && (EqQ(~n2, 2 * ~n) && (Not(IntegerQ((~m - 1) / 2)) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegerQ(~p))))
    @apply_utils Antiderivative(sin(~(d') + ~(e') * ~x) ^ ~m * (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~(p'), ~x) => (1 / (4 ^ ~p * (~c) ^ ~p)) * Antiderivative(sin(~d + ~e * ~x) ^ ~m * (~b + 2 * ~c * cos(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n], ~x) && (EqQ(~n2, 2 * ~n) && (Not(IntegerQ((~m - 1) / 2)) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegerQ(~p))))
    @apply_utils Antiderivative(cos(~(d') + ~(e') * ~x) ^ ~m * (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~p, ~x) => ((~a + ~b * sin(~d + ~e * ~x) ^ ~n + ~c * sin(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p / (~b + 2 * ~c * sin(~d + ~e * ~x) ^ ~n) ^ (2 * ~p)) * Antiderivative(cos(~d + ~e * ~x) ^ ~m * (~b + 2 * ~c * sin(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p], ~x) && (EqQ(~n2, 2 * ~n) && (Not(IntegerQ((~m - 1) / 2)) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && Not(IntegerQ(~p)))))
    @apply_utils Antiderivative(sin(~(d') + ~(e') * ~x) ^ ~m * (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~p, ~x) => ((~a + ~b * cos(~d + ~e * ~x) ^ ~n + ~c * cos(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p / (~b + 2 * ~c * cos(~d + ~e * ~x) ^ ~n) ^ (2 * ~p)) * Antiderivative(sin(~d + ~e * ~x) ^ ~m * (~b + 2 * ~c * cos(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p], ~x) && (EqQ(~n2, 2 * ~n) && (Not(IntegerQ((~m - 1) / 2)) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && Not(IntegerQ(~p)))))
    @apply_utils Antiderivative(cos(~(d') + ~(e') * ~x) ^ ~m * (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~n + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~n2) ^ ~(p'), ~x) => Module([f = FreeFactors(cot(~d + ~e * ~x), ~x)], (-(f ^ (~m + 1)) / ~e) * Subst(Antiderivative(((~x) ^ ~m * ExpandToSum(~c + ~b * (1 + (~x) ^ 2) ^ (~n / 2) + ~a * (1 + (~x) ^ 2) ^ ~n, ~x) ^ ~p) / (1 + f ^ 2 * (~x) ^ 2) ^ (~m / 2 + ~n * ~p + 1), ~x), ~x, cot(~d + ~e * ~x) / f)) <-- FreeQ([~a, ~b, ~c, ~d, ~e], ~x) && (EqQ(~n2, 2 * ~n) && (IntegerQ(~m / 2) && (NeQ((~b) ^ 2 - 4 * ~a * ~c, 0) && (IntegerQ(~n / 2) && IntegerQ(~p)))))
    @apply_utils Antiderivative(sin(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~n + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~n2) ^ ~(p'), ~x) => Module([f = FreeFactors(tan(~d + ~e * ~x), ~x)], (f ^ (~m + 1) / ~e) * Subst(Antiderivative(((~x) ^ ~m * ExpandToSum(~c + ~b * (1 + (~x) ^ 2) ^ (~n / 2) + ~a * (1 + (~x) ^ 2) ^ ~n, ~x) ^ ~p) / (1 + f ^ 2 * (~x) ^ 2) ^ (~m / 2 + ~n * ~p + 1), ~x), ~x, tan(~d + ~e * ~x) / f)) <-- FreeQ([~a, ~b, ~c, ~d, ~e], ~x) && (EqQ(~n2, 2 * ~n) && (IntegerQ(~m / 2) && (NeQ((~b) ^ 2 - 4 * ~a * ~c, 0) && (IntegerQ(~n / 2) && IntegerQ(~p)))))
    @apply_utils Antiderivative(cos(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~(p'), ~x) => Antiderivative(ExpandTrig((1 - sin(~d + ~e * ~x) ^ 2) ^ (~m / 2) * (~a + ~b * sin(~d + ~e * ~x) ^ ~n + ~c * sin(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e], ~x) && (EqQ(~n2, 2 * ~n) && (IntegerQ(~m / 2) && (NeQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegersQ(~n, ~p))))
    @apply_utils Antiderivative(sin(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~(p'), ~x) => Antiderivative(ExpandTrig((1 - cos(~d + ~e * ~x) ^ 2) ^ (~m / 2) * (~a + ~b * cos(~d + ~e * ~x) ^ ~n + ~c * cos(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e], ~x) && (EqQ(~n2, 2 * ~n) && (IntegerQ(~m / 2) && (NeQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegersQ(~n, ~p))))
    @apply_utils Antiderivative(tan(~(d') + ~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~(f') * sin(~(d') + ~(e') * ~x)) ^ ~n + ~(c') * (~(f') * sin(~(d') + ~(e') * ~x)) ^ ~(n2')) ^ ~(p'), ~x) => Module([g = FreeFactors(sin(~d + ~e * ~x), ~x)], (g ^ (~m + 1) / ~e) * Subst(Antiderivative(((~x) ^ ~m * (~a + ~b * (~f * g * ~x) ^ ~n + ~c * (~f * g * ~x) ^ (2 * ~n)) ^ ~p) / (1 - g ^ 2 * (~x) ^ 2) ^ ((~m + 1) / 2), ~x), ~x, sin(~d + ~e * ~x) / g)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~n], ~x) && (IntegerQ((~m - 1) / 2) && IntegerQ(2 * ~p))
    @apply_utils Antiderivative(cot(~(d') + ~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~(f') * cos(~(d') + ~(e') * ~x)) ^ ~n + ~(c') * (~(f') * cos(~(d') + ~(e') * ~x)) ^ ~(n2')) ^ ~(p'), ~x) => Module([g = FreeFactors(cos(~d + ~e * ~x), ~x)], (-(g ^ (~m + 1)) / ~e) * Subst(Antiderivative(((~x) ^ ~m * (~a + ~b * (~f * g * ~x) ^ ~n + ~c * (~f * g * ~x) ^ (2 * ~n)) ^ ~p) / (1 - g ^ 2 * (~x) ^ 2) ^ ((~m + 1) / 2), ~x), ~x, cos(~d + ~e * ~x) / g)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~n], ~x) && (IntegerQ((~m - 1) / 2) && IntegerQ(2 * ~p))
    @apply_utils Antiderivative(tan(~(d') + ~(e') * ~x) ^ ~m * (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~(p'), ~x) => (1 / (4 ^ ~p * (~c) ^ ~p)) * Antiderivative(tan(~d + ~e * ~x) ^ ~m * (~b + 2 * ~c * sin(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n], ~x) && (EqQ(~n2, 2 * ~n) && (Not(IntegerQ((~m - 1) / 2)) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegerQ(~p))))
    @apply_utils Antiderivative(cot(~(d') + ~(e') * ~x) ^ ~m * (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~(p'), ~x) => (1 / (4 ^ ~p * (~c) ^ ~p)) * Antiderivative(cot(~d + ~e * ~x) ^ ~m * (~b + 2 * ~c * cos(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n], ~x) && (EqQ(~n2, 2 * ~n) && (Not(IntegerQ((~m - 1) / 2)) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegerQ(~p))))
    @apply_utils Antiderivative(tan(~(d') + ~(e') * ~x) ^ ~m * (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~p, ~x) => ((~a + ~b * sin(~d + ~e * ~x) ^ ~n + ~c * sin(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p / (~b + 2 * ~c * sin(~d + ~e * ~x) ^ ~n) ^ (2 * ~p)) * Antiderivative(tan(~d + ~e * ~x) ^ ~m * (~b + 2 * ~c * sin(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p], ~x) && (EqQ(~n2, 2 * ~n) && (Not(IntegerQ((~m - 1) / 2)) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && Not(IntegerQ(~p)))))
    @apply_utils Antiderivative(cot(~(d') + ~(e') * ~x) ^ ~m * (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~p, ~x) => ((~a + ~b * cos(~d + ~e * ~x) ^ ~n + ~c * cos(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p / (~b + 2 * ~c * cos(~d + ~e * ~x) ^ ~n) ^ (2 * ~p)) * Antiderivative(cot(~d + ~e * ~x) ^ ~m * (~b + 2 * ~c * cos(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p], ~x) && (EqQ(~n2, 2 * ~n) && (Not(IntegerQ((~m - 1) / 2)) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && Not(IntegerQ(~p)))))
    @apply_utils Antiderivative(tan(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~n + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~n2) ^ ~(p'), ~x) => Module([f = FreeFactors(tan(~d + ~e * ~x), ~x)], (f ^ (~m + 1) / ~e) * Subst(Antiderivative(((~x) ^ ~m * ExpandToSum(~c * (~x) ^ (2 * ~n) + ~b * (~x) ^ ~n * (1 + (~x) ^ 2) ^ (~n / 2) + ~a * (1 + (~x) ^ 2) ^ ~n, ~x) ^ ~p) / (1 + f ^ 2 * (~x) ^ 2) ^ (~n * ~p + 1), ~x), ~x, tan(~d + ~e * ~x) / f)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m], ~x) && (EqQ(~n2, 2 * ~n) && (Not(IntegerQ((~m - 1) / 2)) && (NeQ((~b) ^ 2 - 4 * ~a * ~c, 0) && (IntegerQ(~n / 2) && IntegerQ(~p)))))
    @apply_utils Antiderivative(cot(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~n + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~n2) ^ ~(p'), ~x) => Module([f = FreeFactors(cot(~d + ~e * ~x), ~x)], (-(f ^ (~m + 1)) / ~e) * Subst(Antiderivative(((~x) ^ ~m * ExpandToSum(~c * (~x) ^ (2 * ~n) + ~b * (~x) ^ ~n * (1 + (~x) ^ 2) ^ (~n / 2) + ~a * (1 + (~x) ^ 2) ^ ~n, ~x) ^ ~p) / (1 + f ^ 2 * (~x) ^ 2) ^ (~n * ~p + 1), ~x), ~x, cot(~d + ~e * ~x) / f)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m], ~x) && (EqQ(~n2, 2 * ~n) && (Not(IntegerQ((~m - 1) / 2)) && (NeQ((~b) ^ 2 - 4 * ~a * ~c, 0) && (IntegerQ(~n / 2) && IntegerQ(~p)))))
    @apply_utils Antiderivative(tan(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~(p'), ~x) => Antiderivative(ExpandTrig((sin(~d + ~e * ~x) ^ ~m * (~a + ~b * sin(~d + ~e * ~x) ^ ~n + ~c * sin(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p) / (1 - sin(~d + ~e * ~x) ^ 2) ^ (~m / 2), ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e], ~x) && (EqQ(~n2, 2 * ~n) && (IntegerQ(~m / 2) && (NeQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegersQ(~n, ~p))))
    @apply_utils Antiderivative(cot(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~(p'), ~x) => Antiderivative(ExpandTrig((cos(~d + ~e * ~x) ^ ~m * (~a + ~b * cos(~d + ~e * ~x) ^ ~n + ~c * cos(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p) / (1 - cos(~d + ~e * ~x) ^ 2) ^ (~m / 2), ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e], ~x) && (EqQ(~n2, 2 * ~n) && (IntegerQ(~m / 2) && (NeQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegersQ(~n, ~p))))
    @apply_utils Antiderivative(cot(~(d') + ~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~(f') * sin(~(d') + ~(e') * ~x)) ^ ~n + ~(c') * (~(f') * sin(~(d') + ~(e') * ~x)) ^ ~(n2')) ^ ~(p'), ~x) => Module([g = FreeFactors(sin(~d + ~e * ~x), ~x)], (g ^ (~m + 1) / ~e) * Subst(Antiderivative(((1 - g ^ 2 * (~x) ^ 2) ^ ((~m - 1) / 2) * (~a + ~b * (~f * g * ~x) ^ ~n + ~c * (~f * g * ~x) ^ (2 * ~n)) ^ ~p) / (~x) ^ ~m, ~x), ~x, sin(~d + ~e * ~x) / g)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~n], ~x) && (IntegerQ((~m - 1) / 2) && IntegerQ(2 * ~p))
    @apply_utils Antiderivative(tan(~(d') + ~(e') * ~x) ^ ~(m') * (~a + ~(b') * (~(f') * cos(~(d') + ~(e') * ~x)) ^ ~n + ~(c') * (~(f') * cos(~(d') + ~(e') * ~x)) ^ ~(n2')) ^ ~(p'), ~x) => Module([g = FreeFactors(cos(~d + ~e * ~x), ~x)], (-(g ^ (~m + 1)) / ~e) * Subst(Antiderivative(((1 - g ^ 2 * (~x) ^ 2) ^ ((~m - 1) / 2) * (~a + ~b * (~f * g * ~x) ^ ~n + ~c * (~f * g * ~x) ^ (2 * ~n)) ^ ~p) / (~x) ^ ~m, ~x), ~x, cos(~d + ~e * ~x) / g)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~f, ~n], ~x) && (IntegerQ((~m - 1) / 2) && IntegerQ(2 * ~p))
    @apply_utils Antiderivative(cot(~(d') + ~(e') * ~x) ^ ~m * (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~(p'), ~x) => (1 / (4 ^ ~p * (~c) ^ ~p)) * Antiderivative(cot(~d + ~e * ~x) ^ ~m * (~b + 2 * ~c * sin(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n], ~x) && (EqQ(~n2, 2 * ~n) && (Not(IntegerQ((~m - 1) / 2)) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegerQ(~p))))
    @apply_utils Antiderivative(tan(~(d') + ~(e') * ~x) ^ ~m * (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~(p'), ~x) => (1 / (4 ^ ~p * (~c) ^ ~p)) * Antiderivative(tan(~d + ~e * ~x) ^ ~m * (~b + 2 * ~c * cos(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n], ~x) && (EqQ(~n2, 2 * ~n) && (Not(IntegerQ((~m - 1) / 2)) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegerQ(~p))))
    @apply_utils Antiderivative(cot(~(d') + ~(e') * ~x) ^ ~m * (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~p, ~x) => ((~a + ~b * sin(~d + ~e * ~x) ^ ~n + ~c * sin(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p / (~b + 2 * ~c * sin(~d + ~e * ~x) ^ ~n) ^ (2 * ~p)) * Antiderivative(cot(~d + ~e * ~x) ^ ~m * (~b + 2 * ~c * sin(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p], ~x) && (EqQ(~n2, 2 * ~n) && (Not(IntegerQ((~m - 1) / 2)) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && Not(IntegerQ(~p)))))
    @apply_utils Antiderivative(tan(~(d') + ~(e') * ~x) ^ ~m * (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~p, ~x) => ((~a + ~b * cos(~d + ~e * ~x) ^ ~n + ~c * cos(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p / (~b + 2 * ~c * cos(~d + ~e * ~x) ^ ~n) ^ (2 * ~p)) * Antiderivative(tan(~d + ~e * ~x) ^ ~m * (~b + 2 * ~c * cos(~d + ~e * ~x) ^ ~n) ^ (2 * ~p), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m, ~n, ~p], ~x) && (EqQ(~n2, 2 * ~n) && (Not(IntegerQ((~m - 1) / 2)) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && Not(IntegerQ(~p)))))
    @apply_utils Antiderivative(cot(~(d') + ~(e') * ~x) ^ ~(m') * (~a + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~n + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~n2) ^ ~(p'), ~x) => Module([f = FreeFactors(cot(~d + ~e * ~x), ~x)], (-(f ^ (~m + 1)) / ~e) * Subst(Antiderivative(((~x) ^ ~m * ExpandToSum(~c + ~b * (1 + f ^ 2 * (~x) ^ 2) ^ (~n / 2) + ~a * (1 + f ^ 2 * (~x) ^ 2) ^ ~n, ~x) ^ ~p) / (1 + f ^ 2 * (~x) ^ 2) ^ (~n * ~p + 1), ~x), ~x, cot(~d + ~e * ~x) / f)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m], ~x) && (EqQ(~n2, 2 * ~n) && (IntegerQ(~n / 2) && IntegerQ(~p)))
    @apply_utils Antiderivative(tan(~(d') + ~(e') * ~x) ^ ~(m') * (~a + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~n + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~n2) ^ ~(p'), ~x) => Module([f = FreeFactors(tan(~d + ~e * ~x), ~x)], (f ^ (~m + 1) / ~e) * Subst(Antiderivative(((~x) ^ ~m * ExpandToSum(~c + ~b * (1 + f ^ 2 * (~x) ^ 2) ^ (~n / 2) + ~a * (1 + f ^ 2 * (~x) ^ 2) ^ ~n, ~x) ^ ~p) / (1 + f ^ 2 * (~x) ^ 2) ^ (~n * ~p + 1), ~x), ~x, tan(~d + ~e * ~x) / f)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~m], ~x) && (EqQ(~n2, 2 * ~n) && (IntegerQ(~n / 2) && IntegerQ(~p)))
    @apply_utils Antiderivative(cot(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * sin(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~(p'), ~x) => Antiderivative(ExpandTrig(((1 - sin(~d + ~e * ~x) ^ 2) ^ (~m / 2) * (~a + ~b * sin(~d + ~e * ~x) ^ ~n + ~c * sin(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p) / sin(~d + ~e * ~x) ^ ~m, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e], ~x) && (EqQ(~n2, 2 * ~n) && (IntegerQ(~m / 2) && (NeQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegersQ(~n, ~p))))
    @apply_utils Antiderivative(tan(~(d') + ~(e') * ~x) ^ ~(m') * (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) ^ ~(n') + ~(c') * cos(~(d') + ~(e') * ~x) ^ ~(n2')) ^ ~(p'), ~x) => Antiderivative(ExpandTrig(((1 - cos(~d + ~e * ~x) ^ 2) ^ (~m / 2) * (~a + ~b * cos(~d + ~e * ~x) ^ ~n + ~c * cos(~d + ~e * ~x) ^ (2 * ~n)) ^ ~p) / cos(~d + ~e * ~x) ^ ~m, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e], ~x) && (EqQ(~n2, 2 * ~n) && (IntegerQ(~m / 2) && (NeQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegersQ(~n, ~p))))
    @apply_utils Antiderivative((~A + ~(B') * sin(~(d') + ~(e') * ~x)) * (~a + ~(b') * sin(~(d') + ~(e') * ~x) + ~(c') * sin(~(d') + ~(e') * ~x) ^ 2) ^ ~n, ~x) => (1 / (4 ^ ~n * (~c) ^ ~n)) * Antiderivative((~A + ~B * sin(~d + ~e * ~x)) * (~b + 2 * ~c * sin(~d + ~e * ~x)) ^ (2 * ~n), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~A, ~B], ~x) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegerQ(~n))
    @apply_utils Antiderivative((~A + ~(B') * cos(~(d') + ~(e') * ~x)) * (~a + ~(b') * cos(~(d') + ~(e') * ~x) + ~(c') * cos(~(d') + ~(e') * ~x) ^ 2) ^ ~n, ~x) => (1 / (4 ^ ~n * (~c) ^ ~n)) * Antiderivative((~A + ~B * cos(~d + ~e * ~x)) * (~b + 2 * ~c * cos(~d + ~e * ~x)) ^ (2 * ~n), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~A, ~B], ~x) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegerQ(~n))
    @apply_utils Antiderivative((~A + ~(B') * sin(~(d') + ~(e') * ~x)) * (~a + ~(b') * sin(~(d') + ~(e') * ~x) + ~(c') * sin(~(d') + ~(e') * ~x) ^ 2) ^ ~n, ~x) => ((~a + ~b * sin(~d + ~e * ~x) + ~c * sin(~d + ~e * ~x) ^ 2) ^ ~n / (~b + 2 * ~c * sin(~d + ~e * ~x)) ^ (2 * ~n)) * Antiderivative((~A + ~B * sin(~d + ~e * ~x)) * (~b + 2 * ~c * sin(~d + ~e * ~x)) ^ (2 * ~n), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~A, ~B], ~x) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && Not(IntegerQ(~n)))
    @apply_utils Antiderivative((~A + ~(B') * cos(~(d') + ~(e') * ~x)) * (~a + ~(b') * cos(~(d') + ~(e') * ~x) + ~(c') * cos(~(d') + ~(e') * ~x) ^ 2) ^ ~n, ~x) => ((~a + ~b * cos(~d + ~e * ~x) + ~c * cos(~d + ~e * ~x) ^ 2) ^ ~n / (~b + 2 * ~c * cos(~d + ~e * ~x)) ^ (2 * ~n)) * Antiderivative((~A + ~B * cos(~d + ~e * ~x)) * (~b + 2 * ~c * cos(~d + ~e * ~x)) ^ (2 * ~n), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~A, ~B], ~x) && (EqQ((~b) ^ 2 - 4 * ~a * ~c, 0) && Not(IntegerQ(~n)))
    @apply_utils Antiderivative((~A + ~(B') * sin(~(d') + ~(e') * ~x)) / (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) + ~(c') * sin(~(d') + ~(e') * ~x) ^ 2), ~x) => Module([q = Rt((~b) ^ 2 - 4 * ~a * ~c, 2)], (~B + (~b * ~B - 2 * ~A * ~c) / q) * Antiderivative(1 / (~b + q + 2 * ~c * sin(~d + ~e * ~x)), ~x) + (~B - (~b * ~B - 2 * ~A * ~c) / q) * Antiderivative(1 / ((~b - q) + 2 * ~c * sin(~d + ~e * ~x)), ~x)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~A, ~B], ~x) && NeQ((~b) ^ 2 - 4 * ~a * ~c, 0)
    @apply_utils Antiderivative((~A + ~(B') * cos(~(d') + ~(e') * ~x)) / (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) + ~(c') * cos(~(d') + ~(e') * ~x) ^ 2), ~x) => Module([q = Rt((~b) ^ 2 - 4 * ~a * ~c, 2)], (~B + (~b * ~B - 2 * ~A * ~c) / q) * Antiderivative(1 / (~b + q + 2 * ~c * cos(~d + ~e * ~x)), ~x) + (~B - (~b * ~B - 2 * ~A * ~c) / q) * Antiderivative(1 / ((~b - q) + 2 * ~c * cos(~d + ~e * ~x)), ~x)) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~A, ~B], ~x) && NeQ((~b) ^ 2 - 4 * ~a * ~c, 0)
    @apply_utils Antiderivative((~A + ~(B') * sin(~(d') + ~(e') * ~x)) * (~(a') + ~(b') * sin(~(d') + ~(e') * ~x) + ~(c') * sin(~(d') + ~(e') * ~x) ^ 2) ^ ~n, ~x) => Antiderivative(ExpandTrig((~A + ~B * sin(~d + ~e * ~x)) * (~a + ~b * sin(~d + ~e * ~x) + ~c * sin(~d + ~e * ~x) ^ 2) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~A, ~B], ~x) && (NeQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegerQ(~n))
    @apply_utils Antiderivative((~A + ~(B') * cos(~(d') + ~(e') * ~x)) * (~(a') + ~(b') * cos(~(d') + ~(e') * ~x) + ~(c') * cos(~(d') + ~(e') * ~x) ^ 2) ^ ~n, ~x) => Antiderivative(ExpandTrig((~A + ~B * cos(~d + ~e * ~x)) * (~a + ~b * cos(~d + ~e * ~x) + ~c * cos(~d + ~e * ~x) ^ 2) ^ ~n, ~x), ~x) <-- FreeQ([~a, ~b, ~c, ~d, ~e, ~A, ~B], ~x) && (NeQ((~b) ^ 2 - 4 * ~a * ~c, 0) && IntegerQ(~n))
end

max_stars_repo_path: src/rules/4 Trig functions/4.1 Sine/4.1.9 trig^m (a+b sin^n+c sin^(2 n))^p.jl


text:
function amend_description(res_dir::String, new_comment::String,
        sources::Vector{String})
    tree = Core.ResDirTree(res_dir);
    desc = Core.build_description(Core.resdir(tree),
        new_comment * " (Description amended!!!)", sources);
    Core.save_desc(tree, desc);
    Core.add_to_log(tree, desc);
end

max_stars_repo_name: josePereiro/MyResultsManager

max_issues_repo_name: josePereiro/MyResultsManager

max_forks_repo_name: josePereiro/MyResultsManager


text:
using Test
using Cleaner: CleanTable, names, rename
import Tables

@testset "CleanTable satisfies Tables.jl interface" begin
    testCT = CleanTable([:A, :B, :C], [[1, 2, 3], [4, 5, 6], String["7", "8", "9"]])

    @test Tables.istable(typeof(testCT))
    @test Tables.columnaccess(typeof(testCT))
    @test Tables.columns(testCT) === testCT
    @test testCT.A == [1, 2, 3]
    @test Tables.getcolumn(testCT, :A) == [1, 2, 3]
    @test Tables.getcolumn(testCT, 1) == [1, 2, 3]
    @test Tables.columnnames(testCT) == [:A, :B, :C]

    nt = (A=[1,2,3], B=["x", "y", "z"])
    ctNT = Tables.materializer(testCT)(nt)
    @test nt |> CleanTable isa CleanTable
    @test ctNT isa CleanTable
    @test Tables.columntable(ctNT) == (A = [1, 2, 3], B = ["x", "y", "z"])
    @test Tables.rowtable(ctNT) == [(A = 1, B = "x"), (A = 2, B = "y"), (A = 3, B = "z")]

    ctNT.A[1] = 5
    @test ctNT.A != nt.A
    ctNT = CleanTable(nt, copycols=false)
    ctNT.A[1] = 5
    @test ctNT.A === nt.A
end

@testset "CleanTable works as expected" begin
    testCT = CleanTable([:A, :B, :C], [[1, 2, 3], [4, 5, 6], String["7", "8", "9"]])

    @test CleanTable(testCT) isa CleanTable

    testCT.A = [7, 8, 9]
    @test testCT[1] == [7, 8, 9]

    testCT2 = rename(testCT, [:x, :y, :z])
    @test names(testCT2) == [:x, :y, :z]

    let err = nothing
        try
            rename(testCT, [:a, :b])
        catch err
        end
        @test err isa Exception
        @test sprint(showerror, err) == "Inconsistent length between names given and amount of columns"
    end

    let err = nothing
        try
            CleanTable([:A, :B, :C], [[1, 2, 3], [4, 5, 6]])
        catch err
        end
        @test err isa Exception
        @test sprint(showerror, err) == "Inconsistent length between names given and
        amount of columns"
    end

    let err = nothing
        try
            CleanTable([:A, :B], [[1, 2, 3], [4, 5]])
        catch err
        end
        @test err isa Exception
        @test sprint(showerror, err) == "All columns must be of the same length"
    end

    let err = nothing
        try
            testCT.names = [:x, :y, :z]
        catch err
        end
        @test err isa Exception
        @test sprint(showerror, err) == "Changing property 'names' directly is unsupported, please use the `rename!` function"
    end

    let err = nothing
        try
            tmp = CleanTable([:A, :B], [[1, 2, 3], [4, 5, 6]])
            tmp.cols = [[5,6,7], ["x", "y", "z"]]
        catch err
        end
        @test err isa Exception
        @test sprint(showerror, err) == "Property 'cols' cannot be changed"
    end

    let err = nothing
        try
            tmp = CleanTable([:A, :B], [[1, 2, 3], [4, 5, 6]])
            tmp.c = [7, 8, 9]
        catch err
        end
        @test err isa Exception
        @test sprint(showerror, err) == "Property 'c' does not exist"
    end

    @test CleanTable([:A, :B], [collect(1:1_000_000), collect(1:1_000_000)])[1] |> length == 1_000_000

    let err = nothing
        try
            tmp = CleanTable([:A, :B], [[1, 2, 3], [4, 5, 6]])
            tmp.A = [1]
        catch err
        end
        @test err isa Exception
        @test sprint(showerror, err) == "Length of the AbstractVector being assigned to column 'A' must be consistent with the length of the rest of columns"
    end

    let err = nothing
        try
           tmp = CleanTable([:A, :B], [[1, 2, 3], [4, 5, 6]])
           tmp.A = 1
        catch err
        end
        @test err isa Exception
        @test sprint(showerror, err) == "Value being assigned must be an AbstractVector"
    end
end

max_stars_repo_name: TheRoniOne/Cleaner

max_issues_repo_name: TheRoniOne/Cleaner

max_forks_repo_name: TheRoniOne/Cleaner


text:
using ImageTracking
using Images, ImageView
using CoordinateTransformations, StaticArrays
using LinearAlgebra
algorithm = Farneback(50, estimation_window = 11,
                         σ_estimation_window = 9.0,
                         expansion_window = 6,
                         σ_expansion_window = 5.0)

for i in 1:537
    img1 = load("./dataset/opencv_frame_$(i).png")
    img2 = load("./dataset/opencv_frame_$(i+1).png")

    flow = optical_flow(Gray{Float32}.(img1), Gray{Float32}.(img2), algorithm)

    # Convert from (row,column) to (x,y) convention.
    map!(x-> SVector(last(x),first(x)), flow, flow)

    # Display optical flow as an image, with hue encoding the orientation and
    # saturation encoding the relative magnitude.
    max_norm = maximum(map(norm,flow))
    normalised_flow = map(PolarFromCartesian(),flow / max_norm)
    hsv = zeros(HSV{Float32},size(img1))
    for i in eachindex(flow)
        hsv[i] = HSV((normalised_flow[i].θ + pi) * 180 / pi, normalised_flow[i].r, 1)
    end
    # Visualize the optical flow and save it to disk.
    # imshow(RGB.(hsv))
    save("./demo/optical_flow_$(i).jpg", hsv)
end

max_stars_repo_name: ashwani-rathee/Sigil

max_issues_repo_name: ashwani-rathee/Sigil

max_forks_repo_name: ashwani-rathee/Sigil


text:
# https://docs.influxdata.com/influxdb/v2.1/api/
using HTTP, JSON3, DataFrames, Dates, CSV, CodecZlib

import Base.write, Base.show

struct InfluxServer
    url::String
    org::String
    token::String
    function InfluxServer(url::String, org::String, token::String)

        # remove tailing / if existing
        if endswith(url, '/')
            url = chop(url)
        end
        influx = new(url, org, token)

        # try pinging it
        resp = ping(influx)
        if resp.status != 204
            @warn("Ping status, expected 204, got $(resp.status)")
        end
        # TODO check version, but receive empty string?
        #headers = Dict(resp.headers)
        #headers["X-Influxdb-Version"] < v"2.0" && @warn "..."
        return influx
    end
end

show(io::IO, ::MIME"text/plain", influx::InfluxServer) = print(io, "InfluxServer(url:\"$(influx.url)\",org:\"$(influx.org)\",token:\"$(influx.token[1:4])...\")")
show(io::IO, influx::InfluxServer) = show(io::IO, MIME("text/plain"), influx::InfluxServer)

"""
    writetable(influx::InfluxServer, bucket::String, measurement, table; precision::Union{Symbol, String} = :ms, compression::Symbol = :identity)

Write a table to the influx database. Fields and tags need to be
specified using prefixes \"f_\" and \"t_\" respectively. A column namd timestamp needs to
be provided which contains Int or DateTime entries.
Compression can be set to :gzip to compress the line protocol before sending.
"""
function writetable(influx::InfluxServer, bucket::String, measurement, table; precision::Union{Symbol, String} = :ms, compression::Symbol = :identity)
    buffer = table2lineprotocol(measurement, table, precision = precision)
    return write(influx, bucket, buffer; precision = precision, compression = compression)
end

"""
    writelineprotocol(influx::InfluxServer, bucket::String, linep::String; precision::Union{Symbol, String} = :ms, compression::Symbol = :identity)

Write data using the lineprotocol.
Compression can be set to :gzip to compress the line protocol before sending.
"""
function writelineprotocol(influx::InfluxServer, bucket::String, linep::String; precision::Union{Symbol, String} = :ms, compression::Symbol = :identity)
    return write(influx, bucket, IOBuffer(linep); precision = precision, compression = compression)
end

function write(influx::InfluxServer, bucket::String, body::IOBuffer; precision::Union{Symbol, String} = :ms, compression::Symbol = :identity)
    @assert(compression in (:identity, :gzip), "\"compression\" must be either :identity or :gzip.")
    url = influx.url*"/api/v2/write?org="*HTTP.escapeuri(influx.org)*"&bucket="*HTTP.escapeuri(bucket)*"&precision="*string(precision)
    headers = ["Authorization"=>"Token "*influx.token, "Accept"=>"application/json", "Content-Encoding"=>string(compression), "Content-Type"=>"text/plain"]

    if compression == :gzip
        # gzip compression before sending
        compressed_body = GzipCompressorStream(body)
        return HTTP.post(url, headers, compressed_body)

    else
        # no compression
        return HTTP.post(url, headers, body)
    end
end

listbuckets(influx::InfluxServer) = fluxquery(influx, "buckets()")
listmeasurements(influx::InfluxServer, bucket::String) = fluxquery(influx, "import \"influxdata/influxdb/schema\"\nschema.measurements(bucket: \"$bucket\")")
function listfields(influx::InfluxServer, bucket::String, measurement::String)
    querystring = "import \"influxdata/influxdb/schema\"\n
    schema.measurementFieldKeys(\n
    bucket: \"$bucket\",\n
    measurement: \"$measurement\")"
    return fluxquery(influx, querystring)
end

"""
    listorgs(influx::InfluxServer)

Return tuples containing the name and id of the organisations.
"""
function listorgs(influx::InfluxServer)
    url = influx.url*"/api/v2/orgs"
    headers = ["Authorization"=>"Token "*influx.token]
    resp =  HTTP.get(url, headers)
    jsonobj = JSON3.read(resp.body)
    return [(o.name, o.id) for o in jsonobj.orgs]
end

function getorgid(influx::InfluxServer)
    url = influx.url*"/api/v2/orgs?org="*HTTP.escapeuri(influx.org)
    headers = ["Authorization"=>"Token "*influx.token]
    resp =  HTTP.get(url, headers)
    jsonobj = JSON3.read(resp.body)
    return jsonobj.orgs[1].id
end

"""
    fluxquery(influx::InfluxServer, querystring::String; compression::Symbol = :identity)

Query data and return a DataFrame for each table returned by InfluxDB.
"""
function fluxquery(influx::InfluxServer, querystring::String; compression::Symbol = :identity)
    @assert(compression in (:identity, :gzip), "\"compression\" must be either :identity or :gzip.")
    url = influx.url*"/api/v2/query?org="*HTTP.escapeuri(influx.org)
    headers = ["Authorization"=>"Token "*influx.token, "Content-Type"=>"application/json", "Accept"=>"application/csv", "Accept-Encoding"=>string(compression)]

    body = "{\"query\":"*JSON3.write(querystring)*",\"dialect\":{\"annotations\": [\"datatype\"],\"commentPrefix\": \"#\", \"dateTimeFormat\": \"RFC3339\"}}"
    resp = HTTP.post(url, headers, body)

    # Check if we received teh encoding we asked for (no Content-Encoding returned for identity)
    resp_encoding = Symbol( get( Dict(resp.headers), "Content-Encoding", "identity") )
    if resp_encoding != compression
        @warn "Received Content-Encoding $resp_encoding but asked for $compression"
    end

    # Decompress answer if necessary
    if resp_encoding == :gzip
        influxans = String(transcode(GzipDecompressor, resp.body))
    else
        influxans = String(resp.body)
    end

    return parseinfluxresp( influxans )
end

"""
    simplequery(influx::InfluxServer, bucket::String, measurement::String, fields::Vector{String}, timerange::Tuple{DateTime, DateTime}; tags = nothing, compression::Symbol = :identity)
"""
function simplequery(influx::InfluxServer, bucket::String, measurement::String, fields::Vector{String}, timerange::Tuple{DateTime, DateTime}; tags = nothing, compression::Symbol = :identity)
    @assert length(fields)>0
    from = Dates.format(timerange[1], "yyyy-mm-ddTHH:MM:SS.sZ")
    to = Dates.format(timerange[2], "yyyy-mm-ddTHH:MM:SS.sZ")

    # Create flux query
    querybuffer = IOBuffer()
    Base.write(querybuffer, "from(bucket: \"$bucket\")\n")
    Base.write(querybuffer, "|>range(start: $from, stop: $to)\n")
    Base.write(querybuffer, "|>filter(fn: (r) => r[\"_measurement\"] == \"$measurement\")\n")
    Base.write(querybuffer, "|>filter(fn: (r) =>r[\"_field\"] == \"$(fields[1])\"")
    for f in fields[2:end]
        Base.write(querybuffer, " or r[\"_field\"] == \"$f\"")
    end
    Base.write(querybuffer, ")\n")
    if !isnothing(tags)
        i = iterate(tags)
        (k, v) = i[1]
        Base.write(querybuffer, "|>filter(fn: (r)=>r[\"$(string(k))\"]==\"$(string(v))\"")
        i = iterate(tags, i[2])
        while !isnothing(i)
            (k, v) = i[1]
            Base.write(querybuffer, " or r[\"$(string(k))\"]==\"$(string(v))\"")
            i = iterate(tags, i[2])
        end
        Base.write(querybuffer, ")\n")
    end
    Base.write(querybuffer, "|>drop(columns: [\"_measurement\", \"_start\", \"_stop\"])")
    Base.write(querybuffer, "|>group(columns: [\"_field\"], mode: \"by\")")
    Base.write(querybuffer, "|>sort(columns: [\"_time\"])")
    return fluxquery(influx, String(take!(querybuffer)); compression = compression)
end

"""
    parseinfluxresp(respstr::AbstractString)

Parses the annotated CSV table responses from Influx.
Return a DataFrame for each table.
Annotation needs to be "datatype".
"""
function parseinfluxresp(respstr::AbstractString)
    influxtypesdict = Base.ImmutableDict("string"=>String,"long"=>Int64, "boolean"=>Bool, "dateTime:RFC3339"=>String, "double"=>Float64)

    # split in tables and remove last empty entry
    tablesstr = split(respstr, "\r\n\r\n")[1:end-1]

    # Transform each table string into a DataFrame
    Out = Vector{DataFrame}(undef, 0)
    for (itab, tab) in enumerate(tablesstr)
        rows = split(tab, "\r\n"; limit = 2)
        typesinflux = split(rows[1], ',')
        typesjulia = [get(influxtypesdict, tstr, String) for tstr in typesinflux]

        dframe = CSV.read(IOBuffer(rows[2]), DataFrame; types = typesjulia , drop = [1])
        # Correct DateTimes
        ind = findall(typesinflux.=="dateTime:RFC3339")
        for i in ind
            dframe[!,i-1] = parseRFC3339.(dframe[:,i-1])
        end
        dfsgrouped = groupby(dframe, "table")
        append!(Out, [DataFrame(df) for df in dfsgrouped])
    end

    return Out
end

# A lot faster than using DateTime parser
function parseRFC3339(dtiso)
    strlen = length(dtiso)
    dtiso2 = ifelse( strlen<24, dtiso[1:end-1]*"0000", dtiso)
    year = parse(Int,dtiso2[1:4])
    month = parse(Int,dtiso2[6:7])
    day = parse(Int,dtiso2[9:10])
    hour = parse(Int,dtiso2[12:13])
    minute = parse(Int,dtiso2[15:16])
    second = parse(Int,dtiso2[18:19])
    millisecond = parse(Int,dtiso2[21:23])
    DateTime(year, month, day, hour, minute, second, millisecond)
end

ping(influx::InfluxServer) = HTTP.get(influx.url*"/ping"; status_exception = false, connect_timeout = 3, readtimeout = 5)