text:
#pragma once
#include <aws/wafv2/WAFV2_EXPORTS.h>
#include <aws/wafv2/WAFV2Request.h>
#include <aws/core/utils/memory/stl/AWSString.h>
#include <aws/wafv2/model/Scope.h>
#include <utility>

namespace Aws
{
namespace WAFV2
{
namespace Model
{

  /**
   */
  class AWS_WAFV2_API GetRuleGroupRequest : public WAFV2Request
  {
  public:
    GetRuleGroupRequest();

    // Service request name is the Operation name which will send this request out,
    // each operation should has unique request name, so that we can get operation's name from this request.
    // Note: this is not true for response, multiple operations may have the same response name,
    // so we can not get operation's name from response.
    inline virtual const char* GetServiceRequestName() const override { return "GetRuleGroup"; }

    Aws::String SerializePayload() const override;

    Aws::Http::HeaderValueCollection GetRequestSpecificHeaders() const override;

    /**
     *
The name of the rule group. You cannot change the name of a rule group after
     * you create it.

     */
    inline const Aws::String& GetName() const{ return m_name; }

    /**
     *
The name of the rule group. You cannot change the name of a rule group after
     * you create it.

     */
    inline bool NameHasBeenSet() const { return m_nameHasBeenSet; }

    /**
     *
The name of the rule group. You cannot change the name of a rule group after
     * you create it.

     */
    inline void SetName(const Aws::String& value) { m_nameHasBeenSet = true; m_name = value; }

    /**
     *
The name of the rule group. You cannot change the name of a rule group after
     * you create it.

     */
    inline void SetName(Aws::String&& value) { m_nameHasBeenSet = true; m_name = std::move(value); }

    /**
     *
The name of the rule group. You cannot change the name of a rule group after
     * you create it.

     */
    inline void SetName(const char* value) { m_nameHasBeenSet = true; m_name.assign(value); }

    /**
     *
The name of the rule group. You cannot change the name of a rule group after
     * you create it.

     */
    inline GetRuleGroupRequest& WithName(const Aws::String& value) { SetName(value); return *this;}

    /**
     *
The name of the rule group. You cannot change the name of a rule group after
     * you create it.

     */
    inline GetRuleGroupRequest& WithName(Aws::String&& value) { SetName(std::move(value)); return *this;}

    /**
     *
The name of the rule group. You cannot change the name of a rule group after
     * you create it.

     */
    inline GetRuleGroupRequest& WithName(const char* value) { SetName(value); return *this;}

    /**
     *
Specifies whether this is for an Amazon CloudFront distribution or for a
     * regional application. A regional application can be an Application Load Balancer
     * (ALB), an Amazon API Gateway REST API, an AppSync GraphQL API, or an Amazon
     * Cognito user pool.

To work with CloudFront, you must also specify the
     * Region US East (N. Virginia) as follows:

CLI - Specify the
     * Region when you use the CloudFront scope: --scope=CLOUDFRONT
     * --region=us-east-1.

API and SDKs - For all calls, use
     * the Region endpoint us-east-1.

     */
    inline const Scope& GetScope() const{ return m_scope; }

    /**
     *
Specifies whether this is for an Amazon CloudFront distribution or for a
     * regional application. A regional application can be an Application Load Balancer
     * (ALB), an Amazon API Gateway REST API, an AppSync GraphQL API, or an Amazon
     * Cognito user pool.

To work with CloudFront, you must also specify the
     * Region US East (N. Virginia) as follows:

CLI - Specify the
     * Region when you use the CloudFront scope: --scope=CLOUDFRONT
     * --region=us-east-1.

API and SDKs - For all calls, use
     * the Region endpoint us-east-1.

     */
    inline bool ScopeHasBeenSet() const { return m_scopeHasBeenSet; }

    /**
     *
Specifies whether this is for an Amazon CloudFront distribution or for a
     * regional application. A regional application can be an Application Load Balancer
     * (ALB), an Amazon API Gateway REST API, an AppSync GraphQL API, or an Amazon
     * Cognito user pool.

To work with CloudFront, you must also specify the
     * Region US East (N. Virginia) as follows:

CLI - Specify the
     * Region when you use the CloudFront scope: --scope=CLOUDFRONT
     * --region=us-east-1.

API and SDKs - For all calls, use
     * the Region endpoint us-east-1.

     */
    inline void SetScope(const Scope& value) { m_scopeHasBeenSet = true; m_scope = value; }

    /**
     *
Specifies whether this is for an Amazon CloudFront distribution or for a
     * regional application. A regional application can be an Application Load Balancer
     * (ALB), an Amazon API Gateway REST API, an AppSync GraphQL API, or an Amazon
     * Cognito user pool.

To work with CloudFront, you must also specify the
     * Region US East (N. Virginia) as follows:

CLI - Specify the
     * Region when you use the CloudFront scope: --scope=CLOUDFRONT
     * --region=us-east-1.

API and SDKs - For all calls, use
     * the Region endpoint us-east-1.

     */
    inline void SetScope(Scope&& value) { m_scopeHasBeenSet = true; m_scope = std::move(value); }

    /**
     *
Specifies whether this is for an Amazon CloudFront distribution or for a
     * regional application. A regional application can be an Application Load Balancer
     * (ALB), an Amazon API Gateway REST API, an AppSync GraphQL API, or an Amazon
     * Cognito user pool.

To work with CloudFront, you must also specify the
     * Region US East (N. Virginia) as follows:

CLI - Specify the
     * Region when you use the CloudFront scope: --scope=CLOUDFRONT
     * --region=us-east-1.

API and SDKs - For all calls, use
     * the Region endpoint us-east-1.

     */
    inline GetRuleGroupRequest& WithScope(const Scope& value) { SetScope(value); return *this;}

    /**
     *
Specifies whether this is for an Amazon CloudFront distribution or for a
     * regional application. A regional application can be an Application Load Balancer
     * (ALB), an Amazon API Gateway REST API, an AppSync GraphQL API, or an Amazon
     * Cognito user pool.

To work with CloudFront, you must also specify the
     * Region US East (N. Virginia) as follows:

CLI - Specify the
     * Region when you use the CloudFront scope: --scope=CLOUDFRONT
     * --region=us-east-1.

API and SDKs - For all calls, use
     * the Region endpoint us-east-1.

     */
    inline GetRuleGroupRequest& WithScope(Scope&& value) { SetScope(std::move(value)); return *this;}

    /**
     *
A unique identifier for the rule group. This ID is returned in the responses
     * to create and list commands. You provide it to operations like update and
     * delete.

     */
    inline const Aws::String& GetId() const{ return m_id; }

    /**
     *
A unique identifier for the rule group. This ID is returned in the responses
     * to create and list commands. You provide it to operations like update and
     * delete.

     */
    inline bool IdHasBeenSet() const { return m_idHasBeenSet; }

    /**
     *
A unique identifier for the rule group. This ID is returned in the responses
     * to create and list commands. You provide it to operations like update and
     * delete.

     */
    inline void SetId(const Aws::String& value) { m_idHasBeenSet = true; m_id = value; }

    /**
     *
A unique identifier for the rule group. This ID is returned in the responses
     * to create and list commands. You provide it to operations like update and
     * delete.

     */
    inline void SetId(Aws::String&& value) { m_idHasBeenSet = true; m_id = std::move(value); }

    /**
     *
A unique identifier for the rule group. This ID is returned in the responses
     * to create and list commands. You provide it to operations like update and
     * delete.

     */
    inline void SetId(const char* value) { m_idHasBeenSet = true; m_id.assign(value); }

    /**
     *
A unique identifier for the rule group. This ID is returned in the responses
     * to create and list commands. You provide it to operations like update and
     * delete.

     */
    inline GetRuleGroupRequest& WithId(const Aws::String& value) { SetId(value); return *this;}

    /**
     *
A unique identifier for the rule group. This ID is returned in the responses
     * to create and list commands. You provide it to operations like update and
     * delete.

     */
    inline GetRuleGroupRequest& WithId(Aws::String&& value) { SetId(std::move(value)); return *this;}

    /**
     *
A unique identifier for the rule group. This ID is returned in the responses
     * to create and list commands. You provide it to operations like update and
     * delete.

     */
    inline GetRuleGroupRequest& WithId(const char* value) { SetId(value); return *this;}

    /**
     *
The Amazon Resource Name (ARN) of the entity.

     */
    inline const Aws::String& GetARN() const{ return m_aRN; }

    /**
     *
The Amazon Resource Name (ARN) of the entity.

     */
    inline bool ARNHasBeenSet() const { return m_aRNHasBeenSet; }

    /**
     *
The Amazon Resource Name (ARN) of the entity.

     */
    inline void SetARN(const Aws::String& value) { m_aRNHasBeenSet = true; m_aRN = value; }

    /**
     *
The Amazon Resource Name (ARN) of the entity.

     */
    inline void SetARN(Aws::String&& value) { m_aRNHasBeenSet = true; m_aRN = std::move(value); }

    /**
     *
The Amazon Resource Name (ARN) of the entity.

     */
    inline void SetARN(const char* value) { m_aRNHasBeenSet = true; m_aRN.assign(value); }

    /**
     *
The Amazon Resource Name (ARN) of the entity.

     */
    inline GetRuleGroupRequest& WithARN(const Aws::String& value) { SetARN(value); return *this;}

    /**
     *
The Amazon Resource Name (ARN) of the entity.

     */
    inline GetRuleGroupRequest& WithARN(Aws::String&& value) { SetARN(std::move(value)); return *this;}

    /**
     *
The Amazon Resource Name (ARN) of the entity.

     */
    inline GetRuleGroupRequest& WithARN(const char* value) { SetARN(value); return *this;}

  private:

    Aws::String m_name;
    bool m_nameHasBeenSet = false;

    Scope m_scope;
    bool m_scopeHasBeenSet = false;

    Aws::String m_id;
    bool m_idHasBeenSet = false;

    Aws::String m_aRN;
    bool m_aRNHasBeenSet = false;
  };

} // namespace Model
} // namespace WAFV2
} // namespace Aws


text:
package org.springframework.amqp.tutorials.tut5;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.util.StopWatch;

/**
 * @author Gary Russell
 * @author Scott Deeg
 */
public class Tut5Receiver {

	@RabbitListener(queues = "#{autoDeleteQueue1.name}")
	public void receive1(String in) throws InterruptedException {
		receive(in, 1);
	}

	@RabbitListener(queues = "#{autoDeleteQueue2.name}")
	public void receive2(String in) throws InterruptedException {
		receive(in, 2);
	}

	public void receive(String in, int receiver) throws InterruptedException {
		StopWatch watch = new StopWatch();
		watch.start();
		System.out.println("instance " + receiver + " [x] Received '" + in + "'");
		doWork(in);
		watch.stop();
		System.out.println("instance " + receiver + " [x] Done in " + watch.getTotalTimeSeconds() + "s");
	}

	private void doWork(String in) throws InterruptedException {
		for (char ch : in.toCharArray()) {
			if (ch == '.') {
				Thread.sleep(1000);
			}
		}
	}

}

redpajama_set_name: RedPajamaGithub


text:
import math
def divide(dividend, divisor):
    flag = 1
    if (dividend < 0) ^ (divisor < 0):
        flag = -1
    dividend = abs(dividend)
    divisor =   abs(divisor)
    result = 0
    while dividend >= divisor:
        shift  = 0
        # shift the divisor tp left(multiply by 2)
        while dividend >= (divisor << shift):
            shift += 1
        # count how many multiples of 2 is required
        result += 1<<(shift - 1)
        # subtract the divisor from the largest shifted divisor less than dividend
        dividend -= divisor << (shift - 1)

    result = flag * result
    # To limit integer overflow(Assuming 4B integer)
    return min(max(result, -2147483648), 2147483647)
print(divide(0,1))


text:
<!--

********************************************************************************

WARNING:

    DO NOT EDIT "clefos/README.md"

    IT IS AUTO-GENERATED

    (from the other files in "clefos/" combined with a set of templates)

********************************************************************************

-->

# Quick reference

-	**Maintained by**:
	[The ClefOS Project](https://github.com/nealef/clefos)

-	**Where to get help**:
	[the Docker Community Forums](https://forums.docker.com/), [the Docker Community Slack](https://dockr.ly/slack), or [Stack Overflow](https://stackoverflow.com/search?tab=newest&q=docker)

# Supported tags and respective `Dockerfile` links

-	[`7`, `7.7.1908`, `latest`](https://github.com/nealef/clefos/blob/1aa7d3771b2ced8b8b5cdc9a1a1752d93c56a60e/Dockerfile)

# Quick reference (cont.)

-	**Where to file issues**:
	[GitHub](https://github.com/nealef/clefos/issues)

-	**Supported architectures**: ([more info](https://github.com/docker-library/official-images#architectures-other-than-amd64))
	[`s390x`](https://hub.docker.com/r/s390x/clefos/)

-	**Published image artifact details**:
	[repo-info repo's `repos/clefos/` directory](https://github.com/docker-library/repo-info/blob/master/repos/clefos) ([history](https://github.com/docker-library/repo-info/commits/master/repos/clefos))
	(image metadata, transfer size, etc)

-	**Image updates**:
	[official-images repo's `library/clefos` label](https://github.com/docker-library/official-images/issues?q=label%3Alibrary%2Fclefos)
	[official-images repo's `library/clefos` file](https://github.com/docker-library/official-images/blob/master/library/clefos) ([history](https://github.com/docker-library/official-images/commits/master/library/clefos))

-	**Source of this description**:
	[docs repo's `clefos/` directory](https://github.com/docker-library/docs/tree/master/clefos) ([history](https://github.com/docker-library/docs/commits/master/clefos))

# ClefOS

ClefOS Linux is a community-supported distribution for IBM Z (aka "mainframe") derived from sources freely provided to the public by [CentOS](http://vault.clefos.org/) which in turn is derived from the [Red Hat](ftp://ftp.redhat.com/pub/redhat/linux/enterprise/) sources for Red Hat Enterprise Linux (RHEL). As such, ClefOS Linux aims to be functionally compatible with CentOS and RHEL. The ClefOS Project mainly changes packages to remove upstream vendor branding and artwork. ClefOS Linux is no-cost and free to redistribute. Each ClefOS Linux version is maintained and released according to the CentOS schedule.

![logo](https://raw.githubusercontent.com/docker-library/docs/042f2a1de0eebe3b96d43f77e84aa4aa10e378b9/clefos/logo.png)

## ClefOS image documentation

The `clefos:latest` tag is always the most recent version currently available.

### Building the Base Image

The image is built via the `make` command which will create the tarball and build the image.

The `createBase.sh` script is used to create the tarball for the docker build command. The script uses the yum command with the `tsflags=nodocs` option set to reduce the size of the image. In addition a lot of the locale files are eliminated from the image.

The `VERSION` file contains the id of the current ClefOS version and will be added as a label within the image.

### Rolling builds

The ClefOS Project offers regularly updated images for all active releases. These images will be updated monthly or as needed for emergency fixes. These rolling updates are tagged with the major version number and minor tags as well. For example, if 7.4.1708 is the most current then the build will result in `clefos:7` and `clefos:7.4.1708`. When the next minor level is available then `clefos:7` and `clefos:7.x.yymm` will be identical.

### Overlayfs and yum

Recent Docker versions support the [overlayfs](https://docs.docker.com/engine/userguide/storagedriver/overlayfs-driver/) backend, which is enabled by default on most distros supporting it from Docker 1.13 onwards. On ClefOS 7, **that backend requires yum-plugin-ovl to be installed and enabled**; while it is installed by default in recent clefos images, make it sure you retain the `plugins=1` option in `/etc/yum.conf` if you update that file; otherwise, you may encounter errors related to rpmdb checksum failure - see [Docker ticket 10180](https://github.com/docker/docker/issues/10180) for more details.

## Package documentation

By default, the ClefOS containers are built using yum's `nodocs` option, which helps reduce the size of the image. If you install a package and discover files missing, please comment out the line `tsflags=nodocs` in `/etc/yum.conf` and reinstall your package.

## Systemd integration

Systemd is not included in both the `clefos:7` and `clefos:latest` base containers, but can be created from these bases:

### Dockerfile for systemd base image

```dockerfile
FROM 		clefos:7

ENV 		container docker

RUN		yum install -y --setopt=tsflags=nodocs systemd && \
		yum clean all && \
		rm -rf /var/cache/yum/* /tmp/* /var/log/yum.log

RUN 		(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
		rm -f /lib/systemd/system/multi-user.target.wants/*;\
		rm -f /etc/systemd/system/*.wants/*;\
		rm -f /lib/systemd/system/local-fs.target.wants/*; \
		rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
		rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
		rm -f /lib/systemd/system/basic.target.wants/*;\
		rm -f /lib/systemd/system/anaconda.target.wants/*;

VOLUME 		["/sys/fs/cgroup"]

CMD 		["/usr/sbin/init"]
```

This `Dockerfile` deletes a number of unit files which might cause issues. From here, you are ready to build your base image.

```console
$ docker build --rm -t local/c7-systemd .
```

### Example systemd enabled app container

In order to use the systemd enabled base container created above, you will need to create your `Dockerfile` similar to the one below.

```dockerfile
FROM local/c7-systemd
RUN yum -y install httpd; yum clean all; systemctl enable httpd.service
EXPOSE 80
CMD ["/usr/sbin/init"]
```

Build this image:

```console
$ docker build --rm -t local/c7-systemd-httpd .
```

### Running a systemd enabled app container

In order to run a container with systemd, you will need to mount the cgroups volumes from the host. Below is an example command that will run the systemd enabled httpd container created earlier.

```console
$ docker run -ti -v /sys/fs/cgroup:/sys/fs/cgroup:ro -p 80:80 local/c7-systemd-httpd
```

This container is running with systemd in a limited context, with the cgroups filesystem mounted. There have been reports that if you're using an Ubuntu host, you will need to add `-v /tmp/$(mktemp -d):/run` in addition to the cgroups mount.

# License

View [license information](https://github.com/nealef/clefos/blob/master/LICENSE.md) for the scripts which created this image.

As with all Docker images, these likely also contain other software which may be under other licenses (such as Bash, etc from the base distribution, along with any direct or indirect dependencies of the primary software being contained).

Some additional license information which was able to be auto-detected might be found in [the `repo-info` repository's `clefos/` directory](https://github.com/docker-library/repo-info/tree/master/repos/clefos).

As for any pre-built image usage, it is the image user's responsibility to ensure that any use of this image complies with any relevant licenses for all software contained within.


text:
///#begin zh-cn
//
//  Created by ShareSDK.cn on 13-1-14.
//  官网地址:http://www.ShareSDK.cn
//  技术支持邮箱:support@sharesdk.cn
//  官方微信:ShareSDK   (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复)
//  商务QQ:4006852216
//  Copyright (c) 2013年 ShareSDK.cn. All rights reserved.
//
///#end
///#begin en
//
//  Created by ShareSDK.cn on 13-1-14.
//  website:http://www.ShareSDK.cn
//  Support E-mail:support@sharesdk.cn
//  WeChat ID:ShareSDK   (If publish a new version, we will be push the updates content of version to you. If you have any questions about the ShareSDK, you can get in touch through the WeChat with us, we will respond within 24 hours)
//  Business QQ:4006852216
//  Copyright (c) 2013年 ShareSDK.cn. All rights reserved.
//
///#end

#import <Foundation/Foundation.h>
#import <ShareSDKCoreService/ShareSDKCoreService.h>
#import "SSLinkedInUser.h"
#import "SSLinkedInErrorInfo.h"
#import "SSLinkedInCredential.h"
#import "SSLinkedInShare.h"
#import <ShareSDK/ShareSDKPlugin.h>

///#begin zh-cn
/**
 *	@brief	LinkedIn请求方式
 */
///#end
///#begin en
/**
 *	@brief	LinkedIn request method
 */
///#end
typedef enum
{
	SSLinkedInRequestMethodGet = 0, /**< GET方式 */
	SSLinkedInRequestMethodPost = 1, /**< POST方式 */
	SSLinkedInRequestMethodMultipartPost = 2 /**< Multipart POST方式,用于上传文件的api接口 */
}
SSLinkedInRequestMethod;

@protocol ISSLinkedInApp <ISSPlatformApp>

///#begin zh-cn
/**
 *	@brief	获取应用Key
 *
 *	@return	应用Key
 */
///#end
///#begin en
/**
 *	@brief	Get api key.
 *
 *	@return	Api key.
 */
///#end
- (NSString *)apiKey;

///#begin zh-cn
/**
 *	@brief	获取应用密钥
 *
 *	@return	应用密钥
 */
///#end
///#begin en
/**
 *	@brief	Get secret key.
 *
 *	@return	Secret key.
 */
///#end
- (NSString *)secretKey;

///#begin zh-cn
/**
 *	@brief	获取应用回调地址
 *
 *	@return	应用回调地址
 */
///#end
///#begin en
/**
 *	@brief	Get redirect uri.
 *
 *	@return	Redirect uri.
 */
///#end
- (NSString *)redirectUri;

///#begin zh-cn
/**
 *	@brief	调用开放平台API
 *
 *	@param 	path 	路径
 *	@param 	params 	请求参数,可以为一个ISSCParameters协议对象,也可以为一个NSDictionary对象,为NSDicationary对象时仅在以POST方式提交时有效。
 *  @param  user    授权用户,如果传入nil则表示默认的授权用户
 *  @param  result  返回回调
 *  @param  fault   失败回调
 */
///#end
///#begin en
/**
 *	@brief	Call api.
 *
 *	@param 	path 	API path string.
 *	@param 	params 	Request parameters, which can be a ISSCParameters protocol object, but also for an NSDictionary object. Be a NSDictionary object is only valid when the POST method to submit.
 *  @param  user    Authorized users, it means that if the incoming nil default authorized users
 *  @param  result  Result handler.
 *  @param  fault   Fault handler.
 */
///#end
- (void)api:(NSString *)path
     method:(SSLinkedInRequestMethod)method
     params:(id)params
       user:(id<ISSPlatformUser>)user
     result:(void(^)(id responder))result
      fault:(void(^)(CMErrorInfo *error))fault;

///#begin zh-cn
/**
 *	@brief	分享内容
 *
 *	@param 	comment 	对内容的评论
 *	@param 	title 	标题
 *	@param 	description 	内容描述
 *	@param 	url 	内容链接
 *	@param 	image 	内容图片
 *	@param 	visibility 	可见
 *  @param  result  回调方法
 */
///#end
///#begin en
/**
 *	@brief	Share content.
 *
 *	@param 	comment 	Comment text.
 *	@param 	title 	Title string.
 *	@param 	description 	Content description.
 *	@param 	url 	URL string.
 *	@param 	image 	Image URL string.
 *	@param 	visibility 	Visibility
 *  @param  result  Result handler.
 */
///#end
- (void)shareWithComment:(NSString *)comment
                   title:(NSString *)title
             description:(NSString *)description
                     url:(NSString *)url
                   image:(NSString *)image
              visibility:(NSString *)visibility
                  result:(SSShareResultEvent)result;

@end


text:
using namespace std;

class Integer
{
   private:
     int i;

   public:

   Integer();
   Integer(int);
   Integer(Integer&);
   ~Integer();

   void SetValue(int);
   int GetValue(void);
   friend ostream&
   operator << (ostream&, Integer &);

   Integer& operator++();
   Integer& operator++(int);
};


text:
package org.mycontroller.standalone.backup.mixins;

import org.mycontroller.standalone.db.tables.SensorVariable;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;

/**
 * @author Jeeva Kandasamy (jkandasa)
 * @since 1.5.0
 */

public abstract class MixinForwardPayload {

    @JsonSerialize(using = SerializerSimpleSensorVariable.class)
    public abstract SensorVariable getSource();

    @JsonSerialize(using = SerializerSimpleSensorVariable.class)
    public abstract SensorVariable getDestination();

}


text:
package de.bluebiz.bluelytics.api.query.plan.expressions.operands;

import de.bluebiz.bluelytics.api.query.plan.expressions.ExpressionNode;
import de.bluebiz.bluelytics.api.query.plan.expressions.MathOperators;
import de.bluebiz.bluelytics.api.query.plan.expressions.operands.bool.BooleanFunctionOperand;
import de.bluebiz.bluelytics.api.query.plan.expressions.operands.bool.BooleanOperand;
import de.bluebiz.bluelytics.api.query.plan.expressions.operands.numeric.NumericFunctionOperand;
import de.bluebiz.bluelytics.api.query.plan.expressions.operands.numeric.NumericOperand;
import de.bluebiz.bluelytics.api.query.plan.expressions.operands.string.StringFunctionOperand;
import de.bluebiz.bluelytics.api.query.plan.expressions.operands.string.StringOperand;
import de.bluebiz.bluelytics.api.query.plan.expressions.operands.time.TimeFunctionOperand;
import de.bluebiz.bluelytics.api.query.plan.expressions.operands.time.TimeOperand;
import de.bluebiz.bluelytics.api.query.plan.expressions.targets.NamedExpression;
import de.bluebiz.bluelytics.api.query.plan.expressions.targets.Predicate;
import de.bluebiz.bluelytics.api.query.plan.expressions.targets.PredicateRelational;
import de.bluebiz.bluelytics.api.query.plan.expressions.targets.PredicateSimple;
import de.bluebiz.bluelytics.api.query.plan.expressions.targets.RenameExpression;

/**
 * Base interface for all operands that can be used in expressions.
 */
public abstract class Operand extends ExpressionNode{

    /**
     * Create predicate predicate.
     *
     * @param operator     the operator
     * @param rightOperand the right operand
     * @return the predicate
     */
    protected Predicate createPredicate(MathOperators.Relational operator, Operand rightOperand){
        return new PredicateRelational(this, operator, rightOperand);
    }

    /**
     * Create boolean function boolean operand.
     *
     * @param operand  the operand
     * @param function the function
     * @param inputs   the inputs
     * @return the boolean operand
     */
    protected BooleanOperand createBooleanFunction(Operand operand, String function, Operand... inputs){
        return new BooleanFunctionOperand(operand, function, inputs);
    }

    /**
     * Create numeric function numeric operand.
     *
     * @param operand  the operand
     * @param function the function
     * @param inputs   the inputs
     * @return the numeric operand
     */
    protected NumericOperand createNumericFunction(Operand operand, String function, Operand... inputs){
        return new NumericFunctionOperand(operand, function, inputs);
    }

    /**
     * Create string function string operand.
     *
     * @param operand  the operand
     * @param function the function
     * @param inputs   the inputs
     * @return the string operand
     */
    protected StringOperand createStringFunction(Operand operand, String function, Operand... inputs){
        return new StringFunctionOperand(operand, function, inputs);
    }

    /**
     * Create time function time operand.
     *
     * @param operand  the operand
     * @param function the function
     * @param inputs   the inputs
     * @return the time operand
     */
    protected TimeOperand createTimeFunction(Operand operand, String function, Operand... inputs){
        return new TimeFunctionOperand(operand, function, inputs);
    }

    /**
     * Is null predicate.
     *
     * @return the predicate
     */
    public Predicate isNull(){
        BooleanOperand operand = createBooleanFunction(this, "isNull");
        return new PredicateSimple(operand);
    }

    /**
     * As named expression.
     *
     * @param alias the alias
     * @return the named expression
     */
    public NamedExpression as(String alias){
        return new NamedExpression(this, alias);
    }

    /**
     * Build rename expression rename expression.
     *
     * @param attribute the attribute
     * @param alias     the alias
     * @return the rename expression
     */
    protected RenameExpression buildRenameExpression(AttributeOperand<?> attribute, String alias) {
        return new RenameExpression(attribute, alias);
    }
}


text:
	<title>Aden Ridgeway's panel show appearances</title>

	<link rel="stylesheet" media="all" href="../style.css" type="text/css"/>

Aden Ridgeway's panel show appearances

Aden Ridgeway (born 1962-09-18[ref]) has appeared in 1 episodes between 1999-1999.  Aden Ridgeway on Wikipedia.

1999

1999-10-14 / Question Time


text:
title: Hablemos de Shenmue
header:
  overlay_image: /img/2011/12/Shen1Noti12.jpg
layout: single
categories:
- Colaboraciones
- Shenmue
tags:
- Shenmue
- Shenmue I
---
Bueno, ahora que TWEWY ha tenido su ración de publicidad (¡2500 visualizaciones
del vídeo, muchísimas gracias!), pero pocas descargas (A los piratas les importa
un bledo); va siendo hora de hablar del siguiente proyecto.

Shenmue I para Dreamcast.

Ya está, ya lo he soltado. A partir de ahora intentaré dar más mensajes sobre el
estado de mis traducciones, pero es hora de dar un repasito general por todo lo
que ha pasado este nuevo proyecto.

Para empezar, no empezó siendo mío pero he acabado llevándolo yo. Allá por 2008,
Ryo Suzuki, administrador de SegaSaturno.com,
comenzó la versión definitiva de la traducción al Castellano (Recordemos que hace
diez años salió una, pero hecha de forma casera; esta se ha hecho con las herramientas
del grupo francés ShenmueSubs
de Shenmue I, que dan bastante poder sobre el juego)

Cuando le conocí, creo que a finales de 2009, le ofrecí mi ayuda y me pasó lo que
tenía, había traducido todas las escenas del disco 1, y un buen cacho del Free Quest
(Los NPC que hay por las calles). Avanzaba firme pero seguro, y yo comencé a traducirle
los gráficos, y los subtítulos de los discos 2 y 3.

Llegué a un punto en el que yo había traducido por completo todo el escenario del puerto;
revisadas las cutscenes del disco 1, y traducidas las del 2, 3, e incluso las cabezas
del Passport.

Fue pasando el tiempo, y por suerte para él, Ryo estaba más ocupado con su trabajo,
y acabó abriendo una tienda nueva que consumía todo su tiempo. Así que durante un
tiempo, quizás un año o más, el proyecto quedó parado.

Yo por otro lado me acabé enfrascando en otros proyectos, los cuales los tenéis aquí
presentes: Dead Space, Project Zero 4 y Fragile Dreams de Wii, Time Crisis de PSOne o The
3rd Birthday para PSP. Pero veía el montón de traducciones a medias que tenía pendientes
y tomé una decisión: dejaría de tomar traducciones nuevas, y me centraría en acabar mis
asuntos pendientes, que son demasiados.

El primer asunto pendiente en caer fue The World Ends With You, pendiente también
desde 2008. El siguiente lo veréis ahora.

Ya que Ryo está ocupadísimo con su vida laboral, he conseguido que me de permiso no solo
para terminarle el trabajo, sino para buscar a más personas que pudieran ayudarme a
revisarlo, gente externa pero conocida de otros proyectos que puedan dar un vistazo a todo
lo que hay, que es un porrón.

A día de hoy, las cosas están así:

**- GRÁFICOS: 100% traducidos, incluyendo mapas del mundo, las hojas de trabajo, y todo lo
que tenga texto y se pueda traducir.**
**- TEXTOS: 100% de las escenas cinemáticas del juego, 70% del Free Quest en total, 0% del
ejecutable del juego (El diario de Ryo y tal, eso irá para el final).**

Yo calculo que para navidades podría estar todo ya traducido, a la espera de que estas
personas externas puedan darle el repaso final. De momento ya debo darle las gracias a
Pacochan por adaptar el trabajo de Ryo sobre el FREE del disco 1 a un formato más manejable;
y a Indiket y Neoblast de Dreamcast.es por su más que
valiosa ayuda en más de un aspecto.

Y me guardo una sorpresilla para el final; intentaré dejarlo críptico (Esto va por quien yo
me sé): ¿Recordáis la inocentada del año pasado? Esa escena ha dejado de serlo.

A ver si puedo poner capturas de pantalla conforme pasen los días.


text:
/**
 * The battery reading job. Reads the iAQ CO2 sensor every
 * IAQ_UPDATE_INTERVAL seconds and updates the internal cache with the
 * value.
 */
#ifndef IAQ_JOB_H
#define IAQ_JOB_H

/**
 * Read interval for battery. Set to something lower if you want more
 * samples.
 */
#define IAQ_UPDATE_INTERVAL 10

/**
 * Initialize SAADC and start battery reading job.
 */
void iaq_job_init(void);

#endif


text:
package loadbalancers

import (
	"fmt"
	"testing"

	compute "google.golang.org/api/compute/v1"
	"k8s.io/ingress/controllers/gce/backends"
	"k8s.io/ingress/controllers/gce/healthchecks"
	"k8s.io/ingress/controllers/gce/instances"
	"k8s.io/ingress/controllers/gce/utils"
	"k8s.io/kubernetes/pkg/util/sets"
)

const (
	testDefaultBeNodePort = int64(3000)
	defaultZone           = "zone-a"
)

func newFakeLoadBalancerPool(f LoadBalancers, t *testing.T) LoadBalancerPool {
	fakeBackends := backends.NewFakeBackendServices(func(op int, be *compute.BackendService) error { return nil })
	fakeIGs := instances.NewFakeInstanceGroups(sets.NewString())
	fakeHCs := healthchecks.NewFakeHealthChecks()
	namer := &utils.Namer{}
	healthChecker := healthchecks.NewHealthChecker(fakeHCs, "/", namer)
	healthChecker.Init(&healthchecks.FakeHealthCheckGetter{})
	nodePool := instances.NewNodePool(fakeIGs)
	nodePool.Init(&instances.FakeZoneLister{Zones: []string{defaultZone}})
	backendPool := backends.NewBackendPool(
		fakeBackends, healthChecker, nodePool, namer, []int64{}, false)
	return NewLoadBalancerPool(f, backendPool, testDefaultBeNodePort, namer)
}

func TestCreateHTTPLoadBalancer(t *testing.T) {
	// This should NOT create the forwarding rule and target proxy
	// associated with the HTTPS branch of this loadbalancer.
	lbInfo := &L7RuntimeInfo{Name: "test", AllowHTTP: true}
	f := NewFakeLoadBalancers(lbInfo.Name)
	pool := newFakeLoadBalancerPool(f, t)
	pool.Sync([]*L7RuntimeInfo{lbInfo})
	l7, err := pool.Get(lbInfo.Name)
	if err != nil || l7 == nil {
		t.Fatalf("Expected l7 not created")
	}
	um, err := f.GetUrlMap(f.umName())
	if err != nil ||
		um.DefaultService != pool.(*L7s).glbcDefaultBackend.SelfLink {
		t.Fatalf("%v", err)
	}
	tp, err := f.GetTargetHttpProxy(f.tpName(false))
	if err != nil || tp.UrlMap != um.SelfLink {
		t.Fatalf("%v", err)
	}
	fw, err := f.GetGlobalForwardingRule(f.fwName(false))
	if err != nil || fw.Target != tp.SelfLink {
		t.Fatalf("%v", err)
	}
}

func TestCreateHTTPSLoadBalancer(t *testing.T) {
	// This should NOT create the forwarding rule and target proxy
	// associated with the HTTP branch of this loadbalancer.
	lbInfo := &L7RuntimeInfo{
		Name:      "test",
		AllowHTTP: false,
		TLS:       &TLSCerts{Key: "key", Cert: "cert"},
	}
	f := NewFakeLoadBalancers(lbInfo.Name)
	pool := newFakeLoadBalancerPool(f, t)
	pool.Sync([]*L7RuntimeInfo{lbInfo})
	l7, err := pool.Get(lbInfo.Name)
	if err != nil || l7 == nil {
		t.Fatalf("Expected l7 not created")
	}
	um, err := f.GetUrlMap(f.umName())
	if err != nil ||
		um.DefaultService != pool.(*L7s).glbcDefaultBackend.SelfLink {
		t.Fatalf("%v", err)
	}
	tps, err := f.GetTargetHttpsProxy(f.tpName(true))
	if err != nil || tps.UrlMap != um.SelfLink {
		t.Fatalf("%v", err)
	}
	fws, err := f.GetGlobalForwardingRule(f.fwName(true))
	if err != nil || fws.Target != tps.SelfLink {
		t.Fatalf("%v", err)
	}
}

func TestCreateHTTPSLoadBalancerAnnotationCert(t *testing.T) {
	// This should NOT create the forwarding rule and target proxy
	// associated with the HTTP branch of this loadbalancer.
	tlsName := "external-cert-name"
	lbInfo := &L7RuntimeInfo{
		Name:      "test",
		AllowHTTP: false,
		TLSName:   tlsName,
	}
	f := NewFakeLoadBalancers(lbInfo.Name)
	f.CreateSslCertificate(&compute.SslCertificate{
		Name: tlsName,
	})
	pool := newFakeLoadBalancerPool(f, t)
	pool.Sync([]*L7RuntimeInfo{lbInfo})
	l7, err := pool.Get(lbInfo.Name)
	if err != nil || l7 == nil {
		t.Fatalf("Expected l7 not created")
	}
	um, err := f.GetUrlMap(f.umName())
	if err != nil ||
		um.DefaultService != pool.(*L7s).glbcDefaultBackend.SelfLink {
		t.Fatalf("%v", err)
	}
	tps, err := f.GetTargetHttpsProxy(f.tpName(true))
	if err != nil || tps.UrlMap != um.SelfLink {
		t.Fatalf("%v", err)
	}
	fws, err := f.GetGlobalForwardingRule(f.fwName(true))
	if err != nil || fws.Target != tps.SelfLink {
		t.Fatalf("%v", err)
	}
}

func TestCreateBothLoadBalancers(t *testing.T) {
	// This should create 2 forwarding rules and target proxies
	// but they should use the same urlmap, and have the same
	// static ip.
	lbInfo := &L7RuntimeInfo{
		Name:      "test",
		AllowHTTP: true,
		TLS:       &TLSCerts{Key: "key", Cert: "cert"},
	}
	f := NewFakeLoadBalancers(lbInfo.Name)
	pool := newFakeLoadBalancerPool(f, t)
	pool.Sync([]*L7RuntimeInfo{lbInfo})
	l7, err := pool.Get(lbInfo.Name)
	if err != nil || l7 == nil {
		t.Fatalf("Expected l7 not created")
	}
	um, err := f.GetUrlMap(f.umName())
	if err != nil ||
		um.DefaultService != pool.(*L7s).glbcDefaultBackend.SelfLink {
		t.Fatalf("%v", err)
	}
	tps, err := f.GetTargetHttpsProxy(f.tpName(true))
	if err != nil || tps.UrlMap != um.SelfLink {
		t.Fatalf("%v", err)
	}
	tp, err := f.GetTargetHttpProxy(f.tpName(false))
	if err != nil || tp.UrlMap != um.SelfLink {
		t.Fatalf("%v", err)
	}
	fws, err := f.GetGlobalForwardingRule(f.fwName(true))
	if err != nil || fws.Target != tps.SelfLink {
		t.Fatalf("%v", err)
	}
	fw, err := f.GetGlobalForwardingRule(f.fwName(false))
	if err != nil || fw.Target != tp.SelfLink {
		t.Fatalf("%v", err)
	}
	ip, err := f.GetGlobalStaticIP(f.fwName(false))
	if err != nil || ip.Address != fw.IPAddress || ip.Address != fws.IPAddress {
		t.Fatalf("%v", err)
	}
}

func TestUpdateUrlMap(t *testing.T) {
	um1 := utils.GCEURLMap{
		"bar.example.com": {
			"/bar2": &compute.BackendService{SelfLink: "bar2svc"},
		},
	}
	um2 := utils.GCEURLMap{
		"foo.example.com": {
			"/foo1": &compute.BackendService{SelfLink: "foo1svc"},
			"/foo2": &compute.BackendService{SelfLink: "foo2svc"},
		},
		"bar.example.com": {
			"/bar1": &compute.BackendService{SelfLink: "bar1svc"},
		},
	}
	um2.PutDefaultBackend(&compute.BackendService{SelfLink: "default"})

	lbInfo := &L7RuntimeInfo{Name: "test", AllowHTTP: true}
	f := NewFakeLoadBalancers(lbInfo.Name)
	pool := newFakeLoadBalancerPool(f, t)
	pool.Sync([]*L7RuntimeInfo{lbInfo})
	l7, err := pool.Get(lbInfo.Name)
	if err != nil {
		t.Fatalf("%v", err)
	}
	for _, ir := range []utils.GCEURLMap{um1, um2} {
		if err := l7.UpdateUrlMap(ir); err != nil {
			t.Fatalf("%v", err)
		}
	}
	// The final map doesn't contain /bar2
	expectedMap := map[string]utils.FakeIngressRuleValueMap{
		utils.DefaultBackendKey: {
			utils.DefaultBackendKey: "default",
		},
		"foo.example.com": {
			"/foo1": "foo1svc",
			"/foo2": "foo2svc",
		},
		"bar.example.com": {
			"/bar1": "bar1svc",
		},
	}
	f.CheckURLMap(t, l7, expectedMap)
}

func TestUpdateUrlMapNoChanges(t *testing.T) {
	um1 := utils.GCEURLMap{
		"foo.example.com": {
			"/foo1": &compute.BackendService{SelfLink: "foo1svc"},
			"/foo2": &compute.BackendService{SelfLink: "foo2svc"},
		},
		"bar.example.com": {
			"/bar1": &compute.BackendService{SelfLink: "bar1svc"},
		},
	}
	um1.PutDefaultBackend(&compute.BackendService{SelfLink: "default"})
	um2 := utils.GCEURLMap{
		"foo.example.com": {
			"/foo1": &compute.BackendService{SelfLink: "foo1svc"},
			"/foo2": &compute.BackendService{SelfLink: "foo2svc"},
		},
		"bar.example.com": {
			"/bar1": &compute.BackendService{SelfLink: "bar1svc"},
		},
	}
	um2.PutDefaultBackend(&compute.BackendService{SelfLink: "default"})

	lbInfo := &L7RuntimeInfo{Name: "test", AllowHTTP: true}
	f := NewFakeLoadBalancers(lbInfo.Name)
	pool := newFakeLoadBalancerPool(f, t)
	pool.Sync([]*L7RuntimeInfo{lbInfo})
	l7, err := pool.Get(lbInfo.Name)
	if err != nil {
		t.Fatalf("%v", err)
	}
	for _, ir := range []utils.GCEURLMap{um1, um2} {
		if err := l7.UpdateUrlMap(ir); err != nil {
			t.Fatalf("%v", err)
		}
	}
	for _, call := range f.calls {
		if call == "UpdateUrlMap" {
			t.Errorf("UpdateUrlMap() should not have been called")
		}
	}
}

func TestNameParsing(t *testing.T) {
	clusterName := "123"
	firewallName := clusterName
	namer := utils.NewNamer(clusterName, firewallName)
	fullName := namer.Truncate(fmt.Sprintf("%v-%v", forwardingRulePrefix, namer.LBName("testlb")))
	annotationsMap := map[string]string{
		fmt.Sprintf("%v/forwarding-rule", utils.K8sAnnotationPrefix): fullName,
	}
	components := namer.ParseName(GCEResourceName(annotationsMap, "forwarding-rule"))
	t.Logf("%+v", components)
	if components.ClusterName != clusterName {
		t.Errorf("Failed to parse cluster name from %v, expected %v got %v", fullName, clusterName, components.ClusterName)
	}
	resourceName := "fw"
	if components.Resource != resourceName {
		t.Errorf("Failed to parse resource from %v, expected %v got %v", fullName, resourceName, components.Resource)
	}
}

func TestClusterNameChange(t *testing.T) {
	lbInfo := &L7RuntimeInfo{
		Name: "test",
		TLS:  &TLSCerts{Key: "key", Cert: "cert"},
	}
	f := NewFakeLoadBalancers(lbInfo.Name)
	pool := newFakeLoadBalancerPool(f, t)
	pool.Sync([]*L7RuntimeInfo{lbInfo})
	l7, err := pool.Get(lbInfo.Name)
	if err != nil || l7 == nil {
		t.Fatalf("Expected l7 not created")
	}
	um, err := f.GetUrlMap(f.umName())
	if err != nil ||
		um.DefaultService != pool.(*L7s).glbcDefaultBackend.SelfLink {
		t.Fatalf("%v", err)
	}
	tps, err := f.GetTargetHttpsProxy(f.tpName(true))
	if err != nil || tps.UrlMap != um.SelfLink {
		t.Fatalf("%v", err)
	}
	fws, err := f.GetGlobalForwardingRule(f.fwName(true))
	if err != nil || fws.Target != tps.SelfLink {
		t.Fatalf("%v", err)
	}
	newName := "newName"
	namer := pool.(*L7s).namer
	namer.SetClusterName(newName)
	f.name = fmt.Sprintf("%v--%v", lbInfo.Name, newName)

	// Now the components should get renamed with the next suffix.
	pool.Sync([]*L7RuntimeInfo{lbInfo})
	l7, err = pool.Get(lbInfo.Name)
	if err != nil || namer.ParseName(l7.Name).ClusterName != newName {
		t.Fatalf("Expected L7 name to change.")
	}
	um, err = f.GetUrlMap(f.umName())
	if err != nil || namer.ParseName(um.Name).ClusterName != newName {
		t.Fatalf("Expected urlmap name to change.")
	}
	if err != nil ||
		um.DefaultService != pool.(*L7s).glbcDefaultBackend.SelfLink {
		t.Fatalf("%v", err)
	}

	tps, err = f.GetTargetHttpsProxy(f.tpName(true))
	if err != nil || tps.UrlMap != um.SelfLink {
		t.Fatalf("%v", err)
	}
	fws, err = f.GetGlobalForwardingRule(f.fwName(true))
	if err != nil || fws.Target != tps.SelfLink {
		t.Fatalf("%v", err)
	}
}

func TestInvalidClusterNameChange(t *testing.T) {
	namer := utils.NewNamer("test--123", "test--123")
	if got := namer.GetClusterName(); got != "123" {
		t.Fatalf("Expected name 123, got %v", got)
	}
	// A name with `--` should take the last token
	for _, testCase := range []struct{ newName, expected string }{
		{"foo--bar", "bar"},
		{"--", ""},
		{"", ""},
		{"foo--bar--com", "com"},
	} {
		namer.SetClusterName(testCase.newName)
		if got := namer.GetClusterName(); got != testCase.expected {
			t.Fatalf("Expected %q got %q", testCase.expected, got)
		}
	}

}


text:
using System.Collections.Generic;
using System.Text.Json;
using Azure.Core;

namespace Azure.ResourceManager.ServiceFabricManagedClusters.Models
{
    internal partial class VmManagedIdentity : IUtf8JsonSerializable
    {
        void IUtf8JsonSerializable.Write(Utf8JsonWriter writer)
        {
            writer.WriteStartObject();
            if (Optional.IsCollectionDefined(UserAssignedIdentities))
            {
                writer.WritePropertyName("userAssignedIdentities");
                writer.WriteStartArray();
                foreach (var item in UserAssignedIdentities)
                {
                    writer.WriteStringValue(item);
                }
                writer.WriteEndArray();
            }
            writer.WriteEndObject();
        }

        internal static VmManagedIdentity DeserializeVmManagedIdentity(JsonElement element)
        {
            Optional<IList<ResourceIdentifier>> userAssignedIdentities = default;
            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("userAssignedIdentities"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    List<ResourceIdentifier> array = new List<ResourceIdentifier>();
                    foreach (var item in property.Value.EnumerateArray())
                    {
                        array.Add(new ResourceIdentifier(item.GetString()));
                    }
                    userAssignedIdentities = array;
                    continue;
                }
            }
            return new VmManagedIdentity(Optional.ToList(userAssignedIdentities));
        }
    }
}


text:
cask "coscreen" do
  version "3.9.42"
  sha256 "c2cc8bc0d68e4ac27926092bbb0dd7e080d9a015578c5b7b5b3996e481b8f0cb"

  url "https://update.coscreen.org/CoScreen-#{version}-stable.dmg",
      verified: "https://update.coscreen.org/"
  name "CoScreen"
  desc "Collaboration tool with multi-user screen sharing"
  homepage "https://www.coscreen.co/"

  livecheck do
    url "https://update.coscreen.org/stable-mac.yml"
    strategy :electron_builder
  end

  auto_updates true
  depends_on macos: ">= :mojave"

  app "CoScreen.app"

  zap trash: [
    "~/Library/Application Support/CoScreen",
    "~/Library/Logs/CoScreen",
    "~/Library/Preferences/org.coscreen.CoScreen.plist",
    "~/Library/Saved Application State/org.coscreen.CoScreen.savedState",
  ]
end


text:
/**
 * @fileoverview Build file
 * @author nzakas
 */

/* global cat, cd, cp, echo, exec, exit, find, ls, mkdir, pwd, rm, target, test*/
/* eslint no-use-before-define: "off", no-console: "off" */
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

require("shelljs/make");

const lodash = require("lodash"),
    checker = require("npm-license"),
    ReleaseOps = require("eslint-release"),
    dateformat = require("dateformat"),
    fs = require("fs"),
    glob = require("glob"),
    markdownlint = require("markdownlint"),
    nodeCLI = require("shelljs-nodecli"),
    os = require("os"),
    path = require("path"),
    semver = require("semver"),
    ejs = require("ejs"),
    loadPerf = require("load-perf"),
    yaml = require("js-yaml");

//------------------------------------------------------------------------------
// Settings
//------------------------------------------------------------------------------

/*
 * A little bit fuzzy. My computer has a first CPU speed of 3392 and the perf test
 * always completes in < 3800ms. However, Travis is less predictable due to
 * multiple different VM types. So I'm fudging this for now in the hopes that it
 * at least provides some sort of useful signal.
 */
const PERF_MULTIPLIER = 13e6;

const OPEN_SOURCE_LICENSES = [
    /MIT/, /BSD/, /Apache/, /ISC/, /WTF/, /Public Domain/
];

//------------------------------------------------------------------------------
// Data
//------------------------------------------------------------------------------

const NODE = "node ", // intentional extra space
    NODE_MODULES = "./node_modules/",
    TEMP_DIR = "./tmp/",
    BUILD_DIR = "./build/",
    DOCS_DIR = "../eslint.github.io/docs",
    SITE_DIR = "../eslint.github.io/",
    PERF_TMP_DIR = path.join(os.tmpdir(), "eslint", "performance"),

    // Utilities - intentional extra space at the end of each string
    MOCHA = NODE_MODULES + "mocha/bin/_mocha ",
    ESLINT = NODE + " bin/eslint.js --rulesdir lib/internal-rules/ ",

    // Files
    MAKEFILE = "./Makefile.js",
    JS_FILES = "lib/**/*.js conf/**/*.js",
    JSON_FILES = find("conf/").filter(fileType("json")),
    MARKDOWN_FILES_ARRAY = find("docs/").concat(ls(".")).filter(fileType("md")),
    TEST_FILES = getTestFilePatterns(),
    PERF_ESLINTRC = path.join(PERF_TMP_DIR, "eslintrc.yml"),
    PERF_MULTIFILES_TARGET_DIR = path.join(PERF_TMP_DIR, "eslint"),
    PERF_MULTIFILES_TARGETS = PERF_MULTIFILES_TARGET_DIR + path.sep + "{lib,tests" + path.sep + "lib}" + path.sep + "**" + path.sep + "*.js",

    // Regex
    TAG_REGEX = /^(?:Breaking|Build|Chore|Docs|Fix|New|Update|Upgrade):/,
    ISSUE_REGEX = /\((?:fixes|refs) #\d+(?:.*(?:fixes|refs) #\d+)*\)$/,

    // Settings
    MOCHA_TIMEOUT = 10000;

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

/**
 * Generates file patterns for test files
 * @returns {string} test file patterns
 * @private
 */
function getTestFilePatterns() {
    const testLibPath = "tests/lib/",
        testTemplatesPath = "tests/templates/";

    return ls(testLibPath).filter(function(pathToCheck) {
        return test("-d", testLibPath + pathToCheck);
    }).reduce(function(initialValue, currentValues) {
        if (currentValues !== "rules") {
            initialValue.push(testLibPath + currentValues + "/**/*.js");
        }
        return initialValue;
    }, [testLibPath + "rules/**/*.js", testLibPath + "*.js", testTemplatesPath + "*.js"]).join(" ");
}

/**
 * Simple JSON file validation that relies on ES JSON parser.
 * @param {string} filePath Path to JSON.
 * @throws Error If file contents is invalid JSON.
 * @returns {undefined}
 */
function validateJsonFile(filePath) {
    const contents = fs.readFileSync(filePath, "utf8");

    JSON.parse(contents);
}

/**
 * Generates a function that matches files with a particular extension.
 * @param {string} extension The file extension (i.e. "js")
 * @returns {Function} The function to pass into a filter method.
 * @private
 */
function fileType(extension) {
    return function(filename) {
        return filename.substring(filename.lastIndexOf(".") + 1) === extension;
    };
}

/**
 * Generates a static file that includes each rule by name rather than dynamically
 * looking up based on directory. This is used for the browser version of ESLint.
 * @param {string} basedir The directory in which to look for code.
 * @returns {void}
 */
function generateRulesIndex(basedir) {
    let output = "module.exports = function() {\n";

    output += "    var rules = Object.create(null);\n";

    find(basedir + "rules/").filter(fileType("js")).forEach(function(filename) {
        const basename = path.basename(filename, ".js");

        output += "    rules[\"" + basename + "\"] = require(\"./rules/" + basename + "\");\n";
    });

    output += "\n    return rules;\n};";
    output.to(basedir + "load-rules.js");
}

/**
 * Executes a command and returns the output instead of printing it to stdout.
 * @param {string} cmd The command string to execute.
 * @returns {string} The result of the executed command.
 */
function execSilent(cmd) {
    return exec(cmd, { silent: true }).output;
}

/**
 * Generates a release blog post for eslint.org
 * @param {Object} releaseInfo The release metadata.
 * @returns {void}
 * @private
 */
function generateBlogPost(releaseInfo) {
    const output = ejs.render(cat("./templates/blogpost.md.ejs"), releaseInfo),
        now = new Date(),
        month = now.getMonth() + 1,
        day = now.getDate(),
        filename = "../eslint.github.io/_posts/" + now.getFullYear() + "-" +
            (month < 10 ? "0" + month : month) + "-" +
            (day < 10 ? "0" + day : day) + "-eslint-v" + releaseInfo.version +
            "-released.md";

    output.to(filename);
}

/**
 * Generates a doc page with formatter result examples
 * @param  {Object} formatterInfo Linting results from each formatter
 * @param  {string} [prereleaseVersion] The version used for a prerelease. This
 *      changes where the output is stored.
 * @returns {void}
 */
function generateFormatterExamples(formatterInfo, prereleaseVersion) {
    const output = ejs.render(cat("./templates/formatter-examples.md.ejs"), formatterInfo);
    let filename = "../eslint.github.io/docs/user-guide/formatters/index.md",
        htmlFilename = "../eslint.github.io/docs/user-guide/formatters/html-formatter-example.html";

    if (prereleaseVersion) {
        filename = filename.replace("/docs", "/docs/" + prereleaseVersion);
        htmlFilename = htmlFilename.replace("/docs", "/docs/" + prereleaseVersion);
    }

    output.to(filename);
    formatterInfo.formatterResults.html.result.to(htmlFilename);
}

/**
 * Generate a doc page that lists all of the rules and links to them
 * @param {string} basedir The directory in which to look for code.
 * @returns {void}
 */
function generateRuleIndexPage(basedir) {
    const outputFile = "../eslint.github.io/_data/rules.yml",
        categoryList = "conf/category-list.json",
        categoriesData = JSON.parse(cat(path.resolve(categoryList)));

    find(path.join(basedir, "/lib/rules/")).filter(fileType("js")).forEach(function(filename) {
        const rule = require(filename);
        const basename = path.basename(filename, ".js");

        if (rule.meta.deprecated) {
            categoriesData.deprecated.rules.push({
                name: basename,
                replacedBy: rule.meta.docs.replacedBy
            });
        } else {
            const output = {
                    name: basename,
                    description: rule.meta.docs.description,
                    recommended: rule.meta.docs.recommended || false,
                    fixable: !!rule.meta.fixable
                },
                category = lodash.find(categoriesData.categories, {name: rule.meta.docs.category});

            if (!category.rules) {
                category.rules = [];
            }

            category.rules.push(output);
        }
    });

    const output = yaml.safeDump(categoriesData, {sortKeys: true});

    output.to(outputFile);
}

/**
 * Creates a release version tag and pushes to origin.
 * @param {boolean} [ciRelease] Set to true to indicate this is a CI release.
 * @returns {void}
 */
function release(ciRelease) {

    const releaseInfo = ReleaseOps.release(null, ciRelease);

    echo("Generating site");
    target.gensite();
    generateBlogPost(releaseInfo);
    target.publishsite();

    echo("Site has been published");
}

/**
 * Creates a prerelease version tag and pushes to origin.
 * @param {string} prereleaseId The prerelease identifier (alpha, beta, etc.)
 * @returns {void}
 */
function prerelease(prereleaseId) {

    const releaseInfo = ReleaseOps.release(prereleaseId);

    echo("Generating site");

    // always write docs into the next major directory (so 2.0.0-alpha.0 writes to 2.0.0)
    target.gensite(semver.inc(releaseInfo.version, "major"));
    generateBlogPost(releaseInfo);
    echo("Site has not been pushed, please update blog post and push manually.");
}

/**
 * Splits a command result to separate lines.
 * @param {string} result The command result string.
 * @returns {array} The separated lines.
 */
function splitCommandResultToLines(result) {
    return result.trim().split("\n");
}

/**
 * Gets the first commit sha of the given file.
 * @param {string} filePath The file path which should be checked.
 * @returns {string} The commit sha.
 */
function getFirstCommitOfFile(filePath) {
    let commits = execSilent("git rev-list HEAD -- " + filePath);

    commits = splitCommandResultToLines(commits);
    return commits[commits.length - 1].trim();
}

/**
 * Gets the tag name where a given file was introduced first.
 * @param {string} filePath The file path to check.
 * @returns {string} The tag name.
 */
function getTagOfFirstOccurrence(filePath) {
    const firstCommit = getFirstCommitOfFile(filePath);
    let tags = execSilent("git tag --contains " + firstCommit);

    tags = splitCommandResultToLines(tags);
    return tags.reduce(function(list, version) {
        version = semver.valid(version.trim());
        if (version) {
            list.push(version);
        }
        return list;
    }, []).sort(semver.compare)[0];
}

/**
 * Gets the version number where a given file was introduced first.
 * @param {string} filePath The file path to check.
 * @returns {string} The version number.
 */
function getFirstVersionOfFile(filePath) {
    return getTagOfFirstOccurrence(filePath);
}

/**
 * Gets the commit that deleted a file.
 * @param {string} filePath The path to the deleted file.
 * @returns {string} The commit sha.
 */
function getCommitDeletingFile(filePath) {
    const commits = execSilent("git rev-list HEAD -- " + filePath);

    return splitCommandResultToLines(commits)[0];
}

/**
 * Gets the first version number where a given file is no longer present.
 * @param {string} filePath The path to the deleted file.
 * @returns {string} The version number.
 */
function getFirstVersionOfDeletion(filePath) {
    const deletionCommit = getCommitDeletingFile(filePath),
        tags = execSilent("git tag --contains " + deletionCommit);

    return splitCommandResultToLines(tags)
        .map(function(version) {
            return semver.valid(version.trim());
        })
        .filter(function(version) {
            return version;
        })
        .sort(semver.compare)[0];
}

/**
 * Returns all the branch names
 * @returns {string[]} branch names
 * @private
 */
function getBranches() {
    const branchesRaw = splitCommandResultToLines(execSilent("git branch --list")),
        branches = [];

    for (let i = 0; i < branchesRaw.length; i++) {
        const branchName = branchesRaw[i].replace(/^\*(.*)/, "$1").trim();

        branches.push(branchName);
    }
    return branches;
}

/**
 * Lints Markdown files.
 * @param {array} files Array of file names to lint.
 * @returns {Object} exec-style exit code object.
 * @private
 */
function lintMarkdown(files) {
    const config = {
            default: true,

            // Exclusions for deliberate/widespread violations
            MD001: false, // Header levels should only increment by one level at a time
            MD002: false, // First header should be a h1 header
            MD007: {      // Unordered list indentation
                indent: 4
            },
            MD012: false, // Multiple consecutive blank lines
            MD013: false, // Line length
            MD014: false, // Dollar signs used before commands without showing output
            MD019: false, // Multiple spaces after hash on atx style header
            MD021: false, // Multiple spaces inside hashes on closed atx style header
            MD024: false, // Multiple headers with the same content
            MD026: false, // Trailing punctuation in header
            MD029: false, // Ordered list item prefix
            MD030: false, // Spaces after list markers
            MD033: false, // Allow inline HTML
            MD034: false, // Bare URL used
            MD040: false, // Fenced code blocks should have a language specified
            MD041: false  // First line in file should be a top level header
        },
        result = markdownlint.sync({
            files,
            config
        }),
        resultString = result.toString(),
        returnCode = resultString ? 1 : 0;

    if (resultString) {
        console.error(resultString);
    }
    return { code: returnCode };
}

/**
 * Check if the branch name is valid
 * @param {string} branchName Branch name to check
 * @returns {boolean} true is branch exists
 * @private
 */
function hasBranch(branchName) {
    const branches = getBranches();

    return branches.indexOf(branchName) !== -1;
}

/**
 * Gets linting results from every formatter, based on a hard-coded snippet and config
 * @returns {Object} Output from each formatter
 */
function getFormatterResults() {
    const CLIEngine = require("./lib/cli-engine"),
        chalk = require("chalk");

    const formatterFiles = fs.readdirSync("./lib/formatters/"),
        cli = new CLIEngine({
            useEslintrc: false,
            baseConfig: { extends: "eslint:recommended" },
            rules: {
                "no-else-return": 1,
                indent: [1, 4],
                "space-unary-ops": 2,
                semi: [1, "always"],
                "consistent-return": 2
            }
        }),
        codeString = [
            "function addOne(i) {",
            "    if (i != NaN) {",
            "        return i ++",
            "    } else {",
            "      return",
            "    }",
            "};"
        ].join("\n"),
        rawMessages = cli.executeOnText(codeString, "fullOfProblems.js", true);

    return formatterFiles.reduce(function(data, filename) {
        const fileExt = path.extname(filename),
            name = path.basename(filename, fileExt);

        if (fileExt === ".js") {
            data.formatterResults[name] = {
                result: chalk.stripColor(cli.getFormatter(name)(rawMessages.results))
            };
        }
        return data;
    }, { formatterResults: {} });
}

//------------------------------------------------------------------------------
// Tasks
//------------------------------------------------------------------------------

target.all = function() {
    target.test();
};

target.lint = function() {
    let errors = 0,
        makeFileCache = " ",
        jsCache = " ",
        testCache = " ",
        lastReturn;

    // using the cache locally to speed up linting process
    if (!process.env.TRAVIS) {
        makeFileCache = " --cache --cache-file .cache/makefile_cache ";
        jsCache = " --cache --cache-file .cache/js_cache ";
        testCache = " --cache --cache-file .cache/test_cache ";
    }

    echo("Validating Makefile.js");
    lastReturn = exec(ESLINT + makeFileCache + MAKEFILE);
    if (lastReturn.code !== 0) {
        errors++;
    }

    echo("Validating JSON Files");
    lodash.forEach(JSON_FILES, validateJsonFile);

    echo("Validating Markdown Files");
    lastReturn = lintMarkdown(MARKDOWN_FILES_ARRAY);
    if (lastReturn.code !== 0) {
        errors++;
    }

    echo("Validating JavaScript files");
    lastReturn = exec(ESLINT + jsCache + JS_FILES);
    if (lastReturn.code !== 0) {
        errors++;
    }

    echo("Validating JavaScript test files");
    lastReturn = exec(ESLINT + testCache + TEST_FILES);
    if (lastReturn.code !== 0) {
        errors++;
    }

    if (errors) {
        exit(1);
    }
};

target.test = function() {
    target.lint();
    target.checkRuleFiles();
    let errors = 0,
        lastReturn;

    // exec(ISTANBUL + " cover " + MOCHA + "-- -c " + TEST_FILES);
    lastReturn = nodeCLI.exec("istanbul", "cover", MOCHA, "-- -R progress -t " + MOCHA_TIMEOUT, "-c", TEST_FILES);
    if (lastReturn.code !== 0) {
        errors++;
    }

    // exec(ISTANBUL + "check-coverage --statement 99 --branch 98 --function 99 --lines 99");
    lastReturn = nodeCLI.exec("istanbul", "check-coverage", "--statement 99 --branch 98 --function 99 --lines 99");
    if (lastReturn.code !== 0) {
        errors++;
    }

    target.browserify();

    lastReturn = nodeCLI.exec("karma", "start karma.conf.js");
    if (lastReturn.code !== 0) {
        errors++;
    }

    if (errors) {
        exit(1);
    }

    target.checkLicenses();
};

target.docs = function() {
    echo("Generating documentation");
    nodeCLI.exec("jsdoc", "-d jsdoc lib");
    echo("Documentation has been output to /jsdoc");
};

target.gensite = function(prereleaseVersion) {
    echo("Generating eslint.org");

    let docFiles = [
        "/rules/",
        "/user-guide/",
        "/maintainer-guide/",
        "/developer-guide/",
        "/about/"
    ];

    // append version
    if (prereleaseVersion) {
        docFiles = docFiles.map(function(docFile) {
            return "/" + prereleaseVersion + docFile;
        });
    }

    // 1. create temp and build directory
    if (!test("-d", TEMP_DIR)) {
        mkdir(TEMP_DIR);
    }

    // 2. remove old files from the site
    docFiles.forEach(function(filePath) {
        const fullPath = path.join(DOCS_DIR, filePath),
            htmlFullPath = fullPath.replace(".md", ".html");

        if (test("-f", fullPath)) {

            rm("-r", fullPath);

            if (filePath.indexOf(".md") >= 0 && test("-f", htmlFullPath)) {
                rm("-r", htmlFullPath);
            }
        }
    });

    // 3. Copy docs folder to a temporary directory
    cp("-rf", "docs/*", TEMP_DIR);

    let versions = test("-f", "./versions.json") ? JSON.parse(cat("./versions.json")) : {};

    if (!versions.added) {
        versions = {
            added: versions,
            removed: {}
        };
    }

    // 4. Loop through all files in temporary directory
    find(TEMP_DIR).forEach(function(filename) {
        if (test("-f", filename) && path.extname(filename) === ".md") {

            const rulesUrl = "https://github.com/eslint/eslint/tree/master/lib/rules/",
                docsUrl = "https://github.com/eslint/eslint/tree/master/docs/rules/",
                baseName = path.basename(filename),
                sourceBaseName = path.basename(filename, ".md") + ".js",
                sourcePath = path.join("lib/rules", sourceBaseName),
                ruleName = path.basename(filename, ".md");
            let text = cat(filename),
                title;

            // 5. Prepend page title and layout variables at the top of rules
            if (path.dirname(filename).indexOf("rules") >= 0) {
                text = "---\ntitle: " + ruleName + " - Rules\nlayout: doc\n---\n<!-- Note: No pull requests accepted for this file. See README.md in the root directory for details. -->\n\n" + text;
            } else {

                // extract the title from the file itself
                title = text.match(/#([^#].+)\n/);
                if (title) {
                    title = title[1].trim();
                } else {
                    title = "Documentation";
                }
                text = "---\ntitle: " + title + "\nlayout: doc\n---\n<!-- Note: No pull requests accepted for this file. See README.md in the root directory for details. -->\n\n" + text;
            }

            // 6. Remove .md extension for links and change README to empty string
            text = text.replace(/\.md(.*?\))/g, ")").replace("README.html", "");

            // 7. Check if there's a trailing white line at the end of the file, if there isn't one, add it
            if (!/\n$/.test(text)) {
                text = text + "\n";
            }

            // 8. Append first version of ESLint rule was added at.
            if (filename.indexOf("rules/") !== -1) {
                if (!versions.added[baseName]) {
                    versions.added[baseName] = getFirstVersionOfFile(sourcePath);
                }
                const added = versions.added[baseName];

                if (!versions.removed[baseName] && !test("-f", sourcePath)) {
                    versions.removed[baseName] = getFirstVersionOfDeletion(sourcePath);
                }
                const removed = versions.removed[baseName];

                text += "\n## Version\n\n";
                text += removed
                    ? "This rule was introduced in ESLint " + added + " and removed in " + removed + ".\n"
                    : "This rule was introduced in ESLint " + added + ".\n";

                text += "\n## Resources\n\n";
                if (!removed) {
                    text += "* [Rule source](" + rulesUrl + sourceBaseName + ")\n";
                }
                text += "* [Documentation source](" + docsUrl + baseName + ")\n";
            }

            // 9. Update content of the file with changes
            text.to(filename.replace("README.md", "index.md"));
        }
    });
    JSON.stringify(versions).to("./versions.json");

    // 10. Copy temporary directory to site's docs folder
    let outputDir = DOCS_DIR;

    if (prereleaseVersion) {
        outputDir += "/" + prereleaseVersion;
    }
    cp("-rf", TEMP_DIR + "*", outputDir);

    // 11. Generate rule listing page
    generateRuleIndexPage(process.cwd());

    // 12. Delete temporary directory
    rm("-r", TEMP_DIR);

    // 13. Update demos, but only for non-prereleases
    if (!prereleaseVersion) {
        cp("-f", "build/eslint.js", SITE_DIR + "js/app/eslint.js");
        cp("-f", "conf/eslint.json", SITE_DIR + "js/app/eslint.json");
    }

    // 14. Create Example Formatter Output Page
    generateFormatterExamples(getFormatterResults(), prereleaseVersion);
};

target.publishsite = function() {
    const currentDir = pwd();

    cd(SITE_DIR);
    exec("git add -A .");
    exec("git commit -m \"Autogenerated new docs and demo at " + dateformat(new Date()) + "\"");
    exec("git fetch origin && git rebase origin/master");
    exec("git push origin master");
    cd(currentDir);
};

target.browserify = function() {

    // 1. create temp and build directory
    if (!test("-d", TEMP_DIR)) {
        mkdir(TEMP_DIR);
    }

    if (!test("-d", BUILD_DIR)) {
        mkdir(BUILD_DIR);
    }

    // 2. copy files into temp directory
    cp("-r", "lib/*", TEMP_DIR);

    // 3. delete the load-rules.js file
    rm(TEMP_DIR + "load-rules.js");

    // 4. create new load-rule.js with hardcoded requires
    generateRulesIndex(TEMP_DIR);

    // 5. browserify the temp directory
    nodeCLI.exec("browserify", "-x espree", TEMP_DIR + "eslint.js", "-o", BUILD_DIR + "eslint.js", "-s eslint", "-t [ babelify --presets [ es2015 ] ]");

    // 6. Browserify espree
    nodeCLI.exec("browserify", "-r espree", "-o", TEMP_DIR + "espree.js");

    // 7. Concatenate Babel polyfill, Espree, and ESLint files together
    cat("./node_modules/babel-polyfill/dist/polyfill.js", TEMP_DIR + "espree.js", BUILD_DIR + "eslint.js").to(BUILD_DIR + "eslint.js");

    // 8. remove temp directory
    rm("-r", TEMP_DIR);
};

target.checkRuleFiles = function() {

    echo("Validating rules");

    const eslintConf = require("./conf/eslint.json").rules;

    const ruleFiles = find("lib/rules/").filter(fileType("js"));
    let errors = 0;

    ruleFiles.forEach(function(filename) {
        const basename = path.basename(filename, ".js");
        const docFilename = "docs/rules/" + basename + ".md";

        /**
         * Check if basename is present in eslint conf
         * @returns {boolean} true if present
         * @private
         */
        function isInConfig() {
            return eslintConf.hasOwnProperty(basename);
        }

        /**
         * Check if id is present in title
         * @param {string} id id to check for
         * @returns {boolean} true if present
         * @private
         */
        function hasIdInTitle(id) {
            const docText = cat(docFilename);
            const idOldAtEndOfTitleRegExp = new RegExp("^# (.*?) \\(" + id + "\\)"); // original format
            const idNewAtBeginningOfTitleRegExp = new RegExp("^# " + id + ": "); // new format is same as rules index
            // 1. Added support for new format.
            // 2. Will remove support for old format after all docs files have new format.
            // 3. Will remove this check when the main heading is automatically generated from rule metadata.

            return idNewAtBeginningOfTitleRegExp.test(docText) || idOldAtEndOfTitleRegExp.test(docText);
        }

        // check for docs
        if (!test("-f", docFilename)) {
            console.error("Missing documentation for rule %s", basename);
            errors++;
        } else {

            // check for proper doc format
            if (!hasIdInTitle(basename)) {
                console.error("Missing id in the doc page's title of rule %s", basename);
                errors++;
            }
        }

        // check for default configuration
        if (!isInConfig()) {
            console.error("Missing default setting for %s in eslint.json", basename);
            errors++;
        }

        // check for tests
        if (!test("-f", "tests/lib/rules/" + basename + ".js")) {
            console.error("Missing tests for rule %s", basename);
            errors++;
        }

    });

    if (errors) {
        exit(1);
    }

};

target.checkLicenses = function() {

    /**
     * Check if a dependency is eligible to be used by us
     * @param {Object} dependency dependency to check
     * @returns {boolean} true if we have permission
     * @private
     */
    function isPermissible(dependency) {
        const licenses = dependency.licenses;

        if (Array.isArray(licenses)) {
            return licenses.some(function(license) {
                return isPermissible({
                    name: dependency.name,
                    licenses: license
                });
            });
        }

        return OPEN_SOURCE_LICENSES.some(function(license) {
            return license.test(licenses);
        });
    }

    echo("Validating licenses");

    checker.init({
        start: __dirname
    }, function(deps) {
        const impermissible = Object.keys(deps).map(function(dependency) {
            return {
                name: dependency,
                licenses: deps[dependency].licenses
            };
        }).filter(function(dependency) {
            return !isPermissible(dependency);
        });

        if (impermissible.length) {
            impermissible.forEach(function(dependency) {
                console.error("%s license for %s is impermissible.",
                    dependency.licenses,
                    dependency.name
                );
            });
            exit(1);
        }
    });
};

target.checkGitCommit = function() {
    let commitMsgs,
        failed;

    if (hasBranch("master")) {
        commitMsgs = splitCommandResultToLines(execSilent("git log HEAD --not master --format=format:%s --no-merges"));
    } else {
        commitMsgs = [execSilent("git log -1 --format=format:%s --no-merges")];
    }

    echo("Validating Commit Message");

    // No commit since master should not cause test to fail
    if (commitMsgs[0] === "") {
        return;
    }

    // Check for more than one commit
    if (commitMsgs.length > 1) {
        echo(" - More than one commit found, please squash.");
        failed = true;
    }

    // Only check non-release messages
    if (!semver.valid(commitMsgs[0]) && !/^Revert /.test(commitMsgs[0])) {
        if (commitMsgs[0].split(/\r?\n/)[0].length > 72) {
            echo(" - First line of commit message must not exceed 72 characters");
            failed = true;
        }

        // Check for tag at start of message
        if (!TAG_REGEX.test(commitMsgs[0])) {
            echo([" - Commit summary must start with one of:",
                "    'Fix:'",
                "    'Update:'",
                "    'Breaking:'",
                "    'Docs:'",
                "    'Build:'",
                "    'New:'",
                "    'Upgrade:'",
                "    'Chore:'",
                "   Please refer to the contribution guidelines for more details."].join("\n"));
            failed = true;
        }

        // Check for an issue reference at end (unless it's a documentation commit)
        if (!/^Docs:/.test(commitMsgs[0])) {
            if (!ISSUE_REGEX.test(commitMsgs[0])) {
                echo([" - Commit summary must end with with one of:",
                    "    '(fixes #1234)'",
                    "    '(refs #1234)'",
                    "   Where '1234' is the issue being addressed.",
                    "   Please refer to the contribution guidelines for more details."].join("\n"));
                failed = true;
            }
        }
    }

    if (failed) {
        exit(1);
    }
};

/**
 * Downloads a repository which has many js files to test performance with multi files.
 * Here, it's eslint@1.10.3 (450 files)
 * @param {Function} cb - A callback function.
 * @returns {void}
 */
function downloadMultifilesTestTarget(cb) {
    if (test("-d", PERF_MULTIFILES_TARGET_DIR)) {
        process.nextTick(cb);
    } else {
        mkdir("-p", PERF_MULTIFILES_TARGET_DIR);
        echo("Downloading the repository of multi-files performance test target.");
        exec("git clone -b v1.10.3 --depth 1 https://github.com/eslint/eslint.git \"" + PERF_MULTIFILES_TARGET_DIR + "\"", {silent: true}, cb);
    }
}

/**
 * Creates a config file to use performance tests.
 * This config is turning all core rules on.
 * @returns {void}
 */
function createConfigForPerformanceTest() {
    const content = [
        "root: true",
        "env:",
        "    node: true",
        "    es6: true",
        "rules:"
    ];

    content.push.apply(
        content,
        ls("lib/rules").map(function(fileName) {
            return "    " + path.basename(fileName, ".js") + ": 1";
        })
    );

    content.join("\n").to(PERF_ESLINTRC);
}

/**
 * Calculates the time for each run for performance
 * @param {string} cmd cmd
 * @param {int} runs Total number of runs to do
 * @param {int} runNumber Current run number
 * @param {int[]} results Collection results from each run
 * @param {Function} cb Function to call when everything is done
 * @returns {int[]} calls the cb with all the results
 * @private
 */
function time(cmd, runs, runNumber, results, cb) {
    const start = process.hrtime();

    exec(cmd, { silent: true }, function(code, stdout, stderr) {
        const diff = process.hrtime(start),
            actual = (diff[0] * 1e3 + diff[1] / 1e6); // ms

        if (code) {
            echo("  Performance Run #" + runNumber + " failed.");
            if (stdout) {
                echo("STDOUT:\n" + stdout + "\n\n");
            }

            if (stderr) {
                echo("STDERR:\n" + stderr + "\n\n");
            }
            return cb(null);
        }

        results.push(actual);
        echo("  Performance Run #" + runNumber + ":  %dms", actual);
        if (runs > 1) {
            return time(cmd, runs - 1, runNumber + 1, results, cb);
        } else {
            return cb(results);
        }
    });

}

/**
 * Run a performance test.
 *
 * @param {string} title - A title.
 * @param {string} targets - Test targets.
 * @param {number} multiplier - A multiplier for limitation.
 * @param {Function} cb - A callback function.
 * @returns {void}
 */
function runPerformanceTest(title, targets, multiplier, cb) {
    const cpuSpeed = os.cpus()[0].speed,
        max = multiplier / cpuSpeed,
        cmd = ESLINT + "--config \"" + PERF_ESLINTRC + "\" --no-eslintrc --no-ignore " + targets;

    echo("");
    echo(title);
    echo("  CPU Speed is %d with multiplier %d", cpuSpeed, multiplier);

    time(cmd, 5, 1, [], function(results) {
        if (!results || results.length === 0) {  // No results? Something is wrong.
            throw new Error("Performance test failed.");
        }

        results.sort(function(a, b) {
            return a - b;
        });

        const median = results[~~(results.length / 2)];

        echo("");
        if (median > max) {
            echo("  Performance budget exceeded: %dms (limit: %dms)", median, max);
        } else {
            echo("  Performance budget ok:  %dms (limit: %dms)", median, max);
        }
        echo("");
        cb();
    });
}

/**
 * Run the load performance for eslint
 * @returns {void}
 * @private
 */
function loadPerformance() {
    echo("");
    echo("Loading:");

    const results = [];

    for (let cnt = 0; cnt < 5; cnt++) {
        const loadPerfData = loadPerf({
            checkDependencies: false
        });

        echo("  Load performance Run #" + (cnt + 1) + ":  %dms", loadPerfData.loadTime);
        results.push(loadPerfData.loadTime);
    }

    results.sort(function(a, b) {
        return a - b;
    });
    const median = results[~~(results.length / 2)];

    echo("");
    echo("  Load Performance median:  %dms", median);
    echo("");
}

target.perf = function() {
    downloadMultifilesTestTarget(function() {
        createConfigForPerformanceTest();

        loadPerformance();

        runPerformanceTest(
            "Single File:",
            "tests/performance/jshint.js",
            PERF_MULTIPLIER,
            function() {

                // Count test target files.
                const count = glob.sync(
                    process.platform === "win32"
                        ? PERF_MULTIFILES_TARGETS.slice(2).replace("\\", "/")
                        : PERF_MULTIFILES_TARGETS
                ).length;

                runPerformanceTest(
                    "Multi Files (" + count + " files):",
                    PERF_MULTIFILES_TARGETS,
                    3 * PERF_MULTIPLIER,
                    function() {}
                );
            }
        );
    });
};

target.release = function() {
    release();
};

target.ciRelease = function() {
    release(true);
};

target.prerelease = function(args) {
    prerelease(args[0]);
};