@microsoft/m365-copilot-eval 1.0.1-preview.1 → 1.1.1-preview.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,7 @@ import fs from 'fs/promises';
4
4
  import crypto from 'crypto';
5
5
  import { pipeline } from 'stream/promises';
6
6
  import { createWriteStream } from 'fs';
7
+ import { Transform } from 'stream';
7
8
  import fetch from 'node-fetch';
8
9
 
9
10
  /**
@@ -111,9 +112,15 @@ async function calculateFileHash(filePath) {
111
112
 
112
113
  /**
113
114
  * Download a file with progress indication
115
+ * @param {string} url - URL to download from
116
+ * @param {string} destPath - Destination file path
117
+ * @param {string} expectedHash - Expected SHA256 hash
118
+ * @param {Function} [onProgress] - Optional progress callback
114
119
  */
115
- async function downloadFile(url, destPath, expectedHash) {
116
- console.log(`Downloading: ${url}`);
120
+ async function downloadFile(url, destPath, expectedHash, onProgress) {
121
+ if (!onProgress) {
122
+ console.log(`Downloading: ${url}`);
123
+ }
117
124
 
118
125
  // Support proxy configuration
119
126
  const fetchOptions = {};
@@ -134,12 +141,34 @@ async function downloadFile(url, destPath, expectedHash) {
134
141
  // Create parent directory if needed
135
142
  await fs.mkdir(path.dirname(destPath), { recursive: true });
136
143
 
137
- // Stream to file
144
+ // Get total size from Content-Length header
145
+ const totalBytes = parseInt(response.headers.get('content-length'), 10) || 0;
146
+ let downloadedBytes = 0;
147
+
148
+ // Create transform stream to track progress
149
+ const progressStream = new Transform({
150
+ transform(chunk, encoding, callback) {
151
+ downloadedBytes += chunk.length;
152
+ if (onProgress && totalBytes > 0) {
153
+ onProgress({
154
+ type: 'progress',
155
+ phaseId: 'download',
156
+ current: downloadedBytes,
157
+ total: totalBytes,
158
+ });
159
+ }
160
+ callback(null, chunk);
161
+ },
162
+ });
163
+
164
+ // Stream to file with progress tracking
138
165
  const fileStream = createWriteStream(destPath);
139
- await pipeline(response.body, fileStream);
166
+ await pipeline(response.body, progressStream, fileStream);
140
167
 
141
168
  // Verify checksum
142
- console.log('Verifying checksum...');
169
+ if (!onProgress) {
170
+ console.log('Verifying checksum...');
171
+ }
143
172
  const actualHash = await calculateFileHash(destPath);
144
173
 
145
174
  if (actualHash !== expectedHash) {
@@ -152,16 +181,23 @@ async function downloadFile(url, destPath, expectedHash) {
152
181
  );
153
182
  }
154
183
 
155
- console.log('Checksum verified ✓');
184
+ if (!onProgress) {
185
+ console.log('Checksum verified ✓');
186
+ }
156
187
  }
157
188
 
158
189
  /**
159
190
  * Extract tar.gz archive
191
+ * @param {string} archivePath - Path to archive file
192
+ * @param {string} destDir - Destination directory
193
+ * @param {Function} [onProgress] - Optional progress callback
160
194
  */
161
- async function extractTarGz(archivePath, destDir) {
195
+ async function extractTarGz(archivePath, destDir, onProgress) {
162
196
  const tar = await import('tar');
163
197
 
164
- console.log(`Extracting to: ${destDir}`);
198
+ if (!onProgress) {
199
+ console.log(`Extracting to: ${destDir}`);
200
+ }
165
201
  await fs.mkdir(destDir, { recursive: true });
166
202
 
167
203
  await tar.extract({
@@ -170,14 +206,18 @@ async function extractTarGz(archivePath, destDir) {
170
206
  strip: 1, // Remove the top-level directory from archive
171
207
  });
172
208
 
173
- console.log('Extraction complete ✓');
209
+ if (!onProgress) {
210
+ console.log('Extraction complete ✓');
211
+ }
174
212
  }
175
213
 
176
214
  /**
177
215
  * Download and setup Python Build Standalone runtime
178
216
  * Returns the path to the Python executable
217
+ * @param {boolean} [verbose=false] - Enable verbose output
218
+ * @param {Function} [onProgress] - Optional progress callback
179
219
  */
180
- export async function ensurePythonRuntime(verbose = false) {
220
+ export async function ensurePythonRuntime(verbose = false, onProgress) {
181
221
  const platformKey = getPlatformKey();
182
222
  const distribution = PBS_DISTRIBUTIONS[platformKey];
183
223
 
@@ -197,39 +237,73 @@ export async function ensurePythonRuntime(verbose = false) {
197
237
  pythonExe = path.join(pythonDir, 'bin', 'python3');
198
238
  }
199
239
 
200
- // Check if Python is already installed
240
+ // Check if Python is already installed (silent skip per FR-007)
201
241
  try {
202
242
  await fs.access(pythonExe);
203
243
  if (verbose) {
204
244
  console.log(`Using cached Python runtime: ${pythonExe}`);
205
245
  }
246
+ // Skip both download and extract phases silently
247
+ onProgress?.({ type: 'skip', phaseId: 'download' });
248
+ onProgress?.({ type: 'skip', phaseId: 'extract' });
206
249
  return pythonExe;
207
250
  } catch {
208
251
  // Python not found, proceed with download and extraction
209
252
  }
210
253
 
211
- console.log(
212
- `Setting up Python ${PYTHON_VERSION} runtime for ${platformKey}...`
213
- );
254
+ if (!onProgress) {
255
+ console.log(
256
+ `Setting up Python ${PYTHON_VERSION} runtime for ${platformKey}...`
257
+ );
258
+ }
214
259
 
215
260
  // Download if not cached
261
+ let needsDownload = false;
216
262
  try {
217
263
  await fs.access(archivePath);
218
264
  if (verbose) {
219
265
  console.log('Using cached download');
220
266
  }
267
+ // Skip download phase silently
268
+ onProgress?.({ type: 'skip', phaseId: 'download' });
221
269
  } catch {
222
- const downloadUrl = `${PBS_BASE_URL}/${distribution.filename}`;
223
- await downloadFile(downloadUrl, archivePath, distribution.sha256);
270
+ needsDownload = true;
271
+ }
272
+
273
+ if (needsDownload) {
274
+ // Start download phase
275
+ onProgress?.({ type: 'start', phaseId: 'download' });
276
+ try {
277
+ const downloadUrl = `${PBS_BASE_URL}/${distribution.filename}`;
278
+ await downloadFile(
279
+ downloadUrl,
280
+ archivePath,
281
+ distribution.sha256,
282
+ onProgress
283
+ );
284
+ onProgress?.({ type: 'complete', phaseId: 'download' });
285
+ } catch (error) {
286
+ onProgress?.({ type: 'error', phaseId: 'download', error });
287
+ throw error;
288
+ }
224
289
  }
225
290
 
226
- // Extract
227
- await extractTarGz(archivePath, pythonDir);
291
+ // Extract phase
292
+ onProgress?.({ type: 'start', phaseId: 'extract' });
293
+ try {
294
+ await extractTarGz(archivePath, pythonDir, onProgress);
295
+ onProgress?.({ type: 'complete', phaseId: 'extract' });
296
+ } catch (error) {
297
+ onProgress?.({ type: 'error', phaseId: 'extract', error });
298
+ throw error;
299
+ }
228
300
 
229
301
  // Verify Python executable exists
230
302
  await fs.access(pythonExe);
231
303
 
232
- console.log(`Python runtime ready: ${pythonExe}`);
304
+ if (!onProgress) {
305
+ console.log(`Python runtime ready: ${pythonExe}`);
306
+ }
233
307
  return pythonExe;
234
308
  }
235
309
 
@@ -6,12 +6,25 @@ import { getPythonExecutable, getCacheDir } from './python-runtime.js';
6
6
 
7
7
  /**
8
8
  * Execute a command and return stdout
9
+ * @param {string} command - Command to execute
10
+ * @param {string[]} args - Command arguments
11
+ * @param {Object} options - Execution options
12
+ * @param {boolean} [options.verbose] - Enable verbose output
13
+ * @param {Function} [options.onStdout] - Callback for stdout data
9
14
  */
10
15
  function execCommand(command, args, options = {}) {
11
16
  return new Promise((resolve, reject) => {
12
- const proc = spawn(command, args, {
17
+ // On Windows, we need shell for proper .exe execution, but passing args
18
+ // separately with shell:true triggers DEP0190. Join into single command.
19
+ const isWindows = process.platform === 'win32';
20
+ const spawnArgs = isWindows ? [] : args;
21
+ const spawnCommand = isWindows
22
+ ? `"${command}" ${args.map((a) => `"${a}"`).join(' ')}`
23
+ : command;
24
+
25
+ const proc = spawn(spawnCommand, spawnArgs, {
13
26
  ...options,
14
- shell: process.platform === 'win32',
27
+ shell: isWindows,
15
28
  });
16
29
 
17
30
  let stdout = '';
@@ -23,6 +36,10 @@ function execCommand(command, args, options = {}) {
23
36
  if (options.verbose) {
24
37
  process.stdout.write(data);
25
38
  }
39
+ // Call onStdout callback if provided (for progress tracking)
40
+ if (options.onStdout) {
41
+ options.onStdout(data.toString());
42
+ }
26
43
  });
27
44
  }
28
45
 
@@ -78,22 +95,15 @@ function getVenvPython(venvDir) {
78
95
  }
79
96
  }
80
97
 
81
- /**
82
- * Get the venv pip executable path
83
- */
84
- function getVenvPip(venvDir) {
85
- if (process.platform === 'win32') {
86
- return path.join(venvDir, 'Scripts', 'pip.exe');
87
- } else {
88
- return path.join(venvDir, 'bin', 'pip');
89
- }
90
- }
91
-
92
98
  /**
93
99
  * Create a virtual environment
100
+ * @param {string} pythonExe - Path to Python executable
101
+ * @param {string} venvDir - Path to venv directory
102
+ * @param {boolean} [verbose=false] - Enable verbose output
103
+ * @param {Function} [onProgress] - Optional progress callback
94
104
  */
95
- async function createVenv(pythonExe, venvDir, verbose = false) {
96
- if (verbose) {
105
+ async function createVenv(pythonExe, venvDir, verbose = false, onProgress) {
106
+ if (verbose && !onProgress) {
97
107
  console.log(`Creating virtual environment at: ${venvDir}`);
98
108
  }
99
109
 
@@ -101,28 +111,47 @@ async function createVenv(pythonExe, venvDir, verbose = false) {
101
111
 
102
112
  await execCommand(pythonExe, ['-m', 'venv', venvDir], { verbose });
103
113
 
104
- if (verbose) {
114
+ if (verbose && !onProgress) {
105
115
  console.log('Virtual environment created ✓');
106
116
  }
107
117
  }
108
118
 
109
119
  /**
110
120
  * Install packages from requirements.txt into venv
121
+ * @param {string} venvDir - Path to venv directory
122
+ * @param {string} requirementsPath - Path to requirements.txt
123
+ * @param {boolean} [verbose=false] - Enable verbose output
124
+ * @param {Function} [onProgress] - Optional progress callback
111
125
  */
112
- async function installRequirements(venvDir, requirementsPath, verbose = false) {
113
- const pipExe = getVenvPip(venvDir);
114
-
115
- console.log('Installing Python dependencies...');
126
+ async function installRequirements(
127
+ venvDir,
128
+ requirementsPath,
129
+ verbose = false,
130
+ onProgress
131
+ ) {
132
+ const venvPython = getVenvPython(venvDir);
133
+
134
+ if (!onProgress) {
135
+ console.log('Installing Python dependencies...');
136
+ }
116
137
  if (verbose) {
117
- console.log(`Using pip: ${pipExe}`);
138
+ console.log(`Using pip: ${venvPython} -m pip`);
118
139
  console.log(`Requirements: ${requirementsPath}`);
119
140
  }
120
141
 
121
- // Upgrade pip first
122
- await execCommand(pipExe, ['install', '--upgrade', 'pip'], { verbose });
142
+ // Upgrade pip first (use python -m pip to avoid Windows file locking issues)
143
+ await execCommand(venvPython, ['-m', 'pip', 'install', '--upgrade', 'pip'], {
144
+ verbose,
145
+ });
146
+
147
+ // Track progress through pip's phases: Collecting -> Downloading/Cached -> Installing
148
+ let collectingCount = 0;
149
+ let downloadingCount = 0;
150
+ let cachedCount = 0;
151
+ let pipPhase = 'collecting'; // 'collecting', 'resolving', 'downloading', 'installing'
123
152
 
124
153
  // Install requirements with hash checking if available
125
- const args = ['install', '-r', requirementsPath];
154
+ const args = ['-m', 'pip', 'install', '-r', requirementsPath];
126
155
 
127
156
  // Support proxy and certificate configuration
128
157
  if (process.env.PIP_CERT) {
@@ -133,9 +162,81 @@ async function installRequirements(venvDir, requirementsPath, verbose = false) {
133
162
  args.push('--trusted-host', process.env.PIP_TRUSTED_HOST);
134
163
  }
135
164
 
136
- await execCommand(pipExe, args, { verbose });
165
+ // Track progress by parsing pip output through all phases
166
+ const onStdout = onProgress
167
+ ? (output) => {
168
+ const line = output.trim();
169
+
170
+ // Phase 1: Collecting (dependency resolution)
171
+ if (line.includes('Collecting ')) {
172
+ collectingCount++;
173
+ pipPhase = 'collecting';
174
+ onProgress({
175
+ type: 'progress',
176
+ phaseId: 'deps',
177
+ current: collectingCount,
178
+ status: 'collecting',
179
+ message: line,
180
+ });
181
+ }
182
+ // Using cached packages (can happen during collecting or after)
183
+ else if (line.includes('Using cached ')) {
184
+ cachedCount++;
185
+ onProgress({
186
+ type: 'progress',
187
+ phaseId: 'deps',
188
+ current: cachedCount,
189
+ status: 'cached',
190
+ message: line,
191
+ });
192
+ }
193
+ // Phase 2: Downloading packages
194
+ else if (line.includes('Downloading ')) {
195
+ if (pipPhase !== 'downloading') {
196
+ pipPhase = 'downloading';
197
+ downloadingCount = 0;
198
+ }
199
+ downloadingCount++;
200
+ onProgress({
201
+ type: 'progress',
202
+ phaseId: 'deps',
203
+ current: downloadingCount,
204
+ total: collectingCount, // Now we know the total from collecting phase
205
+ status: 'downloading',
206
+ message: line,
207
+ });
208
+ }
209
+ // Phase 3: Installing packages
210
+ else if (line.includes('Installing collected packages')) {
211
+ pipPhase = 'installing';
212
+ onProgress({
213
+ type: 'progress',
214
+ phaseId: 'deps',
215
+ current: 0,
216
+ total: collectingCount,
217
+ status: 'installing',
218
+ message: 'Installing packages...',
219
+ });
220
+ }
221
+ // Track successful completion
222
+ else if (line.includes('Successfully installed')) {
223
+ onProgress({
224
+ type: 'progress',
225
+ phaseId: 'deps',
226
+ current: collectingCount,
227
+ total: collectingCount,
228
+ status: 'done',
229
+ message: line,
230
+ });
231
+ }
232
+ }
233
+ : undefined;
234
+
235
+ await execCommand(venvPython, args, { verbose, onStdout });
137
236
 
138
- console.log('Dependencies installed ✓');
237
+ if (!onProgress) {
238
+ console.log('Dependencies installed ✓');
239
+ }
139
240
  }
140
241
 
141
242
  /**
@@ -171,21 +272,33 @@ async function writeRequirementsMarker(venvDir, requirementsHash) {
171
272
  /**
172
273
  * Ensure virtual environment is set up with all dependencies
173
274
  * Returns the path to the venv Python executable
275
+ * @param {string} requirementsPath - Path to requirements.txt
276
+ * @param {boolean} [verbose=false] - Enable verbose output
277
+ * @param {Function} [onProgress] - Optional progress callback
174
278
  */
175
- export async function ensureVenv(requirementsPath, verbose = false) {
279
+ export async function ensureVenv(
280
+ requirementsPath,
281
+ verbose = false,
282
+ onProgress
283
+ ) {
176
284
  const pythonExe = await getPythonExecutable();
177
285
  const venvDir = getVenvDir();
178
286
  const requirementsHash = await getRequirementsHash(requirementsPath);
179
287
 
180
- // Check if venv is already set up and valid
288
+ // Check if venv is already set up and valid (silent skip per FR-007)
181
289
  if (await isVenvValid(venvDir, requirementsHash)) {
182
290
  if (verbose) {
183
291
  console.log('Using existing virtual environment');
184
292
  }
293
+ // Skip both venv and deps phases silently
294
+ onProgress?.({ type: 'skip', phaseId: 'venv' });
295
+ onProgress?.({ type: 'skip', phaseId: 'deps' });
185
296
  return getVenvPython(venvDir);
186
297
  }
187
298
 
188
- console.log('Setting up Python virtual environment...');
299
+ if (!onProgress) {
300
+ console.log('Setting up Python virtual environment...');
301
+ }
189
302
 
190
303
  // Remove old venv if it exists but is invalid
191
304
  try {
@@ -194,16 +307,32 @@ export async function ensureVenv(requirementsPath, verbose = false) {
194
307
  // Ignore errors during cleanup
195
308
  }
196
309
 
197
- // Create new venv
198
- await createVenv(pythonExe, venvDir, verbose);
310
+ // Create new venv phase
311
+ onProgress?.({ type: 'start', phaseId: 'venv' });
312
+ try {
313
+ await createVenv(pythonExe, venvDir, verbose, onProgress);
314
+ onProgress?.({ type: 'complete', phaseId: 'venv' });
315
+ } catch (error) {
316
+ onProgress?.({ type: 'error', phaseId: 'venv', error });
317
+ throw error;
318
+ }
199
319
 
200
- // Install requirements
201
- await installRequirements(venvDir, requirementsPath, verbose);
320
+ // Install dependencies phase
321
+ onProgress?.({ type: 'start', phaseId: 'deps' });
322
+ try {
323
+ await installRequirements(venvDir, requirementsPath, verbose, onProgress);
324
+ onProgress?.({ type: 'complete', phaseId: 'deps' });
325
+ } catch (error) {
326
+ onProgress?.({ type: 'error', phaseId: 'deps', error });
327
+ throw error;
328
+ }
202
329
 
203
330
  // Mark as complete
204
331
  await writeRequirementsMarker(venvDir, requirementsHash);
205
332
 
206
- console.log('Virtual environment ready ✓');
333
+ if (!onProgress) {
334
+ console.log('Virtual environment ready ✓');
335
+ }
207
336
  return getVenvPython(venvDir);
208
337
  }
209
338
 
package/TERMS.txt DELETED
@@ -1,65 +0,0 @@
1
- MICROSOFT SOFTWARE LICENSE TERMS
2
- M365 Copilot Agent Eval Tool
3
- ________________________________________
4
- IF YOU LIVE IN (OR ARE A BUSINESS WITH A PRINCIPAL PLACE OF BUSINESS IN) THE UNITED STATES, PLEASE READ THE “BINDING ARBITRATION AND CLASS ACTION WAIVER” SECTION BELOW. IT AFFECTS HOW DISPUTES ARE RESOLVED.
5
- ________________________________________
6
- These license terms are an agreement between you and Microsoft Corporation. They apply to the software named above and any Microsoft services or software updates (except to the extent such services or updates are accompanied by new or additional terms, in which case those different terms apply prospectively and do not alter your or Microsoft’s rights relating to pre-updated software or services). IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW. BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS.
7
- 1. INSTALLATION AND USE RIGHTS.
8
- a) General. You may install and use any number of copies of the software on your devices.
9
- b) Included Microsoft Applications. The software may include other Microsoft applications. These license terms apply to those included applications, if any, unless other license terms are provided with the other Microsoft applications.
10
- c) Work or School Accounts. You can sign into the software with a work or school email address. If you do, you agree that the owner of the domain associated with your email address may control and administer your account, and access and process your data, including the contents of your communications and files. You further agree that your use of the software may be subject to: i) your organization’s guidelines and policies regarding the use of the software; and ii) the agreements Microsoft has with you or your organization, and in such case these terms may not apply. If you already have a Microsoft account and you use a separate work or school email address to access the software, you may be prompted to update the email address associated with your Microsoft account to continue accessing the software.
11
- d) Third Party Components. The software may include third party components with separate legal notices or governed by other agreements, as may be described in the ThirdPartyNotices file(s) accompanying the software.
12
-
13
- e) Microsoft Services Agreement. Some features of the software provide access to, or rely on, online services. The use of those services (but not the software) is governed by the separate terms and privacy policies in the Microsoft Services Agreement at http://go.microsoft.com/fwlink/?linkid=398923. Please read them. The services may not be available in all regions.
14
-
15
- 2. TIME-SENSITIVE SOFTWARE.
16
- a) Period. This agreement is effective on your acceptance and terminates on the earlier of (i) 30 days following first availability of a commercial release of the software or (ii) upon termination by Microsoft. Microsoft may extend this agreement in its discretion.
17
- b) Notice. You may receive periodic reminder notices of this date through the software.
18
- c) Access to data. You may not be able to access data used in the software when it stops running.
19
- 3. SCOPE OF LICENSE. The software is licensed, not sold. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you will not (and have no right to):
20
- a) work around any technical limitations in the software that only allow you to use it in certain ways;
21
- b) reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software, except and to the extent required by third party licensing terms governing use of certain open source components that may be included in the software;
22
- c) remove, minimize, block, or modify any notices of Microsoft or its suppliers in the software;
23
- d) use the software for commercial, non-profit, or revenue-generating activities unless you have commercial use rights under a separate agreement;
24
- e) use the software in any way that is against the law or to create or propagate malware; or
25
- f) share, publish, distribute, or lease the software, provide the software as a stand-alone offering for others to use, or transfer the software or this agreement to any third party.
26
- 4. PRE-RELEASE SOFTWARE. The software is a pre-release version. It may not operate correctly. It may be different from the commercially released version. Customer further acknowledges that the tool is provided in preview and that Customer’s use of any preview features is governed by the Preview Terms within the Product Terms (Microsoft Azure Legal Information | Microsoft Azure, Preview Terms Of Use | Microsoft Azure), as well as the applicable preview provisions of the Data Protection Addendum (DPA)
27
- 5. FEEDBACK. If you give feedback about the software to Microsoft, you give to Microsoft, without charge, the right to use, share and commercialize your feedback in any way and for any purpose. You will not give feedback that is subject to a license that requires Microsoft to license its software or documentation to third parties because Microsoft includes your feedback in them. These rights survive this agreement.
28
- 6. DATA. This software may interact with other Microsoft products that collect data that is transmitted to Microsoft. To learn more about how Microsoft processes personal data we collect, please see the Microsoft Privacy Statement at https://go.microsoft.com/fwlink/?LinkId=248681. Customer is solely responsible for determining what data is submitted for evaluation and for ensuring that such data is handled in compliance with applicable laws, internal policies, and contractual obligations.[A1.1]
29
- 7. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit https://aka.ms/exporting.
30
- 8. SUPPORT SERVICES. Microsoft is not obligated under this agreement to provide any support services for the software. Any support provided is “as is”, “with all faults”, and without warranty of any kind.
31
- 9. UPDATES. The software may periodically check for updates, and download and install them for you. You may obtain updates only from Microsoft or authorized sources. Microsoft may need to update your system to provide you with updates. You agree to receive these automatic updates without any additional notice. Updates may not include or support all existing software features, services, or peripheral devices.
32
- 10. BINDING ARBITRATION AND CLASS ACTION WAIVER. This Section applies if you live in (or, if a business, your principal place of business is in) the United States. If you and Microsoft have a dispute, you and Microsoft agree to try for 60 days to resolve it informally. If you and Microsoft can’t, you and Microsoft agree to binding individual arbitration before the American Arbitration Association under the Federal Arbitration Act (“FAA”), and not to sue in court in front of a judge or jury. Instead, a neutral arbitrator will decide. Class action lawsuits, class-wide arbitrations, private attorney-general actions, and any other proceeding where someone acts in a representative capacity are not allowed; nor is combining individual proceedings without the consent of all parties. The complete Arbitration Agreement contains more terms and is at https://aka.ms/arb-agreement-4. You and Microsoft agree to these terms.
33
- 11. TERMINATION. Without prejudice to any other rights, Microsoft may terminate this agreement if you fail to comply with any of its terms or conditions. In such event, you must destroy all copies of the software and all of its component parts.
34
- 12. ENTIRE AGREEMENT. This agreement, and any other terms Microsoft may provide for supplements, updates, or third-party applications, is the entire agreement for the software.
35
- 13. APPLICABLE LAW AND PLACE TO RESOLVE DISPUTES. If you acquired the software in the United States or Canada, the laws of the state or province where you live (or, if a business, where your principal place of business is located) govern the interpretation of this agreement, claims for its breach, and all other claims (including consumer protection, unfair competition, and tort claims), regardless of conflict of laws principles, except that the FAA governs everything related to arbitration. If you acquired the software in any other country, its laws apply, except that the FAA governs everything related to arbitration. If U.S. federal jurisdiction exists, you and Microsoft consent to exclusive jurisdiction and venue in the federal court in King County, Washington for all disputes heard in court (excluding arbitration). If not, you and Microsoft consent to exclusive jurisdiction and venue in the Superior Court of King County, Washington for all disputes heard in court (excluding arbitration).
36
- 14. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. You may have other rights, including consumer rights, under the laws of your state, province, or country. Separate and apart from your relationship with Microsoft, you may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state, province, or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you:
37
- a) Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights.
38
- b) Canada. If you acquired this software in Canada, you may stop receiving updates by turning off the automatic update feature, disconnecting your device from the Internet (if and when you re-connect to the Internet, however, the software will resume checking for and installing updates), or uninstalling the software. The product documentation, if any, may also specify how to turn off updates for your specific device or software.
39
- c) Germany and Austria.
40
- i. Warranty. The properly licensed software will perform substantially as described in any Microsoft materials that accompany the software. However, Microsoft gives no contractual guarantee in relation to the licensed software.
41
- ii. Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as, in case of death or personal or physical injury, Microsoft is liable according to the statutory law.
42
- Subject to the foregoing clause ii., Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence.
43
-
44
- 15. CONFIDENTIAL INFORMATION. The software, including its user interface, features and documentation, is confidential and proprietary to Microsoft and its suppliers.
45
- c) Use. For five years after installation of the software or its commercial release, whichever is first, you may not disclose confidential information to third parties. You may disclose confidential information only to your employees and consultants who need to know the information. You must have written agreements with them that protect the confidential information at least as much as this agreement.
46
- c) Survival. Your duty to protect confidential information survives this agreement.
47
- c) Exclusions. You may disclose confidential information in response to a judicial or governmental order. You must first give written notice to Microsoft to allow it to seek a protective order or otherwise protect the information. Confidential information does not include information that:
48
- 1. becomes publicly known through no wrongful act;
49
- 2. you received from a third party who did not breach confidentiality obligations to Microsoft or its suppliers; or
50
- 3. you developed independently.
51
-
52
- 16. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS IS.” YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES, OR CONDITIONS. TO THE EXTENT PERMITTED UNDER APPLICABLE LAWS, MICROSOFT EXCLUDES ALL IMPLIED WARRANTIES, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
53
- 17. LIMITATION ON AND EXCLUSION OF DAMAGES. IF YOU HAVE ANY BASIS FOR RECOVERING DAMAGES DESPITE THE PRECEDING DISCLAIMER OF WARRANTY, YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.
54
- This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, warranty, guarantee, or condition; strict liability, negligence, or other tort; or any other claim; in each case to the extent permitted by applicable law.
55
- It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your state, province, or country may not allow the exclusion or limitation of incidental, consequential, or other damages.
56
-
57
- Please note: As this software is distributed in Canada, some of the clauses in this agreement are provided below in French.
58
- Remarque: Ce logiciel étant distribué au Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en français.
59
- EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert « tel quel ». Toute utilisation de ce logiciel est à votre seule risque et péril. Microsoft n’accorde aucune autre garantie expresse. Vous pouvez bénéficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualité marchande, d’adéquation à un usage particulier et d’absence de contrefaçon sont exclues.
60
- LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune indemnisation pour les autres dommages, y compris les dommages spéciaux, indirects ou accessoires et pertes de bénéfices.
61
- Cette limitation concerne:
62
- • tout ce qui est relié au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers; et
63
- • les réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité stricte, de négligence ou d’une autre faute dans la limite autorisée par la loi en vigueur.
64
- Elle s’applique également, même si Microsoft connaissait ou devrait connaître l’éventualité d’un tel dommage. Si votre pays n’autorise pas l’exclusion ou la limitation de responsabilité pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l’exclusion ci-dessus ne s’appliquera pas à votre égard.
65
- EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous pourriez avoir d’autres droits prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois de votre pays si celles-ci ne le permettent pas.