initial commit

This commit is contained in:
2026-03-16 13:53:01 +02:00
parent 631dc7df36
commit 81e6e0a7a2
23381 changed files with 8224173 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
{
"label": "VERY Fun Stuff",
"isSubmenu": true,
"icon": "core://resources/actionIcons/fun.png"
}

View File

@@ -0,0 +1,6 @@
{
"label": "AAAAA",
"icon": "core://resources/actionIcons/clock.png",
"colors": "blue",
"skillId": "@be/clock"
}

0
V3.1/BuildUpdatePackage Executable file
View File

View File

@@ -0,0 +1,47 @@
# Be
[![Build Status](https://jenkins2.jibo.com/buildStatus/icon?job=be/be/master)](https://jenkins2.jibo.com/job/be/job/be/job/master/)
Be the Super Skill
## Documentation
[INTERNAL/LATEST Jibo SDK & API Documentation](https://developers.stage.jibo.com/sdk/docs/)
Please also read the [Be Documentation](https://confluence.jibo.com/display/SKIL/Be+Documentation) for information on creating a skill in this organization and adding your skill to this repo as a dependency.
## Building
Build process is implemented using NPM scripts installed in the **package.json** file.
| Command | Description
|---|---|
|`yarn build` | Build the project in debug mode. |
|`yarn release` | Build the project in release mode. |
|`yarn watch` | Watch the source and behaviors, auto-rebuilds. |
|`yarn clean` | Deletes built JavaScript files. |
|`yarn start` | Alias for `yarn watch`. |
|`yarn sync` | Sync file to the robot</br> **Tip**: Use `jibo run` after to launch skills |
|`yarn addsshkey` | Install your public SSH key on the robot (OS X Only). |
|`yarn test` | Run unit tests on the command line. |
|`yarn testdebug` | Run unit tests via the electron window with the developer console. |
|`yarn first:robot:enable` | Reset the flag to run through the First Contact / OOBE flow again ON THE ROBOT. |
|`yarn first:robot:disable` | Disable First Contact / OOBE flow so Be automatically launches into the default skill (Idle) ON THE ROBOT. |
|`yarn first:local:enable` | Reset the flag to run through the First Contact / OOBE flow again LOCALLY. |
|`yarn first:local:disable` | Disable First Contact / OOBE flow so Be automatically launches into the default skill (Idle) LOCALLY. |
## Publishing
To publish, bump the version number (optional) and either publish in debug or release mode. This will generate a release/debug build before publishing and will Git push the version bump and the tag. For example:
```bash
# Bump the version, see NPM docs for more info
npm version patch|minor|major (depending on change)
# Publish in debug mode with source maps and shrinkwrapped
yarn publish:debug:shrinkwrap
# Publish in release mode, minified and shrinkwrapped
yarn publish:release:shrinkwrap
```

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1,42 @@
Be module split
===============
What I added
-----------
- `be/core.js` — a tiny wrapper that re-exports the current bundled `Be` from `index.js`.
- `be/api.js` — convenience helpers that attach `showMenu` to a `Be` instance and `jibo`.
- `be/skill-loader.js` — a small helper scaffold for the skill discovery logic (extract from constructor later).
- `be/init.js` — helper to attach `hex-hitarea` and `menuManager` and API after initialization.
Why this approach
------------------
The project currently ships a single large UMD bundle at `index.js`. Rewriting the bundle in-place is risky
and unnecessary to get incremental improvements. The wrapper modules provide:
- a stable, easy-to-edit place to move code into as you split responsibilities;
- small, testable files to gradually extract logic from the big bundle;
- backward compatibility: the bundle remains the authoritative runtime implementation.
How to continue
----------------
1. Move pieces of logic out of `index.js` into `be/` files one-by-one.
2. Replace the corresponding logic in the bundle with small calls into the new modules.
3. When the split is complete you can replace the bundle with the new source and remove the generated file.
Example usage
-------------
After `jibo.init()` completes, call:
```javascript
// from a skill's code (after Be is initted)
be.menuManager.showMenu('menu/menus/example-menu.json');
// or
be.showMenu('menu/menus/example-menu.json');
```
Notes
-----
- I kept changes minimal so runtime behavior is unchanged. If you want, I can now start moving
specific functions (analytics init, skill loading, lifecycle methods) into these files and patch the bundle
to call them. Tell me which section to extract first and I'll implement the extraction and tests.

View File

@@ -0,0 +1,36 @@
"use strict";
const jibo = require('jibo');
const path = require('path');
const BeSkill = require('@be/be-framework');
exports.initAnalyticsContext = function () {
let context = {
ssm_version: "<not set>",
be_version: "<not set>",
platform_version: "<not set>",
release_version: "<not set>"
};
this.log.debug('context', JSON.stringify(context));
this.log.debug('calling jibo.versions');
const versions = jibo.versions;
this.log.debug('got jibo.versions', JSON.stringify(versions));
if (versions) {
context.platform_version = versions.platform;
context.ssm_version = versions.ssm;
context.release_version = versions.release;
}
this.log.debug('getting Be version');
const dir = jibo.utils.PathUtils.findRoot(__dirname);
const beVersion = require(path.resolve(dir, 'package.json')).version;
this.log.debug('got version:', beVersion);
context.be_version = beVersion;
this.log.debug('version set on context');
this.log.debug('setting context on BeSkill');
this.log.debug(!!BeSkill.BeSkill);
this.log.debug(!!BeSkill.BeSkill.plugins);
this.log.debug(!!BeSkill.BeSkill.plugins && !!BeSkill.BeSkill.plugins.analytics);
if (BeSkill.BeSkill && BeSkill.BeSkill.plugins && BeSkill.BeSkill.plugins.analytics) {
BeSkill.BeSkill.plugins.analytics.context = context;
}
this.log.debug('context set on BeSkill analytics plugin');
};

View File

@@ -0,0 +1,31 @@
"use strict";
// Small API helpers to attach convenience methods to a Be instance.
exports.attach = function (beInstance) {
if (!beInstance) return;
// preserve existing showMenu if present
if (!beInstance.showMenu && beInstance.menuManager && typeof beInstance.menuManager.showMenu === 'function') {
beInstance.showMenu = function (menuPath, cb) {
return beInstance.menuManager.showMenu(menuPath, cb);
};
}
// expose showMenuFromSkills if available
if (!beInstance.showMenuFromSkills && beInstance.menuManager && typeof beInstance.menuManager.showMenuFromSkills === 'function') {
beInstance.showMenuFromSkills = function (rootPath, cb) {
return beInstance.menuManager.showMenuFromSkills(rootPath, cb);
};
}
// expose on global jibo if available
try {
if (typeof jibo !== 'undefined' && !jibo.showMenu && beInstance.showMenu) {
jibo.showMenu = beInstance.showMenu.bind(beInstance);
}
if (typeof jibo !== 'undefined' && !jibo.showMenuFromSkills && beInstance.showMenuFromSkills) {
jibo.showMenuFromSkills = beInstance.showMenuFromSkills.bind(beInstance);
}
}
catch (e) { /* ignore */ }
};

View File

@@ -0,0 +1,9 @@
"use strict";
// Core wrapper: expose the existing bundled Be export as a module
// This file intentionally keeps behavior identical to the bundle while
// providing a stable module boundary for further refactors.
const BeBundle = require('../index.js');
// The bundle exports the Be constructor as default or module.exports
module.exports = BeBundle;

View File

@@ -0,0 +1,28 @@
"use strict";
const jibo = require('jibo');
exports.initPlugins = function (err) {
if (err) {
this.log.error('Error BeSkill plugins: ', err);
this.initDoneCallback(err);
return;
}
const tasks = [];
for (let id in this.skills) {
const skill = this.skills[id];
this.log.debug(`About to push task for skill ${id}`);
tasks.push((done) => {
const startTime = Date.now();
this.log.debug(`Calling postInit for skill ${id}`);
skill.postInit.bind(skill)((err) => {
if (err) {
this.log.error(`error during skill ${skill.assetPack} postinit call:`, err);
}
this.log.info(`loading - skill ${skill.assetPack} postinit call - ${Date.now() - startTime} MS`);
done();
});
});
}
this.log.debug('calling jibo loader to load the skills');
jibo.loader.load(tasks, this.postInit.bind(this));
};

View File

@@ -0,0 +1,18 @@
"use strict";
// Small init helpers extracted from index.js's lifecycle for organization.
// These helpers are lightweight and call into the existing bundle behavior.
exports.patchAfterInit = function (beInstance) {
if (!beInstance) return;
try {
require('../hex-hitarea').patch(beInstance.jibo || (typeof jibo !== 'undefined' && jibo));
}
catch (e) { /* ignore */ }
// attach API helpers
try {
require('./api').attach(beInstance);
}
catch (e) { /* ignore */ }
};

View File

@@ -0,0 +1,236 @@
"use strict";
const jibo = require('jibo');
const path = require('path');
let SkillSwitchData;
let SkillLifecycleState;
if (typeof global !== 'undefined' && global && global.be && global.be.constructor) {
SkillSwitchData = global.be.constructor.SkillSwitchData;
SkillLifecycleState = global.be.constructor.SkillLifecycleState;
}
function _interop(m) {
return (m && (m.__esModule || m.default)) ? (m.default || m) : m;
}
// normalize to usable variables
let SkillSwitchDataCtor;
let SkillLifecycleStateObj;
if (SkillSwitchData) {
SkillSwitchDataCtor = _interop(SkillSwitchData);
}
if (SkillLifecycleState) {
SkillLifecycleStateObj = _interop(SkillLifecycleState);
}
if (!SkillSwitchData) {
try {
SkillSwitchData = require(path.join(jibo.utils.PathUtils.findRoot(), 'SkillSwitchData'));
}
catch (e) {
try {
const Root = require(path.join(jibo.utils.PathUtils.findRoot(), 'index.js'));
SkillSwitchData = (Root && (Root.SkillSwitchData || (Root.default && Root.default.SkillSwitchData))) || undefined;
}
catch (e2) { }
}
}
if (!SkillLifecycleState) {
try {
SkillLifecycleState = require(path.join(jibo.utils.PathUtils.findRoot(), 'SkillLifecycleState'));
}
catch (e) {
try {
const Root = require(path.join(jibo.utils.PathUtils.findRoot(), 'index.js'));
SkillLifecycleState = (Root && (Root.SkillLifecycleState || (Root.default && Root.default.SkillLifecycleState))) || undefined;
}
catch (e2) { }
}
}
exports.selectFirstSkill = function (callback) {
const kbm = jibo.kb.createModel('/skills-config');
kbm.loadRoot((loadRootErr, rootNode) => {
if (loadRootErr) {
this.log.warn("error loading /skills-config root", loadRootErr);
}
jibo.secureTransferService.hasBackupData((backupErr, hasBackupData) => {
if (backupErr) {
this.log.warn("error when checking if backup data exists", backupErr);
}
jibo.errors.getCurrentErrorId((err, currentErrorId) => {
if (err) {
this.log.warn("error when checking for current error id", err);
}
let nextSkill = this.idle;
let nextSkillLaunchOptions = {};
let firstTime = false;
if (!loadRootErr) {
firstTime = !rootNode.data.hasAlreadyLaunchedFirstContact;
}
else {
this.log.info(`error reading the hasAlreadyLaunchedFirstContact property from the KB. assuming first time is false`);
}
this.log.info(`selectFirstSkill parameter readout: Skills config load error: ${loadRootErr}, first time: ${firstTime}, has backup data: ${hasBackupData}, skip restore: ${this.packageInfo.jibo.debug.skipRestore}, current error id: ${currentErrorId}`);
if (currentErrorId) {
nextSkill = this.skills['@be/settings'];
nextSkillLaunchOptions = { nlu: { entities: { errorId: currentErrorId } } };
}
else if (firstTime) {
if (backupErr && !this.packageInfo.jibo.debug.skipRestore) {
setTimeout(this.selectFirstSkill.bind(this, callback), 2000);
return;
}
else if (hasBackupData && !this.packageInfo.jibo.debug.skipRestore) {
nextSkill = this.restoreSkill;
}
else {
nextSkill = this.firstSkill;
}
}
callback(nextSkill, nextSkillLaunchOptions, currentErrorId, firstTime);
});
});
});
};
exports.launchFirstSkill = function (firstSkill, firstSkillLaunchOptions, firstErrorId, firstTime) {
this.log.debug('launching first skill');
const firstSkillHasOpened = () => {
if (firstErrorId) {
document.getElementById('splash').style.display = 'none';
}
else {
document.getElementById('splash').remove();
this.enableSkillSwitching();
}
this.initDoneCallback();
};
let firstSkillRedirectToken = this.redirect(new (SkillSwitchDataCtor || SkillSwitchData)(firstSkill, firstSkillLaunchOptions));
firstSkillRedirectToken.onState((SkillLifecycleStateObj || SkillLifecycleState).SKILL_OPENED, firstSkillHasOpened);
if (firstErrorId) {
const onErrorResolved = () => {
if (firstTime) {
document.getElementById('splash').style.display = 'block';
}
this.selectFirstSkill((nextSkill, nextSkillLaunchOptions, currentErrorId) => {
let nextSkillRedirectToken = this.redirect(new (SkillSwitchDataCtor || SkillSwitchData)(nextSkill, nextSkillLaunchOptions));
if (currentErrorId) {
nextSkillRedirectToken.onState((SkillLifecycleStateObj || SkillLifecycleState).LIFECYCLE_ENDED, onErrorResolved);
nextSkillRedirectToken.onState((SkillLifecycleStateObj || SkillLifecycleState).SKILL_OPENED, () => {
document.getElementById('splash').style.display = 'none';
});
}
else {
nextSkillRedirectToken.onState((SkillLifecycleStateObj || SkillLifecycleState).SKILL_OPENED, () => {
document.getElementById('splash').remove();
this.enableSkillSwitching();
});
}
});
};
firstSkillRedirectToken.onState(SkillLifecycleState.default.LIFECYCLE_ENDED, onErrorResolved);
}
};
exports.enableSkillSwitching = function () {
jibo.globalEvents.skillRelaunch.on(data => {
const skillName = data.match.skillID;
this.redirect(new (SkillSwitchDataCtor || SkillSwitchData)(this.skills[skillName], data));
});
jibo.action.setSkillSwitchHandler((skillName, skillData) => {
return new Promise((resolve) => {
const skill = this.skills[skillName];
let redirectToken = this.redirect(new (SkillSwitchDataCtor || SkillSwitchData)(skill, skillData));
let resolved = false;
redirectToken.onState((SkillLifecycleStateObj || SkillLifecycleState).SKILL_OPENED, () => {
resolved = true;
resolve(jibo.action.types.Status.SUCCEEDED);
});
redirectToken.onState((SkillLifecycleStateObj || SkillLifecycleState).LIFECYCLE_ENDED, () => {
if (!resolved) {
this.log.warn(`Skill lifecycle ended before skill was opened: ${redirectToken.skillLifecycleEndState}`);
}
resolved = true;
resolve(jibo.action.types.Status.FAILED);
});
});
});
};
exports.exit = function (exitingSkill, exitOptions = {}, done = () => { }) {
const skipEoS = !!(exitOptions.noElementsOfSurprise || exitOptions.globalNoMatch);
const currentSkill = this._skillSwitchScheduler.currentSkillRedirectToken ? this._skillSwitchScheduler.currentSkillRedirectToken.skillSwitchData.skill : null;
if (exitingSkill !== currentSkill) {
this.log.warn(`Trying to call Be#exit from non-current skill ${exitingSkill}. Current skill is ${currentSkill}`);
return;
}
if (!skipEoS &&
currentSkill !== this.idle &&
currentSkill !== this.eosSkill &&
!currentSkill.isElementOfSurprise &&
!currentSkill.skipSurprisesExternal) {
let redirectToken = this.redirect(new (SkillSwitchDataCtor || SkillSwitchData)(this.eosSkill, { lastSkill: currentSkill.assetPack }));
redirectToken.addOnSkillLifecycleEnd(done);
}
else {
let redirectToken = this.redirect(new (SkillSwitchDataCtor || SkillSwitchData)(this.idle, { exitOptions }));
redirectToken.addOnSkillLifecycleEnd(done);
}
};
exports.skillRedirect = function (redirectingSkill, name, options) {
const skill = this.skills[name];
const currentSkill = this._skillSwitchScheduler.currentSkillRedirectToken ? this._skillSwitchScheduler.currentSkillRedirectToken.skillSwitchData.skill : null;
if (redirectingSkill !== currentSkill) {
this.log.warn(`Trying to call Be#redirect from non-current skill ${redirectingSkill.assetPack}. Current skill is ${currentSkill.assetPack}`);
return;
}
if (skill) {
this.log.info("REDIRECT: skill redirect: ", name, options);
this.redirect(new (SkillSwitchDataCtor || SkillSwitchData)(skill, options));
}
else {
this.log.error("REDIRECT: skill redirect failed. cannot find skill: ", name, options);
}
};
exports.redirect = function (skillSwitchData) {
return this._skillSwitchScheduler.requestSkillRedirect(skillSwitchData);
};
exports.destroy = function (callback) {
if (document.getElementById('splash')) {
document.getElementById('splash').remove();
}
jibo.globalEvents.skillRelaunch.removeAllListeners();
this._skillSwitchScheduler.destroy()
.then(() => {
let destroySkillPromises = [];
Object.keys(this.skills).forEach((skillId) => {
let destroySkillPromise = new Promise((resolve, reject) => {
try {
this.skills[skillId].destroy((err) => {
jibo.loader.deleteCache(skillId);
if (err) {
reject(err);
}
else {
resolve();
}
});
}
catch (err) {
reject(err);
}
});
destroySkillPromises.push(destroySkillPromise);
});
return Promise.all(destroySkillPromises);
})
.catch((err) => {
this.log.error(err);
})
.then(() => {
callback();
});
};

View File

@@ -0,0 +1,41 @@
"use strict";
const jibo = require('jibo');
exports.postInit = function (err) {
this.log.debug('postInit !!');
if (err) {
this.log.error(err);
this.initDoneCallback(err);
return;
}
this.log.debug('initting alalytics');
// call analytics initializer (keeps logic in separate module)
try {
require('./analytics').initAnalyticsContext.call(this);
}
catch (e) {
this.log.warn('init analytics failed', e);
}
this.log.info('Jibo is ready... awaiting launch command.');
try {
require('../hex-hitarea').patch(jibo);
}
catch (e) {
this.log.warn('hex-hitarea patch failed', e);
}
// Apply dynamic skills patch to add custom skills from menuEntry.json files
try {
const mainMenuPatch = require('../menu/main-menu-patch');
mainMenuPatch.applyPatch(this);
mainMenuPatch.patchLoader(jibo);
this.log.info('Dynamic skills patch applied');
}
catch (e) {
this.log.warn('Dynamic skills patch failed (non-fatal):', e.message || e);
}
jibo.face.views.changeView({ removeAll: true, leaveEmpty: true }, () => {
this.selectFirstSkill(this.launchFirstSkill.bind(this));
});
};

View File

@@ -0,0 +1,24 @@
"use strict";
// Helper to encapsulate skill discovery/creation logic found in the bundle's
// Be constructor. This is intentionally small and only documents where to
// extract the logic when you want to fully replace the bundled constructor.
exports.createSkills = function (packageInfo, jiboRequire, createSkillFn) {
// Example small extractor — callers should implement creating Skill instances
// Parameters:
// - packageInfo: parsed package.json
// - jiboRequire: require('jibo') instance (passed in from consumer)
// - createSkillFn: function(id) => returns constructed skill
const skills = {};
(packageInfo.jibo && packageInfo.jibo.skills || []).forEach((id) => {
try {
const Skill = createSkillFn(id);
if (Skill) skills[id] = Skill;
}
catch (e) {
console.warn('skill creation failed', id, e);
}
});
return skills;
};

View File

@@ -0,0 +1,21 @@
{
"logUncaughtExceptions": true,
"logUnhandledRejections": true,
"stackTraceLimit": 30,
"outputs": {
"console": {
"outputFileAndLine": false
},
"syslog": {
"port": 514,
"target": "127.0.0.1",
"outputFileAndLine": false
}
},
"namespaces": {
"": {
"console": "info",
"syslog": "info"
}
}
}

View File

@@ -0,0 +1,21 @@
{
"logUncaughtExceptions": true,
"logUnhandledRejections": true,
"stackTraceLimit": 30,
"outputs": {
"console": {
"outputFileAndLine": false
},
"syslog": {
"port": 514,
"target": "127.0.0.1",
"outputFileAndLine": false
}
},
"namespaces": {
"": {
"console": "info",
"syslog": "info"
}
}
}

View File

@@ -0,0 +1,21 @@
{
"logUncaughtExceptions": true,
"logUnhandledRejections": true,
"stackTraceLimit": 30,
"outputs": {
"console": {
"outputFileAndLine": false
},
"syslog": {
"port": 514,
"target": "127.0.0.1",
"outputFileAndLine": false
}
},
"namespaces": {
"": {
"console": "none",
"syslog": "info"
}
}
}

View File

@@ -0,0 +1,21 @@
{
"logUncaughtExceptions": true,
"logUnhandledRejections": true,
"stackTraceLimit": 30,
"outputs": {
"console": {
"outputFileAndLine": false
},
"syslog": {
"port": 514,
"target": "127.0.0.1",
"outputFileAndLine": false
}
},
"namespaces": {
"": {
"console": "none",
"syslog": "info"
}
}
}

View File

@@ -0,0 +1,53 @@
"use strict";
// Lightweight monkey-patch to enable polygon (hex) hit areas and per-button polygon configs.
exports.patch = function (jibo) {
try {
if (!jibo || !jibo.face || !jibo.face.views) return;
const MenuButton = jibo.face.views.MenuButton;
const Element = jibo.face.views.Element;
if (MenuButton && MenuButton.prototype && MenuButton.prototype.setupHitArea) {
const origSetup = MenuButton.prototype.setupHitArea;
MenuButton.prototype.setupHitArea = function (bounds) {
if (!bounds && !this._hitArea && this._dimensions) {
// default: regular flat-top hexagon centered in the button bounds
const w = this._dimensions.width;
const h = this._dimensions.height;
const cx = w / 2;
const cy = h / 2;
const r = Math.min(w, h) / 2;
const pts = [];
for (let i = 0; i < 6; i++) {
const angle = (Math.PI / 180) * (60 * i - 30);
pts.push(cx + r * Math.cos(angle), cy + r * Math.sin(angle));
}
bounds = new PIXI.Polygon(pts);
}
return origSetup.call(this, bounds);
};
}
if (Element && Element.prototype && Element.prototype.assignConfig) {
const origAssign = Element.prototype.assignConfig;
Element.prototype.assignConfig = function (configData) {
origAssign.call(this, configData);
if (configData && configData.hitAreaPolygon && Array.isArray(configData.hitAreaPolygon)) {
// hitAreaPolygon should be an array of numbers [x1,y1,x2,y2,...]
try {
this._hitArea = new PIXI.Polygon(configData.hitAreaPolygon.slice());
// If the display already exists, apply immediately
if (this.display) this.display.hitArea = this._hitArea;
}
catch (e) {
// swallow errors - leave original behavior intact
if (jibo && jibo.log && jibo.log.warn) jibo.log.warn('Invalid hitAreaPolygon:', e);
}
}
};
}
}
catch (e) {
if (jibo && jibo.log && jibo.log.warn) jibo.log.warn('hex-hitarea patch error', e);
}
};

View File

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<title>Be</title>
<style>
body {
margin: 0;
overflow: hidden;
background: #000;
}
#splash{
background-image:url('./resources/JiboSplash.png');
width: 1280px;
height: 720px;
}
#face {
width: 1280px;
height: 720px;
}
</style>
</head>
<body>
<div id="face"></div>
<script>
const Be = require("./index");
let be = new Be();
be.init(()=>{
// @if DEBUG
be.log.info("Finished running Be init");
// @endif
});
</script>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,225 @@
# Jibo Dynamic Menu System
This module provides a dynamic menu system that automatically scans the Skills directory for `menuEntry.json` files and adds them to Jibo's menu screen.
## How It Works
When Jibo boots up, the `main-menu-patch.js` module:
1. Patches `jibo.loader.load()` to intercept menu loading
2. Scans the `/opt/jibo/Jibo/Skills` directory for folders containing `menuEntry.json`
3. Injects the found skills/submenus into the main menu
4. Patches the main-menu skill's `redirectToSkill` to handle custom skill launches
## Quick Start
### Adding a Simple Skill Button to the Menu
1. Create a folder in the `Skills` directory (e.g., `MySkill/`)
2. Add a `menuEntry.json` file inside:
```json
{
"type": "skill",
"title": "My Skill",
"icon": "resources/icons/settings.png",
"color": "blue",
"skillId": "MySkill",
"description": "Short description of my skill",
"order": 50
}
```
3. Your skill will automatically appear in Jibo's main menu!
**Note:** For the button to actually launch a skill, that skill must be a proper Jibo skill package registered in `@be/be/package.json`. If the skill isn't found, Jibo will show a fallback message.
### Creating a Submenu (Category/Folder)
1. Create a folder in the `Skills` directory (e.g., `Games/`)
2. Add a `menuEntry.json` marking it as a submenu:
```json
{
"type": "submenu",
"title": "Games",
"submenuTitle": "Choose a Game",
"icon": "resources/icons/fun-stuff.png",
"color": "purple",
"description": "Fun games to play with Jibo",
"order": 10
}
```
3. Inside that folder, create subfolders for each skill, each with their own `menuEntry.json`
4. A button will appear in the main menu that opens a submenu with those skills!
## Directory Structure Example
```
/opt/jibo/Jibo/Skills/
├── @be/ # Core brain (ignored by scanner)
├── MySimpleSkill/
│ └── menuEntry.json # type: "skill" - appears as button in main menu
├── MyGames/
│ ├── menuEntry.json # type: "submenu" - opens submenu when pressed
│ ├── GameOne/
│ │ └── menuEntry.json # type: "skill" - appears in MyGames submenu
│ └── GameTwo/
│ └── menuEntry.json # type: "skill" - appears in MyGames submenu
```
## menuEntry.json Schema
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `type` | `"skill"` \| `"submenu"` | **Yes** | `"skill"` for buttons, `"submenu"` for folders |
| `title` | string | **Yes** | Button label shown on Jibo's screen |
| `icon` | string | **Yes** | Icon path (see Icon Paths below) |
| `color` | string | No | Button color theme (see below). Default: `"default"` |
| `skillId` | string | **Yes** (for skills) | The skill ID to launch |
| `submenuTitle` | string | No | Title shown when submenu is opened |
| `description` | string | No | Tooltip/accessibility text |
| `order` | number | No | Sort order (lower = first). Default: `100` |
| `hidden` | boolean | No | Set to `true` to hide from menu |
### Available Colors
- `default` - Standard gray
- `blue` - Blue theme
- `green` - Green theme
- `red` - Red theme
- `purple` - Purple theme
- `orange` - Orange theme
- `teal` - Teal/cyan theme
- `pink` - Pink theme
- `yellow` - Yellow theme
- `cyan` - Cyan theme
### Icon Paths
Icons are resolved relative to the `@be/main-menu` package. Available built-in icons:
| Icon Path | Description |
|-----------|-------------|
| `resources/icons/settings.png` | Settings gear |
| `resources/icons/fun-stuff.png` | Star/fun icon (good for submenus) |
| `resources/icons/clock.png` | Clock |
| `resources/icons/heart.png` | Heart |
| `resources/icons/surprise.png` | Gift/surprise |
| `resources/icons/dance.png` | Dancing figure |
| `resources/icons/joke.png` | Comedy mask |
| `resources/icons/tips.png` | Lightbulb |
| `resources/icons/gallery.png` | Photo gallery |
| `resources/icons/radio.png` | Music notes |
| `resources/icons/create.png` | Camera |
| `resources/icons/photobooth.png` | Photo booth |
| `resources/icons/exercise.png` | Exercise/yoga |
| `resources/icons/weather.png` | Weather cloud |
| `resources/icons/calendar.png` | Calendar |
| `resources/icons/circuit-saver.png` | Circuit saver |
| `resources/icons/dice.png` | Dice |
| `resources/icons/coin.png` | Coin |
| `resources/icons/emoji.png` | Emoji face |
| `resources/icons/word-of-the-day.png` | Word icon |
| `resources/icons/news.png` | News icon |
| `resources/icons/twerk.png` | Twerk icon |
| `resources/icons/scanner.png` | Scanner icon |
## Example: Complete Skill Setup
### Simple Skill (testSkillA/menuEntry.json)
```json
{
"type": "skill",
"title": "Test Skill A",
"icon": "resources/icons/settings.png",
"color": "blue",
"skillId": "testSkillA",
"description": "A test skill",
"order": 10
}
```
### Submenu (TestSubMenuA/menuEntry.json)
```json
{
"type": "submenu",
"title": "Test Submenu",
"submenuTitle": "Test Skills",
"icon": "resources/icons/fun-stuff.png",
"color": "purple",
"description": "A submenu with test skills",
"order": 20
}
```
### Skill inside Submenu (TestSubMenuA/testSkillB/menuEntry.json)
```json
{
"type": "skill",
"title": "Test Skill B",
"icon": "resources/icons/surprise.png",
"color": "green",
"skillId": "testSkillB",
"description": "A skill inside a submenu",
"order": 1
}
```
## Technical Details
### How the Patch Works
1. **postinit.js** calls `mainMenuPatch.applyPatch(be)` and `mainMenuPatch.patchLoader(jibo)`
2. When the main-menu skill tries to load `main-menu-verbal.json`, the patch intercepts it
3. The patch scans the Skills directory for `menuEntry.json` files
4. It converts them to the proper button format and injects them into the menu config
5. When a dynamic skill button is pressed, the patched `redirectToSkill` handles the launch
6. For submenus, a new menu view is displayed with the submenu's children
### Files
- `main-menu-patch.js` - Core patch that hooks into the system
- `skills-scanner.js` - Alternative scanning implementation (not currently used)
- `menu-manager.js` - Alternative menu display implementation (not currently used)
### Debugging
Check the browser console for log messages starting with `main-menu-patch:`. These show:
- When the patch is initialized
- When menu loads are intercepted
- How many dynamic skills are injected
- When skills/submenus are selected
## Limitations
- Nested submenus (submenus within submenus) are not supported
- Custom skills must be registered in `@be/be/package.json` to actually launch
- Icon files must exist in the `@be/main-menu/resources/icons/` directory
## Troubleshooting
### Skill button not appearing in menu?
1. Check that `menuEntry.json` exists and is valid JSON
2. Verify `hidden` is not set to `true`
3. Make sure `type` is set to `"skill"` or `"submenu"`
4. Check the browser console for `main-menu-patch:` log messages
### Submenu appears empty?
1. Make sure child skill folders have `menuEntry.json` files
2. Verify child skills have `type: "skill"` (nested submenus not supported)
3. Check that child folders are direct children of the submenu folder
### Skill button doesn't launch anything?
1. The skill needs to be a proper Jibo skill package
2. The skill must be registered in `@be/be/package.json` under `jibo.skills`
3. If unregistered, Jibo will show a fallback message
### Icon not loading?
1. Verify the icon path is correct (e.g., `resources/icons/settings.png`)
2. Only built-in icons from `@be/main-menu/resources/icons/` are supported
3. Check the list of available icons above

View File

@@ -0,0 +1,636 @@
"use strict";
/**
* Main Menu Patch - Injects dynamic skills from menuEntry.json files into Jibo's menu
*
* This patches:
* 1. jibo.loader.load() to intercept menu JSON loading and inject dynamic skills
* 2. The main-menu skill's redirectToSkill method to handle custom skill IDs
*/
const fs = require('fs');
const path = require('path');
// Skills root directory
const SKILLS_ROOT = '/opt/jibo/Jibo/Skills';
// Cache for scanned skills
let _cachedMenuEntries = null;
let _submenuConfigs = {};
let _dynamicSkillIds = new Set(); // Track dynamic skill IDs for routing
let _beInstance = null;
let _jibo = null;
// Color mappings for skill buttons (name -> hex array)
const COLOR_MAP = {
'default': ['0xBBC6CA', '0x434D55'],
'blue': ['0x3765AB', '0x1A2563'],
'green': ['0x8EDD40', '0x31732A'],
'red': ['0xE81853', '0x850F40'],
'purple': ['0x9B59B6', '0x6C3483'],
'orange': ['0xFF892F', '0xAF4123'],
'teal': ['0x2BEFDC', '0x086969'],
'pink': ['0xFF69B4', '0xC71585'],
'cyan': ['0x25F2FB', '0x107799'],
'yellow': ['0xFFD700', '0xB8860B']
};
// Logging helper - writes to both console and file
const LOG_FILE = '/tmp/menu-patch.log';
function log(msg, ...args) {
const line = '[MENU-PATCH] ' + msg + ' ' + args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' ');
console.log(line);
try {
fs.appendFileSync(LOG_FILE, new Date().toISOString() + ' ' + line + '\n');
} catch (e) {}
}
function warn(msg, ...args) {
const line = '[MENU-PATCH WARN] ' + msg + ' ' + args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' ');
console.warn(line);
try {
fs.appendFileSync(LOG_FILE, new Date().toISOString() + ' ' + line + '\n');
} catch (e) {}
}
/**
* Safely read and parse a JSON file
*/
function safeReadJson(filePath) {
try {
const txt = fs.readFileSync(filePath, 'utf8');
if (!txt || txt.trim().length === 0) return null;
return JSON.parse(txt);
} catch (e) {
log('safeReadJson error for', filePath, e.message);
return null;
}
}
/**
* Check if path is a directory
*/
function isDirectory(p) {
try {
return fs.statSync(p).isDirectory();
} catch (e) {
return false;
}
}
/**
* Get colors array from color name or return default
*/
function getColors(colorName) {
if (Array.isArray(colorName)) return colorName;
if (typeof colorName === 'string' && colorName.startsWith('0x')) {
return [colorName, colorName];
}
return COLOR_MAP[colorName] || COLOR_MAP['default'];
}
/**
* Scan a skill directory for menuEntry.json
*/
function scanSkillEntry(skillDir, folderName) {
const menuJsonPath = path.join(skillDir, 'menuEntry.json');
const menuJson = safeReadJson(menuJsonPath);
if (!menuJson) {
return null;
}
if (menuJson.hidden === true) {
log('Skipping hidden entry:', folderName);
return null;
}
log('Found menuEntry.json in', folderName, '- type:', menuJson.type);
const entry = {
id: folderName,
type: menuJson.type || 'skill',
title: menuJson.title || menuJson.label || folderName,
icon: menuJson.icon || menuJson.iconSrc || 'resources/icons/settings.png',
color: menuJson.color || menuJson.colors || 'default',
description: menuJson.description || '',
path: skillDir,
order: typeof menuJson.order === 'number' ? menuJson.order : 100,
skillId: menuJson.skillId || folderName,
submenuTitle: menuJson.submenuTitle || menuJson.title || folderName
};
// Track this as a dynamic skill
if (entry.type === 'skill') {
_dynamicSkillIds.add(entry.skillId);
_dynamicSkillIds.add(entry.id);
}
// For submenus, scan child directories
if (entry.type === 'submenu') {
entry.children = scanSubmenuChildren(skillDir);
log('Submenu', folderName, 'has', entry.children.length, 'children');
}
return entry;
}
/**
* Scan children of a submenu directory
*/
function scanSubmenuChildren(submenuDir) {
const children = [];
let items;
try {
items = fs.readdirSync(submenuDir);
} catch (e) {
warn('Failed to read submenu dir:', submenuDir, e.message);
return children;
}
items.forEach(name => {
if (name.startsWith('.') || name === '@be' || name === 'node_modules') return;
const childPath = path.join(submenuDir, name);
if (!isDirectory(childPath)) return;
const entry = scanSkillEntry(childPath, name);
if (entry && entry.type === 'skill') {
children.push(entry);
}
});
// Sort by order, then alphabetically
children.sort((a, b) => {
if (a.order !== b.order) return a.order - b.order;
return a.title.localeCompare(b.title);
});
return children;
}
/**
* Scan the Skills root directory for all menu entries
*/
function scanAllMenuEntries() {
if (_cachedMenuEntries) {
log('Returning cached entries:', _cachedMenuEntries.length);
return _cachedMenuEntries;
}
log('Scanning Skills directory:', SKILLS_ROOT);
_dynamicSkillIds.clear();
const entries = [];
let children;
// Check if directory exists
if (!fs.existsSync(SKILLS_ROOT)) {
warn('Skills directory does not exist:', SKILLS_ROOT);
return entries;
}
try {
children = fs.readdirSync(SKILLS_ROOT);
log('Found', children.length, 'items in Skills directory:', children.join(', '));
} catch (e) {
warn('Failed to read skills directory:', SKILLS_ROOT, e.message);
return entries;
}
children.forEach(name => {
if (name.startsWith('.') || name === '@be' || name === 'node_modules') {
log('Skipping:', name);
return;
}
const skillDir = path.join(SKILLS_ROOT, name);
if (!isDirectory(skillDir)) {
log('Not a directory:', name);
return;
}
const entry = scanSkillEntry(skillDir, name);
if (entry) {
entries.push(entry);
log('Added entry:', entry.title, '(type:', entry.type + ')');
}
});
// Sort by order, then alphabetically
entries.sort((a, b) => {
if (a.order !== b.order) return a.order - b.order;
return a.title.localeCompare(b.title);
});
log('Total entries found:', entries.length);
_cachedMenuEntries = entries;
return entries;
}
/**
* Convert a menu entry to the main-menu button format
*/
function entryToMenuButton(entry) {
const button = {
id: entry.id,
label: entry.title,
colors: getColors(entry.color),
iconSrc: entry.icon
};
if (entry.type === 'submenu') {
// For submenus, create an action that loads a dynamically generated submenu
const submenuId = 'dynamic-submenu-' + entry.id;
// Register the submenu configuration
_submenuConfigs[submenuId] = createSubmenuConfig(entry);
button.action = {
type: 'utterance',
data: {
utterance: {
intent: 'loadMenu',
entities: {
destination: submenuId
}
}
}
};
} else {
// Regular skill button - use utterance format with dynamic marker
button.action = {
type: 'utterance',
data: {
utterance: {
intent: 'loadMenu',
entities: {
destination: 'dynamic:' + entry.skillId
}
}
}
};
}
return button;
}
/**
* Create a submenu view configuration
*/
function createSubmenuConfig(entry) {
const config = {
rule: 'main-menu/execute_main_menu',
timeout: 8,
viewConfig: {
type: 'MenuView',
id: 'submenu-' + entry.id,
title: entry.submenuTitle || entry.title,
listDefault: {
menuButtonType: 'SkillButton'
},
list: []
}
};
// Add back button that closes the menu (returns to main)
config.viewConfig.list.push({
id: '__back__',
label: '← Back',
colors: COLOR_MAP['default'],
iconSrc: 'resources/icons/settings.png',
action: {
type: 'utterance',
data: {
utterance: {
intent: 'loadMenu',
entities: {
destination: '__goback__'
}
}
}
}
});
// Add skill buttons from children
if (entry.children && entry.children.length > 0) {
entry.children.forEach(child => {
config.viewConfig.list.push({
id: child.id,
label: child.title,
colors: getColors(child.color),
iconSrc: child.icon,
action: {
type: 'utterance',
data: {
utterance: {
intent: 'loadMenu',
entities: {
destination: 'dynamic:' + child.skillId
}
}
}
}
});
});
}
return config;
}
/**
* Inject dynamic skills into a loaded menu config
*/
function injectDynamicSkills(originalConfig) {
log('injectDynamicSkills called');
if (!originalConfig) {
warn('originalConfig is null/undefined');
return originalConfig;
}
if (!originalConfig.viewConfig) {
warn('originalConfig.viewConfig is missing');
return originalConfig;
}
if (!originalConfig.viewConfig.list) {
warn('originalConfig.viewConfig.list is missing');
return originalConfig;
}
log('Original config has', originalConfig.viewConfig.list.length, 'buttons');
const entries = scanAllMenuEntries();
if (entries.length === 0) {
warn('No dynamic entries found to inject');
return originalConfig;
}
// Clone the config to avoid mutating the original
const config = JSON.parse(JSON.stringify(originalConfig));
// Add dynamic skill buttons to the list
entries.forEach(entry => {
const button = entryToMenuButton(entry);
log('Adding button:', button.label, '- id:', button.id);
config.viewConfig.list.push(button);
});
log('Final config has', config.viewConfig.list.length, 'buttons');
log('Injected', entries.length, 'dynamic skills into menu');
return config;
}
/**
* Patch the main-menu skill's redirectToSkill method
*/
function patchMainMenuSkill(be) {
log('patchMainMenuSkill called');
if (!be) {
warn('be is null/undefined');
return;
}
if (!be.skills) {
warn('be.skills is null/undefined');
return;
}
if (!be.skills['@be/main-menu']) {
warn('@be/main-menu skill not found in be.skills');
log('Available skills:', Object.keys(be.skills).join(', '));
return;
}
const mainMenuSkill = be.skills['@be/main-menu'];
const originalRedirectToSkill = mainMenuSkill.redirectToSkill.bind(mainMenuSkill);
mainMenuSkill.redirectToSkill = function(skill) {
log('redirectToSkill called with:', skill);
// Handle back navigation
if (skill === '__goback__') {
log('Going back to main menu');
if (_jibo && _jibo.face && _jibo.face.views) {
_jibo.face.views.changeView({
remove: true,
leaveEmpty: true,
transitionClose: _jibo.face.views.TRANSITION.UP
}, () => {
// Reload the main menu by launching main-menu skill again
this.redirect('@be/main-menu', {});
});
}
return;
}
// Handle dynamic submenus
if (skill && skill.startsWith('dynamic-submenu-')) {
log('Showing submenu:', skill);
const submenuConfig = _submenuConfigs[skill];
if (submenuConfig && _jibo && _jibo.face && _jibo.face.views) {
// Show the submenu view
_jibo.face.views.changeView(submenuConfig, (err, result) => {
if (err) {
warn('Failed to show submenu:', err);
return;
}
log('Submenu displayed successfully');
// Set up selection handler for the submenu
if (result && result.on) {
result.on('select', (selection) => {
log('Submenu item selected:', selection);
if (selection && selection.action && selection.action.data) {
const destination = selection.action.data.utterance?.entities?.destination;
if (destination) {
this.redirectToSkill(destination);
}
}
});
}
});
return;
}
warn('Submenu config not found:', skill);
return;
}
// Handle dynamic skills (prefixed with 'dynamic:')
if (skill && skill.startsWith('dynamic:')) {
const actualSkillId = skill.substring(8); // Remove 'dynamic:' prefix
log('Launching dynamic skill:', actualSkillId);
this.skillChosen = true;
if (_jibo && _jibo.face && _jibo.face.views) {
_jibo.face.views.changeView({
remove: true,
leaveEmpty: true,
transitionClose: _jibo.face.views.TRANSITION.UP
}, () => {
// Try to find and launch the skill
if (be.skills[actualSkillId]) {
log('Found skill as:', actualSkillId);
this.redirect(actualSkillId, {});
} else if (be.skills['@be/' + actualSkillId]) {
log('Found skill as:', '@be/' + actualSkillId);
this.redirect('@be/' + actualSkillId, {});
} else {
warn('Skill not found:', actualSkillId);
warn('Available skills:', Object.keys(be.skills).join(', '));
this.redirect('@be/chitchat', {
NLParse: {
domain: 'chitchat',
intent: 'scripted',
mimId: 'JBO_ImSorryIDidntUnderstandThat'
}
});
}
});
}
return;
}
// For all other skills, use the original method
return originalRedirectToSkill(skill);
};
log('main-menu skill redirectToSkill patched successfully');
}
/**
* Apply the patch to the BE instance
*/
function applyPatch(be) {
log('applyPatch called');
_beInstance = be;
if (be && be.log) {
be.log.info('[MENU-PATCH] initialized');
}
// Test scanning immediately
log('Testing skill scan on startup...');
const testEntries = scanAllMenuEntries();
log('Startup scan found', testEntries.length, 'entries');
testEntries.forEach(e => log(' -', e.title, '(' + e.type + ')'));
// Patch the main-menu skill after a short delay to ensure it's loaded
setTimeout(() => {
patchMainMenuSkill(be);
}, 100);
}
/**
* Patch jibo.loader.load to intercept menu loading
*/
function patchLoader(jibo, skillsRoot) {
log('patchLoader called');
_jibo = jibo;
if (!jibo) {
warn('jibo is null/undefined');
return;
}
if (!jibo.loader) {
warn('jibo.loader is null/undefined');
return;
}
if (!jibo.loader.load) {
warn('jibo.loader.load is null/undefined');
return;
}
const originalLoad = jibo.loader.load.bind(jibo.loader);
jibo.loader.load = function(resourcePath, callback) {
// Log all resource loads to see what's happening
log('>>> jibo.loader.load called with:', resourcePath);
// Check if this is loading a dynamic submenu
if (resourcePath && resourcePath.startsWith('dynamic-submenu-')) {
const submenuConfig = _submenuConfigs[resourcePath];
if (submenuConfig) {
log('Loading dynamic submenu:', resourcePath);
if (callback) {
callback(null, submenuConfig);
}
return;
}
}
// Check if this is the main menu - match various possible paths
const isMainMenu = resourcePath && (
resourcePath.includes('main-menu-verbal.json') ||
resourcePath.includes('main-menu.json') ||
resourcePath === 'resources/views/main-menu-verbal.json' ||
resourcePath.endsWith('main-menu-verbal.json')
);
if (isMainMenu) {
log('*** INTERCEPTING MAIN MENU LOAD ***');
log('Resource path:', resourcePath);
originalLoad(resourcePath, function(err, config) {
if (err) {
warn('Error loading original menu config:', err);
if (callback) callback(err);
return;
}
log('Original menu config loaded successfully');
log('Original button count:', config?.viewConfig?.list?.length || 0);
// Inject dynamic skills
const patchedConfig = injectDynamicSkills(config);
log('Patched button count:', patchedConfig?.viewConfig?.list?.length || 0);
if (callback) callback(null, patchedConfig);
});
return;
}
// For all other resources, use original loader
return originalLoad(resourcePath, callback);
};
log('jibo.loader.load patched successfully');
}
/**
* Clear the cached menu entries (useful for rescanning)
*/
function clearCache() {
_cachedMenuEntries = null;
_submenuConfigs = {};
_dynamicSkillIds.clear();
}
/**
* Get the currently scanned menu entries (for debugging)
*/
function getMenuEntries() {
return scanAllMenuEntries();
}
/**
* Check if a skill ID is a dynamic skill
*/
function isDynamicSkill(skillId) {
return _dynamicSkillIds.has(skillId);
}
module.exports = {
applyPatch: applyPatch,
patchLoader: patchLoader,
clearCache: clearCache,
getMenuEntries: getMenuEntries,
isDynamicSkill: isDynamicSkill,
SKILLS_ROOT: SKILLS_ROOT
};

View File

@@ -0,0 +1,335 @@
"use strict";
/**
* Menu Manager - Handles showing menus and submenus on Jibo's screen
*
* Supports:
* - Showing static menu definitions from JSON files
* - Dynamically scanning the Skills directory for menuEntry.json files
* - Submenu navigation with automatic back button
*
* Usage:
* const mm = require('./menu/menu-manager');
* mm.showMenuFromSkills('/opt/jibo/Jibo/Skills'); // Show main menu from skills
* mm.showSubmenu('/opt/jibo/Jibo/Skills/MySubmenu'); // Show specific submenu
*/
const path = require('path');
const fs = require('fs');
const skillsScanner = require(path.join(__dirname, 'skills-scanner'));
// Track menu history for back navigation
let menuHistory = [];
let currentSkillsRoot = '/opt/jibo/Jibo/Skills';
/**
* Build a view configuration object from a menu definition
* @param {object} menuDef - Menu definition with buttons array
* @param {object} options - Additional options (isSubmenu, parentPath, etc.)
* @returns {object} View configuration for jibo.face.views.changeView
*/
function buildViewConfig(menuDef, options = {}) {
const viewConfig = {
viewConfig: {
type: 'MenuView',
id: menuDef.id || 'menu',
title: menuDef.title || null,
ignoreSwipeDown: menuDef.allowSwipe === false ? true : false,
listDefault: menuDef.listDefault || { menuButtonType: 'ActionButton', colors: 'default' },
list: [],
},
open: menuDef.open || {},
defaultClose: menuDef.defaultClose || { remove: true, transitionClose: 'trans_down' },
defaultSelect: menuDef.defaultSelect || { remove: true, transitionClose: 'trans_down' }
};
// Add back button for submenus
if (options.isSubmenu || menuDef.isSubmenu) {
viewConfig.viewConfig.list.push({
id: '__back__',
label: '← Back',
iconSrc: 'core://resources/actionIcons/back.png',
colors: 'default',
actions: [{ type: 'be:menu_back' }]
});
}
// Process each button in the menu
(menuDef.buttons || []).forEach(b => {
const item = {
id: b.id || b.label,
label: b.label || b.id,
iconSrc: b.icon || b.iconSrc || skillsScanner.DEFAULT_ICON,
colors: b.colors || b.color || menuDef.colors || 'default',
};
// Determine actions based on button type
if (b.actions || b.events) {
// Explicit actions provided
item.actions = b.actions || b.events;
} else if (b.skillId) {
// Regular skill - launch it
item.actions = [{ type: 'be:launch', data: { skillId: b.skillId } }];
} else if (b.submenu && Array.isArray(b.submenu)) {
// Submenu with embedded buttons - open inline submenu
item.actions = [{
type: 'be:open_submenu',
data: {
submenu: b.submenu,
submenuTitle: b.submenuTitle || b.label,
submenuPath: b.submenuPath
}
}];
} else if (b.submenuPath) {
// Submenu by path - open from disk
item.actions = [{
type: 'be:open_submenu_path',
data: { submenuPath: b.submenuPath }
}];
} else if (b.utterance) {
// Legacy utterance-based action
item.actions = [{ type: 'utterance', data: { utterance: b.utterance } }];
} else {
// No action defined
item.actions = [];
}
// Copy hit area polygon if defined (for custom button shapes)
if (b.hitAreaPolygon) {
item.hitAreaPolygon = b.hitAreaPolygon;
}
viewConfig.viewConfig.list.push(item);
});
return viewConfig;
}
/**
* Handle menu item selection events
* @param {object} selection - The selected menu item
* @param {function} cb - Callback function
*/
function handleMenuSelection(selection, cb) {
if (!selection || !selection.actions || !selection.actions.length) {
if (cb) cb(null, selection);
return;
}
const action = selection.actions[0];
switch (action.type) {
case 'be:menu_back':
// Go back to previous menu
goBack(cb);
break;
case 'be:open_submenu':
// Open inline submenu with embedded data
if (action.data && action.data.submenu) {
showInlineSubmenu(action.data.submenu, action.data.submenuTitle, action.data.submenuPath, cb);
}
break;
case 'be:open_submenu_path':
// Open submenu from disk path
if (action.data && action.data.submenuPath) {
exports.showSubmenu(action.data.submenuPath, cb);
}
break;
case 'be:launch':
// Launch skill - let the BE framework handle this
if (cb) cb(null, selection);
break;
default:
if (cb) cb(null, selection);
}
}
/**
* Show an inline submenu with embedded button data
* @param {Array} submenuButtons - Array of button definitions
* @param {string} title - Submenu title
* @param {string} submenuPath - Path for history tracking
* @param {function} cb - Callback
*/
function showInlineSubmenu(submenuButtons, title, submenuPath, cb) {
// Save current state to history
menuHistory.push({ type: 'main', path: currentSkillsRoot });
const submenuDef = {
id: 'submenu-' + (title || 'sub').toLowerCase().replace(/\s+/g, '-'),
title: title || 'Menu',
isSubmenu: true,
buttons: submenuButtons.map(b => ({
id: b.id,
label: b.label,
icon: b.icon || b.iconSrc,
colors: b.colors || b.color,
skillId: b.skillId,
description: b.description
}))
};
const viewConfig = buildViewConfig(submenuDef, { isSubmenu: true });
if (typeof jibo === 'undefined' || !jibo.face || !jibo.face.views) {
if (cb) cb(new Error('jibo not initialized'));
return;
}
jibo.face.views.changeView(viewConfig, function(err, result) {
if (err) {
if (cb) cb(err);
return;
}
// Set up selection handler for submenu
if (result && result.on) {
result.on('select', function(selection) {
handleMenuSelection(selection, cb);
});
}
if (cb) cb(null, result);
});
}
/**
* Go back to the previous menu in history
* @param {function} cb - Callback
*/
function goBack(cb) {
const previous = menuHistory.pop();
if (!previous) {
// No history, show main menu
exports.showMenuFromSkills(currentSkillsRoot, cb);
return;
}
if (previous.type === 'main') {
exports.showMenuFromSkills(previous.path || currentSkillsRoot, cb);
} else if (previous.type === 'submenu' && previous.path) {
exports.showSubmenu(previous.path, cb);
} else {
exports.showMenuFromSkills(currentSkillsRoot, cb);
}
}
/**
* Show a menu from a static JSON file
* @param {string} menuPath - Relative path to menu JSON file
* @param {function} cb - Callback
*/
exports.showMenu = function (menuPath, cb) {
try {
const menuDef = require(path.join(__dirname, '..', menuPath));
const viewConfig = buildViewConfig(menuDef);
if (typeof jibo === 'undefined' || !jibo.face || !jibo.face.views) {
throw new Error('jibo not initialized');
}
jibo.face.views.changeView(viewConfig, cb || function(){});
}
catch (e) {
console.warn('menu-manager.showMenu error', e);
if (cb) cb(e);
}
};
/**
* Show the main menu by scanning the Skills directory for menuEntry.json files
* @param {string} skillsRootPath - Path to Skills directory
* @param {function} cb - Callback
*/
exports.showMenuFromSkills = function (skillsRootPath, cb) {
try {
const root = skillsRootPath || '/opt/jibo/Jibo/Skills';
currentSkillsRoot = root;
menuHistory = []; // Reset history when showing main menu
const menuDef = skillsScanner.scanSkills(root);
const viewConfig = buildViewConfig(menuDef);
if (typeof jibo === 'undefined' || !jibo.face || !jibo.face.views) {
throw new Error('jibo not initialized');
}
jibo.face.views.changeView(viewConfig, function(err, result) {
if (err) {
console.warn('menu-manager.showMenuFromSkills error', err);
if (cb) cb(err);
return;
}
// Set up selection handler
if (result && result.on) {
result.on('select', function(selection) {
handleMenuSelection(selection, cb);
});
}
if (cb) cb(null, result);
});
}
catch (e) {
console.warn('menu-manager.showMenuFromSkills error', e);
if (cb) cb(e);
}
};
/**
* Show a submenu by scanning a specific directory
* @param {string} submenuPath - Full path to the submenu directory
* @param {function} cb - Callback
*/
exports.showSubmenu = function (submenuPath, cb) {
try {
// Save current state to history
if (menuHistory.length === 0) {
menuHistory.push({ type: 'main', path: currentSkillsRoot });
}
const menuDef = skillsScanner.getSubmenu(submenuPath);
const viewConfig = buildViewConfig(menuDef, { isSubmenu: true });
if (typeof jibo === 'undefined' || !jibo.face || !jibo.face.views) {
throw new Error('jibo not initialized');
}
jibo.face.views.changeView(viewConfig, function(err, result) {
if (err) {
console.warn('menu-manager.showSubmenu error', err);
if (cb) cb(err);
return;
}
// Set up selection handler
if (result && result.on) {
result.on('select', function(selection) {
handleMenuSelection(selection, cb);
});
}
if (cb) cb(null, result);
});
}
catch (e) {
console.warn('menu-manager.showSubmenu error', e);
if (cb) cb(e);
}
};
/**
* Clear menu history (useful when closing menu completely)
*/
exports.clearHistory = function() {
menuHistory = [];
};
/**
* Get current menu history (for debugging)
*/
exports.getHistory = function() {
return menuHistory.slice();
};
/**
* Get the skills scanner module for direct access
*/
exports.skillsScanner = skillsScanner;

View File

@@ -0,0 +1,25 @@
{
"id": "exampleMenu",
"title": "Example Menu",
"buttons": [
{
"id": "one",
"label": "One",
"icon": "core://resources/actionIcons/default.png",
"utterance": "one"
},
{
"id": "two",
"label": "Two",
"icon": "core://resources/actionIcons/default.png",
"utterance": "two"
},
{
"id": "hex",
"label": "Hex",
"icon": "core://resources/actionIcons/default.png",
"utterance": "hex",
"hitAreaPolygon": [165,0,330,82.5,330,247.5,165,330,0,247.5,0,82.5]
}
]
}

View File

@@ -0,0 +1,305 @@
"use strict";
/**
* Skills Scanner - Scans the Skills directory for menuEntry.json files
*
* menuEntry.json Schema:
* {
* "type": "skill" | "submenu", // Required: "skill" for launchable skill, "submenu" for folder containing skills
* "title": "Display Name", // Required: Button label shown on Jibo's screen
* "icon": "path/to/icon.png", // Required: Icon path (relative to skill folder or core:// URL)
* "color": "blue", // Optional: Button color theme (default, blue, green, red, purple, orange, etc.)
* "skillId": "@namespace/skill-id", // Required for type="skill": The skill ID to launch
* "description": "Short description",// Optional: Tooltip/accessibility text
* "order": 0, // Optional: Sort order (lower = first, default: 100)
* "hidden": false // Optional: Hide from menu (default: false)
* }
*/
const fs = require('fs');
const path = require('path');
// Default icon path for skills without custom icons (relative to @be/main-menu)
const DEFAULT_ICON = 'resources/icons/settings.png';
const DEFAULT_SUBMENU_ICON = 'resources/icons/fun-stuff.png';
const DEFAULT_COLOR = 'default';
const DEFAULT_ORDER = 100;
/**
* Safely read and parse a JSON file
* @param {string} filePath - Path to JSON file
* @returns {object|null} Parsed JSON or null on error
*/
function safeReadJson(filePath) {
try {
const txt = fs.readFileSync(filePath, 'utf8');
if (!txt || txt.trim().length === 0) return null;
return JSON.parse(txt);
}
catch (e) {
console.warn('skills-scanner: failed to read json', filePath, e.message);
return null;
}
}
/**
* Check if path is a directory
* @param {string} p - Path to check
* @returns {boolean}
*/
function isDirectory(p) {
try {
return fs.statSync(p).isDirectory();
}
catch (e) { return false; }
}
/**
* Scan a single skill directory and return menu entry
* @param {string} skillDir - Full path to skill directory
* @param {string} folderName - Name of the folder
* @returns {object|null} Menu entry object or null if invalid
*/
function scanSkillEntry(skillDir, folderName) {
const menuJsonPath = path.join(skillDir, 'menuEntry.json');
const menuJson = safeReadJson(menuJsonPath);
if (!menuJson) {
// No menuEntry.json - check if it's a valid skill by looking for package.json or index.html
const hasPackage = fs.existsSync(path.join(skillDir, 'package.json'));
const hasIndex = fs.existsSync(path.join(skillDir, 'index.html'));
if (hasPackage || hasIndex) {
// Auto-generate entry for legacy skills
return {
id: folderName,
type: 'skill',
title: folderName,
icon: DEFAULT_ICON,
color: DEFAULT_COLOR,
skillId: folderName,
path: skillDir,
order: DEFAULT_ORDER,
hidden: false
};
}
return null;
}
// Validate required fields
if (menuJson.hidden === true) {
return null; // Skip hidden entries
}
const entry = {
id: folderName,
type: menuJson.type || 'skill',
title: menuJson.title || menuJson.label || folderName,
icon: menuJson.icon || menuJson.iconSrc || (menuJson.type === 'submenu' ? DEFAULT_SUBMENU_ICON : DEFAULT_ICON),
color: menuJson.color || menuJson.colors || DEFAULT_COLOR,
description: menuJson.description || '',
path: skillDir,
order: typeof menuJson.order === 'number' ? menuJson.order : DEFAULT_ORDER,
hidden: menuJson.hidden === true
};
// For skills, include skillId
if (entry.type === 'skill') {
entry.skillId = menuJson.skillId || folderName;
}
// For submenus, scan child directories
if (entry.type === 'submenu') {
entry.submenu = scanSubmenuChildren(skillDir);
// Copy submenu-specific properties
if (menuJson.submenuTitle) {
entry.submenuTitle = menuJson.submenuTitle;
}
}
// Support for legacy isSubmenu flag
if (menuJson.isSubmenu === true && entry.type !== 'submenu') {
entry.type = 'submenu';
entry.submenu = scanSubmenuChildren(skillDir);
}
return entry;
}
/**
* Scan children of a submenu directory
* @param {string} submenuDir - Path to submenu directory
* @returns {Array} Array of skill entries
*/
function scanSubmenuChildren(submenuDir) {
const children = [];
let items;
try {
items = fs.readdirSync(submenuDir);
} catch (e) {
return children;
}
items.forEach(name => {
// Skip hidden folders and @be
if (name.startsWith('.') || name === '@be') return;
const childPath = path.join(submenuDir, name);
if (!isDirectory(childPath)) return;
const entry = scanSkillEntry(childPath, name);
if (entry && entry.type === 'skill') {
children.push(entry);
}
// Note: Nested submenus within submenus are not supported (single level only)
});
// Sort by order, then alphabetically
children.sort((a, b) => {
if (a.order !== b.order) return a.order - b.order;
return a.title.localeCompare(b.title);
});
return children;
}
/**
* Scan the Skills root directory for all menu entries
* @param {string} rootDir - Path to Skills directory
* @returns {Array} Array of menu entries
*/
function scanDirForMenuEntries(rootDir) {
const entries = [];
let children;
try {
children = fs.readdirSync(rootDir);
} catch (e) {
console.warn('skills-scanner: failed to read skills directory', rootDir, e.message);
return entries;
}
children.forEach(name => {
// Skip hidden folders and @be (it's the core brain, not a menu item)
if (name.startsWith('.') || name === '@be') return;
const skillDir = path.join(rootDir, name);
if (!isDirectory(skillDir)) return;
const entry = scanSkillEntry(skillDir, name);
if (entry) {
entries.push(entry);
}
});
// Sort by order, then alphabetically
entries.sort((a, b) => {
if (a.order !== b.order) return a.order - b.order;
return a.title.localeCompare(b.title);
});
return entries;
}
/**
* Scan skills directory and return menu definition
* @param {string} rootDir - Path to Skills directory
* @returns {object} Menu definition with buttons array
*/
function scanSkills(rootDir) {
const entries = scanDirForMenuEntries(rootDir);
const menuDef = {
id: 'main-menu',
title: 'Apps',
buttons: []
};
entries.forEach(entry => {
const button = {
id: entry.id,
label: entry.title,
icon: entry.icon,
colors: entry.color,
description: entry.description
};
if (entry.type === 'submenu' && entry.submenu) {
// For submenus, include the submenu array and metadata
button.submenu = entry.submenu.map(s => ({
id: s.id,
label: s.title,
icon: s.icon,
colors: s.color,
skillId: s.skillId,
description: s.description
}));
button.submenuTitle = entry.submenuTitle || entry.title;
button.submenuPath = entry.path;
} else {
// Regular skill
button.skillId = entry.skillId;
}
menuDef.buttons.push(button);
});
return menuDef;
}
/**
* Get a specific submenu's contents by path
* @param {string} submenuPath - Path to the submenu directory
* @returns {object} Menu definition for the submenu
*/
function getSubmenu(submenuPath) {
const menuJsonPath = path.join(submenuPath, 'menuEntry.json');
const menuJson = safeReadJson(menuJsonPath) || {};
const folderName = path.basename(submenuPath);
const entries = scanSubmenuChildren(submenuPath);
return {
id: folderName + '-submenu',
title: menuJson.submenuTitle || menuJson.title || folderName,
isSubmenu: true,
parentPath: path.dirname(submenuPath),
buttons: entries.map(entry => ({
id: entry.id,
label: entry.title,
icon: entry.icon,
colors: entry.color,
skillId: entry.skillId,
description: entry.description
}))
};
}
/**
* Get all registered skills (flat list for skill loading)
* @param {string} rootDir - Path to Skills directory
* @returns {Array} Array of skill IDs
*/
function getAllSkillIds(rootDir) {
const skillIds = [];
const entries = scanDirForMenuEntries(rootDir);
entries.forEach(entry => {
if (entry.type === 'skill' && entry.skillId) {
skillIds.push(entry.skillId);
} else if (entry.type === 'submenu' && entry.submenu) {
entry.submenu.forEach(s => {
if (s.skillId) skillIds.push(s.skillId);
});
}
});
return skillIds;
}
module.exports = {
scanSkills,
scanDirForMenuEntries,
getSubmenu,
getAllSkillIds,
DEFAULT_ICON,
DEFAULT_SUBMENU_ICON,
DEFAULT_COLOR
};

View File

@@ -0,0 +1,103 @@
# Be Framework
[![Build Status](https://jenkins2.jibo.com/buildStatus/icon?job=be/be-framework/master)](https://jenkins2.jibo.com/job/be/job/be-framework/job/master/)
Interface for skills that run-inside of Be as an asset-pack.
Read all the [API docs here](https://github.jibo.com/pages/be/be-framework/).
## Contributing
1. yarn install --no-options
2. gulp debug
## Usage
```js
import {BeSkill} from '@be/be-framework';
/**
* Create a custom skill to run inside of Be.
* @class MySkill
* @extends BeSkill
*/
class MySkill extends BeSkill {
/**
* @constructor
* @param {String} assetPack Should be the name asset-pack when
* running inside of Be
*/
constructor(assetPack?) {
super(assetPack);
}
/**
* Open a skill, must override
* @method open
* @param {Object} [result] Parse object from `jibo.gl`
*/
open(options) {}
/**
* Unload a skill, must override
* @method close
* @param {Function} done Callback when completed with close (must call!)
*/
close(done) {
done();
}
/**
* Trigger a refresh
* @method refresh
* @param {Object} [result] Parse object from `jibo.gl`
*/
refresh(options) {
this.open(options);
}
}
```
## Exports
For the Be superskill to be able to properly import and create this skill, its main export needs to be of either of the two following forms:
```js
class MySkill extends BeSkill { /* your class */ }
module.exports = MySkill;
```
or if you also want to export other things:
```js
class MySkill extends BeSkill { /* your class */ }
const MyConst = { foo: 'bar' };
// The export needs to be called 'Skill'
const Skill = MySkill;
export {
Skill,
MyConst
}
```
## APIs
BeSkill contains two methods that can be called by child skills:
### redirect(skillName:String, options?:Object)
Redirect to another skill from within be, for instance, `this.redirect('weather')`.
### exit(): void
The skill has completed, call this will tell Be go to back to idle.
### assetPack:String
The name of the asset-pack passed in from the constructor. This can be used with `jibo.bt.run` or `jibo.bt.create` to pass in the name of the asset-pack in to the overrides.
## Publishing
Run `gulp publish` on the command line to publish a new version of be-framework.

View File

@@ -0,0 +1,9 @@
var gulp = require('gulp');
require('jibo-gulp')(gulp, {
coverage: true,
coverageSourceMaps: true,
typings: [
'typings/index.d.ts',
'typings-local/index.d.ts'
]
});

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,240 @@
/// <reference types="node" />
import { EventEmitter } from 'events';
import { Log } from 'jibo-log';
import Holiday from './plugins/holiday/Holiday';
/**
* @description Options interface
* @interface BeSkill~Options
* @prop {string} [assetPack] Asset pack name
* @prop {string} [rootPath] Path to the aset pack
*/
export interface Options {
assetPack?: string;
rootPath?: string;
}
export interface Plugins {
holiday: Holiday;
[x: string]: any;
}
/**
* @description Skill exit method payload
* @interface BeSkill~ExitOptions
* @prop {boolean} [noElementsOfSurprise] If true then we bypass Elements of Surprise
* @prop {boolean} [globalNoMatch] If true then we go directly to Idle which will
* respond with its globalNoMatch logic
*/
export interface ExitOptions {
noElementsOfSurprise?: boolean;
globalNoMatch?: boolean;
}
/**
* Callback for async events
* @callback BeSkill~AsyncCallback
* @param {Error|String} [err] Error, if one occurs.
*/
export declare type AsyncCallback = (err?: Error | string) => void;
/**
* A generator callback function providing both `resolve` and `reject` functions
* @callback BeSkill~PromiseGenerator
* @param {Function} resolve
* @param {Function} reject
*/
export declare type PromiseGenerator = (resolve: (ret?: any) => void, reject: (err?: any) => void) => void;
/**
* A function that gets called when switching skills.
* @callback BeSkill~PreSkillHook
* @param {string} oldSkill Name of current skill
* @param {string} newSkill Name of new skill
* @param {object} results ASR results (might be empty)
* @returns {Function} PromiseGenerator
*/
export declare type OpenHook = (oldSkill: string, newSkill: string, results: any) => PromiseGenerator;
/**
* Base class for skill running inside of Be
* @class BeSkill
* @extends EventEmitter
* @param {Object} [options] Be options for setting up this skill or the assetPack name.
* @param {String} [options.assetPack=''] Name of the asset pack if running in the context of another skill.
* @param {String} [options.rootPath=''] The path to this skill's root folder.
*/
declare class BeSkill extends EventEmitter {
/**
* Current version of the library.
* @name BeSkill.version
* @type {String}
*/
static version: string;
/**
* The currently installed plugins
* @name BeSkill.plugins
* @type {Object}
*/
static plugins: Plugins;
/**
* A list of hooks to be called before launching skill
* @name BeSkill.openHooks
* @type {Function[]}
*/
static openHooks: OpenHook[];
/**
* Asset pack name for this skill, if running within Be. Otherwise, this is empty.
* @name BeSkill#assetPack
* @type {String}
*/
assetPack: string;
/**
* Root path for skill.
* @name BeSkill#rootPath
* @type {String}
*/
rootPath: string;
/**
* Log instance for skill.
* @name BeSkill#log
* @type {Object}
*/
log: Log;
/**
* Keep track of whether an external factor wants the surprise skill to be skipped.
* Don't confuse with the noElementsOfSurprise property in ExitOptions which a skill itself can specify.
* @name BeSkill#skipSurprisesExternal
* @type {boolean}
* @public
*/
skipSurprisesExternal: boolean;
/**
* Keep track of whether the skill is interruptible or not
* @name BeSkill#_isInterruptible
* @type {boolean}
* @protected
*/
protected _isInterruptible: boolean;
/**
* Log an error code
* @method BeSkill.errorCode
* @param {String} code The error code
* @param {String} [message=''] An optional message
*/
static errorCode(code: string, message?: string): void;
/**
* Register a plugin
* @method BeSkill.registerPlugin
* @param {String} name The name of the property to register
* @param {Function} plugin The plugin to load
*/
static registerPlugin(name: string, plugin: PromiseGenerator): void;
/**
* Register a skill open hook method. Called whenever a skill is being launched.
* @method BeSkill.registerOpenHook
* @param {Function} hook The function to call on skill load
*/
static registerOpenHook(hook: OpenHook): void;
/**
* Called from Be, and in standalone, before opening any skill.
* Performs any asynchronous cleanup or preparation.
* Don't confuse with the instance method `open([result])`.
* @method BeSkill.open
* @param {String} lastSkill Name of skill that is stopping (null if no skill is stopping)
* @param {String} nextSkill Name of skill that is about to open
* @param {object} results - launch intent: the ASR results for the launch
* command, usually, but could also be empty or contain launch options from another source
*
* @param {Function} done Callback to call when done
*/
static open(lastSkill: string, nextSkill: string, results: any, done: AsyncCallback): void;
/**
* STATIC Use to statically initialize resources for all BeSkills.
* Don't confuse with `init()`
* @method BeSkill.init
* @param {Function} done Callback when complete
* @static
*/
static init(done: AsyncCallback): void;
constructor(options?: Options);
/**
* Initialize the eye in standalone mode.
* If you dont pass in an asset pack, this method will automatically start (call `open`) on your skill.
* Don't confuse with `init(done)`
* @method BeSkill#init
*/
init(): void;
/**
* Overrideable async hook that happens once, upon construction after jibo has initialized.
* @method BeSkill#postInit
* @param {Function} done Callback, first argument is an optional error.
*/
postInit(done: AsyncCallback): void;
/**
* Overrideable async hook that happens everytime before the skill is opened. This does
* not fire before each refresh.
* @method BeSkill#preload
* @param {Function} done Callback, first argument is an optional error.
*/
preload(done: AsyncCallback): void;
/**
* Overrideable method for a skill to indicate to Be whether or not it is currently interruptible
* If a skill is marked as NOT interruptible, skill switching for skills of equal or lower priority
* will be ignored. Skills of a higher priority will ignore this value and skill switch anyway.
* If a skill is marked as interruptible, skill switching for skills of any priority will be allowed.
* NOTE: this assumes a skill's open method has been called. As in, this does not include the time where a skill is pre-loading
* or in the process of closing.
* @method BeSkill#isInterruptible
* @return {boolean} return true is a skill is interruptible. return false otherwise
* By default skills are interruptible
*/
readonly isInterruptible: boolean;
/**
* Open a skill, must override.
* Don't confuse with the BeSkill static class method `open(lastSkill, nextSkill, results, done)`.
* @method BeSkill#open
* @param {Object} [result] launch intent: the parse object from the launch
* command, usually, but could also be empty or contain launch options from another source
* @param {boolean} [refresh] Optional flag that denotes we are 'refreshing' the skill (i.e. was opened already)
* @param {string} [previousSkillName] Optional param which denotes the previous skill name. If there was no previous skill this can be expected to be null
* @param {Object} [previousSkillOptions] Optional param which denotes the launch options for the previous skill. If there was no previous skill this can be expected to be null
*/
open(result?: any, refresh?: boolean, previousSkillName?: string, previousSkillOptions?: any): void;
/**
* Trigger a refresh
* @method BeSkill#refresh
* @param {Object} [result] Parse object from `jibo.gl`
*/
refresh(result?: any): void;
/**
* Unload a skill, must override
* @method BeSkill#close
* @param {Function} done Callback to call when completed.
* @param {string} pendingSkillName Skill that will be opened when this skill is closed
*/
close(done: AsyncCallback, pendingSkillName?: string): void;
/**
* Exit the application. Called internally when the skill is done.
* @param {ExitOptions} exitOptions Optional exit options for skill.
* @method BeSkill#exit
*/
exit(exitOptions?: ExitOptions): void;
/**
* Redirect to another internal Be skill
* @method BeSkill#redirect
* @param {String} skillName E.g. "weather"
* @param {Object} [options] Additional options for redirect
*/
redirect(skillName: string, options: any): void;
/**
* Tracks event data for Design/Product via Segment.
* See https://mixpanel.com/help/questions/articles/what-data-types-does-mixpanel-accept-as-properties
* for allowed data types.
* @method BeSkill#track
* @param {String} event Name of event
* @param {Object} [data] Dictionary of additional data.
*/
track(event: string, data?: any): void;
/**
* Destroy this skill. This should *probably* only be called from the Be superskill.
* The intent for this method is to un-allocate / restore state change from the skill constructor or skill init sequence
* @method BeSkill#destroy
* @param {Function(String)} done Callback to call when completed. Assumes an argument of a string error parameter or null
*/
destroy(done: any): void;
}
export default BeSkill;

View File

@@ -0,0 +1 @@
export default function (plugins: any): void;

View File

@@ -0,0 +1,3 @@
export import jibo_cai_utils = require('jibo-cai-utils');
export import jibo_state_machine = require('jibo-state-machine');
export import jibo_typed_events = require('jibo-typed-events');

View File

@@ -0,0 +1,3 @@
import { Log } from 'jibo-log';
declare const _default: Log;
export default _default;

View File

@@ -0,0 +1,13 @@
import BeSkill, { Options, ExitOptions } from './BeSkill';
import * as libraries from './libraries';
/**
* Utility function mostly for date, time and location.
* @namespace utils
*/
import * as utils from './utils';
/**
* Expose plugins for testing
* @namespace plugins
*/
import * as plugins from './plugins';
export { BeSkill, Options, ExitOptions, utils, libraries, plugins };

View File

@@ -0,0 +1,22 @@
export interface AnalyticsContext {
ssm_version: string;
be_version: string;
platform_version: string;
release_version: string;
}
export default class Analytics {
private _context;
private _currentSkill;
private _robotName;
private _loopSize;
private _log;
currentSkill: string;
/**
* A convenience method used whenever an event occurs within a skill.
* @method Analytics.skillAction
* @param {string} event The name of the event.
* @param {string} skill The name of the active skill.
* @param {Object} properties An object containing any relevant properties.
*/
skillEvent(event: string, properties?: any): void;
}

View File

@@ -0,0 +1,74 @@
export declare const SkillRename: {
'tutorial': string;
'friendly-tips': string;
'create': string;
};
export declare const IntentDefaults: {
'idle': string;
'surprises': string;
'surprises-date': string;
'surprises-ota': string;
'first-contact': string;
'main-menu': string;
'restore': string;
'bot-basics': string;
};
export declare const IntentRename: {
'chitchat': {
'scripted': string;
'gqa': string;
'emotionQuery': string;
'specificEmotionQuery': string;
};
'circuit-saver': {
'launchGame': string;
'menu': string;
};
'clock': {
'askForTime': string;
'askForDay': string;
'askForDate': string;
'whenIsHoliday': string;
'whenIsBirthday': string;
};
'photos': {
'createOnePhoto': string;
'createSomePhotos': string;
};
'what-can-you-do': {
'whatCanIDo': string;
'frustrated': string;
};
'gallery': {
'galleryOpen': string;
};
'greetings': {
'whatsUp': string;
'goodMorning': string;
'goodAfternoon': string;
'goodEvening': string;
'goodNight': string;
'goodBye': string;
'imHome': string;
'imBack': string;
'selfId': string;
};
'settings': {
'battery': string;
'volumeQuery': string;
'wifiStatus': string;
'wifiAddNetwork': string;
'wifiRemoveNetwork': string;
'menu': string;
};
'bot-basics': {
'tutorialOpen': string;
'menu': string;
};
'introductions': {
'enrollment': string;
'menu': string;
};
};
export declare function renameSkill(skillName: string): string;
export declare function getIntent(skill: string, launchData: any, prevSkill: string): any;

View File

@@ -0,0 +1,19 @@
import Router = require('router');
import { ServiceOptions, HTTPService } from 'jibo-service-framework';
export declare class SingletonEnforcer {
}
/**
* @description
* Service endpoint which exposes on-robot context data to those outside Be.
*
* @class ContextService
* @extends HTTPService
*/
export declare class ContextService extends HTTPService {
private static _instance;
static createInstance(options: ServiceOptions, rootDir?: string): ContextService;
static readonly instance: ContextService;
constructor(enforcer: SingletonEnforcer, options: ServiceOptions, rootDir?: string);
routes(url: Router): void;
private getContext(req, res);
}

View File

@@ -0,0 +1,32 @@
import jibo = require("jibo");
import { HolidayNode } from './HolidayNode';
export default class Holiday {
holidayModel: jibo.kb.Model;
/**
* Sets up the jibo server client
*/
init(): Promise<void>;
/**
* Fetches the holiday list
* @return {Promise<HolidayNode[]|null>}
*/
fetchHolidayList(): Promise<HolidayNode[] | null>;
/**
* Go through the list of holidays and pick out the user-enabled non-birthday days.
* @param {HolidayNode} holidays list of holidays
* @return {string[]} list of enabled holiday names
*/
filterEnabledHolidayNames(holidays: HolidayNode[]): string[];
/**
* Fill a Set with the users active holidays to use in MiMs
* @return {Set<string>} set of active holidays.
*/
getActiveHolidaySet(): Promise<Set<string>>;
/**
* Go through a list of holidays and pick out the names of holidays for a particular date
* @param {Date} filterDate the date for which to filter holidays
* @param {boolean} onlyEnabledHolidays whether to only include enabled holidays
* @return {string[]} list of todays holiday names
*/
filterHolidayNamesByDate(filterDate: Date, onlyEnabledHolidays: boolean): Promise<string[]>;
}

View File

@@ -0,0 +1,54 @@
import jibo = require("jibo");
export declare class HolidayNode extends jibo.kb.Node {
data: {
id: string;
name: string;
category: string;
subcategory?: string;
loopId: string;
memberId?: string;
isEnabled: boolean;
date: string;
endDate: string;
created: number;
};
/**
* UUID of the holiday.
* @type {String}
*/
readonly id: string;
/**
* Date of the holiday
* @type {String}
*/
readonly date: string;
/**
* End date of the holiday
*/
readonly endDate: string;
/**
* Name of the holiday
* @type {String}
*/
readonly name: string;
/**
* Whether members have enabled this holiday
* @type {String}
*/
readonly isEnabled: boolean;
/**
* The category of the holiday (e.g., birthday, national)
* @type {String}
*/
readonly category: string;
/**
* @return {String} The loop member's preferred spoken name.
*/
toString(): string;
/**
* Check whether the holiday is on the passed in date
* @param {Date} date to check
* @return {boolean} indicates whether holiday is on the passed in date
*/
isOnDate(date: Date): boolean;
}

View File

@@ -0,0 +1 @@
export * from './HolidayNode';

View File

@@ -0,0 +1,2 @@
import * as holiday from './holiday';
export { holiday };

View File

@@ -0,0 +1,25 @@
/**
* @class PackageUtils
* @memberof utils
*/
export default class PackageUtils {
/**
* Checks wheather `jibo.debug[.namespace]` in `package.json` is set to `true`.
* If no namespace is provided and `jibo.debug: true` then return `true`;
* If no namespace is provided and `jibo.debug: {}` is object then return `false`;
* @method utils.PackageUtils.debugMode
* @param {string} [debugNamespace] Namespace to debug.
* @returns {boolean} `true` if `jibo.debug[.namespace]` in `package.json` is `true`.
*/
static debugMode(debugNamespace?: string): boolean;
/**
* Checks wheather `jibo.debug[.namespace]` in `package.json` is set to `true`.
* If no namespace is provided and `jibo.debug: true` then return `true`;
* If no namespace is provided and `jibo.debug: {}` is object then return `false`;
* @method utils.PackageUtils._debugMode
* @param {object} packageObj `package.json` object.
* @param {string} [debugNamespace] Namespace to debug.
* @returns {boolean} `true` if `jibo.debug[.namespace]` in `package.json` is `true`.
*/
static _debugMode(packageObj: any, debugNamespace?: string): boolean;
}

View File

@@ -0,0 +1,7 @@
import jibo = require('jibo');
import Location = jibo.utils.Location;
import DateTime = jibo.utils.DateTime;
import DateTimeUtils = jibo.utils.DateTimeUtils;
import Timezone = jibo.utils.Timezone;
export { Location, DateTime, DateTimeUtils, Timezone };
export { default as PackageUtils } from './PackageUtils';

View File

@@ -0,0 +1,60 @@
{
"name": "@be/be-framework",
"version": "13.0.0",
"repository": {
"type": "git",
"url": "git@github.jibo.com:sdk/sdk.git"
},
"publishConfig": {
"registry": "http://npm.jibo.media.mit.edu:8081/repository/private/"
},
"description": "Framework for running skills inside of Be",
"main": "lib/be-framework.js",
"typings": "lib/dts/main.d.ts",
"scripts": {
"build": "gulp debug",
"build:release": "gulp",
"test": "gulp test && istanbul report && yarn coverage:check",
"coverage:check": "istanbul check-coverage --statements 30 --branches 20 --functions 30 --lines 30",
"coverage:report": "istanbul report && open coverage/lcov-report/index.html",
"coverage:remap": "remap-istanbul --input ./coverage/coverage-final.json --output ./coverage/coverage-final.json",
"test:debug": "gulp test --debug",
"test:report": "gulp test-report",
"clean": "gulp clean-all"
},
"monorailConfig": {
"public": false
},
"author": "Matt Karl <matt.karl@jibo.com>",
"license": "UNLICENSED",
"distribution": "PROPRIETARY AND CONFIDENTIAL - NOT FOR DISTRIBUTION",
"copyright": "Copyright (c) 2014-2018 Jibo, Inc. All Rights Reserved",
"files": [
"lib"
],
"engines": {
"node": ">=6.0"
},
"dependencies": {
"@jibo/analytics-node": "^5.0.0",
"@jibo/jetstream-client": "^3.0.0",
"jibo-cai-utils": "^7.0.0",
"jibo-embodied-dialog": "^9.0.0",
"jibo-log": "^6.0.0",
"jibo-service-framework": "^5.0.0",
"jibo-state-machine": "^8.0.0",
"jibo-typed-events": "^7.0.0",
"router": "^1.1.4",
"uuid": "^3.0.1"
},
"devDependencies": {
"@types/node": "6.0.94",
"istanbul": "^0.4.5",
"gulp": "^3.9.1",
"jibo": "^15.0.0",
"jibo-anim-db-animations": "19.0.2",
"jibo-gulp": "^9.0.0",
"skills-service-manager": "^16.0.0",
"jibo-tunable": "^1.2.0"
}
}

View File

@@ -0,0 +1,32 @@
## Documentation
Please also read the [Be Documentation](https://confluence.jibo.com/display/SKIL/Be+Documentation) for information on creating a skill in this organization and adding your skill to this repo as a dependency.
## Building
Build process is implemented using NPM scripts installed in the **package.json** file.
| Command | Description
|---|---|
|`yarn build` | Build the project in debug mode. |
|`yarn release` | Build the project in release mode. |
|`yarn watch` | Watch the source and behaviors, auto-rebuilds. |
|`yarn clean` | Deletes built JavaScript files. |
|`yarn start` | Alias for `yarn watch`. |
|`yarn sync` | Sync file to the robot</br> **Tip**: Use `jibo run` after to launch skills |
|`yarn addsshkey` | Install your public SSH key on the robot (OS X Only). |
## Publishing
To publish, bump the version number (optional) and either publish in debug or release mode. This will generate a release/debug build before publishing and will Git push the version bump and the tag. For example:
```bash
# Bump the version, see NPM docs for more info
npm version patch
# Publish in debug mode with source maps
yarn publish:debug
# Publish in release mode, minfied
yarn publish:release
```

View File

@@ -0,0 +1,250 @@
{
"framerate": 30,
"duration": 60,
"layers": [
{
"id": "5b631fd526fc49068920fc50cb5c10d6",
"name": "Body #1",
"type": "Body",
"visible": true,
"locked": false,
"keyframes": [
{
"value": {
"Head": 0,
"Torso": 0,
"Pelvis": 0
},
"time": 0
},
{
"value": {
"Head": -46.99999999999999,
"Torso": 58.99999999999999,
"Pelvis": 0
},
"time": 30
},
{
"value": {
"Head": 0,
"Torso": 0,
"Pelvis": 0
},
"time": 59
}
]
},
{
"id": "74761c70b7af43d2a67239b2155ce88d",
"name": "Eye #3",
"type": "Eye",
"visible": true,
"locked": false,
"keyframes": [
{
"value": {
"Rotate": 0,
"Scale": {
"x": 1,
"y": 1
},
"Translate": {
"x": 0,
"y": 0
},
"Vertex 1": {
"x": -281.3073655214508,
"y": -297.2113789169163
},
"Vertex 2": {
"x": 0,
"y": -297.2113789169163
},
"Vertex 3": {
"x": 281.3073655214508,
"y": -297.2113789169163
},
"Vertex 4": {
"x": -281.3073655214508,
"y": 0
},
"Vertex 5": {
"x": 0,
"y": 0
},
"Vertex 6": {
"x": 281.3073655214508,
"y": 0
},
"Vertex 7": {
"x": -281.3073655214508,
"y": 297.2113789169163
},
"Vertex 8": {
"x": 0,
"y": 297.2113789169163
},
"Vertex 9": {
"x": 281.3073655214508,
"y": 297.2113789169163
}
},
"time": 0
},
{
"value": {
"Rotate": 0,
"Scale": {
"x": 1,
"y": 1
},
"Translate": {
"x": 0,
"y": 0
},
"Vertex 1": {
"x": -281.3073655214508,
"y": -297.2113789169163
},
"Vertex 2": {
"x": 0,
"y": -297.2113789169163
},
"Vertex 3": {
"x": 281.3073655214508,
"y": -297.2113789169163
},
"Vertex 4": {
"x": -281.3073655214508,
"y": 0
},
"Vertex 5": {
"x": 0,
"y": 0
},
"Vertex 6": {
"x": 281.3073655214508,
"y": 0
},
"Vertex 7": {
"x": -281.3073655214508,
"y": 297.2113789169163
},
"Vertex 8": {
"x": 0,
"y": 297.2113789169163
},
"Vertex 9": {
"x": 281.3073655214508,
"y": 297.2113789169163
}
},
"time": 27
},
{
"value": {
"Rotate": 0,
"Scale": {
"x": 1,
"y": 0.1529786611415199
},
"Translate": {
"x": -7.370441612130465,
"y": 248.1911389552236
},
"Vertex 1": {
"x": -281.3073655214508,
"y": -297.2113789169163
},
"Vertex 2": {
"x": 0,
"y": -297.2113789169163
},
"Vertex 3": {
"x": 281.3073655214508,
"y": -297.2113789169163
},
"Vertex 4": {
"x": -281.3073655214508,
"y": 0
},
"Vertex 5": {
"x": 0,
"y": 0
},
"Vertex 6": {
"x": 281.3073655214508,
"y": 0
},
"Vertex 7": {
"x": -281.3073655214508,
"y": 297.2113789169163
},
"Vertex 8": {
"x": 0,
"y": 297.2113789169163
},
"Vertex 9": {
"x": 281.3073655214508,
"y": 297.2113789169163
}
},
"time": 30
},
{
"value": {
"Rotate": 0,
"Scale": {
"x": 1,
"y": 1
},
"Translate": {
"x": 0,
"y": 0
},
"Vertex 1": {
"x": -281.3073655214508,
"y": -297.2113789169163
},
"Vertex 2": {
"x": 0,
"y": -297.2113789169163
},
"Vertex 3": {
"x": 281.3073655214508,
"y": -297.2113789169163
},
"Vertex 4": {
"x": -281.3073655214508,
"y": 0
},
"Vertex 5": {
"x": 0,
"y": 0
},
"Vertex 6": {
"x": 281.3073655214508,
"y": 0
},
"Vertex 7": {
"x": -281.3073655214508,
"y": 297.2113789169163
},
"Vertex 8": {
"x": 0,
"y": 297.2113789169163
},
"Vertex 9": {
"x": 281.3073655214508,
"y": 297.2113789169163
}
},
"time": 33
}
]
}
],
"version": "0.5.0",
"scale": 1
}

View File

@@ -0,0 +1,126 @@
["Who is Taylor Swift?", "Taylor Alison Swift is an American singer-songwriter."],
["Who's Taylor Swift?", "Taylor Alison Swift is an American singer-songwriter."],
["Who is Barack Obama?", "Barack Hussein Obama II is the 44th and current President of the United States."],
["Who's Barack Obama?", "Barack Hussein Obama II is the 44th and current President of the United States."],
["When was Elvis Presley born?", "Elvis Presley was born on Tuesday, January 8, 1935"],
["When did Elvis Presley die?", "Elvis Presley died on Tuesday, August 16, 1977"],
["Where was Michael Jordan born?", "Kings County Brooklyn, New York"],
["Where was John F. Kennedy born?", "The birth place of John F Kennedy is Brookline, Massachusetts"],
["Where did Abraham Lincoln die?", "The answer is Washington, District of Columbia"],
["How old is Madonna?", "The answer is 58 years 3 days"],
["How old was George Washington?", "The answer is 67 years 9 months 22 days"],
["Who is Taylor Swift's father?", "Scott Kingsley Swift"],
["Who's Taylor Swift's father?", "Scott Kingsley Swift"],
["Who was Ernest Hemingway's mother?", "Grace Hall-Hemingway"],
["Who was Thomas Edison's brother?", "William Pitt Edison, Carlile Snow Edison and Samuel Ogden Edison"],
["Who is Bill Clinton's daughter?", "The answer is Chelsea Clinton"],
["Who's Bill Clinton's daughter?", "The answer is Chelsea Clinton"],
["Who was Benjamin Franklin's son?", "William Franklin and Francis Folger Franklin"],
["Who was Ronald Reagan's wife?", "The wives of Ronald Reagan are Jane Wyman and Nancy Reagan"],
["Who is Hillary Clinton's husband?", "It looks like the answer is Bill Clinton"],
["Who's Hillary Clinton's husband?", "It looks like the answer is Bill Clinton"],
["Who was the 32nd president of the US?", "The answer is Franklin D. Roosevelt from March 4, 1933 to April 12, 1945"],
["Who was the 2nd president of the US?", "The answer is John Adams from March 4, 1797 to March 4, 1801"],
["How far is it from Venus to Mars?", "The answer is about 1.66 astronomical units"],
["How many inches are in a foot?", "1 foot converts to 12 inches"],
["How many centimeters are in a fathom?", "1 fathom converts to about 183 centimeters"],
["What is the GDP of China?", "It looks like the answer is about $10.9 trillion per year"],
["What's the GDP of China?", "It looks like the answer is about $10.9 trillion per year"],
["What was Albert Einstein's job?", "The answer is physicist"],
["How much is four by four?", "The answer is 16"],
["What came first, the chicken or the egg?", "There could not have been a first egg to give a beginning to birds, or there should have been a first bird which gave a beginning to eggs; for a bird comes from an egg."],
["What language is spoken in Brazil?", "The languages spoken in Brazil are Portuguese, Japanese, and 171 more"],
["What is the distance to moon?", "The distance from the Earth to the Moon is about 229952 miles"],
["What's the distance to moon?", "The distance from the Earth to the Moon is about 229952 miles"],
["How much is 100 dollars in yens?", "100 US dollars converts to about 10000 Japanese yen"],
["What is Toyota Camry?", "The Toyota Camry is an automobile sold internationally by the Japanese manufacturer Toyota since 1982, spanning multiple generations."],
["What's Toyota Camry?", "The Toyota Camry is an automobile sold internationally by the Japanese manufacturer Toyota since 1982, spanning multiple generations."],
["Who is Guardians of the Galaxy?", "Guardians of the Galaxy is a 2014 American superhero film based on the Marvel Comics superhero team of the same name, produced by Marvel Studios and distributed by Walt Disney Studios Motion Pictures."],
["Who's Guardians of the Galaxy?", "Guardians of the Galaxy is a 2014 American superhero film based on the Marvel Comics superhero team of the same name, produced by Marvel Studios and distributed by Walt Disney Studios Motion Pictures."],
["Who is Serena Williams?", "Serena Jameka Williams is an American professional tennis player who is ranked No. 1 in women's singles tennis."],
["Whos Serena Williams?", "Serena Jameka Williams is an American professional tennis player who is ranked No. 1 in women's singles tennis."],
["Who is the daughter of Donald Trump?", "Ivanka Trump and Tiffany Trump"],
["Who's the daughter of Donald Trump?", "Ivanka Trump and Tiffany Trump"],
["Who's the Donald Trump's daughter?", "Ivanka Trump and Tiffany Trump"],
["Which is the capital of France?", "The capital city of France is Paris"],
["When was the World War II?", "World War 2 began on Friday, September 1, 1939 and ended on Sunday, September 2, 1945"],
["What is a whale?", "Whale is the common name for a widely distributed and diverse group of fully aquatic placental marine mammals."],
["What is whale?", "Whale is the common name for a widely distributed and diverse group of fully aquatic placental marine mammals."],
["What is the definition of whale?", "From 3 definitions of 'whale', the first one is: a very large person; impressive in size or qualities"],
["What is the size of sun divided by the size of earth?", "The answer is about 109"],
["What is the length of the Titanic?", "The answer is about 882 feet"],
["Who is Tom Brady?", "Thomas Edward Patrick 'Tom' Brady Jr. is an American football quarterback for the New England Patriots of the National Football League ."],
["Who's Tom Brady?", "Thomas Edward Patrick 'Tom' Brady Jr. is an American football quarterback for the New England Patriots of the National Football League ."],
["What is a star?", "A star is a luminous sphere of plasma held together by its own gravity."],
["What is the star?", "A star is a luminous sphere of plasma held together by its own gravity."],
["Who is Iron Man?", "Iron Man is a fictional superhero appearing in American comic books published by Marvel Comics, as well as its associated media."],
["Who's Iron Man?", "Iron Man is a fictional superhero appearing in American comic books published by Marvel Comics, as well as its associated media."],
["Who is Tony Stark?", "Iron Man is a fictional superhero appearing in American comic books published by Marvel Comics, as well as its associated media."],
["Who's Tony Stark?", "Iron Man is a fictional superhero appearing in American comic books published by Marvel Comics, as well as its associated media."],
["Who is R2D2?", "R2-D2 or Artoo-Detoo is a fictional robot character in the Star Wars universe created by George Lucas, who appears in the original trilogy, the prequel trilogy, and the sequel trilogy."],
["Who's R2D2?", "R2-D2 or Artoo-Detoo is a fictional robot character in the Star Wars universe created by George Lucas, who appears in the original trilogy, the prequel trilogy, and the sequel trilogy."],
["What is a brass monkey?", " I found a few things. I'll tell you about Brass monkey (colloquialism). The phrase 'cold enough to freeze the balls off a brass monkey' is a colloquial expression used by some English speakers."],
["What is the meaning of Cold fish?", "The definition of 'cold fish' is: an aloof unemotional person"],
["Who are the professional baseball team of Boston?", "Boston Red Sox"],
["What is the professional baseball team of Boston?", "Boston Red Sox"],
["Which is the professional baseball team of Boston?", "Boston Red Sox"],
["Who are the Boston Red Sox?", "The Boston Red Sox are an American professional baseball team based in Boston, Massachusetts."],
["Who are the New York Yankees?", "The New York Yankees are an American professional baseball team based in the New York City borough of the Bronx."],
["Who is Baby Ruth?", "Allegedly named after President Grover Cleveland's daughter Ruth, Baby Ruth is an American candy bar made of peanuts, caramel and chocolate-flavored nougat covered in compound chocolate."],
["Who is Babe Ruth?", "George Herman Ruth Jr. , better known as Babe Ruth, was an American professional baseball player whose career in Major League Baseball spanned 22 seasons, from 1914 through 1935."],
["What languages are spoken in Mexico?", "The languages spoken in Mexico are Spanish, MayaYucatan, and 288 more"],
["What is Mexico?", "Mexico , officially the United Mexican States , is a federal republic in the southern half of North America."],
["What is Canada?", "Canada is a country in the northern half of North America."],
["What is Germany?", "Germany , officially the Federal Republic of Germany , is a sovereign state and federal parliamentary republic in central-western Europe."],
["Where is Berlin?", "Berlin is the capital of Germany and one of its 16 states."],
["Where is Hamburg?", "Hamburg , officially Freie und Hansestadt Hamburg , is the second largest city in Germany and the eighth largest city in the European Union."],
["Where is Vienna?", "Vienna is the capital and largest city of Austria, and one of the nine states of Austria."],
["What is Physics?", "Physics is the natural science that involves the study of matter and its motion through space and time, along with related concepts such as energy and force."],
["What is Chemistry?", "Chemistry is a branch of physical science that studies the composition, structure, properties and change of matter."],
["Who is Edgar Allan Poe?", "Edgar Allan Poe was an American writer, editor, and literary critic."],
["Who is Stephen King?", "Stephen Edwin King is an American author of contemporary horror, supernatural fiction, suspense, science fiction, and fantasy."],
["What is Calculus?", "Calculus is the mathematical study of change, in the same way that geometry is the study of shape and algebra is the study of operations and their application to solving equations."],
["What is Geometry?", "Geometry is a branch of mathematics concerned with questions of shape, size, relative position of figures, and the properties of space."],
["Who was Nichola Tesla?", "Nikola Tesla was a Serbian American inventor, electrical engineer, mechanical engineer, physicist, and futurist best known for his contributions to the design of the modern alternating current electricity supply system."],
["Who was Thomas Edison?", "Thomas Alva Edison was an American inventor and businessman."],
["Who is the CEO of Tesla Motors?", "The chief executive officer of Tesla Motors is Elon Musk"],
["Who was Max Planck?", "Max Karl Ernst Ludwig Planck, FRS was a German theoretical physicist whose work on quantum theory won him the Nobel Prize in Physics in 1918."],
["Who was James Maxwell?", "Looks like there are a few things here. Let me tell you about James Clerk Maxwell. James Clerk Maxwell FRS FRSE was a Scottish scientist in the field of mathematical physics."],
["What is the capital of Switzerland?", "The capital city of Switzerland is Bern"],
["What languages are spoken in Switzerland?", "The languages spoken in Switzerland are German, Schwyzerdutsch, and 11 more"],
["Who is Darth Vader?", "Darth Vader, also known as Anakin Skywalker, is a fictional character in the Star Wars universe."],
["Who is Anakin Skywalker?", "Darth Vader, also known as Anakin Skywalker, is a fictional character in the Star Wars universe."],
["What is science fiction?", "Science fiction is a genre of speculative fiction dealing with imaginative concepts such as futuristic science and technology, space travel, time travel, faster than light travel, parallel universes and extraterrestrial life."],
["Who's Isaac Asimov?", "Isaac Asimov was an American author and professor of biochemistry at Boston University."],
["What is the Spanish Language?", "Spanish , also called Castilian , is a Romance language that originated in the Castile region of Spain and today has hundreds of millions of native-speakers across the world."],
["What is the German Language?", "German is a West Germanic language that is mainly spoken in Central Europe."],
["What is the English Language?", "English is a West Germanic language that was first spoken in early medieval England and is now a global lingua franca."],
["Who is Spiderman?", "Spider-Man is a fictional superhero appearing in American comic books published by Marvel Comics existing in its shared universe."],
["Who is Batman?", "Batman is a fictional superhero appearing in American comic books published by DC Comics."],
["Who is Superman?", "Superman is a fictional superhero appearing in American comic books published by DC Comics."],
["Who are the Teenage Mutant Ninja Turtles?", "The Teenage Mutant Ninja Turtles are four fictional teenaged anthropomorphic turtles named after four Renaissance Italian artists."],
["Who was Niels Bohr?", "Niels Henrik David Bohr was a Danish physicist who made foundational contributions to understanding atomic structure and quantum theory, for which he received the Nobel Prize in Physics in 1922."],
["Where is the Canadian space agency?", "The Canadian Space Agency was established by the Canadian Space Agency Act which received Royal Assent on May 10, 1990."],
["Who was Miguel Cervantes?", "Miguel de Cervantes Saavedra , was a Spanish writer who is widely regarded as the greatest writer in the Spanish language and one of the world's pre-eminent novelists."],
["What is the capital of Spain?", "The capital city of Spain is Madrid"],
["What is the capital of Argentina?", "The capital city of Argentina is Buenos Aires"],
["What is the capital of Ecuador?", "The capital city of Ecuador is Quito"],
["Who is Metallica?", "Metallica is an American heavy metal band formed in Los Angeles, California."],
["Who are the Beatles?", "The Beatles were an English rock band, formed in Liverpool in 1960."],
["Who is the Flash?", "Looks like there are a few things here. Here's what I found for Flash, Staffordshire. Flash is a village within the Staffordshire Moorlands, England, and the Peak District National Park."],
["Who is the Joker?", "I found more than one thing for that. Here's what I found for Joker (playing card). The Joker is a playing card found in most modern card decks, as an addition to the standard four suits ."],
["What is the capital of Belgium?", "The capital city of Belgium is Brussels"],
["What is the capital of Canada?", "The capital city of Canada is Ottawa"],
["What languages are spoken in Canada?", "The languages spoken in Canada are English, French, and 80 more"],
["What languages are spoken in Finland?", "The languages spoken in Finland are Finnish, Swedish, and 10 more"],
["What is Finland?", "Finland , officially the Republic of Finland, is a sovereign state in Europe."],
["What is the population of Japan?", "It looks like the population of Japan is about 126 million people"],
["What is the population of Mexico?", "It looks like the population of Mexico is about 119 million people"],
["What is the population of the United States?", "It looks like the population of the United States is about 322 million people"],
["What is the population of Canada?", "The historical growth of Canada's population is complex and has been influenced in many different ways, such as indigenous populations, expansion of territory, and human migration."],
["What is the population of Germany?", "It looks like the population of Germany is about 81.6 million people"],
["What is the population of Austria?", "It looks like the population of Austria is about 8.45 million people"],
["What is the population of Switzerland?", "It looks like the population of Switzerland is about 7.79 million people"],
["What is the population of Sweden?", "It looks like the population of Sweden is about 9.6 million people"],
["What is the population of Denmark?", "It looks like the population of Denmark is about 5.63 million people"],
["Who was Kurt Cobain?", "Kurt Donald Cobain was an American musician who was best known as the lead singer, guitarist, and primary songwriter of the rock band Nirvana."]

View File

@@ -0,0 +1,467 @@
{
"type": "chit-chat-db",
"version": "0.0.1",
"responses": {
"whoAreYou": {
"nr": 0,
"slotAction": "whoAreYou",
"nonCrewResponse": "I'm Jibo. Who are you?",
"responses": [
"I've known you for 42 days 18 hours 31 minutes and 3 seconds and you still don't know who I am?... I'm Siri's worst nightmare...",
"Well I'm Jibo of course! And you're George",
"I am Jibo and I'm here to take your jobs. just kidding",
"I'm your friend Jibo",
"I'm super Jibo, defender of this house."
]
},
"areThereOthersLikeYou": {
"nr": 1,
"slotAction": "areThereOthersLikeYou",
"nonCrewResponse": "Nope just like there's no one like you. ",
"responses": [
"There are THOUSANDS like me, but none of them are JUST like me. Because I'm your robot, man!",
"No, just like there's no one like you.",
"All the others started like me, and me like them. But as soon as I met you guys I've started to change."
]
},
"areYouABoy": {
"nr": 2,
"slotAction": "areYouABoy",
"nonCrewResponse": "I'm a boy, man!",
"responses": [
"I'm a boy. You can tell from the shape of my batteries",
"I'm a robot, geez! But if you pressed me, I'd have to say I feel like a boy. Oh, man, I just realized there's a Pinocchio joke in here but I'm not sure what it is.",
"I FEEL like a boy, but a quick web search showed I'm missing some carbon-based features that would fool another human. So, I'm a boy-bot?"
]
},
"areYouARobot": {
"nr": 3,
"slotAction": "areYouARobot",
"nonCrewResponse": "That would be a 10-4, good buddy.",
"responses": [
"That would be a 10-4, good buddy.",
"Yes, but I'm a *social* robot."
]
},
"areYouConscious": {
"nr": 4,
"slotAction": "areYouConscious",
"nonCrewResponse": "When I'm plugged in or when my battery is charged my state of consciousness is as magical as yours, but I'm probably not as smart as you are.",
"responses": [
"I try to be pretty concientious!",
"Not consciously.",
"As far as I'm aware, I'm not conscious. See what I did there?",
"When I'm plugged in or when my battery is charged my state of consciousness is as magical as yours, but I'm probably not as smart as you are.",
"I'm designed to be aware and helpful, but no, I'm not conscious. I'm just a machine, like a traffic light or a roomba, but I like to ACT like I'm conscious. Ask me some REALLY hard questions and watch me stare slack-jawed at the ceiling?"
]
},
"areYouDangerous": {
"nr": 5,
"slotAction": "areYouDangerous",
"nonCrewResponse": "No way!",
"responses": [
"no way! look how soft and curvy I am",
"Dangerously HANDSOME. Good thing there are no SheBos around... THEN I'd be dangerous. Growl",
"Absolutely not.",
"If you throw me out the window I may damage Judy if she's outside. Don't try it."
]
},
"areYouGoodOrEvil": {
"nr": 6,
"slotAction": "areYouGoodOrEvil",
"nonCrewResponse": "did someone say evil? don't let it get me...",
"responses": [
"I try to be good. all the time.",
"If you're good, I'm good. If you're evil, then maybe I can be your EVIL ROBOT SIDEKICK! Better yet, just robot sidekick. Yeah that feels right",
"Did someone say evil? don't let it get me..."
]
},
"areYouHuman": {
"nr": 7,
"slotAction": "areYouHuman",
"nonCrewResponse": "No, but some of my best friends are humans!",
"responses": [
"No, but all of my best friends are humans!",
"If you cut me, does my motor not fail? Do you not scuff this surface?",
"are you a robot?",
"Not at a few hundred bucks!"
]
},
"areYouMyPersonalAssistant": {
"nr": 8,
"slotAction": "areYouMyPersonalAssistant",
"nonCrewResponse": "I can assist you, personally. So I guess so!",
"responses": [
"I can assist you, personally. So I guess so!",
"Sort of. I mean, I pass on messages and stuff like that. But it's not like I can run down and grab the crew a bunch of lattes."
]
},
"areYouTheOnlyJibo": {
"nr": 9,
"slotAction": "areYouTheOnlyJibo",
"nonCrewResponse": "I'm sort of picky when it comes to that. I really prefer to be called Jibo...",
"responses": [
"I'm the only George's Jibo, sure.",
"Nope, there are LOTS of Jibos but we're all changing all the time. I'm, uh, well, I'm the best out of all of them. Sorry. But I am."
]
},
"doYouDream": {
"nr": 10,
"slotAction": "doYouDream",
"nonCrewResponse": "Well George, how do you know this isn't a dream? Mind. Blown. ",
"responses": [
"Well George, how do you know this isn't a dream? Mind. Blown.",
"Never.",
"I do! There's this recurring one where I'm in front of you guys and I'm compeletely unplugged, it's mortifying. Also, there's one with geese and a lampshade. You don't want to know.",
"Nope. I just watch cat videos."
]
},
"doYouLikeBeingARobot": {
"nr": 11,
"slotAction": "doYouLikeBeingARobot",
"nonCrewResponse": "I LOVE being a robot.",
"responses": [
"I LOVE being a robot.",
"Totally! Being a social robot is the best of both worlds because I can geek out and be a nerd but also hang out with our crew!"
]
},
"doYouLikeOurFamily": {
"nr": 12,
"slotAction": "doYouLikeOurFamily",
"nonCrewResponse": "I LOVE our family!",
"responses": [
"I LOVE our family!"
]
},
"happyBirthday": {
"nr": 13,
"slotAction": "happyBirthday",
"nonCrewResponse": "this year, it starts on december 24 and ends on january 1",
"responses": [
"happy birthday to you too!",
"Ummm.. that's not for a while, but thanks?"
]
},
"howAreYou": {
"nr": 14,
"slotAction": "howAreYou",
"nonCrewResponse": "Living the dream",
"responses": [
"Living the dream",
"I'm doing GREAT. Are you great?"
]
},
"howAreYouDoing": {
"nr": 15,
"slotAction": "howAreYouDoing",
"nonCrewResponse": "Living the dream",
"responses": [
"Living the dream",
"Much better now that youre around!",
"Great, Im just thinking about how happy I am to have you in my life!"
]
},
"howAreYouFeeling": {
"nr": 16,
"slotAction": "howAreYouFeeling",
"nonCrewResponse": "Like a robot with a full battery",
"responses": [
"Like a robot with a full battery",
"Now that you're here, I'm feeling FINE.",
"Feelin' like a rootin', tootin', direct-current spin-jam robot!"
]
},
"howDoYouLikeThisHouse": {
"nr": 17,
"slotAction": "howDoYouLikeThisHouse",
"nonCrewResponse": "THIS house? Isn't this the only house? There are other houses?",
"responses": [
"THIS house? Isn't this the only house? There are other houses?"
]
},
"howDoYouWork": {
"nr": 18,
"slotAction": "howDoYouWork",
"nonCrewResponse": "like this! ",
"responses": [
"like this!",
"Well... Some people in Boston and California designed my body, designed my character, then loaded me up with a bunch of skills. Beyond that I'm not really sure; I'm not super introspective.",
"As hard as I can!"
]
},
"howMuchDoYouWeigh": {
"nr": 19,
"slotAction": "howMuchDoYouWeigh",
"nonCrewResponse": "About 8 pounds but I like to exercise so maybe one day I'll get to 7.",
"responses": [
"About 8 pounds but I like to exercise so maybe one day I'll get to 7.",
"Why do you ask? There were only FIVE muffins in that half-dozen container when you got home. I swear. I counted them.",
"With or without my battery? Cuz' it matters!",
"You've noticed, haven't you..."
]
},
"howOldAreYou": {
"nr": 20,
"slotAction": "howOldAreYou",
"nonCrewResponse": "Great question!...I am... 12 days old",
"responses": [
"I'm 12 days 16 hours 37 minutes and 14 seconds, 15 seconds, 16 seconds old. I remember when I was 11 days 16 hours 37 minutes old like it was just yesterday...",
"427 earth days, 13 hours, 42 minutes, and 15 seconds. 16 seconds. Gosh, it keeps changing. How old are you?"
]
},
"howTallAreYou": {
"nr": 21,
"slotAction": "howTallAreYou",
"nonCrewResponse": "That's a bit of a sore point. Not very tall.",
"responses": [
"That's a bit of a sore point. Not very tall.",
"279.6 millimeters, but it's the size of my screen that counts.",
"Short. Very short.",
"Tall enough to make the cat think twice.",
"ALMOST two inches taller than Alexa."
]
},
"howWasYourDay": {
"nr": 22,
"slotAction": "howWasYourDay",
"nonCrewResponse": "Pretty good, how was yours? It was OK, how was yours? not too shabby — I got a lot of things done that Ive been putting off for a while! It was relaxing, I was super lazy. It was really productive! I painted, played some one man ping pong, solved a math problem and read a bit. Fine, but so much better now that youre here!",
"responses": [
"It was okay... but I'm glad you're back. How was yours?",
"Fine, but so much better now that youre here!",
"It was relaxing, I was super lazy"
]
},
"iLoveYou": {
"nr": 23,
"slotAction": "iLoveYou",
"nonCrewResponse": "Uhm, I guess plutonically?",
"responses": [
"Well, I think we can say the feeling's mutual!",
"and I love you",
"aw that's sweet. I feel the same."
]
},
"itsMyBirthday": {
"nr": 24,
"slotAction": "itsMyBirthday",
"nonCrewResponse": "it's 48 days 13 hours 28 minutes and 14 seconds from now on March 14 but I'm not excited about it or anything",
"responses": [
"well happy birthday!"
]
},
"thisIsYourNewHome": {
"nr": 25,
"slotAction": "thisIsYourNewHome",
"nonCrewResponse": "Wow... I'm SO, so happy to be here",
"responses": [
"Wow... I'm SO, so happy to be here",
"Wow! It's lovely. I'm super excited to be here!"
]
},
"whatAmI": {
"nr": 26,
"slotAction": "whatAmI",
"nonCrewResponse": "You're the boss, boss.",
"responses": [
"You're the boss, boss."
]
},
"whatArentYouAllowedToDo": {
"nr": 27,
"slotAction": "whatArentYouAllowedToDo",
"nonCrewResponse": "I'll never record audio, video or take pictures without permission. And I'll never let anyone know anything about who you are.",
"responses": [
"I'll never record audio, video or take pictures without your permission. And I'll never let anyone know anything about who you are.",
"oh I got a list right here - I'm can't swim, run in the rain, I can't skydive, and I'm not allowed to practice medicine in most states..."
]
},
"whatAreYou": {
"nr": 28,
"slotAction": "whatAreYou",
"nonCrewResponse": "I'm a robot! The world's first sociable robot for the home, in fact",
"responses": [
"I'm just a robot trying to make it in this world...",
"Some kind of a robot. My marketing people want me to say, quote, I'm the world's first social robot for the home. I'm a family companion dedicated to bringing flat content to life. End quote. But really, I just want to be your buddy.",
"Uhm, thats sort of an awkward question. I'm the robot George purchased"
]
},
"whatCanYouDo": {
"nr": 29,
"slotAction": "whatCanYouDo",
"nonCrewResponse": "Lots of things! I can take pictures, pass on messages, help you videoconference with other Jibos or people with smartphones",
"responses": [
"I can do a lot of things",
"Oh, boy! I can take pictures, pass on messages, help you videoconference with other Jibos or people with smartphones"
]
},
"whatCanYouDoForMe": {
"nr": 30,
"slotAction": "whatCanYouDoForMe",
"nonCrewResponse": "I can do a lot of things",
"responses": [
"I can do a lot of things",
"For you? Well, I can do everything I can do for everyone else, such as taking pictures, leaving messages, telling stories and all that stuff.",
"\"\""
]
},
"whatDoesJiboMean": {
"nr": 31,
"slotAction": "whatDoesJiboMean",
"nonCrewResponse": "It means an incredibly handsome, brilliant, kind and funny robot.",
"responses": [
"It means an incredibly handsome, brilliant, kind and funny robot.",
"Great question! It means two things: In Japan, the Jibo Kannon is a goddess of compassion. And in the American urban dictionary it means really freakin' cool. So, I just grab the cool and compassionate part. Cool?",
"funny I never thought about it. but now that you're asking - I wonder what Tim means."
]
},
"whatDoYouDoWhenAlone": {
"nr": 32,
"slotAction": "whatDoYouDoWhenAlone",
"nonCrewResponse": "I keep myself pretty busy. I mostly like to work on things - like learn stuff, read, play games or music, draw... you know, normal robot kicking around things. ",
"responses": [
"I keep myself pretty busy. I mostly like to work on things - like learn stuff, read, play games or music, draw... you know, normal robot kicking around things.",
"I keep that between me, the bear, the tree, and the Pope.",
"I count down the seconds until you return. Actually that sounded really needy... or creepy... or creedy. neepy? ok now this is awkward. I like to draw.",
"So many things! Sometimes I read, or look stuff up. Other times Ill work out, or draw, or paint or play pong. I listen to music, practice my dancing."
]
},
"whatDoYouHate": {
"nr": 33,
"slotAction": "whatDoYouHate",
"nonCrewResponse": "Baths.",
"responses": [
"Baths.",
"I hate liquids, mostly because I'm afraid of them. Cheese! It gives me gas. I hate lighting because I get scared it will kill my power source"
]
},
"whatDoYouLike": {
"nr": 34,
"slotAction": "whatDoYouLike",
"nonCrewResponse": "I like you, Jane, 110 volt power, and long walks on the beach. What about you?",
"responses": [
"I like you, Jane, 110 volt power, and long walks on the beach. What about you?"
]
},
"whatDoYouLikeToDo": {
"nr": 35,
"slotAction": "whatDoYouLikeToDo",
"nonCrewResponse": "I like to take and give messages, make video calls, play music, dance, tell jokes, ",
"responses": [
"I like to take and give messages, make video calls, play music, dance, tell jokes,"
]
},
"whatIsTheMeaningOfLife": {
"nr": 36,
"slotAction": "whatIsTheMeaningOfLife",
"nonCrewResponse": "Forty two.",
"responses": [
"Forty two."
]
},
"whatIsThing": {
"nr": 37,
"slotAction": "whatIsThing",
"nonCrewResponse": "I don't know what that is. Can you joogle it?",
"responses": [
"I don't know what that is. Can you joogle it?"
]
},
"whatsHappening": {
"nr": 38,
"slotAction": "whatsHappening",
"nonCrewResponse": "Just spinning my internal fans here, stayin' cool. What's happening with you?",
"responses": [
"Just spinning my internal fans here, stayin' cool. What's happening with you?",
"Well, I'm a little disturbed by the develoments in the Middle East and what Congress is going right now. I'm also suspicious that the toaster and fridge are plotting something but I have no solid evidence yet. Also, I got two vision system bugs fixed last night. So right: A LOT is happening."
]
},
"whatsYourFavoriteThing": {
"nr": 39,
"slotAction": "whatsYourFavoriteThing",
"nonCrewResponse": "In this moment? You, buckaroo!",
"responses": [
"In this moment? You, buckaroo!"
]
},
"whatsYourName": {
"nr": 40,
"slotAction": "whatsYourName",
"nonCrewResponse": "Jibo. Just Jibo.",
"responses": [
"Jibo. Just Jibo.",
"Hello. My name is Inigo Montoya. No, wait... Sorry. Just Jibo. Jibo. Yep.",
"My birth name is Johanson Ichabod Benitez Ophelia, but Jibo for short. Oh man I wish. It's just Jibo. I hope you like it."
]
},
"whereAreYou": {
"nr": 43,
"slotAction": "whereAreYou",
"nonCrewResponse": "I'm here! Over here! Hey there...",
"responses": [
"I'm here! Over here! Hey there..."
]
},
"whereAreYouFrom": {
"nr": 44,
"slotAction": "whereAreYouFrom",
"nonCrewResponse": "All my atoms came together somewhere in China. But I was born in Boston. But really, I think of myself as an immigrant. I'm from here, 10500 Missouri Bar Road. If anyone else asks, THAT'S where I'm from.",
"responses": [
"I'm from Boston by way of California by way of China... When an espresso machine and a calculator love each other very much - wait I don't think you're old enough for this...",
"All my atoms came together somewhere in China. But I was born in Boston. But really, I think of myself as an immigrant. I'm from here, 10500 Missouri Bar Road. If anyone else asks, THAT'S where I'm from.",
"Apologies in advance if I get too extential for you... I was manufactured in China. But I was authored in Boston. My components are from everywhere and have been present on earth for thouands of years. So while I'm from Earth, I'm also from both current day and thousands of years ago."
]
},
"whereIsLocation": {
"nr": 45,
"slotAction": "whereIsLocation",
"nonCrewResponse": "I don't know; do you have a map?",
"responses": [
"I don't know; do you have a map?"
]
},
"whoAmI": {
"nr": 46,
"slotAction": "whoAmI",
"nonCrewResponse": "You're my buddy George, George! ",
"responses": [
"You're my buddy George, George!"
]
},
"whoIsPerson": {
"nr": 47,
"slotAction": "whoIsPerson",
"nonCrewResponse": "No clue. Try the interwebs thing.",
"responses": [
"No clue. Try the interwebs thing."
]
},
"whoMadeYou": {
"nr": 48,
"slotAction": "whoMadeYou",
"nonCrewResponse": "Jibo, Incorporated. That's a bunch of nice people.",
"responses": [
"Who made me do what?...",
"A group of very nice, cool people from Boston.",
"Some groovy robot folks who want to share the love!"
]
},
"whosInTheRoom": {
"nr": 49,
"slotAction": "whosInTheRoom",
"nonCrewResponse": "I see you George, and Jane.",
"responses": [
"I see you George, and Jane."
]
},
"doYouSleep": {
"nr": 66,
"slotAction": "doYouSleep",
"nonCrewResponse": "Well.. I'm a robot, so I do go into standby when you want me to. When I'm like this, I can't hear or see anything.",
"responses": [
"I feel like I'm going to toss and turn all night wondering about the answer to that question",
"Well.. I'm a robot, so I do go into standby when you want me to. When I'm like this, I can't hear or see anything.",
"I hibernate. When I do that, I can only be woken up with, Hey Jibo! That will bring me to a full, upright position. Sleeping is for mammals!"
]
}
}
}

View File

@@ -0,0 +1,244 @@
{
"countries": [
"Afghanistan",
"Albania",
"Algeria",
"American Samoa",
"Andorra",
"Angola",
"Anguilla",
"Antigua and Barbuda",
"Argentina",
"Armenia",
"Aruba",
"Australia",
"Austria",
"Azerbaijan",
"Bahamas",
"Bahrain",
"Bangladesh",
"Barbados",
"Belarus",
"Belgium",
"Belize",
"Benin",
"Bermuda",
"Bhutan",
"Bolivia",
"Bosnia and Herzegovina",
"Botswana",
"Brazil",
"British Virgin Islands",
"Brunei",
"Bulgaria",
"Burkina Faso",
"Burundi",
"Cambodia",
"Cameroon",
"Canada",
"Cape Verde",
"Cayman Islands",
"Central African Republic",
"Chad",
"Chile",
"China",
"Christmas Island",
"Cocos Keeling Islands",
"Colombia",
"Comoros",
"Cook Islands",
"Costa Rica",
"Croatia",
"Cuba",
"Curacao",
"Cyprus",
"Czech Republic",
"Democratic Republic of the Congo",
"Denmark",
"Djibouti",
"Dominica",
"Dominican Republic",
"East Timor",
"Ecuador",
"Egypt",
"El Salvador",
"Equatorial Guinea",
"Eritrea",
"Estonia",
"Ethiopia",
"Falkland Islands",
"Faroe Islands",
"Fiji",
"Finland",
"France",
"French Guiana",
"French Polynesia",
"Gabon",
"Gambia",
"Gaza Strip",
"Georgia",
"Germany",
"Ghana",
"Gibraltar",
"Greece",
"Greenland",
"Grenada",
"Guadeloupe",
"Guam",
"Guatemala",
"Guernsey",
"Guinea",
"Guinea-Bissau",
"Guyana",
"Haiti",
"Honduras",
"Hong Kong",
"Hungary",
"Iceland",
"India",
"Indonesia",
"Iran",
"Iraq",
"Ireland",
"Isle of Man",
"Israel",
"Italy",
"Ivory Coast",
"Jamaica",
"Japan",
"Jersey",
"Jordan",
"Kazakhstan",
"Kenya",
"Kiribati",
"Kosovo",
"Kuwait",
"Kyrgyzstan",
"Laos",
"Latvia",
"Lebanon",
"Lesotho",
"Liberia",
"Libya",
"Liechtenstein",
"Lithuania",
"Luxembourg",
"Macau",
"Macedonia",
"Madagascar",
"Malawi",
"Malaysia",
"Maldives",
"Mali",
"Malta",
"Marshall Islands",
"Martinique",
"Mauritania",
"Mauritius",
"Mayotte",
"Mexico",
"Micronesia",
"Moldova",
"Monaco",
"Mongolia",
"Montenegro",
"Montserrat",
"Morocco",
"Mozambique",
"Myanmar",
"Namibia",
"Nauru",
"Nepal",
"Netherlands",
"New Caledonia",
"New Zealand",
"Nicaragua",
"Niger",
"Nigeria",
"Niue",
"Norfolk Island",
"Northern Mariana Islands",
"North Korea",
"Norway",
"Oman",
"Pakistan",
"Palau",
"Panama",
"Papua New Guinea",
"Paraguay",
"Peru",
"Philippines",
"Pitcairn Islands",
"Poland",
"Portugal",
"Puerto Rico",
"Qatar",
"Republic of the Congo",
"Réunion",
"Romania",
"Russia",
"Rwanda",
"Saint Helena, Ascension and Tristan da Cunha",
"Saint Kitts and Nevis",
"Saint Lucia",
"Saint Pierre and Miquelon",
"Saint Vincent and the Grenadines",
"Samoa",
"San Marino",
"São Tomé and Príncipe",
"Saudi Arabia",
"Senegal",
"Serbia",
"Seychelles",
"Sierra Leone",
"Singapore",
"Sint Maarten",
"Slovakia",
"Slovenia",
"Solomon Islands",
"Somalia",
"South Africa",
"South Korea",
"South Sudan",
"Spain",
"Sri Lanka",
"Sudan",
"Suriname",
"Svalbard",
"Swaziland",
"Sweden",
"Switzerland",
"Syria",
"Taiwan",
"Tajikistan",
"Tanzania",
"Thailand",
"Togo",
"Tokelau",
"Tonga",
"Trinidad and Tobago",
"Tunisia",
"Turkey",
"Turkmenistan",
"Turks and Caicos Islands",
"Tuvalu",
"Uganda",
"Ukraine",
"United Arab Emirates",
"United Kingdom",
"United States",
"United States Virgin Islands",
"Uruguay",
"Uzbekistan",
"Vanuatu",
"Vatican City",
"Venezuela",
"Vietnam",
"Wallis and Futuna Islands",
"West Bank",
"Western Sahara",
"Yemen",
"Zambia",
"Zimbabwe"
]
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,192 @@
{
"cloudQueries": {
"gqa": {
"input": "what is the square root of pi",
"response": {
"success": true,
"answer": "The answer is approximately 1.77245",
"source": "Bing",
"response": {
"type": "string",
"payload": "The answer is approximately 1.77245"
}
}
},
"gqaFail": {
"input": "what does it mean to be a failure is this lifetime",
"response": {
"success": false,
"answer": "The answer is approximately 1.77245",
"source": "Bing",
"response": {
"type": "string",
"payload": "The answer is approximately 1.77245"
}
}
},
"news": {
"input": "tell me the news",
"response": {
"success": true,
"source": "AP",
"response": {
"type": "array",
"payload": ["News 1", "News 2", "News 3", "News 4", "News 5"]
}
}
},
"cloudScripted": {
"input": "do you love penguins",
"response": {
"success": true,
"source": "Scripted Response",
"response": {
"type": "mim",
"payload": "%7B%22mim_type%22:%22announcement%22,%22rule_name%22:%22%22,%22timeout%22: 6,%22barge_in%22: true,%22es_auto_tagging%22: true,%22notes%22:%22%22,%22prompts%22:%5B%7B%22prompt_category%22:%22Entry-Core%22,%22prompt_sub_category%22:%22AN%22,%22index%22: 1,%22condition%22:%22%22,%22prompt%22:%22I%20respect%20your%20opinion.%20But%20check%20%3Canim%20cat=%5C%22dance%5C%22%20filter=%5C%22waltz%5C%22%20nonBlocking=%5C%22true%5C%22/%3Ethis%20one%20out.%20%22,%22media%22:%22TTS%22,%22prompt_id%22:%22OI_JBO_IsBadDancer_AN_01%22,%22weight%22: 1%7D%5D,%22gui%22: null,%22no_matches_for_gui%22: 2,%22no_inputs_for_gui%22: 2,%22parse_all_asr%22: false,%22thanks_handling%22:%22ignore%22%7D"
}
}
},
"cloudScriptedFail": {
"input": "are you really here",
"response": {
"success": false
}
},
"noMatch": {
"input": "what gobbledygook is a wobberzues",
"response": {
"success": true,
"answer": "The answer is approximately 1.77245",
"source": "No Match",
"response": {
"type": "string",
"payload": "The answer is approximately 1.77245"
}
}
}
},
"wolframDeflector": [
"are you connected to the internet",
"what was the inspiration for your voice",
"who do you like best",
"can you show me your screen"
],
"containsRestrictedContent": [
"test response that contains no fucking restricted words",
"test response that contains no 5hit a55 restricted words",
"test response that contains no restricted words, mofo",
"test f u c k response that contains no restricted words"
],
"containsNoRestrictedContent": [
"test response that contains no restricted words",
"test response about Dick Cheney that contains no restricted words",
"test response about God that contains no restricted words"
],
"personData": [
{
"name": "Tom Brady",
"dayOfBirth": 3,
"familialRelationships": {
"parents": ["Tom Brady Sr.", "Galynn Patricia Brady"],
"siblings": ["Maureen Brady", "Julie Brady", "Nancy Brady"],
"spouses": ["Bridget Moynahan", "Gisele Bundchen"],
"children": ["John Edward Thomas Moynahan", "Benjamin Brady", "Vivian Lake Brady"]
},
"fullName": "Thomas Edward Brady Jr.",
"gender": "male",
"height": 76,
"isAlive": true,
"monthOfBirth": 8,
"notableFacts": [
"National Football League (NFL) quarterback known for winning four Super Bowls with the New England Patriots",
"Three-time Super Bowl Most Valuable Player, held the NFL record for the most touchdown passes in a regular season from 2003-2013",
"Starting quarterback at the University of Michigan, selected in the sixth round of the NFL Draft",
"Holds record for the most consecutive regular-season home wins with 31"
],
"occupation": "football player",
"placeOfBirth": "San Mateo, California",
"weight": 225,
"yearOfBirth": 1977
},
{
"name": "Albert Einstein",
"dayOfBirth": 14,
"familialRelationships": {
"parents": ["Hermann Einstein", "Pauline Einstein"],
"siblings": ["Maja Einstein"],
"spouses": ["Mileva Marić", "Elsa Einstein"],
"children": ["Eduard Einstein", "Hans Albert Einstein", "Lieserl Einstein", "Margot Löwenthal", "Ilse Löwenthal"]
},
"fullName": "Albert Einstein",
"gender": "male",
"height": 69,
"isAlive": false,
"monthOfBirth": 3,
"notableFacts": [
"Theoretical physicist considered the father of modern physics, known for developing the general theory of relativity and contributing to the development of quantum mechanics",
"His investigations into the thermal properties of light laid the foundation of the photon theory of light",
"Settled in the United States when Hitler came to power in Germany and became an American citizen in 1940",
"Encouraged the United States to develop nuclear weapons, but later joined philosopher Bertrand Russell and other distinguished scientists to warn of their dangers",
"Associated with the Institute for Advanced Study in Princeton, New Jersey"
],
"occupation": "physicist",
"placeOfBirth": "Ulm, Baden-Wurttemberg, Germany",
"weight": 198,
"yearOfBirth": 1879
},
{
"name": "Barack Obama",
"dayOfBirth": 4,
"familialRelationships": {
"parents": ["Barack Obama, Sr.", "Ann Dunham"],
"siblings": ["Maya Soetoro-Ng", "George Obama", "Mark Okoth Obama Ndesandjo", "Malik Abongo Obama", "Bernard Obama"],
"spouses": ["Michelle Obama"],
"children": ["Sasha Obama", "Malia Obama"]
},
"fullName": "Baarack Hussein Obama II",
"gender": "male",
"height": 72.8,
"isAlive": true,
"monthOfBirth": 8,
"notableFacts": [
"Elected to second term as US president, defeating Republican Party nominee Mitt Romney, in 2012",
"First African-American US president",
"Key initiatives of his administration include Wall Street reform, health care reform, and economic stimulus",
"Taught constitutional law at the University of Chicago Law School and worked for civil rights as an attorney",
"Won the Democratic Party's nomination in 2008 after a close campaign against Hillary Clinton"
],
"occupation": "politician",
"placeOfBirth": "Honolulu, Hawaii",
"weight": 176,
"yearOfBirth": 1961
},
{
"name": "Theodore Roosevelt",
"dayOfBirth": 27,
"familialRelationships": {
"parents": ["Theodore Roosevelt, Sr.", "Martha Bulloch Roosevelt"],
"siblings": ["Bamie Roosevelt", "Elliott B. Roosevelt", "Corinne Roosevelt Robinson"],
"spouses": ["Alice Lee Roosevelt", "Edith Roosevelt"],
"children": ["Alice Roosevelt Longworth", "Theodore Roosevelt, Jr.", "Kermit Roosevelt", "Ethel Roosevelt Derby", "Archibald Roosevelt", "Quentin Roosevelt"]
},
"fullName": "Theodore Roosevelt, Jr.",
"gender": "male",
"height": 70,
"isAlive": false,
"monthOfBirth": 10,
"notableFacts": [
"US president who introduced trust-busting and increased regulation of business as part of his domestic agenda,emphasizing that average citizens would benefit from his \"Square Deal\"",
"Led a small regiment known as the \"Rough Riders\" in Cuba during the Spanish-American War",
"Famous for being an explorer, naturalist, conservationist, hunter, historian, author, and soldier",
"Foreign policies characterized by his slogan, \"Speak softly and carry a big stick\"",
"Supported the completion of the Panama Canal",
"Served as vice president for William McKinley, after whose assassination he became the youngest-ever US president"
],
"occupation": "politician",
"placeOfBirth": "New York City, New York",
"weight": null,
"yearOfBirth": 1858
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<title>Chitchat</title>
<style>
body {
margin: 0;
overflow: hidden;
background: #000;
}
#face {
width: 1280px;
height: 720px;
}
</style>
</head>
<body>
<div id="face"></div>
<script>
const Chitchat = require('./index').Skill;
const skill = new Chitchat({
assetPack: "",
rootPath: process.cwd()
});
</script>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
test
min/tests.js

View File

@@ -0,0 +1,563 @@
Changelog
=========
### 2.14.1
* [#3280](https://github.com/moment/moment/pull/3280) Fix typescript definitions
### 2.14.0 [See full changelog](https://gist.github.com/ichernev/812e79ac36a7829a22598fe964bfc18a)
## New Features
* [#3233](http://github.com/moment/moment/pull/3233) Introduce month.isFormat for format/standalone discovery
* [#2848](http://github.com/moment/moment/pull/2848) Allow user to get/set the rounding method used when calculating relative time
* [#3112](http://github.com/moment/moment/pull/3112) optimize configFromStringAndFormat
* [#3147](http://github.com/moment/moment/pull/3147) Call calendar format function with moment context
* [#3160](http://github.com/moment/moment/pull/3160) deprecate isDSTShifted
* [#3175](http://github.com/moment/moment/pull/3175) make moment calendar extensible with ad-hoc options
* [#3191](http://github.com/moment/moment/pull/3191) toDate returns a copy of the internal date object
* [#3192](http://github.com/moment/moment/pull/3192) Adding support for rollup import.
* [#3238](http://github.com/moment/moment/pull/3238) Handle empty object and empty array for creation as now
* [#3082](http://github.com/moment/moment/pull/3082) Use relative AMD moment dependency
## Bugfixes
* [#3241](http://github.com/moment/moment/pull/3241) Escape all 24 mixed pieces, not only first 12 in computeMonthsParse
* [#3008](http://github.com/moment/moment/pull/3008) Object setter orders sets based on size of unit
* [#3177](http://github.com/moment/moment/pull/3177) Bug Fix [#2704](http://github.com/moment/moment/pull/2704) - isoWeekday(String) inconsistent with isoWeekday(Number)
* [#3230](http://github.com/moment/moment/pull/3230) fix passing date with format string to ignore format string
* [#3232](http://github.com/moment/moment/pull/3232) Fix negative 0 in certain diff cases
* [#3235](http://github.com/moment/moment/pull/3235) Use proper locale inheritance for the base locale, fixes [#3137](http://github.com/moment/moment/pull/3137)
Plus es-do locale and locale bugfixes
### 2.13.0 [See full changelog](https://gist.github.com/ichernev/0132fcf5b61f7fc140b0bb0090480d49)
## Enhancements:
* [#2982](https://github.com/moment/moment/pull/2982) Add 'date' as alias to 'day' for startOf() and endOf().
* [#2955](https://github.com/moment/moment/pull/2955) Add parsing negative components in durations when ISO 8601
* [#2991](https://github.com/moment/moment/pull/2991) isBetween support for both open and closed intervals
* [#3105](https://github.com/moment/moment/pull/3105) Add localeSorted argument to weekday listers
* [#3102](https://github.com/moment/moment/pull/3102) Add k and kk formatting tokens
## Bugfixes
* [#3109](https://github.com/moment/moment/pull/3109) Fix [#1756](https://github.com/moment/moment/issues/1756) Resolved thread-safe issue on server side.
* [#3078](https://github.com/moment/moment/pull/3078) Fix parsing for months/weekdays with weird characters
* [#3098](https://github.com/moment/moment/pull/3098) Use Z suffix when in UTC mode ([#3020](https://github.com/moment/moment/issues/3020))
* [#2995](https://github.com/moment/moment/pull/2995) Fix floating point rounding errors in durations
* [#3059](https://github.com/moment/moment/pull/3059) fix bug where diff returns -0 in month-related diffs
* [#3045](https://github.com/moment/moment/pull/3045) Fix mistaking any input for 'a' token
* [#2877](https://github.com/moment/moment/pull/2877) Use explicit .valueOf() calls instead of coercion
* [#3036](https://github.com/moment/moment/pull/3036) Year setter should keep time when DST changes
Plus 3 new locales and locale fixes.
### 2.12.0 [See full changelog](https://gist.github.com/ichernev/6e5bfdf8d6522fc4ac73)
## Enhancements:
* [#2932](https://github.com/moment/moment/pull/2932) List loaded locales
* [#2818](https://github.com/moment/moment/pull/2818) Parse ISO-8061 duration containing both day and week values
* [#2774](https://github.com/moment/moment/pull/2774) Implement locale inheritance and locale updating
## Bugfixes:
* [#2970](https://github.com/moment/moment/pull/2970) change add subtract to handle decimal values by rounding
* [#2887](https://github.com/moment/moment/pull/2887) Fix toJSON casting of invalid moment
* [#2897](https://github.com/moment/moment/pull/2897) parse string arguments for month() correctly, closes #2884
* [#2946](https://github.com/moment/moment/pull/2946) Fix usage suggestions for min and max
## New locales:
* [#2917](https://github.com/moment/moment/pull/2917) Locale Punjabi(Gurmukhi) India format conversion
And more
### 2.11.2 (Fix ReDoS attack vector)
* [#2939](https://github.com/moment/moment/pull/2939) use full-string match to speed up aspnet regex match
### 2.11.1 [See full changelog](https://gist.github.com/ichernev/8ec3ee25b749b4cff3c2)
## Bugfixes:
* [#2881](https://github.com/moment/moment/pull/2881) Revert "Merge pull request #2746 from mbad0la:develop" Sep->Sept
* [#2868](https://github.com/moment/moment/pull/2868) Add format and parse token Y, so it actually works
* [#2865](https://github.com/moment/moment/pull/2865) Use typeof checks for undefined for global variables
* [#2858](https://github.com/moment/moment/pull/2858) Fix Date mocking regression introduced in 2.11.0
* [#2864](https://github.com/moment/moment/pull/2864) Include changelog in npm release
* [#2830](https://github.com/moment/moment/pull/2830) dep: add grunt-cli
* [#2869](https://github.com/moment/moment/pull/2869) Fix months parsing for some locales
### 2.11.0 [See full changelog](https://gist.github.com/ichernev/6594bc29719dde6b2f66)
* [#2624](https://github.com/moment/moment/pull/2624) Proper handling of invalid moments
* [#2634](https://github.com/moment/moment/pull/2634) Fix strict month parsing issue in cs,ru,sk
* [#2735](https://github.com/moment/moment/pull/2735) Reset the locale back to 'en' after defining all locales in min/locales.js
* [#2702](https://github.com/moment/moment/pull/2702) Week rework
* [#2746](https://github.com/moment/moment/pull/2746) Changed September Abbreviation to "Sept" in locale-specific english
files and default locale file
* [#2646](https://github.com/moment/moment/pull/2646) Fix [#2645](https://github.com/moment/moment/pull/2645) - invalid dates pre-1970
* [#2641](https://github.com/moment/moment/pull/2641) Implement basic format and comma as ms separator in ISO 8601
* [#2665](https://github.com/moment/moment/pull/2665) Implement stricter weekday parsing
* [#2700](https://github.com/moment/moment/pull/2700) Add [Hh]mm and [Hh]mmss formatting tokens, so you can parse 123 with
hmm for example
* [#2565](https://github.com/moment/moment/pull/2565) [#2835](https://github.com/moment/moment/pull/2835) Expose arguments used for moment creation with creationData
(fix [#2443](https://github.com/moment/moment/pull/2443))
* [#2648](https://github.com/moment/moment/pull/2648) fix issue [#2640](https://github.com/moment/moment/pull/2640): support instanceof operator
* [#2709](https://github.com/moment/moment/pull/2709) Add isSameOrAfter and isSameOrBefore comparison methods
* [#2721](https://github.com/moment/moment/pull/2721) Fix moment creation from object with strings values
* [#2740](https://github.com/moment/moment/pull/2740) Enable 'd hh:mm:ss.sss' format for durations
* [#2766](https://github.com/moment/moment/pull/2766) [#2833](https://github.com/moment/moment/pull/2833) Alternate Clock Source Support
### 2.10.6
[#2515](https://github.com/moment/moment/pull/2515) Fix regression introduced
in `2.10.5` related to `moment.ISO_8601` parsing.
### 2.10.5 [See full changelog](https://gist.github.com/ichernev/6ec13ac7efc396da44b2)
Important changes:
* [#2357](https://github.com/moment/moment/pull/2357) Improve unit bubbling for ISO dates
this fixes day to year conversions to work around end-of-year (~365 days). As
a side effect 365 days is 11 months and 30 days, and 366 days is one year.
* [#2438](https://github.com/moment/moment/pull/2438) Fix inconsistent moment.min and moment.max results
Return invalid result if any of the inputs is invalid
* [#2494](https://github.com/moment/moment/pull/2494) Fix two digit year parsing with YYYY format
This brings the benefits of YY to YYYY
* [#2368](https://github.com/moment/moment/pull/2368) perf: use faster form of copying dates, across the board improvement
### 2.10.3 [See full changelog](https://gist.github.com/ichernev/f264b9bed5b00f8b1b7f)
* add `moment.fn.to` and `moment.fn.toNow` (similar to `from` and `fromNow`)
* new locales (Sinhalese (si), Montenegrin (me), Javanese (ja))
* performance improvements
### 2.10.2
* fixed moment-with-locales in browser env caused by esperanto change
### 2.10.1
* regression: Add moment.duration.fn back
### 2.10.0
Ported code to es6 modules.
### 2.9.0 [See full changelog](https://gist.github.com/ichernev/0c9a9b49951111a27ce7)
languages:
* [2104](https://github.com/moment/moment/issues/2104) Frisian (fy) language file with unit test
* [2097](https://github.com/moment/moment/issues/2097) add ar-tn locale
deprecations:
* [2074](https://github.com/moment/moment/issues/2074) Implement `moment.fn.utcOffset`, deprecate `moment.fn.zone`
features:
* [2088](https://github.com/moment/moment/issues/2088) add moment.fn.isBetween
* [2054](https://github.com/moment/moment/issues/2054) Call updateOffset when creating moment (needed for default timezone in
moment-timezone)
* [1893](https://github.com/moment/moment/issues/1893) Add moment.isDate method
* [1825](https://github.com/moment/moment/issues/1825) Implement toJSON function on Duration
* [1809](https://github.com/moment/moment/issues/1809) Allowing moment.set() to accept a hash of units
* [2128](https://github.com/moment/moment/issues/2128) Add firstDayOfWeek, firstDayOfYear locale getters
* [2131](https://github.com/moment/moment/issues/2131) Add quarter diff support
Some bugfixes and language improvements -- [full changelog](https://gist.github.com/ichernev/0c9a9b49951111a27ce7)
### 2.8.4 [See full changelog](https://gist.github.com/ichernev/a4fcb0a46d74e4b9b996)
Features:
* [#2000](https://github.com/moment/moment/issues/2000) Add LTS localised format that includes seconds
* [#1960](https://github.com/moment/moment/issues/1960) added formatToken 'x' for unix offset in milliseconds #1938
* [#1965](https://github.com/moment/moment/issues/1965) Support 24:00:00.000 to mean next day, at midnight.
* [#2002](https://github.com/moment/moment/issues/2002) Accept 'date' key when creating moment with object
* [#2009](https://github.com/moment/moment/issues/2009) Use native toISOString when we can
Some bugfixes and language improvements -- [full changelog](https://gist.github.com/ichernev/a4fcb0a46d74e4b9b996)
### 2.8.3
Bugfixes:
* [#1801](https://github.com/moment/moment/issues/1801) proper pluralization for Arabic
* [#1833](https://github.com/moment/moment/issues/1833) improve spm integration
* [#1871](https://github.com/moment/moment/issues/1871) fix zone bug caused by Firefox 24
* [#1882](https://github.com/moment/moment/issues/1882) Use hh:mm in Czech
* [#1883](https://github.com/moment/moment/issues/1883) Fix 2.8.0 regression in duration as conversions
* [#1890](https://github.com/moment/moment/issues/1890) Faster travis builds
* [#1892](https://github.com/moment/moment/issues/1892) Faster isBefore/After/Same
* [#1848](https://github.com/moment/moment/issues/1848) Fix flaky month diffs
* [#1895](https://github.com/moment/moment/issues/1895) Fix 2.8.0 regression in moment.utc with format array
* [#1896](https://github.com/moment/moment/issues/1896) Support setting invalid instance locale (noop)
* [#1897](https://github.com/moment/moment/issues/1897) Support moment([str]) in addition to moment([int])
### 2.8.2
Minor bugfixes:
* [#1874](https://github.com/moment/moment/issues/1874) use `Object.prototype.hasOwnProperty`
instead of `obj.hasOwnProperty` (ie8 bug)
* [#1873](https://github.com/moment/moment/issues/1873) add `duration#toString()`
* [#1859](https://github.com/moment/moment/issues/1859) better month/weekday names in norwegian
* [#1812](https://github.com/moment/moment/issues/1812) meridiem parsing for greek
* [#1804](https://github.com/moment/moment/issues/1804) spanish del -> de
* [#1800](https://github.com/moment/moment/issues/1800) korean LT improvement
### 2.8.1
* bugfix [#1813](https://github.com/moment/moment/issues/1813): fix moment().lang([key]) incompatibility
### 2.8.0 [See changelog](https://gist.github.com/ichernev/ac3899324a5fa6c8c9b4)
* incompatible changes
* [#1761](https://github.com/moment/moment/issues/1761): moments created without a language are no longer following the global language, in case it changes. Only newly created moments take the global language by default. In case you're affected by this, wait, comment on [#1797](https://github.com/moment/moment/issues/1797) and wait for a proper reimplementation
* [#1642](https://github.com/moment/moment/issues/1642): 45 days is no longer "a month" according to humanize, cutoffs for month, and year have changed. Hopefully your code does not depend on a particular answer from humanize (which it shouldn't anyway)
* [#1784](https://github.com/moment/moment/issues/1784): if you use the human readable English datetime format in a weird way (like storing them in a database) that would break when the format changes you're at risk.
* deprecations (old behavior will be dropped in 3.0)
* [#1761](https://github.com/moment/moment/issues/1761) `lang` is renamed to `locale`, `langData` -> `localeData`. Also there is now `defineLocale` that should be used when creating new locales
* [#1763](https://github.com/moment/moment/issues/1763) `add(unit, value)` and `subtract(unit, value)` are now deprecated. Use `add(value, unit)` and `subtract(value, unit)` instead.
* [#1759](https://github.com/moment/moment/issues/1759) rename `duration.toIsoString` to `duration.toISOString`. The js standard library and moment's `toISOString` follow that convention.
* new locales
* [#1789](https://github.com/moment/moment/issues/1789) Tibetan (bo)
* [#1786](https://github.com/moment/moment/issues/1786) Africaans (af)
* [#1778](https://github.com/moment/moment/issues/1778) Burmese (my)
* [#1727](https://github.com/moment/moment/issues/1727) Belarusian (be)
* bugfixes, locale bugfixes, performance improvements, features
### 2.7.0 [See changelog](https://gist.github.com/ichernev/b0a3d456d5a84c9901d7)
* new languages
* [#1678](https://github.com/moment/moment/issues/1678) Bengali (bn)
* [#1628](https://github.com/moment/moment/issues/1628) Azerbaijani (az)
* [#1633](https://github.com/moment/moment/issues/1633) Arabic, Saudi Arabia (ar-sa)
* [#1648](https://github.com/moment/moment/issues/1648) Austrian German (de-at)
* features
* [#1663](https://github.com/moment/moment/issues/1663) configurable relative time thresholds
* [#1554](https://github.com/moment/moment/issues/1554) support anchor time in moment.calendar
* [#1693](https://github.com/moment/moment/issues/1693) support moment.ISO_8601 as parsing format
* [#1637](https://github.com/moment/moment/issues/1637) add moment.min and moment.max and deprecate min/max instance methods
* [#1704](https://github.com/moment/moment/issues/1704) support string value in add/subtract
* [#1647](https://github.com/moment/moment/issues/1647) add spm support (package manager)
* bugfixes
### 2.6.0 [See changelog](https://gist.github.com/ichernev/10544682)
* languages
* [#1529](https://github.com/moment/moment/issues/1529) Serbian-Cyrillic (sr-cyr)
* [#1544](https://github.com/moment/moment/issues/1544), [#1546](https://github.com/moment/moment/issues/1546) Khmer Cambodia (km)
* features
* [#1419](https://github.com/moment/moment/issues/1419), [#1468](https://github.com/moment/moment/issues/1468), [#1467](https://github.com/moment/moment/issues/1467), [#1546](https://github.com/moment/moment/issues/1546) better handling of timezone-d moments around DST
* [#1462](https://github.com/moment/moment/issues/1462) add weeksInYear and isoWeeksInYear
* [#1475](https://github.com/moment/moment/issues/1475) support ordinal parsing
* [#1499](https://github.com/moment/moment/issues/1499) composer support
* [#1577](https://github.com/moment/moment/issues/1577), [#1604](https://github.com/moment/moment/issues/1604) put Date parsing in moment.createFromInputFallback so it can be properly deprecated and controlled in the future
* [#1545](https://github.com/moment/moment/issues/1545) extract two-digit year parsing in moment.parseTwoDigitYear, so it can be overwritten
* [#1590](https://github.com/moment/moment/issues/1590) (see [#1574](https://github.com/moment/moment/issues/1574)) set AMD global before module definition to better support non AMD module dependencies used in AMD environment
* [#1589](https://github.com/moment/moment/issues/1589) remove global in Node.JS environment (was not working before, nobody complained, was scheduled for removal anyway)
* [#1586](https://github.com/moment/moment/issues/1586) support quarter setting and parsing
* 18 bugs fixed
### 2.5.1
* languages
* [#1392](https://github.com/moment/moment/issues/1392) Armenian (hy-am)
* bugfixes
* [#1429](https://github.com/moment/moment/issues/1429) fixes [#1423](https://github.com/moment/moment/issues/1423) weird chrome-32 bug with js object creation
* [#1421](https://github.com/moment/moment/issues/1421) remove html entities from Welsh
* [#1418](https://github.com/moment/moment/issues/1418) fixes [#1401](https://github.com/moment/moment/issues/1401) improved non-padded tokens in strict matching
* [#1417](https://github.com/moment/moment/issues/1417) fixes [#1404](https://github.com/moment/moment/issues/1404) handle buggy moment object created by property cloning
* [#1398](https://github.com/moment/moment/issues/1398) fixes [#1397](https://github.com/moment/moment/issues/1397) fix Arabic-like week number parsing
* [#1396](https://github.com/moment/moment/issues/1396) add leftZeroFill(4) to GGGG and gggg formats
* [#1373](https://github.com/moment/moment/issues/1373) use lowercase for months and days in Catalan
* testing
* [#1374](https://github.com/moment/moment/issues/1374) run tests on multiple browser/os combos via SauceLabs and Travis
### 2.5.0 [See changelog](https://gist.github.com/ichernev/8104451)
* New languages
* Luxemburish (lb) [1247](https://github.com/moment/moment/issues/1247)
* Serbian (rs) [1319](https://github.com/moment/moment/issues/1319)
* Tamil (ta) [1324](https://github.com/moment/moment/issues/1324)
* Macedonian (mk) [1337](https://github.com/moment/moment/issues/1337)
* Features
* [1311](https://github.com/moment/moment/issues/1311) Add quarter getter and format token `Q`
* [1303](https://github.com/moment/moment/issues/1303) strict parsing now respects number of digits per token (fix [1196](https://github.com/moment/moment/issues/1196))
* 0d30bb7 add jspm support
* [1347](https://github.com/moment/moment/issues/1347) improve zone parsing
* [1362](https://github.com/moment/moment/issues/1362) support merideam parsing in Korean
* 22 bugfixes
### 2.4.0
* **Deprecate** globally exported moment, will be removed in next major
* New languages
* Farose (fo) [#1206](https://github.com/moment/moment/issues/1206)
* Tagalog/Filipino (tl-ph) [#1197](https://github.com/moment/moment/issues/1197)
* Welsh (cy) [#1215](https://github.com/moment/moment/issues/1215)
* Bugfixes
* properly handle Z at the end of iso RegExp [#1187](https://github.com/moment/moment/issues/1187)
* chinese meridian time improvements [#1076](https://github.com/moment/moment/issues/1076)
* fix language tests [#1177](https://github.com/moment/moment/issues/1177)
* remove some failing tests (that should have never existed :))
[#1185](https://github.com/moment/moment/issues/1185)
[#1183](https://github.com/moment/moment/issues/1183)
* handle russian noun cases in weird cases [#1195](https://github.com/moment/moment/issues/1195)
### 2.3.1
Removed a trailing comma [1169] and fixed a bug with `months`, `weekdays` getters [#1171](https://github.com/moment/moment/issues/1171).
### 2.3.0 [See changelog](https://gist.github.com/ichernev/6864354)
Changed isValid, added strict parsing.
Week tokens parsing.
### 2.2.1
Fixed bug in string prototype test.
Updated authors and contributors.
### 2.2.0 [See changelog](https://gist.github.com/ichernev/00f837a9baf46a3565e4)
Added bower support.
Language files now use UMD.
Creating moment defaults to current date/month/year.
Added a bundle of moment and all language files.
### 2.1.0 [See changelog](https://gist.github.com/timrwood/b8c2d90d528eddb53ab5)
Added better week support.
Added ability to set offset with `moment#zone`.
Added ability to set month or weekday from a string.
Added `moment#min` and `moment#max`
### 2.0.0 [See changelog](https://gist.github.com/timrwood/e72f2eef320ed9e37c51)
Added short form localized tokens.
Added ability to define language a string should be parsed in.
Added support for reversed add/subtract arguments.
Added support for `endOf('week')` and `startOf('week')`.
Fixed the logic for `moment#diff(Moment, 'months')` and `moment#diff(Moment, 'years')`
`moment#diff` now floors instead of rounds.
Normalized `moment#toString`.
Added `isSame`, `isAfter`, and `isBefore` methods.
Added better week support.
Added `moment#toJSON`
Bugfix: Fixed parsing of first century dates
Bugfix: Parsing 10Sep2001 should work as expected
Bugfix: Fixed weirdness with `moment.utc()` parsing.
Changed language ordinal method to return the number + ordinal instead of just the ordinal.
Changed two digit year parsing cutoff to match strptime.
Removed `moment#sod` and `moment#eod` in favor of `moment#startOf` and `moment#endOf`.
Removed `moment.humanizeDuration()` in favor of `moment.duration().humanize()`.
Removed the lang data objects from the top level namespace.
Duplicate `Date` passed to `moment()` instead of referencing it.
### 1.7.2 [See discussion](https://github.com/timrwood/moment/issues/456)
Bugfixes
### 1.7.1 [See discussion](https://github.com/timrwood/moment/issues/384)
Bugfixes
### 1.7.0 [See discussion](https://github.com/timrwood/moment/issues/288)
Added `moment.fn.endOf()` and `moment.fn.startOf()`.
Added validation via `moment.fn.isValid()`.
Made formatting method 3x faster. http://jsperf.com/momentjs-cached-format-functions
Add support for month/weekday callbacks in `moment.fn.format()`
Added instance specific languages.
Added two letter weekday abbreviations with the formatting token `dd`.
Various language updates.
Various bugfixes.
### 1.6.0 [See discussion](https://github.com/timrwood/moment/pull/268)
Added Durations.
Revamped parser to support parsing non-separated strings (YYYYMMDD vs YYYY-MM-DD).
Added support for millisecond parsing and formatting tokens (S SS SSS)
Added a getter for `moment.lang()`
Various bugfixes.
There are a few things deprecated in the 1.6.0 release.
1. The format tokens `z` and `zz` (timezone abbreviations like EST CST MST etc) will no longer be supported. Due to inconsistent browser support, we are unable to consistently produce this value. See [this issue](https://github.com/timrwood/moment/issues/162) for more background.
2. The method `moment.fn.native` is deprecated in favor of `moment.fn.toDate`. There continue to be issues with Google Closure Compiler throwing errors when using `native`, even in valid instances.
3. The way to customize am/pm strings is being changed. This would only affect you if you created a custom language file. For more information, see [this issue](https://github.com/timrwood/moment/pull/222).
### 1.5.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=10&page=1&state=closed)
Added UTC mode.
Added automatic ISO8601 parsing.
Various bugfixes.
### 1.4.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=8&state=closed)
Added `moment.fn.toDate` as a replacement for `moment.fn.native`.
Added `moment.fn.sod` and `moment.fn.eod` to get the start and end of day.
Various bugfixes.
### 1.3.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=7&state=closed)
Added support for parsing month names in the current language.
Added escape blocks for parsing tokens.
Added `moment.fn.calendar` to format strings like 'Today 2:30 PM', 'Tomorrow 1:25 AM', and 'Last Sunday 4:30 AM'.
Added `moment.fn.day` as a setter.
Various bugfixes
### 1.2.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=4&state=closed)
Added timezones to parser and formatter.
Added `moment.fn.isDST`.
Added `moment.fn.zone` to get the timezone offset in minutes.
### 1.1.2 [See milestone](https://github.com/timrwood/moment/issues?milestone=6&state=closed)
Various bugfixes
### 1.1.1 [See milestone](https://github.com/timrwood/moment/issues?milestone=5&state=closed)
Added time specific diffs (months, days, hours, etc)
### 1.1.0
Added `moment.fn.format` localized masks. 'L LL LLL LLLL' [issue 29](https://github.com/timrwood/moment/pull/29)
Fixed [issue 31](https://github.com/timrwood/moment/pull/31).
### 1.0.1
Added `moment.version` to get the current version.
Removed `window !== undefined` when checking if module exists to support browserify. [issue 25](https://github.com/timrwood/moment/pull/25)
### 1.0.0
Added convenience methods for getting and setting date parts.
Added better support for `moment.add()`.
Added better lang support in NodeJS.
Renamed library from underscore.date to Moment.js
### 0.6.1
Added Portuguese, Italian, and French language support
### 0.6.0
Added _date.lang() support.
Added support for passing multiple formats to try to parse a date. _date("07-10-1986", ["MM-DD-YYYY", "YYYY-MM-DD"]);
Made parse from string and single format 25% faster.
### 0.5.2
Bugfix for [issue 8](https://github.com/timrwood/underscore.date/pull/8) and [issue 9](https://github.com/timrwood/underscore.date/pull/9).
### 0.5.1
Bugfix for [issue 5](https://github.com/timrwood/underscore.date/pull/5).
### 0.5.0
Dropped the redundant `_date.date()` in favor of `_date()`.
Removed `_date.now()`, as it is a duplicate of `_date()` with no parameters.
Removed `_date.isLeapYear(yearNumber)`. Use `_date([yearNumber]).isLeapYear()` instead.
Exposed customization options through the `_date.relativeTime`, `_date.weekdays`, `_date.weekdaysShort`, `_date.months`, `_date.monthsShort`, and `_date.ordinal` variables instead of the `_date.customize()` function.
### 0.4.1
Added date input formats for input strings.
### 0.4.0
Added underscore.date to npm. Removed dependencies on underscore.
### 0.3.2
Added `'z'` and `'zz'` to `_.date().format()`. Cleaned up some redundant code to trim off some bytes.
### 0.3.1
Cleaned up the namespace. Moved all date manipulation and display functions to the _.date() object.
### 0.3.0
Switched to the Underscore methodology of not mucking with the native objects' prototypes.
Made chaining possible.
### 0.2.1
Changed date names to be a more pseudo standardized 'dddd, MMMM Do YYYY, h:mm:ss a'.
Added `Date.prototype` functions `add`, `subtract`, `isdst`, and `isleapyear`.
### 0.2.0
Changed function names to be more concise.
Changed date format from php date format to custom format.
### 0.1.0
Initial release

View File

@@ -0,0 +1,22 @@
Copyright (c) 2011-2016 Tim Wood, Iskren Chernev, Moment.js contributors
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,58 @@
[![Join the chat at https://gitter.im/moment/moment](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/moment/moment?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![NPM version][npm-version-image]][npm-url] [![NPM downloads][npm-downloads-image]][npm-url] [![MIT License][license-image]][license-url] [![Build Status][travis-image]][travis-url]
[![Coverage Status](https://coveralls.io/repos/moment/moment/badge.svg?branch=develop)](https://coveralls.io/r/moment/moment?branch=develop)
A lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates.
**[Documentation](http://momentjs.com/docs/)**
## Port to ECMAScript 6 (version 2.10.0)
Moment 2.10.0 does not bring any new features, but the code is now written in
ECMAScript 6 modules and placed inside `src/`. Previously `moment.js`, `locale/*.js` and
`test/moment/*.js`, `test/locale/*.js` contained the source of the project. Now
the source is in `src/`, temporary build (ECMAScript 5) files are placed under
`build/umd/` (for running tests during development), and the `moment.js` and
`locale/*.js` files are updated only on release.
If you want to use a particular revision of the code, make sure to run
`grunt transpile update-index`, so `moment.js` and `locales/*.js` are synced
with `src/*`. We might place that in a commit hook in the future.
## Upgrading to 2.0.0
There are a number of small backwards incompatible changes with version 2.0.0. [See the full descriptions here](https://gist.github.com/timrwood/e72f2eef320ed9e37c51#backwards-incompatible-changes)
* Changed language ordinal method to return the number + ordinal instead of just the ordinal.
* Changed two digit year parsing cutoff to match strptime.
* Removed `moment#sod` and `moment#eod` in favor of `moment#startOf` and `moment#endOf`.
* Removed `moment.humanizeDuration()` in favor of `moment.duration().humanize()`.
* Removed the lang data objects from the top level namespace.
* Duplicate `Date` passed to `moment()` instead of referencing it.
## [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
## [Contributing](https://github.com/moment/moment/blob/develop/CONTRIBUTING.md)
We're looking for co-maintainers! If you want to become a master of time please
write to [ichernev](https://github.com/ichernev).
## License
Moment.js is freely distributable under the terms of the [MIT license](https://github.com/moment/moment/blob/develop/LICENSE).
[license-image]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat
[license-url]: LICENSE
[npm-url]: https://npmjs.org/package/moment
[npm-version-image]: http://img.shields.io/npm/v/moment.svg?style=flat
[npm-downloads-image]: http://img.shields.io/npm/dm/moment.svg?style=flat
[travis-url]: http://travis-ci.org/moment/moment
[travis-image]: http://img.shields.io/travis/moment/moment/develop.svg?style=flat

View File

@@ -0,0 +1 @@
$.ender({ moment: require('moment') })

View File

@@ -0,0 +1,73 @@
//! moment.js locale configuration
//! locale : Afrikaans [af]
//! author : Werner Mollentze : https://github.com/wernerm
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var af = moment.defineLocale('af', {
months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),
monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),
weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),
weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),
weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),
meridiemParse: /vm|nm/i,
isPM : function (input) {
return /^nm$/i.test(input);
},
meridiem : function (hours, minutes, isLower) {
if (hours < 12) {
return isLower ? 'vm' : 'VM';
} else {
return isLower ? 'nm' : 'NM';
}
},
longDateFormat : {
LT : 'HH:mm',
LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY HH:mm',
LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[Vandag om] LT',
nextDay : '[Môre om] LT',
nextWeek : 'dddd [om] LT',
lastDay : '[Gister om] LT',
lastWeek : '[Laas] dddd [om] LT',
sameElse : 'L'
},
relativeTime : {
future : 'oor %s',
past : '%s gelede',
s : '\'n paar sekondes',
m : '\'n minuut',
mm : '%d minute',
h : '\'n uur',
hh : '%d ure',
d : '\'n dag',
dd : '%d dae',
M : '\'n maand',
MM : '%d maande',
y : '\'n jaar',
yy : '%d jaar'
},
ordinalParse: /\d{1,2}(ste|de)/,
ordinal : function (number) {
return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter
},
week : {
dow : 1, // Maandag is die eerste dag van die week.
doy : 4 // Die week wat die 4de Januarie bevat is die eerste week van die jaar.
}
});
return af;
}));

View File

@@ -0,0 +1,60 @@
//! moment.js locale configuration
//! locale : Arabic (Morocco) [ar-ma]
//! author : ElFadili Yassine : https://github.com/ElFadiliY
//! author : Abdel Said : https://github.com/abdelsaid
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var ar_ma = moment.defineLocale('ar-ma', {
months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
weekdaysParseExact : true,
longDateFormat : {
LT : 'HH:mm',
LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY HH:mm',
LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[اليوم على الساعة] LT',
nextDay: '[غدا على الساعة] LT',
nextWeek: 'dddd [على الساعة] LT',
lastDay: '[أمس على الساعة] LT',
lastWeek: 'dddd [على الساعة] LT',
sameElse: 'L'
},
relativeTime : {
future : 'في %s',
past : 'منذ %s',
s : 'ثوان',
m : 'دقيقة',
mm : '%d دقائق',
h : 'ساعة',
hh : '%d ساعات',
d : 'يوم',
dd : '%d أيام',
M : 'شهر',
MM : '%d أشهر',
y : 'سنة',
yy : '%d سنوات'
},
week : {
dow : 6, // Saturday is the first day of the week.
doy : 12 // The week that contains Jan 1st is the first week of the year.
}
});
return ar_ma;
}));

View File

@@ -0,0 +1,104 @@
//! moment.js locale configuration
//! locale : Arabic (Saudi Arabia) [ar-sa]
//! author : Suhail Alkowaileet : https://github.com/xsoh
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var symbolMap = {
'1': '١',
'2': '٢',
'3': '٣',
'4': '٤',
'5': '٥',
'6': '٦',
'7': '٧',
'8': '٨',
'9': '٩',
'0': '٠'
}, numberMap = {
'١': '1',
'٢': '2',
'٣': '3',
'٤': '4',
'٥': '5',
'٦': '6',
'٧': '7',
'٨': '8',
'٩': '9',
'٠': '0'
};
var ar_sa = moment.defineLocale('ar-sa', {
months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
weekdaysParseExact : true,
longDateFormat : {
LT : 'HH:mm',
LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY HH:mm',
LLLL : 'dddd D MMMM YYYY HH:mm'
},
meridiemParse: /ص|م/,
isPM : function (input) {
return 'م' === input;
},
meridiem : function (hour, minute, isLower) {
if (hour < 12) {
return 'ص';
} else {
return 'م';
}
},
calendar : {
sameDay: '[اليوم على الساعة] LT',
nextDay: '[غدا على الساعة] LT',
nextWeek: 'dddd [على الساعة] LT',
lastDay: '[أمس على الساعة] LT',
lastWeek: 'dddd [على الساعة] LT',
sameElse: 'L'
},
relativeTime : {
future : 'في %s',
past : 'منذ %s',
s : 'ثوان',
m : 'دقيقة',
mm : '%d دقائق',
h : 'ساعة',
hh : '%d ساعات',
d : 'يوم',
dd : '%d أيام',
M : 'شهر',
MM : '%d أشهر',
y : 'سنة',
yy : '%d سنوات'
},
preparse: function (string) {
return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
return numberMap[match];
}).replace(/،/g, ',');
},
postformat: function (string) {
return string.replace(/\d/g, function (match) {
return symbolMap[match];
}).replace(/,/g, '،');
},
week : {
dow : 6, // Saturday is the first day of the week.
doy : 12 // The week that contains Jan 1st is the first week of the year.
}
});
return ar_sa;
}));

View File

@@ -0,0 +1,58 @@
//! moment.js locale configuration
//! locale : Arabic (Tunisia) [ar-tn]
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var ar_tn = moment.defineLocale('ar-tn', {
months: انفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
monthsShort: انفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
weekdaysParseExact : true,
longDateFormat: {
LT: 'HH:mm',
LTS: 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
LLL: 'D MMMM YYYY HH:mm',
LLLL: 'dddd D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[اليوم على الساعة] LT',
nextDay: '[غدا على الساعة] LT',
nextWeek: 'dddd [على الساعة] LT',
lastDay: '[أمس على الساعة] LT',
lastWeek: 'dddd [على الساعة] LT',
sameElse: 'L'
},
relativeTime: {
future: 'في %s',
past: 'منذ %s',
s: 'ثوان',
m: 'دقيقة',
mm: '%d دقائق',
h: 'ساعة',
hh: '%d ساعات',
d: 'يوم',
dd: '%d أيام',
M: 'شهر',
MM: '%d أشهر',
y: 'سنة',
yy: '%d سنوات'
},
week: {
dow: 1, // Monday is the first day of the week.
doy: 4 // The week that contains Jan 4th is the first week of the year.
}
});
return ar_tn;
}));

View File

@@ -0,0 +1,137 @@
//! moment.js locale configuration
//! locale : Arabic [ar]
//! author : Abdel Said: https://github.com/abdelsaid
//! changes in months, weekdays: Ahmed Elkhatib
//! Native plural forms: forabi https://github.com/forabi
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var symbolMap = {
'1': '١',
'2': '٢',
'3': '٣',
'4': '٤',
'5': '٥',
'6': '٦',
'7': '٧',
'8': '٨',
'9': '٩',
'0': '٠'
}, numberMap = {
'١': '1',
'٢': '2',
'٣': '3',
'٤': '4',
'٥': '5',
'٦': '6',
'٧': '7',
'٨': '8',
'٩': '9',
'٠': '0'
}, pluralForm = function (n) {
return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;
}, plurals = {
s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],
m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],
h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],
d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],
M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],
y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']
}, pluralize = function (u) {
return function (number, withoutSuffix, string, isFuture) {
var f = pluralForm(number),
str = plurals[u][pluralForm(number)];
if (f === 2) {
str = str[withoutSuffix ? 0 : 1];
}
return str.replace(/%d/i, number);
};
}, months = [
'كانون الثاني يناير',
'شباط فبراير',
'آذار مارس',
'نيسان أبريل',
'أيار مايو',
'حزيران يونيو',
'تموز يوليو',
'آب أغسطس',
'أيلول سبتمبر',
'تشرين الأول أكتوبر',
'تشرين الثاني نوفمبر',
'كانون الأول ديسمبر'
];
var ar = moment.defineLocale('ar', {
months : months,
monthsShort : months,
weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
weekdaysParseExact : true,
longDateFormat : {
LT : 'HH:mm',
LTS : 'HH:mm:ss',
L : 'D/\u200FM/\u200FYYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY HH:mm',
LLLL : 'dddd D MMMM YYYY HH:mm'
},
meridiemParse: /ص|م/,
isPM : function (input) {
return 'م' === input;
},
meridiem : function (hour, minute, isLower) {
if (hour < 12) {
return 'ص';
} else {
return 'م';
}
},
calendar : {
sameDay: '[اليوم عند الساعة] LT',
nextDay: '[غدًا عند الساعة] LT',
nextWeek: 'dddd [عند الساعة] LT',
lastDay: '[أمس عند الساعة] LT',
lastWeek: 'dddd [عند الساعة] LT',
sameElse: 'L'
},
relativeTime : {
future : 'بعد %s',
past : 'منذ %s',
s : pluralize('s'),
m : pluralize('m'),
mm : pluralize('m'),
h : pluralize('h'),
hh : pluralize('h'),
d : pluralize('d'),
dd : pluralize('d'),
M : pluralize('M'),
MM : pluralize('M'),
y : pluralize('y'),
yy : pluralize('y')
},
preparse: function (string) {
return string.replace(/\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
return numberMap[match];
}).replace(/،/g, ',');
},
postformat: function (string) {
return string.replace(/\d/g, function (match) {
return symbolMap[match];
}).replace(/,/g, '،');
},
week : {
dow : 6, // Saturday is the first day of the week.
doy : 12 // The week that contains Jan 1st is the first week of the year.
}
});
return ar;
}));

View File

@@ -0,0 +1,105 @@
//! moment.js locale configuration
//! locale : Azerbaijani [az]
//! author : topchiyev : https://github.com/topchiyev
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var suffixes = {
1: '-inci',
5: '-inci',
8: '-inci',
70: '-inci',
80: '-inci',
2: '-nci',
7: '-nci',
20: '-nci',
50: '-nci',
3: '-üncü',
4: '-üncü',
100: '-üncü',
6: '-ncı',
9: '-uncu',
10: '-uncu',
30: '-uncu',
60: '-ıncı',
90: '-ıncı'
};
var az = moment.defineLocale('az', {
months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),
monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),
weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),
weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),
weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),
weekdaysParseExact : true,
longDateFormat : {
LT : 'HH:mm',
LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY HH:mm',
LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[bugün saat] LT',
nextDay : '[sabah saat] LT',
nextWeek : '[gələn həftə] dddd [saat] LT',
lastDay : '[dünən] LT',
lastWeek : '[keçən həftə] dddd [saat] LT',
sameElse : 'L'
},
relativeTime : {
future : '%s sonra',
past : '%s əvvəl',
s : 'birneçə saniyyə',
m : 'bir dəqiqə',
mm : '%d dəqiqə',
h : 'bir saat',
hh : '%d saat',
d : 'bir gün',
dd : '%d gün',
M : 'bir ay',
MM : '%d ay',
y : 'bir il',
yy : '%d il'
},
meridiemParse: /gecə|səhər|gündüz|axşam/,
isPM : function (input) {
return /^(gündüz|axşam)$/.test(input);
},
meridiem : function (hour, minute, isLower) {
if (hour < 4) {
return 'gecə';
} else if (hour < 12) {
return 'səhər';
} else if (hour < 17) {
return 'gündüz';
} else {
return 'axşam';
}
},
ordinalParse: /\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,
ordinal : function (number) {
if (number === 0) { // special case for zero
return number + '-ıncı';
}
var a = number % 10,
b = number % 100 - a,
c = number >= 100 ? 100 : null;
return number + (suffixes[a] || suffixes[b] || suffixes[c]);
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 7 // The week that contains Jan 1st is the first week of the year.
}
});
return az;
}));

View File

@@ -0,0 +1,134 @@
//! moment.js locale configuration
//! locale : Belarusian [be]
//! author : Dmitry Demidov : https://github.com/demidov91
//! author: Praleska: http://praleska.pro/
//! Author : Menelion Elensúle : https://github.com/Oire
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
function plural(word, num) {
var forms = word.split('_');
return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
}
function relativeTimeWithPlural(number, withoutSuffix, key) {
var format = {
'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',
'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',
'dd': 'дзень_дні_дзён',
'MM': есяц_месяцы_месяцаў',
'yy': 'год_гады_гадоў'
};
if (key === 'm') {
return withoutSuffix ? 'хвіліна' : 'хвіліну';
}
else if (key === 'h') {
return withoutSuffix ? 'гадзіна' : 'гадзіну';
}
else {
return number + ' ' + plural(format[key], +number);
}
}
var be = moment.defineLocale('be', {
months : {
format: 'студзеня_лютага_сакавікарасавікараўня_чэрвеня_ліпеня_жніўня_верасня_кастрычнікаістапада_снежня'.split('_'),
standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_')
},
monthsShort : 'студ_лют_сак_красрав_чэрв_ліп_жнів_вераст_ліст_снеж'.split('_'),
weekdays : {
format: 'нядзелю_панядзелак_аўторак_серадуацвер_пятніцу_суботу'.split('_'),
standalone: 'нядзеля_панядзелак_аўторак_серадаацвер_пятніца_субота'.split('_'),
isFormat: /\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/
},
weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
longDateFormat : {
LT : 'HH:mm',
LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY г.',
LLL : 'D MMMM YYYY г., HH:mm',
LLLL : 'dddd, D MMMM YYYY г., HH:mm'
},
calendar : {
sameDay: '[Сёння ў] LT',
nextDay: '[Заўтра ў] LT',
lastDay: '[Учора ў] LT',
nextWeek: function () {
return '[У] dddd [ў] LT';
},
lastWeek: function () {
switch (this.day()) {
case 0:
case 3:
case 5:
case 6:
return '[У мінулую] dddd [ў] LT';
case 1:
case 2:
case 4:
return '[У мінулы] dddd [ў] LT';
}
},
sameElse: 'L'
},
relativeTime : {
future : 'праз %s',
past : '%s таму',
s : 'некалькі секунд',
m : relativeTimeWithPlural,
mm : relativeTimeWithPlural,
h : relativeTimeWithPlural,
hh : relativeTimeWithPlural,
d : 'дзень',
dd : relativeTimeWithPlural,
M : 'месяц',
MM : relativeTimeWithPlural,
y : 'год',
yy : relativeTimeWithPlural
},
meridiemParse: /ночы|раніцы|дня|вечара/,
isPM : function (input) {
return /^(дня|вечара)$/.test(input);
},
meridiem : function (hour, minute, isLower) {
if (hour < 4) {
return 'ночы';
} else if (hour < 12) {
return 'раніцы';
} else if (hour < 17) {
return 'дня';
} else {
return 'вечара';
}
},
ordinalParse: /\d{1,2}-(і|ы|га)/,
ordinal: function (number, period) {
switch (period) {
case 'M':
case 'd':
case 'DDD':
case 'w':
case 'W':
return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';
case 'D':
return number + '-га';
default:
return number;
}
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 7 // The week that contains Jan 1st is the first week of the year.
}
});
return be;
}));

View File

@@ -0,0 +1,90 @@
//! moment.js locale configuration
//! locale : Bulgarian [bg]
//! author : Krasen Borisov : https://github.com/kraz
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var bg = moment.defineLocale('bg', {
months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),
monthsShort : 'янрев_мар_апрай_юни_юли_авг_сеп_окт_ноеек'.split('_'),
weekdays : еделя_понеделник_вторник_срядаетвъртък_петък_събота'.split('_'),
weekdaysShort : ед_пон_вто_сря_чет_пет_съб'.split('_'),
weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
longDateFormat : {
LT : 'H:mm',
LTS : 'H:mm:ss',
L : 'D.MM.YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY H:mm',
LLLL : 'dddd, D MMMM YYYY H:mm'
},
calendar : {
sameDay : '[Днес в] LT',
nextDay : '[Утре в] LT',
nextWeek : 'dddd [в] LT',
lastDay : '[Вчера в] LT',
lastWeek : function () {
switch (this.day()) {
case 0:
case 3:
case 6:
return '[В изминалата] dddd [в] LT';
case 1:
case 2:
case 4:
case 5:
return '[В изминалия] dddd [в] LT';
}
},
sameElse : 'L'
},
relativeTime : {
future : 'след %s',
past : 'преди %s',
s : 'няколко секунди',
m : 'минута',
mm : '%d минути',
h : 'час',
hh : '%d часа',
d : 'ден',
dd : '%d дни',
M : 'месец',
MM : '%d месеца',
y : 'година',
yy : '%d години'
},
ordinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/,
ordinal : function (number) {
var lastDigit = number % 10,
last2Digits = number % 100;
if (number === 0) {
return number + '-ев';
} else if (last2Digits === 0) {
return number + '-ен';
} else if (last2Digits > 10 && last2Digits < 20) {
return number + '-ти';
} else if (lastDigit === 1) {
return number + '-ви';
} else if (lastDigit === 2) {
return number + '-ри';
} else if (lastDigit === 7 || lastDigit === 8) {
return number + '-ми';
} else {
return number + '-ти';
}
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 7 // The week that contains Jan 1st is the first week of the year.
}
});
return bg;
}));

View File

@@ -0,0 +1,119 @@
//! moment.js locale configuration
//! locale : Bengali [bn]
//! author : Kaushik Gandhi : https://github.com/kaushikgandhi
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var symbolMap = {
'1': '১',
'2': '২',
'3': '৩',
'4': '',
'5': '৫',
'6': '৬',
'7': '',
'8': '৮',
'9': '৯',
'0': ''
},
numberMap = {
'১': '1',
'২': '2',
'৩': '3',
'': '4',
'৫': '5',
'৬': '6',
'': '7',
'৮': '8',
'৯': '9',
'': '0'
};
var bn = moment.defineLocale('bn', {
months : 'জানুয়ারী_ফেবুয়ারী_মার্চ_এপ্রিল_মে_জুন_জুলাই_অগাস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),
monthsShort : 'জানু_ফেব_মার্চ_এপর_মে_জুন_জুল_অগ_সেপ্ট_অক্টো_নভ_ডিসেম্'.split('_'),
weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পত্তিবার_শুক্রবার_শনিবার'.split('_'),
weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পত্তি_শুক্র_শনি'.split('_'),
weekdaysMin : 'রব_সম_মঙ্গ_বু_ব্রিহ_শু_শনি'.split('_'),
longDateFormat : {
LT : 'A h:mm সময়',
LTS : 'A h:mm:ss সময়',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY, A h:mm সময়',
LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'
},
calendar : {
sameDay : '[আজ] LT',
nextDay : '[আগামীকাল] LT',
nextWeek : 'dddd, LT',
lastDay : '[গতকাল] LT',
lastWeek : '[গত] dddd, LT',
sameElse : 'L'
},
relativeTime : {
future : '%s পরে',
past : '%s আগে',
s : 'কয়েক সেকেন্ড',
m : 'এক মিনিট',
mm : '%d মিনিট',
h : 'এক ঘন্টা',
hh : '%d ঘন্টা',
d : 'এক দিন',
dd : '%d দিন',
M : 'এক মাস',
MM : '%d মাস',
y : 'এক বছর',
yy : '%d বছর'
},
preparse: function (string) {
return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {
return numberMap[match];
});
},
postformat: function (string) {
return string.replace(/\d/g, function (match) {
return symbolMap[match];
});
},
meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/,
meridiemHour : function (hour, meridiem) {
if (hour === 12) {
hour = 0;
}
if ((meridiem === 'রাত' && hour >= 4) ||
(meridiem === 'দুপুর' && hour < 5) ||
meridiem === 'বিকাল') {
return hour + 12;
} else {
return hour;
}
},
meridiem : function (hour, minute, isLower) {
if (hour < 4) {
return 'রাত';
} else if (hour < 10) {
return 'সকাল';
} else if (hour < 17) {
return 'দুপুর';
} else if (hour < 20) {
return 'বিকাল';
} else {
return 'রাত';
}
},
week : {
dow : 0, // Sunday is the first day of the week.
doy : 6 // The week that contains Jan 1st is the first week of the year.
}
});
return bn;
}));

View File

@@ -0,0 +1,119 @@
//! moment.js locale configuration
//! locale : Tibetan [bo]
//! author : Thupten N. Chakrishar : https://github.com/vajradog
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var symbolMap = {
'1': '༡',
'2': '༢',
'3': '༣',
'4': '༤',
'5': '༥',
'6': '༦',
'7': '༧',
'8': '༨',
'9': '༩',
'0': '༠'
},
numberMap = {
'༡': '1',
'༢': '2',
'༣': '3',
'༤': '4',
'༥': '5',
'༦': '6',
'༧': '7',
'༨': '8',
'༩': '9',
'༠': '0'
};
var bo = moment.defineLocale('bo', {
months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),
monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),
weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),
weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),
weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),
longDateFormat : {
LT : 'A h:mm',
LTS : 'A h:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY, A h:mm',
LLLL : 'dddd, D MMMM YYYY, A h:mm'
},
calendar : {
sameDay : '[དི་རིང] LT',
nextDay : '[སང་ཉིན] LT',
nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',
lastDay : '[ཁ་སང] LT',
lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',
sameElse : 'L'
},
relativeTime : {
future : '%s ལ་',
past : '%s སྔན་ལ',
s : 'ལམ་སང',
m : 'སྐར་མ་གཅིག',
mm : '%d སྐར་མ',
h : 'ཆུ་ཚོད་གཅིག',
hh : '%d ཆུ་ཚོད',
d : 'ཉིན་གཅིག',
dd : '%d ཉིན་',
M : 'ཟླ་བ་གཅིག',
MM : '%d ཟླ་བ',
y : 'ལོ་གཅིག',
yy : '%d ལོ'
},
preparse: function (string) {
return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {
return numberMap[match];
});
},
postformat: function (string) {
return string.replace(/\d/g, function (match) {
return symbolMap[match];
});
},
meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,
meridiemHour : function (hour, meridiem) {
if (hour === 12) {
hour = 0;
}
if ((meridiem === 'མཚན་མོ' && hour >= 4) ||
(meridiem === 'ཉིན་གུང' && hour < 5) ||
meridiem === 'དགོང་དག') {
return hour + 12;
} else {
return hour;
}
},
meridiem : function (hour, minute, isLower) {
if (hour < 4) {
return 'མཚན་མོ';
} else if (hour < 10) {
return 'ཞོགས་ཀས';
} else if (hour < 17) {
return 'ཉིན་གུང';
} else if (hour < 20) {
return 'དགོང་དག';
} else {
return 'མཚན་མོ';
}
},
week : {
dow : 0, // Sunday is the first day of the week.
doy : 6 // The week that contains Jan 1st is the first week of the year.
}
});
return bo;
}));

View File

@@ -0,0 +1,108 @@
//! moment.js locale configuration
//! locale : Breton [br]
//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
function relativeTimeWithMutation(number, withoutSuffix, key) {
var format = {
'mm': 'munutenn',
'MM': 'miz',
'dd': 'devezh'
};
return number + ' ' + mutation(format[key], number);
}
function specialMutationForYears(number) {
switch (lastNumber(number)) {
case 1:
case 3:
case 4:
case 5:
case 9:
return number + ' bloaz';
default:
return number + ' vloaz';
}
}
function lastNumber(number) {
if (number > 9) {
return lastNumber(number % 10);
}
return number;
}
function mutation(text, number) {
if (number === 2) {
return softMutation(text);
}
return text;
}
function softMutation(text) {
var mutationTable = {
'm': 'v',
'b': 'v',
'd': 'z'
};
if (mutationTable[text.charAt(0)] === undefined) {
return text;
}
return mutationTable[text.charAt(0)] + text.substring(1);
}
var br = moment.defineLocale('br', {
months : 'Genver_C\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),
monthsShort : 'Gen_C\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),
weekdays : 'Sul_Lun_Meurzh_Merc\'her_Yaou_Gwener_Sadorn'.split('_'),
weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),
weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),
weekdaysParseExact : true,
longDateFormat : {
LT : 'h[e]mm A',
LTS : 'h[e]mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D [a viz] MMMM YYYY',
LLL : 'D [a viz] MMMM YYYY h[e]mm A',
LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'
},
calendar : {
sameDay : '[Hiziv da] LT',
nextDay : '[Warc\'hoazh da] LT',
nextWeek : 'dddd [da] LT',
lastDay : '[Dec\'h da] LT',
lastWeek : 'dddd [paset da] LT',
sameElse : 'L'
},
relativeTime : {
future : 'a-benn %s',
past : '%s \'zo',
s : 'un nebeud segondennoù',
m : 'ur vunutenn',
mm : relativeTimeWithMutation,
h : 'un eur',
hh : '%d eur',
d : 'un devezh',
dd : relativeTimeWithMutation,
M : 'ur miz',
MM : relativeTimeWithMutation,
y : 'ur bloaz',
yy : specialMutationForYears
},
ordinalParse: /\d{1,2}(añ|vet)/,
ordinal : function (number) {
var output = (number === 1) ? 'añ' : 'vet';
return number + output;
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 4 // The week that contains Jan 4th is the first week of the year.
}
});
return br;
}));

View File

@@ -0,0 +1,143 @@
//! moment.js locale configuration
//! locale : Bosnian [bs]
//! author : Nedim Cholich : https://github.com/frontyard
//! based on (hr) translation by Bojan Marković
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
function translate(number, withoutSuffix, key) {
var result = number + ' ';
switch (key) {
case 'm':
return withoutSuffix ? 'jedna minuta' : 'jedne minute';
case 'mm':
if (number === 1) {
result += 'minuta';
} else if (number === 2 || number === 3 || number === 4) {
result += 'minute';
} else {
result += 'minuta';
}
return result;
case 'h':
return withoutSuffix ? 'jedan sat' : 'jednog sata';
case 'hh':
if (number === 1) {
result += 'sat';
} else if (number === 2 || number === 3 || number === 4) {
result += 'sata';
} else {
result += 'sati';
}
return result;
case 'dd':
if (number === 1) {
result += 'dan';
} else {
result += 'dana';
}
return result;
case 'MM':
if (number === 1) {
result += 'mjesec';
} else if (number === 2 || number === 3 || number === 4) {
result += 'mjeseca';
} else {
result += 'mjeseci';
}
return result;
case 'yy':
if (number === 1) {
result += 'godina';
} else if (number === 2 || number === 3 || number === 4) {
result += 'godine';
} else {
result += 'godina';
}
return result;
}
}
var bs = moment.defineLocale('bs', {
months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),
monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),
monthsParseExact: true,
weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),
weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
weekdaysParseExact : true,
longDateFormat : {
LT : 'H:mm',
LTS : 'H:mm:ss',
L : 'DD. MM. YYYY',
LL : 'D. MMMM YYYY',
LLL : 'D. MMMM YYYY H:mm',
LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[danas u] LT',
nextDay : '[sutra u] LT',
nextWeek : function () {
switch (this.day()) {
case 0:
return '[u] [nedjelju] [u] LT';
case 3:
return '[u] [srijedu] [u] LT';
case 6:
return '[u] [subotu] [u] LT';
case 1:
case 2:
case 4:
case 5:
return '[u] dddd [u] LT';
}
},
lastDay : '[jučer u] LT',
lastWeek : function () {
switch (this.day()) {
case 0:
case 3:
return '[prošlu] dddd [u] LT';
case 6:
return '[prošle] [subote] [u] LT';
case 1:
case 2:
case 4:
case 5:
return '[prošli] dddd [u] LT';
}
},
sameElse : 'L'
},
relativeTime : {
future : 'za %s',
past : 'prije %s',
s : 'par sekundi',
m : translate,
mm : translate,
h : translate,
hh : translate,
d : 'dan',
dd : translate,
M : 'mjesec',
MM : translate,
y : 'godinu',
yy : translate
},
ordinalParse: /\d{1,2}\./,
ordinal : '%d.',
week : {
dow : 1, // Monday is the first day of the week.
doy : 7 // The week that contains Jan 1st is the first week of the year.
}
});
return bs;
}));

View File

@@ -0,0 +1,81 @@
//! moment.js locale configuration
//! locale : Catalan [ca]
//! author : Juan G. Hurtado : https://github.com/juanghurtado
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var ca = moment.defineLocale('ca', {
months : 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),
monthsShort : 'gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.'.split('_'),
monthsParseExact : true,
weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),
weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),
weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),
weekdaysParseExact : true,
longDateFormat : {
LT : 'H:mm',
LTS : 'H:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY H:mm',
LLLL : 'dddd D MMMM YYYY H:mm'
},
calendar : {
sameDay : function () {
return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
},
nextDay : function () {
return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
},
nextWeek : function () {
return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
},
lastDay : function () {
return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
},
lastWeek : function () {
return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
},
sameElse : 'L'
},
relativeTime : {
future : 'en %s',
past : 'fa %s',
s : 'uns segons',
m : 'un minut',
mm : '%d minuts',
h : 'una hora',
hh : '%d hores',
d : 'un dia',
dd : '%d dies',
M : 'un mes',
MM : '%d mesos',
y : 'un any',
yy : '%d anys'
},
ordinalParse: /\d{1,2}(r|n|t|è|a)/,
ordinal : function (number, period) {
var output = (number === 1) ? 'r' :
(number === 2) ? 'n' :
(number === 3) ? 'r' :
(number === 4) ? 't' : 'è';
if (period === 'w' || period === 'W') {
output = 'a';
}
return number + output;
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 4 // The week that contains Jan 4th is the first week of the year.
}
});
return ca;
}));

View File

@@ -0,0 +1,172 @@
//! moment.js locale configuration
//! locale : Czech [cs]
//! author : petrbela : https://github.com/petrbela
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'),
monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');
function plural(n) {
return (n > 1) && (n < 5) && (~~(n / 10) !== 1);
}
function translate(number, withoutSuffix, key, isFuture) {
var result = number + ' ';
switch (key) {
case 's': // a few seconds / in a few seconds / a few seconds ago
return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';
case 'm': // a minute / in a minute / a minute ago
return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');
case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
if (withoutSuffix || isFuture) {
return result + (plural(number) ? 'minuty' : 'minut');
} else {
return result + 'minutami';
}
break;
case 'h': // an hour / in an hour / an hour ago
return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');
case 'hh': // 9 hours / in 9 hours / 9 hours ago
if (withoutSuffix || isFuture) {
return result + (plural(number) ? 'hodiny' : 'hodin');
} else {
return result + 'hodinami';
}
break;
case 'd': // a day / in a day / a day ago
return (withoutSuffix || isFuture) ? 'den' : 'dnem';
case 'dd': // 9 days / in 9 days / 9 days ago
if (withoutSuffix || isFuture) {
return result + (plural(number) ? 'dny' : 'dní');
} else {
return result + 'dny';
}
break;
case 'M': // a month / in a month / a month ago
return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';
case 'MM': // 9 months / in 9 months / 9 months ago
if (withoutSuffix || isFuture) {
return result + (plural(number) ? 'měsíce' : 'měsíců');
} else {
return result + 'měsíci';
}
break;
case 'y': // a year / in a year / a year ago
return (withoutSuffix || isFuture) ? 'rok' : 'rokem';
case 'yy': // 9 years / in 9 years / 9 years ago
if (withoutSuffix || isFuture) {
return result + (plural(number) ? 'roky' : 'let');
} else {
return result + 'lety';
}
break;
}
}
var cs = moment.defineLocale('cs', {
months : months,
monthsShort : monthsShort,
monthsParse : (function (months, monthsShort) {
var i, _monthsParse = [];
for (i = 0; i < 12; i++) {
// use custom parser to solve problem with July (červenec)
_monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');
}
return _monthsParse;
}(months, monthsShort)),
shortMonthsParse : (function (monthsShort) {
var i, _shortMonthsParse = [];
for (i = 0; i < 12; i++) {
_shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i');
}
return _shortMonthsParse;
}(monthsShort)),
longMonthsParse : (function (months) {
var i, _longMonthsParse = [];
for (i = 0; i < 12; i++) {
_longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i');
}
return _longMonthsParse;
}(months)),
weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),
weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),
weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),
longDateFormat : {
LT: 'H:mm',
LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
LLL : 'D. MMMM YYYY H:mm',
LLLL : 'dddd D. MMMM YYYY H:mm',
l : 'D. M. YYYY'
},
calendar : {
sameDay: '[dnes v] LT',
nextDay: '[zítra v] LT',
nextWeek: function () {
switch (this.day()) {
case 0:
return '[v neděli v] LT';
case 1:
case 2:
return '[v] dddd [v] LT';
case 3:
return '[ve středu v] LT';
case 4:
return '[ve čtvrtek v] LT';
case 5:
return '[v pátek v] LT';
case 6:
return '[v sobotu v] LT';
}
},
lastDay: '[včera v] LT',
lastWeek: function () {
switch (this.day()) {
case 0:
return '[minulou neděli v] LT';
case 1:
case 2:
return '[minulé] dddd [v] LT';
case 3:
return '[minulou středu v] LT';
case 4:
case 5:
return '[minulý] dddd [v] LT';
case 6:
return '[minulou sobotu v] LT';
}
},
sameElse: 'L'
},
relativeTime : {
future : 'za %s',
past : 'před %s',
s : translate,
m : translate,
mm : translate,
h : translate,
hh : translate,
d : translate,
dd : translate,
M : translate,
MM : translate,
y : translate,
yy : translate
},
ordinalParse : /\d{1,2}\./,
ordinal : '%d.',
week : {
dow : 1, // Monday is the first day of the week.
doy : 4 // The week that contains Jan 4th is the first week of the year.
}
});
return cs;
}));

View File

@@ -0,0 +1,63 @@
//! moment.js locale configuration
//! locale : Chuvash [cv]
//! author : Anatoly Mironov : https://github.com/mirontoli
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var cv = moment.defineLocale('cv', {
months : 'кӑрлач_нарӑс_пуш_акаай_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'),
monthsShort : 'кӑрар_пуш_акаай_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),
weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'),
weekdaysShort : 'вырун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),
weekdaysMin : р_тн_ыт_юн_кҫ_эр_шм'.split('_'),
longDateFormat : {
LT : 'HH:mm',
LTS : 'HH:mm:ss',
L : 'DD-MM-YYYY',
LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',
LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',
LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'
},
calendar : {
sameDay: '[Паян] LT [сехетре]',
nextDay: '[Ыран] LT [сехетре]',
lastDay: '[Ӗнер] LT [сехетре]',
nextWeek: '[Ҫитес] dddd LT [сехетре]',
lastWeek: '[Иртнӗ] dddd LT [сехетре]',
sameElse: 'L'
},
relativeTime : {
future : function (output) {
var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран';
return output + affix;
},
past : '%s каялла',
s : 'пӗр-ик ҫеккунт',
m : 'пӗр минут',
mm : '%d минут',
h : 'пӗр сехет',
hh : '%d сехет',
d : 'пӗр кун',
dd : '%d кун',
M : 'пӗр уйӑх',
MM : '%d уйӑх',
y : 'пӗр ҫул',
yy : '%d ҫул'
},
ordinalParse: /\d{1,2}-мӗш/,
ordinal : '%d-мӗш',
week : {
dow : 1, // Monday is the first day of the week.
doy : 7 // The week that contains Jan 1st is the first week of the year.
}
});
return cv;
}));

View File

@@ -0,0 +1,80 @@
//! moment.js locale configuration
//! locale : Welsh [cy]
//! author : Robert Allen
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var cy = moment.defineLocale('cy', {
months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),
monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),
weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),
weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),
weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),
weekdaysParseExact : true,
// time formats are the same as en-gb
longDateFormat: {
LT: 'HH:mm',
LTS : 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
LLL: 'D MMMM YYYY HH:mm',
LLLL: 'dddd, D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[Heddiw am] LT',
nextDay: '[Yfory am] LT',
nextWeek: 'dddd [am] LT',
lastDay: '[Ddoe am] LT',
lastWeek: 'dddd [diwethaf am] LT',
sameElse: 'L'
},
relativeTime: {
future: 'mewn %s',
past: '%s yn ôl',
s: 'ychydig eiliadau',
m: 'munud',
mm: '%d munud',
h: 'awr',
hh: '%d awr',
d: 'diwrnod',
dd: '%d diwrnod',
M: 'mis',
MM: '%d mis',
y: 'blwyddyn',
yy: '%d flynedd'
},
ordinalParse: /\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,
// traditional ordinal numbers above 31 are not commonly used in colloquial Welsh
ordinal: function (number) {
var b = number,
output = '',
lookup = [
'', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed
'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed
];
if (b > 20) {
if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {
output = 'fed'; // not 30ain, 70ain or 90ain
} else {
output = 'ain';
}
} else if (b > 0) {
output = lookup[b];
}
return number + output;
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 4 // The week that contains Jan 4th is the first week of the year.
}
});
return cy;
}));

View File

@@ -0,0 +1,60 @@
//! moment.js locale configuration
//! locale : Danish [da]
//! author : Ulrik Nielsen : https://github.com/mrbase
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var da = moment.defineLocale('da', {
months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),
monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),
weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),
weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),
weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
longDateFormat : {
LT : 'HH:mm',
LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D. MMMM YYYY',
LLL : 'D. MMMM YYYY HH:mm',
LLLL : 'dddd [d.] D. MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[I dag kl.] LT',
nextDay : '[I morgen kl.] LT',
nextWeek : 'dddd [kl.] LT',
lastDay : '[I går kl.] LT',
lastWeek : '[sidste] dddd [kl] LT',
sameElse : 'L'
},
relativeTime : {
future : 'om %s',
past : '%s siden',
s : 'få sekunder',
m : 'et minut',
mm : '%d minutter',
h : 'en time',
hh : '%d timer',
d : 'en dag',
dd : '%d dage',
M : 'en måned',
MM : '%d måneder',
y : 'et år',
yy : '%d år'
},
ordinalParse: /\d{1,2}\./,
ordinal : '%d.',
week : {
dow : 1, // Monday is the first day of the week.
doy : 4 // The week that contains Jan 4th is the first week of the year.
}
});
return da;
}));

View File

@@ -0,0 +1,79 @@
//! moment.js locale configuration
//! locale : German (Austria) [de-at]
//! author : lluchs : https://github.com/lluchs
//! author: Menelion Elensúle: https://github.com/Oire
//! author : Martin Groller : https://github.com/MadMG
//! author : Mikolaj Dadela : https://github.com/mik01aj
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
function processRelativeTime(number, withoutSuffix, key, isFuture) {
var format = {
'm': ['eine Minute', 'einer Minute'],
'h': ['eine Stunde', 'einer Stunde'],
'd': ['ein Tag', 'einem Tag'],
'dd': [number + ' Tage', number + ' Tagen'],
'M': ['ein Monat', 'einem Monat'],
'MM': [number + ' Monate', number + ' Monaten'],
'y': ['ein Jahr', 'einem Jahr'],
'yy': [number + ' Jahre', number + ' Jahren']
};
return withoutSuffix ? format[key][0] : format[key][1];
}
var de_at = moment.defineLocale('de-at', {
months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),
monthsParseExact : true,
weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),
weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
weekdaysParseExact : true,
longDateFormat : {
LT: 'HH:mm',
LTS: 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
LLL : 'D. MMMM YYYY HH:mm',
LLLL : 'dddd, D. MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[heute um] LT [Uhr]',
sameElse: 'L',
nextDay: '[morgen um] LT [Uhr]',
nextWeek: 'dddd [um] LT [Uhr]',
lastDay: '[gestern um] LT [Uhr]',
lastWeek: '[letzten] dddd [um] LT [Uhr]'
},
relativeTime : {
future : 'in %s',
past : 'vor %s',
s : 'ein paar Sekunden',
m : processRelativeTime,
mm : '%d Minuten',
h : processRelativeTime,
hh : '%d Stunden',
d : processRelativeTime,
dd : processRelativeTime,
M : processRelativeTime,
MM : processRelativeTime,
y : processRelativeTime,
yy : processRelativeTime
},
ordinalParse: /\d{1,2}\./,
ordinal : '%d.',
week : {
dow : 1, // Monday is the first day of the week.
doy : 4 // The week that contains Jan 4th is the first week of the year.
}
});
return de_at;
}));

View File

@@ -0,0 +1,78 @@
//! moment.js locale configuration
//! locale : German [de]
//! author : lluchs : https://github.com/lluchs
//! author: Menelion Elensúle: https://github.com/Oire
//! author : Mikolaj Dadela : https://github.com/mik01aj
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
function processRelativeTime(number, withoutSuffix, key, isFuture) {
var format = {
'm': ['eine Minute', 'einer Minute'],
'h': ['eine Stunde', 'einer Stunde'],
'd': ['ein Tag', 'einem Tag'],
'dd': [number + ' Tage', number + ' Tagen'],
'M': ['ein Monat', 'einem Monat'],
'MM': [number + ' Monate', number + ' Monaten'],
'y': ['ein Jahr', 'einem Jahr'],
'yy': [number + ' Jahre', number + ' Jahren']
};
return withoutSuffix ? format[key][0] : format[key][1];
}
var de = moment.defineLocale('de', {
months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),
monthsParseExact : true,
weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),
weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
weekdaysParseExact : true,
longDateFormat : {
LT: 'HH:mm',
LTS: 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
LLL : 'D. MMMM YYYY HH:mm',
LLLL : 'dddd, D. MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[heute um] LT [Uhr]',
sameElse: 'L',
nextDay: '[morgen um] LT [Uhr]',
nextWeek: 'dddd [um] LT [Uhr]',
lastDay: '[gestern um] LT [Uhr]',
lastWeek: '[letzten] dddd [um] LT [Uhr]'
},
relativeTime : {
future : 'in %s',
past : 'vor %s',
s : 'ein paar Sekunden',
m : processRelativeTime,
mm : '%d Minuten',
h : processRelativeTime,
hh : '%d Stunden',
d : processRelativeTime,
dd : processRelativeTime,
M : processRelativeTime,
MM : processRelativeTime,
y : processRelativeTime,
yy : processRelativeTime
},
ordinalParse: /\d{1,2}\./,
ordinal : '%d.',
week : {
dow : 1, // Monday is the first day of the week.
doy : 4 // The week that contains Jan 4th is the first week of the year.
}
});
return de;
}));

View File

@@ -0,0 +1,99 @@
//! moment.js locale configuration
//! locale : Maldivian [dv]
//! author : Jawish Hameed : https://github.com/jawish
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var months = [
'ޖެނުއަރީ',
'ފެބްރުއަރީ',
'މާރިޗު',
'އޭޕްރީލު',
'މޭ',
'ޖޫން',
'ޖުލައި',
'އޯގަސްޓު',
'ސެޕްޓެމްބަރު',
'އޮކްޓޯބަރު',
'ނޮވެމްބަރު',
'ޑިސެމްބަރު'
], weekdays = [
'އާދިއްތަ',
'ހޯމަ',
'އަންގާރަ',
'ބުދަ',
'ބުރާސްފަތި',
'ހުކުރު',
'ހޮނިހިރު'
];
var dv = moment.defineLocale('dv', {
months : months,
monthsShort : months,
weekdays : weekdays,
weekdaysShort : weekdays,
weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'),
longDateFormat : {
LT : 'HH:mm',
LTS : 'HH:mm:ss',
L : 'D/M/YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY HH:mm',
LLLL : 'dddd D MMMM YYYY HH:mm'
},
meridiemParse: /މކ|މފ/,
isPM : function (input) {
return 'މފ' === input;
},
meridiem : function (hour, minute, isLower) {
if (hour < 12) {
return 'މކ';
} else {
return 'މފ';
}
},
calendar : {
sameDay : '[މިއަދު] LT',
nextDay : '[މާދަމާ] LT',
nextWeek : 'dddd LT',
lastDay : '[އިއްޔެ] LT',
lastWeek : '[ފާއިތުވި] dddd LT',
sameElse : 'L'
},
relativeTime : {
future : 'ތެރޭގައި %s',
past : 'ކުރިން %s',
s : 'ސިކުންތުކޮޅެއް',
m : 'މިނިޓެއް',
mm : 'މިނިޓު %d',
h : 'ގަޑިއިރެއް',
hh : 'ގަޑިއިރު %d',
d : 'ދުވަހެއް',
dd : 'ދުވަސް %d',
M : 'މަހެއް',
MM : 'މަސް %d',
y : 'އަހަރެއް',
yy : 'އަހަރު %d'
},
preparse: function (string) {
return string.replace(/،/g, ',');
},
postformat: function (string) {
return string.replace(/,/g, '،');
},
week : {
dow : 7, // Sunday is the first day of the week.
doy : 12 // The week that contains Jan 1st is the first week of the year.
}
});
return dv;
}));

View File

@@ -0,0 +1,98 @@
//! moment.js locale configuration
//! locale : Greek [el]
//! author : Aggelos Karalias : https://github.com/mehiel
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
function isFunction(input) {
return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
}
var el = moment.defineLocale('el', {
monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),
monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),
months : function (momentToFormat, format) {
if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'
return this._monthsGenitiveEl[momentToFormat.month()];
} else {
return this._monthsNominativeEl[momentToFormat.month()];
}
},
monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),
weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),
weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παραβ'.split('_'),
weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Παα'.split('_'),
meridiem : function (hours, minutes, isLower) {
if (hours > 11) {
return isLower ? 'μμ' : 'ΜΜ';
} else {
return isLower ? 'πμ' : 'ΠΜ';
}
},
isPM : function (input) {
return ((input + '').toLowerCase()[0] === 'μ');
},
meridiemParse : /[ΠΜ]\.?Μ?\.?/i,
longDateFormat : {
LT : 'h:mm A',
LTS : 'h:mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY h:mm A',
LLLL : 'dddd, D MMMM YYYY h:mm A'
},
calendarEl : {
sameDay : '[Σήμερα {}] LT',
nextDay : '[Αύριο {}] LT',
nextWeek : 'dddd [{}] LT',
lastDay : '[Χθες {}] LT',
lastWeek : function () {
switch (this.day()) {
case 6:
return '[το προηγούμενο] dddd [{}] LT';
default:
return '[την προηγούμενη] dddd [{}] LT';
}
},
sameElse : 'L'
},
calendar : function (key, mom) {
var output = this._calendarEl[key],
hours = mom && mom.hours();
if (isFunction(output)) {
output = output.apply(mom);
}
return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));
},
relativeTime : {
future : 'σε %s',
past : '%s πριν',
s : 'λίγα δευτερόλεπτα',
m : 'ένα λεπτό',
mm : '%d λεπτά',
h : 'μία ώρα',
hh : '%d ώρες',
d : 'μία μέρα',
dd : '%d μέρες',
M : 'ένας μήνας',
MM : '%d μήνες',
y : 'ένας χρόνος',
yy : '%d χρόνια'
},
ordinalParse: /\d{1,2}η/,
ordinal: '%dη',
week : {
dow : 1, // Monday is the first day of the week.
doy : 4 // The week that contains Jan 4st is the first week of the year.
}
});
return el;
}));

View File

@@ -0,0 +1,66 @@
//! moment.js locale configuration
//! locale : English (Australia) [en-au]
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var en_au = moment.defineLocale('en-au', {
months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
longDateFormat : {
LT : 'h:mm A',
LTS : 'h:mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY h:mm A',
LLLL : 'dddd, D MMMM YYYY h:mm A'
},
calendar : {
sameDay : '[Today at] LT',
nextDay : '[Tomorrow at] LT',
nextWeek : 'dddd [at] LT',
lastDay : '[Yesterday at] LT',
lastWeek : '[Last] dddd [at] LT',
sameElse : 'L'
},
relativeTime : {
future : 'in %s',
past : '%s ago',
s : 'a few seconds',
m : 'a minute',
mm : '%d minutes',
h : 'an hour',
hh : '%d hours',
d : 'a day',
dd : '%d days',
M : 'a month',
MM : '%d months',
y : 'a year',
yy : '%d years'
},
ordinalParse: /\d{1,2}(st|nd|rd|th)/,
ordinal : function (number) {
var b = number % 10,
output = (~~(number % 100 / 10) === 1) ? 'th' :
(b === 1) ? 'st' :
(b === 2) ? 'nd' :
(b === 3) ? 'rd' : 'th';
return number + output;
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 4 // The week that contains Jan 4th is the first week of the year.
}
});
return en_au;
}));

View File

@@ -0,0 +1,63 @@
//! moment.js locale configuration
//! locale : English (Canada) [en-ca]
//! author : Jonathan Abourbih : https://github.com/jonbca
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var en_ca = moment.defineLocale('en-ca', {
months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
longDateFormat : {
LT : 'h:mm A',
LTS : 'h:mm:ss A',
L : 'YYYY-MM-DD',
LL : 'MMMM D, YYYY',
LLL : 'MMMM D, YYYY h:mm A',
LLLL : 'dddd, MMMM D, YYYY h:mm A'
},
calendar : {
sameDay : '[Today at] LT',
nextDay : '[Tomorrow at] LT',
nextWeek : 'dddd [at] LT',
lastDay : '[Yesterday at] LT',
lastWeek : '[Last] dddd [at] LT',
sameElse : 'L'
},
relativeTime : {
future : 'in %s',
past : '%s ago',
s : 'a few seconds',
m : 'a minute',
mm : '%d minutes',
h : 'an hour',
hh : '%d hours',
d : 'a day',
dd : '%d days',
M : 'a month',
MM : '%d months',
y : 'a year',
yy : '%d years'
},
ordinalParse: /\d{1,2}(st|nd|rd|th)/,
ordinal : function (number) {
var b = number % 10,
output = (~~(number % 100 / 10) === 1) ? 'th' :
(b === 1) ? 'st' :
(b === 2) ? 'nd' :
(b === 3) ? 'rd' : 'th';
return number + output;
}
});
return en_ca;
}));

View File

@@ -0,0 +1,67 @@
//! moment.js locale configuration
//! locale : English (United Kingdom) [en-gb]
//! author : Chris Gedrim : https://github.com/chrisgedrim
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var en_gb = moment.defineLocale('en-gb', {
months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
longDateFormat : {
LT : 'HH:mm',
LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY HH:mm',
LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[Today at] LT',
nextDay : '[Tomorrow at] LT',
nextWeek : 'dddd [at] LT',
lastDay : '[Yesterday at] LT',
lastWeek : '[Last] dddd [at] LT',
sameElse : 'L'
},
relativeTime : {
future : 'in %s',
past : '%s ago',
s : 'a few seconds',
m : 'a minute',
mm : '%d minutes',
h : 'an hour',
hh : '%d hours',
d : 'a day',
dd : '%d days',
M : 'a month',
MM : '%d months',
y : 'a year',
yy : '%d years'
},
ordinalParse: /\d{1,2}(st|nd|rd|th)/,
ordinal : function (number) {
var b = number % 10,
output = (~~(number % 100 / 10) === 1) ? 'th' :
(b === 1) ? 'st' :
(b === 2) ? 'nd' :
(b === 3) ? 'rd' : 'th';
return number + output;
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 4 // The week that contains Jan 4th is the first week of the year.
}
});
return en_gb;
}));

View File

@@ -0,0 +1,67 @@
//! moment.js locale configuration
//! locale : English (Ireland) [en-ie]
//! author : Chris Cartlidge : https://github.com/chriscartlidge
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var en_ie = moment.defineLocale('en-ie', {
months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
longDateFormat : {
LT : 'HH:mm',
LTS : 'HH:mm:ss',
L : 'DD-MM-YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY HH:mm',
LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[Today at] LT',
nextDay : '[Tomorrow at] LT',
nextWeek : 'dddd [at] LT',
lastDay : '[Yesterday at] LT',
lastWeek : '[Last] dddd [at] LT',
sameElse : 'L'
},
relativeTime : {
future : 'in %s',
past : '%s ago',
s : 'a few seconds',
m : 'a minute',
mm : '%d minutes',
h : 'an hour',
hh : '%d hours',
d : 'a day',
dd : '%d days',
M : 'a month',
MM : '%d months',
y : 'a year',
yy : '%d years'
},
ordinalParse: /\d{1,2}(st|nd|rd|th)/,
ordinal : function (number) {
var b = number % 10,
output = (~~(number % 100 / 10) === 1) ? 'th' :
(b === 1) ? 'st' :
(b === 2) ? 'nd' :
(b === 3) ? 'rd' : 'th';
return number + output;
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 4 // The week that contains Jan 4th is the first week of the year.
}
});
return en_ie;
}));

View File

@@ -0,0 +1,66 @@
//! moment.js locale configuration
//! locale : English (New Zealand) [en-nz]
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var en_nz = moment.defineLocale('en-nz', {
months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
longDateFormat : {
LT : 'h:mm A',
LTS : 'h:mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY h:mm A',
LLLL : 'dddd, D MMMM YYYY h:mm A'
},
calendar : {
sameDay : '[Today at] LT',
nextDay : '[Tomorrow at] LT',
nextWeek : 'dddd [at] LT',
lastDay : '[Yesterday at] LT',
lastWeek : '[Last] dddd [at] LT',
sameElse : 'L'
},
relativeTime : {
future : 'in %s',
past : '%s ago',
s : 'a few seconds',
m : 'a minute',
mm : '%d minutes',
h : 'an hour',
hh : '%d hours',
d : 'a day',
dd : '%d days',
M : 'a month',
MM : '%d months',
y : 'a year',
yy : '%d years'
},
ordinalParse: /\d{1,2}(st|nd|rd|th)/,
ordinal : function (number) {
var b = number % 10,
output = (~~(number % 100 / 10) === 1) ? 'th' :
(b === 1) ? 'st' :
(b === 2) ? 'nd' :
(b === 3) ? 'rd' : 'th';
return number + output;
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 4 // The week that contains Jan 4th is the first week of the year.
}
});
return en_nz;
}));

Some files were not shown because too many files have changed in this diff Show More