0
0
Fork 0
mirror of https://gitlab.com/Oreolek/salet-module.git synced 2024-06-28 21:05:03 +03:00

Merge branch '2.0-dev'

This commit is contained in:
Alexander Yakovlev 2017-11-09 17:24:16 +07:00
commit 6509b31955
12 changed files with 531 additions and 169 deletions

View file

@ -6,6 +6,7 @@ sources = [
'utils.coffee'
'view.coffee'
'unit.coffee'
'container.coffee'
'character.coffee'
'room.coffee'
'localize.coffee'
@ -17,7 +18,7 @@ for source in sources
sourcestring += 'src/'+source+' '
task 'watch', 'Watch source files and build changes', ->
watch = spawn "coffee", ['-c', '-w', '-m', '--no-header', '-j', 'lib/index.js', sourcestring]
watch = spawn "node_modules/coffeescript/bin/coffee", ['-c', '-w', '-m', '--no-header', '-j', 'lib/index.js', sourcestring]
watch.stdout.on 'data', (data) -> console.log data.toString().trim()
task 'compile', 'Compile all CoffeeScript files', ->
@ -27,7 +28,7 @@ task 'compile', 'Compile all CoffeeScript files', ->
# run coffee-script compile
exec "cat #{sourcestring} > lib/index.coffee"
exec "coffee --compile --map --no-header lib/index.coffee", (err, stdout, stderr) ->
exec "node_modules/coffeescript/bin/coffee --compile --map --no-header lib/index.coffee", (err, stdout, stderr) ->
if err
util.log err
process.exit 1 # abort npm packaging

View file

@ -1,4 +1,4 @@
Copyright (c) 2016 Alexander Yakovlev, https://oreolek.ru/
Copyright (c) 2016-2017 Alexander Yakovlev, https://oreolek.ru/
Raconteur is copyright (c) 2015 Bruno Dias, released under the similar license terms.
Undum is copyright (c) 2009-2015 Ian Millington, released under the similar license terms.

View file

@ -2,12 +2,19 @@
"name": "salet",
"version": "1.8.6",
"description": "A general client-side framework for cybertext interactive fiction games.",
"keywords": ["ifiction", "interactive fiction", "games", "coffee-script", "text", "menu"],
"keywords": [
"ifiction",
"interactive fiction",
"games",
"coffee-script",
"text",
"menu"
],
"homepage": "https://salet.su",
"bugs": {
"url" : "https://gitlab.com/oreolek/salet-module/issues"
"url": "https://gitlab.com/oreolek/salet-module/issues"
},
"license" : "MIT",
"license": "MIT",
"dependencies": {},
"private": false,
"author": {
@ -16,7 +23,7 @@
"url": "https://oreolek.ru"
},
"devDependencies": {
"coffee-script": "*"
"coffeescript": "^2.0.0"
},
"main": "lib/index.min.js",
"types": "./typings/salet/index.d.ts",

View file

@ -1,32 +1,6 @@
class Character
class Character extends Container
constructor: (spec) ->
@inventory = []
@take = (thing) =>
@inventory.push thing
@drop = (thing) =>
for i in @inventory
if i.name == thing
@inventory.remove(i)
return true
return false
@has = (thing) =>
for i in @inventory
if i.name == thing
return true
return false
@listinv = (thing) =>
for i in @inventory
if i.name == thing
return invlink(i.display.fcall(i), i.name)
@inv = (thing) =>
for i in @inventory
if i.name == thing
return i.inv.fcall(i)
super spec
for index, value of spec
this[index] = value

35
src/container.coffee Normal file
View file

@ -0,0 +1,35 @@
# A container of elements.
class Container
constructor: (spec) ->
@inventory = []
if spec?
if spec.inventory?
@inventory = spec.inventory
if spec.units?
@inventory = spec.units
@take = (thing) =>
if @name?
thing.location = @name
@inventory.push thing
@drop = (thing) =>
for i in @inventory
if i.name == thing
i.location = null
@inventory.remove(i)
return true
return false
@has = (thing) =>
for i in @inventory
if i.name == thing
return true
return false
@inv = (thing) =>
for i in @inventory
if i.name == thing
return i.inv.fcall(i)
return this

View file

@ -19,6 +19,11 @@ class Localize
else
@strings[lang] = strings
# Check if the translation exists.
# @return bool
exists: (index) ->
return @strings[@lang][index]?
localize: (message, languageCode = @lang) ->
if @strings[languageCode]?
localized = @strings[languageCode][message]

View file

@ -1,5 +1,6 @@
class SaletRoom
class SaletRoom extends Container
constructor: (spec) ->
super spec
@visited = 0
# unique room ID, mandatory to edit
@ -7,7 +8,6 @@ class SaletRoom
# room title, used in waypoint generation, see @ways
@title = "Room"
@units = []
@canView = true
@canChoose = true
@priority = 1
@ -23,24 +23,6 @@ class SaletRoom
@dsc = false # room description
@extendSection = false
@clear = true # clear the screen on entering the room?
###
I call SaletRoom.exit every time the player exits to another room.
Unlike @after this gets called after the section is closed.
It's a styling difference.
###
@exit = (to) =>
return true
###
I call SaletRoom.enter every time the player enters this room but before the section is opened.
Unlike @before this gets called before the current section is opened.
It's a styling difference.
The upstream Undum version does not allow you to redefine @enter function easily but allows custom @exit one.
It was renamed as @entering to achieve API consistency.
###
@enter = (from) =>
return true
###
Salet calls SaletRoom.entering every time a situation is entered, and
@ -50,6 +32,11 @@ class SaletRoom
If f == this.name (we're in the same location) the `before` and `after` callbacks are ignored.
###
@entering = (f, force = false) =>
$(document).trigger("room_transition", {
"from": @name
"to": f
"forced": force
})
if (
f != @name and
salet.rooms[f]? and
@ -64,6 +51,7 @@ class SaletRoom
return salet.doTransitionTo(f, true)
if @clear and f?
$(document).trigger("room_#{@name}_clear_content")
salet.view.clearContent()
if salet.rooms[f]? and not @clear
@ -71,14 +59,29 @@ class SaletRoom
salet.view.removeTransient(f)
else
salet.view.removeTransient()
salet.view.clearChoices()
if f != @name and salet.rooms[f]?
$(document).trigger("room_exit", {
"from": f
"to": @name
})
$(document).trigger("room_#{f}_exit", {
"to": @name
})
@visited++
if salet.rooms[f].exit?
salet.rooms[f].exit @name
if @enter
@enter f
$(document).trigger("room_enter", {
"from": f
"to": @name
})
$(document).trigger("room_#{@name}_enter", {
"from": f
})
if @enter?
@enter(f)
if not @extendSection
classes = if @classes then ' ' + @classes.join(' ') else ''
@ -95,14 +98,18 @@ class SaletRoom
if f != @name and @after?
salet.view.write markdown(@after.fcall(this, f))
if @beforeChoices?
@beforeChoices.fcall(this, f)
$(document).trigger("room_#{@name}_before_choices")
if @beforeChoices
salet.view.write markdown(@beforeChoices.fcall(this, f))
if @choices
if @choices and @choices != ""
salet.view.writeChoices(salet.getSituationIdChoices(@choices, @maxChoices))
else
salet.view.writeVerbs()
if @afterChoices?
@afterChoices.fcall(this, f)
$(document).trigger("room_#{@name}_after_choices")
if @afterChoices
salet.view.write markdown(@afterChoices.fcall(this, f))
if salet.autosave and @canSave
salet.saveGame()
@ -124,7 +131,7 @@ class SaletRoom
retval += markdown(dsc)
unitDescriptions = []
for thing in @units
for thing in @inventory
if thing.name and typeof(thing.look) == "function" and thing.look(f)
unitDescriptions.push ({
order: thing.order,
@ -140,20 +147,6 @@ class SaletRoom
return markdown(retval)
###
Places a unit in this room.
###
@take = (thing) =>
thing.location = @name
@units.push(thing)
@drop = (name) =>
for thing in @units
if thing.name == name
@units.splice(@units.indexOf(thing), 1)
thing.location = null
return @units
###
Unit action. A function or a string which comes when you click on a link in unit description.
You could interpret this as an EXAMINE verb or USE one, it's your call.
@ -162,7 +155,7 @@ class SaletRoom
if (link = action.match(/^_(act|cycle|inv)_(.+)$/)) #unit action
if link[1] == "inv"
return salet.view.write salet.character.inv(link[2])
for thing in @units
for thing in @inventory
if thing.name == link[2]
if link[1] == "act"
# If it's takeable, the player can take this unit.
@ -220,7 +213,7 @@ class SaletRoom
@link = (name) =>
if salet.rooms[name]
@ways.push(name)
# Short way of saying "this room is connected to that room and vice versa"
@bilink = (name) =>
another = salet.rooms[name]

View file

@ -24,58 +24,12 @@ class Salet
# The unique id of the starting room.
@start = "start"
# Regular expression to catch every link action.
# Salet's default is a general URL-safe expression.
@linkRe = /^([0-9A-Za-z_-]+|\.)(\/([0-9A-Za-z_-]+))?$/
###
This function is called at the start of the game. It is
normally overridden to provide initial character creation
(setting initial quality values, setting the
character-text. This is optional, however, as set-up
processing could also be done by the first room's
enter function.
# This variable is set to false before triggering "before_action" event.
# If any of the user-defined triggers set it to true,
# Salet won't execute the action.
###
@init = () ->
###
This function is called before entering any new
room. It is called before the corresponding room
has its `enter` method called.
###
@enter = (oldSituationId, newSituationId) ->
###
Hook for when the room has already been carried out
and printed.
###
@afterEnter = (oldSituationId, newSituationId) ->
###
This function is called before carrying out any action in
any room. It is called before the corresponding
room has its `act` method called.
If the function returns true, then it is indicating that it
has consumed the action, and the action will not be passed
on to the room. Note that this is the only one of
these global handlers that can consume the event.
###
@beforeAction = (roomId, actionId) ->
###
This function is called after carrying out any action in
any room. It is called after the corresponding
room has its `act` method called.
###
@afterAction = (roomId, actionId) ->
###
This function is called after leaving any room. It is
called after the corresponding room has its `exit`
method called.
###
@exit = (oldSituationId, newSituationId) ->
@actionConsumed = false
###
Returns a list of room ids to choose from, given a set of
@ -243,7 +197,7 @@ class Salet
each one, and processLink manages this.
###
@processOneLink = (code) ->
match = code.match(@linkRe)
match = code.match(@view.linkRe)
if not match
console.error "link_not_valid".l()
console.error code
@ -264,17 +218,20 @@ class Salet
if (action)
room = @getCurrentRoom()
if room
consumed = false
@actionConsumed = false
if @beforeAction
# Try the global act handler
consumed = @beforeAction(room, action)
$(document).trigger("before_action", {
"room": room
"action": action
})
if consumed != true
if @actionConsumed == false
room.act(action)
if @afterAction
@afterAction(room, action)
$(document).trigger("after_action", {
"room": room
"action": action
})
@view.append timerResponse
@ -285,7 +242,7 @@ class Salet
# don't save any actions in the room we can't save in
# and remember that the action of entering the start room is always saved
match = code.match(@linkRe)
match = code.match(@view.linkRe)
room = match[1]
if room
if room == '.'
@ -297,11 +254,34 @@ class Salet
# don't save
return @processLink(code)
@progress.sequence.push({link:code, when:@time})
@progress.sequence.push({
link:code,
when:@time
})
if @getRoom(code)? # if it's a room
@progress.path.push(code)
@processLink(code)
# This gets called when the user clicks a link to carry out a verb on a unit.
@processVerb = (code) ->
now = (new Date()).getTime() * 0.001
@time = now - @startTime
# don't save any actions in the room we can't save in
# and remember that the action of entering the start room is always saved
match = code.match(@view.verbRe)
verb = match[1]
unit = match[2]
room = @getCurrentRoom()
assert(room, "unknown_room".l({id:room}))
if room.canSave
@progress.sequence.push({
link:code,
when:@time
})
# TODO: find a unit in current room, execute its "verb" method
# Go back N rooms. It's not an UNDO.
# Also, steps = 1 is the current room
@goBack = (steps = 2) ->
@ -320,21 +300,14 @@ class Salet
assert(newRoom, "unknown_room".l({id:newRoomId}))
# We might not have an old situation if this is the start of the game.
if (oldRoom and @exit)
@exit(oldRoomId, newRoomId, force)
@current = newRoomId
# A global callback before entering
if (@enter)
@enter(oldRoomId, newRoomId, force)
newRoom.entering(oldRoomId, force)
# additional hook for when the situation text has already been printed
if (@afterEnter)
@afterEnter(oldRoomId, newRoomId, force)
$(document).trigger("room_#{newRoomId}_after_enter", {
"from": oldRoomId,
"force": force
})
###
Erases the character in local storage. This is permanent!
@ -366,6 +339,11 @@ class Salet
now = (new Date()).getTime() * 0.001
@progress.saveTime = now - @startTime
$(document).trigger("saveGame", {
"id": @getSaveId()
"progress": @progress
})
# Save the game.
localStorage.setItem(@getSaveId(), JSON.stringify({
progress: @progress
@ -385,13 +363,17 @@ class Salet
@character = new Character()
@rnd = new Random(@progress.seed)
$(document).trigger("loadGame", {
"progress": @progress
})
# Start the game now
@init()
$(document).trigger("init")
# Run through all the player's history.
@interactive = false
for step in @progress.sequence
# The action must be done at the recorded time.
@time = step.when
@ -414,6 +396,7 @@ class Salet
return saveFile
@beginGame = () ->
@view.init()
@view.fixClicks()
# Handle storage.
@ -436,12 +419,12 @@ class Salet
# Start the game
@startTime = new Date().getTime() * 0.001
@init()
$(document).trigger("init")
# Do the first state.
@doTransitionTo(@start)
@getRoom = (name) ->
@getRoom = (name) ->
if @rooms[name]?
return @rooms[name]
return undefined
@ -457,17 +440,14 @@ class Salet
@timers = {}
# Adds a one-time timer <name> that will fire after <steps> clicks
# with <action>.
# Adds a timer <name> that will fire after <steps> clicks
# @param name string timer ID
# @param repeat boolean should it repeat every <step> steps or not
# @param action string or function code to call
# @param step integer number of steps
@addTimer = (name, action, repeatable = false, step = 1) ->
@addTimer = (name, repeatable = false, step = 1) ->
@timers[name] = {
step: step
repeatable: repeatable
action: action
set: @progress.sequence.length
}
return @timers
@ -484,15 +464,20 @@ class Salet
response = ""
for tname, timer of @timers
if ((@progress.sequence.length - timer.set) == timer.step)
response += "\n\n"+timer.action.fcall(this)
$(document).trigger("timer_#{tname}")
if !timer.repeatable
@dropTimer(tname)
return response
# An object in the format of:
# "index": "text",
# i.e. "examine": "Examine"
# Salet enters verb mode if @choices is empty and @verbs is not.
@verbs = {}
for index, value of spec
this[index] = value
return this
window.salet = new Salet()
salet.view.init()

View file

@ -15,9 +15,6 @@ assert = (assertion, msg) -> console.assert assertion, msg
way_to = (content, ref) ->
return "<a href='#{ref}' class='way' id='waylink-#{ref}'>#{content}</a>"
invlink = (content, ref) ->
return "<a href='./_inv_#{ref}' class='once'>#{content.fcall()}</a>"
Array::remove = (e) -> @[t..t] = [] if (t = @indexOf(e)) > -1
addClass = (element, className) ->
@ -36,3 +33,13 @@ parsedsc = (text, name) ->
window.unitname = undefined
return unitlink(p1, name)
return text
# Print a link to the thing, if the container has it
window.listinv = (thing, container = undefined) =>
container ?= salet.character.inventory
for i in container
if i.name == thing
return invlink(i.display.fcall(i), i.name)
invlink = (content, ref) ->
return "<a href='./_inv_#{ref}' class='once'>#{content.fcall()}</a>"

View file

@ -15,18 +15,28 @@ There is only one instance of this class, and it's stored as `salet.view`.
class SaletView
constructor: (spec) ->
@init = () ->
$(document).trigger("viewinit")
$("#page").on("click", "a", (event) ->
event.preventDefault()
a = $(this)
href = a.attr('href')
if a.hasClass("once") || href.match(/[?&]once[=&]?/)
salet.view.clearLinks(href)
if href.match(salet.linkRe)
salet.processClick(href)
if href.match(salet.view.linkRe) != null
event.preventDefault()
return salet.processClick(href)
else if href.match(salet.view.verbRe) != null
event.preventDefault()
return salet.processVerb(href)
)
$("#load").on("click", "a", (event) ->
window.location.reload()
)
$(document).on("click", "#verbs li", () ->
verb = $(this).data("verb")
for unitname, unit of salet.here().units
if unit[verb]?
@writeVerbAction(verb, unitname, text)
)
if (@hasLocalStorage())
$(document).on("click", "#erase", (event) ->
event.preventDefault()
@ -36,6 +46,18 @@ class SaletView
event.preventDefault()
return salet.saveGame()
)
# Regular expression to catch every link action.
# Salet's default is a general URL-safe expression.
@linkRe = /^([0-9A-Za-z_-]+|\.)(\/([0-9A-Za-z_-]+))?$/
# Regular expression to catch every verb action.
@verbRe = /^verb\_(\w+)\_(\w+)$/
# Add a verb action to the list of verb actions
@writeVerbAction = (verb, unitname, text) ->
$("#actions").append("<li><a href='verb_#{verb}_#{unitname}'>#{text}</a></li>")
@disableSaving = () ->
$("#save").addClass('disabled')
@enableSaving = () ->
@ -69,6 +91,7 @@ class SaletView
but the element itself remains, ready to be filled again using @write.
###
@clearContent = (elementSelector = "#content") ->
$(document).trigger("clear_content", elementSelector)
if (elementSelector == "#content") # empty the intro with the content
intro = document.getElementById("intro")
if intro?
@ -140,6 +163,11 @@ class SaletView
a.replaceWith($("<span>").addClass("ex_link").html(a.html()))
return true
@clearChoices = () ->
choices = document.querySelector("#choices")
if choices?
choices.innerHTML = ""
###
Given a list of room ids, this outputs a standard option
block with the room choices in the given order.
@ -177,7 +205,16 @@ class SaletView
$a.html(optionText)
$option.html($a)
$options.append($option)
@write($options)
# if there is a designated block for this, print choices in the block
if ($("#choices").length == 1)
@replace($options, "#choices")
else
@write($options)
@writeVerbs = () ->
$("#verbs").html("")
for verb, text of salet.verbs
$("#verbs").append("<li data-verb='#{verb}'>#{text}</li>")
# Marks all links as old. This gets called in a `processLink` function.
@mark_all_links_old = () ->
@ -286,6 +323,7 @@ class SaletView
@showBlock(".ways #ways_hint")
else
@hideBlock(".ways #ways_hint", false)
@cycleLink = (content) ->
return "<a href='./_replacer_cyclewriter' class='cycle' id='cyclewriter'>#{content}</a>"

View file

@ -49,7 +49,7 @@ $(document).ready(function() {
salet.character.take(lamp);
assert.equal(salet.character.has("lamp"), true, "The character has the lamp now");
assert.equal(salet.character.inv("lamp"), "that's a lamp", "The lamp has an inventory action");
assert.ok(salet.character.listinv("lamp").match("lamp description"), "The lamp has a description");
assert.ok(listinv("lamp").match("lamp description"), "The lamp has a description");
salet.character.drop("lamp");
assert.equal(salet.character.has("lamp"), false, "The character has no lamp again");
return;

317
yarn.lock Normal file
View file

@ -0,0 +1,317 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
babel-code-frame@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
dependencies:
chalk "^1.1.3"
esutils "^2.0.2"
js-tokens "^3.0.2"
babel-core@^6, babel-core@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8"
dependencies:
babel-code-frame "^6.26.0"
babel-generator "^6.26.0"
babel-helpers "^6.24.1"
babel-messages "^6.23.0"
babel-register "^6.26.0"
babel-runtime "^6.26.0"
babel-template "^6.26.0"
babel-traverse "^6.26.0"
babel-types "^6.26.0"
babylon "^6.18.0"
convert-source-map "^1.5.0"
debug "^2.6.8"
json5 "^0.5.1"
lodash "^4.17.4"
minimatch "^3.0.4"
path-is-absolute "^1.0.1"
private "^0.1.7"
slash "^1.0.0"
source-map "^0.5.6"
babel-generator@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5"
dependencies:
babel-messages "^6.23.0"
babel-runtime "^6.26.0"
babel-types "^6.26.0"
detect-indent "^4.0.0"
jsesc "^1.3.0"
lodash "^4.17.4"
source-map "^0.5.6"
trim-right "^1.0.1"
babel-helpers@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2"
dependencies:
babel-runtime "^6.22.0"
babel-template "^6.24.1"
babel-messages@^6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
dependencies:
babel-runtime "^6.22.0"
babel-register@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"
dependencies:
babel-core "^6.26.0"
babel-runtime "^6.26.0"
core-js "^2.5.0"
home-or-tmp "^2.0.0"
lodash "^4.17.4"
mkdirp "^0.5.1"
source-map-support "^0.4.15"
babel-runtime@^6.22.0, babel-runtime@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
dependencies:
core-js "^2.4.0"
regenerator-runtime "^0.11.0"
babel-template@^6.24.1, babel-template@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02"
dependencies:
babel-runtime "^6.26.0"
babel-traverse "^6.26.0"
babel-types "^6.26.0"
babylon "^6.18.0"
lodash "^4.17.4"
babel-traverse@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee"
dependencies:
babel-code-frame "^6.26.0"
babel-messages "^6.23.0"
babel-runtime "^6.26.0"
babel-types "^6.26.0"
babylon "^6.18.0"
debug "^2.6.8"
globals "^9.18.0"
invariant "^2.2.2"
lodash "^4.17.4"
babel-types@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
dependencies:
babel-runtime "^6.26.0"
esutils "^2.0.2"
lodash "^4.17.4"
to-fast-properties "^1.0.3"
babylon@^6.18.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
brace-expansion@^1.1.7:
version "1.1.8"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
dependencies:
ansi-styles "^2.2.1"
escape-string-regexp "^1.0.2"
has-ansi "^2.0.0"
strip-ansi "^3.0.0"
supports-color "^2.0.0"
coffeescript@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-2.0.0.tgz#61bcc70989cc18a0aab6b3d8be110d2ec7743c9a"
optionalDependencies:
babel-core "^6"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
convert-source-map@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5"
core-js@^2.4.0, core-js@^2.5.0:
version "2.5.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b"
debug@^2.6.8:
version "2.6.8"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
dependencies:
ms "2.0.0"
detect-indent@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
dependencies:
repeating "^2.0.0"
escape-string-regexp@^1.0.2:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
esutils@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
globals@^9.18.0:
version "9.18.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
has-ansi@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
dependencies:
ansi-regex "^2.0.0"
home-or-tmp@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
dependencies:
os-homedir "^1.0.0"
os-tmpdir "^1.0.1"
invariant@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
dependencies:
loose-envify "^1.0.0"
is-finite@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
dependencies:
number-is-nan "^1.0.0"
js-tokens@^3.0.0, js-tokens@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
jsesc@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
json5@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
lodash@^4.17.4:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
loose-envify@^1.0.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
dependencies:
js-tokens "^3.0.0"
minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
brace-expansion "^1.1.7"
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
mkdirp@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
dependencies:
minimist "0.0.8"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
number-is-nan@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
os-homedir@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
os-tmpdir@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
path-is-absolute@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
private@^0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1"
regenerator-runtime@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1"
repeating@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
dependencies:
is-finite "^1.0.0"
slash@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
source-map-support@^0.4.15:
version "0.4.18"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f"
dependencies:
source-map "^0.5.6"
source-map@^0.5.6:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
strip-ansi@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
dependencies:
ansi-regex "^2.0.0"
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
to-fast-properties@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
trim-right@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"