Merge remote-tracking branch 'origin/master' into ide-preview-sessions

pull/295/merge
Fabian Jakobs 2016-05-30 13:53:26 +00:00
commit c4eea5501b
65 zmienionych plików z 1613 dodań i 327 usunięć

Wyświetl plik

@ -0,0 +1,564 @@
CLOUD9 ONPREM LICENSE AGREEMENT
For parties who have entered a separate commercial agreement with Cloud9 to use
the Cloud9 SDK for commercial purposes, the following license shall apply.
Congratulations! Youre on your way to a better coding experience.
Cloud9 IDE, Inc.'s ("Cloud9", "we", or "us") Cloud9 OnPrem software helps you
build software faster and more efficiently by enabling distributed collaborative
development for teams. Before you download and/or use our Cloud9 OnPrem software,
we need you to agree to a special set of terms. Welcome to the Software License
Agreement (the "Agreement").
PLEASE READ THIS AGREEMENT CAREFULLY BEFORE INSTALLING OR USING THE SOFTWARE.
THESE TERMS AND CONDITIONS GOVERN YOUR USE OF THE SOFTWARE (AS DEFINED BELOW),
UNLESS WE HAVE EXECUTED A SEPARATE WRITTEN AGREEMENT WITH YOU FOR THAT PURPOSE.
WE'RE ONLY WILLING TO LICENSE THE SOFTWARE TO YOU IF YOU ACCEPT ALL THE TERMS
AND CONDITIONS OF THIS AGREEMENT. BY INSTALLING OR USING THE SOFTWARE OR BY
CLICKING "I ACCEPT" BELOW, YOU ARE CONFIRMING THAT YOU UNDERSTAND THIS
AGREEMENT, AND THAT YOU ACCEPT ALL OF ITS TERMS AND CONDITIONS. IF YOU ARE
ENTERING INTO THIS AGREEMENT ON BEHALF OF A COMPANY OR OTHER LEGAL ENTITY, YOU
REPRESENT THAT YOU HAVE THE LEGAL AUTHORITY TO BIND THE ENTITY TO THIS
AGREEMENT, IN WHICH CASE "YOU" WILL MEAN THE ENTITY YOU REPRESENT. IF YOU DON'T
HAVE SUCH AUTHORITY, OR IF YOU DON'T ACCEPT ALL THE TERMS AND CONDITIONS OF THIS
AGREEMENT, THEN WE ARE UNWILLING TO LICENSE THE SOFTWARE TO YOU, AND YOU MAY NOT
DOWNLOAD, INSTALL, OR USE IT.
1.Definitions.
Here are some definitions we use in this Agreement. If you see a capitalized
word that isn't listed here, it will be defined somewhere in the Agreement.
The "Agreement Effective Date" is the earlier of the date that you either click
"I Accept" to the terms and conditions of this Agreement, or that you first
place an order for Software or Services.
“Cloud9 SDK” is an Application Programming Interface defined to give users the
ability to extend the Cloud9 OnPrem software or integrate it with other systems.
“Derivative Works” refer to any software created using any of the Cloud9 OnPrem
source code.
"Documentation" means any manuals, documentation and other supporting materials
related to the Software that we generally provide to our customers.
Documentation is considered part of the Software.
"Fees" means both: (i) the fees you're required to pay us to use the Software
during the applicable License Term, as such fees are reflected on each
applicable Order Form; and (ii) the fees you're required to pay us for any
Services you engage us to perform, as such fees are reflected on each applicable
SOW.
"License Key" means a data file utilized by the Software's access control
mechanism that allows you to use the Software during the License Term.
"License Term" means one (1) year from the applicable Order Effective Date.
The "Order Form" is a written or electronic form that we'll give you to order
Software (or that we'll use to order Software on your behalf, once we've gotten
your authorization). Upon execution by the parties (or, in the case of an
electronic orders, confirmation and placement of the order), each Order Form
will be subject to the terms and conditions of this Agreement.
The "Order Effective Date" is the effective date of each Order Form.
“Plugins” refer to any software created to interact with the Cloud9 OnPrem
software using the Cloud9 SDK.
"Seats" mean the number of User accounts for the Software that you're authorized
to create. The number of Seats is specified in the applicable Order Form. Only
one User can use a Seat at a time. Multiple Users aren't allowed to use the same
Seat.
"Services" means training, consulting, or implementation services that we
provide to you pursuant to a mutually executed Statement of Work.  Services do
not include support.
"Software" means the object-code/obfuscated source code, actual source code or
Derivative Works version of our proprietary Cloud9 OnPrem software application.
Software includes any applicable Documentation, as well as any Updates to the
Software that we provide you or that you can access under this Agreement.
"Statement of Work" or "SOW" means a mutually executed statement of work
detailing the Services we'll perform for you, their price, and your related
obligations (if any).
An "Update" is a Software release that we make generally available to our
customers, along with any corresponding changes to Documentation. An Update may
be an error correction or bug fix, generally indicated by a change in the digit
to the right of the second decimal point (e.g., a change from version x.x.x to
x.x.y); or it may be an enhancement, new feature, or new functionality,
generally indicated by a change in the digit to the right of the first decimal
point (e.g., x.x.x to x.y.x) or to the left of the first decimal point
(e.g., x.x.x to y.x.x).
A "User" is a single person or machine account that initiates the execution of
the Software and/or interacts with or directs the Software in the performance of
its functions. The number of Users shouldn't exceed the number of Seats you've
licensed from us.
2.License Grant.
Subject to your compliance with the terms of this Agreement (including, among
other things, paying the Fees you owe us), we hereby grant you a non-exclusive,
non-transferable, worldwide, royalty-free, limited-term license to install,
execute, and use the Software for your internal business purposes during the
applicable License Term, in accordance with the Documentation, and only for the
number of Seats that you've paid for. You can make copies of the Software for
non-production purposes only, provided that you reproduce all copyright and
other proprietary notices that are on the original copy of the Software.
Your agents and contractors can use the Software too, so long as they're using
it on your behalf, and provided that you agree to be fully responsible for their
behavior under this Agreement.
3.Restrictions.
We license the Software to you – we don't sell it. As between us, we own all
right, title and interest in and to the Software, and any intellectual property
rights associated with it and with our company. We reserve all rights in and to
the Software that we don't expressly grant you in this Agreement. You agree not
to, nor permit nor authorize any third party to: (i) sublicense, sell, rent,
lease, transfer, assign, or distribute the Software to third parties; (ii) host
the Software for the benefit of third parties; (iii) disclose or permit any
third party to access the Software, except as expressly permitted in Section 2,
above; (iv) hack or modify the License Key, or try to avoid or change any
license registration process we may implement; (v) modify or create derivative
works of the Software, or merge the Software with other software; (vi)
disassemble, decompile, bypass any code obfuscation, or otherwise reverse
engineer the Software or attempt to derive any of its source code, in whole or
in part, except to the extent such activities are expressly permitted by law or
applicable license notwithstanding this prohibition; (vii) modify, obscure, or
delete any proprietary rights notices included in or on the Software or
Documentation; (viii) otherwise use or copy the Software in a manner not
expressly permitted by this Agreement; or (ix) use any Software that we license
to you beyond its applicable License Term.
4.Seats.
Remember, only one User can use a Seat at a time. Multiple Users aren't allowed
to use the same Seat, and only one human being can be associated with a
particular User account. If you want to swap out, delete, or suspend a User, you
can do that, and then assign a new User to the open Seat. If you find that you
need more Seats, that's great – we're here to help! Just submit a new request
through our website or via our sales team, and pay for the additional Seats
(a new Order Form will be generated). If and when you add additional Seats to
your subscription, you'll pay Fees for those seats at the then-current price,
prorated for the balance of the applicable License Term. When the time comes to
renew your Seats for another year-long License Term, we'll invoice you for all
of your Seats at once, at the then-current price (we reserve the right to change
our prices at any time, but the new prices won't affect you until it's time to
renew your license for another year). You agree that any orders that you make
(or that you authorize us to make on your behalf) for additional Seats during
the term of this Agreement will be governed by this Agreement.
5.Verification.
From time to time, we may have reason to make sure that you're not using extra
Seats without paying for them. You agree to cooperate with us to achieve that
goal. To help us verify the number of Seats you're actually using, you agree to
promptly give us any usage files and reports that your instance of the Software
generates, if and when we ask for them. We might also (or instead) ask one of
your officers to certify the number of Seats that you're actually using. You
agree to provide such a certification if we ask for it. If we determine that
you're using more Seats than you've paid for, in addition to any other remedies
we might have at law or in equity, you agree to pay us the then-current Fees for
the additional Seats you're using, starting from the date you began using each
Seat.
6.Government Users.
No technical data or computer software is developed under this Agreement. The
Software and Documentation have been developed solely with private funds, and
are considered "Commercial Computer Software" and "Commercial Computer Software
Documentation" as described in FAR 12.212, FAR 27.405-3, and DFARS 227.7202-3,
and are licensed to the to the U.S. Government end user as restricted computer
software and limited rights data. Any use, disclosure, modification,
distribution, or reproduction of the Software or Documentation by the U.S.
Government or its contractors is subject to the restrictions set forth in this
Agreement.
7.Delivery.
Promptly after the applicable Order Effective Date, we'll make the Software and
the License Key available for you to download on a secure, password-protected
website. As Updates become available, we'll make those available for you to
download on the same website. You're responsible for maintaining the
confidentiality of all of your usernames and passwords, including the ones you
use to download the Software. Take good care of them, because you agree that
you'll be responsible for any activity that takes place using your usernames and
passwords (whether you knew about it or not).
8.Services.
Our Services can help you get the most out of the Software. If you want
Services, let us know, and we'll work with you to prepare a SOW that describes
the date, time, location, and objectives of the Services, as well as the price.
Each SOW will be binding once we both sign it, and you agree that any Services
we provide to you (whether pursuant to a SOW or not) will be governed
exclusively by the terms of this Agreement.  In the event of any conflict
between the terms of this Agreement and any SOW, the terms of this Agreement
will control. Provided you comply with the terms of this Agreement (including,
among other things, paying us the Fees you owe us), we'll perform the Services
described in each SOW, according to the timeframes set forth in that SOW.
We'll control the manner and means by which the Services are performed, and we
reserve the right to determine which personnel we assign to perform Services for
you.
Provided we remain responsible for all of their acts and omissions, we can use
third parties to help us perform the Services.  You acknowledge that we will
retain all right, title and interest in and to anything we use or develop in
connection with performing Services for you, including, among other things,
software programs, tools, specifications, ideas, concepts, inventions,
processes, techniques, and know-how.  To the extent we deliver anything to you
during the course of performing Services, we grant you a non-exclusive,
non-transferable, worldwide, royalty-free, limited-term license to use those
deliverables during the term of this Agreement, solely in conjunction with your
use of the Software.
9.Term and Termination.
9.1 Term.
This Agreement starts on the Agreement Effective Date and will continue in
effect for one (1) year (the "Initial Term"), at which time, so long as you
choose to renew your Software license for additional License Terms (which, to be
clear, you're under no obligation to do), this Agreement will automatically
continue in effect for additional one (1) year terms (each, a "Renewal Term")
until this Agreement is either terminated by a party or expires in accordance
with this Section 8. We'll notify you at least sixty (60) days before the end of
the Initial Term and each Renewal Term that it's time for you to renew your
Software license. If you want to renew, let us know. We'll generate a new Order
Form for you, and make a new License Key available for you to download that will
let you use the Software for another License Term.
9.2 Termination for Convenience;
Automatic Expiration. Either of us can terminate this Agreement for our
convenience at the end of the Initial Term or any Renewal Term by providing
written notice to the other at least thirty (30) days before the end of the
Initial Term or any Renewal Term. This Agreement will automatically expire
without the requirement of notice if, at the end of the Initial Term or any
Renewal Term, you decide not to pay the Fees required to renew your Seats for an
additional License Term.
9.3 Termination for Breach.
We can terminate this Agreement immediately upon notice to you if you breach
any part of it, and you fail to cure the breach within thirty (30) days of us
notifying you of it. That said, there are certain kinds of breaches that we take
much more seriously, and that can really damage us. We therefore reserve the
right to terminate this Agreement immediately upon written notice to you, but
without giving you a cure period, if you breach any of the terms of this
Agreement relating to our intellectual property (including your compliance with
the license grant and any license restrictions) or our Confidential Information
(defined below).
9.4 Effect of Termination.
When this Agreement terminates or expires: (i) the License Term for any Software
in your possession will immediately end, and any outstanding SOWs will
immediately terminate; (ii) you'll no longer have the right to use the Software,
and any licenses we grant you in this Agreement will automatically cease to
exist as of the date of termination/expiration; (iii) if you owed us any money
prior to termination/expiration, you'll need to pay us all that money
immediately; (iv) you'll destroy all copies of the Software in your possession
or control, and certify in writing to us that you've done so; and (v) each of
us will promptly return to the other (or, if the other party requests it,
destroy) all Confidential Information belonging to the other.  You'll still be
able to access the Software to migrate your data for ninety (90) days after
termination or expiration of this Agreement, but you won't be allowed to use the
Software on a production basis during that time.  We encourage you to keep
copies of your data outside of the Software itself, because if the Software gets
disabled, you won't have access to the data you've stored there (and we won't be
liable to you if that happens). Sections 1, 3, 5, 6, 8, 9.2, 9.3, 9.4, 11, 12.2,
and 13-17 will survive the termination or expiration of this Agreement for any
reason.
10.Support.
10.1 Support Times.
Provided that you've paid us the Fees you owe us, we'll provide you with
technical support for the Software twenty-four (24) hours per day, five (5) days
per week, excluding weekends and national U.S. holidays. We currently only offer
support via email (write to us at mailto:support@c9.io) or web-based ticketing
(through https://c9.io/support). You can contact our amazing support team to
help answer your questions on installing and using the Software, identifying and
verifying the causes of suspected errors in the Software, and helping you find
workarounds for Software malfunctions. Though we'll do our best to respond to
automated support requests, we typically need more information than an automated
ticketing system can give us to solve your issue. Whenever possible, please
initiate any support requests from a person or machine that our support team can
interact with. We like the personal touch.
10.2 Updates.
We'll make Updates available to you on the same secure website where you
downloaded the Software and the License Key.
10.3 Exclusions.
We might not be able to correct every problem we find, but we'll use our
reasonable efforts to correct any material, reproducible errors in the Software
that you make us aware of. We might ask for your help in reproducing the error
for us. Please - don't do things with our Software that would make it harder for
us to help you. We won't be responsible for supporting you in those
circumstances, which include, among other things: (i) someone (other than us)
modifying the Software; (ii) changing your operating system or environment in a
way that adversely affects the Software or its performance; (iii) using the
Software in a manner for which it was not designed, or other than as authorized
under this Agreement; or (iv) accident, negligence, or misuse of the Software.
We're only required to support a given version of the Software for a year from
the date of its commercial release, or six months from the commercial release
of the next Update, whichever is longer. If you want support for earlier
versions of the Software, we'll try to help you if we can, but you'll need to
pay us for that help at our then-current rates.
11.Payment.
You agree to pay the Fees to us in full, without deduction or setoff of any
kind, in U.S. Dollars (unless the Order Form says otherwise), within 30 days of
the date of the invoice we send you related to the applicable SOW or Order Form.
Amounts payable under this Agreement are nonrefundable, except as provided in
Section 12.1. If you don't pay us on time, we reserve the right, in addition to
taking any other action that we see fit, to charge you interest on past due
amounts at 1.0% per month or the highest interest rate allowed by law, whichever
is less, and to additionally charge all expenses of recovery. You are solely
responsible for all taxes, fees, duties and governmental assessments (except for
taxes based on Cloud9's net income) that are imposed or become due in connection
with the subject matter of this Agreement.
12.Limited Warranties
12.1 Limited Warranties.
We offer you (and only you) the following limited warranties: (i) that the
unmodified Software, at the time we make it available to you for download, will
not contain or transmit any malware, viruses, or worms (otherwise known as
computer code or other technology specifically designed to disrupt, disable, or
harm your software, hardware, computer system, or network); (ii) that any
Services we perform for you under this Agreement will be performed in a good and
workmanlike manner, by appropriately qualified personnel (you just need to let
us know about a problem within thirty (30) days of the date the Services were
performed); and (iii) that, for ninety (90) days from the date the Software is
made available for download, the unmodified Software will substantially conform
to its Documentation. We don't warrant that your use of the Software will be
uninterrupted, or that the operation of the Software will be error-free.
These warranties won't apply if you modify the Software, or if you use the
Software in any way that isn't expressly permitted by this Agreement and the
Documentation.
Our only obligation, and your only remedy, for any breach of these limited
warranties will be, at our option and expense, to either (i) repair the
Software; (ii) replace the Software; or (iii) terminate this Agreement with
respect to the defective Software, and refund the Fees you've paid for the
defective Software during the then-current License Term once you've returned it
to us (or destroyed it).
12.2 Disclaimer.
THE LIMITED WARRANTIES DESCRIBED ABOVE ARE THE ONLY WARRANTIES WE MAKE WITH
RESPECT TO THE SOFTWARE, SERVICES AND OUR TECHNICAL SUPPORT. WE DON'T MAKE ANY
OTHER WARRANTIES, AND WE HEREBY SPECIFICALLY DISCLAIM ANY OTHER WARRANTIES,
WHETHER EXPRESS, IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT,
OR ANY WARRANTIES OR CONDITIONS ARISING OUT OF COURSE OF DEALING OR USAGE OF
TRADE. NO ADVICE OR INFORMATION, WHETHER ORAL OR WRITTEN, THAT YOU GET FROM US
OR ANYWHERE ELSE WILL CREATE ANY WARRANTY OR CONDITION NOT EXPRESSLY STATED IN
THIS AGREEMENT.
13.LIMITATION OF LIABILITY.
13.1 Waiver of Consequential Damages.
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL WE BE LIABLE
TO YOU OR TO ANY THIRD PARTY FOR ANY INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE, OR
CONSEQUENTIAL DAMAGES (INCLUDING FOR LOSS OF PROFITS, REVENUE, OR DATA) OR FOR
THE COST OF OBTAINING SUBSTITUTE PRODUCTS ARISING OUT OF OR IN CONNECTION WITH
THIS AGREEMENT, HOWEVER CAUSED, WHETHER SUCH LIABILITY ARISES FROM ANY CLAIM
BASED UPON CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
OTHERWISE, AND WHETHER OR NOT WE'VE BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
13.2 Limitation of Total Liability.
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, OUR TOTAL CUMULATIVE
LIABILITY TO YOU OR ANY THIRD PARTY UNDER THIS AGREEMENT, FROM ALL CAUSES OF
ACTION AND ALL THEORIES OF LIABILITY, WILL BE LIMITED TO AND WILL NOT EXCEED THE
FEES YOU'VE ACTUALLY PAID US DURING THE 12 MONTHS PRECEDING THE CLAIM GIVING
RISE TO SUCH LIABILITY.
13.3 Basis of Bargain.
You understand and agree that we've set our prices and entered into this
Agreement with you in reliance upon the limitations of liability set forth in
this Agreement, which allocate risk between us and form the basis of a bargain
between the parties.
14.Indemnification.
14.1 Our Indemnification Obligation.
We'll defend or settle, at our option and expense, any third-party claim brought
against you to the extent that it's based on an allegation that your use or
possession of the Software as permitted under this Agreement infringes a
copyright or misappropriates a trade secret of any third party (each, a "Claim"),
and, subject to Section 13, we'll pay all damages and costs (including
reasonable legal fees) finally awarded by a court of final appeal attributable
to such a Claim, provided that you notify us in writing of any such Claim as
soon as reasonably practicable and allow us to control, and reasonably cooperate
with us in the defense of, any such Claim and related settlement negotiations.
14.2 Exclusions.
You understand that we'll have no obligation to indemnify you for any Claim
that's based on (i) the modification of the Software, unless we were the ones
who made the modifications; (ii) your use of the Software other than as
authorized by this Agreement and the Documentation; (iii) your failure to use
updated or modified Software that we make available to you that would have
helped avoid or mitigate the Claim; (iv) your failure to stop using the Software
after receiving written notice to do so from us in order to avoid further
infringement or misappropriation; or (v) the combination, operation or use of
the Software with equipment, devices, software, systems, or data that we didn't
supply (subparts (i)-(v) may be referred to collectively as "Indemnity
Exclusions").
14.3 Right to Ameliorate Damages.
If your use of the Software is, or in our reasonable opinion is likely to be,
subject to a Claim under Section 14.1, we may, at our sole option and at no
charge to you (and in addition to our indemnity obligation to you in Section
14.1): (i) procure for you the right to continue using the Software; (ii)
replace or modify the Software so that it is non-infringing and substantially
equivalent in function to the original Software; or (iii) if options (i) and (ii)
above are not commercially practicable in our reasonable estimation, we can
terminate this Agreement and all licenses granted hereunder (in which event,
you will immediately stop using the Software) and refund the Fees that you paid
us for the then-current License Term.
14.4 Sole Remedy.
THIS SECTION 14 SETS FORTH OUR SOLE AND EXCLUSIVE OBLIGATIONS, AND YOUR SOLE AND
EXCLUSIVE REMEDIES, WITH RESPECT TO CLAIMS OF INFRINGEMENT OR MISAPPROPRIATION
OF THIRD PARTY INTELLECTUAL PROPERTY RIGHTS.
14.5 Your Indemnification Obligation.
Because we can't know what you're doing with the Software behind your firewall,
except to the extent that we're obliged to indemnify you in Section 14.1 above,
you will defend, indemnify, and hold us harmless from and against any claims
that may arise out of or that are based upon (i) your breach of this Agreement;
(ii) content that you upload to the Software; or (iii) an Indemnity Exclusion.
15.Confidentiality.
15.1 Definition of Confidential Information.
For the purposes of this Agreement, "Confidential Information" means any
business or technical information that either one of us discloses to the other,
in writing, orally, or by any other means, and including things like computer
programs, code, algorithms, data, know-how, formulas, processes, ideas,
inventions (whether patentable or not), schematics and other technical,
business, financial, and product development plans, names and expertise of
employees and consultants, and customer lists. For the purposes of this
Agreement, except as expressly set forth in Section 17.2 below, the source code
of our Software will be deemed to be Cloud9's Confidential Information,
regardless of whether it is marked as such.
15.2 Restrictions on Use and Disclosure.
Neither of us will use the other party's Confidential Information, except as
permitted under this Agreement. Each of us agrees to maintain in confidence and
protect the other party's Confidential Information using at least the same
degree of care as we use for its own information of a similar nature, but in all
events at least a reasonable degree of care. Each of us agrees to take all
reasonable precautions to prevent any unauthorized disclosure of the other's
Confidential Information, including, without limitation, disclosing Confidential
Information only to its employees, independent contractors, consultants, and
legal and financial advisors (collectively, "Representatives") (i) with a need
to know such information, (ii) who are parties to appropriate agreements
sufficient to comply with this Section 15, and (iii) who are informed of the
nondisclosure obligations imposed by this Section 15. Each of us will be
responsible for all acts and omissions of our Representatives. The foregoing
obligations won't restrict either of us from disclosing Confidential Information
of the other party pursuant to the order or requirement of a court,
administrative agency, or other governmental body, provided that the party
required to make such a disclosure gives reasonable notice to the other party to
enable them to contest such order or requirement. The restrictions set forth in
this Section 15 will survive the termination or expiration of this Agreement.
15.3 Exclusions.
The restrictions set forth in Section 15.2 will not apply with respect to any
Confidential Information that: (i) was or becomes publicly known through no
fault of the receiving party; (ii) was rightfully known or becomes rightfully
known to the receiving party without confidential or proprietary restriction
from a source other than the disclosing party who has a right to disclose it;
(iii) is approved by the disclosing party for disclosure without restriction in
a written document which is signed by a duly authorized officer of such
disclosing party; or (iv) the receiving party independently develops without
access to or use of the other party's Confidential Information.
16.Governing Law and Jurisdiction.
This Agreement will be governed by and interpreted in accordance with the laws
of the State of California, without giving effect to any principles of conflict
of laws. The parties expressly agree that the United Nations Convention on
Contracts for the International Sale of Goods and the Uniform Computer
Information Transactions Act will not apply to this Agreement. Any legal action
or proceeding arising under, related to or connected with this Agreement will
be brought exclusively in the federal (if they have jurisdiction) or state
courts located in San Francisco, California and the parties irrevocably consent
to the personal jurisdiction and venue there.
17.Miscellaneous.
17.1 Assignment.
You aren't allowed to assign or transfer any of your rights or obligations in
this Agreement, in whole or in part, by operation of law or otherwise, without
our prior written consent, and any attempt by you to do so without our consent
will be null and void.  We can assign this Agreement in its entirety, upon
notice to you but without the requirement to obtain consent, in connection with
a merger, acquisition, corporate reorganization, or sale of all or substantially
all of our business or assets.
17.3 Severability.
In the event that any provision of this Agreement is deemed by a court of
competent jurisdiction to be illegal, invalid, or unenforceable, the court will
modify or reform this Agreement to give as much effect as possible to that
provision. Any provision that can't be modified or reformed in this way will be
deemed deleted, and the remaining provisions of this Agreement will continue in
full force and effect.
17.4 Notices.
Any notice, request, demand or other communication required or permitted under
this Agreement should be in writing (e-mail counts), should reference this
Agreement, and will be deemed to be properly given: (i) upon receipt, if
delivered personally; (ii) upon confirmation of receipt by the intended
recipient, if by e-mail; (iii) five (5) business days after it is sent by
registered or certified mail, with written confirmation of receipt; or (iv)
three (3) business days after deposit with an internationally recognized express
courier, with written confirmation of receipt. Notices should be sent to the
address(es) set forth on the Invoice, unless we notify each other that those
addresses have changed.
17.5 Waiver.
A party's obligations under this Agreement can only be waived in a writing
signed by an authorized representative of the other party, which waiver will be
effective only with respect to the specific obligation described. Any waiver or
failure to enforce any provision of this Agreement on one occasion will not be
deemed a waiver of any other provision or of such provision on any other
occasion.
17.6 Force Majeure.
We will be excused from performing under this Agreement to the extent that we're
unable to perform due extraordinary causes beyond our reasonable control. That
might include things like acts of God, strikes, lockouts, riots, acts of war,
epidemics, communication line failure, and power failures.
17.7 Independent Contractors.
We're each independent contractors with respect to the subject matter of this
Agreement. Nothing contained in this Agreement will be deemed or construed in
any manner whatsoever to create a partnership, joint venture, employment, agency,
fiduciary, or other similar relationship between us, and neither of us can bind
the other contractually.
17.8 Amendments;
Entire Agreement. No modification, change, or amendment of this Agreement will
be binding upon the parties, unless we both agree to the change in a writing
signed by each of our authorized representatives. This Agreement, including each
Order Form and SOW, constitutes the entire agreement and understanding of the
parties with respect to its subject matter, and supersedes any and all prior or
contemporaneous understandings and agreements, whether oral or written, between
the parties with respect to its subject matter.
17.9 No Other Terms.
Sometimes your accounting folks will send us purchase orders with lots of itty
bitty language attached that requires a microscope for us to read. Everybody
does it – we understand. But this Agreement is the only agreement between us,
and the terms of any purchase order, written terms or conditions, or other
document that you submit to us that contain terms that are different from, in
conflict with, or in addition to the terms of this Agreement, SOW or any Order
Form are hereby rejected by Cloud9, and will be void and of no effect.
17.10 No Publicity Without Your Permission.
We may identify you as a customer to current and prospective clients.
We won't use your name or logo in any advertising or marketing materials without
your permission, though; and if we ask for your permission, you always have the
right to say no.

Wyświetl plik

@ -9,7 +9,10 @@
"https://cloud9beta.com/", "https://ide.cloud9beta.com/",
"http://localhost:8181/", "http://localhost:5252/",
"https://c9.vm:8181/", "https://c9.vm:5252/",
"https://c9.dev/", "https://ide.c9.dev/"
"https://c9.dev/", "https://ide.c9.dev/",
"https://ide.dev.smartface.io",
"https://ide.cs50.io",
"https://ide.mbed.com"
]
},
"description": "Cloud9 is an online platform for development that makes developing applications more convenient than ever",

Wyświetl plik

@ -35,8 +35,6 @@ module.exports = function(options) {
var devel = options.standalone && !options.local || options.mode === "devel" || options.mode == "onlinedev" || options.dev;
var localExtendFiles = options.localExtend || options.standalone;
// allow extend code access only to C9-deveoped plugins
var extendToken = options.extendToken || "token";
var plugins = [
// C9
@ -412,7 +410,6 @@ module.exports = function(options) {
"plugins/c9.ide.language.go/go",
{
packagePath: "plugins/c9.ide.language.jsonalyzer/jsonalyzer",
extendToken: extendToken,
workspaceDir: workspaceDir,
homeDir: options.home,
bashBin: options.bashBin,
@ -692,11 +689,7 @@ module.exports = function(options) {
pubkey: options.user.pubkey,
date_add: options.user.date_add,
active: options.user.active,
alpha: options.user.alpha,
beta: options.user.beta,
c9version: options.user.c9version,
no_newsletter: options.user.no_newsletter,
subscription_on_signup: options.user.subscription_on_signup,
premium: options.user.premium,
region: options.user.region,
},
@ -787,7 +780,6 @@ module.exports = function(options) {
},
{
packagePath: "plugins/c9.ide.pubsub/pubsub-client",
extendToken: extendToken
},
{
packagePath: "plugins/c9.ide.collab/notifications/bubble",
@ -868,7 +860,6 @@ module.exports = function(options) {
plugins.push(
{
packagePath: "plugins/c9.ide.collab/connect",
extendToken: extendToken,
enable: collab,
debug: debug,
localServerFile: localExtendFiles,
@ -924,6 +915,9 @@ module.exports = function(options) {
plugins.push({
packagePath: "plugins/c9.ide.language.codeintel/codeintel",
preinstalled: hosted && !options.ssh,
paths: {
php: ".:./vendor",
},
});
}

Wyświetl plik

@ -105,7 +105,7 @@ module.exports = function(config, optimist) {
console.log("Run using --listen localhost instead to only expose Cloud9 to localhost,");
console.log("or use -a username:password to setup HTTP authentication\n");
}
var auth = (argv.auth || ":").split(":");
var auth = (argv.auth + "").split(":");
var plugins = [
{
@ -158,7 +158,6 @@ module.exports = function(config, optimist) {
"c9.vfs.client": true,
"c9.cli.bridge": true,
"c9.nodeapi": true,
"c9.ide.experiment": true,
"saucelabs.preview": true,
"salesforce.sync": true,
"salesforce.language": true
@ -194,7 +193,6 @@ module.exports = function(config, optimist) {
"./c9.vfs.server/statics",
"./c9.analytics/mock_analytics",
"./c9.metrics/mock_metrics",
"./c9.ide.experiment/mock_experiment",
{
packagePath: "./c9.vfs.server/vfs.connect.standalone",
workspaceDir: baseProc,

Wyświetl plik

@ -148,7 +148,7 @@ var EditSession = function(text, mode) {
this.$undoSelect = true;
this.$foldData = [];
this.id = "session" + EditSession.$uid;
this.id = "session" + (++EditSession.$uid);
this.$foldData.toString = function() {
return this.join("\n");
};

Wyświetl plik

@ -364,10 +364,11 @@ var TextInput = function(parentNode, host) {
return;
// console.log("onCompositionStart", inComposition)
inComposition = {};
inComposition.canUndo = host.session.$undoManager;
host.onCompositionStart();
setTimeout(onCompositionUpdate, 0);
host.on("mousedown", onCompositionEnd);
if (!host.selection.isEmpty()) {
if (inComposition.canUndo && !host.selection.isEmpty()) {
host.insert("");
host.session.markUndoGroup();
host.selection.clearSelection();
@ -385,6 +386,7 @@ var TextInput = function(parentNode, host) {
host.onCompositionUpdate(val);
if (inComposition.lastValue)
host.undo();
if (inComposition.canUndo)
inComposition.lastValue = val;
if (inComposition.lastValue) {
var r = host.selection.getRange();

14
node_modules/ace/lib/ace/keyboard/vim.js wygenerowano vendored
Wyświetl plik

@ -154,8 +154,7 @@ define(function(require, exports, module) {
return this.ace.inVirtualSelectionMode && this.ace.selection.index;
};
this.onChange = function(delta) {
if (delta.action[0] == 'i') {
var change = { text: delta.lines };
var change = { text: delta.action[0] == 'i' ? delta.lines : [] };
var curOp = this.curOp = this.curOp || {};
if (!curOp.changeHandlers)
curOp.changeHandlers = this._eventRegistry["change"] && this._eventRegistry["change"].slice();
@ -165,7 +164,6 @@ define(function(require, exports, module) {
} else {
curOp.lastChange.next = curOp.lastChange = change;
}
}
this.$updateMarkers(delta);
};
this.onSelectionChange = function() {
@ -5693,6 +5691,10 @@ dom.importCssString(".normal-mode .ace_cursor{\
if (changeObj.origin == '+input' || changeObj.origin == 'paste'
|| changeObj.origin === undefined /* only in testing */) {
var text = changeObj.text.join('\n');
if (lastChange.maybeReset) {
lastChange.changes = [];
lastChange.maybeReset = false;
}
lastChange.changes.push(text);
}
// Change objects may be chained with next.
@ -5715,7 +5717,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
lastChange.expectCursorActivityForChange = false;
} else {
// Cursor moved outside the context of an edit. Reset the change.
lastChange.changes = [];
lastChange.maybeReset = true;
}
} else if (!cm.curOp.isVimOp) {
handleExternalSelection(cm, vim);
@ -5779,6 +5781,10 @@ dom.importCssString(".normal-mode .ace_cursor{\
var keyName = CodeMirror.keyName(e);
if (!keyName) { return; }
function onKeyFound() {
if (lastChange.maybeReset) {
lastChange.changes = [];
lastChange.maybeReset = false;
}
lastChange.changes.push(new InsertModeKey(keyName));
return true;
}

2
node_modules/architect-build/build.js wygenerowano vendored
Wyświetl plik

@ -77,7 +77,7 @@ function build(config, opts, callback){
if (added[pkg.id])
return;
added[pkg.id] = true;
if (!pkg.source)
if (pkg.source == null)
return;
if (pkg.deps)
pkg.deps.forEach(addModule);

Wyświetl plik

@ -113,6 +113,7 @@ module.exports = function(mains, opts) {
}
function setModuleSource(mod, src, cb) {
src = src.replace(/\r\n/g, "\n"); // normalize windows newlines
if (cache)
cache.files[mod.file] = src;
mod.source = src;
@ -345,13 +346,14 @@ function removeUseStrict(module) {
module.source = module.source.replace(/['"]use strict['"];/g, "");
}
var commentRe = /^(;)?(?:\s*(?:\/\/.+\n|\/\*(?:[^*]|\*(?!\/))*\*\/))+(?: *\n)?/gm;
function removeLicenceComments(module) {
if (/\.(js|jsx|css|less)/.test(module.path))
module.source = module.source.replace(/(?:(;)|\n|^)\s*\/\*[\d\D]*?\*\/|(\n|^)\s*\/\/.*/g, "$1");
module.source = module.source.replace(commentRe, "$1");
}
function removeLicenceCommentsKeepLines(module) {
if (/\.(js|jsx|css|less)/.test(module.path)) {
module.source = module.source.replace(/(?:(;)|\n|^)\s*\/\*[\d\D]*?\*\/|\n\s*\/\/.*/g, function(cm, start) {
module.source = module.source.replace(commentRe, function(cm, start) {
return (start||"") + cm.replace(/.+/g, "");
});
}
@ -391,8 +393,8 @@ function wrapUMD(module) {
+ ' $build_deps$.module.define(name, [], function() { return $build_deps$.module.exports });\n'
+ ' }\n'
+ '}\n'
+ 'define.amd = true;'
+ module.source
+ 'define.amd = true;\n'
+ module.source + '\n'
+ '});';
}
@ -410,4 +412,7 @@ function quote(str) {
}
module.exports.getSubmodules = getSubmodules;
module.exports.resolveModulePath = resolveModulePath;
module.exports.removeLicenceComments = removeLicenceComments;
module.exports.removeLicenceCommentsKeepLines = removeLicenceCommentsKeepLines;

9
node_modules/c9/gce.js wygenerowano vendored
Wyświetl plik

@ -24,12 +24,15 @@ function runCommand(pattern, command, options, callback) {
return runCommand(pattern, command, {}, options);
}
var parallel = ""
var optionsArray = [];
if (options.parallel) {
parallel = " -P"
optionsArray.push("-P");
}
if (options.cacheOnly) {
optionsArray.push("--cache-only");
}
var gsshCommand = GSSH + " " + parallel + " " + pattern + " '" + command + "'";
var gsshCommand = GSSH + " " + optionsArray.join(" ") + " " + pattern + " '" + command + "'";
childProcess.exec(gsshCommand, function (err, stdout) {
return callback(err, stdout);
});

8
node_modules/c9/is-zuora-id.js wygenerowano vendored 100644
Wyświetl plik

@ -0,0 +1,8 @@
"use strict";
module.exports = function isZuoraId(value){
if (/^\d+$/.test(value))
return false;
return /^[a-z0-9]{32}$/.test(value);
};

42
node_modules/c9/is-zuora-id_test.js wygenerowano vendored 100644
Wyświetl plik

@ -0,0 +1,42 @@
"use strict";
"use mocha";
require("c9/inline-mocha")(module);
var assert = require("assert");
var isZuoraId= require("c9/is-zuora-id");
describe("iz-zuora-id-test", function() {
it("returns false when account id undefined", function() {
assert.equal(false, isZuoraId(undefined), "should return false when account id undefined");
});
it("returns false when account id null", function() {
assert.equal(false, isZuoraId(null), "should return false when account id null");
});
it("returns false when account id is an empty string", function() {
assert.equal(false, isZuoraId(""), "should return false when account id is an empty string");
});
it("returns false when account id contains only digits", function() {
var accountId = "12345700674455";
assert.equal(false, isZuoraId(accountId), "should return false when account id contains only digits");
});
it("returns false when account id contains only digits and has the correct length", function() {
var accountId = "123456789101112131415161718192021";
assert.equal(false, isZuoraId(accountId), "should return false when account id contains only digits and has the correct length");
});
it("returns false when account id contains both digits and letters but does not have the correct length", function() {
var accountId = "78654hjfgf764674h87634876g7h89h";
assert.equal(false, isZuoraId(accountId), "should return false");
});
it("returns true when account id has both letters and digits and correct length", function() {
var accountId = "2c92a0f850a7a1b50150c672fa3a6ddd";
assert.equal(true, isZuoraId(accountId), "should return true when account id has both letters and digits and correct length");
});
});

44
node_modules/c9/ratelimit.js wygenerowano vendored
Wyświetl plik

@ -1,32 +1,46 @@
var error = require("http-error");
var MAX_EXPIRE_INTERVAL = 5000;
/**
* In memory rate limiter as connect middleware
*/
module.exports = ratelimit;
function ratelimit(key, duration, max) {
var limit = {};
var requests = Object.create(null); // in case there handles like 'constructor'
setInterval(function() {
Object.keys(requests).forEach(expireRequests);
}, Math.min(duration * 0.75, MAX_EXPIRE_INTERVAL));
function expireRequests(handle) {
var requestsForHandle = requests[handle];
var totalToSplice = 0;
var expireTime = Date.now() - duration;
/* Requests are already sorted by date as they are appended, so we just loop
until we find one that shouldn't have expired and splice them from the list */
for (totalToSplice = 0; totalToSplice < requestsForHandle.length; totalToSplice++) {
if (requestsForHandle[totalToSplice] >= expireTime) break;
}
requests[handle].splice(0, totalToSplice);
if (requests[handle].length == 0) {
delete requests[handle];
}
return true;
}
return function(req, res, next) {
var handle = req.params[key];
var lim = limit[handle] || (limit[handle] = []);
var now = Date.now();
for (var i = 0; i < lim.length; i++) {
if (now - lim[i] > duration) {
lim.splice(i, 1);
i--;
}
else break;
}
if (lim.length > max) {
requests[handle] = requests[handle] || [];
if (requests[handle].length >= max) {
var err = new error.TooManyRequests("Rate limit exceeded");
err.retryIn = duration - (Date.now() - lim[0]);
next(err);
return;
err.retryIn = Math.min(duration, 5000);
return next(err);
}
lim.push(Date.now());
requests[handle].push(Date.now());
return next();
};
}

104
node_modules/c9/ratelimit_test.js wygenerowano vendored 100644
Wyświetl plik

@ -0,0 +1,104 @@
"use server";
require("c9/inline-mocha")(module);
var ratelimit = require("./ratelimit");
var assert = require("assert");
var async = require("async");
describe("ratelimit", function() {
it("Should limit based on key", function (done) {
var limiter = ratelimit("username", 10, 1);
limiter({params: {username: "super"}}, null, function (err) {
assert(!err, err);
limiter({params: {username: "super"}}, null, function (err) {
assert(err);
assert.equal(err.code, 429);
done();
});
});
});
it("Should work with different keys", function (done) {
var limiter = ratelimit("username", 10, 1);
limiter({params: {username: "super"}}, null, function (err) {
assert(!err, err);
limiter({params: {username: "aloha"}}, null, function (err) {
assert(!err, err);
done();
});
});
});
it("Should work again after a delay", function (done) {
var limiter = ratelimit("username", 10, 1);
limiter({params: {username: "super"}}, null, function (err) {
assert(!err, err);
setTimeout(function() {
limiter({params: {username: "super"}}, null, function (err) {
assert(!err, err);
done();
});
}, 25);
});
});
it("Should work with many requests", function (done) {
var MAX_REQUESTS = 5;
var limiter = ratelimit("username", 10, MAX_REQUESTS);
var successfulRequests = 0;
async.times(10, function(n, next) {
limiter({params: {username: "super"}}, null, function (err) {
if (err) return next(err);
successfulRequests++;
next();
});
}, function (err) {
assert.equal(successfulRequests, MAX_REQUESTS);
setTimeout(function() {
limiter({params: {username: "super"}}, null, function (err) {
assert(!err, err);
done();
});
}, 25);
});
});
it("Should expire keys at the correct times", function (done) {
var limiter = ratelimit("username", 50, 2);
async.series([
function(next) {
limiter({params: {username: "mario"}}, null, function(err) {
assert(!err, err);
setTimeout(next, 25);
});
},
function (next) {
limiter({params: {username: "mario"}}, null, function(err) {
assert(!err, err);
setTimeout(next, 40);
});
},
function (next) {
limiter({params: {username: "mario"}}, null, function(err) {
assert(!err, err);
limiter({params: {username: "mario"}}, null, function(err) {
assert(err);
assert.equal(err.code, 429);
setTimeout(next, 20);
});
});
},
function (next) {
limiter({params: {username: "mario"}}, null, function(err) {
assert(!err, err);
next();
});
}
], done);
});
});

4
node_modules/c9/scm_url_parse.js wygenerowano vendored
Wyświetl plik

@ -13,6 +13,7 @@ define(function(require, exports, module) {
"bitbucket.org": "bitbucket",
"github.com": "github",
"source.developers.google.com": "google",
"gitlab.com": "gitlab",
};
var defaultProvider = "unknown";
@ -75,6 +76,9 @@ define(function(require, exports, module) {
case "bitbucket":
scm = parsed.pathname.match(/\.git$/) ? "git": "hg";
break;
case "gitlab":
scm = "git";
break;
default:
scm = parsed.pathname.match(/\.git$/) ? "git": "hg";
}

31
node_modules/c9/scm_url_parse_test.js wygenerowano vendored
Wyświetl plik

@ -19,21 +19,21 @@ describe(__filename, function() {
var url = parse("git@github.com:fjakobs/lispjs.git");
assert.equal(url.scm, "git");
assert.equal(url.protocol, "ssh:");
assert.equal(url.provider, "github");
assert.equal(url.auth, "git");
assert.equal(url.hostname, "github.com");
assert.equal(url.pathname, "fjakobs/lispjs.git");
done();
}),
it("should parse git url", function(done) {
var url = parse("git://github.com/fjakobs/lispjs.git");
assert.equal(url.scm, "git");
assert.equal(url.protocol, "git:");
assert.equal(url.provider, "github");
assert.equal(url.hostname, "github.com");
assert.equal(url.pathname, "fjakobs/lispjs.git");
done();
}),
it("should parse https url", function(done) {
@ -41,6 +41,7 @@ describe(__filename, function() {
assert.equal(url.protocol, "https:");
assert.equal(url.scm, "git");
assert.equal(url.auth, "fjakobs");
assert.equal(url.provider, "github");
assert.equal(url.hostname, "github.com");
assert.equal(url.pathname, "fjakobs/lispjs.git");
done();
@ -52,6 +53,7 @@ describe(__filename, function() {
assert.equal(url.protocol, "ssh:");
assert.equal(url.scm, "git");
assert.equal(url.auth, "git");
assert.equal(url.provider, "bitbucket");
assert.equal(url.hostname, "bitbucket.org");
assert.equal(url.pathname, "Richard/expressling.git");
done();
@ -61,12 +63,13 @@ describe(__filename, function() {
var url = parse("ssh://hg@bitbucket.org/fjakobs/juhu");
assert.equal(url.protocol, "ssh:");
assert.equal(url.scm, "hg");
assert.equal(url.provider, "bitbucket");
assert.equal(url.hostname, "bitbucket.org");
assert.equal(url.pathname, "fjakobs/juhu");
done();
});
it("should parse github URL without .git", function(done) {
it("should parse Github url without .git", function(done) {
var url = parse("https://github.com/arunoda/meteor-streams");
assert.equal(url.protocol, "https:");
assert.equal(url.scm, "git");
@ -76,7 +79,27 @@ describe(__filename, function() {
done();
});
it("Should refuse a git url with dangerous shell chars in it", function() {
it("should parse Gitlab url", function(done) {
var url = parse("git@gitlab.com:bdewachter/testfiles.git");
assert.equal(url.scm, "git");
assert.equal(url.protocol, "ssh:");
assert.equal(url.provider, "gitlab");
assert.equal(url.hostname, "gitlab.com");
assert.equal(url.pathname, "bdewachter/testfiles.git");
done();
}),
it("should parse Gitlab url without .git", function(done) {
var url = parse("https://gitlab.com/bdewachter/testfiles.git");
assert.equal(url.protocol, "https:");
assert.equal(url.scm, "git");
assert.equal(url.provider, "gitlab");
assert.equal(url.hostname, "gitlab.com");
assert.equal(url.pathname, "bdewachter/testfiles.git");
done();
});
it("should refuse a git url with dangerous shell chars in it", function() {
var validUrls = [
"https://github.com/arunoda/meteor-streams",
"https://fjakobs@github.com/fjakobs/lispjs.git",

Wyświetl plik

@ -11,7 +11,13 @@ module.exports = function startup(options, imports, register) {
set: sessionStore.set.bind(sessionStore),
destroy: sessionStore.destroy.bind(sessionStore),
regenerate: sessionStore.regenerate.bind(sessionStore),
createSession: sessionStore.createSession.bind(sessionStore)
createSession: sessionStore.createSession.bind(sessionStore),
set generate(fn) {
sessionStore.generate = fn;
},
get generate() {
return sessionStore.generate;
}
}
});
};

Wyświetl plik

@ -39,7 +39,7 @@ module.exports = function setup(mount, vfs, mountOptions) {
if (path) {
entry.href = path + entry.name;
var mime = entry.linkStat ? entry.linkStat.mime : entry.mime;
if (mime && mime.match(/(directory|folder)$/)) {
if (/(directory|folder)$/.test(mime)) {
entry.href += "/";
}
}

12
node_modules/vfs-local/localfs.js wygenerowano vendored
Wyświetl plik

@ -9,7 +9,15 @@ var pathBasename = require("path").basename;
var dirname = require("path").dirname;
var basename = require("path").basename;
var Stream = require("stream").Stream;
var getMime = require("simple-mime")("application/octet-stream");
var getMime = (function(simpleMime) {
// workaround for a bug in simple-mime
return function(path) {
var mime = simpleMime(path);
if (typeof mime != "string")
return "application/octet-stream"
return mime;
}
})(require("simple-mime")());
var vm = require("vm");
var exists = fs.exists || require("path").exists;
var crypto = require("crypto");
@ -2094,7 +2102,7 @@ module.exports = function setup(fsOptions) {
// Kill the session with the same name before starting a new one
if (options.kill) {
session = sessions[options.session];
if (session)
if (session && session.pty)
session.pty.kill();
if (!options.command)

Wyświetl plik

@ -1,7 +1,7 @@
{
"name": "c9",
"description": "New Cloud9 Client",
"version": "3.1.2288",
"version": "3.1.2576",
"author": "Ajax.org B.V. <info@ajax.org>",
"private": true,
"main": "bin/c9",
@ -44,6 +44,9 @@
"chai": "~1.5.0",
"mocha": "1.8.2"
},
"scripts": {
"start": "node server.js"
},
"devDependencies": {},
"licenses": [],
"bundledDependencies": [
@ -55,7 +58,7 @@
"c9"
],
"c9plugins": {
"c9.ide.language": "#ebc064ef16",
"c9.ide.language": "#79bcb2fe06",
"c9.ide.language.core": "#undefined",
"c9.ide.language.css": "#be07d72209",
"c9.ide.language.generic": "#3949510863",
@ -64,16 +67,16 @@
"c9.ide.language.javascript": "#e626169643",
"c9.ide.language.javascript.immediate": "#c8b1e5767a",
"c9.ide.language.javascript.eslint": "#4de5457db1",
"c9.ide.language.javascript.tern": "#b55d0069bb",
"c9.ide.language.javascript.tern": "#64ab01f271",
"c9.ide.language.javascript.infer": "#18acb93a3a",
"c9.ide.language.jsonalyzer": "#4b329741b1",
"c9.ide.language.codeintel": "#253ae15f5e",
"c9.ide.collab": "#cd36cae90c",
"c9.ide.language.jsonalyzer": "#d8183d84b4",
"c9.ide.language.codeintel": "#fc867feec4",
"c9.ide.collab": "#cfbf987438",
"c9.ide.local": "#10eb45842a",
"c9.ide.find": "#e33fbaed2f",
"c9.ide.find.infiles": "#c0a13737ef",
"c9.ide.find.infiles": "#bd34c29373",
"c9.ide.find.replace": "#810ebf8bfb",
"c9.ide.run.debug": "#ef40edcc3f",
"c9.ide.run.debug": "#94a48978bf",
"c9.automate": "#47e2c429c9",
"c9.ide.ace.emmet": "#6dc4585e02",
"c9.ide.ace.gotoline": "#a8ff07c8f4",
@ -90,23 +93,23 @@
"c9.ide.format": "#5ec97fb083",
"c9.ide.help.support": "#932fbb3743",
"c9.ide.imgeditor": "#612e75ef4f",
"c9.ide.immediate": "#19758abe08",
"c9.ide.installer": "#1232d4e179",
"c9.ide.language.python": "#330b80e3b2",
"c9.ide.immediate": "#0e0c18066c",
"c9.ide.installer": "#b2e4ba0a92",
"c9.ide.language.python": "#aff0772c78",
"c9.ide.language.go": "#6ce1c7a7ef",
"c9.ide.mount": "#4c39359b87",
"c9.ide.navigate": "#0b7ec7936c",
"c9.ide.mount": "#6ddfd05db3",
"c9.ide.navigate": "#5d5707058c",
"c9.ide.newresource": "#981a408a7b",
"c9.ide.openfiles": "#2ae85a9e33",
"c9.ide.preview": "#5f5fff0185",
"c9.ide.preview.browser": "#897177be7f",
"c9.ide.preview.markdown": "#c3174d86e0",
"c9.ide.pubsub": "#a85fb27eca",
"c9.ide.readonly": "#719881e192",
"c9.ide.pubsub": "#99b7289040",
"c9.ide.readonly": "#cfd951ec16",
"c9.ide.recentfiles": "#7c099abf40",
"c9.ide.remote": "#301d2ab519",
"c9.ide.processlist": "#2b12cd1bdd",
"c9.ide.run": "#6bd4996a4e",
"c9.ide.run": "#d661a7b847",
"c9.ide.run.build": "#0598fff697",
"c9.ide.run.debug.xdebug": "#9956689819",
"c9.ide.save": "#25a63f31e2",

Wyświetl plik

@ -0,0 +1,86 @@
/**
* Server-side support for A/B testing experiments.
*
* Note that this plugin demands users and user IDs for most of its API,
* where this is optional in the client-side implementation.
*/
main.consumes = ["analytics"];
main.provides = ["abtesting"];
module.exports = main;
function main(options, imports, register) {
var analytics = imports["analytics"];
var outplan = require("outplan");
var MS_PER_DAY = 1000 * 60 * 60 * 24;
outplan.configure({
logFunction: function(e) {
var label = e.name + " - " + e.event;
analytics.track(label, { variation: e.params.name });
}
});
function create(name, choices, options) {
return outplan.create(name, choices, options);
}
function expose(experimentName, userId, options) {
return outplan.expose(experimentName, userId, options);
}
function isUserCreatedAfter(experimentDate, user) {
if (!user || !user.date_add)
throw new Error("Expected: user");
var diffDays = (experimentDate - Date.now()) / MS_PER_DAY;
if (diffDays > 20) {
// Sanity check: new Date() takes zero-based month argument, one-based day argument
throw new Error("Passed a date far in the future to isUserCreatedAfter()");
}
return user.date_add > experimentDate;
}
register(null, {
"abtesting": {
/**
* Create a new experiment. Alias for require("outplan").create()
*
* @param {String} name
* The name of the experiment.
* @param {String[]|Object[]} choices
* A list of variations, e.g. ["A", "B"],
* or variation objects, e.g. [{ name: "A", color: "#AAA" }, { name: "B", color: "#BBB" }]
* @param {Object} [option]
* Options for the experiment. This may also include
* arguments for the distribution operator, e.g. weight.
* @param {Function} [options.operator]
* The distribution operator, e.g. outplan.WeightedChoice.
*/
create: create,
/**
* Get the selected variation of an experiment, and call the log function with
* an "expose" event to track its exposure.
*
* @param {String} name The experiment name.
* @param {Number} userId A unique identifier for the current user.
* @param {Object} [options] Options
* @param {Boolean} [options.log=true] Whether to log an "exposure event"
*/
expose: expose,
/**
* Helper to determine if the current user was created after the start of an experiment.
*
* @throws {Error} when a date in the future (~20 days from now) is passed.
* This error is thrown as a sanity check to make sure `new Date()`
* is called with a zero-based month argument (and a one-based day).
*
* @param {Date} experimentDate
* @param {Object} user A user object
* @param {Number} user.date_add
*/
isUserCreatedAfter: isUserCreatedAfter,
}
});
}

Wyświetl plik

@ -30,85 +30,43 @@ define(function(require, exports, module) {
return '"' + name + '"';
};
var SupportedIcons = {
"c9search": "page_white_magnify",
"js": "page_white_code",
"jsx": "page_white_code_red",
"ts": "page_white_code",
"tsx": "page_white_code_red",
"json": "page_white_code",
"css": "css",
"scss": "css",
"sass": "css",
"less": "css",
"xml": "page_white_code_red",
"svg": "page_white_picture",
"php": "page_white_php",
"phtml": "page_white_php",
"html": "html",
"xhtml": "html",
"coffee": "page_white_cup",
"py": "page_white_code",
"go": "page_white_code",
"java": "page_white_cup",
"logic": "logiql",
"ru": "page_white_ruby",
"gemspec": "page_white_ruby",
"rake": "page_white_ruby",
"rb": "page_white_ruby",
"c": "page_white_c",
"cc": "page_white_c",
"cpp": "page_white_cplusplus",
"cxx": "page_white_c",
"h": "page_white_h",
"hh": "page_white_h",
"hpp": "page_white_h",
"bmp": "image",
"djv": "image",
"djvu": "image",
"gif": "image",
"ico": "image",
"jpeg": "image",
"jpg": "image",
"pbm": "image",
"pgm": "image",
"png": "image",
"pnm": "image",
"ppm": "image",
"psd": "image",
"svgz": "image",
"tif": "image",
"tiff": "image",
"xbm": "image",
"xpm": "image",
"pdf": "page_white_acrobat",
"clj": "page_white_code",
"ml": "page_white_code",
"mli": "page_white_code",
"cfm": "page_white_coldfusion",
"sql": "page_white_database",
"db": "page_white_database",
"sh": "page_white_wrench",
"bash": "page_white_wrench",
"xq": "page_white_code",
"xz": "page_white_zip",
"gz": "page_white_zip",
"bz": "page_white_zip",
"zip": "page_white_zip",
"tar": "page_white_zip",
"rar": "page_white_compressed",
"exe": "page_white_swoosh",
"o": "page_white_swoosh",
"lnk": "page_white_swoosh",
"txt": "page_white_text",
"settings": "page_white_gear",
"run": "page_white_gear",
"build": "page_white_gear",
"gitignore": "page_white_gear",
"profile": "page_white_gear",
"bashrc": "page_white_gear",
var SupportedIcons = (function() {
var extToClass = Object.create(null);
var classToExt = {
"page_white_magnify": "c9search",
"page_white_code": ["clj", "go", "js", "json", "ml", "mli", "py", "ts", "xq"],
"page_white_code_red": ["jsx", "tsx", "xml"],
"css": ["css", "less", "sass", "scss"],
"page_white_picture": "svg",
"page_white_php": ["php", "phtml"],
"html": ["html", "xhtml"],
"page_white_cup": ["coffee", "java"],
"logiql": "logic",
"page_white_ruby": ["gemspec", "rake", "rb", "ru"],
"page_white_c": ["c", "cc", "cxx"],
"page_white_cplusplus": "cpp",
"page_white_h": ["h", "hh", "hpp"],
"image": ["bmp", "djv", "djvu", "gif", "ico", "jpeg", "jpg", "pbm", "pgm", "png", "pnm", "ppm", "psd", "svgz", "tif", "tiff", "xbm", "xpm"],
"page_white_acrobat": "pdf",
"page_white_coldfusion": "cfm",
"page_white_database": ["db", "sql"],
"page_white_wrench": ["bash", "sh"],
"page_white_zip": ["bz", "gz", "tar", "xz", "zip"],
"page_white_compressed": "rar",
"page_white_swoosh": ["exe", "lnk", "o", "bin", "class"],
"page_white_text": "txt",
"page_white_gear": ["bashrc", "build", "gitignore", "profile", "run", "settings"]
};
Object.keys(classToExt).forEach(function(k) {
var exts = classToExt[k];
if (typeof exts == "string")
exts = [exts];
exts.forEach(function(ext) {
extToClass[ext] = k;
});
});
return extToClass;
})();
plugin.getFileIcon = function(name) {
var icon = "page_white_text";
var ext;

Wyświetl plik

@ -13,7 +13,7 @@
</p>
<a href="http://status.c9.io">Status Page</a> |
<a href="mailto:support@c9.io">Support</a> |
<a href="https://c9.io/support">Support</a> |
<a href="https://c9.io/dashboard.html">Dashboard</a> |
<a href="https://c9.io">Home</a>
</div>

Wyświetl plik

@ -13,7 +13,7 @@
</p>
<a href="http://status.c9.io">Status Page</a> |
<a href="mailto:support@c9.io">Support</a> |
<a href="https://c9.io/support">Support</a> |
<a href="https://c9.io/dashboard.html">Dashboard</a> |
<a href="https://c9.io/">Home</a>
</div>

Wyświetl plik

@ -30,7 +30,7 @@
<% } %>
<a href="http://status.c9.io">Status Page</a> |
<a href="mailto:support@c9.io">Support</a> |
<a href="https://c9.io/support">Support</a> |
<a href="https://c9.io/dashboard.html">Dashboard</a> |
<a href="https://c9.io/">Home</a>
</div>

Wyświetl plik

@ -29,7 +29,7 @@
<% } %>
<a href="http://status.c9.io">Status Page</a> |
<a href="mailto:support@c9.io">Support</a> |
<a href="https://c9.io/support">Support</a> |
<a href="https://c9.io/dashboard.html">Dashboard</a> |
<a href="https://c9.io/">Home</a>
</div>

Wyświetl plik

@ -27,7 +27,7 @@
<% } %>
<a href="http://status.c9.io">Status Page</a> |
<a href="mailto:support@c9.io">Support</a> |
<a href="https://c9.io/support">Support</a> |
<a href="https://c9.io/dashboard.html">Dashboard</a> |
<a href="https://c9.io">Home</a>
</div>

Wyświetl plik

@ -369,10 +369,10 @@ define(function(require, exports, module) {
createNode(dir, {mime: "folder"});
});
if (!dirsToMake[0])
var node = dirsToMake[0] && findNode(dirsToMake[0]);
if (!node)
return;
var node = findNode(dirsToMake[0]);
e.undo = function(){
dirsToMake.forEach(function(dir) {
var node = findNode(dir);
@ -570,7 +570,7 @@ define(function(require, exports, module) {
node = {label: p, path: subPath, status: "pending", isFolder: true};
// TODO filter hidden files in getChildren instead.
if (!showHidden && isFileHidden(p)) {
orphans[node.path] = path;
orphans[node.path] = node;
return;
}
} else if (updateNode) {
@ -707,7 +707,7 @@ define(function(require, exports, module) {
status: "pending",
className: "projectRoot",
isEditable: false,
map: {}
map: Object.create(null)
};
var root = {};
root.map = Object.create(null);

Wyświetl plik

@ -0,0 +1 @@
e

Wyświetl plik

@ -0,0 +1 @@
v

Wyświetl plik

@ -0,0 +1 @@
i

Wyświetl plik

@ -0,0 +1 @@
l

Wyświetl plik

@ -0,0 +1,105 @@
/**
* Client-side support for A/B testing experiments.
*/
define(function(require, exports, module) {
"use strict";
main.consumes = ["Plugin", "info", "c9.analytics"];
main.provides = ["abtesting"];
return main;
function main(options, imports, register) {
var Plugin = imports.Plugin;
var plugin = new Plugin("Ajax.org", main.consumes);
var info = imports.info;
var analytics = imports["c9.analytics"];
var outplan = require("outplan");
var MS_PER_DAY = 1000 * 60 * 60 * 24;
var userId;
plugin.on("load", function() {
userId = info.getUser().id;
outplan.configure({
logFunction: function(e) {
var label = e.name + " - " + e.event;
analytics.track(label, { variation: e.params.name });
}
});
});
plugin.on("unload", function() {
userId = undefined;
});
function create(name, choices, options) {
var experiment = outplan.create(name, choices, options);
experiment.expose = expose.bind(null, name);
return experiment;
}
function expose(experimentName, overrideUserId, options) {
if (overrideUserId && typeof overrideUserId === "object")
return expose(experimentName, null, options);
return outplan.expose(experimentName, overrideUserId == null ? userId : overrideUserId, options);
}
function isUserCreatedAfter(experimentDate) {
var diffDays = (experimentDate - Date.now()) / MS_PER_DAY;
if (diffDays > 20) {
// Sanity check: new Date() takes zero-based month argument, one-based day argument
throw new Error("Passed a date far in the future to isUserCreatedAfter()");
}
return info.getUser().date_add > experimentDate;
}
/**
* Support for A/B testing experiments.
*/
plugin.freezePublicAPI({
/**
* Create a new experiment. Alias for require("outplan").create()
*
* @param {String} name
* The name of the experiment.
* @param {String[]|Object[]} choices
* A list of variations, e.g. ["A", "B"],
* or variation objects, e.g. [{ name: "A", color: "#AAA" }, { name: "B", color: "#BBB" }]
* @param {Object} [option]
* Options for the experiment. This may also include
* arguments for the distribution operator, e.g. weight.
* @param {Function} [options.operator]
* The distribution operator, e.g. outplan.WeightedChoice.
*/
create: create,
/**
* Get the selected variation of an experiment, and call the log function with
* an "expose" event to track its exposure.
*
* @param {String} name The experiment name.
* @param {Number} [userId] A unique identifier for the current user.
* @param {Object} [options] Options
* @param {Boolean} [options.log=true] Whether to log an "exposure event"
*/
expose: expose,
/**
* Helper to determine if the current user was created after the start of an experiment.
*
* @throws {Error} when a date in the future (~20 days from now) is passed.
* This error is thrown as a sanity check to make sure `new Date()`
* is called with a zero-based month argument (and a one-based day).
*
* @param {Date} experimentDate
*/
isUserCreatedAfter: isUserCreatedAfter,
});
register(null, {
"abtesting": plugin
});
}
});

Wyświetl plik

@ -976,11 +976,12 @@ define(function(require, exports, module) {
c = 0;
addEditorMenu("Edit/Code Folding/Fold", "fold"),
addEditorMenu("Edit/Code Folding/Toggle Fold", "toggleFoldWidget"),
addEditorMenu("Edit/Code Folding/Unfold", "unfold"),
menus.addItemByPath("Edit/Code Folding/~", new ui.divider(), c += 100, handle);
addEditorMenu("Edit/Code Folding/Fold All", "foldall"),
addEditorMenu("Edit/Code Folding/Fold Other", "foldOther");
addEditorMenu("Edit/Code Folding/Fold All", "foldall");
addEditorMenu("Edit/Code Folding/Unfold All", "unfoldall");
c = 0;

Wyświetl plik

@ -52,20 +52,18 @@ define(function(require, exports, module) {
if (notSupported(type))
return;
type = convertType(type);
if (nativeObject) {
nativeObject.setData(type, data);
handleClipboardData(nativeObject, type, data);
return true;
}
var setData = function(e) {
if (list) {
list.forEach(function(type) {
e.clipboardData.setData(type, data);
handleClipboardData(e.clipboardData, type, data);
});
}
e.clipboardData.setData(type, data);
handleClipboardData(e.clipboardData, type, data);
e.preventDefault();
e.stopPropagation();
@ -83,16 +81,14 @@ define(function(require, exports, module) {
if (notSupported(type))
return;
type = convertType(type);
if (!full && nativeObject)
return nativeObject.getData(type);
return handleClipboardData(nativeObject, type);
var data;
var getData = function(e) {
data = full
? e.clipboardData
: e.clipboardData.getData(type);
: handleClipboardData(e.clipboardData, type);
e.preventDefault();
e.stopPropagation();
};
@ -120,8 +116,22 @@ define(function(require, exports, module) {
return !/text($|\/)/.test(type);
}
function convertType(type) {
return document.all ? "Text" : type;
function handleClipboardData(clipboardData, type, data, forceIEMime) {
if (!clipboardData)
return;
// using "Text" doesn't work on old webkit but ie needs it
var mime = forceIEMime ? "Text" : type;
try {
if (data) {
// Safari 5 has clipboardData object, but does not handle setData()
return clipboardData.setData(mime, data) !== false;
} else {
return clipboardData.getData(mime);
}
} catch(e) {
if (!forceIEMime)
return handleClipboardData(clipboardData, type, data, true);
}
}
function wrap(obj) {

Wyświetl plik

@ -2,7 +2,7 @@ define(function(require, exports, module) {
"use strict";
main.consumes = [
"Plugin", "c9", "ui", "menus", "tree", "info", "vfs"
"Plugin", "c9", "ui", "menus", "tree", "info", "vfs", "preferences", "settings"
];
main.provides = ["download"];
return main;
@ -15,6 +15,11 @@ define(function(require, exports, module) {
var tree = imports.tree;
var vfs = imports.vfs;
var info = imports.info;
var prefs = imports.preferences;
var settings = imports.settings;
var SETTING_NAME = "downloadFilesAs";
var SETTING_PATH = "user/general/@" + SETTING_NAME;
/***** Initialization *****/
@ -40,6 +45,28 @@ define(function(require, exports, module) {
onclick: download
}), 140, plugin);
});
// Preferences
prefs.add({
"General" : {
"Tree & Navigate" : {
"Download Files As" : {
type: "dropdown",
path: SETTING_PATH,
items: [
{ caption : "auto", value : "auto" },
{ caption : "tar.gz", value : "tar.gz" },
{ caption : "zip", value : "zip" }
],
position: 5000
}
}
}
}, plugin);
settings.on("read", function() {
settings.setDefaults("user/general", [[SETTING_NAME, "auto"]]);
}, plugin);
}
function download() {
@ -55,7 +82,7 @@ define(function(require, exports, module) {
if (node.isFolder && node.path == "/")
downloadProject();
else if (paths.length > 1)
vfs.download(paths);
downloadPaths(paths);
else if (node.isFolder)
downloadFolder(node.path);
else
@ -64,17 +91,32 @@ define(function(require, exports, module) {
}
function downloadProject() {
vfs.download("/", info.getWorkspace().name + ".tar.gz");
vfs.download("/", info.getWorkspace().name + getArchiveFileExtension());
}
function downloadPaths(paths) {
vfs.download(paths, info.getWorkspace().name + getArchiveFileExtension());
}
function downloadFolder(path) {
vfs.download(path.replace(/\/*$/, "/"));
var withTrailingSlash = path.replace(/\/*$/, "/");
var parts = withTrailingSlash.split("/");
var lastPart = parts[parts.length - 2];
vfs.download(withTrailingSlash, lastPart + getArchiveFileExtension());
}
function downloadFile(path) {
vfs.download(path.replace(/\/*$/, ""), null, true);
}
function getArchiveFileExtension() {
var downloadFilesAs = settings.get(SETTING_PATH);
if (downloadFilesAs === 'auto' || !downloadFilesAs) {
downloadFilesAs = /Win/.test(navigator.platform) ? 'zip' : 'tar.gz';
}
return '.' + downloadFilesAs;
}
/***** Lifecycle *****/
plugin.on("load", function(){

Wyświetl plik

@ -1,26 +0,0 @@
/**
* Dummy implementation of experiments.
*/
"use strict";
plugin.consumes = [];
plugin.provides = ["experiment"];
module.exports = plugin;
function plugin(options, imports, register) {
register(null, {
"experiment": {
configure: function() {},
onStart: function() {
var chain = {
variation: function() {
return chain;
}
};
return chain;
}
}
});
}

Wyświetl plik

@ -33,6 +33,10 @@
padding-left: 33px !important;
}
.c9-menu-btnEmpty {
padding-left: 9px;
}
.c9-menu-btnDown:not(.c9-menu-btnmenuDown){
box-shadow: none;
border: 0;

Wyświetl plik

@ -92,9 +92,9 @@ define(function(require, exports, module) {
delete extraPackages[config.packagePath];
}
});
Object.keys(extraPackages).forEach(function(extraConfig) {
Object.keys(extraPackages).forEach(function(packagePath) {
console.warn("[c9.ide.loader] Package "
+ extraConfig.packagePath + " should be installed, according "
+ packagePath + " should be installed, according "
+ "to the database, but was not found on the filesystem. "
+ "Try reinstalling it.");
});

Wyświetl plik

@ -41,6 +41,7 @@ define(function(require, exports, module) {
ui: "lib/ui",
c9: "lib/c9",
frontdoor: "lib/frontdoor",
outplan: "lib/outplan/dist/outplan",
};
if (whitelist === "*") {
@ -70,6 +71,7 @@ define(function(require, exports, module) {
"ui",
"emmet",
"frontdoor",
"outplan",
"mocha", // TESTING
"chai", // TESTING
].forEach(function(name) {
@ -86,9 +88,11 @@ define(function(require, exports, module) {
}]);
statics.addStatics(externalPlugins.map(function(plugin) {
if (typeof plugin == "string")
plugin = { path: plugin, mount: plugin};
return {
path: __dirname + "/../../node_modules/" + plugin,
mount: "/plugins/" + plugin
path: __dirname + "/../../node_modules/" + plugin.path,
mount: "/plugins/" + plugin.mount
};
}));

Wyświetl plik

@ -155,6 +155,11 @@ define(function(require, exports, module) {
str += this.getLine(end, newLineChar).substring(0, range.end.column);
return str;
};
session.doc.getValue = function() {
return this.getTextRange(new Range(0, 0, this.getLength(), Number.MAX_VALUE));
};
session.$computeWidth =
session.getScreenWidth = function () {
return this.term.cols;

Wyświetl plik

@ -537,7 +537,7 @@ define(function(require, exports, module) {
if (err) {
var message = err.message;
if (err.code == "EEXIST")
message = "File " + path + " already exists.";
message = "File " + newpath + " already exists.";
return showError(message);
}
if (dirname(newpath) != dirname(path))

Wyświetl plik

@ -91,11 +91,13 @@ apf.codebox = function(struct, tagName) {
var checkInitial = function() {
var value = ace.getValue();
if (value && ace.renderer.initialMessageNode) {
ace.renderer.off("afterRender", checkInitial);
dom.removeCssClass(ace.container, "ace_initialMsg");
ace.renderer.scroller.removeChild(ace.renderer.initialMessageNode);
ace.renderer.initialMessageNode = null;
}
else if (!value && !ace.renderer.initialMessageNode) {
ace.renderer.on("afterRender", checkInitial);
dom.addCssClass(ace.container, "ace_initialMsg");
var el = document.createElement("div");
el.className = "tb_textboxInitialMsg";
@ -103,7 +105,6 @@ apf.codebox = function(struct, tagName) {
ace.renderer.initialMessageNode = el;
ace.renderer.scroller.appendChild(ace.renderer.initialMessageNode);
}
};
ace.on("input", checkInitial);

Wyświetl plik

@ -0,0 +1,18 @@
"use strict";
var HttpError = require("http-error");
function isDotFile(path){
return /^[.]/.test(path) ;
}
module.exports = function blockDotFiles(req, res, next){
if (!req.params.path) return next();
var pathParts = req.params.path.split("/");
if (pathParts.some(isDotFile))
return next(new HttpError.NotFound("File does not exist"));
next();
};

Wyświetl plik

@ -0,0 +1,67 @@
"use struct";
"use server";
require("c9/inline-mocha")(module);
var blockDotFiles = require("./block-dot-files");
var async = require("async");
var format = require("util").format;
var assert = require("assert-diff");
var HttpError = require("http-error");
describe(__filename, function() {
it("should block acess to files starting with a dot", function(done) {
var err404 = new HttpError.NotFound("File does not exist");
var cases = [
{
label: "Block ../",
path: "../../../../etc/password",
err: err404
},
{
label: "Block anything starting with a .",
path: ".ssh/id_rsa",
err: err404
},
{
label: "Block anything starting with a .",
path: ".git/config",
err: err404
},
{
label: "Block anything with a . in the start of a pathpart",
path: "deep/.git/config",
err: err404
},
{
label: "Don't block normal paths",
path: "one/two/three.txt",
},
{
label: "Don't block empty paths",
path: "",
},
{
label: "Don't choke on undefineds",
},
];
async.each(cases, function(testCase, next) {
var mockReq = {
params: {
path: testCase.path
}
};
blockDotFiles(mockReq, null, function(err) {
assert.deepEqual(err, testCase.err, testCase.label);
next();
});
}, done);
});
});

Wyświetl plik

@ -52,7 +52,7 @@ define(function(require, exports, module) {
}, [
requestTimeout(15*60*1000),
require("./lib/middleware/sanitize-path-param"),
ratelimit("username", 20 * 1000, 1000),
require("./lib/middleware/block-dot-files"),
handler.getProjectSession(),
handler.getRole(db),
handler.getProxyUrl(function() {

Wyświetl plik

@ -12,7 +12,7 @@
</p>
<a href="http://status.c9.io">Status Page</a> |
<a href="mailto:support@c9.io">Support</a> |
<a href="https://c9.io/support">Support</a> |
<a href="https://c9.io/dashboard.html">Dashboard</a> |
<a href="https://c9.io">Home</a>
</div>

Wyświetl plik

@ -17,7 +17,7 @@ require("amd-loader");
var build, options, pathConfig;
describe("The Module", function(){
describe("The build module", function(){
this.timeout(60000);
beforeEach(function(next) {
@ -63,7 +63,7 @@ describe("The Module", function(){
});
});
it("test compile less", function(done) {
it("should compile less", function(done) {
build.buildSkin("ssh", "dark", pathConfig, function(err, result) {
if (err) return done(err);
@ -71,6 +71,28 @@ describe("The Module", function(){
assert(code);
done(err);
});
});
it("should remove comments", function(done) {
var removeLicenceComments = require("architect-build/module-deps").removeLicenceComments;
function remove(src) {
var module = { source: "" + src, path: ".js" };
removeLicenceComments(module);
return module.source;
}
assert.equal(remove("" + function() {
// 1
var a;
/***/ // hello
var x; // not removed
/* asd
*/
x += "he/*ll*/o" + a;
}) , function() {
var a;
var x; // not removed
x += "he/*ll*/o" + a;
});
done();
});
});

Wyświetl plik

@ -20,6 +20,8 @@ define(function (require, exports, module) {
if (loaded) return false;
loaded = true;
if (c9.readonly) return false;
ext.loadRemotePlugin("log", {
code: require("text!./log-service.js"),
redefine: true

Wyświetl plik

@ -1,7 +1,7 @@
define(function(require, exports, module) {
"use strict";
main.consumes = ["Plugin", "ext", "c9", "vfs", "metrics"];
main.consumes = ["Plugin", "ext", "c9", "vfs"];
main.provides = ["vfs.ping"];
return main;
@ -9,7 +9,6 @@ define(function(require, exports, module) {
var Plugin = imports.Plugin;
var c9 = imports.c9;
var ext = imports.ext;
var metrics = imports.metrics;
/***** Initialization *****/
@ -17,15 +16,18 @@ define(function(require, exports, module) {
var api;
var loaded = false;
function load(){
if (loaded) return;
function load(oldVfs) {
if (loaded && !oldVfs) return;
loaded = true;
ext.loadRemotePlugin("ping", {
code: require("text!./ping-service.js"),
redefine: true
file: oldVfs ? undefined : "c9.vfs.client/ping-service.js",
code: oldVfs ? require("text!./ping-service.js") : undefined
}, function(err, remote) {
if (err)
if (!remote && !oldVfs)
return load(true);
if (!remote)
return console.error(err);
api = remote;

Wyświetl plik

@ -204,11 +204,12 @@ define(function(require, exports, module) {
function reconnectNow() {
reconnect(function(_err) {
connection.connect();
connection && connection.connect();
});
}
function reconnect(callback) {
if (!connection) return;
connection.socket.setSocket(null);
vfsEndpoint.get(protocolVersion, function(err, urls) {
@ -336,6 +337,11 @@ define(function(require, exports, module) {
plugin.on("unload", function(){
loaded = false;
if (consumer)
consumer.disconnect();
if (connection)
connection.disconnect();
id = null;
buffer = [];
region = null;
@ -346,6 +352,7 @@ define(function(require, exports, module) {
serviceUrl = null;
eioOptions = null;
consumer = null;
connection = null;
vfs = null;
showErrorTimer = null;
showErrorTimerMessage = null;

Wyświetl plik

@ -80,29 +80,50 @@ define(function(require, exports, module) {
});
}
else {
// TODO add support for downloding as zip on windows
// var cwd;
// var args = ["-r", "-"];
// paths.forEach(function(path) {
// if (!path) return;
// var dir = Path.dirname(path);
// if (!cwd) cwd = dir;
// var name = Path.relative(cwd, path);
// if (name[0] == "-") name = "./" + name;
// args.push(name);
// });
// vfs.spawn("zip", { args: args, cwd: cwd }
var executable, args, contentType;
var args = ["-zcf", "-"];
paths.forEach(function(path) {
if (/\.zip$/.test(filename)) {
executable = "zip";
args = ["-r", "-", "--"];
contentType = "application/zip"
}
else {
executable = "tar";
args = ["-zcf", "-", "--"];
contentType = "application/x-gzip"
}
// Find the longest common parent directory of all the paths.
var cwd = null;
paths.forEach(function (path) {
if (!path) return;
var dir = Path.dirname(path);
var name = Path.basename(path);
if (name[0] == "-")
name = "--add-file=" + name;
args.push("-C" + dir, name);
if (!cwd) {
cwd = dir;
}
else {
var relative = Path.relative(cwd, dir).split(Path.sep);
var i = 0;
while (relative[i] === '..') {
cwd = Path.resolve(cwd, '..');
i++;
}
}
});
vfs.spawn("tar", { args: args }, function (err, meta) {
paths.forEach(function(path) {
if (!path) return;
path = Path.relative(cwd, path);
// tar misinterprets the Windows path separator as an escape sequence, so use forward slash.
if (Path.sep === '\\') {
path = path.replace(/\\/g, '/');
}
args.push(path);
});
vfs.spawn(executable, {
args: args,
cwd: cwd
}, function (err, meta) {
if (err)
return next(err);
@ -114,7 +135,7 @@ define(function(require, exports, module) {
return;
res.writeHead(200, {
"Content-Type": "application/x-gzip",
"Content-Type": contentType,
"Content-Disposition": filenameHeader
});
res.write(data);
@ -133,16 +154,16 @@ define(function(require, exports, module) {
var err;
if (code == 127) {
err = new error.PreconditionFailed(
"Your instance seems to be missing the 'tar' utility\n" +
"Your instance seems to be missing the '" + executable + "' utility\n" +
"If you are using an SSH workspace, please do:\n" +
" 'sudo apt-get install tar'");
" 'sudo apt-get install " + executable + "'");
} else if (code) {
err = new error.InternalServerError(
"'tar' utility failed with exit code " + code +
"'" + executable + "' utility failed with exit code " + code +
" and stderr:/n'" + stderr + "'");
} else if (signal) {
err = new error.InternalServerError(
"'tar' utility was terminated by signal " + signal
"'" + executable + "' utility was terminated by signal " + signal
);
}

Wyświetl plik

@ -53,8 +53,9 @@ describe(__filename, function(){
describe("download", function() {
it("should download", function(next) {
it("should download as tar", function(next) {
tmp.dir({unsafeCleanup: true}, function(err, path) {
path = path.replace(/\w:/, '');
var filename = path + "/download.tar.gz";
var file = fs.createWriteStream(filename);
http.get("http://localhost:8787/?download=download.tar.gz", function(res) {
@ -77,21 +78,22 @@ describe(__filename, function(){
});
});
it("should download sub directory", function(next) {
it("should download sub directory as tar", function(next) {
tmp.dir({unsafeCleanup: true}, function(err, path) {
path = path.replace(/\w:/, '');
assert.equal(err, null);
var filename = path + "/download.tar.gz";
var file = fs.createWriteStream(filename);
http.get("http://localhost:8787/views?download=download.tar.gz", function(res) {
http.get("http://localhost:8787/test?download=download.tar.gz", function(res) {
res.pipe(file);
res.on("end", function() {
execFile("tar", ["-zxvf", filename, "views/status.html.ejs"], {cwd: path}, function(err) {
execFile("tar", ["-zxvf", filename, "test/dir1/testdata1.txt"], {cwd: path}, function(err) {
assert.equal(err, null);
assert.equal(
fs.readFileSync(__dirname + "/views/status.html.ejs", "utf8"),
fs.readFileSync(path + "/views/status.html.ejs", "utf8")
fs.readFileSync(__dirname + "/test/dir1/testdata1.txt", "utf8"),
fs.readFileSync(path + "/test/dir1/testdata1.txt", "utf8")
);
next();
});
@ -102,22 +104,180 @@ describe(__filename, function(){
it("should download without specifying a name", function(next) {
tmp.dir({unsafeCleanup: true}, function(err, path) {
path = path.replace(/\w:/, '');
assert.equal(err, null);
var filename = path + "/download.tar.gz";
var file = fs.createWriteStream(filename);
http.get("http://localhost:8787/views?download", function(res) {
http.get("http://localhost:8787/test?download", function(res) {
assert.equal(res.headers["content-type"], "application/x-gzip");
assert.equal(res.headers["content-disposition"], "attachment; filename*=utf-8''views.tar.gz");
assert.equal(res.headers["content-disposition"], "attachment; filename*=utf-8''test.tar.gz");
res.pipe(file);
res.on("end", function() {
execFile("tar", ["-zxvf", filename, "views/status.html.ejs"], {cwd: path}, function(err) {
execFile("tar", ["-zxvf", filename, "test/dir1/testdata1.txt"], {cwd: path}, function(err) {
assert.equal(err, null);
assert.equal(
fs.readFileSync(__dirname + "/views/status.html.ejs", "utf8"),
fs.readFileSync(path + "/views/status.html.ejs", "utf8")
fs.readFileSync(__dirname + "/test/dir1/testdata1.txt", "utf8"),
fs.readFileSync(path + "/test/dir1/testdata1.txt", "utf8")
);
next();
});
});
});
});
});
it("should download several files in same directory as tar", function(next) {
tmp.dir({unsafeCleanup: true}, function(err, path) {
path = path.replace(/\w:/, '');
assert.equal(err, null);
var filename = path + "/download.tar.gz";
var file = fs.createWriteStream(filename);
http.get("http://localhost:8787/test/dir2/testdata2a.txt,/test/dir2/testdata2b.txt?download=download.tar.gz", function(res) {
res.pipe(file);
res.on("end", function() {
execFile("tar", ["-zxvf", filename], {cwd: path}, function(err) {
assert.equal(err, null);
assert.equal(
fs.readFileSync(__dirname + "/test/dir2/testdata2a.txt", "utf8"),
fs.readFileSync(path + "/testdata2a.txt", "utf8")
);
assert.equal(
fs.readFileSync(__dirname + "/test/dir2/testdata2b.txt", "utf8"),
fs.readFileSync(path + "/testdata2b.txt", "utf8")
);
next();
});
});
});
});
});
it("should download several files in different directories as tar", function(next) {
tmp.dir({unsafeCleanup: true}, function(err, path) {
path = path.replace(/\w:/, '');
assert.equal(err, null);
var filename = path + "/download.tar.gz";
var file = fs.createWriteStream(filename);
http.get("http://localhost:8787/test/dir1/testdata1.txt,/test/dir2/testdata2a.txt?download=download.tar.gz", function(res) {
res.pipe(file);
res.on("end", function() {
execFile("tar", ["-zxvf", filename], {cwd: path}, function(err) {
assert.equal(err, null);
assert.equal(
fs.readFileSync(__dirname + "/test/dir1/testdata1.txt", "utf8"),
fs.readFileSync(path + "/dir1/testdata1.txt", "utf8")
);
assert.equal(
fs.readFileSync(__dirname + "/test/dir2/testdata2a.txt", "utf8"),
fs.readFileSync(path + "/dir2/testdata2a.txt", "utf8")
);
next();
});
});
});
});
});
it("should download as zip", function(next) {
tmp.dir({unsafeCleanup: true}, function(err, path) {
path = path.replace(/\w:/, '');
var filename = path + "/download.zip";
var file = fs.createWriteStream(filename);
http.get("http://localhost:8787/?download=download.zip", function(res) {
assert.equal(res.headers["content-type"], "application/zip");
assert.equal(res.headers["content-disposition"], "attachment; filename*=utf-8''download.zip");
res.pipe(file);
res.on("end", function() {
execFile("unzip", [filename, "c9.vfs.server/download.js"], {cwd: path}, function(err, stdout, stderr) {
assert.equal(err, null);
assert.equal(
fs.readFileSync(__dirname + "/download.js", "utf8"),
fs.readFileSync(path + "/c9.vfs.server/download.js", "utf8")
);
next();
});
});
});
});
});
it("should download sub directory as zip", function(next) {
tmp.dir({unsafeCleanup: true}, function(err, path) {
path = path.replace(/\w:/, '');
assert.equal(err, null);
var filename = path + "/download.zip";
var file = fs.createWriteStream(filename);
http.get("http://localhost:8787/test?download=download.zip", function(res) {
res.pipe(file);
res.on("end", function() {
execFile("unzip", [filename, "test/dir1/testdata1.txt"], {cwd: path}, function(err) {
assert.equal(err, null);
assert.equal(
fs.readFileSync(__dirname + "/test/dir1/testdata1.txt", "utf8"),
fs.readFileSync(path + "/test/dir1/testdata1.txt", "utf8")
);
next();
});
});
});
});
});
it("should download several files in same directory as zip", function(next) {
tmp.dir({unsafeCleanup: true}, function(err, path) {
path = path.replace(/\w:/, '');
assert.equal(err, null);
var filename = path + "/download.zip";
var file = fs.createWriteStream(filename);
http.get("http://localhost:8787/test/dir2/testdata2a.txt,/test/dir2/testdata2b.txt?download=download.zip", function(res) {
res.pipe(file);
res.on("end", function() {
execFile("unzip", [filename], {cwd: path}, function(err) {
assert.equal(err, null);
assert.equal(
fs.readFileSync(__dirname + "/test/dir2/testdata2a.txt", "utf8"),
fs.readFileSync(path + "/testdata2a.txt", "utf8")
);
assert.equal(
fs.readFileSync(__dirname + "/test/dir2/testdata2b.txt", "utf8"),
fs.readFileSync(path + "/testdata2b.txt", "utf8")
);
next();
});
});
});
});
});
it("should download several files in different directories as zip", function(next) {
tmp.dir({unsafeCleanup: true}, function(err, path) {
path = path.replace(/\w:/, '');
assert.equal(err, null);
var filename = path + "/download.zip";
var file = fs.createWriteStream(filename);
http.get("http://localhost:8787/test/dir1/testdata1.txt,/test/dir2/testdata2a.txt?download=download.zip", function(res) {
res.pipe(file);
res.on("end", function() {
execFile("unzip", [filename], {cwd: path}, function(err) {
assert.equal(err, null);
assert.equal(
fs.readFileSync(__dirname + "/test/dir1/testdata1.txt", "utf8"),
fs.readFileSync(path + "/dir1/testdata1.txt", "utf8")
);
assert.equal(
fs.readFileSync(__dirname + "/test/dir2/testdata2a.txt", "utf8"),
fs.readFileSync(path + "/dir2/testdata2a.txt", "utf8")
);
next();
});

Wyświetl plik

@ -0,0 +1 @@
test data 1

Wyświetl plik

@ -0,0 +1 @@
test data 2a

Wyświetl plik

@ -0,0 +1 @@
test data 2b

Wyświetl plik

@ -56,7 +56,6 @@ define(function(require, exports, module) {
projectDir: vfsOptions.projectDir,
extendDirectory: options.extendDirectory,
extendOptions: projectOptions.extendOptions,
extendToken: "not_needed",
collab: options.collab,
vfsOptions: vfsOptions,
public: true

Wyświetl plik

@ -24,7 +24,6 @@ function Vfs(vfs, master, options) {
this.public = options.public || false;
this.vfsOptions = options.vfsOptions || {};
this.pid = this.vfsOptions.pid;
var extendToken = options.extendToken;
this.homeDir = options.homeDir;
this.workspaceDir = options.projectDir;
@ -36,14 +35,12 @@ function Vfs(vfs, master, options) {
blocked: this.readonly,
extendDirectory: options.extendDirectory,
extendOptions: options.extendOptions,
extendToken: extendToken
});
this.vfsWorkspace = wrapVfs(vfs, {
root: this.workspaceDir,
readonly: this.readonly,
extendDirectory: options.extendDirectory,
extendOptions: options.extendOptions,
extendToken: extendToken
});
var vfsProxy = proxyVfs(Object.keys(this.vfsHome), this.vfsHome, this.vfsWorkspace);

Wyświetl plik

@ -8,7 +8,6 @@ module.exports = function(vfs, options) {
var methods = options.methods || Object.keys(vfs);
var readonly = "readonly" in options ? options.readonly : false;
var blocked = !!options.blocked;
var extendToken = options.extendToken;
var roMethods = {
resolve: 1,
@ -74,15 +73,23 @@ module.exports = function(vfs, options) {
options[key] = extendOptions[key];
}
if (options.code || options.stream) {
if (readonly && (!extendToken || extendToken !== options.extendToken))
return callback(new error.Forbidden("VFS extend: " + name + " with options 'stream' or 'code' not authorized in read only mode"));
else
return vfs.extend(name, options, callback);
if (readonly) {
var whitelist = {
"c9.ide.collab/server/collab-server.js": true,
"c9.ide.pubsub/pubsub-service.js": true,
"c9.vfs.client/ping-service.js": true,
};
if (!options.file || !whitelist[options.file])
return callback(new error.Forbidden("VFS extend: " + name + " is not authorized in read only mode"));
}
if (!options.file)
// localfs extend checks for file, then code, then stream
if (!options.file) {
if (options.code || options.stream)
return vfs.extend(name, options, callback);
return callback(new error.Forbidden("Option 'file' is missing"));
}
if (typeof options.file != "string")
return callback(new error.Forbidden("Invalid option 'file'"));

Wyświetl plik

@ -221,8 +221,6 @@ function plugin(options, imports, register) {
});
});
api.get("/api.json", {name: "api"}, frontdoor.middleware.describeApi(api));
// fake authentication
api.authenticate = api.authenticate || function() {
return function(req, res, next) {
@ -255,7 +253,7 @@ function plugin(options, imports, register) {
};
api.updatConfig = api.updatConfig || function(opts, params) {
var id = params.token;
opts.accessToken = opts.extendToken = id || "token";
opts.accessToken = id || "token";
var user = opts.extendOptions.user;
user.id = id || -1;
user.name = id ? "user" + id : "johndoe";

Wyświetl plik

@ -271,6 +271,7 @@
return cb();
setTimeout.paused = true;
window.app.services.vfs.connection.disconnect();
window.app.services["vfs.endpoint"].clearCache();
setTimeout.force(function() {
setTimeout.paused = false;
setTimeout.clear();

Wyświetl plik

@ -160,7 +160,8 @@ if [ "$os" == "windows" ]; then
cscript //NoLogo //B //E:jscript ./shortcut.wscript.js
rm -f ./shortcut.wscript.js
bash ./makelocal.sh
current_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
bash "$current_dir/makelocal.sh"
fi