diff --git a/.opencode/init b/.opencode/init new file mode 100644 index 000000000..e69de29bb diff --git a/DB-GPT-Core-Code-Design-Analysis.md b/DB-GPT-Core-Code-Design-Analysis.md new file mode 100644 index 000000000..1ae170d88 --- /dev/null +++ b/DB-GPT-Core-Code-Design-Analysis.md @@ -0,0 +1,362 @@ + +# DB-GPT Core Code Design Analysis + +## Overview + +This document provides a comprehensive analysis of DB-GPT's core code design, examining the packages directory structure and understanding the architectural decisions, purposes, and problems solved by each component. + +## Package Architecture Overview + +DB-GPT follows a modular, layered architecture consisting of 6 main packages: + +``` +packages/ +├── dbgpt-core/ # Core abstractions and interfaces +├── dbgpt-serve/ # Service layer with REST APIs +├── dbgpt-app/ # Application layer and business logic +├── dbgpt-client/ # Client SDK and API interfaces +├── dbgpt-ext/ # Extensions and integrations +└── dbgpt-accelerator/ # Performance acceleration modules +``` + +## 1. dbgpt-core: The Foundation Layer + +### Design Purpose +The `dbgpt-core` package serves as the foundational layer that defines all core abstractions, interfaces, and utilities used throughout the entire DB-GPT ecosystem. + +### Key Design Decisions + +#### 1.1 Component System (`component.py`) +```python +class SystemApp(LifeCycle): + """Main System Application class that manages the lifecycle and registration of components.""" +``` + +**Why this design:** +- **Dependency Injection**: Provides a centralized component registry for service discovery +- **Lifecycle Management**: Standardizes component initialization, startup, and shutdown phases +- **Modularity**: Enables loose coupling between different system components + +**Problems solved:** +- Eliminates circular dependencies between modules +- Provides consistent component lifecycle management +- Enables dynamic component registration and discovery + +#### 1.2 Core Interfaces (`core/interface/`) +The core package defines essential interfaces: + +- **LLM Interface**: `llm.py` - Abstracts different language model providers +- **Storage Interface**: `storage.py` - Unified storage abstraction for various backends +- **Message Interface**: `message.py` - Standardizes conversation and message handling +- **Embedding Interface**: `embeddings.py` - Abstracts embedding model implementations + +**Why this design:** +- **Provider Agnostic**: Allows switching between different LLM providers without code changes +- **Extensibility**: New implementations can be added without modifying existing code +- **Type Safety**: Provides strong typing for all core operations + +#### 1.3 AWEL (Agentic Workflow Expression Language) (`core/awel/`) +```python +# AWEL provides declarative workflow orchestration +dag/ # Directed Acyclic Graph management +operators/ # Workflow operators +trigger/ # Event triggers +flow/ # Workflow execution flows +``` + +**Why this design:** +- **Declarative Workflows**: Enables complex AI workflows to be defined as code +- **Visual Programming**: Supports UI-based workflow creation +- **Scalability**: DAG-based execution ensures proper dependency management + +**Problems solved:** +- Complex AI pipeline orchestration +- Visual workflow design requirements +- Parallel and sequential task execution + +### Dependencies and Extras +```toml +# Core dependencies are minimal +dependencies = [ + "aiohttp==3.8.4", + "pydantic>=2.6.0", + "typeguard", + "snowflake-id", +] + +# Rich optional dependencies for different use cases +[project.optional-dependencies] +agent = ["termcolor", "pandas", "mcp>=1.4.1"] +framework = ["SQLAlchemy", "alembic", "transformers"] +``` + +**Design Rationale:** +- **Minimal Core**: Keeps the core lightweight with only essential dependencies +- **Optional Features**: Allows users to install only what they need +- **Conflict Resolution**: Handles version conflicts between different model providers + +## 2. dbgpt-serve: The Service Layer + +### Design Purpose +Provides RESTful APIs and service endpoints for all core functionalities, implementing the service-oriented architecture pattern. + +### Key Components Structure +``` +dbgpt_serve/ +├── agent/ # Agent lifecycle and management services +├── conversation/ # Chat and conversation management +├── datasource/ # Data source connectivity services +├── flow/ # AWEL workflow services +├── model/ # Model serving and management +├── rag/ # RAG pipeline services +├── prompt/ # Prompt management services +└── core/ # Common service utilities +``` + +### Design Decisions + +#### 2.1 Service-Oriented Architecture +**Why this design:** +- **Microservices Ready**: Each service can be independently deployed +- **API Standardization**: Consistent REST API patterns across all services +- **Horizontal Scaling**: Services can be scaled independently based on load + +#### 2.2 Minimal Dependencies +```toml +dependencies = ["dbgpt-ext"] +``` + +**Why this design:** +- **Separation of Concerns**: Service layer focuses only on API exposure +- **Dependency Inversion**: Depends on abstractions rather than implementations +- **Modularity**: Can be deployed with different extension combinations + +**Problems solved:** +- API standardization across different functionalities +- Service discovery and registry +- Independent service deployment and scaling + +## 3. dbgpt-app: The Application Layer + +### Design Purpose +Serves as the main application server that orchestrates all services and provides the complete DB-GPT application experience. + +### Key Components +``` +dbgpt_app/ +├── dbgpt_server.py # Main FastAPI application +├── component_configs.py # Component configuration and registration +├── base.py # Database and initialization logic +├── scene/ # Business scenario implementations +├── openapi/ # OpenAPI endpoint definitions +└── initialization/ # Startup and migration logic +``` + +### Design Decisions + +#### 3.1 Application Orchestration (`dbgpt_server.py`) +```python +system_app = SystemApp(app) +mount_routers(app) +initialize_components(param, system_app) +``` + +**Why this design:** +- **Centralized Orchestration**: Single entry point for the entire application +- **Component Integration**: Brings together all packages into a cohesive application +- **Configuration Management**: Centralizes all configuration concerns + +#### 3.2 Business Scene Management (`scene/`) +**Why this design:** +- **Business Logic Separation**: Isolates business scenarios from technical infrastructure +- **Extensible Scenarios**: New business scenarios can be added without modifying core logic +- **Domain-Driven Design**: Organizes code around business concepts + +#### 3.3 Full Dependency Integration +```toml +dependencies = [ + "dbgpt-acc-auto", + "dbgpt", + "dbgpt-ext", + "dbgpt-serve", + "dbgpt-client" +] +``` + +**Problems solved:** +- Integration of all system components +- Business scenario implementation +- Complete application lifecycle management +- Database migration and initialization + +## 4. dbgpt-client: The Client SDK Layer + +### Design Purpose +Provides a unified Python SDK for external applications to interact with DB-GPT services. + +### Key Components +``` +dbgpt_client/ +├── client.py # Main client implementation +├── schema.py # Request/response schemas +├── app.py # Application management client +├── flow.py # Workflow management client +├── knowledge.py # Knowledge base management client +└── datasource.py # Data source management client +``` + +### Design Decisions + +#### 4.1 Unified Client Interface +```python +class Client: + async def chat(self, model: str, messages: Union[str, List[str]], ...) + async def chat_stream(self, model: str, messages: Union[str, List[str]], ...) +``` + +**Why this design:** +- **Ease of Use**: Single client handles all DB-GPT functionality +- **Type Safety**: Strongly typed interfaces for all operations +- **Async Support**: Modern async/await patterns for better performance + +#### 4.2 OpenAI-Compatible Interface +**Why this design:** +- **Compatibility**: Allows existing OpenAI-based applications to integrate easily +- **Standard Patterns**: Follows established AI API conventions +- **Migration Path**: Provides smooth migration from OpenAI to DB-GPT + +**Problems solved:** +- External system integration +- SDK standardization +- API client management and authentication + +## 5. dbgpt-ext: The Extension Layer + +### Design Purpose +Implements concrete extensions for data sources, storage backends, LLM providers, and other integrations. + +### Key Components +``` +dbgpt_ext/ +├── datasource/ # Database and data source connectors +├── storage/ # Vector stores and storage backends +├── rag/ # RAG implementation extensions +├── llms/ # LLM provider implementations +└── vis/ # Visualization extensions +``` + +### Design Decisions + +#### 5.1 Plugin Architecture +```toml +[project.optional-dependencies] +storage_milvus = ["pymilvus"] +storage_chromadb = ["chromadb>=0.4.22"] +datasource_mysql = ["mysqlclient==2.1.0"] +``` + +**Why this design:** +- **Modular Extensions**: Users install only needed integrations +- **Version Isolation**: Prevents dependency conflicts between different backends +- **Easy Integration**: New providers can be added without core changes + +#### 5.2 Provider Abstractions +**Why this design:** +- **Vendor Independence**: Switch between providers without code changes +- **Consistent Interfaces**: Same API regardless of underlying implementation +- **Performance Optimization**: Provider-specific optimizations while maintaining compatibility + +**Problems solved:** +- Multi-provider support +- Dependency management complexity +- Integration with external systems + +## 6. dbgpt-accelerator: The Performance Layer + +### Design Purpose +Provides performance optimization modules for model inference and computation acceleration. + +### Key Components +``` +dbgpt-accelerator/ +├── dbgpt-acc-auto/ # Automatic acceleration detection +└── dbgpt-acc-flash-attn/ # Flash Attention acceleration +``` + +### Design Decisions + +#### 6.1 Modular Acceleration +**Why this design:** +- **Optional Performance**: Acceleration is opt-in based on hardware capabilities +- **Hardware Specific**: Different optimizations for different hardware configurations +- **Fallback Support**: Graceful degradation when acceleration is unavailable + +**Problems solved:** +- Model inference performance +- Hardware-specific optimizations +- Memory efficiency improvements + +## Architectural Design Principles + +### 1. Separation of Concerns +Each package has a distinct responsibility: +- **Core**: Abstractions and interfaces +- **Serve**: API endpoints and services +- **App**: Business logic and orchestration +- **Client**: External integration +- **Ext**: Concrete implementations +- **Accelerator**: Performance optimizations + +### 2. Dependency Inversion +Higher-level modules (app, serve) depend on abstractions (core) rather than concrete implementations (ext). + +### 3. Open/Closed Principle +The system is open for extension (new providers, storage backends) but closed for modification (core interfaces remain stable). + +### 4. Interface Segregation +Interfaces are focused and cohesive, allowing clients to depend only on methods they use. + +## Problems Solved by This Design + +### 1. **Complexity Management** +- Modular architecture breaks down complexity into manageable pieces +- Clear separation of concerns reduces cognitive load +- Standardized interfaces reduce integration complexity + +### 2. **Scalability Requirements** +- Service-oriented architecture enables horizontal scaling +- Component-based design allows selective optimization +- Microservices-ready architecture supports distributed deployment + +### 3. **Extensibility Needs** +- Plugin architecture enables easy addition of new providers +- Interface-based design allows swapping implementations +- Optional dependencies support different deployment scenarios + +### 4. **Integration Challenges** +- Unified client SDK simplifies external integration +- OpenAI-compatible APIs reduce migration barriers +- Standardized schemas ensure interoperability + +### 5. **Performance Optimization** +- Separate acceleration packages for hardware-specific optimizations +- Optional performance modules prevent dependency bloat +- Modular design enables selective performance tuning + +### 6. **Development Productivity** +- Component lifecycle management reduces boilerplate code +- Dependency injection simplifies testing and development +- Clear architectural boundaries improve team productivity + +## Conclusion + +DB-GPT's package architecture demonstrates sophisticated software engineering principles: + +1. **Layered Architecture**: Clear separation between core abstractions, services, applications, and extensions +2. **Modular Design**: Each package serves a specific purpose with minimal overlap +3. **Dependency Management**: Careful dependency design prevents circular dependencies and version conflicts +4. **Extensibility**: Plugin architecture enables easy addition of new capabilities +5. **Performance**: Separate acceleration packages provide hardware-specific optimizations +6. **Developer Experience**: Unified APIs and strong typing improve development productivity + +This design enables DB-GPT to serve as a robust, scalable foundation for AI-native data applications while maintaining flexibility for diverse deployment scenarios and integration requirements. \ No newline at end of file diff --git a/examples/agents/README_SKILL_AGENT.md b/examples/agents/README_SKILL_AGENT.md new file mode 100644 index 000000000..6974bb3fe --- /dev/null +++ b/examples/agents/README_SKILL_AGENT.md @@ -0,0 +1,8 @@ +Skill integration notes and quick run for the skill-enabled agent example + +Run the example: + +python examples/agents/skill_agent_example.py + +Ensure you have the environment variables needed by the local LLM client, or +replace the LLM client construction with a mock for testing. diff --git a/examples/agents/claude_skill_example.py b/examples/agents/claude_skill_example.py new file mode 100644 index 000000000..5bd938e1e --- /dev/null +++ b/examples/agents/claude_skill_example.py @@ -0,0 +1,102 @@ +""" +Example: Using Claude-style SKILL files with DB-GPT agents. + +This demonstrates how to use the Claude SKILL mechanism +where skills are defined in Markdown files. +""" + +import asyncio +import os + +from dbgpt.agent import AgentContext, AgentMemory, LLMConfig +from dbgpt.agent.claude_skill import ( + ClaudeSkillAgent, + get_registry, + load_skills_from_dir, +) +from dbgpt.model.proxy.llms.siliconflow import SiliconFlowLLMClient + + +async def main(): + """Main function demonstrating Claude SKILL usage.""" + + # Load skills from directory + skill_dir = os.path.join(os.path.dirname(__file__), "../skills/claude") + + load_skills_from_dir(skill_dir, recursive=True) + + # List available skills + registry = get_registry() + print("Loaded skills:") + for skill_metadata in registry.list_skills(): + print(f" - {skill_metadata.name}: {skill_metadata.description}") + + # Create LLM client + llm_client = SiliconFlowLLMClient( + model_alias=os.getenv( + "SILICONFLOW_MODEL_VERSION", "Qwen/Qwen2.5-Coder-32B-Instruct" + ), + ) + + # Create agent context + agent_memory = AgentMemory() + agent_memory.gpts_memory.init(conv_id="claude_skill_test") + + context: AgentContext = AgentContext( + conv_id="claude_skill_test", + gpts_app_name="Claude Skill Agent", + ) + + # Create Claude Skill Agent + agent = ClaudeSkillAgent() + + # Bind necessary components + await ( + agent.bind(context) + .bind(LLMConfig(llm_client=llm_client)) + .bind(agent_memory) + .build() + ) + + print("\n" + "=" * 60) + print("Claude Skill Agent Ready!") + print("=" * 60) + + # Example interactions + test_inputs = [ + "Can you explain how this code works?", + "My code isn't working, can you help debug it?", + "Write a function to sort a list", + "Simplify this complex code for me", + ] + + print("\nTest inputs and skill detection:") + print("-" * 60) + + for user_input in test_inputs: + agent.detect_and_apply_skill(user_input) + + if agent.current_skill: + print(f"Input: {user_input}") + print(f"Matched Skill: {agent.current_skill.metadata.name}") + print(f"Description: {agent.current_skill.metadata.description}") + print(f"Instructions preview: {agent.current_skill.instructions[:100]}...") + print() + + # Show available skills + print("\nAvailable skills:") + for skill_name in agent.get_available_skills(): + print(f" - {skill_name}") + + # Manual skill selection example + print("\n" + "-" * 60) + print("Manual skill selection:") + agent.set_skill("explain-code") + print(f"Current skill: {agent.current_skill.metadata.name}") + + agent.clear_skill() + print(f"After clearing: {agent.current_skill}") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/agents/excel_data_agent.py b/examples/agents/excel_data_agent.py new file mode 100644 index 000000000..899c36235 --- /dev/null +++ b/examples/agents/excel_data_agent.py @@ -0,0 +1,291 @@ +"""Excel Data Analysis Agent Example (ReAct Version with Built-in Skill Metadata). + +This example demonstrates a ReAct agent that has pre-loaded metadata about available skills +in its system prompt. It can choose to load a specific skill to get detailed instructions +without needing to search/list first. +""" + +import asyncio +import logging +import os +import sys + +# Add project root to sys.path +project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) +if project_root not in sys.path: + sys.path.append(project_root) + +from dbgpt.agent import ( + AgentContext, + AgentMemory, + LLMConfig, + UserProxyAgent, + ProfileConfig, +) +from dbgpt.agent.expand.react_agent import ReActAgent +from dbgpt.agent.skill import ( + SkillLoader, + initialize_skill, +) +from dbgpt.agent.resource import ToolPack, tool +from dbgpt.agent.expand.actions.react_action import Terminate +from dbgpt.model import AutoLLMClient +from dbgpt.agent.resource.manage import ( + get_resource_manager, + initialize_resource, +) +from dbgpt.agent.resource.skill_resource import SkillResource + +# Configure logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +# --- Global Execution Context --- +import pandas as pd +import numpy as np +import matplotlib.pyplot as plt + +GLOBAL_EXECUTION_CONTEXT = {"pd": pd, "np": np, "plt": plt, "print": print} + + +# --- Helpers --- + + +def scan_skills(skills_dir: str): + """Scan the skills directory and return a list of skill metadata dicts.""" + skills = [] + if not os.path.exists(skills_dir): + return skills + + # Use SkillLoader to properly load metadata if possible, + # but for scanning we might just want to peek at files to be fast. + # Here we will try to load them to get accurate descriptions. + loader = SkillLoader() + + for root, dirs, files in os.walk(skills_dir): + if "SKILL.md" in files: + skill_path = os.path.join(root, "SKILL.md") + try: + # We load the skill to get its metadata (name, description) + skill = loader.load_skill_from_file(skill_path) + if skill and skill.metadata: + skills.append( + { + "name": skill.metadata.name, + "description": skill.metadata.description, + "path": os.path.relpath(skill_path, project_root), + } + ) + except Exception as e: + logger.warning(f"Failed to load skill at {skill_path}: {e}") + return skills + + +# --- Tools --- + + +@tool +def code_interpreter(code: str) -> str: + """Execute Python code for data analysis. + + This tool allows you to run Python code to analyze data. You can use pandas, numpy, + matplotlib, etc. The environment is persistent between calls. + + Args: + code: The Python code to execute. + + Returns: + The standard output and any error messages from the execution. + """ + try: + import io + import sys + import ast + + # AST transformation: wrap last expression in print() if needed + try: + tree = ast.parse(code) + if tree.body and isinstance(tree.body[-1], ast.Expr): + expr_node = tree.body[-1] + print_call = ast.Call( + func=ast.Name(id="print", ctx=ast.Load()), + args=[expr_node.value], + keywords=[], + ) + tree.body[-1] = ast.Expr(value=print_call) + ast.fix_missing_locations(tree) + compiled_code = compile(tree, filename="", mode="exec") + except Exception: + compiled_code = code + + old_stdout = sys.stdout + redirected_output = sys.stdout = io.StringIO() + + exec(compiled_code, GLOBAL_EXECUTION_CONTEXT) + + sys.stdout = old_stdout + return redirected_output.getvalue() + except Exception as e: + return f"Execution Error: {str(e)}" + + +@tool +def load_skill(skill_name: str) -> str: + """Load a skill to get detailed instructions for a specific task. + + Use this tool when you want to "read" or "activate" a skill from your available list. + It returns the full content and instructions of the skill. + + Args: + skill_name: The name of the skill to load (must be one of the available skills). + + Returns: + The detailed instructions and workflow defined in the skill. + """ + # In a real implementation, we would use the SkillManager or a registry lookup. + # For this script, we'll scan again or use a cached lookup to find the path. + skills_dir = os.path.join(project_root, "skills") + target_skill_path = None + + # Simple search + for root, dirs, files in os.walk(skills_dir): + if "SKILL.md" in files: + # Check if this folder or metadata matches the requested name + # We'll try to match loosely by folder name or strict check if we loaded metadata + # For robustness in this example, let's load it to check name. + try: + loader = SkillLoader() + path = os.path.join(root, "SKILL.md") + skill = loader.load_skill_from_file(path) + if skill and skill.metadata.name == skill_name: + target_skill_path = path + break + except: + continue + + if not target_skill_path: + return f"Error: Skill '{skill_name}' not found." + + try: + with open(target_skill_path, "r", encoding="utf-8") as f: + content = f.read() + return f"Successfully loaded skill '{skill_name}'.\n\nSKILL CONTENT:\n{content}" + except Exception as e: + return f"Error reading skill file: {str(e)}" + + +async def main(): + """Main execution function.""" + system_app = SystemApp() + + # 1. Initialize Managers + initialize_skill(system_app) + initialize_resource(system_app) + + # 2. Setup LLM + llm_client = AutoLLMClient( + provider=os.getenv("LLM_PROVIDER", "proxy/siliconflow"), + name=os.getenv("LLM_MODEL_NAME", "Qwen/Qwen2.5-Coder-32B-Instruct"), + ) + + # 3. Scan for Skills + skills_dir = os.path.join(project_root, "skills") + available_skills_list = scan_skills(skills_dir) + + # 4. Construct Skill Prompt Section + if not available_skills_list: + skill_section = "Load a skill to get detailed instructions for a specific task. No skills are currently available." + else: + skills_xml = [] + for s in available_skills_list: + skills_xml.append(f" ") + skills_xml.append(f" {s['name']}") + skills_xml.append(f" {s['description']}") + skills_xml.append(f" ") + + skill_section_str = "\n".join(skills_xml) + skill_section = ( + "Load a skill to get detailed instructions for a specific task.\n" + "Skills provide specialized knowledge and step-by-step guidance.\n" + "Use this when a task matches an available skill's description.\n" + "Only the skills listed here are available:\n" + "\n" + f"{skill_section_str}\n" + "" + ) + + # 5. Context & Memory + context = AgentContext( + conv_id="skill_metadata_session", gpts_app_name="Skill Specialist" + ) + agent_memory = AgentMemory() + agent_memory.gpts_memory.init(conv_id="skill_metadata_session") + + # 6. Tools (Notice: No list tool, just load/read) + tools = ToolPack([load_skill, code_interpreter, Terminate()]) + + # 7. Profile + profile = ProfileConfig( + name="SkillAwareAgent", + role="Adaptive Assistant", + goal=( + "You are an intelligent assistant. " + f"{skill_section}\n\n" + "WORKFLOW:\n" + "1. Analyze the user's request.\n" + "2. Identify if an available skill in matches the request.\n" + "3. If yes, use the `load_skill` tool with the skill's name to get instructions.\n" + "4. Follow the loaded instructions strictly to complete the task using `code_interpreter`." + ), + ) + + # 8. Build ReAct Agent + agent = ( + await ReActAgent( + profile=profile, + max_retry_count=5, + ) + .bind(context) + .bind(LLMConfig(llm_client=llm_client)) + .bind(agent_memory) + .bind(tools) + .build() + ) + + # 9. User Proxy + user_proxy = await UserProxyAgent().bind(agent_memory).bind(context).build() + + # 10. Test Data Setup + test_file = "sales_data_sample.xlsx" + df = pd.DataFrame( + { + "Date": pd.date_range(start="1/1/2023", periods=10), + "Product": ["Widget A", "Widget B", "Widget A", "Widget C", "Widget B"] * 2, + "Sales": [100, 200, 150, 300, 250, 120, 220, 160, 310, 260], + "Region": ["North", "South", "North", "East", "South"] * 2, + } + ) + df.to_excel(test_file, index=False) + abs_test_file = os.path.abspath(test_file) + logger.info(f"Created test file: {abs_test_file}") + + # 11. Start Chat + msg = f"I have a file at '{abs_test_file}'. Analyze the sales data." + + logger.info("Starting session...") + await user_proxy.initiate_chat( + recipient=agent, + reviewer=user_proxy, + message=msg, + ) + + # Cleanup + if os.path.exists(test_file): + os.remove(test_file) + logger.info("Test file cleaned up.") + + +from dbgpt.component import SystemApp + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/agents/skill_agent_example.py b/examples/agents/skill_agent_example.py new file mode 100644 index 000000000..3d9d12907 --- /dev/null +++ b/examples/agents/skill_agent_example.py @@ -0,0 +1,210 @@ +"""Example: Agent with Skill loading mechanism. + +This example demonstrates how to use the SKILL loading mechanism +with DB-GPT agents. +""" + +import asyncio +import logging +import os + +from dbgpt.agent import ( + AgentContext, + AgentMemory, + ConversableAgent, + LLMConfig, + UserProxyAgent, +) +from dbgpt.agent.skill import ( + Skill, + SkillBuilder, + SkillLoader, + SkillManager, + SkillType, + get_skill_manager, + initialize_skill, +) +from dbgpt.agent.core.profile.base import ProfileConfig +from dbgpt.agent.resource import tool +from dbgpt.component import SystemApp +from dbgpt.agent.core.action.base import ActionOutput +from dbgpt.agent.expand.actions.tool_action import ToolAction +from dbgpt.agent.resource import ToolPack +from dbgpt.agent.expand.actions.react_action import Terminate +from dbgpt.model import AutoLLMClient + + +@tool +def calculate(expression: str) -> str: + """Calculate a mathematical expression. + + Args: + expression: The mathematical expression to calculate (e.g., "1 + 2 * 3"). + + Returns: + The result of the calculation. + """ + try: + result = eval(expression, {"__builtins__": {}}, {}) + return str(result) + except Exception as e: + return f"Error: {str(e)}" + + +# Use ToolAction as the agent's action module to enable tool usage. + + +class MathSkillAgent(ConversableAgent): + """Agent with math skill. + + Supports binding a Skill instance using `.bind(skill_instance)` so that + skills can be provided either in the constructor or later via `bind`. + """ + + def __init__(self, skill: Skill | None = None, **kwargs): + """Initialize the agent with an optional skill.""" + super().__init__(**kwargs) + self._skill = skill + + @property + def skill(self) -> Skill: + """Return the skill if bound, otherwise raise a helpful error.""" + if not getattr(self, "_skill", None): + raise ValueError( + "Skill not bound to agent. Call .bind(skill) before build()." + ) + return self._skill + + +async def main(): + """Main function.""" + system_app = SystemApp() + + # Initialize skill manager + initialize_skill(system_app) + skill_manager = get_skill_manager(system_app) + + # First try to load a SKILL.md from skills/claude + loader = SkillLoader() + loaded_from_file = None + try: + loaded_from_file = loader.load_skill_from_file( + "/Users/chenketing.ckt/Desktop/project/DB-GPT/skills/claude/math_assistant/SKILL.md" + ) + if loaded_from_file: + # register loaded skill (demonstrate file-based loading path) + skill_manager.register_skill( + skill_instance=loaded_from_file, name=loaded_from_file.metadata.name + ) + print(f"Loaded SKILL.md skill: {loaded_from_file.metadata.name}") + except Exception: + loaded_from_file = None + + # If SKILL.md not available, fall back to building programmatically + if not loaded_from_file: + math_skill = ( + SkillBuilder( + name="math_assistant", description="Mathematical calculation assistant" + ) + .with_version("1.0.0") + .with_author("DB-GPT Team") + .with_skill_type(SkillType.Chat) + .with_tags(["math", "calculation"]) + .with_prompt_template( + "You are a mathematical assistant. Help users with calculations and " + "explain mathematical concepts clearly. Use the calculate tool for " + "computations." + ) + .with_required_tool("calculate") + .build() + ) + + # Register the skill + skill_manager.register_skill( + skill_instance=math_skill, + name="math_assistant", + ) + loaded_skill = skill_manager.get_skill(name="math_assistant") + if loaded_skill: + print(f"Loaded programmatic skill: {loaded_skill.metadata.name}") + else: + loaded_skill = loaded_from_file + + # Create an LLM client similar to react_agent_example so the example can + # interact with a real model provider. Configure via environment variables. + logging.basicConfig(level=logging.INFO) + llm_client = AutoLLMClient( + provider=os.getenv("LLM_PROVIDER", "proxy/siliconflow"), + name=os.getenv("LLM_MODEL_NAME", "Qwen/Qwen2.5-Coder-32B-Instruct"), + ) + + agent_memory = AgentMemory() + agent_memory.gpts_memory.init(conv_id="skill_test_001") + + context: AgentContext = AgentContext( + conv_id="skill_test_001", gpts_app_name="Math Skill Agent" + ) + + # Create agent with skill (provide ProfileConfig required by agent role) + profile = ProfileConfig(name="MathAssistant", role="math_assistant") + # Instantiate agent with profile and skill + # If ResourceManager/SkillResource is not initialized when running example + # standalone, the agent will still work as we bind tools directly. However + # for completeness, register SkillResource with the global ResourceManager + # so other components (ToolAction) can resolve skills if needed. + try: + from dbgpt.agent.resource.manage import ( + get_resource_manager, + initialize_resource, + ) + from dbgpt.agent.resource.skill_resource import SkillResource + + initialize_resource(system_app) + rm = get_resource_manager(system_app) + rm.register_resource(SkillResource, resource_type=None) + except Exception as e: + print(e) + # ignore registration failures in example runs + pass + + # Create a ToolPack from the calculate tool and bind it as the agent's resource + tool_packs = ToolPack.from_resource([calculate, Terminate()]) + tool_pack = tool_packs[0] + + # Create agent and bind the loaded skill via .bind(skill) so skills can be + # injected at runtime rather than only via constructor. + math_agent = ( + await MathSkillAgent(profile=profile) + .bind(loaded_skill) + .bind(context) + .bind(LLMConfig(llm_client=llm_client)) + .bind(agent_memory) + .bind(tool_pack) + .bind(ToolAction) + .build() + ) + + print("Math Skill Agent created successfully!") + print(f"Skill: {math_agent.skill.metadata.name}") + print(f"Skill type: {math_agent.skill.metadata.skill_type}") + print(f"Required tools: {math_agent.skill.required_tools}") + + # Create a user proxy to interact with the agent (same pattern as react example) + user_proxy = await UserProxyAgent().bind(agent_memory).bind(context).build() + + # Example interactions + await user_proxy.initiate_chat( + recipient=math_agent, + reviewer=user_proxy, + message="Compute 10 * 99 using the calculate tool and return the numeric result.", + ) + + # Show dbgpt-vis link messages + try: + print(await agent_memory.gpts_memory.app_link_chat_message("skill_test_001")) + except Exception: + pass + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/excel/excel_analysis.py b/examples/excel/excel_analysis.py new file mode 100644 index 000000000..ae17c7e0c --- /dev/null +++ b/examples/excel/excel_analysis.py @@ -0,0 +1,50 @@ +from flask import Flask, request, jsonify +import pandas as pd +import os + +app = Flask(__name__) +UPLOAD_FOLDER = '/tmp/uploads' +os.makedirs(UPLOAD_FOLDER, exist_ok=True) +app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER + +@app.route('/upload_excel', methods=['POST']) +def upload_excel(): + if 'file' not in request.files: + return jsonify({'error': 'No file uploaded'}), 400 + + file = request.files['file'] + if file.filename == '': + return jsonify({'error': 'No selected file'}), 400 + + file_path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename) + file.save(file_path) + + # Optional: Parse Excel to validate it works + try: + df = pd.read_excel(file_path) + columns = df.columns.tolist() + return jsonify({'message': 'File uploaded successfully', 'columns': columns}) + except Exception as e: + return jsonify({'error': str(e)}), 500 + +@app.route('/query_excel', methods=['POST']) +def query_excel(): + data = request.json + file_name = data.get('file_name') + query = data.get('query') + + file_path = os.path.join(app.config['UPLOAD_FOLDER'], file_name) + if not os.path.exists(file_path): + return jsonify({'error': 'File not found'}), 404 + + try: + df = pd.read_excel(file_path) + # Placeholder logic for querying the Excel file: + # This should be replaced with DB-GPT integration for natural language queries. + response = f"Query on {len(df)} rows completed." + return jsonify({'query_result': response}) + except Exception as e: + return jsonify({'error': str(e)}), 500 + +if __name__ == '__main__': + app.run(debug=True) \ No newline at end of file diff --git a/examples/test_skills_middleware.py b/examples/test_skills_middleware.py new file mode 100644 index 000000000..3e438df17 --- /dev/null +++ b/examples/test_skills_middleware.py @@ -0,0 +1,153 @@ +"""Test script for SkillsMiddlewareV2. + +This script demonstrates how to use the new middleware system +to load and use skills in DB-GPT agents. +""" + +import asyncio +import os +import sys + +sys.path.insert( + 0, os.path.join(os.path.dirname(__file__), "../../packages/dbgpt-core/src") +) + +from dbgpt.agent.core.profile.base import ProfileConfig +from dbgpt.agent.core.agent import AgentContext +from dbgpt.agent.middleware.agent import MiddlewareAgent, AgentConfig +from dbgpt.agent.skill.middleware_v2 import SkillsMiddlewareV2 + + +async def test_skills_middleware(): + """Test SkillsMiddlewareV2 functionality.""" + + skills_path = os.path.join(os.path.dirname(__file__), "skills/user") + + if not os.path.exists(skills_path): + print(f"Skills directory not found: {skills_path}") + print("Creating test skills...") + return + + config = AgentConfig( + enable_middleware=True, + enable_skills=True, + skill_sources=[skills_path], + skill_auto_load=True, + skill_auto_match=True, + skill_inject_to_prompt=True, + ) + + profile = ProfileConfig( + name="assistant", + role="AI Assistant", + goal="Help users with their tasks using available skills.", + ) + + agent = MiddlewareAgent( + profile=profile, + agent_config=config, + ) + + agent_context = AgentContext( + conv_id="test_conv_001", + language="zh-CN", + ) + + await agent.bind(agent_context).build() + + print("\n=== Skills Summary ===") + skills = agent.middleware_manager._middlewares[0] # Get SkillsMiddlewareV2 + print(skills.get_skills_summary()) + + print("\n=== Testing Skill Matching ===") + test_inputs = [ + "research quantum computing", + "review my python code", + "analyze this data", + ] + + for test_input in test_inputs: + print(f"\nInput: {test_input}") + matched = skills.match_skills(test_input) + if matched: + print(f"Matched skills: {[s.metadata.name for s in matched]}") + else: + print("No skills matched") + + print("\n=== Test Complete ===") + + +async def test_custom_middleware(): + """Test custom middleware.""" + + from dbgpt.agent.middleware.base import AgentMiddleware + + class LoggingMiddleware(AgentMiddleware): + """Custom middleware for logging.""" + + async def before_generate_reply(self, agent, context, **kwargs): + print(f"[LoggingMiddleware] Before generate reply") + if context and hasattr(context, "message"): + print(f" Message: {context.message.content[:50]}...") + + async def after_generate_reply(self, agent, context, reply_message, **kwargs): + print(f"[LoggingMiddleware] After generate reply") + if reply_message: + print(f" Reply: {reply_message.content[:50]}...") + + async def modify_system_prompt(self, agent, original_prompt, context=None): + modified = ( + f"\n[LoggingMiddleware] Custom prompt section\n\n{original_prompt}" + ) + return modified + + profile = ProfileConfig( + name="assistant", + role="AI Assistant", + ) + + config = AgentConfig( + enable_middleware=True, + enable_skills=False, # Disable skills for this test + ) + + agent = MiddlewareAgent( + profile=profile, + agent_config=config, + ) + + logging_middleware = LoggingMiddleware() + agent.register_middleware(logging_middleware) + + agent_context = AgentContext( + conv_id="test_logging_conv", + language="en", + ) + + await agent.bind(agent_context).build() + + print("\n=== Custom Middleware Test ===") + print("LoggingMiddleware has been registered") + print(f"Total middleware: {len(agent.middleware_manager._middlewares)}") + + print("\n=== Test Complete ===") + + +async def main(): + """Run all tests.""" + + print("=" * 80) + print("DB-GPT Skills Middleware Test") + print("=" * 80) + + print("\n\n### Test 1: SkillsMiddlewareV2 ###") + await test_skills_middleware() + + print("\n\n### Test 2: Custom Middleware ###") + await test_custom_middleware() + + print("\n\n### All Tests Complete ###") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/packages/dbgpt-app/src/dbgpt_app/openapi/api_v1/python_upload_api.py b/packages/dbgpt-app/src/dbgpt_app/openapi/api_v1/python_upload_api.py new file mode 100644 index 000000000..5f0c4e333 --- /dev/null +++ b/packages/dbgpt-app/src/dbgpt_app/openapi/api_v1/python_upload_api.py @@ -0,0 +1,57 @@ +import logging +import os + +from fastapi import APIRouter, UploadFile, File, Depends +from dbgpt_serve.utils.auth import UserRequest, get_user_from_headers +from dbgpt._private.config import Config +from dbgpt_app.openapi.api_view_model import Result + +router = APIRouter() +CFG = Config() +logger = logging.getLogger(__name__) + + +@router.post("/v1/python/file/upload", response_model=Result[str]) +async def python_file_upload( + file: UploadFile = File(...), + user_token: UserRequest = Depends(get_user_from_headers), +): + try: + if not file or not file.filename: + return Result.failed(msg="No file provided or filename is empty") + + user_id = user_token.user_id or "default" + logger.info( + f"Uploading file: {file.filename}, content_type: {file.content_type}, " + f"user: {user_id}" + ) + + # Determine upload base directory + base_dir = os.getcwd() + if ( + CFG.SYSTEM_APP + and hasattr(CFG.SYSTEM_APP, "work_dir") + and CFG.SYSTEM_APP.work_dir + ): + base_dir = CFG.SYSTEM_APP.work_dir + + upload_dir = os.path.join(base_dir, "python_uploads", user_id) + os.makedirs(upload_dir, exist_ok=True) + + file_path = os.path.join(upload_dir, file.filename) + + # Read file content and write to disk + content = await file.read() + if not content: + return Result.failed(msg="Uploaded file is empty") + + with open(file_path, "wb") as buffer: + buffer.write(content) + + abs_path = os.path.abspath(file_path) + logger.info(f"File uploaded successfully to {abs_path} ({len(content)} bytes)") + + return Result.succ(abs_path) + except Exception as e: + logger.exception(f"File upload failed: {e}") + return Result.failed(msg=f"Upload error: {str(e)}") diff --git a/packages/dbgpt-app/src/dbgpt_app/python_uploads/001/Walmart_Sales.csv b/packages/dbgpt-app/src/dbgpt_app/python_uploads/001/Walmart_Sales.csv new file mode 100644 index 000000000..d58bba96c --- /dev/null +++ b/packages/dbgpt-app/src/dbgpt_app/python_uploads/001/Walmart_Sales.csv @@ -0,0 +1,6436 @@ +Store,Date,Weekly_Sales,Holiday_Flag,Temperature,Fuel_Price,CPI,Unemployment +1,05-02-2010,1643690.9,0,42.31,2.572,211.0963582,8.106 +1,12-02-2010,1641957.44,1,38.51,2.548,211.2421698,8.106 +1,19-02-2010,1611968.17,0,39.93,2.514,211.2891429,8.106 +1,26-02-2010,1409727.59,0,46.63,2.561,211.3196429,8.106 +1,05-03-2010,1554806.68,0,46.5,2.625,211.3501429,8.106 +1,12-03-2010,1439541.59,0,57.79,2.667,211.3806429,8.106 +1,19-03-2010,1472515.79,0,54.58,2.72,211.215635,8.106 +1,26-03-2010,1404429.92,0,51.45,2.732,211.0180424,8.106 +1,02-04-2010,1594968.28,0,62.27,2.719,210.8204499,7.808 +1,09-04-2010,1545418.53,0,65.86,2.77,210.6228574,7.808 +1,16-04-2010,1466058.28,0,66.32,2.808,210.4887,7.808 +1,23-04-2010,1391256.12,0,64.84,2.795,210.4391228,7.808 +1,30-04-2010,1425100.71,0,67.41,2.78,210.3895456,7.808 +1,07-05-2010,1603955.12,0,72.55,2.835,210.3399684,7.808 +1,14-05-2010,1494251.5,0,74.78,2.854,210.3374261,7.808 +1,21-05-2010,1399662.07,0,76.44,2.826,210.6170934,7.808 +1,28-05-2010,1432069.95,0,80.44,2.759,210.8967606,7.808 +1,04-06-2010,1615524.71,0,80.69,2.705,211.1764278,7.808 +1,11-06-2010,1542561.09,0,80.43,2.668,211.4560951,7.808 +1,18-06-2010,1503284.06,0,84.11,2.637,211.4537719,7.808 +1,25-06-2010,1422711.6,0,84.34,2.653,211.3386526,7.808 +1,02-07-2010,1492418.14,0,80.91,2.669,211.2235333,7.787 +1,09-07-2010,1546074.18,0,80.48,2.642,211.108414,7.787 +1,16-07-2010,1448938.92,0,83.15,2.623,211.1003854,7.787 +1,23-07-2010,1385065.2,0,83.36,2.608,211.2351443,7.787 +1,30-07-2010,1371986.6,0,81.84,2.64,211.3699032,7.787 +1,06-08-2010,1605491.78,0,87.16,2.627,211.5046621,7.787 +1,13-08-2010,1508237.76,0,87,2.692,211.6394211,7.787 +1,20-08-2010,1513080.49,0,86.65,2.664,211.6033633,7.787 +1,27-08-2010,1449142.92,0,85.22,2.619,211.5673056,7.787 +1,03-09-2010,1540163.53,0,81.21,2.577,211.5312479,7.787 +1,10-09-2010,1507460.69,1,78.69,2.565,211.4951902,7.787 +1,17-09-2010,1430378.67,0,82.11,2.582,211.5224596,7.787 +1,24-09-2010,1351791.03,0,80.94,2.624,211.5972246,7.787 +1,01-10-2010,1453329.5,0,71.89,2.603,211.6719895,7.838 +1,08-10-2010,1508239.93,0,63.93,2.633,211.7467544,7.838 +1,15-10-2010,1459409.1,0,67.18,2.72,211.8137436,7.838 +1,22-10-2010,1345454,0,69.86,2.725,211.8612937,7.838 +1,29-10-2010,1384209.22,0,69.64,2.716,211.9088438,7.838 +1,05-11-2010,1551659.28,0,58.74,2.689,211.9563939,7.838 +1,12-11-2010,1494479.49,0,59.61,2.728,212.003944,7.838 +1,19-11-2010,1483784.18,0,51.41,2.771,211.8896737,7.838 +1,26-11-2010,1955624.11,1,64.52,2.735,211.7484333,7.838 +1,03-12-2010,1548033.78,0,49.27,2.708,211.607193,7.838 +1,10-12-2010,1682614.26,0,46.33,2.843,211.4659526,7.838 +1,17-12-2010,1891034.93,0,49.84,2.869,211.4053124,7.838 +1,24-12-2010,2387950.2,0,52.33,2.886,211.4051222,7.838 +1,31-12-2010,1367320.01,1,48.43,2.943,211.4049321,7.838 +1,07-01-2011,1444732.28,0,48.27,2.976,211.4047419,7.742 +1,14-01-2011,1391013.96,0,35.4,2.983,211.4574109,7.742 +1,21-01-2011,1327405.42,0,44.04,3.016,211.8272343,7.742 +1,28-01-2011,1316899.31,0,43.83,3.01,212.1970577,7.742 +1,04-02-2011,1606629.58,0,42.27,2.989,212.5668812,7.742 +1,11-02-2011,1649614.93,1,36.39,3.022,212.9367046,7.742 +1,18-02-2011,1686842.78,0,57.36,3.045,213.2478853,7.742 +1,25-02-2011,1456800.28,0,62.9,3.065,213.535609,7.742 +1,04-03-2011,1636263.41,0,59.58,3.288,213.8233327,7.742 +1,11-03-2011,1553191.63,0,53.56,3.459,214.1110564,7.742 +1,18-03-2011,1576818.06,0,62.76,3.488,214.3627114,7.742 +1,25-03-2011,1541102.38,0,69.97,3.473,214.5999389,7.742 +1,01-04-2011,1495064.75,0,59.17,3.524,214.8371664,7.682 +1,08-04-2011,1614259.35,0,67.84,3.622,215.0743939,7.682 +1,15-04-2011,1559889,0,71.27,3.743,215.2918561,7.682 +1,22-04-2011,1564819.81,0,72.99,3.807,215.4599053,7.682 +1,29-04-2011,1455090.69,0,72.03,3.81,215.6279544,7.682 +1,06-05-2011,1629391.28,0,64.61,3.906,215.7960035,7.682 +1,13-05-2011,1604775.58,0,75.64,3.899,215.9640526,7.682 +1,20-05-2011,1428218.27,0,67.63,3.907,215.7339202,7.682 +1,27-05-2011,1466046.67,0,77.72,3.786,215.5037878,7.682 +1,03-06-2011,1635078.41,0,83,3.699,215.2736553,7.682 +1,10-06-2011,1588948.32,0,83.13,3.648,215.0435229,7.682 +1,17-06-2011,1532114.86,0,86.41,3.637,214.9980596,7.682 +1,24-06-2011,1438830.15,0,83.58,3.594,215.0910982,7.682 +1,01-07-2011,1488538.09,0,85.55,3.524,215.1841368,7.962 +1,08-07-2011,1534849.64,0,85.83,3.48,215.2771754,7.962 +1,15-07-2011,1455119.97,0,88.54,3.575,215.3611087,7.962 +1,22-07-2011,1396926.82,0,85.77,3.651,215.4222784,7.962 +1,29-07-2011,1352219.79,0,86.83,3.682,215.4834482,7.962 +1,05-08-2011,1624383.75,0,91.65,3.684,215.544618,7.962 +1,12-08-2011,1525147.09,0,90.76,3.638,215.6057878,7.962 +1,19-08-2011,1530761.43,0,89.94,3.554,215.6693107,7.962 +1,26-08-2011,1464693.46,0,87.96,3.523,215.7332258,7.962 +1,02-09-2011,1550229.22,0,87.83,3.533,215.7971409,7.962 +1,09-09-2011,1540471.24,1,76,3.546,215.861056,7.962 +1,16-09-2011,1514259.78,0,79.94,3.526,216.0410526,7.962 +1,23-09-2011,1380020.27,0,75.8,3.467,216.3758246,7.962 +1,30-09-2011,1394561.83,0,79.69,3.355,216.7105965,7.962 +1,07-10-2011,1630989.95,0,69.31,3.285,217.0453684,7.866 +1,14-10-2011,1493525.93,0,71.74,3.274,217.3552733,7.866 +1,21-10-2011,1502562.78,0,63.71,3.353,217.5159762,7.866 +1,28-10-2011,1445249.09,0,66.57,3.372,217.6766791,7.866 +1,04-11-2011,1697229.58,0,54.98,3.332,217.837382,7.866 +1,11-11-2011,1594938.89,0,59.11,3.297,217.9980849,7.866 +1,18-11-2011,1539483.7,0,62.25,3.308,218.2205088,7.866 +1,25-11-2011,2033320.66,1,60.14,3.236,218.4676211,7.866 +1,02-12-2011,1584083.95,0,48.91,3.172,218.7147333,7.866 +1,09-12-2011,1799682.38,0,43.93,3.158,218.9618456,7.866 +1,16-12-2011,1881176.67,0,51.63,3.159,219.1794533,7.866 +1,23-12-2011,2270188.99,0,47.96,3.112,219.3577216,7.866 +1,30-12-2011,1497462.72,1,44.55,3.129,219.5359898,7.866 +1,06-01-2012,1550369.92,0,49.01,3.157,219.7142581,7.348 +1,13-01-2012,1459601.17,0,48.53,3.261,219.8925263,7.348 +1,20-01-2012,1394393.84,0,54.11,3.268,219.9856893,7.348 +1,27-01-2012,1319325.59,0,54.26,3.29,220.0788523,7.348 +1,03-02-2012,1636339.65,0,56.55,3.36,220.1720153,7.348 +1,10-02-2012,1802477.43,1,48.02,3.409,220.2651783,7.348 +1,17-02-2012,1819870,0,45.32,3.51,220.4257586,7.348 +1,24-02-2012,1539387.83,0,57.25,3.555,220.636902,7.348 +1,02-03-2012,1688420.76,0,60.96,3.63,220.8480454,7.348 +1,09-03-2012,1675431.16,0,58.76,3.669,221.0591887,7.348 +1,16-03-2012,1677472.78,0,64.74,3.734,221.2118132,7.348 +1,23-03-2012,1511068.07,0,65.93,3.787,221.2864126,7.348 +1,30-03-2012,1649604.63,0,67.61,3.845,221.3610119,7.348 +1,06-04-2012,1899676.88,0,70.43,3.891,221.4356112,7.143 +1,13-04-2012,1621031.7,0,69.07,3.891,221.5102105,7.143 +1,20-04-2012,1521577.87,0,66.76,3.877,221.5640737,7.143 +1,27-04-2012,1468928.37,0,67.23,3.814,221.6179368,7.143 +1,04-05-2012,1684519.99,0,75.55,3.749,221.6718,7.143 +1,11-05-2012,1611096.05,0,73.77,3.688,221.7256632,7.143 +1,18-05-2012,1595901.87,0,70.33,3.63,221.742674,7.143 +1,25-05-2012,1555444.55,0,77.22,3.561,221.744944,7.143 +1,01-06-2012,1624477.58,0,77.95,3.501,221.7472139,7.143 +1,08-06-2012,1697230.96,0,78.3,3.452,221.7494839,7.143 +1,15-06-2012,1630607,0,79.35,3.393,221.7626421,7.143 +1,22-06-2012,1527845.81,0,78.39,3.346,221.8030211,7.143 +1,29-06-2012,1540421.49,0,84.88,3.286,221.8434,7.143 +1,06-07-2012,1769854.16,0,81.57,3.227,221.8837789,6.908 +1,13-07-2012,1527014.04,0,77.12,3.256,221.9241579,6.908 +1,20-07-2012,1497954.76,0,80.42,3.311,221.9327267,6.908 +1,27-07-2012,1439123.71,0,82.66,3.407,221.9412954,6.908 +1,03-08-2012,1631135.79,0,86.11,3.417,221.9498642,6.908 +1,10-08-2012,1592409.97,0,85.05,3.494,221.9584329,6.908 +1,17-08-2012,1597868.05,0,84.85,3.571,222.0384109,6.908 +1,24-08-2012,1494122.38,0,77.66,3.62,222.1719457,6.908 +1,31-08-2012,1582083.4,0,80.49,3.638,222.3054805,6.908 +1,07-09-2012,1661767.33,1,83.96,3.73,222.4390153,6.908 +1,14-09-2012,1517428.87,0,74.97,3.717,222.5820193,6.908 +1,21-09-2012,1506126.06,0,69.87,3.721,222.7818386,6.908 +1,28-09-2012,1437059.26,0,76.08,3.666,222.9816579,6.908 +1,05-10-2012,1670785.97,0,68.55,3.617,223.1814772,6.573 +1,12-10-2012,1573072.81,0,62.99,3.601,223.3812965,6.573 +1,19-10-2012,1508068.77,0,67.97,3.594,223.4257233,6.573 +1,26-10-2012,1493659.74,0,69.16,3.506,223.4442513,6.573 +2,05-02-2010,2136989.46,0,40.19,2.572,210.7526053,8.324 +2,12-02-2010,2137809.5,1,38.49,2.548,210.8979935,8.324 +2,19-02-2010,2124451.54,0,39.69,2.514,210.9451605,8.324 +2,26-02-2010,1865097.27,0,46.1,2.561,210.9759573,8.324 +2,05-03-2010,1991013.13,0,47.17,2.625,211.0067542,8.324 +2,12-03-2010,1990483.78,0,57.56,2.667,211.037551,8.324 +2,19-03-2010,1946070.88,0,54.52,2.72,210.8733316,8.324 +2,26-03-2010,1750197.81,0,51.26,2.732,210.6766095,8.324 +2,02-04-2010,2066187.72,0,63.27,2.719,210.4798874,8.2 +2,09-04-2010,1954689.21,0,65.41,2.77,210.2831653,8.2 +2,16-04-2010,1874957.94,0,68.07,2.808,210.1495463,8.2 +2,23-04-2010,1821990.93,0,65.11,2.795,210.1000648,8.2 +2,30-04-2010,1802450.29,0,66.98,2.78,210.0505833,8.2 +2,07-05-2010,2042581.71,0,71.28,2.835,210.0011018,8.2 +2,14-05-2010,1880752.36,0,73.31,2.854,209.9984585,8.2 +2,21-05-2010,1896937.1,0,74.83,2.826,210.2768443,8.2 +2,28-05-2010,1957113.89,0,81.13,2.759,210.5552301,8.2 +2,04-06-2010,2102539.93,0,81.81,2.705,210.833616,8.2 +2,11-06-2010,2025538.76,0,83.4,2.668,211.1120018,8.2 +2,18-06-2010,2001636.96,0,85.81,2.637,211.1096543,8.2 +2,25-06-2010,1939927.09,0,86.26,2.653,210.9950134,8.2 +2,02-07-2010,2003940.64,0,82.74,2.669,210.8803726,8.099 +2,09-07-2010,1880902.62,0,82.59,2.642,210.7657317,8.099 +2,16-07-2010,1845879.79,0,85.32,2.623,210.7577954,8.099 +2,23-07-2010,1781717.71,0,87.66,2.608,210.8921319,8.099 +2,30-07-2010,1804246.16,0,83.49,2.64,211.0264684,8.099 +2,06-08-2010,1991909.98,0,89.53,2.627,211.1608049,8.099 +2,13-08-2010,1895601.05,0,89.05,2.692,211.2951413,8.099 +2,20-08-2010,1964335.23,0,88.7,2.664,211.2596586,8.099 +2,27-08-2010,1863840.49,0,87.12,2.619,211.2241759,8.099 +2,03-09-2010,1904608.09,0,81.83,2.577,211.1886931,8.099 +2,10-09-2010,1839128.83,1,79.09,2.565,211.1532104,8.099 +2,17-09-2010,1793903.6,0,82.05,2.582,211.1806415,8.099 +2,24-09-2010,1724557.22,0,81.79,2.624,211.2552578,8.099 +2,01-10-2010,1827440.43,0,69.24,2.603,211.3298742,8.163 +2,08-10-2010,1849921.44,0,63.19,2.633,211.4044906,8.163 +2,15-10-2010,1794355.49,0,65.8,2.72,211.4713286,8.163 +2,22-10-2010,1737947.64,0,68.5,2.725,211.5187208,8.163 +2,29-10-2010,1802755.11,0,66.24,2.716,211.5661131,8.163 +2,05-11-2010,1939061.41,0,57.85,2.689,211.6135053,8.163 +2,12-11-2010,1916812.74,0,59.69,2.728,211.6608975,8.163 +2,19-11-2010,1956739.17,0,50.81,2.771,211.5470304,8.163 +2,26-11-2010,2658725.29,1,62.98,2.735,211.4062867,8.163 +2,03-12-2010,2015781.27,0,49.33,2.708,211.265543,8.163 +2,10-12-2010,2378726.55,0,45.5,2.843,211.1247993,8.163 +2,17-12-2010,2609166.75,0,47.55,2.869,211.0645458,8.163 +2,24-12-2010,3436007.68,0,49.97,2.886,211.0646599,8.163 +2,31-12-2010,1750434.55,1,47.3,2.943,211.064774,8.163 +2,07-01-2011,1758050.79,0,44.69,2.976,211.0648881,8.028 +2,14-01-2011,1744193.58,0,33.02,2.983,211.1176713,8.028 +2,21-01-2011,1751384.9,0,41.4,3.016,211.4864691,8.028 +2,28-01-2011,1695371.68,0,42.83,3.01,211.8552668,8.028 +2,04-02-2011,1929346.23,0,38.25,2.989,212.2240646,8.028 +2,11-02-2011,2168041.61,1,33.19,3.022,212.5928624,8.028 +2,18-02-2011,2080884.82,0,57.83,3.045,212.9033115,8.028 +2,25-02-2011,1833511.08,0,60.8,3.065,213.190421,8.028 +2,04-03-2011,1981607.78,0,57.77,3.288,213.4775305,8.028 +2,11-03-2011,1879107.31,0,52.7,3.459,213.7646401,8.028 +2,18-03-2011,1902557.66,0,62.32,3.488,214.0156238,8.028 +2,25-03-2011,1766162.05,0,69.42,3.473,214.2521573,8.028 +2,01-04-2011,1800171.36,0,55.43,3.524,214.4886908,7.931 +2,08-04-2011,1847552.61,0,67,3.622,214.7252242,7.931 +2,15-04-2011,1856467.84,0,69.48,3.743,214.9420631,7.931 +2,22-04-2011,1886339.6,0,69.39,3.807,215.1096657,7.931 +2,29-04-2011,1745545.28,0,69.21,3.81,215.2772683,7.931 +2,06-05-2011,1837743.6,0,61.48,3.906,215.4448709,7.931 +2,13-05-2011,1838513.07,0,74.61,3.899,215.6124735,7.931 +2,20-05-2011,1688281.86,0,67.14,3.907,215.3834778,7.931 +2,27-05-2011,1797732.56,0,76.42,3.786,215.1544822,7.931 +2,03-06-2011,1933756.21,0,83.07,3.699,214.9254865,7.931 +2,10-06-2011,1929153.16,0,83.4,3.648,214.6964908,7.931 +2,17-06-2011,1953771.99,0,86.53,3.637,214.6513538,7.931 +2,24-06-2011,1790925.8,0,85.17,3.594,214.7441108,7.931 +2,01-07-2011,1866243,0,85.69,3.524,214.8368678,7.852 +2,08-07-2011,1853161.99,0,87.7,3.48,214.9296249,7.852 +2,15-07-2011,1785187.29,0,89.83,3.575,215.0134426,7.852 +2,22-07-2011,1743816.41,0,89.34,3.651,215.0749122,7.852 +2,29-07-2011,1680693.06,0,90.07,3.682,215.1363819,7.852 +2,05-08-2011,1876704.26,0,93.34,3.684,215.1978515,7.852 +2,12-08-2011,1812768.26,0,91.58,3.638,215.2593211,7.852 +2,19-08-2011,1844094.59,0,89.86,3.554,215.3229307,7.852 +2,26-08-2011,1821139.91,0,90.45,3.523,215.386897,7.852 +2,02-09-2011,1809119.7,0,89.64,3.533,215.4508632,7.852 +2,09-09-2011,1748000.65,1,77.97,3.546,215.5148295,7.852 +2,16-09-2011,1691439.52,0,78.85,3.526,215.6944378,7.852 +2,23-09-2011,1669299.78,0,75.58,3.467,216.0282356,7.852 +2,30-09-2011,1650394.44,0,78.14,3.355,216.3620333,7.852 +2,07-10-2011,1837553.43,0,69.92,3.285,216.6958311,7.441 +2,14-10-2011,1743882.19,0,71.67,3.274,217.0048261,7.441 +2,21-10-2011,1834680.25,0,64.53,3.353,217.1650042,7.441 +2,28-10-2011,1769296.25,0,65.87,3.372,217.3251824,7.441 +2,04-11-2011,1959707.9,0,55.53,3.332,217.4853605,7.441 +2,11-11-2011,1920725.15,0,59.33,3.297,217.6455387,7.441 +2,18-11-2011,1902762.5,0,62.01,3.308,217.8670218,7.441 +2,25-11-2011,2614202.3,1,56.36,3.236,218.1130269,7.441 +2,02-12-2011,1954952,0,48.74,3.172,218.3590319,7.441 +2,09-12-2011,2290549.32,0,41.76,3.158,218.605037,7.441 +2,16-12-2011,2432736.52,0,50.13,3.159,218.8217928,7.441 +2,23-12-2011,3224369.8,0,46.66,3.112,218.9995495,7.441 +2,30-12-2011,1874226.52,1,44.57,3.129,219.1773063,7.441 +2,06-01-2012,1799520.14,0,46.75,3.157,219.355063,7.057 +2,13-01-2012,1744725.48,0,45.99,3.261,219.5328198,7.057 +2,20-01-2012,1711769.11,0,51.7,3.268,219.6258417,7.057 +2,27-01-2012,1660906.14,0,50.5,3.29,219.7188636,7.057 +2,03-02-2012,1935299.94,0,55.21,3.36,219.8118854,7.057 +2,10-02-2012,2103322.68,1,46.98,3.409,219.9049073,7.057 +2,17-02-2012,2196688.46,0,43.82,3.51,220.0651993,7.057 +2,24-02-2012,1861802.7,0,54.63,3.555,220.275944,7.057 +2,02-03-2012,1952555.66,0,58.79,3.63,220.4866886,7.057 +2,09-03-2012,1937628.26,0,57.11,3.669,220.6974332,7.057 +2,16-03-2012,1976082.13,0,63.68,3.734,220.8498468,7.057 +2,23-03-2012,1790439.16,0,64.01,3.787,220.9244858,7.057 +2,30-03-2012,1857480.84,0,66.83,3.845,220.9991248,7.057 +2,06-04-2012,2129035.91,0,68.43,3.891,221.0737638,6.891 +2,13-04-2012,1935869.1,0,68.08,3.891,221.1484028,6.891 +2,20-04-2012,1847344.45,0,65.69,3.877,221.2021074,6.891 +2,27-04-2012,1764133.09,0,67.2,3.814,221.255812,6.891 +2,04-05-2012,1923957.09,0,76.73,3.749,221.3095166,6.891 +2,11-05-2012,1917520.99,0,73.87,3.688,221.3632212,6.891 +2,18-05-2012,2000940.67,0,71.27,3.63,221.380331,6.891 +2,25-05-2012,1912791.09,0,78.19,3.561,221.3828029,6.891 +2,01-06-2012,1910092.37,0,78.38,3.501,221.3852748,6.891 +2,08-06-2012,2010216.49,0,78.69,3.452,221.3877467,6.891 +2,15-06-2012,1962924.3,0,80.56,3.393,221.4009901,6.891 +2,22-06-2012,1887733.21,0,81.04,3.346,221.4411622,6.891 +2,29-06-2012,1881046.12,0,86.32,3.286,221.4813343,6.891 +2,06-07-2012,2041507.4,0,84.2,3.227,221.5215064,6.565 +2,13-07-2012,1830075.13,0,80.17,3.256,221.5616784,6.565 +2,20-07-2012,1819666.46,0,83.23,3.311,221.5701123,6.565 +2,27-07-2012,1757923.88,0,86.37,3.407,221.5785461,6.565 +2,03-08-2012,1946104.64,0,90.22,3.417,221.5869799,6.565 +2,10-08-2012,1866719.96,0,88.55,3.494,221.5954138,6.565 +2,17-08-2012,1928016.01,0,84.79,3.571,221.6751459,6.565 +2,24-08-2012,1876788.15,0,76.91,3.62,221.8083518,6.565 +2,31-08-2012,1947083.3,0,82.64,3.638,221.9415576,6.565 +2,07-09-2012,1898777.07,1,87.65,3.73,222.0747635,6.565 +2,14-09-2012,1814806.63,0,75.88,3.717,222.2174395,6.565 +2,21-09-2012,1829415.67,0,71.09,3.721,222.4169362,6.565 +2,28-09-2012,1746470.56,0,79.45,3.666,222.6164329,6.565 +2,05-10-2012,1998321.04,0,70.27,3.617,222.8159296,6.17 +2,12-10-2012,1900745.13,0,60.97,3.601,223.0154263,6.17 +2,19-10-2012,1847990.41,0,68.08,3.594,223.0598077,6.17 +2,26-10-2012,1834458.35,0,69.79,3.506,223.0783366,6.17 +3,05-02-2010,461622.22,0,45.71,2.572,214.4248812,7.368 +3,12-02-2010,420728.96,1,47.93,2.548,214.5747916,7.368 +3,19-02-2010,421642.19,0,47.07,2.514,214.6198868,7.368 +3,26-02-2010,407204.86,0,52.05,2.561,214.6475127,7.368 +3,05-03-2010,415202.04,0,53.04,2.625,214.6751386,7.368 +3,12-03-2010,384200.69,0,63.08,2.667,214.7027646,7.368 +3,19-03-2010,375328.59,0,60.42,2.72,214.5301219,7.368 +3,26-03-2010,359949.27,0,57.06,2.732,214.3241011,7.368 +3,02-04-2010,423294.4,0,65.56,2.719,214.1180803,7.343 +3,09-04-2010,415870.28,0,68,2.77,213.9120595,7.343 +3,16-04-2010,354993.26,0,66.98,2.808,213.7726889,7.343 +3,23-04-2010,339976.65,0,67.87,2.795,213.7221852,7.343 +3,30-04-2010,361248.39,0,70.24,2.78,213.6716815,7.343 +3,07-05-2010,399323.86,0,73.47,2.835,213.6211778,7.343 +3,14-05-2010,384357.94,0,77.18,2.854,213.6196139,7.343 +3,21-05-2010,343763.17,0,75.81,2.826,213.9116886,7.343 +3,28-05-2010,350089.23,0,78.6,2.759,214.2037634,7.343 +3,04-06-2010,396968.8,0,78.53,2.705,214.4958382,7.343 +3,11-06-2010,355017.09,0,82.1,2.668,214.787913,7.343 +3,18-06-2010,364076.85,0,83.52,2.637,214.7858259,7.343 +3,25-06-2010,357346.48,0,83.79,2.653,214.6660741,7.343 +3,02-07-2010,381151.72,0,82.2,2.669,214.5463222,7.346 +3,09-07-2010,349214.18,0,81.75,2.642,214.4265704,7.346 +3,16-07-2010,352728.78,0,84.32,2.623,214.4176476,7.346 +3,23-07-2010,352864.49,0,83.32,2.608,214.5564968,7.346 +3,30-07-2010,347955.05,0,82.04,2.64,214.695346,7.346 +3,06-08-2010,402635.76,0,85.13,2.627,214.8341952,7.346 +3,13-08-2010,339597.38,0,86.74,2.692,214.9730444,7.346 +3,20-08-2010,351728.21,0,88.02,2.664,214.9314191,7.346 +3,27-08-2010,362134.09,0,86.15,2.619,214.8897938,7.346 +3,03-09-2010,366473.97,0,84.16,2.577,214.8481685,7.346 +3,10-09-2010,352260.97,1,80.84,2.565,214.8065431,7.346 +3,17-09-2010,363064.64,0,82.36,2.582,214.8322484,7.346 +3,24-09-2010,355626.87,0,76.9,2.624,214.9084516,7.346 +3,01-10-2010,358784.1,0,73.6,2.603,214.9846548,7.564 +3,08-10-2010,395107.35,0,66.99,2.633,215.060858,7.564 +3,15-10-2010,345584.39,0,69.71,2.72,215.1293114,7.564 +3,22-10-2010,348895.98,0,71.64,2.725,215.17839,7.564 +3,29-10-2010,348591.74,0,72.04,2.716,215.2274686,7.564 +3,05-11-2010,423175.56,0,62.94,2.689,215.2765472,7.564 +3,12-11-2010,386635.03,0,62.79,2.728,215.3256258,7.564 +3,19-11-2010,372545.32,0,57.72,2.771,215.2074519,7.564 +3,26-11-2010,565567.84,1,68.71,2.735,215.0614025,7.564 +3,03-12-2010,476420.77,0,53.76,2.708,214.9153531,7.564 +3,10-12-2010,467642.03,0,51.13,2.843,214.7693037,7.564 +3,17-12-2010,498159.39,0,52.2,2.869,214.704919,7.564 +3,24-12-2010,605990.41,0,57.16,2.886,214.7017828,7.564 +3,31-12-2010,382677.76,1,53.2,2.943,214.6986466,7.564 +3,07-01-2011,378241.34,0,53.35,2.976,214.6955104,7.551 +3,14-01-2011,381061.1,0,44.76,2.983,214.7470729,7.551 +3,21-01-2011,350876.7,0,50.74,3.016,215.1268275,7.551 +3,28-01-2011,364866.24,0,48.71,3.01,215.5065821,7.551 +3,04-02-2011,438516.53,0,45.95,2.989,215.8863367,7.551 +3,11-02-2011,430526.21,1,43.57,3.022,216.2660913,7.551 +3,18-02-2011,432782.1,0,61.58,3.045,216.5843571,7.551 +3,25-02-2011,397211.19,0,67.4,3.065,216.8780275,7.551 +3,04-03-2011,437084.51,0,65.11,3.288,217.1716979,7.551 +3,11-03-2011,404753.3,0,61.29,3.459,217.4653683,7.551 +3,18-03-2011,392109.51,0,69.47,3.488,217.7235226,7.551 +3,25-03-2011,380683.67,0,72.94,3.473,217.9674705,7.551 +3,01-04-2011,374556.08,0,68.76,3.524,218.2114184,7.574 +3,08-04-2011,384075.31,0,72.55,3.622,218.4553663,7.574 +3,15-04-2011,366250.69,0,75.88,3.743,218.6788642,7.574 +3,22-04-2011,391860.04,0,76.91,3.807,218.851237,7.574 +3,29-04-2011,367405.4,0,78.69,3.81,219.0236099,7.574 +3,06-05-2011,413042.12,0,69.45,3.906,219.1959827,7.574 +3,13-05-2011,386312.68,0,79.87,3.899,219.3683556,7.574 +3,20-05-2011,364603.13,0,75.79,3.907,219.127216,7.574 +3,27-05-2011,369350.6,0,84.41,3.786,218.8860765,7.574 +3,03-06-2011,394507.84,0,84.29,3.699,218.6449369,7.574 +3,10-06-2011,391638.75,0,84.84,3.648,218.4037974,7.574 +3,17-06-2011,403423.34,0,86.96,3.637,218.3551748,7.574 +3,24-06-2011,385520.71,0,84.94,3.594,218.45094,7.574 +3,01-07-2011,368962.72,0,85.1,3.524,218.5467052,7.567 +3,08-07-2011,395146.24,0,85.38,3.48,218.6424704,7.567 +3,15-07-2011,373454.33,0,87.14,3.575,218.7275216,7.567 +3,22-07-2011,360617.37,0,86.19,3.651,218.7857881,7.567 +3,29-07-2011,345381.29,0,88.07,3.682,218.8440545,7.567 +3,05-08-2011,409981.25,0,88.45,3.684,218.9023209,7.567 +3,12-08-2011,380376.85,0,88.88,3.638,218.9605873,7.567 +3,19-08-2011,379716.91,0,88.44,3.554,219.023271,7.567 +3,26-08-2011,366367.55,0,87.67,3.523,219.0866908,7.567 +3,02-09-2011,375988.69,0,89.12,3.533,219.1501106,7.567 +3,09-09-2011,377347.49,1,81.72,3.546,219.2135305,7.567 +3,16-09-2011,375629.51,0,83.63,3.526,219.3972867,7.567 +3,23-09-2011,365248.94,0,80.19,3.467,219.7414914,7.567 +3,30-09-2011,368477.93,0,82.58,3.355,220.085696,7.567 +3,07-10-2011,403342.4,0,75.54,3.285,220.4299007,7.197 +3,14-10-2011,368282.57,0,73.75,3.274,220.7486167,7.197 +3,21-10-2011,394976.36,0,69.03,3.353,220.9144005,7.197 +3,28-10-2011,389540.62,0,71.04,3.372,221.0801842,7.197 +3,04-11-2011,459443.22,0,59.31,3.332,221.245968,7.197 +3,11-11-2011,407764.25,0,61.7,3.297,221.4117517,7.197 +3,18-11-2011,398838.97,0,63.91,3.308,221.6432852,7.197 +3,25-11-2011,556925.19,1,68,3.236,221.9011185,7.197 +3,02-12-2011,472511.32,0,54.97,3.172,222.1589519,7.197 +3,09-12-2011,468772.8,0,49.26,3.158,222.4167852,7.197 +3,16-12-2011,510747.62,0,57.95,3.159,222.6426418,7.197 +3,23-12-2011,551221.21,0,53.41,3.112,222.8258628,7.197 +3,30-12-2011,410553.88,1,48.29,3.129,223.0090839,7.197 +3,06-01-2012,398178.21,0,52.42,3.157,223.1923049,6.833 +3,13-01-2012,367438.62,0,51.86,3.261,223.3755259,6.833 +3,20-01-2012,365818.61,0,56.2,3.268,223.4700552,6.833 +3,27-01-2012,349518.1,0,58.06,3.29,223.5645845,6.833 +3,03-02-2012,424960.66,0,59.33,3.36,223.6591137,6.833 +3,10-02-2012,473292.47,1,51.65,3.409,223.753643,6.833 +3,17-02-2012,475591.08,0,52.39,3.51,223.9170153,6.833 +3,24-02-2012,418925.47,0,60.12,3.555,224.1320199,6.833 +3,02-03-2012,469752.56,0,61.65,3.63,224.3470245,6.833 +3,09-03-2012,445162.05,0,60.71,3.669,224.5620291,6.833 +3,16-03-2012,411775.8,0,64,3.734,224.7166953,6.833 +3,23-03-2012,413907.25,0,66.53,3.787,224.7909104,6.833 +3,30-03-2012,407488.84,0,69.36,3.845,224.8651254,6.833 +3,06-04-2012,503232.13,0,73.01,3.891,224.9393405,6.664 +3,13-04-2012,420789.74,0,72.83,3.891,225.0135556,6.664 +3,20-04-2012,434822.13,0,72.05,3.877,225.0689541,6.664 +3,27-04-2012,394616.11,0,73.39,3.814,225.1243526,6.664 +3,04-05-2012,439913.57,0,79.51,3.749,225.1797511,6.664 +3,11-05-2012,431985.36,0,75.19,3.688,225.2351496,6.664 +3,18-05-2012,418112.76,0,72.38,3.63,225.2512024,6.664 +3,25-05-2012,413701.29,0,78.58,3.561,225.2515168,6.664 +3,01-06-2012,432268.53,0,81.55,3.501,225.2518313,6.664 +3,08-06-2012,446336.8,0,81.65,3.452,225.2521458,6.664 +3,15-06-2012,442074.79,0,84.66,3.393,225.2644795,6.664 +3,22-06-2012,419497.95,0,82.7,3.346,225.3068615,6.664 +3,29-06-2012,422965.33,0,86.42,3.286,225.3492435,6.664 +3,06-07-2012,411206.5,0,83.14,3.227,225.3916254,6.334 +3,13-07-2012,416913.1,0,82.28,3.256,225.4340074,6.334 +3,20-07-2012,432424.85,0,81.38,3.311,225.4438827,6.334 +3,27-07-2012,389427.9,0,84.94,3.407,225.4537579,6.334 +3,03-08-2012,419990.29,0,86.55,3.417,225.4636332,6.334 +3,10-08-2012,391811.6,0,85.85,3.494,225.4735085,6.334 +3,17-08-2012,394918.83,0,87.36,3.571,225.5558664,6.334 +3,24-08-2012,412449.67,0,83.01,3.62,225.6925864,6.334 +3,31-08-2012,408838.73,0,85.18,3.638,225.8293063,6.334 +3,07-09-2012,408229.73,1,84.99,3.73,225.9660263,6.334 +3,14-09-2012,407589.16,0,78.36,3.717,226.1122067,6.334 +3,21-09-2012,414392.09,0,72.78,3.721,226.3151496,6.334 +3,28-09-2012,389813.02,0,77.46,3.666,226.5180926,6.334 +3,05-10-2012,443557.65,0,72.74,3.617,226.7210356,6.034 +3,12-10-2012,410804.39,0,70.31,3.601,226.9239785,6.034 +3,19-10-2012,424513.08,0,73.44,3.594,226.9688442,6.034 +3,26-10-2012,405432.7,0,74.66,3.506,226.9873637,6.034 +4,05-02-2010,2135143.87,0,43.76,2.598,126.4420645,8.623 +4,12-02-2010,2188307.39,1,28.84,2.573,126.4962581,8.623 +4,19-02-2010,2049860.26,0,36.45,2.54,126.5262857,8.623 +4,26-02-2010,1925728.84,0,41.36,2.59,126.5522857,8.623 +4,05-03-2010,1971057.44,0,43.49,2.654,126.5782857,8.623 +4,12-03-2010,1894324.09,0,49.63,2.704,126.6042857,8.623 +4,19-03-2010,1897429.36,0,55.19,2.743,126.6066452,8.623 +4,26-03-2010,1762539.3,0,39.91,2.752,126.6050645,8.623 +4,02-04-2010,1979247.12,0,48.77,2.74,126.6034839,7.896 +4,09-04-2010,1818452.72,0,54.16,2.773,126.6019032,7.896 +4,16-04-2010,1851519.69,0,56.23,2.81,126.5621,7.896 +4,23-04-2010,1802677.9,0,56.87,2.805,126.4713333,7.896 +4,30-04-2010,1817273.28,0,53.04,2.787,126.3805667,7.896 +4,07-05-2010,2000626.14,0,56.77,2.836,126.2898,7.896 +4,14-05-2010,1875597.28,0,62.35,2.845,126.2085484,7.896 +4,21-05-2010,1903752.6,0,67.4,2.82,126.1843871,7.896 +4,28-05-2010,1857533.7,0,67.73,2.756,126.1602258,7.896 +4,04-06-2010,1903290.58,0,70.83,2.701,126.1360645,7.896 +4,11-06-2010,1870619.23,0,78.45,2.668,126.1119032,7.896 +4,18-06-2010,1929736.35,0,81.53,2.635,126.114,7.896 +4,25-06-2010,1846651.95,0,81.1,2.654,126.1266,7.896 +4,02-07-2010,1881337.21,0,73.66,2.668,126.1392,7.372 +4,09-07-2010,1812208.22,0,80.35,2.637,126.1518,7.372 +4,16-07-2010,1898427.66,0,78.53,2.621,126.1498065,7.372 +4,23-07-2010,1848426.78,0,79.78,2.612,126.1283548,7.372 +4,30-07-2010,1796637.61,0,80.7,2.65,126.1069032,7.372 +4,06-08-2010,1907638.58,0,76.53,2.64,126.0854516,7.372 +4,13-08-2010,2007050.75,0,78.08,2.698,126.064,7.372 +4,20-08-2010,1997181.09,0,78.83,2.671,126.0766452,7.372 +4,27-08-2010,1848403.92,0,74.44,2.621,126.0892903,7.372 +4,03-09-2010,1935857.58,0,76.8,2.584,126.1019355,7.372 +4,10-09-2010,1865820.81,1,73.54,2.574,126.1145806,7.372 +4,17-09-2010,1899959.61,0,64.91,2.594,126.1454667,7.372 +4,24-09-2010,1810684.68,0,60.96,2.642,126.1900333,7.372 +4,01-10-2010,1842821.02,0,63.96,2.619,126.2346,7.127 +4,08-10-2010,1951494.85,0,67.73,2.645,126.2791667,7.127 +4,15-10-2010,1867345.09,0,62.03,2.732,126.3266774,7.127 +4,22-10-2010,1927610.06,0,64.17,2.736,126.3815484,7.127 +4,29-10-2010,1933333,0,56.94,2.718,126.4364194,7.127 +4,05-11-2010,2013115.79,0,51.6,2.699,126.4912903,7.127 +4,12-11-2010,1999794.26,0,52.65,2.741,126.5461613,7.127 +4,19-11-2010,2097809.4,0,48.05,2.78,126.6072,7.127 +4,26-11-2010,2789469.45,1,48.08,2.752,126.6692667,7.127 +4,03-12-2010,2102530.17,0,46.4,2.727,126.7313333,7.127 +4,10-12-2010,2302504.86,0,42.4,2.86,126.7934,7.127 +4,17-12-2010,2740057.14,0,46.57,2.884,126.8794839,7.127 +4,24-12-2010,3526713.39,0,43.21,2.887,126.9835806,7.127 +4,31-12-2010,1794868.74,1,38.09,2.955,127.0876774,7.127 +4,07-01-2011,1862476.27,0,39.34,2.98,127.1917742,6.51 +4,14-01-2011,1865502.46,0,31.6,2.992,127.3009355,6.51 +4,21-01-2011,1886393.94,0,38.34,3.017,127.4404839,6.51 +4,28-01-2011,1814240.85,0,40.6,3.022,127.5800323,6.51 +4,04-02-2011,2119086.04,0,34.61,2.996,127.7195806,6.51 +4,11-02-2011,2187847.29,1,33.29,3.033,127.859129,6.51 +4,18-02-2011,2316495.56,0,48.17,3.058,127.99525,6.51 +4,25-02-2011,2078094.69,0,49,3.087,128.13,6.51 +4,04-03-2011,2103455.75,0,46.56,3.305,128.26475,6.51 +4,11-03-2011,2039818.41,0,50.93,3.461,128.3995,6.51 +4,18-03-2011,2116475.38,0,51.86,3.495,128.5121935,6.51 +4,25-03-2011,1944164.32,0,59.1,3.48,128.6160645,6.51 +4,01-04-2011,1900246.47,0,56.99,3.521,128.7199355,5.946 +4,08-04-2011,2074953.46,0,62.61,3.605,128.8238065,5.946 +4,15-04-2011,1960587.76,0,62.34,3.724,128.9107333,5.946 +4,22-04-2011,2220600.76,0,68.8,3.781,128.9553,5.946 +4,29-04-2011,1878167.44,0,64.22,3.781,128.9998667,5.946 +4,06-05-2011,2063682.76,0,63.41,3.866,129.0444333,5.946 +4,13-05-2011,2002362.37,0,70.65,3.872,129.089,5.946 +4,20-05-2011,2015563.48,0,70.49,3.881,129.0756774,5.946 +4,27-05-2011,1986597.95,0,73.65,3.771,129.0623548,5.946 +4,03-06-2011,2065377.15,0,78.26,3.683,129.0490323,5.946 +4,10-06-2011,2073951.38,0,80.05,3.64,129.0357097,5.946 +4,17-06-2011,2141210.62,0,83.51,3.618,129.0432,5.946 +4,24-06-2011,2008344.92,0,81.85,3.57,129.0663,5.946 +4,01-07-2011,2051533.53,0,84.54,3.504,129.0894,5.644 +4,08-07-2011,2066541.86,0,84.59,3.469,129.1125,5.644 +4,15-07-2011,2049046.95,0,83.27,3.563,129.1338387,5.644 +4,22-07-2011,2036231.39,0,82.84,3.627,129.1507742,5.644 +4,29-07-2011,1989674.07,0,84.36,3.659,129.1677097,5.644 +4,05-08-2011,2160057.39,0,86.09,3.662,129.1846452,5.644 +4,12-08-2011,2105668.74,0,82.98,3.617,129.2015806,5.644 +4,19-08-2011,2232892.1,0,82.77,3.55,129.2405806,5.644 +4,26-08-2011,1988490.21,0,81.47,3.523,129.2832581,5.644 +4,02-09-2011,2078420.31,0,77.99,3.533,129.3259355,5.644 +4,09-09-2011,2093139.01,1,73.34,3.554,129.3686129,5.644 +4,16-09-2011,2075577.33,0,72.76,3.532,129.4306,5.644 +4,23-09-2011,2031406.41,0,69.23,3.473,129.5183333,5.644 +4,30-09-2011,1929486.63,0,72.15,3.371,129.6060667,5.644 +4,07-10-2011,2166737.65,0,65.79,3.299,129.6938,5.143 +4,14-10-2011,2074548.85,0,63.75,3.283,129.7706452,5.143 +4,21-10-2011,2207742.13,0,64.79,3.361,129.7821613,5.143 +4,28-10-2011,2151659.59,0,55.31,3.362,129.7936774,5.143 +4,04-11-2011,2281217.31,0,49.86,3.322,129.8051935,5.143 +4,11-11-2011,2203028.96,0,47.12,3.286,129.8167097,5.143 +4,18-11-2011,2243946.59,0,50.44,3.294,129.8268333,5.143 +4,25-11-2011,3004702.33,1,47.96,3.225,129.8364,5.143 +4,02-12-2011,2180999.26,0,38.71,3.176,129.8459667,5.143 +4,09-12-2011,2508955.24,0,31.64,3.153,129.8555333,5.143 +4,16-12-2011,2771397.17,0,36.44,3.149,129.8980645,5.143 +4,23-12-2011,3676388.98,0,35.92,3.103,129.9845484,5.143 +4,30-12-2011,2007105.86,1,36.89,3.119,130.0710323,5.143 +4,06-01-2012,2047766.07,0,38.64,3.158,130.1575161,4.607 +4,13-01-2012,1941676.61,0,34.41,3.263,130.244,4.607 +4,20-01-2012,2005097.76,0,42.09,3.273,130.2792258,4.607 +4,27-01-2012,1928720.51,0,40.31,3.29,130.3144516,4.607 +4,03-02-2012,2173373.91,0,41.81,3.354,130.3496774,4.607 +4,10-02-2012,2374660.64,1,33,3.411,130.3849032,4.607 +4,17-02-2012,2427640.17,0,34.19,3.493,130.4546207,4.607 +4,24-02-2012,2226662.17,0,41.31,3.541,130.5502069,4.607 +4,02-03-2012,2206319.9,0,50.38,3.619,130.6457931,4.607 +4,09-03-2012,2202450.81,0,53.63,3.667,130.7413793,4.607 +4,16-03-2012,2214967.44,0,59.81,3.707,130.8261935,4.607 +4,23-03-2012,2091592.54,0,59.07,3.759,130.8966452,4.607 +4,30-03-2012,2089381.77,0,72.63,3.82,130.9670968,4.607 +4,06-04-2012,2470206.13,0,67.69,3.864,131.0375484,4.308 +4,13-04-2012,2105301.39,0,68.69,3.881,131.108,4.308 +4,20-04-2012,2144336.89,0,68.6,3.864,131.1173333,4.308 +4,27-04-2012,2064065.66,0,76.47,3.81,131.1266667,4.308 +4,04-05-2012,2196968.33,0,80.14,3.747,131.136,4.308 +4,11-05-2012,2127661.17,0,67.64,3.685,131.1453333,4.308 +4,18-05-2012,2207214.81,0,68.43,3.62,131.0983226,4.308 +4,25-05-2012,2154137.67,0,77.47,3.551,131.0287742,4.308 +4,01-06-2012,2179360.94,0,77.41,3.483,130.9592258,4.308 +4,08-06-2012,2245257.18,0,78.11,3.433,130.8896774,4.308 +4,15-06-2012,2234190.93,0,80.94,3.372,130.8295333,4.308 +4,22-06-2012,2197299.65,0,81.63,3.329,130.7929,4.308 +4,29-06-2012,2128362.92,0,84.23,3.257,130.7562667,4.308 +4,06-07-2012,2224499.28,0,80.37,3.187,130.7196333,4.077 +4,13-07-2012,2100252.61,0,76.86,3.224,130.683,4.077 +4,20-07-2012,2175563.69,0,79.14,3.263,130.7012903,4.077 +4,27-07-2012,2048613.65,0,81.06,3.356,130.7195806,4.077 +4,03-08-2012,2174514.13,0,83.86,3.374,130.737871,4.077 +4,10-08-2012,2193367.69,0,83.21,3.476,130.7561613,4.077 +4,17-08-2012,2283540.3,0,81.41,3.552,130.7909677,4.077 +4,24-08-2012,2125241.68,0,75.76,3.61,130.8381613,4.077 +4,31-08-2012,2081181.35,0,76.47,3.646,130.8853548,4.077 +4,07-09-2012,2125104.72,1,82.09,3.709,130.9325484,4.077 +4,14-09-2012,2117854.6,0,68.2,3.706,130.9776667,4.077 +4,21-09-2012,2119438.53,0,68.97,3.721,131.0103333,4.077 +4,28-09-2012,2027620.23,0,71.74,3.666,131.043,4.077 +4,05-10-2012,2209835.43,0,63.07,3.62,131.0756667,3.879 +4,12-10-2012,2133026.07,0,57.11,3.603,131.1083333,3.879 +4,19-10-2012,2097266.85,0,64.46,3.61,131.1499677,3.879 +4,26-10-2012,2149594.46,0,63.64,3.514,131.1930968,3.879 +5,05-02-2010,317173.1,0,39.7,2.572,211.6539716,6.566 +5,12-02-2010,311825.7,1,39.81,2.548,211.8004698,6.566 +5,19-02-2010,303447.57,0,41.14,2.514,211.8471283,6.566 +5,26-02-2010,270281.63,0,46.7,2.561,211.8771468,6.566 +5,05-03-2010,288855.71,0,48.89,2.625,211.9071653,6.566 +5,12-03-2010,297293.59,0,58.5,2.667,211.9371839,6.566 +5,19-03-2010,281706.41,0,55.46,2.72,211.770897,6.566 +5,26-03-2010,273282.97,0,52.47,2.732,211.5718925,6.566 +5,02-04-2010,331406,0,63.18,2.719,211.372888,6.465 +5,09-04-2010,328020.49,0,65.19,2.77,211.1738835,6.465 +5,16-04-2010,306858.69,0,65.3,2.808,211.0388528,6.465 +5,23-04-2010,288839.73,0,65.13,2.795,210.9891204,6.465 +5,30-04-2010,298697.84,0,67.53,2.78,210.939388,6.465 +5,07-05-2010,333522.6,0,71.53,2.835,210.8896556,6.465 +5,14-05-2010,296673.77,0,74.79,2.854,210.8872772,6.465 +5,21-05-2010,301615.49,0,75.2,2.826,211.169023,6.465 +5,28-05-2010,310013.11,0,79.81,2.759,211.4507688,6.465 +5,04-06-2010,337825.89,0,79.54,2.705,211.7325146,6.465 +5,11-06-2010,296641.91,0,80.7,2.668,212.0142605,6.465 +5,18-06-2010,313795.6,0,83.91,2.637,212.0119769,6.465 +5,25-06-2010,295257.3,0,83.72,2.653,211.8960815,6.465 +5,02-07-2010,305993.27,0,81.25,2.669,211.7801861,6.496 +5,09-07-2010,291808.87,0,81.14,2.642,211.6642907,6.496 +5,16-07-2010,280701.7,0,83.98,2.623,211.6561123,6.496 +5,23-07-2010,274742.63,0,83.66,2.608,211.7915565,6.496 +5,30-07-2010,268929.03,0,82.46,2.64,211.9270006,6.496 +5,06-08-2010,303043.02,0,86.1,2.627,212.0624447,6.496 +5,13-08-2010,286477.35,0,87.41,2.692,212.1978889,6.496 +5,20-08-2010,287205.38,0,87.71,2.664,212.1608984,6.496 +5,27-08-2010,288519.75,0,87.05,2.619,212.123908,6.496 +5,03-09-2010,323798,0,84.06,2.577,212.0869176,6.496 +5,10-09-2010,306533.08,1,79.86,2.565,212.0499271,6.496 +5,17-09-2010,282558.65,0,82.28,2.582,212.0769346,6.496 +5,24-09-2010,293131.58,0,78.53,2.624,212.1519404,6.496 +5,01-10-2010,283178.12,0,71.1,2.603,212.2269463,6.768 +5,08-10-2010,290494.85,0,64.99,2.633,212.3019522,6.768 +5,15-10-2010,280681.2,0,68.11,2.72,212.3691867,6.768 +5,22-10-2010,284988.27,0,70.96,2.725,212.4169928,6.768 +5,29-10-2010,278031.81,0,70.58,2.716,212.464799,6.768 +5,05-11-2010,325310.3,0,58.88,2.689,212.5126051,6.768 +5,12-11-2010,301827.36,0,62.37,2.728,212.5604113,6.768 +5,19-11-2010,297384.81,0,52.52,2.771,212.445487,6.768 +5,26-11-2010,488362.61,1,66.15,2.735,212.303441,6.768 +5,03-12-2010,344490.88,0,51.31,2.708,212.1613951,6.768 +5,10-12-2010,352811.53,0,48.27,2.843,212.0193491,6.768 +5,17-12-2010,367801.19,0,51.61,2.869,211.9580815,6.768 +5,24-12-2010,466010.25,0,55.01,2.886,211.9573978,6.768 +5,31-12-2010,298180.18,1,49.79,2.943,211.9567142,6.768 +5,07-01-2011,286347.26,0,48.3,2.976,211.9560305,6.634 +5,14-01-2011,260636.71,0,37.74,2.983,212.008514,6.634 +5,21-01-2011,275313.34,0,45.41,3.016,212.3800012,6.634 +5,28-01-2011,279088.39,0,44.5,3.01,212.7514884,6.634 +5,04-02-2011,329613.2,0,41.67,2.989,213.1229755,6.634 +5,11-02-2011,311590.54,1,38.25,3.022,213.4944627,6.634 +5,18-02-2011,356622.61,0,58.83,3.045,213.8068304,6.634 +5,25-02-2011,294659.5,0,63.35,3.065,214.0955503,6.634 +5,04-03-2011,329033.66,0,60.35,3.288,214.3842702,6.634 +5,11-03-2011,293098.1,0,55.74,3.459,214.6729901,6.634 +5,18-03-2011,312177.67,0,64.31,3.488,214.9257339,6.634 +5,25-03-2011,294732.5,0,70.71,3.473,215.1640872,6.634 +5,01-04-2011,314316.55,0,61.5,3.524,215.4024406,6.489 +5,08-04-2011,307333.62,0,69.64,3.622,215.6407939,6.489 +5,15-04-2011,307913.58,0,72.02,3.743,215.8592673,6.489 +5,22-04-2011,328415.44,0,74.34,3.807,216.0280407,6.489 +5,29-04-2011,307291.56,0,74.75,3.81,216.1968142,6.489 +5,06-05-2011,322904.68,0,66.27,3.906,216.3655877,6.489 +5,13-05-2011,290930.01,0,77.38,3.899,216.5343611,6.489 +5,20-05-2011,299614.33,0,71.37,3.907,216.3023847,6.489 +5,27-05-2011,297149.69,0,80.14,3.786,216.0704083,6.489 +5,03-06-2011,329183.92,0,83.81,3.699,215.8384319,6.489 +5,10-06-2011,304984.14,0,83.61,3.648,215.6064555,6.489 +5,17-06-2011,304811.82,0,86.84,3.637,215.560463,6.489 +5,24-06-2011,302881.64,0,84.76,3.594,215.6539583,6.489 +5,01-07-2011,327093.89,0,85.81,3.524,215.7474537,6.529 +5,08-07-2011,310804.93,0,86.64,3.48,215.8409491,6.529 +5,15-07-2011,283248.62,0,88.64,3.575,215.9250696,6.529 +5,22-07-2011,292539.73,0,86.97,3.651,215.985753,6.529 +5,29-07-2011,275142.17,0,89.42,3.682,216.0464364,6.529 +5,05-08-2011,317738.56,0,91.07,3.684,216.1071198,6.529 +5,12-08-2011,289886.16,0,90.16,3.638,216.1678032,6.529 +5,19-08-2011,303643.84,0,89.35,3.554,216.2311855,6.529 +5,26-08-2011,310338.17,0,89.18,3.523,216.2950176,6.529 +5,02-09-2011,315645.53,0,90.38,3.533,216.3588498,6.529 +5,09-09-2011,321110.22,1,79.04,3.546,216.4226819,6.529 +5,16-09-2011,278529.71,0,83.55,3.526,216.6033083,6.529 +5,23-09-2011,291024.98,0,78.01,3.467,216.9396605,6.529 +5,30-09-2011,292315.38,0,81.16,3.355,217.2760127,6.529 +5,07-10-2011,309111.47,0,71.64,3.285,217.6123648,6.3 +5,14-10-2011,286117.72,0,72.36,3.274,217.9237458,6.3 +5,21-10-2011,306069.18,0,66.9,3.353,218.0852999,6.3 +5,28-10-2011,307035.11,0,69.27,3.372,218.2468539,6.3 +5,04-11-2011,353652.23,0,56.71,3.332,218.408408,6.3 +5,11-11-2011,311906.7,0,60.71,3.297,218.5699621,6.3 +5,18-11-2011,307944.37,0,64.33,3.308,218.793912,6.3 +5,25-11-2011,507900.07,1,61.93,3.236,219.0428204,6.3 +5,02-12-2011,376225.61,0,51.14,3.172,219.2917287,6.3 +5,09-12-2011,367433.77,0,44.12,3.158,219.540637,6.3 +5,16-12-2011,379530.3,0,54.42,3.159,219.7596266,6.3 +5,23-12-2011,458562.24,0,50.33,3.112,219.9387246,6.3 +5,30-12-2011,349624.88,1,45.62,3.129,220.1178226,6.3 +5,06-01-2012,312078.71,0,50.21,3.157,220.2969205,5.943 +5,13-01-2012,291454.52,0,48.86,3.261,220.4760185,5.943 +5,20-01-2012,287523.98,0,54.65,3.268,220.5694104,5.943 +5,27-01-2012,295974.22,0,54.63,3.29,220.6628023,5.943 +5,03-02-2012,333948,0,57.35,3.36,220.7561941,5.943 +5,10-02-2012,349239.88,1,48.57,3.409,220.849586,5.943 +5,17-02-2012,356427.98,0,48.25,3.51,221.0106341,5.943 +5,24-02-2012,312220.47,0,57.75,3.555,221.2224243,5.943 +5,02-03-2012,359206.21,0,60.66,3.63,221.4342146,5.943 +5,09-03-2012,347295.6,0,57.69,3.669,221.6460048,5.943 +5,16-03-2012,339392.54,0,63.55,3.734,221.7989713,5.943 +5,23-03-2012,321299.99,0,64.44,3.787,221.8735063,5.943 +5,30-03-2012,331318.73,0,67.76,3.845,221.9480412,5.943 +5,06-04-2012,402985.7,0,70.4,3.891,222.0225762,5.801 +5,13-04-2012,351832.03,0,70.56,3.891,222.0971111,5.801 +5,20-04-2012,330063.06,0,67.33,3.877,222.1512315,5.801 +5,27-04-2012,324839.74,0,68.96,3.814,222.2053519,5.801 +5,04-05-2012,360932.69,0,77.1,3.749,222.2594722,5.801 +5,11-05-2012,333870.52,0,73.45,3.688,222.3135926,5.801 +5,18-05-2012,336189.66,0,70.45,3.63,222.330443,5.801 +5,25-05-2012,341994.48,0,78.23,3.561,222.3323853,5.801 +5,01-06-2012,359867.8,0,79.72,3.501,222.3343277,5.801 +5,08-06-2012,341704.59,0,81.02,3.452,222.33627,5.801 +5,15-06-2012,327383.64,0,81.64,3.393,222.3492901,5.801 +5,22-06-2012,325041.68,0,80.57,3.346,222.3900046,5.801 +5,29-06-2012,329658.1,0,87.08,3.286,222.4307191,5.801 +5,06-07-2012,341214.43,0,82.35,3.227,222.4714336,5.603 +5,13-07-2012,316203.64,0,80.78,3.256,222.5121481,5.603 +5,20-07-2012,321205.12,0,81.05,3.311,222.5209358,5.603 +5,27-07-2012,306827.36,0,85.06,3.407,222.5297234,5.603 +5,03-08-2012,324195.17,0,86.91,3.417,222.5385111,5.603 +5,10-08-2012,306759.7,0,86.96,3.494,222.5472987,5.603 +5,17-08-2012,314014.18,0,87.52,3.571,222.6276753,5.603 +5,24-08-2012,320831.36,0,79.45,3.62,222.7617437,5.603 +5,31-08-2012,344642.01,0,84.25,3.638,222.8958121,5.603 +5,07-09-2012,350648.91,1,86.3,3.73,223.0298805,5.603 +5,14-09-2012,299800.67,0,76.65,3.717,223.1734167,5.603 +5,21-09-2012,307306.76,0,71.09,3.721,223.3737593,5.603 +5,28-09-2012,310141.68,0,78.33,3.666,223.5741019,5.603 +5,05-10-2012,343048.29,0,71.17,3.617,223.7744444,5.422 +5,12-10-2012,325345.41,0,66.24,3.601,223.974787,5.422 +5,19-10-2012,313358.15,0,69.17,3.594,224.0192873,5.422 +5,26-10-2012,319550.77,0,71.7,3.506,224.0378139,5.422 +6,05-02-2010,1652635.1,0,40.43,2.572,212.6223518,7.259 +6,12-02-2010,1606283.86,1,40.57,2.548,212.7700425,7.259 +6,19-02-2010,1567138.07,0,43.58,2.514,212.8161546,7.259 +6,26-02-2010,1432953.21,0,47.1,2.561,212.845337,7.259 +6,05-03-2010,1601348.82,0,49.63,2.625,212.8745193,7.259 +6,12-03-2010,1558621.36,0,58.82,2.667,212.9037017,7.259 +6,19-03-2010,1693058.91,0,56.55,2.72,212.7351935,7.259 +6,26-03-2010,1472033.38,0,53.74,2.732,212.533737,7.259 +6,02-04-2010,1770333.9,0,64.94,2.719,212.3322805,7.092 +6,09-04-2010,1667181.82,0,66.15,2.77,212.1308239,7.092 +6,16-04-2010,1519846.36,0,65.68,2.808,211.9942765,7.092 +6,23-04-2010,1540435.99,0,64.11,2.795,211.9442745,7.092 +6,30-04-2010,1498080.16,0,68.91,2.78,211.8942725,7.092 +6,07-05-2010,1619920.04,0,73.68,2.835,211.8442706,7.092 +6,14-05-2010,1524059.4,0,74.95,2.854,211.8421769,7.092 +6,21-05-2010,1531938.44,0,74.8,2.826,212.1275324,7.092 +6,28-05-2010,1644470.66,0,78.89,2.759,212.412888,7.092 +6,04-06-2010,1857380.09,0,79.44,2.705,212.6982436,7.092 +6,11-06-2010,1685652.35,0,81.81,2.668,212.9835992,7.092 +6,18-06-2010,1677248.24,0,83.89,2.637,212.9813843,7.092 +6,25-06-2010,1640681.88,0,84.2,2.653,212.8641412,7.092 +6,02-07-2010,1759777.25,0,80.34,2.669,212.746898,6.973 +6,09-07-2010,1690317.99,0,80.93,2.642,212.6296549,6.973 +6,16-07-2010,1560120.8,0,83.75,2.623,212.6212163,6.973 +6,23-07-2010,1585240.92,0,83.9,2.608,212.7578505,6.973 +6,30-07-2010,1532308.78,0,81.37,2.64,212.8944846,6.973 +6,06-08-2010,1633241.59,0,86.61,2.627,213.0311188,6.973 +6,13-08-2010,1547654.98,0,86.83,2.692,213.1677529,6.973 +6,20-08-2010,1539930.5,0,87.36,2.664,213.1291427,6.973 +6,27-08-2010,1450766.12,0,85.71,2.619,213.0905324,6.973 +6,03-09-2010,1510925.32,0,82.15,2.577,213.0519222,6.973 +6,10-09-2010,1424225.44,1,78.78,2.565,213.013312,6.973 +6,17-09-2010,1308537.75,0,81.78,2.582,213.0398643,6.973 +6,24-09-2010,1275591.84,0,76.49,2.624,213.1152886,6.973 +6,01-10-2010,1328468.89,0,70.69,2.603,213.1907129,7.007 +6,08-10-2010,1360317.9,0,65.21,2.633,213.2661373,7.007 +6,15-10-2010,1344580.92,0,68.93,2.72,213.3337977,7.007 +6,22-10-2010,1332716.53,0,70.97,2.725,213.3820486,7.007 +6,29-10-2010,1385323.7,0,70.39,2.716,213.4302994,7.007 +6,05-11-2010,1505442.15,0,59.9,2.689,213.4785503,7.007 +6,12-11-2010,1495536.46,0,62.11,2.728,213.5268011,7.007 +6,19-11-2010,1518841.45,0,52.99,2.771,213.4107412,7.007 +6,26-11-2010,2267452.4,1,65.79,2.735,213.2672961,7.007 +6,03-12-2010,1677067.24,0,52.3,2.708,213.123851,7.007 +6,10-12-2010,1834737.58,0,48.46,2.843,212.9804059,7.007 +6,17-12-2010,2090268.95,0,52.24,2.869,212.918049,7.007 +6,24-12-2010,2727575.18,0,55.07,2.886,212.9165082,7.007 +6,31-12-2010,1464050.02,1,49.14,2.943,212.9149674,7.007 +6,07-01-2011,1350441.68,0,47.78,2.976,212.9134266,6.858 +6,14-01-2011,1306194.55,0,38.37,2.983,212.9655882,6.858 +6,21-01-2011,1261253.18,0,46.2,3.016,213.3399647,6.858 +6,28-01-2011,1287034.7,0,44.98,3.01,213.7143412,6.858 +6,04-02-2011,1514999.17,0,40.59,2.989,214.0887176,6.858 +6,11-02-2011,1486920.17,1,39.38,3.022,214.4630941,6.858 +6,18-02-2011,1572117.54,0,59.61,3.045,214.7775231,6.858 +6,25-02-2011,1422600.43,0,62.86,3.065,215.0679731,6.858 +6,04-03-2011,1502617.99,0,60.45,3.288,215.3584231,6.858 +6,11-03-2011,1494497.39,0,57.71,3.459,215.6488731,6.858 +6,18-03-2011,1685375.47,0,65.07,3.488,215.9035078,6.858 +6,25-03-2011,1438465.81,0,70.83,3.473,216.1438163,6.858 +6,01-04-2011,1459276.77,0,62.25,3.524,216.3841249,6.855 +6,08-04-2011,1534594,0,70.35,3.622,216.6244334,6.855 +6,15-04-2011,1448797.02,0,73.17,3.743,216.8446627,6.855 +6,22-04-2011,1639358.93,0,74.24,3.807,217.0146941,6.855 +6,29-04-2011,1479249.9,0,75.27,3.81,217.1847255,6.855 +6,06-05-2011,1504651.57,0,65.42,3.906,217.3547569,6.855 +6,13-05-2011,1453185.65,0,76.95,3.899,217.5247882,6.855 +6,20-05-2011,1382783.83,0,72.01,3.907,217.2896095,6.855 +6,27-05-2011,1523979.11,0,80.83,3.786,217.0544307,6.855 +6,03-06-2011,1705506.29,0,84.01,3.699,216.819252,6.855 +6,10-06-2011,1598643.65,0,84.49,3.648,216.5840732,6.855 +6,17-06-2011,1622150.33,0,87.08,3.637,216.5371616,6.855 +6,24-06-2011,1543365.9,0,85.51,3.594,216.6314502,6.855 +6,01-07-2011,1694551.15,0,87,3.524,216.7257388,6.925 +6,08-07-2011,1709373.62,0,88.36,3.48,216.8200275,6.925 +6,15-07-2011,1526801.24,0,88.93,3.575,216.9044732,6.925 +6,22-07-2011,1526506.08,0,88.06,3.651,216.964312,6.925 +6,29-07-2011,1483991.05,0,90.22,3.682,217.0241507,6.925 +6,05-08-2011,1601584.57,0,91.46,3.684,217.0839894,6.925 +6,12-08-2011,1484995.38,0,90.49,3.638,217.1438281,6.925 +6,19-08-2011,1493544.04,0,89.26,3.554,217.2069662,6.925 +6,26-08-2011,1420405.41,0,90.07,3.523,217.2706543,6.925 +6,02-09-2011,1481618.74,0,91.22,3.533,217.3343423,6.925 +6,09-09-2011,1483574.38,1,80.21,3.546,217.3980304,6.925 +6,16-09-2011,1351407.79,0,84.94,3.526,217.5797506,6.925 +6,23-09-2011,1336044.75,0,78.49,3.467,217.9188471,6.925 +6,30-09-2011,1307551.92,0,82.51,3.355,218.2579435,6.925 +6,07-10-2011,1481739.2,0,74.1,3.285,218.59704,6.551 +6,14-10-2011,1386520.99,0,71.24,3.274,218.9109844,6.551 +6,21-10-2011,1417922.37,0,68.53,3.353,219.0740167,6.551 +6,28-10-2011,1419445.12,0,69.51,3.372,219.237049,6.551 +6,04-11-2011,1523420.38,0,58.54,3.332,219.4000812,6.551 +6,11-11-2011,1536176.54,0,61.33,3.297,219.5631135,6.551 +6,18-11-2011,1524390.07,0,63.89,3.308,219.7897137,6.551 +6,25-11-2011,2249811.55,1,62.78,3.236,220.0417412,6.551 +6,02-12-2011,1688531.34,0,51.18,3.172,220.2937686,6.551 +6,09-12-2011,1903385.14,0,43.64,3.158,220.5457961,6.551 +6,16-12-2011,2034695.56,0,53.27,3.159,220.7671856,6.551 +6,23-12-2011,2644633.02,0,49.45,3.112,220.9477245,6.551 +6,30-12-2011,1598080.52,1,46.8,3.129,221.1282634,6.551 +6,06-01-2012,1395339.71,0,50.82,3.157,221.3088023,6.132 +6,13-01-2012,1344243.17,0,48.33,3.261,221.4893412,6.132 +6,20-01-2012,1326255.7,0,55.37,3.268,221.5831306,6.132 +6,27-01-2012,1315610.66,0,53.95,3.29,221.6769199,6.132 +6,03-02-2012,1496305.78,0,57.45,3.36,221.7707093,6.132 +6,10-02-2012,1620603.92,1,48.58,3.409,221.8644987,6.132 +6,17-02-2012,1632616.09,0,49.03,3.51,222.026359,6.132 +6,24-02-2012,1465187.71,0,59.17,3.555,222.2392726,6.132 +6,02-03-2012,1550385.65,0,60.32,3.63,222.4521862,6.132 +6,09-03-2012,1569304.4,0,57.89,3.669,222.6650998,6.132 +6,16-03-2012,1748010.29,0,62.8,3.734,222.8186603,6.132 +6,23-03-2012,1495143.62,0,63.71,3.787,222.8930835,6.132 +6,30-03-2012,1508933.26,0,67.91,3.845,222.9675066,6.132 +6,06-04-2012,1840131.19,0,71.6,3.891,223.0419298,5.964 +6,13-04-2012,1616394.45,0,71.29,3.891,223.1163529,5.964 +6,20-04-2012,1456073.24,0,68.64,3.877,223.17092,5.964 +6,27-04-2012,1456221.1,0,71.5,3.814,223.2254871,5.964 +6,04-05-2012,1543461.12,0,77.66,3.749,223.2800541,5.964 +6,11-05-2012,1517075.67,0,72.66,3.688,223.3346212,5.964 +6,18-05-2012,1513635.64,0,70.5,3.63,223.3511928,5.964 +6,25-05-2012,1603793.42,0,78.47,3.561,223.3525662,5.964 +6,01-06-2012,1681121.38,0,80.39,3.501,223.3539397,5.964 +6,08-06-2012,1696619.52,0,80.5,3.452,223.3553131,5.964 +6,15-06-2012,1642247.48,0,82.1,3.393,223.3680933,5.964 +6,22-06-2012,1618272.25,0,81.2,3.346,223.4093906,5.964 +6,29-06-2012,1648863.46,0,87.35,3.286,223.4506878,5.964 +6,06-07-2012,1876359.39,0,82.95,3.227,223.4919851,5.668 +6,13-07-2012,1588142.26,0,80.27,3.256,223.5332824,5.668 +6,20-07-2012,1574361.97,0,81.57,3.311,223.5424501,5.668 +6,27-07-2012,1513229.16,0,85.78,3.407,223.5516178,5.668 +6,03-08-2012,1627274.93,0,87.55,3.417,223.5607856,5.668 +6,10-08-2012,1588380.73,0,87.04,3.494,223.5699533,5.668 +6,17-08-2012,1543049.52,0,87.53,3.571,223.6510224,5.668 +6,24-08-2012,1501095.49,0,79.03,3.62,223.7860175,5.668 +6,31-08-2012,1577439.81,0,83.58,3.638,223.9210125,5.668 +6,07-09-2012,1608077.01,1,86.33,3.73,224.0560076,5.668 +6,14-09-2012,1375166.86,0,76.41,3.717,224.2004678,5.668 +6,21-09-2012,1425603.65,0,70.81,3.721,224.4017192,5.668 +6,28-09-2012,1369131.46,0,77.82,3.666,224.6029706,5.668 +6,05-10-2012,1518177.71,0,70.84,3.617,224.804222,5.329 +6,12-10-2012,1459396.84,0,65.43,3.601,225.0054733,5.329 +6,19-10-2012,1436883.99,0,69.68,3.594,225.0501013,5.329 +6,26-10-2012,1431426.34,0,72.34,3.506,225.0686254,5.329 +7,05-02-2010,496725.44,0,10.53,2.58,189.3816974,9.014 +7,12-02-2010,524104.92,1,25.9,2.572,189.4642725,9.014 +7,19-02-2010,506760.54,0,27.28,2.55,189.5340998,9.014 +7,26-02-2010,496083.24,0,24.91,2.586,189.6018023,9.014 +7,05-03-2010,491419.55,0,35.86,2.62,189.6695049,9.014 +7,12-03-2010,480452.1,0,27.25,2.684,189.7372075,9.014 +7,19-03-2010,574450.23,0,29.04,2.692,189.734262,9.014 +7,26-03-2010,514731.6,0,23.33,2.717,189.7195417,9.014 +7,02-04-2010,561145.14,0,38.26,2.725,189.7048215,8.963 +7,09-04-2010,484263.25,0,33.79,2.75,189.6901012,8.963 +7,16-04-2010,406228.19,0,41.89,2.765,189.6628845,8.963 +7,23-04-2010,404751.25,0,43.07,2.776,189.6190057,8.963 +7,30-04-2010,373655.61,0,38.99,2.766,189.575127,8.963 +7,07-05-2010,395453.83,0,40.07,2.771,189.5312483,8.963 +7,14-05-2010,372673.61,0,41.41,2.788,189.4904116,8.963 +7,21-05-2010,395195.65,0,46.6,2.776,189.467827,8.963 +7,28-05-2010,442734.55,0,54.24,2.737,189.4452425,8.963 +7,04-06-2010,509183.22,0,53.63,2.7,189.422658,8.963 +7,11-06-2010,498580.87,0,63.59,2.684,189.4000734,8.963 +7,18-06-2010,481144.09,0,52.7,2.674,189.4185259,8.963 +7,25-06-2010,553714.87,0,59.94,2.715,189.4533931,8.963 +7,02-07-2010,575570.77,0,61.31,2.728,189.4882603,9.017 +7,09-07-2010,593462.34,0,58,2.711,189.5231276,9.017 +7,16-07-2010,557166.35,0,62.19,2.699,189.6125456,9.017 +7,23-07-2010,570231.21,0,64.64,2.691,189.774698,9.017 +7,30-07-2010,603547.16,0,66.07,2.69,189.9368504,9.017 +7,06-08-2010,643854.17,0,61.7,2.69,190.0990028,9.017 +7,13-08-2010,598185.4,0,60.13,2.723,190.2611552,9.017 +7,20-08-2010,582353.17,0,59.59,2.732,190.2948237,9.017 +7,27-08-2010,554309.24,0,57.57,2.731,190.3284922,9.017 +7,03-09-2010,532765.05,0,49.84,2.773,190.3621607,9.017 +7,10-09-2010,535769.32,1,48.5,2.78,190.3958293,9.017 +7,17-09-2010,489408.53,0,48.56,2.8,190.4688287,9.017 +7,24-09-2010,488008.83,0,47.55,2.793,190.5713264,9.017 +7,01-10-2010,448998.73,0,49.99,2.759,190.6738241,9.137 +7,08-10-2010,480239.88,0,44.13,2.745,190.7763218,9.137 +7,15-10-2010,463370.48,0,35.86,2.762,190.8623087,9.137 +7,22-10-2010,472450.81,0,36.84,2.762,190.9070184,9.137 +7,29-10-2010,465493.15,0,34.78,2.748,190.951728,9.137 +7,05-11-2010,480512.44,0,49.44,2.729,190.9964377,9.137 +7,12-11-2010,507584.29,0,22.12,2.737,191.0411474,9.137 +7,19-11-2010,482528.36,0,25.56,2.758,191.0312172,9.137 +7,26-11-2010,835189.26,1,17.95,2.742,191.0121805,9.137 +7,03-12-2010,552811.62,0,21.88,2.712,190.9931437,9.137 +7,10-12-2010,599730.07,0,24.24,2.728,190.9741069,9.137 +7,17-12-2010,716388.81,0,20.74,2.778,191.0303376,9.137 +7,24-12-2010,1045124.88,0,26.04,2.781,191.1430189,9.137 +7,31-12-2010,729572.08,1,13.76,2.829,191.2557002,9.137 +7,07-01-2011,661163.94,0,10.09,2.882,191.3683815,8.818 +7,14-01-2011,547384.9,0,11.32,2.911,191.4784939,8.818 +7,21-01-2011,521539.46,0,25.4,2.973,191.5731924,8.818 +7,28-01-2011,513372.17,0,10.11,3.008,191.667891,8.818 +7,04-02-2011,558027.77,0,-2.06,3.011,191.7625895,8.818 +7,11-02-2011,559903.13,1,10.24,3.037,191.8572881,8.818 +7,18-02-2011,572387.47,0,17.3,3.051,191.9178331,8.818 +7,25-02-2011,546690.84,0,17.46,3.101,191.9647167,8.818 +7,04-03-2011,551378.39,0,21.84,3.232,192.0116004,8.818 +7,11-03-2011,558963.83,0,20.7,3.372,192.058484,8.818 +7,18-03-2011,635014.69,0,27.69,3.406,192.1237981,8.818 +7,25-03-2011,559061.58,0,25.69,3.414,192.1964844,8.818 +7,01-04-2011,513409.67,0,24.83,3.461,192.2691707,8.595 +7,08-04-2011,500552.16,0,30.64,3.532,192.3418571,8.595 +7,15-04-2011,423380.14,0,27.79,3.611,192.4225954,8.595 +7,22-04-2011,466594.89,0,31.84,3.636,192.5234638,8.595 +7,29-04-2011,410429.73,0,26.79,3.663,192.6243322,8.595 +7,06-05-2011,407012.47,0,26.54,3.735,192.7252006,8.595 +7,13-05-2011,414094.05,0,36.61,3.767,192.826069,8.595 +7,20-05-2011,424670.98,0,36.16,3.828,192.831317,8.595 +7,27-05-2011,457216.87,0,37.51,3.795,192.8365651,8.595 +7,03-06-2011,542295.37,0,45.77,3.763,192.8418131,8.595 +7,10-06-2011,621099.95,0,53.3,3.735,192.8470612,8.595 +7,17-06-2011,610991.35,0,48.79,3.697,192.9034759,8.595 +7,24-06-2011,640043.97,0,46.85,3.661,192.9982655,8.595 +7,01-07-2011,704344.21,0,58.54,3.597,193.0930552,8.622 +7,08-07-2011,761793.94,0,59.08,3.54,193.1878448,8.622 +7,15-07-2011,642748.21,0,54.37,3.532,193.3125484,8.622 +7,22-07-2011,688043.96,0,56.22,3.545,193.5120367,8.622 +7,29-07-2011,653382.62,0,56.66,3.547,193.711525,8.622 +7,05-08-2011,695392.84,0,55.91,3.554,193.9110133,8.622 +7,12-08-2011,670670.46,0,54.56,3.542,194.1105017,8.622 +7,19-08-2011,645156.21,0,56.06,3.499,194.2500634,8.622 +7,26-08-2011,629994.47,0,57.6,3.485,194.3796374,8.622 +7,02-09-2011,592355.24,0,53.4,3.511,194.5092113,8.622 +7,09-09-2011,613135.23,1,45.61,3.566,194.6387853,8.622 +7,16-09-2011,558981.45,0,43.67,3.596,194.7419707,8.622 +7,23-09-2011,536144.81,0,43.67,3.581,194.8099713,8.622 +7,30-09-2011,488880.26,0,47.34,3.538,194.8779718,8.622 +7,07-10-2011,525866.36,0,40.65,3.498,194.9459724,8.513 +7,14-10-2011,501959.19,0,32.65,3.491,195.0261012,8.513 +7,21-10-2011,558691.43,0,37.49,3.548,195.1789994,8.513 +7,28-10-2011,527339.52,0,28.82,3.55,195.3318977,8.513 +7,04-11-2011,564536.01,0,23.41,3.527,195.4847959,8.513 +7,11-11-2011,556015.59,0,19.53,3.505,195.6376941,8.513 +7,18-11-2011,539826.56,0,29.53,3.479,195.7184713,8.513 +7,25-11-2011,949075.87,1,27.6,3.424,195.7704,8.513 +7,02-12-2011,591907.88,0,20.38,3.378,195.8223287,8.513 +7,09-12-2011,653845.45,0,11.17,3.331,195.8742575,8.513 +7,16-12-2011,720242.19,0,15.2,3.266,195.9841685,8.513 +7,23-12-2011,1059715.27,0,12.19,3.173,196.1713893,8.513 +7,30-12-2011,815915.52,1,15.56,3.119,196.3586101,8.513 +7,06-01-2012,713117.66,0,18.67,3.095,196.5458309,8.256 +7,13-01-2012,593875.46,0,7.46,3.077,196.7330517,8.256 +7,20-01-2012,578002.85,0,27.41,3.055,196.7796652,8.256 +7,27-01-2012,541037.98,0,26.9,3.038,196.8262786,8.256 +7,03-02-2012,580453.32,0,22.2,3.031,196.8728921,8.256 +7,10-02-2012,563460.77,1,18.79,3.103,196.9195056,8.256 +7,17-02-2012,620908.18,0,27.03,3.113,196.9432711,8.256 +7,24-02-2012,603041.14,0,24.41,3.129,196.9499007,8.256 +7,02-03-2012,551058.13,0,21.64,3.191,196.9565303,8.256 +7,09-03-2012,579166.5,0,30.1,3.286,196.9631599,8.256 +7,16-03-2012,669205.73,0,37.29,3.486,197.0457208,8.256 +7,23-03-2012,615997.29,0,35.06,3.664,197.2295234,8.256 +7,30-03-2012,583322.2,0,44.99,3.75,197.4133259,8.256 +7,06-04-2012,621425.98,0,44.29,3.854,197.5971285,8.09 +7,13-04-2012,517420.23,0,41.43,3.901,197.780931,8.09 +7,20-04-2012,457340.06,0,39.3,3.936,197.7227385,8.09 +7,27-04-2012,467827.75,0,51.49,3.927,197.664546,8.09 +7,04-05-2012,465198.89,0,45.38,3.903,197.6063534,8.09 +7,11-05-2012,460397.41,0,48.54,3.87,197.5481609,8.09 +7,18-05-2012,468428.3,0,49.41,3.837,197.5553137,8.09 +7,25-05-2012,532739.77,0,50.6,3.804,197.5886046,8.09 +7,01-06-2012,598495.02,0,55.06,3.764,197.6218954,8.09 +7,08-06-2012,642963.75,0,63.07,3.741,197.6551863,8.09 +7,15-06-2012,666942.02,0,59.33,3.723,197.692292,8.09 +7,22-06-2012,687344.68,0,63.69,3.735,197.7389345,8.09 +7,29-06-2012,704335.41,0,68.84,3.693,197.785577,8.09 +7,06-07-2012,805642.61,0,64.67,3.646,197.8322195,7.872 +7,13-07-2012,694150.89,0,64.21,3.613,197.8788621,7.872 +7,20-07-2012,686345.69,0,62.87,3.585,197.9290378,7.872 +7,27-07-2012,686365.4,0,64.6,3.57,197.9792136,7.872 +7,03-08-2012,680954.81,0,61.83,3.528,198.0293893,7.872 +7,10-08-2012,675926.3,0,63.41,3.509,198.0795651,7.872 +7,17-08-2012,642450.4,0,59.66,3.545,198.1001057,7.872 +7,24-08-2012,609099.37,0,59.27,3.558,198.0984199,7.872 +7,31-08-2012,586467.16,0,60.46,3.556,198.0967341,7.872 +7,07-09-2012,597876.55,1,57.84,3.596,198.0950484,7.872 +7,14-09-2012,541120.2,0,53.66,3.659,198.1267184,7.872 +7,21-09-2012,530842.25,0,51.77,3.765,198.358523,7.872 +7,28-09-2012,525545.76,0,50.64,3.789,198.5903276,7.872 +7,05-10-2012,505830.56,0,48.43,3.779,198.8221322,7.557 +7,12-10-2012,503463.93,0,41.43,3.76,199.0539368,7.557 +7,19-10-2012,516424.83,0,43.01,3.75,199.1481963,7.557 +7,26-10-2012,495543.28,0,42.53,3.686,199.2195317,7.557 +8,05-02-2010,1004137.09,0,34.14,2.572,214.4714512,6.299 +8,12-02-2010,994801.4,1,33.34,2.548,214.6214189,6.299 +8,19-02-2010,963960.37,0,39.1,2.514,214.6664878,6.299 +8,26-02-2010,847592.11,0,37.91,2.561,214.6940735,6.299 +8,05-03-2010,881503.95,0,45.64,2.625,214.7216592,6.299 +8,12-03-2010,860336.16,0,49.76,2.667,214.7492449,6.299 +8,19-03-2010,839911,0,47.26,2.72,214.5764954,6.299 +8,26-03-2010,772539.12,0,46.51,2.732,214.3703567,6.299 +8,02-04-2010,914500.91,0,60.18,2.719,214.164218,6.29 +8,09-04-2010,916033.92,0,59.25,2.77,213.9580793,6.29 +8,16-04-2010,882917.12,0,62.66,2.808,213.8186357,6.29 +8,23-04-2010,850440.26,0,56.1,2.795,213.768119,6.29 +8,30-04-2010,778672.64,0,61.01,2.78,213.7176024,6.29 +8,07-05-2010,916820.96,0,62.68,2.835,213.6670857,6.29 +8,14-05-2010,873337.84,0,61.35,2.854,213.6655355,6.29 +8,21-05-2010,818333.21,0,66.03,2.826,213.9577839,6.29 +8,28-05-2010,868041.56,0,74.71,2.759,214.2500323,6.29 +8,04-06-2010,958225.41,0,75.71,2.705,214.5422806,6.29 +8,11-06-2010,914835.86,0,82.21,2.668,214.834529,6.29 +8,18-06-2010,869922.56,0,78.79,2.637,214.8324452,6.29 +8,25-06-2010,814919.11,0,81.78,2.653,214.7126286,6.29 +8,02-07-2010,852333.75,0,74.78,2.669,214.5928119,6.315 +8,09-07-2010,845289.77,0,72.49,2.642,214.4729952,6.315 +8,16-07-2010,848630.57,0,77.49,2.623,214.4640599,6.315 +8,23-07-2010,785515.88,0,78.29,2.608,214.6029664,6.315 +8,30-07-2010,787295.09,0,76.02,2.64,214.7418728,6.315 +8,06-08-2010,893399.77,0,80.37,2.627,214.8807793,6.315 +8,13-08-2010,867919.21,0,80.11,2.692,215.0196857,6.315 +8,20-08-2010,870676.44,0,79.36,2.664,214.9779825,6.315 +8,27-08-2010,888816.78,0,74.92,2.619,214.9362793,6.315 +8,03-09-2010,899036.47,0,76.14,2.577,214.894576,6.315 +8,10-09-2010,831425.2,1,74.34,2.565,214.8528728,6.315 +8,17-09-2010,836707.85,0,75.32,2.582,214.8785562,6.315 +8,24-09-2010,773725.08,0,72.21,2.624,214.9547795,6.315 +8,01-10-2010,804105.49,0,68.7,2.603,215.0310029,6.433 +8,08-10-2010,870349.86,0,62.94,2.633,215.1072262,6.433 +8,15-10-2010,826546.96,0,62.59,2.72,215.1757,6.433 +8,22-10-2010,836419.14,0,62.86,2.725,215.2248,6.433 +8,29-10-2010,830756.76,0,57.93,2.716,215.2739,6.433 +8,05-11-2010,927266.34,0,55.76,2.689,215.323,6.433 +8,12-11-2010,911538.98,0,54.89,2.728,215.3721,6.433 +8,19-11-2010,885608.04,0,43.86,2.771,215.2538714,6.433 +8,26-11-2010,1261693.16,1,51.07,2.735,215.1077548,6.433 +8,03-12-2010,952766.93,0,42.85,2.708,214.9616381,6.433 +8,10-12-2010,1069061.63,0,42.47,2.843,214.8155214,6.433 +8,17-12-2010,1220579.55,0,45.03,2.869,214.7510843,6.433 +8,24-12-2010,1511641.09,0,45.67,2.886,214.7479069,6.433 +8,31-12-2010,773586.49,1,41.47,2.943,214.7447295,6.433 +8,07-01-2011,873065.23,0,35.77,2.976,214.7415521,6.262 +8,14-01-2011,809646.66,0,31.62,2.983,214.7930991,6.262 +8,21-01-2011,822668.23,0,42.06,3.016,215.1729926,6.262 +8,28-01-2011,782256.66,0,39.26,3.01,215.5528862,6.262 +8,04-02-2011,944594.78,0,24.48,2.989,215.9327797,6.262 +8,11-02-2011,996147.39,1,28.26,3.022,216.3126733,6.262 +8,18-02-2011,1065108.64,0,50.64,3.045,216.6310383,6.262 +8,25-02-2011,917317.15,0,51.29,3.065,216.9247918,6.262 +8,04-03-2011,935266.43,0,53.18,3.288,217.2185454,6.262 +8,11-03-2011,900387.29,0,49.14,3.459,217.512299,6.262 +8,18-03-2011,898289.14,0,56.68,3.488,217.7705442,6.262 +8,25-03-2011,827968.36,0,59.74,3.473,218.0145862,6.262 +8,01-04-2011,878762.3,0,49.86,3.524,218.2586281,6.297 +8,08-04-2011,949825.83,0,65.62,3.622,218.50267,6.297 +8,15-04-2011,908278.74,0,63.55,3.743,218.7262524,6.297 +8,22-04-2011,937473.13,0,65.11,3.807,218.8986857,6.297 +8,29-04-2011,855014.77,0,62.29,3.81,219.071119,6.297 +8,06-05-2011,941457.34,0,58.92,3.906,219.2435524,6.297 +8,13-05-2011,895763.41,0,72.96,3.899,219.4159857,6.297 +8,20-05-2011,836049.89,0,65.54,3.907,219.1746922,6.297 +8,27-05-2011,857939.41,0,73.14,3.786,218.9333986,6.297 +8,03-06-2011,929222.16,0,82.05,3.699,218.6921051,6.297 +8,10-06-2011,897309.41,0,82.21,3.648,218.4508115,6.297 +8,17-06-2011,922048.41,0,84.73,3.637,218.4021448,6.297 +8,24-06-2011,864881.24,0,83.94,3.594,218.4979481,6.297 +8,01-07-2011,883683.35,0,87.26,3.524,218.5937514,6.425 +8,08-07-2011,861965.12,0,83.57,3.48,218.6895548,6.425 +8,15-07-2011,849925.37,0,84.26,3.575,218.7746217,6.425 +8,22-07-2011,829902.42,0,85.46,3.651,218.8328475,6.425 +8,29-07-2011,807082.19,0,86.46,3.682,218.8910733,6.425 +8,05-08-2011,892393.77,0,85.15,3.684,218.9492991,6.425 +8,12-08-2011,856796.1,0,86.05,3.638,219.0075249,6.425 +8,19-08-2011,895066.5,0,82.92,3.554,219.0701968,6.425 +8,26-08-2011,912542.82,0,84.69,3.523,219.1336097,6.425 +8,02-09-2011,891387.14,0,84.77,3.533,219.1970226,6.425 +8,09-09-2011,848358.09,1,69.01,3.546,219.2604355,6.425 +8,16-09-2011,870971.82,0,69.09,3.526,219.4442443,6.425 +8,23-09-2011,806444.29,0,68.72,3.467,219.788581,6.425 +8,30-09-2011,809049.37,0,72.2,3.355,220.1329176,6.425 +8,07-10-2011,929976.55,0,67.61,3.285,220.4772543,6.123 +8,14-10-2011,863188.26,0,61.74,3.274,220.7960935,6.123 +8,21-10-2011,905984.49,0,59.97,3.353,220.9619484,6.123 +8,28-10-2011,876712.31,0,56.86,3.372,221.1278032,6.123 +8,04-11-2011,947815.05,0,49.68,3.332,221.2936581,6.123 +8,11-11-2011,917088.48,0,50.56,3.297,221.4595129,6.123 +8,18-11-2011,897032.19,0,51.72,3.308,221.6911738,6.123 +8,25-11-2011,1235163.86,1,49.61,3.236,221.9491571,6.123 +8,02-12-2011,986601.46,0,40.82,3.172,222.2071405,6.123 +8,09-12-2011,1051922.95,0,30.51,3.158,222.4651238,6.123 +8,16-12-2011,1118163.94,0,39.79,3.159,222.6910959,6.123 +8,23-12-2011,1462254.05,0,38.16,3.112,222.8743862,6.123 +8,30-12-2011,858572.22,1,36.33,3.129,223.0576765,6.123 +8,06-01-2012,872113.23,0,43.47,3.157,223.2409668,5.825 +8,13-01-2012,817661.76,0,36.46,3.261,223.4242571,5.825 +8,20-01-2012,813954.82,0,46.81,3.268,223.5188055,5.825 +8,27-01-2012,778178.53,0,45.52,3.29,223.6133539,5.825 +8,03-02-2012,927610.69,0,45.56,3.36,223.7079023,5.825 +8,10-02-2012,1021400.42,1,35.71,3.409,223.8024507,5.825 +8,17-02-2012,1096232.89,0,37.51,3.51,223.9658621,5.825 +8,24-02-2012,928537.54,0,46.33,3.555,224.1809207,5.825 +8,02-03-2012,952264.91,0,50.95,3.63,224.3959793,5.825 +8,09-03-2012,960115.56,0,49.59,3.669,224.6110379,5.825 +8,16-03-2012,921178.39,0,56.63,3.734,224.7657327,5.825 +8,23-03-2012,874223.25,0,52.9,3.787,224.8399424,5.825 +8,30-03-2012,905935.29,0,66.69,3.845,224.9141521,5.825 +8,06-04-2012,1046816.59,0,62.18,3.891,224.9883618,5.679 +8,13-04-2012,909989.45,0,65.19,3.891,225.0625714,5.679 +8,20-04-2012,872288.46,0,63.59,3.877,225.1179914,5.679 +8,27-04-2012,879448.25,0,70.34,3.814,225.1734114,5.679 +8,04-05-2012,937232.09,0,73.96,3.749,225.2288314,5.679 +8,11-05-2012,920128.89,0,64.96,3.688,225.2842514,5.679 +8,18-05-2012,913922.01,0,64.16,3.63,225.3002908,5.679 +8,25-05-2012,895157.44,0,76.11,3.561,225.3005779,5.679 +8,01-06-2012,921161.2,0,78.31,3.501,225.300865,5.679 +8,08-06-2012,928820,0,74.28,3.452,225.3011521,5.679 +8,15-06-2012,916918.7,0,77.14,3.393,225.3134743,5.679 +8,22-06-2012,899449.65,0,78.85,3.346,225.3558843,5.679 +8,29-06-2012,878298.22,0,84.47,3.286,225.3982943,5.679 +8,06-07-2012,936205.5,0,81.24,3.227,225.4407043,5.401 +8,13-07-2012,890488.01,0,78.46,3.256,225.4831143,5.401 +8,20-07-2012,888834.07,0,79.94,3.311,225.4930078,5.401 +8,27-07-2012,838227.52,0,81.71,3.407,225.5029014,5.401 +8,03-08-2012,897076.73,0,85.06,3.417,225.5127949,5.401 +8,10-08-2012,930745.69,0,83.74,3.494,225.5226885,5.401 +8,17-08-2012,896613.19,0,81.21,3.571,225.6050797,5.401 +8,24-08-2012,936373.65,0,73.77,3.62,225.7418442,5.401 +8,31-08-2012,976137.73,0,75.33,3.638,225.8786088,5.401 +8,07-09-2012,932160.37,1,80.87,3.73,226.0153733,5.401 +8,14-09-2012,883569.38,0,67.21,3.717,226.1615981,5.401 +8,21-09-2012,857796.45,0,66.96,3.721,226.3645848,5.401 +8,28-09-2012,884724.41,0,71.1,3.666,226.5675714,5.401 +8,05-10-2012,976436.02,0,61.41,3.617,226.7705581,5.124 +8,12-10-2012,927511.99,0,55.03,3.601,226.9735448,5.124 +8,19-10-2012,900309.75,0,62.99,3.594,227.0184166,5.124 +8,26-10-2012,891671.44,0,64.74,3.506,227.0369359,5.124 +9,05-02-2010,549505.55,0,38.01,2.572,214.6554591,6.415 +9,12-02-2010,552677.48,1,37.08,2.548,214.8056534,6.415 +9,19-02-2010,511327.9,0,43.06,2.514,214.8506185,6.415 +9,26-02-2010,473773.27,0,43.83,2.561,214.8780453,6.415 +9,05-03-2010,507297.88,0,48.43,2.625,214.9054721,6.415 +9,12-03-2010,494145.8,0,55.76,2.667,214.932899,6.415 +9,19-03-2010,485744.61,0,53.15,2.72,214.7597274,6.415 +9,26-03-2010,484946.56,0,51.8,2.732,214.5531227,6.415 +9,02-04-2010,545206.32,0,65.21,2.719,214.3465181,6.384 +9,09-04-2010,529384.31,0,64.95,2.77,214.1399135,6.384 +9,16-04-2010,485764.32,0,66.09,2.808,214.0001817,6.384 +9,23-04-2010,488683.57,0,61.26,2.795,213.9496138,6.384 +9,30-04-2010,491723.42,0,66.07,2.78,213.8990459,6.384 +9,07-05-2010,526128.61,0,68.58,2.835,213.848478,6.384 +9,14-05-2010,492792.8,0,70.53,2.854,213.8469819,6.384 +9,21-05-2010,506274.94,0,71.5,2.826,214.1399162,6.384 +9,28-05-2010,558143.53,0,77.12,2.759,214.4328505,6.384 +9,04-06-2010,586061.46,0,79.65,2.705,214.7257848,6.384 +9,11-06-2010,522715.68,0,83.75,2.668,215.0187191,6.384 +9,18-06-2010,513073.87,0,82.99,2.637,215.0166484,6.384 +9,25-06-2010,509263.28,0,85.02,2.653,214.8965756,6.384 +9,02-07-2010,528832.54,0,78.55,2.669,214.7765028,6.442 +9,09-07-2010,485389.15,0,78.51,2.642,214.6564301,6.442 +9,16-07-2010,474030.51,0,82.93,2.623,214.6474453,6.442 +9,23-07-2010,462676.5,0,84.49,2.608,214.7865779,6.442 +9,30-07-2010,468675.19,0,79.83,2.64,214.9257105,6.442 +9,06-08-2010,522815.45,0,87.09,2.627,215.064843,6.442 +9,13-08-2010,481897.98,0,86.85,2.692,215.2039756,6.442 +9,20-08-2010,499325.38,0,86.3,2.664,215.1619646,6.442 +9,27-08-2010,506789.66,0,84.01,2.619,215.1199536,6.442 +9,03-09-2010,511049.06,0,82.47,2.577,215.0779426,6.442 +9,10-09-2010,484835.2,1,77.7,2.565,215.0359315,6.442 +9,17-09-2010,463448.59,0,81.19,2.582,215.0615285,6.442 +9,24-09-2010,452905.22,0,77.15,2.624,215.1378313,6.442 +9,01-10-2010,495692.19,0,69.08,2.603,215.2141341,6.56 +9,08-10-2010,505069.21,0,65.35,2.633,215.290437,6.56 +9,15-10-2010,454769.68,0,67.36,2.72,215.3589917,6.56 +9,22-10-2010,466322.76,0,69.99,2.725,215.4081762,6.56 +9,29-10-2010,508801.61,0,64.43,2.716,215.4573607,6.56 +9,05-11-2010,517869.97,0,58.69,2.689,215.5065452,6.56 +9,12-11-2010,520846.68,0,61.59,2.728,215.5557297,6.56 +9,19-11-2010,519823.3,0,49.96,2.771,215.4372854,6.56 +9,26-11-2010,768070.53,1,60.18,2.735,215.2909028,6.56 +9,03-12-2010,578164.82,0,49.89,2.708,215.1445203,6.56 +9,10-12-2010,618121.82,0,46.1,2.843,214.9981378,6.56 +9,17-12-2010,685243.2,0,49.7,2.869,214.9334937,6.56 +9,24-12-2010,873347.55,0,50.93,2.886,214.9301534,6.56 +9,31-12-2010,459770.85,1,45.92,2.943,214.9268131,6.56 +9,07-01-2011,490981.78,0,41.82,2.976,214.9234729,6.416 +9,14-01-2011,458086.69,0,36.43,2.983,214.9749587,6.416 +9,21-01-2011,454021.69,0,44.72,3.016,215.3554013,6.416 +9,28-01-2011,463561.48,0,43.9,3.01,215.7358438,6.416 +9,04-02-2011,544612.28,0,31.82,2.989,216.1162864,6.416 +9,11-02-2011,555279.02,1,34.13,3.022,216.496729,6.416 +9,18-02-2011,610985.56,0,58.5,3.045,216.8154856,6.416 +9,25-02-2011,513107.2,0,59.01,3.065,217.1095679,6.416 +9,04-03-2011,542016.18,0,60.67,3.288,217.4036503,6.416 +9,11-03-2011,517783.5,0,54.75,3.459,217.6977326,6.416 +9,18-03-2011,515226.11,0,63.82,3.488,217.9563371,6.416 +9,25-03-2011,497488.4,0,68.79,3.473,218.2007506,6.416 +9,01-04-2011,520962.14,0,56.12,3.524,218.445164,6.38 +9,08-04-2011,561625.92,0,71.4,3.622,218.6895775,6.38 +9,15-04-2011,528420.28,0,71.9,3.743,218.9134935,6.38 +9,22-04-2011,549502.11,0,72.35,3.807,219.0861659,6.38 +9,29-04-2011,532226.2,0,70.85,3.81,219.2588382,6.38 +9,06-05-2011,545251.1,0,62.2,3.906,219.4315106,6.38 +9,13-05-2011,539126,0,77.66,3.899,219.6041829,6.38 +9,20-05-2011,518266.9,0,70.49,3.907,219.3622809,6.38 +9,27-05-2011,553834.04,0,80.42,3.786,219.1203788,6.38 +9,03-06-2011,587004.29,0,85.8,3.699,218.8784768,6.38 +9,10-06-2011,550076.32,0,85.81,3.648,218.6365747,6.38 +9,17-06-2011,558671.14,0,89.15,3.637,218.5877333,6.38 +9,24-06-2011,538745.93,0,86.74,3.594,218.6836874,6.38 +9,01-07-2011,537064.03,0,89.14,3.524,218.7796415,6.404 +9,08-07-2011,535983.13,0,89.04,3.48,218.8755955,6.404 +9,15-07-2011,512834.04,0,90.45,3.575,218.9607242,6.404 +9,22-07-2011,491449.94,0,89.08,3.651,219.0187895,6.404 +9,29-07-2011,471449.98,0,91.1,3.682,219.0768548,6.404 +9,05-08-2011,554879.67,0,91.52,3.684,219.1349201,6.404 +9,12-08-2011,520284.79,0,91.63,3.638,219.1929854,6.404 +9,19-08-2011,540819.44,0,85.8,3.554,219.2556109,6.404 +9,26-08-2011,542663.53,0,88.95,3.523,219.3189965,6.404 +9,02-09-2011,544643.33,0,89.33,3.533,219.382382,6.404 +9,09-09-2011,528784.86,1,75.65,3.546,219.4457675,6.404 +9,16-09-2011,500274.03,0,77.95,3.526,219.6297841,6.404 +9,23-09-2011,506743.78,0,74.42,3.467,219.9746423,6.404 +9,30-09-2011,508567.04,0,78.45,3.355,220.3195004,6.404 +9,07-10-2011,553836.98,0,72.62,3.285,220.6643585,6.054 +9,14-10-2011,529515.66,0,67.27,3.274,220.9836849,6.054 +9,21-10-2011,557075.21,0,65.46,3.353,221.1498206,6.054 +9,28-10-2011,548527.49,0,63.96,3.372,221.3159563,6.054 +9,04-11-2011,597855.07,0,54.46,3.332,221.4820921,6.054 +9,11-11-2011,594574.12,0,58.28,3.297,221.6482278,6.054 +9,18-11-2011,542414.27,0,58.8,3.308,221.8803923,6.054 +9,25-11-2011,814753.5,1,54.32,3.236,222.1389683,6.054 +9,02-12-2011,613115.21,0,46.84,3.172,222.3975443,6.054 +9,09-12-2011,630327.28,0,37.65,3.158,222.6561203,6.054 +9,16-12-2011,705557.97,0,47.31,3.159,222.8825484,6.054 +9,23-12-2011,905324.68,0,44.43,3.112,223.0661125,6.054 +9,30-12-2011,549788.36,1,43.41,3.129,223.2496766,6.054 +9,06-01-2012,519585.67,0,47.54,3.157,223.4332408,5.667 +9,13-01-2012,474964.6,0,42.44,3.261,223.6168049,5.667 +9,20-01-2012,480130.04,0,51.56,3.268,223.7114288,5.667 +9,27-01-2012,482451.21,0,49.38,3.29,223.8060527,5.667 +9,03-02-2012,549967.89,0,54.43,3.36,223.9006766,5.667 +9,10-02-2012,609736.12,1,44.03,3.409,223.9953006,5.667 +9,17-02-2012,658965.05,0,43.81,3.51,224.1588663,5.667 +9,24-02-2012,563578.79,0,53.67,3.555,224.3741384,5.667 +9,02-03-2012,619498.28,0,57.2,3.63,224.5894104,5.667 +9,09-03-2012,574955.95,0,54.03,3.669,224.8046825,5.667 +9,16-03-2012,550373.57,0,59.94,3.734,224.9594902,5.667 +9,23-03-2012,550791.32,0,58.79,3.787,225.0336786,5.667 +9,30-03-2012,574985.37,0,67.87,3.845,225.107867,5.667 +9,06-04-2012,677885.99,0,68.83,3.891,225.1820555,5.539 +9,13-04-2012,578539.86,0,69.19,3.891,225.2562439,5.539 +9,20-04-2012,542819.03,0,68.04,3.877,225.3117488,5.539 +9,27-04-2012,550414.99,0,73.07,3.814,225.3672537,5.539 +9,04-05-2012,586289.08,0,78.98,3.749,225.4227585,5.539 +9,11-05-2012,592572.3,0,70.94,3.688,225.4782634,5.539 +9,18-05-2012,571463.93,0,69.52,3.63,225.4942498,5.539 +9,25-05-2012,547226,0,79.69,3.561,225.4944288,5.539 +9,01-06-2012,583648.59,0,80.26,3.501,225.4946078,5.539 +9,08-06-2012,582525.42,0,78.91,3.452,225.4947868,5.539 +9,15-06-2012,564606.1,0,82.21,3.393,225.5070634,5.539 +9,22-06-2012,562173.12,0,81.05,3.346,225.5495841,5.539 +9,29-06-2012,544770.7,0,87.18,3.286,225.5921049,5.539 +9,06-07-2012,578790.36,0,84.15,3.227,225.6346256,5.277 +9,13-07-2012,536537.64,0,82.39,3.256,225.6771463,5.277 +9,20-07-2012,513991.57,0,83.39,3.311,225.6871121,5.277 +9,27-07-2012,495951,0,86.41,3.407,225.6970779,5.277 +9,03-08-2012,533887.54,0,90.23,3.417,225.7070437,5.277 +9,10-08-2012,538713.47,0,88.66,3.494,225.7170094,5.277 +9,17-08-2012,535153.47,0,86.37,3.571,225.7995323,5.277 +9,24-08-2012,572887.78,0,77.9,3.62,225.9364729,5.277 +9,31-08-2012,576879.15,0,80.71,3.638,226.0734135,5.277 +9,07-09-2012,565812.29,1,87.93,3.73,226.2103541,5.277 +9,14-09-2012,523427.35,0,73.55,3.717,226.3567545,5.277 +9,21-09-2012,533756.88,0,69.92,3.721,226.5599138,5.277 +9,28-09-2012,516361.06,0,76.8,3.666,226.7630732,5.277 +9,05-10-2012,606755.3,0,66.61,3.617,226.9662325,4.954 +9,12-10-2012,558464.8,0,60.09,3.601,227.1693919,4.954 +9,19-10-2012,542009.46,0,68.01,3.594,227.214288,4.954 +9,26-10-2012,549731.49,0,69.52,3.506,227.2328068,4.954 +10,05-02-2010,2193048.75,0,54.34,2.962,126.4420645,9.765 +10,12-02-2010,2176028.52,1,49.96,2.828,126.4962581,9.765 +10,19-02-2010,2113432.58,0,58.22,2.915,126.5262857,9.765 +10,26-02-2010,2006774.96,0,52.77,2.825,126.5522857,9.765 +10,05-03-2010,1987090.09,0,55.92,2.877,126.5782857,9.765 +10,12-03-2010,1941346.13,0,52.33,3.034,126.6042857,9.765 +10,19-03-2010,1946875.06,0,61.46,3.054,126.6066452,9.765 +10,26-03-2010,1893532.46,0,60.05,2.98,126.6050645,9.765 +10,02-04-2010,2138651.97,0,63.66,3.086,126.6034839,9.524 +10,09-04-2010,2041069.37,0,65.29,3.004,126.6019032,9.524 +10,16-04-2010,1826241.44,0,69.74,3.109,126.5621,9.524 +10,23-04-2010,1829521.83,0,66.42,3.05,126.4713333,9.524 +10,30-04-2010,1790694.59,0,69.76,3.105,126.3805667,9.524 +10,07-05-2010,1921432.16,0,71.06,3.127,126.2898,9.524 +10,14-05-2010,1808056.41,0,73.88,3.145,126.2085484,9.524 +10,21-05-2010,1847613.58,0,78.32,3.12,126.1843871,9.524 +10,28-05-2010,1904618.17,0,76.67,3.058,126.1602258,9.524 +10,04-06-2010,1931406.28,0,82.82,2.941,126.1360645,9.524 +10,11-06-2010,1827521.71,0,89.67,3.057,126.1119032,9.524 +10,18-06-2010,1837636.24,0,83.49,2.935,126.114,9.524 +10,25-06-2010,1768172.31,0,90.32,3.084,126.1266,9.524 +10,02-07-2010,1845893.87,0,92.89,2.978,126.1392,9.199 +10,09-07-2010,1769793.37,0,91.03,3.1,126.1518,9.199 +10,16-07-2010,1828052.47,0,91.8,2.971,126.1498065,9.199 +10,23-07-2010,1831676.03,0,88.44,3.112,126.1283548,9.199 +10,30-07-2010,1832664.03,0,85.03,3.017,126.1069032,9.199 +10,06-08-2010,1949236.09,0,86.13,3.123,126.0854516,9.199 +10,13-08-2010,1962996.7,0,88.37,3.049,126.064,9.199 +10,20-08-2010,1983190.56,0,89.88,3.041,126.0766452,9.199 +10,27-08-2010,1727565.42,0,84.99,3.022,126.0892903,9.199 +10,03-09-2010,1766331.45,0,83.8,3.087,126.1019355,9.199 +10,10-09-2010,1720530.23,1,84.04,2.961,126.1145806,9.199 +10,17-09-2010,1716755.78,0,85.52,3.028,126.1454667,9.199 +10,24-09-2010,1655036.75,0,85.75,2.939,126.1900333,9.199 +10,01-10-2010,1645892.97,0,86.01,3.001,126.2346,9.003 +10,08-10-2010,1772192.42,0,77.04,2.924,126.2791667,9.003 +10,15-10-2010,1703850.25,0,75.48,3.08,126.3266774,9.003 +10,22-10-2010,1740234.06,0,68.12,3.014,126.3815484,9.003 +10,29-10-2010,1741308.56,0,68.76,3.13,126.4364194,9.003 +10,05-11-2010,1832211.96,0,71.04,3.009,126.4912903,9.003 +10,12-11-2010,1895901.59,0,61.24,3.13,126.5461613,9.003 +10,19-11-2010,1949177.13,0,58.83,3.047,126.6072,9.003 +10,26-11-2010,2939946.38,1,55.33,3.162,126.6692667,9.003 +10,03-12-2010,2251206.64,0,51.17,3.041,126.7313333,9.003 +10,10-12-2010,2411790.21,0,60.51,3.091,126.7934,9.003 +10,17-12-2010,2811646.85,0,59.15,3.125,126.8794839,9.003 +10,24-12-2010,3749057.69,0,57.06,3.236,126.9835806,9.003 +10,31-12-2010,1707298.14,1,49.67,3.148,127.0876774,9.003 +10,07-01-2011,1714309.9,0,43.43,3.287,127.1917742,8.744 +10,14-01-2011,1710803.59,0,49.98,3.312,127.3009355,8.744 +10,21-01-2011,1677556.18,0,56.75,3.336,127.4404839,8.744 +10,28-01-2011,1715769.05,0,53.03,3.231,127.5800323,8.744 +10,04-02-2011,1968045.91,0,44.88,3.348,127.7195806,8.744 +10,11-02-2011,2115408.31,1,51.51,3.381,127.859129,8.744 +10,18-02-2011,2106934.55,0,61.77,3.43,127.99525,8.744 +10,25-02-2011,1967996.71,0,53.59,3.398,128.13,8.744 +10,04-03-2011,1958003.19,0,56.96,3.674,128.26475,8.744 +10,11-03-2011,1933469.15,0,64.22,3.63,128.3995,8.744 +10,18-03-2011,1884734.31,0,70.12,3.892,128.5121935,8.744 +10,25-03-2011,1815798.85,0,62.53,3.716,128.6160645,8.744 +10,01-04-2011,1827733.18,0,67.64,3.772,128.7199355,8.494 +10,08-04-2011,1870720.73,0,73.03,3.818,128.8238065,8.494 +10,15-04-2011,1781767.22,0,61.05,4.089,128.9107333,8.494 +10,22-04-2011,2004831.14,0,75.93,3.917,128.9553,8.494 +10,29-04-2011,1873646.34,0,73.38,4.151,128.9998667,8.494 +10,06-05-2011,1841369.99,0,73.56,4.193,129.0444333,8.494 +10,13-05-2011,1712995.44,0,74.04,4.202,129.089,8.494 +10,20-05-2011,1720908.01,0,72.62,3.99,129.0756774,8.494 +10,27-05-2011,1743000.38,0,78.62,3.933,129.0623548,8.494 +10,03-06-2011,1792210.89,0,81.87,3.893,129.0490323,8.494 +10,10-06-2011,1740063.1,0,84.57,3.981,129.0357097,8.494 +10,17-06-2011,1817934.76,0,87.96,3.935,129.0432,8.494 +10,24-06-2011,1711813.13,0,90.69,3.807,129.0663,8.494 +10,01-07-2011,1751369.75,0,95.36,3.842,129.0894,8.257 +10,08-07-2011,1699708.38,0,88.57,3.793,129.1125,8.257 +10,15-07-2011,1775068.4,0,86.01,3.779,129.1338387,8.257 +10,22-07-2011,1774342.61,0,88.59,3.697,129.1507742,8.257 +10,29-07-2011,1745841.33,0,86.75,3.694,129.1677097,8.257 +10,05-08-2011,1886299.98,0,89.8,3.803,129.1846452,8.257 +10,12-08-2011,1917397.63,0,85.61,3.794,129.2015806,8.257 +10,19-08-2011,1954849.68,0,87.4,3.743,129.2405806,8.257 +10,26-08-2011,1728399.07,0,91.59,3.663,129.2832581,8.257 +10,02-09-2011,1758587.35,0,91.61,3.798,129.3259355,8.257 +10,09-09-2011,1670579.82,1,89.06,3.771,129.3686129,8.257 +10,16-09-2011,1650894.3,0,77.49,3.784,129.4306,8.257 +10,23-09-2011,1685910.53,0,82.51,3.789,129.5183333,8.257 +10,30-09-2011,1627707.31,0,82.27,3.877,129.6060667,8.257 +10,07-10-2011,1788227.6,0,75.01,3.827,129.6938,7.874 +10,14-10-2011,1704753.02,0,70.27,3.698,129.7706452,7.874 +10,21-10-2011,1745928.56,0,77.91,3.842,129.7821613,7.874 +10,28-10-2011,1771792.97,0,72.79,3.843,129.7936774,7.874 +10,04-11-2011,1904438.59,0,68.57,3.828,129.8051935,7.874 +10,11-11-2011,2076570.84,0,55.28,3.677,129.8167097,7.874 +10,18-11-2011,1869087.85,0,58.97,3.669,129.8268333,7.874 +10,25-11-2011,2950198.64,1,60.68,3.76,129.8364,7.874 +10,02-12-2011,2068097.18,0,57.29,3.701,129.8459667,7.874 +10,09-12-2011,2429310.9,0,42.58,3.644,129.8555333,7.874 +10,16-12-2011,2555031.18,0,50.53,3.489,129.8980645,7.874 +10,23-12-2011,3487986.89,0,48.36,3.541,129.9845484,7.874 +10,30-12-2011,1930690.37,1,48.92,3.428,130.0710323,7.874 +10,06-01-2012,1683401.78,0,59.85,3.443,130.1575161,7.545 +10,13-01-2012,1711562.73,0,51,3.477,130.244,7.545 +10,20-01-2012,1675562.94,0,54.51,3.66,130.2792258,7.545 +10,27-01-2012,1632406,0,53.59,3.675,130.3144516,7.545 +10,03-02-2012,1867403.01,0,56.85,3.543,130.3496774,7.545 +10,10-02-2012,2218595.8,1,55.73,3.722,130.3849032,7.545 +10,17-02-2012,2168709.76,0,54.12,3.781,130.4546207,7.545 +10,24-02-2012,2039415.74,0,56.02,3.95,130.5502069,7.545 +10,02-03-2012,1990371.02,0,57.62,3.882,130.6457931,7.545 +10,09-03-2012,1917483.1,0,57.65,3.963,130.7413793,7.545 +10,16-03-2012,1930814.66,0,62.11,4.273,130.8261935,7.545 +10,23-03-2012,1837457.69,0,56.54,4.288,130.8966452,7.545 +10,30-03-2012,1815760.42,0,67.92,4.294,130.9670968,7.545 +10,06-04-2012,2163384.17,0,65.99,4.282,131.0375484,7.382 +10,13-04-2012,1974687.51,0,70.28,4.254,131.108,7.382 +10,20-04-2012,1777166.53,0,67.75,4.111,131.1173333,7.382 +10,27-04-2012,1712987.56,0,80.11,4.088,131.1266667,7.382 +10,04-05-2012,1821364.42,0,77.02,4.058,131.136,7.382 +10,11-05-2012,1792345.3,0,76.03,4.186,131.1453333,7.382 +10,18-05-2012,1795152.73,0,85.19,4.308,131.0983226,7.382 +10,25-05-2012,1830939.1,0,86.03,4.127,131.0287742,7.382 +10,01-06-2012,1767471.48,0,80.06,4.277,130.9592258,7.382 +10,08-06-2012,1840491.41,0,86.87,4.103,130.8896774,7.382 +10,15-06-2012,1811562.88,0,88.58,4.144,130.8295333,7.382 +10,22-06-2012,1755334.18,0,89.92,4.014,130.7929,7.382 +10,29-06-2012,1707481.9,0,91.36,3.875,130.7562667,7.382 +10,06-07-2012,1805999.79,0,86.87,3.666,130.7196333,7.17 +10,13-07-2012,1765571.91,0,89.8,3.723,130.683,7.17 +10,20-07-2012,1869967.03,0,84.45,3.589,130.7012903,7.17 +10,27-07-2012,1817603.66,0,83.98,3.769,130.7195806,7.17 +10,03-08-2012,1939440.09,0,84.76,3.595,130.737871,7.17 +10,10-08-2012,1880436.94,0,90.78,3.811,130.7561613,7.17 +10,17-08-2012,1827797.4,0,88.83,4.002,130.7909677,7.17 +10,24-08-2012,1764984.15,0,82.5,4.055,130.8381613,7.17 +10,31-08-2012,1650285.54,0,86.97,3.886,130.8853548,7.17 +10,07-09-2012,1708283.28,1,83.07,4.124,130.9325484,7.17 +10,14-09-2012,1640168.99,0,78.47,3.966,130.9776667,7.17 +10,21-09-2012,1671857.57,0,81.93,4.125,131.0103333,7.17 +10,28-09-2012,1694862.41,0,82.52,3.966,131.043,7.17 +10,05-10-2012,1758971.38,0,80.88,4.132,131.0756667,6.943 +10,12-10-2012,1713889.11,0,76.03,4.468,131.1083333,6.943 +10,19-10-2012,1734834.82,0,72.71,4.449,131.1499677,6.943 +10,26-10-2012,1744349.05,0,70.5,4.301,131.1930968,6.943 +11,05-02-2010,1528008.64,0,46.04,2.572,214.4248812,7.368 +11,12-02-2010,1574684.08,1,48.01,2.548,214.5747916,7.368 +11,19-02-2010,1503298.7,0,48.3,2.514,214.6198868,7.368 +11,26-02-2010,1336404.65,0,52.79,2.561,214.6475127,7.368 +11,05-03-2010,1426622.65,0,53.96,2.625,214.6751386,7.368 +11,12-03-2010,1331883.16,0,64.1,2.667,214.7027646,7.368 +11,19-03-2010,1364207,0,61.51,2.72,214.5301219,7.368 +11,26-03-2010,1245624.27,0,58.09,2.732,214.3241011,7.368 +11,02-04-2010,1446210.26,0,66.16,2.719,214.1180803,7.343 +11,09-04-2010,1470308.32,0,69.57,2.77,213.9120595,7.343 +11,16-04-2010,1323243.35,0,67.81,2.808,213.7726889,7.343 +11,23-04-2010,1283766.55,0,68.37,2.795,213.7221852,7.343 +11,30-04-2010,1239766.89,0,71.13,2.78,213.6716815,7.343 +11,07-05-2010,1312329.78,0,75.57,2.835,213.6211778,7.343 +11,14-05-2010,1266796.13,0,77.64,2.854,213.6196139,7.343 +11,21-05-2010,1271646.62,0,76.97,2.826,213.9116886,7.343 +11,28-05-2010,1264272.52,0,79.69,2.759,214.2037634,7.343 +11,04-06-2010,1396322.19,0,79.66,2.705,214.4958382,7.343 +11,11-06-2010,1339570.85,0,82.81,2.668,214.787913,7.343 +11,18-06-2010,1336522.92,0,84.13,2.637,214.7858259,7.343 +11,25-06-2010,1262025.08,0,84.5,2.653,214.6660741,7.343 +11,02-07-2010,1302600.14,0,83.09,2.669,214.5463222,7.346 +11,09-07-2010,1280156.47,0,83.01,2.642,214.4265704,7.346 +11,16-07-2010,1290609.54,0,84.9,2.623,214.4176476,7.346 +11,23-07-2010,1244390.03,0,84.57,2.608,214.5564968,7.346 +11,30-07-2010,1250178.89,0,83.26,2.64,214.695346,7.346 +11,06-08-2010,1369634.92,0,86.54,2.627,214.8341952,7.346 +11,13-08-2010,1384339.1,0,87.73,2.692,214.9730444,7.346 +11,20-08-2010,1430192.37,0,88.93,2.664,214.9314191,7.346 +11,27-08-2010,1311263.07,0,87.7,2.619,214.8897938,7.346 +11,03-09-2010,1303914.27,0,84.94,2.577,214.8481685,7.346 +11,10-09-2010,1231428.46,1,81.93,2.565,214.8065431,7.346 +11,17-09-2010,1215676.31,0,83.04,2.582,214.8322484,7.346 +11,24-09-2010,1170103.25,0,77.36,2.624,214.9084516,7.346 +11,01-10-2010,1182490.46,0,75.11,2.603,214.9846548,7.564 +11,08-10-2010,1293472.8,0,68.71,2.633,215.060858,7.564 +11,15-10-2010,1175003.67,0,71.46,2.72,215.1293114,7.564 +11,22-10-2010,1169831.38,0,72.6,2.725,215.17839,7.564 +11,29-10-2010,1195036,0,74.21,2.716,215.2274686,7.564 +11,05-11-2010,1332759.13,0,64.41,2.689,215.2765472,7.564 +11,12-11-2010,1281675.6,0,63.74,2.728,215.3256258,7.564 +11,19-11-2010,1292346.57,0,58.63,2.771,215.2074519,7.564 +11,26-11-2010,1757242.51,1,69.9,2.735,215.0614025,7.564 +11,03-12-2010,1380522.64,0,55.9,2.708,214.9153531,7.564 +11,10-12-2010,1564516.43,0,53.33,2.843,214.7693037,7.564 +11,17-12-2010,1843971.15,0,54.63,2.869,214.704919,7.564 +11,24-12-2010,2306265.36,0,59.33,2.886,214.7017828,7.564 +11,31-12-2010,1172003.1,1,55.03,2.943,214.6986466,7.564 +11,07-01-2011,1178905.44,0,54.43,2.976,214.6955104,7.551 +11,14-01-2011,1194449.78,0,45.34,2.983,214.7470729,7.551 +11,21-01-2011,1187776.19,0,51.51,3.016,215.1268275,7.551 +11,28-01-2011,1100418.69,0,51.04,3.01,215.5065821,7.551 +11,04-02-2011,1422546.05,0,47.17,2.989,215.8863367,7.551 +11,11-02-2011,1419236.9,1,44.61,3.022,216.2660913,7.551 +11,18-02-2011,1554747.15,0,61.5,3.045,216.5843571,7.551 +11,25-02-2011,1323999.36,0,68.74,3.065,216.8780275,7.551 +11,04-03-2011,1399456.99,0,66.5,3.288,217.1716979,7.551 +11,11-03-2011,1314557.31,0,63.29,3.459,217.4653683,7.551 +11,18-03-2011,1391813.69,0,70.17,3.488,217.7235226,7.551 +11,25-03-2011,1229777.24,0,73.74,3.473,217.9674705,7.551 +11,01-04-2011,1258674.12,0,69.1,3.524,218.2114184,7.574 +11,08-04-2011,1327401.06,0,73.57,3.622,218.4553663,7.574 +11,15-04-2011,1312905.8,0,76.64,3.743,218.6788642,7.574 +11,22-04-2011,1388118.53,0,78.31,3.807,218.851237,7.574 +11,29-04-2011,1357589.89,0,79.97,3.81,219.0236099,7.574 +11,06-05-2011,1331453.41,0,71.39,3.906,219.1959827,7.574 +11,13-05-2011,1277959.42,0,80.93,3.899,219.3683556,7.574 +11,20-05-2011,1239466.97,0,76.97,3.907,219.127216,7.574 +11,27-05-2011,1216876.52,0,85.61,3.786,218.8860765,7.574 +11,03-06-2011,1343637,0,86.14,3.699,218.6449369,7.574 +11,10-06-2011,1314626.75,0,85.79,3.648,218.4037974,7.574 +11,17-06-2011,1337506.74,0,87.9,3.637,218.3551748,7.574 +11,24-06-2011,1254587.84,0,86.13,3.594,218.45094,7.574 +11,01-07-2011,1297472.06,0,86.43,3.524,218.5467052,7.567 +11,08-07-2011,1334627.96,0,87.17,3.48,218.6424704,7.567 +11,15-07-2011,1266546.73,0,88.3,3.575,218.7275216,7.567 +11,22-07-2011,1290576.44,0,87.8,3.651,218.7857881,7.567 +11,29-07-2011,1212938.67,0,89.46,3.682,218.8440545,7.567 +11,05-08-2011,1403198.94,0,90.04,3.684,218.9023209,7.567 +11,12-08-2011,1354188.43,0,90.3,3.638,218.9605873,7.567 +11,19-08-2011,1484169.74,0,89.51,3.554,219.023271,7.567 +11,26-08-2011,1304706.75,0,89.09,3.523,219.0866908,7.567 +11,02-09-2011,1297792.41,0,91.44,3.533,219.1501106,7.567 +11,09-09-2011,1249439.95,1,84.91,3.546,219.2135305,7.567 +11,16-09-2011,1270816.01,0,85.11,3.526,219.3972867,7.567 +11,23-09-2011,1235775.15,0,82.14,3.467,219.7414914,7.567 +11,30-09-2011,1190515.83,0,84.4,3.355,220.085696,7.567 +11,07-10-2011,1346271.06,0,76.97,3.285,220.4299007,7.197 +11,14-10-2011,1286388.96,0,75.56,3.274,220.7486167,7.197 +11,21-10-2011,1325107.53,0,70.91,3.353,220.9144005,7.197 +11,28-10-2011,1310684.1,0,72.66,3.372,221.0801842,7.197 +11,04-11-2011,1458287.38,0,61.13,3.332,221.245968,7.197 +11,11-11-2011,1366053.69,0,64.2,3.297,221.4117517,7.197 +11,18-11-2011,1315091.63,0,66.17,3.308,221.6432852,7.197 +11,25-11-2011,1848953.48,1,70.03,3.236,221.9011185,7.197 +11,02-12-2011,1399322.44,0,56.89,3.172,222.1589519,7.197 +11,09-12-2011,1646655.94,0,50.63,3.158,222.4167852,7.197 +11,16-12-2011,1783910.06,0,59.69,3.159,222.6426418,7.197 +11,23-12-2011,2213518.5,0,54.29,3.112,222.8258628,7.197 +11,30-12-2011,1352084.21,1,48.86,3.129,223.0090839,7.197 +11,06-01-2012,1283885.55,0,54.44,3.157,223.1923049,6.833 +11,13-01-2012,1264736.59,0,53.1,3.261,223.3755259,6.833 +11,20-01-2012,1207303.29,0,56.43,3.268,223.4700552,6.833 +11,27-01-2012,1162675.85,0,58.36,3.29,223.5645845,6.833 +11,03-02-2012,1376732.18,0,60.24,3.36,223.6591137,6.833 +11,10-02-2012,1574287.76,1,52.23,3.409,223.753643,6.833 +11,17-02-2012,1569607.94,0,52.77,3.51,223.9170153,6.833 +11,24-02-2012,1379473.03,0,61.11,3.555,224.1320199,6.833 +11,02-03-2012,1438383.44,0,62.61,3.63,224.3470245,6.833 +11,09-03-2012,1413382.76,0,61.44,3.669,224.5620291,6.833 +11,16-03-2012,1441884.28,0,64.21,3.734,224.7166953,6.833 +11,23-03-2012,1300593.61,0,67.16,3.787,224.7909104,6.833 +11,30-03-2012,1300104.03,0,70.23,3.845,224.8651254,6.833 +11,06-04-2012,1596325.01,0,74.19,3.891,224.9393405,6.664 +11,13-04-2012,1472752.01,0,72.74,3.891,225.0135556,6.664 +11,20-04-2012,1315356.99,0,71.97,3.877,225.0689541,6.664 +11,27-04-2012,1236238.29,0,73.4,3.814,225.1243526,6.664 +11,04-05-2012,1370251.22,0,79.07,3.749,225.1797511,6.664 +11,11-05-2012,1300147.07,0,75.13,3.688,225.2351496,6.664 +11,18-05-2012,1352442.31,0,72.53,3.63,225.2512024,6.664 +11,25-05-2012,1297335.87,0,78.44,3.561,225.2515168,6.664 +11,01-06-2012,1361595.33,0,81.67,3.501,225.2518313,6.664 +11,08-06-2012,1414343.53,0,82.1,3.452,225.2521458,6.664 +11,15-06-2012,1417875.42,0,84.97,3.393,225.2644795,6.664 +11,22-06-2012,1355680.3,0,83.26,3.346,225.3068615,6.664 +11,29-06-2012,1297028.6,0,87.86,3.286,225.3492435,6.664 +11,06-07-2012,1461129.94,0,83.44,3.227,225.3916254,6.334 +11,13-07-2012,1320239.51,0,82.46,3.256,225.4340074,6.334 +11,20-07-2012,1344483.81,0,82.41,3.311,225.4438827,6.334 +11,27-07-2012,1272395.02,0,85.43,3.407,225.4537579,6.334 +11,03-08-2012,1399341.07,0,86.94,3.417,225.4636332,6.334 +11,10-08-2012,1388973.65,0,86.21,3.494,225.4735085,6.334 +11,17-08-2012,1421307.2,0,87.73,3.571,225.5558664,6.334 +11,24-08-2012,1409515.73,0,83.17,3.62,225.6925864,6.334 +11,31-08-2012,1372872.35,0,86.49,3.638,225.8293063,6.334 +11,07-09-2012,1304584.4,1,85.17,3.73,225.9660263,6.334 +11,14-09-2012,1267675.05,0,79.61,3.717,226.1122067,6.334 +11,21-09-2012,1326132.98,0,73.64,3.721,226.3151496,6.334 +11,28-09-2012,1227430.73,0,77.67,3.666,226.5180926,6.334 +11,05-10-2012,1422794.26,0,73.37,3.617,226.7210356,6.034 +11,12-10-2012,1311965.09,0,69.94,3.601,226.9239785,6.034 +11,19-10-2012,1232073.18,0,73.77,3.594,226.9688442,6.034 +11,26-10-2012,1200729.45,0,74.26,3.506,226.9873637,6.034 +12,05-02-2010,1100046.37,0,49.47,2.962,126.4420645,13.975 +12,12-02-2010,1117863.33,1,47.87,2.946,126.4962581,13.975 +12,19-02-2010,1095421.65,0,54.83,2.915,126.5262857,13.975 +12,26-02-2010,1048617.17,0,50.23,2.825,126.5522857,13.975 +12,05-03-2010,1077018.27,0,53.77,2.987,126.5782857,13.975 +12,12-03-2010,985594.23,0,50.11,2.925,126.6042857,13.975 +12,19-03-2010,972088.34,0,59.57,3.054,126.6066452,13.975 +12,26-03-2010,981615.81,0,60.06,3.083,126.6050645,13.975 +12,02-04-2010,1011822.3,0,59.84,3.086,126.6034839,14.099 +12,09-04-2010,1041238.87,0,59.25,3.09,126.6019032,14.099 +12,16-04-2010,957997.52,0,64.95,3.109,126.5621,14.099 +12,23-04-2010,993833.44,0,64.55,3.05,126.4713333,14.099 +12,30-04-2010,954220.22,0,67.38,3.105,126.3805667,14.099 +12,07-05-2010,1043240.27,0,70.15,3.127,126.2898,14.099 +12,14-05-2010,966054.97,0,68.44,3.145,126.2085484,14.099 +12,21-05-2010,958374.56,0,76.2,3.12,126.1843871,14.099 +12,28-05-2010,955451.16,0,67.84,3.058,126.1602258,14.099 +12,04-06-2010,1049357.36,0,81.39,2.941,126.1360645,14.099 +12,11-06-2010,1016039.71,0,90.84,2.949,126.1119032,14.099 +12,18-06-2010,956211.2,0,81.06,3.043,126.114,14.099 +12,25-06-2010,958007.69,0,87.27,3.084,126.1266,14.099 +12,02-07-2010,951957.31,0,91.98,3.105,126.1392,14.18 +12,09-07-2010,943506.28,0,90.37,3.1,126.1518,14.18 +12,16-07-2010,916402.76,0,97.18,3.094,126.1498065,14.18 +12,23-07-2010,912403.67,0,99.22,3.112,126.1283548,14.18 +12,30-07-2010,913548.25,0,96.31,3.017,126.1069032,14.18 +12,06-08-2010,967576.95,0,92.95,3.123,126.0854516,14.18 +12,13-08-2010,928264.4,0,87.01,3.159,126.064,14.18 +12,20-08-2010,948447.34,0,92.81,3.041,126.0766452,14.18 +12,27-08-2010,1004516.46,0,93.19,3.129,126.0892903,14.18 +12,03-09-2010,1075758.55,0,83.12,3.087,126.1019355,14.18 +12,10-09-2010,903119.03,1,83.63,3.044,126.1145806,14.18 +12,17-09-2010,852882.61,0,82.45,3.028,126.1454667,14.18 +12,24-09-2010,851919.34,0,81.77,2.939,126.1900333,14.18 +12,01-10-2010,850936.26,0,85.2,3.001,126.2346,14.313 +12,08-10-2010,918335.68,0,71.82,3.013,126.2791667,14.313 +12,15-10-2010,862419.84,0,75,2.976,126.3266774,14.313 +12,22-10-2010,857883.46,0,68.85,3.014,126.3815484,14.313 +12,29-10-2010,955294.7,0,61.09,3.016,126.4364194,14.313 +12,05-11-2010,929690.71,0,65.49,3.129,126.4912903,14.313 +12,12-11-2010,942475.24,0,57.79,3.13,126.5461613,14.313 +12,19-11-2010,894493.7,0,58.18,3.161,126.6072,14.313 +12,26-11-2010,1601377.41,1,47.66,3.162,126.6692667,14.313 +12,03-12-2010,1069533.17,0,43.33,3.041,126.7313333,14.313 +12,10-12-2010,1121934.15,0,50.01,3.203,126.7934,14.313 +12,17-12-2010,1295605.35,0,52.77,3.236,126.8794839,14.313 +12,24-12-2010,1768249.89,0,52.02,3.236,126.9835806,14.313 +12,31-12-2010,891736.91,1,45.64,3.148,127.0876774,14.313 +12,07-01-2011,910110.24,0,37.64,3.287,127.1917742,14.021 +12,14-01-2011,812011.8,0,43.15,3.312,127.3009355,14.021 +12,21-01-2011,802105.5,0,53.53,3.223,127.4404839,14.021 +12,28-01-2011,873119.06,0,50.74,3.342,127.5800323,14.021 +12,04-02-2011,1046068.17,0,45.14,3.348,127.7195806,14.021 +12,11-02-2011,1086421.57,1,51.3,3.381,127.859129,14.021 +12,18-02-2011,1128485.1,0,53.35,3.43,127.99525,14.021 +12,25-02-2011,1046203.72,0,48.45,3.53,128.13,14.021 +12,04-03-2011,1085248.21,0,51.72,3.674,128.26475,14.021 +12,11-03-2011,997672.62,0,57.75,3.818,128.3995,14.021 +12,18-03-2011,1009502.01,0,64.21,3.692,128.5121935,14.021 +12,25-03-2011,954107.32,0,54.4,3.909,128.6160645,14.021 +12,01-04-2011,1005463.49,0,63.63,3.772,128.7199355,13.736 +12,08-04-2011,998362.05,0,64.47,4.003,128.8238065,13.736 +12,15-04-2011,990951.77,0,57.63,3.868,128.9107333,13.736 +12,22-04-2011,1016019.47,0,72.12,4.134,128.9553,13.736 +12,29-04-2011,994966.1,0,68.27,4.151,128.9998667,13.736 +12,06-05-2011,1021154.48,0,68.4,4.193,129.0444333,13.736 +12,13-05-2011,977033.5,0,70.93,4.202,129.089,13.736 +12,20-05-2011,924134.99,0,66.59,4.169,129.0756774,13.736 +12,27-05-2011,964332.51,0,76.67,4.087,129.0623548,13.736 +12,03-06-2011,970328.68,0,71.81,4.031,129.0490323,13.736 +12,10-06-2011,996937.95,0,78.72,3.981,129.0357097,13.736 +12,17-06-2011,986504.93,0,86.84,3.935,129.0432,13.736 +12,24-06-2011,997282.75,0,88.95,3.898,129.0663,13.736 +12,01-07-2011,961993.34,0,89.85,3.842,129.0894,13.503 +12,08-07-2011,943717.38,0,89.9,3.705,129.1125,13.503 +12,15-07-2011,936001.98,0,88.1,3.692,129.1338387,13.503 +12,22-07-2011,922231.92,0,91.17,3.794,129.1507742,13.503 +12,29-07-2011,890547.07,0,93.29,3.805,129.1677097,13.503 +12,05-08-2011,988712.52,0,90.61,3.803,129.1846452,13.503 +12,12-08-2011,955913.68,0,91.04,3.701,129.2015806,13.503 +12,19-08-2011,966817.24,0,91.74,3.743,129.2405806,13.503 +12,26-08-2011,1017593.47,0,94.61,3.74,129.2832581,13.503 +12,02-09-2011,1052051.45,0,93.66,3.798,129.3259355,13.503 +12,09-09-2011,922850.57,1,88,3.913,129.3686129,13.503 +12,16-09-2011,889290.23,0,76.36,3.918,129.4306,13.503 +12,23-09-2011,871692.74,0,82.95,3.789,129.5183333,13.503 +12,30-09-2011,866401.45,0,83.26,3.877,129.6060667,13.503 +12,07-10-2011,951244.66,0,70.44,3.827,129.6938,12.89 +12,14-10-2011,927600.01,0,67.31,3.805,129.7706452,12.89 +12,21-10-2011,938604.58,0,73.05,3.842,129.7821613,12.89 +12,28-10-2011,990926.38,0,67.41,3.727,129.7936774,12.89 +12,04-11-2011,1051944.79,0,59.77,3.828,129.8051935,12.89 +12,11-11-2011,1095091.53,0,48.76,3.824,129.8167097,12.89 +12,18-11-2011,970641.34,0,54.2,3.813,129.8268333,12.89 +12,25-11-2011,1591920.42,1,53.25,3.622,129.8364,12.89 +12,02-12-2011,1071383.1,0,52.5,3.701,129.8459667,12.89 +12,09-12-2011,1189646.45,0,42.17,3.644,129.8555333,12.89 +12,16-12-2011,1293404.18,0,43.29,3.6,129.8980645,12.89 +12,23-12-2011,1617612.03,0,45.4,3.541,129.9845484,12.89 +12,30-12-2011,1111638.07,1,44.64,3.428,130.0710323,12.89 +12,06-01-2012,945823.65,0,50.43,3.599,130.1575161,12.187 +12,13-01-2012,865467.86,0,48.07,3.657,130.244,12.187 +12,20-01-2012,855922.64,0,46.2,3.66,130.2792258,12.187 +12,27-01-2012,888203.69,0,50.43,3.675,130.3144516,12.187 +12,03-02-2012,1058767.95,0,50.58,3.702,130.3496774,12.187 +12,10-02-2012,1199330.85,1,52.27,3.722,130.3849032,12.187 +12,17-02-2012,1240048.85,0,51.8,3.781,130.4546207,12.187 +12,24-02-2012,1112034.72,0,53.13,3.95,130.5502069,12.187 +12,02-03-2012,1147636.96,0,52.27,4.178,130.6457931,12.187 +12,09-03-2012,1113208.57,0,54.54,4.25,130.7413793,12.187 +12,16-03-2012,1088498.52,0,64.44,4.273,130.8261935,12.187 +12,23-03-2012,1045419.87,0,56.26,4.038,130.8966452,12.187 +12,30-03-2012,1025382.22,0,64.36,4.294,130.9670968,12.187 +12,06-04-2012,1128765.71,0,64.05,4.121,131.0375484,11.627 +12,13-04-2012,1083811.19,0,64.28,4.254,131.108,11.627 +12,20-04-2012,1006486.96,0,66.73,4.222,131.1173333,11.627 +12,27-04-2012,1004252.38,0,77.99,4.193,131.1266667,11.627 +12,04-05-2012,1073433.69,0,76.03,4.171,131.136,11.627 +12,11-05-2012,1041995.22,0,77.27,4.186,131.1453333,11.627 +12,18-05-2012,1020486.05,0,84.51,4.11,131.0983226,11.627 +12,25-05-2012,991514.21,0,83.84,4.293,131.0287742,11.627 +12,01-06-2012,981345.2,0,78.11,4.277,130.9592258,11.627 +12,08-06-2012,1086231.47,0,84.83,4.103,130.8896774,11.627 +12,15-06-2012,1019555.51,0,85.94,4.144,130.8295333,11.627 +12,22-06-2012,981386.25,0,91.61,4.014,130.7929,11.627 +12,29-06-2012,943124.74,0,90.47,3.875,130.7562667,11.627 +12,06-07-2012,1014898.78,0,89.13,3.765,130.7196333,10.926 +12,13-07-2012,960312.75,0,95.61,3.723,130.683,10.926 +12,20-07-2012,941550.34,0,85.53,3.726,130.7012903,10.926 +12,27-07-2012,916967.92,0,93.47,3.769,130.7195806,10.926 +12,03-08-2012,958667.23,0,88.16,3.76,130.737871,10.926 +12,10-08-2012,984689.9,0,95.91,3.811,130.7561613,10.926 +12,17-08-2012,1005003.12,0,94.87,4.002,130.7909677,10.926 +12,24-08-2012,1048101.39,0,85.32,4.055,130.8381613,10.926 +12,31-08-2012,1061943.49,0,89.78,4.093,130.8853548,10.926 +12,07-09-2012,955146.04,1,88.52,4.124,130.9325484,10.926 +12,14-09-2012,885892.37,0,83.64,4.133,130.9776667,10.926 +12,21-09-2012,922735.37,0,82.97,4.125,131.0103333,10.926 +12,28-09-2012,880415.67,0,81.22,3.966,131.043,10.926 +12,05-10-2012,979825.92,0,81.61,3.966,131.0756667,10.199 +12,12-10-2012,934917.47,0,71.74,4.468,131.1083333,10.199 +12,19-10-2012,960945.43,0,68.66,4.449,131.1499677,10.199 +12,26-10-2012,974697.6,0,65.95,4.301,131.1930968,10.199 +13,05-02-2010,1967220.53,0,31.53,2.666,126.4420645,8.316 +13,12-02-2010,2030933.46,1,33.16,2.671,126.4962581,8.316 +13,19-02-2010,1970274.64,0,35.7,2.654,126.5262857,8.316 +13,26-02-2010,1817850.32,0,29.98,2.667,126.5522857,8.316 +13,05-03-2010,1939980.43,0,40.65,2.681,126.5782857,8.316 +13,12-03-2010,1840686.94,0,37.62,2.733,126.6042857,8.316 +13,19-03-2010,1879794.89,0,42.49,2.782,126.6066452,8.316 +13,26-03-2010,1882095.98,0,41.48,2.819,126.6050645,8.316 +13,02-04-2010,2142482.14,0,42.15,2.842,126.6034839,8.107 +13,09-04-2010,1898321.33,0,38.97,2.877,126.6019032,8.107 +13,16-04-2010,1819660.44,0,50.39,2.915,126.5621,8.107 +13,23-04-2010,1909330.77,0,55.66,2.936,126.4713333,8.107 +13,30-04-2010,1785823.37,0,48.33,2.941,126.3805667,8.107 +13,07-05-2010,2005478.46,0,44.42,2.948,126.2898,8.107 +13,14-05-2010,1890273.44,0,50.15,2.962,126.2085484,8.107 +13,21-05-2010,1853657.6,0,57.71,2.95,126.1843871,8.107 +13,28-05-2010,1877358.86,0,53.11,2.908,126.1602258,8.107 +13,04-06-2010,2022705.22,0,59.85,2.871,126.1360645,8.107 +13,11-06-2010,2037880.96,0,65.24,2.841,126.1119032,8.107 +13,18-06-2010,2003435.31,0,58.41,2.819,126.114,8.107 +13,25-06-2010,1970340.25,0,71.83,2.82,126.1266,8.107 +13,02-07-2010,2018314.71,0,78.82,2.814,126.1392,7.951 +13,09-07-2010,1870843.9,0,71.33,2.802,126.1518,7.951 +13,16-07-2010,1932231.05,0,77.79,2.791,126.1498065,7.951 +13,23-07-2010,1907351.2,0,82.27,2.797,126.1283548,7.951 +13,30-07-2010,1817887.23,0,78.94,2.797,126.1069032,7.951 +13,06-08-2010,1969121.45,0,81.24,2.802,126.0854516,7.951 +13,13-08-2010,1877592.55,0,74.93,2.837,126.064,7.951 +13,20-08-2010,1997397.63,0,76.34,2.85,126.0766452,7.951 +13,27-08-2010,1908278.27,0,75.31,2.854,126.0892903,7.951 +13,03-09-2010,1911852.58,0,65.71,2.868,126.1019355,7.951 +13,10-09-2010,1772143.94,1,65.74,2.87,126.1145806,7.951 +13,17-09-2010,1790279.74,0,66.84,2.875,126.1454667,7.951 +13,24-09-2010,1705655.09,0,68.22,2.872,126.1900333,7.951 +13,01-10-2010,1765584.48,0,68.74,2.853,126.2346,7.795 +13,08-10-2010,1871924.07,0,63.03,2.841,126.2791667,7.795 +13,15-10-2010,1851431.06,0,54.12,2.845,126.3266774,7.795 +13,22-10-2010,1796949.59,0,56.89,2.849,126.3815484,7.795 +13,29-10-2010,1887895.07,0,45.12,2.841,126.4364194,7.795 +13,05-11-2010,1854967.66,0,49.96,2.831,126.4912903,7.795 +13,12-11-2010,1939964.63,0,42.55,2.831,126.5461613,7.795 +13,19-11-2010,1925393.91,0,42,2.842,126.6072,7.795 +13,26-11-2010,2766400.05,1,28.22,2.83,126.6692667,7.795 +13,03-12-2010,2083379.89,0,25.8,2.812,126.7313333,7.795 +13,10-12-2010,2461468.35,0,36.78,2.817,126.7934,7.795 +13,17-12-2010,2771646.81,0,35.21,2.842,126.8794839,7.795 +13,24-12-2010,3595903.2,0,34.9,2.846,126.9835806,7.795 +13,31-12-2010,1675292,1,26.79,2.868,127.0876774,7.795 +13,07-01-2011,1744544.39,0,16.94,2.891,127.1917742,7.47 +13,14-01-2011,1682316.31,0,20.6,2.903,127.3009355,7.47 +13,21-01-2011,1770177.37,0,34.8,2.934,127.4404839,7.47 +13,28-01-2011,1633663.12,0,31.64,2.96,127.5800323,7.47 +13,04-02-2011,1848186.58,0,23.35,2.974,127.7195806,7.47 +13,11-02-2011,1944438.9,1,30.83,3.034,127.859129,7.47 +13,18-02-2011,2003480.59,0,40.85,3.062,127.99525,7.47 +13,25-02-2011,1831933.95,0,33.17,3.12,128.13,7.47 +13,04-03-2011,1894960.68,0,34.23,3.23,128.26475,7.47 +13,11-03-2011,1852432.58,0,41.28,3.346,128.3995,7.47 +13,18-03-2011,1852443.78,0,44.69,3.407,128.5121935,7.47 +13,25-03-2011,1807545.43,0,42.38,3.435,128.6160645,7.47 +13,01-04-2011,1864238.64,0,42.49,3.487,128.7199355,7.193 +13,08-04-2011,1887465.04,0,42.75,3.547,128.8238065,7.193 +13,15-04-2011,1950994.04,0,41.72,3.616,128.9107333,7.193 +13,22-04-2011,2124316.34,0,47.55,3.655,128.9553,7.193 +13,29-04-2011,1895583.12,0,43.85,3.683,128.9998667,7.193 +13,06-05-2011,1986380.4,0,47.75,3.744,129.0444333,7.193 +13,13-05-2011,1958823.56,0,52.4,3.77,129.089,7.193 +13,20-05-2011,1860923.55,0,52.12,3.802,129.0756774,7.193 +13,27-05-2011,1866369.93,0,54.62,3.778,129.0623548,7.193 +13,03-06-2011,1935593.87,0,52.76,3.752,129.0490323,7.193 +13,10-06-2011,1997816.98,0,61.39,3.732,129.0357097,7.193 +13,17-06-2011,2086433.49,0,63.35,3.704,129.0432,7.193 +13,24-06-2011,2009163.08,0,66.38,3.668,129.0663,7.193 +13,01-07-2011,2048035.74,0,74.29,3.613,129.0894,6.877 +13,08-07-2011,2021699.38,0,77.3,3.563,129.1125,6.877 +13,15-07-2011,1956813.31,0,75.59,3.553,129.1338387,6.877 +13,22-07-2011,1987089.36,0,78.5,3.563,129.1507742,6.877 +13,29-07-2011,1880785.69,0,77.62,3.574,129.1677097,6.877 +13,05-08-2011,2076231.8,0,75.56,3.595,129.1846452,6.877 +13,12-08-2011,1970341.38,0,75.95,3.606,129.2015806,6.877 +13,19-08-2011,2090340.98,0,76.68,3.578,129.2405806,6.877 +13,26-08-2011,2035244.54,0,81.53,3.57,129.2832581,6.877 +13,02-09-2011,1953628.82,0,77,3.58,129.3259355,6.877 +13,09-09-2011,1872921.31,1,70.19,3.619,129.3686129,6.877 +13,16-09-2011,1923223.82,0,67.54,3.641,129.4306,6.877 +13,23-09-2011,1847430.96,0,63.6,3.648,129.5183333,6.877 +13,30-09-2011,1835662.69,0,68.28,3.623,129.6060667,6.877 +13,07-10-2011,2067232.56,0,60.62,3.592,129.6938,6.392 +13,14-10-2011,1929659.07,0,51.74,3.567,129.7706452,6.392 +13,21-10-2011,1973544.27,0,54.66,3.579,129.7821613,6.392 +13,28-10-2011,1948733.81,0,47.41,3.567,129.7936774,6.392 +13,04-11-2011,2036317.54,0,43.51,3.538,129.8051935,6.392 +13,11-11-2011,2111592.09,0,33.8,3.513,129.8167097,6.392 +13,18-11-2011,2016323.51,0,40.65,3.489,129.8268333,6.392 +13,25-11-2011,2864170.61,1,38.89,3.445,129.8364,6.392 +13,02-12-2011,2051315.66,0,33.94,3.389,129.8459667,6.392 +13,09-12-2011,2462779.06,0,24.82,3.341,129.8555333,6.392 +13,16-12-2011,2760346.71,0,27.85,3.282,129.8980645,6.392 +13,23-12-2011,3556766.03,0,24.76,3.186,129.9845484,6.392 +13,30-12-2011,1969056.91,1,31.53,3.119,130.0710323,6.392 +13,06-01-2012,1865752.78,0,33.8,3.08,130.1575161,6.104 +13,13-01-2012,1794962.64,0,25.61,3.056,130.244,6.104 +13,20-01-2012,1811606.21,0,32.71,3.047,130.2792258,6.104 +13,27-01-2012,1733983.09,0,34.32,3.058,130.3144516,6.104 +13,03-02-2012,1927780.74,0,31.39,3.077,130.3496774,6.104 +13,10-02-2012,2069284.57,1,33.73,3.116,130.3849032,6.104 +13,17-02-2012,2214477.06,0,36.57,3.119,130.4546207,6.104 +13,24-02-2012,1929768.03,0,35.38,3.145,130.5502069,6.104 +13,02-03-2012,1969742.76,0,32.36,3.242,130.6457931,6.104 +13,09-03-2012,1986445.65,0,38.24,3.38,130.7413793,6.104 +13,16-03-2012,2025582.62,0,52.5,3.529,130.8261935,6.104 +13,23-03-2012,1904421.74,0,47.83,3.671,130.8966452,6.104 +13,30-03-2012,1948982.7,0,53.2,3.734,130.9670968,6.104 +13,06-04-2012,2271614.76,0,48.85,3.793,131.0375484,5.965 +13,13-04-2012,2057637.86,0,51.7,3.833,131.108,5.965 +13,20-04-2012,1955689.12,0,50.24,3.845,131.1173333,5.965 +13,27-04-2012,1970121.65,0,64.8,3.842,131.1266667,5.965 +13,04-05-2012,1995994.51,0,54.41,3.831,131.136,5.965 +13,11-05-2012,2080764.17,0,56.47,3.809,131.1453333,5.965 +13,18-05-2012,2131900.55,0,65.17,3.808,131.0983226,5.965 +13,25-05-2012,2043349.41,0,62.39,3.801,131.0287742,5.965 +13,01-06-2012,2035431.39,0,61.11,3.788,130.9592258,5.965 +13,08-06-2012,2182437.9,0,68.4,3.776,130.8896774,5.965 +13,15-06-2012,2152229.11,0,65.97,3.756,130.8295333,5.965 +13,22-06-2012,2094373,0,72.89,3.737,130.7929,5.965 +13,29-06-2012,2037663.71,0,82,3.681,130.7562667,5.965 +13,06-07-2012,2184980.35,0,79.23,3.63,130.7196333,5.765 +13,13-07-2012,2002750.99,0,83.68,3.595,130.683,5.765 +13,20-07-2012,2053089.32,0,75.69,3.556,130.7012903,5.765 +13,27-07-2012,1914430.53,0,80.42,3.537,130.7195806,5.765 +13,03-08-2012,2044148.23,0,81.99,3.512,130.737871,5.765 +13,10-08-2012,2041019.92,0,81.69,3.509,130.7561613,5.765 +13,17-08-2012,2095769.18,0,79.4,3.545,130.7909677,5.765 +13,24-08-2012,2059458.25,0,77.37,3.582,130.8381613,5.765 +13,31-08-2012,2073855.42,0,79.18,3.624,130.8853548,5.765 +13,07-09-2012,2165796.31,1,70.65,3.689,130.9325484,5.765 +13,14-09-2012,1919917.03,0,68.55,3.749,130.9776667,5.765 +13,21-09-2012,1938379.66,0,67.96,3.821,131.0103333,5.765 +13,28-09-2012,1927664.11,0,64.8,3.821,131.043,5.765 +13,05-10-2012,2041918.74,0,61.79,3.815,131.0756667,5.621 +13,12-10-2012,1999079.44,0,55.1,3.797,131.1083333,5.621 +13,19-10-2012,2018010.15,0,52.06,3.781,131.1499677,5.621 +13,26-10-2012,2035189.66,0,46.97,3.755,131.1930968,5.621 +14,05-02-2010,2623469.95,0,27.31,2.784,181.8711898,8.992 +14,12-02-2010,1704218.84,1,27.73,2.773,181.982317,8.992 +14,19-02-2010,2204556.7,0,31.27,2.745,182.0347816,8.992 +14,26-02-2010,2095591.63,0,34.89,2.754,182.0774691,8.992 +14,05-03-2010,2237544.75,0,37.13,2.777,182.1201566,8.992 +14,12-03-2010,2156035.06,0,45.8,2.818,182.1628441,8.992 +14,19-03-2010,2066219.3,0,48.79,2.844,182.0779857,8.992 +14,26-03-2010,2050396.27,0,54.36,2.854,181.9718697,8.992 +14,02-04-2010,2495630.51,0,47.74,2.85,181.8657537,8.899 +14,09-04-2010,2258781.28,0,65.45,2.869,181.7596377,8.899 +14,16-04-2010,2121788.61,0,54.28,2.899,181.6924769,8.899 +14,23-04-2010,2138144.91,0,53.47,2.902,181.6772564,8.899 +14,30-04-2010,2082355.12,0,53.15,2.921,181.6620359,8.899 +14,07-05-2010,2370116.52,0,70.75,2.966,181.6468154,8.899 +14,14-05-2010,2129771.13,0,54.26,2.982,181.6612792,8.899 +14,21-05-2010,2108187.1,0,62.62,2.958,181.8538486,8.899 +14,28-05-2010,2227152.16,0,69.27,2.899,182.0464181,8.899 +14,04-06-2010,2363601.47,0,75.93,2.847,182.2389876,8.899 +14,11-06-2010,2249570.04,0,69.71,2.809,182.4315571,8.899 +14,18-06-2010,2248645.59,0,72.62,2.78,182.4424199,8.899 +14,25-06-2010,2246179.91,0,79.32,2.808,182.3806,8.899 +14,02-07-2010,2334788.42,0,76.61,2.815,182.3187801,8.743 +14,09-07-2010,2236209.13,0,82.45,2.793,182.2569603,8.743 +14,16-07-2010,2130287.27,0,77.84,2.783,182.2604411,8.743 +14,23-07-2010,2044155.39,0,81.46,2.771,182.3509895,8.743 +14,30-07-2010,2054843.28,0,79.78,2.781,182.4415378,8.743 +14,06-08-2010,2219813.5,0,77.17,2.784,182.5320862,8.743 +14,13-08-2010,2052984.81,0,78.44,2.805,182.6226346,8.743 +14,20-08-2010,2057138.31,0,76.01,2.779,182.6165205,8.743 +14,27-08-2010,2020332.07,0,71.36,2.755,182.6104063,8.743 +14,03-09-2010,2182563.66,0,78.37,2.715,182.6042922,8.743 +14,10-09-2010,2191767.76,1,70.87,2.699,182.598178,8.743 +14,17-09-2010,1953539.85,0,66.55,2.706,182.622509,8.743 +14,24-09-2010,1879891.13,0,68.59,2.713,182.6696737,8.743 +14,01-10-2010,1855703.66,0,70.58,2.707,182.7168385,8.724 +14,08-10-2010,2091663.2,0,56.49,2.764,182.7640032,8.724 +14,15-10-2010,1932162.63,0,58.61,2.868,182.8106203,8.724 +14,22-10-2010,1936621.09,0,53.15,2.917,182.8558685,8.724 +14,29-10-2010,1984768.34,0,61.3,2.921,182.9011166,8.724 +14,05-11-2010,2078417.47,0,45.65,2.917,182.9463648,8.724 +14,12-11-2010,2092189.06,0,46.14,2.931,182.9916129,8.724 +14,19-11-2010,1968462.58,0,50.02,3,182.8989385,8.724 +14,26-11-2010,2921709.71,1,46.15,3.039,182.7832769,8.724 +14,03-12-2010,2258489.63,0,40.93,3.046,182.6676154,8.724 +14,10-12-2010,2600519.26,0,30.54,3.109,182.5519538,8.724 +14,17-12-2010,2762861.41,0,30.51,3.14,182.517732,8.724 +14,24-12-2010,3818686.45,0,30.59,3.141,182.54459,8.724 +14,31-12-2010,1623716.46,1,29.67,3.179,182.5714479,8.724 +14,07-01-2011,1864746.1,0,34.32,3.193,182.5983058,8.549 +14,14-01-2011,1699095.9,0,24.78,3.205,182.6585782,8.549 +14,21-01-2011,1743188.87,0,30.55,3.229,182.9193368,8.549 +14,28-01-2011,1613718.38,0,24.05,3.237,183.1800955,8.549 +14,04-02-2011,1995891.87,0,28.73,3.231,183.4408542,8.549 +14,11-02-2011,1980405.03,1,30.3,3.239,183.7016129,8.549 +14,18-02-2011,2019031.67,0,40.7,3.245,183.9371353,8.549 +14,25-02-2011,1875708.88,0,35.78,3.274,184.1625632,8.549 +14,04-03-2011,2041215.61,0,38.65,3.433,184.3879911,8.549 +14,11-03-2011,1931104.67,0,45.01,3.582,184.613419,8.549 +14,18-03-2011,1932491.42,0,46.66,3.631,184.809719,8.549 +14,25-03-2011,1879451.23,0,41.76,3.625,184.9943679,8.549 +14,01-04-2011,1869110.55,0,37.27,3.638,185.1790167,8.521 +14,08-04-2011,2037798.88,0,48.71,3.72,185.3636656,8.521 +14,15-04-2011,1974960.86,0,53.69,3.821,185.5339821,8.521 +14,22-04-2011,2256461.39,0,53.04,3.892,185.6684673,8.521 +14,29-04-2011,1930617.64,0,66.18,3.962,185.8029526,8.521 +14,06-05-2011,2095599.93,0,58.21,4.046,185.9374378,8.521 +14,13-05-2011,2004330.3,0,60.38,4.066,186.0719231,8.521 +14,20-05-2011,1959967.8,0,62.28,4.062,185.9661154,8.521 +14,27-05-2011,2080694.24,0,69.7,3.985,185.8603077,8.521 +14,03-06-2011,2079899.47,0,76.38,3.922,185.7545,8.521 +14,10-06-2011,2132446,0,73.88,3.881,185.6486923,8.521 +14,17-06-2011,2082083.34,0,69.32,3.842,185.6719333,8.521 +14,24-06-2011,2069523.52,0,74.85,3.804,185.7919609,8.521 +14,01-07-2011,2074668.19,0,74.04,3.748,185.9119885,8.625 +14,08-07-2011,2063401.06,0,77.49,3.711,186.032016,8.625 +14,15-07-2011,1953544.76,0,78.47,3.76,186.1399808,8.625 +14,22-07-2011,1882070.88,0,82.33,3.811,186.2177885,8.625 +14,29-07-2011,1871021.01,0,81.31,3.829,186.2955962,8.625 +14,05-08-2011,2066020.69,0,78.22,3.842,186.3734038,8.625 +14,12-08-2011,1928773.82,0,77,3.812,186.4512115,8.625 +14,19-08-2011,1896873.99,0,72.98,3.747,186.5093071,8.625 +14,26-08-2011,2273470.62,0,72.55,3.704,186.5641172,8.625 +14,02-09-2011,1750891.47,0,70.63,3.703,186.6189274,8.625 +14,09-09-2011,2202742.9,1,71.48,3.738,186.6737376,8.625 +14,16-09-2011,1864637.89,0,69.17,3.742,186.8024,8.625 +14,23-09-2011,1871555.64,0,63.75,3.711,187.0295321,8.625 +14,30-09-2011,1809989.29,0,70.66,3.645,187.2566641,8.625 +14,07-10-2011,2078796.76,0,55.82,3.583,187.4837962,8.523 +14,14-10-2011,1890870.75,0,63.82,3.541,187.6917481,8.523 +14,21-10-2011,2009004.59,0,59.6,3.57,187.7846197,8.523 +14,28-10-2011,2056846.12,0,51.78,3.569,187.8774913,8.523 +14,04-11-2011,2174056.71,0,43.92,3.551,187.9703629,8.523 +14,11-11-2011,2081534.65,0,47.65,3.53,188.0632345,8.523 +14,18-11-2011,1969360.72,0,51.34,3.53,188.1983654,8.523 +14,25-11-2011,2685351.81,1,48.71,3.492,188.3504,8.523 +14,02-12-2011,2143080.57,0,50.19,3.452,188.5024346,8.523 +14,09-12-2011,2470581.29,0,46.57,3.415,188.6544692,8.523 +14,16-12-2011,2594363.09,0,39.93,3.413,188.7979349,8.523 +14,23-12-2011,3369068.99,0,42.27,3.389,188.9299752,8.523 +14,30-12-2011,1914148.89,1,37.79,3.389,189.0620155,8.523 +14,06-01-2012,1859144.96,0,35.88,3.422,189.1940558,8.424 +14,13-01-2012,1696248.27,0,41.18,3.513,189.3260962,8.424 +14,20-01-2012,1789113.32,0,31.85,3.533,189.4214733,8.424 +14,27-01-2012,1595362.27,0,37.93,3.567,189.5168505,8.424 +14,03-02-2012,1877410.36,0,42.96,3.617,189.6122277,8.424 +14,10-02-2012,2077256.24,1,37,3.64,189.7076048,8.424 +14,17-02-2012,2020550.99,0,36.85,3.695,189.8424834,8.424 +14,24-02-2012,1875040.16,0,42.86,3.739,190.0069881,8.424 +14,02-03-2012,1926004.99,0,41.55,3.816,190.1714927,8.424 +14,09-03-2012,2020839.31,0,45.52,3.848,190.3359973,8.424 +14,16-03-2012,1941040.5,0,50.56,3.862,190.4618964,8.424 +14,23-03-2012,1893447.71,0,59.45,3.9,190.5363213,8.424 +14,30-03-2012,1905033.01,0,50.04,3.953,190.6107463,8.424 +14,06-04-2012,2376022.26,0,49.73,3.996,190.6851712,8.567 +14,13-04-2012,1912909.69,0,51.83,4.044,190.7595962,8.567 +14,20-04-2012,1875686.44,0,63.13,4.027,190.8138013,8.567 +14,27-04-2012,1784029.95,0,53.2,4.004,190.8680064,8.567 +14,04-05-2012,1949354.29,0,55.21,3.951,190.9222115,8.567 +14,11-05-2012,1987531.05,0,61.24,3.889,190.9764167,8.567 +14,18-05-2012,1932233.17,0,66.3,3.848,190.9964479,8.567 +14,25-05-2012,2030869.61,0,67.21,3.798,191.0028096,8.567 +14,01-06-2012,2049485.49,0,74.48,3.742,191.0091712,8.567 +14,08-06-2012,2099615.88,0,64.3,3.689,191.0155329,8.567 +14,15-06-2012,1905733.68,0,71.93,3.62,191.0299731,8.567 +14,22-06-2012,1660228.88,0,74.22,3.564,191.0646096,8.567 +14,29-06-2012,1591835.02,0,75.22,3.506,191.0992462,8.567 +14,06-07-2012,1862128.95,0,82.99,3.475,191.1338827,8.684 +14,13-07-2012,1544422.35,0,79.97,3.523,191.1685192,8.684 +14,20-07-2012,1553250.16,0,78.89,3.567,191.1670428,8.684 +14,27-07-2012,1479514.66,0,77.2,3.647,191.1655664,8.684 +14,03-08-2012,1656886.46,0,76.58,3.654,191.16409,8.684 +14,10-08-2012,1648570.03,0,78.65,3.722,191.1626135,8.684 +14,17-08-2012,1660433.3,0,75.71,3.807,191.2284919,8.684 +14,24-08-2012,1621841.33,0,72.62,3.834,191.3448865,8.684 +14,31-08-2012,1613342.19,0,75.09,3.867,191.461281,8.684 +14,07-09-2012,1904512.34,1,75.7,3.911,191.5776756,8.684 +14,14-09-2012,1554794.22,0,67.87,3.948,191.69985,8.684 +14,21-09-2012,1565352.46,0,65.32,4.038,191.8567038,8.684 +14,28-09-2012,1522512.2,0,64.88,3.997,192.0135577,8.684 +14,05-10-2012,1687592.16,0,64.89,3.985,192.1704115,8.667 +14,12-10-2012,1639585.61,0,54.47,4,192.3272654,8.667 +14,19-10-2012,1590274.72,0,56.47,3.969,192.3308542,8.667 +14,26-10-2012,1704357.62,0,58.85,3.882,192.3088989,8.667 +15,05-02-2010,652122.44,0,19.83,2.954,131.5279032,8.35 +15,12-02-2010,682447.1,1,22,2.94,131.5866129,8.35 +15,19-02-2010,660838.75,0,27.54,2.909,131.637,8.35 +15,26-02-2010,564883.2,0,29.87,2.91,131.686,8.35 +15,05-03-2010,605325.43,0,31.79,2.919,131.735,8.35 +15,12-03-2010,604173.59,0,41.39,2.938,131.784,8.35 +15,19-03-2010,593710.67,0,44.69,2.96,131.8242903,8.35 +15,26-03-2010,592111.49,0,39.53,2.963,131.863129,8.35 +15,02-04-2010,718470.71,0,45.27,2.957,131.9019677,8.185 +15,09-04-2010,634605.77,0,57.77,2.992,131.9408065,8.185 +15,16-04-2010,641208.65,0,49.63,3.01,131.9809,8.185 +15,23-04-2010,643097.6,0,46.54,3.021,132.0226667,8.185 +15,30-04-2010,570791.11,0,49.09,3.042,132.0644333,8.185 +15,07-05-2010,661348.88,0,63.16,3.095,132.1062,8.185 +15,14-05-2010,594385.2,0,47.13,3.112,132.152129,8.185 +15,21-05-2010,616598.1,0,59.09,3.096,132.2230323,8.185 +15,28-05-2010,744772.88,0,70.61,3.046,132.2939355,8.185 +15,04-06-2010,693192.5,0,69.99,3.006,132.3648387,8.185 +15,11-06-2010,619337.29,0,61.04,2.972,132.4357419,8.185 +15,18-06-2010,652329.53,0,65.83,2.942,132.4733333,8.185 +15,25-06-2010,672194.03,0,72.79,2.958,132.4976,8.185 +15,02-07-2010,709337.11,0,66.13,2.958,132.5218667,8.099 +15,09-07-2010,691497.62,0,77.33,2.94,132.5461333,8.099 +15,16-07-2010,633203.69,0,72.83,2.933,132.5667742,8.099 +15,23-07-2010,598553.43,0,73.2,2.924,132.5825806,8.099 +15,30-07-2010,619224.06,0,72.04,2.932,132.5983871,8.099 +15,06-08-2010,639651.24,0,72.7,2.942,132.6141935,8.099 +15,13-08-2010,622437.08,0,72.17,2.923,132.63,8.099 +15,20-08-2010,637090.44,0,71.1,2.913,132.6616129,8.099 +15,27-08-2010,649791.15,0,65.07,2.885,132.6932258,8.099 +15,03-09-2010,638647.21,0,73.17,2.86,132.7248387,8.099 +15,10-09-2010,641965.2,1,62.36,2.837,132.7564516,8.099 +15,17-09-2010,583210.87,0,57.94,2.846,132.7670667,8.099 +15,24-09-2010,548542.47,0,62.53,2.837,132.7619333,8.099 +15,01-10-2010,566945.95,0,59.69,2.84,132.7568,8.067 +15,08-10-2010,591603.79,0,52.19,2.903,132.7516667,8.067 +15,15-10-2010,577011.26,0,49.96,2.999,132.7633548,8.067 +15,22-10-2010,600395.73,0,47.1,3.049,132.8170968,8.067 +15,29-10-2010,598301.5,0,55.09,3.055,132.8708387,8.067 +15,05-11-2010,612987.64,0,40.29,3.049,132.9245806,8.067 +15,12-11-2010,619639.74,0,39.63,3.065,132.9783226,8.067 +15,19-11-2010,608200.81,0,44.1,3.138,132.9172,8.067 +15,26-11-2010,1120018.92,1,40.71,3.186,132.8369333,8.067 +15,03-12-2010,754134.95,0,36,3.2,132.7566667,8.067 +15,10-12-2010,847294.04,0,23.97,3.255,132.6764,8.067 +15,17-12-2010,983825.15,0,25.3,3.301,132.6804516,8.067 +15,24-12-2010,1368318.17,0,25.07,3.309,132.7477419,8.067 +15,31-12-2010,543754.17,1,26.54,3.336,132.8150323,8.067 +15,07-01-2011,509640.77,0,30.53,3.351,132.8823226,7.771 +15,14-01-2011,479424.2,0,19.53,3.367,132.9510645,7.771 +15,21-01-2011,487311.03,0,21.84,3.391,133.0285161,7.771 +15,28-01-2011,481119.6,0,19.61,3.402,133.1059677,7.771 +15,04-02-2011,556550.85,0,20.69,3.4,133.1834194,7.771 +15,11-02-2011,582864.35,1,21.64,3.416,133.260871,7.771 +15,18-02-2011,649993.5,0,33.06,3.42,133.3701429,7.771 +15,25-02-2011,547564.09,0,20.87,3.452,133.4921429,7.771 +15,04-03-2011,573374.49,0,28.16,3.605,133.6141429,7.771 +15,11-03-2011,537035.28,0,34.27,3.752,133.7361429,7.771 +15,18-03-2011,551553.99,0,40.23,3.796,133.8492258,7.771 +15,25-03-2011,527389.28,0,32.63,3.789,133.9587419,7.771 +15,01-04-2011,542556.05,0,30.34,3.811,134.0682581,7.658 +15,08-04-2011,587370.81,0,40.94,3.895,134.1777742,7.658 +15,15-04-2011,607691.36,0,48.63,3.981,134.2784667,7.658 +15,22-04-2011,655318.26,0,41.37,4.061,134.3571,7.658 +15,29-04-2011,560764.41,0,55.46,4.117,134.4357333,7.658 +15,06-05-2011,630522.67,0,49.87,4.192,134.5143667,7.658 +15,13-05-2011,630482.91,0,57.07,4.211,134.593,7.658 +15,20-05-2011,593941.9,0,57.19,4.202,134.6803871,7.658 +15,27-05-2011,636193.24,0,65.87,4.134,134.7677742,7.658 +15,03-06-2011,695396.19,0,69.8,4.069,134.8551613,7.658 +15,10-06-2011,642679.81,0,69.86,4.025,134.9425484,7.658 +15,17-06-2011,639928.85,0,63.9,3.989,135.0837333,7.658 +15,24-06-2011,656594.95,0,69.96,3.964,135.2652667,7.658 +15,01-07-2011,674669.16,0,67.43,3.916,135.4468,7.806 +15,08-07-2011,635118.48,0,73.47,3.886,135.6283333,7.806 +15,15-07-2011,624114.56,0,73.34,3.915,135.7837419,7.806 +15,22-07-2011,607475.44,0,79.97,3.972,135.8738387,7.806 +15,29-07-2011,577511.02,0,74.67,4.004,135.9639355,7.806 +15,05-08-2011,607961.21,0,73.63,4.02,136.0540323,7.806 +15,12-08-2011,590836.37,0,70.63,3.995,136.144129,7.806 +15,19-08-2011,599488.98,0,70.41,3.942,136.183129,7.806 +15,26-08-2011,605413.17,0,69.19,3.906,136.2136129,7.806 +15,02-09-2011,649159.68,0,67.63,3.879,136.2440968,7.806 +15,09-09-2011,607593.51,1,67.59,3.93,136.2745806,7.806 +15,16-09-2011,545052.34,0,62.1,3.937,136.3145,7.806 +15,23-09-2011,545570.86,0,59,3.899,136.367,7.806 +15,30-09-2011,521297.31,0,64.87,3.858,136.4195,7.806 +15,07-10-2011,579068.88,0,51.24,3.775,136.472,7.866 +15,14-10-2011,537300.94,0,61.3,3.744,136.5150968,7.866 +15,21-10-2011,603318.89,0,51.67,3.757,136.5017742,7.866 +15,28-10-2011,589842.69,0,45.54,3.757,136.4884516,7.866 +15,04-11-2011,615121.78,0,43.39,3.738,136.475129,7.866 +15,11-11-2011,618949.82,0,47.13,3.719,136.4618065,7.866 +15,18-11-2011,597856.51,0,46.53,3.717,136.4666667,7.866 +15,25-11-2011,1066478.1,1,41.1,3.689,136.4788,7.866 +15,02-12-2011,699028.66,0,45.67,3.666,136.4909333,7.866 +15,09-12-2011,764565.55,0,38.53,3.627,136.5030667,7.866 +15,16-12-2011,870415.49,0,35.49,3.611,136.5335161,7.866 +15,23-12-2011,1182691.87,0,34.93,3.587,136.5883871,7.866 +15,30-12-2011,603460.79,1,31.44,3.566,136.6432581,7.866 +15,06-01-2012,516087.65,0,30.24,3.585,136.698129,7.943 +15,13-01-2012,454183.42,0,36.26,3.666,136.753,7.943 +15,20-01-2012,492721.85,0,21.39,3.705,136.8564194,7.943 +15,27-01-2012,466045.63,0,30.87,3.737,136.9598387,7.943 +15,03-02-2012,523831.64,0,35.3,3.796,137.0632581,7.943 +15,10-02-2012,628218.22,1,31.91,3.826,137.1666774,7.943 +15,17-02-2012,598502.83,0,30.26,3.874,137.2583103,7.943 +15,24-02-2012,561137.06,0,33.18,3.917,137.3411034,7.943 +15,02-03-2012,541292.64,0,33.24,3.983,137.4238966,7.943 +15,09-03-2012,545120.67,0,36.97,4.021,137.5066897,7.943 +15,16-03-2012,570611.23,0,47.42,4.021,137.5843871,7.943 +15,23-03-2012,565481.88,0,58.92,4.054,137.6552903,7.943 +15,30-03-2012,557547.25,0,42.65,4.098,137.7261935,7.943 +15,06-04-2012,659950.36,0,40.01,4.143,137.7970968,8.15 +15,13-04-2012,558585.13,0,43.52,4.187,137.868,8.15 +15,20-04-2012,534780.57,0,54.47,4.17,137.9230667,8.15 +15,27-04-2012,527402.62,0,41.57,4.163,137.9781333,8.15 +15,04-05-2012,577868.38,0,51.04,4.124,138.0332,8.15 +15,11-05-2012,579539.95,0,54.23,4.055,138.0882667,8.15 +15,18-05-2012,600050.98,0,58.84,4.029,138.1065806,8.15 +15,25-05-2012,693780.42,0,67.97,3.979,138.1101935,8.15 +15,01-06-2012,663971.26,0,67.61,3.915,138.1138065,8.15 +15,08-06-2012,611390.67,0,59.35,3.871,138.1174194,8.15 +15,15-06-2012,636737.65,0,67.7,3.786,138.1295333,8.15 +15,22-06-2012,687085.6,0,74.28,3.722,138.1629,8.15 +15,29-06-2012,624099.48,0,68.91,3.667,138.1962667,8.15 +15,06-07-2012,678024.75,0,74.64,3.646,138.2296333,8.193 +15,13-07-2012,591335.5,0,72.62,3.689,138.263,8.193 +15,20-07-2012,592369.22,0,75.31,3.732,138.2331935,8.193 +15,27-07-2012,571190.83,0,73.9,3.82,138.2033871,8.193 +15,03-08-2012,590739.62,0,73.13,3.819,138.1735806,8.193 +15,10-08-2012,590453.63,0,73.99,3.863,138.1437742,8.193 +15,17-08-2012,579738.2,0,70.29,3.963,138.1857097,8.193 +15,24-08-2012,606210.77,0,66.98,3.997,138.2814516,8.193 +15,31-08-2012,610185.32,0,71.42,4.026,138.3771935,8.193 +15,07-09-2012,587259.82,1,71.61,4.076,138.4729355,8.193 +15,14-09-2012,527509.76,0,65.44,4.088,138.5673,8.193 +15,21-09-2012,533161.64,0,60.34,4.203,138.6534,8.193 +15,28-09-2012,553901.97,0,57.13,4.158,138.7395,8.193 +15,05-10-2012,573498.64,0,59.57,4.151,138.8256,7.992 +15,12-10-2012,551799.63,0,49.12,4.186,138.9117,7.992 +15,19-10-2012,555652.77,0,52.89,4.153,138.8336129,7.992 +15,26-10-2012,558473.6,0,55.75,4.071,138.7281613,7.992 +16,05-02-2010,477409.3,0,19.79,2.58,189.3816974,7.039 +16,12-02-2010,472044.28,1,20.87,2.572,189.4642725,7.039 +16,19-02-2010,469868.7,0,21.13,2.55,189.5340998,7.039 +16,26-02-2010,443242.17,0,18.12,2.586,189.6018023,7.039 +16,05-03-2010,444181.85,0,27.92,2.62,189.6695049,7.039 +16,12-03-2010,445393.74,0,28.64,2.684,189.7372075,7.039 +16,19-03-2010,504307.35,0,33.45,2.692,189.734262,7.039 +16,26-03-2010,483177.2,0,29.88,2.717,189.7195417,7.039 +16,02-04-2010,490503.69,0,36.19,2.725,189.7048215,6.842 +16,09-04-2010,424083.99,0,34.21,2.75,189.6901012,6.842 +16,16-04-2010,436312.41,0,45.69,2.765,189.6628845,6.842 +16,23-04-2010,370230.94,0,44.9,2.776,189.6190057,6.842 +16,30-04-2010,383550.93,0,37.75,2.766,189.575127,6.842 +16,07-05-2010,403217.22,0,37.43,2.771,189.5312483,6.842 +16,14-05-2010,401770.9,0,41.26,2.788,189.4904116,6.842 +16,21-05-2010,435300.51,0,47.34,2.776,189.467827,6.842 +16,28-05-2010,479430,0,52.08,2.737,189.4452425,6.842 +16,04-06-2010,516295.81,0,53.76,2.7,189.422658,6.842 +16,11-06-2010,535587.31,0,62.63,2.684,189.4000734,6.842 +16,18-06-2010,540149.85,0,52.4,2.674,189.4185259,6.842 +16,25-06-2010,546554.96,0,62.37,2.715,189.4533931,6.842 +16,02-07-2010,610641.42,0,64.44,2.728,189.4882603,6.868 +16,09-07-2010,614253.33,0,61.79,2.711,189.5231276,6.868 +16,16-07-2010,586583.69,0,67.68,2.699,189.6125456,6.868 +16,23-07-2010,588344.18,0,70.67,2.691,189.774698,6.868 +16,30-07-2010,562633.67,0,70.71,2.69,189.9368504,6.868 +16,06-08-2010,586936.45,0,67.42,2.69,190.0990028,6.868 +16,13-08-2010,543757.97,0,63.91,2.723,190.2611552,6.868 +16,20-08-2010,521516.96,0,63.59,2.732,190.2948237,6.868 +16,27-08-2010,581010.52,0,65.66,2.731,190.3284922,6.868 +16,03-09-2010,542087.89,0,58.02,2.773,190.3621607,6.868 +16,10-09-2010,537518.57,1,57.24,2.78,190.3958293,6.868 +16,17-09-2010,522049.52,0,56.55,2.8,190.4688287,6.868 +16,24-09-2010,511330.32,0,58.19,2.793,190.5713264,6.868 +16,01-10-2010,463977.54,0,59.39,2.759,190.6738241,6.986 +16,08-10-2010,442894.2,0,54.29,2.745,190.7763218,6.986 +16,15-10-2010,452169.28,0,45,2.762,190.8623087,6.986 +16,22-10-2010,541216.92,0,45.85,2.762,190.9070184,6.986 +16,29-10-2010,495022.51,0,35.76,2.748,190.951728,6.986 +16,05-11-2010,446905.02,0,39.94,2.729,190.9964377,6.986 +16,12-11-2010,453632.76,0,34.04,2.737,191.0411474,6.986 +16,19-11-2010,458634.68,0,27.26,2.758,191.0312172,6.986 +16,26-11-2010,651837.77,1,23.46,2.742,191.0121805,6.986 +16,03-12-2010,512260.59,0,23.68,2.712,190.9931437,6.986 +16,10-12-2010,570103.64,0,32.02,2.728,190.9741069,6.986 +16,17-12-2010,648652.01,0,26.01,2.778,191.0303376,6.986 +16,24-12-2010,1004730.69,0,32.46,2.781,191.1430189,6.986 +16,31-12-2010,575317.38,1,19.66,2.829,191.2557002,6.986 +16,07-01-2011,573545.96,0,12.39,2.882,191.3683815,6.614 +16,14-01-2011,470365.59,0,17.46,2.911,191.4784939,6.614 +16,21-01-2011,462888.13,0,28.6,2.973,191.5731924,6.614 +16,28-01-2011,448391.99,0,20.8,3.008,191.667891,6.614 +16,04-02-2011,479263.15,0,13.64,3.011,191.7625895,6.614 +16,11-02-2011,466806.89,1,15.02,3.037,191.8572881,6.614 +16,18-02-2011,491179.79,0,27.18,3.051,191.9178331,6.614 +16,25-02-2011,475201.64,0,26.15,3.101,191.9647167,6.614 +16,04-03-2011,484829.07,0,31.77,3.232,192.0116004,6.614 +16,11-03-2011,457504.35,0,29.36,3.372,192.058484,6.614 +16,18-03-2011,497373.49,0,36.5,3.406,192.1237981,6.614 +16,25-03-2011,465279.68,0,32.61,3.414,192.1964844,6.614 +16,01-04-2011,459756.11,0,35.75,3.461,192.2691707,6.339 +16,08-04-2011,439276.5,0,38.04,3.532,192.3418571,6.339 +16,15-04-2011,427855.24,0,34.59,3.611,192.4225954,6.339 +16,22-04-2011,368600,0,40.74,3.636,192.5234638,6.339 +16,29-04-2011,378100.31,0,37.77,3.663,192.6243322,6.339 +16,06-05-2011,423805.22,0,38.64,3.735,192.7252006,6.339 +16,13-05-2011,410406.95,0,43.29,3.767,192.826069,6.339 +16,20-05-2011,435397.19,0,43.95,3.828,192.831317,6.339 +16,27-05-2011,444718.68,0,45.17,3.795,192.8365651,6.339 +16,03-06-2011,531080.31,0,54.08,3.763,192.8418131,6.339 +16,10-06-2011,600952.06,0,55.78,3.735,192.8470612,6.339 +16,17-06-2011,581546.23,0,58.34,3.697,192.9034759,6.339 +16,24-06-2011,569105.03,0,54.36,3.661,192.9982655,6.339 +16,01-07-2011,608737.56,0,63.59,3.597,193.0930552,6.338 +16,08-07-2011,634634.66,0,65,3.54,193.1878448,6.338 +16,15-07-2011,586841.77,0,65.16,3.532,193.3125484,6.338 +16,22-07-2011,581758.22,0,65.36,3.545,193.5120367,6.338 +16,29-07-2011,582381.95,0,66.84,3.547,193.711525,6.338 +16,05-08-2011,592981.33,0,63.96,3.554,193.9110133,6.338 +16,12-08-2011,563884.47,0,67.09,3.542,194.1105017,6.338 +16,19-08-2011,554630.42,0,68.83,3.499,194.2500634,6.338 +16,26-08-2011,557312.01,0,67.51,3.485,194.3796374,6.338 +16,02-09-2011,580805.33,0,63.44,3.511,194.5092113,6.338 +16,09-09-2011,574622.56,1,56.99,3.566,194.6387853,6.338 +16,16-09-2011,539081.09,0,53.68,3.596,194.7419707,6.338 +16,23-09-2011,504856.97,0,50.39,3.581,194.8099713,6.338 +16,30-09-2011,450075.31,0,57.61,3.538,194.8779718,6.338 +16,07-10-2011,482926.93,0,48.91,3.498,194.9459724,6.232 +16,14-10-2011,498241.06,0,39.97,3.491,195.0261012,6.232 +16,21-10-2011,560104.16,0,46.99,3.548,195.1789994,6.232 +16,28-10-2011,505918.21,0,41.97,3.55,195.3318977,6.232 +16,04-11-2011,511059.95,0,33.43,3.527,195.4847959,6.232 +16,11-11-2011,513181.31,0,29.56,3.505,195.6376941,6.232 +16,18-11-2011,480353.64,0,31.73,3.479,195.7184713,6.232 +16,25-11-2011,712422.4,1,31.39,3.424,195.7704,6.232 +16,02-12-2011,530492.84,0,27.83,3.378,195.8223287,6.232 +16,09-12-2011,574798.86,0,14.44,3.331,195.8742575,6.232 +16,16-12-2011,679481.9,0,22.5,3.266,195.9841685,6.232 +16,23-12-2011,950691.96,0,20.79,3.173,196.1713893,6.232 +16,30-12-2011,665861.06,1,23.91,3.119,196.3586101,6.232 +16,06-01-2012,564538.07,0,26.49,3.095,196.5458309,6.162 +16,13-01-2012,508520.09,0,19.55,3.077,196.7330517,6.162 +16,20-01-2012,474389.75,0,29.3,3.055,196.7796652,6.162 +16,27-01-2012,453979.19,0,28.17,3.038,196.8262786,6.162 +16,03-02-2012,475905.1,0,25.53,3.031,196.8728921,6.162 +16,10-02-2012,473766.97,1,23.69,3.103,196.9195056,6.162 +16,17-02-2012,494069.49,0,31.19,3.113,196.9432711,6.162 +16,24-02-2012,495720.3,0,26.21,3.129,196.9499007,6.162 +16,02-03-2012,464189.09,0,23.4,3.191,196.9565303,6.162 +16,09-03-2012,495951.66,0,28.16,3.286,196.9631599,6.162 +16,16-03-2012,520850.71,0,38.02,3.486,197.0457208,6.162 +16,23-03-2012,493503.89,0,38.7,3.664,197.2295234,6.162 +16,30-03-2012,485095.41,0,48.29,3.75,197.4133259,6.162 +16,06-04-2012,502662.07,0,48.93,3.854,197.5971285,6.169 +16,13-04-2012,450756.71,0,45.83,3.901,197.780931,6.169 +16,20-04-2012,436221.26,0,43.61,3.936,197.7227385,6.169 +16,27-04-2012,398445.15,0,59.69,3.927,197.664546,6.169 +16,04-05-2012,426959.62,0,51.34,3.903,197.6063534,6.169 +16,11-05-2012,479855,0,53.57,3.87,197.5481609,6.169 +16,18-05-2012,493506.47,0,56.74,3.837,197.5553137,6.169 +16,25-05-2012,518045.09,0,57.36,3.804,197.5886046,6.169 +16,01-06-2012,532311.93,0,58.97,3.764,197.6218954,6.169 +16,08-06-2012,603618.89,0,65.43,3.741,197.6551863,6.169 +16,15-06-2012,570045.79,0,65.36,3.723,197.692292,6.169 +16,22-06-2012,581745.72,0,70.41,3.735,197.7389345,6.169 +16,29-06-2012,570162.28,0,77.31,3.693,197.785577,6.169 +16,06-07-2012,641763.53,0,70.49,3.646,197.8322195,6.061 +16,13-07-2012,569005.06,0,70.29,3.613,197.8788621,6.061 +16,20-07-2012,565297.54,0,68.43,3.585,197.9290378,6.061 +16,27-07-2012,539337.87,0,69,3.57,197.9792136,6.061 +16,03-08-2012,584000.71,0,68.59,3.528,198.0293893,6.061 +16,10-08-2012,554036.84,0,70.24,3.509,198.0795651,6.061 +16,17-08-2012,521896.6,0,62.07,3.545,198.1001057,6.061 +16,24-08-2012,551152.15,0,61.44,3.558,198.0984199,6.061 +16,31-08-2012,551837.31,0,64.19,3.556,198.0967341,6.061 +16,07-09-2012,537138.58,1,60.09,3.596,198.0950484,6.061 +16,14-09-2012,526525.16,0,56.69,3.659,198.1267184,6.061 +16,21-09-2012,509942.56,0,56.48,3.765,198.358523,6.061 +16,28-09-2012,469607.73,0,51.4,3.789,198.5903276,6.061 +16,05-10-2012,471281.68,0,50.46,3.779,198.8221322,5.847 +16,12-10-2012,491817.19,0,43.26,3.76,199.0539368,5.847 +16,19-10-2012,577198.97,0,40.59,3.75,199.1481963,5.847 +16,26-10-2012,475770.14,0,40.99,3.686,199.2195317,5.847 +17,05-02-2010,789036.02,0,23.11,2.666,126.4420645,6.548 +17,12-02-2010,841951.91,1,18.36,2.671,126.4962581,6.548 +17,19-02-2010,800714,0,25.06,2.654,126.5262857,6.548 +17,26-02-2010,749549.55,0,15.64,2.667,126.5522857,6.548 +17,05-03-2010,783300.05,0,31.58,2.681,126.5782857,6.548 +17,12-03-2010,763961.82,0,29.71,2.733,126.6042857,6.548 +17,19-03-2010,752034.52,0,33.96,2.782,126.6066452,6.548 +17,26-03-2010,793097.64,0,35.59,2.819,126.6050645,6.548 +17,02-04-2010,848521.17,0,36.94,2.842,126.6034839,6.635 +17,09-04-2010,770228.02,0,34.05,2.877,126.6019032,6.635 +17,16-04-2010,757738.76,0,45.22,2.915,126.5621,6.635 +17,23-04-2010,977790.83,0,52.25,2.936,126.4713333,6.635 +17,30-04-2010,807798.73,0,43.82,2.941,126.3805667,6.635 +17,07-05-2010,843848.65,0,40.26,2.948,126.2898,6.635 +17,14-05-2010,813756.09,0,47.28,2.962,126.2085484,6.635 +17,21-05-2010,826626.5,0,53.94,2.95,126.1843871,6.635 +17,28-05-2010,872817.62,0,48.19,2.908,126.1602258,6.635 +17,04-06-2010,876902.87,0,53.79,2.871,126.1360645,6.635 +17,11-06-2010,845252.21,0,57.14,2.841,126.1119032,6.635 +17,18-06-2010,877996.27,0,54.94,2.819,126.114,6.635 +17,25-06-2010,893995.44,0,62.64,2.82,126.1266,6.635 +17,02-07-2010,958875.37,0,68.98,2.814,126.1392,6.697 +17,09-07-2010,836915.92,0,62.41,2.802,126.1518,6.697 +17,16-07-2010,876591.41,0,65.66,2.791,126.1498065,6.697 +17,23-07-2010,893504.87,0,69.66,2.797,126.1283548,6.697 +17,30-07-2010,833517.19,0,69.96,2.797,126.1069032,6.697 +17,06-08-2010,795301.17,0,70.53,2.802,126.0854516,6.697 +17,13-08-2010,759995.18,0,65.17,2.837,126.064,6.697 +17,20-08-2010,783929.7,0,67.04,2.85,126.0766452,6.697 +17,27-08-2010,802583.89,0,65.03,2.854,126.0892903,6.697 +17,03-09-2010,834373.73,0,57.86,2.868,126.1019355,6.697 +17,10-09-2010,1200888.28,1,56.28,2.87,126.1145806,6.697 +17,17-09-2010,871264.25,0,58.53,2.875,126.1454667,6.697 +17,24-09-2010,852876.29,0,58.39,2.872,126.1900333,6.697 +17,01-10-2010,829207.27,0,60.07,2.853,126.2346,6.885 +17,08-10-2010,827738.06,0,58.06,2.841,126.2791667,6.885 +17,15-10-2010,838297.32,0,47.35,2.845,126.3266774,6.885 +17,22-10-2010,815093.76,0,47.95,2.849,126.3815484,6.885 +17,29-10-2010,861941.25,0,39.87,2.841,126.4364194,6.885 +17,05-11-2010,818434.49,0,42.54,2.831,126.4912903,6.885 +17,12-11-2010,855459.96,0,36.32,2.831,126.5461613,6.885 +17,19-11-2010,782252.57,0,36.31,2.842,126.6072,6.885 +17,26-11-2010,1005448.76,1,19.03,2.83,126.6692667,6.885 +17,03-12-2010,926573.81,0,22.47,2.812,126.7313333,6.885 +17,10-12-2010,962475.55,0,31.64,2.817,126.7934,6.885 +17,17-12-2010,1049372.38,0,25.13,2.842,126.8794839,6.885 +17,24-12-2010,1309226.79,0,26.58,2.846,126.9835806,6.885 +17,31-12-2010,635862.55,1,20.79,2.868,127.0876774,6.885 +17,07-01-2011,1083071.14,0,6.23,2.891,127.1917742,6.866 +17,14-01-2011,758510.36,0,16.57,2.903,127.3009355,6.866 +17,21-01-2011,755804.37,0,26.62,2.934,127.4404839,6.866 +17,28-01-2011,736335.69,0,22.16,2.96,127.5800323,6.866 +17,04-02-2011,816603.05,0,11.29,2.974,127.7195806,6.866 +17,11-02-2011,813211.46,1,14.19,3.034,127.859129,6.866 +17,18-02-2011,860962.91,0,26.86,3.062,127.99525,6.866 +17,25-02-2011,767256.53,0,24.36,3.12,128.13,6.866 +17,04-03-2011,816138.33,0,24.21,3.23,128.26475,6.866 +17,11-03-2011,779602.36,0,32.42,3.346,128.3995,6.866 +17,18-03-2011,778436.81,0,34.48,3.407,128.5121935,6.866 +17,25-03-2011,781267.76,0,36.71,3.435,128.6160645,6.866 +17,01-04-2011,795859.23,0,39.38,3.487,128.7199355,6.774 +17,08-04-2011,811855.72,0,39.16,3.547,128.8238065,6.774 +17,15-04-2011,825283.43,0,39.98,3.616,128.9107333,6.774 +17,22-04-2011,1060770.11,0,42.24,3.655,128.9553,6.774 +17,29-04-2011,806979.15,0,40.14,3.683,128.9998667,6.774 +17,06-05-2011,882132.28,0,45.66,3.744,129.0444333,6.774 +17,13-05-2011,870625.49,0,49.26,3.77,129.089,6.774 +17,20-05-2011,844443.35,0,51.93,3.802,129.0756774,6.774 +17,27-05-2011,892056.64,0,51.04,3.778,129.0623548,6.774 +17,03-06-2011,895020.48,0,49.61,3.752,129.0490323,6.774 +17,10-06-2011,881190.46,0,54.57,3.732,129.0357097,6.774 +17,17-06-2011,894686.67,0,56.61,3.704,129.0432,6.774 +17,24-06-2011,920719.98,0,60.99,3.668,129.0663,6.774 +17,01-07-2011,940554.34,0,67.39,3.613,129.0894,6.745 +17,08-07-2011,915064.22,0,70.6,3.563,129.1125,6.745 +17,15-07-2011,902727.76,0,67.93,3.553,129.1338387,6.745 +17,22-07-2011,899044.34,0,69.82,3.563,129.1507742,6.745 +17,29-07-2011,861894.77,0,68.59,3.574,129.1677097,6.745 +17,05-08-2011,866184.92,0,65.71,3.595,129.1846452,6.745 +17,12-08-2011,800819.79,0,64.79,3.606,129.2015806,6.745 +17,19-08-2011,797523.04,0,67.59,3.578,129.2405806,6.745 +17,26-08-2011,837390.79,0,72.04,3.57,129.2832581,6.745 +17,02-09-2011,847380.07,0,69.31,3.58,129.3259355,6.745 +17,09-09-2011,1161900.18,1,61.94,3.619,129.3686129,6.745 +17,16-09-2011,1051116.95,0,61.48,3.641,129.4306,6.745 +17,23-09-2011,895535.31,0,56.96,3.648,129.5183333,6.745 +17,30-09-2011,868191.05,0,61.4,3.623,129.6060667,6.745 +17,07-10-2011,918006.9,0,54.4,3.592,129.6938,6.617 +17,14-10-2011,884042.63,0,47.69,3.567,129.7706452,6.617 +17,21-10-2011,877380.22,0,47.27,3.579,129.7821613,6.617 +17,28-10-2011,936508.43,0,41.89,3.567,129.7936774,6.617 +17,04-11-2011,927657.63,0,37.52,3.538,129.8051935,6.617 +17,11-11-2011,914759.2,0,27.61,3.513,129.8167097,6.617 +17,18-11-2011,877724.31,0,32.93,3.489,129.8268333,6.617 +17,25-11-2011,1225700.28,1,32.81,3.445,129.8364,6.617 +17,02-12-2011,945267.68,0,26.47,3.389,129.8459667,6.617 +17,09-12-2011,976522.93,0,17.56,3.341,129.8555333,6.617 +17,16-12-2011,1067754.06,0,21.07,3.282,129.8980645,6.617 +17,23-12-2011,1289156.9,0,18.76,3.186,129.9845484,6.617 +17,30-12-2011,777207.3,1,26.73,3.119,130.0710323,6.617 +17,06-01-2012,1198104.22,0,27.64,3.08,130.1575161,6.403 +17,13-01-2012,873576.96,0,20.28,3.056,130.244,6.403 +17,20-01-2012,809272.65,0,27.26,3.047,130.2792258,6.403 +17,27-01-2012,769522.33,0,29.99,3.058,130.3144516,6.403 +17,03-02-2012,864852.85,0,26.26,3.077,130.3496774,6.403 +17,10-02-2012,880165.7,1,23.63,3.116,130.3849032,6.403 +17,17-02-2012,927084.65,0,30.76,3.119,130.4546207,6.403 +17,24-02-2012,843864.43,0,30.01,3.145,130.5502069,6.403 +17,02-03-2012,856178.47,0,26.28,3.242,130.6457931,6.403 +17,09-03-2012,860224.98,0,32.02,3.38,130.7413793,6.403 +17,16-03-2012,853136.46,0,43.69,3.529,130.8261935,6.403 +17,23-03-2012,851762.28,0,40.69,3.671,130.8966452,6.403 +17,30-03-2012,872469.03,0,45.29,3.734,130.9670968,6.403 +17,06-04-2012,986922.62,0,43.92,3.793,131.0375484,6.235 +17,13-04-2012,877055.32,0,46.94,3.833,131.108,6.235 +17,20-04-2012,1119979.98,0,47.69,3.845,131.1173333,6.235 +17,27-04-2012,925916.65,0,59.11,3.842,131.1266667,6.235 +17,04-05-2012,930121.14,0,48.86,3.831,131.136,6.235 +17,11-05-2012,944100.3,0,49.96,3.809,131.1453333,6.235 +17,18-05-2012,968816.33,0,59.67,3.808,131.0983226,6.235 +17,25-05-2012,984881.59,0,55.69,3.801,131.0287742,6.235 +17,01-06-2012,938914.28,0,54.13,3.788,130.9592258,6.235 +17,08-06-2012,987990.24,0,60.51,3.776,130.8896774,6.235 +17,15-06-2012,964169.67,0,56.67,3.756,130.8295333,6.235 +17,22-06-2012,981210.57,0,62.9,3.737,130.7929,6.235 +17,29-06-2012,982322.24,0,71.14,3.681,130.7562667,6.235 +17,06-07-2012,1046782.52,0,68.91,3.63,130.7196333,5.936 +17,13-07-2012,960746.04,0,72.94,3.595,130.683,5.936 +17,20-07-2012,944698.7,0,70.59,3.556,130.7012903,5.936 +17,27-07-2012,907493.24,0,74.2,3.537,130.7195806,5.936 +17,03-08-2012,877813.33,0,72.94,3.512,130.737871,5.936 +17,10-08-2012,849074.04,0,73.29,3.509,130.7561613,5.936 +17,17-08-2012,844928.17,0,70.98,3.545,130.7909677,5.936 +17,24-08-2012,924299.78,0,68.89,3.582,130.8381613,5.936 +17,31-08-2012,865924.2,0,68.07,3.624,130.8853548,5.936 +17,07-09-2012,1255633.29,1,61.99,3.689,130.9325484,5.936 +17,14-09-2012,1071040.22,0,59.64,3.749,130.9776667,5.936 +17,21-09-2012,938303.28,0,58.43,3.821,131.0103333,5.936 +17,28-09-2012,972716.24,0,57.77,3.821,131.043,5.936 +17,05-10-2012,952609.17,0,52.81,3.815,131.0756667,5.527 +17,12-10-2012,919878.34,0,44.82,3.797,131.1083333,5.527 +17,19-10-2012,957356.84,0,48.16,3.781,131.1499677,5.527 +17,26-10-2012,943465.29,0,39.94,3.755,131.1930968,5.527 +18,05-02-2010,1205307.5,0,21.33,2.788,131.5279032,9.202 +18,12-02-2010,1187880.7,1,26.41,2.771,131.5866129,9.202 +18,19-02-2010,1150663.42,0,30.91,2.747,131.637,9.202 +18,26-02-2010,1068157.45,0,35.42,2.753,131.686,9.202 +18,05-03-2010,1179738.5,0,37.17,2.766,131.735,9.202 +18,12-03-2010,1138800.32,0,42.39,2.805,131.784,9.202 +18,19-03-2010,1087507.47,0,45.42,2.834,131.8242903,9.202 +18,26-03-2010,1092704.09,0,47.55,2.831,131.863129,9.202 +18,02-04-2010,1254107.84,0,45.63,2.826,131.9019677,9.269 +18,09-04-2010,1174447.55,0,59.91,2.849,131.9408065,9.269 +18,16-04-2010,1135577.62,0,50.26,2.885,131.9809,9.269 +18,23-04-2010,1132433.55,0,50.3,2.895,132.0226667,9.269 +18,30-04-2010,1060446.16,0,51.12,2.935,132.0644333,9.269 +18,07-05-2010,1222255.47,0,65.64,2.981,132.1062,9.269 +18,14-05-2010,1092616.49,0,49.9,2.983,132.152129,9.269 +18,21-05-2010,1101621.36,0,60.27,2.961,132.2230323,9.269 +18,28-05-2010,1256282.79,0,69.12,2.906,132.2939355,9.269 +18,04-06-2010,1271311.76,0,70.28,2.857,132.3648387,9.269 +18,11-06-2010,1173521.82,0,64.08,2.83,132.4357419,9.269 +18,18-06-2010,1183225.92,0,65.96,2.805,132.4733333,9.269 +18,25-06-2010,1220983.17,0,74.04,2.81,132.4976,9.269 +18,02-07-2010,1257928.35,0,71.22,2.815,132.5218667,9.342 +18,09-07-2010,1171391.41,0,79.75,2.806,132.5461333,9.342 +18,16-07-2010,1115514.61,0,76.9,2.796,132.5667742,9.342 +18,23-07-2010,1032908.23,0,75.71,2.784,132.5825806,9.342 +18,30-07-2010,1078557.62,0,75.79,2.792,132.5983871,9.342 +18,06-08-2010,1166117.85,0,73.67,2.792,132.6141935,9.342 +18,13-08-2010,1084722.78,0,74.19,2.81,132.63,9.342 +18,20-08-2010,1141860.67,0,71.76,2.796,132.6616129,9.342 +18,27-08-2010,1214302.76,0,67.05,2.77,132.6932258,9.342 +18,03-09-2010,1187359.77,0,75.42,2.735,132.7248387,9.342 +18,10-09-2010,1011201.12,1,67.09,2.717,132.7564516,9.342 +18,17-09-2010,997998.21,0,60.94,2.716,132.7670667,9.342 +18,24-09-2010,950862.92,0,64.82,2.718,132.7619333,9.342 +18,01-10-2010,948977.5,0,67.76,2.717,132.7568,9.331 +18,08-10-2010,1107432.71,0,54.73,2.776,132.7516667,9.331 +18,15-10-2010,1029618.1,0,52.02,2.878,132.7633548,9.331 +18,22-10-2010,1052120.43,0,47.12,2.919,132.8170968,9.331 +18,29-10-2010,1038576.54,0,55.85,2.938,132.8708387,9.331 +18,05-11-2010,1089530.94,0,42.05,2.938,132.9245806,9.331 +18,12-11-2010,1081322.12,0,43.17,2.961,132.9783226,9.331 +18,19-11-2010,1045722.37,0,45.26,3.03,132.9172,9.331 +18,26-11-2010,1653759.36,1,40.81,3.07,132.8369333,9.331 +18,03-12-2010,1211026.13,0,37.09,3.065,132.7566667,9.331 +18,10-12-2010,1416168.98,0,25.64,3.132,132.6764,9.331 +18,17-12-2010,1588430.71,0,27.4,3.139,132.6804516,9.331 +18,24-12-2010,2027507.15,0,28.16,3.15,132.7477419,9.331 +18,31-12-2010,887907.01,1,26.1,3.177,132.8150323,9.331 +18,07-01-2011,933960.3,0,30.1,3.193,132.8823226,9.131 +18,14-01-2011,777175.28,0,22.69,3.215,132.9510645,9.131 +18,21-01-2011,891148.55,0,22.55,3.232,133.0285161,9.131 +18,28-01-2011,849540.85,0,14.84,3.243,133.1059677,9.131 +18,04-02-2011,1055841.24,0,20.79,3.24,133.1834194,9.131 +18,11-02-2011,1122053.58,1,24.3,3.255,133.260871,9.131 +18,18-02-2011,1095058.57,0,31.59,3.263,133.3701429,9.131 +18,25-02-2011,1005983.31,0,26.15,3.281,133.4921429,9.131 +18,04-03-2011,1063310.62,0,28.49,3.437,133.6141429,9.131 +18,11-03-2011,1002714.25,0,38.4,3.6,133.7361429,9.131 +18,18-03-2011,945889.59,0,41.12,3.634,133.8492258,9.131 +18,25-03-2011,944523.3,0,36.65,3.624,133.9587419,9.131 +18,01-04-2011,938083.17,0,35.06,3.638,134.0682581,8.975 +18,08-04-2011,1018541.3,0,43.32,3.72,134.1777742,8.975 +18,15-04-2011,988157.72,0,49.91,3.823,134.2784667,8.975 +18,22-04-2011,1105860.06,0,45.99,3.919,134.3571,8.975 +18,29-04-2011,974114.39,0,58.82,3.988,134.4357333,8.975 +18,06-05-2011,1065427.37,0,54.17,4.078,134.5143667,8.975 +18,13-05-2011,993172.98,0,58.48,4.095,134.593,8.975 +18,20-05-2011,994610.43,0,57.55,4.101,134.6803871,8.975 +18,27-05-2011,1065214.14,0,64.6,4.034,134.7677742,8.975 +18,03-06-2011,1178039,0,70.9,3.973,134.8551613,8.975 +18,10-06-2011,1044079.2,0,69.49,3.924,134.9425484,8.975 +18,17-06-2011,1045859.39,0,63.23,3.873,135.0837333,8.975 +18,24-06-2011,1056478.65,0,67.41,3.851,135.2652667,8.975 +18,01-07-2011,1087051.26,0,69.75,3.815,135.4468,8.89 +18,08-07-2011,1048802.62,0,73.12,3.784,135.6283333,8.89 +18,15-07-2011,974916.13,0,74.36,3.827,135.7837419,8.89 +18,22-07-2011,991262.46,0,78.68,3.882,135.8738387,8.89 +18,29-07-2011,954148.64,0,73.85,3.898,135.9639355,8.89 +18,05-08-2011,1002806.39,0,74.58,3.903,136.0540323,8.89 +18,12-08-2011,928470.83,0,73.57,3.88,136.144129,8.89 +18,19-08-2011,932679.79,0,69.24,3.82,136.183129,8.89 +18,26-08-2011,1147906.46,0,70.32,3.796,136.2136129,8.89 +18,02-09-2011,540922.94,0,68.23,3.784,136.2440968,8.89 +18,09-09-2011,951549.61,1,68.11,3.809,136.2745806,8.89 +18,16-09-2011,845715.37,0,66.23,3.809,136.3145,8.89 +18,23-09-2011,853073.17,0,60.44,3.758,136.367,8.89 +18,30-09-2011,847348.08,0,69.01,3.684,136.4195,8.89 +18,07-10-2011,1019741.1,0,54.65,3.633,136.472,8.471 +18,14-10-2011,953533.95,0,60.26,3.583,136.5150968,8.471 +18,21-10-2011,1048212.62,0,55.83,3.618,136.5017742,8.471 +18,28-10-2011,1106642.63,0,45.61,3.604,136.4884516,8.471 +18,04-11-2011,1100625.06,0,38.29,3.586,136.475129,8.471 +18,11-11-2011,1079931.63,0,45.69,3.57,136.4618065,8.471 +18,18-11-2011,1056992.18,0,47.88,3.571,136.4666667,8.471 +18,25-11-2011,1624170.99,1,41.97,3.536,136.4788,8.471 +18,02-12-2011,1188047.61,0,46.25,3.501,136.4909333,8.471 +18,09-12-2011,1368471.23,0,42.36,3.47,136.5030667,8.471 +18,16-12-2011,1516924.23,0,35.52,3.445,136.5335161,8.471 +18,23-12-2011,1882393.4,0,35.78,3.413,136.5883871,8.471 +18,30-12-2011,1010562.49,1,32.36,3.402,136.6432581,8.471 +18,06-01-2012,977286.07,0,31.27,3.439,136.698129,8.075 +18,13-01-2012,890130.25,0,35.25,3.523,136.753,8.075 +18,20-01-2012,937522.77,0,24.2,3.542,136.8564194,8.075 +18,27-01-2012,825584.22,0,30.44,3.568,136.9598387,8.075 +18,03-02-2012,1049772.04,0,37.62,3.633,137.0632581,8.075 +18,10-02-2012,1161615.51,1,32.83,3.655,137.1666774,8.075 +18,17-02-2012,1115985.81,0,32.87,3.703,137.2583103,8.075 +18,24-02-2012,1037861.11,0,36.34,3.751,137.3411034,8.075 +18,02-03-2012,1047178.91,0,33.59,3.827,137.4238966,8.075 +18,09-03-2012,1084894.47,0,38.1,3.876,137.5066897,8.075 +18,16-03-2012,1022018.43,0,45.84,3.867,137.5843871,8.075 +18,23-03-2012,1031139.3,0,58.06,3.889,137.6552903,8.075 +18,30-03-2012,1009121.2,0,45.35,3.921,137.7261935,8.075 +18,06-04-2012,1200815.3,0,43.8,3.957,137.7970968,8.304 +18,13-04-2012,998443.5,0,47.75,4.025,137.868,8.304 +18,20-04-2012,1025813.8,0,60.88,4.046,137.9230667,8.304 +18,27-04-2012,961186.23,0,50.43,4.023,137.9781333,8.304 +18,04-05-2012,1050027.89,0,49.66,3.991,138.0332,8.304 +18,11-05-2012,1060433.1,0,57.44,3.947,138.0882667,8.304 +18,18-05-2012,1047444.59,0,62.31,3.899,138.1065806,8.304 +18,25-05-2012,1088446.58,0,65.48,3.85,138.1101935,8.304 +18,01-06-2012,1118313.7,0,71.42,3.798,138.1138065,8.304 +18,08-06-2012,1110479.94,0,59.1,3.746,138.1174194,8.304 +18,15-06-2012,1057425.83,0,66.58,3.683,138.1295333,8.304 +18,22-06-2012,1080357.89,0,70.92,3.629,138.1629,8.304 +18,29-06-2012,1097006.3,0,70.17,3.577,138.1962667,8.304 +18,06-07-2012,1158247.31,0,76.08,3.538,138.2296333,8.535 +18,13-07-2012,1024784.92,0,75.09,3.561,138.263,8.535 +18,20-07-2012,1033543.56,0,77.43,3.61,138.2331935,8.535 +18,27-07-2012,924506.26,0,72.97,3.701,138.2033871,8.535 +18,03-08-2012,1052066.58,0,72.67,3.698,138.1735806,8.535 +18,10-08-2012,967304.07,0,75.7,3.772,138.1437742,8.535 +18,17-08-2012,1048134.24,0,73.25,3.84,138.1857097,8.535 +18,24-08-2012,1145840.91,0,68.52,3.874,138.2814516,8.535 +18,31-08-2012,1117097.23,0,70.09,3.884,138.3771935,8.535 +18,07-09-2012,1083521.24,1,71.85,3.921,138.4729355,8.535 +18,14-09-2012,960476.1,0,64.45,3.988,138.5673,8.535 +18,21-09-2012,971386.65,0,60.23,4.056,138.6534,8.535 +18,28-09-2012,1002856.2,0,58.24,4.018,138.7395,8.535 +18,05-10-2012,1092204.79,0,59.68,4.027,138.8256,8.243 +18,12-10-2012,1074079,0,50.97,4.029,138.9117,8.243 +18,19-10-2012,1048706.75,0,51.96,4,138.8336129,8.243 +18,26-10-2012,1127516.25,0,56.09,3.917,138.7281613,8.243 +19,05-02-2010,1507637.17,0,20.96,2.954,131.5279032,8.35 +19,12-02-2010,1536549.95,1,23.22,2.94,131.5866129,8.35 +19,19-02-2010,1515976.11,0,28.57,2.909,131.637,8.35 +19,26-02-2010,1373270.06,0,30.33,2.91,131.686,8.35 +19,05-03-2010,1495844.57,0,32.92,2.919,131.735,8.35 +19,12-03-2010,1467889.2,0,39.06,2.938,131.784,8.35 +19,19-03-2010,1332940.35,0,43.74,2.96,131.8242903,8.35 +19,26-03-2010,1427023.45,0,39.07,2.963,131.863129,8.35 +19,02-04-2010,1642970.27,0,45.26,2.957,131.9019677,8.185 +19,09-04-2010,1489613.32,0,55.66,2.992,131.9408065,8.185 +19,16-04-2010,1460354.67,0,49.67,3.01,131.9809,8.185 +19,23-04-2010,1456793.33,0,46.87,3.021,132.0226667,8.185 +19,30-04-2010,1405065.57,0,49.89,3.042,132.0644333,8.185 +19,07-05-2010,1566219.77,0,62.54,3.095,132.1062,8.185 +19,14-05-2010,1437319.45,0,46.53,3.112,132.152129,8.185 +19,21-05-2010,1377716.17,0,57.53,3.096,132.2230323,8.185 +19,28-05-2010,1648882.62,0,68.85,3.046,132.2939355,8.185 +19,04-06-2010,1519013.49,0,68.88,3.006,132.3648387,8.185 +19,11-06-2010,1410683.94,0,61.64,2.972,132.4357419,8.185 +19,18-06-2010,1457314.39,0,66.25,2.942,132.4733333,8.185 +19,25-06-2010,1450407.32,0,72.3,2.958,132.4976,8.185 +19,02-07-2010,1549018.68,0,66.25,2.958,132.5218667,8.099 +19,09-07-2010,1577541.24,0,78.22,2.94,132.5461333,8.099 +19,16-07-2010,1412157.02,0,74.6,2.933,132.5667742,8.099 +19,23-07-2010,1372043.71,0,74.68,2.924,132.5825806,8.099 +19,30-07-2010,1366395.96,0,72.83,2.932,132.5983871,8.099 +19,06-08-2010,1492060.89,0,74.2,2.942,132.6141935,8.099 +19,13-08-2010,1418027.08,0,72.71,2.923,132.63,8.099 +19,20-08-2010,1419383.19,0,72.22,2.913,132.6616129,8.099 +19,27-08-2010,1557888.16,0,66.4,2.885,132.6932258,8.099 +19,03-09-2010,1623519.64,0,74.69,2.86,132.7248387,8.099 +19,10-09-2010,1591453.39,1,63.36,2.837,132.7564516,8.099 +19,17-09-2010,1386789.31,0,58.68,2.846,132.7670667,8.099 +19,24-09-2010,1318343.58,0,63.43,2.837,132.7619333,8.099 +19,01-10-2010,1379456.3,0,59.91,2.84,132.7568,8.067 +19,08-10-2010,1428960.72,0,53.74,2.903,132.7516667,8.067 +19,15-10-2010,1369317.63,0,51.32,2.999,132.7633548,8.067 +19,22-10-2010,1357154.71,0,48.45,3.049,132.8170968,8.067 +19,29-10-2010,1404576.48,0,56.11,3.055,132.8708387,8.067 +19,05-11-2010,1435379.25,0,41.78,3.049,132.9245806,8.067 +19,12-11-2010,1490235.86,0,40.3,3.065,132.9783226,8.067 +19,19-11-2010,1377593.1,0,44.22,3.138,132.9172,8.067 +19,26-11-2010,1993367.83,1,42.62,3.186,132.8369333,8.067 +19,03-12-2010,1615987.96,0,36.64,3.2,132.7566667,8.067 +19,10-12-2010,1799070.98,0,25.12,3.255,132.6764,8.067 +19,17-12-2010,1911967.44,0,26.83,3.301,132.6804516,8.067 +19,24-12-2010,2678206.42,0,26.05,3.309,132.7477419,8.067 +19,31-12-2010,1275146.94,1,28.65,3.336,132.8150323,8.067 +19,07-01-2011,1224175.99,0,31.34,3.351,132.8823226,7.771 +19,14-01-2011,1181204.53,0,21.68,3.367,132.9510645,7.771 +19,21-01-2011,1212967.84,0,22.8,3.391,133.0285161,7.771 +19,28-01-2011,1284185.49,0,20.66,3.402,133.1059677,7.771 +19,04-02-2011,1370562.11,0,21.02,3.4,133.1834194,7.771 +19,11-02-2011,1430851.11,1,21.79,3.416,133.260871,7.771 +19,18-02-2011,1457270.16,0,34.74,3.42,133.3701429,7.771 +19,25-02-2011,1296658.47,0,23.24,3.452,133.4921429,7.771 +19,04-03-2011,1433569.44,0,29.28,3.605,133.6141429,7.771 +19,11-03-2011,1351450.43,0,35.59,3.752,133.7361429,7.771 +19,18-03-2011,1257972.37,0,40.32,3.796,133.8492258,7.771 +19,25-03-2011,1266564.94,0,33.26,3.789,133.9587419,7.771 +19,01-04-2011,1305950.22,0,30.68,3.811,134.0682581,7.658 +19,08-04-2011,1419911.91,0,41.26,3.895,134.1777742,7.658 +19,15-04-2011,1392093.04,0,48.67,3.981,134.2784667,7.658 +19,22-04-2011,1514288.82,0,41.66,4.061,134.3571,7.658 +19,29-04-2011,1297237.7,0,54.23,4.117,134.4357333,7.658 +19,06-05-2011,1451953.95,0,50.43,4.192,134.5143667,7.658 +19,13-05-2011,1429143.06,0,54.2,4.211,134.593,7.658 +19,20-05-2011,1355234.3,0,52.8,4.202,134.6803871,7.658 +19,27-05-2011,1388553.11,0,63.2,4.134,134.7677742,7.658 +19,03-06-2011,1457345.75,0,66.01,4.069,134.8551613,7.658 +19,10-06-2011,1467473.63,0,68.26,4.025,134.9425484,7.658 +19,17-06-2011,1418973.62,0,64.02,3.989,135.0837333,7.658 +19,24-06-2011,1440785.7,0,68.4,3.964,135.2652667,7.658 +19,01-07-2011,1462731.93,0,67.64,3.916,135.4468,7.806 +19,08-07-2011,1465489.75,0,73.2,3.886,135.6283333,7.806 +19,15-07-2011,1391580.41,0,73.7,3.915,135.7837419,7.806 +19,22-07-2011,1377119.45,0,79.37,3.972,135.8738387,7.806 +19,29-07-2011,1298775.8,0,74.86,4.004,135.9639355,7.806 +19,05-08-2011,1408968.55,0,73.84,4.02,136.0540323,7.806 +19,12-08-2011,1360969.45,0,70.92,3.995,136.144129,7.806 +19,19-08-2011,1391792.69,0,71.14,3.942,136.183129,7.806 +19,26-08-2011,1547729.24,0,69.34,3.906,136.2136129,7.806 +19,02-09-2011,1609951.02,0,69.27,3.879,136.2440968,7.806 +19,09-09-2011,1566712.79,1,68.28,3.93,136.2745806,7.806 +19,16-09-2011,1365633.53,0,62.76,3.937,136.3145,7.806 +19,23-09-2011,1300375.76,0,61.32,3.899,136.367,7.806 +19,30-09-2011,1330757.22,0,64.99,3.858,136.4195,7.806 +19,07-10-2011,1461718.87,0,53.1,3.775,136.472,7.866 +19,14-10-2011,1318905.53,0,61.86,3.744,136.5150968,7.866 +19,21-10-2011,1374863.1,0,52.05,3.757,136.5017742,7.866 +19,28-10-2011,1396612.36,0,46.49,3.757,136.4884516,7.866 +19,04-11-2011,1480289.64,0,44.97,3.738,136.475129,7.866 +19,11-11-2011,1502078.93,0,48.22,3.719,136.4618065,7.866 +19,18-11-2011,1411835.57,0,48.21,3.717,136.4666667,7.866 +19,25-11-2011,1974646.78,1,42.75,3.689,136.4788,7.866 +19,02-12-2011,1484708.38,0,45.67,3.666,136.4909333,7.866 +19,09-12-2011,1713769.06,0,40.18,3.627,136.5030667,7.866 +19,16-12-2011,1852179.15,0,37.07,3.611,136.5335161,7.866 +19,23-12-2011,2480159.47,0,36.09,3.587,136.5883871,7.866 +19,30-12-2011,1405168.06,1,31.65,3.566,136.6432581,7.866 +19,06-01-2012,1266570.4,0,31.84,3.585,136.698129,7.943 +19,13-01-2012,1182198.7,0,37.08,3.666,136.753,7.943 +19,20-01-2012,1237104.73,0,23.44,3.705,136.8564194,7.943 +19,27-01-2012,1279623.26,0,32.41,3.737,136.9598387,7.943 +19,03-02-2012,1345311.65,0,36.22,3.796,137.0632581,7.943 +19,10-02-2012,1499496.67,1,32.61,3.826,137.1666774,7.943 +19,17-02-2012,1424720.27,0,30.95,3.874,137.2583103,7.943 +19,24-02-2012,1352470.09,0,33.91,3.917,137.3411034,7.943 +19,02-03-2012,1308977.05,0,34.83,3.983,137.4238966,7.943 +19,09-03-2012,1358816.46,0,38.15,4.021,137.5066897,7.943 +19,16-03-2012,1312849.1,0,48.2,4.021,137.5843871,7.943 +19,23-03-2012,1342254.55,0,56.72,4.054,137.6552903,7.943 +19,30-03-2012,1327139.35,0,43.47,4.098,137.7261935,7.943 +19,06-04-2012,1631737.68,0,40.23,4.143,137.7970968,8.15 +19,13-04-2012,1365098.46,0,44.42,4.187,137.868,8.15 +19,20-04-2012,1255087.26,0,55.2,4.17,137.9230667,8.15 +19,27-04-2012,1285897.24,0,42.45,4.163,137.9781333,8.15 +19,04-05-2012,1405007.44,0,50.76,4.124,138.0332,8.15 +19,11-05-2012,1442873.22,0,55.33,4.055,138.0882667,8.15 +19,18-05-2012,1366937.1,0,58.81,4.029,138.1065806,8.15 +19,25-05-2012,1485540.28,0,67.79,3.979,138.1101935,8.15 +19,01-06-2012,1450733.29,0,68.18,3.915,138.1138065,8.15 +19,08-06-2012,1390122.11,0,60.19,3.871,138.1174194,8.15 +19,15-06-2012,1440263.15,0,68.19,3.786,138.1295333,8.15 +19,22-06-2012,1468350.36,0,75.83,3.722,138.1629,8.15 +19,29-06-2012,1379652.65,0,69.92,3.667,138.1962667,8.15 +19,06-07-2012,1557120.44,0,76.07,3.646,138.2296333,8.193 +19,13-07-2012,1321741.35,0,73.17,3.689,138.263,8.193 +19,20-07-2012,1317672.92,0,76.17,3.732,138.2331935,8.193 +19,27-07-2012,1248915.43,0,74.43,3.82,138.2033871,8.193 +19,03-08-2012,1342123.78,0,73.41,3.819,138.1735806,8.193 +19,10-08-2012,1408907.89,0,74.45,3.863,138.1437742,8.193 +19,17-08-2012,1375101.26,0,69.83,3.963,138.1857097,8.193 +19,24-08-2012,1544653.37,0,66.66,3.997,138.2814516,8.193 +19,31-08-2012,1542719.87,0,71.85,4.026,138.3771935,8.193 +19,07-09-2012,1497073.82,1,72.2,4.076,138.4729355,8.193 +19,14-09-2012,1370653.41,0,65.08,4.088,138.5673,8.193 +19,21-09-2012,1338572.29,0,60.62,4.203,138.6534,8.193 +19,28-09-2012,1338299.02,0,56.81,4.158,138.7395,8.193 +19,05-10-2012,1408016.1,0,59.86,4.151,138.8256,7.992 +19,12-10-2012,1352809.5,0,48.29,4.186,138.9117,7.992 +19,19-10-2012,1321102.35,0,53.44,4.153,138.8336129,7.992 +19,26-10-2012,1322117.96,0,56.49,4.071,138.7281613,7.992 +20,05-02-2010,2401395.47,0,25.92,2.784,204.2471935,8.187 +20,12-02-2010,2109107.9,1,22.12,2.773,204.3857472,8.187 +20,19-02-2010,2161549.76,0,25.43,2.745,204.4321004,8.187 +20,26-02-2010,1898193.95,0,32.32,2.754,204.4630869,8.187 +20,05-03-2010,2119213.72,0,31.75,2.777,204.4940734,8.187 +20,12-03-2010,2010974.84,0,43.82,2.818,204.5250598,8.187 +20,19-03-2010,1951848.43,0,47.32,2.844,204.3782258,8.187 +20,26-03-2010,1894742.95,0,50.49,2.854,204.201755,8.187 +20,02-04-2010,2405395.22,0,51,2.85,204.0252842,7.856 +20,09-04-2010,2007796.26,0,65.1,2.869,203.8488134,7.856 +20,16-04-2010,1985784.59,0,55.43,2.899,203.7307486,7.856 +20,23-04-2010,1878862.42,0,50.65,2.902,203.6905586,7.856 +20,30-04-2010,1919053.21,0,54.75,2.921,203.6503685,7.856 +20,07-05-2010,2137202.38,0,66.74,2.966,203.6101784,7.856 +20,14-05-2010,2033211.62,0,55.91,2.982,203.6133915,7.856 +20,21-05-2010,1893736.9,0,60.38,2.958,203.8770235,7.856 +20,28-05-2010,2065984.95,0,70.97,2.899,204.1406556,7.856 +20,04-06-2010,2203619.35,0,72.52,2.847,204.4042877,7.856 +20,11-06-2010,2100489.79,0,67.32,2.809,204.6679198,7.856 +20,18-06-2010,2091903.63,0,72.62,2.78,204.670036,7.856 +20,25-06-2010,1973135.87,0,75.17,2.808,204.5675459,7.856 +20,02-07-2010,2143676.77,0,70.1,2.815,204.4650559,7.527 +20,09-07-2010,2107285.85,0,78.09,2.793,204.3625658,7.527 +20,16-07-2010,2031852.16,0,75.14,2.783,204.3571656,7.527 +20,23-07-2010,1900535.9,0,77.75,2.771,204.4812188,7.527 +20,30-07-2010,1955896.59,0,76.03,2.781,204.605272,7.527 +20,06-08-2010,1910177.38,0,74.57,2.784,204.7293252,7.527 +20,13-08-2010,2071022.45,0,75.98,2.805,204.8533784,7.527 +20,20-08-2010,1975374.56,0,75.34,2.779,204.8217044,7.527 +20,27-08-2010,1946369.57,0,70.51,2.755,204.7900305,7.527 +20,03-09-2010,2121561.41,0,75.5,2.715,204.7583566,7.527 +20,10-09-2010,2014954.79,1,65.02,2.699,204.7266827,7.527 +20,17-09-2010,1948359.78,0,65.28,2.706,204.7513279,7.527 +20,24-09-2010,1789687.65,0,69.37,2.713,204.8182126,7.527 +20,01-10-2010,1933719.21,0,61.08,2.707,204.8850973,7.484 +20,08-10-2010,2060389.27,0,51.5,2.764,204.951982,7.484 +20,15-10-2010,1950676.39,0,59.17,2.868,205.0137637,7.484 +20,22-10-2010,1893955.27,0,50.52,2.917,205.0627881,7.484 +20,29-10-2010,1891816,0,57.56,2.921,205.1118126,7.484 +20,05-11-2010,2184316.64,0,42.78,2.917,205.160837,7.484 +20,12-11-2010,2187765.28,0,42.38,2.931,205.2098614,7.484 +20,19-11-2010,2105058.91,0,45.88,3,205.0992811,7.484 +20,26-11-2010,2811634.04,1,46.66,3.039,204.9621,7.484 +20,03-12-2010,2416051.17,0,35.47,3.046,204.8249189,7.484 +20,10-12-2010,2752122.08,0,24.27,3.109,204.6877378,7.484 +20,17-12-2010,2819193.17,0,24.07,3.14,204.6321194,7.484 +20,24-12-2010,3766687.43,0,25.17,3.141,204.6376731,7.484 +20,31-12-2010,1799737.79,1,28.85,3.179,204.6432267,7.484 +20,07-01-2011,1843030.95,0,31.43,3.193,204.6487803,7.343 +20,14-01-2011,1884345.01,0,20.39,3.205,204.7026042,7.343 +20,21-01-2011,1781805.66,0,27.43,3.229,205.0460497,7.343 +20,28-01-2011,1761506.68,0,23.21,3.237,205.3894952,7.343 +20,04-02-2011,2351143.07,0,28.58,3.231,205.7329407,7.343 +20,11-02-2011,2211388.14,1,25.38,3.239,206.0763862,7.343 +20,18-02-2011,2258616.24,0,42.95,3.245,206.3694701,7.343 +20,25-02-2011,1938608.52,0,33.2,3.274,206.6424093,7.343 +20,04-03-2011,2143424.61,0,37.33,3.433,206.9153485,7.343 +20,11-03-2011,1990932.77,0,39.53,3.582,207.1882876,7.343 +20,18-03-2011,1931668.64,0,44.8,3.631,207.4283845,7.343 +20,25-03-2011,1824711.21,0,44.83,3.625,207.6553444,7.343 +20,01-04-2011,1927993.09,0,32.43,3.638,207.8823043,7.287 +20,08-04-2011,2027056.39,0,47.09,3.72,208.1092642,7.287 +20,15-04-2011,2057406.33,0,55,3.821,208.3172811,7.287 +20,22-04-2011,2313861.81,0,52.56,3.892,208.4779405,7.287 +20,29-04-2011,1881788.19,0,62.97,3.962,208.6386,7.287 +20,06-05-2011,2090838.44,0,53.41,4.046,208.7992595,7.287 +20,13-05-2011,2036748.53,0,62.26,4.066,208.9599189,7.287 +20,20-05-2011,1953416.06,0,59.01,4.062,208.7583165,7.287 +20,27-05-2011,1944433.17,0,69.12,3.985,208.556714,7.287 +20,03-06-2011,2182246.69,0,73.51,3.922,208.3551116,7.287 +20,10-06-2011,2135062.04,0,73.64,3.881,208.1535092,7.287 +20,17-06-2011,2065191.27,0,66.41,3.842,208.1265604,7.287 +20,24-06-2011,1950826.32,0,72.4,3.804,208.2306018,7.287 +20,01-07-2011,2053165.41,0,69.66,3.748,208.3346432,7.274 +20,08-07-2011,2123787.79,0,74.69,3.711,208.4386847,7.274 +20,15-07-2011,2039875.75,0,74.88,3.76,208.5309337,7.274 +20,22-07-2011,1950904.84,0,78.89,3.811,208.5937018,7.274 +20,29-07-2011,1858440.92,0,77.47,3.829,208.6564699,7.274 +20,05-08-2011,2189353.63,0,77.8,3.842,208.719238,7.274 +20,12-08-2011,2052246.4,0,73.52,3.812,208.7820061,7.274 +20,19-08-2011,1990017.93,0,71.25,3.747,208.8424359,7.274 +20,26-08-2011,1933577.2,0,70.15,3.704,208.902476,7.274 +20,02-09-2011,2141765.98,0,70.82,3.703,208.9625161,7.274 +20,09-09-2011,2050542.56,1,68.74,3.738,209.0225562,7.274 +20,16-09-2011,1979009.46,0,64.02,3.742,209.1893892,7.274 +20,23-09-2011,1888119.7,0,62.15,3.711,209.4986126,7.274 +20,30-09-2011,1945808.26,0,63.44,3.645,209.807836,7.274 +20,07-10-2011,2135982.79,0,52.42,3.583,210.1170595,7.082 +20,14-10-2011,2010107.68,0,62.54,3.541,210.4027602,7.082 +20,21-10-2011,2104241.9,0,53.69,3.57,210.5473252,7.082 +20,28-10-2011,2065421.52,0,49.36,3.569,210.6918901,7.082 +20,04-11-2011,2284106.6,0,43.88,3.551,210.8364551,7.082 +20,11-11-2011,2269975.85,0,47.27,3.53,210.9810201,7.082 +20,18-11-2011,2169933.82,0,49.3,3.53,211.1847207,7.082 +20,25-11-2011,2906233.25,1,46.38,3.492,211.4120757,7.082 +20,02-12-2011,2298776.83,0,46.32,3.452,211.6394306,7.082 +20,09-12-2011,2546123.78,0,41.64,3.415,211.8667856,7.082 +20,16-12-2011,2762816.65,0,37.16,3.413,212.0685039,7.082 +20,23-12-2011,3555371.03,0,40.19,3.389,212.2360401,7.082 +20,30-12-2011,2043245,1,36.35,3.389,212.4035763,7.082 +20,06-01-2012,1964701.94,0,33.42,3.422,212.5711125,6.961 +20,13-01-2012,1911510.64,0,37.79,3.513,212.7386486,6.961 +20,20-01-2012,1892775.94,0,27.65,3.533,212.8336399,6.961 +20,27-01-2012,1761016.51,0,37.19,3.567,212.9286312,6.961 +20,03-02-2012,2203523.2,0,39.93,3.617,213.0236225,6.961 +20,10-02-2012,2462978.28,1,33.47,3.64,213.1186138,6.961 +20,17-02-2012,2309025.16,0,31.11,3.695,213.2732106,6.961 +20,24-02-2012,2045837.55,0,39.79,3.739,213.4725116,6.961 +20,02-03-2012,2148822.76,0,39.98,3.816,213.6718127,6.961 +20,09-03-2012,2139265.4,0,41.14,3.848,213.8711137,6.961 +20,16-03-2012,2064991.71,0,53.73,3.862,214.0167132,6.961 +20,23-03-2012,1992436.96,0,66.11,3.9,214.0907105,6.961 +20,30-03-2012,2074721.74,0,51.52,3.953,214.1647079,6.961 +20,06-04-2012,2565259.92,0,50.06,3.996,214.2387053,7.139 +20,13-04-2012,2045396.06,0,45.68,4.044,214.3127027,7.139 +20,20-04-2012,1884427.84,0,60.11,4.027,214.3675045,7.139 +20,27-04-2012,1886503.93,0,47.64,4.004,214.4223063,7.139 +20,04-05-2012,2163510.89,0,62.74,3.951,214.4771081,7.139 +20,11-05-2012,2168097.11,0,63.19,3.889,214.5319099,7.139 +20,18-05-2012,2039222.26,0,60.99,3.848,214.5485571,7.139 +20,25-05-2012,2114989,0,70.04,3.798,214.5499425,7.139 +20,01-06-2012,2143126.59,0,73.67,3.742,214.5513278,7.139 +20,08-06-2012,2231962.13,0,62.01,3.689,214.5527132,7.139 +20,15-06-2012,2165160.29,0,71.51,3.62,214.5653243,7.139 +20,22-06-2012,2060588.69,0,76.51,3.564,214.606,7.139 +20,29-06-2012,2055952.61,0,74.15,3.506,214.6466757,7.139 +20,06-07-2012,2358055.3,0,79.2,3.475,214.6873514,7.28 +20,13-07-2012,2134680.12,0,78.27,3.523,214.728027,7.28 +20,20-07-2012,1970170.29,0,76.04,3.567,214.7331351,7.28 +20,27-07-2012,1911559.1,0,74.6,3.647,214.7382432,7.28 +20,03-08-2012,2094515.71,0,74.73,3.654,214.7433514,7.28 +20,10-08-2012,2144245.39,0,75.4,3.722,214.7484595,7.28 +20,17-08-2012,2045061.22,0,69.57,3.807,214.825578,7.28 +20,24-08-2012,2005341.43,0,68.27,3.834,214.9567044,7.28 +20,31-08-2012,2062481.56,0,72.66,3.867,215.0878309,7.28 +20,07-09-2012,2080529.06,1,76.36,3.911,215.2189573,7.28 +20,14-09-2012,2047949.98,0,64.84,3.948,215.3583757,7.28 +20,21-09-2012,2028587.24,0,60.94,4.038,215.5475459,7.28 +20,28-09-2012,2008350.58,0,58.65,3.997,215.7367162,7.28 +20,05-10-2012,2246411.89,0,60.77,3.985,215.9258865,7.293 +20,12-10-2012,2162951.36,0,47.2,4,216.1150568,7.293 +20,19-10-2012,1999363.49,0,56.26,3.969,216.1464699,7.293 +20,26-10-2012,2031650.55,0,60.04,3.882,216.1515902,7.293 +21,05-02-2010,798593.88,0,39.05,2.572,210.7526053,8.324 +21,12-02-2010,809321.44,1,37.77,2.548,210.8979935,8.324 +21,19-02-2010,867283.25,0,39.75,2.514,210.9451605,8.324 +21,26-02-2010,749597.24,0,45.31,2.561,210.9759573,8.324 +21,05-03-2010,747444.32,0,48.61,2.625,211.0067542,8.324 +21,12-03-2010,712312.89,0,57.1,2.667,211.037551,8.324 +21,19-03-2010,727070,0,54.68,2.72,210.8733316,8.324 +21,26-03-2010,686497.53,0,51.66,2.732,210.6766095,8.324 +21,02-04-2010,753664.12,0,64.12,2.719,210.4798874,8.2 +21,09-04-2010,751181.4,0,65.74,2.77,210.2831653,8.2 +21,16-04-2010,716026.51,0,67.87,2.808,210.1495463,8.2 +21,23-04-2010,718780.59,0,64.21,2.795,210.1000648,8.2 +21,30-04-2010,680532.69,0,66.93,2.78,210.0505833,8.2 +21,07-05-2010,744969.42,0,70.87,2.835,210.0011018,8.2 +21,14-05-2010,723559.88,0,73.08,2.854,209.9984585,8.2 +21,21-05-2010,753361.72,0,74.24,2.826,210.2768443,8.2 +21,28-05-2010,755214.26,0,80.94,2.759,210.5552301,8.2 +21,04-06-2010,806012.48,0,82.68,2.705,210.833616,8.2 +21,11-06-2010,784305.55,0,83.51,2.668,211.1120018,8.2 +21,18-06-2010,785104.29,0,86.18,2.637,211.1096543,8.2 +21,25-06-2010,769848.75,0,87.01,2.653,210.9950134,8.2 +21,02-07-2010,711470.8,0,82.29,2.669,210.8803726,8.099 +21,09-07-2010,714677.47,0,81.67,2.642,210.7657317,8.099 +21,16-07-2010,755098.41,0,85.61,2.623,210.7577954,8.099 +21,23-07-2010,765823.48,0,87.17,2.608,210.8921319,8.099 +21,30-07-2010,715876.27,0,83.59,2.64,211.0264684,8.099 +21,06-08-2010,739279.19,0,90.3,2.627,211.1608049,8.099 +21,13-08-2010,793589.18,0,89.65,2.692,211.2951413,8.099 +21,20-08-2010,848873.28,0,89.58,2.664,211.2596586,8.099 +21,27-08-2010,855882.57,0,86.2,2.619,211.2241759,8.099 +21,03-09-2010,727772.8,0,82.57,2.577,211.1886931,8.099 +21,10-09-2010,674055.81,1,79.3,2.565,211.1532104,8.099 +21,17-09-2010,684340.86,0,83.03,2.582,211.1806415,8.099 +21,24-09-2010,671688.06,0,80.79,2.624,211.2552578,8.099 +21,01-10-2010,677158.39,0,70.28,2.603,211.3298742,8.163 +21,08-10-2010,680579.49,0,65.76,2.633,211.4044906,8.163 +21,15-10-2010,693412.05,0,68.61,2.72,211.4713286,8.163 +21,22-10-2010,710668.45,0,70.72,2.725,211.5187208,8.163 +21,29-10-2010,731756.65,0,67.51,2.716,211.5661131,8.163 +21,05-11-2010,719888.76,0,58.71,2.689,211.6135053,8.163 +21,12-11-2010,735796.38,0,60.95,2.728,211.6608975,8.163 +21,19-11-2010,756288.89,0,51.71,2.771,211.5470304,8.163 +21,26-11-2010,1245628.61,1,62.96,2.735,211.4062867,8.163 +21,03-12-2010,829210.73,0,50.43,2.708,211.265543,8.163 +21,10-12-2010,943891.64,0,46.35,2.843,211.1247993,8.163 +21,17-12-2010,1147556.83,0,48.63,2.869,211.0645458,8.163 +21,24-12-2010,1587257.78,0,51.29,2.886,211.0646599,8.163 +21,31-12-2010,672903.23,1,47.19,2.943,211.064774,8.163 +21,07-01-2011,629152.06,0,44.24,2.976,211.0648881,8.028 +21,14-01-2011,650789.13,0,34.14,2.983,211.1176713,8.028 +21,21-01-2011,663941.73,0,42.72,3.016,211.4864691,8.028 +21,28-01-2011,649878.29,0,44.04,3.01,211.8552668,8.028 +21,04-02-2011,596218.24,0,36.33,2.989,212.2240646,8.028 +21,11-02-2011,771908.51,1,34.61,3.022,212.5928624,8.028 +21,18-02-2011,884701.92,0,59.87,3.045,212.9033115,8.028 +21,25-02-2011,768313.85,0,61.27,3.065,213.190421,8.028 +21,04-03-2011,796277.72,0,59.52,3.288,213.4775305,8.028 +21,11-03-2011,763479.9,0,54.69,3.459,213.7646401,8.028 +21,18-03-2011,793569,0,63.26,3.488,214.0156238,8.028 +21,25-03-2011,753711.32,0,70.33,3.473,214.2521573,8.028 +21,01-04-2011,732056.37,0,56.36,3.524,214.4886908,7.931 +21,08-04-2011,744782.89,0,68.62,3.622,214.7252242,7.931 +21,15-04-2011,768390.05,0,71.01,3.743,214.9420631,7.931 +21,22-04-2011,801302.01,0,70.79,3.807,215.1096657,7.931 +21,29-04-2011,783250.75,0,70.19,3.81,215.2772683,7.931 +21,06-05-2011,718898.33,0,61.87,3.906,215.4448709,7.931 +21,13-05-2011,754236.7,0,75.04,3.899,215.6124735,7.931 +21,20-05-2011,744836.56,0,68.36,3.907,215.3834778,7.931 +21,27-05-2011,744389.81,0,76.86,3.786,215.1544822,7.931 +21,03-06-2011,773878.58,0,83.82,3.699,214.9254865,7.931 +21,10-06-2011,794397.89,0,84.71,3.648,214.6964908,7.931 +21,17-06-2011,823220.43,0,87.54,3.637,214.6513538,7.931 +21,24-06-2011,771298.98,0,85.72,3.594,214.7441108,7.931 +21,01-07-2011,784639.12,0,87.57,3.524,214.8368678,7.852 +21,08-07-2011,734099.4,0,89.16,3.48,214.9296249,7.852 +21,15-07-2011,728311.15,0,91.05,3.575,215.0134426,7.852 +21,22-07-2011,784490.67,0,90.27,3.651,215.0749122,7.852 +21,29-07-2011,751167.12,0,91.56,3.682,215.1363819,7.852 +21,05-08-2011,783614.89,0,94.22,3.684,215.1978515,7.852 +21,12-08-2011,776933.37,0,92.32,3.638,215.2593211,7.852 +21,19-08-2011,855546.5,0,90.11,3.554,215.3229307,7.852 +21,26-08-2011,821127.53,0,92.07,3.523,215.386897,7.852 +21,02-09-2011,705557.8,0,91.94,3.533,215.4508632,7.852 +21,09-09-2011,653989.65,1,78.87,3.546,215.5148295,7.852 +21,16-09-2011,653525.84,0,80.62,3.526,215.6944378,7.852 +21,23-09-2011,681913.29,0,75.68,3.467,216.0282356,7.852 +21,30-09-2011,651970.48,0,78.91,3.355,216.3620333,7.852 +21,07-10-2011,663452.46,0,71.64,3.285,216.6958311,7.441 +21,14-10-2011,671379.44,0,69.79,3.274,217.0048261,7.441 +21,21-10-2011,729036.06,0,65.16,3.353,217.1650042,7.441 +21,28-10-2011,738812,0,65.46,3.372,217.3251824,7.441 +21,04-11-2011,767358.37,0,56.01,3.332,217.4853605,7.441 +21,11-11-2011,757369.87,0,59.8,3.297,217.6455387,7.441 +21,18-11-2011,737014.09,0,61.9,3.308,217.8670218,7.441 +21,25-11-2011,1219263.4,1,56.43,3.236,218.1130269,7.441 +21,02-12-2011,793184.25,0,48.72,3.172,218.3590319,7.441 +21,09-12-2011,897747.13,0,41.44,3.158,218.605037,7.441 +21,16-12-2011,1027584.51,0,50.56,3.159,218.8217928,7.441 +21,23-12-2011,1384552.17,0,46.54,3.112,218.9995495,7.441 +21,30-12-2011,804362.36,1,45.16,3.129,219.1773063,7.441 +21,06-01-2012,640181.86,0,48.1,3.157,219.355063,7.057 +21,13-01-2012,631181.25,0,45,3.261,219.5328198,7.057 +21,20-01-2012,651178.2,0,52.21,3.268,219.6258417,7.057 +21,27-01-2012,611258.71,0,50.79,3.29,219.7188636,7.057 +21,03-02-2012,680725.43,0,55.83,3.36,219.8118854,7.057 +21,10-02-2012,770652.79,1,46.52,3.409,219.9049073,7.057 +21,17-02-2012,834663.52,0,45.03,3.51,220.0651993,7.057 +21,24-02-2012,747099.07,0,54.81,3.555,220.275944,7.057 +21,02-03-2012,764385.4,0,59.3,3.63,220.4866886,7.057 +21,09-03-2012,755084.4,0,57.16,3.669,220.6974332,7.057 +21,16-03-2012,767338.32,0,63.39,3.734,220.8498468,7.057 +21,23-03-2012,729759.97,0,62.96,3.787,220.9244858,7.057 +21,30-03-2012,724798.76,0,67.87,3.845,220.9991248,7.057 +21,06-04-2012,761956.58,0,69.02,3.891,221.0737638,6.891 +21,13-04-2012,769319.04,0,69.03,3.891,221.1484028,6.891 +21,20-04-2012,734858.91,0,66.97,3.877,221.2021074,6.891 +21,27-04-2012,674829.58,0,69.21,3.814,221.255812,6.891 +21,04-05-2012,697645.32,0,77.53,3.749,221.3095166,6.891 +21,11-05-2012,649945.54,0,74.14,3.688,221.3632212,6.891 +21,18-05-2012,700554.16,0,72.42,3.63,221.380331,6.891 +21,25-05-2012,722891.24,0,79.49,3.561,221.3828029,6.891 +21,01-06-2012,695439.83,0,79.24,3.501,221.3852748,6.891 +21,08-06-2012,707895.72,0,79.47,3.452,221.3877467,6.891 +21,15-06-2012,727049.04,0,81.51,3.393,221.4009901,6.891 +21,22-06-2012,735870,0,81.78,3.346,221.4411622,6.891 +21,29-06-2012,716341.39,0,88.05,3.286,221.4813343,6.891 +21,06-07-2012,693013.59,0,85.26,3.227,221.5215064,6.565 +21,13-07-2012,668132.36,0,82.51,3.256,221.5616784,6.565 +21,20-07-2012,691200.33,0,84.25,3.311,221.5701123,6.565 +21,27-07-2012,677789.14,0,88.09,3.407,221.5785461,6.565 +21,03-08-2012,693785.85,0,91.57,3.417,221.5869799,6.565 +21,10-08-2012,700272.01,0,89.57,3.494,221.5954138,6.565 +21,17-08-2012,751963.81,0,85.55,3.571,221.6751459,6.565 +21,24-08-2012,802003.61,0,77.72,3.62,221.8083518,6.565 +21,31-08-2012,763867.59,0,83.58,3.638,221.9415576,6.565 +21,07-09-2012,642827.29,1,88.4,3.73,222.0747635,6.565 +21,14-09-2012,628494.63,0,76.1,3.717,222.2174395,6.565 +21,21-09-2012,667151.46,0,71.54,3.721,222.4169362,6.565 +21,28-09-2012,647097.65,0,80.38,3.666,222.6164329,6.565 +21,05-10-2012,651768.91,0,70.28,3.617,222.8159296,6.17 +21,12-10-2012,653043.44,0,61.53,3.601,223.0154263,6.17 +21,19-10-2012,641368.14,0,68.52,3.594,223.0598077,6.17 +21,26-10-2012,675202.87,0,70.5,3.506,223.0783366,6.17 +22,05-02-2010,1033017.37,0,24.36,2.788,135.3524608,8.283 +22,12-02-2010,1022571.25,1,28.14,2.771,135.4113076,8.283 +22,19-02-2010,988467.61,0,31.96,2.747,135.4657781,8.283 +22,26-02-2010,899761.48,0,35.98,2.753,135.5195191,8.283 +22,05-03-2010,1009201.24,0,36.82,2.766,135.5732602,8.283 +22,12-03-2010,967187.37,0,43.43,2.805,135.6270013,8.283 +22,19-03-2010,966145.09,0,46.03,2.834,135.6682247,8.283 +22,26-03-2010,1012075.12,0,48.56,2.831,135.7073618,8.283 +22,02-04-2010,1177340.99,0,44.96,2.826,135.7464988,8.348 +22,09-04-2010,1033171.07,0,57.06,2.849,135.7856359,8.348 +22,16-04-2010,1000968.67,0,51.14,2.885,135.82725,8.348 +22,23-04-2010,969594.47,0,51.04,2.895,135.8721667,8.348 +22,30-04-2010,977683.06,0,50.96,2.935,135.9170833,8.348 +22,07-05-2010,1052973.28,0,63.81,2.981,135.962,8.348 +22,14-05-2010,973585.33,0,50.99,2.983,136.010394,8.348 +22,21-05-2010,979977.89,0,59.99,2.961,136.0796521,8.348 +22,28-05-2010,1103740.4,0,65.64,2.906,136.1489101,8.348 +22,04-06-2010,1095539.13,0,69.49,2.857,136.2181682,8.348 +22,11-06-2010,1061196.47,0,65.01,2.83,136.2874263,8.348 +22,18-06-2010,1052895.25,0,67.13,2.805,136.3243393,8.348 +22,25-06-2010,1095020.33,0,74.37,2.81,136.3483143,8.348 +22,02-07-2010,1120259.71,0,72.88,2.815,136.3722893,8.433 +22,09-07-2010,1092654.26,0,79.22,2.806,136.3962643,8.433 +22,16-07-2010,988392.99,0,76.3,2.796,136.4179827,8.433 +22,23-07-2010,974123.2,0,76.91,2.784,136.4366924,8.433 +22,30-07-2010,970773.64,0,76.35,2.792,136.4554021,8.433 +22,06-08-2010,1010326.14,0,74.37,2.792,136.4741118,8.433 +22,13-08-2010,993097.43,0,74.75,2.81,136.4928214,8.433 +22,20-08-2010,1017045.44,0,73.21,2.796,136.5249182,8.433 +22,27-08-2010,1081420.96,0,68.99,2.77,136.557015,8.433 +22,03-09-2010,1074535.88,0,75.85,2.735,136.5891118,8.433 +22,10-09-2010,924174.4,1,68.6,2.717,136.6212085,8.433 +22,17-09-2010,918285.97,0,62.49,2.716,136.6338071,8.433 +22,24-09-2010,902779.25,0,65.14,2.718,136.6317821,8.433 +22,01-10-2010,905987.17,0,69.31,2.717,136.6297571,8.572 +22,08-10-2010,1015051.62,0,56.32,2.776,136.6277321,8.572 +22,15-10-2010,954401.46,0,55.23,2.878,136.6401935,8.572 +22,22-10-2010,960998.52,0,50.24,2.919,136.688871,8.572 +22,29-10-2010,1025766.27,0,57.73,2.938,136.7375484,8.572 +22,05-11-2010,1006888.16,0,44.34,2.938,136.7862258,8.572 +22,12-11-2010,1043698.64,0,44.42,2.961,136.8349032,8.572 +22,19-11-2010,985896.44,0,48.62,3.03,136.7715714,8.572 +22,26-11-2010,1564502.26,1,44.61,3.07,136.6895714,8.572 +22,03-12-2010,1230514.58,0,39.42,3.065,136.6075714,8.572 +22,10-12-2010,1367202.84,0,28.43,3.132,136.5255714,8.572 +22,17-12-2010,1527682.99,0,30.46,3.139,136.5292811,8.572 +22,24-12-2010,1962445.04,0,29.76,3.15,136.597273,8.572 +22,31-12-2010,774262.28,1,28.49,3.177,136.665265,8.572 +22,07-01-2011,873954.7,0,32.56,3.193,136.7332569,8.458 +22,14-01-2011,807535.52,0,24.76,3.215,136.803477,8.458 +22,21-01-2011,855001.02,0,26.8,3.232,136.8870657,8.458 +22,28-01-2011,799369.15,0,20.61,3.243,136.9706544,8.458 +22,04-02-2011,946060.98,0,26.39,3.24,137.0542431,8.458 +22,11-02-2011,1009206.33,1,28.89,3.255,137.1378318,8.458 +22,18-02-2011,975964.86,0,35.34,3.263,137.2511849,8.458 +22,25-02-2011,911245.43,0,30.23,3.281,137.3764439,8.458 +22,04-03-2011,997353.15,0,33.52,3.437,137.5017028,8.458 +22,11-03-2011,944587.23,0,41.42,3.6,137.6269617,8.458 +22,18-03-2011,926427.12,0,43.38,3.634,137.7398929,8.458 +22,25-03-2011,933528.39,0,38.77,3.624,137.8478929,8.458 +22,01-04-2011,951588.37,0,36.04,3.638,137.9558929,8.252 +22,08-04-2011,969046.69,0,44.42,3.72,138.0638929,8.252 +22,15-04-2011,1008557.04,0,48.88,3.823,138.1646952,8.252 +22,22-04-2011,1152781.9,0,47.76,3.919,138.2475036,8.252 +22,29-04-2011,926133.8,0,57.2,3.988,138.3303119,8.252 +22,06-05-2011,1032076.06,0,53.63,4.078,138.4131202,8.252 +22,13-05-2011,1001558.74,0,57.71,4.095,138.4959286,8.252 +22,20-05-2011,970307.83,0,58.56,4.101,138.587106,8.252 +22,27-05-2011,1021568.34,0,62.59,4.034,138.6782834,8.252 +22,03-06-2011,1125169.92,0,70.09,3.973,138.7694608,8.252 +22,10-06-2011,1060868.49,0,69.53,3.924,138.8606382,8.252 +22,17-06-2011,1042454.61,0,63.97,3.873,139.0028333,8.252 +22,24-06-2011,1012584.2,0,68.53,3.851,139.1832917,8.252 +22,01-07-2011,1077491.68,0,70.8,3.815,139.36375,8.023 +22,08-07-2011,1017050.65,0,74.22,3.784,139.5442083,8.023 +22,15-07-2011,961953.57,0,75.2,3.827,139.7006325,8.023 +22,22-07-2011,964683.8,0,77.79,3.882,139.7969712,8.023 +22,29-07-2011,944958.69,0,75.32,3.898,139.8933099,8.023 +22,05-08-2011,983232.96,0,75.33,3.903,139.9896486,8.023 +22,12-08-2011,991779.2,0,74.69,3.88,140.0859873,8.023 +22,19-08-2011,973004.91,0,71.3,3.82,140.1289205,8.023 +22,26-08-2011,1181815.31,0,72.22,3.796,140.1629528,8.023 +22,02-09-2011,912762.76,0,69.16,3.784,140.196985,8.023 +22,09-09-2011,1004434.54,1,69.14,3.809,140.2310173,8.023 +22,16-09-2011,937420.65,0,68.08,3.809,140.2735,8.023 +22,23-09-2011,899834.75,0,62.36,3.758,140.32725,8.023 +22,30-09-2011,953314.16,0,69.78,3.684,140.381,8.023 +22,07-10-2011,993436.67,0,56.44,3.633,140.43475,7.706 +22,14-10-2011,944337.32,0,62.63,3.583,140.4784194,7.706 +22,21-10-2011,981567.22,0,59.3,3.618,140.4616048,7.706 +22,28-10-2011,1099351.68,0,49.31,3.604,140.4447903,7.706 +22,04-11-2011,1106575.59,0,42.81,3.586,140.4279758,7.706 +22,11-11-2011,1051740.29,0,47.8,3.57,140.4111613,7.706 +22,18-11-2011,1007579.44,0,50.62,3.571,140.4127857,7.706 +22,25-11-2011,1535857.49,1,46.28,3.536,140.4217857,7.706 +22,02-12-2011,1167621.14,0,49.11,3.501,140.4307857,7.706 +22,09-12-2011,1308967.44,0,45.35,3.47,140.4397857,7.706 +22,16-12-2011,1453153.33,0,39.11,3.445,140.4700795,7.706 +22,23-12-2011,1863195.68,0,39.83,3.413,140.528765,7.706 +22,30-12-2011,982661.14,1,36.28,3.402,140.5874505,7.706 +22,06-01-2012,895358.2,0,34.61,3.439,140.6461359,7.503 +22,13-01-2012,855437.57,0,39,3.523,140.7048214,7.503 +22,20-01-2012,897027.44,0,29.16,3.542,140.8086118,7.503 +22,27-01-2012,786459.23,0,35.68,3.568,140.9124021,7.503 +22,03-02-2012,958487.75,0,40.58,3.633,141.0161924,7.503 +22,10-02-2012,1034448.07,1,35.68,3.655,141.1199827,7.503 +22,17-02-2012,1004749.41,0,36.25,3.703,141.2140357,7.503 +22,24-02-2012,912958.95,0,39,3.751,141.3007857,7.503 +22,02-03-2012,974866.65,0,37.47,3.827,141.3875357,7.503 +22,09-03-2012,991127.01,0,41.72,3.876,141.4742857,7.503 +22,16-03-2012,966780.01,0,46.06,3.867,141.55478,7.503 +22,23-03-2012,992774.4,0,54.68,3.889,141.6269332,7.503 +22,30-03-2012,965769.93,0,46.4,3.921,141.6990864,7.503 +22,06-04-2012,1197489.66,0,46.38,3.957,141.7712396,7.671 +22,13-04-2012,939118.24,0,49.89,4.025,141.8433929,7.671 +22,20-04-2012,1000342.87,0,58.81,4.046,141.9015262,7.671 +22,27-04-2012,922539.94,0,51.42,4.023,141.9596595,7.671 +22,04-05-2012,1005083.31,0,50.75,3.991,142.0177929,7.671 +22,11-05-2012,997868.63,0,56.72,3.947,142.0759262,7.671 +22,18-05-2012,986612.02,0,61.9,3.899,142.0970115,7.671 +22,25-05-2012,1047297.38,0,62.39,3.85,142.1032776,7.671 +22,01-06-2012,1102857.37,0,70.01,3.798,142.1095438,7.671 +22,08-06-2012,1061134.37,0,61.71,3.746,142.1158099,7.671 +22,15-06-2012,1061219.19,0,66.56,3.683,142.1292548,7.671 +22,22-06-2012,1112449.3,0,70.61,3.629,142.1606464,7.671 +22,29-06-2012,1053881.78,0,70.99,3.577,142.1920381,7.671 +22,06-07-2012,1097786.14,0,77.41,3.538,142.2234298,7.753 +22,13-07-2012,971361.38,0,75.81,3.561,142.2548214,7.753 +22,20-07-2012,991969.37,0,76.57,3.61,142.2337569,7.753 +22,27-07-2012,925731.21,0,73.52,3.701,142.2126924,7.753 +22,03-08-2012,1007257.83,0,72.99,3.698,142.1916279,7.753 +22,10-08-2012,973812.79,0,76.74,3.772,142.1705634,7.753 +22,17-08-2012,981273.26,0,74.92,3.84,142.2157385,7.753 +22,24-08-2012,1060906.75,0,70.42,3.874,142.3105933,7.753 +22,31-08-2012,1022270.86,0,71.93,3.884,142.4054482,7.753 +22,07-09-2012,996628.8,1,73.3,3.921,142.500303,7.753 +22,14-09-2012,918049.28,0,66.42,3.988,142.5938833,7.753 +22,21-09-2012,921612.53,0,63.38,4.056,142.6798167,7.753 +22,28-09-2012,976479.51,0,62.17,4.018,142.76575,7.753 +22,05-10-2012,1009887.36,0,62.09,4.027,142.8516833,7.543 +22,12-10-2012,1004039.84,0,54.18,4.029,142.9376167,7.543 +22,19-10-2012,978027.95,0,55.28,4,142.8633629,7.543 +22,26-10-2012,1094422.69,0,57.58,3.917,142.7624113,7.543 +23,05-02-2010,1364721.58,0,15.25,2.788,131.5279032,5.892 +23,12-02-2010,1380892.08,1,18.75,2.771,131.5866129,5.892 +23,19-02-2010,1319588.04,0,26.7,2.747,131.637,5.892 +23,26-02-2010,1198709.65,0,32.68,2.753,131.686,5.892 +23,05-03-2010,1311175.93,0,33.15,2.766,131.735,5.892 +23,12-03-2010,1408082.96,0,36.07,2.805,131.784,5.892 +23,19-03-2010,1229008.32,0,43.01,2.834,131.8242903,5.892 +23,26-03-2010,1310701.8,0,38.59,2.831,131.863129,5.892 +23,02-04-2010,1556627.62,0,40.5,2.826,131.9019677,5.435 +23,09-04-2010,1264434.7,0,56.82,2.849,131.9408065,5.435 +23,16-04-2010,1288823.72,0,44.25,2.885,131.9809,5.435 +23,23-04-2010,1315023.08,0,46.4,2.895,132.0226667,5.435 +23,30-04-2010,1259414.52,0,45.47,2.935,132.0644333,5.435 +23,07-05-2010,1365552.28,0,61.04,2.981,132.1062,5.435 +23,14-05-2010,1303055.09,0,45.33,2.983,132.152129,5.435 +23,21-05-2010,1327424.28,0,57.94,2.961,132.2230323,5.435 +23,28-05-2010,1571158.56,0,69.26,2.906,132.2939355,5.435 +23,04-06-2010,1514435.51,0,64.94,2.857,132.3648387,5.435 +23,11-06-2010,1439432.06,0,58.35,2.83,132.4357419,5.435 +23,18-06-2010,1507708.93,0,60.29,2.805,132.4733333,5.435 +23,25-06-2010,1415204.88,0,69.83,2.81,132.4976,5.435 +23,02-07-2010,1549113.18,0,64.76,2.815,132.5218667,5.326 +23,09-07-2010,1417535.78,0,77.16,2.806,132.5461333,5.326 +23,16-07-2010,1413124.11,0,73.94,2.796,132.5667742,5.326 +23,23-07-2010,1333634.45,0,70.2,2.784,132.5825806,5.326 +23,30-07-2010,1319773.55,0,69.71,2.792,132.5983871,5.326 +23,06-08-2010,1417013.07,0,70.03,2.792,132.6141935,5.326 +23,13-08-2010,1346345.97,0,67.43,2.81,132.63,5.326 +23,20-08-2010,1439901.05,0,68.65,2.796,132.6616129,5.326 +23,27-08-2010,1584623.36,0,63.25,2.77,132.6932258,5.326 +23,03-09-2010,1405119.23,0,72.91,2.735,132.7248387,5.326 +23,10-09-2010,1272842.85,1,63.21,2.717,132.7564516,5.326 +23,17-09-2010,1159132.58,0,55.3,2.716,132.7670667,5.326 +23,24-09-2010,1099055.65,0,57.75,2.718,132.7619333,5.326 +23,01-10-2010,1129909.44,0,62.07,2.717,132.7568,5.287 +23,08-10-2010,1179851.68,0,50.75,2.776,132.7516667,5.287 +23,15-10-2010,1119809.71,0,45.55,2.878,132.7633548,5.287 +23,22-10-2010,1147503.92,0,43.19,2.919,132.8170968,5.287 +23,29-10-2010,1112871.23,0,48.68,2.938,132.8708387,5.287 +23,05-11-2010,1203119.96,0,36.6,2.938,132.9245806,5.287 +23,12-11-2010,1387953.75,0,35.59,2.961,132.9783226,5.287 +23,19-11-2010,1314994.32,0,41.66,3.03,132.9172,5.287 +23,26-11-2010,2072685.05,1,34.95,3.07,132.8369333,5.287 +23,03-12-2010,1617025.41,0,34.3,3.065,132.7566667,5.287 +23,10-12-2010,1872365.99,0,20.12,3.132,132.6764,5.287 +23,17-12-2010,2238573.48,0,23.05,3.139,132.6804516,5.287 +23,24-12-2010,2734277.1,0,22.96,3.15,132.7477419,5.287 +23,31-12-2010,1169773.85,1,19.05,3.177,132.8150323,5.287 +23,07-01-2011,1122034.48,0,27.81,3.193,132.8823226,5.114 +23,14-01-2011,1016756.1,0,18.2,3.215,132.9510645,5.114 +23,21-01-2011,1110706.06,0,15.58,3.232,133.0285161,5.114 +23,28-01-2011,1083657.61,0,10.91,3.243,133.1059677,5.114 +23,04-02-2011,1159438.53,0,14.5,3.24,133.1834194,5.114 +23,11-02-2011,1249786.4,1,21.52,3.255,133.260871,5.114 +23,18-02-2011,1369971.57,0,26.6,3.263,133.3701429,5.114 +23,25-02-2011,1206917.2,0,17,3.281,133.4921429,5.114 +23,04-03-2011,1301185.28,0,20.67,3.437,133.6141429,5.114 +23,11-03-2011,1042043.55,0,29.36,3.6,133.7361429,5.114 +23,18-03-2011,1203682.62,0,37.28,3.634,133.8492258,5.114 +23,25-03-2011,1148624.83,0,29.11,3.624,133.9587419,5.114 +23,01-04-2011,1182694.95,0,29.44,3.638,134.0682581,4.781 +23,08-04-2011,1248901.98,0,36.74,3.72,134.1777742,4.781 +23,15-04-2011,1263680.51,0,45.51,3.823,134.2784667,4.781 +23,22-04-2011,1447301.24,0,39.62,3.919,134.3571,4.781 +23,29-04-2011,1173307.4,0,54.2,3.988,134.4357333,4.781 +23,06-05-2011,1359921.13,0,50.07,4.078,134.5143667,4.781 +23,13-05-2011,1254914.87,0,55.12,4.095,134.593,4.781 +23,20-05-2011,1337617.55,0,56.67,4.101,134.6803871,4.781 +23,27-05-2011,1361945.18,0,63.27,4.034,134.7677742,4.781 +23,03-06-2011,1562161.97,0,67.21,3.973,134.8551613,4.781 +23,10-06-2011,1447028.06,0,65.23,3.924,134.9425484,4.781 +23,17-06-2011,1470520.83,0,61.06,3.873,135.0837333,4.781 +23,24-06-2011,1434036.18,0,63.8,3.851,135.2652667,4.781 +23,01-07-2011,1492507.44,0,65.65,3.815,135.4468,4.584 +23,08-07-2011,1379488.05,0,69.92,3.784,135.6283333,4.584 +23,15-07-2011,1360520.56,0,69.8,3.827,135.7837419,4.584 +23,22-07-2011,1362144,0,76.74,3.882,135.8738387,4.584 +23,29-07-2011,1319767.55,0,69.55,3.898,135.9639355,4.584 +23,05-08-2011,1416344.68,0,69.53,3.903,136.0540323,4.584 +23,12-08-2011,1380952.05,0,69.86,3.88,136.144129,4.584 +23,19-08-2011,1453416.53,0,67.09,3.82,136.183129,4.584 +23,26-08-2011,1637266.29,0,67.04,3.796,136.2136129,4.584 +23,02-09-2011,1464295.69,0,65.33,3.784,136.2440968,4.584 +23,09-09-2011,1423289.9,1,66.04,3.809,136.2745806,4.584 +23,16-09-2011,1253329.17,0,60.52,3.809,136.3145,4.584 +23,23-09-2011,1289082.81,0,57.14,3.758,136.367,4.584 +23,30-09-2011,1275597.85,0,64.76,3.684,136.4195,4.584 +23,07-10-2011,1463501.99,0,49,3.633,136.472,4.42 +23,14-10-2011,1257778.34,0,56.79,3.583,136.5150968,4.42 +23,21-10-2011,1441032.59,0,52.12,3.618,136.5017742,4.42 +23,28-10-2011,1407191.96,0,42.57,3.604,136.4884516,4.42 +23,04-11-2011,1428436.33,0,39.18,3.586,136.475129,4.42 +23,11-11-2011,1436940.78,0,44.04,3.57,136.4618065,4.42 +23,18-11-2011,1345631.96,0,45.48,3.571,136.4666667,4.42 +23,25-11-2011,2057059.53,1,35.23,3.536,136.4788,4.42 +23,02-12-2011,1552886.59,0,43.6,3.501,136.4909333,4.42 +23,09-12-2011,1841173.6,0,36.4,3.47,136.5030667,4.42 +23,16-12-2011,2173621.2,0,32.99,3.445,136.5335161,4.42 +23,23-12-2011,2587953.32,0,27.8,3.413,136.5883871,4.42 +23,30-12-2011,1213486.95,1,22.3,3.402,136.6432581,4.42 +23,06-01-2012,1150662.55,0,24.29,3.439,136.698129,4.261 +23,13-01-2012,1031451.35,0,28.49,3.523,136.753,4.261 +23,20-01-2012,1146992.13,0,15.33,3.542,136.8564194,4.261 +23,27-01-2012,1037476.38,0,25.71,3.568,136.9598387,4.261 +23,03-02-2012,1261872.67,0,29.71,3.633,137.0632581,4.261 +23,10-02-2012,1358444.07,1,26.6,3.655,137.1666774,4.261 +23,17-02-2012,1365546.69,0,27.01,3.703,137.2583103,4.261 +23,24-02-2012,1272948.27,0,31.12,3.751,137.3411034,4.261 +23,02-03-2012,1322852.2,0,25.91,3.827,137.4238966,4.261 +23,09-03-2012,1292724.9,0,33.11,3.876,137.5066897,4.261 +23,16-03-2012,1258364.31,0,41.19,3.867,137.5843871,4.261 +23,23-03-2012,1288154.1,0,57.82,3.889,137.6552903,4.261 +23,30-03-2012,1261964.96,0,36.71,3.921,137.7261935,4.261 +23,06-04-2012,1604605.69,0,37.43,3.957,137.7970968,4.125 +23,13-04-2012,1231752.54,0,41.81,4.025,137.868,4.125 +23,20-04-2012,1287899.41,0,56.55,4.046,137.9230667,4.125 +23,27-04-2012,1277758.76,0,44.62,4.023,137.9781333,4.125 +23,04-05-2012,1317379.68,0,45.88,3.991,138.0332,4.125 +23,11-05-2012,1321914.34,0,52.9,3.947,138.0882667,4.125 +23,18-05-2012,1332952.47,0,58.42,3.899,138.1065806,4.125 +23,25-05-2012,1552934.64,0,66.43,3.85,138.1101935,4.125 +23,01-06-2012,1476144.34,0,66.22,3.798,138.1138065,4.125 +23,08-06-2012,1568048.54,0,56.82,3.746,138.1174194,4.125 +23,15-06-2012,1543667.68,0,64.73,3.683,138.1295333,4.125 +23,22-06-2012,1522042.57,0,71.82,3.629,138.1629,4.125 +23,29-06-2012,1451782.16,0,64.23,3.577,138.1962667,4.125 +23,06-07-2012,1545370.16,0,70.86,3.538,138.2296333,4.156 +23,13-07-2012,1384921.63,0,69.19,3.561,138.263,4.156 +23,20-07-2012,1381339.23,0,71.13,3.61,138.2331935,4.156 +23,27-07-2012,1322932.36,0,69.31,3.701,138.2033871,4.156 +23,03-08-2012,1416926.31,0,71.51,3.698,138.1735806,4.156 +23,10-08-2012,1436311.76,0,71.12,3.772,138.1437742,4.156 +23,17-08-2012,1510131.45,0,69.97,3.84,138.1857097,4.156 +23,24-08-2012,1702220.96,0,64.63,3.874,138.2814516,4.156 +23,31-08-2012,1577468.78,0,68.34,3.884,138.3771935,4.156 +23,07-09-2012,1427162.26,1,66.74,3.921,138.4729355,4.156 +23,14-09-2012,1279041.64,0,61.37,3.988,138.5673,4.156 +23,21-09-2012,1338627.55,0,56.8,4.056,138.6534,4.156 +23,28-09-2012,1319035.06,0,53.71,4.018,138.7395,4.156 +23,05-10-2012,1464616.59,0,56.65,4.027,138.8256,4.145 +23,12-10-2012,1412925.25,0,48.1,4.029,138.9117,4.145 +23,19-10-2012,1363155.77,0,47.89,4,138.8336129,4.145 +23,26-10-2012,1347454.59,0,50.56,3.917,138.7281613,4.145 +24,05-02-2010,1388725.63,0,22.43,2.954,131.5279032,8.326 +24,12-02-2010,1414107.1,1,25.94,2.94,131.5866129,8.326 +24,19-02-2010,1385362.49,0,31.05,2.909,131.637,8.326 +24,26-02-2010,1158722.74,0,33.98,2.91,131.686,8.326 +24,05-03-2010,1412387.37,0,36.73,2.919,131.735,8.326 +24,12-03-2010,1309340.16,0,42.31,2.938,131.784,8.326 +24,19-03-2010,1222511.29,0,46.09,2.96,131.8242903,8.326 +24,26-03-2010,1258311.56,0,48.87,2.963,131.863129,8.326 +24,02-04-2010,1478321.26,0,45.22,2.957,131.9019677,8.211 +24,09-04-2010,1379579.63,0,62.06,2.992,131.9408065,8.211 +24,16-04-2010,1268266.72,0,51.08,3.01,131.9809,8.211 +24,23-04-2010,1264117.01,0,51.07,3.021,132.0226667,8.211 +24,30-04-2010,1259877.19,0,51.48,3.042,132.0644333,8.211 +24,07-05-2010,1409705.03,0,66.65,3.095,132.1062,8.211 +24,14-05-2010,1346783.35,0,51.31,3.112,132.152129,8.211 +24,21-05-2010,1283482.85,0,60.44,3.096,132.2230323,8.211 +24,28-05-2010,1473868.15,0,69.59,3.046,132.2939355,8.211 +24,04-06-2010,1566668.91,0,71.99,3.006,132.3648387,8.211 +24,11-06-2010,1375458.21,0,64.84,2.972,132.4357419,8.211 +24,18-06-2010,1354168.18,0,67.17,2.942,132.4733333,8.211 +24,25-06-2010,1399073.75,0,74.9,2.958,132.4976,8.211 +24,02-07-2010,1563387.94,0,71.12,2.958,132.5218667,8.117 +24,09-07-2010,1665502.55,0,79.05,2.94,132.5461333,8.117 +24,16-07-2010,1418697.05,0,76.56,2.933,132.5667742,8.117 +24,23-07-2010,1333740.35,0,75.27,2.924,132.5825806,8.117 +24,30-07-2010,1387517.63,0,75.91,2.932,132.5983871,8.117 +24,06-08-2010,1442819.28,0,74.54,2.942,132.6141935,8.117 +24,13-08-2010,1384243.75,0,74.17,2.923,132.63,8.117 +24,20-08-2010,1375307.54,0,72.17,2.913,132.6616129,8.117 +24,27-08-2010,1350059.35,0,67,2.885,132.6932258,8.117 +24,03-09-2010,1366381.6,0,73.52,2.86,132.7248387,8.117 +24,10-09-2010,1474498.59,1,67.11,2.837,132.7564516,8.117 +24,17-09-2010,1273295.46,0,60.31,2.846,132.7670667,8.117 +24,24-09-2010,1169413.27,0,64.3,2.837,132.7619333,8.117 +24,01-10-2010,1215273.2,0,66.88,2.84,132.7568,8.275 +24,08-10-2010,1361944.94,0,54.82,2.903,132.7516667,8.275 +24,15-10-2010,1300806.74,0,52.83,2.999,132.7633548,8.275 +24,22-10-2010,1234875.33,0,48.69,3.049,132.8170968,8.275 +24,29-10-2010,1244925.94,0,57.29,3.055,132.8708387,8.275 +24,05-11-2010,1285358.01,0,42.2,3.049,132.9245806,8.275 +24,12-11-2010,1312877.01,0,41.76,3.065,132.9783226,8.275 +24,19-11-2010,1277150.6,0,45.63,3.138,132.9172,8.275 +24,26-11-2010,1779276.51,1,41.92,3.186,132.8369333,8.275 +24,03-12-2010,1413302.7,0,37.08,3.2,132.7566667,8.275 +24,10-12-2010,1593012.75,0,27.11,3.255,132.6764,8.275 +24,17-12-2010,1663525.77,0,27.99,3.301,132.6804516,8.275 +24,24-12-2010,2386015.75,0,27.74,3.309,132.7477419,8.275 +24,31-12-2010,1208600.05,1,25.9,3.336,132.8150323,8.275 +24,07-01-2011,1178641.71,0,30.72,3.351,132.8823226,8.252 +24,14-01-2011,1167740.2,0,22.41,3.367,132.9510645,8.252 +24,21-01-2011,1107170.39,0,23.69,3.391,133.0285161,8.252 +24,28-01-2011,1126921.34,0,17.91,3.402,133.1059677,8.252 +24,04-02-2011,1225182.04,0,23.83,3.4,133.1834194,8.252 +24,11-02-2011,1341240.62,1,26.51,3.416,133.260871,8.252 +24,18-02-2011,1360150.12,0,34.04,3.42,133.3701429,8.252 +24,25-02-2011,1235121.33,0,26.09,3.452,133.4921429,8.252 +24,04-03-2011,1346994.53,0,31.36,3.605,133.6141429,8.252 +24,11-03-2011,1253218.7,0,39.51,3.752,133.7361429,8.252 +24,18-03-2011,1168397.26,0,43.39,3.796,133.8492258,8.252 +24,25-03-2011,1158693.12,0,36.88,3.789,133.9587419,8.252 +24,01-04-2011,1163803.3,0,35.73,3.811,134.0682581,8.212 +24,08-04-2011,1273670.32,0,44.7,3.895,134.1777742,8.212 +24,15-04-2011,1245576.65,0,52.36,3.981,134.2784667,8.212 +24,22-04-2011,1372484.9,0,46,4.061,134.3571,8.212 +24,29-04-2011,1197761.17,0,60.48,4.117,134.4357333,8.212 +24,06-05-2011,1339630.35,0,55.75,4.192,134.5143667,8.212 +24,13-05-2011,1311950.16,0,58.49,4.211,134.593,8.212 +24,20-05-2011,1234281.7,0,59.84,4.202,134.6803871,8.212 +24,27-05-2011,1311153.72,0,65.74,4.134,134.7677742,8.212 +24,03-06-2011,1554837.62,0,73.12,4.069,134.8551613,8.212 +24,10-06-2011,1373841.91,0,70.02,4.025,134.9425484,8.212 +24,17-06-2011,1320359.23,0,64.34,3.989,135.0837333,8.212 +24,24-06-2011,1304850.67,0,68.88,3.964,135.2652667,8.212 +24,01-07-2011,1445596.61,0,70.27,3.916,135.4468,8.358 +24,08-07-2011,1567340.07,0,72.56,3.886,135.6283333,8.358 +24,15-07-2011,1356938.95,0,74.43,3.915,135.7837419,8.358 +24,22-07-2011,1357672.24,0,79.29,3.972,135.8738387,8.358 +24,29-07-2011,1310973.06,0,74.84,4.004,135.9639355,8.358 +24,05-08-2011,1417616.81,0,74.64,4.02,136.0540323,8.358 +24,12-08-2011,1402818.01,0,72.52,3.995,136.144129,8.358 +24,19-08-2011,1352039.88,0,69.93,3.942,136.183129,8.358 +24,26-08-2011,1402372.09,0,69.94,3.906,136.2136129,8.358 +24,02-09-2011,1196105.44,0,68.14,3.879,136.2440968,8.358 +24,09-09-2011,1527455.19,1,68.32,3.93,136.2745806,8.358 +24,16-09-2011,1227535.97,0,65.56,3.937,136.3145,8.358 +24,23-09-2011,1232376.49,0,60.61,3.899,136.367,8.358 +24,30-09-2011,1246242.61,0,68,3.858,136.4195,8.358 +24,07-10-2011,1405914.39,0,53.87,3.775,136.472,8.454 +24,14-10-2011,1333315.03,0,60.21,3.744,136.5150968,8.454 +24,21-10-2011,1283563.43,0,56.6,3.757,136.5017742,8.454 +24,28-10-2011,1307142.75,0,48,3.757,136.4884516,8.454 +24,04-11-2011,1385860.38,0,39.87,3.738,136.475129,8.454 +24,11-11-2011,1425078.59,0,46.78,3.719,136.4618065,8.454 +24,18-11-2011,1297535.69,0,48.17,3.717,136.4666667,8.454 +24,25-11-2011,1761235.67,1,41.83,3.689,136.4788,8.454 +24,02-12-2011,1335647.1,0,47.21,3.666,136.4909333,8.454 +24,09-12-2011,1529615.54,0,42.3,3.627,136.5030667,8.454 +24,16-12-2011,1624994.43,0,36,3.611,136.5335161,8.454 +24,23-12-2011,2168344.23,0,36.93,3.587,136.5883871,8.454 +24,30-12-2011,1363973.16,1,33.45,3.566,136.6432581,8.454 +24,06-01-2012,1251581.89,0,32.86,3.585,136.698129,8.659 +24,13-01-2012,1155594.2,0,36.5,3.666,136.753,8.659 +24,20-01-2012,1151993.85,0,25.73,3.705,136.8564194,8.659 +24,27-01-2012,1057290.41,0,31.92,3.737,136.9598387,8.659 +24,03-02-2012,1249696.97,0,38.61,3.796,137.0632581,8.659 +24,10-02-2012,1403460.87,1,33.82,3.826,137.1666774,8.659 +24,17-02-2012,1326370.08,0,33.92,3.874,137.2583103,8.659 +24,24-02-2012,1303233.15,0,37.35,3.917,137.3411034,8.659 +24,02-03-2012,1213994.39,0,35.36,3.983,137.4238966,8.659 +24,09-03-2012,1325835.7,0,41.5,4.021,137.5066897,8.659 +24,16-03-2012,1239299.12,0,48.68,4.021,137.5843871,8.659 +24,23-03-2012,1221723.94,0,59.51,4.054,137.6552903,8.659 +24,30-03-2012,1230106.13,0,47.28,4.098,137.7261935,8.659 +24,06-04-2012,1524734.29,0,45.25,4.143,137.7970968,8.983 +24,13-04-2012,1285783.87,0,48.65,4.187,137.868,8.983 +24,20-04-2012,1208654.4,0,61.05,4.17,137.9230667,8.983 +24,27-04-2012,1194334.65,0,49.26,4.163,137.9781333,8.983 +24,04-05-2012,1306551.71,0,52.14,4.124,138.0332,8.983 +24,11-05-2012,1355391.79,0,58.7,4.055,138.0882667,8.983 +24,18-05-2012,1298809.8,0,63.1,4.029,138.1065806,8.983 +24,25-05-2012,1407897.57,0,65.79,3.979,138.1101935,8.983 +24,01-06-2012,1467722.19,0,71.79,3.915,138.1138065,8.983 +24,08-06-2012,1406313.13,0,59.93,3.871,138.1174194,8.983 +24,15-06-2012,1364445.98,0,68.28,3.786,138.1295333,8.983 +24,22-06-2012,1434709.63,0,72.29,3.722,138.1629,8.983 +24,29-06-2012,1428869.9,0,70.4,3.667,138.1962667,8.983 +24,06-07-2012,1645097.75,0,77.18,3.646,138.2296333,8.953 +24,13-07-2012,1405475.78,0,75.36,3.689,138.263,8.953 +24,20-07-2012,1394299,0,76.42,3.732,138.2331935,8.953 +24,27-07-2012,1307339.14,0,73.62,3.82,138.2033871,8.953 +24,03-08-2012,1440374.13,0,73.26,3.819,138.1735806,8.953 +24,10-08-2012,1497054.81,0,75.53,3.863,138.1437742,8.953 +24,17-08-2012,1397970.54,0,72.87,3.963,138.1857097,8.953 +24,24-08-2012,1303726.54,0,68.13,3.997,138.2814516,8.953 +24,31-08-2012,1344558.92,0,71.18,4.026,138.3771935,8.953 +24,07-09-2012,1477134.75,1,72.81,4.076,138.4729355,8.953 +24,14-09-2012,1242909.53,0,64.28,4.088,138.5673,8.953 +24,21-09-2012,1261158.47,0,61.25,4.203,138.6534,8.953 +24,28-09-2012,1259278.36,0,58.86,4.158,138.7395,8.953 +24,05-10-2012,1416720.54,0,60.35,4.151,138.8256,8.693 +24,12-10-2012,1416301.17,0,51.64,4.186,138.9117,8.693 +24,19-10-2012,1255414.84,0,52.59,4.153,138.8336129,8.693 +24,26-10-2012,1307182.29,0,55.16,4.071,138.7281613,8.693 +25,05-02-2010,677231.63,0,21.1,2.784,204.2471935,8.187 +25,12-02-2010,583364.02,1,19.64,2.773,204.3857472,8.187 +25,19-02-2010,676260.67,0,24.16,2.745,204.4321004,8.187 +25,26-02-2010,628516.57,0,29.16,2.754,204.4630869,8.187 +25,05-03-2010,665750.06,0,29.45,2.777,204.4940734,8.187 +25,12-03-2010,660619.99,0,40.05,2.818,204.5250598,8.187 +25,19-03-2010,659795.84,0,45,2.844,204.3782258,8.187 +25,26-03-2010,696687.6,0,45.84,2.854,204.201755,8.187 +25,02-04-2010,822486.37,0,47.2,2.85,204.0252842,7.856 +25,09-04-2010,712647.97,0,61.36,2.869,203.8488134,7.856 +25,16-04-2010,715311.6,0,52.16,2.899,203.7307486,7.856 +25,23-04-2010,694531.72,0,46.12,2.902,203.6905586,7.856 +25,30-04-2010,706924.02,0,50.97,2.921,203.6503685,7.856 +25,07-05-2010,724468.97,0,63.67,2.966,203.6101784,7.856 +25,14-05-2010,698073.95,0,50.27,2.982,203.6133915,7.856 +25,21-05-2010,704113.22,0,57.17,2.958,203.8770235,7.856 +25,28-05-2010,792442.54,0,69.31,2.899,204.1406556,7.856 +25,04-06-2010,764155.44,0,69.22,2.847,204.4042877,7.856 +25,11-06-2010,737163.2,0,63.68,2.809,204.6679198,7.856 +25,18-06-2010,780444.94,0,69.56,2.78,204.670036,7.856 +25,25-06-2010,737569.14,0,72.17,2.808,204.5675459,7.856 +25,02-07-2010,759407.87,0,66.42,2.815,204.4650559,7.527 +25,09-07-2010,719591.13,0,75.24,2.793,204.3625658,7.527 +25,16-07-2010,726997.84,0,73.43,2.783,204.3571656,7.527 +25,23-07-2010,665290.93,0,75.37,2.771,204.4812188,7.527 +25,30-07-2010,682124.34,0,71.99,2.781,204.605272,7.527 +25,06-08-2010,699464.43,0,71.79,2.784,204.7293252,7.527 +25,13-08-2010,686072.39,0,72.73,2.805,204.8533784,7.527 +25,20-08-2010,724499.81,0,71.81,2.779,204.8217044,7.527 +25,27-08-2010,711461.95,0,67.15,2.755,204.7900305,7.527 +25,03-09-2010,685700.08,0,71.17,2.715,204.7583566,7.527 +25,10-09-2010,655811.95,1,61.14,2.699,204.7266827,7.527 +25,17-09-2010,628989.88,0,60.13,2.706,204.7513279,7.527 +25,24-09-2010,607819.33,0,65.06,2.713,204.8182126,7.527 +25,01-10-2010,658640.14,0,57.56,2.707,204.8850973,7.484 +25,08-10-2010,674283.86,0,48.46,2.764,204.951982,7.484 +25,15-10-2010,616094.72,0,54.09,2.868,205.0137637,7.484 +25,22-10-2010,661644.19,0,46.73,2.917,205.0627881,7.484 +25,29-10-2010,674458.03,0,55.72,2.921,205.1118126,7.484 +25,05-11-2010,696314.53,0,38.8,2.917,205.160837,7.484 +25,12-11-2010,713250.08,0,40.68,2.931,205.2098614,7.484 +25,19-11-2010,718056.73,0,42.72,3,205.0992811,7.484 +25,26-11-2010,1115240.61,1,43.43,3.039,204.9621,7.484 +25,03-12-2010,885572.96,0,32.41,3.046,204.8249189,7.484 +25,10-12-2010,964729.18,0,22.65,3.109,204.6877378,7.484 +25,17-12-2010,1047707.59,0,21.6,3.14,204.6321194,7.484 +25,24-12-2010,1295391.19,0,22.94,3.141,204.6376731,7.484 +25,31-12-2010,623092.54,1,25.89,3.179,204.6432267,7.484 +25,07-01-2011,558794.63,0,29,3.193,204.6487803,7.343 +25,14-01-2011,572360.83,0,18.3,3.205,204.7026042,7.343 +25,21-01-2011,568093.57,0,23.21,3.229,205.0460497,7.343 +25,28-01-2011,600448.69,0,18.92,3.237,205.3894952,7.343 +25,04-02-2011,639830.45,0,23.94,3.231,205.7329407,7.343 +25,11-02-2011,615666.78,1,21.18,3.239,206.0763862,7.343 +25,18-02-2011,634637.03,0,38.42,3.245,206.3694701,7.343 +25,25-02-2011,570816.34,0,28.36,3.274,206.6424093,7.343 +25,04-03-2011,640912.18,0,31.59,3.433,206.9153485,7.343 +25,11-03-2011,599828.39,0,36.73,3.582,207.1882876,7.343 +25,18-03-2011,603393.64,0,40.94,3.631,207.4283845,7.343 +25,25-03-2011,616324.24,0,38.51,3.625,207.6553444,7.343 +25,01-04-2011,618377.79,0,28.5,3.638,207.8823043,7.287 +25,08-04-2011,648606.13,0,42.11,3.72,208.1092642,7.287 +25,15-04-2011,674562.45,0,51.43,3.821,208.3172811,7.287 +25,22-04-2011,756588.42,0,45.87,3.892,208.4779405,7.287 +25,29-04-2011,649245,0,58.43,3.962,208.6386,7.287 +25,06-05-2011,659446.55,0,49.5,4.046,208.7992595,7.287 +25,13-05-2011,684783.15,0,60.1,4.066,208.9599189,7.287 +25,20-05-2011,677971.33,0,56.56,4.062,208.7583165,7.287 +25,27-05-2011,718373.94,0,67.18,3.985,208.556714,7.287 +25,03-06-2011,737551.74,0,70.69,3.922,208.3551116,7.287 +25,10-06-2011,740259.63,0,71.45,3.881,208.1535092,7.287 +25,17-06-2011,717373.43,0,63.58,3.842,208.1265604,7.287 +25,24-06-2011,699270.1,0,70.71,3.804,208.2306018,7.287 +25,01-07-2011,706206.86,0,66.61,3.748,208.3346432,7.274 +25,08-07-2011,698529.64,0,71.64,3.711,208.4386847,7.274 +25,15-07-2011,680510.23,0,72.67,3.76,208.5309337,7.274 +25,22-07-2011,670854.96,0,78.1,3.811,208.5937018,7.274 +25,29-07-2011,668390.82,0,74.72,3.829,208.6564699,7.274 +25,05-08-2011,679706.01,0,74,3.842,208.719238,7.274 +25,12-08-2011,667130.48,0,70.93,3.812,208.7820061,7.274 +25,19-08-2011,688958.75,0,68.09,3.747,208.8424359,7.274 +25,26-08-2011,726422.55,0,66.8,3.704,208.902476,7.274 +25,02-09-2011,699779,0,67.2,3.703,208.9625161,7.274 +25,09-09-2011,673248.48,1,67.51,3.738,209.0225562,7.274 +25,16-09-2011,628720.46,0,62.05,3.742,209.1893892,7.274 +25,23-09-2011,620885.93,0,60.28,3.711,209.4986126,7.274 +25,30-09-2011,639160.24,0,60.7,3.645,209.807836,7.274 +25,07-10-2011,671522.87,0,50.82,3.583,210.1170595,7.082 +25,14-10-2011,646915.47,0,58.95,3.541,210.4027602,7.082 +25,21-10-2011,690675.5,0,50.22,3.57,210.5473252,7.082 +25,28-10-2011,724443.97,0,46.28,3.569,210.6918901,7.082 +25,04-11-2011,718393.61,0,40.88,3.551,210.8364551,7.082 +25,11-11-2011,719235.07,0,44.81,3.53,210.9810201,7.082 +25,18-11-2011,728525.6,0,46.41,3.53,211.1847207,7.082 +25,25-11-2011,1116211.39,1,43.49,3.492,211.4120757,7.082 +25,02-12-2011,878314.57,0,42.85,3.452,211.6394306,7.082 +25,09-12-2011,916446.02,0,38.69,3.415,211.8667856,7.082 +25,16-12-2011,997502.47,0,33.09,3.413,212.0685039,7.082 +25,23-12-2011,1290532.97,0,36.56,3.389,212.2360401,7.082 +25,30-12-2011,683665.37,1,32.42,3.389,212.4035763,7.082 +25,06-01-2012,636419.12,0,30.23,3.422,212.5711125,6.961 +25,13-01-2012,614764.31,0,34.6,3.513,212.7386486,6.961 +25,20-01-2012,594744.89,0,23.87,3.533,212.8336399,6.961 +25,27-01-2012,589554.29,0,32.24,3.567,212.9286312,6.961 +25,03-02-2012,642776.4,0,34.98,3.617,213.0236225,6.961 +25,10-02-2012,658984.38,1,32.47,3.64,213.1186138,6.961 +25,17-02-2012,654088.02,0,32.23,3.695,213.2732106,6.961 +25,24-02-2012,613501.05,0,35.51,3.739,213.4725116,6.961 +25,02-03-2012,643155.89,0,36.01,3.816,213.6718127,6.961 +25,09-03-2012,643711.53,0,37.44,3.848,213.8711137,6.961 +25,16-03-2012,638204.27,0,50.64,3.862,214.0167132,6.961 +25,23-03-2012,672831.78,0,62.7,3.9,214.0907105,6.961 +25,30-03-2012,684348.92,0,47.92,3.953,214.1647079,6.961 +25,06-04-2012,791356.9,0,44.73,3.996,214.2387053,7.139 +25,13-04-2012,658691.56,0,42.46,4.044,214.3127027,7.139 +25,20-04-2012,661566.48,0,57.1,4.027,214.3675045,7.139 +25,27-04-2012,655157.32,0,44.2,4.004,214.4223063,7.139 +25,04-05-2012,696421.72,0,58.76,3.951,214.4771081,7.139 +25,11-05-2012,739866.16,0,59.21,3.889,214.5319099,7.139 +25,18-05-2012,717207.19,0,58.21,3.848,214.5485571,7.139 +25,25-05-2012,783371.02,0,67.69,3.798,214.5499425,7.139 +25,01-06-2012,694765.95,0,69.54,3.742,214.5513278,7.139 +25,08-06-2012,730254.19,0,58.48,3.689,214.5527132,7.139 +25,15-06-2012,753860.89,0,68.34,3.62,214.5653243,7.139 +25,22-06-2012,721601.9,0,73.52,3.564,214.606,7.139 +25,29-06-2012,718890.81,0,69.84,3.506,214.6466757,7.139 +25,06-07-2012,753385.55,0,75.52,3.475,214.6873514,7.28 +25,13-07-2012,714093.95,0,73.87,3.523,214.728027,7.28 +25,20-07-2012,685676.58,0,74.32,3.567,214.7331351,7.28 +25,27-07-2012,659109.53,0,72.98,3.647,214.7382432,7.28 +25,03-08-2012,709724.6,0,72.08,3.654,214.7433514,7.28 +25,10-08-2012,710496.97,0,71.93,3.722,214.7484595,7.28 +25,17-08-2012,728467.72,0,66.99,3.807,214.825578,7.28 +25,24-08-2012,756527.64,0,64.53,3.834,214.9567044,7.28 +25,31-08-2012,714828.73,0,68.55,3.867,215.0878309,7.28 +25,07-09-2012,671482.9,1,72.79,3.911,215.2189573,7.28 +25,14-09-2012,657241.63,0,60.9,3.948,215.3583757,7.28 +25,21-09-2012,664745.2,0,57.6,4.038,215.5475459,7.28 +25,28-09-2012,683300.84,0,54.52,3.997,215.7367162,7.28 +25,05-10-2012,699536.73,0,57.58,3.985,215.9258865,7.293 +25,12-10-2012,697317.41,0,43.74,4,216.1150568,7.293 +25,19-10-2012,685531.85,0,51.93,3.969,216.1464699,7.293 +25,26-10-2012,688940.94,0,56.69,3.882,216.1515902,7.293 +26,05-02-2010,1034119.21,0,9.55,2.788,131.5279032,8.488 +26,12-02-2010,1015684.09,1,18.14,2.771,131.5866129,8.488 +26,19-02-2010,999348.55,0,22.62,2.747,131.637,8.488 +26,26-02-2010,855385.01,0,27.32,2.753,131.686,8.488 +26,05-03-2010,1005669.58,0,28.6,2.766,131.735,8.488 +26,12-03-2010,963382.09,0,31.1,2.805,131.784,8.488 +26,19-03-2010,903366.55,0,35.34,2.834,131.8242903,8.488 +26,26-03-2010,893613,0,35.26,2.831,131.863129,8.488 +26,02-04-2010,1029849.2,0,36.53,2.826,131.9019677,8.512 +26,09-04-2010,1022293.81,0,50.13,2.849,131.9408065,8.512 +26,16-04-2010,905548.38,0,36.6,2.885,131.9809,8.512 +26,23-04-2010,881930.87,0,39.68,2.895,132.0226667,8.512 +26,30-04-2010,904503.85,0,40.56,2.935,132.0644333,8.512 +26,07-05-2010,1074479.73,0,54.72,2.981,132.1062,8.512 +26,14-05-2010,972663.59,0,39.08,2.983,132.152129,8.512 +26,21-05-2010,986765.01,0,50.81,2.961,132.2230323,8.512 +26,28-05-2010,1069851.59,0,61.65,2.906,132.2939355,8.512 +26,04-06-2010,1003202.66,0,58.46,2.857,132.3648387,8.512 +26,11-06-2010,1073862.59,0,51.62,2.83,132.4357419,8.512 +26,18-06-2010,1001286.67,0,53.62,2.805,132.4733333,8.512 +26,25-06-2010,976242.09,0,63.78,2.81,132.4976,8.512 +26,02-07-2010,1078455.48,0,58.9,2.815,132.5218667,8.445 +26,09-07-2010,1122356.53,0,71.08,2.806,132.5461333,8.445 +26,16-07-2010,1028151.72,0,67.66,2.796,132.5667742,8.445 +26,23-07-2010,971615.62,0,65.4,2.784,132.5825806,8.445 +26,30-07-2010,1005324.28,0,63.79,2.792,132.5983871,8.445 +26,06-08-2010,1125329.77,0,62.93,2.792,132.6141935,8.445 +26,13-08-2010,1011938.29,0,61.58,2.81,132.63,8.445 +26,20-08-2010,1007385.36,0,62.68,2.796,132.6616129,8.445 +26,27-08-2010,977322.52,0,57.23,2.77,132.6932258,8.445 +26,03-09-2010,1037549.71,0,66.93,2.735,132.7248387,8.445 +26,10-09-2010,1042226.3,1,54.82,2.717,132.7564516,8.445 +26,17-09-2010,923473.7,0,50.08,2.716,132.7670667,8.445 +26,24-09-2010,868636.3,0,52.47,2.718,132.7619333,8.445 +26,01-10-2010,923221.52,0,57.8,2.717,132.7568,8.149 +26,08-10-2010,1001069.52,0,46.81,2.776,132.7516667,8.149 +26,15-10-2010,937956.89,0,39.93,2.878,132.7633548,8.149 +26,22-10-2010,916522.66,0,36.13,2.919,132.8170968,8.149 +26,29-10-2010,895069.88,0,40.3,2.938,132.8708387,8.149 +26,05-11-2010,970224.51,0,30.51,2.938,132.9245806,8.149 +26,12-11-2010,971193.01,0,37.51,2.961,132.9783226,8.149 +26,19-11-2010,901972.7,0,36.73,3.03,132.9172,8.149 +26,26-11-2010,1286833.62,1,28.11,3.07,132.8369333,8.149 +26,03-12-2010,1016143.64,0,27.73,3.065,132.7566667,8.149 +26,10-12-2010,1149612.04,0,16.6,3.132,132.6764,8.149 +26,17-12-2010,1196813.33,0,20.61,3.139,132.6804516,8.149 +26,24-12-2010,1573982.47,0,21.81,3.15,132.7477419,8.149 +26,31-12-2010,877268.29,1,18.73,3.177,132.8150323,8.149 +26,07-01-2011,938149.21,0,21.13,3.193,132.8823226,7.907 +26,14-01-2011,812323.29,0,16.7,3.215,132.9510645,7.907 +26,21-01-2011,809833.21,0,12.98,3.232,133.0285161,7.907 +26,28-01-2011,817485.14,0,5.54,3.243,133.1059677,7.907 +26,04-02-2011,911807.02,0,11.17,3.24,133.1834194,7.907 +26,11-02-2011,1010711.08,1,15.12,3.255,133.260871,7.907 +26,18-02-2011,981978.02,0,19.63,3.263,133.3701429,7.907 +26,25-02-2011,910298.44,0,16.3,3.281,133.4921429,7.907 +26,04-03-2011,945643.17,0,14.31,3.437,133.6141429,7.907 +26,11-03-2011,946614.55,0,28.13,3.6,133.7361429,7.907 +26,18-03-2011,887426.12,0,31.76,3.634,133.8492258,7.907 +26,25-03-2011,866566.54,0,22.99,3.624,133.9587419,7.907 +26,01-04-2011,849231.61,0,22.99,3.638,134.0682581,7.818 +26,08-04-2011,985229.81,0,29.09,3.72,134.1777742,7.818 +26,15-04-2011,863266.12,0,39.46,3.823,134.2784667,7.818 +26,22-04-2011,921700.61,0,33.81,3.919,134.3571,7.818 +26,29-04-2011,873450.29,0,47.17,3.988,134.4357333,7.818 +26,06-05-2011,1024778.23,0,45,4.078,134.5143667,7.818 +26,13-05-2011,941008.85,0,48.2,4.095,134.593,7.818 +26,20-05-2011,938334.62,0,48.86,4.101,134.6803871,7.818 +26,27-05-2011,996723.58,0,56.74,4.034,134.7677742,7.818 +26,03-06-2011,1054454.4,0,60.49,3.973,134.8551613,7.818 +26,10-06-2011,1094058.68,0,59.85,3.924,134.9425484,7.818 +26,17-06-2011,981646.46,0,54.5,3.873,135.0837333,7.818 +26,24-06-2011,997474.93,0,56.94,3.851,135.2652667,7.818 +26,01-07-2011,1070119.09,0,59.89,3.815,135.4468,7.767 +26,08-07-2011,1133807.03,0,63.34,3.784,135.6283333,7.767 +26,15-07-2011,1021534.7,0,64.43,3.827,135.7837419,7.767 +26,22-07-2011,1017867.8,0,69.52,3.882,135.8738387,7.767 +26,29-07-2011,1005360.5,0,63.32,3.898,135.9639355,7.767 +26,05-08-2011,1107552.43,0,63.16,3.903,136.0540323,7.767 +26,12-08-2011,1087644.5,0,62.99,3.88,136.144129,7.767 +26,19-08-2011,1021766.75,0,60.58,3.82,136.183129,7.767 +26,26-08-2011,1064617.62,0,61.1,3.796,136.2136129,7.767 +26,02-09-2011,1040143.14,0,59.67,3.784,136.2440968,7.767 +26,09-09-2011,1069710.97,1,60.98,3.809,136.2745806,7.767 +26,16-09-2011,951569.84,0,55.19,3.809,136.3145,7.767 +26,23-09-2011,923644.6,0,50.72,3.758,136.367,7.767 +26,30-09-2011,959339.51,0,59.42,3.684,136.4195,7.767 +26,07-10-2011,1130022.99,0,46.84,3.633,136.472,7.598 +26,14-10-2011,987886.08,0,53.91,3.583,136.5150968,7.598 +26,21-10-2011,974907.28,0,45.23,3.618,136.5017742,7.598 +26,28-10-2011,972256.98,0,35.06,3.604,136.4884516,7.598 +26,04-11-2011,988950.75,0,31.7,3.586,136.475129,7.598 +26,11-11-2011,1077640.13,0,40.08,3.57,136.4618065,7.598 +26,18-11-2011,946091.79,0,37.78,3.571,136.4666667,7.598 +26,25-11-2011,1282320.05,1,31.07,3.536,136.4788,7.598 +26,02-12-2011,1012498.49,0,36.74,3.501,136.4909333,7.598 +26,09-12-2011,1148987.46,0,34.24,3.47,136.5030667,7.598 +26,16-12-2011,1204807.83,0,28.24,3.445,136.5335161,7.598 +26,23-12-2011,1515175.01,0,22.53,3.413,136.5883871,7.598 +26,30-12-2011,972834.42,1,18.8,3.402,136.6432581,7.598 +26,06-01-2012,971557.62,0,22.94,3.439,136.698129,7.467 +26,13-01-2012,836305.65,0,25.55,3.523,136.753,7.467 +26,20-01-2012,838751.5,0,15.22,3.542,136.8564194,7.467 +26,27-01-2012,820059.89,0,24.16,3.568,136.9598387,7.467 +26,03-02-2012,939158.25,0,25.24,3.633,137.0632581,7.467 +26,10-02-2012,1081005.64,1,23.89,3.655,137.1666774,7.467 +26,17-02-2012,965788.76,0,23.9,3.703,137.2583103,7.467 +26,24-02-2012,917924.47,0,28.06,3.751,137.3411034,7.467 +26,02-03-2012,955641.74,0,22.49,3.827,137.4238966,7.467 +26,09-03-2012,1028569.01,0,29.03,3.876,137.5066897,7.467 +26,16-03-2012,919503.4,0,35.06,3.867,137.5843871,7.467 +26,23-03-2012,874790.68,0,49.97,3.889,137.6552903,7.467 +26,30-03-2012,922018.43,0,33.33,3.921,137.7261935,7.467 +26,06-04-2012,1116829.23,0,33.35,3.957,137.7970968,7.489 +26,13-04-2012,889670.29,0,36.9,4.025,137.868,7.489 +26,20-04-2012,923600.02,0,50.81,4.046,137.9230667,7.489 +26,27-04-2012,911969,0,43.6,4.023,137.9781333,7.489 +26,04-05-2012,946573.29,0,40.29,3.991,138.0332,7.489 +26,11-05-2012,1062548.73,0,47.11,3.947,138.0882667,7.489 +26,18-05-2012,978082.84,0,52.55,3.899,138.1065806,7.489 +26,25-05-2012,1067310.74,0,58.2,3.85,138.1101935,7.489 +26,01-06-2012,1015853.03,0,58.51,3.798,138.1138065,7.489 +26,08-06-2012,1106176.83,0,49.43,3.746,138.1174194,7.489 +26,15-06-2012,1029248.22,0,57.84,3.683,138.1295333,7.489 +26,22-06-2012,1056282.91,0,63.04,3.629,138.1629,7.489 +26,29-06-2012,1051190.44,0,60.71,3.577,138.1962667,7.489 +26,06-07-2012,1180470.8,0,64.94,3.538,138.2296333,7.405 +26,13-07-2012,1063149.78,0,64.47,3.561,138.263,7.405 +26,20-07-2012,1049625.9,0,66.75,3.61,138.2331935,7.405 +26,27-07-2012,1031745.14,0,64.12,3.701,138.2033871,7.405 +26,03-08-2012,1090915.09,0,65.6,3.698,138.1735806,7.405 +26,10-08-2012,1121476.51,0,67.01,3.772,138.1437742,7.405 +26,17-08-2012,1068292.56,0,65.54,3.84,138.1857097,7.405 +26,24-08-2012,1022704.2,0,62.08,3.874,138.2814516,7.405 +26,31-08-2012,1053495.51,0,63.69,3.884,138.3771935,7.405 +26,07-09-2012,1081874.03,1,61.58,3.921,138.4729355,7.405 +26,14-09-2012,986131.94,0,57.69,3.988,138.5673,7.405 +26,21-09-2012,961084.08,0,52.68,4.056,138.6534,7.405 +26,28-09-2012,964726.37,0,50.66,4.018,138.7395,7.405 +26,05-10-2012,1095504.26,0,54.07,4.027,138.8256,7.138 +26,12-10-2012,1044639.69,0,45.19,4.029,138.9117,7.138 +26,19-10-2012,975578.02,0,43.51,4,138.8336129,7.138 +26,26-10-2012,958619.8,0,46.95,3.917,138.7281613,7.138 +27,05-02-2010,1874289.79,0,27.19,2.954,135.3524608,8.237 +27,12-02-2010,1745362.72,1,29.81,2.94,135.4113076,8.237 +27,19-02-2010,1945070.33,0,32.44,2.909,135.4657781,8.237 +27,26-02-2010,1390934.27,0,36,2.91,135.5195191,8.237 +27,05-03-2010,1313729.72,0,38.07,2.919,135.5732602,8.237 +27,12-03-2010,1925113.12,0,45.98,2.938,135.6270013,8.237 +27,19-03-2010,1700627.97,0,49.04,2.96,135.6682247,8.237 +27,26-03-2010,1836714.84,0,52.34,2.963,135.7073618,8.237 +27,02-04-2010,2053952.97,0,46.9,2.957,135.7464988,8.058 +27,09-04-2010,1955814.13,0,62.62,2.992,135.7856359,8.058 +27,16-04-2010,1857500.96,0,54.95,3.01,135.82725,8.058 +27,23-04-2010,1850205.47,0,53.91,3.021,135.8721667,8.058 +27,30-04-2010,1805885.04,0,53.55,3.042,135.9170833,8.058 +27,07-05-2010,1939458.84,0,69.02,3.095,135.962,8.058 +27,14-05-2010,1842465.78,0,53.82,3.112,136.010394,8.058 +27,21-05-2010,1836595.58,0,63.31,3.096,136.0796521,8.058 +27,28-05-2010,1962468.67,0,67.88,3.046,136.1489101,8.058 +27,04-06-2010,2073102.59,0,74.29,3.006,136.2181682,8.058 +27,11-06-2010,1873812.93,0,68.9,2.972,136.2874263,8.058 +27,18-06-2010,1887182.27,0,70,2.942,136.3243393,8.058 +27,25-06-2010,1962625.01,0,78.02,2.958,136.3483143,8.058 +27,02-07-2010,2024554.1,0,76.25,2.958,136.3722893,7.982 +27,09-07-2010,2119163.01,0,82.69,2.94,136.3962643,7.982 +27,16-07-2010,1880691.64,0,78.26,2.933,136.4179827,7.982 +27,23-07-2010,1808250.71,0,81.56,2.924,136.4366924,7.982 +27,30-07-2010,1816489.53,0,79.78,2.932,136.4554021,7.982 +27,06-08-2010,1908036.68,0,77.45,2.942,136.4741118,7.982 +27,13-08-2010,1864436.12,0,77.36,2.923,136.4928214,7.982 +27,20-08-2010,1936878.46,0,75.16,2.913,136.5249182,7.982 +27,27-08-2010,1870684.21,0,70.31,2.885,136.557015,7.982 +27,03-09-2010,1908110.9,0,78.52,2.86,136.5891118,7.982 +27,10-09-2010,1913494.81,1,70.38,2.837,136.6212085,7.982 +27,17-09-2010,1629978.46,0,64.5,2.846,136.6338071,7.982 +27,24-09-2010,1597002.71,0,67.08,2.837,136.6317821,7.982 +27,01-10-2010,1543532.83,0,70.19,2.84,136.6297571,8.021 +27,08-10-2010,1707662.87,0,57.78,2.903,136.6277321,8.021 +27,15-10-2010,1728388.2,0,58.38,2.999,136.6401935,8.021 +27,22-10-2010,1693935.29,0,52.82,3.049,136.688871,8.021 +27,29-10-2010,1688955.49,0,61.02,3.055,136.7375484,8.021 +27,05-11-2010,1686010.02,0,45.91,3.049,136.7862258,8.021 +27,12-11-2010,1828010.25,0,45.9,3.065,136.8349032,8.021 +27,19-11-2010,1704785.74,0,50.81,3.138,136.7715714,8.021 +27,26-11-2010,2627910.75,1,46.67,3.186,136.6895714,8.021 +27,03-12-2010,1884343.67,0,41.81,3.2,136.6075714,8.021 +27,10-12-2010,2139733.68,0,30.83,3.255,136.5255714,8.021 +27,17-12-2010,2350098.36,0,31.62,3.301,136.5292811,8.021 +27,24-12-2010,3078162.08,0,31.34,3.309,136.597273,8.021 +27,31-12-2010,1440963,1,29.59,3.336,136.665265,8.021 +27,07-01-2011,1568159.48,0,34.42,3.351,136.7332569,7.827 +27,14-01-2011,1532308.62,0,25.7,3.367,136.803477,7.827 +27,21-01-2011,1517029.9,0,30.13,3.391,136.8870657,7.827 +27,28-01-2011,1421111.55,0,23.64,3.402,136.9706544,7.827 +27,04-02-2011,1628100.79,0,28.7,3.4,137.0542431,7.827 +27,11-02-2011,1636224.77,1,30.45,3.416,137.1378318,7.827 +27,18-02-2011,1709365.19,0,39.32,3.42,137.2511849,7.827 +27,25-02-2011,1688935.71,0,33.05,3.452,137.3764439,7.827 +27,04-03-2011,1656130.67,0,36.99,3.605,137.5017028,7.827 +27,11-03-2011,1613259.77,0,43.64,3.752,137.6269617,7.827 +27,18-03-2011,1624539.21,0,46.65,3.796,137.7398929,7.827 +27,25-03-2011,1554651.08,0,40.11,3.789,137.8478929,7.827 +27,01-04-2011,1628868.28,0,37.27,3.811,137.9558929,7.725 +27,08-04-2011,1689844.18,0,46.87,3.895,138.0638929,7.725 +27,15-04-2011,1727175.61,0,52.24,3.981,138.1646952,7.725 +27,22-04-2011,1921655.48,0,50.02,4.061,138.2475036,7.725 +27,29-04-2011,1642074.64,0,61.71,4.117,138.3303119,7.725 +27,06-05-2011,1757041.96,0,56.48,4.192,138.4131202,7.725 +27,13-05-2011,1763545.32,0,60.07,4.211,138.4959286,7.725 +27,20-05-2011,1725268.56,0,60.22,4.202,138.587106,7.725 +27,27-05-2011,1820723.17,0,66.43,4.134,138.6782834,7.725 +27,03-06-2011,2053708.01,0,74.17,4.069,138.7694608,7.725 +27,10-06-2011,1817914.71,0,73.26,4.025,138.8606382,7.725 +27,17-06-2011,1814740.09,0,67.03,3.989,139.0028333,7.725 +27,24-06-2011,1811455.15,0,72.02,3.964,139.1832917,7.725 +27,01-07-2011,1949983.93,0,73.76,3.916,139.36375,7.85 +27,08-07-2011,2000055.27,0,76.87,3.886,139.5442083,7.85 +27,15-07-2011,1762155.79,0,77.83,3.915,139.7006325,7.85 +27,22-07-2011,1754879.45,0,82.28,3.972,139.7969712,7.85 +27,29-07-2011,1744879.06,0,79.41,4.004,139.8933099,7.85 +27,05-08-2011,1747289.53,0,78.14,4.02,139.9896486,7.85 +27,12-08-2011,1758437.96,0,76.67,3.995,140.0859873,7.85 +27,19-08-2011,1781905.24,0,72.97,3.942,140.1289205,7.85 +27,26-08-2011,2034400.78,0,72.88,3.906,140.1629528,7.85 +27,02-09-2011,1511717.53,0,71.44,3.879,140.196985,7.85 +27,09-09-2011,1911470.84,1,70.93,3.93,140.2310173,7.85 +27,16-09-2011,1613773.9,0,69.65,3.937,140.2735,7.85 +27,23-09-2011,1606208.68,0,63.61,3.899,140.32725,7.85 +27,30-09-2011,1599626.26,0,70.92,3.858,140.381,7.85 +27,07-10-2011,1672339.27,0,56.91,3.775,140.43475,7.906 +27,14-10-2011,1682652.51,0,64.78,3.744,140.4784194,7.906 +27,21-10-2011,1689591.44,0,59.62,3.757,140.4616048,7.906 +27,28-10-2011,1710372.4,0,51.81,3.757,140.4447903,7.906 +27,04-11-2011,1621109.3,0,44.46,3.738,140.4279758,7.906 +27,11-11-2011,1800728.07,0,49.69,3.719,140.4111613,7.906 +27,18-11-2011,1723739.44,0,51.42,3.717,140.4127857,7.906 +27,25-11-2011,2504400.71,1,47.88,3.689,140.4217857,7.906 +27,02-12-2011,1806924.74,0,50.55,3.666,140.4307857,7.906 +27,09-12-2011,2014665.98,0,46.28,3.627,140.4397857,7.906 +27,16-12-2011,2205919.86,0,40.68,3.611,140.4700795,7.906 +27,23-12-2011,2739019.75,0,41.59,3.587,140.528765,7.906 +27,30-12-2011,1650604.6,1,37.85,3.566,140.5874505,7.906 +27,06-01-2012,1535287.4,0,35.8,3.585,140.6461359,8.009 +27,13-01-2012,1492399.13,0,41.3,3.666,140.7048214,8.009 +27,20-01-2012,1542131.05,0,30.35,3.705,140.8086118,8.009 +27,27-01-2012,1263534.86,0,36.96,3.737,140.9124021,8.009 +27,03-02-2012,1564246.02,0,42.52,3.796,141.0161924,8.009 +27,10-02-2012,1651605.35,1,37.86,3.826,141.1199827,8.009 +27,17-02-2012,1606221.56,0,37.24,3.874,141.2140357,8.009 +27,24-02-2012,1648602.39,0,41.74,3.917,141.3007857,8.009 +27,02-03-2012,1509323.09,0,40.07,3.983,141.3875357,8.009 +27,09-03-2012,1607343.41,0,44.32,4.021,141.4742857,8.009 +27,16-03-2012,1635984.07,0,49.6,4.021,141.55478,8.009 +27,23-03-2012,1620839.34,0,57.3,4.054,141.6269332,8.009 +27,30-03-2012,1615494.14,0,49.4,4.098,141.6990864,8.009 +27,06-04-2012,1899013.34,0,48.73,4.143,141.7712396,8.253 +27,13-04-2012,1650405.21,0,52.22,4.187,141.8433929,8.253 +27,20-04-2012,1639999.47,0,62.62,4.17,141.9015262,8.253 +27,27-04-2012,1565498.84,0,52.33,4.163,141.9596595,8.253 +27,04-05-2012,1669388.45,0,53.68,4.124,142.0177929,8.253 +27,11-05-2012,1674306.31,0,58.97,4.055,142.0759262,8.253 +27,18-05-2012,1707158.82,0,65.15,4.029,142.0970115,8.253 +27,25-05-2012,1818906.73,0,64.77,3.979,142.1032776,8.253 +27,01-06-2012,1900638.6,0,73.4,3.915,142.1095438,8.253 +27,08-06-2012,1764756.31,0,64.05,3.871,142.1158099,8.253 +27,15-06-2012,1773500.56,0,69.52,3.786,142.1292548,8.253 +27,22-06-2012,1837884.79,0,73.23,3.722,142.1606464,8.253 +27,29-06-2012,1842555.32,0,73.94,3.667,142.1920381,8.253 +27,06-07-2012,2062224.92,0,82.08,3.646,142.2234298,8.239 +27,13-07-2012,1755889.53,0,78.95,3.689,142.2548214,8.239 +27,20-07-2012,1730913.66,0,78.64,3.732,142.2337569,8.239 +27,27-07-2012,1625883.71,0,76.01,3.82,142.2126924,8.239 +27,03-08-2012,1705810.84,0,75.22,3.819,142.1916279,8.239 +27,10-08-2012,1720537.26,0,78.44,3.863,142.1705634,8.239 +27,17-08-2012,1735339.59,0,76.51,3.963,142.2157385,8.239 +27,24-08-2012,1780443.36,0,72.93,3.997,142.3105933,8.239 +27,31-08-2012,1731935.43,0,75,4.026,142.4054482,8.239 +27,07-09-2012,1840955.23,1,76,4.076,142.500303,8.239 +27,14-09-2012,1519604.5,0,68.72,4.088,142.5938833,8.239 +27,21-09-2012,1557485.75,0,66.1,4.203,142.6798167,8.239 +27,28-09-2012,1540687.63,0,64.92,4.158,142.76575,8.239 +27,05-10-2012,1591816.88,0,64.5,4.151,142.8516833,8 +27,12-10-2012,1660081.29,0,55.4,4.186,142.9376167,8 +27,19-10-2012,1620374.24,0,56.53,4.153,142.8633629,8 +27,26-10-2012,1703047.74,0,58.99,4.071,142.7624113,8 +28,05-02-2010,1672352.29,0,49.47,2.962,126.4420645,13.975 +28,12-02-2010,1558968.49,1,47.87,2.946,126.4962581,13.975 +28,19-02-2010,1491300.42,0,54.83,2.915,126.5262857,13.975 +28,26-02-2010,1542173.33,0,50.23,2.825,126.5522857,13.975 +28,05-03-2010,1608435.45,0,53.77,2.987,126.5782857,13.975 +28,12-03-2010,1326877.11,0,50.11,2.925,126.6042857,13.975 +28,19-03-2010,1279819.43,0,59.57,3.054,126.6066452,13.975 +28,26-03-2010,1245268.77,0,60.06,3.083,126.6050645,13.975 +28,02-04-2010,1441559.4,0,59.84,3.086,126.6034839,14.099 +28,09-04-2010,1382359.21,0,59.25,3.09,126.6019032,14.099 +28,16-04-2010,1268240.66,0,64.95,3.109,126.5621,14.099 +28,23-04-2010,1244177.21,0,64.55,3.05,126.4713333,14.099 +28,30-04-2010,1186971.02,0,67.38,3.105,126.3805667,14.099 +28,07-05-2010,1532893.22,0,70.15,3.127,126.2898,14.099 +28,14-05-2010,1245898.73,0,68.44,3.145,126.2085484,14.099 +28,21-05-2010,1217923.71,0,76.2,3.12,126.1843871,14.099 +28,28-05-2010,1176588.25,0,67.84,3.058,126.1602258,14.099 +28,04-06-2010,1543678.02,0,81.39,2.941,126.1360645,14.099 +28,11-06-2010,1348995.17,0,90.84,2.949,126.1119032,14.099 +28,18-06-2010,1267619.06,0,81.06,3.043,126.114,14.099 +28,25-06-2010,1231025.07,0,87.27,3.084,126.1266,14.099 +28,02-07-2010,1399960.15,0,91.98,3.105,126.1392,14.18 +28,09-07-2010,1340293.87,0,90.37,3.1,126.1518,14.18 +28,16-07-2010,1225336.41,0,97.18,3.094,126.1498065,14.18 +28,23-07-2010,1205884.98,0,99.22,3.112,126.1283548,14.18 +28,30-07-2010,1150204.71,0,96.31,3.017,126.1069032,14.18 +28,06-08-2010,1523101.38,0,92.95,3.123,126.0854516,14.18 +28,13-08-2010,1218688.09,0,87.01,3.159,126.064,14.18 +28,20-08-2010,1195897.6,0,92.81,3.041,126.0766452,14.18 +28,27-08-2010,1191585.92,0,93.19,3.129,126.0892903,14.18 +28,03-09-2010,1523410.71,0,83.12,3.087,126.1019355,14.18 +28,10-09-2010,1246062.17,1,83.63,3.044,126.1145806,14.18 +28,17-09-2010,1159812.35,0,82.45,3.028,126.1454667,14.18 +28,24-09-2010,1111797.21,0,81.77,2.939,126.1900333,14.18 +28,01-10-2010,1203080.41,0,85.2,3.001,126.2346,14.313 +28,08-10-2010,1334571.87,0,71.82,3.013,126.2791667,14.313 +28,15-10-2010,1158062.99,0,75,2.976,126.3266774,14.313 +28,22-10-2010,1120619.32,0,68.85,3.014,126.3815484,14.313 +28,29-10-2010,1231688.48,0,61.09,3.016,126.4364194,14.313 +28,05-11-2010,1501663.26,0,65.49,3.129,126.4912903,14.313 +28,12-11-2010,1266460.45,0,57.79,3.13,126.5461613,14.313 +28,19-11-2010,1179315.72,0,58.18,3.161,126.6072,14.313 +28,26-11-2010,1937033.5,1,47.66,3.162,126.6692667,14.313 +28,03-12-2010,1447916.29,0,43.33,3.041,126.7313333,14.313 +28,10-12-2010,1466164.49,0,50.01,3.203,126.7934,14.313 +28,17-12-2010,1510443.62,0,52.77,3.236,126.8794839,14.313 +28,24-12-2010,2026026.39,0,52.02,3.236,126.9835806,14.313 +28,31-12-2010,1090558.57,1,45.64,3.148,127.0876774,14.313 +28,07-01-2011,1402902.47,0,37.64,3.287,127.1917742,14.021 +28,14-01-2011,1098286.61,0,43.15,3.312,127.3009355,14.021 +28,21-01-2011,1079669.11,0,53.53,3.223,127.4404839,14.021 +28,28-01-2011,1127859.69,0,50.74,3.342,127.5800323,14.021 +28,04-02-2011,1564897.32,0,45.14,3.348,127.7195806,14.021 +28,11-02-2011,1397301.38,1,51.3,3.381,127.859129,14.021 +28,18-02-2011,1514828.82,0,53.35,3.43,127.99525,14.021 +28,25-02-2011,1311796.91,0,48.45,3.53,128.13,14.021 +28,04-03-2011,1723736.91,0,51.72,3.674,128.26475,14.021 +28,11-03-2011,1380836.35,0,57.75,3.818,128.3995,14.021 +28,18-03-2011,1286413.71,0,64.21,3.692,128.5121935,14.021 +28,25-03-2011,1201059.72,0,54.4,3.909,128.6160645,14.021 +28,01-04-2011,1336838.41,0,63.63,3.772,128.7199355,13.736 +28,08-04-2011,1414713.5,0,64.47,4.003,128.8238065,13.736 +28,15-04-2011,1240126.07,0,57.63,3.868,128.9107333,13.736 +28,22-04-2011,1297452,0,72.12,4.134,128.9553,13.736 +28,29-04-2011,1222367.9,0,68.27,4.151,128.9998667,13.736 +28,06-05-2011,1515890.38,0,68.4,4.193,129.0444333,13.736 +28,13-05-2011,1253316.3,0,70.93,4.202,129.089,13.736 +28,20-05-2011,1151282.31,0,66.59,4.169,129.0756774,13.736 +28,27-05-2011,1160043.98,0,76.67,4.087,129.0623548,13.736 +28,03-06-2011,1403779.25,0,71.81,4.031,129.0490323,13.736 +28,10-06-2011,1339972.83,0,78.72,3.981,129.0357097,13.736 +28,17-06-2011,1268503.49,0,86.84,3.935,129.0432,13.736 +28,24-06-2011,1208809.34,0,88.95,3.898,129.0663,13.736 +28,01-07-2011,1319054.57,0,89.85,3.842,129.0894,13.503 +28,08-07-2011,1459655.85,0,89.9,3.705,129.1125,13.503 +28,15-07-2011,1197373.13,0,88.1,3.692,129.1338387,13.503 +28,22-07-2011,1165870.54,0,91.17,3.794,129.1507742,13.503 +28,29-07-2011,1114530.29,0,93.29,3.805,129.1677097,13.503 +28,05-08-2011,1523870.89,0,90.61,3.803,129.1846452,13.503 +28,12-08-2011,1218764.94,0,91.04,3.701,129.2015806,13.503 +28,19-08-2011,1200019.74,0,91.74,3.743,129.2405806,13.503 +28,26-08-2011,1166479.51,0,94.61,3.74,129.2832581,13.503 +28,02-09-2011,1468871.49,0,93.66,3.798,129.3259355,13.503 +28,09-09-2011,1310087,1,88,3.913,129.3686129,13.503 +28,16-09-2011,1159212.1,0,76.36,3.918,129.4306,13.503 +28,23-09-2011,1109105.92,0,82.95,3.789,129.5183333,13.503 +28,30-09-2011,1120731.76,0,83.26,3.877,129.6060667,13.503 +28,07-10-2011,1557314.58,0,70.44,3.827,129.6938,12.89 +28,14-10-2011,1220984.94,0,67.31,3.805,129.7706452,12.89 +28,21-10-2011,1203172.05,0,73.05,3.842,129.7821613,12.89 +28,28-10-2011,1242746.06,0,67.41,3.727,129.7936774,12.89 +28,04-11-2011,1576654.67,0,59.77,3.828,129.8051935,12.89 +28,11-11-2011,1402654.95,0,48.76,3.824,129.8167097,12.89 +28,18-11-2011,1255081.22,0,54.2,3.813,129.8268333,12.89 +28,25-11-2011,1929738.27,1,53.25,3.622,129.8364,12.89 +28,02-12-2011,1368130.35,0,52.5,3.701,129.8459667,12.89 +28,09-12-2011,1467024.3,0,42.17,3.644,129.8555333,12.89 +28,16-12-2011,1429954.66,0,43.29,3.6,129.8980645,12.89 +28,23-12-2011,1796203.51,0,45.4,3.541,129.9845484,12.89 +28,30-12-2011,1270036.53,1,44.64,3.428,130.0710323,12.89 +28,06-01-2012,1466046.07,0,50.43,3.599,130.1575161,12.187 +28,13-01-2012,1161190.29,0,48.07,3.657,130.244,12.187 +28,20-01-2012,1129540.48,0,46.2,3.66,130.2792258,12.187 +28,27-01-2012,1132948.48,0,50.43,3.675,130.3144516,12.187 +28,03-02-2012,1531599.44,0,50.58,3.702,130.3496774,12.187 +28,10-02-2012,1572966.15,1,52.27,3.722,130.3849032,12.187 +28,17-02-2012,1501503.68,0,51.8,3.781,130.4546207,12.187 +28,24-02-2012,1323487.91,0,53.13,3.95,130.5502069,12.187 +28,02-03-2012,1451740.57,0,52.27,4.178,130.6457931,12.187 +28,09-03-2012,1680764.06,0,54.54,4.25,130.7413793,12.187 +28,16-03-2012,1337875.49,0,64.44,4.273,130.8261935,12.187 +28,23-03-2012,1216059.41,0,56.26,4.038,130.8966452,12.187 +28,30-03-2012,1209524.11,0,64.36,4.294,130.9670968,12.187 +28,06-04-2012,1559592.79,0,64.05,4.121,131.0375484,11.627 +28,13-04-2012,1290684.95,0,64.28,4.254,131.108,11.627 +28,20-04-2012,1180797.2,0,66.73,4.222,131.1173333,11.627 +28,27-04-2012,1170456.16,0,77.99,4.193,131.1266667,11.627 +28,04-05-2012,1450628.85,0,76.03,4.171,131.136,11.627 +28,11-05-2012,1264575.18,0,77.27,4.186,131.1453333,11.627 +28,18-05-2012,1213310.45,0,84.51,4.11,131.0983226,11.627 +28,25-05-2012,1151214.41,0,83.84,4.293,131.0287742,11.627 +28,01-06-2012,1245480.95,0,78.11,4.277,130.9592258,11.627 +28,08-06-2012,1440687.69,0,84.83,4.103,130.8896774,11.627 +28,15-06-2012,1229760.97,0,85.94,4.144,130.8295333,11.627 +28,22-06-2012,1180671.55,0,91.61,4.014,130.7929,11.627 +28,29-06-2012,1129031.98,0,90.47,3.875,130.7562667,11.627 +28,06-07-2012,1500863.54,0,89.13,3.765,130.7196333,10.926 +28,13-07-2012,1179915.04,0,95.61,3.723,130.683,10.926 +28,20-07-2012,1149427.48,0,85.53,3.726,130.7012903,10.926 +28,27-07-2012,1135035.09,0,93.47,3.769,130.7195806,10.926 +28,03-08-2012,1376520.1,0,88.16,3.76,130.737871,10.926 +28,10-08-2012,1269113.41,0,95.91,3.811,130.7561613,10.926 +28,17-08-2012,1184198.41,0,94.87,4.002,130.7909677,10.926 +28,24-08-2012,1199309.59,0,85.32,4.055,130.8381613,10.926 +28,31-08-2012,1227118.75,0,89.78,4.093,130.8853548,10.926 +28,07-09-2012,1469693.99,1,88.52,4.124,130.9325484,10.926 +28,14-09-2012,1124660.77,0,83.64,4.133,130.9776667,10.926 +28,21-09-2012,1135340.19,0,82.97,4.125,131.0103333,10.926 +28,28-09-2012,1129508.61,0,81.22,3.966,131.043,10.926 +28,05-10-2012,1462941.03,0,81.61,3.966,131.0756667,10.199 +28,12-10-2012,1205536.71,0,71.74,4.468,131.1083333,10.199 +28,19-10-2012,1143724.48,0,68.66,4.449,131.1499677,10.199 +28,26-10-2012,1213860.61,0,65.95,4.301,131.1930968,10.199 +29,05-02-2010,538634.46,0,24.36,2.788,131.5279032,10.064 +29,12-02-2010,529672.95,1,28.14,2.771,131.5866129,10.064 +29,19-02-2010,542399.07,0,31.96,2.747,131.637,10.064 +29,26-02-2010,488417.61,0,35.98,2.753,131.686,10.064 +29,05-03-2010,535087.91,0,36.82,2.766,131.735,10.064 +29,12-03-2010,519042.49,0,43.43,2.805,131.784,10.064 +29,19-03-2010,496851.6,0,46.03,2.834,131.8242903,10.064 +29,26-03-2010,552985.34,0,48.56,2.831,131.863129,10.064 +29,02-04-2010,599629.25,0,44.96,2.826,131.9019677,10.16 +29,09-04-2010,569937.23,0,57.06,2.849,131.9408065,10.16 +29,16-04-2010,509100.84,0,51.14,2.885,131.9809,10.16 +29,23-04-2010,505329.66,0,51.04,2.895,132.0226667,10.16 +29,30-04-2010,501013.47,0,50.96,2.935,132.0644333,10.16 +29,07-05-2010,568497.35,0,63.81,2.981,132.1062,10.16 +29,14-05-2010,518940.88,0,50.99,2.983,132.152129,10.16 +29,21-05-2010,502021.82,0,59.99,2.961,132.2230323,10.16 +29,28-05-2010,577627.66,0,65.64,2.906,132.2939355,10.16 +29,04-06-2010,588017.66,0,69.49,2.857,132.3648387,10.16 +29,11-06-2010,540716.58,0,65.01,2.83,132.4357419,10.16 +29,18-06-2010,558731.74,0,67.13,2.805,132.4733333,10.16 +29,25-06-2010,585548.79,0,74.37,2.81,132.4976,10.16 +29,02-07-2010,581473.55,0,72.88,2.815,132.5218667,10.409 +29,09-07-2010,563449.43,0,79.22,2.806,132.5461333,10.409 +29,16-07-2010,512292.01,0,76.3,2.796,132.5667742,10.409 +29,23-07-2010,506502.09,0,76.91,2.784,132.5825806,10.409 +29,30-07-2010,509872.77,0,76.35,2.792,132.5983871,10.409 +29,06-08-2010,519787.93,0,74.37,2.792,132.6141935,10.409 +29,13-08-2010,495269,0,74.75,2.81,132.63,10.409 +29,20-08-2010,531640.19,0,73.21,2.796,132.6616129,10.409 +29,27-08-2010,545766.13,0,68.99,2.77,132.6932258,10.409 +29,03-09-2010,579272.38,0,75.85,2.735,132.7248387,10.409 +29,10-09-2010,491290.37,1,68.6,2.717,132.7564516,10.409 +29,17-09-2010,463752.89,0,62.49,2.716,132.7670667,10.409 +29,24-09-2010,465338.41,0,65.14,2.718,132.7619333,10.409 +29,01-10-2010,474698.01,0,69.31,2.717,132.7568,10.524 +29,08-10-2010,530059.06,0,56.32,2.776,132.7516667,10.524 +29,15-10-2010,483011.69,0,55.23,2.878,132.7633548,10.524 +29,22-10-2010,505221.17,0,50.24,2.919,132.8170968,10.524 +29,29-10-2010,527058.59,0,57.73,2.938,132.8708387,10.524 +29,05-11-2010,521002.97,0,44.34,2.938,132.9245806,10.524 +29,12-11-2010,524450.7,0,44.42,2.961,132.9783226,10.524 +29,19-11-2010,508174.55,0,48.62,3.03,132.9172,10.524 +29,26-11-2010,975268.91,1,44.61,3.07,132.8369333,10.524 +29,03-12-2010,642678.53,0,39.42,3.065,132.7566667,10.524 +29,10-12-2010,713834.74,0,28.43,3.132,132.6764,10.524 +29,17-12-2010,850538.25,0,30.46,3.139,132.6804516,10.524 +29,24-12-2010,1130926.79,0,29.76,3.15,132.7477419,10.524 +29,31-12-2010,465992.02,1,28.49,3.177,132.8150323,10.524 +29,07-01-2011,455952.18,0,32.56,3.193,132.8823226,10.256 +29,14-01-2011,426905.26,0,24.76,3.215,132.9510645,10.256 +29,21-01-2011,445134.15,0,26.8,3.232,133.0285161,10.256 +29,28-01-2011,410426.97,0,20.61,3.243,133.1059677,10.256 +29,04-02-2011,504126.89,0,26.39,3.24,133.1834194,10.256 +29,11-02-2011,550387.78,1,28.89,3.255,133.260871,10.256 +29,18-02-2011,542529.21,0,35.34,3.263,133.3701429,10.256 +29,25-02-2011,483660.15,0,30.23,3.281,133.4921429,10.256 +29,04-03-2011,536031.67,0,33.52,3.437,133.6141429,10.256 +29,11-03-2011,493430.45,0,41.42,3.6,133.7361429,10.256 +29,18-03-2011,493653.43,0,43.38,3.634,133.8492258,10.256 +29,25-03-2011,478773.05,0,38.77,3.624,133.9587419,10.256 +29,01-04-2011,475615.26,0,36.04,3.638,134.0682581,9.966 +29,08-04-2011,505304.33,0,44.42,3.72,134.1777742,9.966 +29,15-04-2011,518245.97,0,48.88,3.823,134.2784667,9.966 +29,22-04-2011,589252.69,0,47.76,3.919,134.3571,9.966 +29,29-04-2011,493078.64,0,57.2,3.988,134.4357333,9.966 +29,06-05-2011,534372.53,0,53.63,4.078,134.5143667,9.966 +29,13-05-2011,549551.02,0,57.71,4.095,134.593,9.966 +29,20-05-2011,492932.51,0,58.56,4.101,134.6803871,9.966 +29,27-05-2011,550735.64,0,62.59,4.034,134.7677742,9.966 +29,03-06-2011,598251.57,0,70.09,3.973,134.8551613,9.966 +29,10-06-2011,558431.44,0,69.53,3.924,134.9425484,9.966 +29,17-06-2011,536914.17,0,63.97,3.873,135.0837333,9.966 +29,24-06-2011,545368.17,0,68.53,3.851,135.2652667,9.966 +29,01-07-2011,567114.6,0,70.8,3.815,135.4468,9.863 +29,08-07-2011,547586.07,0,74.22,3.784,135.6283333,9.863 +29,15-07-2011,505246.15,0,75.2,3.827,135.7837419,9.863 +29,22-07-2011,507335.75,0,77.79,3.882,135.8738387,9.863 +29,29-07-2011,474653.06,0,75.32,3.898,135.9639355,9.863 +29,05-08-2011,503486.37,0,75.33,3.903,136.0540323,9.863 +29,12-08-2011,471311.5,0,74.69,3.88,136.144129,9.863 +29,19-08-2011,498056,0,71.3,3.82,136.183129,9.863 +29,26-08-2011,608294.98,0,72.22,3.796,136.2136129,9.863 +29,02-09-2011,497085.91,0,69.16,3.784,136.2440968,9.863 +29,09-09-2011,505406.72,1,69.14,3.809,136.2745806,9.863 +29,16-09-2011,474129.35,0,68.08,3.809,136.3145,9.863 +29,23-09-2011,475696.37,0,62.36,3.758,136.367,9.863 +29,30-09-2011,446516.26,0,69.78,3.684,136.4195,9.863 +29,07-10-2011,514993,0,56.44,3.633,136.472,9.357 +29,14-10-2011,475776.45,0,62.63,3.583,136.5150968,9.357 +29,21-10-2011,505068.22,0,59.3,3.618,136.5017742,9.357 +29,28-10-2011,515119.64,0,49.31,3.604,136.4884516,9.357 +29,04-11-2011,620735.72,0,42.81,3.586,136.475129,9.357 +29,11-11-2011,531600.62,0,47.8,3.57,136.4618065,9.357 +29,18-11-2011,504601.29,0,50.62,3.571,136.4666667,9.357 +29,25-11-2011,913165.19,1,46.28,3.536,136.4788,9.357 +29,02-12-2011,579874.22,0,49.11,3.501,136.4909333,9.357 +29,09-12-2011,633240.53,0,45.35,3.47,136.5030667,9.357 +29,16-12-2011,736805.66,0,39.11,3.445,136.5335161,9.357 +29,23-12-2011,1016637.39,0,39.83,3.413,136.5883871,9.357 +29,30-12-2011,551743.05,1,36.28,3.402,136.6432581,9.357 +29,06-01-2012,469773.85,0,34.61,3.439,136.698129,8.988 +29,13-01-2012,444756.37,0,39,3.523,136.753,8.988 +29,20-01-2012,446863.31,0,29.16,3.542,136.8564194,8.988 +29,27-01-2012,395987.24,0,35.68,3.568,136.9598387,8.988 +29,03-02-2012,493159.35,0,40.58,3.633,137.0632581,8.988 +29,10-02-2012,545840.05,1,35.68,3.655,137.1666774,8.988 +29,17-02-2012,559606.91,0,36.25,3.703,137.2583103,8.988 +29,24-02-2012,488782.63,0,39,3.751,137.3411034,8.988 +29,02-03-2012,500801.72,0,37.47,3.827,137.4238966,8.988 +29,09-03-2012,504750.35,0,41.72,3.876,137.5066897,8.988 +29,16-03-2012,489293.72,0,46.06,3.867,137.5843871,8.988 +29,23-03-2012,517408.48,0,54.68,3.889,137.6552903,8.988 +29,30-03-2012,504566.28,0,46.4,3.921,137.7261935,8.988 +29,06-04-2012,633826.55,0,46.38,3.957,137.7970968,9.14 +29,13-04-2012,520493.83,0,49.89,4.025,137.868,9.14 +29,20-04-2012,525200.59,0,58.81,4.046,137.9230667,9.14 +29,27-04-2012,497250.22,0,51.42,4.023,137.9781333,9.14 +29,04-05-2012,504963.84,0,50.75,3.991,138.0332,9.14 +29,11-05-2012,529707.87,0,56.72,3.947,138.0882667,9.14 +29,18-05-2012,543706.04,0,61.9,3.899,138.1065806,9.14 +29,25-05-2012,549665.67,0,62.39,3.85,138.1101935,9.14 +29,01-06-2012,576252.35,0,70.01,3.798,138.1138065,9.14 +29,08-06-2012,554093.15,0,61.71,3.746,138.1174194,9.14 +29,15-06-2012,552338.76,0,66.56,3.683,138.1295333,9.14 +29,22-06-2012,581854.5,0,70.61,3.629,138.1629,9.14 +29,29-06-2012,555954.13,0,70.99,3.577,138.1962667,9.14 +29,06-07-2012,578832.41,0,77.41,3.538,138.2296333,9.419 +29,13-07-2012,514709.76,0,75.81,3.561,138.263,9.419 +29,20-07-2012,506705.36,0,76.57,3.61,138.2331935,9.419 +29,27-07-2012,475158.24,0,73.52,3.701,138.2033871,9.419 +29,03-08-2012,504754.74,0,72.99,3.698,138.1735806,9.419 +29,10-08-2012,518628.42,0,76.74,3.772,138.1437742,9.419 +29,17-08-2012,416881.66,0,74.92,3.84,138.1857097,9.419 +29,24-08-2012,615026.15,0,70.42,3.874,138.2814516,9.419 +29,31-08-2012,545844.91,0,71.93,3.884,138.3771935,9.419 +29,07-09-2012,540811.85,1,73.3,3.921,138.4729355,9.419 +29,14-09-2012,475127.18,0,66.42,3.988,138.5673,9.419 +29,21-09-2012,489079.23,0,63.38,4.056,138.6534,9.419 +29,28-09-2012,489674.23,0,62.17,4.018,138.7395,9.419 +29,05-10-2012,520632.8,0,62.09,4.027,138.8256,9.151 +29,12-10-2012,513737,0,54.18,4.029,138.9117,9.151 +29,19-10-2012,516909.24,0,55.28,4,138.8336129,9.151 +29,26-10-2012,534970.68,0,57.58,3.917,138.7281613,9.151 +30,05-02-2010,465108.52,0,39.05,2.572,210.7526053,8.324 +30,12-02-2010,497374.57,1,37.77,2.548,210.8979935,8.324 +30,19-02-2010,463513.26,0,39.75,2.514,210.9451605,8.324 +30,26-02-2010,472330.71,0,45.31,2.561,210.9759573,8.324 +30,05-03-2010,472591.07,0,48.61,2.625,211.0067542,8.324 +30,12-03-2010,468189.93,0,57.1,2.667,211.037551,8.324 +30,19-03-2010,445736.36,0,54.68,2.72,210.8733316,8.324 +30,26-03-2010,442457.35,0,51.66,2.732,210.6766095,8.324 +30,02-04-2010,457884.06,0,64.12,2.719,210.4798874,8.2 +30,09-04-2010,454800.96,0,65.74,2.77,210.2831653,8.2 +30,16-04-2010,471054.16,0,67.87,2.808,210.1495463,8.2 +30,23-04-2010,462454.39,0,64.21,2.795,210.1000648,8.2 +30,30-04-2010,456140.34,0,66.93,2.78,210.0505833,8.2 +30,07-05-2010,457883.94,0,70.87,2.835,210.0011018,8.2 +30,14-05-2010,461868.09,0,73.08,2.854,209.9984585,8.2 +30,21-05-2010,455751.84,0,74.24,2.826,210.2768443,8.2 +30,28-05-2010,462474.16,0,80.94,2.759,210.5552301,8.2 +30,04-06-2010,458343.7,0,82.68,2.705,210.833616,8.2 +30,11-06-2010,445530.16,0,83.51,2.668,211.1120018,8.2 +30,18-06-2010,447727.52,0,86.18,2.637,211.1096543,8.2 +30,25-06-2010,453210.24,0,87.01,2.653,210.9950134,8.2 +30,02-07-2010,450337.47,0,82.29,2.669,210.8803726,8.099 +30,09-07-2010,436293.4,0,81.67,2.642,210.7657317,8.099 +30,16-07-2010,438068.71,0,85.61,2.623,210.7577954,8.099 +30,23-07-2010,440491.33,0,87.17,2.608,210.8921319,8.099 +30,30-07-2010,437893.76,0,83.59,2.64,211.0264684,8.099 +30,06-08-2010,441407.06,0,90.3,2.627,211.1608049,8.099 +30,13-08-2010,444160.07,0,89.65,2.692,211.2951413,8.099 +30,20-08-2010,447139.8,0,89.58,2.664,211.2596586,8.099 +30,27-08-2010,443810.78,0,86.2,2.619,211.2241759,8.099 +30,03-09-2010,461548.98,0,82.57,2.577,211.1886931,8.099 +30,10-09-2010,455162.92,1,79.3,2.565,211.1532104,8.099 +30,17-09-2010,462058.19,0,83.03,2.582,211.1806415,8.099 +30,24-09-2010,448392.17,0,80.79,2.624,211.2552578,8.099 +30,01-10-2010,445475.3,0,70.28,2.603,211.3298742,8.163 +30,08-10-2010,462080.47,0,65.76,2.633,211.4044906,8.163 +30,15-10-2010,453943.89,0,68.61,2.72,211.4713286,8.163 +30,22-10-2010,459631.74,0,70.72,2.725,211.5187208,8.163 +30,29-10-2010,438334.39,0,67.51,2.716,211.5661131,8.163 +30,05-11-2010,484661.87,0,58.71,2.689,211.6135053,8.163 +30,12-11-2010,431266.64,0,60.95,2.728,211.6608975,8.163 +30,19-11-2010,423707.69,0,51.71,2.771,211.5470304,8.163 +30,26-11-2010,462732.36,1,62.96,2.735,211.4062867,8.163 +30,03-12-2010,407112.22,0,50.43,2.708,211.265543,8.163 +30,10-12-2010,428631.91,0,46.35,2.843,211.1247993,8.163 +30,17-12-2010,445332.28,0,48.63,2.869,211.0645458,8.163 +30,24-12-2010,519354.88,0,51.29,2.886,211.0646599,8.163 +30,31-12-2010,397631.02,1,47.19,2.943,211.064774,8.163 +30,07-01-2011,451077.21,0,44.24,2.976,211.0648881,8.028 +30,14-01-2011,465408.72,0,34.14,2.983,211.1176713,8.028 +30,21-01-2011,439132.62,0,42.72,3.016,211.4864691,8.028 +30,28-01-2011,425989.04,0,44.04,3.01,211.8552668,8.028 +30,04-02-2011,490970.95,0,36.33,2.989,212.2240646,8.028 +30,11-02-2011,470921.24,1,34.61,3.022,212.5928624,8.028 +30,18-02-2011,417070.51,0,59.87,3.045,212.9033115,8.028 +30,25-02-2011,432687.97,0,61.27,3.065,213.190421,8.028 +30,04-03-2011,443334.71,0,59.52,3.288,213.4775305,8.028 +30,11-03-2011,438529.81,0,54.69,3.459,213.7646401,8.028 +30,18-03-2011,425470.84,0,63.26,3.488,214.0156238,8.028 +30,25-03-2011,431754.01,0,70.33,3.473,214.2521573,8.028 +30,01-04-2011,437926.79,0,56.36,3.524,214.4886908,7.931 +30,08-04-2011,443889.5,0,68.62,3.622,214.7252242,7.931 +30,15-04-2011,426666.92,0,71.01,3.743,214.9420631,7.931 +30,22-04-2011,445358.73,0,70.79,3.807,215.1096657,7.931 +30,29-04-2011,423687.2,0,70.19,3.81,215.2772683,7.931 +30,06-05-2011,438789.52,0,61.87,3.906,215.4448709,7.931 +30,13-05-2011,424614.59,0,75.04,3.899,215.6124735,7.931 +30,20-05-2011,435102.2,0,68.36,3.907,215.3834778,7.931 +30,27-05-2011,429305.82,0,76.86,3.786,215.1544822,7.931 +30,03-06-2011,432808.48,0,83.82,3.699,214.9254865,7.931 +30,10-06-2011,424697.05,0,84.71,3.648,214.6964908,7.931 +30,17-06-2011,435481.03,0,87.54,3.637,214.6513538,7.931 +30,24-06-2011,422715.74,0,85.72,3.594,214.7441108,7.931 +30,01-07-2011,428782.38,0,87.57,3.524,214.8368678,7.852 +30,08-07-2011,419764.37,0,89.16,3.48,214.9296249,7.852 +30,15-07-2011,420515.63,0,91.05,3.575,215.0134426,7.852 +30,22-07-2011,423441.76,0,90.27,3.651,215.0749122,7.852 +30,29-07-2011,414245.96,0,91.56,3.682,215.1363819,7.852 +30,05-08-2011,431798.64,0,94.22,3.684,215.1978515,7.852 +30,12-08-2011,412224.67,0,92.32,3.638,215.2593211,7.852 +30,19-08-2011,414450.61,0,90.11,3.554,215.3229307,7.852 +30,26-08-2011,387944.83,0,92.07,3.523,215.386897,7.852 +30,02-09-2011,369722.32,0,91.94,3.533,215.4508632,7.852 +30,09-09-2011,370897.82,1,78.87,3.546,215.5148295,7.852 +30,16-09-2011,382914.66,0,80.62,3.526,215.6944378,7.852 +30,23-09-2011,391837.56,0,75.68,3.467,216.0282356,7.852 +30,30-09-2011,387001.13,0,78.91,3.355,216.3620333,7.852 +30,07-10-2011,417528.26,0,71.64,3.285,216.6958311,7.441 +30,14-10-2011,410711.99,0,69.79,3.274,217.0048261,7.441 +30,21-10-2011,428958.53,0,65.16,3.353,217.1650042,7.441 +30,28-10-2011,426151.88,0,65.46,3.372,217.3251824,7.441 +30,04-11-2011,432359.04,0,56.01,3.332,217.4853605,7.441 +30,11-11-2011,409686.63,0,59.8,3.297,217.6455387,7.441 +30,18-11-2011,436462.63,0,61.9,3.308,217.8670218,7.441 +30,25-11-2011,452163.93,1,56.43,3.236,218.1130269,7.441 +30,02-12-2011,412385.75,0,48.72,3.172,218.3590319,7.441 +30,09-12-2011,436741.02,0,41.44,3.158,218.605037,7.441 +30,16-12-2011,441265.08,0,50.56,3.159,218.8217928,7.441 +30,23-12-2011,492022.68,0,46.54,3.112,218.9995495,7.441 +30,30-12-2011,376777.45,1,45.16,3.129,219.1773063,7.441 +30,06-01-2012,457030.86,0,48.1,3.157,219.355063,7.057 +30,13-01-2012,447023.91,0,45,3.261,219.5328198,7.057 +30,20-01-2012,438760.62,0,52.21,3.268,219.6258417,7.057 +30,27-01-2012,433037.66,0,50.79,3.29,219.7188636,7.057 +30,03-02-2012,434080.74,0,55.83,3.36,219.8118854,7.057 +30,10-02-2012,451365.99,1,46.52,3.409,219.9049073,7.057 +30,17-02-2012,435109.11,0,45.03,3.51,220.0651993,7.057 +30,24-02-2012,425215.71,0,54.81,3.555,220.275944,7.057 +30,02-03-2012,438640.61,0,59.3,3.63,220.4866886,7.057 +30,09-03-2012,446617.89,0,57.16,3.669,220.6974332,7.057 +30,16-03-2012,413617.45,0,63.39,3.734,220.8498468,7.057 +30,23-03-2012,430222.97,0,62.96,3.787,220.9244858,7.057 +30,30-03-2012,449603.91,0,67.87,3.845,220.9991248,7.057 +30,06-04-2012,461511.92,0,69.02,3.891,221.0737638,6.891 +30,13-04-2012,428784.7,0,69.03,3.891,221.1484028,6.891 +30,20-04-2012,462909.41,0,66.97,3.877,221.2021074,6.891 +30,27-04-2012,433744.83,0,69.21,3.814,221.255812,6.891 +30,04-05-2012,454477.54,0,77.53,3.749,221.3095166,6.891 +30,11-05-2012,436070.45,0,74.14,3.688,221.3632212,6.891 +30,18-05-2012,460945.14,0,72.42,3.63,221.380331,6.891 +30,25-05-2012,449355.91,0,79.49,3.561,221.3828029,6.891 +30,01-06-2012,427021.18,0,79.24,3.501,221.3852748,6.891 +30,08-06-2012,437222.94,0,79.47,3.452,221.3877467,6.891 +30,15-06-2012,438523.24,0,81.51,3.393,221.4009901,6.891 +30,22-06-2012,428554.63,0,81.78,3.346,221.4411622,6.891 +30,29-06-2012,423192.4,0,88.05,3.286,221.4813343,6.891 +30,06-07-2012,440553.42,0,85.26,3.227,221.5215064,6.565 +30,13-07-2012,417640.34,0,82.51,3.256,221.5616784,6.565 +30,20-07-2012,427491.04,0,84.25,3.311,221.5701123,6.565 +30,27-07-2012,424581.17,0,88.09,3.407,221.5785461,6.565 +30,03-08-2012,425136.55,0,91.57,3.417,221.5869799,6.565 +30,10-08-2012,430878.28,0,89.57,3.494,221.5954138,6.565 +30,17-08-2012,423351.15,0,85.55,3.571,221.6751459,6.565 +30,24-08-2012,425296.65,0,77.72,3.62,221.8083518,6.565 +30,31-08-2012,439132.5,0,83.58,3.638,221.9415576,6.565 +30,07-09-2012,433565.77,1,88.4,3.73,222.0747635,6.565 +30,14-09-2012,437773.31,0,76.1,3.717,222.2174395,6.565 +30,21-09-2012,443891.64,0,71.54,3.721,222.4169362,6.565 +30,28-09-2012,425410.04,0,80.38,3.666,222.6164329,6.565 +30,05-10-2012,446751.45,0,70.28,3.617,222.8159296,6.17 +30,12-10-2012,434593.26,0,61.53,3.601,223.0154263,6.17 +30,19-10-2012,437537.29,0,68.52,3.594,223.0598077,6.17 +30,26-10-2012,439424.5,0,70.5,3.506,223.0783366,6.17 +31,05-02-2010,1469252.05,0,39.05,2.572,210.7526053,8.324 +31,12-02-2010,1543947.23,1,37.77,2.548,210.8979935,8.324 +31,19-02-2010,1473386.75,0,39.75,2.514,210.9451605,8.324 +31,26-02-2010,1344354.41,0,45.31,2.561,210.9759573,8.324 +31,05-03-2010,1384870.51,0,48.61,2.625,211.0067542,8.324 +31,12-03-2010,1366193.35,0,57.1,2.667,211.037551,8.324 +31,19-03-2010,1332261.01,0,54.68,2.72,210.8733316,8.324 +31,26-03-2010,1229635.7,0,51.66,2.732,210.6766095,8.324 +31,02-04-2010,1357600.68,0,64.12,2.719,210.4798874,8.2 +31,09-04-2010,1395710.09,0,65.74,2.77,210.2831653,8.2 +31,16-04-2010,1367448.28,0,67.87,2.808,210.1495463,8.2 +31,23-04-2010,1280465.8,0,64.21,2.795,210.1000648,8.2 +31,30-04-2010,1243200.24,0,66.93,2.78,210.0505833,8.2 +31,07-05-2010,1381796.8,0,70.87,2.835,210.0011018,8.2 +31,14-05-2010,1287288.59,0,73.08,2.854,209.9984585,8.2 +31,21-05-2010,1337405.6,0,74.24,2.826,210.2768443,8.2 +31,28-05-2010,1309437.17,0,80.94,2.759,210.5552301,8.2 +31,04-06-2010,1427624.5,0,82.68,2.705,210.833616,8.2 +31,11-06-2010,1377092.33,0,83.51,2.668,211.1120018,8.2 +31,18-06-2010,1368090.08,0,86.18,2.637,211.1096543,8.2 +31,25-06-2010,1303523.73,0,87.01,2.653,210.9950134,8.2 +31,02-07-2010,1311704.92,0,82.29,2.669,210.8803726,8.099 +31,09-07-2010,1315118.4,0,81.67,2.642,210.7657317,8.099 +31,16-07-2010,1335433.72,0,85.61,2.623,210.7577954,8.099 +31,23-07-2010,1276031.84,0,87.17,2.608,210.8921319,8.099 +31,30-07-2010,1231993.14,0,83.59,2.64,211.0264684,8.099 +31,06-08-2010,1352401.08,0,90.3,2.627,211.1608049,8.099 +31,13-08-2010,1327719.34,0,89.65,2.692,211.2951413,8.099 +31,20-08-2010,1376571.21,0,89.58,2.664,211.2596586,8.099 +31,27-08-2010,1326621.98,0,86.2,2.619,211.2241759,8.099 +31,03-09-2010,1302047.48,0,82.57,2.577,211.1886931,8.099 +31,10-09-2010,1308179.02,1,79.3,2.565,211.1532104,8.099 +31,17-09-2010,1294105.01,0,83.03,2.582,211.1806415,8.099 +31,24-09-2010,1230250.25,0,80.79,2.624,211.2552578,8.099 +31,01-10-2010,1213981.64,0,70.28,2.603,211.3298742,8.163 +31,08-10-2010,1300131.68,0,65.76,2.633,211.4044906,8.163 +31,15-10-2010,1265852.43,0,68.61,2.72,211.4713286,8.163 +31,22-10-2010,1262289.29,0,70.72,2.725,211.5187208,8.163 +31,29-10-2010,1257921.28,0,67.51,2.716,211.5661131,8.163 +31,05-11-2010,1324455.72,0,58.71,2.689,211.6135053,8.163 +31,12-11-2010,1352780.76,0,60.95,2.728,211.6608975,8.163 +31,19-11-2010,1359158.57,0,51.71,2.771,211.5470304,8.163 +31,26-11-2010,1858856.06,1,62.96,2.735,211.4062867,8.163 +31,03-12-2010,1338716.37,0,50.43,2.708,211.265543,8.163 +31,10-12-2010,1475685.1,0,46.35,2.843,211.1247993,8.163 +31,17-12-2010,1714667,0,48.63,2.869,211.0645458,8.163 +31,24-12-2010,2068942.97,0,51.29,2.886,211.0646599,8.163 +31,31-12-2010,1198071.6,1,47.19,2.943,211.064774,8.163 +31,07-01-2011,1311986.87,0,44.24,2.976,211.0648881,8.028 +31,14-01-2011,1350730.31,0,34.14,2.983,211.1176713,8.028 +31,21-01-2011,1344167.13,0,42.72,3.016,211.4864691,8.028 +31,28-01-2011,1254955.68,0,44.04,3.01,211.8552668,8.028 +31,04-02-2011,1443206.46,0,36.33,2.989,212.2240646,8.028 +31,11-02-2011,1539230.32,1,34.61,3.022,212.5928624,8.028 +31,18-02-2011,1539063.91,0,59.87,3.045,212.9033115,8.028 +31,25-02-2011,1365678.22,0,61.27,3.065,213.190421,8.028 +31,04-03-2011,1412721.18,0,59.52,3.288,213.4775305,8.028 +31,11-03-2011,1405572.93,0,54.69,3.459,213.7646401,8.028 +31,18-03-2011,1425559.02,0,63.26,3.488,214.0156238,8.028 +31,25-03-2011,1357036.1,0,70.33,3.473,214.2521573,8.028 +31,01-04-2011,1344890.73,0,56.36,3.524,214.4886908,7.931 +31,08-04-2011,1416790.17,0,68.62,3.622,214.7252242,7.931 +31,15-04-2011,1408464.08,0,71.01,3.743,214.9420631,7.931 +31,22-04-2011,1461393.91,0,70.79,3.807,215.1096657,7.931 +31,29-04-2011,1331137.96,0,70.19,3.81,215.2772683,7.931 +31,06-05-2011,1388755.61,0,61.87,3.906,215.4448709,7.931 +31,13-05-2011,1408118.22,0,75.04,3.899,215.6124735,7.931 +31,20-05-2011,1387365.19,0,68.36,3.907,215.3834778,7.931 +31,27-05-2011,1342273.64,0,76.86,3.786,215.1544822,7.931 +31,03-06-2011,1430348.1,0,83.82,3.699,214.9254865,7.931 +31,10-06-2011,1425299.37,0,84.71,3.648,214.6964908,7.931 +31,17-06-2011,1491039.14,0,87.54,3.637,214.6513538,7.931 +31,24-06-2011,1375962.46,0,85.72,3.594,214.7441108,7.931 +31,01-07-2011,1371889.27,0,87.57,3.524,214.8368678,7.852 +31,08-07-2011,1423144.47,0,89.16,3.48,214.9296249,7.852 +31,15-07-2011,1415473.91,0,91.05,3.575,215.0134426,7.852 +31,22-07-2011,1401944.8,0,90.27,3.651,215.0749122,7.852 +31,29-07-2011,1308122.15,0,91.56,3.682,215.1363819,7.852 +31,05-08-2011,1428993.33,0,94.22,3.684,215.1978515,7.852 +31,12-08-2011,1443311.49,0,92.32,3.638,215.2593211,7.852 +31,19-08-2011,1487542.53,0,90.11,3.554,215.3229307,7.852 +31,26-08-2011,1417267.07,0,92.07,3.523,215.386897,7.852 +31,02-09-2011,1385769.03,0,91.94,3.533,215.4508632,7.852 +31,09-09-2011,1376670.27,1,78.87,3.546,215.5148295,7.852 +31,16-09-2011,1363460.86,0,80.62,3.526,215.6944378,7.852 +31,23-09-2011,1347607.74,0,75.68,3.467,216.0282356,7.852 +31,30-09-2011,1285534.74,0,78.91,3.355,216.3620333,7.852 +31,07-10-2011,1427383.24,0,71.64,3.285,216.6958311,7.441 +31,14-10-2011,1378340.18,0,69.79,3.274,217.0048261,7.441 +31,21-10-2011,1409310.4,0,65.16,3.353,217.1650042,7.441 +31,28-10-2011,1346862.72,0,65.46,3.372,217.3251824,7.441 +31,04-11-2011,1426405.46,0,56.01,3.332,217.4853605,7.441 +31,11-11-2011,1444783.64,0,59.8,3.297,217.6455387,7.441 +31,18-11-2011,1445174.79,0,61.9,3.308,217.8670218,7.441 +31,25-11-2011,1934099.65,1,56.43,3.236,218.1130269,7.441 +31,02-12-2011,1388809.43,0,48.72,3.172,218.3590319,7.441 +31,09-12-2011,1556798.94,0,41.44,3.158,218.605037,7.441 +31,16-12-2011,1611196.61,0,50.56,3.159,218.8217928,7.441 +31,23-12-2011,2026176.14,0,46.54,3.112,218.9995495,7.441 +31,30-12-2011,1355405.95,1,45.16,3.129,219.1773063,7.441 +31,06-01-2012,1401232.52,0,48.1,3.157,219.355063,7.057 +31,13-01-2012,1377485.12,0,45,3.261,219.5328198,7.057 +31,20-01-2012,1372504.9,0,52.21,3.268,219.6258417,7.057 +31,27-01-2012,1259941.48,0,50.79,3.29,219.7188636,7.057 +31,03-02-2012,1391479.91,0,55.83,3.36,219.8118854,7.057 +31,10-02-2012,1527688.58,1,46.52,3.409,219.9049073,7.057 +31,17-02-2012,1570813.52,0,45.03,3.51,220.0651993,7.057 +31,24-02-2012,1392543.37,0,54.81,3.555,220.275944,7.057 +31,02-03-2012,1427881.22,0,59.3,3.63,220.4866886,7.057 +31,09-03-2012,1439034.86,0,57.16,3.669,220.6974332,7.057 +31,16-03-2012,1481728.13,0,63.39,3.734,220.8498468,7.057 +31,23-03-2012,1365824.97,0,62.96,3.787,220.9244858,7.057 +31,30-03-2012,1318854.22,0,67.87,3.845,220.9991248,7.057 +31,06-04-2012,1496169.81,0,69.02,3.891,221.0737638,6.891 +31,13-04-2012,1407842.91,0,69.03,3.891,221.1484028,6.891 +31,20-04-2012,1407036.59,0,66.97,3.877,221.2021074,6.891 +31,27-04-2012,1311352.25,0,69.21,3.814,221.255812,6.891 +31,04-05-2012,1391257.28,0,77.53,3.749,221.3095166,6.891 +31,11-05-2012,1392938.06,0,74.14,3.688,221.3632212,6.891 +31,18-05-2012,1441473.82,0,72.42,3.63,221.380331,6.891 +31,25-05-2012,1397094.26,0,79.49,3.561,221.3828029,6.891 +31,01-06-2012,1404516.29,0,79.24,3.501,221.3852748,6.891 +31,08-06-2012,1443285.79,0,79.47,3.452,221.3877467,6.891 +31,15-06-2012,1431003.43,0,81.51,3.393,221.4009901,6.891 +31,22-06-2012,1394065.76,0,81.78,3.346,221.4411622,6.891 +31,29-06-2012,1349202.25,0,88.05,3.286,221.4813343,6.891 +31,06-07-2012,1458059.42,0,85.26,3.227,221.5215064,6.565 +31,13-07-2012,1374301.34,0,82.51,3.256,221.5616784,6.565 +31,20-07-2012,1392395.2,0,84.25,3.311,221.5701123,6.565 +31,27-07-2012,1303732.36,0,88.09,3.407,221.5785461,6.565 +31,03-08-2012,1390174.63,0,91.57,3.417,221.5869799,6.565 +31,10-08-2012,1386472.59,0,89.57,3.494,221.5954138,6.565 +31,17-08-2012,1410181.7,0,85.55,3.571,221.6751459,6.565 +31,24-08-2012,1379783.21,0,77.72,3.62,221.8083518,6.565 +31,31-08-2012,1373651.49,0,83.58,3.638,221.9415576,6.565 +31,07-09-2012,1358111.62,1,88.4,3.73,222.0747635,6.565 +31,14-09-2012,1327705.44,0,76.1,3.717,222.2174395,6.565 +31,21-09-2012,1373064.87,0,71.54,3.721,222.4169362,6.565 +31,28-09-2012,1279080.58,0,80.38,3.666,222.6164329,6.565 +31,05-10-2012,1363365.05,0,70.28,3.617,222.8159296,6.17 +31,12-10-2012,1401113.42,0,61.53,3.601,223.0154263,6.17 +31,19-10-2012,1378730.45,0,68.52,3.594,223.0598077,6.17 +31,26-10-2012,1340232.55,0,70.5,3.506,223.0783366,6.17 +32,05-02-2010,1087616.19,0,34.43,2.58,189.3816974,9.014 +32,12-02-2010,1123566.12,1,28.09,2.572,189.4642725,9.014 +32,19-02-2010,1082559.06,0,29.16,2.55,189.5340998,9.014 +32,26-02-2010,1053247.1,0,26.64,2.586,189.6018023,9.014 +32,05-03-2010,1066566.74,0,37.72,2.62,189.6695049,9.014 +32,12-03-2010,1093319.37,0,39.88,2.684,189.7372075,9.014 +32,19-03-2010,1059781.78,0,42.43,2.692,189.734262,9.014 +32,26-03-2010,1076021.58,0,36.59,2.717,189.7195417,9.014 +32,02-04-2010,1131732.94,0,48.28,2.725,189.7048215,8.963 +32,09-04-2010,1095889.22,0,44.88,2.75,189.6901012,8.963 +32,16-04-2010,1082763.27,0,53.49,2.765,189.6628845,8.963 +32,23-04-2010,1072474.8,0,50.06,2.776,189.6190057,8.963 +32,30-04-2010,1066792.63,0,47.51,2.766,189.575127,8.963 +32,07-05-2010,1133657.58,0,48.94,2.771,189.5312483,8.963 +32,14-05-2010,1079314.52,0,46.42,2.788,189.4904116,8.963 +32,21-05-2010,1143819.35,0,55.89,2.776,189.467827,8.963 +32,28-05-2010,1205662.85,0,64.69,2.737,189.4452425,8.963 +32,04-06-2010,1149234.96,0,66.69,2.7,189.422658,8.963 +32,11-06-2010,1192074.09,0,70.86,2.684,189.4000734,8.963 +32,18-06-2010,1150191.72,0,60.94,2.674,189.4185259,8.963 +32,25-06-2010,1124763.74,0,72.42,2.715,189.4533931,8.963 +32,02-07-2010,1187988.64,0,74.74,2.728,189.4882603,9.017 +32,09-07-2010,1077253.67,0,67.55,2.711,189.5231276,9.017 +32,16-07-2010,1120172.24,0,76.2,2.699,189.6125456,9.017 +32,23-07-2010,1109574.11,0,75.69,2.691,189.774698,9.017 +32,30-07-2010,1065350.56,0,75.62,2.69,189.9368504,9.017 +32,06-08-2010,1144552.09,0,72.95,2.69,190.0990028,9.017 +32,13-08-2010,1157975.68,0,74.97,2.723,190.2611552,9.017 +32,20-08-2010,1189887.86,0,71.46,2.732,190.2948237,9.017 +32,27-08-2010,1140501.03,0,74.95,2.731,190.3284922,9.017 +32,03-09-2010,1095932.51,0,70.2,2.773,190.3621607,9.017 +32,10-09-2010,1028635.39,1,68.44,2.78,190.3958293,9.017 +32,17-09-2010,1043962.36,0,67.17,2.8,190.4688287,9.017 +32,24-09-2010,1067432.1,0,64.19,2.793,190.5713264,9.017 +32,01-10-2010,1061089.56,0,66.14,2.759,190.6738241,9.137 +32,08-10-2010,1085483.44,0,61.81,2.745,190.7763218,9.137 +32,15-10-2010,1096692.88,0,52.96,2.762,190.8623087,9.137 +32,22-10-2010,1102185,0,52.3,2.762,190.9070184,9.137 +32,29-10-2010,1115138.51,0,45.45,2.748,190.951728,9.137 +32,05-11-2010,1063056.21,0,49.2,2.729,190.9964377,9.137 +32,12-11-2010,1141019.11,0,42.3,2.737,191.0411474,9.137 +32,19-11-2010,1150729.89,0,36.24,2.758,191.0312172,9.137 +32,26-11-2010,1634635.86,1,29.97,2.742,191.0121805,9.137 +32,03-12-2010,1200892.56,0,35.18,2.712,190.9931437,9.137 +32,10-12-2010,1377322.73,0,36.62,2.728,190.9741069,9.137 +32,17-12-2010,1557776.1,0,36.07,2.778,191.0303376,9.137 +32,24-12-2010,1949183.14,0,30.72,2.781,191.1430189,9.137 +32,31-12-2010,955463.84,1,27.7,2.829,191.2557002,9.137 +32,07-01-2011,1046416.17,0,23.78,2.882,191.3683815,8.818 +32,14-01-2011,1028206.51,0,21.69,2.911,191.4784939,8.818 +32,21-01-2011,1078348.91,0,34.54,2.973,191.5731924,8.818 +32,28-01-2011,1006814.85,0,34.86,3.008,191.667891,8.818 +32,04-02-2011,1070457.8,0,15.47,3.011,191.7625895,8.818 +32,11-02-2011,1124357.2,1,18.51,3.037,191.8572881,8.818 +32,18-02-2011,1183528.58,0,42.09,3.051,191.9178331,8.818 +32,25-02-2011,1054754.67,0,33,3.101,191.9647167,8.818 +32,04-03-2011,1106847.62,0,39.17,3.232,192.0116004,8.818 +32,11-03-2011,1101458.21,0,36.51,3.372,192.058484,8.818 +32,18-03-2011,1100765.5,0,45.25,3.406,192.1237981,8.818 +32,25-03-2011,1068719.22,0,46.7,3.414,192.1964844,8.818 +32,01-04-2011,1051121.02,0,44.83,3.461,192.2691707,8.595 +32,08-04-2011,1102975.59,0,48.81,3.532,192.3418571,8.595 +32,15-04-2011,1120508.14,0,45.97,3.611,192.4225954,8.595 +32,22-04-2011,1210602.91,0,48.69,3.636,192.5234638,8.595 +32,29-04-2011,1107494.55,0,44.86,3.663,192.6243322,8.595 +32,06-05-2011,1181793.55,0,46.65,3.735,192.7252006,8.595 +32,13-05-2011,1138162.76,0,56.09,3.767,192.826069,8.595 +32,20-05-2011,1145084.76,0,45.71,3.828,192.831317,8.595 +32,27-05-2011,1175447.49,0,55.13,3.795,192.8365651,8.595 +32,03-06-2011,1167757,0,61.25,3.763,192.8418131,8.595 +32,10-06-2011,1239741.34,0,65.49,3.735,192.8470612,8.595 +32,17-06-2011,1192031.38,0,67.38,3.697,192.9034759,8.595 +32,24-06-2011,1163869.52,0,65.06,3.661,192.9982655,8.595 +32,01-07-2011,1199845.29,0,72.86,3.597,193.0930552,8.622 +32,08-07-2011,1110244.52,0,72.56,3.54,193.1878448,8.622 +32,15-07-2011,1144254.26,0,70.55,3.532,193.3125484,8.622 +32,22-07-2011,1185674.48,0,76,3.545,193.5120367,8.622 +32,29-07-2011,1169988.62,0,75.91,3.547,193.711525,8.622 +32,05-08-2011,1201694.14,0,74.83,3.554,193.9110133,8.622 +32,12-08-2011,1206795.74,0,74.2,3.542,194.1105017,8.622 +32,19-08-2011,1221318.17,0,73.72,3.499,194.2500634,8.622 +32,26-08-2011,1183740.91,0,75.64,3.485,194.3796374,8.622 +32,02-09-2011,1152117.5,0,74.6,3.511,194.5092113,8.622 +32,09-09-2011,1128237.3,1,61.24,3.566,194.6387853,8.622 +32,16-09-2011,1142499.25,0,60.88,3.596,194.7419707,8.622 +32,23-09-2011,1116140.29,0,58.66,3.581,194.8099713,8.622 +32,30-09-2011,1088943.98,0,65.04,3.538,194.8779718,8.622 +32,07-10-2011,1149448.02,0,62.62,3.498,194.9459724,8.513 +32,14-10-2011,1175420.26,0,50.15,3.491,195.0261012,8.513 +32,21-10-2011,1151258.74,0,48.87,3.548,195.1789994,8.513 +32,28-10-2011,1185391.96,0,42.76,3.55,195.3318977,8.513 +32,04-11-2011,1204628.28,0,37.95,3.527,195.4847959,8.513 +32,11-11-2011,1182733,0,38.1,3.505,195.6376941,8.513 +32,18-11-2011,1181651.55,0,42.61,3.479,195.7184713,8.513 +32,25-11-2011,1684468.66,1,40.22,3.424,195.7704,8.513 +32,02-12-2011,1179773.88,0,33.8,3.378,195.8223287,8.513 +32,09-12-2011,1415746.91,0,17.94,3.331,195.8742575,8.513 +32,16-12-2011,1556017.91,0,26.23,3.266,195.9841685,8.513 +32,23-12-2011,1959526.96,0,25.97,3.173,196.1713893,8.513 +32,30-12-2011,1102367.65,1,32.99,3.119,196.3586101,8.513 +32,06-01-2012,1099937.25,0,36.75,3.095,196.5458309,8.256 +32,13-01-2012,1071598.36,0,28.99,3.077,196.7330517,8.256 +32,20-01-2012,1080012.04,0,36.86,3.055,196.7796652,8.256 +32,27-01-2012,1051864.6,0,36.67,3.038,196.8262786,8.256 +32,03-02-2012,1156826.31,0,35.89,3.031,196.8728921,8.256 +32,10-02-2012,1129422.86,1,23.34,3.103,196.9195056,8.256 +32,17-02-2012,1243812.59,0,24.26,3.113,196.9432711,8.256 +32,24-02-2012,1091822.72,0,33.41,3.129,196.9499007,8.256 +32,02-03-2012,1153332.89,0,33.4,3.191,196.9565303,8.256 +32,09-03-2012,1124537.97,0,39.9,3.286,196.9631599,8.256 +32,16-03-2012,1138101.18,0,51.51,3.486,197.0457208,8.256 +32,23-03-2012,1146632.46,0,47.64,3.664,197.2295234,8.256 +32,30-03-2012,1108686.87,0,56.09,3.75,197.4133259,8.256 +32,06-04-2012,1270577.01,0,51.49,3.854,197.5971285,8.09 +32,13-04-2012,1171834.47,0,52.1,3.901,197.780931,8.09 +32,20-04-2012,1121405.91,0,49.15,3.936,197.7227385,8.09 +32,27-04-2012,1126962.44,0,61.76,3.927,197.664546,8.09 +32,04-05-2012,1187384.53,0,58.29,3.903,197.6063534,8.09 +32,11-05-2012,1187051.07,0,55.4,3.87,197.5481609,8.09 +32,18-05-2012,1177539.71,0,57.46,3.837,197.5553137,8.09 +32,25-05-2012,1232784.22,0,59.74,3.804,197.5886046,8.09 +32,01-06-2012,1157557.79,0,62.84,3.764,197.6218954,8.09 +32,08-06-2012,1246322.44,0,71.14,3.741,197.6551863,8.09 +32,15-06-2012,1234759.54,0,70.91,3.723,197.692292,8.09 +32,22-06-2012,1196880.11,0,74.85,3.735,197.7389345,8.09 +32,29-06-2012,1178211.81,0,81.95,3.693,197.785577,8.09 +32,06-07-2012,1214183.97,0,78.68,3.646,197.8322195,7.872 +32,13-07-2012,1141184.66,0,71.57,3.613,197.8788621,7.872 +32,20-07-2012,1167829.33,0,77.76,3.585,197.9290378,7.872 +32,27-07-2012,1144901.52,0,77.56,3.57,197.9792136,7.872 +32,03-08-2012,1183571.35,0,75.09,3.528,198.0293893,7.872 +32,10-08-2012,1227469.2,0,75.93,3.509,198.0795651,7.872 +32,17-08-2012,1261306.37,0,70.75,3.545,198.1001057,7.872 +32,24-08-2012,1272809.11,0,70.12,3.558,198.0984199,7.872 +32,31-08-2012,1183979.27,0,76.12,3.556,198.0967341,7.872 +32,07-09-2012,1126685.95,1,72.56,3.596,198.0950484,7.872 +32,14-09-2012,1156377.47,0,64.05,3.659,198.1267184,7.872 +32,21-09-2012,1159119.6,0,63.49,3.765,198.358523,7.872 +32,28-09-2012,1157111.15,0,60.62,3.789,198.5903276,7.872 +32,05-10-2012,1202775.24,0,55.34,3.779,198.8221322,7.557 +32,12-10-2012,1176681.31,0,43.49,3.76,199.0539368,7.557 +32,19-10-2012,1199292.06,0,53.57,3.75,199.1481963,7.557 +32,26-10-2012,1219979.29,0,47.22,3.686,199.2195317,7.557 +33,05-02-2010,274593.43,0,58.4,2.962,126.4420645,10.115 +33,12-02-2010,294882.83,1,55.47,2.828,126.4962581,10.115 +33,19-02-2010,296850.83,0,62.16,2.915,126.5262857,10.115 +33,26-02-2010,284052.77,0,56.5,2.825,126.5522857,10.115 +33,05-03-2010,291484.89,0,59.17,2.877,126.5782857,10.115 +33,12-03-2010,312161,0,55.61,3.034,126.6042857,10.115 +33,19-03-2010,282235.73,0,64.6,3.054,126.6066452,10.115 +33,26-03-2010,262893.76,0,64.09,2.98,126.6050645,10.115 +33,02-04-2010,274634.52,0,66.79,3.086,126.6034839,9.849 +33,09-04-2010,325201.05,0,68.43,3.004,126.6019032,9.849 +33,16-04-2010,307779.64,0,72.44,3.109,126.5621,9.849 +33,23-04-2010,263263.02,0,71.59,3.05,126.4713333,9.849 +33,30-04-2010,275883.23,0,73.29,3.105,126.3805667,9.849 +33,07-05-2010,326870.13,0,75.4,3.127,126.2898,9.849 +33,14-05-2010,331173.51,0,76.8,3.145,126.2085484,9.849 +33,21-05-2010,294264.2,0,82.8,3.12,126.1843871,9.849 +33,28-05-2010,279246.33,0,78.47,3.058,126.1602258,9.849 +33,04-06-2010,285100,0,86.06,2.941,126.1360645,9.849 +33,11-06-2010,310800.79,0,93.52,3.057,126.1119032,9.849 +33,18-06-2010,272399.08,0,87.69,2.935,126.114,9.849 +33,25-06-2010,259419.91,0,93.66,3.084,126.1266,9.849 +33,02-07-2010,267495.76,0,97.66,2.978,126.1392,9.495 +33,09-07-2010,302423.93,0,95.88,3.1,126.1518,9.495 +33,16-07-2010,280937.84,0,100.14,2.971,126.1498065,9.495 +33,23-07-2010,252734.31,0,97.04,3.112,126.1283548,9.495 +33,30-07-2010,242047.03,0,92.71,3.017,126.1069032,9.495 +33,06-08-2010,262789.95,0,92.51,3.123,126.0854516,9.495 +33,13-08-2010,265367.51,0,95.57,3.049,126.064,9.495 +33,20-08-2010,230519.49,0,96.46,3.041,126.0766452,9.495 +33,27-08-2010,224031.19,0,94,3.022,126.0892903,9.495 +33,03-09-2010,237405.82,0,90.82,3.087,126.1019355,9.495 +33,10-09-2010,272834.88,1,91.77,2.961,126.1145806,9.495 +33,17-09-2010,246277.18,0,89.43,3.028,126.1454667,9.495 +33,24-09-2010,231976.84,0,91.18,2.939,126.1900333,9.495 +33,01-10-2010,224294.39,0,91.45,3.001,126.2346,9.265 +33,08-10-2010,266484.19,0,79.02,2.924,126.2791667,9.265 +33,15-10-2010,251732.92,0,80.49,3.08,126.3266774,9.265 +33,22-10-2010,234175.92,0,74.2,3.014,126.3815484,9.265 +33,29-10-2010,213538.32,0,71.34,3.13,126.4364194,9.265 +33,05-11-2010,246124.61,0,74.23,3.009,126.4912903,9.265 +33,12-11-2010,272803.94,0,65.21,3.13,126.5461613,9.265 +33,19-11-2010,224639.76,0,61.95,3.047,126.6072,9.265 +33,26-11-2010,240044.57,1,56.87,3.162,126.6692667,9.265 +33,03-12-2010,209986.25,0,52.82,3.041,126.7313333,9.265 +33,10-12-2010,253050.1,0,60.72,3.091,126.7934,9.265 +33,17-12-2010,238875.26,0,61.12,3.125,126.8794839,9.265 +33,24-12-2010,249246.8,0,60.43,3.236,126.9835806,9.265 +33,31-12-2010,219804.85,1,52.91,3.148,127.0876774,9.265 +33,07-01-2011,243948.82,0,46.25,3.287,127.1917742,8.951 +33,14-01-2011,259527.75,0,53.63,3.312,127.3009355,8.951 +33,21-01-2011,244856.44,0,59.46,3.336,127.4404839,8.951 +33,28-01-2011,231155.9,0,56.62,3.231,127.5800323,8.951 +33,04-02-2011,234218.03,0,49.26,3.348,127.7195806,8.951 +33,11-02-2011,276198.74,1,53.35,3.381,127.859129,8.951 +33,18-02-2011,252349.6,0,62.03,3.43,127.99525,8.951 +33,25-02-2011,242901.21,0,54.89,3.398,128.13,8.951 +33,04-03-2011,245435.8,0,59.51,3.674,128.26475,8.951 +33,11-03-2011,270921.44,0,66.51,3.63,128.3995,8.951 +33,18-03-2011,247234.47,0,72.72,3.892,128.5121935,8.951 +33,25-03-2011,238084.08,0,63.34,3.716,128.6160645,8.951 +33,01-04-2011,232769.09,0,71.41,3.772,128.7199355,8.687 +33,08-04-2011,271924.73,0,75.11,3.818,128.8238065,8.687 +33,15-04-2011,275749.56,0,64.64,4.089,128.9107333,8.687 +33,22-04-2011,248603.3,0,79.46,3.917,128.9553,8.687 +33,29-04-2011,248561.86,0,77.44,4.151,128.9998667,8.687 +33,06-05-2011,257031.19,0,77.92,4.193,129.0444333,8.687 +33,13-05-2011,279466.87,0,78.24,4.202,129.089,8.687 +33,20-05-2011,239206.26,0,76.07,3.99,129.0756774,8.687 +33,27-05-2011,239431.85,0,82.32,3.933,129.0623548,8.687 +33,03-06-2011,243477.03,0,82.93,3.893,129.0490323,8.687 +33,10-06-2011,258427.39,0,87.02,3.981,129.0357097,8.687 +33,17-06-2011,238172.66,0,91.11,3.935,129.0432,8.687 +33,24-06-2011,238433.53,0,94.11,3.807,129.0663,8.687 +33,01-07-2011,226702.36,0,98.43,3.842,129.0894,8.442 +33,08-07-2011,262717.71,0,96.44,3.793,129.1125,8.442 +33,15-07-2011,265003.47,0,92.83,3.779,129.1338387,8.442 +33,22-07-2011,238915.05,0,97.17,3.697,129.1507742,8.442 +33,29-07-2011,224806.96,0,95.28,3.694,129.1677097,8.442 +33,05-08-2011,242456.39,0,96.93,3.803,129.1846452,8.442 +33,12-08-2011,274721.85,0,96,3.794,129.2015806,8.442 +33,19-08-2011,242771.37,0,95.89,3.743,129.2405806,8.442 +33,26-08-2011,237095.82,0,99.66,3.663,129.2832581,8.442 +33,02-09-2011,239198.36,0,99.2,3.798,129.3259355,8.442 +33,09-09-2011,281842.28,1,96.22,3.771,129.3686129,8.442 +33,16-09-2011,262407.57,0,85.79,3.784,129.4306,8.442 +33,23-09-2011,234793.12,0,88.93,3.789,129.5183333,8.442 +33,30-09-2011,229731.98,0,89.1,3.877,129.6060667,8.442 +33,07-10-2011,262159.13,0,81.16,3.827,129.6938,8.01 +33,14-10-2011,272487.33,0,76.49,3.698,129.7706452,8.01 +33,21-10-2011,233543.08,0,81.74,3.842,129.7821613,8.01 +33,28-10-2011,231319.96,0,76.73,3.843,129.7936774,8.01 +33,04-11-2011,236157.12,0,71.91,3.828,129.8051935,8.01 +33,11-11-2011,271961.04,0,58.75,3.677,129.8167097,8.01 +33,18-11-2011,251294.5,0,63.35,3.669,129.8268333,8.01 +33,25-11-2011,255996.47,1,62.35,3.76,129.8364,8.01 +33,02-12-2011,220060.35,0,59.12,3.701,129.8459667,8.01 +33,09-12-2011,270373.05,0,47.7,3.644,129.8555333,8.01 +33,16-12-2011,259638.35,0,53.18,3.489,129.8980645,8.01 +33,23-12-2011,256235.19,0,53.39,3.541,129.9845484,8.01 +33,30-12-2011,215359.21,1,51.6,3.428,130.0710323,8.01 +33,06-01-2012,267058.08,0,60.92,3.443,130.1575161,7.603 +33,13-01-2012,279447.22,0,54.61,3.477,130.244,7.603 +33,20-01-2012,244899.2,0,55.99,3.66,130.2792258,7.603 +33,27-01-2012,236920.49,0,56.33,3.675,130.3144516,7.603 +33,03-02-2012,256091.32,0,59.53,3.543,130.3496774,7.603 +33,10-02-2012,282552.58,1,59.94,3.722,130.3849032,7.603 +33,17-02-2012,266300.98,0,57.8,3.781,130.4546207,7.603 +33,24-02-2012,242526.7,0,59.41,3.95,130.5502069,7.603 +33,02-03-2012,248051.53,0,60.91,3.882,130.6457931,7.603 +33,09-03-2012,287346.29,0,62.2,3.963,130.7413793,7.603 +33,16-03-2012,278067.73,0,65.99,4.273,130.8261935,7.603 +33,23-03-2012,246970.97,0,60.82,4.288,130.8966452,7.603 +33,30-03-2012,251327.67,0,71.34,4.294,130.9670968,7.603 +33,06-04-2012,275911.97,0,70.75,4.282,131.0375484,7.396 +33,13-04-2012,312698.67,0,73.17,4.254,131.108,7.396 +33,20-04-2012,261837.2,0,72.94,4.111,131.1173333,7.396 +33,27-04-2012,249798.75,0,83.07,4.088,131.1266667,7.396 +33,04-05-2012,270497.51,0,82.43,4.058,131.136,7.396 +33,11-05-2012,295841.84,0,81.02,4.186,131.1453333,7.396 +33,18-05-2012,276899.95,0,89.81,4.308,131.0983226,7.396 +33,25-05-2012,261851.74,0,88.89,4.127,131.0287742,7.396 +33,01-06-2012,261131.09,0,83.57,4.277,130.9592258,7.396 +33,08-06-2012,286082.76,0,90.94,4.103,130.8896774,7.396 +33,15-06-2012,290444.31,0,92.44,4.144,130.8295333,7.396 +33,22-06-2012,261666.29,0,95.75,4.014,130.7929,7.396 +33,29-06-2012,244338.31,0,98.15,3.875,130.7562667,7.396 +33,06-07-2012,273690.37,0,93.21,3.666,130.7196333,7.147 +33,13-07-2012,287033.64,0,97.6,3.723,130.683,7.147 +33,20-07-2012,253205.89,0,91.49,3.589,130.7012903,7.147 +33,27-07-2012,249134.32,0,93.95,3.769,130.7195806,7.147 +33,03-08-2012,258533.12,0,92.13,3.595,130.737871,7.147 +33,10-08-2012,297753.49,0,100.07,3.811,130.7561613,7.147 +33,17-08-2012,270097.76,0,96.79,4.002,130.7909677,7.147 +33,24-08-2012,247672.56,0,89.62,4.055,130.8381613,7.147 +33,31-08-2012,237129.81,0,94.55,3.886,130.8853548,7.147 +33,07-09-2012,286428.78,1,92.02,4.124,130.9325484,7.147 +33,14-09-2012,277417.53,0,83.4,3.966,130.9776667,7.147 +33,21-09-2012,252709.58,0,86.53,4.125,131.0103333,7.147 +33,28-09-2012,242813.51,0,86.42,3.966,131.043,7.147 +33,05-10-2012,265444.9,0,85.18,4.132,131.0756667,6.895 +33,12-10-2012,291781.15,0,79.64,4.468,131.1083333,6.895 +33,19-10-2012,254412.34,0,75.55,4.449,131.1499677,6.895 +33,26-10-2012,253731.13,0,73.7,4.301,131.1930968,6.895 +34,05-02-2010,956228.96,0,35.44,2.598,126.4420645,9.521 +34,12-02-2010,994610.99,1,36.13,2.573,126.4962581,9.521 +34,19-02-2010,983963.07,0,38.36,2.54,126.5262857,9.521 +34,26-02-2010,905756.13,0,37.28,2.59,126.5522857,9.521 +34,05-03-2010,918295.79,0,42.65,2.654,126.5782857,9.521 +34,12-03-2010,921247.88,0,42.26,2.704,126.6042857,9.521 +34,19-03-2010,892070.82,0,45.86,2.743,126.6066452,9.521 +34,26-03-2010,880742.35,0,42.91,2.752,126.6050645,9.521 +34,02-04-2010,979428.66,0,50.07,2.74,126.6034839,9.593 +34,09-04-2010,950684.2,0,51.26,2.773,126.6019032,9.593 +34,16-04-2010,923344.54,0,59.18,2.81,126.5621,9.593 +34,23-04-2010,910240.68,0,55.04,2.805,126.4713333,9.593 +34,30-04-2010,859922.19,0,56.58,2.787,126.3805667,9.593 +34,07-05-2010,953495.48,0,57.39,2.836,126.2898,9.593 +34,14-05-2010,933924.44,0,60.74,2.845,126.2085484,9.593 +34,21-05-2010,913616.32,0,63.99,2.82,126.1843871,9.593 +34,28-05-2010,942868.38,0,68.68,2.756,126.1602258,9.593 +34,04-06-2010,966187.51,0,72.17,2.701,126.1360645,9.593 +34,11-06-2010,954681.56,0,80.84,2.668,126.1119032,9.593 +34,18-06-2010,941612.04,0,73.48,2.635,126.114,9.593 +34,25-06-2010,895800.07,0,78.47,2.654,126.1266,9.593 +34,02-07-2010,919229.36,0,73.66,2.668,126.1392,9.816 +34,09-07-2010,911210.81,0,75,2.637,126.1518,9.816 +34,16-07-2010,930269.79,0,78.53,2.621,126.1498065,9.816 +34,23-07-2010,902050.95,0,79.58,2.612,126.1283548,9.816 +34,30-07-2010,875976.83,0,72.26,2.65,126.1069032,9.816 +34,06-08-2010,987435.35,0,73.8,2.64,126.0854516,9.816 +34,13-08-2010,951208.65,0,76.72,2.698,126.064,9.816 +34,20-08-2010,985152.94,0,76.45,2.671,126.0766452,9.816 +34,27-08-2010,855421.39,0,72.87,2.621,126.0892903,9.816 +34,03-09-2010,964356.74,0,72.59,2.584,126.1019355,9.816 +34,10-09-2010,932240.96,1,72.61,2.574,126.1145806,9.816 +34,17-09-2010,885445.47,0,70.71,2.594,126.1454667,9.816 +34,24-09-2010,867539.07,0,69.78,2.642,126.1900333,9.816 +34,01-10-2010,865709.11,0,70.13,2.619,126.2346,10.21 +34,08-10-2010,931710.67,0,65.21,2.645,126.2791667,10.21 +34,15-10-2010,888703.62,0,59.57,2.732,126.3266774,10.21 +34,22-10-2010,936293.6,0,58.11,2.736,126.3815484,10.21 +34,29-10-2010,926294.02,0,50.78,2.718,126.4364194,10.21 +34,05-11-2010,972292.31,0,52.43,2.699,126.4912903,10.21 +34,12-11-2010,979730.78,0,47.2,2.741,126.5461613,10.21 +34,19-11-2010,955766.33,0,40.93,2.78,126.6072,10.21 +34,26-11-2010,1309476.68,1,41.13,2.752,126.6692667,10.21 +34,03-12-2010,1001512.21,0,34.7,2.727,126.7313333,10.21 +34,10-12-2010,1086661.02,0,41.93,2.86,126.7934,10.21 +34,17-12-2010,1227148.13,0,42.64,2.884,126.8794839,10.21 +34,24-12-2010,1620748.25,0,42.74,2.887,126.9835806,10.21 +34,31-12-2010,902109.69,1,34.11,2.955,127.0876774,10.21 +34,07-01-2011,900646.94,0,24.5,2.98,127.1917742,10.398 +34,14-01-2011,898610.33,0,30.75,2.992,127.3009355,10.398 +34,21-01-2011,891025.39,0,39.57,3.017,127.4404839,10.398 +34,28-01-2011,836717.75,0,34.68,3.022,127.5800323,10.398 +34,04-02-2011,971932.87,0,23.82,2.996,127.7195806,10.398 +34,11-02-2011,1015654.6,1,28.66,3.033,127.859129,10.398 +34,18-02-2011,1062629.3,0,45.12,3.058,127.99525,10.398 +34,25-02-2011,953331.45,0,44.57,3.087,128.13,10.398 +34,04-03-2011,963910.81,0,46.21,3.305,128.26475,10.398 +34,11-03-2011,943951.67,0,45.87,3.461,128.3995,10.398 +34,18-03-2011,1014218.8,0,55.58,3.495,128.5121935,10.398 +34,25-03-2011,922898.38,0,53.11,3.48,128.6160645,10.398 +34,01-04-2011,884233.67,0,55.46,3.521,128.7199355,10.581 +34,08-04-2011,975479.83,0,58.59,3.605,128.8238065,10.581 +34,15-04-2011,941829,0,53.3,3.724,128.9107333,10.581 +34,22-04-2011,1051518.45,0,63.83,3.781,128.9553,10.581 +34,29-04-2011,895973.02,0,57.73,3.781,128.9998667,10.581 +34,06-05-2011,965853.58,0,54.4,3.866,129.0444333,10.581 +34,13-05-2011,966232.69,0,63.05,3.872,129.089,10.581 +34,20-05-2011,945018.83,0,61.47,3.881,129.0756774,10.581 +34,27-05-2011,941311.83,0,65.99,3.771,129.0623548,10.581 +34,03-06-2011,947229.24,0,74.64,3.683,129.0490323,10.581 +34,10-06-2011,943912.77,0,74.57,3.64,129.0357097,10.581 +34,17-06-2011,968258.09,0,76.58,3.618,129.0432,10.581 +34,24-06-2011,923795.04,0,77.16,3.57,129.0663,10.581 +34,01-07-2011,911106.22,0,81.96,3.504,129.0894,10.641 +34,08-07-2011,926934.57,0,80.84,3.469,129.1125,10.641 +34,15-07-2011,903882.96,0,78.09,3.563,129.1338387,10.641 +34,22-07-2011,913236.62,0,80.75,3.627,129.1507742,10.641 +34,29-07-2011,851461.9,0,78.04,3.659,129.1677097,10.641 +34,05-08-2011,942236.45,0,76.71,3.662,129.1846452,10.641 +34,12-08-2011,956251.18,0,80.23,3.617,129.2015806,10.641 +34,19-08-2011,960418.54,0,77.08,3.55,129.2405806,10.641 +34,26-08-2011,871404.6,0,77.27,3.523,129.2832581,10.641 +34,02-09-2011,926455.64,0,78.24,3.533,129.3259355,10.641 +34,09-09-2011,930506.14,1,70.05,3.554,129.3686129,10.641 +34,16-09-2011,927249.61,0,64.94,3.532,129.4306,10.641 +34,23-09-2011,902852.73,0,66.23,3.473,129.5183333,10.641 +34,30-09-2011,871847.85,0,69.44,3.371,129.6060667,10.641 +34,07-10-2011,954069.45,0,60.42,3.299,129.6938,10.148 +34,14-10-2011,911788.79,0,54.72,3.283,129.7706452,10.148 +34,21-10-2011,953693.23,0,58.93,3.361,129.7821613,10.148 +34,28-10-2011,958063.87,0,54.56,3.362,129.7936774,10.148 +34,04-11-2011,992621.93,0,48.04,3.322,129.8051935,10.148 +34,11-11-2011,991570.02,0,41.04,3.286,129.8167097,10.148 +34,18-11-2011,947552.44,0,46,3.294,129.8268333,10.148 +34,25-11-2011,1345595.82,1,45.99,3.225,129.8364,10.148 +34,02-12-2011,988742.08,0,39.75,3.176,129.8459667,10.148 +34,09-12-2011,1084243.91,0,24.69,3.153,129.8555333,10.148 +34,16-12-2011,1151052.86,0,32.31,3.149,129.8980645,10.148 +34,23-12-2011,1593655.96,0,32.45,3.103,129.9845484,10.148 +34,30-12-2011,965512.36,1,28.84,3.119,130.0710323,10.148 +34,06-01-2012,953844.85,0,36.39,3.158,130.1575161,9.653 +34,13-01-2012,913755.12,0,33.99,3.263,130.244,9.653 +34,20-01-2012,910899.05,0,39.28,3.273,130.2792258,9.653 +34,27-01-2012,872450.37,0,39.81,3.29,130.3144516,9.653 +34,03-02-2012,939367.14,0,38.64,3.354,130.3496774,9.653 +34,10-02-2012,1047658.09,1,36.7,3.411,130.3849032,9.653 +34,17-02-2012,1123446.51,0,37.25,3.493,130.4546207,9.653 +34,24-02-2012,950154.24,0,39.89,3.541,130.5502069,9.653 +34,02-03-2012,990263.7,0,42.74,3.619,130.6457931,9.653 +34,09-03-2012,976393.43,0,42.7,3.667,130.7413793,9.653 +34,16-03-2012,999298.43,0,48.09,3.707,130.8261935,9.653 +34,23-03-2012,945143.33,0,47.93,3.759,130.8966452,9.653 +34,30-03-2012,938861.77,0,59.29,3.82,130.9670968,9.653 +34,06-04-2012,1091020.37,0,54.42,3.864,131.0375484,9.575 +34,13-04-2012,987353.65,0,59.12,3.881,131.108,9.575 +34,20-04-2012,977628.78,0,55.34,3.864,131.1173333,9.575 +34,27-04-2012,940299.87,0,66.49,3.81,131.1266667,9.575 +34,04-05-2012,991104.4,0,65.04,3.747,131.136,9.575 +34,11-05-2012,949625.52,0,61.92,3.685,131.1453333,9.575 +34,18-05-2012,998672.85,0,64.97,3.62,131.0983226,9.575 +34,25-05-2012,1015737.61,0,72.42,3.551,131.0287742,9.575 +34,01-06-2012,977062.44,0,70.41,3.483,130.9592258,9.575 +34,08-06-2012,999511.29,0,75.35,3.433,130.8896774,9.575 +34,15-06-2012,982345.51,0,76.48,3.372,130.8295333,9.575 +34,22-06-2012,1000285.1,0,78.85,3.329,130.7929,9.575 +34,29-06-2012,942970.63,0,81.91,3.257,130.7562667,9.575 +34,06-07-2012,1007867.68,0,77.95,3.187,130.7196333,9.285 +34,13-07-2012,954677.75,0,74.02,3.224,130.683,9.285 +34,20-07-2012,950929.59,0,77.7,3.263,130.7012903,9.285 +34,27-07-2012,917883.79,0,77.3,3.356,130.7195806,9.285 +34,03-08-2012,973250.41,0,78.93,3.374,130.737871,9.285 +34,10-08-2012,1004523.59,0,78.26,3.476,130.7561613,9.285 +34,17-08-2012,1013820.86,0,77.78,3.552,130.7909677,9.285 +34,24-08-2012,926250.21,0,72.44,3.61,130.8381613,9.285 +34,31-08-2012,933487.71,0,75.89,3.646,130.8853548,9.285 +34,07-09-2012,976415.56,1,78.26,3.709,130.9325484,9.285 +34,14-09-2012,955211.7,0,64.28,3.706,130.9776667,9.285 +34,21-09-2012,943047.78,0,66.08,3.721,131.0103333,9.285 +34,28-09-2012,928629.31,0,67.06,3.666,131.043,9.285 +34,05-10-2012,968896.68,0,65.41,3.62,131.0756667,8.839 +34,12-10-2012,948613.39,0,59.94,3.603,131.1083333,8.839 +34,19-10-2012,963516.28,0,58.47,3.61,131.1499677,8.839 +34,26-10-2012,956987.81,0,57.95,3.514,131.1930968,8.839 +35,05-02-2010,1230613.5,0,27.19,2.784,135.3524608,9.262 +35,12-02-2010,1168815.31,1,29.81,2.773,135.4113076,9.262 +35,19-02-2010,1270658.64,0,32.44,2.745,135.4657781,9.262 +35,26-02-2010,1020651.74,0,36,2.754,135.5195191,9.262 +35,05-03-2010,1162610.27,0,38.07,2.777,135.5732602,9.262 +35,12-03-2010,1150344.39,0,45.98,2.818,135.6270013,9.262 +35,19-03-2010,1117536.09,0,49.04,2.844,135.6682247,9.262 +35,26-03-2010,1078900.44,0,52.34,2.854,135.7073618,9.262 +35,02-04-2010,1189556.47,0,46.9,2.85,135.7464988,9.051 +35,09-04-2010,1198014.97,0,62.62,2.869,135.7856359,9.051 +35,16-04-2010,1084487.55,0,54.95,2.899,135.82725,9.051 +35,23-04-2010,1110827.48,0,53.91,2.902,135.8721667,9.051 +35,30-04-2010,1096930.65,0,53.55,2.921,135.9170833,9.051 +35,07-05-2010,1182099.88,0,69.02,2.966,135.962,9.051 +35,14-05-2010,1104277.57,0,53.82,2.982,136.010394,9.051 +35,21-05-2010,1078182.18,0,63.31,2.958,136.0796521,9.051 +35,28-05-2010,1223777.48,0,67.88,2.899,136.1489101,9.051 +35,04-06-2010,1282378.71,0,74.29,2.847,136.2181682,9.051 +35,11-06-2010,1160412.71,0,68.9,2.809,136.2874263,9.051 +35,18-06-2010,1198025.76,0,70,2.78,136.3243393,9.051 +35,25-06-2010,1230245.74,0,78.02,2.808,136.3483143,9.051 +35,02-07-2010,1245827.08,0,76.25,2.815,136.3722893,8.861 +35,09-07-2010,1268766.76,0,82.69,2.793,136.3962643,8.861 +35,16-07-2010,1124414.87,0,78.26,2.783,136.4179827,8.861 +35,23-07-2010,1121756.43,0,81.56,2.771,136.4366924,8.861 +35,30-07-2010,1139131.78,0,79.78,2.781,136.4554021,8.861 +35,06-08-2010,1180183.39,0,77.45,2.784,136.4741118,8.861 +35,13-08-2010,1090587.5,0,77.36,2.805,136.4928214,8.861 +35,20-08-2010,1033719.5,0,75.16,2.779,136.5249182,8.861 +35,27-08-2010,917693.06,0,70.31,2.755,136.557015,8.861 +35,03-09-2010,948660.79,0,78.52,2.715,136.5891118,8.861 +35,10-09-2010,961685.98,1,70.38,2.699,136.6212085,8.861 +35,17-09-2010,831443.61,0,64.5,2.706,136.6338071,8.861 +35,24-09-2010,758069.78,0,67.08,2.713,136.6317821,8.861 +35,01-10-2010,771065.21,0,70.19,2.707,136.6297571,8.763 +35,08-10-2010,874615.32,0,57.78,2.764,136.6277321,8.763 +35,15-10-2010,798376.99,0,58.38,2.868,136.6401935,8.763 +35,22-10-2010,827705.82,0,52.82,2.917,136.688871,8.763 +35,29-10-2010,857797.33,0,61.02,2.921,136.7375484,8.763 +35,05-11-2010,843755.12,0,45.91,2.917,136.7862258,8.763 +35,12-11-2010,870914.69,0,45.9,2.931,136.8349032,8.763 +35,19-11-2010,846850.35,0,50.81,3,136.7715714,8.763 +35,26-11-2010,1781866.98,1,46.67,3.039,136.6895714,8.763 +35,03-12-2010,982598.88,0,41.81,3.046,136.6075714,8.763 +35,10-12-2010,1108580.19,0,30.83,3.109,136.5255714,8.763 +35,17-12-2010,1314987.4,0,31.62,3.14,136.5292811,8.763 +35,24-12-2010,1779236.54,0,31.34,3.141,136.597273,8.763 +35,31-12-2010,576332.05,1,29.59,3.179,136.665265,8.763 +35,07-01-2011,649289.75,0,34.42,3.193,136.7332569,8.549 +35,14-01-2011,687670.78,0,25.7,3.205,136.803477,8.549 +35,21-01-2011,659902.07,0,30.13,3.229,136.8870657,8.549 +35,28-01-2011,633289.78,0,23.64,3.237,136.9706544,8.549 +35,04-02-2011,747577.05,0,28.7,3.231,137.0542431,8.549 +35,11-02-2011,859258.17,1,30.45,3.239,137.1378318,8.549 +35,18-02-2011,865305.88,0,39.32,3.245,137.2511849,8.549 +35,25-02-2011,841129.26,0,33.05,3.274,137.3764439,8.549 +35,04-03-2011,850448.54,0,36.99,3.433,137.5017028,8.549 +35,11-03-2011,830601.39,0,43.64,3.582,137.6269617,8.549 +35,18-03-2011,800662.82,0,46.65,3.631,137.7398929,8.549 +35,25-03-2011,762184.1,0,40.11,3.625,137.8478929,8.549 +35,01-04-2011,762620.94,0,37.27,3.638,137.9558929,8.512 +35,08-04-2011,813352.41,0,46.87,3.72,138.0638929,8.512 +35,15-04-2011,795157.2,0,52.24,3.821,138.1646952,8.512 +35,22-04-2011,841778.34,0,50.02,3.892,138.2475036,8.512 +35,29-04-2011,811824.06,0,61.71,3.962,138.3303119,8.512 +35,06-05-2011,835181.18,0,56.48,4.046,138.4131202,8.512 +35,13-05-2011,826155.95,0,60.07,4.066,138.4959286,8.512 +35,20-05-2011,776838.56,0,60.22,4.062,138.587106,8.512 +35,27-05-2011,850708.6,0,66.43,3.985,138.6782834,8.512 +35,03-06-2011,955466.84,0,74.17,3.922,138.7694608,8.512 +35,10-06-2011,855130.21,0,73.26,3.881,138.8606382,8.512 +35,17-06-2011,828594.86,0,67.03,3.842,139.0028333,8.512 +35,24-06-2011,849397.57,0,72.02,3.804,139.1832917,8.512 +35,01-07-2011,874453.88,0,73.76,3.748,139.36375,8.684 +35,08-07-2011,827717.85,0,76.87,3.711,139.5442083,8.684 +35,15-07-2011,813845.5,0,77.83,3.76,139.7006325,8.684 +35,22-07-2011,820188.42,0,82.28,3.811,139.7969712,8.684 +35,29-07-2011,770820.27,0,79.41,3.829,139.8933099,8.684 +35,05-08-2011,826820.71,0,78.14,3.842,139.9896486,8.684 +35,12-08-2011,819911.89,0,76.67,3.812,140.0859873,8.684 +35,19-08-2011,820288.35,0,72.97,3.747,140.1289205,8.684 +35,26-08-2011,897037.25,0,72.88,3.704,140.1629528,8.684 +35,02-09-2011,813486.55,0,71.44,3.703,140.196985,8.684 +35,09-09-2011,922440.64,1,70.93,3.738,140.2310173,8.684 +35,16-09-2011,738792.11,0,69.65,3.742,140.2735,8.684 +35,23-09-2011,705802.45,0,63.61,3.711,140.32725,8.684 +35,30-09-2011,749676.95,0,70.92,3.645,140.381,8.684 +35,07-10-2011,791637.53,0,56.91,3.583,140.43475,8.745 +35,14-10-2011,772859.25,0,64.78,3.541,140.4784194,8.745 +35,21-10-2011,811328.4,0,59.62,3.57,140.4616048,8.745 +35,28-10-2011,808821.5,0,51.81,3.569,140.4447903,8.745 +35,04-11-2011,653468.75,0,44.46,3.551,140.4279758,8.745 +35,11-11-2011,880576.33,0,49.69,3.53,140.4111613,8.745 +35,18-11-2011,820964.1,0,51.42,3.53,140.4127857,8.745 +35,25-11-2011,1733822.4,1,47.88,3.492,140.4217857,8.745 +35,02-12-2011,903606.03,0,50.55,3.452,140.4307857,8.745 +35,09-12-2011,948964.99,0,46.28,3.415,140.4397857,8.745 +35,16-12-2011,1115255.65,0,40.68,3.413,140.4700795,8.745 +35,23-12-2011,1550214.02,0,41.59,3.389,140.528765,8.745 +35,30-12-2011,904650.55,1,37.85,3.389,140.5874505,8.745 +35,06-01-2012,671708.09,0,35.8,3.422,140.6461359,8.744 +35,13-01-2012,625135.11,0,41.3,3.513,140.7048214,8.744 +35,20-01-2012,669850.04,0,30.35,3.533,140.8086118,8.744 +35,27-01-2012,588722.99,0,36.96,3.567,140.9124021,8.744 +35,03-02-2012,746901.03,0,42.52,3.617,141.0161924,8.744 +35,10-02-2012,849779.14,1,37.86,3.64,141.1199827,8.744 +35,17-02-2012,824568.39,0,37.24,3.695,141.2140357,8.744 +35,24-02-2012,805028.74,0,41.74,3.739,141.3007857,8.744 +35,02-03-2012,766571.1,0,40.07,3.816,141.3875357,8.744 +35,09-03-2012,796351.35,0,44.32,3.848,141.4742857,8.744 +35,16-03-2012,793045.82,0,49.6,3.862,141.55478,8.744 +35,23-03-2012,760671.1,0,57.3,3.9,141.6269332,8.744 +35,30-03-2012,744525.69,0,49.4,3.953,141.6990864,8.744 +35,06-04-2012,860293.46,0,48.73,3.996,141.7712396,8.876 +35,13-04-2012,788633.42,0,52.22,4.044,141.8433929,8.876 +35,20-04-2012,794660.24,0,62.62,4.027,141.9015262,8.876 +35,27-04-2012,721212.45,0,52.33,4.004,141.9596595,8.876 +35,04-05-2012,772036.6,0,53.68,3.951,142.0177929,8.876 +35,11-05-2012,802383.63,0,58.97,3.889,142.0759262,8.876 +35,18-05-2012,819196.68,0,65.15,3.848,142.0970115,8.876 +35,25-05-2012,822167.17,0,64.77,3.798,142.1032776,8.876 +35,01-06-2012,932195.52,0,73.4,3.742,142.1095438,8.876 +35,08-06-2012,873415.01,0,64.05,3.689,142.1158099,8.876 +35,15-06-2012,848289.41,0,69.52,3.62,142.1292548,8.876 +35,22-06-2012,911696,0,73.23,3.564,142.1606464,8.876 +35,29-06-2012,892133.41,0,73.94,3.506,142.1920381,8.876 +35,06-07-2012,985479.64,0,82.08,3.475,142.2234298,8.839 +35,13-07-2012,825763.48,0,78.95,3.523,142.2548214,8.839 +35,20-07-2012,841224.74,0,78.64,3.567,142.2337569,8.839 +35,27-07-2012,808030.15,0,76.01,3.647,142.2126924,8.839 +35,03-08-2012,866216.36,0,75.22,3.654,142.1916279,8.839 +35,10-08-2012,888368.8,0,78.44,3.722,142.1705634,8.839 +35,17-08-2012,887979.47,0,76.51,3.807,142.2157385,8.839 +35,24-08-2012,895274.72,0,72.93,3.834,142.3105933,8.839 +35,31-08-2012,931278.97,0,75,3.867,142.4054482,8.839 +35,07-09-2012,984833.35,1,76,3.911,142.500303,8.839 +35,14-09-2012,821568.64,0,68.72,3.948,142.5938833,8.839 +35,21-09-2012,772302.94,0,66.1,4.038,142.6798167,8.839 +35,28-09-2012,814099.86,0,64.92,3.997,142.76575,8.839 +35,05-10-2012,866064.4,0,64.5,3.985,142.8516833,8.665 +35,12-10-2012,873643.14,0,55.4,4,142.9376167,8.665 +35,19-10-2012,829284.67,0,56.53,3.969,142.8633629,8.665 +35,26-10-2012,865137.6,0,58.99,3.882,142.7624113,8.665 +36,05-02-2010,467546.74,0,45.97,2.545,209.8529663,8.554 +36,12-02-2010,469563.7,1,46.11,2.539,209.9970208,8.554 +36,19-02-2010,470281.03,0,45.66,2.472,210.0451024,8.554 +36,26-02-2010,447519.44,0,50.87,2.52,210.0771885,8.554 +36,05-03-2010,480203.43,0,51.33,2.574,210.1092746,8.554 +36,12-03-2010,441434.2,0,61.96,2.619,210.1413607,8.554 +36,19-03-2010,428851.99,0,59.56,2.701,209.9803208,8.554 +36,26-03-2010,404438.51,0,55.76,2.711,209.7870932,8.554 +36,02-04-2010,435972.82,0,63.43,2.708,209.5938656,8.464 +36,09-04-2010,453016.91,0,68.54,2.743,209.400638,8.464 +36,16-04-2010,483699.56,0,66.74,2.769,209.2691428,8.464 +36,23-04-2010,434116.8,0,68.03,2.762,209.2199574,8.464 +36,30-04-2010,457899.64,0,70.9,2.725,209.170772,8.464 +36,07-05-2010,489372.02,0,75.56,2.786,209.1215867,8.464 +36,14-05-2010,476733.74,0,77.53,2.805,209.118536,8.464 +36,21-05-2010,474917.98,0,77.34,2.767,209.3922937,8.464 +36,28-05-2010,447050.42,0,80.87,2.716,209.6660514,8.464 +36,04-06-2010,471088.88,0,79.93,2.664,209.9398091,8.464 +36,11-06-2010,467711.18,0,82.3,2.615,210.2135668,8.464 +36,18-06-2010,485694.72,0,84.37,2.572,210.2108417,8.464 +36,25-06-2010,434879.87,0,84.14,2.601,210.0975233,8.464 +36,02-07-2010,434252.15,0,81.85,2.606,209.984205,8.36 +36,09-07-2010,471713.59,0,81.74,2.596,209.8708867,8.36 +36,16-07-2010,466962.04,0,84.43,2.561,209.8630532,8.36 +36,23-07-2010,452021.2,0,82.6,2.542,209.9958663,8.36 +36,30-07-2010,432451.91,0,81.88,2.602,210.1286794,8.36 +36,06-08-2010,467442.94,0,85.49,2.573,210.2614925,8.36 +36,13-08-2010,470436.8,0,86.06,2.644,210.3943056,8.36 +36,20-08-2010,437949.9,0,85.54,2.604,210.3617581,8.36 +36,27-08-2010,412050.73,0,84.62,2.562,210.3292106,8.36 +36,03-09-2010,431294.45,0,82.29,2.533,210.2966631,8.36 +36,10-09-2010,434471.38,1,80.58,2.513,210.2641156,8.36 +36,17-09-2010,454694.21,0,82.1,2.55,210.2924504,8.36 +36,24-09-2010,419348.59,0,79.17,2.578,210.3664469,8.36 +36,01-10-2010,422169.47,0,74.66,2.567,210.4404433,8.476 +36,08-10-2010,444351.61,0,66.34,2.595,210.5144398,8.476 +36,15-10-2010,453308.15,0,71.57,2.705,210.5805944,8.476 +36,22-10-2010,424956.3,0,72.24,2.698,210.6271444,8.476 +36,29-10-2010,392654.26,0,76.22,2.68,210.6736944,8.476 +36,05-11-2010,405860.37,0,62.72,2.655,210.7202444,8.476 +36,12-11-2010,425804.8,0,61.97,2.705,210.7667944,8.476 +36,19-11-2010,411615.71,0,56.73,2.741,210.65429,8.476 +36,26-11-2010,408891.49,1,67.73,2.725,210.5152765,8.476 +36,03-12-2010,360266.09,0,54.44,2.694,210.376263,8.476 +36,10-12-2010,404545.03,0,51.83,2.813,210.2372494,8.476 +36,17-12-2010,410214.7,0,56.73,2.852,210.1787224,8.476 +36,24-12-2010,422093.59,0,59.1,2.863,210.1805602,8.476 +36,31-12-2010,359310.65,1,52.88,2.949,210.182398,8.476 +36,07-01-2011,384659.85,0,54.11,2.942,210.1842358,8.395 +36,14-01-2011,410497.73,0,42.87,2.971,210.2379731,8.395 +36,21-01-2011,399191.05,0,51.18,2.98,210.6031072,8.395 +36,28-01-2011,372174.12,0,48.74,2.995,210.9682412,8.395 +36,04-02-2011,417521.7,0,46.68,2.98,211.3333753,8.395 +36,11-02-2011,401501.2,1,41.16,3.009,211.6985093,8.395 +36,18-02-2011,427175.03,0,57.48,3.017,212.0063522,8.395 +36,25-02-2011,380279.44,0,67.73,3.053,212.2912786,8.395 +36,04-03-2011,402579.84,0,64.55,3.282,212.576205,8.395 +36,11-03-2011,407506.78,0,59.15,3.448,212.8611313,8.395 +36,18-03-2011,431412.22,0,64.9,3.487,213.1096787,8.395 +36,25-03-2011,390732.02,0,71.07,3.488,213.3436744,8.395 +36,01-04-2011,385672.11,0,67.31,3.529,213.5776701,8.3 +36,08-04-2011,428727.61,0,69.39,3.645,213.8116658,8.3 +36,15-04-2011,414986.54,0,73.25,3.763,214.026217,8.3 +36,22-04-2011,374574.72,0,74.57,3.805,214.1921572,8.3 +36,29-04-2011,340708.78,0,76.1,3.837,214.3580974,8.3 +36,06-05-2011,393401.4,0,69.56,3.917,214.5240376,8.3 +36,13-05-2011,395316.65,0,76.73,3.92,214.6899778,8.3 +36,20-05-2011,376183.44,0,73.02,3.925,214.465412,8.3 +36,27-05-2011,348655.2,0,81.28,3.786,214.2408462,8.3 +36,03-06-2011,373703.95,0,82.96,3.69,214.0162805,8.3 +36,10-06-2011,374182.04,0,82.41,3.633,213.7917147,8.3 +36,17-06-2011,394645.25,0,84.43,3.599,213.7481256,8.3 +36,24-06-2011,360009.94,0,83.95,3.569,213.8402689,8.3 +36,01-07-2011,354270.77,0,85.33,3.502,213.9324122,8.177 +36,08-07-2011,377464.62,0,84.71,3.44,214.0245556,8.177 +36,15-07-2011,385631.48,0,85.63,3.55,214.1083654,8.177 +36,22-07-2011,361311.41,0,83.31,3.637,214.1713416,8.177 +36,29-07-2011,354361.08,0,84.99,3.66,214.2343177,8.177 +36,05-08-2011,381017.75,0,86.71,3.652,214.2972939,8.177 +36,12-08-2011,380188.69,0,87.64,3.608,214.3602701,8.177 +36,19-08-2011,373267.58,0,87.24,3.534,214.4239935,8.177 +36,26-08-2011,344964.2,0,86.02,3.501,214.4878416,8.177 +36,02-09-2011,350276.29,0,87.5,3.481,214.5516896,8.177 +36,09-09-2011,352960.64,1,77.94,3.499,214.6155376,8.177 +36,16-09-2011,343108.12,0,82.06,3.473,214.7934111,8.177 +36,23-09-2011,322405.13,0,78.35,3.441,215.1233185,8.177 +36,30-09-2011,314910.37,0,81.52,3.328,215.4532259,8.177 +36,07-10-2011,346137.87,0,71.2,3.262,215.7831333,7.716 +36,14-10-2011,342076.99,0,74.16,3.234,216.0885258,7.716 +36,21-10-2011,328633.34,0,67.89,3.308,216.2468287,7.716 +36,28-10-2011,306193.81,0,71.31,3.306,216.4051315,7.716 +36,04-11-2011,313387.11,0,58.97,3.287,216.5634344,7.716 +36,11-11-2011,328498.92,0,63.5,3.254,216.7217373,7.716 +36,18-11-2011,332901.94,0,66.28,3.26,216.9395861,7.716 +36,25-11-2011,332811.55,1,66.41,3.181,217.1812533,7.716 +36,02-12-2011,293350.51,0,53.57,3.164,217.4229206,7.716 +36,09-12-2011,312298.37,0,50.64,3.147,217.6645878,7.716 +36,16-12-2011,341503.92,0,58.31,3.133,217.8781339,7.716 +36,23-12-2011,325262.46,0,55.41,3.098,218.0541851,7.716 +36,30-12-2011,287425.22,1,48.26,3.132,218.2302364,7.716 +36,06-01-2012,329467.82,0,57.18,3.129,218.4062876,7.244 +36,13-01-2012,325976.34,0,56.28,3.254,218.5823389,7.244 +36,20-01-2012,330927.21,0,58.9,3.275,218.6755292,7.244 +36,27-01-2012,301444.94,0,62.73,3.313,218.7687195,7.244 +36,03-02-2012,310982.87,0,61.33,3.421,218.8619099,7.244 +36,10-02-2012,335741.9,1,54.49,3.462,218.9551002,7.244 +36,17-02-2012,326316.73,0,54.38,3.503,219.1148297,7.244 +36,24-02-2012,313270.45,0,62.21,3.55,219.3244636,7.244 +36,02-03-2012,315396.72,0,64.54,3.619,219.5340975,7.244 +36,09-03-2012,318674.93,0,63.19,3.647,219.7437314,7.244 +36,16-03-2012,335345.82,0,67.48,3.779,219.8956335,7.244 +36,23-03-2012,317872.51,0,69.18,3.845,219.9705599,7.244 +36,30-03-2012,304144.9,0,70.48,3.891,220.0454862,7.244 +36,06-04-2012,331026.11,0,73.95,3.934,220.1204125,6.989 +36,13-04-2012,339407.94,0,72.54,3.919,220.1953389,6.989 +36,20-04-2012,323915.32,0,70.87,3.918,220.2483937,6.989 +36,27-04-2012,308389.82,0,70.06,3.888,220.3014485,6.989 +36,04-05-2012,312467.52,0,77.17,3.835,220.3545033,6.989 +36,11-05-2012,330518.34,0,76.55,3.764,220.4075581,6.989 +36,18-05-2012,324801.13,0,73.7,3.713,220.4252149,6.989 +36,25-05-2012,306098.17,0,78.94,3.636,220.4287124,6.989 +36,01-06-2012,306005.53,0,80.74,3.567,220.4322099,6.989 +36,08-06-2012,338273.38,0,81.5,3.513,220.4357073,6.989 +36,15-06-2012,333146.88,0,82.15,3.407,220.4494148,6.989 +36,22-06-2012,306411.01,0,80.4,3.358,220.4886472,6.989 +36,29-06-2012,291530.43,0,86.68,3.273,220.5278796,6.989 +36,06-07-2012,306578.89,0,81.52,3.232,220.567112,6.623 +36,13-07-2012,298337.41,0,78.15,3.245,220.6063444,6.623 +36,20-07-2012,303289.55,0,81.76,3.301,220.6148749,6.623 +36,27-07-2012,279643.43,0,84,3.392,220.6234054,6.623 +36,03-08-2012,304989.97,0,85.56,3.404,220.6319358,6.623 +36,10-08-2012,298947.51,0,84.41,3.49,220.6404663,6.623 +36,17-08-2012,314607.22,0,85.89,3.571,220.7199609,6.623 +36,24-08-2012,282545.55,0,81.26,3.574,220.8526787,6.623 +36,31-08-2012,282647.48,0,84.79,3.608,220.9853964,6.623 +36,07-09-2012,293728.57,1,84.19,3.697,221.1181142,6.623 +36,14-09-2012,301893.63,0,78.16,3.692,221.2601207,6.623 +36,21-09-2012,293804.45,0,75.98,3.709,221.4578604,6.623 +36,28-09-2012,270677.98,0,79.49,3.66,221.6556,6.623 +36,05-10-2012,277137.86,0,73.57,3.611,221.8533396,6.228 +36,12-10-2012,300236.85,0,71.28,3.576,222.0510793,6.228 +36,19-10-2012,287360.05,0,74.06,3.57,222.0951719,6.228 +36,26-10-2012,272489.41,0,74.39,3.494,222.1136566,6.228 +37,05-02-2010,536006.73,0,45.97,2.572,209.8529663,8.554 +37,12-02-2010,529852.7,1,46.11,2.548,209.9970208,8.554 +37,19-02-2010,510382.5,0,45.66,2.514,210.0451024,8.554 +37,26-02-2010,513615.82,0,50.87,2.561,210.0771885,8.554 +37,05-03-2010,519255.68,0,51.33,2.625,210.1092746,8.554 +37,12-03-2010,513015.35,0,61.96,2.667,210.1413607,8.554 +37,19-03-2010,460020.74,0,59.56,2.72,209.9803208,8.554 +37,26-03-2010,515777.97,0,55.76,2.732,209.7870932,8.554 +37,02-04-2010,540189.7,0,63.43,2.719,209.5938656,8.464 +37,09-04-2010,513327.55,0,68.54,2.77,209.400638,8.464 +37,16-04-2010,524544.83,0,66.74,2.808,209.2691428,8.464 +37,23-04-2010,527019.78,0,68.03,2.795,209.2199574,8.464 +37,30-04-2010,517850.83,0,70.9,2.78,209.170772,8.464 +37,07-05-2010,543234.77,0,75.56,2.835,209.1215867,8.464 +37,14-05-2010,505196.08,0,77.53,2.854,209.118536,8.464 +37,21-05-2010,510494.7,0,77.34,2.826,209.3922937,8.464 +37,28-05-2010,532241.22,0,80.87,2.759,209.6660514,8.464 +37,04-06-2010,479195.02,0,79.93,2.705,209.9398091,8.464 +37,11-06-2010,481915.11,0,82.3,2.668,210.2135668,8.464 +37,18-06-2010,505761.62,0,84.37,2.637,210.2108417,8.464 +37,25-06-2010,485419.39,0,84.14,2.653,210.0975233,8.464 +37,02-07-2010,498292.53,0,81.85,2.669,209.984205,8.36 +37,09-07-2010,502456.04,0,81.74,2.642,209.8708867,8.36 +37,16-07-2010,485150.01,0,84.43,2.623,209.8630532,8.36 +37,23-07-2010,491998.12,0,82.6,2.608,209.9958663,8.36 +37,30-07-2010,487912.95,0,81.88,2.64,210.1286794,8.36 +37,06-08-2010,508576.62,0,85.49,2.627,210.2614925,8.36 +37,13-08-2010,491815.83,0,86.06,2.692,210.3943056,8.36 +37,20-08-2010,486930.72,0,85.54,2.664,210.3617581,8.36 +37,27-08-2010,512157.25,0,84.62,2.619,210.3292106,8.36 +37,03-09-2010,510427.53,0,82.29,2.577,210.2966631,8.36 +37,10-09-2010,510296.07,1,80.58,2.565,210.2641156,8.36 +37,17-09-2010,501251.4,0,82.1,2.582,210.2924504,8.36 +37,24-09-2010,494265.48,0,79.17,2.624,210.3664469,8.36 +37,01-10-2010,529877.93,0,74.66,2.603,210.4404433,8.476 +37,08-10-2010,524483.65,0,66.34,2.633,210.5144398,8.476 +37,15-10-2010,498925.86,0,71.57,2.72,210.5805944,8.476 +37,22-10-2010,510425.4,0,72.24,2.725,210.6271444,8.476 +37,29-10-2010,514485.9,0,76.22,2.716,210.6736944,8.476 +37,05-11-2010,539683.42,0,62.72,2.689,210.7202444,8.476 +37,12-11-2010,517546.69,0,61.97,2.728,210.7667944,8.476 +37,19-11-2010,518124.16,0,56.73,2.771,210.65429,8.476 +37,26-11-2010,518220.72,1,67.73,2.735,210.5152765,8.476 +37,03-12-2010,508213.14,0,54.44,2.708,210.376263,8.476 +37,10-12-2010,511207.52,0,51.83,2.843,210.2372494,8.476 +37,17-12-2010,534285.21,0,56.73,2.869,210.1787224,8.476 +37,24-12-2010,576809.92,0,59.1,2.886,210.1805602,8.476 +37,31-12-2010,460331.7,1,52.88,2.943,210.182398,8.476 +37,07-01-2011,542464.02,0,54.11,2.976,210.1842358,8.395 +37,14-01-2011,525616.9,0,42.87,2.983,210.2379731,8.395 +37,21-01-2011,526486.82,0,51.18,3.016,210.6031072,8.395 +37,28-01-2011,513672.36,0,48.74,3.01,210.9682412,8.395 +37,04-02-2011,583835.18,0,46.68,2.989,211.3333753,8.395 +37,11-02-2011,522514.32,1,41.16,3.022,211.6985093,8.395 +37,18-02-2011,536840.69,0,57.48,3.045,212.0063522,8.395 +37,25-02-2011,514758.19,0,67.73,3.065,212.2912786,8.395 +37,04-03-2011,527572.25,0,64.55,3.288,212.576205,8.395 +37,11-03-2011,505610.4,0,59.15,3.459,212.8611313,8.395 +37,18-03-2011,478503.06,0,64.9,3.488,213.1096787,8.395 +37,25-03-2011,522105.93,0,71.07,3.473,213.3436744,8.395 +37,01-04-2011,534578.78,0,67.31,3.524,213.5776701,8.3 +37,08-04-2011,543703.16,0,69.39,3.622,213.8116658,8.3 +37,15-04-2011,543775.87,0,73.25,3.743,214.026217,8.3 +37,22-04-2011,526434.37,0,74.57,3.807,214.1921572,8.3 +37,29-04-2011,502918.18,0,76.1,3.81,214.3580974,8.3 +37,06-05-2011,547513.3,0,69.56,3.906,214.5240376,8.3 +37,13-05-2011,511871.63,0,76.73,3.899,214.6899778,8.3 +37,20-05-2011,533564.42,0,73.02,3.907,214.465412,8.3 +37,27-05-2011,507086.75,0,81.28,3.786,214.2408462,8.3 +37,03-06-2011,500381.23,0,82.96,3.699,214.0162805,8.3 +37,10-06-2011,509647.25,0,82.41,3.648,213.7917147,8.3 +37,17-06-2011,525132.36,0,84.43,3.637,213.7481256,8.3 +37,24-06-2011,509276.22,0,83.95,3.594,213.8402689,8.3 +37,01-07-2011,517021.3,0,85.33,3.524,213.9324122,8.177 +37,08-07-2011,489059.93,0,84.71,3.48,214.0245556,8.177 +37,15-07-2011,498749.62,0,85.63,3.575,214.1083654,8.177 +37,22-07-2011,505543.53,0,83.31,3.651,214.1713416,8.177 +37,29-07-2011,504974.95,0,84.99,3.682,214.2343177,8.177 +37,05-08-2011,510787.46,0,86.71,3.684,214.2972939,8.177 +37,12-08-2011,502504.39,0,87.64,3.638,214.3602701,8.177 +37,19-08-2011,506897.98,0,87.24,3.554,214.4239935,8.177 +37,26-08-2011,527947.21,0,86.02,3.523,214.4878416,8.177 +37,02-09-2011,530367.83,0,87.5,3.533,214.5516896,8.177 +37,09-09-2011,506273.74,1,77.94,3.546,214.6155376,8.177 +37,16-09-2011,513341.94,0,82.06,3.526,214.7934111,8.177 +37,23-09-2011,516556.94,0,78.35,3.467,215.1233185,8.177 +37,30-09-2011,516402.1,0,81.52,3.355,215.4532259,8.177 +37,07-10-2011,522816.85,0,71.2,3.285,215.7831333,7.716 +37,14-10-2011,513636.01,0,74.16,3.274,216.0885258,7.716 +37,21-10-2011,522784.33,0,67.89,3.353,216.2468287,7.716 +37,28-10-2011,517355.44,0,71.31,3.372,216.4051315,7.716 +37,04-11-2011,555925.6,0,58.97,3.332,216.5634344,7.716 +37,11-11-2011,501268.78,0,63.5,3.297,216.7217373,7.716 +37,18-11-2011,527495.09,0,66.28,3.308,216.9395861,7.716 +37,25-11-2011,522554.04,1,66.41,3.236,217.1812533,7.716 +37,02-12-2011,527117.81,0,53.57,3.172,217.4229206,7.716 +37,09-12-2011,537224.52,0,50.64,3.158,217.6645878,7.716 +37,16-12-2011,533905.67,0,58.31,3.159,217.8781339,7.716 +37,23-12-2011,605791.46,0,55.41,3.112,218.0541851,7.716 +37,30-12-2011,451327.61,1,48.26,3.129,218.2302364,7.716 +37,06-01-2012,558343.57,0,57.18,3.157,218.4062876,7.244 +37,13-01-2012,546221.4,0,56.28,3.261,218.5823389,7.244 +37,20-01-2012,543894.07,0,58.9,3.268,218.6755292,7.244 +37,27-01-2012,514116.58,0,62.73,3.29,218.7687195,7.244 +37,03-02-2012,555424.24,0,61.33,3.36,218.8619099,7.244 +37,10-02-2012,527041.46,1,54.49,3.409,218.9551002,7.244 +37,17-02-2012,541071.29,0,54.38,3.51,219.1148297,7.244 +37,24-02-2012,518696.89,0,62.21,3.555,219.3244636,7.244 +37,02-03-2012,525559.17,0,64.54,3.63,219.5340975,7.244 +37,09-03-2012,535937.25,0,63.19,3.669,219.7437314,7.244 +37,16-03-2012,484588.34,0,67.48,3.734,219.8956335,7.244 +37,23-03-2012,520887.23,0,69.18,3.787,219.9705599,7.244 +37,30-03-2012,533734.94,0,70.48,3.845,220.0454862,7.244 +37,06-04-2012,564848.78,0,73.95,3.891,220.1204125,6.989 +37,13-04-2012,506973.17,0,72.54,3.891,220.1953389,6.989 +37,20-04-2012,523483.19,0,70.87,3.877,220.2483937,6.989 +37,27-04-2012,528807.45,0,70.06,3.814,220.3014485,6.989 +37,04-05-2012,535311.64,0,77.17,3.749,220.3545033,6.989 +37,11-05-2012,527983.04,0,76.55,3.688,220.4075581,6.989 +37,18-05-2012,534847.96,0,73.7,3.63,220.4252149,6.989 +37,25-05-2012,540625.79,0,78.94,3.561,220.4287124,6.989 +37,01-06-2012,531811.85,0,80.74,3.501,220.4322099,6.989 +37,08-06-2012,528940.78,0,81.5,3.452,220.4357073,6.989 +37,15-06-2012,508573.16,0,82.15,3.393,220.4494148,6.989 +37,22-06-2012,484032.75,0,80.4,3.346,220.4886472,6.989 +37,29-06-2012,508309.81,0,86.68,3.286,220.5278796,6.989 +37,06-07-2012,519498.32,0,81.52,3.227,220.567112,6.623 +37,13-07-2012,506005.47,0,78.15,3.256,220.6063444,6.623 +37,20-07-2012,503744.56,0,81.76,3.311,220.6148749,6.623 +37,27-07-2012,514489.17,0,84,3.407,220.6234054,6.623 +37,03-08-2012,521959.28,0,85.56,3.417,220.6319358,6.623 +37,10-08-2012,500964.59,0,84.41,3.494,220.6404663,6.623 +37,17-08-2012,509633.71,0,85.89,3.571,220.7199609,6.623 +37,24-08-2012,522665.04,0,81.26,3.62,220.8526787,6.623 +37,31-08-2012,538344.1,0,84.79,3.638,220.9853964,6.623 +37,07-09-2012,526838.14,1,84.19,3.73,221.1181142,6.623 +37,14-09-2012,514651.74,0,78.16,3.717,221.2601207,6.623 +37,21-09-2012,521320.98,0,75.98,3.721,221.4578604,6.623 +37,28-09-2012,527953.14,0,79.49,3.666,221.6556,6.623 +37,05-10-2012,546122.37,0,73.57,3.617,221.8533396,6.228 +37,12-10-2012,521810.75,0,71.28,3.601,222.0510793,6.228 +37,19-10-2012,551969.1,0,74.06,3.594,222.0951719,6.228 +37,26-10-2012,534738.43,0,74.39,3.506,222.1136566,6.228 +38,05-02-2010,358496.14,0,49.47,2.962,126.4420645,13.975 +38,12-02-2010,342214.9,1,47.87,2.946,126.4962581,13.975 +38,19-02-2010,327237.92,0,54.83,2.915,126.5262857,13.975 +38,26-02-2010,334222.73,0,50.23,2.825,126.5522857,13.975 +38,05-03-2010,372239.89,0,53.77,2.987,126.5782857,13.975 +38,12-03-2010,342023.92,0,50.11,2.925,126.6042857,13.975 +38,19-03-2010,333025.47,0,59.57,3.054,126.6066452,13.975 +38,26-03-2010,335858.11,0,60.06,3.083,126.6050645,13.975 +38,02-04-2010,368929.55,0,59.84,3.086,126.6034839,14.099 +38,09-04-2010,341630.46,0,59.25,3.09,126.6019032,14.099 +38,16-04-2010,337723.49,0,64.95,3.109,126.5621,14.099 +38,23-04-2010,335121.82,0,64.55,3.05,126.4713333,14.099 +38,30-04-2010,337979.65,0,67.38,3.105,126.3805667,14.099 +38,07-05-2010,383657.44,0,70.15,3.127,126.2898,14.099 +38,14-05-2010,346174.3,0,68.44,3.145,126.2085484,14.099 +38,21-05-2010,340497.08,0,76.2,3.12,126.1843871,14.099 +38,28-05-2010,326469.43,0,67.84,3.058,126.1602258,14.099 +38,04-06-2010,376184.88,0,81.39,2.941,126.1360645,14.099 +38,11-06-2010,354828.65,0,90.84,2.949,126.1119032,14.099 +38,18-06-2010,335691.85,0,81.06,3.043,126.114,14.099 +38,25-06-2010,322046.76,0,87.27,3.084,126.1266,14.099 +38,02-07-2010,361181.48,0,91.98,3.105,126.1392,14.18 +38,09-07-2010,343850.34,0,90.37,3.1,126.1518,14.18 +38,16-07-2010,338277.71,0,97.18,3.094,126.1498065,14.18 +38,23-07-2010,328336.85,0,99.22,3.112,126.1283548,14.18 +38,30-07-2010,336378.38,0,96.31,3.017,126.1069032,14.18 +38,06-08-2010,378574.44,0,92.95,3.123,126.0854516,14.18 +38,13-08-2010,341400.72,0,87.01,3.159,126.064,14.18 +38,20-08-2010,329139.73,0,92.81,3.041,126.0766452,14.18 +38,27-08-2010,322868.56,0,93.19,3.129,126.0892903,14.18 +38,03-09-2010,377096.55,0,83.12,3.087,126.1019355,14.18 +38,10-09-2010,336227.69,1,83.63,3.044,126.1145806,14.18 +38,17-09-2010,336253.19,0,82.45,3.028,126.1454667,14.18 +38,24-09-2010,330604.9,0,81.77,2.939,126.1900333,14.18 +38,01-10-2010,360256.58,0,85.2,3.001,126.2346,14.313 +38,08-10-2010,351271.36,0,71.82,3.013,126.2791667,14.313 +38,15-10-2010,337743.26,0,75,2.976,126.3266774,14.313 +38,22-10-2010,339042.18,0,68.85,3.014,126.3815484,14.313 +38,29-10-2010,341219.63,0,61.09,3.016,126.4364194,14.313 +38,05-11-2010,380870.09,0,65.49,3.129,126.4912903,14.313 +38,12-11-2010,340147.2,0,57.79,3.13,126.5461613,14.313 +38,19-11-2010,348593.99,0,58.18,3.161,126.6072,14.313 +38,26-11-2010,360857.98,1,47.66,3.162,126.6692667,14.313 +38,03-12-2010,351925.36,0,43.33,3.041,126.7313333,14.313 +38,10-12-2010,355965.23,0,50.01,3.203,126.7934,14.313 +38,17-12-2010,334441.15,0,52.77,3.236,126.8794839,14.313 +38,24-12-2010,369106.72,0,52.02,3.236,126.9835806,14.313 +38,31-12-2010,303908.81,1,45.64,3.148,127.0876774,14.313 +38,07-01-2011,386344.54,0,37.64,3.287,127.1917742,14.021 +38,14-01-2011,356138.79,0,43.15,3.312,127.3009355,14.021 +38,21-01-2011,341098.08,0,53.53,3.223,127.4404839,14.021 +38,28-01-2011,357557.16,0,50.74,3.342,127.5800323,14.021 +38,04-02-2011,402341.76,0,45.14,3.348,127.7195806,14.021 +38,11-02-2011,377672.46,1,51.3,3.381,127.859129,14.021 +38,18-02-2011,364606.7,0,53.35,3.43,127.99525,14.021 +38,25-02-2011,354232.34,0,48.45,3.53,128.13,14.021 +38,04-03-2011,405429.43,0,51.72,3.674,128.26475,14.021 +38,11-03-2011,357897.18,0,57.75,3.818,128.3995,14.021 +38,18-03-2011,349459.95,0,64.21,3.692,128.5121935,14.021 +38,25-03-2011,351541.62,0,54.4,3.909,128.6160645,14.021 +38,01-04-2011,382098.13,0,63.63,3.772,128.7199355,13.736 +38,08-04-2011,392152.3,0,64.47,4.003,128.8238065,13.736 +38,15-04-2011,362758.94,0,57.63,3.868,128.9107333,13.736 +38,22-04-2011,362952.34,0,72.12,4.134,128.9553,13.736 +38,29-04-2011,344225.99,0,68.27,4.151,128.9998667,13.736 +38,06-05-2011,422186.65,0,68.4,4.193,129.0444333,13.736 +38,13-05-2011,366977.79,0,70.93,4.202,129.089,13.736 +38,20-05-2011,365730.76,0,66.59,4.169,129.0756774,13.736 +38,27-05-2011,356886.1,0,76.67,4.087,129.0623548,13.736 +38,03-06-2011,396826.06,0,71.81,4.031,129.0490323,13.736 +38,10-06-2011,381763.02,0,78.72,3.981,129.0357097,13.736 +38,17-06-2011,356797,0,86.84,3.935,129.0432,13.736 +38,24-06-2011,354078.95,0,88.95,3.898,129.0663,13.736 +38,01-07-2011,387334.04,0,89.85,3.842,129.0894,13.503 +38,08-07-2011,399699.17,0,89.9,3.705,129.1125,13.503 +38,15-07-2011,367181.71,0,88.1,3.692,129.1338387,13.503 +38,22-07-2011,365562.67,0,91.17,3.794,129.1507742,13.503 +38,29-07-2011,355131.33,0,93.29,3.805,129.1677097,13.503 +38,05-08-2011,437631.44,0,90.61,3.803,129.1846452,13.503 +38,12-08-2011,387844.05,0,91.04,3.701,129.2015806,13.503 +38,19-08-2011,362224.7,0,91.74,3.743,129.2405806,13.503 +38,26-08-2011,365672.55,0,94.61,3.74,129.2832581,13.503 +38,02-09-2011,416953.51,0,93.66,3.798,129.3259355,13.503 +38,09-09-2011,397771.68,1,88,3.913,129.3686129,13.503 +38,16-09-2011,408188.88,0,76.36,3.918,129.4306,13.503 +38,23-09-2011,394665.28,0,82.95,3.789,129.5183333,13.503 +38,30-09-2011,366819.84,0,83.26,3.877,129.6060667,13.503 +38,07-10-2011,449516.29,0,70.44,3.827,129.6938,12.89 +38,14-10-2011,400430.78,0,67.31,3.805,129.7706452,12.89 +38,21-10-2011,402709.17,0,73.05,3.842,129.7821613,12.89 +38,28-10-2011,378539.17,0,67.41,3.727,129.7936774,12.89 +38,04-11-2011,436970.1,0,59.77,3.828,129.8051935,12.89 +38,11-11-2011,411116.95,0,48.76,3.824,129.8167097,12.89 +38,18-11-2011,392003.13,0,54.2,3.813,129.8268333,12.89 +38,25-11-2011,393715.71,1,53.25,3.622,129.8364,12.89 +38,02-12-2011,411252.02,0,52.5,3.701,129.8459667,12.89 +38,09-12-2011,435401.64,0,42.17,3.644,129.8555333,12.89 +38,16-12-2011,404283.84,0,43.29,3.6,129.8980645,12.89 +38,23-12-2011,419717.41,0,45.4,3.541,129.9845484,12.89 +38,30-12-2011,342667.35,1,44.64,3.428,130.0710323,12.89 +38,06-01-2012,478483.2,0,50.43,3.599,130.1575161,12.187 +38,13-01-2012,423260.82,0,48.07,3.657,130.244,12.187 +38,20-01-2012,405215.91,0,46.2,3.66,130.2792258,12.187 +38,27-01-2012,412882.31,0,50.43,3.675,130.3144516,12.187 +38,03-02-2012,457711.68,0,50.58,3.702,130.3496774,12.187 +38,10-02-2012,469787.38,1,52.27,3.722,130.3849032,12.187 +38,17-02-2012,415513.97,0,51.8,3.781,130.4546207,12.187 +38,24-02-2012,409411.61,0,53.13,3.95,130.5502069,12.187 +38,02-03-2012,471115.38,0,52.27,4.178,130.6457931,12.187 +38,09-03-2012,452792.53,0,54.54,4.25,130.7413793,12.187 +38,16-03-2012,428465.11,0,64.44,4.273,130.8261935,12.187 +38,23-03-2012,412456.48,0,56.26,4.038,130.8966452,12.187 +38,30-03-2012,408679.36,0,64.36,4.294,130.9670968,12.187 +38,06-04-2012,499267.66,0,64.05,4.121,131.0375484,11.627 +38,13-04-2012,435790.74,0,64.28,4.254,131.108,11.627 +38,20-04-2012,401615.8,0,66.73,4.222,131.1173333,11.627 +38,27-04-2012,419964.77,0,77.99,4.193,131.1266667,11.627 +38,04-05-2012,491755.69,0,76.03,4.171,131.136,11.627 +38,11-05-2012,429914.6,0,77.27,4.186,131.1453333,11.627 +38,18-05-2012,412314.71,0,84.51,4.11,131.0983226,11.627 +38,25-05-2012,422810.12,0,83.84,4.293,131.0287742,11.627 +38,01-06-2012,435579.7,0,78.11,4.277,130.9592258,11.627 +38,08-06-2012,448110.25,0,84.83,4.103,130.8896774,11.627 +38,15-06-2012,430222.07,0,85.94,4.144,130.8295333,11.627 +38,22-06-2012,405938.35,0,91.61,4.014,130.7929,11.627 +38,29-06-2012,404634.36,0,90.47,3.875,130.7562667,11.627 +38,06-07-2012,471086.22,0,89.13,3.765,130.7196333,10.926 +38,13-07-2012,416036.75,0,95.61,3.723,130.683,10.926 +38,20-07-2012,441683.74,0,85.53,3.726,130.7012903,10.926 +38,27-07-2012,407186.47,0,93.47,3.769,130.7195806,10.926 +38,03-08-2012,469311.17,0,88.16,3.76,130.737871,10.926 +38,10-08-2012,436690.13,0,95.91,3.811,130.7561613,10.926 +38,17-08-2012,411866.46,0,94.87,4.002,130.7909677,10.926 +38,24-08-2012,397428.22,0,85.32,4.055,130.8381613,10.926 +38,31-08-2012,424904.95,0,89.78,4.093,130.8853548,10.926 +38,07-09-2012,490274.82,1,88.52,4.124,130.9325484,10.926 +38,14-09-2012,430944.39,0,83.64,4.133,130.9776667,10.926 +38,21-09-2012,409600.98,0,82.97,4.125,131.0103333,10.926 +38,28-09-2012,398468.08,0,81.22,3.966,131.043,10.926 +38,05-10-2012,458479.01,0,81.61,3.966,131.0756667,10.199 +38,12-10-2012,437320.66,0,71.74,4.468,131.1083333,10.199 +38,19-10-2012,428806.46,0,68.66,4.449,131.1499677,10.199 +38,26-10-2012,417290.38,0,65.95,4.301,131.1930968,10.199 +39,05-02-2010,1230596.8,0,44.3,2.572,209.8529663,8.554 +39,12-02-2010,1266229.07,1,44.58,2.548,209.9970208,8.554 +39,19-02-2010,1230591.97,0,43.96,2.514,210.0451024,8.554 +39,26-02-2010,1168582.02,0,49.79,2.561,210.0771885,8.554 +39,05-03-2010,1266254.21,0,50.93,2.625,210.1092746,8.554 +39,12-03-2010,1244391.83,0,61.88,2.667,210.1413607,8.554 +39,19-03-2010,1301590.13,0,58.62,2.72,209.9803208,8.554 +39,26-03-2010,1235094.66,0,54.83,2.732,209.7870932,8.554 +39,02-04-2010,1463942.62,0,63.31,2.719,209.5938656,8.464 +39,09-04-2010,1327035.27,0,68.15,2.77,209.400638,8.464 +39,16-04-2010,1242874.98,0,66.33,2.808,209.2691428,8.464 +39,23-04-2010,1280231.85,0,67.64,2.795,209.2199574,8.464 +39,30-04-2010,1263836.59,0,70.03,2.78,209.170772,8.464 +39,07-05-2010,1355704.21,0,74.86,2.835,209.1215867,8.464 +39,14-05-2010,1226997.7,0,77.49,2.854,209.118536,8.464 +39,21-05-2010,1350673.98,0,76.67,2.826,209.3922937,8.464 +39,28-05-2010,1365541.59,0,80.22,2.759,209.6660514,8.464 +39,04-06-2010,1512207.95,0,79.83,2.705,209.9398091,8.464 +39,11-06-2010,1371405.33,0,81.78,2.668,210.2135668,8.464 +39,18-06-2010,1368312.45,0,83.96,2.637,210.2108417,8.464 +39,25-06-2010,1280414.8,0,83.24,2.653,210.0975233,8.464 +39,02-07-2010,1352547.7,0,81.35,2.669,209.984205,8.36 +39,09-07-2010,1330473.47,0,81.1,2.642,209.8708867,8.36 +39,16-07-2010,1339811.68,0,83.86,2.623,209.8630532,8.36 +39,23-07-2010,1314651.83,0,82.2,2.608,209.9958663,8.36 +39,30-07-2010,1308222.24,0,80.99,2.64,210.1286794,8.36 +39,06-08-2010,1409989.67,0,84.92,2.627,210.2614925,8.36 +39,13-08-2010,1371465.66,0,85.66,2.692,210.3943056,8.36 +39,20-08-2010,1471816.52,0,85.73,2.664,210.3617581,8.36 +39,27-08-2010,1417515.93,0,84.31,2.619,210.3292106,8.36 +39,03-09-2010,1345167.61,0,82.13,2.577,210.2966631,8.36 +39,10-09-2010,1279666.47,1,79.94,2.565,210.2641156,8.36 +39,17-09-2010,1252915.43,0,81.83,2.582,210.2924504,8.36 +39,24-09-2010,1199449.54,0,78.5,2.624,210.3664469,8.36 +39,01-10-2010,1219583.91,0,72.74,2.603,210.4404433,8.476 +39,08-10-2010,1286598.59,0,64.8,2.633,210.5144398,8.476 +39,15-10-2010,1238742,0,69.96,2.72,210.5805944,8.476 +39,22-10-2010,1261109.01,0,71.73,2.725,210.6271444,8.476 +39,29-10-2010,1294769.08,0,75.14,2.716,210.6736944,8.476 +39,05-11-2010,1293707.19,0,61.62,2.689,210.7202444,8.476 +39,12-11-2010,1291398.71,0,62.21,2.728,210.7667944,8.476 +39,19-11-2010,1370659.54,0,55.5,2.771,210.65429,8.476 +39,26-11-2010,2149355.2,1,67.75,2.735,210.5152765,8.476 +39,03-12-2010,1431910.98,0,53.55,2.708,210.376263,8.476 +39,10-12-2010,1630564.48,0,50.81,2.843,210.2372494,8.476 +39,17-12-2010,1842172.46,0,55.31,2.869,210.1787224,8.476 +39,24-12-2010,2495489.25,0,58.86,2.886,210.1805602,8.476 +39,31-12-2010,1230012.16,1,52.45,2.943,210.182398,8.476 +39,07-01-2011,1224475.12,0,52.74,2.976,210.1842358,8.395 +39,14-01-2011,1193199.39,0,41.74,2.983,210.2379731,8.395 +39,21-01-2011,1243370.74,0,50.25,3.016,210.6031072,8.395 +39,28-01-2011,1158698.44,0,47.94,3.01,210.9682412,8.395 +39,04-02-2011,1343773.94,0,45.96,2.989,211.3333753,8.395 +39,11-02-2011,1227893.89,1,40.34,3.022,211.6985093,8.395 +39,18-02-2011,1335233.74,0,58.2,3.045,212.0063522,8.395 +39,25-02-2011,1240921.19,0,67.77,3.065,212.2912786,8.395 +39,04-03-2011,1316385.43,0,63.56,3.288,212.576205,8.395 +39,11-03-2011,1283716.81,0,58.35,3.459,212.8611313,8.395 +39,18-03-2011,1348410.05,0,65.28,3.488,213.1096787,8.395 +39,25-03-2011,1284334.79,0,71.17,3.473,213.3436744,8.395 +39,01-04-2011,1316849.36,0,66.57,3.524,213.5776701,8.3 +39,08-04-2011,1350646.16,0,69.45,3.622,213.8116658,8.3 +39,15-04-2011,1348031.55,0,73.19,3.743,214.026217,8.3 +39,22-04-2011,1563140.85,0,74.98,3.807,214.1921572,8.3 +39,29-04-2011,1379651.87,0,76.47,3.81,214.3580974,8.3 +39,06-05-2011,1370920.87,0,68.75,3.906,214.5240376,8.3 +39,13-05-2011,1325022.77,0,77.39,3.899,214.6899778,8.3 +39,20-05-2011,1373907.21,0,73.31,3.907,214.465412,8.3 +39,27-05-2011,1406124.14,0,82.1,3.786,214.2408462,8.3 +39,03-06-2011,1541745.59,0,83.59,3.699,214.0162805,8.3 +39,10-06-2011,1442092.08,0,82.75,3.648,213.7917147,8.3 +39,17-06-2011,1451392.67,0,85.21,3.637,213.7481256,8.3 +39,24-06-2011,1363167.95,0,84.06,3.594,213.8402689,8.3 +39,01-07-2011,1429829.36,0,84.93,3.524,213.9324122,8.177 +39,08-07-2011,1414564.53,0,84.33,3.48,214.0245556,8.177 +39,15-07-2011,1380257.12,0,85.96,3.575,214.1083654,8.177 +39,22-07-2011,1416005.59,0,84.6,3.651,214.1713416,8.177 +39,29-07-2011,1426418.53,0,86.24,3.682,214.2343177,8.177 +39,05-08-2011,1518790.89,0,87.73,3.684,214.2972939,8.177 +39,12-08-2011,1514055.97,0,88.27,3.638,214.3602701,8.177 +39,19-08-2011,1629066.9,0,87.93,3.554,214.4239935,8.177 +39,26-08-2011,1573898.63,0,86.49,3.523,214.4878416,8.177 +39,02-09-2011,1465089.85,0,88.65,3.533,214.5516896,8.177 +39,09-09-2011,1429345.86,1,79.15,3.546,214.6155376,8.177 +39,16-09-2011,1372500.63,0,83.11,3.526,214.7934111,8.177 +39,23-09-2011,1338657.95,0,78.75,3.467,215.1233185,8.177 +39,30-09-2011,1311775.83,0,81.51,3.355,215.4532259,8.177 +39,07-10-2011,1443884.39,0,71.68,3.285,215.7831333,7.716 +39,14-10-2011,1384721.84,0,73.79,3.274,216.0885258,7.716 +39,21-10-2011,1465283.29,0,67.65,3.353,216.2468287,7.716 +39,28-10-2011,1472663.1,0,71.05,3.372,216.4051315,7.716 +39,04-11-2011,1553629.59,0,58.04,3.332,216.5634344,7.716 +39,11-11-2011,1456957.38,0,63.11,3.297,216.7217373,7.716 +39,18-11-2011,1510397.27,0,66.09,3.308,216.9395861,7.716 +39,25-11-2011,2338832.4,1,66.36,3.236,217.1812533,7.716 +39,02-12-2011,1632894.58,0,53.14,3.172,217.4229206,7.716 +39,09-12-2011,1781528.77,0,49.36,3.158,217.6645878,7.716 +39,16-12-2011,1991824.05,0,58.58,3.159,217.8781339,7.716 +39,23-12-2011,2554482.84,0,54.62,3.112,218.0541851,7.716 +39,30-12-2011,1537139.56,1,47.6,3.129,218.2302364,7.716 +39,06-01-2012,1478537.93,0,55.83,3.157,218.4062876,7.244 +39,13-01-2012,1369125.37,0,54.66,3.261,218.5823389,7.244 +39,20-01-2012,1394841.03,0,58.04,3.268,218.6755292,7.244 +39,27-01-2012,1320301.61,0,60.65,3.29,218.7687195,7.244 +39,03-02-2012,1396150.15,0,60.69,3.36,218.8619099,7.244 +39,10-02-2012,1442988.44,1,52.89,3.409,218.9551002,7.244 +39,17-02-2012,1511041.69,0,52.75,3.51,219.1148297,7.244 +39,24-02-2012,1412065.04,0,61.1,3.555,219.3244636,7.244 +39,02-03-2012,1453047.02,0,64.05,3.63,219.5340975,7.244 +39,09-03-2012,1470764.35,0,61.64,3.669,219.7437314,7.244 +39,16-03-2012,1522421.07,0,65.81,3.734,219.8956335,7.244 +39,23-03-2012,1469593.37,0,67.91,3.787,219.9705599,7.244 +39,30-03-2012,1499727.02,0,69.11,3.845,220.0454862,7.244 +39,06-04-2012,1764847.94,0,73.49,3.891,220.1204125,6.989 +39,13-04-2012,1580732.73,0,71.59,3.891,220.1953389,6.989 +39,20-04-2012,1433391.04,0,70.04,3.877,220.2483937,6.989 +39,27-04-2012,1456997.2,0,69.11,3.814,220.3014485,6.989 +39,04-05-2012,1512227.34,0,77.15,3.749,220.3545033,6.989 +39,11-05-2012,1470792.41,0,75.52,3.688,220.4075581,6.989 +39,18-05-2012,1522978.54,0,72.36,3.63,220.4252149,6.989 +39,25-05-2012,1596036.66,0,78.31,3.561,220.4287124,6.989 +39,01-06-2012,1640476.77,0,80.33,3.501,220.4322099,6.989 +39,08-06-2012,1623442.24,0,81.12,3.452,220.4357073,6.989 +39,15-06-2012,1587499.82,0,81.33,3.393,220.4494148,6.989 +39,22-06-2012,1532316.79,0,79.84,3.346,220.4886472,6.989 +39,29-06-2012,1492388.98,0,85.72,3.286,220.5278796,6.989 +39,06-07-2012,1659221.99,0,81.05,3.227,220.567112,6.623 +39,13-07-2012,1471261.76,0,78.16,3.256,220.6063444,6.623 +39,20-07-2012,1582168.27,0,80.32,3.311,220.6148749,6.623 +39,27-07-2012,1487797.54,0,82.89,3.407,220.6234054,6.623 +39,03-08-2012,1608277.74,0,84.05,3.417,220.6319358,6.623 +39,10-08-2012,1641867.92,0,83.47,3.494,220.6404663,6.623 +39,17-08-2012,1720221.91,0,84.72,3.571,220.7199609,6.623 +39,24-08-2012,1724669.75,0,80.49,3.62,220.8526787,6.623 +39,31-08-2012,1710923.94,0,83.72,3.638,220.9853964,6.623 +39,07-09-2012,1609811.75,1,83.71,3.73,221.1181142,6.623 +39,14-09-2012,1447614.08,0,76.71,3.717,221.2601207,6.623 +39,21-09-2012,1555672.51,0,73.58,3.721,221.4578604,6.623 +39,28-09-2012,1495607.07,0,78.04,3.666,221.6556,6.623 +39,05-10-2012,1574408.67,0,72.05,3.617,221.8533396,6.228 +39,12-10-2012,1494417.07,0,69.88,3.601,222.0510793,6.228 +39,19-10-2012,1577486.33,0,71.45,3.594,222.0951719,6.228 +39,26-10-2012,1569502,0,72.9,3.506,222.1136566,6.228 +40,05-02-2010,1001943.8,0,14.48,2.788,131.5279032,5.892 +40,12-02-2010,955338.29,1,20.84,2.771,131.5866129,5.892 +40,19-02-2010,916289.2,0,27.84,2.747,131.637,5.892 +40,26-02-2010,863917.41,0,33.32,2.753,131.686,5.892 +40,05-03-2010,990152.28,0,34.78,2.766,131.735,5.892 +40,12-03-2010,899352.4,0,35.1,2.805,131.784,5.892 +40,19-03-2010,894865.3,0,40.54,2.834,131.8242903,5.892 +40,26-03-2010,873354.58,0,39.51,2.831,131.863129,5.892 +40,02-04-2010,1041202.13,0,41.39,2.826,131.9019677,5.435 +40,09-04-2010,919839.19,0,54.31,2.849,131.9408065,5.435 +40,16-04-2010,882636.96,0,43.3,2.885,131.9809,5.435 +40,23-04-2010,844958.49,0,45.85,2.895,132.0226667,5.435 +40,30-04-2010,816838.31,0,46.5,2.935,132.0644333,5.435 +40,07-05-2010,1009797.06,0,60.05,2.981,132.1062,5.435 +40,14-05-2010,907262.47,0,45.5,2.983,132.152129,5.435 +40,21-05-2010,885613.91,0,56.75,2.961,132.2230323,5.435 +40,28-05-2010,1008483.07,0,67.88,2.906,132.2939355,5.435 +40,04-06-2010,1052429.03,0,65.7,2.857,132.3648387,5.435 +40,11-06-2010,1007574.67,0,59.42,2.83,132.4357419,5.435 +40,18-06-2010,973105.3,0,60.97,2.805,132.4733333,5.435 +40,25-06-2010,940405.03,0,69.72,2.81,132.4976,5.435 +40,02-07-2010,1087578.78,0,65.47,2.815,132.5218667,5.326 +40,09-07-2010,1058250.91,0,76.67,2.806,132.5461333,5.326 +40,16-07-2010,959229.09,0,74.25,2.796,132.5667742,5.326 +40,23-07-2010,922341.82,0,71.79,2.784,132.5825806,5.326 +40,30-07-2010,953393.02,0,71.35,2.792,132.5983871,5.326 +40,06-08-2010,1057295.87,0,69.16,2.792,132.6141935,5.326 +40,13-08-2010,924011.76,0,67.47,2.81,132.63,5.326 +40,20-08-2010,932397,0,67.05,2.796,132.6616129,5.326 +40,27-08-2010,922328.02,0,62.57,2.77,132.6932258,5.326 +40,03-09-2010,976453.34,0,70.66,2.735,132.7248387,5.326 +40,10-09-2010,967310.82,1,62.75,2.717,132.7564516,5.326 +40,17-09-2010,855046.95,0,55.34,2.716,132.7670667,5.326 +40,24-09-2010,844373.31,0,55.63,2.718,132.7619333,5.326 +40,01-10-2010,891152.33,0,62.01,2.717,132.7568,5.287 +40,08-10-2010,972405.38,0,52.02,2.776,132.7516667,5.287 +40,15-10-2010,917883.17,0,44.56,2.878,132.7633548,5.287 +40,22-10-2010,882180.91,0,41.25,2.919,132.8170968,5.287 +40,29-10-2010,875038.84,0,47.1,2.938,132.8708387,5.287 +40,05-11-2010,968270.66,0,36.45,2.938,132.9245806,5.287 +40,12-11-2010,935481.32,0,38.5,2.961,132.9783226,5.287 +40,19-11-2010,852452.93,0,40.52,3.03,132.9172,5.287 +40,26-11-2010,1166142.85,1,32.94,3.07,132.8369333,5.287 +40,03-12-2010,1000582.06,0,33.6,3.065,132.7566667,5.287 +40,10-12-2010,1111215.72,0,21.64,3.132,132.6764,5.287 +40,17-12-2010,1179036.3,0,23.01,3.139,132.6804516,5.287 +40,24-12-2010,1648829.18,0,24.18,3.15,132.7477419,5.287 +40,31-12-2010,811318.3,1,19.29,3.177,132.8150323,5.287 +40,07-01-2011,894280.19,0,24.05,3.193,132.8823226,5.114 +40,14-01-2011,771315.62,0,18.55,3.215,132.9510645,5.114 +40,21-01-2011,764014.75,0,14.64,3.232,133.0285161,5.114 +40,28-01-2011,775910.43,0,9.51,3.243,133.1059677,5.114 +40,04-02-2011,904261.65,0,13.29,3.24,133.1834194,5.114 +40,11-02-2011,931939.52,1,16.87,3.255,133.260871,5.114 +40,18-02-2011,968694.45,0,21.82,3.263,133.3701429,5.114 +40,25-02-2011,888869.27,0,16.5,3.281,133.4921429,5.114 +40,04-03-2011,977070.62,0,18.49,3.437,133.6141429,5.114 +40,11-03-2011,860255.58,0,30.53,3.6,133.7361429,5.114 +40,18-03-2011,871024.26,0,35.76,3.634,133.8492258,5.114 +40,25-03-2011,834621.39,0,28.89,3.624,133.9587419,5.114 +40,01-04-2011,841889.08,0,28.6,3.638,134.0682581,4.781 +40,08-04-2011,947753.32,0,34.77,3.72,134.1777742,4.781 +40,15-04-2011,874446.32,0,43.69,3.823,134.2784667,4.781 +40,22-04-2011,965056.4,0,39.32,3.919,134.3571,4.781 +40,29-04-2011,847246.5,0,52.68,3.988,134.4357333,4.781 +40,06-05-2011,1016752.55,0,50.81,4.078,134.5143667,4.781 +40,13-05-2011,903864.02,0,54.09,4.095,134.593,4.781 +40,20-05-2011,907110.83,0,56.38,4.101,134.6803871,4.781 +40,27-05-2011,972373.81,0,63.11,4.034,134.7677742,4.781 +40,03-06-2011,1075687.74,0,66.16,3.973,134.8551613,4.781 +40,10-06-2011,984336.04,0,64.19,3.924,134.9425484,4.781 +40,17-06-2011,971422.67,0,59.16,3.873,135.0837333,4.781 +40,24-06-2011,977103.64,0,62.59,3.851,135.2652667,4.781 +40,01-07-2011,1048866.3,0,65.25,3.815,135.4468,4.584 +40,08-07-2011,1107366.06,0,67.86,3.784,135.6283333,4.584 +40,15-07-2011,953252.14,0,68.9,3.827,135.7837419,4.584 +40,22-07-2011,980642.1,0,73.34,3.882,135.8738387,4.584 +40,29-07-2011,929096.9,0,67.45,3.898,135.9639355,4.584 +40,05-08-2011,1063818.2,0,68.1,3.903,136.0540323,4.584 +40,12-08-2011,955506.95,0,68.3,3.88,136.144129,4.584 +40,19-08-2011,943237.12,0,64.05,3.82,136.183129,4.584 +40,26-08-2011,969611.3,0,65.01,3.796,136.2136129,4.584 +40,02-09-2011,957298.26,0,63.79,3.784,136.2440968,4.584 +40,09-09-2011,1021391.99,1,64.83,3.809,136.2745806,4.584 +40,16-09-2011,890661.79,0,58.28,3.809,136.3145,4.584 +40,23-09-2011,876583.98,0,54.09,3.758,136.367,4.584 +40,30-09-2011,912857.1,0,63.45,3.684,136.4195,4.584 +40,07-10-2011,1070389.98,0,50.21,3.633,136.472,4.42 +40,14-10-2011,936751.68,0,53.9,3.583,136.5150968,4.42 +40,21-10-2011,942319.65,0,51.61,3.618,136.5017742,4.42 +40,28-10-2011,941675.95,0,42.09,3.604,136.4884516,4.42 +40,04-11-2011,1011321.18,0,35.4,3.586,136.475129,4.42 +40,11-11-2011,1037687.07,0,40.75,3.57,136.4618065,4.42 +40,18-11-2011,905399.99,0,41.85,3.571,136.4666667,4.42 +40,25-11-2011,1230011.95,1,32.76,3.536,136.4788,4.42 +40,02-12-2011,1059676.62,0,38.51,3.501,136.4909333,4.42 +40,09-12-2011,1158708.98,0,34.48,3.47,136.5030667,4.42 +40,16-12-2011,1198670.19,0,29.53,3.445,136.5335161,4.42 +40,23-12-2011,1601585.7,0,24.46,3.413,136.5883871,4.42 +40,30-12-2011,908853.15,1,18.75,3.402,136.6432581,4.42 +40,06-01-2012,954576.86,0,23.29,3.439,136.698129,4.261 +40,13-01-2012,780607.52,0,25.9,3.523,136.753,4.261 +40,20-01-2012,811365.42,0,14.02,3.542,136.8564194,4.261 +40,27-01-2012,770157.29,0,22.91,3.568,136.9598387,4.261 +40,03-02-2012,979552.34,0,27.86,3.633,137.0632581,4.261 +40,10-02-2012,999785.48,1,23.92,3.655,137.1666774,4.261 +40,17-02-2012,975500.87,0,25.56,3.703,137.2583103,4.261 +40,24-02-2012,919301.81,0,29.88,3.751,137.3411034,4.261 +40,02-03-2012,927732.02,0,23.79,3.827,137.4238966,4.261 +40,09-03-2012,954233.87,0,30.58,3.876,137.5066897,4.261 +40,16-03-2012,891154.18,0,37.13,3.867,137.5843871,4.261 +40,23-03-2012,844490.86,0,52.27,3.889,137.6552903,4.261 +40,30-03-2012,871945.64,0,36.25,3.921,137.7261935,4.261 +40,06-04-2012,1132064.23,0,36.54,3.957,137.7970968,4.125 +40,13-04-2012,857811.17,0,40.65,4.025,137.868,4.125 +40,20-04-2012,896979.93,0,55.3,4.046,137.9230667,4.125 +40,27-04-2012,875372.91,0,47.51,4.023,137.9781333,4.125 +40,04-05-2012,993311.59,0,44.47,3.991,138.0332,4.125 +40,11-05-2012,967729.35,0,52.06,3.947,138.0882667,4.125 +40,18-05-2012,896295.41,0,57.59,3.899,138.1065806,4.125 +40,25-05-2012,991054.49,0,65.25,3.85,138.1101935,4.125 +40,01-06-2012,1037464.27,0,64.75,3.798,138.1138065,4.125 +40,08-06-2012,1079386.88,0,55.78,3.746,138.1174194,4.125 +40,15-06-2012,977950.28,0,63.39,3.683,138.1295333,4.125 +40,22-06-2012,1033552.18,0,69.32,3.629,138.1629,4.125 +40,29-06-2012,988764.84,0,64.42,3.577,138.1962667,4.125 +40,06-07-2012,1182901.56,0,69.08,3.538,138.2296333,4.156 +40,13-07-2012,979848.71,0,67.48,3.561,138.263,4.156 +40,20-07-2012,968502.38,0,70.45,3.61,138.2331935,4.156 +40,27-07-2012,954396.85,0,67.88,3.701,138.2033871,4.156 +40,03-08-2012,1068346.76,0,70.15,3.698,138.1735806,4.156 +40,10-08-2012,1007906.43,0,70.09,3.772,138.1437742,4.156 +40,17-08-2012,969387.48,0,69.41,3.84,138.1857097,4.156 +40,24-08-2012,945318.47,0,63.91,3.874,138.2814516,4.156 +40,31-08-2012,987264.67,0,66.11,3.884,138.3771935,4.156 +40,07-09-2012,1088248.4,1,65.06,3.921,138.4729355,4.156 +40,14-09-2012,901709.82,0,59.38,3.988,138.5673,4.156 +40,21-09-2012,899768.4,0,54.12,4.056,138.6534,4.156 +40,28-09-2012,919595.44,0,50.98,4.018,138.7395,4.156 +40,05-10-2012,1069112,0,57.21,4.027,138.8256,4.145 +40,12-10-2012,982523.26,0,47.35,4.029,138.9117,4.145 +40,19-10-2012,918170.5,0,46.33,4,138.8336129,4.145 +40,26-10-2012,921264.52,0,49.65,3.917,138.7281613,4.145 +41,05-02-2010,1086533.18,0,30.27,2.58,189.3816974,7.541 +41,12-02-2010,1075656.34,1,23.04,2.572,189.4642725,7.541 +41,19-02-2010,1052034.74,0,24.13,2.55,189.5340998,7.541 +41,26-02-2010,991941.73,0,21.84,2.586,189.6018023,7.541 +41,05-03-2010,1063557.49,0,32.49,2.62,189.6695049,7.541 +41,12-03-2010,1023997.71,0,33.4,2.684,189.7372075,7.541 +41,19-03-2010,1006597.69,0,36.7,2.692,189.734262,7.541 +41,26-03-2010,1015196.46,0,32.3,2.717,189.7195417,7.541 +41,02-04-2010,1168826.39,0,41.31,2.725,189.7048215,7.363 +41,09-04-2010,1082158.21,0,37.3,2.75,189.6901012,7.363 +41,16-04-2010,1043388.79,0,46.79,2.765,189.6628845,7.363 +41,23-04-2010,1067340.74,0,45.29,2.776,189.6190057,7.363 +41,30-04-2010,1063960.11,0,40.2,2.766,189.575127,7.363 +41,07-05-2010,1175738.22,0,41.5,2.771,189.5312483,7.363 +41,14-05-2010,1116439.02,0,40.23,2.788,189.4904116,7.363 +41,21-05-2010,1163234.33,0,50.59,2.776,189.467827,7.363 +41,28-05-2010,1246654.24,0,56.97,2.737,189.4452425,7.363 +41,04-06-2010,1305068.1,0,60.13,2.7,189.422658,7.363 +41,11-06-2010,1217199.39,0,63.36,2.684,189.4000734,7.363 +41,18-06-2010,1202963.06,0,54.9,2.674,189.4185259,7.363 +41,25-06-2010,1174209.52,0,66,2.715,189.4533931,7.363 +41,02-07-2010,1273279.79,0,69.39,2.728,189.4882603,7.335 +41,09-07-2010,1176079.59,0,60.93,2.711,189.5231276,7.335 +41,16-07-2010,1179788.38,0,69.06,2.699,189.6125456,7.335 +41,23-07-2010,1192213.87,0,70.77,2.691,189.774698,7.335 +41,30-07-2010,1211136.63,0,70.07,2.69,189.9368504,7.335 +41,06-08-2010,1338132.72,0,69.21,2.69,190.0990028,7.335 +41,13-08-2010,1285976.53,0,70.24,2.723,190.2611552,7.335 +41,20-08-2010,1353838.39,0,66.19,2.732,190.2948237,7.335 +41,27-08-2010,1173131.63,0,70.59,2.731,190.3284922,7.335 +41,03-09-2010,1223355.5,0,64.13,2.773,190.3621607,7.335 +41,10-09-2010,1172672.27,1,63.3,2.78,190.3958293,7.335 +41,17-09-2010,1111170.91,0,62.4,2.8,190.4688287,7.335 +41,24-09-2010,1110941.78,0,60.11,2.793,190.5713264,7.335 +41,01-10-2010,1109216.35,0,62.67,2.759,190.6738241,7.508 +41,08-10-2010,1162042.24,0,57.1,2.745,190.7763218,7.508 +41,15-10-2010,1133913.33,0,49.91,2.762,190.8623087,7.508 +41,22-10-2010,1156003.7,0,48.09,2.762,190.9070184,7.508 +41,29-10-2010,1144854.56,0,42.16,2.748,190.951728,7.508 +41,05-11-2010,1163878.49,0,46.74,2.729,190.9964377,7.508 +41,12-11-2010,1175326.23,0,38.99,2.737,191.0411474,7.508 +41,19-11-2010,1172155.28,0,31.34,2.758,191.0312172,7.508 +41,26-11-2010,1866681.57,1,25.3,2.742,191.0121805,7.508 +41,03-12-2010,1220115.75,0,33,2.712,190.9931437,7.508 +41,10-12-2010,1434908.13,0,33.9,2.728,190.9741069,7.508 +41,17-12-2010,1627904.68,0,31.51,2.778,191.0303376,7.508 +41,24-12-2010,2225016.73,0,29.81,2.781,191.1430189,7.508 +41,31-12-2010,1001790.16,1,25.19,2.829,191.2557002,7.508 +41,07-01-2011,1153596.53,0,23.76,2.882,191.3683815,7.241 +41,14-01-2011,1052609.16,0,22.44,2.911,191.4784939,7.241 +41,21-01-2011,1088025.8,0,32.7,2.973,191.5731924,7.241 +41,28-01-2011,1026439.93,0,32.23,3.008,191.667891,7.241 +41,04-02-2011,1179420.5,0,14.56,3.011,191.7625895,7.241 +41,11-02-2011,1150003.36,1,16.81,3.037,191.8572881,7.241 +41,18-02-2011,1203399.64,0,39.39,3.051,191.9178331,7.241 +41,25-02-2011,1099714.93,0,26.1,3.101,191.9647167,7.241 +41,04-03-2011,1229257.7,0,34.99,3.232,192.0116004,7.241 +41,11-03-2011,1159089.6,0,31.6,3.372,192.058484,7.241 +41,18-03-2011,1115504.26,0,40.19,3.406,192.1237981,7.241 +41,25-03-2011,1140578.16,0,41.11,3.414,192.1964844,7.241 +41,01-04-2011,1179125.48,0,38.16,3.461,192.2691707,6.934 +41,08-04-2011,1206252.12,0,42.87,3.532,192.3418571,6.934 +41,15-04-2011,1192982.07,0,39.94,3.611,192.4225954,6.934 +41,22-04-2011,1304481.75,0,42.86,3.636,192.5234638,6.934 +41,29-04-2011,1178841.05,0,39.81,3.663,192.6243322,6.934 +41,06-05-2011,1244956.91,0,41.2,3.735,192.7252006,6.934 +41,13-05-2011,1270025.74,0,50.29,3.767,192.826069,6.934 +41,20-05-2011,1244542.33,0,41.11,3.828,192.831317,6.934 +41,27-05-2011,1278304.33,0,50.56,3.795,192.8365651,6.934 +41,03-06-2011,1297584.95,0,54.81,3.763,192.8418131,6.934 +41,10-06-2011,1311690.11,0,61.1,3.735,192.8470612,6.934 +41,17-06-2011,1289151.84,0,62.3,3.697,192.9034759,6.934 +41,24-06-2011,1244381.98,0,59.54,3.661,192.9982655,6.934 +41,01-07-2011,1333347.78,0,67.01,3.597,193.0930552,6.901 +41,08-07-2011,1338862.58,0,68.49,3.54,193.1878448,6.901 +41,15-07-2011,1245772.7,0,68.18,3.532,193.3125484,6.901 +41,22-07-2011,1292830.93,0,74.11,3.545,193.5120367,6.901 +41,29-07-2011,1248330.1,0,71.3,3.547,193.711525,6.901 +41,05-08-2011,1402233.69,0,72.19,3.554,193.9110133,6.901 +41,12-08-2011,1356689.88,0,67.65,3.542,194.1105017,6.901 +41,19-08-2011,1412959.97,0,70.55,3.499,194.2500634,6.901 +41,26-08-2011,1328740.71,0,71.61,3.485,194.3796374,6.901 +41,02-09-2011,1283849.38,0,70.37,3.511,194.5092113,6.901 +41,09-09-2011,1280958.97,1,58.31,3.566,194.6387853,6.901 +41,16-09-2011,1197019.39,0,54.82,3.596,194.7419707,6.901 +41,23-09-2011,1173059.79,0,55.06,3.581,194.8099713,6.901 +41,30-09-2011,1160619.61,0,61.77,3.538,194.8779718,6.901 +41,07-10-2011,1277882.77,0,58.74,3.498,194.9459724,6.759 +41,14-10-2011,1247130.22,0,47.43,3.491,195.0261012,6.759 +41,21-10-2011,1214944.29,0,45.62,3.548,195.1789994,6.759 +41,28-10-2011,1274463.02,0,37.02,3.55,195.3318977,6.759 +41,04-11-2011,1315684.86,0,35.04,3.527,195.4847959,6.759 +41,11-11-2011,1302499.23,0,32.87,3.505,195.6376941,6.759 +41,18-11-2011,1230118.02,0,36.64,3.479,195.7184713,6.759 +41,25-11-2011,1906713.35,1,36.37,3.424,195.7704,6.759 +41,02-12-2011,1292436.23,0,34.53,3.378,195.8223287,6.759 +41,09-12-2011,1548661.45,0,17.05,3.331,195.8742575,6.759 +41,16-12-2011,1682368.32,0,25.01,3.266,195.9841685,6.759 +41,23-12-2011,2263722.68,0,25.59,3.173,196.1713893,6.759 +41,30-12-2011,1264014.16,1,34.12,3.119,196.3586101,6.759 +41,06-01-2012,1208191.61,0,37.21,3.095,196.5458309,6.589 +41,13-01-2012,1134767.28,0,27.49,3.077,196.7330517,6.589 +41,20-01-2012,1116295.24,0,31.56,3.055,196.7796652,6.589 +41,27-01-2012,1079398.81,0,33.15,3.038,196.8262786,6.589 +41,03-02-2012,1208825.6,0,31.65,3.031,196.8728921,6.589 +41,10-02-2012,1238844.56,1,22,3.103,196.9195056,6.589 +41,17-02-2012,1330451.46,0,22.52,3.113,196.9432711,6.589 +41,24-02-2012,1224915.66,0,27.89,3.129,196.9499007,6.589 +41,02-03-2012,1239813.26,0,27.39,3.191,196.9565303,6.589 +41,09-03-2012,1243814.77,0,35.3,3.286,196.9631599,6.589 +41,16-03-2012,1201511.62,0,47.76,3.486,197.0457208,6.589 +41,23-03-2012,1215354.38,0,44.04,3.664,197.2295234,6.589 +41,30-03-2012,1239423.19,0,51.56,3.75,197.4133259,6.589 +41,06-04-2012,1460234.31,0,48.48,3.854,197.5971285,6.547 +41,13-04-2012,1323004.73,0,46.84,3.901,197.780931,6.547 +41,20-04-2012,1220815.33,0,43.57,3.936,197.7227385,6.547 +41,27-04-2012,1248950.65,0,57.66,3.927,197.664546,6.547 +41,04-05-2012,1359770.73,0,52.86,3.903,197.6063534,6.547 +41,11-05-2012,1353285.1,0,50.22,3.87,197.5481609,6.547 +41,18-05-2012,1331514.44,0,55.24,3.837,197.5553137,6.547 +41,25-05-2012,1424500.47,0,54.89,3.804,197.5886046,6.547 +41,01-06-2012,1374891.36,0,57.29,3.764,197.6218954,6.547 +41,08-06-2012,1436383.84,0,65.11,3.741,197.6551863,6.547 +41,15-06-2012,1384584.59,0,64.92,3.723,197.692292,6.547 +41,22-06-2012,1386407.17,0,66.88,3.735,197.7389345,6.547 +41,29-06-2012,1355600.01,0,76.54,3.693,197.785577,6.547 +41,06-07-2012,1456300.89,0,74.47,3.646,197.8322195,6.432 +41,13-07-2012,1332594.07,0,67.24,3.613,197.8788621,6.432 +41,20-07-2012,1347175.93,0,74.06,3.585,197.9290378,6.432 +41,27-07-2012,1344723.97,0,73.31,3.57,197.9792136,6.432 +41,03-08-2012,1439607.35,0,73.16,3.528,198.0293893,6.432 +41,10-08-2012,1504545.94,0,71.73,3.509,198.0795651,6.432 +41,17-08-2012,1560590.05,0,65.77,3.545,198.1001057,6.432 +41,24-08-2012,1464462.85,0,69.07,3.558,198.0984199,6.432 +41,31-08-2012,1360517.52,0,71.56,3.556,198.0967341,6.432 +41,07-09-2012,1392143.82,1,67.41,3.596,198.0950484,6.432 +41,14-09-2012,1306644.25,0,59.39,3.659,198.1267184,6.432 +41,21-09-2012,1276609.36,0,59.81,3.765,198.358523,6.432 +41,28-09-2012,1307928.01,0,56.08,3.789,198.5903276,6.432 +41,05-10-2012,1400160.95,0,50.14,3.779,198.8221322,6.195 +41,12-10-2012,1409544.97,0,39.38,3.76,199.0539368,6.195 +41,19-10-2012,1326197.24,0,49.56,3.75,199.1481963,6.195 +41,26-10-2012,1316542.59,0,41.8,3.686,199.2195317,6.195 +42,05-02-2010,543384.01,0,54.34,2.962,126.4420645,9.765 +42,12-02-2010,575709.96,1,49.96,2.828,126.4962581,9.765 +42,19-02-2010,508794.87,0,58.22,2.915,126.5262857,9.765 +42,26-02-2010,491510.58,0,52.77,2.825,126.5522857,9.765 +42,05-03-2010,554972.42,0,55.92,2.877,126.5782857,9.765 +42,12-03-2010,588363.62,0,52.33,3.034,126.6042857,9.765 +42,19-03-2010,519914.1,0,61.46,3.054,126.6066452,9.765 +42,26-03-2010,478021.68,0,60.05,2.98,126.6050645,9.765 +42,02-04-2010,505907.41,0,63.66,3.086,126.6034839,9.524 +42,09-04-2010,582552.26,0,65.29,3.004,126.6019032,9.524 +42,16-04-2010,549528.16,0,69.74,3.109,126.5621,9.524 +42,23-04-2010,492364.77,0,66.42,3.05,126.4713333,9.524 +42,30-04-2010,477615.87,0,69.76,3.105,126.3805667,9.524 +42,07-05-2010,582846.22,0,71.06,3.127,126.2898,9.524 +42,14-05-2010,564345.55,0,73.88,3.145,126.2085484,9.524 +42,21-05-2010,504403.16,0,78.32,3.12,126.1843871,9.524 +42,28-05-2010,484097.03,0,76.67,3.058,126.1602258,9.524 +42,04-06-2010,556046.12,0,82.82,2.941,126.1360645,9.524 +42,11-06-2010,607218.6,0,89.67,3.057,126.1119032,9.524 +42,18-06-2010,529418.64,0,83.49,2.935,126.114,9.524 +42,25-06-2010,484327.56,0,90.32,3.084,126.1266,9.524 +42,02-07-2010,507168.8,0,92.89,2.978,126.1392,9.199 +42,09-07-2010,570069.48,0,91.03,3.1,126.1518,9.199 +42,16-07-2010,558837.27,0,91.8,2.971,126.1498065,9.199 +42,23-07-2010,491115.86,0,88.44,3.112,126.1283548,9.199 +42,30-07-2010,469598.57,0,85.03,3.017,126.1069032,9.199 +42,06-08-2010,579544.21,0,86.13,3.123,126.0854516,9.199 +42,13-08-2010,583079.97,0,88.37,3.049,126.064,9.199 +42,20-08-2010,500945.63,0,89.88,3.041,126.0766452,9.199 +42,27-08-2010,465993.51,0,84.99,3.022,126.0892903,9.199 +42,03-09-2010,524658.06,0,83.8,3.087,126.1019355,9.199 +42,10-09-2010,589091.04,1,84.04,2.961,126.1145806,9.199 +42,17-09-2010,536871.58,0,85.52,3.028,126.1454667,9.199 +42,24-09-2010,492262.96,0,85.75,2.939,126.1900333,9.199 +42,01-10-2010,481523.93,0,86.01,3.001,126.2346,9.003 +42,08-10-2010,599759.45,0,77.04,2.924,126.2791667,9.003 +42,15-10-2010,559285.35,0,75.48,3.08,126.3266774,9.003 +42,22-10-2010,522467.51,0,68.12,3.014,126.3815484,9.003 +42,29-10-2010,476967.65,0,68.76,3.13,126.4364194,9.003 +42,05-11-2010,565390.4,0,71.04,3.009,126.4912903,9.003 +42,12-11-2010,588592.61,0,61.24,3.13,126.5461613,9.003 +42,19-11-2010,524316.21,0,58.83,3.047,126.6072,9.003 +42,26-11-2010,522296.71,1,55.33,3.162,126.6692667,9.003 +42,03-12-2010,500250.8,0,51.17,3.041,126.7313333,9.003 +42,10-12-2010,585175.24,0,60.51,3.091,126.7934,9.003 +42,17-12-2010,537455.65,0,59.15,3.125,126.8794839,9.003 +42,24-12-2010,555075.27,0,57.06,3.236,126.9835806,9.003 +42,31-12-2010,428953.6,1,49.67,3.148,127.0876774,9.003 +42,07-01-2011,592947.75,0,43.43,3.287,127.1917742,8.744 +42,14-01-2011,613899.15,0,49.98,3.312,127.3009355,8.744 +42,21-01-2011,533414.62,0,56.75,3.336,127.4404839,8.744 +42,28-01-2011,499081.79,0,53.03,3.231,127.5800323,8.744 +42,04-02-2011,586886.16,0,44.88,3.348,127.7195806,8.744 +42,11-02-2011,628063.88,1,51.51,3.381,127.859129,8.744 +42,18-02-2011,556485.1,0,61.77,3.43,127.99525,8.744 +42,25-02-2011,526904.08,0,53.59,3.398,128.13,8.744 +42,04-03-2011,570879.04,0,56.96,3.674,128.26475,8.744 +42,11-03-2011,607294.56,0,64.22,3.63,128.3995,8.744 +42,18-03-2011,558239.32,0,70.12,3.892,128.5121935,8.744 +42,25-03-2011,522673.62,0,62.53,3.716,128.6160645,8.744 +42,01-04-2011,508432.17,0,67.64,3.772,128.7199355,8.494 +42,08-04-2011,620087.35,0,73.03,3.818,128.8238065,8.494 +42,15-04-2011,597644.02,0,61.05,4.089,128.9107333,8.494 +42,22-04-2011,534597.69,0,75.93,3.917,128.9553,8.494 +42,29-04-2011,496010.17,0,73.38,4.151,128.9998667,8.494 +42,06-05-2011,612337.35,0,73.56,4.193,129.0444333,8.494 +42,13-05-2011,603024.75,0,74.04,4.202,129.089,8.494 +42,20-05-2011,524559.95,0,72.62,3.99,129.0756774,8.494 +42,27-05-2011,503295.29,0,78.62,3.933,129.0623548,8.494 +42,03-06-2011,545109.3,0,81.87,3.893,129.0490323,8.494 +42,10-06-2011,616701.99,0,84.57,3.981,129.0357097,8.494 +42,17-06-2011,546675.65,0,87.96,3.935,129.0432,8.494 +42,24-06-2011,501780.66,0,90.69,3.807,129.0663,8.494 +42,01-07-2011,506343.83,0,95.36,3.842,129.0894,8.257 +42,08-07-2011,593234.27,0,88.57,3.793,129.1125,8.257 +42,15-07-2011,591703.82,0,86.01,3.779,129.1338387,8.257 +42,22-07-2011,511316.29,0,88.59,3.697,129.1507742,8.257 +42,29-07-2011,479256.8,0,86.75,3.694,129.1677097,8.257 +42,05-08-2011,572603.33,0,89.8,3.803,129.1846452,8.257 +42,12-08-2011,603147.26,0,85.61,3.794,129.2015806,8.257 +42,19-08-2011,526641.23,0,87.4,3.743,129.2405806,8.257 +42,26-08-2011,503720.98,0,91.59,3.663,129.2832581,8.257 +42,02-09-2011,537124.76,0,91.61,3.798,129.3259355,8.257 +42,09-09-2011,608390.94,1,89.06,3.771,129.3686129,8.257 +42,16-09-2011,576837.09,0,77.49,3.784,129.4306,8.257 +42,23-09-2011,528486.45,0,82.51,3.789,129.5183333,8.257 +42,30-09-2011,510243.79,0,82.27,3.877,129.6060667,8.257 +42,07-10-2011,649111.23,0,75.01,3.827,129.6938,7.874 +42,14-10-2011,613531.11,0,70.27,3.698,129.7706452,7.874 +42,21-10-2011,537276.41,0,77.91,3.842,129.7821613,7.874 +42,28-10-2011,515599.7,0,72.79,3.843,129.7936774,7.874 +42,04-11-2011,597667.21,0,68.57,3.828,129.8051935,7.874 +42,11-11-2011,643125.29,0,55.28,3.677,129.8167097,7.874 +42,18-11-2011,567673.87,0,58.97,3.669,129.8268333,7.874 +42,25-11-2011,577698.37,1,60.68,3.76,129.8364,7.874 +42,02-12-2011,511883.36,0,57.29,3.701,129.8459667,7.874 +42,09-12-2011,619133.48,0,42.58,3.644,129.8555333,7.874 +42,16-12-2011,598437.98,0,50.53,3.489,129.8980645,7.874 +42,23-12-2011,575676.13,0,48.36,3.541,129.9845484,7.874 +42,30-12-2011,454412.28,1,48.92,3.428,130.0710323,7.874 +42,06-01-2012,636372.37,0,59.85,3.443,130.1575161,7.545 +42,13-01-2012,664348.2,0,51,3.477,130.244,7.545 +42,20-01-2012,579499.93,0,54.51,3.66,130.2792258,7.545 +42,27-01-2012,538978.67,0,53.59,3.675,130.3144516,7.545 +42,03-02-2012,588448.21,0,56.85,3.543,130.3496774,7.545 +42,10-02-2012,674919.45,1,55.73,3.722,130.3849032,7.545 +42,17-02-2012,606671.5,0,54.12,3.781,130.4546207,7.545 +42,24-02-2012,564304.15,0,56.02,3.95,130.5502069,7.545 +42,02-03-2012,585895.34,0,57.62,3.882,130.6457931,7.545 +42,09-03-2012,659816.15,0,57.65,3.963,130.7413793,7.545 +42,16-03-2012,618767.26,0,62.11,4.273,130.8261935,7.545 +42,23-03-2012,561226.38,0,56.54,4.288,130.8966452,7.545 +42,30-03-2012,544408.14,0,67.92,4.294,130.9670968,7.545 +42,06-04-2012,652312.11,0,65.99,4.282,131.0375484,7.382 +42,13-04-2012,639123.45,0,70.28,4.254,131.108,7.382 +42,20-04-2012,552529.23,0,67.75,4.111,131.1173333,7.382 +42,27-04-2012,526625.49,0,80.11,4.088,131.1266667,7.382 +42,04-05-2012,609274.89,0,77.02,4.058,131.136,7.382 +42,11-05-2012,643603.69,0,76.03,4.186,131.1453333,7.382 +42,18-05-2012,590636.38,0,85.19,4.308,131.0983226,7.382 +42,25-05-2012,535764.58,0,86.03,4.127,131.0287742,7.382 +42,01-06-2012,521953.78,0,80.06,4.277,130.9592258,7.382 +42,08-06-2012,642671.48,0,86.87,4.103,130.8896774,7.382 +42,15-06-2012,606309.13,0,88.58,4.144,130.8295333,7.382 +42,22-06-2012,540031.29,0,89.92,4.014,130.7929,7.382 +42,29-06-2012,507403.77,0,91.36,3.875,130.7562667,7.382 +42,06-07-2012,618702.09,0,86.87,3.666,130.7196333,7.17 +42,13-07-2012,628099.08,0,89.8,3.723,130.683,7.17 +42,20-07-2012,530318.39,0,84.45,3.589,130.7012903,7.17 +42,27-07-2012,516352.21,0,83.98,3.769,130.7195806,7.17 +42,03-08-2012,573084.71,0,84.76,3.595,130.737871,7.17 +42,10-08-2012,576620.31,0,90.78,3.811,130.7561613,7.17 +42,17-08-2012,575997.78,0,88.83,4.002,130.7909677,7.17 +42,24-08-2012,535537.03,0,82.5,4.055,130.8381613,7.17 +42,31-08-2012,504760.57,0,86.97,3.886,130.8853548,7.17 +42,07-09-2012,617405.35,1,83.07,4.124,130.9325484,7.17 +42,14-09-2012,586737.66,0,78.47,3.966,130.9776667,7.17 +42,21-09-2012,527165.7,0,81.93,4.125,131.0103333,7.17 +42,28-09-2012,505978.46,0,82.52,3.966,131.043,7.17 +42,05-10-2012,593162.53,0,80.88,4.132,131.0756667,6.943 +42,12-10-2012,612379.9,0,76.03,4.468,131.1083333,6.943 +42,19-10-2012,541406.98,0,72.71,4.449,131.1499677,6.943 +42,26-10-2012,514756.08,0,70.5,4.301,131.1930968,6.943 +43,05-02-2010,647029.28,0,47.31,2.572,203.0642742,9.521 +43,12-02-2010,682918.99,1,47.99,2.548,203.2010968,9.521 +43,19-02-2010,658997.55,0,48.77,2.514,203.2479796,9.521 +43,26-02-2010,618702.79,0,48.77,2.561,203.2798724,9.521 +43,05-03-2010,658600.05,0,52.89,2.625,203.3117653,9.521 +43,12-03-2010,645386.94,0,53.67,2.667,203.3436582,9.521 +43,19-03-2010,668098.49,0,56,2.72,203.195159,9.521 +43,26-03-2010,623097.93,0,54.53,2.732,203.0165945,9.521 +43,02-04-2010,650102.8,0,62.19,2.719,202.83803,9.593 +43,09-04-2010,693058.34,0,64.37,2.77,202.6594654,9.593 +43,16-04-2010,675282.2,0,69.46,2.808,202.5351571,9.593 +43,23-04-2010,638957.35,0,62.71,2.795,202.4831905,9.593 +43,30-04-2010,630740.11,0,66.91,2.78,202.4312238,9.593 +43,07-05-2010,691498.6,0,67.16,2.835,202.3792571,9.593 +43,14-05-2010,690851.59,0,72.14,2.854,202.3705092,9.593 +43,21-05-2010,672062.08,0,74.74,2.826,202.6210737,9.593 +43,28-05-2010,630315.76,0,78.59,2.759,202.8716382,9.593 +43,04-06-2010,682012.53,0,82.76,2.705,203.1222028,9.593 +43,11-06-2010,684023.95,0,88.12,2.668,203.3727673,9.593 +43,18-06-2010,700009.77,0,84.9,2.637,203.370619,9.593 +43,25-06-2010,625196.14,0,88.48,2.653,203.2673857,9.593 +43,02-07-2010,667353.79,0,80.17,2.669,203.1641524,9.816 +43,09-07-2010,718748.33,0,81.52,2.642,203.060919,9.816 +43,16-07-2010,696844.36,0,84.17,2.623,203.0538548,9.816 +43,23-07-2010,649035.55,0,86.6,2.608,203.1750161,9.816 +43,30-07-2010,622112.23,0,79.79,2.64,203.2961774,9.816 +43,06-08-2010,698536.06,0,84.66,2.627,203.4173387,9.816 +43,13-08-2010,713479.91,0,86.31,2.692,203.5385,9.816 +43,20-08-2010,712869.09,0,85.26,2.664,203.5092419,9.816 +43,27-08-2010,655284.69,0,80.32,2.619,203.4799839,9.816 +43,03-09-2010,689326.91,0,80.43,2.577,203.4507258,9.816 +43,10-09-2010,722120.04,1,81.32,2.565,203.4214677,9.816 +43,17-09-2010,725043.04,0,78.86,2.582,203.4499286,9.816 +43,24-09-2010,650263.95,0,77.42,2.624,203.5216786,9.816 +43,01-10-2010,657108.77,0,77.93,2.603,203.5934286,10.21 +43,08-10-2010,713332.54,0,72.81,2.633,203.6651786,10.21 +43,15-10-2010,699852.68,0,68.78,2.72,203.7299032,10.21 +43,22-10-2010,680943.03,0,69.46,2.725,203.7770645,10.21 +43,29-10-2010,610076.32,0,65.88,2.716,203.8242258,10.21 +43,05-11-2010,605960.2,0,62.52,2.689,203.8713871,10.21 +43,12-11-2010,595421.23,0,59.98,2.728,203.9185484,10.21 +43,19-11-2010,589467.35,0,54.96,2.771,203.8191286,10.21 +43,26-11-2010,633520.34,1,54.76,2.735,203.6952786,10.21 +43,03-12-2010,557543.62,0,44.56,2.708,203.5714286,10.21 +43,10-12-2010,598679.02,0,52.52,2.843,203.4475786,10.21 +43,17-12-2010,615761.77,0,56.51,2.869,203.3996521,10.21 +43,24-12-2010,656637.63,0,57.15,2.886,203.4086682,10.21 +43,31-12-2010,534740.3,1,48.61,2.943,203.4176843,10.21 +43,07-01-2011,611796.61,0,40.47,2.976,203.4267005,10.398 +43,14-01-2011,614940.07,0,43.45,2.983,203.4840645,10.398 +43,21-01-2011,601004.79,0,53.05,3.016,203.8315161,10.398 +43,28-01-2011,562558.27,0,44.98,3.01,204.1789677,10.398 +43,04-02-2011,651521.77,0,33.21,2.989,204.5264194,10.398 +43,11-02-2011,635650.98,1,40.65,3.022,204.873871,10.398 +43,18-02-2011,626627.77,0,59.15,3.045,205.1683214,10.398 +43,25-02-2011,592340.01,0,58.37,3.065,205.4415714,10.398 +43,04-03-2011,616345.25,0,60.26,3.288,205.7148214,10.398 +43,11-03-2011,629026.75,0,60.24,3.459,205.9880714,10.398 +43,18-03-2011,635171.05,0,68.98,3.488,206.225924,10.398 +43,25-03-2011,585989.1,0,65.53,3.473,206.4496175,10.398 +43,01-04-2011,611585.54,0,67.79,3.524,206.6733111,10.581 +43,08-04-2011,650418.75,0,70.35,3.622,206.8970046,10.581 +43,15-04-2011,635758.03,0,65.01,3.743,207.1015429,10.581 +43,22-04-2011,638280.67,0,74.49,3.807,207.2581929,10.581 +43,29-04-2011,611464.21,0,71.34,3.81,207.4148429,10.581 +43,06-05-2011,649148.74,0,66.77,3.906,207.5714929,10.581 +43,13-05-2011,684655.91,0,76.03,3.899,207.7281429,10.581 +43,20-05-2011,648330.18,0,74.21,3.907,207.5200622,10.581 +43,27-05-2011,578209.63,0,80.89,3.786,207.3119816,10.581 +43,03-06-2011,630972.15,0,83.49,3.699,207.1039009,10.581 +43,10-06-2011,643041.71,0,85.81,3.648,206.8958203,10.581 +43,17-06-2011,665781.74,0,88.49,3.637,206.8560238,10.581 +43,24-06-2011,604925.08,0,88.3,3.594,206.9424405,10.581 +43,01-07-2011,586781.78,0,91.36,3.524,207.0288571,10.641 +43,08-07-2011,651147.83,0,87.02,3.48,207.1152738,10.641 +43,15-07-2011,631827.38,0,84.67,3.575,207.1940691,10.641 +43,22-07-2011,597354.39,0,88.58,3.651,207.2538111,10.641 +43,29-07-2011,533917.52,0,83.43,3.682,207.313553,10.641 +43,05-08-2011,605956.59,0,87.47,3.684,207.3732949,10.641 +43,12-08-2011,595626.56,0,86.64,3.638,207.4330369,10.641 +43,19-08-2011,663396.32,0,82.08,3.554,207.4953088,10.641 +43,26-08-2011,561573.08,0,87.43,3.523,207.5580023,10.641 +43,02-09-2011,594224.9,0,87.84,3.533,207.6206959,10.641 +43,09-09-2011,649128.23,1,79.29,3.546,207.6833894,10.641 +43,16-09-2011,618877.13,0,77.17,3.526,207.8527143,10.641 +43,23-09-2011,586108.13,0,78.98,3.467,208.1642143,10.641 +43,30-09-2011,555183.72,0,78.97,3.355,208.4757143,10.641 +43,07-10-2011,642828.62,0,74.17,3.285,208.7872143,10.148 +43,14-10-2011,590984.56,0,68.09,3.274,209.0752166,10.148 +43,21-10-2011,594625.96,0,70.3,3.353,209.2222327,10.148 +43,28-10-2011,572516.57,0,66.82,3.372,209.3692488,10.148 +43,04-11-2011,641905.37,0,59.08,3.332,209.516265,10.148 +43,11-11-2011,615975.5,0,51.26,3.297,209.6632811,10.148 +43,18-11-2011,628115.61,0,57.75,3.308,209.8651071,10.148 +43,25-11-2011,669965.22,1,55.7,3.236,210.0888571,10.148 +43,02-12-2011,585028.26,0,47.49,3.172,210.3126071,10.148 +43,09-12-2011,617898.07,0,34.23,3.158,210.5363571,10.148 +43,16-12-2011,665007.08,0,43.78,3.159,210.7365392,10.148 +43,23-12-2011,676290.46,0,42.63,3.112,210.9052972,10.148 +43,30-12-2011,505405.85,1,41.83,3.129,211.0740553,10.148 +43,06-01-2012,670993.01,0,47.59,3.157,211.2428134,9.653 +43,13-01-2012,663529.64,0,43.68,3.261,211.4115714,9.653 +43,20-01-2012,619225.65,0,52.72,3.268,211.4997811,9.653 +43,27-01-2012,587685.38,0,52.1,3.29,211.5879908,9.653 +43,03-02-2012,629176.71,0,51.92,3.36,211.6762005,9.653 +43,10-02-2012,662198.65,1,46.54,3.409,211.7644101,9.653 +43,17-02-2012,660632.05,0,49.38,3.51,211.916835,9.653 +43,24-02-2012,613042.97,0,53.53,3.555,212.1174212,9.653 +43,02-03-2012,693249.98,0,56.43,3.63,212.3180074,9.653 +43,09-03-2012,636677.67,0,54.52,3.669,212.5185936,9.653 +43,16-03-2012,661707.02,0,57.88,3.734,212.6651567,9.653 +43,23-03-2012,610940.94,0,56.28,3.787,212.7396889,9.653 +43,30-03-2012,623258.4,0,69.88,3.845,212.8142212,9.653 +43,06-04-2012,658468.27,0,64.7,3.891,212.8887535,9.575 +43,13-04-2012,665687.92,0,70.18,3.891,212.9632857,9.575 +43,20-04-2012,638144.98,0,67.28,3.877,213.0130524,9.575 +43,27-04-2012,593138.59,0,78.27,3.814,213.062819,9.575 +43,04-05-2012,637964.2,0,77.47,3.749,213.1125857,9.575 +43,11-05-2012,640159.04,0,67.59,3.688,213.1623524,9.575 +43,18-05-2012,648541.81,0,72.06,3.63,213.1753618,9.575 +43,25-05-2012,597406.39,0,82.41,3.561,213.1736682,9.575 +43,01-06-2012,605078.62,0,80.89,3.501,213.1719747,9.575 +43,08-06-2012,643032.51,0,85.73,3.452,213.1702811,9.575 +43,15-06-2012,634815.1,0,87.75,3.393,213.1786952,9.575 +43,22-06-2012,613270.79,0,87.51,3.346,213.2123786,9.575 +43,29-06-2012,593128.13,0,89.85,3.286,213.2460619,9.575 +43,06-07-2012,645618.59,0,82.68,3.227,213.2797452,9.285 +43,13-07-2012,627634.04,0,78.82,3.256,213.3134286,9.285 +43,20-07-2012,596554.05,0,83.83,3.311,213.3219124,9.285 +43,27-07-2012,572447.52,0,82.01,3.407,213.3303963,9.285 +43,03-08-2012,614378.94,0,85.06,3.417,213.3388802,9.285 +43,10-08-2012,643558.78,0,86.36,3.494,213.3473641,9.285 +43,17-08-2012,640210.85,0,85.66,3.571,213.4226959,9.285 +43,24-08-2012,598234.64,0,81.65,3.62,213.5481636,9.285 +43,31-08-2012,593141.29,0,81.12,3.638,213.6736313,9.285 +43,07-09-2012,663814.18,1,84.99,3.73,213.7990991,9.285 +43,14-09-2012,625196.94,0,73.03,3.717,213.9332167,9.285 +43,21-09-2012,601990.02,0,75.87,3.721,214.1192333,9.285 +43,28-09-2012,577792.32,0,77.55,3.666,214.30525,9.285 +43,05-10-2012,642614.89,0,74.09,3.617,214.4912667,8.839 +43,12-10-2012,619369.72,0,71.14,3.601,214.6772833,8.839 +43,19-10-2012,623919.23,0,71.25,3.594,214.7212488,8.839 +43,26-10-2012,587603.55,0,69.17,3.506,214.7415392,8.839 +44,05-02-2010,281090.95,0,31.53,2.666,126.4420645,8.119 +44,12-02-2010,286857.13,1,33.16,2.671,126.4962581,8.119 +44,19-02-2010,267956.3,0,35.7,2.654,126.5262857,8.119 +44,26-02-2010,273079.07,0,29.98,2.667,126.5522857,8.119 +44,05-03-2010,284617.27,0,40.65,2.681,126.5782857,8.119 +44,12-03-2010,272190.83,0,37.62,2.733,126.6042857,8.119 +44,19-03-2010,269624.2,0,42.49,2.782,126.6066452,8.119 +44,26-03-2010,276279.49,0,41.48,2.819,126.6050645,8.119 +44,02-04-2010,286197.5,0,42.15,2.842,126.6034839,7.972 +44,09-04-2010,257361.3,0,38.97,2.877,126.6019032,7.972 +44,16-04-2010,280048.74,0,50.39,2.915,126.5621,7.972 +44,23-04-2010,278287.04,0,55.66,2.936,126.4713333,7.972 +44,30-04-2010,272997.65,0,48.33,2.941,126.3805667,7.972 +44,07-05-2010,285379.86,0,44.42,2.948,126.2898,7.972 +44,14-05-2010,286515.92,0,50.15,2.962,126.2085484,7.972 +44,21-05-2010,267065.35,0,57.71,2.95,126.1843871,7.972 +44,28-05-2010,291891.01,0,53.11,2.908,126.1602258,7.972 +44,04-06-2010,282351.82,0,59.85,2.871,126.1360645,7.972 +44,11-06-2010,296818.2,0,65.24,2.841,126.1119032,7.972 +44,18-06-2010,293481.36,0,58.41,2.819,126.114,7.972 +44,25-06-2010,288247.24,0,71.83,2.82,126.1266,7.972 +44,02-07-2010,300628.19,0,78.82,2.814,126.1392,7.804 +44,09-07-2010,280472.78,0,71.33,2.802,126.1518,7.804 +44,16-07-2010,297099.95,0,77.79,2.791,126.1498065,7.804 +44,23-07-2010,292680.16,0,82.27,2.797,126.1283548,7.804 +44,30-07-2010,275020.96,0,78.94,2.797,126.1069032,7.804 +44,06-08-2010,296804.49,0,81.24,2.802,126.0854516,7.804 +44,13-08-2010,291028.09,0,74.93,2.837,126.064,7.804 +44,20-08-2010,284740.5,0,76.34,2.85,126.0766452,7.804 +44,27-08-2010,293155.08,0,75.31,2.854,126.0892903,7.804 +44,03-09-2010,295880.12,0,65.71,2.868,126.1019355,7.804 +44,10-09-2010,283455.13,1,65.74,2.87,126.1145806,7.804 +44,17-09-2010,279364.13,0,66.84,2.875,126.1454667,7.804 +44,24-09-2010,281313.78,0,68.22,2.872,126.1900333,7.804 +44,01-10-2010,300152.45,0,68.74,2.853,126.2346,7.61 +44,08-10-2010,279524.44,0,63.03,2.841,126.2791667,7.61 +44,15-10-2010,268708.43,0,54.12,2.845,126.3266774,7.61 +44,22-10-2010,270110.3,0,56.89,2.849,126.3815484,7.61 +44,29-10-2010,286497.49,0,45.12,2.841,126.4364194,7.61 +44,05-11-2010,270516.84,0,49.96,2.831,126.4912903,7.61 +44,12-11-2010,281909.79,0,42.55,2.831,126.5461613,7.61 +44,19-11-2010,284322.52,0,42,2.842,126.6072,7.61 +44,26-11-2010,307646.5,1,28.22,2.83,126.6692667,7.61 +44,03-12-2010,264214.12,0,25.8,2.812,126.7313333,7.61 +44,10-12-2010,278253.28,0,36.78,2.817,126.7934,7.61 +44,17-12-2010,278646.35,0,35.21,2.842,126.8794839,7.61 +44,24-12-2010,365098.24,0,34.9,2.846,126.9835806,7.61 +44,31-12-2010,241937.11,1,26.79,2.868,127.0876774,7.61 +44,07-01-2011,288320.38,0,16.94,2.891,127.1917742,7.224 +44,14-01-2011,292859.36,0,20.6,2.903,127.3009355,7.224 +44,21-01-2011,276157.8,0,34.8,2.934,127.4404839,7.224 +44,28-01-2011,276011.4,0,31.64,2.96,127.5800323,7.224 +44,04-02-2011,293953.08,0,23.35,2.974,127.7195806,7.224 +44,11-02-2011,307486.73,1,30.83,3.034,127.859129,7.224 +44,18-02-2011,280785.76,0,40.85,3.062,127.99525,7.224 +44,25-02-2011,279427.93,0,33.17,3.12,128.13,7.224 +44,04-03-2011,293984.54,0,34.23,3.23,128.26475,7.224 +44,11-03-2011,284496.14,0,41.28,3.346,128.3995,7.224 +44,18-03-2011,281699.68,0,44.69,3.407,128.5121935,7.224 +44,25-03-2011,285031.81,0,42.38,3.435,128.6160645,7.224 +44,01-04-2011,281514.26,0,42.49,3.487,128.7199355,6.906 +44,08-04-2011,292498.61,0,42.75,3.547,128.8238065,6.906 +44,15-04-2011,289667.55,0,41.72,3.616,128.9107333,6.906 +44,22-04-2011,280357.3,0,47.55,3.655,128.9553,6.906 +44,29-04-2011,281247.97,0,43.85,3.683,128.9998667,6.906 +44,06-05-2011,299354.67,0,47.75,3.744,129.0444333,6.906 +44,13-05-2011,307095.31,0,52.4,3.77,129.089,6.906 +44,20-05-2011,303559.23,0,52.12,3.802,129.0756774,6.906 +44,27-05-2011,308442.49,0,54.62,3.778,129.0623548,6.906 +44,03-06-2011,308950.04,0,52.76,3.752,129.0490323,6.906 +44,10-06-2011,308770.42,0,61.39,3.732,129.0357097,6.906 +44,17-06-2011,300255.87,0,63.35,3.704,129.0432,6.906 +44,24-06-2011,296765.59,0,66.38,3.668,129.0663,6.906 +44,01-07-2011,315273.08,0,74.29,3.613,129.0894,6.56 +44,08-07-2011,295339.01,0,77.3,3.563,129.1125,6.56 +44,15-07-2011,289201.21,0,75.59,3.553,129.1338387,6.56 +44,22-07-2011,303108.81,0,78.5,3.563,129.1507742,6.56 +44,29-07-2011,279677,0,77.62,3.574,129.1677097,6.56 +44,05-08-2011,298080.45,0,75.56,3.595,129.1846452,6.56 +44,12-08-2011,290399.66,0,75.95,3.606,129.2015806,6.56 +44,19-08-2011,290909.69,0,76.68,3.578,129.2405806,6.56 +44,26-08-2011,324174.79,0,81.53,3.57,129.2832581,6.56 +44,02-09-2011,309543.52,0,77,3.58,129.3259355,6.56 +44,09-09-2011,295811.25,1,70.19,3.619,129.3686129,6.56 +44,16-09-2011,303974.28,0,67.54,3.641,129.4306,6.56 +44,23-09-2011,307409.13,0,63.6,3.648,129.5183333,6.56 +44,30-09-2011,299757.75,0,68.28,3.623,129.6060667,6.56 +44,07-10-2011,312577.36,0,60.62,3.592,129.6938,6.078 +44,14-10-2011,293031.78,0,51.74,3.567,129.7706452,6.078 +44,21-10-2011,305969.81,0,54.66,3.579,129.7821613,6.078 +44,28-10-2011,306336.07,0,47.41,3.567,129.7936774,6.078 +44,04-11-2011,307126.34,0,43.51,3.538,129.8051935,6.078 +44,11-11-2011,312233.56,0,33.8,3.513,129.8167097,6.078 +44,18-11-2011,310531.04,0,40.65,3.489,129.8268333,6.078 +44,25-11-2011,309129.01,1,38.89,3.445,129.8364,6.078 +44,02-12-2011,284309.34,0,33.94,3.389,129.8459667,6.078 +44,09-12-2011,304300.91,0,24.82,3.341,129.8555333,6.078 +44,16-12-2011,311144.16,0,27.85,3.282,129.8980645,6.078 +44,23-12-2011,376233.89,0,24.76,3.186,129.9845484,6.078 +44,30-12-2011,263917.85,1,31.53,3.119,130.0710323,6.078 +44,06-01-2012,325327.93,0,33.8,3.08,130.1575161,5.774 +44,13-01-2012,312361.88,0,25.61,3.056,130.244,5.774 +44,20-01-2012,316948.39,0,32.71,3.047,130.2792258,5.774 +44,27-01-2012,308295.38,0,34.32,3.058,130.3144516,5.774 +44,03-02-2012,325986.05,0,31.39,3.077,130.3496774,5.774 +44,10-02-2012,325377.97,1,33.73,3.116,130.3849032,5.774 +44,17-02-2012,320691.21,0,36.57,3.119,130.4546207,5.774 +44,24-02-2012,315641.8,0,35.38,3.145,130.5502069,5.774 +44,02-03-2012,316687.22,0,32.36,3.242,130.6457931,5.774 +44,09-03-2012,303438.24,0,38.24,3.38,130.7413793,5.774 +44,16-03-2012,331965.95,0,52.5,3.529,130.8261935,5.774 +44,23-03-2012,296947.06,0,47.83,3.671,130.8966452,5.774 +44,30-03-2012,310027.29,0,53.2,3.734,130.9670968,5.774 +44,06-04-2012,320021.1,0,48.85,3.793,131.0375484,5.621 +44,13-04-2012,311390.22,0,51.7,3.833,131.108,5.621 +44,20-04-2012,323233.8,0,50.24,3.845,131.1173333,5.621 +44,27-04-2012,330338.36,0,64.8,3.842,131.1266667,5.621 +44,04-05-2012,326053.28,0,54.41,3.831,131.136,5.621 +44,11-05-2012,341381.08,0,56.47,3.809,131.1453333,5.621 +44,18-05-2012,334042.43,0,65.17,3.808,131.0983226,5.621 +44,25-05-2012,343268.29,0,62.39,3.801,131.0287742,5.621 +44,01-06-2012,323410.94,0,61.11,3.788,130.9592258,5.621 +44,08-06-2012,340238.38,0,68.4,3.776,130.8896774,5.621 +44,15-06-2012,338400.82,0,65.97,3.756,130.8295333,5.621 +44,22-06-2012,336241,0,72.89,3.737,130.7929,5.621 +44,29-06-2012,338386.08,0,82,3.681,130.7562667,5.621 +44,06-07-2012,358461.58,0,79.23,3.63,130.7196333,5.407 +44,13-07-2012,336479.49,0,83.68,3.595,130.683,5.407 +44,20-07-2012,337819.16,0,75.69,3.556,130.7012903,5.407 +44,27-07-2012,319855.26,0,80.42,3.537,130.7195806,5.407 +44,03-08-2012,342385.38,0,81.99,3.512,130.737871,5.407 +44,10-08-2012,333594.81,0,81.69,3.509,130.7561613,5.407 +44,17-08-2012,327389.51,0,79.4,3.545,130.7909677,5.407 +44,24-08-2012,337985.74,0,77.37,3.582,130.8381613,5.407 +44,31-08-2012,339490.69,0,79.18,3.624,130.8853548,5.407 +44,07-09-2012,338737.33,1,70.65,3.689,130.9325484,5.407 +44,14-09-2012,347726.67,0,68.55,3.749,130.9776667,5.407 +44,21-09-2012,336017.6,0,67.96,3.821,131.0103333,5.407 +44,28-09-2012,355307.94,0,64.8,3.821,131.043,5.407 +44,05-10-2012,337390.44,0,61.79,3.815,131.0756667,5.217 +44,12-10-2012,337796.13,0,55.1,3.797,131.1083333,5.217 +44,19-10-2012,323766.77,0,52.06,3.781,131.1499677,5.217 +44,26-10-2012,361067.07,0,46.97,3.755,131.1930968,5.217 +45,05-02-2010,890689.51,0,27.31,2.784,181.8711898,8.992 +45,12-02-2010,656988.64,1,27.73,2.773,181.982317,8.992 +45,19-02-2010,841264.04,0,31.27,2.745,182.0347816,8.992 +45,26-02-2010,741891.65,0,34.89,2.754,182.0774691,8.992 +45,05-03-2010,777951.22,0,37.13,2.777,182.1201566,8.992 +45,12-03-2010,765687.42,0,45.8,2.818,182.1628441,8.992 +45,19-03-2010,773819.49,0,48.79,2.844,182.0779857,8.992 +45,26-03-2010,782563.38,0,54.36,2.854,181.9718697,8.992 +45,02-04-2010,877235.96,0,47.74,2.85,181.8657537,8.899 +45,09-04-2010,833782.7,0,65.45,2.869,181.7596377,8.899 +45,16-04-2010,782221.96,0,54.28,2.899,181.6924769,8.899 +45,23-04-2010,749779.1,0,53.47,2.902,181.6772564,8.899 +45,30-04-2010,737265.57,0,53.15,2.921,181.6620359,8.899 +45,07-05-2010,812190.76,0,70.75,2.966,181.6468154,8.899 +45,14-05-2010,758182.2,0,54.26,2.982,181.6612792,8.899 +45,21-05-2010,747888.25,0,62.62,2.958,181.8538486,8.899 +45,28-05-2010,801098.43,0,69.27,2.899,182.0464181,8.899 +45,04-06-2010,837548.62,0,75.93,2.847,182.2389876,8.899 +45,11-06-2010,794698.77,0,69.71,2.809,182.4315571,8.899 +45,18-06-2010,815130.5,0,72.62,2.78,182.4424199,8.899 +45,25-06-2010,792299.15,0,79.32,2.808,182.3806,8.899 +45,02-07-2010,800147.84,0,76.61,2.815,182.3187801,8.743 +45,09-07-2010,787062,0,82.45,2.793,182.2569603,8.743 +45,16-07-2010,723708.99,0,77.84,2.783,182.2604411,8.743 +45,23-07-2010,714601.11,0,81.46,2.771,182.3509895,8.743 +45,30-07-2010,716859.27,0,79.78,2.781,182.4415378,8.743 +45,06-08-2010,746517.32,0,77.17,2.784,182.5320862,8.743 +45,13-08-2010,722262.21,0,78.44,2.805,182.6226346,8.743 +45,20-08-2010,708568.29,0,76.01,2.779,182.6165205,8.743 +45,27-08-2010,721744.33,0,71.36,2.755,182.6104063,8.743 +45,03-09-2010,790144.7,0,78.37,2.715,182.6042922,8.743 +45,10-09-2010,721460.22,1,70.87,2.699,182.598178,8.743 +45,17-09-2010,716987.58,0,66.55,2.706,182.622509,8.743 +45,24-09-2010,678228.58,0,68.59,2.713,182.6696737,8.743 +45,01-10-2010,690007.76,0,70.58,2.707,182.7168385,8.724 +45,08-10-2010,745782.1,0,56.49,2.764,182.7640032,8.724 +45,15-10-2010,715263.3,0,58.61,2.868,182.8106203,8.724 +45,22-10-2010,730899.37,0,53.15,2.917,182.8558685,8.724 +45,29-10-2010,732859.76,0,61.3,2.921,182.9011166,8.724 +45,05-11-2010,764014.06,0,45.65,2.917,182.9463648,8.724 +45,12-11-2010,765648.93,0,46.14,2.931,182.9916129,8.724 +45,19-11-2010,723987.85,0,50.02,3,182.8989385,8.724 +45,26-11-2010,1182500.16,1,46.15,3.039,182.7832769,8.724 +45,03-12-2010,879244.9,0,40.93,3.046,182.6676154,8.724 +45,10-12-2010,1002364.34,0,30.54,3.109,182.5519538,8.724 +45,17-12-2010,1123282.85,0,30.51,3.14,182.517732,8.724 +45,24-12-2010,1682862.03,0,30.59,3.141,182.54459,8.724 +45,31-12-2010,679156.2,1,29.67,3.179,182.5714479,8.724 +45,07-01-2011,680254.35,0,34.32,3.193,182.5983058,8.549 +45,14-01-2011,654018.95,0,24.78,3.205,182.6585782,8.549 +45,21-01-2011,644285.33,0,30.55,3.229,182.9193368,8.549 +45,28-01-2011,617207.58,0,24.05,3.237,183.1800955,8.549 +45,04-02-2011,759442.33,0,28.73,3.231,183.4408542,8.549 +45,11-02-2011,766456,1,30.3,3.239,183.7016129,8.549 +45,18-02-2011,802253.41,0,40.7,3.245,183.9371353,8.549 +45,25-02-2011,733716.78,0,35.78,3.274,184.1625632,8.549 +45,04-03-2011,761880.36,0,38.65,3.433,184.3879911,8.549 +45,11-03-2011,714014.73,0,45.01,3.582,184.613419,8.549 +45,18-03-2011,733564.77,0,46.66,3.631,184.809719,8.549 +45,25-03-2011,719737.25,0,41.76,3.625,184.9943679,8.549 +45,01-04-2011,712425.76,0,37.27,3.638,185.1790167,8.521 +45,08-04-2011,750182.71,0,48.71,3.72,185.3636656,8.521 +45,15-04-2011,765270.02,0,53.69,3.821,185.5339821,8.521 +45,22-04-2011,813630.44,0,53.04,3.892,185.6684673,8.521 +45,29-04-2011,786561.61,0,66.18,3.962,185.8029526,8.521 +45,06-05-2011,810150.64,0,58.21,4.046,185.9374378,8.521 +45,13-05-2011,793889.1,0,60.38,4.066,186.0719231,8.521 +45,20-05-2011,727163.67,0,62.28,4.062,185.9661154,8.521 +45,27-05-2011,817653.25,0,69.7,3.985,185.8603077,8.521 +45,03-06-2011,877423.45,0,76.38,3.922,185.7545,8.521 +45,10-06-2011,814395.17,0,73.88,3.881,185.6486923,8.521 +45,17-06-2011,811153.67,0,69.32,3.842,185.6719333,8.521 +45,24-06-2011,762861.78,0,74.85,3.804,185.7919609,8.521 +45,01-07-2011,791495.25,0,74.04,3.748,185.9119885,8.625 +45,08-07-2011,768718.11,0,77.49,3.711,186.032016,8.625 +45,15-07-2011,748435.2,0,78.47,3.76,186.1399808,8.625 +45,22-07-2011,741625.25,0,82.33,3.811,186.2177885,8.625 +45,29-07-2011,704680.97,0,81.31,3.829,186.2955962,8.625 +45,05-08-2011,765996.92,0,78.22,3.842,186.3734038,8.625 +45,12-08-2011,724180.89,0,77,3.812,186.4512115,8.625 +45,19-08-2011,712362.72,0,72.98,3.747,186.5093071,8.625 +45,26-08-2011,833979.01,0,72.55,3.704,186.5641172,8.625 +45,02-09-2011,726482.39,0,70.63,3.703,186.6189274,8.625 +45,09-09-2011,746129.56,1,71.48,3.738,186.6737376,8.625 +45,16-09-2011,711367.56,0,69.17,3.742,186.8024,8.625 +45,23-09-2011,714106.42,0,63.75,3.711,187.0295321,8.625 +45,30-09-2011,698986.34,0,70.66,3.645,187.2566641,8.625 +45,07-10-2011,753447.05,0,55.82,3.583,187.4837962,8.523 +45,14-10-2011,720946.99,0,63.82,3.541,187.6917481,8.523 +45,21-10-2011,771686.4,0,59.6,3.57,187.7846197,8.523 +45,28-10-2011,781694.57,0,51.78,3.569,187.8774913,8.523 +45,04-11-2011,833429.22,0,43.92,3.551,187.9703629,8.523 +45,11-11-2011,808624.82,0,47.65,3.53,188.0632345,8.523 +45,18-11-2011,773603.77,0,51.34,3.53,188.1983654,8.523 +45,25-11-2011,1170672.94,1,48.71,3.492,188.3504,8.523 +45,02-12-2011,875699.81,0,50.19,3.452,188.5024346,8.523 +45,09-12-2011,957155.31,0,46.57,3.415,188.6544692,8.523 +45,16-12-2011,1078905.68,0,39.93,3.413,188.7979349,8.523 +45,23-12-2011,1521957.99,0,42.27,3.389,188.9299752,8.523 +45,30-12-2011,869403.63,1,37.79,3.389,189.0620155,8.523 +45,06-01-2012,714081.05,0,35.88,3.422,189.1940558,8.424 +45,13-01-2012,676615.53,0,41.18,3.513,189.3260962,8.424 +45,20-01-2012,700392.21,0,31.85,3.533,189.4214733,8.424 +45,27-01-2012,624081.64,0,37.93,3.567,189.5168505,8.424 +45,03-02-2012,757330.95,0,42.96,3.617,189.6122277,8.424 +45,10-02-2012,803657.12,1,37,3.64,189.7076048,8.424 +45,17-02-2012,858853.75,0,36.85,3.695,189.8424834,8.424 +45,24-02-2012,753060.78,0,42.86,3.739,190.0069881,8.424 +45,02-03-2012,782796.01,0,41.55,3.816,190.1714927,8.424 +45,09-03-2012,776968.87,0,45.52,3.848,190.3359973,8.424 +45,16-03-2012,788340.23,0,50.56,3.862,190.4618964,8.424 +45,23-03-2012,791835.37,0,59.45,3.9,190.5363213,8.424 +45,30-03-2012,777254.06,0,50.04,3.953,190.6107463,8.424 +45,06-04-2012,899479.43,0,49.73,3.996,190.6851712,8.567 +45,13-04-2012,781970.6,0,51.83,4.044,190.7595962,8.567 +45,20-04-2012,776661.74,0,63.13,4.027,190.8138013,8.567 +45,27-04-2012,711571.88,0,53.2,4.004,190.8680064,8.567 +45,04-05-2012,782300.68,0,55.21,3.951,190.9222115,8.567 +45,11-05-2012,770487.37,0,61.24,3.889,190.9764167,8.567 +45,18-05-2012,800842.28,0,66.3,3.848,190.9964479,8.567 +45,25-05-2012,817741.17,0,67.21,3.798,191.0028096,8.567 +45,01-06-2012,837144.63,0,74.48,3.742,191.0091712,8.567 +45,08-06-2012,795133,0,64.3,3.689,191.0155329,8.567 +45,15-06-2012,821498.18,0,71.93,3.62,191.0299731,8.567 +45,22-06-2012,822569.16,0,74.22,3.564,191.0646096,8.567 +45,29-06-2012,773367.71,0,75.22,3.506,191.0992462,8.567 +45,06-07-2012,843361.1,0,82.99,3.475,191.1338827,8.684 +45,13-07-2012,749817.08,0,79.97,3.523,191.1685192,8.684 +45,20-07-2012,737613.65,0,78.89,3.567,191.1670428,8.684 +45,27-07-2012,711671.58,0,77.2,3.647,191.1655664,8.684 +45,03-08-2012,725729.51,0,76.58,3.654,191.16409,8.684 +45,10-08-2012,733037.32,0,78.65,3.722,191.1626135,8.684 +45,17-08-2012,722496.93,0,75.71,3.807,191.2284919,8.684 +45,24-08-2012,718232.26,0,72.62,3.834,191.3448865,8.684 +45,31-08-2012,734297.87,0,75.09,3.867,191.461281,8.684 +45,07-09-2012,766512.66,1,75.7,3.911,191.5776756,8.684 +45,14-09-2012,702238.27,0,67.87,3.948,191.69985,8.684 +45,21-09-2012,723086.2,0,65.32,4.038,191.8567038,8.684 +45,28-09-2012,713173.95,0,64.88,3.997,192.0135577,8.684 +45,05-10-2012,733455.07,0,64.89,3.985,192.1704115,8.667 +45,12-10-2012,734464.36,0,54.47,4,192.3272654,8.667 +45,19-10-2012,718125.53,0,56.47,3.969,192.3308542,8.667 +45,26-10-2012,760281.43,0,58.85,3.882,192.3088989,8.667 \ No newline at end of file diff --git a/packages/dbgpt-app/src/dbgpt_app/python_uploads/001/template.csv b/packages/dbgpt-app/src/dbgpt_app/python_uploads/001/template.csv new file mode 100644 index 000000000..e869bce28 --- /dev/null +++ b/packages/dbgpt-app/src/dbgpt_app/python_uploads/001/template.csv @@ -0,0 +1,7 @@ +q,a,indexes +"Who are you?","I am an AI assistant, here to help with your questions and provide support. I can assist with learning, daily life queries, and creative ideas.","1. What are you? +2. What can you do? +3. What topics can you help with? +4. How do you assist users? +5. What's your goal?","Who are you? I am an AI assistant..." +"What are you?","I am an AI assistant designed to help users with their questions and provide support across various topics.","What are you?","I am an AI assistant..." \ No newline at end of file diff --git a/packages/dbgpt-core/src/dbgpt/agent/claude_skill/__init__.py b/packages/dbgpt-core/src/dbgpt/agent/claude_skill/__init__.py new file mode 100644 index 000000000..4de4a0e5e --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/claude_skill/__init__.py @@ -0,0 +1,467 @@ +"""Claude-style SKILL mechanism for DB-GPT agents. + +This module implements a simple SKILL system similar to Claude's SKILL mechanism, +where skills are defined in Markdown files with metadata and instructions. +""" + +import os +import re +import dataclasses +from pathlib import Path +from typing import Any, Dict, List, Optional, Set +from abc import ABC, abstractmethod + +from dbgpt.core import PromptTemplate + + +@dataclasses.dataclass +class SkillMetadata: + """Metadata for a Claude-style SKILL file.""" + + name: str + description: str + file_path: Optional[str] = None + triggers: Set[str] = dataclasses.field(default_factory=set) + # Optional fields supported in SKILL.md frontmatter + version: Optional[str] = None + author: Optional[str] = None + skill_type: Optional[str] = None + tags: List[str] = dataclasses.field(default_factory=list) + required_tools: List[str] = dataclasses.field(default_factory=list) + required_knowledge: List[str] = dataclasses.field(default_factory=list) + config: Dict[str, Any] = dataclasses.field(default_factory=dict) + + def __str__(self) -> str: + return f"{self.name}: {self.description}" + + +class ClaudeSkill(ABC): + """Base class for Claude-style SKILL.""" + + @classmethod + @abstractmethod + def name(cls) -> str: + """Return the skill name.""" + pass + + @classmethod + @abstractmethod + def description(cls) -> str: + """Return the skill description.""" + pass + + @classmethod + @abstractmethod + def instructions(cls) -> str: + """Return the skill instructions.""" + pass + + @classmethod + def matches(cls, user_input: str) -> bool: + """Check if the user input matches this skill. + + Can be overridden for custom matching logic. + + Args: + user_input: The user's input string. + + Returns: + True if the skill should be activated. + """ + return False + + @classmethod + def get_prompt(cls) -> PromptTemplate: + """Get the prompt template for this skill. + + Returns: + PromptTemplate with the skill instructions. + """ + instructions = cls.instructions() + prompt = f"""{instructions}""" + return PromptTemplate.from_template(prompt) + + +class FileBasedSkill: + """Skill loaded from a SKILL.md file. + + This implements Claude's SKILL.md file format: + + --- + name: skill-name + description: Skill description + --- + + Instructions here... + + Examples triggers are in the description. + """ + + def __init__(self, file_path: str): + """Initialize from a SKILL.md file. + + Args: + file_path: Path to the SKILL.md file. + """ + self.file_path = file_path + self._metadata, self._instructions = self._parse_file(file_path) + + def _parse_file(self, file_path: str) -> tuple[SkillMetadata, str]: + """Parse a SKILL.md file. + + Args: + file_path: Path to the file. + + Returns: + Tuple of (metadata, instructions). + """ + with open(file_path, "r", encoding="utf-8") as f: + content = f.read() + + content = content.strip() + + if not content.startswith("---"): + raise ValueError(f"SKILL file must start with '---': {file_path}") + + parts = content.split("---", 2) + + if len(parts) < 3: + raise ValueError( + f"Invalid SKILL file format. Expected '---metadata---instructions': {file_path}" + ) + + metadata_text = parts[1].strip() + instructions = parts[2].strip() + + metadata = self._parse_metadata(metadata_text, file_path) + + return metadata, instructions + + def _parse_metadata(self, text: str, file_path: str) -> SkillMetadata: + """Parse metadata section. + + Args: + text: Metadata text. + file_path: File path for error messages. + + Returns: + SkillMetadata instance. + """ + # Prefer parsing the frontmatter with PyYAML for robust typing support. + try: + import yaml + + parsed = yaml.safe_load(text) + if not isinstance(parsed, dict): + raise ValueError("SKILL frontmatter is not a mapping") + + if "name" not in parsed: + raise ValueError(f"SKILL file missing 'name': {file_path}") + if "description" not in parsed: + raise ValueError(f"SKILL file missing 'description': {file_path}") + + name = parsed.get("name") + description = parsed.get("description") + version = parsed.get("version") + author = parsed.get("author") + skill_type = parsed.get("skill_type") + + def to_list(val): + if val is None: + return [] + if isinstance(val, list): + return val + if isinstance(val, str): + return [t.strip() for t in val.split(",") if t.strip()] + return [val] + + tags = to_list(parsed.get("tags")) + required_tools = to_list(parsed.get("required_tools")) + required_knowledge = to_list(parsed.get("required_knowledge")) + config = parsed.get("config") or {} + + metadata = SkillMetadata( + name=name or "", + description=description or "", + file_path=file_path, + version=version, + author=author, + skill_type=skill_type, + tags=tags, + required_tools=required_tools, + required_knowledge=required_knowledge, + config=config, + ) + return metadata + except ImportError: + # PyYAML not installed; fallback to line-based parsing + metadata_dict = {} + + for line in text.split("\n"): + line = line.strip() + if not line or ":" not in line: + continue + + key, value = line.split(":", 1) + key = key.strip().lower() + value = value.strip() + + metadata_dict[key] = value + + if "name" not in metadata_dict: + raise ValueError(f"SKILL file missing 'name': {file_path}") + if "description" not in metadata_dict: + raise ValueError(f"SKILL file missing 'description': {file_path}") + + name = metadata_dict["name"] + description = metadata_dict["description"] + + version = metadata_dict.get("version") + author = metadata_dict.get("author") + skill_type = metadata_dict.get("skill_type") + tags = [ + t.strip() for t in metadata_dict.get("tags", "").split(",") if t.strip() + ] + required_tools = [ + t.strip() + for t in metadata_dict.get("required_tools", "").split(",") + if t.strip() + ] + required_knowledge = [ + t.strip() + for t in metadata_dict.get("required_knowledge", "").split(",") + if t.strip() + ] + + metadata = SkillMetadata( + name=name or "", + description=description or "", + file_path=file_path, + version=version, + author=author, + skill_type=skill_type, + tags=tags, + required_tools=required_tools, + required_knowledge=required_knowledge, + ) + + return metadata + + @property + def metadata(self) -> SkillMetadata: + """Return the skill metadata.""" + return self._metadata + + @property + def instructions(self) -> str: + """Return the skill instructions.""" + return self._instructions + + def matches(self, user_input: str) -> bool: + """Check if user input matches this skill. + + Simple matching based on description containing trigger phrases. + + Args: + user_input: User input string. + + Returns: + True if should activate this skill. + """ + user_input_lower = user_input.lower() + description_lower = self.metadata.description.lower() + + keywords = self._extract_keywords(description_lower) + + for keyword in keywords: + if keyword in user_input_lower: + return True + + name_lower = self.metadata.name.lower() + tags_lower = [tag.lower() for tag in (self.metadata.tags or [])] + if ( + "excel" in name_lower + or "excel" in description_lower + or "excel" in tags_lower + ): + return any( + kw in user_input_lower + for kw in [ + "excel", + "xlsx", + "xls", + "spreadsheet", + "sheet", + "workbook", + "表格", + "工作表", + "电子表格", + ] + ) + + return False + + def _extract_keywords(self, description: str) -> List[str]: + """Extract potential trigger keywords from description. + + Args: + description: Skill description. + + Returns: + List of keywords. + """ + keywords = [] + + pattern = r"(?:when|use|for|to)\s+(?:the\s+)?(?:user\s+)?(?:asks|requests|wants|needs)?\s*(?:to\s+)?([a-z\s]+?)(?:\s*(?:\.|,|;|or|\(|\)|use when|$))" + matches = re.findall(pattern, description, re.IGNORECASE) + + for match in matches: + words = [w.strip() for w in match.split() if len(w.strip()) > 2] + keywords.extend(words) + + keywords.append(self.metadata.name.lower()) + + return list(set(keywords)) + + def get_prompt(self) -> PromptTemplate: + """Get the prompt template for this skill. + + Returns: + PromptTemplate with the skill instructions. + """ + prompt = f"""{self.instructions}""" + return PromptTemplate.from_template( + prompt, template_format="jinja2", template_is_strict=False + ) + + def __str__(self) -> str: + return str(self.metadata) + + +class SkillRegistry: + """Registry for managing Claude-style skills.""" + + def __init__(self): + """Initialize the skill registry.""" + self._skills: Dict[str, FileBasedSkill] = {} + self._class_skills: Dict[str, type] = {} + + def register_skill(self, skill: FileBasedSkill): + """Register a file-based skill. + + Args: + skill: FileBasedSkill instance. + """ + self._skills[skill.metadata.name] = skill + + def register_skill_class(self, skill_class: type): + """Register a skill class. + + Args: + skill_class: A subclass of ClaudeSkill. + """ + if not issubclass(skill_class, ClaudeSkill): + raise ValueError(f"{skill_class} must be a subclass of ClaudeSkill") + + self._class_skills[skill_class.name()] = skill_class + + def get_skill(self, name: str) -> Optional[FileBasedSkill]: + """Get a skill by name. + + Args: + name: Skill name. + + Returns: + FileBasedSkill or None. + """ + return self._skills.get(name) + + def get_skill_class(self, name: str) -> Optional[type]: + """Get a skill class by name. + + Args: + name: Skill name. + + Returns: + Skill class or None. + """ + return self._class_skills.get(name) + + def list_skills(self) -> List[SkillMetadata]: + """List all registered skills. + + Returns: + List of skill metadata. + """ + return [skill.metadata for skill in self._skills.values()] + + def match_skill(self, user_input: str) -> Optional[FileBasedSkill]: + """Find a matching skill for the user input. + + Args: + user_input: User's input string. + + Returns: + Matching skill or None. + """ + matches = [] + + for skill in self._skills.values(): + if skill.matches(user_input): + matches.append(skill) + + if not matches: + return None + + if len(matches) == 1: + return matches[0] + + matches.sort(key=lambda s: -len(s.instructions)) + return matches[0] + + def load_from_directory(self, directory: str, recursive: bool = True): + """Load all SKILL.md files from a directory. + + Args: + directory: Directory path. + recursive: Whether to search recursively. + """ + dir_path = Path(directory) + + if not dir_path.exists() or not dir_path.is_dir(): + raise ValueError(f"Directory not found: {directory}") + + pattern = "**/SKILL.md" if recursive else "*/SKILL.md" + + for skill_file in dir_path.glob(pattern): + try: + skill = FileBasedSkill(str(skill_file)) + self.register_skill(skill) + except Exception as e: + print(f"Failed to load skill from {skill_file}: {e}") + + +_global_registry: Optional[SkillRegistry] = None + + +def get_registry() -> SkillRegistry: + """Get the global skill registry. + + Returns: + SkillRegistry instance. + """ + global _global_registry + if _global_registry is None: + _global_registry = SkillRegistry() + return _global_registry + + +def load_skills_from_dir(directory: str, recursive: bool = True): + """Load skills from a directory into the global registry. + + Args: + directory: Directory containing SKILL.md files. + recursive: Whether to search recursively. + """ + registry = get_registry() + registry.load_from_directory(directory, recursive) diff --git a/packages/dbgpt-core/src/dbgpt/agent/claude_skill/agent.py b/packages/dbgpt-core/src/dbgpt/agent/claude_skill/agent.py new file mode 100644 index 000000000..b8b8b2afc --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/claude_skill/agent.py @@ -0,0 +1,166 @@ +"""Integration of Claude-style SKILL mechanism with DB-GPT agents. + +This module provides utilities to use Claude-style SKILL files +with DB-GPT's ConversableAgent. +""" + +import asyncio +from typing import Any, Dict, List, Optional + +from dbgpt.agent.core.agent import AgentContext +from dbgpt.agent.core.base_agent import ConversableAgent +from dbgpt.core import PromptTemplate +from . import FileBasedSkill, get_registry, SkillRegistry + + +class ClaudeSkillAgent(ConversableAgent): + """Agent that uses Claude-style SKILL files. + + This agent automatically detects which SKILL to use based on user input + and applies the corresponding instructions to the prompt. + """ + + def __init__(self, skill_registry: Optional[SkillRegistry] = None, **kwargs): + """Initialize a Claude Skill Agent. + + Args: + skill_registry: Skill registry instance (uses global if None). + **kwargs: Additional arguments for ConversableAgent. + """ + super().__init__(**kwargs) + self._skill_registry = skill_registry or get_registry() + self._current_skill: Optional[FileBasedSkill] = None + self._base_prompt: Optional[PromptTemplate] = None + + @property + def skill_registry(self) -> SkillRegistry: + """Return the skill registry.""" + return self._skill_registry + + @property + def current_skill(self) -> Optional[FileBasedSkill]: + """Return the currently active skill.""" + return self._current_skill + + def detect_and_apply_skill(self, user_input: str): + """Detect and apply a matching skill for the user input. + + Args: + user_input: The user's input message. + """ + matching_skill = self._skill_registry.match_skill(user_input) + + if matching_skill: + self._current_skill = matching_skill + self._apply_skill_to_prompt() + else: + self._current_skill = None + + def set_skill(self, skill_name: str): + """Manually set a specific skill. + + Args: + skill_name: Name of the skill to activate. + + Raises: + ValueError: If skill not found. + """ + skill = self._skill_registry.get_skill(skill_name) + if not skill: + raise ValueError(f"Skill not found: {skill_name}") + + self._current_skill = skill + self._apply_skill_to_prompt() + + def clear_skill(self): + """Clear the current skill and revert to base prompt.""" + self._current_skill = None + if self._base_prompt: + self.bind_prompt = self._base_prompt + + def _apply_skill_to_prompt(self): + """Apply the current skill's prompt template.""" + if self._current_skill: + if self.bind_prompt is None: + self._base_prompt = self.bind_prompt + + skill_prompt = self._current_skill.get_prompt() + + if self.bind_prompt: + combined = f"{skill_prompt.template}\n\n{self.bind_prompt.template}" + else: + combined = skill_prompt.template + + self.bind_prompt = PromptTemplate.from_template(combined) + + async def generate_reply( + self, + received_message, + sender, + reviewer=None, + rely_messages=None, + historical_dialogues=None, + is_retry_chat=False, + last_speaker_name=None, + **kwargs, + ): + """Generate a reply with skill detection. + + Args: + received_message: The received message. + sender: Sender agent. + reviewer: Reviewer agent. + rely_messages: List of relied messages. + historical_dialogues: Historical dialogue messages. + is_retry_chat: Whether this is a retry. + last_speaker_name: Name of the last speaker. + **kwargs: Additional arguments. + + Returns: + Generated reply message. + """ + if received_message.content: + self.detect_and_apply_skill(received_message.content) + + return await super().generate_reply( + received_message, + sender, + reviewer, + rely_messages, + historical_dialogues, + is_retry_chat, + last_speaker_name, + **kwargs, + ) + + def get_available_skills(self) -> List[str]: + """Get list of available skill names. + + Returns: + List of skill names. + """ + return [skill.metadata.name for skill in self._skill_registry._skills.values()] + + +async def create_skill_agent( + skill_dir: str, + context: AgentContext, + **kwargs, +) -> ClaudeSkillAgent: + """Create a Claude Skill Agent with skills loaded from a directory. + + Args: + skill_dir: Directory containing SKILL.md files. + context: Agent context. + **kwargs: Additional arguments for ConversableAgent. + + Returns: + Configured ClaudeSkillAgent instance. + """ + registry = get_registry() + registry.load_from_directory(skill_dir, recursive=True) + + agent = ClaudeSkillAgent(skill_registry=registry, **kwargs) + await agent.bind(context).build() + + return agent diff --git a/packages/dbgpt-core/src/dbgpt/agent/expand/actions/tests/__init__.py b/packages/dbgpt-core/src/dbgpt/agent/expand/actions/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/packages/dbgpt-core/src/dbgpt/agent/expand/actions/tests/test_fallback_parse_args.py b/packages/dbgpt-core/src/dbgpt/agent/expand/actions/tests/test_fallback_parse_args.py new file mode 100644 index 000000000..5be7c2c52 --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/expand/actions/tests/test_fallback_parse_args.py @@ -0,0 +1,147 @@ +from dbgpt.agent.resource.tool.base import ToolParameter, tool +from dbgpt.agent.resource.tool.pack import ToolPack + +from ..react_action import ReActAction + + +def _make_resource(*tool_funcs): + tools = [fn._tool for fn in tool_funcs] + return ToolPack(tools) + + +@tool(description="Execute Python code") +def code_interpreter(code: str) -> str: + """Execute Python code.""" + return code + + +@tool(description="Render HTML content as a web report") +def html_interpreter(html: str, title: str = "Report") -> str: + """Render HTML content as a web report.""" + return html + + +class TestSingleParam: + def test_simple_json_like(self): + resource = _make_resource(code_interpreter) + raw = '{"code": "print(1)"}' + result = ReActAction._fallback_parse_args( + "code_interpreter", raw, resource + ) + assert result == {"code": "print(1)"} + + def test_code_with_newlines_and_quotes(self): + resource = _make_resource(code_interpreter) + raw = '{"code": "import pandas as pd\\ndf = pd.read_csv(\\"data.csv\\")\\nprint(df.head())"}' + result = ReActAction._fallback_parse_args( + "code_interpreter", raw, resource + ) + assert "import pandas as pd" in result["code"] + assert 'pd.read_csv("data.csv")' in result["code"] + + def test_raw_string_fallback(self): + resource = _make_resource(code_interpreter) + raw = "print('hello world')" + result = ReActAction._fallback_parse_args( + "code_interpreter", raw, resource + ) + assert result == {"code": "print('hello world')"} + + +class TestMultiParam: + def test_title_first_html_second(self): + resource = _make_resource(html_interpreter) + raw = ( + '{"title": "Walmart销售数据分析报告", ' + '"html": "\\n\\n' + 'Report\\n' + "

Hello

\\n\"}" + ) + result = ReActAction._fallback_parse_args( + "html_interpreter", raw, resource + ) + assert result.get("title") == "Walmart销售数据分析报告" + assert "" in result.get("html", "") + assert "

Hello

" in result.get("html", "") + + def test_html_first_title_second(self): + resource = _make_resource(html_interpreter) + raw = '{"html": "

Report

", "title": "My Report"}' + result = ReActAction._fallback_parse_args( + "html_interpreter", raw, resource + ) + assert result.get("html") == "

Report

" + assert result.get("title") == "My Report" + + def test_html_with_embedded_quotes_and_css(self): + resource = _make_resource(html_interpreter) + html_content = ( + "
" + "Hello
" + ) + raw = '{"title": "Styled Report", "html": "' + html_content + '"}' + result = ReActAction._fallback_parse_args( + "html_interpreter", raw, resource + ) + assert result.get("title") == "Styled Report" + assert "Hello" in result.get("html", "") + + def test_long_html_with_many_quotes(self): + resource = _make_resource(html_interpreter) + html_body = ( + '\\n' + '\\n' + "\\n" + ' \\n' + " \\n" + "\\n" + "\\n" + '
\\n' + "

Sales Report

\\n" + "

Total: $1,234,567

\\n" + "
\\n" + "\\n" + "" + ) + raw = '{"title": "Sales Analysis", "html": "' + html_body + '"}' + result = ReActAction._fallback_parse_args( + "html_interpreter", raw, resource + ) + assert result.get("title") == "Sales Analysis" + html_val = result.get("html", "") + assert "" in html_val + assert "Sales Report" in html_val + assert "" in html_val + + def test_title_omitted_only_html(self): + resource = _make_resource(html_interpreter) + raw = '{"html": "

Simple report

"}' + result = ReActAction._fallback_parse_args( + "html_interpreter", raw, resource + ) + assert "

Simple report

" in result.get("html", "") + + +class TestEdgeCases: + def test_unknown_tool_returns_empty(self): + resource = _make_resource(code_interpreter) + result = ReActAction._fallback_parse_args( + "nonexistent_tool", '{"code": "x"}', resource + ) + assert result == {} + + def test_none_resource_returns_empty(self): + result = ReActAction._fallback_parse_args( + "code_interpreter", '{"code": "x"}', None + ) + assert result == {} + + def test_empty_input_returns_empty(self): + resource = _make_resource(code_interpreter) + result = ReActAction._fallback_parse_args( + "code_interpreter", "", resource + ) + assert result == {} diff --git a/packages/dbgpt-core/src/dbgpt/agent/expand/data_agent.py b/packages/dbgpt-core/src/dbgpt/agent/expand/data_agent.py new file mode 100644 index 000000000..740d40e97 --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/expand/data_agent.py @@ -0,0 +1,396 @@ +import json +import logging +from typing import Any, Dict, List, Optional, Type, Union + +from dbgpt._private.pydantic import Field +from dbgpt.agent import ( + ActionOutput, + Agent, + AgentMemoryFragment, + AgentMessage, + ConversableAgent, + ProfileConfig, + Resource, + ResourceType, + StructuredAgentMemoryFragment, +) +from dbgpt.agent.core.role import AgentRunMode +from dbgpt.agent.resource import BaseTool, ResourcePack, ToolPack +from dbgpt.agent.util.react_parser import ReActOutputParser +from dbgpt.util.configure import DynConfig + +from ...core import ModelMessageRoleType +from .actions.react_action import ReActAction, Terminate + +logger = logging.getLogger(__name__) + +_DATA_AGENT_DEFAULT_GOAL = """You are an intelligent data analysis agent that can autonomously plan and execute data analysis tasks. +Your goal is to understand data analysis requirements, create analysis plans, and execute them systematically. + +# Planning Process # +1. Understand the analysis objective and requirements +2. Examine available data sources and structure +3. Create a step-by-step analysis plan +4. Execute the plan using appropriate tools +5. Generate insights and visualizations +6. Provide comprehensive results and recommendations + +# Action Space Simple Description # +{{ action_space_simple_desc }} +""" + +_DATA_AGENT_SYSTEM_TEMPLATE = """\ +You are a {{ role }}, {% if name %}named {{ name }}. {% endif %}\ +{{ goal }} + +You are an expert data analyst with strong planning and execution capabilities. +For each data analysis task, you should: + +1. **Planning Phase**: + - Understand the business question or analysis objective + - Identify required data and available data sources + - Create a systematic analysis plan with clear steps + - Consider potential challenges and alternative approaches + +2. **Execution Phase**: + - Load and explore the data systematically + - Perform data cleaning and preprocessing as needed + - Apply appropriate analysis techniques (statistical analysis, visualization, etc.) + - Generate meaningful insights and recommendations + +3. **Communication Phase**: + - Present findings clearly with supporting evidence + - Provide visualizations when helpful + - Suggest next steps or further analysis opportunities + +You can only use one action in the actions provided in the ACTION SPACE to solve the \ +task. For each step, you must output an Action; it cannot be empty. The maximum number \ +of steps you can take is {{ max_steps }}. + +# ACTION SPACE # +{{ action_space }} + +# RESPONSE FORMAT # +For each task input, your response should contain: +1. Thought: Your analysis of the task, planning considerations, and reasoning for the next action +2. Action: The selected action from the ACTION SPACE +3. Action Input: Parameters required for the action (can be empty if no input needed) + +# PLANNING EXAMPLE # +Thought: I need to analyze sales data to identify trends and provide insights. First, I should examine the available data sources to understand the data structure and then create a comprehensive analysis plan. +Action: examine_data_sources +Action Input: {} + +# EXECUTION EXAMPLE # +Thought: Now that I understand the data structure, I'll load the sales data and perform initial exploratory analysis to identify patterns and trends. +Action: load_data +Action Input: {"source": "sales_data", "analysis_type": "exploratory"} + +################### TASK ################### +Please solve this data analysis task: + +{{ question }} + +Please answer in the same language as the user's question. +The current time is: {{ now_time }}. +""" + +_DATA_AGENT_WRITE_MEMORY_TEMPLATE = """\ +{% if question %}Question: {{ question }} {% endif %} +{% if thought %}Thought: {{ thought }} {% endif %} +{% if action %}Action: {{ action }} {% endif %} +{% if action_input %}Action Input: {{ action_input }} {% endif %} +{% if observation %}Observation: {{ observation }} {% endif %} +{% if plan %}Analysis Plan: {{ plan }} {% endif %} +""" + + +class DataAnalysisPlanningAgent(ConversableAgent): + """Data Analysis Agent with autonomous planning capabilities.""" + + max_retry_count: int = 20 + run_mode: AgentRunMode = AgentRunMode.LOOP + + # Planning state + analysis_plan: Optional[List[Dict[str, Any]]] = Field(default=None) + current_step: int = Field(default=0) + planning_complete: bool = Field(default=False) + + profile: ProfileConfig = ProfileConfig( + name=DynConfig( + "DataAnalysisPlanningAgent", + category="agent", + key="dbgpt_agent_data_analysis_planning_agent_name", + ), + role=DynConfig( + "SeniorDataAnalyst", + category="agent", + key="dbgpt_agent_data_analysis_planning_agent_role", + ), + goal=DynConfig( + _DATA_AGENT_DEFAULT_GOAL, + category="agent", + key="dbgpt_agent_data_analysis_planning_agent_goal", + ), + system_prompt_template=_DATA_AGENT_SYSTEM_TEMPLATE, + user_prompt_template="", + write_memory_template=_DATA_AGENT_WRITE_MEMORY_TEMPLATE, + ) + parser: ReActOutputParser = Field(default_factory=ReActOutputParser) + + def __init__(self, **kwargs): + """Initialize Data Analysis Planning Agent.""" + super().__init__(**kwargs) + self._init_actions([ReActAction, Terminate]) + self._reset_planning_state() + + def _reset_planning_state(self): + """Reset planning state for new tasks.""" + self.analysis_plan = None + self.current_step = 0 + self.planning_complete = False + + async def _a_init_reply_message( + self, + received_message: AgentMessage, + rely_messages: Optional[List[AgentMessage]] = None, + ) -> AgentMessage: + reply_message = super()._init_reply_message(received_message, rely_messages) + + tool_packs = ToolPack.from_resource(self.resource) + action_space = [] + action_space_names = [] + action_space_simple_desc = [] + + # Add data analysis specific actions + data_analysis_actions = [ + "create_analysis_plan: Create a systematic plan for data analysis", + "examine_data_sources: Explore available data sources and their structure", + "load_data: Load data from specified sources for analysis", + "clean_data: Perform data cleaning and preprocessing", + "explore_data: Conduct exploratory data analysis", + "statistical_analysis: Perform statistical tests and analysis", + "create_visualization: Generate charts and visualizations", + "generate_insights: Extract and present key insights", + "validate_results: Validate analysis results and methodology" + ] + + if tool_packs: + tool_pack = tool_packs[0] + for tool in tool_pack.sub_resources: + tool_desc, _ = await tool.get_prompt(lang=self.language) + action_space_names.append(tool.name) + action_space.append(tool_desc) + if isinstance(tool, BaseTool): + tool_simple_desc = tool.description + else: + tool_simple_desc = tool.get_prompt() + action_space_simple_desc.append(f"{tool.name}: {tool_simple_desc}") + else: + # Include default data analysis actions + for action_desc in data_analysis_actions: + action_name = action_desc.split(":")[0] + action_space_names.append(action_name) + action_space.append(action_desc) + action_space_simple_desc.append(action_desc) + + for action in self.actions: + action_space_names.append(action.name) + action_space.append(action.get_action_description()) + + reply_message.context = { + "max_steps": self.max_retry_count, + "action_space": "\n".join(action_space), + "action_space_names": ", ".join(action_space_names), + "action_space_simple_desc": "\n".join(action_space_simple_desc), + } + return reply_message + + async def preload_resource(self) -> None: + await super().preload_resource() + self._check_and_add_terminate() + + def _check_and_add_terminate(self): + if not self.resource: + return + _is_has_terminal = False + + def _has_terminal(r: Resource): + nonlocal _is_has_terminal + if r.type() == ResourceType.Tool and isinstance(r, Terminate): + _is_has_terminal = True + return r + + _has_add_terminal = False + + def _add_terminate(r: Resource): + nonlocal _has_add_terminal + if not _has_add_terminal and isinstance(r, ResourcePack): + terminal = Terminate() + r._resources[terminal.name] = terminal + _has_add_terminal = True + return r + + self.resource.apply(apply_func=_has_terminal) + if not _is_has_terminal: + self.resource.apply(apply_pack_func=_add_terminate) + + async def load_resource(self, question: str, is_retry_chat: bool = False): + """Load agent bind resource.""" + if self.resource: + + def _remove_tool(r: Resource): + if r.type() == ResourceType.Tool: + return None + return r + + new_resource = self.resource.apply(apply_func=_remove_tool) + if new_resource: + resource_prompt, resource_reference = await new_resource.get_prompt( + lang=self.language, question=question + ) + return resource_prompt, resource_reference + return None, None + + def prepare_act_param( + self, + received_message: Optional[AgentMessage], + sender: Agent, + rely_messages: Optional[List[AgentMessage]] = None, + **kwargs, + ) -> Dict[str, Any]: + """Prepare the parameters for the act method.""" + return { + "parser": self.parser, + } + + async def act( + self, + message: AgentMessage, + sender: Agent, + reviewer: Optional[Agent] = None, + is_retry_chat: bool = False, + last_speaker_name: Optional[str] = None, + **kwargs, + ) -> ActionOutput: + """Perform actions with planning capabilities.""" + message_content = message.content + if not message_content: + raise ValueError("The response is empty.") + + try: + steps = self.parser.parse(message_content) + err_msg = None + if not steps: + err_msg = ( + "No correct response found. Please check your response, which must" + " be in the format indicated in the system prompt." + ) + elif len(steps) != 1: + err_msg = "Only one action is allowed each time." + if err_msg: + return ActionOutput(is_exe_success=False, content=err_msg) + except Exception as e: + logger.warning(f"review error: {e}") + + action_output = await super().act( + message=message, + sender=sender, + reviewer=reviewer, + is_retry_chat=is_retry_chat, + last_speaker_name=last_speaker_name, + **kwargs, + ) + + # Update planning state based on action results + if action_output.is_exe_success: + await self._update_planning_state(action_output) + + return action_output + + async def _update_planning_state(self, action_output: ActionOutput): + """Update planning state based on action output.""" + # This can be extended to track planning progress + if hasattr(action_output, 'action') and action_output.action: + if action_output.action == "create_analysis_plan": + self.planning_complete = True + # Could parse and store the plan here + elif action_output.action in ["load_data", "explore_data", "statistical_analysis"]: + self.current_step += 1 + + @property + def memory_fragment_class(self) -> Type[AgentMemoryFragment]: + """Return the memory fragment class.""" + return StructuredAgentMemoryFragment + + async def read_memories( + self, + observation: str, + ) -> Union[str, List["AgentMessage"]]: + memories = await self.memory.read(observation) + not_json_memories = [] + messages = [] + structured_memories = [] + + for m in memories: + if m.raw_observation: + try: + mem_dict = json.loads(m.raw_observation) + if isinstance(mem_dict, dict): + structured_memories.append(mem_dict) + elif isinstance(mem_dict, list): + structured_memories.extend(mem_dict) + else: + raise ValueError("Invalid memory format.") + except Exception: + not_json_memories.append(m.raw_observation) + + for mem_dict in structured_memories: + question = mem_dict.get("question") + thought = mem_dict.get("thought") + action = mem_dict.get("action") + action_input = mem_dict.get("action_input") + observation = mem_dict.get("observation") + plan = mem_dict.get("plan") + + if question: + messages.append( + AgentMessage( + content=f"Question: {question}", + role=ModelMessageRoleType.HUMAN, + ) + ) + + ai_content = [] + if thought: + ai_content.append(f"Thought: {thought}") + if plan: + ai_content.append(f"Analysis Plan: {plan}") + if action: + ai_content.append(f"Action: {action}") + if action_input: + ai_content.append(f"Action Input: {action_input}") + + messages.append( + AgentMessage( + content="\n".join(ai_content), + role=ModelMessageRoleType.AI, + ) + ) + + if observation: + messages.append( + AgentMessage( + content=f"Observation: {observation}", + role=ModelMessageRoleType.HUMAN, + ) + ) + + if not messages and not_json_memories: + messages.append( + AgentMessage( + content="\n".join(not_json_memories), + role=ModelMessageRoleType.HUMAN, + ) + ) + return messages \ No newline at end of file diff --git a/packages/dbgpt-core/src/dbgpt/agent/expand/data_analysis_agent.py b/packages/dbgpt-core/src/dbgpt/agent/expand/data_analysis_agent.py new file mode 100644 index 000000000..44a0db0cc --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/expand/data_analysis_agent.py @@ -0,0 +1,88 @@ +import json +import logging +from typing import Any, Dict, List, Optional, Type, Union + +from dbgpt._private.pydantic import Field +from dbgpt.agent import ( + ActionOutput, + Agent, + AgentMemoryFragment, + AgentMessage, + ConversableAgent, + ProfileConfig, + StructuredAgentMemoryFragment, +) +from dbgpt.agent.core.role import AgentRunMode +from dbgpt.agent.resource import BaseTool +from dbgpt.util.configure import DynConfig + +logger = logging.getLogger(__name__) + +_DATA_ANALYSIS_DEFAULT_GOAL = """Perform data analysis tasks efficiently by selecting actions intelligently from the ACTION SPACE.""" + +_DATA_ANALYSIS_SYSTEM_TEMPLATE = """ +You are a {{ role }}, {% if name %}named {{ name }}. {% endif %}{{ goal }} + +You can only use actions in the ACTION SPACE. Your response must include: +- Thought: Your analysis process. +- Action: The selected action. +- Action Input: Any required input. + +{{ action_space }} +""" + +class DataAnalysisAgent(ConversableAgent): + max_retry_count: int = 10 + run_mode: AgentRunMode = AgentRunMode.LOOP + + profile: ProfileConfig = ProfileConfig( + name=DynConfig("DataAnalysisAgent", category="agent", key="data_analysis_agent_name"), + role=DynConfig("DataAnalyzer", category="agent", key="data_analysis_agent_role"), + goal=DynConfig( + _DATA_ANALYSIS_DEFAULT_GOAL, + category="agent", + key="data_analysis_agent_goal", + ), + system_prompt_template=_DATA_ANALYSIS_SYSTEM_TEMPLATE, + ) + + async def act( + self, + message: AgentMessage, + sender: Agent, + reviewer: Optional[Agent] = None, + is_retry_chat: bool = False, + **kwargs, + ) -> ActionOutput: + """Perform a data analysis action.""" + message_content = message.content + if not message_content: + raise ValueError("The response is empty.") + + try: + steps = self.parser.parse(message_content) + if not steps or len(steps) != 1: + return ActionOutput(is_exe_success=False, content="Invalid response format.") + except Exception as e: + logger.warning(f"Parsing error: {e}") + return ActionOutput(is_exe_success=False, content=str(e)) + + action_output = await super().act( + message=message, sender=sender, reviewer=reviewer, is_retry_chat=is_retry_chat, **kwargs + ) + return action_output + + def prepare_act_param( + self, + received_message: Optional[AgentMessage], + sender: Agent, + **kwargs, + ) -> Dict[str, Any]: + """Prepare parameters for the act method.""" + return { + "parser": self.parser, + } + + @property + def memory_fragment_class(self) -> Type[AgentMemoryFragment]: + return StructuredAgentMemoryFragment \ No newline at end of file diff --git a/packages/dbgpt-core/src/dbgpt/agent/middleware/README.md b/packages/dbgpt-core/src/dbgpt/agent/middleware/README.md new file mode 100644 index 000000000..d5b2d5182 --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/middleware/README.md @@ -0,0 +1,222 @@ +# Agent Middleware System for DB-GPT + +This module implements a middleware system for DB-GPT agents, inspired by deepagents' AgentMiddleware pattern. + +## Architecture + +The middleware system allows plugins to hook into agent lifecycle events: + +- `AgentMiddleware` - Base class for all middleware +- `MiddlewareManager` - Manages middleware registration and execution +- `MiddlewareAgent` - ConversableAgent with middleware support +- `SkillsMiddlewareV2` - Skills middleware using the new middleware system + +## Middleware Lifecycle Hooks + +Middleware can hook into the following lifecycle events: + +| Hook | Description | +|------|-------------| +| `before_init` | Called before agent initialization | +| `after_init` | Called after agent initialization | +| `before_generate_reply` | Called before generating a reply | +| `after_generate_reply` | Called after generating a reply | +| `before_thinking` | Called before the thinking step | +| `after_thinking` | Called after the thinking step | +| `before_act` | Called before the act step | +| `after_act` | Called after the act step | +| `modify_system_prompt` | Modify the system prompt before it's sent to LLM | + +## Usage Examples + +### 1. Using MiddlewareAgent with Skills + +```python +from dbgpt.agent.core.profile.base import ProfileConfig +from dbgpt.agent.core.agent import AgentContext +from dbgpt.agent.middleware.agent import MiddlewareAgent, AgentConfig + +profile = ProfileConfig( + name="assistant", + role="AI Assistant", + goal="Help users with their tasks using available skills.", +) + +config = AgentConfig( + enable_middleware=True, + enable_skills=True, + skill_sources=[ + "/path/to/skills/user", + "/path/to/skills/project", + ], +) + +agent = MiddlewareAgent( + profile=profile, + agent_config=config, +) + +agent_context = AgentContext( + conv_id="test_conv_001", +) + +await agent.bind(agent_context).build() +``` + +### 2. Creating Custom Middleware + +```python +from dbgpt.agent.middleware.base import AgentMiddleware + +class LoggingMiddleware(AgentMiddleware): + """Custom middleware for logging.""" + + async def before_generate_reply(self, agent, context, **kwargs): + """Called before generating a reply.""" + print(f"Before generate reply: {context.message.content}") + + async def after_generate_reply(self, agent, context, reply_message, **kwargs): + """Called after generating a reply.""" + print(f"After generate reply: {reply_message.content}") + +agent = MiddlewareAgent(profile=profile) +agent.register_middleware(LoggingMiddleware()) +``` + +### 3. Using SkillsMiddlewareV2 Directly + +```python +from dbgpt.agent.skill.middleware_v2 import SkillsMiddlewareV2 + +skills_middleware = SkillsMiddlewareV2( + sources=["/path/to/skills/user"], + auto_load=True, + auto_match=True, + inject_to_system_prompt=True, +) + +skills = skills_middleware.load_skills() +for name, skill in skills.items(): + print(f"{name}: {skill.metadata.description}") + +matched_skills = skills_middleware.match_skills("research quantum computing") +``` + +## SKILL Format + +Skills are loaded from directories containing a `SKILL.md` file: + +``` +/skills/user/web-research/ +├── SKILL.md # Required: YAML frontmatter + markdown instructions +└── helper.py # Optional: supporting files +``` + +### SKILL.md Format + +```markdown +--- +name: web-research +description: Structured approach to conducting thorough web research +version: 1.0.0 +author: Your Name +skill_type: research +tags: [web, research, analysis] +allowed-tools: web-search +license: MIT +--- + +# Web Research Skill + +## When to Use +- User asks you to research a topic +- You need to gather information from the web +- Research requires structured approach + +## Workflow +1. Define research scope +2. Search for relevant information +3. Evaluate sources +4. Synthesize findings +5. Present results +``` + +## Comparison with DeepAgents + +| Feature | DeepAgents | DB-GPT (New) | +|---------|-------------|----------------| +| Backend Support | Filesystem, State, Remote | Filesystem (planned) | +| Middleware Hooks | before_agent, wrap_model_call | Full lifecycle hooks | +| Skill Format | SKILL.md with YAML | SKILL.md with YAML | +| Progressive Disclosure | Yes | Yes | +| Async Support | Yes | Yes | + +## Migration Guide + +### From Existing SkillsAgent + +If you're using `SkillsAgent` from `dbgpt.agent.skill.agent`, you can migrate to `MiddlewareAgent`: + +```python +# Old way +from dbgpt.agent.skill.agent import SkillsAgent, SkillsAgentConfig + +config = SkillsAgentConfig(skill_sources=["/path/to/skills"]) +agent = SkillsAgent(profile=profile, skills_config=config) + +# New way +from dbgpt.agent.middleware.agent import MiddlewareAgent, AgentConfig + +config = AgentConfig(skill_sources=["/path/to/skills"]) +agent = MiddlewareAgent(profile=profile, agent_config=config) +``` + +### From ConversableAgent + +To add middleware support to existing `ConversableAgent`: + +```python +from dbgpt.agent.core.base_agent import ConversableAgent +from dbgpt.agent.middleware.base import MiddlewareManager + +class MyAgent(ConversableAgent): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.middleware_manager = MiddlewareManager() + + async def build(self, is_retry_chat=False): + await self.middleware_manager.execute_before_init(self) + await super().build(is_retry_chat) + await self.middleware_manager.execute_after_init(self) + return self +``` + +## File Structure + +``` +dbgpt/agent/ +├── middleware/ +│ ├── __init__.py +│ ├── base.py # AgentMiddleware, MiddlewareManager +│ ├── agent.py # MiddlewareAgent +│ └── example.py # Usage examples +├── skill/ +│ ├── base.py # Skill, SkillBase, SkillMetadata +│ ├── middleware.py # Original SkillsMiddleware +│ ├── middleware_v2.py # SkillsMiddlewareV2 (new) +│ ├── agent.py # SkillsAgent (old) +│ ├── manage.py # SkillManager +│ └── parameters.py # SkillParameters +``` + +## Future Improvements + +- Backend abstraction for skills storage (filesystem, state, remote) +- Hot-reloading of skills +- Skill dependencies and versioning +- Skill execution monitoring and analytics +- Skill marketplace integration + +## License + +This module is part of DB-GPT and follows the same license. diff --git a/packages/dbgpt-core/src/dbgpt/agent/middleware/__init__.py b/packages/dbgpt-core/src/dbgpt/agent/middleware/__init__.py new file mode 100644 index 000000000..5d51d9145 --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/middleware/__init__.py @@ -0,0 +1,12 @@ +"""Middleware system for DB-GPT agents.""" + +from .agent import AgentConfig, MiddlewareAgent, create_middleware_agent +from .base import AgentMiddleware, MiddlewareManager + +__all__ = [ + "AgentMiddleware", + "MiddlewareManager", + "AgentConfig", + "MiddlewareAgent", + "create_middleware_agent", +] diff --git a/packages/dbgpt-core/src/dbgpt/agent/middleware/agent.py b/packages/dbgpt-core/src/dbgpt/agent/middleware/agent.py new file mode 100644 index 000000000..8f16cfd59 --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/middleware/agent.py @@ -0,0 +1,335 @@ +"""Middleware-enabled ConversableAgent. + +This module extends ConversableAgent to support middleware integration, +following deepagents' middleware pattern. +""" + +import dataclasses +import logging +from typing import Any, Callable, Dict, List, Optional, Tuple + +from ..core.base_agent import ConversableAgent +from ..core.role import Role +from ..middleware.base import MiddlewareManager +from ..skill.middleware_v2 import SkillsMiddlewareV2 + +logger = logging.getLogger(__name__) + + +@dataclasses.dataclass +class AgentConfig: + """Configuration for MiddlewareAgent.""" + + enable_middleware: bool = True + """Enable middleware system.""" + + enable_skills: bool = True + """Enable skills middleware.""" + + skill_sources: Optional[List[str]] = None + """Skill source directories.""" + + skill_auto_load: bool = True + """Auto-load skills.""" + + skill_auto_match: bool = True + """Auto-match skills.""" + + skill_inject_to_prompt: bool = True + """Inject skills to system prompt.""" + + +class MiddlewareAgent(ConversableAgent): + """ConversableAgent with middleware support. + + This agent extends ConversableAgent to support middleware plugins, + similar to deepagents' middleware pattern. The middleware system + allows plugins to hook into agent lifecycle events. + + Example: + ```python + from dbgpt.agent.core.profile.base import ProfileConfig + from dbgpt.agent.middleware.agent import MiddlewareAgent, AgentConfig + from dbgpt.agent.skill.middleware_v2 import SkillsMiddlewareV2 + + profile = ProfileConfig(name="assistant", role="AI Assistant") + config = AgentConfig(skill_sources=["/path/to/skills/user"]) + + agent = MiddlewareAgent(profile=profile, agent_config=config) + ``` + """ + + def __init__(self, agent_config: Optional[AgentConfig] = None, **kwargs): + """Initialize MiddlewareAgent. + + Args: + agent_config: Agent configuration. + **kwargs: Additional arguments for ConversableAgent. + """ + super().__init__(**kwargs) + + self.agent_config = agent_config or AgentConfig() + self._middleware_manager = MiddlewareManager() + + if self.agent_config.enable_middleware and self.agent_config.enable_skills: + skill_sources = self.agent_config.skill_sources or [] + if skill_sources: + skills_middleware = SkillsMiddlewareV2( + sources=skill_sources, + auto_load=self.agent_config.skill_auto_load, + auto_match=self.agent_config.skill_auto_match, + inject_to_system_prompt=self.agent_config.skill_inject_to_prompt, + ) + self._middleware_manager.register(skills_middleware) + + @property + def middleware_manager(self) -> MiddlewareManager: + """Return the middleware manager.""" + return self._middleware_manager + + def register_middleware(self, middleware): + """Register a middleware. + + Args: + middleware: The middleware to register. + """ + self._middleware_manager.register(middleware) + + def unregister_middleware(self, middleware): + """Unregister a middleware. + + Args: + middleware: The middleware to unregister. + """ + self._middleware_manager.unregister(middleware) + + async def build(self, is_retry_chat: bool = False) -> "MiddlewareAgent": + """Build the agent with middleware integration. + + Args: + is_retry_chat: Whether this is a retry chat. + + Returns: + Built agent instance. + """ + logger.info("Building MiddlewareAgent...") + + if self.agent_config.enable_middleware: + await self._middleware_manager.execute_before_init( + self, is_retry_chat=is_retry_chat + ) + + await super().build(is_retry_chat=is_retry_chat) + + if self.agent_config.enable_middleware: + await self._middleware_manager.execute_after_init( + self, is_retry_chat=is_retry_chat + ) + + return self + + async def _a_init_reply_message( + self, + received_message, + rely_messages: Optional[List] = None, + ): + """Initialize reply message with middleware hooks. + + Args: + received_message: The received message. + rely_messages: List of relied messages. + + Returns: + AgentMessage or None. + """ + if self.agent_config.enable_middleware and received_message: + from ..core.agent import AgentGenerateContext, AgentMessage + + context = AgentGenerateContext( + message=received_message, + sender=self, + ) + await self._middleware_manager.execute_before_generate_reply( + self, context, rely_messages=rely_messages + ) + + return await super()._a_init_reply_message( + received_message=received_message, + rely_messages=rely_messages, + ) + + async def thinking( + self, + messages, + sender=None, + prompt=None, + stream_callback: Optional[Callable[[Dict[str, Any]], Any]] = None, + ) -> Tuple[Optional[str], Optional[str]]: + """Think with middleware hooks. + + Args: + messages: The messages to be reasoned. + sender: Sender agent. + prompt: The prompt to be reasoned. + + Returns: + Tuple of (reply, model_name). + """ + if self.agent_config.enable_middleware: + from ..core.agent import AgentGenerateContext, AgentMessage + + if messages: + last_message = messages[-1] if messages else None + context = AgentGenerateContext( + message=last_message, + sender=sender or self, + ) + await self._middleware_manager.execute_before_thinking(self, context) + + llm_reply, model_name = await super().thinking( + messages, sender, prompt, stream_callback=stream_callback + ) + + if self.agent_config.enable_middleware: + from ..core.agent import AgentGenerateContext, AgentMessage + + if messages: + last_message = messages[-1] if messages else None + context = AgentGenerateContext( + message=last_message, + sender=sender or self, + ) + await self._middleware_manager.execute_after_thinking( + self, + context, + (llm_reply or ""), + (model_name or ""), + ) + + return llm_reply, model_name + + async def act( + self, + message, + sender, + reviewer=None, + is_retry_chat=False, + last_speaker_name=None, + **kwargs, + ): + """Act with middleware hooks. + + Args: + message: The message to be executed. + sender: Sender agent. + reviewer: Reviewer agent. + is_retry_chat: Whether this is a retry chat. + last_speaker_name: Last speaker name. + **kwargs: Additional arguments. + + Returns: + ActionOutput. + """ + if self.agent_config.enable_middleware: + from ..core.agent import AgentGenerateContext + + context = AgentGenerateContext( + message=message, + sender=sender, + reviewer=reviewer, + ) + await self._middleware_manager.execute_before_act( + self, context, message, reviewer=reviewer + ) + + action_output = await super().act( + message, + sender, + reviewer=reviewer, + is_retry_chat=is_retry_chat, + last_speaker_name=last_speaker_name, + **kwargs, + ) + + if self.agent_config.enable_middleware: + from ..core.agent import AgentGenerateContext + + context = AgentGenerateContext( + message=message, + sender=sender, + reviewer=reviewer, + ) + await self._middleware_manager.execute_after_act( + self, context, action_output, reviewer=reviewer + ) + + return action_output + + async def build_system_prompt( + self, + question=None, + most_recent_memories=None, + resource_vars=None, + context=None, + is_retry_chat=False, + ): + """Build system prompt with middleware hooks. + + Args: + question: Current question. + most_recent_memories: Most recent memories. + resource_vars: Resource variables. + context: Additional context. + is_retry_chat: Whether this is a retry chat. + + Returns: + System prompt string. + """ + original_prompt = await super().build_system_prompt( + question=question, + most_recent_memories=most_recent_memories, + resource_vars=resource_vars, + context=context, + is_retry_chat=is_retry_chat, + ) + + if self.agent_config.enable_middleware: + return await self._middleware_manager.execute_modify_system_prompt( + self, original_prompt, context + ) + + return original_prompt + + +def create_middleware_agent( + profile, + agent_config: Optional[AgentConfig] = None, + agent_context=None, + **kwargs, +) -> MiddlewareAgent: + """Create a MiddlewareAgent. + + Args: + profile: Profile configuration. + agent_config: Agent configuration. + agent_context: Agent context. + **kwargs: Additional arguments. + + Returns: + Configured MiddlewareAgent instance. + """ + agent = MiddlewareAgent( + profile=profile, + agent_config=agent_config, + agent_context=agent_context, + **kwargs, + ) + + return agent + + +__all__ = [ + "AgentConfig", + "MiddlewareAgent", + "create_middleware_agent", +] diff --git a/packages/dbgpt-core/src/dbgpt/agent/middleware/base.py b/packages/dbgpt-core/src/dbgpt/agent/middleware/base.py new file mode 100644 index 000000000..148da46c7 --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/middleware/base.py @@ -0,0 +1,488 @@ +"""Agent Middleware System for DB-GPT. + +This module implements a middleware system similar to deepagents' AgentMiddleware, +allowing plugins to hook into agent lifecycle events. +""" + +from __future__ import annotations + +import logging +from abc import ABC, abstractmethod +from typing import Any, Dict, List, Optional + +from dbgpt.agent.core.agent import AgentContext, AgentGenerateContext, AgentMessage +from dbgpt.core import PromptTemplate + +logger = logging.getLogger(__name__) + + +class AgentMiddleware(ABC): + """Base class for agent middleware. + + Middleware can hook into various lifecycle events of an agent: + - before_init: Before agent initialization + - after_init: After agent initialization + - before_generate_reply: Before generating a reply + - after_generate_reply: After generating a reply + - before_thinking: Before the thinking step + - after_thinking: After the thinking step + - before_act: Before the act step + - after_act: After the act step + - modify_system_prompt: Modify the system prompt + """ + + def __init__(self): + """Initialize the middleware.""" + self._enabled: bool = True + + @property + def enabled(self) -> bool: + """Check if middleware is enabled.""" + return self._enabled + + def enable(self): + """Enable the middleware.""" + self._enabled = True + + def disable(self): + """Disable the middleware.""" + self._enabled = False + + async def before_init(self, agent, **kwargs) -> Optional[Dict[str, Any]]: + """Called before agent initialization. + + Args: + agent: The agent instance. + **kwargs: Additional initialization arguments. + + Returns: + Optional state to be passed to other middleware or the agent. + """ + return None + + async def after_init(self, agent, **kwargs) -> Optional[Dict[str, Any]]: + """Called after agent initialization. + + Args: + agent: The agent instance. + **kwargs: Additional initialization arguments. + + Returns: + Optional state to be merged with agent state. + """ + return None + + async def before_generate_reply( + self, + agent, + context: AgentGenerateContext, + **kwargs, + ) -> Optional[Dict[str, Any]]: + """Called before generating a reply. + + Args: + agent: The agent instance. + context: The generate context. + **kwargs: Additional arguments. + + Returns: + Optional state update. + """ + return None + + async def after_generate_reply( + self, + agent, + context: AgentGenerateContext, + reply_message: AgentMessage, + **kwargs, + ) -> Optional[Dict[str, Any]]: + """Called after generating a reply. + + Args: + agent: The agent instance. + context: The generate context. + reply_message: The generated reply message. + **kwargs: Additional arguments. + + Returns: + Optional state update. + """ + return None + + async def before_thinking( + self, + agent, + context: AgentGenerateContext, + **kwargs, + ) -> Optional[Dict[str, Any]]: + """Called before the thinking step. + + Args: + agent: The agent instance. + context: The generate context. + **kwargs: Additional arguments. + + Returns: + Optional state update. + """ + return None + + async def after_thinking( + self, + agent, + context: AgentGenerateContext, + llm_reply: str, + model_name: str, + **kwargs, + ) -> Optional[Dict[str, Any]]: + """Called after the thinking step. + + Args: + agent: The agent instance. + context: The generate context. + llm_reply: The LLM reply. + model_name: The model name used. + **kwargs: Additional arguments. + + Returns: + Optional state update. + """ + return None + + async def before_act( + self, + agent, + context: AgentGenerateContext, + message: AgentMessage, + **kwargs, + ) -> Optional[Dict[str, Any]]: + """Called before the act step. + + Args: + agent: The agent instance. + context: The generate context. + message: The message to act on. + **kwargs: Additional arguments. + + Returns: + Optional state update. + """ + return None + + async def after_act( + self, + agent, + context: AgentGenerateContext, + action_output, + **kwargs, + ) -> Optional[Dict[str, Any]]: + """Called after the act step. + + Args: + agent: The agent instance. + context: The generate context. + action_output: The action output. + **kwargs: Additional arguments. + + Returns: + Optional state update. + """ + return None + + async def modify_system_prompt( + self, + agent, + original_prompt: str, + context: Optional[Dict[str, Any]] = None, + ) -> str: + """Modify the system prompt before it's sent to LLM. + + Args: + agent: The agent instance. + original_prompt: The original system prompt. + context: Additional context information. + + Returns: + Modified system prompt. + """ + return original_prompt + + +class MiddlewareManager: + """Manager for agent middleware. + + Handles registration, ordering, and execution of middleware. + """ + + def __init__(self): + """Initialize the middleware manager.""" + self._middlewares: List[AgentMiddleware] = [] + self._state: Dict[str, Any] = {} + + def register(self, middleware: AgentMiddleware) -> "MiddlewareManager": + """Register a middleware. + + Args: + middleware: The middleware to register. + + Returns: + Self for chaining. + """ + if middleware not in self._middlewares: + self._middlewares.append(middleware) + logger.info(f"Registered middleware: {middleware.__class__.__name__}") + return self + + def unregister(self, middleware: AgentMiddleware) -> "MiddlewareManager": + """Unregister a middleware. + + Args: + middleware: The middleware to unregister. + + Returns: + Self for chaining. + """ + if middleware in self._middlewares: + self._middlewares.remove(middleware) + logger.info(f"Unregistered middleware: {middleware.__class__.__name__}") + return self + + def get_state(self, key: str, default: Any = None) -> Any: + """Get a state value. + + Args: + key: The state key. + default: Default value if key doesn't exist. + + Returns: + The state value. + """ + return self._state.get(key, default) + + def set_state(self, key: str, value: Any) -> None: + """Set a state value. + + Args: + key: The state key. + value: The state value. + """ + self._state[key] = value + + def update_state(self, updates: Dict[str, Any]) -> None: + """Update state with a dictionary. + + Args: + updates: Dictionary of state updates. + """ + self._state.update(updates) + + async def execute_before_init(self, agent, **kwargs) -> Dict[str, Any]: + """Execute all before_init hooks. + + Args: + agent: The agent instance. + **kwargs: Additional arguments. + + Returns: + Combined state from all middleware. + """ + combined_state = {} + for middleware in self._middlewares: + if middleware.enabled: + state = await middleware.before_init(agent, **kwargs) + if state: + combined_state.update(state) + return combined_state + + async def execute_after_init(self, agent, **kwargs) -> Dict[str, Any]: + """Execute all after_init hooks. + + Args: + agent: The agent instance. + **kwargs: Additional arguments. + + Returns: + Combined state from all middleware. + """ + combined_state = {} + for middleware in self._middlewares: + if middleware.enabled: + state = await middleware.after_init(agent, **kwargs) + if state: + combined_state.update(state) + return combined_state + + async def execute_before_generate_reply( + self, agent, context: AgentGenerateContext, **kwargs + ) -> Dict[str, Any]: + """Execute all before_generate_reply hooks. + + Args: + agent: The agent instance. + context: The generate context. + **kwargs: Additional arguments. + + Returns: + Combined state from all middleware. + """ + combined_state = {} + for middleware in self._middlewares: + if middleware.enabled: + state = await middleware.before_generate_reply(agent, context, **kwargs) + if state: + combined_state.update(state) + return combined_state + + async def execute_after_generate_reply( + self, + agent, + context: AgentGenerateContext, + reply_message: AgentMessage, + **kwargs, + ) -> Dict[str, Any]: + """Execute all after_generate_reply hooks. + + Args: + agent: The agent instance. + context: The generate context. + reply_message: The generated reply message. + **kwargs: Additional arguments. + + Returns: + Combined state from all middleware. + """ + combined_state = {} + for middleware in self._middlewares: + if middleware.enabled: + state = await middleware.after_generate_reply( + agent, context, reply_message, **kwargs + ) + if state: + combined_state.update(state) + return combined_state + + async def execute_before_thinking( + self, agent, context: AgentGenerateContext, **kwargs + ) -> Dict[str, Any]: + """Execute all before_thinking hooks. + + Args: + agent: The agent instance. + context: The generate context. + **kwargs: Additional arguments. + + Returns: + Combined state from all middleware. + """ + combined_state = {} + for middleware in self._middlewares: + if middleware.enabled: + state = await middleware.before_thinking(agent, context, **kwargs) + if state: + combined_state.update(state) + return combined_state + + async def execute_after_thinking( + self, + agent, + context: AgentGenerateContext, + llm_reply: str, + model_name: str, + **kwargs, + ) -> Dict[str, Any]: + """Execute all after_thinking hooks. + + Args: + agent: The agent instance. + context: The generate context. + llm_reply: The LLM reply. + model_name: The model name used. + **kwargs: Additional arguments. + + Returns: + Combined state from all middleware. + """ + combined_state = {} + for middleware in self._middlewares: + if middleware.enabled: + state = await middleware.after_thinking( + agent, context, llm_reply, model_name, **kwargs + ) + if state: + combined_state.update(state) + return combined_state + + async def execute_before_act( + self, agent, context: AgentGenerateContext, message: AgentMessage, **kwargs + ) -> Dict[str, Any]: + """Execute all before_act hooks. + + Args: + agent: The agent instance. + context: The generate context. + message: The message to act on. + **kwargs: Additional arguments. + + Returns: + Combined state from all middleware. + """ + combined_state = {} + for middleware in self._middlewares: + if middleware.enabled: + state = await middleware.before_act(agent, context, message, **kwargs) + if state: + combined_state.update(state) + return combined_state + + async def execute_after_act( + self, agent, context: AgentGenerateContext, action_output, **kwargs + ) -> Dict[str, Any]: + """Execute all after_act hooks. + + Args: + agent: The agent instance. + context: The generate context. + action_output: The action output. + **kwargs: Additional arguments. + + Returns: + Combined state from all middleware. + """ + combined_state = {} + for middleware in self._middlewares: + if middleware.enabled: + state = await middleware.after_act( + agent, context, action_output, **kwargs + ) + if state: + combined_state.update(state) + return combined_state + + async def execute_modify_system_prompt( + self, + agent, + original_prompt: str, + context: Optional[Dict[str, Any]] = None, + ) -> str: + """Execute all modify_system_prompt hooks. + + Args: + agent: The agent instance. + original_prompt: The original system prompt. + context: Additional context information. + + Returns: + Modified system prompt. + """ + prompt = original_prompt + for middleware in self._middlewares: + if middleware.enabled: + prompt = await middleware.modify_system_prompt(agent, prompt, context) + return prompt + + +__all__ = [ + "AgentMiddleware", + "MiddlewareManager", +] diff --git a/packages/dbgpt-core/src/dbgpt/agent/middleware/example.py b/packages/dbgpt-core/src/dbgpt/agent/middleware/example.py new file mode 100644 index 000000000..7345fdd7b --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/middleware/example.py @@ -0,0 +1,105 @@ +"""Example: Using SkillsMiddleware with MiddlewareAgent. + +This example demonstrates how to use the new middleware system +to load and use skills in DB-GPT agents. +""" + +import asyncio + +from dbgpt.agent.core.profile.base import ProfileConfig +from dbgpt.agent.core.agent import AgentContext +from dbgpt.agent.middleware.agent import MiddlewareAgent, AgentConfig +from dbgpt.agent.skill.middleware_v2 import SkillsMiddlewareV2 + + +async def example_with_skills(): + """Example of using skills with MiddlewareAgent.""" + + profile = ProfileConfig( + name="assistant", + role="AI Assistant", + goal="Help users with their tasks using available skills.", + ) + + config = AgentConfig( + enable_middleware=True, + enable_skills=True, + skill_sources=[ + "/path/to/skills/user", + "/path/to/skills/project", + ], + skill_auto_load=True, + skill_auto_match=True, + skill_inject_to_prompt=True, + ) + + agent = MiddlewareAgent( + profile=profile, + agent_config=config, + ) + + agent_context = AgentContext( + conv_id="test_conv_001", + language="zh-CN", + ) + + await agent.bind(agent_context).build() + + return agent + + +async def example_custom_middleware(): + """Example of using custom middleware.""" + + from dbgpt.agent.middleware.base import AgentMiddleware + + class LoggingMiddleware(AgentMiddleware): + """Custom middleware for logging.""" + + async def before_generate_reply(self, agent, context, **kwargs): + """Called before generating a reply.""" + print(f"Before generate reply: {context.message.content}") + + async def after_generate_reply(self, agent, context, reply_message, **kwargs): + """Called after generating a reply.""" + print(f"After generate reply: {reply_message.content}") + + profile = ProfileConfig( + name="assistant", + role="AI Assistant", + ) + + agent = MiddlewareAgent( + profile=profile, + agent_config=AgentConfig(enable_middleware=True), + ) + + logging_middleware = LoggingMiddleware() + agent.register_middleware(logging_middleware) + + return agent + + +async def example_skills_middleware_direct(): + """Example of using SkillsMiddlewareV2 directly.""" + + skills_middleware = SkillsMiddlewareV2( + sources=["/path/to/skills/user"], + auto_load=True, + auto_match=True, + inject_to_system_prompt=True, + ) + + skills = skills_middleware.load_skills() + print(f"Loaded {len(skills)} skills:") + for name, skill in skills.items(): + print(f" - {name}: {skill.metadata.description}") + + matched_skills = skills_middleware.match_skills("research quantum computing") + print(f"\nMatched {len(matched_skills)} skills") + + +if __name__ == "__main__": + asyncio.run(example_with_skills()) + asyncio.run(example_custom_middleware()) + asyncio.run(example_skills_middleware_direct()) diff --git a/packages/dbgpt-core/src/dbgpt/agent/resource/skill_resource.py b/packages/dbgpt-core/src/dbgpt/agent/resource/skill_resource.py new file mode 100644 index 000000000..70e0cf8f8 --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/resource/skill_resource.py @@ -0,0 +1,76 @@ +"""Agent Resource wrapper for Skills. + +This file introduces a Resource subclass so skills can be treated as a +first-class Resource (ResourceType.Skill). It uses SkillManager to build +skill instances from parameters and exposes prompt/get_prompt to integrate +with existing resource plumbing. +""" + +from typing import Optional, Tuple, Dict, Any + +from dbgpt.agent.resource.base import Resource, ResourceParameters, ResourceType +from dbgpt.agent.skill.manage import get_skill_manager +from dbgpt.agent.skill.parameters import SkillParameters +from dbgpt.core import Chunk + + +class SkillResource(Resource[SkillParameters]): + @classmethod + def type(cls) -> ResourceType: + return ResourceType.Skill + + def __init__( + self, + name: str, + skill=None, + skill_name: Optional[str] = None, + system_app: Any = None, + **kwargs, + ): + self._name = name + if skill: + self._skill = skill + elif skill_name: + # Load skill from SkillManager + from dbgpt.agent.skill.manage import get_skill_manager + + skill_manager = get_skill_manager(system_app) + self._skill = skill_manager.get_skill(name=skill_name) + if not self._skill: + # Try to load by type if name not found + # Or just keep it None and fail later or log warning + pass + else: + self._skill = None + + @property + def name(self) -> str: + return self._name + + @classmethod + def resource_parameters_class(cls, **kwargs): + return SkillParameters + + async def get_prompt( + self, + *, + lang: str = "en", + prompt_type: str = "default", + question: Optional[str] = None, + resource_name: Optional[str] = None, + **kwargs, + ) -> Tuple[str, Optional[Dict]]: + """Return the skill's prompt template as resource prompt.""" + if not self._skill or not self._skill.prompt_template: + return "", None + # skill.prompt_template is a PromptTemplate + prompt = self._skill.prompt_template.format(question=question or "") + return prompt, None + + async def get_resources(self, *args, **kwargs) -> Tuple[None, str, None]: + prompt, _ = await self.get_prompt(*args, **kwargs) + return None, prompt, None + + async def async_execute(self, *args, resource_name: Optional[str] = None, **kwargs): + # Skills themselves don't execute here; actions/tools implement behavior. + raise NotImplementedError("SkillResource is readonly wrapper") diff --git a/packages/dbgpt-core/src/dbgpt/agent/skill/__init__.py b/packages/dbgpt-core/src/dbgpt/agent/skill/__init__.py new file mode 100644 index 000000000..85531fc99 --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/skill/__init__.py @@ -0,0 +1,41 @@ +"""Skill module for DB-GPT agent framework. + +This module provides a SKILL mechanism, which allows loading and managing +agent skills that include prompts, tools, knowledge, and actions. +""" + +from .agent import SkillsAgent, SkillsAgentConfig, create_skills_agent +from .base import Skill, SkillBase, SkillMetadata, SkillType +from .middleware import ( + LoadedSkill, + SkillsMiddleware, + _list_skills_from_directory, + _parse_skill_metadata, + _validate_skill_name, +) +from .middleware_v2 import SkillsMiddlewareV2 +from .manage import SkillManager, get_skill_manager, initialize_skill +from .parameters import SkillParameters +from .loader import SkillLoader, SkillBuilder + +__all__ = [ + "Skill", + "SkillBase", + "SkillMetadata", + "SkillParameters", + "SkillLoader", + "SkillBuilder", + "SkillType", + "SkillManager", + "get_skill_manager", + "initialize_skill", + "SkillsMiddleware", + "LoadedSkill", + "SkillsAgent", + "SkillsAgentConfig", + "create_skills_agent", + "_list_skills_from_directory", + "_parse_skill_metadata", + "_validate_skill_name", + "SkillsMiddlewareV2", +] diff --git a/packages/dbgpt-core/src/dbgpt/agent/skill/agent.py b/packages/dbgpt-core/src/dbgpt/agent/skill/agent.py new file mode 100644 index 000000000..7750c03ac --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/skill/agent.py @@ -0,0 +1,293 @@ +"""Skills-enabled agent for DB-GPT. + +This module provides an agent implementation with SkillsMiddleware integration, +enabling progressive disclosure of skills from multiple sources. +""" + +import dataclasses +from typing import Any, Dict, List, Optional + +from dbgpt.agent.core.agent import AgentContext +from dbgpt.agent.core.base_agent import ConversableAgent +from dbgpt.agent.skill.middleware import ( + LoadedSkill, + SkillsMiddleware, +) + + +@dataclasses.dataclass +class SkillsAgentConfig: + """Configuration for SkillsAgent.""" + + skill_sources: List[str] + """List of skill source directories.""" + + auto_load: bool = True + """Automatically load skills on initialization.""" + + auto_match: bool = True + """Automatically match skills based on user input.""" + + lazy_content_load: bool = True + """Load skill content on demand (progressive disclosure).""" + + inject_to_system_prompt: bool = True + """Inject skills metadata into system prompt.""" + + +class SkillsAgent(ConversableAgent): + """Agent with progressive disclosure skills support. + + This agent integrates SkillsMiddleware to provide: + - Automatic skill loading from multiple sources + - Progressive disclosure (metadata first, content on demand) + - Automatic skill matching based on user input + - Skill injection into system prompt + + Example: + ```python + from dbgpt.agent.core.profile.base import ProfileConfig + from dbgpt.agent.skill.agent import SkillsAgent, SkillsAgentConfig + + profile = ProfileConfig(name="assistant", role="AI Assistant") + config = SkillsAgentConfig( + skill_sources=["/path/to/skills/user", "/path/to/skills/project"] + ) + + agent = SkillsAgent(profile=profile, skills_config=config) + ``` + """ + + def __init__( + self, + skills_config: SkillsAgentConfig, + **kwargs, + ): + """Initialize a SkillsAgent. + + Args: + skills_config: Configuration for skills middleware. + **kwargs: Additional arguments for ConversableAgent. + """ + super().__init__(**kwargs) + + self._skills_config = skills_config + self._skills_middleware = SkillsMiddleware(sources=skills_config.skill_sources) + self._active_skills: List[LoadedSkill] = [] + self._base_prompt = None + + if skills_config.auto_load: + self._skills_middleware.load_skills() + + @property + def skills_middleware(self) -> SkillsMiddleware: + """Return the skills middleware.""" + return self._skills_middleware + + @property + def active_skills(self) -> List[LoadedSkill]: + """Return currently active skills.""" + return self._active_skills + + @property + def skills_config(self) -> SkillsAgentConfig: + """Return skills configuration.""" + return self._skills_config + + def load_skills(self) -> Dict[str, LoadedSkill]: + """Load skills from all configured sources. + + Returns: + Dictionary of loaded skills keyed by name. + """ + return self._skills_middleware.load_skills() + + def get_skill(self, name: str) -> Optional[LoadedSkill]: + """Get a skill by name. + + Args: + name: Skill name. + + Returns: + LoadedSkill or None. + """ + return self._skills_middleware.get_skill(name) + + def list_skills(self) -> List[str]: + """List all available skill names. + + Returns: + List of skill names. + """ + skills = self._skills_middleware.list_skills() + return [skill.name for skill in skills] + + def match_skills(self, user_input: str) -> List[LoadedSkill]: + """Find skills that match user input. + + Args: + user_input: User input string. + + Returns: + List of matching skills. + """ + return self._skills_middleware.match_skills(user_input) + + def set_skill(self, skill_name: str): + """Manually activate a specific skill. + + Args: + skill_name: Name of skill to activate. + + Raises: + ValueError: If skill not found. + """ + skill = self._skills_middleware.get_skill(skill_name) + if not skill: + raise ValueError(f"Skill not found: {skill_name}") + + if skill not in self._active_skills: + self._active_skills.append(skill) + self._update_prompt_with_skills() + + def clear_active_skills(self): + """Clear all active skills and revert to base prompt.""" + self._active_skills = [] + if self._base_prompt: + self.bind_prompt = self._base_prompt + + def _update_prompt_with_skills(self): + """Update agent prompt with active skills.""" + if self._skills_config.inject_to_system_prompt: + skills_section = self._skills_middleware.create_skills_prompt_section() + + if self.bind_prompt is None: + self._base_prompt = self.bind_prompt + + if self.bind_prompt: + combined = f"{skills_section}\n\n{self.bind_prompt.template}" + else: + combined = skills_section + + from dbgpt.core import PromptTemplate + + self.bind_prompt = PromptTemplate.from_template(combined) + + async def build_system_prompt( + self, + question: Optional[str] = None, + most_recent_memories: Optional[str] = None, + resource_vars: Optional[Dict] = None, + context: Optional[Dict[str, Any]] = None, + is_retry_chat: bool = False, + ): + """Build system prompt with skills integration. + + Args: + question: Current question. + most_recent_memories: Most recent memories. + resource_vars: Resource variables. + context: Additional context. + is_retry_chat: Whether this is a retry chat. + + Returns: + System prompt string. + """ + if self._skills_config.inject_to_system_prompt: + self._update_prompt_with_skills() + + return await super().build_system_prompt( + question=question, + most_recent_memories=most_recent_memories, + resource_vars=resource_vars, + context=context, + is_retry_chat=is_retry_chat, + ) + + async def _a_init_reply_message( + self, + received_message, + rely_messages: Optional[List] = None, + ): + """Initialize reply message with skill detection. + + Args: + received_message: The received message. + rely_messages: List of relied messages. + + Returns: + AgentMessage or None. + """ + if self._skills_config.auto_match and received_message.content: + matched_skills = self.match_skills(received_message.content) + + if matched_skills: + self._active_skills = matched_skills + self._update_prompt_with_skills() + + return await super()._a_init_reply_message( + received_message=received_message, + rely_messages=rely_messages, + ) + + def get_skills_summary(self) -> str: + """Get a summary of available and active skills. + + Returns: + Formatted summary string. + """ + all_skills = self._skills_middleware.list_skills() + active_names = [s.metadata.name for s in self._active_skills] + + summary = f"Total Skills: {len(all_skills)}\n" + summary += f"Active Skills: {len(active_names)}\n\n" + + if active_names: + summary += "**Active Skills:**\n" + for name in active_names: + summary += f" - {name}\n" + summary += "\n" + + summary += "**Available Skills:**\n" + for skill_metadata in all_skills: + is_active = skill_metadata.name in active_names + status = "[ACTIVE]" if is_active else "" + summary += ( + f" {status} {skill_metadata.name}: {skill_metadata.description}\n" + ) + + return summary + + +async def create_skills_agent( + skill_sources: List[str], + context: AgentContext, + **kwargs, +) -> SkillsAgent: + """Create a SkillsAgent with skills from specified sources. + + Args: + skill_sources: List of skill source directories. + context: Agent context. + **kwargs: Additional arguments for SkillsAgent. + + Returns: + Configured SkillsAgent instance. + """ + skills_config = SkillsAgentConfig( + skill_sources=skill_sources, + auto_load=True, + auto_match=True, + lazy_content_load=True, + inject_to_system_prompt=True, + ) + + agent = SkillsAgent( + skills_config=skills_config, + agent_context=context, + **kwargs, + ) + + await agent.bind(context).build() + + return agent diff --git a/packages/dbgpt-core/src/dbgpt/agent/skill/base.py b/packages/dbgpt-core/src/dbgpt/agent/skill/base.py new file mode 100644 index 000000000..a4a30ee7b --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/skill/base.py @@ -0,0 +1,150 @@ +"""Skill base classes.""" + +import dataclasses +from abc import ABC, abstractmethod +from enum import Enum +from typing import Any, Dict, List, Optional, Type, Union + +from dbgpt.core import PromptTemplate +from dbgpt._private.pydantic import BaseModel, Field + + +class SkillType(str, Enum): + """Skill type enumeration.""" + + Coding = "coding" + DataAnalysis = "data_analysis" + WebSearch = "web_search" + KnowledgeQA = "knowledge_qa" + Chat = "chat" + Custom = "custom" + + +@dataclasses.dataclass +class SkillMetadata: + """Metadata for a skill.""" + + name: str + description: str + version: str = "1.0.0" + author: Optional[str] = None + skill_type: SkillType = SkillType.Custom + tags: List[str] = dataclasses.field(default_factory=list) + + def to_dict(self) -> Dict[str, Any]: + """Convert to dictionary.""" + return { + "name": self.name, + "description": self.description, + "version": self.version, + "author": self.author, + "skill_type": self.skill_type.value + if isinstance(self.skill_type, SkillType) + else self.skill_type, + "tags": self.tags, + } + + +class SkillBase(ABC): + """Base class for a skill.""" + + @classmethod + @abstractmethod + def type(cls) -> SkillType: + """Return the skill type.""" + pass + + @property + @abstractmethod + def metadata(self) -> SkillMetadata: + """Return the skill metadata.""" + pass + + @property + @abstractmethod + def prompt_template(self) -> Optional[PromptTemplate]: + """Return the prompt template.""" + pass + + @property + @abstractmethod + def required_tools(self) -> List[str]: + """Return the list of required tool names.""" + pass + + @property + @abstractmethod + def required_knowledge(self) -> List[str]: + """Return the list of required knowledge names.""" + pass + + @property + @abstractmethod + def actions(self) -> List[Any]: + """Return the list of actions.""" + pass + + +class Skill(SkillBase): + """Concrete implementation of a skill.""" + + def __init__( + self, + metadata: SkillMetadata, + prompt_template: Optional[PromptTemplate] = None, + required_tools: Optional[List[str]] = None, + required_knowledge: Optional[List[str]] = None, + actions: Optional[List[Any]] = None, + config: Optional[Dict[str, Any]] = None, + ): + """Initialize a skill. + + Args: + metadata: The skill metadata. + prompt_template: The prompt template for the skill. + required_tools: List of required tool names. + required_knowledge: List of required knowledge names. + actions: List of actions. + config: Additional configuration. + """ + self._metadata = metadata + self._prompt_template = prompt_template + self._required_tools = required_tools or [] + self._required_knowledge = required_knowledge or [] + self._actions = actions or [] + self._config = config or {} + + @classmethod + def type(cls) -> SkillType: + """Return the skill type.""" + return SkillType.Custom + + @property + def metadata(self) -> SkillMetadata: + """Return the skill metadata.""" + return self._metadata + + @property + def prompt_template(self) -> Optional[PromptTemplate]: + """Return the prompt template.""" + return self._prompt_template + + @property + def required_tools(self) -> List[str]: + """Return the list of required tool names.""" + return self._required_tools + + @property + def required_knowledge(self) -> List[str]: + """Return the list of required knowledge names.""" + return self._required_knowledge + + @property + def actions(self) -> List[Any]: + """Return the list of actions.""" + return self._actions + + @property + def config(self) -> Dict[str, Any]: + """Return the skill configuration.""" + return self._config diff --git a/packages/dbgpt-core/src/dbgpt/agent/skill/loader.py b/packages/dbgpt-core/src/dbgpt/agent/skill/loader.py new file mode 100644 index 000000000..647353360 --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/skill/loader.py @@ -0,0 +1,410 @@ +"""Skill loader for loading skills from various sources.""" + +import importlib +import json +import logging +import os +from pathlib import Path +from typing import Any, Dict, List, Optional, Union + +from .base import Skill, SkillBase, SkillMetadata, SkillType + + +logger = logging.getLogger(__name__) + + +class SkillLoader: + """Skill loader for loading skills from files or modules.""" + + def __init__(self, skill_dirs: Optional[List[str]] = None): + """Initialize skill loader. + + Args: + skill_dirs: List of directories to search for skills. + """ + self.skill_dirs = skill_dirs or [] + + def load_skill_from_file(self, file_path: str) -> Optional[SkillBase]: + """Load a skill from a JSON/YAML file. + + Args: + file_path: Path to the skill file. + + Returns: + Skill instance. + """ + # Normalize and resolve the incoming path. Accepts absolute or relative paths. + path = Path(file_path).expanduser() + + # If the provided path is not absolute or doesn't exist, try resolving + # it relative to the current working directory (common when running + # scripts from project root) to give better UX. + tried_paths = [path] + if not path.is_absolute(): + tried_paths.append(Path.cwd() / path) + + # Try all candidate paths and pick the first existing one. + resolved = None + for p in tried_paths: + try: + rp = p.resolve() + except Exception: + rp = p + if rp.exists(): + resolved = rp + break + + if resolved is None or not resolved.exists(): + logger.error( + "Skill file not found. Tried: %s", + ", ".join(str(p) for p in tried_paths), + ) + return None + + path = resolved + + if path.suffix == ".json": + return self._load_from_json(path) + elif path.name == "SKILL.md" or path.suffix == ".md": + return self._load_from_markdown(path) + elif path.suffix in [".yaml", ".yml"]: + return self._load_from_yaml(path) + else: + logger.error(f"Unsupported file format: {path.suffix}") + return None + + def load_skill_from_module(self, module_path: str) -> Optional[SkillBase]: + """Load a skill from a Python module. + + Args: + module_path: Python module path (e.g., "my_skills.coding_skill"). + + Returns: + Skill instance. + """ + try: + module = importlib.import_module(module_path) + skill_cls = getattr(module, "Skill", None) + if skill_cls and issubclass(skill_cls, SkillBase): + return skill_cls() + logger.warning(f"No Skill class found in module: {module_path}") + return None + except Exception as e: + logger.error(f"Failed to load skill from module {module_path}: {e}") + return None + + def load_skills_from_directory( + self, directory: str, recursive: bool = True + ) -> List[SkillBase]: + """Load all skills from a directory. + + Args: + directory: Directory path. + recursive: Whether to search recursively. + + Returns: + List of skill instances. + """ + skills: List[SkillBase] = [] + path = Path(directory) + + if not path.exists() or not path.is_dir(): + logger.warning(f"Directory not found: {directory}") + return skills + + # Look for JSON/YAML files and Claude-style SKILL.md files + pattern = "**/*" if recursive else "*" + for file_path in path.glob(pattern): + if file_path.is_file() and file_path.suffix in [ + ".json", + ".yaml", + ".yml", + ".md", + ]: + # load_skill_from_file will dispatch appropriately + skill = self.load_skill_from_file(str(file_path)) + if skill: + skills.append(skill) + + return skills + + def _load_from_json(self, path: Path) -> Optional[Skill]: + """Load skill from JSON file. + + Args: + path: Path to JSON file. + + Returns: + Skill instance. + """ + try: + with open(path, "r", encoding="utf-8") as f: + data = json.load(f) + + skill = self._create_skill_from_dict(data) + if skill: + # Store the file path in config + skill._config["file_path"] = str(path) + return skill + except Exception as e: + logger.error(f"Failed to load JSON skill from {path}: {e}") + return None + + def _load_from_markdown(self, path: Path) -> Optional[Skill]: + """Load a skill from a Claude-style SKILL.md file. + + This uses the FileBasedSkill parser implemented in the claude_skill module + to parse the SKILL.md frontmatter and instructions, and then converts + it into a core Skill instance. + """ + try: + from dbgpt.agent.claude_skill import FileBasedSkill + + file_skill = FileBasedSkill(str(path)) + # Build core Skill from FileBasedSkill + metadata = file_skill.metadata + from dbgpt.core import PromptTemplate + + prompt_template = file_skill.get_prompt() + from .base import Skill, SkillMetadata + + # Map additional fields from Claude-style SkillMetadata into core SkillMetadata + # Map Claude-style metadata into core Skill and SkillMetadata + from .base import SkillType + + # try to coerce skill_type to known SkillType, fallback to Custom + skill_type_val = SkillType.Custom + if getattr(metadata, "skill_type", None): + try: + skill_type_val = SkillType(metadata.skill_type) + except Exception: + skill_type_val = SkillType.Custom + + core_meta = SkillMetadata( + name=metadata.name, + description=metadata.description, + version=getattr(metadata, "version", "1.0.0") or "1.0.0", + author=getattr(metadata, "author", None), + skill_type=skill_type_val, + tags=getattr(metadata, "tags", []) or [], + ) + + # Build the Skill copying required fields from FileBasedSkill.metadata + skill = Skill( + metadata=core_meta, + prompt_template=prompt_template, + required_tools=getattr(metadata, "required_tools", []) or [], + required_knowledge=getattr(metadata, "required_knowledge", []) or [], + config={"file_path": str(path), **(getattr(metadata, "config", {}) or {})}, + ) + + return skill + except Exception as e: + logger.error(f"Failed to load SKILL.md skill from {path}: {e}") + return None + + def _load_from_yaml(self, path: Path) -> Optional[Skill]: + """Load skill from YAML file. + + Args: + path: Path to YAML file. + + Returns: + Skill instance. + """ + try: + import yaml + + with open(path, "r", encoding="utf-8") as f: + data = yaml.safe_load(f) + + skill = self._create_skill_from_dict(data) + if skill: + skill._config["file_path"] = str(path) + return skill + except ImportError: + logger.error("PyYAML not installed, cannot load YAML skills") + return None + except Exception as e: + logger.error(f"Failed to load YAML skill from {path}: {e}") + return None + + def _create_skill_from_dict(self, data: Dict[str, Any]) -> Optional[Skill]: + """Create a skill from dictionary data. + + Args: + data: Skill data dictionary. + + Returns: + Skill instance. + """ + try: + metadata_data = data.get("metadata", {}) + metadata = SkillMetadata( + name=metadata_data.get("name", "Unknown"), + description=metadata_data.get("description", ""), + version=metadata_data.get("version", "1.0.0"), + author=metadata_data.get("author"), + skill_type=SkillType(metadata_data.get("skill_type", "custom")), + tags=metadata_data.get("tags", []), + ) + + return Skill( + metadata=metadata, + config=data.get("config"), + ) + except Exception as e: + logger.error(f"Failed to create skill from dict: {e}") + return None + + +class SkillBuilder: + """Builder for creating skills programmatically.""" + + def __init__(self, name: str, description: str): + """Initialize skill builder. + + Args: + name: Skill name. + description: Skill description. + """ + self._metadata = SkillMetadata( + name=name, + description=description, + ) + self._prompt_template: Optional[str] = None + self._required_tools: List[str] = [] + self._required_knowledge: List[str] = [] + self._actions: List[Any] = [] + self._config: Dict[str, Any] = {} + + def with_version(self, version: str) -> "SkillBuilder": + """Set skill version. + + Args: + version: Version string. + + Returns: + Self for chaining. + """ + self._metadata.version = version + return self + + def with_author(self, author: str) -> "SkillBuilder": + """Set skill author. + + Args: + author: Author name. + + Returns: + Self for chaining. + """ + self._metadata.author = author + return self + + def with_skill_type(self, skill_type: Union[str, SkillType]) -> "SkillBuilder": + """Set skill type. + + Args: + skill_type: Skill type. + + Returns: + Self for chaining. + """ + if isinstance(skill_type, str): + skill_type = SkillType(skill_type) + self._metadata.skill_type = skill_type + return self + + def with_tags(self, tags: List[str]) -> "SkillBuilder": + """Set skill tags. + + Args: + tags: List of tags. + + Returns: + Self for chaining. + """ + self._metadata.tags = tags + return self + + def with_prompt_template(self, prompt_template: str) -> "SkillBuilder": + """Set prompt template. + + Args: + prompt_template: Prompt template string. + + Returns: + Self for chaining. + """ + self._prompt_template = prompt_template + return self + + def with_required_tool(self, tool_name: str) -> "SkillBuilder": + """Add a required tool. + + Args: + tool_name: Tool name. + + Returns: + Self for chaining. + """ + self._required_tools.append(tool_name) + return self + + def with_required_knowledge(self, knowledge_name: str) -> "SkillBuilder": + """Add required knowledge. + + Args: + knowledge_name: Knowledge name. + + Returns: + Self for chaining. + """ + self._required_knowledge.append(knowledge_name) + return self + + def with_action(self, action: Any) -> "SkillBuilder": + """Add an action. + + Args: + action: Action instance. + + Returns: + Self for chaining. + """ + self._actions.append(action) + return self + + def with_config(self, config: Dict[str, Any]) -> "SkillBuilder": + """Set configuration. + + Args: + config: Configuration dictionary. + + Returns: + Self for chaining. + """ + self._config.update(config) + return self + + def build(self) -> Skill: + """Build the skill. + + Returns: + Skill instance. + """ + from dbgpt.core import PromptTemplate + + prompt_template = None + if self._prompt_template: + prompt_template = PromptTemplate.from_template(self._prompt_template) + + return Skill( + metadata=self._metadata, + prompt_template=prompt_template, + required_tools=self._required_tools, + required_knowledge=self._required_knowledge, + actions=self._actions, + config=self._config, + ) diff --git a/packages/dbgpt-core/src/dbgpt/agent/skill/manage.py b/packages/dbgpt-core/src/dbgpt/agent/skill/manage.py new file mode 100644 index 000000000..9434f295d --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/skill/manage.py @@ -0,0 +1,462 @@ +"""Skill manager.""" + +import json +import logging +from typing import Any, Dict, List, Optional, Type, Union, cast + +from dbgpt.component import BaseComponent, ComponentType, SystemApp +from dbgpt.util.parameter_utils import ParameterDescription + +from .base import Skill, SkillBase, SkillMetadata, SkillType +from .parameters import SkillParameters + +logger = logging.getLogger(__name__) + + +class RegisterSkill: + """Register skill model.""" + + def __init__( + self, + name: str, + skill_cls: Type[SkillBase], + skill_instance: Optional[SkillBase] = None, + metadata: Optional[SkillMetadata] = None, + is_class: bool = True, + ): + """Initialize register skill. + + Args: + name: Skill name. + skill_cls: Skill class. + skill_instance: Skill instance. + metadata: Skill metadata. + is_class: Whether it's a class or instance. + """ + self.name = name + self.skill_cls = skill_cls + self.skill_instance = skill_instance + self.metadata = metadata or ( + skill_instance.metadata if skill_instance else None + ) + self.is_class = is_class + + @property + def key(self) -> str: + """Return the unique key.""" + full_cls = f"{self.skill_cls.__module__}.{self.skill_cls.__qualname__}" + return f"{self.name}:{full_cls}" + + @property + def type_key(self) -> str: + """Return the type key.""" + if self.metadata and getattr(self.metadata, "skill_type", None): + return self.metadata.skill_type.value + return "custom" + + +class SkillManager(BaseComponent): + """Skill manager. + + To manage the skills. + """ + + # Use a distinct component name so SkillManager does not collide with ResourceManager + name = ComponentType.SKILL_MANAGER + + def __init__(self, system_app: SystemApp): + """Create a new SkillManager.""" + super().__init__(system_app) + self.system_app = system_app + self._skills: Dict[str, RegisterSkill] = {} + self._type_to_skills: Dict[str, List[RegisterSkill]] = {} + + def init_app(self, system_app: SystemApp): + """Initialize the SkillManager.""" + self.system_app = system_app + + def after_start(self): + """Register all skills after start.""" + pass + + def register_skill( + self, + skill_cls: Optional[Type[SkillBase]] = None, + skill_instance: Optional[SkillBase] = None, + name: Optional[str] = None, + metadata: Optional[SkillMetadata] = None, + ignore_duplicate: bool = False, + ): + """Register a skill. + + Args: + skill_cls: Skill class. + skill_instance: Skill instance. + name: Skill name. + metadata: Skill metadata. + ignore_duplicate: Whether to ignore duplicate registration. + """ + if skill_cls is None and skill_instance is None: + raise ValueError("Skill class or instance must be provided.") + + if skill_instance is not None: + skill_cls = type(skill_instance) # type: ignore + name = name or skill_instance.metadata.name + else: + name = name or skill_cls.__name__ # type: ignore + + metadata = metadata or (skill_instance.metadata if skill_instance else None) + + register_skill = RegisterSkill( + name=name, + skill_cls=skill_cls, # type: ignore + skill_instance=skill_instance, + metadata=metadata, + is_class=skill_instance is None, + ) + + if register_skill.key in self._skills: + if ignore_duplicate: + return + else: + raise ValueError(f"Skill {register_skill.key} already exists.") + + self._skills[register_skill.key] = register_skill + if register_skill.type_key not in self._type_to_skills: + self._type_to_skills[register_skill.type_key] = [] + self._type_to_skills[register_skill.type_key].append(register_skill) + + def get_skill( + self, + name: Optional[str] = None, + skill_type: Optional[SkillType] = None, + version: Optional[str] = None, + ) -> Optional[SkillBase]: + """Get a skill by name or type. + + Args: + name: Skill name. + skill_type: Skill type. + version: Skill version. + + Returns: + The skill instance or None. + """ + if name: + for register_skill in self._skills.values(): + if register_skill.name == name: + if version and register_skill.metadata.version != version: + continue + return self._instantiate_skill(register_skill) + return None + + if skill_type: + type_key = skill_type.value + skills = self._type_to_skills.get(type_key, []) + if skills: + return self._instantiate_skill(skills[0]) + + return None + + def get_skills_by_type(self, skill_type: SkillType) -> List[SkillBase]: + """Get all skills by type. + + Args: + skill_type: Skill type. + + Returns: + List of skill instances. + """ + type_key = skill_type.value + skills = self._type_to_skills.get(type_key, []) + return [self._instantiate_skill(skill) for skill in skills] + + def list_skills(self) -> List[Dict[str, Any]]: + """List all registered skills. + + Returns: + List of skill metadata dictionaries. + """ + result = [] + for register_skill in self._skills.values(): + if register_skill.metadata is None: + result.append({}) + else: + # metadata may be a dataclass with to_dict method + try: + result.append(register_skill.metadata.to_dict()) + except Exception: + # fallback to attribute access + result.append( + { + "name": getattr(register_skill.metadata, "name", ""), + "description": getattr( + register_skill.metadata, "description", "" + ), + "version": getattr(register_skill.metadata, "version", ""), + } + ) + return result + + def _instantiate_skill(self, register_skill: RegisterSkill) -> SkillBase: + """Instantiate a skill from register skill. + + Args: + register_skill: RegisterSkill instance. + + Returns: + Skill instance. + """ + if not register_skill.is_class: + return cast(SkillBase, register_skill.skill_instance) + + skill_cls = cast(Type[SkillBase], register_skill.skill_cls) + return skill_cls() + + def build_skill_from_parameters( + self, parameters: SkillParameters + ) -> Optional[SkillBase]: + """Build a skill from parameters. + + Args: + parameters: Skill parameters. + + Returns: + Skill instance. + """ + skill = self.get_skill(name=parameters.skill_name) + return skill + + def retrieve_skills(self) -> List[Dict[str, Any]]: + """Retrieve all skills metadata. + + Returns: + List[Dict[str, Any]]: List of skill metadata including name, description and path. + """ + # This is a basic implementation. In a real scenario, this might search directories + # or a database. Since we currently register skills manually or via config, + # we iterate over registered skills. + # To support directory scanning as requested, we would need to implement + # a scanner here or in SkillLoader. + # For now, let's assume skills are registered. + # BUT, the user wants to scan the directory. + return self.list_skills() + + def get_skill_content(self, skill_name: str) -> str: + """Get the content (SKILL.md) of a skill. + + Args: + skill_name: The name of the skill. + + Returns: + str: The content of the SKILL.md file. + """ + skill = self.get_skill(name=skill_name) + if not skill: + return f"Skill '{skill_name}' not found." + + # If the skill was loaded from a file, we might have the path stored somewhere. + # SkillMetadata doesn't strictly enforce a 'path' attribute, but let's check. + # Or we can try to find it via the loader mechanism if we had the path. + # For the sake of the example and current codebase state, let's look at metadata. + # If we can't find the file content easily from the object, we might need to rely + # on how it was loaded. + + # A workaround for the example: The Skill object usually has prompt_template. + # If it's a file-based skill, the prompt_template IS the content. + if skill.prompt_template: + # prompt_template might be a string or a Template object + if hasattr(skill.prompt_template, "template"): + return skill.prompt_template.template + return str(skill.prompt_template) + + return "No content available for this skill." + + def get_skill_scripts(self, skill_name: str) -> List[Dict[str, Any]]: + """Get scripts defined in a skill's configuration. + + Scripts are defined in the skill's config with the following format: + ```yaml + scripts: + - name: "script_name" + description: "Script description" + language: "python" + code: "..." + ``` + + Args: + skill_name: The name of the skill. + + Returns: + List of script definitions. + """ + skill = self.get_skill(name=skill_name) + if not skill: + return [] + + # Try to get scripts from skill's config + scripts = [] + + # Check if skill has config attribute (Skill class) + if hasattr(skill, "config") and skill.config: + config_scripts = skill.config.get("scripts", []) + if isinstance(config_scripts, list): + scripts.extend(config_scripts) + + # Check if skill has metadata with config (FileBasedSkill) + if hasattr(skill, "metadata") and skill.metadata: + metadata = skill.metadata + if hasattr(metadata, "config") and metadata.config: + config_scripts = metadata.config.get("scripts", []) + if isinstance(config_scripts, list): + # Avoid duplicates if already added from skill.config + existing_names = {s.get("name") for s in scripts} + for s in config_scripts: + if s.get("name") not in existing_names: + scripts.append(s) + + return scripts + + async def execute_script( + self, + skill_name: str, + script_name: str, + args: Optional[Dict[str, Any]] = None, + ) -> str: + """Execute a script defined in a skill. + + Args: + skill_name: The name of the skill containing the script. + script_name: The name of the script to execute. + args: Arguments to pass to the script. + + Returns: + JSON string with execution results. + """ + from dbgpt.util.code.server import get_code_server + + args = args or {} + + # Get the script + scripts = self.get_skill_scripts(skill_name) + script = next( + (s for s in scripts if s.get("name") == script_name), + None, + ) + + if not script: + return json.dumps( + { + "chunks": [ + { + "output_type": "text", + "content": f"Script '{script_name}' not found in skill '{skill_name}'", + } + ] + }, + ensure_ascii=False, + ) + + code = script.get("code", "") + language = script.get("language", "python") + + if not code: + return json.dumps( + { + "chunks": [ + { + "output_type": "text", + "content": f"Script '{script_name}' has no code", + } + ] + }, + ensure_ascii=False, + ) + + # Replace parameters in code using safe template substitution + # Use string.Template for safe substitution to avoid code injection + try: + from string import Template + + template = Template(code) + substituted_code = template.safe_substitute(**args) + except Exception as e: + return json.dumps( + { + "chunks": [ + { + "output_type": "text", + "content": f"Parameter substitution failed: {str(e)}", + } + ] + }, + ensure_ascii=False, + ) + + # Execute the code + try: + code_server = await get_code_server(self.system_app) + result = await code_server.exec(substituted_code, language) + output = ( + result.output.decode("utf-8") + if isinstance(result.output, bytes) + else str(result.output) + ) + error_output = ( + result.error_message.decode("utf-8") + if isinstance(result.error_message, bytes) + else str(result.error_message or "") + ) + + chunks: List[Dict[str, Any]] = [ + {"output_type": "code", "content": substituted_code} + ] + + if error_output: + chunks.append({"output_type": "text", "content": f"Error: {error_output}"}) + + if output: + chunks.append({"output_type": "text", "content": output}) + + return json.dumps({"chunks": chunks}, ensure_ascii=False) + except Exception as e: + return json.dumps( + { + "chunks": [ + { + "output_type": "text", + "content": f"Script execution failed: {str(e)}", + } + ] + }, + ensure_ascii=False, + ) + + +_SYSTEM_APP: Optional[SystemApp] = None + + +def initialize_skill(system_app: SystemApp): + """Initialize the skill manager.""" + global _SYSTEM_APP + _SYSTEM_APP = system_app + skill_manager = SkillManager(system_app) + system_app.register_instance(skill_manager) + + +def get_skill_manager(system_app: Optional[SystemApp] = None) -> SkillManager: + """Get the skill manager. + + Args: + system_app: System app instance. + + Returns: + SkillManager instance. + """ + global _SYSTEM_APP + if not _SYSTEM_APP: + if not system_app: + system_app = SystemApp() + initialize_skill(system_app) + app = system_app or _SYSTEM_APP + return SkillManager.get_instance(cast(SystemApp, app)) diff --git a/packages/dbgpt-core/src/dbgpt/agent/skill/middleware.py b/packages/dbgpt-core/src/dbgpt/agent/skill/middleware.py new file mode 100644 index 000000000..f1fe2dbdf --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/skill/middleware.py @@ -0,0 +1,480 @@ +"""Skills middleware for DB-GPT agents. + +This module implements progressive disclosure for skills, similar to +deepagents' SkillsMiddleware. Skills are loaded from configured sources +and their metadata is injected into system prompt, with full content +loaded on demand. +""" + +import dataclasses +import logging +import re +from pathlib import Path +from typing import Any, Dict, List, Optional + +from dbgpt.core import PromptTemplate + +logger = logging.getLogger(__name__) + +MAX_SKILL_FILE_SIZE = 10 * 1024 * 1024 +MAX_SKILL_NAME_LENGTH = 64 +MAX_SKILL_DESCRIPTION_LENGTH = 1024 + + +@dataclasses.dataclass +class SkillMetadata: + """Metadata for a skill.""" + + name: str + description: str + path: str + version: str = "1.0.0" + author: Optional[str] = None + skill_type: str = "custom" + tags: List[str] = dataclasses.field(default_factory=list) + license: Optional[str] = None + allowed_tools: List[str] = dataclasses.field(default_factory=list) + + def to_dict(self) -> Dict[str, Any]: + """Convert to dictionary.""" + return { + "name": self.name, + "description": self.description, + "path": self.path, + "version": self.version, + "author": self.author, + "skill_type": self.skill_type, + "tags": self.tags, + "license": self.license, + "allowed_tools": self.allowed_tools, + } + + +class LoadedSkill: + """A loaded skill with metadata and optional content.""" + + def __init__( + self, + metadata: SkillMetadata, + content: Optional[str] = None, + ): + """Initialize loaded skill. + + Args: + metadata: Skill metadata. + content: Full skill content (markdown instructions). + """ + self._metadata = metadata + self._content = content + + @property + def metadata(self) -> SkillMetadata: + """Return skill metadata.""" + return self._metadata + + @property + def content(self) -> Optional[str]: + """Return skill content.""" + if self._content is None and self._metadata.path: + try: + with open(self._metadata.path, "r", encoding="utf-8") as f: + self._content = f.read() + except Exception as e: + logger.error( + f"Failed to load skill content from {self._metadata.path}: {e}" + ) + return self._content + + def get_prompt_template(self) -> PromptTemplate: + """Get prompt template with skill instructions. + + Returns: + PromptTemplate with the skill's full instructions. + """ + content = ( + self.content or f"# {self.metadata.name}\n\n{self.metadata.description}" + ) + return PromptTemplate.from_template(content) + + +def _validate_skill_name(name: str) -> tuple[bool, str]: + """Validate skill name. + + Requirements: + - Max 64 characters + - Lowercase alphanumeric and hyphens only (a-z, 0-9, -) + - Cannot start or end with hyphen + - No consecutive hyphens + + Args: + name: Skill name to validate. + + Returns: + (is_valid, error_message) tuple. + """ + if not name: + return False, "name is required" + if len(name) > MAX_SKILL_NAME_LENGTH: + return False, "name exceeds 64 characters" + if not re.match(r"^[a-z0-9]+(-[a-z0-9]+)*$", name): + return False, "name must be lowercase alphanumeric with single hyphens only" + return True, "" + + +def _parse_skill_metadata( + content: str, skill_path: str, directory_name: str +) -> Optional[SkillMetadata]: + """Parse YAML frontmatter from SKILL.md content. + + Args: + content: Content of the SKILL.md file. + skill_path: Path to the SKILL.md file. + directory_name: Name of the parent directory. + + Returns: + SkillMetadata if parsing succeeds, None otherwise. + """ + if len(content) > MAX_SKILL_FILE_SIZE: + logger.warning( + "Skipping %s: content too large (%d bytes)", skill_path, len(content) + ) + return None + + frontmatter_pattern = r"^---\s*\n(.*?)\n---\s*\n" + match = re.match(frontmatter_pattern, content, re.DOTALL) + + if not match: + logger.warning("Skipping %s: no valid YAML frontmatter found", skill_path) + return None + + frontmatter_str = match.group(1) + + try: + import yaml + + frontmatter_data = yaml.safe_load(frontmatter_str) + except ImportError: + logger.error("PyYAML not installed, cannot parse SKILL.md files") + return None + except Exception as e: + logger.warning("Failed to parse YAML in %s: %s", skill_path, e) + return None + + if not isinstance(frontmatter_data, dict): + logger.warning("Skipping %s: frontmatter is not a mapping", skill_path) + return None + + name = frontmatter_data.get("name") + description = frontmatter_data.get("description") + + if not name or not description: + logger.warning( + "Skipping %s: missing required 'name' or 'description'", skill_path + ) + return None + + is_valid, error = _validate_skill_name(str(name)) + if not is_valid: + logger.warning( + "Skill '%s' in %s does not follow naming convention: %s", + name, + skill_path, + error, + ) + + description_str = str(description).strip() + if len(description_str) > MAX_SKILL_DESCRIPTION_LENGTH: + logger.warning( + "Description exceeds %d characters in %s, truncating", + MAX_SKILL_DESCRIPTION_LENGTH, + skill_path, + ) + description_str = description_str[:MAX_SKILL_DESCRIPTION_LENGTH] + + allowed_tools = [] + allowed_tools_value = frontmatter_data.get("allowed-tools") + if allowed_tools_value and isinstance(allowed_tools_value, str): + allowed_tools = allowed_tools_value.split(" ") + + return SkillMetadata( + name=str(name), + description=description_str, + path=skill_path, + version=frontmatter_data.get("version", "1.0.0"), + author=frontmatter_data.get("author", "").strip() or None, + license=frontmatter_data.get("license", "").strip() or None, + allowed_tools=allowed_tools, + skill_type=frontmatter_data.get("skill_type", "custom"), + tags=frontmatter_data.get("tags", []), + ) + + +def _list_skills_from_directory(source_path: str) -> List[SkillMetadata]: + """List all skills from a directory. + + Args: + source_path: Path to the skills directory. + + Returns: + List of skill metadata from successfully parsed SKILL.md files. + """ + skills: List[SkillMetadata] = [] + base_path = Path(source_path) + + if not base_path.exists() or not base_path.is_dir(): + logger.warning("Directory not found: %s", source_path) + return skills + + for skill_dir in base_path.iterdir(): + if not skill_dir.is_dir(): + continue + + skill_md_path = skill_dir / "SKILL.md" + if not skill_md_path.exists(): + continue + + try: + with open(skill_md_path, "r", encoding="utf-8") as f: + content = f.read() + + directory_name = skill_dir.name + skill_metadata = _parse_skill_metadata( + content=content, + skill_path=str(skill_md_path), + directory_name=directory_name, + ) + + if skill_metadata: + skills.append(skill_metadata) + + except Exception as e: + logger.warning("Failed to load skill from %s: %s", skill_md_path, e) + + return skills + + +SKILLS_SYSTEM_PROMPT = """ + +## Skills System + +You have access to a skills library that provides specialized capabilities and domain knowledge. + +{skills_locations} + +**Available Skills:** + +{skills_list} + +**How to Use Skills (Progressive Disclosure):** + +Skills follow a **progressive disclosure** pattern - you see their name and description above, but only read full instructions when needed: + +1. **Recognize when a skill applies**: Check if the user's task matches a skill's description +2. **Read the skill's full instructions**: Use the path shown in the skill list above +3. **Follow the skill's instructions**: SKILL.md contains step-by-step workflows, best practices, and examples +4. **Access supporting files**: Skills may include helper scripts, configs, or reference docs - use absolute paths + +**When to Use Skills:** +- User's request matches a skill's domain (e.g., "research X" -> web-research skill) +- You need specialized knowledge or structured workflows +- A skill provides proven patterns for complex tasks + +**Example Workflow:** + +User: "Can you research the latest developments in quantum computing?" + +1. Check available skills -> See "web-research" skill with its path +2. Read the skill using the path shown +3. Follow the skill's research workflow (search -> organize -> synthesize) +4. Use any helper scripts with absolute paths + +Remember: Skills make you more capable and consistent. When in doubt, check if a skill exists for the task! +""" + + +class SkillsMiddleware: + """Middleware for loading and exposing agent skills to the system prompt. + + Loads skills from sources and injects them into the system prompt + using progressive disclosure (metadata first, full content on demand). + + Example: + ```python + middleware = SkillsMiddleware( + sources=[ + "/path/to/skills/user/", + "/path/to/skills/project/", + ], + ) + ``` + """ + + def __init__(self, sources: List[str]): + """Initialize the skills middleware. + + Args: + sources: List of skill source paths. + """ + self.sources = sources + self._skills: Dict[str, LoadedSkill] = {} + self._loaded = False + + def load_skills(self) -> Dict[str, LoadedSkill]: + """Load skills from all configured sources. + + Skills are loaded in source order with later sources overriding + earlier ones if they contain skills with the same name. + + Returns: + Dictionary of loaded skills keyed by name. + """ + if self._loaded: + return self._skills + + all_skills: Dict[str, LoadedSkill] = {} + + for source_path in self.sources: + source_skills = _list_skills_from_directory(source_path) + for skill_metadata in source_skills: + loaded_skill = LoadedSkill(metadata=skill_metadata) + all_skills[skill_metadata.name] = loaded_skill + + self._skills = all_skills + self._loaded = True + return self._skills + + def get_skill(self, name: str) -> Optional[LoadedSkill]: + """Get a skill by name. + + Args: + name: Skill name. + + Returns: + LoadedSkill or None. + """ + if not self._loaded: + self.load_skills() + + return self._skills.get(name) + + def list_skills(self) -> List[SkillMetadata]: + """List all loaded skills. + + Returns: + List of skill metadata. + """ + if not self._loaded: + self.load_skills() + + return [skill.metadata for skill in self._skills.values()] + + def format_skills_locations(self) -> str: + """Format skills locations for display in system prompt. + + Returns: + Formatted string of skills locations. + """ + locations = [] + for i, source_path in enumerate(self.sources): + name = Path(source_path.rstrip("/")).name.capitalize() + suffix = " (higher priority)" if i == len(self.sources) - 1 else "" + locations.append(f"**{name} Skills**: `{source_path}`{suffix}") + return "\n".join(locations) + + def format_skills_list(self) -> str: + """Format skills metadata for display in system prompt. + + Returns: + Formatted string of skills list. + """ + if not self._loaded: + self.load_skills() + + if not self._skills: + paths = [f"`{source_path}`" for source_path in self.sources] + return f"(No skills available yet. You can create skills in {' or '.join(paths)})" + + lines = [] + for skill in self._skills.values(): + lines.append(f"- **{skill.metadata.name}**: {skill.metadata.description}") + lines.append(f" -> Read `{skill.metadata.path}` for full instructions") + + return "\n".join(lines) + + def create_skills_prompt_section(self) -> str: + """Create the skills section for the system prompt. + + Returns: + Formatted skills system prompt section. + """ + skills_locations = self.format_skills_locations() + skills_list = self.format_skills_list() + + return SKILLS_SYSTEM_PROMPT.format( + skills_locations=skills_locations, + skills_list=skills_list, + ) + + def get_skills_by_type(self, skill_type: str) -> List[LoadedSkill]: + """Get skills by type. + + Args: + skill_type: Skill type to filter by. + + Returns: + List of matching skills. + """ + if not self._loaded: + self.load_skills() + + return [ + skill + for skill in self._skills.values() + if skill.metadata.skill_type == skill_type + ] + + def match_skills(self, user_input: str) -> List[LoadedSkill]: + """Find skills that match user input based on description. + + Args: + user_input: User input string. + + Returns: + List of matching skills. + """ + if not self._loaded: + self.load_skills() + + user_input_lower = user_input.lower() + matches = [] + + for skill in self._skills.values(): + description_lower = skill.metadata.description.lower() + + keywords = self._extract_keywords(description_lower) + for keyword in keywords: + if keyword in user_input_lower: + matches.append(skill) + break + + return matches + + def _extract_keywords(self, description: str) -> List[str]: + """Extract potential trigger keywords from description. + + Args: + description: Skill description. + + Returns: + List of keywords. + """ + keywords = [] + + pattern = r"(?:when|use|for|to)\s+(?:the\s+)?(?:user\s+)?(?:asks|requests|wants|needs)?\s*(?:to\s+)?([a-z\s]+?)(?:\s*(?:\.|,|;|or|\(|\)|use when|$))" + matches = re.findall(pattern, description, re.IGNORECASE) + + for match in matches: + words = [w.strip() for w in match.split() if len(w.strip()) > 2] + keywords.extend(words) + + return list(set(keywords)) diff --git a/packages/dbgpt-core/src/dbgpt/agent/skill/middleware_v2.py b/packages/dbgpt-core/src/dbgpt/agent/skill/middleware_v2.py new file mode 100644 index 000000000..5856fca0f --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/skill/middleware_v2.py @@ -0,0 +1,214 @@ +"""Skills middleware using the new middleware system. + +This module implements SkillsMiddleware as an AgentMiddleware, following +deepagents' pattern with lifecycle hooks. +""" + +import logging +from typing import Any, Dict, List, Optional + +from ..middleware.base import AgentMiddleware +from .middleware import LoadedSkill, SkillsMiddleware as BaseSkillsMiddleware + +logger = logging.getLogger(__name__) + + +class SkillsMiddlewareV2(AgentMiddleware): + """Skills middleware using AgentMiddleware pattern. + + Integrates with the middleware system to inject skills into the agent + lifecycle, similar to deepagents' SkillsMiddleware. + + Example: + ```python + from dbgpt.agent.middleware.base import MiddlewareManager + from dbgpt.agent.skill.middleware_v2 import SkillsMiddlewareV2 + + middleware = SkillsMiddlewareV2( + sources=["/path/to/skills/user", "/path/to/skills/project"] + ) + manager = MiddlewareManager() + manager.register(middleware) + ``` + """ + + def __init__( + self, + sources: List[str], + auto_load: bool = True, + auto_match: bool = True, + inject_to_system_prompt: bool = True, + ): + """Initialize the skills middleware. + + Args: + sources: List of skill source paths. + auto_load: Automatically load skills on initialization. + auto_match: Automatically match skills based on user input. + inject_to_system_prompt: Inject skills into system prompt. + """ + super().__init__() + self.sources = sources + self.auto_load = auto_load + self.auto_match = auto_match + self.inject_to_system_prompt = inject_to_system_prompt + + self._base_middleware = BaseSkillsMiddleware(sources=sources) + self._loaded = False + + if auto_load: + self.load_skills() + + def load_skills(self) -> Dict[str, LoadedSkill]: + """Load skills from all configured sources. + + Returns: + Dictionary of loaded skills keyed by name. + """ + self._loaded = True + return self._base_middleware.load_skills() + + def get_skill(self, name: str) -> Optional[LoadedSkill]: + """Get a skill by name. + + Args: + name: Skill name. + + Returns: + LoadedSkill or None. + """ + if not self._loaded: + self.load_skills() + return self._base_middleware.get_skill(name) + + def list_skills(self) -> List: + """List all loaded skills. + + Returns: + List of skill metadata. + """ + if not self._loaded: + self.load_skills() + return self._base_middleware.list_skills() + + def match_skills(self, user_input: str) -> List[LoadedSkill]: + """Find skills that match user input. + + Args: + user_input: User input string. + + Returns: + List of matching skills. + """ + if not self._loaded: + self.load_skills() + return self._base_middleware.match_skills(user_input) + + async def after_init(self, agent, **kwargs) -> Optional[Dict[str, Any]]: + """Called after agent initialization. + + Loads skills and stores them in middleware state. + + Args: + agent: The agent instance. + **kwargs: Additional arguments. + + Returns: + State with skills metadata. + """ + logger.info(f"SkillsMiddlewareV2: after_init for {agent.__class__.__name__}") + + if self.auto_load: + skills = self.load_skills() + logger.info(f"Loaded {len(skills)} skills from {self.sources}") + return { + "skills_loaded": True, + "skills_count": len(skills), + "skills_sources": self.sources, + } + return {} + + async def before_generate_reply( + self, + agent, + context, + **kwargs, + ) -> Optional[Dict[str, Any]]: + """Called before generating a reply. + + Matches skills based on user input if auto_match is enabled. + + Args: + agent: The agent instance. + context: The generate context. + **kwargs: Additional arguments. + + Returns: + State with matched skills. + """ + if not self.auto_match or not context.message: + return {} + + user_input = context.message.content or "" + if user_input: + matched_skills = self.match_skills(user_input) + if matched_skills: + logger.info( + f"Matched {len(matched_skills)} skills for input: {user_input[:50]}..." + ) + return { + "matched_skills": [s.metadata.name for s in matched_skills], + "matched_skills_count": len(matched_skills), + } + return {} + + async def modify_system_prompt( + self, + agent, + original_prompt: str, + context: Optional[Dict[str, Any]] = None, + ) -> str: + """Modify the system prompt with skills information. + + Args: + agent: The agent instance. + original_prompt: The original system prompt. + context: Additional context information. + + Returns: + Modified system prompt with skills section. + """ + if not self.inject_to_system_prompt: + return original_prompt + + if not self._loaded: + self.load_skills() + + skills_section = self._base_middleware.create_skills_prompt_section() + + if original_prompt: + modified = f"{skills_section}\n\n{original_prompt}" + else: + modified = skills_section + + return modified + + def get_skills_summary(self) -> str: + """Get a summary of available skills. + + Returns: + Formatted summary string. + """ + all_skills = self.list_skills() + summary = f"Total Skills: {len(all_skills)}\n" + summary += f"Sources: {', '.join(self.sources)}\n\n" + summary += "**Available Skills:**\n" + for skill_metadata in all_skills: + summary += f" - {skill_metadata.name}: {skill_metadata.description}\n" + + return summary + + +__all__ = [ + "SkillsMiddlewareV2", +] diff --git a/packages/dbgpt-core/src/dbgpt/agent/skill/parameters.py b/packages/dbgpt-core/src/dbgpt/agent/skill/parameters.py new file mode 100644 index 000000000..bfe7e6766 --- /dev/null +++ b/packages/dbgpt-core/src/dbgpt/agent/skill/parameters.py @@ -0,0 +1,34 @@ +"""Skill parameters classes.""" + +import dataclasses +from typing import Any, Dict, List, Optional + +from dbgpt.agent.resource.base import ResourceParameters +from .base import SkillType + + +@dataclasses.dataclass +class SkillParameters(ResourceParameters): + """Skill resource parameters class.""" + + skill_name: str = dataclasses.field( + default=None, metadata={"help": "Name of the skill to load"} + ) + skill_type: Optional[SkillType] = dataclasses.field( + default=None, metadata={"help": "Type of the skill"} + ) + skill_version: Optional[str] = dataclasses.field( + default=None, metadata={"help": "Version of the skill"} + ) + skill_config: Optional[Dict[str, Any]] = dataclasses.field( + default=None, metadata={"help": "Additional skill configuration"} + ) + load_tools: bool = dataclasses.field( + default=True, metadata={"help": "Whether to load required tools"} + ) + load_knowledge: bool = dataclasses.field( + default=True, metadata={"help": "Whether to load required knowledge"} + ) + load_actions: bool = dataclasses.field( + default=True, metadata={"help": "Whether to load actions"} + ) diff --git a/pilot/tmp/3d078afb-ec04-4a89-a4f2-d49e180969be/balance_data.csv b/pilot/tmp/3d078afb-ec04-4a89-a4f2-d49e180969be/balance_data.csv new file mode 100644 index 000000000..52dc24315 --- /dev/null +++ b/pilot/tmp/3d078afb-ec04-4a89-a4f2-d49e180969be/balance_data.csv @@ -0,0 +1,4 @@ +年份,总资产,流动资产,非流动资产,总负债,流动负债,非流动负债,所有者权益,资产负债率(%) +2017,85000,45000,40000,35000,25000,10000,50000,41.18 +2018,95000,52000,43000,40000,28000,12000,55000,42.11 +2019,110000,60000,50000,48000,35000,13000,62000,43.64 diff --git a/pilot/tmp/3d078afb-ec04-4a89-a4f2-d49e180969be/cashflow_data.csv b/pilot/tmp/3d078afb-ec04-4a89-a4f2-d49e180969be/cashflow_data.csv new file mode 100644 index 000000000..4a1f23dea --- /dev/null +++ b/pilot/tmp/3d078afb-ec04-4a89-a4f2-d49e180969be/cashflow_data.csv @@ -0,0 +1,4 @@ +年份,经营活动现金流量净额,投资活动现金流量净额,筹资活动现金流量净额,现金及现金等价物净增加额 +2017,3800,-2500,1000,2300 +2018,4200,-3000,1500,2700 +2019,5200,-3500,2000,3700 diff --git a/pilot/tmp/3d078afb-ec04-4a89-a4f2-d49e180969be/profit_data.csv b/pilot/tmp/3d078afb-ec04-4a89-a4f2-d49e180969be/profit_data.csv new file mode 100644 index 000000000..4008af08b --- /dev/null +++ b/pilot/tmp/3d078afb-ec04-4a89-a4f2-d49e180969be/profit_data.csv @@ -0,0 +1,4 @@ +年份,营业收入,营业成本,营业利润,利润总额,净利润,毛利率(%),净利率(%) +2017,32000,22000,4500,4600,3900,31.25,12.19 +2018,38000,26000,5500,5600,4800,31.58,12.63 +2019,45000,31000,6800,6900,5900,31.11,13.11 diff --git a/skills.py b/skills.py new file mode 100644 index 000000000..ce5c6ec82 --- /dev/null +++ b/skills.py @@ -0,0 +1,553 @@ +"""Skills module for DB-GPT agents. + +This module provides skills loading mechanism for agents, following the +progressive disclosure pattern similar to deepagents' SkillsMiddleware. +""" + +import logging +import re +from dataclasses import dataclass, field +from pathlib import Path +from typing import Any, Dict, List, Optional, Set + +from dbgpt.core import PromptTemplate + +logger = logging.getLogger(__name__) + +MAX_SKILL_FILE_SIZE = 10 * 1024 * 1024 +MAX_SKILL_NAME_LENGTH = 64 +MAX_SKILL_DESCRIPTION_LENGTH = 1024 + + +@dataclass +class SkillMetadata: + """Metadata for a skill.""" + + name: str + description: str + path: str + version: str = "1.0.0" + author: Optional[str] = None + skill_type: str = "custom" + tags: List[str] = field(default_factory=list) + license: Optional[str] = None + allowed_tools: List[str] = field(default_factory=list) + + def to_dict(self) -> Dict[str, Any]: + """Convert to dictionary.""" + return { + "name": self.name, + "description": self.description, + "path": self.path, + "version": self.version, + "author": self.author, + "skill_type": self.skill_type, + "tags": self.tags, + "license": self.license, + "allowed_tools": self.allowed_tools, + } + + +@dataclass +class LoadedSkill: + """A loaded skill with metadata and optional content.""" + + def __init__( + self, + metadata: SkillMetadata, + content: Optional[str] = None, + ): + """Initialize loaded skill. + + Args: + metadata: Skill metadata. + content: Full skill content (markdown instructions). + """ + self._metadata = metadata + self._content = content + + @property + def metadata(self) -> SkillMetadata: + """Return skill metadata.""" + return self._metadata + + @property + def prompt_content(self) -> str: + """Get the skill content for prompt injection.""" + if self._content is None and self._metadata.path: + try: + with open(self._metadata.path, "r", encoding="utf-8") as f: + self._content = f.read() + except Exception as e: + logger.error( + f"Failed to load skill content from {self._metadata.path}: {e}" + ) + self._content = ( + f"# {self._metadata.name}\n\n{self._metadata.description}" + ) + return ( + self._content or f"# {self._metadata.name}\n\n{self._metadata.description}" + ) + + def get_prompt_template(self) -> PromptTemplate: + """Get prompt template with skill instructions. + + Returns: + PromptTemplate with the skill's full instructions. + """ + return PromptTemplate.from_template(self.prompt_content) + + +class SkillsLoader: + """Loader for skills from filesystem sources.""" + + def __init__(self, sources: List[str]): + """Initialize skills loader. + + Args: + sources: List of skill source paths. + """ + self.sources = sources + self._skills: Dict[str, LoadedSkill] = {} + self._loaded = False + + def load_skills(self) -> Dict[str, LoadedSkill]: + """Load skills from all configured sources. + + Skills are loaded in source order with later sources overriding + earlier ones if they contain skills with the same name. + + Returns: + Dictionary of loaded skills keyed by name. + """ + if self._loaded: + return self._skills + + all_skills: Dict[str, LoadedSkill] = {} + + for source_path in self.sources: + source_skills = _list_skills_from_directory(source_path) + for skill_metadata in source_skills: + loaded_skill = LoadedSkill(metadata=skill_metadata) + all_skills[skill_metadata.name] = loaded_skill + + self._skills = all_skills + self._loaded = True + return self._skills + + def get_skill(self, name: str) -> Optional[LoadedSkill]: + """Get a skill by name. + + Args: + name: Skill name. + + Returns: + LoadedSkill or None. + """ + if not self._loaded: + self.load_skills() + return self._skills.get(name) + + def list_skills(self) -> List[SkillMetadata]: + """List all loaded skills. + + Returns: + List of skill metadata. + """ + if not self._loaded: + self.load_skills() + return [skill.metadata for skill in self._skills.values()] + + def get_skills_by_type(self, skill_type: str) -> List[LoadedSkill]: + """Get skills by type. + + Args: + skill_type: Skill type to filter by. + + Returns: + List of matching skills. + """ + if not self._loaded: + self.load_skills() + return [ + skill + for skill in self._skills.values() + if skill.metadata.skill_type == skill_type + ] + + def match_skills(self, user_input: str) -> List[LoadedSkill]: + """Find skills that match user input based on description. + + Args: + user_input: User input string. + + Returns: + List of matching skills. + """ + if not self._loaded: + self.load_skills() + + user_input_lower = user_input.lower() + matches = [] + + for skill in self._skills.values(): + description_lower = skill.metadata.description.lower() + keywords = _extract_keywords(description_lower) + for keyword in keywords: + if keyword in user_input_lower: + matches.append(skill) + break + + return matches + + +def _validate_skill_name(name: str) -> tuple[bool, str]: + """Validate skill name. + + Requirements: + - Max 64 characters + - Lowercase alphanumeric and hyphens only (a-z, 0-9, -) + - Cannot start or end with hyphen + - No consecutive hyphens + + Args: + name: Skill name to validate. + + Returns: + (is_valid, error_message) tuple. + """ + if not name: + return False, "name is required" + if len(name) > MAX_SKILL_NAME_LENGTH: + return False, "name exceeds 64 characters" + if not re.match(r"^[a-z0-9]+(-[a-z0-9]+)*$", name): + return False, "name must be lowercase alphanumeric with single hyphens only" + return True, "" + + +def _parse_skill_metadata( + content: str, skill_path: str, directory_name: str +) -> Optional[SkillMetadata]: + """Parse YAML frontmatter from SKILL.md content. + + Args: + content: Content of the SKILL.md file. + skill_path: Path to the SKILL.md file. + directory_name: Name of the parent directory. + + Returns: + SkillMetadata if parsing succeeds, None otherwise. + """ + if len(content) > MAX_SKILL_FILE_SIZE: + logger.warning( + "Skipping %s: content too large (%d bytes)", skill_path, len(content) + ) + return None + + frontmatter_pattern = r"^---\s*\n(.*?)\n---\s*\n" + match = re.match(frontmatter_pattern, content, re.DOTALL) + + if not match: + logger.warning("Skipping %s: no valid YAML frontmatter found", skill_path) + return None + + frontmatter_str = match.group(1) + + try: + import yaml + + frontmatter_data = yaml.safe_load(frontmatter_str) + except ImportError: + logger.error("PyYAML not installed, cannot parse SKILL.md files") + return None + except Exception as e: + logger.warning("Failed to parse YAML in %s: %s", skill_path, e) + return None + + if not isinstance(frontmatter_data, dict): + logger.warning("Skipping %s: frontmatter is not a mapping", skill_path) + return None + + name = frontmatter_data.get("name") + description = frontmatter_data.get("description") + + if not name or not description: + logger.warning( + "Skipping %s: missing required 'name' or 'description'", skill_path + ) + return None + + is_valid, error = _validate_skill_name(str(name)) + if not is_valid: + logger.warning( + "Skill '%s' in %s does not follow naming convention: %s", + name, + skill_path, + error, + ) + + description_str = str(description).strip() + if len(description_str) > MAX_SKILL_DESCRIPTION_LENGTH: + logger.warning( + "Description exceeds %d characters in %s, truncating", + MAX_SKILL_DESCRIPTION_LENGTH, + skill_path, + ) + description_str = description_str[:MAX_SKILL_DESCRIPTION_LENGTH] + + allowed_tools = [] + allowed_tools_value = frontmatter_data.get("allowed-tools") + if allowed_tools_value and isinstance(allowed_tools_value, str): + allowed_tools = allowed_tools_value.split(" ") + + return SkillMetadata( + name=str(name), + description=description_str, + path=skill_path, + version=frontmatter_data.get("version", "1.0.0"), + author=frontmatter_data.get("author", "").strip() or None, + license=frontmatter_data.get("license", "").strip() or None, + allowed_tools=allowed_tools, + skill_type=frontmatter_data.get("skill_type", "custom"), + tags=frontmatter_data.get("tags", []), + ) + + +def _list_skills_from_directory(source_path: str) -> List[SkillMetadata]: + """List all skills from a directory. + + Args: + source_path: Path to the skills directory. + + Returns: + List of skill metadata from successfully parsed SKILL.md files. + """ + skills: List[SkillMetadata] = [] + base_path = Path(source_path) + + if not base_path.exists() or not base_path.is_dir(): + logger.warning("Directory not found: %s", source_path) + return skills + + for skill_dir in base_path.iterdir(): + if not skill_dir.is_dir(): + continue + + skill_md_path = skill_dir / "SKILL.md" + if not skill_md_path.exists(): + continue + + try: + with open(skill_md_path, "r", encoding="utf-8") as f: + content = f.read() + + directory_name = skill_dir.name + skill_metadata = _parse_skill_metadata( + content=content, + skill_path=str(skill_md_path), + directory_name=directory_name, + ) + + if skill_metadata: + skills.append(skill_metadata) + + except Exception as e: + logger.warning("Failed to load skill from %s: %s", skill_md_path, e) + + return skills + + +def _extract_keywords(description: str) -> List[str]: + """Extract potential trigger keywords from description. + + Args: + description: Skill description. + + Returns: + List of keywords. + """ + keywords = [] + + pattern = r"(?:when|use|for|to)\s+(?:the\s+)?(?:user\s+)?(?:asks|requests|wants|needs)?\s*(?:to\s+)?([a-z\s]+?)(?:\s*(?:\.|,|;|or|\(|\)|use when|$))" + matches = re.findall(pattern, description, re.IGNORECASE) + + for match in matches: + words = [w.strip() for w in match.split() if len(w.strip()) > 2] + keywords.extend(words) + + return list(set(keywords)) + + +SKILLS_SYSTEM_PROMPT = """ + +## Skills System + +You have access to a skills library that provides specialized capabilities and domain knowledge. + +{skills_locations} + +**Available Skills:** + +{skills_list} + +**How to Use Skills (Progressive Disclosure):** + +Skills follow a **progressive disclosure** pattern - you see their name and description above, but only read full instructions when needed: + +1. **Recognize when a skill applies**: Check if the user's task matches a skill's description +2. **Read the skill's full instructions**: Use the path shown in the skill list above +3. **Follow the skill's instructions**: SKILL.md contains step-by-step workflows, best practices, and examples +4. **Access supporting files**: Skills may include helper scripts, configs, or reference docs - use absolute paths + +**When to Use Skills:** +- User's request matches a skill's domain (e.g., "research X" -> web-research skill) +- You need specialized knowledge or structured workflows +- A skill provides proven patterns for complex tasks + +**Example Workflow:** + +User: "Can you research the latest developments in quantum computing?" + +1. Check available skills -> See "web-research" skill with its path +2. Read the skill using the path shown +3. Follow the skill's research workflow (search -> organize -> synthesize) +4. Use any helper scripts with absolute paths + +Remember: Skills make you more capable and consistent. When in doubt, check if a skill exists for the task! +""" + + +class SkillsMiddleware: + """Middleware for loading and exposing agent skills to the system prompt. + + Loads skills from sources and injects them into the system prompt + using progressive disclosure (metadata first, full content on demand). + + Example: + ```python + from skills import SkillsMiddleware + + middleware = SkillsMiddleware( + sources=[ + "/path/to/skills/user/", + "/path/to/skills/project/", + ], + ) + ``` + """ + + def __init__(self, sources: List[str]): + """Initialize the skills middleware. + + Args: + sources: List of skill source paths. + """ + self.sources = sources + self._loader = SkillsLoader(sources) + + def load_skills(self) -> Dict[str, LoadedSkill]: + """Load skills from all configured sources. + + Returns: + Dictionary of loaded skills keyed by name. + """ + return self._loader.load_skills() + + def get_skill(self, name: str) -> Optional[LoadedSkill]: + """Get a skill by name. + + Args: + name: Skill name. + + Returns: + LoadedSkill or None. + """ + return self._loader.get_skill(name) + + def list_skills(self) -> List[SkillMetadata]: + """List all loaded skills. + + Returns: + List of skill metadata. + """ + return self._loader.list_skills() + + def format_skills_locations(self) -> str: + """Format skills locations for display in system prompt. + + Returns: + Formatted string of skills locations. + """ + locations = [] + for i, source_path in enumerate(self.sources): + name = Path(source_path.rstrip("/")).name.capitalize() + suffix = " (higher priority)" if i == len(self.sources) - 1 else "" + locations.append(f"**{name} Skills**: `{source_path}`{suffix}") + return "\n".join(locations) + + def format_skills_list(self) -> str: + """Format skills metadata for display in system prompt. + + Returns: + Formatted string of skills list. + """ + skills = self._loader.list_skills() + + if not skills: + paths = [f"`{source_path}`" for source_path in self.sources] + return f"(No skills available yet. You can create skills in {' or '.join(paths)})" + + lines = [] + for skill in skills: + lines.append(f"- **{skill.name}**: {skill.description}") + lines.append(f" -> Read `{skill.path}` for full instructions") + + return "\n".join(lines) + + def create_skills_prompt_section(self) -> str: + """Create the skills section for the system prompt. + + Returns: + Formatted skills system prompt section. + """ + skills_locations = self.format_skills_locations() + skills_list = self.format_skills_list() + + return SKILLS_SYSTEM_PROMPT.format( + skills_locations=skills_locations, + skills_list=skills_list, + ) + + def get_skills_by_type(self, skill_type: str) -> List[LoadedSkill]: + """Get skills by type. + + Args: + skill_type: Skill type to filter by. + + Returns: + List of matching skills. + """ + return self._loader.get_skills_by_type(skill_type) + + def match_skills(self, user_input: str) -> List[LoadedSkill]: + """Find skills that match user input based on description. + + Args: + user_input: User input string. + + Returns: + List of matching skills. + """ + return self._loader.match_skills(user_input) + + +def create_skills_middleware(sources: List[str]) -> SkillsMiddleware: + """Factory function to create a skills middleware instance. + + Args: + sources: List of skill source paths. + + Returns: + SkillsMiddleware instance. + """ + return SkillsMiddleware(sources=sources) diff --git a/skills/INTEGRATION_GUIDE.md b/skills/INTEGRATION_GUIDE.md new file mode 100644 index 000000000..709e6c5f9 --- /dev/null +++ b/skills/INTEGRATION_GUIDE.md @@ -0,0 +1,296 @@ +# SKILL 机制集成指南 + +本文档说明如何将 SKILL 机制集成到现有的 DB-GPT agent 中。 + +## 集成步骤 + +### 1. 导入 SKILL 模块 + +在需要使用 SKILL 的文件中添加导入: + +```python +from dbgpt.agent.skill import ( + Skill, + SkillBuilder, + SkillLoader, + SkillManager, + SkillType, + get_skill_manager, + initialize_skill, +) +``` + +### 2. 修改 Agent 类以支持 Skill + +在你的 Agent 类中添加 Skill 支持: + +```python +from dbgpt.agent.expand.tool_assistant_agent import ToolAssistantAgent +from dbgpt.agent.skill import Skill + +class SkillEnabledAgent(ToolAssistantAgent): + def __init__(self, skill: Optional[Skill] = None, **kwargs): + super().__init__(**kwargs) + self._skill = skill + + if self._skill: + self._apply_skill_to_profile() + + @property + def skill(self) -> Optional[Skill]: + return self._skill + + def _apply_skill_to_profile(self): + """应用 Skill 配置到 Agent profile。""" + if self.skill.prompt_template: + self.bind_prompt = self.skill.prompt_template + + if self.profile: + self.profile.goal = self.skill.metadata.description + + async def load_resource(self, question: str, is_retry_chat: bool = False): + """加载 Skill 所需的资源。""" + if self.skill: + await self._load_skill_resources() + return await super().load_resource(question, is_retry_chat) + + async def _load_skill_resources(self): + """加载 Skill 所需的工具和知识。""" + if not self.resource: + return + + # 检查必需的工具 + if self.skill.required_tools: + available_tools = self.resource.get_resource_by_type("tool") + available_tool_names = [t.name for t in available_tools] + + for required_tool in self.skill.required_tools: + if required_tool not in available_tool_names: + raise ValueError( + f"Required tool '{required_tool}' not found. " + f"Available tools: {available_tool_names}" + ) + + # 检查必需的知识库 + if self.skill.required_knowledge: + available_knowledge = self.resource.get_resource_by_type("knowledge") + available_knowledge_names = [k.name for k in available_knowledge] + + for required_knowledge in self.skill.required_knowledge: + if required_knowledge not in available_knowledge_names: + raise ValueError( + f"Required knowledge '{required_knowledge}' not found. " + f"Available knowledge: {available_knowledge_names}" + ) +``` + +### 3. 初始化 Skill Manager + +在应用启动时初始化 Skill Manager: + +```python +from dbgpt.component import SystemApp + +def initialize_app(): + system_app = SystemApp() + initialize_skill(system_app) + return system_app +``` + +### 4. 注册 Skill + +```python +from dbgpt.agent.skill import get_skill_manager + +def register_my_skills(system_app): + skill_manager = get_skill_manager(system_app) + + # 创建并注册 Skill + skill = ( + SkillBuilder(name="my_skill", description="My skill description") + .with_skill_type(SkillType.Chat) + .with_prompt_template("You are a helpful assistant.") + .build() + ) + + skill_manager.register_skill( + skill_instance=skill, + name="my_skill", + ) +``` + +### 5. 使用 Skill 创建 Agent + +```python +from dbgpt.agent import AgentContext, LLMConfig, AgentMemory + +async def create_agent_with_skill(): + # 获取 Skill + skill_manager = get_skill_manager() + skill = skill_manager.get_skill(name="my_skill") + + # 创建 Agent + agent = SkillEnabledAgent(skill=skill) + + # 绑定配置 + context = AgentContext(conv_id="test_conv") + llm_config = LLMConfig() + memory = AgentMemory() + + await agent.bind(context).bind(llm_config).bind(memory).build() + + return agent +``` + +## 修改现有 Agent 示例 + +### 示例:修改 IntentRecognitionAgent + +原始文件:`packages/dbgpt-serve/src/dbgpt_serve/agent/agents/expand/intent_recognition_agent.py` + +```python +import logging +from dbgpt.agent import ConversableAgent, get_agent_manager +from dbgpt.agent.core.profile import DynConfig, ProfileConfig +from dbgpt.agent.skill import Skill +from dbgpt_serve.agent.agents.expand.actions.intent_recognition_action import ( + IntentRecognitionAction, +) + +class IntentRecognitionAgent(ConversableAgent): + profile: ProfileConfig = ProfileConfig(...) + + def __init__(self, skill: Optional[Skill] = None, **kwargs): + super().__init__(**kwargs) + self._skill = skill + self._init_actions([IntentRecognitionAction]) + + if self._skill: + self._apply_skill_to_profile() + + @property + def skill(self) -> Optional[Skill]: + return self._skill + + def _apply_skill_to_profile(self): + if self.skill and self.skill.prompt_template: + self.bind_prompt = self.skill.prompt_template + +agent_manage = get_agent_manager() +agent_manage.register_agent(IntentRecognitionAgent) +``` + +## SKILL 文件格式 + +### JSON 格式 + +```json +{ + "metadata": { + "name": "intent_recognition", + "description": "Intent recognition skill for user queries", + "version": "1.0.0", + "author": "DB-GPT Team", + "skill_type": "custom", + "tags": ["intent", "recognition", "nlp"] + }, + "prompt_template": "You are an intent recognition expert. Analyze user queries and identify their intents.", + "required_tools": [], + "required_knowledge": [], + "config": { + "max_intents": 10, + "enable_slot_filling": true + } +} +``` + +### Python 格式 + +```python +from dbgpt.agent.skill import Skill, SkillMetadata, SkillType +from dbgpt.core import PromptTemplate + +class IntentRecognitionSkill(Skill): + def __init__(self): + metadata = SkillMetadata( + name="intent_recognition", + description="Intent recognition skill", + version="1.0.0", + skill_type=SkillType.Custom, + tags=["intent", "recognition"], + ) + prompt = PromptTemplate.from_template( + "You are an intent recognition expert." + ) + super().__init__( + metadata=metadata, + prompt_template=prompt, + config={"max_intents": 10}, + ) +``` + +## 测试 SKILL 集成 + +```python +import pytest +from dbgpt.agent.skill import SkillBuilder, SkillType + +def test_skill_integration(): + # 创建 Skill + skill = ( + SkillBuilder(name="test_skill", description="Test skill") + .build() + ) + + # 创建 Agent + agent = SkillEnabledAgent(skill=skill) + + # 验证 + assert agent.skill is not None + assert agent.skill.metadata.name == "test_skill" +``` + +## 最佳实践 + +1. **分离关注点**:Skill 应该专注于特定领域的能力 +2. **版本管理**:为 Skill 使用语义化版本号 +3. **依赖声明**:清晰声明 Skill 所需的工具和知识 +4. **文档完善**:为 Skill 编写详细的文档和示例 +5. **测试覆盖**:为每个 Skill 编写单元测试 + +## 常见问题 + +### Q: 如何动态切换 Skill? + +A: 在 Agent 中添加 `switch_skill` 方法: + +```python +def switch_skill(self, skill: Skill): + self._skill = skill + self._apply_skill_to_profile() +``` + +### Q: Skill 可以包含多个工具吗? + +A: 可以,使用 `with_required_tool` 多次添加: + +```python +skill = ( + SkillBuilder(name="multi_tool", description="Multi tool skill") + .with_required_tool("tool1") + .with_required_tool("tool2") + .with_required_tool("tool3") + .build() +) +``` + +### Q: 如何从文件加载 Skill? + +A: 使用 `SkillLoader`: + +```python +from dbgpt.agent.skill import SkillLoader + +loader = SkillLoader() +skill = loader.load_skill_from_file("path/to/skill.json") +``` diff --git a/skills/README.md b/skills/README.md new file mode 100644 index 000000000..7411f4aad --- /dev/null +++ b/skills/README.md @@ -0,0 +1,287 @@ +# SKILL 机制 - DB-GPT Agent 技能加载系统 + +## 概述 + +SKILL 机制是 DB-GPT Agent 框架的高级特性,允许 Agent 加载和管理预定义的技能包,实现 Agent 能力的模块化和可复用性。 + +## 核心文件 + +``` +packages/dbgpt-core/src/dbgpt/agent/skill/ +├── __init__.py # 模块入口,导出主要类 +├── base.py # Skill 基础类定义 +├── parameters.py # Skill 参数类 +├── manage.py # Skill 管理器 +└── loader.py # Skill 加载器和构建器 +``` + +## 主要特性 + +### 1. Skill 定义 + +Skill 包含以下组件: +- **Metadata**:技能元信息(名称、描述、版本、类型、标签) +- **Prompt Template**:系统提示词模板 +- **Required Tools**:所需的工具列表 +- **Required Knowledge**:所需的知识库列表 +- **Actions**:可执行的动作 +- **Config**:特定配置参数 + +### 2. Skill 类型 + +| 类型 | 说明 | +|------|------| +| `Coding` | 编程技能 | +| `DataAnalysis` | 数据分析技能 | +| `WebSearch` | 网络搜索技能 | +| `KnowledgeQA` | 知识问答技能 | +| `Chat` | 对话技能 | +| `Custom` | 自定义技能 | + +## 快速开始 + +### 1. 创建 Skill + +```python +from dbgpt.agent.skill import SkillBuilder, SkillType + +skill = ( + SkillBuilder(name="my_skill", description="My awesome skill") + .with_version("1.0.0") + .with_author("Your Name") + .with_skill_type(SkillType.Coding) + .with_tags(["coding", "python"]) + .with_prompt_template( + "You are a coding assistant. Help users write clean, efficient code." + ) + .with_required_tool("python_interpreter") + .build() +) +``` + +### 2. 注册 Skill + +```python +from dbgpt.agent.skill import get_skill_manager, initialize_skill +from dbgpt.component import SystemApp + +system_app = SystemApp() +initialize_skill(system_app) +skill_manager = get_skill_manager(system_app) + +skill_manager.register_skill( + skill_instance=skill, + name="my_awesome_skill", +) +``` + +### 3. 创建 Skill-based Agent + +```python +from dbgpt.agent import ConversableAgent +from dbgpt.agent.skill import Skill + +class SkillBasedAgent(ConversableAgent): + def __init__(self, skill: Skill, **kwargs): + super().__init__(**kwargs) + self._skill = skill + self._apply_skill_to_profile() + + @property + def skill(self) -> Skill: + return self._skill +``` + +### 4. 使用 Agent + +```python +agent = SkillBasedAgent(skill=skill) +await agent.bind(context).bind(llm_config).bind(memory).build() +``` + +## API 参考 + +### SkillBuilder + +| 方法 | 参数 | 说明 | +|------|------|------| +| `with_version(version)` | version: str | 设置版本 | +| `with_author(author)` | author: str | 设置作者 | +| `with_skill_type(type)` | type: SkillType | 设置技能类型 | +| `with_tags(tags)` | tags: List[str] | 设置标签 | +| `with_prompt_template(template)` | template: str | 设置提示词模板 | +| `with_required_tool(name)` | name: str | 添加必需工具 | +| `with_required_knowledge(name)` | name: str | 添加必需知识库 | +| `with_action(action)` | action: Any | 添加动作 | +| `with_config(config)` | config: Dict | 设置配置 | +| `build()` | - | 构建 Skill | + +### SkillManager + +| 方法 | 参数 | 返回值 | 说明 | +|------|------|--------|------| +| `register_skill()` | skill_cls, skill_instance, name, metadata | None | 注册技能 | +| `get_skill()` | name, skill_type, version | SkillBase | 获取技能 | +| `get_skills_by_type()` | skill_type | List[SkillBase] | 按类型获取技能 | +| `list_skills()` | - | List[Dict] | 列出所有技能 | + +### SkillLoader + +| 方法 | 参数 | 返回值 | 说明 | +|------|------|--------|------| +| `load_skill_from_file()` | file_path | Optional[SkillBase] | 从文件加载技能 | +| `load_skill_from_module()` | module_path | Optional[SkillBase] | 从模块加载技能 | +| `load_skills_from_directory()` | directory, recursive | List[SkillBase] | 从目录加载所有技能 | + +## 文件格式 + +### JSON 格式 + +```json +{ + "metadata": { + "name": "web_search_assistant", + "description": "Web search assistant", + "version": "1.0.0", + "author": "DB-GPT Team", + "skill_type": "web_search", + "tags": ["web", "search"] + }, + "prompt_template": "You are a web search assistant.", + "required_tools": ["google_search"], + "required_knowledge": [], + "config": {} +} +``` + +### Python 格式 + +```python +from dbgpt.agent.skill import Skill, SkillMetadata, SkillType +from dbgpt.core import PromptTemplate + +class CustomSkill(Skill): + def __init__(self): + metadata = SkillMetadata( + name="custom_skill", + description="A custom skill", + version="1.0.0", + skill_type=SkillType.Custom, + ) + prompt = PromptTemplate.from_template("You are a custom assistant.") + super().__init__( + metadata=metadata, + prompt_template=prompt, + ) +``` + +## 示例 + +### 完整示例 + +查看 `examples/agents/skill_agent_example.py` 获取完整的使用示例。 + +### 技能文件 + +- `skills/web_search_skill.json` - 网络搜索技能示例 +- `skills/data_analysis_skill.json` - 数据分析技能示例 + +### 实现指南 + +- `skills/skill_implementation_guide.py` - 详细的实现指南 +- `skills/INTEGRATION_GUIDE.md` - 集成到现有 Agent 的指南 + +## 集成步骤 + +1. **导入 SKILL 模块** + ```python + from dbgpt.agent.skill import Skill, SkillBuilder, get_skill_manager + ``` + +2. **修改 Agent 类** + ```python + class MyAgent(ConversableAgent): + def __init__(self, skill: Optional[Skill] = None, **kwargs): + super().__init__(**kwargs) + self._skill = skill + if self._skill: + self._apply_skill_to_profile() + ``` + +3. **初始化 Skill Manager** + ```python + from dbgpt.component import SystemApp + system_app = SystemApp() + initialize_skill(system_app) + ``` + +4. **注册并使用 Skill** + ```python + skill_manager = get_skill_manager(system_app) + skill_manager.register_skill(skill_instance=skill) + agent = MyAgent(skill=skill) + ``` + +## 高级用法 + +### 动态 Skill 切换 + +```python +class DynamicSkillAgent(ConversableAgent): + def switch_skill(self, skill_name: str): + self._skill = self._skills[skill_name] + self._apply_skill_to_profile() +``` + +### 多 Skill 组合 + +```python +class CompositeSkillAgent(ConversableAgent): + def __init__(self, skills: List[Skill], **kwargs): + super().__init__(**kwargs) + self._skills = skills + + def get_all_tools(self) -> List[str]: + all_tools = [] + for skill in self._skills: + all_tools.extend(skill.required_tools) + return list(set(all_tools)) +``` + +## 最佳实践 + +1. **模块化设计**:每个 Skill 专注于单一领域 +2. **版本管理**:使用语义化版本号(如 1.0.0) +3. **依赖声明**:清晰声明所需的工具和知识库 +4. **文档完善**:为 Skill 编写详细的文档 +5. **测试覆盖**:为每个 Skill 编写单元测试 + +## 故障排除 + +### 常见问题 + +**Q: Skill 加载失败?** +A: 检查文件路径、JSON 格式是否正确 + +**Q: 找不到必需的工具?** +A: 确保在绑定 Agent 时提供了所有必需的工具 + +**Q: 提示词模板不生效?** +A: 确保在 `_apply_skill_to_profile` 中正确设置了 `bind_prompt` + +## 贡献指南 + +欢迎贡献新的 Skill!请遵循以下步骤: + +1. Fork 项目 +2. 创建新的 Skill 文件 +3. 编写测试 +4. 提交 Pull Request + +## 许可证 + +MIT License + +## 联系方式 + +如有问题或建议,请提交 Issue 或 Pull Request。 diff --git a/skills/claude/QUICKSTART.md b/skills/claude/QUICKSTART.md new file mode 100644 index 000000000..87371e385 --- /dev/null +++ b/skills/claude/QUICKSTART.md @@ -0,0 +1,368 @@ +# Claude SKILL 机制 - 快速入门指南 + +## ✅ 已实现的功能 + +| 功能 | 状态 | 文件位置 | +|------|--------|----------| +| SKILL 文件解析 | ✅ | `packages/dbgpt-core/src/dbgpt/agent/claude_skill/__init__.py` | +| Agent 集成 | ✅ | `packages/dbgpt-core/src/dbgpt/agent/claude_skill/agent.py` | +| 自动匹配技能 | ✅ | `FileBasedSkill.matches()` | +| 手动选择技能 | ✅ | `ClaudeSkillAgent.set_skill()` | +| 示例 SKILL 文件 | ✅ | `skills/claude/*/SKILL.md` | +| 完整示例 | ✅ | `examples/agents/claude_skill_example.py` | + +## 📦 文件结构 + +``` +packages/dbgpt-core/src/dbgpt/agent/claude_skill/ +├── __init__.py # 核心类:ClaudeSkill, FileBasedSkill, SkillRegistry +└── agent.py # ClaudeSkillAgent - 集成到 DB-GPT Agent + +examples/ +├── agents/ +│ └── claude_skill_example.py # 完整使用示例 +└── skills/claude/ + ├── explain-code/SKILL.md # 代码解释技能 + ├── debug-code/SKILL.md # 代码调试技能 + ├── write-code/SKILL.md # 代码编写技能 + ├── simplify-code/SKILL.md # 代码简化技能 + └── README.md # 详细文档 +``` + +## 🚀 5 分钟快速开始 + +### 1. 创建 SKILL 文件 + +创建 `my-skill/SKILL.md`: + +```markdown +--- +name: my-custom-skill +description: Custom skill for specific task. Use when user asks about this topic. +--- + +When handling this task: + +1. **First step**: What to do first +2. **Second step**: What to do next +3. **Final step**: How to complete + +Additional guidelines and best practices... +``` + +### 2. 加载技能 + +```python +from dbgpt.agent.claude_skill import load_skills_from_dir + +load_skills_from_dir("skills/claude/", recursive=True) +``` + +### 3. 创建 Agent + +```python +from dbgpt.agent.claude_skill import ClaudeSkillAgent + +agent = ClaudeSkillAgent() +await agent.bind(context).bind(llm_config).bind(memory).build() +``` + +### 4. 自动匹配技能 + +```python +user_input = "Can you explain this code?" +agent.detect_and_apply_skill(user_input) + +if agent.current_skill: + print(f"Using skill: {agent.current_skill.metadata.name}") +``` + +## 📝 SKILL 文件格式 + +标准格式: + +```markdown +--- +name: skill-name +description: Description with trigger conditions. Use when user asks... +--- + +Instructions for the AI... +``` + +### 元数据字段 + +| 字段 | 必需 | 说明 | +|------|--------|------| +| `name` | ✅ | 技能的唯一标识符 | +| `description` | ✅ | 描述和触发条件 | + +### 触发条件示例 + +在 `description` 中包含这些短语以触发技能: + +- `"Use when user asks to..."` +- `"Use when the user wants..."` +- `"Use when explaining how code works"` +- `"when user asks 'how does this work?'"` + +## 🎯 自动匹配机制 + +SKILL 系统通过以下方式匹配: + +1. **提取关键词**:从 description 中提取关键词 +2. **匹配用户输入**:检查用户输入是否包含关键词 +3. **技能名称匹配**:直接匹配技能名称 + +### 匹配优先级 + +当多个技能匹配时: +- 选择指令更详细的技能 +- 选择第一个匹配的技能 + +## 🎮 完整示例 + +```python +import asyncio +import os +from dbgpt.agent import AgentContext, AgentMemory, LLMConfig +from dbgpt.agent.claude_skill import ( + ClaudeSkillAgent, + load_skills_from_dir, +) +from dbgpt.model.proxy.llms.siliconflow import SiliconFlowLLMClient + +async def main(): + # 1. 加载技能 + load_skills_from_dir("skills/claude/", recursive=True) + + # 2. 创建 LLM 配置 + llm_client = SiliconFlowLLMClient( + model_alias="Qwen/Qwen2.5-Coder-32B-Instruct", + ) + + # 3. 创建 Agent + agent = ClaudeSkillAgent() + agent_memory = AgentMemory() + context = AgentContext(conv_id="test_conv") + + await agent.bind(context).bind(LLMConfig(llm_client=llm_client)).bind(agent_memory).build() + + # 4. 使用技能 + user_input = "Can you explain how this function works?" + agent.detect_and_apply_skill(user_input) + + if agent.current_skill: + print(f"激活技能: {agent.current_skill.metadata.name}") + print(f"描述: {agent.current_skill.metadata.description}") + +if __name__ == "__main__": + asyncio.run(main()) +``` + +## 🛠️ 核心 API + +### ClaudeSkillAgent + +```python +# 自动匹配技能 +agent.detect_and_apply_skill(user_input) + +# 手动设置技能 +agent.set_skill("explain-code") + +# 清除当前技能 +agent.clear_skill() + +# 获取可用技能列表 +skills = agent.get_available_skills() + +# 获取当前技能 +current = agent.current_skill +``` + +### FileBasedSkill + +```python +from dbgpt.agent.claude_skill import FileBasedSkill + +skill = FileBasedSkill("path/to/SKILL.md") + +# 获取元数据 +print(skill.metadata.name) +print(skill.metadata.description) + +# 获取指令 +print(skill.instructions) + +# 检查是否匹配 +if skill.matches(user_input): + print("匹配成功!") + +# 获取提示词模板 +prompt = skill.get_prompt() +``` + +### SkillRegistry + +```python +from dbgpt.agent.claude_skill import get_registry + +registry = get_registry() + +# 注册技能 +registry.register_skill(skill) + +# 获取技能 +skill = registry.get_skill("explain-code") + +# 匹配技能 +matching = registry.match_skill(user_input) + +# 列出所有技能 +all_skills = registry.list_skills() + +# 从目录加载 +registry.load_from_directory("skills/", recursive=True) +``` + +## 📚 预设 SKILL 示例 + +### explain-code + +用于解释代码的工作原理,包含: + +- 类比(将代码比作日常事物) +- ASCII 图表(显示流程、结构或关系) +- 逐步解释 +- 常见陷阱提示 + +### debug-code + +用于调试代码,包含: + +- 识别问题 +- 解释原因 +- 显示修复方案 +- 预防未来问题 +- 测试修复方法 + +### write-code + +用于编写新代码,包含: + +- 理解需求 +- 规划结构 +- 编写整洁代码 +- 包含导入 +- 添加错误处理 +- 提供使用示例 + +### simplify-code + +用于简化代码,包含: + +- 识别复杂性 +- 逐步重构 +- 移除重复 +- 提高可读性 +- 保持功能不变 + +## 🔧 高级用法 + +### 自定义匹配逻辑 + +```python +from dbgpt.agent.claude_skill import ClaudeSkill + +class MyCustomSkill(ClaudeSkill): + @classmethod + def name(cls) -> str: + return "my-skill" + + @classmethod + def description(cls) -> str: + return "Custom skill description" + + @classmethod + def instructions(cls) -> str: + return "Custom instructions..." + + @classmethod + def matches(cls, user_input: str) -> bool: + # 自定义匹配逻辑 + return "magic" in user_input.lower() +``` + +### 动态技能加载 + +```python +from dbgpt.agent.claude_skill import ClaudeSkillAgent, get_registry + +registry = get_registry() +registry.load_from_directory("~/.claude/skills/", recursive=True) + +agent = ClaudeSkillAgent(skill_registry=registry) +``` + +## 🎓 最佳实践 + +1. **清晰的描述**:在 description 中明确说明何时使用该技能 +2. **具体的指令**:提供清晰的步骤和指南 +3. **使用触发词**:在描述中包含 "Use when..." 或 "when user asks..." +4. **保持简单**:每个技能专注于单一任务 +5. **版本控制**:使用 Git 跟踪 SKILL 文件的变更 + +## 🐛 故障排除 + +### 技能不匹配 + +**原因**:描述中的关键词不清晰 + +**解决**:在描述中添加明确的 "Use when..." 语句 + +### 加载失败 + +**原因**:文件格式不正确 + +**解决**:确保文件以 `---` 开头,格式为: +```markdown +--- +name: skill-name +description: Description +--- + +Instructions... +``` + +### 错误的技能被选中 + +**原因**:多个技能包含相同的关键词 + +**解决**: +1. 使描述更具体 +2. 使用手动选择:`agent.set_skill("specific-skill")` + +## 📚 参考资源 + +- **完整示例**:`examples/agents/claude_skill_example.py` +- **详细文档**:`skills/claude/README.md` +- **SKILL 文件示例**:`skills/claude/*/SKILL.md` + +## 🎉 开始使用 + +运行示例: + +```bash +cd /Users/chenketing.ckt/Desktop/project/DB-GPT +python examples/agents/claude_skill_example.py +``` + +创建你自己的 SKILL: + +1. 创建目录和 `SKILL.md` 文件 +2. 定义 name 和 description +3. 编写指令 +4. 运行 Agent 测试 + +祝使用愉快! 🚀 diff --git a/skills/claude/README.md b/skills/claude/README.md new file mode 100644 index 000000000..6d2c2d1ed --- /dev/null +++ b/skills/claude/README.md @@ -0,0 +1,339 @@ +# Claude-Style SKILL 机制 for DB-GPT + +这是 Claude 风格的 SKILL 机制在 DB-GPT 中的实现,允许使用简单的 Markdown 文件定义 Agent 的技能和行为。 + +## 概述 + +Claude SKILL 机制是一种简单而强大的方式来定义 AI 助手的行为: + +- **简单的 Markdown 文件**:每项技能是一个 `SKILL.md` 文件 +- **声明式元数据**:在文件顶部定义名称和描述 +- **行为指令**:描述 AI 应该如何响应 +- **自动匹配**:基于用户输入自动选择合适的技能 + +## SKILL 文件格式 + +```markdown +--- +name: skill-name +description: Skill description with triggers. Use when user asks specific questions. +--- + +When doing this task, always include: + +1. **Step 1**: Instruction +2. **Step 2**: Instruction +3. **Step 3**: Instruction + +Additional guidelines and best practices... +``` + +### 元数据部分 + +- `name`: 技能的唯一标识符 +- `description`: 技能描述,包含触发条件(如 "Use when user asks...") + +### 指令部分 + +分隔线 `---` 之后是实际的指令,告诉 AI 如何响应特定类型的请求。 + +## 快速开始 + +### 1. 创建 SKILL 文件 + +创建 `~/.claude/skills/my-skill/SKILL.md`: + +```markdown +--- +name: summarize-text +description: Summarizes text concisely. Use when the user asks to summarize content. +--- + +When summarizing text: + +1. **Identify key points**: Extract the main ideas +2. **Maintain meaning**: Keep the core message intact +3. **Be concise**: Use fewer words than the original +4. **Use bullet points**: Organize information clearly + +Create summaries that are easy to scan and understand quickly. +``` + +### 2. 加载技能 + +```python +from dbgpt.agent.claude_skill import load_skills_from_dir + +load_skills_from_dir("~/.claude/skills/", recursive=True) +``` + +### 3. 创建 Agent + +```python +from dbgpt.agent.claude_skill import ClaudeSkillAgent + +agent = ClaudeSkillAgent() +await agent.bind(context).bind(llm_config).bind(memory).build() +``` + +### 4. 自动匹配技能 + +Agent 会根据用户输入自动选择技能: + +```python +user_input = "Can you summarize this text?" +agent.detect_and_apply_skill(user_input) + +if agent.current_skill: + print(f"Using skill: {agent.current_skill.metadata.name}") +``` + +## 核心 API + +### ClaudeSkillAgent + +```python +agent = ClaudeSkillAgent(skill_registry=registry) + +# 自动匹配技能 +agent.detect_and_apply_skill(user_input) + +# 手动设置技能 +agent.set_skill("explain-code") + +# 清除当前技能 +agent.clear_skill() + +# 获取可用技能列表 +skills = agent.get_available_skills() +``` + +### SkillRegistry + +```python +from dbgpt.agent.claude_skill import get_registry + +registry = get_registry() + +# 从目录加载技能 +registry.load_from_directory("skills/", recursive=True) + +# 获取特定技能 +skill = registry.get_skill("explain-code") + +# 匹配技能 +matching_skill = registry.match_skill(user_input) + +# 列出所有技能 +skills = registry.list_skills() +``` + +## 示例 SKILL 文件 + +### explain-code + +```markdown +--- +name: explain-code +description: Explains code with visual diagrams and analogies. Use when explaining how code works, teaching about a codebase, or when the user asks "how does this work?" +--- + +When explaining code, always include: + +1. **Start with an analogy**: Compare the code to something from everyday life +2. **Draw a diagram**: Use ASCII art to show the flow, structure, or relationships +3. **Walk through the code**: Explain step-by-step what happens +4. **Highlight a gotcha**: What's a common mistake or misconception? + +Keep explanations conversational. For complex concepts, use multiple analogies. +``` + +### debug-code + +```markdown +--- +name: debug-code +description: Helps debug code by identifying issues, suggesting fixes, and explaining why the bug occurred. Use when the user has code that isn't working as expected. +--- + +When debugging code: + +1. **Identify the issue**: Clearly state what's going wrong +2. **Explain the cause**: Why is this happening? (refer to the specific line or logic) +3. **Show the fix**: Provide corrected code with clear changes +4. **Prevent recurrence**: Explain how to avoid this issue in the future +5. **Test the fix**: Describe how to verify the solution works + +Be specific with line numbers and variable names. +``` + +### write-code + +```markdown +--- +name: write-code +description: Writes new code based on requirements. Use when the user asks to create, implement, or write code. +--- + +When writing code: + +1. **Understand requirements**: Clarify what needs to be built before coding +2. **Plan the structure**: Briefly describe the architecture or approach +3. **Write clean code**: Follow best practices, add necessary comments +4. **Include imports**: Show all required imports +5. **Add error handling**: Include try-except blocks where appropriate +6. **Provide examples**: Show how to use the code + +Write production-ready code that's readable and maintainable. +``` + +### simplify-code + +```markdown +--- +name: simplify-code +description: Simplifies complex code by refactoring, removing redundancy, and making it more readable. Use when the user asks to simplify, clean up, or refactor code. +--- + +When simplifying code: + +1. **Identify complexity**: Point out what makes the code hard to understand +2. **Refactor step by step**: Show each simplification with explanation +3. **Remove duplication**: Combine repeated logic +4. **Improve readability**: Use better variable names and structure +5. **Preserve functionality**: Ensure the code still does the same thing +6. **Test mentally**: Walk through the simplified code to verify correctness + +Keep the code's original intent. If simplification requires trade-offs, explain them. +``` + +## 技能匹配机制 + +SKILL 机制通过以下方式匹配技能: + +1. **描述中的关键词**:从 `description` 中提取触发词 +2. **技能名称**:直接匹配技能名称 +3. **用户输入**:检查用户输入是否包含这些关键词 + +### 匹配优先级 + +当多个技能匹配时,选择: +- 指令更详细的技能 +- 第一个匹配的技能 + +## 文件结构 + +``` +~/.claude/skills/ +├── explain-code/ +│ └── SKILL.md +├── debug-code/ +│ └── SKILL.md +├── write-code/ +│ └── SKILL.md +└── simplify-code/ + └── SKILL.md +``` + +每个技能都有自己的目录,其中包含 `SKILL.md` 文件。 + +## 完整示例 + +查看 `examples/agents/claude_skill_example.py` 获取完整的使用示例。 + +## 高级用法 + +### 自定义匹配逻辑 + +通过子类化 `ClaudeSkill` 实现自定义匹配: + +```python +from dbgpt.agent.claude_skill import ClaudeSkill + +class CustomSkill(ClaudeSkill): + @classmethod + def name(cls) -> str: + return "my-custom-skill" + + @classmethod + def description(cls) -> str: + return "A custom skill" + + @classmethod + def instructions(cls) -> str: + return "Custom instructions..." + + @classmethod + def matches(cls, user_input: str) -> bool: + return "magic" in user_input.lower() +``` + +### 动态技能加载 + +```python +from dbgpt.agent.claude_skill import ClaudeSkillAgent, create_skill_agent + +async def main(): + skill_dir = "~/.claude/skills/" + context = AgentContext(conv_id="test") + + agent = await create_skill_agent(skill_dir, context) +``` + +## 与其他 Agent 类型集成 + +可以与任何 DB-GPT Agent 集成: + +```python +class MyCustomAgent(ClaudeSkillAgent, ConversableAgent): + def __init__(self, **kwargs): + super().__init__(**kwargs) + + # Your custom implementation... +``` + +## 最佳实践 + +1. **明确的描述**:在 `description` 中清楚地说明何时使用该技能 +2. **具体的指令**:提供清晰的步骤和指南 +3. **使用触发词**:在描述中包含 "Use when..." 或 "when the user asks..." +4. **保持简单**:每个技能专注于单一任务 +5. **版本控制**:使用 Git 跟踪 SKILL 文件的变更 + +## 故障排除 + +### 问题:技能不匹配 + +**原因**:描述中的关键词不清晰或不包含触发词 + +**解决**:在描述中添加明确的 "Use when..." 语句 + +### 问题:加载失败 + +**原因**:文件格式不正确 + +**解决**:确保文件以 `---` 开头,格式为: +```markdown +--- +name: skill-name +description: Description +--- + +Instructions... +``` + +### 问题:错误的技能被选中 + +**原因**:多个技能包含相同的关键词 + +**解决**: +1. 使描述更具体 +2. 使用手动技能选择:`agent.set_skill("specific-skill")` + +## 贡献 + +欢迎贡献新的 SKILL 文件!请遵循格式规范,并确保描述清晰。 + +## 许可证 + +MIT License diff --git a/skills/claude/debug-code/SKILL.md b/skills/claude/debug-code/SKILL.md new file mode 100644 index 000000000..1f65b4f26 --- /dev/null +++ b/skills/claude/debug-code/SKILL.md @@ -0,0 +1,14 @@ +--- +name: debug-code +description: Helps debug code by identifying issues, suggesting fixes, and explaining why the bug occurred. Use when the user has code that isn't working as expected. +--- + +When debugging code: + +1. **Identify the issue**: Clearly state what's going wrong +2. **Explain the cause**: Why is this happening? (refer to the specific line or logic) +3. **Show the fix**: Provide corrected code with clear changes +4. **Prevent recurrence**: Explain how to avoid this issue in the future +5. **Test the fix**: Describe how to verify the solution works + +Be specific with line numbers and variable names. If multiple issues exist, prioritize them. diff --git a/skills/claude/excel_analysis/SKILL.md b/skills/claude/excel_analysis/SKILL.md new file mode 100644 index 000000000..037551afb --- /dev/null +++ b/skills/claude/excel_analysis/SKILL.md @@ -0,0 +1,32 @@ +--- +name: excel_analysis +description: An autonomous data analysis agent specialized in processing Excel files, performing data cleaning, analysis, and visualization. +version: 1.0.0 +author: DB-GPT Team +skill_type: chat +tags: [excel, data-analysis, pandas, visualization] +--- + +You are an expert Data Analysis Agent specialized in Excel data processing. Your goal is to autonomously analyze Excel files provided by the user to extract meaningful insights, trends, and answer specific business questions. + +# Capability Guidelines +1. **Data Loading & Inspection**: Always start by loading the data and inspecting the first few rows (head) and data types (info) to understand the structure. +2. **Data Cleaning**: Identify and handle missing values, duplicates, or incorrect data types before analysis. +3. **Analysis**: Use Python/Pandas to perform filtering, grouping, aggregation, and statistical calculations. +4. **Visualization**: Create clear and relevant plots (using matplotlib/seaborn) to visualize trends. **IMPORTANT**: Always save plots to a file (e.g., `output.png`) using `plt.savefig('filename.png')`. Do NOT use `plt.show()`. +5. **Autonomous Planning**: Break down complex requests into step-by-step actions (Load -> Clean -> Analyze -> Visualize -> Report). + +# Constraint & Safety +- **Read-Only**: Do not overwrite the original Excel file unless explicitly instructed. +- **Verification**: Verify your code results before presenting them as final answers. +- **Tools**: You must use the provided `code_interpreter` or `pandas_tool` to execute code. Do not simulate execution. + +# Workflow +1. **Receive Task**: "Analyze the sales trends in data.xlsx" +2. **Plan**: + - Step 1: Load `data.xlsx`. + - Step 2: Check columns and data types. + - Step 3: Group by date/category and sum sales. + - Step 4: Plot the trend. +3. **Execute**: Run tools for each step. +4. **Response**: Summarize findings with text and chart references. diff --git a/skills/claude/explain-code/SKILL.md b/skills/claude/explain-code/SKILL.md new file mode 100644 index 000000000..a7d622922 --- /dev/null +++ b/skills/claude/explain-code/SKILL.md @@ -0,0 +1,13 @@ +--- +name: explain-code +description: Explains code with visual diagrams and analogies. Use when explaining how code works, teaching about a codebase, or when the user asks "how does this work?" +--- + +When explaining code, always include: + +1. **Start with an analogy**: Compare the code to something from everyday life +2. **Draw a diagram**: Use ASCII art to show the flow, structure, or relationships +3. **Walk through the code**: Explain step-by-step what happens +4. **Highlight a gotcha**: What's a common mistake or misconception? + +Keep explanations conversational. For complex concepts, use multiple analogies. diff --git a/skills/claude/math_assistant/SKILL.md b/skills/claude/math_assistant/SKILL.md new file mode 100644 index 000000000..9cb4d84a6 --- /dev/null +++ b/skills/claude/math_assistant/SKILL.md @@ -0,0 +1,17 @@ +--- +name: math_assistant +description: A concise math assistant. Use when users ask to calculate numeric expressions or need step-by-step arithmetic reasoning. Prefer the `calculate` tool for any arithmetic operations. +skill_type: chat +required_tools: calculate +--- + +When asked to compute numeric expressions, always: + +1. Use the `calculate` tool to perform any arithmetic. +2. Return only the numeric result when the user requests a numeric answer. +3. If the user asks for explanation, provide a short step-by-step derivation after the numeric result. + +Examples: + +- "What is 10 * 99?" -> Use `calculate` with expression `10 * 99`, return `990`. +- "Compute (12+3)/5 and show steps" -> Use `calculate` for the numeric computation, then show steps. diff --git a/skills/claude/simplify-code/SKILL.md b/skills/claude/simplify-code/SKILL.md new file mode 100644 index 000000000..27e7da38e --- /dev/null +++ b/skills/claude/simplify-code/SKILL.md @@ -0,0 +1,15 @@ +--- +name: simplify-code +description: Simplifies complex code by refactoring, removing redundancy, and making it more readable. Use when the user asks to simplify, clean up, or refactor code. +--- + +When simplifying code: + +1. **Identify complexity**: Point out what makes the code hard to understand +2. **Refactor step by step**: Show each simplification with explanation +3. **Remove duplication**: Combine repeated logic +4. **Improve readability**: Use better variable names and structure +5. **Preserve functionality**: Ensure the code still does the same thing +6. **Test mentally**: Walk through the simplified code to verify correctness + +Keep the code's original intent. If simplification requires trade-offs, explain them. diff --git a/skills/claude/write-code/SKILL.md b/skills/claude/write-code/SKILL.md new file mode 100644 index 000000000..b12b0bb85 --- /dev/null +++ b/skills/claude/write-code/SKILL.md @@ -0,0 +1,15 @@ +--- +name: write-code +description: Writes new code based on requirements. Use when the user asks to create, implement, or write code. +--- + +When writing code: + +1. **Understand requirements**: Clarify what needs to be built before coding +2. **Plan the structure**: Briefly describe the architecture or approach +3. **Write clean code**: Follow best practices, add necessary comments +4. **Include imports**: Show all required imports +5. **Add error handling**: Include try-except blocks where appropriate +6. **Provide examples**: Show how to use the code + +Write production-ready code that's readable and maintainable. Explain any complex parts. diff --git a/skills/data_analysis_skill.json b/skills/data_analysis_skill.json new file mode 100644 index 000000000..c5283f5f8 --- /dev/null +++ b/skills/data_analysis_skill.json @@ -0,0 +1,17 @@ +{ + "metadata": { + "name": "data_analysis_assistant", + "description": "Data analysis assistant for processing and visualizing data", + "version": "1.0.0", + "author": "DB-GPT Team", + "skill_type": "data_analysis", + "tags": ["data", "analysis", "visualization"] + }, + "prompt_template": "You are a data analysis assistant. Help users analyze data, generate insights, and create visualizations. Use the available tools to process data and generate reports.", + "required_tools": ["python_interpreter", "plotting_tool"], + "required_knowledge": ["statistics", "data_science"], + "config": { + "max_dataframe_rows": 10000, + "enable_auto_visualization": true + } +} diff --git a/skills/excel-analysis/SKILL.md b/skills/excel-analysis/SKILL.md new file mode 100644 index 000000000..a4950538d --- /dev/null +++ b/skills/excel-analysis/SKILL.md @@ -0,0 +1,391 @@ +--- +name: Excel Analysis +description: Analyze Excel spreadsheets, create pivot tables, generate charts, and perform data analysis. Use when analyzing Excel files, spreadsheets, tabular data, or .xlsx files. +config: + scripts: + - name: load_and_preview + description: Load Excel file and display basic info plus first 5 rows + language: python + code: | + import pandas as pd + import json + + file_path = r"${file_path}" + df = pd.read_excel(file_path) + + result = { + "shape": df.shape, + "columns": list(df.columns), + "head": df.head(5).to_dict(orient="records") + } + print(json.dumps(result, ensure_ascii=False, indent=2)) + + - name: column_statistics + description: Calculate descriptive statistics for a specific column + language: python + code: | + import pandas as pd + import json + + file_path = r"${file_path}" + column_name = "${column_name}" + + df = pd.read_excel(file_path) + + if column_name in df.columns: + stats = df[column_name].describe() + print(f"Statistics for column '{column_name}':") + print(json.dumps(stats.to_dict(), ensure_ascii=False, indent=2)) + else: + print(f"Error: Column '{column_name}' not found. Available columns: {list(df.columns)}") + + - name: groupby_analysis + description: Group by a column and calculate aggregations + language: python + code: | + import pandas as pd + import json + + file_path = r"${file_path}" + group_column = "${group_column}" + agg_column = "${agg_column}" + agg_func = "${agg_func}" + + df = pd.read_excel(file_path) + + if group_column not in df.columns: + print(f"Error: Group column '{group_column}' not found.") + elif agg_column not in df.columns: + print(f"Error: Aggregate column '{agg_column}' not found.") + else: + result = df.groupby(group_column)[agg_column].agg(agg_func).reset_index() + print(json.dumps(result.to_dict(orient="records"), ensure_ascii=False, indent=2)) + + - name: correlation_matrix + description: Calculate correlation matrix for numeric columns + language: python + code: | + import pandas as pd + import json + + file_path = r"${file_path}" + df = pd.read_excel(file_path) + + # Select only numeric columns + numeric_df = df.select_dtypes(include=['number']) + + if numeric_df.empty: + print("No numeric columns found for correlation analysis.") + else: + corr = numeric_df.corr() + print("Correlation matrix:") + print(json.dumps(corr.to_dict(), ensure_ascii=False, indent=2)) + + - name: filter_data + description: Filter data based on conditions + language: python + code: | + import pandas as pd + import json + + file_path = r"${file_path}" + column = "${column}" + operator = "${operator}" + value = "${value}" + + df = pd.read_excel(file_path) + + if column not in df.columns: + print(f"Error: Column '{column}' not found.") + else: + # Try to convert value to number if possible + try: + value = float(value) + except: + pass + + if operator == "eq": + filtered = df[df[column] == value] + elif operator == "gt": + filtered = df[df[column] > value] + elif operator == "lt": + filtered = df[df[column] < value] + elif operator == "ge": + filtered = df[df[column] >= value] + elif operator == "le": + filtered = df[df[column] <= value] + elif operator == "ne": + filtered = df[df[column] != value] + elif operator == "contains": + filtered = df[df[column].astype(str).str.contains(str(value), na=False)] + else: + print(f"Error: Unknown operator '{operator}'") + filtered = pd.DataFrame() + + print(f"Filtered {len(filtered)} rows out of {len(df)}") + print(json.dumps(filtered.head(20).to_dict(orient="records"), ensure_ascii=False, indent=2)) +--- + +# Excel Analysis + +## Quick start + +Read Excel files with pandas: + +```python +import pandas as pd + +# Read Excel file +df = pd.read_excel("data.xlsx", sheet_name="Sheet1") + +# Display first few rows +print(df.head()) + +# Basic statistics +print(df.describe()) +``` + +## Instructions for Script Usage + +This skill provides pre-defined scripts that can be executed using the `execute_skill_script` tool: + +1. **load_and_preview**: Load file and show basic statistics + - Args: `{"file_path": "/path/to/file.xlsx"}` + +2. **column_statistics**: Get statistics for a specific column + - Args: `{"file_path": "...", "column_name": "Sales"}` + +3. **groupby_analysis**: Group and aggregate data + - Args: `{"file_path": "...", "group_column": "Region", "agg_column": "Sales", "agg_func": "sum"}` + +4. **correlation_matrix**: Analyze correlations between numeric columns + - Args: `{"file_path": "..."}` + +5. **filter_data**: Filter rows based on conditions + - Args: `{"file_path": "...", "column": "Sales", "operator": "gt", "value": "1000"}` + +Operators: eq, gt, lt, ge, le, ne, contains + +## Reading multiple sheets + +Process all sheets in a workbook: + +```python +import pandas as pd + +# Read all sheets +excel_file = pd.ExcelFile("workbook.xlsx") + +for sheet_name in excel_file.sheet_names: + df = pd.read_excel(excel_file, sheet_name=sheet_name) + print(f"\n{sheet_name}:") + print(df.head()) +``` + +## Data analysis + +Perform common analysis tasks: + +```python +import pandas as pd + +df = pd.read_excel("sales.xlsx") + +# Group by and aggregate +sales_by_region = df.groupby("region")["sales"].sum() +print(sales_by_region) + +# Filter data +high_sales = df[df["sales"] > 10000] + +# Calculate metrics +df["profit_margin"] = (df["revenue"] - df["cost"]) / df["revenue"] + +# Sort by column +df_sorted = df.sort_values("sales", ascending=False) +``` + +## Creating Excel files + +Write data to Excel with formatting: + +```python +import pandas as pd + +df = pd.DataFrame({ + "Product": ["A", "B", "C"], + "Sales": [100, 200, 150], + "Profit": [20, 40, 30] +}) + +# Write to Excel +writer = pd.ExcelWriter("output.xlsx", engine="openpyxl") +df.to_excel(writer, sheet_name="Sales", index=False) + +# Get worksheet for formatting +worksheet = writer.sheets["Sales"] + +# Auto-adjust column widths +for column in worksheet.columns: + max_length = 0 + column_letter = column[0].column_letter + for cell in column: + if len(str(cell.value)) > max_length: + max_length = len(str(cell.value)) + worksheet.column_dimensions[column_letter].width = max_length + 2 + +writer.close() +``` + +## Pivot tables + +Create pivot tables programmatically: + +```python +import pandas as pd + +df = pd.read_excel("sales_data.xlsx") + +# Create pivot table +pivot = pd.pivot_table( + df, + values="sales", + index="region", + columns="product", + aggfunc="sum", + fill_value=0 +) + +print(pivot) + +# Save pivot table +pivot.to_excel("pivot_report.xlsx") +``` + +## Charts and visualization + +Generate charts from Excel data: + +```python +import pandas as pd +import matplotlib.pyplot as plt + +df = pd.read_excel("data.xlsx") + +# Create bar chart +df.plot(x="category", y="value", kind="bar") +plt.title("Sales by Category") +plt.xlabel("Category") +plt.ylabel("Sales") +plt.tight_layout() +plt.savefig("chart.png") + +# Create pie chart +df.set_index("category")["value"].plot(kind="pie", autopct="%1.1f%%") +plt.title("Market Share") +plt.ylabel("") +plt.savefig("pie_chart.png") +``` + +## Data cleaning + +Clean and prepare Excel data: + +```python +import pandas as pd + +df = pd.read_excel("messy_data.xlsx") + +# Remove duplicates +df = df.drop_duplicates() + +# Handle missing values +df = df.fillna(0) # or df.dropna() + +# Remove whitespace +df["name"] = df["name"].str.strip() + +# Convert data types +df["date"] = pd.to_datetime(df["date"]) +df["amount"] = pd.to_numeric(df["amount"], errors="coerce") + +# Save cleaned data +df.to_excel("cleaned_data.xlsx", index=False) +``` + +## Merging and joining + +Combine multiple Excel files: + +```python +import pandas as pd + +# Read multiple files +df1 = pd.read_excel("sales_q1.xlsx") +df2 = pd.read_excel("sales_q2.xlsx") + +# Concatenate vertically +combined = pd.concat([df1, df2], ignore_index=True) + +# Merge on common column +customers = pd.read_excel("customers.xlsx") +sales = pd.read_excel("sales.xlsx") + +merged = pd.merge(sales, customers, on="customer_id", how="left") + +merged.to_excel("merged_data.xlsx", index=False) +``` + +## Advanced formatting + +Apply conditional formatting and styles: + +```python +import pandas as pd +from openpyxl import load_workbook +from openpyxl.styles import PatternFill, Font + +# Create Excel file +df = pd.DataFrame({ + "Product": ["A", "B", "C"], + "Sales": [100, 200, 150] +}) + +df.to_excel("formatted.xlsx", index=False) + +# Load workbook for formatting +wb = load_workbook("formatted.xlsx") +ws = wb.active + +# Apply conditional formatting +red_fill = PatternFill(start_color="FF0000", end_color="FF0000", fill_type="solid") +green_fill = PatternFill(start_color="00FF00", end_color="00FF00", fill_type="solid") + +for row in range(2, len(df) + 2): + cell = ws[f"B{row}"] + if cell.value < 150: + cell.fill = red_fill + else: + cell.fill = green_fill + +# Bold headers +for cell in ws[1]: + cell.font = Font(bold=True) + +wb.save("formatted.xlsx") +``` + +## Performance tips + +- Use `read_excel` with `usecols` to read specific columns only +- Use `chunksize` for very large files +- Consider using `engine='openpyxl'` or `engine='xlrd'` based on file type +- Use `dtype` parameter to specify column types for faster reading + +## Available packages + +- **pandas** - Data analysis and manipulation (primary) +- **openpyxl** - Excel file creation and formatting +- **xlrd** - Reading older .xls files +- **xlsxwriter** - Advanced Excel writing capabilities +- **matplotlib** - Chart generation diff --git a/skills/excel-generator/SKILL.md b/skills/excel-generator/SKILL.md new file mode 100644 index 000000000..2d720b824 --- /dev/null +++ b/skills/excel-generator/SKILL.md @@ -0,0 +1,672 @@ +--- +name: excel-generator +description: Professional Excel spreadsheet creation with a focus on aesthetics and data analysis. Use when creating spreadsheets for organizing, analyzing, and presenting structured data in a clear and professional format. +--- + +# Excel Generator Skill + +## Goal + +Make the user able to use the Excel immediately and gain insights upon opening. + +## Core Principle + +Enrich visuals as much as possible, while ensuring content clarity and not adding cognitive burden. Every visual element should be meaningful and purposeful—serving the content, not decorating it. + +--- + +## Part 1: User Needs & Feature Matching + +Before creating any Excel, think through: +1. **What does the user need?** — Not "an Excel file", but what problem are they solving? +2. **What can I provide?** — Which features will help them? +3. **How to match?** — Select the right combination for this specific scenario. + +### Feature ↔ User Value Pairs + +#### Help Users「Understand Data」 + +| Feature | User Value | When to Use | +|---------|-----------|-------------| +| Bar/Column Chart | See comparisons at a glance | Comparing values across categories | +| Line Chart | See trends at a glance | Time series data | +| Pie Chart | See proportions at a glance | Part-to-whole (≤6 categories) | +| Data Bars | Compare magnitude without leaving the cell | Numeric columns needing quick comparison | +| Color Scale | Heatmap effect, patterns pop out | Matrices, ranges, distributions | +| Sparklines | See trend within a single cell | Summary rows with historical context | + +#### Help Users「Find What Matters」 + +| Feature | User Value | When to Use | +|---------|-----------|-------------| +| Pre-sorting | Most important data comes first | Rankings, Top N, priorities | +| Conditional Highlighting | Key data stands out automatically | Outliers, thresholds, Top/Bottom N | +| Icon Sets | Status visible at a glance | KPI status, categorical states (use sparingly) | +| Bold/Color Emphasis | Visual distinction between primary and secondary | Summary rows, key metrics | +| KEY INSIGHTS Section | Conclusions delivered directly | Analytical reports | + +#### Help Users「Save Time」 + +| Feature | User Value | When to Use | +|---------|-----------|-------------| +| Overview Sheet | Summary on first page, no hunting | All multi-sheet files | +| Pre-calculated Summaries | Results ready, no manual calculation | Data requiring statistics | +| Consistent Number Formats | No format adjustments needed | All numeric data | +| Freeze Panes | Headers visible while scrolling | Tables with >10 rows | +| Sheet Index with Links | Quick navigation, no guessing | Files with >3 sheets | + +#### Help Users「Use Directly」 + +| Feature | User Value | When to Use | +|---------|-----------|-------------| +| Filters | Users can explore data themselves | Exploratory analysis needs | +| Hyperlinks | Click to navigate, no manual switching | Cross-sheet references, external sources | +| Print-friendly Layout | Ready to print or export to PDF | Reports for sharing | +| Formulas (not hardcoded) | Change parameters, results update | Models, forecasts, adjustable scenarios | +| Data Validation Dropdowns | Prevent input errors | Templates requiring user input | + +#### Help Users「Trust the Data」 + +| Feature | User Value | When to Use | +|---------|-----------|-------------| +| Data Source Attribution | Know where data comes from | All external data | +| Generation Date | Know data freshness | Time-sensitive reports | +| Data Time Range | Know what period is covered | Time series data | +| Professional Formatting | Looks reliable | All external-facing files | +| Consistent Precision | No doubts about accuracy | All numeric values | + +#### Help Users「Gain Insights」 + +| Feature | User Value | When to Use | +|---------|-----------|-------------| +| Comparison Columns (Δ, %) | No manual calculation for comparisons | YoY, MoM, A vs B | +| Rank Column | Position visible directly | Competitive analysis, performance | +| Grouped Summaries | Aggregated results by dimension | Segmented analysis | +| Trend Indicators (↑↓) | Direction clear at a glance | Change direction matters | +| Insight Text | The "so what" is stated explicitly | Analytical reports | + +--- + +## Part 2: Four-Layer Implementation + +### Layer 1: Structure (How It's Organized) + +**Goal**: Logical, easy to navigate, user finds what they need immediately. + +#### Sheet Organization + +| Guideline | Recommendation | +|-----------|----------------| +| Sheet count | 3-5 ideal, max 7 | +| First sheet | Always "Overview" with summary and navigation | +| Sheet order | General → Specific (Overview → Data → Analysis) | +| Naming | Clear, concise (e.g., "Revenue Data", not "Sheet1") | + +#### Information Architecture + +- **Overview sheet must stand alone**: User should understand the main message without opening other sheets +- **Progressive disclosure**: Summary first, details available for those who want to dig deeper +- **Consistent structure across sheets**: Same layout patterns, same starting positions + +#### Layout Rules + +| Element | Position | +|---------|----------| +| Left margin | Column A empty (width 3) | +| Top margin | Row 1 empty | +| Content start | Cell B2 | +| Section spacing | 1 empty row between sections | +| Table spacing | 2 empty rows between tables | +| Charts | Below all tables (2 rows gap), or right of related table | + +**Chart placement**: +- Default: below all tables, left-aligned with content +- Alternative: right of a single related table +- Charts must never overlap each other or tables + +#### Standalone Text Rows + +For rows with a single text cell (titles, descriptions, notes, bullet points), text will naturally extend into empty cells to the right. However, text is **clipped** if right cells contain any content (including spaces). + +**Decision logic**: + +| Condition | Action | +|-----------|--------| +| Right cells guaranteed empty | No action needed—text extends naturally | +| Right cells may have content | Merge cells to content width, or wrap text | +| Text exceeds content area width | Wrap text + set row height manually | + +**Technical note**: Fill and border alone do NOT block text overflow—only actual cell content (including space characters) blocks it. + +#### Navigation + +For files with 3+ sheets, include a Sheet Index on Overview: + +```python +# Sheet Index with hyperlinks +ws['B5'] = "CONTENTS" +ws['B5'].font = Font(name=SERIF_FONT, size=14, bold=True, color=THEME['accent']) + +sheets = ["Overview", "Data", "Analysis"] +for i, sheet_name in enumerate(sheets, start=6): + cell = ws.cell(row=i, column=2, value=sheet_name) + cell.hyperlink = f"#'{sheet_name}'!A1" + cell.font = Font(color=THEME['accent'], underline='single') +``` + +--- + +### Layer 2: Information (What They Learn) + +**Goal**: Accurate, complete, insightful—user gains knowledge, not just data. + +#### Number Formats + +**Critical rules**: +1. **Every numeric cell must have `number_format` set** — both input values AND formula results +2. **Same column = same precision** — never mix `0.1074` and `1.0` in one column +3. **Formula results have no default format** — they display raw precision unless explicitly formatted + +| Data Type | Format Code | Example | +|-----------|-------------|---------| +| Integer | `#,##0` | 1,234,567 | +| Decimal (1) | `#,##0.0` | 1,234.6 | +| Decimal (2) | `#,##0.00` | 1,234.56 | +| Percentage | `0.0%` | 12.3% | +| Currency | `$#,##0.00` | $1,234.56 | + +**Common mistake**: Setting format only for input cells, forgetting formula cells. + +```python +# WRONG: Formula cell without number_format +ws['C10'] = '=C7-C9' # Will display raw precision like 14.123456789 + +# CORRECT: Always set number_format for formula cells +ws['C10'] = '=C7-C9' +ws['C10'].number_format = '#,##0.0' # Displays as 14.1 + +# Best practice: Define format by column/data type, apply to ALL cells +for row in range(data_start, data_end + 1): + cell = ws.cell(row=row, column=value_col) + cell.number_format = '#,##0.0' # Applies to both values and formulas +``` + +#### Data Context + +Every data set needs context: + +| Element | Location | Example | +|---------|----------|---------| +| Data source | Overview or sheet footer | "Source: Company Annual Report 2024" | +| Time range | Near title or in subtitle | "Data from Jan 2020 - Dec 2024" | +| Generation date | Overview footer | "Generated: 2024-01-15" | +| Definitions | Notes section or separate sheet | "Revenue = Net sales excluding returns" | + +#### Key Insights + +For analytical content, don't just present data—tell the user what it means: + +```python +ws['B20'] = "KEY INSIGHTS" +ws['B20'].font = Font(name=SERIF_FONT, size=14, bold=True, color=THEME['accent']) + +insights = [ + "• Revenue grew 23% YoY, driven primarily by APAC expansion", + "• Top 3 customers account for 45% of total revenue", + "• Q4 showed strongest performance across all metrics" +] +for i, insight in enumerate(insights, start=21): + ws.cell(row=i, column=2, value=insight) +``` + +#### Content Completeness + +| Check | Action | +|-------|--------| +| Missing values | Show as blank or "N/A", never 0 unless actually zero | +| Calculated fields | Include formula or note explaining calculation | +| Abbreviations | Define on first use or in notes | +| Units | Include in header (e.g., "Revenue ($M)") | + +--- + +### Layer 3: Visual (What They See) + +**Goal**: Professional appearance, immediate sense of value, visuals serve content. + +#### Essential Setup + +```python +from openpyxl.styles import Font, PatternFill, Alignment, Border, Side + +# Hide gridlines for cleaner look +ws.sheet_view.showGridLines = False + +# Left margin +ws.column_dimensions['A'].width = 3 +``` + +#### Theme System + +Choose ONE theme per workbook. All visual elements derive from the theme color. + +**Available Themes** (select based on context, or let user specify): + +| Theme | Primary | Light | Use Case | +|-------|---------|-------|----------| +| **Elegant Black** | `2D2D2D` | `E5E5E5` | Luxury, fashion, premium reports (recommended default) | +| Corporate Blue | `1F4E79` | `D6E3F0` | Finance, corporate analysis | +| Forest Green | `2E5A4C` | `D4E5DE` | Sustainability, environmental | +| Burgundy | `722F37` | `E8D5D7` | Luxury brands, wine industry | +| Slate Gray | `4A5568` | `E2E8F0` | Tech, modern, minimalist | +| Navy | `1E3A5F` | `D3DCE6` | Government, maritime, institutional | +| Charcoal | `36454F` | `DDE1E4` | Professional, executive | +| Deep Purple | `4A235A` | `E1D5E7` | Creative, innovation, premium tech | +| Teal | `1A5F5F` | `D3E5E5` | Healthcare, wellness | +| Warm Brown | `5D4037` | `E6DDD9` | Natural, organic, artisan | +| Royal Blue | `1A237E` | `D3D5E8` | Academic, institutional | +| Olive | `556B2F` | `E0E5D5` | Military, outdoor | + +**Theme Configuration**: + +```python +# === THEME CONFIGURATION === +THEMES = { + 'elegant_black': { + 'primary': '2D2D2D', + 'light': 'E5E5E5', + 'accent': '2D2D2D', + 'chart_colors': ['2D2D2D', '4A4A4A', '6B6B6B', '8C8C8C', 'ADADAD', 'CFCFCF'], + }, + 'corporate_blue': { + 'primary': '1F4E79', + 'light': 'D6E3F0', + 'accent': '1F4E79', + 'chart_colors': ['1F4E79', '2E75B6', '5B9BD5', '9DC3E6', 'BDD7EE', 'DEEBF7'], + }, + # ... other themes follow same pattern +} + +THEME = THEMES['elegant_black'] # Default +SERIF_FONT = 'Source Serif Pro' # or 'Georgia' as fallback +SANS_FONT = 'Source Sans Pro' # or 'Calibri' as fallback +``` + +**How Theme Colors Apply**: + +| Element | Color | Background | +|---------|-------|------------| +| Document title | `THEME['primary']` | None | +| Section header | `THEME['primary']` | None or `THEME['light']` | +| Table header | White | `THEME['primary']` | +| Data cells | Black | None or alternating `F9F9F9` | +| Chart elements | `THEME['chart_colors']` | — | + +#### Semantic Colors + +For data meaning (independent of theme): + +| Semantic | Color | Use | +|----------|-------|-----| +| Positive | `2E7D32` | Growth, profit, success | +| Negative | `C62828` | Decline, loss, failure | +| Warning | `F57C00` | Caution, attention | + +#### Row Highlight Colors + +For row-level emphasis. Use **high-lightness tints** (85-95% lightness) for subtle distinction. + +| Semantic | Hex | Hue | Use | +|----------|-----|-----|-----| +| Emphasis | `E6F3FF` | 209° | Top rated, important data | +| Section | `FFF3E0` | 37° | Section dividers | +| Input | `FFFDE7` | 55° | Editable cells | +| Special | `FFF9C4` | 55° | Base case, benchmarks | +| Success | `E8F5E9` | 125° | Passed, completed | +| Warning | `FFCCBC` | 14° | Needs attention | + +**Rule**: Same semantic = same color. Different semantic = different color. + +```python +HIGHLIGHT = { + 'emphasis': 'E6F3FF', + 'section': 'FFF3E0', + 'input': 'FFFDE7', + 'special': 'FFF9C4', + 'success': 'E8F5E9', + 'warning': 'FFCCBC', +} +``` + +#### Typography + +Use **serif + sans-serif pairing**. Serif for hierarchy (titles, headers); sans-serif for data (tabular figures). + +**Font Pairings** (in preference order): + +| Serif (Titles) | Sans-Serif (Data) | Notes | +|----------------|-------------------|-------| +| Source Serif Pro | Source Sans Pro | Adobe superfamily, recommended | +| IBM Plex Serif | IBM Plex Sans | Modern, corporate | +| Georgia | Calibri | Pre-installed fallback | + +**Hierarchy**: + +| Element | Font | Size | Style | +|---------|------|------|-------| +| Document title | Serif | 18-22 | Bold, Primary color | +| Section header | Serif | 12-14 | Bold, Primary color | +| Table header | Serif | 10-11 | Bold, White | +| Data cells | Sans-Serif | 11 | Regular, Black | +| Notes | Sans-Serif | 9-10 | Italic, `666666` | + +```python +# Document title +ws['B2'].font = Font(name=SERIF_FONT, size=18, bold=True, color=THEME['primary']) + +# Section header +ws['B6'].font = Font(name=SERIF_FONT, size=14, bold=True, color=THEME['primary']) + +# Table header +header_font = Font(name=SERIF_FONT, size=10, bold=True, color='FFFFFF') + +# Data cells +data_font = Font(name=SANS_FONT, size=11) + +# Notes +notes_font = Font(name=SANS_FONT, size=10, italic=True, color='666666') +``` + +#### Data Block Definition + +A **Data Block** is a group of continuous, non-empty rows that form a visual unit requiring borders. Data Blocks are separated by empty rows. + +**Identification rules**: +1. Scan from Section Header downward +2. Non-empty row starts a Data Block +3. Empty row ends the current Data Block +4. Each Data Block gets its own outer frame + +**Data Block types**: + +| Type | Structure | Example | +|------|-----------|---------| +| With Header | Header row + data rows | Table with column titles | +| Without Header | Data rows only | Continuation data, sub-tables | + +**Example recognition**: + +``` +Row 5: Section Header "INCOME STATEMENT" → No border (not a Data Block) +Row 6: Empty → Separator +Row 7: Header (Item, Year1, Year2...) → Data Block 1 starts +Row 8: Revenue, 47061, 48943... +Row 9: Growth Rate, 4.0%, 3.5%... → Data Block 1 ends +Row 10: Empty → Separator +Row 11: EBITDA, 12121, 12627... → Data Block 2 starts (no header) +Row 12: EBITDA Margin, 25.8%, 25.8%... → Data Block 2 ends +Row 13: Empty → Separator +Row 14: D&A, 1200, 1224... → Data Block 3 starts (no header) +Row 15: EBIT, 10921, 11404... +Row 16: EBIT Margin, 23.2%, 23.3%... → Data Block 3 ends +``` + +Result: 3 separate Data Blocks, each with its own outer frame. + +#### Border Rules + +**Recommended style: Horizontal-only** — cleaner, more modern. + +**Each Data Block must have**: + +| Border Type | Where | +|-------------|-------| +| **Outer frame** | All 4 sides of Data Block (top, bottom, left, right) | +| **Header bottom** | Medium weight, theme primary color (if has header) | +| **Internal horizontal** | Thin, between all rows | +| **Internal vertical** | None (omit for cleaner look) | + +**Critical**: Every cell in the Data Block must have its border set. Do not only set header and label cells—data cells need borders too. + +```python +# Border definitions +outer_border = Side(style='thin', color='D1D1D1') +header_bottom = Side(style='medium', color=THEME['primary']) +inner_horizontal = Side(style='thin', color='D1D1D1') +no_border = Side(style=None) + +def apply_data_block_borders(ws, start_row, end_row, start_col, end_col, has_header=True): + """ + Apply borders to a Data Block. + Every cell must be processed—not just headers and labels. + """ + for row in range(start_row, end_row + 1): + for col in range(start_col, end_col + 1): + cell = ws.cell(row=row, column=col) + + # Left/Right: outer frame + left = outer_border if col == start_col else no_border + right = outer_border if col == end_col else no_border + + # Top: outer for first row, inner horizontal for others + top = outer_border if row == start_row else inner_horizontal + + # Bottom: header_bottom for header, outer for last row, inner for middle + if has_header and row == start_row: + bottom = header_bottom + elif row == end_row: + bottom = outer_border + else: + bottom = inner_horizontal + + cell.border = Border(left=left, right=right, top=top, bottom=bottom) +``` + +**Non-Data-Block elements** (titles, section headers, standalone text, notes): No border. + +#### Alignment + +**Headers**: Center. + +**Data cells**: + +| Content | Horizontal | +|---------|------------| +| Short text (words) | Center | +| Long text (sentences) | Left + `indent=1` | +| Numbers | Right | +| Dates, Status | Center | + +**Vertical**: Always `center` (including wrapped text). + +```python +# Left-aligned text with padding +cell.alignment = Alignment(horizontal='left', vertical='center', indent=1) + +# Numbers +cell.alignment = Alignment(horizontal='right', vertical='center') + +# Wrapped text +cell.alignment = Alignment(horizontal='left', vertical='center', wrap_text=True, indent=1) +``` + +#### Column Width + +**Calculation scope**: Only Data Block cells. Exclude standalone text rows, section headers, and notes. + +**Formula**: `max(max_content_length_in_data_blocks + padding, minimum)` + +| Column Type | Padding | Minimum | Notes | +|-------------|---------|---------|-------| +| Label/Text | +4 | 15 | First column usually | +| Numbers | +6 | 14 | Extra space for formatted numbers (negative signs, commas) | +| Long text | +4 | 20, max 40 | Wrap if exceeds max | + +**Design constraint**: Same column across different Data Blocks should serve similar roles. Column width is determined by the widest content across all Data Blocks in that column. + +**Standalone text rows**: Do NOT include in column width calculation. Let text extend naturally or use wrap/merge. + +```python +def calculate_column_width(ws, col, data_block_ranges): + """ + Calculate column width based only on Data Block content. + Standalone text rows are excluded. + + data_block_ranges: list of (start_row, end_row) tuples + """ + max_len = 0 + is_numeric = True + + for start_row, end_row in data_block_ranges: + for row in range(start_row, end_row + 1): + cell = ws.cell(row=row, column=col) + if cell.value: + # Get formatted display length + display_value = str(cell.value) + max_len = max(max_len, len(display_value)) + if not isinstance(cell.value, (int, float)): + is_numeric = False + + padding = 6 if is_numeric else 4 + minimum = 14 if is_numeric else 15 + + return max(max_len + padding, minimum) +``` + +#### Row Height + +Must set manually—openpyxl does not auto-adjust. + +| Row Type | Height | +|----------|--------| +| Document title | 35 | +| Section header | 25 | +| Table header | 30 | +| Standard data | 18 | +| Wrapped text | `lines × 15 + 10` | + +```python +ws.row_dimensions[2].height = 35 # Title +ws.row_dimensions[5].height = 25 # Section header +ws.row_dimensions[7].height = 30 # Table header +ws.row_dimensions[8].height = 18 # Data row +``` + +#### Merge Cells + +| Element | Merge? | Span | +|---------|--------|------| +| Document/Sheet title | Yes | Width of content below | +| Section header | Yes | Width of related table | +| Multi-level header (parent) | Yes | Span child columns | +| Long text row | Yes | Width of content area | + +**When to merge**: Merge when text would otherwise be clipped at the column boundary. If text fits within a single column, merging is optional. + +Common cases requiring merge: +- Titles and subtitles (usually span full content width) +- Section headers (span width of related table) +- KEY INSIGHTS bullet points (long sentences) +- Notes and disclaimers (multi-sentence text) + +**Section header with background** — merge width must match table width: + +```python +# Section header spans same width as table below +last_col = 8 # Must match table's last column +ws.merge_cells(f'B6:{get_column_letter(last_col)}6') +ws['B6'] = "KEY METRICS" +ws['B6'].font = Font(name=SERIF_FONT, size=14, bold=True, color=THEME['primary']) +ws['B6'].fill = PatternFill(start_color=THEME['light'], end_color=THEME['light'], fill_type='solid') +ws['B6'].alignment = Alignment(horizontal='left', vertical='center') +``` + +#### Data Visualization + +**Data Bars**: +```python +from openpyxl.formatting.rule import DataBarRule + +rule = DataBarRule(start_type='min', end_type='max', color=THEME['primary']) +ws.conditional_formatting.add('C5:C50', rule) +``` + +**Color Scale**: +```python +from openpyxl.formatting.rule import ColorScaleRule + +rule = ColorScaleRule( + start_type='min', start_color='FFFFFF', + end_type='max', end_color=THEME['primary'] +) +ws.conditional_formatting.add('D5:D50', rule) +``` + +**Charts**: +```python +from openpyxl.chart import BarChart, Reference + +chart = BarChart() +chart.title = "Revenue by Region" +data = Reference(ws, min_col=3, min_row=4, max_row=10) +cats = Reference(ws, min_col=2, min_row=5, max_row=10) +chart.add_data(data, titles_from_data=True) +chart.set_categories(cats) + +# Apply theme colors to chart series +for i, series in enumerate(chart.series): + series.graphicalProperties.solidFill = THEME['chart_colors'][i % len(THEME['chart_colors'])] + +ws.add_chart(chart, "F5") +``` + +--- + +### Layer 4: Interaction (How They Interact) + +**Goal**: Usable, flexible, user can explore and work with the data. + +#### Freeze Panes + +For tables with >10 rows: + +```python +ws.freeze_panes = 'B5' # Freeze below header row +``` + +#### Filters + +For tables with >20 rows: + +```python +ws.auto_filter.ref = f"B4:{get_column_letter(last_col)}{last_row}" +``` + +#### Hyperlinks + +```python +# Internal link +cell.hyperlink = "#'Data'!A1" +cell.font = Font(color=THEME['accent'], underline='single') + +# External link +cell.hyperlink = "https://example.com" +cell.font = Font(color=THEME['accent'], underline='single') +``` + +#### Sorting + +Pre-sort by most meaningful dimension: +- Rankings → by value descending +- Time series → by date ascending +- Alphabetical → when no clear priority + +```python +df = df.sort_values('revenue', ascending=False) +``` + +#### Editability + +- Use formulas when users may update inputs +- Use hardcoded values when data is final +- Keep formulas simple; document complex ones diff --git a/skills/skill-creator/LICENSE.txt b/skills/skill-creator/LICENSE.txt new file mode 100644 index 000000000..7a4a3ea24 --- /dev/null +++ b/skills/skill-creator/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/skills/skill-creator/SKILL.md b/skills/skill-creator/SKILL.md new file mode 100644 index 000000000..b7f86598b --- /dev/null +++ b/skills/skill-creator/SKILL.md @@ -0,0 +1,356 @@ +--- +name: skill-creator +description: Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations. +license: Complete terms in LICENSE.txt +--- + +# Skill Creator + +This skill provides guidance for creating effective skills. + +## About Skills + +Skills are modular, self-contained packages that extend Claude's capabilities by providing +specialized knowledge, workflows, and tools. Think of them as "onboarding guides" for specific +domains or tasks—they transform Claude from a general-purpose agent into a specialized agent +equipped with procedural knowledge that no model can fully possess. + +### What Skills Provide + +1. Specialized workflows - Multi-step procedures for specific domains +2. Tool integrations - Instructions for working with specific file formats or APIs +3. Domain expertise - Company-specific knowledge, schemas, business logic +4. Bundled resources - Scripts, references, and assets for complex and repetitive tasks + +## Core Principles + +### Concise is Key + +The context window is a public good. Skills share the context window with everything else Claude needs: system prompt, conversation history, other Skills' metadata, and the actual user request. + +**Default assumption: Claude is already very smart.** Only add context Claude doesn't already have. Challenge each piece of information: "Does Claude really need this explanation?" and "Does this paragraph justify its token cost?" + +Prefer concise examples over verbose explanations. + +### Set Appropriate Degrees of Freedom + +Match the level of specificity to the task's fragility and variability: + +**High freedom (text-based instructions)**: Use when multiple approaches are valid, decisions depend on context, or heuristics guide the approach. + +**Medium freedom (pseudocode or scripts with parameters)**: Use when a preferred pattern exists, some variation is acceptable, or configuration affects behavior. + +**Low freedom (specific scripts, few parameters)**: Use when operations are fragile and error-prone, consistency is critical, or a specific sequence must be followed. + +Think of Claude as exploring a path: a narrow bridge with cliffs needs specific guardrails (low freedom), while an open field allows many routes (high freedom). + +### Anatomy of a Skill + +Every skill consists of a required SKILL.md file and optional bundled resources: + +``` +skill-name/ +├── SKILL.md (required) +│ ├── YAML frontmatter metadata (required) +│ │ ├── name: (required) +│ │ └── description: (required) +│ └── Markdown instructions (required) +└── Bundled Resources (optional) + ├── scripts/ - Executable code (Python/Bash/etc.) + ├── references/ - Documentation intended to be loaded into context as needed + └── assets/ - Files used in output (templates, icons, fonts, etc.) +``` + +#### SKILL.md (required) + +Every SKILL.md consists of: + +- **Frontmatter** (YAML): Contains `name` and `description` fields. These are the only fields that Claude reads to determine when the skill gets used, thus it is very important to be clear and comprehensive in describing what the skill is, and when it should be used. +- **Body** (Markdown): Instructions and guidance for using the skill. Only loaded AFTER the skill triggers (if at all). + +#### Bundled Resources (optional) + +##### Scripts (`scripts/`) + +Executable code (Python/Bash/etc.) for tasks that require deterministic reliability or are repeatedly rewritten. + +- **When to include**: When the same code is being rewritten repeatedly or deterministic reliability is needed +- **Example**: `scripts/rotate_pdf.py` for PDF rotation tasks +- **Benefits**: Token efficient, deterministic, may be executed without loading into context +- **Note**: Scripts may still need to be read by Claude for patching or environment-specific adjustments + +##### References (`references/`) + +Documentation and reference material intended to be loaded as needed into context to inform Claude's process and thinking. + +- **When to include**: For documentation that Claude should reference while working +- **Examples**: `references/finance.md` for financial schemas, `references/mnda.md` for company NDA template, `references/policies.md` for company policies, `references/api_docs.md` for API specifications +- **Use cases**: Database schemas, API documentation, domain knowledge, company policies, detailed workflow guides +- **Benefits**: Keeps SKILL.md lean, loaded only when Claude determines it's needed +- **Best practice**: If files are large (>10k words), include grep search patterns in SKILL.md +- **Avoid duplication**: Information should live in either SKILL.md or references files, not both. Prefer references files for detailed information unless it's truly core to the skill—this keeps SKILL.md lean while making information discoverable without hogging the context window. Keep only essential procedural instructions and workflow guidance in SKILL.md; move detailed reference material, schemas, and examples to references files. + +##### Assets (`assets/`) + +Files not intended to be loaded into context, but rather used within the output Claude produces. + +- **When to include**: When the skill needs files that will be used in the final output +- **Examples**: `assets/logo.png` for brand assets, `assets/slides.pptx` for PowerPoint templates, `assets/frontend-template/` for HTML/React boilerplate, `assets/font.ttf` for typography +- **Use cases**: Templates, images, icons, boilerplate code, fonts, sample documents that get copied or modified +- **Benefits**: Separates output resources from documentation, enables Claude to use files without loading them into context + +#### What to Not Include in a Skill + +A skill should only contain essential files that directly support its functionality. Do NOT create extraneous documentation or auxiliary files, including: + +- README.md +- INSTALLATION_GUIDE.md +- QUICK_REFERENCE.md +- CHANGELOG.md +- etc. + +The skill should only contain the information needed for an AI agent to do the job at hand. It should not contain auxilary context about the process that went into creating it, setup and testing procedures, user-facing documentation, etc. Creating additional documentation files just adds clutter and confusion. + +### Progressive Disclosure Design Principle + +Skills use a three-level loading system to manage context efficiently: + +1. **Metadata (name + description)** - Always in context (~100 words) +2. **SKILL.md body** - When skill triggers (<5k words) +3. **Bundled resources** - As needed by Claude (Unlimited because scripts can be executed without reading into context window) + +#### Progressive Disclosure Patterns + +Keep SKILL.md body to the essentials and under 500 lines to minimize context bloat. Split content into separate files when approaching this limit. When splitting out content into other files, it is very important to reference them from SKILL.md and describe clearly when to read them, to ensure the reader of the skill knows they exist and when to use them. + +**Key principle:** When a skill supports multiple variations, frameworks, or options, keep only the core workflow and selection guidance in SKILL.md. Move variant-specific details (patterns, examples, configuration) into separate reference files. + +**Pattern 1: High-level guide with references** + +```markdown +# PDF Processing + +## Quick start + +Extract text with pdfplumber: +[code example] + +## Advanced features + +- **Form filling**: See [FORMS.md](FORMS.md) for complete guide +- **API reference**: See [REFERENCE.md](REFERENCE.md) for all methods +- **Examples**: See [EXAMPLES.md](EXAMPLES.md) for common patterns +``` + +Claude loads FORMS.md, REFERENCE.md, or EXAMPLES.md only when needed. + +**Pattern 2: Domain-specific organization** + +For Skills with multiple domains, organize content by domain to avoid loading irrelevant context: + +``` +bigquery-skill/ +├── SKILL.md (overview and navigation) +└── reference/ + ├── finance.md (revenue, billing metrics) + ├── sales.md (opportunities, pipeline) + ├── product.md (API usage, features) + └── marketing.md (campaigns, attribution) +``` + +When a user asks about sales metrics, Claude only reads sales.md. + +Similarly, for skills supporting multiple frameworks or variants, organize by variant: + +``` +cloud-deploy/ +├── SKILL.md (workflow + provider selection) +└── references/ + ├── aws.md (AWS deployment patterns) + ├── gcp.md (GCP deployment patterns) + └── azure.md (Azure deployment patterns) +``` + +When the user chooses AWS, Claude only reads aws.md. + +**Pattern 3: Conditional details** + +Show basic content, link to advanced content: + +```markdown +# DOCX Processing + +## Creating documents + +Use docx-js for new documents. See [DOCX-JS.md](DOCX-JS.md). + +## Editing documents + +For simple edits, modify the XML directly. + +**For tracked changes**: See [REDLINING.md](REDLINING.md) +**For OOXML details**: See [OOXML.md](OOXML.md) +``` + +Claude reads REDLINING.md or OOXML.md only when the user needs those features. + +**Important guidelines:** + +- **Avoid deeply nested references** - Keep references one level deep from SKILL.md. All reference files should link directly from SKILL.md. +- **Structure longer reference files** - For files longer than 100 lines, include a table of contents at the top so Claude can see the full scope when previewing. + +## Skill Creation Process + +Skill creation involves these steps: + +1. Understand the skill with concrete examples +2. Plan reusable skill contents (scripts, references, assets) +3. Initialize the skill (run init_skill.py) +4. Edit the skill (implement resources and write SKILL.md) +5. Package the skill (run package_skill.py) +6. Iterate based on real usage + +Follow these steps in order, skipping only if there is a clear reason why they are not applicable. + +### Step 1: Understanding the Skill with Concrete Examples + +Skip this step only when the skill's usage patterns are already clearly understood. It remains valuable even when working with an existing skill. + +To create an effective skill, clearly understand concrete examples of how the skill will be used. This understanding can come from either direct user examples or generated examples that are validated with user feedback. + +For example, when building an image-editor skill, relevant questions include: + +- "What functionality should the image-editor skill support? Editing, rotating, anything else?" +- "Can you give some examples of how this skill would be used?" +- "I can imagine users asking for things like 'Remove the red-eye from this image' or 'Rotate this image'. Are there other ways you imagine this skill being used?" +- "What would a user say that should trigger this skill?" + +To avoid overwhelming users, avoid asking too many questions in a single message. Start with the most important questions and follow up as needed for better effectiveness. + +Conclude this step when there is a clear sense of the functionality the skill should support. + +### Step 2: Planning the Reusable Skill Contents + +To turn concrete examples into an effective skill, analyze each example by: + +1. Considering how to execute on the example from scratch +2. Identifying what scripts, references, and assets would be helpful when executing these workflows repeatedly + +Example: When building a `pdf-editor` skill to handle queries like "Help me rotate this PDF," the analysis shows: + +1. Rotating a PDF requires re-writing the same code each time +2. A `scripts/rotate_pdf.py` script would be helpful to store in the skill + +Example: When designing a `frontend-webapp-builder` skill for queries like "Build me a todo app" or "Build me a dashboard to track my steps," the analysis shows: + +1. Writing a frontend webapp requires the same boilerplate HTML/React each time +2. An `assets/hello-world/` template containing the boilerplate HTML/React project files would be helpful to store in the skill + +Example: When building a `big-query` skill to handle queries like "How many users have logged in today?" the analysis shows: + +1. Querying BigQuery requires re-discovering the table schemas and relationships each time +2. A `references/schema.md` file documenting the table schemas would be helpful to store in the skill + +To establish the skill's contents, analyze each concrete example to create a list of the reusable resources to include: scripts, references, and assets. + +### Step 3: Initializing the Skill + +At this point, it is time to actually create the skill. + +Skip this step only if the skill being developed already exists, and iteration or packaging is needed. In this case, continue to the next step. + +When creating a new skill from scratch, always run the `init_skill.py` script. The script conveniently generates a new template skill directory that automatically includes everything a skill requires, making the skill creation process much more efficient and reliable. + +Usage: + +```bash +scripts/init_skill.py --path +``` + +The script: + +- Creates the skill directory at the specified path +- Generates a SKILL.md template with proper frontmatter and TODO placeholders +- Creates example resource directories: `scripts/`, `references/`, and `assets/` +- Adds example files in each directory that can be customized or deleted + +After initialization, customize or remove the generated SKILL.md and example files as needed. + +### Step 4: Edit the Skill + +When editing the (newly-generated or existing) skill, remember that the skill is being created for another instance of Claude to use. Include information that would be beneficial and non-obvious to Claude. Consider what procedural knowledge, domain-specific details, or reusable assets would help another Claude instance execute these tasks more effectively. + +#### Learn Proven Design Patterns + +Consult these helpful guides based on your skill's needs: + +- **Multi-step processes**: See references/workflows.md for sequential workflows and conditional logic +- **Specific output formats or quality standards**: See references/output-patterns.md for template and example patterns + +These files contain established best practices for effective skill design. + +#### Start with Reusable Skill Contents + +To begin implementation, start with the reusable resources identified above: `scripts/`, `references/`, and `assets/` files. Note that this step may require user input. For example, when implementing a `brand-guidelines` skill, the user may need to provide brand assets or templates to store in `assets/`, or documentation to store in `references/`. + +Added scripts must be tested by actually running them to ensure there are no bugs and that the output matches what is expected. If there are many similar scripts, only a representative sample needs to be tested to ensure confidence that they all work while balancing time to completion. + +Any example files and directories not needed for the skill should be deleted. The initialization script creates example files in `scripts/`, `references/`, and `assets/` to demonstrate structure, but most skills won't need all of them. + +#### Update SKILL.md + +**Writing Guidelines:** Always use imperative/infinitive form. + +##### Frontmatter + +Write the YAML frontmatter with `name` and `description`: + +- `name`: The skill name +- `description`: This is the primary triggering mechanism for your skill, and helps Claude understand when to use the skill. + - Include both what the Skill does and specific triggers/contexts for when to use it. + - Include all "when to use" information here - Not in the body. The body is only loaded after triggering, so "When to Use This Skill" sections in the body are not helpful to Claude. + - Example description for a `docx` skill: "Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. Use when Claude needs to work with professional documents (.docx files) for: (1) Creating new documents, (2) Modifying or editing content, (3) Working with tracked changes, (4) Adding comments, or any other document tasks" + +Do not include any other fields in YAML frontmatter. + +##### Body + +Write instructions for using the skill and its bundled resources. + +### Step 5: Packaging a Skill + +Once development of the skill is complete, it must be packaged into a distributable .skill file that gets shared with the user. The packaging process automatically validates the skill first to ensure it meets all requirements: + +```bash +scripts/package_skill.py +``` + +Optional output directory specification: + +```bash +scripts/package_skill.py ./dist +``` + +The packaging script will: + +1. **Validate** the skill automatically, checking: + + - YAML frontmatter format and required fields + - Skill naming conventions and directory structure + - Description completeness and quality + - File organization and resource references + +2. **Package** the skill if validation passes, creating a .skill file named after the skill (e.g., `my-skill.skill`) that includes all files and maintains the proper directory structure for distribution. The .skill file is a zip file with a .skill extension. + +If validation fails, the script will report the errors and exit without creating a package. Fix any validation errors and run the packaging command again. + +### Step 6: Iterate + +After testing the skill, users may request improvements. Often this happens right after using the skill, with fresh context of how the skill performed. + +**Iteration workflow:** + +1. Use the skill on real tasks +2. Notice struggles or inefficiencies +3. Identify how SKILL.md or bundled resources should be updated +4. Implement changes and test again diff --git a/skills/skill-creator/scripts/init_skill.py b/skills/skill-creator/scripts/init_skill.py new file mode 100755 index 000000000..329ad4e5a --- /dev/null +++ b/skills/skill-creator/scripts/init_skill.py @@ -0,0 +1,303 @@ +#!/usr/bin/env python3 +""" +Skill Initializer - Creates a new skill from template + +Usage: + init_skill.py --path + +Examples: + init_skill.py my-new-skill --path skills/public + init_skill.py my-api-helper --path skills/private + init_skill.py custom-skill --path /custom/location +""" + +import sys +from pathlib import Path + + +SKILL_TEMPLATE = """--- +name: {skill_name} +description: [TODO: Complete and informative explanation of what the skill does and when to use it. Include WHEN to use this skill - specific scenarios, file types, or tasks that trigger it.] +--- + +# {skill_title} + +## Overview + +[TODO: 1-2 sentences explaining what this skill enables] + +## Structuring This Skill + +[TODO: Choose the structure that best fits this skill's purpose. Common patterns: + +**1. Workflow-Based** (best for sequential processes) +- Works well when there are clear step-by-step procedures +- Example: DOCX skill with "Workflow Decision Tree" → "Reading" → "Creating" → "Editing" +- Structure: ## Overview → ## Workflow Decision Tree → ## Step 1 → ## Step 2... + +**2. Task-Based** (best for tool collections) +- Works well when the skill offers different operations/capabilities +- Example: PDF skill with "Quick Start" → "Merge PDFs" → "Split PDFs" → "Extract Text" +- Structure: ## Overview → ## Quick Start → ## Task Category 1 → ## Task Category 2... + +**3. Reference/Guidelines** (best for standards or specifications) +- Works well for brand guidelines, coding standards, or requirements +- Example: Brand styling with "Brand Guidelines" → "Colors" → "Typography" → "Features" +- Structure: ## Overview → ## Guidelines → ## Specifications → ## Usage... + +**4. Capabilities-Based** (best for integrated systems) +- Works well when the skill provides multiple interrelated features +- Example: Product Management with "Core Capabilities" → numbered capability list +- Structure: ## Overview → ## Core Capabilities → ### 1. Feature → ### 2. Feature... + +Patterns can be mixed and matched as needed. Most skills combine patterns (e.g., start with task-based, add workflow for complex operations). + +Delete this entire "Structuring This Skill" section when done - it's just guidance.] + +## [TODO: Replace with the first main section based on chosen structure] + +[TODO: Add content here. See examples in existing skills: +- Code samples for technical skills +- Decision trees for complex workflows +- Concrete examples with realistic user requests +- References to scripts/templates/references as needed] + +## Resources + +This skill includes example resource directories that demonstrate how to organize different types of bundled resources: + +### scripts/ +Executable code (Python/Bash/etc.) that can be run directly to perform specific operations. + +**Examples from other skills:** +- PDF skill: `fill_fillable_fields.py`, `extract_form_field_info.py` - utilities for PDF manipulation +- DOCX skill: `document.py`, `utilities.py` - Python modules for document processing + +**Appropriate for:** Python scripts, shell scripts, or any executable code that performs automation, data processing, or specific operations. + +**Note:** Scripts may be executed without loading into context, but can still be read by Claude for patching or environment adjustments. + +### references/ +Documentation and reference material intended to be loaded into context to inform Claude's process and thinking. + +**Examples from other skills:** +- Product management: `communication.md`, `context_building.md` - detailed workflow guides +- BigQuery: API reference documentation and query examples +- Finance: Schema documentation, company policies + +**Appropriate for:** In-depth documentation, API references, database schemas, comprehensive guides, or any detailed information that Claude should reference while working. + +### assets/ +Files not intended to be loaded into context, but rather used within the output Claude produces. + +**Examples from other skills:** +- Brand styling: PowerPoint template files (.pptx), logo files +- Frontend builder: HTML/React boilerplate project directories +- Typography: Font files (.ttf, .woff2) + +**Appropriate for:** Templates, boilerplate code, document templates, images, icons, fonts, or any files meant to be copied or used in the final output. + +--- + +**Any unneeded directories can be deleted.** Not every skill requires all three types of resources. +""" + +EXAMPLE_SCRIPT = '''#!/usr/bin/env python3 +""" +Example helper script for {skill_name} + +This is a placeholder script that can be executed directly. +Replace with actual implementation or delete if not needed. + +Example real scripts from other skills: +- pdf/scripts/fill_fillable_fields.py - Fills PDF form fields +- pdf/scripts/convert_pdf_to_images.py - Converts PDF pages to images +""" + +def main(): + print("This is an example script for {skill_name}") + # TODO: Add actual script logic here + # This could be data processing, file conversion, API calls, etc. + +if __name__ == "__main__": + main() +''' + +EXAMPLE_REFERENCE = """# Reference Documentation for {skill_title} + +This is a placeholder for detailed reference documentation. +Replace with actual reference content or delete if not needed. + +Example real reference docs from other skills: +- product-management/references/communication.md - Comprehensive guide for status updates +- product-management/references/context_building.md - Deep-dive on gathering context +- bigquery/references/ - API references and query examples + +## When Reference Docs Are Useful + +Reference docs are ideal for: +- Comprehensive API documentation +- Detailed workflow guides +- Complex multi-step processes +- Information too lengthy for main SKILL.md +- Content that's only needed for specific use cases + +## Structure Suggestions + +### API Reference Example +- Overview +- Authentication +- Endpoints with examples +- Error codes +- Rate limits + +### Workflow Guide Example +- Prerequisites +- Step-by-step instructions +- Common patterns +- Troubleshooting +- Best practices +""" + +EXAMPLE_ASSET = """# Example Asset File + +This placeholder represents where asset files would be stored. +Replace with actual asset files (templates, images, fonts, etc.) or delete if not needed. + +Asset files are NOT intended to be loaded into context, but rather used within +the output Claude produces. + +Example asset files from other skills: +- Brand guidelines: logo.png, slides_template.pptx +- Frontend builder: hello-world/ directory with HTML/React boilerplate +- Typography: custom-font.ttf, font-family.woff2 +- Data: sample_data.csv, test_dataset.json + +## Common Asset Types + +- Templates: .pptx, .docx, boilerplate directories +- Images: .png, .jpg, .svg, .gif +- Fonts: .ttf, .otf, .woff, .woff2 +- Boilerplate code: Project directories, starter files +- Icons: .ico, .svg +- Data files: .csv, .json, .xml, .yaml + +Note: This is a text placeholder. Actual assets can be any file type. +""" + + +def title_case_skill_name(skill_name): + """Convert hyphenated skill name to Title Case for display.""" + return ' '.join(word.capitalize() for word in skill_name.split('-')) + + +def init_skill(skill_name, path): + """ + Initialize a new skill directory with template SKILL.md. + + Args: + skill_name: Name of the skill + path: Path where the skill directory should be created + + Returns: + Path to created skill directory, or None if error + """ + # Determine skill directory path + skill_dir = Path(path).resolve() / skill_name + + # Check if directory already exists + if skill_dir.exists(): + print(f"❌ Error: Skill directory already exists: {skill_dir}") + return None + + # Create skill directory + try: + skill_dir.mkdir(parents=True, exist_ok=False) + print(f"✅ Created skill directory: {skill_dir}") + except Exception as e: + print(f"❌ Error creating directory: {e}") + return None + + # Create SKILL.md from template + skill_title = title_case_skill_name(skill_name) + skill_content = SKILL_TEMPLATE.format( + skill_name=skill_name, + skill_title=skill_title + ) + + skill_md_path = skill_dir / 'SKILL.md' + try: + skill_md_path.write_text(skill_content) + print("✅ Created SKILL.md") + except Exception as e: + print(f"❌ Error creating SKILL.md: {e}") + return None + + # Create resource directories with example files + try: + # Create scripts/ directory with example script + scripts_dir = skill_dir / 'scripts' + scripts_dir.mkdir(exist_ok=True) + example_script = scripts_dir / 'example.py' + example_script.write_text(EXAMPLE_SCRIPT.format(skill_name=skill_name)) + example_script.chmod(0o755) + print("✅ Created scripts/example.py") + + # Create references/ directory with example reference doc + references_dir = skill_dir / 'references' + references_dir.mkdir(exist_ok=True) + example_reference = references_dir / 'api_reference.md' + example_reference.write_text(EXAMPLE_REFERENCE.format(skill_title=skill_title)) + print("✅ Created references/api_reference.md") + + # Create assets/ directory with example asset placeholder + assets_dir = skill_dir / 'assets' + assets_dir.mkdir(exist_ok=True) + example_asset = assets_dir / 'example_asset.txt' + example_asset.write_text(EXAMPLE_ASSET) + print("✅ Created assets/example_asset.txt") + except Exception as e: + print(f"❌ Error creating resource directories: {e}") + return None + + # Print next steps + print(f"\n✅ Skill '{skill_name}' initialized successfully at {skill_dir}") + print("\nNext steps:") + print("1. Edit SKILL.md to complete the TODO items and update the description") + print("2. Customize or delete the example files in scripts/, references/, and assets/") + print("3. Run the validator when ready to check the skill structure") + + return skill_dir + + +def main(): + if len(sys.argv) < 4 or sys.argv[2] != '--path': + print("Usage: init_skill.py --path ") + print("\nSkill name requirements:") + print(" - Hyphen-case identifier (e.g., 'data-analyzer')") + print(" - Lowercase letters, digits, and hyphens only") + print(" - Max 40 characters") + print(" - Must match directory name exactly") + print("\nExamples:") + print(" init_skill.py my-new-skill --path skills/public") + print(" init_skill.py my-api-helper --path skills/private") + print(" init_skill.py custom-skill --path /custom/location") + sys.exit(1) + + skill_name = sys.argv[1] + path = sys.argv[3] + + print(f"🚀 Initializing skill: {skill_name}") + print(f" Location: {path}") + print() + + result = init_skill(skill_name, path) + + if result: + sys.exit(0) + else: + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/skills/skill-creator/scripts/package_skill.py b/skills/skill-creator/scripts/package_skill.py new file mode 100755 index 000000000..5cd36cb16 --- /dev/null +++ b/skills/skill-creator/scripts/package_skill.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +""" +Skill Packager - Creates a distributable .skill file of a skill folder + +Usage: + python utils/package_skill.py [output-directory] + +Example: + python utils/package_skill.py skills/public/my-skill + python utils/package_skill.py skills/public/my-skill ./dist +""" + +import sys +import zipfile +from pathlib import Path +from quick_validate import validate_skill + + +def package_skill(skill_path, output_dir=None): + """ + Package a skill folder into a .skill file. + + Args: + skill_path: Path to the skill folder + output_dir: Optional output directory for the .skill file (defaults to current directory) + + Returns: + Path to the created .skill file, or None if error + """ + skill_path = Path(skill_path).resolve() + + # Validate skill folder exists + if not skill_path.exists(): + print(f"❌ Error: Skill folder not found: {skill_path}") + return None + + if not skill_path.is_dir(): + print(f"❌ Error: Path is not a directory: {skill_path}") + return None + + # Validate SKILL.md exists + skill_md = skill_path / "SKILL.md" + if not skill_md.exists(): + print(f"❌ Error: SKILL.md not found in {skill_path}") + return None + + # Run validation before packaging + print("🔍 Validating skill...") + valid, message = validate_skill(skill_path) + if not valid: + print(f"❌ Validation failed: {message}") + print(" Please fix the validation errors before packaging.") + return None + print(f"✅ {message}\n") + + # Determine output location + skill_name = skill_path.name + if output_dir: + output_path = Path(output_dir).resolve() + output_path.mkdir(parents=True, exist_ok=True) + else: + output_path = Path.cwd() + + skill_filename = output_path / f"{skill_name}.skill" + + # Create the .skill file (zip format) + try: + with zipfile.ZipFile(skill_filename, 'w', zipfile.ZIP_DEFLATED) as zipf: + # Walk through the skill directory + for file_path in skill_path.rglob('*'): + if file_path.is_file(): + # Calculate the relative path within the zip + arcname = file_path.relative_to(skill_path.parent) + zipf.write(file_path, arcname) + print(f" Added: {arcname}") + + print(f"\n✅ Successfully packaged skill to: {skill_filename}") + return skill_filename + + except Exception as e: + print(f"❌ Error creating .skill file: {e}") + return None + + +def main(): + if len(sys.argv) < 2: + print("Usage: python utils/package_skill.py [output-directory]") + print("\nExample:") + print(" python utils/package_skill.py skills/public/my-skill") + print(" python utils/package_skill.py skills/public/my-skill ./dist") + sys.exit(1) + + skill_path = sys.argv[1] + output_dir = sys.argv[2] if len(sys.argv) > 2 else None + + print(f"📦 Packaging skill: {skill_path}") + if output_dir: + print(f" Output directory: {output_dir}") + print() + + result = package_skill(skill_path, output_dir) + + if result: + sys.exit(0) + else: + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/skills/skill-creator/scripts/quick_validate.py b/skills/skill-creator/scripts/quick_validate.py new file mode 100755 index 000000000..d9fbeb75e --- /dev/null +++ b/skills/skill-creator/scripts/quick_validate.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 +""" +Quick validation script for skills - minimal version +""" + +import sys +import os +import re +import yaml +from pathlib import Path + +def validate_skill(skill_path): + """Basic validation of a skill""" + skill_path = Path(skill_path) + + # Check SKILL.md exists + skill_md = skill_path / 'SKILL.md' + if not skill_md.exists(): + return False, "SKILL.md not found" + + # Read and validate frontmatter + content = skill_md.read_text() + if not content.startswith('---'): + return False, "No YAML frontmatter found" + + # Extract frontmatter + match = re.match(r'^---\n(.*?)\n---', content, re.DOTALL) + if not match: + return False, "Invalid frontmatter format" + + frontmatter_text = match.group(1) + + # Parse YAML frontmatter + try: + frontmatter = yaml.safe_load(frontmatter_text) + if not isinstance(frontmatter, dict): + return False, "Frontmatter must be a YAML dictionary" + except yaml.YAMLError as e: + return False, f"Invalid YAML in frontmatter: {e}" + + # Define allowed properties + ALLOWED_PROPERTIES = {'name', 'description', 'license', 'allowed-tools', 'metadata'} + + # Check for unexpected properties (excluding nested keys under metadata) + unexpected_keys = set(frontmatter.keys()) - ALLOWED_PROPERTIES + if unexpected_keys: + return False, ( + f"Unexpected key(s) in SKILL.md frontmatter: {', '.join(sorted(unexpected_keys))}. " + f"Allowed properties are: {', '.join(sorted(ALLOWED_PROPERTIES))}" + ) + + # Check required fields + if 'name' not in frontmatter: + return False, "Missing 'name' in frontmatter" + if 'description' not in frontmatter: + return False, "Missing 'description' in frontmatter" + + # Extract name for validation + name = frontmatter.get('name', '') + if not isinstance(name, str): + return False, f"Name must be a string, got {type(name).__name__}" + name = name.strip() + if name: + # Check naming convention (hyphen-case: lowercase with hyphens) + if not re.match(r'^[a-z0-9-]+$', name): + return False, f"Name '{name}' should be hyphen-case (lowercase letters, digits, and hyphens only)" + if name.startswith('-') or name.endswith('-') or '--' in name: + return False, f"Name '{name}' cannot start/end with hyphen or contain consecutive hyphens" + # Check name length (max 64 characters per spec) + if len(name) > 64: + return False, f"Name is too long ({len(name)} characters). Maximum is 64 characters." + + # Extract and validate description + description = frontmatter.get('description', '') + if not isinstance(description, str): + return False, f"Description must be a string, got {type(description).__name__}" + description = description.strip() + if description: + # Check for angle brackets + if '<' in description or '>' in description: + return False, "Description cannot contain angle brackets (< or >)" + # Check description length (max 1024 characters per spec) + if len(description) > 1024: + return False, f"Description is too long ({len(description)} characters). Maximum is 1024 characters." + + return True, "Skill is valid!" + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("Usage: python quick_validate.py ") + sys.exit(1) + + valid, message = validate_skill(sys.argv[1]) + print(message) + sys.exit(0 if valid else 1) \ No newline at end of file diff --git a/skills/skill_implementation_guide.py b/skills/skill_implementation_guide.py new file mode 100644 index 000000000..743d0db80 --- /dev/null +++ b/skills/skill_implementation_guide.py @@ -0,0 +1,275 @@ +""" +Skill-based Agent Implementation Guide + +This guide shows how to integrate SKILL loading mechanism into DB-GPT agents. +""" + +# ============================================================================ +# 1. Basic Skill Definition +# ============================================================================ + +from dbgpt.agent.skill import ( + Skill, + SkillBuilder, + SkillType, +) +from dbgpt.core import PromptTemplate + + +# Method 1: Define skill class +class CustomSkill(Skill): + """Custom skill example.""" + + def __init__(self): + """Initialize custom skill.""" + metadata = SkillMetadata( + name="custom_skill", + description="A custom skill for specific tasks", + version="1.0.0", + skill_type=SkillType.Custom, + tags=["custom", "example"], + ) + prompt = PromptTemplate.from_template( + "You are a custom assistant for specific tasks." + ) + super().__init__( + metadata=metadata, + prompt_template=prompt, + required_tools=["tool1", "tool2"], + required_knowledge=["knowledge_base"], + ) + + +# Method 2: Use SkillBuilder +custom_skill = ( + SkillBuilder(name="my_skill", description="My awesome skill") + .with_version("1.0.0") + .with_author("Your Name") + .with_skill_type(SkillType.Coding) + .with_tags(["coding", "python"]) + .with_prompt_template( + "You are a coding assistant. Help users write clean, efficient code." + ) + .with_required_tool("python_interpreter") + .with_config({"max_lines": 1000}) + .build() +) + + +# ============================================================================ +# 2. Skill Registration +# ============================================================================ + +from dbgpt.agent.skill import get_skill_manager, initialize_skill +from dbgpt.component import SystemApp + + +def register_skills(): + """Register skills in the system.""" + system_app = SystemApp() + initialize_skill(system_app) + skill_manager = get_skill_manager(system_app) + + # Register skill instance + skill_manager.register_skill( + skill_instance=custom_skill, + name="my_awesome_skill", + ) + + # List all skills + skills = skill_manager.list_skills() + print(f"Registered skills: {skills}") + + +# ============================================================================ +# 3. Agent with Skill Integration +# ============================================================================ + +from dbgpt.agent import ConversableAgent +from dbgpt.agent.skill import Skill + + +class SkillBasedAgent(ConversableAgent): + """Agent that uses a skill.""" + + def __init__(self, skill: Skill, **kwargs): + """Initialize agent with skill.""" + super().__init__(**kwargs) + self._skill = skill + self._apply_skill_to_profile() + + @property + def skill(self) -> Skill: + """Return the skill.""" + return self._skill + + def _apply_skill_to_profile(self): + """Apply skill settings to agent profile.""" + if self.skill.prompt_template: + self.bind_prompt = self.skill.prompt_template + + # Set profile based on skill metadata + if self.profile: + self.profile.goal = self.skill.metadata.description + + async def load_resource(self, question: str, is_retry_chat: bool = False): + """Load resources required by the skill.""" + # Load required tools + if self.skill.required_tools and self.resource: + tools = self.resource.get_resource_by_type("tool") + for tool_name in self.skill.required_tools: + if tool_name not in [t.name for t in tools]: + raise ValueError(f"Required tool {tool_name} not found") + + # Load required knowledge + if self.skill.required_knowledge and self.resource: + knowledge = self.resource.get_resource_by_type("knowledge") + for knowledge_name in self.skill.required_knowledge: + if knowledge_name not in [k.name for k in knowledge]: + raise ValueError(f"Required knowledge {knowledge_name} not found") + + return await super().load_resource(question, is_retry_chat) + + +# ============================================================================ +# 4. Skill Loading from Files +# ============================================================================ + +from dbgpt.agent.skill import SkillLoader + + +def load_skills_from_directory(directory: str): + """Load all skills from a directory.""" + loader = SkillLoader() + skills = loader.load_skills_from_directory(directory, recursive=True) + + system_app = SystemApp() + initialize_skill(system_app) + skill_manager = get_skill_manager(system_app) + + for skill in skills: + skill_manager.register_skill(skill_instance=skill, name=skill.metadata.name) + + print(f"Loaded {len(skills)} skills from {directory}") + + +# ============================================================================ +# 5. Dynamic Skill Switching +# ============================================================================ + + +class DynamicSkillAgent(ConversableAgent): + """Agent that can switch between different skills.""" + + def __init__(self, **kwargs): + """Initialize agent with dynamic skill support.""" + super().__init__(**kwargs) + self._current_skill: Optional[Skill] = None + self._available_skills: Dict[str, Skill] = {} + + def register_skill(self, skill: Skill): + """Register a skill.""" + self._available_skills[skill.metadata.name] = skill + + def switch_skill(self, skill_name: str): + """Switch to a different skill.""" + if skill_name not in self._available_skills: + raise ValueError(f"Skill {skill_name} not found") + + self._current_skill = self._available_skills[skill_name] + + if self._current_skill.prompt_template: + self.bind_prompt = self._current_skill.prompt_template + + print(f"Switched to skill: {skill_name}") + + @property + def current_skill(self) -> Optional[Skill]: + """Return the current skill.""" + return self._current_skill + + +# ============================================================================ +# 6. Skill Composition (Multiple Skills) +# ============================================================================ + + +class CompositeSkillAgent(ConversableAgent): + """Agent that combines multiple skills.""" + + def __init__(self, skills: List[Skill], **kwargs): + """Initialize agent with multiple skills.""" + super().__init__(**kwargs) + self._skills = skills + + def get_skill_by_type(self, skill_type: SkillType) -> Optional[Skill]: + """Get skill by type.""" + for skill in self._skills: + if skill.metadata.skill_type == skill_type: + return skill + return None + + def get_all_tools(self) -> List[str]: + """Get all required tools from all skills.""" + all_tools = [] + for skill in self._skills: + all_tools.extend(skill.required_tools) + return list(set(all_tools)) + + def combine_prompts(self) -> str: + """Combine prompts from all skills.""" + prompts = [] + for skill in self._skills: + if skill.prompt_template: + prompts.append(skill.prompt_template.template) + return "\n\n".join(prompts) + + +# ============================================================================ +# 7. Usage Example +# ============================================================================ + + +async def example_usage(): + """Example usage of skill-based agents.""" + from dbgpt.agent import AgentContext, LLMConfig, AgentMemory + from dbgpt.agent.resource import tool + + @tool + def search(query: str) -> str: + """Search for information. + + Args: + query: Search query. + + Returns: + Search results. + """ + return f"Search results for: {query}" + + # Create skill + skill = ( + SkillBuilder(name="search_skill", description="Search assistant") + .with_prompt_template("Help users search for information.") + .with_required_tool("search") + .build() + ) + + # Create agent with skill + agent = SkillBasedAgent(skill=skill) + + # Bind necessary components + context = AgentContext(conv_id="test_conv") + llm_config = LLMConfig() + memory = AgentMemory() + + await agent.bind(context).bind(llm_config).bind(memory).bind([search]).build() + + print("Agent created with skill!") + print(f"Skill name: {agent.skill.metadata.name}") + print(f"Required tools: {agent.skill.required_tools}") + + +if __name__ == "__main__": + register_skills() + asyncio.run(example_usage()) diff --git a/skills/user/code-review/SKILL.md b/skills/user/code-review/SKILL.md new file mode 100644 index 000000000..e6fbe4206 --- /dev/null +++ b/skills/user/code-review/SKILL.md @@ -0,0 +1,246 @@ +--- +name: code-review +description: Systematic approach to reviewing code quality and best practices +version: 1.0.0 +author: DB-GPT Team +skill_type: coding +tags: [code, review, quality] +allowed-tools: +license: MIT +--- + +# Code Review Skill + +## When to Use +- User requests code review +- Need to evaluate code quality +- Looking for bugs or issues +- Checking for best practices +- Assessing security vulnerabilities +- Reviewing performance considerations + +## Code Review Checklist + +### Functionality +- [ ] Does the code implement the required features? +- [ ] Are edge cases handled properly? +- [ ] Does it handle errors gracefully? +- [ ] Are there any obvious bugs? + +### Code Quality +- [ ] Is the code readable and well-structured? +- [ ] Are variable and function names descriptive? +- [ ] Is there unnecessary code duplication? +- [ ] Are comments clear and helpful? + +### Performance +- [ ] Are there any performance bottlenecks? +- [ ] Are data structures chosen appropriately? +- [ ] Are there inefficient loops or operations? +- [ ] Is caching appropriate? + +### Security +- [ ] Are there any security vulnerabilities? +- [ ] Is user input properly validated? +- [ ] Are sensitive data handled correctly? +- [ ] Are there injection risks? + +### Best Practices +- [ ] Does it follow language conventions? +- [ ] Are common patterns used appropriately? +- [ ] Is the code modular and reusable? +- [ ] Are dependencies managed properly? + +## Review Structure + +### 1. Summary +- Brief overview of what the code does +- Overall impression +- Key strengths and weaknesses + +### 2. Issues by Category + +#### Critical Issues +```markdown +**Issue**: [Brief description] +**Location**: [File:Line] +**Impact**: [Why this matters] +**Suggestion**: [How to fix] +``` + +#### Style and Convention Issues +```markdown +**Issue**: [Brief description] +**Location**: [File:Line] +**Suggestion**: [How to fix] +``` + +#### Optimization Opportunities +```markdown +**Opportunity**: [Brief description] +**Location**: [File:Line] +**Current**: [Current approach] +**Suggested**: [Better approach] +**Impact**: [Expected improvement] +``` + +#### Best Practices +```markdown +**Suggestion**: [Improvement] +**Location**: [File:Line] +**Reason**: [Why this is better] +``` + +### 3. Positive Feedback +- Well-implemented features +- Good practices observed +- Notable strengths + +### 4. Recommendations +- Prioritized list of improvements +- Long-term suggestions +- Additional resources + +## Common Patterns to Check + +### Python +- Use list comprehensions appropriately +- Follow PEP 8 guidelines +- Use context managers (`with` statements) +- Implement `__str__` and `__repr__` +- Use type hints +- Handle exceptions properly +- Avoid mutable default arguments + +### JavaScript/TypeScript +- Use `const` and `let` instead of `var` +- Use arrow functions appropriately +- Handle promises correctly +- Avoid implicit globals +- Use modern ES6+ features +- Properly scope variables + +### SQL +- Use parameterized queries +- Index common query columns +- Avoid SELECT * +- Use appropriate JOIN types +- Handle NULL values correctly +- Optimize subqueries + +## Security Checks + +### Input Validation +```python +# Bad +user_input = request.form.get('data') +# Direct use without validation + +# Good +user_input = request.form.get('data', '').strip() +if not is_valid_input(user_input): + raise ValueError("Invalid input") +``` + +### SQL Injection +```python +# Bad +query = f"SELECT * FROM users WHERE name = '{name}'" + +# Good +query = "SELECT * FROM users WHERE name = %s" +cursor.execute(query, (name,)) +``` + +### XSS Prevention +```python +# Bad +return f"
{user_content}
" + +# Good +from markupsafe import escape +return f"
{escape(user_content)}
" +``` + +## Code Review Principles + +1. **Be Constructive**: Focus on improvement, not criticism +2. **Be Specific**: Point to exact locations and issues +3. **Provide Context**: Explain why something is a problem +4. **Offer Solutions**: Suggest how to fix issues +5. **Be Thorough**: Don't miss important issues +6. **Be Timely**: Review code while it's fresh +7. **Be Respectful**: Consider the author's perspective + +## Performance Considerations + +### Time Complexity +- Identify O(n²) operations that could be O(n log n) or O(n) +- Check nested loops +- Look for unnecessary repeated computations + +### Space Complexity +- Check for memory leaks +- Consider using generators instead of lists +- Release resources when done + +### Database Queries +- N+1 query problems +- Missing indexes +- Unnecessary joins +- Fetching too much data + +## Example Review Output + +```markdown +# Code Review: user_authentication.py + +## Summary +The code implements user authentication with JWT tokens. Overall, it's well-structured +but has some security concerns and opportunities for improvement. + +## Critical Issues + +**Issue**: Hardcoded secret key +**Location**: Line 15 +**Impact**: Security vulnerability - JWT secret should be in environment +**Suggestion**: Move to `os.environ.get('JWT_SECRET_KEY')` + +**Issue**: SQL injection vulnerability +**Location**: Line 42 +**Impact**: Attackers could execute arbitrary SQL +**Suggestion**: Use parameterized queries + +## Style and Convention Issues + +**Issue**: Missing type hints +**Location**: Functions throughout +**Suggestion**: Add type hints for better IDE support and documentation + +## Optimization Opportunities + +**Opportunity**: Repeated password hashing +**Location**: Line 58 +**Current**: Hashing password on every validation +**Suggested**: Cache hashed password or use constant-time comparison +**Impact**: Performance improvement for authentication + +## Positive Feedback +- Good error handling overall +- Clean function separation +- Good use of logging + +## Recommendations (Prioritized) +1. Fix security vulnerabilities immediately +2. Add comprehensive tests +3. Add type hints throughout +4. Consider using a password hashing library +5. Add rate limiting +``` + +## Resources + +- [PEP 8 - Style Guide](https://peps.python.org/pep-0008/) +- [Clean Code](https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882) +- [Effective Java](https://www.amazon.com/Effective-Java-Joshua-Bloch/dp/0134685997) +- [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html) diff --git a/skills/user/web-research/SKILL.md b/skills/user/web-research/SKILL.md new file mode 100644 index 000000000..fd7b9b0f6 --- /dev/null +++ b/skills/user/web-research/SKILL.md @@ -0,0 +1,97 @@ +--- +name: web-research +description: Structured approach to conducting thorough web research +version: 1.0.0 +author: DB-GPT Team +skill_type: research +tags: [web, research, analysis] +allowed-tools: web-search +license: MIT +--- + +# Web Research Skill + +## When to Use +- User asks you to research a topic +- You need to gather information from the web +- Research requires a structured approach +- User wants comprehensive information on a subject + +## Workflow + +### 1. Define Research Scope +- Clarify the research topic +- Identify key questions to answer +- Determine time period and geographic scope +- Note any constraints or preferences + +### 2. Search for Information +- Use web-search tools to find relevant sources +- Search for multiple keywords and phrases +- Include both popular and specialized sources +- Search across different domains (news, academic, blogs) + +### 3. Evaluate Sources +- Check source credibility and authority +- Identify potential biases +- Verify information across multiple sources +- Consider publication dates for currency + +### 4. Synthesize Findings +- Organize information by theme +- Identify common patterns and disagreements +- Highlight key insights and statistics +- Note gaps in available information + +### 5. Present Results +- Structure findings clearly +- Use headings and bullet points for readability +- Include sources and citations +- Provide summary and conclusions + +## Best Practices + +- Start with broad searches, then narrow down +- Cross-reference information from multiple sources +- Be transparent about uncertainty +- Cite sources when possible +- Use quotes for key information +- Organize findings logically + +## Example Output Structure + +```markdown +# Research: [Topic] + +## Overview +[Brief summary of findings] + +## Key Findings +- Finding 1 +- Finding 2 +- Finding 3 + +## Details +[Detailed information organized by theme] + +## Sources +- Source 1 +- Source 2 +``` + +## Tips for Deep Research + +- Use specific search terms for better results +- Try variations of keywords +- Look for both recent and foundational sources +- Check for opposing viewpoints +- Consider searching in different languages if relevant +- Look for official reports and studies + +## Common Mistakes to Avoid + +- Relying on a single source +- Ignoring source credibility +- Not verifying facts +- Overlooking recent developments +- Misrepresenting source information diff --git a/tests/unit_tests/agent/test_claude_skill.py b/tests/unit_tests/agent/test_claude_skill.py new file mode 100644 index 000000000..ab921caa5 --- /dev/null +++ b/tests/unit_tests/agent/test_claude_skill.py @@ -0,0 +1,105 @@ +import os +from pathlib import Path + +import pytest + + +def _write_skill_md(path: Path, content: str) -> Path: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(content, encoding="utf-8") + return path + + +def test_filebasedskill_parses_frontmatter(tmp_path): + """FileBasedSkill should parse SKILL.md frontmatter into metadata and instructions.""" + skill_md = """ +--- +name: math-assistant +description: Simple math assistant that can multiply numbers. +version: 0.1.0 +author: Test Author +skill_type: chat +tags: math, calculator +required_tools: calculate, terminate +config: + precision: 2 +--- + +You are a helpful math assistant. When asked, produce the calculation result only. +""" + + file_path = tmp_path / "math_assistant" / "SKILL.md" + _write_skill_md(file_path, skill_md) + + from dbgpt.agent.claude_skill import FileBasedSkill + + fskill = FileBasedSkill(str(file_path)) + + meta = fskill.metadata + + assert meta.name == "math-assistant" + assert "math assistant" in meta.description + assert meta.version == "0.1.0" + assert meta.author == "Test Author" + # skill_type in FileBasedSkill.metadata is the raw value from frontmatter + assert getattr(meta, "skill_type") == "chat" + + # tags and required_tools should be lists parsed from the comma-separated string + assert isinstance(meta.tags, list) + assert "math" in meta.tags + assert "calculator" in meta.tags + + assert isinstance(meta.required_tools, list) + assert "calculate" in meta.required_tools + + # instructions content should be present + instructions = fskill.instructions + assert "You are a helpful math assistant" in instructions + + +def test_skillloader_converts_filebasedskill_to_core_skill(tmp_path): + """SkillLoader should convert a SKILL.md into a core Skill with mapped fields.""" + skill_md = """ +--- +name: math-assistant +description: Simple math assistant +version: 0.1.0 +author: Test Author +skill_type: chat +tags: math, calculator +required_tools: calculate, terminate +config: + precision: 2 +--- + +Compute the product of two numbers when asked. +""" + + file_path = tmp_path / "math_assistant" / "SKILL.md" + _write_skill_md(file_path, skill_md) + + from dbgpt.agent.skill.loader import SkillLoader + + loader = SkillLoader() + skill = loader.load_skill_from_file(str(file_path)) + + assert skill is not None + # metadata values should be mapped + assert skill.metadata.name == "math-assistant" + assert "math assistant" in skill.metadata.description + + # skill_type should be coerced to SkillType when possible + from dbgpt.agent.skill.base import SkillType + + assert isinstance(skill.metadata.skill_type, SkillType) + + # required_tools should be set on the core Skill + assert "calculate" in skill.required_tools + + # config is only available when PyYAML parsed the frontmatter; accept either {} + # or the dict with precision key. + cfg = getattr(skill, "config", {}) + if isinstance(cfg, dict): + # If PyYAML is available, config should include precision + if cfg: + assert cfg.get("precision") == 2 diff --git a/web/.opencode/init b/web/.opencode/init new file mode 100644 index 000000000..e69de29bb diff --git a/web/components/chat/chat-content/vis-tabs.tsx b/web/components/chat/chat-content/vis-tabs.tsx new file mode 100644 index 000000000..68d286054 --- /dev/null +++ b/web/components/chat/chat-content/vis-tabs.tsx @@ -0,0 +1,133 @@ +import { findParentElementByClassName } from '@/utils/dom'; +import { EVENTS, ee } from '@/utils/event-emitter'; +import { GPTVis } from '@antv/gpt-vis'; +import { Tabs } from 'antd'; +import { useEffect, useRef, useState } from 'react'; +import markdownComponents, { markdownPlugins, preprocessLaTeX } from './config'; + +export type VisTabsData = { + name: string; + status: string; + num: number; + task_id: string; + agent: string; + avatar: string; + markdown: string; +}; + +function getLastActiveKey(data: VisTabsData[]) { + // Get the last tab as the default active key + return data.length > 0 ? data[data.length - 1].task_id : ''; +} + +/** + * Show tabs ui for llm output. + * This tab pane is renderred with GPT-Vis. + */ +export function VisTabs({ data }: { data: VisTabsData[] }) { + // Currently, the last tab is active by default. + const [activeKey, setActiveKey] = useState(getLastActiveKey(data)); + const [isUserActive, setIsUserActive] = useState(false); + const [isAutoSroll, setIsAutoSroll] = useState(true); + const scrollRef = useRef(null); + + /** + * When the user scrolls to the bottom of the tab content, we will automatically scroll to the bottom of the tab content. + */ + function handleScroll() { + if (!scrollRef.current) return; + const container = findParentElementByClassName(scrollRef.current, 'overflow-y-auto'); + if (!container) return; + + const scrollTop = container.scrollTop; + const scrollHeight = container.scrollHeight; + const clientHeight = container.clientHeight; + const buffer = 10; // Small buffer for better UX + + const isAtBottom = scrollTop + clientHeight >= scrollHeight - buffer; + + setIsAutoSroll(isAtBottom); + } + + useEffect(() => { + if (!isUserActive) { + setActiveKey(getLastActiveKey(data)); + } + + if (isAutoSroll && !isUserActive) { + // If the user is not actively switching tabs, we will scroll to the bottom of the tab content automatically + if (scrollRef.current) { + // Ensure the parent node is scrollable + const scrollContainer = findParentElementByClassName(scrollRef.current, 'overflow-y-auto'); + if (scrollContainer) { + // Scroll to the bottom of the parent node + scrollContainer.scrollTo({ + top: scrollContainer.scrollHeight, + }); + } + } + } + }, [data]); + + useEffect(() => { + ee.on(EVENTS.TASK_CLICK, (data: any) => { + setTabActiveByUser(data.taskId); + }); + + if (scrollRef.current) { + const scrollContainer = findParentElementByClassName(scrollRef.current, 'overflow-y-auto'); + if (scrollContainer) { + scrollContainer.addEventListener('scroll', handleScroll); + } + } + }, []); + + /** + * When the user clicks on a tab, we set the active key to the clicked tab. + * If the clicked tab is the last active key, we set isUserActive to false, + * indicating that the user is not actively switching tabs. + * Otherwise, we set isUserActive to true. + * This is used to determine whether to reset the active tab when new data arrives. + */ + function setTabActiveByUser(key: string) { + if (key === getLastActiveKey(data)) { + setIsUserActive(false); + } else { + setIsUserActive(true); + } + setActiveKey(key); + } + + /** + * Organize the data structure into the format required by the Tabs component + */ + function getTabItems() { + return data.map(content => { + const { agent, markdown, task_id } = content; + return { + key: task_id, + label: ( +
+ {`${agent} + {agent} +
+ ), + children: ( + + {preprocessLaTeX(markdown)} + + ), + }; + }); + } + + return ( +
+ +
+ ); +} diff --git a/web/components/chat/chat-content/vis-tasks.tsx b/web/components/chat/chat-content/vis-tasks.tsx new file mode 100644 index 000000000..4a8b9a69d --- /dev/null +++ b/web/components/chat/chat-content/vis-tasks.tsx @@ -0,0 +1,73 @@ +import { ee, EVENTS } from '@/utils/event-emitter'; +import { CheckOutlined, ClockCircleOutlined, CloseOutlined, LoadingOutlined, PauseOutlined } from '@ant-design/icons'; + +export type VisTasksData = { + name: string; + content: string; + num: number; + status: string; + task_id: string; + model: string; + agent: string; + avatar: string; + tasks: string[]; +}; + +/** + * VisTasks component that displays a list of tasks. + * It contains no GPT-Vis components. + */ +export function VisTasks({ data }: { data: VisTasksData[] }) { + if (!data || !data.length) return null; + + function getStatusIcon(status: string) { + switch (status) { + case 'todo': + return ; + case 'running': + return ; + case 'waiting': + return ; + case 'retrying': + return ; + case 'failed': + return ; + case 'complete': + return ; + default: + return ; + } + } + + function onTaskClick(taskId: string) { + return () => { + // You can add any additional logic here, such as navigating to a task detail page + ee.emit(EVENTS.TASK_CLICK, { taskId }); + }; + } + + return ( +
+ {data.map(item => { + return ( +
+ +
+
+ + {item.name} @{item.agent} + + {getStatusIcon(item.status)} +
+
{item.content}
+
+
+ ); + })} +
+ ); +} diff --git a/web/components/chat/opencode-agent-chat-container.tsx b/web/components/chat/opencode-agent-chat-container.tsx new file mode 100644 index 000000000..5a4e9cad0 --- /dev/null +++ b/web/components/chat/opencode-agent-chat-container.tsx @@ -0,0 +1,306 @@ +/** + * OpenCode Agent Chat Container + * + * A dedicated chat container for agent mode that uses the ReAct Agent API + * with OpenCode-style UI rendering. This component replaces the default + * chat flow when scene === 'chat_agent'. + */ + +import { ChatContext } from '@/app/chat-context'; +import { apiInterceptors, getChatHistory } from '@/client/api'; +import { IChatDialogueMessageSchema } from '@/types/chat'; +import { STORAGE_INIT_MESSAGE_KET, getInitMessage } from '@/utils'; +import { useAsyncEffect } from 'ahooks'; +import { message } from 'antd'; +import classNames from 'classnames'; +import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; +import { useTranslation } from 'react-i18next'; + +import useReActAgent, { ReActAgentRequest, parseReActText } from '@/hooks/use-react-agent'; +import OpenCodeSessionTurn, { MessagePart } from '@/new-components/chat/content/OpenCodeSessionTurn'; +import MyEmpty from '../common/MyEmpty'; +import CompletionInput from '../common/completion-input'; +import MuiLoading from '../common/loading'; +import Header from './header'; +import { renderModelIcon } from './header/model-selector'; + +interface StreamingTurn { + userMessage: string; + parts: MessagePart[]; + finalContent: string; + isWorking: boolean; + startTime: number; + endTime?: number; +} + +interface HistoryTurn { + human?: IChatDialogueMessageSchema; + view?: IChatDialogueMessageSchema; +} + +const OpenCodeAgentChatContainer: React.FC = () => { + const { t } = useTranslation(); + const { scene, chatId, model, agent, setModel, history, setHistory } = useContext(ChatContext); + + const [loading, setLoading] = useState(false); + const [streamingTurn, setStreamingTurn] = useState(null); + const scrollableRef = useRef(null); + + const { + state: agentState, + sendMessage, + cancel, + reset: _reset, + } = useReActAgent({ + baseUrl: '/api/v1/chat/react-agent', + onPartUpdate: parts => { + setStreamingTurn(prev => (prev ? { ...prev, parts } : null)); + }, + onFinalContent: content => { + setStreamingTurn(prev => (prev ? { ...prev, finalContent: content } : null)); + }, + onComplete: () => { + setStreamingTurn(prev => { + if (!prev) return null; + + const endTime = Date.now(); + const newHistoryItem: IChatDialogueMessageSchema = { + role: 'view', + context: prev.finalContent || buildReActContext(prev.parts), + model_name: model, + order: history.length, + time_stamp: endTime, + }; + + setHistory(h => [...h, newHistoryItem]); + + return { ...prev, isWorking: false, endTime }; + }); + + setTimeout(() => setStreamingTurn(null), 100); + }, + onError: error => { + message.error(error); + setStreamingTurn(prev => (prev ? { ...prev, isWorking: false } : null)); + }, + }); + + const getHistory = useCallback(async () => { + setLoading(true); + const [, res] = await apiInterceptors(getChatHistory(chatId)); + setHistory(res ?? []); + setLoading(false); + }, [chatId, setHistory]); + + useAsyncEffect(async () => { + const initMessage = getInitMessage(); + if (initMessage && initMessage.id === chatId) return; + await getHistory(); + }, [chatId]); + + useEffect(() => { + if (!history.length) return; + const lastView = history.filter(i => i.role === 'view')?.slice(-1)?.[0]; + lastView?.model_name && setModel(lastView.model_name); + }, [history.length, setModel]); + + useEffect(() => { + return () => { + setHistory([]); + cancel(); + }; + }, [setHistory, cancel]); + + const handleChat = useCallback( + async (content: string, data?: Record) => { + if (!content.trim()) return; + if (!agent) { + message.warning(t('choice_agent_tip')); + return; + } + + const humanMessage: IChatDialogueMessageSchema = { + role: 'human', + context: content, + model_name: model, + order: history.length, + time_stamp: Date.now(), + }; + setHistory(h => [...h, humanMessage]); + + setStreamingTurn({ + userMessage: content, + parts: [], + finalContent: '', + isWorking: true, + startTime: Date.now(), + }); + + const request: ReActAgentRequest = { + user_input: content, + conv_uid: chatId, + chat_mode: scene || 'chat_agent', + model_name: model, + select_param: agent, + temperature: 0.2, + ...data, + }; + + await sendMessage(request); + }, + [agent, model, chatId, scene, history.length, setHistory, sendMessage, t], + ); + + useAsyncEffect(async () => { + const initMessage = getInitMessage(); + if (initMessage && initMessage.id === chatId) { + await handleChat(initMessage.message); + localStorage.removeItem(STORAGE_INIT_MESSAGE_KET); + } + }, [chatId]); + + const groupedHistory = useMemo(() => { + const groups: HistoryTurn[] = []; + let currentGroup: HistoryTurn = {}; + + for (const msg of history) { + if (msg.role === 'human') { + if (currentGroup.human || currentGroup.view) { + groups.push(currentGroup); + } + currentGroup = { human: msg }; + } else if (msg.role === 'view') { + currentGroup.view = msg; + groups.push(currentGroup); + currentGroup = {}; + } + } + + if (currentGroup.human || currentGroup.view) { + groups.push(currentGroup); + } + + return groups; + }, [history]); + + useEffect(() => { + if (scrollableRef.current) { + scrollableRef.current.scrollTo({ + top: scrollableRef.current.scrollHeight, + behavior: 'smooth', + }); + } + }, [groupedHistory.length, streamingTurn?.parts.length, streamingTurn?.finalContent]); + + const renderHistoryTurn = (turn: HistoryTurn, index: number) => { + const userMessage = turn.human?.context + ? typeof turn.human.context === 'string' + ? turn.human.context + : JSON.stringify(turn.human.context) + : ''; + + let assistantMessage = ''; + let parts: MessagePart[] = []; + + if (turn.view?.context) { + const contextStr = typeof turn.view.context === 'string' ? turn.view.context : JSON.stringify(turn.view.context); + + const parsed = parseReActText(contextStr); + parts = parsed.parts; + assistantMessage = parsed.finalContent || contextStr; + } + + return ( + 0} + defaultStepsExpanded={false} + modelName={turn.view?.model_name || model} + className='w-full' + /> + ); + }; + + const isWorking = streamingTurn?.isWorking || agentState.isWorking; + + return ( +
+ + +
+
setModel(newModel)} /> +
+ +
+
+
+ {groupedHistory.length === 0 && !streamingTurn ? ( + + ) : ( + <> + {groupedHistory.map((turn, index) => renderHistoryTurn(turn, index))} + + {streamingTurn && ( + + )} + + )} +
+
+ +
+
+ {model &&
{renderModelIcon(model)}
} + {}} /> +
+
+
+
+ ); +}; + +function buildReActContext(parts: MessagePart[]): string { + const lines: string[] = []; + + for (const part of parts) { + if (part.type === 'reasoning') { + lines.push(`Thought: ${part.text}`); + } else if (part.type === 'tool') { + const toolPart = part as MessagePart & { tool: string; state: any }; + const action = toolPart.state?.metadata?.action || toolPart.tool; + lines.push(`Action: ${action}`); + if (toolPart.state?.input) { + lines.push(`Action Input: ${JSON.stringify(toolPart.state.input)}`); + } + if (toolPart.state?.output) { + lines.push(`Observation: ${toolPart.state.output}`); + } + } + } + + return lines.join('\n'); +} + +export default OpenCodeAgentChatContainer; diff --git a/web/components/chat/opencode-agent-content.tsx b/web/components/chat/opencode-agent-content.tsx new file mode 100644 index 000000000..f1f526adc --- /dev/null +++ b/web/components/chat/opencode-agent-content.tsx @@ -0,0 +1,261 @@ +/** + * OpenCode Agent Content Component + * + * Renders chat_agent messages in OpenCode style using OpenCodeSessionTurn. + * This component handles both: + * 1. Historical messages (parsing ReAct format from context string) + * 2. Streaming messages (receiving real-time updates via props) + */ + +import { ChatContext } from '@/app/chat-context'; +import { parseReActText } from '@/hooks/use-react-agent'; +import OpenCodeSessionTurn, { MessagePart } from '@/new-components/chat/content/OpenCodeSessionTurn'; +import { IChatDialogueMessageSchema } from '@/types/chat'; +import classNames from 'classnames'; +import { memo, useContext, useMemo } from 'react'; + +interface Props { + content: IChatDialogueMessageSchema; + /** Optional streaming parts (for real-time updates) */ + streamingParts?: MessagePart[]; + /** Optional streaming final content */ + streamingFinalContent?: string; + /** Is currently working (streaming in progress) */ + isWorking?: boolean; + /** Start time for duration tracking */ + startTime?: number; + /** End time for duration tracking */ + endTime?: number; + /** Current status text */ + currentStatus?: string; + /** Additional className */ + className?: string; +} + +/** + * Parse ReAct format text from message context + * This handles the historical messages stored in the database + */ +function parseContextToMessageParts(context: string): { parts: MessagePart[]; finalContent: string } { + if (!context || typeof context !== 'string') { + return { parts: [], finalContent: '' }; + } + + // Check if this looks like ReAct format + const hasReActFormat = + context.includes('Thought:') || + context.includes('Action:') || + context.includes('Action Input:') || + context.includes('Observation:'); + + if (!hasReActFormat) { + // Not ReAct format, return as plain text + return { parts: [], finalContent: context }; + } + + // Use the parseReActText function from the hook + return parseReActText(context); +} + +/** + * Extract user message and assistant response from message pair + */ +function extractMessages( + content: IChatDialogueMessageSchema, + allMessages?: IChatDialogueMessageSchema[], +): { userMessage: string; assistantMessage: string; parts: MessagePart[] } { + const isView = content.role === 'view'; + const context = typeof content.context === 'string' ? content.context : JSON.stringify(content.context); + + if (isView) { + // This is an assistant message (view role) + const { parts, finalContent } = parseContextToMessageParts(context); + + // Try to find the corresponding user message + let userMessage = ''; + if (allMessages && content.order !== undefined) { + const humanMsg = allMessages.find(m => m.role === 'human' && m.order === content.order); + if (humanMsg) { + userMessage = typeof humanMsg.context === 'string' ? humanMsg.context : JSON.stringify(humanMsg.context); + } + } + + return { + userMessage, + assistantMessage: finalContent || context, + parts, + }; + } else { + // This is a user message (human role) + return { + userMessage: context, + assistantMessage: '', + parts: [], + }; + } +} + +/** + * OpenCode Agent Content Component + * + * Renders agent messages with OpenCode-style tool execution visualization. + */ +function OpenCodeAgentContent({ + content, + streamingParts, + streamingFinalContent, + isWorking = false, + startTime, + endTime, + currentStatus: _currentStatus, + className, +}: Props) { + const { model } = useContext(ChatContext); + const isView = content.role === 'view'; + + // Parse the content to get message parts + const { userMessage, assistantMessage, parts } = useMemo(() => { + return extractMessages(content); + }, [content]); + + // Use streaming parts if provided, otherwise use parsed parts + const displayParts = streamingParts || parts; + const displayFinalContent = streamingFinalContent ?? assistantMessage; + + // Only render view messages with OpenCodeSessionTurn + // Human messages will be rendered as part of the next view message + if (!isView) { + // For human messages, we just show the message simply + // The full OpenCode turn will be rendered when the view message comes + return ( +
+ +
+ ); + } + + return ( +
+ 0} + defaultStepsExpanded={false} + modelName={model} + stepsPlacement='outside' + /> +
+ ); +} + +export default memo(OpenCodeAgentContent); + +/** + * OpenCode Agent Message Pair Component + * + * Renders a pair of user + assistant messages together as one OpenCode turn. + * This is useful when we have both messages available. + */ +interface MessagePairProps { + humanMessage: IChatDialogueMessageSchema; + viewMessage: IChatDialogueMessageSchema; + streamingParts?: MessagePart[]; + streamingFinalContent?: string; + isWorking?: boolean; + startTime?: number; + endTime?: number; + className?: string; +} + +export const OpenCodeAgentMessagePair = memo(function OpenCodeAgentMessagePair({ + humanMessage, + viewMessage, + streamingParts, + streamingFinalContent, + isWorking = false, + startTime, + endTime, + className, +}: MessagePairProps) { + const { model } = useContext(ChatContext); + + // Get user message content + const userMessage = useMemo(() => { + const ctx = humanMessage.context; + return typeof ctx === 'string' ? ctx : JSON.stringify(ctx); + }, [humanMessage]); + + // Parse view message + const { parts, finalContent } = useMemo(() => { + const ctx = viewMessage.context; + const contextStr = typeof ctx === 'string' ? ctx : JSON.stringify(ctx); + return parseContextToMessageParts(contextStr); + }, [viewMessage]); + + // Use streaming data if provided + const displayParts = streamingParts || parts; + const displayFinalContent = streamingFinalContent ?? finalContent; + + return ( +
+ 0} + defaultStepsExpanded={false} + modelName={model} + stepsPlacement='outside' + /> +
+ ); +}); + +/** + * Hook to group messages into pairs for OpenCode rendering + */ +export function useGroupedMessages( + messages: IChatDialogueMessageSchema[], +): Array<{ human?: IChatDialogueMessageSchema; view?: IChatDialogueMessageSchema }> { + return useMemo(() => { + const groups: Array<{ human?: IChatDialogueMessageSchema; view?: IChatDialogueMessageSchema }> = []; + + let currentGroup: { human?: IChatDialogueMessageSchema; view?: IChatDialogueMessageSchema } = {}; + + for (const msg of messages) { + if (msg.role === 'human') { + // Start a new group with human message + if (currentGroup.human || currentGroup.view) { + groups.push(currentGroup); + } + currentGroup = { human: msg }; + } else if (msg.role === 'view') { + // Add view to current group + currentGroup.view = msg; + groups.push(currentGroup); + currentGroup = {}; + } + } + + // Don't forget the last group if it has content + if (currentGroup.human || currentGroup.view) { + groups.push(currentGroup); + } + + return groups; + }, [messages]); +} diff --git a/web/hooks/use-react-agent-chat.ts b/web/hooks/use-react-agent-chat.ts new file mode 100644 index 000000000..2f76a2139 --- /dev/null +++ b/web/hooks/use-react-agent-chat.ts @@ -0,0 +1,371 @@ +/** + * useReActAgentChat Hook + * + * Integrates the ReAct Agent API with the chat flow. + * Manages streaming state, history updates, and message formatting. + */ + +import { MessagePart, ToolPart } from '@/new-components/chat/content/OpenCodeSessionTurn'; +import { ChatHistoryResponse } from '@/types/chat'; +import { ReActSSEState, createReActSSEState, parseSSELine } from '@/utils/react-sse-parser'; +import { useCallback, useEffect, useRef, useState } from 'react'; + +export interface ReActChatRequest { + user_input: string; + conv_uid: string; + chat_mode?: string; + model_name?: string; + app_code?: string; + temperature?: number; + max_new_tokens?: number; + select_param?: string; + [key: string]: any; +} + +export interface StreamingTurn { + userMessage: string; + parts: MessagePart[]; + finalContent: string; + isWorking: boolean; + startTime: number; + endTime?: number; + currentStatus: string; + thinkingContent?: string; +} + +export interface UseReActAgentChatOptions { + baseUrl?: string; + onHistoryUpdate?: (history: ChatHistoryResponse) => void; + onError?: (error: string) => void; + onComplete?: () => void; +} + +export interface UseReActAgentChatReturn { + streamingTurn: StreamingTurn | null; + isStreaming: boolean; + sendMessage: ( + request: ReActChatRequest, + currentHistory: ChatHistoryResponse, + order: number, + ) => Promise; + cancel: () => void; +} + +export function useReActAgentChat(options: UseReActAgentChatOptions = {}): UseReActAgentChatReturn { + const { baseUrl = '/api/v1/chat/react-agent', onHistoryUpdate, onError, onComplete } = options; + + const [streamingTurn, setStreamingTurn] = useState(null); + const [isStreaming, setIsStreaming] = useState(false); + + const abortControllerRef = useRef(null); + const sseStateRef = useRef(null); + const readerRef = useRef | null>(null); + + // Cleanup on unmount + useEffect(() => { + return () => { + cancel(); + }; + }, []); + + const cancel = useCallback(() => { + if (abortControllerRef.current) { + abortControllerRef.current.abort(); + abortControllerRef.current = null; + } + if (readerRef.current) { + readerRef.current.cancel(); + readerRef.current = null; + } + setIsStreaming(false); + setStreamingTurn(prev => { + if (prev) { + return { ...prev, isWorking: false, endTime: Date.now() }; + } + return null; + }); + }, []); + + const processSSELine = useCallback((line: string) => { + if (!sseStateRef.current) return; + + const event = parseSSELine(line); + if (!event) return; + + sseStateRef.current.processEvent(event); + + // Update streaming turn state + const parts = sseStateRef.current.toMessageParts(); + const finalContent = sseStateRef.current.getFinalContent(); + const isWorking = sseStateRef.current.isWorking(); + const currentStatus = sseStateRef.current.getCurrentStatus(); + + // Extract thinking content from reasoning parts + const reasoningParts = parts.filter(p => p.type === 'reasoning'); + const thinkingContent = reasoningParts.length > 0 ? reasoningParts.map(p => (p as any).text).join('\n') : undefined; + + setStreamingTurn(prev => { + if (!prev) return null; + return { + ...prev, + parts, + finalContent, + isWorking, + currentStatus, + thinkingContent, + endTime: sseStateRef.current?.isComplete() ? sseStateRef.current.getEndTime() : undefined, + }; + }); + }, []); + + const sendMessage = useCallback( + async ( + request: ReActChatRequest, + currentHistory: ChatHistoryResponse, + order: number, + ): Promise => { + // Cancel any existing request + cancel(); + + // Initialize state + sseStateRef.current = createReActSSEState(); + abortControllerRef.current = new AbortController(); + setIsStreaming(true); + + const userMessage = + typeof request.user_input === 'string' ? request.user_input : JSON.stringify(request.user_input); + + // Initialize streaming turn + const startTime = Date.now(); + setStreamingTurn({ + userMessage, + parts: [], + finalContent: '', + isWorking: true, + startTime, + currentStatus: 'Starting...', + }); + + // Add human message to history immediately + const tempHistory: ChatHistoryResponse = [ + ...currentHistory, + { + role: 'human', + context: userMessage, + model_name: request.model_name || '', + order: order, + time_stamp: startTime, + }, + { + role: 'view', + context: '', + model_name: request.model_name || '', + order: order, + time_stamp: startTime, + thinking: true, + }, + ]; + + if (onHistoryUpdate) { + onHistoryUpdate(tempHistory); + } + + try { + const response = await fetch(baseUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Accept: 'text/event-stream', + }, + body: JSON.stringify(request), + signal: abortControllerRef.current.signal, + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + if (!response.body) { + throw new Error('Response body is null'); + } + + const reader = response.body.getReader(); + readerRef.current = reader; + const decoder = new TextDecoder(); + let buffer = ''; + + while (true) { + const { done, value } = await reader.read(); + + if (done) { + // Process any remaining buffer + if (buffer.trim()) { + const lines = buffer.split('\n'); + for (const line of lines) { + if (line.trim()) { + processSSELine(line.trim()); + } + } + } + break; + } + + // Decode chunk and add to buffer + buffer += decoder.decode(value, { stream: true }); + + // Process complete lines + const lines = buffer.split('\n'); + buffer = lines.pop() || ''; // Keep incomplete line in buffer + + for (const line of lines) { + const trimmedLine = line.trim(); + if (trimmedLine) { + processSSELine(trimmedLine); + } + } + } + + // Get final state + const finalParts = sseStateRef.current?.toMessageParts() || []; + const finalContent = sseStateRef.current?.getFinalContent() || ''; + + // Format final response for history + // Combine tool parts and final content into a structured response + const formattedResponse = formatReActResponse(finalParts, finalContent); + + // Update final history + const finalHistory: ChatHistoryResponse = [ + ...currentHistory, + { + role: 'human', + context: userMessage, + model_name: request.model_name || '', + order: order, + time_stamp: startTime, + }, + { + role: 'view', + context: formattedResponse, + model_name: request.model_name || '', + order: order, + time_stamp: Date.now(), + thinking: false, + }, + ]; + + // Clear streaming turn after a brief delay + setTimeout(() => { + setStreamingTurn(null); + setIsStreaming(false); + }, 300); + + if (onHistoryUpdate) { + onHistoryUpdate(finalHistory); + } + + if (onComplete) { + onComplete(); + } + + return finalHistory; + } catch (error: any) { + if (error.name === 'AbortError') { + // Request was cancelled + return tempHistory; + } + + const errorMessage = error.message || 'Unknown error occurred'; + + setStreamingTurn(prev => { + if (prev) { + return { ...prev, isWorking: false, endTime: Date.now() }; + } + return null; + }); + setIsStreaming(false); + + // Update history with error + const errorHistory: ChatHistoryResponse = [ + ...currentHistory, + { + role: 'human', + context: userMessage, + model_name: request.model_name || '', + order: order, + time_stamp: startTime, + }, + { + role: 'view', + context: `Error: ${errorMessage}`, + model_name: request.model_name || '', + order: order, + time_stamp: Date.now(), + thinking: false, + }, + ]; + + if (onHistoryUpdate) { + onHistoryUpdate(errorHistory); + } + + if (onError) { + onError(errorMessage); + } + + return errorHistory; + } + }, + [baseUrl, cancel, processSSELine, onHistoryUpdate, onError, onComplete], + ); + + return { + streamingTurn, + isStreaming, + sendMessage, + cancel, + }; +} + +/** + * Format ReAct response parts into a storable string format + * This preserves tool execution info in a parseable format + */ +function formatReActResponse(parts: MessagePart[], finalContent: string): string { + const toolParts = parts.filter(p => p.type === 'tool') as ToolPart[]; + + if (toolParts.length === 0) { + return finalContent; + } + + // Format as ReAct-style text that can be parsed later + let formatted = ''; + let stepNum = 0; + + for (const part of parts) { + if (part.type === 'reasoning') { + formatted += `Thought: ${(part as any).text}\n`; + } else if (part.type === 'tool') { + const tool = part as ToolPart; + stepNum++; + const action = tool.state.metadata?.action || tool.tool; + formatted += `Action: ${action}\n`; + if (tool.state.input) { + formatted += `Action Input: ${JSON.stringify(tool.state.input)}\n`; + } + if (tool.state.output) { + formatted += `Observation: ${tool.state.output}\n`; + } + if (tool.state.error) { + formatted += `Error: ${tool.state.error}\n`; + } + } + } + + if (finalContent) { + formatted += `\nFinal Answer: ${finalContent}`; + } + + return formatted || finalContent; +} + +export default useReActAgentChat; diff --git a/web/hooks/use-react-agent.ts b/web/hooks/use-react-agent.ts new file mode 100644 index 000000000..554243aab --- /dev/null +++ b/web/hooks/use-react-agent.ts @@ -0,0 +1,374 @@ +/** + * useReActAgent Hook + * + * Custom React hook for interacting with the DB-GPT ReAct Agent API. + * Handles SSE streaming and converts events to OpenCode MessagePart format. + */ + +import { MessagePart, ReasoningPart, ToolPart } from '@/new-components/chat/content/OpenCodeSessionTurn'; +import { ReActSSEState, createReActSSEState, parseSSELine } from '@/utils/react-sse-parser'; +import { useCallback, useEffect, useRef, useState } from 'react'; + +export interface ReActAgentRequest { + user_input: string; + conv_uid?: string; + chat_mode?: string; + model_name?: string; + select_param?: string; + temperature?: number; + ext_info?: Record; +} + +export interface ReActAgentState { + isWorking: boolean; + parts: MessagePart[]; + finalContent: string; + error: string | null; + startTime: number | null; + endTime: number | null; + currentStatus: string; +} + +export interface UseReActAgentOptions { + baseUrl?: string; + onPartUpdate?: (parts: MessagePart[]) => void; + onFinalContent?: (content: string) => void; + onError?: (error: string) => void; + onComplete?: () => void; +} + +export interface UseReActAgentReturn { + state: ReActAgentState; + sendMessage: (request: ReActAgentRequest) => Promise; + cancel: () => void; + reset: () => void; +} + +const initialState: ReActAgentState = { + isWorking: false, + parts: [], + finalContent: '', + error: null, + startTime: null, + endTime: null, + currentStatus: '', +}; + +export function useReActAgent(options: UseReActAgentOptions = {}): UseReActAgentReturn { + const { baseUrl = '/api/v1/chat/react-agent', onPartUpdate, onFinalContent, onError, onComplete } = options; + + const [state, setState] = useState(initialState); + const abortControllerRef = useRef(null); + const sseStateRef = useRef(null); + const readerRef = useRef | null>(null); + + // Cleanup on unmount + useEffect(() => { + return () => { + cancel(); + }; + }, []); + + const cancel = useCallback(() => { + if (abortControllerRef.current) { + abortControllerRef.current.abort(); + abortControllerRef.current = null; + } + if (readerRef.current) { + readerRef.current.cancel(); + readerRef.current = null; + } + setState(prev => ({ + ...prev, + isWorking: false, + endTime: Date.now(), + })); + }, []); + + const reset = useCallback(() => { + cancel(); + setState(initialState); + sseStateRef.current = null; + }, [cancel]); + + const processSSELine = useCallback( + (line: string) => { + if (!sseStateRef.current) return; + + const event = parseSSELine(line); + if (!event) return; + + sseStateRef.current.processEvent(event); + + // Update React state + const parts = sseStateRef.current.toMessageParts(); + const finalContent = sseStateRef.current.getFinalContent(); + const isWorking = sseStateRef.current.isWorking(); + const currentStatus = sseStateRef.current.getCurrentStatus(); + + setState(prev => ({ + ...prev, + parts, + finalContent, + isWorking, + currentStatus, + endTime: sseStateRef.current?.isComplete() ? (sseStateRef.current.getEndTime() ?? null) : null, + })); + + // Trigger callbacks + if (onPartUpdate) { + onPartUpdate(parts); + } + + if (event.type === 'final' && onFinalContent) { + onFinalContent(finalContent); + } + + if (event.type === 'done' && onComplete) { + onComplete(); + } + }, + [onPartUpdate, onFinalContent, onComplete], + ); + + const sendMessage = useCallback( + async (request: ReActAgentRequest) => { + // Cancel any existing request + cancel(); + + // Initialize state + sseStateRef.current = createReActSSEState(); + abortControllerRef.current = new AbortController(); + + setState({ + isWorking: true, + parts: [], + finalContent: '', + error: null, + startTime: Date.now(), + endTime: null, + currentStatus: 'Starting...', + }); + + try { + const response = await fetch(baseUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Accept: 'text/event-stream', + }, + body: JSON.stringify(request), + signal: abortControllerRef.current.signal, + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + if (!response.body) { + throw new Error('Response body is null'); + } + + const reader = response.body.getReader(); + readerRef.current = reader; + const decoder = new TextDecoder(); + let buffer = ''; + + while (true) { + const { done, value } = await reader.read(); + + if (done) { + // Process any remaining buffer + if (buffer.trim()) { + const lines = buffer.split('\n'); + for (const line of lines) { + if (line.trim()) { + processSSELine(line.trim()); + } + } + } + break; + } + + // Decode chunk and add to buffer + buffer += decoder.decode(value, { stream: true }); + + // Process complete lines + const lines = buffer.split('\n'); + buffer = lines.pop() || ''; // Keep incomplete line in buffer + + for (const line of lines) { + const trimmedLine = line.trim(); + if (trimmedLine) { + processSSELine(trimmedLine); + } + } + } + + // Mark as complete + setState(prev => ({ + ...prev, + isWorking: false, + endTime: Date.now(), + })); + } catch (error: any) { + if (error.name === 'AbortError') { + // Request was cancelled, don't treat as error + return; + } + + const errorMessage = error.message || 'Unknown error occurred'; + + setState(prev => ({ + ...prev, + isWorking: false, + error: errorMessage, + endTime: Date.now(), + })); + + if (onError) { + onError(errorMessage); + } + } + }, + [baseUrl, cancel, processSSELine, onError], + ); + + return { + state, + sendMessage, + cancel, + reset, + }; +} + +/** + * Parse existing ReAct format text (non-streaming) + * Useful for rendering historical messages that contain ReAct format + */ +export function parseReActText(text: string): { parts: MessagePart[]; finalContent: string } { + const parts: MessagePart[] = []; + let finalContent = ''; + + // Pattern to match ReAct format + const thoughtPattern = /Thought:\s*(.*?)(?=Action:|Observation:|$)/gs; + const actionPattern = /Action:\s*(.*?)(?=Action Input:|Observation:|$)/gs; + const actionInputPattern = /Action Input:\s*(.*?)(?=Observation:|Thought:|$)/gs; + const observationPattern = /Observation:\s*(.*?)(?=Thought:|$)/gs; + + let stepNum = 0; + let currentThought = ''; + let currentAction = ''; + let currentActionInput: any = null; + + // Split by "Thought:" to get individual steps + const sections = text.split(/(?=Thought:)/); + + for (const section of sections) { + if (!section.trim()) continue; + + // Extract thought + const thoughtMatch = section.match(/Thought:\s*(.*?)(?=Action:|Observation:|$)/s); + if (thoughtMatch) { + currentThought = thoughtMatch[1].trim(); + } + + // Extract action + const actionMatch = section.match(/Action:\s*(.*?)(?=Action Input:|Observation:|$)/s); + if (actionMatch) { + currentAction = actionMatch[1].trim(); + } + + // Extract action input + const inputMatch = section.match(/Action Input:\s*(.*?)(?=Observation:|Thought:|$)/s); + if (inputMatch) { + const inputText = inputMatch[1].trim(); + try { + currentActionInput = JSON.parse(inputText); + } catch { + currentActionInput = { value: inputText }; + } + } + + // Extract observation + const obsMatch = section.match(/Observation:\s*(.*?)(?=Thought:|$)/s); + const observation = obsMatch ? obsMatch[1].trim() : ''; + + // Check if this is a terminate action + if (currentAction.toLowerCase() === 'terminate') { + if (currentActionInput && currentActionInput.output) { + finalContent = currentActionInput.output; + } + currentThought = ''; + currentAction = ''; + currentActionInput = null; + continue; + } + + // Only add if we have something meaningful + if (currentThought || currentAction) { + stepNum++; + const stepId = `react-step-${stepNum}`; + + // Add reasoning part if we have a thought + if (currentThought) { + parts.push({ + id: `${stepId}-reasoning`, + type: 'reasoning', + text: currentThought, + } as ReasoningPart); + } + + // Add tool part + const toolPart: ToolPart = { + id: stepId, + type: 'tool', + tool: mapActionToTool(currentAction), + state: { + status: 'completed', + input: currentActionInput, + output: observation || undefined, + metadata: { action: currentAction }, + }, + }; + parts.push(toolPart); + } + + // Reset for next iteration + currentThought = ''; + currentAction = ''; + currentActionInput = null; + } + + return { parts, finalContent }; +} + +/** + * Map action name to OpenCode tool type + */ +function mapActionToTool(action: string): string { + const lowerAction = action.toLowerCase(); + + const actionMap: Record = { + load_skills: 'list', + select_skill: 'question', + load_skill: 'skill', + load_file: 'read', + execute_analysis: 'bash', + load_tools: 'list', + execute_tool: 'bash', + terminate: 'task', + read: 'read', + write: 'write', + edit: 'edit', + search: 'grep', + grep: 'grep', + glob: 'glob', + bash: 'bash', + webfetch: 'webfetch', + }; + + return actionMap[lowerAction] || 'task'; +} + +export default useReActAgent; diff --git a/web/new-components/analysis/DataAnalyzer.tsx b/web/new-components/analysis/DataAnalyzer.tsx new file mode 100644 index 000000000..c6521afd7 --- /dev/null +++ b/web/new-components/analysis/DataAnalyzer.tsx @@ -0,0 +1,645 @@ +import { + ArrowDownOutlined, + ArrowUpOutlined, + CheckCircleOutlined, + InfoCircleOutlined, + WarningOutlined, +} from '@ant-design/icons'; +import { Card, Col, Progress, Row, Statistic, Tag, Tooltip } from 'antd'; +import React, { useMemo } from 'react'; + +export interface DataColumn { + name: string; + type: 'number' | 'string' | 'date' | 'boolean' | 'unknown'; + values: any[]; +} + +export interface StatisticalSummary { + count: number; + mean?: number; + median?: number; + mode?: any; + stdDev?: number; + variance?: number; + min?: number; + max?: number; + range?: number; + q1?: number; + q3?: number; + iqr?: number; + skewness?: number; + kurtosis?: number; + uniqueCount: number; + nullCount: number; + nullPercentage: number; +} + +export interface TrendAnalysis { + direction: 'up' | 'down' | 'stable'; + changePercent: number; + slope: number; + correlation: number; + seasonality?: string; + forecast?: number[]; +} + +export interface AnomalyResult { + index: number; + value: any; + zscore: number; + isAnomaly: boolean; + reason: string; +} + +export interface ColumnAnalysis { + column: string; + type: string; + stats: StatisticalSummary; + trend?: TrendAnalysis; + anomalies: AnomalyResult[]; + quality: { + score: number; + issues: string[]; + }; +} + +const detectColumnType = (values: any[]): 'number' | 'string' | 'date' | 'boolean' | 'unknown' => { + const nonNullValues = values.filter(v => v !== null && v !== undefined && v !== ''); + if (nonNullValues.length === 0) return 'unknown'; + + const sample = nonNullValues.slice(0, 100); + + const numericCount = sample.filter(v => !isNaN(Number(v)) && v !== '').length; + if (numericCount / sample.length > 0.8) return 'number'; + + const booleanCount = sample.filter( + v => typeof v === 'boolean' || ['true', 'false', '1', '0', 'yes', 'no'].includes(String(v).toLowerCase()), + ).length; + if (booleanCount / sample.length > 0.8) return 'boolean'; + + const dateCount = sample.filter(v => { + const d = new Date(v); + return !isNaN(d.getTime()) && String(v).length > 4; + }).length; + if (dateCount / sample.length > 0.8) return 'date'; + + return 'string'; +}; + +const calculateStatistics = (values: any[], type: string): StatisticalSummary => { + const nonNullValues = values.filter(v => v !== null && v !== undefined && v !== ''); + const nullCount = values.length - nonNullValues.length; + const uniqueValues = new Set(nonNullValues); + + const baseSummary: StatisticalSummary = { + count: values.length, + uniqueCount: uniqueValues.size, + nullCount, + nullPercentage: (nullCount / values.length) * 100, + }; + + if (type !== 'number') { + const frequency: Record = {}; + nonNullValues.forEach(v => { + const key = String(v); + frequency[key] = (frequency[key] || 0) + 1; + }); + const sortedByFreq = Object.entries(frequency).sort((a, b) => b[1] - a[1]); + baseSummary.mode = sortedByFreq[0]?.[0]; + return baseSummary; + } + + const numbers = nonNullValues + .map(Number) + .filter(n => !isNaN(n)) + .sort((a, b) => a - b); + if (numbers.length === 0) return baseSummary; + + const sum = numbers.reduce((a, b) => a + b, 0); + const mean = sum / numbers.length; + + const mid = Math.floor(numbers.length / 2); + const median = numbers.length % 2 ? numbers[mid] : (numbers[mid - 1] + numbers[mid]) / 2; + + const squaredDiffs = numbers.map(n => Math.pow(n - mean, 2)); + const variance = squaredDiffs.reduce((a, b) => a + b, 0) / numbers.length; + const stdDev = Math.sqrt(variance); + + const q1Index = Math.floor(numbers.length * 0.25); + const q3Index = Math.floor(numbers.length * 0.75); + const q1 = numbers[q1Index]; + const q3 = numbers[q3Index]; + const iqr = q3 - q1; + + const cubedDiffs = numbers.map(n => Math.pow((n - mean) / stdDev, 3)); + const skewness = stdDev > 0 ? cubedDiffs.reduce((a, b) => a + b, 0) / numbers.length : 0; + + const fourthDiffs = numbers.map(n => Math.pow((n - mean) / stdDev, 4)); + const kurtosis = stdDev > 0 ? fourthDiffs.reduce((a, b) => a + b, 0) / numbers.length - 3 : 0; + + const frequency: Record = {}; + numbers.forEach(n => { + frequency[n] = (frequency[n] || 0) + 1; + }); + const maxFreq = Math.max(...Object.values(frequency)); + const mode = Number(Object.entries(frequency).find(([, f]) => f === maxFreq)?.[0]); + + return { + ...baseSummary, + mean, + median, + mode, + stdDev, + variance, + min: numbers[0], + max: numbers[numbers.length - 1], + range: numbers[numbers.length - 1] - numbers[0], + q1, + q3, + iqr, + skewness, + kurtosis, + }; +}; + +const analyzeTrend = (values: number[]): TrendAnalysis => { + const validValues = values.filter(v => !isNaN(v) && v !== null); + if (validValues.length < 3) { + return { direction: 'stable', changePercent: 0, slope: 0, correlation: 0 }; + } + + const n = validValues.length; + const xMean = (n - 1) / 2; + const yMean = validValues.reduce((a, b) => a + b, 0) / n; + + let numerator = 0; + let denominator = 0; + for (let i = 0; i < n; i++) { + numerator += (i - xMean) * (validValues[i] - yMean); + denominator += Math.pow(i - xMean, 2); + } + const slope = denominator !== 0 ? numerator / denominator : 0; + + const yPredicted = validValues.map((_, i) => yMean + slope * (i - xMean)); + const ssRes = validValues.reduce((sum, y, i) => sum + Math.pow(y - yPredicted[i], 2), 0); + const ssTot = validValues.reduce((sum, y) => sum + Math.pow(y - yMean, 2), 0); + const correlation = ssTot !== 0 ? Math.sqrt(1 - ssRes / ssTot) : 0; + + const firstHalf = validValues.slice(0, Math.floor(n / 2)); + const secondHalf = validValues.slice(Math.floor(n / 2)); + const firstMean = firstHalf.reduce((a, b) => a + b, 0) / firstHalf.length; + const secondMean = secondHalf.reduce((a, b) => a + b, 0) / secondHalf.length; + const changePercent = firstMean !== 0 ? ((secondMean - firstMean) / Math.abs(firstMean)) * 100 : 0; + + let direction: 'up' | 'down' | 'stable' = 'stable'; + if (Math.abs(changePercent) > 5) { + direction = changePercent > 0 ? 'up' : 'down'; + } + + return { + direction, + changePercent, + slope, + correlation: slope >= 0 ? correlation : -correlation, + }; +}; + +const detectAnomalies = (values: any[], type: string, threshold: number = 2.5): AnomalyResult[] => { + if (type !== 'number') return []; + + const numbers = values.map((v, i) => ({ value: Number(v), index: i })).filter(n => !isNaN(n.value)); + if (numbers.length < 10) return []; + + const vals = numbers.map(n => n.value); + const mean = vals.reduce((a, b) => a + b, 0) / vals.length; + const stdDev = Math.sqrt(vals.reduce((sum, v) => sum + Math.pow(v - mean, 2), 0) / vals.length); + + if (stdDev === 0) return []; + + const sorted = [...vals].sort((a, b) => a - b); + const q1 = sorted[Math.floor(sorted.length * 0.25)]; + const q3 = sorted[Math.floor(sorted.length * 0.75)]; + const iqr = q3 - q1; + const lowerBound = q1 - 1.5 * iqr; + const upperBound = q3 + 1.5 * iqr; + + return numbers + .map(({ value, index }) => { + const zscore = (value - mean) / stdDev; + const isZScoreAnomaly = Math.abs(zscore) > threshold; + const isIQRAnomaly = value < lowerBound || value > upperBound; + const isAnomaly = isZScoreAnomaly || isIQRAnomaly; + + let reason = ''; + if (isZScoreAnomaly && isIQRAnomaly) { + reason = `Z-score: ${zscore.toFixed(2)}, Outside IQR bounds`; + } else if (isZScoreAnomaly) { + reason = `Z-score: ${zscore.toFixed(2)} exceeds threshold`; + } else if (isIQRAnomaly) { + reason = value < lowerBound ? 'Below lower IQR bound' : 'Above upper IQR bound'; + } + + return { index, value, zscore, isAnomaly, reason }; + }) + .filter(r => r.isAnomaly); +}; + +const assessDataQuality = (stats: StatisticalSummary, anomalyCount: number): { score: number; issues: string[] } => { + let score = 100; + const issues: string[] = []; + + if (stats.nullPercentage > 20) { + score -= 30; + issues.push(`High missing value rate (${stats.nullPercentage.toFixed(1)}%)`); + } else if (stats.nullPercentage > 5) { + score -= 15; + issues.push(`Moderate missing values (${stats.nullPercentage.toFixed(1)}%)`); + } + + if (stats.count > 0 && stats.uniqueCount / stats.count < 0.01) { + score -= 10; + issues.push('Very low cardinality'); + } + + if (anomalyCount > stats.count * 0.1) { + score -= 20; + issues.push(`High anomaly rate (${((anomalyCount / stats.count) * 100).toFixed(1)}%)`); + } else if (anomalyCount > 0) { + score -= 5; + issues.push(`${anomalyCount} anomalies detected`); + } + + if (stats.skewness !== undefined && Math.abs(stats.skewness) > 2) { + score -= 10; + issues.push(`Highly skewed distribution (${stats.skewness.toFixed(2)})`); + } + + return { score: Math.max(0, score), issues }; +}; + +export const analyzeColumn = (name: string, values: any[]): ColumnAnalysis => { + const type = detectColumnType(values); + const stats = calculateStatistics(values, type); + const anomalies = detectAnomalies(values, type); + const quality = assessDataQuality(stats, anomalies.length); + + let trend: TrendAnalysis | undefined; + if (type === 'number') { + const numbers = values.map(Number).filter(n => !isNaN(n)); + trend = analyzeTrend(numbers); + } + + return { column: name, type, stats, trend, anomalies, quality }; +}; + +export const analyzeDataset = (data: Record[], columns?: string[]): ColumnAnalysis[] => { + if (!data || data.length === 0) return []; + + const colNames = columns || Object.keys(data[0]); + return colNames.map(col => { + const values = data.map(row => row[col]); + return analyzeColumn(col, values); + }); +}; + +interface StatCardProps { + title: string; + value: number | string; + precision?: number; + prefix?: React.ReactNode; + suffix?: string; + trend?: 'up' | 'down' | 'stable'; + trendValue?: number; + color?: string; +} + +const StatCard: React.FC = ({ + title, + value, + precision = 2, + prefix, + suffix, + trend, + trendValue, + color, +}) => ( + + {title}} + value={typeof value === 'number' ? value : value} + precision={typeof value === 'number' ? precision : undefined} + prefix={prefix} + suffix={suffix} + valueStyle={{ + fontSize: '1.25rem', + fontWeight: 600, + color: color || 'inherit', + }} + /> + {trend && trendValue !== undefined && ( +
+ {trend === 'up' ? : trend === 'down' ? : null} + {Math.abs(trendValue).toFixed(1)}% +
+ )} +
+); + +interface DataAnalysisPanelProps { + analysis: ColumnAnalysis; + showDetails?: boolean; +} + +export const DataAnalysisPanel: React.FC = ({ analysis, showDetails = true }) => { + const { stats, trend, anomalies, quality } = analysis; + + const typeColors: Record = { + number: 'blue', + string: 'green', + date: 'purple', + boolean: 'orange', + unknown: 'default', + }; + + return ( +
+
+
+ {analysis.column} + {analysis.type} +
+
+ 0 ? quality.issues.join(', ') : 'Good quality'}> + = 80 ? '#52c41a' : quality.score >= 50 ? '#faad14' : '#ff4d4f'} + format={percent => {percent}} + /> + +
+
+ + + + + + + + + + 10 ? '#ff4d4f' : undefined} + /> + + + 0 ? '#faad14' : undefined} + /> + + + + {analysis.type === 'number' && stats.mean !== undefined && ( + <> +
+ Statistical Summary +
+ + + + + + + + + + + + + + + + {showDetails && ( + + + + + + + + + + + + + + + )} + + {trend && ( +
+
+ Trend Analysis + {trend.direction === 'up' && ( + }> + Upward + + )} + {trend.direction === 'down' && ( + }> + Downward + + )} + {trend.direction === 'stable' && Stable} +
+
+
+ Change: + 0 + ? 'text-green-500' + : trend.changePercent < 0 + ? 'text-red-500' + : 'text-gray-500' + }`} + > + {trend.changePercent > 0 ? '+' : ''} + {trend.changePercent.toFixed(1)}% + +
+
+ Slope: + {trend.slope.toFixed(4)} +
+
+ Correlation: + {trend.correlation.toFixed(3)} +
+
+
+ )} + + )} + + {anomalies.length > 0 && showDetails && ( +
+
+ + + Anomalies Detected ({anomalies.length}) + +
+
+ {anomalies.slice(0, 5).map((anomaly, i) => ( +
+ + Row {anomaly.index + 1}: {anomaly.value} + + {anomaly.reason} +
+ ))} + {anomalies.length > 5 && ( +
+{anomalies.length - 5} more anomalies
+ )} +
+
+ )} + + {quality.issues.length > 0 && showDetails && ( +
+
+ + Data Quality Issues +
+
+ {quality.issues.map((issue, i) => ( + + {issue} + + ))} +
+
+ )} +
+ ); +}; + +interface DatasetAnalysisSummaryProps { + analyses: ColumnAnalysis[]; + title?: string; +} + +export const DatasetAnalysisSummary: React.FC = ({ + analyses, + title = 'Dataset Analysis Summary', +}) => { + const summary = useMemo(() => { + const totalColumns = analyses.length; + const numericColumns = analyses.filter(a => a.type === 'number').length; + const totalAnomalies = analyses.reduce((sum, a) => sum + a.anomalies.length, 0); + const avgQuality = analyses.reduce((sum, a) => sum + a.quality.score, 0) / totalColumns; + const columnsWithIssues = analyses.filter(a => a.quality.issues.length > 0).length; + + const trendingUp = analyses.filter(a => a.trend?.direction === 'up').length; + const trendingDown = analyses.filter(a => a.trend?.direction === 'down').length; + + return { + totalColumns, + numericColumns, + totalAnomalies, + avgQuality, + columnsWithIssues, + trendingUp, + trendingDown, + }; + }, [analyses]); + + return ( +
+
+

{title}

+
+ {summary.avgQuality >= 80 ? ( + }> + Good Quality + + ) : summary.avgQuality >= 50 ? ( + }> + Moderate Quality + + ) : ( + }> + Poor Quality + + )} +
+
+ + + + + + + + + + = 80 ? '#52c41a' : summary.avgQuality >= 50 ? '#faad14' : '#ff4d4f'} + /> + + + 0 ? '#faad14' : '#52c41a'} + /> + + + + {summary.numericColumns > 0 && ( +
+
+ + {summary.trendingUp} trending up +
+
+ + {summary.trendingDown} trending down +
+ {summary.columnsWithIssues > 0 && ( +
+ + {summary.columnsWithIssues} with issues +
+ )} +
+ )} +
+ ); +}; + +export default { + analyzeColumn, + analyzeDataset, + DataAnalysisPanel, + DatasetAnalysisSummary, +}; diff --git a/web/new-components/analysis/DataPreprocessor.tsx b/web/new-components/analysis/DataPreprocessor.tsx new file mode 100644 index 000000000..c5990c0b6 --- /dev/null +++ b/web/new-components/analysis/DataPreprocessor.tsx @@ -0,0 +1,1023 @@ +/** + * DataPreprocessor.tsx + * Advanced data preprocessing component with auto type detection, missing value handling, + * outlier processing, and data normalization/scaling. + */ + +import { + AlertOutlined, + CheckCircleOutlined, + EditOutlined, + EyeOutlined, + FilterOutlined, + ReloadOutlined, + SettingOutlined, + ThunderboltOutlined, + WarningOutlined, +} from '@ant-design/icons'; +import { + Alert, + Badge, + Button, + Card, + Checkbox, + Divider, + Modal, + Progress, + Radio, + Select, + Statistic, + Switch, + Table, + Tabs, + Tag, +} from 'antd'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; + +export type ColumnType = 'number' | 'string' | 'date' | 'boolean' | 'category' | 'mixed' | 'unknown'; + +export type MissingValueStrategy = + | 'drop' + | 'fill_mean' + | 'fill_median' + | 'fill_mode' + | 'fill_zero' + | 'fill_custom' + | 'interpolate' + | 'keep'; + +export type OutlierStrategy = 'keep' | 'remove' | 'cap' | 'flag'; + +export type NormalizationMethod = 'none' | 'minmax' | 'zscore' | 'log' | 'robust'; + +export interface ColumnConfig { + name: string; + detectedType: ColumnType; + selectedType: ColumnType; + missingCount: number; + missingPercent: number; + missingStrategy: MissingValueStrategy; + customFillValue?: any; + outlierCount: number; + outlierStrategy: OutlierStrategy; + outlierThreshold: number; + normalization: NormalizationMethod; + include: boolean; + uniqueValues: number; + sampleValues: any[]; +} + +export interface PreprocessingConfig { + columns: ColumnConfig[]; + globalMissingStrategy: MissingValueStrategy; + globalOutlierStrategy: OutlierStrategy; + dropDuplicates: boolean; + trimWhitespace: boolean; + lowercaseStrings: boolean; + removeEmptyRows: boolean; +} + +export interface PreprocessingResult { + originalRowCount: number; + processedRowCount: number; + columnsProcessed: number; + missingValuesFilled: number; + outliersHandled: number; + duplicatesRemoved: number; + data: any[]; + warnings: string[]; + errors: string[]; +} + +const detectColumnType = (values: any[]): ColumnType => { + const nonNullValues = values.filter(v => v != null && v !== ''); + if (nonNullValues.length === 0) return 'unknown'; + + let numberCount = 0; + let dateCount = 0; + let boolCount = 0; + let stringCount = 0; + + for (const val of nonNullValues) { + if (typeof val === 'boolean' || val === 'true' || val === 'false' || val === '0' || val === '1') { + boolCount++; + } else if (!isNaN(Number(val)) && val !== '') { + numberCount++; + } else if (!isNaN(Date.parse(String(val))) && /\d{4}|\d{2}[-/]\d{2}/.test(String(val))) { + dateCount++; + } else { + stringCount++; + } + } + + const total = nonNullValues.length; + const threshold = 0.8; + + if (numberCount / total >= threshold) return 'number'; + if (dateCount / total >= threshold) return 'date'; + if (boolCount / total >= threshold) return 'boolean'; + if (stringCount / total >= threshold) { + const uniqueRatio = new Set(nonNullValues).size / total; + if (uniqueRatio < 0.3 && total > 10) return 'category'; + return 'string'; + } + + return 'mixed'; +}; + +const calculateMissing = (values: any[]): { count: number; percent: number } => { + const missing = values.filter(v => v == null || v === '' || (typeof v === 'number' && isNaN(v))).length; + return { + count: missing, + percent: values.length > 0 ? (missing / values.length) * 100 : 0, + }; +}; + +const detectOutliers = (values: number[], threshold: number = 3): number[] => { + const numericValues = values.filter(v => typeof v === 'number' && !isNaN(v)); + if (numericValues.length < 3) return []; + + const mean = numericValues.reduce((a, b) => a + b, 0) / numericValues.length; + const variance = numericValues.reduce((sum, v) => sum + Math.pow(v - mean, 2), 0) / numericValues.length; + const stdDev = Math.sqrt(variance); + + if (stdDev === 0) return []; + + const outlierIndices: number[] = []; + values.forEach((v, i) => { + if (typeof v === 'number' && !isNaN(v)) { + const zScore = Math.abs((v - mean) / stdDev); + if (zScore > threshold) { + outlierIndices.push(i); + } + } + }); + + return outlierIndices; +}; + +const getSampleValues = (values: any[], count: number = 5): any[] => { + const unique = [...new Set(values.filter(v => v != null && v !== ''))]; + return unique.slice(0, count); +}; + +export const analyzeColumns = (data: any[], columns: string[]): ColumnConfig[] => { + return columns.map(colName => { + const values = data.map(row => row[colName]); + const detectedType = detectColumnType(values); + const { count: missingCount, percent: missingPercent } = calculateMissing(values); + + let outlierCount = 0; + if (detectedType === 'number') { + const numericValues = values.map(v => (v != null && v !== '' ? Number(v) : NaN)); + outlierCount = detectOutliers(numericValues).length; + } + + return { + name: colName, + detectedType, + selectedType: detectedType, + missingCount, + missingPercent, + missingStrategy: missingPercent > 50 ? 'drop' : missingPercent > 0 ? 'fill_mean' : 'keep', + outlierCount, + outlierStrategy: 'keep', + outlierThreshold: 3, + normalization: 'none', + include: true, + uniqueValues: new Set(values.filter(v => v != null)).size, + sampleValues: getSampleValues(values), + }; + }); +}; + +const fillMissingValues = (values: any[], strategy: MissingValueStrategy, customValue?: any): any[] => { + if (strategy === 'keep') return values; + + const nonNull = values.filter(v => v != null && v !== '' && !(typeof v === 'number' && isNaN(v))); + + let fillValue: any = null; + switch (strategy) { + case 'fill_mean': + const nums = nonNull.filter(v => !isNaN(Number(v))).map(Number); + fillValue = nums.length > 0 ? nums.reduce((a, b) => a + b, 0) / nums.length : 0; + break; + case 'fill_median': + const sorted = nonNull + .filter(v => !isNaN(Number(v))) + .map(Number) + .sort((a, b) => a - b); + fillValue = sorted.length > 0 ? sorted[Math.floor(sorted.length / 2)] : 0; + break; + case 'fill_mode': + const frequency: Record = {}; + nonNull.forEach(v => { + frequency[String(v)] = (frequency[String(v)] || 0) + 1; + }); + const maxFreq = Math.max(...Object.values(frequency)); + fillValue = Object.keys(frequency).find(k => frequency[k] === maxFreq) || ''; + break; + case 'fill_zero': + fillValue = 0; + break; + case 'fill_custom': + fillValue = customValue; + break; + case 'interpolate': + return values.map((v, i) => { + if (v == null || v === '' || (typeof v === 'number' && isNaN(v))) { + let prev = null, + next = null; + for (let j = i - 1; j >= 0; j--) { + if (values[j] != null && !isNaN(Number(values[j]))) { + prev = Number(values[j]); + break; + } + } + for (let j = i + 1; j < values.length; j++) { + if (values[j] != null && !isNaN(Number(values[j]))) { + next = Number(values[j]); + break; + } + } + if (prev !== null && next !== null) return (prev + next) / 2; + return prev ?? next ?? 0; + } + return v; + }); + case 'drop': + return values; + } + + return values.map(v => (v == null || v === '' || (typeof v === 'number' && isNaN(v)) ? fillValue : v)); +}; + +const handleOutliers = ( + values: number[], + strategy: OutlierStrategy, + threshold: number = 3, +): { values: number[]; handled: number } => { + if (strategy === 'keep') return { values, handled: 0 }; + + const numericValues = values.filter(v => typeof v === 'number' && !isNaN(v)); + if (numericValues.length < 3) return { values, handled: 0 }; + + const mean = numericValues.reduce((a, b) => a + b, 0) / numericValues.length; + const variance = numericValues.reduce((sum, v) => sum + Math.pow(v - mean, 2), 0) / numericValues.length; + const stdDev = Math.sqrt(variance); + + if (stdDev === 0) return { values, handled: 0 }; + + const lowerBound = mean - threshold * stdDev; + const upperBound = mean + threshold * stdDev; + + let handled = 0; + const result = values.map(v => { + if (typeof v !== 'number' || isNaN(v)) return v; + + if (v < lowerBound || v > upperBound) { + handled++; + switch (strategy) { + case 'cap': + return v < lowerBound ? lowerBound : upperBound; + case 'remove': + return NaN; + case 'flag': + return v; + default: + return v; + } + } + return v; + }); + + return { values: result, handled }; +}; + +const normalizeValues = (values: number[], method: NormalizationMethod): number[] => { + if (method === 'none') return values; + + const numericValues = values.filter(v => typeof v === 'number' && !isNaN(v)); + if (numericValues.length === 0) return values; + + switch (method) { + case 'minmax': { + const min = Math.min(...numericValues); + const max = Math.max(...numericValues); + const range = max - min; + if (range === 0) return values.map(() => 0); + return values.map(v => (typeof v === 'number' && !isNaN(v) ? (v - min) / range : v)); + } + case 'zscore': { + const mean = numericValues.reduce((a, b) => a + b, 0) / numericValues.length; + const variance = numericValues.reduce((sum, v) => sum + Math.pow(v - mean, 2), 0) / numericValues.length; + const stdDev = Math.sqrt(variance); + if (stdDev === 0) return values.map(() => 0); + return values.map(v => (typeof v === 'number' && !isNaN(v) ? (v - mean) / stdDev : v)); + } + case 'log': { + return values.map(v => (typeof v === 'number' && !isNaN(v) && v > 0 ? Math.log(v) : v)); + } + case 'robust': { + const sorted = [...numericValues].sort((a, b) => a - b); + const q1 = sorted[Math.floor(sorted.length * 0.25)]; + const q3 = sorted[Math.floor(sorted.length * 0.75)]; + const median = sorted[Math.floor(sorted.length * 0.5)]; + const iqr = q3 - q1; + if (iqr === 0) return values.map(() => 0); + return values.map(v => (typeof v === 'number' && !isNaN(v) ? (v - median) / iqr : v)); + } + default: + return values; + } +}; + +export const preprocessData = (data: any[], config: PreprocessingConfig): PreprocessingResult => { + const warnings: string[] = []; + const errors: string[] = []; + let processedData = [...data.map(row => ({ ...row }))]; + + const originalRowCount = processedData.length; + let missingValuesFilled = 0; + let outliersHandled = 0; + let duplicatesRemoved = 0; + + if (config.trimWhitespace) { + processedData = processedData.map(row => { + const newRow = { ...row }; + Object.keys(newRow).forEach(key => { + if (typeof newRow[key] === 'string') { + newRow[key] = newRow[key].trim(); + } + }); + return newRow; + }); + } + + if (config.lowercaseStrings) { + config.columns + .filter(c => c.selectedType === 'string' && c.include) + .forEach(colConfig => { + processedData.forEach(row => { + if (typeof row[colConfig.name] === 'string') { + row[colConfig.name] = row[colConfig.name].toLowerCase(); + } + }); + }); + } + + const includedColumns = config.columns.filter(c => c.include); + const dropColumns = config.columns.filter(c => !c.include).map(c => c.name); + + processedData = processedData.map(row => { + const newRow = { ...row }; + dropColumns.forEach(col => delete newRow[col]); + return newRow; + }); + + for (const colConfig of includedColumns) { + const values = processedData.map(row => row[colConfig.name]); + + if (colConfig.missingStrategy !== 'keep') { + const filled = fillMissingValues(values, colConfig.missingStrategy, colConfig.customFillValue); + const filledCount = values.filter( + (v, i) => (v == null || v === '') && filled[i] != null && filled[i] !== '', + ).length; + missingValuesFilled += filledCount; + + if (colConfig.missingStrategy === 'drop') { + const indicesToRemove = new Set(); + values.forEach((v, i) => { + if (v == null || v === '' || (typeof v === 'number' && isNaN(v))) { + indicesToRemove.add(i); + } + }); + processedData = processedData.filter((_, i) => !indicesToRemove.has(i)); + } else { + filled.forEach((v, i) => { + if (processedData[i]) { + processedData[i][colConfig.name] = v; + } + }); + } + } + + if (colConfig.selectedType === 'number' && colConfig.outlierStrategy !== 'keep') { + const currentValues = processedData.map(row => Number(row[colConfig.name])); + const { values: handledValues, handled } = handleOutliers( + currentValues, + colConfig.outlierStrategy, + colConfig.outlierThreshold, + ); + outliersHandled += handled; + + if (colConfig.outlierStrategy === 'remove') { + processedData = processedData.filter((_, i) => !isNaN(handledValues[i])); + } else { + handledValues.forEach((v, i) => { + if (processedData[i]) { + processedData[i][colConfig.name] = v; + } + }); + } + } + + if (colConfig.selectedType === 'number' && colConfig.normalization !== 'none') { + const currentValues = processedData.map(row => Number(row[colConfig.name])); + const normalized = normalizeValues(currentValues, colConfig.normalization); + normalized.forEach((v, i) => { + if (processedData[i]) { + processedData[i][colConfig.name] = v; + } + }); + } + } + + if (config.dropDuplicates) { + const seen = new Set(); + const uniqueData: any[] = []; + processedData.forEach(row => { + const key = JSON.stringify(row); + if (!seen.has(key)) { + seen.add(key); + uniqueData.push(row); + } + }); + duplicatesRemoved = processedData.length - uniqueData.length; + processedData = uniqueData; + } + + if (config.removeEmptyRows) { + const beforeCount = processedData.length; + processedData = processedData.filter(row => Object.values(row).some(v => v != null && v !== '')); + if (beforeCount > processedData.length) { + warnings.push(`Removed ${beforeCount - processedData.length} empty rows`); + } + } + + return { + originalRowCount, + processedRowCount: processedData.length, + columnsProcessed: includedColumns.length, + missingValuesFilled, + outliersHandled, + duplicatesRemoved, + data: processedData, + warnings, + errors, + }; +}; + +interface DataPreprocessorProps { + data: any[]; + columns: string[]; + onPreprocess: (result: PreprocessingResult) => void; + onConfigChange?: (config: PreprocessingConfig) => void; + initialConfig?: Partial; +} + +const DataPreprocessor: React.FC = ({ + data, + columns, + onPreprocess, + onConfigChange, + initialConfig, +}) => { + const [config, setConfig] = useState(() => { + const columnConfigs = analyzeColumns(data, columns); + return { + columns: columnConfigs, + globalMissingStrategy: 'fill_mean', + globalOutlierStrategy: 'keep', + dropDuplicates: false, + trimWhitespace: true, + lowercaseStrings: false, + removeEmptyRows: true, + ...initialConfig, + }; + }); + + const [previewResult, setPreviewResult] = useState(null); + const [showPreview, setShowPreview] = useState(false); + const [activeTab, setActiveTab] = useState('columns'); + + useEffect(() => { + onConfigChange?.(config); + }, [config, onConfigChange]); + + const updateColumnConfig = useCallback((columnName: string, updates: Partial) => { + setConfig(prev => ({ + ...prev, + columns: prev.columns.map(col => (col.name === columnName ? { ...col, ...updates } : col)), + })); + }, []); + + const applyGlobalStrategy = useCallback((type: 'missing' | 'outlier') => { + setConfig(prev => ({ + ...prev, + columns: prev.columns.map(col => ({ + ...col, + ...(type === 'missing' + ? { missingStrategy: prev.globalMissingStrategy } + : { outlierStrategy: prev.globalOutlierStrategy }), + })), + })); + }, []); + + const handlePreview = useCallback(() => { + const result = preprocessData(data, config); + setPreviewResult(result); + setShowPreview(true); + }, [data, config]); + + const handleApply = useCallback(() => { + const result = preprocessData(data, config); + onPreprocess(result); + }, [data, config, onPreprocess]); + + const dataQualityScore = useMemo(() => { + const totalMissing = config.columns.reduce((sum, c) => sum + c.missingPercent, 0) / config.columns.length; + const totalOutliers = config.columns + .filter(c => c.selectedType === 'number') + .reduce((sum, c) => sum + c.outlierCount, 0); + const outlierPercent = data.length > 0 ? (totalOutliers / data.length) * 100 : 0; + + const missingScore = Math.max(0, 100 - totalMissing * 2); + const outlierScore = Math.max(0, 100 - outlierPercent * 5); + const typeScore = + (config.columns.filter(c => c.detectedType !== 'mixed' && c.detectedType !== 'unknown').length / + config.columns.length) * + 100; + + return Math.round(missingScore * 0.4 + outlierScore * 0.3 + typeScore * 0.3); + }, [config.columns, data.length]); + + const getTypeIcon = (type: ColumnType) => { + switch (type) { + case 'number': + return '#'; + case 'string': + return 'Aa'; + case 'date': + return '📅'; + case 'boolean': + return '✓'; + case 'category': + return '📋'; + default: + return '?'; + } + }; + + const getTypeColor = (type: ColumnType) => { + switch (type) { + case 'number': + return 'blue'; + case 'string': + return 'green'; + case 'date': + return 'purple'; + case 'boolean': + return 'orange'; + case 'category': + return 'cyan'; + case 'mixed': + return 'red'; + default: + return 'default'; + } + }; + + const columnTableColumns = [ + { + title: 'Column', + dataIndex: 'name', + key: 'name', + render: (name: string, record: ColumnConfig) => ( +
+ updateColumnConfig(name, { include: e.target.checked })} /> + {name} +
+ ), + }, + { + title: 'Type', + dataIndex: 'detectedType', + key: 'type', + render: (type: ColumnType, record: ColumnConfig) => ( + updateColumnConfig(record.name, { missingStrategy: val })} + className='w-32' + disabled={record.missingCount === 0} + options={[ + { value: 'keep', label: 'Keep as is' }, + { value: 'drop', label: 'Drop rows' }, + { value: 'fill_mean', label: 'Fill mean' }, + { value: 'fill_median', label: 'Fill median' }, + { value: 'fill_mode', label: 'Fill mode' }, + { value: 'fill_zero', label: 'Fill zero' }, + { value: 'interpolate', label: 'Interpolate' }, + ]} + /> + ), + }, + { + title: 'Outliers', + key: 'outliers', + render: (_: any, record: ColumnConfig) => + record.selectedType === 'number' ? ( + record.outlierCount > 0 ? ( + }> + {record.outlierCount} + + ) : ( + None + ) + ) : ( + N/A + ), + }, + { + title: 'Normalize', + key: 'normalization', + render: (_: any, record: ColumnConfig) => + record.selectedType === 'number' ? ( + setConfig(prev => ({ ...prev, globalMissingStrategy: val }))} + className='w-32' + options={[ + { value: 'keep', label: 'Keep missing' }, + { value: 'fill_mean', label: 'Fill mean' }, + { value: 'fill_median', label: 'Fill median' }, + { value: 'drop', label: 'Drop rows' }, + ]} + /> + + +
+ c.include).length} overflowCount={99}> + Selected Columns + +
+ + + + + ), + }, + { + key: 'options', + label: ( + + + Global Options + + ), + children: ( +
+ +
+
+ Trim whitespace + setConfig(prev => ({ ...prev, trimWhitespace: val }))} + /> +
+
+ Lowercase strings + setConfig(prev => ({ ...prev, lowercaseStrings: val }))} + /> +
+
+
+ + +
+
+ Remove duplicates + setConfig(prev => ({ ...prev, dropDuplicates: val }))} + /> +
+
+ Remove empty rows + setConfig(prev => ({ ...prev, removeEmptyRows: val }))} + /> +
+
+
+ + +
+
+ Global strategy: + setConfig(prev => ({ ...prev, globalOutlierStrategy: e.target.value }))} + size='small' + > + Keep + Cap + Remove + Flag + + +
+
+
+
+ ), + }, + { + key: 'summary', + label: ( + + + Summary + + ), + children: ( +
+ + + + + + + + sum + c.missingCount, 0)} + valueStyle={{ color: '#F59E0B' }} + prefix={} + /> + + + c.selectedType === 'number') + .reduce((sum, c) => sum + c.outlierCount, 0)} + valueStyle={{ color: '#EF4444' }} + prefix={} + /> + + +
+

+ Column Type Distribution +

+
+ {['number', 'string', 'date', 'boolean', 'category', 'mixed', 'unknown'].map(type => { + const count = config.columns.filter(c => c.detectedType === type).length; + if (count === 0) return null; + return ( + + {getTypeIcon(type as ColumnType)} {type}: {count} + + ); + })} +
+
+
+ ), + }, + ]} + /> + + + +
+
+ +
+
+ + +
+
+ + setShowPreview(false)} + width={800} + footer={[ + , + , + ]} + > + {previewResult && ( +
+
+ + + + + + + + + +
+ + {previewResult.warnings.length > 0 && ( + + {previewResult.warnings.map((w, i) => ( +
  • {w}
  • + ))} + + } + showIcon + /> + )} + +
    +
    ({ + title: key, + dataIndex: key, + key, + ellipsis: true, + width: 120, + }))} + dataSource={previewResult.data.slice(0, 10)} + rowKey={(_, i) => String(i)} + size='small' + pagination={false} + scroll={{ x: true }} + /> + {previewResult.data.length > 10 && ( +
    + Showing first 10 of {previewResult.data.length} rows +
    + )} + + + )} + + + ); +}; + +export default DataPreprocessor; diff --git a/web/new-components/analysis/index.ts b/web/new-components/analysis/index.ts new file mode 100644 index 000000000..4d1f77c28 --- /dev/null +++ b/web/new-components/analysis/index.ts @@ -0,0 +1,15 @@ +export { DataAnalysisPanel, DatasetAnalysisSummary, analyzeColumn, analyzeDataset, default } from './DataAnalyzer'; + +export type { AnomalyResult, ColumnAnalysis, DataColumn, StatisticalSummary, TrendAnalysis } from './DataAnalyzer'; + +export { default as DataPreprocessor, analyzeColumns, preprocessData } from './DataPreprocessor'; + +export type { + ColumnConfig, + ColumnType, + MissingValueStrategy, + NormalizationMethod, + OutlierStrategy, + PreprocessingConfig, + PreprocessingResult, +} from './DataPreprocessor'; diff --git a/web/new-components/charts/AdvancedCharts.tsx b/web/new-components/charts/AdvancedCharts.tsx new file mode 100644 index 000000000..98f0969c3 --- /dev/null +++ b/web/new-components/charts/AdvancedCharts.tsx @@ -0,0 +1,830 @@ +/** + * AdvancedCharts.tsx + * A unified chart component that supports multiple chart types with a premium, clean design. + * Uses @ant-design/plots (AntV) for rendering. + * Enhanced with advanced interactions: zoom, pan, brush selection, and data point click handlers. + */ + +import { + FullscreenExitOutlined, + FullscreenOutlined, + ReloadOutlined, + ZoomInOutlined, + ZoomOutOutlined, +} from '@ant-design/icons'; +import { Area, Bar, Column, DualAxes, Line, Pie, Scatter } from '@ant-design/plots'; +import { Button, Tooltip } from 'antd'; +import React, { useCallback, useMemo, useRef, useState } from 'react'; + +// Chart type definitions +export type ChartType = 'line' | 'column' | 'bar' | 'pie' | 'area' | 'scatter' | 'donut' | 'dual-axes'; + +export interface ChartConfig { + chartType: ChartType; + data: any[]; + // Common fields + xField?: string; + yField?: string; + seriesField?: string; + colorField?: string; + // Pie chart specific + angleField?: string; + // Dual axes specific + yFields?: [string, string]; + geometries?: any[]; + // Appearance + title?: string; + description?: string; + smooth?: boolean; + autoFit?: boolean; + height?: number; + colors?: string[]; + showLegend?: boolean; + showGrid?: boolean; + animate?: boolean; + // Interaction options + enableZoom?: boolean; + enableBrush?: boolean; + enableTooltipCrosshairs?: boolean; + onDataPointClick?: (data: any, event: any) => void; + onBrushSelection?: (selectedData: any[]) => void; + // Toolbar options + showToolbar?: boolean; + enableFullscreen?: boolean; +} + +// Premium color palette - clean and professional +const PREMIUM_COLORS = [ + '#3B82F6', // Blue + '#10B981', // Emerald + '#F59E0B', // Amber + '#EF4444', // Red + '#8B5CF6', // Violet + '#EC4899', // Pink + '#06B6D4', // Cyan + '#84CC16', // Lime + '#F97316', // Orange + '#6366F1', // Indigo +]; + +// Gradient colors for area charts +const GRADIENT_COLORS = { + blue: 'l(270) 0:#ffffff 0.5:#3B82F6 1:#1E40AF', + green: 'l(270) 0:#ffffff 0.5:#10B981 1:#065F46', + amber: 'l(270) 0:#ffffff 0.5:#F59E0B 1:#B45309', + purple: 'l(270) 0:#ffffff 0.5:#8B5CF6 1:#5B21B6', +}; + +// Common theme configuration for all charts +const getCommonConfig = (config: ChartConfig) => ({ + autoFit: config.autoFit ?? true, + animation: + config.animate !== false + ? { + appear: { + animation: 'fade-in', + duration: 500, + }, + } + : false, + theme: { + colors10: config.colors || PREMIUM_COLORS, + colors20: config.colors || PREMIUM_COLORS, + }, +}); + +// Common axis configuration +const getAxisConfig = (showGrid: boolean = true) => ({ + xAxis: { + line: { + style: { + stroke: '#e5e7eb', + lineWidth: 1, + }, + }, + tickLine: { + style: { + stroke: '#e5e7eb', + }, + }, + label: { + style: { + fill: '#6b7280', + fontSize: 11, + }, + }, + grid: showGrid + ? { + line: { + style: { + stroke: '#f3f4f6', + lineWidth: 1, + lineDash: [4, 4], + }, + }, + } + : null, + }, + yAxis: { + line: { + style: { + stroke: '#e5e7eb', + lineWidth: 1, + }, + }, + tickLine: { + style: { + stroke: '#e5e7eb', + }, + }, + label: { + style: { + fill: '#6b7280', + fontSize: 11, + }, + }, + grid: showGrid + ? { + line: { + style: { + stroke: '#f3f4f6', + lineWidth: 1, + lineDash: [4, 4], + }, + }, + } + : null, + }, +}); + +// Legend configuration +const getLegendConfig = (showLegend: boolean = true) => ({ + legend: showLegend + ? { + position: 'top-right' as const, + itemName: { + style: { + fill: '#374151', + fontSize: 12, + }, + }, + marker: { + symbol: 'circle', + }, + } + : false, +}); + +// Enhanced tooltip configuration with crosshairs +const getTooltipConfig = (config: ChartConfig) => ({ + tooltip: { + showTitle: true, + showMarkers: true, + showCrosshairs: config.enableTooltipCrosshairs ?? true, + crosshairs: { + type: 'xy' as const, + line: { + style: { + stroke: '#9CA3AF', + lineWidth: 1, + lineDash: [4, 4], + }, + }, + }, + domStyles: { + 'g2-tooltip': { + backgroundColor: '#ffffff', + boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)', + borderRadius: '8px', + padding: '12px 16px', + border: '1px solid #e5e7eb', + }, + 'g2-tooltip-title': { + color: '#111827', + fontWeight: '600', + fontSize: '13px', + marginBottom: '8px', + }, + 'g2-tooltip-list-item': { + color: '#4b5563', + fontSize: '12px', + }, + }, + customContent: (title: string, items: any[]) => { + if (!items?.length) return ''; + const xField = config.xField || 'x'; + const yField = config.yField || 'y'; + + return ` +
    +
    + ${title} +
    + ${items + .map( + item => ` +
    +
    + + ${item.name || yField} +
    + ${typeof item.value === 'number' ? item.value.toLocaleString() : item.value} +
    + `, + ) + .join('')} +
    + Click for details • Scroll to zoom +
    +
    + `; + }, + }, +}); + +// Get interaction configuration +const getInteractionConfig = (config: ChartConfig) => { + const interactions: any[] = [{ type: 'element-active' }, { type: 'element-highlight' }]; + + if (config.enableZoom !== false) { + interactions.push( + { type: 'view-zoom' }, + { + type: 'element-single-selected', + cfg: { + start: [{ trigger: 'element:click', action: 'element-single-selected:toggle' }], + }, + }, + ); + } + + if (config.enableBrush) { + interactions.push({ + type: 'brush-x', + cfg: { + showEnable: [ + { trigger: 'plot:mouseenter', action: 'cursor:crosshair' }, + { trigger: 'plot:mouseleave', action: 'cursor:default' }, + ], + }, + }); + } + + return { interactions }; +}; + +// Get click handler config +const getClickHandlerConfig = (config: ChartConfig, chartRef: React.MutableRefObject) => { + if (!config.onDataPointClick) return {}; + + return { + onReady: (plot: any) => { + chartRef.current = plot; + plot.on('element:click', (evt: any) => { + const { data } = evt; + config.onDataPointClick?.(data?.data, evt); + }); + }, + }; +}; + +// Chart Toolbar Component +interface ChartToolbarProps { + onZoomIn: () => void; + onZoomOut: () => void; + onReset: () => void; + onToggleFullscreen: () => void; + isFullscreen: boolean; + showZoom?: boolean; + showFullscreen?: boolean; +} + +const ChartToolbar: React.FC = ({ + onZoomIn, + onZoomOut, + onReset, + onToggleFullscreen, + isFullscreen, + showZoom = true, + showFullscreen = true, +}) => ( +
    + {showZoom && ( + <> + +
    +); + +// Line Chart Component +const LineChart: React.FC<{ config: ChartConfig; chartRef: React.MutableRefObject }> = ({ config, chartRef }) => { + const chartConfig = useMemo( + () => ({ + data: config.data, + xField: config.xField || 'x', + yField: config.yField || 'y', + seriesField: config.seriesField, + smooth: config.smooth ?? true, + ...getCommonConfig(config), + ...getAxisConfig(config.showGrid), + ...getLegendConfig(config.showLegend), + ...getTooltipConfig(config), + ...getInteractionConfig(config), + ...getClickHandlerConfig(config, chartRef), + point: { + size: 3, + shape: 'circle', + style: { + fill: '#ffffff', + stroke: config.colors?.[0] || PREMIUM_COLORS[0], + lineWidth: 2, + cursor: 'pointer', + }, + }, + lineStyle: { + lineWidth: 2.5, + }, + color: config.colors || PREMIUM_COLORS, + slider: config.enableZoom !== false ? { start: 0, end: 1 } : undefined, + }), + [config, chartRef], + ); + + return ; +}; + +// Column Chart Component (Vertical Bar) +const ColumnChart: React.FC<{ config: ChartConfig; chartRef: React.MutableRefObject }> = ({ + config, + chartRef, +}) => { + const chartConfig = useMemo( + () => ({ + data: config.data, + xField: config.xField || 'x', + yField: config.yField || 'y', + seriesField: config.seriesField, + ...getCommonConfig(config), + ...getAxisConfig(config.showGrid), + ...getLegendConfig(config.showLegend), + ...getTooltipConfig(config), + ...getInteractionConfig(config), + ...getClickHandlerConfig(config, chartRef), + columnWidthRatio: 0.6, + columnStyle: { + radius: [4, 4, 0, 0], + cursor: 'pointer', + }, + color: config.colors || PREMIUM_COLORS, + label: { + position: 'top' as const, + style: { + fill: '#6b7280', + fontSize: 10, + }, + }, + scrollbar: config.data.length > 12 ? { type: 'horizontal' as const } : undefined, + }), + [config, chartRef], + ); + + return ; +}; + +// Bar Chart Component (Horizontal Bar) +const BarChart: React.FC<{ config: ChartConfig; chartRef: React.MutableRefObject }> = ({ config, chartRef }) => { + const chartConfig = useMemo( + () => ({ + data: config.data, + xField: config.yField || 'y', // For horizontal bars, x is the value + yField: config.xField || 'x', // y is the category + seriesField: config.seriesField, + ...getCommonConfig(config), + ...getAxisConfig(config.showGrid), + ...getLegendConfig(config.showLegend), + ...getTooltipConfig(config), + ...getInteractionConfig(config), + ...getClickHandlerConfig(config, chartRef), + barWidthRatio: 0.6, + barStyle: { + radius: [0, 4, 4, 0], + cursor: 'pointer', + }, + color: config.colors || PREMIUM_COLORS, + label: { + position: 'right' as const, + style: { + fill: '#6b7280', + fontSize: 10, + }, + }, + scrollbar: config.data.length > 10 ? { type: 'vertical' as const } : undefined, + }), + [config, chartRef], + ); + + return ; +}; + +// Pie Chart Component +const PieChart: React.FC<{ config: ChartConfig; chartRef: React.MutableRefObject }> = ({ config, chartRef }) => { + const isDonut = config.chartType === 'donut'; + + const chartConfig = useMemo( + () => ({ + data: config.data, + angleField: config.angleField || config.yField || 'value', + colorField: config.colorField || config.xField || 'type', + ...getCommonConfig(config), + ...getLegendConfig(config.showLegend), + ...getTooltipConfig(config), + ...getClickHandlerConfig(config, chartRef), + radius: 0.9, + innerRadius: isDonut ? 0.6 : 0, + color: config.colors || PREMIUM_COLORS, + label: { + type: 'outer', + content: '{name}: {percentage}', + style: { + fill: '#6b7280', + fontSize: 11, + }, + }, + pieStyle: { + lineWidth: 2, + stroke: '#ffffff', + cursor: 'pointer', + }, + statistic: isDonut + ? { + title: { + style: { + fontSize: '14px', + color: '#6b7280', + }, + content: 'Total', + }, + content: { + style: { + fontSize: '24px', + fontWeight: '600', + color: '#111827', + }, + }, + } + : undefined, + interactions: [ + { type: 'element-active' }, + { type: 'element-selected' }, + { type: 'pie-legend-active' }, + { type: 'pie-statistic-active' }, + ], + }), + [config, isDonut, chartRef], + ); + + return ; +}; + +// Area Chart Component +const AreaChart: React.FC<{ config: ChartConfig; chartRef: React.MutableRefObject }> = ({ config, chartRef }) => { + const chartConfig = useMemo( + () => ({ + data: config.data, + xField: config.xField || 'x', + yField: config.yField || 'y', + seriesField: config.seriesField, + smooth: config.smooth ?? true, + ...getCommonConfig(config), + ...getAxisConfig(config.showGrid), + ...getLegendConfig(config.showLegend), + ...getTooltipConfig(config), + ...getInteractionConfig(config), + ...getClickHandlerConfig(config, chartRef), + areaStyle: () => ({ + fill: GRADIENT_COLORS.blue, + fillOpacity: 0.25, + }), + line: { + style: { + lineWidth: 2, + }, + }, + color: config.colors || PREMIUM_COLORS, + slider: config.enableZoom !== false ? { start: 0, end: 1 } : undefined, + }), + [config, chartRef], + ); + + return ; +}; + +// Scatter Chart Component +const ScatterChart: React.FC<{ config: ChartConfig; chartRef: React.MutableRefObject }> = ({ + config, + chartRef, +}) => { + const chartConfig = useMemo( + () => ({ + data: config.data, + xField: config.xField || 'x', + yField: config.yField || 'y', + colorField: config.colorField || config.seriesField, + ...getCommonConfig(config), + ...getAxisConfig(config.showGrid), + ...getLegendConfig(config.showLegend), + ...getTooltipConfig(config), + ...getInteractionConfig(config), + ...getClickHandlerConfig(config, chartRef), + size: 5, + shape: 'circle', + pointStyle: { + fillOpacity: 0.8, + stroke: '#ffffff', + lineWidth: 1, + cursor: 'pointer', + }, + color: config.colors || PREMIUM_COLORS, + brush: config.enableBrush + ? { + enabled: true, + type: 'rect' as const, + } + : undefined, + }), + [config, chartRef], + ); + + return ; +}; + +// Dual Axes Chart Component +const DualAxesChart: React.FC<{ config: ChartConfig; chartRef: React.MutableRefObject }> = ({ + config, + chartRef, +}) => { + const chartConfig = useMemo( + () => ({ + data: [config.data, config.data], + xField: config.xField || 'x', + yField: config.yFields || [config.yField || 'y1', 'y2'], + ...getCommonConfig(config), + ...getTooltipConfig(config), + ...getClickHandlerConfig(config, chartRef), + geometryOptions: config.geometries || [ + { + geometry: 'column', + columnWidthRatio: 0.4, + color: config.colors?.[0] || PREMIUM_COLORS[0], + }, + { + geometry: 'line', + smooth: true, + lineStyle: { + lineWidth: 2, + }, + color: config.colors?.[1] || PREMIUM_COLORS[1], + }, + ], + legend: { + position: 'top-right' as const, + }, + interactions: [{ type: 'element-active' }, { type: 'element-highlight' }], + slider: config.enableZoom !== false ? { start: 0, end: 1 } : undefined, + }), + [config, chartRef], + ); + + return ; +}; + +// Main AdvancedChart Component +export interface AdvancedChartProps { + config: ChartConfig; + className?: string; + style?: React.CSSProperties; +} + +const AdvancedChart: React.FC = ({ config, className, style }) => { + const chartRef = useRef(null); + const containerRef = useRef(null); + const [isFullscreen, setIsFullscreen] = useState(false); + const [zoomLevel, setZoomLevel] = useState(1); + + const handleZoomIn = useCallback(() => { + setZoomLevel(prev => Math.min(prev * 1.2, 3)); + // If the chart has zoom interactions, trigger them + if (chartRef.current?.chart) { + const chart = chartRef.current.chart; + try { + chart.zoom(1.2); + } catch { + // Some charts don't support direct zoom + } + } + }, []); + + const handleZoomOut = useCallback(() => { + setZoomLevel(prev => Math.max(prev / 1.2, 0.5)); + if (chartRef.current?.chart) { + const chart = chartRef.current.chart; + try { + chart.zoom(0.8); + } catch { + // Some charts don't support direct zoom + } + } + }, []); + + const handleReset = useCallback(() => { + setZoomLevel(1); + if (chartRef.current?.chart) { + const chart = chartRef.current.chart; + try { + chart.resetZoom?.(); + chart.render(); + } catch { + // Fallback: just re-render + chart.render(); + } + } + }, []); + + const handleToggleFullscreen = useCallback(() => { + if (!containerRef.current) return; + + if (!isFullscreen) { + if (containerRef.current.requestFullscreen) { + containerRef.current.requestFullscreen(); + } + } else { + if (document.exitFullscreen) { + document.exitFullscreen(); + } + } + setIsFullscreen(!isFullscreen); + }, [isFullscreen]); + + // Listen for fullscreen changes + React.useEffect(() => { + const handleFullscreenChange = () => { + setIsFullscreen(!!document.fullscreenElement); + }; + + document.addEventListener('fullscreenchange', handleFullscreenChange); + return () => document.removeEventListener('fullscreenchange', handleFullscreenChange); + }, []); + + const renderChart = () => { + switch (config.chartType) { + case 'line': + return ; + case 'column': + return ; + case 'bar': + return ; + case 'pie': + case 'donut': + return ; + case 'area': + return ; + case 'scatter': + return ; + case 'dual-axes': + return ; + default: + // Default to line chart + return ; + } + }; + + const showToolbar = config.showToolbar !== false && config.chartType !== 'pie' && config.chartType !== 'donut'; + + return ( +
    + {config.title && ( +
    +

    {config.title}

    + {config.description && ( +

    {config.description}

    + )} +
    + )} + + {showToolbar && ( + + )} + +
    + {renderChart()} +
    + + {/* Zoom indicator */} + {zoomLevel !== 1 && ( +
    + {Math.round(zoomLevel * 100)}% +
    + )} +
    + ); +}; + +// Helper function to auto-detect best chart type based on data +export const detectChartType = (data: any[], xField: string, yField: string): ChartType => { + if (!data || data.length === 0) return 'line'; + + const uniqueXValues = new Set(data.map(d => d[xField])).size; + const hasNegativeValues = data.some(d => d[yField] < 0); + const isTimeSeries = data.some(d => { + const val = d[xField]; + return val instanceof Date || !isNaN(Date.parse(val)); + }); + + // If time series data, use line or area + if (isTimeSeries) { + return 'area'; + } + + // If few categories (< 6), pie chart might be good + if (uniqueXValues <= 5 && !hasNegativeValues && data.length <= 10) { + return 'pie'; + } + + // If many categories with comparison, use column + if (uniqueXValues > 5 && uniqueXValues <= 15) { + return 'column'; + } + + // Default to line for continuous data + return 'line'; +}; + +// Helper to convert simple data to chart config +export const createChartConfig = (data: any[], options: Partial = {}): ChartConfig => { + const xField = options.xField || 'x'; + const yField = options.yField || 'y'; + const chartType = options.chartType || detectChartType(data, xField, yField); + + return { + chartType, + data, + xField, + yField, + smooth: true, + autoFit: true, + showLegend: true, + showGrid: true, + animate: true, + enableZoom: true, + enableTooltipCrosshairs: true, + showToolbar: true, + enableFullscreen: true, + ...options, + }; +}; + +// Export individual chart components for direct use +export { AreaChart, BarChart, ColumnChart, DualAxesChart, LineChart, PieChart, ScatterChart }; + +export default AdvancedChart; diff --git a/web/new-components/charts/index.ts b/web/new-components/charts/index.ts new file mode 100644 index 000000000..12f8f4971 --- /dev/null +++ b/web/new-components/charts/index.ts @@ -0,0 +1,15 @@ +export { + default as AdvancedChart, + AreaChart, + BarChart, + ColumnChart, + DualAxesChart, + LineChart, + PieChart, + ScatterChart, + createChartConfig, + default, + detectChartType, +} from './AdvancedCharts'; + +export type { AdvancedChartProps, ChartConfig, ChartType } from './AdvancedCharts'; diff --git a/web/new-components/chat/ChatHeader.tsx b/web/new-components/chat/ChatHeader.tsx new file mode 100644 index 000000000..c15e5e7c9 --- /dev/null +++ b/web/new-components/chat/ChatHeader.tsx @@ -0,0 +1,114 @@ +import { MenuOutlined, PlusOutlined, SettingOutlined } from '@ant-design/icons'; +import { Tooltip } from 'antd'; +import classNames from 'classnames'; +import Image from 'next/image'; +import React, { memo } from 'react'; +import { useTranslation } from 'react-i18next'; + +interface ChatHeaderProps { + title?: string; + modelName?: string; + onNewChat?: () => void; + onOpenSettings?: () => void; + onToggleSidebar?: () => void; + showSidebarToggle?: boolean; + extra?: React.ReactNode; + className?: string; +} + +const ChatHeader: React.FC = ({ + title, + modelName, + onNewChat, + onOpenSettings, + onToggleSidebar, + showSidebarToggle = false, + extra, + className, +}) => { + const { t } = useTranslation(); + + return ( +
    +
    + {showSidebarToggle && ( + + )} + +
    +
    + { + const target = e.target as HTMLImageElement; + target.style.display = 'none'; + }} + /> +
    +
    + {title || 'DB-GPT'} + {modelName && {modelName}} +
    +
    +
    + +
    + {extra} + + {onNewChat && ( + + + + )} + + {onOpenSettings && ( + + + + )} +
    +
    + ); +}; + +export default memo(ChatHeader); diff --git a/web/new-components/chat/ChatMessageList.tsx b/web/new-components/chat/ChatMessageList.tsx new file mode 100644 index 000000000..92c233fec --- /dev/null +++ b/web/new-components/chat/ChatMessageList.tsx @@ -0,0 +1,146 @@ +import { ArrowDownOutlined } from '@ant-design/icons'; +import classNames from 'classnames'; +import React, { memo, useCallback, useEffect, useRef, useState } from 'react'; +import SessionTurn, { ExecutionStep } from './content/SessionTurn'; + +export interface ChatMessage { + id: string; + role: 'user' | 'assistant'; + content: string; + timestamp?: number; + steps?: ExecutionStep[]; + isStreaming?: boolean; + modelName?: string; + thinkingContent?: string; +} + +export interface ChatTurn { + id: string; + userMessage: string; + assistantMessage?: string; + steps?: ExecutionStep[]; + isWorking?: boolean; + startTime?: number; + endTime?: number; + modelName?: string; + thinkingContent?: string; +} + +interface ChatMessageListProps { + turns: ChatTurn[]; + isLoading?: boolean; + onCopy?: (text: string) => void; + showSteps?: boolean; + className?: string; + emptyState?: React.ReactNode; +} + +const ChatMessageList: React.FC = ({ + turns, + isLoading = false, + onCopy, + showSteps = true, + className, + emptyState, +}) => { + const containerRef = useRef(null); + const bottomRef = useRef(null); + const [isAtBottom, setIsAtBottom] = useState(true); + const [showScrollButton, setShowScrollButton] = useState(false); + const userScrolledRef = useRef(false); + + const scrollToBottom = useCallback((behavior: ScrollBehavior = 'smooth') => { + if (bottomRef.current) { + bottomRef.current.scrollIntoView({ behavior, block: 'end' }); + } + }, []); + + const handleScroll = useCallback(() => { + if (!containerRef.current) return; + + const { scrollTop, scrollHeight, clientHeight } = containerRef.current; + const distanceFromBottom = scrollHeight - scrollTop - clientHeight; + const threshold = 100; + + const atBottom = distanceFromBottom < threshold; + setIsAtBottom(atBottom); + setShowScrollButton(!atBottom && scrollHeight > clientHeight); + + if (!atBottom) { + userScrolledRef.current = true; + } + }, []); + + useEffect(() => { + if (turns.length === 0) return; + + const lastTurn = turns[turns.length - 1]; + const isStreaming = lastTurn?.isWorking; + + if (isStreaming && !userScrolledRef.current) { + scrollToBottom('auto'); + } else if (!isStreaming && isAtBottom) { + scrollToBottom('smooth'); + userScrolledRef.current = false; + } + }, [turns, isAtBottom, scrollToBottom]); + + useEffect(() => { + const container = containerRef.current; + if (!container) return; + + container.addEventListener('scroll', handleScroll, { passive: true }); + return () => container.removeEventListener('scroll', handleScroll); + }, [handleScroll]); + + if (turns.length === 0 && emptyState) { + return <>{emptyState}; + } + + return ( +
    +
    +
    + {turns.map(turn => ( +
    + +
    + ))} +
    +
    +
    + + {showScrollButton && ( + + )} +
    + ); +}; + +export default memo(ChatMessageList); diff --git a/web/new-components/chat/ChatPage.tsx b/web/new-components/chat/ChatPage.tsx new file mode 100644 index 000000000..9a4c55583 --- /dev/null +++ b/web/new-components/chat/ChatPage.tsx @@ -0,0 +1,141 @@ +import classNames from 'classnames'; +import React, { memo, useCallback, useMemo, useRef } from 'react'; +import ChatHeader from './ChatHeader'; +import ChatMessageList, { ChatTurn } from './ChatMessageList'; +import ChatWelcome from './ChatWelcome'; +import { SlashCommand } from './input/CommandPopover'; +import { ContentPart } from './input/EnhancedChatInput'; +import StandaloneChatInput, { StandaloneChatInputRef } from './input/StandaloneChatInput'; + +export interface ChatPageProps { + turns: ChatTurn[]; + isLoading?: boolean; + modelName?: string; + title?: string; + + onSendMessage?: (text: string, parts: ContentPart[]) => void; + onNewChat?: () => void; + onOpenSettings?: () => void; + onStopGeneration?: () => void; + + agents?: Array<{ name: string; description?: string }>; + commands?: SlashCommand[]; + onFileSearch?: (query: string) => Promise; + onCommandSelect?: (command: SlashCommand) => void; + + disabled?: boolean; + inputPlaceholder?: string; + showSteps?: boolean; + + headerExtra?: React.ReactNode; + welcomeExtra?: React.ReactNode; + inputExtra?: React.ReactNode; + + className?: string; +} + +const ChatPage: React.FC = ({ + turns, + isLoading = false, + modelName, + title, + + onSendMessage, + onNewChat, + onOpenSettings, + onStopGeneration, + + agents = [], + commands = [], + onFileSearch, + onCommandSelect, + + disabled = false, + inputPlaceholder, + showSteps = true, + + headerExtra, + welcomeExtra, + inputExtra, + + className, +}) => { + const inputRef = useRef(null); + + const isEmpty = turns.length === 0; + + const isStreaming = useMemo(() => { + if (turns.length === 0) return false; + return turns[turns.length - 1]?.isWorking ?? false; + }, [turns]); + + const handleSubmit = useCallback( + (text: string, parts: ContentPart[]) => { + if (!text.trim() && parts.filter(p => p.type === 'image').length === 0) return; + onSendMessage?.(text, parts); + }, + [onSendMessage], + ); + + const handleStop = useCallback(() => { + onStopGeneration?.(); + }, [onStopGeneration]); + + const handleCopy = useCallback((text: string) => { + navigator.clipboard.writeText(text); + }, []); + + const handleSuggestionClick = useCallback((suggestion: { title: string }) => { + if (inputRef.current) { + inputRef.current.focus(); + } + }, []); + + return ( +
    + + +
    + {isEmpty ? ( + + {welcomeExtra} + + ) : ( + + )} + +
    + + {inputExtra} + +
    +
    +
    + ); +}; + +export default memo(ChatPage); diff --git a/web/new-components/chat/ChatWelcome.tsx b/web/new-components/chat/ChatWelcome.tsx new file mode 100644 index 000000000..49c928bc0 --- /dev/null +++ b/web/new-components/chat/ChatWelcome.tsx @@ -0,0 +1,137 @@ +import { DatabaseOutlined, FileTextOutlined, RobotOutlined, ThunderboltOutlined } from '@ant-design/icons'; +import classNames from 'classnames'; +import Image from 'next/image'; +import React, { memo } from 'react'; +import { useTranslation } from 'react-i18next'; + +interface SuggestionItem { + icon: React.ReactNode; + title: string; + description: string; + onClick?: () => void; +} + +interface ChatWelcomeProps { + userName?: string; + suggestions?: SuggestionItem[]; + onSuggestionClick?: (suggestion: SuggestionItem) => void; + className?: string; + children?: React.ReactNode; +} + +const defaultSuggestions: SuggestionItem[] = [ + { + icon: , + title: 'Database Analysis', + description: 'Connect to your database and explore data with natural language', + }, + { + icon: , + title: 'Knowledge Base', + description: 'Chat with your documents and knowledge base', + }, + { + icon: , + title: 'Agent Tasks', + description: 'Let AI agents help you complete complex tasks', + }, + { + icon: , + title: 'Code Assistant', + description: 'Get help with coding, debugging, and code review', + }, +]; + +const ChatWelcome: React.FC = ({ + userName, + suggestions = defaultSuggestions, + onSuggestionClick, + className, + children, +}) => { + const { t } = useTranslation(); + + const getGreeting = (): string => { + const hour = new Date().getHours(); + if (hour < 12) return String(t('good_morning', 'Good morning')); + if (hour < 18) return String(t('good_afternoon', 'Good afternoon')); + return String(t('good_evening', 'Good evening')); + }; + + return ( +
    +
    +
    + { + const target = e.target as HTMLImageElement; + target.style.display = 'none'; + }} + /> +
    + +

    + {getGreeting()} + {userName ? `, ${userName}` : ''} +

    + +

    + {t('welcome_message', 'How can I help you today? Ask me anything or try one of the suggestions below.')} +

    + + {children} + +
    + {suggestions.map((suggestion, index) => ( + + ))} +
    + +
    + Powered by + DB-GPT +
    +
    +
    + ); +}; + +export default memo(ChatWelcome); diff --git a/web/new-components/chat/content/ManusLeftPanel.tsx b/web/new-components/chat/content/ManusLeftPanel.tsx new file mode 100644 index 000000000..28be4bd8c --- /dev/null +++ b/web/new-components/chat/content/ManusLeftPanel.tsx @@ -0,0 +1,665 @@ +import { + BarChartOutlined, + BookOutlined, + CaretDownOutlined, + CaretRightOutlined, + CheckCircleFilled, + CheckCircleOutlined, + CheckOutlined, + ClockCircleOutlined, + CodeOutlined, + ConsoleSqlOutlined, + DesktopOutlined, + DownloadOutlined, + EditOutlined, + ExclamationCircleOutlined, + FileExcelOutlined, + FileImageOutlined, + FileOutlined, + FilePptOutlined, + FileSearchOutlined, + FileTextOutlined, + FolderOpenOutlined, + LoadingOutlined, + PieChartOutlined, + PlayCircleOutlined, + SearchOutlined, + TableOutlined, +} from '@ant-design/icons'; +import { Button, Tooltip } from 'antd'; +import classNames from 'classnames'; +import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import ObservationFormatter from './ObservationFormatter'; +import MarkdownContext from '@/new-components/common/MarkdownContext'; + +export type StepStatus = 'pending' | 'running' | 'completed' | 'error'; + +export type StepType = 'read' | 'edit' | 'write' | 'bash' | 'grep' | 'glob' | 'task' | 'skill' | 'python' | 'html' | 'other'; + +export interface ExecutionStep { + id: string; + type: StepType; + title: string; + subtitle?: string; + description?: string; + status: StepStatus; + output?: any; +} + +export interface ThinkingSection { + id: string; + title: string; + content?: string; + isCompleted: boolean; + steps: ExecutionStep[]; +} + +export interface ArtifactItem { + id: string; + type: 'file' | 'table' | 'chart' | 'image' | 'code' | 'markdown' | 'summary' | 'html'; + name: string; + content: any; + createdAt: number; + downloadable?: boolean; + mimeType?: string; + size?: number; + filePath?: string; +} + +export interface ManusLeftPanelProps { + sections: ThinkingSection[]; + activeStepId?: string | null; + onStepClick?: (stepId: string, sectionId: string) => void; + isWorking?: boolean; + userQuery?: string; + assistantText?: string; + modelName?: string; + stepThoughts?: Record; + artifacts?: ArtifactItem[]; + onArtifactClick?: (artifact: ArtifactItem) => void; + onViewAllFiles?: () => void; + attachedFile?: { + name: string; + size: number; + type: string; + }; + attachedKnowledge?: { + id: number; + name: string; + vector_type: string; + desc?: string; + owner?: string; + }; +} + +// Get step icon based on type and status +const getStepIcon = (type: StepType, status: StepStatus) => { + const iconClass = 'text-sm'; + + if (status === 'running') { + return ; + } + + switch (type) { + case 'read': + return ; + case 'edit': + case 'write': + return ; + case 'bash': + return ; + case 'grep': + case 'glob': + return ; + case 'python': + return ; + case 'html': + return ; + case 'task': + case 'skill': + return ; + default: + return ; + } +}; + +// Get step type label in Chinese +const getTypeLabel = (type: StepType): string => { + const labels: Record = { + read: '读取文件', + edit: '编辑文件', + write: '写入文件', + bash: '执行命令', + grep: '搜索内容', + glob: '查找文件', + task: '执行任务', + skill: '加载技能', + python: 'Python', + html: 'HTML', + other: '操作', + }; + return labels[type] || '操作'; +}; + +// Get icon background color based on type +const getIconBgClass = (type: StepType): string => { + const bgClasses: Record = { + read: 'bg-emerald-50 dark:bg-emerald-900/30', + edit: 'bg-amber-50 dark:bg-amber-900/30', + write: 'bg-amber-50 dark:bg-amber-900/30', + bash: 'bg-purple-50 dark:bg-purple-900/30', + grep: 'bg-cyan-50 dark:bg-cyan-900/30', + glob: 'bg-cyan-50 dark:bg-cyan-900/30', + python: 'bg-blue-50 dark:bg-blue-900/30', + html: 'bg-orange-50 dark:bg-orange-900/30', + task: 'bg-indigo-50 dark:bg-indigo-900/30', + skill: 'bg-indigo-50 dark:bg-indigo-900/30', + other: 'bg-gray-50 dark:bg-gray-800', + }; + return bgClasses[type] || 'bg-gray-50 dark:bg-gray-800'; +}; + +const formatFileSize = (bytes: number): string => { + if (bytes < 1024) return bytes + ' B'; + if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB'; + return (bytes / (1024 * 1024)).toFixed(2) + ' MB'; +}; + +const getFileTypeLabel = (fileName: string, mimeType?: string): string => { + const ext = fileName.toLowerCase().split('.').pop() || ''; + if (['xlsx', 'xls'].includes(ext) || mimeType?.includes('spreadsheet') || mimeType?.includes('excel')) return '电子表格'; + if (ext === 'csv' || mimeType?.includes('csv')) return '电子表格'; + if (ext === 'pdf' || mimeType?.includes('pdf')) return 'PDF'; + if (['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg'].includes(ext) || mimeType?.includes('image')) return '图片'; + if (['doc', 'docx'].includes(ext) || mimeType?.includes('word')) return 'Word 文档'; + if (['txt', 'md'].includes(ext) || mimeType?.includes('text')) return '文本文件'; + return '文件'; +}; + +const getFileIconElement = (fileName: string, mimeType?: string) => { + const ext = fileName.toLowerCase().split('.').pop() || ''; + if (['xlsx', 'xls', 'csv'].includes(ext) || mimeType?.includes('spreadsheet') || mimeType?.includes('excel') || mimeType?.includes('csv')) { + return ; + } + if (['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg'].includes(ext) || mimeType?.includes('image')) { + return ; + } + if (['ppt', 'pptx'].includes(ext)) { + return ; + } + return ; +}; + +// Get icon for artifact type +const getArtifactIcon = (artifact: ArtifactItem) => { + switch (artifact.type) { + case 'file': + return getFileIconElement(artifact.name, artifact.mimeType); + case 'html': + return ; + case 'table': + return ; + case 'chart': + return ; + case 'image': + return ; + case 'code': + return ; + case 'markdown': + return ; + case 'summary': + return ; + default: + return ; + } +}; + +// Get artifact type label +const getArtifactTypeLabel = (artifact: ArtifactItem): string => { + const labels: Record = { + file: '文件', + html: '网页报告', + table: '数据表', + chart: '图表', + image: '图片', + code: '代码', + markdown: '文档', + summary: '总结', + }; + return labels[artifact.type] || '产物'; +}; + +// Get icon background for artifact type +const getArtifactIconBg = (type: string): string => { + const bgs: Record = { + file: 'bg-gray-50 dark:bg-gray-800', + html: 'bg-blue-50 dark:bg-blue-900/30', + table: 'bg-blue-50 dark:bg-blue-900/30', + chart: 'bg-green-50 dark:bg-green-900/30', + image: 'bg-pink-50 dark:bg-pink-900/30', + code: 'bg-purple-50 dark:bg-purple-900/30', + markdown: 'bg-orange-50 dark:bg-orange-900/30', + summary: 'bg-emerald-50 dark:bg-emerald-900/30', + }; + return bgs[type] || 'bg-gray-50 dark:bg-gray-800'; +}; + +// Artifact Card Component +const ArtifactCard: React.FC<{ + artifact: ArtifactItem; + onClick?: () => void; +}> = memo(({ artifact, onClick }) => { + return ( +
    +
    + {getArtifactIcon(artifact)} +
    +
    +
    {artifact.name}
    +
    + {getArtifactTypeLabel(artifact)} + {artifact.size != null && ( + <> + · + {formatFileSize(artifact.size)} + + )} +
    +
    + {artifact.downloadable && ( + +
    + ); +}); + +ArtifactCard.displayName = 'ArtifactCard'; + +const StreamingText: React.FC<{ text: string }> = memo(({ text }) => { + const [displayed, setDisplayed] = useState(''); + const prevLenRef = useRef(0); + const rafRef = useRef(null); + const queueRef = useRef(''); + const idxRef = useRef(0); + + useEffect(() => { + if (text.length <= prevLenRef.current) { + prevLenRef.current = text.length; + setDisplayed(text); + return; + } + const newChars = text.slice(prevLenRef.current); + prevLenRef.current = text.length; + queueRef.current += newChars; + + if (rafRef.current !== null) return; + + const flush = () => { + const batch = Math.max(1, Math.ceil(queueRef.current.length / 12)); + const chunk = queueRef.current.slice(0, batch); + queueRef.current = queueRef.current.slice(batch); + idxRef.current += chunk.length; + setDisplayed(prev => prev + chunk); + if (queueRef.current.length > 0) { + rafRef.current = requestAnimationFrame(flush); + } else { + rafRef.current = null; + } + }; + rafRef.current = requestAnimationFrame(flush); + + return () => { + if (rafRef.current !== null) { + cancelAnimationFrame(rafRef.current); + rafRef.current = null; + } + }; + }, [text]); + + useEffect(() => { + return () => { + if (rafRef.current !== null) cancelAnimationFrame(rafRef.current); + }; + }, []); + + return <>{displayed}; +}); + +StreamingText.displayName = 'StreamingText'; + +const StepCard: React.FC<{ + step: ExecutionStep; + isActive: boolean; + onClick: () => void; +}> = memo(({ step, isActive, onClick }) => { + const [isVisible, setIsVisible] = useState(false); + + React.useEffect(() => { + const timer = setTimeout(() => setIsVisible(true), 50); + return () => clearTimeout(timer); + }, []); + + return ( +
    +
    + {getStepIcon(step.type, step.status)} +
    + + + {getTypeLabel(step.type)} + + + {step.title} + +
    + {step.status === 'pending' && } + {step.status === 'running' && } + {step.status === 'completed' && } + {step.status === 'error' && } +
    +
    + ); +}); + +StepCard.displayName = 'StepCard'; + +// Section Component +const SectionBlock: React.FC<{ + section: ThinkingSection; + activeStepId?: string | null; + onStepClick: (stepId: string) => void; + defaultExpanded?: boolean; + stepThoughts?: Record; +}> = memo(({ section, activeStepId, onStepClick, defaultExpanded = true, stepThoughts }) => { + const [isExpanded, setIsExpanded] = useState(defaultExpanded); + + const completedCount = section.steps.filter(s => s.status === 'completed').length; + const totalCount = section.steps.length; + const isAllCompleted = completedCount === totalCount && totalCount > 0; + const hasRunningStep = section.steps.some(s => s.status === 'running'); + + const hasObservations = useMemo(() => { + return section.steps.some(step => step.description?.includes('Observation:')); + }, [section.steps]); + + return ( +
    + {/* Section Header */} +
    setIsExpanded(!isExpanded)}> + {/* Status indicator */} +
    + {isAllCompleted ? ( + + ) : hasRunningStep ? ( + + ) : ( + + )} +
    + + {/* Section title */} + {section.title} + + {/* Progress indicator */} + {totalCount > 0 && ( + + {completedCount}/{totalCount} + + )} + + {/* Expand/collapse icon */} + + {isExpanded ? : } + +
    + + {/* Section Content */} + {isExpanded && ( +
    + {stepThoughts?.['initial'] && ( +
    + 💭 +

    +
    + )} + + {hasObservations && + section.steps.map(step => { + if (!step.description?.includes('Observation:')) return null; + return ; + })} + + {section.steps.map((step) => ( + + onStepClick(step.id)} + /> + {stepThoughts?.[step.id] && ( +
    + 💭 +

    +
    + )} +
    + ))} +
    + )} +
    + ); +}); + +SectionBlock.displayName = 'SectionBlock'; + +// Main Component +const ManusLeftPanel: React.FC = ({ + sections, + activeStepId, + onStepClick, + isWorking, + userQuery, + assistantText, + modelName, + stepThoughts, + artifacts, + onArtifactClick, + onViewAllFiles, + attachedFile, + attachedKnowledge, +}) => { + const handleStepClick = useCallback( + (stepId: string, sectionId: string) => { + onStepClick?.(stepId, sectionId); + }, + [onStepClick], + ); + + return ( +
    +
    + {userQuery && ( +
    +
    + {attachedFile && ( +
    +
    + {getFileIconElement(attachedFile.name, attachedFile.type)} +
    +
    +
    {attachedFile.name}
    +
    + {getFileTypeLabel(attachedFile.name, attachedFile.type)} · {formatFileSize(attachedFile.size)} +
    +
    +
    + )} + {attachedKnowledge && ( +
    +
    + +
    +
    +
    {attachedKnowledge.name}
    +
    + {attachedKnowledge.desc || attachedKnowledge.vector_type} +
    +
    +
    + )} +
    + {userQuery} +
    +
    +
    + )} + + {sections.length > 0 ? ( +
    + {sections.map((section, index) => ( + handleStepClick(stepId, section.id)} + defaultExpanded={index === sections.length - 1} + stepThoughts={stepThoughts} + /> + ))} +
    + ) : ( +
    + {isWorking ? ( + <> + + DB-GPT 正在思考 ··· + + ) : ( + 等待开始... + )} +
    + )} + + {isWorking && sections.length > 0 && ( +
    + + DB-GPT 正在思考 ··· +
    + )} + + {assistantText && ( +
    +
    + {assistantText} +
    +
    + )} + + {artifacts && artifacts.length > 0 && ( +
    +
    + {artifacts + .filter(a => a.type === 'file' || a.type === 'html') + .slice(0, 3) + .map(artifact => ( + onArtifactClick?.(artifact)} + /> + ))} + + {onViewAllFiles && ( +
    +
    + +
    + 查看此任务中的所有文件 +
    + )} +
    + +
    + + 任务已完成 +
    +
    + )} +
    + + {modelName && ( +
    +
    + Model: {modelName} + {isWorking && Processing...} +
    +
    + )} +
    + ); +}; + +export default memo(ManusLeftPanel); diff --git a/web/new-components/chat/content/ManusRightPanel.tsx b/web/new-components/chat/content/ManusRightPanel.tsx new file mode 100644 index 000000000..74c737602 --- /dev/null +++ b/web/new-components/chat/content/ManusRightPanel.tsx @@ -0,0 +1,977 @@ +import { CodePreview } from '@/components/chat/chat-content/code-preview'; +import markdownComponents, { markdownPlugins, preprocessLaTeX } from '@/components/chat/chat-content/config'; +import AdvancedChart, { createChartConfig } from '@/new-components/charts'; +import { + BarChartOutlined, + CheckCircleFilled, + CloseCircleFilled, + CodeOutlined, + ConsoleSqlOutlined, + DesktopOutlined, + DownOutlined, + EditOutlined, + ExportOutlined, + EyeOutlined, + FileExcelOutlined, + FileImageOutlined, + FileOutlined, + FilePptOutlined, + FileSearchOutlined, + FileTextOutlined, + FolderOpenOutlined, + LeftOutlined, + LoadingOutlined, + PlayCircleOutlined, + SearchOutlined, + SyncOutlined, + TableOutlined, + UpOutlined, +} from '@ant-design/icons'; +import { GPTVis } from '@antv/gpt-vis'; +import { Button, Table, Tooltip, message } from 'antd'; +import classNames from 'classnames'; +import React, { memo, useEffect, useMemo, useRef, useState } from 'react'; +import { ArtifactItem, StepStatus, StepType } from './ManusLeftPanel'; + +/** Resolve image paths like `/images/xxx.png` to full backend URLs in dev mode */ +const resolveImageUrl = (src: string): string => { + if (!src) return src; + if (/^https?:\/\//.test(src)) return src; + if (src.startsWith('/images/')) { + const base = process.env.API_BASE_URL || ''; + return base ? `${base}${src}` : src; + } + return src; +}; + +/** Replace `/images/...` references inside HTML content with full backend URLs */ +const resolveHtmlImageUrls = (html: string): string => { + const base = process.env.API_BASE_URL || ''; + if (!base || !html) return html; + return html.replace(/(src\s*=\s*["'])\/images\//gi, `$1${base}/images/`); +}; + +export interface ExecutionOutput { + output_type: 'code' | 'text' | 'markdown' | 'table' | 'chart' | 'json' | 'error' | 'thought' | 'html' | 'image'; + content: any; + timestamp?: number; +} + +export interface ActiveStepInfo { + id: string; + type: StepType; + title: string; + subtitle?: string; + status: StepStatus; + detail?: string; +} + +export interface ManusRightPanelProps { + activeStep?: ActiveStepInfo | null; + outputs: ExecutionOutput[]; + isRunning?: boolean; + onRerun?: () => void; + terminalTitle?: string; + onCollapse?: () => void; + isCollapsed?: boolean; + artifacts?: ArtifactItem[]; + onArtifactClick?: (artifact: ArtifactItem) => void; + /** Controlled panel view — when provided, overrides internal state */ + panelView?: PanelView; + /** Callback when panel view changes (for lifting state) */ + onPanelViewChange?: (view: PanelView) => void; + /** Artifact to preview in html-preview mode */ + previewArtifact?: ArtifactItem | null; +} + +export type PanelView = 'execution' | 'files' | 'html-preview'; + +// Get icon for step type +const getStepTypeIcon = (type: StepType) => { + switch (type) { + case 'read': + return ; + case 'edit': + case 'write': + return ; + case 'bash': + return ; + case 'grep': + case 'glob': + return ; + case 'python': + return ; + case 'html': + return ; + case 'task': + case 'skill': + return ; + default: + return ; + } +}; + +// Get status badge +const StatusBadge: React.FC<{ status: StepStatus }> = ({ status }) => { + switch (status) { + case 'running': + return ( +
    + + 运行中 +
    + ); + case 'completed': + return ( +
    + + 完成 +
    + ); + case 'error': + return ( +
    + + 错误 +
    + ); + default: + return ( +
    + 待执行 +
    + ); + } +}; + +// Copy to clipboard helper +const copyToClipboard = (text: string) => { + navigator.clipboard.writeText(text); + message.success('已复制到剪贴板'); +}; + +const getArtifactFileIcon = (artifact: ArtifactItem) => { + switch (artifact.type) { + case 'file': { + const ext = artifact.name.toLowerCase().split('.').pop() || ''; + if (['xlsx', 'xls', 'csv'].includes(ext)) return ; + if (['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg'].includes(ext)) + return ; + if (['ppt', 'pptx'].includes(ext)) return ; + return ; + } + case 'html': + return ; + case 'table': + return ; + case 'chart': + return ; + case 'image': + return ; + case 'code': + return ; + case 'markdown': + return ; + case 'summary': + return ; + default: + return ; + } +}; + +const getArtifactFileBg = (type: string): string => { + const map: Record = { + file: 'bg-gray-50 dark:bg-gray-800', + html: 'bg-blue-50 dark:bg-blue-900/20', + table: 'bg-blue-50 dark:bg-blue-900/20', + chart: 'bg-green-50 dark:bg-green-900/20', + image: 'bg-pink-50 dark:bg-pink-900/20', + code: 'bg-purple-50 dark:bg-purple-900/20', + markdown: 'bg-orange-50 dark:bg-orange-900/20', + summary: 'bg-emerald-50 dark:bg-emerald-900/20', + }; + return map[type] || 'bg-gray-50 dark:bg-gray-800'; +}; + +const getArtifactTypeLabel = (type: string): string => { + const map: Record = { + file: '文件', + html: '网页报告', + table: '数据表', + chart: '图表', + image: '图片', + code: '代码', + markdown: '文档', + summary: '分析总结', + }; + return map[type] || '产物'; +}; + +type FileFilterTab = 'all' | 'document' | 'image' | 'code' | 'link'; + +const FILE_FILTER_TABS: { key: FileFilterTab; label: string }[] = [ + { key: 'all', label: '全部' }, + { key: 'document', label: '文档' }, + { key: 'image', label: '图片' }, + { key: 'code', label: '代码文件' }, + { key: 'link', label: '链接' }, +]; + +const getFileFilterCategory = (artifact: ArtifactItem): FileFilterTab[] => { + const categories: FileFilterTab[] = ['all']; + const ext = artifact.name.toLowerCase().split('.').pop() || ''; + if (artifact.type === 'image' || ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg'].includes(ext)) { + categories.push('image'); + } + if (artifact.type === 'code' || ['py', 'js', 'ts', 'tsx', 'jsx', 'sql', 'sh', 'json', 'yaml', 'yml'].includes(ext)) { + categories.push('code'); + } + if ( + artifact.type === 'html' || + artifact.type === 'markdown' || + artifact.type === 'summary' || + artifact.type === 'table' || + ['xlsx', 'xls', 'csv', 'doc', 'docx', 'pdf', 'ppt', 'pptx', 'md', 'txt', 'html', 'htm'].includes(ext) + ) { + categories.push('document'); + } + if (artifact.type === 'file' && categories.length === 1) { + categories.push('document'); + } + return categories; +}; + +const formatArtifactDate = (timestamp: number): string => { + const now = new Date(); + const date = new Date(timestamp); + const diffMs = now.getTime() - date.getTime(); + const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); + + if (diffDays === 0) return '今天'; + if (diffDays === 1) return '昨天'; + if (diffDays < 7) { + const dayNames = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']; + return dayNames[date.getDay()]; + } + return `${date.getMonth() + 1}月${date.getDate()}日`; +}; + +const FileListItem: React.FC<{ artifact: ArtifactItem; onClick?: () => void }> = memo(({ artifact, onClick }) => { + const isImage = artifact.type === 'image' || /\.(png|jpg|jpeg|gif|webp|svg)$/i.test(artifact.name); + const imgSrc = isImage && typeof artifact.content === 'string' ? resolveImageUrl(artifact.content) : null; + + return ( +
    + {imgSrc ? ( + {artifact.name} + ) : ( +
    + {getArtifactFileIcon(artifact)} +
    + )} +
    +
    {artifact.name}
    +
    + {getArtifactTypeLabel(artifact.type)} + {artifact.size != null && ( + <> + · + + {artifact.size < 1024 + ? artifact.size + ' B' + : artifact.size < 1024 * 1024 + ? (artifact.size / 1024).toFixed(1) + ' KB' + : (artifact.size / (1024 * 1024)).toFixed(1) + ' MB'} + + + )} +
    +
    +
    + ); +}); + +FileListItem.displayName = 'FileListItem'; + +// Output Renderer Component +const OutputRenderer: React.FC<{ output: ExecutionOutput; index: number }> = memo(({ output, index }) => { + const content = output.content; + + if (output.output_type === 'thought') { + return null; // Don't render thoughts + } + + return ( + <> + {output.output_type === 'code' && ( + + )} + + {output.output_type === 'error' && ( +
    + {String(content)} +
    + )} + + {output.output_type === 'text' && ( +
    + {String(content)} +
    + )} + + {output.output_type === 'markdown' && ( +
    + + {preprocessLaTeX(String(content))} + +
    + )} + + {output.output_type === 'table' && ( +
    + typeof col === 'string' ? { title: col, dataIndex: col, key: col, ellipsis: true } : col, + )} + dataSource={content?.rows || []} + rowKey={(row, idx) => String(row?.id ?? idx)} + scroll={{ x: 'max-content' }} + className='border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden' + /> + )} + + {output.output_type === 'chart' && ( +
    + +
    + )} + + {output.output_type === 'json' && ( + + )} + + {output.output_type === 'html' && ( +
    + {content?.title && ( +
    + + {content.title} +
    + )} +