From ded6fb077bd443c5404054ba7d12e012920f7015 Mon Sep 17 00:00:00 2001 From: yiliang114 Date: Mon, 6 Jul 2026 11:14:32 +0800 Subject: [PATCH 1/5] fix(core): allow rewind after compressed history --- .../core/src/utils/environmentContext.test.ts | 63 +++++++++++++++++++ packages/core/src/utils/environmentContext.ts | 36 +++++++++-- 2 files changed, 95 insertions(+), 4 deletions(-) diff --git a/packages/core/src/utils/environmentContext.test.ts b/packages/core/src/utils/environmentContext.test.ts index 7ce84c32888..55f121ec1a7 100644 --- a/packages/core/src/utils/environmentContext.test.ts +++ b/packages/core/src/utils/environmentContext.test.ts @@ -616,6 +616,69 @@ describe('getStartupContextLength', () => { ); expect(getStartupContextLength([merged])).toBe(0); }); + + // Compressed history prefix: composePostCompactHistory produces + // [user(summary), model(ack), user(postAckParts)?, ...]. The ack sentinel + // is distinct from the legacy ack above. + + it('is 2 for a compressed prefix without attachments', () => { + const history: Content[] = [ + { + role: 'user', + parts: [{ text: 'summary text\n\nResume the prior task...' }], + }, + { + role: 'model', + parts: [{ text: 'Got it. Thanks for the additional context!' }], + }, + ]; + expect(getStartupContextLength(history)).toBe(2); + }); + + it('is 3 for a compressed prefix with post-compact attachments', () => { + const history: Content[] = [ + { + role: 'user', + parts: [{ text: 'summary text\n\nResume the prior task...' }], + }, + { + role: 'model', + parts: [{ text: 'Got it. Thanks for the additional context!' }], + }, + { + role: 'user', + parts: [ + { text: 'file restoration content' }, + { text: '\nplan mode\n' }, + ], + }, + ]; + expect(getStartupContextLength(history)).toBe(3); + }); + + it('is 2 for a degraded compression fallback with merged reminders', () => { + const history: Content[] = [ + { + role: 'user', + parts: [ + { text: 'summary\n\nResume the prior task...' }, + { text: '\nplan mode active\n' }, + ], + }, + { + role: 'model', + parts: [ + { text: 'Got it. Thanks for the additional context!' }, + { functionCall: { name: 'fn', args: {} } }, + ], + }, + { + role: 'user', + parts: [{ functionResponse: { name: 'fn', response: {} } }], + }, + ]; + expect(getStartupContextLength(history)).toBe(2); + }); }); describe('buildAvailableSkillsReminder', () => { diff --git a/packages/core/src/utils/environmentContext.ts b/packages/core/src/utils/environmentContext.ts index a1fc01bf827..fdfc26dbc54 100644 --- a/packages/core/src/utils/environmentContext.ts +++ b/packages/core/src/utils/environmentContext.ts @@ -571,10 +571,18 @@ export async function getInitialChatHistory( } /** - * Returns the number of initial API entries occupied by the startup reminder - * (0 or 1). A single user message wrapped in is the only - * shape getInitialChatHistory currently produces, but routes through this - * helper so detection stays consistent across the CLI and ACP integration. + * Returns the number of initial API entries occupied by structural context + * that should be skipped when counting real user turns: + * + * - The startup reminder prelude (0 or 1 entry) — a single user message + * wrapped in ``, produced by + * `getInitialChatHistory`. + * - The legacy ack-pair prelude (2 entries) — sessions saved before the + * startup context moved into system reminders. + * - The compressed-history prefix (2 or 3 entries) — summary, ack, and + * optionally a post-compact attachments entry produced by + * `composePostCompactHistory`. These synthetic entries must not be + * counted as real user prompts for rewind indexing. */ export function getStartupContextLength(history: Content[]): number { const firstEntry = history[0]; @@ -601,9 +609,29 @@ export function getStartupContextLength(history: Content[]): number { ) { return 2; } + // Post-compression prefix: composePostCompactHistory always produces + // [user(summary), model(ack)] and optionally appends user(postAckParts) + // when file restorations or state reminders accompany the summary. The + // summary is plain prose (not -wrapped) so it would pass + // isUserTextContent and corrupt rewind turn-counting. Detected via the + // compression-specific ack sentinel — distinct from the legacy ack above. + if ( + history[1]?.role === 'model' && + history[1]?.parts?.[0]?.text === + 'Got it. Thanks for the additional context!' + ) { + if (isUserTextContextEntry(history[2])) return 3; + return 2; + } return 0; } +function isUserTextContextEntry(content: Content | undefined): boolean { + if (content?.role !== 'user') return false; + const parts = content.parts ?? []; + return parts.length > 0 && !parts.some((part) => 'functionResponse' in part); +} + /** * True when `content` is a *pure* system-reminder entry: it has parts and * EVERY part is a text part wrapped in ``. From b3ca6904cb665949c6d1a135765b0763090ab31a Mon Sep 17 00:00:00 2001 From: yiliang114 Date: Mon, 6 Jul 2026 15:32:02 +0800 Subject: [PATCH 2/5] fix(core): separate compressed prefix rewind handling --- .../src/acp-integration/session/Session.ts | 8 ++- packages/cli/src/ui/utils/historyMapping.ts | 4 +- .../core/src/utils/environmentContext.test.ts | 66 +++++++++++++++++-- packages/core/src/utils/environmentContext.ts | 48 +++++++++++--- 4 files changed, 106 insertions(+), 20 deletions(-) diff --git a/packages/cli/src/acp-integration/session/Session.ts b/packages/cli/src/acp-integration/session/Session.ts index f89745c2927..2260023992c 100644 --- a/packages/cli/src/acp-integration/session/Session.ts +++ b/packages/cli/src/acp-integration/session/Session.ts @@ -1151,7 +1151,9 @@ export class Session implements SessionContext { getRewindableUserTurnCount(): number { const apiHistory = this.captureHistorySnapshot(); - const startIndex = getStartupContextLength(apiHistory); + const startIndex = getStartupContextLength(apiHistory, { + includeCompressed: true, + }); let count = 0; for (let i = startIndex; i < apiHistory.length; i++) { @@ -1187,7 +1189,9 @@ export class Session implements SessionContext { apiHistory: Content[], targetTurnIndex: number, ): number { - const startIndex = getStartupContextLength(apiHistory); + const startIndex = getStartupContextLength(apiHistory, { + includeCompressed: true, + }); if (targetTurnIndex === 0) { return startIndex; diff --git a/packages/cli/src/ui/utils/historyMapping.ts b/packages/cli/src/ui/utils/historyMapping.ts index c86c72ecd88..fae29168218 100644 --- a/packages/cli/src/ui/utils/historyMapping.ts +++ b/packages/cli/src/ui/utils/historyMapping.ts @@ -100,7 +100,9 @@ export function computeApiTruncationIndex( } // Determine the starting index in the API history (skip startup context) - const startIndex = getStartupContextLength(apiHistory); + const startIndex = getStartupContextLength(apiHistory, { + includeCompressed: true, + }); if (uiUserTurnCount === 0) { // Rewinding to the first user turn: keep only startup context (if any) diff --git a/packages/core/src/utils/environmentContext.test.ts b/packages/core/src/utils/environmentContext.test.ts index 55f121ec1a7..e3891788607 100644 --- a/packages/core/src/utils/environmentContext.test.ts +++ b/packages/core/src/utils/environmentContext.test.ts @@ -621,7 +621,7 @@ describe('getStartupContextLength', () => { // [user(summary), model(ack), user(postAckParts)?, ...]. The ack sentinel // is distinct from the legacy ack above. - it('is 2 for a compressed prefix without attachments', () => { + it('is 0 for compressed prefixes by default', () => { const history: Content[] = [ { role: 'user', @@ -632,10 +632,30 @@ describe('getStartupContextLength', () => { parts: [{ text: 'Got it. Thanks for the additional context!' }], }, ]; - expect(getStartupContextLength(history)).toBe(2); + expect(getStartupContextLength(history)).toBe(0); }); - it('is 3 for a compressed prefix with post-compact attachments', () => { + it('is 2 for rewind when a real prompt follows a compressed prefix', () => { + const history: Content[] = [ + { + role: 'user', + parts: [{ text: 'summary text\n\nResume the prior task...' }], + }, + { + role: 'model', + parts: [{ text: 'Got it. Thanks for the additional context!' }], + }, + { + role: 'user', + parts: [{ text: 'Now do something else' }], + }, + ]; + expect(getStartupContextLength(history, { includeCompressed: true })).toBe( + 2, + ); + }); + + it('is 3 for rewind with post-compact attachments', () => { const history: Content[] = [ { role: 'user', @@ -648,15 +668,45 @@ describe('getStartupContextLength', () => { { role: 'user', parts: [ - { text: 'file restoration content' }, + { + text: + 'Recently accessed file (full current content embedded):\n\n' + + '## /repo/file.ts\n\n```ts\nexport const x = 1;\n```', + }, { text: '\nplan mode\n' }, ], }, ]; - expect(getStartupContextLength(history)).toBe(3); + expect(getStartupContextLength(history, { includeCompressed: true })).toBe( + 3, + ); }); - it('is 2 for a degraded compression fallback with merged reminders', () => { + it('is 4 for rewind with attachments and a trailing function call', () => { + const history: Content[] = [ + { + role: 'user', + parts: [{ text: 'summary\n\nResume the prior task...' }], + }, + { + role: 'model', + parts: [{ text: 'Got it. Thanks for the additional context!' }], + }, + { + role: 'user', + parts: [{ text: '\nplan\n' }], + }, + { + role: 'model', + parts: [{ functionCall: { name: 'fn', args: {} } }], + }, + ]; + expect(getStartupContextLength(history, { includeCompressed: true })).toBe( + 4, + ); + }); + + it('is 2 for rewind with degraded compression fallback', () => { const history: Content[] = [ { role: 'user', @@ -677,7 +727,9 @@ describe('getStartupContextLength', () => { parts: [{ functionResponse: { name: 'fn', response: {} } }], }, ]; - expect(getStartupContextLength(history)).toBe(2); + expect(getStartupContextLength(history, { includeCompressed: true })).toBe( + 2, + ); }); }); diff --git a/packages/core/src/utils/environmentContext.ts b/packages/core/src/utils/environmentContext.ts index fdfc26dbc54..65f633cc304 100644 --- a/packages/core/src/utils/environmentContext.ts +++ b/packages/core/src/utils/environmentContext.ts @@ -584,7 +584,10 @@ export async function getInitialChatHistory( * `composePostCompactHistory`. These synthetic entries must not be * counted as real user prompts for rewind indexing. */ -export function getStartupContextLength(history: Content[]): number { +export function getStartupContextLength( + history: Content[], + options: { includeCompressed?: boolean } = {}, +): number { const firstEntry = history[0]; if (firstEntry?.role !== 'user') return 0; const firstText = firstEntry.parts?.[0]?.text; @@ -609,27 +612,52 @@ export function getStartupContextLength(history: Content[]): number { ) { return 2; } - // Post-compression prefix: composePostCompactHistory always produces - // [user(summary), model(ack)] and optionally appends user(postAckParts) - // when file restorations or state reminders accompany the summary. The - // summary is plain prose (not -wrapped) so it would pass - // isUserTextContent and corrupt rewind turn-counting. Detected via the - // compression-specific ack sentinel — distinct from the legacy ack above. + if (!options.includeCompressed) return 0; + + // Post-compression prefix for rewind indexing only. The startup-context + // refresh/restore paths need compressed history to look like "no startup + // prelude" so they don't strip or skip the compressed summary. if ( + typeof firstText === 'string' && + firstText.includes('Resume the prior task') && history[1]?.role === 'model' && history[1]?.parts?.[0]?.text === 'Got it. Thanks for the additional context!' ) { - if (isUserTextContextEntry(history[2])) return 3; + if (isPostCompactAttachmentEntry(history[2])) { + if (isModelFunctionCallEntry(history[3])) return 4; + return 3; + } return 2; } return 0; } -function isUserTextContextEntry(content: Content | undefined): boolean { +function isPostCompactAttachmentEntry(content: Content | undefined): boolean { if (content?.role !== 'user') return false; const parts = content.parts ?? []; - return parts.length > 0 && !parts.some((part) => 'functionResponse' in part); + return parts.some( + (part) => + typeof part.text === 'string' && + (part.text.startsWith('') || + part.text.startsWith('') || + part.text.startsWith( + 'The following files were recently accessed before context was compacted.', + ) || + part.text.startsWith( + 'Recently accessed file (full current content embedded):', + ) || + part.text.startsWith( + 'Recent visual snapshots preserved from before context was compacted', + )), + ); +} + +function isModelFunctionCallEntry(content: Content | undefined): boolean { + return ( + content?.role === 'model' && + (content.parts ?? []).some((part) => 'functionCall' in part) + ); } /** From ab415cf8ff969d333ae8e5ac6592f3010b31691a Mon Sep 17 00:00:00 2001 From: yiliang114 Date: Mon, 6 Jul 2026 17:56:17 +0800 Subject: [PATCH 3/5] fix(core): handle rewind after restored startup context --- .../core/src/utils/environmentContext.test.ts | 39 +++++++++++++++++++ packages/core/src/utils/environmentContext.ts | 36 +++++++++++------ 2 files changed, 64 insertions(+), 11 deletions(-) diff --git a/packages/core/src/utils/environmentContext.test.ts b/packages/core/src/utils/environmentContext.test.ts index e3891788607..2013ad2c95a 100644 --- a/packages/core/src/utils/environmentContext.test.ts +++ b/packages/core/src/utils/environmentContext.test.ts @@ -635,6 +635,24 @@ describe('getStartupContextLength', () => { expect(getStartupContextLength(history)).toBe(0); }); + it('is 0 for compressed prefixes with trailing prompts by default', () => { + const history: Content[] = [ + { + role: 'user', + parts: [{ text: 'summary text\n\nResume the prior task...' }], + }, + { + role: 'model', + parts: [{ text: 'Got it. Thanks for the additional context!' }], + }, + { + role: 'user', + parts: [{ text: 'Now do something else' }], + }, + ]; + expect(getStartupContextLength(history)).toBe(0); + }); + it('is 2 for rewind when a real prompt follows a compressed prefix', () => { const history: Content[] = [ { @@ -655,6 +673,27 @@ describe('getStartupContextLength', () => { ); }); + it('includes compressed prefixes after startup reminders for rewind', () => { + const history: Content[] = [ + { role: 'user', parts: [{ text: wrap('env') }] }, + { + role: 'user', + parts: [{ text: 'summary text\n\nResume the prior task...' }], + }, + { + role: 'model', + parts: [{ text: 'Got it. Thanks for the additional context!' }], + }, + { + role: 'user', + parts: [{ text: 'Now do something else' }], + }, + ]; + expect(getStartupContextLength(history, { includeCompressed: true })).toBe( + 3, + ); + }); + it('is 3 for rewind with post-compact attachments', () => { const history: Content[] = [ { diff --git a/packages/core/src/utils/environmentContext.ts b/packages/core/src/utils/environmentContext.ts index 65f633cc304..378e896411b 100644 --- a/packages/core/src/utils/environmentContext.ts +++ b/packages/core/src/utils/environmentContext.ts @@ -579,7 +579,7 @@ export async function getInitialChatHistory( * `getInitialChatHistory`. * - The legacy ack-pair prelude (2 entries) — sessions saved before the * startup context moved into system reminders. - * - The compressed-history prefix (2 or 3 entries) — summary, ack, and + * - The compressed-history prefix (2-4 entries) — summary, ack, and * optionally a post-compact attachments entry produced by * `composePostCompactHistory`. These synthetic entries must not be * counted as real user prompts for rewind indexing. @@ -599,6 +599,10 @@ export function getStartupContextLength( firstText.startsWith(SYSTEM_REMINDER_OPEN) && firstText.trimEnd().endsWith(SYSTEM_REMINDER_CLOSE) ) { + if (options.includeCompressed) { + const compressedLength = detectCompressedPrefixLength(history, 1); + if (compressedLength > 0) return 1 + compressedLength; + } return 1; } // Legacy format (sessions saved before startup context moved into system @@ -614,23 +618,33 @@ export function getStartupContextLength( } if (!options.includeCompressed) return 0; + return detectCompressedPrefixLength(history, 0); +} + +function detectCompressedPrefixLength( + history: Content[], + offset: number, +): number { + const firstEntry = history[offset]; + if (firstEntry?.role !== 'user') return 0; + const firstText = firstEntry.parts?.[0]?.text; // Post-compression prefix for rewind indexing only. The startup-context // refresh/restore paths need compressed history to look like "no startup // prelude" so they don't strip or skip the compressed summary. if ( - typeof firstText === 'string' && - firstText.includes('Resume the prior task') && - history[1]?.role === 'model' && - history[1]?.parts?.[0]?.text === + typeof firstText !== 'string' || + !firstText.includes('Resume the prior task') || + history[offset + 1]?.role !== 'model' || + history[offset + 1]?.parts?.[0]?.text !== 'Got it. Thanks for the additional context!' ) { - if (isPostCompactAttachmentEntry(history[2])) { - if (isModelFunctionCallEntry(history[3])) return 4; - return 3; - } - return 2; + return 0; + } + if (isPostCompactAttachmentEntry(history[offset + 2])) { + if (isModelFunctionCallEntry(history[offset + 3])) return 4; + return 3; } - return 0; + return 2; } function isPostCompactAttachmentEntry(content: Content | undefined): boolean { From 8e8e7a87e59a0f32281bc0701a4913a7e9e8a398 Mon Sep 17 00:00:00 2001 From: yiliang114 Date: Mon, 6 Jul 2026 19:51:51 +0800 Subject: [PATCH 4/5] test(core): cover compressed rewind sentinel mismatch --- .../core/src/utils/environmentContext.test.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/packages/core/src/utils/environmentContext.test.ts b/packages/core/src/utils/environmentContext.test.ts index 2013ad2c95a..cef3e504ac9 100644 --- a/packages/core/src/utils/environmentContext.test.ts +++ b/packages/core/src/utils/environmentContext.test.ts @@ -653,6 +653,32 @@ describe('getStartupContextLength', () => { expect(getStartupContextLength(history)).toBe(0); }); + it('is 0 for rewind when summary text lacks the resume sentinel', () => { + const history: Content[] = [ + { role: 'user', parts: [{ text: 'unrelated summary text' }] }, + { + role: 'model', + parts: [{ text: 'Got it. Thanks for the additional context!' }], + }, + ]; + expect(getStartupContextLength(history, { includeCompressed: true })).toBe( + 0, + ); + }); + + it('is 0 for rewind when the compression ack text does not match', () => { + const history: Content[] = [ + { + role: 'user', + parts: [{ text: 'summary text\n\nResume the prior task...' }], + }, + { role: 'model', parts: [{ text: 'Understood, resuming now.' }] }, + ]; + expect(getStartupContextLength(history, { includeCompressed: true })).toBe( + 0, + ); + }); + it('is 2 for rewind when a real prompt follows a compressed prefix', () => { const history: Content[] = [ { From 09f144e042c8bf3d9a609da0c4227cce4d8900a4 Mon Sep 17 00:00:00 2001 From: yiliang114 Date: Tue, 7 Jul 2026 10:34:38 +0800 Subject: [PATCH 5/5] fix(cli): align rewind mapping after compression --- .../cli/src/ui/utils/historyMapping.test.ts | 82 +++++++++++++++++++ packages/cli/src/ui/utils/historyMapping.ts | 27 +++++- 2 files changed, 105 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/ui/utils/historyMapping.test.ts b/packages/cli/src/ui/utils/historyMapping.test.ts index 21dd633a7d7..92dd9a8c7f9 100644 --- a/packages/cli/src/ui/utils/historyMapping.test.ts +++ b/packages/cli/src/ui/utils/historyMapping.test.ts @@ -9,6 +9,7 @@ import { computeApiTruncationIndex, isRealUserTurn } from './historyMapping.js'; import type { HistoryItem } from '../types.js'; import type { Content, Part } from '@google/genai'; import { + CompressionStatus, SYSTEM_REMINDER_OPEN, SYSTEM_REMINDER_CLOSE, } from '@qwen-code/qwen-code-core'; @@ -59,6 +60,22 @@ function geminiItem(id: number): HistoryItem { return { type: 'gemini', id, text: `response ${id}` } as HistoryItem; } +function compressionItem( + id: number, + compressionStatus = CompressionStatus.COMPRESSED, +): HistoryItem { + return { + type: 'compression', + id, + compression: { + isPending: false, + originalTokenCount: 100, + newTokenCount: 40, + compressionStatus, + }, + } as HistoryItem; +} + // --------------------------------------------------------------------------- // Tests // --------------------------------------------------------------------------- @@ -266,6 +283,71 @@ describe('computeApiTruncationIndex', () => { // Rewind to turn 5 → 2 user turns before it, but API only has 1 user text expect(computeApiTruncationIndex(ui, 5, api)).toBe(-1); }); + + it('maps post-compression UI turns from the latest compressed marker', () => { + const ui: HistoryItem[] = [ + userItem(1, 'pre-compression prompt'), + geminiItem(2), + compressionItem(3), + userItem(4, 'post 1'), + geminiItem(5), + userItem(6, 'post 2'), + geminiItem(7), + userItem(8, 'post 3'), + geminiItem(9), + ]; + const api: Content[] = [ + startupEntry(), + userContent('summary\n\nResume the prior task...'), + modelContent('Got it. Thanks for the additional context!'), + userContent('post 1'), + modelContent('response 1'), + userContent('post 2'), + modelContent('response 2'), + userContent('post 3'), + modelContent('response 3'), + ]; + + expect(computeApiTruncationIndex(ui, 4, api)).toBe(3); + expect(computeApiTruncationIndex(ui, 6, api)).toBe(5); + expect(computeApiTruncationIndex(ui, 8, api)).toBe(7); + }); + + it('does not rewind to UI turns before a successful compression marker', () => { + const ui: HistoryItem[] = [ + userItem(1, 'pre-compression prompt'), + geminiItem(2), + compressionItem(3), + userItem(4, 'post compression'), + ]; + const api: Content[] = [ + startupEntry(), + userContent('summary\n\nResume the prior task...'), + modelContent('Got it. Thanks for the additional context!'), + userContent('post compression'), + ]; + + expect(computeApiTruncationIndex(ui, 1, api)).toBe(-1); + }); + + it('does not treat no-op compression markers as collapsed history', () => { + const ui: HistoryItem[] = [ + userItem(1, 'first prompt'), + geminiItem(2), + compressionItem(3, CompressionStatus.NOOP), + userItem(4, 'second prompt'), + geminiItem(5), + ]; + const api: Content[] = [ + startupEntry(), + userContent('first prompt'), + modelContent('response 1'), + userContent('second prompt'), + modelContent('response 2'), + ]; + + expect(computeApiTruncationIndex(ui, 4, api)).toBe(3); + }); }); describe('mid-turn user messages (notification type)', () => { diff --git a/packages/cli/src/ui/utils/historyMapping.ts b/packages/cli/src/ui/utils/historyMapping.ts index fae29168218..bfe3df5ca8e 100644 --- a/packages/cli/src/ui/utils/historyMapping.ts +++ b/packages/cli/src/ui/utils/historyMapping.ts @@ -7,6 +7,7 @@ import type { HistoryItem, HistoryItemUser } from '../types.js'; import type { Content } from '@google/genai'; import { + CompressionStatus, getStartupContextLength, isSystemReminderContent, } from '@qwen-code/qwen-code-core'; @@ -58,6 +59,14 @@ function isUserTextContent(content: Content): boolean { return content.parts.some((part) => 'text' in part && part.text); } +function findLastSuccessfulCompressionIndex(history: HistoryItem[]): number { + return history.findLastIndex( + (item) => + item.type === 'compression' && + item.compression.compressionStatus === CompressionStatus.COMPRESSED, + ); +} + /** * Computes the number of API Content[] entries to keep when rewinding * to a specific user turn in the UI history. @@ -88,12 +97,22 @@ export function computeApiTruncationIndex( targetUserItemId: number, apiHistory: Content[], ): number { + const targetIndex = uiHistory.findIndex( + (item) => item.id === targetUserItemId, + ); + if (targetIndex === -1) return -1; + + const compressionIndex = findLastSuccessfulCompressionIndex(uiHistory); + if (compressionIndex !== -1 && targetIndex <= compressionIndex) return -1; + // Count how many UI user turns exist before the target let uiUserTurnCount = 0; - for (const item of uiHistory) { - if (item.id === targetUserItemId) { - break; - } + for ( + let i = compressionIndex === -1 ? 0 : compressionIndex + 1; + i < targetIndex; + i++ + ) { + const item = uiHistory[i]!; if (isRealUserTurn(item)) { uiUserTurnCount++; }