diff --git a/README.md b/README.md index 5df3e21..5a8b6c1 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,19 @@ -![AWESOME CHEATSHEETS LOGO](_images/awesome_cheatsheets_logo@2x.png) +![AWESOME CHEATSHEETS LOGO](_design/cover_github@2x.png) -[![Awesome](https://awesome.re/badge.svg)](https://awesome.re) +[![Awesome](https://awesome.re/badge.svg)](https://awesome.re) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/LeCoupa/awesome-cheatsheets/blob/master/LICENSE) > šŸ“š Awesome cheatsheets for popular programming languages, frameworks and development tools. They include everything you should know in one single file. > ā¤ļø **If you like this repository, [you can click here to tweet it and make it spread](https://ctt.ec/PHba4).** -## šŸŽ© Why Awesome-Cheatsheets? +## šŸ¤” Why Awesome-Cheatsheets? I always make a cheatsheet when I want to improve my skills on a programming language, a framework or a development tool. [I started doing these kind of things a long time ago on Gist](https://gist.github.com/LeCoupa) To better keep track of the history and to let people contribute to them, I reorganized everything into this single repository. Most of the content is coming from official documentations and some books I have read. Feel free to browse each cheatsheet to learn new things and to keep them at hand when you forgot about one command. They have been designed to provide a quick way to assess your knowledge and to save you time. -## šŸ™ŒšŸ¼ How to Contribute? - -You are more than welcome to contribute and build your own cheatsheet for your favorite programming language, framework or development tool. Just submit changes via pull request and I will review them before merging. - - ## šŸ“š Table of Contents ### šŸ“ƒ Languages @@ -52,6 +47,7 @@ You are more than welcome to contribute and build your own cheatsheet for your f #### Javascript * [Feathers.js](backend/feathers.js) +* [Moleculer](backend/moleculer.js) * [Node.js](backend/node.js) @@ -67,6 +63,7 @@ You are more than welcome to contribute and build your own cheatsheet for your f #### Frameworks +* [React.js](frontend/react.js) * [Vue.js](frontend/vue.js) @@ -95,24 +92,33 @@ You are more than welcome to contribute and build your own cheatsheet for your f #### Infrastructure * [Docker](tools/docker.sh) +* [Kubernetes](tools/kubernetes.sh) * [Nanobox Boxfile](tools/nanobox_boxfile.yml) * [Nanobox CLI](tools/nanobox_cli.sh) +## šŸ™ŒšŸ¼ How to Contribute? + +You are more than welcome to contribute and build your own cheatsheet for your favorite programming language, framework or development tool. Just submit changes via pull request and I will review them before merging. + + ## šŸ™šŸ» Contribution +
- + - + + +
diff --git a/_design/Awesome Cheatsheets.sketch b/_design/Awesome Cheatsheets.sketch new file mode 100644 index 0000000..4a6444f Binary files /dev/null and b/_design/Awesome Cheatsheets.sketch differ diff --git a/_design/awesome_cheatsheets_logo.png b/_design/awesome_cheatsheets_logo.png new file mode 100644 index 0000000..b40d174 Binary files /dev/null and b/_design/awesome_cheatsheets_logo.png differ diff --git a/_design/awesome_cheatsheets_logo.psd b/_design/awesome_cheatsheets_logo.psd new file mode 100644 index 0000000..d00b5e2 Binary files /dev/null and b/_design/awesome_cheatsheets_logo.psd differ diff --git a/_design/awesome_cheatsheets_logo@2x.png b/_design/awesome_cheatsheets_logo@2x.png new file mode 100644 index 0000000..ef691c2 Binary files /dev/null and b/_design/awesome_cheatsheets_logo@2x.png differ diff --git a/_design/awesome_cheatsheets_logo@4x.png b/_design/awesome_cheatsheets_logo@4x.png new file mode 100644 index 0000000..e8c39e9 Binary files /dev/null and b/_design/awesome_cheatsheets_logo@4x.png differ diff --git a/_design/cover_github@2x.png b/_design/cover_github@2x.png new file mode 100644 index 0000000..970c5b3 Binary files /dev/null and b/_design/cover_github@2x.png differ diff --git a/_images/awesome_cheatsheets_logo.png b/_images/awesome_cheatsheets_logo.png deleted file mode 100644 index 33f33de..0000000 Binary files a/_images/awesome_cheatsheets_logo.png and /dev/null differ diff --git a/_images/awesome_cheatsheets_logo.psd b/_images/awesome_cheatsheets_logo.psd deleted file mode 100644 index 564a2db..0000000 Binary files a/_images/awesome_cheatsheets_logo.psd and /dev/null differ diff --git a/_images/awesome_cheatsheets_logo@2x.png b/_images/awesome_cheatsheets_logo@2x.png deleted file mode 100644 index 91d9a9e..0000000 Binary files a/_images/awesome_cheatsheets_logo@2x.png and /dev/null differ diff --git a/backend/feathers.js b/backend/feathers.js index fb72c45..c1cd63e 100644 --- a/backend/feathers.js +++ b/backend/feathers.js @@ -15,7 +15,7 @@ * ******************************************************************************************* */ -```bash +``` # Provides the ability to initialize new application instances npm install @feathersjs/feathers --save @@ -185,7 +185,7 @@ app.on('login', (payload, info) => {}) // sent by the authentication module and * ******************************************************************************************* */ -```bash +``` # Contains Express framework integrations npm install @feathersjs/express --save @@ -252,7 +252,7 @@ app.configure(primus(options, callback)) // sets up the Primus transport with t * ******************************************************************************************* */ -```bash +``` # Bundles the separate Feathers client side modules into one providing the code as ES5 (compatible with modern browsers) # You do not have to install or load any of the other modules listed below npm install @feathersjs/client --save @@ -299,7 +299,7 @@ primus(socket, options) // initialize the Primus client using a given socket an * ******************************************************************************************* */ -```bash +``` #Ā Assists in using JWT for authentication npm install @feathersjs/authentication --save @@ -562,7 +562,7 @@ app.service('authentication').hooks({ * ******************************************************************************************* */ -```bash +``` # [MEMORY/FILESYSTEM] In-memory database adapter npm install feathers-memory --save diff --git a/backend/moleculer.js b/backend/moleculer.js new file mode 100644 index 0000000..4af4538 --- /dev/null +++ b/backend/moleculer.js @@ -0,0 +1,747 @@ +/* ******************************************************************************************* + * MOLECULER MICROSERVICES FRAMEWORK - CORE CHEATSHEET + * http://moleculer.services/0.12/docs/ + * + * Version: 0.12.x + * ******************************************************************************************* */ + + +/* ******************************************************************************************* + * Install Moleculer + * ******************************************************************************************* */ + + +```bash +npm i moleculer +``` + + +/* ******************************************************************************************* + * SERVICE BROKER OPTIONS + * ******************************************************************************************* */ + + +// All ServiceBroker options with default values +const broker = new ServiceBroker({ + namespace: "", // Namespace for node segmentation + nodeID: null, // NodeID. Default value is generated from hostname and PID + + logger: null, // Logger instance. + logLevel: null, // Log level + logFormatter: "default", // Log formatter. Options: "default", "simple" + + transporter: null, // Transporter config + requestTimeout: 0 * 1000, // Timeout of requests + requestRetry: 0, // Retries for requests + maxCallLevel: 0, // Maximum calling level. + heartbeatInterval: 5, // Heartbeat sending interval in seconds + heartbeatTimeout: 15, // Heartbeat timeout in seconds + + disableBalancer: false, // Disable the built-in Moleculer balancer + + registry: { // Service Registry options + strategy: "RoundRobin", // Invocation strategy + strategyOptions: null, // Strategy options + preferLocal: true // Prefer local invocations + }, + + circuitBreaker: { // Circuit-breaker options + enabled: false, // Enable circuit-breaker + maxFailures: 3, // Maximum failures + halfOpenTime: 10 * 1000, // Half-open time interval + failureOnTimeout: true, // Failure on timeouts + failureOnReject: true // Failure on rejects + }, + + transit: { // Transit options + maxQueueSize: 50 * 1000 // Max items in outgoing queue + }, + + cacher: null, // Cacher config + serializer: null, // Serializer config + + validation: true, // Enable params validation + validator: null, // Validator instance + metrics: false, // Enable metrics + metricsRate: 1, // Metrics rate + statistics: false, // Enable statistics + internalServices: true, // Load internal ($node) services + + hotReload: false, // Hot-reload services + + middlewares: null, // List of middlewares + + replCommands: null, // Custom REPL commands + + ServiceFactory: null, // Custom Service factory class + ContextFactory: null // Custom Context factory class +}); + + +/* ******************************************************************************************* + * SERVICE BROKER METHODS + * ******************************************************************************************* */ + + +// Broker properties +broker.Promise // Pointer to Bluebird Promise lib +broker.namespace // Namespace from options +broker.nodeID // Local NodeID +broker.logger // Logger instance +broker.cacher // Cacher instance +broker.serializer // Serializer instance +broker.validator // Validator instance + +// Broker methods +broker.start(); // Start broker & all services. Returns a Promise +broker.stop(); // Stop broker & all services. Returns a Promise +broker.fatal(message, err, needExit = true); // Fired a fatal error. +broker.repl(); // Switch broker to REPL mode. + +broker.getLogger(module, service, version); // Create a custom logger instance for modules + +broker.loadServices(folder, fileMask); // Load all services from directory +broker.loadService(filePath); // Load a service from a file +broker.createService(schema, schemaMods); // Create a local service from schema +broker.destroyService(service); // Destroy a local service +broker.getLocalService(name, version); // Get a local service instance by name + +// Wait for services. Returns a Promise +await broker.waitForServices(serviceNames, timeout, interval); +await broker.waitForServices(["posts", "users"], 5000); +await broker.waitForServices({ + name: "posts", version: 2, + name: "users", version: 1 +}, 5000); + +broker.use(...middlewares); // Register middlewares + +broker.call(actionName, params, opts); // Call a service +broker.mcall(def); // Multiple service calls + +broker.emit(eventName, payload, groups); // Emit a balanced event +broker.broadcast(eventName, payload, groups = null) // Broadcast an event +broker.broadcastLocal(eventName, payload, groups = null) // Broadcast an event to local services + +broker.sendPing(nodeID); // Ping a remote node +broker.MOLECULER_VERSION // Version number of Moleculer lib +broker.PROTOCOL_VERSION // Version number of Moleculer protocol + + +/* ******************************************************************************************* + * BROKER SERVICE CALLS + * ******************************************************************************************* */ + + +// Call the "users.get" service with params +broker.call("users.get", { id: 150 }).then(user => console.log(user)); + +// Call with async/await +const user = await broker.call("users.get", { id: 150}); + +// Call with calling options +const user = await broker.call("users.get", { id: 150}, { timeout: 5000, retryCount: 3 }); + +// Direct call to a remote node +const info = await broker.call("$node.services", null, { nodeID: "node-123" }); + +// Multiple calls with array def +const [posts, users] = await broker.mcall([ + { action: "posts.find", params: { limit: 5, offset: 0 } }, + { action: "users.find", params: { limit: 5, sort: "username" }, opts: { timeout: 500 } } +]); + +// Multip calls with object def +const res = await broker.mcall({ + posts: { action: "posts.find", params: { limit: 5, offset: 0 } }, + users: { action: "users.find", params: { limit: 5, sort: "username" }, opts: { timeout: 500 } } +}); +console.log(res.posts, res.users); + + +/* ******************************************************************************************* + * BROKER EVENTS + * ******************************************************************************************* */ + + +// Send a balanced event with payload +broker.emit("user.created", { user: user }); + +// Send a balanced event only for "mail" and "payment" service (only one instance) +broker.emit("user.created", { user: user }, ["mail", "payment"]); + +// Send a broadcast event (for all service instances) +broker.broadcast("user.created", { user: user }); + +// Send a broadcast event only for "mail" and "payment" services (all instances) +broker.broadcast("user.created", { user: user }, ["mail", "payment"]); + + +/* ******************************************************************************************* + * NATS TRANSPORTER + * Requirement: `npm i nats` + * ******************************************************************************************* */ + + +// Default options +const broker = new ServiceBroker({ + transporter: "NATS" +}); + +// With URI +const broker = new ServiceBroker({ + transporter: "nats://localhost:4222" +}); + +// With options +const broker = new ServiceBroker({ + transporter: { + type: "NATS", + options: { + url: "nats://localhost:4222", + user: "admin", + pass: "1234" + } + } +}); + +// With TLS (https://github.com/nats-io/node-nats#tls) +const broker = new ServiceBroker({ + transporter: { + type: "NATS", + options: { + url: "nats://localhost:4222", + tls: { + key: fs.readFileSync('./client-key.pem'), + cert: fs.readFileSync('./client-cert.pem'), + ca: [ fs.readFileSync('./ca.pem') ] + } + } + } +}); + + +/* ******************************************************************************************* + * REDIS TRANSPORTER + * Requirement: `npm i ioredis` + * ******************************************************************************************* */ + + +// Default options +const broker = new ServiceBroker({ + transporter: "Redis" +}); + +// With URI +const broker = new ServiceBroker({ + transporter: "redis://redis-server:6379" +}); + +// With options +const broker = new ServiceBroker({ + transporter: { + type: "Redis", + options: { + port: 6379, // Redis port + host: 'redis-server', // Redis host + family: 4, // 4 (IPv4) or 6 (IPv6) + password: 'auth', // Password + db: 0 // Database index + } + } +}); + + +/* ******************************************************************************************* + * MQTT TRANSPORTER + * Requirement: `npm i mqtt` + * ******************************************************************************************* */ + + +// Default options +const broker = new ServiceBroker({ + transporter: "MQTT" +}); + +// With URI +const broker = new ServiceBroker({ + transporter: "mqtt://mqtt-server:1883" +}); + +// With options +const broker = new ServiceBroker({ + transporter: { + type: "MQTT", + options: { + host: "mqtt-server", + port: 1883, + username: "admin", + password: "1234" + } + } +}); + + +/* ******************************************************************************************* + * AMQP TRANSPORTER + * Requirement: `npm i amqplib` + * ******************************************************************************************* */ + + +// Default options +const broker = new ServiceBroker({ + transporter: "AMQP" +}); + +// With URI +const broker = new ServiceBroker({ + transporter: "amqp://rabbitmq-server:5672" +}); + +// With options +const broker = new ServiceBroker({ + transporter: { + type: "AMQP", + options: { + url: "amqp://user:pass@rabbitmq-server:5672", + eventTimeToLive: 5000, + prefetch: 1 + } + } +}); + + +/* ******************************************************************************************* + * KAFKA TRANSPORTER + * Requirement: `npm i kafka-node` + * ******************************************************************************************* */ + + +// Default options +const broker = new ServiceBroker({ + transporter: "Kafka" +}); + +// With URI +const broker = new ServiceBroker({ + transporter: "kafka://192.168.51.29:2181" +}); + +// With options +const broker = new ServiceBroker({ + transporter: { + type: "kafka", + options: { + host: "192.168.51.29:2181", + + // KafkaClient options. More info: https://github.com/SOHU-Co/kafka-node#clientconnectionstring-clientid-zkoptions-noackbatchoptions-ssloptions + client: { + zkOptions: undefined, + noAckBatchOptions: undefined, + sslOptions: undefined + }, + + // KafkaProducer options. More info: https://github.com/SOHU-Co/kafka-node#producerclient-options-custompartitioner + producer: {}, + customPartitioner: undefined, + + // ConsumerGroup options. More info: https://github.com/SOHU-Co/kafka-node#consumergroupoptions-topics + consumer: { + }, + + // Advanced options for `send`. More info: https://github.com/SOHU-Co/kafka-node#sendpayloads-cb + publish: { + partition: 0, + attributes: 0 + } + } + } +}); + + +/* ******************************************************************************************* + * NATS STREAMING TRANSPORTER + * Requirement: `npm i node-nats-streaming` + * ******************************************************************************************* */ + + +// Default options +const broker = new ServiceBroker({ + transporter: "STAN" +}); + +// With URI +const broker = new ServiceBroker({ + transporter: "stan://192.168.0.120:4222" +}); + +// With options +const broker = new ServiceBroker({ + transporter: { + type: "STAN", + options: { + url: "stan://127.0.0.1:4222", + clusterID: "my-cluster" + } + } +}); + + +/* ******************************************************************************************* + * TCP STREAMING TRANSPORTER + * No requirements + * ******************************************************************************************* */ + + +// Default options +const broker = new ServiceBroker({ + transporter: "TCP" +}); + +// With static node list +const broker = new ServiceBroker({ + transporter: "tcp://172.17.0.1:6000/node-1,172.17.0.2:6000/node-2" +}); + +const broker = new ServiceBroker({ + nodeID: "node-1", + transporter: { + type: "TCP", + options: { + udpDiscovery: false, + urls: [ + "172.17.0.1:6000/node-1", + "172.17.0.2:6000/node-2", + "172.17.0.3:6000/node-3" + ] + } + } +}); + +// With full options +const broker = new ServiceBroker({ + logger: true, + transporter: { + type: "TCP", + options: { + // Enable UDP discovery + udpDiscovery: true, + // Reusing UDP server socket + udpReuseAddr: true, + + // UDP port + udpPort: 4445, + // UDP bind address + udpBindAddress: null, + // UDP sending period + udpPeriod: 5, + + // Multicast address. + udpMulticast: "239.0.0.0", + // Multicast TTL setting + udpMulticastTTL: 1, + + // Send broadcast + udpBroadcast: false, + + // TCP server port. Null or 0 means random port + port: null, + // Static remote nodes address list (when UDP discovery is not available) + urls: null, + // Use hostname as preffered connection address + useHostname: true, + + // Gossip sending period in seconds + gossipPeriod: 2, + // Maximum enabled outgoing connections. If reach, close the old connections + maxConnections: 32, + // Maximum TCP packet size + maxPacketSize: 1 * 1024 * 1024 + } + } +}); + + +/* ******************************************************************************************* + * CACHERS + * http://moleculer.services/docs/cachers.html + * ******************************************************************************************* */ + + +// Memory cacher +const broker = new ServiceBroker({ + cacher: "Memory" +}); +// or +const broker = new ServiceBroker({ + cacher: true +}); + +// Memory cacher with options +const broker = new ServiceBroker({ + cacher: { + type: "Memory", + options: { + ttl: 30 + } + } +}); + +// Redis cacher +const broker = new ServiceBroker({ + cacher: "Redis" +}); + +// Redis cacher with URI +const broker = new ServiceBroker({ + cacher: "redis://redis-server:6379" +}); + +// Redis cacher with options +const broker = new ServiceBroker({ + cacher: { + type: "Redis", + options: { + prefix: "MOL", + redis: { + host: "redis", + port: 6379, + password: "1234", + db: 0 + } + } + } +}); + + +/* ******************************************************************************************* + * Manual caching + * ******************************************************************************************* */ + + +// Save to cache +broker.cacher.set("mykey.a", { a: 5 }); + +// Get from cache +const obj = await broker.cacher.get("mykey.a"); + +// Remove entry from cache +broker.cacher.del("mykey.a"); + +// Clean all 'mykey' entries +broker.cacher.clean("mykey.*"); + +// Clean all entries +broker.cacher.clean(); + + +/* ******************************************************************************************* + * SERIALIZER + * http://moleculer.services/docs/serializers.html + * ******************************************************************************************* */ + + +// JSON serializer (default) +const broker = new ServiceBroker({ + serializer: "JSON" +}); + +// Avro serializer (need `npm i avsc`) +const broker = new ServiceBroker({ + serializer: "Avro" +}); + +// Protocol Buffer serializer (need `npm i protobufjs`) +const broker = new ServiceBroker({ + serializer: "ProtoBuf" +}); + +// MsgPack serializer (need `npm i msgpack5`) +const broker = new ServiceBroker({ + serializer: "MsgPack" +}); + + +/* ******************************************************************************************* + * STRATEGY + * ******************************************************************************************* */ + + +// Round-robin strategy (default) +const broker = new ServiceBroker({ + registry: { + strategy: "RoundRobin" + } +}); + +// Random strategy +const broker = new ServiceBroker({ + registry: { + strategy: "Random" + } +}); + +// CPU usage-based strategy +const broker = new ServiceBroker({ + registry: { + strategy: "CpuUsageStrategy" + } +}); + +// CPU usage-based strategy with options +const broker = new ServiceBroker({ + registry: { + strategy: "CpuUsageStrategy", + strategyOptions: { + sampleCount: 3, + lowCpuUsage: 10 + } + } +}); + + +/* ******************************************************************************************* + * LOGGER + * http://moleculer.services/docs/logger.html + * ******************************************************************************************* */ + + +// Logger methods +broker.logger.fatal(); +broker.logger.error(); +broker.logger.warn(); +broker.logger.info(); +broker.logger.debug(); +broker.logger.trace(); + +// Custom log formatter +const broker = new ServiceBroker({ + logger: console, + logFormatter(level, args, bindings) { + return level.toUpperCase() + " " + bindings.nodeID + ": " + args.join(" "); + } +}); + +// External Pino logger +const pino = require("pino")({ level: "info" }); +const broker = new ServiceBroker({ + logger: bindings => pino.child(bindings) +}); + +// External Bunyan logger +const logger = require("bunyan").createLogger({ name: "moleculer", level: "info" }); +const broker = new ServiceBroker({ + logger: bindings => logger.child(bindings) +}); + + +/* ******************************************************************************************* + * SERVICE SCHEMA + * ******************************************************************************************* */ + + +module.exports = { + // Name + name: "greeter", + // Version + version: 2, + + // Settings + settings: {}, + // Metadata + metadata: {}, + // Dependencies + dependencies: [], + + // Actions + actions: { + // Shorthand actions + hello() { + // Call a method + this.doSomething(); + + return "Hello Moleculer"; + }, + + // With properties + welcome: { + // Cache options + cache: { + keys: ["name"] + }, + // Validation options + params: { + name: "string" + }, + // Action handler + handler(ctx) { + return `Welcome, ${ctx.params.name}`; + } + } + }, + + events: { + "user.created"(payload, sender) { + + } + }, + + // Service methods + methods: { + doSomething() {} + }, + + // Lifecycle event handlers + created() { + console.log("Service created"); + }, + + started() { + console.log("Service started"); + return Promise.resolve(); + }, + + stopped() { + console.log("Service stopped"); + return Promise.resolve(); + } +}; + + +/* ******************************************************************************************* + * SERVICE + * ******************************************************************************************* */ + + +this.name // Name of service +this.version // Version of service +this.settings // Settings of service +this.schema // Schema definition of service +this.broker // Broker instance +this.Promise // Class of Promise (Bluebird) +this.logger // Logger instance +this.actions // Actions of service. +this.waitForServices // Pointer to ā€˜broker.waitForServices’ method + + +/* ******************************************************************************************* + * CONTEXT + * ******************************************************************************************* */ + + +ctx.id // Context ID +ctx.broker // Broker instance +ctx.action // Action definition +ctx.nodeID // Node ID +ctx.requestID // Request ID +ctx.parentID // ID of parent context (in case of sub-calls). +ctx.params // Request params +ctx.meta // Request metadata +ctx.callerNodeID // Caller Node ID if it is requested from a remote node. +ctx.level // Request level (in case of sub-calls). The first level is 1. + +// Make a sub-call +ctx.call(actionName, params, callingOptions) + +// Emit an event +ctx.emit(eventName, payload, groups); diff --git a/frontend/angularjs.js b/frontend/angularjs.js new file mode 100644 index 0000000..3c09974 --- /dev/null +++ b/frontend/angularjs.js @@ -0,0 +1,434 @@ +/* ******************************************************************************************* + * ANGULARJS CHEATSHEET + * API DOCUMENTATION: https://docs.angularjs.org/api + * DEVELOPER GUIDE: https://docs.angularjs.org/guide + * ERROR REFERENCE: https://docs.angularjs.org/error + * ******************************************************************************************* */ + + +/* ******************************************************************************************* + * TIPS & TRICKS + * ******************************************************************************************* */ + + +// You can retrieve a scope for any DOM element by using: +angular.element(aDomElement).scope() + +// An object that contains information about the current AngularJS version. +// This object has the following properties: full, major, minor, dot, codeName +angular.version + + +/* ******************************************************************************************* + * CSS CLASS USED BY ANGULAR + * ******************************************************************************************* */ + + +// AngularJS applies this class to any element for which a new scope is defined. +ng-scope + +// AngularJS applies this class to any element for which a new isolate scope is defined. +ng-isolate-scope + +// AngularJS applies this class to any element that is attached to a data binding, via ng-bind or {{}} curly braces, for example. +ng-binding + +// AngularJS applies this class to a form control widget element if that element's input does not pass validation. +ng-invalid, ng-valid + +// AngularJS ngModel directive applies ng-pristine class to a new form control widget which did not have user interaction. +// Once the user interacts with the form control, the class is changed to ng-dirty. +ng-pristine, ng-dirty + +// AngularJS ngModel directive applies ng-untouched class to a new form control widget which has not been blurred. +// Once the user blurs the form control, the class is changed to ng-touched. +ng-touched, ng-untouched + + +/* ******************************************************************************************* + * NG MODULE > FUNCTIONS + * ******************************************************************************************* */ + + +// Returns a function which calls function fn bound to self (self becomes the this for fn). +// You can supply optional args that are prebound to the function. +// This feature is also known as partial application, as distinguished from function currying. +angular.bind(self, fn, args) + +// Use this function to manually start up AngularJS application. +angular.bootstrap(element, [modules], [config]) + +// Creates a deep copy of source, which should be an object or an array. +angular.copy(source, [destination]) + +// Wraps a raw DOM element or HTML string as a jQuery element. +angular.element(element) + +// Determines if two objects or two values are equivalent. +// Supports value types, regular expressions, arrays and objects. +angular.equals(o1, o2) + +// Configure several aspects of error handling in AngularJS if used as a setter or return the current configuration if used as a getter. +angular.errorHandlingConfig([config]) + +// Extends the destination object dst by copying own enumerable properties from the src object(s) to dst. +// You can specify multiple src objects. +angular.extend(dst, src) + +// Invokes the iterator function once for each item in obj collection, which can be either an object or an array. +angular.forEach(obj, iterator, [context]) + +// Deserializes a JSON string. +angular.fromJson(json) + +// A function that returns its first argument. +// This function is useful when writing code in the functional style. +angular.identity(value) + +// Creates an injector object that can be used for retrieving services as well as for dependency injection. +angular.injector(modules, [strictDi]) + +// Determines if a reference is an Array. +angular.isArray(value) + +// Determines if a value is a date. +angular.isDate(value) + +// Determines if a reference is defined. +angular.isDefined(value) + +// Determines if a reference is a DOM element (or wrapped jQuery element). +angular.isElement(value) + +// Determines if a reference is a Function. +angular.isFunction(value) + +// Determines if a reference is a Number. +angular.isNumber(value) + +// Determines if a reference is an Object. Unlike typeof in JavaScript, nulls are not considered to be objects. +angular.isObject(value) + +// Determines if a reference is a String. +angular.isString(value) + +// Determines if a reference is undefined. +angular.isUndefined(value) + +// The angular.module is a global place for creating, registering and retrieving AngularJS modules. +// All modules (AngularJS core or 3rd party) that should be available to an application must be registered using this mechanism. +// Passing one argument retrieves an existing angular.Module, whereas passing more than one argument creates a new angular.Module +angular.module(name, [requires], [configFn]) + +// A function that performs no operations. +// This function can be useful when writing code in the functional style. +angular.noop() + +// Use this function to reload the current application with debug information turned on. +// This takes precedence over a call to $compileProvider.debugInfoEnabled(false). +angular.reloadWithDebugInfo() + +// Serializes input into a JSON-formatted string. +// Properties with leading $$ characters will be stripped since AngularJS uses this notation internally. +angular.toJson(obj, pretty) + + +/* ******************************************************************************************* + * NG MODULE > DIRECTIVES + * ******************************************************************************************* */ + + +// Use this directive to auto-bootstrap an AngularJS application. +// Only one AngularJS application can be auto-bootstrapped per HTML document. +// You can specify an AngularJS module to be used as the root module for the application. +'ng-app' + +// The ngBind attribute tells AngularJS to replace the text content of the specified HTML element with +// the value of a given expression, and to update the text content when the value of that expression changes. +'ng-bind' + +// Evaluates the expression and inserts the resulting HTML into the element in a secure way. +'ng-bind-html' + +// The ngBindTemplate directive specifies that the element text content should be replaced with +// the interpolation of the template in the ngBindTemplate attribute. +'ng-bind-template' + +// Specify custom behavior on blur event. +'ng-blur' + +// Evaluate the given expression when the user changes the input. +'ng-change' + +// Sets the checked attribute on the element, if the expression inside ngChecked is truthy. +'ng-checked' + +// The ngClass directive allows you to dynamically set CSS classes on an HTML element by databinding +// an expression that represents all classes to be added. +'ng-class' + +// The ngClassOdd and ngClassEven directives work exactly as ngClass, except they work in +// conjunction with ngRepeat and take effect only on odd (even) rows. +'ng-class-even' + +// The ngClassOdd and ngClassEven directives work exactly as ngClass, except they work in +// conjunction with ngRepeat and take effect only on odd (even) rows. +'ng-class-odd' + +// The ngClick directive allows you to specify custom behavior when an element is clicked. +'ng-click' + +// The ngCloak directive is used to prevent the AngularJS html template from being briefly displayed +// by the browser in its raw (uncompiled) form while your application is loading. +'ng-cloak' + +// The ngController directive attaches a controller class to the view. +'ng-controller' + +// Specify custom behavior on copy event. +'ng-copy' + +// Specify custom behavior on cut event. +'ng-cut' + +// Allows you to specify custom behavior on a dblclick event. +'ng-dblclick' + +// This directive sets the disabled attribute on the element (typically a form control, e.g. input, button, select etc.) +// if the expression inside ngDisabled evaluates to truthy. +'ng-disabled' + +// Specify custom behavior on focus event. +'ng-focus' + +// Nestable alias of form directive. HTML does not allow nesting of form elements. +// It is useful to nest forms, for example if the validity of a sub-group of controls needs to be determined. +'ng-form' + +// Shows or hides the given HTML element based on the expression provided to the ngHide attribute. +'ng-hide' + +// Executes the expression and replaces with the right href link +'ng-href' + +// Removes or recreates a portion of the DOM tree based on an {expression}. +'ng-if' + +// Fetches, compiles and includes an external HTML fragment. +'ng-include' + +// Allows you to evaluate an expression in the current scope. +'ng-init' + +// Force the angular.element library. +// This should be used to force either jqLite by leaving ng-jq blank or setting the name of the jquery variable under window (eg. jQuery). +'ng-jq' + +// Specify custom behavior on keydown event. +'ng-keydown' + +// Specify custom behavior on keypress event. +'ng-keypress' + +// Specify custom behavior on keyup event. +'ng-keyup' + +// Text input that converts between a delimited string and an array of strings. +'ng-list' + +// Adds the maxlength validator to ngModel. +'ng-maxlength' + +// Adds the minlength validator to ngModel. +'ng-minlength' + +// The ngModel directive binds an input,select, textarea (or custom form control) to a property on the scope using NgModelController, +// which is created and exposed by this directive. +'ng-model' + +// Modify the behaviour of ngModel directives within your application. +// You can specify an ngModelOptions directive on any element. +// All ngModel directives will use the options of their nearest ngModelOptions ancestor. +'ng-model-options' + +// Allows you to specify custom behavior on mousedown event. +'ng-mousedown' + +// Specify custom behavior on mouseenter event. +'ng-mouseenter' + +// Specify custom behavior on mouseleave event. +'ng-mouseleave' + +// Specify custom behavior on mousemove event. +'ng-mousemove' + +// Specify custom behavior on mouseover event. +'ng-mouseover' + +// Specify custom behavior on mouseup event. +'ng-mouseup' + +// Tells AngularJS not to compile or bind the contents of the current DOM element, +// including directives on the element itself that have a lower priority than ngNonBindable. +'ng-non-bindable' + +// Sets the open attribute on the element, if the expression inside ngOpen is truthy. +'ng-open' + +// The ngOptions attribute can be used to dynamically generate a list of